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