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)
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. */
23 int server_active = 0;
25 #if defined(SERVER_SUPPORT) || defined(CLIENT_SUPPORT)
27 /* This stuff isn't included solely with SERVER_SUPPORT since some of these
28 * functions (encryption & the like) get compiled with or without server
31 * FIXME - They should be in a different file.
35 /* We use Kerberos 5 routines to map the GSSAPI credential to a user
39 /* We need this to wrap data. */
40 static gss_ctx_id_t gcontext;
42 static void gserver_authenticate_connection PROTO((void));
44 /* Whether we are already wrapping GSSAPI communication. */
45 static int cvs_gssapi_wrapping;
48 /* Whether to encrypt GSSAPI communication. We use a global variable
49 like this because we use the same buffer type (gssapi_wrap) to
50 handle both authentication and encryption, and we don't want
51 multiple instances of that buffer in the communication stream. */
52 int cvs_gssapi_encrypt;
54 # endif /* HAVE_GSSAPI */
55 #endif /* defined(SERVER_SUPPORT) || defined(CLIENT_SUPPORT) */
63 #if defined (AUTH_SERVER_SUPPORT) || defined (HAVE_KERBEROS) || defined (HAVE_GSSAPI)
64 #include <sys/socket.h>
69 # ifndef LOG_DAEMON /* for ancient syslogs */
75 # include <netinet/in.h>
77 # ifndef HAVE_KRB_GET_ERR_TEXT
78 # define krb_get_err_text(status) krb_err_txt[status]
81 /* Information we need if we are going to use Kerberos encryption. */
82 static C_Block kblock;
83 static Key_schedule sched;
91 #define O_NONBLOCK O_NDELAY
94 /* EWOULDBLOCK is not defined by POSIX, but some BSD systems will
95 return it, rather than EAGAIN, for nonblocking writes. */
97 #define blocking_error(err) ((err) == EWOULDBLOCK || (err) == EAGAIN)
99 #define blocking_error(err) ((err) == EAGAIN)
102 /* For initgroups(). */
105 #endif /* HAVE_INITGROUPS */
107 # ifdef AUTH_SERVER_SUPPORT
109 # ifdef HAVE_GETSPNAM
113 /* The cvs username sent by the client, which might or might not be
114 the same as the system username the server eventually switches to
115 run as. CVS_Username gets set iff password authentication is
117 char *CVS_Username = NULL;
119 /* Used to check that same repos is transmitted in pserver auth and in
120 later CVS protocol. Exported because root.c also uses. */
121 static char *Pserver_Repos = NULL;
123 /* Should we check for system usernames/passwords? Can be changed by
127 # endif /* AUTH_SERVER_SUPPORT */
130 /* While processing requests, this buffer accumulates data to be sent to
131 the client, and then once we are in do_cvs_command, we use it
132 for all the data to be sent. */
133 static struct buffer *buf_to_net;
135 /* This buffer is used to read input from the client. */
136 static struct buffer *buf_from_net;
139 * This is where we stash stuff we are going to use. Format string
140 * which expects a single directory within it, starting with a slash.
142 static char *server_temp_dir;
144 /* This is the original value of server_temp_dir, before any possible
145 changes inserted by serve_max_dotdot. */
146 static char *orig_server_temp_dir;
148 /* Nonzero if we should keep the temp directory around after we exit. */
149 static int dont_delete_temp;
151 static void server_write_entries PROTO((void));
153 /* All server communication goes through buffer structures. Most of
154 the buffers are built on top of a file descriptor. This structure
155 is used as the closure field in a buffer. */
159 /* The file descriptor. */
161 /* Nonzero if the file descriptor is in blocking mode. */
165 static struct buffer *fd_buffer_initialize
166 PROTO ((int, int, void (*) (struct buffer *)));
167 static int fd_buffer_input PROTO((void *, char *, int, int, int *));
168 static int fd_buffer_output PROTO((void *, const char *, int, int *));
169 static int fd_buffer_flush PROTO((void *));
170 static int fd_buffer_block PROTO((void *, int));
171 static int fd_buffer_shutdown PROTO((struct buffer *));
173 /* Initialize a buffer built on a file descriptor. FD is the file
174 descriptor. INPUT is nonzero if this is for input, zero if this is
175 for output. MEMORY is the function to call when a memory error
178 static struct buffer *
179 fd_buffer_initialize (fd, input, memory)
182 void (*memory) PROTO((struct buffer *));
186 n = (struct fd_buffer *) xmalloc (sizeof *n);
189 return buf_initialize (input ? fd_buffer_input : NULL,
190 input ? NULL : fd_buffer_output,
191 input ? NULL : fd_buffer_flush,
198 /* The buffer input function for a buffer built on a file descriptor. */
201 fd_buffer_input (closure, data, need, size, got)
208 struct fd_buffer *fd = (struct fd_buffer *) closure;
212 nbytes = read (fd->fd, data, size);
215 /* This case is not efficient. Fortunately, I don't think it
216 ever actually happens. */
217 nbytes = read (fd->fd, data, need == 0 ? 1 : need);
230 /* End of file. This assumes that we are using POSIX or BSD
231 style nonblocking I/O. On System V we will get a zero
232 return if there is no data, even when not at EOF. */
236 /* Some error occurred. */
238 if (blocking_error (errno))
240 /* Everything's fine, we just didn't get any data. */
247 /* The buffer output function for a buffer built on a file descriptor. */
250 fd_buffer_output (closure, data, have, wrote)
256 struct fd_buffer *fd = (struct fd_buffer *) closure;
264 nbytes = write (fd->fd, data, have);
269 && (nbytes == 0 || blocking_error (errno)))
271 /* A nonblocking write failed to write any data. Just
276 /* Some sort of error occurred. */
292 /* The buffer flush function for a buffer built on a file descriptor. */
296 fd_buffer_flush (closure)
299 /* Nothing to do. File descriptors are always flushed. */
303 /* The buffer block function for a buffer built on a file descriptor. */
306 fd_buffer_block (closure, block)
310 struct fd_buffer *fd = (struct fd_buffer *) closure;
313 flags = fcntl (fd->fd, F_GETFL, 0);
318 flags &= ~O_NONBLOCK;
322 if (fcntl (fd->fd, F_SETFL, flags) < 0)
325 fd->blocking = block;
330 /* The buffer shutdown function for a buffer built on a file descriptor. */
333 fd_buffer_shutdown (buf)
341 /* Populate all of the directories between BASE_DIR and its relative
342 subdirectory DIR with CVSADM directories. Return 0 for success or
344 static int create_adm_p PROTO((char *, char *));
347 create_adm_p (base_dir, dir)
351 char *dir_where_cvsadm_lives, *dir_to_register, *p, *tmp;
355 if (strcmp (dir, ".") == 0)
356 return 0; /* nothing to do */
358 /* Allocate some space for our directory-munging string. */
359 p = xmalloc (strlen (dir) + 1);
363 dir_where_cvsadm_lives = xmalloc (strlen (base_dir) + strlen (dir) + 100);
364 if (dir_where_cvsadm_lives == NULL)
370 /* Allocate some space for the temporary string in which we will
371 construct filenames. */
372 tmp = xmalloc (strlen (base_dir) + strlen (dir) + 100);
376 free (dir_where_cvsadm_lives);
381 /* We make several passes through this loop. On the first pass,
382 we simply create the CVSADM directory in the deepest directory.
383 For each subsequent pass, we try to remove the last path
384 element from DIR, create the CVSADM directory in the remaining
385 pathname, and register the subdirectory in the newly created
391 strcpy (dir_where_cvsadm_lives, base_dir);
392 strcat (dir_where_cvsadm_lives, "/");
393 strcat (dir_where_cvsadm_lives, p);
394 dir_to_register = NULL;
399 (void) sprintf (tmp, "%s/%s", dir_where_cvsadm_lives, CVSADM);
400 if ((CVS_MKDIR (tmp, 0777) < 0) && (errno != EEXIST))
406 /* Create CVSADM_REP. */
407 (void) sprintf (tmp, "%s/%s", dir_where_cvsadm_lives, CVSADM_REP);
410 /* Use Emptydir as the placeholder until the client sends
411 us the real value. This code is similar to checkout.c
412 (emptydir_name), but the code below returns errors
416 empty = xmalloc (strlen (current_parsed_root->directory)
417 + sizeof (CVSROOTADM)
418 + sizeof (CVSNULLREPOS)
426 /* Create the directory name. */
427 (void) sprintf (empty, "%s/%s/%s", current_parsed_root->directory,
428 CVSROOTADM, CVSNULLREPOS);
430 /* Create the directory if it doesn't exist. */
431 if (! isfile (empty))
434 omask = umask (cvsumask);
435 if (CVS_MKDIR (empty, 0777) < 0)
441 (void) umask (omask);
444 f = CVS_FOPEN (tmp, "w");
451 /* Write the directory name to CVSADM_REP. */
452 if (fprintf (f, "%s\n", empty) < 0)
459 if (fclose (f) == EOF)
466 /* Clean up after ourselves. */
470 /* Create CVSADM_ENT. We open in append mode because we
471 don't want to clobber an existing Entries file. */
472 (void) sprintf (tmp, "%s/%s", dir_where_cvsadm_lives, CVSADM_ENT);
473 f = CVS_FOPEN (tmp, "a");
479 if (fclose (f) == EOF)
485 if (dir_to_register != NULL)
487 /* FIXME: Yes, this results in duplicate entries in the
488 Entries.Log file, but it doesn't currently matter. We
489 might need to change this later on to make sure that we
490 only write one entry. */
492 Subdir_Register ((List *) NULL, dir_where_cvsadm_lives,
499 dir_to_register = strrchr (p, '/');
500 if (dir_to_register == NULL)
503 strcpy (dir_where_cvsadm_lives, base_dir);
508 *dir_to_register = '\0';
510 strcpy (dir_where_cvsadm_lives, base_dir);
511 strcat (dir_where_cvsadm_lives, "/");
512 strcat (dir_where_cvsadm_lives, p);
518 free (dir_where_cvsadm_lives);
524 * Make directory DIR, including all intermediate directories if necessary.
525 * Returns 0 for success or errno code.
527 static int mkdir_p PROTO((char *));
534 char *q = xmalloc (strlen (dir) + 1);
543 * Skip over leading slash if present. We won't bother to try to
549 while (*p != '/' && *p != '\0')
553 strncpy (q, dir, p - dir);
555 if (q[p - dir - 1] != '/' && CVS_MKDIR (q, 0777) < 0)
557 int saved_errno = errno;
559 if (saved_errno != EEXIST
560 && ((saved_errno != EACCES && saved_errno != EROFS)
563 retval = saved_errno;
571 if (CVS_MKDIR (dir, 0777) < 0)
582 * Print the error response for error code STATUS. The caller is
583 * reponsible for making sure we get back to the command loop without
584 * any further output occuring.
585 * Must be called only in contexts where it is OK to send output.
594 buf_output0 (buf_to_net, "error ");
595 msg = strerror (status);
598 sprintf (tmpstr, "unknown error %d", status);
601 buf_output0 (buf_to_net, msg);
602 buf_append_char (buf_to_net, '\n');
604 buf_flush (buf_to_net, 0);
607 static int pending_error;
609 * Malloc'd text for pending error. Each line must start with "E ". The
610 * last line should not end with a newline.
612 static char *pending_error_text;
614 /* If an error is pending, print it and return 1. If not, return 0.
615 Must be called only in contexts where it is OK to send output. */
617 print_pending_error ()
619 if (pending_error_text)
621 buf_output0 (buf_to_net, pending_error_text);
622 buf_append_char (buf_to_net, '\n');
624 print_error (pending_error);
626 buf_output0 (buf_to_net, "error \n");
628 buf_flush (buf_to_net, 0);
631 free (pending_error_text);
632 pending_error_text = NULL;
635 else if (pending_error)
637 print_error (pending_error);
645 /* Is an error pending? */
646 #define error_pending() (pending_error || pending_error_text)
648 static int alloc_pending PROTO ((size_t size));
650 /* Allocate SIZE bytes for pending_error_text and return nonzero
651 if we could do it. */
656 if (error_pending ())
657 /* Probably alloc_pending callers will have already checked for
658 this case. But we might as well handle it if they don't, I
661 pending_error_text = xmalloc (size);
662 if (pending_error_text == NULL)
664 pending_error = ENOMEM;
670 static void serve_is_modified PROTO ((char *));
672 static int supported_response PROTO ((char *));
675 supported_response (name)
680 for (rs = responses; rs->name != NULL; ++rs)
681 if (strcmp (rs->name, name) == 0)
682 return rs->status == rs_supported;
683 error (1, 0, "internal error: testing support for unknown response?");
689 serve_valid_responses (arg)
700 for (rs = responses; rs->name != NULL; ++rs)
702 if (strcmp (rs->name, p) == 0)
705 if (rs->name == NULL)
707 * It is a response we have never heard of (and thus never
708 * will want to use). So don't worry about it.
712 rs->status = rs_supported;
715 for (rs = responses; rs->name != NULL; ++rs)
717 if (rs->status == rs_essential)
719 buf_output0 (buf_to_net, "E response `");
720 buf_output0 (buf_to_net, rs->name);
721 buf_output0 (buf_to_net, "' not supported by client\nerror \n");
723 /* FIXME: This call to buf_flush could conceivably
724 cause deadlock, as noted in server_cleanup. */
725 buf_flush (buf_to_net, 1);
729 else if (rs->status == rs_optional)
730 rs->status = rs_not_supported;
741 if (error_pending()) return;
743 if (!isabsolute (arg))
745 if (alloc_pending (80 + strlen (arg)))
746 sprintf (pending_error_text,
747 "E Root %s must be an absolute pathname", arg);
751 /* Sending "Root" twice is illegal.
753 The other way to handle a duplicate Root requests would be as a
754 request to clear out all state and start over as if it was a
755 new connection. Doing this would cause interoperability
756 headaches, so it should be a different request, if there is
757 any reason why such a feature is needed. */
758 if (current_parsed_root != NULL)
760 if (alloc_pending (80 + strlen (arg)))
761 sprintf (pending_error_text,
762 "E Protocol error: Duplicate Root request, for %s", arg);
766 /* We need to check :ext: server here, :pserver: checks happen below. */
767 if (root_allow_used() && !root_allow_ok (arg)
768 # ifdef AUTH_SERVER_SUPPORT
769 && Pserver_Repos == NULL
773 if (alloc_pending (80 + strlen (arg)))
774 sprintf (pending_error_text,
775 "E Bad root %s", arg);
779 #ifdef AUTH_SERVER_SUPPORT
780 if (Pserver_Repos != NULL)
782 if (strcmp (Pserver_Repos, arg) != 0)
784 if (alloc_pending (80 + strlen (Pserver_Repos) + strlen (arg)))
785 /* The explicitness is to aid people who are writing clients.
786 I don't see how this information could help an
788 sprintf (pending_error_text, "\
789 E Protocol error: Root says \"%s\" but pserver says \"%s\"",
796 current_parsed_root = local_cvsroot (arg);
798 /* For pserver, this will already have happened, and the call will do
799 nothing. But for rsh, we need to do it now. */
800 parse_config (current_parsed_root->directory);
802 /* Now is a good time to read CVSROOT/options too. */
803 parseopts(current_parsed_root->directory);
805 path = xmalloc (strlen (current_parsed_root->directory)
806 + sizeof (CVSROOTADM)
810 pending_error = ENOMEM;
813 (void) sprintf (path, "%s/%s", current_parsed_root->directory, CVSROOTADM);
814 if (!isaccessible (path, R_OK | X_OK))
816 int save_errno = errno;
817 if (alloc_pending (80 + strlen (path)))
818 sprintf (pending_error_text, "E Cannot access %s", path);
819 pending_error = save_errno;
824 env = xmalloc (strlen (CVSROOT_ENV) + strlen (current_parsed_root->directory) + 2);
827 pending_error = ENOMEM;
830 (void) sprintf (env, "%s=%s", CVSROOT_ENV, current_parsed_root->directory);
832 /* do not free env, as putenv has control of it */
836 static int max_dotdot_limit = 0;
838 /* Is this pathname OK to recurse into when we are running as the server?
839 If not, call error() with a fatal error. */
841 server_pathname_check (path)
844 /* An absolute pathname is almost surely a path on the *client* machine,
845 and is unlikely to do us any good here. It also is probably capable
846 of being a security hole in the anonymous readonly case. */
847 if (isabsolute (path))
848 /* Giving an error is actually kind of a cop-out, in the sense
849 that it would be nice for "cvs co -d /foo/bar/baz" to work.
850 A quick fix in the server would be requiring Max-dotdot of
851 at least one if pathnames are absolute, and then putting
852 /abs/foo/bar/baz in the temp dir beside the /d/d/d stuff.
853 A cleaner fix in the server might be to decouple the
854 pathnames we pass back to the client from pathnames in our
855 temp directory (this would also probably remove the need
856 for Max-dotdot). A fix in the client would have the client
857 turn it into "cd /foo/bar; cvs co -d baz" (more or less).
858 This probably has some problems with pathnames which appear
860 error (1, 0, "absolute pathname `%s' illegal for server", path);
861 if (pathname_levels (path) > max_dotdot_limit)
863 /* Similar to the isabsolute case in security implications. */
864 error (0, 0, "protocol error: `%s' contains more leading ..", path);
865 error (1, 0, "than the %d which Max-dotdot specified",
870 static int outside_root PROTO ((char *));
872 /* Is file or directory REPOS an absolute pathname within the
873 current_parsed_root->directory? If yes, return 0. If no, set pending_error
879 size_t repos_len = strlen (repos);
880 size_t root_len = strlen (current_parsed_root->directory);
882 /* isabsolute (repos) should always be true, but
883 this is a good security precaution regardless. -DRP
885 if (!isabsolute (repos))
887 if (alloc_pending (repos_len + 80))
888 sprintf (pending_error_text, "\
889 E protocol error: %s is not absolute", repos);
893 if (repos_len < root_len
894 || strncmp (current_parsed_root->directory, repos, root_len) != 0)
897 if (alloc_pending (strlen (current_parsed_root->directory)
900 sprintf (pending_error_text, "\
901 E protocol error: directory '%s' not within root '%s'",
902 repos, current_parsed_root->directory);
905 if (repos_len > root_len)
907 if (repos[root_len] != '/')
909 if (pathname_levels (repos + root_len + 1) > 0)
915 static int outside_dir PROTO ((char *));
917 /* Is file or directory FILE outside the current directory (that is, does
918 it contain '/')? If no, return 0. If yes, set pending_error
924 if (strchr (file, '/') != NULL)
926 if (alloc_pending (strlen (file)
928 sprintf (pending_error_text, "\
929 E protocol error: directory '%s' not within current directory",
937 * Add as many directories to the temp directory as the client tells us it
938 * will use "..", so we never try to access something outside the temp
939 * directory via "..".
942 serve_max_dotdot (arg)
945 int lim = atoi (arg);
949 if (lim < 0 || lim > 10000)
951 p = xmalloc (strlen (server_temp_dir) + 2 * lim + 10);
954 pending_error = ENOMEM;
957 strcpy (p, server_temp_dir);
958 for (i = 0; i < lim; ++i)
960 if (server_temp_dir != orig_server_temp_dir)
961 free (server_temp_dir);
963 max_dotdot_limit = lim;
966 static char *dir_name;
969 dirswitch (dir, repos)
977 server_write_entries ();
979 if (error_pending()) return;
981 /* Check for bad directory name.
983 FIXME: could/should unify these checks with server_pathname_check
984 except they need to report errors differently. */
985 if (isabsolute (dir))
987 if (alloc_pending (80 + strlen (dir)))
988 sprintf (pending_error_text,
989 "E absolute pathname `%s' illegal for server", dir);
992 if (pathname_levels (dir) > max_dotdot_limit)
994 if (alloc_pending (80 + strlen (dir)))
995 sprintf (pending_error_text,
996 "E protocol error: `%s' has too many ..", dir);
1000 dir_len = strlen (dir);
1002 /* Check for a trailing '/'. This is not ISDIRSEP because \ in the
1003 protocol is an ordinary character, not a directory separator (of
1004 course, it is perhaps unwise to use it in directory names, but that
1005 is another issue). */
1007 && dir[dir_len - 1] == '/')
1009 if (alloc_pending (80 + dir_len))
1010 sprintf (pending_error_text,
1011 "E protocol error: invalid directory syntax in %s", dir);
1015 if (dir_name != NULL)
1018 dir_name = xmalloc (strlen (server_temp_dir) + dir_len + 40);
1019 if (dir_name == NULL)
1021 pending_error = ENOMEM;
1025 strcpy (dir_name, server_temp_dir);
1026 strcat (dir_name, "/");
1027 strcat (dir_name, dir);
1029 status = mkdir_p (dir_name);
1031 && status != EEXIST)
1033 if (alloc_pending (80 + strlen (dir_name)))
1034 sprintf (pending_error_text, "E cannot mkdir %s", dir_name);
1035 pending_error = status;
1039 /* We need to create adm directories in all path elements because
1040 we want the server to descend them, even if the client hasn't
1041 sent the appropriate "Argument xxx" command to match the
1042 already-sent "Directory xxx" command. See recurse.c
1043 (start_recursion) for a big discussion of this. */
1045 status = create_adm_p (server_temp_dir, dir);
1048 if (alloc_pending (80 + strlen (dir_name)))
1049 sprintf (pending_error_text, "E cannot create_adm_p %s", dir_name);
1050 pending_error = status;
1054 if ( CVS_CHDIR (dir_name) < 0)
1056 int save_errno = errno;
1057 if (alloc_pending (80 + strlen (dir_name)))
1058 sprintf (pending_error_text, "E cannot change to %s", dir_name);
1059 pending_error = save_errno;
1063 * This is pretty much like calling Create_Admin, but Create_Admin doesn't
1064 * report errors in the right way for us.
1066 if ((CVS_MKDIR (CVSADM, 0777) < 0) && (errno != EEXIST))
1068 int save_errno = errno;
1069 if (alloc_pending (80 + strlen (dir_name) + strlen (CVSADM)))
1070 sprintf (pending_error_text,
1071 "E cannot mkdir %s/%s", dir_name, CVSADM);
1072 pending_error = save_errno;
1076 /* The following will overwrite the contents of CVSADM_REP. This
1077 is the correct behavior -- mkdir_p may have written a
1078 placeholder value to this file and we need to insert the
1081 f = CVS_FOPEN (CVSADM_REP, "w");
1084 int save_errno = errno;
1085 if (alloc_pending (80 + strlen (dir_name) + strlen (CVSADM_REP)))
1086 sprintf (pending_error_text,
1087 "E cannot open %s/%s", dir_name, CVSADM_REP);
1088 pending_error = save_errno;
1091 if (fprintf (f, "%s", repos) < 0)
1093 int save_errno = errno;
1094 if (alloc_pending (80 + strlen (dir_name) + strlen (CVSADM_REP)))
1095 sprintf (pending_error_text,
1096 "E error writing %s/%s", dir_name, CVSADM_REP);
1097 pending_error = save_errno;
1101 /* Non-remote CVS handles a module representing the entire tree
1102 (e.g., an entry like ``world -a .'') by putting /. at the end
1103 of the Repository file, so we do the same. */
1104 if (strcmp (dir, ".") == 0
1105 && current_parsed_root != NULL
1106 && current_parsed_root->directory != NULL
1107 && strcmp (current_parsed_root->directory, repos) == 0)
1109 if (fprintf (f, "/.") < 0)
1111 int save_errno = errno;
1112 if (alloc_pending (80 + strlen (dir_name) + strlen (CVSADM_REP)))
1113 sprintf (pending_error_text,
1114 "E error writing %s/%s", dir_name, CVSADM_REP);
1115 pending_error = save_errno;
1120 if (fprintf (f, "\n") < 0)
1122 int save_errno = errno;
1123 if (alloc_pending (80 + strlen (dir_name) + strlen (CVSADM_REP)))
1124 sprintf (pending_error_text,
1125 "E error writing %s/%s", dir_name, CVSADM_REP);
1126 pending_error = save_errno;
1130 if (fclose (f) == EOF)
1132 int save_errno = errno;
1133 if (alloc_pending (80 + strlen (dir_name) + strlen (CVSADM_REP)))
1134 sprintf (pending_error_text,
1135 "E error closing %s/%s", dir_name, CVSADM_REP);
1136 pending_error = save_errno;
1139 /* We open in append mode because we don't want to clobber an
1140 existing Entries file. */
1141 f = CVS_FOPEN (CVSADM_ENT, "a");
1144 int save_errno = errno;
1145 if (alloc_pending (80 + strlen (CVSADM_ENT)))
1146 sprintf (pending_error_text, "E cannot open %s", CVSADM_ENT);
1147 pending_error = save_errno;
1150 if (fclose (f) == EOF)
1152 int save_errno = errno;
1153 if (alloc_pending (80 + strlen (CVSADM_ENT)))
1154 sprintf (pending_error_text, "E cannot close %s", CVSADM_ENT);
1155 pending_error = save_errno;
1161 serve_repository (arg)
1164 if (alloc_pending (80))
1165 strcpy (pending_error_text,
1166 "E Repository request is obsolete; aborted");
1171 serve_directory (arg)
1177 status = buf_read_line (buf_from_net, &repos, (int *) NULL);
1180 if (!outside_root (repos))
1181 dirswitch (arg, repos);
1184 else if (status == -2)
1186 pending_error = ENOMEM;
1190 pending_error_text = xmalloc (80 + strlen (arg));
1191 if (pending_error_text == NULL)
1193 pending_error = ENOMEM;
1195 else if (status == -1)
1197 sprintf (pending_error_text,
1198 "E end of file reading mode for %s", arg);
1202 sprintf (pending_error_text,
1203 "E error reading mode for %s", arg);
1204 pending_error = status;
1210 serve_static_directory (arg)
1215 if (error_pending ()) return;
1217 f = CVS_FOPEN (CVSADM_ENTSTAT, "w+");
1220 int save_errno = errno;
1221 if (alloc_pending (80 + strlen (CVSADM_ENTSTAT)))
1222 sprintf (pending_error_text, "E cannot open %s", CVSADM_ENTSTAT);
1223 pending_error = save_errno;
1226 if (fclose (f) == EOF)
1228 int save_errno = errno;
1229 if (alloc_pending (80 + strlen (CVSADM_ENTSTAT)))
1230 sprintf (pending_error_text, "E cannot close %s", CVSADM_ENTSTAT);
1231 pending_error = save_errno;
1242 if (error_pending ()) return;
1244 f = CVS_FOPEN (CVSADM_TAG, "w+");
1247 int save_errno = errno;
1248 if (alloc_pending (80 + strlen (CVSADM_TAG)))
1249 sprintf (pending_error_text, "E cannot open %s", CVSADM_TAG);
1250 pending_error = save_errno;
1253 if (fprintf (f, "%s\n", arg) < 0)
1255 int save_errno = errno;
1256 if (alloc_pending (80 + strlen (CVSADM_TAG)))
1257 sprintf (pending_error_text, "E cannot write to %s", CVSADM_TAG);
1258 pending_error = save_errno;
1262 if (fclose (f) == EOF)
1264 int save_errno = errno;
1265 if (alloc_pending (80 + strlen (CVSADM_TAG)))
1266 sprintf (pending_error_text, "E cannot close %s", CVSADM_TAG);
1267 pending_error = save_errno;
1273 * Read SIZE bytes from buf_from_net, write them to FILE.
1275 * Currently this isn't really used for receiving parts of a file --
1276 * the file is still sent over in one chunk. But if/when we get
1277 * spiffy in-process gzip support working, perhaps the compressed
1278 * pieces could be sent over as they're ready, if the network is fast
1279 * enough. Or something.
1282 receive_partial_file (size, file)
1291 status = buf_read_data (buf_from_net, size, &data, &nread);
1295 pending_error = ENOMEM;
1298 pending_error_text = xmalloc (80);
1299 if (pending_error_text == NULL)
1300 pending_error = ENOMEM;
1301 else if (status == -1)
1303 sprintf (pending_error_text,
1304 "E premature end of file from client");
1309 sprintf (pending_error_text,
1310 "E error reading from client");
1311 pending_error = status;
1323 nwrote = write (file, data, nread);
1326 int save_errno = errno;
1327 if (alloc_pending (40))
1328 strcpy (pending_error_text, "E unable to write");
1329 pending_error = save_errno;
1331 /* Read and discard the file data. */
1337 status = buf_read_data (buf_from_net, size, &data, &nread);
1351 /* Receive SIZE bytes, write to filename FILE. */
1353 receive_file (size, file, gzipped)
1361 /* Write the file. */
1362 fd = CVS_OPEN (arg, O_WRONLY | O_CREAT | O_TRUNC, 0600);
1365 int save_errno = errno;
1366 if (alloc_pending (40 + strlen (arg)))
1367 sprintf (pending_error_text, "E cannot open %s", arg);
1368 pending_error = save_errno;
1374 /* Using gunzip_and_write isn't really a high-performance
1375 approach, because it keeps the whole thing in memory
1376 (contiguous memory, worse yet). But it seems easier to
1377 code than the alternative (and less vulnerable to subtle
1378 bugs). Given that this feature is mainly for
1379 compatibility, that is the better tradeoff. */
1385 filebuf = xmalloc (size);
1387 /* If NULL, we still want to read the data and discard it. */
1394 status = buf_read_data (buf_from_net, toread, &data, &nread);
1398 pending_error = ENOMEM;
1401 pending_error_text = xmalloc (80);
1402 if (pending_error_text == NULL)
1403 pending_error = ENOMEM;
1404 else if (status == -1)
1406 sprintf (pending_error_text,
1407 "E premature end of file from client");
1412 sprintf (pending_error_text,
1413 "E error reading from client");
1414 pending_error = status;
1422 if (filebuf != NULL)
1424 memcpy (p, data, nread);
1428 if (filebuf == NULL)
1430 pending_error = ENOMEM;
1434 if (gunzip_and_write (fd, file, (unsigned char *) filebuf, size))
1436 if (alloc_pending (80))
1437 sprintf (pending_error_text,
1438 "E aborting due to compression error");
1443 receive_partial_file (size, fd);
1445 if (pending_error_text)
1447 char *p = xrealloc (pending_error_text,
1448 strlen (pending_error_text) + strlen (arg) + 30);
1451 pending_error_text = p;
1452 sprintf (p + strlen (p), ", file %s", arg);
1454 /* else original string is supposed to be unchanged */
1458 if (close (fd) < 0 && !error_pending ())
1460 int save_errno = errno;
1461 if (alloc_pending (40 + strlen (arg)))
1462 sprintf (pending_error_text, "E cannot close %s", arg);
1463 pending_error = save_errno;
1468 /* Kopt for the next file sent in Modified or Is-modified. */
1471 /* Timestamp (Checkin-time) for next file sent in Modified or
1473 static int checkin_time_valid;
1474 static time_t checkin_time;
1476 static void serve_modified PROTO ((char *));
1479 serve_modified (arg)
1489 * This used to return immediately if error_pending () was true.
1490 * However, that fails, because it causes each line of the file to
1491 * be echoed back to the client as an unrecognized command. The
1492 * client isn't reading from the socket, so eventually both
1493 * processes block trying to write to the other. Now, we try to
1494 * read the file if we can.
1497 status = buf_read_line (buf_from_net, &mode_text, (int *) NULL);
1501 pending_error = ENOMEM;
1504 pending_error_text = xmalloc (80 + strlen (arg));
1505 if (pending_error_text == NULL)
1506 pending_error = ENOMEM;
1510 sprintf (pending_error_text,
1511 "E end of file reading mode for %s", arg);
1514 sprintf (pending_error_text,
1515 "E error reading mode for %s", arg);
1516 pending_error = status;
1523 status = buf_read_line (buf_from_net, &size_text, (int *) NULL);
1527 pending_error = ENOMEM;
1530 pending_error_text = xmalloc (80 + strlen (arg));
1531 if (pending_error_text == NULL)
1532 pending_error = ENOMEM;
1536 sprintf (pending_error_text,
1537 "E end of file reading size for %s", arg);
1540 sprintf (pending_error_text,
1541 "E error reading size for %s", arg);
1542 pending_error = status;
1549 if (size_text[0] == 'z')
1552 size = atoi (size_text + 1);
1555 size = atoi (size_text);
1558 if (error_pending ())
1560 /* Now that we know the size, read and discard the file data. */
1566 status = buf_read_data (buf_from_net, size, &data, &nread);
1575 if (outside_dir (arg))
1583 receive_file (size, arg, gzipped);
1584 if (error_pending ())
1591 if (checkin_time_valid)
1595 memset (&t, 0, sizeof (t));
1596 t.modtime = t.actime = checkin_time;
1597 if (utime (arg, &t) < 0)
1599 int save_errno = errno;
1600 if (alloc_pending (80 + strlen (arg)))
1601 sprintf (pending_error_text, "E cannot utime %s", arg);
1602 pending_error = save_errno;
1606 checkin_time_valid = 0;
1610 int status = change_mode (arg, mode_text, 0);
1614 if (alloc_pending (40 + strlen (arg)))
1615 sprintf (pending_error_text,
1616 "E cannot change mode for %s", arg);
1617 pending_error = status;
1622 /* Make sure that the Entries indicate the right kopt. We probably
1623 could do this even in the non-kopt case and, I think, save a stat()
1624 call in time_stamp_server. But for conservatism I'm leaving the
1625 non-kopt case alone. */
1627 serve_is_modified (arg);
1632 serve_enable_unchanged (arg)
1638 struct an_entry *next;
1642 static struct an_entry *entries;
1644 static void serve_unchanged PROTO ((char *));
1647 serve_unchanged (arg)
1655 if (error_pending ()) return;
1657 if (outside_dir (arg))
1660 /* Rewrite entries file to have `=' in timestamp field. */
1661 for (p = entries; p != NULL; p = p->next)
1663 name = p->entry + 1;
1664 cp = strchr (name, '/');
1666 && strlen (arg) == cp - name
1667 && strncmp (arg, name, cp - name) == 0)
1669 if (!(timefield = strchr (cp + 1, '/')) || *++timefield == '\0')
1671 /* We didn't find the record separator or it is followed by
1672 * the end of the string, so just exit.
1674 if (alloc_pending (80))
1675 sprintf (pending_error_text,
1676 "E Malformed Entry encountered.");
1679 /* If the time field is not currently empty, then one of
1680 * serve_modified, serve_is_modified, & serve_unchanged were
1681 * already called for this file. We would like to ignore the
1682 * reinvocation silently or, better yet, exit with an error
1683 * message, but we just avoid the copy-forward and overwrite the
1684 * value from the last invocation instead. See the comment below
1687 if (*timefield == '/')
1689 /* Copy forward one character. Space was allocated for this
1690 * already in serve_entry(). */
1691 cp = timefield + strlen (timefield);
1693 while (cp > timefield)
1699 /* If *TIMEFIELD wasn't "/", we assume that it was because of
1700 * multiple calls to Is-Modified & Unchanged by the client and
1701 * just overwrite the value from the last call. Technically, we
1702 * should probably either ignore calls after the first or send the
1703 * client an error, since the client/server protocol specification
1704 * specifies that only one call to either Is-Modified or Unchanged
1705 * is allowed, but broken versions of WinCVS & TortoiseCVS rely on
1708 if (*timefield != '+')
1709 /* Skip this for entries with conflict markers. */
1717 serve_is_modified (arg)
1724 /* Have we found this file in "entries" yet. */
1727 if (error_pending ()) return;
1729 if (outside_dir (arg))
1732 /* Rewrite entries file to have `M' in timestamp field. */
1734 for (p = entries; p != NULL; p = p->next)
1736 name = p->entry + 1;
1737 cp = strchr (name, '/');
1739 && strlen (arg) == cp - name
1740 && strncmp (arg, name, cp - name) == 0)
1742 if (!(timefield = strchr (cp + 1, '/')) || *++timefield == '\0')
1744 /* We didn't find the record separator or it is followed by
1745 * the end of the string, so just exit.
1747 if (alloc_pending (80))
1748 sprintf (pending_error_text,
1749 "E Malformed Entry encountered.");
1752 /* If the time field is not currently empty, then one of
1753 * serve_modified, serve_is_modified, & serve_unchanged were
1754 * already called for this file. We would like to ignore the
1755 * reinvocation silently or, better yet, exit with an error
1756 * message, but we just avoid the copy-forward and overwrite the
1757 * value from the last invocation instead. See the comment below
1760 if (*timefield == '/')
1762 /* Copy forward one character. Space was allocated for this
1763 * already in serve_entry(). */
1764 cp = timefield + strlen (timefield);
1766 while (cp > timefield)
1772 /* If *TIMEFIELD wasn't "/", we assume that it was because of
1773 * multiple calls to Is-Modified & Unchanged by the client and
1774 * just overwrite the value from the last call. Technically, we
1775 * should probably either ignore calls after the first or send the
1776 * client an error, since the client/server protocol specification
1777 * specifies that only one call to either Is-Modified or Unchanged
1778 * is allowed, but broken versions of WinCVS & TortoiseCVS rely on
1781 if (*timefield != '+')
1782 /* Skip this for entries with conflict markers. */
1787 if (alloc_pending (strlen (name) + 80))
1788 sprintf (pending_error_text,
1789 "E protocol error: both Kopt and Entry for %s",
1801 /* We got Is-modified but no Entry. Add a dummy entry.
1802 The "D" timestamp is what makes it a dummy. */
1803 p = (struct an_entry *) xmalloc (sizeof (struct an_entry));
1806 pending_error = ENOMEM;
1809 p->entry = xmalloc (strlen (arg) + 80);
1810 if (p->entry == NULL)
1812 pending_error = ENOMEM;
1816 strcpy (p->entry, "/");
1817 strcat (p->entry, arg);
1818 strcat (p->entry, "//D/");
1821 strcat (p->entry, kopt);
1825 strcat (p->entry, "/");
1831 static void serve_entry PROTO ((char *));
1840 if (error_pending()) return;
1842 /* Verify that the entry is well-formed. This can avoid problems later.
1843 * At the moment we only check that the Entry contains five slashes in
1844 * approximately the correct locations since some of the code makes
1845 * assumptions about this.
1848 if (*cp == 'D') cp++;
1851 if (!cp || *cp != '/')
1853 if (alloc_pending (80))
1854 sprintf (pending_error_text,
1855 "E protocol error: Malformed Entry");
1858 cp = strchr (cp + 1, '/');
1861 p = xmalloc (sizeof (struct an_entry));
1864 pending_error = ENOMEM;
1867 /* Leave space for serve_unchanged to write '=' if it wants. */
1868 cp = xmalloc (strlen (arg) + 2);
1872 pending_error = ENOMEM;
1881 static void serve_kopt PROTO ((char *));
1887 if (error_pending ())
1892 if (alloc_pending (80 + strlen (arg)))
1893 sprintf (pending_error_text,
1894 "E protocol error: duplicate Kopt request: %s", arg);
1898 /* Do some sanity checks. In particular, that it is not too long.
1899 This lets the rest of the code not worry so much about buffer
1900 overrun attacks. Probably should call RCS_check_kflag here,
1901 but that would mean changing RCS_check_kflag to handle errors
1902 other than via exit(), fprintf(), and such. */
1903 if (strlen (arg) > 10)
1905 if (alloc_pending (80 + strlen (arg)))
1906 sprintf (pending_error_text,
1907 "E protocol error: invalid Kopt request: %s", arg);
1911 kopt = xmalloc (strlen (arg) + 1);
1914 pending_error = ENOMEM;
1920 static void serve_checkin_time PROTO ((char *));
1923 serve_checkin_time (arg)
1926 if (error_pending ())
1929 if (checkin_time_valid)
1931 if (alloc_pending (80 + strlen (arg)))
1932 sprintf (pending_error_text,
1933 "E protocol error: duplicate Checkin-time request: %s",
1938 checkin_time = get_date (arg, NULL);
1939 if (checkin_time == (time_t)-1)
1941 if (alloc_pending (80 + strlen (arg)))
1942 sprintf (pending_error_text, "E cannot parse date %s", arg);
1945 checkin_time_valid = 1;
1949 server_write_entries ()
1955 if (entries == NULL)
1959 /* Note that we free all the entries regardless of errors. */
1960 if (!error_pending ())
1962 /* We open in append mode because we don't want to clobber an
1963 existing Entries file. If we are checking out a module
1964 which explicitly lists more than one file in a particular
1965 directory, then we will wind up calling
1966 server_write_entries for each such file. */
1967 f = CVS_FOPEN (CVSADM_ENT, "a");
1970 int save_errno = errno;
1971 if (alloc_pending (80 + strlen (CVSADM_ENT)))
1972 sprintf (pending_error_text, "E cannot open %s", CVSADM_ENT);
1973 pending_error = save_errno;
1976 for (p = entries; p != NULL;)
1978 if (!error_pending ())
1980 if (fprintf (f, "%s\n", p->entry) < 0)
1982 int save_errno = errno;
1983 if (alloc_pending (80 + strlen(CVSADM_ENT)))
1984 sprintf (pending_error_text,
1985 "E cannot write to %s", CVSADM_ENT);
1986 pending_error = save_errno;
1995 if (f != NULL && fclose (f) == EOF && !error_pending ())
1997 int save_errno = errno;
1998 if (alloc_pending (80 + strlen (CVSADM_ENT)))
1999 sprintf (pending_error_text, "E cannot close %s", CVSADM_ENT);
2000 pending_error = save_errno;
2004 struct notify_note {
2005 /* Directory in which this notification happens. xmalloc'd*/
2011 /* The following three all in one xmalloc'd block, pointed to by TYPE.
2012 Each '\0' terminated. */
2019 struct notify_note *next;
2022 static struct notify_note *notify_list;
2023 /* Used while building list, to point to the last node that already exists. */
2024 static struct notify_note *last_node;
2026 static void serve_notify PROTO ((char *));
2032 struct notify_note *new = NULL;
2036 if (error_pending ()) return;
2038 if (outside_dir (arg))
2041 if (dir_name == NULL)
2044 new = (struct notify_note *) xmalloc (sizeof (struct notify_note));
2047 pending_error = ENOMEM;
2050 new->dir = xmalloc (strlen (dir_name) + 1);
2051 new->filename = xmalloc (strlen (arg) + 1);
2052 if (new->dir == NULL || new->filename == NULL)
2054 pending_error = ENOMEM;
2055 if (new->dir != NULL)
2060 strcpy (new->dir, dir_name);
2061 strcpy (new->filename, arg);
2063 status = buf_read_line (buf_from_net, &data, (int *) NULL);
2067 pending_error = ENOMEM;
2070 pending_error_text = xmalloc (80 + strlen (arg));
2071 if (pending_error_text == NULL)
2072 pending_error = ENOMEM;
2076 sprintf (pending_error_text,
2077 "E end of file reading notification for %s", arg);
2080 sprintf (pending_error_text,
2081 "E error reading notification for %s", arg);
2082 pending_error = status;
2086 free (new->filename);
2097 if (strchr (data, '+'))
2101 if (data[1] != '\t')
2106 cp = strchr (cp, '\t');
2110 cp = strchr (cp, '\t');
2114 cp = strchr (cp, '\t');
2119 /* If there is another tab, ignore everything after it,
2120 for future expansion. */
2121 cp = strchr (cp, '\t');
2129 if (last_node == NULL)
2134 last_node->next = new;
2140 if (alloc_pending (80))
2141 strcpy (pending_error_text,
2142 "E Protocol error; misformed Notify request");
2147 free (new->filename);
2154 /* Process all the Notify requests that we have stored up. Returns 0
2155 if successful, if not prints error message (via error()) and
2156 returns negative value. */
2160 struct notify_note *p;
2163 while (notify_list != NULL)
2165 if ( CVS_CHDIR (notify_list->dir) < 0)
2167 error (0, errno, "cannot change to %s", notify_list->dir);
2170 repos = Name_Repository (NULL, NULL);
2172 lock_dir_for_write (repos);
2174 fileattr_startdir (repos);
2176 notify_do (*notify_list->type, notify_list->filename, getcaller(),
2177 notify_list->val, notify_list->watches, repos);
2179 buf_output0 (buf_to_net, "Notified ");
2181 char *dir = notify_list->dir + strlen (server_temp_dir) + 1;
2183 buf_append_char (buf_to_net, '.');
2185 buf_output0 (buf_to_net, dir);
2186 buf_append_char (buf_to_net, '/');
2187 buf_append_char (buf_to_net, '\n');
2189 buf_output0 (buf_to_net, repos);
2190 buf_append_char (buf_to_net, '/');
2191 buf_output0 (buf_to_net, notify_list->filename);
2192 buf_append_char (buf_to_net, '\n');
2195 p = notify_list->next;
2196 free (notify_list->filename);
2197 free (notify_list->dir);
2198 free (notify_list->type);
2210 /* The code used to call fflush (stdout) here, but that is no
2211 longer necessary. The data is now buffered in buf_to_net,
2212 which will be flushed by the caller, do_cvs_command. */
2217 static int argument_count;
2218 static char **argument_vector;
2219 static int argument_vector_size;
2222 serve_argument (arg)
2227 if (error_pending()) return;
2229 if (argument_count >= 10000)
2231 if (alloc_pending (80))
2232 sprintf (pending_error_text,
2233 "E Protocol error: too many arguments");
2237 if (argument_vector_size <= argument_count)
2239 argument_vector_size *= 2;
2241 (char **) xrealloc ((char *)argument_vector,
2242 argument_vector_size * sizeof (char *));
2243 if (argument_vector == NULL)
2245 pending_error = ENOMEM;
2249 p = xmalloc (strlen (arg) + 1);
2252 pending_error = ENOMEM;
2256 argument_vector[argument_count++] = p;
2260 serve_argumentx (arg)
2265 if (error_pending()) return;
2267 if (argument_count <= 1)
2269 if (alloc_pending (80))
2270 sprintf (pending_error_text,
2271 "E Protocol error: called argumentx without prior call to argument");
2275 p = argument_vector[argument_count - 1];
2276 p = xrealloc (p, strlen (p) + 1 + strlen (arg) + 1);
2279 pending_error = ENOMEM;
2284 argument_vector[argument_count - 1] = p;
2288 serve_global_option (arg)
2291 if (arg[0] != '-' || arg[1] == '\0' || arg[2] != '\0')
2294 if (alloc_pending (strlen (arg) + 80))
2295 sprintf (pending_error_text,
2296 "E Protocol error: bad global option %s",
2303 error(0, 0, "WARNING: global `-l' option ignored.");
2330 /* FIXME: This sends errors immediately (I think); they should be
2331 put into pending_error. */
2337 #ifdef HAVE_KERBEROS
2340 serve_kerberos_encrypt (arg)
2343 /* All future communication with the client will be encrypted. */
2345 buf_to_net = krb_encrypt_buffer_initialize (buf_to_net, 0, sched,
2347 buf_to_net->memory_error);
2348 buf_from_net = krb_encrypt_buffer_initialize (buf_from_net, 1, sched,
2350 buf_from_net->memory_error);
2353 #endif /* HAVE_KERBEROS */
2358 serve_gssapi_encrypt (arg)
2361 if (cvs_gssapi_wrapping)
2363 /* We're already using a gssapi_wrap buffer for stream
2364 authentication. Flush everything we've output so far, and
2365 turn on encryption for future data. On the input side, we
2366 should only have unwrapped as far as the Gssapi-encrypt
2367 command, so future unwrapping will become encrypted. */
2368 buf_flush (buf_to_net, 1);
2369 cvs_gssapi_encrypt = 1;
2373 /* All future communication with the client will be encrypted. */
2375 cvs_gssapi_encrypt = 1;
2377 buf_to_net = cvs_gssapi_wrap_buffer_initialize (buf_to_net, 0,
2379 buf_to_net->memory_error);
2380 buf_from_net = cvs_gssapi_wrap_buffer_initialize (buf_from_net, 1,
2382 buf_from_net->memory_error);
2384 cvs_gssapi_wrapping = 1;
2387 #endif /* HAVE_GSSAPI */
2389 #endif /* ENCRYPTION */
2394 serve_gssapi_authenticate (arg)
2397 if (cvs_gssapi_wrapping)
2399 /* We're already using a gssapi_wrap buffer for encryption.
2400 That includes authentication, so we don't have to do
2401 anything further. */
2405 buf_to_net = cvs_gssapi_wrap_buffer_initialize (buf_to_net, 0,
2407 buf_to_net->memory_error);
2408 buf_from_net = cvs_gssapi_wrap_buffer_initialize (buf_from_net, 1,
2410 buf_from_net->memory_error);
2412 cvs_gssapi_wrapping = 1;
2415 #endif /* HAVE_GSSAPI */
2419 #ifdef SERVER_FLOWCONTROL
2420 /* The maximum we'll queue to the remote client before blocking. */
2421 # ifndef SERVER_HI_WATER
2422 # define SERVER_HI_WATER (2 * 1024 * 1024)
2423 # endif /* SERVER_HI_WATER */
2424 /* When the buffer drops to this, we restart the child */
2425 # ifndef SERVER_LO_WATER
2426 # define SERVER_LO_WATER (1 * 1024 * 1024)
2427 # endif /* SERVER_LO_WATER */
2428 #endif /* SERVER_FLOWCONTROL */
2432 static void serve_questionable PROTO((char *));
2435 serve_questionable (arg)
2442 /* Pick up ignores from CVSROOTADM_IGNORE, $HOME/.cvsignore on server,
2443 and CVSIGNORE on server. */
2448 if (dir_name == NULL)
2450 buf_output0 (buf_to_net, "E Protocol error: 'Directory' missing");
2454 if (outside_dir (arg))
2457 if (!ign_name (arg))
2461 buf_output (buf_to_net, "M ? ", 4);
2462 update_dir = dir_name + strlen (server_temp_dir) + 1;
2463 if (!(update_dir[0] == '.' && update_dir[1] == '\0'))
2465 buf_output0 (buf_to_net, update_dir);
2466 buf_output (buf_to_net, "/", 1);
2468 buf_output0 (buf_to_net, arg);
2469 buf_output (buf_to_net, "\n", 1);
2475 static struct buffer *protocol;
2477 /* This is the output which we are saving up to send to the server, in the
2478 child process. We will push it through, via the `protocol' buffer, when
2479 we have a complete line. */
2480 static struct buffer *saved_output;
2481 /* Likewise, but stuff which will go to stderr. */
2482 static struct buffer *saved_outerr;
2485 protocol_memory_error (buf)
2488 error (1, ENOMEM, "Virtual memory exhausted");
2492 * Process IDs of the subprocess, or negative if that subprocess
2495 static pid_t command_pid;
2498 outbuf_memory_error (buf)
2501 static const char msg[] = "E Fatal server error\n\
2502 error ENOMEM Virtual memory exhausted.\n";
2503 if (command_pid > 0)
2504 kill (command_pid, SIGTERM);
2507 * We have arranged things so that printing this now either will
2508 * be legal, or the "E fatal error" line will get glommed onto the
2509 * end of an existing "E" or "M" response.
2512 /* If this gives an error, not much we could do. syslog() it? */
2513 write (STDOUT_FILENO, msg, sizeof (msg) - 1);
2514 #ifdef HAVE_SYSLOG_H
2515 syslog (LOG_DAEMON | LOG_ERR, "virtual memory exhausted");
2521 input_memory_error (buf)
2524 outbuf_memory_error (buf);
2529 /* If command is legal, return 1.
2530 * Else if command is illegal and croak_on_illegal is set, then die.
2531 * Else just return 0 to indicate that command is illegal.
2534 check_command_legal_p (cmd_name)
2537 /* Right now, only pserver notices illegal commands -- namely,
2538 * write attempts by a read-only user. Therefore, if CVS_Username
2539 * is not set, this just returns 1, because CVS_Username unset
2540 * means pserver is not active.
2542 #ifdef AUTH_SERVER_SUPPORT
2543 if (CVS_Username == NULL)
2546 if (lookup_command_attribute (cmd_name) & CVS_CMD_MODIFIES_REPOSITORY)
2548 /* This command has the potential to modify the repository, so
2549 * we check if the user have permission to do that.
2551 * (Only relevant for remote users -- local users can do
2552 * whatever normal Unix file permissions allow them to do.)
2554 * The decision method:
2556 * If $CVSROOT/CVSADMROOT_READERS exists and user is listed
2557 * in it, then read-only access for user.
2559 * Or if $CVSROOT/CVSADMROOT_WRITERS exists and user NOT
2560 * listed in it, then also read-only access for user.
2562 * Else read-write access for user.
2565 char *linebuf = NULL;
2567 size_t linebuf_len = 0;
2574 flen = strlen (current_parsed_root->directory)
2575 + strlen (CVSROOTADM)
2576 + strlen (CVSROOTADM_READERS)
2579 fname = xmalloc (flen);
2580 (void) sprintf (fname, "%s/%s/%s", current_parsed_root->directory,
2581 CVSROOTADM, CVSROOTADM_READERS);
2583 fp = fopen (fname, "r");
2587 if (!existence_error (errno))
2589 /* Need to deny access, so that attackers can't fool
2590 us with some sort of denial of service attack. */
2591 error (0, errno, "cannot open %s", fname);
2596 else /* successfully opened readers file */
2598 while ((num_red = getline (&linebuf, &linebuf_len, fp)) >= 0)
2600 /* Hmmm, is it worth importing my own readline
2601 library into CVS? It takes care of chopping
2602 leading and trailing whitespace, "#" comments, and
2603 newlines automatically when so requested. Would
2604 save some code here... -kff */
2606 /* Chop newline by hand, for strcmp()'s sake. */
2607 if (num_red > 0 && linebuf[num_red - 1] == '\n')
2608 linebuf[num_red - 1] = '\0';
2610 if (strcmp (linebuf, CVS_Username) == 0)
2611 goto handle_illegal;
2613 if (num_red < 0 && !feof (fp))
2614 error (0, errno, "cannot read %s", fname);
2616 /* If not listed specifically as a reader, then this user
2617 has write access by default unless writers are also
2618 specified in a file . */
2619 if (fclose (fp) < 0)
2620 error (0, errno, "cannot close %s", fname);
2624 /* Now check the writers file. */
2626 flen = strlen (current_parsed_root->directory)
2627 + strlen (CVSROOTADM)
2628 + strlen (CVSROOTADM_WRITERS)
2631 fname = xmalloc (flen);
2632 (void) sprintf (fname, "%s/%s/%s", current_parsed_root->directory,
2633 CVSROOTADM, CVSROOTADM_WRITERS);
2635 fp = fopen (fname, "r");
2641 if (existence_error (errno))
2643 /* Writers file does not exist, so everyone is a writer,
2650 /* Need to deny access, so that attackers can't fool
2651 us with some sort of denial of service attack. */
2652 error (0, errno, "cannot read %s", fname);
2659 while ((num_red = getline (&linebuf, &linebuf_len, fp)) >= 0)
2661 /* Chop newline by hand, for strcmp()'s sake. */
2662 if (num_red > 0 && linebuf[num_red - 1] == '\n')
2663 linebuf[num_red - 1] = '\0';
2665 if (strcmp (linebuf, CVS_Username) == 0)
2671 if (num_red < 0 && !feof (fp))
2672 error (0, errno, "cannot read %s", fname);
2676 if (fclose (fp) < 0)
2677 error (0, errno, "cannot close %s", fname);
2683 else /* writers file exists, but this user not listed in it */
2686 if (fclose (fp) < 0)
2687 error (0, errno, "cannot close %s", fname);
2694 #endif /* AUTH_SERVER_SUPPORT */
2696 /* If ever reach end of this function, command must be legal. */
2702 /* Execute COMMAND in a subprocess with the approriate funky things done. */
2704 static struct fd_set_wrapper { fd_set fds; } command_fds_to_drain;
2706 static int max_command_fd;
2709 #ifdef SERVER_FLOWCONTROL
2710 static int flowcontrol_pipe[2];
2711 #endif /* SERVER_FLOWCONTROL */
2716 * Set buffer FD to non-blocking I/O. Returns 0 for success or errno
2720 set_nonblock_fd (fd)
2725 flags = fcntl (fd, F_GETFL, 0);
2728 if (fcntl (fd, F_SETFL, flags | O_NONBLOCK) < 0)
2736 * Set buffer FD to blocking I/O. Returns 0 for success or errno code.
2744 flags = fcntl (fd, F_GETFL, 0);
2747 if (fcntl (fd, F_SETFL, flags & ~O_NONBLOCK) < 0)
2755 do_cvs_command (cmd_name, command)
2757 int (*command) PROTO((int argc, char **argv));
2760 * The following file descriptors are set to -1 if that file is not
2764 /* Data on these pipes is a series of '\n'-terminated lines. */
2769 * Data on this pipe is a series of counted (see buf_send_counted)
2770 * packets. Each packet must be processed atomically (i.e. not
2771 * interleaved with data from stdout_pipe or stderr_pipe).
2773 int protocol_pipe[2];
2775 int dev_null_fd = -1;
2780 stdout_pipe[0] = -1;
2781 stdout_pipe[1] = -1;
2782 stderr_pipe[0] = -1;
2783 stderr_pipe[1] = -1;
2784 protocol_pipe[0] = -1;
2785 protocol_pipe[1] = -1;
2787 server_write_entries ();
2789 if (print_pending_error ())
2790 goto free_args_and_return;
2792 /* Global `cvs_cmd_name' is probably "server" right now -- only
2793 serve_export() sets it to anything else. So we will use local
2794 parameter `cmd_name' to determine if this command is legal for
2796 if (!check_command_legal_p (cmd_name))
2798 buf_output0 (buf_to_net, "E ");
2799 buf_output0 (buf_to_net, program_name);
2800 buf_output0 (buf_to_net, " [server aborted]: \"");
2801 buf_output0 (buf_to_net, cmd_name);
2802 buf_output0 (buf_to_net, "\" requires write access to the repository\n\
2804 goto free_args_and_return;
2806 cvs_cmd_name = cmd_name;
2808 (void) server_notify ();
2811 * We use a child process which actually does the operation. This
2812 * is so we can intercept its standard output. Even if all of CVS
2813 * were written to go to some special routine instead of writing
2814 * to stdout or stderr, we would still need to do the same thing
2815 * for the RCS commands.
2818 if (pipe (stdout_pipe) < 0)
2820 buf_output0 (buf_to_net, "E pipe failed\n");
2821 print_error (errno);
2824 if (pipe (stderr_pipe) < 0)
2826 buf_output0 (buf_to_net, "E pipe failed\n");
2827 print_error (errno);
2830 if (pipe (protocol_pipe) < 0)
2832 buf_output0 (buf_to_net, "E pipe failed\n");
2833 print_error (errno);
2836 #ifdef SERVER_FLOWCONTROL
2837 if (pipe (flowcontrol_pipe) < 0)
2839 buf_output0 (buf_to_net, "E pipe failed\n");
2840 print_error (errno);
2843 set_nonblock_fd (flowcontrol_pipe[0]);
2844 set_nonblock_fd (flowcontrol_pipe[1]);
2845 #endif /* SERVER_FLOWCONTROL */
2847 dev_null_fd = CVS_OPEN (DEVNULL, O_RDONLY);
2848 if (dev_null_fd < 0)
2850 buf_output0 (buf_to_net, "E open /dev/null failed\n");
2851 print_error (errno);
2855 /* We shouldn't have any partial lines from cvs_output and
2856 cvs_outerr, but we handle them here in case there is a bug. */
2857 /* FIXME: appending a newline, rather than using "MT" as we
2858 do in the child process, is probably not really a very good
2859 way to "handle" them. */
2860 if (! buf_empty_p (saved_output))
2862 buf_append_char (saved_output, '\n');
2863 buf_copy_lines (buf_to_net, saved_output, 'M');
2865 if (! buf_empty_p (saved_outerr))
2867 buf_append_char (saved_outerr, '\n');
2868 buf_copy_lines (buf_to_net, saved_outerr, 'E');
2871 /* Flush out any pending data. */
2872 buf_flush (buf_to_net, 1);
2874 /* Don't use vfork; we're not going to exec(). */
2875 command_pid = fork ();
2876 if (command_pid < 0)
2878 buf_output0 (buf_to_net, "E fork failed\n");
2879 print_error (errno);
2882 if (command_pid == 0)
2886 /* Since we're in the child, and the parent is going to take
2887 care of packaging up our error messages, we can clear this
2889 error_use_protocol = 0;
2891 protocol = fd_buffer_initialize (protocol_pipe[1], 0,
2892 protocol_memory_error);
2894 /* At this point we should no longer be using buf_to_net and
2895 buf_from_net. Instead, everything should go through
2897 if (buf_to_net != NULL)
2899 buf_free (buf_to_net);
2902 if (buf_from_net != NULL)
2904 buf_free (buf_from_net);
2905 buf_from_net = NULL;
2908 /* These were originally set up to use outbuf_memory_error.
2909 Since we're now in the child, we should use the simpler
2910 protocol_memory_error function. */
2911 saved_output->memory_error = protocol_memory_error;
2912 saved_outerr->memory_error = protocol_memory_error;
2914 if (dup2 (dev_null_fd, STDIN_FILENO) < 0)
2915 error (1, errno, "can't set up pipes");
2916 if (dup2 (stdout_pipe[1], STDOUT_FILENO) < 0)
2917 error (1, errno, "can't set up pipes");
2918 if (dup2 (stderr_pipe[1], STDERR_FILENO) < 0)
2919 error (1, errno, "can't set up pipes");
2920 close (dev_null_fd);
2921 close (stdout_pipe[0]);
2922 close (stdout_pipe[1]);
2923 close (stderr_pipe[0]);
2924 close (stderr_pipe[1]);
2925 close (protocol_pipe[0]);
2926 close_on_exec (protocol_pipe[1]);
2927 #ifdef SERVER_FLOWCONTROL
2928 close_on_exec (flowcontrol_pipe[0]);
2929 close (flowcontrol_pipe[1]);
2930 #endif /* SERVER_FLOWCONTROL */
2933 * Set this in .bashrc if you want to give yourself time to attach
2934 * to the subprocess with a debugger.
2936 if (getenv ("CVS_SERVER_SLEEP"))
2938 int secs = atoi (getenv ("CVS_SERVER_SLEEP"));
2942 exitstatus = (*command) (argument_count, argument_vector);
2944 /* Output any partial lines. If the client doesn't support
2945 "MT", we go ahead and just tack on a newline since the
2946 protocol doesn't support anything better. */
2947 if (! buf_empty_p (saved_output))
2949 buf_output0 (protocol, supported_response ("MT") ? "MT text " : "M ");
2950 buf_append_buffer (protocol, saved_output);
2951 buf_output (protocol, "\n", 1);
2952 buf_send_counted (protocol);
2954 /* For now we just discard partial lines on stderr. I suspect
2955 that CVS can't write such lines unless there is a bug. */
2957 buf_free (protocol);
2959 /* Close the pipes explicitly in order to send an EOF to the parent,
2960 * then wait for the parent to close the flow control pipe. This
2961 * avoids a race condition where a child which dumped more than the
2962 * high water mark into the pipes could complete its job and exit,
2963 * leaving the parent process to attempt to write a stop byte to the
2964 * closed flow control pipe, which earned the parent a SIGPIPE, which
2965 * it normally only expects on the network pipe and that causes it to
2966 * exit with an error message, rather than the SIGCHILD that it knows
2967 * how to handle correctly.
2969 /* Let exit() close STDIN - it's from /dev/null anyhow. */
2972 close (protocol_pipe[1]);
2973 #ifdef SERVER_FLOWCONTROL
2976 set_block_fd (flowcontrol_pipe[0]);
2977 while (read (flowcontrol_pipe[0], &junk, 1) > 0);
2979 /* FIXME: No point in printing an error message with error(),
2980 * as STDERR is already closed, but perhaps this could be syslogged?
2986 /* Don't call server_cleanup - the parent will handle that. */
2987 #ifdef SYSTEM_CLEANUP
2988 /* Hook for OS-specific behavior, for example socket subsystems on
2989 NT and OS2 or dealing with windows and arguments on Mac. */
2995 /* OK, sit around getting all the input from the child. */
2997 struct buffer *stdoutbuf = NULL;
2998 struct buffer *stderrbuf = NULL;
2999 struct buffer *protocol_inbuf = NULL;
3001 /* Number of file descriptors to check in select (). */
3003 int count_needed = 1;
3004 #ifdef SERVER_FLOWCONTROL
3005 int have_flowcontrolled = 0;
3006 #endif /* SERVER_FLOWCONTROL */
3008 FD_ZERO (&command_fds_to_drain.fds);
3009 num_to_check = stdout_pipe[0];
3010 FD_SET (stdout_pipe[0], &command_fds_to_drain.fds);
3011 if (stderr_pipe[0] > num_to_check)
3012 num_to_check = stderr_pipe[0];
3013 FD_SET (stderr_pipe[0], &command_fds_to_drain.fds);
3014 if (protocol_pipe[0] > num_to_check)
3015 num_to_check = protocol_pipe[0];
3016 FD_SET (protocol_pipe[0], &command_fds_to_drain.fds);
3017 if (STDOUT_FILENO > num_to_check)
3018 num_to_check = STDOUT_FILENO;
3020 max_command_fd = num_to_check;
3023 * File descriptors are numbered from 0, so num_to_check needs to
3024 * be one larger than the largest descriptor.
3027 if (num_to_check > FD_SETSIZE)
3029 buf_output0 (buf_to_net,
3030 "E internal error: FD_SETSIZE not big enough.\n\
3035 stdoutbuf = fd_buffer_initialize (stdout_pipe[0], 1,
3036 input_memory_error);
3038 stderrbuf = fd_buffer_initialize (stderr_pipe[0], 1,
3039 input_memory_error);
3041 protocol_inbuf = fd_buffer_initialize (protocol_pipe[0], 1,
3042 input_memory_error);
3044 set_nonblock (buf_to_net);
3045 set_nonblock (stdoutbuf);
3046 set_nonblock (stderrbuf);
3047 set_nonblock (protocol_inbuf);
3049 if (close (stdout_pipe[1]) < 0)
3051 buf_output0 (buf_to_net, "E close failed\n");
3052 print_error (errno);
3056 stdout_pipe[1] = -1;
3058 if (close (stderr_pipe[1]) < 0)
3060 buf_output0 (buf_to_net, "E close failed\n");
3061 print_error (errno);
3065 stderr_pipe[1] = -1;
3067 if (close (protocol_pipe[1]) < 0)
3069 buf_output0 (buf_to_net, "E close failed\n");
3070 print_error (errno);
3074 protocol_pipe[1] = -1;
3076 #ifdef SERVER_FLOWCONTROL
3077 if (close (flowcontrol_pipe[0]) < 0)
3079 buf_output0 (buf_to_net, "E close failed\n");
3080 print_error (errno);
3084 flowcontrol_pipe[0] = -1;
3085 #endif /* SERVER_FLOWCONTROL */
3087 if (close (dev_null_fd) < 0)
3089 buf_output0 (buf_to_net, "E close failed\n");
3090 print_error (errno);
3091 dev_null_fd = -1; /* Do not try to close it again. */
3097 while (stdout_pipe[0] >= 0
3098 || stderr_pipe[0] >= 0
3099 || protocol_pipe[0] >= 0
3100 || count_needed <= 0)
3105 struct timeval *timeout_ptr;
3106 struct timeval timeout;
3107 #ifdef SERVER_FLOWCONTROL
3111 * See if we are swamping the remote client and filling our VM.
3112 * Tell child to hold off if we do.
3114 bufmemsize = buf_count_mem (buf_to_net);
3115 if (!have_flowcontrolled && (bufmemsize > SERVER_HI_WATER))
3117 if (write(flowcontrol_pipe[1], "S", 1) == 1)
3118 have_flowcontrolled = 1;
3120 else if (have_flowcontrolled && (bufmemsize < SERVER_LO_WATER))
3122 if (write(flowcontrol_pipe[1], "G", 1) == 1)
3123 have_flowcontrolled = 0;
3125 #endif /* SERVER_FLOWCONTROL */
3128 FD_ZERO (&writefds);
3130 if (count_needed <= 0)
3132 /* there is data pending which was read from the protocol pipe
3133 * so don't block if we don't find any data
3136 timeout.tv_usec = 0;
3137 timeout_ptr = &timeout;
3141 /* block indefinately */
3145 if (! buf_empty_p (buf_to_net))
3146 FD_SET (STDOUT_FILENO, &writefds);
3148 if (stdout_pipe[0] >= 0)
3150 FD_SET (stdout_pipe[0], &readfds);
3152 if (stderr_pipe[0] >= 0)
3154 FD_SET (stderr_pipe[0], &readfds);
3156 if (protocol_pipe[0] >= 0)
3158 FD_SET (protocol_pipe[0], &readfds);
3161 /* This process of selecting on the three pipes means that
3162 we might not get output in the same order in which it
3163 was written, thus producing the well-known
3164 "out-of-order" bug. If the child process uses
3165 cvs_output and cvs_outerr, it will send everything on
3166 the protocol_pipe and avoid this problem, so the
3167 solution is to use cvs_output and cvs_outerr in the
3170 /* This used to select on exceptions too, but as far
3171 as I know there was never any reason to do that and
3172 SCO doesn't let you select on exceptions on pipes. */
3173 numfds = select (num_to_check, &readfds, &writefds,
3174 (fd_set *)0, timeout_ptr);
3178 buf_output0 (buf_to_net, "E select failed\n");
3179 print_error (errno);
3183 } while (numfds < 0);
3188 FD_ZERO (&writefds);
3191 if (FD_ISSET (STDOUT_FILENO, &writefds))
3193 /* What should we do with errors? syslog() them? */
3194 buf_send_output (buf_to_net);
3197 if (protocol_pipe[0] >= 0
3198 && (FD_ISSET (protocol_pipe[0], &readfds)))
3203 status = buf_input_data (protocol_inbuf, &count_read);
3207 close (protocol_pipe[0]);
3208 protocol_pipe[0] = -1;
3210 else if (status > 0)
3212 buf_output0 (buf_to_net, "E buf_input_data failed\n");
3213 print_error (status);
3219 * We only call buf_copy_counted if we have read
3220 * enough bytes to make it worthwhile. This saves us
3221 * from continually recounting the amount of data we
3224 count_needed -= count_read;
3226 /* this is still part of the protocol pipe procedure, but it is
3227 * outside the above conditional so that unprocessed data can be
3228 * left in the buffer and stderr/stdout can be read when a flush
3229 * signal is received and control can return here without passing
3230 * through the select code and maybe blocking
3232 while (count_needed <= 0)
3236 count_needed = buf_copy_counted (buf_to_net,
3240 /* What should we do with errors? syslog() them? */
3241 buf_send_output (buf_to_net);
3243 /* If SPECIAL got set to <0, it means that the child
3244 * wants us to flush the pipe & maybe stderr or stdout.
3246 * After that we break to read stderr & stdout again before
3247 * going back to the protocol pipe
3249 * Upon breaking, count_needed = 0, so the next pass will only
3250 * perform a non-blocking select before returning here to finish
3251 * processing data we already read from the protocol buffer
3260 /* If the client supports the 'F' command, we send it. */
3261 if (supported_response ("F"))
3263 buf_append_char (buf_to_net, 'F');
3264 buf_append_char (buf_to_net, '\n');
3271 if (stdout_pipe[0] >= 0
3272 && (FD_ISSET (stdout_pipe[0], &readfds)))
3276 status = buf_input_data (stdoutbuf, (int *) NULL);
3278 buf_copy_lines (buf_to_net, stdoutbuf, 'M');
3282 close (stdout_pipe[0]);
3283 stdout_pipe[0] = -1;
3285 else if (status > 0)
3287 buf_output0 (buf_to_net, "E buf_input_data failed\n");
3288 print_error (status);
3293 /* What should we do with errors? syslog() them? */
3294 buf_send_output (buf_to_net);
3297 if (stderr_pipe[0] >= 0
3298 && (FD_ISSET (stderr_pipe[0], &readfds)))
3302 status = buf_input_data (stderrbuf, (int *) NULL);
3304 buf_copy_lines (buf_to_net, stderrbuf, 'E');
3308 close (stderr_pipe[0]);
3309 stderr_pipe[0] = -1;
3311 else if (status > 0)
3313 buf_output0 (buf_to_net, "E buf_input_data failed\n");
3314 print_error (status);
3319 /* What should we do with errors? syslog() them? */
3320 buf_send_output (buf_to_net);
3325 * OK, we've gotten EOF on all the pipes. If there is
3326 * anything left on stdoutbuf or stderrbuf (this could only
3327 * happen if there was no trailing newline), send it over.
3329 if (! buf_empty_p (stdoutbuf))
3331 buf_append_char (stdoutbuf, '\n');
3332 buf_copy_lines (buf_to_net, stdoutbuf, 'M');
3334 if (! buf_empty_p (stderrbuf))
3336 buf_append_char (stderrbuf, '\n');
3337 buf_copy_lines (buf_to_net, stderrbuf, 'E');
3339 if (! buf_empty_p (protocol_inbuf))
3340 buf_output0 (buf_to_net,
3341 "E Protocol error: uncounted data discarded\n");
3343 #ifdef SERVER_FLOWCONTROL
3344 close (flowcontrol_pipe[1]);
3345 flowcontrol_pipe[1] = -1;
3346 #endif /* SERVER_FLOWCONTROL */
3350 while (command_pid > 0)
3354 waited_pid = waitpid (command_pid, &status, 0);
3358 * Intentionally ignoring EINTR. Other errors
3364 if (WIFEXITED (status))
3365 errs += WEXITSTATUS (status);
3368 int sig = WTERMSIG (status);
3371 * This is really evil, because signals might be numbered
3372 * differently on the two systems. We should be using
3373 * signal names (either of the "Terminated" or the "SIGTERM"
3374 * variety). But cvs doesn't currently use libiberty...we
3375 * could roll our own.... FIXME.
3377 buf_output0 (buf_to_net, "E Terminated with fatal signal ");
3378 sprintf (buf, "%d\n", sig);
3379 buf_output0 (buf_to_net, buf);
3381 /* Test for a core dump. */
3382 if (WCOREDUMP (status))
3384 buf_output0 (buf_to_net, "E Core dumped; preserving ");
3385 buf_output0 (buf_to_net, orig_server_temp_dir);
3386 buf_output0 (buf_to_net, " on server.\n\
3387 E CVS locks may need cleaning up.\n");
3388 dont_delete_temp = 1;
3392 if (waited_pid == command_pid)
3398 * OK, we've waited for the child. By now all CVS locks are free
3399 * and it's OK to block on the network.
3401 set_block (buf_to_net);
3402 buf_flush (buf_to_net, 1);
3405 buf_shutdown (protocol_inbuf);
3406 buf_free (protocol_inbuf);
3407 protocol_inbuf = NULL;
3411 buf_shutdown (stderrbuf);
3412 buf_free (stderrbuf);
3417 buf_shutdown (stdoutbuf);
3418 buf_free (stdoutbuf);
3426 /* We will have printed an error message already. */
3427 buf_output0 (buf_to_net, "error \n");
3429 buf_output0 (buf_to_net, "ok\n");
3430 goto free_args_and_return;
3433 if (command_pid > 0)
3434 kill (command_pid, SIGTERM);
3436 while (command_pid > 0)
3439 waited_pid = waitpid (command_pid, (int *) 0, 0);
3440 if (waited_pid < 0 && errno == EINTR)
3442 if (waited_pid == command_pid)
3446 if (dev_null_fd >= 0)
3447 close (dev_null_fd);
3448 close (protocol_pipe[0]);
3449 close (protocol_pipe[1]);
3450 close (stderr_pipe[0]);
3451 close (stderr_pipe[1]);
3452 close (stdout_pipe[0]);
3453 close (stdout_pipe[1]);
3454 #ifdef SERVER_FLOWCONTROL
3455 close (flowcontrol_pipe[0]);
3456 close (flowcontrol_pipe[1]);
3457 #endif /* SERVER_FLOWCONTROL */
3459 free_args_and_return:
3460 /* Now free the arguments. */
3462 /* argument_vector[0] is a dummy argument, we don't mess with it. */
3464 for (cp = argument_vector + 1;
3465 cp < argument_vector + argument_count;
3472 /* Flush out any data not yet sent. */
3473 set_block (buf_to_net);
3474 buf_flush (buf_to_net, 1);
3479 #ifdef SERVER_FLOWCONTROL
3481 * Called by the child at convenient points in the server's execution for
3482 * the server child to block.. ie: when it has no locks active.
3485 server_pause_check()
3490 while (read (flowcontrol_pipe[0], buf, 1) == 1)
3492 if (*buf == 'S') /* Stop */
3494 else if (*buf == 'G') /* Go */
3500 int numfds, numtocheck;
3504 FD_SET (flowcontrol_pipe[0], &fds);
3505 numtocheck = flowcontrol_pipe[0] + 1;
3508 numfds = select (numtocheck, &fds, (fd_set *)0,
3509 (fd_set *)0, (struct timeval *)NULL);
3513 buf_output0 (buf_to_net, "E select failed\n");
3514 print_error (errno);
3517 } while (numfds < 0);
3519 if (FD_ISSET (flowcontrol_pipe[0], &fds))
3523 while ((got = read (flowcontrol_pipe[0], buf, 1)) == 1)
3525 if (*buf == 'S') /* Stop */
3527 else if (*buf == 'G') /* Go */
3533 /* This assumes that we are using BSD or POSIX nonblocking
3534 I/O. System V nonblocking I/O returns zero if there is
3537 error (1, 0, "flow control EOF");
3538 if (got < 0 && ! blocking_error (errno))
3540 error (1, errno, "flow control read failed");
3545 #endif /* SERVER_FLOWCONTROL */
3547 /* This variable commented in server.h. */
3548 char *server_dir = NULL;
3552 static void output_dir PROTO((const char *, const char *));
3555 output_dir (update_dir, repository)
3556 const char *update_dir;
3557 const char *repository;
3559 if (server_dir != NULL)
3561 buf_output0 (protocol, server_dir);
3562 buf_output0 (protocol, "/");
3564 if (update_dir[0] == '\0')
3565 buf_output0 (protocol, ".");
3567 buf_output0 (protocol, update_dir);
3568 buf_output0 (protocol, "/\n");
3569 buf_output0 (protocol, repository);
3570 buf_output0 (protocol, "/");
3576 * Entries line that we are squirreling away to send to the client when
3579 static char *entries_line;
3582 * File which has been Scratch_File'd, we are squirreling away that fact
3583 * to inform the client when we are ready.
3585 static char *scratched_file;
3588 * The scratched_file will need to be removed as well as having its entry
3591 static int kill_scratched_file;
3596 server_register (name, version, timestamp, options, tag, date, conflict)
3598 const char *version;
3599 const char *timestamp;
3600 const char *options;
3603 const char *conflict;
3607 if (options == NULL)
3612 (void) fprintf (stderr,
3613 "%s-> server_register(%s, %s, %s, %s, %s, %s, %s)\n",
3615 name, version, timestamp ? timestamp : "", options,
3616 tag ? tag : "", date ? date : "",
3617 conflict ? conflict : "");
3620 if (entries_line != NULL)
3623 * If CVS decides to Register it more than once (which happens
3624 * on "cvs update foo/foo.c" where foo and foo.c are already
3625 * checked out), use the last of the entries lines Register'd.
3627 free (entries_line);
3631 * I have reports of Scratch_Entry and Register both happening, in
3632 * two different cases. Using the last one which happens is almost
3633 * surely correct; I haven't tracked down why they both happen (or
3634 * even verified that they are for the same file).
3636 if (scratched_file != NULL)
3638 free (scratched_file);
3639 scratched_file = NULL;
3642 len = (strlen (name) + strlen (version) + strlen (options) + 80);
3644 len += strlen (tag);
3646 len += strlen (date);
3648 entries_line = xmalloc (len);
3649 sprintf (entries_line, "/%s/%s/", name, version);
3650 if (conflict != NULL)
3652 strcat (entries_line, "+=");
3654 strcat (entries_line, "/");
3655 strcat (entries_line, options);
3656 strcat (entries_line, "/");
3659 strcat (entries_line, "T");
3660 strcat (entries_line, tag);
3662 else if (date != NULL)
3664 strcat (entries_line, "D");
3665 strcat (entries_line, date);
3672 server_scratch (fname)
3676 * I have reports of Scratch_Entry and Register both happening, in
3677 * two different cases. Using the last one which happens is almost
3678 * surely correct; I haven't tracked down why they both happen (or
3679 * even verified that they are for the same file).
3681 * Don't know if this is what whoever wrote the above comment was
3682 * talking about, but this can happen in the case where a join
3683 * removes a file - the call to Register puts the '-vers' into the
3684 * Entries file after the file is removed
3686 if (entries_line != NULL)
3688 free (entries_line);
3689 entries_line = NULL;
3692 if (scratched_file != NULL)
3694 buf_output0 (protocol,
3695 "E CVS server internal error: duplicate Scratch_Entry\n");
3696 buf_send_counted (protocol);
3699 scratched_file = xstrdup (fname);
3700 kill_scratched_file = 1;
3704 server_scratch_entry_only ()
3706 kill_scratched_file = 0;
3709 /* Print a new entries line, from a previous server_register. */
3715 buf_output0 (protocol, entries_line);
3716 buf_output (protocol, "\n", 1);
3719 /* Return the error message as the Entries line. */
3720 buf_output0 (protocol,
3721 "CVS server internal error: Register missing\n");
3722 free (entries_line);
3723 entries_line = NULL;
3731 do_cvs_command ("commit", commit);
3735 checked_in_response (file, update_dir, repository)
3740 if (supported_response ("Mode"))
3745 if ( CVS_STAT (file, &sb) < 0)
3747 /* Not clear to me why the file would fail to exist, but it
3748 was happening somewhere in the testsuite. */
3749 if (!existence_error (errno))
3750 error (0, errno, "cannot stat %s", file);
3754 buf_output0 (protocol, "Mode ");
3755 mode_string = mode_to_string (sb.st_mode);
3756 buf_output0 (protocol, mode_string);
3757 buf_output0 (protocol, "\n");
3762 buf_output0 (protocol, "Checked-in ");
3763 output_dir (update_dir, repository);
3764 buf_output0 (protocol, file);
3765 buf_output (protocol, "\n", 1);
3766 new_entries_line ();
3770 server_checked_in (file, update_dir, repository)
3772 const char *update_dir;
3773 const char *repository;
3776 assert (update_dir);
3777 assert (repository);
3781 if (scratched_file != NULL && entries_line == NULL)
3784 * This happens if we are now doing a "cvs remove" after a previous
3785 * "cvs add" (without a "cvs ci" in between).
3787 buf_output0 (protocol, "Remove-entry ");
3788 output_dir (update_dir, repository);
3789 buf_output0 (protocol, file);
3790 buf_output (protocol, "\n", 1);
3791 free (scratched_file);
3792 scratched_file = NULL;
3796 checked_in_response (file, update_dir, repository);
3798 buf_send_counted (protocol);
3802 server_update_entries (file, update_dir, repository, updated)
3804 const char *update_dir;
3805 const char *repository;
3806 enum server_updated_arg4 updated;
3810 if (updated == SERVER_UPDATED)
3811 checked_in_response (file, update_dir, repository);
3814 if (!supported_response ("New-entry"))
3816 buf_output0 (protocol, "New-entry ");
3817 output_dir (update_dir, repository);
3818 buf_output0 (protocol, file);
3819 buf_output (protocol, "\n", 1);
3820 new_entries_line ();
3823 buf_send_counted (protocol);
3830 do_cvs_command ("update", update);
3837 do_cvs_command ("diff", diff);
3844 do_cvs_command ("log", cvslog);
3851 do_cvs_command ("rlog", cvslog);
3858 do_cvs_command ("add", add);
3865 do_cvs_command ("remove", cvsremove);
3872 do_cvs_command ("status", cvsstatus);
3879 do_cvs_command ("rdiff", patch);
3886 do_cvs_command ("tag", cvstag);
3893 do_cvs_command ("rtag", cvstag);
3900 do_cvs_command ("import", import);
3907 do_cvs_command ("admin", admin);
3914 do_cvs_command ("history", history);
3921 do_cvs_command ("release", release);
3924 static void serve_watch_on PROTO ((char *));
3927 serve_watch_on (arg)
3930 do_cvs_command ("watch", watch_on);
3933 static void serve_watch_off PROTO ((char *));
3936 serve_watch_off (arg)
3939 do_cvs_command ("watch", watch_off);
3942 static void serve_watch_add PROTO ((char *));
3945 serve_watch_add (arg)
3948 do_cvs_command ("watch", watch_add);
3951 static void serve_watch_remove PROTO ((char *));
3954 serve_watch_remove (arg)
3957 do_cvs_command ("watch", watch_remove);
3960 static void serve_watchers PROTO ((char *));
3963 serve_watchers (arg)
3966 do_cvs_command ("watchers", watchers);
3969 static void serve_editors PROTO ((char *));
3975 do_cvs_command ("editors", editors);
3978 static void serve_noop PROTO ((char *));
3985 server_write_entries ();
3986 if (!print_pending_error ())
3988 (void) server_notify ();
3989 buf_output0 (buf_to_net, "ok\n");
3991 buf_flush (buf_to_net, 1);
3994 static void serve_version PROTO ((char *));
4000 do_cvs_command ("version", version);
4003 static void serve_init PROTO ((char *));
4009 if (alloc_pending (80 + strlen (arg)))
4010 sprintf (pending_error_text, "E init may not be run remotely");
4012 if (print_pending_error ())
4016 static void serve_annotate PROTO ((char *));
4019 serve_annotate (arg)
4022 do_cvs_command ("annotate", annotate);
4025 static void serve_rannotate PROTO ((char *));
4028 serve_rannotate (arg)
4031 do_cvs_command ("rannotate", annotate);
4041 if (print_pending_error ())
4044 if (!isdir (CVSADM))
4047 * The client has not sent a "Repository" line. Check out
4048 * into a pristine directory.
4050 tempdir = xmalloc (strlen (server_temp_dir) + 80);
4051 if (tempdir == NULL)
4053 buf_output0 (buf_to_net, "E Out of memory\n");
4056 strcpy (tempdir, server_temp_dir);
4057 strcat (tempdir, "/checkout-dir");
4058 status = mkdir_p (tempdir);
4059 if (status != 0 && status != EEXIST)
4061 buf_output0 (buf_to_net, "E Cannot create ");
4062 buf_output0 (buf_to_net, tempdir);
4063 buf_append_char (buf_to_net, '\n');
4064 print_error (errno);
4069 if ( CVS_CHDIR (tempdir) < 0)
4071 buf_output0 (buf_to_net, "E Cannot change to directory ");
4072 buf_output0 (buf_to_net, tempdir);
4073 buf_append_char (buf_to_net, '\n');
4074 print_error (errno);
4081 /* Compensate for server_export()'s setting of cvs_cmd_name.
4083 * [It probably doesn't matter if do_cvs_command() gets "export"
4084 * or "checkout", but we ought to be accurate where possible.]
4086 do_cvs_command ((strcmp (cvs_cmd_name, "export") == 0) ?
4087 "export" : "checkout",
4095 /* Tell checkout() to behave like export not checkout. */
4096 cvs_cmd_name = "export";
4103 server_copy_file (file, update_dir, repository, newfile)
4105 const char *update_dir;
4106 const char *repository;
4107 const char *newfile;
4109 /* At least for now, our practice is to have the server enforce
4110 noexec for the repository and the client enforce it for the
4111 working directory. This might want more thought, and/or
4112 documentation in cvsclient.texi (other responses do it
4115 if (!supported_response ("Copy-file"))
4117 buf_output0 (protocol, "Copy-file ");
4118 output_dir (update_dir, repository);
4119 buf_output0 (protocol, file);
4120 buf_output0 (protocol, "\n");
4121 buf_output0 (protocol, newfile);
4122 buf_output0 (protocol, "\n");
4125 /* See server.h for description. */
4128 server_modtime (finfo, vers_ts)
4129 struct file_info *finfo;
4132 char date[MAXDATELEN];
4133 char outdate[MAXDATELEN];
4135 assert (vers_ts->vn_rcs != NULL);
4137 if (!supported_response ("Mod-time"))
4140 if (RCS_getrevtime (finfo->rcs, vers_ts->vn_rcs, date, 0) == (time_t) -1)
4141 /* FIXME? should we be printing some kind of warning? For one
4142 thing I'm not 100% sure whether this happens in non-error
4145 date_to_internet (outdate, date);
4146 buf_output0 (protocol, "Mod-time ");
4147 buf_output0 (protocol, outdate);
4148 buf_output0 (protocol, "\n");
4151 /* See server.h for description. */
4153 #if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__)
4154 /* Need to prototype because mode_t might be smaller than int. */
4157 struct file_info *finfo,
4159 enum server_updated_arg4 updated,
4161 unsigned char *checksum,
4162 struct buffer *filebuf)
4165 server_updated (finfo, vers, updated, mode, checksum, filebuf)
4166 struct file_info *finfo;
4168 enum server_updated_arg4 updated;
4170 unsigned char *checksum;
4171 struct buffer *filebuf;
4176 /* Hmm, maybe if we did the same thing for entries_file, we
4177 could get rid of the kludges in server_register and
4178 server_scratch which refrain from warning if both
4179 Scratch_Entry and Register get called. Maybe. */
4182 free (scratched_file);
4183 scratched_file = NULL;
4185 buf_send_counted (protocol);
4189 if (entries_line != NULL && scratched_file == NULL)
4192 struct buffer_data *list, *last;
4196 /* The contents of the file will be in one of filebuf,
4197 list/last, or here. */
4198 unsigned char *file;
4199 size_t file_allocated;
4202 if (filebuf != NULL)
4204 size = buf_length (filebuf);
4205 if (mode == (mode_t) -1)
4207 CVS server internal error: no mode in server_updated");
4213 if ( CVS_STAT (finfo->file, &sb) < 0)
4215 if (existence_error (errno))
4217 /* If we have a sticky tag for a branch on which
4218 the file is dead, and cvs update the directory,
4219 it gets a T_CHECKOUT but no file. So in this
4220 case just forget the whole thing. */
4221 free (entries_line);
4222 entries_line = NULL;
4225 error (1, errno, "reading %s", finfo->fullname);
4228 if (mode == (mode_t) -1)
4230 /* FIXME: When we check out files the umask of the
4231 server (set in .bashrc if rsh is in use) affects
4232 what mode we send, and it shouldn't. */
4237 if (checksum != NULL)
4239 static int checksum_supported = -1;
4241 if (checksum_supported == -1)
4243 checksum_supported = supported_response ("Checksum");
4246 if (checksum_supported)
4251 buf_output0 (protocol, "Checksum ");
4252 for (i = 0; i < 16; i++)
4254 sprintf (buf, "%02x", (unsigned int) checksum[i]);
4255 buf_output0 (protocol, buf);
4257 buf_append_char (protocol, '\n');
4261 if (updated == SERVER_UPDATED)
4265 if (!(supported_response ("Created")
4266 && supported_response ("Update-existing")))
4267 buf_output0 (protocol, "Updated ");
4270 assert (vers != NULL);
4271 if (vers->ts_user == NULL)
4272 buf_output0 (protocol, "Created ");
4274 buf_output0 (protocol, "Update-existing ");
4277 /* Now munge the entries to say that the file is unmodified,
4278 in case we end up processing it again (e.g. modules3-6
4279 in the testsuite). */
4280 node = findnode_fn (finfo->entries, finfo->file);
4281 assert (node != NULL);
4284 Entnode *entnode = node->data;
4285 free (entnode->timestamp);
4286 entnode->timestamp = xstrdup ("=");
4289 else if (updated == SERVER_MERGED)
4290 buf_output0 (protocol, "Merged ");
4291 else if (updated == SERVER_PATCHED)
4292 buf_output0 (protocol, "Patched ");
4293 else if (updated == SERVER_RCS_DIFF)
4294 buf_output0 (protocol, "Rcs-diff ");
4297 output_dir (finfo->update_dir, finfo->repository);
4298 buf_output0 (protocol, finfo->file);
4299 buf_output (protocol, "\n", 1);
4301 new_entries_line ();
4306 mode_string = mode_to_string (mode);
4307 buf_output0 (protocol, mode_string);
4308 buf_output0 (protocol, "\n");
4320 /* Throughout this section we use binary mode to read the
4321 file we are sending. The client handles any line ending
4322 translation if necessary. */
4326 * For really tiny files, the gzip process startup
4327 * time will outweigh the compression savings. This
4328 * might be computable somehow; using 100 here is just
4329 * a first approximation.
4333 /* Basing this routine on read_and_gzip is not a
4334 high-performance approach. But it seems easier
4335 to code than the alternative (and less
4336 vulnerable to subtle bugs). Given that this feature
4337 is mainly for compatibility, that is the better
4342 /* Callers must avoid passing us a buffer if
4343 file_gzip_level is set. We could handle this case,
4344 but it's not worth it since this case never arises
4345 with a current client and server. */
4346 if (filebuf != NULL)
4348 CVS server internal error: unhandled case in server_updated");
4350 fd = CVS_OPEN (finfo->file, O_RDONLY | OPEN_BINARY, 0);
4352 error (1, errno, "reading %s", finfo->fullname);
4353 if (read_and_gzip (fd, finfo->fullname, &file,
4354 &file_allocated, &file_used,
4356 error (1, 0, "aborting due to compression error");
4359 error (1, errno, "reading %s", finfo->fullname);
4360 /* Prepending length with "z" is flag for using gzip here. */
4361 buf_output0 (protocol, "z");
4363 else if (filebuf == NULL)
4367 f = CVS_FOPEN (finfo->file, "rb");
4369 error (1, errno, "reading %s", finfo->fullname);
4370 status = buf_read_file (f, size, &list, &last);
4372 (*protocol->memory_error) (protocol);
4373 else if (status != 0)
4374 error (1, ferror (f) ? errno : 0, "reading %s",
4376 if (fclose (f) == EOF)
4377 error (1, errno, "reading %s", finfo->fullname);
4381 sprintf (size_text, "%lu\n", size);
4382 buf_output0 (protocol, size_text);
4386 buf_output (protocol, (char *) file, file_used);
4390 else if (filebuf == NULL)
4391 buf_append_data (protocol, list, last);
4394 buf_append_buffer (protocol, filebuf);
4396 /* Note we only send a newline here if the file ended with one. */
4399 * Avoid using up too much disk space for temporary files.
4400 * A file which does not exist indicates that the file is up-to-date,
4401 * which is now the case. If this is SERVER_MERGED, the file is
4402 * not up-to-date, and we indicate that by leaving the file there.
4403 * I'm thinking of cases like "cvs update foo/foo.c foo".
4405 if ((updated == SERVER_UPDATED
4406 || updated == SERVER_PATCHED
4407 || updated == SERVER_RCS_DIFF)
4409 /* But if we are joining, we'll need the file when we call
4413 if (CVS_UNLINK (finfo->file) < 0)
4414 error (0, errno, "cannot remove temp file for %s",
4418 else if (scratched_file != NULL && entries_line == NULL)
4420 if (strcmp (scratched_file, finfo->file) != 0)
4422 "CVS server internal error: `%s' vs. `%s' scratched",
4425 free (scratched_file);
4426 scratched_file = NULL;
4428 if (kill_scratched_file)
4429 buf_output0 (protocol, "Removed ");
4431 buf_output0 (protocol, "Remove-entry ");
4432 output_dir (finfo->update_dir, finfo->repository);
4433 buf_output0 (protocol, finfo->file);
4434 buf_output (protocol, "\n", 1);
4435 /* keep the vers structure up to date in case we do a join
4436 * - if there isn't a file, it can't very well have a version number, can it?
4438 * we do it here on the assumption that since we just told the client
4439 * to remove the file/entry, it will, and we want to remember that.
4440 * If it fails, that's the client's problem, not ours
4442 if (vers && vers->vn_user != NULL)
4444 free (vers->vn_user);
4445 vers->vn_user = NULL;
4447 if (vers && vers->ts_user != NULL)
4449 free (vers->ts_user);
4450 vers->ts_user = NULL;
4453 else if (scratched_file == NULL && entries_line == NULL)
4456 * This can happen with death support if we were processing
4457 * a dead file in a checkout.
4462 "CVS server internal error: Register *and* Scratch_Entry.\n");
4463 buf_send_counted (protocol);
4467 /* Return whether we should send patches in RCS format. */
4470 server_use_rcs_diff ()
4472 return supported_response ("Rcs-diff");
4478 server_set_entstat (update_dir, repository)
4479 const char *update_dir;
4480 const char *repository;
4482 static int set_static_supported = -1;
4483 if (set_static_supported == -1)
4484 set_static_supported = supported_response ("Set-static-directory");
4485 if (!set_static_supported) return;
4487 buf_output0 (protocol, "Set-static-directory ");
4488 output_dir (update_dir, repository);
4489 buf_output0 (protocol, "\n");
4490 buf_send_counted (protocol);
4496 server_clear_entstat (update_dir, repository)
4497 const char *update_dir;
4498 const char *repository;
4500 static int clear_static_supported = -1;
4501 if (clear_static_supported == -1)
4502 clear_static_supported = supported_response ("Clear-static-directory");
4503 if (!clear_static_supported) return;
4508 buf_output0 (protocol, "Clear-static-directory ");
4509 output_dir (update_dir, repository);
4510 buf_output0 (protocol, "\n");
4511 buf_send_counted (protocol);
4517 server_set_sticky (update_dir, repository, tag, date, nonbranch)
4518 const char *update_dir;
4519 const char *repository;
4524 static int set_sticky_supported = -1;
4526 assert (update_dir != NULL);
4528 if (set_sticky_supported == -1)
4529 set_sticky_supported = supported_response ("Set-sticky");
4530 if (!set_sticky_supported) return;
4535 if (tag == NULL && date == NULL)
4537 buf_output0 (protocol, "Clear-sticky ");
4538 output_dir (update_dir, repository);
4539 buf_output0 (protocol, "\n");
4543 buf_output0 (protocol, "Set-sticky ");
4544 output_dir (update_dir, repository);
4545 buf_output0 (protocol, "\n");
4549 buf_output0 (protocol, "N");
4551 buf_output0 (protocol, "T");
4552 buf_output0 (protocol, tag);
4556 buf_output0 (protocol, "D");
4557 buf_output0 (protocol, date);
4559 buf_output0 (protocol, "\n");
4561 buf_send_counted (protocol);
4564 struct template_proc_data
4566 const char *update_dir;
4567 const char *repository;
4570 /* Here as a static until we get around to fixing Parse_Info to pass along
4572 static struct template_proc_data *tpd;
4575 template_proc PROTO((const char *repository, const char *template));
4578 template_proc (repository, template)
4579 const char *repository;
4580 const char *template;
4586 struct template_proc_data *data = tpd;
4588 if (!supported_response ("Template"))
4589 /* Might want to warn the user that the rcsinfo feature won't work. */
4591 buf_output0 (protocol, "Template ");
4592 output_dir (data->update_dir, data->repository);
4593 buf_output0 (protocol, "\n");
4595 fp = CVS_FOPEN (template, "rb");
4598 error (0, errno, "Couldn't open rcsinfo template file %s", template);
4601 if (fstat (fileno (fp), &sb) < 0)
4603 error (0, errno, "cannot stat rcsinfo template file %s", template);
4606 sprintf (buf, "%ld\n", (long) sb.st_size);
4607 buf_output0 (protocol, buf);
4610 n = fread (buf, 1, sizeof buf, fp);
4611 buf_output (protocol, buf, n);
4614 error (0, errno, "cannot read rcsinfo template file %s", template);
4619 buf_send_counted (protocol);
4620 if (fclose (fp) < 0)
4621 error (0, errno, "cannot close rcsinfo template file %s", template);
4628 server_template (update_dir, repository)
4629 const char *update_dir;
4630 const char *repository;
4632 struct template_proc_data data;
4633 data.update_dir = update_dir;
4634 data.repository = repository;
4636 (void) Parse_Info (CVSROOTADM_RCSINFO, repository, template_proc, 1);
4642 serve_gzip_contents (arg)
4649 file_gzip_level = level;
4653 serve_gzip_stream (arg)
4661 /* All further communication with the client will be compressed. */
4663 buf_to_net = compress_buffer_initialize (buf_to_net, 0, level,
4664 buf_to_net->memory_error);
4665 buf_from_net = compress_buffer_initialize (buf_from_net, 1, level,
4666 buf_from_net->memory_error);
4669 /* Tell the client about RCS options set in CVSROOT/cvswrappers. */
4671 serve_wrapper_sendme_rcs_options (arg)
4674 /* Actually, this is kind of sdrawkcab-ssa: the client wants
4675 * verbatim lines from a cvswrappers file, but the server has
4676 * already parsed the cvswrappers file into the wrap_list struct.
4677 * Therefore, the server loops over wrap_list, unparsing each
4678 * entry before sending it.
4680 char *wrapper_line = NULL;
4684 for (wrap_unparse_rcs_options (&wrapper_line, 1);
4686 wrap_unparse_rcs_options (&wrapper_line, 0))
4688 buf_output0 (buf_to_net, "Wrapper-rcsOption ");
4689 buf_output0 (buf_to_net, wrapper_line);
4690 buf_output0 (buf_to_net, "\012");;
4691 free (wrapper_line);
4694 buf_output0 (buf_to_net, "ok\012");
4696 /* The client is waiting for us, so we better send the data now. */
4697 buf_flush (buf_to_net, 1);
4706 * Just ignore this command. This is used to support the
4707 * update-patches command, which is not a real command, but a signal
4708 * to the client that update will accept the -u argument.
4713 expand_proc (argc, argv, where, mwhere, mfile, shorten,
4714 local_specified, omodule, msg)
4721 int local_specified;
4726 char *dir = argv[0];
4728 /* If mwhere has been specified, the thing we're expanding is a
4729 module -- just return its name so the client will ask for the
4730 right thing later. If it is an alias or a real directory,
4731 mwhere will not be set, so send out the appropriate
4736 buf_output0 (buf_to_net, "Module-expansion ");
4737 if (server_dir != NULL)
4739 buf_output0 (buf_to_net, server_dir);
4740 buf_output0 (buf_to_net, "/");
4742 buf_output0 (buf_to_net, mwhere);
4745 buf_append_char (buf_to_net, '/');
4746 buf_output0 (buf_to_net, mfile);
4748 buf_append_char (buf_to_net, '\n');
4752 /* We may not need to do this anymore -- check the definition
4753 of aliases before removing */
4756 buf_output0 (buf_to_net, "Module-expansion ");
4757 if (server_dir != NULL)
4759 buf_output0 (buf_to_net, server_dir);
4760 buf_output0 (buf_to_net, "/");
4762 buf_output0 (buf_to_net, dir);
4763 buf_append_char (buf_to_net, '\n');
4767 for (i = 1; i < argc; ++i)
4769 buf_output0 (buf_to_net, "Module-expansion ");
4770 if (server_dir != NULL)
4772 buf_output0 (buf_to_net, server_dir);
4773 buf_output0 (buf_to_net, "/");
4775 buf_output0 (buf_to_net, dir);
4776 buf_append_char (buf_to_net, '/');
4777 buf_output0 (buf_to_net, argv[i]);
4778 buf_append_char (buf_to_net, '\n');
4786 serve_expand_modules (arg)
4794 db = open_module ();
4795 for (i = 1; i < argument_count; i++)
4796 err += do_module (db, argument_vector[i],
4797 CHECKOUT, "Updating", expand_proc,
4802 /* argument_vector[0] is a dummy argument, we don't mess with it. */
4804 for (cp = argument_vector + 1;
4805 cp < argument_vector + argument_count;
4812 /* We will have printed an error message already. */
4813 buf_output0 (buf_to_net, "error \n");
4815 buf_output0 (buf_to_net, "ok\n");
4817 /* The client is waiting for the module expansions, so we must
4818 send the output now. */
4819 buf_flush (buf_to_net, 1);
4824 static void serve_valid_requests PROTO((char *arg));
4826 #endif /* SERVER_SUPPORT */
4827 #if defined(SERVER_SUPPORT) || defined(CLIENT_SUPPORT)
4830 * Parts of this table are shared with the client code,
4831 * but the client doesn't need to know about the handler
4835 struct request requests[] =
4837 #ifdef SERVER_SUPPORT
4838 #define REQ_LINE(n, f, s) {n, f, s}
4840 #define REQ_LINE(n, f, s) {n, s}
4843 REQ_LINE("Root", serve_root, RQ_ESSENTIAL | RQ_ROOTLESS),
4844 REQ_LINE("Valid-responses", serve_valid_responses,
4845 RQ_ESSENTIAL | RQ_ROOTLESS),
4846 REQ_LINE("valid-requests", serve_valid_requests,
4847 RQ_ESSENTIAL | RQ_ROOTLESS),
4848 REQ_LINE("Repository", serve_repository, 0),
4849 REQ_LINE("Directory", serve_directory, RQ_ESSENTIAL),
4850 REQ_LINE("Max-dotdot", serve_max_dotdot, 0),
4851 REQ_LINE("Static-directory", serve_static_directory, 0),
4852 REQ_LINE("Sticky", serve_sticky, 0),
4853 REQ_LINE("Entry", serve_entry, RQ_ESSENTIAL),
4854 REQ_LINE("Kopt", serve_kopt, 0),
4855 REQ_LINE("Checkin-time", serve_checkin_time, 0),
4856 REQ_LINE("Modified", serve_modified, RQ_ESSENTIAL),
4857 REQ_LINE("Is-modified", serve_is_modified, 0),
4858 REQ_LINE("Empty-conflicts", serve_noop, 0),
4860 /* The client must send this request to interoperate with CVS 1.5
4861 through 1.9 servers. The server must support it (although it can
4862 be and is a noop) to interoperate with CVS 1.5 to 1.9 clients. */
4863 REQ_LINE("UseUnchanged", serve_enable_unchanged, RQ_ENABLEME | RQ_ROOTLESS),
4865 REQ_LINE("Unchanged", serve_unchanged, RQ_ESSENTIAL),
4866 REQ_LINE("Notify", serve_notify, 0),
4867 REQ_LINE("Questionable", serve_questionable, 0),
4868 REQ_LINE("Argument", serve_argument, RQ_ESSENTIAL),
4869 REQ_LINE("Argumentx", serve_argumentx, RQ_ESSENTIAL),
4870 REQ_LINE("Global_option", serve_global_option, RQ_ROOTLESS),
4871 REQ_LINE("Gzip-stream", serve_gzip_stream, 0),
4872 REQ_LINE("wrapper-sendme-rcsOptions",
4873 serve_wrapper_sendme_rcs_options,
4875 REQ_LINE("Set", serve_set, RQ_ROOTLESS),
4877 # ifdef HAVE_KERBEROS
4878 REQ_LINE("Kerberos-encrypt", serve_kerberos_encrypt, 0),
4881 REQ_LINE("Gssapi-encrypt", serve_gssapi_encrypt, 0),
4885 REQ_LINE("Gssapi-authenticate", serve_gssapi_authenticate, 0),
4887 REQ_LINE("expand-modules", serve_expand_modules, 0),
4888 REQ_LINE("ci", serve_ci, RQ_ESSENTIAL),
4889 REQ_LINE("co", serve_co, RQ_ESSENTIAL),
4890 REQ_LINE("update", serve_update, RQ_ESSENTIAL),
4891 REQ_LINE("diff", serve_diff, 0),
4892 REQ_LINE("log", serve_log, 0),
4893 REQ_LINE("rlog", serve_rlog, 0),
4894 REQ_LINE("add", serve_add, 0),
4895 REQ_LINE("remove", serve_remove, 0),
4896 REQ_LINE("update-patches", serve_ignore, 0),
4897 REQ_LINE("gzip-file-contents", serve_gzip_contents, 0),
4898 REQ_LINE("status", serve_status, 0),
4899 REQ_LINE("rdiff", serve_rdiff, 0),
4900 REQ_LINE("tag", serve_tag, 0),
4901 REQ_LINE("rtag", serve_rtag, 0),
4902 REQ_LINE("import", serve_import, 0),
4903 REQ_LINE("admin", serve_admin, 0),
4904 REQ_LINE("export", serve_export, 0),
4905 REQ_LINE("history", serve_history, 0),
4906 REQ_LINE("release", serve_release, 0),
4907 REQ_LINE("watch-on", serve_watch_on, 0),
4908 REQ_LINE("watch-off", serve_watch_off, 0),
4909 REQ_LINE("watch-add", serve_watch_add, 0),
4910 REQ_LINE("watch-remove", serve_watch_remove, 0),
4911 REQ_LINE("watchers", serve_watchers, 0),
4912 REQ_LINE("editors", serve_editors, 0),
4913 REQ_LINE("init", serve_init, RQ_ROOTLESS),
4914 REQ_LINE("annotate", serve_annotate, 0),
4915 REQ_LINE("rannotate", serve_rannotate, 0),
4916 REQ_LINE("noop", serve_noop, RQ_ROOTLESS),
4917 REQ_LINE("version", serve_version, RQ_ROOTLESS),
4918 REQ_LINE(NULL, NULL, 0)
4923 #endif /* SERVER_SUPPORT or CLIENT_SUPPORT */
4924 #ifdef SERVER_SUPPORT
4927 serve_valid_requests (arg)
4931 if (print_pending_error ())
4933 buf_output0 (buf_to_net, "Valid-requests");
4934 for (rq = requests; rq->name != NULL; rq++)
4936 if (rq->func != NULL)
4938 buf_append_char (buf_to_net, ' ');
4939 buf_output0 (buf_to_net, rq->name);
4942 buf_output0 (buf_to_net, "\nok\n");
4944 /* The client is waiting for the list of valid requests, so we
4945 must send the output now. */
4946 buf_flush (buf_to_net, 1);
4951 * Delete temporary files. SIG is the signal making this happen, or
4952 * 0 if not called as a result of a signal.
4954 static int command_pid_is_dead;
4955 static void wait_sig (sig)
4959 pid_t r = wait (&status);
4960 if (r == command_pid)
4961 command_pid_is_dead++;
4963 #endif /* SUNOS_KLUDGE */
4966 server_cleanup (sig)
4969 /* Do "rm -rf" on the temp directory. */
4973 if (buf_to_net != NULL)
4975 /* Since we're done, go ahead and put BUF_TO_NET back into blocking
4976 * mode and send any pending output. In the usual case there won't
4977 * won't be any, but there might be if an error occured.
4980 set_block (buf_to_net);
4981 buf_flush (buf_to_net, 1);
4983 /* Next we shut down BUF_FROM_NET. That will pick up the checksum
4984 * generated when the client shuts down its buffer. Then, after we
4985 * have generated any final output, we shut down BUF_TO_NET.
4988 if (buf_from_net != NULL)
4990 status = buf_shutdown (buf_from_net);
4992 error (0, status, "shutting down buffer from client");
4993 buf_free (buf_from_net);
4994 buf_from_net = NULL;
4997 if (dont_delete_temp)
4999 (void) buf_flush (buf_to_net, 1);
5000 (void) buf_shutdown (buf_to_net);
5001 buf_free (buf_to_net);
5003 error_use_protocol = 0;
5007 else if (dont_delete_temp)
5010 /* What a bogus kludge. This disgusting code makes all kinds of
5011 assumptions about SunOS, and is only for a bug in that system.
5012 So only enable it on Suns. */
5014 if (command_pid > 0)
5016 /* To avoid crashes on SunOS due to bugs in SunOS tmpfs
5017 triggered by the use of rename() in RCS, wait for the
5018 subprocess to die. Unfortunately, this means draining output
5019 while waiting for it to unblock the signal we sent it. Yuck! */
5023 signal (SIGCHLD, wait_sig);
5025 /* Perhaps SIGTERM would be more correct. But the child
5026 process will delay the SIGINT delivery until its own
5027 children have exited. */
5028 kill (command_pid, SIGINT);
5029 /* The caller may also have sent a signal to command_pid, so
5030 always try waiting. First, though, check and see if it's still
5033 r = waitpid (command_pid, &status, WNOHANG);
5036 else if (r == command_pid)
5037 command_pid_is_dead++;
5042 command_pid_is_dead++;
5048 /* waitpid should always return one of the above values */
5050 while (!command_pid_is_dead)
5052 struct timeval timeout;
5053 struct fd_set_wrapper readfds;
5057 /* Use a non-zero timeout to avoid eating up CPU cycles. */
5059 timeout.tv_usec = 0;
5060 readfds = command_fds_to_drain;
5061 switch (select (max_command_fd + 1, &readfds.fds,
5062 (fd_set *)0, (fd_set *)0,
5072 for (i = 0; i <= max_command_fd; i++)
5074 if (!FD_ISSET (i, &readfds.fds))
5076 /* this fd is non-blocking */
5077 while (read (i, buf, sizeof (buf)) >= 1)
5086 #endif /* SUNOS_KLUDGE */
5089 /* Temporarily clear noexec, so that we clean up our temp directory
5090 regardless of it (this could more cleanly be handled by moving
5091 the noexec check to all the unlink_file_dir callers from
5092 unlink_file_dir itself). */
5093 save_noexec = noexec;
5095 /* FIXME? Would be nice to not ignore errors. But what should we do?
5096 We could try to do this before we shut down the network connection,
5097 and try to notify the client (but the client might not be waiting
5098 for responses). We could try something like syslog() or our own
5100 unlink_file_dir (orig_server_temp_dir);
5101 noexec = save_noexec;
5103 if (buf_to_net != NULL)
5105 (void) buf_flush (buf_to_net, 1);
5106 (void) buf_shutdown (buf_to_net);
5107 buf_free (buf_to_net);
5109 error_use_protocol = 0;
5118 char *error_prog_name; /* Used in error messages */
5122 static const char *const msg[] =
5125 " Normally invoked by a cvs client on a remote machine.\n",
5130 /* Ignore argc and argv. They might be from .cvsrc. */
5132 buf_to_net = fd_buffer_initialize (STDOUT_FILENO, 0,
5133 outbuf_memory_error);
5134 buf_from_net = stdio_buffer_initialize (stdin, 0, 1, outbuf_memory_error);
5136 saved_output = buf_nonio_initialize (outbuf_memory_error);
5137 saved_outerr = buf_nonio_initialize (outbuf_memory_error);
5139 /* Since we're in the server parent process, error should use the
5140 protocol to report error messages. */
5141 error_use_protocol = 1;
5143 /* OK, now figure out where we stash our temporary files. */
5147 /* The code which wants to chdir into server_temp_dir is not set
5148 up to deal with it being a relative path. So give an error
5150 if (!isabsolute (Tmpdir))
5152 if (alloc_pending (80 + strlen (Tmpdir)))
5153 sprintf (pending_error_text,
5154 "E Value of %s for TMPDIR is not absolute", Tmpdir);
5156 /* FIXME: we would like this error to be persistent, that
5157 is, not cleared by print_pending_error. The current client
5158 will exit as soon as it gets an error, but the protocol spec
5159 does not require a client to do so. */
5166 server_temp_dir = xmalloc (strlen (Tmpdir) + 80);
5167 if (server_temp_dir == NULL)
5170 * Strictly speaking, we're not supposed to output anything
5171 * now. But we're about to exit(), give it a try.
5173 printf ("E Fatal server error, aborting.\n\
5174 error ENOMEM Virtual memory exhausted.\n");
5178 strcpy (server_temp_dir, Tmpdir);
5180 /* Remove a trailing slash from TMPDIR if present. */
5181 p = server_temp_dir + strlen (server_temp_dir) - 1;
5186 * I wanted to use cvs-serv/PID, but then you have to worry about
5187 * the permissions on the cvs-serv directory being right. So
5190 strcat (server_temp_dir, "/cvs-serv");
5192 p = server_temp_dir + strlen (server_temp_dir);
5193 sprintf (p, "%ld", (long) getpid ());
5195 orig_server_temp_dir = server_temp_dir;
5197 /* Create the temporary directory, and set the mode to
5198 700, to discourage random people from tampering with
5200 while ((status = mkdir_p (server_temp_dir)) == EEXIST)
5202 static const char suffix[] = "abcdefghijklmnopqrstuvwxyz";
5204 if (i >= sizeof suffix - 1) break;
5205 if (i == 0) p = server_temp_dir + strlen (server_temp_dir);
5211 if (alloc_pending (80 + strlen (server_temp_dir)))
5212 sprintf (pending_error_text,
5213 "E can't create temporary directory %s",
5215 pending_error = status;
5217 #ifndef CHMOD_BROKEN
5218 else if (chmod (server_temp_dir, S_IRWXU) < 0)
5220 int save_errno = errno;
5221 if (alloc_pending (80 + strlen (server_temp_dir)))
5222 sprintf (pending_error_text,
5223 "E cannot change permissions on temporary directory %s",
5225 pending_error = save_errno;
5228 else if (CVS_CHDIR (server_temp_dir) < 0)
5230 int save_errno = errno;
5231 if (alloc_pending (80 + strlen (server_temp_dir)))
5232 sprintf (pending_error_text,
5233 "E cannot change to temporary directory %s",
5235 pending_error = save_errno;
5240 /* Now initialize our argument vector (for arguments from the client). */
5242 /* Small for testing. */
5243 argument_vector_size = 1;
5244 argument_vector = xmalloc (argument_vector_size * sizeof (char *));
5246 /* This gets printed if the client supports an option which the
5247 server doesn't, causing the server to print a usage message.
5248 FIXME: just a nit, I suppose, but the usage message the server
5249 prints isn't literally true--it suggests "cvs server" followed
5250 by options which are for a particular command. Might be nice to
5251 say something like "client apparently supports an option not supported
5252 by this server" or something like that instead of usage message. */
5253 error_prog_name = xmalloc (strlen (program_name) + 8);
5254 sprintf(error_prog_name, "%s server", program_name);
5255 argument_vector[0] = error_prog_name;
5259 char *cmd, *orig_cmd;
5263 status = buf_read_line (buf_from_net, &cmd, NULL);
5266 buf_output0 (buf_to_net, "E Fatal server error, aborting.\n\
5267 error ENOMEM Virtual memory exhausted.\n");
5274 for (rq = requests; rq->name != NULL; ++rq)
5275 if (strncmp (cmd, rq->name, strlen (rq->name)) == 0)
5277 int len = strlen (rq->name);
5278 if (cmd[len] == '\0')
5280 else if (cmd[len] == ' ')
5284 * The first len characters match, but it's a different
5285 * command. e.g. the command is "cooperate" but we matched
5290 if (!(rq->flags & RQ_ROOTLESS)
5291 && current_parsed_root == NULL)
5293 /* For commands which change the way in which data
5294 is sent and received, for example Gzip-stream,
5295 this does the wrong thing. Since the client
5296 assumes that everything is being compressed,
5297 unconditionally, there is no way to give this
5298 error to the client without turning on
5299 compression. The obvious fix would be to make
5300 Gzip-stream RQ_ROOTLESS (with the corresponding
5301 change to the spec), and that might be a good
5302 idea but then again I can see some settings in
5303 CVSROOT about what compression level to allow.
5304 I suppose a more baroque answer would be to
5305 turn on compression (say, at level 1), just
5306 enough to give the "Root request missing"
5307 error. For now we just lose. */
5308 if (alloc_pending (80))
5309 sprintf (pending_error_text,
5310 "E Protocol error: Root request missing");
5316 if (rq->name == NULL)
5318 if (!print_pending_error ())
5320 buf_output0 (buf_to_net, "error unrecognized request `");
5321 buf_output0 (buf_to_net, cmd);
5322 buf_append_char (buf_to_net, '\'');
5323 buf_append_char (buf_to_net, '\n');
5328 free (error_prog_name);
5330 /* We expect the client is done talking to us at this point. If there is
5331 * any data in the buffer or on the network pipe, then something we didn't
5332 * prepare for is happening.
5334 if (!buf_empty (buf_from_net))
5336 /* Try to send the error message to the client, but also syslog it, in
5337 * case the client isn't listening anymore.
5339 #ifdef HAVE_SYSLOG_H
5340 /* FIXME: Can the IP address of the connecting client be retrieved
5343 syslog (LOG_DAEMON | LOG_ERR, "Dying gasps received from client.");
5345 error (0, 0, "Dying gasps received from client.");
5348 /* This command will actually close the network buffers. */
5355 #if defined (HAVE_KERBEROS) || defined (AUTH_SERVER_SUPPORT) || defined (HAVE_GSSAPI)
5356 static void switch_to_user PROTO((const char *, const char *));
5359 switch_to_user (cvs_username, username)
5360 const char *cvs_username; /* Only used for error messages. */
5361 const char *username;
5365 pw = getpwnam (username);
5368 /* check_password contains a similar check, so this usually won't be
5369 reached unless the CVS user is mapped to an invalid system user. */
5371 printf ("E Fatal error, aborting.\n\
5372 error 0 %s: no such system user\n", username);
5373 /* Don't worry about server_cleanup; server_active isn't set yet. */
5377 if (pw->pw_uid == 0)
5379 #ifdef HAVE_SYSLOG_H
5380 /* FIXME: Can the IP address of the connecting client be retrieved
5383 syslog (LOG_DAEMON | LOG_ALERT,
5384 "attempt to root from account: %s", cvs_username
5387 printf("error 0: root not allowed\n");
5392 if (initgroups (pw->pw_name, pw->pw_gid) < 0
5394 /* At least on the system I tried, initgroups() only works as root.
5395 But we do still want to report ENOMEM and whatever other
5396 errors initgroups() might dish up. */
5401 /* This could be a warning, but I'm not sure I see the point
5402 in doing that instead of an error given that it would happen
5403 on every connection. We could log it somewhere and not tell
5404 the user. But at least for now make it an error. */
5405 printf ("error 0 initgroups failed: %s\n", strerror (errno));
5406 /* Don't worry about server_cleanup; server_active isn't set yet. */
5409 #endif /* HAVE_INITGROUPS */
5411 #ifdef SETXID_SUPPORT
5412 /* honor the setgid bit iff set*/
5413 if (getgid() != getegid())
5415 if (setgid (getegid ()) < 0)
5417 /* See comments at setuid call below for more discussion. */
5418 printf ("error 0 setgid failed: %s\n", strerror (errno));
5419 /* Don't worry about server_cleanup;
5420 server_active isn't set yet. */
5427 if (setgid (pw->pw_gid) < 0)
5429 /* See comments at setuid call below for more discussion. */
5430 printf ("error 0 setgid failed: %s\n", strerror (errno));
5431 #ifdef HAVE_SYSLOG_H
5432 syslog (LOG_DAEMON | LOG_ERR,
5433 "setgid to %d failed (%m): real %d/%d, effective %d/%d ",
5434 pw->pw_gid, getuid(), getgid(), geteuid(), getegid());
5436 /* Don't worry about server_cleanup;
5437 server_active isn't set yet. */
5442 if (setuid (pw->pw_uid) < 0)
5444 /* Note that this means that if run as a non-root user,
5445 CVSROOT/passwd must contain the user we are running as
5446 (e.g. "joe:FsEfVcu:cvs" if run as "cvs" user). This seems
5447 cleaner than ignoring the error like CVS 1.10 and older but
5448 it does mean that some people might need to update their
5449 CVSROOT/passwd file. */
5450 printf ("error 0 setuid failed: %s\n", strerror (errno));
5451 #ifdef HAVE_SYSLOG_H
5452 syslog (LOG_DAEMON | LOG_ERR,
5453 "setuid to %d failed (%m): real %d/%d, effective %d/%d ",
5454 pw->pw_uid, getuid(), getgid(), geteuid(), getegid());
5456 /* Don't worry about server_cleanup; server_active isn't set yet. */
5460 /* We don't want our umask to change file modes. The modes should
5461 be set by the modes used in the repository, and by the umask of
5465 #ifdef AUTH_SERVER_SUPPORT
5466 /* Make sure our CVS_Username has been set. */
5467 if (CVS_Username == NULL)
5468 CVS_Username = xstrdup (username);
5472 /* Set LOGNAME, USER and CVS_USER in the environment, in case they
5473 are already set to something else. */
5477 env = xmalloc (sizeof "LOGNAME=" + strlen (username));
5478 (void) sprintf (env, "LOGNAME=%s", username);
5479 (void) putenv (env);
5481 env = xmalloc (sizeof "USER=" + strlen (username));
5482 (void) sprintf (env, "USER=%s", username);
5483 (void) putenv (env);
5485 #ifdef AUTH_SERVER_SUPPORT
5486 env = xmalloc (sizeof "CVS_USER=" + strlen (CVS_Username));
5487 (void) sprintf (env, "CVS_USER=%s", CVS_Username);
5488 (void) putenv (env);
5491 #endif /* HAVE_PUTENV */
5495 #ifdef AUTH_SERVER_SUPPORT
5497 extern char *crypt PROTO((const char *, const char *));
5501 * 0 means no entry found for this user.
5502 * 1 means entry found and password matches (or found password is empty)
5503 * 2 means entry found, but password does not match.
5505 * If 1, host_user_ptr will be set to point at the system
5506 * username (i.e., the "real" identity, which may or may not be the
5507 * CVS username) of this user; caller may free this. Global
5508 * CVS_Username will point at an allocated copy of cvs username (i.e.,
5509 * the username argument below).
5510 * kff todo: FIXME: last sentence is not true, it applies to caller.
5513 check_repository_password (username, password, repository, host_user_ptr)
5514 char *username, *password, *repository, **host_user_ptr;
5519 char *linebuf = NULL;
5524 /* We don't use current_parsed_root->directory because it hasn't been
5525 * set yet -- our `repository' argument came from the authentication
5526 * protocol, not the regular CVS protocol.
5529 filename = xmalloc (strlen (repository)
5531 + strlen (CVSROOTADM)
5533 + strlen (CVSROOTADM_PASSWD)
5536 (void) sprintf (filename, "%s/%s/%s", repository,
5537 CVSROOTADM, CVSROOTADM_PASSWD);
5539 fp = CVS_FOPEN (filename, "r");
5542 if (!existence_error (errno))
5543 error (0, errno, "cannot open %s", filename);
5548 /* Look for a relevant line -- one with this user's name. */
5549 namelen = strlen (username);
5550 while (getline (&linebuf, &linebuf_len, fp) >= 0)
5552 if ((strncmp (linebuf, username, namelen) == 0)
5553 && (linebuf[namelen] == ':'))
5560 error (0, errno, "cannot read %s", filename);
5561 if (fclose (fp) < 0)
5562 error (0, errno, "cannot close %s", filename);
5564 /* If found_it, then linebuf contains the information we need. */
5567 char *found_password, *host_user_tmp;
5568 char *non_cvsuser_portion;
5570 /* We need to make sure lines such as
5572 * "username::sysuser\n"
5576 * all result in a found_password of NULL, but we also need to
5579 * "username: :sysuser\n"
5580 * "username: <whatever>:sysuser\n"
5582 * continues to result in an impossible password. That way,
5583 * an admin would be on safe ground by going in and tacking a
5584 * space onto the front of a password to disable the account
5585 * (a technique some people use to close accounts
5589 /* Make `non_cvsuser_portion' contain everything after the CVS
5590 username, but null out any final newline. */
5591 non_cvsuser_portion = linebuf + namelen;
5592 strtok (non_cvsuser_portion, "\n");
5594 /* If there's a colon now, we just want to inch past it. */
5595 if (strchr (non_cvsuser_portion, ':') == non_cvsuser_portion)
5596 non_cvsuser_portion++;
5598 /* Okay, after this conditional chain, found_password and
5599 host_user_tmp will have useful values: */
5601 if ((non_cvsuser_portion == NULL)
5602 || (strlen (non_cvsuser_portion) == 0)
5603 || ((strspn (non_cvsuser_portion, " \t"))
5604 == strlen (non_cvsuser_portion)))
5606 found_password = NULL;
5607 host_user_tmp = NULL;
5609 else if (strncmp (non_cvsuser_portion, ":", 1) == 0)
5611 found_password = NULL;
5612 host_user_tmp = non_cvsuser_portion + 1;
5613 if (strlen (host_user_tmp) == 0)
5614 host_user_tmp = NULL;
5618 found_password = strtok (non_cvsuser_portion, ":");
5619 host_user_tmp = strtok (NULL, ":");
5622 /* Of course, maybe there was no system user portion... */
5623 if (host_user_tmp == NULL)
5624 host_user_tmp = username;
5626 /* Verify blank passwords directly, otherwise use crypt(). */
5627 if ((found_password == NULL)
5628 || ((strcmp (found_password, crypt (password, found_password))
5631 /* Give host_user_ptr permanent storage. */
5632 *host_user_ptr = xstrdup (host_user_tmp);
5638 syslog (LOG_AUTHPRIV | LOG_NOTICE,
5639 "password mismatch for %s in %s: %s vs. %s", username,
5640 repository, crypt(password, found_password), found_password);
5642 *host_user_ptr = NULL;
5646 else /* Didn't find this user, so deny access. */
5648 *host_user_ptr = NULL;
5661 /* Return a hosting username if password matches, else NULL. */
5663 check_password (username, password, repository)
5664 char *username, *password, *repository;
5667 char *host_user = NULL;
5668 char *found_passwd = NULL;
5671 /* First we see if this user has a password in the CVS-specific
5672 password file. If so, that's enough to authenticate with. If
5673 not, we'll check /etc/passwd. */
5675 if (require_real_user)
5676 rc = 0; /* "not found" */
5678 rc = check_repository_password (username, password, repository,
5686 /* host_user already set by reference, so just return. */
5694 /* Note that the message _does_ distinguish between the case in
5695 which we check for a system password and the case in which
5696 we do not. It is a real pain to track down why it isn't
5697 letting you in if it won't say why, and I am not convinced
5698 that the potential information disclosure to an attacker
5700 printf ("error 0 no such user %s in CVSROOT/passwd\n", username);
5705 /* No cvs password found, so try /etc/passwd. */
5707 #ifdef HAVE_GETSPNAM
5711 spw = getspnam (username);
5714 found_passwd = spw->sp_pwdp;
5719 if (found_passwd == NULL && (pw = getpwnam (username)) != NULL)
5721 found_passwd = pw->pw_passwd;
5724 if (found_passwd == NULL)
5726 printf ("E Fatal error, aborting.\n\
5727 error 0 %s: no such user\n", username);
5732 /* Allow for dain bramaged HPUX passwd aging
5733 * - Basically, HPUX adds a comma and some data
5734 * about whether the passwd has expired or not
5735 * on the end of the passwd field.
5736 * - This code replaces the ',' with '\0'.
5738 * FIXME - our workaround is brain damaged too. I'm
5739 * guessing that HPUX WANTED other systems to think the
5740 * password was wrong so logins would fail if the
5741 * system didn't handle expired passwds and the passwd
5742 * might be expired. I think the way to go here
5745 strtok (found_passwd, ",");
5749 /* user exists and has a password */
5750 if (strcmp (found_passwd, crypt (password, found_passwd)) == 0)
5752 host_user = xstrdup (username);
5758 syslog (LOG_AUTHPRIV | LOG_NOTICE,
5759 "password mismatch for %s: %s vs. %s", username,
5760 crypt(password, found_passwd), found_passwd);
5766 if (password && *password)
5768 /* user exists and has no system password, but we got
5770 host_user = xstrdup (username);
5774 /* user exists but has no password at all */
5777 syslog (LOG_AUTHPRIV | LOG_NOTICE,
5778 "login refused for %s: user has no password", username);
5784 /* Set CVS_Username here, in allocated space.
5785 It might or might not be the same as host_user. */
5786 CVS_Username = xmalloc (strlen (username) + 1);
5787 strcpy (CVS_Username, username);
5793 #endif /* AUTH_SERVER_SUPPORT */
5795 #if defined (AUTH_SERVER_SUPPORT) || defined (HAVE_GSSAPI)
5797 /* Read username and password from client (i.e., stdin).
5798 If correct, then switch to run as that user and send an ACK to the
5799 client via stdout, else send NACK and die. */
5801 pserver_authenticate_connection ()
5804 size_t tmp_allocated = 0;
5805 #ifdef AUTH_SERVER_SUPPORT
5806 char *repository = NULL;
5807 size_t repository_allocated = 0;
5808 char *username = NULL;
5809 size_t username_allocated = 0;
5810 char *password = NULL;
5811 size_t password_allocated = 0;
5814 char *descrambled_password;
5815 #endif /* AUTH_SERVER_SUPPORT */
5816 int verify_and_exit = 0;
5818 /* The Authentication Protocol. Client sends:
5820 * BEGIN AUTH REQUEST\n
5824 * END AUTH REQUEST\n
5826 * Server uses above information to authenticate, then sends
5830 * if it grants access, else
5834 * if it denies access (and it exits if denying).
5836 * When the client is "cvs login", the user does not desire actual
5837 * repository access, but would like to confirm the password with
5838 * the server. In this case, the start and stop strings are
5840 * BEGIN VERIFICATION REQUEST\n
5844 * END VERIFICATION REQUEST\n
5846 * On a verification request, the server's responses are the same
5847 * (with the obvious semantics), but it exits immediately after
5848 * sending the response in both cases.
5850 * Why is the repository sent? Well, note that the actual
5851 * client/server protocol can't start up until authentication is
5852 * successful. But in order to perform authentication, the server
5853 * needs to look up the password in the special CVS passwd file,
5854 * before trying /etc/passwd. So the client transmits the
5855 * repository as part of the "authentication protocol". The
5856 * repository will be redundantly retransmitted later, but that's no
5861 /* Set SO_KEEPALIVE on the socket, so that we don't hang forever
5862 if the client dies while we are waiting for input. */
5866 if (setsockopt (STDIN_FILENO, SOL_SOCKET, SO_KEEPALIVE,
5867 (char *) &on, sizeof on) < 0)
5869 #ifdef HAVE_SYSLOG_H
5870 syslog (LOG_DAEMON | LOG_ERR, "error setting KEEPALIVE: %m");
5876 /* Make sure the protocol starts off on the right foot... */
5877 if (getline_safe (&tmp, &tmp_allocated, stdin, PATH_MAX) < 0)
5879 #ifdef HAVE_SYSLOG_H
5880 syslog (LOG_DAEMON | LOG_NOTICE, "bad auth protocol start: EOF");
5882 error (1, 0, "bad auth protocol start: EOF");
5885 if (strcmp (tmp, "BEGIN VERIFICATION REQUEST\n") == 0)
5886 verify_and_exit = 1;
5887 else if (strcmp (tmp, "BEGIN AUTH REQUEST\n") == 0)
5889 else if (strcmp (tmp, "BEGIN GSSAPI REQUEST\n") == 0)
5893 gserver_authenticate_connection ();
5896 error (1, 0, "GSSAPI authentication not supported by this server");
5900 error (1, 0, "bad auth protocol start: %s", tmp);
5902 #ifndef AUTH_SERVER_SUPPORT
5904 error (1, 0, "Password authentication not supported by this server");
5906 #else /* AUTH_SERVER_SUPPORT */
5908 /* Get the three important pieces of information in order. */
5909 /* See above comment about error handling. */
5910 getline_safe (&repository, &repository_allocated, stdin, PATH_MAX);
5911 getline_safe (&username, &username_allocated, stdin, PATH_MAX);
5912 getline_safe (&password, &password_allocated, stdin, PATH_MAX);
5916 * We check that none of the lines were truncated by getnline in order
5917 * to be sure that we don't accidentally allow a blind DOS attack to
5918 * authenticate, however slim the odds of that might be.
5920 if (!strip_trailing_newlines (repository)
5921 || !strip_trailing_newlines (username)
5922 || !strip_trailing_newlines (password))
5923 error (1, 0, "Maximum line length exceeded during authentication.");
5925 /* ... and make sure the protocol ends on the right foot. */
5926 /* See above comment about error handling. */
5927 getline_safe (&tmp, &tmp_allocated, stdin, PATH_MAX);
5930 "END VERIFICATION REQUEST\n" : "END AUTH REQUEST\n")
5933 error (1, 0, "bad auth protocol end: %s", tmp);
5935 if (!root_allow_ok (repository))
5937 printf ("error 0 %s: no such repository\n", repository);
5938 #ifdef HAVE_SYSLOG_H
5939 syslog (LOG_DAEMON | LOG_NOTICE, "login refused for %s", repository);
5944 /* OK, now parse the config file, so we can use it to control how
5945 to check passwords. If there was an error parsing the config
5946 file, parse_config already printed an error. We keep going.
5947 Why? Because if we didn't, then there would be no way to check
5948 in a new CVSROOT/config file to fix the broken one! */
5949 parse_config (repository);
5951 /* We need the real cleartext before we hash it. */
5952 descrambled_password = descramble (password);
5953 host_user = check_password (username, descrambled_password, repository);
5954 if (host_user == NULL)
5956 #ifdef HAVE_SYSLOG_H
5957 syslog (LOG_DAEMON | LOG_NOTICE, "login failure (for %s)", repository);
5959 memset (descrambled_password, 0, strlen (descrambled_password));
5960 free (descrambled_password);
5962 printf ("I HATE YOU\n");
5965 /* Don't worry about server_cleanup, server_active isn't set
5969 memset (descrambled_password, 0, strlen (descrambled_password));
5970 free (descrambled_password);
5972 /* Don't go any farther if we're just responding to "cvs login". */
5973 if (verify_and_exit)
5975 printf ("I LOVE YOU\n");
5978 /* It's okay to skip rcs_cleanup() and Lock_Cleanup() here. */
5980 #ifdef SYSTEM_CLEANUP
5981 /* Hook for OS-specific behavior, for example socket subsystems on
5982 NT and OS2 or dealing with windows and arguments on Mac. */
5989 /* Set Pserver_Repos so that we can check later that the same
5990 repository is sent in later client/server protocol. */
5991 Pserver_Repos = xmalloc (strlen (repository) + 1);
5992 strcpy (Pserver_Repos, repository);
5994 /* Switch to run as this user. */
5995 switch_to_user (username, host_user);
6002 printf ("I LOVE YOU\n");
6004 #endif /* AUTH_SERVER_SUPPORT */
6007 #endif /* AUTH_SERVER_SUPPORT || HAVE_GSSAPI */
6010 #ifdef HAVE_KERBEROS
6012 kserver_authenticate_connection ()
6015 char instance[INST_SZ];
6016 struct sockaddr_in peer;
6017 struct sockaddr_in laddr;
6021 char version[KRB_SENDAUTH_VLEN];
6022 char user[ANAME_SZ];
6024 strcpy (instance, "*");
6026 if (getpeername (STDIN_FILENO, (struct sockaddr *) &peer, &len) < 0
6027 || getsockname (STDIN_FILENO, (struct sockaddr *) &laddr,
6030 printf ("E Fatal error, aborting.\n\
6031 error %s getpeername or getsockname failed\n", strerror (errno));
6037 /* Set SO_KEEPALIVE on the socket, so that we don't hang forever
6038 if the client dies while we are waiting for input. */
6042 if (setsockopt (STDIN_FILENO, SOL_SOCKET, SO_KEEPALIVE,
6043 (char *) &on, sizeof on) < 0)
6045 #ifdef HAVE_SYSLOG_H
6046 syslog (LOG_DAEMON | LOG_ERR, "error setting KEEPALIVE: %m");
6052 status = krb_recvauth (KOPT_DO_MUTUAL, STDIN_FILENO, &ticket, "rcmd",
6053 instance, &peer, &laddr, &auth, "", sched,
6055 if (status != KSUCCESS)
6057 printf ("E Fatal error, aborting.\n\
6058 error 0 kerberos: %s\n", krb_get_err_text(status));
6063 memcpy (kblock, auth.session, sizeof (C_Block));
6065 /* Get the local name. */
6066 status = krb_kntoln (&auth, user);
6067 if (status != KSUCCESS)
6069 printf ("E Fatal error, aborting.\n\
6070 error 0 kerberos: can't get local name: %s\n", krb_get_err_text(status));
6075 /* Switch to run as this user. */
6076 switch_to_user ("Kerberos 4", user);
6078 #endif /* HAVE_KERBEROS */
6082 #ifndef MAXHOSTNAMELEN
6083 #define MAXHOSTNAMELEN (256)
6086 /* Authenticate a GSSAPI connection. This is called from
6087 pserver_authenticate_connection, and it handles success and failure
6091 gserver_authenticate_connection ()
6093 char hostname[MAXHOSTNAMELEN];
6095 gss_buffer_desc tok_in, tok_out;
6099 OM_uint32 stat_min, ret;
6100 gss_name_t server_name, client_name;
6101 gss_cred_id_t server_creds;
6105 gethostname (hostname, sizeof hostname);
6106 hp = gethostbyname (hostname);
6108 error (1, 0, "can't get canonical hostname");
6110 sprintf (buf, "cvs@%s", hp->h_name);
6112 tok_in.length = strlen (buf);
6114 if (gss_import_name (&stat_min, &tok_in, GSS_C_NT_HOSTBASED_SERVICE,
6115 &server_name) != GSS_S_COMPLETE)
6116 error (1, 0, "could not import GSSAPI service name %s", buf);
6118 /* Acquire the server credential to verify the client's
6120 if (gss_acquire_cred (&stat_min, server_name, 0, GSS_C_NULL_OID_SET,
6121 GSS_C_ACCEPT, &server_creds,
6122 NULL, NULL) != GSS_S_COMPLETE)
6123 error (1, 0, "could not acquire GSSAPI server credentials");
6125 gss_release_name (&stat_min, &server_name);
6127 /* The client will send us a two byte length followed by that many
6129 if (fread (buf, 1, 2, stdin) != 2)
6130 error (1, errno, "read of length failed");
6132 nbytes = ((buf[0] & 0xff) << 8) | (buf[1] & 0xff);
6133 if (nbytes <= sizeof buf)
6136 credbuflen = sizeof buf;
6140 credbuflen = nbytes;
6141 credbuf = xmalloc (credbuflen);
6144 if (fread (credbuf, 1, nbytes, stdin) != nbytes)
6145 error (1, errno, "read of data failed");
6147 gcontext = GSS_C_NO_CONTEXT;
6148 tok_in.length = nbytes;
6149 tok_in.value = credbuf;
6151 if (gss_accept_sec_context (&stat_min,
6152 &gcontext, /* context_handle */
6153 server_creds, /* verifier_cred_handle */
6154 &tok_in, /* input_token */
6155 NULL, /* channel bindings */
6156 &client_name, /* src_name */
6157 &mechid, /* mech_type */
6158 &tok_out, /* output_token */
6160 NULL, /* ignore time_rec */
6161 NULL) /* ignore del_cred_handle */
6164 error (1, 0, "could not verify credentials");
6167 /* FIXME: Use Kerberos v5 specific code to authenticate to a user.
6168 We could instead use an authentication to access mapping. */
6172 gss_buffer_desc desc;
6174 krb5_init_context (&kc);
6175 if (gss_display_name (&stat_min, client_name, &desc,
6176 &mechid) != GSS_S_COMPLETE
6177 || krb5_parse_name (kc, ((gss_buffer_t) &desc)->value, &p) != 0
6178 || krb5_aname_to_localname (kc, p, sizeof buf, buf) != 0
6179 || krb5_kuserok (kc, p, buf) != TRUE)
6181 error (1, 0, "access denied");
6183 krb5_free_principal (kc, p);
6184 krb5_free_context (kc);
6187 if (tok_out.length != 0)
6191 cbuf[0] = (tok_out.length >> 8) & 0xff;
6192 cbuf[1] = tok_out.length & 0xff;
6193 if (fwrite (cbuf, 1, 2, stdout) != 2
6194 || (fwrite (tok_out.value, 1, tok_out.length, stdout)
6196 error (1, errno, "fwrite failed");
6199 switch_to_user ("GSSAPI", buf);
6204 printf ("I LOVE YOU\n");
6208 #endif /* HAVE_GSSAPI */
6210 #endif /* SERVER_SUPPORT */
6212 #if defined (CLIENT_SUPPORT) || defined (SERVER_SUPPORT)
6214 /* This global variable is non-zero if the user requests encryption on
6215 the command line. */
6218 /* This global variable is non-zero if the users requests stream
6219 authentication on the command line. */
6220 int cvsauthenticate;
6224 /* An buffer interface using GSSAPI. This is built on top of a
6225 packetizing buffer. */
6227 /* This structure is the closure field of the GSSAPI translation
6230 struct cvs_gssapi_wrap_data
6232 /* The GSSAPI context. */
6233 gss_ctx_id_t gcontext;
6236 static int cvs_gssapi_wrap_input PROTO((void *, const char *, char *, int));
6237 static int cvs_gssapi_wrap_output PROTO((void *, const char *, char *, int,
6240 /* Create a GSSAPI wrapping buffer. We use a packetizing buffer with
6241 GSSAPI wrapping routines. */
6244 cvs_gssapi_wrap_buffer_initialize (buf, input, gcontext, memory)
6247 gss_ctx_id_t gcontext;
6248 void (*memory) PROTO((struct buffer *));
6250 struct cvs_gssapi_wrap_data *gd;
6252 gd = (struct cvs_gssapi_wrap_data *) xmalloc (sizeof *gd);
6253 gd->gcontext = gcontext;
6255 return (packetizing_buffer_initialize
6257 input ? cvs_gssapi_wrap_input : NULL,
6258 input ? NULL : cvs_gssapi_wrap_output,
6263 /* Unwrap data using GSSAPI. */
6266 cvs_gssapi_wrap_input (fnclosure, input, output, size)
6272 struct cvs_gssapi_wrap_data *gd =
6273 (struct cvs_gssapi_wrap_data *) fnclosure;
6274 gss_buffer_desc inbuf, outbuf;
6278 inbuf.value = (void *) input;
6279 inbuf.length = size;
6281 if (gss_unwrap (&stat_min, gd->gcontext, &inbuf, &outbuf, &conf, NULL)
6284 error (1, 0, "gss_unwrap failed");
6287 if (outbuf.length > size)
6290 memcpy (output, outbuf.value, outbuf.length);
6292 /* The real packet size is stored in the data, so we don't need to
6293 remember outbuf.length. */
6295 gss_release_buffer (&stat_min, &outbuf);
6300 /* Wrap data using GSSAPI. */
6303 cvs_gssapi_wrap_output (fnclosure, input, output, size, translated)
6310 struct cvs_gssapi_wrap_data *gd =
6311 (struct cvs_gssapi_wrap_data *) fnclosure;
6312 gss_buffer_desc inbuf, outbuf;
6316 inbuf.value = (void *) input;
6317 inbuf.length = size;
6320 conf_req = cvs_gssapi_encrypt;
6325 if (gss_wrap (&stat_min, gd->gcontext, conf_req, GSS_C_QOP_DEFAULT,
6326 &inbuf, &conf, &outbuf) != GSS_S_COMPLETE)
6327 error (1, 0, "gss_wrap failed");
6329 /* The packetizing buffer only permits us to add 100 bytes.
6330 FIXME: I don't know what, if anything, is guaranteed by GSSAPI.
6331 This may need to be increased for a different GSSAPI
6332 implementation, or we may need a different algorithm. */
6333 if (outbuf.length > size + 100)
6336 memcpy (output, outbuf.value, outbuf.length);
6338 *translated = outbuf.length;
6340 gss_release_buffer (&stat_min, &outbuf);
6345 #endif /* HAVE_GSSAPI */
6349 #ifdef HAVE_KERBEROS
6351 /* An encryption interface using Kerberos. This is built on top of a
6352 packetizing buffer. */
6354 /* This structure is the closure field of the Kerberos translation
6357 struct krb_encrypt_data
6359 /* The Kerberos key schedule. */
6361 /* The Kerberos DES block. */
6365 static int krb_encrypt_input PROTO((void *, const char *, char *, int));
6366 static int krb_encrypt_output PROTO((void *, const char *, char *, int,
6369 /* Create a Kerberos encryption buffer. We use a packetizing buffer
6370 with Kerberos encryption translation routines. */
6373 krb_encrypt_buffer_initialize (buf, input, sched, block, memory)
6378 void (*memory) PROTO((struct buffer *));
6380 struct krb_encrypt_data *kd;
6382 kd = (struct krb_encrypt_data *) xmalloc (sizeof *kd);
6383 memcpy (kd->sched, sched, sizeof (Key_schedule));
6384 memcpy (kd->block, block, sizeof (C_Block));
6386 return packetizing_buffer_initialize (buf,
6387 input ? krb_encrypt_input : NULL,
6388 input ? NULL : krb_encrypt_output,
6393 /* Decrypt Kerberos data. */
6396 krb_encrypt_input (fnclosure, input, output, size)
6402 struct krb_encrypt_data *kd = (struct krb_encrypt_data *) fnclosure;
6405 des_cbc_encrypt ((C_Block *) input, (C_Block *) output,
6406 size, kd->sched, &kd->block, 0);
6408 /* SIZE is the size of the buffer, which is set by the encryption
6409 routine. The packetizing buffer will arrange for the first two
6410 bytes in the decrypted buffer to be the real (unaligned)
6411 length. As a safety check, make sure that the length in the
6412 buffer corresponds to SIZE. Note that the length in the buffer
6413 is just the length of the data. We must add 2 to account for
6414 the buffer count itself. */
6415 tcount = ((output[0] & 0xff) << 8) + (output[1] & 0xff);
6416 if (((tcount + 2 + 7) & ~7) != size)
6417 error (1, 0, "Decryption failure");
6422 /* Encrypt Kerberos data. */
6425 krb_encrypt_output (fnclosure, input, output, size, translated)
6432 struct krb_encrypt_data *kd = (struct krb_encrypt_data *) fnclosure;
6435 /* For security against a known plaintext attack, we should
6436 initialize any padding bytes to random values. Instead, we
6437 just pick up whatever is on the stack, which is at least better
6440 /* Align SIZE to an 8 byte boundary. Note that SIZE includes the
6441 two byte buffer count at the start of INPUT which was added by
6442 the packetizing buffer. */
6443 aligned = (size + 7) & ~7;
6445 /* We use des_cbc_encrypt rather than krb_mk_priv because the
6446 latter sticks a timestamp in the block, and krb_rd_priv expects
6447 that timestamp to be within five minutes of the current time.
6448 Given the way the CVS server buffers up data, that can easily
6449 fail over a long network connection. We trust krb_recvauth to
6450 guard against a replay attack. */
6452 des_cbc_encrypt ((C_Block *) input, (C_Block *) output, aligned,
6453 kd->sched, &kd->block, 1);
6455 *translated = aligned;
6460 #endif /* HAVE_KERBEROS */
6461 #endif /* ENCRYPTION */
6462 #endif /* defined (CLIENT_SUPPORT) || defined (SERVER_SUPPORT) */
6464 /* Output LEN bytes at STR. If LEN is zero, then output up to (not including)
6465 the first '\0' byte. */
6468 cvs_output (str, len)
6474 #ifdef SERVER_SUPPORT
6475 if (error_use_protocol && buf_to_net != NULL)
6477 buf_output (saved_output, str, len);
6478 buf_copy_lines (buf_to_net, saved_output, 'M');
6480 else if (server_active && protocol != NULL)
6482 buf_output (saved_output, str, len);
6483 buf_copy_lines (protocol, saved_output, 'M');
6484 buf_send_counted (protocol);
6490 size_t to_write = len;
6491 const char *p = str;
6493 /* Local users that do 'cvs status 2>&1' on a local repository
6494 may see the informational messages out-of-order with the
6495 status messages unless we use the fflush (stderr) here. */
6498 while (to_write > 0)
6500 written = fwrite (p, 1, to_write, stdout);
6504 to_write -= written;
6509 /* Output LEN bytes at STR in binary mode. If LEN is zero, then
6510 output zero bytes. */
6513 cvs_output_binary (str, len)
6517 #ifdef SERVER_SUPPORT
6518 if (error_use_protocol || server_active)
6523 if (error_use_protocol)
6528 if (!supported_response ("Mbinary"))
6531 this client does not support writing binary files to stdout");
6535 buf_output0 (buf, "Mbinary\012");
6536 sprintf (size_text, "%lu\012", (unsigned long) len);
6537 buf_output0 (buf, size_text);
6539 /* Not sure what would be involved in using buf_append_data here
6540 without stepping on the toes of our caller (which is responsible
6541 for the memory allocation of STR). */
6542 buf_output (buf, str, len);
6544 if (!error_use_protocol)
6545 buf_send_counted (protocol);
6551 size_t to_write = len;
6552 const char *p = str;
6553 #ifdef USE_SETMODE_STDOUT
6557 /* Local users that do 'cvs status 2>&1' on a local repository
6558 may see the informational messages out-of-order with the
6559 status messages unless we use the fflush (stderr) here. */
6562 #ifdef USE_SETMODE_STDOUT
6563 /* It is possible that this should be the same ifdef as
6564 USE_SETMODE_BINARY but at least for the moment we keep them
6565 separate. Mostly this is just laziness and/or a question
6566 of what has been tested where. Also there might be an
6567 issue of setmode vs. _setmode. */
6568 /* The Windows doc says to call setmode only right after startup.
6569 I assume that what they are talking about can also be helped
6570 by flushing the stream before changing the mode. */
6572 oldmode = _setmode (_fileno (stdout), OPEN_BINARY);
6574 error (0, errno, "failed to setmode on stdout");
6577 while (to_write > 0)
6579 written = fwrite (p, 1, to_write, stdout);
6583 to_write -= written;
6585 #ifdef USE_SETMODE_STDOUT
6587 if (_setmode (_fileno (stdout), oldmode) != OPEN_BINARY)
6588 error (0, errno, "failed to setmode on stdout");
6595 /* Like CVS_OUTPUT but output is for stderr not stdout. */
6597 cvs_outerr (str, len)
6603 #ifdef SERVER_SUPPORT
6604 if (error_use_protocol)
6606 buf_output (saved_outerr, str, len);
6607 buf_copy_lines (buf_to_net, saved_outerr, 'E');
6609 else if (server_active)
6611 buf_output (saved_outerr, str, len);
6612 buf_copy_lines (protocol, saved_outerr, 'E');
6613 buf_send_counted (protocol);
6619 size_t to_write = len;
6620 const char *p = str;
6622 /* Make sure that output appears in order if stdout and stderr
6623 point to the same place. For the server case this is taken
6624 care of by the fact that saved_outerr always holds less
6628 while (to_write > 0)
6630 written = fwrite (p, 1, to_write, stderr);
6634 to_write -= written;
6641 /* Flush stderr. stderr is normally flushed automatically, of course,
6642 but this function is used to flush information from the server back
6647 #ifdef SERVER_SUPPORT
6648 if (error_use_protocol)
6650 /* skip the actual stderr flush in this case since the parent process
6651 * on the server should only be writing to stdout anyhow
6653 /* Flush what we can to the network, but don't block. */
6654 buf_flush (buf_to_net, 0);
6656 else if (server_active)
6658 /* make sure stderr is flushed before we send the flush count on the
6662 /* Send a special count to tell the parent to flush. */
6663 buf_send_special_count (protocol, -2);
6672 /* Make it possible for the user to see what has been written to
6673 stdout (it is up to the implementation to decide exactly how far it
6674 should go to ensure this). */
6678 #ifdef SERVER_SUPPORT
6679 if (error_use_protocol)
6681 /* Flush what we can to the network, but don't block. */
6682 buf_flush (buf_to_net, 0);
6684 else if (server_active)
6686 /* Just do nothing. This is because the code which
6687 cvs_flushout replaces, setting stdout to line buffering in
6688 main.c, didn't get called in the server child process. But
6689 in the future it is quite plausible that we'll want to make
6690 this case work analogously to cvs_flusherr.
6692 FIXME - DRP - I tried to implement this and triggered the following
6693 error: "Protocol error: uncounted data discarded". I don't need
6694 this feature right now, so I'm not going to bother with it yet.
6696 buf_send_special_count (protocol, -1);
6703 /* Output TEXT, tagging it according to TAG. There are lots more
6704 details about what TAG means in cvsclient.texi but for the simple
6705 case (e.g. non-client/server), TAG is just "newline" to output a
6706 newline (in which case TEXT must be NULL), and any other tag to
6709 Note that there is no way to output either \0 or \n as part of TEXT. */
6712 cvs_output_tagged (tag, text)
6716 if (text != NULL && strchr (text, '\n') != NULL)
6717 /* Uh oh. The protocol has no way to cope with this. For now
6718 we dump core, although that really isn't such a nice
6719 response given that this probably can be caused by newlines
6720 in filenames and other causes other than bugs in CVS. Note
6721 that we don't want to turn this into "MT newline" because
6722 this case is a newline within a tagged item, not a newline
6723 as extraneous sugar for the user. */
6726 /* Start and end tags don't take any text, per cvsclient.texi. */
6727 if (tag[0] == '+' || tag[0] == '-')
6728 assert (text == NULL);
6730 #ifdef SERVER_SUPPORT
6731 if (server_active && supported_response ("MT"))
6735 if (error_use_protocol)
6740 buf_output0 (buf, "MT ");
6741 buf_output0 (buf, tag);
6744 buf_output (buf, " ", 1);
6745 buf_output0 (buf, text);
6747 buf_output (buf, "\n", 1);
6749 if (!error_use_protocol)
6750 buf_send_counted (protocol);
6755 if (strcmp (tag, "newline") == 0)
6756 cvs_output ("\n", 1);
6757 else if (text != NULL)
6758 cvs_output (text, 0);