comparison lib-src/emacsclient.c @ 74118:bee73d83d967

Include <stdarg.h>. [WINDOWSNT]: Include <windows.h>. (w32_check_console_app): New function. (message): New function. (decode_options, print_help_and_exit, fail, main, initialize_sockets, get_server_config, set_tcp_socket, set_local_socket, set_socket): Use message().
author Juanma Barranquero <lekktu@gmail.com>
date Wed, 22 Nov 2006 14:16:42 +0000
parents 7c6eb34059d6
children 46dc2e041725
comparison
equal deleted inserted replaced
74117:db85df5747ae 74118:bee73d83d967
32 # undef _WINSOCKAPI_ 32 # undef _WINSOCKAPI_
33 # undef _WINSOCK_H 33 # undef _WINSOCK_H
34 34
35 # include <malloc.h> 35 # include <malloc.h>
36 # include <stdlib.h> 36 # include <stdlib.h>
37 # include <windows.h>
37 38
38 # define NO_SOCKETS_IN_FILE_SYSTEM 39 # define NO_SOCKETS_IN_FILE_SYSTEM
39 40
40 # define HSOCKET SOCKET 41 # define HSOCKET SOCKET
41 # define CLOSE_SOCKET closesocket 42 # define CLOSE_SOCKET closesocket
56 57
57 #endif /* !WINDOWSNT */ 58 #endif /* !WINDOWSNT */
58 59
59 #undef signal 60 #undef signal
60 61
62 #include <stdarg.h>
61 #include <ctype.h> 63 #include <ctype.h>
62 #include <stdio.h> 64 #include <stdio.h>
63 #include "getopt.h" 65 #include "getopt.h"
64 #ifdef HAVE_UNISTD_H 66 #ifdef HAVE_UNISTD_H
65 #include <unistd.h> 67 #include <unistd.h>
142 { "server-file", required_argument, NULL, 'f' }, 144 { "server-file", required_argument, NULL, 'f' },
143 { "display", required_argument, NULL, 'd' }, 145 { "display", required_argument, NULL, 'd' },
144 { 0, 0, 0, 0 } 146 { 0, 0, 0, 0 }
145 }; 147 };
146 148
149 /* Message functions. */
150
151 #ifdef WINDOWSNT
152 /* I first tried to check for STDOUT. The check did not work,
153 I get a valid handle also in nonconsole apps.
154 Instead I test for console title, which seems to work. */
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 window_app = (GetConsoleTitleA (szTitle, MAX_PATH) == 0);
163
164 return window_app;
165 }
166 #endif
167
168 void
169 message (int is_error, char *message, ...)
170 {
171 char buf [2048];
172 char *msg = buf;
173 va_list args;
174
175 va_start (args, message);
176
177 if (is_error)
178 {
179 sprintf (buf, "%s: ", progname);
180 msg = strchr (buf, '\0');
181 }
182
183 vsprintf (msg, message, args);
184 va_end (args);
185
186 #ifdef WINDOWSNT
187 if (w32_window_app ())
188 {
189 if (is_error)
190 MessageBox (NULL, msg, "Emacsclient ERROR", MB_ICONERROR);
191 else
192 MessageBox (NULL, msg, "Emacsclient", MB_ICONINFORMATION);
193 }
194 else
195 #endif
196 fprintf (is_error ? stderr : stdout, msg);
197 }
198
147 /* Decode the options from argv and argc. 199 /* Decode the options from argv and argc.
148 The global variable `optind' will say how many arguments we used up. */ 200 The global variable `optind' will say how many arguments we used up. */
149 201
150 void 202 void
151 decode_options (argc, argv) 203 decode_options (argc, argv)
199 case 'e': 251 case 'e':
200 eval = 1; 252 eval = 1;
201 break; 253 break;
202 254
203 case 'V': 255 case 'V':
204 printf ("emacsclient %s\n", VERSION); 256 message (FALSE, "emacsclient %s\n", VERSION);
205 exit (EXIT_SUCCESS); 257 exit (EXIT_SUCCESS);
206 break; 258 break;
207 259
208 case 'H': 260 case 'H':
209 print_help_and_exit (); 261 print_help_and_exit ();
210 break; 262 break;
211 263
212 default: 264 default:
213 fprintf (stderr, "Try `%s --help' for more information\n", progname); 265 message (TRUE, "Try `%s --help' for more information\n", progname);
214 exit (EXIT_FAILURE); 266 exit (EXIT_FAILURE);
215 break; 267 break;
216 } 268 }
217 } 269 }
218 } 270 }
219 271
220 void 272 void
221 print_help_and_exit () 273 print_help_and_exit ()
222 { 274 {
223 printf ( 275 message (FALSE,
224 "Usage: %s [OPTIONS] FILE...\n\ 276 "Usage: %s [OPTIONS] FILE...\n\
225 Tell the Emacs server to visit the specified files.\n\ 277 Tell the Emacs server to visit the specified files.\n\
226 Every FILE can be either just a FILENAME or [+LINE[:COLUMN]] FILENAME.\n\ 278 Every FILE can be either just a FILENAME or [+LINE[:COLUMN]] FILENAME.\n\
227 \n\ 279 \n\
228 The following OPTIONS are accepted:\n\ 280 The following OPTIONS are accepted:\n\
259 int i = optind - 1; 311 int i = optind - 1;
260 #ifdef WINDOWSNT 312 #ifdef WINDOWSNT
261 argv[i] = (char *)alternate_editor; 313 argv[i] = (char *)alternate_editor;
262 #endif 314 #endif
263 execvp (alternate_editor, argv + i); 315 execvp (alternate_editor, argv + i);
264 fprintf (stderr, "%s: error executing alternate editor \"%s\"\n", 316 message (TRUE, "%s: error executing alternate editor \"%s\"\n",
265 progname, alternate_editor); 317 progname, alternate_editor);
266 } 318 }
267 exit (EXIT_FAILURE); 319 exit (EXIT_FAILURE);
268 } 320 }
269 321
273 int 325 int
274 main (argc, argv) 326 main (argc, argv)
275 int argc; 327 int argc;
276 char **argv; 328 char **argv;
277 { 329 {
278 fprintf (stderr, "%s: Sorry, the Emacs server is supported only\n", 330 message (TRUE, "%s: Sorry, the Emacs server is supported only\non systems with Berkely sockets.\n",
279 argv[0]); 331 argv[0]);
280 fprintf (stderr, "on systems with Berkeley sockets.\n");
281 332
282 fail (argc, argv); 333 fail (argc, argv);
283 } 334 }
284 335
285 #else /* HAVE_SOCKETS && HAVE_INET_SOCKETS */ 336 #else /* HAVE_SOCKETS && HAVE_INET_SOCKETS */
424 { 475 {
425 WSADATA wsaData; 476 WSADATA wsaData;
426 477
427 if (WSAStartup (MAKEWORD (2, 0), &wsaData)) 478 if (WSAStartup (MAKEWORD (2, 0), &wsaData))
428 { 479 {
429 fprintf (stderr, "%s: error initializing WinSock2", progname); 480 message (TRUE, "%s: error initializing WinSock2", progname);
430 exit (EXIT_FAILURE); 481 exit (EXIT_FAILURE);
431 } 482 }
432 483
433 atexit (close_winsock); 484 atexit (close_winsock);
434 } 485 }
480 *port++ = '\0'; 531 *port++ = '\0';
481 *pid++ = '\0'; 532 *pid++ = '\0';
482 } 533 }
483 else 534 else
484 { 535 {
485 fprintf (stderr, "%s: invalid configuration info", progname); 536 message (TRUE, "%s: invalid configuration info", progname);
486 exit (EXIT_FAILURE); 537 exit (EXIT_FAILURE);
487 } 538 }
488 539
489 server->sin_family = AF_INET; 540 server->sin_family = AF_INET;
490 server->sin_addr.s_addr = inet_addr (dotted); 541 server->sin_addr.s_addr = inet_addr (dotted);
491 server->sin_port = htons (atoi (port)); 542 server->sin_port = htons (atoi (port));
492 543
493 if (! fread (authentication, AUTH_KEY_LENGTH, 1, config)) 544 if (! fread (authentication, AUTH_KEY_LENGTH, 1, config))
494 { 545 {
495 fprintf (stderr, "%s: cannot read authentication info", progname); 546 message (TRUE, "%s: cannot read authentication info", progname);
496 exit (EXIT_FAILURE); 547 exit (EXIT_FAILURE);
497 } 548 }
498 549
499 fclose (config); 550 fclose (config);
500 551
535 586
536 if (! get_server_config (&server, auth_string)) 587 if (! get_server_config (&server, auth_string))
537 return INVALID_SOCKET; 588 return INVALID_SOCKET;
538 589
539 if (server.sin_addr.s_addr != inet_addr ("127.0.0.1")) 590 if (server.sin_addr.s_addr != inet_addr ("127.0.0.1"))
540 fprintf (stderr, "%s: connected to remote socket at %s\n", 591 message (TRUE, "%s: connected to remote socket at %s\n",
541 progname, inet_ntoa (server.sin_addr)); 592 progname, inet_ntoa (server.sin_addr));
542 593
543 /* 594 /*
544 * Open up an AF_INET socket 595 * Open up an AF_INET socket
545 */ 596 */
546 if ((s = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) 597 if ((s = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
547 { 598 {
548 fprintf (stderr, "%s: ", progname); 599 message (TRUE, "%s: socket: %s\n", progname, strerror (errno));
549 perror ("socket");
550 return INVALID_SOCKET; 600 return INVALID_SOCKET;
551 } 601 }
552 602
553 /* 603 /*
554 * Set up the socket 604 * Set up the socket
555 */ 605 */
556 if (connect (s, (struct sockaddr *) &server, sizeof server) < 0) 606 if (connect (s, (struct sockaddr *) &server, sizeof server) < 0)
557 { 607 {
558 fprintf (stderr, "%s: ", progname); 608 message (TRUE, "%s: connect: %s\n", progname, strerror (errno));
559 perror ("connect");
560 return INVALID_SOCKET; 609 return INVALID_SOCKET;
561 } 610 }
562 611
563 setsockopt (s, SOL_SOCKET, SO_LINGER, (char *) &l_arg, sizeof l_arg); 612 setsockopt (s, SOL_SOCKET, SO_LINGER, (char *) &l_arg, sizeof l_arg);
564 613
606 * Open up an AF_UNIX socket in this person's home directory 655 * Open up an AF_UNIX socket in this person's home directory
607 */ 656 */
608 657
609 if ((s = socket (AF_UNIX, SOCK_STREAM, 0)) < 0) 658 if ((s = socket (AF_UNIX, SOCK_STREAM, 0)) < 0)
610 { 659 {
611 fprintf (stderr, "%s: ", progname); 660 message (TRUE, "%s: socket: %s\n", progname, strerror (errno));
612 perror ("socket");
613 return INVALID_SOCKET; 661 return INVALID_SOCKET;
614 } 662 }
615 663
616 server.sun_family = AF_UNIX; 664 server.sun_family = AF_UNIX;
617 665
637 685
638 if (strlen (socket_name) < sizeof (server.sun_path)) 686 if (strlen (socket_name) < sizeof (server.sun_path))
639 strcpy (server.sun_path, socket_name); 687 strcpy (server.sun_path, socket_name);
640 else 688 else
641 { 689 {
642 fprintf (stderr, "%s: socket-name %s too long", 690 message (TRUE, "%s: socket-name %s too long",
643 progname, socket_name); 691 progname, socket_name);
644 exit (EXIT_FAILURE); 692 exit (EXIT_FAILURE);
645 } 693 }
646 694
647 /* See if the socket exists, and if it's owned by us. */ 695 /* See if the socket exists, and if it's owned by us. */
672 720
673 if (strlen (socket_name) < sizeof (server.sun_path)) 721 if (strlen (socket_name) < sizeof (server.sun_path))
674 strcpy (server.sun_path, socket_name); 722 strcpy (server.sun_path, socket_name);
675 else 723 else
676 { 724 {
677 fprintf (stderr, "%s: socket-name %s too long", 725 message (TRUE, "%s: socket-name %s too long",
678 progname, socket_name); 726 progname, socket_name);
679 exit (EXIT_FAILURE); 727 exit (EXIT_FAILURE);
680 } 728 }
681 729
682 sock_status = socket_status (server.sun_path); 730 sock_status = socket_status (server.sun_path);
692 case 1: 740 case 1:
693 /* There's a socket, but it isn't owned by us. This is OK if 741 /* There's a socket, but it isn't owned by us. This is OK if
694 we are root. */ 742 we are root. */
695 if (0 != geteuid ()) 743 if (0 != geteuid ())
696 { 744 {
697 fprintf (stderr, "%s: Invalid socket owner\n", progname); 745 message (TRUE, "%s: Invalid socket owner\n", progname);
698 return INVALID_SOCKET; 746 return INVALID_SOCKET;
699 } 747 }
700 break; 748 break;
701 749
702 case 2: 750 case 2:
703 /* `stat' failed */ 751 /* `stat' failed */
704 if (saved_errno == ENOENT) 752 if (saved_errno == ENOENT)
705 fprintf (stderr, 753 message (TRUE,
706 "%s: can't find socket; have you started the server?\n\ 754 "%s: can't find socket; have you started the server?\n\
707 To start the server in Emacs, type \"M-x server-start\".\n", 755 To start the server in Emacs, type \"M-x server-start\".\n",
708 progname); 756 progname);
709 else 757 else
710 fprintf (stderr, "%s: can't stat %s: %s\n", 758 message (TRUE, "%s: can't stat %s: %s\n",
711 progname, server.sun_path, strerror (saved_errno)); 759 progname, server.sun_path, strerror (saved_errno));
712 return INVALID_SOCKET; 760 return INVALID_SOCKET;
713 } 761 }
714 } 762 }
715 763
716 if (connect (s, (struct sockaddr *) &server, strlen (server.sun_path) + 2) 764 if (connect (s, (struct sockaddr *) &server, strlen (server.sun_path) + 2)
717 < 0) 765 < 0)
718 { 766 {
719 fprintf (stderr, "%s: ", progname); 767 message (TRUE, "%s: connect: %s\n", progname, strerror (errno));
720 perror ("connect");
721 return INVALID_SOCKET; 768 return INVALID_SOCKET;
722 } 769 }
723 770
724 return s; 771 return s;
725 } 772 }
738 { 785 {
739 s = set_local_socket (); 786 s = set_local_socket ();
740 if ((s != INVALID_SOCKET) || alternate_editor) 787 if ((s != INVALID_SOCKET) || alternate_editor)
741 return s; 788 return s;
742 789
743 fprintf (stderr, "%s: error accessing socket \"%s\"", 790 message (TRUE, "%s: error accessing socket \"%s\"",
744 progname, socket_name); 791 progname, socket_name);
745 exit (EXIT_FAILURE); 792 exit (EXIT_FAILURE);
746 } 793 }
747 #endif 794 #endif
748 795
754 { 801 {
755 s = set_tcp_socket (); 802 s = set_tcp_socket ();
756 if ((s != INVALID_SOCKET) || alternate_editor) 803 if ((s != INVALID_SOCKET) || alternate_editor)
757 return s; 804 return s;
758 805
759 fprintf (stderr, "%s: error accessing server file \"%s\"", 806 message (TRUE, "%s: error accessing server file \"%s\"",
760 progname, server_file); 807 progname, server_file);
761 exit (EXIT_FAILURE); 808 exit (EXIT_FAILURE);
762 } 809 }
763 810
764 #ifndef NO_SOCKETS_IN_FILE_SYSTEM 811 #ifndef NO_SOCKETS_IN_FILE_SYSTEM
773 s = set_tcp_socket (); 820 s = set_tcp_socket ();
774 if ((s != INVALID_SOCKET) || alternate_editor) 821 if ((s != INVALID_SOCKET) || alternate_editor)
775 return s; 822 return s;
776 823
777 /* No implicit or explicit socket, and no alternate editor. */ 824 /* No implicit or explicit socket, and no alternate editor. */
778 fprintf (stderr, "%s: No socket or alternate editor. Please use:\n\n" 825 message (TRUE, "%s: No socket or alternate editor. Please use:\n\n"
779 #ifndef NO_SOCKETS_IN_FILE_SYSTEM 826 #ifndef NO_SOCKETS_IN_FILE_SYSTEM
780 "\t--socket-name\n" 827 "\t--socket-name\n"
781 #endif 828 #endif
782 "\t--server-file (or environment variable EMACS_SERVER_FILE)\n\ 829 "\t--server-file (or environment variable EMACS_SERVER_FILE)\n\
783 \t--alternate-editor (or environment variable ALTERNATE_EDITOR)\n", 830 \t--alternate-editor (or environment variable ALTERNATE_EDITOR)\n",
800 /* Process options. */ 847 /* Process options. */
801 decode_options (argc, argv); 848 decode_options (argc, argv);
802 849
803 if ((argc - optind < 1) && !eval) 850 if ((argc - optind < 1) && !eval)
804 { 851 {
805 fprintf (stderr, "%s: file name or argument required\n", progname); 852 message (TRUE, "%s: file name or argument required\nTry `%s --help' for more information\n",
806 fprintf (stderr, "Try `%s --help' for more information\n", progname); 853 progname, progname);
807 exit (EXIT_FAILURE); 854 exit (EXIT_FAILURE);
808 } 855 }
809 856
810 if ((s = set_socket ()) == INVALID_SOCKET) 857 if ((s = set_socket ()) == INVALID_SOCKET)
811 fail (argc, argv); 858 fail (argc, argv);
817 #endif 864 #endif
818 if (cwd == 0) 865 if (cwd == 0)
819 { 866 {
820 /* getwd puts message in STRING if it fails. */ 867 /* getwd puts message in STRING if it fails. */
821 #ifdef HAVE_GETCWD 868 #ifdef HAVE_GETCWD
822 fprintf (stderr, "%s: %s (%s)\n", progname, 869 message (TRUE, "%s: %s (%s)\n", progname,
823 "Cannot get current working directory", strerror (errno)); 870 "Cannot get current working directory", strerror (errno));
824 #else 871 #else
825 fprintf (stderr, "%s: %s (%s)\n", progname, string, strerror (errno)); 872 message (TRUE, "%s: %s (%s)\n", progname, string, strerror (errno));
826 #endif 873 #endif
827 fail (argc, argv); 874 fail (argc, argv);
828 } 875 }
829 876
830 if (nowait) 877 if (nowait)