| 3603 | } |
| 3604 | |
| 3605 | AP_DECLARE(const char *)ap_dir_nofnmatch(ap_dir_match_t *w, const char *fname) |
| 3606 | { |
| 3607 | const char *error; |
| 3608 | apr_status_t rv; |
| 3609 | |
| 3610 | if ((w->flags & AP_DIR_FLAG_RECURSIVE) && ap_is_directory(w->ptemp, fname)) { |
| 3611 | apr_dir_t *dirp; |
| 3612 | apr_finfo_t dirent; |
| 3613 | int current; |
| 3614 | apr_array_header_t *candidates = NULL; |
| 3615 | fnames *fnew; |
| 3616 | char *path = apr_pstrdup(w->ptemp, fname); |
| 3617 | |
| 3618 | if (++w->depth > AP_MAX_FNMATCH_DIR_DEPTH) { |
| 3619 | return apr_psprintf(w->p, "%sDirectory '%s' exceeds the maximum include " |
| 3620 | "directory nesting level of %u. You have " |
| 3621 | "probably a recursion somewhere.", w->prefix ? w->prefix : "", path, |
| 3622 | AP_MAX_FNMATCH_DIR_DEPTH); |
| 3623 | } |
| 3624 | |
| 3625 | /* |
| 3626 | * first course of business is to grok all the directory |
| 3627 | * entries here and store 'em away. Recall we need full pathnames |
| 3628 | * for this. |
| 3629 | */ |
| 3630 | rv = apr_dir_open(&dirp, path, w->ptemp); |
| 3631 | if (rv != APR_SUCCESS) { |
| 3632 | return apr_psprintf(w->p, "%sCould not open directory %s: %pm", |
| 3633 | w->prefix ? w->prefix : "", path, &rv); |
| 3634 | } |
| 3635 | |
| 3636 | candidates = apr_array_make(w->ptemp, 1, sizeof(fnames)); |
| 3637 | while (apr_dir_read(&dirent, APR_FINFO_DIRENT, dirp) == APR_SUCCESS) { |
| 3638 | /* strip out '.' and '..' */ |
| 3639 | if (strcmp(dirent.name, ".") |
| 3640 | && strcmp(dirent.name, "..")) { |
| 3641 | fnew = (fnames *) apr_array_push(candidates); |
| 3642 | fnew->fname = ap_make_full_path(w->ptemp, path, dirent.name); |
| 3643 | } |
| 3644 | } |
| 3645 | |
| 3646 | apr_dir_close(dirp); |
| 3647 | if (candidates->nelts != 0) { |
| 3648 | qsort((void *) candidates->elts, candidates->nelts, |
| 3649 | sizeof(fnames), fname_alphasort); |
| 3650 | |
| 3651 | /* |
| 3652 | * Now recurse these... we handle errors and subdirectories |
| 3653 | * via the recursion, which is nice |
| 3654 | */ |
| 3655 | for (current = 0; current < candidates->nelts; ++current) { |
| 3656 | fnew = &((fnames *) candidates->elts)[current]; |
| 3657 | error = ap_dir_nofnmatch(w, fnew->fname); |
| 3658 | if (error) { |
| 3659 | return error; |
| 3660 | } |
| 3661 | } |
| 3662 | } |
no test coverage detected