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