summaryrefslogtreecommitdiff
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
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
-rw-r--r--usr.bin/cvs/cvs.h7
-rw-r--r--usr.bin/cvs/file.c181
-rw-r--r--usr.bin/cvs/util.c76
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);
+}