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