# HG changeset patch # User Juanma Barranquero # Date 1162816666 0 # Node ID bcb5c0f9a466891ef71c794f55b799e0512af21e # Parent 4dea79b8c06e7eb105d2673d5152bfd16b70e2dd (longopts) [! NO_SOCKETS_IN_FILE_SYSTEM]: Don't show option --socket-name. (decode_options): Don't get EMACS_SERVER_FILE here, it could override command line options. (decode_options) [! NO_SOCKETS_IN_FILE_SYSTEM]: Don't parse "-s" option. (fail): Don't check for missing arguments, it is now done in set_socket. (file_name_absolute_p): New function (loosely based on the one in fileio.c). (initialize_sockets): Don't check for duplicate loading of Winsock. (get_server_config): Only try relative paths in the default directory locations. (set_tcp_socket): Don't call INITIALIZE(). Warn when connecting to a remote server. (set_socket): Call INITIALIZE(). Search explicit command-line arguments, then environment variable EMACS_SERVER_FILE, then implicit socket paths, before trying the alternate editor. (main): Use file_name_absolute_p. diff -r 4dea79b8c06e -r bcb5c0f9a466 lib-src/emacsclient.c --- a/lib-src/emacsclient.c Mon Nov 06 03:04:08 2006 +0000 +++ b/lib-src/emacsclient.c Mon Nov 06 12:37:46 2006 +0000 @@ -115,7 +115,7 @@ /* If non-NULL, the name of an editor to fallback to if the server is not running. --alternate-editor. */ -const char * alternate_editor = NULL; +const char *alternate_editor = NULL; /* If non-NULL, the filename of the UNIX socket. */ char *socket_name = NULL; @@ -132,7 +132,9 @@ { "help", no_argument, NULL, 'H' }, { "version", no_argument, NULL, 'V' }, { "alternate-editor", required_argument, NULL, 'a' }, +#ifndef NO_SOCKETS_IN_FILE_SYSTEM { "socket-name", required_argument, NULL, 's' }, +#endif { "server-file", required_argument, NULL, 'f' }, { "display", required_argument, NULL, 'd' }, { 0, 0, 0, 0 } @@ -147,12 +149,16 @@ char **argv; { alternate_editor = getenv ("ALTERNATE_EDITOR"); - server_file = getenv ("EMACS_SERVER_FILE"); while (1) { int opt = getopt_long (argc, argv, - "VHnea:s:f:d:", longopts, 0); +#ifndef NO_SOCKETS_IN_FILE_SYSTEM + "VHnea:s:f:d:", +#else + "VHnea:f:d:", +#endif + longopts, 0); if (opt == EOF) break; @@ -168,9 +174,11 @@ alternate_editor = optarg; break; +#ifndef NO_SOCKETS_IN_FILE_SYSTEM case 's': socket_name = optarg; break; +#endif case 'f': server_file = optarg; @@ -252,16 +260,6 @@ fprintf (stderr, "%s: error executing alternate editor \"%s\"\n", progname, alternate_editor); } - else - { - fprintf (stderr, "%s: No socket or alternate editor. Please use:\n\n" -#if !defined (NO_SOCKETS_IN_FILE_SYSTEM) -"\t--socket-name\n" -#endif -"\t--server-file (or environment variable EMACS_SERVER_FILE)\n\ -\t--alternate-editor (or environment variable ALTERNATE_EDITOR)\n", - progname); - } exit (EXIT_FAILURE); } @@ -306,7 +304,8 @@ - the data ends in "\n", or - the buffer is full (but this shouldn't happen) Otherwise, we just accumulate it. */ -void send_to_emacs (s, data) +void +send_to_emacs (s, data) HSOCKET s; char *data; { @@ -381,21 +380,46 @@ free (copy); } +int +file_name_absolute_p (filename) + const unsigned char *filename; +{ + /* Sanity check, it shouldn't happen. */ + if (! filename) return FALSE; + + /* /xxx is always an absolute path. */ + if (filename[0] == '/') return TRUE; + + /* Empty filenames (which shouldn't happen) are relative. */ + if (filename[0] == '\0') return FALSE; + +#ifdef WINDOWSNT + /* X:\xxx is always absolute; X:xxx is an error and will fail. */ + if (islower (tolower (filename[0])) + && filename[1] == ':' && filename[2] == '\\') + return TRUE; + + /* Both \xxx and \\xxx\yyy are absolute. */ + if (filename[0] == '\\') return TRUE; +#endif + + return FALSE; +} + #ifdef WINDOWSNT /* Wrapper to make WSACleanup a cdecl, as required by atexit(). */ -void __cdecl close_winsock () +void +__cdecl close_winsock () { WSACleanup (); } -void initialize_sockets () +/* Initialize the WinSock2 library. */ +void +initialize_sockets () { - static done = FALSE; WSADATA wsaData; - if (done) return; - - /* Initialize the WinSock2 library. */ if (WSAStartup (MAKEWORD (2, 0), &wsaData)) { fprintf (stderr, "%s: error initializing WinSock2", progname); @@ -403,7 +427,6 @@ } atexit (close_winsock); - done = TRUE; } #endif /* WINDOWSNT */ @@ -411,15 +434,18 @@ * Read the information needed to set up a TCP comm channel with * the Emacs server: host, port and authentication string. */ -int get_server_config (server, authentication) +int +get_server_config (server, authentication) struct sockaddr_in *server; char *authentication; { - FILE *config; char dotted[32]; char *port; + FILE *config = NULL; - if (! (config = fopen (server_file, "rb"))) + if (file_name_absolute_p (server_file)) + config = fopen (server_file, "rb"); + else { char *home = getenv ("HOME"); #ifdef WINDOWSNT @@ -471,11 +497,13 @@ struct linger l_arg = {1, 1}; char auth_string[AUTH_KEY_LENGTH + 1]; - INITIALIZE (); - if (! get_server_config (&server, auth_string)) return INVALID_SOCKET; + if (server.sin_addr.s_addr != inet_addr ("127.0.0.1")) + fprintf (stderr, "%s: connected to remote socket at %s\n", + progname, inet_ntoa (server.sin_addr)); + /* * Open up an AF_INET socket */ @@ -645,7 +673,7 @@ else fprintf (stderr, "%s: can't stat %s: %s\n", progname, server.sun_path, strerror (saved_errno)); - return INVALID_SOCKET; + return INVALID_SOCKET; } } @@ -664,17 +692,61 @@ HSOCKET set_socket () { - if (server_file) - return set_tcp_socket (); - else + HSOCKET s; + + INITIALIZE (); + #ifndef NO_SOCKETS_IN_FILE_SYSTEM - return set_local_socket (); -#else + /* Explicit --socket-name argument. */ + if (socket_name) { - server_file = "server"; - return set_tcp_socket (); + s = set_local_socket (); + if ((s != INVALID_SOCKET) || alternate_editor) + return s; + + fprintf (stderr, "%s: error accessing socket \"%s\"", + progname, socket_name); + exit (EXIT_FAILURE); } #endif + + /* Explicit --server-file arg or EMACS_SERVER_FILE variable. */ + if (!server_file) + server_file = getenv ("EMACS_SERVER_FILE"); + + if (server_file) + { + s = set_tcp_socket (); + if ((s != INVALID_SOCKET) || alternate_editor) + return s; + + fprintf (stderr, "%s: error accessing server file \"%s\"", + progname, server_file); + exit (EXIT_FAILURE); + } + +#ifndef NO_SOCKETS_IN_FILE_SYSTEM + /* Implicit local socket. */ + s = set_local_socket (); + if (s != INVALID_SOCKET) + return s; +#endif + + /* Implicit server file. */ + server_file = "server"; + s = set_tcp_socket (); + if ((s != INVALID_SOCKET) || alternate_editor) + return s; + + /* No implicit or explicit socket, and no alternate editor. */ + fprintf (stderr, "%s: No socket or alternate editor. Please use:\n\n" +#ifndef NO_SOCKETS_IN_FILE_SYSTEM +"\t--socket-name\n" +#endif +"\t--server-file (or environment variable EMACS_SERVER_FILE)\n\ +\t--alternate-editor (or environment variable ALTERNATE_EDITOR)\n", + progname); + exit (EXIT_FAILURE); } int @@ -748,16 +820,7 @@ SEND_STRING ("/"); } } -#ifndef WINDOWSNT - else if (*argv[i] != '/') -#else - else if ((*argv[i] != '/') - /* Absolute paths can also start with backslash - or drive letters. */ - && (*argv[i] != '\\') - && (!islower (tolower (*argv[i])) - || (argv[i][1] != ':'))) -#endif + else if (! file_name_absolute_p (argv[i])) { SEND_QUOTED (cwd); SEND_STRING ("/");