1 /* Client process that communicates with GNU Emacs acting as server.
2 Copyright (C) 1986, 1987, 1994, 1999, 2000 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>
38 char *getenv (), *getwd ();
41 /* This is defined with -D from the compilation command,
42 which extracts it from ../lisp/version.el. */
45 #define VERSION "unspecified"
48 /* Name used to invoke this program. */
51 /* Nonzero means don't wait for a response from Emacs. --no-wait. */
54 void print_help_and_exit ();
56 struct option longopts
[] =
58 { "no-wait", no_argument
, NULL
, 'n' },
59 { "help", no_argument
, NULL
, 'H' },
60 { "version", no_argument
, NULL
, 'V' },
61 { "alternate-editor",required_argument
, NULL
, 'a' },
66 const char * alternate_editor
= NULL
;
68 /* Decode the options from argv and argc.
69 The global variable `optind' will say how many arguments we used up. */
72 decode_options (argc
, argv
)
78 int opt
= getopt_long (argc
, argv
,
79 "VHna:", longopts
, 0);
84 alternate_editor
= getenv ("ALTERNATE_EDITOR");
89 /* If getopt returns 0, then it has already processed a
90 long-named option. We should do nothing. */
94 alternate_editor
= optarg
;
102 fprintf (stderr
, "emacsclient %s\n", VERSION
);
108 print_help_and_exit ();
114 print_help_and_exit ()
117 "Usage: %s [-a ALTERNATE-EDITOR] [-n] [--no-wait] [+LINENUMBER] FILENAME\n",
123 "Report bugs to bug-gnu-emacs@gnu.org.\n");
127 /* Return a copy of NAME, inserting a &
128 before each &, each space, and any initial -.
129 Change spaces to underscores, too, so that the
130 return value never contains a space. */
133 quote_file_name (name
)
136 char *copy
= (char *) malloc (strlen (name
) * 2 + 1);
151 if (*p
== '&' || (*p
== '-' && p
== name
))
162 /* Like malloc but get fatal error if memory is exhausted. */
168 long *result
= (long *) malloc (size
);
178 Try to run a different command, or --if no alternate editor is
179 defined-- exit with an errorcode.
185 if (alternate_editor
)
188 execvp (alternate_editor
, argv
+ i
);
199 #if !defined (HAVE_SOCKETS) && !defined (HAVE_SYSVIPC)
205 fprintf (stderr
, "%s: Sorry, the Emacs server is supported only\n",
207 fprintf (stderr
, "on systems with Berkeley sockets or System V IPC.\n");
212 #else /* HAVE_SOCKETS or HAVE_SYSVIPC */
214 #if defined (HAVE_SOCKETS) && ! defined (NO_SOCKETS_IN_FILE_SYSTEM)
215 /* BSD code is very different from SYSV IPC code */
217 #include <sys/types.h>
218 #include <sys/socket.h>
220 #include <sys/stat.h>
223 extern char *strerror ();
226 /* Three possibilities:
227 2 - can't be `stat'ed (sets errno)
228 1 - isn't owned by us
229 0 - success: none of the above */
232 socket_status (socket_name
)
237 if (stat (socket_name
, &statbfr
) == -1)
240 if (statbfr
.st_uid
!= geteuid ())
252 int system_name_length
;
255 struct sockaddr_un server
;
256 #ifdef SERVER_HOME_DIR
264 /* Process options. */
265 decode_options (argc
, argv
);
267 if (argc
- optind
< 1)
268 print_help_and_exit ();
271 * Open up an AF_UNIX socket in this person's home directory
274 if ((s
= socket (AF_UNIX
, SOCK_STREAM
, 0)) < 0)
276 fprintf (stderr
, "%s: ", argv
[0]);
281 server
.sun_family
= AF_UNIX
;
284 system_name_length
= 32;
288 system_name
= (char *) xmalloc (system_name_length
+ 1);
290 /* system_name must be null-terminated string. */
291 system_name
[system_name_length
] = '\0';
293 if (gethostname (system_name
, system_name_length
) == 0)
297 system_name_length
*= 2;
301 #ifndef SERVER_HOME_DIR
305 sprintf (server
.sun_path
, "/tmp/esrv%d-%s", geteuid (), system_name
);
307 /* See if the socket exists, and if it's owned by us. */
308 sock_status
= socket_status (server
.sun_path
);
311 /* Failing that, see if LOGNAME or USER exist and differ from
312 our euid. If so, look for a socket based on the UID
313 associated with the name. This is reminiscent of the logic
314 that init_editfns uses to set the global Vuser_full_name. */
316 char *user_name
= (char *) getenv ("LOGNAME");
318 user_name
= (char *) getenv ("USER");
322 struct passwd
*pw
= getpwnam (user_name
);
323 if (pw
&& (pw
->pw_uid
!= geteuid ()))
325 /* We're running under su, apparently. */
326 sprintf (server
.sun_path
, "/tmp/esrv%d-%s",
327 pw
->pw_uid
, system_name
);
328 sock_status
= socket_status (server
.sun_path
);
336 /* There's a socket, but it isn't owned by us. This is OK if
340 fprintf (stderr
, "%s: Invalid socket owner\n", argv
[0]);
349 "%s: can't find socket; have you started the server?\n",
352 fprintf (stderr
, "%s: can't stat %s: %s\n",
353 argv
[0], server
.sun_path
, strerror (errno
));
359 if ((homedir
= getenv ("HOME")) == NULL
)
361 fprintf (stderr
, "%s: No home directory\n", argv
[0]);
364 strcpy (server
.sun_path
, homedir
);
365 strcat (server
.sun_path
, "/.emacs-server-");
366 strcat (server
.sun_path
, system_name
);
369 if (connect (s
, (struct sockaddr
*) &server
, strlen (server
.sun_path
) + 2)
372 fprintf (stderr
, "%s: ", argv
[0]);
377 /* We use the stream OUT to send our command to the server. */
378 if ((out
= fdopen (s
, "r+")) == NULL
)
380 fprintf (stderr
, "%s: ", argv
[0]);
385 /* We use the stream IN to read the response.
386 We used to use just one stream for both output and input
387 on the socket, but reversing direction works nonportably:
388 on some systems, the output appears as the first input;
389 on other systems it does not. */
390 if ((in
= fdopen (s
, "r+")) == NULL
)
392 fprintf (stderr
, "%s: ", argv
[0]);
398 cwd
= getwd (string
);
400 cwd
= getcwd (string
, sizeof string
);
404 /* getwd puts message in STRING if it fails. */
405 fprintf (stderr
, "%s: %s (%s)\n", argv
[0],
409 "Cannot get current working directory",
416 fprintf (out
, "-nowait ");
418 for (i
= optind
; i
< argc
; i
++)
422 char *p
= argv
[i
] + 1;
423 while (*p
>= '0' && *p
<= '9') p
++;
425 fprintf (out
, "%s/", quote_file_name (cwd
));
427 else if (*argv
[i
] != '/')
428 fprintf (out
, "%s/", quote_file_name (cwd
));
430 fprintf (out
, "%s ", quote_file_name (argv
[i
]));
435 /* Maybe wait for an answer. */
439 printf ("Waiting for Emacs...");
442 /* Now, wait for an answer and print any messages. On some systems,
443 the first line we read will actually be the output we just sent.
444 We can't predict whether that will happen, so if it does, we
445 detect it by recognizing `Client: ' at the beginning. */
447 while (str
= fgets (string
, BUFSIZ
, in
))
453 #else /* This is the SYSV IPC section */
455 #include <sys/types.h>
458 #include <sys/utsname.h>
463 char *getwd (), *getcwd (), *getenv ();
464 struct utsname system_name
;
472 /* Size of text allocated in MSGP. */
473 int size_allocated
= BUFSIZ
;
474 /* Amount of text used in MSGP. */
477 = (struct msgbuf
*) malloc (sizeof (struct msgbuf
) + size_allocated
);
478 struct msqid_ds
* msg_st
;
479 char *homedir
, buf
[BUFSIZ
];
486 /* Process options. */
487 decode_options (argc
, argv
);
489 if (argc
- optind
< 1)
490 print_help_and_exit ();
493 * Create a message queue using ~/.emacs-server as the path for ftok
495 if ((homedir
= getenv ("HOME")) == NULL
)
497 fprintf (stderr
, "%s: No home directory\n", argv
[0]);
500 strcpy (buf
, homedir
);
501 #ifndef HAVE_LONG_FILE_NAMES
502 /* If file names are short, we can't fit the host name. */
503 strcat (buf
, "/.emacs-server");
505 strcat (buf
, "/.emacs-server-");
506 uname (&system_name
);
507 strcat (buf
, system_name
.nodename
);
510 key
= ftok (buf
, 1); /* unlikely to be anyone else using it */
511 s
= msgget (key
, 0600 | IPC_CREAT
);
514 fprintf (stderr
, "%s: ", argv
[0]);
519 /* Determine working dir, so we can prefix it to all the arguments. */
521 temp
= getwd (gwdirb
);
523 temp
= getcwd (gwdirb
, sizeof gwdirb
);
529 /* On some systems, cwd can look like `@machine/...';
530 ignore everything before the first slash in such a case. */
531 while (*cwd
&& *cwd
!= '/')
538 fprintf (stderr
, "%s: %s\n", argv
[0], cwd
);
540 fprintf (stderr
, "%s: Cannot get current working directory: %s\n",
541 argv
[0], strerror (errno
));
551 strcat (msgp
->mtext
, "-nowait ");
561 char *modified_arg
= argv
[0];
563 if (*modified_arg
== '+')
565 char *p
= modified_arg
+ 1;
566 while (*p
>= '0' && *p
<= '9') p
++;
570 else if (*modified_arg
!= '/')
573 modified_arg
= quote_file_name (modified_arg
);
576 /* Overestimate in case we have to quote something in CWD. */
577 used
+= 2 * strlen (cwd
);
578 used
+= strlen (modified_arg
) + 1;
579 while (used
+ 2 > size_allocated
)
582 msgp
= (struct msgbuf
*) realloc (msgp
,
583 (sizeof (struct msgbuf
)
588 strcat (msgp
->mtext
, quote_file_name (cwd
));
590 strcat (msgp
->mtext
, modified_arg
);
591 strcat (msgp
->mtext
, " ");
594 strcat (msgp
->mtext
, "\n");
595 #ifdef HPUX /* HPUX has a bug. */
596 if (strlen (msgp
->mtext
) >= 512)
598 fprintf (stderr
, "%s: args too long for msgsnd\n", progname
);
603 if (msgsnd (s
, msgp
, strlen (msgp
->mtext
)+1, 0) < 0)
605 fprintf (stderr
, "%s: ", progname
);
610 /* Maybe wait for an answer. */
614 printf ("Waiting for Emacs...");
617 msgrcv (s
, msgp
, BUFSIZ
, getpid (), 0); /* wait for anything back */
618 strcpy (buf
, msgp
->mtext
);
622 printf ("%s\n", buf
);
626 #endif /* HAVE_SYSVIPC */
628 #endif /* HAVE_SOCKETS or HAVE_SYSVIPC */
630 #ifndef HAVE_STRERROR
635 extern char *sys_errlist
[];
638 if (errnum
>= 0 && errnum
< sys_nerr
)
639 return sys_errlist
[errnum
];
640 return (char *) "Unknown error";
643 #endif /* ! HAVE_STRERROR */