(server-process-filter): Don't force the authentication
[bpt/emacs.git] / lib-src / emacsclient.c
... / ...
CommitLineData
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, 2007, 2008 Free Software Foundation, Inc.
4
5This file is part of GNU Emacs.
6
7GNU Emacs is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 3, or (at your option)
10any later version.
11
12GNU Emacs is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GNU Emacs; see the file COPYING. If not, write to
19the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20Boston, 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/* config.h defines these, which disables sockets altogether! */
32# undef _WINSOCKAPI_
33# undef _WINSOCK_H
34
35# include <malloc.h>
36# include <stdlib.h>
37# include <windows.h>
38# include <commctrl.h>
39
40# define NO_SOCKETS_IN_FILE_SYSTEM
41
42# define HSOCKET SOCKET
43# define CLOSE_SOCKET closesocket
44# define INITIALIZE() (initialize_sockets ())
45
46#else /* !WINDOWSNT */
47
48# include <sys/types.h>
49
50# ifdef HAVE_INET_SOCKETS
51# include <netinet/in.h>
52# endif
53
54# define INVALID_SOCKET -1
55# define HSOCKET int
56# define CLOSE_SOCKET close
57# define INITIALIZE()
58
59#endif /* !WINDOWSNT */
60
61#undef signal
62
63#include <stdarg.h>
64#include <ctype.h>
65#include <stdio.h>
66#include "getopt.h"
67#ifdef HAVE_UNISTD_H
68#include <unistd.h>
69#endif
70
71#ifdef VMS
72# include "vms-pwd.h"
73#else /* not VMS */
74#ifdef WINDOWSNT
75# include <io.h>
76#else /* not WINDOWSNT */
77# include <pwd.h>
78#endif /* not WINDOWSNT */
79#endif /* not VMS */
80#include <sys/stat.h>
81
82#include <signal.h>
83#include <errno.h>
84
85\f
86char *getenv (), *getwd ();
87char *(getcwd) ();
88
89#ifdef WINDOWSNT
90char *w32_getenv ();
91#define egetenv(VAR) w32_getenv(VAR)
92#else
93#define egetenv(VAR) getenv(VAR)
94#endif
95
96#ifndef VERSION
97#define VERSION "unspecified"
98#endif
99\f
100
101#ifndef EXIT_SUCCESS
102#define EXIT_SUCCESS 0
103#endif
104
105#ifndef EXIT_FAILURE
106#define EXIT_FAILURE 1
107#endif
108
109#ifndef FALSE
110#define FALSE 0
111#endif
112
113#ifndef TRUE
114#define TRUE 1
115#endif
116
117#ifndef NO_RETURN
118#define NO_RETURN
119#endif
120\f
121/* Name used to invoke this program. */
122char *progname;
123
124/* The second argument to main. */
125char **main_argv;
126
127/* Nonzero means don't wait for a response from Emacs. --no-wait. */
128int nowait = 0;
129
130/* Nonzero means args are expressions to be evaluated. --eval. */
131int eval = 0;
132
133/* Nonzero means don't open a new frame. Inverse of --create-frame. */
134int current_frame = 1;
135
136/* Nonzero means open a new graphical frame. */
137int window_system = 0;
138
139/* The display on which Emacs should work. --display. */
140char *display = NULL;
141
142/* Nonzero means open a new Emacs frame on the current terminal. */
143int tty = 0;
144
145/* If non-NULL, the name of an editor to fallback to if the server
146 is not running. --alternate-editor. */
147const char *alternate_editor = NULL;
148
149/* If non-NULL, the filename of the UNIX socket. */
150char *socket_name = NULL;
151
152/* If non-NULL, the filename of the authentication file. */
153char *server_file = NULL;
154
155/* PID of the Emacs server process. */
156int emacs_pid = 0;
157
158void print_help_and_exit () NO_RETURN;
159
160struct option longopts[] =
161{
162 { "no-wait", no_argument, NULL, 'n' },
163 { "eval", no_argument, NULL, 'e' },
164 { "help", no_argument, NULL, 'H' },
165 { "version", no_argument, NULL, 'V' },
166 { "tty", no_argument, NULL, 't' },
167 { "create-frame", no_argument, NULL, 'c' },
168 { "alternate-editor", required_argument, NULL, 'a' },
169#ifndef NO_SOCKETS_IN_FILE_SYSTEM
170 { "socket-name", required_argument, NULL, 's' },
171#endif
172 { "server-file", required_argument, NULL, 'f' },
173#ifndef WINDOWSNT
174 { "display", required_argument, NULL, 'd' },
175#endif
176 { 0, 0, 0, 0 }
177};
178
179\f
180/* Like malloc but get fatal error if memory is exhausted. */
181
182long *
183xmalloc (size)
184 unsigned int size;
185{
186 long *result = (long *) malloc (size);
187 if (result == NULL)
188 {
189 perror ("malloc");
190 exit (EXIT_FAILURE);
191 }
192 return result;
193}
194
195/* Like strdup but get a fatal error if memory is exhausted. */
196
197char *
198xstrdup (const char *s)
199{
200 char *result = strdup (s);
201 if (result == NULL)
202 {
203 perror ("strdup");
204 exit (EXIT_FAILURE);
205 }
206 return result;
207}
208
209/* From sysdep.c */
210#if !defined (HAVE_GET_CURRENT_DIR_NAME) || defined (BROKEN_GET_CURRENT_DIR_NAME)
211
212/* From lisp.h */
213#ifndef DIRECTORY_SEP
214#define DIRECTORY_SEP '/'
215#endif
216#ifndef IS_DIRECTORY_SEP
217#define IS_DIRECTORY_SEP(_c_) ((_c_) == DIRECTORY_SEP)
218#endif
219#ifndef IS_DEVICE_SEP
220#ifndef DEVICE_SEP
221#define IS_DEVICE_SEP(_c_) 0
222#else
223#define IS_DEVICE_SEP(_c_) ((_c_) == DEVICE_SEP)
224#endif
225#endif
226#ifndef IS_ANY_SEP
227#define IS_ANY_SEP(_c_) (IS_DIRECTORY_SEP (_c_))
228#endif
229
230
231/* Return the current working directory. Returns NULL on errors.
232 Any other returned value must be freed with free. This is used
233 only when get_current_dir_name is not defined on the system. */
234char*
235get_current_dir_name ()
236{
237 char *buf;
238 char *pwd;
239 struct stat dotstat, pwdstat;
240 /* If PWD is accurate, use it instead of calling getwd. PWD is
241 sometimes a nicer name, and using it may avoid a fatal error if a
242 parent directory is searchable but not readable. */
243 if ((pwd = egetenv ("PWD")) != 0
244 && (IS_DIRECTORY_SEP (*pwd) || (*pwd && IS_DEVICE_SEP (pwd[1])))
245 && stat (pwd, &pwdstat) == 0
246 && stat (".", &dotstat) == 0
247 && dotstat.st_ino == pwdstat.st_ino
248 && dotstat.st_dev == pwdstat.st_dev
249#ifdef MAXPATHLEN
250 && strlen (pwd) < MAXPATHLEN
251#endif
252 )
253 {
254 buf = (char *) xmalloc (strlen (pwd) + 1);
255 if (!buf)
256 return NULL;
257 strcpy (buf, pwd);
258 }
259#ifdef HAVE_GETCWD
260 else
261 {
262 size_t buf_size = 1024;
263 buf = (char *) xmalloc (buf_size);
264 if (!buf)
265 return NULL;
266 for (;;)
267 {
268 if (getcwd (buf, buf_size) == buf)
269 break;
270 if (errno != ERANGE)
271 {
272 int tmp_errno = errno;
273 free (buf);
274 errno = tmp_errno;
275 return NULL;
276 }
277 buf_size *= 2;
278 buf = (char *) realloc (buf, buf_size);
279 if (!buf)
280 return NULL;
281 }
282 }
283#else
284 else
285 {
286 /* We need MAXPATHLEN here. */
287 buf = (char *) xmalloc (MAXPATHLEN + 1);
288 if (!buf)
289 return NULL;
290 if (getwd (buf) == NULL)
291 {
292 int tmp_errno = errno;
293 free (buf);
294 errno = tmp_errno;
295 return NULL;
296 }
297 }
298#endif
299 return buf;
300}
301#endif
302
303#ifdef WINDOWSNT
304
305#define REG_ROOT "SOFTWARE\\GNU\\Emacs"
306
307/* Retrieve an environment variable from the Emacs subkeys of the registry.
308 Return NULL if the variable was not found, or it was empty.
309 This code is based on w32_get_resource (w32.c). */
310char *
311w32_get_resource (predefined, key, type)
312 HKEY predefined;
313 char *key;
314 LPDWORD type;
315{
316 HKEY hrootkey = NULL;
317 char *result = NULL;
318 DWORD cbData;
319
320 if (RegOpenKeyEx (predefined, REG_ROOT, 0, KEY_READ, &hrootkey) == ERROR_SUCCESS)
321 {
322 if (RegQueryValueEx (hrootkey, key, NULL, NULL, NULL, &cbData) == ERROR_SUCCESS)
323 {
324 result = (char *) xmalloc (cbData);
325
326 if ((RegQueryValueEx (hrootkey, key, NULL, type, result, &cbData) != ERROR_SUCCESS) ||
327 (*result == 0))
328 {
329 free (result);
330 result = NULL;
331 }
332 }
333
334 RegCloseKey (hrootkey);
335 }
336
337 return result;
338}
339
340/*
341 getenv wrapper for Windows
342
343 This is needed to duplicate Emacs's behavior, which is to look for enviroment
344 variables in the registry if they don't appear in the environment.
345*/
346char *
347w32_getenv (envvar)
348 char *envvar;
349{
350 char *value;
351 DWORD dwType;
352
353 if (value = getenv (envvar))
354 /* Found in the environment. */
355 return value;
356
357 if (! (value = w32_get_resource (HKEY_CURRENT_USER, envvar, &dwType)) &&
358 ! (value = w32_get_resource (HKEY_LOCAL_MACHINE, envvar, &dwType)))
359 /* Not found in the registry. */
360 return NULL;
361
362 if (dwType == REG_SZ)
363 /* Registry; no need to expand. */
364 return value;
365
366 if (dwType == REG_EXPAND_SZ)
367 {
368 DWORD size;
369
370 if (size = ExpandEnvironmentStrings (value, NULL, 0))
371 {
372 char *buffer = (char *) xmalloc (size);
373 if (ExpandEnvironmentStrings (value, buffer, size))
374 {
375 /* Found and expanded. */
376 free (value);
377 return buffer;
378 }
379
380 /* Error expanding. */
381 free (buffer);
382 }
383 }
384
385 /* Not the right type, or not correctly expanded. */
386 free (value);
387 return NULL;
388}
389
390int
391w32_window_app ()
392{
393 static int window_app = -1;
394 char szTitle[MAX_PATH];
395
396 if (window_app < 0)
397 {
398 /* Checking for STDOUT does not work; it's a valid handle also in
399 nonconsole apps. Testing for the console title seems to work. */
400 window_app = (GetConsoleTitleA (szTitle, MAX_PATH) == 0);
401 if (window_app)
402 InitCommonControls();
403 }
404
405 return window_app;
406}
407
408/*
409 execvp wrapper for Windows. Quotes arguments with embedded spaces.
410
411 This is necessary due to the broken implementation of exec* routines in
412 the Microsoft libraries: they concatenate the arguments together without
413 quoting special characters, and pass the result to CreateProcess, with
414 predictably bad results. By contrast, Posix execvp passes the arguments
415 directly into the argv array of the child process.
416*/
417int
418w32_execvp (path, argv)
419 char *path;
420 char **argv;
421{
422 int i;
423
424 /* Required to allow a .BAT script as alternate editor. */
425 argv[0] = (char *) alternate_editor;
426
427 for (i = 0; argv[i]; i++)
428 if (strchr (argv[i], ' '))
429 {
430 char *quoted = alloca (strlen (argv[i]) + 3);
431 sprintf (quoted, "\"%s\"", argv[i]);
432 argv[i] = quoted;
433 }
434
435 return execvp (path, argv);
436}
437
438#undef execvp
439#define execvp w32_execvp
440
441#endif /* WINDOWSNT */
442
443/* Display a normal or error message.
444 On Windows, use a message box if compiled as a Windows app. */
445void
446message (int is_error, char *message, ...)
447{
448 char msg [2048];
449 va_list args;
450
451 va_start (args, message);
452 vsprintf (msg, message, args);
453 va_end (args);
454
455#ifdef WINDOWSNT
456 if (w32_window_app ())
457 {
458 if (is_error)
459 MessageBox (NULL, msg, "Emacsclient ERROR", MB_ICONERROR);
460 else
461 MessageBox (NULL, msg, "Emacsclient", MB_ICONINFORMATION);
462 }
463 else
464#endif
465 {
466 FILE *f = is_error ? stderr : stdout;
467
468 fputs (msg, f);
469 fflush (f);
470 }
471}
472
473/* Decode the options from argv and argc.
474 The global variable `optind' will say how many arguments we used up. */
475
476void
477decode_options (argc, argv)
478 int argc;
479 char **argv;
480{
481 alternate_editor = egetenv ("ALTERNATE_EDITOR");
482#ifndef WINDOWSNT
483 display = egetenv ("DISPLAY");
484 if (display && strlen (display) == 0)
485 display = NULL;
486#endif
487
488 while (1)
489 {
490 int opt = getopt_long (argc, argv,
491#ifndef NO_SOCKETS_IN_FILE_SYSTEM
492 "VHnea:s:f:d:tc",
493#else
494 "VHnea:f:d:tc",
495#endif
496 longopts, 0);
497
498 if (opt == EOF)
499 break;
500
501 switch (opt)
502 {
503 case 0:
504 /* If getopt returns 0, then it has already processed a
505 long-named option. We should do nothing. */
506 break;
507
508 case 'a':
509 alternate_editor = optarg;
510 break;
511
512#ifndef NO_SOCKETS_IN_FILE_SYSTEM
513 case 's':
514 socket_name = optarg;
515 break;
516#endif
517
518 case 'f':
519 server_file = optarg;
520 break;
521
522#ifndef WINDOWSNT
523 case 'd':
524 display = optarg;
525 break;
526#endif
527
528 case 'n':
529 nowait = 1;
530 break;
531
532 case 'e':
533 eval = 1;
534 break;
535
536 case 'V':
537 message (FALSE, "emacsclient %s\n", VERSION);
538 exit (EXIT_SUCCESS);
539 break;
540
541 case 't':
542 tty = 1;
543 current_frame = 0;
544 break;
545
546 case 'c':
547 current_frame = 0;
548 break;
549
550 case 'H':
551 print_help_and_exit ();
552 break;
553
554 default:
555 message (TRUE, "Try `%s --help' for more information\n", progname);
556 exit (EXIT_FAILURE);
557 break;
558 }
559 }
560
561 if (!tty && display)
562 window_system = 1;
563#if !defined (WINDOWSNT) && !defined (HAVE_CARBON)
564 else
565 tty = 1;
566#endif
567
568 /* --no-wait implies --current-frame on ttys when there are file
569 arguments or expressions given. */
570 if (nowait && tty && argc - optind > 0)
571 current_frame = 1;
572
573 if (current_frame)
574 {
575 tty = 0;
576 window_system = 0;
577 }
578
579 if (tty)
580 window_system = 0;
581}
582
583\f
584void
585print_help_and_exit ()
586{
587 /* Spaces and tabs are significant in this message; they're chosen so the
588 message aligns properly both in a tty and in a Windows message box.
589 Please try to preserve them; otherwise the output is very hard to read
590 when using emacsclientw. */
591 message (FALSE,
592 "Usage: %s [OPTIONS] FILE...\n\
593Tell the Emacs server to visit the specified files.\n\
594Every FILE can be either just a FILENAME or [+LINE[:COLUMN]] FILENAME.\n\
595\n\
596The following OPTIONS are accepted:\n\
597-V, --version Just print version info and return\n\
598-H, --help Print this usage information message\n\
599-t, --tty Open a new Emacs frame on the current terminal\n\
600-c, --create-frame Create a new frame instead of trying to\n\
601 use the current Emacs frame\n\
602-e, --eval Evaluate the FILE arguments as ELisp expressions\n\
603-n, --no-wait Don't wait for the server to return\n"
604#ifndef WINDOWSNT
605"-d, --display=DISPLAY Visit the file in the given display\n"
606#endif
607#ifndef NO_SOCKETS_IN_FILE_SYSTEM
608"-s, --socket-name=FILENAME\n\
609 Set filename of the UNIX socket for communication\n"
610#endif
611"-f, --server-file=FILENAME\n\
612 Set filename of the TCP authentication file\n\
613-a, --alternate-editor=EDITOR\n\
614 Editor to fallback to if the server is not running\n\
615\n\
616Report bugs to bug-gnu-emacs@gnu.org.\n", progname);
617 exit (EXIT_SUCCESS);
618}
619
620/*
621 Try to run a different command, or --if no alternate editor is
622 defined-- exit with an errorcode.
623 Uses argv, but gets it from the global variable main_argv.
624*/
625void
626fail (void)
627{
628 if (alternate_editor)
629 {
630 int i = optind - 1;
631
632 execvp (alternate_editor, main_argv + i);
633 message (TRUE, "%s: error executing alternate editor \"%s\"\n",
634 progname, alternate_editor);
635 }
636 exit (EXIT_FAILURE);
637}
638
639\f
640#if !defined (HAVE_SOCKETS) || !defined (HAVE_INET_SOCKETS)
641
642int
643main (argc, argv)
644 int argc;
645 char **argv;
646{
647 main_argv = argv;
648 progname = argv[0];
649 message (TRUE, "%s: Sorry, the Emacs server is supported only\n"
650 "on systems with Berkeley sockets.\n",
651 argv[0]);
652 fail ();
653}
654
655#else /* HAVE_SOCKETS && HAVE_INET_SOCKETS */
656
657#ifdef WINDOWSNT
658# include <winsock2.h>
659#else
660# include <sys/types.h>
661# include <sys/socket.h>
662# include <sys/un.h>
663#endif
664
665#define AUTH_KEY_LENGTH 64
666#define SEND_BUFFER_SIZE 4096
667
668extern char *strerror ();
669extern int errno;
670
671/* Buffer to accumulate data to send in TCP connections. */
672char send_buffer[SEND_BUFFER_SIZE + 1];
673int sblen = 0; /* Fill pointer for the send buffer. */
674/* Socket used to communicate with the Emacs server process. */
675HSOCKET emacs_socket = 0;
676
677/* On Windows, the socket library was historically separate from the standard
678 C library, so errors are handled differently. */
679void
680sock_err_message (function_name)
681 char *function_name;
682{
683#ifdef WINDOWSNT
684 char* msg = NULL;
685
686 FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM
687 | FORMAT_MESSAGE_ALLOCATE_BUFFER
688 | FORMAT_MESSAGE_ARGUMENT_ARRAY,
689 NULL, WSAGetLastError (), 0, (LPTSTR)&msg, 0, NULL);
690
691 message (TRUE, "%s: %s: %s\n", progname, function_name, msg);
692
693 LocalFree (msg);
694#else
695 message (TRUE, "%s: %s: %s\n", progname, function_name, strerror (errno));
696#endif
697}
698
699
700/* Let's send the data to Emacs when either
701 - the data ends in "\n", or
702 - the buffer is full (but this shouldn't happen)
703 Otherwise, we just accumulate it. */
704void
705send_to_emacs (s, data)
706 HSOCKET s;
707 char *data;
708{
709 while (data)
710 {
711 int dlen = strlen (data);
712 if (dlen + sblen >= SEND_BUFFER_SIZE)
713 {
714 int part = SEND_BUFFER_SIZE - sblen;
715 strncpy (&send_buffer[sblen], data, part);
716 data += part;
717 sblen = SEND_BUFFER_SIZE;
718 }
719 else if (dlen)
720 {
721 strcpy (&send_buffer[sblen], data);
722 data = NULL;
723 sblen += dlen;
724 }
725 else
726 break;
727
728 if (sblen == SEND_BUFFER_SIZE
729 || (sblen > 0 && send_buffer[sblen-1] == '\n'))
730 {
731 int sent = send (s, send_buffer, sblen, 0);
732 if (sent != sblen)
733 strcpy (send_buffer, &send_buffer[sent]);
734 sblen -= sent;
735 }
736 }
737}
738
739\f
740/* In STR, insert a & before each &, each space, each newline, and
741 any initial -. Change spaces to underscores, too, so that the
742 return value never contains a space.
743
744 Does not change the string. Outputs the result to STREAM. */
745void
746quote_argument (s, str)
747 HSOCKET s;
748 char *str;
749{
750 char *copy = (char *) xmalloc (strlen (str) * 2 + 1);
751 char *p, *q;
752
753 p = str;
754 q = copy;
755 while (*p)
756 {
757 if (*p == ' ')
758 {
759 *q++ = '&';
760 *q++ = '_';
761 p++;
762 }
763 else if (*p == '\n')
764 {
765 *q++ = '&';
766 *q++ = 'n';
767 p++;
768 }
769 else
770 {
771 if (*p == '&' || (*p == '-' && p == str))
772 *q++ = '&';
773 *q++ = *p++;
774 }
775 }
776 *q++ = 0;
777
778 send_to_emacs (s, copy);
779
780 free (copy);
781}
782
783
784/* The inverse of quote_argument. Removes quoting in string STR by
785 modifying the string in place. Returns STR. */
786
787char *
788unquote_argument (str)
789 char *str;
790{
791 char *p, *q;
792
793 if (! str)
794 return str;
795
796 p = str;
797 q = str;
798 while (*p)
799 {
800 if (*p == '&')
801 {
802 p++;
803 if (*p == '&')
804 *p = '&';
805 else if (*p == '_')
806 *p = ' ';
807 else if (*p == 'n')
808 *p = '\n';
809 else if (*p == '-')
810 *p = '-';
811 }
812 *q++ = *p++;
813 }
814 *q = 0;
815 return str;
816}
817
818\f
819int
820file_name_absolute_p (filename)
821 const unsigned char *filename;
822{
823 /* Sanity check, it shouldn't happen. */
824 if (! filename) return FALSE;
825
826 /* /xxx is always an absolute path. */
827 if (filename[0] == '/') return TRUE;
828
829 /* Empty filenames (which shouldn't happen) are relative. */
830 if (filename[0] == '\0') return FALSE;
831
832#ifdef WINDOWSNT
833 /* X:\xxx is always absolute. */
834 if (isalpha (filename[0])
835 && filename[1] == ':' && (filename[2] == '\\' || filename[2] == '/'))
836 return TRUE;
837
838 /* Both \xxx and \\xxx\yyy are absolute. */
839 if (filename[0] == '\\') return TRUE;
840
841 /*
842 FIXME: There's a corner case not dealt with, "x:y", where:
843
844 1) x is a valid drive designation (usually a letter in the A-Z range)
845 and y is a path, relative to the current directory on drive x. This
846 is absolute, *after* fixing the y part to include the current
847 directory in x.
848
849 2) x is a relative file name, and y is an NTFS stream name. This is a
850 correct relative path, but it is very unusual.
851
852 The trouble is that first case items are also valid examples of the
853 second case, i.e., "c:test" can be understood as drive:path or as
854 file:stream.
855
856 The "right" fix would involve checking whether
857 - the current drive/partition is NTFS,
858 - x is a valid (and accesible) drive designator,
859 - x:y already exists as a file:stream in the current directory,
860 - y already exists on the current directory of drive x,
861 - the auspices are favorable,
862 and then taking an "informed decision" based on the above.
863
864 Whatever the result, Emacs currently does a very bad job of dealing
865 with NTFS file:streams: it cannot visit them, and the only way to
866 create one is by setting `buffer-file-name' to point to it (either
867 manually or with emacsclient). So perhaps resorting to 1) and ignoring
868 2) for now is the right thing to do.
869
870 Anyway, something to decide After the Release.
871 */
872#endif
873
874 return FALSE;
875}
876
877#ifdef WINDOWSNT
878/* Wrapper to make WSACleanup a cdecl, as required by atexit. */
879void
880__cdecl close_winsock ()
881{
882 WSACleanup ();
883}
884
885/* Initialize the WinSock2 library. */
886void
887initialize_sockets ()
888{
889 WSADATA wsaData;
890
891 if (WSAStartup (MAKEWORD (2, 0), &wsaData))
892 {
893 message (TRUE, "%s: error initializing WinSock2\n", progname);
894 exit (EXIT_FAILURE);
895 }
896
897 atexit (close_winsock);
898}
899#endif /* WINDOWSNT */
900
901\f
902/*
903 * Read the information needed to set up a TCP comm channel with
904 * the Emacs server: host, port, pid and authentication string.
905 */
906int
907get_server_config (server, authentication)
908 struct sockaddr_in *server;
909 char *authentication;
910{
911 char dotted[32];
912 char *port;
913 char *pid;
914 FILE *config = NULL;
915
916 if (file_name_absolute_p (server_file))
917 config = fopen (server_file, "rb");
918 else
919 {
920 char *home = egetenv ("HOME");
921
922 if (home)
923 {
924 char *path = alloca (32 + strlen (home) + strlen (server_file));
925 sprintf (path, "%s/.emacs.d/server/%s", home, server_file);
926 config = fopen (path, "rb");
927 }
928#ifdef WINDOWSNT
929 if (!config && (home = egetenv ("APPDATA")))
930 {
931 char *path = alloca (32 + strlen (home) + strlen (server_file));
932 sprintf (path, "%s/.emacs.d/server/%s", home, server_file);
933 config = fopen (path, "rb");
934 }
935#endif
936 }
937
938 if (! config)
939 return FALSE;
940
941 if (fgets (dotted, sizeof dotted, config)
942 && (port = strchr (dotted, ':'))
943 && (pid = strchr (port, ' ')))
944 {
945 *port++ = '\0';
946 *pid++ = '\0';
947 }
948 else
949 {
950 message (TRUE, "%s: invalid configuration info\n", progname);
951 exit (EXIT_FAILURE);
952 }
953
954 server->sin_family = AF_INET;
955 server->sin_addr.s_addr = inet_addr (dotted);
956 server->sin_port = htons (atoi (port));
957
958 if (! fread (authentication, AUTH_KEY_LENGTH, 1, config))
959 {
960 message (TRUE, "%s: cannot read authentication info\n", progname);
961 exit (EXIT_FAILURE);
962 }
963
964 fclose (config);
965
966 emacs_pid = atoi (pid);
967
968 return TRUE;
969}
970
971HSOCKET
972set_tcp_socket ()
973{
974 HSOCKET s;
975 struct sockaddr_in server;
976 struct linger l_arg = {1, 1};
977 char auth_string[AUTH_KEY_LENGTH + 1];
978
979 if (! get_server_config (&server, auth_string))
980 return INVALID_SOCKET;
981
982 if (server.sin_addr.s_addr != inet_addr ("127.0.0.1"))
983 message (FALSE, "%s: connected to remote socket at %s\n",
984 progname, inet_ntoa (server.sin_addr));
985
986 /*
987 * Open up an AF_INET socket
988 */
989 if ((s = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
990 {
991 sock_err_message ("socket");
992 return INVALID_SOCKET;
993 }
994
995 /*
996 * Set up the socket
997 */
998 if (connect (s, (struct sockaddr *) &server, sizeof server) < 0)
999 {
1000 sock_err_message ("connect");
1001 return INVALID_SOCKET;
1002 }
1003
1004 setsockopt (s, SOL_SOCKET, SO_LINGER, (char *) &l_arg, sizeof l_arg);
1005
1006 /*
1007 * Send the authentication
1008 */
1009 auth_string[AUTH_KEY_LENGTH] = '\0';
1010
1011 send_to_emacs (s, "-auth ");
1012 send_to_emacs (s, auth_string);
1013 send_to_emacs (s, "\n");
1014
1015 return s;
1016}
1017
1018
1019/* Returns 1 if PREFIX is a prefix of STRING. */
1020static int
1021strprefix (char *prefix, char *string)
1022{
1023 return !strncmp (prefix, string, strlen (prefix));
1024}
1025
1026
1027#if !defined (NO_SOCKETS_IN_FILE_SYSTEM)
1028
1029/* Three possibilities:
1030 2 - can't be `stat'ed (sets errno)
1031 1 - isn't owned by us
1032 0 - success: none of the above */
1033
1034static int
1035socket_status (socket_name)
1036 char *socket_name;
1037{
1038 struct stat statbfr;
1039
1040 if (stat (socket_name, &statbfr) == -1)
1041 return 2;
1042
1043 if (statbfr.st_uid != geteuid ())
1044 return 1;
1045
1046 return 0;
1047}
1048
1049\f
1050/* A signal handler that passes the signal to the Emacs process.
1051 Useful for SIGWINCH. */
1052
1053SIGTYPE
1054pass_signal_to_emacs (int signalnum)
1055{
1056 int old_errno = errno;
1057
1058 if (emacs_pid)
1059 kill (emacs_pid, signalnum);
1060
1061 signal (signalnum, pass_signal_to_emacs);
1062 errno = old_errno;
1063}
1064
1065/* Signal handler for SIGCONT; notify the Emacs process that it can
1066 now resume our tty frame. */
1067
1068SIGTYPE
1069handle_sigcont (int signalnum)
1070{
1071 int old_errno = errno;
1072
1073 if (tcgetpgrp (1) == getpgrp ())
1074 {
1075 /* We are in the foreground. */
1076 send_to_emacs (emacs_socket, "-resume \n");
1077 }
1078 else
1079 {
1080 /* We are in the background; cancel the continue. */
1081 kill (getpid (), SIGSTOP);
1082 }
1083
1084 signal (signalnum, handle_sigcont);
1085 errno = old_errno;
1086}
1087
1088/* Signal handler for SIGTSTP; notify the Emacs process that we are
1089 going to sleep. Normally the suspend is initiated by Emacs via
1090 server-handle-suspend-tty, but if the server gets out of sync with
1091 reality, we may get a SIGTSTP on C-z. Handling this signal and
1092 notifying Emacs about it should get things under control again. */
1093
1094SIGTYPE
1095handle_sigtstp (int signalnum)
1096{
1097 int old_errno = errno;
1098 sigset_t set;
1099
1100 if (emacs_socket)
1101 send_to_emacs (emacs_socket, "-suspend \n");
1102
1103 /* Unblock this signal and call the default handler by temprarily
1104 changing the handler and resignalling. */
1105 sigprocmask (SIG_BLOCK, NULL, &set);
1106 sigdelset (&set, signalnum);
1107 signal (signalnum, SIG_DFL);
1108 kill (getpid (), signalnum);
1109 sigprocmask (SIG_SETMASK, &set, NULL); /* Let's the above signal through. */
1110 signal (signalnum, handle_sigtstp);
1111
1112 errno = old_errno;
1113}
1114/* Set up signal handlers before opening a frame on the current tty. */
1115
1116void
1117init_signals (void)
1118{
1119 /* Set up signal handlers. */
1120 signal (SIGWINCH, pass_signal_to_emacs);
1121
1122 /* Don't pass SIGINT and SIGQUIT to Emacs, because it has no way of
1123 deciding which terminal the signal came from. C-g is now a
1124 normal input event on secondary terminals. */
1125#if 0
1126 signal (SIGINT, pass_signal_to_emacs);
1127 signal (SIGQUIT, pass_signal_to_emacs);
1128#endif
1129
1130 signal (SIGCONT, handle_sigcont);
1131 signal (SIGTSTP, handle_sigtstp);
1132 signal (SIGTTOU, handle_sigtstp);
1133}
1134
1135
1136HSOCKET
1137set_local_socket ()
1138{
1139 HSOCKET s;
1140 struct sockaddr_un server;
1141
1142 /*
1143 * Open up an AF_UNIX socket in this person's home directory
1144 */
1145
1146 if ((s = socket (AF_UNIX, SOCK_STREAM, 0)) < 0)
1147 {
1148 message (TRUE, "%s: socket: %s\n", progname, strerror (errno));
1149 return INVALID_SOCKET;
1150 }
1151
1152 server.sun_family = AF_UNIX;
1153
1154 {
1155 int sock_status = 0;
1156 int default_sock = !socket_name;
1157 int saved_errno = 0;
1158 char *server_name = "server";
1159
1160 if (socket_name && !index (socket_name, '/') && !index (socket_name, '\\'))
1161 { /* socket_name is a file name component. */
1162 server_name = socket_name;
1163 socket_name = NULL;
1164 default_sock = 1; /* Try both UIDs. */
1165 }
1166
1167 if (default_sock)
1168 {
1169 socket_name = alloca (100 + strlen (server_name));
1170 sprintf (socket_name, "/tmp/emacs%d/%s",
1171 (int) geteuid (), server_name);
1172 }
1173
1174 if (strlen (socket_name) < sizeof (server.sun_path))
1175 strcpy (server.sun_path, socket_name);
1176 else
1177 {
1178 message (TRUE, "%s: socket-name %s too long\n",
1179 progname, socket_name);
1180 fail ();
1181 }
1182
1183 /* See if the socket exists, and if it's owned by us. */
1184 sock_status = socket_status (server.sun_path);
1185 saved_errno = errno;
1186 if (sock_status && default_sock)
1187 {
1188 /* Failing that, see if LOGNAME or USER exist and differ from
1189 our euid. If so, look for a socket based on the UID
1190 associated with the name. This is reminiscent of the logic
1191 that init_editfns uses to set the global Vuser_full_name. */
1192
1193 char *user_name = (char *) egetenv ("LOGNAME");
1194
1195 if (!user_name)
1196 user_name = (char *) egetenv ("USER");
1197
1198 if (user_name)
1199 {
1200 struct passwd *pw = getpwnam (user_name);
1201
1202 if (pw && (pw->pw_uid != geteuid ()))
1203 {
1204 /* We're running under su, apparently. */
1205 socket_name = alloca (100 + strlen (server_name));
1206 sprintf (socket_name, "/tmp/emacs%d/%s",
1207 (int) pw->pw_uid, server_name);
1208
1209 if (strlen (socket_name) < sizeof (server.sun_path))
1210 strcpy (server.sun_path, socket_name);
1211 else
1212 {
1213 message (TRUE, "%s: socket-name %s too long\n",
1214 progname, socket_name);
1215 exit (EXIT_FAILURE);
1216 }
1217
1218 sock_status = socket_status (server.sun_path);
1219 saved_errno = errno;
1220 }
1221 else
1222 errno = saved_errno;
1223 }
1224 }
1225
1226 switch (sock_status)
1227 {
1228 case 1:
1229 /* There's a socket, but it isn't owned by us. This is OK if
1230 we are root. */
1231 if (0 != geteuid ())
1232 {
1233 message (TRUE, "%s: Invalid socket owner\n", progname);
1234 return INVALID_SOCKET;
1235 }
1236 break;
1237
1238 case 2:
1239 /* `stat' failed */
1240 if (saved_errno == ENOENT)
1241 message (TRUE,
1242 "%s: can't find socket; have you started the server?\n\
1243To start the server in Emacs, type \"M-x server-start\".\n",
1244 progname);
1245 else
1246 message (TRUE, "%s: can't stat %s: %s\n",
1247 progname, server.sun_path, strerror (saved_errno));
1248 return INVALID_SOCKET;
1249 }
1250 }
1251
1252 if (connect (s, (struct sockaddr *) &server, strlen (server.sun_path) + 2)
1253 < 0)
1254 {
1255 message (TRUE, "%s: connect: %s\n", progname, strerror (errno));
1256 return INVALID_SOCKET;
1257 }
1258
1259 return s;
1260}
1261#endif /* ! NO_SOCKETS_IN_FILE_SYSTEM */
1262
1263HSOCKET
1264set_socket ()
1265{
1266 HSOCKET s;
1267
1268 INITIALIZE ();
1269
1270#ifndef NO_SOCKETS_IN_FILE_SYSTEM
1271 /* Explicit --socket-name argument. */
1272 if (socket_name)
1273 {
1274 s = set_local_socket ();
1275 if ((s != INVALID_SOCKET) || alternate_editor)
1276 return s;
1277 message (TRUE, "%s: error accessing socket \"%s\"\n",
1278 progname, socket_name);
1279 exit (EXIT_FAILURE);
1280 }
1281#endif
1282
1283 /* Explicit --server-file arg or EMACS_SERVER_FILE variable. */
1284 if (!server_file)
1285 server_file = egetenv ("EMACS_SERVER_FILE");
1286
1287 if (server_file)
1288 {
1289 s = set_tcp_socket ();
1290 if ((s != INVALID_SOCKET) || alternate_editor)
1291 return s;
1292
1293 message (TRUE, "%s: error accessing server file \"%s\"\n",
1294 progname, server_file);
1295 exit (EXIT_FAILURE);
1296 }
1297
1298#ifndef NO_SOCKETS_IN_FILE_SYSTEM
1299 /* Implicit local socket. */
1300 s = set_local_socket ();
1301 if (s != INVALID_SOCKET)
1302 return s;
1303#endif
1304
1305 /* Implicit server file. */
1306 server_file = "server";
1307 s = set_tcp_socket ();
1308 if ((s != INVALID_SOCKET) || alternate_editor)
1309 return s;
1310
1311 /* No implicit or explicit socket, and no alternate editor. */
1312 message (TRUE, "%s: No socket or alternate editor. Please use:\n\n"
1313#ifndef NO_SOCKETS_IN_FILE_SYSTEM
1314"\t--socket-name\n"
1315#endif
1316"\t--server-file (or environment variable EMACS_SERVER_FILE)\n\
1317\t--alternate-editor (or environment variable ALTERNATE_EDITOR)\n",
1318 progname);
1319 exit (EXIT_FAILURE);
1320}
1321
1322#ifdef WINDOWSNT
1323FARPROC set_fg; /* Pointer to AllowSetForegroundWindow. */
1324FARPROC get_wc; /* Pointer to RealGetWindowClassA. */
1325
1326BOOL CALLBACK
1327w32_find_emacs_process (hWnd, lParam)
1328 HWND hWnd;
1329 LPARAM lParam;
1330{
1331 DWORD pid;
1332 char class[6];
1333
1334 /* Reject any window not of class "Emacs". */
1335 if (! get_wc (hWnd, class, sizeof (class))
1336 || strcmp (class, "Emacs"))
1337 return TRUE;
1338
1339 /* We only need the process id, not the thread id. */
1340 (void) GetWindowThreadProcessId (hWnd, &pid);
1341
1342 /* Not the one we're looking for. */
1343 if (pid != (DWORD) emacs_pid) return TRUE;
1344
1345 /* OK, let's raise it. */
1346 set_fg (emacs_pid);
1347
1348 /* Stop enumeration. */
1349 return FALSE;
1350}
1351
1352/*
1353 * Search for a window of class "Emacs" and owned by a process with
1354 * process id = emacs_pid. If found, allow it to grab the focus.
1355 */
1356void
1357w32_give_focus ()
1358{
1359 HMODULE hUser32;
1360
1361 /* It shouldn't happen when dealing with TCP sockets. */
1362 if (!emacs_pid) return;
1363
1364 if (!(hUser32 = LoadLibrary ("user32.dll"))) return;
1365
1366 /* Modern Windows restrict which processes can set the foreground window.
1367 emacsclient can allow Emacs to grab the focus by calling the function
1368 AllowSetForegroundWindow. Unfortunately, older Windows (W95, W98 and
1369 NT) lack this function, so we have to check its availability. */
1370 if ((set_fg = GetProcAddress (hUser32, "AllowSetForegroundWindow"))
1371 && (get_wc = GetProcAddress (hUser32, "RealGetWindowClassA")))
1372 EnumWindows (w32_find_emacs_process, (LPARAM) 0);
1373
1374 FreeLibrary (hUser32);
1375}
1376#endif
1377
1378int
1379main (argc, argv)
1380 int argc;
1381 char **argv;
1382{
1383 int i, rl, needlf = 0;
1384 char *cwd, *str;
1385 char string[BUFSIZ+1];
1386
1387 main_argv = argv;
1388 progname = argv[0];
1389
1390 /* Process options. */
1391 decode_options (argc, argv);
1392
1393 if ((argc - optind < 1) && !eval && !tty && !window_system)
1394 {
1395 message (TRUE, "%s: file name or argument required\n"
1396 "Try `%s --help' for more information\n",
1397 progname, progname);
1398 exit (EXIT_FAILURE);
1399 }
1400
1401 if ((emacs_socket = set_socket ()) == INVALID_SOCKET)
1402 fail ();
1403
1404
1405 cwd = get_current_dir_name ();
1406 if (cwd == 0)
1407 {
1408 /* getwd puts message in STRING if it fails. */
1409 message (TRUE, "%s: %s\n", progname,
1410 "Cannot get current working directory");
1411 fail ();
1412 }
1413
1414#ifdef WINDOWSNT
1415 w32_give_focus ();
1416#endif
1417
1418 /* Send over our environment. */
1419 if (!current_frame)
1420 {
1421 extern char **environ;
1422 int i;
1423 for (i = 0; environ[i]; i++)
1424 {
1425 char *name = xstrdup (environ[i]);
1426 char *value = strchr (name, '=');
1427 send_to_emacs (emacs_socket, "-env ");
1428 quote_argument (emacs_socket, environ[i]);
1429 send_to_emacs (emacs_socket, " ");
1430 }
1431 }
1432
1433 /* Send over our current directory. */
1434 if (!current_frame)
1435 {
1436 send_to_emacs (emacs_socket, "-dir ");
1437 quote_argument (emacs_socket, cwd);
1438 send_to_emacs (emacs_socket, "/");
1439 send_to_emacs (emacs_socket, " ");
1440 }
1441
1442 retry:
1443 if (nowait)
1444 send_to_emacs (emacs_socket, "-nowait ");
1445
1446 if (current_frame)
1447 send_to_emacs (emacs_socket, "-current-frame ");
1448
1449 if (display)
1450 {
1451 send_to_emacs (emacs_socket, "-display ");
1452 quote_argument (emacs_socket, display);
1453 send_to_emacs (emacs_socket, " ");
1454 }
1455
1456 if (tty)
1457 {
1458 char *type = egetenv ("TERM");
1459 char *tty_name = NULL;
1460#ifndef WINDOWSNT
1461 tty_name = ttyname (fileno (stdin));
1462#endif
1463
1464 if (! tty_name)
1465 {
1466 message (TRUE, "%s: could not get terminal name\n", progname);
1467 fail ();
1468 }
1469
1470 if (! type)
1471 {
1472 message (TRUE, "%s: please set the TERM variable to your terminal type\n",
1473 progname);
1474 fail ();
1475 }
1476
1477 if (! strcmp (type, "eterm"))
1478 {
1479 /* This causes nasty, MULTI_KBOARD-related input lockouts. */
1480 message (TRUE, "%s: opening a frame in an Emacs term buffer"
1481 " is not supported\n", progname);
1482 fail ();
1483 }
1484#if !defined (NO_SOCKETS_IN_FILE_SYSTEM)
1485 init_signals ();
1486#endif
1487
1488 send_to_emacs (emacs_socket, "-tty ");
1489 quote_argument (emacs_socket, tty_name);
1490 send_to_emacs (emacs_socket, " ");
1491 quote_argument (emacs_socket, type);
1492 send_to_emacs (emacs_socket, " ");
1493 }
1494
1495 if (window_system)
1496 send_to_emacs (emacs_socket, "-window-system ");
1497
1498 if ((argc - optind > 0))
1499 {
1500 for (i = optind; i < argc; i++)
1501 {
1502 int relative = 0;
1503
1504 if (eval)
1505 {
1506 /* Don't prepend cwd or anything like that. */
1507 send_to_emacs (emacs_socket, "-eval ");
1508 quote_argument (emacs_socket, argv[i]);
1509 send_to_emacs (emacs_socket, " ");
1510 continue;
1511 }
1512
1513 if (*argv[i] == '+')
1514 {
1515 char *p = argv[i] + 1;
1516 while (isdigit ((unsigned char) *p) || *p == ':') p++;
1517 if (*p == 0)
1518 {
1519 send_to_emacs (emacs_socket, "-position ");
1520 quote_argument (emacs_socket, argv[i]);
1521 send_to_emacs (emacs_socket, " ");
1522 continue;
1523 }
1524 else
1525 relative = 1;
1526 }
1527 else if (! file_name_absolute_p (argv[i]))
1528 relative = 1;
1529
1530 send_to_emacs (emacs_socket, "-file ");
1531 if (relative)
1532 {
1533 quote_argument (emacs_socket, cwd);
1534 send_to_emacs (emacs_socket, "/");
1535 }
1536 quote_argument (emacs_socket, argv[i]);
1537 send_to_emacs (emacs_socket, " ");
1538 }
1539 }
1540 else
1541 {
1542 if (!tty && !window_system)
1543 {
1544 while ((str = fgets (string, BUFSIZ, stdin)))
1545 {
1546 if (eval)
1547 send_to_emacs (emacs_socket, "-eval ");
1548 else
1549 send_to_emacs (emacs_socket, "-file ");
1550 quote_argument (emacs_socket, str);
1551 }
1552 send_to_emacs (emacs_socket, " ");
1553 }
1554 }
1555
1556 send_to_emacs (emacs_socket, "\n");
1557
1558 /* Wait for an answer. */
1559 if (!eval && !tty && !nowait)
1560 {
1561 printf ("Waiting for Emacs...");
1562 needlf = 2;
1563 }
1564 fflush (stdout);
1565 fsync (1);
1566
1567 /* Now, wait for an answer and print any messages. */
1568 while ((rl = recv (emacs_socket, string, BUFSIZ, 0)) > 0)
1569 {
1570 char *p;
1571 string[rl] = '\0';
1572
1573 p = string + strlen (string) - 1;
1574 while (p > string && *p == '\n')
1575 *p-- = 0;
1576
1577 if (strprefix ("-emacs-pid ", string))
1578 {
1579 /* -emacs-pid PID: The process id of the Emacs process. */
1580 emacs_pid = strtol (string + strlen ("-emacs-pid"), NULL, 10);
1581 }
1582 else if (strprefix ("-window-system-unsupported ", string))
1583 {
1584 /* -window-system-unsupported: Emacs was compiled without X
1585 support. Try again on the terminal. */
1586 window_system = 0;
1587 nowait = 0;
1588 tty = 1;
1589 goto retry;
1590 }
1591 else if (strprefix ("-print ", string))
1592 {
1593 /* -print STRING: Print STRING on the terminal. */
1594 str = unquote_argument (string + strlen ("-print "));
1595 if (needlf)
1596 printf ("\n");
1597 printf ("%s", str);
1598 needlf = str[0] == '\0' ? needlf : str[strlen (str) - 1] != '\n';
1599 }
1600 else if (strprefix ("-error ", string))
1601 {
1602 /* -error DESCRIPTION: Signal an error on the terminal. */
1603 str = unquote_argument (string + strlen ("-error "));
1604 if (needlf)
1605 printf ("\n");
1606 fprintf (stderr, "*ERROR*: %s", str);
1607 needlf = str[0] == '\0' ? needlf : str[strlen (str) - 1] != '\n';
1608 }
1609#ifdef SIGSTOP
1610 else if (strprefix ("-suspend ", string))
1611 {
1612 /* -suspend: Suspend this terminal, i.e., stop the process. */
1613 if (needlf)
1614 printf ("\n");
1615 needlf = 0;
1616 kill (0, SIGSTOP);
1617 }
1618#endif
1619 else
1620 {
1621 /* Unknown command. */
1622 if (needlf)
1623 printf ("\n");
1624 printf ("*ERROR*: Unknown message: %s", string);
1625 needlf = string[0] == '\0' ? needlf : string[strlen (string) - 1] != '\n';
1626 }
1627 }
1628
1629 if (needlf)
1630 printf ("\n");
1631 fflush (stdout);
1632 fsync (1);
1633
1634 CLOSE_SOCKET (emacs_socket);
1635 return EXIT_SUCCESS;
1636}
1637
1638#endif /* HAVE_SOCKETS && HAVE_INET_SOCKETS */
1639
1640\f
1641#ifndef HAVE_STRERROR
1642char *
1643strerror (errnum)
1644 int errnum;
1645{
1646 extern char *sys_errlist[];
1647 extern int sys_nerr;
1648
1649 if (errnum >= 0 && errnum < sys_nerr)
1650 return sys_errlist[errnum];
1651 return (char *) "Unknown error";
1652}
1653
1654#endif /* ! HAVE_STRERROR */
1655
1656/* arch-tag: f39bb9c4-73eb-477e-896d-50832e2ca9a7
1657 (do not change this comment) */
1658
1659/* emacsclient.c ends here */