(PC-try-load-many-files): Set truename.
[emacs.git] / lib-src / emacsclient.c
blob2e99e9d34adc409ca34f599dd953521a4afa0fe3
1 /* Client process that communicates with GNU Emacs acting as server.
2 Copyright (C) 1986, 1987, 1994 Free Software Foundation, Inc.
4 This file is part of GNU Emacs.
6 GNU Emacs is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs; see the file COPYING. If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
22 #define NO_SHORTNAMES
23 #include <../src/config.h>
24 #undef read
25 #undef write
26 #undef open
27 #undef close
28 #undef signal
30 #include <stdio.h>
31 #include <getopt.h>
33 char *getenv (), *getwd ();
34 char *getcwd ();
35 int geteuid ();
37 /* This is defined with -D from the compilation command,
38 which extracts it from ../lisp/version.el. */
40 #ifndef VERSION
41 #define VERSION "unspecified"
42 #endif
44 /* Name used to invoke this program. */
45 char *progname;
47 /* Nonzero means don't wait for a response from Emacs. --no-wait. */
48 int nowait = 0;
50 struct option longopts[] =
52 { "no-wait", no_argument, NULL, 'n' },
53 { "help", no_argument, NULL, 'H' },
54 { "version", no_argument, NULL, 'V' },
55 { 0 }
58 /* Decode the options from argv and argc.
59 The global variable `optind' will say how many arguments we used up. */
61 void
62 decode_options (argc, argv)
63 int argc;
64 char **argv;
66 while (1)
68 int opt = getopt_long (argc, argv,
69 "VHn", longopts, 0);
71 if (opt == EOF)
72 break;
74 switch (opt)
76 case 0:
77 /* If getopt returns 0, then it has already processed a
78 long-named option. We should do nothing. */
79 break;
81 case 'n':
82 nowait = 1;
83 break;
85 case 'V':
86 fprintf (stderr, "Version %s\n", VERSION);
87 exit (1);
88 break;
90 case 'H':
91 default:
92 print_help_and_exit ();
97 print_help_and_exit ()
99 fprintf (stderr,
100 "Usage: %s [-n] [--no-wait] [+LINENUMBER] FILENAME\n",
101 progname);
102 fprintf (stderr,
103 "Report bugs to bug-gnu-emacs@prep.ai.mit.edu.\n");
104 exit (1);
107 /* Return a copy of NAME, inserting a &
108 before each &, each space, and any initial -.
109 Change spaces to underscores, too, so that the
110 return value never contains a space. */
112 char *
113 quote_file_name (name)
114 char *name;
116 char *copy = (char *) malloc (strlen (name) * 2 + 1);
117 char *p, *q;
119 p = name;
120 q = copy;
121 while (*p)
123 if (*p == ' ')
125 *q++ = '&';
126 *q++ = '_';
127 p++;
129 else
131 if (*p == '&' || (*p == '-' && p == name))
132 *q++ = '&';
133 *q++ = *p++;
136 *q++ = 0;
138 return copy;
141 #if !defined (HAVE_SOCKETS) && !defined (HAVE_SYSVIPC)
143 main (argc, argv)
144 int argc;
145 char **argv;
147 fprintf (stderr, "%s: Sorry, the Emacs server is supported only\n",
148 argv[0]);
149 fprintf (stderr, "on systems with Berkeley sockets or System V IPC.\n");
150 exit (1);
153 #else /* HAVE_SOCKETS or HAVE_SYSVIPC */
155 #if defined (HAVE_SOCKETS) && ! defined (NO_SOCKETS_IN_FILE_SYSTEM)
156 /* BSD code is very different from SYSV IPC code */
158 #include <sys/types.h>
159 #include <sys/socket.h>
160 #include <sys/un.h>
161 #include <sys/stat.h>
162 #include <errno.h>
164 extern char *strerror ();
165 extern int errno;
168 main (argc, argv)
169 int argc;
170 char **argv;
172 char system_name[32];
173 int s, i;
174 FILE *out, *in;
175 struct sockaddr_un server;
176 char *homedir, *cwd, *str;
177 char string[BUFSIZ];
179 progname = argv[0];
181 /* Process options. */
182 decode_options (argc, argv);
184 if (argc - optind < 1)
185 print_help_and_exit ();
188 * Open up an AF_UNIX socket in this person's home directory
191 if ((s = socket (AF_UNIX, SOCK_STREAM, 0)) < 0)
193 fprintf (stderr, "%s: ", argv[0]);
194 perror ("socket");
195 exit (1);
197 server.sun_family = AF_UNIX;
198 #ifndef SERVER_HOME_DIR
200 struct stat statbfr;
202 gethostname (system_name, sizeof (system_name));
203 sprintf (server.sun_path, "/tmp/esrv%d-%s", geteuid (), system_name);
205 if (stat (server.sun_path, &statbfr) == -1)
207 if (errno == ENOENT)
208 fprintf (stderr,
209 "%s: can't find socket; have you started the server?\n",
210 argv[0]);
211 else
212 fprintf (stderr, "%s: can't stat %s: %s\n",
213 argv[0], server.sun_path, strerror (errno));
214 exit (1);
216 if (statbfr.st_uid != geteuid ())
218 fprintf (stderr, "%s: Invalid socket owner\n", argv[0]);
219 exit (1);
222 #else
223 if ((homedir = getenv ("HOME")) == NULL)
225 fprintf (stderr, "%s: No home directory\n", argv[0]);
226 exit (1);
228 strcpy (server.sun_path, homedir);
229 strcat (server.sun_path, "/.emacs-server-");
230 gethostname (system_name, sizeof (system_name));
231 strcat (server.sun_path, system_name);
232 #endif
234 if (connect (s, (struct sockaddr *) &server, strlen (server.sun_path) + 2)
235 < 0)
237 fprintf (stderr, "%s: ", argv[0]);
238 perror ("connect");
239 exit (1);
242 /* We use the stream OUT to send our command to the server. */
243 if ((out = fdopen (s, "r+")) == NULL)
245 fprintf (stderr, "%s: ", argv[0]);
246 perror ("fdopen");
247 exit (1);
250 /* We use the stream IN to read the response.
251 We used to use just one stream for both output and input
252 on the socket, but reversing direction works nonportably:
253 on some systems, the output appears as the first input;
254 on other systems it does not. */
255 if ((in = fdopen (s, "r+")) == NULL)
257 fprintf (stderr, "%s: ", argv[0]);
258 perror ("fdopen");
259 exit (1);
262 #ifdef BSD_SYSTEM
263 cwd = getwd (string);
264 #else
265 cwd = getcwd (string, sizeof string);
266 #endif
267 if (cwd == 0)
269 /* getwd puts message in STRING if it fails. */
270 fprintf (stderr, "%s: %s (%s)\n", argv[0], string, strerror (errno));
271 exit (1);
274 if (nowait)
275 fprintf (out, "-nowait ");
277 for (i = optind; i < argc; i++)
279 if (*argv[i] == '+')
281 char *p = argv[i] + 1;
282 while (*p >= '0' && *p <= '9') p++;
283 if (*p != 0)
284 fprintf (out, "%s/", cwd);
286 else if (*argv[i] != '/')
287 fprintf (out, "%s/", cwd);
289 fprintf (out, "%s ", quote_file_name (argv[i]));
291 fprintf (out, "\n");
292 fflush (out);
294 /* Maybe wait for an answer. */
295 if (nowait)
296 return 0;
298 printf ("Waiting for Emacs...");
299 fflush (stdout);
301 /* Now, wait for an answer and print any messages. On some systems,
302 the first line we read will actually be the output we just sent.
303 We can't predict whether that will happen, so if it does, we
304 detect it by recognizing `Client: ' at the beginning. */
306 while (str = fgets (string, BUFSIZ, in))
307 printf ("%s", str);
309 return 0;
312 #else /* This is the SYSV IPC section */
314 #include <sys/types.h>
315 #include <sys/ipc.h>
316 #include <sys/msg.h>
317 #include <sys/utsname.h>
318 #include <stdio.h>
320 char *getwd (), *getcwd (), *getenv ();
321 struct utsname system_name;
323 main (argc, argv)
324 int argc;
325 char **argv;
327 int s;
328 key_t key;
329 /* Size of text allocated in MSGP. */
330 int size_allocated = BUFSIZ;
331 /* Amount of text used in MSGP. */
332 int used;
333 struct msgbuf *msgp
334 = (struct msgbuf *) malloc (sizeof (struct msgbuf) + size_allocated);
335 struct msqid_ds * msg_st;
336 char *homedir, buf[BUFSIZ];
337 char gwdirb[BUFSIZ];
338 char *cwd;
339 char *temp;
341 progname = argv[0];
343 /* Process options. */
344 decode_options (argc, argv);
346 if (argc - optind < 1)
347 print_help_and_exit ();
350 * Create a message queue using ~/.emacs-server as the path for ftok
352 if ((homedir = getenv ("HOME")) == NULL)
354 fprintf (stderr, "%s: No home directory\n", argv[0]);
355 exit (1);
357 strcpy (buf, homedir);
358 #ifndef HAVE_LONG_FILE_NAMES
359 /* If file names are short, we can't fit the host name. */
360 strcat (buf, "/.emacs-server");
361 #else
362 strcat (buf, "/.emacs-server-");
363 uname (&system_name);
364 strcat (buf, system_name.nodename);
365 #endif
366 creat (buf, 0600);
367 key = ftok (buf, 1); /* unlikely to be anyone else using it */
368 s = msgget (key, 0600 | IPC_CREAT);
369 if (s == -1)
371 fprintf (stderr, "%s: ", argv[0]);
372 perror ("msgget");
373 exit (1);
376 /* Determine working dir, so we can prefix it to all the arguments. */
377 #ifdef BSD_SYSTEM
378 temp = getwd (gwdirb);
379 #else
380 temp = getcwd (gwdirb, sizeof gwdirb);
381 #endif
383 cwd = gwdirb;
384 if (temp != 0)
386 /* On some systems, cwd can look like `@machine/...';
387 ignore everything before the first slash in such a case. */
388 while (*cwd && *cwd != '/')
389 cwd++;
390 strcat (cwd, "/");
392 else
394 fprintf (stderr, "%s: %s\n", argv[0], cwd);
395 exit (1);
398 msgp->mtext[0] = 0;
399 used = 0;
401 if (nowait)
403 strcat (msgp->mtext, "-nowait ");
404 used += 8;
407 argc -= optind;
408 argv += optind;
410 while (argc)
412 int need_cwd = 0;
413 char *modified_arg = argv[0];
415 if (*modified_arg == '+')
417 char *p = modified_arg + 1;
418 while (*p >= '0' && *p <= '9') p++;
419 if (*p != 0)
420 need_cwd = 1;
422 else if (*modified_arg != '/')
423 need_cwd = 1;
425 modified_arg = quote_file_name (modified_arg);
427 if (need_cwd)
428 used += strlen (cwd);
429 used += strlen (modified_arg) + 1;
430 while (used + 2 > size_allocated)
432 size_allocated *= 2;
433 msgp = (struct msgbuf *) realloc (msgp,
434 (sizeof (struct msgbuf)
435 + size_allocated));
438 if (need_cwd)
439 strcat (msgp->mtext, cwd);
441 strcat (msgp->mtext, modified_arg);
442 strcat (msgp->mtext, " ");
443 argv++; argc--;
445 strcat (msgp->mtext, "\n");
446 #ifdef HPUX /* HPUX has a bug. */
447 if (strlen (msgp->mtext) >= 512)
449 fprintf (stderr, "%s: args too long for msgsnd\n", progname);
450 exit (1);
452 #endif
453 msgp->mtype = 1;
454 if (msgsnd (s, msgp, strlen (msgp->mtext)+1, 0) < 0)
456 fprintf (stderr, "%s: ", progname);
457 perror ("msgsnd");
458 exit (1);
461 /* Maybe wait for an answer. */
462 if (nowait)
463 return 0;
465 printf ("Waiting for Emacs...");
466 fflush (stdout);
468 msgrcv (s, msgp, BUFSIZ, getpid (), 0); /* wait for anything back */
469 strcpy (buf, msgp->mtext);
471 printf ("\n");
472 if (*buf)
473 printf ("%s\n", buf);
474 exit (0);
477 #endif /* HAVE_SYSVIPC */
479 #endif /* HAVE_SOCKETS or HAVE_SYSVIPC */
481 #ifndef HAVE_STRERROR
482 char *
483 strerror (errnum)
484 int errnum;
486 extern char *sys_errlist[];
487 extern int sys_nerr;
489 if (errnum >= 0 && errnum < sys_nerr)
490 return sys_errlist[errnum];
491 return (char *) "Unknown error";
494 #endif /* ! HAVE_STRERROR */