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