* frame.c (x_fullscreen_adjust): Declare var as Display_Info.
[emacs.git] / lib-src / emacsclient.c
blob8f0231db540f586b3d0c590de4124d15f96e8b0a
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.
5 This file is part of GNU Emacs.
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 3 of the License, or
10 (at your option) any later version.
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.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
21 #ifdef HAVE_CONFIG_H
22 #include <config.h>
23 #endif
25 #ifdef WINDOWSNT
27 /* config.h defines these, which disables sockets altogether! */
28 # undef _WINSOCKAPI_
29 # undef _WINSOCK_H
31 # include <malloc.h>
32 # include <stdlib.h>
33 # include <windows.h>
34 # include <commctrl.h>
36 # define NO_SOCKETS_IN_FILE_SYSTEM
38 # define HSOCKET SOCKET
39 # define CLOSE_SOCKET closesocket
40 # define INITIALIZE() (initialize_sockets ())
42 #else /* !WINDOWSNT */
44 # include <sys/types.h>
46 # ifdef HAVE_INET_SOCKETS
47 # include <netinet/in.h>
48 # endif
50 # define INVALID_SOCKET -1
51 # define HSOCKET int
52 # define CLOSE_SOCKET close
53 # define INITIALIZE()
55 #endif /* !WINDOWSNT */
57 #undef signal
59 #include <stdarg.h>
60 #include <ctype.h>
61 #include <stdio.h>
62 #include "getopt.h"
63 #ifdef HAVE_UNISTD_H
64 #include <unistd.h>
65 #endif
67 #ifdef WINDOWSNT
68 # include <io.h>
69 #else /* not WINDOWSNT */
70 # include <pwd.h>
71 #endif /* not WINDOWSNT */
72 #include <sys/stat.h>
74 #include <signal.h>
75 #include <errno.h>
78 char *getenv (), *getwd ();
79 char *(getcwd) ();
81 #ifdef WINDOWSNT
82 char *w32_getenv ();
83 #define egetenv(VAR) w32_getenv(VAR)
84 #else
85 #define egetenv(VAR) getenv(VAR)
86 #endif
88 #ifndef VERSION
89 #define VERSION "unspecified"
90 #endif
93 #ifndef EXIT_SUCCESS
94 #define EXIT_SUCCESS 0
95 #endif
97 #ifndef EXIT_FAILURE
98 #define EXIT_FAILURE 1
99 #endif
101 #ifndef FALSE
102 #define FALSE 0
103 #endif
105 #ifndef TRUE
106 #define TRUE 1
107 #endif
109 #ifndef NO_RETURN
110 #define NO_RETURN
111 #endif
113 /* Name used to invoke this program. */
114 char *progname;
116 /* The second argument to main. */
117 char **main_argv;
119 /* Nonzero means don't wait for a response from Emacs. --no-wait. */
120 int nowait = 0;
122 /* Nonzero means args are expressions to be evaluated. --eval. */
123 int eval = 0;
125 /* Nonzero means don't open a new frame. Inverse of --create-frame. */
126 int current_frame = 1;
128 /* Nonzero means open a new graphical frame. */
129 int window_system = 0;
131 /* The display on which Emacs should work. --display. */
132 char *display = NULL;
134 /* Nonzero means open a new Emacs frame on the current terminal. */
135 int tty = 0;
137 /* If non-NULL, the name of an editor to fallback to if the server
138 is not running. --alternate-editor. */
139 const char *alternate_editor = NULL;
141 /* If non-NULL, the filename of the UNIX socket. */
142 char *socket_name = NULL;
144 /* If non-NULL, the filename of the authentication file. */
145 char *server_file = NULL;
147 /* PID of the Emacs server process. */
148 int emacs_pid = 0;
150 void print_help_and_exit () NO_RETURN;
152 struct option longopts[] =
154 { "no-wait", no_argument, NULL, 'n' },
155 { "eval", no_argument, NULL, 'e' },
156 { "help", no_argument, NULL, 'H' },
157 { "version", no_argument, NULL, 'V' },
158 { "tty", no_argument, NULL, 't' },
159 { "create-frame", no_argument, NULL, 'c' },
160 { "alternate-editor", required_argument, NULL, 'a' },
161 #ifndef NO_SOCKETS_IN_FILE_SYSTEM
162 { "socket-name", required_argument, NULL, 's' },
163 #endif
164 { "server-file", required_argument, NULL, 'f' },
165 #ifndef WINDOWSNT
166 { "display", required_argument, NULL, 'd' },
167 #endif
168 { 0, 0, 0, 0 }
172 /* Like malloc but get fatal error if memory is exhausted. */
174 long *
175 xmalloc (size)
176 unsigned int size;
178 long *result = (long *) malloc (size);
179 if (result == NULL)
181 perror ("malloc");
182 exit (EXIT_FAILURE);
184 return result;
187 /* Like strdup but get a fatal error if memory is exhausted. */
189 char *
190 xstrdup (const char *s)
192 char *result = strdup (s);
193 if (result == NULL)
195 perror ("strdup");
196 exit (EXIT_FAILURE);
198 return result;
201 /* From sysdep.c */
202 #if !defined (HAVE_GET_CURRENT_DIR_NAME) || defined (BROKEN_GET_CURRENT_DIR_NAME)
204 /* From lisp.h */
205 #ifndef DIRECTORY_SEP
206 #define DIRECTORY_SEP '/'
207 #endif
208 #ifndef IS_DIRECTORY_SEP
209 #define IS_DIRECTORY_SEP(_c_) ((_c_) == DIRECTORY_SEP)
210 #endif
211 #ifndef IS_DEVICE_SEP
212 #ifndef DEVICE_SEP
213 #define IS_DEVICE_SEP(_c_) 0
214 #else
215 #define IS_DEVICE_SEP(_c_) ((_c_) == DEVICE_SEP)
216 #endif
217 #endif
218 #ifndef IS_ANY_SEP
219 #define IS_ANY_SEP(_c_) (IS_DIRECTORY_SEP (_c_))
220 #endif
223 /* Return the current working directory. Returns NULL on errors.
224 Any other returned value must be freed with free. This is used
225 only when get_current_dir_name is not defined on the system. */
226 char*
227 get_current_dir_name ()
229 char *buf;
230 char *pwd;
231 struct stat dotstat, pwdstat;
232 /* If PWD is accurate, use it instead of calling getwd. PWD is
233 sometimes a nicer name, and using it may avoid a fatal error if a
234 parent directory is searchable but not readable. */
235 if ((pwd = egetenv ("PWD")) != 0
236 && (IS_DIRECTORY_SEP (*pwd) || (*pwd && IS_DEVICE_SEP (pwd[1])))
237 && stat (pwd, &pwdstat) == 0
238 && stat (".", &dotstat) == 0
239 && dotstat.st_ino == pwdstat.st_ino
240 && dotstat.st_dev == pwdstat.st_dev
241 #ifdef MAXPATHLEN
242 && strlen (pwd) < MAXPATHLEN
243 #endif
246 buf = (char *) xmalloc (strlen (pwd) + 1);
247 if (!buf)
248 return NULL;
249 strcpy (buf, pwd);
251 #ifdef HAVE_GETCWD
252 else
254 size_t buf_size = 1024;
255 buf = (char *) xmalloc (buf_size);
256 if (!buf)
257 return NULL;
258 for (;;)
260 if (getcwd (buf, buf_size) == buf)
261 break;
262 if (errno != ERANGE)
264 int tmp_errno = errno;
265 free (buf);
266 errno = tmp_errno;
267 return NULL;
269 buf_size *= 2;
270 buf = (char *) realloc (buf, buf_size);
271 if (!buf)
272 return NULL;
275 #else
276 else
278 /* We need MAXPATHLEN here. */
279 buf = (char *) xmalloc (MAXPATHLEN + 1);
280 if (!buf)
281 return NULL;
282 if (getwd (buf) == NULL)
284 int tmp_errno = errno;
285 free (buf);
286 errno = tmp_errno;
287 return NULL;
290 #endif
291 return buf;
293 #endif
295 #ifdef WINDOWSNT
297 #define REG_ROOT "SOFTWARE\\GNU\\Emacs"
299 /* Retrieve an environment variable from the Emacs subkeys of the registry.
300 Return NULL if the variable was not found, or it was empty.
301 This code is based on w32_get_resource (w32.c). */
302 char *
303 w32_get_resource (predefined, key, type)
304 HKEY predefined;
305 char *key;
306 LPDWORD type;
308 HKEY hrootkey = NULL;
309 char *result = NULL;
310 DWORD cbData;
312 if (RegOpenKeyEx (predefined, REG_ROOT, 0, KEY_READ, &hrootkey) == ERROR_SUCCESS)
314 if (RegQueryValueEx (hrootkey, key, NULL, NULL, NULL, &cbData) == ERROR_SUCCESS)
316 result = (char *) xmalloc (cbData);
318 if ((RegQueryValueEx (hrootkey, key, NULL, type, result, &cbData) != ERROR_SUCCESS) ||
319 (*result == 0))
321 free (result);
322 result = NULL;
326 RegCloseKey (hrootkey);
329 return result;
333 getenv wrapper for Windows
335 This is needed to duplicate Emacs's behavior, which is to look for enviroment
336 variables in the registry if they don't appear in the environment.
338 char *
339 w32_getenv (envvar)
340 char *envvar;
342 char *value;
343 DWORD dwType;
345 if (value = getenv (envvar))
346 /* Found in the environment. */
347 return value;
349 if (! (value = w32_get_resource (HKEY_CURRENT_USER, envvar, &dwType)) &&
350 ! (value = w32_get_resource (HKEY_LOCAL_MACHINE, envvar, &dwType)))
351 /* Not found in the registry. */
352 return NULL;
354 if (dwType == REG_SZ)
355 /* Registry; no need to expand. */
356 return value;
358 if (dwType == REG_EXPAND_SZ)
360 DWORD size;
362 if (size = ExpandEnvironmentStrings (value, NULL, 0))
364 char *buffer = (char *) xmalloc (size);
365 if (ExpandEnvironmentStrings (value, buffer, size))
367 /* Found and expanded. */
368 free (value);
369 return buffer;
372 /* Error expanding. */
373 free (buffer);
377 /* Not the right type, or not correctly expanded. */
378 free (value);
379 return NULL;
383 w32_window_app ()
385 static int window_app = -1;
386 char szTitle[MAX_PATH];
388 if (window_app < 0)
390 /* Checking for STDOUT does not work; it's a valid handle also in
391 nonconsole apps. Testing for the console title seems to work. */
392 window_app = (GetConsoleTitleA (szTitle, MAX_PATH) == 0);
393 if (window_app)
394 InitCommonControls();
397 return window_app;
401 execvp wrapper for Windows. Quotes arguments with embedded spaces.
403 This is necessary due to the broken implementation of exec* routines in
404 the Microsoft libraries: they concatenate the arguments together without
405 quoting special characters, and pass the result to CreateProcess, with
406 predictably bad results. By contrast, Posix execvp passes the arguments
407 directly into the argv array of the child process.
410 w32_execvp (path, argv)
411 char *path;
412 char **argv;
414 int i;
416 /* Required to allow a .BAT script as alternate editor. */
417 argv[0] = (char *) alternate_editor;
419 for (i = 0; argv[i]; i++)
420 if (strchr (argv[i], ' '))
422 char *quoted = alloca (strlen (argv[i]) + 3);
423 sprintf (quoted, "\"%s\"", argv[i]);
424 argv[i] = quoted;
427 return execvp (path, argv);
430 #undef execvp
431 #define execvp w32_execvp
433 #endif /* WINDOWSNT */
435 /* Display a normal or error message.
436 On Windows, use a message box if compiled as a Windows app. */
437 void
438 message (int is_error, char *message, ...)
440 char msg [2048];
441 va_list args;
443 va_start (args, message);
444 vsprintf (msg, message, args);
445 va_end (args);
447 #ifdef WINDOWSNT
448 if (w32_window_app ())
450 if (is_error)
451 MessageBox (NULL, msg, "Emacsclient ERROR", MB_ICONERROR);
452 else
453 MessageBox (NULL, msg, "Emacsclient", MB_ICONINFORMATION);
455 else
456 #endif
458 FILE *f = is_error ? stderr : stdout;
460 fputs (msg, f);
461 fflush (f);
465 /* Decode the options from argv and argc.
466 The global variable `optind' will say how many arguments we used up. */
468 void
469 decode_options (argc, argv)
470 int argc;
471 char **argv;
473 alternate_editor = egetenv ("ALTERNATE_EDITOR");
475 while (1)
477 int opt = getopt_long (argc, argv,
478 #ifndef NO_SOCKETS_IN_FILE_SYSTEM
479 "VHnea:s:f:d:tc",
480 #else
481 "VHnea:f:d:tc",
482 #endif
483 longopts, 0);
485 if (opt == EOF)
486 break;
488 switch (opt)
490 case 0:
491 /* If getopt returns 0, then it has already processed a
492 long-named option. We should do nothing. */
493 break;
495 case 'a':
496 alternate_editor = optarg;
497 break;
499 #ifndef NO_SOCKETS_IN_FILE_SYSTEM
500 case 's':
501 socket_name = optarg;
502 break;
503 #endif
505 case 'f':
506 server_file = optarg;
507 break;
509 /* We used to disallow this argument in w32, but it seems better
510 to allow it, for the occasional case where the user is
511 connecting with a w32 client to a server compiled with X11
512 support. */
513 #if 1 /* !defined WINDOWS */
514 case 'd':
515 display = optarg;
516 break;
517 #endif
519 case 'n':
520 nowait = 1;
521 break;
523 case 'e':
524 eval = 1;
525 break;
527 case 'V':
528 message (FALSE, "emacsclient %s\n", VERSION);
529 exit (EXIT_SUCCESS);
530 break;
532 case 't':
533 tty = 1;
534 current_frame = 0;
535 break;
537 case 'c':
538 current_frame = 0;
539 break;
541 case 'H':
542 print_help_and_exit ();
543 break;
545 default:
546 message (TRUE, "Try `%s --help' for more information\n", progname);
547 exit (EXIT_FAILURE);
548 break;
552 /* We used to set `display' to $DISPLAY by default, but this changed the
553 default behavior and is sometimes inconvenient. So instead of forcing
554 users to say "--display ''" when they want to use Emacs's existing tty
555 or display connection, we force them to use "--display $DISPLAY" if
556 they want Emacs to connect to their current display.
557 -c still implicitly passes --display $DISPLAY unless -t was specified
558 so as to try and mimick the behavior of `emacs' which either uses
559 the current tty or the current $DISPLAY. */
560 if (!current_frame && !tty && !display)
561 display = egetenv ("DISPLAY");
563 if (display && strlen (display) == 0)
564 display = NULL;
566 if (!tty && display)
567 window_system = 1;
568 #if !defined (WINDOWSNT)
569 else if (!current_frame)
570 tty = 1;
571 #endif
573 /* --no-wait implies --current-frame on ttys when there are file
574 arguments or expressions given. */
575 if (nowait && tty && argc - optind > 0)
576 current_frame = 1;
578 if (current_frame)
580 tty = 0;
581 window_system = 0;
584 if (tty)
585 window_system = 0;
589 void
590 print_help_and_exit ()
592 /* Spaces and tabs are significant in this message; they're chosen so the
593 message aligns properly both in a tty and in a Windows message box.
594 Please try to preserve them; otherwise the output is very hard to read
595 when using emacsclientw. */
596 message (FALSE,
597 "Usage: %s [OPTIONS] FILE...\n\
598 Tell the Emacs server to visit the specified files.\n\
599 Every FILE can be either just a FILENAME or [+LINE[:COLUMN]] FILENAME.\n\
601 The following OPTIONS are accepted:\n\
602 -V, --version Just print version info and return\n\
603 -H, --help Print this usage information message\n\
604 -t, --tty Open a new Emacs frame on the current terminal\n\
605 -c, --create-frame Create a new frame instead of trying to\n\
606 use the current Emacs frame\n\
607 -e, --eval Evaluate the FILE arguments as ELisp expressions\n\
608 -n, --no-wait Don't wait for the server to return\n\
609 -d, --display=DISPLAY Visit the file in the given display\n"
610 #ifndef NO_SOCKETS_IN_FILE_SYSTEM
611 "-s, --socket-name=FILENAME\n\
612 Set filename of the UNIX socket for communication\n"
613 #endif
614 "-f, --server-file=FILENAME\n\
615 Set filename of the TCP authentication file\n\
616 -a, --alternate-editor=EDITOR\n\
617 Editor to fallback to if the server is not running\n\
619 Report bugs to bug-gnu-emacs@gnu.org.\n", progname);
620 exit (EXIT_SUCCESS);
624 Try to run a different command, or --if no alternate editor is
625 defined-- exit with an errorcode.
626 Uses argv, but gets it from the global variable main_argv.
628 void
629 fail (void)
631 if (alternate_editor)
633 int i = optind - 1;
635 execvp (alternate_editor, main_argv + i);
636 message (TRUE, "%s: error executing alternate editor \"%s\"\n",
637 progname, alternate_editor);
639 exit (EXIT_FAILURE);
643 #if !defined (HAVE_SOCKETS) || !defined (HAVE_INET_SOCKETS)
646 main (argc, argv)
647 int argc;
648 char **argv;
650 main_argv = argv;
651 progname = argv[0];
652 message (TRUE, "%s: Sorry, the Emacs server is supported only\n"
653 "on systems with Berkeley sockets.\n",
654 argv[0]);
655 fail ();
658 #else /* HAVE_SOCKETS && HAVE_INET_SOCKETS */
660 #ifdef WINDOWSNT
661 # include <winsock2.h>
662 #else
663 # include <sys/types.h>
664 # include <sys/socket.h>
665 # include <sys/un.h>
666 #endif
668 #define AUTH_KEY_LENGTH 64
669 #define SEND_BUFFER_SIZE 4096
671 extern char *strerror ();
672 extern int errno;
674 /* Buffer to accumulate data to send in TCP connections. */
675 char send_buffer[SEND_BUFFER_SIZE + 1];
676 int sblen = 0; /* Fill pointer for the send buffer. */
677 /* Socket used to communicate with the Emacs server process. */
678 HSOCKET emacs_socket = 0;
680 /* On Windows, the socket library was historically separate from the standard
681 C library, so errors are handled differently. */
682 void
683 sock_err_message (function_name)
684 char *function_name;
686 #ifdef WINDOWSNT
687 char* msg = NULL;
689 FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM
690 | FORMAT_MESSAGE_ALLOCATE_BUFFER
691 | FORMAT_MESSAGE_ARGUMENT_ARRAY,
692 NULL, WSAGetLastError (), 0, (LPTSTR)&msg, 0, NULL);
694 message (TRUE, "%s: %s: %s\n", progname, function_name, msg);
696 LocalFree (msg);
697 #else
698 message (TRUE, "%s: %s: %s\n", progname, function_name, strerror (errno));
699 #endif
703 /* Let's send the data to Emacs when either
704 - the data ends in "\n", or
705 - the buffer is full (but this shouldn't happen)
706 Otherwise, we just accumulate it. */
707 void
708 send_to_emacs (s, data)
709 HSOCKET s;
710 char *data;
712 while (data)
714 int dlen = strlen (data);
715 if (dlen + sblen >= SEND_BUFFER_SIZE)
717 int part = SEND_BUFFER_SIZE - sblen;
718 strncpy (&send_buffer[sblen], data, part);
719 data += part;
720 sblen = SEND_BUFFER_SIZE;
722 else if (dlen)
724 strcpy (&send_buffer[sblen], data);
725 data = NULL;
726 sblen += dlen;
728 else
729 break;
731 if (sblen == SEND_BUFFER_SIZE
732 || (sblen > 0 && send_buffer[sblen-1] == '\n'))
734 int sent = send (s, send_buffer, sblen, 0);
735 if (sent != sblen)
736 strcpy (send_buffer, &send_buffer[sent]);
737 sblen -= sent;
743 /* In STR, insert a & before each &, each space, each newline, and
744 any initial -. Change spaces to underscores, too, so that the
745 return value never contains a space.
747 Does not change the string. Outputs the result to STREAM. */
748 void
749 quote_argument (s, str)
750 HSOCKET s;
751 char *str;
753 char *copy = (char *) xmalloc (strlen (str) * 2 + 1);
754 char *p, *q;
756 p = str;
757 q = copy;
758 while (*p)
760 if (*p == ' ')
762 *q++ = '&';
763 *q++ = '_';
764 p++;
766 else if (*p == '\n')
768 *q++ = '&';
769 *q++ = 'n';
770 p++;
772 else
774 if (*p == '&' || (*p == '-' && p == str))
775 *q++ = '&';
776 *q++ = *p++;
779 *q++ = 0;
781 send_to_emacs (s, copy);
783 free (copy);
787 /* The inverse of quote_argument. Removes quoting in string STR by
788 modifying the string in place. Returns STR. */
790 char *
791 unquote_argument (str)
792 char *str;
794 char *p, *q;
796 if (! str)
797 return str;
799 p = str;
800 q = str;
801 while (*p)
803 if (*p == '&')
805 p++;
806 if (*p == '&')
807 *p = '&';
808 else if (*p == '_')
809 *p = ' ';
810 else if (*p == 'n')
811 *p = '\n';
812 else if (*p == '-')
813 *p = '-';
815 *q++ = *p++;
817 *q = 0;
818 return str;
823 file_name_absolute_p (filename)
824 const unsigned char *filename;
826 /* Sanity check, it shouldn't happen. */
827 if (! filename) return FALSE;
829 /* /xxx is always an absolute path. */
830 if (filename[0] == '/') return TRUE;
832 /* Empty filenames (which shouldn't happen) are relative. */
833 if (filename[0] == '\0') return FALSE;
835 #ifdef WINDOWSNT
836 /* X:\xxx is always absolute. */
837 if (isalpha (filename[0])
838 && filename[1] == ':' && (filename[2] == '\\' || filename[2] == '/'))
839 return TRUE;
841 /* Both \xxx and \\xxx\yyy are absolute. */
842 if (filename[0] == '\\') return TRUE;
843 #endif
845 return FALSE;
848 #ifdef WINDOWSNT
849 /* Wrapper to make WSACleanup a cdecl, as required by atexit. */
850 void
851 __cdecl close_winsock ()
853 WSACleanup ();
856 /* Initialize the WinSock2 library. */
857 void
858 initialize_sockets ()
860 WSADATA wsaData;
862 if (WSAStartup (MAKEWORD (2, 0), &wsaData))
864 message (TRUE, "%s: error initializing WinSock2\n", progname);
865 exit (EXIT_FAILURE);
868 atexit (close_winsock);
870 #endif /* WINDOWSNT */
874 * Read the information needed to set up a TCP comm channel with
875 * the Emacs server: host, port, pid and authentication string.
878 get_server_config (server, authentication)
879 struct sockaddr_in *server;
880 char *authentication;
882 char dotted[32];
883 char *port;
884 char *pid;
885 FILE *config = NULL;
887 if (file_name_absolute_p (server_file))
888 config = fopen (server_file, "rb");
889 else
891 char *home = egetenv ("HOME");
893 if (home)
895 char *path = alloca (32 + strlen (home) + strlen (server_file));
896 sprintf (path, "%s/.emacs.d/server/%s", home, server_file);
897 config = fopen (path, "rb");
899 #ifdef WINDOWSNT
900 if (!config && (home = egetenv ("APPDATA")))
902 char *path = alloca (32 + strlen (home) + strlen (server_file));
903 sprintf (path, "%s/.emacs.d/server/%s", home, server_file);
904 config = fopen (path, "rb");
906 #endif
909 if (! config)
910 return FALSE;
912 if (fgets (dotted, sizeof dotted, config)
913 && (port = strchr (dotted, ':'))
914 && (pid = strchr (port, ' ')))
916 *port++ = '\0';
917 *pid++ = '\0';
919 else
921 message (TRUE, "%s: invalid configuration info\n", progname);
922 exit (EXIT_FAILURE);
925 server->sin_family = AF_INET;
926 server->sin_addr.s_addr = inet_addr (dotted);
927 server->sin_port = htons (atoi (port));
929 if (! fread (authentication, AUTH_KEY_LENGTH, 1, config))
931 message (TRUE, "%s: cannot read authentication info\n", progname);
932 exit (EXIT_FAILURE);
935 fclose (config);
937 emacs_pid = atoi (pid);
939 return TRUE;
942 HSOCKET
943 set_tcp_socket ()
945 HSOCKET s;
946 struct sockaddr_in server;
947 struct linger l_arg = {1, 1};
948 char auth_string[AUTH_KEY_LENGTH + 1];
950 if (! get_server_config (&server, auth_string))
951 return INVALID_SOCKET;
953 if (server.sin_addr.s_addr != inet_addr ("127.0.0.1"))
954 message (FALSE, "%s: connected to remote socket at %s\n",
955 progname, inet_ntoa (server.sin_addr));
958 * Open up an AF_INET socket
960 if ((s = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
962 sock_err_message ("socket");
963 return INVALID_SOCKET;
967 * Set up the socket
969 if (connect (s, (struct sockaddr *) &server, sizeof server) < 0)
971 sock_err_message ("connect");
972 return INVALID_SOCKET;
975 setsockopt (s, SOL_SOCKET, SO_LINGER, (char *) &l_arg, sizeof l_arg);
978 * Send the authentication
980 auth_string[AUTH_KEY_LENGTH] = '\0';
982 send_to_emacs (s, "-auth ");
983 send_to_emacs (s, auth_string);
984 send_to_emacs (s, " ");
986 return s;
990 /* Returns 1 if PREFIX is a prefix of STRING. */
991 static int
992 strprefix (char *prefix, char *string)
994 return !strncmp (prefix, string, strlen (prefix));
998 #if !defined (NO_SOCKETS_IN_FILE_SYSTEM)
1000 /* Three possibilities:
1001 2 - can't be `stat'ed (sets errno)
1002 1 - isn't owned by us
1003 0 - success: none of the above */
1005 static int
1006 socket_status (socket_name)
1007 char *socket_name;
1009 struct stat statbfr;
1011 if (stat (socket_name, &statbfr) == -1)
1012 return 2;
1014 if (statbfr.st_uid != geteuid ())
1015 return 1;
1017 return 0;
1021 /* A signal handler that passes the signal to the Emacs process.
1022 Useful for SIGWINCH. */
1024 SIGTYPE
1025 pass_signal_to_emacs (int signalnum)
1027 int old_errno = errno;
1029 if (emacs_pid)
1030 kill (emacs_pid, signalnum);
1032 signal (signalnum, pass_signal_to_emacs);
1033 errno = old_errno;
1036 /* Signal handler for SIGCONT; notify the Emacs process that it can
1037 now resume our tty frame. */
1039 SIGTYPE
1040 handle_sigcont (int signalnum)
1042 int old_errno = errno;
1044 if (tcgetpgrp (1) == getpgrp ())
1046 /* We are in the foreground. */
1047 send_to_emacs (emacs_socket, "-resume \n");
1049 else
1051 /* We are in the background; cancel the continue. */
1052 kill (getpid (), SIGSTOP);
1055 signal (signalnum, handle_sigcont);
1056 errno = old_errno;
1059 /* Signal handler for SIGTSTP; notify the Emacs process that we are
1060 going to sleep. Normally the suspend is initiated by Emacs via
1061 server-handle-suspend-tty, but if the server gets out of sync with
1062 reality, we may get a SIGTSTP on C-z. Handling this signal and
1063 notifying Emacs about it should get things under control again. */
1065 SIGTYPE
1066 handle_sigtstp (int signalnum)
1068 int old_errno = errno;
1069 sigset_t set;
1071 if (emacs_socket)
1072 send_to_emacs (emacs_socket, "-suspend \n");
1074 /* Unblock this signal and call the default handler by temporarily
1075 changing the handler and resignalling. */
1076 sigprocmask (SIG_BLOCK, NULL, &set);
1077 sigdelset (&set, signalnum);
1078 signal (signalnum, SIG_DFL);
1079 kill (getpid (), signalnum);
1080 sigprocmask (SIG_SETMASK, &set, NULL); /* Let's the above signal through. */
1081 signal (signalnum, handle_sigtstp);
1083 errno = old_errno;
1085 /* Set up signal handlers before opening a frame on the current tty. */
1087 void
1088 init_signals (void)
1090 /* Set up signal handlers. */
1091 signal (SIGWINCH, pass_signal_to_emacs);
1093 /* Don't pass SIGINT and SIGQUIT to Emacs, because it has no way of
1094 deciding which terminal the signal came from. C-g is now a
1095 normal input event on secondary terminals. */
1096 #if 0
1097 signal (SIGINT, pass_signal_to_emacs);
1098 signal (SIGQUIT, pass_signal_to_emacs);
1099 #endif
1101 signal (SIGCONT, handle_sigcont);
1102 signal (SIGTSTP, handle_sigtstp);
1103 signal (SIGTTOU, handle_sigtstp);
1107 HSOCKET
1108 set_local_socket ()
1110 HSOCKET s;
1111 struct sockaddr_un server;
1114 * Open up an AF_UNIX socket in this person's home directory
1117 if ((s = socket (AF_UNIX, SOCK_STREAM, 0)) < 0)
1119 message (TRUE, "%s: socket: %s\n", progname, strerror (errno));
1120 return INVALID_SOCKET;
1123 server.sun_family = AF_UNIX;
1126 int sock_status = 0;
1127 int default_sock = !socket_name;
1128 int saved_errno = 0;
1129 char *server_name = "server";
1131 if (socket_name && !index (socket_name, '/') && !index (socket_name, '\\'))
1132 { /* socket_name is a file name component. */
1133 server_name = socket_name;
1134 socket_name = NULL;
1135 default_sock = 1; /* Try both UIDs. */
1138 if (default_sock)
1140 socket_name = alloca (100 + strlen (server_name));
1141 sprintf (socket_name, "/tmp/emacs%d/%s",
1142 (int) geteuid (), server_name);
1145 if (strlen (socket_name) < sizeof (server.sun_path))
1146 strcpy (server.sun_path, socket_name);
1147 else
1149 message (TRUE, "%s: socket-name %s too long\n",
1150 progname, socket_name);
1151 fail ();
1154 /* See if the socket exists, and if it's owned by us. */
1155 sock_status = socket_status (server.sun_path);
1156 saved_errno = errno;
1157 if (sock_status && default_sock)
1159 /* Failing that, see if LOGNAME or USER exist and differ from
1160 our euid. If so, look for a socket based on the UID
1161 associated with the name. This is reminiscent of the logic
1162 that init_editfns uses to set the global Vuser_full_name. */
1164 char *user_name = (char *) egetenv ("LOGNAME");
1166 if (!user_name)
1167 user_name = (char *) egetenv ("USER");
1169 if (user_name)
1171 struct passwd *pw = getpwnam (user_name);
1173 if (pw && (pw->pw_uid != geteuid ()))
1175 /* We're running under su, apparently. */
1176 socket_name = alloca (100 + strlen (server_name));
1177 sprintf (socket_name, "/tmp/emacs%d/%s",
1178 (int) pw->pw_uid, server_name);
1180 if (strlen (socket_name) < sizeof (server.sun_path))
1181 strcpy (server.sun_path, socket_name);
1182 else
1184 message (TRUE, "%s: socket-name %s too long\n",
1185 progname, socket_name);
1186 exit (EXIT_FAILURE);
1189 sock_status = socket_status (server.sun_path);
1190 saved_errno = errno;
1192 else
1193 errno = saved_errno;
1197 switch (sock_status)
1199 case 1:
1200 /* There's a socket, but it isn't owned by us. This is OK if
1201 we are root. */
1202 if (0 != geteuid ())
1204 message (TRUE, "%s: Invalid socket owner\n", progname);
1205 return INVALID_SOCKET;
1207 break;
1209 case 2:
1210 /* `stat' failed */
1211 if (saved_errno == ENOENT)
1212 message (TRUE,
1213 "%s: can't find socket; have you started the server?\n\
1214 To start the server in Emacs, type \"M-x server-start\".\n",
1215 progname);
1216 else
1217 message (TRUE, "%s: can't stat %s: %s\n",
1218 progname, server.sun_path, strerror (saved_errno));
1219 return INVALID_SOCKET;
1223 if (connect (s, (struct sockaddr *) &server, strlen (server.sun_path) + 2)
1224 < 0)
1226 message (TRUE, "%s: connect: %s\n", progname, strerror (errno));
1227 return INVALID_SOCKET;
1230 return s;
1232 #endif /* ! NO_SOCKETS_IN_FILE_SYSTEM */
1234 HSOCKET
1235 set_socket ()
1237 HSOCKET s;
1239 INITIALIZE ();
1241 #ifndef NO_SOCKETS_IN_FILE_SYSTEM
1242 /* Explicit --socket-name argument. */
1243 if (socket_name)
1245 s = set_local_socket ();
1246 if ((s != INVALID_SOCKET) || alternate_editor)
1247 return s;
1248 message (TRUE, "%s: error accessing socket \"%s\"\n",
1249 progname, socket_name);
1250 exit (EXIT_FAILURE);
1252 #endif
1254 /* Explicit --server-file arg or EMACS_SERVER_FILE variable. */
1255 if (!server_file)
1256 server_file = egetenv ("EMACS_SERVER_FILE");
1258 if (server_file)
1260 s = set_tcp_socket ();
1261 if ((s != INVALID_SOCKET) || alternate_editor)
1262 return s;
1264 message (TRUE, "%s: error accessing server file \"%s\"\n",
1265 progname, server_file);
1266 exit (EXIT_FAILURE);
1269 #ifndef NO_SOCKETS_IN_FILE_SYSTEM
1270 /* Implicit local socket. */
1271 s = set_local_socket ();
1272 if (s != INVALID_SOCKET)
1273 return s;
1274 #endif
1276 /* Implicit server file. */
1277 server_file = "server";
1278 s = set_tcp_socket ();
1279 if ((s != INVALID_SOCKET) || alternate_editor)
1280 return s;
1282 /* No implicit or explicit socket, and no alternate editor. */
1283 message (TRUE, "%s: No socket or alternate editor. Please use:\n\n"
1284 #ifndef NO_SOCKETS_IN_FILE_SYSTEM
1285 "\t--socket-name\n"
1286 #endif
1287 "\t--server-file (or environment variable EMACS_SERVER_FILE)\n\
1288 \t--alternate-editor (or environment variable ALTERNATE_EDITOR)\n",
1289 progname);
1290 exit (EXIT_FAILURE);
1293 #ifdef WINDOWSNT
1294 FARPROC set_fg; /* Pointer to AllowSetForegroundWindow. */
1295 FARPROC get_wc; /* Pointer to RealGetWindowClassA. */
1297 BOOL CALLBACK
1298 w32_find_emacs_process (hWnd, lParam)
1299 HWND hWnd;
1300 LPARAM lParam;
1302 DWORD pid;
1303 char class[6];
1305 /* Reject any window not of class "Emacs". */
1306 if (! get_wc (hWnd, class, sizeof (class))
1307 || strcmp (class, "Emacs"))
1308 return TRUE;
1310 /* We only need the process id, not the thread id. */
1311 (void) GetWindowThreadProcessId (hWnd, &pid);
1313 /* Not the one we're looking for. */
1314 if (pid != (DWORD) emacs_pid) return TRUE;
1316 /* OK, let's raise it. */
1317 set_fg (emacs_pid);
1319 /* Stop enumeration. */
1320 return FALSE;
1324 * Search for a window of class "Emacs" and owned by a process with
1325 * process id = emacs_pid. If found, allow it to grab the focus.
1327 void
1328 w32_give_focus ()
1330 HMODULE hUser32;
1332 /* It shouldn't happen when dealing with TCP sockets. */
1333 if (!emacs_pid) return;
1335 if (!(hUser32 = LoadLibrary ("user32.dll"))) return;
1337 /* Modern Windows restrict which processes can set the foreground window.
1338 emacsclient can allow Emacs to grab the focus by calling the function
1339 AllowSetForegroundWindow. Unfortunately, older Windows (W95, W98 and
1340 NT) lack this function, so we have to check its availability. */
1341 if ((set_fg = GetProcAddress (hUser32, "AllowSetForegroundWindow"))
1342 && (get_wc = GetProcAddress (hUser32, "RealGetWindowClassA")))
1343 EnumWindows (w32_find_emacs_process, (LPARAM) 0);
1345 FreeLibrary (hUser32);
1347 #endif
1350 main (argc, argv)
1351 int argc;
1352 char **argv;
1354 int i, rl, needlf = 0;
1355 char *cwd, *str;
1356 char string[BUFSIZ+1];
1358 main_argv = argv;
1359 progname = argv[0];
1361 /* Process options. */
1362 decode_options (argc, argv);
1364 if ((argc - optind < 1) && !eval && !tty && !window_system)
1366 message (TRUE, "%s: file name or argument required\n"
1367 "Try `%s --help' for more information\n",
1368 progname, progname);
1369 exit (EXIT_FAILURE);
1372 if ((emacs_socket = set_socket ()) == INVALID_SOCKET)
1373 fail ();
1376 cwd = get_current_dir_name ();
1377 if (cwd == 0)
1379 /* getwd puts message in STRING if it fails. */
1380 message (TRUE, "%s: %s\n", progname,
1381 "Cannot get current working directory");
1382 fail ();
1385 #ifdef WINDOWSNT
1386 w32_give_focus ();
1387 #endif
1389 /* Send over our environment. */
1390 if (!current_frame)
1392 extern char **environ;
1393 int i;
1394 for (i = 0; environ[i]; i++)
1396 char *name = xstrdup (environ[i]);
1397 char *value = strchr (name, '=');
1398 send_to_emacs (emacs_socket, "-env ");
1399 quote_argument (emacs_socket, environ[i]);
1400 send_to_emacs (emacs_socket, " ");
1404 /* Send over our current directory. */
1405 if (!current_frame)
1407 send_to_emacs (emacs_socket, "-dir ");
1408 quote_argument (emacs_socket, cwd);
1409 send_to_emacs (emacs_socket, "/");
1410 send_to_emacs (emacs_socket, " ");
1413 retry:
1414 if (nowait)
1415 send_to_emacs (emacs_socket, "-nowait ");
1417 if (current_frame)
1418 send_to_emacs (emacs_socket, "-current-frame ");
1420 if (display)
1422 send_to_emacs (emacs_socket, "-display ");
1423 quote_argument (emacs_socket, display);
1424 send_to_emacs (emacs_socket, " ");
1427 if (tty)
1429 char *type = egetenv ("TERM");
1430 char *tty_name = NULL;
1431 #ifndef WINDOWSNT
1432 tty_name = ttyname (fileno (stdin));
1433 #endif
1435 if (! tty_name)
1437 message (TRUE, "%s: could not get terminal name\n", progname);
1438 fail ();
1441 if (! type)
1443 message (TRUE, "%s: please set the TERM variable to your terminal type\n",
1444 progname);
1445 fail ();
1448 if (! strcmp (type, "eterm"))
1450 /* This causes nasty, MULTI_KBOARD-related input lockouts. */
1451 message (TRUE, "%s: opening a frame in an Emacs term buffer"
1452 " is not supported\n", progname);
1453 fail ();
1455 #if !defined (NO_SOCKETS_IN_FILE_SYSTEM)
1456 init_signals ();
1457 #endif
1459 send_to_emacs (emacs_socket, "-tty ");
1460 quote_argument (emacs_socket, tty_name);
1461 send_to_emacs (emacs_socket, " ");
1462 quote_argument (emacs_socket, type);
1463 send_to_emacs (emacs_socket, " ");
1466 if (window_system)
1467 send_to_emacs (emacs_socket, "-window-system ");
1469 if ((argc - optind > 0))
1471 for (i = optind; i < argc; i++)
1473 int relative = 0;
1475 if (eval)
1477 /* Don't prepend cwd or anything like that. */
1478 send_to_emacs (emacs_socket, "-eval ");
1479 quote_argument (emacs_socket, argv[i]);
1480 send_to_emacs (emacs_socket, " ");
1481 continue;
1484 if (*argv[i] == '+')
1486 char *p = argv[i] + 1;
1487 while (isdigit ((unsigned char) *p) || *p == ':') p++;
1488 if (*p == 0)
1490 send_to_emacs (emacs_socket, "-position ");
1491 quote_argument (emacs_socket, argv[i]);
1492 send_to_emacs (emacs_socket, " ");
1493 continue;
1495 else
1496 relative = 1;
1498 else if (! file_name_absolute_p (argv[i]))
1499 #ifndef WINDOWSNT
1500 relative = 1;
1501 #else
1502 /* Call GetFullPathName so filenames of the form X:Y, where X is
1503 a valid drive designator, are interpreted as drive:path, not
1504 file:stream, and treated as absolute.
1505 The user can still pass a file:stream if desired (for example,
1506 .\X:Y), but it is not very useful, as Emacs currently does a
1507 very bad job of dealing wih NTFS streams. */
1509 char *filename = (char *) xmalloc (MAX_PATH);
1510 DWORD size;
1512 size = GetFullPathName (argv[i], MAX_PATH, filename, NULL);
1513 if (size > 0 && size < MAX_PATH)
1514 argv[i] = filename;
1515 else
1517 relative = 1;
1518 free (filename);
1521 #endif
1523 send_to_emacs (emacs_socket, "-file ");
1524 if (relative)
1526 quote_argument (emacs_socket, cwd);
1527 send_to_emacs (emacs_socket, "/");
1529 quote_argument (emacs_socket, argv[i]);
1530 send_to_emacs (emacs_socket, " ");
1533 else
1535 if (!tty && !window_system)
1537 while ((str = fgets (string, BUFSIZ, stdin)))
1539 if (eval)
1540 send_to_emacs (emacs_socket, "-eval ");
1541 else
1542 send_to_emacs (emacs_socket, "-file ");
1543 quote_argument (emacs_socket, str);
1545 send_to_emacs (emacs_socket, " ");
1549 send_to_emacs (emacs_socket, "\n");
1551 /* Wait for an answer. */
1552 if (!eval && !tty && !nowait)
1554 printf ("Waiting for Emacs...");
1555 needlf = 2;
1557 fflush (stdout);
1558 fsync (1);
1560 /* Now, wait for an answer and print any messages. */
1561 while ((rl = recv (emacs_socket, string, BUFSIZ, 0)) > 0)
1563 char *p;
1564 string[rl] = '\0';
1566 p = string + strlen (string) - 1;
1567 while (p > string && *p == '\n')
1568 *p-- = 0;
1570 if (strprefix ("-emacs-pid ", string))
1572 /* -emacs-pid PID: The process id of the Emacs process. */
1573 emacs_pid = strtol (string + strlen ("-emacs-pid"), NULL, 10);
1575 else if (strprefix ("-window-system-unsupported ", string))
1577 /* -window-system-unsupported: Emacs was compiled without X
1578 support. Try again on the terminal. */
1579 window_system = 0;
1580 nowait = 0;
1581 tty = 1;
1582 goto retry;
1584 else if (strprefix ("-print ", string))
1586 /* -print STRING: Print STRING on the terminal. */
1587 str = unquote_argument (string + strlen ("-print "));
1588 if (needlf)
1589 printf ("\n");
1590 printf ("%s", str);
1591 needlf = str[0] == '\0' ? needlf : str[strlen (str) - 1] != '\n';
1593 else if (strprefix ("-error ", string))
1595 /* -error DESCRIPTION: Signal an error on the terminal. */
1596 str = unquote_argument (string + strlen ("-error "));
1597 if (needlf)
1598 printf ("\n");
1599 fprintf (stderr, "*ERROR*: %s", str);
1600 needlf = str[0] == '\0' ? needlf : str[strlen (str) - 1] != '\n';
1602 #ifdef SIGSTOP
1603 else if (strprefix ("-suspend ", string))
1605 /* -suspend: Suspend this terminal, i.e., stop the process. */
1606 if (needlf)
1607 printf ("\n");
1608 needlf = 0;
1609 kill (0, SIGSTOP);
1611 #endif
1612 else
1614 /* Unknown command. */
1615 if (needlf)
1616 printf ("\n");
1617 printf ("*ERROR*: Unknown message: %s", string);
1618 needlf = string[0] == '\0' ? needlf : string[strlen (string) - 1] != '\n';
1622 if (needlf)
1623 printf ("\n");
1624 fflush (stdout);
1625 fsync (1);
1627 CLOSE_SOCKET (emacs_socket);
1628 return EXIT_SUCCESS;
1631 #endif /* HAVE_SOCKETS && HAVE_INET_SOCKETS */
1634 #ifndef HAVE_STRERROR
1635 char *
1636 strerror (errnum)
1637 int errnum;
1639 extern char *sys_errlist[];
1640 extern int sys_nerr;
1642 if (errnum >= 0 && errnum < sys_nerr)
1643 return sys_errlist[errnum];
1644 return (char *) "Unknown error";
1647 #endif /* ! HAVE_STRERROR */
1649 /* arch-tag: f39bb9c4-73eb-477e-896d-50832e2ca9a7
1650 (do not change this comment) */
1652 /* emacsclient.c ends here */