Fix bootstrapping problems.
[emacs.git] / lib-src / emacsclient.c
blob11946ff2ec0ac88b608ab7e7996236dcad56f042
1 /* Client process that communicates with GNU Emacs acting as server.
2 Copyright (C) 1986, 1987, 1994, 1999 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 signal
26 #include <stdio.h>
27 #include <getopt.h>
28 #ifdef HAVE_UNISTD_H
29 #include <unistd.h>
30 #endif
32 char *getenv (), *getwd ();
33 char *getcwd ();
35 /* This is defined with -D from the compilation command,
36 which extracts it from ../lisp/version.el. */
38 #ifndef VERSION
39 #define VERSION "unspecified"
40 #endif
42 /* Name used to invoke this program. */
43 char *progname;
45 /* Nonzero means don't wait for a response from Emacs. --no-wait. */
46 int nowait = 0;
48 void print_help_and_exit ();
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, "emacsclient %s\n", VERSION);
87 exit (1);
88 break;
90 case 'H':
91 default:
92 print_help_and_exit ();
97 void
98 print_help_and_exit ()
100 fprintf (stderr,
101 "Usage: %s [-n] [--no-wait] [+LINENUMBER] FILENAME\n",
102 progname);
103 fprintf (stderr,
104 "Or %s --version\n",
105 progname);
106 fprintf (stderr,
107 "Report bugs to bug-gnu-emacs@gnu.org.\n");
108 exit (1);
111 /* Return a copy of NAME, inserting a &
112 before each &, each space, and any initial -.
113 Change spaces to underscores, too, so that the
114 return value never contains a space. */
116 char *
117 quote_file_name (name)
118 char *name;
120 char *copy = (char *) malloc (strlen (name) * 2 + 1);
121 char *p, *q;
123 p = name;
124 q = copy;
125 while (*p)
127 if (*p == ' ')
129 *q++ = '&';
130 *q++ = '_';
131 p++;
133 else
135 if (*p == '&' || (*p == '-' && p == name))
136 *q++ = '&';
137 *q++ = *p++;
140 *q++ = 0;
142 return copy;
145 /* Like malloc but get fatal error if memory is exhausted. */
147 long *
148 xmalloc (size)
149 unsigned int size;
151 long *result = (long *) malloc (size);
152 if (result == NULL)
154 perror ("malloc");
155 exit (1);
157 return result;
160 #if !defined (HAVE_SOCKETS) && !defined (HAVE_SYSVIPC)
162 main (argc, argv)
163 int argc;
164 char **argv;
166 fprintf (stderr, "%s: Sorry, the Emacs server is supported only\n",
167 argv[0]);
168 fprintf (stderr, "on systems with Berkeley sockets or System V IPC.\n");
169 exit (1);
172 #else /* HAVE_SOCKETS or HAVE_SYSVIPC */
174 #if defined (HAVE_SOCKETS) && ! defined (NO_SOCKETS_IN_FILE_SYSTEM)
175 /* BSD code is very different from SYSV IPC code */
177 #include <sys/types.h>
178 #include <sys/socket.h>
179 #include <sys/un.h>
180 #include <sys/stat.h>
181 #include <errno.h>
183 extern char *strerror ();
184 extern int errno;
187 main (argc, argv)
188 int argc;
189 char **argv;
191 char *system_name;
192 int system_name_length;
193 int s, i;
194 FILE *out, *in;
195 struct sockaddr_un server;
196 char *homedir, *cwd, *str;
197 char string[BUFSIZ];
199 progname = argv[0];
201 /* Process options. */
202 decode_options (argc, argv);
204 if (argc - optind < 1)
205 print_help_and_exit ();
208 * Open up an AF_UNIX socket in this person's home directory
211 if ((s = socket (AF_UNIX, SOCK_STREAM, 0)) < 0)
213 fprintf (stderr, "%s: ", argv[0]);
214 perror ("socket");
215 exit (1);
217 server.sun_family = AF_UNIX;
220 system_name_length = 32;
222 while (1)
224 system_name = (char *) xmalloc (system_name_length + 1);
226 /* system_name must be null-terminated string. */
227 system_name[system_name_length] = '\0';
229 if (gethostname (system_name, system_name_length) == 0)
230 break;
232 free (system_name);
233 system_name_length *= 2;
237 #ifndef SERVER_HOME_DIR
239 struct stat statbfr;
241 sprintf (server.sun_path, "/tmp/esrv%d-%s", geteuid (), system_name);
243 if (stat (server.sun_path, &statbfr) == -1)
245 if (errno == ENOENT)
246 fprintf (stderr,
247 "%s: can't find socket; have you started the server?\n",
248 argv[0]);
249 else
250 fprintf (stderr, "%s: can't stat %s: %s\n",
251 argv[0], server.sun_path, strerror (errno));
252 exit (1);
254 if (statbfr.st_uid != geteuid ())
256 fprintf (stderr, "%s: Invalid socket owner\n", argv[0]);
257 exit (1);
260 #else
261 if ((homedir = getenv ("HOME")) == NULL)
263 fprintf (stderr, "%s: No home directory\n", argv[0]);
264 exit (1);
266 strcpy (server.sun_path, homedir);
267 strcat (server.sun_path, "/.emacs-server-");
268 strcat (server.sun_path, system_name);
269 #endif
271 if (connect (s, (struct sockaddr *) &server, strlen (server.sun_path) + 2)
272 < 0)
274 fprintf (stderr, "%s: ", argv[0]);
275 perror ("connect");
276 exit (1);
279 /* We use the stream OUT to send our command to the server. */
280 if ((out = fdopen (s, "r+")) == NULL)
282 fprintf (stderr, "%s: ", argv[0]);
283 perror ("fdopen");
284 exit (1);
287 /* We use the stream IN to read the response.
288 We used to use just one stream for both output and input
289 on the socket, but reversing direction works nonportably:
290 on some systems, the output appears as the first input;
291 on other systems it does not. */
292 if ((in = fdopen (s, "r+")) == NULL)
294 fprintf (stderr, "%s: ", argv[0]);
295 perror ("fdopen");
296 exit (1);
299 #ifdef BSD_SYSTEM
300 cwd = getwd (string);
301 #else
302 cwd = getcwd (string, sizeof string);
303 #endif
304 if (cwd == 0)
306 /* getwd puts message in STRING if it fails. */
307 fprintf (stderr, "%s: %s (%s)\n", argv[0],
308 #ifdef BSD_SYSTEM
309 string,
310 #else
311 "Cannot get current working directory",
312 #endif
313 strerror (errno));
314 exit (1);
317 if (nowait)
318 fprintf (out, "-nowait ");
320 for (i = optind; i < argc; i++)
322 if (*argv[i] == '+')
324 char *p = argv[i] + 1;
325 while (*p >= '0' && *p <= '9') p++;
326 if (*p != 0)
327 fprintf (out, "%s/", quote_file_name (cwd));
329 else if (*argv[i] != '/')
330 fprintf (out, "%s/", quote_file_name (cwd));
332 fprintf (out, "%s ", quote_file_name (argv[i]));
334 fprintf (out, "\n");
335 fflush (out);
337 /* Maybe wait for an answer. */
338 if (nowait)
339 return 0;
341 printf ("Waiting for Emacs...");
342 fflush (stdout);
344 /* Now, wait for an answer and print any messages. On some systems,
345 the first line we read will actually be the output we just sent.
346 We can't predict whether that will happen, so if it does, we
347 detect it by recognizing `Client: ' at the beginning. */
349 while (str = fgets (string, BUFSIZ, in))
350 printf ("%s", str);
352 return 0;
355 #else /* This is the SYSV IPC section */
357 #include <sys/types.h>
358 #include <sys/ipc.h>
359 #include <sys/msg.h>
360 #include <sys/utsname.h>
361 #include <stdio.h>
362 #include <errno.h>
363 extern int errno;
365 char *getwd (), *getcwd (), *getenv ();
366 struct utsname system_name;
368 main (argc, argv)
369 int argc;
370 char **argv;
372 int s;
373 key_t key;
374 /* Size of text allocated in MSGP. */
375 int size_allocated = BUFSIZ;
376 /* Amount of text used in MSGP. */
377 int used;
378 struct msgbuf *msgp
379 = (struct msgbuf *) malloc (sizeof (struct msgbuf) + size_allocated);
380 struct msqid_ds * msg_st;
381 char *homedir, buf[BUFSIZ];
382 char gwdirb[BUFSIZ];
383 char *cwd;
384 char *temp;
386 progname = argv[0];
388 /* Process options. */
389 decode_options (argc, argv);
391 if (argc - optind < 1)
392 print_help_and_exit ();
395 * Create a message queue using ~/.emacs-server as the path for ftok
397 if ((homedir = getenv ("HOME")) == NULL)
399 fprintf (stderr, "%s: No home directory\n", argv[0]);
400 exit (1);
402 strcpy (buf, homedir);
403 #ifndef HAVE_LONG_FILE_NAMES
404 /* If file names are short, we can't fit the host name. */
405 strcat (buf, "/.emacs-server");
406 #else
407 strcat (buf, "/.emacs-server-");
408 uname (&system_name);
409 strcat (buf, system_name.nodename);
410 #endif
411 creat (buf, 0600);
412 key = ftok (buf, 1); /* unlikely to be anyone else using it */
413 s = msgget (key, 0600 | IPC_CREAT);
414 if (s == -1)
416 fprintf (stderr, "%s: ", argv[0]);
417 perror ("msgget");
418 exit (1);
421 /* Determine working dir, so we can prefix it to all the arguments. */
422 #ifdef BSD_SYSTEM
423 temp = getwd (gwdirb);
424 #else
425 temp = getcwd (gwdirb, sizeof gwdirb);
426 #endif
428 cwd = gwdirb;
429 if (temp != 0)
431 /* On some systems, cwd can look like `@machine/...';
432 ignore everything before the first slash in such a case. */
433 while (*cwd && *cwd != '/')
434 cwd++;
435 strcat (cwd, "/");
437 else
439 #ifdef BSD_SYSTEM
440 fprintf (stderr, "%s: %s\n", argv[0], cwd);
441 #else
442 fprintf (stderr, "%s: Cannot get current working directory: %s\n",
443 argv[0], strerror (errno));
444 #endif
445 exit (1);
448 msgp->mtext[0] = 0;
449 used = 0;
451 if (nowait)
453 strcat (msgp->mtext, "-nowait ");
454 used += 8;
457 argc -= optind;
458 argv += optind;
460 while (argc)
462 int need_cwd = 0;
463 char *modified_arg = argv[0];
465 if (*modified_arg == '+')
467 char *p = modified_arg + 1;
468 while (*p >= '0' && *p <= '9') p++;
469 if (*p != 0)
470 need_cwd = 1;
472 else if (*modified_arg != '/')
473 need_cwd = 1;
475 modified_arg = quote_file_name (modified_arg);
477 if (need_cwd)
478 /* Overestimate in case we have to quote something in CWD. */
479 used += 2 * strlen (cwd);
480 used += strlen (modified_arg) + 1;
481 while (used + 2 > size_allocated)
483 size_allocated *= 2;
484 msgp = (struct msgbuf *) realloc (msgp,
485 (sizeof (struct msgbuf)
486 + size_allocated));
489 if (need_cwd)
490 strcat (msgp->mtext, quote_file_name (cwd));
492 strcat (msgp->mtext, modified_arg);
493 strcat (msgp->mtext, " ");
494 argv++; argc--;
496 strcat (msgp->mtext, "\n");
497 #ifdef HPUX /* HPUX has a bug. */
498 if (strlen (msgp->mtext) >= 512)
500 fprintf (stderr, "%s: args too long for msgsnd\n", progname);
501 exit (1);
503 #endif
504 msgp->mtype = 1;
505 if (msgsnd (s, msgp, strlen (msgp->mtext)+1, 0) < 0)
507 fprintf (stderr, "%s: ", progname);
508 perror ("msgsnd");
509 exit (1);
512 /* Maybe wait for an answer. */
513 if (nowait)
514 return 0;
516 printf ("Waiting for Emacs...");
517 fflush (stdout);
519 msgrcv (s, msgp, BUFSIZ, getpid (), 0); /* wait for anything back */
520 strcpy (buf, msgp->mtext);
522 printf ("\n");
523 if (*buf)
524 printf ("%s\n", buf);
525 exit (0);
528 #endif /* HAVE_SYSVIPC */
530 #endif /* HAVE_SOCKETS or HAVE_SYSVIPC */
532 #ifndef HAVE_STRERROR
533 char *
534 strerror (errnum)
535 int errnum;
537 extern char *sys_errlist[];
538 extern int sys_nerr;
540 if (errnum >= 0 && errnum < sys_nerr)
541 return sys_errlist[errnum];
542 return (char *) "Unknown error";
545 #endif /* ! HAVE_STRERROR */