示例#1
0
文件: transport.c 项目: ruoso/git
static int read_loose_refs(struct strbuf *path, int name_offset,
		struct ref **tail)
{
	DIR *dir = opendir(path->buf);
	struct dirent *de;
	struct {
		char **entries;
		int nr, alloc;
	} list;
	int i, pathlen;

	if (!dir)
		return -1;

	memset (&list, 0, sizeof(list));

	while ((de = readdir(dir))) {
		if (is_dot_or_dotdot(de->d_name))
			continue;
		ALLOC_GROW(list.entries, list.nr + 1, list.alloc);
		list.entries[list.nr++] = xstrdup(de->d_name);
	}
	closedir(dir);

	/* sort the list */

	qsort(list.entries, list.nr, sizeof(char *), str_cmp);

	pathlen = path->len;
	strbuf_addch(path, '/');

	for (i = 0; i < list.nr; i++, strbuf_setlen(path, pathlen + 1)) {
		strbuf_addstr(path, list.entries[i]);
		if (read_loose_refs(path, name_offset, tail)) {
			int fd = open(path->buf, O_RDONLY);
			char buffer[40];
			struct ref *next;

			if (fd < 0)
				continue;
			next = alloc_ref(path->buf + name_offset);
			if (read_in_full(fd, buffer, 40) != 40 ||
					get_sha1_hex(buffer, next->old_sha1)) {
				close(fd);
				free(next);
				continue;
			}
			close(fd);
			(*tail)->next = next;
			*tail = next;
		}
	}
	strbuf_setlen(path, pathlen);

	for (i = 0; i < list.nr; i++)
		free(list.entries[i]);
	free(list.entries);

	return 0;
}
示例#2
0
文件: worktree.c 项目: ayanmw/git
static void prune_worktrees(void)
{
	struct strbuf reason = STRBUF_INIT;
	struct strbuf path = STRBUF_INIT;
	DIR *dir = opendir(git_path("worktrees"));
	struct dirent *d;
	int ret;
	if (!dir)
		return;
	while ((d = readdir(dir)) != NULL) {
		if (is_dot_or_dotdot(d->d_name))
			continue;
		strbuf_reset(&reason);
		if (!prune_worktree(d->d_name, &reason))
			continue;
		if (show_only || verbose)
			printf("%s\n", reason.buf);
		if (show_only)
			continue;
		git_path_buf(&path, "worktrees/%s", d->d_name);
		ret = remove_dir_recursively(&path, 0);
		if (ret < 0 && errno == ENOTDIR)
			ret = unlink(path.buf);
		if (ret)
			error_errno(_("failed to remove '%s'"), path.buf);
	}
	closedir(dir);
	if (!show_only)
		rmdir(git_path("worktrees"));
	strbuf_release(&reason);
	strbuf_release(&path);
}
示例#3
0
文件: dirlist.c 项目: sudolee/sudolee
int dirlist(char *pathname)
{
	DIR *dirp;
	struct dirent *dt;
	char *currentpath;
	long max_pathname, namelen, orig_offset;
	int olderrno;

	dirp = opendir(pathname);
	if (dirp == NULL) {
		perror(":: opendir ");
		return RET_ERROR;
	}

	max_pathname = dirent_buf_size(dirp);

	namelen = strlen(pathname) + max_pathname + 1;

	currentpath = malloc(namelen);
	if (currentpath == NULL) {
		perror(":: malloc ");

		closedir(dirp);
		return RET_ERROR;
	}
	memset(currentpath, 0, namelen);

	orig_offset = sprintf(currentpath, "%s/", pathname);

	for (;;) {
		olderrno = errno;

		dt = readdir(dirp);
		if (dt == NULL) {
			/* error detected when errno changed with readdir return NULL. */
			if (errno != olderrno)
				perror(":: readdir ");
			/* else, end of stream reached */
			break;
		}

		/* hide . & .. */
		if (is_dot_or_dotdot(dt->d_name))
			continue;

		sprintf(currentpath + orig_offset, "%s", dt->d_name);

		printf("%s\n", currentpath);

#ifdef DIRLIST_RECURSIVE
		if (is_directory(currentpath))
			dirlist(currentpath);
#endif
	}

	free(currentpath);
	closedir(dirp);

	return RET_OKAY;
}
示例#4
0
文件: builtin-rerere.c 项目: emk/git
static void garbage_collect(struct string_list *rr)
{
	struct string_list to_remove = { NULL, 0, 0, 1 };
	DIR *dir;
	struct dirent *e;
	int i, cutoff;
	time_t now = time(NULL), then;

	git_config(git_rerere_gc_config, NULL);
	dir = opendir(git_path("rr-cache"));
	while ((e = readdir(dir))) {
		if (is_dot_or_dotdot(e->d_name))
			continue;
		then = rerere_created_at(e->d_name);
		if (!then)
			continue;
		cutoff = (has_resolution(e->d_name)
			  ? cutoff_resolve : cutoff_noresolve);
		if (then < now - cutoff * 86400)
			string_list_append(e->d_name, &to_remove);
	}
	for (i = 0; i < to_remove.nr; i++)
		unlink_rr_item(to_remove.items[i].string);
	string_list_clear(&to_remove, 0);
}
示例#5
0
文件: holding.c 项目: code-mx/amanda
/* Recurse over all holding directories in a holding disk.
 *
 * Call per_dir_fn for each dir, and so on, stopping at the level given by 
 * stop_at.
 *
 * datap is passed, unchanged, to all holding_walk_fns.
 *
 * @param hdisk: holding disk to examine (fully qualified path)
 * @param datap: generic user-data pointer
 * @param stop_at: do not proceed beyond this level of the hierarchy
 * @param per_dir_fn: function to call for each holding dir
 * @param per_file_fn: function to call for each holding file
 * @param per_chunk_fn: function to call for each holding chunk
 */
static void 
holding_walk_disk(
    char *hdisk,
    gpointer datap,
    stop_at_t stop_at,
    holding_walk_fn per_dir_fn,
    holding_walk_fn per_file_fn,
    holding_walk_fn per_chunk_fn)
{
    DIR *dir;
    struct dirent *workdir;
    char *hdir = NULL;
    int proceed = 1;

    if ((dir = opendir(hdisk)) == NULL) {
        if (errno != ENOENT)
           dbprintf(_("Warning: could not open holding disk %s: %s\n"),
                  hdisk, strerror(errno));
        return;
    }

    while ((workdir = readdir(dir)) != NULL) {
	int is_cruft = 0;

        if (is_dot_or_dotdot(workdir->d_name))
            continue; /* expected cruft */

        g_free(hdir);
        hdir = g_strconcat(hdisk, "/", workdir->d_name, NULL);

        /* detect cruft */
        if (!is_dir(hdir)) {
	    is_cruft = 1;
        } else if (!is_datestr(workdir->d_name)) {
            /* EXT2/3 leave these in the root of each volume */
            if (g_str_equal(workdir->d_name, "lost+found"))
		continue; /* expected cruft */
	    else
		is_cruft = 1; /* unexpected */
        }

	if (per_dir_fn) 
	    proceed = per_dir_fn(datap, 
			hdisk, 
			workdir->d_name, 
			hdir, 
			is_cruft);
	if (!is_cruft && proceed && stop_at != STOP_AT_DIR)
	    holding_walk_dir(hdir,
		    datap,
		    stop_at,
		    per_file_fn,
		    per_chunk_fn);
    }

    closedir(dir);
    amfree(hdir);
}
示例#6
0
文件: dirlist.c 项目: sudolee/sudolee
/* scandir (optional, sort) files under directory "pathname" */
int _scandir(char *pathname)
{
	DIR *dirp;
	struct dirent **namelist;
	char *currentpath;
	long max_pathname, namelen, orig_offset;
	int count;

	dirp = opendir(pathname);
	if (dirp == NULL) {
		perror(":: opendir ");
		return RET_ERROR;
	}

	max_pathname = dirent_buf_size(dirp);

	namelen = strlen(pathname) + max_pathname + 1;

	currentpath = malloc(namelen);
	if (currentpath == NULL) {
		perror(":: malloc ");

		closedir(dirp);
		return RET_ERROR;
	}
	memset(currentpath, 0, namelen);

	orig_offset = sprintf(currentpath, "%s/", pathname);

	//	count = scandir(currentpath, &namelist, NULL, alphasort);
	count = scandir(currentpath, &namelist, NULL, NULL);
	if (count == -1)
		perror(":: scandir ");
	else {
		while (count--) {
			if (is_dot_or_dotdot(namelist[count]->d_name)) {
				continue;
				free(namelist[count]);
			}

			sprintf(currentpath + orig_offset, "%s", namelist[count]->d_name);
			printf("%s\n", currentpath);

			free(namelist[count]);

#ifdef DIRLIST_RECURSIVE
			if (is_directory(currentpath))
				_scandir(currentpath);
#endif
		}
		free(namelist);
	}

	closedir(dirp);
	free(currentpath);

	return RET_OKAY;
}
示例#7
0
文件: dirlist.c 项目: sudolee/sudolee
/* reentrant version */
int dirlist_r(char *pathname)
{
	DIR *dirp;
	struct dirent *dt, *entry;
	long max_pathname, namelen, orig_offset;
	char *currentpath;

	dirp = opendir(pathname);
	if (dirp == NULL) {
		perror(":: opendir ");
		return RET_ERROR;
	}

	max_pathname = dirent_buf_size(dirp);

	entry = malloc(max_pathname);
	if (entry == NULL) {
		perror(":: malloc ");
		closedir(dirp);
		return RET_ERROR;
	}

	namelen = strlen(pathname) + max_pathname + 1;

	currentpath = malloc(namelen);
	if (currentpath == NULL) {
		perror(":: malloc ");

		free(entry);
		closedir(dirp);
		return RET_ERROR;
	}
	memset(currentpath, 0, namelen);

	orig_offset = sprintf(currentpath, "%s/", pathname);

	while ((readdir_r(dirp, entry, &dt) == 0) && (dt != NULL)) {
		/* hide . & .. */
		if (is_dot_or_dotdot(dt->d_name))
			continue;

		sprintf(currentpath + orig_offset, "%s", dt->d_name);

		printf("%s\n", currentpath);

#ifdef DIRLIST_RECURSIVE
		if (is_directory(currentpath))
			dirlist_r(currentpath);
#endif
	}

	free(entry);
	free(currentpath);
	closedir(dirp);

	return RET_OKAY;
}
示例#8
0
static void count_objects(DIR *d, char *path, int len, int verbose,
			  unsigned long *loose,
			  unsigned long *loose_size,
			  unsigned long *packed_loose,
			  unsigned long *garbage)
{
	struct dirent *ent;
	while ((ent = readdir(d)) != NULL) {
		char hex[41];
		unsigned char sha1[20];
		const char *cp;
		int bad = 0;

		if (is_dot_or_dotdot(ent->d_name))
			continue;
		for (cp = ent->d_name; *cp; cp++) {
			int ch = *cp;
			if (('0' <= ch && ch <= '9') ||
			    ('a' <= ch && ch <= 'f'))
				continue;
			bad = 1;
			break;
		}
		if (cp - ent->d_name != 38)
			bad = 1;
		else {
			struct stat st;
			memcpy(path + len + 3, ent->d_name, 38);
			path[len + 2] = '/';
			path[len + 41] = 0;
			if (lstat(path, &st) || !S_ISREG(st.st_mode))
				bad = 1;
			else
				(*loose_size) += xsize_t(on_disk_bytes(st));
		}
		if (bad) {
			if (verbose) {
				error("garbage found: %.*s/%s",
				      len + 2, path, ent->d_name);
				(*garbage)++;
			}
			continue;
		}
		(*loose)++;
		if (!verbose)
			continue;
		memcpy(hex, path+len, 2);
		memcpy(hex+2, ent->d_name, 38);
		hex[40] = 0;
		if (get_sha1_hex(hex, sha1))
			die("internal error");
		if (has_sha1_pack(sha1))
			(*packed_loose)++;
	}
}
示例#9
0
文件: path.c 项目: Asquera/libgit2
int git_path_direach(
	git_buf *path,
	int (*fn)(void *, git_buf *),
	void *arg)
{
	ssize_t wd_len;
	DIR *dir;
	struct dirent *de, *de_buf;

	if (git_path_to_dir(path) < 0)
		return -1;

	wd_len = git_buf_len(path);

	if ((dir = opendir(path->ptr)) == NULL) {
		giterr_set(GITERR_OS, "Failed to open directory '%s'", path->ptr);
		return -1;
	}

#ifdef __sun
	de_buf = git__malloc(sizeof(struct dirent) + FILENAME_MAX + 1);
#else
	de_buf = git__malloc(sizeof(struct dirent));
#endif

	while (p_readdir_r(dir, de_buf, &de) == 0 && de != NULL) {
		int result;

		if (is_dot_or_dotdot(de->d_name))
			continue;

		if (git_buf_puts(path, de->d_name) < 0) {
			closedir(dir);
			git__free(de_buf);
			return -1;
		}

		result = fn(arg, path);

		git_buf_truncate(path, wd_len); /* restore path */

		if (result < 0) {
			closedir(dir);
			git__free(de_buf);
			return -1;
		}
	}

	closedir(dir);
	git__free(de_buf);
	return 0;
}
示例#10
0
文件: dir.c 项目: nbp/git
int remove_dir_recursively(struct strbuf *path, int flag)
{
	DIR *dir;
	struct dirent *e;
	int ret = 0, original_len = path->len, len;
	int only_empty = (flag & REMOVE_DIR_EMPTY_ONLY);
	int keep_toplevel = (flag & REMOVE_DIR_KEEP_TOPLEVEL);
	unsigned char submodule_head[20];

	if ((flag & REMOVE_DIR_KEEP_NESTED_GIT) &&
	    !resolve_gitlink_ref(path->buf, "HEAD", submodule_head))
		/* Do not descend and nuke a nested git work tree. */
		return 0;

	flag &= ~(REMOVE_DIR_KEEP_TOPLEVEL|REMOVE_DIR_KEEP_NESTED_GIT);
	dir = opendir(path->buf);
	if (!dir) {
		if (!keep_toplevel)
			return rmdir(path->buf);
		else
			return -1;
	}
	if (path->buf[original_len - 1] != '/')
		strbuf_addch(path, '/');

	len = path->len;
	while ((e = readdir(dir)) != NULL) {
		struct stat st;
		if (is_dot_or_dotdot(e->d_name))
			continue;

		strbuf_setlen(path, len);
		strbuf_addstr(path, e->d_name);
		if (lstat(path->buf, &st))
			; /* fall thru */
		else if (S_ISDIR(st.st_mode)) {
			if (!remove_dir_recursively(path, flag))
				continue; /* happy */
		} else if (!only_empty && !unlink(path->buf))
			continue; /* happy, too */

		/* path too long, stat fails, or non-directory still exists */
		ret = -1;
		break;
	}
	closedir(dir);

	strbuf_setlen(path, original_len);
	if (!ret && !keep_toplevel)
		ret = rmdir(path->buf);
	return ret;
}
示例#11
0
文件: fec.cpp 项目: AleksiNorman/fec
      // read
      dirent* read()
      { 
	dirent* buf;
	if (! good() )
	  return 0;
	
	do {
	  buf = readdir(dir);
	  f_eof = (buf == 0);
	} while ( good() && is_dot_or_dotdot(&(buf->d_name[0])) );
	
	return buf;
      }
示例#12
0
int git_futils_direach(
	char *path,
	size_t path_sz,
	int (*fn)(void *, char *),
	void *arg)
{
	size_t wd_len = strlen(path);
	DIR *dir;
	struct dirent *de;

	if (!wd_len || path_sz < wd_len + 2)
		return git__throw(GIT_EINVALIDARGS, "Failed to process `%s` tree structure. Path is either empty or buffer size is too short", path);

	while (path[wd_len - 1] == '/')
		wd_len--;
	path[wd_len++] = '/';
	path[wd_len] = '\0';

	dir = opendir(path);
	if (!dir)
		return git__throw(GIT_EOSERR, "Failed to process `%s` tree structure. An error occured while opening the directory", path);

	while ((de = readdir(dir)) != NULL) {
		size_t de_len;
		int result;

		if (is_dot_or_dotdot(de->d_name))
			continue;

		de_len = strlen(de->d_name);
		if (path_sz < wd_len + de_len + 1) {
			closedir(dir);
			return git__throw(GIT_ERROR, "Failed to process `%s` tree structure. Buffer size is too short", path);
		}

		strcpy(path + wd_len, de->d_name);
		result = fn(arg, path);
		if (result < GIT_SUCCESS) {
			closedir(dir);
			return result;	/* The callee is reponsible for setting the correct error message */
		}
		if (result > 0) {
			closedir(dir);
			return result;
		}
	}

	closedir(dir);
	return GIT_SUCCESS;
}
示例#13
0
文件: rerere.c 项目: foggg7777/git
void rerere_gc(struct string_list *rr)
{
	struct string_list to_remove = STRING_LIST_INIT_DUP;
	DIR *dir;
	struct dirent *e;
	int i;
	timestamp_t now = time(NULL);
	timestamp_t cutoff_noresolve = now - 15 * 86400;
	timestamp_t cutoff_resolve = now - 60 * 86400;

	if (setup_rerere(rr, 0) < 0)
		return;

	git_config_get_expiry_in_days("gc.rerereresolved", &cutoff_resolve, now);
	git_config_get_expiry_in_days("gc.rerereunresolved", &cutoff_noresolve, now);
	git_config(git_default_config, NULL);
	dir = opendir(git_path("rr-cache"));
	if (!dir)
		die_errno(_("unable to open rr-cache directory"));
	/* Collect stale conflict IDs ... */
	while ((e = readdir(dir))) {
		struct rerere_dir *rr_dir;
		struct rerere_id id;
		int now_empty;

		if (is_dot_or_dotdot(e->d_name))
			continue;
		rr_dir = find_rerere_dir(e->d_name);
		if (!rr_dir)
			continue; /* or should we remove e->d_name? */

		now_empty = 1;
		for (id.variant = 0, id.collection = rr_dir;
		     id.variant < id.collection->status_nr;
		     id.variant++) {
			prune_one(&id, cutoff_resolve, cutoff_noresolve);
			if (id.collection->status[id.variant])
				now_empty = 0;
		}
		if (now_empty)
			string_list_append(&to_remove, e->d_name);
	}
	closedir(dir);

	/* ... and then remove the empty directories */
	for (i = 0; i < to_remove.nr; i++)
		rmdir(git_path("rr-cache/%s", to_remove.items[i].string));
	string_list_clear(&to_remove, 0);
	rollback_lock_file(&write_lock);
}
示例#14
0
int
remove_any_file (const char *path, int recurse)
{
  struct L_STAT stat_buffer;

  if (L_LSTAT (path, &stat_buffer) < 0)
    return 0;

  if (S_ISDIR (stat_buffer.st_mode))
    if (recurse)
      {
	DIR *dirp = opendir (path);
	struct dirent *dp;

	if (dirp == NULL)
	  return 0;

	while (dp = readdir (dirp), dp && !is_dot_or_dotdot (dp->d_name))
	  {
	    char *path_buffer = new_name (path, dp->d_name);

	    if (!remove_any_file (path_buffer, 1))
	      {
		int saved_errno = errno;

		free (path_buffer);
		closedir (dirp);
		errno = saved_errno; /* FIXME: errno should be read-only */
		return 0;
	      }
	    free (path_buffer);
	  }
	closedir (dirp);
	return rmdir (path) >= 0;
      }
    else
      {
	/* FIXME: Saving errno might not be needed anymore, now that
	   extract_archive tests for the special case before recovery.  */
	int saved_errno = errno;

	if (rmdir (path) >= 0)
	  return 1;
	errno = saved_errno;	/* FIXME: errno should be read-only */
	return 0;
      }

  return unlink (path) >= 0;
}
示例#15
0
int submodule_uses_worktrees(const char *path)
{
	char *submodule_gitdir;
	struct strbuf sb = STRBUF_INIT;
	DIR *dir;
	struct dirent *d;
	int ret = 0;
	struct repository_format format;

	submodule_gitdir = git_pathdup_submodule(path, "%s", "");
	if (!submodule_gitdir)
		return 0;

	/* The env would be set for the superproject. */
	get_common_dir_noenv(&sb, submodule_gitdir);
	free(submodule_gitdir);

	/*
	 * The check below is only known to be good for repository format
	 * version 0 at the time of writing this code.
	 */
	strbuf_addstr(&sb, "/config");
	read_repository_format(&format, sb.buf);
	if (format.version != 0) {
		strbuf_release(&sb);
		return 1;
	}

	/* Replace config by worktrees. */
	strbuf_setlen(&sb, sb.len - strlen("config"));
	strbuf_addstr(&sb, "worktrees");

	/* See if there is any file inside the worktrees directory. */
	dir = opendir(sb.buf);
	strbuf_release(&sb);

	if (!dir)
		return 0;

	while ((d = readdir(dir)) != NULL) {
		if (is_dot_or_dotdot(d->d_name))
			continue;

		ret = 1;
		break;
	}
	closedir(dir);
	return ret;
}
示例#16
0
static int read_directory_contents(const char *path, struct string_list *list)
{
	DIR *dir;
	struct dirent *e;

	if (!(dir = opendir(path)))
		return error("Could not open directory %s", path);

	while ((e = readdir(dir)))
		if (!is_dot_or_dotdot(e->d_name))
			string_list_insert(list, e->d_name);

	closedir(dir);
	return 0;
}
示例#17
0
文件: prune.c 项目: 7sOddities/git
static int prune_dir(int i, struct strbuf *path)
{
	size_t baselen = path->len;
	DIR *dir = opendir(path->buf);
	struct dirent *de;

	if (!dir)
		return 0;

	while ((de = readdir(dir)) != NULL) {
		char name[100];
		unsigned char sha1[20];

		if (is_dot_or_dotdot(de->d_name))
			continue;
		if (strlen(de->d_name) == 38) {
			sprintf(name, "%02x", i);
			memcpy(name+2, de->d_name, 39);
			if (get_sha1_hex(name, sha1) < 0)
				break;

			/*
			 * Do we know about this object?
			 * It must have been reachable
			 */
			if (lookup_object(sha1))
				continue;

			strbuf_addf(path, "/%s", de->d_name);
			prune_object(path->buf, sha1);
			strbuf_setlen(path, baselen);
			continue;
		}
		if (starts_with(de->d_name, "tmp_obj_")) {
			strbuf_addf(path, "/%s", de->d_name);
			prune_tmp_file(path->buf);
			strbuf_setlen(path, baselen);
			continue;
		}
		fprintf(stderr, "bad sha1 file: %s/%s\n", path->buf, de->d_name);
	}
	closedir(dir);
	if (!show_only)
		rmdir(path->buf);
	return 0;
}
示例#18
0
文件: dir.c 项目: CCorreia/git
int is_empty_dir(const char *path)
{
	DIR *dir = opendir(path);
	struct dirent *e;
	int ret = 1;

	if (!dir)
		return 0;

	while ((e = readdir(dir)) != NULL)
		if (!is_dot_or_dotdot(e->d_name)) {
			ret = 0;
			break;
		}

	closedir(dir);
	return ret;
}
示例#19
0
文件: dir.c 项目: B-Rich/git
static enum path_treatment treat_path(struct dir_struct *dir,
				      struct dirent *de,
				      struct strbuf *path,
				      int baselen,
				      const struct path_simplify *simplify)
{
	int dtype;

	if (is_dot_or_dotdot(de->d_name) || !strcmp(de->d_name, ".git"))
		return path_none;
	strbuf_setlen(path, baselen);
	strbuf_addstr(path, de->d_name);
	if (simplify_away(path->buf, path->len, simplify))
		return path_none;

	dtype = DTYPE(de);
	return treat_one_path(dir, path, simplify, dtype, de);
}
示例#20
0
文件: rerere.c 项目: AndSoAway/git
void rerere_gc(struct string_list *rr)
{
	struct string_list to_remove = STRING_LIST_INIT_DUP;
	DIR *dir;
	struct dirent *e;
	int i, cutoff;
	time_t now = time(NULL), then;
	int cutoff_noresolve = 15;
	int cutoff_resolve = 60;

	if (setup_rerere(rr, 0) < 0)
		return;

	git_config_get_int("gc.rerereresolved", &cutoff_resolve);
	git_config_get_int("gc.rerereunresolved", &cutoff_noresolve);
	git_config(git_default_config, NULL);
	dir = opendir(git_path("rr-cache"));
	if (!dir)
		die_errno("unable to open rr-cache directory");
	/* Collect stale conflict IDs ... */
	while ((e = readdir(dir))) {
		if (is_dot_or_dotdot(e->d_name))
			continue;

		then = rerere_last_used_at(e->d_name);
		if (then) {
			cutoff = cutoff_resolve;
		} else {
			then = rerere_created_at(e->d_name);
			if (!then)
				continue;
			cutoff = cutoff_noresolve;
		}
		if (then < now - cutoff * 86400)
			string_list_append(&to_remove, e->d_name);
	}
	closedir(dir);
	/* ... and then remove them one-by-one */
	for (i = 0; i < to_remove.nr; i++)
		unlink_rr_item(dirname_to_id(to_remove.items[i].string));
	string_list_clear(&to_remove, 0);
	rollback_lock_file(&write_lock);
}
示例#21
0
文件: prune.c 项目: DavidGould/git
static int prune_dir(int i, char *path)
{
	DIR *dir = opendir(path);
	struct dirent *de;

	if (!dir)
		return 0;

	while ((de = readdir(dir)) != NULL) {
		char name[100];
		unsigned char sha1[20];

		if (is_dot_or_dotdot(de->d_name))
			continue;
		if (strlen(de->d_name) == 38) {
			sprintf(name, "%02x", i);
			memcpy(name+2, de->d_name, 39);
			if (get_sha1_hex(name, sha1) < 0)
				break;

			/*
			 * Do we know about this object?
			 * It must have been reachable
			 */
			if (lookup_object(sha1))
				continue;

			prune_object(path, de->d_name, sha1);
			continue;
		}
		if (!prefixcmp(de->d_name, "tmp_obj_")) {
			prune_tmp_object(path, de->d_name);
			continue;
		}
		fprintf(stderr, "bad sha1 file: %s/%s\n", path, de->d_name);
	}
	closedir(dir);
	if (!show_only)
		rmdir(path);
	return 0;
}
示例#22
0
文件: path.c 项目: DJHartley/libgit2
int git_path_direach(
	git_buf *path,
	int (*fn)(void *, git_buf *),
	void *arg)
{
	ssize_t wd_len;
	DIR *dir;
	struct dirent *de;

	if (git_path_to_dir(path) < GIT_SUCCESS)
		return git_buf_lasterror(path);

	wd_len = path->size;
	dir = opendir(path->ptr);
	if (!dir)
		return git__throw(GIT_EOSERR, "Failed to process `%s` tree structure. An error occured while opening the directory", path->ptr);

	while ((de = readdir(dir)) != NULL) {
		int result;

		if (is_dot_or_dotdot(de->d_name))
			continue;

		if (git_buf_puts(path, de->d_name) < GIT_SUCCESS)
			return git_buf_lasterror(path);

		result = fn(arg, path);

		git_buf_truncate(path, wd_len); /* restore path */

		if (result != GIT_SUCCESS) {
			closedir(dir);
			return result;	/* The callee is reponsible for setting the correct error message */
		}
	}

	closedir(dir);
	return GIT_SUCCESS;
}
示例#23
0
文件: dir.c 项目: sirnot/git
int remove_dir_recursively(struct strbuf *path, int only_empty)
{
	DIR *dir = opendir(path->buf);
	struct dirent *e;
	int ret = 0, original_len = path->len, len;

	if (!dir)
		return -1;
	if (path->buf[original_len - 1] != '/')
		strbuf_addch(path, '/');

	len = path->len;
	while ((e = readdir(dir)) != NULL) {
		struct stat st;
		if (is_dot_or_dotdot(e->d_name))
			continue;

		strbuf_setlen(path, len);
		strbuf_addstr(path, e->d_name);
		if (lstat(path->buf, &st))
			; /* fall thru */
		else if (S_ISDIR(st.st_mode)) {
			if (!remove_dir_recursively(path, only_empty))
				continue; /* happy */
		} else if (!only_empty && !unlink(path->buf))
			continue; /* happy, too */

		/* path too long, stat fails, or non-directory still exists */
		ret = -1;
		break;
	}
	closedir(dir);

	strbuf_setlen(path, original_len);
	if (!ret)
		ret = rmdir(path->buf);
	return ret;
}
示例#24
0
文件: dir.c 项目: CCorreia/git
static enum path_treatment treat_path(struct dir_struct *dir,
				      struct dirent *de,
				      char *path, int path_max,
				      int baselen,
				      const struct path_simplify *simplify,
				      int *len)
{
	int dtype;

	if (is_dot_or_dotdot(de->d_name) || !strcmp(de->d_name, ".git"))
		return path_ignored;
	*len = strlen(de->d_name);
	/* Ignore overly long pathnames! */
	if (*len + baselen + 8 > path_max)
		return path_ignored;
	memcpy(path + baselen, de->d_name, *len + 1);
	*len += baselen;
	if (simplify_away(path, *len, simplify))
		return path_ignored;

	dtype = DTYPE(de);
	return treat_one_path(dir, path, len, simplify, dtype, de);
}
示例#25
0
文件: dir.c 项目: CCorreia/git
static int remove_dir_recurse(struct strbuf *path, int flag, int *kept_up)
{
	DIR *dir;
	struct dirent *e;
	int ret = 0, original_len = path->len, len, kept_down = 0;
	int only_empty = (flag & REMOVE_DIR_EMPTY_ONLY);
	int keep_toplevel = (flag & REMOVE_DIR_KEEP_TOPLEVEL);
	unsigned char submodule_head[20];

	if ((flag & REMOVE_DIR_KEEP_NESTED_GIT) &&
	    !resolve_gitlink_ref(path->buf, "HEAD", submodule_head)) {
		/* Do not descend and nuke a nested git work tree. */
		if (kept_up)
			*kept_up = 1;
		return 0;
	}

	flag &= ~REMOVE_DIR_KEEP_TOPLEVEL;
	dir = opendir(path->buf);
	if (!dir) {
		/* an empty dir could be removed even if it is unreadble */
		if (!keep_toplevel)
			return rmdir(path->buf);
		else
			return -1;
	}
	if (path->buf[original_len - 1] != '/')
		strbuf_addch(path, '/');

	len = path->len;
	while ((e = readdir(dir)) != NULL) {
		struct stat st;
		if (is_dot_or_dotdot(e->d_name))
			continue;

		strbuf_setlen(path, len);
		strbuf_addstr(path, e->d_name);
		if (lstat(path->buf, &st))
			; /* fall thru */
		else if (S_ISDIR(st.st_mode)) {
			if (!remove_dir_recurse(path, flag, &kept_down))
				continue; /* happy */
		} else if (!only_empty && !unlink(path->buf))
			continue; /* happy, too */

		/* path too long, stat fails, or non-directory still exists */
		ret = -1;
		break;
	}
	closedir(dir);

	strbuf_setlen(path, original_len);
	if (!ret && !keep_toplevel && !kept_down)
		ret = rmdir(path->buf);
	else if (kept_up)
		/*
		 * report the uplevel that it is not an error that we
		 * did not rmdir() our directory.
		 */
		*kept_up = !ret;
	return ret;
}
示例#26
0
/* Remove a directory entry.  Files are removed, directories are
   recursively walked and removed.
   Return 0 on success, and -1 on falure.
   In practice, OpenAxiom does not remove directories with
   non-trivial recursive structues.  */
OPENAXIOM_C_EXPORT int
oa_unlink(const char* path)
{
   const char* curdir;
   int status = -1;
#ifdef OPENAXIOM_MS_WINDOWS_HOST
   WIN32_FIND_DATA findData;
   HANDLE walkHandle;

   if (is_dot_or_dotdot(path))
      return -1;

   walkHandle = FindFirstFile(path, &findData);
   if (walkHandle == INVALID_HANDLE_VALUE) 
      return -1;

   /* Remember where we are so we can return back properly.  */
   curdir = oa_getcwd();

   do {
      if (is_dot_or_dotdot(findData.cFileName))
         continue;
      if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
         if ((status = oa_chdir(findData.cFileName)) < 0)
            goto sortie;
         if ((status = oa_unlink("*")) < 0)
            goto sortie;
         if ((status = oa_chdir("..")) < 0)
            goto sortie;
         if(!RemoveDirectory(findData.cFileName)) {
            status = -1;
            goto sortie;
         }
      }
      else if (!DeleteFile(findData.cFileName)) {
         status = -1;
         goto sortie;
      }
      status = 0;
   } while (FindNextFile(walkHandle, &findData));
   if (!FindClose(walkHandle)) {
      status = -1;
      goto sortie;
   }
#else
   struct stat pathstat;
   DIR* dir;
   struct dirent* entry;

   /* Don't ever try to remove `.' or `..'.  */
   if (is_dot_or_dotdot(path))
      return -1;

   if (stat(path, &pathstat) < 0)
      return -1;

   /* handle non directories first.  */
   if (!S_ISDIR(pathstat.st_mode))
      return unlink(path);

   /* change into the path so that we don't have to form full
      pathnames. */
   curdir = oa_getcwd();
   if ((dir = opendir(path)) == NULL || oa_chdir(path) < 0)
      goto sortie;

   while (errno = 0, (entry = readdir(dir)) != NULL) {
      struct stat s;
      if (is_dot_or_dotdot(entry->d_name))
         continue;
      if ((status = stat(entry->d_name, &s)) < 0)
         goto sortie;
      if (S_ISDIR(s.st_mode)) {
         if ((status = oa_unlink(entry->d_name)) < 0)
            goto sortie;
      }
      else if ((status = unlink(entry->d_name)) < 0)
         goto sortie;
   }
   if (errno != 0) {
      status = -1;
      goto sortie;
   }

   /* Now, get one level up, and remove the empty directory.  */
   if (oa_chdir("..") < 0 || closedir(dir) < 0 || rmdir(path) < 0) 
      status = -1;
   else
      status = 0;
#endif /* OPENAXIOM_MS_WINDOWS_HOST */

  sortie:
   oa_chdir(curdir);
   free((char*) curdir);
   return status;
}
示例#27
0
static int 
read_directory_recursive(struct dir_struct *dir,
                         const char *base, int baselen,
                         int check_only,
                         struct index_state *index,
                         const char *worktree,
                         IgnoreFunc ignore_func,
                         void *data)
{
    char *realpath = g_build_path (PATH_SEPERATOR, worktree, base, NULL);
    GDir *fdir = g_dir_open (realpath, 0, NULL);
    const char *dname;
    char *nfc_dname;
    int contents = 0;
    int dtype;

    if (fdir) {
        char path[SEAF_PATH_MAX + 1];
        memcpy(path, base, baselen);
        while ((dname = g_dir_read_name(fdir)) != NULL) {
            int len = 0;

#ifdef __APPLE__
            nfc_dname = g_utf8_normalize (dname, -1, G_NORMALIZE_NFC);
#else
            nfc_dname = g_strdup(dname);
#endif

            if (is_dot_or_dotdot(nfc_dname)) {
                g_free (nfc_dname);
                continue;
            }

            if (ignore_func (realpath, nfc_dname, data)) {
                g_free (nfc_dname);
                continue;
            }

            dtype = get_dtype(nfc_dname, realpath);
            switch (dtype) {
            case DT_REG:
                len = strlen(nfc_dname);
                memcpy(path + baselen, nfc_dname, len + 1);
                len = strlen(path);
                break;
            case DT_DIR:
                len = strlen(nfc_dname);
                memcpy(path + baselen, nfc_dname, len + 1);
                memcpy(path + baselen + len, "/", 2);
                len = strlen(path);
                read_directory_recursive(dir, path, len, 0,
                                         index, worktree, ignore_func, data);
                g_free (nfc_dname);
                continue;
            default: /* DT_UNKNOWN */
                len = 0;
                break;
            }
            if(len > 0)
                dir_add_name(dir, path, len, index);
            g_free (nfc_dname);
        }
        g_dir_close(fdir);
    }

    g_free(realpath);
    return contents;
}
示例#28
0
void
traverse_dirs(
    char *	parent_dir,
    char *	include)
{
    DIR *d;
    struct dirent *f;
    struct stat finfo;
    char *dirname, *newname = NULL;
    char *newbase = NULL;
    dev_t parent_dev = (dev_t)0;
    int i;
    size_t l;
    size_t parent_len;
    int has_exclude;
    char *aparent;

    if(parent_dir == NULL || include == NULL)
	return;

    has_exclude = !is_empty_sl(exclude_sl) && (use_gtar_excl || use_star_excl);
    aparent = g_strjoin(NULL, parent_dir, "/", include, NULL);

    /* We (may) need root privs for the *stat() calls here. */
    set_root_privs(1);
    if(stat(parent_dir, &finfo) != -1)
	parent_dev = finfo.st_dev;

    parent_len = strlen(parent_dir);

    push_name(aparent);

    for(; (dirname = pop_name()) != NULL; free(dirname)) {
	if(has_exclude && calc_check_exclude(dirname+parent_len+1)) {
	    continue;
	}
	if((d = opendir(dirname)) == NULL) {
	    perror(dirname);
	    continue;
	}

	l = strlen(dirname);
	if(l > 0 && dirname[l - 1] != '/') {
	    g_free(newbase);
	    newbase = g_strconcat(dirname, "/", NULL);
	} else {
	    g_free(newbase);
	    newbase = g_strdup(dirname);
	}

	while((f = readdir(d)) != NULL) {
	    int is_symlink = 0;
	    int is_dir;
	    int is_file;
	    if(is_dot_or_dotdot(f->d_name)) {
		continue;
	    }

	    g_free(newname);
	    newname = g_strconcat(newbase, f->d_name, NULL);
	    if(lstat(newname, &finfo) == -1) {
		g_fprintf(stderr, "%s/%s: %s\n",
			dirname, f->d_name, strerror(errno));
		continue;
	    }

	    if(finfo.st_dev != parent_dev)
		continue;

#ifdef S_IFLNK
	    is_symlink = ((finfo.st_mode & S_IFMT) == S_IFLNK);
#endif
	    is_dir = ((finfo.st_mode & S_IFMT) == S_IFDIR);
	    is_file = ((finfo.st_mode & S_IFMT) == S_IFREG);

	    if (!(is_file || is_dir || is_symlink)) {
		continue;
	    }

	    {
		int is_excluded = -1;
		for(i = 0; i < ndumps; i++) {
		    add_file_name(i, newname);
		    if(is_file && (time_t)finfo.st_ctime >= dumpdate[i]) {

			if(has_exclude) {
			    if(is_excluded == -1)
				is_excluded =
				       calc_check_exclude(newname+parent_len+1);
			    if(is_excluded == 1) {
				i = ndumps;
				continue;
			    }
			}
			add_file(i, &finfo);
		    }
		}
		if(is_dir) {
		    if(has_exclude && calc_check_exclude(newname+parent_len+1))
			continue;
		    push_name(newname);
		}
	    }
	}

#ifdef CLOSEDIR_VOID
	closedir(d);
#else
	if(closedir(d) == -1)
	    perror(dirname);
#endif
    }

    /* drop root privs -- we're done with the permission-sensitive calls */
    set_root_privs(0);

    amfree(newbase);
    amfree(newname);
    amfree(aparent);
}
示例#29
0
文件: amtrmidx.c 项目: neepher/amanda
int
main(
    int		argc,
    char **	argv)
{
    GList  *dlist;
    GList  *dlist1;
    disk_t *diskp;
    disklist_t diskl;
    size_t i;
    char *conf_diskfile;
    char *conf_tapelist;
    char *conf_indexdir;
    find_result_t *output_find;
    time_t tmp_time;
    int amtrmidx_debug = 0;
    config_overrides_t *cfg_ovr = NULL;
    gboolean   compress_index;
    gboolean   sort_index;
    char      *lock_file;
    file_lock *lock_index;

    if (argc > 1 && argv[1] && g_str_equal(argv[1], "--version")) {
	printf("amtrmidx-%s\n", VERSION);
	return (0);
    }

    /*
     * Configure program for internationalization:
     *   1) Only set the message locale for now.
     *   2) Set textdomain for all amanda related programs to "amanda"
     *      We don't want to be forced to support dozens of message catalogs.
     */
    setlocale(LC_MESSAGES, "C");
    textdomain("amanda");

    safe_fd(-1, 0);
    safe_cd();

    set_pname("amtrmidx");

    /* Don't die when child closes pipe */
    signal(SIGPIPE, SIG_IGN);

    dbopen(DBG_SUBDIR_SERVER);
    dbprintf(_("%s: version %s\n"), argv[0], VERSION);

    cfg_ovr = extract_commandline_config_overrides(&argc, &argv);

    if (argc > 1 && g_str_equal(argv[1], "-t")) {
	amtrmidx_debug = 1;
	argc--;
	argv++;
    }

    if (argc < 2) {
	g_fprintf(stderr, _("Usage: %s [-t] <config> [-o configoption]*\n"), argv[0]);
	return 1;
    }

    set_config_overrides(cfg_ovr);
    config_init_with_global(CONFIG_INIT_EXPLICIT_NAME | CONFIG_INIT_USE_CWD, argv[1]);

    conf_diskfile = config_dir_relative(getconf_str(CNF_DISKFILE));
    read_diskfile(conf_diskfile, &diskl);
    amfree(conf_diskfile);

    if (config_errors(NULL) >= CFGERR_WARNINGS) {
	config_print_errors();
	if (config_errors(NULL) >= CFGERR_ERRORS) {
	    g_critical(_("errors processing config file"));
	}
    }

    check_running_as(RUNNING_AS_DUMPUSER);

    dbrename(get_config_name(), DBG_SUBDIR_SERVER);

    conf_tapelist = config_dir_relative(getconf_str(CNF_TAPELIST));
    if(read_tapelist(conf_tapelist)) {
	error(_("could not load tapelist \"%s\""), conf_tapelist);
	/*NOTREACHED*/
    }
    amfree(conf_tapelist);

    compress_index = getconf_boolean(CNF_COMPRESS_INDEX);
    sort_index = getconf_boolean(CNF_SORT_INDEX);

    output_find = find_dump(&diskl);

    conf_indexdir = config_dir_relative(getconf_str(CNF_INDEXDIR));

    /* take a lock file to prevent concurent trim */
    lock_file = g_strdup_printf("%s/%s", conf_indexdir, "lock");
    lock_index = file_lock_new(lock_file);
    if (file_lock_lock_wr(lock_index) != 0)
	goto lock_failed;

    /* now go through the list of disks and find which have indexes */
    time(&tmp_time);
    tmp_time -= 7*24*60*60;			/* back one week */
    for (dlist = diskl.head; dlist != NULL; dlist = dlist->next)
    {
	diskp = dlist->data;
	if (diskp->index)
	{
	    char *indexdir, *qindexdir;
	    DIR *d;
	    struct dirent *f;
	    char **names;
	    size_t name_length;
	    size_t name_count;
	    char *host;
	    char *disk, *qdisk;
	    size_t len_date;
	    disk_t *dp;
	    GSList *matching_dp = NULL;

	    /* get listing of indices, newest first */
	    host = sanitise_filename(diskp->host->hostname);
	    disk = sanitise_filename(diskp->name);
	    qdisk = quote_string(diskp->name);
	    indexdir = g_strjoin(NULL, conf_indexdir, "/",
				 host, "/",
				 disk, "/",
				 NULL);
	    qindexdir = quote_string(indexdir);

	    /* find all dles that use the same indexdir */
	    for (dlist1 = diskl.head; dlist1 != NULL; dlist1 = dlist1->next)
	    {
		char *dp_host, *dp_disk;

		dp = dlist1->data;
		dp_host = sanitise_filename(dp->host->hostname);
		dp_disk = sanitise_filename(dp->name);
		if (g_str_equal(host, dp_host) &&
		    g_str_equal(disk, dp_disk)) {
		    matching_dp = g_slist_append(matching_dp, dp);
		}
		amfree(dp_host);
		amfree(dp_disk);
	    }

	    dbprintf("%s %s -> %s\n", diskp->host->hostname,
			qdisk, qindexdir);
	    amfree(qdisk);
	    if ((d = opendir(indexdir)) == NULL) {
		dbprintf(_("could not open index directory %s\n"), qindexdir);
		amfree(host);
		amfree(disk);
		amfree(indexdir);
	        amfree(qindexdir);
		g_slist_free(matching_dp);
		continue;
	    }
	    name_length = 100;
	    names = (char **)g_malloc(name_length * sizeof(char *));
	    name_count = 0;
	    while ((f = readdir(d)) != NULL) {
		size_t l;

		if(is_dot_or_dotdot(f->d_name)) {
		    continue;
		}
		for(i = 0; i < sizeof("YYYYMMDDHHMMSS")-1; i++) {
		    if(! isdigit((int)(f->d_name[i]))) {
			break;
		    }
		}
		len_date = i;
		/* len_date=8  for YYYYMMDD       */
		/* len_date=14 for YYYYMMDDHHMMSS */
		if((len_date != 8 && len_date != 14)
		    || f->d_name[len_date] != '_'
		    || ! isdigit((int)(f->d_name[len_date+1]))) {
		    continue;			/* not an index file */
		}
		/*
		 * Clear out old index temp files.
		 */
		l = strlen(f->d_name) - (sizeof(".tmp")-1);
		if ((l > (len_date + 1))
			&& (g_str_equal(f->d_name + l, ".tmp"))) {
		    struct stat sbuf;
		    char *path, *qpath;

		    path = g_strconcat(indexdir, f->d_name, NULL);
		    qpath = quote_string(path);
		    if(lstat(path, &sbuf) != -1
			&& ((sbuf.st_mode & S_IFMT) == S_IFREG)
			&& ((time_t)sbuf.st_mtime < tmp_time)) {
			dbprintf("rm %s\n", qpath);
		        if(amtrmidx_debug == 0 && unlink(path) == -1) {
			    dbprintf(_("Error removing %s: %s\n"),
				      qpath, strerror(errno));
		        }
		    }
		    amfree(qpath);
		    amfree(path);
		    continue;
		}
		if(name_count >= name_length) {
		    char **new_names;

		    new_names = g_malloc((name_length * 2) * sizeof(char *));
		    memcpy(new_names, names, name_length * sizeof(char *));
		    amfree(names);
		    names = new_names;
		    name_length *= 2;
		}
		names[name_count++] = g_strdup(f->d_name);
	    }
	    closedir(d);
	    qsort(names, name_count, sizeof(char *), sort_by_name_reversed);

	    /*
	     * Search for the first full dump past the minimum number
	     * of index files to keep.
	     */
	    for(i = 0; i < name_count; i++) {
		char *datestamp;
		int level;
		size_t len_date;
		int matching = 0;
		GSList *mdp;

		for(len_date = 0; len_date < sizeof("YYYYMMDDHHMMSS")-1; len_date++) {
                    if(! isdigit((int)(names[i][len_date]))) {
                        break;
                    }
                }

		datestamp = g_strdup(names[i]);
		datestamp[len_date] = '\0';
		if (sscanf(&names[i][len_date+1], "%d", &level) != 1)
		    level = 0;
		for (mdp = matching_dp; mdp != NULL; mdp = mdp->next) {
		    dp = mdp->data;
		    if (dump_exist(output_find, dp->host->hostname,
				   dp->name, datestamp, level)) {
			matching = 1;
		    }
		}
		if (!matching) {
		    struct stat sbuf;
		    char *path, *qpath;

		    path = g_strconcat(indexdir, names[i], NULL);
		    qpath = quote_string(path);
		    if(lstat(path, &sbuf) != -1
			&& ((sbuf.st_mode & S_IFMT) == S_IFREG)
			&& ((time_t)sbuf.st_mtime < tmp_time)) {
			dbprintf("rm %s\n", qpath);
		        if(amtrmidx_debug == 0 && unlink(path) == -1) {
			    dbprintf(_("Error removing %s: %s\n"),
				      qpath, strerror(errno));
		        }
		    }
		    amfree(qpath);
		    amfree(path);
		}

		/* Did it require un/compression and/or sorting */
		{
		char *orig_name = getindexfname(host, disk, datestamp, level);
		char *sorted_name = getindex_sorted_fname(host, disk, datestamp, level);
		char *sorted_gz_name = getindex_sorted_gz_fname(host, disk, datestamp, level);
		char *unsorted_name = getindex_unsorted_fname(host, disk, datestamp, level);
		char *unsorted_gz_name = getindex_unsorted_gz_fname(host, disk, datestamp, level);

		gboolean orig_exist = FALSE;
		gboolean sorted_exist = FALSE;
		gboolean sorted_gz_exist = FALSE;
		gboolean unsorted_exist = FALSE;
		gboolean unsorted_gz_exist = FALSE;

		int fd;
		int uncompress_err_fd = -1;
		int sort_err_fd = -1;
		int compress_err_fd = -1;

		pid_t uncompress_pid = -1;
		pid_t sort_pid = -1;
		pid_t compress_pid = -1;

		orig_exist = file_exists(orig_name);
		sorted_exist = file_exists(sorted_name);
		sorted_gz_exist = file_exists(sorted_gz_name);
		unsorted_exist = file_exists(unsorted_name);
		unsorted_gz_exist = file_exists(unsorted_gz_name);

		if (sort_index && compress_index) {
		    if (!sorted_gz_exist) {
			if (sorted_exist) {
			    // COMPRESS
			    compress_pid = run_compress(-1, NULL, &compress_err_fd, sorted_name, sorted_gz_name);
			    unlink(sorted_name);
			} else if (unsorted_exist) {
			    // SORT AND COMPRESS
			    sort_pid = run_sort(-1, &fd, &sort_err_fd, unsorted_name, NULL);
			    compress_pid = run_compress(fd, NULL, &compress_err_fd, NULL, sorted_gz_name);
			    unlink(unsorted_name);
			} else if (unsorted_gz_exist) {
			    // UNCOMPRESS SORT AND COMPRESS
			    uncompress_pid = run_uncompress(-1, &fd, &uncompress_err_fd, unsorted_gz_name, NULL);
			    sort_pid = run_sort(fd, &fd, &sort_err_fd, NULL, NULL);
			    compress_pid = run_compress(fd, NULL, &compress_err_fd, NULL, sorted_gz_name);
			    unlink(unsorted_gz_name);
			} else if (orig_exist) {
			    // UNCOMPRESS SORT AND COMPRESS
			    uncompress_pid = run_uncompress(-1, &fd, &uncompress_err_fd, orig_name, NULL);
			    sort_pid = run_sort(fd, &fd, &sort_err_fd, NULL, NULL);
			    compress_pid = run_compress(fd, NULL, &compress_err_fd, NULL, sorted_gz_name);
			    unlink(orig_name);
			}
		    } else {
			if (sorted_exist) {
			    unlink(sorted_name);
			}
			if (unsorted_exist) {
			    unlink(unsorted_name);
			}
			if (unsorted_gz_exist) {
			    unlink(unsorted_gz_name);
			}
		    }
		} else if (sort_index && !compress_index) {
		    if (!sorted_exist) {
			if (sorted_gz_exist) {
			    // UNCOMPRESS
			    uncompress_pid = run_uncompress(-1, NULL, &uncompress_err_fd, sorted_gz_name, sorted_name);
			    unlink(sorted_gz_name);
			} else if (unsorted_exist) {
			    // SORT
			    sort_pid = run_sort(-1, NULL, &sort_err_fd, unsorted_name, sorted_name);
			    unlink(unsorted_name);
			} else if (unsorted_gz_exist) {
			    // UNCOMPRESS AND SORT
			    uncompress_pid = run_uncompress(-1, &fd, &uncompress_err_fd, unsorted_gz_name, NULL);
			    sort_pid = run_sort(fd, NULL, &sort_err_fd, NULL, sorted_name);
			    unlink(unsorted_gz_name);
			} else if (orig_exist) {
			    // UNCOMPRESS AND SORT
			    uncompress_pid = run_uncompress(-1, &fd, &uncompress_err_fd, orig_name, NULL);
			    sort_pid = run_sort(fd, NULL, &sort_err_fd, NULL, sorted_name);
			    unlink(orig_name);
			}
		    } else {
			if (sorted_gz_exist) {
			    unlink(sorted_gz_name);
			}
			if (unsorted_exist) {
			    unlink(unsorted_name);
			}
			if (unsorted_gz_exist) {
			    unlink(unsorted_gz_name);
			}
		    }
		} else if (!sort_index && compress_index) {
		    if (!sorted_gz_exist && !unsorted_gz_exist) {
			if (sorted_exist) {
			    // COMPRESS sorted
			    compress_pid = run_compress(-1, NULL, &compress_err_fd, sorted_name, sorted_gz_name);
			    unlink(sorted_name);
			} else if (unsorted_exist) {
			    // COMPRESS unsorted
			    compress_pid = run_compress(-1, NULL, &compress_err_fd, unsorted_name, unsorted_gz_name);
			    unlink(unsorted_name);
			} else if (orig_exist) {
			    // RENAME orig
			    rename(orig_name, unsorted_gz_name);
			}
		    } else {
			if (sorted_exist) {
			    unlink(sorted_name);
			}
			if (unsorted_exist) {
			    unlink(unsorted_name);
			}
			if (sorted_gz_exist && unsorted_gz_exist) {
			    unlink(unsorted_gz_name);
			}
		    }
		} else if (!sort_index && !compress_index) {
		    if (!sorted_exist && !unsorted_exist) {
			if (sorted_gz_exist) {
			    // UNCOMPRESS sorted
			    uncompress_pid = run_uncompress(-1, NULL, &uncompress_err_fd, sorted_gz_name, sorted_name);
			    unlink(sorted_gz_name);
			} else if (unsorted_gz_exist) {
			    // UNCOMPRESS unsorted
			    uncompress_pid = run_uncompress(-1, NULL, &uncompress_err_fd, unsorted_gz_name, unsorted_name);
			    unlink(unsorted_gz_name);
			} else if (orig_exist) {
			    // UNCOMPRESS orig
			    uncompress_pid = run_uncompress(-1, NULL, &uncompress_err_fd, orig_name, unsorted_name);
			    unlink(orig_name);
			}
		    } else {
			if (sorted_gz_exist) {
			    unlink(sorted_gz_name);
			}
			if (unsorted_gz_exist) {
			    unlink(unsorted_gz_name);
			}
			if (sorted_exist && unsorted_exist) {
			    unlink(unsorted_name);
			}
		    }
		}
		    if (uncompress_pid != -1)
			wait_process(uncompress_pid, uncompress_err_fd, "uncompress");
		    if (sort_pid != -1)
			wait_process(sort_pid, sort_err_fd, "sort");
		    if (compress_pid != -1)
			wait_process(compress_pid, compress_err_fd, "compress");

		    g_free(orig_name);
		    g_free(sorted_name);
		    g_free(sorted_gz_name);
		    g_free(unsorted_name);
		    g_free(unsorted_gz_name);
		}

		amfree(datestamp);
		amfree(names[i]);
	    }
	    g_slist_free(matching_dp);
	    amfree(names);
	    amfree(host);
	    amfree(disk);
	    amfree(indexdir);
	    amfree(qindexdir);
	}
    }

    file_lock_unlock(lock_index);
lock_failed:
    file_lock_free(lock_index);
    amfree(conf_indexdir);
    amfree(lock_file);
    free_find_result(&output_find);
    clear_tapelist();
    free_disklist(&diskl);
    unload_disklist();

    dbclose();

    return 0;
}
示例#30
0
文件: holding.c 项目: code-mx/amanda
/* Recurse over all holding files in a holding directory.
 *
 * Call per_file_fn for each file, and so on, stopping at the level given by 
 * stop_at.
 *
 * datap is passed, unchanged, to all holding_walk_fns.
 *
 * @param hdir: holding directory to examine (fully qualified path)
 * @param datap: generic user-data pointer
 * @param stop_at: do not proceed beyond this level of the hierarchy
 * @param per_file_fn: function to call for each holding file
 * @param per_chunk_fn: function to call for each holding chunk
 */
static void holding_walk_dir(
    char *hdir,
    gpointer datap,
    stop_at_t stop_at,
    holding_walk_fn per_file_fn,
    holding_walk_fn per_chunk_fn)
{
    DIR *dir;
    struct dirent *workdir;
    char *hfile = NULL;
    dumpfile_t dumpf;
    int dumpf_ok;
    int proceed = 1;

    if ((dir = opendir(hdir)) == NULL) {
        if (errno != ENOENT)
           dbprintf(_("Warning: could not open holding dir %s: %s\n"),
                  hdir, strerror(errno));
        return;
    }

    while ((workdir = readdir(dir)) != NULL) {
	int is_cruft = 0;

        if (is_dot_or_dotdot(workdir->d_name))
            continue; /* expected cruft */

        g_free(hfile);
        hfile = g_strconcat(hdir, "/", workdir->d_name, NULL);

        /* filter out various undesirables */
        if (is_emptyfile(hfile))
            is_cruft = 1;

        if (is_dir(hfile)) {
            is_cruft= 1;
        }

        if (!(dumpf_ok=holding_file_get_dumpfile(hfile, &dumpf)) ||
            dumpf.type != F_DUMPFILE) {
            if (dumpf_ok && dumpf.type == F_CONT_DUMPFILE) {
		dumpfile_free_data(&dumpf);
                continue; /* silently skip expected file */
	    }

            is_cruft = 1;
        }

	if (dumpf.dumplevel < 0 || dumpf.dumplevel > 9) {
	    is_cruft = 1;
	}

	if (per_file_fn) 
	    proceed = per_file_fn(datap, 
			hdir, 
			workdir->d_name, 
			hfile, 
			is_cruft);
	if (!is_cruft && proceed && stop_at != STOP_AT_FILE)
	    holding_walk_file(hfile,
		    datap,
		    per_chunk_fn);
	dumpfile_free_data(&dumpf);
    }

    closedir(dir);
    amfree(hfile);
}