/* Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* The file contains an alternative Directory Index Handler that * displays information about the mailing list. */ #include "mod_mbox.h" /* Compare two file entries (in reverse order). * * This function is only Used when sorting file list to : * 200501 * 200412 * 200411 */ static int filename_rsort(const void *fn1, const void *fn2) { mbox_file_t *f1 = (mbox_file_t *) fn1; mbox_file_t *f2 = (mbox_file_t *) fn2; return strcmp(f2->filename, f1->filename); } /* Fetches the .mbox files from the directory and return a chained * list of mbox_files_t containing all the information we need to * output a complete box listing. */ apr_array_header_t *mbox_fetch_boxes_list(request_rec *r, mbox_cache_info *mli, char *path) { apr_status_t rv = APR_SUCCESS; apr_finfo_t finfo; apr_dir_t *dir; mbox_file_t *fi; apr_array_header_t *files; rv = apr_dir_open(&dir, path, r->pool); /* If we couldn't open the directory, something like file permissions are stopping us. */ if (rv != APR_SUCCESS) { ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, "mod_mbox(fetch_boxes_list): Failed to open directory '%s' for index", path); return NULL; } if (!mli) { return NULL; } /* 15 Years of Mail Archives */ files = apr_array_make(r->pool, 15 * 12, sizeof(mbox_file_t)); /* Foreach file in the directory, add its name and the message count to our array */ while (apr_dir_read(&finfo, APR_FINFO_NAME, dir) == APR_SUCCESS) { if ((apr_fnmatch("*.mbox", finfo.name, 0) == APR_SUCCESS) && (strstr(finfo.name, "incomplete") == NULL)) { fi = (mbox_file_t *) apr_array_push(files); fi->filename = apr_pstrdup(r->pool, finfo.name); mbox_cache_get_count(mli, &(fi->count), (char *) finfo.name); } } apr_dir_close(dir); if (files->nelts == 0) { return NULL; } /* Sort by reverse filename order */ qsort((void *) files->elts, files->nelts, sizeof(mbox_file_t), filename_rsort); return files; } int mbox_atom_handler(request_rec *r, mbox_cache_info *mli) { int errstatus; char dstr[100]; apr_size_t dlen; char *etag; apr_time_exp_t extime; /* Only allow GETs */ r->allowed |= (AP_METHOD_BIT << M_GET); if (r->method_number != M_GET) { return HTTP_METHOD_NOT_ALLOWED; } ap_set_content_type(r, "application/xml; charset=utf-8"); /* Try to make the index page more cache friendly */ ap_update_mtime(r, mli->mtime); ap_set_last_modified(r); etag = ap_make_etag(r, 1); apr_table_setn(r->headers_out, "ETag", etag); if (r->header_only) { return OK; } if ((errstatus = ap_meets_conditions(r)) != OK) { r->status = errstatus; return r->status; } ap_rputs("\n", r); ap_rputs("\n", r); ap_rprintf(r, "%s@%s Archives\n", ESCAPE_OR_BLANK(r->pool, mli->list), ESCAPE_OR_BLANK(r->pool, mli->domain)); ap_rprintf(r, "\n", ap_construct_url(r->pool, r->uri, r)); ap_rprintf(r, "\n", ap_construct_url(r->pool, r->uri, r)); ap_rprintf(r, "%s\n", ap_construct_url(r->pool, r->uri, r)); apr_time_exp_gmt(&extime, mli->mtime); apr_strftime(dstr, &dlen, sizeof(dstr), "%G-%m-%dT%H:%M:%SZ", &extime); ap_rprintf(r, "%s\n", dstr); mbox_atom_entries(r, mli); ap_rputs("\n", r); return OK; } /* The default index handler, using mbox_display_static_index() */ int mbox_index_handler(request_rec *r) { int errstatus; apr_status_t rv = APR_SUCCESS; mbox_dir_cfg_t *conf; mbox_cache_info *mli; char dstr[APR_RFC822_DATE_LEN]; char *etag; conf = ap_get_module_config(r->per_dir_config, &mbox_module); /* Don't serve index if it's not a directory or if it's not enabled */ if (strcmp(r->handler, DIR_MAGIC_TYPE) || !conf->enabled) { return DECLINED; } /* Open mbox cache */ rv = mbox_cache_get(&mli, r->filename, r->pool); if (rv != APR_SUCCESS) { ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rv, r, "mod_mbox: Can't open directory cache '%s' for index", r->filename); return DECLINED; } if (r->args && strstr(r->args, "format=atom") != NULL) { return mbox_atom_handler(r, mli); } if (r->args && strstr(r->args, "format=sitemap") != NULL) { return mbox_sitemap_handler(r, mli); } /* Only allow GETs */ r->allowed |= (AP_METHOD_BIT << M_GET); if (r->method_number != M_GET) { return HTTP_METHOD_NOT_ALLOWED; } ap_set_content_type(r, "text/html; charset=utf-8"); /* Try to make the index page more cache friendly */ ap_update_mtime(r, mli->mtime); ap_set_last_modified(r); etag = ap_make_etag(r, 1); apr_table_setn(r->headers_out, "ETag", etag); if (r->header_only) { return OK; } if ((errstatus = ap_meets_conditions(r)) != OK) { r->status = errstatus; return r->status; } ap_rputs("\n", r); ap_rputs("\n\n", r); ap_rputs("\n", r); ap_rputs(" \n", r); ap_rputs (" \n", r); if (mli->list && mli->domain) { ap_rprintf(r, " %s@%s Archives\n", ESCAPE_OR_BLANK(r->pool, mli->list), ESCAPE_OR_BLANK(r->pool, mli->domain)); } else { ap_rputs(" Mailing list archives\n", r); } ap_rprintf(r, "", ESCAPE_OR_BLANK(r->pool, mli->list), ESCAPE_OR_BLANK(r->pool, mli->domain), ap_construct_url(r->pool, r->uri, r)); if (conf->style_path) { ap_rprintf(r, " \n", conf->style_path); } if (conf->script_path) { ap_rprintf(r, " \n", conf->script_path); } ap_rputs(" \n\n", r); ap_rputs(" \n", r); ap_rprintf(r, "

Mailing list archives: %s@%s

\n", ESCAPE_OR_BLANK(r->pool, mli->list), ESCAPE_OR_BLANK(r->pool, mli->domain)); if (conf->root_path) { ap_rprintf(r, "
" "Site index
\n\n", conf->root_path); } /* Output header and list information */ ap_rputs(" \n", r); ap_rputs (" \n", r); ap_rputs(" \n", r); ap_rprintf(r, " " "\n", ESCAPE_OR_BLANK(r->pool, mli->list), ESCAPE_OR_BLANK(r->pool, mli->domain)); ap_rprintf(r, " " "\n", ESCAPE_OR_BLANK(r->pool, mli->list), ESCAPE_OR_BLANK(r->pool, mli->domain)); ap_rprintf(r, " " "\n", ESCAPE_OR_BLANK(r->pool, mli->list), ESCAPE_OR_BLANK(r->pool, mli-> domain)); ap_rprintf(r, " " "\n", ESCAPE_OR_BLANK(r->pool, mli->list), ESCAPE_OR_BLANK(r->pool, mli->domain)); ap_rprintf(r, " " "\n", ESCAPE_OR_BLANK(r->pool, mli->list), ESCAPE_OR_BLANK(r->pool, mli->domain)); ap_rputs("" "\n", r); ap_rputs(" \n", r); ap_rputs("
List information
Writing to the list%s@%s
Subscription address%s-subscribe@%s
Digest subscription address%s-digest-subscribe@%s
Unsubscription addresses%s-unsubscribe@%s
Getting help with the list%s-help@%s
Feeds:" "Atom 1.0
\n", r); /* Display the box list */ rv = mbox_static_index_boxlist(r, conf, mli); if (rv != APR_SUCCESS) { return rv; } apr_rfc822_date(dstr, mli->mtime); ap_rprintf(r, "

Last updated on: %s

\n", dstr); ap_rputs(" \n", r); ap_rputs("", r); return OK; }