1 /* This program is free software; you can redistribute it and/or modify
2 it under the terms of the GNU General Public License as published by
3 the Free Software Foundation; either version 2, or (at your option)
6 This program is distributed in the hope that it will be useful,
7 but WITHOUT ANY WARRANTY; without even the implied warranty of
8 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 GNU General Public License for more details. */
23 int server_active = 0;
25 #if defined(SERVER_SUPPORT) || defined(CLIENT_SUPPORT)
27 /* This stuff isn't included solely with SERVER_SUPPORT since some of these
28 * functions (encryption & the like) get compiled with or without server
31 * FIXME - They should be in a different file.
35 /* We use Kerberos 5 routines to map the GSSAPI credential to a user
39 /* We need this to wrap data. */
40 static gss_ctx_id_t gcontext;
42 static void gserver_authenticate_connection PROTO((void));
44 /* Whether we are already wrapping GSSAPI communication. */
45 static int cvs_gssapi_wrapping;
48 /* Whether to encrypt GSSAPI communication. We use a global variable
49 like this because we use the same buffer type (gssapi_wrap) to
50 handle both authentication and encryption, and we don't want
51 multiple instances of that buffer in the communication stream. */
52 int cvs_gssapi_encrypt;
54 # endif /* HAVE_GSSAPI */
55 #endif /* defined(SERVER_SUPPORT) || defined(CLIENT_SUPPORT) */
63 #if defined (AUTH_SERVER_SUPPORT) || defined (HAVE_KERBEROS) || defined (HAVE_GSSAPI)
64 #include <sys/socket.h>
69 # ifndef LOG_DAEMON /* for ancient syslogs */
75 # include <netinet/in.h>
77 # ifndef HAVE_KRB_GET_ERR_TEXT
78 # define krb_get_err_text(status) krb_err_txt[status]
81 /* Information we need if we are going to use Kerberos encryption. */
82 static C_Block kblock;
83 static Key_schedule sched;
91 #define O_NONBLOCK O_NDELAY
94 /* EWOULDBLOCK is not defined by POSIX, but some BSD systems will
95 return it, rather than EAGAIN, for nonblocking writes. */
97 #define blocking_error(err) ((err) == EWOULDBLOCK || (err) == EAGAIN)
99 #define blocking_error(err) ((err) == EAGAIN)
102 /* For initgroups(). */
105 #endif /* HAVE_INITGROUPS */
107 # ifdef AUTH_SERVER_SUPPORT
109 # ifdef HAVE_GETSPNAM
113 /* The cvs username sent by the client, which might or might not be
114 the same as the system username the server eventually switches to
115 run as. CVS_Username gets set iff password authentication is
117 char *CVS_Username = NULL;
119 /* Used to check that same repos is transmitted in pserver auth and in
120 later CVS protocol. Exported because root.c also uses. */
121 static char *Pserver_Repos = NULL;
123 /* Should we check for system usernames/passwords? Can be changed by
127 # endif /* AUTH_SERVER_SUPPORT */
130 /* While processing requests, this buffer accumulates data to be sent to
131 the client, and then once we are in do_cvs_command, we use it
132 for all the data to be sent. */
133 static struct buffer *buf_to_net;
135 /* This buffer is used to read input from the client. */
136 static struct buffer *buf_from_net;
139 * This is where we stash stuff we are going to use. Format string
140 * which expects a single directory within it, starting with a slash.
142 static char *server_temp_dir;
144 /* This is the original value of server_temp_dir, before any possible
145 changes inserted by serve_max_dotdot. */
146 static char *orig_server_temp_dir;
148 /* Nonzero if we should keep the temp directory around after we exit. */
149 static int dont_delete_temp;
151 static void server_write_entries PROTO((void));
153 /* All server communication goes through buffer structures. Most of
154 the buffers are built on top of a file descriptor. This structure
155 is used as the closure field in a buffer. */
159 /* The file descriptor. */
161 /* Nonzero if the file descriptor is in blocking mode. */
165 static struct buffer *fd_buffer_initialize
166 PROTO ((int, int, void (*) (struct buffer *)));
167 static int fd_buffer_input PROTO((void *, char *, int, int, int *));
168 static int fd_buffer_output PROTO((void *, const char *, int, int *));
169 static int fd_buffer_flush PROTO((void *));
170 static int fd_buffer_block PROTO((void *, int));
171 static int fd_buffer_shutdown PROTO((struct buffer *));
173 /* Initialize a buffer built on a file descriptor. FD is the file
174 descriptor. INPUT is nonzero if this is for input, zero if this is
175 for output. MEMORY is the function to call when a memory error
178 static struct buffer *
179 fd_buffer_initialize (fd, input, memory)
182 void (*memory) PROTO((struct buffer *));
186 n = (struct fd_buffer *) xmalloc (sizeof *n);
189 return buf_initialize (input ? fd_buffer_input : NULL,
190 input ? NULL : fd_buffer_output,
191 input ? NULL : fd_buffer_flush,
198 /* The buffer input function for a buffer built on a file descriptor. */
201 fd_buffer_input (closure, data, need, size, got)
208 struct fd_buffer *fd = (struct fd_buffer *) closure;
212 nbytes = read (fd->fd, data, size);
215 /* This case is not efficient. Fortunately, I don't think it
216 ever actually happens. */
217 nbytes = read (fd->fd, data, need == 0 ? 1 : need);
230 /* End of file. This assumes that we are using POSIX or BSD
231 style nonblocking I/O. On System V we will get a zero
232 return if there is no data, even when not at EOF. */
236 /* Some error occurred. */
238 if (blocking_error (errno))
240 /* Everything's fine, we just didn't get any data. */
247 /* The buffer output function for a buffer built on a file descriptor. */
250 fd_buffer_output (closure, data, have, wrote)
256 struct fd_buffer *fd = (struct fd_buffer *) closure;
264 nbytes = write (fd->fd, data, have);
269 && (nbytes == 0 || blocking_error (errno)))
271 /* A nonblocking write failed to write any data. Just
276 /* Some sort of error occurred. */
292 /* The buffer flush function for a buffer built on a file descriptor. */
296 fd_buffer_flush (closure)
299 /* Nothing to do. File descriptors are always flushed. */
303 /* The buffer block function for a buffer built on a file descriptor. */
306 fd_buffer_block (closure, block)
310 struct fd_buffer *fd = (struct fd_buffer *) closure;
313 flags = fcntl (fd->fd, F_GETFL, 0);
318 flags &= ~O_NONBLOCK;
322 if (fcntl (fd->fd, F_SETFL, flags) < 0)
325 fd->blocking = block;
330 /* The buffer shutdown function for a buffer built on a file descriptor. */
333 fd_buffer_shutdown (buf)
341 /* Populate all of the directories between BASE_DIR and its relative
342 subdirectory DIR with CVSADM directories. Return 0 for success or
344 static int create_adm_p PROTO((char *, char *));
347 create_adm_p (base_dir, dir)
351 char *dir_where_cvsadm_lives, *dir_to_register, *p, *tmp;
355 if (strcmp (dir, ".") == 0)
356 return 0; /* nothing to do */
358 /* Allocate some space for our directory-munging string. */
359 p = xmalloc (strlen (dir) + 1);
363 dir_where_cvsadm_lives = xmalloc (strlen (base_dir) + strlen (dir) + 100);
364 if (dir_where_cvsadm_lives == NULL)
370 /* Allocate some space for the temporary string in which we will
371 construct filenames. */
372 tmp = xmalloc (strlen (base_dir) + strlen (dir) + 100);
376 free (dir_where_cvsadm_lives);
381 /* We make several passes through this loop. On the first pass,
382 we simply create the CVSADM directory in the deepest directory.
383 For each subsequent pass, we try to remove the last path
384 element from DIR, create the CVSADM directory in the remaining
385 pathname, and register the subdirectory in the newly created
391 strcpy (dir_where_cvsadm_lives, base_dir);
392 strcat (dir_where_cvsadm_lives, "/");
393 strcat (dir_where_cvsadm_lives, p);
394 dir_to_register = NULL;
399 (void) sprintf (tmp, "%s/%s", dir_where_cvsadm_lives, CVSADM);
400 if ((CVS_MKDIR (tmp, 0777) < 0) && (errno != EEXIST))
406 /* Create CVSADM_REP. */
407 (void) sprintf (tmp, "%s/%s", dir_where_cvsadm_lives, CVSADM_REP);
410 /* Use Emptydir as the placeholder until the client sends
411 us the real value. This code is similar to checkout.c
412 (emptydir_name), but the code below returns errors
416 empty = xmalloc (strlen (current_parsed_root->directory)
417 + sizeof (CVSROOTADM)
418 + sizeof (CVSNULLREPOS)
426 /* Create the directory name. */
427 (void) sprintf (empty, "%s/%s/%s", current_parsed_root->directory,
428 CVSROOTADM, CVSNULLREPOS);
430 /* Create the directory if it doesn't exist. */
431 if (! isfile (empty))
434 omask = umask (cvsumask);
435 if (CVS_MKDIR (empty, 0777) < 0)
441 (void) umask (omask);
444 f = CVS_FOPEN (tmp, "w");
451 /* Write the directory name to CVSADM_REP. */
452 if (fprintf (f, "%s\n", empty) < 0)
459 if (fclose (f) == EOF)
466 /* Clean up after ourselves. */
470 /* Create CVSADM_ENT. We open in append mode because we
471 don't want to clobber an existing Entries file. */
472 (void) sprintf (tmp, "%s/%s", dir_where_cvsadm_lives, CVSADM_ENT);
473 f = CVS_FOPEN (tmp, "a");
479 if (fclose (f) == EOF)
485 if (dir_to_register != NULL)
487 /* FIXME: Yes, this results in duplicate entries in the
488 Entries.Log file, but it doesn't currently matter. We
489 might need to change this later on to make sure that we
490 only write one entry. */
492 Subdir_Register ((List *) NULL, dir_where_cvsadm_lives,
499 dir_to_register = strrchr (p, '/');
500 if (dir_to_register == NULL)
503 strcpy (dir_where_cvsadm_lives, base_dir);
508 *dir_to_register = '\0';
510 strcpy (dir_where_cvsadm_lives, base_dir);
511 strcat (dir_where_cvsadm_lives, "/");
512 strcat (dir_where_cvsadm_lives, p);
518 free (dir_where_cvsadm_lives);
524 * Make directory DIR, including all intermediate directories if necessary.
525 * Returns 0 for success or errno code.
527 static int mkdir_p PROTO((char *));
534 char *q = xmalloc (strlen (dir) + 1);
543 * Skip over leading slash if present. We won't bother to try to
549 while (*p != '/' && *p != '\0')
553 strncpy (q, dir, p - dir);
555 if (q[p - dir - 1] != '/' && CVS_MKDIR (q, 0777) < 0)
557 int saved_errno = errno;
559 if (saved_errno != EEXIST
560 && ((saved_errno != EACCES && saved_errno != EROFS)
563 retval = saved_errno;
571 if (CVS_MKDIR (dir, 0777) < 0)
582 * Print the error response for error code STATUS. The caller is
583 * reponsible for making sure we get back to the command loop without
584 * any further output occuring.
585 * Must be called only in contexts where it is OK to send output.
594 buf_output0 (buf_to_net, "error ");
595 msg = strerror (status);
598 sprintf (tmpstr, "unknown error %d", status);
601 buf_output0 (buf_to_net, msg);
602 buf_append_char (buf_to_net, '\n');
604 buf_flush (buf_to_net, 0);
607 static int pending_error;
609 * Malloc'd text for pending error. Each line must start with "E ". The
610 * last line should not end with a newline.
612 static char *pending_error_text;
614 /* If an error is pending, print it and return 1. If not, return 0.
615 Must be called only in contexts where it is OK to send output. */
617 print_pending_error ()
619 if (pending_error_text)
621 buf_output0 (buf_to_net, pending_error_text);
622 buf_append_char (buf_to_net, '\n');
624 print_error (pending_error);
626 buf_output0 (buf_to_net, "error \n");
628 buf_flush (buf_to_net, 0);
631 free (pending_error_text);
632 pending_error_text = NULL;
635 else if (pending_error)
637 print_error (pending_error);
645 /* Is an error pending? */
646 #define error_pending() (pending_error || pending_error_text)
648 static int alloc_pending PROTO ((size_t size));
650 /* Allocate SIZE bytes for pending_error_text and return nonzero
651 if we could do it. */
656 if (error_pending ())
657 /* Probably alloc_pending callers will have already checked for
658 this case. But we might as well handle it if they don't, I
661 pending_error_text = xmalloc (size);
662 if (pending_error_text == NULL)
664 pending_error = ENOMEM;
670 static void serve_is_modified PROTO ((char *));
672 static int supported_response PROTO ((char *));
675 supported_response (name)
680 for (rs = responses; rs->name != NULL; ++rs)
681 if (strcmp (rs->name, name) == 0)
682 return rs->status == rs_supported;
683 error (1, 0, "internal error: testing support for unknown response?");
689 serve_valid_responses (arg)
700 for (rs = responses; rs->name != NULL; ++rs)
702 if (strcmp (rs->name, p) == 0)
705 if (rs->name == NULL)
707 * It is a response we have never heard of (and thus never
708 * will want to use). So don't worry about it.
712 rs->status = rs_supported;
715 for (rs = responses; rs->name != NULL; ++rs)
717 if (rs->status == rs_essential)
719 buf_output0 (buf_to_net, "E response `");
720 buf_output0 (buf_to_net, rs->name);
721 buf_output0 (buf_to_net, "' not supported by client\nerror \n");
723 /* FIXME: This call to buf_flush could conceivably
724 cause deadlock, as noted in server_cleanup. */
725 buf_flush (buf_to_net, 1);
729 else if (rs->status == rs_optional)
730 rs->status = rs_not_supported;
741 if (error_pending()) return;
743 if (!isabsolute (arg))
745 if (alloc_pending (80 + strlen (arg)))
746 sprintf (pending_error_text,
747 "E Root %s must be an absolute pathname", arg);
751 /* Sending "Root" twice is illegal.
753 The other way to handle a duplicate Root requests would be as a
754 request to clear out all state and start over as if it was a
755 new connection. Doing this would cause interoperability
756 headaches, so it should be a different request, if there is
757 any reason why such a feature is needed. */
758 if (current_parsed_root != NULL)
760 if (alloc_pending (80 + strlen (arg)))
761 sprintf (pending_error_text,
762 "E Protocol error: Duplicate Root request, for %s", arg);
766 #ifdef AUTH_SERVER_SUPPORT
767 if (Pserver_Repos != NULL)
769 if (strcmp (Pserver_Repos, arg) != 0)
771 if (alloc_pending (80 + strlen (Pserver_Repos) + strlen (arg)))
772 /* The explicitness is to aid people who are writing clients.
773 I don't see how this information could help an
775 sprintf (pending_error_text, "\
776 E Protocol error: Root says \"%s\" but pserver says \"%s\"",
783 current_parsed_root = local_cvsroot (arg);
785 /* For pserver, this will already have happened, and the call will do
786 nothing. But for rsh, we need to do it now. */
787 parse_config (current_parsed_root->directory);
789 /* Now is a good time to read CVSROOT/options too. */
790 parseopts(current_parsed_root->directory);
792 path = xmalloc (strlen (current_parsed_root->directory)
793 + sizeof (CVSROOTADM)
797 pending_error = ENOMEM;
800 (void) sprintf (path, "%s/%s", current_parsed_root->directory, CVSROOTADM);
801 if (!isaccessible (path, R_OK | X_OK))
803 int save_errno = errno;
804 if (alloc_pending (80 + strlen (path)))
805 sprintf (pending_error_text, "E Cannot access %s", path);
806 pending_error = save_errno;
811 env = xmalloc (strlen (CVSROOT_ENV) + strlen (current_parsed_root->directory) + 2);
814 pending_error = ENOMEM;
817 (void) sprintf (env, "%s=%s", CVSROOT_ENV, current_parsed_root->directory);
819 /* do not free env, as putenv has control of it */
823 static int max_dotdot_limit = 0;
825 /* Is this pathname OK to recurse into when we are running as the server?
826 If not, call error() with a fatal error. */
828 server_pathname_check (path)
831 /* An absolute pathname is almost surely a path on the *client* machine,
832 and is unlikely to do us any good here. It also is probably capable
833 of being a security hole in the anonymous readonly case. */
834 if (isabsolute (path))
835 /* Giving an error is actually kind of a cop-out, in the sense
836 that it would be nice for "cvs co -d /foo/bar/baz" to work.
837 A quick fix in the server would be requiring Max-dotdot of
838 at least one if pathnames are absolute, and then putting
839 /abs/foo/bar/baz in the temp dir beside the /d/d/d stuff.
840 A cleaner fix in the server might be to decouple the
841 pathnames we pass back to the client from pathnames in our
842 temp directory (this would also probably remove the need
843 for Max-dotdot). A fix in the client would have the client
844 turn it into "cd /foo/bar; cvs co -d baz" (more or less).
845 This probably has some problems with pathnames which appear
847 error (1, 0, "absolute pathname `%s' illegal for server", path);
848 if (pathname_levels (path) > max_dotdot_limit)
850 /* Similar to the isabsolute case in security implications. */
851 error (0, 0, "protocol error: `%s' contains more leading ..", path);
852 error (1, 0, "than the %d which Max-dotdot specified",
857 static int outside_root PROTO ((char *));
859 /* Is file or directory REPOS an absolute pathname within the
860 current_parsed_root->directory? If yes, return 0. If no, set pending_error
866 size_t repos_len = strlen (repos);
867 size_t root_len = strlen (current_parsed_root->directory);
869 /* isabsolute (repos) should always be true, but
870 this is a good security precaution regardless. -DRP
872 if (!isabsolute (repos))
874 if (alloc_pending (repos_len + 80))
875 sprintf (pending_error_text, "\
876 E protocol error: %s is not absolute", repos);
880 if (repos_len < root_len
881 || strncmp (current_parsed_root->directory, repos, root_len) != 0)
884 if (alloc_pending (strlen (current_parsed_root->directory)
887 sprintf (pending_error_text, "\
888 E protocol error: directory '%s' not within root '%s'",
889 repos, current_parsed_root->directory);
892 if (repos_len > root_len)
894 if (repos[root_len] != '/')
896 if (pathname_levels (repos + root_len + 1) > 0)
902 static int outside_dir PROTO ((char *));
904 /* Is file or directory FILE outside the current directory (that is, does
905 it contain '/')? If no, return 0. If yes, set pending_error
911 if (strchr (file, '/') != NULL)
913 if (alloc_pending (strlen (file)
915 sprintf (pending_error_text, "\
916 E protocol error: directory '%s' not within current directory",
924 * Add as many directories to the temp directory as the client tells us it
925 * will use "..", so we never try to access something outside the temp
926 * directory via "..".
929 serve_max_dotdot (arg)
932 int lim = atoi (arg);
936 if (lim < 0 || lim > 10000)
938 p = xmalloc (strlen (server_temp_dir) + 2 * lim + 10);
941 pending_error = ENOMEM;
944 strcpy (p, server_temp_dir);
945 for (i = 0; i < lim; ++i)
947 if (server_temp_dir != orig_server_temp_dir)
948 free (server_temp_dir);
950 max_dotdot_limit = lim;
953 static char *dir_name;
956 dirswitch (dir, repos)
964 server_write_entries ();
966 if (error_pending()) return;
968 /* Check for bad directory name.
970 FIXME: could/should unify these checks with server_pathname_check
971 except they need to report errors differently. */
972 if (isabsolute (dir))
974 if (alloc_pending (80 + strlen (dir)))
975 sprintf (pending_error_text,
976 "E absolute pathname `%s' illegal for server", dir);
979 if (pathname_levels (dir) > max_dotdot_limit)
981 if (alloc_pending (80 + strlen (dir)))
982 sprintf (pending_error_text,
983 "E protocol error: `%s' has too many ..", dir);
987 dir_len = strlen (dir);
989 /* Check for a trailing '/'. This is not ISDIRSEP because \ in the
990 protocol is an ordinary character, not a directory separator (of
991 course, it is perhaps unwise to use it in directory names, but that
992 is another issue). */
994 && dir[dir_len - 1] == '/')
996 if (alloc_pending (80 + dir_len))
997 sprintf (pending_error_text,
998 "E protocol error: invalid directory syntax in %s", dir);
1002 if (dir_name != NULL)
1005 dir_name = xmalloc (strlen (server_temp_dir) + dir_len + 40);
1006 if (dir_name == NULL)
1008 pending_error = ENOMEM;
1012 strcpy (dir_name, server_temp_dir);
1013 strcat (dir_name, "/");
1014 strcat (dir_name, dir);
1016 status = mkdir_p (dir_name);
1018 && status != EEXIST)
1020 if (alloc_pending (80 + strlen (dir_name)))
1021 sprintf (pending_error_text, "E cannot mkdir %s", dir_name);
1022 pending_error = status;
1026 /* We need to create adm directories in all path elements because
1027 we want the server to descend them, even if the client hasn't
1028 sent the appropriate "Argument xxx" command to match the
1029 already-sent "Directory xxx" command. See recurse.c
1030 (start_recursion) for a big discussion of this. */
1032 status = create_adm_p (server_temp_dir, dir);
1035 if (alloc_pending (80 + strlen (dir_name)))
1036 sprintf (pending_error_text, "E cannot create_adm_p %s", dir_name);
1037 pending_error = status;
1041 if ( CVS_CHDIR (dir_name) < 0)
1043 int save_errno = errno;
1044 if (alloc_pending (80 + strlen (dir_name)))
1045 sprintf (pending_error_text, "E cannot change to %s", dir_name);
1046 pending_error = save_errno;
1050 * This is pretty much like calling Create_Admin, but Create_Admin doesn't
1051 * report errors in the right way for us.
1053 if ((CVS_MKDIR (CVSADM, 0777) < 0) && (errno != EEXIST))
1055 int save_errno = errno;
1056 if (alloc_pending (80 + strlen (dir_name) + strlen (CVSADM)))
1057 sprintf (pending_error_text,
1058 "E cannot mkdir %s/%s", dir_name, CVSADM);
1059 pending_error = save_errno;
1063 /* The following will overwrite the contents of CVSADM_REP. This
1064 is the correct behavior -- mkdir_p may have written a
1065 placeholder value to this file and we need to insert the
1068 f = CVS_FOPEN (CVSADM_REP, "w");
1071 int save_errno = errno;
1072 if (alloc_pending (80 + strlen (dir_name) + strlen (CVSADM_REP)))
1073 sprintf (pending_error_text,
1074 "E cannot open %s/%s", dir_name, CVSADM_REP);
1075 pending_error = save_errno;
1078 if (fprintf (f, "%s", repos) < 0)
1080 int save_errno = errno;
1081 if (alloc_pending (80 + strlen (dir_name) + strlen (CVSADM_REP)))
1082 sprintf (pending_error_text,
1083 "E error writing %s/%s", dir_name, CVSADM_REP);
1084 pending_error = save_errno;
1088 /* Non-remote CVS handles a module representing the entire tree
1089 (e.g., an entry like ``world -a .'') by putting /. at the end
1090 of the Repository file, so we do the same. */
1091 if (strcmp (dir, ".") == 0
1092 && current_parsed_root != NULL
1093 && current_parsed_root->directory != NULL
1094 && strcmp (current_parsed_root->directory, repos) == 0)
1096 if (fprintf (f, "/.") < 0)
1098 int save_errno = errno;
1099 if (alloc_pending (80 + strlen (dir_name) + strlen (CVSADM_REP)))
1100 sprintf (pending_error_text,
1101 "E error writing %s/%s", dir_name, CVSADM_REP);
1102 pending_error = save_errno;
1107 if (fprintf (f, "\n") < 0)
1109 int save_errno = errno;
1110 if (alloc_pending (80 + strlen (dir_name) + strlen (CVSADM_REP)))
1111 sprintf (pending_error_text,
1112 "E error writing %s/%s", dir_name, CVSADM_REP);
1113 pending_error = save_errno;
1117 if (fclose (f) == EOF)
1119 int save_errno = errno;
1120 if (alloc_pending (80 + strlen (dir_name) + strlen (CVSADM_REP)))
1121 sprintf (pending_error_text,
1122 "E error closing %s/%s", dir_name, CVSADM_REP);
1123 pending_error = save_errno;
1126 /* We open in append mode because we don't want to clobber an
1127 existing Entries file. */
1128 f = CVS_FOPEN (CVSADM_ENT, "a");
1131 int save_errno = errno;
1132 if (alloc_pending (80 + strlen (CVSADM_ENT)))
1133 sprintf (pending_error_text, "E cannot open %s", CVSADM_ENT);
1134 pending_error = save_errno;
1137 if (fclose (f) == EOF)
1139 int save_errno = errno;
1140 if (alloc_pending (80 + strlen (CVSADM_ENT)))
1141 sprintf (pending_error_text, "E cannot close %s", CVSADM_ENT);
1142 pending_error = save_errno;
1148 serve_repository (arg)
1151 if (alloc_pending (80))
1152 strcpy (pending_error_text,
1153 "E Repository request is obsolete; aborted");
1158 serve_directory (arg)
1164 status = buf_read_line (buf_from_net, &repos, (int *) NULL);
1167 if (!outside_root (repos))
1168 dirswitch (arg, repos);
1171 else if (status == -2)
1173 pending_error = ENOMEM;
1177 pending_error_text = xmalloc (80 + strlen (arg));
1178 if (pending_error_text == NULL)
1180 pending_error = ENOMEM;
1182 else if (status == -1)
1184 sprintf (pending_error_text,
1185 "E end of file reading mode for %s", arg);
1189 sprintf (pending_error_text,
1190 "E error reading mode for %s", arg);
1191 pending_error = status;
1197 serve_static_directory (arg)
1202 if (error_pending ()) return;
1204 f = CVS_FOPEN (CVSADM_ENTSTAT, "w+");
1207 int save_errno = errno;
1208 if (alloc_pending (80 + strlen (CVSADM_ENTSTAT)))
1209 sprintf (pending_error_text, "E cannot open %s", CVSADM_ENTSTAT);
1210 pending_error = save_errno;
1213 if (fclose (f) == EOF)
1215 int save_errno = errno;
1216 if (alloc_pending (80 + strlen (CVSADM_ENTSTAT)))
1217 sprintf (pending_error_text, "E cannot close %s", CVSADM_ENTSTAT);
1218 pending_error = save_errno;
1229 if (error_pending ()) return;
1231 f = CVS_FOPEN (CVSADM_TAG, "w+");
1234 int save_errno = errno;
1235 if (alloc_pending (80 + strlen (CVSADM_TAG)))
1236 sprintf (pending_error_text, "E cannot open %s", CVSADM_TAG);
1237 pending_error = save_errno;
1240 if (fprintf (f, "%s\n", arg) < 0)
1242 int save_errno = errno;
1243 if (alloc_pending (80 + strlen (CVSADM_TAG)))
1244 sprintf (pending_error_text, "E cannot write to %s", CVSADM_TAG);
1245 pending_error = save_errno;
1249 if (fclose (f) == EOF)
1251 int save_errno = errno;
1252 if (alloc_pending (80 + strlen (CVSADM_TAG)))
1253 sprintf (pending_error_text, "E cannot close %s", CVSADM_TAG);
1254 pending_error = save_errno;
1260 * Read SIZE bytes from buf_from_net, write them to FILE.
1262 * Currently this isn't really used for receiving parts of a file --
1263 * the file is still sent over in one chunk. But if/when we get
1264 * spiffy in-process gzip support working, perhaps the compressed
1265 * pieces could be sent over as they're ready, if the network is fast
1266 * enough. Or something.
1269 receive_partial_file (size, file)
1278 status = buf_read_data (buf_from_net, size, &data, &nread);
1282 pending_error = ENOMEM;
1285 pending_error_text = xmalloc (80);
1286 if (pending_error_text == NULL)
1287 pending_error = ENOMEM;
1288 else if (status == -1)
1290 sprintf (pending_error_text,
1291 "E premature end of file from client");
1296 sprintf (pending_error_text,
1297 "E error reading from client");
1298 pending_error = status;
1310 nwrote = write (file, data, nread);
1313 int save_errno = errno;
1314 if (alloc_pending (40))
1315 strcpy (pending_error_text, "E unable to write");
1316 pending_error = save_errno;
1318 /* Read and discard the file data. */
1324 status = buf_read_data (buf_from_net, size, &data, &nread);
1338 /* Receive SIZE bytes, write to filename FILE. */
1340 receive_file (size, file, gzipped)
1348 /* Write the file. */
1349 fd = CVS_OPEN (arg, O_WRONLY | O_CREAT | O_TRUNC, 0600);
1352 int save_errno = errno;
1353 if (alloc_pending (40 + strlen (arg)))
1354 sprintf (pending_error_text, "E cannot open %s", arg);
1355 pending_error = save_errno;
1361 /* Using gunzip_and_write isn't really a high-performance
1362 approach, because it keeps the whole thing in memory
1363 (contiguous memory, worse yet). But it seems easier to
1364 code than the alternative (and less vulnerable to subtle
1365 bugs). Given that this feature is mainly for
1366 compatibility, that is the better tradeoff. */
1372 filebuf = xmalloc (size);
1374 /* If NULL, we still want to read the data and discard it. */
1381 status = buf_read_data (buf_from_net, toread, &data, &nread);
1385 pending_error = ENOMEM;
1388 pending_error_text = xmalloc (80);
1389 if (pending_error_text == NULL)
1390 pending_error = ENOMEM;
1391 else if (status == -1)
1393 sprintf (pending_error_text,
1394 "E premature end of file from client");
1399 sprintf (pending_error_text,
1400 "E error reading from client");
1401 pending_error = status;
1409 if (filebuf != NULL)
1411 memcpy (p, data, nread);
1415 if (filebuf == NULL)
1417 pending_error = ENOMEM;
1421 if (gunzip_and_write (fd, file, (unsigned char *) filebuf, size))
1423 if (alloc_pending (80))
1424 sprintf (pending_error_text,
1425 "E aborting due to compression error");
1430 receive_partial_file (size, fd);
1432 if (pending_error_text)
1434 char *p = xrealloc (pending_error_text,
1435 strlen (pending_error_text) + strlen (arg) + 30);
1438 pending_error_text = p;
1439 sprintf (p + strlen (p), ", file %s", arg);
1441 /* else original string is supposed to be unchanged */
1445 if (close (fd) < 0 && !error_pending ())
1447 int save_errno = errno;
1448 if (alloc_pending (40 + strlen (arg)))
1449 sprintf (pending_error_text, "E cannot close %s", arg);
1450 pending_error = save_errno;
1455 /* Kopt for the next file sent in Modified or Is-modified. */
1458 /* Timestamp (Checkin-time) for next file sent in Modified or
1460 static int checkin_time_valid;
1461 static time_t checkin_time;
1463 static void serve_modified PROTO ((char *));
1466 serve_modified (arg)
1476 * This used to return immediately if error_pending () was true.
1477 * However, that fails, because it causes each line of the file to
1478 * be echoed back to the client as an unrecognized command. The
1479 * client isn't reading from the socket, so eventually both
1480 * processes block trying to write to the other. Now, we try to
1481 * read the file if we can.
1484 status = buf_read_line (buf_from_net, &mode_text, (int *) NULL);
1488 pending_error = ENOMEM;
1491 pending_error_text = xmalloc (80 + strlen (arg));
1492 if (pending_error_text == NULL)
1493 pending_error = ENOMEM;
1497 sprintf (pending_error_text,
1498 "E end of file reading mode for %s", arg);
1501 sprintf (pending_error_text,
1502 "E error reading mode for %s", arg);
1503 pending_error = status;
1510 status = buf_read_line (buf_from_net, &size_text, (int *) NULL);
1514 pending_error = ENOMEM;
1517 pending_error_text = xmalloc (80 + strlen (arg));
1518 if (pending_error_text == NULL)
1519 pending_error = ENOMEM;
1523 sprintf (pending_error_text,
1524 "E end of file reading size for %s", arg);
1527 sprintf (pending_error_text,
1528 "E error reading size for %s", arg);
1529 pending_error = status;
1536 if (size_text[0] == 'z')
1539 size = atoi (size_text + 1);
1542 size = atoi (size_text);
1545 if (error_pending ())
1547 /* Now that we know the size, read and discard the file data. */
1553 status = buf_read_data (buf_from_net, size, &data, &nread);
1562 if (outside_dir (arg))
1570 receive_file (size, arg, gzipped);
1571 if (error_pending ())
1578 if (checkin_time_valid)
1582 memset (&t, 0, sizeof (t));
1583 t.modtime = t.actime = checkin_time;
1584 if (utime (arg, &t) < 0)
1586 int save_errno = errno;
1587 if (alloc_pending (80 + strlen (arg)))
1588 sprintf (pending_error_text, "E cannot utime %s", arg);
1589 pending_error = save_errno;
1593 checkin_time_valid = 0;
1597 int status = change_mode (arg, mode_text, 0);
1601 if (alloc_pending (40 + strlen (arg)))
1602 sprintf (pending_error_text,
1603 "E cannot change mode for %s", arg);
1604 pending_error = status;
1609 /* Make sure that the Entries indicate the right kopt. We probably
1610 could do this even in the non-kopt case and, I think, save a stat()
1611 call in time_stamp_server. But for conservatism I'm leaving the
1612 non-kopt case alone. */
1614 serve_is_modified (arg);
1619 serve_enable_unchanged (arg)
1625 struct an_entry *next;
1629 static struct an_entry *entries;
1631 static void serve_unchanged PROTO ((char *));
1634 serve_unchanged (arg)
1642 if (error_pending ()) return;
1644 if (outside_dir (arg))
1647 /* Rewrite entries file to have `=' in timestamp field. */
1648 for (p = entries; p != NULL; p = p->next)
1650 name = p->entry + 1;
1651 cp = strchr (name, '/');
1653 && strlen (arg) == cp - name
1654 && strncmp (arg, name, cp - name) == 0)
1656 if (!(timefield = strchr (cp + 1, '/')) || *++timefield == '\0')
1658 /* We didn't find the record separator or it is followed by
1659 * the end of the string, so just exit.
1661 if (alloc_pending (80))
1662 sprintf (pending_error_text,
1663 "E Malformed Entry encountered.");
1666 /* If the time field is not currently empty, then one of
1667 * serve_modified, serve_is_modified, & serve_unchanged were
1668 * already called for this file. We would like to ignore the
1669 * reinvocation silently or, better yet, exit with an error
1670 * message, but we just avoid the copy-forward and overwrite the
1671 * value from the last invocation instead. See the comment below
1674 if (*timefield == '/')
1676 /* Copy forward one character. Space was allocated for this
1677 * already in serve_entry(). */
1678 cp = timefield + strlen (timefield);
1680 while (cp > timefield)
1686 /* If *TIMEFIELD wasn't "/", we assume that it was because of
1687 * multiple calls to Is-Modified & Unchanged by the client and
1688 * just overwrite the value from the last call. Technically, we
1689 * should probably either ignore calls after the first or send the
1690 * client an error, since the client/server protocol specification
1691 * specifies that only one call to either Is-Modified or Unchanged
1692 * is allowed, but broken versions of WinCVS & TortoiseCVS rely on
1695 if (*timefield != '+')
1696 /* Skip this for entries with conflict markers. */
1704 serve_is_modified (arg)
1711 /* Have we found this file in "entries" yet. */
1714 if (error_pending ()) return;
1716 if (outside_dir (arg))
1719 /* Rewrite entries file to have `M' in timestamp field. */
1721 for (p = entries; p != NULL; p = p->next)
1723 name = p->entry + 1;
1724 cp = strchr (name, '/');
1726 && strlen (arg) == cp - name
1727 && strncmp (arg, name, cp - name) == 0)
1729 if (!(timefield = strchr (cp + 1, '/')) || *++timefield == '\0')
1731 /* We didn't find the record separator or it is followed by
1732 * the end of the string, so just exit.
1734 if (alloc_pending (80))
1735 sprintf (pending_error_text,
1736 "E Malformed Entry encountered.");
1739 /* If the time field is not currently empty, then one of
1740 * serve_modified, serve_is_modified, & serve_unchanged were
1741 * already called for this file. We would like to ignore the
1742 * reinvocation silently or, better yet, exit with an error
1743 * message, but we just avoid the copy-forward and overwrite the
1744 * value from the last invocation instead. See the comment below
1747 if (*timefield == '/')
1749 /* Copy forward one character. Space was allocated for this
1750 * already in serve_entry(). */
1751 cp = timefield + strlen (timefield);
1753 while (cp > timefield)
1759 /* If *TIMEFIELD wasn't "/", we assume that it was because of
1760 * multiple calls to Is-Modified & Unchanged by the client and
1761 * just overwrite the value from the last call. Technically, we
1762 * should probably either ignore calls after the first or send the
1763 * client an error, since the client/server protocol specification
1764 * specifies that only one call to either Is-Modified or Unchanged
1765 * is allowed, but broken versions of WinCVS & TortoiseCVS rely on
1768 if (*timefield != '+')
1769 /* Skip this for entries with conflict markers. */
1774 if (alloc_pending (strlen (name) + 80))
1775 sprintf (pending_error_text,
1776 "E protocol error: both Kopt and Entry for %s",
1788 /* We got Is-modified but no Entry. Add a dummy entry.
1789 The "D" timestamp is what makes it a dummy. */
1790 p = (struct an_entry *) xmalloc (sizeof (struct an_entry));
1793 pending_error = ENOMEM;
1796 p->entry = xmalloc (strlen (arg) + 80);
1797 if (p->entry == NULL)
1799 pending_error = ENOMEM;
1803 strcpy (p->entry, "/");
1804 strcat (p->entry, arg);
1805 strcat (p->entry, "//D/");
1808 strcat (p->entry, kopt);
1812 strcat (p->entry, "/");
1818 static void serve_entry PROTO ((char *));
1827 if (error_pending()) return;
1829 /* Verify that the entry is well-formed. This can avoid problems later.
1830 * At the moment we only check that the Entry contains five slashes in
1831 * approximately the correct locations since some of the code makes
1832 * assumptions about this.
1835 if (*cp == 'D') cp++;
1838 if (!cp || *cp != '/')
1840 if (alloc_pending (80))
1841 sprintf (pending_error_text,
1842 "E protocol error: Malformed Entry");
1845 cp = strchr (cp + 1, '/');
1848 p = xmalloc (sizeof (struct an_entry));
1851 pending_error = ENOMEM;
1854 /* Leave space for serve_unchanged to write '=' if it wants. */
1855 cp = xmalloc (strlen (arg) + 2);
1859 pending_error = ENOMEM;
1868 static void serve_kopt PROTO ((char *));
1874 if (error_pending ())
1879 if (alloc_pending (80 + strlen (arg)))
1880 sprintf (pending_error_text,
1881 "E protocol error: duplicate Kopt request: %s", arg);
1885 /* Do some sanity checks. In particular, that it is not too long.
1886 This lets the rest of the code not worry so much about buffer
1887 overrun attacks. Probably should call RCS_check_kflag here,
1888 but that would mean changing RCS_check_kflag to handle errors
1889 other than via exit(), fprintf(), and such. */
1890 if (strlen (arg) > 10)
1892 if (alloc_pending (80 + strlen (arg)))
1893 sprintf (pending_error_text,
1894 "E protocol error: invalid Kopt request: %s", arg);
1898 kopt = xmalloc (strlen (arg) + 1);
1901 pending_error = ENOMEM;
1907 static void serve_checkin_time PROTO ((char *));
1910 serve_checkin_time (arg)
1913 if (error_pending ())
1916 if (checkin_time_valid)
1918 if (alloc_pending (80 + strlen (arg)))
1919 sprintf (pending_error_text,
1920 "E protocol error: duplicate Checkin-time request: %s",
1925 checkin_time = get_date (arg, NULL);
1926 if (checkin_time == (time_t)-1)
1928 if (alloc_pending (80 + strlen (arg)))
1929 sprintf (pending_error_text, "E cannot parse date %s", arg);
1932 checkin_time_valid = 1;
1936 server_write_entries ()
1942 if (entries == NULL)
1946 /* Note that we free all the entries regardless of errors. */
1947 if (!error_pending ())
1949 /* We open in append mode because we don't want to clobber an
1950 existing Entries file. If we are checking out a module
1951 which explicitly lists more than one file in a particular
1952 directory, then we will wind up calling
1953 server_write_entries for each such file. */
1954 f = CVS_FOPEN (CVSADM_ENT, "a");
1957 int save_errno = errno;
1958 if (alloc_pending (80 + strlen (CVSADM_ENT)))
1959 sprintf (pending_error_text, "E cannot open %s", CVSADM_ENT);
1960 pending_error = save_errno;
1963 for (p = entries; p != NULL;)
1965 if (!error_pending ())
1967 if (fprintf (f, "%s\n", p->entry) < 0)
1969 int save_errno = errno;
1970 if (alloc_pending (80 + strlen(CVSADM_ENT)))
1971 sprintf (pending_error_text,
1972 "E cannot write to %s", CVSADM_ENT);
1973 pending_error = save_errno;
1982 if (f != NULL && fclose (f) == EOF && !error_pending ())
1984 int save_errno = errno;
1985 if (alloc_pending (80 + strlen (CVSADM_ENT)))
1986 sprintf (pending_error_text, "E cannot close %s", CVSADM_ENT);
1987 pending_error = save_errno;
1991 struct notify_note {
1992 /* Directory in which this notification happens. xmalloc'd*/
1998 /* The following three all in one xmalloc'd block, pointed to by TYPE.
1999 Each '\0' terminated. */
2006 struct notify_note *next;
2009 static struct notify_note *notify_list;
2010 /* Used while building list, to point to the last node that already exists. */
2011 static struct notify_note *last_node;
2013 static void serve_notify PROTO ((char *));
2019 struct notify_note *new = NULL;
2023 if (error_pending ()) return;
2025 if (outside_dir (arg))
2028 if (dir_name == NULL)
2031 new = (struct notify_note *) xmalloc (sizeof (struct notify_note));
2034 pending_error = ENOMEM;
2037 new->dir = xmalloc (strlen (dir_name) + 1);
2038 new->filename = xmalloc (strlen (arg) + 1);
2039 if (new->dir == NULL || new->filename == NULL)
2041 pending_error = ENOMEM;
2042 if (new->dir != NULL)
2047 strcpy (new->dir, dir_name);
2048 strcpy (new->filename, arg);
2050 status = buf_read_line (buf_from_net, &data, (int *) NULL);
2054 pending_error = ENOMEM;
2057 pending_error_text = xmalloc (80 + strlen (arg));
2058 if (pending_error_text == NULL)
2059 pending_error = ENOMEM;
2063 sprintf (pending_error_text,
2064 "E end of file reading notification for %s", arg);
2067 sprintf (pending_error_text,
2068 "E error reading notification for %s", arg);
2069 pending_error = status;
2073 free (new->filename);
2084 if (strchr (data, '+'))
2088 if (data[1] != '\t')
2093 cp = strchr (cp, '\t');
2097 cp = strchr (cp, '\t');
2101 cp = strchr (cp, '\t');
2106 /* If there is another tab, ignore everything after it,
2107 for future expansion. */
2108 cp = strchr (cp, '\t');
2116 if (last_node == NULL)
2121 last_node->next = new;
2127 if (alloc_pending (80))
2128 strcpy (pending_error_text,
2129 "E Protocol error; misformed Notify request");
2134 free (new->filename);
2141 /* Process all the Notify requests that we have stored up. Returns 0
2142 if successful, if not prints error message (via error()) and
2143 returns negative value. */
2147 struct notify_note *p;
2150 while (notify_list != NULL)
2152 if ( CVS_CHDIR (notify_list->dir) < 0)
2154 error (0, errno, "cannot change to %s", notify_list->dir);
2157 repos = Name_Repository (NULL, NULL);
2159 lock_dir_for_write (repos);
2161 fileattr_startdir (repos);
2163 notify_do (*notify_list->type, notify_list->filename, getcaller(),
2164 notify_list->val, notify_list->watches, repos);
2166 buf_output0 (buf_to_net, "Notified ");
2168 char *dir = notify_list->dir + strlen (server_temp_dir) + 1;
2170 buf_append_char (buf_to_net, '.');
2172 buf_output0 (buf_to_net, dir);
2173 buf_append_char (buf_to_net, '/');
2174 buf_append_char (buf_to_net, '\n');
2176 buf_output0 (buf_to_net, repos);
2177 buf_append_char (buf_to_net, '/');
2178 buf_output0 (buf_to_net, notify_list->filename);
2179 buf_append_char (buf_to_net, '\n');
2182 p = notify_list->next;
2183 free (notify_list->filename);
2184 free (notify_list->dir);
2185 free (notify_list->type);
2197 /* The code used to call fflush (stdout) here, but that is no
2198 longer necessary. The data is now buffered in buf_to_net,
2199 which will be flushed by the caller, do_cvs_command. */
2204 static int argument_count;
2205 static char **argument_vector;
2206 static int argument_vector_size;
2209 serve_argument (arg)
2214 if (error_pending()) return;
2216 if (argument_count >= 10000)
2218 if (alloc_pending (80))
2219 sprintf (pending_error_text,
2220 "E Protocol error: too many arguments");
2224 if (argument_vector_size <= argument_count)
2226 argument_vector_size *= 2;
2228 (char **) xrealloc ((char *)argument_vector,
2229 argument_vector_size * sizeof (char *));
2230 if (argument_vector == NULL)
2232 pending_error = ENOMEM;
2236 p = xmalloc (strlen (arg) + 1);
2239 pending_error = ENOMEM;
2243 argument_vector[argument_count++] = p;
2247 serve_argumentx (arg)
2252 if (error_pending()) return;
2254 if (argument_count <= 1)
2256 if (alloc_pending (80))
2257 sprintf (pending_error_text,
2258 "E Protocol error: called argumentx without prior call to argument");
2262 p = argument_vector[argument_count - 1];
2263 p = xrealloc (p, strlen (p) + 1 + strlen (arg) + 1);
2266 pending_error = ENOMEM;
2271 argument_vector[argument_count - 1] = p;
2275 serve_global_option (arg)
2278 if (arg[0] != '-' || arg[1] == '\0' || arg[2] != '\0')
2281 if (alloc_pending (strlen (arg) + 80))
2282 sprintf (pending_error_text,
2283 "E Protocol error: bad global option %s",
2290 error(0, 0, "WARNING: global `-l' option ignored.");
2317 /* FIXME: This sends errors immediately (I think); they should be
2318 put into pending_error. */
2324 #ifdef HAVE_KERBEROS
2327 serve_kerberos_encrypt (arg)
2330 /* All future communication with the client will be encrypted. */
2332 buf_to_net = krb_encrypt_buffer_initialize (buf_to_net, 0, sched,
2334 buf_to_net->memory_error);
2335 buf_from_net = krb_encrypt_buffer_initialize (buf_from_net, 1, sched,
2337 buf_from_net->memory_error);
2340 #endif /* HAVE_KERBEROS */
2345 serve_gssapi_encrypt (arg)
2348 if (cvs_gssapi_wrapping)
2350 /* We're already using a gssapi_wrap buffer for stream
2351 authentication. Flush everything we've output so far, and
2352 turn on encryption for future data. On the input side, we
2353 should only have unwrapped as far as the Gssapi-encrypt
2354 command, so future unwrapping will become encrypted. */
2355 buf_flush (buf_to_net, 1);
2356 cvs_gssapi_encrypt = 1;
2360 /* All future communication with the client will be encrypted. */
2362 cvs_gssapi_encrypt = 1;
2364 buf_to_net = cvs_gssapi_wrap_buffer_initialize (buf_to_net, 0,
2366 buf_to_net->memory_error);
2367 buf_from_net = cvs_gssapi_wrap_buffer_initialize (buf_from_net, 1,
2369 buf_from_net->memory_error);
2371 cvs_gssapi_wrapping = 1;
2374 #endif /* HAVE_GSSAPI */
2376 #endif /* ENCRYPTION */
2381 serve_gssapi_authenticate (arg)
2384 if (cvs_gssapi_wrapping)
2386 /* We're already using a gssapi_wrap buffer for encryption.
2387 That includes authentication, so we don't have to do
2388 anything further. */
2392 buf_to_net = cvs_gssapi_wrap_buffer_initialize (buf_to_net, 0,
2394 buf_to_net->memory_error);
2395 buf_from_net = cvs_gssapi_wrap_buffer_initialize (buf_from_net, 1,
2397 buf_from_net->memory_error);
2399 cvs_gssapi_wrapping = 1;
2402 #endif /* HAVE_GSSAPI */
2406 #ifdef SERVER_FLOWCONTROL
2407 /* The maximum we'll queue to the remote client before blocking. */
2408 # ifndef SERVER_HI_WATER
2409 # define SERVER_HI_WATER (2 * 1024 * 1024)
2410 # endif /* SERVER_HI_WATER */
2411 /* When the buffer drops to this, we restart the child */
2412 # ifndef SERVER_LO_WATER
2413 # define SERVER_LO_WATER (1 * 1024 * 1024)
2414 # endif /* SERVER_LO_WATER */
2415 #endif /* SERVER_FLOWCONTROL */
2419 static void serve_questionable PROTO((char *));
2422 serve_questionable (arg)
2429 /* Pick up ignores from CVSROOTADM_IGNORE, $HOME/.cvsignore on server,
2430 and CVSIGNORE on server. */
2435 if (dir_name == NULL)
2437 buf_output0 (buf_to_net, "E Protocol error: 'Directory' missing");
2441 if (outside_dir (arg))
2444 if (!ign_name (arg))
2448 buf_output (buf_to_net, "M ? ", 4);
2449 update_dir = dir_name + strlen (server_temp_dir) + 1;
2450 if (!(update_dir[0] == '.' && update_dir[1] == '\0'))
2452 buf_output0 (buf_to_net, update_dir);
2453 buf_output (buf_to_net, "/", 1);
2455 buf_output0 (buf_to_net, arg);
2456 buf_output (buf_to_net, "\n", 1);
2462 static struct buffer *protocol;
2464 /* This is the output which we are saving up to send to the server, in the
2465 child process. We will push it through, via the `protocol' buffer, when
2466 we have a complete line. */
2467 static struct buffer *saved_output;
2468 /* Likewise, but stuff which will go to stderr. */
2469 static struct buffer *saved_outerr;
2472 protocol_memory_error (buf)
2475 error (1, ENOMEM, "Virtual memory exhausted");
2479 * Process IDs of the subprocess, or negative if that subprocess
2482 static pid_t command_pid;
2485 outbuf_memory_error (buf)
2488 static const char msg[] = "E Fatal server error\n\
2489 error ENOMEM Virtual memory exhausted.\n";
2490 if (command_pid > 0)
2491 kill (command_pid, SIGTERM);
2494 * We have arranged things so that printing this now either will
2495 * be legal, or the "E fatal error" line will get glommed onto the
2496 * end of an existing "E" or "M" response.
2499 /* If this gives an error, not much we could do. syslog() it? */
2500 write (STDOUT_FILENO, msg, sizeof (msg) - 1);
2501 #ifdef HAVE_SYSLOG_H
2502 syslog (LOG_DAEMON | LOG_ERR, "virtual memory exhausted");
2508 input_memory_error (buf)
2511 outbuf_memory_error (buf);
2516 /* If command is legal, return 1.
2517 * Else if command is illegal and croak_on_illegal is set, then die.
2518 * Else just return 0 to indicate that command is illegal.
2521 check_command_legal_p (cmd_name)
2524 /* Right now, only pserver notices illegal commands -- namely,
2525 * write attempts by a read-only user. Therefore, if CVS_Username
2526 * is not set, this just returns 1, because CVS_Username unset
2527 * means pserver is not active.
2529 #ifdef AUTH_SERVER_SUPPORT
2530 if (CVS_Username == NULL)
2533 if (lookup_command_attribute (cmd_name) & CVS_CMD_MODIFIES_REPOSITORY)
2535 /* This command has the potential to modify the repository, so
2536 * we check if the user have permission to do that.
2538 * (Only relevant for remote users -- local users can do
2539 * whatever normal Unix file permissions allow them to do.)
2541 * The decision method:
2543 * If $CVSROOT/CVSADMROOT_READERS exists and user is listed
2544 * in it, then read-only access for user.
2546 * Or if $CVSROOT/CVSADMROOT_WRITERS exists and user NOT
2547 * listed in it, then also read-only access for user.
2549 * Else read-write access for user.
2552 char *linebuf = NULL;
2554 size_t linebuf_len = 0;
2561 flen = strlen (current_parsed_root->directory)
2562 + strlen (CVSROOTADM)
2563 + strlen (CVSROOTADM_READERS)
2566 fname = xmalloc (flen);
2567 (void) sprintf (fname, "%s/%s/%s", current_parsed_root->directory,
2568 CVSROOTADM, CVSROOTADM_READERS);
2570 fp = fopen (fname, "r");
2574 if (!existence_error (errno))
2576 /* Need to deny access, so that attackers can't fool
2577 us with some sort of denial of service attack. */
2578 error (0, errno, "cannot open %s", fname);
2583 else /* successfully opened readers file */
2585 while ((num_red = getline (&linebuf, &linebuf_len, fp)) >= 0)
2587 /* Hmmm, is it worth importing my own readline
2588 library into CVS? It takes care of chopping
2589 leading and trailing whitespace, "#" comments, and
2590 newlines automatically when so requested. Would
2591 save some code here... -kff */
2593 /* Chop newline by hand, for strcmp()'s sake. */
2594 if (num_red > 0 && linebuf[num_red - 1] == '\n')
2595 linebuf[num_red - 1] = '\0';
2597 if (strcmp (linebuf, CVS_Username) == 0)
2598 goto handle_illegal;
2600 if (num_red < 0 && !feof (fp))
2601 error (0, errno, "cannot read %s", fname);
2603 /* If not listed specifically as a reader, then this user
2604 has write access by default unless writers are also
2605 specified in a file . */
2606 if (fclose (fp) < 0)
2607 error (0, errno, "cannot close %s", fname);
2611 /* Now check the writers file. */
2613 flen = strlen (current_parsed_root->directory)
2614 + strlen (CVSROOTADM)
2615 + strlen (CVSROOTADM_WRITERS)
2618 fname = xmalloc (flen);
2619 (void) sprintf (fname, "%s/%s/%s", current_parsed_root->directory,
2620 CVSROOTADM, CVSROOTADM_WRITERS);
2622 fp = fopen (fname, "r");
2628 if (existence_error (errno))
2630 /* Writers file does not exist, so everyone is a writer,
2637 /* Need to deny access, so that attackers can't fool
2638 us with some sort of denial of service attack. */
2639 error (0, errno, "cannot read %s", fname);
2646 while ((num_red = getline (&linebuf, &linebuf_len, fp)) >= 0)
2648 /* Chop newline by hand, for strcmp()'s sake. */
2649 if (num_red > 0 && linebuf[num_red - 1] == '\n')
2650 linebuf[num_red - 1] = '\0';
2652 if (strcmp (linebuf, CVS_Username) == 0)
2658 if (num_red < 0 && !feof (fp))
2659 error (0, errno, "cannot read %s", fname);
2663 if (fclose (fp) < 0)
2664 error (0, errno, "cannot close %s", fname);
2670 else /* writers file exists, but this user not listed in it */
2673 if (fclose (fp) < 0)
2674 error (0, errno, "cannot close %s", fname);
2681 #endif /* AUTH_SERVER_SUPPORT */
2683 /* If ever reach end of this function, command must be legal. */
2689 /* Execute COMMAND in a subprocess with the approriate funky things done. */
2691 static struct fd_set_wrapper { fd_set fds; } command_fds_to_drain;
2693 static int max_command_fd;
2696 #ifdef SERVER_FLOWCONTROL
2697 static int flowcontrol_pipe[2];
2698 #endif /* SERVER_FLOWCONTROL */
2703 * Set buffer FD to non-blocking I/O. Returns 0 for success or errno
2707 set_nonblock_fd (fd)
2712 flags = fcntl (fd, F_GETFL, 0);
2715 if (fcntl (fd, F_SETFL, flags | O_NONBLOCK) < 0)
2723 * Set buffer FD to blocking I/O. Returns 0 for success or errno code.
2731 flags = fcntl (fd, F_GETFL, 0);
2734 if (fcntl (fd, F_SETFL, flags & ~O_NONBLOCK) < 0)
2742 do_cvs_command (cmd_name, command)
2744 int (*command) PROTO((int argc, char **argv));
2747 * The following file descriptors are set to -1 if that file is not
2751 /* Data on these pipes is a series of '\n'-terminated lines. */
2756 * Data on this pipe is a series of counted (see buf_send_counted)
2757 * packets. Each packet must be processed atomically (i.e. not
2758 * interleaved with data from stdout_pipe or stderr_pipe).
2760 int protocol_pipe[2];
2762 int dev_null_fd = -1;
2767 stdout_pipe[0] = -1;
2768 stdout_pipe[1] = -1;
2769 stderr_pipe[0] = -1;
2770 stderr_pipe[1] = -1;
2771 protocol_pipe[0] = -1;
2772 protocol_pipe[1] = -1;
2774 server_write_entries ();
2776 if (print_pending_error ())
2777 goto free_args_and_return;
2779 /* Global `cvs_cmd_name' is probably "server" right now -- only
2780 serve_export() sets it to anything else. So we will use local
2781 parameter `cmd_name' to determine if this command is legal for
2783 if (!check_command_legal_p (cmd_name))
2785 buf_output0 (buf_to_net, "E ");
2786 buf_output0 (buf_to_net, program_name);
2787 buf_output0 (buf_to_net, " [server aborted]: \"");
2788 buf_output0 (buf_to_net, cmd_name);
2789 buf_output0 (buf_to_net, "\" requires write access to the repository\n\
2791 goto free_args_and_return;
2793 cvs_cmd_name = cmd_name;
2795 (void) server_notify ();
2798 * We use a child process which actually does the operation. This
2799 * is so we can intercept its standard output. Even if all of CVS
2800 * were written to go to some special routine instead of writing
2801 * to stdout or stderr, we would still need to do the same thing
2802 * for the RCS commands.
2805 if (pipe (stdout_pipe) < 0)
2807 buf_output0 (buf_to_net, "E pipe failed\n");
2808 print_error (errno);
2811 if (pipe (stderr_pipe) < 0)
2813 buf_output0 (buf_to_net, "E pipe failed\n");
2814 print_error (errno);
2817 if (pipe (protocol_pipe) < 0)
2819 buf_output0 (buf_to_net, "E pipe failed\n");
2820 print_error (errno);
2823 #ifdef SERVER_FLOWCONTROL
2824 if (pipe (flowcontrol_pipe) < 0)
2826 buf_output0 (buf_to_net, "E pipe failed\n");
2827 print_error (errno);
2830 set_nonblock_fd (flowcontrol_pipe[0]);
2831 set_nonblock_fd (flowcontrol_pipe[1]);
2832 #endif /* SERVER_FLOWCONTROL */
2834 dev_null_fd = CVS_OPEN (DEVNULL, O_RDONLY);
2835 if (dev_null_fd < 0)
2837 buf_output0 (buf_to_net, "E open /dev/null failed\n");
2838 print_error (errno);
2842 /* We shouldn't have any partial lines from cvs_output and
2843 cvs_outerr, but we handle them here in case there is a bug. */
2844 /* FIXME: appending a newline, rather than using "MT" as we
2845 do in the child process, is probably not really a very good
2846 way to "handle" them. */
2847 if (! buf_empty_p (saved_output))
2849 buf_append_char (saved_output, '\n');
2850 buf_copy_lines (buf_to_net, saved_output, 'M');
2852 if (! buf_empty_p (saved_outerr))
2854 buf_append_char (saved_outerr, '\n');
2855 buf_copy_lines (buf_to_net, saved_outerr, 'E');
2858 /* Flush out any pending data. */
2859 buf_flush (buf_to_net, 1);
2861 /* Don't use vfork; we're not going to exec(). */
2862 command_pid = fork ();
2863 if (command_pid < 0)
2865 buf_output0 (buf_to_net, "E fork failed\n");
2866 print_error (errno);
2869 if (command_pid == 0)
2873 /* Since we're in the child, and the parent is going to take
2874 care of packaging up our error messages, we can clear this
2876 error_use_protocol = 0;
2878 protocol = fd_buffer_initialize (protocol_pipe[1], 0,
2879 protocol_memory_error);
2881 /* At this point we should no longer be using buf_to_net and
2882 buf_from_net. Instead, everything should go through
2884 if (buf_to_net != NULL)
2886 buf_free (buf_to_net);
2889 if (buf_from_net != NULL)
2891 buf_free (buf_from_net);
2892 buf_from_net = NULL;
2895 /* These were originally set up to use outbuf_memory_error.
2896 Since we're now in the child, we should use the simpler
2897 protocol_memory_error function. */
2898 saved_output->memory_error = protocol_memory_error;
2899 saved_outerr->memory_error = protocol_memory_error;
2901 if (dup2 (dev_null_fd, STDIN_FILENO) < 0)
2902 error (1, errno, "can't set up pipes");
2903 if (dup2 (stdout_pipe[1], STDOUT_FILENO) < 0)
2904 error (1, errno, "can't set up pipes");
2905 if (dup2 (stderr_pipe[1], STDERR_FILENO) < 0)
2906 error (1, errno, "can't set up pipes");
2907 close (dev_null_fd);
2908 close (stdout_pipe[0]);
2909 close (stdout_pipe[1]);
2910 close (stderr_pipe[0]);
2911 close (stderr_pipe[1]);
2912 close (protocol_pipe[0]);
2913 close_on_exec (protocol_pipe[1]);
2914 #ifdef SERVER_FLOWCONTROL
2915 close_on_exec (flowcontrol_pipe[0]);
2916 close (flowcontrol_pipe[1]);
2917 #endif /* SERVER_FLOWCONTROL */
2920 * Set this in .bashrc if you want to give yourself time to attach
2921 * to the subprocess with a debugger.
2923 if (getenv ("CVS_SERVER_SLEEP"))
2925 int secs = atoi (getenv ("CVS_SERVER_SLEEP"));
2929 exitstatus = (*command) (argument_count, argument_vector);
2931 /* Output any partial lines. If the client doesn't support
2932 "MT", we go ahead and just tack on a newline since the
2933 protocol doesn't support anything better. */
2934 if (! buf_empty_p (saved_output))
2936 buf_output0 (protocol, supported_response ("MT") ? "MT text " : "M ");
2937 buf_append_buffer (protocol, saved_output);
2938 buf_output (protocol, "\n", 1);
2939 buf_send_counted (protocol);
2941 /* For now we just discard partial lines on stderr. I suspect
2942 that CVS can't write such lines unless there is a bug. */
2944 buf_free (protocol);
2946 /* Close the pipes explicitly in order to send an EOF to the parent,
2947 * then wait for the parent to close the flow control pipe. This
2948 * avoids a race condition where a child which dumped more than the
2949 * high water mark into the pipes could complete its job and exit,
2950 * leaving the parent process to attempt to write a stop byte to the
2951 * closed flow control pipe, which earned the parent a SIGPIPE, which
2952 * it normally only expects on the network pipe and that causes it to
2953 * exit with an error message, rather than the SIGCHILD that it knows
2954 * how to handle correctly.
2956 /* Let exit() close STDIN - it's from /dev/null anyhow. */
2959 close (protocol_pipe[1]);
2960 #ifdef SERVER_FLOWCONTROL
2964 set_block_fd (flowcontrol_pipe[0]);
2965 while ((status = read (flowcontrol_pipe[0], &junk, 1)) > 0);
2967 /* FIXME: No point in printing an error message with error(),
2968 * as STDERR is already closed, but perhaps this could be syslogged?
2974 /* Don't call server_cleanup - the parent will handle that. */
2975 #ifdef SYSTEM_CLEANUP
2976 /* Hook for OS-specific behavior, for example socket subsystems on
2977 NT and OS2 or dealing with windows and arguments on Mac. */
2983 /* OK, sit around getting all the input from the child. */
2985 struct buffer *stdoutbuf = NULL;
2986 struct buffer *stderrbuf = NULL;
2987 struct buffer *protocol_inbuf = NULL;
2989 /* Number of file descriptors to check in select (). */
2991 int count_needed = 1;
2992 #ifdef SERVER_FLOWCONTROL
2993 int have_flowcontrolled = 0;
2994 #endif /* SERVER_FLOWCONTROL */
2996 FD_ZERO (&command_fds_to_drain.fds);
2997 num_to_check = stdout_pipe[0];
2998 FD_SET (stdout_pipe[0], &command_fds_to_drain.fds);
2999 if (stderr_pipe[0] > num_to_check)
3000 num_to_check = stderr_pipe[0];
3001 FD_SET (stderr_pipe[0], &command_fds_to_drain.fds);
3002 if (protocol_pipe[0] > num_to_check)
3003 num_to_check = protocol_pipe[0];
3004 FD_SET (protocol_pipe[0], &command_fds_to_drain.fds);
3005 if (STDOUT_FILENO > num_to_check)
3006 num_to_check = STDOUT_FILENO;
3008 max_command_fd = num_to_check;
3011 * File descriptors are numbered from 0, so num_to_check needs to
3012 * be one larger than the largest descriptor.
3015 if (num_to_check > FD_SETSIZE)
3017 buf_output0 (buf_to_net,
3018 "E internal error: FD_SETSIZE not big enough.\n\
3023 stdoutbuf = fd_buffer_initialize (stdout_pipe[0], 1,
3024 input_memory_error);
3026 stderrbuf = fd_buffer_initialize (stderr_pipe[0], 1,
3027 input_memory_error);
3029 protocol_inbuf = fd_buffer_initialize (protocol_pipe[0], 1,
3030 input_memory_error);
3032 set_nonblock (buf_to_net);
3033 set_nonblock (stdoutbuf);
3034 set_nonblock (stderrbuf);
3035 set_nonblock (protocol_inbuf);
3037 if (close (stdout_pipe[1]) < 0)
3039 buf_output0 (buf_to_net, "E close failed\n");
3040 print_error (errno);
3044 stdout_pipe[1] = -1;
3046 if (close (stderr_pipe[1]) < 0)
3048 buf_output0 (buf_to_net, "E close failed\n");
3049 print_error (errno);
3053 stderr_pipe[1] = -1;
3055 if (close (protocol_pipe[1]) < 0)
3057 buf_output0 (buf_to_net, "E close failed\n");
3058 print_error (errno);
3062 protocol_pipe[1] = -1;
3064 #ifdef SERVER_FLOWCONTROL
3065 if (close (flowcontrol_pipe[0]) < 0)
3067 buf_output0 (buf_to_net, "E close failed\n");
3068 print_error (errno);
3072 flowcontrol_pipe[0] = -1;
3073 #endif /* SERVER_FLOWCONTROL */
3075 if (close (dev_null_fd) < 0)
3077 buf_output0 (buf_to_net, "E close failed\n");
3078 print_error (errno);
3079 dev_null_fd = -1; /* Do not try to close it again. */
3085 while (stdout_pipe[0] >= 0
3086 || stderr_pipe[0] >= 0
3087 || protocol_pipe[0] >= 0
3088 || count_needed <= 0)
3093 struct timeval *timeout_ptr;
3094 struct timeval timeout;
3095 #ifdef SERVER_FLOWCONTROL
3099 * See if we are swamping the remote client and filling our VM.
3100 * Tell child to hold off if we do.
3102 bufmemsize = buf_count_mem (buf_to_net);
3103 if (!have_flowcontrolled && (bufmemsize > SERVER_HI_WATER))
3105 if (write(flowcontrol_pipe[1], "S", 1) == 1)
3106 have_flowcontrolled = 1;
3108 else if (have_flowcontrolled && (bufmemsize < SERVER_LO_WATER))
3110 if (write(flowcontrol_pipe[1], "G", 1) == 1)
3111 have_flowcontrolled = 0;
3113 #endif /* SERVER_FLOWCONTROL */
3116 FD_ZERO (&writefds);
3118 if (count_needed <= 0)
3120 /* there is data pending which was read from the protocol pipe
3121 * so don't block if we don't find any data
3124 timeout.tv_usec = 0;
3125 timeout_ptr = &timeout;
3129 /* block indefinately */
3133 if (! buf_empty_p (buf_to_net))
3134 FD_SET (STDOUT_FILENO, &writefds);
3136 if (stdout_pipe[0] >= 0)
3138 FD_SET (stdout_pipe[0], &readfds);
3140 if (stderr_pipe[0] >= 0)
3142 FD_SET (stderr_pipe[0], &readfds);
3144 if (protocol_pipe[0] >= 0)
3146 FD_SET (protocol_pipe[0], &readfds);
3149 /* This process of selecting on the three pipes means that
3150 we might not get output in the same order in which it
3151 was written, thus producing the well-known
3152 "out-of-order" bug. If the child process uses
3153 cvs_output and cvs_outerr, it will send everything on
3154 the protocol_pipe and avoid this problem, so the
3155 solution is to use cvs_output and cvs_outerr in the
3158 /* This used to select on exceptions too, but as far
3159 as I know there was never any reason to do that and
3160 SCO doesn't let you select on exceptions on pipes. */
3161 numfds = select (num_to_check, &readfds, &writefds,
3162 (fd_set *)0, timeout_ptr);
3166 buf_output0 (buf_to_net, "E select failed\n");
3167 print_error (errno);
3171 } while (numfds < 0);
3176 FD_ZERO (&writefds);
3179 if (FD_ISSET (STDOUT_FILENO, &writefds))
3181 /* What should we do with errors? syslog() them? */
3182 buf_send_output (buf_to_net);
3185 if (protocol_pipe[0] >= 0
3186 && (FD_ISSET (protocol_pipe[0], &readfds)))
3191 status = buf_input_data (protocol_inbuf, &count_read);
3195 close (protocol_pipe[0]);
3196 protocol_pipe[0] = -1;
3198 else if (status > 0)
3200 buf_output0 (buf_to_net, "E buf_input_data failed\n");
3201 print_error (status);
3207 * We only call buf_copy_counted if we have read
3208 * enough bytes to make it worthwhile. This saves us
3209 * from continually recounting the amount of data we
3212 count_needed -= count_read;
3214 /* this is still part of the protocol pipe procedure, but it is
3215 * outside the above conditional so that unprocessed data can be
3216 * left in the buffer and stderr/stdout can be read when a flush
3217 * signal is received and control can return here without passing
3218 * through the select code and maybe blocking
3220 while (count_needed <= 0)
3224 count_needed = buf_copy_counted (buf_to_net,
3228 /* What should we do with errors? syslog() them? */
3229 buf_send_output (buf_to_net);
3231 /* If SPECIAL got set to <0, it means that the child
3232 * wants us to flush the pipe & maybe stderr or stdout.
3234 * After that we break to read stderr & stdout again before
3235 * going back to the protocol pipe
3237 * Upon breaking, count_needed = 0, so the next pass will only
3238 * perform a non-blocking select before returning here to finish
3239 * processing data we already read from the protocol buffer
3248 /* If the client supports the 'F' command, we send it. */
3249 if (supported_response ("F"))
3251 buf_append_char (buf_to_net, 'F');
3252 buf_append_char (buf_to_net, '\n');
3259 if (stdout_pipe[0] >= 0
3260 && (FD_ISSET (stdout_pipe[0], &readfds)))
3264 status = buf_input_data (stdoutbuf, (int *) NULL);
3266 buf_copy_lines (buf_to_net, stdoutbuf, 'M');
3270 close (stdout_pipe[0]);
3271 stdout_pipe[0] = -1;
3273 else if (status > 0)
3275 buf_output0 (buf_to_net, "E buf_input_data failed\n");
3276 print_error (status);
3281 /* What should we do with errors? syslog() them? */
3282 buf_send_output (buf_to_net);
3285 if (stderr_pipe[0] >= 0
3286 && (FD_ISSET (stderr_pipe[0], &readfds)))
3290 status = buf_input_data (stderrbuf, (int *) NULL);
3292 buf_copy_lines (buf_to_net, stderrbuf, 'E');
3296 close (stderr_pipe[0]);
3297 stderr_pipe[0] = -1;
3299 else if (status > 0)
3301 buf_output0 (buf_to_net, "E buf_input_data failed\n");
3302 print_error (status);
3307 /* What should we do with errors? syslog() them? */
3308 buf_send_output (buf_to_net);
3313 * OK, we've gotten EOF on all the pipes. If there is
3314 * anything left on stdoutbuf or stderrbuf (this could only
3315 * happen if there was no trailing newline), send it over.
3317 if (! buf_empty_p (stdoutbuf))
3319 buf_append_char (stdoutbuf, '\n');
3320 buf_copy_lines (buf_to_net, stdoutbuf, 'M');
3322 if (! buf_empty_p (stderrbuf))
3324 buf_append_char (stderrbuf, '\n');
3325 buf_copy_lines (buf_to_net, stderrbuf, 'E');
3327 if (! buf_empty_p (protocol_inbuf))
3328 buf_output0 (buf_to_net,
3329 "E Protocol error: uncounted data discarded\n");
3331 #ifdef SERVER_FLOWCONTROL
3332 close (flowcontrol_pipe[1]);
3333 flowcontrol_pipe[1] = -1;
3334 #endif /* SERVER_FLOWCONTROL */
3338 while (command_pid > 0)
3342 waited_pid = waitpid (command_pid, &status, 0);
3346 * Intentionally ignoring EINTR. Other errors
3352 if (WIFEXITED (status))
3353 errs += WEXITSTATUS (status);
3356 int sig = WTERMSIG (status);
3359 * This is really evil, because signals might be numbered
3360 * differently on the two systems. We should be using
3361 * signal names (either of the "Terminated" or the "SIGTERM"
3362 * variety). But cvs doesn't currently use libiberty...we
3363 * could roll our own.... FIXME.
3365 buf_output0 (buf_to_net, "E Terminated with fatal signal ");
3366 sprintf (buf, "%d\n", sig);
3367 buf_output0 (buf_to_net, buf);
3369 /* Test for a core dump. */
3370 if (WCOREDUMP (status))
3372 buf_output0 (buf_to_net, "E Core dumped; preserving ");
3373 buf_output0 (buf_to_net, orig_server_temp_dir);
3374 buf_output0 (buf_to_net, " on server.\n\
3375 E CVS locks may need cleaning up.\n");
3376 dont_delete_temp = 1;
3380 if (waited_pid == command_pid)
3386 * OK, we've waited for the child. By now all CVS locks are free
3387 * and it's OK to block on the network.
3389 set_block (buf_to_net);
3390 buf_flush (buf_to_net, 1);
3393 buf_shutdown (protocol_inbuf);
3394 buf_free (protocol_inbuf);
3395 protocol_inbuf = NULL;
3399 buf_shutdown (stderrbuf);
3400 buf_free (stderrbuf);
3405 buf_shutdown (stdoutbuf);
3406 buf_free (stdoutbuf);
3414 /* We will have printed an error message already. */
3415 buf_output0 (buf_to_net, "error \n");
3417 buf_output0 (buf_to_net, "ok\n");
3418 goto free_args_and_return;
3421 if (command_pid > 0)
3422 kill (command_pid, SIGTERM);
3424 while (command_pid > 0)
3427 waited_pid = waitpid (command_pid, (int *) 0, 0);
3428 if (waited_pid < 0 && errno == EINTR)
3430 if (waited_pid == command_pid)
3434 if (dev_null_fd >= 0)
3435 close (dev_null_fd);
3436 close (protocol_pipe[0]);
3437 close (protocol_pipe[1]);
3438 close (stderr_pipe[0]);
3439 close (stderr_pipe[1]);
3440 close (stdout_pipe[0]);
3441 close (stdout_pipe[1]);
3442 #ifdef SERVER_FLOWCONTROL
3443 close (flowcontrol_pipe[0]);
3444 close (flowcontrol_pipe[1]);
3445 #endif /* SERVER_FLOWCONTROL */
3447 free_args_and_return:
3448 /* Now free the arguments. */
3450 /* argument_vector[0] is a dummy argument, we don't mess with it. */
3452 for (cp = argument_vector + 1;
3453 cp < argument_vector + argument_count;
3460 /* Flush out any data not yet sent. */
3461 set_block (buf_to_net);
3462 buf_flush (buf_to_net, 1);
3467 #ifdef SERVER_FLOWCONTROL
3469 * Called by the child at convenient points in the server's execution for
3470 * the server child to block.. ie: when it has no locks active.
3473 server_pause_check()
3478 while (read (flowcontrol_pipe[0], buf, 1) == 1)
3480 if (*buf == 'S') /* Stop */
3482 else if (*buf == 'G') /* Go */
3488 int numfds, numtocheck;
3492 FD_SET (flowcontrol_pipe[0], &fds);
3493 numtocheck = flowcontrol_pipe[0] + 1;
3496 numfds = select (numtocheck, &fds, (fd_set *)0,
3497 (fd_set *)0, (struct timeval *)NULL);
3501 buf_output0 (buf_to_net, "E select failed\n");
3502 print_error (errno);
3505 } while (numfds < 0);
3507 if (FD_ISSET (flowcontrol_pipe[0], &fds))
3511 while ((got = read (flowcontrol_pipe[0], buf, 1)) == 1)
3513 if (*buf == 'S') /* Stop */
3515 else if (*buf == 'G') /* Go */
3521 /* This assumes that we are using BSD or POSIX nonblocking
3522 I/O. System V nonblocking I/O returns zero if there is
3525 error (1, 0, "flow control EOF");
3526 if (got < 0 && ! blocking_error (errno))
3528 error (1, errno, "flow control read failed");
3533 #endif /* SERVER_FLOWCONTROL */
3535 /* This variable commented in server.h. */
3536 char *server_dir = NULL;
3540 static void output_dir PROTO((const char *, const char *));
3543 output_dir (update_dir, repository)
3544 const char *update_dir;
3545 const char *repository;
3547 if (server_dir != NULL)
3549 buf_output0 (protocol, server_dir);
3550 buf_output0 (protocol, "/");
3552 if (update_dir[0] == '\0')
3553 buf_output0 (protocol, ".");
3555 buf_output0 (protocol, update_dir);
3556 buf_output0 (protocol, "/\n");
3557 buf_output0 (protocol, repository);
3558 buf_output0 (protocol, "/");
3564 * Entries line that we are squirreling away to send to the client when
3567 static char *entries_line;
3570 * File which has been Scratch_File'd, we are squirreling away that fact
3571 * to inform the client when we are ready.
3573 static char *scratched_file;
3576 * The scratched_file will need to be removed as well as having its entry
3579 static int kill_scratched_file;
3584 server_register (name, version, timestamp, options, tag, date, conflict)
3586 const char *version;
3587 const char *timestamp;
3588 const char *options;
3591 const char *conflict;
3595 if (options == NULL)
3600 (void) fprintf (stderr,
3601 "%s-> server_register(%s, %s, %s, %s, %s, %s, %s)\n",
3603 name, version, timestamp ? timestamp : "", options,
3604 tag ? tag : "", date ? date : "",
3605 conflict ? conflict : "");
3608 if (entries_line != NULL)
3611 * If CVS decides to Register it more than once (which happens
3612 * on "cvs update foo/foo.c" where foo and foo.c are already
3613 * checked out), use the last of the entries lines Register'd.
3615 free (entries_line);
3619 * I have reports of Scratch_Entry and Register both happening, in
3620 * two different cases. Using the last one which happens is almost
3621 * surely correct; I haven't tracked down why they both happen (or
3622 * even verified that they are for the same file).
3624 if (scratched_file != NULL)
3626 free (scratched_file);
3627 scratched_file = NULL;
3630 len = (strlen (name) + strlen (version) + strlen (options) + 80);
3632 len += strlen (tag);
3634 len += strlen (date);
3636 entries_line = xmalloc (len);
3637 sprintf (entries_line, "/%s/%s/", name, version);
3638 if (conflict != NULL)
3640 strcat (entries_line, "+=");
3642 strcat (entries_line, "/");
3643 strcat (entries_line, options);
3644 strcat (entries_line, "/");
3647 strcat (entries_line, "T");
3648 strcat (entries_line, tag);
3650 else if (date != NULL)
3652 strcat (entries_line, "D");
3653 strcat (entries_line, date);
3660 server_scratch (fname)
3664 * I have reports of Scratch_Entry and Register both happening, in
3665 * two different cases. Using the last one which happens is almost
3666 * surely correct; I haven't tracked down why they both happen (or
3667 * even verified that they are for the same file).
3669 * Don't know if this is what whoever wrote the above comment was
3670 * talking about, but this can happen in the case where a join
3671 * removes a file - the call to Register puts the '-vers' into the
3672 * Entries file after the file is removed
3674 if (entries_line != NULL)
3676 free (entries_line);
3677 entries_line = NULL;
3680 if (scratched_file != NULL)
3682 buf_output0 (protocol,
3683 "E CVS server internal error: duplicate Scratch_Entry\n");
3684 buf_send_counted (protocol);
3687 scratched_file = xstrdup (fname);
3688 kill_scratched_file = 1;
3692 server_scratch_entry_only ()
3694 kill_scratched_file = 0;
3697 /* Print a new entries line, from a previous server_register. */
3703 buf_output0 (protocol, entries_line);
3704 buf_output (protocol, "\n", 1);
3707 /* Return the error message as the Entries line. */
3708 buf_output0 (protocol,
3709 "CVS server internal error: Register missing\n");
3710 free (entries_line);
3711 entries_line = NULL;
3719 do_cvs_command ("commit", commit);
3723 checked_in_response (file, update_dir, repository)
3728 if (supported_response ("Mode"))
3733 if ( CVS_STAT (file, &sb) < 0)
3735 /* Not clear to me why the file would fail to exist, but it
3736 was happening somewhere in the testsuite. */
3737 if (!existence_error (errno))
3738 error (0, errno, "cannot stat %s", file);
3742 buf_output0 (protocol, "Mode ");
3743 mode_string = mode_to_string (sb.st_mode);
3744 buf_output0 (protocol, mode_string);
3745 buf_output0 (protocol, "\n");
3750 buf_output0 (protocol, "Checked-in ");
3751 output_dir (update_dir, repository);
3752 buf_output0 (protocol, file);
3753 buf_output (protocol, "\n", 1);
3754 new_entries_line ();
3758 server_checked_in (file, update_dir, repository)
3760 const char *update_dir;
3761 const char *repository;
3764 assert (update_dir);
3765 assert (repository);
3769 if (scratched_file != NULL && entries_line == NULL)
3772 * This happens if we are now doing a "cvs remove" after a previous
3773 * "cvs add" (without a "cvs ci" in between).
3775 buf_output0 (protocol, "Remove-entry ");
3776 output_dir (update_dir, repository);
3777 buf_output0 (protocol, file);
3778 buf_output (protocol, "\n", 1);
3779 free (scratched_file);
3780 scratched_file = NULL;
3784 checked_in_response (file, update_dir, repository);
3786 buf_send_counted (protocol);
3790 server_update_entries (file, update_dir, repository, updated)
3792 const char *update_dir;
3793 const char *repository;
3794 enum server_updated_arg4 updated;
3798 if (updated == SERVER_UPDATED)
3799 checked_in_response (file, update_dir, repository);
3802 if (!supported_response ("New-entry"))
3804 buf_output0 (protocol, "New-entry ");
3805 output_dir (update_dir, repository);
3806 buf_output0 (protocol, file);
3807 buf_output (protocol, "\n", 1);
3808 new_entries_line ();
3811 buf_send_counted (protocol);
3818 do_cvs_command ("update", update);
3825 do_cvs_command ("diff", diff);
3832 do_cvs_command ("log", cvslog);
3839 do_cvs_command ("rlog", cvslog);
3846 do_cvs_command ("add", add);
3853 do_cvs_command ("remove", cvsremove);
3860 do_cvs_command ("status", cvsstatus);
3867 do_cvs_command ("rdiff", patch);
3874 do_cvs_command ("tag", cvstag);
3881 do_cvs_command ("rtag", cvstag);
3888 do_cvs_command ("import", import);
3895 do_cvs_command ("admin", admin);
3902 do_cvs_command ("history", history);
3909 do_cvs_command ("release", release);
3912 static void serve_watch_on PROTO ((char *));
3915 serve_watch_on (arg)
3918 do_cvs_command ("watch", watch_on);
3921 static void serve_watch_off PROTO ((char *));
3924 serve_watch_off (arg)
3927 do_cvs_command ("watch", watch_off);
3930 static void serve_watch_add PROTO ((char *));
3933 serve_watch_add (arg)
3936 do_cvs_command ("watch", watch_add);
3939 static void serve_watch_remove PROTO ((char *));
3942 serve_watch_remove (arg)
3945 do_cvs_command ("watch", watch_remove);
3948 static void serve_watchers PROTO ((char *));
3951 serve_watchers (arg)
3954 do_cvs_command ("watchers", watchers);
3957 static void serve_editors PROTO ((char *));
3963 do_cvs_command ("editors", editors);
3966 static void serve_noop PROTO ((char *));
3973 server_write_entries ();
3974 if (!print_pending_error ())
3976 (void) server_notify ();
3977 buf_output0 (buf_to_net, "ok\n");
3979 buf_flush (buf_to_net, 1);
3982 static void serve_version PROTO ((char *));
3988 do_cvs_command ("version", version);
3991 static void serve_init PROTO ((char *));
3997 cvsroot_t *saved_parsed_root;
3999 if (!isabsolute (arg))
4001 if (alloc_pending (80 + strlen (arg)))
4002 sprintf (pending_error_text,
4003 "E init %s must be an absolute pathname", arg);
4005 #ifdef AUTH_SERVER_SUPPORT
4006 else if (Pserver_Repos != NULL)
4008 if (strcmp (Pserver_Repos, arg) != 0)
4010 if (alloc_pending (80 + strlen (Pserver_Repos) + strlen (arg)))
4011 /* The explicitness is to aid people who are writing clients.
4012 I don't see how this information could help an
4014 sprintf (pending_error_text, "\
4015 E Protocol error: init says \"%s\" but pserver says \"%s\"",
4016 arg, Pserver_Repos);
4021 if (print_pending_error ())
4024 saved_parsed_root = current_parsed_root;
4025 current_parsed_root = local_cvsroot (arg);
4026 do_cvs_command ("init", init);
4027 free_cvsroot_t (current_parsed_root);
4028 current_parsed_root = saved_parsed_root;
4031 static void serve_annotate PROTO ((char *));
4034 serve_annotate (arg)
4037 do_cvs_command ("annotate", annotate);
4040 static void serve_rannotate PROTO ((char *));
4043 serve_rannotate (arg)
4046 do_cvs_command ("rannotate", annotate);
4056 if (print_pending_error ())
4059 if (!isdir (CVSADM))
4062 * The client has not sent a "Repository" line. Check out
4063 * into a pristine directory.
4065 tempdir = xmalloc (strlen (server_temp_dir) + 80);
4066 if (tempdir == NULL)
4068 buf_output0 (buf_to_net, "E Out of memory\n");
4071 strcpy (tempdir, server_temp_dir);
4072 strcat (tempdir, "/checkout-dir");
4073 status = mkdir_p (tempdir);
4074 if (status != 0 && status != EEXIST)
4076 buf_output0 (buf_to_net, "E Cannot create ");
4077 buf_output0 (buf_to_net, tempdir);
4078 buf_append_char (buf_to_net, '\n');
4079 print_error (errno);
4084 if ( CVS_CHDIR (tempdir) < 0)
4086 buf_output0 (buf_to_net, "E Cannot change to directory ");
4087 buf_output0 (buf_to_net, tempdir);
4088 buf_append_char (buf_to_net, '\n');
4089 print_error (errno);
4096 /* Compensate for server_export()'s setting of cvs_cmd_name.
4098 * [It probably doesn't matter if do_cvs_command() gets "export"
4099 * or "checkout", but we ought to be accurate where possible.]
4101 do_cvs_command ((strcmp (cvs_cmd_name, "export") == 0) ?
4102 "export" : "checkout",
4110 /* Tell checkout() to behave like export not checkout. */
4111 cvs_cmd_name = "export";
4118 server_copy_file (file, update_dir, repository, newfile)
4120 const char *update_dir;
4121 const char *repository;
4122 const char *newfile;
4124 /* At least for now, our practice is to have the server enforce
4125 noexec for the repository and the client enforce it for the
4126 working directory. This might want more thought, and/or
4127 documentation in cvsclient.texi (other responses do it
4130 if (!supported_response ("Copy-file"))
4132 buf_output0 (protocol, "Copy-file ");
4133 output_dir (update_dir, repository);
4134 buf_output0 (protocol, file);
4135 buf_output0 (protocol, "\n");
4136 buf_output0 (protocol, newfile);
4137 buf_output0 (protocol, "\n");
4140 /* See server.h for description. */
4143 server_modtime (finfo, vers_ts)
4144 struct file_info *finfo;
4147 char date[MAXDATELEN];
4148 char outdate[MAXDATELEN];
4150 assert (vers_ts->vn_rcs != NULL);
4152 if (!supported_response ("Mod-time"))
4155 if (RCS_getrevtime (finfo->rcs, vers_ts->vn_rcs, date, 0) == (time_t) -1)
4156 /* FIXME? should we be printing some kind of warning? For one
4157 thing I'm not 100% sure whether this happens in non-error
4160 date_to_internet (outdate, date);
4161 buf_output0 (protocol, "Mod-time ");
4162 buf_output0 (protocol, outdate);
4163 buf_output0 (protocol, "\n");
4166 /* See server.h for description. */
4168 #if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__)
4169 /* Need to prototype because mode_t might be smaller than int. */
4172 struct file_info *finfo,
4174 enum server_updated_arg4 updated,
4176 unsigned char *checksum,
4177 struct buffer *filebuf)
4180 server_updated (finfo, vers, updated, mode, checksum, filebuf)
4181 struct file_info *finfo;
4183 enum server_updated_arg4 updated;
4185 unsigned char *checksum;
4186 struct buffer *filebuf;
4191 /* Hmm, maybe if we did the same thing for entries_file, we
4192 could get rid of the kludges in server_register and
4193 server_scratch which refrain from warning if both
4194 Scratch_Entry and Register get called. Maybe. */
4197 free (scratched_file);
4198 scratched_file = NULL;
4200 buf_send_counted (protocol);
4204 if (entries_line != NULL && scratched_file == NULL)
4207 struct buffer_data *list, *last;
4211 /* The contents of the file will be in one of filebuf,
4212 list/last, or here. */
4213 unsigned char *file;
4214 size_t file_allocated;
4217 if (filebuf != NULL)
4219 size = buf_length (filebuf);
4220 if (mode == (mode_t) -1)
4222 CVS server internal error: no mode in server_updated");
4228 if ( CVS_STAT (finfo->file, &sb) < 0)
4230 if (existence_error (errno))
4232 /* If we have a sticky tag for a branch on which
4233 the file is dead, and cvs update the directory,
4234 it gets a T_CHECKOUT but no file. So in this
4235 case just forget the whole thing. */
4236 free (entries_line);
4237 entries_line = NULL;
4240 error (1, errno, "reading %s", finfo->fullname);
4243 if (mode == (mode_t) -1)
4245 /* FIXME: When we check out files the umask of the
4246 server (set in .bashrc if rsh is in use) affects
4247 what mode we send, and it shouldn't. */
4252 if (checksum != NULL)
4254 static int checksum_supported = -1;
4256 if (checksum_supported == -1)
4258 checksum_supported = supported_response ("Checksum");
4261 if (checksum_supported)
4266 buf_output0 (protocol, "Checksum ");
4267 for (i = 0; i < 16; i++)
4269 sprintf (buf, "%02x", (unsigned int) checksum[i]);
4270 buf_output0 (protocol, buf);
4272 buf_append_char (protocol, '\n');
4276 if (updated == SERVER_UPDATED)
4280 if (!(supported_response ("Created")
4281 && supported_response ("Update-existing")))
4282 buf_output0 (protocol, "Updated ");
4285 assert (vers != NULL);
4286 if (vers->ts_user == NULL)
4287 buf_output0 (protocol, "Created ");
4289 buf_output0 (protocol, "Update-existing ");
4292 /* Now munge the entries to say that the file is unmodified,
4293 in case we end up processing it again (e.g. modules3-6
4294 in the testsuite). */
4295 node = findnode_fn (finfo->entries, finfo->file);
4296 assert (node != NULL);
4299 Entnode *entnode = node->data;
4300 free (entnode->timestamp);
4301 entnode->timestamp = xstrdup ("=");
4304 else if (updated == SERVER_MERGED)
4305 buf_output0 (protocol, "Merged ");
4306 else if (updated == SERVER_PATCHED)
4307 buf_output0 (protocol, "Patched ");
4308 else if (updated == SERVER_RCS_DIFF)
4309 buf_output0 (protocol, "Rcs-diff ");
4312 output_dir (finfo->update_dir, finfo->repository);
4313 buf_output0 (protocol, finfo->file);
4314 buf_output (protocol, "\n", 1);
4316 new_entries_line ();
4321 mode_string = mode_to_string (mode);
4322 buf_output0 (protocol, mode_string);
4323 buf_output0 (protocol, "\n");
4335 /* Throughout this section we use binary mode to read the
4336 file we are sending. The client handles any line ending
4337 translation if necessary. */
4341 * For really tiny files, the gzip process startup
4342 * time will outweigh the compression savings. This
4343 * might be computable somehow; using 100 here is just
4344 * a first approximation.
4348 /* Basing this routine on read_and_gzip is not a
4349 high-performance approach. But it seems easier
4350 to code than the alternative (and less
4351 vulnerable to subtle bugs). Given that this feature
4352 is mainly for compatibility, that is the better
4357 /* Callers must avoid passing us a buffer if
4358 file_gzip_level is set. We could handle this case,
4359 but it's not worth it since this case never arises
4360 with a current client and server. */
4361 if (filebuf != NULL)
4363 CVS server internal error: unhandled case in server_updated");
4365 fd = CVS_OPEN (finfo->file, O_RDONLY | OPEN_BINARY, 0);
4367 error (1, errno, "reading %s", finfo->fullname);
4368 if (read_and_gzip (fd, finfo->fullname, &file,
4369 &file_allocated, &file_used,
4371 error (1, 0, "aborting due to compression error");
4374 error (1, errno, "reading %s", finfo->fullname);
4375 /* Prepending length with "z" is flag for using gzip here. */
4376 buf_output0 (protocol, "z");
4378 else if (filebuf == NULL)
4382 f = CVS_FOPEN (finfo->file, "rb");
4384 error (1, errno, "reading %s", finfo->fullname);
4385 status = buf_read_file (f, size, &list, &last);
4387 (*protocol->memory_error) (protocol);
4388 else if (status != 0)
4389 error (1, ferror (f) ? errno : 0, "reading %s",
4391 if (fclose (f) == EOF)
4392 error (1, errno, "reading %s", finfo->fullname);
4396 sprintf (size_text, "%lu\n", size);
4397 buf_output0 (protocol, size_text);
4401 buf_output (protocol, (char *) file, file_used);
4405 else if (filebuf == NULL)
4406 buf_append_data (protocol, list, last);
4409 buf_append_buffer (protocol, filebuf);
4411 /* Note we only send a newline here if the file ended with one. */
4414 * Avoid using up too much disk space for temporary files.
4415 * A file which does not exist indicates that the file is up-to-date,
4416 * which is now the case. If this is SERVER_MERGED, the file is
4417 * not up-to-date, and we indicate that by leaving the file there.
4418 * I'm thinking of cases like "cvs update foo/foo.c foo".
4420 if ((updated == SERVER_UPDATED
4421 || updated == SERVER_PATCHED
4422 || updated == SERVER_RCS_DIFF)
4424 /* But if we are joining, we'll need the file when we call
4428 if (CVS_UNLINK (finfo->file) < 0)
4429 error (0, errno, "cannot remove temp file for %s",
4433 else if (scratched_file != NULL && entries_line == NULL)
4435 if (strcmp (scratched_file, finfo->file) != 0)
4437 "CVS server internal error: `%s' vs. `%s' scratched",
4440 free (scratched_file);
4441 scratched_file = NULL;
4443 if (kill_scratched_file)
4444 buf_output0 (protocol, "Removed ");
4446 buf_output0 (protocol, "Remove-entry ");
4447 output_dir (finfo->update_dir, finfo->repository);
4448 buf_output0 (protocol, finfo->file);
4449 buf_output (protocol, "\n", 1);
4450 /* keep the vers structure up to date in case we do a join
4451 * - if there isn't a file, it can't very well have a version number, can it?
4453 * we do it here on the assumption that since we just told the client
4454 * to remove the file/entry, it will, and we want to remember that.
4455 * If it fails, that's the client's problem, not ours
4457 if (vers && vers->vn_user != NULL)
4459 free (vers->vn_user);
4460 vers->vn_user = NULL;
4462 if (vers && vers->ts_user != NULL)
4464 free (vers->ts_user);
4465 vers->ts_user = NULL;
4468 else if (scratched_file == NULL && entries_line == NULL)
4471 * This can happen with death support if we were processing
4472 * a dead file in a checkout.
4477 "CVS server internal error: Register *and* Scratch_Entry.\n");
4478 buf_send_counted (protocol);
4482 /* Return whether we should send patches in RCS format. */
4485 server_use_rcs_diff ()
4487 return supported_response ("Rcs-diff");
4493 server_set_entstat (update_dir, repository)
4494 const char *update_dir;
4495 const char *repository;
4497 static int set_static_supported = -1;
4498 if (set_static_supported == -1)
4499 set_static_supported = supported_response ("Set-static-directory");
4500 if (!set_static_supported) return;
4502 buf_output0 (protocol, "Set-static-directory ");
4503 output_dir (update_dir, repository);
4504 buf_output0 (protocol, "\n");
4505 buf_send_counted (protocol);
4511 server_clear_entstat (update_dir, repository)
4512 const char *update_dir;
4513 const char *repository;
4515 static int clear_static_supported = -1;
4516 if (clear_static_supported == -1)
4517 clear_static_supported = supported_response ("Clear-static-directory");
4518 if (!clear_static_supported) return;
4523 buf_output0 (protocol, "Clear-static-directory ");
4524 output_dir (update_dir, repository);
4525 buf_output0 (protocol, "\n");
4526 buf_send_counted (protocol);
4532 server_set_sticky (update_dir, repository, tag, date, nonbranch)
4533 const char *update_dir;
4534 const char *repository;
4539 static int set_sticky_supported = -1;
4541 assert (update_dir != NULL);
4543 if (set_sticky_supported == -1)
4544 set_sticky_supported = supported_response ("Set-sticky");
4545 if (!set_sticky_supported) return;
4550 if (tag == NULL && date == NULL)
4552 buf_output0 (protocol, "Clear-sticky ");
4553 output_dir (update_dir, repository);
4554 buf_output0 (protocol, "\n");
4558 buf_output0 (protocol, "Set-sticky ");
4559 output_dir (update_dir, repository);
4560 buf_output0 (protocol, "\n");
4564 buf_output0 (protocol, "N");
4566 buf_output0 (protocol, "T");
4567 buf_output0 (protocol, tag);
4571 buf_output0 (protocol, "D");
4572 buf_output0 (protocol, date);
4574 buf_output0 (protocol, "\n");
4576 buf_send_counted (protocol);
4579 struct template_proc_data
4581 const char *update_dir;
4582 const char *repository;
4585 /* Here as a static until we get around to fixing Parse_Info to pass along
4587 static struct template_proc_data *tpd;
4590 template_proc PROTO((const char *repository, const char *template));
4593 template_proc (repository, template)
4594 const char *repository;
4595 const char *template;
4601 struct template_proc_data *data = tpd;
4603 if (!supported_response ("Template"))
4604 /* Might want to warn the user that the rcsinfo feature won't work. */
4606 buf_output0 (protocol, "Template ");
4607 output_dir (data->update_dir, data->repository);
4608 buf_output0 (protocol, "\n");
4610 fp = CVS_FOPEN (template, "rb");
4613 error (0, errno, "Couldn't open rcsinfo template file %s", template);
4616 if (fstat (fileno (fp), &sb) < 0)
4618 error (0, errno, "cannot stat rcsinfo template file %s", template);
4621 sprintf (buf, "%ld\n", (long) sb.st_size);
4622 buf_output0 (protocol, buf);
4625 n = fread (buf, 1, sizeof buf, fp);
4626 buf_output (protocol, buf, n);
4629 error (0, errno, "cannot read rcsinfo template file %s", template);
4634 buf_send_counted (protocol);
4635 if (fclose (fp) < 0)
4636 error (0, errno, "cannot close rcsinfo template file %s", template);
4643 server_template (update_dir, repository)
4644 const char *update_dir;
4645 const char *repository;
4647 struct template_proc_data data;
4648 data.update_dir = update_dir;
4649 data.repository = repository;
4651 (void) Parse_Info (CVSROOTADM_RCSINFO, repository, template_proc, 1);
4657 serve_gzip_contents (arg)
4664 file_gzip_level = level;
4668 serve_gzip_stream (arg)
4676 /* All further communication with the client will be compressed. */
4678 buf_to_net = compress_buffer_initialize (buf_to_net, 0, level,
4679 buf_to_net->memory_error);
4680 buf_from_net = compress_buffer_initialize (buf_from_net, 1, level,
4681 buf_from_net->memory_error);
4684 /* Tell the client about RCS options set in CVSROOT/cvswrappers. */
4686 serve_wrapper_sendme_rcs_options (arg)
4689 /* Actually, this is kind of sdrawkcab-ssa: the client wants
4690 * verbatim lines from a cvswrappers file, but the server has
4691 * already parsed the cvswrappers file into the wrap_list struct.
4692 * Therefore, the server loops over wrap_list, unparsing each
4693 * entry before sending it.
4695 char *wrapper_line = NULL;
4699 for (wrap_unparse_rcs_options (&wrapper_line, 1);
4701 wrap_unparse_rcs_options (&wrapper_line, 0))
4703 buf_output0 (buf_to_net, "Wrapper-rcsOption ");
4704 buf_output0 (buf_to_net, wrapper_line);
4705 buf_output0 (buf_to_net, "\012");;
4706 free (wrapper_line);
4709 buf_output0 (buf_to_net, "ok\012");
4711 /* The client is waiting for us, so we better send the data now. */
4712 buf_flush (buf_to_net, 1);
4721 * Just ignore this command. This is used to support the
4722 * update-patches command, which is not a real command, but a signal
4723 * to the client that update will accept the -u argument.
4728 expand_proc (argc, argv, where, mwhere, mfile, shorten,
4729 local_specified, omodule, msg)
4736 int local_specified;
4741 char *dir = argv[0];
4743 /* If mwhere has been specified, the thing we're expanding is a
4744 module -- just return its name so the client will ask for the
4745 right thing later. If it is an alias or a real directory,
4746 mwhere will not be set, so send out the appropriate
4751 buf_output0 (buf_to_net, "Module-expansion ");
4752 if (server_dir != NULL)
4754 buf_output0 (buf_to_net, server_dir);
4755 buf_output0 (buf_to_net, "/");
4757 buf_output0 (buf_to_net, mwhere);
4760 buf_append_char (buf_to_net, '/');
4761 buf_output0 (buf_to_net, mfile);
4763 buf_append_char (buf_to_net, '\n');
4767 /* We may not need to do this anymore -- check the definition
4768 of aliases before removing */
4771 buf_output0 (buf_to_net, "Module-expansion ");
4772 if (server_dir != NULL)
4774 buf_output0 (buf_to_net, server_dir);
4775 buf_output0 (buf_to_net, "/");
4777 buf_output0 (buf_to_net, dir);
4778 buf_append_char (buf_to_net, '\n');
4782 for (i = 1; i < argc; ++i)
4784 buf_output0 (buf_to_net, "Module-expansion ");
4785 if (server_dir != NULL)
4787 buf_output0 (buf_to_net, server_dir);
4788 buf_output0 (buf_to_net, "/");
4790 buf_output0 (buf_to_net, dir);
4791 buf_append_char (buf_to_net, '/');
4792 buf_output0 (buf_to_net, argv[i]);
4793 buf_append_char (buf_to_net, '\n');
4801 serve_expand_modules (arg)
4809 db = open_module ();
4810 for (i = 1; i < argument_count; i++)
4811 err += do_module (db, argument_vector[i],
4812 CHECKOUT, "Updating", expand_proc,
4817 /* argument_vector[0] is a dummy argument, we don't mess with it. */
4819 for (cp = argument_vector + 1;
4820 cp < argument_vector + argument_count;
4827 /* We will have printed an error message already. */
4828 buf_output0 (buf_to_net, "error \n");
4830 buf_output0 (buf_to_net, "ok\n");
4832 /* The client is waiting for the module expansions, so we must
4833 send the output now. */
4834 buf_flush (buf_to_net, 1);
4839 static void serve_valid_requests PROTO((char *arg));
4841 #endif /* SERVER_SUPPORT */
4842 #if defined(SERVER_SUPPORT) || defined(CLIENT_SUPPORT)
4845 * Parts of this table are shared with the client code,
4846 * but the client doesn't need to know about the handler
4850 struct request requests[] =
4852 #ifdef SERVER_SUPPORT
4853 #define REQ_LINE(n, f, s) {n, f, s}
4855 #define REQ_LINE(n, f, s) {n, s}
4858 REQ_LINE("Root", serve_root, RQ_ESSENTIAL | RQ_ROOTLESS),
4859 REQ_LINE("Valid-responses", serve_valid_responses,
4860 RQ_ESSENTIAL | RQ_ROOTLESS),
4861 REQ_LINE("valid-requests", serve_valid_requests,
4862 RQ_ESSENTIAL | RQ_ROOTLESS),
4863 REQ_LINE("Repository", serve_repository, 0),
4864 REQ_LINE("Directory", serve_directory, RQ_ESSENTIAL),
4865 REQ_LINE("Max-dotdot", serve_max_dotdot, 0),
4866 REQ_LINE("Static-directory", serve_static_directory, 0),
4867 REQ_LINE("Sticky", serve_sticky, 0),
4868 REQ_LINE("Entry", serve_entry, RQ_ESSENTIAL),
4869 REQ_LINE("Kopt", serve_kopt, 0),
4870 REQ_LINE("Checkin-time", serve_checkin_time, 0),
4871 REQ_LINE("Modified", serve_modified, RQ_ESSENTIAL),
4872 REQ_LINE("Is-modified", serve_is_modified, 0),
4873 REQ_LINE("Empty-conflicts", serve_noop, 0),
4875 /* The client must send this request to interoperate with CVS 1.5
4876 through 1.9 servers. The server must support it (although it can
4877 be and is a noop) to interoperate with CVS 1.5 to 1.9 clients. */
4878 REQ_LINE("UseUnchanged", serve_enable_unchanged, RQ_ENABLEME | RQ_ROOTLESS),
4880 REQ_LINE("Unchanged", serve_unchanged, RQ_ESSENTIAL),
4881 REQ_LINE("Notify", serve_notify, 0),
4882 REQ_LINE("Questionable", serve_questionable, 0),
4883 REQ_LINE("Argument", serve_argument, RQ_ESSENTIAL),
4884 REQ_LINE("Argumentx", serve_argumentx, RQ_ESSENTIAL),
4885 REQ_LINE("Global_option", serve_global_option, RQ_ROOTLESS),
4886 REQ_LINE("Gzip-stream", serve_gzip_stream, 0),
4887 REQ_LINE("wrapper-sendme-rcsOptions",
4888 serve_wrapper_sendme_rcs_options,
4890 REQ_LINE("Set", serve_set, RQ_ROOTLESS),
4892 # ifdef HAVE_KERBEROS
4893 REQ_LINE("Kerberos-encrypt", serve_kerberos_encrypt, 0),
4896 REQ_LINE("Gssapi-encrypt", serve_gssapi_encrypt, 0),
4900 REQ_LINE("Gssapi-authenticate", serve_gssapi_authenticate, 0),
4902 REQ_LINE("expand-modules", serve_expand_modules, 0),
4903 REQ_LINE("ci", serve_ci, RQ_ESSENTIAL),
4904 REQ_LINE("co", serve_co, RQ_ESSENTIAL),
4905 REQ_LINE("update", serve_update, RQ_ESSENTIAL),
4906 REQ_LINE("diff", serve_diff, 0),
4907 REQ_LINE("log", serve_log, 0),
4908 REQ_LINE("rlog", serve_rlog, 0),
4909 REQ_LINE("add", serve_add, 0),
4910 REQ_LINE("remove", serve_remove, 0),
4911 REQ_LINE("update-patches", serve_ignore, 0),
4912 REQ_LINE("gzip-file-contents", serve_gzip_contents, 0),
4913 REQ_LINE("status", serve_status, 0),
4914 REQ_LINE("rdiff", serve_rdiff, 0),
4915 REQ_LINE("tag", serve_tag, 0),
4916 REQ_LINE("rtag", serve_rtag, 0),
4917 REQ_LINE("import", serve_import, 0),
4918 REQ_LINE("admin", serve_admin, 0),
4919 REQ_LINE("export", serve_export, 0),
4920 REQ_LINE("history", serve_history, 0),
4921 REQ_LINE("release", serve_release, 0),
4922 REQ_LINE("watch-on", serve_watch_on, 0),
4923 REQ_LINE("watch-off", serve_watch_off, 0),
4924 REQ_LINE("watch-add", serve_watch_add, 0),
4925 REQ_LINE("watch-remove", serve_watch_remove, 0),
4926 REQ_LINE("watchers", serve_watchers, 0),
4927 REQ_LINE("editors", serve_editors, 0),
4928 REQ_LINE("init", serve_init, RQ_ROOTLESS),
4929 REQ_LINE("annotate", serve_annotate, 0),
4930 REQ_LINE("rannotate", serve_rannotate, 0),
4931 REQ_LINE("noop", serve_noop, RQ_ROOTLESS),
4932 REQ_LINE("version", serve_version, RQ_ROOTLESS),
4933 REQ_LINE(NULL, NULL, 0)
4938 #endif /* SERVER_SUPPORT or CLIENT_SUPPORT */
4939 #ifdef SERVER_SUPPORT
4942 serve_valid_requests (arg)
4946 if (print_pending_error ())
4948 buf_output0 (buf_to_net, "Valid-requests");
4949 for (rq = requests; rq->name != NULL; rq++)
4951 if (rq->func != NULL)
4953 buf_append_char (buf_to_net, ' ');
4954 buf_output0 (buf_to_net, rq->name);
4957 buf_output0 (buf_to_net, "\nok\n");
4959 /* The client is waiting for the list of valid requests, so we
4960 must send the output now. */
4961 buf_flush (buf_to_net, 1);
4966 * Delete temporary files. SIG is the signal making this happen, or
4967 * 0 if not called as a result of a signal.
4969 static int command_pid_is_dead;
4970 static void wait_sig (sig)
4974 pid_t r = wait (&status);
4975 if (r == command_pid)
4976 command_pid_is_dead++;
4978 #endif /* SUNOS_KLUDGE */
4981 server_cleanup (sig)
4984 /* Do "rm -rf" on the temp directory. */
4988 if (buf_to_net != NULL)
4990 /* Since we're done, go ahead and put BUF_TO_NET back into blocking
4991 * mode and send any pending output. In the usual case there won't
4992 * won't be any, but there might be if an error occured.
4995 set_block (buf_to_net);
4996 buf_flush (buf_to_net, 1);
4998 /* Next we shut down BUF_FROM_NET. That will pick up the checksum
4999 * generated when the client shuts down its buffer. Then, after we
5000 * have generated any final output, we shut down BUF_TO_NET.
5003 if (buf_from_net != NULL)
5005 status = buf_shutdown (buf_from_net);
5007 error (0, status, "shutting down buffer from client");
5008 buf_free (buf_from_net);
5009 buf_from_net = NULL;
5012 if (dont_delete_temp)
5014 (void) buf_flush (buf_to_net, 1);
5015 (void) buf_shutdown (buf_to_net);
5016 buf_free (buf_to_net);
5018 error_use_protocol = 0;
5022 else if (dont_delete_temp)
5025 /* What a bogus kludge. This disgusting code makes all kinds of
5026 assumptions about SunOS, and is only for a bug in that system.
5027 So only enable it on Suns. */
5029 if (command_pid > 0)
5031 /* To avoid crashes on SunOS due to bugs in SunOS tmpfs
5032 triggered by the use of rename() in RCS, wait for the
5033 subprocess to die. Unfortunately, this means draining output
5034 while waiting for it to unblock the signal we sent it. Yuck! */
5038 signal (SIGCHLD, wait_sig);
5040 /* Perhaps SIGTERM would be more correct. But the child
5041 process will delay the SIGINT delivery until its own
5042 children have exited. */
5043 kill (command_pid, SIGINT);
5044 /* The caller may also have sent a signal to command_pid, so
5045 always try waiting. First, though, check and see if it's still
5048 r = waitpid (command_pid, &status, WNOHANG);
5051 else if (r == command_pid)
5052 command_pid_is_dead++;
5057 command_pid_is_dead++;
5063 /* waitpid should always return one of the above values */
5065 while (!command_pid_is_dead)
5067 struct timeval timeout;
5068 struct fd_set_wrapper readfds;
5072 /* Use a non-zero timeout to avoid eating up CPU cycles. */
5074 timeout.tv_usec = 0;
5075 readfds = command_fds_to_drain;
5076 switch (select (max_command_fd + 1, &readfds.fds,
5077 (fd_set *)0, (fd_set *)0,
5087 for (i = 0; i <= max_command_fd; i++)
5089 if (!FD_ISSET (i, &readfds.fds))
5091 /* this fd is non-blocking */
5092 while (read (i, buf, sizeof (buf)) >= 1)
5101 #endif /* SUNOS_KLUDGE */
5104 /* Temporarily clear noexec, so that we clean up our temp directory
5105 regardless of it (this could more cleanly be handled by moving
5106 the noexec check to all the unlink_file_dir callers from
5107 unlink_file_dir itself). */
5108 save_noexec = noexec;
5110 /* FIXME? Would be nice to not ignore errors. But what should we do?
5111 We could try to do this before we shut down the network connection,
5112 and try to notify the client (but the client might not be waiting
5113 for responses). We could try something like syslog() or our own
5115 unlink_file_dir (orig_server_temp_dir);
5116 noexec = save_noexec;
5118 if (buf_to_net != NULL)
5120 (void) buf_flush (buf_to_net, 1);
5121 (void) buf_shutdown (buf_to_net);
5122 buf_free (buf_to_net);
5124 error_use_protocol = 0;
5133 char *error_prog_name; /* Used in error messages */
5137 static const char *const msg[] =
5140 " Normally invoked by a cvs client on a remote machine.\n",
5145 /* Ignore argc and argv. They might be from .cvsrc. */
5147 buf_to_net = fd_buffer_initialize (STDOUT_FILENO, 0,
5148 outbuf_memory_error);
5149 buf_from_net = stdio_buffer_initialize (stdin, 0, 1, outbuf_memory_error);
5151 saved_output = buf_nonio_initialize (outbuf_memory_error);
5152 saved_outerr = buf_nonio_initialize (outbuf_memory_error);
5154 /* Since we're in the server parent process, error should use the
5155 protocol to report error messages. */
5156 error_use_protocol = 1;
5158 /* OK, now figure out where we stash our temporary files. */
5162 /* The code which wants to chdir into server_temp_dir is not set
5163 up to deal with it being a relative path. So give an error
5165 if (!isabsolute (Tmpdir))
5167 if (alloc_pending (80 + strlen (Tmpdir)))
5168 sprintf (pending_error_text,
5169 "E Value of %s for TMPDIR is not absolute", Tmpdir);
5171 /* FIXME: we would like this error to be persistent, that
5172 is, not cleared by print_pending_error. The current client
5173 will exit as soon as it gets an error, but the protocol spec
5174 does not require a client to do so. */
5181 server_temp_dir = xmalloc (strlen (Tmpdir) + 80);
5182 if (server_temp_dir == NULL)
5185 * Strictly speaking, we're not supposed to output anything
5186 * now. But we're about to exit(), give it a try.
5188 printf ("E Fatal server error, aborting.\n\
5189 error ENOMEM Virtual memory exhausted.\n");
5193 strcpy (server_temp_dir, Tmpdir);
5195 /* Remove a trailing slash from TMPDIR if present. */
5196 p = server_temp_dir + strlen (server_temp_dir) - 1;
5201 * I wanted to use cvs-serv/PID, but then you have to worry about
5202 * the permissions on the cvs-serv directory being right. So
5205 strcat (server_temp_dir, "/cvs-serv");
5207 p = server_temp_dir + strlen (server_temp_dir);
5208 sprintf (p, "%ld", (long) getpid ());
5210 orig_server_temp_dir = server_temp_dir;
5212 /* Create the temporary directory, and set the mode to
5213 700, to discourage random people from tampering with
5215 while ((status = mkdir_p (server_temp_dir)) == EEXIST)
5217 static const char suffix[] = "abcdefghijklmnopqrstuvwxyz";
5219 if (i >= sizeof suffix - 1) break;
5220 if (i == 0) p = server_temp_dir + strlen (server_temp_dir);
5226 if (alloc_pending (80 + strlen (server_temp_dir)))
5227 sprintf (pending_error_text,
5228 "E can't create temporary directory %s",
5230 pending_error = status;
5232 #ifndef CHMOD_BROKEN
5233 else if (chmod (server_temp_dir, S_IRWXU) < 0)
5235 int save_errno = errno;
5236 if (alloc_pending (80 + strlen (server_temp_dir)))
5237 sprintf (pending_error_text,
5238 "E cannot change permissions on temporary directory %s",
5240 pending_error = save_errno;
5243 else if (CVS_CHDIR (server_temp_dir) < 0)
5245 int save_errno = errno;
5246 if (alloc_pending (80 + strlen (server_temp_dir)))
5247 sprintf (pending_error_text,
5248 "E cannot change to temporary directory %s",
5250 pending_error = save_errno;
5255 /* Now initialize our argument vector (for arguments from the client). */
5257 /* Small for testing. */
5258 argument_vector_size = 1;
5259 argument_vector = xmalloc (argument_vector_size * sizeof (char *));
5261 /* This gets printed if the client supports an option which the
5262 server doesn't, causing the server to print a usage message.
5263 FIXME: just a nit, I suppose, but the usage message the server
5264 prints isn't literally true--it suggests "cvs server" followed
5265 by options which are for a particular command. Might be nice to
5266 say something like "client apparently supports an option not supported
5267 by this server" or something like that instead of usage message. */
5268 error_prog_name = xmalloc (strlen (program_name) + 8);
5269 sprintf(error_prog_name, "%s server", program_name);
5270 argument_vector[0] = error_prog_name;
5274 char *cmd, *orig_cmd;
5278 status = buf_read_line (buf_from_net, &cmd, NULL);
5281 buf_output0 (buf_to_net, "E Fatal server error, aborting.\n\
5282 error ENOMEM Virtual memory exhausted.\n");
5289 for (rq = requests; rq->name != NULL; ++rq)
5290 if (strncmp (cmd, rq->name, strlen (rq->name)) == 0)
5292 int len = strlen (rq->name);
5293 if (cmd[len] == '\0')
5295 else if (cmd[len] == ' ')
5299 * The first len characters match, but it's a different
5300 * command. e.g. the command is "cooperate" but we matched
5305 if (!(rq->flags & RQ_ROOTLESS)
5306 && current_parsed_root == NULL)
5308 /* For commands which change the way in which data
5309 is sent and received, for example Gzip-stream,
5310 this does the wrong thing. Since the client
5311 assumes that everything is being compressed,
5312 unconditionally, there is no way to give this
5313 error to the client without turning on
5314 compression. The obvious fix would be to make
5315 Gzip-stream RQ_ROOTLESS (with the corresponding
5316 change to the spec), and that might be a good
5317 idea but then again I can see some settings in
5318 CVSROOT about what compression level to allow.
5319 I suppose a more baroque answer would be to
5320 turn on compression (say, at level 1), just
5321 enough to give the "Root request missing"
5322 error. For now we just lose. */
5323 if (alloc_pending (80))
5324 sprintf (pending_error_text,
5325 "E Protocol error: Root request missing");
5331 if (rq->name == NULL)
5333 if (!print_pending_error ())
5335 buf_output0 (buf_to_net, "error unrecognized request `");
5336 buf_output0 (buf_to_net, cmd);
5337 buf_append_char (buf_to_net, '\'');
5338 buf_append_char (buf_to_net, '\n');
5343 free (error_prog_name);
5345 /* We expect the client is done talking to us at this point. If there is
5346 * any data in the buffer or on the network pipe, then something we didn't
5347 * prepare for is happening.
5349 if (!buf_empty (buf_from_net))
5351 /* Try to send the error message to the client, but also syslog it, in
5352 * case the client isn't listening anymore.
5354 #ifdef HAVE_SYSLOG_H
5355 /* FIXME: Can the IP address of the connecting client be retrieved
5358 syslog (LOG_DAEMON | LOG_ERR, "Dying gasps received from client.");
5360 error (0, 0, "Dying gasps received from client.");
5363 /* This command will actually close the network buffers. */
5370 #if defined (HAVE_KERBEROS) || defined (AUTH_SERVER_SUPPORT) || defined (HAVE_GSSAPI)
5371 static void switch_to_user PROTO((const char *, const char *));
5374 switch_to_user (cvs_username, username)
5375 const char *cvs_username; /* Only used for error messages. */
5376 const char *username;
5380 pw = getpwnam (username);
5383 /* check_password contains a similar check, so this usually won't be
5384 reached unless the CVS user is mapped to an invalid system user. */
5386 printf ("E Fatal error, aborting.\n\
5387 error 0 %s: no such system user\n", username);
5388 /* Don't worry about server_cleanup; server_active isn't set yet. */
5392 if (pw->pw_uid == 0)
5394 #ifdef HAVE_SYSLOG_H
5395 /* FIXME: Can the IP address of the connecting client be retrieved
5398 syslog (LOG_DAEMON | LOG_ALERT,
5399 "attempt to root from account: %s", cvs_username
5402 printf("error 0: root not allowed\n");
5407 if (initgroups (pw->pw_name, pw->pw_gid) < 0
5409 /* At least on the system I tried, initgroups() only works as root.
5410 But we do still want to report ENOMEM and whatever other
5411 errors initgroups() might dish up. */
5416 /* This could be a warning, but I'm not sure I see the point
5417 in doing that instead of an error given that it would happen
5418 on every connection. We could log it somewhere and not tell
5419 the user. But at least for now make it an error. */
5420 printf ("error 0 initgroups failed: %s\n", strerror (errno));
5421 /* Don't worry about server_cleanup; server_active isn't set yet. */
5424 #endif /* HAVE_INITGROUPS */
5426 #ifdef SETXID_SUPPORT
5427 /* honor the setgid bit iff set*/
5428 if (getgid() != getegid())
5430 if (setgid (getegid ()) < 0)
5432 /* See comments at setuid call below for more discussion. */
5433 printf ("error 0 setgid failed: %s\n", strerror (errno));
5434 /* Don't worry about server_cleanup;
5435 server_active isn't set yet. */
5442 if (setgid (pw->pw_gid) < 0)
5444 /* See comments at setuid call below for more discussion. */
5445 printf ("error 0 setgid failed: %s\n", strerror (errno));
5446 #ifdef HAVE_SYSLOG_H
5447 syslog (LOG_DAEMON | LOG_ERR,
5448 "setgid to %d failed (%m): real %d/%d, effective %d/%d ",
5449 pw->pw_gid, getuid(), getgid(), geteuid(), getegid());
5451 /* Don't worry about server_cleanup;
5452 server_active isn't set yet. */
5457 if (setuid (pw->pw_uid) < 0)
5459 /* Note that this means that if run as a non-root user,
5460 CVSROOT/passwd must contain the user we are running as
5461 (e.g. "joe:FsEfVcu:cvs" if run as "cvs" user). This seems
5462 cleaner than ignoring the error like CVS 1.10 and older but
5463 it does mean that some people might need to update their
5464 CVSROOT/passwd file. */
5465 printf ("error 0 setuid failed: %s\n", strerror (errno));
5466 #ifdef HAVE_SYSLOG_H
5467 syslog (LOG_DAEMON | LOG_ERR,
5468 "setuid to %d failed (%m): real %d/%d, effective %d/%d ",
5469 pw->pw_uid, getuid(), getgid(), geteuid(), getegid());
5471 /* Don't worry about server_cleanup; server_active isn't set yet. */
5475 /* We don't want our umask to change file modes. The modes should
5476 be set by the modes used in the repository, and by the umask of
5480 #ifdef AUTH_SERVER_SUPPORT
5481 /* Make sure our CVS_Username has been set. */
5482 if (CVS_Username == NULL)
5483 CVS_Username = xstrdup (username);
5487 /* Set LOGNAME, USER and CVS_USER in the environment, in case they
5488 are already set to something else. */
5492 env = xmalloc (sizeof "LOGNAME=" + strlen (username));
5493 (void) sprintf (env, "LOGNAME=%s", username);
5494 (void) putenv (env);
5496 env = xmalloc (sizeof "USER=" + strlen (username));
5497 (void) sprintf (env, "USER=%s", username);
5498 (void) putenv (env);
5500 #ifdef AUTH_SERVER_SUPPORT
5501 env = xmalloc (sizeof "CVS_USER=" + strlen (CVS_Username));
5502 (void) sprintf (env, "CVS_USER=%s", CVS_Username);
5503 (void) putenv (env);
5506 #endif /* HAVE_PUTENV */
5510 #ifdef AUTH_SERVER_SUPPORT
5512 extern char *crypt PROTO((const char *, const char *));
5516 * 0 means no entry found for this user.
5517 * 1 means entry found and password matches (or found password is empty)
5518 * 2 means entry found, but password does not match.
5520 * If 1, host_user_ptr will be set to point at the system
5521 * username (i.e., the "real" identity, which may or may not be the
5522 * CVS username) of this user; caller may free this. Global
5523 * CVS_Username will point at an allocated copy of cvs username (i.e.,
5524 * the username argument below).
5525 * kff todo: FIXME: last sentence is not true, it applies to caller.
5528 check_repository_password (username, password, repository, host_user_ptr)
5529 char *username, *password, *repository, **host_user_ptr;
5534 char *linebuf = NULL;
5539 /* We don't use current_parsed_root->directory because it hasn't been
5540 * set yet -- our `repository' argument came from the authentication
5541 * protocol, not the regular CVS protocol.
5544 filename = xmalloc (strlen (repository)
5546 + strlen (CVSROOTADM)
5548 + strlen (CVSROOTADM_PASSWD)
5551 (void) sprintf (filename, "%s/%s/%s", repository,
5552 CVSROOTADM, CVSROOTADM_PASSWD);
5554 fp = CVS_FOPEN (filename, "r");
5557 if (!existence_error (errno))
5558 error (0, errno, "cannot open %s", filename);
5563 /* Look for a relevant line -- one with this user's name. */
5564 namelen = strlen (username);
5565 while (getline (&linebuf, &linebuf_len, fp) >= 0)
5567 if ((strncmp (linebuf, username, namelen) == 0)
5568 && (linebuf[namelen] == ':'))
5575 error (0, errno, "cannot read %s", filename);
5576 if (fclose (fp) < 0)
5577 error (0, errno, "cannot close %s", filename);
5579 /* If found_it, then linebuf contains the information we need. */
5582 char *found_password, *host_user_tmp;
5583 char *non_cvsuser_portion;
5585 /* We need to make sure lines such as
5587 * "username::sysuser\n"
5591 * all result in a found_password of NULL, but we also need to
5594 * "username: :sysuser\n"
5595 * "username: <whatever>:sysuser\n"
5597 * continues to result in an impossible password. That way,
5598 * an admin would be on safe ground by going in and tacking a
5599 * space onto the front of a password to disable the account
5600 * (a technique some people use to close accounts
5604 /* Make `non_cvsuser_portion' contain everything after the CVS
5605 username, but null out any final newline. */
5606 non_cvsuser_portion = linebuf + namelen;
5607 strtok (non_cvsuser_portion, "\n");
5609 /* If there's a colon now, we just want to inch past it. */
5610 if (strchr (non_cvsuser_portion, ':') == non_cvsuser_portion)
5611 non_cvsuser_portion++;
5613 /* Okay, after this conditional chain, found_password and
5614 host_user_tmp will have useful values: */
5616 if ((non_cvsuser_portion == NULL)
5617 || (strlen (non_cvsuser_portion) == 0)
5618 || ((strspn (non_cvsuser_portion, " \t"))
5619 == strlen (non_cvsuser_portion)))
5621 found_password = NULL;
5622 host_user_tmp = NULL;
5624 else if (strncmp (non_cvsuser_portion, ":", 1) == 0)
5626 found_password = NULL;
5627 host_user_tmp = non_cvsuser_portion + 1;
5628 if (strlen (host_user_tmp) == 0)
5629 host_user_tmp = NULL;
5633 found_password = strtok (non_cvsuser_portion, ":");
5634 host_user_tmp = strtok (NULL, ":");
5637 /* Of course, maybe there was no system user portion... */
5638 if (host_user_tmp == NULL)
5639 host_user_tmp = username;
5641 /* Verify blank passwords directly, otherwise use crypt(). */
5642 if ((found_password == NULL)
5643 || ((strcmp (found_password, crypt (password, found_password))
5646 /* Give host_user_ptr permanent storage. */
5647 *host_user_ptr = xstrdup (host_user_tmp);
5653 syslog (LOG_AUTHPRIV | LOG_NOTICE,
5654 "password mismatch for %s in %s: %s vs. %s", username,
5655 repository, crypt(password, found_password), found_password);
5657 *host_user_ptr = NULL;
5661 else /* Didn't find this user, so deny access. */
5663 *host_user_ptr = NULL;
5676 /* Return a hosting username if password matches, else NULL. */
5678 check_password (username, password, repository)
5679 char *username, *password, *repository;
5682 char *host_user = NULL;
5683 char *found_passwd = NULL;
5686 /* First we see if this user has a password in the CVS-specific
5687 password file. If so, that's enough to authenticate with. If
5688 not, we'll check /etc/passwd. */
5690 if (require_real_user)
5691 rc = 0; /* "not found" */
5693 rc = check_repository_password (username, password, repository,
5701 /* host_user already set by reference, so just return. */
5709 /* Note that the message _does_ distinguish between the case in
5710 which we check for a system password and the case in which
5711 we do not. It is a real pain to track down why it isn't
5712 letting you in if it won't say why, and I am not convinced
5713 that the potential information disclosure to an attacker
5715 printf ("error 0 no such user %s in CVSROOT/passwd\n", username);
5720 /* No cvs password found, so try /etc/passwd. */
5722 #ifdef HAVE_GETSPNAM
5726 spw = getspnam (username);
5729 found_passwd = spw->sp_pwdp;
5734 if (found_passwd == NULL && (pw = getpwnam (username)) != NULL)
5736 found_passwd = pw->pw_passwd;
5739 if (found_passwd == NULL)
5741 printf ("E Fatal error, aborting.\n\
5742 error 0 %s: no such user\n", username);
5747 /* Allow for dain bramaged HPUX passwd aging
5748 * - Basically, HPUX adds a comma and some data
5749 * about whether the passwd has expired or not
5750 * on the end of the passwd field.
5751 * - This code replaces the ',' with '\0'.
5753 * FIXME - our workaround is brain damaged too. I'm
5754 * guessing that HPUX WANTED other systems to think the
5755 * password was wrong so logins would fail if the
5756 * system didn't handle expired passwds and the passwd
5757 * might be expired. I think the way to go here
5760 strtok (found_passwd, ",");
5764 /* user exists and has a password */
5765 if (strcmp (found_passwd, crypt (password, found_passwd)) == 0)
5767 host_user = xstrdup (username);
5773 syslog (LOG_AUTHPRIV | LOG_NOTICE,
5774 "password mismatch for %s: %s vs. %s", username,
5775 crypt(password, found_passwd), found_passwd);
5781 if (password && *password)
5783 /* user exists and has no system password, but we got
5785 host_user = xstrdup (username);
5789 /* user exists but has no password at all */
5792 syslog (LOG_AUTHPRIV | LOG_NOTICE,
5793 "login refused for %s: user has no password", username);
5799 /* Set CVS_Username here, in allocated space.
5800 It might or might not be the same as host_user. */
5801 CVS_Username = xmalloc (strlen (username) + 1);
5802 strcpy (CVS_Username, username);
5808 #endif /* AUTH_SERVER_SUPPORT */
5810 #if defined (AUTH_SERVER_SUPPORT) || defined (HAVE_GSSAPI)
5812 /* Read username and password from client (i.e., stdin).
5813 If correct, then switch to run as that user and send an ACK to the
5814 client via stdout, else send NACK and die. */
5816 pserver_authenticate_connection ()
5819 size_t tmp_allocated = 0;
5820 #ifdef AUTH_SERVER_SUPPORT
5821 char *repository = NULL;
5822 size_t repository_allocated = 0;
5823 char *username = NULL;
5824 size_t username_allocated = 0;
5825 char *password = NULL;
5826 size_t password_allocated = 0;
5829 char *descrambled_password;
5830 #endif /* AUTH_SERVER_SUPPORT */
5831 int verify_and_exit = 0;
5833 /* The Authentication Protocol. Client sends:
5835 * BEGIN AUTH REQUEST\n
5839 * END AUTH REQUEST\n
5841 * Server uses above information to authenticate, then sends
5845 * if it grants access, else
5849 * if it denies access (and it exits if denying).
5851 * When the client is "cvs login", the user does not desire actual
5852 * repository access, but would like to confirm the password with
5853 * the server. In this case, the start and stop strings are
5855 * BEGIN VERIFICATION REQUEST\n
5859 * END VERIFICATION REQUEST\n
5861 * On a verification request, the server's responses are the same
5862 * (with the obvious semantics), but it exits immediately after
5863 * sending the response in both cases.
5865 * Why is the repository sent? Well, note that the actual
5866 * client/server protocol can't start up until authentication is
5867 * successful. But in order to perform authentication, the server
5868 * needs to look up the password in the special CVS passwd file,
5869 * before trying /etc/passwd. So the client transmits the
5870 * repository as part of the "authentication protocol". The
5871 * repository will be redundantly retransmitted later, but that's no
5876 /* Set SO_KEEPALIVE on the socket, so that we don't hang forever
5877 if the client dies while we are waiting for input. */
5881 if (setsockopt (STDIN_FILENO, SOL_SOCKET, SO_KEEPALIVE,
5882 (char *) &on, sizeof on) < 0)
5884 #ifdef HAVE_SYSLOG_H
5885 syslog (LOG_DAEMON | LOG_ERR, "error setting KEEPALIVE: %m");
5891 /* Make sure the protocol starts off on the right foot... */
5892 if (getline_safe (&tmp, &tmp_allocated, stdin, PATH_MAX) < 0)
5894 #ifdef HAVE_SYSLOG_H
5895 syslog (LOG_DAEMON | LOG_NOTICE, "bad auth protocol start: EOF");
5897 error (1, 0, "bad auth protocol start: EOF");
5900 if (strcmp (tmp, "BEGIN VERIFICATION REQUEST\n") == 0)
5901 verify_and_exit = 1;
5902 else if (strcmp (tmp, "BEGIN AUTH REQUEST\n") == 0)
5904 else if (strcmp (tmp, "BEGIN GSSAPI REQUEST\n") == 0)
5908 gserver_authenticate_connection ();
5911 error (1, 0, "GSSAPI authentication not supported by this server");
5915 error (1, 0, "bad auth protocol start: %s", tmp);
5917 #ifndef AUTH_SERVER_SUPPORT
5919 error (1, 0, "Password authentication not supported by this server");
5921 #else /* AUTH_SERVER_SUPPORT */
5923 /* Get the three important pieces of information in order. */
5924 /* See above comment about error handling. */
5925 getline_safe (&repository, &repository_allocated, stdin, PATH_MAX);
5926 getline_safe (&username, &username_allocated, stdin, PATH_MAX);
5927 getline_safe (&password, &password_allocated, stdin, PATH_MAX);
5931 * We check that none of the lines were truncated by getnline in order
5932 * to be sure that we don't accidentally allow a blind DOS attack to
5933 * authenticate, however slim the odds of that might be.
5935 if (!strip_trailing_newlines (repository)
5936 || !strip_trailing_newlines (username)
5937 || !strip_trailing_newlines (password))
5938 error (1, 0, "Maximum line length exceeded during authentication.");
5940 /* ... and make sure the protocol ends on the right foot. */
5941 /* See above comment about error handling. */
5942 getline_safe (&tmp, &tmp_allocated, stdin, PATH_MAX);
5945 "END VERIFICATION REQUEST\n" : "END AUTH REQUEST\n")
5948 error (1, 0, "bad auth protocol end: %s", tmp);
5950 if (!root_allow_ok (repository))
5952 printf ("error 0 %s: no such repository\n", repository);
5953 #ifdef HAVE_SYSLOG_H
5954 syslog (LOG_DAEMON | LOG_NOTICE, "login refused for %s", repository);
5959 /* OK, now parse the config file, so we can use it to control how
5960 to check passwords. If there was an error parsing the config
5961 file, parse_config already printed an error. We keep going.
5962 Why? Because if we didn't, then there would be no way to check
5963 in a new CVSROOT/config file to fix the broken one! */
5964 parse_config (repository);
5966 /* We need the real cleartext before we hash it. */
5967 descrambled_password = descramble (password);
5968 host_user = check_password (username, descrambled_password, repository);
5969 if (host_user == NULL)
5971 #ifdef HAVE_SYSLOG_H
5972 syslog (LOG_DAEMON | LOG_NOTICE, "login failure (for %s)", repository);
5974 memset (descrambled_password, 0, strlen (descrambled_password));
5975 free (descrambled_password);
5977 printf ("I HATE YOU\n");
5980 /* Don't worry about server_cleanup, server_active isn't set
5984 memset (descrambled_password, 0, strlen (descrambled_password));
5985 free (descrambled_password);
5987 /* Don't go any farther if we're just responding to "cvs login". */
5988 if (verify_and_exit)
5990 printf ("I LOVE YOU\n");
5993 /* It's okay to skip rcs_cleanup() and Lock_Cleanup() here. */
5995 #ifdef SYSTEM_CLEANUP
5996 /* Hook for OS-specific behavior, for example socket subsystems on
5997 NT and OS2 or dealing with windows and arguments on Mac. */
6004 /* Set Pserver_Repos so that we can check later that the same
6005 repository is sent in later client/server protocol. */
6006 Pserver_Repos = xmalloc (strlen (repository) + 1);
6007 strcpy (Pserver_Repos, repository);
6009 /* Switch to run as this user. */
6010 switch_to_user (username, host_user);
6017 printf ("I LOVE YOU\n");
6019 #endif /* AUTH_SERVER_SUPPORT */
6022 #endif /* AUTH_SERVER_SUPPORT || HAVE_GSSAPI */
6025 #ifdef HAVE_KERBEROS
6027 kserver_authenticate_connection ()
6030 char instance[INST_SZ];
6031 struct sockaddr_in peer;
6032 struct sockaddr_in laddr;
6036 char version[KRB_SENDAUTH_VLEN];
6037 char user[ANAME_SZ];
6039 strcpy (instance, "*");
6041 if (getpeername (STDIN_FILENO, (struct sockaddr *) &peer, &len) < 0
6042 || getsockname (STDIN_FILENO, (struct sockaddr *) &laddr,
6045 printf ("E Fatal error, aborting.\n\
6046 error %s getpeername or getsockname failed\n", strerror (errno));
6052 /* Set SO_KEEPALIVE on the socket, so that we don't hang forever
6053 if the client dies while we are waiting for input. */
6057 if (setsockopt (STDIN_FILENO, SOL_SOCKET, SO_KEEPALIVE,
6058 (char *) &on, sizeof on) < 0)
6060 #ifdef HAVE_SYSLOG_H
6061 syslog (LOG_DAEMON | LOG_ERR, "error setting KEEPALIVE: %m");
6067 status = krb_recvauth (KOPT_DO_MUTUAL, STDIN_FILENO, &ticket, "rcmd",
6068 instance, &peer, &laddr, &auth, "", sched,
6070 if (status != KSUCCESS)
6072 printf ("E Fatal error, aborting.\n\
6073 error 0 kerberos: %s\n", krb_get_err_text(status));
6078 memcpy (kblock, auth.session, sizeof (C_Block));
6080 /* Get the local name. */
6081 status = krb_kntoln (&auth, user);
6082 if (status != KSUCCESS)
6084 printf ("E Fatal error, aborting.\n\
6085 error 0 kerberos: can't get local name: %s\n", krb_get_err_text(status));
6090 /* Switch to run as this user. */
6091 switch_to_user ("Kerberos 4", user);
6093 #endif /* HAVE_KERBEROS */
6097 #ifndef MAXHOSTNAMELEN
6098 #define MAXHOSTNAMELEN (256)
6101 /* Authenticate a GSSAPI connection. This is called from
6102 pserver_authenticate_connection, and it handles success and failure
6106 gserver_authenticate_connection ()
6108 char hostname[MAXHOSTNAMELEN];
6110 gss_buffer_desc tok_in, tok_out;
6114 OM_uint32 stat_min, ret;
6115 gss_name_t server_name, client_name;
6116 gss_cred_id_t server_creds;
6120 gethostname (hostname, sizeof hostname);
6121 hp = gethostbyname (hostname);
6123 error (1, 0, "can't get canonical hostname");
6125 sprintf (buf, "cvs@%s", hp->h_name);
6127 tok_in.length = strlen (buf);
6129 if (gss_import_name (&stat_min, &tok_in, GSS_C_NT_HOSTBASED_SERVICE,
6130 &server_name) != GSS_S_COMPLETE)
6131 error (1, 0, "could not import GSSAPI service name %s", buf);
6133 /* Acquire the server credential to verify the client's
6135 if (gss_acquire_cred (&stat_min, server_name, 0, GSS_C_NULL_OID_SET,
6136 GSS_C_ACCEPT, &server_creds,
6137 NULL, NULL) != GSS_S_COMPLETE)
6138 error (1, 0, "could not acquire GSSAPI server credentials");
6140 gss_release_name (&stat_min, &server_name);
6142 /* The client will send us a two byte length followed by that many
6144 if (fread (buf, 1, 2, stdin) != 2)
6145 error (1, errno, "read of length failed");
6147 nbytes = ((buf[0] & 0xff) << 8) | (buf[1] & 0xff);
6148 if (nbytes <= sizeof buf)
6151 credbuflen = sizeof buf;
6155 credbuflen = nbytes;
6156 credbuf = xmalloc (credbuflen);
6159 if (fread (credbuf, 1, nbytes, stdin) != nbytes)
6160 error (1, errno, "read of data failed");
6162 gcontext = GSS_C_NO_CONTEXT;
6163 tok_in.length = nbytes;
6164 tok_in.value = credbuf;
6166 if (gss_accept_sec_context (&stat_min,
6167 &gcontext, /* context_handle */
6168 server_creds, /* verifier_cred_handle */
6169 &tok_in, /* input_token */
6170 NULL, /* channel bindings */
6171 &client_name, /* src_name */
6172 &mechid, /* mech_type */
6173 &tok_out, /* output_token */
6175 NULL, /* ignore time_rec */
6176 NULL) /* ignore del_cred_handle */
6179 error (1, 0, "could not verify credentials");
6182 /* FIXME: Use Kerberos v5 specific code to authenticate to a user.
6183 We could instead use an authentication to access mapping. */
6187 gss_buffer_desc desc;
6189 krb5_init_context (&kc);
6190 if (gss_display_name (&stat_min, client_name, &desc,
6191 &mechid) != GSS_S_COMPLETE
6192 || krb5_parse_name (kc, ((gss_buffer_t) &desc)->value, &p) != 0
6193 || krb5_aname_to_localname (kc, p, sizeof buf, buf) != 0
6194 || krb5_kuserok (kc, p, buf) != TRUE)
6196 error (1, 0, "access denied");
6198 krb5_free_principal (kc, p);
6199 krb5_free_context (kc);
6202 if (tok_out.length != 0)
6206 cbuf[0] = (tok_out.length >> 8) & 0xff;
6207 cbuf[1] = tok_out.length & 0xff;
6208 if (fwrite (cbuf, 1, 2, stdout) != 2
6209 || (fwrite (tok_out.value, 1, tok_out.length, stdout)
6211 error (1, errno, "fwrite failed");
6214 switch_to_user ("GSSAPI", buf);
6219 printf ("I LOVE YOU\n");
6223 #endif /* HAVE_GSSAPI */
6225 #endif /* SERVER_SUPPORT */
6227 #if defined (CLIENT_SUPPORT) || defined (SERVER_SUPPORT)
6229 /* This global variable is non-zero if the user requests encryption on
6230 the command line. */
6233 /* This global variable is non-zero if the users requests stream
6234 authentication on the command line. */
6235 int cvsauthenticate;
6239 /* An buffer interface using GSSAPI. This is built on top of a
6240 packetizing buffer. */
6242 /* This structure is the closure field of the GSSAPI translation
6245 struct cvs_gssapi_wrap_data
6247 /* The GSSAPI context. */
6248 gss_ctx_id_t gcontext;
6251 static int cvs_gssapi_wrap_input PROTO((void *, const char *, char *, int));
6252 static int cvs_gssapi_wrap_output PROTO((void *, const char *, char *, int,
6255 /* Create a GSSAPI wrapping buffer. We use a packetizing buffer with
6256 GSSAPI wrapping routines. */
6259 cvs_gssapi_wrap_buffer_initialize (buf, input, gcontext, memory)
6262 gss_ctx_id_t gcontext;
6263 void (*memory) PROTO((struct buffer *));
6265 struct cvs_gssapi_wrap_data *gd;
6267 gd = (struct cvs_gssapi_wrap_data *) xmalloc (sizeof *gd);
6268 gd->gcontext = gcontext;
6270 return (packetizing_buffer_initialize
6272 input ? cvs_gssapi_wrap_input : NULL,
6273 input ? NULL : cvs_gssapi_wrap_output,
6278 /* Unwrap data using GSSAPI. */
6281 cvs_gssapi_wrap_input (fnclosure, input, output, size)
6287 struct cvs_gssapi_wrap_data *gd =
6288 (struct cvs_gssapi_wrap_data *) fnclosure;
6289 gss_buffer_desc inbuf, outbuf;
6293 inbuf.value = (void *) input;
6294 inbuf.length = size;
6296 if (gss_unwrap (&stat_min, gd->gcontext, &inbuf, &outbuf, &conf, NULL)
6299 error (1, 0, "gss_unwrap failed");
6302 if (outbuf.length > size)
6305 memcpy (output, outbuf.value, outbuf.length);
6307 /* The real packet size is stored in the data, so we don't need to
6308 remember outbuf.length. */
6310 gss_release_buffer (&stat_min, &outbuf);
6315 /* Wrap data using GSSAPI. */
6318 cvs_gssapi_wrap_output (fnclosure, input, output, size, translated)
6325 struct cvs_gssapi_wrap_data *gd =
6326 (struct cvs_gssapi_wrap_data *) fnclosure;
6327 gss_buffer_desc inbuf, outbuf;
6331 inbuf.value = (void *) input;
6332 inbuf.length = size;
6335 conf_req = cvs_gssapi_encrypt;
6340 if (gss_wrap (&stat_min, gd->gcontext, conf_req, GSS_C_QOP_DEFAULT,
6341 &inbuf, &conf, &outbuf) != GSS_S_COMPLETE)
6342 error (1, 0, "gss_wrap failed");
6344 /* The packetizing buffer only permits us to add 100 bytes.
6345 FIXME: I don't know what, if anything, is guaranteed by GSSAPI.
6346 This may need to be increased for a different GSSAPI
6347 implementation, or we may need a different algorithm. */
6348 if (outbuf.length > size + 100)
6351 memcpy (output, outbuf.value, outbuf.length);
6353 *translated = outbuf.length;
6355 gss_release_buffer (&stat_min, &outbuf);
6360 #endif /* HAVE_GSSAPI */
6364 #ifdef HAVE_KERBEROS
6366 /* An encryption interface using Kerberos. This is built on top of a
6367 packetizing buffer. */
6369 /* This structure is the closure field of the Kerberos translation
6372 struct krb_encrypt_data
6374 /* The Kerberos key schedule. */
6376 /* The Kerberos DES block. */
6380 static int krb_encrypt_input PROTO((void *, const char *, char *, int));
6381 static int krb_encrypt_output PROTO((void *, const char *, char *, int,
6384 /* Create a Kerberos encryption buffer. We use a packetizing buffer
6385 with Kerberos encryption translation routines. */
6388 krb_encrypt_buffer_initialize (buf, input, sched, block, memory)
6393 void (*memory) PROTO((struct buffer *));
6395 struct krb_encrypt_data *kd;
6397 kd = (struct krb_encrypt_data *) xmalloc (sizeof *kd);
6398 memcpy (kd->sched, sched, sizeof (Key_schedule));
6399 memcpy (kd->block, block, sizeof (C_Block));
6401 return packetizing_buffer_initialize (buf,
6402 input ? krb_encrypt_input : NULL,
6403 input ? NULL : krb_encrypt_output,
6408 /* Decrypt Kerberos data. */
6411 krb_encrypt_input (fnclosure, input, output, size)
6417 struct krb_encrypt_data *kd = (struct krb_encrypt_data *) fnclosure;
6420 des_cbc_encrypt ((C_Block *) input, (C_Block *) output,
6421 size, kd->sched, &kd->block, 0);
6423 /* SIZE is the size of the buffer, which is set by the encryption
6424 routine. The packetizing buffer will arrange for the first two
6425 bytes in the decrypted buffer to be the real (unaligned)
6426 length. As a safety check, make sure that the length in the
6427 buffer corresponds to SIZE. Note that the length in the buffer
6428 is just the length of the data. We must add 2 to account for
6429 the buffer count itself. */
6430 tcount = ((output[0] & 0xff) << 8) + (output[1] & 0xff);
6431 if (((tcount + 2 + 7) & ~7) != size)
6432 error (1, 0, "Decryption failure");
6437 /* Encrypt Kerberos data. */
6440 krb_encrypt_output (fnclosure, input, output, size, translated)
6447 struct krb_encrypt_data *kd = (struct krb_encrypt_data *) fnclosure;
6450 /* For security against a known plaintext attack, we should
6451 initialize any padding bytes to random values. Instead, we
6452 just pick up whatever is on the stack, which is at least better
6455 /* Align SIZE to an 8 byte boundary. Note that SIZE includes the
6456 two byte buffer count at the start of INPUT which was added by
6457 the packetizing buffer. */
6458 aligned = (size + 7) & ~7;
6460 /* We use des_cbc_encrypt rather than krb_mk_priv because the
6461 latter sticks a timestamp in the block, and krb_rd_priv expects
6462 that timestamp to be within five minutes of the current time.
6463 Given the way the CVS server buffers up data, that can easily
6464 fail over a long network connection. We trust krb_recvauth to
6465 guard against a replay attack. */
6467 des_cbc_encrypt ((C_Block *) input, (C_Block *) output, aligned,
6468 kd->sched, &kd->block, 1);
6470 *translated = aligned;
6475 #endif /* HAVE_KERBEROS */
6476 #endif /* ENCRYPTION */
6477 #endif /* defined (CLIENT_SUPPORT) || defined (SERVER_SUPPORT) */
6479 /* Output LEN bytes at STR. If LEN is zero, then output up to (not including)
6480 the first '\0' byte. */
6483 cvs_output (str, len)
6489 #ifdef SERVER_SUPPORT
6490 if (error_use_protocol && buf_to_net != NULL)
6492 buf_output (saved_output, str, len);
6493 buf_copy_lines (buf_to_net, saved_output, 'M');
6495 else if (server_active && protocol != NULL)
6497 buf_output (saved_output, str, len);
6498 buf_copy_lines (protocol, saved_output, 'M');
6499 buf_send_counted (protocol);
6505 size_t to_write = len;
6506 const char *p = str;
6508 /* Local users that do 'cvs status 2>&1' on a local repository
6509 may see the informational messages out-of-order with the
6510 status messages unless we use the fflush (stderr) here. */
6513 while (to_write > 0)
6515 written = fwrite (p, 1, to_write, stdout);
6519 to_write -= written;
6524 /* Output LEN bytes at STR in binary mode. If LEN is zero, then
6525 output zero bytes. */
6528 cvs_output_binary (str, len)
6532 #ifdef SERVER_SUPPORT
6533 if (error_use_protocol || server_active)
6538 if (error_use_protocol)
6543 if (!supported_response ("Mbinary"))
6546 this client does not support writing binary files to stdout");
6550 buf_output0 (buf, "Mbinary\012");
6551 sprintf (size_text, "%lu\012", (unsigned long) len);
6552 buf_output0 (buf, size_text);
6554 /* Not sure what would be involved in using buf_append_data here
6555 without stepping on the toes of our caller (which is responsible
6556 for the memory allocation of STR). */
6557 buf_output (buf, str, len);
6559 if (!error_use_protocol)
6560 buf_send_counted (protocol);
6566 size_t to_write = len;
6567 const char *p = str;
6568 #ifdef USE_SETMODE_STDOUT
6572 /* Local users that do 'cvs status 2>&1' on a local repository
6573 may see the informational messages out-of-order with the
6574 status messages unless we use the fflush (stderr) here. */
6577 #ifdef USE_SETMODE_STDOUT
6578 /* It is possible that this should be the same ifdef as
6579 USE_SETMODE_BINARY but at least for the moment we keep them
6580 separate. Mostly this is just laziness and/or a question
6581 of what has been tested where. Also there might be an
6582 issue of setmode vs. _setmode. */
6583 /* The Windows doc says to call setmode only right after startup.
6584 I assume that what they are talking about can also be helped
6585 by flushing the stream before changing the mode. */
6587 oldmode = _setmode (_fileno (stdout), OPEN_BINARY);
6589 error (0, errno, "failed to setmode on stdout");
6592 while (to_write > 0)
6594 written = fwrite (p, 1, to_write, stdout);
6598 to_write -= written;
6600 #ifdef USE_SETMODE_STDOUT
6602 if (_setmode (_fileno (stdout), oldmode) != OPEN_BINARY)
6603 error (0, errno, "failed to setmode on stdout");
6610 /* Like CVS_OUTPUT but output is for stderr not stdout. */
6612 cvs_outerr (str, len)
6618 #ifdef SERVER_SUPPORT
6619 if (error_use_protocol)
6621 buf_output (saved_outerr, str, len);
6622 buf_copy_lines (buf_to_net, saved_outerr, 'E');
6624 else if (server_active)
6626 buf_output (saved_outerr, str, len);
6627 buf_copy_lines (protocol, saved_outerr, 'E');
6628 buf_send_counted (protocol);
6634 size_t to_write = len;
6635 const char *p = str;
6637 /* Make sure that output appears in order if stdout and stderr
6638 point to the same place. For the server case this is taken
6639 care of by the fact that saved_outerr always holds less
6643 while (to_write > 0)
6645 written = fwrite (p, 1, to_write, stderr);
6649 to_write -= written;
6656 /* Flush stderr. stderr is normally flushed automatically, of course,
6657 but this function is used to flush information from the server back
6662 #ifdef SERVER_SUPPORT
6663 if (error_use_protocol)
6665 /* skip the actual stderr flush in this case since the parent process
6666 * on the server should only be writing to stdout anyhow
6668 /* Flush what we can to the network, but don't block. */
6669 buf_flush (buf_to_net, 0);
6671 else if (server_active)
6673 /* make sure stderr is flushed before we send the flush count on the
6677 /* Send a special count to tell the parent to flush. */
6678 buf_send_special_count (protocol, -2);
6687 /* Make it possible for the user to see what has been written to
6688 stdout (it is up to the implementation to decide exactly how far it
6689 should go to ensure this). */
6693 #ifdef SERVER_SUPPORT
6694 if (error_use_protocol)
6696 /* Flush what we can to the network, but don't block. */
6697 buf_flush (buf_to_net, 0);
6699 else if (server_active)
6701 /* Just do nothing. This is because the code which
6702 cvs_flushout replaces, setting stdout to line buffering in
6703 main.c, didn't get called in the server child process. But
6704 in the future it is quite plausible that we'll want to make
6705 this case work analogously to cvs_flusherr.
6707 FIXME - DRP - I tried to implement this and triggered the following
6708 error: "Protocol error: uncounted data discarded". I don't need
6709 this feature right now, so I'm not going to bother with it yet.
6711 buf_send_special_count (protocol, -1);
6718 /* Output TEXT, tagging it according to TAG. There are lots more
6719 details about what TAG means in cvsclient.texi but for the simple
6720 case (e.g. non-client/server), TAG is just "newline" to output a
6721 newline (in which case TEXT must be NULL), and any other tag to
6724 Note that there is no way to output either \0 or \n as part of TEXT. */
6727 cvs_output_tagged (tag, text)
6731 if (text != NULL && strchr (text, '\n') != NULL)
6732 /* Uh oh. The protocol has no way to cope with this. For now
6733 we dump core, although that really isn't such a nice
6734 response given that this probably can be caused by newlines
6735 in filenames and other causes other than bugs in CVS. Note
6736 that we don't want to turn this into "MT newline" because
6737 this case is a newline within a tagged item, not a newline
6738 as extraneous sugar for the user. */
6741 /* Start and end tags don't take any text, per cvsclient.texi. */
6742 if (tag[0] == '+' || tag[0] == '-')
6743 assert (text == NULL);
6745 #ifdef SERVER_SUPPORT
6746 if (server_active && supported_response ("MT"))
6750 if (error_use_protocol)
6755 buf_output0 (buf, "MT ");
6756 buf_output0 (buf, tag);
6759 buf_output (buf, " ", 1);
6760 buf_output0 (buf, text);
6762 buf_output (buf, "\n", 1);
6764 if (!error_use_protocol)
6765 buf_send_counted (protocol);
6770 if (strcmp (tag, "newline") == 0)
6771 cvs_output ("\n", 1);
6772 else if (text != NULL)
6773 cvs_output (text, 0);