diff options
author | Jean-Francois Brousseau <jfb@cvs.openbsd.org> | 2004-07-25 03:18:54 +0000 |
---|---|---|
committer | Jean-Francois Brousseau <jfb@cvs.openbsd.org> | 2004-07-25 03:18:54 +0000 |
commit | 0bc2ac3e967cca4a3f1ebde45b18e9a73d3af118 (patch) | |
tree | 31b7d1aab4689c32bf80f0ba8b4b274b4da59cbe /usr.bin/cvs/entries.c | |
parent | ef47280b946b382c1f6be8bea3f4f9aa17d5bc78 (diff) |
* cleanup the file API with regards to flag handling and
general structure
* implement cvs_ent_close() correctly, fix some memory leaks, and add
cvs_ent_getent() to get a single entry easily
Diffstat (limited to 'usr.bin/cvs/entries.c')
-rw-r--r-- | usr.bin/cvs/entries.c | 86 |
1 files changed, 76 insertions, 10 deletions
diff --git a/usr.bin/cvs/entries.c b/usr.bin/cvs/entries.c index 967373eeb91..40f9db3bdd1 100644 --- a/usr.bin/cvs/entries.c +++ b/usr.bin/cvs/entries.c @@ -1,4 +1,4 @@ -/* $OpenBSD: entries.c,v 1.4 2004/07/14 19:03:00 jfb Exp $ */ +/* $OpenBSD: entries.c,v 1.5 2004/07/25 03:18:53 jfb Exp $ */ /* * Copyright (c) 2004 Jean-Francois Brousseau <jfb@openbsd.org> * All rights reserved. @@ -90,6 +90,8 @@ cvs_ent_open(const char *dir, int flags) (void)fclose(fp); return (NULL); } + memset(ep, 0, sizeof(*ep)); + ep->cef_path = strdup(dir); if (ep->cef_path == NULL) { cvs_log(LP_ERRNO, "failed to copy Entries path"); @@ -125,12 +127,26 @@ cvs_ent_open(const char *dir, int flags) /* * cvs_ent_close() * - * Close the Entries file <ep>. + * Close the Entries file <ep> and free all data. Any reference to entries + * structure within that file become invalid. */ void cvs_ent_close(CVSENTRIES *ep) { + struct cvs_ent *ent; + + if (ep->cef_file != NULL) + (void)fclose(ep); + if (ep->cef_path != NULL) + free(ep->cef_path); + + while (!TAILQ_EMPTY(&(ep->cef_ent))) { + ent = TAILQ_FIRST(&(ep->cef_ent)); + TAILQ_REMOVE(&(ep->cef_ent), ent, ce_list); + cvs_ent_free(ent); + } + free(ep); } @@ -228,12 +244,11 @@ cvs_ent_get(CVSENTRIES *ef, const char *file) struct cvs_ent* cvs_ent_next(CVSENTRIES *ef) { - if (ef->cef_cur == NULL) { + if (ef->cef_cur == NULL) ef->cef_cur = TAILQ_FIRST(&(ef->cef_ent)); - return (ef->cef_cur); - } - - return TAILQ_NEXT(ef->cef_cur, ce_list); + else + ef->cef_cur = TAILQ_NEXT(ef->cef_cur, ce_list); + return (ef->cef_cur); } @@ -256,6 +271,7 @@ cvs_ent_parse(const char *entry) cvs_log(LP_ERRNO, "failed to allocate CVS entry"); return (NULL); } + memset(entp, 0, sizeof(*entp)); entp->ce_rev = rcsnum_alloc(); if (entp->ce_rev == NULL) { @@ -265,14 +281,13 @@ cvs_ent_parse(const char *entry) entp->ce_line = strdup(entry); if (entp->ce_line == NULL) { - free(entp); + cvs_ent_free(entp); return (NULL); } entp->ce_buf = strdup(entry); if (entp->ce_buf == NULL) { - free(entp->ce_line); - free(entp); + cvs_ent_free(entp); return (NULL); } sp = entp->ce_buf; @@ -310,3 +325,54 @@ cvs_ent_parse(const char *entry) return (entp); } + + +/* + * cvs_ent_free() + * + * Free a single CVS entries structure. + */ + +void +cvs_ent_free(struct cvs_ent *ent) +{ + if (ent->ce_rev != NULL) + rcsnum_free(ent->ce_rev); + if (ent->ce_line != NULL) + free(ent->ce_line); + if (ent->ce_buf != NULL) + free(ent->ce_buf); + free(ent); +} + + +/* + * cvs_ent_getent() + * + * Get a single entry from the CVS/Entries file of the basename portion of + * path <path> and return that entry. That entry must later be freed using + * cvs_ent_free(). + */ + +struct cvs_ent* +cvs_ent_getent(const char *path) +{ + char base[MAXPATHLEN], file[MAXPATHLEN]; + CVSENTRIES *entf; + struct cvs_ent *ep; + + cvs_splitpath(path, base, sizeof(base), file, sizeof(file)); + + entf = cvs_ent_open(base, O_RDONLY); + if (entf == NULL) + return (NULL); + + ep = cvs_ent_get(entf, file); + if (ep != NULL) { + /* take it out of the queue so it doesn't get freed */ + TAILQ_REMOVE(&(entf->cef_ent), ep, ce_list); + } + + cvs_ent_close(entf); + return (ep); +} |