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