summaryrefslogtreecommitdiff
path: root/usr.bin/cvs/file.c
diff options
context:
space:
mode:
authorJean-Francois Brousseau <jfb@cvs.openbsd.org>2004-07-27 12:01:59 +0000
committerJean-Francois Brousseau <jfb@cvs.openbsd.org>2004-07-27 12:01:59 +0000
commit1722c840e24772e94215ffc22d75bd28068c9d7d (patch)
tree234a3c925990b90dabfb37053d606515114faae3 /usr.bin/cvs/file.c
parent51b9336fbbc2c242550ccc4ecb81a2b8e42d7a72 (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
Diffstat (limited to 'usr.bin/cvs/file.c')
-rw-r--r--usr.bin/cvs/file.c181
1 files changed, 91 insertions, 90 deletions
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);
+}