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