(emacs_socket): Rename from s.
[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,
4e6835db 3 2005, 2006, 2007 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
bc28de71
JB
31/* config.h defines these, which disables sockets altogether! */
32# undef _WINSOCKAPI_
33# undef _WINSOCK_H
34
411b80a5
JB
35# include <malloc.h>
36# include <stdlib.h>
42073bfb 37# include <windows.h>
411b80a5 38
411b80a5
JB
39# define NO_SOCKETS_IN_FILE_SYSTEM
40
aa0b6932
JB
41# define HSOCKET SOCKET
42# define CLOSE_SOCKET closesocket
aa0b6932 43# define INITIALIZE() (initialize_sockets ())
411b80a5
JB
44
45#else /* !WINDOWSNT */
46
ed4a3730
JB
47# include <sys/types.h>
48
1e7823d0
JB
49# ifdef HAVE_INET_SOCKETS
50# include <netinet/in.h>
51# endif
411b80a5 52
e35fc962 53# define INVALID_SOCKET -1
aa0b6932
JB
54# define HSOCKET int
55# define CLOSE_SOCKET close
aa0b6932 56# define INITIALIZE()
411b80a5
JB
57
58#endif /* !WINDOWSNT */
aa0b6932 59
4e23f2ba 60#undef signal
46cec291 61
42073bfb 62#include <stdarg.h>
e69233c2 63#include <ctype.h>
8f9aaa0a 64#include <stdio.h>
aa0b6932 65#include "getopt.h"
79f13bba
DL
66#ifdef HAVE_UNISTD_H
67#include <unistd.h>
68#endif
8f9aaa0a 69
9f637eea
GM
70#ifdef VMS
71# include "vms-pwd.h"
aa0b6932
JB
72#else /* not VMS */
73#ifdef WINDOWSNT
74# include <io.h>
75#else /* not WINDOWSNT */
9f637eea 76# include <pwd.h>
aa0b6932 77#endif /* not WINDOWSNT */
9f637eea 78#endif /* not VMS */
dc4a4a14 79#include <sys/stat.h>
9f637eea 80
9628b887 81#include <signal.h>
4d553a13 82#include <errno.h>
9628b887 83
6bcc8ec7
KL
84/* From lisp.h */
85#ifndef DIRECTORY_SEP
86#define DIRECTORY_SEP '/'
87#endif
88#ifndef IS_DIRECTORY_SEP
89#define IS_DIRECTORY_SEP(_c_) ((_c_) == DIRECTORY_SEP)
90#endif
91#ifndef IS_DEVICE_SEP
92#ifndef DEVICE_SEP
93#define IS_DEVICE_SEP(_c_) 0
94#else
95#define IS_DEVICE_SEP(_c_) ((_c_) == DEVICE_SEP)
96#endif
97#endif
98#ifndef IS_ANY_SEP
99#define IS_ANY_SEP(_c_) (IS_DIRECTORY_SEP (_c_))
100#endif
101
102
9628b887 103\f
8f9aaa0a 104char *getenv (), *getwd ();
5b9562c3 105char *(getcwd) ();
8f9aaa0a 106
8f9aaa0a
RS
107#ifndef VERSION
108#define VERSION "unspecified"
109#endif
110\f
4b7b77f6
JR
111#define SEND_STRING(data) (send_to_emacs (emacs_socket, (data)))
112#define SEND_QUOTED(data) (quote_argument (emacs_socket, (data)))
aa0b6932
JB
113
114#ifndef EXIT_SUCCESS
115#define EXIT_SUCCESS 0
116#endif
117
118#ifndef EXIT_FAILURE
119#define EXIT_FAILURE 1
120#endif
121
122#ifndef FALSE
123#define FALSE 0
124#endif
125
126#ifndef TRUE
127#define TRUE 1
128#endif
129
130#ifndef NO_RETURN
131#define NO_RETURN
132#endif
133\f
8f9aaa0a
RS
134/* Name used to invoke this program. */
135char *progname;
136
0a125897
KL
137/* The first argument to main. */
138int main_argc;
139
140/* The second argument to main. */
141char **main_argv;
142
749ae770 143/* Nonzero means don't wait for a response from Emacs. --no-wait. */
8f9aaa0a
RS
144int nowait = 0;
145
30be2360
SM
146/* Nonzero means args are expressions to be evaluated. --eval. */
147int eval = 0;
148
92071250
KL
149/* Nonzero means don't open a new frame. --current-frame. */
150int current_frame = 0;
151
77134727
KL
152/* Nonzero means open a new graphical frame. */
153int window_system = 0;
154
30be2360
SM
155/* The display on which Emacs should work. --display. */
156char *display = NULL;
157
9628b887 158/* Nonzero means open a new Emacs frame on the current terminal. */
77134727 159int tty = 0;
9628b887 160
30be2360
SM
161/* If non-NULL, the name of an editor to fallback to if the server
162 is not running. --alternate-editor. */
b03d27bd 163const char *alternate_editor = NULL;
30be2360 164
3db926be 165/* If non-NULL, the filename of the UNIX socket. */
254107e4
RS
166char *socket_name = NULL;
167
aa0b6932
JB
168/* If non-NULL, the filename of the authentication file. */
169char *server_file = NULL;
170
c66648e0
JB
171/* PID of the Emacs server process. */
172int emacs_pid = 0;
173
2381d38d 174void print_help_and_exit () NO_RETURN;
7f3bff3e 175
8f9aaa0a
RS
176struct option longopts[] =
177{
749ae770 178 { "no-wait", no_argument, NULL, 'n' },
30be2360 179 { "eval", no_argument, NULL, 'e' },
8f9aaa0a
RS
180 { "help", no_argument, NULL, 'H' },
181 { "version", no_argument, NULL, 'V' },
b28c910d 182 { "tty", no_argument, NULL, 't' },
e5299d8d 183 { "current-frame", no_argument, NULL, 'c' },
3cf8c6aa 184 { "alternate-editor", required_argument, NULL, 'a' },
b03d27bd 185#ifndef NO_SOCKETS_IN_FILE_SYSTEM
254107e4 186 { "socket-name", required_argument, NULL, 's' },
b03d27bd 187#endif
aa0b6932 188 { "server-file", required_argument, NULL, 'f' },
30be2360
SM
189 { "display", required_argument, NULL, 'd' },
190 { 0, 0, 0, 0 }
8f9aaa0a
RS
191};
192
974b73e8
KL
193\f
194/* Like malloc but get fatal error if memory is exhausted. */
195
196long *
197xmalloc (size)
198 unsigned int size;
199{
200 long *result = (long *) malloc (size);
201 if (result == NULL)
202 {
203 perror ("malloc");
204 exit (EXIT_FAILURE);
205 }
206 return result;
207}
208
209/* Like strdup but get a fatal error if memory is exhausted. */
210
211char *
212xstrdup (const char *s)
213{
214 char *result = strdup (s);
215 if (result == NULL)
216 {
217 perror ("strdup");
218 exit (EXIT_FAILURE);
219 }
220 return result;
221}
222
223/* From sysdep.c */
224#if !defined (HAVE_GET_CURRENT_DIR_NAME) || defined (BROKEN_GET_CURRENT_DIR_NAME)
225
226/* Return the current working directory. Returns NULL on errors.
227 Any other returned value must be freed with free. This is used
228 only when get_current_dir_name is not defined on the system. */
229char*
230get_current_dir_name ()
231{
232 char *buf;
233 char *pwd;
234 struct stat dotstat, pwdstat;
235 /* If PWD is accurate, use it instead of calling getwd. PWD is
236 sometimes a nicer name, and using it may avoid a fatal error if a
237 parent directory is searchable but not readable. */
238 if ((pwd = getenv ("PWD")) != 0
239 && (IS_DIRECTORY_SEP (*pwd) || (*pwd && IS_DEVICE_SEP (pwd[1])))
240 && stat (pwd, &pwdstat) == 0
241 && stat (".", &dotstat) == 0
242 && dotstat.st_ino == pwdstat.st_ino
243 && dotstat.st_dev == pwdstat.st_dev
244#ifdef MAXPATHLEN
245 && strlen (pwd) < MAXPATHLEN
246#endif
247 )
248 {
249 buf = (char *) xmalloc (strlen (pwd) + 1);
250 if (!buf)
251 return NULL;
252 strcpy (buf, pwd);
253 }
254#ifdef HAVE_GETCWD
255 else
256 {
257 size_t buf_size = 1024;
258 buf = (char *) xmalloc (buf_size);
259 if (!buf)
260 return NULL;
261 for (;;)
262 {
263 if (getcwd (buf, buf_size) == buf)
264 break;
265 if (errno != ERANGE)
266 {
267 int tmp_errno = errno;
268 free (buf);
269 errno = tmp_errno;
270 return NULL;
271 }
272 buf_size *= 2;
273 buf = (char *) realloc (buf, buf_size);
274 if (!buf)
275 return NULL;
276 }
277 }
278#else
279 else
280 {
281 /* We need MAXPATHLEN here. */
282 buf = (char *) xmalloc (MAXPATHLEN + 1);
283 if (!buf)
284 return NULL;
285 if (getwd (buf) == NULL)
286 {
287 int tmp_errno = errno;
288 free (buf);
289 errno = tmp_errno;
290 return NULL;
291 }
292 }
293#endif
294 return buf;
295}
296#endif
297
42073bfb
JB
298/* Message functions. */
299
300#ifdef WINDOWSNT
42073bfb 301int
f0384499 302w32_window_app ()
42073bfb
JB
303{
304 static int window_app = -1;
305 char szTitle[MAX_PATH];
306
307 if (window_app < 0)
0d3d6719
JB
308 /* Checking for STDOUT does not work; it's a valid handle also in
309 nonconsole apps. Testing for the console title seems to work. */
42073bfb
JB
310 window_app = (GetConsoleTitleA (szTitle, MAX_PATH) == 0);
311
312 return window_app;
313}
105faa84
DN
314
315/*
316 execvp wrapper for Windows. Quotes arguments with embedded spaces.
317
318 This is necessary due to the broken implementation of exec* routines in
319 the Microsoft libraries: they concatenate the arguments together without
320 quoting special characters, and pass the result to CreateProcess, with
321 predictably bad results. By contrast, Posix execvp passes the arguments
322 directly into the argv array of the child process.
323*/
324int
325w32_execvp (path, argv)
326 char *path;
327 char **argv;
328{
329 int i;
330
331 /* Required to allow a .BAT script as alternate editor. */
332 argv[0] = (char *) alternate_editor;
333
334 for (i = 0; argv[i]; i++)
335 if (strchr (argv[i], ' '))
336 {
337 char *quoted = alloca (strlen (argv[i]) + 3);
338 sprintf (quoted, "\"%s\"", argv[i]);
339 argv[i] = quoted;
340 }
341
342 return execvp (path, argv);
343}
344
345#undef execvp
346#define execvp w32_execvp
347
348#endif /* WINDOWSNT */
42073bfb
JB
349
350void
351message (int is_error, char *message, ...)
352{
c66648e0 353 char msg [2048];
42073bfb
JB
354 va_list args;
355
356 va_start (args, message);
42073bfb
JB
357 vsprintf (msg, message, args);
358 va_end (args);
359
360#ifdef WINDOWSNT
361 if (w32_window_app ())
362 {
363 if (is_error)
364 MessageBox (NULL, msg, "Emacsclient ERROR", MB_ICONERROR);
365 else
366 MessageBox (NULL, msg, "Emacsclient", MB_ICONINFORMATION);
367 }
368 else
369#endif
9219db75
JB
370 {
371 FILE *f = is_error ? stderr : stdout;
372
373 fputs (msg, f);
374 fflush (f);
375 }
42073bfb
JB
376}
377
8f9aaa0a 378/* Decode the options from argv and argc.
5212210c 379 The global variable `optind' will say how many arguments we used up. */
8f9aaa0a 380
5212210c 381void
8f9aaa0a
RS
382decode_options (argc, argv)
383 int argc;
384 char **argv;
385{
b6b6d6d2 386 alternate_editor = getenv ("ALTERNATE_EDITOR");
77134727 387 display = getenv ("DISPLAY");
8689463a 388 if (display && strlen (display) == 0)
e5299d8d 389 display = NULL;
0b0d3e0b 390
8f9aaa0a
RS
391 while (1)
392 {
393 int opt = getopt_long (argc, argv,
b03d27bd 394#ifndef NO_SOCKETS_IN_FILE_SYSTEM
974b73e8 395 "VHnea:s:f:d:tc",
b03d27bd 396#else
974b73e8 397 "VHnea:f:d:tc",
b03d27bd 398#endif
974b73e8 399 longopts, 0);
8f9aaa0a
RS
400
401 if (opt == EOF)
402 break;
403
404 switch (opt)
405 {
406 case 0:
407 /* If getopt returns 0, then it has already processed a
408 long-named option. We should do nothing. */
409 break;
e69233c2 410
97e3214d
GM
411 case 'a':
412 alternate_editor = optarg;
413 break;
e69233c2 414
b03d27bd 415#ifndef NO_SOCKETS_IN_FILE_SYSTEM
254107e4
RS
416 case 's':
417 socket_name = optarg;
418 break;
b03d27bd 419#endif
254107e4 420
aa0b6932
JB
421 case 'f':
422 server_file = optarg;
423 break;
254107e4 424
30be2360
SM
425 case 'd':
426 display = optarg;
427 break;
428
8f9aaa0a
RS
429 case 'n':
430 nowait = 1;
431 break;
432
30be2360
SM
433 case 'e':
434 eval = 1;
435 break;
436
8f9aaa0a 437 case 'V':
42073bfb 438 message (FALSE, "emacsclient %s\n", VERSION);
65396510 439 exit (EXIT_SUCCESS);
8f9aaa0a 440 break;
46cec291 441
819b8f00 442 case 't':
77134727 443 tty = 1;
77134727
KL
444 break;
445
e5299d8d 446 case 'c':
92071250 447 current_frame = 1;
9628b887 448 break;
0b0d3e0b 449
8f9aaa0a 450 case 'H':
8f9aaa0a 451 print_help_and_exit ();
20c396e8
JB
452 break;
453
454 default:
42073bfb 455 message (TRUE, "Try `%s --help' for more information\n", progname);
65396510 456 exit (EXIT_FAILURE);
20c396e8 457 break;
8f9aaa0a
RS
458 }
459 }
9628b887 460
92071250
KL
461 if (!tty && display)
462 window_system = 1;
463 else
464 tty = 1;
465
b8ccaf6f
KL
466 /* --no-wait implies --current-frame on ttys when there are file
467 arguments or expressions given. */
468 if (nowait && tty && argc - optind > 0)
92071250
KL
469 current_frame = 1;
470
471 if (current_frame)
472 {
473 tty = 0;
474 window_system = 0;
475 }
476
477 if (tty)
478 window_system = 0;
8f9aaa0a
RS
479}
480
974b73e8 481\f
7f3bff3e 482void
8f9aaa0a
RS
483print_help_and_exit ()
484{
42073bfb 485 message (FALSE,
974b73e8 486 "Usage: %s [OPTIONS] FILE...\n\
30be2360
SM
487Tell the Emacs server to visit the specified files.\n\
488Every FILE can be either just a FILENAME or [+LINE[:COLUMN]] FILENAME.\n\
20c396e8 489\n\
30be2360 490The following OPTIONS are accepted:\n\
974b73e8 491-V, --version Just print version info and return\n\
30be2360 492-H, --help Print this usage information message\n\
819b8f00 493-t, --tty Open a new Emacs frame on the current terminal\n\
e5299d8d 494-c, --current-frame Do not create a new frame; use the current Emacs frame\n\
30be2360 495-e, --eval Evaluate the FILE arguments as ELisp expressions\n\
974b73e8
KL
496-n, --no-wait Don't wait for the server to return\n\
497-d, --display=DISPLAY Visit the file in the given display\n"
aa0b6932
JB
498#ifndef NO_SOCKETS_IN_FILE_SYSTEM
499"-s, --socket-name=FILENAME\n\
974b73e8 500 Set filename of the UNIX socket for communication\n"
aa0b6932
JB
501#endif
502"-f, --server-file=FILENAME\n\
974b73e8 503 Set filename of the TCP authentication file\n\
30be2360
SM
504-a, --alternate-editor=EDITOR\n\
505 Editor to fallback to if the server is not running\n\
20c396e8 506\n\
30be2360 507Report bugs to bug-gnu-emacs@gnu.org.\n", progname);
65396510 508 exit (EXIT_SUCCESS);
8f9aaa0a 509}
5212210c 510
aa0b6932
JB
511/*
512 Try to run a different command, or --if no alternate editor is
513 defined-- exit with an errorcode.
514*/
515void
974b73e8 516fail (void)
9002956f 517{
aa0b6932 518 if (alternate_editor)
9002956f 519 {
aa0b6932 520 int i = optind - 1;
4472aef4 521
974b73e8 522 execvp (alternate_editor, main_argv + i);
42073bfb 523 message (TRUE, "%s: error executing alternate editor \"%s\"\n",
974b73e8 524 progname, alternate_editor);
9002956f 525 }
aa0b6932 526 exit (EXIT_FAILURE);
9002956f
KL
527}
528
aa0b6932 529\f
1e7823d0 530#if !defined (HAVE_SOCKETS) || !defined (HAVE_INET_SOCKETS)
9002956f 531
aa0b6932
JB
532int
533main (argc, argv)
534 int argc;
535 char **argv;
9002956f 536{
974b73e8
KL
537 main_argc = argc;
538 main_argv = argv;
539 progname = argv[0];
540 message (TRUE, "%s: Sorry, the Emacs server is supported only\n"
541 "on systems with Berkeley sockets.\n",
aa0b6932 542 argv[0]);
974b73e8 543 fail ();
9002956f
KL
544}
545
1e7823d0 546#else /* HAVE_SOCKETS && HAVE_INET_SOCKETS */
2828d5f9 547
aa0b6932
JB
548#ifdef WINDOWSNT
549# include <winsock2.h>
2828d5f9 550#else
aa0b6932
JB
551# include <sys/types.h>
552# include <sys/socket.h>
553# include <sys/un.h>
554# include <sys/stat.h>
555# include <errno.h>
556#endif
557
558#define AUTH_KEY_LENGTH 64
559#define SEND_BUFFER_SIZE 4096
560
561extern char *strerror ();
562extern int errno;
563
564/* Buffer to accumulate data to send in TCP connections. */
565char send_buffer[SEND_BUFFER_SIZE + 1];
566int sblen = 0; /* Fill pointer for the send buffer. */
4b7b77f6
JR
567/* Socket used to communicate with the Emacs server process. */
568HSOCKET emacs_socket = 0;
aa0b6932
JB
569
570/* Let's send the data to Emacs when either
571 - the data ends in "\n", or
572 - the buffer is full (but this shouldn't happen)
573 Otherwise, we just accumulate it. */
b03d27bd
JB
574void
575send_to_emacs (s, data)
aa0b6932
JB
576 HSOCKET s;
577 char *data;
578{
579 while (data)
2828d5f9 580 {
aa0b6932
JB
581 int dlen = strlen (data);
582 if (dlen + sblen >= SEND_BUFFER_SIZE)
583 {
584 int part = SEND_BUFFER_SIZE - sblen;
585 strncpy (&send_buffer[sblen], data, part);
586 data += part;
587 sblen = SEND_BUFFER_SIZE;
588 }
589 else if (dlen)
590 {
591 strcpy (&send_buffer[sblen], data);
592 data = NULL;
593 sblen += dlen;
594 }
595 else
596 break;
597
598 if (sblen == SEND_BUFFER_SIZE
599 || (sblen > 0 && send_buffer[sblen-1] == '\n'))
600 {
601 int sent = send (s, send_buffer, sblen, 0);
602 if (sent != sblen)
603 strcpy (send_buffer, &send_buffer[sent]);
604 sblen -= sent;
605 }
2828d5f9 606 }
2828d5f9 607}
2828d5f9
KL
608
609\f
0b0d3e0b 610/* In STR, insert a & before each &, each space, each newline, and
a4cf2096 611 any initial -. Change spaces to underscores, too, so that the
0b0d3e0b
KL
612 return value never contains a space.
613
614 Does not change the string. Outputs the result to STREAM. */
87209357 615void
974b73e8 616quote_argument (s, str)
aa0b6932 617 HSOCKET s;
0b0d3e0b 618 char *str;
5212210c 619{
9002956f 620 char *copy = (char *) xmalloc (strlen (str) * 2 + 1);
5212210c
RS
621 char *p, *q;
622
0b0d3e0b 623 p = str;
5212210c
RS
624 q = copy;
625 while (*p)
626 {
627 if (*p == ' ')
628 {
f1db6a73 629 *q++ = '&';
5212210c
RS
630 *q++ = '_';
631 p++;
632 }
3cf8c6aa
SM
633 else if (*p == '\n')
634 {
635 *q++ = '&';
636 *q++ = 'n';
637 p++;
638 }
5212210c
RS
639 else
640 {
0b0d3e0b 641 if (*p == '&' || (*p == '-' && p == str))
f1db6a73 642 *q++ = '&';
5212210c
RS
643 *q++ = *p++;
644 }
645 }
f1db6a73 646 *q++ = 0;
5212210c 647
aa0b6932 648 SEND_STRING (copy);
87209357
EZ
649
650 free (copy);
5212210c 651}
0c76956f 652
0b0d3e0b
KL
653
654/* The inverse of quote_argument. Removes quoting in string STR by
655 modifying the string in place. Returns STR. */
656
657char *
658unquote_argument (str)
659 char *str;
660{
661 char *p, *q;
662
663 if (! str)
664 return str;
665
666 p = str;
667 q = str;
668 while (*p)
669 {
670 if (*p == '&')
671 {
672 p++;
673 if (*p == '&')
674 *p = '&';
675 else if (*p == '_')
676 *p = ' ';
677 else if (*p == 'n')
678 *p = '\n';
679 else if (*p == '-')
680 *p = '-';
681 }
682 *q++ = *p++;
683 }
684 *q = 0;
685 return str;
686}
687
8f9aaa0a 688\f
b03d27bd
JB
689int
690file_name_absolute_p (filename)
691 const unsigned char *filename;
692{
693 /* Sanity check, it shouldn't happen. */
694 if (! filename) return FALSE;
695
696 /* /xxx is always an absolute path. */
697 if (filename[0] == '/') return TRUE;
698
699 /* Empty filenames (which shouldn't happen) are relative. */
700 if (filename[0] == '\0') return FALSE;
701
702#ifdef WINDOWSNT
71b8f735 703 /* X:\xxx is always absolute. */
5f7a4874 704 if (isalpha (filename[0])
cb0297bb 705 && filename[1] == ':' && (filename[2] == '\\' || filename[2] == '/'))
b03d27bd
JB
706 return TRUE;
707
708 /* Both \xxx and \\xxx\yyy are absolute. */
709 if (filename[0] == '\\') return TRUE;
71b8f735
JB
710
711 /*
712 FIXME: There's a corner case not dealt with, "x:y", where:
713
714 1) x is a valid drive designation (usually a letter in the A-Z range)
715 and y is a path, relative to the current directory on drive x. This
716 is absolute, *after* fixing the y part to include the current
717 directory in x.
718
719 2) x is a relative file name, and y is an NTFS stream name. This is a
720 correct relative path, but it is very unusual.
721
722 The trouble is that first case items are also valid examples of the
723 second case, i.e., "c:test" can be understood as drive:path or as
724 file:stream.
725
726 The "right" fix would involve checking whether
727 - the current drive/partition is NTFS,
728 - x is a valid (and accesible) drive designator,
729 - x:y already exists as a file:stream in the current directory,
730 - y already exists on the current directory of drive x,
731 - the auspices are favorable,
732 and then taking an "informed decision" based on the above.
733
734 Whatever the result, Emacs currently does a very bad job of dealing
735 with NTFS file:streams: it cannot visit them, and the only way to
736 create one is by setting `buffer-file-name' to point to it (either
737 manually or with emacsclient). So perhaps resorting to 1) and ignoring
738 2) for now is the right thing to do.
739
740 Anyway, something to decide After the Release.
741 */
b03d27bd
JB
742#endif
743
744 return FALSE;
745}
746
aa0b6932 747#ifdef WINDOWSNT
f0384499 748/* Wrapper to make WSACleanup a cdecl, as required by atexit. */
b03d27bd
JB
749void
750__cdecl close_winsock ()
aa0b6932
JB
751{
752 WSACleanup ();
753}
0c76956f 754
b03d27bd
JB
755/* Initialize the WinSock2 library. */
756void
757initialize_sockets ()
0c76956f 758{
aa0b6932
JB
759 WSADATA wsaData;
760
aa0b6932
JB
761 if (WSAStartup (MAKEWORD (2, 0), &wsaData))
762 {
42073bfb 763 message (TRUE, "%s: error initializing WinSock2", progname);
aa0b6932
JB
764 exit (EXIT_FAILURE);
765 }
766
767 atexit (close_winsock);
0c76956f 768}
e35fc962 769#endif /* WINDOWSNT */
974b73e8 770
8f9aaa0a 771\f
97e3214d 772/*
aa0b6932 773 * Read the information needed to set up a TCP comm channel with
434a6c5d 774 * the Emacs server: host, port, pid and authentication string.
0e0dced5 775 */
b03d27bd
JB
776int
777get_server_config (server, authentication)
aa0b6932
JB
778 struct sockaddr_in *server;
779 char *authentication;
97e3214d 780{
aa0b6932
JB
781 char dotted[32];
782 char *port;
434a6c5d 783 char *pid;
b03d27bd 784 FILE *config = NULL;
aa0b6932 785
b03d27bd
JB
786 if (file_name_absolute_p (server_file))
787 config = fopen (server_file, "rb");
788 else
97e3214d 789 {
aa0b6932 790 char *home = getenv ("HOME");
88b46d84 791
aa0b6932
JB
792 if (home)
793 {
794 char *path = alloca (32 + strlen (home) + strlen (server_file));
795 sprintf (path, "%s/.emacs.d/server/%s", home, server_file);
796 config = fopen (path, "rb");
797 }
88b46d84
JB
798#ifdef WINDOWSNT
799 if (!config && (home = getenv ("APPDATA")))
800 {
801 char *path = alloca (32 + strlen (home) + strlen (server_file));
802 sprintf (path, "%s/.emacs.d/server/%s", home, server_file);
803 config = fopen (path, "rb");
804 }
805#endif
aa0b6932
JB
806 }
807
808 if (! config)
809 return FALSE;
810
811 if (fgets (dotted, sizeof dotted, config)
434a6c5d
JB
812 && (port = strchr (dotted, ':'))
813 && (pid = strchr (port, ' ')))
aa0b6932
JB
814 {
815 *port++ = '\0';
434a6c5d 816 *pid++ = '\0';
97e3214d
GM
817 }
818 else
819 {
42073bfb 820 message (TRUE, "%s: invalid configuration info", progname);
65396510 821 exit (EXIT_FAILURE);
97e3214d 822 }
97e3214d 823
aa0b6932
JB
824 server->sin_family = AF_INET;
825 server->sin_addr.s_addr = inet_addr (dotted);
826 server->sin_port = htons (atoi (port));
97e3214d 827
aa0b6932
JB
828 if (! fread (authentication, AUTH_KEY_LENGTH, 1, config))
829 {
42073bfb 830 message (TRUE, "%s: cannot read authentication info", progname);
aa0b6932
JB
831 exit (EXIT_FAILURE);
832 }
46cec291 833
aa0b6932 834 fclose (config);
97e3214d 835
c66648e0 836 emacs_pid = atoi (pid);
434a6c5d 837
aa0b6932 838 return TRUE;
97e3214d
GM
839}
840
aa0b6932
JB
841HSOCKET
842set_tcp_socket ()
843{
844 HSOCKET s;
845 struct sockaddr_in server;
aa0b6932
JB
846 struct linger l_arg = {1, 1};
847 char auth_string[AUTH_KEY_LENGTH + 1];
9628b887 848
aa0b6932
JB
849 if (! get_server_config (&server, auth_string))
850 return INVALID_SOCKET;
851
b03d27bd 852 if (server.sin_addr.s_addr != inet_addr ("127.0.0.1"))
9219db75 853 message (FALSE, "%s: connected to remote socket at %s\n",
b03d27bd
JB
854 progname, inet_ntoa (server.sin_addr));
855
aa0b6932
JB
856 /*
857 * Open up an AF_INET socket
858 */
859 if ((s = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
860 {
42073bfb 861 message (TRUE, "%s: socket: %s\n", progname, strerror (errno));
aa0b6932
JB
862 return INVALID_SOCKET;
863 }
864
865 /*
866 * Set up the socket
867 */
868 if (connect (s, (struct sockaddr *) &server, sizeof server) < 0)
869 {
42073bfb 870 message (TRUE, "%s: connect: %s\n", progname, strerror (errno));
aa0b6932
JB
871 return INVALID_SOCKET;
872 }
873
aa0b6932
JB
874 setsockopt (s, SOL_SOCKET, SO_LINGER, (char *) &l_arg, sizeof l_arg);
875
876 /*
877 * Send the authentication
878 */
879 auth_string[AUTH_KEY_LENGTH] = '\0';
880
881 SEND_STRING ("-auth ");
882 SEND_STRING (auth_string);
883 SEND_STRING ("\n");
884
885 return s;
886}
887
b2ff54a0
JR
888
889/* Returns 1 if PREFIX is a prefix of STRING. */
890static int
891strprefix (char *prefix, char *string)
892{
893 int i;
894 if (! prefix)
895 return 1;
896
897 if (!string)
898 return 0;
899
900 for (i = 0; prefix[i]; i++)
901 if (!string[i] || string[i] != prefix[i])
902 return 0;
903 return 1;
904}
905
906
aa0b6932 907#if !defined (NO_SOCKETS_IN_FILE_SYSTEM)
46cec291 908
9f637eea
GM
909/* Three possibilities:
910 2 - can't be `stat'ed (sets errno)
911 1 - isn't owned by us
912 0 - success: none of the above */
913
914static int
915socket_status (socket_name)
916 char *socket_name;
917{
918 struct stat statbfr;
919
920 if (stat (socket_name, &statbfr) == -1)
921 return 2;
922
923 if (statbfr.st_uid != geteuid ())
924 return 1;
0b0d3e0b 925
9f637eea
GM
926 return 0;
927}
928
974b73e8 929\f
da8e1115
KL
930/* A signal handler that passes the signal to the Emacs process.
931 Useful for SIGWINCH. */
932
9628b887 933SIGTYPE
428a555e 934pass_signal_to_emacs (int signalnum)
9628b887
KL
935{
936 int old_errno = errno;
937
9f729af5 938 if (emacs_pid)
428a555e 939 kill (emacs_pid, signalnum);
9f729af5 940
428a555e 941 signal (signalnum, pass_signal_to_emacs);
9f729af5
KL
942 errno = old_errno;
943}
944
0b0d3e0b
KL
945/* Signal handler for SIGCONT; notify the Emacs process that it can
946 now resume our tty frame. */
947
948SIGTYPE
949handle_sigcont (int signalnum)
950{
951 int old_errno = errno;
952
953 if (tcgetpgrp (1) == getpgrp ())
954 {
955 /* We are in the foreground. */
382707ec 956 SEND_STRING ("-resume \n");
0b0d3e0b
KL
957 }
958 else
959 {
960 /* We are in the background; cancel the continue. */
961 kill (getpid (), SIGSTOP);
962 }
c6c53c3e
KL
963
964 signal (signalnum, handle_sigcont);
0b0d3e0b
KL
965 errno = old_errno;
966}
967
968/* Signal handler for SIGTSTP; notify the Emacs process that we are
969 going to sleep. Normally the suspend is initiated by Emacs via
970 server-handle-suspend-tty, but if the server gets out of sync with
971 reality, we may get a SIGTSTP on C-z. Handling this signal and
972 notifying Emacs about it should get things under control again. */
973
974SIGTYPE
975handle_sigtstp (int signalnum)
976{
977 int old_errno = errno;
978 sigset_t set;
979
382707ec
KL
980 if (s)
981 SEND_STRING ("-suspend \n");
0b0d3e0b
KL
982
983 /* Unblock this signal and call the default handler by temprarily
984 changing the handler and resignalling. */
985 sigprocmask (SIG_BLOCK, NULL, &set);
986 sigdelset (&set, signalnum);
987 signal (signalnum, SIG_DFL);
988 kill (getpid (), signalnum);
989 sigprocmask (SIG_SETMASK, &set, NULL); /* Let's the above signal through. */
990 signal (signalnum, handle_sigtstp);
991
992 errno = old_errno;
993}
da8e1115 994/* Set up signal handlers before opening a frame on the current tty. */
0b0d3e0b 995
4d553a13
KL
996void
997init_signals (void)
9628b887
KL
998{
999 /* Set up signal handlers. */
428a555e 1000 signal (SIGWINCH, pass_signal_to_emacs);
4ca927b4
KL
1001
1002 /* Don't pass SIGINT and SIGQUIT to Emacs, because it has no way of
1003 deciding which terminal the signal came from. C-g is now a
1004 normal input event on secondary terminals. */
1005#if 0
428a555e
KL
1006 signal (SIGINT, pass_signal_to_emacs);
1007 signal (SIGQUIT, pass_signal_to_emacs);
4ca927b4 1008#endif
0b0d3e0b
KL
1009
1010 signal (SIGCONT, handle_sigcont);
1011 signal (SIGTSTP, handle_sigtstp);
1012 signal (SIGTTOU, handle_sigtstp);
9628b887
KL
1013}
1014
46cec291 1015
aa0b6932
JB
1016HSOCKET
1017set_local_socket ()
46cec291 1018{
aa0b6932 1019 HSOCKET s;
46cec291 1020 struct sockaddr_un server;
46cec291 1021
e69233c2 1022 /*
46cec291
RS
1023 * Open up an AF_UNIX socket in this person's home directory
1024 */
1025
1026 if ((s = socket (AF_UNIX, SOCK_STREAM, 0)) < 0)
1027 {
42073bfb 1028 message (TRUE, "%s: socket: %s\n", progname, strerror (errno));
aa0b6932 1029 return INVALID_SOCKET;
46cec291 1030 }
e69233c2 1031
46cec291 1032 server.sun_family = AF_UNIX;
c5fee545 1033
c5fee545 1034 {
9f637eea 1035 int sock_status = 0;
5c9659d3 1036 int default_sock = !socket_name;
b80bf66e 1037 int saved_errno = 0;
0b0d3e0b 1038
0734b0d0 1039 char *server_name = "server";
0b0d3e0b 1040
0734b0d0
SM
1041 if (socket_name && !index (socket_name, '/') && !index (socket_name, '\\'))
1042 { /* socket_name is a file name component. */
d3a6748c
KL
1043 server_name = socket_name;
1044 socket_name = NULL;
1045 default_sock = 1; /* Try both UIDs. */
0734b0d0 1046 }
efb859b4 1047
5c9659d3 1048 if (default_sock)
254107e4 1049 {
d3a6748c
KL
1050 socket_name = alloca (100 + strlen (server_name));
1051 sprintf (socket_name, "/tmp/emacs%d/%s",
1052 (int) geteuid (), server_name);
254107e4
RS
1053 }
1054
1055 if (strlen (socket_name) < sizeof (server.sun_path))
1056 strcpy (server.sun_path, socket_name);
1057 else
819b8f00 1058 {
974b73e8
KL
1059 message (TRUE, "%s: socket-name %s too long",
1060 progname, socket_name);
819b8f00
KL
1061 fail ();
1062 }
efb859b4 1063
9f637eea
GM
1064 /* See if the socket exists, and if it's owned by us. */
1065 sock_status = socket_status (server.sun_path);
152b6e83 1066 saved_errno = errno;
5c9659d3 1067 if (sock_status && default_sock)
efb859b4 1068 {
9f637eea
GM
1069 /* Failing that, see if LOGNAME or USER exist and differ from
1070 our euid. If so, look for a socket based on the UID
1071 associated with the name. This is reminiscent of the logic
1072 that init_editfns uses to set the global Vuser_full_name. */
e69233c2 1073
9f637eea 1074 char *user_name = (char *) getenv ("LOGNAME");
293f9f2a 1075
9f637eea
GM
1076 if (!user_name)
1077 user_name = (char *) getenv ("USER");
e69233c2 1078
9f637eea
GM
1079 if (user_name)
1080 {
1081 struct passwd *pw = getpwnam (user_name);
293f9f2a 1082
9f637eea
GM
1083 if (pw && (pw->pw_uid != geteuid ()))
1084 {
1085 /* We're running under su, apparently. */
0734b0d0
SM
1086 socket_name = alloca (100 + strlen (server_name));
1087 sprintf (socket_name, "/tmp/emacs%d/%s",
1088 (int) pw->pw_uid, server_name);
5c9659d3
SM
1089
1090 if (strlen (socket_name) < sizeof (server.sun_path))
1091 strcpy (server.sun_path, socket_name);
1092 else
1093 {
42073bfb 1094 message (TRUE, "%s: socket-name %s too long",
aa0b6932 1095 progname, socket_name);
65396510 1096 exit (EXIT_FAILURE);
5c9659d3
SM
1097 }
1098
9f637eea 1099 sock_status = socket_status (server.sun_path);
b80bf66e 1100 saved_errno = errno;
9f637eea 1101 }
293f9f2a
RS
1102 else
1103 errno = saved_errno;
9f637eea 1104 }
efb859b4 1105 }
e69233c2 1106
aa0b6932
JB
1107 switch (sock_status)
1108 {
1109 case 1:
974b73e8
KL
1110 /* There's a socket, but it isn't owned by us. This is OK if
1111 we are root. */
1112 if (0 != geteuid ())
1113 {
1114 message (TRUE, "%s: Invalid socket owner\n", progname);
aa0b6932 1115 return INVALID_SOCKET;
974b73e8
KL
1116 }
1117 break;
aa0b6932
JB
1118
1119 case 2:
974b73e8
KL
1120 /* `stat' failed */
1121 if (saved_errno == ENOENT)
1122 message (TRUE,
1123 "%s: can't find socket; have you started the server?\n\
45adde32 1124To start the server in Emacs, type \"M-x server-start\".\n",
aa0b6932 1125 progname);
974b73e8
KL
1126 else
1127 message (TRUE, "%s: can't stat %s: %s\n",
aa0b6932 1128 progname, server.sun_path, strerror (saved_errno));
974b73e8 1129 return INVALID_SOCKET;
aa0b6932 1130 }
efb859b4 1131 }
46cec291 1132
4e23f2ba
JB
1133 if (connect (s, (struct sockaddr *) &server, strlen (server.sun_path) + 2)
1134 < 0)
46cec291 1135 {
42073bfb 1136 message (TRUE, "%s: connect: %s\n", progname, strerror (errno));
aa0b6932 1137 return INVALID_SOCKET;
46cec291 1138 }
23a7488d 1139
aa0b6932
JB
1140 return s;
1141}
1142#endif /* ! NO_SOCKETS_IN_FILE_SYSTEM */
1143
1144HSOCKET
1145set_socket ()
1146{
b03d27bd 1147 HSOCKET s;
974b73e8 1148
b03d27bd 1149 INITIALIZE ();
974b73e8 1150
aa0b6932 1151#ifndef NO_SOCKETS_IN_FILE_SYSTEM
b03d27bd
JB
1152 /* Explicit --socket-name argument. */
1153 if (socket_name)
46cec291 1154 {
b03d27bd
JB
1155 s = set_local_socket ();
1156 if ((s != INVALID_SOCKET) || alternate_editor)
974b73e8 1157 return s;
42073bfb 1158 message (TRUE, "%s: error accessing socket \"%s\"",
974b73e8 1159 progname, socket_name);
b03d27bd 1160 exit (EXIT_FAILURE);
46cec291 1161 }
b03d27bd
JB
1162#endif
1163
1164 /* Explicit --server-file arg or EMACS_SERVER_FILE variable. */
1165 if (!server_file)
1166 server_file = getenv ("EMACS_SERVER_FILE");
46cec291 1167
b03d27bd 1168 if (server_file)
23a7488d 1169 {
b03d27bd
JB
1170 s = set_tcp_socket ();
1171 if ((s != INVALID_SOCKET) || alternate_editor)
974b73e8
KL
1172 return s;
1173
42073bfb 1174 message (TRUE, "%s: error accessing server file \"%s\"",
974b73e8 1175 progname, server_file);
b03d27bd 1176 exit (EXIT_FAILURE);
23a7488d 1177 }
974b73e8 1178
b03d27bd
JB
1179#ifndef NO_SOCKETS_IN_FILE_SYSTEM
1180 /* Implicit local socket. */
1181 s = set_local_socket ();
1182 if (s != INVALID_SOCKET)
1183 return s;
1184#endif
23a7488d 1185
b03d27bd
JB
1186 /* Implicit server file. */
1187 server_file = "server";
1188 s = set_tcp_socket ();
1189 if ((s != INVALID_SOCKET) || alternate_editor)
1190 return s;
1191
1192 /* No implicit or explicit socket, and no alternate editor. */
42073bfb 1193 message (TRUE, "%s: No socket or alternate editor. Please use:\n\n"
b03d27bd
JB
1194#ifndef NO_SOCKETS_IN_FILE_SYSTEM
1195"\t--socket-name\n"
ee6a193c 1196#endif
b03d27bd
JB
1197"\t--server-file (or environment variable EMACS_SERVER_FILE)\n\
1198\t--alternate-editor (or environment variable ALTERNATE_EDITOR)\n",
1199 progname);
1200 exit (EXIT_FAILURE);
aa0b6932 1201}
46cec291 1202
0e0dced5
JB
1203#ifdef WINDOWSNT
1204FARPROC set_fg; /* Pointer to AllowSetForegroundWindow. */
1205FARPROC get_wc; /* Pointer to RealGetWindowClassA. */
1206
1207BOOL CALLBACK
1208w32_find_emacs_process (hWnd, lParam)
1209 HWND hWnd;
1210 LPARAM lParam;
1211{
1212 DWORD pid;
1213 char class[6];
1214
1215 /* Reject any window not of class "Emacs". */
1216 if (! get_wc (hWnd, class, sizeof (class))
1217 || strcmp (class, "Emacs"))
1218 return TRUE;
1219
1220 /* We only need the process id, not the thread id. */
1221 (void) GetWindowThreadProcessId (hWnd, &pid);
1222
1223 /* Not the one we're looking for. */
1224 if (pid != (DWORD) emacs_pid) return TRUE;
1225
1226 /* OK, let's raise it. */
1227 set_fg (emacs_pid);
1228
1229 /* Stop enumeration. */
1230 return FALSE;
1231}
1232
1233/*
1234 * Search for a window of class "Emacs" and owned by a process with
1235 * process id = emacs_pid. If found, allow it to grab the focus.
1236 */
1237void
1238w32_give_focus ()
1239{
1240 HMODULE hUser32;
1241
71b8f735 1242 /* It shouldn't happen when dealing with TCP sockets. */
0e0dced5
JB
1243 if (!emacs_pid) return;
1244
1245 if (!(hUser32 = LoadLibrary ("user32.dll"))) return;
1246
1247 /* Modern Windows restrict which processes can set the foreground window.
1248 emacsclient can allow Emacs to grab the focus by calling the function
1249 AllowSetForegroundWindow. Unfortunately, older Windows (W95, W98 and
1250 NT) lack this function, so we have to check its availability. */
1251 if ((set_fg = GetProcAddress (hUser32, "AllowSetForegroundWindow"))
1252 && (get_wc = GetProcAddress (hUser32, "RealGetWindowClassA")))
1253 EnumWindows (w32_find_emacs_process, (LPARAM) 0);
1254
1255 FreeLibrary (hUser32);
1256}
1257#endif
1258
aa0b6932
JB
1259int
1260main (argc, argv)
1261 int argc;
1262 char **argv;
1263{
aa0b6932 1264 int i, rl, needlf = 0;
974b73e8 1265 char *cwd, *str;
aa0b6932
JB
1266 char string[BUFSIZ+1];
1267
974b73e8
KL
1268 main_argc = argc;
1269 main_argv = argv;
aa0b6932
JB
1270 progname = argv[0];
1271
1272 /* Process options. */
1273 decode_options (argc, argv);
1274
974b73e8 1275 if ((argc - optind < 1) && !eval && !tty && !window_system)
23a7488d 1276 {
974b73e8
KL
1277 message (TRUE, "%s: file name or argument required\n"
1278 "Try `%s --help' for more information\n",
1279 progname, progname);
aa0b6932 1280 exit (EXIT_FAILURE);
23a7488d
RS
1281 }
1282
4b7b77f6 1283 if ((emacs_socket = set_socket ()) == INVALID_SOCKET)
974b73e8 1284 fail ();
aa0b6932 1285
974b73e8
KL
1286
1287 cwd = get_current_dir_name ();
46cec291
RS
1288 if (cwd == 0)
1289 {
1290 /* getwd puts message in STRING if it fails. */
974b73e8
KL
1291 message (TRUE, "%s: %s\n", progname,
1292 "Cannot get current working directory");
819b8f00 1293 fail ();
46cec291
RS
1294 }
1295
c66648e0 1296#ifdef WINDOWSNT
0e0dced5 1297 w32_give_focus ();
c66648e0
JB
1298#endif
1299
a9298135 1300 /* First of all, send our version number for verification. */
974b73e8
KL
1301 SEND_STRING ("-version ");
1302 SEND_STRING (VERSION);
1303 SEND_STRING (" ");
0b0d3e0b 1304
9002956f 1305 /* Send over our environment. */
59e085e0
KL
1306 if (!current_frame)
1307 {
1308 extern char **environ;
1309 int i;
1310 for (i = 0; environ[i]; i++)
1311 {
1312 char *name = xstrdup (environ[i]);
1313 char *value = strchr (name, '=');
974b73e8
KL
1314 SEND_STRING ("-env ");
1315 SEND_QUOTED (environ[i]);
1316 SEND_STRING (" ");
59e085e0
KL
1317 }
1318 }
9002956f 1319
2828d5f9
KL
1320 /* Send over our current directory. */
1321 if (!current_frame)
1322 {
974b73e8
KL
1323 SEND_STRING ("-dir ");
1324 SEND_QUOTED (cwd);
1325 SEND_STRING ("/");
1326 SEND_STRING (" ");
2828d5f9
KL
1327 }
1328
6afdd335 1329 retry:
5212210c 1330 if (nowait)
aa0b6932 1331 SEND_STRING ("-nowait ");
292d74a3 1332
92071250 1333 if (current_frame)
974b73e8 1334 SEND_STRING ("-current-frame ");
92071250 1335
30be2360 1336 if (display)
87209357 1337 {
aa0b6932
JB
1338 SEND_STRING ("-display ");
1339 SEND_QUOTED (display);
1340 SEND_STRING (" ");
87209357 1341 }
30be2360 1342
77134727 1343 if (tty)
9628b887 1344 {
b2ff54a0
JR
1345 char *tty_name = NULL;
1346#ifndef WINDOWSNT
1347 tty_name = ttyname (fileno (stdin));
1348#endif
2fc0cf2a 1349 char *type = getenv ("TERM");
0b0d3e0b 1350
4d553a13 1351 if (! tty_name)
2fc0cf2a 1352 {
974b73e8 1353 message (TRUE, "%s: could not get terminal name\n", progname);
2fc0cf2a
KL
1354 fail ();
1355 }
1356
1357 if (! type)
1358 {
974b73e8 1359 message (TRUE, "%s: please set the TERM variable to your terminal type\n",
2fc0cf2a
KL
1360 progname);
1361 fail ();
1362 }
1363
1364 if (! strcmp (type, "eterm"))
1365 {
1366 /* This causes nasty, MULTI_KBOARD-related input lockouts. */
974b73e8 1367 message (TRUE, "%s: opening a frame in an Emacs term buffer"
2fc0cf2a
KL
1368 " is not supported\n", progname);
1369 fail ();
1370 }
b2ff54a0 1371#if !defined (NO_SOCKETS_IN_FILE_SYSTEM)
4d553a13 1372 init_signals ();
b2ff54a0 1373#endif
0b0d3e0b 1374
974b73e8
KL
1375 SEND_STRING ("-tty ");
1376 SEND_QUOTED (tty_name);
1377 SEND_STRING (" ");
1378 SEND_QUOTED (type);
1379 SEND_STRING (" ");
9628b887 1380 }
77134727
KL
1381
1382 if (window_system)
974b73e8 1383 SEND_STRING ("-window-system ");
0b0d3e0b 1384
87209357 1385 if ((argc - optind > 0))
5212210c 1386 {
87209357 1387 for (i = optind; i < argc; i++)
46cec291 1388 {
0b0d3e0b
KL
1389 int relative = 0;
1390
87209357 1391 if (eval)
0b0d3e0b 1392 {
974b73e8
KL
1393 /* Don't prepend cwd or anything like that. */
1394 SEND_STRING ("-eval ");
1395 SEND_QUOTED (argv[i]);
1396 SEND_STRING (" ");
0b0d3e0b
KL
1397 continue;
1398 }
1399
1400 if (*argv[i] == '+')
1401 {
87209357
EZ
1402 char *p = argv[i] + 1;
1403 while (isdigit ((unsigned char) *p) || *p == ':') p++;
0b0d3e0b
KL
1404 if (*p == 0)
1405 {
974b73e8
KL
1406 SEND_STRING ("-position ");
1407 SEND_QUOTED (argv[i]);
1408 SEND_STRING (" ");
0b0d3e0b
KL
1409 continue;
1410 }
1411 else
1412 relative = 1;
1413 }
b03d27bd 1414 else if (! file_name_absolute_p (argv[i]))
0b0d3e0b
KL
1415 relative = 1;
1416
974b73e8 1417 SEND_STRING ("-file ");
0b0d3e0b
KL
1418 if (relative)
1419 {
974b73e8
KL
1420 SEND_QUOTED (cwd);
1421 SEND_STRING ("/");
0b0d3e0b 1422 }
974b73e8
KL
1423 SEND_QUOTED (argv[i]);
1424 SEND_STRING (" ");
0b0d3e0b 1425 }
46cec291 1426 }
87209357
EZ
1427 else
1428 {
77134727 1429 if (!tty && !window_system)
9628b887
KL
1430 {
1431 while ((str = fgets (string, BUFSIZ, stdin)))
1432 {
0b0d3e0b 1433 if (eval)
974b73e8 1434 SEND_STRING ("-eval ");
0b0d3e0b 1435 else
974b73e8 1436 SEND_STRING ("-file ");
382707ec 1437 SEND_QUOTED (str);
9628b887 1438 }
974b73e8 1439 SEND_STRING (" ");
9628b887 1440 }
87209357 1441 }
0b0d3e0b 1442
aa0b6932 1443 SEND_STRING ("\n");
46cec291 1444
fc2040c0
KL
1445 /* Wait for an answer. */
1446 if (!eval && !tty && !nowait)
30be2360
SM
1447 {
1448 printf ("Waiting for Emacs...");
1449 needlf = 2;
1450 }
46cec291 1451 fflush (stdout);
0b0d3e0b 1452 fsync (1);
46cec291 1453
3cf8c6aa 1454 /* Now, wait for an answer and print any messages. */
4b7b77f6 1455 while ((rl = recv (emacs_socket, string, BUFSIZ, 0)) > 0)
3cf8c6aa 1456 {
974b73e8
KL
1457 char *p;
1458 string[rl] = '\0';
1459
1460 p = string + strlen (string) - 1;
1461 while (p > string && *p == '\n')
0b0d3e0b
KL
1462 *p-- = 0;
1463
974b73e8 1464 if (strprefix ("-good-version ", string))
a9298135 1465 {
6afdd335 1466 /* -good-version: The versions match. */
a9298135 1467 }
974b73e8 1468 else if (strprefix ("-emacs-pid ", string))
4d553a13 1469 {
6afdd335 1470 /* -emacs-pid PID: The process id of the Emacs process. */
77134727
KL
1471 emacs_pid = strtol (string + strlen ("-emacs-pid"), NULL, 10);
1472 }
974b73e8 1473 else if (strprefix ("-window-system-unsupported ", string))
6afdd335
KL
1474 {
1475 /* -window-system-unsupported: Emacs was compiled without X
1476 support. Try again on the terminal. */
1477 window_system = 0;
1478 nowait = 0;
1479 tty = 1;
1480 goto retry;
1481 }
974b73e8 1482 else if (strprefix ("-print ", string))
77134727 1483 {
6afdd335 1484 /* -print STRING: Print STRING on the terminal. */
974b73e8 1485 str = unquote_argument (string + strlen ("-print "));
0b0d3e0b 1486 if (needlf)
77134727 1487 printf ("\n");
0b0d3e0b
KL
1488 printf ("%s", str);
1489 needlf = str[0] == '\0' ? needlf : str[strlen (str) - 1] != '\n';
77134727 1490 }
974b73e8 1491 else if (strprefix ("-error ", string))
77134727 1492 {
6afdd335 1493 /* -error DESCRIPTION: Signal an error on the terminal. */
974b73e8 1494 str = unquote_argument (string + strlen ("-error "));
0b0d3e0b
KL
1495 if (needlf)
1496 printf ("\n");
974b73e8 1497 fprintf (stderr, "*ERROR*: %s", str);
0b0d3e0b
KL
1498 needlf = str[0] == '\0' ? needlf : str[strlen (str) - 1] != '\n';
1499 }
b2ff54a0 1500#ifndef WINDOWSNT
382707ec 1501 else if (strprefix ("-suspend ", string))
0b0d3e0b 1502 {
6afdd335 1503 /* -suspend: Suspend this terminal, i.e., stop the process. */
0b0d3e0b 1504 if (needlf)
77134727 1505 printf ("\n");
0b0d3e0b
KL
1506 needlf = 0;
1507 kill (0, SIGSTOP);
4d553a13 1508 }
b2ff54a0 1509#endif
4d553a13
KL
1510 else
1511 {
6afdd335 1512 /* Unknown command. */
0b0d3e0b 1513 if (needlf)
4d553a13 1514 printf ("\n");
974b73e8
KL
1515 printf ("*ERROR*: Unknown message: %s", string);
1516 needlf = string[0] == '\0' ? needlf : string[strlen (string) - 1] != '\n';
4d553a13 1517 }
3cf8c6aa
SM
1518 }
1519
1520 if (needlf)
1521 printf ("\n");
1522 fflush (stdout);
0b0d3e0b 1523 fsync (1);
23a7488d 1524
4b7b77f6 1525 CLOSE_SOCKET (emacs_socket);
65396510 1526 return EXIT_SUCCESS;
46cec291
RS
1527}
1528
1e7823d0 1529#endif /* HAVE_SOCKETS && HAVE_INET_SOCKETS */
aa0b6932 1530
27711600
RM
1531\f
1532#ifndef HAVE_STRERROR
1533char *
1534strerror (errnum)
1535 int errnum;
1536{
1537 extern char *sys_errlist[];
1538 extern int sys_nerr;
1539
1540 if (errnum >= 0 && errnum < sys_nerr)
1541 return sys_errlist[errnum];
1542 return (char *) "Unknown error";
1543}
1544
1545#endif /* ! HAVE_STRERROR */
ab5796a9
MB
1546
1547/* arch-tag: f39bb9c4-73eb-477e-896d-50832e2ca9a7
1548 (do not change this comment) */
65396510
TTN
1549
1550/* emacsclient.c ends here */