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