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, each newline, 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);
163 if (*p
== '&' || (*p
== '-' && p
== name
))
173 /* Like malloc but get fatal error if memory is exhausted. */
179 long *result
= (long *) malloc (size
);
189 Try to run a different command, or --if no alternate editor is
190 defined-- exit with an errorcode.
197 if (alternate_editor
)
200 execvp (alternate_editor
, argv
+ i
);
211 #if !defined (HAVE_SOCKETS) && !defined (HAVE_SYSVIPC)
218 fprintf (stderr
, "%s: Sorry, the Emacs server is supported only\n",
220 fprintf (stderr
, "on systems with Berkeley sockets or System V IPC.\n");
225 #else /* HAVE_SOCKETS or HAVE_SYSVIPC */
227 #if defined (HAVE_SOCKETS) && ! defined (NO_SOCKETS_IN_FILE_SYSTEM)
228 /* BSD code is very different from SYSV IPC code */
230 #include <sys/types.h>
231 #include <sys/socket.h>
233 #include <sys/stat.h>
236 extern char *strerror ();
239 /* Three possibilities:
240 2 - can't be `stat'ed (sets errno)
241 1 - isn't owned by us
242 0 - success: none of the above */
245 socket_status (socket_name
)
250 if (stat (socket_name
, &statbfr
) == -1)
253 if (statbfr
.st_uid
!= geteuid ())
265 int system_name_length
;
266 int s
, i
, needlf
= 0;
268 struct sockaddr_un server
;
269 #ifdef SERVER_HOME_DIR
277 /* Process options. */
278 decode_options (argc
, argv
);
280 if (argc
- optind
< 1)
281 print_help_and_exit ();
284 * Open up an AF_UNIX socket in this person's home directory
287 if ((s
= socket (AF_UNIX
, SOCK_STREAM
, 0)) < 0)
289 fprintf (stderr
, "%s: ", argv
[0]);
294 server
.sun_family
= AF_UNIX
;
297 system_name_length
= 32;
301 system_name
= (char *) xmalloc (system_name_length
+ 1);
303 /* system_name must be null-terminated string. */
304 system_name
[system_name_length
] = '\0';
306 if (gethostname (system_name
, system_name_length
) == 0)
310 system_name_length
*= 2;
314 #ifndef SERVER_HOME_DIR
318 sprintf (server
.sun_path
, "/tmp/esrv%d-%s", (int) geteuid (), system_name
);
320 /* See if the socket exists, and if it's owned by us. */
321 sock_status
= socket_status (server
.sun_path
);
324 /* Failing that, see if LOGNAME or USER exist and differ from
325 our euid. If so, look for a socket based on the UID
326 associated with the name. This is reminiscent of the logic
327 that init_editfns uses to set the global Vuser_full_name. */
329 char *user_name
= (char *) getenv ("LOGNAME");
331 user_name
= (char *) getenv ("USER");
335 struct passwd
*pw
= getpwnam (user_name
);
336 if (pw
&& (pw
->pw_uid
!= geteuid ()))
338 /* We're running under su, apparently. */
339 sprintf (server
.sun_path
, "/tmp/esrv%d-%s",
340 (int) pw
->pw_uid
, system_name
);
341 sock_status
= socket_status (server
.sun_path
);
349 /* There's a socket, but it isn't owned by us. This is OK if
353 fprintf (stderr
, "%s: Invalid socket owner\n", argv
[0]);
362 "%s: can't find socket; have you started the server?\n",
365 fprintf (stderr
, "%s: can't stat %s: %s\n",
366 argv
[0], server
.sun_path
, strerror (errno
));
372 if ((homedir
= getenv ("HOME")) == NULL
)
374 fprintf (stderr
, "%s: No home directory\n", argv
[0]);
377 strcpy (server
.sun_path
, homedir
);
378 strcat (server
.sun_path
, "/.emacs-server-");
379 strcat (server
.sun_path
, system_name
);
382 if (connect (s
, (struct sockaddr
*) &server
, strlen (server
.sun_path
) + 2)
385 fprintf (stderr
, "%s: ", argv
[0]);
390 /* We use the stream OUT to send our command to the server. */
391 if ((out
= fdopen (s
, "r+")) == NULL
)
393 fprintf (stderr
, "%s: ", argv
[0]);
398 /* We use the stream IN to read the response.
399 We used to use just one stream for both output and input
400 on the socket, but reversing direction works nonportably:
401 on some systems, the output appears as the first input;
402 on other systems it does not. */
403 if ((in
= fdopen (s
, "r+")) == NULL
)
405 fprintf (stderr
, "%s: ", argv
[0]);
411 cwd
= getwd (string
);
413 cwd
= getcwd (string
, sizeof string
);
417 /* getwd puts message in STRING if it fails. */
418 fprintf (stderr
, "%s: %s (%s)\n", argv
[0],
422 "Cannot get current working directory",
429 fprintf (out
, "-nowait ");
431 for (i
= optind
; i
< argc
; i
++)
435 char *p
= argv
[i
] + 1;
436 while (isdigit ((unsigned char) *p
) || *p
== ':') p
++;
438 fprintf (out
, "%s/", quote_file_name (cwd
));
440 else if (*argv
[i
] != '/')
441 fprintf (out
, "%s/", quote_file_name (cwd
));
443 fprintf (out
, "%s ", quote_file_name (argv
[i
]));
448 /* Maybe wait for an answer. */
452 printf ("Waiting for Emacs...");
456 /* Now, wait for an answer and print any messages. */
457 while ((str
= fgets (string
, BUFSIZ
, in
)))
462 needlf
= str
[0] == '\0' ? needlf
: str
[strlen (str
) - 1] != '\n';
472 #else /* This is the SYSV IPC section */
474 #include <sys/types.h>
477 #include <sys/utsname.h>
482 char *getwd (), *getcwd (), *getenv ();
483 struct utsname system_name
;
491 /* Size of text allocated in MSGP. */
492 int size_allocated
= BUFSIZ
;
493 /* Amount of text used in MSGP. */
496 = (struct msgbuf
*) malloc (sizeof (struct msgbuf
) + size_allocated
);
497 struct msqid_ds
* msg_st
;
498 char *homedir
, buf
[BUFSIZ
];
505 /* Process options. */
506 decode_options (argc
, argv
);
508 if (argc
- optind
< 1)
509 print_help_and_exit ();
512 * Create a message queue using ~/.emacs-server as the path for ftok
514 if ((homedir
= getenv ("HOME")) == NULL
)
516 fprintf (stderr
, "%s: No home directory\n", argv
[0]);
519 strcpy (buf
, homedir
);
520 #ifndef HAVE_LONG_FILE_NAMES
521 /* If file names are short, we can't fit the host name. */
522 strcat (buf
, "/.emacs-server");
524 strcat (buf
, "/.emacs-server-");
525 uname (&system_name
);
526 strcat (buf
, system_name
.nodename
);
529 key
= ftok (buf
, 1); /* unlikely to be anyone else using it */
530 s
= msgget (key
, 0600 | IPC_CREAT
);
533 fprintf (stderr
, "%s: ", argv
[0]);
538 /* Determine working dir, so we can prefix it to all the arguments. */
540 temp
= getwd (gwdirb
);
542 temp
= getcwd (gwdirb
, sizeof gwdirb
);
548 /* On some systems, cwd can look like `@machine/...';
549 ignore everything before the first slash in such a case. */
550 while (*cwd
&& *cwd
!= '/')
557 fprintf (stderr
, "%s: %s\n", argv
[0], cwd
);
559 fprintf (stderr
, "%s: Cannot get current working directory: %s\n",
560 argv
[0], strerror (errno
));
570 strcat (msgp
->mtext
, "-nowait ");
580 char *modified_arg
= argv
[0];
582 if (*modified_arg
== '+')
584 char *p
= modified_arg
+ 1;
585 while (isdigit (*p
) || *p
== ':')
590 else if (*modified_arg
!= '/')
593 modified_arg
= quote_file_name (modified_arg
);
596 /* Overestimate in case we have to quote something in CWD. */
597 used
+= 2 * strlen (cwd
);
598 used
+= strlen (modified_arg
) + 1;
599 while (used
+ 2 > size_allocated
)
602 msgp
= (struct msgbuf
*) realloc (msgp
,
603 (sizeof (struct msgbuf
)
608 strcat (msgp
->mtext
, quote_file_name (cwd
));
610 strcat (msgp
->mtext
, modified_arg
);
611 strcat (msgp
->mtext
, " ");
614 strcat (msgp
->mtext
, "\n");
615 #ifdef HPUX /* HPUX has a bug. */
616 if (strlen (msgp
->mtext
) >= 512)
618 fprintf (stderr
, "%s: args too long for msgsnd\n", progname
);
623 if (msgsnd (s
, msgp
, strlen (msgp
->mtext
)+1, 0) < 0)
625 fprintf (stderr
, "%s: ", progname
);
630 /* Maybe wait for an answer. */
634 printf ("Waiting for Emacs...");
637 msgrcv (s
, msgp
, BUFSIZ
, getpid (), 0); /* wait for anything back */
638 strcpy (buf
, msgp
->mtext
);
642 printf ("%s\n", buf
);
646 #endif /* HAVE_SYSVIPC */
648 #endif /* HAVE_SOCKETS or HAVE_SYSVIPC */
650 #ifndef HAVE_STRERROR
655 extern char *sys_errlist
[];
658 if (errnum
>= 0 && errnum
< sys_nerr
)
659 return sys_errlist
[errnum
];
660 return (char *) "Unknown error";
663 #endif /* ! HAVE_STRERROR */