term_t bif_list_dir3_0_1(term_t Dir, process_t *ctx) { apr_status_t rs; apr_pool_t *p; const char *path; apr_dir_t *dir; term_t r = nil; term_t cons = nil; apr_uint32_t wanted = APR_FINFO_MTIME | APR_FINFO_CTIME | APR_FINFO_ATIME | APR_FINFO_NAME | APR_FINFO_SIZE | APR_FINFO_TYPE | APR_FINFO_USER | APR_FINFO_GROUP | APR_FINFO_PROT; if (!is_string(Dir)) return A_BADARG; apr_pool_create(&p, 0); path = ltoz(Dir, p); rs = apr_dir_open(&dir, path, p); if (rs == 0) { apr_finfo_t fi; for (;;) { rs = apr_dir_read(&fi, wanted, dir); if (rs == 0 || APR_STATUS_IS_INCOMPLETE(rs)) { term_t file_info = make_file_info(&fi, proc_gc_pool(ctx)); lst_add(r, cons, file_info, proc_gc_pool(ctx)); } else if (APR_STATUS_IS_ENOENT(rs)) { rs = 0; break; } } apr_dir_close(dir); } if (rs != 0) result(make_tuple2(A_ERROR, decipher_status(rs), proc_gc_pool(ctx))); else result(make_tuple2(A_OK, r, proc_gc_pool(ctx))); apr_pool_destroy(p); return AI_OK; }
/* Find all files matching the specified pattern */ APR_DECLARE(apr_status_t) apr_match_glob(const char *pattern, apr_array_header_t **result, apr_pool_t *p) { apr_dir_t *dir; apr_finfo_t finfo; apr_status_t rv; char *path; /* XXX So, this is kind of bogus. Basically, I need to strip any leading * directories off the pattern, but there is no portable way to do that. * So, for now we just find the last occurance of '/' and if that doesn't * return anything, then we look for '\'. This means that we could * screw up on unix if the pattern is something like "foo\.*" That '\' * isn't a directory delimiter, it is a part of the filename. To fix this, * we really need apr_filepath_basename, which will be coming as soon as * I get to it. rbb */ char *idx = strrchr(pattern, '/'); if (idx == NULL) { idx = strrchr(pattern, '\\'); } if (idx == NULL) { path = "."; } else { path = apr_pstrndup(p, pattern, idx - pattern); pattern = idx + 1; } *result = apr_array_make(p, 0, sizeof(char *)); rv = apr_dir_open(&dir, path, p); if (rv != APR_SUCCESS) { return rv; } while (apr_dir_read(&finfo, APR_FINFO_NAME, dir) == APR_SUCCESS) { if (apr_fnmatch(pattern, finfo.name, 0) == APR_SUCCESS) { *(const char **)apr_array_push(*result) = apr_pstrdup(p, finfo.name); } } apr_dir_close(dir); return APR_SUCCESS; }
term_t bif_list_dir2_1(term_t Dir, process_t *ctx) { apr_status_t rs; apr_pool_t *p; const char *path; apr_dir_t *dir; term_t r = nil; if (!is_string(Dir)) return A_BADARG; apr_pool_create(&p, 0); path = ltoz(Dir, p); rs = apr_dir_open(&dir, path, p); if (rs == 0) { term_t cons = nil; apr_finfo_t fi; for (;;) { term_t v; term_t name; rs = apr_dir_read(&fi, APR_FINFO_NAME | APR_FINFO_SIZE, dir); if (rs != 0) break; name = ztol(fi.name, proc_gc_pool(ctx)); if (fi.filetype == APR_DIR) v = make_tuple2(A_DIR, name, proc_gc_pool(ctx)); else if (fi.filetype == APR_REG) v = make_tuple3(A_FILE, name, intnum(fi.size), proc_gc_pool(ctx)); //TODO: large size else v = make_tuple2(A_UNKNOWN, name, proc_gc_pool(ctx)); lst_add(r, cons, v, proc_gc_pool(ctx)); } apr_dir_close(dir); } if (rs != 0 && !APR_STATUS_IS_ENOENT(rs)) result(make_tuple2(A_ERROR, decipher_status(rs), proc_gc_pool(ctx))); else result(make_tuple2(A_OK, r, proc_gc_pool(ctx))); apr_pool_destroy(p); return AI_OK; }
static void test_rewind(abts_case *tc, void *data) { apr_dir_t *dir; apr_finfo_t first, second; APR_ASSERT_SUCCESS(tc, "apr_dir_open failed", apr_dir_open(&dir, "data", p)); APR_ASSERT_SUCCESS(tc, "apr_dir_read failed", apr_dir_read(&first, APR_FINFO_DIRENT, dir)); APR_ASSERT_SUCCESS(tc, "apr_dir_rewind failed", apr_dir_rewind(dir)); APR_ASSERT_SUCCESS(tc, "second apr_dir_read failed", apr_dir_read(&second, APR_FINFO_DIRENT, dir)); APR_ASSERT_SUCCESS(tc, "apr_dir_close failed", apr_dir_close(dir)); ABTS_STR_EQUAL(tc, first.name, second.name); }
List* read_dir(apr_pool_t* pool, List* file_list, const char* dir_path, int* count, error_messages_t* error_messages){ apr_status_t rv; char errorbuf [255]; apr_dir_t *dir; apr_finfo_t filef; char* file_path; rv = apr_dir_open(&dir, dir_path, pool); if (rv != 0){ apr_strerror(rv, (char *)&errorbuf, 255); error_messages_add(error_messages, ERROR,apr_psprintf(pool, "Error opening directory (%s) (%d)", dir_path, rv), errorbuf); return NULL; } //Read file is directory while (apr_dir_read(&filef, APR_FINFO_TYPE | APR_FINFO_NAME | APR_FINFO_MTIME, dir) == 0){ file_path = apr_pstrcat(pool, dir_path, "/", filef.name, NULL); if (file_path == NULL){ return NULL; ///BIG ERROR } //Is a Directory if (filef.filetype == APR_DIR){ if(filef.name[0] != '.'){ file_list = read_dir(pool, file_list, file_path, count, error_messages); } } //Is a File if (filef.filetype == APR_REG){ List* file_list_new; (*count)++; file_list_new = apr_pcalloc(pool, sizeof(List)); file_list->file.path = file_path; file_list->file.mtime = filef.mtime; file_list->file.type = get_file_ext(pool,file_path); file_list->next = file_list_new; file_list = file_list_new; } } rv = apr_dir_close(dir); return file_list; }
/* * check if arg is a valid directory on the file system */ const char *oidc_valid_dir(apr_pool_t *pool, const char *arg) { char s_err[STR_ERROR_MAX]; apr_dir_t *dir = NULL; apr_status_t rc = APR_SUCCESS; /* ensure the directory exists */ if ((rc = apr_dir_open(&dir, arg, pool)) != APR_SUCCESS) { return apr_psprintf(pool, "cannot access directory '%s' (%s)", arg, apr_strerror(rc, s_err, STR_ERROR_MAX)); } /* and cleanup... */ if ((rc = apr_dir_close(dir)) != APR_SUCCESS) { return apr_psprintf(pool, "cannot close directory '%s' (%s)", arg, apr_strerror(rc, s_err, STR_ERROR_MAX)); } return NULL; }
SWITCH_DECLARE(switch_status_t) switch_dir_open(switch_dir_t ** new_dir, const char *dirname, switch_memory_pool_t *pool) { switch_status_t status; switch_dir_t *dir = malloc(sizeof(*dir)); if (!dir) { *new_dir = NULL; return SWITCH_STATUS_FALSE; } memset(dir, 0, sizeof(*dir)); if ((status = apr_dir_open(&(dir->dir_handle), dirname, pool)) == APR_SUCCESS) { *new_dir = dir; } else { free(dir); *new_dir = NULL; } return status; }
bool find(const std::string& name, FilePath& result, bool recursive=true) { bool found = false; if (dir && APR_SUCCESS == check_apr(apr_dir_open(&dir, dirname.c_str(), mPool))) { // iterate over directory: while ((!found) && APR_SUCCESS == (apr_dir_read(&dirent, APR_FINFO_TYPE|APR_FINFO_NAME, dir))) { //printf("test %s %s\n", dirname.c_str(), dirent.name); if (dirent.filetype == APR_REG && dirent.name && std::string(dirent.name) == name) { result.file(dirent.name); result.path(dirname); found = true; break; } else if (recursive && dirent.filetype == APR_DIR && dirent.name && dirent.name[0] != '.') { Path path(dirname + dirent.name + AL_FILE_DELIMITER); found = path.find(name, result, true); } } } else { printf("couldn't open directory %s\n", dirname.c_str()); } return found; }
SWITCH_DECLARE(switch_status_t) switch_directory_exists(const char *dirname, switch_memory_pool_t *pool) { apr_dir_t *dir_handle; switch_memory_pool_t *our_pool = NULL; switch_status_t status; if (!pool) { switch_core_new_memory_pool(&our_pool); pool = our_pool; } if ((status = apr_dir_open(&dir_handle, dirname, pool)) == APR_SUCCESS) { apr_dir_close(dir_handle); } if (our_pool) { switch_core_destroy_memory_pool(&our_pool); } return status; }
int glob(const std::string& regex, FileList& result, bool recursive=true) { std::regex e(regex); if (dir && APR_SUCCESS == check_apr(apr_dir_open(&dir, dirname.c_str(), mPool))) { // iterate over directory: while (APR_SUCCESS == (apr_dir_read(&dirent, APR_FINFO_TYPE|APR_FINFO_NAME, dir))) { //printf("test %s %s\n", dirname.c_str(), dirent.name); if (dirent.filetype == APR_REG && dirent.name && std::regex_match(dirname+dirent.name,e) ) { FilePath res; res.file(dirent.name); res.path(dirname); result.add(res); } else if (recursive && dirent.filetype == APR_DIR && dirent.name && dirent.name[0] != '.') { Path path(dirname + dirent.name + AL_FILE_DELIMITER); path.glob(regex, result, true); } } } else { AL_WARN("couldn't open directory %s", dirname.c_str()); } return result.count(); }
static int add_ldap_certs(abts_case *tc) { apr_status_t status; apr_dir_t *thedir; apr_finfo_t dirent; apr_ldap_err_t *result = NULL; if ((status = apr_dir_open(&thedir, DIRNAME, p)) == APR_SUCCESS) { apr_ldap_opt_tls_cert_t *cert = (apr_ldap_opt_tls_cert_t *)apr_pcalloc(p, sizeof(apr_ldap_opt_tls_cert_t)); do { status = apr_dir_read(&dirent, APR_FINFO_MIN | APR_FINFO_NAME, thedir); if (APR_STATUS_IS_INCOMPLETE(status)) { continue; /* ignore un-stat()able files */ } else if (status != APR_SUCCESS) { break; } if (strstr(dirent.name, ".der")) { cert->type = APR_LDAP_CA_TYPE_DER; cert->path = apr_pstrcat (p, DIRNAME, "/", dirent.name, NULL); apr_ldap_set_option(p, NULL, APR_LDAP_OPT_TLS_CERT, (void *)cert, &result); ABTS_TRUE(tc, result->rc == LDAP_SUCCESS); } if (strstr(dirent.name, ".b64")) { cert->type = APR_LDAP_CA_TYPE_BASE64; cert->path = apr_pstrcat (p, DIRNAME, "/", dirent.name, NULL); apr_ldap_set_option(p, NULL, APR_LDAP_OPT_TLS_CERT, (void *)cert, &result); ABTS_TRUE(tc, result->rc == LDAP_SUCCESS); } } while (1); apr_dir_close(thedir); } return 0; }
bool UmcFramework::LoadScenarios() { apr_dir_t* pDir; apr_finfo_t finfo; apr_status_t rv; const char* pDirPath; pDirPath = apt_dir_layout_path_compose(m_pDirLayout,APT_LAYOUT_CONF_DIR,"umc-scenarios",m_pPool); if(!pDirPath) { apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Compose Config File Path"); return false; } apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Enter Directory [%s]",pDirPath); rv = apr_dir_open(&pDir,pDirPath,m_pPool); if(rv != APR_SUCCESS) { apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"No Such Directory %s",pDirPath); return false; } while(apr_dir_read(&finfo,APR_FINFO_NAME,pDir) == APR_SUCCESS) { if(apr_fnmatch("*.xml",finfo.name,0) == APR_SUCCESS) { char* pFilePath; if(apr_filepath_merge(&pFilePath,pDirPath,finfo.name,APR_FILEPATH_NATIVE,m_pPool) == APR_SUCCESS) { LoadScenario(pFilePath); } } } apr_dir_close(pDir); return true; }
/* Update cursor to point to next top-level directory to search, if any. */ static int next_directory(vtab_cursor *p_cur) { vtab *p_vt = (vtab*)((sqlite3_vtab_cursor*)p_cur)->pVtab; /* Get the next path name in the search list. If there isn't next_path() * will return 0, as do we. */ if (next_path(p_cur) == 0) { /* No more directories to search. End of result set. */ p_cur->eof = 1; return SQLITE_OK; } /* Now try to open the directory. If it can be opended, set up the dirent to ** return as a row in the rowset. */ /* ZERO-FILL DIRENT: Very important to zero-fill here, otherwise we may have ** dirent.fname and/or dirent.name members pointing to invalid addresses ** after apr_stat(). Our code depends in being able to check NULL status of ** these members, so all pointers must be NULL by default. */ memset(&p_cur->current_node->dirent, 0, sizeof(apr_finfo_t)); /* Check to see if the directory exists */ p_cur->status = apr_stat( &p_cur->current_node->dirent, p_cur->current_node->path, APR_FINFO_TYPE, p_cur->pool ); if (p_cur->status != APR_SUCCESS) { /* Directory does not exist */ p_cur->eof = 1; if (p_vt->base.zErrMsg != NULL) { sqlite3_free(p_vt->base.zErrMsg); } printf( "Invalid directory: %s\n", p_cur->current_node->path ); p_vt->base.zErrMsg = sqlite3_mprintf( "Invalid directory: %s", p_cur->current_node->path ); return SQLITE_ERROR; } else { /* If this entry is a directory, then open it */ if (p_cur->current_node->dirent.filetype == APR_DIR) { p_cur->status = apr_dir_open( &p_cur->current_node->dir, p_cur->current_node->path, p_cur->pool); if (p_cur->status != APR_SUCCESS) { /* Could not open directory */ p_cur->eof = 1; if (p_vt->base.zErrMsg != NULL) { sqlite3_free(p_vt->base.zErrMsg); } printf("Could not open directory: %s\n", p_cur->current_node->path ); p_vt->base.zErrMsg = sqlite3_mprintf( "Could not open directory: %s", p_cur->current_node->path ); return SQLITE_ERROR; } } else { /** Set dir to NULL to indicate that this entry is NOT a * directory. In this case, we have a top-level file, not a * top-level directory. vt_next() will pick up on this and do the * Right Thing. */ p_cur->current_node->dir = NULL; } } /** Move cursor to first row: get the directory information on the top level * directory. */ apr_stat( &p_cur->current_node->dirent, p_cur->current_node->path, APR_FINFO_DIRENT|APR_FINFO_TYPE|APR_FINFO_NAME, p_cur->pool ); return SQLITE_OK; }
const char *fcgi_config_make_dynamic_dir(pool *p, const int wax) { const char *err; pool *tp; fcgi_dynamic_dir = ap_pstrcat(p, fcgi_socket_dir, "/dynamic", NULL); if ((err = fcgi_config_make_dir(p, fcgi_dynamic_dir))) return ap_psprintf(p, "can't create dynamic directory \"%s\": %s", fcgi_dynamic_dir, err); /* Don't step on a running server unless its OK. */ if (!wax) return NULL; #ifdef APACHE2 { apr_dir_t * dir; apr_finfo_t finfo; if (apr_pool_create(&tp, p)) return "apr_pool_create() failed"; if (apr_dir_open(&dir, fcgi_dynamic_dir, tp)) return "apr_dir_open() failed"; /* delete the contents */ while (apr_dir_read(&finfo, APR_FINFO_NAME, dir) == APR_SUCCESS) { if (strcmp(finfo.name, ".") == 0 || strcmp(finfo.name, "..") == 0) continue; apr_file_remove(finfo.name, tp); } } #else /* !APACHE2 */ { DIR *dp; struct dirent *dirp = NULL; tp = ap_make_sub_pool(p); dp = ap_popendir(tp, fcgi_dynamic_dir); if (dp == NULL) { ap_destroy_pool(tp); return ap_psprintf(p, "can't open dynamic directory \"%s\": %s", fcgi_dynamic_dir, strerror(errno)); } /* delete the contents */ while ((dirp = readdir(dp)) != NULL) { if (strcmp(dirp->d_name, ".") == 0 || strcmp(dirp->d_name, "..") == 0) continue; unlink(ap_pstrcat(tp, fcgi_dynamic_dir, "/", dirp->d_name, NULL)); } } #endif /* !APACHE2 */ ap_destroy_pool(tp); return NULL; }
static int mediarss_index_directory(request_rec* r) { apr_status_t status; apr_dir_t* dir; apr_finfo_t dirent; if ((status = apr_dir_open(&dir, r->filename, r->pool)) != APR_SUCCESS) { ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, "Can't open directory for index: %s", r->filename); return HTTP_FORBIDDEN; } /* Content header */ char* url; url = ap_construct_url(r->pool, r->uri, r); ap_set_content_type(r, "text/xml; charset=utf-8"); ap_rputs("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n\n", r); if (strcmp(r->args, "format=mediarss") == 0) { ap_rputs("<rss version=\"2.0\" xmlns:media=\"http://search.yahoo.com/mrss/\">\n", r); } else { ap_rputs("<rss version=\"2.0\">\n", r); } ap_rputs(" <channel>\n", r); ap_rvputs(r, " <title>Index of ", url, "</title>\n", NULL); ap_rvputs(r, " <link>", url, "</link>\n", NULL); /* Collect information about the files in the directory */ while (1) { status = apr_dir_read(&dirent, APR_FINFO_MIN | APR_FINFO_NAME, dir); if (APR_STATUS_IS_INCOMPLETE(status)) { continue; /* ignore un-stat()able files */ } else if (status != APR_SUCCESS) { break; } /* We are only interested in regular files. TODO Deal with symlinks. */ if (dirent.filetype == APR_REG) { request_rec* rr; rr = ap_sub_req_lookup_dirent(&dirent, r, AP_SUBREQ_NO_ARGS, NULL); if (rr != NULL) { if (rr->finfo.filetype == APR_REG && rr->status == HTTP_OK) { /* In case of media rss, only include the item if it is a media type */ if (strcmp(r->args, "format=mediarss") == 0 && mediarss_is_media_content(rr->content_type) == 0) { continue; } char size[16]; snprintf(size, sizeof(size), "%d", dirent.size); char date[APR_RFC822_DATE_LEN]; apr_rfc822_date(date, dirent.mtime); char* guid = ap_md5(r->pool, (unsigned char*) apr_pstrcat(r->pool, url, dirent.name, NULL)); ap_rputs(" <item>\n", r); ap_rvputs(r, " <guid>", guid, "</guid>\n", NULL); ap_rvputs(r, " <title>", dirent.name, "</title>\n", NULL); ap_rvputs(r, " <pubDate>", date, "</pubDate>\n", NULL); ap_rvputs(r, " <enclosure url=\"", url, dirent.name, "\" length=\"", size, "\"\n", NULL); ap_rvputs(r, " type=\"", rr->content_type, "\"/>\n", NULL); if (strcmp(r->args, "format=mediarss") == 0) { ap_rvputs(r, " <media:content url=\"", url, dirent.name, "\" fileSize=\"", size, "\"\n", NULL); ap_rvputs(r, " type=\"", rr->content_type, "\"/>\n", NULL); } ap_rputs(" </item>\n", r); } ap_destroy_sub_req(rr); } } } /* Content footer */ ap_rputs(" </channel>\n", r); ap_rputs("</rss>\n", r); apr_dir_close(dir); return OK; }
static int vt_next(sqlite3_vtab_cursor *cur) { vtab_cursor *p_cur = (vtab_cursor*)cur; vtab* p_vt = (vtab*)cur->pVtab; /** This is a rather involved function. It is the core of this virtual * table. This function recursively reads down into a directory. It * automatically decends into a directory when it finds one, and * automatically ascends out of it when it has read all of its entries. * The logic is as follows: * The p_cur->current_node (a filenode struct) points to the current file * entry (given by the APR handle p_cur->current_node->dirent) and its * associated directory (given by the APR handle * p_cur->current_node->dirent) * We attempt to read the next entry in p_cur->current_node->dir, filling * the p_cur->current_node->dirent. If we succeed, then we have either a * file or a directory. If we have a directory, then we descend into it. If * we have a file, we proceed as usual. In either case, the dirent entry * will consitute a row in the result set, as we have done as much as we * have to and can exit the function. Our only job is to get to the next * valid file or directory entry to return as the current row in the * rowset. * If there are no more entries in the current directory, then we * deallocate p_cur->current_node and proceed up one directory (given by * p_cur->current_node->parent). We thus set p_cur->current_node to * p_cur->current_node->parent, and start over again. */ read_next_entry: /** First, check for a special case where the top level directory is * actually a top-level file. In this case, we rely that * p_cur->current_node->dir == NULL (set by next_directory()). If this is * true, resort to next_directory(). */ if (p_cur->current_node->dir == NULL) { return next_directory(p_cur); } /* Read the next directory entry. */ /* Increment the current row count. */ p_cur->count += 1; struct filenode* d = p_cur->current_node; struct filenode* prev_d = d; reread_next_entry: /* Read the next entry in the directory (d->dir). Fills the d->dirent member. */ if ( apr_dir_read( &d->dirent, APR_FINFO_DIRENT|APR_FINFO_PROT|APR_FINFO_TYPE| APR_FINFO_NAME|APR_FINFO_SIZE, d->dir) != APR_SUCCESS ) { /** If we get here, the call failed. There are no more entries in * directory. */ /** If we are at the top level directory */ if (d->parent == NULL) { /** We are done with this directory. See if there is another * top-level directory to search. * * If there is not another directory, next_directory() will have set * eof=1. We are at the end of the result set. If there is another * directory to search, then it will load the next dirent for * us. Either way, we have nothing left to do here. */ return next_directory(p_cur); } else { /** There is a parent directory that we still have to search * through. Free this filenode and resume iterating through the * parent. */ d = move_up_directory(p_cur); /* Start over, reading the next entry from parent. */ goto read_next_entry; } } /* If the current dirent is a directory, then descend into it. */ if (d->dirent.filetype == APR_DIR) { /* Skip . and .. entries */ if (d->dirent.name != NULL) { if (strcmp(d->dirent.name, ".") == 0 || strcmp(d->dirent.name, "..") == 0) { goto read_next_entry; } } /* Create a new child directory node */ /* Combine the path and file names to get full path */ char path[1024]; sprintf(&path[0], "%s/%s", d->path, d->dirent.name); /* Allocate space for new filenode and initlialize members. */ d = malloc(sizeof(struct filenode)); d->path = strdup(path); d->parent = p_cur->current_node; /* See note ZERO-FILL DIRENT below. */ memset(&d->dirent, 0, sizeof(apr_finfo_t)); /* Set current pointer to it. */ p_cur->current_node = d; /* Clear the pool memory associated with the path string allocated above. */ apr_pool_clear(p_cur->tmp_pool); /* Open the directory */ if ((p_cur->status = apr_dir_open(&d->dir, d->path, p_cur->pool)) != APR_SUCCESS) { /* Problem. Couldn't open directory. */ fprintf( stderr, "Failed to open directory: %s\n", p_cur->current_node->path ); /* Set this to null to move_up_directory() doesn't try to * apr_close() it (->core dump) */ p_cur->current_node->dir = NULL; /* Skip to next entry */ deallocate_filenode(d); p_cur->current_node = d = prev_d; goto reread_next_entry; } /* Else we were able to open directory. Update the currnet dirent info ** to that of the opened directory. This is our next row in the result ** set. */ apr_stat( &d->dirent, d->path, APR_FINFO_DIRENT|APR_FINFO_TYPE|APR_FINFO_NAME, p_cur->pool ); } return SQLITE_OK; }
/** Load UniMRCP client */ static apt_bool_t unimrcp_client_load(unimrcp_client_loader_t *loader, const char *dir_path, const char *file_name, apr_pool_t *pool) { apr_xml_doc *doc; const apr_xml_elem *elem; const apr_xml_elem *root; const apr_xml_attr *attr; const char *file_path; const char *version = NULL; const char *subfolder = NULL; if(!dir_path || !file_name) { return FALSE; } if(*dir_path == '\0') { file_path = file_name; } else { file_path = apr_psprintf(pool,"%s/%s",dir_path,file_name); } /* Parse XML document */ doc = unimrcp_client_doc_parse(file_path,pool); if(!doc) { return FALSE; } root = doc->root; /* Match document name */ if(!root || strcasecmp(root->name,"unimrcpclient") != 0) { apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Document <%s>",root->name); return FALSE; } /* Read attributes */ for(attr = root->attr; attr; attr = attr->next) { if(strcasecmp(attr->name,"version") == 0) { version = attr->value; } else if(strcasecmp(attr->name,"subfolder") == 0) { subfolder = attr->value; } } /* Check version number first */ if(!version) { apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Version"); return FALSE; } loader->doc = doc; /* Navigate through document */ for(elem = root->first_child; elem; elem = elem->next) { if(strcasecmp(elem->name,"properties") == 0) { unimrcp_client_properties_load(loader,elem); } else if(strcasecmp(elem->name,"components") == 0) { unimrcp_client_components_load(loader,elem); } else if(strcasecmp(elem->name,"settings") == 0) { unimrcp_client_settings_load(loader,elem); } else if(strcasecmp(elem->name,"profiles") == 0) { unimrcp_client_profiles_load(loader,elem); } else { apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Element <%s>",elem->name); } } if(subfolder && subfolder != '\0') { apr_dir_t *dir; apr_finfo_t finfo; apr_status_t rv; dir_path = apr_psprintf(pool,"%s/%s",dir_path,subfolder); apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Enter Directory [%s]",dir_path); rv = apr_dir_open(&dir,dir_path,pool); if(rv == APR_SUCCESS) { while(apr_dir_read(&finfo, APR_FINFO_NAME, dir) == APR_SUCCESS) { if(apr_fnmatch("*.xml", finfo.name, 0) == APR_SUCCESS) { unimrcp_client_load(loader,dir_path,finfo.name,pool); } } apr_dir_close(dir); apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Leave Directory [%s]",dir_path); } else { apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"No Such Directory %s",dir_path); } } return TRUE; }
void nx_expr_proc__xm_fileop_file_remove(nx_expr_eval_ctx_t *eval_ctx, nx_module_t *module, nx_expr_arg_list_t *args) { nx_expr_arg_t *arg; nx_value_t file; apr_status_t rv; apr_pool_t *pool = NULL; apr_dir_t *dir; nx_exception_t e; nx_string_t *dirname = NULL; nx_string_t *fname = NULL; char *filename; char *idx; int flags = 0; apr_finfo_t finfo; nx_expr_arg_t *older; nx_value_t olderval; apr_time_t older_time = 0LL; ASSERT(module != NULL); ASSERT(args != NULL); arg = NX_DLIST_FIRST(args); ASSERT(arg != NULL); ASSERT(arg->expr != NULL); nx_expr_evaluate(eval_ctx, &file, arg->expr); if ( file.defined != TRUE ) { throw_msg("'file' is undef"); } try { if ( file.type != NX_VALUE_TYPE_STRING ) { throw_msg("string type required for 'file'"); } older = NX_DLIST_NEXT(arg, link); if ( older != NULL ) { ASSERT(older->expr != NULL); nx_expr_evaluate(eval_ctx, &olderval, older->expr); if ( olderval.type != NX_VALUE_TYPE_DATETIME ) { nx_value_kill(&olderval); throw_msg("datetime type required for 'older'"); } if ( olderval.defined == TRUE ) { older_time = olderval.datetime; } } if ( apr_fnmatch_test(file.string->buf) != 0 ) { // we have wildcards, expand it pool = nx_pool_create_core(); filename = file.string->buf; idx = strrchr(filename, '/'); #ifndef WIN32 flags = APR_FNM_CASE_BLIND; if ( idx == NULL ) { idx = strrchr(filename, '\\'); } #endif if ( idx == NULL ) { dirname = nx_string_create("."NX_DIR_SEPARATOR, -1); } else { dirname = nx_string_create(filename, (int) (idx + 1 - filename)); filename = idx + 1; } CHECKERR_MSG(apr_dir_open(&dir, dirname->buf, pool), "failed to open directory: %s", dirname->buf); fname = nx_string_new(); while ( apr_dir_read(&finfo, APR_FINFO_NAME | APR_FINFO_TYPE | APR_FINFO_CTIME, dir) == APR_SUCCESS ) { if ( finfo.filetype == APR_REG ) { log_debug("checking '%s' against wildcard '%s':", finfo.name, filename); if ( apr_fnmatch(filename, finfo.name, flags) == APR_SUCCESS ) { nx_string_sprintf(fname, "%s%s", dirname->buf, finfo.name); if ( (older_time == 0) || ((older_time != 0) && (finfo.ctime < older_time)) ) { log_debug("'%s' matches wildcard '%s' and is 'older', removing", fname->buf, file.string->buf); log_info("removing file %s", fname->buf); rv = apr_file_remove(fname->buf, NULL); if ( APR_STATUS_IS_ENOENT(rv) ) { } else if ( rv == APR_SUCCESS ) { } else { log_aprerror(rv, "failed to remove file '%s'", fname->buf); } _reopen_logfile(fname->buf); } } } } nx_string_free(fname); apr_pool_destroy(pool); } else { CHECKERR_MSG(apr_file_remove(file.string->buf, NULL), "failed to remove file '%s'", file.string->buf); } } catch(e) { nx_value_kill(&file); if ( pool != NULL ) { apr_pool_destroy(pool); } if ( dirname != NULL ) { nx_string_free(dirname); } log_exception(e); } }
bool open(const std::string& dirName){ return APR_SUCCESS == check_apr(apr_dir_open(&dir, dirName.c_str(), mPool)); }
Path(const std::string& dirname) : ImplAPR(), dir(NULL), dirname(dirname) { if (APR_SUCCESS != check_apr(apr_dir_open(&dir, dirname.c_str(), mPool))) { //printf("dir %p\n", dir); dir=NULL; } }
int main(int argc, char *argv[]) { char *outname = NULL; FILE *fp; FILE *input_file; char *input_file_name = NULL; char *path_prefix = NULL; int index; int process_self = 0; int verbose = 0; int max_build, accum_build; int max_year, max_month, max_day; int ismodified, filemodified; char prefix[MAX_SYMBOLLENGTH], suffix[MAX_SYMBOLLENGTH]; char modified_suffix[2]; int write_java = 0; /* flag for Java output, 0=.h output, 1=.java output */ /* java package to put revision info in. * REVIEW - I assume if you want Java output you will specify a package. */ char *java_package = NULL; if (argc <= 1) about(); /* collect the options */ prefix[0] = '\0'; suffix[0] = '\0'; for (index = 1; index < argc; index++) { /* check for options */ if (argv[index][0] == '-' #if defined __WIN32__ || defined _Win32 || defined _WIN32 || argv[index][0] == '/' #endif ) { switch (argv[index][1]) { case 'f': { int len; char *ptr = strchr(&argv[index][2], '#'); len = (ptr != NULL) ? (int)(ptr - &argv[index][2]) : (int)strlen(&argv[index][2]); if (len >= MAX_SYMBOLLENGTH) len = MAX_SYMBOLLENGTH - 1; strncpy(prefix, &argv[index][2], len); prefix[len] = '\0'; ptr = (ptr != NULL) ? ptr + 1 : strchr(argv[index], '\0'); len = (int)strlen(ptr); if (len >= MAX_SYMBOLLENGTH) len = MAX_SYMBOLLENGTH - 1; strncpy(suffix, ptr, len); suffix[len] = '\0'; break; } /* case */ case 'i': process_self = 1; break; case 'j': write_java=1; java_package = &argv[index][2]; break; case 'o': outname = &argv[index][2]; break; case 'r': input_file_name = &argv[index][2]; break; case 'p': path_prefix = &argv[index][2]; break; case 'v': verbose = 1; break; default: fprintf(stderr, "Invalid option '%s'\n", argv[index]); about(); } /* switch */ } /* if */ } /* for */ if (outname == NULL) outname = write_java ? "SvnRevision.java" : "uni_revision.h"; if (!process_self && *outname != '\0') remove(outname); /* phase 1: scan through all files and get the highest build number */ max_build = 0; accum_build = 0; /* for RCS / CVS */ max_year = max_month = max_day = 0; ismodified = 0; if(input_file_name) { input_file = fopen(input_file_name, "r"); if (input_file != NULL) { apr_dir_t *dir; apr_finfo_t finfo; apr_status_t rv; apr_pool_t *pool; char *file_path; char dir_path[256]; /* line */ int offset = 0; if(path_prefix) offset = sprintf(dir_path, "%s", path_prefix); else offset = sprintf(dir_path, "../../"); apr_initialize(); apr_pool_create(&pool,NULL); while (fgets(dir_path + offset, sizeof(dir_path) - offset, input_file) != NULL ) { /* read a line */ size_t len = strlen(dir_path)-1; if(dir_path[len] == '\n') dir_path[len] = 0; rv = apr_dir_open(&dir,dir_path,pool); if(rv == APR_SUCCESS) { while (apr_dir_read(&finfo, APR_FINFO_NAME, dir) == APR_SUCCESS) { /* get next file */ if(finfo.filetype != APR_REG) continue; apr_filepath_merge(&file_path,dir_path,finfo.name,0,pool); filemodified = 0; if (strcasecmp(file_path, outname)!=0) processfile(file_path, 0, &max_build, &accum_build, &max_year, &max_month, &max_day, &filemodified); if (filemodified && verbose) fprintf(stderr, "\tNotice: modified file '%s'\n", file_path); ismodified = ismodified || filemodified; } apr_dir_close(dir); } else { fprintf(stderr, "No such directory '%s'\n", dir_path); } } fclose (input_file); apr_pool_destroy(pool); apr_terminate(); } else { fprintf(stderr, "No such input file '%s'\n", input_file_name); } } else { for (index = 1; index < argc; index++) { /* skip the options (already handled) */ if (argv[index][0] == '-' #if defined __WIN32__ || defined _Win32 || defined _WIN32 || argv[index][0] == '/' #endif ) continue; filemodified = 0; if (strcasecmp(argv[index], outname)!=0) processfile(argv[index], 0, &max_build, &accum_build, &max_year, &max_month, &max_day, &filemodified); if (filemodified && verbose) fprintf(stderr, "\tNotice: modified file '%s'\n", argv[index]); ismodified = ismodified || filemodified; } /* for */ } /* also run over the existing header file, if any */ if (process_self && *outname != '\0') processfile(outname, 1, &max_build, &accum_build, &max_year, &max_month, &max_day, NULL/*&ismodified*/); if (accum_build > max_build) max_build = accum_build; modified_suffix[0] = ismodified ? 'M' : '\0'; modified_suffix[1] = '\0'; /* phase 2: write a file with this highest build number */ if (*outname == '\0') { fp = stdout; } else if ((fp = fopen(outname, "w")) == NULL) { fprintf(stderr, "Failed to create output file '%s'\n", outname); return 2; } /* if */ if (*outname != '\0') { /* don't print the comments to stdout */ fprintf(fp, "/* This file was generated by the \"svnrev\" utility\n" " * (http://www.compuphase.com/svnrev.htm).\n" " * You should not modify it manually, as it may be re-generated.\n" " *\n" " * $Revision: %d%s$\n" " * $Date: %04d-%02d-%02d$\n" " */\n\n", max_build, modified_suffix, max_year, max_month, max_day); } /* if */ fprintf(fp, "#ifndef UNI_REVISION_H\n"); fprintf(fp, "#define UNI_REVISION_H\n\n"); fprintf(fp, "#define UNI_REVISION\t\t%d\n", max_build); fprintf(fp, "#define UNI_REVISION_STRING\t\"%s%d%s%s\"\n", prefix, max_build, modified_suffix, suffix); fprintf(fp, "#define UNI_REVISION_DATE\t\"%04d-%02d-%02d\"\n", max_year, max_month, max_day); fprintf(fp, "#define UNI_REVISION_STAMP\t%04d%02d%02dL\n", max_year, max_month, max_day); fprintf(fp, "#define UNI_REVISION_MODIFIED\t%d\n", ismodified); fprintf(fp, "\n#endif /* UNI_REVISION_H */\n"); if (*outname != '\0') fclose(fp); return 0; }
static int check_speling(request_rec *r) { spconfig *cfg; char *good, *bad, *postgood, *url; apr_finfo_t dirent; int filoc, dotloc, urlen, pglen; apr_array_header_t *candidates = NULL; apr_dir_t *dir; cfg = ap_get_module_config(r->per_dir_config, &speling_module); if (!cfg->enabled) { return DECLINED; } /* We only want to worry about GETs */ if (r->method_number != M_GET) { return DECLINED; } /* We've already got a file of some kind or another */ if (r->finfo.filetype != APR_NOFILE) { return DECLINED; } /* Not a file request */ if (r->proxyreq || !r->filename) { return DECLINED; } /* This is a sub request - don't mess with it */ if (r->main) { return DECLINED; } /* * The request should end up looking like this: * r->uri: /correct-url/mispelling/more * r->filename: /correct-file/mispelling r->path_info: /more * * So we do this in steps. First break r->filename into two pieces */ filoc = ap_rind(r->filename, '/'); /* * Don't do anything if the request doesn't contain a slash, or * requests "/" */ if (filoc == -1 || strcmp(r->uri, "/") == 0) { return DECLINED; } /* good = /correct-file */ good = apr_pstrndup(r->pool, r->filename, filoc); /* bad = mispelling */ bad = apr_pstrdup(r->pool, r->filename + filoc + 1); /* postgood = mispelling/more */ postgood = apr_pstrcat(r->pool, bad, r->path_info, NULL); urlen = strlen(r->uri); pglen = strlen(postgood); /* Check to see if the URL pieces add up */ if (strcmp(postgood, r->uri + (urlen - pglen))) { return DECLINED; } /* url = /correct-url */ url = apr_pstrndup(r->pool, r->uri, (urlen - pglen)); /* Now open the directory and do ourselves a check... */ if (apr_dir_open(&dir, good, r->pool) != APR_SUCCESS) { /* Oops, not a directory... */ return DECLINED; } candidates = apr_array_make(r->pool, 2, sizeof(misspelled_file)); dotloc = ap_ind(bad, '.'); if (dotloc == -1) { dotloc = strlen(bad); } while (apr_dir_read(&dirent, APR_FINFO_DIRENT, dir) == APR_SUCCESS) { sp_reason q; /* * If we end up with a "fixed" URL which is identical to the * requested one, we must have found a broken symlink or some such. * Do _not_ try to redirect this, it causes a loop! */ if (strcmp(bad, dirent.name) == 0) { apr_dir_close(dir); return OK; } /* * miscapitalization errors are checked first (like, e.g., lower case * file, upper case request) */ else if (strcasecmp(bad, dirent.name) == 0) { misspelled_file *sp_new; sp_new = (misspelled_file *) apr_array_push(candidates); sp_new->name = apr_pstrdup(r->pool, dirent.name); sp_new->quality = SP_MISCAPITALIZED; } /* * simple typing errors are checked next (like, e.g., * missing/extra/transposed char) */ else if ((cfg->check_case_only == 0) && ((q = spdist(bad, dirent.name)) != SP_VERYDIFFERENT)) { misspelled_file *sp_new; sp_new = (misspelled_file *) apr_array_push(candidates); sp_new->name = apr_pstrdup(r->pool, dirent.name); sp_new->quality = q; } /* * The spdist() should have found the majority of the misspelled * requests. It is of questionable use to continue looking for * files with the same base name, but potentially of totally wrong * type (index.html <-> index.db). * * If you're using MultiViews, and have a file named foobar.html, * which you refer to as "foobar", and someone tried to access * "Foobar", without CheckBasenameMatch, mod_speling won't find it, * because it won't find anything matching that spelling. * With the extension-munging, it would locate "foobar.html". */ else if ((cfg->check_case_only == 0) && (cfg->check_basename_match == 1)) { /* * Okay... we didn't find anything. Now we take out the hard-core * power tools. There are several cases here. Someone might have * entered a wrong extension (.htm instead of .html or vice * versa) or the document could be negotiated. At any rate, now * we just compare stuff before the first dot. If it matches, we * figure we got us a match. This can result in wrong things if * there are files of different content types but the same prefix * (e.g. foo.gif and foo.html) This code will pick the first one * it finds. Better than a Not Found, though. */ int entloc = ap_ind(dirent.name, '.'); if (entloc == -1) { entloc = strlen(dirent.name); } if ((dotloc == entloc) && !strncasecmp(bad, dirent.name, dotloc)) { misspelled_file *sp_new; sp_new = (misspelled_file *) apr_array_push(candidates); sp_new->name = apr_pstrdup(r->pool, dirent.name); sp_new->quality = SP_VERYDIFFERENT; } } } apr_dir_close(dir); if (candidates->nelts != 0) { /* Wow... we found us a mispelling. Construct a fixed url */ char *nuri; const char *ref; misspelled_file *variant = (misspelled_file *) candidates->elts; int i; ref = apr_table_get(r->headers_in, "Referer"); qsort((void *) candidates->elts, candidates->nelts, sizeof(misspelled_file), sort_by_quality); /* * Conditions for immediate redirection: * a) the first candidate was not found by stripping the suffix * AND b) there exists only one candidate OR the best match is not * ambiguous * then return a redirection right away. */ if (variant[0].quality != SP_VERYDIFFERENT && (candidates->nelts == 1 || variant[0].quality != variant[1].quality)) { nuri = ap_escape_uri(r->pool, apr_pstrcat(r->pool, url, variant[0].name, r->path_info, NULL)); if (r->parsed_uri.query) nuri = apr_pstrcat(r->pool, nuri, "?", r->parsed_uri.query, NULL); apr_table_setn(r->headers_out, "Location", ap_construct_url(r->pool, nuri, r)); ap_log_rerror(APLOG_MARK, APLOG_INFO, APR_SUCCESS, r, ref ? "Fixed spelling: %s to %s from %s" : "Fixed spelling: %s to %s%s", r->uri, nuri, (ref ? ref : "")); return HTTP_MOVED_PERMANENTLY; } /* * Otherwise, a "[300] Multiple Choices" list with the variants is * returned. */ else { apr_pool_t *p; apr_table_t *notes; apr_pool_t *sub_pool; apr_array_header_t *t; apr_array_header_t *v; if (r->main == NULL) { p = r->pool; notes = r->notes; } else { p = r->main->pool; notes = r->main->notes; } if (apr_pool_create(&sub_pool, p) != APR_SUCCESS) return DECLINED; t = apr_array_make(sub_pool, candidates->nelts * 8 + 8, sizeof(char *)); v = apr_array_make(sub_pool, candidates->nelts * 5, sizeof(char *)); /* Generate the response text. */ *(const char **)apr_array_push(t) = "The document name you requested (<code>"; *(const char **)apr_array_push(t) = ap_escape_html(sub_pool, r->uri); *(const char **)apr_array_push(t) = "</code>) could not be found on this server.\n" "However, we found documents with names similar " "to the one you requested.<p>" "Available documents:\n<ul>\n"; for (i = 0; i < candidates->nelts; ++i) { char *vuri; const char *reason; reason = sp_reason_str[(int) (variant[i].quality)]; /* The format isn't very neat... */ vuri = apr_pstrcat(sub_pool, url, variant[i].name, r->path_info, (r->parsed_uri.query != NULL) ? "?" : "", (r->parsed_uri.query != NULL) ? r->parsed_uri.query : "", NULL); *(const char **)apr_array_push(v) = "\""; *(const char **)apr_array_push(v) = ap_escape_uri(sub_pool, vuri); *(const char **)apr_array_push(v) = "\";\""; *(const char **)apr_array_push(v) = reason; *(const char **)apr_array_push(v) = "\""; *(const char **)apr_array_push(t) = "<li><a href=\""; *(const char **)apr_array_push(t) = ap_escape_uri(sub_pool, vuri); *(const char **)apr_array_push(t) = "\">"; *(const char **)apr_array_push(t) = ap_escape_html(sub_pool, vuri); *(const char **)apr_array_push(t) = "</a> ("; *(const char **)apr_array_push(t) = reason; *(const char **)apr_array_push(t) = ")\n"; /* * when we have printed the "close matches" and there are * more "distant matches" (matched by stripping the suffix), * then we insert an additional separator text to suggest * that the user LOOK CLOSELY whether these are really the * files she wanted. */ if (i > 0 && i < candidates->nelts - 1 && variant[i].quality != SP_VERYDIFFERENT && variant[i + 1].quality == SP_VERYDIFFERENT) { *(const char **)apr_array_push(t) = "</ul>\nFurthermore, the following related " "documents were found:\n<ul>\n"; } } *(const char **)apr_array_push(t) = "</ul>\n"; /* If we know there was a referring page, add a note: */ if (ref != NULL) { *(const char **)apr_array_push(t) = "Please consider informing the owner of the " "<a href=\""; *(const char **)apr_array_push(t) = ap_escape_uri(sub_pool, ref); *(const char **)apr_array_push(t) = "\">referring page</a> " "about the broken link.\n"; } /* Pass our apr_table_t to http_protocol.c (see mod_negotiation): */ apr_table_setn(notes, "variant-list", apr_array_pstrcat(p, t, 0)); apr_table_mergen(r->subprocess_env, "VARIANTS", apr_array_pstrcat(p, v, ',')); apr_pool_destroy(sub_pool); ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, ref ? "Spelling fix: %s: %d candidates from %s" : "Spelling fix: %s: %d candidates%s", r->uri, candidates->nelts, (ref ? ref : "")); return HTTP_MULTIPLE_CHOICES; } } return OK; }
/** Process parsed XML document */ static apt_bool_t unimrcp_client_doc_process(unimrcp_client_loader_t *loader, const char *dir_path, apr_xml_doc *doc, apr_pool_t *pool) { const apr_xml_elem *elem; const apr_xml_elem *root; const apr_xml_attr *attr; const char *version = NULL; const char *subfolder = NULL; if(!doc) { return FALSE; } root = doc->root; /* Match document name */ if(!root || strcasecmp(root->name,"unimrcpclient") != 0) { apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Document <%s>",root ? root->name : "null"); return FALSE; } /* Read attributes */ for(attr = root->attr; attr; attr = attr->next) { if(strcasecmp(attr->name,"version") == 0) { version = attr->value; } else if(strcasecmp(attr->name,"subfolder") == 0) { subfolder = attr->value; } } /* Check version number first */ if(!version) { apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Version"); return FALSE; } loader->doc = doc; /* Navigate through document */ for(elem = root->first_child; elem; elem = elem->next) { if(strcasecmp(elem->name,"properties") == 0) { unimrcp_client_properties_load(loader,elem); } else if(strcasecmp(elem->name,"components") == 0) { unimrcp_client_components_load(loader,elem); } else if(strcasecmp(elem->name,"settings") == 0) { unimrcp_client_settings_load(loader,elem); } else if(strcasecmp(elem->name,"profiles") == 0) { unimrcp_client_profiles_load(loader,elem); } else if(strcasecmp(elem->name,"misc") == 0) { unimrcp_client_misc_load(loader,elem); } else { apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Element <%s>",elem->name); } } if(subfolder && *subfolder != '\0') { apr_dir_t *dir; apr_finfo_t finfo; apr_status_t rv; char *subdir_path; if (!dir_path) { apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Attempt to Process Subdirectory when " "Creating from Config String"); return TRUE; } if(apr_filepath_merge(&subdir_path,dir_path,subfolder,APR_FILEPATH_NATIVE,pool) == APR_SUCCESS) { apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Enter Directory [%s]",subdir_path); rv = apr_dir_open(&dir,subdir_path,pool); if(rv == APR_SUCCESS) { while(apr_dir_read(&finfo, APR_FINFO_NAME, dir) == APR_SUCCESS) { if(apr_fnmatch("*.xml", finfo.name, 0) == APR_SUCCESS) { unimrcp_client_load(loader,subdir_path,finfo.name); } } apr_dir_close(dir); apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Leave Directory [%s]",dir_path); } else { apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"No Such Directory %s",dir_path); } } } return TRUE; }
/* * walk the cache directory tree */ static int process_dir(char *path, apr_pool_t *pool) { apr_dir_t *dir; apr_pool_t *p; apr_hash_t *h; apr_hash_index_t *i; apr_file_t *fd; apr_status_t status; apr_finfo_t info; apr_size_t len; apr_time_t current, deviation; char *nextpath, *base, *ext, *orig_basename; APR_RING_ENTRY(_direntry) anchor; DIRENTRY *d, *t, *n; ENTRY *e; int skip, retries; disk_cache_info_t disk_info; APR_RING_INIT(&anchor, _direntry, link); apr_pool_create(&p, pool); h = apr_hash_make(p); fd = NULL; skip = 0; deviation = MAXDEVIATION * APR_USEC_PER_SEC; if (apr_dir_open(&dir, path, p) != APR_SUCCESS) { return 1; } while (apr_dir_read(&info, 0, dir) == APR_SUCCESS && !interrupted) { if (!strcmp(info.name, ".") || !strcmp(info.name, "..")) { continue; } d = apr_pcalloc(p, sizeof(DIRENTRY)); d->basename = apr_pstrcat(p, path, "/", info.name, NULL); APR_RING_INSERT_TAIL(&anchor, d, _direntry, link); } apr_dir_close(dir); if (interrupted) { return 1; } skip = baselen + 1; for (d = APR_RING_FIRST(&anchor); !interrupted && d != APR_RING_SENTINEL(&anchor, _direntry, link); d=n) { n = APR_RING_NEXT(d, link); base = strrchr(d->basename, '/'); if (!base++) { base = d->basename; } ext = strchr(base, '.'); /* there may be temporary files which may be gone before * processing, always skip these if not in realclean mode */ if (!ext && !realclean) { if (!strncasecmp(base, AP_TEMPFILE_BASE, AP_TEMPFILE_BASELEN) && strlen(base) == AP_TEMPFILE_NAMELEN) { continue; } } /* this may look strange but apr_stat() may return errno which * is system dependent and there may be transient failures, * so just blindly retry for a short while */ retries = STAT_ATTEMPTS; status = APR_SUCCESS; do { if (status != APR_SUCCESS) { apr_sleep(STAT_DELAY); } status = apr_stat(&info, d->basename, DIRINFO, p); } while (status != APR_SUCCESS && !interrupted && --retries); /* what may happen here is that apache did create a file which * we did detect but then does delete the file before we can * get file information, so if we don't get any file information * we will ignore the file in this case */ if (status != APR_SUCCESS) { if (!realclean && !interrupted) { continue; } return 1; } if (info.filetype == APR_DIR) { /* Make a copy of the basename, as process_dir modifies it */ orig_basename = apr_pstrdup(pool, d->basename); if (process_dir(d->basename, pool)) { return 1; } /* If asked to delete dirs, do so now. We don't care if it fails. * If it fails, it likely means there was something else there. */ if (deldirs && !dryrun) { apr_dir_remove(orig_basename, pool); } continue; } if (info.filetype != APR_REG) { continue; } if (!ext) { if (!strncasecmp(base, AP_TEMPFILE_BASE, AP_TEMPFILE_BASELEN) && strlen(base) == AP_TEMPFILE_NAMELEN) { d->basename += skip; d->type = TEMP; d->dsize = info.size; apr_hash_set(h, d->basename, APR_HASH_KEY_STRING, d); } continue; } if (!strcasecmp(ext, CACHE_HEADER_SUFFIX)) { *ext = '\0'; d->basename += skip; /* if a user manually creates a '.header' file */ if (d->basename[0] == '\0') { continue; } t = apr_hash_get(h, d->basename, APR_HASH_KEY_STRING); if (t) { d = t; } d->type |= HEADER; d->htime = info.mtime; d->hsize = info.size; apr_hash_set(h, d->basename, APR_HASH_KEY_STRING, d); continue; } if (!strcasecmp(ext, CACHE_DATA_SUFFIX)) { *ext = '\0'; d->basename += skip; /* if a user manually creates a '.data' file */ if (d->basename[0] == '\0') { continue; } t = apr_hash_get(h, d->basename, APR_HASH_KEY_STRING); if (t) { d = t; } d->type |= DATA; d->dtime = info.mtime; d->dsize = info.size; apr_hash_set(h, d->basename, APR_HASH_KEY_STRING, d); } } if (interrupted) { return 1; } path[baselen] = '\0'; for (i = apr_hash_first(p, h); i && !interrupted; i = apr_hash_next(i)) { void *hvalue; apr_uint32_t format; apr_hash_this(i, NULL, NULL, &hvalue); d = hvalue; switch(d->type) { case HEADERDATA: nextpath = apr_pstrcat(p, path, "/", d->basename, CACHE_HEADER_SUFFIX, NULL); if (apr_file_open(&fd, nextpath, APR_FOPEN_READ | APR_FOPEN_BINARY, APR_OS_DEFAULT, p) == APR_SUCCESS) { len = sizeof(format); if (apr_file_read_full(fd, &format, len, &len) == APR_SUCCESS) { if (format == DISK_FORMAT_VERSION) { apr_off_t offset = 0; apr_file_seek(fd, APR_SET, &offset); len = sizeof(disk_cache_info_t); if (apr_file_read_full(fd, &disk_info, len, &len) == APR_SUCCESS) { apr_file_close(fd); e = apr_palloc(pool, sizeof(ENTRY)); APR_RING_INSERT_TAIL(&root, e, _entry, link); e->expire = disk_info.expire; e->response_time = disk_info.response_time; e->htime = d->htime; e->dtime = d->dtime; e->hsize = d->hsize; e->dsize = d->dsize; e->basename = apr_pstrdup(pool, d->basename); break; } else { apr_file_close(fd); } } else if (format == VARY_FORMAT_VERSION) { /* This must be a URL that added Vary headers later, * so kill the orphaned .data file */ apr_file_close(fd); apr_file_remove(apr_pstrcat(p, path, "/", d->basename, CACHE_DATA_SUFFIX, NULL), p); } } else { apr_file_close(fd); } } /* we have a somehow unreadable headers file which is associated * with a data file. this may be caused by apache currently * rewriting the headers file. thus we may delete the file set * either in realclean mode or if the headers file modification * timestamp is not within a specified positive or negative offset * to the current time. */ current = apr_time_now(); if (realclean || d->htime < current - deviation || d->htime > current + deviation) { delete_entry(path, d->basename, p); unsolicited += d->hsize; unsolicited += d->dsize; } break; /* single data and header files may be deleted either in realclean * mode or if their modification timestamp is not within a * specified positive or negative offset to the current time. * this handling is necessary due to possible race conditions * between apache and this process */ case HEADER: current = apr_time_now(); nextpath = apr_pstrcat(p, path, "/", d->basename, CACHE_HEADER_SUFFIX, NULL); if (apr_file_open(&fd, nextpath, APR_FOPEN_READ | APR_FOPEN_BINARY, APR_OS_DEFAULT, p) == APR_SUCCESS) { len = sizeof(format); if (apr_file_read_full(fd, &format, len, &len) == APR_SUCCESS) { if (format == VARY_FORMAT_VERSION) { apr_time_t expires; len = sizeof(expires); apr_file_read_full(fd, &expires, len, &len); apr_file_close(fd); if (expires < current) { delete_entry(path, d->basename, p); } break; } } apr_file_close(fd); } if (realclean || d->htime < current - deviation || d->htime > current + deviation) { delete_entry(path, d->basename, p); unsolicited += d->hsize; } break; case DATA: current = apr_time_now(); if (realclean || d->dtime < current - deviation || d->dtime > current + deviation) { delete_entry(path, d->basename, p); unsolicited += d->dsize; } break; /* temp files may only be deleted in realclean mode which * is asserted above if a tempfile is in the hash array */ case TEMP: delete_file(path, d->basename, p); unsolicited += d->dsize; break; } } if (interrupted) { return 1; } apr_pool_destroy(p); if (benice) { apr_sleep(NICE_DELAY); } if (interrupted) { return 1; } return 0; }
int lua_apr_dir_remove_recursive(lua_State *L) { apr_status_t status; apr_pool_t *outer_pool; /* used to store todo/done arrays and directory pathnames */ apr_pool_t *middle_pool; /* used to store directory handles (apr_dir_t structs) */ apr_pool_t *inner_pool; /* used to store pathnames of non-subdirectory entries */ apr_array_header_t *todo, *done; apr_dir_t *directory; apr_finfo_t info; char **top, *tmp; const char *filepath; int allocation_counter; directory = NULL; outer_pool = middle_pool = inner_pool = NULL; filepath = luaL_checkstring(L, 1); allocation_counter = 0; status = apr_pool_create(&outer_pool, NULL); if (APR_SUCCESS == status) status = apr_pool_create(&middle_pool, NULL); if (APR_SUCCESS == status) status = apr_pool_create(&inner_pool, NULL); if (APR_SUCCESS != status) goto cleanup; # define out_of_memory do { \ status = APR_ENOMEM; \ goto cleanup; \ } while (0) # define push_filepath(stack, filepath) do { \ const char **p = apr_array_push(stack); \ if (p != NULL) *p = filepath; else out_of_memory; \ } while (0) todo = apr_array_make(outer_pool, 0, sizeof filepath); done = apr_array_make(outer_pool, 0, sizeof filepath); if (todo == NULL || done == NULL) out_of_memory; push_filepath(todo, filepath); while ((top = apr_array_pop(todo))) { filepath = *(char**)top; apr_pool_clear(middle_pool); status = apr_dir_open(&directory, filepath, middle_pool); if (status != APR_SUCCESS) { directory = NULL; goto cleanup; } for (;;) { /* This is a compromise between having `inner_pool' grow almost unbounded * on very large directories (e.g. ~/Maildir/) and clearing it for every * non-subdirectory pathname that's allocated (very inefficient). */ if (allocation_counter % 1000 == 0) apr_pool_clear(inner_pool); /* FIXME?! apr_dir_read() uses directory->pool (middle_pool) for allocation */ status = apr_dir_read(&info, APR_FINFO_NAME|APR_FINFO_TYPE|APR_FINFO_LINK, directory); if (APR_STATUS_IS_ENOENT(status)) break; /* no more entries */ else if (status != APR_SUCCESS && status != APR_INCOMPLETE) goto cleanup; /* something went wrong */ else if (filename_symbolic(info.name)) continue; /* bogus entry */ else if (info.filetype == APR_DIR) { /* recurse into subdirectory */ status = apr_filepath_merge(&tmp, filepath, info.name, 0, outer_pool); if (status != APR_SUCCESS) goto cleanup; push_filepath(todo, tmp); } else { /* delete non-subdirectory entry */ status = apr_filepath_merge(&tmp, filepath, info.name, 0, inner_pool); allocation_counter++; if (APR_SUCCESS == status) status = apr_file_remove(tmp, inner_pool); if (APR_SUCCESS != status) goto cleanup; } } status = apr_dir_close(directory); directory = NULL; if (status != APR_SUCCESS) goto cleanup; push_filepath(done, filepath); } # undef out_of_memory # undef push_filepath while ((top = apr_array_pop(done))) { filepath = *(char**)top; if (allocation_counter++ % 100 == 0) apr_pool_clear(middle_pool); status = apr_dir_remove(filepath, middle_pool); if (status != APR_SUCCESS) goto cleanup; } cleanup: if (directory != NULL) apr_dir_close(directory); if (inner_pool != NULL) apr_pool_destroy(inner_pool); if (middle_pool != NULL) apr_pool_destroy(middle_pool); if (outer_pool != NULL) apr_pool_destroy(outer_pool); return push_status(L, status); }