summaryrefslogtreecommitdiff
path: root/gnu
diff options
context:
space:
mode:
authorThorsten Lockert <tholo@cvs.openbsd.org>1996-05-04 07:26:06 +0000
committerThorsten Lockert <tholo@cvs.openbsd.org>1996-05-04 07:26:06 +0000
commit333d936c4b59ae3c1a3cddf87b00531c7befd9d1 (patch)
treec9b1df022db6dca7efb0ac8ff7e1c70c179220dc /gnu
parent4178701cd811d1ed3a4e989388085cdbda2af60b (diff)
Don't use the result of "diff" if just sending the new file would be shorter
Diffstat (limited to 'gnu')
-rw-r--r--gnu/usr.bin/cvs/src/update.c538
1 files changed, 264 insertions, 274 deletions
diff --git a/gnu/usr.bin/cvs/src/update.c b/gnu/usr.bin/cvs/src/update.c
index 0e01faeda74..84d406ccb70 100644
--- a/gnu/usr.bin/cvs/src/update.c
+++ b/gnu/usr.bin/cvs/src/update.c
@@ -34,17 +34,12 @@
*/
#include "cvs.h"
-#ifdef CLIENT_SUPPORT
-#include "update.h"
-#endif
#ifdef SERVER_SUPPORT
#include "md5.h"
#endif
-
-#ifndef lint
-static const char rcsid[] = "$CVSid: @(#)update.c 1.95 94/10/22 $";
-USE(rcsid);
-#endif
+#include "watch.h"
+#include "fileattr.h"
+#include "edit.h"
static int checkout_file PROTO((char *file, char *repository, List *entries,
List *srcfiles, Vers_TS *vers_ts, char *update_dir));
@@ -61,13 +56,10 @@ static int scratch_file PROTO((char *file, char *repository, List * entries,
char *update_dir));
static Dtype update_dirent_proc PROTO((char *dir, char *repository, char *update_dir));
static int update_dirleave_proc PROTO((char *dir, int err, char *update_dir));
-static int update_file_proc PROTO((char *file, char *update_dir, char *repository,
- List * entries, List * srcfiles));
-#ifndef CLIENT_SUPPORT
-static int update_filesdone_proc PROTO((int err, char *repository, char *update_dir));
-#endif
+static int update_fileproc PROTO ((struct file_info *));
+static int update_filesdone_proc PROTO((int err, char *repository,
+ char *update_dir));
static int write_letter PROTO((char *file, int letter, char *update_dir));
-static void ignore_files PROTO((List * ilist, char *update_dir));
#ifdef SERVER_SUPPORT
static void join_file PROTO((char *file, List *srcfiles, Vers_TS *vers_ts,
char *update_dir, List *entries, char *repository));
@@ -89,11 +81,7 @@ static int pipeout = 0;
#ifdef SERVER_SUPPORT
static int patches = 0;
#endif
-#ifdef CLIENT_SUPPORT
-List *ignlist = (List *) NULL;
-#else
static List *ignlist = (List *) NULL;
-#endif
static time_t last_register_time;
static const char *const update_usage[] =
{
@@ -226,8 +214,6 @@ update (argc, argv)
start_server ();
- ign_setup ();
-
if (local)
send_arg("-l");
if (update_build_dirs)
@@ -270,7 +256,10 @@ update (argc, argv)
}
if (failed_patches == NULL)
+ {
+ send_file_names (argc, argv);
send_files (argc, argv, local, aflag);
+ }
else
{
int i;
@@ -286,6 +275,7 @@ update (argc, argv)
for (i = 0; i < failed_patches_count; i++)
(void) unlink_file (failed_patches[i]);
+ send_file_names (failed_patches_count, failed_patches);
send_files (failed_patches_count, failed_patches, local,
aflag);
}
@@ -293,8 +283,7 @@ update (argc, argv)
failed_patches = NULL;
failed_patches_count = 0;
- if (fprintf (to_server, "update\n") < 0)
- error (1, errno, "writing to server");
+ send_to_server ("update\012", 0);
status = get_responses_and_close ();
if (status != 0)
@@ -306,6 +295,11 @@ update (argc, argv)
}
#endif
+ if (tag != NULL)
+ tag_check_valid (tag, argc, argv, local, aflag, "");
+ /* FIXME: We don't call tag_check_valid on join_rev1 and join_rev2
+ yet (make sure to handle ':' correctly if we do, though). */
+
/*
* If we are updating the entire directory (for real) and building dirs
* as we go, we make sure there is no static entries file and write the
@@ -315,7 +309,7 @@ update (argc, argv)
{
if (update_build_dirs)
{
- if (unlink_file (CVSADM_ENTSTAT) < 0 && errno != ENOENT)
+ if (unlink_file (CVSADM_ENTSTAT) < 0 && ! existence_error (errno))
error (1, errno, "cannot remove file %s", CVSADM_ENTSTAT);
#ifdef SERVER_SUPPORT
if (server_active)
@@ -407,7 +401,7 @@ do_update (argc, argv, xoptions, xtag, xdate, xforce, local, xbuild, xaflag,
date_rev2 = (char *) NULL;
/* call the recursion processor */
- err = start_recursion (update_file_proc, update_filesdone_proc,
+ err = start_recursion (update_fileproc, update_filesdone_proc,
update_dirent_proc, update_dirleave_proc,
argc, argv, local, which, aflag, 1,
preload_update_dir, 1, 0);
@@ -437,20 +431,16 @@ do_update (argc, argv, xoptions, xtag, xdate, xforce, local, xbuild, xaflag,
* appropriate magic for checkout
*/
static int
-update_file_proc (file, update_dir, repository, entries, srcfiles)
- char *file;
- char *update_dir;
- char *repository;
- List *entries;
- List *srcfiles;
+update_fileproc (finfo)
+ struct file_info *finfo;
{
int retval;
Ctype status;
Vers_TS *vers;
- status = Classify_File (file, tag, date, options, force_tag_match,
- aflag, repository, entries, srcfiles, &vers,
- update_dir, pipeout);
+ status = Classify_File (finfo->file, tag, date, options, force_tag_match,
+ aflag, finfo->repository, finfo->entries, finfo->srcfiles, &vers,
+ finfo->update_dir, pipeout);
if (pipeout)
{
/*
@@ -479,13 +469,13 @@ update_file_proc (file, update_dir, repository, entries, srcfiles)
#ifdef SERVER_SUPPORT
case T_PATCH: /* needs patch */
#endif
- retval = checkout_file (file, repository, entries, srcfiles,
- vers, update_dir);
+ retval = checkout_file (finfo->file, finfo->repository, finfo->entries, finfo->srcfiles,
+ vers, finfo->update_dir);
break;
default: /* can't ever happen :-) */
error (0, 0,
- "unknown file status %d for file %s", status, file);
+ "unknown file status %d for file %s", status, finfo->file);
retval = 0;
break;
}
@@ -501,24 +491,24 @@ update_file_proc (file, update_dir, repository, entries, srcfiles)
break;
case T_CONFLICT: /* old punt-type errors */
retval = 1;
- (void) write_letter (file, 'C', update_dir);
+ (void) write_letter (finfo->file, 'C', finfo->update_dir);
break;
case T_NEEDS_MERGE: /* needs merging */
if (noexec)
{
retval = 1;
- (void) write_letter (file, 'C', update_dir);
+ (void) write_letter (finfo->file, 'C', finfo->update_dir);
}
else
{
- if (wrap_merge_is_copy (file))
+ if (wrap_merge_is_copy (finfo->file))
/* Should we be warning the user that we are
* overwriting the user's copy of the file? */
- retval = checkout_file (file, repository, entries,
- srcfiles, vers, update_dir);
+ retval = checkout_file (finfo->file, finfo->repository, finfo->entries,
+ finfo->srcfiles, vers, finfo->update_dir);
else
- retval = merge_file (file, repository, entries,
- vers, update_dir);
+ retval = merge_file (finfo->file, finfo->repository, finfo->entries,
+ vers, finfo->update_dir);
}
break;
case T_MODIFIED: /* locally modified */
@@ -536,12 +526,12 @@ update_file_proc (file, update_dir, repository, entries, srcfiles)
if (server_active)
retcode = vers->ts_conflict[0] != '=';
else {
- filestamp = time_stamp (file);
+ filestamp = time_stamp (finfo->file);
retcode = strcmp (vers->ts_conflict, filestamp);
free (filestamp);
}
#else
- filestamp = time_stamp (file);
+ filestamp = time_stamp (finfo->file);
retcode = strcmp (vers->ts_conflict, filestamp);
free (filestamp);
#endif
@@ -552,38 +542,38 @@ update_file_proc (file, update_dir, repository, entries, srcfiles)
* If the timestamps differ, look for Conflict
* indicators to see if 'C' anyway.
*/
- run_setup ("%s -s", GREP);
+ run_setup ("%s", GREP);
run_arg (RCS_MERGE_PAT);
- run_arg (file);
- retcode = run_exec (RUN_TTY, RUN_TTY,
+ run_arg (finfo->file);
+ retcode = run_exec (RUN_TTY, DEVNULL,
RUN_TTY,RUN_NORMAL);
if (retcode == -1)
{
- if (update_dir[0] == '\0')
+ if (finfo->update_dir[0] == '\0')
error (1, errno,
"fork failed while examining conflict in `%s'",
- file);
+ finfo->file);
else
error (1, errno,
"fork failed while examining conflict in `%s/%s'",
- update_dir, file);
+ finfo->update_dir, finfo->file);
}
}
if (!retcode)
{
- (void) write_letter (file, 'C', update_dir);
+ (void) write_letter (finfo->file, 'C', finfo->update_dir);
retval = 1;
}
else
{
/* Reregister to clear conflict flag. */
- Register (entries, file, vers->vn_rcs, vers->ts_rcs,
+ Register (finfo->entries, finfo->file, vers->vn_rcs, vers->ts_rcs,
vers->options, vers->tag,
vers->date, (char *)0);
}
}
if (!retval)
- retval = write_letter (file, 'M', update_dir);
+ retval = write_letter (finfo->file, 'M', finfo->update_dir);
break;
#ifdef SERVER_SUPPORT
case T_PATCH: /* needs patch */
@@ -593,13 +583,13 @@ update_file_proc (file, update_dir, repository, entries, srcfiles)
struct stat file_info;
unsigned char checksum[16];
- retval = patch_file (file, repository, entries, srcfiles,
- vers, update_dir, &docheckout,
+ retval = patch_file (finfo->file, finfo->repository, finfo->entries, finfo->srcfiles,
+ vers, finfo->update_dir, &docheckout,
&file_info, checksum);
if (! docheckout)
{
if (server_active && retval == 0)
- server_updated (file, update_dir, repository,
+ server_updated (finfo->file, finfo->update_dir, finfo->repository,
SERVER_PATCHED, &file_info,
checksum);
break;
@@ -612,33 +602,33 @@ update_file_proc (file, update_dir, repository, entries, srcfiles)
/* Fall through. */
#endif
case T_CHECKOUT: /* needs checkout */
- retval = checkout_file (file, repository, entries, srcfiles,
- vers, update_dir);
+ retval = checkout_file (finfo->file, finfo->repository, finfo->entries, finfo->srcfiles,
+ vers, finfo->update_dir);
#ifdef SERVER_SUPPORT
if (server_active && retval == 0)
- server_updated (file, update_dir, repository,
+ server_updated (finfo->file, finfo->update_dir, finfo->repository,
SERVER_UPDATED, (struct stat *) NULL,
(unsigned char *) NULL);
#endif
break;
case T_ADDED: /* added but not committed */
- retval = write_letter (file, 'A', update_dir);
+ retval = write_letter (finfo->file, 'A', finfo->update_dir);
break;
case T_REMOVED: /* removed but not committed */
- retval = write_letter (file, 'R', update_dir);
+ retval = write_letter (finfo->file, 'R', finfo->update_dir);
break;
case T_REMOVE_ENTRY: /* needs to be un-registered */
- retval = scratch_file (file, repository, entries, update_dir);
+ retval = scratch_file (finfo->file, finfo->repository, finfo->entries, finfo->update_dir);
#ifdef SERVER_SUPPORT
if (server_active && retval == 0)
- server_updated (file, update_dir, repository,
+ server_updated (finfo->file, finfo->update_dir, finfo->repository,
SERVER_UPDATED, (struct stat *) NULL,
(unsigned char *) NULL);
#endif
break;
default: /* can't ever happen :-) */
error (0, 0,
- "unknown file status %d for file %s", status, file);
+ "unknown file status %d for file %s", status, finfo->file);
retval = 0;
break;
}
@@ -647,9 +637,9 @@ update_file_proc (file, update_dir, repository, entries, srcfiles)
/* only try to join if things have gone well thus far */
if (retval == 0 && join_rev1)
#ifdef SERVER_SUPPORT
- join_file (file, srcfiles, vers, update_dir, entries, repository);
+ join_file (finfo->file, finfo->srcfiles, vers, finfo->update_dir, finfo->entries, finfo->repository);
#else
- join_file (file, srcfiles, vers, update_dir, entries);
+ join_file (finfo->file, finfo->srcfiles, vers, finfo->update_dir, finfo->entries);
#endif
/* if this directory has an ignore list, add this file to it */
@@ -659,7 +649,7 @@ update_file_proc (file, update_dir, repository, entries, srcfiles)
p = getnode ();
p->type = FILES;
- p->key = xstrdup (file);
+ p->key = xstrdup (finfo->file);
if (addnode (ignlist, p) != 0)
freenode (p);
}
@@ -668,16 +658,18 @@ update_file_proc (file, update_dir, repository, entries, srcfiles)
return (retval);
}
-/*
- * update_filesdone_proc () is used
- */
+static void update_ignproc PROTO ((char *, char *));
+
+static void
+update_ignproc (file, dir)
+ char *file;
+ char *dir;
+{
+ (void) write_letter (file, '?', dir);
+}
+
/* ARGSUSED */
-#ifdef CLIENT_SUPPORT
-/* Also used by client.c */
-int
-#else
static int
-#endif
update_filesdone_proc (err, repository, update_dir)
int err;
char *repository;
@@ -686,25 +678,19 @@ update_filesdone_proc (err, repository, update_dir)
/* if this directory has an ignore list, process it then free it */
if (ignlist)
{
- ignore_files (ignlist, update_dir);
+ ignore_files (ignlist, update_dir, update_ignproc);
dellist (&ignlist);
}
/* Clean up CVS admin dirs if we are export */
-#ifdef CLIENT_SUPPORT
- /* In the client, we need to clean these up after we create them. Doing
- it here might would clean up the user's previous contents even on
- SIGINT which probably is bad. */
- if (!client_active && strcmp (command_name, "export") == 0)
-#else
if (strcmp (command_name, "export") == 0)
-#endif
{
- run_setup ("%s -fr", RM);
- run_arg (CVSADM);
- (void) run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL);
+ /* I'm not sure the existence_error is actually possible (except
+ in cases where we really should print a message), but since
+ this code used to ignore all errors, I'll play it safe. */
+ if (unlink_file_dir (CVSADM) < 0 && !existence_error (errno))
+ error (0, errno, "cannot remove %s directory", CVSADM);
}
-#ifdef CVSADM_ROOT
#ifdef SERVER_SUPPORT
else if (!server_active && !pipeout)
#else
@@ -712,17 +698,9 @@ update_filesdone_proc (err, repository, update_dir)
#endif /* SERVER_SUPPORT */
{
/* If there is no CVS/Root file, add one */
-#ifdef CLIENT_SUPPORT
- if (!isfile (CVSADM_ROOT)
- /* but only if we want it */
- && ! (getenv ("CVS_IGNORE_REMOTE_ROOT") && strchr (CVSroot, ':'))
- )
-#else /* No CLIENT_SUPPORT */
if (!isfile (CVSADM_ROOT))
-#endif /* No CLIENT_SUPPORT */
Create_Root( (char *) NULL, CVSroot );
}
-#endif /* CVSADM_ROOT */
return (err);
}
@@ -768,6 +746,28 @@ update_dirent_proc (dir, repository, update_dir)
Create_Admin (dir, update_dir, repository, tag, date);
}
}
+ else
+ {
+ char *cvsadmdir;
+
+ /* The directory exists. Check to see if it has a CVS
+ subdirectory. */
+
+ cvsadmdir = xmalloc (strlen (dir) + 80);
+ strcpy (cvsadmdir, dir);
+ strcat (cvsadmdir, "/");
+ strcat (cvsadmdir, CVSADM);
+
+ if (!isdir (cvsadmdir))
+ {
+ /* We cannot successfully recurse into a directory without a CVS
+ subdirectory. Generally we will have already printed
+ "? foo". */
+ free (cvsadmdir);
+ return R_SKIP_ALL;
+ }
+ free (cvsadmdir);
+ }
/*
* If we are building dirs and not going to stdout, we make sure there is
@@ -780,7 +780,7 @@ update_dirent_proc (dir, repository, update_dir)
char tmp[PATH_MAX];
(void) sprintf (tmp, "%s/%s", dir, CVSADM_ENTSTAT);
- if (unlink_file (tmp) < 0 && errno != ENOENT)
+ if (unlink_file (tmp) < 0 && ! existence_error (errno))
error (1, errno, "cannot remove file %s", tmp);
#ifdef SERVER_SUPPORT
if (server_active)
@@ -846,13 +846,16 @@ update_dirleave_proc (dir, err, update_dir)
free (repository);
}
+ /* FIXME: chdir ("..") loses with symlinks. */
/* Prune empty dirs on the way out - if necessary */
(void) chdir ("..");
if (update_prune_dirs && isemptydir (dir))
{
- run_setup ("%s -fr", RM);
- run_arg (dir);
- (void) run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL);
+ /* I'm not sure the existence_error is actually possible (except
+ in cases where we really should print a message), but since
+ this code used to ignore all errors, I'll play it safe. */
+ if (unlink_file_dir (dir) < 0 && !existence_error (errno))
+ error (0, errno, "cannot remove %s directory", dir);
}
return (err);
@@ -918,9 +921,8 @@ checkout_file (file, repository, entries, srcfiles, vers_ts, update_dir)
char backup[PATH_MAX];
int set_time, retval = 0;
int retcode = 0;
-#ifdef DEATH_SUPPORT
+ int status;
int file_is_dead;
-#endif
/* don't screw with backup files if we're going to stdout */
if (!pipeout)
@@ -932,84 +934,102 @@ checkout_file (file, repository, entries, srcfiles, vers_ts, update_dir)
(void) unlink_file (backup);
}
-#ifdef DEATH_SUPPORT
file_is_dead = RCS_isdead (vers_ts->srcfile, vers_ts->vn_rcs);
- if (!file_is_dead) {
-#endif
-
- run_setup ("%s%s -q -r%s %s", Rcsbin, RCS_CO, vers_ts->vn_rcs,
- vers_ts->options);
-
- /*
- * if we are checking out to stdout, print a nice message to stderr, and
- * add the -p flag to the command
- */
- if (pipeout)
+ if (!file_is_dead)
{
- run_arg ("-p");
- if (!quiet)
+ /*
+ * if we are checking out to stdout, print a nice message to
+ * stderr, and add the -p flag to the command */
+ if (pipeout)
{
- (void) fprintf (stderr, "===================================================================\n");
- if (update_dir[0])
- (void) fprintf (stderr, "Checking out %s/%s\n",
- update_dir, file);
- else
- (void) fprintf (stderr, "Checking out %s\n", file);
- (void) fprintf (stderr, "RCS: %s\n", vers_ts->srcfile->path);
- (void) fprintf (stderr, "VERS: %s\n", vers_ts->vn_rcs);
- (void) fprintf (stderr, "***************\n");
+ if (!quiet)
+ {
+ (void) fprintf (stderr, "\
+===================================================================\n");
+ if (update_dir[0])
+ (void) fprintf (stderr, "Checking out %s/%s\n",
+ update_dir, file);
+ else
+ (void) fprintf (stderr, "Checking out %s\n", file);
+ (void) fprintf (stderr, "RCS: %s\n", vers_ts->srcfile->path);
+ (void) fprintf (stderr, "VERS: %s\n", vers_ts->vn_rcs);
+ (void) fprintf (stderr, "***************\n");
+ }
}
- }
-
- /* tack on the rcs and maybe the user file */
- run_arg (vers_ts->srcfile->path);
- if (!pipeout)
- run_arg (file);
-#ifdef DEATH_SUPPORT
+ status = RCS_checkout (vers_ts->srcfile->path,
+ pipeout ? NULL : file, vers_ts->vn_tag,
+ vers_ts->options, RUN_TTY, 0, 0);
}
- if (file_is_dead || (retcode = run_exec (RUN_TTY, RUN_TTY, RUN_TTY,
-#else
- if ((retcode = run_exec (RUN_TTY, RUN_TTY, RUN_TTY,
-#endif
- (pipeout ? (RUN_NORMAL|RUN_REALLY) : RUN_NORMAL))) == 0)
+ if (file_is_dead || status == 0)
{
if (!pipeout)
{
Vers_TS *xvers_ts;
-#ifdef DEATH_SUPPORT
int resurrecting;
resurrecting = 0;
if (file_is_dead && joining())
{
- /* when joining, we need to get dead files checked
- out. Try harder. */
- run_setup ("%s%s -q -r%s %s", Rcsbin, RCS_CO, vers_ts->vn_rcs,
- vers_ts->options);
-
- run_arg ("-f");
- run_arg (vers_ts->srcfile->path);
- run_arg (file);
- if ((retcode = run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL)) != 0)
+ if (RCS_getversion (vers_ts->srcfile, join_rev1,
+ date_rev1, 1, 0)
+ || (join_rev2 != NULL &&
+ RCS_getversion (vers_ts->srcfile, join_rev2,
+ date_rev2, 1, 0)))
+ {
+ /* when joining, we need to get dead files checked
+ out. Try harder. */
+ /* I think that RCS_FLAGS_FORCE is here only because
+ passing -f to co used to enable checking out
+ a dead revision in the old version of death
+ support which used a hacked RCS instead of using
+ the RCS state. */
+ retcode = RCS_checkout (vers_ts->srcfile->path, file,
+ vers_ts->vn_rcs,
+ vers_ts->options, RUN_TTY,
+ RCS_FLAGS_FORCE, 0);
+ if (retcode != 0)
+ {
+ error (retcode == -1 ? 1 : 0,
+ retcode == -1 ? errno : 0,
+ "could not check out %s", file);
+ (void) unlink_file (backup);
+ return (retcode);
+ }
+ file_is_dead = 0;
+ resurrecting = 1;
+ }
+ else
{
- error (retcode == -1 ? 1 : 0, retcode == -1 ? errno : 0,
- "could not check out %s", file);
- (void) unlink_file (backup);
- return (retcode);
+ /* If the file is dead and does not contain either of
+ the join revisions, then we don't want to check it
+ out. */
+ return 0;
}
- file_is_dead = 0;
- resurrecting = 1;
}
- if (cvswrite == TRUE && !file_is_dead)
+ if (cvswrite == TRUE
+ && !file_is_dead
+ && !fileattr_get (file, "_watched"))
xchmod (file, 1);
-#else /* No DEATH_SUPPORT */
- if (cvswrite == TRUE)
- xchmod (file, 1);
-#endif /* No DEATH_SUPPORT */
+
+ {
+ /* A newly checked out file is never under the spell
+ of "cvs edit". If we think we were editing it
+ from a previous life, clean up. Would be better to
+ check for same the working directory instead of
+ same user, but that is hairy. */
+
+ struct addremove_args args;
+
+ editor_set (file, getcaller (), NULL);
+
+ memset (&args, 0, sizeof args);
+ args.remove_temp = 1;
+ watch_modify_watchers (file, &args);
+ }
/* set the time from the RCS file iff it was unknown before */
if (vers_ts->vn_user == NULL ||
@@ -1026,10 +1046,23 @@ checkout_file (file, repository, entries, srcfiles, vers_ts, update_dir)
force_tag_match, set_time, entries, srcfiles);
if (strcmp (xvers_ts->options, "-V4") == 0)
xvers_ts->options[0] = '\0';
+ /* If no keyword expansion was specified on command line,
+ use whatever was in the file. This is how we tell the client
+ whether a file is binary. */
+ if (xvers_ts->options[0] == '\0')
+ {
+ if (vers_ts->srcfile->expand != NULL)
+ {
+ free (xvers_ts->options);
+ xvers_ts->options =
+ xmalloc (strlen (vers_ts->srcfile->expand) + 3);
+ strcpy (xvers_ts->options, "-k");
+ strcat (xvers_ts->options, vers_ts->srcfile->expand);
+ }
+ }
(void) time (&last_register_time);
-#ifdef DEATH_SUPPORT
if (file_is_dead)
{
if (xvers_ts->vn_user != NULL)
@@ -1044,7 +1077,7 @@ checkout_file (file, repository, entries, srcfiles, vers_ts, update_dir)
update_dir, file);
}
Scratch_Entry (entries, file);
- if (unlink_file (file) < 0 && errno != ENOENT)
+ if (unlink_file (file) < 0 && ! existence_error (errno))
{
if (update_dir[0] == '\0')
error (0, errno, "cannot remove %s", file);
@@ -1059,11 +1092,6 @@ checkout_file (file, repository, entries, srcfiles, vers_ts, update_dir)
xvers_ts->ts_user, xvers_ts->options,
xvers_ts->tag, xvers_ts->date,
(char *)0); /* Clear conflict flag on fresh checkout */
-#else /* No DEATH_SUPPORT */
- Register (entries, file, xvers_ts->vn_rcs, xvers_ts->ts_user,
- xvers_ts->options, xvers_ts->tag, xvers_ts->date,
- (char *)0); /* Clear conflict flag on fresh checkout */
-#endif /* No DEATH_SUPPORT */
/* fix up the vers structure, in case it is used by join */
if (join_rev1)
@@ -1083,16 +1111,9 @@ checkout_file (file, repository, entries, srcfiles, vers_ts, update_dir)
freevers_ts (&xvers_ts);
-#ifdef DEATH_SUPPORT
if (!really_quiet && !file_is_dead)
-#else
- if (!really_quiet)
-#endif
{
- if (update_dir[0])
- (void) printf ("U %s/%s\n", update_dir, file);
- else
- (void) printf ("U %s\n", file);
+ write_letter (file, 'U', update_dir);
}
}
}
@@ -1139,6 +1160,7 @@ patch_file (file, repository, entries, srcfiles, vers_ts, update_dir,
int retval = 0;
int retcode = 0;
int fail;
+ long file_size;
FILE *e;
*docheckout = 0;
@@ -1163,9 +1185,13 @@ patch_file (file, repository, entries, srcfiles, vers_ts, update_dir,
/* We need to check out both revisions first, to see if either one
has a trailing newline. Because of this, we don't use rcsdiff,
but just use diff. */
- run_setup ("%s%s -q -p -r%s %s %s", Rcsbin, RCS_CO, vers_ts->vn_user,
- vers_ts->options, vers_ts->srcfile->path);
- if (run_exec (RUN_TTY, file1, RUN_TTY, RUN_NORMAL) != 0)
+ if (noexec)
+ retcode = 0;
+ else
+ retcode = RCS_checkout (vers_ts->srcfile->path, NULL,
+ vers_ts->vn_user,
+ vers_ts->options, file1, 0, 0);
+ if (retcode != 0)
fail = 1;
else
{
@@ -1189,9 +1215,10 @@ patch_file (file, repository, entries, srcfiles, vers_ts, update_dir,
can get the right modes into *FILE_INFO. We can't check it
out directly into file2 because co doesn't understand how
to do that. */
- run_setup ("%s%s -q -r%s %s %s %s", Rcsbin, RCS_CO, vers_ts->vn_rcs,
- vers_ts->options, vers_ts->srcfile->path, file);
- if (run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL) != 0)
+ retcode = RCS_checkout (vers_ts->srcfile->path, file,
+ vers_ts->vn_rcs,
+ vers_ts->options, RUN_TTY, 0, 0);
+ if (retcode != 0)
fail = 1;
else
{
@@ -1203,7 +1230,8 @@ patch_file (file, repository, entries, srcfiles, vers_ts, update_dir,
else
{
rename_file (file, file2);
- if (cvswrite == TRUE)
+ if (cvswrite == TRUE
+ && !fileattr_get (file, "_watched"))
xchmod (file2, 1);
e = fopen (file2, "r");
if (e == NULL)
@@ -1232,12 +1260,16 @@ patch_file (file, repository, entries, srcfiles, vers_ts, update_dir,
fail = 1;
}
+ fseek(e, 0L, SEEK_END);
+ file_size = ftell(e);
+
fclose (e);
}
}
}
}
+ retcode = 0;
if (! fail)
{
/* FIXME: This whole thing with diff/patch is rather more
@@ -1275,6 +1307,16 @@ patch_file (file, repository, entries, srcfiles, vers_ts, update_dir,
patch can't handle that. */
fail = 1;
}
+ else {
+ /*
+ * Don't send a diff if just sending the entire file
+ * would be smaller
+ */
+ fseek(e, 0L, SEEK_END);
+ if (file_size < ftell(e))
+ fail = 1;
+ }
+
fclose (e);
}
}
@@ -1306,10 +1348,7 @@ patch_file (file, repository, entries, srcfiles, vers_ts, update_dir,
if (!really_quiet)
{
- if (update_dir[0])
- (void) printf ("P %s/%s\n", update_dir, file);
- else
- (void) printf ("P %s\n", file);
+ write_letter (file, 'P', update_dir);
}
}
else
@@ -1347,10 +1386,17 @@ write_letter (file, letter, update_dir)
{
if (!really_quiet)
{
+ char buf[2];
+ buf[0] = letter;
+ buf[1] = ' ';
+ cvs_output (buf, 2);
if (update_dir[0])
- (void) printf ("%c %s/%s\n", letter, update_dir, file);
- else
- (void) printf ("%c %s\n", letter, file);
+ {
+ cvs_output (update_dir, 0);
+ cvs_output ("/", 1);
+ }
+ cvs_output (file, 0);
+ cvs_output ("\n", 1);
}
return (0);
}
@@ -1447,8 +1493,7 @@ merge_file (file, repository, entries, vers, update_dir)
if (!noexec)
error (0, 0, "conflicts found in %s", user);
- if (!really_quiet)
- (void) printf ("C %s\n", user);
+ write_letter (file, 'C', update_dir);
history_write ('C', update_dir, vers->vn_rcs, file, repository);
@@ -1459,8 +1504,7 @@ merge_file (file, repository, entries, vers, update_dir)
}
else
{
- if (!really_quiet)
- (void) printf ("M %s\n", user);
+ write_letter (file, 'M', update_dir);
history_write ('G', update_dir, vers->vn_rcs, file, repository);
}
return (0);
@@ -1544,9 +1588,20 @@ join_file (file, srcfiles, vers, update_dir, entries)
return;
}
+ /* Fix for bug CVS/193:
+ * Used to dump core if the file had been removed on the current branch.
+ */
+ if (strcmp(vers->vn_user, "0") == 0)
+ {
+ error(0, 0,
+ "file %s has been deleted",
+ file);
+ return;
+ }
+
/* convert the second rev spec, walking branches and dates. */
- rev2 = RCS_getversion (vers->srcfile, jrev2, jdate2, 1);
+ rev2 = RCS_getversion (vers->srcfile, jrev2, jdate2, 1, 0);
if (rev2 == NULL)
{
if (!quiet)
@@ -1598,7 +1653,7 @@ join_file (file, srcfiles, vers, update_dir, entries)
abort();
}
- tst = RCS_gettag (vers->srcfile, rev2, 1);
+ tst = RCS_gettag (vers->srcfile, rev2, 1, 0);
if (tst == NULL)
{
/* this should not be possible. */
@@ -1621,7 +1676,7 @@ join_file (file, srcfiles, vers, update_dir, entries)
/* otherwise, convert the first rev spec, walking branches and
dates. */
- rev1 = RCS_getversion (vers->srcfile, jrev1, jdate1, 1);
+ rev1 = RCS_getversion (vers->srcfile, jrev1, jdate1, 1, 0);
if (rev1 == NULL)
{
if (!quiet) {
@@ -1645,7 +1700,7 @@ join_file (file, srcfiles, vers, update_dir, entries)
/* special handling when two revisions are specified */
if (join_rev1 && join_rev2)
{
- rev = RCS_getversion (vers->srcfile, join_rev2, date_rev2, 1);
+ rev = RCS_getversion (vers->srcfile, join_rev2, date_rev2, 1, 0);
if (rev == NULL)
{
if (!quiet && date_rev2 == NULL)
@@ -1654,7 +1709,7 @@ join_file (file, srcfiles, vers, update_dir, entries)
return;
}
- baserev = RCS_getversion (vers->srcfile, join_rev1, date_rev1, 1);
+ baserev = RCS_getversion (vers->srcfile, join_rev1, date_rev1, 1, 0);
if (baserev == NULL)
{
if (!quiet && date_rev1 == NULL)
@@ -1682,7 +1737,7 @@ join_file (file, srcfiles, vers, update_dir, entries)
}
else
{
- rev = RCS_getversion (vers->srcfile, join_rev1, date_rev1, 1);
+ rev = RCS_getversion (vers->srcfile, join_rev1, date_rev1, 1, 0);
if (rev == NULL)
return;
if (strcmp (rev, vers->vn_user) == 0) /* no merge necessary */
@@ -1723,9 +1778,8 @@ join_file (file, srcfiles, vers, update_dir, entries)
{
int retcode;
/* The file is up to date. Need to check out the current contents. */
- run_setup ("%s%s -q -r%s", Rcsbin, RCS_CO, vers->vn_user);
- run_arg (vers->srcfile->path);
- retcode = run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL);
+ retcode = RCS_checkout (vers->srcfile->path, "", vers->vn_user, NULL,
+ RUN_TTY, 0, 0);
if (retcode != 0)
error (1, retcode == -1 ? errno : 0,
"failed to check out %s file", file);
@@ -1769,7 +1823,17 @@ join_file (file, srcfiles, vers, update_dir, entries)
free (rev1);
free (rev2);
+#ifdef SERVER_SUPPORT
+ /*
+ * If we're in server mode, then we need to re-register the file
+ * even if there were no conflicts (status == 0).
+ * This tells server_updated() to send the modified file back to
+ * the client.
+ */
+ if (status == 1 || (status == 0 && server_active))
+#else
if (status == 1)
+#endif
{
char *cp = 0;
@@ -1791,80 +1855,6 @@ join_file (file, srcfiles, vers, update_dir, entries)
#endif
}
-/*
- * Process the current directory, looking for files not in ILIST and not on
- * the global ignore list for this directory.
- */
-static void
-ignore_files (ilist, update_dir)
- List *ilist;
- char *update_dir;
-{
- DIR *dirp;
- struct dirent *dp;
- struct stat sb;
- char *file;
- char *xdir;
-
- /* we get called with update_dir set to "." sometimes... strip it */
- if (strcmp (update_dir, ".") == 0)
- xdir = "";
- else
- xdir = update_dir;
-
- dirp = opendir (".");
- if (dirp == NULL)
- return;
-
- ign_add_file (CVSDOTIGNORE, 1);
- wrap_add_file (CVSDOTWRAPPER, 1);
-
- while ((dp = readdir (dirp)) != NULL)
- {
- file = dp->d_name;
- if (strcmp (file, ".") == 0 || strcmp (file, "..") == 0)
- continue;
- if (findnode (ilist, file) != NULL)
- continue;
-
- if (
-#ifdef DT_DIR
- dp->d_type != DT_UNKNOWN ||
-#endif
- lstat(file, &sb) != -1)
- {
-
- if (
-#ifdef DT_DIR
- dp->d_type == DT_DIR || dp->d_type == DT_UNKNOWN &&
-#endif
- S_ISDIR(sb.st_mode))
- {
- char temp[PATH_MAX];
-
- (void) sprintf (temp, "%s/%s", file, CVSADM);
- if (isdir (temp))
- continue;
- }
-#ifdef S_ISLNK
- else if (
-#ifdef DT_DIR
- dp->d_type == DT_LNK || dp->d_type == DT_UNKNOWN &&
-#endif
- S_ISLNK(sb.st_mode))
- {
- continue;
- }
-#endif
- }
-
- if (ign_name (file))
- continue;
- (void) write_letter (file, '?', xdir);
- }
- (void) closedir (dirp);
-}
-
int
joining ()
{