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