]>
code.delx.au - gnu-emacs/blob - 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.
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 2, or (at your option)
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; 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. */
35 # define HAVE_INET_SOCKETS
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 # ifdef HAVE_INET_SOCKETS
45 # include <netinet/in.h>
48 # define INVALID_SOCKET -1
50 # define CLOSE_SOCKET close
53 #endif /* !WINDOWSNT */
69 #else /* not WINDOWSNT */
71 #endif /* not WINDOWSNT */
74 char *getenv (), *getwd ();
78 #define VERSION "unspecified"
81 #define SEND_STRING(data) (send_to_emacs (s, (data)))
82 #define SEND_QUOTED(data) (quote_file_name (s, (data)))
85 #define EXIT_SUCCESS 0
89 #define EXIT_FAILURE 1
104 /* Name used to invoke this program. */
107 /* Nonzero means don't wait for a response from Emacs. --no-wait. */
110 /* Nonzero means args are expressions to be evaluated. --eval. */
113 /* The display on which Emacs should work. --display. */
114 char *display
= NULL
;
116 /* If non-NULL, the name of an editor to fallback to if the server
117 is not running. --alternate-editor. */
118 const char *alternate_editor
= NULL
;
120 /* If non-NULL, the filename of the UNIX socket. */
121 char *socket_name
= NULL
;
123 /* If non-NULL, the filename of the authentication file. */
124 char *server_file
= NULL
;
126 void print_help_and_exit () NO_RETURN
;
128 struct option longopts
[] =
130 { "no-wait", no_argument
, NULL
, 'n' },
131 { "eval", no_argument
, NULL
, 'e' },
132 { "help", no_argument
, NULL
, 'H' },
133 { "version", no_argument
, NULL
, 'V' },
134 { "alternate-editor", required_argument
, NULL
, 'a' },
135 #ifndef NO_SOCKETS_IN_FILE_SYSTEM
136 { "socket-name", required_argument
, NULL
, 's' },
138 { "server-file", required_argument
, NULL
, 'f' },
139 { "display", required_argument
, NULL
, 'd' },
143 /* Decode the options from argv and argc.
144 The global variable `optind' will say how many arguments we used up. */
147 decode_options (argc
, argv
)
151 alternate_editor
= getenv ("ALTERNATE_EDITOR");
155 int opt
= getopt_long (argc
, argv
,
156 #ifndef NO_SOCKETS_IN_FILE_SYSTEM
169 /* If getopt returns 0, then it has already processed a
170 long-named option. We should do nothing. */
174 alternate_editor
= optarg
;
177 #ifndef NO_SOCKETS_IN_FILE_SYSTEM
179 socket_name
= optarg
;
184 server_file
= optarg
;
200 printf ("emacsclient %s\n", VERSION
);
205 print_help_and_exit ();
209 fprintf (stderr
, "Try `%s --help' for more information\n", progname
);
217 print_help_and_exit ()
220 "Usage: %s [OPTIONS] FILE...\n\
221 Tell the Emacs server to visit the specified files.\n\
222 Every FILE can be either just a FILENAME or [+LINE[:COLUMN]] FILENAME.\n\
224 The following OPTIONS are accepted:\n\
225 -V, --version Just print a version info and return\n\
226 -H, --help Print this usage information message\n\
227 -n, --no-wait Don't wait for the server to return\n\
228 -e, --eval Evaluate the FILE arguments as ELisp expressions\n\
229 -d, --display=DISPLAY Visit the file in the given display\n"
230 #ifndef NO_SOCKETS_IN_FILE_SYSTEM
231 "-s, --socket-name=FILENAME\n\
232 Set the filename of the UNIX socket for communication\n"
234 "-f, --server-file=FILENAME\n\
235 Set the filename of the TCP configuration file\n\
236 -a, --alternate-editor=EDITOR\n\
237 Editor to fallback to if the server is not running\n\
239 Report bugs to bug-gnu-emacs@gnu.org.\n", progname
);
245 Try to run a different command, or --if no alternate editor is
246 defined-- exit with an errorcode.
253 if (alternate_editor
)
257 argv
[i
] = (char *)alternate_editor
;
259 execvp (alternate_editor
, argv
+ i
);
260 fprintf (stderr
, "%s: error executing alternate editor \"%s\"\n",
261 progname
, alternate_editor
);
267 #if !defined (HAVE_SOCKETS) || !defined (HAVE_INET_SOCKETS)
274 fprintf (stderr
, "%s: Sorry, the Emacs server is supported only\n",
276 fprintf (stderr
, "on systems with Berkeley sockets.\n");
281 #else /* HAVE_SOCKETS && HAVE_INET_SOCKETS */
284 # include <winsock2.h>
286 # include <sys/types.h>
287 # include <sys/socket.h>
289 # include <sys/stat.h>
293 #define AUTH_KEY_LENGTH 64
294 #define SEND_BUFFER_SIZE 4096
296 extern char *strerror ();
299 /* Buffer to accumulate data to send in TCP connections. */
300 char send_buffer
[SEND_BUFFER_SIZE
+ 1];
301 int sblen
= 0; /* Fill pointer for the send buffer. */
303 /* Let's send the data to Emacs when either
304 - the data ends in "\n", or
305 - the buffer is full (but this shouldn't happen)
306 Otherwise, we just accumulate it. */
308 send_to_emacs (s
, data
)
314 int dlen
= strlen (data
);
315 if (dlen
+ sblen
>= SEND_BUFFER_SIZE
)
317 int part
= SEND_BUFFER_SIZE
- sblen
;
318 strncpy (&send_buffer
[sblen
], data
, part
);
320 sblen
= SEND_BUFFER_SIZE
;
324 strcpy (&send_buffer
[sblen
], data
);
331 if (sblen
== SEND_BUFFER_SIZE
332 || (sblen
> 0 && send_buffer
[sblen
-1] == '\n'))
334 int sent
= send (s
, send_buffer
, sblen
, 0);
336 strcpy (send_buffer
, &send_buffer
[sent
]);
342 /* In NAME, insert a & before each &, each space, each newline, and
343 any initial -. Change spaces to underscores, too, so that the
344 return value never contains a space. */
346 quote_file_name (s
, name
)
350 char *copy
= (char *) malloc (strlen (name
) * 2 + 1);
371 if (*p
== '&' || (*p
== '-' && p
== name
))
384 file_name_absolute_p (filename
)
385 const unsigned char *filename
;
387 /* Sanity check, it shouldn't happen. */
388 if (! filename
) return FALSE
;
390 /* /xxx is always an absolute path. */
391 if (filename
[0] == '/') return TRUE
;
393 /* Empty filenames (which shouldn't happen) are relative. */
394 if (filename
[0] == '\0') return FALSE
;
397 /* X:\xxx is always absolute; X:xxx is an error and will fail. */
398 if (islower (tolower (filename
[0]))
399 && filename
[1] == ':' && filename
[2] == '\\')
402 /* Both \xxx and \\xxx\yyy are absolute. */
403 if (filename
[0] == '\\') return TRUE
;
410 /* Wrapper to make WSACleanup a cdecl, as required by atexit(). */
412 __cdecl
close_winsock ()
417 /* Initialize the WinSock2 library. */
419 initialize_sockets ()
423 if (WSAStartup (MAKEWORD (2, 0), &wsaData
))
425 fprintf (stderr
, "%s: error initializing WinSock2", progname
);
429 atexit (close_winsock
);
431 #endif /* WINDOWSNT */
434 * Read the information needed to set up a TCP comm channel with
435 * the Emacs server: host, port and authentication string.
438 get_server_config (server
, authentication
)
439 struct sockaddr_in
*server
;
440 char *authentication
;
446 if (file_name_absolute_p (server_file
))
447 config
= fopen (server_file
, "rb");
450 char *home
= getenv ("HOME");
453 home
= getenv ("APPDATA");
457 char *path
= alloca (32 + strlen (home
) + strlen (server_file
));
458 sprintf (path
, "%s/.emacs.d/server/%s", home
, server_file
);
459 config
= fopen (path
, "rb");
466 if (fgets (dotted
, sizeof dotted
, config
)
467 && (port
= strchr (dotted
, ':')))
473 fprintf (stderr
, "%s: invalid configuration info", progname
);
477 server
->sin_family
= AF_INET
;
478 server
->sin_addr
.s_addr
= inet_addr (dotted
);
479 server
->sin_port
= htons (atoi (port
));
481 if (! fread (authentication
, AUTH_KEY_LENGTH
, 1, config
))
483 fprintf (stderr
, "%s: cannot read authentication info", progname
);
496 struct sockaddr_in server
;
497 struct linger l_arg
= {1, 1};
498 char auth_string
[AUTH_KEY_LENGTH
+ 1];
500 if (! get_server_config (&server
, auth_string
))
501 return INVALID_SOCKET
;
503 if (server
.sin_addr
.s_addr
!= inet_addr ("127.0.0.1"))
504 fprintf (stderr
, "%s: connected to remote socket at %s\n",
505 progname
, inet_ntoa (server
.sin_addr
));
508 * Open up an AF_INET socket
510 if ((s
= socket (AF_INET
, SOCK_STREAM
, IPPROTO_TCP
)) < 0)
512 fprintf (stderr
, "%s: ", progname
);
514 return INVALID_SOCKET
;
520 if (connect (s
, (struct sockaddr
*) &server
, sizeof server
) < 0)
522 fprintf (stderr
, "%s: ", progname
);
524 return INVALID_SOCKET
;
527 setsockopt (s
, SOL_SOCKET
, SO_LINGER
, (char *) &l_arg
, sizeof l_arg
);
530 * Send the authentication
532 auth_string
[AUTH_KEY_LENGTH
] = '\0';
534 SEND_STRING ("-auth ");
535 SEND_STRING (auth_string
);
541 #if !defined (NO_SOCKETS_IN_FILE_SYSTEM)
543 /* Three possibilities:
544 2 - can't be `stat'ed (sets errno)
545 1 - isn't owned by us
546 0 - success: none of the above */
549 socket_status (socket_name
)
554 if (stat (socket_name
, &statbfr
) == -1)
557 if (statbfr
.st_uid
!= geteuid ())
567 struct sockaddr_un server
;
570 * Open up an AF_UNIX socket in this person's home directory
573 if ((s
= socket (AF_UNIX
, SOCK_STREAM
, 0)) < 0)
575 fprintf (stderr
, "%s: ", progname
);
577 return INVALID_SOCKET
;
580 server
.sun_family
= AF_UNIX
;
584 int default_sock
= !socket_name
;
586 char *server_name
= "server";
588 if (socket_name
&& !index (socket_name
, '/') && !index (socket_name
, '\\'))
589 { /* socket_name is a file name component. */
590 server_name
= socket_name
;
592 default_sock
= 1; /* Try both UIDs. */
597 socket_name
= alloca (100 + strlen (server_name
));
598 sprintf (socket_name
, "/tmp/emacs%d/%s",
599 (int) geteuid (), server_name
);
602 if (strlen (socket_name
) < sizeof (server
.sun_path
))
603 strcpy (server
.sun_path
, socket_name
);
606 fprintf (stderr
, "%s: socket-name %s too long",
607 progname
, socket_name
);
611 /* See if the socket exists, and if it's owned by us. */
612 sock_status
= socket_status (server
.sun_path
);
614 if (sock_status
&& default_sock
)
616 /* Failing that, see if LOGNAME or USER exist and differ from
617 our euid. If so, look for a socket based on the UID
618 associated with the name. This is reminiscent of the logic
619 that init_editfns uses to set the global Vuser_full_name. */
621 char *user_name
= (char *) getenv ("LOGNAME");
624 user_name
= (char *) getenv ("USER");
628 struct passwd
*pw
= getpwnam (user_name
);
630 if (pw
&& (pw
->pw_uid
!= geteuid ()))
632 /* We're running under su, apparently. */
633 socket_name
= alloca (100 + strlen (server_name
));
634 sprintf (socket_name
, "/tmp/emacs%d/%s",
635 (int) pw
->pw_uid
, server_name
);
637 if (strlen (socket_name
) < sizeof (server
.sun_path
))
638 strcpy (server
.sun_path
, socket_name
);
641 fprintf (stderr
, "%s: socket-name %s too long",
642 progname
, socket_name
);
646 sock_status
= socket_status (server
.sun_path
);
657 /* There's a socket, but it isn't owned by us. This is OK if
661 fprintf (stderr
, "%s: Invalid socket owner\n", progname
);
662 return INVALID_SOCKET
;
668 if (saved_errno
== ENOENT
)
670 "%s: can't find socket; have you started the server?\n\
671 To start the server in Emacs, type \"M-x server-start\".\n",
674 fprintf (stderr
, "%s: can't stat %s: %s\n",
675 progname
, server
.sun_path
, strerror (saved_errno
));
676 return INVALID_SOCKET
;
680 if (connect (s
, (struct sockaddr
*) &server
, strlen (server
.sun_path
) + 2)
683 fprintf (stderr
, "%s: ", progname
);
685 return INVALID_SOCKET
;
690 #endif /* ! NO_SOCKETS_IN_FILE_SYSTEM */
699 #ifndef NO_SOCKETS_IN_FILE_SYSTEM
700 /* Explicit --socket-name argument. */
703 s
= set_local_socket ();
704 if ((s
!= INVALID_SOCKET
) || alternate_editor
)
707 fprintf (stderr
, "%s: error accessing socket \"%s\"",
708 progname
, socket_name
);
713 /* Explicit --server-file arg or EMACS_SERVER_FILE variable. */
715 server_file
= getenv ("EMACS_SERVER_FILE");
719 s
= set_tcp_socket ();
720 if ((s
!= INVALID_SOCKET
) || alternate_editor
)
723 fprintf (stderr
, "%s: error accessing server file \"%s\"",
724 progname
, server_file
);
728 #ifndef NO_SOCKETS_IN_FILE_SYSTEM
729 /* Implicit local socket. */
730 s
= set_local_socket ();
731 if (s
!= INVALID_SOCKET
)
735 /* Implicit server file. */
736 server_file
= "server";
737 s
= set_tcp_socket ();
738 if ((s
!= INVALID_SOCKET
) || alternate_editor
)
741 /* No implicit or explicit socket, and no alternate editor. */
742 fprintf (stderr
, "%s: No socket or alternate editor. Please use:\n\n"
743 #ifndef NO_SOCKETS_IN_FILE_SYSTEM
746 "\t--server-file (or environment variable EMACS_SERVER_FILE)\n\
747 \t--alternate-editor (or environment variable ALTERNATE_EDITOR)\n",
758 int i
, rl
, needlf
= 0;
760 char string
[BUFSIZ
+1];
764 /* Process options. */
765 decode_options (argc
, argv
);
767 if ((argc
- optind
< 1) && !eval
)
769 fprintf (stderr
, "%s: file name or argument required\n", progname
);
770 fprintf (stderr
, "Try `%s --help' for more information\n", progname
);
774 if ((s
= set_socket ()) == INVALID_SOCKET
)
778 cwd
= getcwd (string
, sizeof string
);
780 cwd
= getwd (string
);
784 /* getwd puts message in STRING if it fails. */
786 fprintf (stderr
, "%s: %s (%s)\n", progname
,
787 "Cannot get current working directory", strerror (errno
));
789 fprintf (stderr
, "%s: %s (%s)\n", progname
, string
, strerror (errno
));
795 SEND_STRING ("-nowait ");
798 SEND_STRING ("-eval ");
802 SEND_STRING ("-display ");
803 SEND_QUOTED (display
);
807 if ((argc
- optind
> 0))
809 for (i
= optind
; i
< argc
; i
++)
812 ; /* Don't prepend any cwd or anything like that. */
813 else if (*argv
[i
] == '+')
815 char *p
= argv
[i
] + 1;
816 while (isdigit ((unsigned char) *p
) || *p
== ':') p
++;
823 else if (! file_name_absolute_p (argv
[i
]))
829 SEND_QUOTED (argv
[i
]);
835 while (fgets (string
, BUFSIZ
, stdin
))
837 SEND_QUOTED (string
);
844 /* Maybe wait for an answer. */
849 printf ("Waiting for Emacs...");
854 /* Now, wait for an answer and print any messages. */
855 while ((rl
= recv (s
, string
, BUFSIZ
, 0)) > 0)
860 printf ("%s", string
);
861 needlf
= string
[0] == '\0' ? needlf
: string
[strlen (string
) - 1] != '\n';
873 #endif /* HAVE_SOCKETS && HAVE_INET_SOCKETS */
875 #ifndef HAVE_STRERROR
880 extern char *sys_errlist
[];
883 if (errnum
>= 0 && errnum
< sys_nerr
)
884 return sys_errlist
[errnum
];
885 return (char *) "Unknown error";
888 #endif /* ! HAVE_STRERROR */
890 /* arch-tag: f39bb9c4-73eb-477e-896d-50832e2ca9a7
891 (do not change this comment) */
893 /* emacsclient.c ends here */