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>
33 char *getenv (), *getwd ();
37 /* This is defined with -D from the compilation command,
38 which extracts it from ../lisp/version.el. */
41 #define VERSION "unspecified"
44 /* Name used to invoke this program. */
47 /* Nonzero means don't wait for a response from Emacs. --nowait. */
50 struct option longopts
[] =
52 { "nowait", 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
, "Version %s\n", VERSION
);
92 print_help_and_exit ();
97 print_help_and_exit ()
100 "Usage: %s [-n] [--nowait] [+linenumber] filename\n",
103 "Report bugs to bug-gnu-emacs@prep.ai.mit.edu.\n");
107 /* Return a copy of NAME, inserting a \
108 before each \, each -, and each space.
109 Change spaces to underscores, too, so that the
110 return value never contains a space. */
113 quote_file_name (name
)
116 char *copy
= (char *) malloc (strlen (name
) * 2 + 1);
131 if (*p
== '\\' || *p
== '-')
140 #if !defined (HAVE_SOCKETS) && !defined (HAVE_SYSVIPC)
146 fprintf (stderr
, "%s: Sorry, the Emacs server is supported only\n",
148 fprintf (stderr
, "on systems with Berkeley sockets or System V IPC.\n");
152 #else /* HAVE_SOCKETS or HAVE_SYSVIPC */
154 #if defined (HAVE_SOCKETS) && ! defined (NO_SOCKETS_IN_FILE_SYSTEM)
155 /* BSD code is very different from SYSV IPC code */
157 #include <sys/types.h>
158 #include <sys/socket.h>
160 #include <sys/stat.h>
163 extern char *strerror ();
171 char system_name
[32];
174 struct sockaddr_un server
;
175 char *homedir
, *cwd
, *str
;
180 /* Process options. */
181 decode_options (argc
, argv
);
183 if (argc
- optind
< 1)
184 print_help_and_exit ();
187 * Open up an AF_UNIX socket in this person's home directory
190 if ((s
= socket (AF_UNIX
, SOCK_STREAM
, 0)) < 0)
192 fprintf (stderr
, "%s: ", argv
[0]);
196 server
.sun_family
= AF_UNIX
;
197 #ifndef SERVER_HOME_DIR
201 gethostname (system_name
, sizeof (system_name
));
202 sprintf (server
.sun_path
, "/tmp/esrv%d-%s", geteuid (), system_name
);
204 if (stat (server
.sun_path
, &statbfr
) == -1)
208 "%s: can't find socket; have you started the server?\n",
211 fprintf (stderr
, "%s: can't stat %s: %s\n",
212 argv
[0], server
.sun_path
, strerror (errno
));
215 if (statbfr
.st_uid
!= geteuid ())
217 fprintf (stderr
, "%s: Invalid socket owner\n", argv
[0]);
222 if ((homedir
= getenv ("HOME")) == NULL
)
224 fprintf (stderr
, "%s: No home directory\n", argv
[0]);
227 strcpy (server
.sun_path
, homedir
);
228 strcat (server
.sun_path
, "/.emacs-server-");
229 gethostname (system_name
, sizeof (system_name
));
230 strcat (server
.sun_path
, system_name
);
233 if (connect (s
, (struct sockaddr
*) &server
, strlen (server
.sun_path
) + 2)
236 fprintf (stderr
, "%s: ", argv
[0]);
241 /* We use the stream OUT to send our command to the server. */
242 if ((out
= fdopen (s
, "r+")) == NULL
)
244 fprintf (stderr
, "%s: ", argv
[0]);
249 /* We use the stream IN to read the response.
250 We used to use just one stream for both output and input
251 on the socket, but reversing direction works nonportably:
252 on some systems, the output appears as the first input;
253 on other systems it does not. */
254 if ((in
= fdopen (s
, "r+")) == NULL
)
256 fprintf (stderr
, "%s: ", argv
[0]);
262 cwd
= getwd (string
);
264 cwd
= getcwd (string
, sizeof string
);
268 /* getwd puts message in STRING if it fails. */
269 fprintf (stderr
, "%s: %s (%s)\n", argv
[0], string
, strerror (errno
));
274 fprintf (out
, "-nowait ");
276 for (i
= optind
; i
< argc
; i
++)
280 char *p
= argv
[i
] + 1;
281 while (*p
>= '0' && *p
<= '9') p
++;
283 fprintf (out
, "%s/", cwd
);
285 else if (*argv
[i
] != '/')
286 fprintf (out
, "%s/", cwd
);
288 fprintf (out
, "%s ", quote_file_name (argv
[i
]));
293 /* Maybe wait for an answer. */
297 printf ("Waiting for Emacs...");
300 /* Now, wait for an answer and print any messages. On some systems,
301 the first line we read will actually be the output we just sent.
302 We can't predict whether that will happen, so if it does, we
303 detect it by recognizing `Client: ' at the beginning. */
305 while (str
= fgets (string
, BUFSIZ
, in
))
311 #else /* This is the SYSV IPC section */
313 #include <sys/types.h>
316 #include <sys/utsname.h>
319 char *getwd (), *getcwd (), *getenv ();
320 struct utsname system_name
;
328 /* Size of text allocated in MSGP. */
329 int size_allocated
= BUFSIZ
;
330 /* Amount of text used in MSGP. */
333 = (struct msgbuf
*) malloc (sizeof (struct msgbuf
) + size_allocated
);
334 struct msqid_ds
* msg_st
;
335 char *homedir
, buf
[BUFSIZ
];
342 /* Process options. */
343 decode_options (argc
, argv
);
345 if (argc
- optind
< 1)
346 print_help_and_exit ();
349 * Create a message queue using ~/.emacs-server as the path for ftok
351 if ((homedir
= getenv ("HOME")) == NULL
)
353 fprintf (stderr
, "%s: No home directory\n", argv
[0]);
356 strcpy (buf
, homedir
);
357 #ifndef HAVE_LONG_FILE_NAMES
358 /* If file names are short, we can't fit the host name. */
359 strcat (buf
, "/.emacs-server");
361 strcat (buf
, "/.emacs-server-");
362 uname (&system_name
);
363 strcat (buf
, system_name
.nodename
);
366 key
= ftok (buf
, 1); /* unlikely to be anyone else using it */
367 s
= msgget (key
, 0600 | IPC_CREAT
);
370 fprintf (stderr
, "%s: ", argv
[0]);
375 /* Determine working dir, so we can prefix it to all the arguments. */
377 temp
= getwd (gwdirb
);
379 temp
= getcwd (gwdirb
, sizeof gwdirb
);
385 /* On some systems, cwd can look like `@machine/...';
386 ignore everything before the first slash in such a case. */
387 while (*cwd
&& *cwd
!= '/')
393 fprintf (stderr
, "%s: %s\n", argv
[0], cwd
);
402 strcat (msgp
->mtext
, "-nowait ");
412 char *modified_arg
= argv
[0];
414 if (*modified_arg
== '+')
416 char *p
= modified_arg
+ 1;
417 while (*p
>= '0' && *p
<= '9') p
++;
421 else if (*modified_arg
!= '/')
424 modified_arg
= quote_file_name (modified_arg
);
427 used
+= strlen (cwd
);
428 used
+= strlen (modified_arg
) + 1;
429 while (used
+ 2 > size_allocated
)
432 msgp
= (struct msgbuf
*) realloc (msgp
,
433 (sizeof (struct msgbuf
)
438 strcat (msgp
->mtext
, cwd
);
440 strcat (msgp
->mtext
, modified_arg
);
441 strcat (msgp
->mtext
, " ");
444 strcat (msgp
->mtext
, "\n");
445 #ifdef HPUX /* HPUX has a bug. */
446 if (strlen (msgp
->mtext
) >= 512)
448 fprintf (stderr
, "%s: args too long for msgsnd\n", progname
);
453 if (msgsnd (s
, msgp
, strlen (msgp
->mtext
)+1, 0) < 0)
455 fprintf (stderr
, "%s: ", progname
);
460 /* Maybe wait for an answer. */
464 printf ("Waiting for Emacs...");
467 msgrcv (s
, msgp
, BUFSIZ
, getpid (), 0); /* wait for anything back */
468 strcpy (buf
, msgp
->mtext
);
472 printf ("%s\n", buf
);
476 #endif /* HAVE_SYSVIPC */
478 #endif /* HAVE_SOCKETS or HAVE_SYSVIPC */
480 #ifndef HAVE_STRERROR
485 extern char *sys_errlist
[];
488 if (errnum
>= 0 && errnum
< sys_nerr
)
489 return sys_errlist
[errnum
];
490 return (char *) "Unknown error";
493 #endif /* ! HAVE_STRERROR */