sync from MirBSD
[alioth/cvs.git] / src / client.c
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 "cvs.h"
18 #include "getline.h"
19 #include "edit.h"
20 #include "buffer.h"
21 #include "save-cwd.h"
22
23 __RCSID("$MirOS: src/gnu/usr.bin/cvs/src/client.c,v 1.10 2017/11/18 22:15:52 tg Exp $");
24
25 #ifdef CLIENT_SUPPORT
26
27 # include "log-buffer.h"
28 # include "md5.h"
29
30 #include "socket-client.h"
31 #include "rsh-client.h"
32
33 # ifdef HAVE_GSSAPI
34 #   include "gssapi-client.h"
35 # endif
36
37 # ifdef HAVE_KERBEROS
38 #   include "kerberos4-client.h"
39 # endif
40
41
42
43 /* Keep track of any paths we are sending for Max-dotdot so that we can verify
44  * that uplevel paths coming back form the server are valid.
45  *
46  * FIXME: The correct way to do this is probably provide some sort of virtual
47  * path map on the client side.  This would be generic enough to be applied to
48  * absolute paths supplied by the user too.
49  */
50 static List *uppaths;
51
52
53
54 static void add_prune_candidate (const char *);
55
56 /* All the commands.  */
57 int add (int argc, char **argv);
58 int admin (int argc, char **argv);
59 int checkout (int argc, char **argv);
60 int commit (int argc, char **argv);
61 int diff (int argc, char **argv);
62 int history (int argc, char **argv);
63 int import (int argc, char **argv);
64 int cvslog (int argc, char **argv);
65 int patch (int argc, char **argv);
66 int release (int argc, char **argv);
67 int cvsremove (int argc, char **argv);
68 int rtag (int argc, char **argv);
69 int status (int argc, char **argv);
70 int tag (int argc, char **argv);
71 int update (int argc, char **argv);
72
73 static size_t try_read_from_server (char *, size_t);
74
75 static void auth_server (cvsroot_t *, struct buffer *, struct buffer *,
76                          int, int, struct hostent *);
77
78
79
80 /* This is the referrer who referred us to a primary, or write server, using
81  * the "Redirect" request.
82  */
83 static cvsroot_t *client_referrer;
84
85 /* We need to keep track of the list of directories we've sent to the
86    server.  This list, along with the current CVSROOT, will help us
87    decide which command-line arguments to send.  */
88 List *dirs_sent_to_server;
89 static int
90 is_arg_a_parent_or_listed_dir (Node *n, void *d)
91 {
92     char *directory = n->key;   /* name of the dir sent to server */
93     char *this_argv_elem = d;   /* this argv element */
94
95     /* Say we should send this argument if the argument matches the
96        beginning of a directory name sent to the server.  This way,
97        the server will know to start at the top of that directory
98        hierarchy and descend. */
99
100     if (!strncmp (directory, this_argv_elem, strlen (this_argv_elem)))
101         return 1;
102
103     return 0;
104 }
105
106
107
108 /* Return nonzero if this argument should not be sent to the
109    server. */
110 static int
111 arg_should_not_be_sent_to_server (char *arg)
112 {
113     /* Decide if we should send this directory name to the server.  We
114        should always send argv[i] if:
115
116        1) the list of directories sent to the server is empty (as it
117        will be for checkout, etc.).
118
119        2) the argument is "."
120
121        3) the argument is a file in the cwd and the cwd is checked out
122        from the current root
123
124        4) the argument lies within one of the paths in
125        dirs_sent_to_server.
126
127        */
128
129     if (list_isempty (dirs_sent_to_server))
130         return 0;               /* always send it */
131
132     if (!strcmp (arg, "."))
133         return 0;               /* always send it */
134
135     /* We should send arg if it is one of the directories sent to the
136        server or the parent of one; this tells the server to descend
137        the hierarchy starting at this level. */
138     if (isdir (arg))
139     {
140         if (walklist (dirs_sent_to_server, is_arg_a_parent_or_listed_dir, arg))
141             return 0;
142
143         /* If arg wasn't a parent, we don't know anything about it (we
144            would have seen something related to it during the
145            send_files phase).  Don't send it.  */
146         return 1;
147     }
148
149     /* Try to decide whether we should send arg to the server by
150        checking the contents of the corresponding CVSADM directory. */
151     {
152         char *t, *root_string;
153         cvsroot_t *this_root = NULL;
154
155         /* Calculate "dirname arg" */
156         for (t = arg + strlen (arg) - 1; t >= arg; t--)
157         {
158             if (ISSLASH (*t))
159                 break;
160         }
161
162         /* Now we're either poiting to the beginning of the
163            string, or we found a path separator. */
164         if (t >= arg)
165         {
166             /* Found a path separator.  */
167             char c = *t;
168             *t = '\0';
169             
170             /* First, check to see if we sent this directory to the
171                server, because it takes less time than actually
172                opening the stuff in the CVSADM directory.  */
173             if (walklist (dirs_sent_to_server, is_arg_a_parent_or_listed_dir,
174                           arg))
175             {
176                 *t = c;         /* make sure to un-truncate the arg */
177                 return 0;
178             }
179
180             /* Since we didn't find it in the list, check the CVSADM
181                files on disk.  */
182             this_root = Name_Root (arg, NULL);
183             root_string = this_root->original;
184             *t = c;
185         }
186         else
187         {
188             /* We're at the beginning of the string.  Look at the
189                CVSADM files in cwd.  */
190             if (CVSroot_cmdline)
191                 root_string = CVSroot_cmdline;
192             else
193             {
194                 this_root = Name_Root (NULL, NULL);
195                 root_string = this_root->original;
196             }
197         }
198
199         /* Now check the value for root. */
200         if (root_string && current_parsed_root
201             && strcmp (root_string, original_parsed_root->original))
202         {
203             /* Don't send this, since the CVSROOTs don't match. */
204             return 1;
205         }
206     }
207     
208     /* OK, let's send it. */
209     return 0;
210 }
211 #endif /* CLIENT_SUPPORT */
212
213
214
215 #if defined(CLIENT_SUPPORT) || defined(SERVER_SUPPORT)
216
217 /* Shared with server.  */
218
219 /*
220  * Return a malloc'd, '\0'-terminated string
221  * corresponding to the mode in SB.
222  */
223 char *
224 mode_to_string (mode_t mode)
225 {
226     char u[4], g[4], o[4];
227     int i;
228
229     i = 0;
230     if (mode & S_IRUSR) u[i++] = 'r';
231     if (mode & S_IWUSR) u[i++] = 'w';
232     if (mode & S_IXUSR) u[i++] = 'x';
233     u[i] = '\0';
234
235     i = 0;
236     if (mode & S_IRGRP) g[i++] = 'r';
237     if (mode & S_IWGRP) g[i++] = 'w';
238     if (mode & S_IXGRP) g[i++] = 'x';
239     g[i] = '\0';
240
241     i = 0;
242     if (mode & S_IROTH) o[i++] = 'r';
243     if (mode & S_IWOTH) o[i++] = 'w';
244     if (mode & S_IXOTH) o[i++] = 'x';
245     o[i] = '\0';
246
247     return Xasprintf ("u=%s,g=%s,o=%s", u, g, o);
248 }
249
250
251
252 /*
253  * Change mode of FILENAME to MODE_STRING.
254  * Returns 0 for success or errno code.
255  * If RESPECT_UMASK is set, then honor the umask.
256  */
257 int
258 change_mode (const char *filename, const char *mode_string, int respect_umask)
259 {
260 #ifdef CHMOD_BROKEN
261     char *p;
262     int writeable = 0;
263
264     /* We can only distinguish between
265          1) readable
266          2) writeable
267          3) Picasso's "Blue Period"
268        We handle the first two. */
269     p = mode_string;
270     while (*p != '\0')
271     {
272         if ((p[0] == 'u' || p[0] == 'g' || p[0] == 'o') && p[1] == '=')
273         {
274             char *q = p + 2;
275             while (*q != ',' && *q != '\0')
276             {
277                 if (*q == 'w')
278                     writeable = 1;
279                 ++q;
280             }
281         }
282         /* Skip to the next field.  */
283         while (*p != ',' && *p != '\0')
284             ++p;
285         if (*p == ',')
286             ++p;
287     }
288
289     /* xchmod honors the umask for us.  In the !respect_umask case, we
290        don't try to cope with it (probably to handle that well, the server
291        needs to deal with modes in data structures, rather than via the
292        modes in temporary files).  */
293     xchmod (filename, writeable);
294         return 0;
295
296 #else /* ! CHMOD_BROKEN */
297
298     const char *p;
299     mode_t mode = 0;
300     mode_t oumask;
301
302     p = mode_string;
303     while (*p != '\0')
304     {
305         if ((p[0] == 'u' || p[0] == 'g' || p[0] == 'o') && p[1] == '=')
306         {
307             int can_read = 0, can_write = 0, can_execute = 0;
308             const char *q = p + 2;
309             while (*q != ',' && *q != '\0')
310             {
311                 if (*q == 'r')
312                     can_read = 1;
313                 else if (*q == 'w')
314                     can_write = 1;
315                 else if (*q == 'x')
316                     can_execute = 1;
317                 ++q;
318             }
319             if (p[0] == 'u')
320             {
321                 if (can_read)
322                     mode |= S_IRUSR;
323                 if (can_write)
324                     mode |= S_IWUSR;
325                 if (can_execute)
326                     mode |= S_IXUSR;
327             }
328             else if (p[0] == 'g')
329             {
330                 if (can_read)
331                     mode |= S_IRGRP;
332                 if (can_write)
333                     mode |= S_IWGRP;
334                 if (can_execute)
335                     mode |= S_IXGRP;
336             }
337             else if (p[0] == 'o')
338             {
339                 if (can_read)
340                     mode |= S_IROTH;
341                 if (can_write)
342                     mode |= S_IWOTH;
343                 if (can_execute)
344                     mode |= S_IXOTH;
345             }
346         }
347         /* Skip to the next field.  */
348         while (*p != ',' && *p != '\0')
349             ++p;
350         if (*p == ',')
351             ++p;
352     }
353
354     if (respect_umask)
355     {
356         oumask = umask (0);
357         (void) umask (oumask);
358         mode &= ~oumask;
359     }
360
361     if (chmod (filename, mode) < 0)
362         return errno;
363     return 0;
364 #endif /* ! CHMOD_BROKEN */
365 }
366 #endif /* CLIENT_SUPPORT or SERVER_SUPPORT */
367
368
369
370 #ifdef CLIENT_SUPPORT
371 int client_prune_dirs;
372
373 static List *ignlist = NULL;
374
375 /* Buffer to write to the server.  */
376 static struct buffer *global_to_server;
377
378 /* Buffer used to read from the server.  */
379 static struct buffer *global_from_server;
380
381
382
383 /*
384  * Read a line from the server.  Result does not include the terminating \n.
385  *
386  * Space for the result is malloc'd and should be freed by the caller.
387  *
388  * Returns number of bytes read.
389  */
390 static size_t
391 read_line_via (struct buffer *via_from_buffer, struct buffer *via_to_buffer,
392                char **resultp)
393 {
394     int status;
395     char *result;
396     size_t len;
397
398     status = buf_flush (via_to_buffer, 1);
399     if (status != 0)
400         error (1, status, "writing to server");
401
402     status = buf_read_line (via_from_buffer, &result, &len);
403     if (status != 0)
404     {
405         if (status == -1)
406             error (1, 0,
407                    "end of file from server (consult above messages if any)");
408         else if (status == -2)
409             error (1, 0, "out of memory");
410         else
411             error (1, status, "reading from server");
412     }
413
414     if (resultp)
415         *resultp = result;
416     else
417         free (result);
418
419     return len;
420 }
421
422
423
424 static size_t
425 read_line (char **resultp)
426 {
427   return read_line_via (global_from_server, global_to_server, resultp);
428 }
429 #endif /* CLIENT_SUPPORT */
430
431
432
433 #if defined(CLIENT_SUPPORT) || defined(SERVER_SUPPORT)
434 /*
435  * Zero if compression isn't supported or requested; non-zero to indicate
436  * a compression level to request from gzip.
437  */
438 int gzip_level;
439
440 /*
441  * Level of compression to use when running gzip on a single file.
442  */
443 int file_gzip_level;
444
445 #endif /* CLIENT_SUPPORT or SERVER_SUPPORT */
446 \f
447 #ifdef CLIENT_SUPPORT
448
449 /* Whether the server asked us to force compression.  */
450 static bool force_gzip;
451
452 /*
453  * The Repository for the top level of this command (not necessarily
454  * the CVSROOT, just the current directory at the time we do it).
455  */
456 static char *toplevel_repos;
457
458 /* Working directory when we first started.  Note: we could speed things
459    up on some systems by using savecwd.h here instead of just always
460    storing a name.  */
461 char *toplevel_wd;
462
463
464
465 static void
466 handle_ok (char *args, size_t len)
467 {
468     return;
469 }
470
471
472
473 static void
474 handle_error (char *args, size_t len)
475 {
476     int something_printed;
477     
478     /*
479      * First there is a symbolic error code followed by a space, which
480      * we ignore.
481      */
482     char *p = strchr (args, ' ');
483     if (!p)
484     {
485         error (0, 0, "invalid data from cvs server");
486         return;
487     }
488     ++p;
489
490     /* Next we print the text of the message from the server.  We
491        probably should be prefixing it with "server error" or some
492        such, because if it is something like "Out of memory", the
493        current behavior doesn't say which machine is out of
494        memory.  */
495
496     len -= p - args;
497     something_printed = 0;
498     for (; len > 0; --len)
499     {
500         something_printed = 1;
501         putc (*p++, stderr);
502     }
503     if (something_printed)
504         putc ('\n', stderr);
505 }
506
507
508
509 static void
510 handle_valid_requests (char *args, size_t len)
511 {
512     char *p = args;
513     char *q;
514     struct request *rq;
515     do
516     {
517         q = strchr (p, ' ');
518         if (q)
519             *q++ = '\0';
520         for (rq = requests; rq->name; ++rq)
521         {
522             if (!strcmp (rq->name, p))
523                 break;
524         }
525         if (!rq->name)
526             /*
527              * It is a request we have never heard of (and thus never
528              * will want to use).  So don't worry about it.
529              */
530             ;
531         else
532         {
533             if (rq->flags & RQ_ENABLEME)
534             {
535                 /*
536                  * Server wants to know if we have this, to enable the
537                  * feature.
538                  */
539                 send_to_server (rq->name, 0);
540                 send_to_server ("\012", 0);
541             }
542             else
543                 rq->flags |= RQ_SUPPORTED;
544         }
545         p = q;
546     } while (q);
547     for (rq = requests; rq->name; ++rq)
548     {
549         if ((rq->flags & RQ_SUPPORTED)
550             || (rq->flags & RQ_ENABLEME))
551             continue;
552         if (rq->flags & RQ_ESSENTIAL)
553             error (1, 0, "request `%s' not supported by server", rq->name);
554     }
555 }
556
557 static void
558 handle_force_gzip (char *args, size_t len)
559 {
560     force_gzip = true;
561 }
562
563
564
565 /* Has the server told us its name since the last redirect?
566  */
567 static bool referred_since_last_redirect = false;
568 static bool free_client_referrer = false;
569
570
571
572 static void
573 handle_referrer (char *args, size_t len)
574 {
575     TRACE (TRACE_FUNCTION, "handle_referrer (%s)", args);
576     client_referrer = parse_cvsroot (args);
577     referred_since_last_redirect = true;
578     free_client_referrer = true;
579 }
580
581
582
583 /* Redirect our connection to a different server and start over.
584  *
585  * GLOBALS
586  *   current_parsed_root        The CVSROOT being accessed.
587  *   client_referrer            Used to track the server which referred us to a
588  *                              new server.  Can be supplied by the referring
589  *                              server.
590  *   free_client_referrer       Used to track whether the client_referrer needs
591  *                              to be freed before changing it.
592  *   referred_since_last_redirect       
593  *                              Tracks whether the currect server told us how
594  *                              to refer to it.
595  *
596  * OUTPUTS
597  *   current_parsed_root        Updated to point to the new CVSROOT.
598  *   referred_since_last_redirect
599  *                              Always cleared.
600  *   client_referrer            Set automatically to current_parsed_root if
601  *                              the current server did not give us a name to
602  *                              refer to it by.
603  *   free_client_referrer       Reset when necessary.
604  */
605 static void
606 handle_redirect (char *args, size_t len)
607 {
608     static List *redirects = NULL;
609
610     TRACE (TRACE_FUNCTION, "handle_redirect (%s)", args);
611
612     if (redirects && findnode (redirects, args))
613         error (1, 0, "`Redirect' loop detected.  Server misconfiguration?");
614     else
615     {
616         if (!redirects) redirects = getlist();
617         push_string (redirects, args);
618     }
619
620     if (referred_since_last_redirect)
621         referred_since_last_redirect = false;
622     else
623     {
624         if (free_client_referrer) free (client_referrer);
625         client_referrer = current_parsed_root;
626         free_client_referrer = false;
627     }
628
629     current_parsed_root = parse_cvsroot (args);
630
631     /* We deliberately do not set ORIGINAL_PARSED_ROOT here.
632      * ORIGINAL_PARSED_ROOT is used by the client to determine the current root
633      * being processed for the purpose of looking it up in lists and such, even
634      * after a redirect.
635      *
636      * FIXME
637      *   CURRENT_PARSED_ROOT should not be reset by this function.  Redirects
638      *   should be "added" to it.  The REDIRECTS list should also be replaced
639      *   by this new CURRENT_PARSED_ROOT element.  This way, if, for instance,
640      *   a multi-root workspace had two secondaries pointing to the same
641      *   primary, then the client would not report a looping error.
642      *
643      *   There is also a potential memory leak above and storing new roots as
644      *   part of the original could help avoid it fairly elegantly.
645      */
646     if (!current_parsed_root)
647         error (1, 0, "Server requested redirect to invalid root: `%s'",
648                args);
649 }
650
651
652
653 /*
654  * This is a proc for walklist().  It inverts the error return premise of
655  * walklist.
656  *
657  * RETURNS
658  *   True       If this path is prefixed by one of the paths in walklist and
659  *              does not step above the prefix path.
660  *   False      Otherwise.
661  */
662 static
663 int path_list_prefixed (Node *p, void *closure)
664 {
665     const char *questionable = closure;
666     const char *prefix = p->key;
667     if (strncmp (prefix, questionable, strlen (prefix))) return 0;
668     questionable += strlen (prefix);
669     while (ISSLASH (*questionable)) questionable++;
670     if (*questionable == '\0') return 1;
671     return pathname_levels (questionable);
672 }
673
674
675
676 /*
677  * Need to validate the client pathname.  Disallowed paths include:
678  *
679  *   1. Absolute paths.
680  *   2. Pathnames that do not reference a specifically requested update
681  *      directory.
682  *
683  * In case 2, we actually only check that the directory is under the uppermost
684  * directories mentioned on the command line.
685  *
686  * RETURNS
687  *   True       If the path is valid.
688  *   False      Otherwise.
689  */
690 static
691 int is_valid_client_path (const char *pathname)
692 {
693     /* 1. Absolute paths. */
694     if (ISABSOLUTE (pathname)) return 0;
695     /* 2. No up-references in path.  */
696     if (pathname_levels (pathname) == 0) return 1;
697     /* 2. No Max-dotdot paths registered.  */
698     if (!uppaths) return 0;
699
700     return walklist (uppaths, path_list_prefixed, (void *)pathname);
701 }
702
703
704
705 /*
706  * Do all the processing for PATHNAME, where pathname consists of the
707  * repository and the filename.  The parameters we pass to FUNC are:
708  * DATA is just the DATA parameter which was passed to
709  * call_in_directory; ENT_LIST is a pointer to an entries list (which
710  * we manage the storage for); SHORT_PATHNAME is the pathname of the
711  * file relative to the (overall) directory in which the command is
712  * taking place; and FILENAME is the filename portion only of
713  * SHORT_PATHNAME.  When we call FUNC, the curent directory points to
714  * the directory portion of SHORT_PATHNAME.  */
715 static void
716 call_in_directory (const char *pathname,
717                    void (*func) (void *, List *, const char *, const char *),
718                    void *data)
719 {
720     /* This variable holds the result of Entries_Open. */
721     List *last_entries = NULL;
722     char *dir_name;
723     char *filename;
724     /* This is what we get when we hook up the directory (working directory
725        name) from PATHNAME with the filename from REPOSNAME.  For example:
726        pathname: ccvs/src/
727        reposname: /u/src/master/ccvs/foo/ChangeLog
728        short_pathname: ccvs/src/ChangeLog
729        */
730     char *short_pathname;
731     char *p;
732
733     /*
734      * Do the whole descent in parallel for the repositories, so we
735      * know what to put in CVS/Repository files.  I'm not sure the
736      * full hair is necessary since the server does a similar
737      * computation; I suspect that we only end up creating one
738      * directory at a time anyway.
739      *
740      * Also note that we must *only* worry about this stuff when we
741      * are creating directories; `cvs co foo/bar; cd foo/bar; cvs co
742      * CVSROOT; cvs update' is legitimate, but in this case
743      * foo/bar/CVSROOT/CVS/Repository is not a subdirectory of
744      * foo/bar/CVS/Repository.
745      */
746     char *reposname;
747     char *short_repos;
748     char *reposdirname;
749     char *rdirp;
750     int reposdirname_absolute;
751     int newdir = 0;
752
753     assert (pathname);
754
755     reposname = NULL;
756     read_line (&reposname);
757     assert (reposname);
758
759     reposdirname_absolute = 0;
760     if (strncmp (reposname, toplevel_repos, strlen (toplevel_repos)))
761     {
762         reposdirname_absolute = 1;
763         short_repos = reposname;
764     }
765     else
766     {
767         short_repos = reposname + strlen (toplevel_repos) + 1;
768         if (short_repos[-1] != '/')
769         {
770             reposdirname_absolute = 1;
771             short_repos = reposname;
772         }
773     }
774
775    /* Now that we have SHORT_REPOS, we can calculate the path to the file we
776     * are being requested to operate on.
777     */
778     filename = strrchr (short_repos, '/');
779     if (!filename)
780         filename = short_repos;
781     else
782         ++filename;
783
784     short_pathname = xmalloc (strlen (pathname) + strlen (filename) + 5);
785     strcpy (short_pathname, pathname);
786     strcat (short_pathname, filename);
787
788     /* Now that we know the path to the file we were requested to operate on,
789      * we can verify that it is valid.
790      *
791      * For security reasons, if SHORT_PATHNAME is absolute or attempts to
792      * ascend outside of the current sanbbox, we abort.  The server should not
793      * send us anything but relative paths which remain inside the sandbox
794      * here.  Anything less means a trojan CVS server could create and edit
795      * arbitrary files on the client.
796      */
797     if (!is_valid_client_path (short_pathname))
798     {
799         error (0, 0,
800                "Server attempted to update a file via an invalid pathname:");
801         error (1, 0, "`%s'.", short_pathname);
802     }
803
804     reposdirname = xstrdup (short_repos);
805     p = strrchr (reposdirname, '/');
806     if (!p)
807     {
808         reposdirname = xrealloc (reposdirname, 2);
809         reposdirname[0] = '.'; reposdirname[1] = '\0';
810     }
811     else
812         *p = '\0';
813
814     dir_name = xstrdup (pathname);
815     p = strrchr (dir_name, '/');
816     if (!p)
817     {
818         dir_name = xrealloc (dir_name, 2);
819         dir_name[0] = '.'; dir_name[1] = '\0';
820     }
821     else
822         *p = '\0';
823     if (client_prune_dirs)
824         add_prune_candidate (dir_name);
825
826     if (!toplevel_wd)
827     {
828         toplevel_wd = xgetcwd ();
829         if (!toplevel_wd)
830             error (1, errno, "could not get working directory");
831     }
832
833     if (CVS_CHDIR (toplevel_wd) < 0)
834         error (1, errno, "could not chdir to %s", toplevel_wd);
835
836     /* Create the CVS directory at the top level if needed.  The
837        isdir seems like an unneeded system call, but it *does*
838        need to be called both if the CVS_CHDIR below succeeds
839        (e.g.  "cvs co .") or if it fails (e.g. basicb-1a in
840        testsuite).  We only need to do this for the "." case,
841        since the server takes care of forcing this directory to be
842        created in all other cases.  If we don't create CVSADM
843        here, the call to Entries_Open below will fail.  FIXME:
844        perhaps this means that we should change our algorithm
845        below that calls Create_Admin instead of having this code
846        here? */
847     if (/* I think the reposdirname_absolute case has to do with
848            things like "cvs update /foo/bar".  In any event, the
849            code below which tries to put toplevel_repos into
850            CVS/Repository is almost surely unsuited to
851            the reposdirname_absolute case.  */
852         !reposdirname_absolute
853         && !strcmp (dir_name, ".")
854         && ! isdir (CVSADM))
855     {
856         char *repo;
857         char *r;
858
859         newdir = 1;
860
861         /* If toplevel_repos doesn't have at least one character, then the
862          * reference to r[-1] below could be out of bounds.
863          */
864         assert (*toplevel_repos);
865
866         repo = xmalloc (strlen (toplevel_repos)
867                         + 10);
868         strcpy (repo, toplevel_repos);
869         r = repo + strlen (repo);
870         if (r[-1] != '.' || r[-2] != '/')
871             strcpy (r, "/.");
872
873         Create_Admin (".", ".", repo, NULL, NULL, 0, 1, 1);
874
875         free (repo);
876     }
877
878     if (CVS_CHDIR (dir_name) < 0)
879     {
880         char *dir;
881         char *dirp;
882         
883         if (! existence_error (errno))
884             error (1, errno, "could not chdir to %s", dir_name);
885         
886         /* Directory does not exist, we need to create it.  */
887         newdir = 1;
888
889         /* Provided we are willing to assume that directories get
890            created one at a time, we could simplify this a lot.
891            Do note that one aspect still would need to walk the
892            dir_name path: the checking for "fncmp (dir, CVSADM)".  */
893
894         dir = xmalloc (strlen (dir_name) + 1);
895         dirp = dir_name;
896         rdirp = reposdirname;
897
898         /* This algorithm makes nested directories one at a time
899            and create CVS administration files in them.  For
900            example, we're checking out foo/bar/baz from the
901            repository:
902
903            1) create foo, point CVS/Repository to <root>/foo
904            2)     .. foo/bar                   .. <root>/foo/bar
905            3)     .. foo/bar/baz               .. <root>/foo/bar/baz
906            
907            As you can see, we're just stepping along DIR_NAME (with
908            DIRP) and REPOSDIRNAME (with RDIRP) respectively.
909
910            We need to be careful when we are checking out a
911            module, however, since DIR_NAME and REPOSDIRNAME are not
912            going to be the same.  Since modules will not have any
913            slashes in their names, we should watch the output of
914            STRCHR to decide whether or not we should use STRCHR on
915            the RDIRP.  That is, if we're down to a module name,
916            don't keep picking apart the repository directory name.  */
917
918         do
919         {
920             dirp = strchr (dirp, '/');
921             if (dirp)
922             {
923                 strncpy (dir, dir_name, dirp - dir_name);
924                 dir[dirp - dir_name] = '\0';
925                 /* Skip the slash.  */
926                 ++dirp;
927                 if (!rdirp)
928                     /* This just means that the repository string has
929                        fewer components than the dir_name string.  But
930                        that is OK (e.g. see modules3-8 in testsuite).  */
931                     ;
932                 else
933                     rdirp = strchr (rdirp, '/');
934             }
935             else
936             {
937                 /* If there are no more slashes in the dir name,
938                    we're down to the most nested directory -OR- to
939                    the name of a module.  In the first case, we
940                    should be down to a DIRP that has no slashes,
941                    so it won't help/hurt to do another STRCHR call
942                    on DIRP.  It will definitely hurt, however, if
943                    we're down to a module name, since a module
944                    name can point to a nested directory (that is,
945                    DIRP will still have slashes in it.  Therefore,
946                    we should set it to NULL so the routine below
947                    copies the contents of REMOTEDIRNAME onto the
948                    root repository directory (does this if rdirp
949                    is set to NULL, because we used to do an extra
950                    STRCHR call here). */
951
952                 rdirp = NULL;
953                 strcpy (dir, dir_name);
954             }
955
956             if (fncmp (dir, CVSADM) == 0)
957             {
958                 error (0, 0, "cannot create a directory named %s", dir);
959                 error (0, 0, "because CVS uses \"%s\" for its own uses",
960                        CVSADM);
961                 error (1, 0, "rename the directory and try again");
962             }
963
964             if (mkdir_if_needed (dir))
965             {
966                 /* It already existed, fine.  Just keep going.  */
967             }
968             else if (!strcmp (cvs_cmd_name, "export"))
969                 /* Don't create CVSADM directories if this is export.  */
970                 ;
971             else
972             {
973                 /*
974                  * Put repository in CVS/Repository.  For historical
975                  * (pre-CVS/Root) reasons, this is an absolute pathname,
976                  * but what really matters is the part of it which is
977                  * relative to cvsroot.
978                  */
979                 char *repo;
980                 char *r, *b;
981
982                 repo = xmalloc (strlen (reposdirname)
983                                 + strlen (toplevel_repos)
984                                 + 80);
985                 if (reposdirname_absolute)
986                     r = repo;
987                 else
988                 {
989                     strcpy (repo, toplevel_repos);
990                     strcat (repo, "/");
991                     r = repo + strlen (repo);
992                 }
993
994                 if (rdirp)
995                 {
996                     /* See comment near start of function; the only
997                        way that the server can put the right thing
998                        in each CVS/Repository file is to create the
999                        directories one at a time.  I think that the
1000                        CVS server has been doing this all along.  */
1001                     error (0, 0, "\
1002 warning: server is not creating directories one at a time");
1003                     strncpy (r, reposdirname, rdirp - reposdirname);
1004                     r[rdirp - reposdirname] = '\0';
1005                 }
1006                 else
1007                     strcpy (r, reposdirname);
1008
1009                 Create_Admin (dir, dir, repo, NULL, NULL, 0, 0, 1);
1010                 free (repo);
1011
1012                 b = strrchr (dir, '/');
1013                 if (!b)
1014                     Subdir_Register (NULL, NULL, dir);
1015                 else
1016                 {
1017                     *b = '\0';
1018                     Subdir_Register (NULL, dir, b + 1);
1019                     *b = '/';
1020                 }
1021             }
1022
1023             if (rdirp)
1024             {
1025                 /* Skip the slash.  */
1026                 ++rdirp;
1027             }
1028
1029         } while (dirp);
1030         free (dir);
1031         /* Now it better work.  */
1032         if (CVS_CHDIR (dir_name) < 0)
1033             error (1, errno, "could not chdir to %s", dir_name);
1034     }
1035     else if (!strcmp (cvs_cmd_name, "export"))
1036         /* Don't create CVSADM directories if this is export.  */
1037         ;
1038     else if (!isdir (CVSADM))
1039     {
1040         /*
1041          * Put repository in CVS/Repository.  For historical
1042          * (pre-CVS/Root) reasons, this is an absolute pathname,
1043          * but what really matters is the part of it which is
1044          * relative to cvsroot.
1045          */
1046         char *repo;
1047
1048         if (reposdirname_absolute)
1049             repo = reposdirname;
1050         else
1051             repo = Xasprintf ("%s/%s", toplevel_repos, reposdirname);
1052
1053         Create_Admin (".", ".", repo, NULL, NULL, 0, 1, 1);
1054         if (repo != reposdirname)
1055             free (repo);
1056     }
1057
1058     if (strcmp (cvs_cmd_name, "export"))
1059     {
1060         last_entries = Entries_Open (0, dir_name);
1061
1062         /* If this is a newly created directory, we will record
1063            all subdirectory information, so call Subdirs_Known in
1064            case there are no subdirectories.  If this is not a
1065            newly created directory, it may be an old working
1066            directory from before we recorded subdirectory
1067            information in the Entries file.  We force a search for
1068            all subdirectories now, to make sure our subdirectory
1069            information is up to date.  If the Entries file does
1070            record subdirectory information, then this call only
1071            does list manipulation.  */
1072         if (newdir)
1073             Subdirs_Known (last_entries);
1074         else
1075         {
1076             List *dirlist;
1077
1078             dirlist = Find_Directories (NULL, W_LOCAL, last_entries);
1079             dellist (&dirlist);
1080         }
1081     }
1082     free (reposdirname);
1083     (*func) (data, last_entries, short_pathname, filename);
1084     if (last_entries)
1085         Entries_Close (last_entries);
1086     free (dir_name);
1087     free (short_pathname);
1088     free (reposname);
1089 }
1090
1091
1092
1093 static void
1094 copy_a_file (void *data, List *ent_list, const char *short_pathname,
1095              const char *filename)
1096 {
1097     char *newname;
1098
1099     read_line (&newname);
1100
1101 #ifdef USE_VMS_FILENAMES
1102     {
1103         /* Mogrify the filename so VMS is happy with it. */
1104         char *p;
1105         for(p = newname; *p; p++)
1106            if(*p == '.' || *p == '#') *p = '_';
1107     }
1108 #endif
1109     /* cvsclient.texi has said for a long time that newname must be in the
1110        same directory.  Wouldn't want a malicious or buggy server overwriting
1111        ~/.profile, /etc/passwd, or anything like that.  */
1112     if (last_component (newname) != newname)
1113         error (1, 0, "protocol error: Copy-file tried to specify directory");
1114
1115     if (unlink_file (newname) && !existence_error (errno))
1116         error (0, errno, "unable to remove %s", newname);
1117     copy_file (filename, newname);
1118     free (newname);
1119 }
1120
1121
1122
1123 static void
1124 handle_copy_file (char *args, size_t len)
1125 {
1126     call_in_directory (args, copy_a_file, NULL);
1127 }
1128
1129
1130
1131 /* Read from the server the count for the length of a file, then read
1132    the contents of that file and write them to FILENAME.  FULLNAME is
1133    the name of the file for use in error messages.  FIXME-someday:
1134    extend this to deal with compressed files and make update_entries
1135    use it.  On error, gives a fatal error.  */
1136 static void
1137 read_counted_file (char *filename, char *fullname)
1138 {
1139     char *size_string;
1140     size_t size;
1141     char *buf;
1142
1143     /* Pointers in buf to the place to put data which will be read,
1144        and the data which needs to be written, respectively.  */
1145     char *pread;
1146     char *pwrite;
1147     /* Number of bytes left to read and number of bytes in buf waiting to
1148        be written, respectively.  */
1149     size_t nread;
1150     size_t nwrite;
1151
1152     FILE *fp;
1153
1154     read_line (&size_string);
1155     if (size_string[0] == 'z')
1156         error (1, 0, "\
1157 protocol error: compressed files not supported for that operation");
1158     /* FIXME: should be doing more error checking, probably.  Like using
1159        strtoul and making sure we used up the whole line.  */
1160     size = atoi (size_string);
1161     free (size_string);
1162
1163     /* A more sophisticated implementation would use only a limited amount
1164        of buffer space (8K perhaps), and read that much at a time.  We allocate
1165        a buffer for the whole file only to make it easy to keep track what
1166        needs to be read and written.  */
1167     buf = xmalloc (size);
1168
1169     /* FIXME-someday: caller should pass in a flag saying whether it
1170        is binary or not.  I haven't carefully looked into whether
1171        CVS/Template files should use local text file conventions or
1172        not.  */
1173     fp = CVS_FOPEN (filename, "wb");
1174     if (!fp)
1175         error (1, errno, "cannot write %s", fullname);
1176     nread = size;
1177     nwrite = 0;
1178     pread = buf;
1179     pwrite = buf;
1180     while (nread > 0 || nwrite > 0)
1181     {
1182         size_t n;
1183
1184         if (nread > 0)
1185         {
1186             n = try_read_from_server (pread, nread);
1187             nread -= n;
1188             pread += n;
1189             nwrite += n;
1190         }
1191
1192         if (nwrite > 0)
1193         {
1194             n = fwrite (pwrite, sizeof *pwrite, nwrite, fp);
1195             if (ferror (fp))
1196                 error (1, errno, "cannot write %s", fullname);
1197             nwrite -= n;
1198             pwrite += n;
1199         }
1200     }
1201     free (buf);
1202     if (fclose (fp) < 0)
1203         error (1, errno, "cannot close %s", fullname);
1204 }
1205
1206
1207
1208 /* OK, we want to swallow the "U foo.c" response and then output it only
1209    if we can update the file.  In the future we probably want some more
1210    systematic approach to parsing tagged text, but for now we keep it
1211    ad hoc.  "Why," I hear you cry, "do we not just look at the
1212    Update-existing and Created responses?"  That is an excellent question,
1213    and the answer is roughly conservatism/laziness--I haven't read through
1214    update.c enough to figure out the exact correspondence or lack thereof
1215    between those responses and a "U foo.c" line (note that Merged, from
1216    join_file, can be either "C foo" or "U foo" depending on the context).  */
1217 /* Nonzero if we have seen +updated and not -updated.  */
1218 static int updated_seen;
1219 /* Filename from an "fname" tagged response within +updated/-updated.  */
1220 static char *updated_fname;
1221
1222 /* This struct is used to hold data when reading the +importmergecmd
1223    and -importmergecmd tags.  We put the variables in a struct only
1224    for namespace issues.  FIXME: As noted above, we need to develop a
1225    more systematic approach.  */
1226 static struct
1227 {
1228     /* Nonzero if we have seen +importmergecmd and not -importmergecmd.  */
1229     int seen;
1230     /* Number of conflicts, from a "conflicts" tagged response.  */
1231     int conflicts;
1232     /* First merge tag, from a "mergetag1" tagged response.  */
1233     char *mergetag1;
1234     /* Second merge tag, from a "mergetag2" tagged response.  */
1235     char *mergetag2;
1236     /* Repository, from a "repository" tagged response.  */
1237     char *repository;
1238 } importmergecmd;
1239
1240 /* Nonzero if we should arrange to return with a failure exit status.  */
1241 static bool failure_exit;
1242
1243
1244 /*
1245  * The time stamp of the last file we registered.
1246  */
1247 static time_t last_register_time;
1248
1249
1250
1251 /*
1252  * The Checksum response gives the checksum for the file transferred
1253  * over by the next Updated, Merged or Patch response.  We just store
1254  * it here, and then check it in update_entries.
1255  */
1256 static int stored_checksum_valid;
1257 static unsigned char stored_checksum[16];
1258 static void
1259 handle_checksum (char *args, size_t len)
1260 {
1261     char *s;
1262     char buf[3];
1263     int i;
1264
1265     if (stored_checksum_valid)
1266         error (1, 0, "Checksum received before last one was used");
1267
1268     s = args;
1269     buf[2] = '\0';
1270     for (i = 0; i < 16; i++)
1271     {
1272         char *bufend;
1273
1274         buf[0] = *s++;
1275         buf[1] = *s++;
1276         stored_checksum[i] = (char) strtol (buf, &bufend, 16);
1277         if (bufend != buf + 2)
1278             break;
1279     }
1280
1281     if (i < 16 || *s != '\0')
1282         error (1, 0, "Invalid Checksum response: `%s'", args);
1283
1284     stored_checksum_valid = 1;
1285 }
1286
1287
1288
1289 /* Mode that we got in a "Mode" response (malloc'd), or NULL if none.  */
1290 static char *stored_mode;
1291 static void
1292 handle_mode (char *args, size_t len)
1293 {
1294     if (stored_mode)
1295         error (1, 0, "protocol error: duplicate Mode");
1296     stored_mode = xstrdup (args);
1297 }
1298
1299
1300
1301 /* Nonzero if time was specified in Mod-time.  */
1302 static int stored_modtime_valid;
1303 /* Time specified in Mod-time.  */
1304 static time_t stored_modtime;
1305 static void
1306 handle_mod_time (char *args, size_t len)
1307 {
1308     struct timespec newtime;
1309     if (stored_modtime_valid)
1310         error (0, 0, "protocol error: duplicate Mod-time");
1311     if (get_date (&newtime, args, NULL))
1312     {
1313         /* Truncate nanoseconds.  */
1314         stored_modtime = newtime.tv_sec;
1315         stored_modtime_valid = 1;
1316     }
1317     else
1318         error (0, 0, "protocol error: cannot parse date %s", args);
1319 }
1320
1321
1322
1323 /*
1324  * If we receive a patch, but the patch program fails to apply it, we
1325  * want to request the original file.  We keep a list of files whose
1326  * patches have failed.
1327  */
1328
1329 char **failed_patches;
1330 int failed_patches_count;
1331
1332 struct update_entries_data
1333 {
1334     enum {
1335       /*
1336        * We are just getting an Entries line; the local file is
1337        * correct.
1338        */
1339       UPDATE_ENTRIES_CHECKIN,
1340       /* We are getting the file contents as well.  */
1341       UPDATE_ENTRIES_UPDATE,
1342       /*
1343        * We are getting a patch against the existing local file, not
1344        * an entire new file.
1345        */
1346       UPDATE_ENTRIES_PATCH,
1347       /*
1348        * We are getting an RCS change text (diff -n output) against
1349        * the existing local file, not an entire new file.
1350        */
1351       UPDATE_ENTRIES_RCS_DIFF
1352     } contents;
1353
1354     enum {
1355         /* We are replacing an existing file.  */
1356         UPDATE_ENTRIES_EXISTING,
1357         /* We are creating a new file.  */
1358         UPDATE_ENTRIES_NEW,
1359         /* We don't know whether it is existing or new.  */
1360         UPDATE_ENTRIES_EXISTING_OR_NEW
1361     } existp;
1362
1363     /*
1364      * String to put in the timestamp field or NULL to use the timestamp
1365      * of the file.
1366      */
1367     char *timestamp;
1368 };
1369
1370
1371
1372 /* Update the Entries line for this file.  */
1373 static void
1374 update_entries (void *data_arg, List *ent_list, const char *short_pathname,
1375                 const char *filename)
1376 {
1377     char *entries_line;
1378     struct update_entries_data *data = data_arg;
1379
1380     char *cp;
1381     char *user;
1382     char *vn;
1383     /* Timestamp field.  Always empty according to the protocol.  */
1384     char *ts;
1385     char *options = NULL;
1386     char *tag = NULL;
1387     char *date = NULL;
1388     char *tag_or_date;
1389     char *scratch_entries = NULL;
1390     int bin;
1391
1392 #ifdef UTIME_EXPECTS_WRITABLE
1393     int change_it_back = 0;
1394 #endif
1395
1396     read_line (&entries_line);
1397
1398     /*
1399      * Parse the entries line.
1400      */
1401     scratch_entries = xstrdup (entries_line);
1402
1403     if (scratch_entries[0] != '/')
1404         error (1, 0, "bad entries line `%s' from server", entries_line);
1405     user = scratch_entries + 1;
1406     if (!(cp = strchr (user, '/')))
1407         error (1, 0, "bad entries line `%s' from server", entries_line);
1408     *cp++ = '\0';
1409     vn = cp;
1410     if (!(cp = strchr (vn, '/')))
1411         error (1, 0, "bad entries line `%s' from server", entries_line);
1412     *cp++ = '\0';
1413     
1414     ts = cp;
1415     if (!(cp = strchr (ts, '/')))
1416         error (1, 0, "bad entries line `%s' from server", entries_line);
1417     *cp++ = '\0';
1418     options = cp;
1419     if (!(cp = strchr (options, '/')))
1420         error (1, 0, "bad entries line `%s' from server", entries_line);
1421     *cp++ = '\0';
1422     tag_or_date = cp;
1423     
1424     /* If a slash ends the tag_or_date, ignore everything after it.  */
1425     cp = strchr (tag_or_date, '/');
1426     if (cp)
1427         *cp = '\0';
1428     if (*tag_or_date == 'T')
1429         tag = tag_or_date + 1;
1430     else if (*tag_or_date == 'D')
1431         date = tag_or_date + 1;
1432
1433     /* Done parsing the entries line. */
1434
1435     if (data->contents == UPDATE_ENTRIES_UPDATE
1436         || data->contents == UPDATE_ENTRIES_PATCH
1437         || data->contents == UPDATE_ENTRIES_RCS_DIFF)
1438     {
1439         char *size_string;
1440         char *mode_string;
1441         int size;
1442         char *buf;
1443         char *temp_filename;
1444         int use_gzip;
1445         int patch_failed;
1446
1447         read_line (&mode_string);
1448         
1449         read_line (&size_string);
1450         if (size_string[0] == 'z')
1451         {
1452             use_gzip = 1;
1453             size = atoi (size_string+1);
1454         }
1455         else
1456         {
1457             use_gzip = 0;
1458             size = atoi (size_string);
1459         }
1460         free (size_string);
1461
1462         /* Note that checking this separately from writing the file is
1463            a race condition: if the existence or lack thereof of the
1464            file changes between now and the actual calls which
1465            operate on it, we lose.  However (a) there are so many
1466            cases, I'm reluctant to try to fix them all, (b) in some
1467            cases the system might not even have a system call which
1468            does the right thing, and (c) it isn't clear this needs to
1469            work.  */
1470         if (data->existp == UPDATE_ENTRIES_EXISTING
1471             && !isfile (filename))
1472             /* Emit a warning and update the file anyway.  */
1473             error (0, 0, "warning: %s unexpectedly disappeared",
1474                    short_pathname);
1475
1476         if (data->existp == UPDATE_ENTRIES_NEW
1477             && isfile (filename))
1478         {
1479             /* Emit a warning and refuse to update the file; we don't want
1480                to clobber a user's file.  */
1481             size_t nread;
1482             size_t toread;
1483
1484             /* size should be unsigned, but until we get around to fixing
1485                that, work around it.  */
1486             size_t usize;
1487
1488             char buf[8192];
1489
1490             /* This error might be confusing; it isn't really clear to
1491                the user what to do about it.  Keep in mind that it has
1492                several causes: (1) something/someone creates the file
1493                during the time that CVS is running, (2) the repository
1494                has two files whose names clash for the client because
1495                of case-insensitivity or similar causes, See 3 for
1496                additional notes.  (3) a special case of this is that a
1497                file gets renamed for example from a.c to A.C.  A
1498                "cvs update" on a case-insensitive client will get this
1499                error.  In this case and in case 2, the filename
1500                (short_pathname) printed in the error message will likely _not_
1501                have the same case as seen by the user in a directory listing.
1502                (4) the client has a file which the server doesn't know
1503                about (e.g. "? foo" file), and that name clashes with a file
1504                the server does know about, (5) classify.c will print the same
1505                message for other reasons.
1506
1507                I hope the above paragraph makes it clear that making this
1508                clearer is not a one-line fix.  */
1509             error (0, 0, "move away `%s'; it is in the way", short_pathname);
1510             if (updated_fname)
1511             {
1512                 cvs_output ("C ", 0);
1513                 cvs_output (updated_fname, 0);
1514                 cvs_output ("\n", 1);
1515             }
1516             failure_exit = true;
1517
1518         discard_file_and_return:
1519             /* Now read and discard the file contents.  */
1520             usize = size;
1521             nread = 0;
1522             while (nread < usize)
1523             {
1524                 toread = usize - nread;
1525                 if (toread > sizeof buf)
1526                     toread = sizeof buf;
1527
1528                 nread += try_read_from_server (buf, toread);
1529                 if (nread == usize)
1530                     break;
1531             }
1532
1533             free (mode_string);
1534             free (scratch_entries);
1535             free (entries_line);
1536
1537             /* The Mode, Mod-time, and Checksum responses should not carry
1538                over to a subsequent Created (or whatever) response, even
1539                in the error case.  */
1540             if (stored_mode)
1541             {
1542                 free (stored_mode);
1543                 stored_mode = NULL;
1544             }
1545             stored_modtime_valid = 0;
1546             stored_checksum_valid = 0;
1547
1548             if (updated_fname)
1549             {
1550                 free (updated_fname);
1551                 updated_fname = NULL;
1552             }
1553             return;
1554         }
1555
1556         temp_filename = xmalloc (strlen (filename) + 80);
1557 #ifdef USE_VMS_FILENAMES
1558         /* A VMS rename of "blah.dat" to "foo" to implies a
1559            destination of "foo.dat" which is unfortinate for CVS */
1560         sprintf (temp_filename, "%s_new_", filename);
1561 #else
1562 #ifdef _POSIX_NO_TRUNC
1563         sprintf (temp_filename, ".new.%.9s", filename);
1564 #else /* _POSIX_NO_TRUNC */
1565         sprintf (temp_filename, ".new.%s", filename);
1566 #endif /* _POSIX_NO_TRUNC */
1567 #endif /* USE_VMS_FILENAMES */
1568
1569         buf = xmalloc (size);
1570
1571         /* Some systems, like OS/2 and Windows NT, end lines with CRLF
1572            instead of just LF.  Format translation is done in the C
1573            library I/O funtions.  Here we tell them whether or not to
1574            convert -- if this file is marked "binary" with the RCS -kb
1575            flag, then we don't want to convert, else we do (because
1576            CVS assumes text files by default). */
1577
1578         if (options)
1579             bin = !strcmp (options, "-kb");
1580         else
1581             bin = 0;
1582
1583         if (data->contents == UPDATE_ENTRIES_RCS_DIFF)
1584         {
1585             /* This is an RCS change text.  We just hold the change
1586                text in memory.  */
1587
1588             if (use_gzip)
1589                 error (1, 0,
1590                        "server error: gzip invalid with RCS change text");
1591
1592             read_from_server (buf, size);
1593         }
1594         else
1595         {
1596             int fd;
1597
1598             fd = CVS_OPEN (temp_filename,
1599                            (O_WRONLY | O_CREAT | O_TRUNC
1600                             | (bin ? OPEN_BINARY : 0)),
1601                            0777);
1602
1603             if (fd < 0)
1604             {
1605                 /* I can see a case for making this a fatal error; for
1606                    a condition like disk full or network unreachable
1607                    (for a file server), carrying on and giving an
1608                    error on each file seems unnecessary.  But if it is
1609                    a permission problem, or some such, then it is
1610                    entirely possible that future files will not have
1611                    the same problem.  */
1612                 error (0, errno, "cannot write %s", short_pathname);
1613                 free (temp_filename);
1614                 free (buf);
1615                 goto discard_file_and_return;
1616             }
1617
1618             if (size > 0)
1619             {
1620                 read_from_server (buf, size);
1621
1622                 if (use_gzip)
1623                 {
1624                     if (gunzip_and_write (fd, short_pathname, 
1625                                           (unsigned char *) buf, size))
1626                         error (1, 0, "aborting due to compression error");
1627                 }
1628                 else if (write (fd, buf, size) != size)
1629                     error (1, errno, "writing %s", short_pathname);
1630             }
1631
1632             if (close (fd) < 0)
1633                 error (1, errno, "writing %s", short_pathname);
1634         }
1635
1636         /* This is after we have read the file from the net (a change
1637            from previous versions, where the server would send us
1638            "M U foo.c" before Update-existing or whatever), but before
1639            we finish writing the file (arguably a bug).  The timing
1640            affects a user who wants status info about how far we have
1641            gotten, and also affects whether "U foo.c" appears in addition
1642            to various error messages.  */
1643         if (updated_fname)
1644         {
1645             cvs_output ("U ", 0);
1646             cvs_output (updated_fname, 0);
1647             cvs_output ("\n", 1);
1648             free (updated_fname);
1649             updated_fname = 0;
1650         }
1651
1652         patch_failed = 0;
1653
1654         if (data->contents == UPDATE_ENTRIES_UPDATE)
1655         {
1656             rename_file (temp_filename, filename);
1657         }
1658         else if (data->contents == UPDATE_ENTRIES_PATCH)
1659         {
1660             /* You might think we could just leave Patched out of
1661                Valid-responses and not get this response.  However, if
1662                memory serves, the CVS 1.9 server bases this on -u
1663                (update-patches), and there is no way for us to send -u
1664                or not based on whether the server supports "Rcs-diff".  
1665
1666                Fall back to transmitting entire files.  */
1667             patch_failed = 1;
1668         }
1669         else
1670         {
1671             char *filebuf;
1672             size_t filebufsize;
1673             size_t nread;
1674             char *patchedbuf;
1675             size_t patchedlen;
1676
1677             /* Handle UPDATE_ENTRIES_RCS_DIFF.  */
1678
1679             if (!isfile (filename))
1680                 error (1, 0, "patch original file %s does not exist",
1681                        short_pathname);
1682             filebuf = NULL;
1683             filebufsize = 0;
1684             nread = 0;
1685
1686             get_file (filename, short_pathname, bin ? FOPEN_BINARY_READ : "r",
1687                       &filebuf, &filebufsize, &nread);
1688             /* At this point the contents of the existing file are in
1689                FILEBUF, and the length of the contents is in NREAD.
1690                The contents of the patch from the network are in BUF,
1691                and the length of the patch is in SIZE.  */
1692
1693             if (! rcs_change_text (short_pathname, filebuf, nread, buf, size,
1694                                    &patchedbuf, &patchedlen))
1695                 patch_failed = 1;
1696             else
1697             {
1698                 if (stored_checksum_valid)
1699                 {
1700                     unsigned char checksum[16];
1701
1702                     /* We have a checksum.  Check it before writing
1703                        the file out, so that we don't have to read it
1704                        back in again.  */
1705                     md5_buffer (patchedbuf, patchedlen, checksum);
1706                     if (memcmp (checksum, stored_checksum, 16) != 0)
1707                     {
1708                         error (0, 0,
1709 "checksum failure after patch to %s; will refetch",
1710                                short_pathname);
1711
1712                         patch_failed = 1;
1713                     }
1714
1715                     stored_checksum_valid = 0;
1716                 }
1717
1718                 if (! patch_failed)
1719                 {
1720                     FILE *e;
1721
1722                     e = xfopen (temp_filename,
1723                                 bin ? FOPEN_BINARY_WRITE : "w");
1724                     if (fwrite (patchedbuf, sizeof *patchedbuf, patchedlen, e)
1725                         != patchedlen)
1726                         error (1, errno, "cannot write %s", temp_filename);
1727                     if (fclose (e) == EOF)
1728                         error (1, errno, "cannot close %s", temp_filename);
1729                     rename_file (temp_filename, filename);
1730                 }
1731
1732                 free (patchedbuf);
1733             }
1734
1735             free (filebuf);
1736         }
1737
1738         free (temp_filename);
1739
1740         if (stored_checksum_valid && ! patch_failed)
1741         {
1742             FILE *e;
1743             struct md5_ctx context;
1744             unsigned char buf[8192];
1745             unsigned len;
1746             unsigned char checksum[16];
1747
1748             /*
1749              * Compute the MD5 checksum.  This will normally only be
1750              * used when receiving a patch, so we always compute it
1751              * here on the final file, rather than on the received
1752              * data.
1753              *
1754              * Note that if the file is a text file, we should read it
1755              * here using text mode, so its lines will be terminated the same
1756              * way they were transmitted.
1757              */
1758             e = CVS_FOPEN (filename, "r");
1759             if (!e)
1760                 error (1, errno, "could not open %s", short_pathname);
1761
1762             md5_init_ctx (&context);
1763             while ((len = fread (buf, 1, sizeof buf, e)) != 0)
1764                 md5_process_bytes (buf, len, &context);
1765             if (ferror (e))
1766                 error (1, errno, "could not read %s", short_pathname);
1767             md5_finish_ctx (&context, checksum);
1768
1769             fclose (e);
1770
1771             stored_checksum_valid = 0;
1772
1773             if (memcmp (checksum, stored_checksum, 16) != 0)
1774             {
1775                 if (data->contents != UPDATE_ENTRIES_PATCH)
1776                     error (1, 0, "checksum failure on %s",
1777                            short_pathname);
1778
1779                 error (0, 0,
1780                        "checksum failure after patch to %s; will refetch",
1781                        short_pathname);
1782
1783                 patch_failed = 1;
1784             }
1785         }
1786
1787         if (patch_failed)
1788         {
1789             /* Save this file to retrieve later.  */
1790             failed_patches = xnrealloc (failed_patches,
1791                                         failed_patches_count + 1,
1792                                         sizeof (char *));
1793             failed_patches[failed_patches_count] = xstrdup (short_pathname);
1794             ++failed_patches_count;
1795
1796             stored_checksum_valid = 0;
1797
1798             free (mode_string);
1799             free (buf);
1800             free (scratch_entries);
1801             free (entries_line);
1802
1803             return;
1804         }
1805
1806         {
1807             int status = change_mode (filename, mode_string, 1);
1808             if (status != 0)
1809                 error (0, status, "cannot change mode of %s", short_pathname);
1810         }
1811
1812         free (mode_string);
1813         free (buf);
1814     }
1815
1816     if (stored_mode)
1817     {
1818         change_mode (filename, stored_mode, 1);
1819         free (stored_mode);
1820         stored_mode = NULL;
1821     }
1822    
1823     if (stored_modtime_valid)
1824     {
1825         struct utimbuf t;
1826
1827         memset (&t, 0, sizeof (t));
1828         t.modtime = stored_modtime;
1829         (void) time (&t.actime);
1830
1831 #ifdef UTIME_EXPECTS_WRITABLE
1832         if (!iswritable (filename))
1833         {
1834             xchmod (filename, 1);
1835             change_it_back = 1;
1836         }
1837 #endif  /* UTIME_EXPECTS_WRITABLE  */
1838
1839         if (utime (filename, &t) < 0)
1840             error (0, errno, "cannot set time on %s", filename);
1841
1842 #ifdef UTIME_EXPECTS_WRITABLE
1843         if (change_it_back)
1844         {
1845             xchmod (filename, 0);
1846             change_it_back = 0;
1847         }
1848 #endif  /*  UTIME_EXPECTS_WRITABLE  */
1849
1850         stored_modtime_valid = 0;
1851     }
1852
1853     /*
1854      * Process the entries line.  Do this after we've written the file,
1855      * since we need the timestamp.
1856      */
1857     if (strcmp (cvs_cmd_name, "export"))
1858     {
1859         char *local_timestamp;
1860         char *file_timestamp;
1861
1862         (void) time (&last_register_time);
1863
1864         local_timestamp = data->timestamp;
1865         if (!local_timestamp || ts[0] == '+')
1866             file_timestamp = time_stamp (filename);
1867         else
1868             file_timestamp = NULL;
1869
1870         /*
1871          * These special version numbers signify that it is not up to
1872          * date.  Create a dummy timestamp which will never compare
1873          * equal to the timestamp of the file.
1874          */
1875         if (vn[0] == '\0' || !strcmp (vn, "0") || vn[0] == '-')
1876             local_timestamp = "dummy timestamp";
1877         else if (!local_timestamp)
1878         {
1879             local_timestamp = file_timestamp;
1880
1881             /* Checking for cvs_cmd_name of "commit" doesn't seem like
1882                the cleanest way to handle this, but it seem to roughly
1883                parallel what the :local: code which calls
1884                mark_up_to_date ends up amounting to.  Some day, should
1885                think more about what the Checked-in response means
1886                vis-a-vis both Entries and Base and clarify
1887                cvsclient.texi accordingly.  */
1888
1889             if (!strcmp (cvs_cmd_name, "commit"))
1890                 mark_up_to_date (filename);
1891         }
1892
1893         Register (ent_list, filename, vn, local_timestamp,
1894                   options, tag, date, ts[0] == '+' ? file_timestamp : NULL);
1895
1896         if (file_timestamp)
1897             free (file_timestamp);
1898
1899     }
1900     free (scratch_entries);
1901     free (entries_line);
1902 }
1903
1904
1905
1906 static void
1907 handle_checked_in (char *args, size_t len)
1908 {
1909     struct update_entries_data dat;
1910     dat.contents = UPDATE_ENTRIES_CHECKIN;
1911     dat.existp = UPDATE_ENTRIES_EXISTING_OR_NEW;
1912     dat.timestamp = NULL;
1913     call_in_directory (args, update_entries, &dat);
1914 }
1915
1916
1917
1918 static void
1919 handle_new_entry (char *args, size_t len)
1920 {
1921     struct update_entries_data dat;
1922     dat.contents = UPDATE_ENTRIES_CHECKIN;
1923     dat.existp = UPDATE_ENTRIES_EXISTING_OR_NEW;
1924     dat.timestamp = "dummy timestamp from new-entry";
1925     call_in_directory (args, update_entries, &dat);
1926 }
1927
1928
1929
1930 static void
1931 handle_updated (char *args, size_t len)
1932 {
1933     struct update_entries_data dat;
1934     dat.contents = UPDATE_ENTRIES_UPDATE;
1935     dat.existp = UPDATE_ENTRIES_EXISTING_OR_NEW;
1936     dat.timestamp = NULL;
1937     call_in_directory (args, update_entries, &dat);
1938 }
1939
1940
1941
1942 static void
1943 handle_created (char *args, size_t len)
1944 {
1945     struct update_entries_data dat;
1946     dat.contents = UPDATE_ENTRIES_UPDATE;
1947     dat.existp = UPDATE_ENTRIES_NEW;
1948     dat.timestamp = NULL;
1949     call_in_directory (args, update_entries, &dat);
1950 }
1951
1952
1953
1954 static void
1955 handle_update_existing (char *args, size_t len)
1956 {
1957     struct update_entries_data dat;
1958     dat.contents = UPDATE_ENTRIES_UPDATE;
1959     dat.existp = UPDATE_ENTRIES_EXISTING;
1960     dat.timestamp = NULL;
1961     call_in_directory (args, update_entries, &dat);
1962 }
1963
1964
1965
1966 static void
1967 handle_merged (char *args, size_t len)
1968 {
1969     struct update_entries_data dat;
1970     dat.contents = UPDATE_ENTRIES_UPDATE;
1971     /* Think this could be UPDATE_ENTRIES_EXISTING, but just in case...  */
1972     dat.existp = UPDATE_ENTRIES_EXISTING_OR_NEW;
1973     dat.timestamp = "Result of merge";
1974     call_in_directory (args, update_entries, &dat);
1975 }
1976
1977
1978
1979 static void
1980 handle_patched (char *args, size_t len)
1981 {
1982     struct update_entries_data dat;
1983     dat.contents = UPDATE_ENTRIES_PATCH;
1984     /* Think this could be UPDATE_ENTRIES_EXISTING, but just in case...  */
1985     dat.existp = UPDATE_ENTRIES_EXISTING_OR_NEW;
1986     dat.timestamp = NULL;
1987     call_in_directory (args, update_entries, &dat);
1988 }
1989
1990
1991
1992 static void
1993 handle_rcs_diff (char *args, size_t len)
1994 {
1995     struct update_entries_data dat;
1996     dat.contents = UPDATE_ENTRIES_RCS_DIFF;
1997     /* Think this could be UPDATE_ENTRIES_EXISTING, but just in case...  */
1998     dat.existp = UPDATE_ENTRIES_EXISTING_OR_NEW;
1999     dat.timestamp = NULL;
2000     call_in_directory (args, update_entries, &dat);
2001 }
2002
2003
2004
2005 static void
2006 remove_entry (void *data, List *ent_list, const char *short_pathname,
2007               const char *filename)
2008 {
2009     Scratch_Entry (ent_list, filename);
2010 }
2011
2012
2013
2014 static void
2015 handle_remove_entry (char *args, size_t len)
2016 {
2017     call_in_directory (args, remove_entry, NULL);
2018 }
2019
2020
2021
2022 static void
2023 remove_entry_and_file (void *data, List *ent_list, const char *short_pathname,
2024                        const char *filename)
2025 {
2026     Scratch_Entry (ent_list, filename);
2027     /* Note that we don't ignore existence_error's here.  The server
2028        should be sending Remove-entry rather than Removed in cases
2029        where the file does not exist.  And if the user removes the
2030        file halfway through a cvs command, we should be printing an
2031        error.  */
2032     if (unlink_file (filename) < 0)
2033         error (0, errno, "unable to remove %s", short_pathname);
2034 }
2035
2036
2037
2038 static void
2039 handle_removed (char *args, size_t len)
2040 {
2041     call_in_directory (args, remove_entry_and_file, NULL);
2042 }
2043
2044
2045
2046 /* Is this the top level (directory containing CVSROOT)?  */
2047 static int
2048 is_cvsroot_level (char *pathname)
2049 {
2050     if (strcmp (toplevel_repos, current_parsed_root->directory))
2051         return 0;
2052
2053     return !strchr (pathname, '/');
2054 }
2055
2056
2057
2058 static void
2059 set_static (void *data, List *ent_list, const char *short_pathname,
2060             const char *filename)
2061 {
2062     FILE *fp;
2063     fp = xfopen (CVSADM_ENTSTAT, "w+");
2064     if (fclose (fp) == EOF)
2065         error (1, errno, "cannot close %s", CVSADM_ENTSTAT);
2066 }
2067
2068
2069
2070 static void
2071 handle_set_static_directory (char *args, size_t len)
2072 {
2073     if (!strcmp (cvs_cmd_name, "export"))
2074     {
2075         /* Swallow the repository.  */
2076         read_line (NULL);
2077         return;
2078     }
2079     call_in_directory (args, set_static, NULL);
2080 }
2081
2082
2083
2084 static void
2085 clear_static (void *data, List *ent_list, const char *short_pathname,
2086               const char *filename)
2087 {
2088     if (unlink_file (CVSADM_ENTSTAT) < 0 && ! existence_error (errno))
2089         error (1, errno, "cannot remove file %s", CVSADM_ENTSTAT);
2090 }
2091
2092
2093
2094 static void
2095 handle_clear_static_directory (char *pathname, size_t len)
2096 {
2097     if (!strcmp (cvs_cmd_name, "export"))
2098     {
2099         /* Swallow the repository.  */
2100         read_line (NULL);
2101         return;
2102     }
2103
2104     if (is_cvsroot_level (pathname))
2105     {
2106         /*
2107          * Top level (directory containing CVSROOT).  This seems to normally
2108          * lack a CVS directory, so don't try to create files in it.
2109          */
2110         return;
2111     }
2112     call_in_directory (pathname, clear_static, NULL);
2113 }
2114
2115
2116
2117 static void
2118 set_sticky (void *data, List *ent_list, const char *short_pathname,
2119             const char *filename)
2120 {
2121     char *tagspec;
2122     FILE *f;
2123
2124     read_line (&tagspec);
2125
2126     /* FIXME-update-dir: error messages should include the directory.  */
2127     f = CVS_FOPEN (CVSADM_TAG, "w+");
2128     if (!f)
2129     {
2130         /* Making this non-fatal is a bit of a kludge (see dirs2
2131            in testsuite).  A better solution would be to avoid having
2132            the server tell us about a directory we shouldn't be doing
2133            anything with anyway (e.g. by handling directory
2134            addition/removal better).  */
2135         error (0, errno, "cannot open %s", CVSADM_TAG);
2136         free (tagspec);
2137         return;
2138     }
2139     if (fprintf (f, "%s\n", tagspec) < 0)
2140         error (1, errno, "writing %s", CVSADM_TAG);
2141     if (fclose (f) == EOF)
2142         error (1, errno, "closing %s", CVSADM_TAG);
2143     free (tagspec);
2144 }
2145
2146
2147
2148 static void
2149 handle_set_sticky (char *pathname, size_t len)
2150 {
2151     if (!strcmp (cvs_cmd_name, "export"))
2152     {
2153         /* Swallow the repository.  */
2154         read_line (NULL);
2155         /* Swallow the tag line.  */
2156         read_line (NULL);
2157         return;
2158     }
2159     if (is_cvsroot_level (pathname))
2160     {
2161         /*
2162          * Top level (directory containing CVSROOT).  This seems to normally
2163          * lack a CVS directory, so don't try to create files in it.
2164          */
2165
2166         /* Swallow the repository.  */
2167         read_line (NULL);
2168         /* Swallow the tag line.  */
2169         read_line (NULL);
2170         return;
2171     }
2172
2173     call_in_directory (pathname, set_sticky, NULL);
2174 }
2175
2176
2177
2178 static void
2179 clear_sticky (void *data, List *ent_list, const char *short_pathname,
2180               const char *filename)
2181 {
2182     if (unlink_file (CVSADM_TAG) < 0 && ! existence_error (errno))
2183         error (1, errno, "cannot remove %s", CVSADM_TAG);
2184 }
2185
2186
2187
2188 static void
2189 handle_clear_sticky (char *pathname, size_t len)
2190 {
2191     if (!strcmp (cvs_cmd_name, "export"))
2192     {
2193         /* Swallow the repository.  */
2194         read_line (NULL);
2195         return;
2196     }
2197
2198     if (is_cvsroot_level (pathname))
2199     {
2200         /*
2201          * Top level (directory containing CVSROOT).  This seems to normally
2202          * lack a CVS directory, so don't try to create files in it.
2203          */
2204         return;
2205     }
2206
2207     call_in_directory (pathname, clear_sticky, NULL);
2208 }
2209
2210
2211
2212 /* Handle the client-side support for a successful edit.
2213  */
2214 static void
2215 handle_edit_file (char *pathname, size_t len)
2216 {
2217     call_in_directory (pathname, edit_file, NULL);
2218 }
2219
2220
2221
2222 static void
2223 template (void *data, List *ent_list, const char *short_pathname,
2224           const char *filename)
2225 {
2226     char *buf = Xasprintf ("%s/%s", short_pathname, CVSADM_TEMPLATE);
2227     read_counted_file (CVSADM_TEMPLATE, buf);
2228     free (buf);
2229 }
2230
2231
2232
2233 static void
2234 handle_template (char *pathname, size_t len)
2235 {
2236     call_in_directory (pathname, template, NULL);
2237 }
2238
2239
2240
2241 static void
2242 clear_template (void *data, List *ent_list, const char *short_pathname,
2243                 const char *filename)
2244 {
2245     if (unlink_file (CVSADM_TEMPLATE) < 0 && ! existence_error (errno))
2246         error (1, errno, "cannot remove %s", CVSADM_TEMPLATE);
2247 }
2248
2249
2250
2251 static void
2252 handle_clear_template (char *pathname, size_t len)
2253 {
2254     call_in_directory (pathname, clear_template, NULL);
2255 }
2256
2257
2258
2259 struct save_dir {
2260     char *dir;
2261     struct save_dir *next;
2262 };
2263
2264 struct save_dir *prune_candidates;
2265
2266 static void
2267 add_prune_candidate (const char *dir)
2268 {
2269     struct save_dir *p;
2270
2271     if ((dir[0] == '.' && dir[1] == '\0')
2272         || (prune_candidates && !strcmp (dir, prune_candidates->dir)))
2273         return;
2274     p = xmalloc (sizeof (struct save_dir));
2275     p->dir = xstrdup (dir);
2276     p->next = prune_candidates;
2277     prune_candidates = p;
2278 }
2279
2280
2281
2282 static void
2283 process_prune_candidates (void)
2284 {
2285     struct save_dir *p;
2286     struct save_dir *q;
2287
2288     if (toplevel_wd)
2289     {
2290         if (CVS_CHDIR (toplevel_wd) < 0)
2291             error (1, errno, "could not chdir to %s", toplevel_wd);
2292     }
2293     for (p = prune_candidates; p; )
2294     {
2295         if (isemptydir (p->dir, 1))
2296         {
2297             char *b;
2298
2299             if (unlink_file_dir (p->dir) < 0)
2300                 error (0, errno, "cannot remove %s", p->dir);
2301             b = strrchr (p->dir, '/');
2302             if (!b)
2303                 Subdir_Deregister (NULL, NULL, p->dir);
2304             else
2305             {
2306                 *b = '\0';
2307                 Subdir_Deregister (NULL, p->dir, b + 1);
2308             }
2309         }
2310         free (p->dir);
2311         q = p->next;
2312         free (p);
2313         p = q;
2314     }
2315     prune_candidates = NULL;
2316 }
2317
2318
2319
2320 /* Send a Repository line.  */
2321 static char *last_repos;
2322 static char *last_update_dir;
2323 static void
2324 send_repository (const char *dir, const char *repos, const char *update_dir)
2325 {
2326     char *adm_name;
2327
2328     /* FIXME: this is probably not the best place to check; I wish I
2329      * knew where in here's callers to really trap this bug.  To
2330      * reproduce the bug, just do this:
2331      * 
2332      *       mkdir junk
2333      *       cd junk
2334      *       cvs -d some_repos update foo
2335      *
2336      * Poof, CVS seg faults and dies!  It's because it's trying to
2337      * send a NULL string to the server but dies in send_to_server.
2338      * That string was supposed to be the repository, but it doesn't
2339      * get set because there's no CVSADM dir, and somehow it's not
2340      * getting set from the -d argument either... ?
2341      */
2342     if (!repos)
2343     {
2344         /* Lame error.  I want a real fix but can't stay up to track
2345            this down right now. */
2346         error (1, 0, "no repository");
2347     }
2348
2349     if (!update_dir || update_dir[0] == '\0')
2350         update_dir = ".";
2351
2352     if (last_repos && !strcmp (repos, last_repos)
2353         && last_update_dir && !strcmp (update_dir, last_update_dir))
2354         /* We've already sent it.  */
2355         return;
2356
2357     if (client_prune_dirs)
2358         add_prune_candidate (update_dir);
2359
2360     /* Add a directory name to the list of those sent to the
2361        server. */
2362     if (update_dir && *update_dir != '\0' && strcmp (update_dir, ".")
2363         && !findnode (dirs_sent_to_server, update_dir))
2364     {
2365         Node *n;
2366         n = getnode ();
2367         n->type = NT_UNKNOWN;
2368         n->key = xstrdup (update_dir);
2369         n->data = NULL;
2370
2371         if (addnode (dirs_sent_to_server, n))
2372             error (1, 0, "cannot add directory %s to list", n->key);
2373     }
2374
2375     /* 80 is large enough for any of CVSADM_*.  */
2376     adm_name = xmalloc (strlen (dir) + 80);
2377
2378     send_to_server ("Directory ", 0);
2379     {
2380         /* Send the directory name.  I know that this
2381            sort of duplicates code elsewhere, but each
2382            case seems slightly different...  */
2383         char buf[1];
2384         const char *p = update_dir;
2385         while (*p != '\0')
2386         {
2387             assert (*p != '\012');
2388             if (ISSLASH (*p))
2389             {
2390                 buf[0] = '/';
2391                 send_to_server (buf, 1);
2392             }
2393             else
2394             {
2395                 buf[0] = *p;
2396                 send_to_server (buf, 1);
2397             }
2398             ++p;
2399         }
2400     }
2401     send_to_server ("\012", 1);
2402     if (supported_request ("Relative-directory"))
2403     {
2404         const char *short_repos = Short_Repository (repos);
2405         send_to_server (short_repos, 0);
2406     }
2407     else
2408         send_to_server (repos, 0);
2409     send_to_server ("\012", 1);
2410
2411     if (supported_request ("Static-directory"))
2412     {
2413         adm_name[0] = '\0';
2414         if (dir[0] != '\0')
2415         {
2416             strcat (adm_name, dir);
2417             strcat (adm_name, "/");
2418         }
2419         strcat (adm_name, CVSADM_ENTSTAT);
2420         if (isreadable (adm_name))
2421         {
2422             send_to_server ("Static-directory\012", 0);
2423         }
2424     }
2425     if (supported_request ("Sticky"))
2426     {
2427         FILE *f;
2428         if (dir[0] == '\0')
2429             strcpy (adm_name, CVSADM_TAG);
2430         else
2431             sprintf (adm_name, "%s/%s", dir, CVSADM_TAG);
2432
2433         f = CVS_FOPEN (adm_name, "r");
2434         if (!f)
2435         {
2436             if (! existence_error (errno))
2437                 error (1, errno, "reading %s", adm_name);
2438         }
2439         else
2440         {
2441             char line[80];
2442             char *nl = NULL;
2443             send_to_server ("Sticky ", 0);
2444             while (fgets (line, sizeof (line), f))
2445             {
2446                 send_to_server (line, 0);
2447                 nl = strchr (line, '\n');
2448                 if (nl)
2449                     break;
2450             }
2451             if (!nl)
2452                 send_to_server ("\012", 1);
2453             if (fclose (f) == EOF)
2454                 error (0, errno, "closing %s", adm_name);
2455         }
2456     }
2457     free (adm_name);
2458     if (last_repos) free (last_repos);
2459     if (last_update_dir) free (last_update_dir);
2460     last_repos = xstrdup (repos);
2461     last_update_dir = xstrdup (update_dir);
2462 }
2463
2464
2465
2466 /* Send a Repository line and set toplevel_repos.  */
2467 void
2468 send_a_repository (const char *dir, const char *repository,
2469                    const char *update_dir_in)
2470 {
2471     char *update_dir = xstrdup (update_dir_in);
2472
2473     if (!toplevel_repos && repository)
2474     {
2475         if (update_dir[0] == '\0'
2476             || (update_dir[0] == '.' && update_dir[1] == '\0'))
2477             toplevel_repos = xstrdup (repository);
2478         else
2479         {
2480             /*
2481              * Get the repository from a CVS/Repository file if update_dir
2482              * is absolute.  This is not correct in general, because
2483              * the CVS/Repository file might not be the top-level one.
2484              * This is for cases like "cvs update /foo/bar" (I'm not
2485              * sure it matters what toplevel_repos we get, but it does
2486              * matter that we don't hit the "internal error" code below).
2487              */
2488             if (update_dir[0] == '/')
2489                 toplevel_repos = Name_Repository (update_dir, update_dir);
2490             else
2491             {
2492                 /*
2493                  * Guess the repository of that directory by looking at a
2494                  * subdirectory and removing as many pathname components
2495                  * as are in update_dir.  I think that will always (or at
2496                  * least almost always) be 1.
2497                  *
2498                  * So this deals with directories which have been
2499                  * renamed, though it doesn't necessarily deal with
2500                  * directories which have been put inside other
2501                  * directories (and cvs invoked on the containing
2502                  * directory).  I'm not sure the latter case needs to
2503                  * work.
2504                  *
2505                  * 21 Aug 1998: Well, Mr. Above-Comment-Writer, it
2506                  * does need to work after all.  When we are using the
2507                  * client in a multi-cvsroot environment, it will be
2508                  * fairly common that we have the above case (e.g.,
2509                  * cwd checked out from one repository but
2510                  * subdirectory checked out from another).  We can't
2511                  * assume that by walking up a directory in our wd we
2512                  * necessarily walk up a directory in the repository.
2513                  */
2514                 /*
2515                  * This gets toplevel_repos wrong for "cvs update ../foo"
2516                  * but I'm not sure toplevel_repos matters in that case.
2517                  */
2518
2519                 int repository_len, update_dir_len;
2520
2521                 strip_trailing_slashes (update_dir);
2522
2523                 repository_len = strlen (repository);
2524                 update_dir_len = strlen (update_dir);
2525
2526                 /* Try to remove the path components in UPDATE_DIR
2527                    from REPOSITORY.  If the path elements don't exist
2528                    in REPOSITORY, or the removal of those path
2529                    elements mean that we "step above"
2530                    current_parsed_root->directory, set toplevel_repos to
2531                    current_parsed_root->directory. */
2532                 if (repository_len > update_dir_len
2533                     && !strcmp (repository + repository_len - update_dir_len,
2534                                 update_dir)
2535                     /* TOPLEVEL_REPOS shouldn't be above current_parsed_root->directory */
2536                     && ((size_t)(repository_len - update_dir_len)
2537                         > strlen (current_parsed_root->directory)))
2538                 {
2539                     /* The repository name contains UPDATE_DIR.  Set
2540                        toplevel_repos to the repository name without
2541                        UPDATE_DIR. */
2542
2543                     toplevel_repos = xmalloc (repository_len - update_dir_len);
2544                     /* Note that we don't copy the trailing '/'.  */
2545                     strncpy (toplevel_repos, repository,
2546                              repository_len - update_dir_len - 1);
2547                     toplevel_repos[repository_len - update_dir_len - 1] = '\0';
2548                 }
2549                 else
2550                 {
2551                     toplevel_repos = xstrdup (current_parsed_root->directory);
2552                 }
2553             }
2554         }
2555     }
2556
2557     send_repository (dir, repository, update_dir);
2558     free (update_dir);
2559 }
2560
2561
2562
2563 static void
2564 notified_a_file (void *data, List *ent_list, const char *short_pathname,
2565                  const char *filename)
2566 {
2567     FILE *fp;
2568     FILE *newf;
2569     size_t line_len = 8192;
2570     char *line = xmalloc (line_len);
2571     char *cp;
2572     int nread;
2573     int nwritten;
2574     char *p;
2575
2576     fp = xfopen (CVSADM_NOTIFY, "r");
2577     if (getline (&line, &line_len, fp) < 0)
2578     {
2579         if (feof (fp))
2580             error (0, 0, "cannot read %s: end of file", CVSADM_NOTIFY);
2581         else
2582             error (0, errno, "cannot read %s", CVSADM_NOTIFY);
2583         goto error_exit;
2584     }
2585     cp = strchr (line, '\t');
2586     if (!cp)
2587     {
2588         error (0, 0, "malformed %s file", CVSADM_NOTIFY);
2589         goto error_exit;
2590     }
2591     *cp = '\0';
2592     if (strcmp (filename, line + 1))
2593         error (0, 0, "protocol error: notified %s, expected %s", filename,
2594                line + 1);
2595
2596     if (getline (&line, &line_len, fp) < 0)
2597     {
2598         if (feof (fp))
2599         {
2600             free (line);
2601             if (fclose (fp) < 0)
2602                 error (0, errno, "cannot close %s", CVSADM_NOTIFY);
2603             if ( CVS_UNLINK (CVSADM_NOTIFY) < 0)
2604                 error (0, errno, "cannot remove %s", CVSADM_NOTIFY);
2605             return;
2606         }
2607         else
2608         {
2609             error (0, errno, "cannot read %s", CVSADM_NOTIFY);
2610             goto error_exit;
2611         }
2612     }
2613     newf = xfopen (CVSADM_NOTIFYTMP, "w");
2614     if (fputs (line, newf) < 0)
2615     {
2616         error (0, errno, "cannot write %s", CVSADM_NOTIFYTMP);
2617         goto error2;
2618     }
2619     while ((nread = fread (line, 1, line_len, fp)) > 0)
2620     {
2621         p = line;
2622         while ((nwritten = fwrite (p, sizeof *p, nread, newf)) > 0)
2623         {
2624             nread -= nwritten;
2625             p += nwritten;
2626         }
2627         if (ferror (newf))
2628         {
2629             error (0, errno, "cannot write %s", CVSADM_NOTIFYTMP);
2630             goto error2;
2631         }
2632     }
2633     if (ferror (fp))
2634     {
2635         error (0, errno, "cannot read %s", CVSADM_NOTIFY);
2636         goto error2;
2637     }
2638     if (fclose (newf) < 0)
2639     {
2640         error (0, errno, "cannot close %s", CVSADM_NOTIFYTMP);
2641         goto error_exit;
2642     }
2643     free (line);
2644     if (fclose (fp) < 0)
2645     {
2646         error (0, errno, "cannot close %s", CVSADM_NOTIFY);
2647         return;
2648     }
2649
2650     {
2651         /* In this case, we want rename_file() to ignore noexec. */
2652         int saved_noexec = noexec;
2653         noexec = 0;
2654         rename_file (CVSADM_NOTIFYTMP, CVSADM_NOTIFY);
2655         noexec = saved_noexec;
2656     }
2657
2658     return;
2659   error2:
2660     (void)fclose (newf);
2661   error_exit:
2662     free (line);
2663     (void)fclose (fp);
2664 }
2665
2666
2667
2668 static void
2669 handle_notified (char *args, size_t len)
2670 {
2671     call_in_directory (args, notified_a_file, NULL);
2672 }
2673
2674
2675
2676 /* The "expanded" modules.  */
2677 static int modules_count;
2678 static int modules_allocated;
2679 static char **modules_vector;
2680
2681 static void
2682 handle_module_expansion (char *args, size_t len)
2683 {
2684     if (!modules_vector)
2685     {
2686         modules_allocated = 1; /* Small for testing */
2687         modules_vector = xnmalloc (modules_allocated,
2688                                    sizeof (modules_vector[0]));
2689     }
2690     else if (modules_count >= modules_allocated)
2691     {
2692         modules_allocated *= 2;
2693         modules_vector = xnrealloc (modules_vector,
2694                                     modules_allocated,
2695                                     sizeof (modules_vector[0]));
2696     }
2697     modules_vector[modules_count] = xstrdup (args);
2698     ++modules_count;
2699 }
2700
2701
2702
2703 /* Original, not "expanded" modules.  */
2704 static int module_argc;
2705 static char **module_argv;
2706
2707 void
2708 client_expand_modules (int argc, char **argv, int local)
2709 {
2710     int errs;
2711     int i;
2712
2713     module_argc = argc;
2714     module_argv = xnmalloc (argc + 1, sizeof (module_argv[0]));
2715     for (i = 0; i < argc; ++i)
2716         module_argv[i] = xstrdup (argv[i]);
2717     module_argv[argc] = NULL;
2718
2719     for (i = 0; i < argc; ++i)
2720         send_arg (argv[i]);
2721     send_a_repository ("", current_parsed_root->directory, "");
2722
2723     send_to_server ("expand-modules\012", 0);
2724
2725     errs = get_server_responses ();
2726
2727     if (last_repos) free (last_repos);
2728     last_repos = NULL;
2729
2730     if (last_update_dir) free (last_update_dir);
2731     last_update_dir = NULL;
2732
2733     if (errs)
2734         error (errs, 0, "cannot expand modules");
2735 }
2736
2737
2738
2739 void
2740 client_send_expansions (int local, char *where, int build_dirs)
2741 {
2742     int i;
2743     char *argv[1];
2744
2745     /* Send the original module names.  The "expanded" module name might
2746        not be suitable as an argument to a co request (e.g. it might be
2747        the result of a -d argument in the modules file).  It might be
2748        cleaner if we genuinely expanded module names, all the way to a
2749        local directory and repository, but that isn't the way it works
2750        now.  */
2751     send_file_names (module_argc, module_argv, 0);
2752
2753     for (i = 0; i < modules_count; ++i)
2754     {
2755         argv[0] = where ? where : modules_vector[i];
2756         if (isfile (argv[0]))
2757             send_files (1, argv, local, 0, build_dirs ? SEND_BUILD_DIRS : 0);
2758     }
2759     send_a_repository ("", current_parsed_root->directory, "");
2760 }
2761
2762
2763
2764 void
2765 client_nonexpanded_setup (void)
2766 {
2767     send_a_repository ("", current_parsed_root->directory, "");
2768 }
2769
2770
2771
2772 /* Receive a cvswrappers line from the server; it must be a line
2773    containing an RCS option (e.g., "*.exe   -k 'b'").
2774
2775    Note that this doesn't try to handle -t/-f options (which are a
2776    whole separate issue which noone has thought much about, as far
2777    as I know).
2778
2779    We need to know the keyword expansion mode so we know whether to
2780    read the file in text or binary mode.  */
2781 static void
2782 handle_wrapper_rcs_option (char *args, size_t len)
2783 {
2784     char *p;
2785
2786     /* Enforce the notes in cvsclient.texi about how the response is not
2787        as free-form as it looks.  */
2788     p = strchr (args, ' ');
2789     if (!p)
2790         goto handle_error;
2791     if (*++p != '-'
2792         || *++p != 'k'
2793         || *++p != ' '
2794         || *++p != '\'')
2795         goto handle_error;
2796     if (!strchr (p, '\''))
2797         goto handle_error;
2798
2799     /* Add server-side cvswrappers line to our wrapper list. */
2800     wrap_add (args, 0);
2801     return;
2802  handle_error:
2803     error (0, errno, "protocol error: ignoring invalid wrappers %s", args);
2804 }
2805
2806
2807
2808
2809 static void
2810 handle_m (char *args, size_t len)
2811 {
2812     /* In the case where stdout and stderr point to the same place,
2813        fflushing stderr will make output happen in the correct order.
2814        Often stderr will be line-buffered and this won't be needed,
2815        but not always (is that true?  I think the comment is probably
2816        based on being confused between default buffering between
2817        stdout and stderr.  But I'm not sure).  */
2818     fflush (stderr);
2819     fwrite (args, sizeof *args, len, stdout);
2820     putc ('\n', stdout);
2821 }
2822
2823
2824
2825 static void
2826 handle_mbinary (char *args, size_t len)
2827 {
2828     char *size_string;
2829     size_t size;
2830     size_t totalread;
2831     size_t nread;
2832     size_t toread;
2833     char buf[8192];
2834
2835     /* See comment at handle_m about (non)flush of stderr.  */
2836
2837     /* Get the size.  */
2838     read_line (&size_string);
2839     size = atoi (size_string);
2840     free (size_string);
2841
2842     /* OK, now get all the data.  The algorithm here is that we read
2843        as much as the network wants to give us in
2844        try_read_from_server, and then we output it all, and then
2845        repeat, until we get all the data.  */
2846     totalread = 0;
2847     while (totalread < size)
2848     {
2849         toread = size - totalread;
2850         if (toread > sizeof buf)
2851             toread = sizeof buf;
2852
2853         nread = try_read_from_server (buf, toread);
2854         cvs_output_binary (buf, nread);
2855         totalread += nread;
2856     }
2857 }
2858
2859
2860
2861 static void
2862 handle_e (char *args, size_t len)
2863 {
2864     /* In the case where stdout and stderr point to the same place,
2865        fflushing stdout will make output happen in the correct order.  */
2866     fflush (stdout);
2867     fwrite (args, sizeof *args, len, stderr);
2868     putc ('\n', stderr);
2869 }
2870
2871
2872
2873 /*ARGSUSED*/
2874 static void
2875 handle_f  (char *args, size_t len)
2876 {
2877     fflush (stderr);
2878 }
2879
2880
2881
2882 static void
2883 handle_mt (char *args, size_t len)
2884 {
2885     char *p;
2886     char *tag = args;
2887     char *text;
2888
2889     /* See comment at handle_m for more details.  */
2890     fflush (stderr);
2891
2892     p = strchr (args, ' ');
2893     if (!p)
2894         text = NULL;
2895     else
2896     {
2897         *p++ = '\0';
2898         text = p;
2899     }
2900
2901     switch (tag[0])
2902     {
2903         case '+':
2904             if (!strcmp (tag, "+updated"))
2905                 updated_seen = 1;
2906             else if (!strcmp (tag, "+importmergecmd"))
2907                 importmergecmd.seen = 1;
2908             break;
2909         case '-':
2910             if (!strcmp (tag, "-updated"))
2911                 updated_seen = 0;
2912             else if (!strcmp (tag, "-importmergecmd"))
2913             {
2914                 char buf[80];
2915
2916                 /* Now that we have gathered the information, we can
2917                    output the suggested merge command.  */
2918
2919                 if (importmergecmd.conflicts == 0
2920                     || !importmergecmd.mergetag1
2921                     || !importmergecmd.mergetag2
2922                     || !importmergecmd.repository)
2923                 {
2924                     error (0, 0,
2925                            "invalid server: incomplete importmergecmd tags");
2926                     break;
2927                 }
2928
2929                 if (importmergecmd.conflicts == -1)
2930                     sprintf (buf, "\nNo conflicts created by this import.\n");
2931                 else
2932                     sprintf (buf, "\n%d conflicts created by this import.\n",
2933                              importmergecmd.conflicts);
2934                 cvs_output (buf, 0);
2935                 cvs_output ("Use the following command to help the merge:\n\n",
2936                             0);
2937                 cvs_output ("\t", 1);
2938                 cvs_output (program_name, 0);
2939                 if (CVSroot_cmdline)
2940                 {
2941                     cvs_output (" -d ", 0);
2942                     cvs_output (CVSroot_cmdline, 0);
2943                 }
2944                 cvs_output (" checkout -j", 0);
2945                 cvs_output (importmergecmd.mergetag1, 0);
2946                 cvs_output (" -j", 0);
2947                 cvs_output (importmergecmd.mergetag2, 0);
2948                 cvs_output (" ", 1);
2949                 cvs_output (importmergecmd.repository, 0);
2950                 cvs_output ("\n\n", 0);
2951
2952                 /* Clear the static variables so that everything is
2953                    ready for any subsequent importmergecmd tag.  */
2954                 importmergecmd.conflicts = 0;
2955                 free (importmergecmd.mergetag1);
2956                 importmergecmd.mergetag1 = NULL;
2957                 free (importmergecmd.mergetag2);
2958                 importmergecmd.mergetag2 = NULL;
2959                 free (importmergecmd.repository);
2960                 importmergecmd.repository = NULL;
2961
2962                 importmergecmd.seen = 0;
2963             }
2964             break;
2965         default:
2966             if (updated_seen)
2967             {
2968                 if (!strcmp (tag, "fname"))
2969                 {
2970                     if (updated_fname)
2971                     {
2972                         /* Output the previous message now.  This can happen
2973                            if there was no Update-existing or other such
2974                            response, due to the -n global option.  */
2975                         cvs_output ("U ", 0);
2976                         cvs_output (updated_fname, 0);
2977                         cvs_output ("\n", 1);
2978                         free (updated_fname);
2979                     }
2980                     updated_fname = xstrdup (text);
2981                 }
2982                 /* Swallow all other tags.  Either they are extraneous
2983                    or they reflect future extensions that we can
2984                    safely ignore.  */
2985             }
2986             else if (importmergecmd.seen)
2987             {
2988                 if (!strcmp (tag, "conflicts"))
2989                 {
2990                     if (!strcmp (text, "No"))
2991                         importmergecmd.conflicts = -1;
2992                     else
2993                         importmergecmd.conflicts = atoi (text);
2994                 }
2995                 else if (!strcmp (tag, "mergetag1"))
2996                     importmergecmd.mergetag1 = xstrdup (text);
2997                 else if (!strcmp (tag, "mergetag2"))
2998                     importmergecmd.mergetag2 = xstrdup (text);
2999                 else if (!strcmp (tag, "repository"))
3000                     importmergecmd.repository = xstrdup (text);
3001                 /* Swallow all other tags.  Either they are text for
3002                    which we are going to print our own version when we
3003                    see -importmergecmd, or they are future extensions
3004                    we can safely ignore.  */
3005             }
3006             else if (!strcmp (tag, "newline"))
3007                 printf ("\n");
3008             else if (!strcmp (tag, "date"))
3009             {
3010                 char *date = format_date_alloc (text);
3011                 printf ("%s", date);
3012                 free (date);
3013             }
3014             else if (text)
3015                 printf ("%s", text);
3016     }
3017 }
3018
3019
3020
3021 #endif /* CLIENT_SUPPORT */
3022 #if defined(CLIENT_SUPPORT) || defined(SERVER_SUPPORT)
3023
3024 /* This table must be writeable if the server code is included.  */
3025 struct response responses[] =
3026 {
3027 #ifdef CLIENT_SUPPORT
3028 #define RSP_LINE(n, f, t, s) {n, f, t, s}
3029 #else /* ! CLIENT_SUPPORT */
3030 #define RSP_LINE(n, f, t, s) {n, s}
3031 #endif /* CLIENT_SUPPORT */
3032
3033     RSP_LINE("ok", handle_ok, response_type_ok, rs_essential),
3034     RSP_LINE("error", handle_error, response_type_error, rs_essential),
3035     RSP_LINE("Valid-requests", handle_valid_requests, response_type_normal,
3036        rs_essential),
3037     RSP_LINE("Force-gzip", handle_force_gzip, response_type_normal,
3038        rs_optional),
3039     RSP_LINE("Referrer", handle_referrer, response_type_normal, rs_optional),
3040     RSP_LINE("Redirect", handle_redirect, response_type_redirect, rs_optional),
3041     RSP_LINE("Checked-in", handle_checked_in, response_type_normal,
3042        rs_essential),
3043     RSP_LINE("New-entry", handle_new_entry, response_type_normal, rs_optional),
3044     RSP_LINE("Checksum", handle_checksum, response_type_normal, rs_optional),
3045     RSP_LINE("Copy-file", handle_copy_file, response_type_normal, rs_optional),
3046     RSP_LINE("Updated", handle_updated, response_type_normal, rs_essential),
3047     RSP_LINE("Created", handle_created, response_type_normal, rs_optional),
3048     RSP_LINE("Update-existing", handle_update_existing, response_type_normal,
3049        rs_optional),
3050     RSP_LINE("Merged", handle_merged, response_type_normal, rs_essential),
3051     RSP_LINE("Patched", handle_patched, response_type_normal, rs_optional),
3052     RSP_LINE("Rcs-diff", handle_rcs_diff, response_type_normal, rs_optional),
3053     RSP_LINE("Mode", handle_mode, response_type_normal, rs_optional),
3054     RSP_LINE("Mod-time", handle_mod_time, response_type_normal, rs_optional),
3055     RSP_LINE("Removed", handle_removed, response_type_normal, rs_essential),
3056     RSP_LINE("Remove-entry", handle_remove_entry, response_type_normal,
3057        rs_optional),
3058     RSP_LINE("Set-static-directory", handle_set_static_directory,
3059        response_type_normal,
3060        rs_optional),
3061     RSP_LINE("Clear-static-directory", handle_clear_static_directory,
3062        response_type_normal,
3063        rs_optional),
3064     RSP_LINE("Set-sticky", handle_set_sticky, response_type_normal,
3065        rs_optional),
3066     RSP_LINE("Clear-sticky", handle_clear_sticky, response_type_normal,
3067        rs_optional),
3068     RSP_LINE("Edit-file", handle_edit_file, response_type_normal,
3069        rs_optional),
3070     RSP_LINE("Template", handle_template, response_type_normal,
3071        rs_optional),
3072     RSP_LINE("Clear-template", handle_clear_template, response_type_normal,
3073        rs_optional),
3074     RSP_LINE("Notified", handle_notified, response_type_normal, rs_optional),
3075     RSP_LINE("Module-expansion", handle_module_expansion, response_type_normal,
3076        rs_optional),
3077     RSP_LINE("Wrapper-rcsOption", handle_wrapper_rcs_option,
3078        response_type_normal,
3079        rs_optional),
3080     RSP_LINE("M", handle_m, response_type_normal, rs_essential),
3081     RSP_LINE("Mbinary", handle_mbinary, response_type_normal, rs_optional),
3082     RSP_LINE("LOGM", handle_m, response_type_normal, rs_optional),
3083     RSP_LINE("E", handle_e, response_type_normal, rs_essential),
3084     RSP_LINE("F", handle_f, response_type_normal, rs_optional),
3085     RSP_LINE("MT", handle_mt, response_type_normal, rs_optional),
3086     /* Possibly should be response_type_error.  */
3087     RSP_LINE(NULL, NULL, response_type_normal, rs_essential)
3088
3089 #undef RSP_LINE
3090 };
3091
3092 #endif /* CLIENT_SUPPORT or SERVER_SUPPORT */
3093 #ifdef CLIENT_SUPPORT
3094
3095
3096
3097 /* 
3098  * If LEN is 0, then send_to_server_via() computes string's length itself.
3099  *
3100  * Therefore, pass the real length when transmitting data that might
3101  * contain 0's.
3102  */
3103 void
3104 send_to_server_via (struct buffer *via_buffer, const char *str, size_t len)
3105 {
3106     static int nbytes;
3107
3108     if (len == 0)
3109         len = strlen (str);
3110
3111     buf_output (via_buffer, str, len);
3112       
3113     /* There is no reason not to send data to the server, so do it
3114        whenever we've accumulated enough information in the buffer to
3115        make it worth sending.  */
3116     nbytes += len;
3117     if (nbytes >= 2 * BUFFER_DATA_SIZE)
3118     {
3119         int status;
3120
3121         status = buf_send_output (via_buffer);
3122         if (status != 0)
3123             error (1, status, "error writing to server");
3124         nbytes = 0;
3125     }
3126 }
3127
3128
3129
3130 void
3131 send_to_server (const char *str, size_t len)
3132 {
3133   send_to_server_via (global_to_server, str, len);
3134 }
3135
3136
3137
3138 /* Read up to LEN bytes from the server.  Returns actual number of
3139    bytes read, which will always be at least one; blocks if there is
3140    no data available at all.  Gives a fatal error on EOF or error.  */
3141 static size_t
3142 try_read_from_server( char *buf, size_t len )
3143 {
3144     int status;
3145     size_t nread;
3146     char *data;
3147
3148     status = buf_read_data (global_from_server, len, &data, &nread);
3149     if (status != 0)
3150     {
3151         if (status == -1)
3152             error (1, 0,
3153                    "end of file from server (consult above messages if any)");
3154         else if (status == -2)
3155             error (1, 0, "out of memory");
3156         else
3157             error (1, status, "reading from server");
3158     }
3159
3160     memcpy (buf, data, nread);
3161
3162     return nread;
3163 }
3164
3165
3166
3167 /*
3168  * Read LEN bytes from the server or die trying.
3169  */
3170 void
3171 read_from_server (char *buf, size_t len)
3172 {
3173     size_t red = 0;
3174     while (red < len)
3175     {
3176         red += try_read_from_server (buf + red, len - red);
3177         if (red == len)
3178             break;
3179     }
3180 }
3181
3182
3183
3184 /* Get some server responses and process them.
3185  *
3186  * RETURNS
3187  *   0          Success
3188  *   1          Error
3189  *   2          Redirect
3190  */
3191 int
3192 get_server_responses (void)
3193 {
3194     struct response *rs;
3195     do
3196     {
3197         char *cmd;
3198         size_t len;
3199         
3200         len = read_line (&cmd);
3201         for (rs = responses; rs->name; ++rs)
3202             if (!strncmp (cmd, rs->name, strlen (rs->name)))
3203             {
3204                 size_t cmdlen = strlen (rs->name);
3205                 if (cmd[cmdlen] == '\0')
3206                     ;
3207                 else if (cmd[cmdlen] == ' ')
3208                     ++cmdlen;
3209                 else
3210                     /*
3211                      * The first len characters match, but it's a different
3212                      * response.  e.g. the response is "oklahoma" but we
3213                      * matched "ok".
3214                      */
3215                     continue;
3216                 (*rs->func) (cmd + cmdlen, len - cmdlen);
3217                 break;
3218             }
3219         if (!rs->name)
3220             /* It's OK to print just to the first '\0'.  */
3221             /* We might want to handle control characters and the like
3222                in some other way other than just sending them to stdout.
3223                One common reason for this error is if people use :ext:
3224                with a version of rsh which is doing CRLF translation or
3225                something, and so the client gets "ok^M" instead of "ok".
3226                Right now that will tend to print part of this error
3227                message over the other part of it.  It seems like we could
3228                do better (either in general, by quoting or omitting all
3229                control characters, and/or specifically, by detecting the CRLF
3230                case and printing a specific error message).  */
3231             error (0, 0,
3232                    "warning: unrecognized response `%s' from cvs server",
3233                    cmd);
3234         free (cmd);
3235     } while (rs->type == response_type_normal);
3236
3237     if (updated_fname)
3238     {
3239         /* Output the previous message now.  This can happen
3240            if there was no Update-existing or other such
3241            response, due to the -n global option.  */
3242         cvs_output ("U ", 0);
3243         cvs_output (updated_fname, 0);
3244         cvs_output ("\n", 1);
3245         free (updated_fname);
3246         updated_fname = NULL;
3247     }
3248
3249     if (rs->type == response_type_redirect) return 2;
3250     if (rs->type == response_type_error) return 1;
3251     if (failure_exit) return 1;
3252     return 0;
3253 }
3254
3255
3256
3257 static inline void
3258 close_connection_to_server (struct buffer **to, struct buffer **from)
3259 {
3260     int status;
3261
3262     /* First we shut down GLOBAL_TO_SERVER.  That tells the server that its
3263      * input is finished.  It then shuts down the buffer it is sending to us,
3264      * at which point our shut down of GLOBAL_FROM_SERVER will complete.
3265      */
3266
3267     TRACE (TRACE_FUNCTION, "close_connection_to_server ()");
3268
3269     status = buf_shutdown (*to);
3270     if (status != 0)
3271         error (0, status, "shutting down buffer to server");
3272     buf_free (*to);
3273     *to = NULL;
3274
3275     status = buf_shutdown (*from);
3276     if (status != 0)
3277         error (0, status, "shutting down buffer from server");
3278     buf_free (*from);
3279     *from = NULL;
3280 }
3281
3282
3283
3284 /* Get the responses and then close the connection.  */
3285
3286 /*
3287  * Flag var; we'll set it in start_server() and not one of its
3288  * callees, such as start_rsh_server().  This means that there might
3289  * be a small window between the starting of the server and the
3290  * setting of this var, but all the code in that window shouldn't care
3291  * because it's busy checking return values to see if the server got
3292  * started successfully anyway.
3293  */
3294 int server_started = 0;
3295
3296 int
3297 get_responses_and_close (void)
3298 {
3299     int errs = get_server_responses ();
3300
3301     /* The following is necessary when working with multiple cvsroots, at least
3302      * with commit.  It used to be buried nicely in do_deferred_progs() before
3303      * that function was removed.  I suspect it wouldn't be necessary if
3304      * call_in_directory() saved its working directory via save_cwd() before
3305      * changing its directory and restored the saved working directory via
3306      * restore_cwd() before exiting.  Of course, calling CVS_CHDIR only once,
3307      * here, may be more efficient.
3308      */
3309     if (toplevel_wd)
3310     {
3311         if (CVS_CHDIR (toplevel_wd) < 0)
3312             error (1, errno, "could not chdir to %s", toplevel_wd);
3313     }
3314
3315     if (client_prune_dirs)
3316         process_prune_candidates ();
3317
3318     close_connection_to_server (&global_to_server, &global_from_server);
3319     server_started = 0;
3320
3321     /* see if we need to sleep before returning to avoid time-stamp races */
3322     if (last_register_time)
3323         sleep_past (last_register_time);
3324
3325     return errs;
3326 }
3327
3328
3329
3330 bool
3331 supported_request (const char *name)
3332 {
3333     struct request *rq;
3334
3335     for (rq = requests; rq->name; rq++)
3336         if (!strcmp (rq->name, name))
3337             return (rq->flags & RQ_SUPPORTED) != 0;
3338     error (1, 0, "internal error: testing support for unknown request?");
3339     /* NOTREACHED */
3340     return 0;
3341 }
3342
3343
3344
3345 #if defined (AUTH_CLIENT_SUPPORT) || defined (SERVER_SUPPORT) || defined (HAVE_KERBEROS) || defined (HAVE_GSSAPI)
3346
3347
3348 /* Generic function to do port number lookup tasks.
3349  *
3350  * In order of precedence, will return:
3351  *      getenv (envname), if defined
3352  *      getservbyname (portname), if defined
3353  *      defaultport
3354  */
3355 static int
3356 get_port_number (const char *envname, const char *portname, int defaultport)
3357 {
3358     struct servent *s;
3359     char *port_s;
3360
3361     if (envname && (port_s = getenv (envname)) && *port_s)
3362     {
3363         int port = atoi (port_s);
3364         if (port <= 0)
3365         {
3366             error (0, 0, "%s must be a positive integer!  If you", envname);
3367             error (0, 0, "are trying to force a connection via rsh, please");
3368             error (0, 0, "put \":server:\" at the beginning of your CVSROOT");
3369             error (1, 0, "variable.");
3370         }
3371         return port;
3372     }
3373     else if (portname && (s = getservbyname (portname, "tcp")))
3374         return ntohs (s->s_port);
3375     else
3376         return defaultport;
3377 }
3378
3379
3380
3381 /* get the port number for a client to connect to based on the port
3382  * and method of a cvsroot_t.
3383  *
3384  * we do this here instead of in parse_cvsroot so that we can keep network
3385  * code confined to a localized area and also to delay the lookup until the
3386  * last possible moment so it remains possible to run cvs client commands that
3387  * skip opening connections to the server (i.e. skip network operations
3388  * entirely)
3389  *
3390  * and yes, I know none of the commands do that now, but here's to planning
3391  * for the future, eh?  cheers.
3392  */
3393 int
3394 get_cvs_port_number (const cvsroot_t *root)
3395 {
3396
3397     if (root->port) return root->port;
3398
3399     switch (root->method)
3400     {
3401 # ifdef HAVE_GSSAPI
3402         case gserver_method:
3403 # endif /* HAVE_GSSAPI */
3404 # ifdef AUTH_CLIENT_SUPPORT
3405         case pserver_method:
3406 # endif /* AUTH_CLIENT_SUPPORT */
3407 # if defined (AUTH_CLIENT_SUPPORT) || defined (HAVE_GSSAPI)
3408             return get_port_number ("CVS_CLIENT_PORT", "cvspserver",
3409                                     CVS_AUTH_PORT);
3410 # endif /* defined (AUTH_CLIENT_SUPPORT) || defined (HAVE_GSSAPI) */
3411 # ifdef HAVE_KERBEROS
3412         case kserver_method:
3413             return get_port_number ("CVS_CLIENT_PORT", "cvs", CVS_PORT);
3414 # endif /* HAVE_KERBEROS */
3415         default:
3416             error(1, EINVAL,
3417 "internal error: get_cvs_port_number called for invalid connection method (%s)",
3418                   method_names[root->method]);
3419             break;
3420     }
3421     /* NOTREACHED */
3422     return -1;
3423 }
3424
3425
3426
3427 /* get the port number for a client to connect to based on the proxy port
3428  * of a cvsroot_t.
3429  */
3430 static int
3431 get_proxy_port_number (const cvsroot_t *root)
3432 {
3433
3434     if (root->proxy_port) return root->proxy_port;
3435
3436     return get_port_number ("CVS_PROXY_PORT", NULL, CVS_PROXY_PORT);
3437 }
3438
3439
3440
3441 void
3442 make_bufs_from_fds(int tofd, int fromfd, int child_pid, cvsroot_t *root,
3443                    struct buffer **to_server_p,
3444                    struct buffer **from_server_p, int is_sock)
3445 {
3446 # ifdef NO_SOCKET_TO_FD
3447     if (is_sock)
3448     {
3449         assert (tofd == fromfd);
3450         *to_server_p = socket_buffer_initialize (tofd, 0, NULL);
3451         *from_server_p = socket_buffer_initialize (tofd, 1, NULL);
3452     }
3453     else
3454 # endif /* NO_SOCKET_TO_FD */
3455     {
3456         /* todo: some OS's don't need these calls... */
3457         close_on_exec (tofd);
3458         close_on_exec (fromfd);
3459
3460         /* SCO 3 and AIX have a nasty bug in the I/O libraries which precludes
3461            fdopening the same file descriptor twice, so dup it if it is the
3462            same.  */
3463         if (tofd == fromfd)
3464         {
3465             fromfd = dup (tofd);
3466             if (fromfd < 0)
3467                 error (1, errno, "cannot dup net connection");
3468         }
3469
3470         /* These will use binary mode on systems which have it.  */
3471         /*
3472          * Also, we know that from_server is shut down second, so we pass
3473          * child_pid in there.  In theory, it should be stored in both
3474          * buffers with a ref count...
3475          */
3476         *to_server_p = fd_buffer_initialize (tofd, 0, root, false, NULL);
3477         *from_server_p = fd_buffer_initialize (fromfd, child_pid, root,
3478                                                true, NULL);
3479     }
3480 }
3481 #endif /* defined (AUTH_CLIENT_SUPPORT) || defined (SERVER_SUPPORT) || defined (HAVE_KERBEROS) || defined(HAVE_GSSAPI) */
3482
3483
3484
3485 #if defined (AUTH_CLIENT_SUPPORT) || defined(HAVE_GSSAPI)
3486 /* Connect to the authenticating server.
3487
3488    If VERIFY_ONLY is non-zero, then just verify that the password is
3489    correct and then shutdown the connection.
3490
3491    If VERIFY_ONLY is 0, then really connect to the server.
3492
3493    If DO_GSSAPI is non-zero, then we use GSSAPI authentication rather
3494    than the pserver password authentication.
3495
3496    If we fail to connect or if access is denied, then die with fatal
3497    error.  */
3498 void
3499 connect_to_pserver (cvsroot_t *root, struct buffer **to_server_p,
3500                     struct buffer **from_server_p, int verify_only,
3501                     int do_gssapi)
3502 {
3503     int sock;
3504     int port_number,
3505         proxy_port_number = 0; /* Initialize to silence -Wall.  Dumb.  */
3506     union sai {
3507         struct sockaddr_in addr_in;
3508         struct sockaddr addr;
3509     } client_sai;
3510     struct hostent *hostinfo;
3511     struct buffer *to_server, *from_server;
3512
3513     sock = socket (AF_INET, SOCK_STREAM, 0);
3514     if (sock == -1)
3515         error (1, 0, "cannot create socket: %s", SOCK_STRERROR (SOCK_ERRNO));
3516
3517 #ifdef TCP_NODELAY
3518     /* Avoid latency due to Nagle algorithm.  */
3519     {
3520         int on = 1;
3521
3522         if (setsockopt (sock, IPPROTO_TCP, TCP_NODELAY, &on, sizeof on) < 0)
3523             error (0, errno, "warning: cannot set TCP_NODELAY on socket");
3524     }
3525 #endif
3526
3527     port_number = get_cvs_port_number (root);
3528
3529     /* if we have a proxy connect to that instead */
3530     if (root->proxy_hostname)
3531     {
3532         proxy_port_number = get_proxy_port_number (root);
3533         hostinfo = init_sockaddr (&client_sai.addr_in, root->proxy_hostname,
3534                                   proxy_port_number);
3535         TRACE (TRACE_FUNCTION, "Connecting to %s:%d via proxy %s(%s):%d.",
3536                root->hostname, port_number, root->proxy_hostname,
3537                inet_ntoa (client_sai.addr_in.sin_addr), proxy_port_number);
3538     }
3539     else
3540     {
3541         hostinfo = init_sockaddr (&client_sai.addr_in, root->hostname,
3542                                   port_number);
3543         TRACE (TRACE_FUNCTION, "Connecting to %s(%s):%d.",
3544                root->hostname,
3545                inet_ntoa (client_sai.addr_in.sin_addr), port_number);
3546     }
3547
3548     if (connect (sock, &client_sai.addr, sizeof (client_sai))
3549         < 0)
3550         error (1, 0, "connect to %s(%s):%d failed: %s",
3551                root->proxy_hostname ? root->proxy_hostname : root->hostname,
3552                inet_ntoa (client_sai.addr_in.sin_addr),
3553                root->proxy_hostname ? proxy_port_number : port_number,
3554                SOCK_STRERROR (SOCK_ERRNO));
3555
3556     make_bufs_from_fds (sock, sock, 0, root, &to_server, &from_server, 1);
3557
3558     /* if we have proxy then connect to the proxy first */
3559     if (root->proxy_hostname)
3560     {
3561 #define CONNECT_STRING "CONNECT %s:%d HTTP/1.0\r\n\r\n"
3562         /* Send a "CONNECT" command to proxy: */
3563         char* read_buf;
3564         int codenum;
3565         size_t count;
3566         /* 4 characters for port covered by the length of %s & %d */
3567         char* write_buf = Xasnprintf (NULL, &count, CONNECT_STRING,
3568                                       root->hostname, port_number);
3569         send_to_server_via (to_server, write_buf, count);
3570
3571         /* Wait for HTTP status code, bail out if you don't get back a 2xx
3572          * code.
3573          */
3574         read_line_via (from_server, to_server, &read_buf);
3575         count = sscanf (read_buf, "%*s %d", &codenum);
3576
3577         if (count != 1 || (codenum / 100) != 2)
3578             error (1, 0, "proxy server %s:%d does not support http tunnelling",
3579                    root->proxy_hostname, proxy_port_number);
3580         free (read_buf);
3581         free (write_buf);
3582
3583         /* Skip through remaining part of MIME header, recv_line
3584            consumes the trailing \n */
3585         while (read_line_via (from_server, to_server, &read_buf) > 0)
3586         {
3587             if (read_buf[0] == '\r' || read_buf[0] == 0)
3588             {
3589                 free (read_buf);
3590                 break;
3591             }
3592             free (read_buf);
3593         }
3594     }
3595
3596     auth_server (root, to_server, from_server, verify_only, do_gssapi,
3597                  hostinfo);
3598
3599     if (verify_only)
3600     {
3601         int status;
3602
3603         status = buf_shutdown (to_server);
3604         if (status != 0)
3605             error (0, status, "shutting down buffer to server");
3606         buf_free (to_server);
3607         to_server = NULL;
3608
3609         status = buf_shutdown (from_server);
3610         if (status != 0)
3611             error (0, status, "shutting down buffer from server");
3612         buf_free (from_server);
3613         from_server = NULL;
3614