/* ANT_DIRECTORY_ITERATOR_RECURSIVE::NEXT_MATCH_WILDCARD() ------------------------------------------------------- */ char *ANT_directory_iterator_recursive::next_match_wildcard(void) { #ifdef _MSC_VER ANT_disk_directory *current_file_list; size_t path_length; while (get_next_candidate()) { if (internals->file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { if (!(strcmp(internals->file_data.cFileName, ".") == 0 || strcmp(internals->file_data.cFileName, "..") == 0)) { current_file_list = file_list; push_directory(); path_length = strlen(current_file_list->path) - 4; sprintf(file_list->path, "%*.*s/%s/*.*", (int)path_length, (int)path_length, current_file_list->path, internals->file_data.cFileName); } } else if (PathMatchSpec(internals->file_data.cFileName, wildcard)) return internals->file_data.cFileName; } return NULL; #else char *file; long match = FALSE, at_end = 1; while (!match) { if (at_end == 0 || file_list->glob_index >= file_list->matching_files.gl_pathc) { globfree(&file_list->matching_files); if (pop_directory()) { file_list->glob_index++; return next_match_wildcard(); } else return NULL; } // check if the matching path is a directory else if (file_list->matching_files.gl_pathv[file_list->glob_index][strlen(file_list->matching_files.gl_pathv[file_list->glob_index]) - 1] == '/') { if (true) { /* tmp is here as push_directory() will trash current file_list*/ char *tmp=file_list->matching_files.gl_pathv[file_list->glob_index]; push_directory(); if ((file = first_match_wildcard(tmp)) != NULL) return file; } } else if ((match = PathMatchSpec(file_list->matching_files.gl_pathv[file_list->glob_index], wildcard)) != 0) break; at_end = !(file_list->glob_index++ == file_list->matching_files.gl_pathc); } return file_list->matching_files.gl_pathv[file_list->glob_index++]; #endif }
static void add_directory(std::string directory, bool recursively = false){ push_directory(directory); if(recursively){ add_recursively(directory); } }
static void add_recursively(std::string parent) { if(is_dir(parent)){ push_directory(parent); if (DIR *dp = opendir(parent.c_str())) { while (struct dirent *ep = readdir(dp)) if (ep->d_name[0] != '.') add_recursively(parent + "/" + ep->d_name); closedir(dp); } else throw std::runtime_error(parent + std::string(": Couldn't open the directory.")); } }
static svn_error_t * new_node_record(void **node_baton, apr_hash_t *headers, void *revision_baton, apr_pool_t *pool) { struct revision_baton *rb = revision_baton; const struct svn_delta_editor_t *commit_editor = rb->pb->commit_editor; void *commit_edit_baton = rb->pb->commit_edit_baton; struct node_baton *nb; apr_hash_index_t *hi; void *child_baton; const char *nb_dirname; nb = apr_pcalloc(rb->pool, sizeof(*nb)); nb->rb = rb; nb->is_added = FALSE; nb->copyfrom_path = NULL; nb->copyfrom_url = NULL; nb->copyfrom_rev = SVN_INVALID_REVNUM; nb->prop_changes = apr_hash_make(rb->pool); /* If the creation of commit_editor is pending, create it now and open_root on it; also create a top-level directory baton. */ if (!commit_editor) { /* The revprop_table should have been filled in with important information like svn:log in set_revision_property. We can now use it all this information to create our commit_editor. But first, clear revprops that we aren't allowed to set with the commit_editor. We'll set them separately using the RA API after closing the editor (see close_revision). */ svn_hash_sets(rb->revprop_table, SVN_PROP_REVISION_AUTHOR, NULL); svn_hash_sets(rb->revprop_table, SVN_PROP_REVISION_DATE, NULL); SVN_ERR(svn_ra__register_editor_shim_callbacks(rb->pb->session, get_shim_callbacks(rb, rb->pool))); SVN_ERR(svn_ra_get_commit_editor3(rb->pb->session, &commit_editor, &commit_edit_baton, rb->revprop_table, commit_callback, revision_baton, NULL, FALSE, rb->pool)); rb->pb->commit_editor = commit_editor; rb->pb->commit_edit_baton = commit_edit_baton; SVN_ERR(commit_editor->open_root(commit_edit_baton, rb->rev - rb->rev_offset - 1, rb->pool, &child_baton)); LDR_DBG(("Opened root %p\n", child_baton)); /* child_baton corresponds to the root directory baton here */ push_directory(rb, child_baton, "", TRUE /*is_added*/, NULL, SVN_INVALID_REVNUM); } for (hi = apr_hash_first(rb->pool, headers); hi; hi = apr_hash_next(hi)) { const char *hname = svn__apr_hash_index_key(hi); const char *hval = svn__apr_hash_index_val(hi); /* Parse the different kinds of headers we can encounter and stuff them into the node_baton for writing later */ if (strcmp(hname, SVN_REPOS_DUMPFILE_NODE_PATH) == 0) nb->path = apr_pstrdup(rb->pool, hval); if (strcmp(hname, SVN_REPOS_DUMPFILE_NODE_KIND) == 0) nb->kind = strcmp(hval, "file") == 0 ? svn_node_file : svn_node_dir; if (strcmp(hname, SVN_REPOS_DUMPFILE_NODE_ACTION) == 0) { if (strcmp(hval, "add") == 0) nb->action = svn_node_action_add; if (strcmp(hval, "change") == 0) nb->action = svn_node_action_change; if (strcmp(hval, "delete") == 0) nb->action = svn_node_action_delete; if (strcmp(hval, "replace") == 0) nb->action = svn_node_action_replace; } if (strcmp(hname, SVN_REPOS_DUMPFILE_TEXT_DELTA_BASE_MD5) == 0) nb->base_checksum = apr_pstrdup(rb->pool, hval); if (strcmp(hname, SVN_REPOS_DUMPFILE_NODE_COPYFROM_REV) == 0) nb->copyfrom_rev = atoi(hval); if (strcmp(hname, SVN_REPOS_DUMPFILE_NODE_COPYFROM_PATH) == 0) nb->copyfrom_path = apr_pstrdup(rb->pool, hval); } nb_dirname = svn_relpath_dirname(nb->path, pool); if (svn_path_compare_paths(nb_dirname, rb->db->relpath) != 0) { char *ancestor_path; apr_size_t residual_close_count; apr_array_header_t *residual_open_path; int i; apr_size_t n; /* Before attempting to handle the action, call open_directory for all the path components and set the directory baton accordingly */ ancestor_path = svn_relpath_get_longest_ancestor(nb_dirname, rb->db->relpath, pool); residual_close_count = svn_path_component_count(svn_relpath_skip_ancestor(ancestor_path, rb->db->relpath)); residual_open_path = svn_path_decompose(svn_relpath_skip_ancestor(ancestor_path, nb_dirname), pool); /* First close all as many directories as there are after skip_ancestor, and then open fresh directories */ for (n = 0; n < residual_close_count; n ++) { /* Don't worry about destroying the actual rb->db object, since the pool we're using has the lifetime of one revision anyway */ LDR_DBG(("Closing dir %p\n", rb->db->baton)); SVN_ERR(commit_editor->close_directory(rb->db->baton, rb->pool)); rb->db = rb->db->parent; } for (i = 0; i < residual_open_path->nelts; i ++) { char *relpath_compose = svn_relpath_join(rb->db->relpath, APR_ARRAY_IDX(residual_open_path, i, const char *), rb->pool); SVN_ERR(commit_editor->open_directory(relpath_compose, rb->db->baton, rb->rev - rb->rev_offset - 1, rb->pool, &child_baton)); LDR_DBG(("Opened dir %p\n", child_baton)); push_directory(rb, child_baton, relpath_compose, TRUE /*is_added*/, NULL, SVN_INVALID_REVNUM); } }
/* Walk a path string, either changing directories or finding the right path If mode is WALK_CHDIR, the result of this function is entering into the new directory on success, or the old directory being returned on failure. If mode is WALK_OPEN, the result of this function is the directory remains unchanged and a pointer to the directory entry for the requested file or directory is returned. If it is a file, the directory entry for the file itself is returned. If it is a directory, the directory entry of the first file or directory inside that directory is returned. The type specifier allows a person to specify that only a directory or file should be returned. This works for WALK_OPEN only. */ static int recurse_path(const char * const path, int mode, directory_entry_t **dirent, int type) { int ret = DFS_ESUCCESS; char token[MAX_FILENAME_LEN+1]; char *cur_path = (char *)path; uint32_t dir_stack[MAX_DIRECTORY_DEPTH]; uint32_t dir_loc = directory_top; int last_type = TYPE_ANY; int ignore = 1; // Do not, by default, read again during the first while /* Save directory stack */ memcpy(dir_stack, directories, sizeof(uint32_t) * MAX_DIRECTORY_DEPTH); /* Grab first token, make sure it isn't root */ cur_path = get_next_token(cur_path, token); if(strcmp(token, "/") == 0) { /* It is an absolute path */ clear_directory(); /* Ensure that we remember this as a directory */ last_type = TYPE_DIR; /* We need to read through the first while loop */ ignore = 0; } /* Loop through the rest */ while(cur_path || ignore) { /* Grab out the next token */ if(!ignore) { cur_path = get_next_token(cur_path, token); } ignore = 0; if( (token[0] == '/' || token[0] == '.') ) { if(token[1] == '.') pop_directory();/* Up one directory */ last_type = TYPE_DIR; } else { /* Find directory entry, push */ directory_entry_t *tmp_node = find_dirent(token, peek_directory()); if(tmp_node) { /* Grab node, make sure it is a directory, push subdirectory, try again! */ directory_entry_t node; grab_sector(tmp_node, &node); uint32_t flags = get_flags(&node); if(FILETYPE(flags) == FLAGS_DIR) { /* Push subdirectory onto stack and loop */ push_directory(get_first_entry(&node)); last_type = TYPE_DIR; } else { if(mode == WALK_CHDIR) { /* Not found, this is a file */ ret = DFS_ENOFILE; break; } else { last_type = TYPE_FILE; /* Only count if this is the last thing we are doing */ if(!cur_path) { /* Push file entry onto stack in preparation of a return */ push_directory(tmp_node); } else { /* Not found, this is a file */ ret = DFS_ENOFILE; break; } } } } else { /* Not found! */ ret = DFS_ENOFILE; break; } } } if(type != TYPE_ANY && type != last_type) { /* Found an entry, but it was the wrong type! */ ret = DFS_ENOFILE; } if(mode == WALK_OPEN) { /* Must return the node found if we found one */ if(ret == DFS_ESUCCESS && dirent) { *dirent = peek_directory(); } } if(mode == WALK_OPEN || ret != DFS_ESUCCESS) { /* Restore stack */ directory_top = dir_loc; memcpy(directories, dir_stack, sizeof(uint32_t) * MAX_DIRECTORY_DEPTH); } return ret; }