diff options
author | Jean-Francois Brousseau <jfb@cvs.openbsd.org> | 2004-07-27 12:01:59 +0000 |
---|---|---|
committer | Jean-Francois Brousseau <jfb@cvs.openbsd.org> | 2004-07-27 12:01:59 +0000 |
commit | 1722c840e24772e94215ffc22d75bd28068c9d7d (patch) | |
tree | 234a3c925990b90dabfb37053d606515114faae3 | |
parent | 51b9336fbbc2c242550ccc4ecb81a2b8e42d7a72 (diff) |
* create cvs_file_alloc() to keep one copy of the file allocation code
and reuse it
* add cvs_file_create() to explicitly create a file or directory
* add cvs_mkadmin() to fill the administrative files for a CVS directory
-rw-r--r-- | usr.bin/cvs/cvs.h | 7 | ||||
-rw-r--r-- | usr.bin/cvs/file.c | 181 | ||||
-rw-r--r-- | usr.bin/cvs/util.c | 76 |
3 files changed, 166 insertions, 98 deletions
diff --git a/usr.bin/cvs/cvs.h b/usr.bin/cvs/cvs.h index 9bab20ff59a..4694917354e 100644 --- a/usr.bin/cvs/cvs.h +++ b/usr.bin/cvs/cvs.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cvs.h,v 1.9 2004/07/26 15:56:43 jfb Exp $ */ +/* $OpenBSD: cvs.h,v 1.10 2004/07/27 12:01:58 jfb Exp $ */ /* * Copyright (c) 2004 Jean-Francois Brousseau <jfb@openbsd.org> * All rights reserved. @@ -213,6 +213,7 @@ #define CVS_PATH_STATICENTRIES CVS_PATH_CVSDIR "/Entries.Static" #define CVS_PATH_LOGENTRIES CVS_PATH_CVSDIR "/Entries.Log" #define CVS_PATH_ROOTSPEC CVS_PATH_CVSDIR "/Root" +#define CVS_PATH_REPOSITORY CVS_PATH_CVSDIR "/Repository" struct cvs_file; @@ -244,6 +245,7 @@ struct cvsroot { #define CF_RECURSE 0x04 /* recurse on directory operations */ #define CF_SORT 0x08 /* all files are sorted alphabetically */ #define CF_KNOWN 0x10 /* only recurse in directories known to CVS */ +#define CF_CREATE 0x20 /* create if file does not exist */ /* @@ -402,7 +404,7 @@ struct cvsroot* cvsroot_get (const char *); int cvs_file_init (void); int cvs_file_ignore (const char *); int cvs_file_chkign (const char *); -char** cvs_file_getv (const char *, int *, int); +CVSFILE* cvs_file_create (const char *, u_int, mode_t); CVSFILE* cvs_file_get (const char *, int); void cvs_file_free (struct cvs_file *); int cvs_file_examine (CVSFILE *, int (*)(CVSFILE *, void *), void *); @@ -433,6 +435,7 @@ int cvs_readrepo (const char *, char *, size_t); int cvs_splitpath (const char *, char *, size_t, char *, size_t); int cvs_modetostr (mode_t, char *, size_t); int cvs_strtomode (const char *, mode_t *); +int cvs_mkadmin (struct cvs_file *, mode_t); int cvs_cksum (const char *, char *, size_t); int cvs_exec (int, char **, int []); int cvs_getargv (const char *, char **, int); diff --git a/usr.bin/cvs/file.c b/usr.bin/cvs/file.c index 2bd5864a340..73f87bac996 100644 --- a/usr.bin/cvs/file.c +++ b/usr.bin/cvs/file.c @@ -1,4 +1,4 @@ -/* $OpenBSD: file.c,v 1.5 2004/07/26 15:58:01 jfb Exp $ */ +/* $OpenBSD: file.c,v 1.6 2004/07/27 12:01:58 jfb Exp $ */ /* * Copyright (c) 2004 Jean-Francois Brousseau <jfb@openbsd.org> * All rights reserved. @@ -93,10 +93,11 @@ static RCSNUM *cvs_addedrev; TAILQ_HEAD(, cvs_ignpat) cvs_ign_pats; -static struct cvs_dir* cvs_file_getdir (struct cvs_file *, int); -static void cvs_file_freedir (struct cvs_dir *); -static int cvs_file_sort (struct cvs_flist *); -static int cvs_file_cmp (const void *, const void *); +static int cvs_file_getdir (struct cvs_file *, int); +static void cvs_file_freedir (struct cvs_dir *); +static int cvs_file_sort (struct cvs_flist *); +static int cvs_file_cmp (const void *, const void *); +static CVSFILE* cvs_file_alloc (const char *, u_int); @@ -214,64 +215,38 @@ cvs_file_chkign(const char *file) /* - * cvs_file_getv() + * cvs_file_create() * - * Get a vector of all the files found in the directory <dir> and not - * matching any of the ignore patterns. The number of files found is - * returned in <nfiles>. - * Returns a pointer to a dynamically-allocated string vector on success, - * or NULL on failure. The returned vector should be freed with - * cvs_freeargv(). + * Create a new file whose path is specified in <path> and of type <type>. */ -char** -cvs_file_getv(const char *dir, int *nfiles, int recurse) +CVSFILE* +cvs_file_create(const char *path, u_int type, mode_t mode) { - int nf, ret, fd; - long base; - void *dp, *ep, *tmp; - char fbuf[1024], **fvec; - struct dirent *ent; - - *nfiles = 0; - fvec = NULL; + int fd; + CVSFILE *cfp; - fd = open(dir, O_RDONLY); - if (fd == -1) { - cvs_log(LP_ERRNO, "failed to open `%s'", dir); - return (NULL); - } - ret = getdirentries(fd, fbuf, sizeof(fbuf), &base); - if (ret == -1) { - cvs_log(LP_ERRNO, "failed to get directory entries"); - (void)close(fd); + cfp = cvs_file_alloc(path, type); + if (cfp == NULL) return (NULL); - } - - dp = fbuf; - ep = fbuf + (size_t)ret; - while (dp < ep) { - ent = (struct dirent *)dp; - dp += ent->d_reclen; - - if (cvs_file_chkign(ent->d_name)) - continue; + cfp->cf_type = type; - tmp = realloc(fvec, (*nfiles + 1) * sizeof(char *)); - if (tmp == NULL) { - cvs_log(LP_ERRNO, "failed to reallocate file vector"); - (void)close(fd); - free(fvec); + if (type == DT_DIR) { + if (mkdir(path, mode) == -1) { + cvs_file_free(cfp); return (NULL); } - fvec[++(*nfiles)] = strdup(ent->d_name); - - *nfiles++; + } + else { + fd = open(path, O_WRONLY|O_CREAT|O_EXCL, mode); + if (fd == -1) { + cvs_file_free(cfp); + return (NULL); + } + (void)close(fd); } - (void)close(fd); - - return (fvec); + return (cfp); } @@ -304,8 +279,6 @@ cvs_file_get(const char *path, int flags) struct cvs_file *cfp; struct cvs_ent *ent; - printf("cvs_file_get(%s)\n", path); - if (strcmp(path, ".") == 0) cwd = 1; else @@ -316,12 +289,11 @@ cvs_file_get(const char *path, int flags) return (NULL); } - cfp = (struct cvs_file *)malloc(sizeof(*cfp)); + cfp = cvs_file_alloc(path, IFTODT(st.st_mode)); if (cfp == NULL) { cvs_log(LP_ERRNO, "failed to allocate CVS file data"); return (NULL); } - memset(cfp, 0, sizeof(*cfp)); ent = cvs_ent_getent(path); if (ent == NULL) @@ -348,30 +320,16 @@ cvs_file_get(const char *path, int flags) cvs_ent_free(ent); } - cfp->cf_path = strdup(path); - if (cfp->cf_path == NULL) { - cvs_log(LP_ERRNO, "failed to allocate file path"); - free(cfp); - return (NULL); - } - - cfp->cf_name = strrchr(cfp->cf_path, '/'); - if (cfp->cf_name == NULL) - cfp->cf_name = cfp->cf_path; - else - cfp->cf_name++; - /* convert from stat mode to dirent values */ cfp->cf_type = IFTODT(st.st_mode); if ((cfp->cf_type == DT_DIR) && ((flags & CF_RECURSE) || cwd)) { - if ((flags & CF_KNOWN) && (cfp->cf_cvstat == CVS_FST_UNKNOWN)) + if ((flags & CF_KNOWN) && (cfp->cf_cvstat == CVS_FST_UNKNOWN)) { + free(cfp->cf_ddat); cfp->cf_ddat = NULL; - else { - cfp->cf_ddat = cvs_file_getdir(cfp, flags); - if (cfp->cf_ddat == NULL) { - cvs_file_free(cfp); - return (NULL); - } + } + else if (cvs_file_getdir(cfp, flags) < 0) { + cvs_file_free(cfp); + return (NULL); } } @@ -396,7 +354,7 @@ cvs_file_get(const char *path, int flags) * Get a cvs directory structure for the directory whose path is <dir>. */ -static struct cvs_dir* +static int cvs_file_getdir(struct cvs_file *cf, int flags) { int nf, ret, fd; @@ -407,40 +365,32 @@ cvs_file_getdir(struct cvs_file *cf, int flags) struct cvs_file *cfp; struct cvs_dir *cdp; - cdp = (struct cvs_dir *)malloc(sizeof(*cdp)); - if (cdp == NULL) { - cvs_log(LP_ERRNO, "failed to allocate dir"); - return (NULL); - } - memset(cdp, 0, sizeof(*cdp)); - LIST_INIT(&(cdp->cd_files)); - if (cvs_readrepo(cf->cf_path, pbuf, sizeof(pbuf)) == 0) { cdp->cd_repo = strdup(pbuf); if (cdp->cd_repo == NULL) { free(cdp); - return (NULL); + return (-1); } } cdp->cd_root = cvsroot_get(cf->cf_path); if (cdp->cd_root == NULL) { cvs_file_freedir(cdp); - return (NULL); + return (-1); } fd = open(cf->cf_path, O_RDONLY); if (fd == -1) { cvs_log(LP_ERRNO, "failed to open `%s'", cf->cf_path); cvs_file_freedir(cdp); - return (NULL); + return (-1); } ret = getdirentries(fd, fbuf, sizeof(fbuf), &base); if (ret == -1) { cvs_log(LP_ERRNO, "failed to get directory entries"); (void)close(fd); cvs_file_freedir(cdp); - return (NULL); + return (-1); } dp = fbuf; @@ -464,8 +414,9 @@ cvs_file_getdir(struct cvs_file *cf, int flags) cvs_file_sort(&(cdp->cd_files)); (void)close(fd); + cf->cf_ddat = cdp; - return (cdp); + return (0); } @@ -591,3 +542,53 @@ cvs_file_cmp(const void *f1, const void *f2) cf2 = *(struct cvs_file **)f2; return strcmp(cf1->cf_name, cf2->cf_name); } + + +CVSFILE* +cvs_file_alloc(const char *path, u_int type) +{ + size_t len; + char pbuf[MAXPATHLEN]; + CVSFILE *cfp; + struct cvs_dir *ddat; + + cfp = (struct cvs_file *)malloc(sizeof(*cfp)); + if (cfp == NULL) { + cvs_log(LP_ERRNO, "failed to allocate CVS file data"); + return (NULL); + } + memset(cfp, 0, sizeof(*cfp)); + + /* ditch trailing slashes */ + strlcpy(pbuf, path, sizeof(pbuf)); + len = strlen(pbuf); + while (pbuf[len - 1] == '/') + pbuf[--len] = '\0'; + + cfp->cf_path = strdup(pbuf); + if (cfp->cf_path == NULL) { + free(cfp); + return (NULL); + } + + cfp->cf_name = strrchr(cfp->cf_path, '/'); + if (cfp->cf_name == NULL) + cfp->cf_name = cfp->cf_path; + else + cfp->cf_name++; + + cfp->cf_type = type; + cfp->cf_cvstat = CVS_FST_UNKNOWN; + + if (type == DT_DIR) { + ddat = (struct cvs_dir *)malloc(sizeof(*ddat)); + if (ddat == NULL) { + cvs_file_free(cfp); + return (NULL); + } + memset(ddat, 0, sizeof(*ddat)); + LIST_INIT(&(ddat->cd_files)); + cfp->cf_ddat = ddat; + } + return (cfp); +} diff --git a/usr.bin/cvs/util.c b/usr.bin/cvs/util.c index f0c579bdebf..0ae827dad5c 100644 --- a/usr.bin/cvs/util.c +++ b/usr.bin/cvs/util.c @@ -1,4 +1,4 @@ -/* $OpenBSD: util.c,v 1.1 2004/07/13 22:02:40 jfb Exp $ */ +/* $OpenBSD: util.c,v 1.2 2004/07/27 12:01:58 jfb Exp $ */ /* * Copyright (c) 2004 Jean-Francois Brousseau <jfb@openbsd.org> * All rights reserved. @@ -29,6 +29,7 @@ #include <md5.h> #include <errno.h> +#include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> @@ -94,7 +95,6 @@ cvs_readrepo(const char *dir, char *dst, size_t len) fp = fopen(repo_path, "r"); if (fp == NULL) { - cvs_log(LP_ERRNO, "failed to open `%s'", repo_path); return (-1); } @@ -111,7 +111,6 @@ cvs_readrepo(const char *dir, char *dst, size_t len) dst[--dlen] = '\0'; (void)fclose(fp); - return (0); } @@ -130,7 +129,7 @@ cvs_readrepo(const char *dir, char *dst, size_t len) int cvs_strtomode(const char *str, mode_t *mode) { - int type; + char type; mode_t m; char buf[32], ms[4], *sp, *ep; @@ -142,9 +141,9 @@ cvs_strtomode(const char *str, mode_t *mode) for (sp = buf; ep != NULL; sp = ep + 1) { ep = strchr(sp, ','); if (ep != NULL) - *(ep++) = '\0'; + *ep = '\0'; - if (sscanf(sp, "%c=%3s", (char *)&type, ms) != 2) { + if (sscanf(sp, "%c=%3s", &type, ms) != 2) { cvs_log(LP_WARN, "failed to scan mode string `%s'", sp); continue; } @@ -384,3 +383,68 @@ cvs_freeargv(char **argv, int argc) for (i = 0; i < argc; i++) free(argv[i]); } + + +/* + * cvs_mkadmin() + * + * Create the CVS administrative files within the directory <cdir>. + * Returns 0 on success, or -1 on failure. + */ + +int +cvs_mkadmin(struct cvs_file *cdir, mode_t mode) +{ + char path[MAXPATHLEN]; + FILE *fp; + CVSENTRIES *ef; + struct cvsroot *root; + + snprintf(path, sizeof(path), "%s/" CVS_PATH_CVSDIR, cdir->cf_path); + if (mkdir(path, mode) == -1) { + cvs_log(LP_ERRNO, "failed to create directory %s", path); + return (-1); + } + + ef = cvs_ent_open(cdir->cf_path, O_WRONLY); + (void)cvs_ent_close(ef); + + snprintf(path, sizeof(path), "%s/" CVS_PATH_ROOTSPEC, cdir->cf_path); + fp = fopen(path, "w"); + if (fp == NULL) { + cvs_log(LP_ERRNO, "failed to open %s", path); + return (-1); + } + root = cdir->cf_ddat->cd_root; + if (root->cr_user != NULL) { + fprintf(fp, "%s", root->cr_user); + if (root->cr_pass != NULL) + fprintf(fp, ":%s", root->cr_pass); + if (root->cr_host != NULL) + putc('@', fp); + } + + if (root->cr_host != NULL) { + fprintf(fp, "%s", root->cr_host); + if (root->cr_dir != NULL) + putc(':', fp); + } + if (root->cr_dir) + fprintf(fp, "%s", root->cr_dir); + (void)fclose(fp); + + if (cdir->cf_ddat->cd_repo != NULL) { + snprintf(path, sizeof(path), "%s/" CVS_PATH_REPOSITORY, + cdir->cf_path); + fp = fopen(path, "w"); + if (fp == NULL) { + cvs_log(LP_ERRNO, "failed to open %s", path); + return (-1); + } + fprintf(fp, "%s", cdir->cf_ddat->cd_repo); + (void)fclose(fp); + } + + + return (0); +} |