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