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)
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>
32 char *getenv (), *getwd ();
35 /* This is defined with -D from the compilation command,
36 which extracts it from ../lisp/version.el. */
39 #define VERSION "unspecified"
42 /* Name used to invoke this program. */
45 /* Nonzero means don't wait for a response from Emacs. --no-wait. */
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' },
58 /* Decode the options from argv and argc.
59 The global variable `optind' will say how many arguments we used up. */
62 decode_options (argc
, argv
)
68 int opt
= getopt_long (argc
, argv
,
77 /* If getopt returns 0, then it has already processed a
78 long-named option. We should do nothing. */
86 fprintf (stderr
, "emacsclient %s\n", VERSION
);
92 print_help_and_exit ();
98 print_help_and_exit ()
101 "Usage: %s [-n] [--no-wait] [+LINENUMBER] FILENAME\n",
107 "Report bugs to bug-gnu-emacs@gnu.org.\n");
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. */
117 quote_file_name (name
)
120 char *copy
= (char *) malloc (strlen (name
) * 2 + 1);
135 if (*p
== '&' || (*p
== '-' && p
== name
))
145 /* Like malloc but get fatal error if memory is exhausted. */
151 long *result
= (long *) malloc (size
);
160 #if !defined (HAVE_SOCKETS) && !defined (HAVE_SYSVIPC)
166 fprintf (stderr
, "%s: Sorry, the Emacs server is supported only\n",
168 fprintf (stderr
, "on systems with Berkeley sockets or System V IPC.\n");
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>
180 #include <sys/stat.h>
183 extern char *strerror ();
192 int system_name_length
;
195 struct sockaddr_un server
;
196 char *homedir
, *cwd
, *str
;
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]);
217 server
.sun_family
= AF_UNIX
;
220 system_name_length
= 32;
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)
233 system_name_length
*= 2;
237 #ifndef SERVER_HOME_DIR
241 sprintf (server
.sun_path
, "/tmp/esrv%d-%s", geteuid (), system_name
);
243 if (stat (server
.sun_path
, &statbfr
) == -1)
247 "%s: can't find socket; have you started the server?\n",
250 fprintf (stderr
, "%s: can't stat %s: %s\n",
251 argv
[0], server
.sun_path
, strerror (errno
));
254 if (statbfr
.st_uid
!= geteuid ())
256 fprintf (stderr
, "%s: Invalid socket owner\n", argv
[0]);
261 if ((homedir
= getenv ("HOME")) == NULL
)
263 fprintf (stderr
, "%s: No home directory\n", argv
[0]);
266 strcpy (server
.sun_path
, homedir
);
267 strcat (server
.sun_path
, "/.emacs-server-");
268 strcat (server
.sun_path
, system_name
);
271 if (connect (s
, (struct sockaddr
*) &server
, strlen (server
.sun_path
) + 2)
274 fprintf (stderr
, "%s: ", argv
[0]);
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]);
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]);
300 cwd
= getwd (string
);
302 cwd
= getcwd (string
, sizeof string
);
306 /* getwd puts message in STRING if it fails. */
307 fprintf (stderr
, "%s: %s (%s)\n", argv
[0],
311 "Cannot get current working directory",
318 fprintf (out
, "-nowait ");
320 for (i
= optind
; i
< argc
; i
++)
324 char *p
= argv
[i
] + 1;
325 while (*p
>= '0' && *p
<= '9') p
++;
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
]));
337 /* Maybe wait for an answer. */
341 printf ("Waiting for Emacs...");
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
))
355 #else /* This is the SYSV IPC section */
357 #include <sys/types.h>
360 #include <sys/utsname.h>
365 char *getwd (), *getcwd (), *getenv ();
366 struct utsname system_name
;
374 /* Size of text allocated in MSGP. */
375 int size_allocated
= BUFSIZ
;
376 /* Amount of text used in MSGP. */
379 = (struct msgbuf
*) malloc (sizeof (struct msgbuf
) + size_allocated
);
380 struct msqid_ds
* msg_st
;
381 char *homedir
, buf
[BUFSIZ
];
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]);
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");
407 strcat (buf
, "/.emacs-server-");
408 uname (&system_name
);
409 strcat (buf
, system_name
.nodename
);
412 key
= ftok (buf
, 1); /* unlikely to be anyone else using it */
413 s
= msgget (key
, 0600 | IPC_CREAT
);
416 fprintf (stderr
, "%s: ", argv
[0]);
421 /* Determine working dir, so we can prefix it to all the arguments. */
423 temp
= getwd (gwdirb
);
425 temp
= getcwd (gwdirb
, sizeof gwdirb
);
431 /* On some systems, cwd can look like `@machine/...';
432 ignore everything before the first slash in such a case. */
433 while (*cwd
&& *cwd
!= '/')
440 fprintf (stderr
, "%s: %s\n", argv
[0], cwd
);
442 fprintf (stderr
, "%s: Cannot get current working directory: %s\n",
443 argv
[0], strerror (errno
));
453 strcat (msgp
->mtext
, "-nowait ");
463 char *modified_arg
= argv
[0];
465 if (*modified_arg
== '+')
467 char *p
= modified_arg
+ 1;
468 while (*p
>= '0' && *p
<= '9') p
++;
472 else if (*modified_arg
!= '/')
475 modified_arg
= quote_file_name (modified_arg
);
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
)
484 msgp
= (struct msgbuf
*) realloc (msgp
,
485 (sizeof (struct msgbuf
)
490 strcat (msgp
->mtext
, quote_file_name (cwd
));
492 strcat (msgp
->mtext
, modified_arg
);
493 strcat (msgp
->mtext
, " ");
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
);
505 if (msgsnd (s
, msgp
, strlen (msgp
->mtext
)+1, 0) < 0)
507 fprintf (stderr
, "%s: ", progname
);
512 /* Maybe wait for an answer. */
516 printf ("Waiting for Emacs...");
519 msgrcv (s
, msgp
, BUFSIZ
, getpid (), 0); /* wait for anything back */
520 strcpy (buf
, msgp
->mtext
);
524 printf ("%s\n", buf
);
528 #endif /* HAVE_SYSVIPC */
530 #endif /* HAVE_SOCKETS or HAVE_SYSVIPC */
532 #ifndef HAVE_STRERROR
537 extern char *sys_errlist
[];
540 if (errnum
>= 0 && errnum
< sys_nerr
)
541 return sys_errlist
[errnum
];
542 return (char *) "Unknown error";
545 #endif /* ! HAVE_STRERROR */