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