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)
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. */
23 #include <../src/config.h>
39 char *getenv (), *getwd ();
42 /* This is defined with -D from the compilation command,
43 which extracts it from ../lisp/version.el. */
46 #define VERSION "unspecified"
49 /* Name used to invoke this program. */
52 /* Nonzero means don't wait for a response from Emacs. --no-wait. */
55 void print_help_and_exit ();
57 struct option longopts
[] =
59 { "no-wait", no_argument
, NULL
, 'n' },
60 { "help", no_argument
, NULL
, 'H' },
61 { "version", no_argument
, NULL
, 'V' },
65 /* Decode the options from argv and argc.
66 The global variable `optind' will say how many arguments we used up. */
69 decode_options (argc
, argv
)
75 int opt
= getopt_long (argc
, argv
,
84 /* If getopt returns 0, then it has already processed a
85 long-named option. We should do nothing. */
93 fprintf (stderr
, "emacsclient %s\n", VERSION
);
99 print_help_and_exit ();
105 print_help_and_exit ()
108 "Usage: %s [-n] [--no-wait] [+LINENUMBER] FILENAME\n",
114 "Report bugs to bug-gnu-emacs@gnu.org.\n");
118 /* Return a copy of NAME, inserting a &
119 before each &, each space, and any initial -.
120 Change spaces to underscores, too, so that the
121 return value never contains a space. */
124 quote_file_name (name
)
127 char *copy
= (char *) malloc (strlen (name
) * 2 + 1);
142 if (*p
== '&' || (*p
== '-' && p
== name
))
152 /* Like malloc but get fatal error if memory is exhausted. */
158 long *result
= (long *) malloc (size
);
167 #if !defined (HAVE_SOCKETS) && !defined (HAVE_SYSVIPC)
173 fprintf (stderr
, "%s: Sorry, the Emacs server is supported only\n",
175 fprintf (stderr
, "on systems with Berkeley sockets or System V IPC.\n");
179 #else /* HAVE_SOCKETS or HAVE_SYSVIPC */
181 #if defined (HAVE_SOCKETS) && ! defined (NO_SOCKETS_IN_FILE_SYSTEM)
182 /* BSD code is very different from SYSV IPC code */
184 #include <sys/types.h>
185 #include <sys/socket.h>
187 #include <sys/stat.h>
190 extern char *strerror ();
199 int system_name_length
;
202 struct sockaddr_un server
;
203 char *homedir
, *cwd
, *str
;
208 /* Process options. */
209 decode_options (argc
, argv
);
211 if (argc
- optind
< 1)
212 print_help_and_exit ();
215 * Open up an AF_UNIX socket in this person's home directory
218 if ((s
= socket (AF_UNIX
, SOCK_STREAM
, 0)) < 0)
220 fprintf (stderr
, "%s: ", argv
[0]);
224 server
.sun_family
= AF_UNIX
;
227 system_name_length
= 32;
231 system_name
= (char *) xmalloc (system_name_length
+ 1);
233 /* system_name must be null-terminated string. */
234 system_name
[system_name_length
] = '\0';
236 if (gethostname (system_name
, system_name_length
) == 0)
240 system_name_length
*= 2;
244 #ifndef SERVER_HOME_DIR
248 sprintf (server
.sun_path
, "/tmp/esrv%d-%s", geteuid (), system_name
);
250 if (stat (server
.sun_path
, &statbfr
) == -1)
254 "%s: can't find socket; have you started the server?\n",
257 fprintf (stderr
, "%s: can't stat %s: %s\n",
258 argv
[0], server
.sun_path
, strerror (errno
));
261 if (statbfr
.st_uid
!= geteuid ())
263 fprintf (stderr
, "%s: Invalid socket owner\n", argv
[0]);
268 if ((homedir
= getenv ("HOME")) == NULL
)
270 fprintf (stderr
, "%s: No home directory\n", argv
[0]);
273 strcpy (server
.sun_path
, homedir
);
274 strcat (server
.sun_path
, "/.emacs-server-");
275 strcat (server
.sun_path
, system_name
);
278 if (connect (s
, (struct sockaddr
*) &server
, strlen (server
.sun_path
) + 2)
281 fprintf (stderr
, "%s: ", argv
[0]);
286 /* We use the stream OUT to send our command to the server. */
287 if ((out
= fdopen (s
, "r+")) == NULL
)
289 fprintf (stderr
, "%s: ", argv
[0]);
294 /* We use the stream IN to read the response.
295 We used to use just one stream for both output and input
296 on the socket, but reversing direction works nonportably:
297 on some systems, the output appears as the first input;
298 on other systems it does not. */
299 if ((in
= fdopen (s
, "r+")) == NULL
)
301 fprintf (stderr
, "%s: ", argv
[0]);
307 cwd
= getwd (string
);
309 cwd
= getcwd (string
, sizeof string
);
313 /* getwd puts message in STRING if it fails. */
314 fprintf (stderr
, "%s: %s (%s)\n", argv
[0],
318 "Cannot get current working directory",
325 fprintf (out
, "-nowait ");
327 for (i
= optind
; i
< argc
; i
++)
331 char *p
= argv
[i
] + 1;
332 while (*p
>= '0' && *p
<= '9') p
++;
334 fprintf (out
, "%s/", quote_file_name (cwd
));
336 else if (*argv
[i
] != '/')
337 fprintf (out
, "%s/", quote_file_name (cwd
));
339 fprintf (out
, "%s ", quote_file_name (argv
[i
]));
344 /* Maybe wait for an answer. */
348 printf ("Waiting for Emacs...");
351 /* Now, wait for an answer and print any messages. On some systems,
352 the first line we read will actually be the output we just sent.
353 We can't predict whether that will happen, so if it does, we
354 detect it by recognizing `Client: ' at the beginning. */
356 while (str
= fgets (string
, BUFSIZ
, in
))
362 #else /* This is the SYSV IPC section */
364 #include <sys/types.h>
367 #include <sys/utsname.h>
372 char *getwd (), *getcwd (), *getenv ();
373 struct utsname system_name
;
381 /* Size of text allocated in MSGP. */
382 int size_allocated
= BUFSIZ
;
383 /* Amount of text used in MSGP. */
386 = (struct msgbuf
*) malloc (sizeof (struct msgbuf
) + size_allocated
);
387 struct msqid_ds
* msg_st
;
388 char *homedir
, buf
[BUFSIZ
];
395 /* Process options. */
396 decode_options (argc
, argv
);
398 if (argc
- optind
< 1)
399 print_help_and_exit ();
402 * Create a message queue using ~/.emacs-server as the path for ftok
404 if ((homedir
= getenv ("HOME")) == NULL
)
406 fprintf (stderr
, "%s: No home directory\n", argv
[0]);
409 strcpy (buf
, homedir
);
410 #ifndef HAVE_LONG_FILE_NAMES
411 /* If file names are short, we can't fit the host name. */
412 strcat (buf
, "/.emacs-server");
414 strcat (buf
, "/.emacs-server-");
415 uname (&system_name
);
416 strcat (buf
, system_name
.nodename
);
419 key
= ftok (buf
, 1); /* unlikely to be anyone else using it */
420 s
= msgget (key
, 0600 | IPC_CREAT
);
423 fprintf (stderr
, "%s: ", argv
[0]);
428 /* Determine working dir, so we can prefix it to all the arguments. */
430 temp
= getwd (gwdirb
);
432 temp
= getcwd (gwdirb
, sizeof gwdirb
);
438 /* On some systems, cwd can look like `@machine/...';
439 ignore everything before the first slash in such a case. */
440 while (*cwd
&& *cwd
!= '/')
447 fprintf (stderr
, "%s: %s\n", argv
[0], cwd
);
449 fprintf (stderr
, "%s: Cannot get current working directory: %s\n",
450 argv
[0], strerror (errno
));
460 strcat (msgp
->mtext
, "-nowait ");
470 char *modified_arg
= argv
[0];
472 if (*modified_arg
== '+')
474 char *p
= modified_arg
+ 1;
475 while (*p
>= '0' && *p
<= '9') p
++;
479 else if (*modified_arg
!= '/')
482 modified_arg
= quote_file_name (modified_arg
);
485 /* Overestimate in case we have to quote something in CWD. */
486 used
+= 2 * strlen (cwd
);
487 used
+= strlen (modified_arg
) + 1;
488 while (used
+ 2 > size_allocated
)
491 msgp
= (struct msgbuf
*) realloc (msgp
,
492 (sizeof (struct msgbuf
)
497 strcat (msgp
->mtext
, quote_file_name (cwd
));
499 strcat (msgp
->mtext
, modified_arg
);
500 strcat (msgp
->mtext
, " ");
503 strcat (msgp
->mtext
, "\n");
504 #ifdef HPUX /* HPUX has a bug. */
505 if (strlen (msgp
->mtext
) >= 512)
507 fprintf (stderr
, "%s: args too long for msgsnd\n", progname
);
512 if (msgsnd (s
, msgp
, strlen (msgp
->mtext
)+1, 0) < 0)
514 fprintf (stderr
, "%s: ", progname
);
519 /* Maybe wait for an answer. */
523 printf ("Waiting for Emacs...");
526 msgrcv (s
, msgp
, BUFSIZ
, getpid (), 0); /* wait for anything back */
527 strcpy (buf
, msgp
->mtext
);
531 printf ("%s\n", buf
);
535 #endif /* HAVE_SYSVIPC */
537 #endif /* HAVE_SOCKETS or HAVE_SYSVIPC */
539 #ifndef HAVE_STRERROR
544 extern char *sys_errlist
[];
547 if (errnum
>= 0 && errnum
< sys_nerr
)
548 return sys_errlist
[errnum
];
549 return (char *) "Unknown error";
552 #endif /* ! HAVE_STRERROR */