PageRenderTime 216ms CodeModel.GetById 22ms app.highlight 147ms RepoModel.GetById 1ms app.codeStats 1ms

/contrib/cvs/src/client.c

https://bitbucket.org/freebsd/freebsd-head/
C | 5948 lines | 4003 code | 769 blank | 1176 comment | 924 complexity | 9511b64d9b8ee98d0142435b9235f1e7 MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, BSD-3-Clause, LGPL-2.0, LGPL-2.1, BSD-2-Clause, 0BSD, JSON, AGPL-1.0, GPL-2.0
   1/* CVS client-related stuff.
   2
   3   This program is free software; you can redistribute it and/or modify
   4   it under the terms of the GNU General Public License as published by
   5   the Free Software Foundation; either version 2, or (at your option)
   6   any later version.
   7
   8   This program is distributed in the hope that it will be useful,
   9   but WITHOUT ANY WARRANTY; without even the implied warranty of
  10   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11   GNU General Public License for more details.  */
  12
  13/*
  14 * $FreeBSD$
  15 */
  16
  17#ifdef HAVE_CONFIG_H
  18# include "config.h"
  19#endif /* HAVE_CONFIG_H */
  20
  21#include <assert.h>
  22#include "cvs.h"
  23#include "getline.h"
  24#include "edit.h"
  25#include "buffer.h"
  26#include "savecwd.h"
  27
  28#ifdef CLIENT_SUPPORT
  29
  30# include "md5.h"
  31
  32# if defined(AUTH_CLIENT_SUPPORT) || defined(HAVE_KERBEROS) || defined(HAVE_GSSAPI) || defined(SOCK_ERRNO) || defined(SOCK_STRERROR)
  33#   ifdef HAVE_WINSOCK_H
  34#     include <winsock.h>
  35#   else /* No winsock.h */
  36#     include <sys/socket.h>
  37#     include <netinet/in.h>
  38#     include <arpa/inet.h>
  39#     include <netdb.h>
  40#   endif /* No winsock.h */
  41# endif
  42
  43/* If SOCK_ERRNO is defined, then send()/recv() and other socket calls
  44   do not set errno, but that this macro should be used to obtain an
  45   error code.  This probably doesn't make sense unless
  46   NO_SOCKET_TO_FD is also defined. */
  47# ifndef SOCK_ERRNO
  48#   define SOCK_ERRNO errno
  49# endif
  50
  51/* If SOCK_STRERROR is defined, then the error codes returned by
  52   socket operations are not known to strerror, and this macro must be
  53   used instead to convert those error codes to strings. */
  54# ifndef SOCK_STRERROR
  55#   define SOCK_STRERROR strerror
  56
  57#   if STDC_HEADERS
  58#     include <string.h>
  59#   endif
  60
  61#   ifndef strerror
  62extern char *strerror ();
  63#   endif
  64# endif /* ! SOCK_STRERROR */
  65
  66# if HAVE_KERBEROS
  67
  68#   include <krb.h>
  69
  70extern char *krb_realmofhost ();
  71#   ifndef HAVE_KRB_GET_ERR_TEXT
  72#     define krb_get_err_text(status) krb_err_txt[status]
  73#   endif /* HAVE_KRB_GET_ERR_TEXT */
  74
  75/* Information we need if we are going to use Kerberos encryption.  */
  76static C_Block kblock;
  77static Key_schedule sched;
  78
  79# endif /* HAVE_KERBEROS */
  80
  81# ifdef HAVE_GSSAPI
  82
  83#   include "xgssapi.h"
  84
  85/* This is needed for GSSAPI encryption.  */
  86static gss_ctx_id_t gcontext;
  87
  88static int connect_to_gserver PROTO((cvsroot_t *, int, struct hostent *));
  89
  90# endif /* HAVE_GSSAPI */
  91
  92
  93
  94/* Keep track of any paths we are sending for Max-dotdot so that we can verify
  95 * that uplevel paths coming back form the server are valid.
  96 *
  97 * FIXME: The correct way to do this is probably provide some sort of virtual
  98 * path map on the client side.  This would be generic enough to be applied to
  99 * absolute paths supplied by the user too.
 100 */
 101static List *uppaths = NULL;
 102
 103
 104
 105static void add_prune_candidate PROTO((const char *));
 106
 107/* All the commands.  */
 108int add PROTO((int argc, char **argv));
 109int admin PROTO((int argc, char **argv));
 110int checkout PROTO((int argc, char **argv));
 111int commit PROTO((int argc, char **argv));
 112int diff PROTO((int argc, char **argv));
 113int history PROTO((int argc, char **argv));
 114int import PROTO((int argc, char **argv));
 115int cvslog PROTO((int argc, char **argv));
 116int patch PROTO((int argc, char **argv));
 117int release PROTO((int argc, char **argv));
 118int cvsremove PROTO((int argc, char **argv));
 119int rtag PROTO((int argc, char **argv));
 120int status PROTO((int argc, char **argv));
 121int tag PROTO((int argc, char **argv));
 122int update PROTO((int argc, char **argv));
 123
 124/* All the response handling functions.  */
 125static void handle_ok PROTO((char *, int));
 126static void handle_error PROTO((char *, int));
 127static void handle_valid_requests PROTO((char *, int));
 128static void handle_checked_in PROTO((char *, int));
 129static void handle_new_entry PROTO((char *, int));
 130static void handle_checksum PROTO((char *, int));
 131static void handle_copy_file PROTO((char *, int));
 132static void handle_updated PROTO((char *, int));
 133static void handle_merged PROTO((char *, int));
 134static void handle_patched PROTO((char *, int));
 135static void handle_rcs_diff PROTO((char *, int));
 136static void handle_removed PROTO((char *, int));
 137static void handle_remove_entry PROTO((char *, int));
 138static void handle_set_static_directory PROTO((char *, int));
 139static void handle_clear_static_directory PROTO((char *, int));
 140static void handle_set_sticky PROTO((char *, int));
 141static void handle_clear_sticky PROTO((char *, int));
 142static void handle_module_expansion PROTO((char *, int));
 143static void handle_wrapper_rcs_option PROTO((char *, int));
 144static void handle_m PROTO((char *, int));
 145static void handle_e PROTO((char *, int));
 146static void handle_f PROTO((char *, int));
 147static void handle_notified PROTO((char *, int));
 148
 149static size_t try_read_from_server PROTO ((char *, size_t));
 150
 151static void auth_server PROTO ((cvsroot_t *, struct buffer *, struct buffer *,
 152				int, int, struct hostent *));
 153
 154/* We need to keep track of the list of directories we've sent to the
 155   server.  This list, along with the current CVSROOT, will help us
 156   decide which command-line arguments to send.  */
 157List *dirs_sent_to_server = NULL;
 158
 159static int is_arg_a_parent_or_listed_dir PROTO((Node *, void *));
 160
 161static int
 162is_arg_a_parent_or_listed_dir (n, d)
 163    Node *n;
 164    void *d;
 165{
 166    char *directory = n->key;	/* name of the dir sent to server */
 167    char *this_argv_elem = xstrdup (d);	/* this argv element */
 168    int retval;
 169
 170    /* Say we should send this argument if the argument matches the
 171       beginning of a directory name sent to the server.  This way,
 172       the server will know to start at the top of that directory
 173       hierarchy and descend. */
 174
 175    strip_trailing_slashes (this_argv_elem);
 176    if (strncmp (directory, this_argv_elem, strlen (this_argv_elem)) == 0)
 177	retval = 1;
 178    else
 179	retval = 0;
 180
 181    free (this_argv_elem);
 182    return retval;
 183}
 184
 185static int arg_should_not_be_sent_to_server PROTO((char *));
 186
 187/* Return nonzero if this argument should not be sent to the
 188   server. */
 189
 190static int
 191arg_should_not_be_sent_to_server (arg)
 192    char *arg;
 193{
 194    /* Decide if we should send this directory name to the server.  We
 195       should always send argv[i] if:
 196
 197       1) the list of directories sent to the server is empty (as it
 198       will be for checkout, etc.).
 199
 200       2) the argument is "."
 201
 202       3) the argument is a file in the cwd and the cwd is checked out
 203       from the current root
 204
 205       4) the argument lies within one of the paths in
 206       dirs_sent_to_server.
 207
 208       */
 209
 210    if (list_isempty (dirs_sent_to_server))
 211	return 0;		/* always send it */
 212
 213    if (strcmp (arg, ".") == 0)
 214	return 0;		/* always send it */
 215
 216    /* We should send arg if it is one of the directories sent to the
 217       server or the parent of one; this tells the server to descend
 218       the hierarchy starting at this level. */
 219    if (isdir (arg))
 220    {
 221	if (walklist (dirs_sent_to_server, is_arg_a_parent_or_listed_dir, arg))
 222	    return 0;
 223
 224	/* If arg wasn't a parent, we don't know anything about it (we
 225	   would have seen something related to it during the
 226	   send_files phase).  Don't send it.  */
 227	return 1;
 228    }
 229
 230    /* Try to decide whether we should send arg to the server by
 231       checking the contents of the corresponding CVSADM directory. */
 232    {
 233	char *t, *root_string;
 234	cvsroot_t *this_root = NULL;
 235
 236	/* Calculate "dirname arg" */
 237	for (t = arg + strlen (arg) - 1; t >= arg; t--)
 238	{
 239	    if (ISDIRSEP(*t))
 240		break;
 241	}
 242
 243	/* Now we're either poiting to the beginning of the
 244	   string, or we found a path separator. */
 245	if (t >= arg)
 246	{
 247	    /* Found a path separator.  */
 248	    char c = *t;
 249	    *t = '\0';
 250	    
 251	    /* First, check to see if we sent this directory to the
 252               server, because it takes less time than actually
 253               opening the stuff in the CVSADM directory.  */
 254	    if (walklist (dirs_sent_to_server, is_arg_a_parent_or_listed_dir,
 255			  arg))
 256	    {
 257		*t = c;		/* make sure to un-truncate the arg */
 258		return 0;
 259	    }
 260
 261	    /* Since we didn't find it in the list, check the CVSADM
 262               files on disk.  */
 263	    this_root = Name_Root (arg, (char *) NULL);
 264	    root_string = this_root->original;
 265	    *t = c;
 266	}
 267	else
 268	{
 269	    /* We're at the beginning of the string.  Look at the
 270               CVSADM files in cwd.  */
 271	    if (CVSroot_cmdline)
 272		root_string = CVSroot_cmdline;
 273	    else
 274	    {
 275		this_root = Name_Root ((char *) NULL, (char *) NULL);
 276		root_string = this_root->original;
 277	    }
 278	}
 279
 280	/* Now check the value for root. */
 281	if (CVSroot_cmdline == NULL &&
 282	    root_string && current_parsed_root
 283	    && (strcmp (root_string, current_parsed_root->original) != 0))
 284	{
 285	    /* Don't send this, since the CVSROOTs don't match. */
 286	    if (this_root) free_cvsroot_t (this_root);
 287	    return 1;
 288	}
 289	if (this_root) free_cvsroot_t (this_root);
 290    }
 291    
 292    /* OK, let's send it. */
 293    return 0;
 294}
 295
 296
 297
 298#endif /* CLIENT_SUPPORT */
 299
 300
 301
 302#if defined(CLIENT_SUPPORT) || defined(SERVER_SUPPORT)
 303
 304/* Shared with server.  */
 305
 306/*
 307 * Return a malloc'd, '\0'-terminated string
 308 * corresponding to the mode in SB.
 309 */
 310char *
 311#ifdef __STDC__
 312mode_to_string (mode_t mode)
 313#else /* ! __STDC__ */
 314mode_to_string (mode)
 315	mode_t mode;
 316#endif /* __STDC__ */
 317{
 318    char buf[18], u[4], g[4], o[4];
 319    int i;
 320
 321    i = 0;
 322    if (mode & S_IRUSR) u[i++] = 'r';
 323    if (mode & S_IWUSR) u[i++] = 'w';
 324    if (mode & S_IXUSR) u[i++] = 'x';
 325    u[i] = '\0';
 326
 327    i = 0;
 328    if (mode & S_IRGRP) g[i++] = 'r';
 329    if (mode & S_IWGRP) g[i++] = 'w';
 330    if (mode & S_IXGRP) g[i++] = 'x';
 331    g[i] = '\0';
 332
 333    i = 0;
 334    if (mode & S_IROTH) o[i++] = 'r';
 335    if (mode & S_IWOTH) o[i++] = 'w';
 336    if (mode & S_IXOTH) o[i++] = 'x';
 337    o[i] = '\0';
 338
 339    sprintf(buf, "u=%s,g=%s,o=%s", u, g, o);
 340    return xstrdup(buf);
 341}
 342
 343/*
 344 * Change mode of FILENAME to MODE_STRING.
 345 * Returns 0 for success or errno code.
 346 * If RESPECT_UMASK is set, then honor the umask.
 347 */
 348int
 349change_mode (filename, mode_string, respect_umask)
 350    char *filename;
 351    char *mode_string;
 352    int respect_umask;
 353{
 354#ifdef CHMOD_BROKEN
 355    char *p;
 356    int writeable = 0;
 357
 358    /* We can only distinguish between
 359         1) readable
 360         2) writeable
 361         3) Picasso's "Blue Period"
 362       We handle the first two. */
 363    p = mode_string;
 364    while (*p != '\0')
 365    {
 366	if ((p[0] == 'u' || p[0] == 'g' || p[0] == 'o') && p[1] == '=')
 367	{
 368	    char *q = p + 2;
 369	    while (*q != ',' && *q != '\0')
 370	    {
 371		if (*q == 'w')
 372		    writeable = 1;
 373		++q;
 374	    }
 375	}
 376	/* Skip to the next field.  */
 377	while (*p != ',' && *p != '\0')
 378	    ++p;
 379	if (*p == ',')
 380	    ++p;
 381    }
 382
 383    /* xchmod honors the umask for us.  In the !respect_umask case, we
 384       don't try to cope with it (probably to handle that well, the server
 385       needs to deal with modes in data structures, rather than via the
 386       modes in temporary files).  */
 387    xchmod (filename, writeable);
 388	return 0;
 389
 390#else /* ! CHMOD_BROKEN */
 391
 392    char *p;
 393    mode_t mode = 0;
 394    mode_t oumask;
 395
 396    p = mode_string;
 397    while (*p != '\0')
 398    {
 399	if ((p[0] == 'u' || p[0] == 'g' || p[0] == 'o') && p[1] == '=')
 400	{
 401	    int can_read = 0, can_write = 0, can_execute = 0;
 402	    char *q = p + 2;
 403	    while (*q != ',' && *q != '\0')
 404	    {
 405		if (*q == 'r')
 406		    can_read = 1;
 407		else if (*q == 'w')
 408		    can_write = 1;
 409		else if (*q == 'x')
 410		    can_execute = 1;
 411		++q;
 412	    }
 413	    if (p[0] == 'u')
 414	    {
 415		if (can_read)
 416		    mode |= S_IRUSR;
 417		if (can_write)
 418		    mode |= S_IWUSR;
 419		if (can_execute)
 420		    mode |= S_IXUSR;
 421	    }
 422	    else if (p[0] == 'g')
 423	    {
 424		if (can_read)
 425		    mode |= S_IRGRP;
 426		if (can_write)
 427		    mode |= S_IWGRP;
 428		if (can_execute)
 429		    mode |= S_IXGRP;
 430	    }
 431	    else if (p[0] == 'o')
 432	    {
 433		if (can_read)
 434		    mode |= S_IROTH;
 435		if (can_write)
 436		    mode |= S_IWOTH;
 437		if (can_execute)
 438		    mode |= S_IXOTH;
 439	    }
 440	}
 441	/* Skip to the next field.  */
 442	while (*p != ',' && *p != '\0')
 443	    ++p;
 444	if (*p == ',')
 445	    ++p;
 446    }
 447
 448    if (respect_umask)
 449    {
 450	oumask = umask (0);
 451	(void) umask (oumask);
 452	mode &= ~oumask;
 453    }
 454
 455    if (chmod (filename, mode) < 0)
 456	return errno;
 457    return 0;
 458#endif /* ! CHMOD_BROKEN */
 459}
 460
 461#endif /* CLIENT_SUPPORT or SERVER_SUPPORT */
 462
 463#ifdef CLIENT_SUPPORT
 464
 465int client_prune_dirs;
 466
 467static List *ignlist = (List *) NULL;
 468
 469/* Buffer to write to the server.  */
 470static struct buffer *to_server;
 471
 472/* Buffer used to read from the server.  */
 473static struct buffer *from_server;
 474
 475
 476/* We want to be able to log data sent between us and the server.  We
 477   do it using log buffers.  Each log buffer has another buffer which
 478   handles the actual I/O, and a file to log information to.
 479
 480   This structure is the closure field of a log buffer.  */
 481
 482struct log_buffer
 483{
 484    /* The underlying buffer.  */
 485    struct buffer *buf;
 486    /* The file to log information to.  */
 487    FILE *log;
 488};
 489
 490static struct buffer *log_buffer_initialize
 491  PROTO((struct buffer *, FILE *, int, void (*) (struct buffer *)));
 492static int log_buffer_input PROTO((void *, char *, int, int, int *));
 493static int log_buffer_output PROTO((void *, const char *, int, int *));
 494static int log_buffer_flush PROTO((void *));
 495static int log_buffer_block PROTO((void *, int));
 496static int log_buffer_shutdown PROTO((struct buffer *));
 497
 498/* Create a log buffer.  */
 499
 500static struct buffer *
 501log_buffer_initialize (buf, fp, input, memory)
 502     struct buffer *buf;
 503     FILE *fp;
 504     int input;
 505     void (*memory) PROTO((struct buffer *));
 506{
 507    struct log_buffer *n;
 508
 509    n = (struct log_buffer *) xmalloc (sizeof *n);
 510    n->buf = buf;
 511    n->log = fp;
 512    return buf_initialize (input ? log_buffer_input : NULL,
 513			   input ? NULL : log_buffer_output,
 514			   input ? NULL : log_buffer_flush,
 515			   log_buffer_block,
 516			   log_buffer_shutdown,
 517			   memory,
 518			   n);
 519}
 520
 521/* The input function for a log buffer.  */
 522
 523static int
 524log_buffer_input (closure, data, need, size, got)
 525     void *closure;
 526     char *data;
 527     int need;
 528     int size;
 529     int *got;
 530{
 531    struct log_buffer *lb = (struct log_buffer *) closure;
 532    int status;
 533    size_t n_to_write;
 534
 535    if (lb->buf->input == NULL)
 536	abort ();
 537
 538    status = (*lb->buf->input) (lb->buf->closure, data, need, size, got);
 539    if (status != 0)
 540	return status;
 541
 542    if (*got > 0)
 543    {
 544	n_to_write = *got;
 545	if (fwrite (data, 1, n_to_write, lb->log) != n_to_write)
 546	    error (0, errno, "writing to log file");
 547    }
 548
 549    return 0;
 550}
 551
 552/* The output function for a log buffer.  */
 553
 554static int
 555log_buffer_output (closure, data, have, wrote)
 556     void *closure;
 557     const char *data;
 558     int have;
 559     int *wrote;
 560{
 561    struct log_buffer *lb = (struct log_buffer *) closure;
 562    int status;
 563    size_t n_to_write;
 564
 565    if (lb->buf->output == NULL)
 566	abort ();
 567
 568    status = (*lb->buf->output) (lb->buf->closure, data, have, wrote);
 569    if (status != 0)
 570	return status;
 571
 572    if (*wrote > 0)
 573    {
 574	n_to_write = *wrote;
 575	if (fwrite (data, 1, n_to_write, lb->log) != n_to_write)
 576	    error (0, errno, "writing to log file");
 577    }
 578
 579    return 0;
 580}
 581
 582/* The flush function for a log buffer.  */
 583
 584static int
 585log_buffer_flush (closure)
 586     void *closure;
 587{
 588    struct log_buffer *lb = (struct log_buffer *) closure;
 589
 590    if (lb->buf->flush == NULL)
 591	abort ();
 592
 593    /* We don't really have to flush the log file here, but doing it
 594       will let tail -f on the log file show what is sent to the
 595       network as it is sent.  */
 596    if (fflush (lb->log) != 0)
 597        error (0, errno, "flushing log file");
 598
 599    return (*lb->buf->flush) (lb->buf->closure);
 600}
 601
 602/* The block function for a log buffer.  */
 603
 604static int
 605log_buffer_block (closure, block)
 606     void *closure;
 607     int block;
 608{
 609    struct log_buffer *lb = (struct log_buffer *) closure;
 610
 611    if (block)
 612	return set_block (lb->buf);
 613    else
 614	return set_nonblock (lb->buf);
 615}
 616
 617/* The shutdown function for a log buffer.  */
 618
 619static int
 620log_buffer_shutdown (buf)
 621     struct buffer *buf;
 622{
 623    struct log_buffer *lb = (struct log_buffer *) buf->closure;
 624    int retval;
 625
 626    retval = buf_shutdown (lb->buf);
 627    if (fclose (lb->log) < 0)
 628	error (0, errno, "closing log file");
 629    return retval;
 630}
 631
 632#ifdef NO_SOCKET_TO_FD
 633
 634/* Under certain circumstances, we must communicate with the server
 635   via a socket using send() and recv().  This is because under some
 636   operating systems (OS/2 and Windows 95 come to mind), a socket
 637   cannot be converted to a file descriptor -- it must be treated as a
 638   socket and nothing else.
 639   
 640   We may also need to deal with socket routine error codes differently
 641   in these cases.  This is handled through the SOCK_ERRNO and
 642   SOCK_STRERROR macros. */
 643
 644/* These routines implement a buffer structure which uses send and
 645   recv.  The buffer is always in blocking mode so we don't implement
 646   the block routine.  */
 647
 648/* Note that it is important that these routines always handle errors
 649   internally and never return a positive errno code, since it would in
 650   general be impossible for the caller to know in general whether any
 651   error code came from a socket routine (to decide whether to use
 652   SOCK_STRERROR or simply strerror to print an error message). */
 653
 654/* We use an instance of this structure as the closure field.  */
 655
 656struct socket_buffer
 657{
 658    /* The socket number.  */
 659    int socket;
 660};
 661
 662static struct buffer *socket_buffer_initialize
 663  PROTO ((int, int, void (*) (struct buffer *)));
 664static int socket_buffer_input PROTO((void *, char *, int, int, int *));
 665static int socket_buffer_output PROTO((void *, const char *, int, int *));
 666static int socket_buffer_flush PROTO((void *));
 667static int socket_buffer_shutdown PROTO((struct buffer *));
 668
 669
 670
 671/* Create a buffer based on a socket.  */
 672
 673static struct buffer *
 674socket_buffer_initialize (socket, input, memory)
 675    int socket;
 676    int input;
 677    void (*memory) PROTO((struct buffer *));
 678{
 679    struct socket_buffer *n;
 680
 681    n = (struct socket_buffer *) xmalloc (sizeof *n);
 682    n->socket = socket;
 683    return buf_initialize (input ? socket_buffer_input : NULL,
 684			   input ? NULL : socket_buffer_output,
 685			   input ? NULL : socket_buffer_flush,
 686			   (int (*) PROTO((void *, int))) NULL,
 687			   socket_buffer_shutdown,
 688			   memory,
 689			   n);
 690}
 691
 692
 693
 694/* The buffer input function for a buffer built on a socket.  */
 695
 696static int
 697socket_buffer_input (closure, data, need, size, got)
 698     void *closure;
 699     char *data;
 700     int need;
 701     int size;
 702     int *got;
 703{
 704    struct socket_buffer *sb = (struct socket_buffer *) closure;
 705    int nbytes;
 706
 707    /* I believe that the recv function gives us exactly the semantics
 708       we want.  If there is a message, it returns immediately with
 709       whatever it could get.  If there is no message, it waits until
 710       one comes in.  In other words, it is not like read, which in
 711       blocking mode normally waits until all the requested data is
 712       available.  */
 713
 714    *got = 0;
 715
 716    do
 717    {
 718
 719	/* Note that for certain (broken?) networking stacks, like
 720	   VMS's UCX (not sure what version, problem reported with
 721	   recv() in 1997), and (according to windows-NT/config.h)
 722	   Windows NT 3.51, we must call recv or send with a
 723	   moderately sized buffer (say, less than 200K or something),
 724	   or else there may be network errors (somewhat hard to
 725	   produce, e.g. WAN not LAN or some such).  buf_read_data
 726	   makes sure that we only recv() BUFFER_DATA_SIZE bytes at
 727	   a time.  */
 728
 729	nbytes = recv (sb->socket, data, size, 0);
 730	if (nbytes < 0)
 731	    error (1, 0, "reading from server: %s", SOCK_STRERROR (SOCK_ERRNO));
 732	if (nbytes == 0)
 733	{
 734	    /* End of file (for example, the server has closed
 735	       the connection).  If we've already read something, we
 736	       just tell the caller about the data, not about the end of
 737	       file.  If we've read nothing, we return end of file.  */
 738	    if (*got == 0)
 739		return -1;
 740	    else
 741		return 0;
 742	}
 743	need -= nbytes;
 744	size -= nbytes;
 745	data += nbytes;
 746	*got += nbytes;
 747    }
 748    while (need > 0);
 749
 750    return 0;
 751}
 752
 753
 754
 755/* The buffer output function for a buffer built on a socket.  */
 756
 757static int
 758socket_buffer_output (closure, data, have, wrote)
 759     void *closure;
 760     const char *data;
 761     int have;
 762     int *wrote;
 763{
 764    struct socket_buffer *sb = (struct socket_buffer *) closure;
 765
 766    *wrote = have;
 767
 768    /* See comment in socket_buffer_input regarding buffer size we pass
 769       to send and recv.  */
 770
 771#ifdef SEND_NEVER_PARTIAL
 772    /* If send() never will produce a partial write, then just do it.  This
 773       is needed for systems where its return value is something other than
 774       the number of bytes written.  */
 775    if (send (sb->socket, data, have, 0) < 0)
 776	error (1, 0, "writing to server socket: %s", SOCK_STRERROR (SOCK_ERRNO));
 777#else
 778    while (have > 0)
 779    {
 780	int nbytes;
 781
 782	nbytes = send (sb->socket, data, have, 0);
 783	if (nbytes < 0)
 784	    error (1, 0, "writing to server socket: %s", SOCK_STRERROR (SOCK_ERRNO));
 785
 786	have -= nbytes;
 787	data += nbytes;
 788    }
 789#endif
 790
 791    return 0;
 792}
 793
 794
 795
 796/* The buffer flush function for a buffer built on a socket.  */
 797
 798/*ARGSUSED*/
 799static int
 800socket_buffer_flush (closure)
 801     void *closure;
 802{
 803    /* Nothing to do.  Sockets are always flushed.  */
 804    return 0;
 805}
 806
 807
 808
 809static int
 810socket_buffer_shutdown (buf)
 811    struct buffer *buf;
 812{
 813    struct socket_buffer *n = (struct socket_buffer *) buf->closure;
 814    char tmp;
 815
 816    /* no need to flush children of an endpoint buffer here */
 817
 818    if (buf->input)
 819    {
 820	int err = 0;
 821	if (! buf_empty_p (buf)
 822	    || (err = recv (n->socket, &tmp, 1, 0)) > 0)
 823	    error (0, 0, "dying gasps from %s unexpected", current_parsed_root->hostname);
 824	else if (err == -1)
 825	    error (0, 0, "reading from %s: %s", current_parsed_root->hostname, SOCK_STRERROR (SOCK_ERRNO));
 826
 827	/* shutdown() socket */
 828# ifdef SHUTDOWN_SERVER
 829	if (current_parsed_root->method != server_method)
 830# endif
 831	if (shutdown (n->socket, 0) < 0)
 832	{
 833	    error (1, 0, "shutting down server socket: %s", SOCK_STRERROR (SOCK_ERRNO));
 834	}
 835
 836	buf->input = NULL;
 837    }
 838    else if (buf->output)
 839    {
 840	/* shutdown() socket */
 841# ifdef SHUTDOWN_SERVER
 842	/* FIXME:  Should have a SHUTDOWN_SERVER_INPUT &
 843	 * SHUTDOWN_SERVER_OUTPUT
 844	 */
 845	if (current_parsed_root->method == server_method)
 846	    SHUTDOWN_SERVER (n->socket);
 847	else
 848# endif
 849	if (shutdown (n->socket, 1) < 0)
 850	{
 851	    error (1, 0, "shutting down server socket: %s", SOCK_STRERROR (SOCK_ERRNO));
 852	}
 853
 854	buf->output = NULL;
 855    }
 856
 857    return 0;
 858}
 859
 860#endif /* NO_SOCKET_TO_FD */
 861
 862/*
 863 * Read a line from the server.  Result does not include the terminating \n.
 864 *
 865 * Space for the result is malloc'd and should be freed by the caller.
 866 *
 867 * Returns number of bytes read.
 868 */
 869static int
 870read_line (resultp)
 871    char **resultp;
 872{
 873    int status;
 874    char *result;
 875    int len;
 876
 877    status = buf_flush (to_server, 1);
 878    if (status != 0)
 879	error (1, status, "writing to server");
 880
 881    status = buf_read_line (from_server, &result, &len);
 882    if (status != 0)
 883    {
 884	if (status == -1)
 885	    error (1, 0, "end of file from server (consult above messages if any)");
 886	else if (status == -2)
 887	    error (1, 0, "out of memory");
 888	else
 889	    error (1, status, "reading from server");
 890    }
 891
 892    if (resultp != NULL)
 893	*resultp = result;
 894    else
 895	free (result);
 896
 897    return len;
 898}
 899
 900#endif /* CLIENT_SUPPORT */
 901
 902
 903#if defined(CLIENT_SUPPORT) || defined(SERVER_SUPPORT)
 904
 905/*
 906 * Level of compression to use when running gzip on a single file.
 907 */
 908int file_gzip_level;
 909
 910#endif /* CLIENT_SUPPORT or SERVER_SUPPORT */
 911
 912#ifdef CLIENT_SUPPORT
 913
 914/*
 915 * The Repository for the top level of this command (not necessarily
 916 * the CVSROOT, just the current directory at the time we do it).
 917 */
 918static char *toplevel_repos = NULL;
 919
 920/* Working directory when we first started.  Note: we could speed things
 921   up on some systems by using savecwd.h here instead of just always
 922   storing a name.  */
 923char *toplevel_wd;
 924
 925static void
 926handle_ok (args, len)
 927    char *args;
 928    int len;
 929{
 930    return;
 931}
 932
 933static void
 934handle_error (args, len)
 935    char *args;
 936    int len;
 937{
 938    int something_printed;
 939    
 940    /*
 941     * First there is a symbolic error code followed by a space, which
 942     * we ignore.
 943     */
 944    char *p = strchr (args, ' ');
 945    if (p == NULL)
 946    {
 947	error (0, 0, "invalid data from cvs server");
 948	return;
 949    }
 950    ++p;
 951
 952    /* Next we print the text of the message from the server.  We
 953       probably should be prefixing it with "server error" or some
 954       such, because if it is something like "Out of memory", the
 955       current behavior doesn't say which machine is out of
 956       memory.  */
 957
 958    len -= p - args;
 959    something_printed = 0;
 960    for (; len > 0; --len)
 961    {
 962	something_printed = 1;
 963	putc (*p++, stderr);
 964    }
 965    if (something_printed)
 966	putc ('\n', stderr);
 967}
 968
 969static void
 970handle_valid_requests (args, len)
 971    char *args;
 972    int len;
 973{
 974    char *p = args;
 975    char *q;
 976    struct request *rq;
 977    do
 978    {
 979	q = strchr (p, ' ');
 980	if (q != NULL)
 981	    *q++ = '\0';
 982	for (rq = requests; rq->name != NULL; ++rq)
 983	{
 984	    if (strcmp (rq->name, p) == 0)
 985		break;
 986	}
 987	if (rq->name == NULL)
 988	    /*
 989	     * It is a request we have never heard of (and thus never
 990	     * will want to use).  So don't worry about it.
 991	     */
 992	    ;
 993	else
 994	{
 995	    if (rq->flags & RQ_ENABLEME)
 996	    {
 997		/*
 998		 * Server wants to know if we have this, to enable the
 999		 * feature.
1000		 */
1001		send_to_server (rq->name, 0);
1002                send_to_server ("\012", 0);
1003	    }
1004	    else
1005		rq->flags |= RQ_SUPPORTED;
1006	}
1007	p = q;
1008    } while (q != NULL);
1009    for (rq = requests; rq->name != NULL; ++rq)
1010    {
1011	if ((rq->flags & RQ_SUPPORTED)
1012	    || (rq->flags & RQ_ENABLEME))
1013	    continue;
1014	if (rq->flags & RQ_ESSENTIAL)
1015	    error (1, 0, "request `%s' not supported by server", rq->name);
1016    }
1017}
1018
1019
1020
1021/*
1022 * This is a proc for walklist().  It inverts the error return premise of
1023 * walklist.
1024 *
1025 * RETURNS
1026 *   True       If this path is prefixed by one of the paths in walklist and
1027 *              does not step above the prefix path.
1028 *   False      Otherwise.
1029 */
1030static
1031int path_list_prefixed (p, closure)
1032    Node *p;
1033    void *closure;
1034{
1035    const char *questionable = closure;
1036    const char *prefix = p->key;
1037    if (strncmp (prefix, questionable, strlen (prefix))) return 0;
1038    questionable += strlen (prefix);
1039    while (ISDIRSEP (*questionable)) questionable++;
1040    if (*questionable == '\0') return 1;
1041    return pathname_levels (questionable);
1042}
1043
1044
1045
1046/*
1047 * Need to validate the client pathname.  Disallowed paths include:
1048 *
1049 *   1. Absolute paths.
1050 *   2. Pathnames that do not reference a specifically requested update
1051 *      directory.
1052 *
1053 * In case 2, we actually only check that the directory is under the uppermost
1054 * directories mentioned on the command line.
1055 *
1056 * RETURNS
1057 *   True       If the path is valid.
1058 *   False      Otherwise.
1059 */
1060static
1061int is_valid_client_path (pathname)
1062    const char *pathname;
1063{
1064    /* 1. Absolute paths. */
1065    if (isabsolute (pathname)) return 0;
1066    /* 2. No up-references in path.  */
1067    if (pathname_levels (pathname) == 0) return 1;
1068    /* 2. No Max-dotdot paths registered.  */
1069    if (uppaths == NULL) return 0;
1070
1071    return walklist (uppaths, path_list_prefixed, (void *)pathname);
1072}
1073
1074
1075
1076/*
1077 * Do all the processing for PATHNAME, where pathname consists of the
1078 * repository and the filename.  The parameters we pass to FUNC are:
1079 * DATA is just the DATA parameter which was passed to
1080 * call_in_directory; ENT_LIST is a pointer to an entries list (which
1081 * we manage the storage for); SHORT_PATHNAME is the pathname of the
1082 * file relative to the (overall) directory in which the command is
1083 * taking place; and FILENAME is the filename portion only of
1084 * SHORT_PATHNAME.  When we call FUNC, the curent directory points to
1085 * the directory portion of SHORT_PATHNAME.  */
1086
1087static void
1088call_in_directory (pathname, func, data)
1089    char *pathname;
1090    void (*func) PROTO((char *data, List *ent_list, char *short_pathname,
1091			  char *filename));
1092    char *data;
1093{
1094    /* This variable holds the result of Entries_Open. */
1095    List *last_entries = NULL;
1096    char *dir_name;
1097    char *filename;
1098    /* This is what we get when we hook up the directory (working directory
1099       name) from PATHNAME with the filename from REPOSNAME.  For example:
1100       pathname: ccvs/src/
1101       reposname: /u/src/master/ccvs/foo/ChangeLog
1102       short_pathname: ccvs/src/ChangeLog
1103       */
1104    char *short_pathname;
1105    char *p;
1106
1107    /*
1108     * Do the whole descent in parallel for the repositories, so we
1109     * know what to put in CVS/Repository files.  I'm not sure the
1110     * full hair is necessary since the server does a similar
1111     * computation; I suspect that we only end up creating one
1112     * directory at a time anyway.
1113     *
1114     * Also note that we must *only* worry about this stuff when we
1115     * are creating directories; `cvs co foo/bar; cd foo/bar; cvs co
1116     * CVSROOT; cvs update' is legitimate, but in this case
1117     * foo/bar/CVSROOT/CVS/Repository is not a subdirectory of
1118     * foo/bar/CVS/Repository.
1119     */
1120    char *reposname;
1121    char *short_repos;
1122    char *reposdirname;
1123    char *rdirp;
1124    int reposdirname_absolute;
1125    int newdir = 0;
1126
1127    assert (pathname);
1128
1129    reposname = NULL;
1130    read_line (&reposname);
1131    assert (reposname != NULL);
1132
1133    reposdirname_absolute = 0;
1134    if (strncmp (reposname, toplevel_repos, strlen (toplevel_repos)) != 0)
1135    {
1136	reposdirname_absolute = 1;
1137	short_repos = reposname;
1138    }
1139    else
1140    {
1141	short_repos = reposname + strlen (toplevel_repos) + 1;
1142	if (short_repos[-1] != '/')
1143	{
1144	    reposdirname_absolute = 1;
1145	    short_repos = reposname;
1146	}
1147    }
1148
1149   /* Now that we have SHORT_REPOS, we can calculate the path to the file we
1150    * are being requested to operate on.
1151    */
1152    filename = strrchr (short_repos, '/');
1153    if (filename == NULL)
1154	filename = short_repos;
1155    else
1156	++filename;
1157
1158    short_pathname = xmalloc (strlen (pathname) + strlen (filename) + 5);
1159    strcpy (short_pathname, pathname);
1160    strcat (short_pathname, filename);
1161
1162    /* Now that we know the path to the file we were requested to operate on,
1163     * we can verify that it is valid.
1164     *
1165     * For security reasons, if SHORT_PATHNAME is absolute or attempts to
1166     * ascend outside of the current sanbbox, we abort.  The server should not
1167     * send us anything but relative paths which remain inside the sandbox
1168     * here.  Anything less means a trojan CVS server could create and edit
1169     * arbitrary files on the client.
1170     */
1171    if (!is_valid_client_path (short_pathname))
1172    {
1173	error (0, 0,
1174               "Server attempted to update a file via an invalid pathname:");
1175        error (1, 0, "`%s'.", short_pathname);
1176    }
1177
1178    reposdirname = xstrdup (short_repos);
1179    p = strrchr (reposdirname, '/');
1180    if (p == NULL)
1181    {
1182	reposdirname = xrealloc (reposdirname, 2);
1183	reposdirname[0] = '.'; reposdirname[1] = '\0';
1184    }
1185    else
1186	*p = '\0';
1187
1188    dir_name = xstrdup (pathname);
1189    p = strrchr (dir_name, '/');
1190    if (p == NULL)
1191    {
1192	dir_name = xrealloc (dir_name, 2);
1193	dir_name[0] = '.'; dir_name[1] = '\0';
1194    }
1195    else
1196	*p = '\0';
1197    if (client_prune_dirs)
1198	add_prune_candidate (dir_name);
1199
1200    if (toplevel_wd == NULL)
1201    {
1202	toplevel_wd = xgetwd ();
1203	if (toplevel_wd == NULL)
1204	    error (1, errno, "could not get working directory");
1205    }
1206
1207    if (CVS_CHDIR (toplevel_wd) < 0)
1208	error (1, errno, "could not chdir to %s", toplevel_wd);
1209
1210    if (CVS_CHDIR (dir_name) < 0)
1211    {
1212	char *dir;
1213	char *dirp;
1214	
1215	if (! existence_error (errno))
1216	    error (1, errno, "could not chdir to %s", dir_name);
1217	
1218	/* Directory does not exist, we need to create it.  */
1219	newdir = 1;
1220
1221	/* Provided we are willing to assume that directories get
1222	   created one at a time, we could simplify this a lot.
1223	   Do note that one aspect still would need to walk the
1224	   dir_name path: the checking for "fncmp (dir, CVSADM)".  */
1225
1226	dir = xmalloc (strlen (dir_name) + 1);
1227	dirp = dir_name;
1228	rdirp = reposdirname;
1229
1230	/* This algorithm makes nested directories one at a time
1231	   and create CVS administration files in them.  For
1232	   example, we're checking out foo/bar/baz from the
1233	   repository:
1234
1235	   1) create foo, point CVS/Repository to <root>/foo
1236	   2)     .. foo/bar                   .. <root>/foo/bar
1237	   3)     .. foo/bar/baz               .. <root>/foo/bar/baz
1238	   
1239	   As you can see, we're just stepping along DIR_NAME (with
1240	   DIRP) and REPOSDIRNAME (with RDIRP) respectively.
1241
1242	   We need to be careful when we are checking out a
1243	   module, however, since DIR_NAME and REPOSDIRNAME are not
1244	   going to be the same.  Since modules will not have any
1245	   slashes in their names, we should watch the output of
1246	   STRCHR to decide whether or not we should use STRCHR on
1247	   the RDIRP.  That is, if we're down to a module name,
1248	   don't keep picking apart the repository directory name.  */
1249
1250	do
1251	{
1252	    dirp = strchr (dirp, '/');
1253	    if (dirp)
1254	    {
1255		strncpy (dir, dir_name, dirp - dir_name);
1256		dir[dirp - dir_name] = '\0';
1257		/* Skip the slash.  */
1258		++dirp;
1259		if (rdirp == NULL)
1260		    /* This just means that the repository string has
1261		       fewer components than the dir_name string.  But
1262		       that is OK (e.g. see modules3-8 in testsuite).  */
1263		    ;
1264		else
1265		    rdirp = strchr (rdirp, '/');
1266	    }
1267	    else
1268	    {
1269		/* If there are no more slashes in the dir name,
1270		   we're down to the most nested directory -OR- to
1271		   the name of a module.  In the first case, we
1272		   should be down to a DIRP that has no slashes,
1273		   so it won't help/hurt to do another STRCHR call
1274		   on DIRP.  It will definitely hurt, however, if
1275		   we're down to a module name, since a module
1276		   name can point to a nested directory (that is,
1277		   DIRP will still have slashes in it.  Therefore,
1278		   we should set it to NULL so the routine below
1279		   copies the contents of REMOTEDIRNAME onto the
1280		   root repository directory (does this if rdirp
1281		   is set to NULL, because we used to do an extra
1282		   STRCHR call here). */
1283
1284		rdirp = NULL;
1285		strcpy (dir, dir_name);
1286	    }
1287
1288	    if (fncmp (dir, CVSADM) == 0)
1289	    {
1290		error (0, 0, "cannot create a directory named %s", dir);
1291		error (0, 0, "because CVS uses \"%s\" for its own uses",
1292		       CVSADM);
1293		error (1, 0, "rename the directory and try again");
1294	    }
1295
1296	    if (mkdir_if_needed (dir))
1297	    {
1298		/* It already existed, fine.  Just keep going.  */
1299	    }
1300	    else if (strcmp (cvs_cmd_name, "export") == 0)
1301		/* Don't create CVSADM directories if this is export.  */
1302		;
1303	    else
1304	    {
1305		/*
1306		 * Put repository in CVS/Repository.  For historical
1307		 * (pre-CVS/Root) reasons, this is an absolute pathname,
1308		 * but what really matters is the part of it which is
1309		 * relative to cvsroot.
1310		 */
1311		char *repo;
1312		char *r, *b;
1313
1314		repo = xmalloc (strlen (reposdirname)
1315				+ strlen (toplevel_repos)
1316				+ 80);
1317		if (reposdirname_absolute)
1318		    r = repo;
1319		else
1320		{
1321		    strcpy (repo, toplevel_repos);
1322		    strcat (repo, "/");
1323		    r = repo + strlen (repo);
1324		}
1325
1326		if (rdirp)
1327		{
1328		    /* See comment near start of function; the only
1329		       way that the server can put the right thing
1330		       in each CVS/Repository file is to create the
1331		       directories one at a time.  I think that the
1332		       CVS server has been doing this all along.  */
1333		    error (0, 0, "\
1334warning: server is not creating directories one at a time");
1335		    strncpy (r, reposdirname, rdirp - reposdirname);
1336		    r[rdirp - reposdirname] = '\0';
1337		}
1338		else
1339		    strcpy (r, reposdirname);
1340
1341		Create_Admin (dir, dir, repo,
1342			      (char *)NULL, (char *)NULL, 0, 0, 1);
1343		free (repo);
1344
1345		b = strrchr (dir, '/');
1346		if (b == NULL)
1347		    Subdir_Register ((List *) NULL, (char *) NULL, dir);
1348		else
1349		{
1350		    *b = '\0';
1351		    Subdir_Register ((List *) NULL, dir, b + 1);
1352		    *b = '/';
1353		}
1354	    }
1355
1356	    if (rdirp != NULL)
1357	    {
1358		/* Skip the slash.  */
1359		++rdirp;
1360	    }
1361
1362	} while (dirp != NULL);
1363	free (dir);
1364	/* Now it better work.  */
1365	if ( CVS_CHDIR (dir_name) < 0)
1366	    error (1, errno, "could not chdir to %s", dir_name);
1367    }
1368    else if (strcmp (cvs_cmd_name, "export") == 0)
1369	/* Don't create CVSADM directories if this is export.  */
1370	;
1371    else if (!isdir (CVSADM))
1372    {
1373	/*
1374	 * Put repository in CVS/Repository.  For historical
1375	 * (pre-CVS/Root) reasons, this is an absolute pathname,
1376	 * but what really matters is the part of it which is
1377	 * relative to cvsroot.
1378	 */
1379	char *repo;
1380
1381	if (reposdirname_absolute)
1382	    repo = reposdirname;
1383	else
1384	{
1385	    repo = xmalloc (strlen (reposdirname)
1386			    + strlen (toplevel_repos)
1387			    + 10);
1388	    strcpy (repo, toplevel_repos);
1389	    strcat (repo, "/");
1390	    strcat (repo, reposdirname);
1391	}
1392
1393	Create_Admin (".", ".", repo, (char *)NULL, (char *)NULL, 0, 1, 1);
1394	if (repo != reposdirname)
1395	    free (repo);
1396    }
1397
1398    if (strcmp (cvs_cmd_name, "export") != 0)
1399    {
1400	last_entries = Entries_Open (0, dir_name);
1401
1402	/* If this is a newly created directory, we will record
1403	   all subdirectory information, so call Subdirs_Known in
1404	   case there are no subdirectories.  If this is not a
1405	   newly created directory, it may be an old working
1406	   directory from before we recorded subdirectory
1407	   information in the Entries file.  We force a search for
1408	   all subdirectories now, to make sure our subdirectory
1409	   information is up to date.  If the Entries file does
1410	   record subdirectory information, then this call only
1411	   does list manipulation.  */
1412	if (newdir)
1413	    Subdirs_Known (last_entries);
1414	else
1415	{
1416	    List *dirlist;
1417
1418	    dirlist = Find_Directories ((char *) NULL, W_LOCAL,
1419					last_entries);
1420	    dellist (&dirlist);
1421	}
1422    }
1423    free (reposdirname);
1424    (*func) (data, last_entries, short_pathname, filename);
1425    if (last_entries != NULL)
1426	Entries_Close (last_entries);
1427    free (dir_name);
1428    free (short_pathname);
1429    free (reposname);
1430}
1431
1432static void
1433copy_a_file (data, ent_list, short_pathname, filename)
1434    char *data;
1435    List *ent_list;
1436    char *short_pathname;
1437    char *filename;
1438{
1439    char *newname;
1440#ifdef USE_VMS_FILENAMES
1441    char *p;
1442#endif
1443
1444    read_line (&newname);
1445
1446#ifdef USE_VMS_FILENAMES
1447    /* Mogrify the filename so VMS is happy with it. */
1448    for(p = newname; *p; p++)
1449       if(*p == '.' || *p == '#') *p = '_';
1450#endif
1451    /* cvsclient.texi has said for a long time that newname must be in the
1452       same directory.  Wouldn't want a malicious or buggy server overwriting
1453       ~/.profile, /etc/passwd, or anything like that.  */
1454    if (last_component (newname) != newname)
1455	error (1, 0, "protocol error: Copy-file tried to specify directory");
1456
1457    if (unlink_file (newname) && !existence_error (errno))
1458	error (0, errno, "unable to remove %s", newname);
1459    copy_file (filename, newname);
1460    free (newname);
1461}
1462
1463static void
1464handle_copy_file (args, len)
1465    char *args;
1466    int len;
1467{
1468    call_in_directory (args, copy_a_file, (char *)NULL);
1469}
1470
1471
1472
1473/* Attempt to read a file size from a string.  Accepts base 8 (0N), base 16
1474 * (0xN), or base 10.  Exits on error.
1475 *
1476 * RETURNS
1477 *   The file size, in a size_t.
1478 *
1479 * FATAL ERRORS
1480 *   1.  As strtoul().
1481 *   2.  If the number read exceeds SIZE_MAX.
1482 */
1483static size_t
1484strto_file_size (const char *s)
1485{
1486    unsigned long tmp;
1487    char *endptr;
1488
1489    /* Read it.  */
1490    errno = 0;
1491    tmp = strtoul (s, &endptr, 0);
1492
1493    /* Check for errors.  */
1494    if (errno || endptr == s)
1495	error (1, errno, "Server sent invalid file size `%s'", s);
1496    if (*endptr != '\0')
1497	error (1, 0,
1498	       "Server sent trailing characters in file size `%s'",
1499	       endptr);
1500    if (tmp > SIZE_MAX)
1501	error (1, 0, "Server sent file size exceeding client max.");
1502
1503    /* Return it.  */
1504    return (size_t)tmp;
1505}
1506
1507
1508
1509static void read_counted_file PROTO ((char *, char *));
1510
1511/* Read from the server the count for the length of a file, then read
1512   the contents of that file and write them to FILENAME.  FULLNAME is
1513   the name of the file for use in error messages.  FIXME-someday:
1514   extend this to deal with compressed files and make update_entries
1515   use it.  On error, gives a fatal error.  */
1516static void
1517read_counted_file (filename, fullname)
1518    char *filename;
1519    char *fullname;
1520{
1521    char *size_string;
1522    size_t size;
1523    char *buf;
1524
1525    /* Pointers in buf to the place to put data which will be read,
1526       and the data which needs to be written, respectively.  */
1527    char *pread;
1528    char *pwrite;
1529    /* Number of bytes left to read and number of bytes in buf waiting to
1530       be written, respectively.  */
1531    size_t nread;
1532    size_t nwrite;
1533
1534    FILE *fp;
1535
1536    read_line (&size_string);
1537    if (size_string[0] == 'z')
1538	error (1, 0, "\
1539protocol error: compressed files not supported for that operation");
1540    size = strto_file_size (size_string);
1541    free (size_string);
1542
1543    /* A more sophisticated implementation would use only a limited amount
1544       of buffer space (8K perhaps), and read that much at a time.  We allocate
1545       a buffer for the whole file only to make it easy to keep track what
1546       needs to be read and written.  */
1547    buf = xmalloc (size);
1548
1549    /* FIXME-someday: caller should pass in a flag saying whether it
1550       is binary or not.  I haven't carefully looked into whether
1551       CVS/Template files should use local text file conventions or
1552       not.  */
1553    fp = CVS_FOPEN (filename, "wb");
1554    if (fp == NULL)
1555	error (1, errno, "cannot write %s", fullname);
1556    nread = size;
1557    nwrite = 0;
1558    pread = buf;
1559    pwrite = buf;
1560    while (nread > 0 || nwrite > 0)
1561    {
1562	size_t n;
1563
1564	if (nread > 0)
1565	{
1566	    n = try_read_from_server (pread, nread);
1567	    nread -= n;
1568	    pread += n;
1569	    nwrite += n;
1570	}
1571
1572	if (nwrite > 0)
1573	{
1574	    n = fwrite (pwrite, 1, nwrite, fp);
1575	    if (ferror (fp))
1576		error (1, errno, "cannot write %s", fullname);
1577	    nwrite -= n;
1578	    pwrite += n;
1579	}
1580    }
1581    free (buf);
1582    if (fclose (fp) < 0)
1583	error (1, errno, "cannot close %s", fullname);
1584}
1585
1586/* OK, we want to swallow the "U foo.c" response and then output it only
1587   if we can update the file.  In the future we probably want some more
1588   systematic approach to parsing tagged text, but for now we keep it
1589   ad hoc.  "Why," I hear you cry, "do we not just look at the
1590   Update-existing and Created responses?"  That is an excellent question,
1591   and the answer is roughly conservatism/laziness--I haven't read through
1592   update.c enough to figure out the exact correspondence or lack thereof
1593   between those responses and a "U foo.c" line (note that Merged, from
1594   join_file, can be either "C foo" or "U foo" depending on the context).  */
1595/* Nonzero if we have seen +updated and not -updated.  */
1596static int updated_seen;
1597/* Filename from an "fname" tagged response within +updated/-updated.  */
1598static char *updated_fname;
1599
1600/* This struct is used to hold data when reading the +importmergecmd
1601   and -importmergecmd tags.  We put the variables in a struct only
1602   for namespace issues.  FIXME: As noted above, we need to develop a
1603   more systematic approach.  */
1604static struct
1605{
1606    /* Nonzero if we have seen +importmergecmd and not -importmergecmd.  */
1607    int seen;
1608    /* Number of conflicts, from a "conflicts" tagged response.  */
1609    int conflicts;
1610    /* First merge tag, from a "mergetag1" tagged response.  */
1611    char *mergetag1;
1612    /* Second merge tag, from a "mergetag2" tagged response.  */
1613    char *mergetag2;
1614    /* Repository, from a "repository" tagged response.  */
1615    char *repository;
1616} importmergecmd;
1617
1618/* Nonzero if we should arrange to return with a failure exit status.  */
1619static int failure_exit;
1620
1621
1622/*
1623 * The time stamp of the last file we registered.
1624 */
1625static time_t last_register_time;
1626
1627/*
1628 * The Checksum response gives the checksum for the file transferred
1629 * over by the next Updated, Merged or Patch response.  We just store
1630 * it here, and then check it in update_entries.
1631 */
1632
1633static int stored_checksum_valid;
1634static unsigned char stored_checksum[16];
1635
1636static void
1637handle_checksum (args, len)
1638    char *args;
1639    int len;
1640{
1641    char *s;
1642    char buf[3];
1643    int i;
1644
1645    if (stored_checksum_valid)
1646        error (1, 0, "Checksum received before last one was used");
1647
1648    s = args;
1649    buf[2] = '\0';
1650    for (i = 0; i < 16; i++)
1651    {
1652        char *bufend;
1653
1654	buf[0] = *s++;
1655	buf[1] = *s++;
1656	stored_checksum[i] = (char) strtol (buf, &bufend, 16);
1657	if (bufend != buf + 2)
1658	    break;
1659    }
1660
1661    if (i < 16 || *s != '\0')
1662        error (1, 0, "Invalid Checksum response: `%s'", args);
1663
1664    stored_checksum_valid = 1;
1665}
1666
1667/* Mode that we got in a "Mode" response (malloc'd), or NULL if none.  */
1668static char *stored_mode;
1669
1670static void handle_mode PROTO ((char *, int));
1671
1672static void
1673handle_mode (args, len)
1674    char *args;
1675    int len;
1676{
1677    if (stored_mode != NULL)
1678	error (1, 0, "protocol error: duplicate Mode");
1679    stored_mode = xstrdup (args);
1680}
1681
1682/* Nonzero if time was specified in Mod-time.  */
1683static int stored_modtime_valid;
1684/* Time specified in Mod-time.  */
1685static time_t stored_modtime;
1686
1687static void handle_mod_time PROTO ((char *, int));
1688
1689static void
1690handle_mod_time (args, len)
1691    char *args;
1692    int len;
1693{
1694    if (stored_modtime_valid)
1695	error (0, 0, "protocol error: duplicate Mod-time");
1696    stored_modtime = get_date (args, NULL);
1697    if (stored_modtime == (time_t) -1)
1698	error (0, 0, "protocol error: cannot parse date %s", args);
1699    else
1700	stored_modtime_valid = 1;
1701}
1702
1703/*
1704 * If we receive a patch, but the patch program fails to apply it, we
1705 * want to request the original file.  We keep a list of files whose
1706 * patches have failed.
1707 */
1708
1709char **failed_patches;
1710int failed_patches_count;
1711
1712struct update_entries_data
1713{
1714    enum {
1715      /*
1716       * We are just getting an Entries line; the local file is
1717       * correct.
1718       */
1719      UPDATE_ENTRIES_CHECKIN,
1720      /* We are getting the file contents as well.  */
1721      UPDATE_ENTRIES_UPDATE,
1722      /*
1723       * We are getting a patch against the existing local file, not
1724       * an entire new file.
1725       */
1726      UPDATE_ENTRIES_PATCH,
1727      /*
1728       * We are getting an RCS change text (diff -n output) against
1729       * the existing local file, not an entire new file.
1730       */
1731      UPDATE_ENTRIES_RCS_DIFF
1732    } contents;
1733
1734    enum {
1735	/* We are replacing an existing file.  */
1736	UPDATE_ENTRIES_EXISTING,
1737	/* We are creating a new file.  */
1738	UPDATE_ENTRIES_NEW,
1739	/* We don't know whether it is existing or new.  */
1740	UPDATE_ENTRIES_EXISTING_OR_NEW
1741    } existp;
1742
1743    /*
1744     * String to put in the timestamp field or NULL to use the timestamp
1745     * of the file.
1746     */
1747    char *timestamp;
1748};
1749
1750/* Update the Entries line for this file.  */
1751static void
1752update_entries (data_arg, ent_list, short_pathname, filename)
1753    char *data_arg;
1754    List *ent_list;
1755    char *short_pathname;
1756    char *filename;
1757{
1758    char *entries_line;
1759    struct update_entries_data *data = (struct update_entries_data *)data_arg;
1760
1761    char *cp;
1762    char *user;
1763    char *vn;
1764    /* Timestamp field.  Always empty according to the protocol.  */
1765    char *ts;
1766    char *options = NULL;
1767    char *tag = NULL;
1768    char *date = NULL;
1769    char *tag_or_date;
1770    char *scratch_entries = NULL;
1771    int bin;
1772
1773#ifdef UTIME_EXPECTS_WRITABLE
1774    int change_it_back = 0;
1775#endif
1776
1777    read_line (&entries_line);
1778
1779    /*
1780     * Parse the entries line.
1781     */
1782    scratch_entries = xstrdup (entries_line);
1783
1784    if (scratch_entries[0] != '/')
1785        error (1, 0, "bad entries line `%s' from server", entries_line);
1786    user = scratch_entries + 1;
1787    if ((cp = strchr (user, '/')) == NULL)
1788        error (1, 0, "bad entries line `%s' from server", entries_line);
1789    *cp++ = '\0';
1790    vn = cp;
1791    if ((cp = strchr (vn, '/')) == NULL)
1792        error (1, 0, "bad entries line `%s' from server", entries_line);
1793    *cp++ = '\0';
1794    
1795    ts = cp;
1796    if ((cp = strchr (ts, '/')) == NULL)
1797        error (1, 0, "bad entries line `%s' from server", entries_line);
1798    *cp++ = '\0';
1799    options = cp;
1800    if ((cp = strchr (options, '/')) == NULL)
1801        error (1, 0, "bad entries line `%s' from server", entries_line);
1802    *cp++ = '\0';
1803    tag_or_date = cp;
1804    
1805    /* If a slash ends the tag_or_date, ignore everything after it.  */
1806    cp = strchr (tag_or_date, '/');
1807    if (cp != NULL)
1808        *cp = '\0';
1809    if (*tag_or_date == 'T')
1810        tag = tag_or_date + 1;
1811    else if (*tag_or_date == 'D')
1812        date = tag_or_date + 1;
1813
1814    /* Done parsing the entries line. */
1815
1816    if (data->contents == UPDATE_ENTRIES_UPDATE
1817	|| data->contents == UPDATE_ENTRIES_PATCH
1818	|| data->contents == UPDATE_ENTRIES_RCS_DIFF)
1819    {
1820	char *size_string;
1821	char *mode_string;
1822	size_t size;
1823	char *buf;
1824	char *temp_filename;
1825	int use_gzip;
1826	int patch_failed;
1827	char *s;
1828
1829	read_line (&mode_string);
1830	
1831	read_line (&size_string);
1832	if (size_string[0] == 'z')
1833	{
1834	    use_gzip = 1;
1835	    s = size_string + 1;
1836	}
1837	else
1838	{
1839	    use_gzip = 0;
1840	    s = size_string;
1841	}
1842	size = strto_file_size (s);
1843	free (size_string);
1844
1845	/* Note that checking this separately from writing the file is
1846	   a race condition: if the existence or lack thereof of the
1847	   file changes between now and the actual calls which
1848	   operate on it, we lose.  However (a) there are so many
1849	   cases, I'm reluctant to try to fix them all, (b) in some
1850	   cases the system might not even have a system call which
1851	   does the right thing, and (c) it isn't clear this needs to
1852	   work.  */
1853	if (data->existp == UPDATE_ENTRIES_EXISTING
1854	    && !isfile (filename))
1855	    /* Emit a warning and update the file anyway.  */
1856	    error (0, 0, "warning: %s unexpectedly disappeared",
1857		   short_pathname);
1858
1859	if (data->existp == UPDATE_ENTRIES_NEW
1860	    && isfile (filename))
1861	{
1862	    /* Emit a warning and refuse to update the file; we don't want
1863	       to clobber a user's file.  */
1864	    size_t nread;
1865	    size_t toread;
1866
1867	    /* size should be unsigned, but until we get around to fixing
1868	       that, work around it.  */
1869	    size_t usize;
1870
1871	    char buf[8192];
1872
1873	    /* This error might be confusing; it isn't really clear to
1874	       the user what to do about it.  Keep in mind that it has
1875	       several causes: (1) something/someone creates the file
1876	       during the time that CVS is running, (2) the repository
1877	       has two files whose names clash for the client because
1878	       of case-insensitivity or similar causes, See 3 for
1879	       additional notes.  (3) a special case of this is that a
1880	       file gets renamed for example from a.c to A.C.  A
1881	       "cvs update" on a case-insensitive client will get this
1882	       error.  In this case and in case 2, the filename
1883	       (short_pathname) printed in the error message will likely _not_
1884	       have the same case as seen by the user in a directory listing.
1885	       (4) the client has a file which the server doesn't know
1886	       about (e.g. "? foo" file), and that name clashes with a file
1887	       the server does know about, (5) classify.c will print the same
1888	       message for other reasons.
1889
1890	       I hope the above paragraph makes it clear that making this
1891	       clearer is not a one-line fix.  */
1892	    error (0, 0, "move away %s; it is in the way", short_pathname);
1893	    if (updated_fname != NULL)
1894	    {
1895		cvs_output ("C ", 0);
1896		cvs_output (updated_fname, 0);
1897		cvs_output ("\n", 1);
1898	    }
1899	    failure_exit = 1;
1900
1901	discard_file_and_return:
1902	    /* Now read and discard the file contents.  */
1903	    usize = size;
1904	    nread = 0;
1905	    while (nread < usize)
1906	    {
1907		toread = usize - nread;
1908		if (toread > sizeof buf)
1909		    toread = sizeof buf;
1910
1911		nread += try_read_from_server (buf, toread);
1912		if (nread == usize)
1913		    break;
1914	    }
1915
1916	    free (mode_string);
1917	    free (scratch_entries);
1918	    free (entries_line);
1919
1920	    /* The Mode, Mod-time, and Checksum responses should not carry
1921	       over to a subsequent Created (or whatever) response, even
1922	       in the error case.  */
1923	    if (stored_mode != NULL)
1924	    {
1925		free (stored_mode);
1926		stored_mode = NULL;
1927	    }
1928	    stored_modtime_valid = 0;
1929	    stored_checksum_valid = 0;
1930
1931	    if (updated_fname != NULL)
1932	    {
1933		free (updated_fname);
1934		updated_fname = NULL;
1935	    }
1936	    return;
1937	}
1938
1939	temp_filename = xmalloc (strlen (filename) + 80);
1940#ifdef USE_VMS_FILENAMES
1941        /* A VMS rename of "blah.dat" to "foo" to implies a
1942           destination of "foo.dat" which is unfortinate for CVS */
1943	sprintf (temp_filename, "%s_new_", filename);
1944#else
1945#ifdef _POSIX_NO_TRUNC
1946	sprintf (temp_filename, ".new.%.9s", filename);
1947#else /* _POSIX_NO_TRUNC */
1948	sprintf (temp_filename, ".new.%s", filename);
1949#endif /* _POSIX_NO_TRUNC */
1950#endif /* USE_VMS_FILENAMES */
1951
1952	buf = xmalloc (size);
1953
1954        /* Some systems, like OS/2 and Windows NT, end lines with CRLF
1955           instead of just LF.  Format translation is done in the C
1956           library I/O funtions.  Here we tell them whether or not to
1957           convert -- if this file is marked "binary" with the RCS -kb
1958           flag, then we don't want to convert, else we do (because
1959           CVS assumes text files by default). */
1960
1961	if (options)
1962	    bin = !(strcmp (options, "-kb"));
1963	else
1964	    bin = 0;
1965
1966	if (data->contents == UPDATE_ENTRIES_RCS_DIFF)
1967	{
1968	    /* This is an RCS change text.  We just hold the change
1969	       text in memory.  */
1970
1971	    if (use_gzip)
1972		error (1, 0,
1973		       "server error: gzip invalid with RCS change text");
1974
1975	    read_from_server (buf, size);
1976	}
1977	else
1978	{
1979	    int fd;
1980
1981	    fd = CVS_OPEN (temp_filename,
1982			   (O_WRONLY | O_CREAT | O_TRUNC
1983			    | (bin ? OPEN_BINARY : 0)),
1984			   0777);
1985
1986	    if (fd < 0)
1987	    {
1988		/* I can see a case for making this a fatal error; for
1989		   a condition like disk full or network unreachable
1990		   (for a file server), carrying on and giving an
1991		   error on each file seems unnecessary.  But if it is
1992		   a permission problem, or some such, then it is
1993		   entirely possible that future files will not have
1994		   the same problem.  */
1995		error (0, errno, "cannot write %s", short_pathname);
1996		free (temp_filename);
1997		free (buf);
1998		goto discard_file_and_return;
1999	    }
2000
2001	    if (size > 0)
2002	    {
2003		read_from_server (buf, size);
2004
2005		if (use_gzip)
2006		{
2007		    if (gunzip_and_write (fd, short_pathname, 
2008					  (unsigned char *) buf, size))
2009			error (1, 0, "aborting due to compression error");
2010		}
2011		else if (write (fd, buf, size) != size)
2012		    error (1, errno, "writing %s", short_pathname);
2013	    }
2014
2015	    if (close (fd) < 0)
2016		error (1, errno, "writing %s", short_pathname);
2017	}
2018
2019	/* This is after we have read the file from the net (a change
2020	   from previous versions, where the server would send us
2021	   "M U foo.c" before Update-existing or whatever), but before
2022	   we finish writing the file (arguably a bug).  The timing
2023	   affects a user who wants status info about how far we have
2024	   gotten, and also affects whether "U foo.c" appears in addition
2025	   to various error messages.  */
2026	if (updated_fname != NULL)
2027	{
2028	    cvs_output ("U ", 0);
2029	    cvs_output (updated_fname, 0);
2030	    cvs_output ("\n", 1);
2031	    free (updated_fname);
2032	    updated_fname = 0;
2033	}
2034
2035	patch_failed = 0;
2036
2037	if (data->contents == UPDATE_ENTRIES_UPDATE)
2038	{
2039	    rename_file (temp_filename, filename);
2040	}
2041	else if (data->contents == UPDATE_ENTRIES_PATCH)
2042	{
2043	    /* You might think we could just leave Patched out of
2044	       Valid-responses and not get this response.  However, if
2045	       memory serves, the CVS 1.9 server bases this on -u
2046	       (update-patches), and there is no way for us to send -u
2047	       or not based on whether the server supports "Rcs-diff".  
2048
2049	       Fall back to transmitting entire files.  */
2050	    patch_failed = 1;
2051	}
2052	else
2053	{
2054	    char *filebuf;
2055	    size_t filebufsize;
2056	    size_t nread;
2057	    char *patchedbuf;
2058	    size_t patchedlen;
2059
2060	    /* Handle UPDATE_ENTRIES_RCS_DIFF.  */
2061
2062	    if (!isfile (filename))
2063	        error (1, 0, "patch original file %s does not exist",
2064		       short_pathname);
2065	    filebuf = NULL;
2066	    filebufsize = 0;
2067	    nread = 0;
2068
2069	    get_file (filename, short_pathname, bin ? FOPEN_BINARY_READ : "r",
2070		      &filebuf, &filebufsize, &nread);
2071	    /* At this point the contents of the existing file are in
2072               FILEBUF, and the length of the contents is in NREAD.
2073               The contents of the patch from the network are in BUF,
2074               and the length of the patch is in SIZE.  */
2075
2076	    if (! rcs_change_text (short_pathname, filebuf, nread, buf, size,
2077				   &patchedbuf, &patchedlen))
2078		patch_failed = 1;
2079	    else
2080	    {
2081		if (stored_checksum_valid)
2082		{
2083		    struct cvs_MD5Context context;
2084		    unsigned char checksum[16];
2085
2086		    /* We have a checksum.  Check it before writing
2087		       the file out, so that we don't have to read it
2088		       back in again.  */
2089		    cvs_MD5Init (&context);
2090		    cvs_MD5Update (&context,
2091				   (unsigned char *) patchedbuf, patchedlen);
2092		    cvs_MD5Final (checksum, &context);
2093		    if (memcmp (checksum, stored_checksum, 16) != 0)
2094		    {
2095			error (0, 0,
2096			       "checksum failure after patch to %s; will refetch",
2097			       short_pathname);
2098
2099			patch_failed = 1;
2100		    }
2101
2102		    stored_checksum_valid = 0;
2103		}
2104
2105		if (! patch_failed)
2106		{
2107		    FILE *e;
2108
2109		    e = open_file (temp_filename,
2110				   bin ? FOPEN_BINARY_WRITE : "w");
2111		    if (fwrite (patchedbuf, 1, patchedlen, e) != patchedlen)
2112			error (1, errno, "cannot write %s", temp_filename);
2113		    if (fclose (e) == EOF)
2114			error (1, errno, "cannot close %s", temp_filename);
2115		    rename_file (temp_filename, filename);
2116		}
2117
2118		free (patchedbuf);
2119	    }
2120
2121	    free (filebuf);
2122	}
2123
2124	free (temp_filename);
2125
2126	if (stored_checksum_valid && ! patch_failed)
2127	{
2128	    FILE *e;
2129	    struct cvs_MD5Context context;
2130	    unsigned char buf[8192];
2131	    unsigned len;
2132	    unsigned char checksum[16];
2133
2134	    /*
2135	     * Compute the MD5 checksum.  This will normally only be
2136	     * used when receiving a patch, so we always compute it
2137	     * here on the final file, rather than on the received
2138	     * data.
2139	     *
2140	     * Note that if the file is a text file, we should read it
2141	     * here using text mode, so its lines will be terminated the same
2142	     * way they were transmitted.
2143	     */
2144	    e = CVS_FOPEN (filename, "r");
2145	    if (e == NULL)
2146	        error (1, errno, "could not open %s", short_pathname);
2147
2148	    cvs_MD5Init (&context);
2149	    while ((len = fread (buf, 1, sizeof buf, e)) != 0)
2150		cvs_MD5Update (&context, buf, len);
2151	    if (ferror (e))
2152		error (1, errno, "could not read %s", short_pathname);
2153	    cvs_MD5Final (checksum, &context);
2154
2155	    fclose (e);
2156
2157	    stored_checksum_valid = 0;
2158
2159	    if (memcmp (checksum, stored_checksum, 16) != 0)
2160	    {
2161	        if (data->contents != UPDATE_ENTRIES_PATCH)
2162		    error (1, 0, "checksum failure on %s",
2163			   short_pathname);
2164
2165		error (0, 0,
2166		       "checksum failure after patch to %s; will refetch",
2167		       short_pathname);
2168
2169		patch_failed = 1;
2170	    }
2171	}
2172
2173	if (patch_failed)
2174	{
2175	    /* Save this file to retrieve later.  */
2176	    failed_patches = (char **) xrealloc ((char *) failed_patches,
2177						 ((failed_patches_count + 1)
2178						  * sizeof (char *)));
2179	    failed_patches[failed_patches_count] = xstrdup (short_pathname);
2180	    ++failed_patches_count;
2181
2182	    stored_checksum_valid = 0;
2183
2184	    free (mode_string);
2185	    free (buf);
2186	    free (scratch_entries);
2187	    free (entries_line);
2188
2189	    return;
2190	}
2191
2192        {
2193	    int status = change_mode (filename, mode_string, 1);
2194	    if (status != 0)
2195		error (0, status, "cannot change mode of %s", short_pathname);
2196	}
2197
2198	free (mode_string);
2199	free (buf);
2200    }
2201
2202    if (stored_mode != NULL)
2203    {
2204	change_mode (filename, stored_mode, 1);
2205	free (stored_mode);
2206	stored_mode = NULL;
2207    }
2208   
2209    if (stored_modtime_valid)
2210    {
2211	struct utimbuf t;
2212
2213	memset (&t, 0, sizeof (t));
2214	t.modtime = stored_modtime;
2215	(void) time (&t.actime);
2216
2217#ifdef UTIME_EXPECTS_WRITABLE
2218	if (!iswritable (filename))
2219	{
2220	    xchmod (filename, 1);
2221	    change_it_back = 1;
2222	}
2223#endif  /* UTIME_EXPECTS_WRITABLE  */
2224
2225	if (utime (filename, &t) < 0)
2226	    error (0, errno, "cannot set time on %s", filename);
2227
2228#ifdef UTIME_EXPECTS_WRITABLE
2229	if (change_it_back)
2230	{
2231	    xchmod (filename, 0);
2232	    change_it_back = 0;
2233	}
2234#endif  /*  UTIME_EXPECTS_WRITABLE  */
2235
2236	stored_modtime_valid = 0;
2237    }
2238
2239    /*
2240     * Process the entries line.  Do this after we've written the file,
2241     * since we need the timestamp.
2242     */
2243    if (strcmp (cvs_cmd_name, "export") != 0)
2244    {
2245	char *local_timestamp;
2246	char *file_timestamp;
2247
2248	(void) time (&last_register_time);
2249
2250	local_timestamp = data->timestamp;
2251	if (local_timestamp == NULL || ts[0] == '+')
2252	    file_timestamp = time_stamp (filename);
2253	else
2254	    file_timestamp = NULL;
2255
2256	/*
2257	 * These special version numbers signify that it is not up to
2258	 * date.  Create a dummy timestamp which will never compare
2259	 * equal to the timestamp of the file.
2260	 */
2261	if (vn[0] == '\0' || strcmp (vn, "0") == 0 || vn[0] == '-')
2262	    local_timestamp = "dummy timestamp";
2263	else if (local_timestamp == NULL)
2264	{
2265	    local_timestamp = file_timestamp;
2266
2267	    /* Checking for cvs_cmd_name of "commit" doesn't seem like
2268	       the cleanest way to handle this, but it seem to roughly
2269	       parallel what the :local: code which calls
2270	       mark_up_to_date ends up amounting to.  Some day, should
2271	       think more about what the Checked-in response means
2272	       vis-a-vis both Entries and Base and clarify
2273	       cvsclient.texi accordingly.  */
2274
2275	    if (!strcmp (cvs_cmd_name, "commit"))
2276		mark_up_to_date (filename);
2277	}
2278
2279	Register (ent_list, filename, vn, local_timestamp,
2280		  options, tag, date, ts[0] == '+' ? file_timestamp : NULL);
2281
2282	if (file_timestamp)
2283	    free (file_timestamp);
2284
2285    }
2286    free (scratch_entries);
2287    free (entries_line);
2288}
2289
2290static void
2291handle_checked_in (args, len)
2292    char *args;
2293    int len;
2294{
2295    struct update_entries_data dat;
2296    dat.contents = UPDATE_ENTRIES_CHECKIN;
2297    dat.existp = UPDATE_ENTRIES_EXISTING_OR_NEW;
2298    dat.timestamp = NULL;
2299    call_in_directory (args, update_entries, (char *)&dat);
2300}
2301
2302static void
2303handle_new_entry (args, len)
2304    char *args;
2305    int len;
2306{
2307    struct update_entries_data dat;
2308    dat.contents = UPDATE_ENTRIES_CHECKIN;
2309    dat.existp = UPDATE_ENTRIES_EXISTING_OR_NEW;
2310    dat.timestamp = "dummy timestamp from new-entry";
2311    call_in_directory (args, update_entries, (char *)&dat);
2312}
2313
2314static void
2315handle_updated (args, len)
2316    char *args;
2317    int len;
2318{
2319    struct update_entries_data dat;
2320    dat.contents = UPDATE_ENTRIES_UPDATE;
2321    dat.existp = UPDATE_ENTRIES_EXISTING_OR_NEW;
2322    dat.timestamp = NULL;
2323    call_in_directory (args, update_entries, (char *)&dat);
2324}
2325
2326static void handle_created PROTO((char *, int));
2327
2328static void
2329handle_created (args, len)
2330    char *args;
2331    int len;
2332{
2333    struct update_entries_data dat;
2334    dat.contents = UPDATE_ENTRIES_UPDATE;
2335    dat.existp = UPDATE_ENTRIES_NEW;
2336    dat.timestamp = NULL;
2337    call_in_directory (args, update_entries, (char *)&dat);
2338}
2339
2340static void handle_update_existing PROTO((char *, int));
2341
2342static void
2343handle_update_existing (args, len)
2344    char *args;
2345    int len;
2346{
2347    struct update_entries_data dat;
2348    dat.contents = UPDATE_ENTRIES_UPDATE;
2349    dat.existp = UPDATE_ENTRIES_EXISTING;
2350    dat.timestamp = NULL;
2351    call_in_directory (args, update_entries, (char *)&dat);
2352}
2353
2354static void
2355handle_merged (args, len)
2356    char *args;
2357    int len;
2358{
2359    struct update_entries_data dat;
2360    dat.contents = UPDATE_ENTRIES_UPDATE;
2361    /* Think this could be UPDATE_ENTRIES_EXISTING, but just in case...  */
2362    dat.existp = UPDATE_ENTRIES_EXISTING_OR_NEW;
2363    dat.timestamp = "Result of merge";
2364    call_in_directory (args, update_entries, (char *)&dat);
2365}
2366
2367static void
2368handle_patched (args, len)
2369     char *args;
2370     int len;
2371{
2372    struct update_entries_data dat;
2373    dat.contents = UPDATE_ENTRIES_PATCH;
2374    /* Think this could be UPDATE_ENTRIES_EXISTING, but just in case...  */
2375    dat.existp = UPDATE_ENTRIES_EXISTING_OR_NEW;
2376    dat.timestamp = NULL;
2377    call_in_directory (args, update_entries, (char *)&dat);
2378}
2379
2380static void
2381handle_rcs_diff (args, len)
2382     char *args;
2383     int len;
2384{
2385    struct update_entries_data dat;
2386    dat.contents = UPDATE_ENTRIES_RCS_DIFF;
2387    /* Think this could be UPDATE_ENTRIES_EXISTING, but just in case...  */
2388    dat.existp = UPDATE_ENTRIES_EXISTING_OR_NEW;
2389    dat.timestamp = NULL;
2390    call_in_directory (args, update_entries, (char *)&dat);
2391}
2392
2393static void
2394remove_entry (data, ent_list, short_pathname, filename)
2395    char *data;
2396    List *ent_list;
2397    char *short_pathname;
2398    char *filename;
2399{
2400    Scratch_Entry (ent_list, filename);
2401}
2402
2403static void
2404handle_remove_entry (args, len)
2405    char *args;
2406    int len;
2407{
2408    call_in_directory (args, remove_entry, (char *)NULL);
2409}
2410
2411static void
2412remove_entry_and_file (data, ent_list, short_pathname, filename)
2413    char *data;
2414    List *ent_list;
2415    char *short_pathname;
2416    char *filename;
2417{
2418    Scratch_Entry (ent_list, filename);
2419    /* Note that we don't ignore existence_error's here.  The server
2420       should be sending Remove-entry rather than Removed in cases
2421       where the file does not exist.  And if the user removes the
2422       file halfway through a cvs command, we should be printing an
2423       error.  */
2424    if (unlink_file (filename) < 0)
2425	error (0, errno, "unable to remove %s", short_pathname);
2426}
2427
2428static void
2429handle_removed (args, len)
2430    char *args;
2431    int len;
2432{
2433    call_in_directory (args, remove_entry_and_file, (char *)NULL);
2434}
2435
2436/* Is this the top level (directory containing CVSROOT)?  */
2437static int
2438is_cvsroot_level (pathname)
2439    char *pathname;
2440{
2441    if (strcmp (toplevel_repos, current_parsed_root->directory) != 0)
2442	return 0;
2443
2444    return strchr (pathname, '/') == NULL;
2445}
2446
2447static void
2448set_static (data, ent_list, short_pathname, filename)
2449    char *data;
2450    List *ent_list;
2451    char *short_pathname;
2452    char *filename;
2453{
2454    FILE *fp;
2455    fp = open_file (CVSADM_ENTSTAT, "w+");
2456    if (fclose (fp) == EOF)
2457        error (1, errno, "cannot close %s", CVSADM_ENTSTAT);
2458}
2459
2460static void
2461handle_set_static_directory (args, len)
2462    char *args;
2463    int len;
2464{
2465    if (strcmp (cvs_cmd_name, "export") == 0)
2466    {
2467	/* Swallow the repository.  */
2468	read_line (NULL);
2469	return;
2470    }
2471    call_in_directory (args, set_static, (char *)NULL);
2472}
2473
2474static void
2475clear_static (data, ent_list, short_pathname, filename)
2476    char *data;
2477    List *ent_list;
2478    char *short_pathname;
2479    char *filename;
2480{
2481    if (unlink_file (CVSADM_ENTSTAT) < 0 && ! existence_error (errno))
2482        error (1, errno, "cannot remove file %s", CVSADM_ENTSTAT);
2483}
2484
2485static void
2486handle_clear_static_directory (pathname, len)
2487    char *pathname;
2488    int len;
2489{
2490    if (strcmp (cvs_cmd_name, "export") == 0)
2491    {
2492	/* Swallow the repository.  */
2493	read_line (NULL);
2494	return;
2495    }
2496
2497    if (is_cvsroot_level (pathname))
2498    {
2499        /*
2500	 * Top level (directory containing CVSROOT).  This seems to normally
2501	 * lack a CVS directory, so don't try to create files in it.
2502	 */
2503	return;
2504    }
2505    call_in_directory (pathname, clear_static, (char *)NULL);
2506}
2507
2508static void
2509set_sticky (data, ent_list, short_pathname, filename)
2510    char *data;
2511    List *ent_list;
2512    char *short_pathname;
2513    char *filename;
2514{
2515    char *tagspec;
2516    FILE *f;
2517
2518    read_line (&tagspec);
2519
2520    /* FIXME-update-dir: error messages should include the directory.  */
2521    f = CVS_FOPEN (CVSADM_TAG, "w+");
2522    if (f == NULL)
2523    {
2524	/* Making this non-fatal is a bit of a kludge (see dirs2
2525	   in testsuite).  A better solution would be to avoid having
2526	   the server tell us about a directory we shouldn't be doing
2527	   anything with anyway (e.g. by handling directory
2528	   addition/removal better).  */
2529	error (0, errno, "cannot open %s", CVSADM_TAG);
2530	free (tagspec);
2531	return;
2532    }
2533    if (fprintf (f, "%s\n", tagspec) < 0)
2534	error (1, errno, "writing %s", CVSADM_TAG);
2535    if (fclose (f) == EOF)
2536	error (1, errno, "closing %s", CVSADM_TAG);
2537    free (tagspec);
2538}
2539
2540static void
2541handle_set_sticky (pathname, len)
2542    char *pathname;
2543    int len;
2544{
2545    if (strcmp (cvs_cmd_name, "export") == 0)
2546    {
2547	/* Swallow the repository.  */
2548	read_line (NULL);
2549        /* Swallow the tag line.  */
2550	read_line (NULL);
2551	return;
2552    }
2553    if (is_cvsroot_level (pathname))
2554    {
2555        /*
2556	 * Top level (directory containing CVSROOT).  This seems to normally
2557	 * lack a CVS directory, so don't try to create files in it.
2558	 */
2559
2560	/* Swallow the repository.  */
2561	read_line (NULL);
2562        /* Swallow the tag line.  */
2563	read_line (NULL);
2564	return;
2565    }
2566
2567    call_in_directory (pathname, set_sticky, (char *)NULL);
2568}
2569
2570static void
2571clear_sticky (data, ent_list, short_pathname, filename)
2572    char *data;
2573    List *ent_list;
2574    char *short_pathname;
2575    char *filename;
2576{
2577    if (unlink_file (CVSADM_TAG) < 0 && ! existence_error (errno))
2578	error (1, errno, "cannot remove %s", CVSADM_TAG);
2579}
2580
2581static void
2582handle_clear_sticky (pathname, len)
2583    char *pathname;
2584    int len;
2585{
2586    if (strcmp (cvs_cmd_name, "export") == 0)
2587    {
2588	/* Swallow the repository.  */
2589	read_line (NULL);
2590	return;
2591    }
2592
2593    if (is_cvsroot_level (pathname))
2594    {
2595        /*
2596	 * Top level (directory containing CVSROOT).  This seems to normally
2597	 * lack a CVS directory, so don't try to create files in it.
2598	 */
2599	return;
2600    }
2601
2602    call_in_directory (pathname, clear_sticky, (char *)NULL);
2603}
2604
2605
2606static void template PROTO ((char *, List *, char *, char *));
2607
2608static void
2609template (data, ent_list, short_pathname, filename)
2610    char *data;
2611    List *ent_list;
2612    char *short_pathname;
2613    char *filename;
2614{
2615    char *buf = xmalloc ( strlen ( short_pathname )
2616	    		  + strlen ( CVSADM_TEMPLATE )
2617			  + 2 );
2618    sprintf ( buf, "%s/%s", short_pathname, CVSADM_TEMPLATE );
2619    read_counted_file ( CVSADM_TEMPLATE, buf );
2620    free ( buf );
2621}
2622
2623static void handle_template PROTO ((char *, int));
2624
2625static void
2626handle_template (pathname, len)
2627    char *pathname;
2628    int len;
2629{
2630    call_in_directory (pathname, template, NULL);
2631}
2632
2633
2634
2635struct save_dir {
2636    char *dir;
2637    struct save_dir *next;
2638};
2639
2640struct save_dir *prune_candidates;
2641
2642static void
2643add_prune_candidate (dir)
2644    const char *dir;
2645{
2646    struct save_dir *p;
2647
2648    if ((dir[0] == '.' && dir[1] == '\0')
2649	|| (prune_candidates != NULL
2650	    && strcmp (dir, prune_candidates->dir) == 0))
2651	return;
2652    p = (struct save_dir *) xmalloc (sizeof (struct save_dir));
2653    p->dir = xstrdup (dir);
2654    p->next = prune_candidates;
2655    prune_candidates = p;
2656}
2657
2658static void process_prune_candidates PROTO((void));
2659
2660static void
2661process_prune_candidates ()
2662{
2663    struct save_dir *p;
2664    struct save_dir *q;
2665
2666    if (toplevel_wd != NULL)
2667    {
2668	if (CVS_CHDIR (toplevel_wd) < 0)
2669	    error (1, errno, "could not chdir to %s", toplevel_wd);
2670    }
2671    for (p = prune_candidates; p != NULL; )
2672    {
2673	if (isemptydir (p->dir, 1))
2674	{
2675	    char *b;
2676
2677	    if (unlink_file_dir (p->dir) < 0)
2678		error (0, errno, "cannot remove %s", p->dir);
2679	    b = strrchr (p->dir, '/');
2680	    if (b == NULL)
2681		Subdir_Deregister ((List *) NULL, (char *) NULL, p->dir);
2682	    else
2683	    {
2684		*b = '\0';
2685		Subdir_Deregister ((List *) NULL, p->dir, b + 1);
2686	    }
2687	}
2688	free (p->dir);
2689	q = p->next;
2690	free (p);
2691	p = q;
2692    }
2693    prune_candidates = NULL;
2694}
2695
2696/* Send a Repository line.  */
2697
2698static char *last_repos;
2699static char *last_update_dir;
2700
2701static void send_repository PROTO((const char *, const char *, const char *));
2702
2703static void
2704send_repository (dir, repos, update_dir)
2705    const char *dir;
2706    const char *repos;
2707    const char *update_dir;
2708{
2709    char *adm_name;
2710
2711    /* FIXME: this is probably not the best place to check; I wish I
2712     * knew where in here's callers to really trap this bug.  To
2713     * reproduce the bug, just do this:
2714     * 
2715     *       mkdir junk
2716     *       cd junk
2717     *       cvs -d some_repos update foo
2718     *
2719     * Poof, CVS seg faults and dies!  It's because it's trying to
2720     * send a NULL string to the server but dies in send_to_server.
2721     * That string was supposed to be the repository, but it doesn't
2722     * get set because there's no CVSADM dir, and somehow it's not
2723     * getting set from the -d argument either... ?
2724     */
2725    if (repos == NULL)
2726    {
2727        /* Lame error.  I want a real fix but can't stay up to track
2728           this down right now. */
2729        error (1, 0, "no repository");
2730    }
2731
2732    if (update_dir == NULL || update_dir[0] == '\0')
2733	update_dir = ".";
2734
2735    if (last_repos != NULL
2736	&& strcmp (repos, last_repos) == 0
2737	&& last_update_dir != NULL
2738	&& strcmp (update_dir, last_update_dir) == 0)
2739	/* We've already sent it.  */
2740	return;
2741
2742    if (client_prune_dirs)
2743	add_prune_candidate (update_dir);
2744
2745    /* Add a directory name to the list of those sent to the
2746       server. */
2747    if (update_dir && (*update_dir != '\0')
2748	&& (strcmp (update_dir, ".") != 0)
2749	&& (findnode (dirs_sent_to_server, update_dir) == NULL))
2750    {
2751	Node *n;
2752	n = getnode ();
2753	n->type = NT_UNKNOWN;
2754	n->key = xstrdup (update_dir);
2755	n->data = NULL;
2756
2757	if (addnode (dirs_sent_to_server, n))
2758	    error (1, 0, "cannot add directory %s to list", n->key);
2759    }
2760
2761    /* 80 is large enough for any of CVSADM_*.  */
2762    adm_name = xmalloc (strlen (dir) + 80);
2763
2764    send_to_server ("Directory ", 0);
2765    {
2766	/* Send the directory name.  I know that this
2767	   sort of duplicates code elsewhere, but each
2768	   case seems slightly different...  */
2769	char buf[1];
2770	const char *p = update_dir;
2771	while (*p != '\0')
2772	{
2773	    assert (*p != '\012');
2774	    if (ISDIRSEP (*p))
2775	    {
2776		buf[0] = '/';
2777		send_to_server (buf, 1);
2778	    }
2779	    else
2780	    {
2781		buf[0] = *p;
2782		send_to_server (buf, 1);
2783	    }
2784	    ++p;
2785	}
2786    }
2787    send_to_server ("\012", 1);
2788    send_to_server (repos, 0);
2789    send_to_server ("\012", 1);
2790
2791    if (strcmp (cvs_cmd_name, "import")
2792	&& supported_request ("Static-directory"))
2793    {
2794	adm_name[0] = '\0';
2795	if (dir[0] != '\0')
2796	{
2797	    strcat (adm_name, dir);
2798	    strcat (adm_name, "/");
2799	}
2800	strcat (adm_name, CVSADM_ENTSTAT);
2801	if (isreadable (adm_name))
2802	{
2803	    send_to_server ("Static-directory\012", 0);
2804	}
2805    }
2806    if (strcmp (cvs_cmd_name, "import")
2807	&& supported_request ("Sticky"))
2808    {
2809	FILE *f;
2810	if (dir[0] == '\0')
2811	    strcpy (adm_name, CVSADM_TAG);
2812	else
2813	    sprintf (adm_name, "%s/%s", dir, CVSADM_TAG);
2814
2815	f = CVS_FOPEN (adm_name, "r");
2816	if (f == NULL)
2817	{
2818	    if (! existence_error (errno))
2819		error (1, errno, "reading %s", adm_name);
2820	}
2821	else
2822	{
2823	    char line[80];
2824	    char *nl = NULL;
2825	    send_to_server ("Sticky ", 0);
2826	    while (fgets (line, sizeof (line), f) != NULL)
2827	    {
2828		send_to_server (line, 0);
2829		nl = strchr (line, '\n');
2830		if (nl != NULL)
2831		    break;
2832	    }
2833	    if (nl == NULL)
2834                send_to_server ("\012", 1);
2835	    if (fclose (f) == EOF)
2836		error (0, errno, "closing %s", adm_name);
2837	}
2838    }
2839    free (adm_name);
2840    if (last_repos != NULL)
2841	free (last_repos);
2842    if (last_update_dir != NULL)
2843	free (last_update_dir);
2844    last_repos = xstrdup (repos);
2845    last_update_dir = xstrdup (update_dir);
2846}
2847
2848/* Send a Repository line and set toplevel_repos.  */
2849
2850void
2851send_a_repository (dir, repository, update_dir_in)
2852    const char *dir;
2853    const char *repository;
2854    const char *update_dir_in;
2855{
2856    char *update_dir;
2857
2858    assert (update_dir_in);
2859    update_dir = xstrdup (update_dir_in);
2860
2861    if (toplevel_repos == NULL && repository != NULL)
2862    {
2863	if (update_dir[0] == '\0'
2864	    || (update_dir[0] == '.' && update_dir[1] == '\0'))
2865	    toplevel_repos = xstrdup (repository);
2866	else
2867	{
2868	    /*
2869	     * Get the repository from a CVS/Repository file if update_dir
2870	     * is absolute.  This is not correct in general, because
2871	     * the CVS/Repository file might not be the top-level one.
2872	     * This is for cases like "cvs update /foo/bar" (I'm not
2873	     * sure it matters what toplevel_repos we get, but it does
2874	     * matter that we don't hit the "internal error" code below).
2875	     */
2876	    if (update_dir[0] == '/')
2877		toplevel_repos = Name_Repository (update_dir, update_dir);
2878	    else
2879	    {
2880		/*
2881		 * Guess the repository of that directory by looking at a
2882		 * subdirectory and removing as many pathname components
2883		 * as are in update_dir.  I think that will always (or at
2884		 * least almost always) be 1.
2885		 *
2886		 * So this deals with directories which have been
2887		 * renamed, though it doesn't necessarily deal with
2888		 * directories which have been put inside other
2889		 * directories (and cvs invoked on the containing
2890		 * directory).  I'm not sure the latter case needs to
2891		 * work.
2892		 *
2893		 * 21 Aug 1998: Well, Mr. Above-Comment-Writer, it
2894		 * does need to work after all.  When we are using the
2895		 * client in a multi-cvsroot environment, it will be
2896		 * fairly common that we have the above case (e.g.,
2897		 * cwd checked out from one repository but
2898		 * subdirectory checked out from another).  We can't
2899		 * assume that by walking up a directory in our wd we
2900		 * necessarily walk up a directory in the repository.
2901		 */
2902		/*
2903		 * This gets toplevel_repos wrong for "cvs update ../foo"
2904		 * but I'm not sure toplevel_repos matters in that case.
2905		 */
2906
2907		int repository_len, update_dir_len;
2908
2909		strip_trailing_slashes (update_dir);
2910
2911		repository_len = strlen (repository);
2912		update_dir_len = strlen (update_dir);
2913
2914		/* Try to remove the path components in UPDATE_DIR
2915                   from REPOSITORY.  If the path elements don't exist
2916                   in REPOSITORY, or the removal of those path
2917                   elements mean that we "step above"
2918                   current_parsed_root->directory, set toplevel_repos to
2919                   current_parsed_root->directory. */
2920		if ((repository_len > update_dir_len)
2921		    && (strcmp (repository + repository_len - update_dir_len,
2922				update_dir) == 0)
2923		    /* TOPLEVEL_REPOS shouldn't be above current_parsed_root->directory */
2924		    && ((size_t)(repository_len - update_dir_len)
2925			> strlen (current_parsed_root->directory)))
2926		{
2927		    /* The repository name contains UPDATE_DIR.  Set
2928                       toplevel_repos to the repository name without
2929                       UPDATE_DIR. */
2930
2931		    toplevel_repos = xmalloc (repository_len - update_dir_len);
2932		    /* Note that we don't copy the trailing '/'.  */
2933		    strncpy (toplevel_repos, repository,
2934			     repository_len - update_dir_len - 1);
2935		    toplevel_repos[repository_len - update_dir_len - 1] = '\0';
2936		}
2937		else
2938		{
2939		    toplevel_repos = xstrdup (current_parsed_root->directory);
2940		}
2941	    }
2942	}
2943    }
2944
2945    send_repository (dir, repository, update_dir);
2946    free (update_dir);
2947}
2948
2949
2950
2951/* The "expanded" modules.  */
2952static int modules_count;
2953static int modules_allocated;
2954static char **modules_vector;
2955
2956static void
2957handle_module_expansion (args, len)
2958    char *args;
2959    int len;
2960{
2961    if (modules_vector == NULL)
2962    {
2963	modules_allocated = 1; /* Small for testing */
2964	modules_vector = (char **) xmalloc
2965	  (modules_allocated * sizeof (modules_vector[0]));
2966    }
2967    else if (modules_count >= modules_allocated)
2968    {
2969	modules_allocated *= 2;
2970	modules_vector = (char **) xrealloc
2971	  ((char *) modules_vector,
2972	   modules_allocated * sizeof (modules_vector[0]));
2973    }
2974    modules_vector[modules_count] = xmalloc (strlen (args) + 1);
2975    strcpy (modules_vector[modules_count], args);
2976    ++modules_count;
2977}
2978
2979/* Original, not "expanded" modules.  */
2980static int module_argc;
2981static char **module_argv;
2982
2983void
2984client_expand_modules (argc, argv, local)
2985    int argc;
2986    char **argv;
2987    int local;
2988{
2989    int errs;
2990    int i;
2991
2992    module_argc = argc;
2993    module_argv = (char **) xmalloc ((argc + 1) * sizeof (module_argv[0]));
2994    for (i = 0; i < argc; ++i)
2995	module_argv[i] = xstrdup (argv[i]);
2996    module_argv[argc] = NULL;
2997
2998    for (i = 0; i < argc; ++i)
2999	send_arg (argv[i]);
3000    send_a_repository ("", current_parsed_root->directory, "");
3001
3002    send_to_server ("expand-modules\012", 0);
3003
3004    errs = get_server_responses ();
3005    if (last_repos != NULL)
3006        free (last_repos);
3007    last_repos = NULL;
3008    if (last_update_dir != NULL)
3009        free (last_update_dir);
3010    last_update_dir = NULL;
3011    if (errs)
3012	error (errs, 0, "cannot expand modules");
3013}
3014
3015void
3016client_send_expansions (local, where, build_dirs)
3017    int local;
3018    char *where;
3019    int build_dirs;
3020{
3021    int i;
3022    char *argv[1];
3023
3024    /* Send the original module names.  The "expanded" module name might
3025       not be suitable as an argument to a co request (e.g. it might be
3026       the result of a -d argument in the modules file).  It might be
3027       cleaner if we genuinely expanded module names, all the way to a
3028       local directory and repository, but that isn't the way it works
3029       now.  */
3030    send_file_names (module_argc, module_argv, 0);
3031
3032    for (i = 0; i < modules_count; ++i)
3033    {
3034	argv[0] = where ? where : modules_vector[i];
3035	if (isfile (argv[0]))
3036	    send_files (1, argv, local, 0, build_dirs ? SEND_BUILD_DIRS : 0);
3037    }
3038    send_a_repository ("", current_parsed_root->directory, "");
3039}
3040
3041void
3042client_nonexpanded_setup ()
3043{
3044    send_a_repository ("", current_parsed_root->directory, "");
3045}
3046
3047/* Receive a cvswrappers line from the server; it must be a line
3048   containing an RCS option (e.g., "*.exe   -k 'b'").
3049
3050   Note that this doesn't try to handle -t/-f options (which are a
3051   whole separate issue which noone has thought much about, as far
3052   as I know).
3053
3054   We need to know the keyword expansion mode so we know whether to
3055   read the file in text or binary mode.  */
3056
3057static void
3058handle_wrapper_rcs_option (args, len)
3059    char *args;
3060    int len;
3061{
3062    char *p;
3063
3064    /* Enforce the notes in cvsclient.texi about how the response is not
3065       as free-form as it looks.  */
3066    p = strchr (args, ' ');
3067    if (p == NULL)
3068	goto handle_error;
3069    if (*++p != '-'
3070	|| *++p != 'k'
3071	|| *++p != ' '
3072	|| *++p != '\'')
3073	goto handle_error;
3074    if (strchr (p, '\'') == NULL)
3075	goto handle_error;
3076
3077    /* Add server-side cvswrappers line to our wrapper list. */
3078    wrap_add (args, 0);
3079    return;
3080 handle_error:
3081    error (0, errno, "protocol error: ignoring invalid wrappers %s", args);
3082}
3083
3084
3085static void
3086handle_m (args, len)
3087    char *args;
3088    int len;
3089{
3090    /* In the case where stdout and stderr point to the same place,
3091       fflushing stderr will make output happen in the correct order.
3092       Often stderr will be line-buffered and this won't be needed,
3093       but not always (is that true?  I think the comment is probably
3094       based on being confused between default buffering between
3095       stdout and stderr.  But I'm not sure).  */
3096    fflush (stderr);
3097    fwrite (args, len, sizeof (*args), stdout);
3098    putc ('\n', stdout);
3099}
3100
3101static void handle_mbinary PROTO ((char *, int));
3102
3103static void
3104handle_mbinary (args, len)
3105    char *args;
3106    int len;
3107{
3108    char *size_string;
3109    size_t size;
3110    size_t totalread;
3111    size_t nread;
3112    size_t toread;
3113    char buf[8192];
3114
3115    /* See comment at handle_m about (non)flush of stderr.  */
3116
3117    /* Get the size.  */
3118    read_line (&size_string);
3119    size = strto_file_size (size_string);
3120    free (size_string);
3121
3122    /* OK, now get all the data.  The algorithm here is that we read
3123       as much as the network wants to give us in
3124       try_read_from_server, and then we output it all, and then
3125       repeat, until we get all the data.  */
3126    totalread = 0;
3127    while (totalread < size)
3128    {
3129	toread = size - totalread;
3130	if (toread > sizeof buf)
3131	    toread = sizeof buf;
3132
3133	nread = try_read_from_server (buf, toread);
3134	cvs_output_binary (buf, nread);
3135	totalread += nread;
3136    }
3137}
3138
3139static void
3140handle_e (args, len)
3141    char *args;
3142    int len;
3143{
3144    /* In the case where stdout and stderr point to the same place,
3145       fflushing stdout will make output happen in the correct order.  */
3146    fflush (stdout);
3147    fwrite (args, len, sizeof (*args), stderr);
3148    putc ('\n', stderr);
3149}
3150
3151/*ARGSUSED*/
3152static void
3153handle_f (args, len)
3154    char *args;
3155    int len;
3156{
3157    fflush (stderr);
3158}
3159
3160static void handle_mt PROTO ((char *, int));
3161
3162static void
3163handle_mt (args, len)
3164    char *args;
3165    int len;
3166{
3167    char *p;
3168    char *tag = args;
3169    char *text;
3170
3171    /* See comment at handle_m for more details.  */
3172    fflush (stderr);
3173
3174    p = strchr (args, ' ');
3175    if (p == NULL)
3176	text = NULL;
3177    else
3178    {
3179	*p++ = '\0';
3180	text = p;
3181    }
3182
3183    switch (tag[0])
3184    {
3185	case '+':
3186	    if (strcmp (tag, "+updated") == 0)
3187		updated_seen = 1;
3188	    else if (strcmp (tag, "+importmergecmd") == 0)
3189		importmergecmd.seen = 1;
3190	    break;
3191	case '-':
3192	    if (strcmp (tag, "-updated") == 0)
3193		updated_seen = 0;
3194	    else if (strcmp (tag, "-importmergecmd") == 0)
3195	    {
3196		char buf[80];
3197
3198		/* Now that we have gathered the information, we can
3199                   output the suggested merge command.  */
3200
3201		if (importmergecmd.conflicts == 0
3202		    || importmergecmd.mergetag1 == NULL
3203		    || importmergecmd.mergetag2 == NULL
3204		    || importmergecmd.repository == NULL)
3205		{
3206		    error (0, 0,
3207			   "invalid server: incomplete importmergecmd tags");
3208		    break;
3209		}
3210
3211		sprintf (buf, "\n%d conflicts created by this import.\n",
3212			 importmergecmd.conflicts);
3213		cvs_output (buf, 0);
3214		cvs_output ("Use the following command to help the merge:\n\n",
3215			    0);
3216		cvs_output ("\t", 1);
3217		cvs_output (program_name, 0);
3218		if (CVSroot_cmdline != NULL)
3219		{
3220		    cvs_output (" -d ", 0);
3221		    cvs_output (CVSroot_cmdline, 0);
3222		}
3223		cvs_output (" checkout -j", 0);
3224		cvs_output (importmergecmd.mergetag1, 0);
3225		cvs_output (" -j", 0);
3226		cvs_output (importmergecmd.mergetag2, 0);
3227		cvs_output (" ", 1);
3228		cvs_output (importmergecmd.repository, 0);
3229		cvs_output ("\n\n", 0);
3230
3231		/* Clear the static variables so that everything is
3232                   ready for any subsequent importmergecmd tag.  */
3233		importmergecmd.conflicts = 0;
3234		free (importmergecmd.mergetag1);
3235		importmergecmd.mergetag1 = NULL;
3236		free (importmergecmd.mergetag2);
3237		importmergecmd.mergetag2 = NULL;
3238		free (importmergecmd.repository);
3239		importmergecmd.repository = NULL;
3240
3241		importmergecmd.seen = 0;
3242	    }
3243	    break;
3244	default:
3245	    if (updated_seen)
3246	    {
3247		if (strcmp (tag, "fname") == 0)
3248		{
3249		    if (updated_fname != NULL)
3250		    {
3251			/* Output the previous message now.  This can happen
3252			   if there was no Update-existing or other such
3253			   response, due to the -n global option.  */
3254			cvs_output ("U ", 0);
3255			cvs_output (updated_fname, 0);
3256			cvs_output ("\n", 1);
3257			free (updated_fname);
3258		    }
3259		    updated_fname = xstrdup (text);
3260		}
3261		/* Swallow all other tags.  Either they are extraneous
3262		   or they reflect future extensions that we can
3263		   safely ignore.  */
3264	    }
3265	    else if (importmergecmd.seen)
3266	    {
3267		if (strcmp (tag, "conflicts") == 0)
3268		    importmergecmd.conflicts = text ? atoi (text) : -1;
3269		else if (strcmp (tag, "mergetag1") == 0)
3270		    importmergecmd.mergetag1 = xstrdup (text);
3271		else if (strcmp (tag, "mergetag2") == 0)
3272		    importmergecmd.mergetag2 = xstrdup (text);
3273		else if (strcmp (tag, "repository") == 0)
3274		    importmergecmd.repository = xstrdup (text);
3275		/* Swallow all other tags.  Either they are text for
3276                   which we are going to print our own version when we
3277                   see -importmergecmd, or they are future extensions
3278                   we can safely ignore.  */
3279	    }
3280	    else if (strcmp (tag, "newline") == 0)
3281		printf ("\n");
3282	    else if (text != NULL)
3283		printf ("%s", text);
3284    }
3285}
3286
3287#endif /* CLIENT_SUPPORT */
3288#if defined(CLIENT_SUPPORT) || defined(SERVER_SUPPORT)
3289
3290/* This table must be writeable if the server code is included.  */
3291struct response responses[] =
3292{
3293#ifdef CLIENT_SUPPORT
3294#define RSP_LINE(n, f, t, s) {n, f, t, s}
3295#else /* ! CLIENT_SUPPORT */
3296#define RSP_LINE(n, f, t, s) {n, s}
3297#endif /* CLIENT_SUPPORT */
3298
3299    RSP_LINE("ok", handle_ok, response_type_ok, rs_essential),
3300    RSP_LINE("error", handle_error, response_type_error, rs_essential),
3301    RSP_LINE("Valid-requests", handle_valid_requests, response_type_normal,
3302       rs_essential),
3303    RSP_LINE("Checked-in", handle_checked_in, response_type_normal,
3304       rs_essential),
3305    RSP_LINE("New-entry", handle_new_entry, response_type_normal, rs_optional),
3306    RSP_LINE("Checksum", handle_checksum, response_type_normal, rs_optional),
3307    RSP_LINE("Copy-file", handle_copy_file, response_type_normal, rs_optional),
3308    RSP_LINE("Updated", handle_updated, response_type_normal, rs_essential),
3309    RSP_LINE("Created", handle_created, response_type_normal, rs_optional),
3310    RSP_LINE("Update-existing", handle_update_existing, response_type_normal,
3311       rs_optional),
3312    RSP_LINE("Merged", handle_merged, response_type_normal, rs_essential),
3313    RSP_LINE("Patched", handle_patched, response_type_normal, rs_optional),
3314    RSP_LINE("Rcs-diff", handle_rcs_diff, response_type_normal, rs_optional),
3315    RSP_LINE("Mode", handle_mode, response_type_normal, rs_optional),
3316    RSP_LINE("Mod-time", handle_mod_time, response_type_normal, rs_optional),
3317    RSP_LINE("Removed", handle_removed, response_type_normal, rs_essential),
3318    RSP_LINE("Remove-entry", handle_remove_entry, response_type_normal,
3319       rs_optional),
3320    RSP_LINE("Set-static-directory", handle_set_static_directory,
3321       response_type_normal,
3322       rs_optional),
3323    RSP_LINE("Clear-static-directory", handle_clear_static_directory,
3324       response_type_normal,
3325       rs_optional),
3326    RSP_LINE("Set-sticky", handle_set_sticky, response_type_normal,
3327       rs_optional),
3328    RSP_LINE("Clear-sticky", handle_clear_sticky, response_type_normal,
3329       rs_optional),
3330    RSP_LINE("Template", handle_template, response_type_normal,
3331       rs_optional),
3332    RSP_LINE("Notified", handle_notified, response_type_normal, rs_optional),
3333    RSP_LINE("Module-expansion", handle_module_expansion, response_type_normal,
3334       rs_optional),
3335    RSP_LINE("Wrapper-rcsOption", handle_wrapper_rcs_option,
3336       response_type_normal,
3337       rs_optional),
3338    RSP_LINE("M", handle_m, response_type_normal, rs_essential),
3339    RSP_LINE("Mbinary", handle_mbinary, response_type_normal, rs_optional),
3340    RSP_LINE("E", handle_e, response_type_normal, rs_essential),
3341    RSP_LINE("F", handle_f, response_type_normal, rs_optional),
3342    RSP_LINE("MT", handle_mt, response_type_normal, rs_optional),
3343    /* Possibly should be response_type_error.  */
3344    RSP_LINE(NULL, NULL, response_type_normal, rs_essential)
3345
3346#undef RSP_LINE
3347};
3348
3349#endif /* CLIENT_SUPPORT or SERVER_SUPPORT */
3350#ifdef CLIENT_SUPPORT
3351
3352/* 
3353 * If LEN is 0, then send_to_server() computes string's length itself.
3354 *
3355 * Therefore, pass the real length when transmitting data that might
3356 * contain 0's.
3357 */
3358void
3359send_to_server (str, len)
3360     const char *str;
3361     size_t len;
3362{
3363    static int nbytes;
3364
3365    if (len == 0)
3366	len = strlen (str);
3367
3368    buf_output (to_server, str, len);
3369      
3370    /* There is no reason not to send data to the server, so do it
3371       whenever we've accumulated enough information in the buffer to
3372       make it worth sending.  */
3373    nbytes += len;
3374    if (nbytes >= 2 * BUFFER_DATA_SIZE)
3375    {
3376	int status;
3377
3378        status = buf_send_output (to_server);
3379	if (status != 0)
3380	    error (1, status, "error writing to server");
3381	nbytes = 0;
3382    }
3383}
3384
3385/* Read up to LEN bytes from the server.  Returns actual number of
3386   bytes read, which will always be at least one; blocks if there is
3387   no data available at all.  Gives a fatal error on EOF or error.  */
3388static size_t
3389try_read_from_server (buf, len)
3390    char *buf;
3391    size_t len;
3392{
3393    int status, nread;
3394    char *data;
3395
3396    status = buf_read_data (from_server, len, &data, &nread);
3397    if (status != 0)
3398    {
3399	if (status == -1)
3400	    error (1, 0,
3401		   "end of file from server (consult above messages if any)");
3402	else if (status == -2)
3403	    error (1, 0, "out of memory");
3404	else
3405	    error (1, status, "reading from server");
3406    }
3407
3408    memcpy (buf, data, nread);
3409
3410    return nread;
3411}
3412
3413/*
3414 * Read LEN bytes from the server or die trying.
3415 */
3416void
3417read_from_server (buf, len)
3418    char *buf;
3419    size_t len;
3420{
3421    size_t red = 0;
3422    while (red < len)
3423    {
3424	red += try_read_from_server (buf + red, len - red);
3425	if (red == len)
3426	    break;
3427    }
3428}
3429
3430/*
3431 * Get some server responses and process them.  Returns nonzero for
3432 * error, 0 for success.  */
3433int
3434get_server_responses ()
3435{
3436    struct response *rs;
3437    do
3438    {
3439	char *cmd;
3440	int len;
3441	
3442	len = read_line (&cmd);
3443	for (rs = responses; rs->name != NULL; ++rs)
3444	    if (strncmp (cmd, rs->name, strlen (rs->name)) == 0)
3445	    {
3446		int cmdlen = strlen (rs->name);
3447		if (cmd[cmdlen] == '\0')
3448		    ;
3449		else if (cmd[cmdlen] == ' ')
3450		    ++cmdlen;
3451		else
3452		    /*
3453		     * The first len characters match, but it's a different
3454		     * response.  e.g. the response is "oklahoma" but we
3455		     * matched "ok".
3456		     */
3457		    continue;
3458		(*rs->func) (cmd + cmdlen, len - cmdlen);
3459		break;
3460	    }
3461	if (rs->name == NULL)
3462	    /* It's OK to print just to the first '\0'.  */
3463	    /* We might want to handle control characters and the like
3464	       in some other way other than just sending them to stdout.
3465	       One common reason for this error is if people use :ext:
3466	       with a version of rsh which is doing CRLF translation or
3467	       something, and so the client gets "ok^M" instead of "ok".
3468	       Right now that will tend to print part of this error
3469	       message over the other part of it.  It seems like we could
3470	       do better (either in general, by quoting or omitting all
3471	       control characters, and/or specifically, by detecting the CRLF
3472	       case and printing a specific error message).  */
3473	    error (0, 0,
3474		   "warning: unrecognized response `%s' from cvs server",
3475		   cmd);
3476	free (cmd);
3477    } while (rs->type == response_type_normal);
3478
3479    if (updated_fname != NULL)
3480    {
3481	/* Output the previous message now.  This can happen
3482	   if there was no Update-existing or other such
3483	   response, due to the -n global option.  */
3484	cvs_output ("U ", 0);
3485	cvs_output (updated_fname, 0);
3486	cvs_output ("\n", 1);
3487	free (updated_fname);
3488	updated_fname = NULL;
3489    }
3490
3491    if (rs->type == response_type_error)
3492	return 1;
3493    if (failure_exit)
3494	return 1;
3495    return 0;
3496}
3497
3498
3499
3500/* Get the responses and then close the connection.  */
3501
3502/*
3503 * Flag var; we'll set it in start_server() and not one of its
3504 * callees, such as start_rsh_server().  This means that there might
3505 * be a small window between the starting of the server and the
3506 * setting of this var, but all the code in that window shouldn't care
3507 * because it's busy checking return values to see if the server got
3508 * started successfully anyway.
3509 */
3510int server_started = 0;
3511
3512int
3513get_responses_and_close ()
3514{
3515    int errs = get_server_responses ();
3516    int status;
3517
3518    /* The following is necessary when working with multiple cvsroots, at least
3519     * with commit.  It used to be buried nicely in do_deferred_progs() before
3520     * that function was removed.  I suspect it wouldn't be necessary if
3521     * call_in_directory() saved its working directory via save_cwd() before
3522     * changing its directory and restored the saved working directory via
3523     * restore_cwd() before exiting.  Of course, calling CVS_CHDIR only once,
3524     * here, may be more efficient.
3525     */
3526    if( toplevel_wd != NULL )
3527    {
3528	if( CVS_CHDIR( toplevel_wd ) < 0 )
3529	    error( 1, errno, "could not chdir to %s", toplevel_wd );
3530    }
3531
3532    if (client_prune_dirs)
3533	process_prune_candidates ();
3534
3535    /* First we shut down TO_SERVER.  That tells the server that its input is
3536     * finished.  It then shuts down the buffer it is sending to us, at which
3537     * point our shut down of FROM_SERVER will complete.
3538     */
3539
3540    status = buf_shutdown (to_server);
3541    if (status != 0)
3542	error (0, status, "shutting down buffer to server");
3543    buf_free (to_server);
3544    to_server = NULL;
3545
3546    status = buf_shutdown (from_server);
3547    if (status != 0)
3548	error (0, status, "shutting down buffer from server");
3549    buf_free (from_server);
3550    from_server = NULL;
3551    server_started = 0;
3552
3553    /* see if we need to sleep before returning to avoid time-stamp races */
3554    if (last_register_time)
3555    {
3556	sleep_past (last_register_time);
3557    }
3558
3559    return errs;
3560}
3561	
3562#ifndef NO_EXT_METHOD
3563static void start_rsh_server PROTO((cvsroot_t *, struct buffer **, struct buffer **));
3564#endif
3565
3566int
3567supported_request (name)
3568    char *name;
3569{
3570    struct request *rq;
3571
3572    for (rq = requests; rq->name; rq++)
3573	if (!strcmp (rq->name, name))
3574	    return (rq->flags & RQ_SUPPORTED) != 0;
3575    error (1, 0, "internal error: testing support for unknown option?");
3576    /* NOTREACHED */
3577    return 0;
3578}
3579
3580
3581
3582#if defined (AUTH_CLIENT_SUPPORT) || defined (HAVE_KERBEROS) || defined (HAVE_GSSAPI)
3583static struct hostent *init_sockaddr PROTO ((struct sockaddr_in *, char *,
3584					     unsigned int));
3585
3586static struct hostent *
3587init_sockaddr (name, hostname, port)
3588    struct sockaddr_in *name;
3589    char *hostname;
3590    unsigned int port;
3591{
3592    struct hostent *hostinfo;
3593    unsigned short shortport = port;
3594
3595    memset (name, 0, sizeof (*name));
3596    name->sin_family = AF_INET;
3597    name->sin_port = htons (shortport);
3598    hostinfo = gethostbyname (hostname);
3599    if (hostinfo == NULL)
3600    {
3601	fprintf (stderr, "Unknown host %s.\n", hostname);
3602	error_exit ();
3603    }
3604    name->sin_addr = *(struct in_addr *) hostinfo->h_addr;
3605    return hostinfo;
3606}
3607
3608
3609
3610/* Generic function to do port number lookup tasks.
3611 *
3612 * In order of precedence, will return:
3613 * 	getenv (envname), if defined
3614 * 	getservbyname (portname), if defined
3615 * 	defaultport
3616 */
3617static int
3618get_port_number (envname, portname, defaultport)
3619    const char *envname;
3620    const char *portname;
3621    int defaultport;
3622{
3623    struct servent *s;
3624    char *port_s;
3625
3626    if (envname && (port_s = getenv (envname)))
3627    {
3628	int port = atoi (port_s);
3629	if (port <= 0)
3630	{
3631	    error (0, 0, "%s must be a positive integer!  If you", envname);
3632	    error (0, 0, "are trying to force a connection via rsh, please");
3633	    error (0, 0, "put \":server:\" at the beginning of your CVSROOT");
3634	    error (1, 0, "variable.");
3635	}
3636	return port;
3637    }
3638    else if (portname && (s = getservbyname (portname, "tcp")))
3639	return ntohs (s->s_port);
3640    else
3641	return defaultport;
3642}
3643
3644
3645
3646/* get the port number for a client to connect to based on the port
3647 * and method of a cvsroot_t.
3648 *
3649 * we do this here instead of in parse_cvsroot so that we can keep network
3650 * code confined to a localized area and also to delay the lookup until the
3651 * last possible moment so it remains possible to run cvs client commands that
3652 * skip opening connections to the server (i.e. skip network operations
3653 * entirely)
3654 *
3655 * and yes, I know none of the commands do that now, but here's to planning
3656 * for the future, eh?  cheers.
3657 *
3658 * FIXME - We could cache the port lookup safely right now as we never change
3659 * it for a single root on the fly, but we'd have to un'const some other
3660 * functions - REMOVE_FIXME? This may be unecessary.  We're talking about,
3661 * what, usually one, sometimes two lookups of the port per invocation.  I
3662 * think twice is by far the rarer of the two cases - only the login function
3663 * will need to do it to save the canonical CVSROOT. -DRP
3664 */
3665int
3666get_cvs_port_number (root)
3667    const cvsroot_t *root;
3668{
3669
3670    if (root->port) return root->port;
3671
3672    switch (root->method)
3673    {
3674# ifdef HAVE_GSSAPI
3675	case gserver_method:
3676# endif /* HAVE_GSSAPI */
3677# ifdef AUTH_CLIENT_SUPPORT
3678	case pserver_method:
3679# endif /* AUTH_CLIENT_SUPPORT */
3680# if defined (AUTH_CLIENT_SUPPORT) || defined (HAVE_GSSAPI)
3681	    return get_port_number ("CVS_CLIENT_PORT", "cvspserver", CVS_AUTH_PORT);
3682# endif /* defined (AUTH_CLIENT_SUPPORT) || defined (HAVE_GSSAPI) */
3683# ifdef HAVE_KERBEROS
3684	case kserver_method:
3685	    return get_port_number ("CVS_CLIENT_PORT", "cvs", CVS_PORT);
3686# endif /* HAVE_KERBEROS */
3687	default:
3688	    error(1, EINVAL, "internal error: get_cvs_port_number called for invalid connection method (%s)",
3689		    method_names[root->method]);
3690	    break;
3691    }
3692    /* NOTREACHED */
3693    return -1;
3694}
3695
3696
3697
3698void
3699make_bufs_from_fds (tofd, fromfd, child_pid, to_server, from_server, is_sock)
3700    int tofd;
3701    int fromfd;
3702    int child_pid;
3703    struct buffer **to_server;
3704    struct buffer **from_server;
3705    int is_sock;
3706{
3707    FILE *to_server_fp;
3708    FILE *from_server_fp;
3709
3710# ifdef NO_SOCKET_TO_FD
3711    if (is_sock)
3712    {
3713	assert (tofd == fromfd);
3714	*to_server = socket_buffer_initialize (tofd, 0,
3715					      (BUFMEMERRPROC) NULL);
3716	*from_server = socket_buffer_initialize (tofd, 1,
3717						(BUFMEMERRPROC) NULL);
3718    }
3719    else
3720# endif /* NO_SOCKET_TO_FD */
3721    {
3722	/* todo: some OS's don't need these calls... */
3723	close_on_exec (tofd);
3724	close_on_exec (fromfd);
3725
3726	/* SCO 3 and AIX have a nasty bug in the I/O libraries which precludes
3727	   fdopening the same file descriptor twice, so dup it if it is the
3728	   same.  */
3729	if (tofd == fromfd)
3730	{
3731	    fromfd = dup (tofd);
3732	    if (fromfd < 0)
3733		error (1, errno, "cannot dup net connection");
3734	}
3735
3736	/* These will use binary mode on systems which have it.  */
3737	/*
3738	 * Also, we know that from_server is shut down second, so we pass
3739	 * child_pid in there.  In theory, it should be stored in both
3740	 * buffers with a ref count...
3741	 */
3742	to_server_fp = fdopen (tofd, FOPEN_BINARY_WRITE);
3743	if (to_server_fp == NULL)
3744	    error (1, errno, "cannot fdopen %d for write", tofd);
3745	*to_server = stdio_buffer_initialize (to_server_fp, 0, 0,
3746					     (BUFMEMERRPROC) NULL);
3747
3748	from_server_fp = fdopen (fromfd, FOPEN_BINARY_READ);
3749	if (from_server_fp == NULL)
3750	    error (1, errno, "cannot fdopen %d for read", fromfd);
3751	*from_server = stdio_buffer_initialize (from_server_fp, child_pid, 1,
3752					       (BUFMEMERRPROC) NULL);
3753    }
3754}
3755#endif /* defined (AUTH_CLIENT_SUPPORT) || defined (HAVE_KERBEROS) || defined(HAVE_GSSAPI) */
3756
3757
3758
3759#if defined (AUTH_CLIENT_SUPPORT) || defined(HAVE_GSSAPI)
3760/* Connect to the authenticating server.
3761
3762   If VERIFY_ONLY is non-zero, then just verify that the password is
3763   correct and then shutdown the connection.
3764
3765   If VERIFY_ONLY is 0, then really connect to the server.
3766
3767   If DO_GSSAPI is non-zero, then we use GSSAPI authentication rather
3768   than the pserver password authentication.
3769
3770   If we fail to connect or if access is denied, then die with fatal
3771   error.  */
3772void
3773connect_to_pserver (root, to_server_p, from_server_p, verify_only, do_gssapi)
3774    cvsroot_t *root;
3775    struct buffer **to_server_p;
3776    struct buffer **from_server_p;
3777    int verify_only;
3778    int do_gssapi;
3779{
3780    int sock;
3781    int port_number;
3782    struct sockaddr_in client_sai;
3783    struct hostent *hostinfo;
3784    struct buffer *to_server, *from_server;
3785
3786    sock = socket (AF_INET, SOCK_STREAM, 0);
3787    if (sock == -1)
3788    {
3789	error (1, 0, "cannot create socket: %s", SOCK_STRERROR (SOCK_ERRNO));
3790    }
3791    port_number = get_cvs_port_number (root);
3792    hostinfo = init_sockaddr (&client_sai, root->hostname, port_number);
3793    if (trace)
3794    {
3795	fprintf (stderr, " -> Connecting to %s(%s):%d\n",
3796		 root->hostname,
3797		 inet_ntoa (client_sai.sin_addr), port_number);
3798    }
3799    if (connect (sock, (struct sockaddr *) &client_sai, sizeof (client_sai))
3800	< 0)
3801	error (1, 0, "connect to %s(%s):%d failed: %s",
3802	       root->hostname,
3803	       inet_ntoa (client_sai.sin_addr),
3804	       port_number, SOCK_STRERROR (SOCK_ERRNO));
3805
3806    make_bufs_from_fds (sock, sock, 0, &to_server, &from_server, 1);
3807
3808    auth_server (root, to_server, from_server, verify_only, do_gssapi, hostinfo);
3809
3810    if (verify_only)
3811    {
3812	int status;
3813
3814	status = buf_shutdown (to_server);
3815	if (status != 0)
3816	    error (0, status, "shutting down buffer to server");
3817	buf_free (to_server);
3818	to_server = NULL;
3819
3820	status = buf_shutdown (from_server);
3821	if (status != 0)
3822	    error (0, status, "shutting down buffer from server");
3823	buf_free (from_server);
3824	from_server = NULL;
3825
3826	/* Don't need to set server_started = 0 since we don't set it to 1
3827	 * until returning from this call.
3828	 */
3829    }
3830    else
3831    {
3832	*to_server_p = to_server;
3833	*from_server_p = from_server;
3834    }
3835
3836    return;
3837}
3838
3839
3840
3841static void
3842auth_server (root, lto_server, lfrom_server, verify_only, do_gssapi, hostinfo)
3843    cvsroot_t *root;
3844    struct buffer *lto_server;
3845    struct buffer *lfrom_server;
3846    int verify_only;
3847    int do_gssapi;
3848    struct hostent *hostinfo;
3849{
3850    char *username = "";		/* the username we use to connect */
3851    char no_passwd = 0;			/* gets set if no password found */
3852
3853    /* FIXME!!!!!!!!!!!!!!!!!!
3854     *
3855     * THIS IS REALLY UGLY!
3856     *
3857     * I'm setting the globals here so we can make calls to send_to_server &
3858     * read_line.  This happens again _after_ we return if we're not in
3859     * verify_only mode.  We should be relying on the values we passed in, but
3860     * sent_to_server and read_line don't require an outside buf yet.
3861     */
3862    to_server = lto_server;
3863    from_server = lfrom_server;
3864
3865    /* Run the authorization mini-protocol before anything else. */
3866    if (do_gssapi)
3867    {
3868# ifdef HAVE_GSSAPI
3869	FILE *fp = stdio_buffer_get_file(lto_server);
3870	int fd = fp ? fileno(fp) : -1;
3871	struct stat s;
3872
3873	if ((fd < 0) || (fstat (fd, &s) < 0) || !S_ISSOCK(s.st_mode))
3874	{
3875	    error (1, 0, "gserver currently only enabled for socket connections");
3876	}
3877
3878	if (! connect_to_gserver (root, fd, hostinfo))
3879	{
3880	    error (1, 0,
3881		    "authorization failed: server %s rejected access to %s",
3882		    root->hostname, root->directory);
3883	}
3884# else /* ! HAVE_GSSAPI */
3885	error (1, 0, "INTERNAL ERROR: This client does not support GSSAPI authentication");
3886# endif /* HAVE_GSSAPI */
3887    }
3888    else /* ! do_gssapi */
3889    {
3890# ifdef AUTH_CLIENT_SUPPORT
3891	char *begin      = NULL;
3892	char *password   = NULL;
3893	char *end        = NULL;
3894	
3895	if (verify_only)
3896	{
3897	    begin = "BEGIN VERIFICATION REQUEST";
3898	    end   = "END VERIFICATION REQUEST";
3899	}
3900	else
3901	{
3902	    begin = "BEGIN AUTH REQUEST";
3903	    end   = "END AUTH REQUEST";
3904	}
3905
3906	/* Get the password, probably from ~/.cvspass. */
3907	password = get_cvs_password ();
3908	username = root->username ? root->username : getcaller();
3909
3910	/* Send the empty string by default.  This is so anonymous CVS
3911	   access doesn't require client to have done "cvs login". */
3912	if (password == NULL) 
3913	{
3914	    no_passwd = 1;
3915	    password = scramble ("");
3916	}
3917
3918	/* Announce that we're starting the authorization protocol. */
3919	send_to_server(begin, 0);
3920	send_to_server("\012", 1);
3921
3922	/* Send the data the server needs. */
3923	send_to_server(root->directory, 0);
3924	send_to_server("\012", 1);
3925	send_to_server(username, 0);
3926	send_to_server("\012", 1);
3927	send_to_server(password, 0);
3928	send_to_server("\012", 1);
3929
3930	/* Announce that we're ending the authorization protocol. */
3931	send_to_server(end, 0);
3932	send_to_server("\012", 1);
3933
3934	free_cvs_password (password);
3935	password = NULL;
3936# else /* ! AUTH_CLIENT_SUPPORT */
3937	error (1, 0, "INTERNAL ERROR: This client does not support pserver authentication");
3938# endif /* AUTH_CLIENT_SUPPORT */
3939    } /* if (do_gssapi) */
3940
3941    {
3942	char *read_buf;
3943
3944	/* Loop, getting responses from the server.  */
3945	while (1)
3946	{
3947	    read_line (&read_buf);
3948
3949	    if (strcmp (read_buf, "I HATE YOU") == 0)
3950	    {
3951		/* Authorization not granted.
3952		 *
3953		 * This is a little confusing since we can reach this while loop in GSSAPI
3954		 * mode, but if GSSAPI authentication failed, we already jumped to the
3955		 * rejected label (there is no case where the connect_to_gserver function
3956		 * can return 1 and we will not receive "I LOVE YOU" from the server, barring
3957		 * broken connections and garbled messages, of course).
3958		 *
3959		 * i.e. This is a pserver specific error message and should be since
3960		 * GSSAPI doesn't use username.
3961		 */
3962		error (0, 0,
3963			"authorization failed: server %s rejected access to %s for user %s",
3964			root->hostname, root->directory, username);
3965
3966		/* Output a special error message if authentication was attempted
3967		with no password -- the user should be made aware that they may
3968		have missed a step. */
3969		if (no_passwd)
3970		{
3971		    error (0, 0,
3972			    "used empty password; try \"cvs login\" with a real password");
3973		}
3974		error_exit();
3975	    }
3976	    else if (strncmp (read_buf, "E ", 2) == 0)
3977	    {
3978		fprintf (stderr, "%s\n", read_buf + 2);
3979
3980		/* Continue with the authentication protocol.  */
3981	    }
3982	    else if (strncmp (read_buf, "error ", 6) == 0)
3983	    {
3984		char *p;
3985
3986		/* First skip the code.  */
3987		p = read_buf + 6;
3988		while (*p != ' ' && *p != '\0')
3989		    ++p;
3990
3991		/* Skip the space that follows the code.  */
3992		if (*p == ' ')
3993		    ++p;
3994
3995		/* Now output the text.  */
3996		fprintf (stderr, "%s\n", p);
3997		error_exit();
3998	    }
3999	    else if (strcmp (read_buf, "I LOVE YOU") == 0)
4000	    {
4001		free (read_buf);
4002		break;
4003	    }
4004	    else
4005	    {
4006		error (1, 0, 
4007		       "unrecognized auth response from %s: %s", 
4008		       root->hostname, read_buf);
4009	    }
4010	    free (read_buf);
4011	}
4012    }
4013}
4014#endif /* defined (AUTH_CLIENT_SUPPORT) || defined(HAVE_GSSAPI) */
4015
4016
4017
4018#ifdef CLIENT_SUPPORT
4019/* void
4020 * connect_to_forked_server ( struct buffer **to_server,
4021 *                            struct buffer **from_server )
4022 *
4023 * Connect to a forked server process.
4024 */
4025void
4026connect_to_forked_server (to_server, from_server)
4027    struct buffer **to_server;
4028    struct buffer **from_server;
4029{
4030    int tofd, fromfd;
4031    int child_pid;
4032
4033    /* This is pretty simple.  All we need to do is choose the correct
4034       cvs binary and call piped_child. */
4035
4036     const char *command[3];
4037
4038    command[0] = getenv ("CVS_SERVER");
4039    if (! command[0])
4040	command[0] = program_path;
4041    
4042    command[1] = "server";
4043    command[2] = NULL;
4044
4045    if (trace)
4046    {
4047	fprintf (stderr, " -> Forking server: %s %s\n", command[0], command[1]);
4048    }
4049
4050    child_pid = piped_child (command, &tofd, &fromfd, 0);
4051    if (child_pid < 0)
4052	error (1, 0, "could not fork server process");
4053
4054    make_bufs_from_fds (tofd, fromfd, child_pid, to_server, from_server, 0);
4055}
4056#endif /* CLIENT_SUPPORT */
4057
4058
4059
4060#ifdef HAVE_KERBEROS
4061/* This function has not been changed to deal with NO_SOCKET_TO_FD
4062   (i.e., systems on which sockets cannot be converted to file
4063   descriptors).  The first person to try building a kerberos client
4064   on such a system (OS/2, Windows 95, and maybe others) will have to
4065   take care of this.  */
4066void
4067start_tcp_server (root, to_server, from_server)
4068    cvsroot_t *root;
4069    struct buffer **to_server;
4070    struct buffer **from_server;
4071{
4072    int s;
4073    const char *portenv;
4074    int port;
4075    struct hostent *hp;
4076    struct sockaddr_in sin;
4077    char *hname;
4078
4079    s = socket (AF_INET, SOCK_STREAM, 0);
4080    if (s < 0)
4081	error (1, 0, "cannot create socket: %s", SOCK_STRERROR (SOCK_ERRNO));
4082
4083    port = get_cvs_port_number (root);
4084
4085    hp = init_sockaddr (&sin, root->hostname, port);
4086
4087    hname = xstrdup (hp->h_name);
4088  
4089    if (trace)
4090    {
4091	fprintf (stderr, " -> Connecting to %s(%s):%d\n",
4092		 root->hostname,
4093		 inet_ntoa (sin.sin_addr), port);
4094    }
4095
4096    if (connect (s, (struct sockaddr *) &sin, sizeof sin) < 0)
4097	error (1, 0, "connect to %s(%s):%d failed: %s",
4098	       root->hostname,
4099	       inet_ntoa (sin.sin_addr),
4100	       port, SOCK_STRERROR (SOCK_ERRNO));
4101
4102    {
4103	const char *realm;
4104	struct sockaddr_in laddr;
4105	int laddrlen;
4106	KTEXT_ST ticket;
4107	MSG_DAT msg_data;
4108	CREDENTIALS cred;
4109	int status;
4110
4111	realm = krb_realmofhost (hname);
4112
4113	laddrlen = sizeof (laddr);
4114	if (getsockname (s, (struct sockaddr *) &laddr, &laddrlen) < 0)
4115	    error (1, 0, "getsockname failed: %s", SOCK_STRERROR (SOCK_ERRNO));
4116
4117	/* We don't care about the checksum, and pass it as zero.  */
4118	status = krb_sendauth (KOPT_DO_MUTUAL, s, &ticket, "rcmd",
4119			       hname, realm, (unsigned long) 0, &msg_data,
4120			       &cred, sched, &laddr, &sin, "KCVSV1.0");
4121	if (status != KSUCCESS)
4122	    error (1, 0, "kerberos authentication failed: %s",
4123		   krb_get_err_text (status));
4124	memcpy (kblock, cred.session, sizeof (C_Block));
4125    }
4126
4127    close_on_exec (s);
4128
4129    free (hname);
4130
4131    /* Give caller the values it wants. */
4132    make_bufs_from_fds (s, s, 0, to_server, from_server, 1);
4133}
4134
4135#endif /* HAVE_KERBEROS */
4136
4137#ifdef HAVE_GSSAPI
4138
4139/* Receive a given number of bytes.  */
4140
4141static void
4142recv_bytes (sock, buf, need)
4143     int sock;
4144     char *buf;
4145     int need;
4146{
4147    while (need > 0)
4148    {
4149	int got;
4150
4151	got = recv (sock, buf, need, 0);
4152	if (got <= 0)
4153	    error (1, 0, "recv() from server %s: %s", current_parsed_root->hostname,
4154		   got == 0 ? "EOF" : SOCK_STRERROR (SOCK_ERRNO));
4155
4156	buf += got;
4157	need -= got;
4158    }
4159}
4160
4161/* Connect to the server using GSSAPI authentication.  */
4162
4163/* FIXME
4164 *
4165 * This really needs to be rewritten to use a buffer and not a socket.
4166 * This would enable gserver to work with the SSL code I'm about to commit
4167 * since the SSL connection is going to look like a FIFO and not a socket.
4168 *
4169 * I think, basically, it will need to use buf_output and buf_read directly
4170 * since I don't think there is a read_bytes function - only read_line.
4171 *
4172 * recv_bytes could then be removed too.
4173 *
4174 * Besides, I added some cruft to reenable the socket which shouldn't be
4175 * there.  This would also enable its removal.
4176 */
4177#define BUFSIZE 1024
4178static int
4179connect_to_gserver (root, sock, hostinfo)
4180    cvsroot_t *root;
4181    int sock;
4182    struct hostent *hostinfo;
4183{
4184    char *str;
4185    char buf[BUFSIZE];
4186    gss_buffer_desc *tok_in_ptr, tok_in, tok_out;
4187    OM_uint32 stat_min, stat_maj;
4188    gss_name_t server_name;
4189
4190    str = "BEGIN GSSAPI REQUEST\012";
4191
4192    if (send (sock, str, strlen (str), 0) < 0)
4193	error (1, 0, "cannot send: %s", SOCK_STRERROR (SOCK_ERRNO));
4194
4195    if (strlen (hostinfo->h_name) > BUFSIZE - 5)
4196	error (1, 0, "Internal error: hostname exceeds length of buffer");
4197    sprintf (buf, "cvs@%s", hostinfo->h_name);
4198    tok_in.length = strlen (buf);
4199    tok_in.value = buf;
4200    gss_import_name (&stat_min, &tok_in, GSS_C_NT_HOSTBASED_SERVICE,
4201		     &server_name);
4202
4203    tok_in_ptr = GSS_C_NO_BUFFER;
4204    gcontext = GSS_C_NO_CONTEXT;
4205
4206    do
4207    {
4208	stat_maj = gss_init_sec_context (&stat_min, GSS_C_NO_CREDENTIAL,
4209					 &gcontext, server_name,
4210					 GSS_C_NULL_OID,
4211					 (GSS_C_MUTUAL_FLAG
4212					  | GSS_C_REPLAY_FLAG),
4213					 0, NULL, tok_in_ptr, NULL, &tok_out,
4214					 NULL, NULL);
4215	if (stat_maj != GSS_S_COMPLETE && stat_maj != GSS_S_CONTINUE_NEEDED)
4216	{
4217	    OM_uint32 message_context;
4218	    OM_uint32 new_stat_min;
4219
4220	    message_context = 0;
4221	    gss_display_status (&new_stat_min, stat_maj, GSS_C_GSS_CODE,
4222                                GSS_C_NULL_OID, &message_context, &tok_out);
4223	    error (0, 0, "GSSAPI authentication failed: %s",
4224		   (char *) tok_out.value);
4225
4226	    message_context = 0;
4227	    gss_display_status (&new_stat_min, stat_min, GSS_C_MECH_CODE,
4228				GSS_C_NULL_OID, &message_context, &tok_out);
4229	    error (1, 0, "GSSAPI authentication failed: %s",
4230		   (char *) tok_out.value);
4231	}
4232
4233	if (tok_out.length == 0)
4234	{
4235	    tok_in.length = 0;
4236	}
4237	else
4238	{
4239	    char cbuf[2];
4240	    int need;
4241
4242	    cbuf[0] = (tok_out.length >> 8) & 0xff;
4243	    cbuf[1] = tok_out.length & 0xff;
4244	    if (send (sock, cbuf, 2, 0) < 0)
4245		error (1, 0, "cannot send: %s", SOCK_STRERROR (SOCK_ERRNO));
4246	    if (send (sock, tok_out.value, tok_out.length, 0) < 0)
4247		error (1, 0, "cannot send: %s", SOCK_STRERROR (SOCK_ERRNO));
4248
4249	    recv_bytes (sock, cbuf, 2);
4250	    need = ((cbuf[0] & 0xff) << 8) | (cbuf[1] & 0xff);
4251
4252	    if (need > sizeof buf)
4253	    {
4254		ssize_t got;
4255		size_t total;
4256
4257		/* This usually means that the server sent us an error
4258		   message.  Read it byte by byte and print it out.
4259		   FIXME: This is a terrible error handling strategy.
4260		   However, even if we fix the server, we will still
4261		   want to do this to work with older servers.  */
4262		buf[0] = cbuf[0];
4263		buf[1] = cbuf[1];
4264		total = 2;
4265		while (got = recv (sock, buf + total, sizeof buf - total, 0))
4266		{
4267		    if (got < 0)
4268			error (1, 0, "recv() from server %s: %s",
4269			       root->hostname, SOCK_STRERROR (SOCK_ERRNO));
4270		    total += got;
4271		    if (strrchr (buf + total - got, '\n'))
4272			break;
4273		}
4274		buf[total] = '\0';
4275		if (buf[total - 1] == '\n')
4276		    buf[total - 1] = '\0';
4277		error (1, 0, "error from server %s: %s", root->hostname,
4278		       buf);
4279	    }
4280
4281	    recv_bytes (sock, buf, need);
4282	    tok_in.length = need;
4283	}
4284
4285	tok_in.value = buf;
4286	tok_in_ptr = &tok_in;
4287    }
4288    while (stat_maj == GSS_S_CONTINUE_NEEDED);
4289
4290    return 1;
4291}
4292
4293#endif /* HAVE_GSSAPI */
4294
4295
4296
4297static int send_variable_proc PROTO ((Node *, void *));
4298
4299static int
4300send_variable_proc (node, closure)
4301    Node *node;
4302    void *closure;
4303{
4304    send_to_server ("Set ", 0);
4305    send_to_server (node->key, 0);
4306    send_to_server ("=", 1);
4307    send_to_server (node->data, 0);
4308    send_to_server ("\012", 1);
4309    return 0;
4310}
4311
4312
4313
4314/* Contact the server.  */
4315void
4316start_server ()
4317{
4318    int rootless;
4319    char *log = getenv ("CVS_CLIENT_LOG");
4320
4321    /* Clear our static variables for this invocation. */
4322    if (toplevel_repos != NULL)
4323	free (toplevel_repos);
4324    toplevel_repos = NULL;
4325
4326    /* Note that generally speaking we do *not* fall back to a different
4327       way of connecting if the first one does not work.  This is slow
4328       (*really* slow on a 14.4kbps link); the clean way to have a CVS
4329       which supports several ways of connecting is with access methods.  */
4330
4331    switch (current_parsed_root->method)
4332    {
4333
4334#ifdef AUTH_CLIENT_SUPPORT
4335	case pserver_method:
4336	    /* Toss the return value.  It will die with an error message if
4337	     * anything goes wrong anyway.
4338	     */
4339	    connect_to_pserver (current_parsed_root, &to_server, &from_server, 0, 0);
4340	    break;
4341#endif /* AUTH_CLIENT_SUPPORT */
4342
4343#if HAVE_KERBEROS
4344	case kserver_method:
4345	    start_tcp_server (current_parsed_root, &to_server, &from_server);
4346	    break;
4347#endif /* HAVE_KERBEROS */
4348
4349#ifdef HAVE_GSSAPI
4350	case gserver_method:
4351	    /* GSSAPI authentication is handled by the pserver.  */
4352	    connect_to_pserver (current_parsed_root, &to_server, &from_server, 0, 1);
4353	    break;
4354#endif /* HAVE_GSSAPI */
4355
4356	case ext_method:
4357	case extssh_method:
4358#ifdef NO_EXT_METHOD
4359	    error (0, 0, ":ext: method not supported by this port of CVS");
4360	    error (1, 0, "try :server: instead");
4361#else /* ! NO_EXT_METHOD */
4362	    start_rsh_server (current_parsed_root, &to_server, &from_server);
4363#endif /* NO_EXT_METHOD */
4364	    break;
4365
4366	case server_method:
4367#ifdef START_SERVER
4368	    {
4369	    int tofd, fromfd;
4370	    START_SERVER (&tofd, &fromfd, getcaller (),
4371			  current_parsed_root->username, current_parsed_root->hostname,
4372			  current_parsed_root->directory);
4373# ifdef START_SERVER_RETURNS_SOCKET
4374	    make_bufs_from_fds (tofd, fromfd, 0, &to_server, &from_server, 1);
4375# else /* ! START_SERVER_RETURNS_SOCKET */
4376	    make_bufs_from_fds (tofd, fromfd, 0, &to_server, &from_server, 0);
4377# endif /* START_SERVER_RETURNS_SOCKET */
4378	    }
4379#else /* ! START_SERVER */
4380	    /* FIXME: It should be possible to implement this portably,
4381	       like pserver, which would get rid of the duplicated code
4382	       in {vms,windows-NT,...}/startserver.c.  */
4383	    error (1, 0,
4384"the :server: access method is not supported by this port of CVS");
4385#endif /* START_SERVER */
4386	    break;
4387
4388        case fork_method:
4389	    connect_to_forked_server (&to_server, &from_server);
4390	    break;
4391
4392	default:
4393	    error (1, 0, "\
4394(start_server internal error): unknown access method");
4395	    break;
4396    }
4397
4398    /* "Hi, I'm Darlene and I'll be your server tonight..." */
4399    server_started = 1;
4400
4401    /* Set up logfiles, if any.
4402     *
4403     * We do this _after_ authentication on purpose.  Wouldn't really like to
4404     * worry about logging passwords...
4405     */
4406    if (log)
4407    {
4408	int len = strlen (log);
4409	char *buf = xmalloc (len + 5);
4410	char *p;
4411	FILE *fp;
4412
4413	strcpy (buf, log);
4414	p = buf + len;
4415
4416	/* Open logfiles in binary mode so that they reflect
4417	   exactly what was transmitted and received (that is
4418	   more important than that they be maximally
4419	   convenient to view).  */
4420	/* Note that if we create several connections in a single CVS client
4421	   (currently used by update.c), then the last set of logfiles will
4422	   overwrite the others.  There is currently no way around this.  */
4423	strcpy (p, ".in");
4424	fp = open_file (buf, "wb");
4425        if (fp == NULL)
4426	    error (0, errno, "opening to-server logfile %s", buf);
4427	else
4428	    to_server = log_buffer_initialize (to_server, fp, 0,
4429					       (BUFMEMERRPROC) NULL);
4430
4431	strcpy (p, ".out");
4432	fp = open_file (buf, "wb");
4433        if (fp == NULL)
4434	    error (0, errno, "opening from-server logfile %s", buf);
4435	else
4436	    from_server = log_buffer_initialize (from_server, fp, 1,
4437						 (BUFMEMERRPROC) NULL);
4438
4439	free (buf);
4440    }
4441
4442    /* Clear static variables.  */
4443    if (toplevel_repos != NULL)
4444	free (toplevel_repos);
4445    toplevel_repos = NULL;
4446    if (last_repos != NULL)
4447	free (last_repos);
4448    last_repos = NULL;
4449    if (last_update_dir != NULL)
4450	free (last_update_dir);
4451    last_update_dir = NULL;
4452    stored_checksum_valid = 0;
4453    if (stored_mode != NULL)
4454    {
4455	free (stored_mode);
4456	stored_mode = NULL;
4457    }
4458
4459    rootless = (strcmp (cvs_cmd_name, "init") == 0);
4460    if (!rootless)
4461    {
4462	send_to_server ("Root ", 0);
4463	send_to_server (current_parsed_root->directory, 0);
4464	send_to_server ("\012", 1);
4465    }
4466
4467    {
4468	struct response *rs;
4469
4470	send_to_server ("Valid-responses", 0);
4471
4472	for (rs = responses; rs->name != NULL; ++rs)
4473	{
4474	    send_to_server (" ", 0);
4475	    send_to_server (rs->name, 0);
4476	}
4477	send_to_server ("\012", 1);
4478    }
4479    send_to_server ("valid-requests\012", 0);
4480
4481    if (get_server_responses ())
4482	error_exit ();
4483
4484    /*
4485     * Now handle global options.
4486     *
4487     * -H, -f, -d, -e should be handled OK locally.
4488     *
4489     * -b we ignore (treating it as a server installation issue).
4490     * FIXME: should be an error message.
4491     *
4492     * -v we print local version info; FIXME: Add a protocol request to get
4493     * the version from the server so we can print that too.
4494     *
4495     * -l -t -r -w -q -n and -Q need to go to the server.
4496     */
4497
4498    {
4499	int have_global = supported_request ("Global_option");
4500
4501	if (noexec)
4502	{
4503	    if (have_global)
4504	    {
4505		send_to_server ("Global_option -n\012", 0);
4506	    }
4507	    else
4508		error (1, 0,
4509		       "This server does not support the global -n option.");
4510	}
4511	if (quiet)
4512	{
4513	    if (have_global)
4514	    {
4515		send_to_server ("Global_option -q\012", 0);
4516	    }
4517	    else
4518		error (1, 0,
4519		       "This server does not support the global -q option.");
4520	}
4521	if (really_quiet)
4522	{
4523	    if (have_global)
4524	    {
4525		send_to_server ("Global_option -Q\012", 0);
4526	    }
4527	    else
4528		error (1, 0,
4529		       "This server does not support the global -Q option.");
4530	}
4531	if (!cvswrite)
4532	{
4533	    if (have_global)
4534	    {
4535		send_to_server ("Global_option -r\012", 0);
4536	    }
4537	    else
4538		error (1, 0,
4539		       "This server does not support the global -r option.");
4540	}
4541	if (trace)
4542	{
4543	    if (have_global)
4544	    {
4545		send_to_server ("Global_option -t\012", 0);
4546	    }
4547	    else
4548		error (1, 0,
4549		       "This server does not support the global -t option.");
4550	}
4551    }
4552
4553    /* Find out about server-side cvswrappers.  An extra network
4554       turnaround for cvs import seems to be unavoidable, unless we
4555       want to add some kind of client-side place to configure which
4556       filenames imply binary.  For cvs add, we could avoid the
4557       problem by keeping a copy of the wrappers in CVSADM (the main
4558       reason to bother would be so we could make add work without
4559       contacting the server, I suspect).  */
4560
4561    if ((strcmp (cvs_cmd_name, "import") == 0)
4562        || (strcmp (cvs_cmd_name, "add") == 0))
4563    {
4564	if (supported_request ("wrapper-sendme-rcsOptions"))
4565	{
4566	    int err;
4567	    send_to_server ("wrapper-sendme-rcsOptions\012", 0);
4568	    err = get_server_responses ();
4569	    if (err != 0)
4570		error (err, 0, "error reading from server");
4571	}
4572    }
4573
4574    if (cvsencrypt && !rootless)
4575    {
4576#ifdef ENCRYPTION
4577	/* Turn on encryption before turning on compression.  We do
4578           not want to try to compress the encrypted stream.  Instead,
4579           we want to encrypt the compressed stream.  If we can't turn
4580           on encryption, bomb out; don't let the user think the data
4581           is being encrypted when it is not.  */
4582#ifdef HAVE_KERBEROS
4583	if (current_parsed_root->method == kserver_method)
4584	{
4585	    if (! supported_request ("Kerberos-encrypt"))
4586		error (1, 0, "This server does not support encryption");
4587	    send_to_server ("Kerberos-encrypt\012", 0);
4588	    to_server = krb_encrypt_buffer_initialize (to_server, 0, sched,
4589						       kblock,
4590						       (BUFMEMERRPROC) NULL);
4591	    from_server = krb_encrypt_buffer_initialize (from_server, 1,
4592							 sched, kblock,
4593							 (BUFMEMERRPROC) NULL);
4594	}
4595	else
4596#endif /* HAVE_KERBEROS */
4597#ifdef HAVE_GSSAPI
4598	if (current_parsed_root->method == gserver_method)
4599	{
4600	    if (! supported_request ("Gssapi-encrypt"))
4601		error (1, 0, "This server does not support encryption");
4602	    send_to_server ("Gssapi-encrypt\012", 0);
4603	    to_server = cvs_gssapi_wrap_buffer_initialize (to_server, 0,
4604							   gcontext,
4605							   ((BUFMEMERRPROC)
4606							    NULL));
4607	    from_server = cvs_gssapi_wrap_buffer_initialize (from_server, 1,
4608							     gcontext,
4609							     ((BUFMEMERRPROC)
4610							      NULL));
4611	    cvs_gssapi_encrypt = 1;
4612	}
4613	else
4614#endif /* HAVE_GSSAPI */
4615	    error (1, 0, "Encryption is only supported when using GSSAPI or Kerberos");
4616#else /* ! ENCRYPTION */
4617	error (1, 0, "This client does not support encryption");
4618#endif /* ! ENCRYPTION */
4619    }
4620
4621    if (gzip_level && !rootless)
4622    {
4623	if (supported_request ("Gzip-stream"))
4624	{
4625	    char gzip_level_buf[5];
4626	    send_to_server ("Gzip-stream ", 0);
4627	    sprintf (gzip_level_buf, "%d", gzip_level);
4628	    send_to_server (gzip_level_buf, 0);
4629	    send_to_server ("\012", 1);
4630
4631	    /* All further communication with the server will be
4632               compressed.  */
4633
4634	    to_server = compress_buffer_initialize (to_server, 0, gzip_level,
4635						    (BUFMEMERRPROC) NULL);
4636	    from_server = compress_buffer_initialize (from_server, 1,
4637						      gzip_level,
4638						      (BUFMEMERRPROC) NULL);
4639	}
4640#ifndef NO_CLIENT_GZIP_PROCESS
4641	else if (supported_request ("gzip-file-contents"))
4642	{
4643            char gzip_level_buf[5];
4644	    send_to_server ("gzip-file-contents ", 0);
4645            sprintf (gzip_level_buf, "%d", gzip_level);
4646	    send_to_server (gzip_level_buf, 0);
4647
4648	    send_to_server ("\012", 1);
4649
4650	    file_gzip_level = gzip_level;
4651	}
4652#endif
4653	else
4654	{
4655	    fprintf (stderr, "server doesn't support gzip-file-contents\n");
4656	    /* Setting gzip_level to 0 prevents us from giving the
4657               error twice if update has to contact the server again
4658               to fetch unpatchable files.  */
4659	    gzip_level = 0;
4660	}
4661    }
4662
4663    if (cvsauthenticate && ! cvsencrypt && !rootless)
4664    {
4665	/* Turn on authentication after turning on compression, so
4666	   that we can compress the authentication information.  We
4667	   assume that encrypted data is always authenticated--the
4668	   ability to decrypt the data stream is itself a form of
4669	   authentication.  */
4670#ifdef HAVE_GSSAPI
4671	if (current_parsed_root->method == gserver_method)
4672	{
4673	    if (! supported_request ("Gssapi-authenticate"))
4674		error (1, 0,
4675		       "This server does not support stream authentication");
4676	    send_to_server ("Gssapi-authenticate\012", 0);
4677	    to_server = cvs_gssapi_wrap_buffer_initialize (to_server, 0,
4678							   gcontext,
4679							   ((BUFMEMERRPROC)
4680							    NULL));
4681	    from_server = cvs_gssapi_wrap_buffer_initialize (from_server, 1,
4682							     gcontext,
4683							     ((BUFMEMERRPROC)
4684							      NULL));
4685	}
4686	else
4687	    error (1, 0, "Stream authentication is only supported when using GSSAPI");
4688#else /* ! HAVE_GSSAPI */
4689	error (1, 0, "This client does not support stream authentication");
4690#endif /* ! HAVE_GSSAPI */
4691    }
4692
4693    /* If "Set" is not supported, just silently fail to send the variables.
4694       Users with an old server should get a useful error message when it
4695       fails to recognize the ${=foo} syntax.  This way if someone uses
4696       several servers, some of which are new and some old, they can still
4697       set user variables in their .cvsrc without trouble.  */
4698    if (supported_request ("Set"))
4699	walklist (variable_list, send_variable_proc, NULL);
4700}
4701
4702
4703
4704#ifndef NO_EXT_METHOD
4705
4706/* Contact the server by starting it with rsh.  */
4707
4708/* Right now, we have two different definitions for this function,
4709   depending on whether we start the rsh server using popenRW or not.
4710   This isn't ideal, and the best thing would probably be to change
4711   the OS/2 port to be more like the regular Unix client (i.e., by
4712   implementing piped_child)... but I'm doing something else at the
4713   moment, and wish to make only one change at a time.  -Karl */
4714
4715# ifdef START_RSH_WITH_POPEN_RW
4716
4717/* This is actually a crock -- it's OS/2-specific, for no one else
4718   uses it.  If I get time, I want to make piped_child and all the
4719   other stuff in os2/run.c work right.  In the meantime, this gets us
4720   up and running, and that's most important. */
4721
4722static void
4723start_rsh_server (root, to_server, from_server)
4724    cvsroot_t *root;
4725    struct buffer **to_server;
4726    struct buffer **from_server;
4727{
4728    int pipes[2];
4729    int child_pid;
4730
4731    /* If you're working through firewalls, you can set the
4732       CVS_RSH environment variable to a script which uses rsh to
4733       invoke another rsh on a proxy machine.  */
4734    char *env_cvs_rsh = getenv ("CVS_RSH");
4735    char *env_cvs_ssh = getenv ("CVS_SSH");
4736    char *cvs_rsh;
4737    char *cvs_server = getenv ("CVS_SERVER");
4738    int i = 0;
4739    /* This needs to fit "rsh", "-b", "-l", "USER", "host",
4740       "cmd (w/ args)", and NULL.  We leave some room to grow. */
4741    char *rsh_argv[10];
4742
4743    if (root->method == extssh_method)
4744	cvs_rsh = env_cvs_ssh ? env_cvs_ssh : SSH_DFLT;
4745    else
4746	cvs_rsh = env_cvs_rsh ? env_cvs_rsh : RSH_DFLT;
4747
4748    if (!cvs_server)
4749	cvs_server = "cvs";
4750
4751    /* The command line starts out with rsh. */
4752    rsh_argv[i++] = cvs_rsh;
4753
4754#   ifdef RSH_NEEDS_BINARY_FLAG
4755    /* "-b" for binary, under OS/2. */
4756    rsh_argv[i++] = "-b";
4757#   endif /* RSH_NEEDS_BINARY_FLAG */
4758
4759    /* Then we strcat more things on the end one by one. */
4760    if (root->username != NULL)
4761    {
4762	rsh_argv[i++] = "-l";
4763	rsh_argv[i++] = root->username;
4764    }
4765
4766    rsh_argv[i++] = root->hostname;
4767    rsh_argv[i++] = cvs_server;
4768    rsh_argv[i++] = "server";
4769
4770    /* Mark the end of the arg list. */
4771    rsh_argv[i]   = (char *) NULL;
4772
4773    if (trace)
4774    {
4775	fprintf (stderr, " -> Starting server: ");
4776	for (i = 0; rsh_argv[i]; i++)
4777	    fprintf (stderr, "%s ", rsh_argv[i]);
4778	putc ('\n', stderr);
4779    }
4780
4781    /* Do the deed. */
4782    child_pid = popenRW (rsh_argv, pipes);
4783    if (child_pid < 0)
4784	error (1, errno, "cannot start server via rsh");
4785
4786    /* Give caller the file descriptors in a form it can deal with. */
4787    make_bufs_from_fds (pipes[0], pipes[1], child_pid, to_server, from_server, 0);
4788}
4789
4790# else /* ! START_RSH_WITH_POPEN_RW */
4791
4792static void
4793start_rsh_server (root, to_server, from_server)
4794    cvsroot_t *root;
4795    struct buffer **to_server;
4796    struct buffer **from_server;
4797{
4798    /* If you're working through firewalls, you can set the
4799       CVS_RSH environment variable to a script which uses rsh to
4800       invoke another rsh on a proxy machine.  */
4801    char *env_cvs_rsh = getenv ("CVS_RSH");
4802    char *env_cvs_ssh = getenv ("CVS_SSH");
4803    char *cvs_rsh;
4804    char *cvs_server = getenv ("CVS_SERVER");
4805    char *command;
4806    int tofd, fromfd;
4807    int child_pid;
4808
4809    if (root->method == extssh_method)
4810	cvs_rsh = env_cvs_ssh ? env_cvs_ssh : SSH_DFLT;
4811    else
4812	cvs_rsh = env_cvs_rsh ? env_cvs_rsh : RSH_DFLT;
4813
4814    if (!cvs_server)
4815	cvs_server = "cvs";
4816
4817    /* Pass the command to rsh as a single string.  This shouldn't
4818       affect most rsh servers at all, and will pacify some buggy
4819       versions of rsh that grab switches out of the middle of the
4820       command (they're calling the GNU getopt routines incorrectly).  */
4821    command = xmalloc (strlen (cvs_server) + 8);
4822
4823    /* If you are running a very old (Nov 3, 1994, before 1.5)
4824     * version of the server, you need to make sure that your .bashrc
4825     * on the server machine does not set CVSROOT to something
4826     * containing a colon (or better yet, upgrade the server).  */
4827    sprintf (command, "%s server", cvs_server);
4828
4829    {
4830        const char *argv[10];
4831	const char **p = argv;
4832
4833	*p++ = cvs_rsh;
4834
4835	/* If the login names differ between client and server
4836	 * pass it on to rsh.
4837	 */
4838	if (root->username != NULL)
4839	{
4840	    *p++ = "-l";
4841	    *p++ = root->username;
4842	}
4843
4844	*p++ = root->hostname;
4845	*p++ = command;
4846	*p++ = NULL;
4847
4848	if (trace)
4849        {
4850	    int i;
4851
4852            fprintf (stderr, " -> Starting server: ");
4853	    for (i = 0; argv[i]; i++)
4854	        fprintf (stderr, "%s ", argv[i]);
4855	    putc ('\n', stderr);
4856	}
4857	child_pid = piped_child (argv, &tofd, &fromfd, 1);
4858
4859	if (child_pid < 0)
4860	    error (1, errno, "cannot start server via rsh");
4861    }
4862    free (command);
4863
4864    make_bufs_from_fds (tofd, fromfd, child_pid, to_server, from_server, 0);
4865}
4866
4867# endif /* START_RSH_WITH_POPEN_RW */
4868
4869#endif /* NO_EXT_METHOD */
4870
4871
4872
4873/* Send an argument STRING.  */
4874void
4875send_arg (string)
4876    const char *string;
4877{
4878    char buf[1];
4879    const char *p = string;
4880
4881    send_to_server ("Argument ", 0);
4882
4883    while (*p)
4884    {
4885	if (*p == '\n')
4886	{
4887	    send_to_server ("\012Argumentx ", 0);
4888	}
4889	else
4890        {
4891	    buf[0] = *p;
4892	    send_to_server (buf, 1);
4893        }
4894	++p;
4895    }
4896    send_to_server ("\012", 1);
4897}
4898
4899
4900
4901static void send_modified PROTO ((const char *, const char *, Vers_TS *));
4902
4903/* VERS->OPTIONS specifies whether the file is binary or not.  NOTE: BEFORE
4904   using any other fields of the struct vers, we would need to fix
4905   client_process_import_file to set them up.  */
4906
4907static void
4908send_modified (file, short_pathname, vers)
4909    const char *file;
4910    const char *short_pathname;
4911    Vers_TS *vers;
4912{
4913    /* File was modified, send it.  */
4914    struct stat sb;
4915    int fd;
4916    char *buf;
4917    char *mode_string;
4918    size_t bufsize;
4919    int bin;
4920
4921    if (trace)
4922	(void) fprintf (stderr, " -> Sending file `%s' to server\n", file);
4923
4924    /* Don't think we can assume fstat exists.  */
4925    if ( CVS_STAT (file, &sb) < 0)
4926	error (1, errno, "reading %s", short_pathname);
4927
4928    mode_string = mode_to_string (sb.st_mode);
4929
4930    /* Beware: on systems using CRLF line termination conventions,
4931       the read and write functions will convert CRLF to LF, so the
4932       number of characters read is not the same as sb.st_size.  Text
4933       files should always be transmitted using the LF convention, so
4934       we don't want to disable this conversion.  */
4935    bufsize = sb.st_size;
4936    buf = xmalloc (bufsize);
4937
4938    /* Is the file marked as containing binary data by the "-kb" flag?
4939       If so, make sure to open it in binary mode: */
4940
4941    if (vers && vers->options)
4942      bin = !(strcmp (vers->options, "-kb"));
4943    else
4944      bin = 0;
4945
4946#ifdef BROKEN_READWRITE_CONVERSION
4947    if (!bin)
4948    {
4949	/* If only stdio, not open/write/etc., do text/binary
4950	   conversion, use convert_file which can compensate
4951	   (FIXME: we could just use stdio instead which would
4952	   avoid the whole problem).  */
4953	char tfile[1024]; strcpy(tfile, file); strcat(tfile, ".CVSBFCTMP");
4954	convert_file (file, O_RDONLY,
4955		      tfile, O_WRONLY | O_CREAT | O_TRUNC | OPEN_BINARY);
4956	fd = CVS_OPEN (tfile, O_RDONLY | OPEN_BINARY);
4957	if (fd < 0)
4958	    error (1, errno, "reading %s", short_pathname);
4959    }
4960    else
4961	fd = CVS_OPEN (file, O_RDONLY | OPEN_BINARY);
4962#else
4963    fd = CVS_OPEN (file, O_RDONLY | (bin ? OPEN_BINARY : 0));
4964#endif
4965
4966    if (fd < 0)
4967	error (1, errno, "reading %s", short_pathname);
4968
4969    if (file_gzip_level && sb.st_size > 100)
4970    {
4971	size_t newsize = 0;
4972
4973	if (read_and_gzip (fd, short_pathname, (unsigned char **)&buf,
4974			   &bufsize, &newsize,
4975			   file_gzip_level))
4976	    error (1, 0, "aborting due to compression error");
4977
4978	if (close (fd) < 0)
4979	    error (0, errno, "warning: can't close %s", short_pathname);
4980
4981        {
4982          char tmp[80];
4983
4984	  send_to_server ("Modified ", 0);
4985	  send_to_server (file, 0);
4986	  send_to_server ("\012", 1);
4987	  send_to_server (mode_string, 0);
4988	  send_to_server ("\012z", 2);
4989	  sprintf (tmp, "%lu\n", (unsigned long) newsize);
4990	  send_to_server (tmp, 0);
4991
4992          send_to_server (buf, newsize);
4993        }
4994    }
4995    else
4996    {
4997    	int newsize;
4998
4999        {
5000	    char *bufp = buf;
5001	    int len;
5002
5003	    /* FIXME: This is gross.  It assumes that we might read
5004	       less than st_size bytes (true on NT), but not more.
5005	       Instead of this we should just be reading a block of
5006	       data (e.g. 8192 bytes), writing it to the network, and
5007	       so on until EOF.  */
5008	    while ((len = read (fd, bufp, (buf + sb.st_size) - bufp)) > 0)
5009	        bufp += len;
5010
5011	    if (len < 0)
5012	        error (1, errno, "reading %s", short_pathname);
5013
5014	    newsize = bufp - buf;
5015	}
5016	if (close (fd) < 0)
5017	    error (0, errno, "warning: can't close %s", short_pathname);
5018
5019        {
5020          char tmp[80];
5021
5022	  send_to_server ("Modified ", 0);
5023	  send_to_server (file, 0);
5024	  send_to_server ("\012", 1);
5025	  send_to_server (mode_string, 0);
5026	  send_to_server ("\012", 1);
5027          sprintf (tmp, "%lu\012", (unsigned long) newsize);
5028          send_to_server (tmp, 0);
5029        }
5030#ifdef BROKEN_READWRITE_CONVERSION
5031	if (!bin)
5032	{
5033	    char tfile[1024]; strcpy(tfile, file); strcat(tfile, ".CVSBFCTMP");
5034	    if (CVS_UNLINK (tfile) < 0)
5035		error (0, errno, "warning: can't remove temp file %s", tfile);
5036	}
5037#endif
5038
5039	/*
5040	 * Note that this only ends with a newline if the file ended with
5041	 * one.
5042	 */
5043	if (newsize > 0)
5044	    send_to_server (buf, newsize);
5045    }
5046    free (buf);
5047    free (mode_string);
5048}
5049
5050/* The address of an instance of this structure is passed to
5051   send_fileproc, send_filesdoneproc, and send_direntproc, as the
5052   callerdat parameter.  */
5053
5054struct send_data
5055{
5056    /* Each of the following flags are zero for clear or nonzero for set.  */
5057    int build_dirs;
5058    int force;
5059    int no_contents;
5060    int backup_modified;
5061};
5062
5063static int send_fileproc PROTO ((void *callerdat, struct file_info *finfo));
5064
5065/* Deal with one file.  */
5066static int
5067send_fileproc (callerdat, finfo)
5068    void *callerdat;
5069    struct file_info *finfo;
5070{
5071    struct send_data *args = (struct send_data *) callerdat;
5072    Vers_TS *vers;
5073    struct file_info xfinfo;
5074    /* File name to actually use.  Might differ in case from
5075       finfo->file.  */
5076    const char *filename;
5077
5078    send_a_repository ("", finfo->repository, finfo->update_dir);
5079
5080    xfinfo = *finfo;
5081    xfinfo.repository = NULL;
5082    xfinfo.rcs = NULL;
5083    vers = Version_TS (&xfinfo, NULL, NULL, NULL, 0, 0);
5084
5085    if (vers->entdata != NULL)
5086	filename = vers->entdata->user;
5087    else
5088	filename = finfo->file;
5089
5090    if (vers->vn_user != NULL)
5091    {
5092	/* The Entries request.  */
5093	send_to_server ("Entry /", 0);
5094	send_to_server (filename, 0);
5095	send_to_server ("/", 0);
5096	send_to_server (vers->vn_user, 0);
5097	send_to_server ("/", 0);
5098	if (vers->ts_conflict != NULL)
5099	{
5100	    if (vers->ts_user != NULL &&
5101		strcmp (vers->ts_conflict, vers->ts_user) == 0)
5102		send_to_server ("+=", 0);
5103	    else
5104		send_to_server ("+modified", 0);
5105	}
5106	send_to_server ("/", 0);
5107	send_to_server (vers->entdata != NULL
5108			? vers->entdata->options
5109			: vers->options,
5110			0);
5111	send_to_server ("/", 0);
5112	if (vers->entdata != NULL && vers->entdata->tag)
5113	{
5114	    send_to_server ("T", 0);
5115	    send_to_server (vers->entdata->tag, 0);
5116	}
5117	else if (vers->entdata != NULL && vers->entdata->date)
5118          {
5119	    send_to_server ("D", 0);
5120	    send_to_server (vers->entdata->date, 0);
5121          }
5122	send_to_server ("\012", 1);
5123    }
5124    else
5125    {
5126	/* It seems a little silly to re-read this on each file, but
5127	   send_dirent_proc doesn't get called if filenames are specified
5128	   explicitly on the command line.  */
5129	wrap_add_file (CVSDOTWRAPPER, 1);
5130
5131	if (wrap_name_has (filename, WRAP_RCSOPTION))
5132	{
5133	    /* No "Entry", but the wrappers did give us a kopt so we better
5134	       send it with "Kopt".  As far as I know this only happens
5135	       for "cvs add".  Question: is there any reason why checking
5136	       for options from wrappers isn't done in Version_TS?
5137
5138	       Note: it might have been better to just remember all the
5139	       kopts on the client side, rather than send them to the server,
5140	       and have it send us back the same kopts.  But that seemed like
5141	       a bigger change than I had in mind making now.  */
5142
5143	    if (supported_request ("Kopt"))
5144	    {
5145		char *opt;
5146
5147		send_to_server ("Kopt ", 0);
5148		opt = wrap_rcsoption (filename, 1);
5149		send_to_server (opt, 0);
5150		send_to_server ("\012", 1);
5151		free (opt);
5152	    }
5153	    else
5154		error (0, 0,
5155		       "\
5156warning: ignoring -k options due to server limitations");
5157	}
5158    }
5159
5160    if (vers->ts_user == NULL)
5161    {
5162	/*
5163	 * Do we want to print "file was lost" like normal CVS?
5164	 * Would it always be appropriate?
5165	 */
5166	/* File no longer exists.  Don't do anything, missing files
5167	   just happen.  */
5168    }
5169    else if (vers->ts_rcs == NULL
5170	     || args->force
5171	     || strcmp (vers->ts_conflict
5172			&& supported_request ("Empty-conflicts")
5173		        ? vers->ts_conflict : vers->ts_rcs, vers->ts_user)
5174	     || (vers->ts_conflict && !strcmp (cvs_cmd_name, "diff"))
5175	     || (vers->vn_user && *vers->vn_user == '0'))
5176    {
5177	if (args->no_contents
5178	    && supported_request ("Is-modified"))
5179	{
5180	    send_to_server ("Is-modified ", 0);
5181	    send_to_server (filename, 0);
5182	    send_to_server ("\012", 1);
5183	}
5184	else
5185	    send_modified (filename, finfo->fullname, vers);
5186
5187        if (args->backup_modified)
5188        {
5189            char *bakname;
5190            bakname = backup_file (filename, vers->vn_user);
5191            /* This behavior is sufficiently unexpected to
5192               justify overinformativeness, I think. */
5193            if (! really_quiet)
5194                printf ("(Locally modified %s moved to %s)\n",
5195                        filename, bakname);
5196            free (bakname);
5197        }
5198    }
5199    else
5200    {
5201	send_to_server ("Unchanged ", 0);
5202	send_to_server (filename, 0);
5203	send_to_server ("\012", 1);
5204    }
5205
5206    /* if this directory has an ignore list, add this file to it */
5207    if (ignlist)
5208    {
5209	Node *p;
5210
5211	p = getnode ();
5212	p->type = FILES;
5213	p->key = xstrdup (finfo->file);
5214	(void) addnode (ignlist, p);
5215    }
5216
5217    freevers_ts (&vers);
5218    return 0;
5219}
5220
5221
5222
5223static void send_ignproc PROTO ((const char *, const char *));
5224
5225static void
5226send_ignproc (file, dir)
5227    const char *file;
5228    const char *dir;
5229{
5230    if (ign_inhibit_server || !supported_request ("Questionable"))
5231    {
5232	if (dir[0] != '\0')
5233	    (void) printf ("? %s/%s\n", dir, file);
5234	else
5235	    (void) printf ("? %s\n", file);
5236    }
5237    else
5238    {
5239	send_to_server ("Questionable ", 0);
5240	send_to_server (file, 0);
5241	send_to_server ("\012", 1);
5242    }
5243}
5244
5245
5246
5247static int send_filesdoneproc PROTO ((void *, int, const char *, const char *,
5248                                      List *));
5249
5250static int
5251send_filesdoneproc (callerdat, err, repository, update_dir, entries)
5252    void *callerdat;
5253    int err;
5254    const char *repository;
5255    const char *update_dir;
5256    List *entries;
5257{
5258    /* if this directory has an ignore list, process it then free it */
5259    if (ignlist)
5260    {
5261	ignore_files (ignlist, entries, update_dir, send_ignproc);
5262	dellist (&ignlist);
5263    }
5264
5265    return (err);
5266}
5267
5268static Dtype send_dirent_proc PROTO ((void *, const char *, const char *,
5269                                      const char *, List *));
5270
5271/*
5272 * send_dirent_proc () is called back by the recursion processor before a
5273 * sub-directory is processed for update.
5274 * A return code of 0 indicates the directory should be
5275 * processed by the recursion code.  A return of non-zero indicates the
5276 * recursion code should skip this directory.
5277 *
5278 */
5279static Dtype
5280send_dirent_proc (callerdat, dir, repository, update_dir, entries)
5281    void *callerdat;
5282    const char *dir;
5283    const char *repository;
5284    const char *update_dir;
5285    List *entries;
5286{
5287    struct send_data *args = (struct send_data *) callerdat;
5288    int dir_exists;
5289    char *cvsadm_name;
5290
5291    if (ignore_directory (update_dir))
5292    {
5293	/* print the warm fuzzy message */
5294	if (!quiet)
5295	    error (0, 0, "Ignoring %s", update_dir);
5296        return (R_SKIP_ALL);
5297    }
5298
5299    /*
5300     * If the directory does not exist yet (e.g. "cvs update -d foo"),
5301     * no need to send any files from it.  If the directory does not
5302     * have a CVS directory, then we pretend that it does not exist.
5303     * Otherwise, we will fail when trying to open the Entries file.
5304     * This case will happen when checking out a module defined as
5305     * ``-a .''.
5306     */
5307    cvsadm_name = xmalloc (strlen (dir) + sizeof (CVSADM) + 10);
5308    sprintf (cvsadm_name, "%s/%s", dir, CVSADM);
5309    dir_exists = isdir (cvsadm_name);
5310    free (cvsadm_name);
5311
5312    /*
5313     * If there is an empty directory (e.g. we are doing `cvs add' on a
5314     * newly-created directory), the server still needs to know about it.
5315     */
5316
5317    if (dir_exists)
5318    {
5319	/*
5320	 * Get the repository from a CVS/Repository file whenever possible.
5321	 * The repository variable is wrong if the names in the local
5322	 * directory don't match the names in the repository.
5323	 */
5324	char *repos = Name_Repository (dir, update_dir);
5325	send_a_repository (dir, repos, update_dir);
5326	free (repos);
5327
5328	/* initialize the ignore list for this directory */
5329	ignlist = getlist ();
5330    }
5331    else
5332    {
5333	/* It doesn't make sense to send a non-existent directory,
5334	   because there is no way to get the correct value for
5335	   the repository (I suppose maybe via the expand-modules
5336	   request).  In the case where the "obvious" choice for
5337	   repository is correct, the server can figure out whether
5338	   to recreate the directory; in the case where it is wrong
5339	   (that is, does not match what modules give us), we might as
5340	   well just fail to recreate it.
5341
5342	   Checking for noexec is a kludge for "cvs -n add dir".  */
5343	/* Don't send a non-existent directory unless we are building
5344           new directories (build_dirs is true).  Otherwise, CVS may
5345           see a D line in an Entries file, and recreate a directory
5346           which the user removed by hand.  */
5347	if (args->build_dirs && noexec)
5348	    send_a_repository (dir, repository, update_dir);
5349    }
5350
5351    return (dir_exists ? R_PROCESS : R_SKIP_ALL);
5352}
5353
5354
5355
5356static int send_dirleave_proc PROTO ((void *, const char *, int, const char *,
5357                                      List *));
5358
5359/*
5360 * send_dirleave_proc () is called back by the recursion code upon leaving
5361 * a directory.  All it does is delete the ignore list if it hasn't already
5362 * been done (by send_filesdone_proc).
5363 */
5364/* ARGSUSED */
5365static int
5366send_dirleave_proc (callerdat, dir, err, update_dir, entries)
5367    void *callerdat;
5368    const char *dir;
5369    int err;
5370    const char *update_dir;
5371    List *entries;
5372{
5373
5374    /* Delete the ignore list if it hasn't already been done.  */
5375    if (ignlist)
5376	dellist (&ignlist);
5377    return err;
5378}
5379
5380/*
5381 * Send each option in an array to the server, one by one.
5382 * argv might be "--foo=bar",  "-C", "5", "-y".
5383 */
5384void
5385send_options (int argc, char *const *argv)
5386{
5387    int i;
5388    for (i = 0; i < argc; i++)
5389	send_arg (argv[i]);
5390}
5391
5392
5393
5394/* Send the names of all the argument files to the server.  */
5395void
5396send_file_names (argc, argv, flags)
5397    int argc;
5398    char **argv;
5399    unsigned int flags;
5400{
5401    int i;
5402    
5403    /* The fact that we do this here as well as start_recursion is a bit 
5404       of a performance hit.  Perhaps worth cleaning up someday.  */
5405    if (flags & SEND_EXPAND_WILD)
5406	expand_wild (argc, argv, &argc, &argv);
5407
5408    for (i = 0; i < argc; ++i)
5409    {
5410	char buf[1];
5411	char *p;
5412#ifdef FILENAMES_CASE_INSENSITIVE
5413	char *line = xmalloc (1);
5414	*line = '\0';
5415#endif /* FILENAMES_CASE_INSENSITIVE */
5416
5417	if (arg_should_not_be_sent_to_server (argv[i]))
5418	    continue;
5419
5420#ifdef FILENAMES_CASE_INSENSITIVE
5421	/* We want to send the path as it appears in the
5422	   CVS/Entries files.  We put this inside an ifdef
5423	   to avoid doing all these system calls in
5424	   cases where fncmp is just strcmp anyway.  */
5425	/* The isdir (CVSADM) check could more gracefully be replaced
5426	   with a way of having Entries_Open report back the
5427	   error to us and letting us ignore existence_error.
5428	   Or some such.  */
5429	{
5430	    List *stack;
5431	    size_t line_len = 0;
5432	    char *q, *r;
5433	    struct saved_cwd sdir;
5434
5435	    /* Split the argument onto the stack.  */
5436	    stack = getlist();
5437	    r = xstrdup (argv[i]);
5438            /* It's okay to discard the const from the last_component return
5439             * below since we know we passed in an arg that was not const.
5440             */
5441	    while ((q = (char *)last_component (r)) != r)
5442	    {
5443		push (stack, xstrdup (q));
5444		*--q = '\0';
5445	    }
5446	    push (stack, r);
5447
5448	    /* Normalize the path into outstr. */
5449	    save_cwd (&sdir);
5450	    while (q = pop (stack))
5451	    {
5452		Node *node = NULL;
5453	        if (isdir (CVSADM))
5454		{
5455		    List *entries;
5456
5457		    /* Note that if we are adding a directory,
5458		       the following will read the entry
5459		       that we just wrote there, that is, we
5460		       will get the case specified on the
5461		       command line, not the case of the
5462		       directory in the filesystem.  This
5463		       is correct behavior.  */
5464		    entries = Entries_Open (0, NULL);
5465		    node = findnode_fn (entries, q);
5466		    if (node != NULL)
5467		    {
5468			/* Add the slash unless this is our first element. */
5469			if (line_len)
5470			    xrealloc_and_strcat (&line, &line_len, "/");
5471			xrealloc_and_strcat (&line, &line_len, node->key);
5472			delnode (node);
5473		    }
5474		    Entries_Close (entries);
5475		}
5476
5477		/* If node is still NULL then we either didn't find CVSADM or
5478		 * we didn't find an entry there.
5479		 */
5480		if (node == NULL)
5481		{
5482		    /* Add the slash unless this is our first element. */
5483		    if (line_len)
5484			xrealloc_and_strcat (&line, &line_len, "/");
5485		    xrealloc_and_strcat (&line, &line_len, q);
5486		    break;
5487		}
5488
5489		/* And descend the tree. */
5490		if (isdir (q))
5491		    CVS_CHDIR (q);
5492		free (q);
5493	    }
5494	    restore_cwd (&sdir, NULL);
5495	    free_cwd (&sdir);
5496
5497	    /* Now put everything we didn't find entries for back on. */
5498	    while (q = pop (stack))
5499	    {
5500		if (line_len)
5501		    xrealloc_and_strcat (&line, &line_len, "/");
5502		xrealloc_and_strcat (&line, &line_len, q);
5503		free (q);
5504	    }
5505
5506	    p = line;
5507
5508	    dellist (&stack);
5509	}
5510#else /* !FILENAMES_CASE_INSENSITIVE */
5511	p = argv[i];
5512#endif /* FILENAMES_CASE_INSENSITIVE */
5513
5514	send_to_server ("Argument ", 0);
5515
5516	while (*p)
5517	{
5518	    if (*p == '\n')
5519	    {
5520		send_to_server ("\012Argumentx ", 0);
5521	    }
5522	    else if (ISDIRSEP (*p))
5523	    {
5524		buf[0] = '/';
5525		send_to_server (buf, 1);
5526	    }
5527	    else
5528	    {
5529		buf[0] = *p;
5530		send_to_server (buf, 1);
5531	    }
5532	    ++p;
5533	}
5534	send_to_server ("\012", 1);
5535#ifdef FILENAMES_CASE_INSENSITIVE
5536	free (line);
5537#endif /* FILENAMES_CASE_INSENSITIVE */
5538    }
5539
5540    if (flags & SEND_EXPAND_WILD)
5541    {
5542	int i;
5543	for (i = 0; i < argc; ++i)
5544	    free (argv[i]);
5545	free (argv);
5546    }
5547}
5548
5549
5550
5551/* Calculate and send max-dotdot to the server */
5552static void
5553send_max_dotdot (argc, argv)
5554    int argc;
5555    char **argv;
5556{
5557    int i;
5558    int level = 0;
5559    int max_level = 0;
5560
5561    /* Send Max-dotdot if needed.  */
5562    for (i = 0; i < argc; ++i)
5563    {
5564        level = pathname_levels (argv[i]);
5565	if (level > 0)
5566	{
5567            if (uppaths == NULL) uppaths = getlist();
5568	    push_string (uppaths, xstrdup (argv[i]));
5569	}
5570        if (level > max_level)
5571            max_level = level;
5572    }
5573
5574    if (max_level > 0)
5575    {
5576        if (supported_request ("Max-dotdot"))
5577        {
5578            char buf[10];
5579            sprintf (buf, "%d", max_level);
5580
5581            send_to_server ("Max-dotdot ", 0);
5582            send_to_server (buf, 0);
5583            send_to_server ("\012", 1);
5584        }
5585        else
5586        {
5587            error (1, 0,
5588"backreference in path (`..') not supported by old (pre-Max-dotdot) servers");
5589        }
5590    }
5591}
5592
5593
5594
5595/* Send Repository, Modified and Entry.  argc and argv contain only
5596  the files to operate on (or empty for everything), not options.
5597  local is nonzero if we should not recurse (-l option).  flags &
5598  SEND_BUILD_DIRS is nonzero if nonexistent directories should be
5599  sent.  flags & SEND_FORCE is nonzero if we should send unmodified
5600  files to the server as though they were modified.  flags &
5601  SEND_NO_CONTENTS means that this command only needs to know
5602  _whether_ a file is modified, not the contents.  Also sends Argument
5603  lines for argc and argv, so should be called after options are sent.  */
5604void
5605send_files (argc, argv, local, aflag, flags)
5606    int argc;
5607    char **argv;
5608    int local;
5609    int aflag;
5610    unsigned int flags;
5611{
5612    struct send_data args;
5613    int err;
5614
5615    send_max_dotdot (argc, argv);
5616
5617    /*
5618     * aflag controls whether the tag/date is copied into the vers_ts.
5619     * But we don't actually use it, so I don't think it matters what we pass
5620     * for aflag here.
5621     */
5622    args.build_dirs = flags & SEND_BUILD_DIRS;
5623    args.force = flags & SEND_FORCE;
5624    args.no_contents = flags & SEND_NO_CONTENTS;
5625    args.backup_modified = flags & BACKUP_MODIFIED_FILES;
5626    err = start_recursion
5627	(send_fileproc, send_filesdoneproc,
5628	 send_dirent_proc, send_dirleave_proc, (void *) &args,
5629	 argc, argv, local, W_LOCAL, aflag, CVS_LOCK_NONE, (char *) NULL, 0,
5630	 (char *) NULL);
5631    if (err)
5632	error_exit ();
5633    if (toplevel_repos == NULL)
5634	/*
5635	 * This happens if we are not processing any files,
5636	 * or for checkouts in directories without any existing stuff
5637	 * checked out.  The following assignment is correct for the
5638	 * latter case; I don't think toplevel_repos matters for the
5639	 * former.
5640	 */
5641	toplevel_repos = xstrdup (current_parsed_root->directory);
5642    send_repository ("", toplevel_repos, ".");
5643}
5644
5645void
5646client_import_setup (repository)
5647    char *repository;
5648{
5649    if (toplevel_repos == NULL)		/* should always be true */
5650        send_a_repository ("", repository, "");
5651}
5652
5653/*
5654 * Process the argument import file.
5655 */
5656int
5657client_process_import_file (message, vfile, vtag, targc, targv, repository,
5658                            all_files_binary, modtime)
5659    char *message;
5660    char *vfile;
5661    char *vtag;
5662    int targc;
5663    char *targv[];
5664    char *repository;
5665    int all_files_binary;
5666
5667    /* Nonzero for "import -d".  */
5668    int modtime;
5669{
5670    char *update_dir;
5671    char *fullname;
5672    Vers_TS vers;
5673
5674    assert (toplevel_repos != NULL);
5675
5676    if (strncmp (repository, toplevel_repos, strlen (toplevel_repos)) != 0)
5677	error (1, 0,
5678	       "internal error: pathname `%s' doesn't specify file in `%s'",
5679	       repository, toplevel_repos);
5680
5681    if (strcmp (repository, toplevel_repos) == 0)
5682    {
5683	update_dir = "";
5684	fullname = xstrdup (vfile);
5685    }
5686    else
5687    {
5688	update_dir = repository + strlen (toplevel_repos) + 1;
5689
5690	fullname = xmalloc (strlen (vfile) + strlen (update_dir) + 10);
5691	strcpy (fullname, update_dir);
5692	strcat (fullname, "/");
5693	strcat (fullname, vfile);
5694    }
5695
5696    send_a_repository ("", repository, update_dir);
5697    if (all_files_binary)
5698    {
5699	vers.options = xmalloc (4); /* strlen("-kb") + 1 */
5700	strcpy (vers.options, "-kb");
5701    }
5702    else
5703    {
5704	vers.options = wrap_rcsoption (vfile, 1);
5705    }
5706    if (vers.options != NULL)
5707    {
5708	if (supported_request ("Kopt"))
5709	{
5710	    send_to_server ("Kopt ", 0);
5711	    send_to_server (vers.options, 0);
5712	    send_to_server ("\012", 1);
5713	}
5714	else
5715	    error (0, 0,
5716		   "warning: ignoring -k options due to server limitations");
5717    }
5718    if (modtime)
5719    {
5720	if (supported_request ("Checkin-time"))
5721	{
5722	    struct stat sb;
5723	    char *rcsdate;
5724	    char netdate[MAXDATELEN];
5725
5726	    if (CVS_STAT (vfile, &sb) < 0)
5727		error (1, errno, "cannot stat %s", fullname);
5728	    rcsdate = date_from_time_t (sb.st_mtime);
5729	    date_to_internet (netdate, rcsdate);
5730	    free (rcsdate);
5731
5732	    send_to_server ("Checkin-time ", 0);
5733	    send_to_server (netdate, 0);
5734	    send_to_server ("\012", 1);
5735	}
5736	else
5737	    error (0, 0,
5738		   "warning: ignoring -d option due to server limitations");
5739    }
5740    send_modified (vfile, fullname, &vers);
5741    if (vers.options != NULL)
5742	free (vers.options);
5743    free (fullname);
5744    return 0;
5745}
5746
5747void
5748client_import_done ()
5749{
5750    if (toplevel_repos == NULL)
5751	/*
5752	 * This happens if we are not processing any files,
5753	 * or for checkouts in directories without any existing stuff
5754	 * checked out.  The following assignment is correct for the
5755	 * latter case; I don't think toplevel_repos matters for the
5756	 * former.
5757	 */
5758        /* FIXME: "can't happen" now that we call client_import_setup
5759	   at the beginning.  */
5760	toplevel_repos = xstrdup (current_parsed_root->directory);
5761    send_repository ("", toplevel_repos, ".");
5762}
5763
5764
5765
5766static void
5767notified_a_file (data, ent_list, short_pathname, filename)
5768    char *data;
5769    List *ent_list;
5770    char *short_pathname;
5771    char *filename;
5772{
5773    FILE *fp;
5774    FILE *newf;
5775    size_t line_len = 8192;
5776    char *line = xmalloc (line_len);
5777    char *cp;
5778    int nread;
5779    int nwritten;
5780    char *p;
5781
5782    fp = open_file (CVSADM_NOTIFY, "r");
5783    if (getline (&line, &line_len, fp) < 0)
5784    {
5785	if (feof (fp))
5786	    error (0, 0, "cannot read %s: end of file", CVSADM_NOTIFY);
5787	else
5788	    error (0, errno, "cannot read %s", CVSADM_NOTIFY);
5789	goto error_exit;
5790    }
5791    cp = strchr (line, '\t');
5792    if (cp == NULL)
5793    {
5794	error (0, 0, "malformed %s file", CVSADM_NOTIFY);
5795	goto error_exit;
5796    }
5797    *cp = '\0';
5798    if (strcmp (filename, line + 1) != 0)
5799    {
5800	error (0, 0, "protocol error: notified %s, expected %s", filename,
5801	       line + 1);
5802    }
5803
5804    if (getline (&line, &line_len, fp) < 0)
5805    {
5806	if (feof (fp))
5807	{
5808	    free (line);
5809	    if (fclose (fp) < 0)
5810		error (0, errno, "cannot close %s", CVSADM_NOTIFY);
5811	    if ( CVS_UNLINK (CVSADM_NOTIFY) < 0)
5812		error (0, errno, "cannot remove %s", CVSADM_NOTIFY);
5813	    return;
5814	}
5815	else
5816	{
5817	    error (0, errno, "cannot read %s", CVSADM_NOTIFY);
5818	    goto error_exit;
5819	}
5820    }
5821    newf = open_file (CVSADM_NOTIFYTMP, "w");
5822    if (fputs (line, newf) < 0)
5823    {
5824	error (0, errno, "cannot write %s", CVSADM_NOTIFYTMP);
5825	goto error2;
5826    }
5827    while ((nread = fread (line, 1, line_len, fp)) > 0)
5828    {
5829	p = line;
5830	while ((nwritten = fwrite (p, 1, nread, newf)) > 0)
5831	{
5832	    nread -= nwritten;
5833	    p += nwritten;
5834	}
5835	if (ferror (newf))
5836	{
5837	    error (0, errno, "cannot write %s", CVSADM_NOTIFYTMP);
5838	    goto error2;
5839	}
5840    }
5841    if (ferror (fp))
5842    {
5843	error (0, errno, "cannot read %s", CVSADM_NOTIFY);
5844	goto error2;
5845    }
5846    if (fclose (newf) < 0)
5847    {
5848	error (0, errno, "cannot close %s", CVSADM_NOTIFYTMP);
5849	goto error_exit;
5850    }
5851    free (line);
5852    if (fclose (fp) < 0)
5853    {
5854	error (0, errno, "cannot close %s", CVSADM_NOTIFY);
5855	return;
5856    }
5857
5858    {
5859        /* In this case, we want rename_file() to ignore noexec. */
5860        int saved_noexec = noexec;
5861        noexec = 0;
5862        rename_file (CVSADM_NOTIFYTMP, CVSADM_NOTIFY);
5863        noexec = saved_noexec;
5864    }
5865
5866    return;
5867  error2:
5868    (void) fclose (newf);
5869  error_exit:
5870    free (line);
5871    (void) fclose (fp);
5872}
5873
5874static void
5875handle_notified (args, len)
5876    char *args;
5877    int len;
5878{
5879    call_in_directory (args, notified_a_file, NULL);
5880}
5881
5882void
5883client_notify (repository, update_dir, filename, notif_type, val)
5884    const char *repository;
5885    const char *update_dir;
5886    const char *filename;
5887    int notif_type;
5888    const char *val;
5889{
5890    char buf[2];
5891
5892    send_a_repository ("", repository, update_dir);
5893    send_to_server ("Notify ", 0);
5894    send_to_server (filename, 0);
5895    send_to_server ("\012", 1);
5896    buf[0] = notif_type;
5897    buf[1] = '\0';
5898    send_to_server (buf, 1);
5899    send_to_server ("\t", 1);
5900    send_to_server (val, 0);
5901}
5902
5903/*
5904 * Send an option with an argument, dealing correctly with newlines in
5905 * the argument.  If ARG is NULL, forget the whole thing.
5906 */
5907void
5908option_with_arg (option, arg)
5909    char *option;
5910    char *arg;
5911{
5912    if (arg == NULL)
5913	return;
5914
5915    send_to_server ("Argument ", 0);
5916    send_to_server (option, 0);
5917    send_to_server ("\012", 1);
5918
5919    send_arg (arg);
5920}
5921
5922/* Send a date to the server.  The input DATE is in RCS format.
5923   The time will be GMT.
5924
5925   We then convert that to the format required in the protocol
5926   (including the "-D" option) and send it.  According to
5927   cvsclient.texi, RFC 822/1123 format is preferred.  */
5928
5929void
5930client_senddate (date)
5931    const char *date;
5932{
5933    char buf[MAXDATELEN];
5934
5935    date_to_internet (buf, (char *)date);
5936    option_with_arg ("-D", buf);
5937}
5938
5939void
5940send_init_command ()
5941{
5942    /* This is here because we need the current_parsed_root->directory variable.  */
5943    send_to_server ("init ", 0);
5944    send_to_server (current_parsed_root->directory, 0);
5945    send_to_server ("\012", 0);
5946}
5947
5948#endif /* CLIENT_SUPPORT */