Package: unison Version: 2.9.1-2 Severity: wishlist Tags: patch, upstream Hi,
Here is a patch to handle IPv6: replaced gethostbyname by getaddrinfo, which prefers port strings, and people may indeed want to use strings, so the patch makes unison use strings for ports as well. Regards, Samuel Thibault -- System Information: Debian Release: 3.1 APT prefers unstable APT policy: (100, 'unstable'), (1, 'experimental') Architecture: i386 (i686) Kernel: Linux 2.6.11 Locale: [EMAIL PROTECTED], [EMAIL PROTECTED] (charmap=ISO-8859-15) Versions of packages unison depends on: ii libc6 2.3.2.ds1-20 GNU C Library: Shared libraries an -- no debconf information
diff -ur unison-2.9.1/main.ml unison-2.9.1-mine/main.ml --- unison-2.9.1/main.ml 2002-04-11 07:13:23.000000000 +0200 +++ unison-2.9.1-mine/main.ml 2005-03-30 02:15:01.000000000 +0200 @@ -174,15 +174,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 i); diff -ur unison-2.9.1/remote.ml unison-2.9.1-mine/remote.ml --- unison-2.9.1/remote.ml 2002-04-11 07:13:23.000000000 +0200 +++ unison-2.9.1-mine/remote.ml 2005-03-30 02:24:04.000000000 +0200 @@ -1037,25 +1037,24 @@ Lwt.return conn)) let buildSocketConnection host port = - let targetInetAddr = - try - let targetHostEntry = Unix.gethostbyname host in - targetHostEntry.Unix.h_addr_list.(0) - 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; - Lwt_unix.run (initConnection socket socket) + (Printf.sprintf + "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; + Lwt_unix.run (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 = let (in_ch, out_ch) = @@ -1071,7 +1070,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 @@ -1197,18 +1196,31 @@ (* 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 portnum = +let waitOnPort 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 *) - Unix.bind listening (Unix.ADDR_INET(Unix.inet_addr_any,portnum)); - (* Start listening, allow up to 1 pending request *) - Unix.listen listening 1; + let rec loop = function + [] -> raise (Util.Fatal + (Printf.sprintf "Can't find local port %s" 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 local port (%s:%s): %s" ai.Unix.ai_canonname port reason); + loop r) + end in + let listening = loop (Unix.getaddrinfo "" port [ Unix.AI_SOCKTYPE Unix.SOCK_STREAM ; Unix.AI_PASSIVE ]) in Util.msg "server started\n"; while (* Accept a connection *) diff -ur unison-2.9.1/remote.mli unison-2.9.1-mine/remote.mli --- unison-2.9.1/remote.mli 2002-04-11 07:13:23.000000000 +0200 +++ unison-2.9.1-mine/remote.mli 2005-03-30 02:13:53.000000000 +0200 @@ -64,7 +64,7 @@ (* Enter "server mode", reading and processing commands from a remote client process until killed *) val beAServer : unit -> unit -val waitOnPort : int -> unit +val waitOnPort : string -> unit (* Whether the server should be killed when the client terminates *) val killServer : bool Prefs.t diff -ur unison-2.9.1/uigtk.ml unison-2.9.1-mine/uigtk.ml --- unison-2.9.1/uigtk.ml 2002-04-11 07:13:23.000000000 +0200 +++ unison-2.9.1-mine/uigtk.ml 2005-03-30 01:58:19.000000000 +0200 @@ -655,21 +655,17 @@ `Local -> Uri.clroot2string(Uri.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 Uri.clroot2string( Uri.ConnectByShell((if !varLocalRemote=`SSH then "ssh" else "rsh"), host, (if user="" then None else Some user), - portOpt, + Some portE#text, Some file)) | `SOCKET -> Uri.clroot2string( (* FIX: report an error if the port entry is not well formed *) Uri.ConnectBySocket(host, - int_of_string(portE#text), + portE#text, Some file)) in let contCommand() = try diff -ur unison-2.9.1/uri.ml unison-2.9.1-mine/uri.ml --- unison-2.9.1/uri.ml 2002-04-11 07:13:23.000000000 +0200 +++ unison-2.9.1-mine/uri.ml 2005-03-30 01:34:08.000000000 +0200 @@ -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 diff -ur unison-2.9.1/uri.mli unison-2.9.1-mine/uri.mli --- unison-2.9.1/uri.mli 2002-04-11 07:13:23.000000000 +0200 +++ unison-2.9.1-mine/uri.mli 2005-03-30 01:35:47.000000000 +0200 @@ -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