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. */
31 #define NO_SOCKETS_IN_FILE_SYSTEM
35 # define HSOCKET SOCKET
36 # define CLOSE_SOCKET closesocket
37 # define IOCTL ioctlsocket
38 # define INITIALIZE() (initialize_sockets ())
39 typedef unsigned long IOCTL_BOOL_ARG
;
41 # include <netinet/in.h>
42 # include <sys/ioctl.h>
43 # define INVALID_SOCKET -1
45 # define CLOSE_SOCKET close
48 typedef int IOCTL_BOOL_ARG
;
65 #else /* not WINDOWSNT */
67 #endif /* not WINDOWSNT */
70 char *getenv (), *getwd ();
74 #define VERSION "unspecified"
77 #define SEND_STRING(data) (send_to_emacs (s, (data)))
78 #define SEND_QUOTED(data) (quote_file_name (s, (data)))
81 #define EXIT_SUCCESS 0
85 #define EXIT_FAILURE 1
100 /* Name used to invoke this program. */
103 /* Nonzero means don't wait for a response from Emacs. --no-wait. */
106 /* Nonzero means args are expressions to be evaluated. --eval. */
109 /* The display on which Emacs should work. --display. */
110 char *display
= NULL
;
112 /* If non-NULL, the name of an editor to fallback to if the server
113 is not running. --alternate-editor. */
114 const char * alternate_editor
= NULL
;
116 /* If non-NULL, the filename of the UNIX socket. */
117 char *socket_name
= NULL
;
119 /* If non-NULL, the filename of the authentication file. */
120 char *server_file
= NULL
;
122 void print_help_and_exit () NO_RETURN
;
124 struct option longopts
[] =
126 { "no-wait", no_argument
, NULL
, 'n' },
127 { "eval", no_argument
, NULL
, 'e' },
128 { "help", no_argument
, NULL
, 'H' },
129 { "version", no_argument
, NULL
, 'V' },
130 { "alternate-editor", required_argument
, NULL
, 'a' },
131 { "socket-name", required_argument
, NULL
, 's' },
132 { "server-file", required_argument
, NULL
, 'f' },
133 { "display", required_argument
, NULL
, 'd' },
137 /* Decode the options from argv and argc.
138 The global variable `optind' will say how many arguments we used up. */
141 decode_options (argc
, argv
)
145 alternate_editor
= getenv ("ALTERNATE_EDITOR");
146 server_file
= getenv ("EMACS_SERVER_FILE");
150 int opt
= getopt_long (argc
, argv
,
151 "VHnea:s:f:d:", longopts
, 0);
159 /* If getopt returns 0, then it has already processed a
160 long-named option. We should do nothing. */
164 alternate_editor
= optarg
;
168 socket_name
= optarg
;
172 server_file
= optarg
;
188 printf ("emacsclient %s\n", VERSION
);
193 print_help_and_exit ();
197 fprintf (stderr
, "Try `%s --help' for more information\n", progname
);
205 print_help_and_exit ()
208 "Usage: %s [OPTIONS] FILE...\n\
209 Tell the Emacs server to visit the specified files.\n\
210 Every FILE can be either just a FILENAME or [+LINE[:COLUMN]] FILENAME.\n\
212 The following OPTIONS are accepted:\n\
213 -V, --version Just print a version info and return\n\
214 -H, --help Print this usage information message\n\
215 -n, --no-wait Don't wait for the server to return\n\
216 -e, --eval Evaluate the FILE arguments as ELisp expressions\n\
217 -d, --display=DISPLAY Visit the file in the given display\n"
218 #ifndef NO_SOCKETS_IN_FILE_SYSTEM
219 "-s, --socket-name=FILENAME\n\
220 Set the filename of the UNIX socket for communication\n"
222 "-f, --server-file=FILENAME\n\
223 Set the filename of the TCP configuration file\n\
224 -a, --alternate-editor=EDITOR\n\
225 Editor to fallback to if the server is not running\n\
227 Report bugs to bug-gnu-emacs@gnu.org.\n", progname
);
233 Try to run a different command, or --if no alternate editor is
234 defined-- exit with an errorcode.
241 if (alternate_editor
)
244 execvp (alternate_editor
, argv
+ i
);
245 fprintf (stderr
, "%s: error executing alternate editor \"%s\"\n",
246 progname
, alternate_editor
);
250 fprintf (stderr
, "%s: No socket or alternate editor. Please use:\n\n"
251 #if !defined (NO_SOCKETS_IN_FILE_SYSTEM)
254 "\t--server-file (or environment variable EMACS_SERVER_FILE)\n\
255 \t--alternate-editor (or environment variable ALTERNATE_EDITOR)\n",
262 #if !defined (HAVE_SOCKETS)
269 fprintf (stderr
, "%s: Sorry, the Emacs server is supported only\n",
271 fprintf (stderr
, "on systems with Berkeley sockets.\n");
276 #else /* HAVE_SOCKETS */
279 # include <winsock2.h>
281 # include <sys/types.h>
282 # include <sys/socket.h>
284 # include <sys/stat.h>
288 #define AUTH_KEY_LENGTH 64
289 #define SEND_BUFFER_SIZE 4096
291 extern char *strerror ();
294 /* Buffer to accumulate data to send in TCP connections. */
295 char send_buffer
[SEND_BUFFER_SIZE
+ 1];
296 int sblen
= 0; /* Fill pointer for the send buffer. */
298 /* Let's send the data to Emacs when either
299 - the data ends in "\n", or
300 - the buffer is full (but this shouldn't happen)
301 Otherwise, we just accumulate it. */
302 void send_to_emacs (s
, data
)
308 int dlen
= strlen (data
);
309 if (dlen
+ sblen
>= SEND_BUFFER_SIZE
)
311 int part
= SEND_BUFFER_SIZE
- sblen
;
312 strncpy (&send_buffer
[sblen
], data
, part
);
314 sblen
= SEND_BUFFER_SIZE
;
318 strcpy (&send_buffer
[sblen
], data
);
325 if (sblen
== SEND_BUFFER_SIZE
326 || (sblen
> 0 && send_buffer
[sblen
-1] == '\n'))
328 int sent
= send (s
, send_buffer
, sblen
, 0);
330 strcpy (send_buffer
, &send_buffer
[sent
]);
336 /* In NAME, insert a & before each &, each space, each newline, and
337 any initial -. Change spaces to underscores, too, so that the
338 return value never contains a space. */
340 quote_file_name (s
, name
)
344 char *copy
= (char *) malloc (strlen (name
) * 2 + 1);
365 if (*p
== '&' || (*p
== '-' && p
== name
))
378 /* Wrapper to make WSACleanup a cdecl, as required by atexit(). */
379 void close_winsock ()
384 void initialize_sockets ()
388 /* Initialize the WinSock2 library. */
389 if (WSAStartup (MAKEWORD (2, 0), &wsaData
))
391 fprintf (stderr
, "%s: error initializing WinSock2", progname
);
395 atexit (close_winsock
);
397 #endif /* WINDOWSNT */
400 * Read the information needed to set up a TCP comm channel with
401 * the Emacs server: host, port and authentication string.
403 int get_server_config (server
, authentication
)
404 struct sockaddr_in
*server
;
405 char *authentication
;
411 if (! (config
= fopen (server_file
, "rb")))
413 char *home
= getenv ("HOME");
416 home
= getenv ("APPDATA");
420 char *path
= alloca (32 + strlen (home
) + strlen (server_file
));
421 sprintf (path
, "%s/.emacs.d/server/%s", home
, server_file
);
422 config
= fopen (path
, "rb");
429 if (fgets (dotted
, sizeof dotted
, config
)
430 && (port
= strchr (dotted
, ':')))
436 fprintf (stderr
, "%s: invalid configuration info", progname
);
440 server
->sin_family
= AF_INET
;
441 server
->sin_addr
.s_addr
= inet_addr (dotted
);
442 server
->sin_port
= htons (atoi (port
));
444 if (! fread (authentication
, AUTH_KEY_LENGTH
, 1, config
))
446 fprintf (stderr
, "%s: cannot read authentication info", progname
);
459 struct sockaddr_in server
;
460 IOCTL_BOOL_ARG c_arg
= 0;
461 struct linger l_arg
= {1, 1};
462 char auth_string
[AUTH_KEY_LENGTH
+ 1];
466 if (! get_server_config (&server
, auth_string
))
467 return INVALID_SOCKET
;
470 * Open up an AF_INET socket
472 if ((s
= socket (AF_INET
, SOCK_STREAM
, IPPROTO_TCP
)) < 0)
474 fprintf (stderr
, "%s: ", progname
);
476 return INVALID_SOCKET
;
482 if (connect (s
, (struct sockaddr
*) &server
, sizeof server
) < 0)
484 fprintf (stderr
, "%s: ", progname
);
486 return INVALID_SOCKET
;
489 IOCTL (s
, FIONBIO
, &c_arg
);
490 setsockopt (s
, SOL_SOCKET
, SO_LINGER
, (char *) &l_arg
, sizeof l_arg
);
493 * Send the authentication
495 auth_string
[AUTH_KEY_LENGTH
] = '\0';
497 SEND_STRING ("-auth ");
498 SEND_STRING (auth_string
);
504 #if !defined (NO_SOCKETS_IN_FILE_SYSTEM)
506 /* Three possibilities:
507 2 - can't be `stat'ed (sets errno)
508 1 - isn't owned by us
509 0 - success: none of the above */
512 socket_status (socket_name
)
517 if (stat (socket_name
, &statbfr
) == -1)
520 if (statbfr
.st_uid
!= geteuid ())
530 struct sockaddr_un server
;
533 * Open up an AF_UNIX socket in this person's home directory
536 if ((s
= socket (AF_UNIX
, SOCK_STREAM
, 0)) < 0)
538 fprintf (stderr
, "%s: ", progname
);
540 return INVALID_SOCKET
;
543 server
.sun_family
= AF_UNIX
;
547 int default_sock
= !socket_name
;
549 char *server_name
= "server";
551 if (socket_name
&& !index (socket_name
, '/') && !index (socket_name
, '\\'))
552 { /* socket_name is a file name component. */
553 server_name
= socket_name
;
555 default_sock
= 1; /* Try both UIDs. */
560 socket_name
= alloca (100 + strlen (server_name
));
561 sprintf (socket_name
, "/tmp/emacs%d/%s",
562 (int) geteuid (), server_name
);
565 if (strlen (socket_name
) < sizeof (server
.sun_path
))
566 strcpy (server
.sun_path
, socket_name
);
569 fprintf (stderr
, "%s: socket-name %s too long",
570 progname
, socket_name
);
574 /* See if the socket exists, and if it's owned by us. */
575 sock_status
= socket_status (server
.sun_path
);
577 if (sock_status
&& default_sock
)
579 /* Failing that, see if LOGNAME or USER exist and differ from
580 our euid. If so, look for a socket based on the UID
581 associated with the name. This is reminiscent of the logic
582 that init_editfns uses to set the global Vuser_full_name. */
584 char *user_name
= (char *) getenv ("LOGNAME");
587 user_name
= (char *) getenv ("USER");
591 struct passwd
*pw
= getpwnam (user_name
);
593 if (pw
&& (pw
->pw_uid
!= geteuid ()))
595 /* We're running under su, apparently. */
596 socket_name
= alloca (100 + strlen (server_name
));
597 sprintf (socket_name
, "/tmp/emacs%d/%s",
598 (int) pw
->pw_uid
, server_name
);
600 if (strlen (socket_name
) < sizeof (server
.sun_path
))
601 strcpy (server
.sun_path
, socket_name
);
604 fprintf (stderr
, "%s: socket-name %s too long",
605 progname
, socket_name
);
609 sock_status
= socket_status (server
.sun_path
);
620 /* There's a socket, but it isn't owned by us. This is OK if
624 fprintf (stderr
, "%s: Invalid socket owner\n", progname
);
625 return INVALID_SOCKET
;
631 if (saved_errno
== ENOENT
)
633 "%s: can't find socket; have you started the server?\n\
634 To start the server in Emacs, type \"M-x server-start\".\n",
637 fprintf (stderr
, "%s: can't stat %s: %s\n",
638 progname
, server
.sun_path
, strerror (saved_errno
));
639 return INVALID_SOCKET
;
643 if (connect (s
, (struct sockaddr
*) &server
, strlen (server
.sun_path
) + 2)
646 fprintf (stderr
, "%s: ", progname
);
648 return INVALID_SOCKET
;
653 #endif /* ! NO_SOCKETS_IN_FILE_SYSTEM */
659 return set_tcp_socket ();
661 #ifndef NO_SOCKETS_IN_FILE_SYSTEM
662 return set_local_socket ();
665 server_file
= "server";
666 return set_tcp_socket ();
677 int i
, rl
, needlf
= 0;
679 char string
[BUFSIZ
+1];
683 /* Process options. */
684 decode_options (argc
, argv
);
686 if ((argc
- optind
< 1) && !eval
)
688 fprintf (stderr
, "%s: file name or argument required\n", progname
);
689 fprintf (stderr
, "Try `%s --help' for more information\n", progname
);
693 if ((s
= set_socket ()) == INVALID_SOCKET
)
697 cwd
= getcwd (string
, sizeof string
);
699 cwd
= getwd (string
);
703 /* getwd puts message in STRING if it fails. */
705 fprintf (stderr
, "%s: %s (%s)\n", progname
,
706 "Cannot get current working directory", strerror (errno
));
708 fprintf (stderr
, "%s: %s (%s)\n", progname
, string
, strerror (errno
));
714 SEND_STRING ("-nowait ");
717 SEND_STRING ("-eval ");
721 SEND_STRING ("-display ");
722 SEND_QUOTED (display
);
726 if ((argc
- optind
> 0))
728 for (i
= optind
; i
< argc
; i
++)
731 ; /* Don't prepend any cwd or anything like that. */
732 else if (*argv
[i
] == '+')
734 char *p
= argv
[i
] + 1;
735 while (isdigit ((unsigned char) *p
) || *p
== ':') p
++;
743 else if (*argv
[i
] != '/')
745 else if ((*argv
[i
] != '/')
746 /* Absolute paths can also start with backslash
748 && (*argv
[i
] != '\\')
749 && (!islower (tolower (*argv
[i
]))
750 || (argv
[i
][1] != ':')))
757 SEND_QUOTED (argv
[i
]);
763 while (fgets (string
, BUFSIZ
, stdin
))
765 SEND_QUOTED (string
);
772 /* Maybe wait for an answer. */
777 printf ("Waiting for Emacs...");
782 /* Now, wait for an answer and print any messages. */
783 while ((rl
= recv (s
, string
, BUFSIZ
, 0)) > 0)
788 printf ("%s", string
);
789 needlf
= string
[0] == '\0' ? needlf
: string
[strlen (string
) - 1] != '\n';
801 #endif /* HAVE_SOCKETS */
803 #ifndef HAVE_STRERROR
808 extern char *sys_errlist
[];
811 if (errnum
>= 0 && errnum
< sys_nerr
)
812 return sys_errlist
[errnum
];
813 return (char *) "Unknown error";
816 #endif /* ! HAVE_STRERROR */
818 /* arch-tag: f39bb9c4-73eb-477e-896d-50832e2ca9a7
819 (do not change this comment) */
821 /* emacsclient.c ends here */