summaryrefslogtreecommitdiffstats
path: root/contrib/cvs/src/server.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/cvs/src/server.c')
-rw-r--r--contrib/cvs/src/server.c88
1 files changed, 57 insertions, 31 deletions
diff --git a/contrib/cvs/src/server.c b/contrib/cvs/src/server.c
index e820388..2959ac2 100644
--- a/contrib/cvs/src/server.c
+++ b/contrib/cvs/src/server.c
@@ -1197,7 +1197,7 @@ serve_modified (arg)
}
{
- int status = change_mode (arg, mode_text);
+ int status = change_mode (arg, mode_text, 0);
free (mode_text);
if (status)
{
@@ -3358,12 +3358,13 @@ server_modtime (finfo, vers_ts)
/* See server.h for description. */
void
-server_updated (finfo, vers, updated, file_info, checksum)
+server_updated (finfo, vers, updated, mode, checksum, filebuf)
struct file_info *finfo;
Vers_TS *vers;
enum server_updated_arg4 updated;
- struct stat *file_info;
+ mode_t mode;
unsigned char *checksum;
+ struct buffer *filebuf;
{
if (noexec)
{
@@ -3382,25 +3383,43 @@ server_updated (finfo, vers, updated, file_info, checksum)
if (entries_line != NULL && scratched_file == NULL)
{
FILE *f;
- struct stat sb;
struct buffer_data *list, *last;
unsigned long size;
char size_text[80];
- if ( CVS_STAT (finfo->file, &sb) < 0)
+ if (filebuf != NULL)
{
- if (existence_error (errno))
+ size = buf_length (filebuf);
+ if (mode == (mode_t) -1)
+ error (1, 0, "\
+CVS server internal error: no mode in server_updated");
+ }
+ else
+ {
+ struct stat sb;
+
+ if ( CVS_STAT (finfo->file, &sb) < 0)
{
- /*
- * If we have a sticky tag for a branch on which the
- * file is dead, and cvs update the directory, it gets
- * a T_CHECKOUT but no file. So in this case just
- * forget the whole thing. */
- free (entries_line);
- entries_line = NULL;
- goto done;
+ if (existence_error (errno))
+ {
+ /* If we have a sticky tag for a branch on which
+ the file is dead, and cvs update the directory,
+ it gets a T_CHECKOUT but no file. So in this
+ case just forget the whole thing. */
+ free (entries_line);
+ entries_line = NULL;
+ goto done;
+ }
+ error (1, errno, "reading %s", finfo->fullname);
+ }
+ size = sb.st_size;
+ if (mode == (mode_t) -1)
+ {
+ /* FIXME: When we check out files the umask of the
+ server (set in .bashrc if rsh is in use) affects
+ what mode we send, and it shouldn't. */
+ mode = sb.st_mode;
}
- error (1, errno, "reading %s", finfo->fullname);
}
if (checksum != NULL)
@@ -3469,21 +3488,14 @@ server_updated (finfo, vers, updated, file_info, checksum)
{
char *mode_string;
- /* FIXME: When we check out files the umask of the server
- (set in .bashrc if rsh is in use) affects what mode we
- send, and it shouldn't. */
- if (file_info != NULL)
- mode_string = mode_to_string (file_info->st_mode);
- else
- mode_string = mode_to_string (sb.st_mode);
+ mode_string = mode_to_string (mode);
buf_output0 (protocol, mode_string);
buf_output0 (protocol, "\n");
free (mode_string);
}
list = last = NULL;
- size = 0;
- if (sb.st_size > 0)
+ if (size > 0)
{
/* Throughout this section we use binary mode to read the
file we are sending. The client handles any line ending
@@ -3496,11 +3508,19 @@ server_updated (finfo, vers, updated, file_info, checksum)
* might be computable somehow; using 100 here is just
* a first approximation.
*/
- && sb.st_size > 100)
+ && size > 100)
{
int status, fd, gzip_status;
pid_t gzip_pid;
+ /* Callers must avoid passing us a buffer if
+ file_gzip_level is set. We could handle this case,
+ but it's not worth it since this case never arises
+ with a current client and server. */
+ if (filebuf != NULL)
+ error (1, 0, "\
+CVS server internal error: unhandled case in server_updated");
+
fd = CVS_OPEN (finfo->file, O_RDONLY | OPEN_BINARY, 0);
if (fd < 0)
error (1, errno, "reading %s", finfo->fullname);
@@ -3523,15 +3543,14 @@ server_updated (finfo, vers, updated, file_info, checksum)
/* Prepending length with "z" is flag for using gzip here. */
buf_output0 (protocol, "z");
}
- else
+ else if (filebuf == NULL)
{
long status;
- size = sb.st_size;
f = CVS_FOPEN (finfo->file, "rb");
if (f == NULL)
error (1, errno, "reading %s", finfo->fullname);
- status = buf_read_file (f, sb.st_size, &list, &last);
+ status = buf_read_file (f, size, &list, &last);
if (status == -2)
(*protocol->memory_error) (protocol);
else if (status != 0)
@@ -3545,7 +3564,13 @@ server_updated (finfo, vers, updated, file_info, checksum)
sprintf (size_text, "%lu\n", size);
buf_output0 (protocol, size_text);
- buf_append_data (protocol, list, last);
+ if (filebuf == NULL)
+ buf_append_data (protocol, list, last);
+ else
+ {
+ buf_append_buffer (protocol, filebuf);
+ buf_free (filebuf);
+ }
/* Note we only send a newline here if the file ended with one. */
/*
@@ -3558,6 +3583,7 @@ server_updated (finfo, vers, updated, file_info, checksum)
if ((updated == SERVER_UPDATED
|| updated == SERVER_PATCHED
|| updated == SERVER_RCS_DIFF)
+ && filebuf != NULL
/* But if we are joining, we'll need the file when we call
join_file. */
&& !joining ())
@@ -5611,7 +5637,7 @@ this client does not support writing binary files to stdout");
I assume that what they are talking about can also be helped
by flushing the stream before changing the mode. */
fflush (stdout);
- oldmode = _setmode (_fileno (stdout), _O_BINARY);
+ oldmode = _setmode (_fileno (stdout), OPEN_BINARY);
if (oldmode < 0)
error (0, errno, "failed to setmode on stdout");
#endif
@@ -5626,7 +5652,7 @@ this client does not support writing binary files to stdout");
}
#ifdef USE_SETMODE_STDOUT
fflush (stdout);
- if (_setmode (_fileno (stdout), oldmode) != _O_BINARY)
+ if (_setmode (_fileno (stdout), oldmode) != OPEN_BINARY)
error (0, errno, "failed to setmode on stdout");
#endif
}
OpenPOWER on IntegriCloud