Bugfix festival.
[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, 2003
3 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., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
21
22
23 #define NO_SHORTNAMES
24
25 #ifdef HAVE_CONFIG_H
26 #include <config.h>
27 #endif
28
29 #undef signal
30
31 #include <ctype.h>
32 #include <stdio.h>
33 #include <getopt.h>
34 #ifdef HAVE_UNISTD_H
35 #include <unistd.h>
36 #endif
37
38 #ifdef VMS
39 # include "vms-pwd.h"
40 #else
41 # include <pwd.h>
42 #endif /* not VMS */
43
44
45 /****************************************/
46
47 #include <errno.h>
48 #include <signal.h>
49
50 #ifndef INCLUDED_FCNTL
51 #define INCLUDED_FCNTL
52 #include <fcntl.h>
53 #endif
54
55 #ifdef HAVE_TERMIOS
56 #ifndef NO_TERMIO
57 #include <termio.h>
58 #endif
59 #include <termios.h>
60 #endif /* not HAVE_TERMIOS */
61
62 #ifdef __GNU_LIBRARY__
63 #include <sys/ioctl.h>
64 #include <termios.h>
65 #endif
66
67 #if (defined (POSIX) || defined (NEED_UNISTD_H)) && defined (HAVE_UNISTD_H)
68 #include <unistd.h>
69 #endif
70
71
72 \f
73 /* Try to establish the correct character to disable terminal functions
74 in a system-independent manner. Note that USG (at least) define
75 _POSIX_VDISABLE as 0! */
76
77 #ifdef _POSIX_VDISABLE
78 #define CDISABLE _POSIX_VDISABLE
79 #else /* not _POSIX_VDISABLE */
80 #ifdef CDEL
81 #undef CDISABLE
82 #define CDISABLE CDEL
83 #else /* not CDEL */
84 #define CDISABLE 255
85 #endif /* not CDEL */
86 #endif /* not _POSIX_VDISABLE */
87 \f
88
89
90 /****************************************/
91
92 char *getenv (), *getwd ();
93 char *getcwd ();
94
95 /* This is defined with -D from the compilation command,
96 which extracts it from ../lisp/version.el. */
97
98 #ifndef VERSION
99 #define VERSION "unspecified"
100 #endif
101 \f
102 /* Name used to invoke this program. */
103 char *progname;
104
105 /* The first argument to main. */
106 int main_argc;
107
108 /* The second argument to main. */
109 char **main_argv;
110
111 /* Nonzero means don't wait for a response from Emacs. --no-wait. */
112 int nowait = 0;
113
114 /* Nonzero means args are expressions to be evaluated. --eval. */
115 int eval = 0;
116
117 /* The display on which Emacs should work. --display. */
118 char *display = NULL;
119
120 /* Nonzero means open a new Emacs frame on the current terminal. */
121 int here = 0;
122
123 /* If non-NULL, the name of an editor to fallback to if the server
124 is not running. --alternate-editor. */
125 const char * alternate_editor = NULL;
126
127 /* If non-NULL, the filename of the UNIX socket. */
128 char *socket_name = NULL;
129
130 void print_help_and_exit ();
131
132 struct option longopts[] =
133 {
134 { "no-wait", no_argument, NULL, 'n' },
135 { "eval", no_argument, NULL, 'e' },
136 { "help", no_argument, NULL, 'H' },
137 { "version", no_argument, NULL, 'V' },
138 { "here", no_argument, NULL, 'h' },
139 { "alternate-editor", required_argument, NULL, 'a' },
140 { "socket-name", required_argument, NULL, 's' },
141 { "display", required_argument, NULL, 'd' },
142 { 0, 0, 0, 0 }
143 };
144
145 /* Decode the options from argv and argc.
146 The global variable `optind' will say how many arguments we used up. */
147
148 void
149 decode_options (argc, argv)
150 int argc;
151 char **argv;
152 {
153 while (1)
154 {
155 int opt = getopt_long (argc, argv,
156 "VHnea:s:d:h", longopts, 0);
157
158 if (opt == EOF)
159 break;
160
161 alternate_editor = getenv ("ALTERNATE_EDITOR");
162
163 switch (opt)
164 {
165 case 0:
166 /* If getopt returns 0, then it has already processed a
167 long-named option. We should do nothing. */
168 break;
169
170 case 'a':
171 alternate_editor = optarg;
172 break;
173
174 case 's':
175 socket_name = optarg;
176 break;
177
178 case 'd':
179 display = optarg;
180 break;
181
182 case 'n':
183 nowait = 1;
184 break;
185
186 case 'e':
187 eval = 1;
188 break;
189
190 case 'V':
191 printf ("emacsclient %s\n", VERSION);
192 exit (0);
193 break;
194
195 case 'h':
196 here = 1;
197 break;
198
199 case 'H':
200 print_help_and_exit ();
201 break;
202
203 default:
204 fprintf (stderr, "Try `%s --help' for more information\n", progname);
205 exit (1);
206 break;
207 }
208 }
209
210 if (here) {
211 nowait = 0;
212 display = 0;
213 }
214
215 }
216
217 void
218 print_help_and_exit ()
219 {
220 printf (
221 "Usage: %s [OPTIONS] FILE...\n\
222 Tell the Emacs server to visit the specified files.\n\
223 Every FILE can be either just a FILENAME or [+LINE[:COLUMN]] FILENAME.\n\
224 \n\
225 The following OPTIONS are accepted:\n\
226 -V, --version Just print a version info and return\n\
227 -H, --help Print this usage information message\n\
228 -h, --here Open a new Emacs frame on the current terminal\n\
229 -n, --no-wait Don't wait for the server to return\n\
230 -e, --eval Evaluate the FILE arguments as ELisp expressions\n\
231 -d, --display=DISPLAY Visit the file in the given display\n\
232 -s, --socket-name=FILENAME\n\
233 Set the filename of the UNIX socket for communication\n\
234 -a, --alternate-editor=EDITOR\n\
235 Editor to fallback to if the server is not running\n\
236 \n\
237 Report bugs to bug-gnu-emacs@gnu.org.\n", progname);
238 exit (0);
239 }
240
241 /* In NAME, insert a & before each &, each space, each newline, and
242 any initial -. Change spaces to underscores, too, so that the
243 return value never contains a space. */
244
245 void
246 quote_file_name (name, stream)
247 char *name;
248 FILE *stream;
249 {
250 char *copy = (char *) malloc (strlen (name) * 2 + 1);
251 char *p, *q;
252
253 p = name;
254 q = copy;
255 while (*p)
256 {
257 if (*p == ' ')
258 {
259 *q++ = '&';
260 *q++ = '_';
261 p++;
262 }
263 else if (*p == '\n')
264 {
265 *q++ = '&';
266 *q++ = 'n';
267 p++;
268 }
269 else
270 {
271 if (*p == '&' || (*p == '-' && p == name))
272 *q++ = '&';
273 *q++ = *p++;
274 }
275 }
276 *q++ = 0;
277
278 fprintf (stream, copy);
279
280 free (copy);
281 }
282
283 /* Like malloc but get fatal error if memory is exhausted. */
284
285 long *
286 xmalloc (size)
287 unsigned int size;
288 {
289 long *result = (long *) malloc (size);
290 if (result == NULL)
291 {
292 perror ("malloc");
293 exit (1);
294 }
295 return result;
296 }
297 \f
298 /*
299 Try to run a different command, or --if no alternate editor is
300 defined-- exit with an errorcode.
301 */
302 void
303 fail ()
304 {
305 if (alternate_editor)
306 {
307 int i = optind - 1;
308 execvp (alternate_editor, main_argv + i);
309 return;
310 }
311 else
312 {
313 exit (1);
314 }
315 }
316
317 \f
318 #ifdef HAVE_TERMIOS
319
320 /* Adapted from emacs_get_tty() in sysdep.c. */
321 int
322 ec_get_tty (int fd, struct termios *settings)
323 {
324 bzero (settings, sizeof (struct termios));
325 if (tcgetattr (fd, settings) < 0)
326 return -1;
327 return 0;
328 }
329
330 /* Adapted from emacs_set_tty() in sysdep.c. */
331 int
332 ec_set_tty (int fd, struct termios *settings, int flushp)
333 {
334 /* Set the primary parameters - baud rate, character size, etcetera. */
335
336 int i;
337 /* We have those nifty POSIX tcmumbleattr functions.
338 William J. Smith <wjs@wiis.wang.com> writes:
339 "POSIX 1003.1 defines tcsetattr to return success if it was
340 able to perform any of the requested actions, even if some
341 of the requested actions could not be performed.
342 We must read settings back to ensure tty setup properly.
343 AIX requires this to keep tty from hanging occasionally." */
344 /* This make sure that we don't loop indefinitely in here. */
345 for (i = 0 ; i < 10 ; i++)
346 if (tcsetattr (fd, flushp ? TCSAFLUSH : TCSADRAIN, settings) < 0)
347 {
348 if (errno == EINTR)
349 continue;
350 else
351 return -1;
352 }
353 else
354 {
355 struct termios new;
356
357 bzero (&new, sizeof (new));
358 /* Get the current settings, and see if they're what we asked for. */
359 tcgetattr (fd, &new);
360 /* We cannot use memcmp on the whole structure here because under
361 * aix386 the termios structure has some reserved field that may
362 * not be filled in.
363 */
364 if ( new.c_iflag == settings->c_iflag
365 && new.c_oflag == settings->c_oflag
366 && new.c_cflag == settings->c_cflag
367 && new.c_lflag == settings->c_lflag
368 && memcmp (new.c_cc, settings->c_cc, NCCS) == 0)
369 break;
370 else
371 continue;
372 }
373 return 0;
374 }
375
376 int master;
377 char *pty_name;
378
379 struct termios old_tty;
380 struct termios tty;
381 int old_tty_valid;
382
383 int tty_erase_char;
384 int flow_control = 0;
385 int meta_key = 0;
386 char _sobuf[BUFSIZ];
387 int emacs_pid;
388
389 /* Adapted from init_sys_modes() in sysdep.c. */
390 int
391 init_tty ()
392 {
393 if (! isatty (0))
394 {
395 fprintf (stderr, "%s: Input is not a terminal", "init_tty");
396 return 0;
397 }
398
399 ec_get_tty (0, &old_tty);
400 old_tty_valid = 1;
401 tty = old_tty;
402
403 tty_erase_char = old_tty.c_cc[VERASE];
404
405 tty.c_iflag |= (IGNBRK); /* Ignore break condition */
406 tty.c_iflag &= ~ICRNL; /* Disable map of CR to NL on input */
407 #ifdef INLCR
408 tty.c_iflag &= ~INLCR; /* Disable map of NL to CR on input */
409 #endif
410 #ifdef ISTRIP
411 tty.c_iflag &= ~ISTRIP; /* don't strip 8th bit on input */
412 #endif
413 tty.c_lflag &= ~ECHO; /* Disable echo */
414 tty.c_lflag &= ~ICANON; /* Disable erase/kill processing */
415 #ifdef IEXTEN
416 tty.c_lflag &= ~IEXTEN; /* Disable other editing characters. */
417 #endif
418 tty.c_lflag |= ISIG; /* Enable signals */
419 if (flow_control)
420 {
421 tty.c_iflag |= IXON; /* Enable start/stop output control */
422 #ifdef IXANY
423 tty.c_iflag &= ~IXANY;
424 #endif /* IXANY */
425 }
426 else
427 tty.c_iflag &= ~IXON; /* Disable start/stop output control */
428 tty.c_oflag &= ~ONLCR; /* Disable map of NL to CR-NL
429 on output */
430 tty.c_oflag &= ~TAB3; /* Disable tab expansion */
431 #ifdef CS8
432 if (meta_key)
433 {
434 tty.c_cflag |= CS8; /* allow 8th bit on input */
435 tty.c_cflag &= ~PARENB; /* Don't check parity */
436 }
437 #endif
438 tty.c_cc[VINTR] = CDISABLE;
439 tty.c_cc[VQUIT] = CDISABLE;
440 tty.c_cc[VMIN] = 1; /* Input should wait for at least 1 char */
441 tty.c_cc[VTIME] = 0; /* no matter how long that takes. */
442 #ifdef VSWTCH
443 tty.c_cc[VSWTCH] = CDISABLE; /* Turn off shell layering use of C-z */
444 #endif
445
446 #ifdef VSUSP
447 tty.c_cc[VSUSP] = CDISABLE; /* Turn off mips handling of C-z. */
448 #endif /* VSUSP */
449 #ifdef V_DSUSP
450 tty.c_cc[V_DSUSP] = CDISABLE; /* Turn off mips handling of C-y. */
451 #endif /* V_DSUSP */
452 #ifdef VDSUSP /* Some systems have VDSUSP, some have V_DSUSP. */
453 tty.c_cc[VDSUSP] = CDISABLE;
454 #endif /* VDSUSP */
455 #ifdef VLNEXT
456 tty.c_cc[VLNEXT] = CDISABLE;
457 #endif /* VLNEXT */
458 #ifdef VREPRINT
459 tty.c_cc[VREPRINT] = CDISABLE;
460 #endif /* VREPRINT */
461 #ifdef VWERASE
462 tty.c_cc[VWERASE] = CDISABLE;
463 #endif /* VWERASE */
464 #ifdef VDISCARD
465 tty.c_cc[VDISCARD] = CDISABLE;
466 #endif /* VDISCARD */
467
468 if (flow_control)
469 {
470 #ifdef VSTART
471 tty.c_cc[VSTART] = '\021';
472 #endif /* VSTART */
473 #ifdef VSTOP
474 tty.c_cc[VSTOP] = '\023';
475 #endif /* VSTOP */
476 }
477 else
478 {
479 #ifdef VSTART
480 tty.c_cc[VSTART] = CDISABLE;
481 #endif /* VSTART */
482 #ifdef VSTOP
483 tty.c_cc[VSTOP] = CDISABLE;
484 #endif /* VSTOP */
485 }
486
487 #ifdef SET_LINE_DISCIPLINE
488 /* Need to explicitly request TERMIODISC line discipline or
489 Ultrix's termios does not work correctly. */
490 tty.c_line = SET_LINE_DISCIPLINE;
491 #endif
492
493 #ifdef AIX
494 #ifndef IBMR2AIX
495 /* AIX enhanced edit loses NULs, so disable it. */
496 tty.c_line = 0;
497 tty.c_iflag &= ~ASCEDIT;
498 #else
499 tty.c_cc[VSTRT] = 255;
500 tty.c_cc[VSTOP] = 255;
501 tty.c_cc[VSUSP] = 255;
502 tty.c_cc[VDSUSP] = 255;
503 #endif /* IBMR2AIX */
504 if (flow_control)
505 {
506 #ifdef VSTART
507 tty.c_cc[VSTART] = '\021';
508 #endif /* VSTART */
509 #ifdef VSTOP
510 tty.c_cc[VSTOP] = '\023';
511 #endif /* VSTOP */
512 }
513 /* Also, PTY overloads NUL and BREAK.
514 don't ignore break, but don't signal either, so it looks like NUL.
515 This really serves a purpose only if running in an XTERM window
516 or via TELNET or the like, but does no harm elsewhere. */
517 tty.c_iflag &= ~IGNBRK;
518 tty.c_iflag &= ~BRKINT;
519 #endif /* AIX */
520
521 ec_set_tty (0, &tty, 0);
522
523 /* This code added to insure that, if flow-control is not to be used,
524 we have an unlocked terminal at the start. */
525
526 #ifdef TCXONC
527 if (!flow_control) ioctl (0, TCXONC, 1);
528 #endif
529 #ifndef APOLLO
530 #ifdef TIOCSTART
531 if (!flow_control) ioctl (0, TIOCSTART, 0);
532 #endif
533 #endif
534
535 #if defined (HAVE_TERMIOS) || defined (HPUX9)
536 #ifdef TCOON
537 if (!flow_control) tcflow (0, TCOON);
538 #endif
539 #endif
540
541 #ifdef _IOFBF
542 /* This symbol is defined on recent USG systems.
543 Someone says without this call USG won't really buffer the file
544 even with a call to setbuf. */
545 setvbuf (stdout, (char *) _sobuf, _IOFBF, sizeof _sobuf);
546 #else
547 setbuf (stdout, (char *) _sobuf);
548 #endif
549
550 return 1;
551 }
552
553 void
554 window_change ()
555 {
556 int width = 0, height = 0;
557
558 #ifdef TIOCGWINSZ
559 {
560 /* BSD-style. */
561 struct winsize size;
562
563 if (ioctl (0, TIOCGWINSZ, &size) == -1)
564 width = height = 0;
565 else
566 {
567 width = size.ws_col;
568 height = size.ws_row;
569 }
570 }
571 #else
572 #ifdef TIOCGSIZE
573 {
574 /* SunOS - style. */
575 struct ttysize size;
576
577 if (ioctl (0, TIOCGSIZE, &size) == -1)
578 width = height = 0;
579 else
580 {
581 width = size.ts_cols;
582 height = size.ts_lines;
583 }
584 }
585 #endif /* not SunOS-style */
586 #endif /* not BSD-style */
587
588 #ifdef TIOCSWINSZ
589 {
590 /* BSD-style. */
591 struct winsize size;
592 size.ws_row = height;
593 size.ws_col = width;
594
595 ioctl (master, TIOCSWINSZ, &size);
596 }
597 #else
598 #ifdef TIOCSSIZE
599 {
600 /* SunOS - style. */
601 struct ttysize size;
602 size.ts_lines = height;
603 size.ts_cols = width;
604
605 ioctl (master, TIOCGSIZE, &size);
606 }
607 #endif /* not SunOS-style */
608 #endif /* not BSD-style */
609
610 if (emacs_pid && width && height)
611 kill (emacs_pid, SIGWINCH);
612 }
613
614 int in_conversation = 0;
615 int quit_conversation = 0;
616
617 SIGTYPE
618 hang_up_signal (int signalnum)
619 {
620 int old_errno = errno;
621
622 if (! in_conversation)
623 return;
624
625 quit_conversation = 1;
626
627 errno = old_errno;
628 }
629
630 SIGTYPE
631 window_change_signal (int signalnum)
632 {
633 int old_errno = errno;
634
635 if (! in_conversation)
636 goto end;
637
638 window_change();
639
640 end:
641 signal (SIGWINCH, window_change_signal);
642 errno = old_errno;
643 }
644
645 int
646 init_signals ()
647 {
648 /* Set up signal handlers. */
649 signal (SIGWINCH, window_change_signal);
650 signal (SIGHUP, hang_up_signal);
651
652 return 1;
653 }
654
655
656
657 /* Adapted from reset_sys_modes in sysdep.c. */
658 int
659 reset_tty ()
660 {
661 fflush (stdout);
662 #ifdef BSD_SYSTEM
663 #ifndef BSD4_1
664 /* Avoid possible loss of output when changing terminal modes. */
665 fsync (fileno (stdout));
666 #endif
667 #endif
668
669 #ifdef F_SETFL
670 #ifdef O_NDELAY
671 fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) & ~O_NDELAY);
672 #endif
673 #endif /* F_SETFL */
674
675 if (old_tty_valid)
676 while (ec_set_tty (0, &old_tty, 0) < 0 && errno == EINTR)
677 ;
678
679 return 1;
680 }
681
682
683 int
684 init_pty ()
685 {
686 master = getpt ();
687 if (master < 0)
688 return 0;
689
690 if (grantpt (master) < 0 || unlockpt (master) < 0)
691 goto close_master;
692 pty_name = strdup (ptsname (master));
693 if (! pty_name)
694 goto close_master;
695
696 /* Propagate window size. */
697 window_change ();
698
699 return 1;
700
701 close_master:
702 close (master);
703 return 0;
704 }
705
706 int
707 copy_from_to (int in, int out, int sigio)
708 {
709 static char buf[BUFSIZ];
710 int nread = read (in, &buf, BUFSIZ);
711 if (nread == 0)
712 return 1; /* EOF */
713 else if (nread < 0 && errno != EAGAIN)
714 return 0; /* Error */
715 else if (nread > 0)
716 {
717 int r = 0;
718 int written = 0;
719
720 do {
721 r = write (out, &buf, nread);
722 } while ((r < 0 && errno == EAGAIN)
723 || (r > 0 && (written += r) && written != nread));
724
725 if (r < 0)
726 return 0; /* Error */
727
728 if (emacs_pid && sigio)
729 {
730 kill (emacs_pid, SIGIO);
731 }
732 }
733 return 1;
734 }
735
736 int
737 pty_conversation (FILE *in)
738 {
739 char *str;
740 char string[BUFSIZ];
741 fd_set set;
742
743 in_conversation = 1;
744
745 while (! quit_conversation) {
746 int res;
747
748 FD_ZERO (&set);
749 FD_SET (master, &set);
750 FD_SET (1, &set);
751 FD_SET (fileno (in), &set);
752 res = select (FD_SETSIZE, &set, NULL, NULL, NULL);
753 if (res < 0)
754 {
755 if (errno != EINTR)
756 return 0;
757 }
758 else if (res > 0)
759 {
760 if (FD_ISSET (master, &set))
761 {
762 /* Copy Emacs output to stdout. */
763 if (! copy_from_to (master, 0, 0))
764 return 1;
765 }
766 if (FD_ISSET (1, &set))
767 {
768 /* Forward user input to Emacs. */
769 if (! copy_from_to (1, master, 1))
770 return 1;
771 }
772 if (FD_ISSET (fileno (in), &set))
773 {
774 if (! emacs_pid)
775 {
776 /* Get the pid of the Emacs process.
777 XXX Is there is some nifty libc/kernel feature for doing this?
778 */
779 str = fgets (string, BUFSIZ, in);
780 if (! str)
781 {
782 reset_tty ();
783 fprintf (stderr, "%s: %s\n", progname, str);
784 fail ();
785 }
786
787 emacs_pid = atoi (str);
788 }
789 }
790 }
791 }
792 return 1;
793 }
794
795 #endif /* HAVE_TERMIOS */
796
797 \f
798 #if !defined (HAVE_SOCKETS) || defined (NO_SOCKETS_IN_FILE_SYSTEM)
799
800 int
801 main (argc, argv)
802 int argc;
803 char **argv;
804 {
805 fprintf (stderr, "%s: Sorry, the Emacs server is supported only\n",
806 argv[0]);
807 fprintf (stderr, "on systems with Berkeley sockets.\n");
808
809 fail (argc, argv);
810 }
811
812 #else /* HAVE_SOCKETS */
813
814 #include <sys/types.h>
815 #include <sys/socket.h>
816 #include <sys/un.h>
817 #include <sys/stat.h>
818 #include <errno.h>
819
820 extern char *strerror ();
821 extern int errno;
822
823 /* Three possibilities:
824 2 - can't be `stat'ed (sets errno)
825 1 - isn't owned by us
826 0 - success: none of the above */
827
828 static int
829 socket_status (socket_name)
830 char *socket_name;
831 {
832 struct stat statbfr;
833
834 if (stat (socket_name, &statbfr) == -1)
835 return 2;
836
837 if (statbfr.st_uid != geteuid ())
838 return 1;
839
840 return 0;
841 }
842
843 int
844 main (argc, argv)
845 int argc;
846 char **argv;
847 {
848 char *system_name;
849 int system_name_length;
850 int s, i, needlf = 0;
851 FILE *out, *in;
852 struct sockaddr_un server;
853 char *cwd, *str;
854 char string[BUFSIZ];
855
856 main_argc = argc;
857 main_argv = argv;
858 progname = argv[0];
859
860 /* Process options. */
861 decode_options (argc, argv);
862
863 if ((argc - optind < 1) && !eval && !here)
864 {
865 fprintf (stderr, "%s: file name or argument required\n", progname);
866 fprintf (stderr, "Try `%s --help' for more information\n", progname);
867 exit (1);
868 }
869
870 /*
871 * Open up an AF_UNIX socket in this person's home directory
872 */
873
874 if ((s = socket (AF_UNIX, SOCK_STREAM, 0)) < 0)
875 {
876 fprintf (stderr, "%s: ", argv[0]);
877 perror ("socket");
878 fail (argc, argv);
879 }
880
881 server.sun_family = AF_UNIX;
882
883 {
884 char *dot;
885 system_name_length = 32;
886
887 while (1)
888 {
889 system_name = (char *) xmalloc (system_name_length + 1);
890
891 /* system_name must be null-terminated string. */
892 system_name[system_name_length] = '\0';
893
894 if (gethostname (system_name, system_name_length) == 0)
895 break;
896
897 free (system_name);
898 system_name_length *= 2;
899 }
900
901 /* We always use the non-dotted host name, for simplicity. */
902 dot = index (system_name, '.');
903 if (dot)
904 *dot = '\0';
905 }
906
907 {
908 int sock_status = 0;
909
910 if (! socket_name)
911 {
912 socket_name = alloca (system_name_length + 100);
913 sprintf (socket_name, "/tmp/emacs%d-%s/server",
914 (int) geteuid (), system_name);
915 }
916
917 if (strlen (socket_name) < sizeof (server.sun_path))
918 strcpy (server.sun_path, socket_name);
919 else
920 fprintf (stderr, "%s: socket-name %s too long",
921 argv[0], socket_name);
922
923 /* See if the socket exists, and if it's owned by us. */
924 sock_status = socket_status (server.sun_path);
925 if (sock_status)
926 {
927 /* Failing that, see if LOGNAME or USER exist and differ from
928 our euid. If so, look for a socket based on the UID
929 associated with the name. This is reminiscent of the logic
930 that init_editfns uses to set the global Vuser_full_name. */
931
932 char *user_name = (char *) getenv ("LOGNAME");
933 if (!user_name)
934 user_name = (char *) getenv ("USER");
935
936 if (user_name)
937 {
938 struct passwd *pw = getpwnam (user_name);
939 if (pw && (pw->pw_uid != geteuid ()))
940 {
941 /* We're running under su, apparently. */
942 sprintf (server.sun_path, "/tmp/esrv%d-%s",
943 (int) pw->pw_uid, system_name);
944 sock_status = socket_status (server.sun_path);
945 }
946 }
947 }
948
949 switch (sock_status)
950 {
951 case 1:
952 /* There's a socket, but it isn't owned by us. This is OK if
953 we are root. */
954 if (0 != geteuid ())
955 {
956 fprintf (stderr, "%s: Invalid socket owner\n", argv[0]);
957 fail (argc, argv);
958 }
959 break;
960
961 case 2:
962 /* `stat' failed */
963 if (errno == ENOENT)
964 fprintf (stderr,
965 "%s: can't find socket; have you started the server?\n\
966 To start the server in Emacs, type \"M-x server-start\".\n",
967 argv[0]);
968 else
969 fprintf (stderr, "%s: can't stat %s: %s\n",
970 argv[0], server.sun_path, strerror (errno));
971 fail (argc, argv);
972 break;
973 }
974 }
975
976 if (connect (s, (struct sockaddr *) &server, strlen (server.sun_path) + 2)
977 < 0)
978 {
979 fprintf (stderr, "%s: ", argv[0]);
980 perror ("connect");
981 fail (argc, argv);
982 }
983
984 /* We use the stream OUT to send our command to the server. */
985 if ((out = fdopen (s, "r+")) == NULL)
986 {
987 fprintf (stderr, "%s: ", argv[0]);
988 perror ("fdopen");
989 fail (argc, argv);
990 }
991
992 /* We use the stream IN to read the response.
993 We used to use just one stream for both output and input
994 on the socket, but reversing direction works nonportably:
995 on some systems, the output appears as the first input;
996 on other systems it does not. */
997 if ((in = fdopen (s, "r+")) == NULL)
998 {
999 fprintf (stderr, "%s: ", argv[0]);
1000 perror ("fdopen");
1001 fail (argc, argv);
1002 }
1003
1004 #ifdef HAVE_GETCWD
1005 cwd = getcwd (string, sizeof string);
1006 #else
1007 cwd = getwd (string);
1008 #endif
1009 if (cwd == 0)
1010 {
1011 /* getwd puts message in STRING if it fails. */
1012
1013 #ifdef HAVE_GETCWD
1014 fprintf (stderr, "%s: %s (%s)\n", argv[0],
1015 "Cannot get current working directory", strerror (errno));
1016 #else
1017 fprintf (stderr, "%s: %s (%s)\n", argv[0], string, strerror (errno));
1018 #endif
1019 fail (argc, argv);
1020 }
1021
1022 if (nowait)
1023 fprintf (out, "-nowait ");
1024
1025 if (eval)
1026 fprintf (out, "-eval ");
1027
1028 if (display)
1029 {
1030 fprintf (out, "-display ");
1031 quote_file_name (display, out);
1032 fprintf (out, " ");
1033 }
1034
1035 if (here)
1036 {
1037 if (! init_signals ())
1038 {
1039 fprintf (stderr, "%s: ", argv[0]);
1040 perror ("fdopen");
1041 fail (argc, argv);
1042 }
1043
1044 if (! init_tty ())
1045 {
1046 reset_tty ();
1047 fprintf (stderr, "%s: ", argv[0]);
1048 perror ("fdopen");
1049 fail (argc, argv);
1050 }
1051
1052 if (! init_pty ())
1053 {
1054 reset_tty ();
1055 fprintf (stderr, "%s: ", argv[0]);
1056 perror ("fdopen");
1057 fail (argc, argv);
1058 }
1059
1060 fprintf (out, "-pty ");
1061 quote_file_name (pty_name, out);
1062 fprintf (out, " ");
1063 quote_file_name (getenv("TERM"), out);
1064 fprintf (out, " ");
1065 }
1066
1067 if ((argc - optind > 0))
1068 {
1069 for (i = optind; i < argc; i++)
1070 {
1071 if (eval)
1072 ; /* Don't prepend any cwd or anything like that. */
1073 else if (*argv[i] == '+')
1074 {
1075 char *p = argv[i] + 1;
1076 while (isdigit ((unsigned char) *p) || *p == ':') p++;
1077 if (*p != 0)
1078 {
1079 quote_file_name (cwd, out);
1080 fprintf (out, "/");
1081 }
1082 }
1083 else if (*argv[i] != '/')
1084 {
1085 quote_file_name (cwd, out);
1086 fprintf (out, "/");
1087 }
1088
1089 quote_file_name (argv[i], out);
1090 fprintf (out, " ");
1091 }
1092 }
1093 else
1094 {
1095 if (!here)
1096 {
1097 while ((str = fgets (string, BUFSIZ, stdin)))
1098 {
1099 quote_file_name (str, out);
1100 }
1101 fprintf (out, " ");
1102 }
1103 }
1104
1105 fprintf (out, "\n");
1106 fflush (out);
1107
1108 /* Maybe wait for an answer. */
1109 if (nowait)
1110 {
1111 reset_tty ();
1112 return 0;
1113 }
1114
1115 if (here)
1116 {
1117 if (! pty_conversation (out))
1118 {
1119 reset_tty ();
1120 fprintf (stderr, "%s: ", argv[0]);
1121 perror ("fdopen");
1122 fail (argc, argv);
1123 }
1124 close (master);
1125 reset_tty ();
1126 return 0;
1127 }
1128
1129 if (!eval)
1130 {
1131 printf ("Waiting for Emacs...");
1132 needlf = 2;
1133 }
1134 fflush (stdout);
1135
1136 /* Now, wait for an answer and print any messages. */
1137 while ((str = fgets (string, BUFSIZ, in)))
1138 {
1139 if (needlf == 2)
1140 printf ("\n");
1141 printf ("%s", str);
1142 needlf = str[0] == '\0' ? needlf : str[strlen (str) - 1] != '\n';
1143 }
1144
1145 if (needlf)
1146 printf ("\n");
1147 fflush (stdout);
1148
1149 reset_tty ();
1150 return 0;
1151 }
1152
1153 #endif /* HAVE_SOCKETS */
1154 \f
1155 #ifndef HAVE_STRERROR
1156 char *
1157 strerror (errnum)
1158 int errnum;
1159 {
1160 extern char *sys_errlist[];
1161 extern int sys_nerr;
1162
1163 if (errnum >= 0 && errnum < sys_nerr)
1164 return sys_errlist[errnum];
1165 return (char *) "Unknown error";
1166 }
1167
1168 #endif /* ! HAVE_STRERROR */
1169
1170 /* arch-tag: f39bb9c4-73eb-477e-896d-50832e2ca9a7
1171 (do not change this comment) */