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