return (0);
ret = 0; done: if (entfile != NULL) cvs_ent_close(entfile);  return (ret);
cvs_file_getdir(CVSFILE *cf, int flags, char *path, int (*cb)(CVSFILE *, void *), void *arg){	int l;	int check_entry;	u_int ndirs, nfiles;	char *cur, *np;	char pbuf[MAXPATHLEN], fpath[MAXPATHLEN];	struct dirent *ent;	CVSFILE *cfp;	struct cvs_ent *cvsent;	struct cvs_flist dirs;	DIR *dirp;	CVSENTRIES *entfile;	check_entry = 1;	ndirs = nfiles = 0;	SIMPLEQ_INIT(&dirs);	cvs_file_getpath(cf, fpath, sizeof(fpath));	entfile = cvs_ent_open(fpath, O_RDONLY);	cf->cf_root = cvsroot_get(fpath);	if (cf->cf_root == NULL)		return (-1);	cur = np = NULL;	if (path != NULL) {		cur = strchr(path, '/');		if (cur != NULL) {			*cur = '\0';			np = cur + 1;			if (np != NULL && *np == '\0')				np = NULL;		}	}	if ((flags & CF_KNOWN) && (cf->cf_cvstat == CVS_FST_UNKNOWN))		return (0);	/* callback for the directory entry */	if (cb != NULL) {		if (cb(cf, arg) != CVS_EX_OK)			return (-1);	}	dirp = opendir(fpath);	if (dirp == NULL) {		cvs_log(LP_ERRNO, "failed to open directory %s", fpath);		return (-1);	}	while ((ent = readdir(dirp)) != NULL) {		if ((flags & CF_IGNORE) && cvs_file_chkign(ent->d_name))			continue;		if ((flags & CF_NOSYMS) && (ent->d_type == DT_LNK))			continue;		if (!(flags & CF_RECURSE) && (ent->d_type == DT_DIR)) {			if (entfile != NULL)				(void)cvs_ent_remove(entfile,				    ent->d_name);			continue;		}		if ((ent->d_type != DT_DIR) && (flags & CF_NOFILES))			continue;		if (path != NULL) {			if (strcmp(path, ent->d_name))				continue;		}		l = snprintf(pbuf, sizeof(pbuf), "%s/%s", fpath,		    ent->d_name);		if (l == -1 || l >= (int)sizeof(pbuf)) {			errno = ENAMETOOLONG;			cvs_log(LP_ERRNO, "%s", pbuf);			closedir(dirp);			return (-1);		}		cfp = cvs_file_find(cf, ent->d_name);		if (cfp == NULL) {			if (entfile != NULL)				cvsent = cvs_ent_get(entfile, ent->d_name);			else				cvsent = NULL;			cfp = cvs_file_lget(pbuf, flags, cf, cvsent);			if (cfp == NULL) {				closedir(dirp);				return (-1);			}			if (entfile != NULL)				cvs_ent_remove(entfile, cfp->cf_name);			if (cfp->cf_type != DT_DIR) {				SIMPLEQ_INSERT_TAIL(&(cf->cf_files), cfp,			    	    cf_list);				nfiles++;			}		} else {			cfp->cf_flags |= CVS_GDIR_IGNORE;		}		if (cfp->cf_type == DT_DIR) {			ndirs++;			SIMPLEQ_INSERT_TAIL(&dirs, cfp, cf_list);		} else {			/* callback for the file */			if (cb != NULL) {				if (cb(cfp, arg) != CVS_EX_OK) {					closedir(dirp);					return (-1);				}			}		}		if (path != NULL) {			check_entry = 0;			break;		}	}	closedir(dirp);	if (entfile != NULL && check_entry) {		while ((cvsent = cvs_ent_next(entfile)) != NULL) {			if (path != NULL) {				if (strcmp(cvsent->ce_name, path))					continue;			}			l = snprintf(pbuf, sizeof(pbuf), "%s/%s", fpath,			    cvsent->ce_name);			if (l == -1 || l >= (int)sizeof(pbuf)) {				errno = ENAMETOOLONG;				cvs_log(LP_ERRNO, "%s", pbuf);				return (-1);			}			cfp = cvs_file_find(cf, cvsent->ce_name);			if (cfp == NULL) {				cfp = cvs_file_lget(pbuf, flags, cf, cvsent);				if (cfp == NULL)					continue;				if (cfp->cf_type != DT_DIR) {					SIMPLEQ_INSERT_TAIL(&(cf->cf_files),					    cfp, cf_list);					nfiles++;				}			} else {				cfp->cf_flags |= CVS_GDIR_IGNORE;			}			if (cfp->cf_type == DT_DIR) {				ndirs++;				SIMPLEQ_INSERT_TAIL(&dirs, cfp, 				    cf_list);			} else {				/* callback for the file */				if (cb != NULL) {					if (cb(cfp, arg) != CVS_EX_OK)						return (-1);				}			}			if (path != NULL)				break;		}		cvs_ent_close(entfile);	}	if (flags & CF_SORT) {		if (nfiles > 0)			cvs_file_sort(&(cf->cf_files), nfiles);		if (ndirs > 0)			cvs_file_sort(&dirs, ndirs);	}	while (!SIMPLEQ_EMPTY(&dirs)) {		cfp = SIMPLEQ_FIRST(&dirs);		SIMPLEQ_REMOVE_HEAD(&dirs, cf_list);		if (!(cfp->cf_flags & CVS_GDIR_IGNORE))			SIMPLEQ_INSERT_TAIL(&(cf->cf_files), cfp, cf_list);		else			cfp->cf_flags &= ~CVS_GDIR_IGNORE;		if (cvs_file_getdir(cfp, flags, np, cb, arg) < 0) {			cvs_log(LP_ERR, "failed to get %s", CVS_FILE_NAME(cfp));			continue;		}	}	return (0);}