xref: /openbsd-src/gnu/usr.bin/cvs/src/server.c (revision 3a3fbb3f2e2521ab7c4a56b7ff7462ebd9095ec5)
1 /* This program is free software; you can redistribute it and/or modify
2    it under the terms of the GNU General Public License as published by
3    the Free Software Foundation; either version 2, or (at your option)
4    any later version.
5 
6    This program is distributed in the hope that it will be useful,
7    but WITHOUT ANY WARRANTY; without even the implied warranty of
8    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
9    GNU General Public License for more details.  */
10 
11 #include <assert.h>
12 #include "cvs.h"
13 #include "watch.h"
14 #include "edit.h"
15 #include "fileattr.h"
16 #include "getline.h"
17 #include "buffer.h"
18 
19 #if defined(SERVER_SUPPORT) || defined(CLIENT_SUPPORT)
20 # ifdef HAVE_GSSAPI
21 /* This stuff isn't included solely with SERVER_SUPPORT since some of these
22  * functions (encryption & the like) get compiled with or without server
23  * support.
24  *
25  * FIXME - They should be in a different file.
26  */
27 #   include <netdb.h>
28 #   include "xgssapi.h"
29 /* We use Kerberos 5 routines to map the GSSAPI credential to a user
30    name.  */
31 #   include <krb5.h>
32 
33 /* We need this to wrap data.  */
34 static gss_ctx_id_t gcontext;
35 
36 static void gserver_authenticate_connection PROTO((void));
37 
38 /* Whether we are already wrapping GSSAPI communication.  */
39 static int cvs_gssapi_wrapping;
40 
41 #   ifdef ENCRYPTION
42 /* Whether to encrypt GSSAPI communication.  We use a global variable
43    like this because we use the same buffer type (gssapi_wrap) to
44    handle both authentication and encryption, and we don't want
45    multiple instances of that buffer in the communication stream.  */
46 int cvs_gssapi_encrypt;
47 #   endif
48 # endif	/* HAVE_GSSAPI */
49 #endif	/* defined(SERVER_SUPPORT) || defined(CLIENT_SUPPORT) */
50 
51 #ifdef SERVER_SUPPORT
52 
53 #ifdef HAVE_WINSOCK_H
54 #include <winsock.h>
55 #endif
56 
57 #if defined (AUTH_SERVER_SUPPORT) || defined (HAVE_KERBEROS) || defined (HAVE_GSSAPI)
58 #include <sys/socket.h>
59 #endif
60 
61 #ifdef HAVE_SYSLOG_H
62 #include <syslog.h>
63 #endif
64 
65 #ifdef HAVE_KERBEROS
66 # include <netinet/in.h>
67 # include <krb.h>
68 # ifndef HAVE_KRB_GET_ERR_TEXT
69 #   define krb_get_err_text(status) krb_err_txt[status]
70 # endif
71 
72 /* Information we need if we are going to use Kerberos encryption.  */
73 static C_Block kblock;
74 static Key_schedule sched;
75 
76 #endif
77 
78 /* for select */
79 #include "xselect.h"
80 
81 #ifndef O_NONBLOCK
82 #define O_NONBLOCK O_NDELAY
83 #endif
84 
85 /* EWOULDBLOCK is not defined by POSIX, but some BSD systems will
86    return it, rather than EAGAIN, for nonblocking writes.  */
87 #ifdef EWOULDBLOCK
88 #define blocking_error(err) ((err) == EWOULDBLOCK || (err) == EAGAIN)
89 #else
90 #define blocking_error(err) ((err) == EAGAIN)
91 #endif
92 
93 /* For initgroups().  */
94 #if HAVE_INITGROUPS
95 #include <grp.h>
96 #endif /* HAVE_INITGROUPS */
97 
98 # ifdef AUTH_SERVER_SUPPORT
99 
100 #   ifdef HAVE_GETSPNAM
101 #     include <shadow.h>
102 #   endif
103 
104 /* The cvs username sent by the client, which might or might not be
105    the same as the system username the server eventually switches to
106    run as.  CVS_Username gets set iff password authentication is
107    successful. */
108 char *CVS_Username = NULL;
109 
110 /* Used to check that same repos is transmitted in pserver auth and in
111    later CVS protocol.  Exported because root.c also uses. */
112 static char *Pserver_Repos = NULL;
113 
114 /* Should we check for system usernames/passwords?  Can be changed by
115    CVSROOT/config.  */
116 int system_auth = 1;
117 
118 # endif /* AUTH_SERVER_SUPPORT */
119 
120 
121 /* While processing requests, this buffer accumulates data to be sent to
122    the client, and then once we are in do_cvs_command, we use it
123    for all the data to be sent.  */
124 static struct buffer *buf_to_net;
125 
126 /* This buffer is used to read input from the client.  */
127 static struct buffer *buf_from_net;
128 
129 /*
130  * This is where we stash stuff we are going to use.  Format string
131  * which expects a single directory within it, starting with a slash.
132  */
133 static char *server_temp_dir;
134 
135 /* This is the original value of server_temp_dir, before any possible
136    changes inserted by serve_max_dotdot.  */
137 static char *orig_server_temp_dir;
138 
139 /* Nonzero if we should keep the temp directory around after we exit.  */
140 static int dont_delete_temp;
141 
142 static void server_write_entries PROTO((void));
143 
144 /* All server communication goes through buffer structures.  Most of
145    the buffers are built on top of a file descriptor.  This structure
146    is used as the closure field in a buffer.  */
147 
148 struct fd_buffer
149 {
150     /* The file descriptor.  */
151     int fd;
152     /* Nonzero if the file descriptor is in blocking mode.  */
153     int blocking;
154 };
155 
156 static struct buffer *fd_buffer_initialize
157   PROTO ((int, int, void (*) (struct buffer *)));
158 static int fd_buffer_input PROTO((void *, char *, int, int, int *));
159 static int fd_buffer_output PROTO((void *, const char *, int, int *));
160 static int fd_buffer_flush PROTO((void *));
161 static int fd_buffer_block PROTO((void *, int));
162 static int fd_buffer_shutdown PROTO((void *));
163 
164 /* Initialize a buffer built on a file descriptor.  FD is the file
165    descriptor.  INPUT is nonzero if this is for input, zero if this is
166    for output.  MEMORY is the function to call when a memory error
167    occurs.  */
168 
169 static struct buffer *
170 fd_buffer_initialize (fd, input, memory)
171      int fd;
172      int input;
173      void (*memory) PROTO((struct buffer *));
174 {
175     struct fd_buffer *n;
176 
177     n = (struct fd_buffer *) xmalloc (sizeof *n);
178     n->fd = fd;
179     n->blocking = 1;
180     return buf_initialize (input ? fd_buffer_input : NULL,
181 			   input ? NULL : fd_buffer_output,
182 			   input ? NULL : fd_buffer_flush,
183 			   fd_buffer_block,
184 			   fd_buffer_shutdown,
185 			   memory,
186 			   n);
187 }
188 
189 /* The buffer input function for a buffer built on a file descriptor.  */
190 
191 static int
192 fd_buffer_input (closure, data, need, size, got)
193      void *closure;
194      char *data;
195      int need;
196      int size;
197      int *got;
198 {
199     struct fd_buffer *fd = (struct fd_buffer *) closure;
200     int nbytes;
201 
202     if (! fd->blocking)
203 	nbytes = read (fd->fd, data, size);
204     else
205     {
206 	/* This case is not efficient.  Fortunately, I don't think it
207            ever actually happens.  */
208 	nbytes = read (fd->fd, data, need == 0 ? 1 : need);
209     }
210 
211     if (nbytes > 0)
212     {
213 	*got = nbytes;
214 	return 0;
215     }
216 
217     *got = 0;
218 
219     if (nbytes == 0)
220     {
221 	/* End of file.  This assumes that we are using POSIX or BSD
222            style nonblocking I/O.  On System V we will get a zero
223            return if there is no data, even when not at EOF.  */
224 	return -1;
225     }
226 
227     /* Some error occurred.  */
228 
229     if (blocking_error (errno))
230     {
231 	/* Everything's fine, we just didn't get any data.  */
232 	return 0;
233     }
234 
235     return errno;
236 }
237 
238 /* The buffer output function for a buffer built on a file descriptor.  */
239 
240 static int
241 fd_buffer_output (closure, data, have, wrote)
242      void *closure;
243      const char *data;
244      int have;
245      int *wrote;
246 {
247     struct fd_buffer *fd = (struct fd_buffer *) closure;
248 
249     *wrote = 0;
250 
251     while (have > 0)
252     {
253 	int nbytes;
254 
255 	nbytes = write (fd->fd, data, have);
256 
257 	if (nbytes <= 0)
258 	{
259 	    if (! fd->blocking
260 		&& (nbytes == 0 || blocking_error (errno)))
261 	    {
262 		/* A nonblocking write failed to write any data.  Just
263                    return.  */
264 		return 0;
265 	    }
266 
267 	    /* Some sort of error occurred.  */
268 
269 	    if (nbytes == 0)
270 	        return EIO;
271 
272 	    return errno;
273 	}
274 
275 	*wrote += nbytes;
276 	data += nbytes;
277 	have -= nbytes;
278     }
279 
280     return 0;
281 }
282 
283 /* The buffer flush function for a buffer built on a file descriptor.  */
284 
285 /*ARGSUSED*/
286 static int
287 fd_buffer_flush (closure)
288      void *closure;
289 {
290     /* Nothing to do.  File descriptors are always flushed.  */
291     return 0;
292 }
293 
294 /* The buffer block function for a buffer built on a file descriptor.  */
295 
296 static int
297 fd_buffer_block (closure, block)
298      void *closure;
299      int block;
300 {
301     struct fd_buffer *fd = (struct fd_buffer *) closure;
302     int flags;
303 
304     flags = fcntl (fd->fd, F_GETFL, 0);
305     if (flags < 0)
306 	return errno;
307 
308     if (block)
309 	flags &= ~O_NONBLOCK;
310     else
311 	flags |= O_NONBLOCK;
312 
313     if (fcntl (fd->fd, F_SETFL, flags) < 0)
314         return errno;
315 
316     fd->blocking = block;
317 
318     return 0;
319 }
320 
321 /* The buffer shutdown function for a buffer built on a file descriptor.  */
322 
323 static int
324 fd_buffer_shutdown (closure)
325      void *closure;
326 {
327     free (closure);
328     return 0;
329 }
330 
331 /* Populate all of the directories between BASE_DIR and its relative
332    subdirectory DIR with CVSADM directories.  Return 0 for success or
333    errno value.  */
334 static int create_adm_p PROTO((char *, char *));
335 
336 static int
337 create_adm_p (base_dir, dir)
338     char *base_dir;
339     char *dir;
340 {
341     char *dir_where_cvsadm_lives, *dir_to_register, *p, *tmp;
342     int retval, done;
343     FILE *f;
344 
345     if (strcmp (dir, ".") == 0)
346 	return 0;			/* nothing to do */
347 
348     /* Allocate some space for our directory-munging string. */
349     p = malloc (strlen (dir) + 1);
350     if (p == NULL)
351 	return ENOMEM;
352 
353     dir_where_cvsadm_lives = malloc (strlen (base_dir) + strlen (dir) + 100);
354     if (dir_where_cvsadm_lives == NULL)
355 	return ENOMEM;
356 
357     /* Allocate some space for the temporary string in which we will
358        construct filenames. */
359     tmp = malloc (strlen (base_dir) + strlen (dir) + 100);
360     if (tmp == NULL)
361 	return ENOMEM;
362 
363 
364     /* We make several passes through this loop.  On the first pass,
365        we simply create the CVSADM directory in the deepest directory.
366        For each subsequent pass, we try to remove the last path
367        element from DIR, create the CVSADM directory in the remaining
368        pathname, and register the subdirectory in the newly created
369        CVSADM directory. */
370 
371     retval = done = 0;
372 
373     strcpy (p, dir);
374     strcpy (dir_where_cvsadm_lives, base_dir);
375     strcat (dir_where_cvsadm_lives, "/");
376     strcat (dir_where_cvsadm_lives, p);
377     dir_to_register = NULL;
378 
379     while (1)
380     {
381 	/* Create CVSADM. */
382 	(void) sprintf (tmp, "%s/%s", dir_where_cvsadm_lives, CVSADM);
383 	if ((CVS_MKDIR (tmp, 0777) < 0) && (errno != EEXIST))
384 	{
385 	    retval = errno;
386 	    goto finish;
387 	}
388 
389 	/* Create CVSADM_REP. */
390 	(void) sprintf (tmp, "%s/%s", dir_where_cvsadm_lives, CVSADM_REP);
391 	if (! isfile (tmp))
392 	{
393 	    /* Use Emptydir as the placeholder until the client sends
394 	       us the real value.  This code is similar to checkout.c
395 	       (emptydir_name), but the code below returns errors
396 	       differently.  */
397 
398 	    char *empty;
399 	    empty = malloc (strlen (current_parsed_root->directory)
400 			    + sizeof (CVSROOTADM)
401 			    + sizeof (CVSNULLREPOS)
402 			    + 3);
403 	    if (! empty)
404 	    {
405 		retval = ENOMEM;
406 		goto finish;
407 	    }
408 
409 	    /* Create the directory name. */
410 	    (void) sprintf (empty, "%s/%s/%s", current_parsed_root->directory,
411 			    CVSROOTADM, CVSNULLREPOS);
412 
413 	    /* Create the directory if it doesn't exist. */
414 	    if (! isfile (empty))
415 	    {
416 		mode_t omask;
417 		omask = umask (cvsumask);
418 		if (CVS_MKDIR (empty, 0777) < 0)
419 		{
420 		    retval = errno;
421 		    free (empty);
422 		    goto finish;
423 		}
424 		(void) umask (omask);
425 	    }
426 
427 
428 	    f = CVS_FOPEN (tmp, "w");
429 	    if (f == NULL)
430 	    {
431 		retval = errno;
432 		free (empty);
433 		goto finish;
434 	    }
435 	    /* Write the directory name to CVSADM_REP. */
436 	    if (fprintf (f, "%s\n", empty) < 0)
437 	    {
438 		retval = errno;
439 		fclose (f);
440 		free (empty);
441 		goto finish;
442 	    }
443 	    if (fclose (f) == EOF)
444 	    {
445 		retval = errno;
446 		free (empty);
447 		goto finish;
448 	    }
449 
450 	    /* Clean up after ourselves. */
451 	    free (empty);
452 	}
453 
454 	/* Create CVSADM_ENT.  We open in append mode because we
455 	   don't want to clobber an existing Entries file.  */
456 	(void) sprintf (tmp, "%s/%s", dir_where_cvsadm_lives, CVSADM_ENT);
457 	f = CVS_FOPEN (tmp, "a");
458 	if (f == NULL)
459 	{
460 	    retval = errno;
461 	    goto finish;
462 	}
463 	if (fclose (f) == EOF)
464 	{
465 	    retval = errno;
466 	    goto finish;
467 	}
468 
469 	if (dir_to_register != NULL)
470 	{
471 	    /* FIXME: Yes, this results in duplicate entries in the
472 	       Entries.Log file, but it doesn't currently matter.  We
473 	       might need to change this later on to make sure that we
474 	       only write one entry.  */
475 
476 	    Subdir_Register ((List *) NULL, dir_where_cvsadm_lives,
477 			     dir_to_register);
478 	}
479 
480 	if (done)
481 	    break;
482 
483 	dir_to_register = strrchr (p, '/');
484 	if (dir_to_register == NULL)
485 	{
486 	    dir_to_register = p;
487 	    strcpy (dir_where_cvsadm_lives, base_dir);
488 	    done = 1;
489 	}
490 	else
491 	{
492 	    *dir_to_register = '\0';
493 	    dir_to_register++;
494 	    strcpy (dir_where_cvsadm_lives, base_dir);
495 	    strcat (dir_where_cvsadm_lives, "/");
496 	    strcat (dir_where_cvsadm_lives, p);
497 	}
498     }
499 
500   finish:
501     free (tmp);
502     free (dir_where_cvsadm_lives);
503     free (p);
504     return retval;
505 }
506 
507 /*
508  * Make directory DIR, including all intermediate directories if necessary.
509  * Returns 0 for success or errno code.
510  */
511 static int mkdir_p PROTO((char *));
512 
513 static int
514 mkdir_p (dir)
515      char *dir;
516 {
517     char *p;
518     char *q = malloc (strlen (dir) + 1);
519     int retval;
520 
521     if (q == NULL)
522 	return ENOMEM;
523 
524     retval = 0;
525 
526     /*
527      * Skip over leading slash if present.  We won't bother to try to
528      * make '/'.
529      */
530     p = dir + 1;
531     while (1)
532     {
533 	while (*p != '/' && *p != '\0')
534 	    ++p;
535 	if (*p == '/')
536 	{
537 	    strncpy (q, dir, p - dir);
538 	    q[p - dir] = '\0';
539 	    if (q[p - dir - 1] != '/'  &&  CVS_MKDIR (q, 0777) < 0)
540 	    {
541 		int saved_errno = errno;
542 
543 		if (saved_errno != EEXIST
544 		    && ((saved_errno != EACCES && saved_errno != EROFS)
545 			|| !isdir (q)))
546 		{
547 		    retval = saved_errno;
548 		    goto done;
549 		}
550 	    }
551 	    ++p;
552 	}
553 	else
554 	{
555 	    if (CVS_MKDIR (dir, 0777) < 0)
556 		retval = errno;
557 	    goto done;
558 	}
559     }
560   done:
561     free (q);
562     return retval;
563 }
564 
565 /*
566  * Print the error response for error code STATUS.  The caller is
567  * reponsible for making sure we get back to the command loop without
568  * any further output occuring.
569  * Must be called only in contexts where it is OK to send output.
570  */
571 static void
572 print_error (status)
573     int status;
574 {
575     char *msg;
576     char tmpstr[80];
577 
578     buf_output0 (buf_to_net, "error  ");
579     msg = strerror (status);
580     if (msg == NULL)
581     {
582        sprintf (tmpstr, "unknown error %d", status);
583        msg = tmpstr;
584     }
585     buf_output0 (buf_to_net, msg);
586     buf_append_char (buf_to_net, '\n');
587 
588     buf_flush (buf_to_net, 0);
589 }
590 
591 static int pending_error;
592 /*
593  * Malloc'd text for pending error.  Each line must start with "E ".  The
594  * last line should not end with a newline.
595  */
596 static char *pending_error_text;
597 
598 /* If an error is pending, print it and return 1.  If not, return 0.
599    Must be called only in contexts where it is OK to send output.  */
600 static int
601 print_pending_error ()
602 {
603     if (pending_error_text)
604     {
605 	buf_output0 (buf_to_net, pending_error_text);
606 	buf_append_char (buf_to_net, '\n');
607 	if (pending_error)
608 	    print_error (pending_error);
609 	else
610 	    buf_output0 (buf_to_net, "error  \n");
611 
612 	buf_flush (buf_to_net, 0);
613 
614 	pending_error = 0;
615 	free (pending_error_text);
616 	pending_error_text = NULL;
617 	return 1;
618     }
619     else if (pending_error)
620     {
621 	print_error (pending_error);
622 	pending_error = 0;
623 	return 1;
624     }
625     else
626 	return 0;
627 }
628 
629 /* Is an error pending?  */
630 #define error_pending() (pending_error || pending_error_text)
631 
632 static int alloc_pending PROTO ((size_t size));
633 
634 /* Allocate SIZE bytes for pending_error_text and return nonzero
635    if we could do it.  */
636 static int
637 alloc_pending (size)
638     size_t size;
639 {
640     if (error_pending ())
641 	/* Probably alloc_pending callers will have already checked for
642 	   this case.  But we might as well handle it if they don't, I
643 	   guess.  */
644 	return 0;
645     pending_error_text = malloc (size);
646     if (pending_error_text == NULL)
647     {
648 	pending_error = ENOMEM;
649 	return 0;
650     }
651     return 1;
652 }
653 
654 static void serve_is_modified PROTO ((char *));
655 
656 static int supported_response PROTO ((char *));
657 
658 static int
659 supported_response (name)
660      char *name;
661 {
662     struct response *rs;
663 
664     for (rs = responses; rs->name != NULL; ++rs)
665 	if (strcmp (rs->name, name) == 0)
666 	    return rs->status == rs_supported;
667     error (1, 0, "internal error: testing support for unknown response?");
668     /* NOTREACHED */
669     return 0;
670 }
671 
672 static void
673 serve_valid_responses (arg)
674      char *arg;
675 {
676     char *p = arg;
677     char *q;
678     struct response *rs;
679     do
680     {
681 	q = strchr (p, ' ');
682 	if (q != NULL)
683 	    *q++ = '\0';
684 	for (rs = responses; rs->name != NULL; ++rs)
685 	{
686 	    if (strcmp (rs->name, p) == 0)
687 		break;
688 	}
689 	if (rs->name == NULL)
690 	    /*
691 	     * It is a response we have never heard of (and thus never
692 	     * will want to use).  So don't worry about it.
693 	     */
694 	    ;
695 	else
696 	    rs->status = rs_supported;
697 	p = q;
698     } while (q != NULL);
699     for (rs = responses; rs->name != NULL; ++rs)
700     {
701 	if (rs->status == rs_essential)
702 	{
703 	    buf_output0 (buf_to_net, "E response `");
704 	    buf_output0 (buf_to_net, rs->name);
705 	    buf_output0 (buf_to_net, "' not supported by client\nerror  \n");
706 
707 	    /* FIXME: This call to buf_flush could conceivably
708 	       cause deadlock, as noted in server_cleanup.  */
709 	    buf_flush (buf_to_net, 1);
710 
711 	    /* I'm doing this manually rather than via error_exit ()
712 	       because I'm not sure whether we want to call server_cleanup.
713 	       Needs more investigation....  */
714 
715 #ifdef SYSTEM_CLEANUP
716 	    /* Hook for OS-specific behavior, for example socket subsystems on
717 	       NT and OS2 or dealing with windows and arguments on Mac.  */
718 	    SYSTEM_CLEANUP ();
719 #endif
720 
721 	    exit (EXIT_FAILURE);
722 	}
723 	else if (rs->status == rs_optional)
724 	    rs->status = rs_not_supported;
725     }
726 }
727 
728 static void
729 serve_root (arg)
730     char *arg;
731 {
732     char *env;
733     char *path;
734 
735     if (error_pending()) return;
736 
737     if (!isabsolute (arg))
738     {
739 	if (alloc_pending (80 + strlen (arg)))
740 	    sprintf (pending_error_text,
741 		     "E Root %s must be an absolute pathname", arg);
742 	return;
743     }
744 
745     /* Sending "Root" twice is illegal.
746 
747        The other way to handle a duplicate Root requests would be as a
748        request to clear out all state and start over as if it was a
749        new connection.  Doing this would cause interoperability
750        headaches, so it should be a different request, if there is
751        any reason why such a feature is needed.  */
752     if (current_parsed_root != NULL)
753     {
754 	if (alloc_pending (80 + strlen (arg)))
755 	    sprintf (pending_error_text,
756 		     "E Protocol error: Duplicate Root request, for %s", arg);
757 	return;
758     }
759 
760 #ifdef AUTH_SERVER_SUPPORT
761     if (Pserver_Repos != NULL)
762     {
763 	if (strcmp (Pserver_Repos, arg) != 0)
764 	{
765 	    if (alloc_pending (80 + strlen (Pserver_Repos) + strlen (arg)))
766 		/* The explicitness is to aid people who are writing clients.
767 		   I don't see how this information could help an
768 		   attacker.  */
769 		sprintf (pending_error_text, "\
770 E Protocol error: Root says \"%s\" but pserver says \"%s\"",
771 			 arg, Pserver_Repos);
772 	}
773     }
774 #endif
775 
776     if (current_parsed_root != NULL)
777 	free_cvsroot_t (current_parsed_root);
778     current_parsed_root = local_cvsroot (arg);
779 
780     /* For pserver, this will already have happened, and the call will do
781        nothing.  But for rsh, we need to do it now.  */
782     parse_config (current_parsed_root->directory);
783 
784     path = malloc (strlen (current_parsed_root->directory)
785 		   + sizeof (CVSROOTADM)
786 		   + 2);
787     if (path == NULL)
788     {
789 	pending_error = ENOMEM;
790 	return;
791     }
792     (void) sprintf (path, "%s/%s", current_parsed_root->directory, CVSROOTADM);
793     if (readonlyfs == 0 && !isaccessible (path, R_OK | X_OK))
794     {
795 	int save_errno = errno;
796 	if (alloc_pending (80 + strlen (path)))
797 	    sprintf (pending_error_text, "E Cannot access %s", path);
798 	pending_error = save_errno;
799     }
800     free (path);
801 
802 #ifdef HAVE_PUTENV
803     env = malloc (strlen (CVSROOT_ENV) + strlen (current_parsed_root->directory) + 2);
804     if (env == NULL)
805     {
806 	pending_error = ENOMEM;
807 	return;
808     }
809     (void) sprintf (env, "%s=%s", CVSROOT_ENV, current_parsed_root->directory);
810     (void) putenv (env);
811     /* do not free env, as putenv has control of it */
812 #endif
813 }
814 
815 static int max_dotdot_limit = 0;
816 
817 /* Is this pathname OK to recurse into when we are running as the server?
818    If not, call error() with a fatal error.  */
819 void
820 server_pathname_check (path)
821     char *path;
822 {
823     /* An absolute pathname is almost surely a path on the *client* machine,
824        and is unlikely to do us any good here.  It also is probably capable
825        of being a security hole in the anonymous readonly case.  */
826     if (isabsolute (path))
827 	/* Giving an error is actually kind of a cop-out, in the sense
828 	   that it would be nice for "cvs co -d /foo/bar/baz" to work.
829 	   A quick fix in the server would be requiring Max-dotdot of
830 	   at least one if pathnames are absolute, and then putting
831 	   /abs/foo/bar/baz in the temp dir beside the /d/d/d stuff.
832 	   A cleaner fix in the server might be to decouple the
833 	   pathnames we pass back to the client from pathnames in our
834 	   temp directory (this would also probably remove the need
835 	   for Max-dotdot).  A fix in the client would have the client
836 	   turn it into "cd /foo/bar; cvs co -d baz" (more or less).
837 	   This probably has some problems with pathnames which appear
838 	   in messages.  */
839 	error (1, 0, "absolute pathname `%s' illegal for server", path);
840     if (pathname_levels (path) > max_dotdot_limit)
841     {
842 	/* Similar to the isabsolute case in security implications.  */
843 	error (0, 0, "protocol error: `%s' contains more leading ..", path);
844 	error (1, 0, "than the %d which Max-dotdot specified",
845 	       max_dotdot_limit);
846     }
847 }
848 
849 static int outside_root PROTO ((char *));
850 
851 /* Is file or directory REPOS an absolute pathname within the
852    current_parsed_root->directory?  If yes, return 0.  If no, set pending_error
853    and return 1.  */
854 static int
855 outside_root (repos)
856     char *repos;
857 {
858     size_t repos_len = strlen (repos);
859     size_t root_len = strlen (current_parsed_root->directory);
860 
861     /* I think isabsolute (repos) should always be true, and that
862        any RELATIVE_REPOS stuff should only be in CVS/Repository
863        files, not the protocol (for compatibility), but I'm putting
864        in the isabsolute check just in case.  */
865     if (!isabsolute (repos))
866     {
867 	if (alloc_pending (repos_len + 80))
868 	    sprintf (pending_error_text, "\
869 E protocol error: %s is not absolute", repos);
870 	return 1;
871     }
872 
873     if (repos_len < root_len
874 	|| strncmp (current_parsed_root->directory, repos, root_len) != 0)
875     {
876     not_within:
877 	if (alloc_pending (strlen (current_parsed_root->directory)
878 			   + strlen (repos)
879 			   + 80))
880 	    sprintf (pending_error_text, "\
881 E protocol error: directory '%s' not within root '%s'",
882 		     repos, current_parsed_root->directory);
883 	return 1;
884     }
885     if (repos_len > root_len)
886     {
887 	if (repos[root_len] != '/')
888 	    goto not_within;
889 	if (pathname_levels (repos + root_len + 1) > 0)
890 	    goto not_within;
891     }
892     return 0;
893 }
894 
895 static int outside_dir PROTO ((char *));
896 
897 /* Is file or directory FILE outside the current directory (that is, does
898    it contain '/')?  If no, return 0.  If yes, set pending_error
899    and return 1.  */
900 static int
901 outside_dir (file)
902     char *file;
903 {
904     if (strchr (file, '/') != NULL)
905     {
906 	if (alloc_pending (strlen (file)
907 			   + 80))
908 	    sprintf (pending_error_text, "\
909 E protocol error: directory '%s' not within current directory",
910 		     file);
911 	return 1;
912     }
913     return 0;
914 }
915 
916 /*
917  * Add as many directories to the temp directory as the client tells us it
918  * will use "..", so we never try to access something outside the temp
919  * directory via "..".
920  */
921 static void
922 serve_max_dotdot (arg)
923     char *arg;
924 {
925     int lim = atoi (arg);
926     int i;
927     char *p;
928 
929     if (lim < 0)
930 	return;
931     p = malloc (strlen (server_temp_dir) + 2 * lim + 10);
932     if (p == NULL)
933     {
934 	pending_error = ENOMEM;
935 	return;
936     }
937     strcpy (p, server_temp_dir);
938     for (i = 0; i < lim; ++i)
939 	strcat (p, "/d");
940     if (server_temp_dir != orig_server_temp_dir)
941 	free (server_temp_dir);
942     server_temp_dir = p;
943     max_dotdot_limit = lim;
944 }
945 
946 static char *dir_name;
947 
948 static void
949 dirswitch (dir, repos)
950     char *dir;
951     char *repos;
952 {
953     int status;
954     FILE *f;
955     size_t dir_len;
956 
957     server_write_entries ();
958 
959     if (error_pending()) return;
960 
961     /* Check for bad directory name.
962 
963        FIXME: could/should unify these checks with server_pathname_check
964        except they need to report errors differently.  */
965     if (isabsolute (dir))
966     {
967 	if (alloc_pending (80 + strlen (dir)))
968 	    sprintf (pending_error_text,
969 		     "E absolute pathname `%s' illegal for server", dir);
970 	return;
971     }
972     if (pathname_levels (dir) > max_dotdot_limit)
973     {
974 	if (alloc_pending (80 + strlen (dir)))
975 	    sprintf (pending_error_text,
976 		     "E protocol error: `%s' has too many ..", dir);
977 	return;
978     }
979 
980     if (dir_name != NULL)
981 	free (dir_name);
982 
983     dir_len = strlen (dir);
984 
985     /* Check for a trailing '/'.  This is not ISDIRSEP because \ in the
986        protocol is an ordinary character, not a directory separator (of
987        course, it is perhaps unwise to use it in directory names, but that
988        is another issue).  */
989     if (dir_len > 0
990 	&& dir[dir_len - 1] == '/')
991     {
992 	if (alloc_pending (80 + dir_len))
993 	    sprintf (pending_error_text,
994 		     "E protocol error: invalid directory syntax in %s", dir);
995 	return;
996     }
997 
998     dir_name = malloc (strlen (server_temp_dir) + dir_len + 40);
999     if (dir_name == NULL)
1000     {
1001 	pending_error = ENOMEM;
1002 	return;
1003     }
1004 
1005     strcpy (dir_name, server_temp_dir);
1006     strcat (dir_name, "/");
1007     strcat (dir_name, dir);
1008 
1009     status = mkdir_p (dir_name);
1010     if (status != 0
1011 	&& status != EEXIST)
1012     {
1013 	if (alloc_pending (80 + strlen (dir_name)))
1014 	    sprintf (pending_error_text, "E cannot mkdir %s", dir_name);
1015 	pending_error = status;
1016 	return;
1017     }
1018 
1019     /* We need to create adm directories in all path elements because
1020        we want the server to descend them, even if the client hasn't
1021        sent the appropriate "Argument xxx" command to match the
1022        already-sent "Directory xxx" command.  See recurse.c
1023        (start_recursion) for a big discussion of this.  */
1024 
1025     status = create_adm_p (server_temp_dir, dir);
1026     if (status != 0)
1027     {
1028 	if (alloc_pending (80 + strlen (dir_name)))
1029 	    sprintf (pending_error_text, "E cannot create_adm_p %s", dir_name);
1030 	pending_error = status;
1031 	return;
1032     }
1033 
1034     if ( CVS_CHDIR (dir_name) < 0)
1035     {
1036 	int save_errno = errno;
1037 	if (alloc_pending (80 + strlen (dir_name)))
1038 	    sprintf (pending_error_text, "E cannot change to %s", dir_name);
1039 	pending_error = save_errno;
1040 	return;
1041     }
1042     /*
1043      * This is pretty much like calling Create_Admin, but Create_Admin doesn't
1044      * report errors in the right way for us.
1045      */
1046     if ((CVS_MKDIR (CVSADM, 0777) < 0) && (errno != EEXIST))
1047     {
1048 	int save_errno = errno;
1049 	if (alloc_pending (80 + strlen (dir_name) + strlen (CVSADM)))
1050 	    sprintf (pending_error_text,
1051 		     "E cannot mkdir %s/%s", dir_name, CVSADM);
1052 	pending_error = save_errno;
1053 	return;
1054     }
1055 
1056     /* The following will overwrite the contents of CVSADM_REP.  This
1057        is the correct behavior -- mkdir_p may have written a
1058        placeholder value to this file and we need to insert the
1059        correct value. */
1060 
1061     f = CVS_FOPEN (CVSADM_REP, "w");
1062     if (f == NULL)
1063     {
1064 	int save_errno = errno;
1065 	if (alloc_pending (80 + strlen (dir_name) + strlen (CVSADM_REP)))
1066 	    sprintf (pending_error_text,
1067 		     "E cannot open %s/%s", dir_name, CVSADM_REP);
1068 	pending_error = save_errno;
1069 	return;
1070     }
1071     if (fprintf (f, "%s", repos) < 0)
1072     {
1073 	int save_errno = errno;
1074 	if (alloc_pending (80 + strlen (dir_name) + strlen (CVSADM_REP)))
1075 	    sprintf (pending_error_text,
1076 		     "E error writing %s/%s", dir_name, CVSADM_REP);
1077 	pending_error = save_errno;
1078 	fclose (f);
1079 	return;
1080     }
1081     /* Non-remote CVS handles a module representing the entire tree
1082        (e.g., an entry like ``world -a .'') by putting /. at the end
1083        of the Repository file, so we do the same.  */
1084     if (strcmp (dir, ".") == 0
1085 	&& current_parsed_root != NULL
1086 	&& current_parsed_root->directory != NULL
1087 	&& strcmp (current_parsed_root->directory, repos) == 0)
1088     {
1089         if (fprintf (f, "/.") < 0)
1090 	{
1091 	    int save_errno = errno;
1092 	    if (alloc_pending (80 + strlen (dir_name) + strlen (CVSADM_REP)))
1093 		sprintf (pending_error_text,
1094 			 "E error writing %s/%s", dir_name, CVSADM_REP);
1095 	    pending_error = save_errno;
1096 	    fclose (f);
1097 	    return;
1098 	}
1099     }
1100     if (fprintf (f, "\n") < 0)
1101     {
1102 	int save_errno = errno;
1103 	if (alloc_pending (80 + strlen (dir_name) + strlen (CVSADM_REP)))
1104 	    sprintf (pending_error_text,
1105 		     "E error writing %s/%s", dir_name, CVSADM_REP);
1106 	pending_error = save_errno;
1107 	fclose (f);
1108 	return;
1109     }
1110     if (fclose (f) == EOF)
1111     {
1112 	int save_errno = errno;
1113 	if (alloc_pending (80 + strlen (dir_name) + strlen (CVSADM_REP)))
1114 	    sprintf (pending_error_text,
1115 		     "E error closing %s/%s", dir_name, CVSADM_REP);
1116 	pending_error = save_errno;
1117 	return;
1118     }
1119     /* We open in append mode because we don't want to clobber an
1120        existing Entries file.  */
1121     f = CVS_FOPEN (CVSADM_ENT, "a");
1122     if (f == NULL)
1123     {
1124 	int save_errno = errno;
1125 	if (alloc_pending (80 + strlen (CVSADM_ENT)))
1126 	    sprintf (pending_error_text, "E cannot open %s", CVSADM_ENT);
1127 	pending_error = save_errno;
1128 	return;
1129     }
1130     if (fclose (f) == EOF)
1131     {
1132 	int save_errno = errno;
1133 	if (alloc_pending (80 + strlen (CVSADM_ENT)))
1134 	    sprintf (pending_error_text, "E cannot close %s", CVSADM_ENT);
1135 	pending_error = save_errno;
1136 	return;
1137     }
1138 }
1139 
1140 static void
1141 serve_repository (arg)
1142     char *arg;
1143 {
1144     if (alloc_pending (80))
1145 	strcpy (pending_error_text,
1146 		"E Repository request is obsolete; aborted");
1147     return;
1148 }
1149 
1150 static void
1151 serve_directory (arg)
1152     char *arg;
1153 {
1154     int status;
1155     char *repos;
1156 
1157     status = buf_read_line (buf_from_net, &repos, (int *) NULL);
1158     if (status == 0)
1159     {
1160 	if (!outside_root (repos))
1161 	    dirswitch (arg, repos);
1162 	free (repos);
1163     }
1164     else if (status == -2)
1165     {
1166         pending_error = ENOMEM;
1167     }
1168     else
1169     {
1170 	pending_error_text = malloc (80 + strlen (arg));
1171 	if (pending_error_text == NULL)
1172 	{
1173 	    pending_error = ENOMEM;
1174 	}
1175 	else if (status == -1)
1176 	{
1177 	    sprintf (pending_error_text,
1178 		     "E end of file reading mode for %s", arg);
1179 	}
1180 	else
1181 	{
1182 	    sprintf (pending_error_text,
1183 		     "E error reading mode for %s", arg);
1184 	    pending_error = status;
1185 	}
1186     }
1187 }
1188 
1189 static void
1190 serve_static_directory (arg)
1191     char *arg;
1192 {
1193     FILE *f;
1194 
1195     if (error_pending ()) return;
1196 
1197     f = CVS_FOPEN (CVSADM_ENTSTAT, "w+");
1198     if (f == NULL)
1199     {
1200 	int save_errno = errno;
1201 	if (alloc_pending (80 + strlen (CVSADM_ENTSTAT)))
1202 	    sprintf (pending_error_text, "E cannot open %s", CVSADM_ENTSTAT);
1203 	pending_error = save_errno;
1204 	return;
1205     }
1206     if (fclose (f) == EOF)
1207     {
1208 	int save_errno = errno;
1209 	if (alloc_pending (80 + strlen (CVSADM_ENTSTAT)))
1210 	    sprintf (pending_error_text, "E cannot close %s", CVSADM_ENTSTAT);
1211 	pending_error = save_errno;
1212 	return;
1213     }
1214 }
1215 
1216 static void
1217 serve_sticky (arg)
1218     char *arg;
1219 {
1220     FILE *f;
1221 
1222     if (error_pending ()) return;
1223 
1224     f = CVS_FOPEN (CVSADM_TAG, "w+");
1225     if (f == NULL)
1226     {
1227 	int save_errno = errno;
1228 	if (alloc_pending (80 + strlen (CVSADM_TAG)))
1229 	    sprintf (pending_error_text, "E cannot open %s", CVSADM_TAG);
1230 	pending_error = save_errno;
1231 	return;
1232     }
1233     if (fprintf (f, "%s\n", arg) < 0)
1234     {
1235 	int save_errno = errno;
1236 	if (alloc_pending (80 + strlen (CVSADM_TAG)))
1237 	    sprintf (pending_error_text, "E cannot write to %s", CVSADM_TAG);
1238 	pending_error = save_errno;
1239 	return;
1240     }
1241     if (fclose (f) == EOF)
1242     {
1243 	int save_errno = errno;
1244 	if (alloc_pending (80 + strlen (CVSADM_TAG)))
1245 	    sprintf (pending_error_text, "E cannot close %s", CVSADM_TAG);
1246 	pending_error = save_errno;
1247 	return;
1248     }
1249 }
1250 
1251 /*
1252  * Read SIZE bytes from buf_from_net, write them to FILE.
1253  *
1254  * Currently this isn't really used for receiving parts of a file --
1255  * the file is still sent over in one chunk.  But if/when we get
1256  * spiffy in-process gzip support working, perhaps the compressed
1257  * pieces could be sent over as they're ready, if the network is fast
1258  * enough.  Or something.
1259  */
1260 static void
1261 receive_partial_file (size, file)
1262      int size;
1263      int file;
1264 {
1265     while (size > 0)
1266     {
1267 	int status, nread;
1268 	char *data;
1269 
1270 	status = buf_read_data (buf_from_net, size, &data, &nread);
1271 	if (status != 0)
1272 	{
1273 	    if (status == -2)
1274 		pending_error = ENOMEM;
1275 	    else
1276 	    {
1277 		pending_error_text = malloc (80);
1278 		if (pending_error_text == NULL)
1279 		    pending_error = ENOMEM;
1280 		else if (status == -1)
1281 		{
1282 		    sprintf (pending_error_text,
1283 			     "E premature end of file from client");
1284 		    pending_error = 0;
1285 		}
1286 		else
1287 		{
1288 		    sprintf (pending_error_text,
1289 			     "E error reading from client");
1290 		    pending_error = status;
1291 		}
1292 	    }
1293 	    return;
1294 	}
1295 
1296 	size -= nread;
1297 
1298 	while (nread > 0)
1299 	{
1300 	    int nwrote;
1301 
1302 	    nwrote = write (file, data, nread);
1303 	    if (nwrote < 0)
1304 	    {
1305 	        int save_errno = errno;
1306 		if (alloc_pending (40))
1307 		    strcpy (pending_error_text, "E unable to write");
1308 		pending_error = save_errno;
1309 
1310 		/* Read and discard the file data.  */
1311 		while (size > 0)
1312 		{
1313 		    int status, nread;
1314 		    char *data;
1315 
1316 		    status = buf_read_data (buf_from_net, size, &data, &nread);
1317 		    if (status != 0)
1318 			return;
1319 		    size -= nread;
1320 		}
1321 
1322 		return;
1323 	    }
1324 	    nread -= nwrote;
1325 	    data += nwrote;
1326 	}
1327     }
1328 }
1329 
1330 /* Receive SIZE bytes, write to filename FILE.  */
1331 static void
1332 receive_file (size, file, gzipped)
1333      int size;
1334      char *file;
1335      int gzipped;
1336 {
1337     int fd;
1338     char *arg = file;
1339 
1340     /* Write the file.  */
1341     fd = CVS_OPEN (arg, O_WRONLY | O_CREAT | O_TRUNC, 0600);
1342     if (fd < 0)
1343     {
1344 	int save_errno = errno;
1345 	if (alloc_pending (40 + strlen (arg)))
1346 	    sprintf (pending_error_text, "E cannot open %s", arg);
1347 	pending_error = save_errno;
1348 	return;
1349     }
1350 
1351     if (gzipped)
1352     {
1353 	/* Using gunzip_and_write isn't really a high-performance
1354 	   approach, because it keeps the whole thing in memory
1355 	   (contiguous memory, worse yet).  But it seems easier to
1356 	   code than the alternative (and less vulnerable to subtle
1357 	   bugs).  Given that this feature is mainly for
1358 	   compatibility, that is the better tradeoff.  */
1359 
1360 	int toread = size;
1361 	char *filebuf;
1362 	char *p;
1363 
1364 	filebuf = malloc (size);
1365 	p = filebuf;
1366 	/* If NULL, we still want to read the data and discard it.  */
1367 
1368 	while (toread > 0)
1369 	{
1370 	    int status, nread;
1371 	    char *data;
1372 
1373 	    status = buf_read_data (buf_from_net, toread, &data, &nread);
1374 	    if (status != 0)
1375 	    {
1376 		if (status == -2)
1377 		    pending_error = ENOMEM;
1378 		else
1379 		{
1380 		    pending_error_text = malloc (80);
1381 		    if (pending_error_text == NULL)
1382 			pending_error = ENOMEM;
1383 		    else if (status == -1)
1384 		    {
1385 			sprintf (pending_error_text,
1386 				 "E premature end of file from client");
1387 			pending_error = 0;
1388 		    }
1389 		    else
1390 		    {
1391 			sprintf (pending_error_text,
1392 				 "E error reading from client");
1393 			pending_error = status;
1394 		    }
1395 		}
1396 		return;
1397 	    }
1398 
1399 	    toread -= nread;
1400 
1401 	    if (filebuf != NULL)
1402 	    {
1403 		memcpy (p, data, nread);
1404 		p += nread;
1405 	    }
1406 	}
1407 	if (filebuf == NULL)
1408 	{
1409 	    pending_error = ENOMEM;
1410 	    goto out;
1411 	}
1412 
1413 	if (gunzip_and_write (fd, file, (unsigned char *) filebuf, size))
1414 	{
1415 	    if (alloc_pending (80))
1416 		sprintf (pending_error_text,
1417 			 "E aborting due to compression error");
1418 	}
1419 	free (filebuf);
1420     }
1421     else
1422 	receive_partial_file (size, fd);
1423 
1424     if (pending_error_text)
1425     {
1426 	char *p = realloc (pending_error_text,
1427 			   strlen (pending_error_text) + strlen (arg) + 30);
1428 	if (p)
1429 	{
1430 	    pending_error_text = p;
1431 	    sprintf (p + strlen (p), ", file %s", arg);
1432 	}
1433 	/* else original string is supposed to be unchanged */
1434     }
1435 
1436  out:
1437     if (close (fd) < 0 && !error_pending ())
1438     {
1439 	int save_errno = errno;
1440 	if (alloc_pending (40 + strlen (arg)))
1441 	    sprintf (pending_error_text, "E cannot close %s", arg);
1442 	pending_error = save_errno;
1443 	return;
1444     }
1445 }
1446 
1447 /* Kopt for the next file sent in Modified or Is-modified.  */
1448 static char *kopt;
1449 
1450 /* Timestamp (Checkin-time) for next file sent in Modified or
1451    Is-modified.  */
1452 static int checkin_time_valid;
1453 static time_t checkin_time;
1454 
1455 static void serve_modified PROTO ((char *));
1456 
1457 static void
1458 serve_modified (arg)
1459      char *arg;
1460 {
1461     int size, status;
1462     char *size_text;
1463     char *mode_text;
1464 
1465     int gzipped = 0;
1466 
1467     /*
1468      * This used to return immediately if error_pending () was true.
1469      * However, that fails, because it causes each line of the file to
1470      * be echoed back to the client as an unrecognized command.  The
1471      * client isn't reading from the socket, so eventually both
1472      * processes block trying to write to the other.  Now, we try to
1473      * read the file if we can.
1474      */
1475 
1476     status = buf_read_line (buf_from_net, &mode_text, (int *) NULL);
1477     if (status != 0)
1478     {
1479         if (status == -2)
1480 	    pending_error = ENOMEM;
1481 	else
1482 	{
1483 	    pending_error_text = malloc (80 + strlen (arg));
1484 	    if (pending_error_text == NULL)
1485 		pending_error = ENOMEM;
1486 	    else
1487 	    {
1488 		if (status == -1)
1489 		    sprintf (pending_error_text,
1490 			     "E end of file reading mode for %s", arg);
1491 		else
1492 		{
1493 		    sprintf (pending_error_text,
1494 			     "E error reading mode for %s", arg);
1495 		    pending_error = status;
1496 		}
1497 	    }
1498 	}
1499 	return;
1500     }
1501 
1502     status = buf_read_line (buf_from_net, &size_text, (int *) NULL);
1503     if (status != 0)
1504     {
1505 	if (status == -2)
1506 	    pending_error = ENOMEM;
1507 	else
1508 	{
1509 	    pending_error_text = malloc (80 + strlen (arg));
1510 	    if (pending_error_text == NULL)
1511 		pending_error = ENOMEM;
1512 	    else
1513 	    {
1514 		if (status == -1)
1515 		    sprintf (pending_error_text,
1516 			     "E end of file reading size for %s", arg);
1517 		else
1518 		{
1519 		    sprintf (pending_error_text,
1520 			     "E error reading size for %s", arg);
1521 		    pending_error = status;
1522 		}
1523 	    }
1524 	}
1525 	free (mode_text);
1526 	return;
1527     }
1528     if (size_text[0] == 'z')
1529     {
1530 	gzipped = 1;
1531 	size = atoi (size_text + 1);
1532     }
1533     else
1534 	size = atoi (size_text);
1535     free (size_text);
1536 
1537     if (error_pending ())
1538     {
1539         /* Now that we know the size, read and discard the file data.  */
1540 	while (size > 0)
1541 	{
1542 	    int status, nread;
1543 	    char *data;
1544 
1545 	    status = buf_read_data (buf_from_net, size, &data, &nread);
1546 	    if (status != 0)
1547 		return;
1548 	    size -= nread;
1549 	}
1550 	free (mode_text);
1551 	return;
1552     }
1553 
1554     if (outside_dir (arg))
1555     {
1556 	free (mode_text);
1557 	return;
1558     }
1559 
1560     if (size >= 0)
1561     {
1562 	receive_file (size, arg, gzipped);
1563 	if (error_pending ())
1564 	{
1565 	    free (mode_text);
1566 	    return;
1567 	}
1568     }
1569 
1570     if (checkin_time_valid)
1571     {
1572 	struct utimbuf t;
1573 
1574 	memset (&t, 0, sizeof (t));
1575 	t.modtime = t.actime = checkin_time;
1576 	if (utime (arg, &t) < 0)
1577 	{
1578 	    int save_errno = errno;
1579 	    if (alloc_pending (80 + strlen (arg)))
1580 		sprintf (pending_error_text, "E cannot utime %s", arg);
1581 	    pending_error = save_errno;
1582 	    free (mode_text);
1583 	    return;
1584 	}
1585 	checkin_time_valid = 0;
1586     }
1587 
1588     {
1589 	int status = change_mode (arg, mode_text, 0);
1590 	free (mode_text);
1591 	if (status)
1592 	{
1593 	    if (alloc_pending (40 + strlen (arg)))
1594 		sprintf (pending_error_text,
1595 			 "E cannot change mode for %s", arg);
1596 	    pending_error = status;
1597 	    return;
1598 	}
1599     }
1600 
1601     /* Make sure that the Entries indicate the right kopt.  We probably
1602        could do this even in the non-kopt case and, I think, save a stat()
1603        call in time_stamp_server.  But for conservatism I'm leaving the
1604        non-kopt case alone.  */
1605     if (kopt != NULL)
1606 	serve_is_modified (arg);
1607 }
1608 
1609 
1610 static void
1611 serve_enable_unchanged (arg)
1612      char *arg;
1613 {
1614 }
1615 
1616 struct an_entry {
1617     struct an_entry *next;
1618     char *entry;
1619 };
1620 
1621 static struct an_entry *entries;
1622 
1623 static void serve_unchanged PROTO ((char *));
1624 
1625 static void
1626 serve_unchanged (arg)
1627     char *arg;
1628 {
1629     struct an_entry *p;
1630     char *name;
1631     char *cp;
1632     char *timefield;
1633 
1634     if (error_pending ())
1635 	return;
1636 
1637     if (outside_dir (arg))
1638 	return;
1639 
1640     /* Rewrite entries file to have `=' in timestamp field.  */
1641     for (p = entries; p != NULL; p = p->next)
1642     {
1643 	name = p->entry + 1;
1644 	cp = strchr (name, '/');
1645 	if (cp != NULL
1646 	    && strlen (arg) == cp - name
1647 	    && strncmp (arg, name, cp - name) == 0)
1648 	{
1649 	    timefield = strchr (cp + 1, '/') + 1;
1650 	    if (*timefield != '=')
1651 	    {
1652 		cp = timefield + strlen (timefield);
1653 		cp[1] = '\0';
1654 		while (cp > timefield)
1655 		{
1656 		    *cp = cp[-1];
1657 		    --cp;
1658 		}
1659 		*timefield = '=';
1660 	    }
1661 	    break;
1662 	}
1663     }
1664 }
1665 
1666 static void
1667 serve_is_modified (arg)
1668     char *arg;
1669 {
1670     struct an_entry *p;
1671     char *name;
1672     char *cp;
1673     char *timefield;
1674     /* Have we found this file in "entries" yet.  */
1675     int found;
1676 
1677     if (error_pending ())
1678 	return;
1679 
1680     if (outside_dir (arg))
1681 	return;
1682 
1683     /* Rewrite entries file to have `M' in timestamp field.  */
1684     found = 0;
1685     for (p = entries; p != NULL; p = p->next)
1686     {
1687 	name = p->entry + 1;
1688 	cp = strchr (name, '/');
1689 	if (cp != NULL
1690 	    && strlen (arg) == cp - name
1691 	    && strncmp (arg, name, cp - name) == 0)
1692 	{
1693 	    timefield = strchr (cp + 1, '/') + 1;
1694 	    if (!(timefield[0] == 'M' && timefield[1] == '/'))
1695 	    {
1696 		cp = timefield + strlen (timefield);
1697 		cp[1] = '\0';
1698 		while (cp > timefield)
1699 		{
1700 		    *cp = cp[-1];
1701 		    --cp;
1702 		}
1703 		*timefield = 'M';
1704 	    }
1705 	    if (kopt != NULL)
1706 	    {
1707 		if (alloc_pending (strlen (name) + 80))
1708 		    sprintf (pending_error_text,
1709 			     "E protocol error: both Kopt and Entry for %s",
1710 			     arg);
1711 		free (kopt);
1712 		kopt = NULL;
1713 		return;
1714 	    }
1715 	    found = 1;
1716 	    break;
1717 	}
1718     }
1719     if (!found)
1720     {
1721 	/* We got Is-modified but no Entry.  Add a dummy entry.
1722 	   The "D" timestamp is what makes it a dummy.  */
1723 	p = (struct an_entry *) malloc (sizeof (struct an_entry));
1724 	if (p == NULL)
1725 	{
1726 	    pending_error = ENOMEM;
1727 	    return;
1728 	}
1729 	p->entry = malloc (strlen (arg) + 80);
1730 	if (p->entry == NULL)
1731 	{
1732 	    pending_error = ENOMEM;
1733 	    free (p);
1734 	    return;
1735 	}
1736 	strcpy (p->entry, "/");
1737 	strcat (p->entry, arg);
1738 	strcat (p->entry, "//D/");
1739 	if (kopt != NULL)
1740 	{
1741 	    strcat (p->entry, kopt);
1742 	    free (kopt);
1743 	    kopt = NULL;
1744 	}
1745 	strcat (p->entry, "/");
1746 	p->next = entries;
1747 	entries = p;
1748     }
1749 }
1750 
1751 static void serve_entry PROTO ((char *));
1752 
1753 static void
1754 serve_entry (arg)
1755      char *arg;
1756 {
1757     struct an_entry *p;
1758     char *cp;
1759     if (error_pending()) return;
1760     p = (struct an_entry *) malloc (sizeof (struct an_entry));
1761     if (p == NULL)
1762     {
1763 	pending_error = ENOMEM;
1764 	return;
1765     }
1766     /* Leave space for serve_unchanged to write '=' if it wants.  */
1767     cp = malloc (strlen (arg) + 2);
1768     if (cp == NULL)
1769     {
1770 	pending_error = ENOMEM;
1771 	return;
1772     }
1773     strcpy (cp, arg);
1774     p->next = entries;
1775     p->entry = cp;
1776     entries = p;
1777 }
1778 
1779 static void serve_kopt PROTO ((char *));
1780 
1781 static void
1782 serve_kopt (arg)
1783      char *arg;
1784 {
1785     if (error_pending ())
1786 	return;
1787 
1788     if (kopt != NULL)
1789     {
1790 	if (alloc_pending (80 + strlen (arg)))
1791 	    sprintf (pending_error_text,
1792 		     "E protocol error: duplicate Kopt request: %s", arg);
1793 	return;
1794     }
1795 
1796     /* Do some sanity checks.  In particular, that it is not too long.
1797        This lets the rest of the code not worry so much about buffer
1798        overrun attacks.  Probably should call RCS_check_kflag here,
1799        but that would mean changing RCS_check_kflag to handle errors
1800        other than via exit(), fprintf(), and such.  */
1801     if (strlen (arg) > 10)
1802     {
1803 	if (alloc_pending (80 + strlen (arg)))
1804 	    sprintf (pending_error_text,
1805 		     "E protocol error: invalid Kopt request: %s", arg);
1806 	return;
1807     }
1808 
1809     kopt = malloc (strlen (arg) + 1);
1810     if (kopt == NULL)
1811     {
1812 	pending_error = ENOMEM;
1813 	return;
1814     }
1815     strcpy (kopt, arg);
1816 }
1817 
1818 static void serve_checkin_time PROTO ((char *));
1819 
1820 static void
1821 serve_checkin_time (arg)
1822      char *arg;
1823 {
1824     if (error_pending ())
1825 	return;
1826 
1827     if (checkin_time_valid)
1828     {
1829 	if (alloc_pending (80 + strlen (arg)))
1830 	    sprintf (pending_error_text,
1831 		     "E protocol error: duplicate Checkin-time request: %s",
1832 		     arg);
1833 	return;
1834     }
1835 
1836     checkin_time = get_date (arg, NULL);
1837     if (checkin_time == (time_t)-1)
1838     {
1839 	if (alloc_pending (80 + strlen (arg)))
1840 	    sprintf (pending_error_text, "E cannot parse date %s", arg);
1841 	return;
1842     }
1843     checkin_time_valid = 1;
1844 }
1845 
1846 static void
1847 server_write_entries ()
1848 {
1849     FILE *f;
1850     struct an_entry *p;
1851     struct an_entry *q;
1852 
1853     if (entries == NULL)
1854 	return;
1855 
1856     f = NULL;
1857     /* Note that we free all the entries regardless of errors.  */
1858     if (!error_pending ())
1859     {
1860 	/* We open in append mode because we don't want to clobber an
1861            existing Entries file.  If we are checking out a module
1862            which explicitly lists more than one file in a particular
1863            directory, then we will wind up calling
1864            server_write_entries for each such file.  */
1865 	f = CVS_FOPEN (CVSADM_ENT, "a");
1866 	if (f == NULL)
1867 	{
1868 	    int save_errno = errno;
1869 	    if (alloc_pending (80 + strlen (CVSADM_ENT)))
1870 		sprintf (pending_error_text, "E cannot open %s", CVSADM_ENT);
1871 	    pending_error = save_errno;
1872 	}
1873     }
1874     for (p = entries; p != NULL;)
1875     {
1876 	if (!error_pending ())
1877 	{
1878 	    if (fprintf (f, "%s\n", p->entry) < 0)
1879 	    {
1880 		int save_errno = errno;
1881 		if (alloc_pending (80 + strlen(CVSADM_ENT)))
1882 		    sprintf (pending_error_text,
1883 			     "E cannot write to %s", CVSADM_ENT);
1884 		pending_error = save_errno;
1885 	    }
1886 	}
1887 	free (p->entry);
1888 	q = p->next;
1889 	free (p);
1890 	p = q;
1891     }
1892     entries = NULL;
1893     if (f != NULL && fclose (f) == EOF && !error_pending ())
1894     {
1895 	int save_errno = errno;
1896 	if (alloc_pending (80 + strlen (CVSADM_ENT)))
1897 	    sprintf (pending_error_text, "E cannot close %s", CVSADM_ENT);
1898 	pending_error = save_errno;
1899     }
1900 }
1901 
1902 struct notify_note {
1903     /* Directory in which this notification happens.  malloc'd*/
1904     char *dir;
1905 
1906     /* malloc'd.  */
1907     char *filename;
1908 
1909     /* The following three all in one malloc'd block, pointed to by TYPE.
1910        Each '\0' terminated.  */
1911     /* "E" or "U".  */
1912     char *type;
1913     /* time+host+dir */
1914     char *val;
1915     char *watches;
1916 
1917     struct notify_note *next;
1918 };
1919 
1920 static struct notify_note *notify_list;
1921 /* Used while building list, to point to the last node that already exists.  */
1922 static struct notify_note *last_node;
1923 
1924 static void serve_notify PROTO ((char *));
1925 
1926 static void
1927 serve_notify (arg)
1928     char *arg;
1929 {
1930     struct notify_note *new = NULL;
1931     char *data = NULL;
1932     int status;
1933 
1934     if (error_pending ()) return;
1935 
1936     if (outside_dir (arg))
1937 	return;
1938 
1939     if (dir_name == NULL)
1940 	goto error;
1941 
1942     new = (struct notify_note *) malloc (sizeof (struct notify_note));
1943     if (new == NULL)
1944     {
1945 	pending_error = ENOMEM;
1946 	return;
1947     }
1948     new->dir = malloc (strlen (dir_name) + 1);
1949     new->filename = malloc (strlen (arg) + 1);
1950     if (new->dir == NULL || new->filename == NULL)
1951     {
1952 	pending_error = ENOMEM;
1953 	if (new->dir != NULL)
1954 	    free (new->dir);
1955 	free (new);
1956 	return;
1957     }
1958     strcpy (new->dir, dir_name);
1959     strcpy (new->filename, arg);
1960 
1961     status = buf_read_line (buf_from_net, &data, (int *) NULL);
1962     if (status != 0)
1963     {
1964 	if (status == -2)
1965 	    pending_error = ENOMEM;
1966 	else
1967 	{
1968 	    pending_error_text = malloc (80 + strlen (arg));
1969 	    if (pending_error_text == NULL)
1970 		pending_error = ENOMEM;
1971 	    else
1972 	    {
1973 		if (status == -1)
1974 		    sprintf (pending_error_text,
1975 			     "E end of file reading notification for %s", arg);
1976 		else
1977 		{
1978 		    sprintf (pending_error_text,
1979 			     "E error reading notification for %s", arg);
1980 		    pending_error = status;
1981 		}
1982 	    }
1983 	}
1984 	free (new->filename);
1985 	free (new->dir);
1986 	free (new);
1987     }
1988     else
1989     {
1990 	char *cp;
1991 
1992 	if (strchr (data, '+'))
1993 	    goto error;
1994 
1995 	new->type = data;
1996 	if (data[1] != '\t')
1997 	    goto error;
1998 	data[1] = '\0';
1999 	cp = data + 2;
2000 	new->val = cp;
2001 	cp = strchr (cp, '\t');
2002 	if (cp == NULL)
2003 	    goto error;
2004 	*cp++ = '+';
2005 	cp = strchr (cp, '\t');
2006 	if (cp == NULL)
2007 	    goto error;
2008 	*cp++ = '+';
2009 	cp = strchr (cp, '\t');
2010 	if (cp == NULL)
2011 	    goto error;
2012 	*cp++ = '\0';
2013 	new->watches = cp;
2014 	/* If there is another tab, ignore everything after it,
2015 	   for future expansion.  */
2016 	cp = strchr (cp, '\t');
2017 	if (cp != NULL)
2018 	{
2019 	    *cp = '\0';
2020 	}
2021 
2022 	new->next = NULL;
2023 
2024 	if (last_node == NULL)
2025 	{
2026 	    notify_list = new;
2027 	}
2028 	else
2029 	    last_node->next = new;
2030 	last_node = new;
2031     }
2032     return;
2033   error:
2034     pending_error = 0;
2035     if (alloc_pending (80))
2036 	strcpy (pending_error_text,
2037 		"E Protocol error; misformed Notify request");
2038     if (data != NULL)
2039 	free (data);
2040     if (new != NULL)
2041     {
2042 	free (new->filename);
2043 	free (new->dir);
2044 	free (new);
2045     }
2046     return;
2047 }
2048 
2049 /* Process all the Notify requests that we have stored up.  Returns 0
2050    if successful, if not prints error message (via error()) and
2051    returns negative value.  */
2052 static int
2053 server_notify ()
2054 {
2055     struct notify_note *p;
2056     char *repos;
2057 
2058     while (notify_list != NULL)
2059     {
2060 	if ( CVS_CHDIR (notify_list->dir) < 0)
2061 	{
2062 	    error (0, errno, "cannot change to %s", notify_list->dir);
2063 	    return -1;
2064 	}
2065 	repos = Name_Repository (NULL, NULL);
2066 
2067 	lock_dir_for_write (repos);
2068 
2069 	fileattr_startdir (repos);
2070 
2071 	notify_do (*notify_list->type, notify_list->filename, getcaller(),
2072 		   notify_list->val, notify_list->watches, repos);
2073 
2074 	buf_output0 (buf_to_net, "Notified ");
2075 	{
2076 	    char *dir = notify_list->dir + strlen (server_temp_dir) + 1;
2077 	    if (dir[0] == '\0')
2078 	        buf_append_char (buf_to_net, '.');
2079 	    else
2080 	        buf_output0 (buf_to_net, dir);
2081 	    buf_append_char (buf_to_net, '/');
2082 	    buf_append_char (buf_to_net, '\n');
2083 	}
2084 	buf_output0 (buf_to_net, repos);
2085 	buf_append_char (buf_to_net, '/');
2086 	buf_output0 (buf_to_net, notify_list->filename);
2087 	buf_append_char (buf_to_net, '\n');
2088 	free (repos);
2089 
2090 	p = notify_list->next;
2091 	free (notify_list->filename);
2092 	free (notify_list->dir);
2093 	free (notify_list->type);
2094 	free (notify_list);
2095 	notify_list = p;
2096 
2097 	fileattr_write ();
2098 	fileattr_free ();
2099 
2100 	Lock_Cleanup ();
2101     }
2102 
2103     last_node = NULL;
2104 
2105     /* The code used to call fflush (stdout) here, but that is no
2106        longer necessary.  The data is now buffered in buf_to_net,
2107        which will be flushed by the caller, do_cvs_command.  */
2108 
2109     return 0;
2110 }
2111 
2112 static int argument_count;
2113 static char **argument_vector;
2114 static int argument_vector_size;
2115 
2116 static void
2117 serve_argument (arg)
2118      char *arg;
2119 {
2120     char *p;
2121 
2122     if (error_pending()) return;
2123 
2124     if (argument_vector_size <= argument_count)
2125     {
2126 	argument_vector_size *= 2;
2127 	argument_vector =
2128 	    (char **) realloc ((char *)argument_vector,
2129 			       argument_vector_size * sizeof (char *));
2130 	if (argument_vector == NULL)
2131 	{
2132 	    pending_error = ENOMEM;
2133 	    return;
2134 	}
2135     }
2136     p = malloc (strlen (arg) + 1);
2137     if (p == NULL)
2138     {
2139 	pending_error = ENOMEM;
2140 	return;
2141     }
2142     strcpy (p, arg);
2143     argument_vector[argument_count++] = p;
2144 }
2145 
2146 static void
2147 serve_argumentx (arg)
2148      char *arg;
2149 {
2150     char *p;
2151 
2152     if (error_pending()) return;
2153 
2154     p = argument_vector[argument_count - 1];
2155     p = realloc (p, strlen (p) + 1 + strlen (arg) + 1);
2156     if (p == NULL)
2157     {
2158 	pending_error = ENOMEM;
2159 	return;
2160     }
2161     strcat (p, "\n");
2162     strcat (p, arg);
2163     argument_vector[argument_count - 1] = p;
2164 }
2165 
2166 static void
2167 serve_global_option (arg)
2168     char *arg;
2169 {
2170     if (arg[0] != '-' || arg[1] == '\0' || arg[2] != '\0')
2171     {
2172     error_return:
2173 	if (alloc_pending (strlen (arg) + 80))
2174 	    sprintf (pending_error_text,
2175 		     "E Protocol error: bad global option %s",
2176 		     arg);
2177 	return;
2178     }
2179     switch (arg[1])
2180     {
2181 	case 'n':
2182 	    noexec = 1;
2183 	    break;
2184 	case 'q':
2185 	    quiet = 1;
2186 	    break;
2187 	case 'r':
2188 	    cvswrite = 0;
2189 	    break;
2190 	case 'Q':
2191 	    really_quiet = 1;
2192 	    break;
2193 	case 'l':
2194 	    logoff = 1;
2195 	    break;
2196 	case 't':
2197 	    trace = 1;
2198 	    break;
2199 	default:
2200 	    goto error_return;
2201     }
2202 }
2203 
2204 static void
2205 serve_set (arg)
2206     char *arg;
2207 {
2208     /* FIXME: This sends errors immediately (I think); they should be
2209        put into pending_error.  */
2210     variable_set (arg);
2211 }
2212 
2213 #ifdef ENCRYPTION
2214 
2215 #ifdef HAVE_KERBEROS
2216 
2217 static void
2218 serve_kerberos_encrypt (arg)
2219      char *arg;
2220 {
2221     /* All future communication with the client will be encrypted.  */
2222 
2223     buf_to_net = krb_encrypt_buffer_initialize (buf_to_net, 0, sched,
2224 						kblock,
2225 						buf_to_net->memory_error);
2226     buf_from_net = krb_encrypt_buffer_initialize (buf_from_net, 1, sched,
2227 						  kblock,
2228 						  buf_from_net->memory_error);
2229 }
2230 
2231 #endif /* HAVE_KERBEROS */
2232 
2233 #ifdef HAVE_GSSAPI
2234 
2235 static void
2236 serve_gssapi_encrypt (arg)
2237      char *arg;
2238 {
2239     if (cvs_gssapi_wrapping)
2240     {
2241 	/* We're already using a gssapi_wrap buffer for stream
2242            authentication.  Flush everything we've output so far, and
2243            turn on encryption for future data.  On the input side, we
2244            should only have unwrapped as far as the Gssapi-encrypt
2245            command, so future unwrapping will become encrypted.  */
2246 	buf_flush (buf_to_net, 1);
2247 	cvs_gssapi_encrypt = 1;
2248 	return;
2249     }
2250 
2251     /* All future communication with the client will be encrypted.  */
2252 
2253     cvs_gssapi_encrypt = 1;
2254 
2255     buf_to_net = cvs_gssapi_wrap_buffer_initialize (buf_to_net, 0,
2256 						    gcontext,
2257 						    buf_to_net->memory_error);
2258     buf_from_net = cvs_gssapi_wrap_buffer_initialize (buf_from_net, 1,
2259 						      gcontext,
2260 						      buf_from_net->memory_error);
2261 
2262     cvs_gssapi_wrapping = 1;
2263 }
2264 
2265 #endif /* HAVE_GSSAPI */
2266 
2267 #endif /* ENCRYPTION */
2268 
2269 #ifdef HAVE_GSSAPI
2270 
2271 static void
2272 serve_gssapi_authenticate (arg)
2273      char *arg;
2274 {
2275     if (cvs_gssapi_wrapping)
2276     {
2277 	/* We're already using a gssapi_wrap buffer for encryption.
2278            That includes authentication, so we don't have to do
2279            anything further.  */
2280 	return;
2281     }
2282 
2283     buf_to_net = cvs_gssapi_wrap_buffer_initialize (buf_to_net, 0,
2284 						    gcontext,
2285 						    buf_to_net->memory_error);
2286     buf_from_net = cvs_gssapi_wrap_buffer_initialize (buf_from_net, 1,
2287 						      gcontext,
2288 						      buf_from_net->memory_error);
2289 
2290     cvs_gssapi_wrapping = 1;
2291 }
2292 
2293 #endif /* HAVE_GSSAPI */
2294 
2295 #ifdef SERVER_FLOWCONTROL
2296 /* The maximum we'll queue to the remote client before blocking.  */
2297 # ifndef SERVER_HI_WATER
2298 #  define SERVER_HI_WATER (2 * 1024 * 1024)
2299 # endif /* SERVER_HI_WATER */
2300 /* When the buffer drops to this, we restart the child */
2301 # ifndef SERVER_LO_WATER
2302 #  define SERVER_LO_WATER (1 * 1024 * 1024)
2303 # endif /* SERVER_LO_WATER */
2304 
2305 static int set_nonblock_fd PROTO((int));
2306 
2307 /*
2308  * Set buffer BUF to non-blocking I/O.  Returns 0 for success or errno
2309  * code.
2310  */
2311 
2312 static int
2313 set_nonblock_fd (fd)
2314      int fd;
2315 {
2316     int flags;
2317 
2318     flags = fcntl (fd, F_GETFL, 0);
2319     if (flags < 0)
2320 	return errno;
2321     if (fcntl (fd, F_SETFL, flags | O_NONBLOCK) < 0)
2322 	return errno;
2323     return 0;
2324 }
2325 
2326 #endif /* SERVER_FLOWCONTROL */
2327 
2328 static void serve_questionable PROTO((char *));
2329 
2330 static void
2331 serve_questionable (arg)
2332     char *arg;
2333 {
2334     static int initted;
2335 
2336     if (!initted)
2337     {
2338 	/* Pick up ignores from CVSROOTADM_IGNORE, $HOME/.cvsignore on server,
2339 	   and CVSIGNORE on server.  */
2340 	ign_setup ();
2341 	initted = 1;
2342     }
2343 
2344     if (dir_name == NULL)
2345     {
2346 	buf_output0 (buf_to_net, "E Protocol error: 'Directory' missing");
2347 	return;
2348     }
2349 
2350     if (outside_dir (arg))
2351 	return;
2352 
2353     if (!ign_name (arg))
2354     {
2355 	char *update_dir;
2356 
2357 	buf_output (buf_to_net, "M ? ", 4);
2358 	update_dir = dir_name + strlen (server_temp_dir) + 1;
2359 	if (!(update_dir[0] == '.' && update_dir[1] == '\0'))
2360 	{
2361 	    buf_output0 (buf_to_net, update_dir);
2362 	    buf_output (buf_to_net, "/", 1);
2363 	}
2364 	buf_output0 (buf_to_net, arg);
2365 	buf_output (buf_to_net, "\n", 1);
2366     }
2367 }
2368 
2369 static void serve_case PROTO ((char *));
2370 
2371 static void
2372 serve_case (arg)
2373     char *arg;
2374 {
2375     ign_case = 1;
2376 }
2377 
2378 static struct buffer *protocol;
2379 
2380 /* This is the output which we are saving up to send to the server, in the
2381    child process.  We will push it through, via the `protocol' buffer, when
2382    we have a complete line.  */
2383 static struct buffer *saved_output;
2384 /* Likewise, but stuff which will go to stderr.  */
2385 static struct buffer *saved_outerr;
2386 
2387 static void
2388 protocol_memory_error (buf)
2389     struct buffer *buf;
2390 {
2391     error (1, ENOMEM, "Virtual memory exhausted");
2392 }
2393 
2394 /*
2395  * Process IDs of the subprocess, or negative if that subprocess
2396  * does not exist.
2397  */
2398 static pid_t command_pid;
2399 
2400 static void
2401 outbuf_memory_error (buf)
2402     struct buffer *buf;
2403 {
2404     static const char msg[] = "E Fatal server error\n\
2405 error ENOMEM Virtual memory exhausted.\n";
2406     if (command_pid > 0)
2407 	kill (command_pid, SIGTERM);
2408 
2409     /*
2410      * We have arranged things so that printing this now either will
2411      * be legal, or the "E fatal error" line will get glommed onto the
2412      * end of an existing "E" or "M" response.
2413      */
2414 
2415     /* If this gives an error, not much we could do.  syslog() it?  */
2416     write (STDOUT_FILENO, msg, sizeof (msg) - 1);
2417 #ifdef HAVE_SYSLOG_H
2418     syslog (LOG_DAEMON | LOG_ERR, "virtual memory exhausted");
2419 #endif
2420     error_exit ();
2421 }
2422 
2423 static void
2424 input_memory_error (buf)
2425      struct buffer *buf;
2426 {
2427     outbuf_memory_error (buf);
2428 }
2429 
2430 
2431 
2432 /* If command is legal, return 1.
2433  * Else if command is illegal and croak_on_illegal is set, then die.
2434  * Else just return 0 to indicate that command is illegal.
2435  */
2436 static int
2437 check_command_legal_p (cmd_name)
2438     char *cmd_name;
2439 {
2440     /* Right now, only pserver notices illegal commands -- namely,
2441      * write attempts by a read-only user.  Therefore, if CVS_Username
2442      * is not set, this just returns 1, because CVS_Username unset
2443      * means pserver is not active.
2444      */
2445 #ifdef AUTH_SERVER_SUPPORT
2446     if (CVS_Username == NULL)
2447         return 1;
2448 
2449     if (lookup_command_attribute (cmd_name) & CVS_CMD_MODIFIES_REPOSITORY)
2450     {
2451         /* This command has the potential to modify the repository, so
2452          * we check if the user have permission to do that.
2453          *
2454          * (Only relevant for remote users -- local users can do
2455          * whatever normal Unix file permissions allow them to do.)
2456          *
2457          * The decision method:
2458          *
2459          *    If $CVSROOT/CVSADMROOT_READERS exists and user is listed
2460          *    in it, then read-only access for user.
2461          *
2462          *    Or if $CVSROOT/CVSADMROOT_WRITERS exists and user NOT
2463          *    listed in it, then also read-only access for user.
2464          *
2465          *    Else read-write access for user.
2466          */
2467 
2468          char *linebuf = NULL;
2469          int num_red = 0;
2470          size_t linebuf_len = 0;
2471          char *fname;
2472          size_t flen;
2473          FILE *fp;
2474          int found_it = 0;
2475 
2476          /* else */
2477          flen = strlen (current_parsed_root->directory)
2478                 + strlen (CVSROOTADM)
2479                 + strlen (CVSROOTADM_READERS)
2480                 + 3;
2481 
2482          fname = xmalloc (flen);
2483          (void) sprintf (fname, "%s/%s/%s", current_parsed_root->directory,
2484 			CVSROOTADM, CVSROOTADM_READERS);
2485 
2486          fp = fopen (fname, "r");
2487 
2488          if (fp == NULL)
2489 	 {
2490 	     if (!existence_error (errno))
2491 	     {
2492 		 /* Need to deny access, so that attackers can't fool
2493 		    us with some sort of denial of service attack.  */
2494 		 error (0, errno, "cannot open %s", fname);
2495 		 free (fname);
2496 		 return 0;
2497 	     }
2498 	 }
2499          else  /* successfully opened readers file */
2500          {
2501              while ((num_red = getline (&linebuf, &linebuf_len, fp)) >= 0)
2502              {
2503                  /* Hmmm, is it worth importing my own readline
2504                     library into CVS?  It takes care of chopping
2505                     leading and trailing whitespace, "#" comments, and
2506                     newlines automatically when so requested.  Would
2507                     save some code here...  -kff */
2508 
2509                  /* Chop newline by hand, for strcmp()'s sake. */
2510                  if (linebuf[num_red - 1] == '\n')
2511                      linebuf[num_red - 1] = '\0';
2512 
2513                  if (strcmp (linebuf, CVS_Username) == 0)
2514                      goto handle_illegal;
2515              }
2516 	     if (num_red < 0 && !feof (fp))
2517 		 error (0, errno, "cannot read %s", fname);
2518 
2519              /* If not listed specifically as a reader, then this user
2520                 has write access by default unless writers are also
2521                 specified in a file . */
2522 	     if (fclose (fp) < 0)
2523 		 error (0, errno, "cannot close %s", fname);
2524          }
2525 	 free (fname);
2526 
2527 	 /* Now check the writers file.  */
2528 
2529          flen = strlen (current_parsed_root->directory)
2530                 + strlen (CVSROOTADM)
2531                 + strlen (CVSROOTADM_WRITERS)
2532                 + 3;
2533 
2534          fname = xmalloc (flen);
2535          (void) sprintf (fname, "%s/%s/%s", current_parsed_root->directory,
2536 			CVSROOTADM, CVSROOTADM_WRITERS);
2537 
2538          fp = fopen (fname, "r");
2539 
2540          if (fp == NULL)
2541          {
2542 	     if (linebuf)
2543 	         free (linebuf);
2544 	     if (existence_error (errno))
2545 	     {
2546 		 /* Writers file does not exist, so everyone is a writer,
2547 		    by default.  */
2548 		 free (fname);
2549 		 return 1;
2550 	     }
2551 	     else
2552 	     {
2553 		 /* Need to deny access, so that attackers can't fool
2554 		    us with some sort of denial of service attack.  */
2555 		 error (0, errno, "cannot read %s", fname);
2556 		 free (fname);
2557 		 return 0;
2558 	     }
2559          }
2560 
2561          found_it = 0;
2562          while ((num_red = getline (&linebuf, &linebuf_len, fp)) >= 0)
2563          {
2564              /* Chop newline by hand, for strcmp()'s sake. */
2565              if (linebuf[num_red - 1] == '\n')
2566                  linebuf[num_red - 1] = '\0';
2567 
2568              if (strcmp (linebuf, CVS_Username) == 0)
2569              {
2570                  found_it = 1;
2571                  break;
2572              }
2573          }
2574 	 if (num_red < 0 && !feof (fp))
2575 	     error (0, errno, "cannot read %s", fname);
2576 
2577          if (found_it)
2578          {
2579              if (fclose (fp) < 0)
2580 		 error (0, errno, "cannot close %s", fname);
2581              if (linebuf)
2582                  free (linebuf);
2583 	     free (fname);
2584              return 1;
2585          }
2586          else   /* writers file exists, but this user not listed in it */
2587          {
2588          handle_illegal:
2589              if (fclose (fp) < 0)
2590 		 error (0, errno, "cannot close %s", fname);
2591              if (linebuf)
2592                  free (linebuf);
2593 	     free (fname);
2594 	     return 0;
2595          }
2596     }
2597 #endif /* AUTH_SERVER_SUPPORT */
2598 
2599     /* If ever reach end of this function, command must be legal. */
2600     return 1;
2601 }
2602 
2603 
2604 
2605 /* Execute COMMAND in a subprocess with the approriate funky things done.  */
2606 
2607 static struct fd_set_wrapper { fd_set fds; } command_fds_to_drain;
2608 static int max_command_fd;
2609 
2610 #ifdef SERVER_FLOWCONTROL
2611 static int flowcontrol_pipe[2];
2612 #endif /* SERVER_FLOWCONTROL */
2613 
2614 static void
2615 do_cvs_command (cmd_name, command)
2616     char *cmd_name;
2617     int (*command) PROTO((int argc, char **argv));
2618 {
2619     /*
2620      * The following file descriptors are set to -1 if that file is not
2621      * currently open.
2622      */
2623 
2624     /* Data on these pipes is a series of '\n'-terminated lines.  */
2625     int stdout_pipe[2];
2626     int stderr_pipe[2];
2627 
2628     /*
2629      * Data on this pipe is a series of counted (see buf_send_counted)
2630      * packets.  Each packet must be processed atomically (i.e. not
2631      * interleaved with data from stdout_pipe or stderr_pipe).
2632      */
2633     int protocol_pipe[2];
2634 
2635     int dev_null_fd = -1;
2636 
2637     int errs;
2638 
2639     command_pid = -1;
2640     stdout_pipe[0] = -1;
2641     stdout_pipe[1] = -1;
2642     stderr_pipe[0] = -1;
2643     stderr_pipe[1] = -1;
2644     protocol_pipe[0] = -1;
2645     protocol_pipe[1] = -1;
2646 
2647     server_write_entries ();
2648 
2649     if (print_pending_error ())
2650 	goto free_args_and_return;
2651 
2652     /* Global `command_name' is probably "server" right now -- only
2653        serve_export() sets it to anything else.  So we will use local
2654        parameter `cmd_name' to determine if this command is legal for
2655        this user.  */
2656     if (!check_command_legal_p (cmd_name))
2657     {
2658 	buf_output0 (buf_to_net, "E ");
2659 	buf_output0 (buf_to_net, program_name);
2660 	buf_output0 (buf_to_net, " [server aborted]: \"");
2661 	buf_output0 (buf_to_net, cmd_name);
2662 	buf_output0 (buf_to_net, "\" requires write access to the repository\n\
2663 error  \n");
2664 	goto free_args_and_return;
2665     }
2666 
2667     (void) server_notify ();
2668 
2669     /*
2670      * We use a child process which actually does the operation.  This
2671      * is so we can intercept its standard output.  Even if all of CVS
2672      * were written to go to some special routine instead of writing
2673      * to stdout or stderr, we would still need to do the same thing
2674      * for the RCS commands.
2675      */
2676 
2677     if (pipe (stdout_pipe) < 0)
2678     {
2679 	buf_output0 (buf_to_net, "E pipe failed\n");
2680 	print_error (errno);
2681 	goto error_exit;
2682     }
2683     if (pipe (stderr_pipe) < 0)
2684     {
2685 	buf_output0 (buf_to_net, "E pipe failed\n");
2686 	print_error (errno);
2687 	goto error_exit;
2688     }
2689     if (pipe (protocol_pipe) < 0)
2690     {
2691 	buf_output0 (buf_to_net, "E pipe failed\n");
2692 	print_error (errno);
2693 	goto error_exit;
2694     }
2695 #ifdef SERVER_FLOWCONTROL
2696     if (pipe (flowcontrol_pipe) < 0)
2697     {
2698 	buf_output0 (buf_to_net, "E pipe failed\n");
2699 	print_error (errno);
2700 	goto error_exit;
2701     }
2702     set_nonblock_fd (flowcontrol_pipe[0]);
2703     set_nonblock_fd (flowcontrol_pipe[1]);
2704 #endif /* SERVER_FLOWCONTROL */
2705 
2706     dev_null_fd = CVS_OPEN (DEVNULL, O_RDONLY);
2707     if (dev_null_fd < 0)
2708     {
2709 	buf_output0 (buf_to_net, "E open /dev/null failed\n");
2710 	print_error (errno);
2711 	goto error_exit;
2712     }
2713 
2714     /* We shouldn't have any partial lines from cvs_output and
2715        cvs_outerr, but we handle them here in case there is a bug.  */
2716     /* FIXME: appending a newline, rather than using "MT" as we
2717        do in the child process, is probably not really a very good
2718        way to "handle" them.  */
2719     if (! buf_empty_p (saved_output))
2720     {
2721 	buf_append_char (saved_output, '\n');
2722 	buf_copy_lines (buf_to_net, saved_output, 'M');
2723     }
2724     if (! buf_empty_p (saved_outerr))
2725     {
2726 	buf_append_char (saved_outerr, '\n');
2727 	buf_copy_lines (buf_to_net, saved_outerr, 'E');
2728     }
2729 
2730     /* Flush out any pending data.  */
2731     buf_flush (buf_to_net, 1);
2732 
2733     /* Don't use vfork; we're not going to exec().  */
2734     command_pid = fork ();
2735     if (command_pid < 0)
2736     {
2737 	buf_output0 (buf_to_net, "E fork failed\n");
2738 	print_error (errno);
2739 	goto error_exit;
2740     }
2741     if (command_pid == 0)
2742     {
2743 	int exitstatus;
2744 
2745 	/* Since we're in the child, and the parent is going to take
2746 	   care of packaging up our error messages, we can clear this
2747 	   flag.  */
2748 	error_use_protocol = 0;
2749 
2750 	protocol = fd_buffer_initialize (protocol_pipe[1], 0,
2751 					 protocol_memory_error);
2752 
2753 	/* At this point we should no longer be using buf_to_net and
2754            buf_from_net.  Instead, everything should go through
2755            protocol.  */
2756 	buf_to_net = NULL;
2757 	buf_from_net = NULL;
2758 
2759 	/* These were originally set up to use outbuf_memory_error.
2760            Since we're now in the child, we should use the simpler
2761            protocol_memory_error function.  */
2762 	saved_output->memory_error = protocol_memory_error;
2763 	saved_outerr->memory_error = protocol_memory_error;
2764 
2765 	if (dup2 (dev_null_fd, STDIN_FILENO) < 0)
2766 	    error (1, errno, "can't set up pipes");
2767 	if (dup2 (stdout_pipe[1], STDOUT_FILENO) < 0)
2768 	    error (1, errno, "can't set up pipes");
2769 	if (dup2 (stderr_pipe[1], STDERR_FILENO) < 0)
2770 	    error (1, errno, "can't set up pipes");
2771 	close (dev_null_fd);
2772 	close (stdout_pipe[0]);
2773 	close (stdout_pipe[1]);
2774 	close (stderr_pipe[0]);
2775 	close (stderr_pipe[1]);
2776 	close (protocol_pipe[0]);
2777 	close_on_exec (protocol_pipe[1]);
2778 #ifdef SERVER_FLOWCONTROL
2779 	close_on_exec (flowcontrol_pipe[0]);
2780 	close (flowcontrol_pipe[1]);
2781 #endif /* SERVER_FLOWCONTROL */
2782 
2783 	/*
2784 	 * Set this in .bashrc if you want to give yourself time to attach
2785 	 * to the subprocess with a debugger.
2786 	 */
2787 	if (getenv ("CVS_SERVER_SLEEP"))
2788 	{
2789 	    int secs = atoi (getenv ("CVS_SERVER_SLEEP"));
2790 	    sleep (secs);
2791 	}
2792 
2793 	exitstatus = (*command) (argument_count, argument_vector);
2794 
2795 	/* Output any partial lines.  If the client doesn't support
2796 	   "MT", we go ahead and just tack on a newline since the
2797 	   protocol doesn't support anything better.  */
2798 	if (! buf_empty_p (saved_output))
2799 	{
2800 	    buf_output0 (protocol, supported_response ("MT") ? "MT text " : "M ");
2801 	    buf_append_buffer (protocol, saved_output);
2802 	    buf_output (protocol, "\n", 1);
2803 	    buf_send_counted (protocol);
2804 	}
2805 	/* For now we just discard partial lines on stderr.  I suspect
2806 	   that CVS can't write such lines unless there is a bug.  */
2807 
2808 	/*
2809 	 * When we exit, that will close the pipes, giving an EOF to
2810 	 * the parent.
2811 	 */
2812 	buf_free (protocol);
2813 	exit (exitstatus);
2814     }
2815 
2816     /* OK, sit around getting all the input from the child.  */
2817     {
2818 	struct buffer *stdoutbuf;
2819 	struct buffer *stderrbuf;
2820 	struct buffer *protocol_inbuf;
2821 	/* Number of file descriptors to check in select ().  */
2822 	int num_to_check;
2823 	int count_needed = 1;
2824 #ifdef SERVER_FLOWCONTROL
2825 	int have_flowcontrolled = 0;
2826 #endif /* SERVER_FLOWCONTROL */
2827 
2828 	FD_ZERO (&command_fds_to_drain.fds);
2829 	num_to_check = stdout_pipe[0];
2830 	FD_SET (stdout_pipe[0], &command_fds_to_drain.fds);
2831 	if (stderr_pipe[0] > num_to_check)
2832 	  num_to_check = stderr_pipe[0];
2833 	FD_SET (stderr_pipe[0], &command_fds_to_drain.fds);
2834 	if (protocol_pipe[0] > num_to_check)
2835 	  num_to_check = protocol_pipe[0];
2836 	FD_SET (protocol_pipe[0], &command_fds_to_drain.fds);
2837 	if (STDOUT_FILENO > num_to_check)
2838 	  num_to_check = STDOUT_FILENO;
2839 	max_command_fd = num_to_check;
2840 	/*
2841 	 * File descriptors are numbered from 0, so num_to_check needs to
2842 	 * be one larger than the largest descriptor.
2843 	 */
2844 	++num_to_check;
2845 	if (num_to_check > FD_SETSIZE)
2846 	{
2847 	    buf_output0 (buf_to_net,
2848 			 "E internal error: FD_SETSIZE not big enough.\n\
2849 error  \n");
2850 	    goto error_exit;
2851 	}
2852 
2853 	stdoutbuf = fd_buffer_initialize (stdout_pipe[0], 1,
2854 					  input_memory_error);
2855 
2856 	stderrbuf = fd_buffer_initialize (stderr_pipe[0], 1,
2857 					  input_memory_error);
2858 
2859 	protocol_inbuf = fd_buffer_initialize (protocol_pipe[0], 1,
2860 					       input_memory_error);
2861 
2862 	set_nonblock (buf_to_net);
2863 	set_nonblock (stdoutbuf);
2864 	set_nonblock (stderrbuf);
2865 	set_nonblock (protocol_inbuf);
2866 
2867 	if (close (stdout_pipe[1]) < 0)
2868 	{
2869 	    buf_output0 (buf_to_net, "E close failed\n");
2870 	    print_error (errno);
2871 	    goto error_exit;
2872 	}
2873 	stdout_pipe[1] = -1;
2874 
2875 	if (close (stderr_pipe[1]) < 0)
2876 	{
2877 	    buf_output0 (buf_to_net, "E close failed\n");
2878 	    print_error (errno);
2879 	    goto error_exit;
2880 	}
2881 	stderr_pipe[1] = -1;
2882 
2883 	if (close (protocol_pipe[1]) < 0)
2884 	{
2885 	    buf_output0 (buf_to_net, "E close failed\n");
2886 	    print_error (errno);
2887 	    goto error_exit;
2888 	}
2889 	protocol_pipe[1] = -1;
2890 
2891 #ifdef SERVER_FLOWCONTROL
2892 	if (close (flowcontrol_pipe[0]) < 0)
2893 	{
2894 	    buf_output0 (buf_to_net, "E close failed\n");
2895 	    print_error (errno);
2896 	    goto error_exit;
2897 	}
2898 	flowcontrol_pipe[0] = -1;
2899 #endif /* SERVER_FLOWCONTROL */
2900 
2901 	if (close (dev_null_fd) < 0)
2902 	{
2903 	    buf_output0 (buf_to_net, "E close failed\n");
2904 	    print_error (errno);
2905 	    goto error_exit;
2906 	}
2907 	dev_null_fd = -1;
2908 
2909 	while (stdout_pipe[0] >= 0
2910 	       || stderr_pipe[0] >= 0
2911 	       || protocol_pipe[0] >= 0
2912 	       || count_needed <= 0)
2913 	{
2914 	    fd_set readfds;
2915 	    fd_set writefds;
2916 	    int numfds;
2917 #ifdef SERVER_FLOWCONTROL
2918 	    int bufmemsize;
2919 	    struct timeval *timeout_ptr;
2920 	    struct timeval timeout;
2921 
2922 	    /*
2923 	     * See if we are swamping the remote client and filling our VM.
2924 	     * Tell child to hold off if we do.
2925 	     */
2926 	    bufmemsize = buf_count_mem (buf_to_net);
2927 	    if (!have_flowcontrolled && (bufmemsize > SERVER_HI_WATER))
2928 	    {
2929 		if (write(flowcontrol_pipe[1], "S", 1) == 1)
2930 		    have_flowcontrolled = 1;
2931 	    }
2932 	    else if (have_flowcontrolled && (bufmemsize < SERVER_LO_WATER))
2933 	    {
2934 		if (write(flowcontrol_pipe[1], "G", 1) == 1)
2935 		    have_flowcontrolled = 0;
2936 	    }
2937 #endif /* SERVER_FLOWCONTROL */
2938 
2939 	    FD_ZERO (&readfds);
2940 	    FD_ZERO (&writefds);
2941 
2942 	    if (count_needed <= 0)
2943 	    {
2944 		/* there is data pending which was read from the protocol pipe
2945 		 * so don't block if we don't find any data
2946 		 */
2947 		timeout.tv_sec = 0;
2948 		timeout.tv_usec = 0;
2949 		timeout_ptr = &timeout;
2950 	    }
2951 	    else
2952 	    {
2953 		/* block indefinately */
2954 		timeout_ptr = NULL;
2955 	    }
2956 
2957 	    if (! buf_empty_p (buf_to_net))
2958 		FD_SET (STDOUT_FILENO, &writefds);
2959 
2960 	    if (stdout_pipe[0] >= 0)
2961 	    {
2962 		FD_SET (stdout_pipe[0], &readfds);
2963 	    }
2964 	    if (stderr_pipe[0] >= 0)
2965 	    {
2966 		FD_SET (stderr_pipe[0], &readfds);
2967 	    }
2968 	    if (protocol_pipe[0] >= 0)
2969 	    {
2970 		FD_SET (protocol_pipe[0], &readfds);
2971 	    }
2972 
2973 	    /* This process of selecting on the three pipes means that
2974 	     we might not get output in the same order in which it
2975 	     was written, thus producing the well-known
2976 	     "out-of-order" bug.  If the child process uses
2977 	     cvs_output and cvs_outerr, it will send everything on
2978 	     the protocol_pipe and avoid this problem, so the
2979 	     solution is to use cvs_output and cvs_outerr in the
2980 	     child process.  */
2981 	    do {
2982 		/* This used to select on exceptions too, but as far
2983                    as I know there was never any reason to do that and
2984                    SCO doesn't let you select on exceptions on pipes.  */
2985 		numfds = select (num_to_check, &readfds, &writefds,
2986 				 (fd_set *)0, timeout_ptr);
2987 		if (numfds < 0
2988 			&& errno != EINTR)
2989 		{
2990 		    buf_output0 (buf_to_net, "E select failed\n");
2991 		    print_error (errno);
2992 		    goto error_exit;
2993 		}
2994 	    } while (numfds < 0);
2995 
2996 	    if (numfds == 0)
2997 	    {
2998 		FD_ZERO (&readfds);
2999 		FD_ZERO (&writefds);
3000 	    }
3001 
3002 	    if (FD_ISSET (STDOUT_FILENO, &writefds))
3003 	    {
3004 		/* What should we do with errors?  syslog() them?  */
3005 		buf_send_output (buf_to_net);
3006 	    }
3007 
3008 	    if (protocol_pipe[0] >= 0
3009 		&& (FD_ISSET (protocol_pipe[0], &readfds)))
3010 	    {
3011 		int status;
3012 		int count_read;
3013 
3014 		status = buf_input_data (protocol_inbuf, &count_read);
3015 
3016 		if (status == -1)
3017 		{
3018 		    close (protocol_pipe[0]);
3019 		    protocol_pipe[0] = -1;
3020 		}
3021 		else if (status > 0)
3022 		{
3023 		    buf_output0 (buf_to_net, "E buf_input_data failed\n");
3024 		    print_error (status);
3025 		    goto error_exit;
3026 		}
3027 
3028 		/*
3029 		 * We only call buf_copy_counted if we have read
3030 		 * enough bytes to make it worthwhile.  This saves us
3031 		 * from continually recounting the amount of data we
3032 		 * have.
3033 		 */
3034 		count_needed -= count_read;
3035 	    }
3036 	    /* this is still part of the protocol pipe procedure, but it is
3037 	     * outside the above conditional so that unprocessed data can be
3038 	     * left in the buffer and stderr/stdout can be read when a flush
3039 	     * signal is received and control can return here without passing
3040 	     * through the select code and maybe blocking
3041 	     */
3042 	    while (count_needed <= 0)
3043 	    {
3044 		int special = 0;
3045 
3046 		count_needed = buf_copy_counted (buf_to_net,
3047 						     protocol_inbuf,
3048 						     &special);
3049 
3050 		/* What should we do with errors?  syslog() them?  */
3051 		buf_send_output (buf_to_net);
3052 
3053 		/* If SPECIAL got set to <0, it means that the child
3054 		 * wants us to flush the pipe & maybe stderr or stdout.
3055 		 *
3056 		 * After that we break to read stderr & stdout again before
3057 		 * going back to the protocol pipe
3058 		 *
3059 		 * Upon breaking, count_needed = 0, so the next pass will only
3060 		 * perform a non-blocking select before returning here to finish
3061 		 * processing data we already read from the protocol buffer
3062 		 */
3063 		 if (special == -1)
3064 		 {
3065 		     cvs_flushout();
3066 		     break;
3067 		 }
3068 		if (special == -2)
3069 		{
3070 		    /* If the client supports the 'F' command, we send it. */
3071 		    if (supported_response ("F"))
3072 		    {
3073 			buf_append_char (buf_to_net, 'F');
3074 			buf_append_char (buf_to_net, '\n');
3075 		    }
3076 		    cvs_flusherr ();
3077 		    break;
3078 		}
3079 	    }
3080 
3081 	    if (stdout_pipe[0] >= 0
3082 		&& (FD_ISSET (stdout_pipe[0], &readfds)))
3083 	    {
3084 	        int status;
3085 
3086 	        status = buf_input_data (stdoutbuf, (int *) NULL);
3087 
3088 		buf_copy_lines (buf_to_net, stdoutbuf, 'M');
3089 
3090 		if (status == -1)
3091 		{
3092 		    close (stdout_pipe[0]);
3093 		    stdout_pipe[0] = -1;
3094 		}
3095 		else if (status > 0)
3096 		{
3097 		    buf_output0 (buf_to_net, "E buf_input_data failed\n");
3098 		    print_error (status);
3099 		    goto error_exit;
3100 		}
3101 
3102 		/* What should we do with errors?  syslog() them?  */
3103 		buf_send_output (buf_to_net);
3104 	    }
3105 
3106 	    if (stderr_pipe[0] >= 0
3107 		&& (FD_ISSET (stderr_pipe[0], &readfds)))
3108 	    {
3109 	        int status;
3110 
3111 	        status = buf_input_data (stderrbuf, (int *) NULL);
3112 
3113 		buf_copy_lines (buf_to_net, stderrbuf, 'E');
3114 
3115 		if (status == -1)
3116 		{
3117 		    close (stderr_pipe[0]);
3118 		    stderr_pipe[0] = -1;
3119 		}
3120 		else if (status > 0)
3121 		{
3122 		    buf_output0 (buf_to_net, "E buf_input_data failed\n");
3123 		    print_error (status);
3124 		    goto error_exit;
3125 		}
3126 
3127 		/* What should we do with errors?  syslog() them?  */
3128 		buf_send_output (buf_to_net);
3129 	    }
3130 	}
3131 
3132 	/*
3133 	 * OK, we've gotten EOF on all the pipes.  If there is
3134 	 * anything left on stdoutbuf or stderrbuf (this could only
3135 	 * happen if there was no trailing newline), send it over.
3136 	 */
3137 	if (! buf_empty_p (stdoutbuf))
3138 	{
3139 	    buf_append_char (stdoutbuf, '\n');
3140 	    buf_copy_lines (buf_to_net, stdoutbuf, 'M');
3141 	}
3142 	if (! buf_empty_p (stderrbuf))
3143 	{
3144 	    buf_append_char (stderrbuf, '\n');
3145 	    buf_copy_lines (buf_to_net, stderrbuf, 'E');
3146 	}
3147 	if (! buf_empty_p (protocol_inbuf))
3148 	    buf_output0 (buf_to_net,
3149 			 "E Protocol error: uncounted data discarded\n");
3150 
3151 #ifdef SERVER_FLOWCONTROL
3152 	close (flowcontrol_pipe[1]);
3153 	flowcontrol_pipe[1] = -1;
3154 #endif /* SERVER_FLOWCONTROL */
3155 
3156 	errs = 0;
3157 
3158 	while (command_pid > 0)
3159 	{
3160 	    int status;
3161 	    pid_t waited_pid;
3162 	    waited_pid = waitpid (command_pid, &status, 0);
3163 	    if (waited_pid < 0)
3164 	    {
3165 		/*
3166 		 * Intentionally ignoring EINTR.  Other errors
3167 		 * "can't happen".
3168 		 */
3169 		continue;
3170 	    }
3171 
3172 	    if (WIFEXITED (status))
3173 		errs += WEXITSTATUS (status);
3174 	    else
3175 	    {
3176 	        int sig = WTERMSIG (status);
3177 	        char buf[50];
3178 		/*
3179 		 * This is really evil, because signals might be numbered
3180 		 * differently on the two systems.  We should be using
3181 		 * signal names (either of the "Terminated" or the "SIGTERM"
3182 		 * variety).  But cvs doesn't currently use libiberty...we
3183 		 * could roll our own....  FIXME.
3184 		 */
3185 		buf_output0 (buf_to_net, "E Terminated with fatal signal ");
3186 		sprintf (buf, "%d\n", sig);
3187 		buf_output0 (buf_to_net, buf);
3188 
3189 		/* Test for a core dump.  Is this portable?  */
3190 		if (status & 0x80)
3191 		{
3192 		    buf_output0 (buf_to_net, "E Core dumped; preserving ");
3193 		    buf_output0 (buf_to_net, orig_server_temp_dir);
3194 		    buf_output0 (buf_to_net, " on server.\n\
3195 E CVS locks may need cleaning up.\n");
3196 		    dont_delete_temp = 1;
3197 		}
3198 		++errs;
3199 	    }
3200 	    if (waited_pid == command_pid)
3201 		command_pid = -1;
3202 	}
3203 
3204 	/*
3205 	 * OK, we've waited for the child.  By now all CVS locks are free
3206 	 * and it's OK to block on the network.
3207 	 */
3208 	set_block (buf_to_net);
3209 	buf_flush (buf_to_net, 1);
3210 	buf_shutdown (protocol_inbuf);
3211 	buf_free (protocol_inbuf);
3212 	buf_shutdown (stderrbuf);
3213 	buf_free (stderrbuf);
3214 	buf_shutdown (stdoutbuf);
3215 	buf_free (stdoutbuf);
3216     }
3217 
3218     if (errs)
3219 	/* We will have printed an error message already.  */
3220 	buf_output0 (buf_to_net, "error  \n");
3221     else
3222 	buf_output0 (buf_to_net, "ok\n");
3223     goto free_args_and_return;
3224 
3225  error_exit:
3226     if (command_pid > 0)
3227 	kill (command_pid, SIGTERM);
3228 
3229     while (command_pid > 0)
3230     {
3231 	pid_t waited_pid;
3232 	waited_pid = waitpid (command_pid, (int *) 0, 0);
3233 	if (waited_pid < 0 && errno == EINTR)
3234 	    continue;
3235 	if (waited_pid == command_pid)
3236 	    command_pid = -1;
3237     }
3238 
3239     close (dev_null_fd);
3240     close (protocol_pipe[0]);
3241     close (protocol_pipe[1]);
3242     close (stderr_pipe[0]);
3243     close (stderr_pipe[1]);
3244     close (stdout_pipe[0]);
3245     close (stdout_pipe[1]);
3246 #ifdef SERVER_FLOWCONTROL
3247     close (flowcontrol_pipe[0]);
3248     close (flowcontrol_pipe[1]);
3249 #endif /* SERVER_FLOWCONTROL */
3250 
3251  free_args_and_return:
3252     /* Now free the arguments.  */
3253     {
3254 	/* argument_vector[0] is a dummy argument, we don't mess with it.  */
3255 	char **cp;
3256 	for (cp = argument_vector + 1;
3257 	     cp < argument_vector + argument_count;
3258 	     ++cp)
3259 	    free (*cp);
3260 
3261 	argument_count = 1;
3262     }
3263 
3264     /* Flush out any data not yet sent.  */
3265     set_block (buf_to_net);
3266     buf_flush (buf_to_net, 1);
3267 
3268     return;
3269 }
3270 
3271 #ifdef SERVER_FLOWCONTROL
3272 /*
3273  * Called by the child at convenient points in the server's execution for
3274  * the server child to block.. ie: when it has no locks active.
3275  */
3276 void
3277 server_pause_check()
3278 {
3279     int paused = 0;
3280     char buf[1];
3281 
3282     while (read (flowcontrol_pipe[0], buf, 1) == 1)
3283     {
3284 	if (*buf == 'S')	/* Stop */
3285 	    paused = 1;
3286 	else if (*buf == 'G')	/* Go */
3287 	    paused = 0;
3288 	else
3289 	    return;		/* ??? */
3290     }
3291     while (paused) {
3292 	int numfds, numtocheck;
3293 	fd_set fds;
3294 
3295 	FD_ZERO (&fds);
3296 	FD_SET (flowcontrol_pipe[0], &fds);
3297 	numtocheck = flowcontrol_pipe[0] + 1;
3298 
3299 	do {
3300 	    numfds = select (numtocheck, &fds, (fd_set *)0,
3301 			     (fd_set *)0, (struct timeval *)NULL);
3302 	    if (numfds < 0
3303 		&& errno != EINTR)
3304 	    {
3305 		buf_output0 (buf_to_net, "E select failed\n");
3306 		print_error (errno);
3307 		return;
3308 	    }
3309 	} while (numfds < 0);
3310 
3311 	if (FD_ISSET (flowcontrol_pipe[0], &fds))
3312 	{
3313 	    int got;
3314 
3315 	    while ((got = read (flowcontrol_pipe[0], buf, 1)) == 1)
3316 	    {
3317 		if (*buf == 'S')	/* Stop */
3318 		    paused = 1;
3319 		else if (*buf == 'G')	/* Go */
3320 		    paused = 0;
3321 		else
3322 		    return;		/* ??? */
3323 	    }
3324 
3325 	    /* This assumes that we are using BSD or POSIX nonblocking
3326                I/O.  System V nonblocking I/O returns zero if there is
3327                nothing to read.  */
3328 	    if (got == 0)
3329 	        error (1, 0, "flow control EOF");
3330 	    if (got < 0 && ! blocking_error (errno))
3331 	    {
3332 	        error (1, errno, "flow control read failed");
3333 	    }
3334 	}
3335     }
3336 }
3337 #endif /* SERVER_FLOWCONTROL */
3338 
3339 /* This variable commented in server.h.  */
3340 char *server_dir = NULL;
3341 
3342 static void output_dir PROTO((char *, char *));
3343 
3344 static void
3345 output_dir (update_dir, repository)
3346     char *update_dir;
3347     char *repository;
3348 {
3349     if (server_dir != NULL)
3350     {
3351 	buf_output0 (protocol, server_dir);
3352 	buf_output0 (protocol, "/");
3353     }
3354     if (update_dir[0] == '\0')
3355 	buf_output0 (protocol, ".");
3356     else
3357 	buf_output0 (protocol, update_dir);
3358     buf_output0 (protocol, "/\n");
3359     buf_output0 (protocol, repository);
3360     buf_output0 (protocol, "/");
3361 }
3362 
3363 /*
3364  * Entries line that we are squirreling away to send to the client when
3365  * we are ready.
3366  */
3367 static char *entries_line;
3368 
3369 /*
3370  * File which has been Scratch_File'd, we are squirreling away that fact
3371  * to inform the client when we are ready.
3372  */
3373 static char *scratched_file;
3374 
3375 /*
3376  * The scratched_file will need to be removed as well as having its entry
3377  * removed.
3378  */
3379 static int kill_scratched_file;
3380 
3381 void
3382 server_register (name, version, timestamp, options, tag, date, conflict)
3383     char *name;
3384     char *version;
3385     char *timestamp;
3386     char *options;
3387     char *tag;
3388     char *date;
3389     char *conflict;
3390 {
3391     int len;
3392 
3393     if (options == NULL)
3394 	options = "";
3395 
3396     if (trace)
3397     {
3398 	(void) fprintf (stderr,
3399 			"%s-> server_register(%s, %s, %s, %s, %s, %s, %s)\n",
3400 			CLIENT_SERVER_STR,
3401 			name, version, timestamp ? timestamp : "", options,
3402 			tag ? tag : "", date ? date : "",
3403 			conflict ? conflict : "");
3404     }
3405 
3406     if (entries_line != NULL)
3407     {
3408 	/*
3409 	 * If CVS decides to Register it more than once (which happens
3410 	 * on "cvs update foo/foo.c" where foo and foo.c are already
3411 	 * checked out), use the last of the entries lines Register'd.
3412 	 */
3413 	free (entries_line);
3414     }
3415 
3416     /*
3417      * I have reports of Scratch_Entry and Register both happening, in
3418      * two different cases.  Using the last one which happens is almost
3419      * surely correct; I haven't tracked down why they both happen (or
3420      * even verified that they are for the same file).
3421      */
3422     if (scratched_file != NULL)
3423     {
3424 	free (scratched_file);
3425 	scratched_file = NULL;
3426     }
3427 
3428     len = (strlen (name) + strlen (version) + strlen (options) + 80);
3429     if (tag)
3430 	len += strlen (tag);
3431     if (date)
3432 	len += strlen (date);
3433 
3434     entries_line = xmalloc (len);
3435     sprintf (entries_line, "/%s/%s/", name, version);
3436     if (conflict != NULL)
3437     {
3438 	strcat (entries_line, "+=");
3439     }
3440     strcat (entries_line, "/");
3441     strcat (entries_line, options);
3442     strcat (entries_line, "/");
3443     if (tag != NULL)
3444     {
3445 	strcat (entries_line, "T");
3446 	strcat (entries_line, tag);
3447     }
3448     else if (date != NULL)
3449     {
3450 	strcat (entries_line, "D");
3451 	strcat (entries_line, date);
3452     }
3453 }
3454 
3455 void
3456 server_scratch (fname)
3457     char *fname;
3458 {
3459     /*
3460      * I have reports of Scratch_Entry and Register both happening, in
3461      * two different cases.  Using the last one which happens is almost
3462      * surely correct; I haven't tracked down why they both happen (or
3463      * even verified that they are for the same file).
3464      *
3465      * Don't know if this is what whoever wrote the above comment was
3466      * talking about, but this can happen in the case where a join
3467      * removes a file - the call to Register puts the '-vers' into the
3468      * Entries file after the file is removed
3469      */
3470     if (entries_line != NULL)
3471     {
3472 	free (entries_line);
3473 	entries_line = NULL;
3474     }
3475 
3476     if (scratched_file != NULL)
3477     {
3478 	buf_output0 (protocol,
3479 		     "E CVS server internal error: duplicate Scratch_Entry\n");
3480 	buf_send_counted (protocol);
3481 	return;
3482     }
3483     scratched_file = xstrdup (fname);
3484     kill_scratched_file = 1;
3485 }
3486 
3487 void
3488 server_scratch_entry_only ()
3489 {
3490     kill_scratched_file = 0;
3491 }
3492 
3493 /* Print a new entries line, from a previous server_register.  */
3494 static void
3495 new_entries_line ()
3496 {
3497     if (entries_line)
3498     {
3499 	buf_output0 (protocol, entries_line);
3500 	buf_output (protocol, "\n", 1);
3501     }
3502     else
3503 	/* Return the error message as the Entries line.  */
3504 	buf_output0 (protocol,
3505 		     "CVS server internal error: Register missing\n");
3506     free (entries_line);
3507     entries_line = NULL;
3508 }
3509 
3510 
3511 static void
3512 serve_ci (arg)
3513     char *arg;
3514 {
3515     do_cvs_command ("commit", commit);
3516 }
3517 
3518 static void
3519 checked_in_response (file, update_dir, repository)
3520     char *file;
3521     char *update_dir;
3522     char *repository;
3523 {
3524     if (supported_response ("Mode"))
3525     {
3526 	struct stat sb;
3527 	char *mode_string;
3528 
3529 	if ( CVS_STAT (file, &sb) < 0)
3530 	{
3531 	    /* Not clear to me why the file would fail to exist, but it
3532 	       was happening somewhere in the testsuite.  */
3533 	    if (!existence_error (errno))
3534 		error (0, errno, "cannot stat %s", file);
3535 	}
3536 	else
3537 	{
3538 	    buf_output0 (protocol, "Mode ");
3539 	    mode_string = mode_to_string (sb.st_mode);
3540 	    buf_output0 (protocol, mode_string);
3541 	    buf_output0 (protocol, "\n");
3542 	    free (mode_string);
3543 	}
3544     }
3545 
3546     buf_output0 (protocol, "Checked-in ");
3547     output_dir (update_dir, repository);
3548     buf_output0 (protocol, file);
3549     buf_output (protocol, "\n", 1);
3550     new_entries_line ();
3551 }
3552 
3553 void
3554 server_checked_in (file, update_dir, repository)
3555     char *file;
3556     char *update_dir;
3557     char *repository;
3558 {
3559     if (noexec)
3560 	return;
3561     if (scratched_file != NULL && entries_line == NULL)
3562     {
3563 	/*
3564 	 * This happens if we are now doing a "cvs remove" after a previous
3565 	 * "cvs add" (without a "cvs ci" in between).
3566 	 */
3567 	buf_output0 (protocol, "Remove-entry ");
3568 	output_dir (update_dir, repository);
3569 	buf_output0 (protocol, file);
3570 	buf_output (protocol, "\n", 1);
3571 	free (scratched_file);
3572 	scratched_file = NULL;
3573     }
3574     else
3575     {
3576 	checked_in_response (file, update_dir, repository);
3577     }
3578     buf_send_counted (protocol);
3579 }
3580 
3581 void
3582 server_update_entries (file, update_dir, repository, updated)
3583     char *file;
3584     char *update_dir;
3585     char *repository;
3586     enum server_updated_arg4 updated;
3587 {
3588     if (noexec)
3589 	return;
3590     if (updated == SERVER_UPDATED)
3591 	checked_in_response (file, update_dir, repository);
3592     else
3593     {
3594 	if (!supported_response ("New-entry"))
3595 	    return;
3596 	buf_output0 (protocol, "New-entry ");
3597 	output_dir (update_dir, repository);
3598 	buf_output0 (protocol, file);
3599 	buf_output (protocol, "\n", 1);
3600 	new_entries_line ();
3601     }
3602 
3603     buf_send_counted (protocol);
3604 }
3605 
3606 static void
3607 serve_update (arg)
3608     char *arg;
3609 {
3610     do_cvs_command ("update", update);
3611 }
3612 
3613 static void
3614 serve_diff (arg)
3615     char *arg;
3616 {
3617     do_cvs_command ("diff", diff);
3618 }
3619 
3620 static void
3621 serve_log (arg)
3622     char *arg;
3623 {
3624     do_cvs_command ("log", cvslog);
3625 }
3626 
3627 static void
3628 serve_rlog (arg)
3629     char *arg;
3630 {
3631     /* Tell cvslog() to behave like rlog not log.  */
3632     command_name = "rlog";
3633     do_cvs_command ("rlog", cvslog);
3634 }
3635 
3636 static void
3637 serve_add (arg)
3638     char *arg;
3639 {
3640     do_cvs_command ("add", add);
3641 }
3642 
3643 static void
3644 serve_remove (arg)
3645     char *arg;
3646 {
3647     do_cvs_command ("remove", cvsremove);
3648 }
3649 
3650 static void
3651 serve_status (arg)
3652     char *arg;
3653 {
3654     do_cvs_command ("status", cvsstatus);
3655 }
3656 
3657 static void
3658 serve_rdiff (arg)
3659     char *arg;
3660 {
3661     do_cvs_command ("rdiff", patch);
3662 }
3663 
3664 static void
3665 serve_tag (arg)
3666     char *arg;
3667 {
3668     do_cvs_command ("cvstag", cvstag);
3669 }
3670 
3671 static void
3672 serve_rtag (arg)
3673     char *arg;
3674 {
3675     /* Tell cvstag() to behave like rtag not tag.  */
3676     command_name = "rtag";
3677     do_cvs_command ("rtag", cvstag);
3678 }
3679 
3680 static void
3681 serve_import (arg)
3682     char *arg;
3683 {
3684     do_cvs_command ("import", import);
3685 }
3686 
3687 static void
3688 serve_admin (arg)
3689     char *arg;
3690 {
3691     do_cvs_command ("admin", admin);
3692 }
3693 
3694 static void
3695 serve_history (arg)
3696     char *arg;
3697 {
3698     do_cvs_command ("history", history);
3699 }
3700 
3701 static void
3702 serve_release (arg)
3703     char *arg;
3704 {
3705     do_cvs_command ("release", release);
3706 }
3707 
3708 static void serve_watch_on PROTO ((char *));
3709 
3710 static void
3711 serve_watch_on (arg)
3712     char *arg;
3713 {
3714     do_cvs_command ("watch_on", watch_on);
3715 }
3716 
3717 static void serve_watch_off PROTO ((char *));
3718 
3719 static void
3720 serve_watch_off (arg)
3721     char *arg;
3722 {
3723     do_cvs_command ("watch_off", watch_off);
3724 }
3725 
3726 static void serve_watch_add PROTO ((char *));
3727 
3728 static void
3729 serve_watch_add (arg)
3730     char *arg;
3731 {
3732     do_cvs_command ("watch_add", watch_add);
3733 }
3734 
3735 static void serve_watch_remove PROTO ((char *));
3736 
3737 static void
3738 serve_watch_remove (arg)
3739     char *arg;
3740 {
3741     do_cvs_command ("watch_remove", watch_remove);
3742 }
3743 
3744 static void serve_watchers PROTO ((char *));
3745 
3746 static void
3747 serve_watchers (arg)
3748     char *arg;
3749 {
3750     do_cvs_command ("watchers", watchers);
3751 }
3752 
3753 static void serve_editors PROTO ((char *));
3754 
3755 static void
3756 serve_editors (arg)
3757     char *arg;
3758 {
3759     do_cvs_command ("editors", editors);
3760 }
3761 
3762 static void serve_noop PROTO ((char *));
3763 
3764 static void
3765 serve_noop (arg)
3766     char *arg;
3767 {
3768 
3769     server_write_entries ();
3770     if (!print_pending_error ())
3771     {
3772 	(void) server_notify ();
3773 	buf_output0 (buf_to_net, "ok\n");
3774     }
3775     buf_flush (buf_to_net, 1);
3776 }
3777 
3778 static void serve_version PROTO ((char *));
3779 
3780 static void
3781 serve_version (arg)
3782     char *arg;
3783 {
3784     do_cvs_command ("version", version);
3785 }
3786 
3787 static void serve_init PROTO ((char *));
3788 
3789 static void
3790 serve_init (arg)
3791     char *arg;
3792 {
3793     if (!isabsolute (arg))
3794     {
3795 	if (alloc_pending (80 + strlen (arg)))
3796 	    sprintf (pending_error_text,
3797 		     "E Root %s must be an absolute pathname", arg);
3798 	/* Fall through to do_cvs_command which will return the
3799 	   actual error.  */
3800     }
3801 
3802     if (current_parsed_root != NULL)
3803 	free_cvsroot_t (current_parsed_root);
3804     current_parsed_root = local_cvsroot (arg);
3805 
3806     do_cvs_command ("init", init);
3807 }
3808 
3809 static void serve_annotate PROTO ((char *));
3810 
3811 static void
3812 serve_annotate (arg)
3813     char *arg;
3814 {
3815     do_cvs_command ("annotate", annotate);
3816 }
3817 
3818 static void serve_rannotate PROTO ((char *));
3819 
3820 static void
3821 serve_rannotate (arg)
3822     char *arg;
3823 {
3824     /* Tell annotate() to behave like rannotate not annotate.  */
3825     command_name = "rannotate";
3826     do_cvs_command ("rannotate", annotate);
3827 }
3828 
3829 static void
3830 serve_co (arg)
3831     char *arg;
3832 {
3833     char *tempdir;
3834     int status;
3835 
3836     if (print_pending_error ())
3837 	return;
3838 
3839     if (!isdir (CVSADM))
3840     {
3841 	/*
3842 	 * The client has not sent a "Repository" line.  Check out
3843 	 * into a pristine directory.
3844 	 */
3845 	tempdir = malloc (strlen (server_temp_dir) + 80);
3846 	if (tempdir == NULL)
3847 	{
3848 	    buf_output0 (buf_to_net, "E Out of memory\n");
3849 	    return;
3850 	}
3851 	strcpy (tempdir, server_temp_dir);
3852 	strcat (tempdir, "/checkout-dir");
3853 	status = mkdir_p (tempdir);
3854 	if (status != 0 && status != EEXIST)
3855 	{
3856 	    buf_output0 (buf_to_net, "E Cannot create ");
3857 	    buf_output0 (buf_to_net, tempdir);
3858 	    buf_append_char (buf_to_net, '\n');
3859 	    print_error (errno);
3860 	    free (tempdir);
3861 	    return;
3862 	}
3863 
3864 	if ( CVS_CHDIR (tempdir) < 0)
3865 	{
3866 	    buf_output0 (buf_to_net, "E Cannot change to directory ");
3867 	    buf_output0 (buf_to_net, tempdir);
3868 	    buf_append_char (buf_to_net, '\n');
3869 	    print_error (errno);
3870 	    free (tempdir);
3871 	    return;
3872 	}
3873 	free (tempdir);
3874     }
3875 
3876     /* Compensate for server_export()'s setting of command_name.
3877      *
3878      * [It probably doesn't matter if do_cvs_command() gets "export"
3879      *  or "checkout", but we ought to be accurate where possible.]
3880      */
3881     do_cvs_command ((strcmp (command_name, "export") == 0) ?
3882                     "export" : "checkout",
3883                     checkout);
3884 }
3885 
3886 static void
3887 serve_export (arg)
3888     char *arg;
3889 {
3890     /* Tell checkout() to behave like export not checkout.  */
3891     command_name = "export";
3892     serve_co (arg);
3893 }
3894 
3895 void
3896 server_copy_file (file, update_dir, repository, newfile)
3897     char *file;
3898     char *update_dir;
3899     char *repository;
3900     char *newfile;
3901 {
3902     /* At least for now, our practice is to have the server enforce
3903        noexec for the repository and the client enforce it for the
3904        working directory.  This might want more thought, and/or
3905        documentation in cvsclient.texi (other responses do it
3906        differently).  */
3907 
3908     if (!supported_response ("Copy-file"))
3909 	return;
3910     buf_output0 (protocol, "Copy-file ");
3911     output_dir (update_dir, repository);
3912     buf_output0 (protocol, file);
3913     buf_output0 (protocol, "\n");
3914     buf_output0 (protocol, newfile);
3915     buf_output0 (protocol, "\n");
3916 }
3917 
3918 /* See server.h for description.  */
3919 
3920 void
3921 server_modtime (finfo, vers_ts)
3922     struct file_info *finfo;
3923     Vers_TS *vers_ts;
3924 {
3925     char date[MAXDATELEN];
3926     char outdate[MAXDATELEN];
3927 
3928     assert (vers_ts->vn_rcs != NULL);
3929 
3930     if (!supported_response ("Mod-time"))
3931 	return;
3932 
3933     if (RCS_getrevtime (finfo->rcs, vers_ts->vn_rcs, date, 0) == (time_t) -1)
3934 	/* FIXME? should we be printing some kind of warning?  For one
3935 	   thing I'm not 100% sure whether this happens in non-error
3936 	   circumstances.  */
3937 	return;
3938     date_to_internet (outdate, date);
3939     buf_output0 (protocol, "Mod-time ");
3940     buf_output0 (protocol, outdate);
3941     buf_output0 (protocol, "\n");
3942 }
3943 
3944 /* See server.h for description.  */
3945 
3946 #if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__)
3947 /* Need to prototype because mode_t might be smaller than int.  */
3948 void
3949 server_updated (
3950     struct file_info *finfo,
3951     Vers_TS *vers,
3952     enum server_updated_arg4 updated,
3953     mode_t mode,
3954     unsigned char *checksum,
3955     struct buffer *filebuf)
3956 #else
3957 void
3958 server_updated (finfo, vers, updated, mode, checksum, filebuf)
3959     struct file_info *finfo;
3960     Vers_TS *vers;
3961     enum server_updated_arg4 updated;
3962     mode_t mode;
3963     unsigned char *checksum;
3964     struct buffer *filebuf;
3965 #endif
3966 {
3967     if (noexec)
3968     {
3969 	/* Hmm, maybe if we did the same thing for entries_file, we
3970 	   could get rid of the kludges in server_register and
3971 	   server_scratch which refrain from warning if both
3972 	   Scratch_Entry and Register get called.  Maybe.  */
3973 	if (scratched_file)
3974 	{
3975 	    free (scratched_file);
3976 	    scratched_file = NULL;
3977 	}
3978 	return;
3979     }
3980 
3981     if (entries_line != NULL && scratched_file == NULL)
3982     {
3983 	FILE *f;
3984 	struct buffer_data *list, *last;
3985 	unsigned long size;
3986 	char size_text[80];
3987 
3988 	/* The contents of the file will be in one of filebuf,
3989 	   list/last, or here.  */
3990 	unsigned char *file;
3991 	size_t file_allocated;
3992 	size_t file_used;
3993 
3994 	if (filebuf != NULL)
3995 	{
3996 	    size = buf_length (filebuf);
3997 	    if (mode == (mode_t) -1)
3998 		error (1, 0, "\
3999 CVS server internal error: no mode in server_updated");
4000 	}
4001 	else
4002 	{
4003 	    struct stat sb;
4004 
4005 	    if ( CVS_STAT (finfo->file, &sb) < 0)
4006 	    {
4007 		if (existence_error (errno))
4008 		{
4009 		    /* If we have a sticky tag for a branch on which
4010 		       the file is dead, and cvs update the directory,
4011 		       it gets a T_CHECKOUT but no file.  So in this
4012 		       case just forget the whole thing.  */
4013 		    free (entries_line);
4014 		    entries_line = NULL;
4015 		    goto done;
4016 		}
4017 		error (1, errno, "reading %s", finfo->fullname);
4018 	    }
4019 	    size = sb.st_size;
4020 	    if (mode == (mode_t) -1)
4021 	    {
4022 		/* FIXME: When we check out files the umask of the
4023 		   server (set in .bashrc if rsh is in use) affects
4024 		   what mode we send, and it shouldn't.  */
4025 		mode = sb.st_mode;
4026 	    }
4027 	}
4028 
4029 	if (checksum != NULL)
4030 	{
4031 	    static int checksum_supported = -1;
4032 
4033 	    if (checksum_supported == -1)
4034 	    {
4035 		checksum_supported = supported_response ("Checksum");
4036 	    }
4037 
4038 	    if (checksum_supported)
4039 	    {
4040 	        int i;
4041 		char buf[3];
4042 
4043 	        buf_output0 (protocol, "Checksum ");
4044 		for (i = 0; i < 16; i++)
4045 		{
4046 		    sprintf (buf, "%02x", (unsigned int) checksum[i]);
4047 		    buf_output0 (protocol, buf);
4048 		}
4049 		buf_append_char (protocol, '\n');
4050 	    }
4051 	}
4052 
4053 	if (updated == SERVER_UPDATED)
4054 	{
4055 	    Node *node;
4056 	    Entnode *entnode;
4057 
4058 	    if (!(supported_response ("Created")
4059 		  && supported_response ("Update-existing")))
4060 		buf_output0 (protocol, "Updated ");
4061 	    else
4062 	    {
4063 		assert (vers != NULL);
4064 		if (vers->ts_user == NULL)
4065 		    buf_output0 (protocol, "Created ");
4066 		else
4067 		    buf_output0 (protocol, "Update-existing ");
4068 	    }
4069 
4070 	    /* Now munge the entries to say that the file is unmodified,
4071 	       in case we end up processing it again (e.g. modules3-6
4072 	       in the testsuite).  */
4073 	    node = findnode_fn (finfo->entries, finfo->file);
4074 	    entnode = (Entnode *)node->data;
4075 	    free (entnode->timestamp);
4076 	    entnode->timestamp = xstrdup ("=");
4077 	}
4078 	else if (updated == SERVER_MERGED)
4079 	    buf_output0 (protocol, "Merged ");
4080 	else if (updated == SERVER_PATCHED)
4081 	    buf_output0 (protocol, "Patched ");
4082 	else if (updated == SERVER_RCS_DIFF)
4083 	    buf_output0 (protocol, "Rcs-diff ");
4084 	else
4085 	    abort ();
4086 	output_dir (finfo->update_dir, finfo->repository);
4087 	buf_output0 (protocol, finfo->file);
4088 	buf_output (protocol, "\n", 1);
4089 
4090 	new_entries_line ();
4091 
4092         {
4093 	    char *mode_string;
4094 
4095 	    mode_string = mode_to_string (mode);
4096 	    buf_output0 (protocol, mode_string);
4097 	    buf_output0 (protocol, "\n");
4098 	    free (mode_string);
4099 	}
4100 
4101 	list = last = NULL;
4102 
4103 	file = NULL;
4104 	file_allocated = 0;
4105 	file_used = 0;
4106 
4107 	if (size > 0)
4108 	{
4109 	    /* Throughout this section we use binary mode to read the
4110 	       file we are sending.  The client handles any line ending
4111 	       translation if necessary.  */
4112 
4113 	    if (file_gzip_level
4114 		/*
4115 		 * For really tiny files, the gzip process startup
4116 		 * time will outweigh the compression savings.  This
4117 		 * might be computable somehow; using 100 here is just
4118 		 * a first approximation.
4119 		 */
4120 		&& size > 100)
4121 	    {
4122 		/* Basing this routine on read_and_gzip is not a
4123 		   high-performance approach.  But it seems easier
4124 		   to code than the alternative (and less
4125 		   vulnerable to subtle bugs).  Given that this feature
4126 		   is mainly for compatibility, that is the better
4127 		   tradeoff.  */
4128 
4129 		int fd;
4130 
4131 		/* Callers must avoid passing us a buffer if
4132                    file_gzip_level is set.  We could handle this case,
4133                    but it's not worth it since this case never arises
4134                    with a current client and server.  */
4135 		if (filebuf != NULL)
4136 		    error (1, 0, "\
4137 CVS server internal error: unhandled case in server_updated");
4138 
4139 		fd = CVS_OPEN (finfo->file, O_RDONLY | OPEN_BINARY, 0);
4140 		if (fd < 0)
4141 		    error (1, errno, "reading %s", finfo->fullname);
4142 		if (read_and_gzip (fd, finfo->fullname, &file,
4143 				   &file_allocated, &file_used,
4144 				   file_gzip_level))
4145 		    error (1, 0, "aborting due to compression error");
4146 		size = file_used;
4147 		if (close (fd) < 0)
4148 		    error (1, errno, "reading %s", finfo->fullname);
4149 		/* Prepending length with "z" is flag for using gzip here.  */
4150 		buf_output0 (protocol, "z");
4151 	    }
4152 	    else if (filebuf == NULL)
4153 	    {
4154 		long status;
4155 
4156 		f = CVS_FOPEN (finfo->file, "rb");
4157 		if (f == NULL)
4158 		    error (1, errno, "reading %s", finfo->fullname);
4159 		status = buf_read_file (f, size, &list, &last);
4160 		if (status == -2)
4161 		    (*protocol->memory_error) (protocol);
4162 		else if (status != 0)
4163 		    error (1, ferror (f) ? errno : 0, "reading %s",
4164 			   finfo->fullname);
4165 		if (fclose (f) == EOF)
4166 		    error (1, errno, "reading %s", finfo->fullname);
4167 	    }
4168 	}
4169 
4170 	sprintf (size_text, "%lu\n", size);
4171 	buf_output0 (protocol, size_text);
4172 
4173 	if (file != NULL)
4174 	{
4175 	    buf_output (protocol, (char *) file, file_used);
4176 	    free (file);
4177 	    file = NULL;
4178 	}
4179 	else if (filebuf == NULL)
4180 	    buf_append_data (protocol, list, last);
4181 	else
4182 	{
4183 	    buf_append_buffer (protocol, filebuf);
4184 	    buf_free (filebuf);
4185 	}
4186 	/* Note we only send a newline here if the file ended with one.  */
4187 
4188 	/*
4189 	 * Avoid using up too much disk space for temporary files.
4190 	 * A file which does not exist indicates that the file is up-to-date,
4191 	 * which is now the case.  If this is SERVER_MERGED, the file is
4192 	 * not up-to-date, and we indicate that by leaving the file there.
4193 	 * I'm thinking of cases like "cvs update foo/foo.c foo".
4194 	 */
4195 	if ((updated == SERVER_UPDATED
4196 	     || updated == SERVER_PATCHED
4197 	     || updated == SERVER_RCS_DIFF)
4198 	    && filebuf == NULL
4199 	    /* But if we are joining, we'll need the file when we call
4200 	       join_file.  */
4201 	    && !joining ())
4202 	{
4203 	    if (CVS_UNLINK (finfo->file) < 0)
4204 		error (0, errno, "cannot remove temp file for %s",
4205 		       finfo->fullname);
4206 	}
4207     }
4208     else if (scratched_file != NULL && entries_line == NULL)
4209     {
4210 	if (strcmp (scratched_file, finfo->file) != 0)
4211 	    error (1, 0,
4212 		   "CVS server internal error: `%s' vs. `%s' scratched",
4213 		   scratched_file,
4214 		   finfo->file);
4215 	free (scratched_file);
4216 	scratched_file = NULL;
4217 
4218 	if (kill_scratched_file)
4219 	    buf_output0 (protocol, "Removed ");
4220 	else
4221 	    buf_output0 (protocol, "Remove-entry ");
4222 	output_dir (finfo->update_dir, finfo->repository);
4223 	buf_output0 (protocol, finfo->file);
4224 	buf_output (protocol, "\n", 1);
4225 	/* keep the vers structure up to date in case we do a join
4226 	 * - if there isn't a file, it can't very well have a version number, can it?
4227 	 *
4228 	 * we do it here on the assumption that since we just told the client
4229 	 * to remove the file/entry, it will, and we want to remember that.
4230 	 * If it fails, that's the client's problem, not ours
4231 	 */
4232 	if (vers && vers->vn_user != NULL)
4233 	{
4234 	    free (vers->vn_user);
4235 	    vers->vn_user = NULL;
4236 	}
4237 	if (vers && vers->ts_user != NULL)
4238 	{
4239 	    free (vers->ts_user);
4240 	    vers->ts_user = NULL;
4241 	}
4242     }
4243     else if (scratched_file == NULL && entries_line == NULL)
4244     {
4245 	/*
4246 	 * This can happen with death support if we were processing
4247 	 * a dead file in a checkout.
4248 	 */
4249     }
4250     else
4251 	error (1, 0,
4252 	       "CVS server internal error: Register *and* Scratch_Entry.\n");
4253     buf_send_counted (protocol);
4254   done:;
4255 }
4256 
4257 /* Return whether we should send patches in RCS format.  */
4258 
4259 int
4260 server_use_rcs_diff ()
4261 {
4262     return supported_response ("Rcs-diff");
4263 }
4264 
4265 void
4266 server_set_entstat (update_dir, repository)
4267     char *update_dir;
4268     char *repository;
4269 {
4270     static int set_static_supported = -1;
4271     if (set_static_supported == -1)
4272 	set_static_supported = supported_response ("Set-static-directory");
4273     if (!set_static_supported) return;
4274 
4275     buf_output0 (protocol, "Set-static-directory ");
4276     output_dir (update_dir, repository);
4277     buf_output0 (protocol, "\n");
4278     buf_send_counted (protocol);
4279 }
4280 
4281 void
4282 server_clear_entstat (update_dir, repository)
4283      char *update_dir;
4284      char *repository;
4285 {
4286     static int clear_static_supported = -1;
4287     if (clear_static_supported == -1)
4288 	clear_static_supported = supported_response ("Clear-static-directory");
4289     if (!clear_static_supported) return;
4290 
4291     if (noexec)
4292 	return;
4293 
4294     buf_output0 (protocol, "Clear-static-directory ");
4295     output_dir (update_dir, repository);
4296     buf_output0 (protocol, "\n");
4297     buf_send_counted (protocol);
4298 }
4299 
4300 void
4301 server_set_sticky (update_dir, repository, tag, date, nonbranch)
4302     char *update_dir;
4303     char *repository;
4304     char *tag;
4305     char *date;
4306     int nonbranch;
4307 {
4308     static int set_sticky_supported = -1;
4309 
4310     assert (update_dir != NULL);
4311 
4312     if (set_sticky_supported == -1)
4313 	set_sticky_supported = supported_response ("Set-sticky");
4314     if (!set_sticky_supported) return;
4315 
4316     if (noexec)
4317 	return;
4318 
4319     if (tag == NULL && date == NULL)
4320     {
4321 	buf_output0 (protocol, "Clear-sticky ");
4322 	output_dir (update_dir, repository);
4323 	buf_output0 (protocol, "\n");
4324     }
4325     else
4326     {
4327 	buf_output0 (protocol, "Set-sticky ");
4328 	output_dir (update_dir, repository);
4329 	buf_output0 (protocol, "\n");
4330 	if (tag != NULL)
4331 	{
4332 	    if (nonbranch)
4333 		buf_output0 (protocol, "N");
4334 	    else
4335 		buf_output0 (protocol, "T");
4336 	    buf_output0 (protocol, tag);
4337 	}
4338 	else
4339 	{
4340 	    buf_output0 (protocol, "D");
4341 	    buf_output0 (protocol, date);
4342 	}
4343 	buf_output0 (protocol, "\n");
4344     }
4345     buf_send_counted (protocol);
4346 }
4347 
4348 struct template_proc_data
4349 {
4350     char *update_dir;
4351     char *repository;
4352 };
4353 
4354 /* Here as a static until we get around to fixing Parse_Info to pass along
4355    a void * for it.  */
4356 static struct template_proc_data *tpd;
4357 
4358 static int
4359 template_proc (repository, template)
4360     char *repository;
4361     char *template;
4362 {
4363     FILE *fp;
4364     char buf[1024];
4365     size_t n;
4366     struct stat sb;
4367     struct template_proc_data *data = tpd;
4368 
4369     if (!supported_response ("Template"))
4370 	/* Might want to warn the user that the rcsinfo feature won't work.  */
4371 	return 0;
4372     buf_output0 (protocol, "Template ");
4373     output_dir (data->update_dir, data->repository);
4374     buf_output0 (protocol, "\n");
4375 
4376     fp = CVS_FOPEN (template, "rb");
4377     if (fp == NULL)
4378     {
4379 	error (0, errno, "Couldn't open rcsinfo template file %s", template);
4380 	return 1;
4381     }
4382     if (fstat (fileno (fp), &sb) < 0)
4383     {
4384 	error (0, errno, "cannot stat rcsinfo template file %s", template);
4385 	return 1;
4386     }
4387     sprintf (buf, "%ld\n", (long) sb.st_size);
4388     buf_output0 (protocol, buf);
4389     while (!feof (fp))
4390     {
4391 	n = fread (buf, 1, sizeof buf, fp);
4392 	buf_output (protocol, buf, n);
4393 	if (ferror (fp))
4394 	{
4395 	    error (0, errno, "cannot read rcsinfo template file %s", template);
4396 	    (void) fclose (fp);
4397 	    return 1;
4398 	}
4399     }
4400     if (fclose (fp) < 0)
4401 	error (0, errno, "cannot close rcsinfo template file %s", template);
4402     return 0;
4403 }
4404 
4405 void
4406 server_template (update_dir, repository)
4407     char *update_dir;
4408     char *repository;
4409 {
4410     struct template_proc_data data;
4411     data.update_dir = update_dir;
4412     data.repository = repository;
4413     tpd = &data;
4414     (void) Parse_Info (CVSROOTADM_RCSINFO, repository, template_proc, 1);
4415 }
4416 
4417 static void
4418 serve_gzip_contents (arg)
4419      char *arg;
4420 {
4421     int level;
4422     level = atoi (arg);
4423     if (level == 0)
4424 	level = 6;
4425     file_gzip_level = level;
4426 }
4427 
4428 static void
4429 serve_gzip_stream (arg)
4430      char *arg;
4431 {
4432     int level;
4433     level = atoi (arg);
4434     if (level == 0)
4435 	level = 6;
4436 
4437     /* All further communication with the client will be compressed.  */
4438 
4439     buf_to_net = compress_buffer_initialize (buf_to_net, 0, level,
4440 					     buf_to_net->memory_error);
4441     buf_from_net = compress_buffer_initialize (buf_from_net, 1, level,
4442 					       buf_from_net->memory_error);
4443 }
4444 
4445 /* Tell the client about RCS options set in CVSROOT/cvswrappers. */
4446 static void
4447 serve_wrapper_sendme_rcs_options (arg)
4448      char *arg;
4449 {
4450     /* Actually, this is kind of sdrawkcab-ssa: the client wants
4451      * verbatim lines from a cvswrappers file, but the server has
4452      * already parsed the cvswrappers file into the wrap_list struct.
4453      * Therefore, the server loops over wrap_list, unparsing each
4454      * entry before sending it.
4455      */
4456     char *wrapper_line = NULL;
4457 
4458     wrap_setup ();
4459 
4460     for (wrap_unparse_rcs_options (&wrapper_line, 1);
4461          wrapper_line;
4462          wrap_unparse_rcs_options (&wrapper_line, 0))
4463     {
4464 	buf_output0 (buf_to_net, "Wrapper-rcsOption ");
4465 	buf_output0 (buf_to_net, wrapper_line);
4466 	buf_output0 (buf_to_net, "\012");;
4467 	free (wrapper_line);
4468     }
4469 
4470     buf_output0 (buf_to_net, "ok\012");
4471 
4472     /* The client is waiting for us, so we better send the data now.  */
4473     buf_flush (buf_to_net, 1);
4474 }
4475 
4476 
4477 static void
4478 serve_ignore (arg)
4479     char *arg;
4480 {
4481     /*
4482      * Just ignore this command.  This is used to support the
4483      * update-patches command, which is not a real command, but a signal
4484      * to the client that update will accept the -u argument.
4485      */
4486 }
4487 
4488 static int
4489 expand_proc (argc, argv, where, mwhere, mfile, shorten,
4490 	     local_specified, omodule, msg)
4491     int argc;
4492     char **argv;
4493     char *where;
4494     char *mwhere;
4495     char *mfile;
4496     int shorten;
4497     int local_specified;
4498     char *omodule;
4499     char *msg;
4500 {
4501     int i;
4502     char *dir = argv[0];
4503 
4504     /* If mwhere has been specified, the thing we're expanding is a
4505        module -- just return its name so the client will ask for the
4506        right thing later.  If it is an alias or a real directory,
4507        mwhere will not be set, so send out the appropriate
4508        expansion. */
4509 
4510     if (mwhere != NULL)
4511     {
4512 	buf_output0 (buf_to_net, "Module-expansion ");
4513 	if (server_dir != NULL)
4514 	{
4515 	    buf_output0 (buf_to_net, server_dir);
4516 	    buf_output0 (buf_to_net, "/");
4517 	}
4518 	buf_output0 (buf_to_net, mwhere);
4519 	if (mfile != NULL)
4520 	{
4521 	    buf_append_char (buf_to_net, '/');
4522 	    buf_output0 (buf_to_net, mfile);
4523 	}
4524 	buf_append_char (buf_to_net, '\n');
4525     }
4526     else
4527     {
4528 	/* We may not need to do this anymore -- check the definition
4529            of aliases before removing */
4530 	if (argc == 1)
4531 	{
4532 	    buf_output0 (buf_to_net, "Module-expansion ");
4533 	    if (server_dir != NULL)
4534 	    {
4535 		buf_output0 (buf_to_net, server_dir);
4536 		buf_output0 (buf_to_net, "/");
4537 	    }
4538 	    buf_output0 (buf_to_net, dir);
4539 	    buf_append_char (buf_to_net, '\n');
4540 	}
4541 	else
4542 	{
4543 	    for (i = 1; i < argc; ++i)
4544 	    {
4545 	        buf_output0 (buf_to_net, "Module-expansion ");
4546 		if (server_dir != NULL)
4547 		{
4548 		    buf_output0 (buf_to_net, server_dir);
4549 		    buf_output0 (buf_to_net, "/");
4550 		}
4551 		buf_output0 (buf_to_net, dir);
4552 		buf_append_char (buf_to_net, '/');
4553 		buf_output0 (buf_to_net, argv[i]);
4554 		buf_append_char (buf_to_net, '\n');
4555 	    }
4556 	}
4557     }
4558     return 0;
4559 }
4560 
4561 static void
4562 serve_expand_modules (arg)
4563     char *arg;
4564 {
4565     int i;
4566     int err;
4567     DBM *db;
4568     err = 0;
4569 
4570     server_expanding = 1;
4571     db = open_module ();
4572     for (i = 1; i < argument_count; i++)
4573 	err += do_module (db, argument_vector[i],
4574 			  CHECKOUT, "Updating", expand_proc,
4575 			  NULL, 0, 0, 0, 0,
4576 			  (char *) NULL);
4577     close_module (db);
4578     server_expanding = 0;
4579     {
4580 	/* argument_vector[0] is a dummy argument, we don't mess with it.  */
4581 	char **cp;
4582 	for (cp = argument_vector + 1;
4583 	     cp < argument_vector + argument_count;
4584 	     ++cp)
4585 	    free (*cp);
4586 
4587 	argument_count = 1;
4588     }
4589     if (err)
4590 	/* We will have printed an error message already.  */
4591 	buf_output0 (buf_to_net, "error  \n");
4592     else
4593 	buf_output0 (buf_to_net, "ok\n");
4594 
4595     /* The client is waiting for the module expansions, so we must
4596        send the output now.  */
4597     buf_flush (buf_to_net, 1);
4598 }
4599 
4600 void
4601 server_prog (dir, name, which)
4602     char *dir;
4603     char *name;
4604     enum progs which;
4605 {
4606     if (!supported_response ("Set-checkin-prog"))
4607     {
4608 	buf_output0 (buf_to_net, "E \
4609 warning: this client does not support -i or -u flags in the modules file.\n");
4610 	return;
4611     }
4612     switch (which)
4613     {
4614 	case PROG_CHECKIN:
4615 	    buf_output0 (buf_to_net, "Set-checkin-prog ");
4616 	    break;
4617 	case PROG_UPDATE:
4618 	    buf_output0 (buf_to_net, "Set-update-prog ");
4619 	    break;
4620     }
4621     buf_output0 (buf_to_net, dir);
4622     buf_append_char (buf_to_net, '\n');
4623     buf_output0 (buf_to_net, name);
4624     buf_append_char (buf_to_net, '\n');
4625 }
4626 
4627 static void
4628 serve_checkin_prog (arg)
4629     char *arg;
4630 {
4631     FILE *f;
4632     f = CVS_FOPEN (CVSADM_CIPROG, "w+");
4633     if (f == NULL)
4634     {
4635 	int save_errno = errno;
4636 	if (alloc_pending (80 + strlen (CVSADM_CIPROG)))
4637 	    sprintf (pending_error_text, "E cannot open %s", CVSADM_CIPROG);
4638 	pending_error = save_errno;
4639 	return;
4640     }
4641     if (fprintf (f, "%s\n", arg) < 0)
4642     {
4643 	int save_errno = errno;
4644 	if (alloc_pending (80 + strlen (CVSADM_CIPROG)))
4645 	    sprintf (pending_error_text,
4646 		     "E cannot write to %s", CVSADM_CIPROG);
4647 	pending_error = save_errno;
4648 	return;
4649     }
4650     if (fclose (f) == EOF)
4651     {
4652 	int save_errno = errno;
4653 	if (alloc_pending (80 + strlen (CVSADM_CIPROG)))
4654 	    sprintf (pending_error_text, "E cannot close %s", CVSADM_CIPROG);
4655 	pending_error = save_errno;
4656 	return;
4657     }
4658 }
4659 
4660 static void
4661 serve_update_prog (arg)
4662     char *arg;
4663 {
4664     FILE *f;
4665 
4666     /* Before we do anything we need to make sure we are not in readonly
4667        mode.  */
4668     if (!check_command_legal_p ("commit"))
4669     {
4670 	/* I might be willing to make this a warning, except we lack the
4671 	   machinery to do so.  */
4672 	if (alloc_pending (80))
4673 	    sprintf (pending_error_text, "\
4674 E Flag -u in modules not allowed in readonly mode");
4675 	return;
4676     }
4677 
4678     f = CVS_FOPEN (CVSADM_UPROG, "w+");
4679     if (f == NULL)
4680     {
4681 	int save_errno = errno;
4682 	if (alloc_pending (80 + strlen (CVSADM_UPROG)))
4683 	    sprintf (pending_error_text, "E cannot open %s", CVSADM_UPROG);
4684 	pending_error = save_errno;
4685 	return;
4686     }
4687     if (fprintf (f, "%s\n", arg) < 0)
4688     {
4689 	int save_errno = errno;
4690 	if (alloc_pending (80 + strlen (CVSADM_UPROG)))
4691 	    sprintf (pending_error_text, "E cannot write to %s", CVSADM_UPROG);
4692 	pending_error = save_errno;
4693 	return;
4694     }
4695     if (fclose (f) == EOF)
4696     {
4697 	int save_errno = errno;
4698 	if (alloc_pending (80 + strlen (CVSADM_UPROG)))
4699 	    sprintf (pending_error_text, "E cannot close %s", CVSADM_UPROG);
4700 	pending_error = save_errno;
4701 	return;
4702     }
4703 }
4704 
4705 static void serve_valid_requests PROTO((char *arg));
4706 
4707 #endif /* SERVER_SUPPORT */
4708 #if defined(SERVER_SUPPORT) || defined(CLIENT_SUPPORT)
4709 
4710 /*
4711  * Parts of this table are shared with the client code,
4712  * but the client doesn't need to know about the handler
4713  * functions.
4714  */
4715 
4716 struct request requests[] =
4717 {
4718 #ifdef SERVER_SUPPORT
4719 #define REQ_LINE(n, f, s) {n, f, s}
4720 #else
4721 #define REQ_LINE(n, f, s) {n, s}
4722 #endif
4723 
4724   REQ_LINE("Root", serve_root, RQ_ESSENTIAL | RQ_ROOTLESS),
4725   REQ_LINE("Valid-responses", serve_valid_responses,
4726 	   RQ_ESSENTIAL | RQ_ROOTLESS),
4727   REQ_LINE("valid-requests", serve_valid_requests,
4728 	   RQ_ESSENTIAL | RQ_ROOTLESS),
4729   REQ_LINE("Repository", serve_repository, 0),
4730   REQ_LINE("Directory", serve_directory, RQ_ESSENTIAL),
4731   REQ_LINE("Max-dotdot", serve_max_dotdot, 0),
4732   REQ_LINE("Static-directory", serve_static_directory, 0),
4733   REQ_LINE("Sticky", serve_sticky, 0),
4734   REQ_LINE("Checkin-prog", serve_checkin_prog, 0),
4735   REQ_LINE("Update-prog", serve_update_prog, 0),
4736   REQ_LINE("Entry", serve_entry, RQ_ESSENTIAL),
4737   REQ_LINE("Kopt", serve_kopt, 0),
4738   REQ_LINE("Checkin-time", serve_checkin_time, 0),
4739   REQ_LINE("Modified", serve_modified, RQ_ESSENTIAL),
4740   REQ_LINE("Is-modified", serve_is_modified, 0),
4741 
4742   /* The client must send this request to interoperate with CVS 1.5
4743      through 1.9 servers.  The server must support it (although it can
4744      be and is a noop) to interoperate with CVS 1.5 to 1.9 clients.  */
4745   REQ_LINE("UseUnchanged", serve_enable_unchanged, RQ_ENABLEME | RQ_ROOTLESS),
4746 
4747   REQ_LINE("Unchanged", serve_unchanged, RQ_ESSENTIAL),
4748   REQ_LINE("Notify", serve_notify, 0),
4749   REQ_LINE("Questionable", serve_questionable, 0),
4750   REQ_LINE("Case", serve_case, 0),
4751   REQ_LINE("Argument", serve_argument, RQ_ESSENTIAL),
4752   REQ_LINE("Argumentx", serve_argumentx, RQ_ESSENTIAL),
4753   REQ_LINE("Global_option", serve_global_option, RQ_ROOTLESS),
4754   REQ_LINE("Gzip-stream", serve_gzip_stream, 0),
4755   REQ_LINE("wrapper-sendme-rcsOptions",
4756            serve_wrapper_sendme_rcs_options,
4757            0),
4758   REQ_LINE("Set", serve_set, RQ_ROOTLESS),
4759 #ifdef ENCRYPTION
4760 #  ifdef HAVE_KERBEROS
4761   REQ_LINE("Kerberos-encrypt", serve_kerberos_encrypt, 0),
4762 #  endif
4763 #  ifdef HAVE_GSSAPI
4764   REQ_LINE("Gssapi-encrypt", serve_gssapi_encrypt, 0),
4765 #  endif
4766 #endif
4767 #ifdef HAVE_GSSAPI
4768   REQ_LINE("Gssapi-authenticate", serve_gssapi_authenticate, 0),
4769 #endif
4770   REQ_LINE("expand-modules", serve_expand_modules, 0),
4771   REQ_LINE("ci", serve_ci, RQ_ESSENTIAL),
4772   REQ_LINE("co", serve_co, RQ_ESSENTIAL),
4773   REQ_LINE("update", serve_update, RQ_ESSENTIAL),
4774   REQ_LINE("diff", serve_diff, 0),
4775   REQ_LINE("log", serve_log, 0),
4776   REQ_LINE("rlog", serve_rlog, 0),
4777   REQ_LINE("add", serve_add, 0),
4778   REQ_LINE("remove", serve_remove, 0),
4779   REQ_LINE("update-patches", serve_ignore, 0),
4780   REQ_LINE("gzip-file-contents", serve_gzip_contents, 0),
4781   REQ_LINE("status", serve_status, 0),
4782   REQ_LINE("rdiff", serve_rdiff, 0),
4783   REQ_LINE("tag", serve_tag, 0),
4784   REQ_LINE("rtag", serve_rtag, 0),
4785   REQ_LINE("import", serve_import, 0),
4786   REQ_LINE("admin", serve_admin, 0),
4787   REQ_LINE("export", serve_export, 0),
4788   REQ_LINE("history", serve_history, 0),
4789   REQ_LINE("release", serve_release, 0),
4790   REQ_LINE("watch-on", serve_watch_on, 0),
4791   REQ_LINE("watch-off", serve_watch_off, 0),
4792   REQ_LINE("watch-add", serve_watch_add, 0),
4793   REQ_LINE("watch-remove", serve_watch_remove, 0),
4794   REQ_LINE("watchers", serve_watchers, 0),
4795   REQ_LINE("editors", serve_editors, 0),
4796   REQ_LINE("init", serve_init, RQ_ROOTLESS),
4797   REQ_LINE("annotate", serve_annotate, 0),
4798   REQ_LINE("rannotate", serve_rannotate, 0),
4799   REQ_LINE("noop", serve_noop, RQ_ROOTLESS),
4800   REQ_LINE("version", serve_version, RQ_ROOTLESS),
4801   REQ_LINE(NULL, NULL, 0)
4802 
4803 #undef REQ_LINE
4804 };
4805 
4806 #endif /* SERVER_SUPPORT or CLIENT_SUPPORT */
4807 #ifdef SERVER_SUPPORT
4808 
4809 static void
4810 serve_valid_requests (arg)
4811      char *arg;
4812 {
4813     struct request *rq;
4814     if (print_pending_error ())
4815 	return;
4816     buf_output0 (buf_to_net, "Valid-requests");
4817     for (rq = requests; rq->name != NULL; rq++)
4818     {
4819 	if (rq->func != NULL)
4820 	{
4821 	    buf_append_char (buf_to_net, ' ');
4822 	    buf_output0 (buf_to_net, rq->name);
4823 	}
4824     }
4825     buf_output0 (buf_to_net, "\nok\n");
4826 
4827     /* The client is waiting for the list of valid requests, so we
4828        must send the output now.  */
4829     buf_flush (buf_to_net, 1);
4830 }
4831 
4832 #ifdef SUNOS_KLUDGE
4833 /*
4834  * Delete temporary files.  SIG is the signal making this happen, or
4835  * 0 if not called as a result of a signal.
4836  */
4837 static int command_pid_is_dead;
4838 static void wait_sig (sig)
4839      int sig;
4840 {
4841     int status;
4842     int save_errno = errno;
4843 
4844     pid_t r = wait (&status);
4845     if (r == command_pid)
4846 	command_pid_is_dead++;
4847     errno = save_errno;
4848 }
4849 #endif /* SUNOS_KLUDGE */
4850 
4851 void
4852 server_cleanup (sig)
4853     int sig;
4854 {
4855     /* Do "rm -rf" on the temp directory.  */
4856     int status;
4857     int save_noexec;
4858 
4859     if (buf_to_net != NULL)
4860     {
4861 	/* FIXME: If this is not the final call from server, this
4862 	   could deadlock, because the client might be blocked writing
4863 	   to us.  This should not be a problem in practice, because
4864 	   we do not generate much output when the client is not
4865 	   waiting for it.  */
4866 	set_block (buf_to_net);
4867 	buf_flush (buf_to_net, 1);
4868 
4869 	/* The calls to buf_shutdown are currently only meaningful
4870 	   when we are using compression.  First we shut down
4871 	   BUF_FROM_NET.  That will pick up the checksum generated
4872 	   when the client shuts down its buffer.  Then, after we have
4873 	   generated any final output, we shut down BUF_TO_NET.  */
4874 
4875 	status = buf_shutdown (buf_from_net);
4876 	if (status != 0)
4877 	{
4878 	    error (0, status, "shutting down buffer from client");
4879 	    buf_flush (buf_to_net, 1);
4880 	}
4881     }
4882 
4883     if (dont_delete_temp)
4884     {
4885 	if (buf_to_net != NULL)
4886 	    (void) buf_shutdown (buf_to_net);
4887 	return;
4888     }
4889 
4890     /* What a bogus kludge.  This disgusting code makes all kinds of
4891        assumptions about SunOS, and is only for a bug in that system.
4892        So only enable it on Suns.  */
4893 #ifdef SUNOS_KLUDGE
4894     if (command_pid > 0)
4895     {
4896 	/* To avoid crashes on SunOS due to bugs in SunOS tmpfs
4897 	   triggered by the use of rename() in RCS, wait for the
4898 	   subprocess to die.  Unfortunately, this means draining output
4899 	   while waiting for it to unblock the signal we sent it.  Yuck!  */
4900 	int status;
4901 	pid_t r;
4902 
4903 	signal (SIGCHLD, wait_sig);
4904 	if (sig)
4905 	    /* Perhaps SIGTERM would be more correct.  But the child
4906 	       process will delay the SIGINT delivery until its own
4907 	       children have exited.  */
4908 	    kill (command_pid, SIGINT);
4909 	/* The caller may also have sent a signal to command_pid, so
4910 	   always try waiting.  First, though, check and see if it's still
4911 	   there....  */
4912     do_waitpid:
4913 	r = waitpid (command_pid, &status, WNOHANG);
4914 	if (r == 0)
4915 	    ;
4916 	else if (r == command_pid)
4917 	    command_pid_is_dead++;
4918 	else if (r == -1)
4919 	    switch (errno)
4920 	    {
4921 		case ECHILD:
4922 		    command_pid_is_dead++;
4923 		    break;
4924 		case EINTR:
4925 		    goto do_waitpid;
4926 	    }
4927 	else
4928 	    /* waitpid should always return one of the above values */
4929 	    abort ();
4930 	while (!command_pid_is_dead)
4931 	{
4932 	    struct timeval timeout;
4933 	    struct fd_set_wrapper readfds;
4934 	    char buf[100];
4935 	    int i;
4936 
4937 	    /* Use a non-zero timeout to avoid eating up CPU cycles.  */
4938 	    timeout.tv_sec = 2;
4939 	    timeout.tv_usec = 0;
4940 	    readfds = command_fds_to_drain;
4941 	    switch (select (max_command_fd + 1, &readfds.fds,
4942 			    (fd_set *)0, (fd_set *)0,
4943 			    &timeout))
4944 	    {
4945 		case -1:
4946 		    if (errno != EINTR)
4947 			abort ();
4948 		case 0:
4949 		    /* timeout */
4950 		    break;
4951 		case 1:
4952 		    for (i = 0; i <= max_command_fd; i++)
4953 		    {
4954 			if (!FD_ISSET (i, &readfds.fds))
4955 			    continue;
4956 			/* this fd is non-blocking */
4957 			while (read (i, buf, sizeof (buf)) >= 1)
4958 			    ;
4959 		    }
4960 		    break;
4961 		default:
4962 		    abort ();
4963 	    }
4964 	}
4965     }
4966 #endif /* SUNOS_KLUDGE */
4967 
4968     CVS_CHDIR (Tmpdir);
4969     /* Temporarily clear noexec, so that we clean up our temp directory
4970        regardless of it (this could more cleanly be handled by moving
4971        the noexec check to all the unlink_file_dir callers from
4972        unlink_file_dir itself).  */
4973     save_noexec = noexec;
4974     noexec = 0;
4975     /* FIXME?  Would be nice to not ignore errors.  But what should we do?
4976        We could try to do this before we shut down the network connection,
4977        and try to notify the client (but the client might not be waiting
4978        for responses).  We could try something like syslog() or our own
4979        log file.  */
4980     unlink_file_dir (orig_server_temp_dir);
4981     noexec = save_noexec;
4982 
4983     if (buf_to_net != NULL)
4984 	(void) buf_shutdown (buf_to_net);
4985 }
4986 
4987 int server_active = 0;
4988 int server_expanding = 0;
4989 
4990 int
4991 server (argc, argv)
4992      int argc;
4993      char **argv;
4994 {
4995     if (argc == -1)
4996     {
4997 	static const char *const msg[] =
4998 	{
4999 	    "Usage: %s %s\n",
5000 	    "  Normally invoked by a cvs client on a remote machine.\n",
5001 	    NULL
5002 	};
5003 	usage (msg);
5004     }
5005     /* Ignore argc and argv.  They might be from .cvsrc.  */
5006 
5007     buf_to_net = fd_buffer_initialize (STDOUT_FILENO, 0,
5008 				       outbuf_memory_error);
5009     buf_from_net = stdio_buffer_initialize (stdin, 1, outbuf_memory_error);
5010 
5011     saved_output = buf_nonio_initialize (outbuf_memory_error);
5012     saved_outerr = buf_nonio_initialize (outbuf_memory_error);
5013 
5014     /* Since we're in the server parent process, error should use the
5015        protocol to report error messages.  */
5016     error_use_protocol = 1;
5017 
5018     /* OK, now figure out where we stash our temporary files.  */
5019     {
5020 	char *p;
5021 
5022 	/* The code which wants to chdir into server_temp_dir is not set
5023 	   up to deal with it being a relative path.  So give an error
5024 	   for that case.  */
5025 	if (!isabsolute (Tmpdir))
5026 	{
5027 	    if (alloc_pending (80 + strlen (Tmpdir)))
5028 		sprintf (pending_error_text,
5029 			 "E Value of %s for TMPDIR is not absolute", Tmpdir);
5030 
5031 	    /* FIXME: we would like this error to be persistent, that
5032 	       is, not cleared by print_pending_error.  The current client
5033 	       will exit as soon as it gets an error, but the protocol spec
5034 	       does not require a client to do so.  */
5035 	}
5036 	else
5037 	{
5038 	    int status;
5039 	    int i = 0;
5040 
5041 	    server_temp_dir = malloc (strlen (Tmpdir) + 80);
5042 	    if (server_temp_dir == NULL)
5043 	    {
5044 		/*
5045 		 * Strictly speaking, we're not supposed to output anything
5046 		 * now.  But we're about to exit(), give it a try.
5047 		 */
5048 		printf ("E Fatal server error, aborting.\n\
5049 error ENOMEM Virtual memory exhausted.\n");
5050 
5051 		/* I'm doing this manually rather than via error_exit ()
5052 		   because I'm not sure whether we want to call server_cleanup.
5053 		   Needs more investigation....  */
5054 
5055 #ifdef SYSTEM_CLEANUP
5056 		/* Hook for OS-specific behavior, for example socket
5057 		   subsystems on NT and OS2 or dealing with windows
5058 		   and arguments on Mac.  */
5059 		SYSTEM_CLEANUP ();
5060 #endif
5061 
5062 		exit (EXIT_FAILURE);
5063 	    }
5064 	    strcpy (server_temp_dir, Tmpdir);
5065 
5066 	    /* Remove a trailing slash from TMPDIR if present.  */
5067 	    p = server_temp_dir + strlen (server_temp_dir) - 1;
5068 	    if (*p == '/')
5069 		*p = '\0';
5070 
5071 	    /*
5072 	     * I wanted to use cvs-serv/PID, but then you have to worry about
5073 	     * the permissions on the cvs-serv directory being right.  So
5074 	     * use cvs-servPID.
5075 	     */
5076 	    strcat (server_temp_dir, "/cvs-serv");
5077 
5078 	    p = server_temp_dir + strlen (server_temp_dir);
5079 	    sprintf (p, "%ld", (long) getpid ());
5080 
5081 	    orig_server_temp_dir = server_temp_dir;
5082 
5083 	    /* Create the temporary directory, and set the mode to
5084                700, to discourage random people from tampering with
5085                it.  */
5086 	    while ((status = mkdir_p (server_temp_dir)) == EEXIST)
5087 	    {
5088 	        static const char suffix[] = "abcdefghijklmnopqrstuvwxyz";
5089 
5090 	        if (i >= sizeof suffix - 1) break;
5091 		if (i == 0) p = server_temp_dir + strlen (server_temp_dir);
5092 		p[0] = suffix[i++];
5093 		p[1] = '\0';
5094 	    }
5095 	    if (status != 0)
5096 	    {
5097 		if (alloc_pending (80 + strlen (server_temp_dir)))
5098 		    sprintf (pending_error_text,
5099 			    "E can't create temporary directory %s",
5100 			    server_temp_dir);
5101 		pending_error = status;
5102 	    }
5103 #ifndef CHMOD_BROKEN
5104 	    else if (chmod (server_temp_dir, S_IRWXU) < 0)
5105 	    {
5106 		int save_errno = errno;
5107 		if (alloc_pending (80 + strlen (server_temp_dir)))
5108 		    sprintf (pending_error_text,
5109 "E cannot change permissions on temporary directory %s",
5110 			     server_temp_dir);
5111 		pending_error = save_errno;
5112 	    }
5113 #endif
5114 	    else if (CVS_CHDIR (server_temp_dir) < 0)
5115 	    {
5116 		int save_errno = errno;
5117 		if (alloc_pending (80 + strlen (server_temp_dir)))
5118 		    sprintf (pending_error_text,
5119 "E cannot change to temporary directory %s",
5120 			     server_temp_dir);
5121 		pending_error = save_errno;
5122 	    }
5123 	}
5124     }
5125 
5126 #ifdef SIGABRT
5127     (void) SIG_register (SIGABRT, server_cleanup);
5128 #endif
5129 #ifdef SIGHUP
5130     (void) SIG_register (SIGHUP, server_cleanup);
5131 #endif
5132 #ifdef SIGINT
5133     (void) SIG_register (SIGINT, server_cleanup);
5134 #endif
5135 #ifdef SIGQUIT
5136     (void) SIG_register (SIGQUIT, server_cleanup);
5137 #endif
5138 #ifdef SIGPIPE
5139     (void) SIG_register (SIGPIPE, server_cleanup);
5140 #endif
5141 #ifdef SIGTERM
5142     (void) SIG_register (SIGTERM, server_cleanup);
5143 #endif
5144 
5145     /* Now initialize our argument vector (for arguments from the client).  */
5146 
5147     /* Small for testing.  */
5148     argument_vector_size = 1;
5149     argument_vector =
5150 	(char **) malloc (argument_vector_size * sizeof (char *));
5151     if (argument_vector == NULL)
5152     {
5153 	/*
5154 	 * Strictly speaking, we're not supposed to output anything
5155 	 * now.  But we're about to exit(), give it a try.
5156 	 */
5157 	printf ("E Fatal server error, aborting.\n\
5158 error ENOMEM Virtual memory exhausted.\n");
5159 
5160 	/* I'm doing this manually rather than via error_exit ()
5161 	   because I'm not sure whether we want to call server_cleanup.
5162 	   Needs more investigation....  */
5163 
5164 #ifdef SYSTEM_CLEANUP
5165 	/* Hook for OS-specific behavior, for example socket subsystems on
5166 	   NT and OS2 or dealing with windows and arguments on Mac.  */
5167 	SYSTEM_CLEANUP ();
5168 #endif
5169 
5170 	exit (EXIT_FAILURE);
5171     }
5172 
5173     argument_count = 1;
5174     /* This gets printed if the client supports an option which the
5175        server doesn't, causing the server to print a usage message.
5176        FIXME: probably should be using program_name here.
5177        FIXME: just a nit, I suppose, but the usage message the server
5178        prints isn't literally true--it suggests "cvs server" followed
5179        by options which are for a particular command.  Might be nice to
5180        say something like "client apparently supports an option not supported
5181        by this server" or something like that instead of usage message.  */
5182     argument_vector[0] = "cvs server";
5183 
5184     while (1)
5185     {
5186 	char *cmd, *orig_cmd;
5187 	struct request *rq;
5188 	int status;
5189 
5190 	status = buf_read_line (buf_from_net, &cmd, (int *) NULL);
5191 	if (status == -2)
5192 	{
5193 	    buf_output0 (buf_to_net, "E Fatal server error, aborting.\n\
5194 error ENOMEM Virtual memory exhausted.\n");
5195 	    break;
5196 	}
5197 	if (status != 0)
5198 	    break;
5199 
5200 	orig_cmd = cmd;
5201 	for (rq = requests; rq->name != NULL; ++rq)
5202 	    if (strncmp (cmd, rq->name, strlen (rq->name)) == 0)
5203 	    {
5204 		int len = strlen (rq->name);
5205 		if (cmd[len] == '\0')
5206 		    cmd += len;
5207 		else if (cmd[len] == ' ')
5208 		    cmd += len + 1;
5209 		else
5210 		    /*
5211 		     * The first len characters match, but it's a different
5212 		     * command.  e.g. the command is "cooperate" but we matched
5213 		     * "co".
5214 		     */
5215 		    continue;
5216 
5217 		if (!(rq->flags & RQ_ROOTLESS)
5218 		    && current_parsed_root == NULL)
5219 		{
5220 		    /* For commands which change the way in which data
5221 		       is sent and received, for example Gzip-stream,
5222 		       this does the wrong thing.  Since the client
5223 		       assumes that everything is being compressed,
5224 		       unconditionally, there is no way to give this
5225 		       error to the client without turning on
5226 		       compression.  The obvious fix would be to make
5227 		       Gzip-stream RQ_ROOTLESS (with the corresponding
5228 		       change to the spec), and that might be a good
5229 		       idea but then again I can see some settings in
5230 		       CVSROOT about what compression level to allow.
5231 		       I suppose a more baroque answer would be to
5232 		       turn on compression (say, at level 1), just
5233 		       enough to give the "Root request missing"
5234 		       error.  For now we just lose.  */
5235 		    if (alloc_pending (80))
5236 			sprintf (pending_error_text,
5237 				 "E Protocol error: Root request missing");
5238 		}
5239 		else
5240 		    (*rq->func) (cmd);
5241 		break;
5242 	    }
5243 	if (rq->name == NULL)
5244 	{
5245 	    if (!print_pending_error ())
5246 	    {
5247 	        buf_output0 (buf_to_net, "error  unrecognized request `");
5248 		buf_output0 (buf_to_net, cmd);
5249 		buf_append_char (buf_to_net, '\'');
5250 		buf_append_char (buf_to_net, '\n');
5251 	    }
5252 	}
5253 	free (orig_cmd);
5254     }
5255     server_cleanup (0);
5256     return 0;
5257 }
5258 
5259 
5260 #if defined (HAVE_KERBEROS) || defined (AUTH_SERVER_SUPPORT) || defined (HAVE_GSSAPI)
5261 static void switch_to_user PROTO((const char *));
5262 
5263 static void
5264 switch_to_user (username)
5265     const char *username;
5266 {
5267     struct passwd *pw;
5268 
5269     pw = getpwnam (username);
5270     if (pw == NULL)
5271     {
5272 	/* Normally this won't be reached; check_password contains
5273 	   a similar check.  */
5274 
5275 	printf ("E Fatal error, aborting.\n\
5276 error 0 %s: no such user\n", username);
5277 	/* Don't worry about server_cleanup; server_active isn't set yet.  */
5278 	error_exit ();
5279     }
5280 
5281 #if HAVE_INITGROUPS
5282     if (initgroups (pw->pw_name, pw->pw_gid) < 0
5283 #  ifdef EPERM
5284 	/* At least on the system I tried, initgroups() only works as root.
5285 	   But we do still want to report ENOMEM and whatever other
5286 	   errors initgroups() might dish up.  */
5287 	&& errno != EPERM
5288 #  endif
5289 	)
5290     {
5291 	/* This could be a warning, but I'm not sure I see the point
5292 	   in doing that instead of an error given that it would happen
5293 	   on every connection.  We could log it somewhere and not tell
5294 	   the user.  But at least for now make it an error.  */
5295 	printf ("error 0 initgroups failed: %s\n", strerror (errno));
5296 	/* Don't worry about server_cleanup; server_active isn't set yet.  */
5297 	error_exit ();
5298     }
5299 #endif /* HAVE_INITGROUPS */
5300 
5301 #ifdef SETXID_SUPPORT
5302     /* honor the setgid bit iff set*/
5303     if (getgid() != getegid())
5304     {
5305 	if (setgid (getegid ()) < 0)
5306 	{
5307 	    /* See comments at setuid call below for more discussion.  */
5308 	    printf ("error 0 setgid failed: %s\n", strerror (errno));
5309 	    /* Don't worry about server_cleanup;
5310 	       server_active isn't set yet.  */
5311 	    error_exit ();
5312 	}
5313     }
5314     else
5315 #endif
5316     {
5317 	if (setgid (pw->pw_gid) < 0)
5318 	{
5319 	    /* See comments at setuid call below for more discussion.  */
5320 	    printf ("error 0 setgid failed: %s\n", strerror (errno));
5321 	    /* Don't worry about server_cleanup;
5322 	       server_active isn't set yet.  */
5323 	    error_exit ();
5324 	}
5325     }
5326 
5327     if (setuid (pw->pw_uid) < 0)
5328     {
5329 	/* Note that this means that if run as a non-root user,
5330 	   CVSROOT/passwd must contain the user we are running as
5331 	   (e.g. "joe:FsEfVcu:cvs" if run as "cvs" user).  This seems
5332 	   cleaner than ignoring the error like CVS 1.10 and older but
5333 	   it does mean that some people might need to update their
5334 	   CVSROOT/passwd file.  */
5335 	printf ("error 0 setuid failed: %s\n", strerror (errno));
5336 	/* Don't worry about server_cleanup; server_active isn't set yet.  */
5337 	error_exit ();
5338     }
5339 
5340     /* We don't want our umask to change file modes.  The modes should
5341        be set by the modes used in the repository, and by the umask of
5342        the client.  */
5343     umask (0);
5344 
5345 #ifdef AUTH_SERVER_SUPPORT
5346     /* Make sure our CVS_Username has been set. */
5347     if (CVS_Username == NULL)
5348 	CVS_Username = xstrdup (username);
5349 #endif
5350 
5351 #if HAVE_PUTENV
5352     /* Set LOGNAME, USER and CVS_USER in the environment, in case they
5353        are already set to something else.  */
5354     {
5355 	char *env;
5356 #ifdef AUTH_SERVER_SUPPORT
5357 	char *cvs_user;
5358 #endif
5359 
5360 	env = xmalloc (sizeof "LOGNAME=" + strlen (username));
5361 	(void) sprintf (env, "LOGNAME=%s", username);
5362 	(void) putenv (env);
5363 
5364 	env = xmalloc (sizeof "USER=" + strlen (username));
5365 	(void) sprintf (env, "USER=%s", username);
5366 	(void) putenv (env);
5367 
5368 #ifdef AUTH_SERVER_SUPPORT
5369         cvs_user = NULL != CVS_Username ? CVS_Username : "";
5370         env = xmalloc (sizeof "CVS_USER=" + strlen (cvs_user));
5371         (void) sprintf (env, "CVS_USER=%s", cvs_user);
5372         (void) putenv (env);
5373 #endif
5374     }
5375 #endif /* HAVE_PUTENV */
5376 }
5377 #endif
5378 
5379 #ifdef AUTH_SERVER_SUPPORT
5380 
5381 extern char *crypt PROTO((const char *, const char *));
5382 
5383 
5384 /*
5385  * 0 means no entry found for this user.
5386  * 1 means entry found and password matches (or found password is empty)
5387  * 2 means entry found, but password does not match.
5388  *
5389  * If 1, host_user_ptr will be set to point at the system
5390  * username (i.e., the "real" identity, which may or may not be the
5391  * CVS username) of this user; caller may free this.  Global
5392  * CVS_Username will point at an allocated copy of cvs username (i.e.,
5393  * the username argument below).
5394  * kff todo: FIXME: last sentence is not true, it applies to caller.
5395  */
5396 static int
5397 check_repository_password (username, password, repository, host_user_ptr)
5398      char *username, *password, *repository, **host_user_ptr;
5399 {
5400     int retval = 0;
5401     FILE *fp;
5402     char *filename;
5403     char *linebuf = NULL;
5404     size_t linebuf_len;
5405     int found_it = 0;
5406     int namelen;
5407 
5408     /* We don't use current_parsed_root->directory because it hasn't been set yet
5409      * -- our `repository' argument came from the authentication
5410      * protocol, not the regular CVS protocol.
5411      */
5412 
5413     filename = xmalloc (strlen (repository)
5414 			+ 1
5415 			+ strlen (CVSROOTADM)
5416 			+ 1
5417 			+ strlen (CVSROOTADM_PASSWD)
5418 			+ 1);
5419 
5420     (void) sprintf (filename, "%s/%s/%s", repository,
5421                     CVSROOTADM, CVSROOTADM_PASSWD);
5422 
5423     fp = CVS_FOPEN (filename, "r");
5424     if (fp == NULL)
5425     {
5426 	if (!existence_error (errno))
5427 	    error (0, errno, "cannot open %s", filename);
5428 	return 0;
5429     }
5430 
5431     /* Look for a relevant line -- one with this user's name. */
5432     namelen = strlen (username);
5433     while (getline (&linebuf, &linebuf_len, fp) >= 0)
5434     {
5435 	if ((strncmp (linebuf, username, namelen) == 0)
5436 	    && (linebuf[namelen] == ':'))
5437         {
5438 	    found_it = 1;
5439 	    break;
5440         }
5441     }
5442     if (ferror (fp))
5443 	error (0, errno, "cannot read %s", filename);
5444     if (fclose (fp) < 0)
5445 	error (0, errno, "cannot close %s", filename);
5446 
5447     /* If found_it, then linebuf contains the information we need. */
5448     if (found_it)
5449     {
5450 	char *found_password, *host_user_tmp;
5451         char *non_cvsuser_portion;
5452 
5453         /* We need to make sure lines such as
5454          *
5455          *    "username::sysuser\n"
5456          *    "username:\n"
5457          *    "username:  \n"
5458          *
5459          * all result in a found_password of NULL, but we also need to
5460          * make sure that
5461          *
5462          *    "username:   :sysuser\n"
5463          *    "username: <whatever>:sysuser\n"
5464          *
5465          * continues to result in an impossible password.  That way,
5466          * an admin would be on safe ground by going in and tacking a
5467          * space onto the front of a password to disable the account
5468          * (a technique some people use to close accounts
5469          * temporarily).
5470          */
5471 
5472         /* Make `non_cvsuser_portion' contain everything after the CVS
5473            username, but null out any final newline. */
5474 	non_cvsuser_portion = linebuf + namelen;
5475         strtok (non_cvsuser_portion, "\n");
5476 
5477         /* If there's a colon now, we just want to inch past it. */
5478         if (strchr (non_cvsuser_portion, ':') == non_cvsuser_portion)
5479             non_cvsuser_portion++;
5480 
5481         /* Okay, after this conditional chain, found_password and
5482            host_user_tmp will have useful values: */
5483 
5484         if ((non_cvsuser_portion == NULL)
5485             || (strlen (non_cvsuser_portion) == 0)
5486             || ((strspn (non_cvsuser_portion, " \t"))
5487                 == strlen (non_cvsuser_portion)))
5488         {
5489             found_password = NULL;
5490             host_user_tmp = NULL;
5491         }
5492         else if (strncmp (non_cvsuser_portion, ":", 1) == 0)
5493         {
5494             found_password = NULL;
5495             host_user_tmp = non_cvsuser_portion + 1;
5496             if (strlen (host_user_tmp) == 0)
5497                 host_user_tmp = NULL;
5498         }
5499         else
5500         {
5501             found_password = strtok (non_cvsuser_portion, ":");
5502             host_user_tmp = strtok (NULL, ":");
5503         }
5504 
5505         /* Of course, maybe there was no system user portion... */
5506 	if (host_user_tmp == NULL)
5507             host_user_tmp = username;
5508 
5509         /* Verify blank passwords directly, otherwise use crypt(). */
5510         if ((found_password == NULL)
5511             || ((strcmp (found_password, crypt (password, found_password))
5512                  == 0)))
5513         {
5514             /* Give host_user_ptr permanent storage. */
5515             *host_user_ptr = xstrdup (host_user_tmp);
5516 	    retval = 1;
5517         }
5518 	else
5519         {
5520             *host_user_ptr = NULL;
5521 	    retval         = 2;
5522         }
5523     }
5524     else     /* Didn't find this user, so deny access. */
5525     {
5526 	*host_user_ptr = NULL;
5527 	retval = 0;
5528     }
5529 
5530     free (filename);
5531     if (linebuf)
5532         free (linebuf);
5533 
5534     return retval;
5535 }
5536 
5537 
5538 /* Return a hosting username if password matches, else NULL. */
5539 static char *
5540 check_password (username, password, repository)
5541     char *username, *password, *repository;
5542 {
5543     int rc;
5544     char *host_user = NULL;
5545 
5546     /* First we see if this user has a password in the CVS-specific
5547        password file.  If so, that's enough to authenticate with.  If
5548        not, we'll check /etc/passwd. */
5549 
5550     rc = check_repository_password (username, password, repository,
5551 				    &host_user);
5552 
5553     if (rc == 2)
5554 	return NULL;
5555 
5556     /* else */
5557 
5558     if (rc == 1)
5559     {
5560         /* host_user already set by reference, so just return. */
5561         goto handle_return;
5562     }
5563     else if (rc == 0 && system_auth)
5564     {
5565 	/* No cvs password found, so try /etc/passwd. */
5566 
5567 	const char *found_passwd = NULL;
5568 	struct passwd *pw;
5569 #ifdef HAVE_GETSPNAM
5570 	struct spwd *spw;
5571 
5572 	spw = getspnam (username);
5573 	if (spw != NULL)
5574 	{
5575 	    found_passwd = spw->sp_pwdp;
5576 	}
5577 #endif
5578 
5579 	if (found_passwd == NULL && (pw = getpwnam (username)) != NULL)
5580 	{
5581 	    found_passwd = pw->pw_passwd;
5582 	}
5583 
5584 	if (found_passwd == NULL)
5585 	{
5586 	    printf ("E Fatal error, aborting.\n\
5587 error 0 %s: no such user\n", username);
5588 
5589 	    /* I'm doing this manually rather than via error_exit ()
5590 	       because I'm not sure whether we want to call server_cleanup.
5591 	       Needs more investigation....  */
5592 
5593 #ifdef SYSTEM_CLEANUP
5594 	    /* Hook for OS-specific behavior, for example socket subsystems on
5595 	       NT and OS2 or dealing with windows and arguments on Mac.  */
5596 	    SYSTEM_CLEANUP ();
5597 #endif
5598 
5599 	    exit (EXIT_FAILURE);
5600 	}
5601 
5602 	if (*found_passwd)
5603         {
5604 	    /* user exists and has a password */
5605 	    host_user = ((! strcmp (found_passwd,
5606                                     crypt (password, found_passwd)))
5607                          ? xstrdup (username) : NULL);
5608             goto handle_return;
5609         }
5610 	else if (password && *password)
5611         {
5612 	    /* user exists and has no system password, but we got
5613 	       one as parameter */
5614 	    host_user = xstrdup (username);
5615             goto handle_return;
5616         }
5617 	else
5618         {
5619 	    /* user exists but has no password at all */
5620 	    host_user = NULL;
5621             goto handle_return;
5622         }
5623     }
5624     else if (rc == 0)
5625     {
5626 	/* Note that the message _does_ distinguish between the case in
5627 	   which we check for a system password and the case in which
5628 	   we do not.  It is a real pain to track down why it isn't
5629 	   letting you in if it won't say why, and I am not convinced
5630 	   that the potential information disclosure to an attacker
5631 	   outweighs this.  */
5632 	printf ("error 0 no such user %s in CVSROOT/passwd\n", username);
5633 
5634 	/* I'm doing this manually rather than via error_exit ()
5635 	   because I'm not sure whether we want to call server_cleanup.
5636 	   Needs more investigation....  */
5637 
5638 #ifdef SYSTEM_CLEANUP
5639 	/* Hook for OS-specific behavior, for example socket subsystems on
5640 	   NT and OS2 or dealing with windows and arguments on Mac.  */
5641 	SYSTEM_CLEANUP ();
5642 #endif
5643 	exit (EXIT_FAILURE);
5644     }
5645     else
5646     {
5647 	/* Something strange happened.  We don't know what it was, but
5648 	   we certainly won't grant authorization. */
5649 	host_user = NULL;
5650         goto handle_return;
5651     }
5652 
5653 handle_return:
5654     if (host_user)
5655     {
5656         /* Set CVS_Username here, in allocated space.
5657            It might or might not be the same as host_user. */
5658         CVS_Username = xmalloc (strlen (username) + 1);
5659         strcpy (CVS_Username, username);
5660     }
5661 
5662     return host_user;
5663 }
5664 
5665 #endif /* AUTH_SERVER_SUPPORT */
5666 
5667 #if defined (AUTH_SERVER_SUPPORT) || defined (HAVE_GSSAPI)
5668 
5669 /* Read username and password from client (i.e., stdin).
5670    If correct, then switch to run as that user and send an ACK to the
5671    client via stdout, else send NACK and die. */
5672 void
5673 pserver_authenticate_connection ()
5674 {
5675     char *tmp = NULL;
5676     size_t tmp_allocated = 0;
5677 #ifdef AUTH_SERVER_SUPPORT
5678     char *repository = NULL;
5679     size_t repository_allocated = 0;
5680     char *username = NULL;
5681     size_t username_allocated = 0;
5682     char *password = NULL;
5683     size_t password_allocated = 0;
5684 
5685     char *host_user;
5686     char *descrambled_password;
5687 #endif /* AUTH_SERVER_SUPPORT */
5688     int verify_and_exit = 0;
5689 
5690     /* The Authentication Protocol.  Client sends:
5691      *
5692      *   BEGIN AUTH REQUEST\n
5693      *   <REPOSITORY>\n
5694      *   <USERNAME>\n
5695      *   <PASSWORD>\n
5696      *   END AUTH REQUEST\n
5697      *
5698      * Server uses above information to authenticate, then sends
5699      *
5700      *   I LOVE YOU\n
5701      *
5702      * if it grants access, else
5703      *
5704      *   I HATE YOU\n
5705      *
5706      * if it denies access (and it exits if denying).
5707      *
5708      * When the client is "cvs login", the user does not desire actual
5709      * repository access, but would like to confirm the password with
5710      * the server.  In this case, the start and stop strings are
5711      *
5712      *   BEGIN VERIFICATION REQUEST\n
5713      *
5714      *            and
5715      *
5716      *   END VERIFICATION REQUEST\n
5717      *
5718      * On a verification request, the server's responses are the same
5719      * (with the obvious semantics), but it exits immediately after
5720      * sending the response in both cases.
5721      *
5722      * Why is the repository sent?  Well, note that the actual
5723      * client/server protocol can't start up until authentication is
5724      * successful.  But in order to perform authentication, the server
5725      * needs to look up the password in the special CVS passwd file,
5726      * before trying /etc/passwd.  So the client transmits the
5727      * repository as part of the "authentication protocol".  The
5728      * repository will be redundantly retransmitted later, but that's no
5729      * big deal.
5730      */
5731 
5732 #ifdef SO_KEEPALIVE
5733     /* Set SO_KEEPALIVE on the socket, so that we don't hang forever
5734        if the client dies while we are waiting for input.  */
5735     {
5736 	int on = 1;
5737 
5738 	if (setsockopt (STDIN_FILENO, SOL_SOCKET, SO_KEEPALIVE,
5739 			   (char *) &on, sizeof on) < 0)
5740 	{
5741 #ifdef HAVE_SYSLOG_H
5742 	    syslog (LOG_DAEMON | LOG_ERR, "error setting KEEPALIVE: %m");
5743 #endif
5744 	}
5745     }
5746 #endif
5747 
5748     /* Make sure the protocol starts off on the right foot... */
5749     if (getline_safe (&tmp, &tmp_allocated, stdin, PATH_MAX) < 0)
5750 	/* FIXME: what?  We could try writing error/eof, but chances
5751 	   are the network connection is dead bidirectionally.  log it
5752 	   somewhere?  */
5753 	;
5754 
5755     if (strcmp (tmp, "BEGIN VERIFICATION REQUEST\n") == 0)
5756 	verify_and_exit = 1;
5757     else if (strcmp (tmp, "BEGIN AUTH REQUEST\n") == 0)
5758 	;
5759     else if (strcmp (tmp, "BEGIN GSSAPI REQUEST\n") == 0)
5760     {
5761 #ifdef HAVE_GSSAPI
5762 	free (tmp);
5763 	gserver_authenticate_connection ();
5764 	return;
5765 #else
5766 	error (1, 0, "GSSAPI authentication not supported by this server");
5767 #endif
5768     }
5769     else
5770 	error (1, 0, "bad auth protocol start: %s", tmp);
5771 
5772 #ifndef AUTH_SERVER_SUPPORT
5773 
5774     error (1, 0, "Password authentication not supported by this server");
5775 
5776 #else /* AUTH_SERVER_SUPPORT */
5777 
5778     /* Get the three important pieces of information in order. */
5779     /* See above comment about error handling.  */
5780     getline_safe (&repository, &repository_allocated, stdin, PATH_MAX);
5781     getline_safe (&username, &username_allocated, stdin, PATH_MAX);
5782     getline_safe (&password, &password_allocated, stdin, PATH_MAX);
5783 
5784     /* Make them pure. */
5785     strip_trailing_newlines (repository);
5786     strip_trailing_newlines (username);
5787     strip_trailing_newlines (password);
5788 
5789     /* ... and make sure the protocol ends on the right foot. */
5790     /* See above comment about error handling.  */
5791     getline_safe (&tmp, &tmp_allocated, stdin, PATH_MAX);
5792     if (strcmp (tmp,
5793 		verify_and_exit ?
5794 		"END VERIFICATION REQUEST\n" : "END AUTH REQUEST\n")
5795 	!= 0)
5796     {
5797 	error (1, 0, "bad auth protocol end: %s", tmp);
5798     }
5799     if (!root_allow_ok (repository))
5800     {
5801 	printf ("error 0 %s: no such repository\n", repository);
5802 #ifdef HAVE_SYSLOG_H
5803 	syslog (LOG_DAEMON | LOG_NOTICE, "login refused for %s", repository);
5804 #endif
5805 	goto i_hate_you;
5806     }
5807 
5808     /* OK, now parse the config file, so we can use it to control how
5809        to check passwords.  If there was an error parsing the config
5810        file, parse_config already printed an error.  We keep going.
5811        Why?  Because if we didn't, then there would be no way to check
5812        in a new CVSROOT/config file to fix the broken one!  */
5813     parse_config (repository);
5814 
5815     /* We need the real cleartext before we hash it. */
5816     descrambled_password = descramble (password);
5817     host_user = check_password (username, descrambled_password, repository);
5818     memset (descrambled_password, 0, strlen (descrambled_password));
5819     free (descrambled_password);
5820     if (host_user == NULL)
5821     {
5822 #ifdef HAVE_SYSLOG_H
5823 	syslog (LOG_DAEMON | LOG_NOTICE, "login failure (for %s)", repository);
5824 #ifdef LOG_AUTHPRIV
5825         syslog (LOG_AUTHPRIV | LOG_NOTICE, "login failure by %s / %s (for %s)",
5826         	username, descrambled_password, repository);
5827 #endif
5828 #endif
5829     i_hate_you:
5830 	printf ("I HATE YOU\n");
5831 	fflush (stdout);
5832 
5833 	/* Don't worry about server_cleanup, server_active isn't set
5834 	   yet.  */
5835 	error_exit ();
5836     }
5837 
5838     /* Don't go any farther if we're just responding to "cvs login". */
5839     if (verify_and_exit)
5840     {
5841 	printf ("I LOVE YOU\n");
5842 	fflush (stdout);
5843 
5844 #ifdef SYSTEM_CLEANUP
5845 	/* Hook for OS-specific behavior, for example socket subsystems on
5846 	   NT and OS2 or dealing with windows and arguments on Mac.  */
5847 	SYSTEM_CLEANUP ();
5848 #endif
5849 
5850 	exit (0);
5851     }
5852 
5853     /* Set Pserver_Repos so that we can check later that the same
5854        repository is sent in later client/server protocol. */
5855     Pserver_Repos = xmalloc (strlen (repository) + 1);
5856     strcpy (Pserver_Repos, repository);
5857 
5858     /* Switch to run as this user. */
5859     switch_to_user (host_user);
5860     free (host_user);
5861     free (tmp);
5862     free (repository);
5863     free (username);
5864     free (password);
5865 
5866     printf ("I LOVE YOU\n");
5867     fflush (stdout);
5868 #endif /* AUTH_SERVER_SUPPORT */
5869 }
5870 
5871 #endif /* AUTH_SERVER_SUPPORT || HAVE_GSSAPI */
5872 
5873 
5874 #ifdef HAVE_KERBEROS
5875 void
5876 kserver_authenticate_connection ()
5877 {
5878     int status;
5879     char instance[INST_SZ];
5880     struct sockaddr_in peer;
5881     struct sockaddr_in laddr;
5882     int len;
5883     KTEXT_ST ticket;
5884     AUTH_DAT auth;
5885     char version[KRB_SENDAUTH_VLEN];
5886     char user[ANAME_SZ];
5887 
5888     strcpy (instance, "*");
5889     len = sizeof peer;
5890     if (getpeername (STDIN_FILENO, (struct sockaddr *) &peer, &len) < 0
5891 	|| getsockname (STDIN_FILENO, (struct sockaddr *) &laddr,
5892 			&len) < 0)
5893     {
5894 	printf ("E Fatal error, aborting.\n\
5895 error %s getpeername or getsockname failed\n", strerror (errno));
5896 #ifdef SYSTEM_CLEANUP
5897 	/* Hook for OS-specific behavior, for example socket subsystems on
5898 	   NT and OS2 or dealing with windows and arguments on Mac.  */
5899 	SYSTEM_CLEANUP ();
5900 #endif
5901 	exit (EXIT_FAILURE);
5902     }
5903 
5904 #ifdef SO_KEEPALIVE
5905     /* Set SO_KEEPALIVE on the socket, so that we don't hang forever
5906        if the client dies while we are waiting for input.  */
5907     {
5908 	int on = 1;
5909 
5910 	if (setsockopt (STDIN_FILENO, SOL_SOCKET, SO_KEEPALIVE,
5911 			   (char *) &on, sizeof on) < 0)
5912 	{
5913 #ifdef HAVE_SYSLOG_H
5914 	    syslog (LOG_DAEMON | LOG_ERR, "error setting KEEPALIVE: %m");
5915 #endif
5916 	}
5917     }
5918 #endif
5919 
5920     status = krb_recvauth (KOPT_DO_MUTUAL, STDIN_FILENO, &ticket, "rcmd",
5921 			   instance, &peer, &laddr, &auth, "", sched,
5922 			   version);
5923     if (status != KSUCCESS)
5924     {
5925 	printf ("E Fatal error, aborting.\n\
5926 error 0 kerberos: %s\n", krb_get_err_text(status));
5927 #ifdef SYSTEM_CLEANUP
5928 	/* Hook for OS-specific behavior, for example socket subsystems on
5929 	   NT and OS2 or dealing with windows and arguments on Mac.  */
5930 	SYSTEM_CLEANUP ();
5931 #endif
5932 	exit (EXIT_FAILURE);
5933     }
5934 
5935     memcpy (kblock, auth.session, sizeof (C_Block));
5936 
5937     /* Get the local name.  */
5938     status = krb_kntoln (&auth, user);
5939     if (status != KSUCCESS)
5940     {
5941 	printf ("E Fatal error, aborting.\n\
5942 error 0 kerberos: can't get local name: %s\n", krb_get_err_text(status));
5943 #ifdef SYSTEM_CLEANUP
5944 	/* Hook for OS-specific behavior, for example socket subsystems on
5945 	   NT and OS2 or dealing with windows and arguments on Mac.  */
5946 	SYSTEM_CLEANUP ();
5947 #endif
5948 	exit (EXIT_FAILURE);
5949     }
5950 
5951     /* Switch to run as this user. */
5952     switch_to_user (user);
5953 }
5954 #endif /* HAVE_KERBEROS */
5955 
5956 #ifdef HAVE_GSSAPI
5957 
5958 #ifndef MAXHOSTNAMELEN
5959 #define MAXHOSTNAMELEN (256)
5960 #endif
5961 
5962 /* Authenticate a GSSAPI connection.  This is called from
5963    pserver_authenticate_connection, and it handles success and failure
5964    the same way.  */
5965 
5966 static void
5967 gserver_authenticate_connection ()
5968 {
5969     char hostname[MAXHOSTNAMELEN];
5970     struct hostent *hp;
5971     gss_buffer_desc tok_in, tok_out;
5972     char buf[1024];
5973     OM_uint32 stat_min, ret;
5974     gss_name_t server_name, client_name;
5975     gss_cred_id_t server_creds;
5976     int nbytes;
5977     gss_OID mechid;
5978 
5979     gethostname (hostname, sizeof hostname);
5980     hp = gethostbyname (hostname);
5981     if (hp == NULL)
5982 	error (1, 0, "can't get canonical hostname");
5983 
5984     sprintf (buf, "cvs@%s", hp->h_name);
5985     tok_in.value = buf;
5986     tok_in.length = strlen (buf);
5987 
5988     if (gss_import_name (&stat_min, &tok_in, GSS_C_NT_HOSTBASED_SERVICE,
5989 			 &server_name) != GSS_S_COMPLETE)
5990 	error (1, 0, "could not import GSSAPI service name %s", buf);
5991 
5992     /* Acquire the server credential to verify the client's
5993        authentication.  */
5994     if (gss_acquire_cred (&stat_min, server_name, 0, GSS_C_NULL_OID_SET,
5995 			  GSS_C_ACCEPT, &server_creds,
5996 			  NULL, NULL) != GSS_S_COMPLETE)
5997 	error (1, 0, "could not acquire GSSAPI server credentials");
5998 
5999     gss_release_name (&stat_min, &server_name);
6000 
6001     /* The client will send us a two byte length followed by that many
6002        bytes.  */
6003     if (fread (buf, 1, 2, stdin) != 2)
6004 	error (1, errno, "read of length failed");
6005 
6006     nbytes = ((buf[0] & 0xff) << 8) | (buf[1] & 0xff);
6007     assert (nbytes <= sizeof buf);
6008 
6009     if (fread (buf, 1, nbytes, stdin) != nbytes)
6010 	error (1, errno, "read of data failed");
6011 
6012     gcontext = GSS_C_NO_CONTEXT;
6013     tok_in.length = nbytes;
6014     tok_in.value = buf;
6015 
6016     if (gss_accept_sec_context (&stat_min,
6017                                 &gcontext,	/* context_handle */
6018                                 server_creds,	/* verifier_cred_handle */
6019                                 &tok_in,	/* input_token */
6020                                 NULL,		/* channel bindings */
6021                                 &client_name,	/* src_name */
6022                                 &mechid,	/* mech_type */
6023                                 &tok_out,	/* output_token */
6024                                 &ret,
6025                                 NULL,	 	/* ignore time_rec */
6026                                 NULL)		/* ignore del_cred_handle */
6027 	!= GSS_S_COMPLETE)
6028     {
6029 	error (1, 0, "could not verify credentials");
6030     }
6031 
6032     /* FIXME: Use Kerberos v5 specific code to authenticate to a user.
6033        We could instead use an authentication to access mapping.  */
6034     {
6035 	krb5_context kc;
6036 	krb5_principal p;
6037 	gss_buffer_desc desc;
6038 
6039 	krb5_init_context (&kc);
6040 	if (gss_display_name (&stat_min, client_name, &desc,
6041 			      &mechid) != GSS_S_COMPLETE
6042 	    || krb5_parse_name (kc, ((gss_buffer_t) &desc)->value, &p) != 0
6043 	    || krb5_aname_to_localname (kc, p, sizeof buf, buf) != 0
6044 	    || krb5_kuserok (kc, p, buf) != TRUE)
6045 	{
6046 	    error (1, 0, "access denied");
6047 	}
6048 	krb5_free_principal (kc, p);
6049 	krb5_free_context (kc);
6050     }
6051 
6052     if (tok_out.length != 0)
6053     {
6054 	char cbuf[2];
6055 
6056 	cbuf[0] = (tok_out.length >> 8) & 0xff;
6057 	cbuf[1] = tok_out.length & 0xff;
6058 	if (fwrite (cbuf, 1, 2, stdout) != 2
6059 	    || (fwrite (tok_out.value, 1, tok_out.length, stdout)
6060 		!= tok_out.length))
6061 	    error (1, errno, "fwrite failed");
6062     }
6063 
6064     switch_to_user (buf);
6065 
6066     printf ("I LOVE YOU\n");
6067     fflush (stdout);
6068 }
6069 
6070 #endif /* HAVE_GSSAPI */
6071 
6072 #endif /* SERVER_SUPPORT */
6073 
6074 #if defined (CLIENT_SUPPORT) || defined (SERVER_SUPPORT)
6075 
6076 /* This global variable is non-zero if the user requests encryption on
6077    the command line.  */
6078 int cvsencrypt;
6079 
6080 /* This global variable is non-zero if the users requests stream
6081    authentication on the command line.  */
6082 int cvsauthenticate;
6083 
6084 #ifdef HAVE_GSSAPI
6085 
6086 /* An buffer interface using GSSAPI.  This is built on top of a
6087    packetizing buffer.  */
6088 
6089 /* This structure is the closure field of the GSSAPI translation
6090    routines.  */
6091 
6092 struct cvs_gssapi_wrap_data
6093 {
6094     /* The GSSAPI context.  */
6095     gss_ctx_id_t gcontext;
6096 };
6097 
6098 static int cvs_gssapi_wrap_input PROTO((void *, const char *, char *, int));
6099 static int cvs_gssapi_wrap_output PROTO((void *, const char *, char *, int,
6100 					 int *));
6101 
6102 /* Create a GSSAPI wrapping buffer.  We use a packetizing buffer with
6103    GSSAPI wrapping routines.  */
6104 
6105 struct buffer *
6106 cvs_gssapi_wrap_buffer_initialize (buf, input, gcontext, memory)
6107      struct buffer *buf;
6108      int input;
6109      gss_ctx_id_t gcontext;
6110      void (*memory) PROTO((struct buffer *));
6111 {
6112     struct cvs_gssapi_wrap_data *gd;
6113 
6114     gd = (struct cvs_gssapi_wrap_data *) xmalloc (sizeof *gd);
6115     gd->gcontext = gcontext;
6116 
6117     return (packetizing_buffer_initialize
6118 	    (buf,
6119 	     input ? cvs_gssapi_wrap_input : NULL,
6120 	     input ? NULL : cvs_gssapi_wrap_output,
6121 	     gd,
6122 	     memory));
6123 }
6124 
6125 /* Unwrap data using GSSAPI.  */
6126 
6127 static int
6128 cvs_gssapi_wrap_input (fnclosure, input, output, size)
6129      void *fnclosure;
6130      const char *input;
6131      char *output;
6132      int size;
6133 {
6134     struct cvs_gssapi_wrap_data *gd =
6135 	(struct cvs_gssapi_wrap_data *) fnclosure;
6136     gss_buffer_desc inbuf, outbuf;
6137     OM_uint32 stat_min;
6138     int conf;
6139 
6140     inbuf.value = (void *) input;
6141     inbuf.length = size;
6142 
6143     if (gss_unwrap (&stat_min, gd->gcontext, &inbuf, &outbuf, &conf, NULL)
6144 	!= GSS_S_COMPLETE)
6145     {
6146 	error (1, 0, "gss_unwrap failed");
6147     }
6148 
6149     if (outbuf.length > size)
6150 	abort ();
6151 
6152     memcpy (output, outbuf.value, outbuf.length);
6153 
6154     /* The real packet size is stored in the data, so we don't need to
6155        remember outbuf.length.  */
6156 
6157     gss_release_buffer (&stat_min, &outbuf);
6158 
6159     return 0;
6160 }
6161 
6162 /* Wrap data using GSSAPI.  */
6163 
6164 static int
6165 cvs_gssapi_wrap_output (fnclosure, input, output, size, translated)
6166      void *fnclosure;
6167      const char *input;
6168      char *output;
6169      int size;
6170      int *translated;
6171 {
6172     struct cvs_gssapi_wrap_data *gd =
6173 	(struct cvs_gssapi_wrap_data *) fnclosure;
6174     gss_buffer_desc inbuf, outbuf;
6175     OM_uint32 stat_min;
6176     int conf_req, conf;
6177 
6178     inbuf.value = (void *) input;
6179     inbuf.length = size;
6180 
6181 #ifdef ENCRYPTION
6182     conf_req = cvs_gssapi_encrypt;
6183 #else
6184     conf_req = 0;
6185 #endif
6186 
6187     if (gss_wrap (&stat_min, gd->gcontext, conf_req, GSS_C_QOP_DEFAULT,
6188 		  &inbuf, &conf, &outbuf) != GSS_S_COMPLETE)
6189 	error (1, 0, "gss_wrap failed");
6190 
6191     /* The packetizing buffer only permits us to add 100 bytes.
6192        FIXME: I don't know what, if anything, is guaranteed by GSSAPI.
6193        This may need to be increased for a different GSSAPI
6194        implementation, or we may need a different algorithm.  */
6195     if (outbuf.length > size + 100)
6196 	abort ();
6197 
6198     memcpy (output, outbuf.value, outbuf.length);
6199 
6200     *translated = outbuf.length;
6201 
6202     gss_release_buffer (&stat_min, &outbuf);
6203 
6204     return 0;
6205 }
6206 
6207 #endif /* HAVE_GSSAPI */
6208 
6209 #ifdef ENCRYPTION
6210 
6211 #ifdef HAVE_KERBEROS
6212 
6213 /* An encryption interface using Kerberos.  This is built on top of a
6214    packetizing buffer.  */
6215 
6216 /* This structure is the closure field of the Kerberos translation
6217    routines.  */
6218 
6219 struct krb_encrypt_data
6220 {
6221     /* The Kerberos key schedule.  */
6222     Key_schedule sched;
6223     /* The Kerberos DES block.  */
6224     C_Block block;
6225 };
6226 
6227 static int krb_encrypt_input PROTO((void *, const char *, char *, int));
6228 static int krb_encrypt_output PROTO((void *, const char *, char *, int,
6229 				     int *));
6230 
6231 /* Create a Kerberos encryption buffer.  We use a packetizing buffer
6232    with Kerberos encryption translation routines.  */
6233 
6234 struct buffer *
6235 krb_encrypt_buffer_initialize (buf, input, sched, block, memory)
6236      struct buffer *buf;
6237      int input;
6238      Key_schedule sched;
6239      C_Block block;
6240      void (*memory) PROTO((struct buffer *));
6241 {
6242     struct krb_encrypt_data *kd;
6243 
6244     kd = (struct krb_encrypt_data *) xmalloc (sizeof *kd);
6245     memcpy (kd->sched, sched, sizeof (Key_schedule));
6246     memcpy (kd->block, block, sizeof (C_Block));
6247 
6248     return packetizing_buffer_initialize (buf,
6249 					  input ? krb_encrypt_input : NULL,
6250 					  input ? NULL : krb_encrypt_output,
6251 					  kd,
6252 					  memory);
6253 }
6254 
6255 /* Decrypt Kerberos data.  */
6256 
6257 static int
6258 krb_encrypt_input (fnclosure, input, output, size)
6259      void *fnclosure;
6260      const char *input;
6261      char *output;
6262      int size;
6263 {
6264     struct krb_encrypt_data *kd = (struct krb_encrypt_data *) fnclosure;
6265     int tcount;
6266 
6267     des_cbc_encrypt ((C_Block *) input, (C_Block *) output,
6268 		     size, kd->sched, &kd->block, 0);
6269 
6270     /* SIZE is the size of the buffer, which is set by the encryption
6271        routine.  The packetizing buffer will arrange for the first two
6272        bytes in the decrypted buffer to be the real (unaligned)
6273        length.  As a safety check, make sure that the length in the
6274        buffer corresponds to SIZE.  Note that the length in the buffer
6275        is just the length of the data.  We must add 2 to account for
6276        the buffer count itself.  */
6277     tcount = ((output[0] & 0xff) << 8) + (output[1] & 0xff);
6278     if (((tcount + 2 + 7) & ~7) != size)
6279       error (1, 0, "Decryption failure");
6280 
6281     return 0;
6282 }
6283 
6284 /* Encrypt Kerberos data.  */
6285 
6286 static int
6287 krb_encrypt_output (fnclosure, input, output, size, translated)
6288      void *fnclosure;
6289      const char *input;
6290      char *output;
6291      int size;
6292      int *translated;
6293 {
6294     struct krb_encrypt_data *kd = (struct krb_encrypt_data *) fnclosure;
6295     int aligned;
6296 
6297     /* For security against a known plaintext attack, we should
6298        initialize any padding bytes to random values.  Instead, we
6299        just pick up whatever is on the stack, which is at least better
6300        than using zero.  */
6301 
6302     /* Align SIZE to an 8 byte boundary.  Note that SIZE includes the
6303        two byte buffer count at the start of INPUT which was added by
6304        the packetizing buffer.  */
6305     aligned = (size + 7) & ~7;
6306 
6307     /* We use des_cbc_encrypt rather than krb_mk_priv because the
6308        latter sticks a timestamp in the block, and krb_rd_priv expects
6309        that timestamp to be within five minutes of the current time.
6310        Given the way the CVS server buffers up data, that can easily
6311        fail over a long network connection.  We trust krb_recvauth to
6312        guard against a replay attack.  */
6313 
6314     des_cbc_encrypt ((C_Block *) input, (C_Block *) output, aligned,
6315 		     kd->sched, &kd->block, 1);
6316 
6317     *translated = aligned;
6318 
6319     return 0;
6320 }
6321 
6322 #endif /* HAVE_KERBEROS */
6323 #endif /* ENCRYPTION */
6324 #endif /* defined (CLIENT_SUPPORT) || defined (SERVER_SUPPORT) */
6325 
6326 /* Output LEN bytes at STR.  If LEN is zero, then output up to (not including)
6327    the first '\0' byte.  */
6328 
6329 void
6330 cvs_output (str, len)
6331     const char *str;
6332     size_t len;
6333 {
6334     if (len == 0)
6335 	len = strlen (str);
6336 #ifdef SERVER_SUPPORT
6337     if (error_use_protocol)
6338     {
6339 	buf_output (saved_output, str, len);
6340 	buf_copy_lines (buf_to_net, saved_output, 'M');
6341     }
6342     else if (server_active)
6343     {
6344 	buf_output (saved_output, str, len);
6345 	buf_copy_lines (protocol, saved_output, 'M');
6346 	buf_send_counted (protocol);
6347     }
6348     else
6349 #endif
6350     {
6351 	size_t written;
6352 	size_t to_write = len;
6353 	const char *p = str;
6354 
6355 	/* For symmetry with cvs_outerr we would call fflush (stderr)
6356 	   here.  I guess the assumption is that stderr will be
6357 	   unbuffered, so we don't need to.  That sounds like a sound
6358 	   assumption from the manpage I looked at, but if there was
6359 	   something fishy about it, my guess is that calling fflush
6360 	   would not produce a significant performance problem.  */
6361 
6362 	while (to_write > 0)
6363 	{
6364 	    written = fwrite (p, 1, to_write, stdout);
6365 	    if (written == 0)
6366 		break;
6367 	    p += written;
6368 	    to_write -= written;
6369 	}
6370     }
6371 }
6372 
6373 /* Output LEN bytes at STR in binary mode.  If LEN is zero, then
6374    output zero bytes.  */
6375 
6376 void
6377 cvs_output_binary (str, len)
6378     char *str;
6379     size_t len;
6380 {
6381 #ifdef SERVER_SUPPORT
6382     if (error_use_protocol || server_active)
6383     {
6384 	struct buffer *buf;
6385 	char size_text[40];
6386 
6387 	if (error_use_protocol)
6388 	    buf = buf_to_net;
6389 	else
6390 	    buf = protocol;
6391 
6392 	if (!supported_response ("Mbinary"))
6393 	{
6394 	    error (0, 0, "\
6395 this client does not support writing binary files to stdout");
6396 	    return;
6397 	}
6398 
6399 	buf_output0 (buf, "Mbinary\012");
6400 	sprintf (size_text, "%lu\012", (unsigned long) len);
6401 	buf_output0 (buf, size_text);
6402 
6403 	/* Not sure what would be involved in using buf_append_data here
6404 	   without stepping on the toes of our caller (which is responsible
6405 	   for the memory allocation of STR).  */
6406 	buf_output (buf, str, len);
6407 
6408 	if (!error_use_protocol)
6409 	    buf_send_counted (protocol);
6410     }
6411     else
6412 #endif
6413     {
6414 	size_t written;
6415 	size_t to_write = len;
6416 	const char *p = str;
6417 
6418 	/* For symmetry with cvs_outerr we would call fflush (stderr)
6419 	   here.  I guess the assumption is that stderr will be
6420 	   unbuffered, so we don't need to.  That sounds like a sound
6421 	   assumption from the manpage I looked at, but if there was
6422 	   something fishy about it, my guess is that calling fflush
6423 	   would not produce a significant performance problem.  */
6424 #ifdef USE_SETMODE_STDOUT
6425 	int oldmode;
6426 
6427 	/* It is possible that this should be the same ifdef as
6428 	   USE_SETMODE_BINARY but at least for the moment we keep them
6429 	   separate.  Mostly this is just laziness and/or a question
6430 	   of what has been tested where.  Also there might be an
6431 	   issue of setmode vs. _setmode.  */
6432 	/* The Windows doc says to call setmode only right after startup.
6433 	   I assume that what they are talking about can also be helped
6434 	   by flushing the stream before changing the mode.  */
6435 	fflush (stdout);
6436 	oldmode = _setmode (_fileno (stdout), OPEN_BINARY);
6437 	if (oldmode < 0)
6438 	    error (0, errno, "failed to setmode on stdout");
6439 #endif
6440 
6441 	while (to_write > 0)
6442 	{
6443 	    written = fwrite (p, 1, to_write, stdout);
6444 	    if (written == 0)
6445 		break;
6446 	    p += written;
6447 	    to_write -= written;
6448 	}
6449 #ifdef USE_SETMODE_STDOUT
6450 	fflush (stdout);
6451 	if (_setmode (_fileno (stdout), oldmode) != OPEN_BINARY)
6452 	    error (0, errno, "failed to setmode on stdout");
6453 #endif
6454     }
6455 }
6456 
6457 /* Like CVS_OUTPUT but output is for stderr not stdout.  */
6458 
6459 void
6460 cvs_outerr (str, len)
6461     const char *str;
6462     size_t len;
6463 {
6464     if (len == 0)
6465 	len = strlen (str);
6466 #ifdef SERVER_SUPPORT
6467     if (error_use_protocol)
6468     {
6469 	buf_output (saved_outerr, str, len);
6470 	buf_copy_lines (buf_to_net, saved_outerr, 'E');
6471     }
6472     else if (server_active)
6473     {
6474 	buf_output (saved_outerr, str, len);
6475 	buf_copy_lines (protocol, saved_outerr, 'E');
6476 	buf_send_counted (protocol);
6477     }
6478     else
6479 #endif
6480     {
6481 	size_t written;
6482 	size_t to_write = len;
6483 	const char *p = str;
6484 
6485 	/* Make sure that output appears in order if stdout and stderr
6486 	   point to the same place.  For the server case this is taken
6487 	   care of by the fact that saved_outerr always holds less
6488 	   than a line.  */
6489 	fflush (stdout);
6490 
6491 	while (to_write > 0)
6492 	{
6493 	    written = fwrite (p, 1, to_write, stderr);
6494 	    if (written == 0)
6495 		break;
6496 	    p += written;
6497 	    to_write -= written;
6498 	}
6499     }
6500 }
6501 
6502 /* Flush stderr.  stderr is normally flushed automatically, of course,
6503    but this function is used to flush information from the server back
6504    to the client.  */
6505 
6506 void
6507 cvs_flusherr ()
6508 {
6509 #ifdef SERVER_SUPPORT
6510     if (error_use_protocol)
6511     {
6512 	/* skip the actual stderr flush in this case since the parent process
6513 	 * on the server should only be writing to stdout anyhow
6514 	 */
6515 	/* Flush what we can to the network, but don't block.  */
6516 	buf_flush (buf_to_net, 0);
6517     }
6518     else if (server_active)
6519     {
6520 	/* make sure stderr is flushed before we send the flush count on the
6521 	 * protocol pipe
6522 	 */
6523 	fflush (stderr);
6524 	/* Send a special count to tell the parent to flush.  */
6525 	buf_send_special_count (protocol, -2);
6526     }
6527     else
6528 #endif
6529 	fflush (stderr);
6530 }
6531 
6532 /* Make it possible for the user to see what has been written to
6533    stdout (it is up to the implementation to decide exactly how far it
6534    should go to ensure this).  */
6535 
6536 void
6537 cvs_flushout ()
6538 {
6539 #ifdef SERVER_SUPPORT
6540     if (error_use_protocol)
6541     {
6542 	/* Flush what we can to the network, but don't block.  */
6543 	buf_flush (buf_to_net, 0);
6544     }
6545     else if (server_active)
6546     {
6547 	/* Just do nothing.  This is because the code which
6548 	   cvs_flushout replaces, setting stdout to line buffering in
6549 	   main.c, didn't get called in the server child process.  But
6550 	   in the future it is quite plausible that we'll want to make
6551 	   this case work analogously to cvs_flusherr.
6552 
6553 	   FIXME - DRP - I tried to implement this and triggered the following
6554 	   error: "Protocol error: uncounted data discarded".  I don't need
6555 	   this feature right now, so I'm not going to bother with it yet.
6556 	 */
6557 	buf_send_special_count (protocol, -1);
6558     }
6559     else
6560 #endif
6561 	fflush (stdout);
6562 }
6563 
6564 /* Output TEXT, tagging it according to TAG.  There are lots more
6565    details about what TAG means in cvsclient.texi but for the simple
6566    case (e.g. non-client/server), TAG is just "newline" to output a
6567    newline (in which case TEXT must be NULL), and any other tag to
6568    output normal text.
6569 
6570    Note that there is no way to output either \0 or \n as part of TEXT.  */
6571 
6572 void
6573 cvs_output_tagged (tag, text)
6574     char *tag;
6575     char *text;
6576 {
6577     if (text != NULL && strchr (text, '\n') != NULL)
6578 	/* Uh oh.  The protocol has no way to cope with this.  For now
6579 	   we dump core, although that really isn't such a nice
6580 	   response given that this probably can be caused by newlines
6581 	   in filenames and other causes other than bugs in CVS.  Note
6582 	   that we don't want to turn this into "MT newline" because
6583 	   this case is a newline within a tagged item, not a newline
6584 	   as extraneous sugar for the user.  */
6585 	assert (0);
6586 
6587     /* Start and end tags don't take any text, per cvsclient.texi.  */
6588     if (tag[0] == '+' || tag[0] == '-')
6589 	assert (text == NULL);
6590 
6591 #ifdef SERVER_SUPPORT
6592     if (server_active && supported_response ("MT"))
6593     {
6594 	struct buffer *buf;
6595 
6596 	if (error_use_protocol)
6597 	    buf = buf_to_net;
6598 	else
6599 	    buf = protocol;
6600 
6601 	buf_output0 (buf, "MT ");
6602 	buf_output0 (buf, tag);
6603 	if (text != NULL)
6604 	{
6605 	    buf_output (buf, " ", 1);
6606 	    buf_output0 (buf, text);
6607 	}
6608 	buf_output (buf, "\n", 1);
6609 
6610 	if (!error_use_protocol)
6611 	    buf_send_counted (protocol);
6612     }
6613     else
6614 #endif
6615     {
6616 	if (strcmp (tag, "newline") == 0)
6617 	    cvs_output ("\n", 1);
6618 	else if (text != NULL)
6619 	    cvs_output (text, 0);
6620     }
6621 }
6622