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