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