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. --no-wait. */
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
, "Version %s\n", VERSION
);
92 print_help_and_exit ();
97 print_help_and_exit ()
100 "Usage: %s [-n] [--no-wait] [+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 space, and any initial -.
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
== '-' && p
== name
))
141 #if !defined (HAVE_SOCKETS) && !defined (HAVE_SYSVIPC)
147 fprintf (stderr
, "%s: Sorry, the Emacs server is supported only\n",
149 fprintf (stderr
, "on systems with Berkeley sockets or System V IPC.\n");
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>
161 #include <sys/stat.h>
164 extern char *strerror ();
172 char system_name
[32];
175 struct sockaddr_un server
;
176 char *homedir
, *cwd
, *str
;
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]);
197 server
.sun_family
= AF_UNIX
;
198 #ifndef SERVER_HOME_DIR
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)
209 "%s: can't find socket; have you started the server?\n",
212 fprintf (stderr
, "%s: can't stat %s: %s\n",
213 argv
[0], server
.sun_path
, strerror (errno
));
216 if (statbfr
.st_uid
!= geteuid ())
218 fprintf (stderr
, "%s: Invalid socket owner\n", argv
[0]);
223 if ((homedir
= getenv ("HOME")) == NULL
)
225 fprintf (stderr
, "%s: No home directory\n", argv
[0]);
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
);
234 if (connect (s
, (struct sockaddr
*) &server
, strlen (server
.sun_path
) + 2)
237 fprintf (stderr
, "%s: ", argv
[0]);
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]);
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]);
263 cwd
= getwd (string
);
265 cwd
= getcwd (string
, sizeof string
);
269 /* getwd puts message in STRING if it fails. */
270 fprintf (stderr
, "%s: %s (%s)\n", argv
[0], string
, strerror (errno
));
275 fprintf (out
, "-nowait ");
277 for (i
= optind
; i
< argc
; i
++)
281 char *p
= argv
[i
] + 1;
282 while (*p
>= '0' && *p
<= '9') p
++;
284 fprintf (out
, "%s/", cwd
);
286 else if (*argv
[i
] != '/')
287 fprintf (out
, "%s/", cwd
);
289 fprintf (out
, "%s ", quote_file_name (argv
[i
]));
294 /* Maybe wait for an answer. */
298 printf ("Waiting for Emacs...");
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
))
312 #else /* This is the SYSV IPC section */
314 #include <sys/types.h>
317 #include <sys/utsname.h>
320 char *getwd (), *getcwd (), *getenv ();
321 struct utsname system_name
;
329 /* Size of text allocated in MSGP. */
330 int size_allocated
= BUFSIZ
;
331 /* Amount of text used in MSGP. */
334 = (struct msgbuf
*) malloc (sizeof (struct msgbuf
) + size_allocated
);
335 struct msqid_ds
* msg_st
;
336 char *homedir
, buf
[BUFSIZ
];
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]);
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");
362 strcat (buf
, "/.emacs-server-");
363 uname (&system_name
);
364 strcat (buf
, system_name
.nodename
);
367 key
= ftok (buf
, 1); /* unlikely to be anyone else using it */
368 s
= msgget (key
, 0600 | IPC_CREAT
);
371 fprintf (stderr
, "%s: ", argv
[0]);
376 /* Determine working dir, so we can prefix it to all the arguments. */
378 temp
= getwd (gwdirb
);
380 temp
= getcwd (gwdirb
, sizeof gwdirb
);
386 /* On some systems, cwd can look like `@machine/...';
387 ignore everything before the first slash in such a case. */
388 while (*cwd
&& *cwd
!= '/')
394 fprintf (stderr
, "%s: %s\n", argv
[0], cwd
);
403 strcat (msgp
->mtext
, "-nowait ");
413 char *modified_arg
= argv
[0];
415 if (*modified_arg
== '+')
417 char *p
= modified_arg
+ 1;
418 while (*p
>= '0' && *p
<= '9') p
++;
422 else if (*modified_arg
!= '/')
425 modified_arg
= quote_file_name (modified_arg
);
428 used
+= strlen (cwd
);
429 used
+= strlen (modified_arg
) + 1;
430 while (used
+ 2 > size_allocated
)
433 msgp
= (struct msgbuf
*) realloc (msgp
,
434 (sizeof (struct msgbuf
)
439 strcat (msgp
->mtext
, cwd
);
441 strcat (msgp
->mtext
, modified_arg
);
442 strcat (msgp
->mtext
, " ");
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
);
454 if (msgsnd (s
, msgp
, strlen (msgp
->mtext
)+1, 0) < 0)
456 fprintf (stderr
, "%s: ", progname
);
461 /* Maybe wait for an answer. */
465 printf ("Waiting for Emacs...");
468 msgrcv (s
, msgp
, BUFSIZ
, getpid (), 0); /* wait for anything back */
469 strcpy (buf
, msgp
->mtext
);
473 printf ("%s\n", buf
);
477 #endif /* HAVE_SYSVIPC */
479 #endif /* HAVE_SOCKETS or HAVE_SYSVIPC */
481 #ifndef HAVE_STRERROR
486 extern char *sys_errlist
[];
489 if (errnum
>= 0 && errnum
< sys_nerr
)
490 return sys_errlist
[errnum
];
491 return (char *) "Unknown error";
494 #endif /* ! HAVE_STRERROR */