*** empty log message ***
[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. */
118const char * alternate_editor = NULL;
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' },
254107e4 135 { "socket-name", required_argument, NULL, 's' },
aa0b6932 136 { "server-file", required_argument, NULL, 'f' },
30be2360
SM
137 { "display", required_argument, NULL, 'd' },
138 { 0, 0, 0, 0 }
8f9aaa0a
RS
139};
140
141/* Decode the options from argv and argc.
5212210c 142 The global variable `optind' will say how many arguments we used up. */
8f9aaa0a 143
5212210c 144void
8f9aaa0a
RS
145decode_options (argc, argv)
146 int argc;
147 char **argv;
148{
b6b6d6d2 149 alternate_editor = getenv ("ALTERNATE_EDITOR");
aa0b6932 150 server_file = getenv ("EMACS_SERVER_FILE");
b6b6d6d2 151
8f9aaa0a
RS
152 while (1)
153 {
154 int opt = getopt_long (argc, argv,
aa0b6932 155 "VHnea:s:f:d:", longopts, 0);
8f9aaa0a
RS
156
157 if (opt == EOF)
158 break;
159
160 switch (opt)
161 {
162 case 0:
163 /* If getopt returns 0, then it has already processed a
164 long-named option. We should do nothing. */
165 break;
e69233c2 166
97e3214d
GM
167 case 'a':
168 alternate_editor = optarg;
169 break;
e69233c2 170
254107e4
RS
171 case 's':
172 socket_name = optarg;
173 break;
174
aa0b6932
JB
175 case 'f':
176 server_file = optarg;
177 break;
178
30be2360
SM
179 case 'd':
180 display = optarg;
181 break;
182
8f9aaa0a
RS
183 case 'n':
184 nowait = 1;
185 break;
186
30be2360
SM
187 case 'e':
188 eval = 1;
189 break;
190
8f9aaa0a 191 case 'V':
20c396e8 192 printf ("emacsclient %s\n", VERSION);
65396510 193 exit (EXIT_SUCCESS);
8f9aaa0a 194 break;
46cec291 195
8f9aaa0a 196 case 'H':
8f9aaa0a 197 print_help_and_exit ();
20c396e8
JB
198 break;
199
200 default:
201 fprintf (stderr, "Try `%s --help' for more information\n", progname);
65396510 202 exit (EXIT_FAILURE);
20c396e8 203 break;
8f9aaa0a
RS
204 }
205 }
8f9aaa0a
RS
206}
207
7f3bff3e 208void
8f9aaa0a
RS
209print_help_and_exit ()
210{
20c396e8
JB
211 printf (
212 "Usage: %s [OPTIONS] FILE...\n\
30be2360
SM
213Tell the Emacs server to visit the specified files.\n\
214Every FILE can be either just a FILENAME or [+LINE[:COLUMN]] FILENAME.\n\
20c396e8 215\n\
30be2360
SM
216The following OPTIONS are accepted:\n\
217-V, --version Just print a version info and return\n\
218-H, --help Print this usage information message\n\
219-n, --no-wait Don't wait for the server to return\n\
220-e, --eval Evaluate the FILE arguments as ELisp expressions\n\
aa0b6932
JB
221-d, --display=DISPLAY Visit the file in the given display\n"
222#ifndef NO_SOCKETS_IN_FILE_SYSTEM
223"-s, --socket-name=FILENAME\n\
224 Set the filename of the UNIX socket for communication\n"
225#endif
226"-f, --server-file=FILENAME\n\
227 Set the filename of the TCP configuration file\n\
30be2360
SM
228-a, --alternate-editor=EDITOR\n\
229 Editor to fallback to if the server is not running\n\
20c396e8 230\n\
30be2360 231Report bugs to bug-gnu-emacs@gnu.org.\n", progname);
65396510 232 exit (EXIT_SUCCESS);
8f9aaa0a 233}
5212210c 234
aa0b6932
JB
235\f
236/*
237 Try to run a different command, or --if no alternate editor is
238 defined-- exit with an errorcode.
239*/
240void
241fail (argc, argv)
242 int argc;
243 char **argv;
244{
245 if (alternate_editor)
246 {
247 int i = optind - 1;
b73ea44b
JB
248#ifdef WINDOWSNT
249 argv[i] = (char *)alternate_editor;
250#endif
aa0b6932
JB
251 execvp (alternate_editor, argv + i);
252 fprintf (stderr, "%s: error executing alternate editor \"%s\"\n",
253 progname, alternate_editor);
254 }
255 else
256 {
257 fprintf (stderr, "%s: No socket or alternate editor. Please use:\n\n"
258#if !defined (NO_SOCKETS_IN_FILE_SYSTEM)
259"\t--socket-name\n"
260#endif
261"\t--server-file (or environment variable EMACS_SERVER_FILE)\n\
262\t--alternate-editor (or environment variable ALTERNATE_EDITOR)\n",
263 progname);
264 }
265 exit (EXIT_FAILURE);
266}
267
268\f
1e7823d0 269#if !defined (HAVE_SOCKETS) || !defined (HAVE_INET_SOCKETS)
aa0b6932
JB
270
271int
272main (argc, argv)
273 int argc;
274 char **argv;
275{
276 fprintf (stderr, "%s: Sorry, the Emacs server is supported only\n",
277 argv[0]);
278 fprintf (stderr, "on systems with Berkeley sockets.\n");
279
280 fail (argc, argv);
281}
282
1e7823d0 283#else /* HAVE_SOCKETS && HAVE_INET_SOCKETS */
aa0b6932
JB
284
285#ifdef WINDOWSNT
286# include <winsock2.h>
287#else
288# include <sys/types.h>
289# include <sys/socket.h>
290# include <sys/un.h>
291# include <sys/stat.h>
292# include <errno.h>
293#endif
294
295#define AUTH_KEY_LENGTH 64
296#define SEND_BUFFER_SIZE 4096
297
298extern char *strerror ();
299extern int errno;
300
301/* Buffer to accumulate data to send in TCP connections. */
302char send_buffer[SEND_BUFFER_SIZE + 1];
303int sblen = 0; /* Fill pointer for the send buffer. */
304
305/* Let's send the data to Emacs when either
306 - the data ends in "\n", or
307 - the buffer is full (but this shouldn't happen)
308 Otherwise, we just accumulate it. */
309void send_to_emacs (s, data)
310 HSOCKET s;
311 char *data;
312{
313 while (data)
314 {
315 int dlen = strlen (data);
316 if (dlen + sblen >= SEND_BUFFER_SIZE)
317 {
318 int part = SEND_BUFFER_SIZE - sblen;
319 strncpy (&send_buffer[sblen], data, part);
320 data += part;
321 sblen = SEND_BUFFER_SIZE;
322 }
323 else if (dlen)
324 {
325 strcpy (&send_buffer[sblen], data);
326 data = NULL;
327 sblen += dlen;
328 }
329 else
330 break;
331
332 if (sblen == SEND_BUFFER_SIZE
333 || (sblen > 0 && send_buffer[sblen-1] == '\n'))
334 {
335 int sent = send (s, send_buffer, sblen, 0);
336 if (sent != sblen)
337 strcpy (send_buffer, &send_buffer[sent]);
338 sblen -= sent;
339 }
340 }
341}
342
a4cf2096
RS
343/* In NAME, insert a & before each &, each space, each newline, and
344 any initial -. Change spaces to underscores, too, so that the
5212210c 345 return value never contains a space. */
87209357 346void
aa0b6932
JB
347quote_file_name (s, name)
348 HSOCKET s;
5212210c
RS
349 char *name;
350{
351 char *copy = (char *) malloc (strlen (name) * 2 + 1);
352 char *p, *q;
353
354 p = name;
355 q = copy;
356 while (*p)
357 {
358 if (*p == ' ')
359 {
f1db6a73 360 *q++ = '&';
5212210c
RS
361 *q++ = '_';
362 p++;
363 }
3cf8c6aa
SM
364 else if (*p == '\n')
365 {
366 *q++ = '&';
367 *q++ = 'n';
368 p++;
369 }
5212210c
RS
370 else
371 {
f1db6a73
RS
372 if (*p == '&' || (*p == '-' && p == name))
373 *q++ = '&';
5212210c
RS
374 *q++ = *p++;
375 }
376 }
f1db6a73 377 *q++ = 0;
5212210c 378
aa0b6932 379 SEND_STRING (copy);
87209357
EZ
380
381 free (copy);
5212210c 382}
0c76956f 383
aa0b6932
JB
384#ifdef WINDOWSNT
385/* Wrapper to make WSACleanup a cdecl, as required by atexit(). */
411b80a5 386void __cdecl close_winsock ()
aa0b6932
JB
387{
388 WSACleanup ();
389}
0c76956f 390
aa0b6932 391void initialize_sockets ()
0c76956f 392{
5796dab7 393 static done = FALSE;
aa0b6932
JB
394 WSADATA wsaData;
395
5796dab7
JB
396 if (done) return;
397
aa0b6932
JB
398 /* Initialize the WinSock2 library. */
399 if (WSAStartup (MAKEWORD (2, 0), &wsaData))
400 {
401 fprintf (stderr, "%s: error initializing WinSock2", progname);
402 exit (EXIT_FAILURE);
403 }
404
405 atexit (close_winsock);
5796dab7 406 done = TRUE;
0c76956f 407}
e35fc962 408#endif /* WINDOWSNT */
8f9aaa0a 409\f
97e3214d 410/*
aa0b6932
JB
411 * Read the information needed to set up a TCP comm channel with
412 * the Emacs server: host, port and authentication string.
97e3214d 413*/
aa0b6932
JB
414int get_server_config (server, authentication)
415 struct sockaddr_in *server;
416 char *authentication;
97e3214d 417{
aa0b6932
JB
418 FILE *config;
419 char dotted[32];
420 char *port;
421
422 if (! (config = fopen (server_file, "rb")))
97e3214d 423 {
aa0b6932
JB
424 char *home = getenv ("HOME");
425#ifdef WINDOWSNT
426 if (! home)
427 home = getenv ("APPDATA");
428#endif
429 if (home)
430 {
431 char *path = alloca (32 + strlen (home) + strlen (server_file));
432 sprintf (path, "%s/.emacs.d/server/%s", home, server_file);
433 config = fopen (path, "rb");
434 }
435 }
436
437 if (! config)
438 return FALSE;
439
440 if (fgets (dotted, sizeof dotted, config)
441 && (port = strchr (dotted, ':')))
442 {
443 *port++ = '\0';
97e3214d
GM
444 }
445 else
446 {
aa0b6932 447 fprintf (stderr, "%s: invalid configuration info", progname);
65396510 448 exit (EXIT_FAILURE);
97e3214d 449 }
97e3214d 450
aa0b6932
JB
451 server->sin_family = AF_INET;
452 server->sin_addr.s_addr = inet_addr (dotted);
453 server->sin_port = htons (atoi (port));
97e3214d 454
aa0b6932
JB
455 if (! fread (authentication, AUTH_KEY_LENGTH, 1, config))
456 {
457 fprintf (stderr, "%s: cannot read authentication info", progname);
458 exit (EXIT_FAILURE);
459 }
46cec291 460
aa0b6932 461 fclose (config);
97e3214d 462
aa0b6932 463 return TRUE;
46cec291
RS
464}
465
aa0b6932
JB
466HSOCKET
467set_tcp_socket ()
468{
469 HSOCKET s;
470 struct sockaddr_in server;
aa0b6932
JB
471 struct linger l_arg = {1, 1};
472 char auth_string[AUTH_KEY_LENGTH + 1];
46cec291 473
aa0b6932 474 INITIALIZE ();
46cec291 475
aa0b6932
JB
476 if (! get_server_config (&server, auth_string))
477 return INVALID_SOCKET;
478
479 /*
480 * Open up an AF_INET socket
481 */
482 if ((s = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
483 {
484 fprintf (stderr, "%s: ", progname);
485 perror ("socket");
486 return INVALID_SOCKET;
487 }
488
489 /*
490 * Set up the socket
491 */
492 if (connect (s, (struct sockaddr *) &server, sizeof server) < 0)
493 {
494 fprintf (stderr, "%s: ", progname);
495 perror ("connect");
496 return INVALID_SOCKET;
497 }
498
aa0b6932
JB
499 setsockopt (s, SOL_SOCKET, SO_LINGER, (char *) &l_arg, sizeof l_arg);
500
501 /*
502 * Send the authentication
503 */
504 auth_string[AUTH_KEY_LENGTH] = '\0';
505
506 SEND_STRING ("-auth ");
507 SEND_STRING (auth_string);
508 SEND_STRING ("\n");
509
510 return s;
511}
512
513#if !defined (NO_SOCKETS_IN_FILE_SYSTEM)
46cec291 514
9f637eea
GM
515/* Three possibilities:
516 2 - can't be `stat'ed (sets errno)
517 1 - isn't owned by us
518 0 - success: none of the above */
519
520static int
521socket_status (socket_name)
522 char *socket_name;
523{
524 struct stat statbfr;
525
526 if (stat (socket_name, &statbfr) == -1)
527 return 2;
528
529 if (statbfr.st_uid != geteuid ())
530 return 1;
531
532 return 0;
533}
534
aa0b6932
JB
535HSOCKET
536set_local_socket ()
46cec291 537{
aa0b6932 538 HSOCKET s;
46cec291 539 struct sockaddr_un server;
46cec291 540
e69233c2 541 /*
46cec291
RS
542 * Open up an AF_UNIX socket in this person's home directory
543 */
544
545 if ((s = socket (AF_UNIX, SOCK_STREAM, 0)) < 0)
546 {
aa0b6932 547 fprintf (stderr, "%s: ", progname);
46cec291 548 perror ("socket");
aa0b6932 549 return INVALID_SOCKET;
46cec291 550 }
e69233c2 551
46cec291 552 server.sun_family = AF_UNIX;
c5fee545 553
c5fee545 554 {
9f637eea 555 int sock_status = 0;
5c9659d3 556 int default_sock = !socket_name;
152b6e83 557 int saved_errno;
0734b0d0
SM
558 char *server_name = "server";
559
560 if (socket_name && !index (socket_name, '/') && !index (socket_name, '\\'))
561 { /* socket_name is a file name component. */
562 server_name = socket_name;
563 socket_name = NULL;
564 default_sock = 1; /* Try both UIDs. */
565 }
efb859b4 566
5c9659d3 567 if (default_sock)
254107e4 568 {
0734b0d0
SM
569 socket_name = alloca (100 + strlen (server_name));
570 sprintf (socket_name, "/tmp/emacs%d/%s",
571 (int) geteuid (), server_name);
254107e4
RS
572 }
573
574 if (strlen (socket_name) < sizeof (server.sun_path))
575 strcpy (server.sun_path, socket_name);
576 else
5c9659d3
SM
577 {
578 fprintf (stderr, "%s: socket-name %s too long",
aa0b6932 579 progname, socket_name);
65396510 580 exit (EXIT_FAILURE);
5c9659d3 581 }
efb859b4 582
9f637eea
GM
583 /* See if the socket exists, and if it's owned by us. */
584 sock_status = socket_status (server.sun_path);
152b6e83 585 saved_errno = errno;
5c9659d3 586 if (sock_status && default_sock)
efb859b4 587 {
9f637eea
GM
588 /* Failing that, see if LOGNAME or USER exist and differ from
589 our euid. If so, look for a socket based on the UID
590 associated with the name. This is reminiscent of the logic
591 that init_editfns uses to set the global Vuser_full_name. */
e69233c2 592
9f637eea 593 char *user_name = (char *) getenv ("LOGNAME");
293f9f2a 594
9f637eea
GM
595 if (!user_name)
596 user_name = (char *) getenv ("USER");
e69233c2 597
9f637eea
GM
598 if (user_name)
599 {
600 struct passwd *pw = getpwnam (user_name);
293f9f2a 601
9f637eea
GM
602 if (pw && (pw->pw_uid != geteuid ()))
603 {
604 /* We're running under su, apparently. */
0734b0d0
SM
605 socket_name = alloca (100 + strlen (server_name));
606 sprintf (socket_name, "/tmp/emacs%d/%s",
607 (int) pw->pw_uid, server_name);
5c9659d3
SM
608
609 if (strlen (socket_name) < sizeof (server.sun_path))
610 strcpy (server.sun_path, socket_name);
611 else
612 {
613 fprintf (stderr, "%s: socket-name %s too long",
aa0b6932 614 progname, socket_name);
65396510 615 exit (EXIT_FAILURE);
5c9659d3
SM
616 }
617
9f637eea 618 sock_status = socket_status (server.sun_path);
152b6e83 619 saved_errno = errno;
9f637eea 620 }
293f9f2a
RS
621 else
622 errno = saved_errno;
9f637eea 623 }
efb859b4 624 }
e69233c2 625
aa0b6932
JB
626 switch (sock_status)
627 {
628 case 1:
629 /* There's a socket, but it isn't owned by us. This is OK if
630 we are root. */
631 if (0 != geteuid ())
632 {
e35fc962 633 fprintf (stderr, "%s: Invalid socket owner\n", progname);
aa0b6932
JB
634 return INVALID_SOCKET;
635 }
636 break;
637
638 case 2:
639 /* `stat' failed */
640 if (saved_errno == ENOENT)
641 fprintf (stderr,
642 "%s: can't find socket; have you started the server?\n\
45adde32 643To start the server in Emacs, type \"M-x server-start\".\n",
aa0b6932
JB
644 progname);
645 else
646 fprintf (stderr, "%s: can't stat %s: %s\n",
647 progname, server.sun_path, strerror (saved_errno));
648 return INVALID_SOCKET;
649 }
efb859b4 650 }
46cec291 651
4e23f2ba
JB
652 if (connect (s, (struct sockaddr *) &server, strlen (server.sun_path) + 2)
653 < 0)
46cec291 654 {
aa0b6932 655 fprintf (stderr, "%s: ", progname);
46cec291 656 perror ("connect");
aa0b6932 657 return INVALID_SOCKET;
46cec291 658 }
23a7488d 659
aa0b6932
JB
660 return s;
661}
662#endif /* ! NO_SOCKETS_IN_FILE_SYSTEM */
663
664HSOCKET
665set_socket ()
666{
667 if (server_file)
668 return set_tcp_socket ();
669 else
670#ifndef NO_SOCKETS_IN_FILE_SYSTEM
671 return set_local_socket ();
672#else
46cec291 673 {
aa0b6932
JB
674 server_file = "server";
675 return set_tcp_socket ();
46cec291 676 }
aa0b6932
JB
677#endif
678}
46cec291 679
aa0b6932
JB
680int
681main (argc, argv)
682 int argc;
683 char **argv;
684{
685 HSOCKET s;
686 int i, rl, needlf = 0;
687 char *cwd;
688 char string[BUFSIZ+1];
689
690 progname = argv[0];
691
692 /* Process options. */
693 decode_options (argc, argv);
694
695 if ((argc - optind < 1) && !eval)
23a7488d 696 {
aa0b6932
JB
697 fprintf (stderr, "%s: file name or argument required\n", progname);
698 fprintf (stderr, "Try `%s --help' for more information\n", progname);
699 exit (EXIT_FAILURE);
23a7488d
RS
700 }
701
aa0b6932
JB
702 if ((s = set_socket ()) == INVALID_SOCKET)
703 fail (argc, argv);
704
38732dba 705#ifdef HAVE_GETCWD
ee6a193c 706 cwd = getcwd (string, sizeof string);
38732dba
RS
707#else
708 cwd = getwd (string);
ee6a193c 709#endif
46cec291
RS
710 if (cwd == 0)
711 {
712 /* getwd puts message in STRING if it fails. */
38732dba 713#ifdef HAVE_GETCWD
aa0b6932 714 fprintf (stderr, "%s: %s (%s)\n", progname,
bb5618fe 715 "Cannot get current working directory", strerror (errno));
38732dba 716#else
aa0b6932 717 fprintf (stderr, "%s: %s (%s)\n", progname, string, strerror (errno));
bd252662 718#endif
97e3214d 719 fail (argc, argv);
46cec291
RS
720 }
721
5212210c 722 if (nowait)
aa0b6932 723 SEND_STRING ("-nowait ");
292d74a3 724
30be2360 725 if (eval)
aa0b6932 726 SEND_STRING ("-eval ");
30be2360
SM
727
728 if (display)
87209357 729 {
aa0b6932
JB
730 SEND_STRING ("-display ");
731 SEND_QUOTED (display);
732 SEND_STRING (" ");
87209357 733 }
30be2360 734
87209357 735 if ((argc - optind > 0))
5212210c 736 {
87209357 737 for (i = optind; i < argc; i++)
46cec291 738 {
87209357
EZ
739 if (eval)
740 ; /* Don't prepend any cwd or anything like that. */
741 else if (*argv[i] == '+')
742 {
743 char *p = argv[i] + 1;
744 while (isdigit ((unsigned char) *p) || *p == ':') p++;
745 if (*p != 0)
746 {
aa0b6932
JB
747 SEND_QUOTED (cwd);
748 SEND_STRING ("/");
87209357
EZ
749 }
750 }
aa0b6932 751#ifndef WINDOWSNT
87209357 752 else if (*argv[i] != '/')
aa0b6932
JB
753#else
754 else if ((*argv[i] != '/')
755 /* Absolute paths can also start with backslash
756 or drive letters. */
757 && (*argv[i] != '\\')
758 && (!islower (tolower (*argv[i]))
759 || (argv[i][1] != ':')))
760#endif
87209357 761 {
aa0b6932
JB
762 SEND_QUOTED (cwd);
763 SEND_STRING ("/");
87209357
EZ
764 }
765
aa0b6932
JB
766 SEND_QUOTED (argv[i]);
767 SEND_STRING (" ");
46cec291 768 }
46cec291 769 }
87209357
EZ
770 else
771 {
aa0b6932 772 while (fgets (string, BUFSIZ, stdin))
87209357 773 {
aa0b6932 774 SEND_QUOTED (string);
87209357 775 }
aa0b6932 776 SEND_STRING (" ");
87209357 777 }
65396510 778
aa0b6932 779 SEND_STRING ("\n");
46cec291 780
292d74a3 781 /* Maybe wait for an answer. */
aa0b6932 782 if (!nowait)
30be2360 783 {
aa0b6932
JB
784 if (!eval)
785 {
786 printf ("Waiting for Emacs...");
787 needlf = 2;
788 }
789 fflush (stdout);
790
791 /* Now, wait for an answer and print any messages. */
792 while ((rl = recv (s, string, BUFSIZ, 0)) > 0)
793 {
794 string[rl] = '\0';
795 if (needlf == 2)
796 printf ("\n");
797 printf ("%s", string);
798 needlf = string[0] == '\0' ? needlf : string[strlen (string) - 1] != '\n';
799 }
800
801 if (needlf)
802 printf ("\n");
803 fflush (stdout);
30be2360 804 }
23a7488d 805
aa0b6932 806 CLOSE_SOCKET (s);
65396510 807 return EXIT_SUCCESS;
46cec291
RS
808}
809
1e7823d0 810#endif /* HAVE_SOCKETS && HAVE_INET_SOCKETS */
aa0b6932 811
27711600
RM
812#ifndef HAVE_STRERROR
813char *
814strerror (errnum)
815 int errnum;
816{
817 extern char *sys_errlist[];
818 extern int sys_nerr;
819
820 if (errnum >= 0 && errnum < sys_nerr)
821 return sys_errlist[errnum];
822 return (char *) "Unknown error";
823}
824
825#endif /* ! HAVE_STRERROR */
ab5796a9
MB
826
827/* arch-tag: f39bb9c4-73eb-477e-896d-50832e2ca9a7
828 (do not change this comment) */
65396510
TTN
829
830/* emacsclient.c ends here */