diff options
author | Joris Vink <joris@cvs.openbsd.org> | 2005-12-03 15:02:56 +0000 |
---|---|---|
committer | Joris Vink <joris@cvs.openbsd.org> | 2005-12-03 15:02:56 +0000 |
commit | 3d78890027fb19ead4c3ba84f930b0a1bd219f96 (patch) | |
tree | b32dfb0d17c783898842bb592c8206c311adf439 | |
parent | adafd44db90a04c4df796b4e345001a39a835287 (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.h | 4 | ||||
-rw-r--r-- | usr.bin/cvs/entries.c | 68 |
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); } |