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