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