emacsclient.c 45.2 KB
Newer Older
Jim Blandy's avatar
Jim Blandy committed
1
/* Client process that communicates with GNU Emacs acting as server.
2

3
Copyright (C) 1986-1987, 1994, 1999-2014 Free Software Foundation, Inc.
Richard M. Stallman's avatar
Richard M. Stallman committed
4 5 6

This file is part of GNU Emacs.

7
GNU Emacs is free software: you can redistribute it and/or modify
Richard M. Stallman's avatar
Richard M. Stallman committed
8
it under the terms of the GNU General Public License as published by
9 10
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Richard M. Stallman's avatar
Richard M. Stallman committed
11 12 13 14 15 16 17

GNU Emacs is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
18
along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
Richard M. Stallman's avatar
Richard M. Stallman committed
19 20


Pavel Janík's avatar
Pavel Janík committed
21
#include <config.h>
22

23 24
#ifdef WINDOWSNT

25
/* ms-w32.h defines these, which disables sockets altogether!  */
26 27 28
# undef _WINSOCKAPI_
# undef _WINSOCK_H

29 30
# include <malloc.h>
# include <stdlib.h>
Juanma Barranquero's avatar
Juanma Barranquero committed
31
# include <windows.h>
32
# include <commctrl.h>
Dan Nicolaescu's avatar
Dan Nicolaescu committed
33 34
# include <io.h>
# include <winsock2.h>
35 36 37

# define NO_SOCKETS_IN_FILE_SYSTEM

38 39 40
# define HSOCKET SOCKET
# define CLOSE_SOCKET closesocket
# define INITIALIZE() (initialize_sockets ())
41

Dan Nicolaescu's avatar
Dan Nicolaescu committed
42 43 44
char *w32_getenv (char *);
#define egetenv(VAR) w32_getenv(VAR)

45 46
#else /* !WINDOWSNT */

47 48 49 50
# ifdef HAVE_NTGUI
# include <windows.h>
# endif /* HAVE_NTGUI */

51
# include "syswait.h"
52

53 54
# ifdef HAVE_INET_SOCKETS
#  include <netinet/in.h>
Dan Nicolaescu's avatar
Dan Nicolaescu committed
55 56 57 58 59
#  ifdef HAVE_SOCKETS
#    include <sys/types.h>
#    include <sys/socket.h>
#    include <sys/un.h>
#  endif /* HAVE_SOCKETS */
60
# endif
Dan Nicolaescu's avatar
Dan Nicolaescu committed
61
# include <arpa/inet.h>
Dan Nicolaescu's avatar
Dan Nicolaescu committed
62

63
# define INVALID_SOCKET -1
64 65 66
# define HSOCKET int
# define CLOSE_SOCKET close
# define INITIALIZE()
67

Dan Nicolaescu's avatar
Dan Nicolaescu committed
68 69
#define egetenv(VAR) getenv(VAR)

70
#endif /* !WINDOWSNT */
71

72
#undef signal
Richard M. Stallman's avatar
Richard M. Stallman committed
73

Juanma Barranquero's avatar
Juanma Barranquero committed
74
#include <stdarg.h>
75
#include <ctype.h>
76
#include <stdio.h>
77
#include <getopt.h>
Paul Eggert's avatar
Paul Eggert committed
78
#include <unistd.h>
79

Dan Nicolaescu's avatar
Dan Nicolaescu committed
80
#include <pwd.h>
81
#include <sys/stat.h>
82
#include <signal.h>
83
#include <errno.h>
84

85 86 87 88
#ifndef VERSION
#define VERSION "unspecified"
#endif

89 90 91 92 93 94 95 96 97

#ifndef EXIT_SUCCESS
#define EXIT_SUCCESS 0
#endif

#ifndef EXIT_FAILURE
#define EXIT_FAILURE 1
#endif

98 99 100
/* Additional space when allocating buffers for filenames, etc.  */
#define EXTRA_SPACE 100

101 102 103
#ifdef min
#undef min
#endif
104 105
#define min(x, y) (((x) < (y)) ? (x) : (y))

106

107
/* Name used to invoke this program.  */
Dan Nicolaescu's avatar
Dan Nicolaescu committed
108
const char *progname;
109

Karoly Lorentey's avatar
Karoly Lorentey committed
110 111 112
/* The second argument to main. */
char **main_argv;

113
/* Nonzero means don't wait for a response from Emacs.  --no-wait.  */
114 115
int nowait = 0;

116 117 118
/* Nonzero means don't print messages for successful operations.  --quiet. */
int quiet = 0;

Stefan Monnier's avatar
Stefan Monnier committed
119 120 121
/* Nonzero means args are expressions to be evaluated.  --eval.  */
int eval = 0;

122 123
/* Nonzero means don't open a new frame.  Inverse of --create-frame.  */
int current_frame = 1;
124

Stefan Monnier's avatar
Stefan Monnier committed
125
/* The display on which Emacs should work.  --display.  */
126
const char *display = NULL;
Stefan Monnier's avatar
Stefan Monnier committed
127

128 129 130
/* The alternate display we should try if Emacs does not support display.  */
const char *alt_display = NULL;

131 132 133
/* The parent window ID, if we are opening a frame via XEmbed.  */
char *parent_id = NULL;

134
/* Nonzero means open a new Emacs frame on the current terminal. */
135
int tty = 0;
136

Stefan Monnier's avatar
Stefan Monnier committed
137 138
/* If non-NULL, the name of an editor to fallback to if the server
   is not running.  --alternate-editor.   */
139
const char *alternate_editor = NULL;
Stefan Monnier's avatar
Stefan Monnier committed
140

Richard M. Stallman's avatar
Richard M. Stallman committed
141
/* If non-NULL, the filename of the UNIX socket.  */
142
const char *socket_name = NULL;
143

144
/* If non-NULL, the filename of the authentication file.  */
145
const char *server_file = NULL;
146

147 148 149
/* PID of the Emacs server process.  */
int emacs_pid = 0;

150 151 152 153
/* If non-NULL, a string that should form a frame parameter alist to
   be used for the new frame */
const char *frame_parameters = NULL;

154
static _Noreturn void print_help_and_exit (void);
155

156

157 158
struct option longopts[] =
{
159
  { "no-wait",	no_argument,	   NULL, 'n' },
160
  { "quiet",	no_argument,	   NULL, 'q' },
Stefan Monnier's avatar
Stefan Monnier committed
161
  { "eval",	no_argument,	   NULL, 'e' },
162 163
  { "help",	no_argument,	   NULL, 'H' },
  { "version",	no_argument,	   NULL, 'V' },
164
  { "tty",	no_argument,       NULL, 't' },
165
  { "nw",	no_argument,       NULL, 't' },
166
  { "create-frame", no_argument,   NULL, 'c' },
Stefan Monnier's avatar
Stefan Monnier committed
167
  { "alternate-editor", required_argument, NULL, 'a' },
168
  { "frame-parameters", required_argument, NULL, 'F' },
169
#ifndef NO_SOCKETS_IN_FILE_SYSTEM
170
  { "socket-name",	required_argument, NULL, 's' },
171
#endif
172
  { "server-file",	required_argument, NULL, 'f' },
Stefan Monnier's avatar
Stefan Monnier committed
173
  { "display",	required_argument, NULL, 'd' },
174
  { "parent-id", required_argument, NULL, 'p' },
Stefan Monnier's avatar
Stefan Monnier committed
175
  { 0, 0, 0, 0 }
176 177
};

178 179 180

/* Like malloc but get fatal error if memory is exhausted.  */

181 182
static void *
xmalloc (size_t size)
183
{
184
  void *result = malloc (size);
185 186 187 188 189 190 191 192 193 194 195
  if (result == NULL)
    {
      perror ("malloc");
      exit (EXIT_FAILURE);
    }
  return result;
}

/* From sysdep.c */
#if !defined (HAVE_GET_CURRENT_DIR_NAME) || defined (BROKEN_GET_CURRENT_DIR_NAME)

196
char *get_current_dir_name (void);
197

198
/* Return the current working directory.  Returns NULL on errors.
199
   Any other returned value must be freed with free.  This is used
200 201
   only when get_current_dir_name is not defined on the system.  */
char*
202
get_current_dir_name (void)
203 204
{
  char *buf;
205
  const char *pwd;
206
  struct stat dotstat, pwdstat;
207
  /* If PWD is accurate, use it instead of calling getcwd.  PWD is
208 209
     sometimes a nicer name, and using it may avoid a fatal error if a
     parent directory is searchable but not readable.  */
210
    if ((pwd = egetenv ("PWD")) != 0
211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228
      && (IS_DIRECTORY_SEP (*pwd) || (*pwd && IS_DEVICE_SEP (pwd[1])))
      && stat (pwd, &pwdstat) == 0
      && stat (".", &dotstat) == 0
      && dotstat.st_ino == pwdstat.st_ino
      && dotstat.st_dev == pwdstat.st_dev
#ifdef MAXPATHLEN
      && strlen (pwd) < MAXPATHLEN
#endif
      )
    {
      buf = (char *) xmalloc (strlen (pwd) + 1);
      strcpy (buf, pwd);
    }
  else
    {
      size_t buf_size = 1024;
      for (;;)
        {
229 230 231 232
	  int tmp_errno;
	  buf = malloc (buf_size);
	  if (! buf)
	    break;
233 234
          if (getcwd (buf, buf_size) == buf)
            break;
235 236 237
	  tmp_errno = errno;
	  free (buf);
	  if (tmp_errno != ERANGE)
238 239 240 241 242
            {
              errno = tmp_errno;
              return NULL;
            }
          buf_size *= 2;
243 244 245 246 247
	  if (! buf_size)
	    {
	      errno = ENOMEM;
	      return NULL;
	    }
248 249 250 251 252 253
        }
    }
  return buf;
}
#endif

Juanma Barranquero's avatar
Juanma Barranquero committed
254
#ifdef WINDOWSNT
255

256 257 258 259 260 261 262 263 264 265 266 267 268 269
/* Like strdup but get a fatal error if memory is exhausted. */

char *
xstrdup (const char *s)
{
  char *result = strdup (s);
  if (result == NULL)
    {
      perror ("strdup");
      exit (EXIT_FAILURE);
    }
  return result;
}

270 271 272 273 274 275
#define REG_ROOT "SOFTWARE\\GNU\\Emacs"

/* Retrieve an environment variable from the Emacs subkeys of the registry.
   Return NULL if the variable was not found, or it was empty.
   This code is based on w32_get_resource (w32.c).  */
char *
276
w32_get_resource (HKEY predefined, char *key, LPDWORD type)
277 278 279 280 281 282 283 284 285 286 287
{
  HKEY hrootkey = NULL;
  char *result = NULL;
  DWORD cbData;

  if (RegOpenKeyEx (predefined, REG_ROOT, 0, KEY_READ, &hrootkey) == ERROR_SUCCESS)
    {
      if (RegQueryValueEx (hrootkey, key, NULL, NULL, NULL, &cbData) == ERROR_SUCCESS)
	{
	  result = (char *) xmalloc (cbData);

288 289
	  if ((RegQueryValueEx (hrootkey, key, NULL, type, result, &cbData) != ERROR_SUCCESS)
	      || (*result == 0))
290 291 292 293 294 295 296 297 298 299 300 301 302 303 304
	    {
	      free (result);
	      result = NULL;
	    }
	}

      RegCloseKey (hrootkey);
    }

  return result;
}

/*
  getenv wrapper for Windows

305 306 307 308 309
  Value is allocated on the heap, and can be free'd.

  This is needed to duplicate Emacs's behavior, which is to look for
  environment variables in the registry if they don't appear in the
  environment.  */
310
char *
311
w32_getenv (char *envvar)
312 313 314 315
{
  char *value;
  DWORD dwType;

316
  if ((value = getenv (envvar)))
317 318 319
    /* Found in the environment.  strdup it, because values returned
       by getenv cannot be free'd.  */
    return xstrdup (value);
320 321 322

  if (! (value = w32_get_resource (HKEY_CURRENT_USER, envvar, &dwType)) &&
      ! (value = w32_get_resource (HKEY_LOCAL_MACHINE, envvar, &dwType)))
323 324 325
    {
      /* "w32console" is what Emacs on Windows uses for tty-type under -nw.  */
      if (strcmp (envvar, "TERM") == 0)
326
	return xstrdup ("w32console");
327 328 329
      /* Found neither in the environment nor in the registry.  */
      return NULL;
    }
330 331 332 333 334 335 336 337 338

  if (dwType == REG_SZ)
    /* Registry; no need to expand.  */
    return value;

  if (dwType == REG_EXPAND_SZ)
    {
      DWORD size;

339
      if ((size = ExpandEnvironmentStrings (value, NULL, 0)))
340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358
	{
	  char *buffer = (char *) xmalloc (size);
	  if (ExpandEnvironmentStrings (value, buffer, size))
	    {
	      /* Found and expanded.  */
	      free (value);
	      return buffer;
	    }

	  /* Error expanding.  */
	  free (buffer);
	}
    }

  /* Not the right type, or not correctly expanded.  */
  free (value);
  return NULL;
}

359

Juanma Barranquero's avatar
Juanma Barranquero committed
360
int
361
w32_window_app (void)
Juanma Barranquero's avatar
Juanma Barranquero committed
362 363 364 365 366
{
  static int window_app = -1;
  char szTitle[MAX_PATH];

  if (window_app < 0)
367 368 369 370 371
    {
      /* Checking for STDOUT does not work; it's a valid handle also in
         nonconsole apps.  Testing for the console title seems to work. */
      window_app = (GetConsoleTitleA (szTitle, MAX_PATH) == 0);
      if (window_app)
372
        InitCommonControls ();
373
    }
Juanma Barranquero's avatar
Juanma Barranquero committed
374 375 376

  return window_app;
}
Dan Nicolaescu's avatar
Dan Nicolaescu committed
377

378
/* execvp wrapper for Windows.  Quotes arguments with embedded spaces.
Dan Nicolaescu's avatar
Dan Nicolaescu committed
379 380 381 382

  This is necessary due to the broken implementation of exec* routines in
  the Microsoft libraries: they concatenate the arguments together without
  quoting special characters, and pass the result to CreateProcess, with
383
  predictably bad results.  By contrast, POSIX execvp passes the arguments
384 385
  directly into the argv array of the child process.  */

Dan Nicolaescu's avatar
Dan Nicolaescu committed
386
int
387
w32_execvp (const char *path, char **argv)
Dan Nicolaescu's avatar
Dan Nicolaescu committed
388 389
{
  int i;
390
  extern int execvp (const char*, char **);
Dan Nicolaescu's avatar
Dan Nicolaescu committed
391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408

  /* Required to allow a .BAT script as alternate editor.  */
  argv[0] = (char *) alternate_editor;

  for (i = 0; argv[i]; i++)
    if (strchr (argv[i], ' '))
      {
	char *quoted = alloca (strlen (argv[i]) + 3);
	sprintf (quoted, "\"%s\"", argv[i]);
	argv[i] = quoted;
      }

  return execvp (path, argv);
}

#undef execvp
#define execvp w32_execvp

409 410 411 412 413 414 415
/* Emulation of ttyname for Windows.  */
char *
ttyname (int fd)
{
  return "CONOUT$";
}

Dan Nicolaescu's avatar
Dan Nicolaescu committed
416
#endif /* WINDOWSNT */
Juanma Barranquero's avatar
Juanma Barranquero committed
417

Juanma Barranquero's avatar
Juanma Barranquero committed
418 419
/* Display a normal or error message.
   On Windows, use a message box if compiled as a Windows app.  */
420
static void message (bool, const char *, ...) ATTRIBUTE_FORMAT_PRINTF (2, 3);
421
static void
422
message (bool is_error, const char *format, ...)
Juanma Barranquero's avatar
Juanma Barranquero committed
423 424 425
{
  va_list args;

426
  va_start (args, format);
Juanma Barranquero's avatar
Juanma Barranquero committed
427 428 429 430

#ifdef WINDOWSNT
  if (w32_window_app ())
    {
431 432 433 434
      char msg[2048];
      vsnprintf (msg, sizeof msg, format, args);
      msg[sizeof msg - 1] = '\0';

Juanma Barranquero's avatar
Juanma Barranquero committed
435 436 437 438 439 440 441
      if (is_error)
	MessageBox (NULL, msg, "Emacsclient ERROR", MB_ICONERROR);
      else
	MessageBox (NULL, msg, "Emacsclient", MB_ICONINFORMATION);
    }
  else
#endif
442 443 444
    {
      FILE *f = is_error ? stderr : stdout;

445
      vfprintf (f, format, args);
446 447
      fflush (f);
    }
448 449

  va_end (args);
Juanma Barranquero's avatar
Juanma Barranquero committed
450 451
}

452
/* Decode the options from argv and argc.
453
   The global variable `optind' will say how many arguments we used up.  */
454

455
static void
456
decode_options (int argc, char **argv)
457
{
458
  alternate_editor = egetenv ("ALTERNATE_EDITOR");
459

460 461
  while (1)
    {
462
      int opt = getopt_long_only (argc, argv,
463
#ifndef NO_SOCKETS_IN_FILE_SYSTEM
464
			     "VHneqa:s:f:d:F:tc",
465
#else
466
			     "VHneqa:f:d:F:tc",
467
#endif
468
			     longopts, 0);
469 470 471 472 473 474 475 476 477 478

      if (opt == EOF)
	break;

      switch (opt)
	{
	case 0:
	  /* If getopt returns 0, then it has already processed a
	     long-named option.  We should do nothing.  */
	  break;
479

480 481 482
	case 'a':
	  alternate_editor = optarg;
	  break;
483

484
#ifndef NO_SOCKETS_IN_FILE_SYSTEM
485 486 487
	case 's':
	  socket_name = optarg;
	  break;
488
#endif
489

490 491 492
	case 'f':
	  server_file = optarg;
	  break;
493

494 495 496 497
	  /* We used to disallow this argument in w32, but it seems better
	     to allow it, for the occasional case where the user is
	     connecting with a w32 client to a server compiled with X11
	     support.  */
Stefan Monnier's avatar
Stefan Monnier committed
498 499 500 501
	case 'd':
	  display = optarg;
	  break;

502 503 504 505
	case 'n':
	  nowait = 1;
	  break;

Stefan Monnier's avatar
Stefan Monnier committed
506 507 508 509
	case 'e':
	  eval = 1;
	  break;

510 511 512 513
	case 'q':
	  quiet = 1;
	  break;

514
	case 'V':
515
	  message (false, "emacsclient %s\n", VERSION);
516
	  exit (EXIT_SUCCESS);
517
	  break;
Richard M. Stallman's avatar
Richard M. Stallman committed
518

519
        case 't':
520
          tty = 1;
521
	  current_frame = 0;
522 523
          break;

524
        case 'c':
525
          current_frame = 0;
526
          break;
527

528 529 530 531 532
	case 'p':
	  parent_id = optarg;
          current_frame = 0;
	  break;

533 534
	case 'H':
	  print_help_and_exit ();
535 536
	  break;

537 538 539 540
        case 'F':
          frame_parameters = optarg;
          break;

541
	default:
542
	  message (true, "Try `%s --help' for more information\n", progname);
543
	  exit (EXIT_FAILURE);
544
	  break;
545 546
	}
    }
547

548 549 550 551 552
  /* If the -c option is used (without -t) and no --display argument
     is provided, try $DISPLAY.
     Without the -c option, we used to set `display' to $DISPLAY by
     default, but this changed the default behavior and is sometimes
     inconvenient.  So we force users to use "--display $DISPLAY" if
553 554 555 556 557 558
     they want Emacs to connect to their current display.

     Some window systems have a notion of default display not
     reflected in the DISPLAY variable.  If the user didn't give us an
     explicit display, try this platform-specific after trying the
     display in DISPLAY (if any).  */
559
  if (!current_frame && !tty && !display)
560
    {
561 562 563 564 565
      /* Set these here so we use a default_display only when the user
         didn't give us an explicit display.  */
#if defined (NS_IMPL_COCOA)
      alt_display = "ns";
#elif defined (HAVE_NTGUI)
566
      alt_display = "w32";
567
#endif
568 569 570 571 572 573 574 575

      display = egetenv ("DISPLAY");
    }

  if (!display)
    {
      display = alt_display;
      alt_display = NULL;
576
    }
577

578
  /* A null-string display is invalid.  */
579 580 581
  if (display && strlen (display) == 0)
    display = NULL;

582 583
  /* If no display is available, new frames are tty frames.  */
  if (!current_frame && !display)
584
    tty = 1;
585

586
#ifdef WINDOWSNT
587 588 589 590 591 592 593 594 595 596 597 598
  /* Emacs on Windows does not support graphical and text terminal
     frames in the same instance.  So, treat the -t and -c options as
     equivalent, and open a new frame on the server's terminal.
     Ideally, we would only set tty = 1 when the serve is running in a
     console, but alas we don't know that.  As a workaround, always
     ask for a tty frame, and let server.el figure it out.  */
  if (!current_frame)
    {
      display = NULL;
      tty = 1;
    }

Dan Nicolaescu's avatar
Dan Nicolaescu committed
599
  if (alternate_editor && alternate_editor[0] == '\0')
600
    {
601
      message (true, "--alternate-editor argument or ALTERNATE_EDITOR variable cannot be\n\
602 603 604 605
an empty string");
      exit (EXIT_FAILURE);
    }
#endif /* WINDOWSNT */
606 607
}

608

609
static _Noreturn void
610
print_help_and_exit (void)
611
{
612 613 614 615
  /* Spaces and tabs are significant in this message; they're chosen so the
     message aligns properly both in a tty and in a Windows message box.
     Please try to preserve them; otherwise the output is very hard to read
     when using emacsclientw.  */
616
  message (false,
Paul Eggert's avatar
Paul Eggert committed
617
	   "Usage: %s [OPTIONS] FILE...\n%s%s%s", progname, "\
Stefan Monnier's avatar
Stefan Monnier committed
618 619
Tell the Emacs server to visit the specified files.\n\
Every FILE can be either just a FILENAME or [+LINE[:COLUMN]] FILENAME.\n\
620
\n\
Stefan Monnier's avatar
Stefan Monnier committed
621
The following OPTIONS are accepted:\n\
622 623
-V, --version		Just print version info and return\n\
-H, --help    		Print this usage information message\n\
624
-nw, -t, --tty 		Open a new Emacs frame on the current terminal\n\
625
-c, --create-frame    	Create a new frame instead of trying to\n\
626
			use the current Emacs frame\n\
Paul Eggert's avatar
Paul Eggert committed
627
", "\
628
-F ALIST, --frame-parameters=ALIST\n\
629
			Set the parameters of a new frame\n\
630
-e, --eval    		Evaluate the FILE arguments as ELisp expressions\n\
631
-n, --no-wait		Don't wait for the server to return\n\
632
-q, --quiet		Don't display messages on success\n\
633
-d DISPLAY, --display=DISPLAY\n\
634
			Visit the file in the given display\n\
Paul Eggert's avatar
Paul Eggert committed
635
", "\
636
--parent-id=ID          Open in parent window ID, via XEmbed\n"
637
#ifndef NO_SOCKETS_IN_FILE_SYSTEM
638
"-s SOCKET, --socket-name=SOCKET\n\
639
			Set filename of the UNIX socket for communication\n"
640
#endif
641
"-f SERVER, --server-file=SERVER\n\
642
			Set filename of the TCP authentication file\n\
643
-a EDITOR, --alternate-editor=EDITOR\n\
644
			Editor to fallback to if the server is not running\n"
645
#ifndef WINDOWSNT
646 647
"			If EDITOR is the empty string, start Emacs in daemon\n\
			mode and try connecting again\n"
648
#endif /* not WINDOWSNT */
649
"\n\
Paul Eggert's avatar
Paul Eggert committed
650
Report bugs with M-x report-emacs-bug.\n");
651
  exit (EXIT_SUCCESS);
652
}
653

654 655 656 657
/* Try to run a different command, or --if no alternate editor is
   defined-- exit with an errorcode.
   Uses argv, but gets it from the global variable main_argv.  */

658
static _Noreturn void
659
fail (void)
Karoly Lorentey's avatar
Karoly Lorentey committed
660
{
661
  if (alternate_editor)
Karoly Lorentey's avatar
Karoly Lorentey committed
662
    {
663
      int i = optind - 1;
664

665
      execvp (alternate_editor, main_argv + i);
666
      message (true, "%s: error executing alternate editor \"%s\"\n",
667
	       progname, alternate_editor);
Karoly Lorentey's avatar
Karoly Lorentey committed
668
    }
669
  exit (EXIT_FAILURE);
Karoly Lorentey's avatar
Karoly Lorentey committed
670 671
}

672

673
#if !defined (HAVE_SOCKETS) || !defined (HAVE_INET_SOCKETS)
Karoly Lorentey's avatar
Karoly Lorentey committed
674

675
int
Dan Nicolaescu's avatar
Dan Nicolaescu committed
676
main (int argc, char **argv)
Karoly Lorentey's avatar
Karoly Lorentey committed
677
{
678 679
  main_argv = argv;
  progname = argv[0];
680
  message (true, "%s: Sorry, the Emacs server is supported only\n"
681
	   "on systems with Berkeley sockets.\n",
682
	   argv[0]);
683
  fail ();
Karoly Lorentey's avatar
Karoly Lorentey committed
684 685
}

686
#else /* HAVE_SOCKETS && HAVE_INET_SOCKETS */
687

688 689 690 691 692 693
#define AUTH_KEY_LENGTH      64
#define SEND_BUFFER_SIZE   4096

/* Buffer to accumulate data to send in TCP connections.  */
char send_buffer[SEND_BUFFER_SIZE + 1];
int sblen = 0;	/* Fill pointer for the send buffer.  */
Jason Rumney's avatar
Jason Rumney committed
694 695
/* Socket used to communicate with the Emacs server process.  */
HSOCKET emacs_socket = 0;
696

697 698 699
/* On Windows, the socket library was historically separate from the
   standard C library, so errors are handled differently.  */

700
static void
701
sock_err_message (const char *function_name)
702 703 704 705 706 707 708 709 710
{
#ifdef WINDOWSNT
  char* msg = NULL;

  FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM
                 | FORMAT_MESSAGE_ALLOCATE_BUFFER
                 | FORMAT_MESSAGE_ARGUMENT_ARRAY,
                 NULL, WSAGetLastError (), 0, (LPTSTR)&msg, 0, NULL);

711
  message (true, "%s: %s: %s\n", progname, function_name, msg);
712 713 714

  LocalFree (msg);
#else
715
  message (true, "%s: %s: %s\n", progname, function_name, strerror (errno));
716 717 718 719
#endif
}


720 721 722 723
/* Let's send the data to Emacs when either
   - the data ends in "\n", or
   - the buffer is full (but this shouldn't happen)
   Otherwise, we just accumulate it.  */
724
static void
725
send_to_emacs (HSOCKET s, const char *data)
726
{
727 728 729 730 731 732 733
  size_t dlen;

  if (!data)
    return;

  dlen = strlen (data);
  while (*data)
734
    {
735 736 737 738
      size_t part = min (dlen, SEND_BUFFER_SIZE - sblen);
      memcpy (&send_buffer[sblen], data, part);
      data += part;
      sblen += part;
739 740 741 742 743

      if (sblen == SEND_BUFFER_SIZE
	  || (sblen > 0 && send_buffer[sblen-1] == '\n'))
	{
	  int sent = send (s, send_buffer, sblen, 0);
744 745
	  if (sent < 0)
	    {
746
	      message (true, "%s: failed to send %d bytes to socket: %s\n",
747 748 749
		       progname, sblen, strerror (errno));
	      fail ();
	    }
750
	  if (sent != sblen)
751
	    memmove (send_buffer, &send_buffer[sent], sblen - sent);
752 753
	  sblen -= sent;
	}
754 755

      dlen -= part;
756 757 758 759
    }
}


760
/* In STR, insert a & before each &, each space, each newline, and
Richard M. Stallman's avatar
Richard M. Stallman committed
761
   any initial -.  Change spaces to underscores, too, so that the
762 763
   return value never contains a space.

Juanma Barranquero's avatar
Juanma Barranquero committed
764
   Does not change the string.  Outputs the result to S.  */
765
static void
766
quote_argument (HSOCKET s, const char *str)
767
{
Karoly Lorentey's avatar
Karoly Lorentey committed
768
  char *copy = (char *) xmalloc (strlen (str) * 2 + 1);
769 770
  const char *p;
  char *q;
771

772
  p = str;
773 774 775 776 777
  q = copy;
  while (*p)
    {
      if (*p == ' ')
	{
778
	  *q++ = '&';
779 780 781
	  *q++ = '_';
	  p++;
	}
Stefan Monnier's avatar
Stefan Monnier committed
782 783 784 785 786 787
      else if (*p == '\n')
	{
	  *q++ = '&';
	  *q++ = 'n';
	  p++;
	}
788 789
      else
	{
790
	  if (*p == '&' || (*p == '-' && p == str))
791
	    *q++ = '&';
792 793 794
	  *q++ = *p++;
	}
    }
795
  *q++ = 0;
796

Jason Rumney's avatar
Jason Rumney committed
797
  send_to_emacs (s, copy);
798 799

  free (copy);
800
}
801

802 803

/* The inverse of quote_argument.  Removes quoting in string STR by
804
   modifying the string in place.   Returns STR.  */
805

806
static char *
807
unquote_argument (char *str)
808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835
{
  char *p, *q;

  if (! str)
    return str;

  p = str;
  q = str;
  while (*p)
    {
      if (*p == '&')
        {
          p++;
          if (*p == '&')
            *p = '&';
          else if (*p == '_')
            *p = ' ';
          else if (*p == 'n')
            *p = '\n';
          else if (*p == '-')
            *p = '-';
        }
      *q++ = *p++;
    }
  *q = 0;
  return str;
}

836

837
static int
838
file_name_absolute_p (const char *filename)
839 840
{
  /* Sanity check, it shouldn't happen.  */
841
  if (! filename) return false;
842 843

  /* /xxx is always an absolute path.  */
844
  if (filename[0] == '/') return true;
845 846

  /* Empty filenames (which shouldn't happen) are relative.  */
847
  if (filename[0] == '\0') return false;
848 849

#ifdef WINDOWSNT
850
  /* X:\xxx is always absolute.  */
851
  if (isalpha ((unsigned char) filename[0])
852
      && filename[1] == ':' && (filename[2] == '\\' || filename[2] == '/'))
853
    return true;
854 855

  /* Both \xxx and \\xxx\yyy are absolute.  */
856
  if (filename[0] == '\\') return true;
857 858
#endif

859
  return false;
860 861
}

862
#ifdef WINDOWSNT
863
/* Wrapper to make WSACleanup a cdecl, as required by atexit.  */
864 865
void __cdecl
close_winsock (void)
866 867 868
{
  WSACleanup ();
}