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