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>
40 char *getenv (), *getwd ();
43 /* This is defined with -D from the compilation command,
44 which extracts it from ../lisp/version.el. */
47 #define VERSION "unspecified"
50 /* Name used to invoke this program. */
53 /* Nonzero means don't wait for a response from Emacs. --no-wait. */
56 void print_help_and_exit ();
58 struct option longopts
[] =
60 { "no-wait", no_argument
, NULL
, 'n' },
61 { "help", no_argument
, NULL
, 'H' },
62 { "version", no_argument
, NULL
, 'V' },
63 { "alternate-editor",required_argument
, NULL
, 'a' },
68 const char * alternate_editor
= NULL
;
70 /* Decode the options from argv and argc.
71 The global variable `optind' will say how many arguments we used up. */
74 decode_options (argc
, argv
)
80 int opt
= getopt_long (argc
, argv
,
81 "VHna:", longopts
, 0);
86 alternate_editor
= getenv ("ALTERNATE_EDITOR");
91 /* If getopt returns 0, then it has already processed a
92 long-named option. We should do nothing. */
96 alternate_editor
= optarg
;
104 fprintf (stderr
, "emacsclient %s\n", VERSION
);
110 print_help_and_exit ();
116 print_help_and_exit ()
119 "Usage: %s [-a ALTERNATE-EDITOR] [-n] [--no-wait] [+LINE[:COLUMN]] FILENAME\n",
125 "Report bugs to bug-gnu-emacs@gnu.org.\n");
129 /* Return a copy of NAME, inserting a &
130 before each &, each space, and any initial -.
131 Change spaces to underscores, too, so that the
132 return value never contains a space. */
135 quote_file_name (name
)
138 char *copy
= (char *) malloc (strlen (name
) * 2 + 1);
153 if (*p
== '&' || (*p
== '-' && p
== name
))
164 /* Like malloc but get fatal error if memory is exhausted. */
170 long *result
= (long *) malloc (size
);
180 Try to run a different command, or --if no alternate editor is
181 defined-- exit with an errorcode.
188 if (alternate_editor
)
191 execvp (alternate_editor
, argv
+ i
);
203 #if !defined (HAVE_SOCKETS) && !defined (HAVE_SYSVIPC)
210 fprintf (stderr
, "%s: Sorry, the Emacs server is supported only\n",
212 fprintf (stderr
, "on systems with Berkeley sockets or System V IPC.\n");
217 #else /* HAVE_SOCKETS or HAVE_SYSVIPC */
219 #if defined (HAVE_SOCKETS) && ! defined (NO_SOCKETS_IN_FILE_SYSTEM)
220 /* BSD code is very different from SYSV IPC code */
222 #include <sys/types.h>
223 #include <sys/socket.h>
225 #include <sys/stat.h>
228 extern char *strerror ();
231 /* Three possibilities:
232 2 - can't be `stat'ed (sets errno)
233 1 - isn't owned by us
234 0 - success: none of the above */
237 socket_status (socket_name
)
242 if (stat (socket_name
, &statbfr
) == -1)
245 if (statbfr
.st_uid
!= geteuid ())
257 int system_name_length
;
260 struct sockaddr_un server
;
261 #ifdef SERVER_HOME_DIR
269 /* Process options. */
270 decode_options (argc
, argv
);
272 if (argc
- optind
< 1)
273 print_help_and_exit ();
276 * Open up an AF_UNIX socket in this person's home directory
279 if ((s
= socket (AF_UNIX
, SOCK_STREAM
, 0)) < 0)
281 fprintf (stderr
, "%s: ", argv
[0]);
286 server
.sun_family
= AF_UNIX
;
289 system_name_length
= 32;
293 system_name
= (char *) xmalloc (system_name_length
+ 1);
295 /* system_name must be null-terminated string. */
296 system_name
[system_name_length
] = '\0';
298 if (gethostname (system_name
, system_name_length
) == 0)
302 system_name_length
*= 2;
306 #ifndef SERVER_HOME_DIR
310 sprintf (server
.sun_path
, "/tmp/esrv%d-%s", (int) geteuid (), system_name
);
312 /* See if the socket exists, and if it's owned by us. */
313 sock_status
= socket_status (server
.sun_path
);
316 /* Failing that, see if LOGNAME or USER exist and differ from
317 our euid. If so, look for a socket based on the UID
318 associated with the name. This is reminiscent of the logic
319 that init_editfns uses to set the global Vuser_full_name. */
321 char *user_name
= (char *) getenv ("LOGNAME");
323 user_name
= (char *) getenv ("USER");
327 struct passwd
*pw
= getpwnam (user_name
);
328 if (pw
&& (pw
->pw_uid
!= geteuid ()))
330 /* We're running under su, apparently. */
331 sprintf (server
.sun_path
, "/tmp/esrv%d-%s",
332 (int) pw
->pw_uid
, system_name
);
333 sock_status
= socket_status (server
.sun_path
);
341 /* There's a socket, but it isn't owned by us. This is OK if
345 fprintf (stderr
, "%s: Invalid socket owner\n", argv
[0]);
354 "%s: can't find socket; have you started the server?\n",
357 fprintf (stderr
, "%s: can't stat %s: %s\n",
358 argv
[0], server
.sun_path
, strerror (errno
));
364 if ((homedir
= getenv ("HOME")) == NULL
)
366 fprintf (stderr
, "%s: No home directory\n", argv
[0]);
369 strcpy (server
.sun_path
, homedir
);
370 strcat (server
.sun_path
, "/.emacs-server-");
371 strcat (server
.sun_path
, system_name
);
374 if (connect (s
, (struct sockaddr
*) &server
, strlen (server
.sun_path
) + 2)
377 fprintf (stderr
, "%s: ", argv
[0]);
382 /* We use the stream OUT to send our command to the server. */
383 if ((out
= fdopen (s
, "r+")) == NULL
)
385 fprintf (stderr
, "%s: ", argv
[0]);
390 /* We use the stream IN to read the response.
391 We used to use just one stream for both output and input
392 on the socket, but reversing direction works nonportably:
393 on some systems, the output appears as the first input;
394 on other systems it does not. */
395 if ((in
= fdopen (s
, "r+")) == NULL
)
397 fprintf (stderr
, "%s: ", argv
[0]);
403 cwd
= getwd (string
);
405 cwd
= getcwd (string
, sizeof string
);
409 /* getwd puts message in STRING if it fails. */
410 fprintf (stderr
, "%s: %s (%s)\n", argv
[0],
414 "Cannot get current working directory",
421 fprintf (out
, "-nowait ");
423 for (i
= optind
; i
< argc
; i
++)
427 char *p
= argv
[i
] + 1;
428 while (isdigit ((unsigned char) *p
) || *p
== ':') p
++;
430 fprintf (out
, "%s/", quote_file_name (cwd
));
432 else if (*argv
[i
] != '/')
433 fprintf (out
, "%s/", quote_file_name (cwd
));
435 fprintf (out
, "%s ", quote_file_name (argv
[i
]));
440 /* Maybe wait for an answer. */
444 printf ("Waiting for Emacs...");
447 /* Now, wait for an answer and print any messages. On some systems,
448 the first line we read will actually be the output we just sent.
449 We can't predict whether that will happen, so if it does, we
450 detect it by recognizing `Client: ' at the beginning. */
452 while (str
= fgets (string
, BUFSIZ
, in
))
458 #else /* This is the SYSV IPC section */
460 #include <sys/types.h>
463 #include <sys/utsname.h>
468 char *getwd (), *getcwd (), *getenv ();
469 struct utsname system_name
;
477 /* Size of text allocated in MSGP. */
478 int size_allocated
= BUFSIZ
;
479 /* Amount of text used in MSGP. */
482 = (struct msgbuf
*) malloc (sizeof (struct msgbuf
) + size_allocated
);
483 struct msqid_ds
* msg_st
;
484 char *homedir
, buf
[BUFSIZ
];
491 /* Process options. */
492 decode_options (argc
, argv
);
494 if (argc
- optind
< 1)
495 print_help_and_exit ();
498 * Create a message queue using ~/.emacs-server as the path for ftok
500 if ((homedir
= getenv ("HOME")) == NULL
)
502 fprintf (stderr
, "%s: No home directory\n", argv
[0]);
505 strcpy (buf
, homedir
);
506 #ifndef HAVE_LONG_FILE_NAMES
507 /* If file names are short, we can't fit the host name. */
508 strcat (buf
, "/.emacs-server");
510 strcat (buf
, "/.emacs-server-");
511 uname (&system_name
);
512 strcat (buf
, system_name
.nodename
);
515 key
= ftok (buf
, 1); /* unlikely to be anyone else using it */
516 s
= msgget (key
, 0600 | IPC_CREAT
);
519 fprintf (stderr
, "%s: ", argv
[0]);
524 /* Determine working dir, so we can prefix it to all the arguments. */
526 temp
= getwd (gwdirb
);
528 temp
= getcwd (gwdirb
, sizeof gwdirb
);
534 /* On some systems, cwd can look like `@machine/...';
535 ignore everything before the first slash in such a case. */
536 while (*cwd
&& *cwd
!= '/')
543 fprintf (stderr
, "%s: %s\n", argv
[0], cwd
);
545 fprintf (stderr
, "%s: Cannot get current working directory: %s\n",
546 argv
[0], strerror (errno
));
556 strcat (msgp
->mtext
, "-nowait ");
566 char *modified_arg
= argv
[0];
568 if (*modified_arg
== '+')
570 char *p
= modified_arg
+ 1;
571 while (isdigit (*p
) || *p
== ':')
576 else if (*modified_arg
!= '/')
579 modified_arg
= quote_file_name (modified_arg
);
582 /* Overestimate in case we have to quote something in CWD. */
583 used
+= 2 * strlen (cwd
);
584 used
+= strlen (modified_arg
) + 1;
585 while (used
+ 2 > size_allocated
)
588 msgp
= (struct msgbuf
*) realloc (msgp
,
589 (sizeof (struct msgbuf
)
594 strcat (msgp
->mtext
, quote_file_name (cwd
));
596 strcat (msgp
->mtext
, modified_arg
);
597 strcat (msgp
->mtext
, " ");
600 strcat (msgp
->mtext
, "\n");
601 #ifdef HPUX /* HPUX has a bug. */
602 if (strlen (msgp
->mtext
) >= 512)
604 fprintf (stderr
, "%s: args too long for msgsnd\n", progname
);
609 if (msgsnd (s
, msgp
, strlen (msgp
->mtext
)+1, 0) < 0)
611 fprintf (stderr
, "%s: ", progname
);
616 /* Maybe wait for an answer. */
620 printf ("Waiting for Emacs...");
623 msgrcv (s
, msgp
, BUFSIZ
, getpid (), 0); /* wait for anything back */
624 strcpy (buf
, msgp
->mtext
);
628 printf ("%s\n", buf
);
632 #endif /* HAVE_SYSVIPC */
634 #endif /* HAVE_SOCKETS or HAVE_SYSVIPC */
636 #ifndef HAVE_STRERROR
641 extern char *sys_errlist
[];
644 if (errnum
>= 0 && errnum
< sys_nerr
)
645 return sys_errlist
[errnum
];
646 return (char *) "Unknown error";
649 #endif /* ! HAVE_STRERROR */