1 /* Client process that communicates with GNU Emacs acting as server.
2 Copyright (C) 1986, 1987, 1994, 1999, 2000, 2001
3 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
24 #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' },
62 { "alternate-editor",required_argument
, NULL
, 'a' },
67 const char * alternate_editor
= NULL
;
69 /* Decode the options from argv and argc.
70 The global variable `optind' will say how many arguments we used up. */
73 decode_options (argc
, argv
)
79 int opt
= getopt_long (argc
, argv
,
80 "VHna:", longopts
, 0);
85 alternate_editor
= getenv ("ALTERNATE_EDITOR");
90 /* If getopt returns 0, then it has already processed a
91 long-named option. We should do nothing. */
95 alternate_editor
= optarg
;
103 fprintf (stderr
, "emacsclient %s\n", VERSION
);
109 print_help_and_exit ();
115 print_help_and_exit ()
118 "Usage: %s [-a ALTERNATE-EDITOR] [-n] [--no-wait] [+LINENUMBER] FILENAME\n",
124 "Report bugs to bug-gnu-emacs@gnu.org.\n");
128 /* Return a copy of NAME, inserting a &
129 before each &, each space, and any initial -.
130 Change spaces to underscores, too, so that the
131 return value never contains a space. */
134 quote_file_name (name
)
137 char *copy
= (char *) malloc (strlen (name
) * 2 + 1);
152 if (*p
== '&' || (*p
== '-' && p
== name
))
163 /* Like malloc but get fatal error if memory is exhausted. */
169 long *result
= (long *) malloc (size
);
179 Try to run a different command, or --if no alternate editor is
180 defined-- exit with an errorcode.
187 if (alternate_editor
)
190 execvp (alternate_editor
, argv
+ i
);
202 #if !defined (HAVE_SOCKETS) && !defined (HAVE_SYSVIPC)
209 fprintf (stderr
, "%s: Sorry, the Emacs server is supported only\n",
211 fprintf (stderr
, "on systems with Berkeley sockets or System V IPC.\n");
216 #else /* HAVE_SOCKETS or HAVE_SYSVIPC */
218 #if defined (HAVE_SOCKETS) && ! defined (NO_SOCKETS_IN_FILE_SYSTEM)
219 /* BSD code is very different from SYSV IPC code */
221 #include <sys/types.h>
222 #include <sys/socket.h>
224 #include <sys/stat.h>
227 extern char *strerror ();
230 /* Three possibilities:
231 2 - can't be `stat'ed (sets errno)
232 1 - isn't owned by us
233 0 - success: none of the above */
236 socket_status (socket_name
)
241 if (stat (socket_name
, &statbfr
) == -1)
244 if (statbfr
.st_uid
!= geteuid ())
256 int system_name_length
;
259 struct sockaddr_un server
;
260 #ifdef SERVER_HOME_DIR
268 /* Process options. */
269 decode_options (argc
, argv
);
271 if (argc
- optind
< 1)
272 print_help_and_exit ();
275 * Open up an AF_UNIX socket in this person's home directory
278 if ((s
= socket (AF_UNIX
, SOCK_STREAM
, 0)) < 0)
280 fprintf (stderr
, "%s: ", argv
[0]);
285 server
.sun_family
= AF_UNIX
;
288 system_name_length
= 32;
292 system_name
= (char *) xmalloc (system_name_length
+ 1);
294 /* system_name must be null-terminated string. */
295 system_name
[system_name_length
] = '\0';
297 if (gethostname (system_name
, system_name_length
) == 0)
301 system_name_length
*= 2;
305 #ifndef SERVER_HOME_DIR
309 sprintf (server
.sun_path
, "/tmp/esrv%d-%s", (int) geteuid (), system_name
);
311 /* See if the socket exists, and if it's owned by us. */
312 sock_status
= socket_status (server
.sun_path
);
315 /* Failing that, see if LOGNAME or USER exist and differ from
316 our euid. If so, look for a socket based on the UID
317 associated with the name. This is reminiscent of the logic
318 that init_editfns uses to set the global Vuser_full_name. */
320 char *user_name
= (char *) getenv ("LOGNAME");
322 user_name
= (char *) getenv ("USER");
326 struct passwd
*pw
= getpwnam (user_name
);
327 if (pw
&& (pw
->pw_uid
!= geteuid ()))
329 /* We're running under su, apparently. */
330 sprintf (server
.sun_path
, "/tmp/esrv%d-%s",
331 (int) pw
->pw_uid
, system_name
);
332 sock_status
= socket_status (server
.sun_path
);
340 /* There's a socket, but it isn't owned by us. This is OK if
344 fprintf (stderr
, "%s: Invalid socket owner\n", argv
[0]);
353 "%s: can't find socket; have you started the server?\n",
356 fprintf (stderr
, "%s: can't stat %s: %s\n",
357 argv
[0], server
.sun_path
, strerror (errno
));
363 if ((homedir
= getenv ("HOME")) == NULL
)
365 fprintf (stderr
, "%s: No home directory\n", argv
[0]);
368 strcpy (server
.sun_path
, homedir
);
369 strcat (server
.sun_path
, "/.emacs-server-");
370 strcat (server
.sun_path
, system_name
);
373 if (connect (s
, (struct sockaddr
*) &server
, strlen (server
.sun_path
) + 2)
376 fprintf (stderr
, "%s: ", argv
[0]);
381 /* We use the stream OUT to send our command to the server. */
382 if ((out
= fdopen (s
, "r+")) == NULL
)
384 fprintf (stderr
, "%s: ", argv
[0]);
389 /* We use the stream IN to read the response.
390 We used to use just one stream for both output and input
391 on the socket, but reversing direction works nonportably:
392 on some systems, the output appears as the first input;
393 on other systems it does not. */
394 if ((in
= fdopen (s
, "r+")) == NULL
)
396 fprintf (stderr
, "%s: ", argv
[0]);
402 cwd
= getwd (string
);
404 cwd
= getcwd (string
, sizeof string
);
408 /* getwd puts message in STRING if it fails. */
409 fprintf (stderr
, "%s: %s (%s)\n", argv
[0],
413 "Cannot get current working directory",
420 fprintf (out
, "-nowait ");
422 for (i
= optind
; i
< argc
; i
++)
426 char *p
= argv
[i
] + 1;
427 while (*p
>= '0' && *p
<= '9') p
++;
429 fprintf (out
, "%s/", quote_file_name (cwd
));
431 else if (*argv
[i
] != '/')
432 fprintf (out
, "%s/", quote_file_name (cwd
));
434 fprintf (out
, "%s ", quote_file_name (argv
[i
]));
439 /* Maybe wait for an answer. */
443 printf ("Waiting for Emacs...");
446 /* Now, wait for an answer and print any messages. On some systems,
447 the first line we read will actually be the output we just sent.
448 We can't predict whether that will happen, so if it does, we
449 detect it by recognizing `Client: ' at the beginning. */
451 while (str
= fgets (string
, BUFSIZ
, in
))
457 #else /* This is the SYSV IPC section */
459 #include <sys/types.h>
462 #include <sys/utsname.h>
467 char *getwd (), *getcwd (), *getenv ();
468 struct utsname system_name
;
476 /* Size of text allocated in MSGP. */
477 int size_allocated
= BUFSIZ
;
478 /* Amount of text used in MSGP. */
481 = (struct msgbuf
*) malloc (sizeof (struct msgbuf
) + size_allocated
);
482 struct msqid_ds
* msg_st
;
483 char *homedir
, buf
[BUFSIZ
];
490 /* Process options. */
491 decode_options (argc
, argv
);
493 if (argc
- optind
< 1)
494 print_help_and_exit ();
497 * Create a message queue using ~/.emacs-server as the path for ftok
499 if ((homedir
= getenv ("HOME")) == NULL
)
501 fprintf (stderr
, "%s: No home directory\n", argv
[0]);
504 strcpy (buf
, homedir
);
505 #ifndef HAVE_LONG_FILE_NAMES
506 /* If file names are short, we can't fit the host name. */
507 strcat (buf
, "/.emacs-server");
509 strcat (buf
, "/.emacs-server-");
510 uname (&system_name
);
511 strcat (buf
, system_name
.nodename
);
514 key
= ftok (buf
, 1); /* unlikely to be anyone else using it */
515 s
= msgget (key
, 0600 | IPC_CREAT
);
518 fprintf (stderr
, "%s: ", argv
[0]);
523 /* Determine working dir, so we can prefix it to all the arguments. */
525 temp
= getwd (gwdirb
);
527 temp
= getcwd (gwdirb
, sizeof gwdirb
);
533 /* On some systems, cwd can look like `@machine/...';
534 ignore everything before the first slash in such a case. */
535 while (*cwd
&& *cwd
!= '/')
542 fprintf (stderr
, "%s: %s\n", argv
[0], cwd
);
544 fprintf (stderr
, "%s: Cannot get current working directory: %s\n",
545 argv
[0], strerror (errno
));
555 strcat (msgp
->mtext
, "-nowait ");
565 char *modified_arg
= argv
[0];
567 if (*modified_arg
== '+')
569 char *p
= modified_arg
+ 1;
570 while (*p
>= '0' && *p
<= '9') p
++;
574 else if (*modified_arg
!= '/')
577 modified_arg
= quote_file_name (modified_arg
);
580 /* Overestimate in case we have to quote something in CWD. */
581 used
+= 2 * strlen (cwd
);
582 used
+= strlen (modified_arg
) + 1;
583 while (used
+ 2 > size_allocated
)
586 msgp
= (struct msgbuf
*) realloc (msgp
,
587 (sizeof (struct msgbuf
)
592 strcat (msgp
->mtext
, quote_file_name (cwd
));
594 strcat (msgp
->mtext
, modified_arg
);
595 strcat (msgp
->mtext
, " ");
598 strcat (msgp
->mtext
, "\n");
599 #ifdef HPUX /* HPUX has a bug. */
600 if (strlen (msgp
->mtext
) >= 512)
602 fprintf (stderr
, "%s: args too long for msgsnd\n", progname
);
607 if (msgsnd (s
, msgp
, strlen (msgp
->mtext
)+1, 0) < 0)
609 fprintf (stderr
, "%s: ", progname
);
614 /* Maybe wait for an answer. */
618 printf ("Waiting for Emacs...");
621 msgrcv (s
, msgp
, BUFSIZ
, getpid (), 0); /* wait for anything back */
622 strcpy (buf
, msgp
->mtext
);
626 printf ("%s\n", buf
);
630 #endif /* HAVE_SYSVIPC */
632 #endif /* HAVE_SOCKETS or HAVE_SYSVIPC */
634 #ifndef HAVE_STRERROR
639 extern char *sys_errlist
[];
642 if (errnum
>= 0 && errnum
< sys_nerr
)
643 return sys_errlist
[errnum
];
644 return (char *) "Unknown error";
647 #endif /* ! HAVE_STRERROR */