version 1.5, 2004/07/26 15:58:01 |
version 1.6, 2004/07/27 12:01:58 |
|
|
TAILQ_HEAD(, cvs_ignpat) cvs_ign_pats; |
TAILQ_HEAD(, cvs_ignpat) cvs_ign_pats; |
|
|
|
|
static struct cvs_dir* cvs_file_getdir (struct cvs_file *, int); |
static int cvs_file_getdir (struct cvs_file *, int); |
static void cvs_file_freedir (struct cvs_dir *); |
static void cvs_file_freedir (struct cvs_dir *); |
static int cvs_file_sort (struct cvs_flist *); |
static int cvs_file_sort (struct cvs_flist *); |
static int cvs_file_cmp (const void *, const void *); |
static int cvs_file_cmp (const void *, const void *); |
|
static CVSFILE* cvs_file_alloc (const char *, u_int); |
|
|
|
|
|
|
|
|
|
|
|
|
/* |
/* |
* cvs_file_getv() |
* cvs_file_create() |
* |
* |
* Get a vector of all the files found in the directory <dir> and not |
* Create a new file whose path is specified in <path> and of type <type>. |
* 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(). |
|
*/ |
*/ |
|
|
char** |
CVSFILE* |
cvs_file_getv(const char *dir, int *nfiles, int recurse) |
cvs_file_create(const char *path, u_int type, mode_t mode) |
{ |
{ |
int nf, ret, fd; |
int fd; |
long base; |
CVSFILE *cfp; |
void *dp, *ep, *tmp; |
|
char fbuf[1024], **fvec; |
|
struct dirent *ent; |
|
|
|
*nfiles = 0; |
cfp = cvs_file_alloc(path, type); |
fvec = NULL; |
if (cfp == NULL) |
|
|
fd = open(dir, O_RDONLY); |
|
if (fd == -1) { |
|
cvs_log(LP_ERRNO, "failed to open `%s'", dir); |
|
return (NULL); |
return (NULL); |
} |
cfp->cf_type = type; |
ret = getdirentries(fd, fbuf, sizeof(fbuf), &base); |
|
if (ret == -1) { |
|
cvs_log(LP_ERRNO, "failed to get directory entries"); |
|
(void)close(fd); |
|
return (NULL); |
|
} |
|
|
|
dp = fbuf; |
if (type == DT_DIR) { |
ep = fbuf + (size_t)ret; |
if (mkdir(path, mode) == -1) { |
while (dp < ep) { |
cvs_file_free(cfp); |
ent = (struct dirent *)dp; |
|
dp += ent->d_reclen; |
|
|
|
if (cvs_file_chkign(ent->d_name)) |
|
continue; |
|
|
|
tmp = realloc(fvec, (*nfiles + 1) * sizeof(char *)); |
|
if (tmp == NULL) { |
|
cvs_log(LP_ERRNO, "failed to reallocate file vector"); |
|
(void)close(fd); |
|
free(fvec); |
|
return (NULL); |
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 (cfp); |
|
|
return (fvec); |
|
} |
} |
|
|
|
|
|
|
struct cvs_file *cfp; |
struct cvs_file *cfp; |
struct cvs_ent *ent; |
struct cvs_ent *ent; |
|
|
printf("cvs_file_get(%s)\n", path); |
|
|
|
if (strcmp(path, ".") == 0) |
if (strcmp(path, ".") == 0) |
cwd = 1; |
cwd = 1; |
else |
else |
|
|
return (NULL); |
return (NULL); |
} |
} |
|
|
cfp = (struct cvs_file *)malloc(sizeof(*cfp)); |
cfp = cvs_file_alloc(path, IFTODT(st.st_mode)); |
if (cfp == NULL) { |
if (cfp == NULL) { |
cvs_log(LP_ERRNO, "failed to allocate CVS file data"); |
cvs_log(LP_ERRNO, "failed to allocate CVS file data"); |
return (NULL); |
return (NULL); |
} |
} |
memset(cfp, 0, sizeof(*cfp)); |
|
|
|
ent = cvs_ent_getent(path); |
ent = cvs_ent_getent(path); |
if (ent == NULL) |
if (ent == NULL) |
|
|
cvs_ent_free(ent); |
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 */ |
/* convert from stat mode to dirent values */ |
cfp->cf_type = IFTODT(st.st_mode); |
cfp->cf_type = IFTODT(st.st_mode); |
if ((cfp->cf_type == DT_DIR) && ((flags & CF_RECURSE) || cwd)) { |
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; |
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); |
|
} |
} |
} |
|
|
if (flags & CF_STAT) { |
if (flags & CF_STAT) { |
|
|
* Get a cvs directory structure for the directory whose path is <dir>. |
* 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) |
cvs_file_getdir(struct cvs_file *cf, int flags) |
{ |
{ |
int nf, ret, fd; |
int nf, ret, fd; |
|
|
struct cvs_file *cfp; |
struct cvs_file *cfp; |
struct cvs_dir *cdp; |
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) { |
if (cvs_readrepo(cf->cf_path, pbuf, sizeof(pbuf)) == 0) { |
cdp->cd_repo = strdup(pbuf); |
cdp->cd_repo = strdup(pbuf); |
if (cdp->cd_repo == NULL) { |
if (cdp->cd_repo == NULL) { |
free(cdp); |
free(cdp); |
return (NULL); |
return (-1); |
} |
} |
} |
} |
|
|
cdp->cd_root = cvsroot_get(cf->cf_path); |
cdp->cd_root = cvsroot_get(cf->cf_path); |
if (cdp->cd_root == NULL) { |
if (cdp->cd_root == NULL) { |
cvs_file_freedir(cdp); |
cvs_file_freedir(cdp); |
return (NULL); |
return (-1); |
} |
} |
|
|
fd = open(cf->cf_path, O_RDONLY); |
fd = open(cf->cf_path, O_RDONLY); |
if (fd == -1) { |
if (fd == -1) { |
cvs_log(LP_ERRNO, "failed to open `%s'", cf->cf_path); |
cvs_log(LP_ERRNO, "failed to open `%s'", cf->cf_path); |
cvs_file_freedir(cdp); |
cvs_file_freedir(cdp); |
return (NULL); |
return (-1); |
} |
} |
ret = getdirentries(fd, fbuf, sizeof(fbuf), &base); |
ret = getdirentries(fd, fbuf, sizeof(fbuf), &base); |
if (ret == -1) { |
if (ret == -1) { |
cvs_log(LP_ERRNO, "failed to get directory entries"); |
cvs_log(LP_ERRNO, "failed to get directory entries"); |
(void)close(fd); |
(void)close(fd); |
cvs_file_freedir(cdp); |
cvs_file_freedir(cdp); |
return (NULL); |
return (-1); |
} |
} |
|
|
dp = fbuf; |
dp = fbuf; |
|
|
cvs_file_sort(&(cdp->cd_files)); |
cvs_file_sort(&(cdp->cd_files)); |
|
|
(void)close(fd); |
(void)close(fd); |
|
cf->cf_ddat = cdp; |
|
|
return (cdp); |
return (0); |
} |
} |
|
|
|
|
|
|
cf1 = *(struct cvs_file **)f1; |
cf1 = *(struct cvs_file **)f1; |
cf2 = *(struct cvs_file **)f2; |
cf2 = *(struct cvs_file **)f2; |
return strcmp(cf1->cf_name, cf2->cf_name); |
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); |
} |
} |