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. */
44 char *getenv (), *getwd ();
47 /* This is defined with -D from the compilation command,
48 which extracts it from ../lisp/version.el. */
51 #define VERSION "unspecified"
54 /* Name used to invoke this program. */
57 /* Nonzero means don't wait for a response from Emacs. --no-wait. */
60 void print_help_and_exit ();
62 struct option longopts
[] =
64 { "no-wait", no_argument
, NULL
, 'n' },
65 { "help", no_argument
, NULL
, 'H' },
66 { "version", no_argument
, NULL
, 'V' },
67 { "alternate-editor",required_argument
, NULL
, 'a' },
72 const char * alternate_editor
= NULL
;
74 /* Decode the options from argv and argc.
75 The global variable `optind' will say how many arguments we used up. */
78 decode_options (argc
, argv
)
84 int opt
= getopt_long (argc
, argv
,
85 "VHna:", longopts
, 0);
90 alternate_editor
= getenv ("ALTERNATE_EDITOR");
95 /* If getopt returns 0, then it has already processed a
96 long-named option. We should do nothing. */
100 alternate_editor
= optarg
;
108 fprintf (stderr
, "emacsclient %s\n", VERSION
);
114 print_help_and_exit ();
120 print_help_and_exit ()
123 "Usage: %s [-a ALTERNATE-EDITOR] [-n] [--no-wait] [+LINE[:COLUMN]] FILENAME\n",
129 "Report bugs to bug-gnu-emacs@gnu.org.\n");
133 /* Return a copy of NAME, inserting a &
134 before each &, each space, and any initial -.
135 Change spaces to underscores, too, so that the
136 return value never contains a space. */
139 quote_file_name (name
)
142 char *copy
= (char *) malloc (strlen (name
) * 2 + 1);
157 if (*p
== '&' || (*p
== '-' && p
== name
))
167 /* Like malloc but get fatal error if memory is exhausted. */
173 long *result
= (long *) malloc (size
);
183 Try to run a different command, or --if no alternate editor is
184 defined-- exit with an errorcode.
191 if (alternate_editor
)
194 execvp (alternate_editor
, argv
+ i
);
205 #if !defined (HAVE_SOCKETS) && !defined (HAVE_SYSVIPC)
212 fprintf (stderr
, "%s: Sorry, the Emacs server is supported only\n",
214 fprintf (stderr
, "on systems with Berkeley sockets or System V IPC.\n");
219 #else /* HAVE_SOCKETS or HAVE_SYSVIPC */
221 #if defined (HAVE_SOCKETS) && ! defined (NO_SOCKETS_IN_FILE_SYSTEM)
222 /* BSD code is very different from SYSV IPC code */
224 #include <sys/types.h>
225 #include <sys/socket.h>
227 #include <sys/stat.h>
230 extern char *strerror ();
233 /* Three possibilities:
234 2 - can't be `stat'ed (sets errno)
235 1 - isn't owned by us
236 0 - success: none of the above */
239 socket_status (socket_name
)
244 if (stat (socket_name
, &statbfr
) == -1)
247 if (statbfr
.st_uid
!= geteuid ())
259 int system_name_length
;
262 struct sockaddr_un server
;
263 #ifdef SERVER_HOME_DIR
271 /* Process options. */
272 decode_options (argc
, argv
);
274 if (argc
- optind
< 1)
275 print_help_and_exit ();
278 * Open up an AF_UNIX socket in this person's home directory
281 if ((s
= socket (AF_UNIX
, SOCK_STREAM
, 0)) < 0)
283 fprintf (stderr
, "%s: ", argv
[0]);
288 server
.sun_family
= AF_UNIX
;
291 system_name_length
= 32;
295 system_name
= (char *) xmalloc (system_name_length
+ 1);
297 /* system_name must be null-terminated string. */
298 system_name
[system_name_length
] = '\0';
300 if (gethostname (system_name
, system_name_length
) == 0)
304 system_name_length
*= 2;
308 #ifndef SERVER_HOME_DIR
312 sprintf (server
.sun_path
, "/tmp/esrv%d-%s", (int) geteuid (), system_name
);
314 /* See if the socket exists, and if it's owned by us. */
315 sock_status
= socket_status (server
.sun_path
);
318 /* Failing that, see if LOGNAME or USER exist and differ from
319 our euid. If so, look for a socket based on the UID
320 associated with the name. This is reminiscent of the logic
321 that init_editfns uses to set the global Vuser_full_name. */
323 char *user_name
= (char *) getenv ("LOGNAME");
325 user_name
= (char *) getenv ("USER");
329 struct passwd
*pw
= getpwnam (user_name
);
330 if (pw
&& (pw
->pw_uid
!= geteuid ()))
332 /* We're running under su, apparently. */
333 sprintf (server
.sun_path
, "/tmp/esrv%d-%s",
334 (int) pw
->pw_uid
, system_name
);
335 sock_status
= socket_status (server
.sun_path
);
343 /* There's a socket, but it isn't owned by us. This is OK if
347 fprintf (stderr
, "%s: Invalid socket owner\n", argv
[0]);
356 "%s: can't find socket; have you started the server?\n",
359 fprintf (stderr
, "%s: can't stat %s: %s\n",
360 argv
[0], server
.sun_path
, strerror (errno
));
366 if ((homedir
= getenv ("HOME")) == NULL
)
368 fprintf (stderr
, "%s: No home directory\n", argv
[0]);
371 strcpy (server
.sun_path
, homedir
);
372 strcat (server
.sun_path
, "/.emacs-server-");
373 strcat (server
.sun_path
, system_name
);
376 if (connect (s
, (struct sockaddr
*) &server
, strlen (server
.sun_path
) + 2)
379 fprintf (stderr
, "%s: ", argv
[0]);
384 /* We use the stream OUT to send our command to the server. */
385 if ((out
= fdopen (s
, "r+")) == NULL
)
387 fprintf (stderr
, "%s: ", argv
[0]);
392 /* We use the stream IN to read the response.
393 We used to use just one stream for both output and input
394 on the socket, but reversing direction works nonportably:
395 on some systems, the output appears as the first input;
396 on other systems it does not. */
397 if ((in
= fdopen (s
, "r+")) == NULL
)
399 fprintf (stderr
, "%s: ", argv
[0]);
405 cwd
= getwd (string
);
407 cwd
= getcwd (string
, sizeof string
);
411 /* getwd puts message in STRING if it fails. */
412 fprintf (stderr
, "%s: %s (%s)\n", argv
[0],
416 "Cannot get current working directory",
423 fprintf (out
, "-nowait ");
425 for (i
= optind
; i
< argc
; i
++)
429 char *p
= argv
[i
] + 1;
430 while (isdigit ((unsigned char) *p
) || *p
== ':') p
++;
432 fprintf (out
, "%s/", quote_file_name (cwd
));
434 else if (*argv
[i
] != '/')
435 fprintf (out
, "%s/", quote_file_name (cwd
));
437 fprintf (out
, "%s ", quote_file_name (argv
[i
]));
442 /* Maybe wait for an answer. */
446 printf ("Waiting for Emacs...");
449 /* Now, wait for an answer and print any messages. On some systems,
450 the first line we read will actually be the output we just sent.
451 We can't predict whether that will happen, so if it does, we
452 detect it by recognizing `Client: ' at the beginning. */
454 while ((str
= fgets (string
, BUFSIZ
, in
)))
460 #else /* This is the SYSV IPC section */
462 #include <sys/types.h>
465 #include <sys/utsname.h>
470 char *getwd (), *getcwd (), *getenv ();
471 struct utsname system_name
;
479 /* Size of text allocated in MSGP. */
480 int size_allocated
= BUFSIZ
;
481 /* Amount of text used in MSGP. */
484 = (struct msgbuf
*) malloc (sizeof (struct msgbuf
) + size_allocated
);
485 struct msqid_ds
* msg_st
;
486 char *homedir
, buf
[BUFSIZ
];
493 /* Process options. */
494 decode_options (argc
, argv
);
496 if (argc
- optind
< 1)
497 print_help_and_exit ();
500 * Create a message queue using ~/.emacs-server as the path for ftok
502 if ((homedir
= getenv ("HOME")) == NULL
)
504 fprintf (stderr
, "%s: No home directory\n", argv
[0]);
507 strcpy (buf
, homedir
);
508 #ifndef HAVE_LONG_FILE_NAMES
509 /* If file names are short, we can't fit the host name. */
510 strcat (buf
, "/.emacs-server");
512 strcat (buf
, "/.emacs-server-");
513 uname (&system_name
);
514 strcat (buf
, system_name
.nodename
);
517 key
= ftok (buf
, 1); /* unlikely to be anyone else using it */
518 s
= msgget (key
, 0600 | IPC_CREAT
);
521 fprintf (stderr
, "%s: ", argv
[0]);
526 /* Determine working dir, so we can prefix it to all the arguments. */
528 temp
= getwd (gwdirb
);
530 temp
= getcwd (gwdirb
, sizeof gwdirb
);
536 /* On some systems, cwd can look like `@machine/...';
537 ignore everything before the first slash in such a case. */
538 while (*cwd
&& *cwd
!= '/')
545 fprintf (stderr
, "%s: %s\n", argv
[0], cwd
);
547 fprintf (stderr
, "%s: Cannot get current working directory: %s\n",
548 argv
[0], strerror (errno
));
558 strcat (msgp
->mtext
, "-nowait ");
568 char *modified_arg
= argv
[0];
570 if (*modified_arg
== '+')
572 char *p
= modified_arg
+ 1;
573 while (isdigit (*p
) || *p
== ':')
578 else if (*modified_arg
!= '/')
581 modified_arg
= quote_file_name (modified_arg
);
584 /* Overestimate in case we have to quote something in CWD. */
585 used
+= 2 * strlen (cwd
);
586 used
+= strlen (modified_arg
) + 1;
587 while (used
+ 2 > size_allocated
)
590 msgp
= (struct msgbuf
*) realloc (msgp
,
591 (sizeof (struct msgbuf
)
596 strcat (msgp
->mtext
, quote_file_name (cwd
));
598 strcat (msgp
->mtext
, modified_arg
);
599 strcat (msgp
->mtext
, " ");
602 strcat (msgp
->mtext
, "\n");
603 #ifdef HPUX /* HPUX has a bug. */
604 if (strlen (msgp
->mtext
) >= 512)
606 fprintf (stderr
, "%s: args too long for msgsnd\n", progname
);
611 if (msgsnd (s
, msgp
, strlen (msgp
->mtext
)+1, 0) < 0)
613 fprintf (stderr
, "%s: ", progname
);
618 /* Maybe wait for an answer. */
622 printf ("Waiting for Emacs...");
625 msgrcv (s
, msgp
, BUFSIZ
, getpid (), 0); /* wait for anything back */
626 strcpy (buf
, msgp
->mtext
);
630 printf ("%s\n", buf
);
634 #endif /* HAVE_SYSVIPC */
636 #endif /* HAVE_SOCKETS or HAVE_SYSVIPC */
638 #ifndef HAVE_STRERROR
643 extern char *sys_errlist
[];
646 if (errnum
>= 0 && errnum
< sys_nerr
)
647 return sys_errlist
[errnum
];
648 return (char *) "Unknown error";
651 #endif /* ! HAVE_STRERROR */