Add a wrapper for getenv so it also checks the registry on Windows.
[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
JB
301/* Message functions. */
302
303#ifdef WINDOWSNT
7ce8671d
JB
304
305#define REG_ROOT "SOFTWARE\\GNU\\Emacs"
306
307/* Retrieve an environment variable from the Emacs subkeys of the registry.
308 Return NULL if the variable was not found, or it was empty.
309 This code is based on w32_get_resource (w32.c). */
310char *
311w32_get_resource (predefined, key, type)
312 HKEY predefined;
313 char *key;
314 LPDWORD type;
315{
316 HKEY hrootkey = NULL;
317 char *result = NULL;
318 DWORD cbData;
319
320 if (RegOpenKeyEx (predefined, REG_ROOT, 0, KEY_READ, &hrootkey) == ERROR_SUCCESS)
321 {
322 if (RegQueryValueEx (hrootkey, key, NULL, NULL, NULL, &cbData) == ERROR_SUCCESS)
323 {
324 result = (char *) xmalloc (cbData);
325
326 if ((RegQueryValueEx (hrootkey, key, NULL, type, result, &cbData) != ERROR_SUCCESS) ||
327 (*result == 0))
328 {
329 free (result);
330 result = NULL;
331 }
332 }
333
334 RegCloseKey (hrootkey);
335 }
336
337 return result;
338}
339
340/*
341 getenv wrapper for Windows
342
343 This is needed to duplicate Emacs's behavior, which is to look for enviroment
344 variables in the registry if they don't appear in the environment.
345*/
346char *
347w32_getenv (envvar)
348 char *envvar;
349{
350 char *value;
351 DWORD dwType;
352
353 if (value = getenv (envvar))
354 /* Found in the environment. */
355 return value;
356
357 if (! (value = w32_get_resource (HKEY_CURRENT_USER, envvar, &dwType)) &&
358 ! (value = w32_get_resource (HKEY_LOCAL_MACHINE, envvar, &dwType)))
359 /* Not found in the registry. */
360 return NULL;
361
362 if (dwType == REG_SZ)
363 /* Registry; no need to expand. */
364 return value;
365
366 if (dwType == REG_EXPAND_SZ)
367 {
368 DWORD size;
369
370 if (size = ExpandEnvironmentStrings (value, NULL, 0))
371 {
372 char *buffer = (char *) xmalloc (size);
373 if (ExpandEnvironmentStrings (value, buffer, size))
374 {
375 /* Found and expanded. */
376 free (value);
377 return buffer;
378 }
379
380 /* Error expanding. */
381 free (buffer);
382 }
383 }
384
385 /* Not the right type, or not correctly expanded. */
386 free (value);
387 return NULL;
388}
389
42073bfb 390int
f0384499 391w32_window_app ()
42073bfb
JB
392{
393 static int window_app = -1;
394 char szTitle[MAX_PATH];
395
396 if (window_app < 0)
dbf60b07
JR
397 {
398 /* Checking for STDOUT does not work; it's a valid handle also in
399 nonconsole apps. Testing for the console title seems to work. */
400 window_app = (GetConsoleTitleA (szTitle, MAX_PATH) == 0);
401 if (window_app)
402 InitCommonControls();
403 }
42073bfb
JB
404
405 return window_app;
406}
105faa84
DN
407
408/*
cb06b8dc 409 execvp wrapper for Windows. Quotes arguments with embedded spaces.
105faa84
DN
410
411 This is necessary due to the broken implementation of exec* routines in
412 the Microsoft libraries: they concatenate the arguments together without
413 quoting special characters, and pass the result to CreateProcess, with
414 predictably bad results. By contrast, Posix execvp passes the arguments
415 directly into the argv array of the child process.
416*/
417int
418w32_execvp (path, argv)
419 char *path;
420 char **argv;
421{
422 int i;
423
424 /* Required to allow a .BAT script as alternate editor. */
425 argv[0] = (char *) alternate_editor;
426
427 for (i = 0; argv[i]; i++)
428 if (strchr (argv[i], ' '))
429 {
430 char *quoted = alloca (strlen (argv[i]) + 3);
431 sprintf (quoted, "\"%s\"", argv[i]);
432 argv[i] = quoted;
433 }
434
435 return execvp (path, argv);
436}
437
438#undef execvp
439#define execvp w32_execvp
440
441#endif /* WINDOWSNT */
42073bfb
JB
442
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
JB
668
669/* Let's send the data to Emacs when either
670 - the data ends in "\n", or
671 - the buffer is full (but this shouldn't happen)
672 Otherwise, we just accumulate it. */
b03d27bd
JB
673void
674send_to_emacs (s, data)
aa0b6932
JB
675 HSOCKET s;
676 char *data;
677{
678 while (data)
2828d5f9 679 {
aa0b6932
JB
680 int dlen = strlen (data);
681 if (dlen + sblen >= SEND_BUFFER_SIZE)
682 {
683 int part = SEND_BUFFER_SIZE - sblen;
684 strncpy (&send_buffer[sblen], data, part);
685 data += part;
686 sblen = SEND_BUFFER_SIZE;
687 }
688 else if (dlen)
689 {
690 strcpy (&send_buffer[sblen], data);
691 data = NULL;
692 sblen += dlen;
693 }
694 else
695 break;
696
697 if (sblen == SEND_BUFFER_SIZE
698 || (sblen > 0 && send_buffer[sblen-1] == '\n'))
699 {
700 int sent = send (s, send_buffer, sblen, 0);
701 if (sent != sblen)
702 strcpy (send_buffer, &send_buffer[sent]);
703 sblen -= sent;
704 }
2828d5f9 705 }
2828d5f9 706}
2828d5f9
KL
707
708\f
0b0d3e0b 709/* In STR, insert a & before each &, each space, each newline, and
a4cf2096 710 any initial -. Change spaces to underscores, too, so that the
0b0d3e0b
KL
711 return value never contains a space.
712
713 Does not change the string. Outputs the result to STREAM. */
87209357 714void
974b73e8 715quote_argument (s, str)
aa0b6932 716 HSOCKET s;
0b0d3e0b 717 char *str;
5212210c 718{
9002956f 719 char *copy = (char *) xmalloc (strlen (str) * 2 + 1);
5212210c
RS
720 char *p, *q;
721
0b0d3e0b 722 p = str;
5212210c
RS
723 q = copy;
724 while (*p)
725 {
726 if (*p == ' ')
727 {
f1db6a73 728 *q++ = '&';
5212210c
RS
729 *q++ = '_';
730 p++;
731 }
3cf8c6aa
SM
732 else if (*p == '\n')
733 {
734 *q++ = '&';
735 *q++ = 'n';
736 p++;
737 }
5212210c
RS
738 else
739 {
0b0d3e0b 740 if (*p == '&' || (*p == '-' && p == str))
f1db6a73 741 *q++ = '&';
5212210c
RS
742 *q++ = *p++;
743 }
744 }
f1db6a73 745 *q++ = 0;
5212210c 746
486ba65f 747 send_to_emacs (s, copy);
87209357
EZ
748
749 free (copy);
5212210c 750}
0c76956f 751
0b0d3e0b
KL
752
753/* The inverse of quote_argument. Removes quoting in string STR by
754 modifying the string in place. Returns STR. */
755
756char *
757unquote_argument (str)
758 char *str;
759{
760 char *p, *q;
761
762 if (! str)
763 return str;
764
765 p = str;
766 q = str;
767 while (*p)
768 {
769 if (*p == '&')
770 {
771 p++;
772 if (*p == '&')
773 *p = '&';
774 else if (*p == '_')
775 *p = ' ';
776 else if (*p == 'n')
777 *p = '\n';
778 else if (*p == '-')
779 *p = '-';
780 }
781 *q++ = *p++;
782 }
783 *q = 0;
784 return str;
785}
786
8f9aaa0a 787\f
b03d27bd
JB
788int
789file_name_absolute_p (filename)
790 const unsigned char *filename;
791{
792 /* Sanity check, it shouldn't happen. */
793 if (! filename) return FALSE;
794
795 /* /xxx is always an absolute path. */
796 if (filename[0] == '/') return TRUE;
797
798 /* Empty filenames (which shouldn't happen) are relative. */
799 if (filename[0] == '\0') return FALSE;
800
801#ifdef WINDOWSNT
71b8f735 802 /* X:\xxx is always absolute. */
5f7a4874 803 if (isalpha (filename[0])
cb0297bb 804 && filename[1] == ':' && (filename[2] == '\\' || filename[2] == '/'))
b03d27bd
JB
805 return TRUE;
806
807 /* Both \xxx and \\xxx\yyy are absolute. */
808 if (filename[0] == '\\') return TRUE;
71b8f735
JB
809
810 /*
811 FIXME: There's a corner case not dealt with, "x:y", where:
812
813 1) x is a valid drive designation (usually a letter in the A-Z range)
814 and y is a path, relative to the current directory on drive x. This
815 is absolute, *after* fixing the y part to include the current
816 directory in x.
817
818 2) x is a relative file name, and y is an NTFS stream name. This is a
819 correct relative path, but it is very unusual.
820
821 The trouble is that first case items are also valid examples of the
822 second case, i.e., "c:test" can be understood as drive:path or as
823 file:stream.
824
825 The "right" fix would involve checking whether
826 - the current drive/partition is NTFS,
827 - x is a valid (and accesible) drive designator,
828 - x:y already exists as a file:stream in the current directory,
829 - y already exists on the current directory of drive x,
830 - the auspices are favorable,
831 and then taking an "informed decision" based on the above.
832
833 Whatever the result, Emacs currently does a very bad job of dealing
834 with NTFS file:streams: it cannot visit them, and the only way to
835 create one is by setting `buffer-file-name' to point to it (either
836 manually or with emacsclient). So perhaps resorting to 1) and ignoring
837 2) for now is the right thing to do.
838
839 Anyway, something to decide After the Release.
840 */
b03d27bd
JB
841#endif
842
843 return FALSE;
844}
845
aa0b6932 846#ifdef WINDOWSNT
f0384499 847/* Wrapper to make WSACleanup a cdecl, as required by atexit. */
b03d27bd
JB
848void
849__cdecl close_winsock ()
aa0b6932
JB
850{
851 WSACleanup ();
852}
0c76956f 853
b03d27bd
JB
854/* Initialize the WinSock2 library. */
855void
856initialize_sockets ()
0c76956f 857{
aa0b6932
JB
858 WSADATA wsaData;
859
aa0b6932
JB
860 if (WSAStartup (MAKEWORD (2, 0), &wsaData))
861 {
42073bfb 862 message (TRUE, "%s: error initializing WinSock2", progname);
aa0b6932
JB
863 exit (EXIT_FAILURE);
864 }
865
866 atexit (close_winsock);
0c76956f 867}
e35fc962 868#endif /* WINDOWSNT */
974b73e8 869
8f9aaa0a 870\f
97e3214d 871/*
aa0b6932 872 * Read the information needed to set up a TCP comm channel with
434a6c5d 873 * the Emacs server: host, port, pid and authentication string.
0e0dced5 874 */
b03d27bd
JB
875int
876get_server_config (server, authentication)
aa0b6932
JB
877 struct sockaddr_in *server;
878 char *authentication;
97e3214d 879{
aa0b6932
JB
880 char dotted[32];
881 char *port;
434a6c5d 882 char *pid;
b03d27bd 883 FILE *config = NULL;
aa0b6932 884
b03d27bd
JB
885 if (file_name_absolute_p (server_file))
886 config = fopen (server_file, "rb");
887 else
97e3214d 888 {
7ce8671d 889 char *home = egetenv ("HOME");
88b46d84 890
aa0b6932
JB
891 if (home)
892 {
893 char *path = alloca (32 + strlen (home) + strlen (server_file));
894 sprintf (path, "%s/.emacs.d/server/%s", home, server_file);
895 config = fopen (path, "rb");
896 }
88b46d84 897#ifdef WINDOWSNT
7ce8671d 898 if (!config && (home = egetenv ("APPDATA")))
88b46d84
JB
899 {
900 char *path = alloca (32 + strlen (home) + strlen (server_file));
901 sprintf (path, "%s/.emacs.d/server/%s", home, server_file);
902 config = fopen (path, "rb");
903 }
904#endif
aa0b6932
JB
905 }
906
907 if (! config)
908 return FALSE;
909
910 if (fgets (dotted, sizeof dotted, config)
434a6c5d
JB
911 && (port = strchr (dotted, ':'))
912 && (pid = strchr (port, ' ')))
aa0b6932
JB
913 {
914 *port++ = '\0';
434a6c5d 915 *pid++ = '\0';
97e3214d
GM
916 }
917 else
918 {
42073bfb 919 message (TRUE, "%s: invalid configuration info", progname);
65396510 920 exit (EXIT_FAILURE);
97e3214d 921 }
97e3214d 922
aa0b6932
JB
923 server->sin_family = AF_INET;
924 server->sin_addr.s_addr = inet_addr (dotted);
925 server->sin_port = htons (atoi (port));
97e3214d 926
aa0b6932
JB
927 if (! fread (authentication, AUTH_KEY_LENGTH, 1, config))
928 {
42073bfb 929 message (TRUE, "%s: cannot read authentication info", progname);
aa0b6932
JB
930 exit (EXIT_FAILURE);
931 }
46cec291 932
aa0b6932 933 fclose (config);
97e3214d 934
c66648e0 935 emacs_pid = atoi (pid);
434a6c5d 936
aa0b6932 937 return TRUE;
97e3214d
GM
938}
939
aa0b6932
JB
940HSOCKET
941set_tcp_socket ()
942{
943 HSOCKET s;
944 struct sockaddr_in server;
aa0b6932
JB
945 struct linger l_arg = {1, 1};
946 char auth_string[AUTH_KEY_LENGTH + 1];
9628b887 947
aa0b6932
JB
948 if (! get_server_config (&server, auth_string))
949 return INVALID_SOCKET;
950
b03d27bd 951 if (server.sin_addr.s_addr != inet_addr ("127.0.0.1"))
9219db75 952 message (FALSE, "%s: connected to remote socket at %s\n",
b03d27bd
JB
953 progname, inet_ntoa (server.sin_addr));
954
aa0b6932
JB
955 /*
956 * Open up an AF_INET socket
957 */
958 if ((s = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
959 {
42073bfb 960 message (TRUE, "%s: socket: %s\n", progname, strerror (errno));
aa0b6932
JB
961 return INVALID_SOCKET;
962 }
963
964 /*
965 * Set up the socket
966 */
967 if (connect (s, (struct sockaddr *) &server, sizeof server) < 0)
968 {
42073bfb 969 message (TRUE, "%s: connect: %s\n", progname, strerror (errno));
aa0b6932
JB
970 return INVALID_SOCKET;
971 }
972
aa0b6932
JB
973 setsockopt (s, SOL_SOCKET, SO_LINGER, (char *) &l_arg, sizeof l_arg);
974
975 /*
976 * Send the authentication
977 */
978 auth_string[AUTH_KEY_LENGTH] = '\0';
979
486ba65f
JR
980 send_to_emacs (s, "-auth ");
981 send_to_emacs (s, auth_string);
982 send_to_emacs (s, "\n");
aa0b6932
JB
983
984 return s;
985}
986
b2ff54a0
JR
987
988/* Returns 1 if PREFIX is a prefix of STRING. */
989static int
990strprefix (char *prefix, char *string)
991{
cb06b8dc 992 return !strncmp (prefix, string, strlen (prefix));
b2ff54a0
JR
993}
994
995
aa0b6932 996#if !defined (NO_SOCKETS_IN_FILE_SYSTEM)
46cec291 997
9f637eea
GM
998/* Three possibilities:
999 2 - can't be `stat'ed (sets errno)
1000 1 - isn't owned by us
1001 0 - success: none of the above */
1002
1003static int
1004socket_status (socket_name)
1005 char *socket_name;
1006{
1007 struct stat statbfr;
1008
1009 if (stat (socket_name, &statbfr) == -1)
1010 return 2;
1011
1012 if (statbfr.st_uid != geteuid ())
1013 return 1;
0b0d3e0b 1014
9f637eea
GM
1015 return 0;
1016}
1017
974b73e8 1018\f
da8e1115
KL
1019/* A signal handler that passes the signal to the Emacs process.
1020 Useful for SIGWINCH. */
1021
9628b887 1022SIGTYPE
428a555e 1023pass_signal_to_emacs (int signalnum)
9628b887
KL
1024{
1025 int old_errno = errno;
1026
9f729af5 1027 if (emacs_pid)
428a555e 1028 kill (emacs_pid, signalnum);
9f729af5 1029
428a555e 1030 signal (signalnum, pass_signal_to_emacs);
9f729af5
KL
1031 errno = old_errno;
1032}
1033
0b0d3e0b
KL
1034/* Signal handler for SIGCONT; notify the Emacs process that it can
1035 now resume our tty frame. */
1036
1037SIGTYPE
1038handle_sigcont (int signalnum)
1039{
1040 int old_errno = errno;
1041
1042 if (tcgetpgrp (1) == getpgrp ())
1043 {
1044 /* We are in the foreground. */
486ba65f 1045 send_to_emacs (emacs_socket, "-resume \n");
0b0d3e0b
KL
1046 }
1047 else
1048 {
1049 /* We are in the background; cancel the continue. */
1050 kill (getpid (), SIGSTOP);
1051 }
c6c53c3e
KL
1052
1053 signal (signalnum, handle_sigcont);
0b0d3e0b
KL
1054 errno = old_errno;
1055}
1056
1057/* Signal handler for SIGTSTP; notify the Emacs process that we are
1058 going to sleep. Normally the suspend is initiated by Emacs via
1059 server-handle-suspend-tty, but if the server gets out of sync with
1060 reality, we may get a SIGTSTP on C-z. Handling this signal and
1061 notifying Emacs about it should get things under control again. */
1062
1063SIGTYPE
1064handle_sigtstp (int signalnum)
1065{
1066 int old_errno = errno;
1067 sigset_t set;
c0f342ab 1068
90843190 1069 if (emacs_socket)
486ba65f 1070 send_to_emacs (emacs_socket, "-suspend \n");
0b0d3e0b
KL
1071
1072 /* Unblock this signal and call the default handler by temprarily
1073 changing the handler and resignalling. */
1074 sigprocmask (SIG_BLOCK, NULL, &set);
1075 sigdelset (&set, signalnum);
1076 signal (signalnum, SIG_DFL);
1077 kill (getpid (), signalnum);
1078 sigprocmask (SIG_SETMASK, &set, NULL); /* Let's the above signal through. */
1079 signal (signalnum, handle_sigtstp);
1080
1081 errno = old_errno;
1082}
da8e1115 1083/* Set up signal handlers before opening a frame on the current tty. */
0b0d3e0b 1084
4d553a13
KL
1085void
1086init_signals (void)
9628b887
KL
1087{
1088 /* Set up signal handlers. */
428a555e 1089 signal (SIGWINCH, pass_signal_to_emacs);
4ca927b4
KL
1090
1091 /* Don't pass SIGINT and SIGQUIT to Emacs, because it has no way of
1092 deciding which terminal the signal came from. C-g is now a
1093 normal input event on secondary terminals. */
1094#if 0
428a555e
KL
1095 signal (SIGINT, pass_signal_to_emacs);
1096 signal (SIGQUIT, pass_signal_to_emacs);
4ca927b4 1097#endif
0b0d3e0b
KL
1098
1099 signal (SIGCONT, handle_sigcont);
1100 signal (SIGTSTP, handle_sigtstp);
1101 signal (SIGTTOU, handle_sigtstp);
9628b887
KL
1102}
1103
46cec291 1104
aa0b6932
JB
1105HSOCKET
1106set_local_socket ()
46cec291 1107{
aa0b6932 1108 HSOCKET s;
46cec291 1109 struct sockaddr_un server;
46cec291 1110
e69233c2 1111 /*
46cec291
RS
1112 * Open up an AF_UNIX socket in this person's home directory
1113 */
1114
1115 if ((s = socket (AF_UNIX, SOCK_STREAM, 0)) < 0)
1116 {
42073bfb 1117 message (TRUE, "%s: socket: %s\n", progname, strerror (errno));
aa0b6932 1118 return INVALID_SOCKET;
46cec291 1119 }
e69233c2 1120
46cec291 1121 server.sun_family = AF_UNIX;
c5fee545 1122
c5fee545 1123 {
9f637eea 1124 int sock_status = 0;
5c9659d3 1125 int default_sock = !socket_name;
b80bf66e 1126 int saved_errno = 0;
0734b0d0 1127 char *server_name = "server";
0b0d3e0b 1128
0734b0d0
SM
1129 if (socket_name && !index (socket_name, '/') && !index (socket_name, '\\'))
1130 { /* socket_name is a file name component. */
d3a6748c
KL
1131 server_name = socket_name;
1132 socket_name = NULL;
1133 default_sock = 1; /* Try both UIDs. */
0734b0d0 1134 }
efb859b4 1135
5c9659d3 1136 if (default_sock)
254107e4 1137 {
d3a6748c
KL
1138 socket_name = alloca (100 + strlen (server_name));
1139 sprintf (socket_name, "/tmp/emacs%d/%s",
1140 (int) geteuid (), server_name);
254107e4
RS
1141 }
1142
1143 if (strlen (socket_name) < sizeof (server.sun_path))
1144 strcpy (server.sun_path, socket_name);
1145 else
819b8f00 1146 {
974b73e8
KL
1147 message (TRUE, "%s: socket-name %s too long",
1148 progname, socket_name);
819b8f00
KL
1149 fail ();
1150 }
efb859b4 1151
9f637eea
GM
1152 /* See if the socket exists, and if it's owned by us. */
1153 sock_status = socket_status (server.sun_path);
152b6e83 1154 saved_errno = errno;
5c9659d3 1155 if (sock_status && default_sock)
efb859b4 1156 {
9f637eea
GM
1157 /* Failing that, see if LOGNAME or USER exist and differ from
1158 our euid. If so, look for a socket based on the UID
1159 associated with the name. This is reminiscent of the logic
1160 that init_editfns uses to set the global Vuser_full_name. */
e69233c2 1161
7ce8671d 1162 char *user_name = (char *) egetenv ("LOGNAME");
293f9f2a 1163
9f637eea 1164 if (!user_name)
7ce8671d 1165 user_name = (char *) egetenv ("USER");
e69233c2 1166
9f637eea
GM
1167 if (user_name)
1168 {
1169 struct passwd *pw = getpwnam (user_name);
293f9f2a 1170
9f637eea
GM
1171 if (pw && (pw->pw_uid != geteuid ()))
1172 {
1173 /* We're running under su, apparently. */
0734b0d0
SM
1174 socket_name = alloca (100 + strlen (server_name));
1175 sprintf (socket_name, "/tmp/emacs%d/%s",
1176 (int) pw->pw_uid, server_name);
5c9659d3
SM
1177
1178 if (strlen (socket_name) < sizeof (server.sun_path))
1179 strcpy (server.sun_path, socket_name);
1180 else
1181 {
42073bfb 1182 message (TRUE, "%s: socket-name %s too long",
aa0b6932 1183 progname, socket_name);
65396510 1184 exit (EXIT_FAILURE);
5c9659d3
SM
1185 }
1186
9f637eea 1187 sock_status = socket_status (server.sun_path);
b80bf66e 1188 saved_errno = errno;
9f637eea 1189 }
293f9f2a
RS
1190 else
1191 errno = saved_errno;
9f637eea 1192 }
efb859b4 1193 }
e69233c2 1194
aa0b6932
JB
1195 switch (sock_status)
1196 {
1197 case 1:
974b73e8
KL
1198 /* There's a socket, but it isn't owned by us. This is OK if
1199 we are root. */
1200 if (0 != geteuid ())
1201 {
1202 message (TRUE, "%s: Invalid socket owner\n", progname);
aa0b6932 1203 return INVALID_SOCKET;
974b73e8
KL
1204 }
1205 break;
aa0b6932
JB
1206
1207 case 2:
974b73e8
KL
1208 /* `stat' failed */
1209 if (saved_errno == ENOENT)
1210 message (TRUE,
1211 "%s: can't find socket; have you started the server?\n\
45adde32 1212To start the server in Emacs, type \"M-x server-start\".\n",
aa0b6932 1213 progname);
974b73e8
KL
1214 else
1215 message (TRUE, "%s: can't stat %s: %s\n",
aa0b6932 1216 progname, server.sun_path, strerror (saved_errno));
974b73e8 1217 return INVALID_SOCKET;
aa0b6932 1218 }
efb859b4 1219 }
46cec291 1220
4e23f2ba
JB
1221 if (connect (s, (struct sockaddr *) &server, strlen (server.sun_path) + 2)
1222 < 0)
46cec291 1223 {
42073bfb 1224 message (TRUE, "%s: connect: %s\n", progname, strerror (errno));
aa0b6932 1225 return INVALID_SOCKET;
46cec291 1226 }
23a7488d 1227
aa0b6932
JB
1228 return s;
1229}
1230#endif /* ! NO_SOCKETS_IN_FILE_SYSTEM */
1231
1232HSOCKET
1233set_socket ()
1234{
b03d27bd 1235 HSOCKET s;
c0f342ab 1236
b03d27bd 1237 INITIALIZE ();
c0f342ab 1238
aa0b6932 1239#ifndef NO_SOCKETS_IN_FILE_SYSTEM
b03d27bd
JB
1240 /* Explicit --socket-name argument. */
1241 if (socket_name)
46cec291 1242 {
b03d27bd
JB
1243 s = set_local_socket ();
1244 if ((s != INVALID_SOCKET) || alternate_editor)
974b73e8 1245 return s;
42073bfb 1246 message (TRUE, "%s: error accessing socket \"%s\"",
974b73e8 1247 progname, socket_name);
b03d27bd 1248 exit (EXIT_FAILURE);
46cec291 1249 }
b03d27bd
JB
1250#endif
1251
1252 /* Explicit --server-file arg or EMACS_SERVER_FILE variable. */
1253 if (!server_file)
7ce8671d 1254 server_file = egetenv ("EMACS_SERVER_FILE");
46cec291 1255
b03d27bd 1256 if (server_file)
23a7488d 1257 {
b03d27bd
JB
1258 s = set_tcp_socket ();
1259 if ((s != INVALID_SOCKET) || alternate_editor)
974b73e8 1260 return s;
c0f342ab 1261
42073bfb 1262 message (TRUE, "%s: error accessing server file \"%s\"",
974b73e8 1263 progname, server_file);
b03d27bd 1264 exit (EXIT_FAILURE);
23a7488d 1265 }
c0f342ab 1266
b03d27bd
JB
1267#ifndef NO_SOCKETS_IN_FILE_SYSTEM
1268 /* Implicit local socket. */
1269 s = set_local_socket ();
1270 if (s != INVALID_SOCKET)
1271 return s;
1272#endif
23a7488d 1273
b03d27bd
JB
1274 /* Implicit server file. */
1275 server_file = "server";
1276 s = set_tcp_socket ();
1277 if ((s != INVALID_SOCKET) || alternate_editor)
1278 return s;
1279
1280 /* No implicit or explicit socket, and no alternate editor. */
42073bfb 1281 message (TRUE, "%s: No socket or alternate editor. Please use:\n\n"
b03d27bd
JB
1282#ifndef NO_SOCKETS_IN_FILE_SYSTEM
1283"\t--socket-name\n"
ee6a193c 1284#endif
b03d27bd
JB
1285"\t--server-file (or environment variable EMACS_SERVER_FILE)\n\
1286\t--alternate-editor (or environment variable ALTERNATE_EDITOR)\n",
1287 progname);
1288 exit (EXIT_FAILURE);
aa0b6932 1289}
46cec291 1290
0e0dced5
JB
1291#ifdef WINDOWSNT
1292FARPROC set_fg; /* Pointer to AllowSetForegroundWindow. */
1293FARPROC get_wc; /* Pointer to RealGetWindowClassA. */
1294
1295BOOL CALLBACK
1296w32_find_emacs_process (hWnd, lParam)
1297 HWND hWnd;
1298 LPARAM lParam;
1299{
1300 DWORD pid;
1301 char class[6];
1302
1303 /* Reject any window not of class "Emacs". */
1304 if (! get_wc (hWnd, class, sizeof (class))
1305 || strcmp (class, "Emacs"))
1306 return TRUE;
1307
1308 /* We only need the process id, not the thread id. */
1309 (void) GetWindowThreadProcessId (hWnd, &pid);
1310
1311 /* Not the one we're looking for. */
1312 if (pid != (DWORD) emacs_pid) return TRUE;
1313
1314 /* OK, let's raise it. */
1315 set_fg (emacs_pid);
1316
1317 /* Stop enumeration. */
1318 return FALSE;
1319}
1320
1321/*
1322 * Search for a window of class "Emacs" and owned by a process with
1323 * process id = emacs_pid. If found, allow it to grab the focus.
1324 */
1325void
1326w32_give_focus ()
1327{
1328 HMODULE hUser32;
1329
71b8f735 1330 /* It shouldn't happen when dealing with TCP sockets. */
0e0dced5
JB
1331 if (!emacs_pid) return;
1332
1333 if (!(hUser32 = LoadLibrary ("user32.dll"))) return;
1334
1335 /* Modern Windows restrict which processes can set the foreground window.
1336 emacsclient can allow Emacs to grab the focus by calling the function
1337 AllowSetForegroundWindow. Unfortunately, older Windows (W95, W98 and
1338 NT) lack this function, so we have to check its availability. */
1339 if ((set_fg = GetProcAddress (hUser32, "AllowSetForegroundWindow"))
1340 && (get_wc = GetProcAddress (hUser32, "RealGetWindowClassA")))
1341 EnumWindows (w32_find_emacs_process, (LPARAM) 0);
1342
1343 FreeLibrary (hUser32);
1344}
1345#endif
1346
aa0b6932
JB
1347int
1348main (argc, argv)
1349 int argc;
1350 char **argv;
1351{
aa0b6932 1352 int i, rl, needlf = 0;
974b73e8 1353 char *cwd, *str;
aa0b6932
JB
1354 char string[BUFSIZ+1];
1355
974b73e8 1356 main_argv = argv;
aa0b6932
JB
1357 progname = argv[0];
1358
1359 /* Process options. */
1360 decode_options (argc, argv);
1361
974b73e8 1362 if ((argc - optind < 1) && !eval && !tty && !window_system)
23a7488d 1363 {
974b73e8
KL
1364 message (TRUE, "%s: file name or argument required\n"
1365 "Try `%s --help' for more information\n",
1366 progname, progname);
aa0b6932 1367 exit (EXIT_FAILURE);
23a7488d
RS
1368 }
1369
4b7b77f6 1370 if ((emacs_socket = set_socket ()) == INVALID_SOCKET)
974b73e8 1371 fail ();
aa0b6932 1372
974b73e8
KL
1373
1374 cwd = get_current_dir_name ();
46cec291
RS
1375 if (cwd == 0)
1376 {
1377 /* getwd puts message in STRING if it fails. */
974b73e8
KL
1378 message (TRUE, "%s: %s\n", progname,
1379 "Cannot get current working directory");
819b8f00 1380 fail ();
46cec291
RS
1381 }
1382
c66648e0 1383#ifdef WINDOWSNT
0e0dced5 1384 w32_give_focus ();
c66648e0
JB
1385#endif
1386
9002956f 1387 /* Send over our environment. */
59e085e0
KL
1388 if (!current_frame)
1389 {
1390 extern char **environ;
1391 int i;
1392 for (i = 0; environ[i]; i++)
1393 {
1394 char *name = xstrdup (environ[i]);
1395 char *value = strchr (name, '=');
486ba65f
JR
1396 send_to_emacs (emacs_socket, "-env ");
1397 quote_argument (emacs_socket, environ[i]);
1398 send_to_emacs (emacs_socket, " ");
59e085e0
KL
1399 }
1400 }
9002956f 1401
2828d5f9
KL
1402 /* Send over our current directory. */
1403 if (!current_frame)
1404 {
486ba65f
JR
1405 send_to_emacs (emacs_socket, "-dir ");
1406 quote_argument (emacs_socket, cwd);
1407 send_to_emacs (emacs_socket, "/");
1408 send_to_emacs (emacs_socket, " ");
2828d5f9
KL
1409 }
1410
6afdd335 1411 retry:
5212210c 1412 if (nowait)
486ba65f 1413 send_to_emacs (emacs_socket, "-nowait ");
292d74a3 1414
92071250 1415 if (current_frame)
486ba65f 1416 send_to_emacs (emacs_socket, "-current-frame ");
c0f342ab 1417
30be2360 1418 if (display)
87209357 1419 {
486ba65f
JR
1420 send_to_emacs (emacs_socket, "-display ");
1421 quote_argument (emacs_socket, display);
1422 send_to_emacs (emacs_socket, " ");
87209357 1423 }
30be2360 1424
77134727 1425 if (tty)
9628b887 1426 {
7ce8671d 1427 char *type = egetenv ("TERM");
b2ff54a0
JR
1428 char *tty_name = NULL;
1429#ifndef WINDOWSNT
1430 tty_name = ttyname (fileno (stdin));
1431#endif
0b0d3e0b 1432
4d553a13 1433 if (! tty_name)
2fc0cf2a 1434 {
974b73e8 1435 message (TRUE, "%s: could not get terminal name\n", progname);
2fc0cf2a
KL
1436 fail ();
1437 }
1438
1439 if (! type)
1440 {
974b73e8 1441 message (TRUE, "%s: please set the TERM variable to your terminal type\n",
2fc0cf2a
KL
1442 progname);
1443 fail ();
1444 }
1445
1446 if (! strcmp (type, "eterm"))
1447 {
1448 /* This causes nasty, MULTI_KBOARD-related input lockouts. */
974b73e8 1449 message (TRUE, "%s: opening a frame in an Emacs term buffer"
2fc0cf2a
KL
1450 " is not supported\n", progname);
1451 fail ();
1452 }
b2ff54a0 1453#if !defined (NO_SOCKETS_IN_FILE_SYSTEM)
4d553a13 1454 init_signals ();
b2ff54a0 1455#endif
0b0d3e0b 1456
486ba65f
JR
1457 send_to_emacs (emacs_socket, "-tty ");
1458 quote_argument (emacs_socket, tty_name);
1459 send_to_emacs (emacs_socket, " ");
1460 quote_argument (emacs_socket, type);
1461 send_to_emacs (emacs_socket, " ");
9628b887 1462 }
77134727
KL
1463
1464 if (window_system)
486ba65f 1465 send_to_emacs (emacs_socket, "-window-system ");
0b0d3e0b 1466
87209357 1467 if ((argc - optind > 0))
5212210c 1468 {
87209357 1469 for (i = optind; i < argc; i++)
46cec291 1470 {
0b0d3e0b
KL
1471 int relative = 0;
1472
87209357 1473 if (eval)
0b0d3e0b 1474 {
974b73e8 1475 /* Don't prepend cwd or anything like that. */
486ba65f
JR
1476 send_to_emacs (emacs_socket, "-eval ");
1477 quote_argument (emacs_socket, argv[i]);
1478 send_to_emacs (emacs_socket, " ");
0b0d3e0b
KL
1479 continue;
1480 }
1481
1482 if (*argv[i] == '+')
1483 {
87209357
EZ
1484 char *p = argv[i] + 1;
1485 while (isdigit ((unsigned char) *p) || *p == ':') p++;
0b0d3e0b
KL
1486 if (*p == 0)
1487 {
486ba65f
JR
1488 send_to_emacs (emacs_socket, "-position ");
1489 quote_argument (emacs_socket, argv[i]);
1490 send_to_emacs (emacs_socket, " ");
0b0d3e0b
KL
1491 continue;
1492 }
1493 else
1494 relative = 1;
1495 }
b03d27bd 1496 else if (! file_name_absolute_p (argv[i]))
0b0d3e0b
KL
1497 relative = 1;
1498
486ba65f 1499 send_to_emacs (emacs_socket, "-file ");
0b0d3e0b
KL
1500 if (relative)
1501 {
486ba65f
JR
1502 quote_argument (emacs_socket, cwd);
1503 send_to_emacs (emacs_socket, "/");
0b0d3e0b 1504 }
486ba65f
JR
1505 quote_argument (emacs_socket, argv[i]);
1506 send_to_emacs (emacs_socket, " ");
0b0d3e0b 1507 }
46cec291 1508 }
87209357
EZ
1509 else
1510 {
77134727 1511 if (!tty && !window_system)
9628b887
KL
1512 {
1513 while ((str = fgets (string, BUFSIZ, stdin)))
1514 {
0b0d3e0b 1515 if (eval)
486ba65f 1516 send_to_emacs (emacs_socket, "-eval ");
0b0d3e0b 1517 else
486ba65f
JR
1518 send_to_emacs (emacs_socket, "-file ");
1519 quote_argument (emacs_socket, str);
9628b887 1520 }
486ba65f 1521 send_to_emacs (emacs_socket, " ");
9628b887 1522 }
87209357 1523 }
0b0d3e0b 1524
486ba65f 1525 send_to_emacs (emacs_socket, "\n");
46cec291 1526
fc2040c0
KL
1527 /* Wait for an answer. */
1528 if (!eval && !tty && !nowait)
30be2360
SM
1529 {
1530 printf ("Waiting for Emacs...");
1531 needlf = 2;
1532 }
46cec291 1533 fflush (stdout);
0b0d3e0b 1534 fsync (1);
46cec291 1535
3cf8c6aa 1536 /* Now, wait for an answer and print any messages. */
4b7b77f6 1537 while ((rl = recv (emacs_socket, string, BUFSIZ, 0)) > 0)
3cf8c6aa 1538 {
974b73e8
KL
1539 char *p;
1540 string[rl] = '\0';
1541
1542 p = string + strlen (string) - 1;
1543 while (p > string && *p == '\n')
0b0d3e0b
KL
1544 *p-- = 0;
1545
31fa6595 1546 if (strprefix ("-emacs-pid ", string))
4d553a13 1547 {
6afdd335 1548 /* -emacs-pid PID: The process id of the Emacs process. */
77134727
KL
1549 emacs_pid = strtol (string + strlen ("-emacs-pid"), NULL, 10);
1550 }
974b73e8 1551 else if (strprefix ("-window-system-unsupported ", string))
6afdd335
KL
1552 {
1553 /* -window-system-unsupported: Emacs was compiled without X
1554 support. Try again on the terminal. */
1555 window_system = 0;
1556 nowait = 0;
1557 tty = 1;
1558 goto retry;
1559 }
974b73e8 1560 else if (strprefix ("-print ", string))
77134727 1561 {
6afdd335 1562 /* -print STRING: Print STRING on the terminal. */
974b73e8 1563 str = unquote_argument (string + strlen ("-print "));
0b0d3e0b 1564 if (needlf)
77134727 1565 printf ("\n");
0b0d3e0b
KL
1566 printf ("%s", str);
1567 needlf = str[0] == '\0' ? needlf : str[strlen (str) - 1] != '\n';
77134727 1568 }
974b73e8 1569 else if (strprefix ("-error ", string))
77134727 1570 {
6afdd335 1571 /* -error DESCRIPTION: Signal an error on the terminal. */
974b73e8 1572 str = unquote_argument (string + strlen ("-error "));
0b0d3e0b
KL
1573 if (needlf)
1574 printf ("\n");
974b73e8 1575 fprintf (stderr, "*ERROR*: %s", str);
0b0d3e0b
KL
1576 needlf = str[0] == '\0' ? needlf : str[strlen (str) - 1] != '\n';
1577 }
c801ad51 1578#ifdef SIGSTOP
382707ec 1579 else if (strprefix ("-suspend ", string))
0b0d3e0b 1580 {
6afdd335 1581 /* -suspend: Suspend this terminal, i.e., stop the process. */
0b0d3e0b 1582 if (needlf)
77134727 1583 printf ("\n");
0b0d3e0b
KL
1584 needlf = 0;
1585 kill (0, SIGSTOP);
4d553a13 1586 }
b2ff54a0 1587#endif
4d553a13
KL
1588 else
1589 {
6afdd335 1590 /* Unknown command. */
0b0d3e0b 1591 if (needlf)
4d553a13 1592 printf ("\n");
974b73e8
KL
1593 printf ("*ERROR*: Unknown message: %s", string);
1594 needlf = string[0] == '\0' ? needlf : string[strlen (string) - 1] != '\n';
4d553a13 1595 }
3cf8c6aa
SM
1596 }
1597
1598 if (needlf)
1599 printf ("\n");
1600 fflush (stdout);
0b0d3e0b 1601 fsync (1);
23a7488d 1602
4b7b77f6 1603 CLOSE_SOCKET (emacs_socket);
65396510 1604 return EXIT_SUCCESS;
46cec291
RS
1605}
1606
1e7823d0 1607#endif /* HAVE_SOCKETS && HAVE_INET_SOCKETS */
aa0b6932 1608
27711600
RM
1609\f
1610#ifndef HAVE_STRERROR
1611char *
1612strerror (errnum)
1613 int errnum;
1614{
1615 extern char *sys_errlist[];
1616 extern int sys_nerr;
1617
1618 if (errnum >= 0 && errnum < sys_nerr)
1619 return sys_errlist[errnum];
1620 return (char *) "Unknown error";
1621}
1622
1623#endif /* ! HAVE_STRERROR */
ab5796a9
MB
1624
1625/* arch-tag: f39bb9c4-73eb-477e-896d-50832e2ca9a7
1626 (do not change this comment) */
65396510
TTN
1627
1628/* emacsclient.c ends here */