You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by pq...@apache.org on 2005/10/08 11:04:27 UTC
svn commit: r307275 - in /httpd/mod_mbox/trunk/module-2.0: mbox_parse.c
mbox_parse.h mod_mbox.h mod_mbox_file.c mod_mbox_index.c mod_mbox_out.c
Author: pquerna
Date: Sat Oct 8 02:04:23 2005
New Revision: 307275
URL: http://svn.apache.org/viewcvs?rev=307275&view=rev
Log:
Add support for Atom 1.0 feeds to mod_mbox indexes. Just pass '?format=atom' to any directory index handled by mod_mbox.
mod_mbox_file.c: Expose load_message, since this is the first time we are fetching message data without searching for a specific message ID
mod_mbox_index.c: Add mbox_atom_handler, to create the base Atom Feed.
mod_mbox_out.c: Add worker output functions for Atom Feeds.
mod_mbox.h: Add mbox_atom_entries, load_message, and MBOX_ATOM_NUM_ENTRIES(40)
mbox_parse.{c,h}: Add MBOX_SORT_REVERSE_DATE for sorting in newest to oldest.
Modified:
httpd/mod_mbox/trunk/module-2.0/mbox_parse.c
httpd/mod_mbox/trunk/module-2.0/mbox_parse.h
httpd/mod_mbox/trunk/module-2.0/mod_mbox.h
httpd/mod_mbox/trunk/module-2.0/mod_mbox_file.c
httpd/mod_mbox/trunk/module-2.0/mod_mbox_index.c
httpd/mod_mbox/trunk/module-2.0/mod_mbox_out.c
Modified: httpd/mod_mbox/trunk/module-2.0/mbox_parse.c
URL: http://svn.apache.org/viewcvs/httpd/mod_mbox/trunk/module-2.0/mbox_parse.c?rev=307275&r1=307274&r2=307275&view=diff
==============================================================================
--- httpd/mod_mbox/trunk/module-2.0/mbox_parse.c (original)
+++ httpd/mod_mbox/trunk/module-2.0/mbox_parse.c Sat Oct 8 02:04:23 2005
@@ -360,6 +360,14 @@
return ((a->key > b->key) ? 1 : -1);
}
+static int mbox_reverse_list(void *p, void *q, void *pointer)
+{
+ MBOX_LIST *a = (MBOX_LIST*)p;
+ MBOX_LIST *b = (MBOX_LIST*)q;
+
+ return ((a->key > b->key) ? -1 : 1);
+}
+
/*
* Comparison function called by sort_linked_list to sort MBOX_LIST items
* by author (then by date).
@@ -398,6 +406,10 @@
{
case MBOX_SORT_DATE:
l = (MBOX_LIST*) mbox_sort_linked_list(l, 0, mbox_compare_list,
+ NULL, NULL);
+ break;
+ case MBOX_SORT_REVERSE_DATE:
+ l = (MBOX_LIST*) mbox_sort_linked_list(l, 0, mbox_reverse_list,
NULL, NULL);
break;
case MBOX_SORT_AUTHOR:
Modified: httpd/mod_mbox/trunk/module-2.0/mbox_parse.h
URL: http://svn.apache.org/viewcvs/httpd/mod_mbox/trunk/module-2.0/mbox_parse.h?rev=307275&r1=307274&r2=307275&view=diff
==============================================================================
--- httpd/mod_mbox/trunk/module-2.0/mbox_parse.h (original)
+++ httpd/mod_mbox/trunk/module-2.0/mbox_parse.h Sat Oct 8 02:04:23 2005
@@ -41,6 +41,7 @@
#define MBOX_SORT_DATE 0
#define MBOX_SORT_AUTHOR 1
#define MBOX_SORT_THREAD 2
+#define MBOX_SORT_REVERSE_DATE 3
/*
* MBOX_BUFF emulates the Apache BUFF structure, however it only
Modified: httpd/mod_mbox/trunk/module-2.0/mod_mbox.h
URL: http://svn.apache.org/viewcvs/httpd/mod_mbox/trunk/module-2.0/mod_mbox.h?rev=307275&r1=307274&r2=307275&view=diff
==============================================================================
--- httpd/mod_mbox/trunk/module-2.0/mod_mbox.h (original)
+++ httpd/mod_mbox/trunk/module-2.0/mod_mbox.h Sat Oct 8 02:04:23 2005
@@ -62,6 +62,8 @@
#define MBOX_WRAP_TO 90
+#define MBOX_ATOM_NUM_ENTRIES 40
+
typedef struct mbox_dir_cfg {
int enabled;
int antispam;
@@ -98,12 +100,13 @@
/* Output functions */
apr_status_t mbox_xml_msglist(request_rec *r, apr_file_t *f, int sortFlags);
apr_status_t mbox_static_msglist(request_rec *r, apr_file_t *f, int sortFlags);
-
apr_status_t mbox_xml_boxlist(request_rec *r);
apr_status_t mbox_static_boxlist(request_rec *r);
apr_status_t mbox_static_index_boxlist(request_rec *r, mbox_dir_cfg_t *conf,
mbox_cache_info *mli);
+void mbox_atom_entries(request_rec *r, mbox_cache_info *mli);
+
apr_status_t mbox_ajax_browser(request_rec *r);
apr_status_t mbox_raw_message(request_rec *r, apr_file_t *f);
@@ -139,6 +142,8 @@
char *path);
Message *fetch_message(request_rec *r, apr_file_t *f, char *msgID);
char **fetch_context_msgids(request_rec *r, apr_file_t *f, char*msgID);
+
+void load_message(apr_pool_t *p, apr_file_t *f, Message *m);
#ifdef __cplusplus
}
Modified: httpd/mod_mbox/trunk/module-2.0/mod_mbox_file.c
URL: http://svn.apache.org/viewcvs/httpd/mod_mbox/trunk/module-2.0/mod_mbox_file.c?rev=307275&r1=307274&r2=307275&view=diff
==============================================================================
--- httpd/mod_mbox/trunk/module-2.0/mod_mbox_file.c (original)
+++ httpd/mod_mbox/trunk/module-2.0/mod_mbox_file.c Sat Oct 8 02:04:23 2005
@@ -49,6 +49,27 @@
return m;
}
+/* Fetch a message from mailbox */
+void load_message(apr_pool_t *p, apr_file_t *f, Message *m)
+{
+ apr_size_t len = 0;
+
+ /* Fetch message (from msg_start to body_end) */
+ if (apr_file_seek(f, APR_SET, &m->msg_start) != APR_SUCCESS) {
+ return;
+ }
+
+ len = m->body_end - m->msg_start;
+ m->raw_msg = apr_palloc(p, len+1);
+
+ if (apr_file_read(f, m->raw_msg, &len) != APR_SUCCESS) {
+ return;
+ }
+
+ m->raw_msg[len] = '\0';
+ m->raw_body = m->raw_msg + (m->body_start - m->msg_start);
+}
+
/* Find thread starting with message 'msgID' in container 'c' */
static Container *find_thread(request_rec *r, char *msgID, Container *c)
{
Modified: httpd/mod_mbox/trunk/module-2.0/mod_mbox_index.c
URL: http://svn.apache.org/viewcvs/httpd/mod_mbox/trunk/module-2.0/mod_mbox_index.c?rev=307275&r1=307274&r2=307275&view=diff
==============================================================================
--- httpd/mod_mbox/trunk/module-2.0/mod_mbox_index.c (original)
+++ httpd/mod_mbox/trunk/module-2.0/mod_mbox_index.c Sat Oct 8 02:04:23 2005
@@ -89,6 +89,42 @@
return files;
}
+
+int mbox_atom_handler(request_rec *r, mbox_cache_info *mli)
+{
+ char dstr[100];
+ apr_size_t dlen;
+ char *etag;
+ apr_time_exp_t extime;
+
+ 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);
+
+ ap_rputs("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n", r);
+ ap_rputs("<feed xmlns=\"http://www.w3.org/2005/Atom\">\n", r);
+ ap_rprintf(r, "<title>%s@%s Archives</title>\n",
+ ESCAPE_OR_BLANK(r->pool, mli->list),
+ ESCAPE_OR_BLANK(r->pool, mli->domain));
+ ap_rprintf(r, "<link rel=\"self\" href=\"%s?format=atom\"/>\n", ap_construct_url(r->pool, r->uri, r));
+ ap_rprintf(r, "<link href=\"%s\"/>\n", ap_construct_url(r->pool, r->uri, r));
+ ap_rprintf(r, "<id>%s</id>\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, "<updated>%s</updated>\n", dstr);
+ mbox_atom_entries(r, mli);
+ ap_rputs("</feed>\n", r);
+ return OK;
+}
+
/* The default index handler, using mbox_display_static_index() */
int mbox_index_handler(request_rec *r)
{
@@ -115,6 +151,10 @@
"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);
}
ap_set_content_type(r, "text/html; charset=utf-8");
Modified: httpd/mod_mbox/trunk/module-2.0/mod_mbox_out.c
URL: http://svn.apache.org/viewcvs/httpd/mod_mbox/trunk/module-2.0/mod_mbox_out.c?rev=307275&r1=307274&r2=307275&view=diff
==============================================================================
--- httpd/mod_mbox/trunk/module-2.0/mod_mbox_out.c (original)
+++ httpd/mod_mbox/trunk/module-2.0/mod_mbox_out.c Sat Oct 8 02:04:23 2005
@@ -34,6 +34,122 @@
{ "Dec", "December" }
};
+void display_atom_entry(request_rec *r, Message *m, const char* mboxfile,
+ apr_pool_t *pool, apr_file_t *f)
+{
+ char dstr[100];
+ apr_size_t dlen;
+ apr_time_exp_t extime;
+ char* uid;
+ char* c;
+
+ ap_rputs("<entry>\n", r);
+ ap_rprintf(r, "<title>%s</title>\n", ESCAPE_OR_BLANK(pool, m->subject));
+ ap_rprintf(r, "<author><name>%s</name></author>\n",
+ ESCAPE_OR_BLANK(pool, m->from));
+
+ ap_rprintf(r, "<link rel=\"alternate\" href=\"%s%s/%s\"/>\n",
+ ap_construct_url(r->pool, r->uri, r),
+ mboxfile, URI_ESCAPE_OR_BLANK(pool, m->msgID));
+
+ uid = URI_ESCAPE_OR_BLANK(pool, m->msgID);
+
+ c = uid;
+ while (*c != '\0') {
+ if (*c == '.') {
+ *c = '-';
+ }
+ *c++;
+ }
+
+ ap_rprintf(r, "<id>urn:uuid:%s</id>\n", uid);
+
+ apr_time_exp_gmt(&extime, m->date);
+
+ apr_strftime(dstr, &dlen, sizeof(dstr),
+ "%G-%m-%dT%H:%M:%SZ", &extime);
+
+ ap_rprintf(r, "<updated>%s</updated>\n", dstr);
+ ap_rputs("<content type=\"text\">\n", r);
+
+ load_message(pool, f, m);
+ /* Parse multipart information */
+ m->mime_msg = mbox_mime_decode_multipart(pool, m->raw_body,
+ m->content_type,
+ m->cte, m->boundary);
+
+ ap_rprintf(r, "%s", mbox_wrap_text(mbox_mime_get_body(pool, m->mime_msg)));
+
+ ap_rputs("</content>\n", r);
+ ap_rputs("</entry>\n", r);
+}
+
+static int mbox2atom(request_rec *r, const char* mboxfile, mbox_cache_info *mli, int max)
+{
+ apr_status_t rv;
+ char* filename;
+ char* origfilename;
+ apr_file_t *f;
+ MBOX_LIST *head;
+ Message *m;
+ int i;
+ apr_pool_t* tpool;
+
+ apr_pool_create(&tpool, r->pool);
+
+ filename = apr_pstrcat(r->pool, r->filename, mboxfile, NULL);
+
+ rv = apr_file_open(&f, filename, APR_READ,
+ APR_OS_DEFAULT, r->pool);
+
+ if(rv != APR_SUCCESS) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
+ "mod_mbox(mbox2atom): Can't open mbox '%s' for atom feed",
+ filename);
+ return 0;
+ }
+ origfilename = r->filename;
+
+ r->filename = filename;
+
+ head = mbox_load_index(r, f, NULL);
+
+ /* Sort the list */
+ head = mbox_sort_list(head, MBOX_SORT_REVERSE_DATE);
+
+ for (i = 0; i < max && head != NULL; i++) {
+ m = (Message*)head->value;
+ display_atom_entry(r, m, mboxfile, tpool, f);
+ head = head->next;
+ apr_pool_clear(tpool);
+ }
+
+ r->filename = origfilename;
+ apr_pool_destroy(tpool);
+ return i;
+}
+
+void mbox_atom_entries(request_rec *r, mbox_cache_info *mli)
+{
+ mbox_file_t *fi;
+ apr_array_header_t *files;
+ int i, entries = 0;
+
+ files = mbox_fetch_boxes_list(r, mli, r->filename);
+ if (!files) {
+ return;
+ }
+
+ fi = (mbox_file_t *)files->elts;
+ for (i = 0; i < files->nelts && entries < MBOX_ATOM_NUM_ENTRIES; i++) {
+ if (!fi[i].count) {
+ continue;
+ }
+ entries += mbox2atom(r, fi[i].filename, mli, MBOX_ATOM_NUM_ENTRIES - entries);
+ }
+}
+
+
/* Outputs an XML list of available mailboxes */
apr_status_t mbox_xml_boxlist(request_rec *r)
{