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