Fixes to emacsclient.c for GNU/Linux.
[bpt/emacs.git] / lib-src / emacsclient.c
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.
4
5 This file is part of GNU Emacs.
6
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)
10 any later version.
11
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.
16
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. */
21
22
23 #define NO_SHORTNAMES
24
25 #ifdef HAVE_CONFIG_H
26 #include <config.h>
27 #endif
28
29 #ifdef WINDOWSNT
30 #define HAVE_SOCKETS
31 #define NO_SOCKETS_IN_FILE_SYSTEM
32 #endif
33
34 #ifdef WINDOWSNT
35 # define HSOCKET SOCKET
36 # define CLOSE_SOCKET closesocket
37 # define IOCTL ioctlsocket
38 # define INITIALIZE() (initialize_sockets ())
39 typedef unsigned long IOCTL_BOOL_ARG;
40 #else
41 # include <netinet/in.h>
42 # include <sys/ioctl.h>
43 # define INVALID_SOCKET -1
44 # define HSOCKET int
45 # define CLOSE_SOCKET close
46 # define IOCTL ioctl
47 # define INITIALIZE()
48 typedef int IOCTL_BOOL_ARG;
49 #endif
50
51 #undef signal
52
53 #include <ctype.h>
54 #include <stdio.h>
55 #include "getopt.h"
56 #ifdef HAVE_UNISTD_H
57 #include <unistd.h>
58 #endif
59
60 #ifdef VMS
61 # include "vms-pwd.h"
62 #else /* not VMS */
63 #ifdef WINDOWSNT
64 # include <io.h>
65 #else /* not WINDOWSNT */
66 # include <pwd.h>
67 #endif /* not WINDOWSNT */
68 #endif /* not VMS */
69
70 char *getenv (), *getwd ();
71 char *(getcwd) ();
72
73 #ifndef VERSION
74 #define VERSION "unspecified"
75 #endif
76 \f
77 #define SEND_STRING(data) (send_to_emacs (s, (data)))
78 #define SEND_QUOTED(data) (quote_file_name (s, (data)))
79
80 #ifndef EXIT_SUCCESS
81 #define EXIT_SUCCESS 0
82 #endif
83
84 #ifndef EXIT_FAILURE
85 #define EXIT_FAILURE 1
86 #endif
87
88 #ifndef FALSE
89 #define FALSE 0
90 #endif
91
92 #ifndef TRUE
93 #define TRUE 1
94 #endif
95
96 #ifndef NO_RETURN
97 #define NO_RETURN
98 #endif
99 \f
100 /* Name used to invoke this program. */
101 char *progname;
102
103 /* Nonzero means don't wait for a response from Emacs. --no-wait. */
104 int nowait = 0;
105
106 /* Nonzero means args are expressions to be evaluated. --eval. */
107 int eval = 0;
108
109 /* The display on which Emacs should work. --display. */
110 char *display = NULL;
111
112 /* If non-NULL, the name of an editor to fallback to if the server
113 is not running. --alternate-editor. */
114 const char * alternate_editor = NULL;
115
116 /* If non-NULL, the filename of the UNIX socket. */
117 char *socket_name = NULL;
118
119 /* If non-NULL, the filename of the authentication file. */
120 char *server_file = NULL;
121
122 void print_help_and_exit () NO_RETURN;
123
124 struct option longopts[] =
125 {
126 { "no-wait", no_argument, NULL, 'n' },
127 { "eval", no_argument, NULL, 'e' },
128 { "help", no_argument, NULL, 'H' },
129 { "version", no_argument, NULL, 'V' },
130 { "alternate-editor", required_argument, NULL, 'a' },
131 { "socket-name", required_argument, NULL, 's' },
132 { "server-file", required_argument, NULL, 'f' },
133 { "display", required_argument, NULL, 'd' },
134 { 0, 0, 0, 0 }
135 };
136
137 /* Decode the options from argv and argc.
138 The global variable `optind' will say how many arguments we used up. */
139
140 void
141 decode_options (argc, argv)
142 int argc;
143 char **argv;
144 {
145 alternate_editor = getenv ("ALTERNATE_EDITOR");
146 server_file = getenv ("EMACS_SERVER_FILE");
147
148 while (1)
149 {
150 int opt = getopt_long (argc, argv,
151 "VHnea:s:f:d:", longopts, 0);
152
153 if (opt == EOF)
154 break;
155
156 switch (opt)
157 {
158 case 0:
159 /* If getopt returns 0, then it has already processed a
160 long-named option. We should do nothing. */
161 break;
162
163 case 'a':
164 alternate_editor = optarg;
165 break;
166
167 case 's':
168 socket_name = optarg;
169 break;
170
171 case 'f':
172 server_file = optarg;
173 break;
174
175 case 'd':
176 display = optarg;
177 break;
178
179 case 'n':
180 nowait = 1;
181 break;
182
183 case 'e':
184 eval = 1;
185 break;
186
187 case 'V':
188 printf ("emacsclient %s\n", VERSION);
189 exit (EXIT_SUCCESS);
190 break;
191
192 case 'H':
193 print_help_and_exit ();
194 break;
195
196 default:
197 fprintf (stderr, "Try `%s --help' for more information\n", progname);
198 exit (EXIT_FAILURE);
199 break;
200 }
201 }
202 }
203
204 void
205 print_help_and_exit ()
206 {
207 printf (
208 "Usage: %s [OPTIONS] FILE...\n\
209 Tell the Emacs server to visit the specified files.\n\
210 Every FILE can be either just a FILENAME or [+LINE[:COLUMN]] FILENAME.\n\
211 \n\
212 The following OPTIONS are accepted:\n\
213 -V, --version Just print a version info and return\n\
214 -H, --help Print this usage information message\n\
215 -n, --no-wait Don't wait for the server to return\n\
216 -e, --eval Evaluate the FILE arguments as ELisp expressions\n\
217 -d, --display=DISPLAY Visit the file in the given display\n"
218 #ifndef NO_SOCKETS_IN_FILE_SYSTEM
219 "-s, --socket-name=FILENAME\n\
220 Set the filename of the UNIX socket for communication\n"
221 #endif
222 "-f, --server-file=FILENAME\n\
223 Set the filename of the TCP configuration file\n\
224 -a, --alternate-editor=EDITOR\n\
225 Editor to fallback to if the server is not running\n\
226 \n\
227 Report bugs to bug-gnu-emacs@gnu.org.\n", progname);
228 exit (EXIT_SUCCESS);
229 }
230
231 \f
232 /*
233 Try to run a different command, or --if no alternate editor is
234 defined-- exit with an errorcode.
235 */
236 void
237 fail (argc, argv)
238 int argc;
239 char **argv;
240 {
241 if (alternate_editor)
242 {
243 int i = optind - 1;
244 execvp (alternate_editor, argv + i);
245 fprintf (stderr, "%s: error executing alternate editor \"%s\"\n",
246 progname, alternate_editor);
247 }
248 else
249 {
250 fprintf (stderr, "%s: No socket or alternate editor. Please use:\n\n"
251 #if !defined (NO_SOCKETS_IN_FILE_SYSTEM)
252 "\t--socket-name\n"
253 #endif
254 "\t--server-file (or environment variable EMACS_SERVER_FILE)\n\
255 \t--alternate-editor (or environment variable ALTERNATE_EDITOR)\n",
256 progname);
257 }
258 exit (EXIT_FAILURE);
259 }
260
261 \f
262 #if !defined (HAVE_SOCKETS)
263
264 int
265 main (argc, argv)
266 int argc;
267 char **argv;
268 {
269 fprintf (stderr, "%s: Sorry, the Emacs server is supported only\n",
270 argv[0]);
271 fprintf (stderr, "on systems with Berkeley sockets.\n");
272
273 fail (argc, argv);
274 }
275
276 #else /* HAVE_SOCKETS */
277
278 #ifdef WINDOWSNT
279 # include <winsock2.h>
280 #else
281 # include <sys/types.h>
282 # include <sys/socket.h>
283 # include <sys/un.h>
284 # include <sys/stat.h>
285 # include <errno.h>
286 #endif
287
288 #define AUTH_KEY_LENGTH 64
289 #define SEND_BUFFER_SIZE 4096
290
291 extern char *strerror ();
292 extern int errno;
293
294 /* Buffer to accumulate data to send in TCP connections. */
295 char send_buffer[SEND_BUFFER_SIZE + 1];
296 int sblen = 0; /* Fill pointer for the send buffer. */
297
298 /* Let's send the data to Emacs when either
299 - the data ends in "\n", or
300 - the buffer is full (but this shouldn't happen)
301 Otherwise, we just accumulate it. */
302 void send_to_emacs (s, data)
303 HSOCKET s;
304 char *data;
305 {
306 while (data)
307 {
308 int dlen = strlen (data);
309 if (dlen + sblen >= SEND_BUFFER_SIZE)
310 {
311 int part = SEND_BUFFER_SIZE - sblen;
312 strncpy (&send_buffer[sblen], data, part);
313 data += part;
314 sblen = SEND_BUFFER_SIZE;
315 }
316 else if (dlen)
317 {
318 strcpy (&send_buffer[sblen], data);
319 data = NULL;
320 sblen += dlen;
321 }
322 else
323 break;
324
325 if (sblen == SEND_BUFFER_SIZE
326 || (sblen > 0 && send_buffer[sblen-1] == '\n'))
327 {
328 int sent = send (s, send_buffer, sblen, 0);
329 if (sent != sblen)
330 strcpy (send_buffer, &send_buffer[sent]);
331 sblen -= sent;
332 }
333 }
334 }
335
336 /* In NAME, insert a & before each &, each space, each newline, and
337 any initial -. Change spaces to underscores, too, so that the
338 return value never contains a space. */
339 void
340 quote_file_name (s, name)
341 HSOCKET s;
342 char *name;
343 {
344 char *copy = (char *) malloc (strlen (name) * 2 + 1);
345 char *p, *q;
346
347 p = name;
348 q = copy;
349 while (*p)
350 {
351 if (*p == ' ')
352 {
353 *q++ = '&';
354 *q++ = '_';
355 p++;
356 }
357 else if (*p == '\n')
358 {
359 *q++ = '&';
360 *q++ = 'n';
361 p++;
362 }
363 else
364 {
365 if (*p == '&' || (*p == '-' && p == name))
366 *q++ = '&';
367 *q++ = *p++;
368 }
369 }
370 *q++ = 0;
371
372 SEND_STRING (copy);
373
374 free (copy);
375 }
376
377 #ifdef WINDOWSNT
378 /* Wrapper to make WSACleanup a cdecl, as required by atexit(). */
379 void close_winsock ()
380 {
381 WSACleanup ();
382 }
383
384 void initialize_sockets ()
385 {
386 WSADATA wsaData;
387
388 /* Initialize the WinSock2 library. */
389 if (WSAStartup (MAKEWORD (2, 0), &wsaData))
390 {
391 fprintf (stderr, "%s: error initializing WinSock2", progname);
392 exit (EXIT_FAILURE);
393 }
394
395 atexit (close_winsock);
396 }
397 #endif /* WINDOWSNT */
398 \f
399 /*
400 * Read the information needed to set up a TCP comm channel with
401 * the Emacs server: host, port and authentication string.
402 */
403 int get_server_config (server, authentication)
404 struct sockaddr_in *server;
405 char *authentication;
406 {
407 FILE *config;
408 char dotted[32];
409 char *port;
410
411 if (! (config = fopen (server_file, "rb")))
412 {
413 char *home = getenv ("HOME");
414 #ifdef WINDOWSNT
415 if (! home)
416 home = getenv ("APPDATA");
417 #endif
418 if (home)
419 {
420 char *path = alloca (32 + strlen (home) + strlen (server_file));
421 sprintf (path, "%s/.emacs.d/server/%s", home, server_file);
422 config = fopen (path, "rb");
423 }
424 }
425
426 if (! config)
427 return FALSE;
428
429 if (fgets (dotted, sizeof dotted, config)
430 && (port = strchr (dotted, ':')))
431 {
432 *port++ = '\0';
433 }
434 else
435 {
436 fprintf (stderr, "%s: invalid configuration info", progname);
437 exit (EXIT_FAILURE);
438 }
439
440 server->sin_family = AF_INET;
441 server->sin_addr.s_addr = inet_addr (dotted);
442 server->sin_port = htons (atoi (port));
443
444 if (! fread (authentication, AUTH_KEY_LENGTH, 1, config))
445 {
446 fprintf (stderr, "%s: cannot read authentication info", progname);
447 exit (EXIT_FAILURE);
448 }
449
450 fclose (config);
451
452 return TRUE;
453 }
454
455 HSOCKET
456 set_tcp_socket ()
457 {
458 HSOCKET s;
459 struct sockaddr_in server;
460 IOCTL_BOOL_ARG c_arg = 0;
461 struct linger l_arg = {1, 1};
462 char auth_string[AUTH_KEY_LENGTH + 1];
463
464 INITIALIZE ();
465
466 if (! get_server_config (&server, auth_string))
467 return INVALID_SOCKET;
468
469 /*
470 * Open up an AF_INET socket
471 */
472 if ((s = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
473 {
474 fprintf (stderr, "%s: ", progname);
475 perror ("socket");
476 return INVALID_SOCKET;
477 }
478
479 /*
480 * Set up the socket
481 */
482 if (connect (s, (struct sockaddr *) &server, sizeof server) < 0)
483 {
484 fprintf (stderr, "%s: ", progname);
485 perror ("connect");
486 return INVALID_SOCKET;
487 }
488
489 IOCTL (s, FIONBIO, &c_arg);
490 setsockopt (s, SOL_SOCKET, SO_LINGER, (char *) &l_arg, sizeof l_arg);
491
492 /*
493 * Send the authentication
494 */
495 auth_string[AUTH_KEY_LENGTH] = '\0';
496
497 SEND_STRING ("-auth ");
498 SEND_STRING (auth_string);
499 SEND_STRING ("\n");
500
501 return s;
502 }
503
504 #if !defined (NO_SOCKETS_IN_FILE_SYSTEM)
505
506 /* Three possibilities:
507 2 - can't be `stat'ed (sets errno)
508 1 - isn't owned by us
509 0 - success: none of the above */
510
511 static int
512 socket_status (socket_name)
513 char *socket_name;
514 {
515 struct stat statbfr;
516
517 if (stat (socket_name, &statbfr) == -1)
518 return 2;
519
520 if (statbfr.st_uid != geteuid ())
521 return 1;
522
523 return 0;
524 }
525
526 HSOCKET
527 set_local_socket ()
528 {
529 HSOCKET s;
530 struct sockaddr_un server;
531
532 /*
533 * Open up an AF_UNIX socket in this person's home directory
534 */
535
536 if ((s = socket (AF_UNIX, SOCK_STREAM, 0)) < 0)
537 {
538 fprintf (stderr, "%s: ", progname);
539 perror ("socket");
540 return INVALID_SOCKET;
541 }
542
543 server.sun_family = AF_UNIX;
544
545 {
546 int sock_status = 0;
547 int default_sock = !socket_name;
548 int saved_errno;
549 char *server_name = "server";
550
551 if (socket_name && !index (socket_name, '/') && !index (socket_name, '\\'))
552 { /* socket_name is a file name component. */
553 server_name = socket_name;
554 socket_name = NULL;
555 default_sock = 1; /* Try both UIDs. */
556 }
557
558 if (default_sock)
559 {
560 socket_name = alloca (100 + strlen (server_name));
561 sprintf (socket_name, "/tmp/emacs%d/%s",
562 (int) geteuid (), server_name);
563 }
564
565 if (strlen (socket_name) < sizeof (server.sun_path))
566 strcpy (server.sun_path, socket_name);
567 else
568 {
569 fprintf (stderr, "%s: socket-name %s too long",
570 progname, socket_name);
571 exit (EXIT_FAILURE);
572 }
573
574 /* See if the socket exists, and if it's owned by us. */
575 sock_status = socket_status (server.sun_path);
576 saved_errno = errno;
577 if (sock_status && default_sock)
578 {
579 /* Failing that, see if LOGNAME or USER exist and differ from
580 our euid. If so, look for a socket based on the UID
581 associated with the name. This is reminiscent of the logic
582 that init_editfns uses to set the global Vuser_full_name. */
583
584 char *user_name = (char *) getenv ("LOGNAME");
585
586 if (!user_name)
587 user_name = (char *) getenv ("USER");
588
589 if (user_name)
590 {
591 struct passwd *pw = getpwnam (user_name);
592
593 if (pw && (pw->pw_uid != geteuid ()))
594 {
595 /* We're running under su, apparently. */
596 socket_name = alloca (100 + strlen (server_name));
597 sprintf (socket_name, "/tmp/emacs%d/%s",
598 (int) pw->pw_uid, server_name);
599
600 if (strlen (socket_name) < sizeof (server.sun_path))
601 strcpy (server.sun_path, socket_name);
602 else
603 {
604 fprintf (stderr, "%s: socket-name %s too long",
605 progname, socket_name);
606 exit (EXIT_FAILURE);
607 }
608
609 sock_status = socket_status (server.sun_path);
610 saved_errno = errno;
611 }
612 else
613 errno = saved_errno;
614 }
615 }
616
617 switch (sock_status)
618 {
619 case 1:
620 /* There's a socket, but it isn't owned by us. This is OK if
621 we are root. */
622 if (0 != geteuid ())
623 {
624 fprintf (stderr, "%s: Invalid socket owner\n", progname);
625 return INVALID_SOCKET;
626 }
627 break;
628
629 case 2:
630 /* `stat' failed */
631 if (saved_errno == ENOENT)
632 fprintf (stderr,
633 "%s: can't find socket; have you started the server?\n\
634 To start the server in Emacs, type \"M-x server-start\".\n",
635 progname);
636 else
637 fprintf (stderr, "%s: can't stat %s: %s\n",
638 progname, server.sun_path, strerror (saved_errno));
639 return INVALID_SOCKET;
640 }
641 }
642
643 if (connect (s, (struct sockaddr *) &server, strlen (server.sun_path) + 2)
644 < 0)
645 {
646 fprintf (stderr, "%s: ", progname);
647 perror ("connect");
648 return INVALID_SOCKET;
649 }
650
651 return s;
652 }
653 #endif /* ! NO_SOCKETS_IN_FILE_SYSTEM */
654
655 HSOCKET
656 set_socket ()
657 {
658 if (server_file)
659 return set_tcp_socket ();
660 else
661 #ifndef NO_SOCKETS_IN_FILE_SYSTEM
662 return set_local_socket ();
663 #else
664 {
665 server_file = "server";
666 return set_tcp_socket ();
667 }
668 #endif
669 }
670
671 int
672 main (argc, argv)
673 int argc;
674 char **argv;
675 {
676 HSOCKET s;
677 int i, rl, needlf = 0;
678 char *cwd;
679 char string[BUFSIZ+1];
680
681 progname = argv[0];
682
683 /* Process options. */
684 decode_options (argc, argv);
685
686 if ((argc - optind < 1) && !eval)
687 {
688 fprintf (stderr, "%s: file name or argument required\n", progname);
689 fprintf (stderr, "Try `%s --help' for more information\n", progname);
690 exit (EXIT_FAILURE);
691 }
692
693 if ((s = set_socket ()) == INVALID_SOCKET)
694 fail (argc, argv);
695
696 #ifdef HAVE_GETCWD
697 cwd = getcwd (string, sizeof string);
698 #else
699 cwd = getwd (string);
700 #endif
701 if (cwd == 0)
702 {
703 /* getwd puts message in STRING if it fails. */
704 #ifdef HAVE_GETCWD
705 fprintf (stderr, "%s: %s (%s)\n", progname,
706 "Cannot get current working directory", strerror (errno));
707 #else
708 fprintf (stderr, "%s: %s (%s)\n", progname, string, strerror (errno));
709 #endif
710 fail (argc, argv);
711 }
712
713 if (nowait)
714 SEND_STRING ("-nowait ");
715
716 if (eval)
717 SEND_STRING ("-eval ");
718
719 if (display)
720 {
721 SEND_STRING ("-display ");
722 SEND_QUOTED (display);
723 SEND_STRING (" ");
724 }
725
726 if ((argc - optind > 0))
727 {
728 for (i = optind; i < argc; i++)
729 {
730 if (eval)
731 ; /* Don't prepend any cwd or anything like that. */
732 else if (*argv[i] == '+')
733 {
734 char *p = argv[i] + 1;
735 while (isdigit ((unsigned char) *p) || *p == ':') p++;
736 if (*p != 0)
737 {
738 SEND_QUOTED (cwd);
739 SEND_STRING ("/");
740 }
741 }
742 #ifndef WINDOWSNT
743 else if (*argv[i] != '/')
744 #else
745 else if ((*argv[i] != '/')
746 /* Absolute paths can also start with backslash
747 or drive letters. */
748 && (*argv[i] != '\\')
749 && (!islower (tolower (*argv[i]))
750 || (argv[i][1] != ':')))
751 #endif
752 {
753 SEND_QUOTED (cwd);
754 SEND_STRING ("/");
755 }
756
757 SEND_QUOTED (argv[i]);
758 SEND_STRING (" ");
759 }
760 }
761 else
762 {
763 while (fgets (string, BUFSIZ, stdin))
764 {
765 SEND_QUOTED (string);
766 }
767 SEND_STRING (" ");
768 }
769
770 SEND_STRING ("\n");
771
772 /* Maybe wait for an answer. */
773 if (!nowait)
774 {
775 if (!eval)
776 {
777 printf ("Waiting for Emacs...");
778 needlf = 2;
779 }
780 fflush (stdout);
781
782 /* Now, wait for an answer and print any messages. */
783 while ((rl = recv (s, string, BUFSIZ, 0)) > 0)
784 {
785 string[rl] = '\0';
786 if (needlf == 2)
787 printf ("\n");
788 printf ("%s", string);
789 needlf = string[0] == '\0' ? needlf : string[strlen (string) - 1] != '\n';
790 }
791
792 if (needlf)
793 printf ("\n");
794 fflush (stdout);
795 }
796
797 CLOSE_SOCKET (s);
798 return EXIT_SUCCESS;
799 }
800
801 #endif /* HAVE_SOCKETS */
802
803 #ifndef HAVE_STRERROR
804 char *
805 strerror (errnum)
806 int errnum;
807 {
808 extern char *sys_errlist[];
809 extern int sys_nerr;
810
811 if (errnum >= 0 && errnum < sys_nerr)
812 return sys_errlist[errnum];
813 return (char *) "Unknown error";
814 }
815
816 #endif /* ! HAVE_STRERROR */
817
818 /* arch-tag: f39bb9c4-73eb-477e-896d-50832e2ca9a7
819 (do not change this comment) */
820
821 /* emacsclient.c ends here */