(w32_window_app): Init common controls when windowed.
[bpt/emacs.git] / lib-src / emacsclient.c
CommitLineData
efb859b4 1/* Client process that communicates with GNU Emacs acting as server.
92b47a4a 2 Copyright (C) 1986, 1987, 1994, 1999, 2000, 2001, 2002, 2003, 2004,
4e6835db 3 2005, 2006, 2007 Free Software Foundation, Inc.
46cec291
RS
4
5This file is part of GNU Emacs.
6
7GNU Emacs is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
4a9f99bd 9the Free Software Foundation; either version 3, or (at your option)
46cec291
RS
10any later version.
11
12GNU Emacs is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GNU Emacs; see the file COPYING. If not, write to
364c38d3
LK
19the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20Boston, MA 02110-1301, USA. */
46cec291
RS
21
22
23#define NO_SHORTNAMES
e69233c2
PJ
24
25#ifdef HAVE_CONFIG_H
2f8fe2f4 26#include <config.h>
e69233c2
PJ
27#endif
28
aa0b6932 29#ifdef WINDOWSNT
aa0b6932 30
bc28de71
JB
31/* config.h defines these, which disables sockets altogether! */
32# undef _WINSOCKAPI_
33# undef _WINSOCK_H
34
411b80a5
JB
35# include <malloc.h>
36# include <stdlib.h>
42073bfb 37# include <windows.h>
dbf60b07 38# include <commctrl.h>
411b80a5 39
411b80a5
JB
40# define NO_SOCKETS_IN_FILE_SYSTEM
41
aa0b6932
JB
42# define HSOCKET SOCKET
43# define CLOSE_SOCKET closesocket
aa0b6932 44# define INITIALIZE() (initialize_sockets ())
411b80a5
JB
45
46#else /* !WINDOWSNT */
47
ed4a3730
JB
48# include <sys/types.h>
49
1e7823d0
JB
50# ifdef HAVE_INET_SOCKETS
51# include <netinet/in.h>
52# endif
411b80a5 53
e35fc962 54# define INVALID_SOCKET -1
aa0b6932
JB
55# define HSOCKET int
56# define CLOSE_SOCKET close
aa0b6932 57# define INITIALIZE()
411b80a5
JB
58
59#endif /* !WINDOWSNT */
aa0b6932 60
4e23f2ba 61#undef signal
46cec291 62
42073bfb 63#include <stdarg.h>
e69233c2 64#include <ctype.h>
8f9aaa0a 65#include <stdio.h>
aa0b6932 66#include "getopt.h"
79f13bba
DL
67#ifdef HAVE_UNISTD_H
68#include <unistd.h>
69#endif
8f9aaa0a 70
9f637eea
GM
71#ifdef VMS
72# include "vms-pwd.h"
aa0b6932
JB
73#else /* not VMS */
74#ifdef WINDOWSNT
75# include <io.h>
76#else /* not WINDOWSNT */
9f637eea 77# include <pwd.h>
aa0b6932 78#endif /* not WINDOWSNT */
9f637eea
GM
79#endif /* not VMS */
80
8f9aaa0a 81char *getenv (), *getwd ();
5b9562c3 82char *(getcwd) ();
8f9aaa0a 83
8f9aaa0a
RS
84#ifndef VERSION
85#define VERSION "unspecified"
86#endif
87\f
aa0b6932
JB
88#define SEND_STRING(data) (send_to_emacs (s, (data)))
89#define SEND_QUOTED(data) (quote_file_name (s, (data)))
90
91#ifndef EXIT_SUCCESS
92#define EXIT_SUCCESS 0
93#endif
94
95#ifndef EXIT_FAILURE
96#define EXIT_FAILURE 1
97#endif
98
99#ifndef FALSE
100#define FALSE 0
101#endif
102
103#ifndef TRUE
104#define TRUE 1
105#endif
106
107#ifndef NO_RETURN
108#define NO_RETURN
109#endif
110\f
8f9aaa0a
RS
111/* Name used to invoke this program. */
112char *progname;
113
749ae770 114/* Nonzero means don't wait for a response from Emacs. --no-wait. */
8f9aaa0a
RS
115int nowait = 0;
116
30be2360
SM
117/* Nonzero means args are expressions to be evaluated. --eval. */
118int eval = 0;
119
120/* The display on which Emacs should work. --display. */
121char *display = NULL;
122
123/* If non-NULL, the name of an editor to fallback to if the server
124 is not running. --alternate-editor. */
b03d27bd 125const char *alternate_editor = NULL;
30be2360 126
3db926be 127/* If non-NULL, the filename of the UNIX socket. */
254107e4
RS
128char *socket_name = NULL;
129
aa0b6932
JB
130/* If non-NULL, the filename of the authentication file. */
131char *server_file = NULL;
132
c66648e0
JB
133/* PID of the Emacs server process. */
134int emacs_pid = 0;
135
2381d38d 136void print_help_and_exit () NO_RETURN;
7f3bff3e 137
8f9aaa0a
RS
138struct option longopts[] =
139{
749ae770 140 { "no-wait", no_argument, NULL, 'n' },
30be2360 141 { "eval", no_argument, NULL, 'e' },
8f9aaa0a
RS
142 { "help", no_argument, NULL, 'H' },
143 { "version", no_argument, NULL, 'V' },
3cf8c6aa 144 { "alternate-editor", required_argument, NULL, 'a' },
b03d27bd 145#ifndef NO_SOCKETS_IN_FILE_SYSTEM
254107e4 146 { "socket-name", required_argument, NULL, 's' },
b03d27bd 147#endif
aa0b6932 148 { "server-file", required_argument, NULL, 'f' },
30be2360
SM
149 { "display", required_argument, NULL, 'd' },
150 { 0, 0, 0, 0 }
8f9aaa0a
RS
151};
152
42073bfb
JB
153/* Message functions. */
154
155#ifdef WINDOWSNT
42073bfb 156int
f0384499 157w32_window_app ()
42073bfb
JB
158{
159 static int window_app = -1;
160 char szTitle[MAX_PATH];
161
162 if (window_app < 0)
dbf60b07
JR
163 {
164 /* Checking for STDOUT does not work; it's a valid handle also in
165 nonconsole apps. Testing for the console title seems to work. */
166 window_app = (GetConsoleTitleA (szTitle, MAX_PATH) == 0);
167 if (window_app)
168 InitCommonControls();
169 }
42073bfb
JB
170
171 return window_app;
172}
173#endif
174
175void
176message (int is_error, char *message, ...)
177{
c66648e0 178 char msg [2048];
42073bfb
JB
179 va_list args;
180
181 va_start (args, message);
42073bfb
JB
182 vsprintf (msg, message, args);
183 va_end (args);
184
185#ifdef WINDOWSNT
186 if (w32_window_app ())
187 {
188 if (is_error)
189 MessageBox (NULL, msg, "Emacsclient ERROR", MB_ICONERROR);
190 else
191 MessageBox (NULL, msg, "Emacsclient", MB_ICONINFORMATION);
192 }
193 else
194#endif
9219db75
JB
195 {
196 FILE *f = is_error ? stderr : stdout;
197
198 fputs (msg, f);
199 fflush (f);
200 }
42073bfb
JB
201}
202
8f9aaa0a 203/* Decode the options from argv and argc.
5212210c 204 The global variable `optind' will say how many arguments we used up. */
8f9aaa0a 205
5212210c 206void
8f9aaa0a
RS
207decode_options (argc, argv)
208 int argc;
209 char **argv;
210{
b6b6d6d2
SM
211 alternate_editor = getenv ("ALTERNATE_EDITOR");
212
8f9aaa0a
RS
213 while (1)
214 {
215 int opt = getopt_long (argc, argv,
b03d27bd
JB
216#ifndef NO_SOCKETS_IN_FILE_SYSTEM
217 "VHnea:s:f:d:",
218#else
219 "VHnea:f:d:",
220#endif
221 longopts, 0);
8f9aaa0a
RS
222
223 if (opt == EOF)
224 break;
225
226 switch (opt)
227 {
228 case 0:
229 /* If getopt returns 0, then it has already processed a
230 long-named option. We should do nothing. */
231 break;
e69233c2 232
97e3214d
GM
233 case 'a':
234 alternate_editor = optarg;
235 break;
e69233c2 236
b03d27bd 237#ifndef NO_SOCKETS_IN_FILE_SYSTEM
254107e4
RS
238 case 's':
239 socket_name = optarg;
240 break;
b03d27bd 241#endif
254107e4 242
aa0b6932
JB
243 case 'f':
244 server_file = optarg;
245 break;
246
30be2360
SM
247 case 'd':
248 display = optarg;
249 break;
250
8f9aaa0a
RS
251 case 'n':
252 nowait = 1;
253 break;
254
30be2360
SM
255 case 'e':
256 eval = 1;
257 break;
258
8f9aaa0a 259 case 'V':
42073bfb 260 message (FALSE, "emacsclient %s\n", VERSION);
65396510 261 exit (EXIT_SUCCESS);
8f9aaa0a 262 break;
46cec291 263
8f9aaa0a 264 case 'H':
8f9aaa0a 265 print_help_and_exit ();
20c396e8
JB
266 break;
267
268 default:
42073bfb 269 message (TRUE, "Try `%s --help' for more information\n", progname);
65396510 270 exit (EXIT_FAILURE);
20c396e8 271 break;
8f9aaa0a
RS
272 }
273 }
8f9aaa0a
RS
274}
275
7f3bff3e 276void
8f9aaa0a
RS
277print_help_and_exit ()
278{
42073bfb 279 message (FALSE,
20c396e8 280 "Usage: %s [OPTIONS] FILE...\n\
30be2360
SM
281Tell the Emacs server to visit the specified files.\n\
282Every FILE can be either just a FILENAME or [+LINE[:COLUMN]] FILENAME.\n\
20c396e8 283\n\
30be2360 284The following OPTIONS are accepted:\n\
30aa95ce
JB
285\n\
286-V, --version Just print version info and return\n\
287-H, --help Print this usage information message\n\
288-e, --eval Evaluate FILE arguments as Lisp expressions\n\
289-n, --no-wait Don't wait for the server to return\n\
290-d, --display=DISPLAY Visit the file in the given display\n"
aa0b6932
JB
291#ifndef NO_SOCKETS_IN_FILE_SYSTEM
292"-s, --socket-name=FILENAME\n\
30aa95ce 293 Set filename of the UNIX socket for communication\n"
aa0b6932
JB
294#endif
295"-f, --server-file=FILENAME\n\
30aa95ce 296 Set filename of the TCP authentication file\n\
30be2360 297-a, --alternate-editor=EDITOR\n\
30aa95ce 298 Editor to fallback to if server is not running\n\
20c396e8 299\n\
30be2360 300Report bugs to bug-gnu-emacs@gnu.org.\n", progname);
65396510 301 exit (EXIT_SUCCESS);
8f9aaa0a 302}
5212210c 303
aa0b6932 304\f
4472aef4
JB
305#ifdef WINDOWSNT
306
307/*
f0384499 308 execvp wrapper for Windows. Quotes arguments with embedded spaces.
4472aef4
JB
309
310 This is necessary due to the broken implementation of exec* routines in
311 the Microsoft libraries: they concatenate the arguments together without
312 quoting special characters, and pass the result to CreateProcess, with
313 predictably bad results. By contrast, Posix execvp passes the arguments
f0384499 314 directly into the argv array of the child process.
4472aef4
JB
315*/
316int
317w32_execvp (path, argv)
318 char *path;
319 char **argv;
320{
321 int i;
322
0d3d6719 323 /* Required to allow a .BAT script as alternate editor. */
4472aef4
JB
324 argv[0] = (char *) alternate_editor;
325
326 for (i = 0; argv[i]; i++)
327 if (strchr (argv[i], ' '))
328 {
329 char *quoted = alloca (strlen (argv[i]) + 3);
330 sprintf (quoted, "\"%s\"", argv[i]);
331 argv[i] = quoted;
332 }
333
334 return execvp (path, argv);
335}
336
337#undef execvp
338#define execvp w32_execvp
339
340#endif /* WINDOWSNT */
341
aa0b6932
JB
342/*
343 Try to run a different command, or --if no alternate editor is
344 defined-- exit with an errorcode.
345*/
346void
347fail (argc, argv)
348 int argc;
349 char **argv;
350{
351 if (alternate_editor)
352 {
353 int i = optind - 1;
4472aef4 354
aa0b6932 355 execvp (alternate_editor, argv + i);
42073bfb 356 message (TRUE, "%s: error executing alternate editor \"%s\"\n",
aa0b6932
JB
357 progname, alternate_editor);
358 }
aa0b6932
JB
359 exit (EXIT_FAILURE);
360}
361
362\f
1e7823d0 363#if !defined (HAVE_SOCKETS) || !defined (HAVE_INET_SOCKETS)
aa0b6932
JB
364
365int
366main (argc, argv)
367 int argc;
368 char **argv;
369{
42073bfb 370 message (TRUE, "%s: Sorry, the Emacs server is supported only\non systems with Berkely sockets.\n",
aa0b6932 371 argv[0]);
aa0b6932
JB
372
373 fail (argc, argv);
374}
375
1e7823d0 376#else /* HAVE_SOCKETS && HAVE_INET_SOCKETS */
aa0b6932
JB
377
378#ifdef WINDOWSNT
379# include <winsock2.h>
380#else
381# include <sys/types.h>
382# include <sys/socket.h>
383# include <sys/un.h>
384# include <sys/stat.h>
385# include <errno.h>
386#endif
387
388#define AUTH_KEY_LENGTH 64
389#define SEND_BUFFER_SIZE 4096
390
391extern char *strerror ();
392extern int errno;
393
394/* Buffer to accumulate data to send in TCP connections. */
395char send_buffer[SEND_BUFFER_SIZE + 1];
396int sblen = 0; /* Fill pointer for the send buffer. */
397
398/* Let's send the data to Emacs when either
399 - the data ends in "\n", or
400 - the buffer is full (but this shouldn't happen)
401 Otherwise, we just accumulate it. */
b03d27bd
JB
402void
403send_to_emacs (s, data)
aa0b6932
JB
404 HSOCKET s;
405 char *data;
406{
407 while (data)
408 {
409 int dlen = strlen (data);
410 if (dlen + sblen >= SEND_BUFFER_SIZE)
411 {
412 int part = SEND_BUFFER_SIZE - sblen;
413 strncpy (&send_buffer[sblen], data, part);
414 data += part;
415 sblen = SEND_BUFFER_SIZE;
416 }
417 else if (dlen)
418 {
419 strcpy (&send_buffer[sblen], data);
420 data = NULL;
421 sblen += dlen;
422 }
423 else
424 break;
425
426 if (sblen == SEND_BUFFER_SIZE
427 || (sblen > 0 && send_buffer[sblen-1] == '\n'))
428 {
429 int sent = send (s, send_buffer, sblen, 0);
430 if (sent != sblen)
431 strcpy (send_buffer, &send_buffer[sent]);
432 sblen -= sent;
433 }
434 }
435}
436
a4cf2096
RS
437/* In NAME, insert a & before each &, each space, each newline, and
438 any initial -. Change spaces to underscores, too, so that the
5212210c 439 return value never contains a space. */
87209357 440void
aa0b6932
JB
441quote_file_name (s, name)
442 HSOCKET s;
5212210c
RS
443 char *name;
444{
445 char *copy = (char *) malloc (strlen (name) * 2 + 1);
446 char *p, *q;
447
448 p = name;
449 q = copy;
450 while (*p)
451 {
452 if (*p == ' ')
453 {
f1db6a73 454 *q++ = '&';
5212210c
RS
455 *q++ = '_';
456 p++;
457 }
3cf8c6aa
SM
458 else if (*p == '\n')
459 {
460 *q++ = '&';
461 *q++ = 'n';
462 p++;
463 }
5212210c
RS
464 else
465 {
f1db6a73
RS
466 if (*p == '&' || (*p == '-' && p == name))
467 *q++ = '&';
5212210c
RS
468 *q++ = *p++;
469 }
470 }
f1db6a73 471 *q++ = 0;
5212210c 472
aa0b6932 473 SEND_STRING (copy);
87209357
EZ
474
475 free (copy);
5212210c 476}
0c76956f 477
b03d27bd
JB
478int
479file_name_absolute_p (filename)
480 const unsigned char *filename;
481{
482 /* Sanity check, it shouldn't happen. */
483 if (! filename) return FALSE;
484
485 /* /xxx is always an absolute path. */
486 if (filename[0] == '/') return TRUE;
487
488 /* Empty filenames (which shouldn't happen) are relative. */
489 if (filename[0] == '\0') return FALSE;
490
491#ifdef WINDOWSNT
71b8f735 492 /* X:\xxx is always absolute. */
5f7a4874 493 if (isalpha (filename[0])
cb0297bb 494 && filename[1] == ':' && (filename[2] == '\\' || filename[2] == '/'))
b03d27bd
JB
495 return TRUE;
496
497 /* Both \xxx and \\xxx\yyy are absolute. */
498 if (filename[0] == '\\') return TRUE;
71b8f735
JB
499
500 /*
501 FIXME: There's a corner case not dealt with, "x:y", where:
502
503 1) x is a valid drive designation (usually a letter in the A-Z range)
504 and y is a path, relative to the current directory on drive x. This
505 is absolute, *after* fixing the y part to include the current
506 directory in x.
507
508 2) x is a relative file name, and y is an NTFS stream name. This is a
509 correct relative path, but it is very unusual.
510
511 The trouble is that first case items are also valid examples of the
512 second case, i.e., "c:test" can be understood as drive:path or as
513 file:stream.
514
515 The "right" fix would involve checking whether
516 - the current drive/partition is NTFS,
517 - x is a valid (and accesible) drive designator,
518 - x:y already exists as a file:stream in the current directory,
519 - y already exists on the current directory of drive x,
520 - the auspices are favorable,
521 and then taking an "informed decision" based on the above.
522
523 Whatever the result, Emacs currently does a very bad job of dealing
524 with NTFS file:streams: it cannot visit them, and the only way to
525 create one is by setting `buffer-file-name' to point to it (either
526 manually or with emacsclient). So perhaps resorting to 1) and ignoring
527 2) for now is the right thing to do.
528
529 Anyway, something to decide After the Release.
530 */
b03d27bd
JB
531#endif
532
533 return FALSE;
534}
535
aa0b6932 536#ifdef WINDOWSNT
f0384499 537/* Wrapper to make WSACleanup a cdecl, as required by atexit. */
b03d27bd
JB
538void
539__cdecl close_winsock ()
aa0b6932
JB
540{
541 WSACleanup ();
542}
0c76956f 543
b03d27bd
JB
544/* Initialize the WinSock2 library. */
545void
546initialize_sockets ()
0c76956f 547{
aa0b6932
JB
548 WSADATA wsaData;
549
aa0b6932
JB
550 if (WSAStartup (MAKEWORD (2, 0), &wsaData))
551 {
42073bfb 552 message (TRUE, "%s: error initializing WinSock2", progname);
aa0b6932
JB
553 exit (EXIT_FAILURE);
554 }
555
556 atexit (close_winsock);
0c76956f 557}
e35fc962 558#endif /* WINDOWSNT */
8f9aaa0a 559\f
97e3214d 560/*
aa0b6932 561 * Read the information needed to set up a TCP comm channel with
434a6c5d 562 * the Emacs server: host, port, pid and authentication string.
0e0dced5 563 */
b03d27bd
JB
564int
565get_server_config (server, authentication)
aa0b6932
JB
566 struct sockaddr_in *server;
567 char *authentication;
97e3214d 568{
aa0b6932
JB
569 char dotted[32];
570 char *port;
434a6c5d 571 char *pid;
b03d27bd 572 FILE *config = NULL;
aa0b6932 573
b03d27bd
JB
574 if (file_name_absolute_p (server_file))
575 config = fopen (server_file, "rb");
576 else
97e3214d 577 {
aa0b6932 578 char *home = getenv ("HOME");
88b46d84 579
aa0b6932
JB
580 if (home)
581 {
582 char *path = alloca (32 + strlen (home) + strlen (server_file));
583 sprintf (path, "%s/.emacs.d/server/%s", home, server_file);
584 config = fopen (path, "rb");
585 }
88b46d84
JB
586#ifdef WINDOWSNT
587 if (!config && (home = getenv ("APPDATA")))
588 {
589 char *path = alloca (32 + strlen (home) + strlen (server_file));
590 sprintf (path, "%s/.emacs.d/server/%s", home, server_file);
591 config = fopen (path, "rb");
592 }
593#endif
aa0b6932
JB
594 }
595
596 if (! config)
597 return FALSE;
598
599 if (fgets (dotted, sizeof dotted, config)
434a6c5d
JB
600 && (port = strchr (dotted, ':'))
601 && (pid = strchr (port, ' ')))
aa0b6932
JB
602 {
603 *port++ = '\0';
434a6c5d 604 *pid++ = '\0';
97e3214d
GM
605 }
606 else
607 {
42073bfb 608 message (TRUE, "%s: invalid configuration info", progname);
65396510 609 exit (EXIT_FAILURE);
97e3214d 610 }
97e3214d 611
aa0b6932
JB
612 server->sin_family = AF_INET;
613 server->sin_addr.s_addr = inet_addr (dotted);
614 server->sin_port = htons (atoi (port));
97e3214d 615
aa0b6932
JB
616 if (! fread (authentication, AUTH_KEY_LENGTH, 1, config))
617 {
42073bfb 618 message (TRUE, "%s: cannot read authentication info", progname);
aa0b6932
JB
619 exit (EXIT_FAILURE);
620 }
46cec291 621
aa0b6932 622 fclose (config);
97e3214d 623
c66648e0 624 emacs_pid = atoi (pid);
434a6c5d 625
aa0b6932 626 return TRUE;
46cec291
RS
627}
628
aa0b6932
JB
629HSOCKET
630set_tcp_socket ()
631{
632 HSOCKET s;
633 struct sockaddr_in server;
aa0b6932
JB
634 struct linger l_arg = {1, 1};
635 char auth_string[AUTH_KEY_LENGTH + 1];
46cec291 636
aa0b6932
JB
637 if (! get_server_config (&server, auth_string))
638 return INVALID_SOCKET;
639
b03d27bd 640 if (server.sin_addr.s_addr != inet_addr ("127.0.0.1"))
9219db75 641 message (FALSE, "%s: connected to remote socket at %s\n",
b03d27bd
JB
642 progname, inet_ntoa (server.sin_addr));
643
aa0b6932
JB
644 /*
645 * Open up an AF_INET socket
646 */
647 if ((s = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
648 {
42073bfb 649 message (TRUE, "%s: socket: %s\n", progname, strerror (errno));
aa0b6932
JB
650 return INVALID_SOCKET;
651 }
652
653 /*
654 * Set up the socket
655 */
656 if (connect (s, (struct sockaddr *) &server, sizeof server) < 0)
657 {
42073bfb 658 message (TRUE, "%s: connect: %s\n", progname, strerror (errno));
aa0b6932
JB
659 return INVALID_SOCKET;
660 }
661
aa0b6932
JB
662 setsockopt (s, SOL_SOCKET, SO_LINGER, (char *) &l_arg, sizeof l_arg);
663
664 /*
665 * Send the authentication
666 */
667 auth_string[AUTH_KEY_LENGTH] = '\0';
668
669 SEND_STRING ("-auth ");
670 SEND_STRING (auth_string);
671 SEND_STRING ("\n");
672
673 return s;
674}
675
676#if !defined (NO_SOCKETS_IN_FILE_SYSTEM)
46cec291 677
9f637eea
GM
678/* Three possibilities:
679 2 - can't be `stat'ed (sets errno)
680 1 - isn't owned by us
681 0 - success: none of the above */
682
683static int
684socket_status (socket_name)
685 char *socket_name;
686{
687 struct stat statbfr;
688
689 if (stat (socket_name, &statbfr) == -1)
690 return 2;
691
692 if (statbfr.st_uid != geteuid ())
693 return 1;
694
695 return 0;
696}
697
aa0b6932
JB
698HSOCKET
699set_local_socket ()
46cec291 700{
aa0b6932 701 HSOCKET s;
46cec291 702 struct sockaddr_un server;
46cec291 703
e69233c2 704 /*
46cec291
RS
705 * Open up an AF_UNIX socket in this person's home directory
706 */
707
708 if ((s = socket (AF_UNIX, SOCK_STREAM, 0)) < 0)
709 {
42073bfb 710 message (TRUE, "%s: socket: %s\n", progname, strerror (errno));
aa0b6932 711 return INVALID_SOCKET;
46cec291 712 }
e69233c2 713
46cec291 714 server.sun_family = AF_UNIX;
c5fee545 715
c5fee545 716 {
9f637eea 717 int sock_status = 0;
5c9659d3 718 int default_sock = !socket_name;
152b6e83 719 int saved_errno;
0734b0d0
SM
720 char *server_name = "server";
721
722 if (socket_name && !index (socket_name, '/') && !index (socket_name, '\\'))
723 { /* socket_name is a file name component. */
724 server_name = socket_name;
725 socket_name = NULL;
726 default_sock = 1; /* Try both UIDs. */
727 }
efb859b4 728
5c9659d3 729 if (default_sock)
254107e4 730 {
0734b0d0
SM
731 socket_name = alloca (100 + strlen (server_name));
732 sprintf (socket_name, "/tmp/emacs%d/%s",
733 (int) geteuid (), server_name);
254107e4
RS
734 }
735
736 if (strlen (socket_name) < sizeof (server.sun_path))
737 strcpy (server.sun_path, socket_name);
738 else
5c9659d3 739 {
42073bfb 740 message (TRUE, "%s: socket-name %s too long",
aa0b6932 741 progname, socket_name);
65396510 742 exit (EXIT_FAILURE);
5c9659d3 743 }
efb859b4 744
9f637eea
GM
745 /* See if the socket exists, and if it's owned by us. */
746 sock_status = socket_status (server.sun_path);
152b6e83 747 saved_errno = errno;
5c9659d3 748 if (sock_status && default_sock)
efb859b4 749 {
9f637eea
GM
750 /* Failing that, see if LOGNAME or USER exist and differ from
751 our euid. If so, look for a socket based on the UID
752 associated with the name. This is reminiscent of the logic
753 that init_editfns uses to set the global Vuser_full_name. */
e69233c2 754
9f637eea 755 char *user_name = (char *) getenv ("LOGNAME");
293f9f2a 756
9f637eea
GM
757 if (!user_name)
758 user_name = (char *) getenv ("USER");
e69233c2 759
9f637eea
GM
760 if (user_name)
761 {
762 struct passwd *pw = getpwnam (user_name);
293f9f2a 763
9f637eea
GM
764 if (pw && (pw->pw_uid != geteuid ()))
765 {
766 /* We're running under su, apparently. */
0734b0d0
SM
767 socket_name = alloca (100 + strlen (server_name));
768 sprintf (socket_name, "/tmp/emacs%d/%s",
769 (int) pw->pw_uid, server_name);
5c9659d3
SM
770
771 if (strlen (socket_name) < sizeof (server.sun_path))
772 strcpy (server.sun_path, socket_name);
773 else
774 {
42073bfb 775 message (TRUE, "%s: socket-name %s too long",
aa0b6932 776 progname, socket_name);
65396510 777 exit (EXIT_FAILURE);
5c9659d3
SM
778 }
779
9f637eea 780 sock_status = socket_status (server.sun_path);
152b6e83 781 saved_errno = errno;
9f637eea 782 }
293f9f2a
RS
783 else
784 errno = saved_errno;
9f637eea 785 }
efb859b4 786 }
e69233c2 787
aa0b6932
JB
788 switch (sock_status)
789 {
790 case 1:
791 /* There's a socket, but it isn't owned by us. This is OK if
792 we are root. */
793 if (0 != geteuid ())
794 {
42073bfb 795 message (TRUE, "%s: Invalid socket owner\n", progname);
aa0b6932
JB
796 return INVALID_SOCKET;
797 }
798 break;
799
800 case 2:
801 /* `stat' failed */
802 if (saved_errno == ENOENT)
42073bfb 803 message (TRUE,
aa0b6932 804 "%s: can't find socket; have you started the server?\n\
45adde32 805To start the server in Emacs, type \"M-x server-start\".\n",
aa0b6932
JB
806 progname);
807 else
42073bfb 808 message (TRUE, "%s: can't stat %s: %s\n",
aa0b6932 809 progname, server.sun_path, strerror (saved_errno));
b03d27bd 810 return INVALID_SOCKET;
aa0b6932 811 }
efb859b4 812 }
46cec291 813
4e23f2ba
JB
814 if (connect (s, (struct sockaddr *) &server, strlen (server.sun_path) + 2)
815 < 0)
46cec291 816 {
42073bfb 817 message (TRUE, "%s: connect: %s\n", progname, strerror (errno));
aa0b6932 818 return INVALID_SOCKET;
46cec291 819 }
23a7488d 820
aa0b6932
JB
821 return s;
822}
823#endif /* ! NO_SOCKETS_IN_FILE_SYSTEM */
824
825HSOCKET
826set_socket ()
827{
b03d27bd
JB
828 HSOCKET s;
829
830 INITIALIZE ();
831
aa0b6932 832#ifndef NO_SOCKETS_IN_FILE_SYSTEM
b03d27bd
JB
833 /* Explicit --socket-name argument. */
834 if (socket_name)
835 {
836 s = set_local_socket ();
837 if ((s != INVALID_SOCKET) || alternate_editor)
838 return s;
839
42073bfb 840 message (TRUE, "%s: error accessing socket \"%s\"",
b03d27bd
JB
841 progname, socket_name);
842 exit (EXIT_FAILURE);
843 }
844#endif
845
846 /* Explicit --server-file arg or EMACS_SERVER_FILE variable. */
847 if (!server_file)
848 server_file = getenv ("EMACS_SERVER_FILE");
849
850 if (server_file)
46cec291 851 {
b03d27bd
JB
852 s = set_tcp_socket ();
853 if ((s != INVALID_SOCKET) || alternate_editor)
854 return s;
855
42073bfb 856 message (TRUE, "%s: error accessing server file \"%s\"",
b03d27bd
JB
857 progname, server_file);
858 exit (EXIT_FAILURE);
46cec291 859 }
b03d27bd
JB
860
861#ifndef NO_SOCKETS_IN_FILE_SYSTEM
862 /* Implicit local socket. */
863 s = set_local_socket ();
864 if (s != INVALID_SOCKET)
865 return s;
866#endif
867
868 /* Implicit server file. */
869 server_file = "server";
870 s = set_tcp_socket ();
871 if ((s != INVALID_SOCKET) || alternate_editor)
872 return s;
873
874 /* No implicit or explicit socket, and no alternate editor. */
42073bfb 875 message (TRUE, "%s: No socket or alternate editor. Please use:\n\n"
b03d27bd
JB
876#ifndef NO_SOCKETS_IN_FILE_SYSTEM
877"\t--socket-name\n"
aa0b6932 878#endif
b03d27bd
JB
879"\t--server-file (or environment variable EMACS_SERVER_FILE)\n\
880\t--alternate-editor (or environment variable ALTERNATE_EDITOR)\n",
881 progname);
882 exit (EXIT_FAILURE);
aa0b6932 883}
46cec291 884
0e0dced5
JB
885#ifdef WINDOWSNT
886FARPROC set_fg; /* Pointer to AllowSetForegroundWindow. */
887FARPROC get_wc; /* Pointer to RealGetWindowClassA. */
888
889BOOL CALLBACK
890w32_find_emacs_process (hWnd, lParam)
891 HWND hWnd;
892 LPARAM lParam;
893{
894 DWORD pid;
895 char class[6];
896
897 /* Reject any window not of class "Emacs". */
898 if (! get_wc (hWnd, class, sizeof (class))
899 || strcmp (class, "Emacs"))
900 return TRUE;
901
902 /* We only need the process id, not the thread id. */
903 (void) GetWindowThreadProcessId (hWnd, &pid);
904
905 /* Not the one we're looking for. */
906 if (pid != (DWORD) emacs_pid) return TRUE;
907
908 /* OK, let's raise it. */
909 set_fg (emacs_pid);
910
911 /* Stop enumeration. */
912 return FALSE;
913}
914
915/*
916 * Search for a window of class "Emacs" and owned by a process with
917 * process id = emacs_pid. If found, allow it to grab the focus.
918 */
919void
920w32_give_focus ()
921{
922 HMODULE hUser32;
923
71b8f735 924 /* It shouldn't happen when dealing with TCP sockets. */
0e0dced5
JB
925 if (!emacs_pid) return;
926
927 if (!(hUser32 = LoadLibrary ("user32.dll"))) return;
928
929 /* Modern Windows restrict which processes can set the foreground window.
930 emacsclient can allow Emacs to grab the focus by calling the function
931 AllowSetForegroundWindow. Unfortunately, older Windows (W95, W98 and
932 NT) lack this function, so we have to check its availability. */
933 if ((set_fg = GetProcAddress (hUser32, "AllowSetForegroundWindow"))
934 && (get_wc = GetProcAddress (hUser32, "RealGetWindowClassA")))
935 EnumWindows (w32_find_emacs_process, (LPARAM) 0);
936
937 FreeLibrary (hUser32);
938}
939#endif
940
aa0b6932
JB
941int
942main (argc, argv)
943 int argc;
944 char **argv;
945{
946 HSOCKET s;
947 int i, rl, needlf = 0;
948 char *cwd;
949 char string[BUFSIZ+1];
950
951 progname = argv[0];
952
953 /* Process options. */
954 decode_options (argc, argv);
955
956 if ((argc - optind < 1) && !eval)
23a7488d 957 {
42073bfb
JB
958 message (TRUE, "%s: file name or argument required\nTry `%s --help' for more information\n",
959 progname, progname);
aa0b6932 960 exit (EXIT_FAILURE);
23a7488d
RS
961 }
962
aa0b6932
JB
963 if ((s = set_socket ()) == INVALID_SOCKET)
964 fail (argc, argv);
965
38732dba 966#ifdef HAVE_GETCWD
ee6a193c 967 cwd = getcwd (string, sizeof string);
38732dba
RS
968#else
969 cwd = getwd (string);
ee6a193c 970#endif
46cec291
RS
971 if (cwd == 0)
972 {
973 /* getwd puts message in STRING if it fails. */
42073bfb 974 message (TRUE, "%s: %s (%s)\n", progname,
c66648e0
JB
975#ifdef HAVE_GETCWD
976 "Cannot get current working directory",
38732dba 977#else
c66648e0 978 string,
bd252662 979#endif
c66648e0 980 strerror (errno));
97e3214d 981 fail (argc, argv);
46cec291
RS
982 }
983
c66648e0 984#ifdef WINDOWSNT
0e0dced5 985 w32_give_focus ();
c66648e0
JB
986#endif
987
5212210c 988 if (nowait)
aa0b6932 989 SEND_STRING ("-nowait ");
292d74a3 990
30be2360 991 if (eval)
aa0b6932 992 SEND_STRING ("-eval ");
30be2360
SM
993
994 if (display)
87209357 995 {
aa0b6932
JB
996 SEND_STRING ("-display ");
997 SEND_QUOTED (display);
998 SEND_STRING (" ");
87209357 999 }
30be2360 1000
87209357 1001 if ((argc - optind > 0))
5212210c 1002 {
87209357 1003 for (i = optind; i < argc; i++)
46cec291 1004 {
87209357
EZ
1005 if (eval)
1006 ; /* Don't prepend any cwd or anything like that. */
1007 else if (*argv[i] == '+')
1008 {
1009 char *p = argv[i] + 1;
1010 while (isdigit ((unsigned char) *p) || *p == ':') p++;
1011 if (*p != 0)
1012 {
aa0b6932
JB
1013 SEND_QUOTED (cwd);
1014 SEND_STRING ("/");
87209357
EZ
1015 }
1016 }
b03d27bd 1017 else if (! file_name_absolute_p (argv[i]))
87209357 1018 {
aa0b6932
JB
1019 SEND_QUOTED (cwd);
1020 SEND_STRING ("/");
87209357
EZ
1021 }
1022
aa0b6932
JB
1023 SEND_QUOTED (argv[i]);
1024 SEND_STRING (" ");
46cec291 1025 }
46cec291 1026 }
87209357
EZ
1027 else
1028 {
aa0b6932 1029 while (fgets (string, BUFSIZ, stdin))
87209357 1030 {
aa0b6932 1031 SEND_QUOTED (string);
87209357 1032 }
aa0b6932 1033 SEND_STRING (" ");
87209357 1034 }
65396510 1035
aa0b6932 1036 SEND_STRING ("\n");
46cec291 1037
292d74a3 1038 /* Maybe wait for an answer. */
aa0b6932 1039 if (!nowait)
30be2360 1040 {
aa0b6932
JB
1041 if (!eval)
1042 {
1043 printf ("Waiting for Emacs...");
1044 needlf = 2;
1045 }
1046 fflush (stdout);
1047
1048 /* Now, wait for an answer and print any messages. */
1049 while ((rl = recv (s, string, BUFSIZ, 0)) > 0)
1050 {
1051 string[rl] = '\0';
1052 if (needlf == 2)
1053 printf ("\n");
1054 printf ("%s", string);
1055 needlf = string[0] == '\0' ? needlf : string[strlen (string) - 1] != '\n';
1056 }
1057
1058 if (needlf)
1059 printf ("\n");
1060 fflush (stdout);
30be2360 1061 }
23a7488d 1062
aa0b6932 1063 CLOSE_SOCKET (s);
65396510 1064 return EXIT_SUCCESS;
46cec291
RS
1065}
1066
1e7823d0 1067#endif /* HAVE_SOCKETS && HAVE_INET_SOCKETS */
aa0b6932 1068
27711600
RM
1069#ifndef HAVE_STRERROR
1070char *
1071strerror (errnum)
1072 int errnum;
1073{
1074 extern char *sys_errlist[];
1075 extern int sys_nerr;
1076
1077 if (errnum >= 0 && errnum < sys_nerr)
1078 return sys_errlist[errnum];
1079 return (char *) "Unknown error";
1080}
1081
1082#endif /* ! HAVE_STRERROR */
ab5796a9
MB
1083
1084/* arch-tag: f39bb9c4-73eb-477e-896d-50832e2ca9a7
1085 (do not change this comment) */
65396510
TTN
1086
1087/* emacsclient.c ends here */