summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoris Vink <joris@cvs.openbsd.org>2005-12-03 15:02:56 +0000
committerJoris Vink <joris@cvs.openbsd.org>2005-12-03 15:02:56 +0000
commit3d78890027fb19ead4c3ba84f930b0a1bd219f96 (patch)
treeb32dfb0d17c783898842bb592c8206c311adf439
parentadafd44db90a04c4df796b4e345001a39a835287 (diff)
- teach opencvs about Entries.Log and what to do with it
it it exists in the CVS admin dir. - when writing the Entries file write it to Entries.Backup first and then rename it to Entries when the writing was successfull.
-rw-r--r--usr.bin/cvs/cvs.h4
-rw-r--r--usr.bin/cvs/entries.c68
2 files changed, 66 insertions, 6 deletions
diff --git a/usr.bin/cvs/cvs.h b/usr.bin/cvs/cvs.h
index 9e47b394016..5860bb596fe 100644
--- a/usr.bin/cvs/cvs.h
+++ b/usr.bin/cvs/cvs.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: cvs.h,v 1.88 2005/12/03 01:02:08 joris Exp $ */
+/* $OpenBSD: cvs.h,v 1.89 2005/12/03 15:02:54 joris Exp $ */
/*
* Copyright (c) 2004 Jean-Francois Brousseau <jfb@openbsd.org>
* All rights reserved.
@@ -137,6 +137,7 @@
#define CVS_PATH_ENTRIES CVS_PATH_CVSDIR "/Entries"
#define CVS_PATH_STATICENTRIES CVS_PATH_CVSDIR "/Entries.Static"
#define CVS_PATH_LOGENTRIES CVS_PATH_CVSDIR "/Entries.Log"
+#define CVS_PATH_BACKUPENTRIES CVS_PATH_CVSDIR "/Entries.Backup"
#define CVS_PATH_ROOTSPEC CVS_PATH_CVSDIR "/Root"
#define CVS_PATH_REPOSITORY CVS_PATH_CVSDIR "/Repository"
#define CVS_PATH_TAG CVS_PATH_CVSDIR "/Tag"
@@ -278,6 +279,7 @@ struct cvs_ent {
typedef struct cvs_entries {
char *cef_path;
+ char *cef_bpath;
u_int cef_flags;
TAILQ_HEAD(cvsentrieshead, cvs_ent) cef_ent;
diff --git a/usr.bin/cvs/entries.c b/usr.bin/cvs/entries.c
index e17ff7d92a3..1ece81f0864 100644
--- a/usr.bin/cvs/entries.c
+++ b/usr.bin/cvs/entries.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: entries.c,v 1.51 2005/12/03 01:02:08 joris Exp $ */
+/* $OpenBSD: entries.c,v 1.52 2005/12/03 15:02:55 joris Exp $ */
/*
* Copyright (c) 2004 Jean-Francois Brousseau <jfb@openbsd.org>
* All rights reserved.
@@ -53,6 +53,7 @@ cvs_ent_open(const char *dir, int flags)
{
size_t len;
int exists, nodir;
+ char bpath[MAXPATHLEN], *p;
char cdpath[MAXPATHLEN], ebuf[CVS_ENT_MAXLINELEN], entpath[MAXPATHLEN];
char mode[4];
FILE *fp;
@@ -77,6 +78,10 @@ cvs_ent_open(const char *dir, int flags)
if ((stat(cdpath, &st) == 0) && S_ISDIR(st.st_mode))
nodir = 0; /* the CVS/ directory does exist */
+ len = cvs_path_cat(dir, CVS_PATH_BACKUPENTRIES, bpath, sizeof(bpath));
+ if (len >= sizeof(entpath))
+ return (NULL);
+
len = cvs_path_cat(dir, CVS_PATH_ENTRIES, entpath, sizeof(entpath));
if (len >= sizeof(entpath))
return (NULL);
@@ -123,6 +128,13 @@ cvs_ent_open(const char *dir, int flags)
return (NULL);
}
+ ep->cef_bpath = strdup(bpath);
+ if (ep->cef_bpath == NULL) {
+ cvs_ent_close(ep);
+ (void)fclose(fp);
+ return (NULL);
+ }
+
ep->cef_cur = NULL;
TAILQ_INIT(&(ep->cef_ent));
@@ -138,6 +150,7 @@ cvs_ent_open(const char *dir, int flags)
TAILQ_INSERT_TAIL(&(ep->cef_ent), ent, ce_list);
}
+
if (ferror(fp)) {
cvs_log(LP_ERRNO, "read error on %s", entpath);
(void)fclose(fp);
@@ -151,8 +164,43 @@ cvs_ent_open(const char *dir, int flags)
(void)fclose(fp);
- if (exists == 1)
- ep->cef_flags |= CVS_ENTF_SYNC;
+ /*
+ * look for Entries.Log and add merge it together with our
+ * list of things.
+ */
+ len = cvs_path_cat(dir, CVS_PATH_LOGENTRIES, entpath, sizeof(entpath));
+ if (len >= sizeof(entpath)) {
+ cvs_ent_close(ep);
+ return (NULL);
+ }
+
+ fp = fopen(entpath, "r");
+ if (fp != NULL) {
+ while (fgets(ebuf, (int)sizeof(ebuf), fp) != NULL) {
+ len = strlen(ebuf);
+ if ((len > 0) && (ebuf[len - 1] == '\n'))
+ ebuf[--len] = '\0';
+
+ p = &ebuf[2];
+ ent = cvs_ent_parse(p);
+ if (ent == NULL)
+ continue;
+
+ if (ebuf[0] == 'A')
+ cvs_ent_add(ep, ent);
+ else if (ebuf[0] == 'R')
+ cvs_ent_remove(ep, ent->ce_name, 0);
+ }
+ (void)fclose(fp);
+
+ /* always un-synced here, because we
+ * just added or removed entries.
+ */
+ ep->cef_flags &= ~CVS_ENTF_SYNC;
+ } else {
+ if (exists == 1)
+ ep->cef_flags |= CVS_ENTF_SYNC;
+ }
return (ep);
}
@@ -178,6 +226,9 @@ cvs_ent_close(CVSENTRIES *ep)
if (ep->cef_path != NULL)
free(ep->cef_path);
+ if (ep->cef_bpath != NULL)
+ free(ep->cef_bpath);
+
while (!TAILQ_EMPTY(&(ep->cef_ent))) {
ent = TAILQ_FIRST(&(ep->cef_ent));
TAILQ_REMOVE(&(ep->cef_ent), ent, ce_list);
@@ -442,8 +493,8 @@ cvs_ent_write(CVSENTRIES *ef)
if (ef->cef_flags & CVS_ENTF_SYNC)
return (0);
- if ((fp = fopen(ef->cef_path, "w")) == NULL) {
- cvs_log(LP_ERRNO, "failed to open Entries `%s'", ef->cef_path);
+ if ((fp = fopen(ef->cef_bpath, "w")) == NULL) {
+ cvs_log(LP_ERRNO, "failed to open Entries `%s'", ef->cef_bpath);
return (-1);
}
@@ -488,5 +539,12 @@ cvs_ent_write(CVSENTRIES *ef)
ef->cef_flags |= CVS_ENTF_SYNC;
fclose(fp);
+
+ /* rename Entries.Backup to Entries */
+ cvs_rename(ef->cef_bpath, ef->cef_path);
+
+ /* remove Entries.Log */
+ cvs_unlink(CVS_PATH_LOGENTRIES);
+
return (0);
}