Merge rev 1.9 (new long flag to ignore the CVSROOT/passwd file)

rev 1.2 (local tag/$Id$ keyword support)  into version 1.11.22.
This commit is contained in:
David E. O'Brien 2008-01-13 06:12:54 +00:00
parent d0d4f2ef9b
commit defa58274e

View File

@ -20,6 +20,8 @@
#include "getline.h"
#include "buffer.h"
int server_active = 0;
#if defined(SERVER_SUPPORT) || defined(CLIENT_SUPPORT)
# ifdef HAVE_GSSAPI
/* This stuff isn't included solely with SERVER_SUPPORT since some of these
@ -360,13 +362,20 @@ create_adm_p (base_dir, dir)
dir_where_cvsadm_lives = xmalloc (strlen (base_dir) + strlen (dir) + 100);
if (dir_where_cvsadm_lives == NULL)
{
free (p);
return ENOMEM;
}
/* Allocate some space for the temporary string in which we will
construct filenames. */
tmp = xmalloc (strlen (base_dir) + strlen (dir) + 100);
if (tmp == NULL)
{
free (p);
free (dir_where_cvsadm_lives);
return ENOMEM;
}
/* We make several passes through this loop. On the first pass,
@ -1234,6 +1243,7 @@ serve_sticky (arg)
if (alloc_pending (80 + strlen (CVSADM_TAG)))
sprintf (pending_error_text, "E cannot write to %s", CVSADM_TAG);
pending_error = save_errno;
(void) fclose (f);
return;
}
if (fclose (f) == EOF)
@ -1682,7 +1692,9 @@ serve_unchanged (arg)
* is allowed, but broken versions of WinCVS & TortoiseCVS rely on
* this behavior.
*/
*timefield = '=';
if (*timefield != '+')
/* Skip this for entries with conflict markers. */
*timefield = '=';
break;
}
}
@ -1753,7 +1765,10 @@ serve_is_modified (arg)
* is allowed, but broken versions of WinCVS & TortoiseCVS rely on
* this behavior.
*/
*timefield = 'M';
if (*timefield != '+')
/* Skip this for entries with conflict markers. */
*timefield = 'M';
if (kopt != NULL)
{
if (alloc_pending (strlen (name) + 80))
@ -1840,6 +1855,7 @@ serve_entry (arg)
cp = xmalloc (strlen (arg) + 2);
if (cp == NULL)
{
free (p);
pending_error = ENOMEM;
return;
}
@ -2703,6 +2719,25 @@ set_nonblock_fd (fd)
/*
* Set buffer FD to blocking I/O. Returns 0 for success or errno code.
*/
int
set_block_fd (fd)
int fd;
{
int flags;
flags = fcntl (fd, F_GETFL, 0);
if (flags < 0)
return errno;
if (fcntl (fd, F_SETFL, flags & ~O_NONBLOCK) < 0)
return errno;
return 0;
}
static void
do_cvs_command (cmd_name, command)
char *cmd_name;
@ -2926,22 +2961,31 @@ error \n");
{
char junk;
ssize_t status;
while ((status = read (flowcontrol_pipe[0], &junk, 1)) > 0
|| (status == -1 && errno == EAGAIN));
set_block_fd (flowcontrol_pipe[0]);
while ((status = read (flowcontrol_pipe[0], &junk, 1)) > 0);
}
/* FIXME: No point in printing an error message with error(),
* as STDERR is already closed, but perhaps this could be syslogged?
*/
#endif
rcs_cleanup ();
Lock_Cleanup ();
/* Don't call server_cleanup - the parent will handle that. */
#ifdef SYSTEM_CLEANUP
/* Hook for OS-specific behavior, for example socket subsystems on
NT and OS2 or dealing with windows and arguments on Mac. */
SYSTEM_CLEANUP ();
#endif
exit (exitstatus);
}
/* OK, sit around getting all the input from the child. */
{
struct buffer *stdoutbuf;
struct buffer *stderrbuf;
struct buffer *protocol_inbuf;
struct buffer *stdoutbuf = NULL;
struct buffer *stderrbuf = NULL;
struct buffer *protocol_inbuf = NULL;
int err_exit = 0;
/* Number of file descriptors to check in select (). */
int num_to_check;
int count_needed = 1;
@ -2994,7 +3038,8 @@ error \n");
{
buf_output0 (buf_to_net, "E close failed\n");
print_error (errno);
goto error_exit;
err_exit = 1;
goto child_finish;
}
stdout_pipe[1] = -1;
@ -3002,7 +3047,8 @@ error \n");
{
buf_output0 (buf_to_net, "E close failed\n");
print_error (errno);
goto error_exit;
err_exit = 1;
goto child_finish;
}
stderr_pipe[1] = -1;
@ -3010,7 +3056,8 @@ error \n");
{
buf_output0 (buf_to_net, "E close failed\n");
print_error (errno);
goto error_exit;
err_exit = 1;
goto child_finish;
}
protocol_pipe[1] = -1;
@ -3019,7 +3066,8 @@ error \n");
{
buf_output0 (buf_to_net, "E close failed\n");
print_error (errno);
goto error_exit;
err_exit = 1;
goto child_finish;
}
flowcontrol_pipe[0] = -1;
#endif /* SERVER_FLOWCONTROL */
@ -3028,7 +3076,9 @@ error \n");
{
buf_output0 (buf_to_net, "E close failed\n");
print_error (errno);
goto error_exit;
dev_null_fd = -1; /* Do not try to close it again. */
err_exit = 1;
goto child_finish;
}
dev_null_fd = -1;
@ -3115,7 +3165,8 @@ error \n");
{
buf_output0 (buf_to_net, "E select failed\n");
print_error (errno);
goto error_exit;
err_exit = 1;
goto child_finish;
}
} while (numfds < 0);
@ -3148,7 +3199,8 @@ error \n");
{
buf_output0 (buf_to_net, "E buf_input_data failed\n");
print_error (status);
goto error_exit;
err_exit = 1;
goto child_finish;
}
/*
@ -3222,7 +3274,8 @@ error \n");
{
buf_output0 (buf_to_net, "E buf_input_data failed\n");
print_error (status);
goto error_exit;
err_exit = 1;
goto child_finish;
}
/* What should we do with errors? syslog() them? */
@ -3247,7 +3300,8 @@ error \n");
{
buf_output0 (buf_to_net, "E buf_input_data failed\n");
print_error (status);
goto error_exit;
err_exit = 1;
goto child_finish;
}
/* What should we do with errors? syslog() them? */
@ -3327,21 +3381,33 @@ E CVS locks may need cleaning up.\n");
command_pid = -1;
}
child_finish:
/*
* OK, we've waited for the child. By now all CVS locks are free
* and it's OK to block on the network.
*/
set_block (buf_to_net);
buf_flush (buf_to_net, 1);
buf_shutdown (protocol_inbuf);
buf_free (protocol_inbuf);
protocol_inbuf = NULL;
buf_shutdown (stderrbuf);
buf_free (stderrbuf);
stderrbuf = NULL;
buf_shutdown (stdoutbuf);
buf_free (stdoutbuf);
stdoutbuf = NULL;
if (protocol_inbuf)
{
buf_shutdown (protocol_inbuf);
buf_free (protocol_inbuf);
protocol_inbuf = NULL;
}
if (stderrbuf)
{
buf_shutdown (stderrbuf);
buf_free (stderrbuf);
stderrbuf = NULL;
}
if (stdoutbuf)
{
buf_shutdown (stdoutbuf);
buf_free (stdoutbuf);
stdoutbuf = NULL;
}
if (err_exit)
goto error_exit;
}
if (errs)
@ -3365,7 +3431,8 @@ E CVS locks may need cleaning up.\n");
command_pid = -1;
}
close (dev_null_fd);
if (dev_null_fd >= 0)
close (dev_null_fd);
close (protocol_pipe[0]);
close (protocol_pipe[1]);
close (stderr_pipe[0]);
@ -3693,6 +3760,10 @@ server_checked_in (file, update_dir, repository)
const char *update_dir;
const char *repository;
{
assert (file);
assert (update_dir);
assert (repository);
if (noexec)
return;
if (scratched_file != NULL && entries_line == NULL)
@ -4126,6 +4197,7 @@ server_updated (finfo, vers, updated, mode, checksum, filebuf)
free (scratched_file);
scratched_file = NULL;
}
buf_send_counted (protocol);
return;
}
@ -4204,7 +4276,6 @@ CVS server internal error: no mode in server_updated");
if (updated == SERVER_UPDATED)
{
Node *node;
Entnode *entnode;
if (!(supported_response ("Created")
&& supported_response ("Update-existing")))
@ -4222,9 +4293,13 @@ CVS server internal error: no mode in server_updated");
in case we end up processing it again (e.g. modules3-6
in the testsuite). */
node = findnode_fn (finfo->entries, finfo->file);
entnode = node->data;
free (entnode->timestamp);
entnode->timestamp = xstrdup ("=");
assert (node != NULL);
if (node != NULL)
{
Entnode *entnode = node->data;
free (entnode->timestamp);
entnode->timestamp = xstrdup ("=");
}
}
else if (updated == SERVER_MERGED)
buf_output0 (protocol, "Merged ");
@ -4511,10 +4586,13 @@ struct template_proc_data
a void * for it. */
static struct template_proc_data *tpd;
static int
template_proc PROTO((const char *repository, const char *template));
static int
template_proc (repository, template)
char *repository;
char *template;
const char *repository;
const char *template;
{
FILE *fp;
char buf[1024];
@ -4792,6 +4870,7 @@ struct request requests[] =
REQ_LINE("Checkin-time", serve_checkin_time, 0),
REQ_LINE("Modified", serve_modified, RQ_ESSENTIAL),
REQ_LINE("Is-modified", serve_is_modified, 0),
REQ_LINE("Empty-conflicts", serve_noop, 0),
/* The client must send this request to interoperate with CVS 1.5
through 1.9 servers. The server must support it (although it can
@ -5046,8 +5125,6 @@ server_cleanup (sig)
}
}
int server_active = 0;
int
server (argc, argv)
int argc;
@ -5479,6 +5556,7 @@ check_repository_password (username, password, repository, host_user_ptr)
{
if (!existence_error (errno))
error (0, errno, "cannot open %s", filename);
free (filename);
return 0;
}
@ -5912,6 +5990,8 @@ pserver_authenticate_connection ()
printf ("I LOVE YOU\n");
fflush (stdout);
/* It's okay to skip rcs_cleanup() and Lock_Cleanup() here. */
#ifdef SYSTEM_CLEANUP
/* Hook for OS-specific behavior, for example socket subsystems on
NT and OS2 or dealing with windows and arguments on Mac. */
@ -6425,12 +6505,10 @@ cvs_output (str, len)
size_t to_write = len;
const char *p = str;
/* For symmetry with cvs_outerr we would call fflush (stderr)
here. I guess the assumption is that stderr will be
unbuffered, so we don't need to. That sounds like a sound
assumption from the manpage I looked at, but if there was
something fishy about it, my guess is that calling fflush
would not produce a significant performance problem. */
/* Local users that do 'cvs status 2>&1' on a local repository
may see the informational messages out-of-order with the
status messages unless we use the fflush (stderr) here. */
fflush (stderr);
while (to_write > 0)
{
@ -6487,16 +6565,16 @@ this client does not support writing binary files to stdout");
size_t written;
size_t to_write = len;
const char *p = str;
/* For symmetry with cvs_outerr we would call fflush (stderr)
here. I guess the assumption is that stderr will be
unbuffered, so we don't need to. That sounds like a sound
assumption from the manpage I looked at, but if there was
something fishy about it, my guess is that calling fflush
would not produce a significant performance problem. */
#ifdef USE_SETMODE_STDOUT
int oldmode;
#endif
/* Local users that do 'cvs status 2>&1' on a local repository
may see the informational messages out-of-order with the
status messages unless we use the fflush (stderr) here. */
fflush (stderr);
#ifdef USE_SETMODE_STDOUT
/* It is possible that this should be the same ifdef as
USE_SETMODE_BINARY but at least for the moment we keep them
separate. Mostly this is just laziness and/or a question