"Fossies" - the Fresh Open Source Software Archive

Member "cvs-1.11.23/src/client.c" (7 May 2008, 159883 Bytes) of package /linux/misc/old/cvs-1.11.23.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "client.c" see the Fossies "Dox" file reference documentation.

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