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