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 #if defined(SERVER_SUPPORT) || defined(CLIENT_SUPPORT)
25 /* This stuff isn't included solely with SERVER_SUPPORT since some of these
26 * functions (encryption & the like) get compiled with or without server
29 * FIXME - They should be in a different file.
33 /* We use Kerberos 5 routines to map the GSSAPI credential to a user
37 /* We need this to wrap data. */
38 static gss_ctx_id_t gcontext;
40 static void gserver_authenticate_connection PROTO((void));
42 /* Whether we are already wrapping GSSAPI communication. */
43 static int cvs_gssapi_wrapping;
46 /* Whether to encrypt GSSAPI communication. We use a global variable
47 like this because we use the same buffer type (gssapi_wrap) to
48 handle both authentication and encryption, and we don't want
49 multiple instances of that buffer in the communication stream. */
50 int cvs_gssapi_encrypt;
52 # endif /* HAVE_GSSAPI */
53 #endif /* defined(SERVER_SUPPORT) || defined(CLIENT_SUPPORT) */
61 #if defined (AUTH_SERVER_SUPPORT) || defined (HAVE_KERBEROS) || defined (HAVE_GSSAPI)
62 #include <sys/socket.h>
67 # ifndef LOG_DAEMON /* for ancient syslogs */
73 # include <netinet/in.h>
75 # ifndef HAVE_KRB_GET_ERR_TEXT
76 # define krb_get_err_text(status) krb_err_txt[status]
79 /* Information we need if we are going to use Kerberos encryption. */
80 static C_Block kblock;
81 static Key_schedule sched;
89 #define O_NONBLOCK O_NDELAY
92 /* EWOULDBLOCK is not defined by POSIX, but some BSD systems will
93 return it, rather than EAGAIN, for nonblocking writes. */
95 #define blocking_error(err) ((err) == EWOULDBLOCK || (err) == EAGAIN)
97 #define blocking_error(err) ((err) == EAGAIN)
100 /* For initgroups(). */
103 #endif /* HAVE_INITGROUPS */
105 # ifdef AUTH_SERVER_SUPPORT
107 # ifdef HAVE_GETSPNAM
111 /* The cvs username sent by the client, which might or might not be
112 the same as the system username the server eventually switches to
113 run as. CVS_Username gets set iff password authentication is
115 char *CVS_Username = NULL;
117 /* Used to check that same repos is transmitted in pserver auth and in
118 later CVS protocol. Exported because root.c also uses. */
119 static char *Pserver_Repos = NULL;
121 /* Should we check for system usernames/passwords? Can be changed by
125 # endif /* AUTH_SERVER_SUPPORT */
128 /* While processing requests, this buffer accumulates data to be sent to
129 the client, and then once we are in do_cvs_command, we use it
130 for all the data to be sent. */
131 static struct buffer *buf_to_net;
133 /* This buffer is used to read input from the client. */
134 static struct buffer *buf_from_net;
137 * This is where we stash stuff we are going to use. Format string
138 * which expects a single directory within it, starting with a slash.
140 static char *server_temp_dir;
142 /* This is the original value of server_temp_dir, before any possible
143 changes inserted by serve_max_dotdot. */
144 static char *orig_server_temp_dir;
146 /* Nonzero if we should keep the temp directory around after we exit. */
147 static int dont_delete_temp;
149 static void server_write_entries PROTO((void));
151 /* All server communication goes through buffer structures. Most of
152 the buffers are built on top of a file descriptor. This structure
153 is used as the closure field in a buffer. */
157 /* The file descriptor. */
159 /* Nonzero if the file descriptor is in blocking mode. */
163 static struct buffer *fd_buffer_initialize
164 PROTO ((int, int, void (*) (struct buffer *)));
165 static int fd_buffer_input PROTO((void *, char *, int, int, int *));
166 static int fd_buffer_output PROTO((void *, const char *, int, int *));
167 static int fd_buffer_flush PROTO((void *));
168 static int fd_buffer_block PROTO((void *, int));
169 static int fd_buffer_shutdown PROTO((struct buffer *));
171 /* Initialize a buffer built on a file descriptor. FD is the file
172 descriptor. INPUT is nonzero if this is for input, zero if this is
173 for output. MEMORY is the function to call when a memory error
176 static struct buffer *
177 fd_buffer_initialize (fd, input, memory)
180 void (*memory) PROTO((struct buffer *));
184 n = (struct fd_buffer *) xmalloc (sizeof *n);
187 return buf_initialize (input ? fd_buffer_input : NULL,
188 input ? NULL : fd_buffer_output,
189 input ? NULL : fd_buffer_flush,
196 /* The buffer input function for a buffer built on a file descriptor. */
199 fd_buffer_input (closure, data, need, size, got)
206 struct fd_buffer *fd = (struct fd_buffer *) closure;
210 nbytes = read (fd->fd, data, size);
213 /* This case is not efficient. Fortunately, I don't think it
214 ever actually happens. */
215 nbytes = read (fd->fd, data, need == 0 ? 1 : need);
228 /* End of file. This assumes that we are using POSIX or BSD
229 style nonblocking I/O. On System V we will get a zero
230 return if there is no data, even when not at EOF. */
234 /* Some error occurred. */
236 if (blocking_error (errno))
238 /* Everything's fine, we just didn't get any data. */
245 /* The buffer output function for a buffer built on a file descriptor. */
248 fd_buffer_output (closure, data, have, wrote)
254 struct fd_buffer *fd = (struct fd_buffer *) closure;
262 nbytes = write (fd->fd, data, have);
267 && (nbytes == 0 || blocking_error (errno)))
269 /* A nonblocking write failed to write any data. Just
274 /* Some sort of error occurred. */
290 /* The buffer flush function for a buffer built on a file descriptor. */
294 fd_buffer_flush (closure)
297 /* Nothing to do. File descriptors are always flushed. */
301 /* The buffer block function for a buffer built on a file descriptor. */
304 fd_buffer_block (closure, block)
308 struct fd_buffer *fd = (struct fd_buffer *) closure;
311 flags = fcntl (fd->fd, F_GETFL, 0);
316 flags &= ~O_NONBLOCK;
320 if (fcntl (fd->fd, F_SETFL, flags) < 0)
323 fd->blocking = block;
328 /* The buffer shutdown function for a buffer built on a file descriptor. */
331 fd_buffer_shutdown (buf)
339 /* Populate all of the directories between BASE_DIR and its relative
340 subdirectory DIR with CVSADM directories. Return 0 for success or
342 static int create_adm_p PROTO((char *, char *));
345 create_adm_p (base_dir, dir)
349 char *dir_where_cvsadm_lives, *dir_to_register, *p, *tmp;
353 if (strcmp (dir, ".") == 0)
354 return 0; /* nothing to do */
356 /* Allocate some space for our directory-munging string. */
357 p = xmalloc (strlen (dir) + 1);
361 dir_where_cvsadm_lives = xmalloc (strlen (base_dir) + strlen (dir) + 100);
362 if (dir_where_cvsadm_lives == NULL)
365 /* Allocate some space for the temporary string in which we will
366 construct filenames. */
367 tmp = xmalloc (strlen (base_dir) + strlen (dir) + 100);
372 /* We make several passes through this loop. On the first pass,
373 we simply create the CVSADM directory in the deepest directory.
374 For each subsequent pass, we try to remove the last path
375 element from DIR, create the CVSADM directory in the remaining
376 pathname, and register the subdirectory in the newly created
382 strcpy (dir_where_cvsadm_lives, base_dir);
383 strcat (dir_where_cvsadm_lives, "/");
384 strcat (dir_where_cvsadm_lives, p);
385 dir_to_register = NULL;
390 (void) sprintf (tmp, "%s/%s", dir_where_cvsadm_lives, CVSADM);
391 if ((CVS_MKDIR (tmp, 0777) < 0) && (errno != EEXIST))
397 /* Create CVSADM_REP. */
398 (void) sprintf (tmp, "%s/%s", dir_where_cvsadm_lives, CVSADM_REP);
401 /* Use Emptydir as the placeholder until the client sends
402 us the real value. This code is similar to checkout.c
403 (emptydir_name), but the code below returns errors
407 empty = xmalloc (strlen (current_parsed_root->directory)
408 + sizeof (CVSROOTADM)
409 + sizeof (CVSNULLREPOS)
417 /* Create the directory name. */
418 (void) sprintf (empty, "%s/%s/%s", current_parsed_root->directory,
419 CVSROOTADM, CVSNULLREPOS);
421 /* Create the directory if it doesn't exist. */
422 if (! isfile (empty))
425 omask = umask (cvsumask);
426 if (CVS_MKDIR (empty, 0777) < 0)
432 (void) umask (omask);
435 f = CVS_FOPEN (tmp, "w");
442 /* Write the directory name to CVSADM_REP. */
443 if (fprintf (f, "%s\n", empty) < 0)
450 if (fclose (f) == EOF)
457 /* Clean up after ourselves. */
461 /* Create CVSADM_ENT. We open in append mode because we
462 don't want to clobber an existing Entries file. */
463 (void) sprintf (tmp, "%s/%s", dir_where_cvsadm_lives, CVSADM_ENT);
464 f = CVS_FOPEN (tmp, "a");
470 if (fclose (f) == EOF)
476 if (dir_to_register != NULL)
478 /* FIXME: Yes, this results in duplicate entries in the
479 Entries.Log file, but it doesn't currently matter. We
480 might need to change this later on to make sure that we
481 only write one entry. */
483 Subdir_Register ((List *) NULL, dir_where_cvsadm_lives,
490 dir_to_register = strrchr (p, '/');
491 if (dir_to_register == NULL)
494 strcpy (dir_where_cvsadm_lives, base_dir);
499 *dir_to_register = '\0';
501 strcpy (dir_where_cvsadm_lives, base_dir);
502 strcat (dir_where_cvsadm_lives, "/");
503 strcat (dir_where_cvsadm_lives, p);
509 free (dir_where_cvsadm_lives);
515 * Make directory DIR, including all intermediate directories if necessary.
516 * Returns 0 for success or errno code.
518 static int mkdir_p PROTO((char *));
525 char *q = xmalloc (strlen (dir) + 1);
534 * Skip over leading slash if present. We won't bother to try to
540 while (*p != '/' && *p != '\0')
544 strncpy (q, dir, p - dir);
546 if (q[p - dir - 1] != '/' && CVS_MKDIR (q, 0777) < 0)
548 int saved_errno = errno;
550 if (saved_errno != EEXIST
551 && ((saved_errno != EACCES && saved_errno != EROFS)
554 retval = saved_errno;
562 if (CVS_MKDIR (dir, 0777) < 0)
573 * Print the error response for error code STATUS. The caller is
574 * reponsible for making sure we get back to the command loop without
575 * any further output occuring.
576 * Must be called only in contexts where it is OK to send output.
585 buf_output0 (buf_to_net, "error ");
586 msg = strerror (status);
589 sprintf (tmpstr, "unknown error %d", status);
592 buf_output0 (buf_to_net, msg);
593 buf_append_char (buf_to_net, '\n');
595 buf_flush (buf_to_net, 0);
598 static int pending_error;
600 * Malloc'd text for pending error. Each line must start with "E ". The
601 * last line should not end with a newline.
603 static char *pending_error_text;
605 /* If an error is pending, print it and return 1. If not, return 0.
606 Must be called only in contexts where it is OK to send output. */
608 print_pending_error ()
610 if (pending_error_text)
612 buf_output0 (buf_to_net, pending_error_text);
613 buf_append_char (buf_to_net, '\n');
615 print_error (pending_error);
617 buf_output0 (buf_to_net, "error \n");
619 buf_flush (buf_to_net, 0);
622 free (pending_error_text);
623 pending_error_text = NULL;
626 else if (pending_error)
628 print_error (pending_error);
636 /* Is an error pending? */
637 #define error_pending() (pending_error || pending_error_text)
639 static int alloc_pending PROTO ((size_t size));
641 /* Allocate SIZE bytes for pending_error_text and return nonzero
642 if we could do it. */
647 if (error_pending ())
648 /* Probably alloc_pending callers will have already checked for
649 this case. But we might as well handle it if they don't, I
652 pending_error_text = xmalloc (size);
653 if (pending_error_text == NULL)
655 pending_error = ENOMEM;
661 static void serve_is_modified PROTO ((char *));
663 static int supported_response PROTO ((char *));
666 supported_response (name)
671 for (rs = responses; rs->name != NULL; ++rs)
672 if (strcmp (rs->name, name) == 0)
673 return rs->status == rs_supported;
674 error (1, 0, "internal error: testing support for unknown response?");
680 serve_valid_responses (arg)
691 for (rs = responses; rs->name != NULL; ++rs)
693 if (strcmp (rs->name, p) == 0)
696 if (rs->name == NULL)
698 * It is a response we have never heard of (and thus never
699 * will want to use). So don't worry about it.
703 rs->status = rs_supported;
706 for (rs = responses; rs->name != NULL; ++rs)
708 if (rs->status == rs_essential)
710 buf_output0 (buf_to_net, "E response `");
711 buf_output0 (buf_to_net, rs->name);
712 buf_output0 (buf_to_net, "' not supported by client\nerror \n");
714 /* FIXME: This call to buf_flush could conceivably
715 cause deadlock, as noted in server_cleanup. */
716 buf_flush (buf_to_net, 1);
720 else if (rs->status == rs_optional)
721 rs->status = rs_not_supported;
732 if (error_pending()) return;
734 if (!isabsolute (arg))
736 if (alloc_pending (80 + strlen (arg)))
737 sprintf (pending_error_text,
738 "E Root %s must be an absolute pathname", arg);
742 /* Sending "Root" twice is illegal.
744 The other way to handle a duplicate Root requests would be as a
745 request to clear out all state and start over as if it was a
746 new connection. Doing this would cause interoperability
747 headaches, so it should be a different request, if there is
748 any reason why such a feature is needed. */
749 if (current_parsed_root != NULL)
751 if (alloc_pending (80 + strlen (arg)))
752 sprintf (pending_error_text,
753 "E Protocol error: Duplicate Root request, for %s", arg);
757 #ifdef AUTH_SERVER_SUPPORT
758 if (Pserver_Repos != NULL)
760 if (strcmp (Pserver_Repos, arg) != 0)
762 if (alloc_pending (80 + strlen (Pserver_Repos) + strlen (arg)))
763 /* The explicitness is to aid people who are writing clients.
764 I don't see how this information could help an
766 sprintf (pending_error_text, "\
767 E Protocol error: Root says \"%s\" but pserver says \"%s\"",
774 current_parsed_root = local_cvsroot (arg);
776 /* For pserver, this will already have happened, and the call will do
777 nothing. But for rsh, we need to do it now. */
778 parse_config (current_parsed_root->directory);
780 /* Now is a good time to read CVSROOT/options too. */
781 parseopts(current_parsed_root->directory);
783 path = xmalloc (strlen (current_parsed_root->directory)
784 + sizeof (CVSROOTADM)
788 pending_error = ENOMEM;
791 (void) sprintf (path, "%s/%s", current_parsed_root->directory, CVSROOTADM);
792 if (!isaccessible (path, R_OK | X_OK))
794 int save_errno = errno;
795 if (alloc_pending (80 + strlen (path)))
796 sprintf (pending_error_text, "E Cannot access %s", path);
797 pending_error = save_errno;
802 env = xmalloc (strlen (CVSROOT_ENV) + strlen (current_parsed_root->directory) + 2);
805 pending_error = ENOMEM;
808 (void) sprintf (env, "%s=%s", CVSROOT_ENV, current_parsed_root->directory);
810 /* do not free env, as putenv has control of it */
814 static int max_dotdot_limit = 0;
816 /* Is this pathname OK to recurse into when we are running as the server?
817 If not, call error() with a fatal error. */
819 server_pathname_check (path)
822 /* An absolute pathname is almost surely a path on the *client* machine,
823 and is unlikely to do us any good here. It also is probably capable
824 of being a security hole in the anonymous readonly case. */
825 if (isabsolute (path))
826 /* Giving an error is actually kind of a cop-out, in the sense
827 that it would be nice for "cvs co -d /foo/bar/baz" to work.
828 A quick fix in the server would be requiring Max-dotdot of
829 at least one if pathnames are absolute, and then putting
830 /abs/foo/bar/baz in the temp dir beside the /d/d/d stuff.
831 A cleaner fix in the server might be to decouple the
832 pathnames we pass back to the client from pathnames in our
833 temp directory (this would also probably remove the need
834 for Max-dotdot). A fix in the client would have the client
835 turn it into "cd /foo/bar; cvs co -d baz" (more or less).
836 This probably has some problems with pathnames which appear
838 error (1, 0, "absolute pathname `%s' illegal for server", path);
839 if (pathname_levels (path) > max_dotdot_limit)
841 /* Similar to the isabsolute case in security implications. */
842 error (0, 0, "protocol error: `%s' contains more leading ..", path);
843 error (1, 0, "than the %d which Max-dotdot specified",
848 static int outside_root PROTO ((char *));
850 /* Is file or directory REPOS an absolute pathname within the
851 current_parsed_root->directory? If yes, return 0. If no, set pending_error
857 size_t repos_len = strlen (repos);
858 size_t root_len = strlen (current_parsed_root->directory);
860 /* isabsolute (repos) should always be true, but
861 this is a good security precaution regardless. -DRP
863 if (!isabsolute (repos))
865 if (alloc_pending (repos_len + 80))
866 sprintf (pending_error_text, "\
867 E protocol error: %s is not absolute", repos);
871 if (repos_len < root_len
872 || strncmp (current_parsed_root->directory, repos, root_len) != 0)
875 if (alloc_pending (strlen (current_parsed_root->directory)
878 sprintf (pending_error_text, "\
879 E protocol error: directory '%s' not within root '%s'",
880 repos, current_parsed_root->directory);
883 if (repos_len > root_len)
885 if (repos[root_len] != '/')
887 if (pathname_levels (repos + root_len + 1) > 0)
893 static int outside_dir PROTO ((char *));
895 /* Is file or directory FILE outside the current directory (that is, does
896 it contain '/')? If no, return 0. If yes, set pending_error
902 if (strchr (file, '/') != NULL)
904 if (alloc_pending (strlen (file)
906 sprintf (pending_error_text, "\
907 E protocol error: directory '%s' not within current directory",
915 * Add as many directories to the temp directory as the client tells us it
916 * will use "..", so we never try to access something outside the temp
917 * directory via "..".
920 serve_max_dotdot (arg)
923 int lim = atoi (arg);
927 if (lim < 0 || lim > 10000)
929 p = xmalloc (strlen (server_temp_dir) + 2 * lim + 10);
932 pending_error = ENOMEM;
935 strcpy (p, server_temp_dir);
936 for (i = 0; i < lim; ++i)
938 if (server_temp_dir != orig_server_temp_dir)
939 free (server_temp_dir);
941 max_dotdot_limit = lim;
944 static char *dir_name;
947 dirswitch (dir, repos)
955 server_write_entries ();
957 if (error_pending()) return;
959 /* Check for bad directory name.
961 FIXME: could/should unify these checks with server_pathname_check
962 except they need to report errors differently. */
963 if (isabsolute (dir))
965 if (alloc_pending (80 + strlen (dir)))
966 sprintf (pending_error_text,
967 "E absolute pathname `%s' illegal for server", dir);
970 if (pathname_levels (dir) > max_dotdot_limit)
972 if (alloc_pending (80 + strlen (dir)))
973 sprintf (pending_error_text,
974 "E protocol error: `%s' has too many ..", dir);
978 dir_len = strlen (dir);
980 /* Check for a trailing '/'. This is not ISDIRSEP because \ in the
981 protocol is an ordinary character, not a directory separator (of
982 course, it is perhaps unwise to use it in directory names, but that
983 is another issue). */
985 && dir[dir_len - 1] == '/')
987 if (alloc_pending (80 + dir_len))
988 sprintf (pending_error_text,
989 "E protocol error: invalid directory syntax in %s", dir);
993 if (dir_name != NULL)
996 dir_name = xmalloc (strlen (server_temp_dir) + dir_len + 40);
997 if (dir_name == NULL)
999 pending_error = ENOMEM;
1003 strcpy (dir_name, server_temp_dir);
1004 strcat (dir_name, "/");
1005 strcat (dir_name, dir);
1007 status = mkdir_p (dir_name);
1009 && status != EEXIST)
1011 if (alloc_pending (80 + strlen (dir_name)))
1012 sprintf (pending_error_text, "E cannot mkdir %s", dir_name);
1013 pending_error = status;
1017 /* We need to create adm directories in all path elements because
1018 we want the server to descend them, even if the client hasn't
1019 sent the appropriate "Argument xxx" command to match the
1020 already-sent "Directory xxx" command. See recurse.c
1021 (start_recursion) for a big discussion of this. */
1023 status = create_adm_p (server_temp_dir, dir);
1026 if (alloc_pending (80 + strlen (dir_name)))
1027 sprintf (pending_error_text, "E cannot create_adm_p %s", dir_name);
1028 pending_error = status;
1032 if ( CVS_CHDIR (dir_name) < 0)
1034 int save_errno = errno;
1035 if (alloc_pending (80 + strlen (dir_name)))
1036 sprintf (pending_error_text, "E cannot change to %s", dir_name);
1037 pending_error = save_errno;
1041 * This is pretty much like calling Create_Admin, but Create_Admin doesn't
1042 * report errors in the right way for us.
1044 if ((CVS_MKDIR (CVSADM, 0777) < 0) && (errno != EEXIST))
1046 int save_errno = errno;
1047 if (alloc_pending (80 + strlen (dir_name) + strlen (CVSADM)))
1048 sprintf (pending_error_text,
1049 "E cannot mkdir %s/%s", dir_name, CVSADM);
1050 pending_error = save_errno;
1054 /* The following will overwrite the contents of CVSADM_REP. This
1055 is the correct behavior -- mkdir_p may have written a
1056 placeholder value to this file and we need to insert the
1059 f = CVS_FOPEN (CVSADM_REP, "w");
1062 int save_errno = errno;
1063 if (alloc_pending (80 + strlen (dir_name) + strlen (CVSADM_REP)))
1064 sprintf (pending_error_text,
1065 "E cannot open %s/%s", dir_name, CVSADM_REP);
1066 pending_error = save_errno;
1069 if (fprintf (f, "%s", repos) < 0)
1071 int save_errno = errno;
1072 if (alloc_pending (80 + strlen (dir_name) + strlen (CVSADM_REP)))
1073 sprintf (pending_error_text,
1074 "E error writing %s/%s", dir_name, CVSADM_REP);
1075 pending_error = save_errno;
1079 /* Non-remote CVS handles a module representing the entire tree
1080 (e.g., an entry like ``world -a .'') by putting /. at the end
1081 of the Repository file, so we do the same. */
1082 if (strcmp (dir, ".") == 0
1083 && current_parsed_root != NULL
1084 && current_parsed_root->directory != NULL
1085 && strcmp (current_parsed_root->directory, repos) == 0)
1087 if (fprintf (f, "/.") < 0)
1089 int save_errno = errno;
1090 if (alloc_pending (80 + strlen (dir_name) + strlen (CVSADM_REP)))
1091 sprintf (pending_error_text,
1092 "E error writing %s/%s", dir_name, CVSADM_REP);
1093 pending_error = save_errno;
1098 if (fprintf (f, "\n") < 0)
1100 int save_errno = errno;
1101 if (alloc_pending (80 + strlen (dir_name) + strlen (CVSADM_REP)))
1102 sprintf (pending_error_text,
1103 "E error writing %s/%s", dir_name, CVSADM_REP);
1104 pending_error = save_errno;
1108 if (fclose (f) == EOF)
1110 int save_errno = errno;
1111 if (alloc_pending (80 + strlen (dir_name) + strlen (CVSADM_REP)))
1112 sprintf (pending_error_text,
1113 "E error closing %s/%s", dir_name, CVSADM_REP);
1114 pending_error = save_errno;
1117 /* We open in append mode because we don't want to clobber an
1118 existing Entries file. */
1119 f = CVS_FOPEN (CVSADM_ENT, "a");
1122 int save_errno = errno;
1123 if (alloc_pending (80 + strlen (CVSADM_ENT)))
1124 sprintf (pending_error_text, "E cannot open %s", CVSADM_ENT);
1125 pending_error = save_errno;
1128 if (fclose (f) == EOF)
1130 int save_errno = errno;
1131 if (alloc_pending (80 + strlen (CVSADM_ENT)))
1132 sprintf (pending_error_text, "E cannot close %s", CVSADM_ENT);
1133 pending_error = save_errno;
1139 serve_repository (arg)
1142 if (alloc_pending (80))
1143 strcpy (pending_error_text,
1144 "E Repository request is obsolete; aborted");
1149 serve_directory (arg)
1155 status = buf_read_line (buf_from_net, &repos, (int *) NULL);
1158 if (!outside_root (repos))
1159 dirswitch (arg, repos);
1162 else if (status == -2)
1164 pending_error = ENOMEM;
1168 pending_error_text = xmalloc (80 + strlen (arg));
1169 if (pending_error_text == NULL)
1171 pending_error = ENOMEM;
1173 else if (status == -1)
1175 sprintf (pending_error_text,
1176 "E end of file reading mode for %s", arg);
1180 sprintf (pending_error_text,
1181 "E error reading mode for %s", arg);
1182 pending_error = status;
1188 serve_static_directory (arg)
1193 if (error_pending ()) return;
1195 f = CVS_FOPEN (CVSADM_ENTSTAT, "w+");
1198 int save_errno = errno;
1199 if (alloc_pending (80 + strlen (CVSADM_ENTSTAT)))
1200 sprintf (pending_error_text, "E cannot open %s", CVSADM_ENTSTAT);
1201 pending_error = save_errno;
1204 if (fclose (f) == EOF)
1206 int save_errno = errno;
1207 if (alloc_pending (80 + strlen (CVSADM_ENTSTAT)))
1208 sprintf (pending_error_text, "E cannot close %s", CVSADM_ENTSTAT);
1209 pending_error = save_errno;
1220 if (error_pending ()) return;
1222 f = CVS_FOPEN (CVSADM_TAG, "w+");
1225 int save_errno = errno;
1226 if (alloc_pending (80 + strlen (CVSADM_TAG)))
1227 sprintf (pending_error_text, "E cannot open %s", CVSADM_TAG);
1228 pending_error = save_errno;
1231 if (fprintf (f, "%s\n", arg) < 0)
1233 int save_errno = errno;
1234 if (alloc_pending (80 + strlen (CVSADM_TAG)))
1235 sprintf (pending_error_text, "E cannot write to %s", CVSADM_TAG);
1236 pending_error = save_errno;
1239 if (fclose (f) == EOF)
1241 int save_errno = errno;
1242 if (alloc_pending (80 + strlen (CVSADM_TAG)))
1243 sprintf (pending_error_text, "E cannot close %s", CVSADM_TAG);
1244 pending_error = save_errno;
1250 * Read SIZE bytes from buf_from_net, write them to FILE.
1252 * Currently this isn't really used for receiving parts of a file --
1253 * the file is still sent over in one chunk. But if/when we get
1254 * spiffy in-process gzip support working, perhaps the compressed
1255 * pieces could be sent over as they're ready, if the network is fast
1256 * enough. Or something.
1259 receive_partial_file (size, file)
1268 status = buf_read_data (buf_from_net, size, &data, &nread);
1272 pending_error = ENOMEM;
1275 pending_error_text = xmalloc (80);
1276 if (pending_error_text == NULL)
1277 pending_error = ENOMEM;
1278 else if (status == -1)
1280 sprintf (pending_error_text,
1281 "E premature end of file from client");
1286 sprintf (pending_error_text,
1287 "E error reading from client");
1288 pending_error = status;
1300 nwrote = write (file, data, nread);
1303 int save_errno = errno;
1304 if (alloc_pending (40))
1305 strcpy (pending_error_text, "E unable to write");
1306 pending_error = save_errno;
1308 /* Read and discard the file data. */
1314 status = buf_read_data (buf_from_net, size, &data, &nread);
1328 /* Receive SIZE bytes, write to filename FILE. */
1330 receive_file (size, file, gzipped)
1338 /* Write the file. */
1339 fd = CVS_OPEN (arg, O_WRONLY | O_CREAT | O_TRUNC, 0600);
1342 int save_errno = errno;
1343 if (alloc_pending (40 + strlen (arg)))
1344 sprintf (pending_error_text, "E cannot open %s", arg);
1345 pending_error = save_errno;
1351 /* Using gunzip_and_write isn't really a high-performance
1352 approach, because it keeps the whole thing in memory
1353 (contiguous memory, worse yet). But it seems easier to
1354 code than the alternative (and less vulnerable to subtle
1355 bugs). Given that this feature is mainly for
1356 compatibility, that is the better tradeoff. */
1362 filebuf = xmalloc (size);
1364 /* If NULL, we still want to read the data and discard it. */
1371 status = buf_read_data (buf_from_net, toread, &data, &nread);
1375 pending_error = ENOMEM;
1378 pending_error_text = xmalloc (80);
1379 if (pending_error_text == NULL)
1380 pending_error = ENOMEM;
1381 else if (status == -1)
1383 sprintf (pending_error_text,
1384 "E premature end of file from client");
1389 sprintf (pending_error_text,
1390 "E error reading from client");
1391 pending_error = status;
1399 if (filebuf != NULL)
1401 memcpy (p, data, nread);
1405 if (filebuf == NULL)
1407 pending_error = ENOMEM;
1411 if (gunzip_and_write (fd, file, (unsigned char *) filebuf, size))
1413 if (alloc_pending (80))
1414 sprintf (pending_error_text,
1415 "E aborting due to compression error");
1420 receive_partial_file (size, fd);
1422 if (pending_error_text)
1424 char *p = xrealloc (pending_error_text,
1425 strlen (pending_error_text) + strlen (arg) + 30);
1428 pending_error_text = p;
1429 sprintf (p + strlen (p), ", file %s", arg);
1431 /* else original string is supposed to be unchanged */
1435 if (close (fd) < 0 && !error_pending ())
1437 int save_errno = errno;
1438 if (alloc_pending (40 + strlen (arg)))
1439 sprintf (pending_error_text, "E cannot close %s", arg);
1440 pending_error = save_errno;
1445 /* Kopt for the next file sent in Modified or Is-modified. */
1448 /* Timestamp (Checkin-time) for next file sent in Modified or
1450 static int checkin_time_valid;
1451 static time_t checkin_time;
1453 static void serve_modified PROTO ((char *));
1456 serve_modified (arg)
1466 * This used to return immediately if error_pending () was true.
1467 * However, that fails, because it causes each line of the file to
1468 * be echoed back to the client as an unrecognized command. The
1469 * client isn't reading from the socket, so eventually both
1470 * processes block trying to write to the other. Now, we try to
1471 * read the file if we can.
1474 status = buf_read_line (buf_from_net, &mode_text, (int *) NULL);
1478 pending_error = ENOMEM;
1481 pending_error_text = xmalloc (80 + strlen (arg));
1482 if (pending_error_text == NULL)
1483 pending_error = ENOMEM;
1487 sprintf (pending_error_text,
1488 "E end of file reading mode for %s", arg);
1491 sprintf (pending_error_text,
1492 "E error reading mode for %s", arg);
1493 pending_error = status;
1500 status = buf_read_line (buf_from_net, &size_text, (int *) NULL);
1504 pending_error = ENOMEM;
1507 pending_error_text = xmalloc (80 + strlen (arg));
1508 if (pending_error_text == NULL)
1509 pending_error = ENOMEM;
1513 sprintf (pending_error_text,
1514 "E end of file reading size for %s", arg);
1517 sprintf (pending_error_text,
1518 "E error reading size for %s", arg);
1519 pending_error = status;
1526 if (size_text[0] == 'z')
1529 size = atoi (size_text + 1);
1532 size = atoi (size_text);
1535 if (error_pending ())
1537 /* Now that we know the size, read and discard the file data. */
1543 status = buf_read_data (buf_from_net, size, &data, &nread);
1552 if (outside_dir (arg))
1560 receive_file (size, arg, gzipped);
1561 if (error_pending ())
1568 if (checkin_time_valid)
1572 memset (&t, 0, sizeof (t));
1573 t.modtime = t.actime = checkin_time;
1574 if (utime (arg, &t) < 0)
1576 int save_errno = errno;
1577 if (alloc_pending (80 + strlen (arg)))
1578 sprintf (pending_error_text, "E cannot utime %s", arg);
1579 pending_error = save_errno;
1583 checkin_time_valid = 0;
1587 int status = change_mode (arg, mode_text, 0);
1591 if (alloc_pending (40 + strlen (arg)))
1592 sprintf (pending_error_text,
1593 "E cannot change mode for %s", arg);
1594 pending_error = status;
1599 /* Make sure that the Entries indicate the right kopt. We probably
1600 could do this even in the non-kopt case and, I think, save a stat()
1601 call in time_stamp_server. But for conservatism I'm leaving the
1602 non-kopt case alone. */
1604 serve_is_modified (arg);
1609 serve_enable_unchanged (arg)
1615 struct an_entry *next;
1619 static struct an_entry *entries;
1621 static void serve_unchanged PROTO ((char *));
1624 serve_unchanged (arg)
1632 if (error_pending ()) return;
1634 if (outside_dir (arg))
1637 /* Rewrite entries file to have `=' in timestamp field. */
1638 for (p = entries; p != NULL; p = p->next)
1640 name = p->entry + 1;
1641 cp = strchr (name, '/');
1643 && strlen (arg) == cp - name
1644 && strncmp (arg, name, cp - name) == 0)
1646 if (!(timefield = strchr (cp + 1, '/')) || *++timefield == '\0')
1648 /* We didn't find the record separator or it is followed by
1649 * the end of the string, so just exit.
1651 if (alloc_pending (80))
1652 sprintf (pending_error_text,
1653 "E Malformed Entry encountered.");
1656 /* If the time field is not currently empty, then one of
1657 * serve_modified, serve_is_modified, & serve_unchanged were
1658 * already called for this file. We would like to ignore the
1659 * reinvocation silently or, better yet, exit with an error
1660 * message, but we just avoid the copy-forward and overwrite the
1661 * value from the last invocation instead. See the comment below
1664 if (*timefield == '/')
1666 /* Copy forward one character. Space was allocated for this
1667 * already in serve_entry(). */
1668 cp = timefield + strlen (timefield);
1670 while (cp > timefield)
1676 /* If *TIMEFIELD wasn't "/", we assume that it was because of
1677 * multiple calls to Is-Modified & Unchanged by the client and
1678 * just overwrite the value from the last call. Technically, we
1679 * should probably either ignore calls after the first or send the
1680 * client an error, since the client/server protocol specification
1681 * specifies that only one call to either Is-Modified or Unchanged
1682 * is allowed, but broken versions of WinCVS & TortoiseCVS rely on
1692 serve_is_modified (arg)
1699 /* Have we found this file in "entries" yet. */
1702 if (error_pending ()) return;
1704 if (outside_dir (arg))
1707 /* Rewrite entries file to have `M' in timestamp field. */
1709 for (p = entries; p != NULL; p = p->next)
1711 name = p->entry + 1;
1712 cp = strchr (name, '/');
1714 && strlen (arg) == cp - name
1715 && strncmp (arg, name, cp - name) == 0)
1717 if (!(timefield = strchr (cp + 1, '/')) || *++timefield == '\0')
1719 /* We didn't find the record separator or it is followed by
1720 * the end of the string, so just exit.
1722 if (alloc_pending (80))
1723 sprintf (pending_error_text,
1724 "E Malformed Entry encountered.");
1727 /* If the time field is not currently empty, then one of
1728 * serve_modified, serve_is_modified, & serve_unchanged were
1729 * already called for this file. We would like to ignore the
1730 * reinvocation silently or, better yet, exit with an error
1731 * message, but we just avoid the copy-forward and overwrite the
1732 * value from the last invocation instead. See the comment below
1735 if (*timefield == '/')
1737 /* Copy forward one character. Space was allocated for this
1738 * already in serve_entry(). */
1739 cp = timefield + strlen (timefield);
1741 while (cp > timefield)
1747 /* If *TIMEFIELD wasn't "/", we assume that it was because of
1748 * multiple calls to Is-Modified & Unchanged by the client and
1749 * just overwrite the value from the last call. Technically, we
1750 * should probably either ignore calls after the first or send the
1751 * client an error, since the client/server protocol specification
1752 * specifies that only one call to either Is-Modified or Unchanged
1753 * is allowed, but broken versions of WinCVS & TortoiseCVS rely on
1759 if (alloc_pending (strlen (name) + 80))
1760 sprintf (pending_error_text,
1761 "E protocol error: both Kopt and Entry for %s",
1773 /* We got Is-modified but no Entry. Add a dummy entry.
1774 The "D" timestamp is what makes it a dummy. */
1775 p = (struct an_entry *) xmalloc (sizeof (struct an_entry));
1778 pending_error = ENOMEM;
1781 p->entry = xmalloc (strlen (arg) + 80);
1782 if (p->entry == NULL)
1784 pending_error = ENOMEM;
1788 strcpy (p->entry, "/");
1789 strcat (p->entry, arg);
1790 strcat (p->entry, "//D/");
1793 strcat (p->entry, kopt);
1797 strcat (p->entry, "/");
1803 static void serve_entry PROTO ((char *));
1812 if (error_pending()) return;
1814 /* Verify that the entry is well-formed. This can avoid problems later.
1815 * At the moment we only check that the Entry contains five slashes in
1816 * approximately the correct locations since some of the code makes
1817 * assumptions about this.
1820 if (*cp == 'D') cp++;
1823 if (!cp || *cp != '/')
1825 if (alloc_pending (80))
1826 sprintf (pending_error_text,
1827 "E protocol error: Malformed Entry");
1830 cp = strchr (cp + 1, '/');
1833 p = xmalloc (sizeof (struct an_entry));
1836 pending_error = ENOMEM;
1839 /* Leave space for serve_unchanged to write '=' if it wants. */
1840 cp = xmalloc (strlen (arg) + 2);
1843 pending_error = ENOMEM;
1852 static void serve_kopt PROTO ((char *));
1858 if (error_pending ())
1863 if (alloc_pending (80 + strlen (arg)))
1864 sprintf (pending_error_text,
1865 "E protocol error: duplicate Kopt request: %s", arg);
1869 /* Do some sanity checks. In particular, that it is not too long.
1870 This lets the rest of the code not worry so much about buffer
1871 overrun attacks. Probably should call RCS_check_kflag here,
1872 but that would mean changing RCS_check_kflag to handle errors
1873 other than via exit(), fprintf(), and such. */
1874 if (strlen (arg) > 10)
1876 if (alloc_pending (80 + strlen (arg)))
1877 sprintf (pending_error_text,
1878 "E protocol error: invalid Kopt request: %s", arg);
1882 kopt = xmalloc (strlen (arg) + 1);
1885 pending_error = ENOMEM;
1891 static void serve_checkin_time PROTO ((char *));
1894 serve_checkin_time (arg)
1897 if (error_pending ())
1900 if (checkin_time_valid)
1902 if (alloc_pending (80 + strlen (arg)))
1903 sprintf (pending_error_text,
1904 "E protocol error: duplicate Checkin-time request: %s",
1909 checkin_time = get_date (arg, NULL);
1910 if (checkin_time == (time_t)-1)
1912 if (alloc_pending (80 + strlen (arg)))
1913 sprintf (pending_error_text, "E cannot parse date %s", arg);
1916 checkin_time_valid = 1;
1920 server_write_entries ()
1926 if (entries == NULL)
1930 /* Note that we free all the entries regardless of errors. */
1931 if (!error_pending ())
1933 /* We open in append mode because we don't want to clobber an
1934 existing Entries file. If we are checking out a module
1935 which explicitly lists more than one file in a particular
1936 directory, then we will wind up calling
1937 server_write_entries for each such file. */
1938 f = CVS_FOPEN (CVSADM_ENT, "a");
1941 int save_errno = errno;
1942 if (alloc_pending (80 + strlen (CVSADM_ENT)))
1943 sprintf (pending_error_text, "E cannot open %s", CVSADM_ENT);
1944 pending_error = save_errno;
1947 for (p = entries; p != NULL;)
1949 if (!error_pending ())
1951 if (fprintf (f, "%s\n", p->entry) < 0)
1953 int save_errno = errno;
1954 if (alloc_pending (80 + strlen(CVSADM_ENT)))
1955 sprintf (pending_error_text,
1956 "E cannot write to %s", CVSADM_ENT);
1957 pending_error = save_errno;
1966 if (f != NULL && fclose (f) == EOF && !error_pending ())
1968 int save_errno = errno;
1969 if (alloc_pending (80 + strlen (CVSADM_ENT)))
1970 sprintf (pending_error_text, "E cannot close %s", CVSADM_ENT);
1971 pending_error = save_errno;
1975 struct notify_note {
1976 /* Directory in which this notification happens. xmalloc'd*/
1982 /* The following three all in one xmalloc'd block, pointed to by TYPE.
1983 Each '\0' terminated. */
1990 struct notify_note *next;
1993 static struct notify_note *notify_list;
1994 /* Used while building list, to point to the last node that already exists. */
1995 static struct notify_note *last_node;
1997 static void serve_notify PROTO ((char *));
2003 struct notify_note *new = NULL;
2007 if (error_pending ()) return;
2009 if (outside_dir (arg))
2012 if (dir_name == NULL)
2015 new = (struct notify_note *) xmalloc (sizeof (struct notify_note));
2018 pending_error = ENOMEM;
2021 new->dir = xmalloc (strlen (dir_name) + 1);
2022 new->filename = xmalloc (strlen (arg) + 1);
2023 if (new->dir == NULL || new->filename == NULL)
2025 pending_error = ENOMEM;
2026 if (new->dir != NULL)
2031 strcpy (new->dir, dir_name);
2032 strcpy (new->filename, arg);
2034 status = buf_read_line (buf_from_net, &data, (int *) NULL);
2038 pending_error = ENOMEM;
2041 pending_error_text = xmalloc (80 + strlen (arg));
2042 if (pending_error_text == NULL)
2043 pending_error = ENOMEM;
2047 sprintf (pending_error_text,
2048 "E end of file reading notification for %s", arg);
2051 sprintf (pending_error_text,
2052 "E error reading notification for %s", arg);
2053 pending_error = status;
2057 free (new->filename);
2068 if (strchr (data, '+'))
2072 if (data[1] != '\t')
2077 cp = strchr (cp, '\t');
2081 cp = strchr (cp, '\t');
2085 cp = strchr (cp, '\t');
2090 /* If there is another tab, ignore everything after it,
2091 for future expansion. */
2092 cp = strchr (cp, '\t');
2100 if (last_node == NULL)
2105 last_node->next = new;
2111 if (alloc_pending (80))
2112 strcpy (pending_error_text,
2113 "E Protocol error; misformed Notify request");
2118 free (new->filename);
2125 /* Process all the Notify requests that we have stored up. Returns 0
2126 if successful, if not prints error message (via error()) and
2127 returns negative value. */
2131 struct notify_note *p;
2134 while (notify_list != NULL)
2136 if ( CVS_CHDIR (notify_list->dir) < 0)
2138 error (0, errno, "cannot change to %s", notify_list->dir);
2141 repos = Name_Repository (NULL, NULL);
2143 lock_dir_for_write (repos);
2145 fileattr_startdir (repos);
2147 notify_do (*notify_list->type, notify_list->filename, getcaller(),
2148 notify_list->val, notify_list->watches, repos);
2150 buf_output0 (buf_to_net, "Notified ");
2152 char *dir = notify_list->dir + strlen (server_temp_dir) + 1;
2154 buf_append_char (buf_to_net, '.');
2156 buf_output0 (buf_to_net, dir);
2157 buf_append_char (buf_to_net, '/');
2158 buf_append_char (buf_to_net, '\n');
2160 buf_output0 (buf_to_net, repos);
2161 buf_append_char (buf_to_net, '/');
2162 buf_output0 (buf_to_net, notify_list->filename);
2163 buf_append_char (buf_to_net, '\n');
2166 p = notify_list->next;
2167 free (notify_list->filename);
2168 free (notify_list->dir);
2169 free (notify_list->type);
2181 /* The code used to call fflush (stdout) here, but that is no
2182 longer necessary. The data is now buffered in buf_to_net,
2183 which will be flushed by the caller, do_cvs_command. */
2188 static int argument_count;
2189 static char **argument_vector;
2190 static int argument_vector_size;
2193 serve_argument (arg)
2198 if (error_pending()) return;
2200 if (argument_count >= 10000)
2202 if (alloc_pending (80))
2203 sprintf (pending_error_text,
2204 "E Protocol error: too many arguments");
2208 if (argument_vector_size <= argument_count)
2210 argument_vector_size *= 2;
2212 (char **) xrealloc ((char *)argument_vector,
2213 argument_vector_size * sizeof (char *));
2214 if (argument_vector == NULL)
2216 pending_error = ENOMEM;
2220 p = xmalloc (strlen (arg) + 1);
2223 pending_error = ENOMEM;
2227 argument_vector[argument_count++] = p;
2231 serve_argumentx (arg)
2236 if (error_pending()) return;
2238 if (argument_count <= 1)
2240 if (alloc_pending (80))
2241 sprintf (pending_error_text,
2242 "E Protocol error: called argumentx without prior call to argument");
2246 p = argument_vector[argument_count - 1];
2247 p = xrealloc (p, strlen (p) + 1 + strlen (arg) + 1);
2250 pending_error = ENOMEM;
2255 argument_vector[argument_count - 1] = p;
2259 serve_global_option (arg)
2262 if (arg[0] != '-' || arg[1] == '\0' || arg[2] != '\0')
2265 if (alloc_pending (strlen (arg) + 80))
2266 sprintf (pending_error_text,
2267 "E Protocol error: bad global option %s",
2274 error(0, 0, "WARNING: global `-l' option ignored.");
2301 /* FIXME: This sends errors immediately (I think); they should be
2302 put into pending_error. */
2308 #ifdef HAVE_KERBEROS
2311 serve_kerberos_encrypt (arg)
2314 /* All future communication with the client will be encrypted. */
2316 buf_to_net = krb_encrypt_buffer_initialize (buf_to_net, 0, sched,
2318 buf_to_net->memory_error);
2319 buf_from_net = krb_encrypt_buffer_initialize (buf_from_net, 1, sched,
2321 buf_from_net->memory_error);
2324 #endif /* HAVE_KERBEROS */
2329 serve_gssapi_encrypt (arg)
2332 if (cvs_gssapi_wrapping)
2334 /* We're already using a gssapi_wrap buffer for stream
2335 authentication. Flush everything we've output so far, and
2336 turn on encryption for future data. On the input side, we
2337 should only have unwrapped as far as the Gssapi-encrypt
2338 command, so future unwrapping will become encrypted. */
2339 buf_flush (buf_to_net, 1);
2340 cvs_gssapi_encrypt = 1;
2344 /* All future communication with the client will be encrypted. */
2346 cvs_gssapi_encrypt = 1;
2348 buf_to_net = cvs_gssapi_wrap_buffer_initialize (buf_to_net, 0,
2350 buf_to_net->memory_error);
2351 buf_from_net = cvs_gssapi_wrap_buffer_initialize (buf_from_net, 1,
2353 buf_from_net->memory_error);
2355 cvs_gssapi_wrapping = 1;
2358 #endif /* HAVE_GSSAPI */
2360 #endif /* ENCRYPTION */
2365 serve_gssapi_authenticate (arg)
2368 if (cvs_gssapi_wrapping)
2370 /* We're already using a gssapi_wrap buffer for encryption.
2371 That includes authentication, so we don't have to do
2372 anything further. */
2376 buf_to_net = cvs_gssapi_wrap_buffer_initialize (buf_to_net, 0,
2378 buf_to_net->memory_error);
2379 buf_from_net = cvs_gssapi_wrap_buffer_initialize (buf_from_net, 1,
2381 buf_from_net->memory_error);
2383 cvs_gssapi_wrapping = 1;
2386 #endif /* HAVE_GSSAPI */
2390 #ifdef SERVER_FLOWCONTROL
2391 /* The maximum we'll queue to the remote client before blocking. */
2392 # ifndef SERVER_HI_WATER
2393 # define SERVER_HI_WATER (2 * 1024 * 1024)
2394 # endif /* SERVER_HI_WATER */
2395 /* When the buffer drops to this, we restart the child */
2396 # ifndef SERVER_LO_WATER
2397 # define SERVER_LO_WATER (1 * 1024 * 1024)
2398 # endif /* SERVER_LO_WATER */
2399 #endif /* SERVER_FLOWCONTROL */
2403 static void serve_questionable PROTO((char *));
2406 serve_questionable (arg)
2413 /* Pick up ignores from CVSROOTADM_IGNORE, $HOME/.cvsignore on server,
2414 and CVSIGNORE on server. */
2419 if (dir_name == NULL)
2421 buf_output0 (buf_to_net, "E Protocol error: 'Directory' missing");
2425 if (outside_dir (arg))
2428 if (!ign_name (arg))
2432 buf_output (buf_to_net, "M ? ", 4);
2433 update_dir = dir_name + strlen (server_temp_dir) + 1;
2434 if (!(update_dir[0] == '.' && update_dir[1] == '\0'))
2436 buf_output0 (buf_to_net, update_dir);
2437 buf_output (buf_to_net, "/", 1);
2439 buf_output0 (buf_to_net, arg);
2440 buf_output (buf_to_net, "\n", 1);
2446 static struct buffer *protocol;
2448 /* This is the output which we are saving up to send to the server, in the
2449 child process. We will push it through, via the `protocol' buffer, when
2450 we have a complete line. */
2451 static struct buffer *saved_output;
2452 /* Likewise, but stuff which will go to stderr. */
2453 static struct buffer *saved_outerr;
2456 protocol_memory_error (buf)
2459 error (1, ENOMEM, "Virtual memory exhausted");
2463 * Process IDs of the subprocess, or negative if that subprocess
2466 static pid_t command_pid;
2469 outbuf_memory_error (buf)
2472 static const char msg[] = "E Fatal server error\n\
2473 error ENOMEM Virtual memory exhausted.\n";
2474 if (command_pid > 0)
2475 kill (command_pid, SIGTERM);
2478 * We have arranged things so that printing this now either will
2479 * be legal, or the "E fatal error" line will get glommed onto the
2480 * end of an existing "E" or "M" response.
2483 /* If this gives an error, not much we could do. syslog() it? */
2484 write (STDOUT_FILENO, msg, sizeof (msg) - 1);
2485 #ifdef HAVE_SYSLOG_H
2486 syslog (LOG_DAEMON | LOG_ERR, "virtual memory exhausted");
2492 input_memory_error (buf)
2495 outbuf_memory_error (buf);
2500 /* If command is legal, return 1.
2501 * Else if command is illegal and croak_on_illegal is set, then die.
2502 * Else just return 0 to indicate that command is illegal.
2505 check_command_legal_p (cmd_name)
2508 /* Right now, only pserver notices illegal commands -- namely,
2509 * write attempts by a read-only user. Therefore, if CVS_Username
2510 * is not set, this just returns 1, because CVS_Username unset
2511 * means pserver is not active.
2513 #ifdef AUTH_SERVER_SUPPORT
2514 if (CVS_Username == NULL)
2517 if (lookup_command_attribute (cmd_name) & CVS_CMD_MODIFIES_REPOSITORY)
2519 /* This command has the potential to modify the repository, so
2520 * we check if the user have permission to do that.
2522 * (Only relevant for remote users -- local users can do
2523 * whatever normal Unix file permissions allow them to do.)
2525 * The decision method:
2527 * If $CVSROOT/CVSADMROOT_READERS exists and user is listed
2528 * in it, then read-only access for user.
2530 * Or if $CVSROOT/CVSADMROOT_WRITERS exists and user NOT
2531 * listed in it, then also read-only access for user.
2533 * Else read-write access for user.
2536 char *linebuf = NULL;
2538 size_t linebuf_len = 0;
2545 flen = strlen (current_parsed_root->directory)
2546 + strlen (CVSROOTADM)
2547 + strlen (CVSROOTADM_READERS)
2550 fname = xmalloc (flen);
2551 (void) sprintf (fname, "%s/%s/%s", current_parsed_root->directory,
2552 CVSROOTADM, CVSROOTADM_READERS);
2554 fp = fopen (fname, "r");
2558 if (!existence_error (errno))
2560 /* Need to deny access, so that attackers can't fool
2561 us with some sort of denial of service attack. */
2562 error (0, errno, "cannot open %s", fname);
2567 else /* successfully opened readers file */
2569 while ((num_red = getline (&linebuf, &linebuf_len, fp)) >= 0)
2571 /* Hmmm, is it worth importing my own readline
2572 library into CVS? It takes care of chopping
2573 leading and trailing whitespace, "#" comments, and
2574 newlines automatically when so requested. Would
2575 save some code here... -kff */
2577 /* Chop newline by hand, for strcmp()'s sake. */
2578 if (num_red > 0 && linebuf[num_red - 1] == '\n')
2579 linebuf[num_red - 1] = '\0';
2581 if (strcmp (linebuf, CVS_Username) == 0)
2582 goto handle_illegal;
2584 if (num_red < 0 && !feof (fp))
2585 error (0, errno, "cannot read %s", fname);
2587 /* If not listed specifically as a reader, then this user
2588 has write access by default unless writers are also
2589 specified in a file . */
2590 if (fclose (fp) < 0)
2591 error (0, errno, "cannot close %s", fname);
2595 /* Now check the writers file. */
2597 flen = strlen (current_parsed_root->directory)
2598 + strlen (CVSROOTADM)
2599 + strlen (CVSROOTADM_WRITERS)
2602 fname = xmalloc (flen);
2603 (void) sprintf (fname, "%s/%s/%s", current_parsed_root->directory,
2604 CVSROOTADM, CVSROOTADM_WRITERS);
2606 fp = fopen (fname, "r");
2612 if (existence_error (errno))
2614 /* Writers file does not exist, so everyone is a writer,
2621 /* Need to deny access, so that attackers can't fool
2622 us with some sort of denial of service attack. */
2623 error (0, errno, "cannot read %s", fname);
2630 while ((num_red = getline (&linebuf, &linebuf_len, fp)) >= 0)
2632 /* Chop newline by hand, for strcmp()'s sake. */
2633 if (num_red > 0 && linebuf[num_red - 1] == '\n')
2634 linebuf[num_red - 1] = '\0';
2636 if (strcmp (linebuf, CVS_Username) == 0)
2642 if (num_red < 0 && !feof (fp))
2643 error (0, errno, "cannot read %s", fname);
2647 if (fclose (fp) < 0)
2648 error (0, errno, "cannot close %s", fname);
2654 else /* writers file exists, but this user not listed in it */
2657 if (fclose (fp) < 0)
2658 error (0, errno, "cannot close %s", fname);
2665 #endif /* AUTH_SERVER_SUPPORT */
2667 /* If ever reach end of this function, command must be legal. */
2673 /* Execute COMMAND in a subprocess with the approriate funky things done. */
2675 static struct fd_set_wrapper { fd_set fds; } command_fds_to_drain;
2677 static int max_command_fd;
2680 #ifdef SERVER_FLOWCONTROL
2681 static int flowcontrol_pipe[2];
2682 #endif /* SERVER_FLOWCONTROL */
2687 * Set buffer FD to non-blocking I/O. Returns 0 for success or errno
2691 set_nonblock_fd (fd)
2696 flags = fcntl (fd, F_GETFL, 0);
2699 if (fcntl (fd, F_SETFL, flags | O_NONBLOCK) < 0)
2707 do_cvs_command (cmd_name, command)
2709 int (*command) PROTO((int argc, char **argv));
2712 * The following file descriptors are set to -1 if that file is not
2716 /* Data on these pipes is a series of '\n'-terminated lines. */
2721 * Data on this pipe is a series of counted (see buf_send_counted)
2722 * packets. Each packet must be processed atomically (i.e. not
2723 * interleaved with data from stdout_pipe or stderr_pipe).
2725 int protocol_pipe[2];
2727 int dev_null_fd = -1;
2732 stdout_pipe[0] = -1;
2733 stdout_pipe[1] = -1;
2734 stderr_pipe[0] = -1;
2735 stderr_pipe[1] = -1;
2736 protocol_pipe[0] = -1;
2737 protocol_pipe[1] = -1;
2739 server_write_entries ();
2741 if (print_pending_error ())
2742 goto free_args_and_return;
2744 /* Global `cvs_cmd_name' is probably "server" right now -- only
2745 serve_export() sets it to anything else. So we will use local
2746 parameter `cmd_name' to determine if this command is legal for
2748 if (!check_command_legal_p (cmd_name))
2750 buf_output0 (buf_to_net, "E ");
2751 buf_output0 (buf_to_net, program_name);
2752 buf_output0 (buf_to_net, " [server aborted]: \"");
2753 buf_output0 (buf_to_net, cmd_name);
2754 buf_output0 (buf_to_net, "\" requires write access to the repository\n\
2756 goto free_args_and_return;
2758 cvs_cmd_name = cmd_name;
2760 (void) server_notify ();
2763 * We use a child process which actually does the operation. This
2764 * is so we can intercept its standard output. Even if all of CVS
2765 * were written to go to some special routine instead of writing
2766 * to stdout or stderr, we would still need to do the same thing
2767 * for the RCS commands.
2770 if (pipe (stdout_pipe) < 0)
2772 buf_output0 (buf_to_net, "E pipe failed\n");
2773 print_error (errno);
2776 if (pipe (stderr_pipe) < 0)
2778 buf_output0 (buf_to_net, "E pipe failed\n");
2779 print_error (errno);
2782 if (pipe (protocol_pipe) < 0)
2784 buf_output0 (buf_to_net, "E pipe failed\n");
2785 print_error (errno);
2788 #ifdef SERVER_FLOWCONTROL
2789 if (pipe (flowcontrol_pipe) < 0)
2791 buf_output0 (buf_to_net, "E pipe failed\n");
2792 print_error (errno);
2795 set_nonblock_fd (flowcontrol_pipe[0]);
2796 set_nonblock_fd (flowcontrol_pipe[1]);
2797 #endif /* SERVER_FLOWCONTROL */
2799 dev_null_fd = CVS_OPEN (DEVNULL, O_RDONLY);
2800 if (dev_null_fd < 0)
2802 buf_output0 (buf_to_net, "E open /dev/null failed\n");
2803 print_error (errno);
2807 /* We shouldn't have any partial lines from cvs_output and
2808 cvs_outerr, but we handle them here in case there is a bug. */
2809 /* FIXME: appending a newline, rather than using "MT" as we
2810 do in the child process, is probably not really a very good
2811 way to "handle" them. */
2812 if (! buf_empty_p (saved_output))
2814 buf_append_char (saved_output, '\n');
2815 buf_copy_lines (buf_to_net, saved_output, 'M');
2817 if (! buf_empty_p (saved_outerr))
2819 buf_append_char (saved_outerr, '\n');
2820 buf_copy_lines (buf_to_net, saved_outerr, 'E');
2823 /* Flush out any pending data. */
2824 buf_flush (buf_to_net, 1);
2826 /* Don't use vfork; we're not going to exec(). */
2827 command_pid = fork ();
2828 if (command_pid < 0)
2830 buf_output0 (buf_to_net, "E fork failed\n");
2831 print_error (errno);
2834 if (command_pid == 0)
2838 /* Since we're in the child, and the parent is going to take
2839 care of packaging up our error messages, we can clear this
2841 error_use_protocol = 0;
2843 protocol = fd_buffer_initialize (protocol_pipe[1], 0,
2844 protocol_memory_error);
2846 /* At this point we should no longer be using buf_to_net and
2847 buf_from_net. Instead, everything should go through
2849 if (buf_to_net != NULL)
2851 buf_free (buf_to_net);
2854 if (buf_from_net != NULL)
2856 buf_free (buf_from_net);
2857 buf_from_net = NULL;
2860 /* These were originally set up to use outbuf_memory_error.
2861 Since we're now in the child, we should use the simpler
2862 protocol_memory_error function. */
2863 saved_output->memory_error = protocol_memory_error;
2864 saved_outerr->memory_error = protocol_memory_error;
2866 if (dup2 (dev_null_fd, STDIN_FILENO) < 0)
2867 error (1, errno, "can't set up pipes");
2868 if (dup2 (stdout_pipe[1], STDOUT_FILENO) < 0)
2869 error (1, errno, "can't set up pipes");
2870 if (dup2 (stderr_pipe[1], STDERR_FILENO) < 0)
2871 error (1, errno, "can't set up pipes");
2872 close (dev_null_fd);
2873 close (stdout_pipe[0]);
2874 close (stdout_pipe[1]);
2875 close (stderr_pipe[0]);
2876 close (stderr_pipe[1]);
2877 close (protocol_pipe[0]);
2878 close_on_exec (protocol_pipe[1]);
2879 #ifdef SERVER_FLOWCONTROL
2880 close_on_exec (flowcontrol_pipe[0]);
2881 close (flowcontrol_pipe[1]);
2882 #endif /* SERVER_FLOWCONTROL */
2885 * Set this in .bashrc if you want to give yourself time to attach
2886 * to the subprocess with a debugger.
2888 if (getenv ("CVS_SERVER_SLEEP"))
2890 int secs = atoi (getenv ("CVS_SERVER_SLEEP"));
2894 exitstatus = (*command) (argument_count, argument_vector);
2896 /* Output any partial lines. If the client doesn't support
2897 "MT", we go ahead and just tack on a newline since the
2898 protocol doesn't support anything better. */
2899 if (! buf_empty_p (saved_output))
2901 buf_output0 (protocol, supported_response ("MT") ? "MT text " : "M ");
2902 buf_append_buffer (protocol, saved_output);
2903 buf_output (protocol, "\n", 1);
2904 buf_send_counted (protocol);
2906 /* For now we just discard partial lines on stderr. I suspect
2907 that CVS can't write such lines unless there is a bug. */
2909 buf_free (protocol);
2911 /* Close the pipes explicitly in order to send an EOF to the parent,
2912 * then wait for the parent to close the flow control pipe. This
2913 * avoids a race condition where a child which dumped more than the
2914 * high water mark into the pipes could complete its job and exit,
2915 * leaving the parent process to attempt to write a stop byte to the
2916 * closed flow control pipe, which earned the parent a SIGPIPE, which
2917 * it normally only expects on the network pipe and that causes it to
2918 * exit with an error message, rather than the SIGCHILD that it knows
2919 * how to handle correctly.
2921 /* Let exit() close STDIN - it's from /dev/null anyhow. */
2924 close (protocol_pipe[1]);
2925 #ifdef SERVER_FLOWCONTROL
2929 while ((status = read (flowcontrol_pipe[0], &junk, 1)) > 0
2930 || (status == -1 && errno == EAGAIN));
2932 /* FIXME: No point in printing an error message with error(),
2933 * as STDERR is already closed, but perhaps this could be syslogged?
2940 /* OK, sit around getting all the input from the child. */
2942 struct buffer *stdoutbuf;
2943 struct buffer *stderrbuf;
2944 struct buffer *protocol_inbuf;
2945 /* Number of file descriptors to check in select (). */
2947 int count_needed = 1;
2948 #ifdef SERVER_FLOWCONTROL
2949 int have_flowcontrolled = 0;
2950 #endif /* SERVER_FLOWCONTROL */
2952 FD_ZERO (&command_fds_to_drain.fds);
2953 num_to_check = stdout_pipe[0];
2954 FD_SET (stdout_pipe[0], &command_fds_to_drain.fds);
2955 if (stderr_pipe[0] > num_to_check)
2956 num_to_check = stderr_pipe[0];
2957 FD_SET (stderr_pipe[0], &command_fds_to_drain.fds);
2958 if (protocol_pipe[0] > num_to_check)
2959 num_to_check = protocol_pipe[0];
2960 FD_SET (protocol_pipe[0], &command_fds_to_drain.fds);
2961 if (STDOUT_FILENO > num_to_check)
2962 num_to_check = STDOUT_FILENO;
2964 max_command_fd = num_to_check;
2967 * File descriptors are numbered from 0, so num_to_check needs to
2968 * be one larger than the largest descriptor.
2971 if (num_to_check > FD_SETSIZE)
2973 buf_output0 (buf_to_net,
2974 "E internal error: FD_SETSIZE not big enough.\n\
2979 stdoutbuf = fd_buffer_initialize (stdout_pipe[0], 1,
2980 input_memory_error);
2982 stderrbuf = fd_buffer_initialize (stderr_pipe[0], 1,
2983 input_memory_error);
2985 protocol_inbuf = fd_buffer_initialize (protocol_pipe[0], 1,
2986 input_memory_error);
2988 set_nonblock (buf_to_net);
2989 set_nonblock (stdoutbuf);
2990 set_nonblock (stderrbuf);
2991 set_nonblock (protocol_inbuf);
2993 if (close (stdout_pipe[1]) < 0)
2995 buf_output0 (buf_to_net, "E close failed\n");
2996 print_error (errno);
2999 stdout_pipe[1] = -1;
3001 if (close (stderr_pipe[1]) < 0)
3003 buf_output0 (buf_to_net, "E close failed\n");
3004 print_error (errno);
3007 stderr_pipe[1] = -1;
3009 if (close (protocol_pipe[1]) < 0)
3011 buf_output0 (buf_to_net, "E close failed\n");
3012 print_error (errno);
3015 protocol_pipe[1] = -1;
3017 #ifdef SERVER_FLOWCONTROL
3018 if (close (flowcontrol_pipe[0]) < 0)
3020 buf_output0 (buf_to_net, "E close failed\n");
3021 print_error (errno);
3024 flowcontrol_pipe[0] = -1;
3025 #endif /* SERVER_FLOWCONTROL */
3027 if (close (dev_null_fd) < 0)
3029 buf_output0 (buf_to_net, "E close failed\n");
3030 print_error (errno);
3035 while (stdout_pipe[0] >= 0
3036 || stderr_pipe[0] >= 0
3037 || protocol_pipe[0] >= 0
3038 || count_needed <= 0)
3043 struct timeval *timeout_ptr;
3044 struct timeval timeout;
3045 #ifdef SERVER_FLOWCONTROL
3049 * See if we are swamping the remote client and filling our VM.
3050 * Tell child to hold off if we do.
3052 bufmemsize = buf_count_mem (buf_to_net);
3053 if (!have_flowcontrolled && (bufmemsize > SERVER_HI_WATER))
3055 if (write(flowcontrol_pipe[1], "S", 1) == 1)
3056 have_flowcontrolled = 1;
3058 else if (have_flowcontrolled && (bufmemsize < SERVER_LO_WATER))
3060 if (write(flowcontrol_pipe[1], "G", 1) == 1)
3061 have_flowcontrolled = 0;
3063 #endif /* SERVER_FLOWCONTROL */
3066 FD_ZERO (&writefds);
3068 if (count_needed <= 0)
3070 /* there is data pending which was read from the protocol pipe
3071 * so don't block if we don't find any data
3074 timeout.tv_usec = 0;
3075 timeout_ptr = &timeout;
3079 /* block indefinately */
3083 if (! buf_empty_p (buf_to_net))
3084 FD_SET (STDOUT_FILENO, &writefds);
3086 if (stdout_pipe[0] >= 0)
3088 FD_SET (stdout_pipe[0], &readfds);
3090 if (stderr_pipe[0] >= 0)
3092 FD_SET (stderr_pipe[0], &readfds);
3094 if (protocol_pipe[0] >= 0)
3096 FD_SET (protocol_pipe[0], &readfds);
3099 /* This process of selecting on the three pipes means that
3100 we might not get output in the same order in which it
3101 was written, thus producing the well-known
3102 "out-of-order" bug. If the child process uses
3103 cvs_output and cvs_outerr, it will send everything on
3104 the protocol_pipe and avoid this problem, so the
3105 solution is to use cvs_output and cvs_outerr in the
3108 /* This used to select on exceptions too, but as far
3109 as I know there was never any reason to do that and
3110 SCO doesn't let you select on exceptions on pipes. */
3111 numfds = select (num_to_check, &readfds, &writefds,
3112 (fd_set *)0, timeout_ptr);
3116 buf_output0 (buf_to_net, "E select failed\n");
3117 print_error (errno);
3120 } while (numfds < 0);
3125 FD_ZERO (&writefds);
3128 if (FD_ISSET (STDOUT_FILENO, &writefds))
3130 /* What should we do with errors? syslog() them? */
3131 buf_send_output (buf_to_net);
3134 if (protocol_pipe[0] >= 0
3135 && (FD_ISSET (protocol_pipe[0], &readfds)))
3140 status = buf_input_data (protocol_inbuf, &count_read);
3144 close (protocol_pipe[0]);
3145 protocol_pipe[0] = -1;
3147 else if (status > 0)
3149 buf_output0 (buf_to_net, "E buf_input_data failed\n");
3150 print_error (status);
3155 * We only call buf_copy_counted if we have read
3156 * enough bytes to make it worthwhile. This saves us
3157 * from continually recounting the amount of data we
3160 count_needed -= count_read;
3162 /* this is still part of the protocol pipe procedure, but it is
3163 * outside the above conditional so that unprocessed data can be
3164 * left in the buffer and stderr/stdout can be read when a flush
3165 * signal is received and control can return here without passing
3166 * through the select code and maybe blocking
3168 while (count_needed <= 0)
3172 count_needed = buf_copy_counted (buf_to_net,
3176 /* What should we do with errors? syslog() them? */
3177 buf_send_output (buf_to_net);
3179 /* If SPECIAL got set to <0, it means that the child
3180 * wants us to flush the pipe & maybe stderr or stdout.
3182 * After that we break to read stderr & stdout again before
3183 * going back to the protocol pipe
3185 * Upon breaking, count_needed = 0, so the next pass will only
3186 * perform a non-blocking select before returning here to finish
3187 * processing data we already read from the protocol buffer
3196 /* If the client supports the 'F' command, we send it. */
3197 if (supported_response ("F"))
3199 buf_append_char (buf_to_net, 'F');
3200 buf_append_char (buf_to_net, '\n');
3207 if (stdout_pipe[0] >= 0
3208 && (FD_ISSET (stdout_pipe[0], &readfds)))
3212 status = buf_input_data (stdoutbuf, (int *) NULL);
3214 buf_copy_lines (buf_to_net, stdoutbuf, 'M');
3218 close (stdout_pipe[0]);
3219 stdout_pipe[0] = -1;
3221 else if (status > 0)
3223 buf_output0 (buf_to_net, "E buf_input_data failed\n");
3224 print_error (status);
3228 /* What should we do with errors? syslog() them? */
3229 buf_send_output (buf_to_net);
3232 if (stderr_pipe[0] >= 0
3233 && (FD_ISSET (stderr_pipe[0], &readfds)))
3237 status = buf_input_data (stderrbuf, (int *) NULL);
3239 buf_copy_lines (buf_to_net, stderrbuf, 'E');
3243 close (stderr_pipe[0]);
3244 stderr_pipe[0] = -1;
3246 else if (status > 0)
3248 buf_output0 (buf_to_net, "E buf_input_data failed\n");
3249 print_error (status);
3253 /* What should we do with errors? syslog() them? */
3254 buf_send_output (buf_to_net);
3259 * OK, we've gotten EOF on all the pipes. If there is
3260 * anything left on stdoutbuf or stderrbuf (this could only
3261 * happen if there was no trailing newline), send it over.
3263 if (! buf_empty_p (stdoutbuf))
3265 buf_append_char (stdoutbuf, '\n');
3266 buf_copy_lines (buf_to_net, stdoutbuf, 'M');
3268 if (! buf_empty_p (stderrbuf))
3270 buf_append_char (stderrbuf, '\n');
3271 buf_copy_lines (buf_to_net, stderrbuf, 'E');
3273 if (! buf_empty_p (protocol_inbuf))
3274 buf_output0 (buf_to_net,
3275 "E Protocol error: uncounted data discarded\n");
3277 #ifdef SERVER_FLOWCONTROL
3278 close (flowcontrol_pipe[1]);
3279 flowcontrol_pipe[1] = -1;
3280 #endif /* SERVER_FLOWCONTROL */
3284 while (command_pid > 0)
3288 waited_pid = waitpid (command_pid, &status, 0);
3292 * Intentionally ignoring EINTR. Other errors
3298 if (WIFEXITED (status))
3299 errs += WEXITSTATUS (status);
3302 int sig = WTERMSIG (status);
3305 * This is really evil, because signals might be numbered
3306 * differently on the two systems. We should be using
3307 * signal names (either of the "Terminated" or the "SIGTERM"
3308 * variety). But cvs doesn't currently use libiberty...we
3309 * could roll our own.... FIXME.
3311 buf_output0 (buf_to_net, "E Terminated with fatal signal ");
3312 sprintf (buf, "%d\n", sig);
3313 buf_output0 (buf_to_net, buf);
3315 /* Test for a core dump. */
3316 if (WCOREDUMP (status))
3318 buf_output0 (buf_to_net, "E Core dumped; preserving ");
3319 buf_output0 (buf_to_net, orig_server_temp_dir);
3320 buf_output0 (buf_to_net, " on server.\n\
3321 E CVS locks may need cleaning up.\n");
3322 dont_delete_temp = 1;
3326 if (waited_pid == command_pid)
3331 * OK, we've waited for the child. By now all CVS locks are free
3332 * and it's OK to block on the network.
3334 set_block (buf_to_net);
3335 buf_flush (buf_to_net, 1);
3336 buf_shutdown (protocol_inbuf);
3337 buf_free (protocol_inbuf);
3338 protocol_inbuf = NULL;
3339 buf_shutdown (stderrbuf);
3340 buf_free (stderrbuf);
3342 buf_shutdown (stdoutbuf);
3343 buf_free (stdoutbuf);
3348 /* We will have printed an error message already. */
3349 buf_output0 (buf_to_net, "error \n");
3351 buf_output0 (buf_to_net, "ok\n");
3352 goto free_args_and_return;
3355 if (command_pid > 0)
3356 kill (command_pid, SIGTERM);
3358 while (command_pid > 0)
3361 waited_pid = waitpid (command_pid, (int *) 0, 0);
3362 if (waited_pid < 0 && errno == EINTR)
3364 if (waited_pid == command_pid)
3368 close (dev_null_fd);
3369 close (protocol_pipe[0]);
3370 close (protocol_pipe[1]);
3371 close (stderr_pipe[0]);
3372 close (stderr_pipe[1]);
3373 close (stdout_pipe[0]);
3374 close (stdout_pipe[1]);
3375 #ifdef SERVER_FLOWCONTROL
3376 close (flowcontrol_pipe[0]);
3377 close (flowcontrol_pipe[1]);
3378 #endif /* SERVER_FLOWCONTROL */
3380 free_args_and_return:
3381 /* Now free the arguments. */
3383 /* argument_vector[0] is a dummy argument, we don't mess with it. */
3385 for (cp = argument_vector + 1;
3386 cp < argument_vector + argument_count;
3393 /* Flush out any data not yet sent. */
3394 set_block (buf_to_net);
3395 buf_flush (buf_to_net, 1);
3400 #ifdef SERVER_FLOWCONTROL
3402 * Called by the child at convenient points in the server's execution for
3403 * the server child to block.. ie: when it has no locks active.
3406 server_pause_check()
3411 while (read (flowcontrol_pipe[0], buf, 1) == 1)
3413 if (*buf == 'S') /* Stop */
3415 else if (*buf == 'G') /* Go */
3421 int numfds, numtocheck;
3425 FD_SET (flowcontrol_pipe[0], &fds);
3426 numtocheck = flowcontrol_pipe[0] + 1;
3429 numfds = select (numtocheck, &fds, (fd_set *)0,
3430 (fd_set *)0, (struct timeval *)NULL);
3434 buf_output0 (buf_to_net, "E select failed\n");
3435 print_error (errno);
3438 } while (numfds < 0);
3440 if (FD_ISSET (flowcontrol_pipe[0], &fds))
3444 while ((got = read (flowcontrol_pipe[0], buf, 1)) == 1)
3446 if (*buf == 'S') /* Stop */
3448 else if (*buf == 'G') /* Go */
3454 /* This assumes that we are using BSD or POSIX nonblocking
3455 I/O. System V nonblocking I/O returns zero if there is
3458 error (1, 0, "flow control EOF");
3459 if (got < 0 && ! blocking_error (errno))
3461 error (1, errno, "flow control read failed");
3466 #endif /* SERVER_FLOWCONTROL */
3468 /* This variable commented in server.h. */
3469 char *server_dir = NULL;
3473 static void output_dir PROTO((const char *, const char *));
3476 output_dir (update_dir, repository)
3477 const char *update_dir;
3478 const char *repository;
3480 if (server_dir != NULL)
3482 buf_output0 (protocol, server_dir);
3483 buf_output0 (protocol, "/");
3485 if (update_dir[0] == '\0')
3486 buf_output0 (protocol, ".");
3488 buf_output0 (protocol, update_dir);
3489 buf_output0 (protocol, "/\n");
3490 buf_output0 (protocol, repository);
3491 buf_output0 (protocol, "/");
3497 * Entries line that we are squirreling away to send to the client when
3500 static char *entries_line;
3503 * File which has been Scratch_File'd, we are squirreling away that fact
3504 * to inform the client when we are ready.
3506 static char *scratched_file;
3509 * The scratched_file will need to be removed as well as having its entry
3512 static int kill_scratched_file;
3517 server_register (name, version, timestamp, options, tag, date, conflict)
3519 const char *version;
3520 const char *timestamp;
3521 const char *options;
3524 const char *conflict;
3528 if (options == NULL)
3533 (void) fprintf (stderr,
3534 "%s-> server_register(%s, %s, %s, %s, %s, %s, %s)\n",
3536 name, version, timestamp ? timestamp : "", options,
3537 tag ? tag : "", date ? date : "",
3538 conflict ? conflict : "");
3541 if (entries_line != NULL)
3544 * If CVS decides to Register it more than once (which happens
3545 * on "cvs update foo/foo.c" where foo and foo.c are already
3546 * checked out), use the last of the entries lines Register'd.
3548 free (entries_line);
3552 * I have reports of Scratch_Entry and Register both happening, in
3553 * two different cases. Using the last one which happens is almost
3554 * surely correct; I haven't tracked down why they both happen (or
3555 * even verified that they are for the same file).
3557 if (scratched_file != NULL)
3559 free (scratched_file);
3560 scratched_file = NULL;
3563 len = (strlen (name) + strlen (version) + strlen (options) + 80);
3565 len += strlen (tag);
3567 len += strlen (date);
3569 entries_line = xmalloc (len);
3570 sprintf (entries_line, "/%s/%s/", name, version);
3571 if (conflict != NULL)
3573 strcat (entries_line, "+=");
3575 strcat (entries_line, "/");
3576 strcat (entries_line, options);
3577 strcat (entries_line, "/");
3580 strcat (entries_line, "T");
3581 strcat (entries_line, tag);
3583 else if (date != NULL)
3585 strcat (entries_line, "D");
3586 strcat (entries_line, date);
3593 server_scratch (fname)
3597 * I have reports of Scratch_Entry and Register both happening, in
3598 * two different cases. Using the last one which happens is almost
3599 * surely correct; I haven't tracked down why they both happen (or
3600 * even verified that they are for the same file).
3602 * Don't know if this is what whoever wrote the above comment was
3603 * talking about, but this can happen in the case where a join
3604 * removes a file - the call to Register puts the '-vers' into the
3605 * Entries file after the file is removed
3607 if (entries_line != NULL)
3609 free (entries_line);
3610 entries_line = NULL;
3613 if (scratched_file != NULL)
3615 buf_output0 (protocol,
3616 "E CVS server internal error: duplicate Scratch_Entry\n");
3617 buf_send_counted (protocol);
3620 scratched_file = xstrdup (fname);
3621 kill_scratched_file = 1;
3625 server_scratch_entry_only ()
3627 kill_scratched_file = 0;
3630 /* Print a new entries line, from a previous server_register. */
3636 buf_output0 (protocol, entries_line);
3637 buf_output (protocol, "\n", 1);
3640 /* Return the error message as the Entries line. */
3641 buf_output0 (protocol,
3642 "CVS server internal error: Register missing\n");
3643 free (entries_line);
3644 entries_line = NULL;
3652 do_cvs_command ("commit", commit);
3656 checked_in_response (file, update_dir, repository)
3661 if (supported_response ("Mode"))
3666 if ( CVS_STAT (file, &sb) < 0)
3668 /* Not clear to me why the file would fail to exist, but it
3669 was happening somewhere in the testsuite. */
3670 if (!existence_error (errno))
3671 error (0, errno, "cannot stat %s", file);
3675 buf_output0 (protocol, "Mode ");
3676 mode_string = mode_to_string (sb.st_mode);
3677 buf_output0 (protocol, mode_string);
3678 buf_output0 (protocol, "\n");
3683 buf_output0 (protocol, "Checked-in ");
3684 output_dir (update_dir, repository);
3685 buf_output0 (protocol, file);
3686 buf_output (protocol, "\n", 1);
3687 new_entries_line ();
3691 server_checked_in (file, update_dir, repository)
3693 const char *update_dir;
3694 const char *repository;
3698 if (scratched_file != NULL && entries_line == NULL)
3701 * This happens if we are now doing a "cvs remove" after a previous
3702 * "cvs add" (without a "cvs ci" in between).
3704 buf_output0 (protocol, "Remove-entry ");
3705 output_dir (update_dir, repository);
3706 buf_output0 (protocol, file);
3707 buf_output (protocol, "\n", 1);
3708 free (scratched_file);
3709 scratched_file = NULL;
3713 checked_in_response (file, update_dir, repository);
3715 buf_send_counted (protocol);
3719 server_update_entries (file, update_dir, repository, updated)
3721 const char *update_dir;
3722 const char *repository;
3723 enum server_updated_arg4 updated;
3727 if (updated == SERVER_UPDATED)
3728 checked_in_response (file, update_dir, repository);
3731 if (!supported_response ("New-entry"))
3733 buf_output0 (protocol, "New-entry ");
3734 output_dir (update_dir, repository);
3735 buf_output0 (protocol, file);
3736 buf_output (protocol, "\n", 1);
3737 new_entries_line ();
3740 buf_send_counted (protocol);
3747 do_cvs_command ("update", update);
3754 do_cvs_command ("diff", diff);
3761 do_cvs_command ("log", cvslog);
3768 do_cvs_command ("rlog", cvslog);
3775 do_cvs_command ("add", add);
3782 do_cvs_command ("remove", cvsremove);
3789 do_cvs_command ("status", cvsstatus);
3796 do_cvs_command ("rdiff", patch);
3803 do_cvs_command ("tag", cvstag);
3810 do_cvs_command ("rtag", cvstag);
3817 do_cvs_command ("import", import);
3824 do_cvs_command ("admin", admin);
3831 do_cvs_command ("history", history);
3838 do_cvs_command ("release", release);
3841 static void serve_watch_on PROTO ((char *));
3844 serve_watch_on (arg)
3847 do_cvs_command ("watch", watch_on);
3850 static void serve_watch_off PROTO ((char *));
3853 serve_watch_off (arg)
3856 do_cvs_command ("watch", watch_off);
3859 static void serve_watch_add PROTO ((char *));
3862 serve_watch_add (arg)
3865 do_cvs_command ("watch", watch_add);
3868 static void serve_watch_remove PROTO ((char *));
3871 serve_watch_remove (arg)
3874 do_cvs_command ("watch", watch_remove);
3877 static void serve_watchers PROTO ((char *));
3880 serve_watchers (arg)
3883 do_cvs_command ("watchers", watchers);
3886 static void serve_editors PROTO ((char *));
3892 do_cvs_command ("editors", editors);
3895 static void serve_noop PROTO ((char *));
3902 server_write_entries ();
3903 if (!print_pending_error ())
3905 (void) server_notify ();
3906 buf_output0 (buf_to_net, "ok\n");
3908 buf_flush (buf_to_net, 1);
3911 static void serve_version PROTO ((char *));
3917 do_cvs_command ("version", version);
3920 static void serve_init PROTO ((char *));
3926 cvsroot_t *saved_parsed_root;
3928 if (!isabsolute (arg))
3930 if (alloc_pending (80 + strlen (arg)))
3931 sprintf (pending_error_text,
3932 "E init %s must be an absolute pathname", arg);
3934 #ifdef AUTH_SERVER_SUPPORT
3935 else if (Pserver_Repos != NULL)
3937 if (strcmp (Pserver_Repos, arg) != 0)
3939 if (alloc_pending (80 + strlen (Pserver_Repos) + strlen (arg)))
3940 /* The explicitness is to aid people who are writing clients.
3941 I don't see how this information could help an
3943 sprintf (pending_error_text, "\
3944 E Protocol error: init says \"%s\" but pserver says \"%s\"",
3945 arg, Pserver_Repos);
3950 if (print_pending_error ())
3953 saved_parsed_root = current_parsed_root;
3954 current_parsed_root = local_cvsroot (arg);
3955 do_cvs_command ("init", init);
3956 free_cvsroot_t (current_parsed_root);
3957 current_parsed_root = saved_parsed_root;
3960 static void serve_annotate PROTO ((char *));
3963 serve_annotate (arg)
3966 do_cvs_command ("annotate", annotate);
3969 static void serve_rannotate PROTO ((char *));
3972 serve_rannotate (arg)
3975 do_cvs_command ("rannotate", annotate);
3985 if (print_pending_error ())
3988 if (!isdir (CVSADM))
3991 * The client has not sent a "Repository" line. Check out
3992 * into a pristine directory.
3994 tempdir = xmalloc (strlen (server_temp_dir) + 80);
3995 if (tempdir == NULL)
3997 buf_output0 (buf_to_net, "E Out of memory\n");
4000 strcpy (tempdir, server_temp_dir);
4001 strcat (tempdir, "/checkout-dir");
4002 status = mkdir_p (tempdir);
4003 if (status != 0 && status != EEXIST)
4005 buf_output0 (buf_to_net, "E Cannot create ");
4006 buf_output0 (buf_to_net, tempdir);
4007 buf_append_char (buf_to_net, '\n');
4008 print_error (errno);
4013 if ( CVS_CHDIR (tempdir) < 0)
4015 buf_output0 (buf_to_net, "E Cannot change to directory ");
4016 buf_output0 (buf_to_net, tempdir);
4017 buf_append_char (buf_to_net, '\n');
4018 print_error (errno);
4025 /* Compensate for server_export()'s setting of cvs_cmd_name.
4027 * [It probably doesn't matter if do_cvs_command() gets "export"
4028 * or "checkout", but we ought to be accurate where possible.]
4030 do_cvs_command ((strcmp (cvs_cmd_name, "export") == 0) ?
4031 "export" : "checkout",
4039 /* Tell checkout() to behave like export not checkout. */
4040 cvs_cmd_name = "export";
4047 server_copy_file (file, update_dir, repository, newfile)
4049 const char *update_dir;
4050 const char *repository;
4051 const char *newfile;
4053 /* At least for now, our practice is to have the server enforce
4054 noexec for the repository and the client enforce it for the
4055 working directory. This might want more thought, and/or
4056 documentation in cvsclient.texi (other responses do it
4059 if (!supported_response ("Copy-file"))
4061 buf_output0 (protocol, "Copy-file ");
4062 output_dir (update_dir, repository);
4063 buf_output0 (protocol, file);
4064 buf_output0 (protocol, "\n");
4065 buf_output0 (protocol, newfile);
4066 buf_output0 (protocol, "\n");
4069 /* See server.h for description. */
4072 server_modtime (finfo, vers_ts)
4073 struct file_info *finfo;
4076 char date[MAXDATELEN];
4077 char outdate[MAXDATELEN];
4079 assert (vers_ts->vn_rcs != NULL);
4081 if (!supported_response ("Mod-time"))
4084 if (RCS_getrevtime (finfo->rcs, vers_ts->vn_rcs, date, 0) == (time_t) -1)
4085 /* FIXME? should we be printing some kind of warning? For one
4086 thing I'm not 100% sure whether this happens in non-error
4089 date_to_internet (outdate, date);
4090 buf_output0 (protocol, "Mod-time ");
4091 buf_output0 (protocol, outdate);
4092 buf_output0 (protocol, "\n");
4095 /* See server.h for description. */
4097 #if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__)
4098 /* Need to prototype because mode_t might be smaller than int. */
4101 struct file_info *finfo,
4103 enum server_updated_arg4 updated,
4105 unsigned char *checksum,
4106 struct buffer *filebuf)
4109 server_updated (finfo, vers, updated, mode, checksum, filebuf)
4110 struct file_info *finfo;
4112 enum server_updated_arg4 updated;
4114 unsigned char *checksum;
4115 struct buffer *filebuf;
4120 /* Hmm, maybe if we did the same thing for entries_file, we
4121 could get rid of the kludges in server_register and
4122 server_scratch which refrain from warning if both
4123 Scratch_Entry and Register get called. Maybe. */
4126 free (scratched_file);
4127 scratched_file = NULL;
4132 if (entries_line != NULL && scratched_file == NULL)
4135 struct buffer_data *list, *last;
4139 /* The contents of the file will be in one of filebuf,
4140 list/last, or here. */
4141 unsigned char *file;
4142 size_t file_allocated;
4145 if (filebuf != NULL)
4147 size = buf_length (filebuf);
4148 if (mode == (mode_t) -1)
4150 CVS server internal error: no mode in server_updated");
4156 if ( CVS_STAT (finfo->file, &sb) < 0)
4158 if (existence_error (errno))
4160 /* If we have a sticky tag for a branch on which
4161 the file is dead, and cvs update the directory,
4162 it gets a T_CHECKOUT but no file. So in this
4163 case just forget the whole thing. */
4164 free (entries_line);
4165 entries_line = NULL;
4168 error (1, errno, "reading %s", finfo->fullname);
4171 if (mode == (mode_t) -1)
4173 /* FIXME: When we check out files the umask of the
4174 server (set in .bashrc if rsh is in use) affects
4175 what mode we send, and it shouldn't. */
4180 if (checksum != NULL)
4182 static int checksum_supported = -1;
4184 if (checksum_supported == -1)
4186 checksum_supported = supported_response ("Checksum");
4189 if (checksum_supported)
4194 buf_output0 (protocol, "Checksum ");
4195 for (i = 0; i < 16; i++)
4197 sprintf (buf, "%02x", (unsigned int) checksum[i]);
4198 buf_output0 (protocol, buf);
4200 buf_append_char (protocol, '\n');
4204 if (updated == SERVER_UPDATED)
4209 if (!(supported_response ("Created")
4210 && supported_response ("Update-existing")))
4211 buf_output0 (protocol, "Updated ");
4214 assert (vers != NULL);
4215 if (vers->ts_user == NULL)
4216 buf_output0 (protocol, "Created ");
4218 buf_output0 (protocol, "Update-existing ");
4221 /* Now munge the entries to say that the file is unmodified,
4222 in case we end up processing it again (e.g. modules3-6
4223 in the testsuite). */
4224 node = findnode_fn (finfo->entries, finfo->file);
4225 entnode = node->data;
4226 free (entnode->timestamp);
4227 entnode->timestamp = xstrdup ("=");
4229 else if (updated == SERVER_MERGED)
4230 buf_output0 (protocol, "Merged ");
4231 else if (updated == SERVER_PATCHED)
4232 buf_output0 (protocol, "Patched ");
4233 else if (updated == SERVER_RCS_DIFF)
4234 buf_output0 (protocol, "Rcs-diff ");
4237 output_dir (finfo->update_dir, finfo->repository);
4238 buf_output0 (protocol, finfo->file);
4239 buf_output (protocol, "\n", 1);
4241 new_entries_line ();
4246 mode_string = mode_to_string (mode);
4247 buf_output0 (protocol, mode_string);
4248 buf_output0 (protocol, "\n");
4260 /* Throughout this section we use binary mode to read the
4261 file we are sending. The client handles any line ending
4262 translation if necessary. */
4266 * For really tiny files, the gzip process startup
4267 * time will outweigh the compression savings. This
4268 * might be computable somehow; using 100 here is just
4269 * a first approximation.
4273 /* Basing this routine on read_and_gzip is not a
4274 high-performance approach. But it seems easier
4275 to code than the alternative (and less
4276 vulnerable to subtle bugs). Given that this feature
4277 is mainly for compatibility, that is the better
4282 /* Callers must avoid passing us a buffer if
4283 file_gzip_level is set. We could handle this case,
4284 but it's not worth it since this case never arises
4285 with a current client and server. */
4286 if (filebuf != NULL)
4288 CVS server internal error: unhandled case in server_updated");
4290 fd = CVS_OPEN (finfo->file, O_RDONLY | OPEN_BINARY, 0);
4292 error (1, errno, "reading %s", finfo->fullname);
4293 if (read_and_gzip (fd, finfo->fullname, &file,
4294 &file_allocated, &file_used,
4296 error (1, 0, "aborting due to compression error");
4299 error (1, errno, "reading %s", finfo->fullname);
4300 /* Prepending length with "z" is flag for using gzip here. */
4301 buf_output0 (protocol, "z");
4303 else if (filebuf == NULL)
4307 f = CVS_FOPEN (finfo->file, "rb");
4309 error (1, errno, "reading %s", finfo->fullname);
4310 status = buf_read_file (f, size, &list, &last);
4312 (*protocol->memory_error) (protocol);
4313 else if (status != 0)
4314 error (1, ferror (f) ? errno : 0, "reading %s",
4316 if (fclose (f) == EOF)
4317 error (1, errno, "reading %s", finfo->fullname);
4321 sprintf (size_text, "%lu\n", size);
4322 buf_output0 (protocol, size_text);
4326 buf_output (protocol, (char *) file, file_used);
4330 else if (filebuf == NULL)
4331 buf_append_data (protocol, list, last);
4334 buf_append_buffer (protocol, filebuf);
4336 /* Note we only send a newline here if the file ended with one. */
4339 * Avoid using up too much disk space for temporary files.
4340 * A file which does not exist indicates that the file is up-to-date,
4341 * which is now the case. If this is SERVER_MERGED, the file is
4342 * not up-to-date, and we indicate that by leaving the file there.
4343 * I'm thinking of cases like "cvs update foo/foo.c foo".
4345 if ((updated == SERVER_UPDATED
4346 || updated == SERVER_PATCHED
4347 || updated == SERVER_RCS_DIFF)
4349 /* But if we are joining, we'll need the file when we call
4353 if (CVS_UNLINK (finfo->file) < 0)
4354 error (0, errno, "cannot remove temp file for %s",
4358 else if (scratched_file != NULL && entries_line == NULL)
4360 if (strcmp (scratched_file, finfo->file) != 0)
4362 "CVS server internal error: `%s' vs. `%s' scratched",
4365 free (scratched_file);
4366 scratched_file = NULL;
4368 if (kill_scratched_file)
4369 buf_output0 (protocol, "Removed ");
4371 buf_output0 (protocol, "Remove-entry ");
4372 output_dir (finfo->update_dir, finfo->repository);
4373 buf_output0 (protocol, finfo->file);
4374 buf_output (protocol, "\n", 1);
4375 /* keep the vers structure up to date in case we do a join
4376 * - if there isn't a file, it can't very well have a version number, can it?
4378 * we do it here on the assumption that since we just told the client
4379 * to remove the file/entry, it will, and we want to remember that.
4380 * If it fails, that's the client's problem, not ours
4382 if (vers && vers->vn_user != NULL)
4384 free (vers->vn_user);
4385 vers->vn_user = NULL;
4387 if (vers && vers->ts_user != NULL)
4389 free (vers->ts_user);
4390 vers->ts_user = NULL;
4393 else if (scratched_file == NULL && entries_line == NULL)
4396 * This can happen with death support if we were processing
4397 * a dead file in a checkout.
4402 "CVS server internal error: Register *and* Scratch_Entry.\n");
4403 buf_send_counted (protocol);
4407 /* Return whether we should send patches in RCS format. */
4410 server_use_rcs_diff ()
4412 return supported_response ("Rcs-diff");
4418 server_set_entstat (update_dir, repository)
4419 const char *update_dir;
4420 const char *repository;
4422 static int set_static_supported = -1;
4423 if (set_static_supported == -1)
4424 set_static_supported = supported_response ("Set-static-directory");
4425 if (!set_static_supported) return;
4427 buf_output0 (protocol, "Set-static-directory ");
4428 output_dir (update_dir, repository);
4429 buf_output0 (protocol, "\n");
4430 buf_send_counted (protocol);
4436 server_clear_entstat (update_dir, repository)
4437 const char *update_dir;
4438 const char *repository;
4440 static int clear_static_supported = -1;
4441 if (clear_static_supported == -1)
4442 clear_static_supported = supported_response ("Clear-static-directory");
4443 if (!clear_static_supported) return;
4448 buf_output0 (protocol, "Clear-static-directory ");
4449 output_dir (update_dir, repository);
4450 buf_output0 (protocol, "\n");
4451 buf_send_counted (protocol);
4457 server_set_sticky (update_dir, repository, tag, date, nonbranch)
4458 const char *update_dir;
4459 const char *repository;
4464 static int set_sticky_supported = -1;
4466 assert (update_dir != NULL);
4468 if (set_sticky_supported == -1)
4469 set_sticky_supported = supported_response ("Set-sticky");
4470 if (!set_sticky_supported) return;
4475 if (tag == NULL && date == NULL)
4477 buf_output0 (protocol, "Clear-sticky ");
4478 output_dir (update_dir, repository);
4479 buf_output0 (protocol, "\n");
4483 buf_output0 (protocol, "Set-sticky ");
4484 output_dir (update_dir, repository);
4485 buf_output0 (protocol, "\n");
4489 buf_output0 (protocol, "N");
4491 buf_output0 (protocol, "T");
4492 buf_output0 (protocol, tag);
4496 buf_output0 (protocol, "D");
4497 buf_output0 (protocol, date);
4499 buf_output0 (protocol, "\n");
4501 buf_send_counted (protocol);
4504 struct template_proc_data
4506 const char *update_dir;
4507 const char *repository;
4510 /* Here as a static until we get around to fixing Parse_Info to pass along
4512 static struct template_proc_data *tpd;
4515 template_proc (repository, template)
4523 struct template_proc_data *data = tpd;
4525 if (!supported_response ("Template"))
4526 /* Might want to warn the user that the rcsinfo feature won't work. */
4528 buf_output0 (protocol, "Template ");
4529 output_dir (data->update_dir, data->repository);
4530 buf_output0 (protocol, "\n");
4532 fp = CVS_FOPEN (template, "rb");
4535 error (0, errno, "Couldn't open rcsinfo template file %s", template);
4538 if (fstat (fileno (fp), &sb) < 0)
4540 error (0, errno, "cannot stat rcsinfo template file %s", template);
4543 sprintf (buf, "%ld\n", (long) sb.st_size);
4544 buf_output0 (protocol, buf);
4547 n = fread (buf, 1, sizeof buf, fp);
4548 buf_output (protocol, buf, n);
4551 error (0, errno, "cannot read rcsinfo template file %s", template);
4556 buf_send_counted (protocol);
4557 if (fclose (fp) < 0)
4558 error (0, errno, "cannot close rcsinfo template file %s", template);
4565 server_template (update_dir, repository)
4566 const char *update_dir;
4567 const char *repository;
4569 struct template_proc_data data;
4570 data.update_dir = update_dir;
4571 data.repository = repository;
4573 (void) Parse_Info (CVSROOTADM_RCSINFO, repository, template_proc, 1);
4579 serve_gzip_contents (arg)
4586 file_gzip_level = level;
4590 serve_gzip_stream (arg)
4598 /* All further communication with the client will be compressed. */
4600 buf_to_net = compress_buffer_initialize (buf_to_net, 0, level,
4601 buf_to_net->memory_error);
4602 buf_from_net = compress_buffer_initialize (buf_from_net, 1, level,
4603 buf_from_net->memory_error);
4606 /* Tell the client about RCS options set in CVSROOT/cvswrappers. */
4608 serve_wrapper_sendme_rcs_options (arg)
4611 /* Actually, this is kind of sdrawkcab-ssa: the client wants
4612 * verbatim lines from a cvswrappers file, but the server has
4613 * already parsed the cvswrappers file into the wrap_list struct.
4614 * Therefore, the server loops over wrap_list, unparsing each
4615 * entry before sending it.
4617 char *wrapper_line = NULL;
4621 for (wrap_unparse_rcs_options (&wrapper_line, 1);
4623 wrap_unparse_rcs_options (&wrapper_line, 0))
4625 buf_output0 (buf_to_net, "Wrapper-rcsOption ");
4626 buf_output0 (buf_to_net, wrapper_line);
4627 buf_output0 (buf_to_net, "\012");;
4628 free (wrapper_line);
4631 buf_output0 (buf_to_net, "ok\012");
4633 /* The client is waiting for us, so we better send the data now. */
4634 buf_flush (buf_to_net, 1);
4643 * Just ignore this command. This is used to support the
4644 * update-patches command, which is not a real command, but a signal
4645 * to the client that update will accept the -u argument.
4650 expand_proc (argc, argv, where, mwhere, mfile, shorten,
4651 local_specified, omodule, msg)
4658 int local_specified;
4663 char *dir = argv[0];
4665 /* If mwhere has been specified, the thing we're expanding is a
4666 module -- just return its name so the client will ask for the
4667 right thing later. If it is an alias or a real directory,
4668 mwhere will not be set, so send out the appropriate
4673 buf_output0 (buf_to_net, "Module-expansion ");
4674 if (server_dir != NULL)
4676 buf_output0 (buf_to_net, server_dir);
4677 buf_output0 (buf_to_net, "/");
4679 buf_output0 (buf_to_net, mwhere);
4682 buf_append_char (buf_to_net, '/');
4683 buf_output0 (buf_to_net, mfile);
4685 buf_append_char (buf_to_net, '\n');
4689 /* We may not need to do this anymore -- check the definition
4690 of aliases before removing */
4693 buf_output0 (buf_to_net, "Module-expansion ");
4694 if (server_dir != NULL)
4696 buf_output0 (buf_to_net, server_dir);
4697 buf_output0 (buf_to_net, "/");
4699 buf_output0 (buf_to_net, dir);
4700 buf_append_char (buf_to_net, '\n');
4704 for (i = 1; i < argc; ++i)
4706 buf_output0 (buf_to_net, "Module-expansion ");
4707 if (server_dir != NULL)
4709 buf_output0 (buf_to_net, server_dir);
4710 buf_output0 (buf_to_net, "/");
4712 buf_output0 (buf_to_net, dir);
4713 buf_append_char (buf_to_net, '/');
4714 buf_output0 (buf_to_net, argv[i]);
4715 buf_append_char (buf_to_net, '\n');
4723 serve_expand_modules (arg)
4731 db = open_module ();
4732 for (i = 1; i < argument_count; i++)
4733 err += do_module (db, argument_vector[i],
4734 CHECKOUT, "Updating", expand_proc,
4739 /* argument_vector[0] is a dummy argument, we don't mess with it. */
4741 for (cp = argument_vector + 1;
4742 cp < argument_vector + argument_count;
4749 /* We will have printed an error message already. */
4750 buf_output0 (buf_to_net, "error \n");
4752 buf_output0 (buf_to_net, "ok\n");
4754 /* The client is waiting for the module expansions, so we must
4755 send the output now. */
4756 buf_flush (buf_to_net, 1);
4761 static void serve_valid_requests PROTO((char *arg));
4763 #endif /* SERVER_SUPPORT */
4764 #if defined(SERVER_SUPPORT) || defined(CLIENT_SUPPORT)
4767 * Parts of this table are shared with the client code,
4768 * but the client doesn't need to know about the handler
4772 struct request requests[] =
4774 #ifdef SERVER_SUPPORT
4775 #define REQ_LINE(n, f, s) {n, f, s}
4777 #define REQ_LINE(n, f, s) {n, s}
4780 REQ_LINE("Root", serve_root, RQ_ESSENTIAL | RQ_ROOTLESS),
4781 REQ_LINE("Valid-responses", serve_valid_responses,
4782 RQ_ESSENTIAL | RQ_ROOTLESS),
4783 REQ_LINE("valid-requests", serve_valid_requests,
4784 RQ_ESSENTIAL | RQ_ROOTLESS),
4785 REQ_LINE("Repository", serve_repository, 0),
4786 REQ_LINE("Directory", serve_directory, RQ_ESSENTIAL),
4787 REQ_LINE("Max-dotdot", serve_max_dotdot, 0),
4788 REQ_LINE("Static-directory", serve_static_directory, 0),
4789 REQ_LINE("Sticky", serve_sticky, 0),
4790 REQ_LINE("Entry", serve_entry, RQ_ESSENTIAL),
4791 REQ_LINE("Kopt", serve_kopt, 0),
4792 REQ_LINE("Checkin-time", serve_checkin_time, 0),
4793 REQ_LINE("Modified", serve_modified, RQ_ESSENTIAL),
4794 REQ_LINE("Is-modified", serve_is_modified, 0),
4796 /* The client must send this request to interoperate with CVS 1.5
4797 through 1.9 servers. The server must support it (although it can
4798 be and is a noop) to interoperate with CVS 1.5 to 1.9 clients. */
4799 REQ_LINE("UseUnchanged", serve_enable_unchanged, RQ_ENABLEME | RQ_ROOTLESS),
4801 REQ_LINE("Unchanged", serve_unchanged, RQ_ESSENTIAL),
4802 REQ_LINE("Notify", serve_notify, 0),
4803 REQ_LINE("Questionable", serve_questionable, 0),
4804 REQ_LINE("Argument", serve_argument, RQ_ESSENTIAL),
4805 REQ_LINE("Argumentx", serve_argumentx, RQ_ESSENTIAL),
4806 REQ_LINE("Global_option", serve_global_option, RQ_ROOTLESS),
4807 REQ_LINE("Gzip-stream", serve_gzip_stream, 0),
4808 REQ_LINE("wrapper-sendme-rcsOptions",
4809 serve_wrapper_sendme_rcs_options,
4811 REQ_LINE("Set", serve_set, RQ_ROOTLESS),
4813 # ifdef HAVE_KERBEROS
4814 REQ_LINE("Kerberos-encrypt", serve_kerberos_encrypt, 0),
4817 REQ_LINE("Gssapi-encrypt", serve_gssapi_encrypt, 0),
4821 REQ_LINE("Gssapi-authenticate", serve_gssapi_authenticate, 0),
4823 REQ_LINE("expand-modules", serve_expand_modules, 0),
4824 REQ_LINE("ci", serve_ci, RQ_ESSENTIAL),
4825 REQ_LINE("co", serve_co, RQ_ESSENTIAL),
4826 REQ_LINE("update", serve_update, RQ_ESSENTIAL),
4827 REQ_LINE("diff", serve_diff, 0),
4828 REQ_LINE("log", serve_log, 0),
4829 REQ_LINE("rlog", serve_rlog, 0),
4830 REQ_LINE("add", serve_add, 0),
4831 REQ_LINE("remove", serve_remove, 0),
4832 REQ_LINE("update-patches", serve_ignore, 0),
4833 REQ_LINE("gzip-file-contents", serve_gzip_contents, 0),
4834 REQ_LINE("status", serve_status, 0),
4835 REQ_LINE("rdiff", serve_rdiff, 0),
4836 REQ_LINE("tag", serve_tag, 0),
4837 REQ_LINE("rtag", serve_rtag, 0),
4838 REQ_LINE("import", serve_import, 0),
4839 REQ_LINE("admin", serve_admin, 0),
4840 REQ_LINE("export", serve_export, 0),
4841 REQ_LINE("history", serve_history, 0),
4842 REQ_LINE("release", serve_release, 0),
4843 REQ_LINE("watch-on", serve_watch_on, 0),
4844 REQ_LINE("watch-off", serve_watch_off, 0),
4845 REQ_LINE("watch-add", serve_watch_add, 0),
4846 REQ_LINE("watch-remove", serve_watch_remove, 0),
4847 REQ_LINE("watchers", serve_watchers, 0),
4848 REQ_LINE("editors", serve_editors, 0),
4849 REQ_LINE("init", serve_init, RQ_ROOTLESS),
4850 REQ_LINE("annotate", serve_annotate, 0),
4851 REQ_LINE("rannotate", serve_rannotate, 0),
4852 REQ_LINE("noop", serve_noop, RQ_ROOTLESS),
4853 REQ_LINE("version", serve_version, RQ_ROOTLESS),
4854 REQ_LINE(NULL, NULL, 0)
4859 #endif /* SERVER_SUPPORT or CLIENT_SUPPORT */
4860 #ifdef SERVER_SUPPORT
4863 serve_valid_requests (arg)
4867 if (print_pending_error ())
4869 buf_output0 (buf_to_net, "Valid-requests");
4870 for (rq = requests; rq->name != NULL; rq++)
4872 if (rq->func != NULL)
4874 buf_append_char (buf_to_net, ' ');
4875 buf_output0 (buf_to_net, rq->name);
4878 buf_output0 (buf_to_net, "\nok\n");
4880 /* The client is waiting for the list of valid requests, so we
4881 must send the output now. */
4882 buf_flush (buf_to_net, 1);
4887 * Delete temporary files. SIG is the signal making this happen, or
4888 * 0 if not called as a result of a signal.
4890 static int command_pid_is_dead;
4891 static void wait_sig (sig)
4895 pid_t r = wait (&status);
4896 if (r == command_pid)
4897 command_pid_is_dead++;
4899 #endif /* SUNOS_KLUDGE */
4902 server_cleanup (sig)
4905 /* Do "rm -rf" on the temp directory. */
4909 if (buf_to_net != NULL)
4911 /* Since we're done, go ahead and put BUF_TO_NET back into blocking
4912 * mode and send any pending output. In the usual case there won't
4913 * won't be any, but there might be if an error occured.
4916 set_block (buf_to_net);
4917 buf_flush (buf_to_net, 1);
4919 /* Next we shut down BUF_FROM_NET. That will pick up the checksum
4920 * generated when the client shuts down its buffer. Then, after we
4921 * have generated any final output, we shut down BUF_TO_NET.
4924 if (buf_from_net != NULL)
4926 status = buf_shutdown (buf_from_net);
4928 error (0, status, "shutting down buffer from client");
4929 buf_free (buf_from_net);
4930 buf_from_net = NULL;
4933 if (dont_delete_temp)
4935 (void) buf_flush (buf_to_net, 1);
4936 (void) buf_shutdown (buf_to_net);
4937 buf_free (buf_to_net);
4939 error_use_protocol = 0;
4943 else if (dont_delete_temp)
4946 /* What a bogus kludge. This disgusting code makes all kinds of
4947 assumptions about SunOS, and is only for a bug in that system.
4948 So only enable it on Suns. */
4950 if (command_pid > 0)
4952 /* To avoid crashes on SunOS due to bugs in SunOS tmpfs
4953 triggered by the use of rename() in RCS, wait for the
4954 subprocess to die. Unfortunately, this means draining output
4955 while waiting for it to unblock the signal we sent it. Yuck! */
4959 signal (SIGCHLD, wait_sig);
4961 /* Perhaps SIGTERM would be more correct. But the child
4962 process will delay the SIGINT delivery until its own
4963 children have exited. */
4964 kill (command_pid, SIGINT);
4965 /* The caller may also have sent a signal to command_pid, so
4966 always try waiting. First, though, check and see if it's still
4969 r = waitpid (command_pid, &status, WNOHANG);
4972 else if (r == command_pid)
4973 command_pid_is_dead++;
4978 command_pid_is_dead++;
4984 /* waitpid should always return one of the above values */
4986 while (!command_pid_is_dead)
4988 struct timeval timeout;
4989 struct fd_set_wrapper readfds;
4993 /* Use a non-zero timeout to avoid eating up CPU cycles. */
4995 timeout.tv_usec = 0;
4996 readfds = command_fds_to_drain;
4997 switch (select (max_command_fd + 1, &readfds.fds,
4998 (fd_set *)0, (fd_set *)0,
5008 for (i = 0; i <= max_command_fd; i++)
5010 if (!FD_ISSET (i, &readfds.fds))
5012 /* this fd is non-blocking */
5013 while (read (i, buf, sizeof (buf)) >= 1)
5022 #endif /* SUNOS_KLUDGE */
5025 /* Temporarily clear noexec, so that we clean up our temp directory
5026 regardless of it (this could more cleanly be handled by moving
5027 the noexec check to all the unlink_file_dir callers from
5028 unlink_file_dir itself). */
5029 save_noexec = noexec;
5031 /* FIXME? Would be nice to not ignore errors. But what should we do?
5032 We could try to do this before we shut down the network connection,
5033 and try to notify the client (but the client might not be waiting
5034 for responses). We could try something like syslog() or our own
5036 unlink_file_dir (orig_server_temp_dir);
5037 noexec = save_noexec;
5039 if (buf_to_net != NULL)
5041 (void) buf_flush (buf_to_net, 1);
5042 (void) buf_shutdown (buf_to_net);
5043 buf_free (buf_to_net);
5045 error_use_protocol = 0;
5049 int server_active = 0;
5056 char *error_prog_name; /* Used in error messages */
5060 static const char *const msg[] =
5063 " Normally invoked by a cvs client on a remote machine.\n",
5068 /* Ignore argc and argv. They might be from .cvsrc. */
5070 buf_to_net = fd_buffer_initialize (STDOUT_FILENO, 0,
5071 outbuf_memory_error);
5072 buf_from_net = stdio_buffer_initialize (stdin, 0, 1, outbuf_memory_error);
5074 saved_output = buf_nonio_initialize (outbuf_memory_error);
5075 saved_outerr = buf_nonio_initialize (outbuf_memory_error);
5077 /* Since we're in the server parent process, error should use the
5078 protocol to report error messages. */
5079 error_use_protocol = 1;
5081 /* OK, now figure out where we stash our temporary files. */
5085 /* The code which wants to chdir into server_temp_dir is not set
5086 up to deal with it being a relative path. So give an error
5088 if (!isabsolute (Tmpdir))
5090 if (alloc_pending (80 + strlen (Tmpdir)))
5091 sprintf (pending_error_text,
5092 "E Value of %s for TMPDIR is not absolute", Tmpdir);
5094 /* FIXME: we would like this error to be persistent, that
5095 is, not cleared by print_pending_error. The current client
5096 will exit as soon as it gets an error, but the protocol spec
5097 does not require a client to do so. */
5104 server_temp_dir = xmalloc (strlen (Tmpdir) + 80);
5105 if (server_temp_dir == NULL)
5108 * Strictly speaking, we're not supposed to output anything
5109 * now. But we're about to exit(), give it a try.
5111 printf ("E Fatal server error, aborting.\n\
5112 error ENOMEM Virtual memory exhausted.\n");
5116 strcpy (server_temp_dir, Tmpdir);
5118 /* Remove a trailing slash from TMPDIR if present. */
5119 p = server_temp_dir + strlen (server_temp_dir) - 1;
5124 * I wanted to use cvs-serv/PID, but then you have to worry about
5125 * the permissions on the cvs-serv directory being right. So
5128 strcat (server_temp_dir, "/cvs-serv");
5130 p = server_temp_dir + strlen (server_temp_dir);
5131 sprintf (p, "%ld", (long) getpid ());
5133 orig_server_temp_dir = server_temp_dir;
5135 /* Create the temporary directory, and set the mode to
5136 700, to discourage random people from tampering with
5138 while ((status = mkdir_p (server_temp_dir)) == EEXIST)
5140 static const char suffix[] = "abcdefghijklmnopqrstuvwxyz";
5142 if (i >= sizeof suffix - 1) break;
5143 if (i == 0) p = server_temp_dir + strlen (server_temp_dir);
5149 if (alloc_pending (80 + strlen (server_temp_dir)))
5150 sprintf (pending_error_text,
5151 "E can't create temporary directory %s",
5153 pending_error = status;
5155 #ifndef CHMOD_BROKEN
5156 else if (chmod (server_temp_dir, S_IRWXU) < 0)
5158 int save_errno = errno;
5159 if (alloc_pending (80 + strlen (server_temp_dir)))
5160 sprintf (pending_error_text,
5161 "E cannot change permissions on temporary directory %s",
5163 pending_error = save_errno;
5166 else if (CVS_CHDIR (server_temp_dir) < 0)
5168 int save_errno = errno;
5169 if (alloc_pending (80 + strlen (server_temp_dir)))
5170 sprintf (pending_error_text,
5171 "E cannot change to temporary directory %s",
5173 pending_error = save_errno;
5178 /* Now initialize our argument vector (for arguments from the client). */
5180 /* Small for testing. */
5181 argument_vector_size = 1;
5182 argument_vector = xmalloc (argument_vector_size * sizeof (char *));
5184 /* This gets printed if the client supports an option which the
5185 server doesn't, causing the server to print a usage message.
5186 FIXME: just a nit, I suppose, but the usage message the server
5187 prints isn't literally true--it suggests "cvs server" followed
5188 by options which are for a particular command. Might be nice to
5189 say something like "client apparently supports an option not supported
5190 by this server" or something like that instead of usage message. */
5191 error_prog_name = xmalloc (strlen (program_name) + 8);
5192 sprintf(error_prog_name, "%s server", program_name);
5193 argument_vector[0] = error_prog_name;
5197 char *cmd, *orig_cmd;
5201 status = buf_read_line (buf_from_net, &cmd, NULL);
5204 buf_output0 (buf_to_net, "E Fatal server error, aborting.\n\
5205 error ENOMEM Virtual memory exhausted.\n");
5212 for (rq = requests; rq->name != NULL; ++rq)
5213 if (strncmp (cmd, rq->name, strlen (rq->name)) == 0)
5215 int len = strlen (rq->name);
5216 if (cmd[len] == '\0')
5218 else if (cmd[len] == ' ')
5222 * The first len characters match, but it's a different
5223 * command. e.g. the command is "cooperate" but we matched
5228 if (!(rq->flags & RQ_ROOTLESS)
5229 && current_parsed_root == NULL)
5231 /* For commands which change the way in which data
5232 is sent and received, for example Gzip-stream,
5233 this does the wrong thing. Since the client
5234 assumes that everything is being compressed,
5235 unconditionally, there is no way to give this
5236 error to the client without turning on
5237 compression. The obvious fix would be to make
5238 Gzip-stream RQ_ROOTLESS (with the corresponding
5239 change to the spec), and that might be a good
5240 idea but then again I can see some settings in
5241 CVSROOT about what compression level to allow.
5242 I suppose a more baroque answer would be to
5243 turn on compression (say, at level 1), just
5244 enough to give the "Root request missing"
5245 error. For now we just lose. */
5246 if (alloc_pending (80))
5247 sprintf (pending_error_text,
5248 "E Protocol error: Root request missing");
5254 if (rq->name == NULL)
5256 if (!print_pending_error ())
5258 buf_output0 (buf_to_net, "error unrecognized request `");
5259 buf_output0 (buf_to_net, cmd);
5260 buf_append_char (buf_to_net, '\'');
5261 buf_append_char (buf_to_net, '\n');
5266 free (error_prog_name);
5268 /* We expect the client is done talking to us at this point. If there is
5269 * any data in the buffer or on the network pipe, then something we didn't
5270 * prepare for is happening.
5272 if (!buf_empty (buf_from_net))
5274 /* Try to send the error message to the client, but also syslog it, in
5275 * case the client isn't listening anymore.
5277 #ifdef HAVE_SYSLOG_H
5278 /* FIXME: Can the IP address of the connecting client be retrieved
5281 syslog (LOG_DAEMON | LOG_ERR, "Dying gasps received from client.");
5283 error (0, 0, "Dying gasps received from client.");
5286 /* This command will actually close the network buffers. */
5293 #if defined (HAVE_KERBEROS) || defined (AUTH_SERVER_SUPPORT) || defined (HAVE_GSSAPI)
5294 static void switch_to_user PROTO((const char *, const char *));
5297 switch_to_user (cvs_username, username)
5298 const char *cvs_username; /* Only used for error messages. */
5299 const char *username;
5303 pw = getpwnam (username);
5306 /* check_password contains a similar check, so this usually won't be
5307 reached unless the CVS user is mapped to an invalid system user. */
5309 printf ("E Fatal error, aborting.\n\
5310 error 0 %s: no such system user\n", username);
5311 /* Don't worry about server_cleanup; server_active isn't set yet. */
5315 if (pw->pw_uid == 0)
5317 #ifdef HAVE_SYSLOG_H
5318 /* FIXME: Can the IP address of the connecting client be retrieved
5321 syslog (LOG_DAEMON | LOG_ALERT,
5322 "attempt to root from account: %s", cvs_username
5325 printf("error 0: root not allowed\n");
5330 if (initgroups (pw->pw_name, pw->pw_gid) < 0
5332 /* At least on the system I tried, initgroups() only works as root.
5333 But we do still want to report ENOMEM and whatever other
5334 errors initgroups() might dish up. */
5339 /* This could be a warning, but I'm not sure I see the point
5340 in doing that instead of an error given that it would happen
5341 on every connection. We could log it somewhere and not tell
5342 the user. But at least for now make it an error. */
5343 printf ("error 0 initgroups failed: %s\n", strerror (errno));
5344 /* Don't worry about server_cleanup; server_active isn't set yet. */
5347 #endif /* HAVE_INITGROUPS */
5349 #ifdef SETXID_SUPPORT
5350 /* honor the setgid bit iff set*/
5351 if (getgid() != getegid())
5353 if (setgid (getegid ()) < 0)
5355 /* See comments at setuid call below for more discussion. */
5356 printf ("error 0 setgid failed: %s\n", strerror (errno));
5357 /* Don't worry about server_cleanup;
5358 server_active isn't set yet. */
5365 if (setgid (pw->pw_gid) < 0)
5367 /* See comments at setuid call below for more discussion. */
5368 printf ("error 0 setgid failed: %s\n", strerror (errno));
5369 #ifdef HAVE_SYSLOG_H
5370 syslog (LOG_DAEMON | LOG_ERR,
5371 "setgid to %d failed (%m): real %d/%d, effective %d/%d ",
5372 pw->pw_gid, getuid(), getgid(), geteuid(), getegid());
5374 /* Don't worry about server_cleanup;
5375 server_active isn't set yet. */
5380 if (setuid (pw->pw_uid) < 0)
5382 /* Note that this means that if run as a non-root user,
5383 CVSROOT/passwd must contain the user we are running as
5384 (e.g. "joe:FsEfVcu:cvs" if run as "cvs" user). This seems
5385 cleaner than ignoring the error like CVS 1.10 and older but
5386 it does mean that some people might need to update their
5387 CVSROOT/passwd file. */
5388 printf ("error 0 setuid failed: %s\n", strerror (errno));
5389 #ifdef HAVE_SYSLOG_H
5390 syslog (LOG_DAEMON | LOG_ERR,
5391 "setuid to %d failed (%m): real %d/%d, effective %d/%d ",
5392 pw->pw_uid, getuid(), getgid(), geteuid(), getegid());
5394 /* Don't worry about server_cleanup; server_active isn't set yet. */
5398 /* We don't want our umask to change file modes. The modes should
5399 be set by the modes used in the repository, and by the umask of
5403 #ifdef AUTH_SERVER_SUPPORT
5404 /* Make sure our CVS_Username has been set. */
5405 if (CVS_Username == NULL)
5406 CVS_Username = xstrdup (username);
5410 /* Set LOGNAME, USER and CVS_USER in the environment, in case they
5411 are already set to something else. */
5415 env = xmalloc (sizeof "LOGNAME=" + strlen (username));
5416 (void) sprintf (env, "LOGNAME=%s", username);
5417 (void) putenv (env);
5419 env = xmalloc (sizeof "USER=" + strlen (username));
5420 (void) sprintf (env, "USER=%s", username);
5421 (void) putenv (env);
5423 #ifdef AUTH_SERVER_SUPPORT
5424 env = xmalloc (sizeof "CVS_USER=" + strlen (CVS_Username));
5425 (void) sprintf (env, "CVS_USER=%s", CVS_Username);
5426 (void) putenv (env);
5429 #endif /* HAVE_PUTENV */
5433 #ifdef AUTH_SERVER_SUPPORT
5435 extern char *crypt PROTO((const char *, const char *));
5439 * 0 means no entry found for this user.
5440 * 1 means entry found and password matches (or found password is empty)
5441 * 2 means entry found, but password does not match.
5443 * If 1, host_user_ptr will be set to point at the system
5444 * username (i.e., the "real" identity, which may or may not be the
5445 * CVS username) of this user; caller may free this. Global
5446 * CVS_Username will point at an allocated copy of cvs username (i.e.,
5447 * the username argument below).
5448 * kff todo: FIXME: last sentence is not true, it applies to caller.
5451 check_repository_password (username, password, repository, host_user_ptr)
5452 char *username, *password, *repository, **host_user_ptr;
5457 char *linebuf = NULL;
5462 /* We don't use current_parsed_root->directory because it hasn't been
5463 * set yet -- our `repository' argument came from the authentication
5464 * protocol, not the regular CVS protocol.
5467 filename = xmalloc (strlen (repository)
5469 + strlen (CVSROOTADM)
5471 + strlen (CVSROOTADM_PASSWD)
5474 (void) sprintf (filename, "%s/%s/%s", repository,
5475 CVSROOTADM, CVSROOTADM_PASSWD);
5477 fp = CVS_FOPEN (filename, "r");
5480 if (!existence_error (errno))
5481 error (0, errno, "cannot open %s", filename);
5485 /* Look for a relevant line -- one with this user's name. */
5486 namelen = strlen (username);
5487 while (getline (&linebuf, &linebuf_len, fp) >= 0)
5489 if ((strncmp (linebuf, username, namelen) == 0)
5490 && (linebuf[namelen] == ':'))
5497 error (0, errno, "cannot read %s", filename);
5498 if (fclose (fp) < 0)
5499 error (0, errno, "cannot close %s", filename);
5501 /* If found_it, then linebuf contains the information we need. */
5504 char *found_password, *host_user_tmp;
5505 char *non_cvsuser_portion;
5507 /* We need to make sure lines such as
5509 * "username::sysuser\n"
5513 * all result in a found_password of NULL, but we also need to
5516 * "username: :sysuser\n"
5517 * "username: <whatever>:sysuser\n"
5519 * continues to result in an impossible password. That way,
5520 * an admin would be on safe ground by going in and tacking a
5521 * space onto the front of a password to disable the account
5522 * (a technique some people use to close accounts
5526 /* Make `non_cvsuser_portion' contain everything after the CVS
5527 username, but null out any final newline. */
5528 non_cvsuser_portion = linebuf + namelen;
5529 strtok (non_cvsuser_portion, "\n");
5531 /* If there's a colon now, we just want to inch past it. */
5532 if (strchr (non_cvsuser_portion, ':') == non_cvsuser_portion)
5533 non_cvsuser_portion++;
5535 /* Okay, after this conditional chain, found_password and
5536 host_user_tmp will have useful values: */
5538 if ((non_cvsuser_portion == NULL)
5539 || (strlen (non_cvsuser_portion) == 0)
5540 || ((strspn (non_cvsuser_portion, " \t"))
5541 == strlen (non_cvsuser_portion)))
5543 found_password = NULL;
5544 host_user_tmp = NULL;
5546 else if (strncmp (non_cvsuser_portion, ":", 1) == 0)
5548 found_password = NULL;
5549 host_user_tmp = non_cvsuser_portion + 1;
5550 if (strlen (host_user_tmp) == 0)
5551 host_user_tmp = NULL;
5555 found_password = strtok (non_cvsuser_portion, ":");
5556 host_user_tmp = strtok (NULL, ":");
5559 /* Of course, maybe there was no system user portion... */
5560 if (host_user_tmp == NULL)
5561 host_user_tmp = username;
5563 /* Verify blank passwords directly, otherwise use crypt(). */
5564 if ((found_password == NULL)
5565 || ((strcmp (found_password, crypt (password, found_password))
5568 /* Give host_user_ptr permanent storage. */
5569 *host_user_ptr = xstrdup (host_user_tmp);
5575 syslog (LOG_AUTHPRIV | LOG_NOTICE,
5576 "password mismatch for %s in %s: %s vs. %s", username,
5577 repository, crypt(password, found_password), found_password);
5579 *host_user_ptr = NULL;
5583 else /* Didn't find this user, so deny access. */
5585 *host_user_ptr = NULL;
5598 /* Return a hosting username if password matches, else NULL. */
5600 check_password (username, password, repository)
5601 char *username, *password, *repository;
5604 char *host_user = NULL;
5605 char *found_passwd = NULL;
5608 /* First we see if this user has a password in the CVS-specific
5609 password file. If so, that's enough to authenticate with. If
5610 not, we'll check /etc/passwd. */
5612 if (require_real_user)
5613 rc = 0; /* "not found" */
5615 rc = check_repository_password (username, password, repository,
5623 /* host_user already set by reference, so just return. */
5631 /* Note that the message _does_ distinguish between the case in
5632 which we check for a system password and the case in which
5633 we do not. It is a real pain to track down why it isn't
5634 letting you in if it won't say why, and I am not convinced
5635 that the potential information disclosure to an attacker
5637 printf ("error 0 no such user %s in CVSROOT/passwd\n", username);
5642 /* No cvs password found, so try /etc/passwd. */
5644 #ifdef HAVE_GETSPNAM
5648 spw = getspnam (username);
5651 found_passwd = spw->sp_pwdp;
5656 if (found_passwd == NULL && (pw = getpwnam (username)) != NULL)
5658 found_passwd = pw->pw_passwd;
5661 if (found_passwd == NULL)
5663 printf ("E Fatal error, aborting.\n\
5664 error 0 %s: no such user\n", username);
5669 /* Allow for dain bramaged HPUX passwd aging
5670 * - Basically, HPUX adds a comma and some data
5671 * about whether the passwd has expired or not
5672 * on the end of the passwd field.
5673 * - This code replaces the ',' with '\0'.
5675 * FIXME - our workaround is brain damaged too. I'm
5676 * guessing that HPUX WANTED other systems to think the
5677 * password was wrong so logins would fail if the
5678 * system didn't handle expired passwds and the passwd
5679 * might be expired. I think the way to go here
5682 strtok (found_passwd, ",");
5686 /* user exists and has a password */
5687 if (strcmp (found_passwd, crypt (password, found_passwd)) == 0)
5689 host_user = xstrdup (username);
5695 syslog (LOG_AUTHPRIV | LOG_NOTICE,
5696 "password mismatch for %s: %s vs. %s", username,
5697 crypt(password, found_passwd), found_passwd);
5703 if (password && *password)
5705 /* user exists and has no system password, but we got
5707 host_user = xstrdup (username);
5711 /* user exists but has no password at all */
5714 syslog (LOG_AUTHPRIV | LOG_NOTICE,
5715 "login refused for %s: user has no password", username);
5721 /* Set CVS_Username here, in allocated space.
5722 It might or might not be the same as host_user. */
5723 CVS_Username = xmalloc (strlen (username) + 1);
5724 strcpy (CVS_Username, username);
5730 #endif /* AUTH_SERVER_SUPPORT */
5732 #if defined (AUTH_SERVER_SUPPORT) || defined (HAVE_GSSAPI)
5734 /* Read username and password from client (i.e., stdin).
5735 If correct, then switch to run as that user and send an ACK to the
5736 client via stdout, else send NACK and die. */
5738 pserver_authenticate_connection ()
5741 size_t tmp_allocated = 0;
5742 #ifdef AUTH_SERVER_SUPPORT
5743 char *repository = NULL;
5744 size_t repository_allocated = 0;
5745 char *username = NULL;
5746 size_t username_allocated = 0;
5747 char *password = NULL;
5748 size_t password_allocated = 0;
5751 char *descrambled_password;
5752 #endif /* AUTH_SERVER_SUPPORT */
5753 int verify_and_exit = 0;
5755 /* The Authentication Protocol. Client sends:
5757 * BEGIN AUTH REQUEST\n
5761 * END AUTH REQUEST\n
5763 * Server uses above information to authenticate, then sends
5767 * if it grants access, else
5771 * if it denies access (and it exits if denying).
5773 * When the client is "cvs login", the user does not desire actual
5774 * repository access, but would like to confirm the password with
5775 * the server. In this case, the start and stop strings are
5777 * BEGIN VERIFICATION REQUEST\n
5781 * END VERIFICATION REQUEST\n
5783 * On a verification request, the server's responses are the same
5784 * (with the obvious semantics), but it exits immediately after
5785 * sending the response in both cases.
5787 * Why is the repository sent? Well, note that the actual
5788 * client/server protocol can't start up until authentication is
5789 * successful. But in order to perform authentication, the server
5790 * needs to look up the password in the special CVS passwd file,
5791 * before trying /etc/passwd. So the client transmits the
5792 * repository as part of the "authentication protocol". The
5793 * repository will be redundantly retransmitted later, but that's no
5798 /* Set SO_KEEPALIVE on the socket, so that we don't hang forever
5799 if the client dies while we are waiting for input. */
5803 if (setsockopt (STDIN_FILENO, SOL_SOCKET, SO_KEEPALIVE,
5804 (char *) &on, sizeof on) < 0)
5806 #ifdef HAVE_SYSLOG_H
5807 syslog (LOG_DAEMON | LOG_ERR, "error setting KEEPALIVE: %m");
5813 /* Make sure the protocol starts off on the right foot... */
5814 if (getline_safe (&tmp, &tmp_allocated, stdin, PATH_MAX) < 0)
5816 #ifdef HAVE_SYSLOG_H
5817 syslog (LOG_DAEMON | LOG_NOTICE, "bad auth protocol start: EOF");
5819 error (1, 0, "bad auth protocol start: EOF");
5822 if (strcmp (tmp, "BEGIN VERIFICATION REQUEST\n") == 0)
5823 verify_and_exit = 1;
5824 else if (strcmp (tmp, "BEGIN AUTH REQUEST\n") == 0)
5826 else if (strcmp (tmp, "BEGIN GSSAPI REQUEST\n") == 0)
5830 gserver_authenticate_connection ();
5833 error (1, 0, "GSSAPI authentication not supported by this server");
5837 error (1, 0, "bad auth protocol start: %s", tmp);
5839 #ifndef AUTH_SERVER_SUPPORT
5841 error (1, 0, "Password authentication not supported by this server");
5843 #else /* AUTH_SERVER_SUPPORT */
5845 /* Get the three important pieces of information in order. */
5846 /* See above comment about error handling. */
5847 getline_safe (&repository, &repository_allocated, stdin, PATH_MAX);
5848 getline_safe (&username, &username_allocated, stdin, PATH_MAX);
5849 getline_safe (&password, &password_allocated, stdin, PATH_MAX);
5853 * We check that none of the lines were truncated by getnline in order
5854 * to be sure that we don't accidentally allow a blind DOS attack to
5855 * authenticate, however slim the odds of that might be.
5857 if (!strip_trailing_newlines (repository)
5858 || !strip_trailing_newlines (username)
5859 || !strip_trailing_newlines (password))
5860 error (1, 0, "Maximum line length exceeded during authentication.");
5862 /* ... and make sure the protocol ends on the right foot. */
5863 /* See above comment about error handling. */
5864 getline_safe (&tmp, &tmp_allocated, stdin, PATH_MAX);
5867 "END VERIFICATION REQUEST\n" : "END AUTH REQUEST\n")
5870 error (1, 0, "bad auth protocol end: %s", tmp);
5872 if (!root_allow_ok (repository))
5874 printf ("error 0 %s: no such repository\n", repository);
5875 #ifdef HAVE_SYSLOG_H
5876 syslog (LOG_DAEMON | LOG_NOTICE, "login refused for %s", repository);
5881 /* OK, now parse the config file, so we can use it to control how
5882 to check passwords. If there was an error parsing the config
5883 file, parse_config already printed an error. We keep going.
5884 Why? Because if we didn't, then there would be no way to check
5885 in a new CVSROOT/config file to fix the broken one! */
5886 parse_config (repository);
5888 /* We need the real cleartext before we hash it. */
5889 descrambled_password = descramble (password);
5890 host_user = check_password (username, descrambled_password, repository);
5891 if (host_user == NULL)
5893 #ifdef HAVE_SYSLOG_H
5894 syslog (LOG_DAEMON | LOG_NOTICE, "login failure (for %s)", repository);
5896 memset (descrambled_password, 0, strlen (descrambled_password));
5897 free (descrambled_password);
5899 printf ("I HATE YOU\n");
5902 /* Don't worry about server_cleanup, server_active isn't set
5906 memset (descrambled_password, 0, strlen (descrambled_password));
5907 free (descrambled_password);
5909 /* Don't go any farther if we're just responding to "cvs login". */
5910 if (verify_and_exit)
5912 printf ("I LOVE YOU\n");
5915 #ifdef SYSTEM_CLEANUP
5916 /* Hook for OS-specific behavior, for example socket subsystems on
5917 NT and OS2 or dealing with windows and arguments on Mac. */
5924 /* Set Pserver_Repos so that we can check later that the same
5925 repository is sent in later client/server protocol. */
5926 Pserver_Repos = xmalloc (strlen (repository) + 1);
5927 strcpy (Pserver_Repos, repository);
5929 /* Switch to run as this user. */
5930 switch_to_user (username, host_user);
5937 printf ("I LOVE YOU\n");
5939 #endif /* AUTH_SERVER_SUPPORT */
5942 #endif /* AUTH_SERVER_SUPPORT || HAVE_GSSAPI */
5945 #ifdef HAVE_KERBEROS
5947 kserver_authenticate_connection ()
5950 char instance[INST_SZ];
5951 struct sockaddr_in peer;
5952 struct sockaddr_in laddr;
5956 char version[KRB_SENDAUTH_VLEN];
5957 char user[ANAME_SZ];
5959 strcpy (instance, "*");
5961 if (getpeername (STDIN_FILENO, (struct sockaddr *) &peer, &len) < 0
5962 || getsockname (STDIN_FILENO, (struct sockaddr *) &laddr,
5965 printf ("E Fatal error, aborting.\n\
5966 error %s getpeername or getsockname failed\n", strerror (errno));
5972 /* Set SO_KEEPALIVE on the socket, so that we don't hang forever
5973 if the client dies while we are waiting for input. */
5977 if (setsockopt (STDIN_FILENO, SOL_SOCKET, SO_KEEPALIVE,
5978 (char *) &on, sizeof on) < 0)
5980 #ifdef HAVE_SYSLOG_H
5981 syslog (LOG_DAEMON | LOG_ERR, "error setting KEEPALIVE: %m");
5987 status = krb_recvauth (KOPT_DO_MUTUAL, STDIN_FILENO, &ticket, "rcmd",
5988 instance, &peer, &laddr, &auth, "", sched,
5990 if (status != KSUCCESS)
5992 printf ("E Fatal error, aborting.\n\
5993 error 0 kerberos: %s\n", krb_get_err_text(status));
5998 memcpy (kblock, auth.session, sizeof (C_Block));
6000 /* Get the local name. */
6001 status = krb_kntoln (&auth, user);
6002 if (status != KSUCCESS)
6004 printf ("E Fatal error, aborting.\n\
6005 error 0 kerberos: can't get local name: %s\n", krb_get_err_text(status));
6010 /* Switch to run as this user. */
6011 switch_to_user ("Kerberos 4", user);
6013 #endif /* HAVE_KERBEROS */
6017 #ifndef MAXHOSTNAMELEN
6018 #define MAXHOSTNAMELEN (256)
6021 /* Authenticate a GSSAPI connection. This is called from
6022 pserver_authenticate_connection, and it handles success and failure
6026 gserver_authenticate_connection ()
6028 char hostname[MAXHOSTNAMELEN];
6030 gss_buffer_desc tok_in, tok_out;
6034 OM_uint32 stat_min, ret;
6035 gss_name_t server_name, client_name;
6036 gss_cred_id_t server_creds;
6040 gethostname (hostname, sizeof hostname);
6041 hp = gethostbyname (hostname);
6043 error (1, 0, "can't get canonical hostname");
6045 sprintf (buf, "cvs@%s", hp->h_name);
6047 tok_in.length = strlen (buf);
6049 if (gss_import_name (&stat_min, &tok_in, GSS_C_NT_HOSTBASED_SERVICE,
6050 &server_name) != GSS_S_COMPLETE)
6051 error (1, 0, "could not import GSSAPI service name %s", buf);
6053 /* Acquire the server credential to verify the client's
6055 if (gss_acquire_cred (&stat_min, server_name, 0, GSS_C_NULL_OID_SET,
6056 GSS_C_ACCEPT, &server_creds,
6057 NULL, NULL) != GSS_S_COMPLETE)
6058 error (1, 0, "could not acquire GSSAPI server credentials");
6060 gss_release_name (&stat_min, &server_name);
6062 /* The client will send us a two byte length followed by that many
6064 if (fread (buf, 1, 2, stdin) != 2)
6065 error (1, errno, "read of length failed");
6067 nbytes = ((buf[0] & 0xff) << 8) | (buf[1] & 0xff);
6068 if (nbytes <= sizeof buf)
6071 credbuflen = sizeof buf;
6075 credbuflen = nbytes;
6076 credbuf = xmalloc (credbuflen);
6079 if (fread (credbuf, 1, nbytes, stdin) != nbytes)
6080 error (1, errno, "read of data failed");
6082 gcontext = GSS_C_NO_CONTEXT;
6083 tok_in.length = nbytes;
6084 tok_in.value = credbuf;
6086 if (gss_accept_sec_context (&stat_min,
6087 &gcontext, /* context_handle */
6088 server_creds, /* verifier_cred_handle */
6089 &tok_in, /* input_token */
6090 NULL, /* channel bindings */
6091 &client_name, /* src_name */
6092 &mechid, /* mech_type */
6093 &tok_out, /* output_token */
6095 NULL, /* ignore time_rec */
6096 NULL) /* ignore del_cred_handle */
6099 error (1, 0, "could not verify credentials");
6102 /* FIXME: Use Kerberos v5 specific code to authenticate to a user.
6103 We could instead use an authentication to access mapping. */
6107 gss_buffer_desc desc;
6109 krb5_init_context (&kc);
6110 if (gss_display_name (&stat_min, client_name, &desc,
6111 &mechid) != GSS_S_COMPLETE
6112 || krb5_parse_name (kc, ((gss_buffer_t) &desc)->value, &p) != 0
6113 || krb5_aname_to_localname (kc, p, sizeof buf, buf) != 0
6114 || krb5_kuserok (kc, p, buf) != TRUE)
6116 error (1, 0, "access denied");
6118 krb5_free_principal (kc, p);
6119 krb5_free_context (kc);
6122 if (tok_out.length != 0)
6126 cbuf[0] = (tok_out.length >> 8) & 0xff;
6127 cbuf[1] = tok_out.length & 0xff;
6128 if (fwrite (cbuf, 1, 2, stdout) != 2
6129 || (fwrite (tok_out.value, 1, tok_out.length, stdout)
6131 error (1, errno, "fwrite failed");
6134 switch_to_user ("GSSAPI", buf);
6139 printf ("I LOVE YOU\n");
6143 #endif /* HAVE_GSSAPI */
6145 #endif /* SERVER_SUPPORT */
6147 #if defined (CLIENT_SUPPORT) || defined (SERVER_SUPPORT)
6149 /* This global variable is non-zero if the user requests encryption on
6150 the command line. */
6153 /* This global variable is non-zero if the users requests stream
6154 authentication on the command line. */
6155 int cvsauthenticate;
6159 /* An buffer interface using GSSAPI. This is built on top of a
6160 packetizing buffer. */
6162 /* This structure is the closure field of the GSSAPI translation
6165 struct cvs_gssapi_wrap_data
6167 /* The GSSAPI context. */
6168 gss_ctx_id_t gcontext;
6171 static int cvs_gssapi_wrap_input PROTO((void *, const char *, char *, int));
6172 static int cvs_gssapi_wrap_output PROTO((void *, const char *, char *, int,
6175 /* Create a GSSAPI wrapping buffer. We use a packetizing buffer with
6176 GSSAPI wrapping routines. */
6179 cvs_gssapi_wrap_buffer_initialize (buf, input, gcontext, memory)
6182 gss_ctx_id_t gcontext;
6183 void (*memory) PROTO((struct buffer *));
6185 struct cvs_gssapi_wrap_data *gd;
6187 gd = (struct cvs_gssapi_wrap_data *) xmalloc (sizeof *gd);
6188 gd->gcontext = gcontext;
6190 return (packetizing_buffer_initialize
6192 input ? cvs_gssapi_wrap_input : NULL,
6193 input ? NULL : cvs_gssapi_wrap_output,
6198 /* Unwrap data using GSSAPI. */
6201 cvs_gssapi_wrap_input (fnclosure, input, output, size)
6207 struct cvs_gssapi_wrap_data *gd =
6208 (struct cvs_gssapi_wrap_data *) fnclosure;
6209 gss_buffer_desc inbuf, outbuf;
6213 inbuf.value = (void *) input;
6214 inbuf.length = size;
6216 if (gss_unwrap (&stat_min, gd->gcontext, &inbuf, &outbuf, &conf, NULL)
6219 error (1, 0, "gss_unwrap failed");
6222 if (outbuf.length > size)
6225 memcpy (output, outbuf.value, outbuf.length);
6227 /* The real packet size is stored in the data, so we don't need to
6228 remember outbuf.length. */
6230 gss_release_buffer (&stat_min, &outbuf);
6235 /* Wrap data using GSSAPI. */
6238 cvs_gssapi_wrap_output (fnclosure, input, output, size, translated)
6245 struct cvs_gssapi_wrap_data *gd =
6246 (struct cvs_gssapi_wrap_data *) fnclosure;
6247 gss_buffer_desc inbuf, outbuf;
6251 inbuf.value = (void *) input;
6252 inbuf.length = size;
6255 conf_req = cvs_gssapi_encrypt;
6260 if (gss_wrap (&stat_min, gd->gcontext, conf_req, GSS_C_QOP_DEFAULT,
6261 &inbuf, &conf, &outbuf) != GSS_S_COMPLETE)
6262 error (1, 0, "gss_wrap failed");
6264 /* The packetizing buffer only permits us to add 100 bytes.
6265 FIXME: I don't know what, if anything, is guaranteed by GSSAPI.
6266 This may need to be increased for a different GSSAPI
6267 implementation, or we may need a different algorithm. */
6268 if (outbuf.length > size + 100)
6271 memcpy (output, outbuf.value, outbuf.length);
6273 *translated = outbuf.length;
6275 gss_release_buffer (&stat_min, &outbuf);
6280 #endif /* HAVE_GSSAPI */
6284 #ifdef HAVE_KERBEROS
6286 /* An encryption interface using Kerberos. This is built on top of a
6287 packetizing buffer. */
6289 /* This structure is the closure field of the Kerberos translation
6292 struct krb_encrypt_data
6294 /* The Kerberos key schedule. */
6296 /* The Kerberos DES block. */
6300 static int krb_encrypt_input PROTO((void *, const char *, char *, int));
6301 static int krb_encrypt_output PROTO((void *, const char *, char *, int,
6304 /* Create a Kerberos encryption buffer. We use a packetizing buffer
6305 with Kerberos encryption translation routines. */
6308 krb_encrypt_buffer_initialize (buf, input, sched, block, memory)
6313 void (*memory) PROTO((struct buffer *));
6315 struct krb_encrypt_data *kd;
6317 kd = (struct krb_encrypt_data *) xmalloc (sizeof *kd);
6318 memcpy (kd->sched, sched, sizeof (Key_schedule));
6319 memcpy (kd->block, block, sizeof (C_Block));
6321 return packetizing_buffer_initialize (buf,
6322 input ? krb_encrypt_input : NULL,
6323 input ? NULL : krb_encrypt_output,
6328 /* Decrypt Kerberos data. */
6331 krb_encrypt_input (fnclosure, input, output, size)
6337 struct krb_encrypt_data *kd = (struct krb_encrypt_data *) fnclosure;
6340 des_cbc_encrypt ((C_Block *) input, (C_Block *) output,
6341 size, kd->sched, &kd->block, 0);
6343 /* SIZE is the size of the buffer, which is set by the encryption
6344 routine. The packetizing buffer will arrange for the first two
6345 bytes in the decrypted buffer to be the real (unaligned)
6346 length. As a safety check, make sure that the length in the
6347 buffer corresponds to SIZE. Note that the length in the buffer
6348 is just the length of the data. We must add 2 to account for
6349 the buffer count itself. */
6350 tcount = ((output[0] & 0xff) << 8) + (output[1] & 0xff);
6351 if (((tcount + 2 + 7) & ~7) != size)
6352 error (1, 0, "Decryption failure");
6357 /* Encrypt Kerberos data. */
6360 krb_encrypt_output (fnclosure, input, output, size, translated)
6367 struct krb_encrypt_data *kd = (struct krb_encrypt_data *) fnclosure;
6370 /* For security against a known plaintext attack, we should
6371 initialize any padding bytes to random values. Instead, we
6372 just pick up whatever is on the stack, which is at least better
6375 /* Align SIZE to an 8 byte boundary. Note that SIZE includes the
6376 two byte buffer count at the start of INPUT which was added by
6377 the packetizing buffer. */
6378 aligned = (size + 7) & ~7;
6380 /* We use des_cbc_encrypt rather than krb_mk_priv because the
6381 latter sticks a timestamp in the block, and krb_rd_priv expects
6382 that timestamp to be within five minutes of the current time.
6383 Given the way the CVS server buffers up data, that can easily
6384 fail over a long network connection. We trust krb_recvauth to
6385 guard against a replay attack. */
6387 des_cbc_encrypt ((C_Block *) input, (C_Block *) output, aligned,
6388 kd->sched, &kd->block, 1);
6390 *translated = aligned;
6395 #endif /* HAVE_KERBEROS */
6396 #endif /* ENCRYPTION */
6397 #endif /* defined (CLIENT_SUPPORT) || defined (SERVER_SUPPORT) */
6399 /* Output LEN bytes at STR. If LEN is zero, then output up to (not including)
6400 the first '\0' byte. */
6403 cvs_output (str, len)
6409 #ifdef SERVER_SUPPORT
6410 if (error_use_protocol && buf_to_net != NULL)
6412 buf_output (saved_output, str, len);
6413 buf_copy_lines (buf_to_net, saved_output, 'M');
6415 else if (server_active && protocol != NULL)
6417 buf_output (saved_output, str, len);
6418 buf_copy_lines (protocol, saved_output, 'M');
6419 buf_send_counted (protocol);
6425 size_t to_write = len;
6426 const char *p = str;
6428 /* For symmetry with cvs_outerr we would call fflush (stderr)
6429 here. I guess the assumption is that stderr will be
6430 unbuffered, so we don't need to. That sounds like a sound
6431 assumption from the manpage I looked at, but if there was
6432 something fishy about it, my guess is that calling fflush
6433 would not produce a significant performance problem. */
6435 while (to_write > 0)
6437 written = fwrite (p, 1, to_write, stdout);
6441 to_write -= written;
6446 /* Output LEN bytes at STR in binary mode. If LEN is zero, then
6447 output zero bytes. */
6450 cvs_output_binary (str, len)
6454 #ifdef SERVER_SUPPORT
6455 if (error_use_protocol || server_active)
6460 if (error_use_protocol)
6465 if (!supported_response ("Mbinary"))
6468 this client does not support writing binary files to stdout");
6472 buf_output0 (buf, "Mbinary\012");
6473 sprintf (size_text, "%lu\012", (unsigned long) len);
6474 buf_output0 (buf, size_text);
6476 /* Not sure what would be involved in using buf_append_data here
6477 without stepping on the toes of our caller (which is responsible
6478 for the memory allocation of STR). */
6479 buf_output (buf, str, len);
6481 if (!error_use_protocol)
6482 buf_send_counted (protocol);
6488 size_t to_write = len;
6489 const char *p = str;
6491 /* For symmetry with cvs_outerr we would call fflush (stderr)
6492 here. I guess the assumption is that stderr will be
6493 unbuffered, so we don't need to. That sounds like a sound
6494 assumption from the manpage I looked at, but if there was
6495 something fishy about it, my guess is that calling fflush
6496 would not produce a significant performance problem. */
6497 #ifdef USE_SETMODE_STDOUT
6500 /* It is possible that this should be the same ifdef as
6501 USE_SETMODE_BINARY but at least for the moment we keep them
6502 separate. Mostly this is just laziness and/or a question
6503 of what has been tested where. Also there might be an
6504 issue of setmode vs. _setmode. */
6505 /* The Windows doc says to call setmode only right after startup.
6506 I assume that what they are talking about can also be helped
6507 by flushing the stream before changing the mode. */
6509 oldmode = _setmode (_fileno (stdout), OPEN_BINARY);
6511 error (0, errno, "failed to setmode on stdout");
6514 while (to_write > 0)
6516 written = fwrite (p, 1, to_write, stdout);
6520 to_write -= written;
6522 #ifdef USE_SETMODE_STDOUT
6524 if (_setmode (_fileno (stdout), oldmode) != OPEN_BINARY)
6525 error (0, errno, "failed to setmode on stdout");
6532 /* Like CVS_OUTPUT but output is for stderr not stdout. */
6534 cvs_outerr (str, len)
6540 #ifdef SERVER_SUPPORT
6541 if (error_use_protocol)
6543 buf_output (saved_outerr, str, len);
6544 buf_copy_lines (buf_to_net, saved_outerr, 'E');
6546 else if (server_active)
6548 buf_output (saved_outerr, str, len);
6549 buf_copy_lines (protocol, saved_outerr, 'E');
6550 buf_send_counted (protocol);
6556 size_t to_write = len;
6557 const char *p = str;
6559 /* Make sure that output appears in order if stdout and stderr
6560 point to the same place. For the server case this is taken
6561 care of by the fact that saved_outerr always holds less
6565 while (to_write > 0)
6567 written = fwrite (p, 1, to_write, stderr);
6571 to_write -= written;
6578 /* Flush stderr. stderr is normally flushed automatically, of course,
6579 but this function is used to flush information from the server back
6584 #ifdef SERVER_SUPPORT
6585 if (error_use_protocol)
6587 /* skip the actual stderr flush in this case since the parent process
6588 * on the server should only be writing to stdout anyhow
6590 /* Flush what we can to the network, but don't block. */
6591 buf_flush (buf_to_net, 0);
6593 else if (server_active)
6595 /* make sure stderr is flushed before we send the flush count on the
6599 /* Send a special count to tell the parent to flush. */
6600 buf_send_special_count (protocol, -2);
6609 /* Make it possible for the user to see what has been written to
6610 stdout (it is up to the implementation to decide exactly how far it
6611 should go to ensure this). */
6615 #ifdef SERVER_SUPPORT
6616 if (error_use_protocol)
6618 /* Flush what we can to the network, but don't block. */
6619 buf_flush (buf_to_net, 0);
6621 else if (server_active)
6623 /* Just do nothing. This is because the code which
6624 cvs_flushout replaces, setting stdout to line buffering in
6625 main.c, didn't get called in the server child process. But
6626 in the future it is quite plausible that we'll want to make
6627 this case work analogously to cvs_flusherr.
6629 FIXME - DRP - I tried to implement this and triggered the following
6630 error: "Protocol error: uncounted data discarded". I don't need
6631 this feature right now, so I'm not going to bother with it yet.
6633 buf_send_special_count (protocol, -1);
6640 /* Output TEXT, tagging it according to TAG. There are lots more
6641 details about what TAG means in cvsclient.texi but for the simple
6642 case (e.g. non-client/server), TAG is just "newline" to output a
6643 newline (in which case TEXT must be NULL), and any other tag to
6646 Note that there is no way to output either \0 or \n as part of TEXT. */
6649 cvs_output_tagged (tag, text)
6653 if (text != NULL && strchr (text, '\n') != NULL)
6654 /* Uh oh. The protocol has no way to cope with this. For now
6655 we dump core, although that really isn't such a nice
6656 response given that this probably can be caused by newlines
6657 in filenames and other causes other than bugs in CVS. Note
6658 that we don't want to turn this into "MT newline" because
6659 this case is a newline within a tagged item, not a newline
6660 as extraneous sugar for the user. */
6663 /* Start and end tags don't take any text, per cvsclient.texi. */
6664 if (tag[0] == '+' || tag[0] == '-')
6665 assert (text == NULL);
6667 #ifdef SERVER_SUPPORT
6668 if (server_active && supported_response ("MT"))
6672 if (error_use_protocol)
6677 buf_output0 (buf, "MT ");
6678 buf_output0 (buf, tag);
6681 buf_output (buf, " ", 1);
6682 buf_output0 (buf, text);
6684 buf_output (buf, "\n", 1);
6686 if (!error_use_protocol)
6687 buf_send_counted (protocol);
6692 if (strcmp (tag, "newline") == 0)
6693 cvs_output ("\n", 1);
6694 else if (text != NULL)
6695 cvs_output (text, 0);