Index: remote.ml =================================================================== --- remote.ml (révision 92) +++ remote.ml (copie de travail) @@ -811,25 +811,26 @@ let buildSocketConnection host port = Util.convertUnixErrorsToFatal "canonizeRoot" (fun () -> - let targetInetAddr = - try - inetAddr host - with Not_found -> + let rec loop = function + [] -> raise (Util.Fatal (Printf.sprintf - "Can't find the IP address of the server (%s)" host)) - in - (* create a socket to talk to the remote host *) - let socket = Unix.socket Unix.PF_INET Unix.SOCK_STREAM 0 in - begin try - Unix.connect socket (Unix.ADDR_INET(targetInetAddr,port)) - with - Unix.Unix_error (_, _, reason) -> - raise (Util.Fatal - (Printf.sprintf - "Can't connect to server (%s): %s" host reason)) - end; - initConnection socket socket) + "Can't find the IP address of the server (%s:%s)" host + port)) + | ai::r -> + (* create a socket to talk to the remote host *) + let socket = Unix.socket ai.Unix.ai_family ai.Unix.ai_socktype ai.Unix.ai_protocol in + begin try + Unix.connect socket ai.Unix.ai_addr; + initConnection socket socket + with + Unix.Unix_error (_, _, reason) -> + (Util.warn + (Printf.sprintf + "Can't connect to server (%s:%s): %s" host port reason); + loop r) + end + in loop (Unix.getaddrinfo host port [ Unix.AI_SOCKTYPE Unix.SOCK_STREAM ])) let buildShellConnection shell host userOpt portOpt rootName termInteract = let remoteCmd = @@ -844,7 +845,7 @@ let portArgs = match portOpt with None -> [] - | Some port -> ["-p"; string_of_int port] in + | Some port -> ["-p"; port] in let shellCmd = (if shell = "ssh" then Prefs.read sshCmd @@ -980,7 +981,7 @@ let portArgs = match portOpt with None -> [] - | Some port -> ["-p"; string_of_int port] in + | Some port -> ["-p"; port] in let shellCmd = (if shell = "ssh" then Prefs.read sshCmd @@ -1113,30 +1114,38 @@ (* Used by the socket mechanism: Create a socket on portNum and wait for a request. Each request is processed by commandLoop. When a session finishes, the server waits for another request. *) -let waitOnPort hostOpt portnum = +let waitOnPort hostOpt port = Util.convertUnixErrorsToFatal "waiting on port" (fun () -> - (* Open a socket to listen for queries *) - let listening = Unix.socket Unix.PF_INET Unix.SOCK_STREAM 0 in - (* Allow reuse of local addresses for bind *) - Unix.setsockopt listening Unix.SO_REUSEADDR true; - (* Bind the socket to portnum on the local host *) - let addr = - match hostOpt with - Some host -> - begin try inetAddr host with Not_found -> - raise (Util.Fatal - (Printf.sprintf - "Can't find the IP address of the host (%s)" host)) - end - | None -> - Unix.inet_addr_any - in - Unix.bind listening - (Unix.ADDR_INET (addr, portnum)); - (* Start listening, allow up to 1 pending request *) - Unix.listen listening 1; + let host = match hostOpt with + Some host -> host + | None -> "" in + let rec loop = function + [] -> raise (Util.Fatal + (Printf.sprintf "Can't find host (%s:%s)" host port)) + | ai::r -> + (* Open a socket to listen for queries *) + let socket = Unix.socket ai.Unix.ai_family ai.Unix.ai_socktype + ai.Unix.ai_protocol in + begin try + (* Allow reuse of local addresses for bind *) + Unix.setsockopt socket Unix.SO_REUSEADDR true; + (* Bind the socket to portnum on the local host *) + Unix.bind socket ai.Unix.ai_addr; + (* Start listening, allow up to 1 pending request *) + Unix.listen socket 1; + socket + with + Unix.Unix_error (_, _, reason) -> + (Util.warn + (Printf.sprintf + "Can't bind to host (%s:%s): %s" ai.Unix.ai_canonname port + reason); + loop r) + end in + let listening = loop (Unix.getaddrinfo host port [ Unix.AI_SOCKTYPE + Unix.SOCK_STREAM ; Unix.AI_PASSIVE ]) in Util.msg "server started\n"; while (* Accept a connection *) Index: clroot.ml =================================================================== --- clroot.ml (révision 92) +++ clroot.ml (copie de travail) @@ -33,11 +33,11 @@ string (* shell = "rsh" or "ssh" *) * string (* name of host *) * string option (* user name to log in as *) - * int option (* port *) + * string option (* port *) * string option (* root of replica in host fs *) | ConnectBySocket of string (* name of host *) - * int (* port where server should be listening *) + * string (* port where server should be listening *) * string option (* root of replica in host fs *) (* Internal datatypes used in parsing command-line roots *) @@ -107,13 +107,13 @@ (Some host,s') else (None,s) -let colonPortRegexp = Str.regexp ":[0-9]+" +let colonPortRegexp = Str.regexp ":[^/]+" let getPort s = if Str.string_match colonPortRegexp s 0 then let colonPort = Str.matched_string s in let len = String.length colonPort in - let port = int_of_string(String.sub colonPort 1 (len-1)) in + let port = String.sub colonPort 1 (len-1) in let s' = Str.string_after s len in (Some port,s') else (None,s) @@ -178,11 +178,11 @@ else Printf.sprintf "file:///%s" s else s | ConnectBySocket(h,p,s) -> - Printf.sprintf "socket://%s:%d/%s" h p + Printf.sprintf "socket://%s:%s/%s" h p (match s with None -> "" | Some x -> x) | ConnectByShell(sh,h,u,p,s) -> let user = match u with None -> "" | Some x -> x^"@" in - let port = match p with None -> "" | Some x -> ":"^(string_of_int x) in + let port = match p with None -> "" | Some x -> ":"^x in let path = match s with None -> "" | Some x -> x in Printf.sprintf "%s://%s%s%s/%s" sh user h port path Index: clroot.mli =================================================================== --- clroot.mli (révision 92) +++ clroot.mli (copie de travail) @@ -10,11 +10,11 @@ string (* shell = "rsh" or "ssh" *) * string (* name of host *) * string option (* user name to log in as *) - * int option (* port *) + * string option (* port *) * string option (* root of replica in host fs *) | ConnectBySocket of string (* name of host *) - * int (* port where server should be listening *) + * string (* port where server should be listening *) * string option (* root of replica in host fs *) val clroot2string : clroot -> string Index: remote.mli =================================================================== --- remote.mli (révision 92) +++ remote.mli (copie de travail) @@ -36,7 +36,7 @@ (* Enter "server mode", reading and processing commands from a remote client process until killed *) val beAServer : unit -> unit -val waitOnPort : string option -> int -> unit +val waitOnPort : string option -> string -> unit (* Whether the server should be killed when the client terminates *) val killServer : bool Prefs.t Index: uigtk.ml =================================================================== --- uigtk.ml (révision 92) +++ uigtk.ml (copie de travail) @@ -655,21 +655,17 @@ `Local -> Clroot.clroot2string(Clroot.ConnectLocal(Some file)) | `SSH | `RSH -> - let portOpt = - (* FIX: report an error if the port entry is not well formed *) - try Some(int_of_string(portE#text)) - with _ -> None in Clroot.clroot2string( Clroot.ConnectByShell((if !varLocalRemote=`SSH then "ssh" else "rsh"), host, (if user="" then None else Some user), - portOpt, + Some portE#text, Some file)) | `SOCKET -> Clroot.clroot2string( (* FIX: report an error if the port entry is not well formed *) Clroot.ConnectBySocket(host, - int_of_string(portE#text), + portE#text, Some file)) in let contCommand() = try Index: main.ml =================================================================== --- main.ml (révision 92) +++ main.ml (copie de travail) @@ -183,15 +183,7 @@ (* Start a socket server if requested *) begin try - let i = - match Util.StringMap.find socketPrefName argv with - [] -> - assert false - | i::_ -> - try int_of_string i with Failure _ -> - Util.msg "-socket must be followed by a number\n"; - exit 1 - in + let i = List.hd (Util.StringMap.find socketPrefName argv) in catch_all (fun () -> Os.createUnisonDir(); Remote.waitOnPort