1 /* Client process that communicates with GNU Emacs acting as server.
2 Copyright (C) 1986, 1987, 1994, 1999, 2000, 2001, 2002, 2003, 2004,
3 2005, 2006 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 Boston, MA 02110-1301, USA. */
35 # define NO_SOCKETS_IN_FILE_SYSTEM
37 # define HSOCKET SOCKET
38 # define CLOSE_SOCKET closesocket
39 # define IOCTL ioctlsocket
40 # define INITIALIZE() (initialize_sockets ())
41 typedef unsigned long IOCTL_BOOL_ARG
;
43 #else /* !WINDOWSNT */
48 # include <netinet/in.h>
49 # include <sys/ioctl.h>
51 # define INVALID_SOCKET -1
53 # define CLOSE_SOCKET close
56 typedef int IOCTL_BOOL_ARG
;
58 #endif /* !WINDOWSNT */
74 #else /* not WINDOWSNT */
76 #endif /* not WINDOWSNT */
79 char *getenv (), *getwd ();
83 #define VERSION "unspecified"
86 #define SEND_STRING(data) (send_to_emacs (s, (data)))
87 #define SEND_QUOTED(data) (quote_file_name (s, (data)))
90 #define EXIT_SUCCESS 0
94 #define EXIT_FAILURE 1
109 /* Name used to invoke this program. */
112 /* Nonzero means don't wait for a response from Emacs. --no-wait. */
115 /* Nonzero means args are expressions to be evaluated. --eval. */
118 /* The display on which Emacs should work. --display. */
119 char *display
= NULL
;
121 /* If non-NULL, the name of an editor to fallback to if the server
122 is not running. --alternate-editor. */
123 const char * alternate_editor
= NULL
;
125 /* If non-NULL, the filename of the UNIX socket. */
126 char *socket_name
= NULL
;
128 /* If non-NULL, the filename of the authentication file. */
129 char *server_file
= NULL
;
131 void print_help_and_exit () NO_RETURN
;
133 struct option longopts
[] =
135 { "no-wait", no_argument
, NULL
, 'n' },
136 { "eval", no_argument
, NULL
, 'e' },
137 { "help", no_argument
, NULL
, 'H' },
138 { "version", no_argument
, NULL
, 'V' },
139 { "alternate-editor", required_argument
, NULL
, 'a' },
140 { "socket-name", required_argument
, NULL
, 's' },
141 { "server-file", required_argument
, NULL
, 'f' },
142 { "display", required_argument
, NULL
, 'd' },
146 /* Decode the options from argv and argc.
147 The global variable `optind' will say how many arguments we used up. */
150 decode_options (argc
, argv
)
154 alternate_editor
= getenv ("ALTERNATE_EDITOR");
155 server_file
= getenv ("EMACS_SERVER_FILE");
159 int opt
= getopt_long (argc
, argv
,
160 "VHnea:s:f:d:", longopts
, 0);
168 /* If getopt returns 0, then it has already processed a
169 long-named option. We should do nothing. */
173 alternate_editor
= optarg
;
177 socket_name
= optarg
;
181 server_file
= optarg
;
197 printf ("emacsclient %s\n", VERSION
);
202 print_help_and_exit ();
206 fprintf (stderr
, "Try `%s --help' for more information\n", progname
);
214 print_help_and_exit ()
217 "Usage: %s [OPTIONS] FILE...\n\
218 Tell the Emacs server to visit the specified files.\n\
219 Every FILE can be either just a FILENAME or [+LINE[:COLUMN]] FILENAME.\n\
221 The following OPTIONS are accepted:\n\
222 -V, --version Just print a version info and return\n\
223 -H, --help Print this usage information message\n\
224 -n, --no-wait Don't wait for the server to return\n\
225 -e, --eval Evaluate the FILE arguments as ELisp expressions\n\
226 -d, --display=DISPLAY Visit the file in the given display\n"
227 #ifndef NO_SOCKETS_IN_FILE_SYSTEM
228 "-s, --socket-name=FILENAME\n\
229 Set the filename of the UNIX socket for communication\n"
231 "-f, --server-file=FILENAME\n\
232 Set the filename of the TCP configuration file\n\
233 -a, --alternate-editor=EDITOR\n\
234 Editor to fallback to if the server is not running\n\
236 Report bugs to bug-gnu-emacs@gnu.org.\n", progname
);
242 Try to run a different command, or --if no alternate editor is
243 defined-- exit with an errorcode.
250 if (alternate_editor
)
254 argv
[i
] = (char *)alternate_editor
;
256 execvp (alternate_editor
, argv
+ i
);
257 fprintf (stderr
, "%s: error executing alternate editor \"%s\"\n",
258 progname
, alternate_editor
);
262 fprintf (stderr
, "%s: No socket or alternate editor. Please use:\n\n"
263 #if !defined (NO_SOCKETS_IN_FILE_SYSTEM)
266 "\t--server-file (or environment variable EMACS_SERVER_FILE)\n\
267 \t--alternate-editor (or environment variable ALTERNATE_EDITOR)\n",
274 #if !defined (HAVE_SOCKETS)
281 fprintf (stderr
, "%s: Sorry, the Emacs server is supported only\n",
283 fprintf (stderr
, "on systems with Berkeley sockets.\n");
288 #else /* HAVE_SOCKETS */
291 # include <winsock2.h>
293 # include <sys/types.h>
294 # include <sys/socket.h>
296 # include <sys/stat.h>
300 #define AUTH_KEY_LENGTH 64
301 #define SEND_BUFFER_SIZE 4096
303 extern char *strerror ();
306 /* Buffer to accumulate data to send in TCP connections. */
307 char send_buffer
[SEND_BUFFER_SIZE
+ 1];
308 int sblen
= 0; /* Fill pointer for the send buffer. */
310 /* Let's send the data to Emacs when either
311 - the data ends in "\n", or
312 - the buffer is full (but this shouldn't happen)
313 Otherwise, we just accumulate it. */
314 void send_to_emacs (s
, data
)
320 int dlen
= strlen (data
);
321 if (dlen
+ sblen
>= SEND_BUFFER_SIZE
)
323 int part
= SEND_BUFFER_SIZE
- sblen
;
324 strncpy (&send_buffer
[sblen
], data
, part
);
326 sblen
= SEND_BUFFER_SIZE
;
330 strcpy (&send_buffer
[sblen
], data
);
337 if (sblen
== SEND_BUFFER_SIZE
338 || (sblen
> 0 && send_buffer
[sblen
-1] == '\n'))
340 int sent
= send (s
, send_buffer
, sblen
, 0);
342 strcpy (send_buffer
, &send_buffer
[sent
]);
348 /* In NAME, insert a & before each &, each space, each newline, and
349 any initial -. Change spaces to underscores, too, so that the
350 return value never contains a space. */
352 quote_file_name (s
, name
)
356 char *copy
= (char *) malloc (strlen (name
) * 2 + 1);
377 if (*p
== '&' || (*p
== '-' && p
== name
))
390 /* Wrapper to make WSACleanup a cdecl, as required by atexit(). */
391 void __cdecl
close_winsock ()
396 void initialize_sockets ()
400 /* Initialize the WinSock2 library. */
401 if (WSAStartup (MAKEWORD (2, 0), &wsaData
))
403 fprintf (stderr
, "%s: error initializing WinSock2", progname
);
407 atexit (close_winsock
);
409 #endif /* WINDOWSNT */
412 * Read the information needed to set up a TCP comm channel with
413 * the Emacs server: host, port and authentication string.
415 int get_server_config (server
, authentication
)
416 struct sockaddr_in
*server
;
417 char *authentication
;
423 if (! (config
= fopen (server_file
, "rb")))
425 char *home
= getenv ("HOME");
428 home
= getenv ("APPDATA");
432 char *path
= alloca (32 + strlen (home
) + strlen (server_file
));
433 sprintf (path
, "%s/.emacs.d/server/%s", home
, server_file
);
434 config
= fopen (path
, "rb");
441 if (fgets (dotted
, sizeof dotted
, config
)
442 && (port
= strchr (dotted
, ':')))
448 fprintf (stderr
, "%s: invalid configuration info", progname
);
452 server
->sin_family
= AF_INET
;
453 server
->sin_addr
.s_addr
= inet_addr (dotted
);
454 server
->sin_port
= htons (atoi (port
));
456 if (! fread (authentication
, AUTH_KEY_LENGTH
, 1, config
))
458 fprintf (stderr
, "%s: cannot read authentication info", progname
);
471 struct sockaddr_in server
;
472 IOCTL_BOOL_ARG c_arg
= 0;
473 struct linger l_arg
= {1, 1};
474 char auth_string
[AUTH_KEY_LENGTH
+ 1];
478 if (! get_server_config (&server
, auth_string
))
479 return INVALID_SOCKET
;
482 * Open up an AF_INET socket
484 if ((s
= socket (AF_INET
, SOCK_STREAM
, IPPROTO_TCP
)) < 0)
486 fprintf (stderr
, "%s: ", progname
);
488 return INVALID_SOCKET
;
494 if (connect (s
, (struct sockaddr
*) &server
, sizeof server
) < 0)
496 fprintf (stderr
, "%s: ", progname
);
498 return INVALID_SOCKET
;
502 IOCTL (s
, O_NONBLOCK
, &c_arg
);
505 IOCTL (s
, O_NDELAY
, &c_arg
);
507 IOCTL (s
, FIONBIO
, &c_arg
);
510 setsockopt (s
, SOL_SOCKET
, SO_LINGER
, (char *) &l_arg
, sizeof l_arg
);
513 * Send the authentication
515 auth_string
[AUTH_KEY_LENGTH
] = '\0';
517 SEND_STRING ("-auth ");
518 SEND_STRING (auth_string
);
524 #if !defined (NO_SOCKETS_IN_FILE_SYSTEM)
526 /* Three possibilities:
527 2 - can't be `stat'ed (sets errno)
528 1 - isn't owned by us
529 0 - success: none of the above */
532 socket_status (socket_name
)
537 if (stat (socket_name
, &statbfr
) == -1)
540 if (statbfr
.st_uid
!= geteuid ())
550 struct sockaddr_un server
;
553 * Open up an AF_UNIX socket in this person's home directory
556 if ((s
= socket (AF_UNIX
, SOCK_STREAM
, 0)) < 0)
558 fprintf (stderr
, "%s: ", progname
);
560 return INVALID_SOCKET
;
563 server
.sun_family
= AF_UNIX
;
567 int default_sock
= !socket_name
;
569 char *server_name
= "server";
571 if (socket_name
&& !index (socket_name
, '/') && !index (socket_name
, '\\'))
572 { /* socket_name is a file name component. */
573 server_name
= socket_name
;
575 default_sock
= 1; /* Try both UIDs. */
580 socket_name
= alloca (100 + strlen (server_name
));
581 sprintf (socket_name
, "/tmp/emacs%d/%s",
582 (int) geteuid (), server_name
);
585 if (strlen (socket_name
) < sizeof (server
.sun_path
))
586 strcpy (server
.sun_path
, socket_name
);
589 fprintf (stderr
, "%s: socket-name %s too long",
590 progname
, socket_name
);
594 /* See if the socket exists, and if it's owned by us. */
595 sock_status
= socket_status (server
.sun_path
);
597 if (sock_status
&& default_sock
)
599 /* Failing that, see if LOGNAME or USER exist and differ from
600 our euid. If so, look for a socket based on the UID
601 associated with the name. This is reminiscent of the logic
602 that init_editfns uses to set the global Vuser_full_name. */
604 char *user_name
= (char *) getenv ("LOGNAME");
607 user_name
= (char *) getenv ("USER");
611 struct passwd
*pw
= getpwnam (user_name
);
613 if (pw
&& (pw
->pw_uid
!= geteuid ()))
615 /* We're running under su, apparently. */
616 socket_name
= alloca (100 + strlen (server_name
));
617 sprintf (socket_name
, "/tmp/emacs%d/%s",
618 (int) pw
->pw_uid
, server_name
);
620 if (strlen (socket_name
) < sizeof (server
.sun_path
))
621 strcpy (server
.sun_path
, socket_name
);
624 fprintf (stderr
, "%s: socket-name %s too long",
625 progname
, socket_name
);
629 sock_status
= socket_status (server
.sun_path
);
640 /* There's a socket, but it isn't owned by us. This is OK if
644 fprintf (stderr
, "%s: Invalid socket owner\n", progname
);
645 return INVALID_SOCKET
;
651 if (saved_errno
== ENOENT
)
653 "%s: can't find socket; have you started the server?\n\
654 To start the server in Emacs, type \"M-x server-start\".\n",
657 fprintf (stderr
, "%s: can't stat %s: %s\n",
658 progname
, server
.sun_path
, strerror (saved_errno
));
659 return INVALID_SOCKET
;
663 if (connect (s
, (struct sockaddr
*) &server
, strlen (server
.sun_path
) + 2)
666 fprintf (stderr
, "%s: ", progname
);
668 return INVALID_SOCKET
;
673 #endif /* ! NO_SOCKETS_IN_FILE_SYSTEM */
679 return set_tcp_socket ();
681 #ifndef NO_SOCKETS_IN_FILE_SYSTEM
682 return set_local_socket ();
685 server_file
= "server";
686 return set_tcp_socket ();
697 int i
, rl
, needlf
= 0;
699 char string
[BUFSIZ
+1];
703 /* Process options. */
704 decode_options (argc
, argv
);
706 if ((argc
- optind
< 1) && !eval
)
708 fprintf (stderr
, "%s: file name or argument required\n", progname
);
709 fprintf (stderr
, "Try `%s --help' for more information\n", progname
);
713 if ((s
= set_socket ()) == INVALID_SOCKET
)
717 cwd
= getcwd (string
, sizeof string
);
719 cwd
= getwd (string
);
723 /* getwd puts message in STRING if it fails. */
725 fprintf (stderr
, "%s: %s (%s)\n", progname
,
726 "Cannot get current working directory", strerror (errno
));
728 fprintf (stderr
, "%s: %s (%s)\n", progname
, string
, strerror (errno
));
734 SEND_STRING ("-nowait ");
737 SEND_STRING ("-eval ");
741 SEND_STRING ("-display ");
742 SEND_QUOTED (display
);
746 if ((argc
- optind
> 0))
748 for (i
= optind
; i
< argc
; i
++)
751 ; /* Don't prepend any cwd or anything like that. */
752 else if (*argv
[i
] == '+')
754 char *p
= argv
[i
] + 1;
755 while (isdigit ((unsigned char) *p
) || *p
== ':') p
++;
763 else if (*argv
[i
] != '/')
765 else if ((*argv
[i
] != '/')
766 /* Absolute paths can also start with backslash
768 && (*argv
[i
] != '\\')
769 && (!islower (tolower (*argv
[i
]))
770 || (argv
[i
][1] != ':')))
777 SEND_QUOTED (argv
[i
]);
783 while (fgets (string
, BUFSIZ
, stdin
))
785 SEND_QUOTED (string
);
792 /* Maybe wait for an answer. */
797 printf ("Waiting for Emacs...");
802 /* Now, wait for an answer and print any messages. */
803 while ((rl
= recv (s
, string
, BUFSIZ
, 0)) > 0)
808 printf ("%s", string
);
809 needlf
= string
[0] == '\0' ? needlf
: string
[strlen (string
) - 1] != '\n';
821 #endif /* HAVE_SOCKETS */
823 #ifndef HAVE_STRERROR
828 extern char *sys_errlist
[];
831 if (errnum
>= 0 && errnum
< sys_nerr
)
832 return sys_errlist
[errnum
];
833 return (char *) "Unknown error";
836 #endif /* ! HAVE_STRERROR */
838 /* arch-tag: f39bb9c4-73eb-477e-896d-50832e2ca9a7
839 (do not change this comment) */
841 /* emacsclient.c ends here */