(filesets-conditional-sort): Use copy-sequence, not copy-list.
[emacs.git] / lib-src / emacsclient.c
blob27bce2d0b1dabb1e5c288634e99f7d7fe7e25edc
1 /* Client process that communicates with GNU Emacs acting as server.
2 Copyright (C) 1986, 1987, 1994, 1999, 2000, 2001
3 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)
10 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; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
23 #define NO_SHORTNAMES
25 #ifdef HAVE_CONFIG_H
26 #include <config.h>
27 #endif
29 #undef signal
31 #include <ctype.h>
32 #include <stdio.h>
33 #include <getopt.h>
34 #ifdef HAVE_UNISTD_H
35 #include <unistd.h>
36 #endif
38 #ifdef VMS
39 # include "vms-pwd.h"
40 #else
41 # include <pwd.h>
42 #endif /* not VMS */
44 char *getenv (), *getwd ();
45 char *getcwd ();
47 /* This is defined with -D from the compilation command,
48 which extracts it from ../lisp/version.el. */
50 #ifndef VERSION
51 #define VERSION "unspecified"
52 #endif
54 /* Name used to invoke this program. */
55 char *progname;
57 /* Nonzero means don't wait for a response from Emacs. --no-wait. */
58 int nowait = 0;
60 void print_help_and_exit ();
62 struct option longopts[] =
64 { "no-wait", no_argument, NULL, 'n' },
65 { "help", no_argument, NULL, 'H' },
66 { "version", no_argument, NULL, 'V' },
67 { "alternate-editor",required_argument, NULL, 'a' },
68 { 0 }
72 const char * alternate_editor = NULL;
74 /* Decode the options from argv and argc.
75 The global variable `optind' will say how many arguments we used up. */
77 void
78 decode_options (argc, argv)
79 int argc;
80 char **argv;
82 while (1)
84 int opt = getopt_long (argc, argv,
85 "VHna:", longopts, 0);
87 if (opt == EOF)
88 break;
90 alternate_editor = getenv ("ALTERNATE_EDITOR");
92 switch (opt)
94 case 0:
95 /* If getopt returns 0, then it has already processed a
96 long-named option. We should do nothing. */
97 break;
99 case 'a':
100 alternate_editor = optarg;
101 break;
103 case 'n':
104 nowait = 1;
105 break;
107 case 'V':
108 fprintf (stderr, "emacsclient %s\n", VERSION);
109 exit (1);
110 break;
112 case 'H':
113 default:
114 print_help_and_exit ();
119 void
120 print_help_and_exit ()
122 fprintf (stderr,
123 "Usage: %s [-a ALTERNATE-EDITOR] [-n] [--no-wait] [+LINE[:COLUMN]] FILENAME\n",
124 progname);
125 fprintf (stderr,
126 "Or %s --version\n",
127 progname);
128 fprintf (stderr,
129 "Report bugs to bug-gnu-emacs@gnu.org.\n");
130 exit (1);
133 /* Return a copy of NAME, inserting a &
134 before each &, each space, and any initial -.
135 Change spaces to underscores, too, so that the
136 return value never contains a space. */
138 char *
139 quote_file_name (name)
140 char *name;
142 char *copy = (char *) malloc (strlen (name) * 2 + 1);
143 char *p, *q;
145 p = name;
146 q = copy;
147 while (*p)
149 if (*p == ' ')
151 *q++ = '&';
152 *q++ = '_';
153 p++;
155 else
157 if (*p == '&' || (*p == '-' && p == name))
158 *q++ = '&';
159 *q++ = *p++;
162 *q++ = 0;
164 return copy;
167 /* Like malloc but get fatal error if memory is exhausted. */
169 long *
170 xmalloc (size)
171 unsigned int size;
173 long *result = (long *) malloc (size);
174 if (result == NULL)
176 perror ("malloc");
177 exit (1);
179 return result;
183 Try to run a different command, or --if no alternate editor is
184 defined-- exit with an errorcode.
186 void
187 fail (argc, argv)
188 int argc;
189 char **argv;
191 if (alternate_editor)
193 int i = optind -1 ;
194 execvp (alternate_editor, argv + i);
195 return;
197 else
199 exit (1);
205 #if !defined (HAVE_SOCKETS) && !defined (HAVE_SYSVIPC)
208 main (argc, argv)
209 int argc;
210 char **argv;
212 fprintf (stderr, "%s: Sorry, the Emacs server is supported only\n",
213 argv[0]);
214 fprintf (stderr, "on systems with Berkeley sockets or System V IPC.\n");
216 fail (argc, argv);
219 #else /* HAVE_SOCKETS or HAVE_SYSVIPC */
221 #if defined (HAVE_SOCKETS) && ! defined (NO_SOCKETS_IN_FILE_SYSTEM)
222 /* BSD code is very different from SYSV IPC code */
224 #include <sys/types.h>
225 #include <sys/socket.h>
226 #include <sys/un.h>
227 #include <sys/stat.h>
228 #include <errno.h>
230 extern char *strerror ();
231 extern int errno;
233 /* Three possibilities:
234 2 - can't be `stat'ed (sets errno)
235 1 - isn't owned by us
236 0 - success: none of the above */
238 static int
239 socket_status (socket_name)
240 char *socket_name;
242 struct stat statbfr;
244 if (stat (socket_name, &statbfr) == -1)
245 return 2;
247 if (statbfr.st_uid != geteuid ())
248 return 1;
250 return 0;
254 main (argc, argv)
255 int argc;
256 char **argv;
258 char *system_name;
259 int system_name_length;
260 int s, i;
261 FILE *out, *in;
262 struct sockaddr_un server;
263 #ifdef SERVER_HOME_DIR
264 char *homedir;
265 #endif
266 char *cwd, *str;
267 char string[BUFSIZ];
269 progname = argv[0];
271 /* Process options. */
272 decode_options (argc, argv);
274 if (argc - optind < 1)
275 print_help_and_exit ();
278 * Open up an AF_UNIX socket in this person's home directory
281 if ((s = socket (AF_UNIX, SOCK_STREAM, 0)) < 0)
283 fprintf (stderr, "%s: ", argv[0]);
284 perror ("socket");
285 fail (argc, argv);
288 server.sun_family = AF_UNIX;
291 system_name_length = 32;
293 while (1)
295 system_name = (char *) xmalloc (system_name_length + 1);
297 /* system_name must be null-terminated string. */
298 system_name[system_name_length] = '\0';
300 if (gethostname (system_name, system_name_length) == 0)
301 break;
303 free (system_name);
304 system_name_length *= 2;
308 #ifndef SERVER_HOME_DIR
310 int sock_status = 0;
312 sprintf (server.sun_path, "/tmp/esrv%d-%s", (int) geteuid (), system_name);
314 /* See if the socket exists, and if it's owned by us. */
315 sock_status = socket_status (server.sun_path);
316 if (sock_status)
318 /* Failing that, see if LOGNAME or USER exist and differ from
319 our euid. If so, look for a socket based on the UID
320 associated with the name. This is reminiscent of the logic
321 that init_editfns uses to set the global Vuser_full_name. */
323 char *user_name = (char *) getenv ("LOGNAME");
324 if (!user_name)
325 user_name = (char *) getenv ("USER");
327 if (user_name)
329 struct passwd *pw = getpwnam (user_name);
330 if (pw && (pw->pw_uid != geteuid ()))
332 /* We're running under su, apparently. */
333 sprintf (server.sun_path, "/tmp/esrv%d-%s",
334 (int) pw->pw_uid, system_name);
335 sock_status = socket_status (server.sun_path);
340 switch (sock_status)
342 case 1:
343 /* There's a socket, but it isn't owned by us. This is OK if
344 we are root. */
345 if (0 != geteuid ())
347 fprintf (stderr, "%s: Invalid socket owner\n", argv[0]);
348 fail (argc, argv);
350 break;
352 case 2:
353 /* `stat' failed */
354 if (errno == ENOENT)
355 fprintf (stderr,
356 "%s: can't find socket; have you started the server?\n",
357 argv[0]);
358 else
359 fprintf (stderr, "%s: can't stat %s: %s\n",
360 argv[0], server.sun_path, strerror (errno));
361 fail (argc, argv);
362 break;
365 #else
366 if ((homedir = getenv ("HOME")) == NULL)
368 fprintf (stderr, "%s: No home directory\n", argv[0]);
369 fail (argc, argv);
371 strcpy (server.sun_path, homedir);
372 strcat (server.sun_path, "/.emacs-server-");
373 strcat (server.sun_path, system_name);
374 #endif
376 if (connect (s, (struct sockaddr *) &server, strlen (server.sun_path) + 2)
377 < 0)
379 fprintf (stderr, "%s: ", argv[0]);
380 perror ("connect");
381 fail (argc, argv);
384 /* We use the stream OUT to send our command to the server. */
385 if ((out = fdopen (s, "r+")) == NULL)
387 fprintf (stderr, "%s: ", argv[0]);
388 perror ("fdopen");
389 fail (argc, argv);
392 /* We use the stream IN to read the response.
393 We used to use just one stream for both output and input
394 on the socket, but reversing direction works nonportably:
395 on some systems, the output appears as the first input;
396 on other systems it does not. */
397 if ((in = fdopen (s, "r+")) == NULL)
399 fprintf (stderr, "%s: ", argv[0]);
400 perror ("fdopen");
401 fail (argc, argv);
404 #ifdef BSD_SYSTEM
405 cwd = getwd (string);
406 #else
407 cwd = getcwd (string, sizeof string);
408 #endif
409 if (cwd == 0)
411 /* getwd puts message in STRING if it fails. */
412 fprintf (stderr, "%s: %s (%s)\n", argv[0],
413 #ifdef BSD_SYSTEM
414 string,
415 #else
416 "Cannot get current working directory",
417 #endif
418 strerror (errno));
419 fail (argc, argv);
422 if (nowait)
423 fprintf (out, "-nowait ");
425 for (i = optind; i < argc; i++)
427 if (*argv[i] == '+')
429 char *p = argv[i] + 1;
430 while (isdigit ((unsigned char) *p) || *p == ':') p++;
431 if (*p != 0)
432 fprintf (out, "%s/", quote_file_name (cwd));
434 else if (*argv[i] != '/')
435 fprintf (out, "%s/", quote_file_name (cwd));
437 fprintf (out, "%s ", quote_file_name (argv[i]));
439 fprintf (out, "\n");
440 fflush (out);
442 /* Maybe wait for an answer. */
443 if (nowait)
444 return 0;
446 printf ("Waiting for Emacs...");
447 fflush (stdout);
449 /* Now, wait for an answer and print any messages. On some systems,
450 the first line we read will actually be the output we just sent.
451 We can't predict whether that will happen, so if it does, we
452 detect it by recognizing `Client: ' at the beginning. */
454 while ((str = fgets (string, BUFSIZ, in)))
455 printf ("%s", str);
457 return 0;
460 #else /* This is the SYSV IPC section */
462 #include <sys/types.h>
463 #include <sys/ipc.h>
464 #include <sys/msg.h>
465 #include <sys/utsname.h>
466 #include <stdio.h>
467 #include <errno.h>
468 extern int errno;
470 char *getwd (), *getcwd (), *getenv ();
471 struct utsname system_name;
473 main (argc, argv)
474 int argc;
475 char **argv;
477 int s;
478 key_t key;
479 /* Size of text allocated in MSGP. */
480 int size_allocated = BUFSIZ;
481 /* Amount of text used in MSGP. */
482 int used;
483 struct msgbuf *msgp
484 = (struct msgbuf *) malloc (sizeof (struct msgbuf) + size_allocated);
485 struct msqid_ds * msg_st;
486 char *homedir, buf[BUFSIZ];
487 char gwdirb[BUFSIZ];
488 char *cwd;
489 char *temp;
491 progname = argv[0];
493 /* Process options. */
494 decode_options (argc, argv);
496 if (argc - optind < 1)
497 print_help_and_exit ();
500 * Create a message queue using ~/.emacs-server as the path for ftok
502 if ((homedir = getenv ("HOME")) == NULL)
504 fprintf (stderr, "%s: No home directory\n", argv[0]);
505 exit (1);
507 strcpy (buf, homedir);
508 #ifndef HAVE_LONG_FILE_NAMES
509 /* If file names are short, we can't fit the host name. */
510 strcat (buf, "/.emacs-server");
511 #else
512 strcat (buf, "/.emacs-server-");
513 uname (&system_name);
514 strcat (buf, system_name.nodename);
515 #endif
516 creat (buf, 0600);
517 key = ftok (buf, 1); /* unlikely to be anyone else using it */
518 s = msgget (key, 0600 | IPC_CREAT);
519 if (s == -1)
521 fprintf (stderr, "%s: ", argv[0]);
522 perror ("msgget");
523 exit (1);
526 /* Determine working dir, so we can prefix it to all the arguments. */
527 #ifdef BSD_SYSTEM
528 temp = getwd (gwdirb);
529 #else
530 temp = getcwd (gwdirb, sizeof gwdirb);
531 #endif
533 cwd = gwdirb;
534 if (temp != 0)
536 /* On some systems, cwd can look like `@machine/...';
537 ignore everything before the first slash in such a case. */
538 while (*cwd && *cwd != '/')
539 cwd++;
540 strcat (cwd, "/");
542 else
544 #ifdef BSD_SYSTEM
545 fprintf (stderr, "%s: %s\n", argv[0], cwd);
546 #else
547 fprintf (stderr, "%s: Cannot get current working directory: %s\n",
548 argv[0], strerror (errno));
549 #endif
550 fail (argc, argv);
553 msgp->mtext[0] = 0;
554 used = 0;
556 if (nowait)
558 strcat (msgp->mtext, "-nowait ");
559 used += 8;
562 argc -= optind;
563 argv += optind;
565 while (argc)
567 int need_cwd = 0;
568 char *modified_arg = argv[0];
570 if (*modified_arg == '+')
572 char *p = modified_arg + 1;
573 while (isdigit (*p) || *p == ':')
574 p++;
575 if (*p != 0)
576 need_cwd = 1;
578 else if (*modified_arg != '/')
579 need_cwd = 1;
581 modified_arg = quote_file_name (modified_arg);
583 if (need_cwd)
584 /* Overestimate in case we have to quote something in CWD. */
585 used += 2 * strlen (cwd);
586 used += strlen (modified_arg) + 1;
587 while (used + 2 > size_allocated)
589 size_allocated *= 2;
590 msgp = (struct msgbuf *) realloc (msgp,
591 (sizeof (struct msgbuf)
592 + size_allocated));
595 if (need_cwd)
596 strcat (msgp->mtext, quote_file_name (cwd));
598 strcat (msgp->mtext, modified_arg);
599 strcat (msgp->mtext, " ");
600 argv++; argc--;
602 strcat (msgp->mtext, "\n");
603 #ifdef HPUX /* HPUX has a bug. */
604 if (strlen (msgp->mtext) >= 512)
606 fprintf (stderr, "%s: args too long for msgsnd\n", progname);
607 fail (argc, argv);
609 #endif
610 msgp->mtype = 1;
611 if (msgsnd (s, msgp, strlen (msgp->mtext)+1, 0) < 0)
613 fprintf (stderr, "%s: ", progname);
614 perror ("msgsnd");
615 fail (argc, argv);
618 /* Maybe wait for an answer. */
619 if (nowait)
620 return 0;
622 printf ("Waiting for Emacs...");
623 fflush (stdout);
625 msgrcv (s, msgp, BUFSIZ, getpid (), 0); /* wait for anything back */
626 strcpy (buf, msgp->mtext);
628 printf ("\n");
629 if (*buf)
630 printf ("%s\n", buf);
631 exit (0);
634 #endif /* HAVE_SYSVIPC */
636 #endif /* HAVE_SOCKETS or HAVE_SYSVIPC */
638 #ifndef HAVE_STRERROR
639 char *
640 strerror (errnum)
641 int errnum;
643 extern char *sys_errlist[];
644 extern int sys_nerr;
646 if (errnum >= 0 && errnum < sys_nerr)
647 return sys_errlist[errnum];
648 return (char *) "Unknown error";
651 #endif /* ! HAVE_STRERROR */