(server-start): Save also the Emacs pid in the server authentication file.
[bpt/emacs.git] / lib-src / emacsclient.c
CommitLineData
efb859b4 1/* Client process that communicates with GNU Emacs acting as server.
92b47a4a 2 Copyright (C) 1986, 1987, 1994, 1999, 2000, 2001, 2002, 2003, 2004,
273dc16a 3 2005, 2006 Free Software Foundation, Inc.
46cec291
RS
4
5This file is part of GNU Emacs.
6
7GNU Emacs is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
92af894f 9the Free Software Foundation; either version 2, or (at your option)
46cec291
RS
10any later version.
11
12GNU Emacs is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GNU Emacs; see the file COPYING. If not, write to
364c38d3
LK
19the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20Boston, MA 02110-1301, USA. */
46cec291
RS
21
22
23#define NO_SHORTNAMES
e69233c2
PJ
24
25#ifdef HAVE_CONFIG_H
2f8fe2f4 26#include <config.h>
e69233c2
PJ
27#endif
28
aa0b6932 29#ifdef WINDOWSNT
aa0b6932 30
411b80a5
JB
31# include <malloc.h>
32# include <stdlib.h>
33
34# define HAVE_SOCKETS
1e7823d0 35# define HAVE_INET_SOCKETS
411b80a5
JB
36# define NO_SOCKETS_IN_FILE_SYSTEM
37
aa0b6932
JB
38# define HSOCKET SOCKET
39# define CLOSE_SOCKET closesocket
aa0b6932 40# define INITIALIZE() (initialize_sockets ())
411b80a5
JB
41
42#else /* !WINDOWSNT */
43
1e7823d0
JB
44# ifdef HAVE_INET_SOCKETS
45# include <netinet/in.h>
46# endif
411b80a5 47
e35fc962 48# define INVALID_SOCKET -1
aa0b6932
JB
49# define HSOCKET int
50# define CLOSE_SOCKET close
aa0b6932 51# define INITIALIZE()
411b80a5
JB
52
53#endif /* !WINDOWSNT */
aa0b6932 54
4e23f2ba 55#undef signal
46cec291 56
e69233c2 57#include <ctype.h>
8f9aaa0a 58#include <stdio.h>
aa0b6932 59#include "getopt.h"
79f13bba
DL
60#ifdef HAVE_UNISTD_H
61#include <unistd.h>
62#endif
8f9aaa0a 63
9f637eea
GM
64#ifdef VMS
65# include "vms-pwd.h"
aa0b6932
JB
66#else /* not VMS */
67#ifdef WINDOWSNT
68# include <io.h>
69#else /* not WINDOWSNT */
9f637eea 70# include <pwd.h>
aa0b6932 71#endif /* not WINDOWSNT */
9f637eea
GM
72#endif /* not VMS */
73
8f9aaa0a 74char *getenv (), *getwd ();
5b9562c3 75char *(getcwd) ();
8f9aaa0a 76
8f9aaa0a
RS
77#ifndef VERSION
78#define VERSION "unspecified"
79#endif
80\f
aa0b6932
JB
81#define SEND_STRING(data) (send_to_emacs (s, (data)))
82#define SEND_QUOTED(data) (quote_file_name (s, (data)))
83
84#ifndef EXIT_SUCCESS
85#define EXIT_SUCCESS 0
86#endif
87
88#ifndef EXIT_FAILURE
89#define EXIT_FAILURE 1
90#endif
91
92#ifndef FALSE
93#define FALSE 0
94#endif
95
96#ifndef TRUE
97#define TRUE 1
98#endif
99
100#ifndef NO_RETURN
101#define NO_RETURN
102#endif
103\f
8f9aaa0a
RS
104/* Name used to invoke this program. */
105char *progname;
106
749ae770 107/* Nonzero means don't wait for a response from Emacs. --no-wait. */
8f9aaa0a
RS
108int nowait = 0;
109
30be2360
SM
110/* Nonzero means args are expressions to be evaluated. --eval. */
111int eval = 0;
112
113/* The display on which Emacs should work. --display. */
114char *display = NULL;
115
116/* If non-NULL, the name of an editor to fallback to if the server
117 is not running. --alternate-editor. */
b03d27bd 118const char *alternate_editor = NULL;
30be2360 119
3db926be 120/* If non-NULL, the filename of the UNIX socket. */
254107e4
RS
121char *socket_name = NULL;
122
aa0b6932
JB
123/* If non-NULL, the filename of the authentication file. */
124char *server_file = NULL;
125
2381d38d 126void print_help_and_exit () NO_RETURN;
7f3bff3e 127
8f9aaa0a
RS
128struct option longopts[] =
129{
749ae770 130 { "no-wait", no_argument, NULL, 'n' },
30be2360 131 { "eval", no_argument, NULL, 'e' },
8f9aaa0a
RS
132 { "help", no_argument, NULL, 'H' },
133 { "version", no_argument, NULL, 'V' },
3cf8c6aa 134 { "alternate-editor", required_argument, NULL, 'a' },
b03d27bd 135#ifndef NO_SOCKETS_IN_FILE_SYSTEM
254107e4 136 { "socket-name", required_argument, NULL, 's' },
b03d27bd 137#endif
aa0b6932 138 { "server-file", required_argument, NULL, 'f' },
30be2360
SM
139 { "display", required_argument, NULL, 'd' },
140 { 0, 0, 0, 0 }
8f9aaa0a
RS
141};
142
143/* Decode the options from argv and argc.
5212210c 144 The global variable `optind' will say how many arguments we used up. */
8f9aaa0a 145
5212210c 146void
8f9aaa0a
RS
147decode_options (argc, argv)
148 int argc;
149 char **argv;
150{
b6b6d6d2
SM
151 alternate_editor = getenv ("ALTERNATE_EDITOR");
152
8f9aaa0a
RS
153 while (1)
154 {
155 int opt = getopt_long (argc, argv,
b03d27bd
JB
156#ifndef NO_SOCKETS_IN_FILE_SYSTEM
157 "VHnea:s:f:d:",
158#else
159 "VHnea:f:d:",
160#endif
161 longopts, 0);
8f9aaa0a
RS
162
163 if (opt == EOF)
164 break;
165
166 switch (opt)
167 {
168 case 0:
169 /* If getopt returns 0, then it has already processed a
170 long-named option. We should do nothing. */
171 break;
e69233c2 172
97e3214d
GM
173 case 'a':
174 alternate_editor = optarg;
175 break;
e69233c2 176
b03d27bd 177#ifndef NO_SOCKETS_IN_FILE_SYSTEM
254107e4
RS
178 case 's':
179 socket_name = optarg;
180 break;
b03d27bd 181#endif
254107e4 182
aa0b6932
JB
183 case 'f':
184 server_file = optarg;
185 break;
186
30be2360
SM
187 case 'd':
188 display = optarg;
189 break;
190
8f9aaa0a
RS
191 case 'n':
192 nowait = 1;
193 break;
194
30be2360
SM
195 case 'e':
196 eval = 1;
197 break;
198
8f9aaa0a 199 case 'V':
20c396e8 200 printf ("emacsclient %s\n", VERSION);
65396510 201 exit (EXIT_SUCCESS);
8f9aaa0a 202 break;
46cec291 203
8f9aaa0a 204 case 'H':
8f9aaa0a 205 print_help_and_exit ();
20c396e8
JB
206 break;
207
208 default:
209 fprintf (stderr, "Try `%s --help' for more information\n", progname);
65396510 210 exit (EXIT_FAILURE);
20c396e8 211 break;
8f9aaa0a
RS
212 }
213 }
8f9aaa0a
RS
214}
215
7f3bff3e 216void
8f9aaa0a
RS
217print_help_and_exit ()
218{
20c396e8
JB
219 printf (
220 "Usage: %s [OPTIONS] FILE...\n\
30be2360
SM
221Tell the Emacs server to visit the specified files.\n\
222Every FILE can be either just a FILENAME or [+LINE[:COLUMN]] FILENAME.\n\
20c396e8 223\n\
30be2360
SM
224The following OPTIONS are accepted:\n\
225-V, --version Just print a version info and return\n\
226-H, --help Print this usage information message\n\
227-n, --no-wait Don't wait for the server to return\n\
228-e, --eval Evaluate the FILE arguments as ELisp expressions\n\
aa0b6932
JB
229-d, --display=DISPLAY Visit the file in the given display\n"
230#ifndef NO_SOCKETS_IN_FILE_SYSTEM
231"-s, --socket-name=FILENAME\n\
232 Set the filename of the UNIX socket for communication\n"
233#endif
234"-f, --server-file=FILENAME\n\
235 Set the filename of the TCP configuration file\n\
30be2360
SM
236-a, --alternate-editor=EDITOR\n\
237 Editor to fallback to if the server is not running\n\
20c396e8 238\n\
30be2360 239Report bugs to bug-gnu-emacs@gnu.org.\n", progname);
65396510 240 exit (EXIT_SUCCESS);
8f9aaa0a 241}
5212210c 242
aa0b6932
JB
243\f
244/*
245 Try to run a different command, or --if no alternate editor is
246 defined-- exit with an errorcode.
247*/
248void
249fail (argc, argv)
250 int argc;
251 char **argv;
252{
253 if (alternate_editor)
254 {
255 int i = optind - 1;
b73ea44b
JB
256#ifdef WINDOWSNT
257 argv[i] = (char *)alternate_editor;
258#endif
aa0b6932
JB
259 execvp (alternate_editor, argv + i);
260 fprintf (stderr, "%s: error executing alternate editor \"%s\"\n",
261 progname, alternate_editor);
262 }
aa0b6932
JB
263 exit (EXIT_FAILURE);
264}
265
266\f
1e7823d0 267#if !defined (HAVE_SOCKETS) || !defined (HAVE_INET_SOCKETS)
aa0b6932
JB
268
269int
270main (argc, argv)
271 int argc;
272 char **argv;
273{
274 fprintf (stderr, "%s: Sorry, the Emacs server is supported only\n",
275 argv[0]);
276 fprintf (stderr, "on systems with Berkeley sockets.\n");
277
278 fail (argc, argv);
279}
280
1e7823d0 281#else /* HAVE_SOCKETS && HAVE_INET_SOCKETS */
aa0b6932
JB
282
283#ifdef WINDOWSNT
284# include <winsock2.h>
285#else
286# include <sys/types.h>
287# include <sys/socket.h>
288# include <sys/un.h>
289# include <sys/stat.h>
290# include <errno.h>
291#endif
292
293#define AUTH_KEY_LENGTH 64
294#define SEND_BUFFER_SIZE 4096
295
296extern char *strerror ();
297extern int errno;
298
299/* Buffer to accumulate data to send in TCP connections. */
300char send_buffer[SEND_BUFFER_SIZE + 1];
301int sblen = 0; /* Fill pointer for the send buffer. */
302
303/* Let's send the data to Emacs when either
304 - the data ends in "\n", or
305 - the buffer is full (but this shouldn't happen)
306 Otherwise, we just accumulate it. */
b03d27bd
JB
307void
308send_to_emacs (s, data)
aa0b6932
JB
309 HSOCKET s;
310 char *data;
311{
312 while (data)
313 {
314 int dlen = strlen (data);
315 if (dlen + sblen >= SEND_BUFFER_SIZE)
316 {
317 int part = SEND_BUFFER_SIZE - sblen;
318 strncpy (&send_buffer[sblen], data, part);
319 data += part;
320 sblen = SEND_BUFFER_SIZE;
321 }
322 else if (dlen)
323 {
324 strcpy (&send_buffer[sblen], data);
325 data = NULL;
326 sblen += dlen;
327 }
328 else
329 break;
330
331 if (sblen == SEND_BUFFER_SIZE
332 || (sblen > 0 && send_buffer[sblen-1] == '\n'))
333 {
334 int sent = send (s, send_buffer, sblen, 0);
335 if (sent != sblen)
336 strcpy (send_buffer, &send_buffer[sent]);
337 sblen -= sent;
338 }
339 }
340}
341
a4cf2096
RS
342/* In NAME, insert a & before each &, each space, each newline, and
343 any initial -. Change spaces to underscores, too, so that the
5212210c 344 return value never contains a space. */
87209357 345void
aa0b6932
JB
346quote_file_name (s, name)
347 HSOCKET s;
5212210c
RS
348 char *name;
349{
350 char *copy = (char *) malloc (strlen (name) * 2 + 1);
351 char *p, *q;
352
353 p = name;
354 q = copy;
355 while (*p)
356 {
357 if (*p == ' ')
358 {
f1db6a73 359 *q++ = '&';
5212210c
RS
360 *q++ = '_';
361 p++;
362 }
3cf8c6aa
SM
363 else if (*p == '\n')
364 {
365 *q++ = '&';
366 *q++ = 'n';
367 p++;
368 }
5212210c
RS
369 else
370 {
f1db6a73
RS
371 if (*p == '&' || (*p == '-' && p == name))
372 *q++ = '&';
5212210c
RS
373 *q++ = *p++;
374 }
375 }
f1db6a73 376 *q++ = 0;
5212210c 377
aa0b6932 378 SEND_STRING (copy);
87209357
EZ
379
380 free (copy);
5212210c 381}
0c76956f 382
b03d27bd
JB
383int
384file_name_absolute_p (filename)
385 const unsigned char *filename;
386{
387 /* Sanity check, it shouldn't happen. */
388 if (! filename) return FALSE;
389
390 /* /xxx is always an absolute path. */
391 if (filename[0] == '/') return TRUE;
392
393 /* Empty filenames (which shouldn't happen) are relative. */
394 if (filename[0] == '\0') return FALSE;
395
396#ifdef WINDOWSNT
397 /* X:\xxx is always absolute; X:xxx is an error and will fail. */
398 if (islower (tolower (filename[0]))
399 && filename[1] == ':' && filename[2] == '\\')
400 return TRUE;
401
402 /* Both \xxx and \\xxx\yyy are absolute. */
403 if (filename[0] == '\\') return TRUE;
404#endif
405
406 return FALSE;
407}
408
aa0b6932
JB
409#ifdef WINDOWSNT
410/* Wrapper to make WSACleanup a cdecl, as required by atexit(). */
b03d27bd
JB
411void
412__cdecl close_winsock ()
aa0b6932
JB
413{
414 WSACleanup ();
415}
0c76956f 416
b03d27bd
JB
417/* Initialize the WinSock2 library. */
418void
419initialize_sockets ()
0c76956f 420{
aa0b6932
JB
421 WSADATA wsaData;
422
aa0b6932
JB
423 if (WSAStartup (MAKEWORD (2, 0), &wsaData))
424 {
425 fprintf (stderr, "%s: error initializing WinSock2", progname);
426 exit (EXIT_FAILURE);
427 }
428
429 atexit (close_winsock);
0c76956f 430}
e35fc962 431#endif /* WINDOWSNT */
8f9aaa0a 432\f
97e3214d 433/*
aa0b6932
JB
434 * Read the information needed to set up a TCP comm channel with
435 * the Emacs server: host, port and authentication string.
97e3214d 436*/
b03d27bd
JB
437int
438get_server_config (server, authentication)
aa0b6932
JB
439 struct sockaddr_in *server;
440 char *authentication;
97e3214d 441{
aa0b6932
JB
442 char dotted[32];
443 char *port;
b03d27bd 444 FILE *config = NULL;
aa0b6932 445
b03d27bd
JB
446 if (file_name_absolute_p (server_file))
447 config = fopen (server_file, "rb");
448 else
97e3214d 449 {
aa0b6932
JB
450 char *home = getenv ("HOME");
451#ifdef WINDOWSNT
452 if (! home)
453 home = getenv ("APPDATA");
454#endif
455 if (home)
456 {
457 char *path = alloca (32 + strlen (home) + strlen (server_file));
458 sprintf (path, "%s/.emacs.d/server/%s", home, server_file);
459 config = fopen (path, "rb");
460 }
461 }
462
463 if (! config)
464 return FALSE;
465
466 if (fgets (dotted, sizeof dotted, config)
467 && (port = strchr (dotted, ':')))
468 {
469 *port++ = '\0';
97e3214d
GM
470 }
471 else
472 {
aa0b6932 473 fprintf (stderr, "%s: invalid configuration info", progname);
65396510 474 exit (EXIT_FAILURE);
97e3214d 475 }
97e3214d 476
aa0b6932
JB
477 server->sin_family = AF_INET;
478 server->sin_addr.s_addr = inet_addr (dotted);
479 server->sin_port = htons (atoi (port));
97e3214d 480
aa0b6932
JB
481 if (! fread (authentication, AUTH_KEY_LENGTH, 1, config))
482 {
483 fprintf (stderr, "%s: cannot read authentication info", progname);
484 exit (EXIT_FAILURE);
485 }
46cec291 486
aa0b6932 487 fclose (config);
97e3214d 488
aa0b6932 489 return TRUE;
46cec291
RS
490}
491
aa0b6932
JB
492HSOCKET
493set_tcp_socket ()
494{
495 HSOCKET s;
496 struct sockaddr_in server;
aa0b6932
JB
497 struct linger l_arg = {1, 1};
498 char auth_string[AUTH_KEY_LENGTH + 1];
46cec291 499
aa0b6932
JB
500 if (! get_server_config (&server, auth_string))
501 return INVALID_SOCKET;
502
b03d27bd
JB
503 if (server.sin_addr.s_addr != inet_addr ("127.0.0.1"))
504 fprintf (stderr, "%s: connected to remote socket at %s\n",
505 progname, inet_ntoa (server.sin_addr));
506
aa0b6932
JB
507 /*
508 * Open up an AF_INET socket
509 */
510 if ((s = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
511 {
512 fprintf (stderr, "%s: ", progname);
513 perror ("socket");
514 return INVALID_SOCKET;
515 }
516
517 /*
518 * Set up the socket
519 */
520 if (connect (s, (struct sockaddr *) &server, sizeof server) < 0)
521 {
522 fprintf (stderr, "%s: ", progname);
523 perror ("connect");
524 return INVALID_SOCKET;
525 }
526
aa0b6932
JB
527 setsockopt (s, SOL_SOCKET, SO_LINGER, (char *) &l_arg, sizeof l_arg);
528
529 /*
530 * Send the authentication
531 */
532 auth_string[AUTH_KEY_LENGTH] = '\0';
533
534 SEND_STRING ("-auth ");
535 SEND_STRING (auth_string);
536 SEND_STRING ("\n");
537
538 return s;
539}
540
541#if !defined (NO_SOCKETS_IN_FILE_SYSTEM)
46cec291 542
9f637eea
GM
543/* Three possibilities:
544 2 - can't be `stat'ed (sets errno)
545 1 - isn't owned by us
546 0 - success: none of the above */
547
548static int
549socket_status (socket_name)
550 char *socket_name;
551{
552 struct stat statbfr;
553
554 if (stat (socket_name, &statbfr) == -1)
555 return 2;
556
557 if (statbfr.st_uid != geteuid ())
558 return 1;
559
560 return 0;
561}
562
aa0b6932
JB
563HSOCKET
564set_local_socket ()
46cec291 565{
aa0b6932 566 HSOCKET s;
46cec291 567 struct sockaddr_un server;
46cec291 568
e69233c2 569 /*
46cec291
RS
570 * Open up an AF_UNIX socket in this person's home directory
571 */
572
573 if ((s = socket (AF_UNIX, SOCK_STREAM, 0)) < 0)
574 {
aa0b6932 575 fprintf (stderr, "%s: ", progname);
46cec291 576 perror ("socket");
aa0b6932 577 return INVALID_SOCKET;
46cec291 578 }
e69233c2 579
46cec291 580 server.sun_family = AF_UNIX;
c5fee545 581
c5fee545 582 {
9f637eea 583 int sock_status = 0;
5c9659d3 584 int default_sock = !socket_name;
152b6e83 585 int saved_errno;
0734b0d0
SM
586 char *server_name = "server";
587
588 if (socket_name && !index (socket_name, '/') && !index (socket_name, '\\'))
589 { /* socket_name is a file name component. */
590 server_name = socket_name;
591 socket_name = NULL;
592 default_sock = 1; /* Try both UIDs. */
593 }
efb859b4 594
5c9659d3 595 if (default_sock)
254107e4 596 {
0734b0d0
SM
597 socket_name = alloca (100 + strlen (server_name));
598 sprintf (socket_name, "/tmp/emacs%d/%s",
599 (int) geteuid (), server_name);
254107e4
RS
600 }
601
602 if (strlen (socket_name) < sizeof (server.sun_path))
603 strcpy (server.sun_path, socket_name);
604 else
5c9659d3
SM
605 {
606 fprintf (stderr, "%s: socket-name %s too long",
aa0b6932 607 progname, socket_name);
65396510 608 exit (EXIT_FAILURE);
5c9659d3 609 }
efb859b4 610
9f637eea
GM
611 /* See if the socket exists, and if it's owned by us. */
612 sock_status = socket_status (server.sun_path);
152b6e83 613 saved_errno = errno;
5c9659d3 614 if (sock_status && default_sock)
efb859b4 615 {
9f637eea
GM
616 /* Failing that, see if LOGNAME or USER exist and differ from
617 our euid. If so, look for a socket based on the UID
618 associated with the name. This is reminiscent of the logic
619 that init_editfns uses to set the global Vuser_full_name. */
e69233c2 620
9f637eea 621 char *user_name = (char *) getenv ("LOGNAME");
293f9f2a 622
9f637eea
GM
623 if (!user_name)
624 user_name = (char *) getenv ("USER");
e69233c2 625
9f637eea
GM
626 if (user_name)
627 {
628 struct passwd *pw = getpwnam (user_name);
293f9f2a 629
9f637eea
GM
630 if (pw && (pw->pw_uid != geteuid ()))
631 {
632 /* We're running under su, apparently. */
0734b0d0
SM
633 socket_name = alloca (100 + strlen (server_name));
634 sprintf (socket_name, "/tmp/emacs%d/%s",
635 (int) pw->pw_uid, server_name);
5c9659d3
SM
636
637 if (strlen (socket_name) < sizeof (server.sun_path))
638 strcpy (server.sun_path, socket_name);
639 else
640 {
641 fprintf (stderr, "%s: socket-name %s too long",
aa0b6932 642 progname, socket_name);
65396510 643 exit (EXIT_FAILURE);
5c9659d3
SM
644 }
645
9f637eea 646 sock_status = socket_status (server.sun_path);
152b6e83 647 saved_errno = errno;
9f637eea 648 }
293f9f2a
RS
649 else
650 errno = saved_errno;
9f637eea 651 }
efb859b4 652 }
e69233c2 653
aa0b6932
JB
654 switch (sock_status)
655 {
656 case 1:
657 /* There's a socket, but it isn't owned by us. This is OK if
658 we are root. */
659 if (0 != geteuid ())
660 {
e35fc962 661 fprintf (stderr, "%s: Invalid socket owner\n", progname);
aa0b6932
JB
662 return INVALID_SOCKET;
663 }
664 break;
665
666 case 2:
667 /* `stat' failed */
668 if (saved_errno == ENOENT)
669 fprintf (stderr,
670 "%s: can't find socket; have you started the server?\n\
45adde32 671To start the server in Emacs, type \"M-x server-start\".\n",
aa0b6932
JB
672 progname);
673 else
674 fprintf (stderr, "%s: can't stat %s: %s\n",
675 progname, server.sun_path, strerror (saved_errno));
b03d27bd 676 return INVALID_SOCKET;
aa0b6932 677 }
efb859b4 678 }
46cec291 679
4e23f2ba
JB
680 if (connect (s, (struct sockaddr *) &server, strlen (server.sun_path) + 2)
681 < 0)
46cec291 682 {
aa0b6932 683 fprintf (stderr, "%s: ", progname);
46cec291 684 perror ("connect");
aa0b6932 685 return INVALID_SOCKET;
46cec291 686 }
23a7488d 687
aa0b6932
JB
688 return s;
689}
690#endif /* ! NO_SOCKETS_IN_FILE_SYSTEM */
691
692HSOCKET
693set_socket ()
694{
b03d27bd
JB
695 HSOCKET s;
696
697 INITIALIZE ();
698
aa0b6932 699#ifndef NO_SOCKETS_IN_FILE_SYSTEM
b03d27bd
JB
700 /* Explicit --socket-name argument. */
701 if (socket_name)
702 {
703 s = set_local_socket ();
704 if ((s != INVALID_SOCKET) || alternate_editor)
705 return s;
706
707 fprintf (stderr, "%s: error accessing socket \"%s\"",
708 progname, socket_name);
709 exit (EXIT_FAILURE);
710 }
711#endif
712
713 /* Explicit --server-file arg or EMACS_SERVER_FILE variable. */
714 if (!server_file)
715 server_file = getenv ("EMACS_SERVER_FILE");
716
717 if (server_file)
46cec291 718 {
b03d27bd
JB
719 s = set_tcp_socket ();
720 if ((s != INVALID_SOCKET) || alternate_editor)
721 return s;
722
723 fprintf (stderr, "%s: error accessing server file \"%s\"",
724 progname, server_file);
725 exit (EXIT_FAILURE);
46cec291 726 }
b03d27bd
JB
727
728#ifndef NO_SOCKETS_IN_FILE_SYSTEM
729 /* Implicit local socket. */
730 s = set_local_socket ();
731 if (s != INVALID_SOCKET)
732 return s;
733#endif
734
735 /* Implicit server file. */
736 server_file = "server";
737 s = set_tcp_socket ();
738 if ((s != INVALID_SOCKET) || alternate_editor)
739 return s;
740
741 /* No implicit or explicit socket, and no alternate editor. */
742 fprintf (stderr, "%s: No socket or alternate editor. Please use:\n\n"
743#ifndef NO_SOCKETS_IN_FILE_SYSTEM
744"\t--socket-name\n"
aa0b6932 745#endif
b03d27bd
JB
746"\t--server-file (or environment variable EMACS_SERVER_FILE)\n\
747\t--alternate-editor (or environment variable ALTERNATE_EDITOR)\n",
748 progname);
749 exit (EXIT_FAILURE);
aa0b6932 750}
46cec291 751
aa0b6932
JB
752int
753main (argc, argv)
754 int argc;
755 char **argv;
756{
757 HSOCKET s;
758 int i, rl, needlf = 0;
759 char *cwd;
760 char string[BUFSIZ+1];
761
762 progname = argv[0];
763
764 /* Process options. */
765 decode_options (argc, argv);
766
767 if ((argc - optind < 1) && !eval)
23a7488d 768 {
aa0b6932
JB
769 fprintf (stderr, "%s: file name or argument required\n", progname);
770 fprintf (stderr, "Try `%s --help' for more information\n", progname);
771 exit (EXIT_FAILURE);
23a7488d
RS
772 }
773
aa0b6932
JB
774 if ((s = set_socket ()) == INVALID_SOCKET)
775 fail (argc, argv);
776
38732dba 777#ifdef HAVE_GETCWD
ee6a193c 778 cwd = getcwd (string, sizeof string);
38732dba
RS
779#else
780 cwd = getwd (string);
ee6a193c 781#endif
46cec291
RS
782 if (cwd == 0)
783 {
784 /* getwd puts message in STRING if it fails. */
38732dba 785#ifdef HAVE_GETCWD
aa0b6932 786 fprintf (stderr, "%s: %s (%s)\n", progname,
bb5618fe 787 "Cannot get current working directory", strerror (errno));
38732dba 788#else
aa0b6932 789 fprintf (stderr, "%s: %s (%s)\n", progname, string, strerror (errno));
bd252662 790#endif
97e3214d 791 fail (argc, argv);
46cec291
RS
792 }
793
5212210c 794 if (nowait)
aa0b6932 795 SEND_STRING ("-nowait ");
292d74a3 796
30be2360 797 if (eval)
aa0b6932 798 SEND_STRING ("-eval ");
30be2360
SM
799
800 if (display)
87209357 801 {
aa0b6932
JB
802 SEND_STRING ("-display ");
803 SEND_QUOTED (display);
804 SEND_STRING (" ");
87209357 805 }
30be2360 806
87209357 807 if ((argc - optind > 0))
5212210c 808 {
87209357 809 for (i = optind; i < argc; i++)
46cec291 810 {
87209357
EZ
811 if (eval)
812 ; /* Don't prepend any cwd or anything like that. */
813 else if (*argv[i] == '+')
814 {
815 char *p = argv[i] + 1;
816 while (isdigit ((unsigned char) *p) || *p == ':') p++;
817 if (*p != 0)
818 {
aa0b6932
JB
819 SEND_QUOTED (cwd);
820 SEND_STRING ("/");
87209357
EZ
821 }
822 }
b03d27bd 823 else if (! file_name_absolute_p (argv[i]))
87209357 824 {
aa0b6932
JB
825 SEND_QUOTED (cwd);
826 SEND_STRING ("/");
87209357
EZ
827 }
828
aa0b6932
JB
829 SEND_QUOTED (argv[i]);
830 SEND_STRING (" ");
46cec291 831 }
46cec291 832 }
87209357
EZ
833 else
834 {
aa0b6932 835 while (fgets (string, BUFSIZ, stdin))
87209357 836 {
aa0b6932 837 SEND_QUOTED (string);
87209357 838 }
aa0b6932 839 SEND_STRING (" ");
87209357 840 }
65396510 841
aa0b6932 842 SEND_STRING ("\n");
46cec291 843
292d74a3 844 /* Maybe wait for an answer. */
aa0b6932 845 if (!nowait)
30be2360 846 {
aa0b6932
JB
847 if (!eval)
848 {
849 printf ("Waiting for Emacs...");
850 needlf = 2;
851 }
852 fflush (stdout);
853
854 /* Now, wait for an answer and print any messages. */
855 while ((rl = recv (s, string, BUFSIZ, 0)) > 0)
856 {
857 string[rl] = '\0';
858 if (needlf == 2)
859 printf ("\n");
860 printf ("%s", string);
861 needlf = string[0] == '\0' ? needlf : string[strlen (string) - 1] != '\n';
862 }
863
864 if (needlf)
865 printf ("\n");
866 fflush (stdout);
30be2360 867 }
23a7488d 868
aa0b6932 869 CLOSE_SOCKET (s);
65396510 870 return EXIT_SUCCESS;
46cec291
RS
871}
872
1e7823d0 873#endif /* HAVE_SOCKETS && HAVE_INET_SOCKETS */
aa0b6932 874
27711600
RM
875#ifndef HAVE_STRERROR
876char *
877strerror (errnum)
878 int errnum;
879{
880 extern char *sys_errlist[];
881 extern int sys_nerr;
882
883 if (errnum >= 0 && errnum < sys_nerr)
884 return sys_errlist[errnum];
885 return (char *) "Unknown error";
886}
887
888#endif /* ! HAVE_STRERROR */
ab5796a9
MB
889
890/* arch-tag: f39bb9c4-73eb-477e-896d-50832e2ca9a7
891 (do not change this comment) */
65396510
TTN
892
893/* emacsclient.c ends here */