[subversion:17] Working lazy-creation hooks for index.html and feed.atom.
- From: TimBray@kenai.com
- To: commits@mod-atom.kenai.com
- Subject: [subversion:17] Working lazy-creation hooks for index.html and feed.atom.
- Date: Wed, 5 Nov 2008 20:27:16 +0000 (GMT)
Repository: subversion
Revision: 17
Author: tim.bray@sun.com
Date: 2008-11-05 20:27:10 UTC
Log Message:
-----------
Working lazy-creation hooks for index.html and feed.atom. Step 1,
modularize out the refresh_collection code.
Modified Paths:
--------------
src/mod_atom.hsrc/mod_atom.c
Diffs:
-----
Index: src/mod_atom.c
===================================================================
--- src/mod_atom.c (revision 16)
+++ src/mod_atom.c (revision 17)
@@ -144,9 +144,11 @@
/* A bunch of regexes for sorting incoming URIs into buckets
*/
-typedef struct pub_patterns_t {
+typedef struct pub_patterns_t
+{
ap_regex_t * entry;
ap_regex_t * collection;
+ ap_regex_t * feed;
ap_regex_t * media_object;
ap_regex_t * entries_space;
ap_regex_t * extras_space;
@@ -156,12 +158,14 @@
/* A publication can be regular, or a meta-pub, or a sub-pub created
* by posting to a meta-pub
*/
-typedef enum pub_type_t {
+typedef enum pub_type_t
+{
REGULAR_PUB, META_PUB, SUB_PUB
} pub_type_t;
/* a publication, corresponding to an AtomPub directive in config */
-typedef struct pub_t {
+typedef struct pub_t
+{
char * path; /* the path used by the world to refer to this pub */
char * dir; /* the directory where the pub's data is rooted */
char * title; /* the pub's human-readable title */
@@ -174,7 +178,8 @@
} pub_t;
/* fake low-rent continuation in run_fp_template */
-typedef enum template_state_t {
+typedef enum template_state_t
+{
Writing,
Bypassing,
Done
@@ -186,13 +191,14 @@
* However, it does have the benefit of reducing almost all calls to
just
* a couple of arguments, making things easier to read.
*/
-typedef struct entry_t {
+typedef struct entry_t
+{
apr_xml_doc * xml; /* DOM of the entry */
- char * path; /* the part after ...(atom|pub) & with no
extension */
- pub_t * pub; /* the publication */
- char * coll_base; /* dir for this entry's collection & feed */
- char * id; /* unique id */
- int size; /* in bytes, for media objects only */
+ char * path; /* the part after ...(atom|pub) & with no extension
*/
+ pub_t * pub; /* the publication */
+ char * coll_base; /* dir for this entry's collection & feed */
+ char * id; /* unique id */
+ int size; /* in bytes, for media objects only */
text_construct_type_t type_of_content;
} entry_t;
@@ -241,6 +247,8 @@
static int put(request_rec * r, pub_t * pub);
static int put_entry(request_rec * r, pub_t * pub, entry_t * e);
static int put_media(request_rec * r, pub_t * pub, entry_t * e);
+static char * refresh_collection(char * coll_base, pub_t * pub,
+ apr_pool_t * pool, apr_finfo_t *
coll_finfo);
static int replace_media(request_rec * r, entry_t * e);
static char * rm_rf(apr_pool_t * pool, char * dir);
static int save_new_entry(request_rec * r, entry_t * e);
@@ -301,7 +309,8 @@
"Can't initialize publication '%s' at URI
'%s': '%s'",
pub->title, pub->path, problem);
continue;
- } else {
+ }
+ else {
ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,
"Publication '%s' at '%s' successfully
loaded!",
pub->title, pub->path);
@@ -341,7 +350,7 @@
publist = (pub_t *) pubs_from_config->elts;
for (i = 0; i < pubs_from_config->nelts - 1; i++)
if (is_prefix(path, publist[i].path) ||
- is_prefix(publist[i].path, path)) {
+ is_prefix(publist[i].path, path)) {
ap_log_error(APLOG_MARK, APLOG_ERR, 0, cmd->server,
"One publication prefixes another: '%s' and
'%s'",
path, publist[i].path);
@@ -396,11 +405,10 @@
*/
static int map_to_storage(request_rec * r) {
pub_t * pub = find_pub(r);
- apr_finfo_t * finfo;
+ apr_finfo_t finfo;
apr_status_t status;
char * s;
char * post_atom;
- int basics = APR_FINFO_MTIME | APR_FINFO_INODE | APR_FINFO_SIZE;
if (pub == NULL)
return DECLINED;
@@ -409,16 +417,15 @@
s = is_prefix(r->uri, pub->path) + 1;
if ((post_atom = is_prefix(s, ATOM_DIR)))
s = atom_join(r->pool, pub->dir, PUB_DIR, post_atom, NULL);
- else
+ else
s = atom_join(r->pool, pub->dir, s, NULL);
r->canonical_filename = r->filename = s; /* why 'canonical' too?
*/
/* it seems we have to fill in r->finfo too */
- finfo = (apr_finfo_t *) apr_palloc(r->pool, sizeof (apr_finfo_t));
- finfo->name = r->filename;
- status = apr_stat(finfo, r->filename, basics, r->pool);
- r->finfo = *finfo;
+ finfo.name = r->filename;
+ status = apr_stat(&finfo, r->filename, BASICS, r->pool);
+ /* assuming the target filename exists */
if (status == APR_SUCCESS) {
/* if we're getting a collection, check the timestamp file to
see
@@ -426,45 +433,22 @@
*/
if ((r->method_number == M_GET) &&
MATCHES(pub->patterns->collection, r->uri)) {
- apr_finfo_t ts_info;
char * coll_base = dir_of(r->pool, r->filename);
- char * ts_name;
- apr_status_t ts_status;
- int rebuild = 1;
+ char * prob = refresh_collection(coll_base, pub, r->pool,
&finfo);
- ts_name = atom_join(r->pool, coll_base, TIMESTAMP_FILE,
NULL);
- ts_status = apr_stat(&ts_info, ts_name, basics, r->pool);
+ if (prob)
+ return server_error(r, APR_SUCCESS, "In GET
collection, %s",
+ prob);
- /* note, rebuild even if the timestamp date and the
collection
- * date are the same. Stupid unix 1-second mtime
granularity...
- */
- if (ts_status == APR_SUCCESS && ts_info.mtime <
finfo->mtime)
- rebuild = 0;
-
- if (rebuild) {
- char * problem;
- problem = write_collection(r->pool, pub, coll_base,
- DEFAULT_ENTRIES_IN_FEED);
- if (problem)
- return server_error(r, APR_SUCCESS,
- "Can't refresh collection '%s':
%s",
- r->filename, problem);
-
- /* of course, now the finfo is different */
- apr_stat(finfo, r->filename, basics, r->pool);
- r->finfo = *finfo;
- }
- }
+ }
+ r->finfo = finfo;
return OK;
}
-
- /* It has to exist... */
- if (status == APR_SUCCESS)
- return OK;
- /* ... unless this is a PUT into the extras space */
+ /* Initial stat failed. This may not be a problem.
+ * It has to exist... unless this is a PUT into the extras space
*/
if ((r->method_number == M_PUT) &&
- MATCHES(pub->patterns->extras_space, r->uri))
+ MATCHES(pub->patterns->extras_space, r->uri))
return OK;
return HTTP_NOT_FOUND;
@@ -491,15 +475,15 @@
*/
if (!is_atom_path) {
- if (r->method_number == M_POST || r->method_number == M_PUT ||
- r->method_number == M_DELETE)
- return HTTP_FORBIDDEN;
+ if (r->method_number == M_POST || r->method_number == M_PUT ||
+ r->method_number == M_DELETE)
+ return HTTP_FORBIDDEN;
- if (MATCHES(pub->patterns->entry, r->uri))
- return HTTP_FORBIDDEN;
+ if (MATCHES(pub->patterns->entry, r->uri))
+ return HTTP_FORBIDDEN;
- if (MATCHES(pub->patterns->collection, r->uri))
- return HTTP_FORBIDDEN;
+ if (MATCHES(pub->patterns->collection, r->uri))
+ return HTTP_FORBIDDEN;
}
return DECLINED;
}
@@ -537,7 +521,7 @@
if (MATCHES(pub->patterns->media_object, r->uri)) {
char * mt_name =
- apr_psprintf(r->pool, "%s.%s", r->filename,
MEDIA_TYPE_SUFFIX);
+ apr_psprintf(r->pool, "%s.%s", r->filename,
MEDIA_TYPE_SUFFIX);
char * problem;
char * media_type;
@@ -569,7 +553,7 @@
return DECLINED;
if (r->method_number == M_GET)
- return get(r, pub);
+ return get(r, pub);
switch (r->method_number) {
@@ -602,12 +586,14 @@
start = find_num(&a);
if (start == -1)
return HTTP_NOT_FOUND;
- } else if (strncmp(a, "count=", 6) == 0) {
+ }
+ else if (strncmp(a, "count=", 6) == 0) {
a += 6;
count = find_num(&a);
if (count == -1)
return HTTP_NOT_FOUND;
- } else
+ }
+ else
return HTTP_NOT_FOUND;
if (*a == '&')
@@ -657,12 +643,14 @@
return HTTP_UNSUPPORTED_MEDIA_TYPE;
if (MATCHES(pub->patterns->entries_space, r->uri)) {
if (strcmp(media_type, "application/atom+xml;type=entry") != 0
&&
- strcmp(media_type, "application/atom+xml") != 0)
+ strcmp(media_type, "application/atom+xml") != 0)
return HTTP_UNSUPPORTED_MEDIA_TYPE;
return post_entry(r, &entry);
- } else if (MATCHES(pub->patterns->media_space, r->uri)) {
+ }
+ else if (MATCHES(pub->patterns->media_space, r->uri)) {
return post_media(r, entry.pub);
- } else
+ }
+ else
return server_error(r, APR_SUCCESS,
"Weird media type '%s' on POST '%s'",
media_type, r->uri);
@@ -745,8 +733,8 @@
/* sanity-check media-type */
media_type = (char *) apr_table_get(r->headers_in,
"Content-Type");
if ((media_type == NULL) ||
- (strcmp(media_type, "application/atom+xml;type=entry")
!= 0 &&
- strcmp(media_type, "application/atom+xml") != 0))
+ (strcmp(media_type, "application/atom+xml;type=entry") !=
0 &&
+ strcmp(media_type, "application/atom+xml") != 0))
return HTTP_UNSUPPORTED_MEDIA_TYPE;
is_entry = 1;
@@ -755,9 +743,11 @@
if ((status = ap_xml_parse_input(r, &(entry.xml))) != OK)
return server_error(r, status, "Can't parse XML PUT
body");
- } else if (MATCHES(pub->patterns->media_object, r->uri)) {
+ }
+ else if (MATCHES(pub->patterns->media_object, r->uri)) {
is_entry = 0;
- } else {
+ }
+ else {
apr_table_set(r->headers_out, "Allow", "GET, HEAD");
return HTTP_METHOD_NOT_ALLOWED;
}
@@ -797,7 +787,7 @@
ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
"ETag mismatch on PUT (%s vs %s), rejected",
if_match, etag);
- unlock_file(mutex);
+ unlock_file(mutex);
return HTTP_PRECONDITION_FAILED;
}
@@ -827,7 +817,7 @@
char * linkname;
char * filename = entry_filename(r->pool, &entry);
- dir = atom_join(r->pool, entry.coll_base,
+ dir = atom_join(r->pool, entry.coll_base,
yyyymmdd_at(apr_time_now(), r->pool), NULL);
if ((problem = atom_dir(dir, r->pool)))
return server_error(r, APR_SUCCESS,
@@ -847,7 +837,7 @@
/* update the public-facing html & feed & front-page if required
*/
if ((entry.type_of_content != MEDIA_TYPE) &&
- MATCHES(pub->patterns->entries_space, r->uri))
+ MATCHES(pub->patterns->entries_space, r->uri))
write_html_entry(r, &entry);
return status;
@@ -875,12 +865,13 @@
return server_error(r, APR_SUCCESS,
"failed to delete directory '%s'",
r->filename);
- } else {
- if ((status = apr_file_remove(r->filename, r->pool)) !=
APR_SUCCESS)
- return server_error(r, status,
- "failed to delete file '%s'",
r->filename);
- }
- return HTTP_NO_CONTENT;
+ }
+ else {
+ if ((status = apr_file_remove(r->filename, r->pool)) !=
APR_SUCCESS)
+ return server_error(r, status,
+ "failed to delete file '%s'",
r->filename);
+ }
+ return HTTP_NO_CONTENT;
}
/* can't delete media resources directly */
@@ -915,24 +906,25 @@
return server_error(r, status,
"Can't remove media resource at '%s'",
bits);
- } else {
+ }
+ else {
/* not a media-link entry. Thus there may be an HTML or text
file
- * to lose; but there may not be, if the content@type was none
of
- * 'html', 'xhtml', or 'text'.
- * We could parse the entry and look at the content type
+ * to lose; but there may not be, if the content@type was
none of
+ * 'html', 'xhtml', or 'text'.
+ * We could parse the entry and look at the content type
* to figure out the exact name, but why not just try
deleting any
- * of them.
+ * of them.
*/
- char * extensions[] = { ".html", ".text", ".html", NULL };
- int i;
- char * base = apr_pstrdup(r->pool, r->filename);
- *(rindex(base, '.')) = 0;
+ char * extensions[] = {".html", ".text", ".html", NULL};
+ int i;
+ char * base = apr_pstrdup(r->pool, r->filename);
+ *(rindex(base, '.')) = 0;
- for (i = 0; extensions[i] && !html_removed; i++) {
- char * target = apr_pstrcat(r->pool, base, extensions[i],
NULL);
- status = apr_file_remove(target, r->pool);
- html_removed = html_removed || (status == APR_SUCCESS);
- }
+ for (i = 0; extensions[i] && !html_removed; i++) {
+ char * target = apr_pstrcat(r->pool, base, extensions[i],
NULL);
+ status = apr_file_remove(target, r->pool);
+ html_removed = html_removed || (status == APR_SUCCESS);
+ }
}
/* delete on a META will delete a whole publication. I hope they
@@ -954,21 +946,21 @@
namespaces = (char * *) entry->namespaces->elts;
for (child = entry->root->first_child; child; child =
child->next) {
if (strcmp(namespaces[child->ns], ATOM_NS) == 0 &&
- strcmp(child->name, "link") == 0) {
+ strcmp(child->name, "link") == 0) {
apr_xml_attr * a;
- char * href = NULL;
- char * rel = "";
+ char * href = NULL;
+ char * rel = "";
for (a = child->attr; a; a = a->next) {
if (a->ns == APR_XML_NS_NONE) {
- if (strcmp(a->name, "rel") == 0)
- rel = (char *) a->value;
- else if (strcmp(a->name, "href") == 0)
- href = (char *) a->value;
- }
+ if (strcmp(a->name, "rel") == 0)
+ rel = (char *) a->value;
+ else if (strcmp(a->name, "href") == 0)
+ href = (char *) a->value;
+ }
}
- if (strcmp(rel, "publication") == 0)
- sub_pub = href;
+ if (strcmp(rel, "publication") == 0)
+ sub_pub = href;
}
}
@@ -1018,6 +1010,43 @@
/********************* Utilities ***********************/
+/* Check (by looking at a timestamp) whether a collection file needs
to be
+ * updated, and update it if necessary. Fill in the finfo_t for the
+ * collection.
+ */
+static char * refresh_collection(char * coll_base, pub_t * pub,
+ apr_pool_t * pool, apr_finfo_t *
coll_finfo) {
+ apr_finfo_t ts_finfo;
+ apr_status_t ts_status, coll_status;
+ char * ts_fn = atom_join(pool, coll_base, TIMESTAMP_FILE, NULL);
+ char * coll_fn = atom_join(pool, coll_base, COLLECTION_FILE,
NULL);
+ int refresh = 1;
+ char * problem = NULL;
+
+ coll_status = apr_stat(coll_finfo, coll_fn, BASICS, pool);
+ ts_status = apr_stat(&ts_finfo, ts_fn, BASICS, pool);
+
+ /* note, rebuild even if the timestamp date and the collection
+ * date are the same. Stupid unix 1-second mtime granularity...
+ */
+ if (coll_status == APR_SUCCESS && ts_status == APR_SUCCESS &&
+ ts_finfo.mtime < coll_finfo->mtime)
+ refresh = 0;
+
+ if (refresh) {
+ problem = write_collection(pool, pub, coll_base,
+ DEFAULT_ENTRIES_IN_FEED);
+ if (problem == NULL) {
+ coll_status = apr_stat(coll_finfo, coll_fn, BASICS, pool);
+ if (coll_status != APR_SUCCESS)
+ problem = apr_psprintf(pool,
+ "Can't stat refreshed
collection '%s",
+ coll_fn);
+ }
+ }
+ return problem;
+}
+
/* write a timestamp indicating that a collection needs to be updated
*/
static void timestamp(char * dir, apr_pool_t * pool) {
@@ -1036,30 +1065,31 @@
apr_status_t status;
status = apr_file_open(&fp, mutex_name, APR_FOPEN_WRITE |
APR_FOPEN_CREATE,
- PERMS, p);
+ PERMS, p);
if (status == APR_SUCCESS) {
- status = apr_file_lock(fp, APR_FLOCK_EXCLUSIVE);
- if (status != APR_SUCCESS)
- apr_file_close(fp);
+ status = apr_file_lock(fp, APR_FLOCK_EXCLUSIVE);
+ if (status != APR_SUCCESS)
+ apr_file_close(fp);
}
if (status == APR_SUCCESS)
- *mutex_p = fp;
+ *mutex_p = fp;
return status;
}
+
static void unlock_file(void * mutex) {
apr_file_t * fp = (apr_file_t *) mutex;
if (apr_file_unlock(fp) != APR_SUCCESS)
- fprintf(stderr, "UNLOCK FAILED\n");
+ fprintf(stderr, "UNLOCK FAILED\n");
if (apr_file_close(fp) != APR_SUCCESS)
- fprintf(stderr, "CLOSE FAILED\n");
+ fprintf(stderr, "CLOSE FAILED\n");
}
/* apr equivalent of random() */
static long arandom() {
long ret;
- long mask = 1 << ((sizeof(long) * 8) - 1);
- apr_generate_random_bytes((unsigned char *) &ret, sizeof(long));
+ long mask = 1 << ((sizeof (long) * 8) - 1);
+ apr_generate_random_bytes((unsigned char *) & ret, sizeof (long));
return ret & ~mask;
}
@@ -1124,7 +1154,8 @@
if (apr_file_remove(fname, pool) != APR_SUCCESS)
return apr_psprintf(pool, "Can't remove file '%s' in
rm_rf",
fname);
- } else if (finfo.filetype == APR_DIR) {
+ }
+ else if (finfo.filetype == APR_DIR) {
if (strcmp(finfo.name, ".") == 0 || strcmp(finfo.name,
"..") == 0)
continue;
@@ -1198,7 +1229,7 @@
char * msg;
if (status != APR_SUCCESS) {
- char * em = error_message(r->pool, status);
+ char * em = error_message(r->pool, status);
fmt = apr_pstrcat(r->pool, fmt, ": ", NULL);
fmt = apr_pstrcat(r->pool, fmt, em, NULL);
@@ -1226,7 +1257,7 @@
};
if (e->ns == APR_XML_NS_NONE ||
- strcmp((char *) namespaces[e->ns], ATOM_NS) != 0)
+ strcmp((char *) namespaces[e->ns], ATOM_NS) != 0)
return 0;
for (i = 0; text_constructs[i]; i++)
@@ -1247,7 +1278,8 @@
if (*a == 0 || *a == '&') {
*a_p = a;
return sofar;
- } else
+ }
+ else
return -1;
}
@@ -1353,8 +1385,8 @@
entry_names = (char * *) apr_pcalloc(pool, count * sizeof (char
*));
for (problem = atom_iter_next(iter, &entry_name), i =
entries_in_feed = 0;
- entry_name && (!problem) && (entries_in_feed < (start +
count));
- problem = atom_iter_next(iter, &entry_name),
entries_in_feed++) {
+ entry_name && (!problem) && (entries_in_feed < (start +
count));
+ problem = atom_iter_next(iter, &entry_name),
entries_in_feed++) {
if (entries_in_feed >= start)
entry_names[i++] = entry_name;
}
@@ -1377,16 +1409,16 @@
char * entry_body;
if ((problem = atom_snarf(entry_names[i], &entry_body, pool)))
{
- /* in the situation where a file is found by the iterator
but
- * doesn't seem to be here, this seems to be just
filesystem
- * churn, we have to survive it
- */
- if (entry_body == SNARF_NOT_FOUND)
- continue;
- else
- return apr_psprintf(pool, "Can't read entry '%s': %s",
- entry_names[i], problem);
- }
+ /* in the situation where a file is found by the iterator
but
+ * doesn't seem to be here, this seems to be just
filesystem
+ * churn, we have to survive it
+ */
+ if (entry_body == SNARF_NOT_FOUND)
+ continue;
+ else
+ return apr_psprintf(pool, "Can't read entry '%s': %s",
+ entry_names[i], problem);
+ }
if (atom_genx_send(writer, entry_body) != GENX_SUCCESS)
return "Can't write to collection";
@@ -1415,28 +1447,28 @@
status = apr_file_open(&fp, tempname, APR_FOPEN_WRITE |
APR_FOPEN_CREATE,
PERMS, pool);
- if (status != APR_SUCCESS)
+ if (status != APR_SUCCESS)
return apr_psprintf(pool, "Can't open collection tempfile
'%s': %s",
tempname, error_message(pool, status));
writer = atom_genx_file_writer(pool, fp, &problem);
- if (!writer)
+ if (!writer)
return apr_psprintf(pool, "Can't start XML writer: '%s'",
problem);
ret = NULL;
problem = generate_collection(dirname, pool, pub, writer, 0,
size);
if (problem)
ret = apr_psprintf(pool, "Can't generate collection in '%s':
%s",
- dirname, problem);
+ dirname, problem);
apr_file_flush(fp);
apr_file_close(fp);
if (ret == NULL) {
- status = apr_file_rename(tempname, filename, pool);
- if (status != APR_SUCCESS)
+ status = apr_file_rename(tempname, filename, pool);
+ if (status != APR_SUCCESS)
ret = apr_psprintf(pool, "Can't rename '%s' to '%s': %s",
tempname, filename,
- error_message(pool, status));
+ error_message(pool, status));
}
return ret;
}
@@ -1609,13 +1641,13 @@
if (r->parsed_uri.port_str != NULL)
return atom_join(r->pool,
apr_psprintf(r->pool, "%s://%s:%s",
ap_http_scheme(r),
- r->hostname,
+ r->hostname,
r->parsed_uri.port_str),
relative, NULL);
else
return atom_join(r->pool,
apr_psprintf(r->pool, "%s://%s",
ap_http_scheme(r),
- r->hostname),
+ r->hostname),
relative, NULL);
}
@@ -1754,17 +1786,17 @@
apr_xml_elem * entry, apr_xml_doc * doc,
genxWriter gw) {
apr_xml_elem * title = NULL, * summary = NULL, * content = NULL,
- * author = NULL;
+ * author = NULL;
char * link = NULL;
char * wanted[] = {
- "title", "summary", "content", "author", NULL
+ "title", "summary", "content", "author", NULL
};
apr_xml_elem * * children[] = {
- &title, &summary, &content, &author
+ &title, &summary, &content, &author
};
if (is_draft(r->pool, doc))
- return;
+ return;
atom_xml_children(doc, entry, ATOM_NS, wanted, children);
link = atom_xml_link_href(doc, entry, "alternate");
@@ -1779,7 +1811,8 @@
genxAddAttributeLiteral(gw, NULL, (utf8) "href", (utf8) link);
atom_filter_text_construct(r->pool, doc, title, gw, 1);
genxEndElement(gw);
- } else
+ }
+ else
atom_filter_text_construct(r->pool, doc, title, gw, 1);
genxEndElement(gw); /* <div class="atom-entry-title> */
genxAddCharacter(gw, '\n');
@@ -1798,12 +1831,12 @@
if (author) {
apr_xml_elem * name = atom_xml_child(doc, author, ATOM_NS,
"name");
-
+
if (name) {
genxStartElementLiteral(gw, NULL, (utf8) "div");
genxAddAttributeLiteral(gw, NULL, (utf8) "class",
(utf8) "atom-entry-author");
- genxAddText(gw, (utf8) element_text(name, r->pool));
+ genxAddText(gw, (utf8) element_text(name, r->pool));
genxEndElement(gw); /* <div clss='atom-entry-author"> */
genxAddCharacter(gw, '\n');
}
@@ -1907,7 +1940,7 @@
if (strcmp(a->name, "label") == 0)
label = (utf8) a->value;
else if (strcmp(a->name, "term") == 0 &&
- label == NULL)
+ label == NULL)
label = (utf8) a->value;
}
}
@@ -1924,9 +1957,11 @@
}
genxEndElement(gw); /* </ul> */
genxAddCharacter(gw, '\n');
- } else if (strcmp(elem->name, "content") == 0) {
+ }
+ else if (strcmp(elem->name, "content") == 0) {
htmlify_text_construct(entry, "content", atom_ns, fields, gw,
r->pool);
- } else if (strcmp(elem->name, "contributors") == 0) {
+ }
+ else if (strcmp(elem->name, "contributors") == 0) {
/* put contributors in a comma-separated list, hyperlinked
names */
apr_xml_elem * * contribs = (apr_xml_elem * *) fields->elts;
count = find_entry_fields("contributor", atom_ns, entry,
fields);
@@ -1943,7 +1978,8 @@
}
genxEndElement(gw); /* </div> */
genxAddCharacter(gw, '\n');
- } else if (strcmp(elem->name, "entry-author") == 0) {
+ }
+ else if (strcmp(elem->name, "entry-author") == 0) {
apr_xml_elem * author;
count = find_entry_fields("author", atom_ns, entry, fields);
if (count != 1)
@@ -1955,7 +1991,8 @@
htmlify_person(author, gw, atom_ns, r->pool);
genxEndElement(gw); /* </author> */
genxAddCharacter(gw, '\n');
- } else if (strcmp(elem->name, "entry-script") == 0) {
+ }
+ else if (strcmp(elem->name, "entry-script") == 0) {
genxStartElementLiteral(gw, NULL, (constUtf8) "script");
genxAddAttributeLiteral(gw, NULL, (utf8) "type", (utf8)
"text/javascript");
genxAddAttributeLiteral(gw, NULL, (utf8) "src",
@@ -1964,7 +2001,8 @@
ENTRY_JS, NULL));
genxEndElement(gw);
genxAddCharacter(gw, '\n');
- } else if (strcmp(elem->name, "entry-stylesheet") == 0) {
+ }
+ else if (strcmp(elem->name, "entry-stylesheet") == 0) {
genxStartElementLiteral(gw, NULL, (constUtf8) "link");
genxAddAttributeLiteral(gw, NULL, (utf8) "rel", (utf8)
"stylesheet");
genxAddAttributeLiteral(gw, NULL, (utf8) "href",
@@ -1973,23 +2011,34 @@
ENTRY_CSS, NULL));
genxEndElement(gw);
genxAddCharacter(gw, '\n');
- } else if (strcmp(elem->name, "front-author") == 0) {
- } else if (strcmp(elem->name, "front-links") == 0) {
- } else if (strcmp(elem->name, "front-script") == 0) {
- } else if (strcmp(elem->name, "front-stylesheet") == 0) {
- } else if (strcmp(elem->name, "generator") == 0) {
+ }
+ else if (strcmp(elem->name, "front-author") == 0) {
+ }
+ else if (strcmp(elem->name, "front-links") == 0) {
+ }
+ else if (strcmp(elem->name, "front-script") == 0) {
+ }
+ else if (strcmp(elem->name, "front-stylesheet") == 0) {
+ }
+ else if (strcmp(elem->name, "generator") == 0) {
genxComment(gw, (utf8) GENERATOR);
genxAddCharacter(gw, '\n');
- } else if (strcmp(elem->name, "logo") == 0) {
- } else if (strcmp(elem->name, "pub-title") == 0) {
+ }
+ else if (strcmp(elem->name, "logo") == 0) {
+ }
+ else if (strcmp(elem->name, "pub-title") == 0) {
genxAddText(gw, (utf8) get_title(entry->pub, r->pool));
- } else if (strcmp(elem->name, "published") == 0) {
+ }
+ else if (strcmp(elem->name, "published") == 0) {
htmlify_date(entry, "published", atom_ns, gw, fields,
r->pool);
- } else if (strcmp(elem->name, "rights") == 0) {
+ }
+ else if (strcmp(elem->name, "rights") == 0) {
htmlify_text_construct(entry, "rights", atom_ns, fields, gw,
r->pool);
- } else if (strcmp(elem->name, "title") == 0) {
+ }
+ else if (strcmp(elem->name, "title") == 0) {
htmlify_text_construct(entry, "title", atom_ns, fields, gw,
r->pool);
- } else if (strcmp(elem->name, "updated") == 0) {
+ }
+ else if (strcmp(elem->name, "updated") == 0) {
htmlify_date(entry, "updated", atom_ns, gw, fields, r->pool);
}
}
@@ -2068,7 +2117,8 @@
FEED_FILE, NULL));
genxEndElement(gw);
genxAddCharacter(gw, '\n');
- } else if (strcmp(elem->name, "front-script") == 0) {
+ }
+ else if (strcmp(elem->name, "front-script") == 0) {
genxStartElementLiteral(gw, NULL, (utf8) "script");
genxAddAttributeLiteral(gw, NULL, (utf8) "type", (utf8)
"text/javascript");
genxAddAttributeLiteral(gw, NULL, (utf8) "src",
@@ -2078,7 +2128,8 @@
FRONT_PAGE_JS,
NULL));
genxEndElement(gw);
genxAddCharacter(gw, '\n');
- } else if (strcmp(elem->name, "front-stylesheet") == 0) {
+ }
+ else if (strcmp(elem->name, "front-stylesheet") == 0) {
genxStartElementLiteral(gw, NULL, (constUtf8) "link");
genxAddAttributeLiteral(gw, NULL, (utf8) "rel", (utf8)
"stylesheet");
genxAddAttributeLiteral(gw, NULL, (utf8) "href",
@@ -2087,21 +2138,25 @@
FRONT_PAGE_CSS,
NULL));
genxEndElement(gw);
genxAddCharacter(gw, '\n');
- } else if (strcmp(elem->name, "generator") == 0) {
+ }
+ else if (strcmp(elem->name, "generator") == 0) {
genxComment(gw, (utf8)
"Brought to you by the awesome power of XML, "
"the Atom Publishing Protocol, the Apache Web
server, "
"and mod_atom.");
genxAddCharacter(gw, '\n');
- } else if (strcmp(elem->name, "pub-author") == 0) {
+ }
+ else if (strcmp(elem->name, "pub-author") == 0) {
genxStartElementLiteral(gw, NULL, (utf8) "div");
genxAddAttributeLiteral(gw, NULL, (utf8) "class", (utf8)
"atom-author");
genxAddText(gw, (utf8) get_author(pub, r->pool));
genxEndElement(gw); /* </author> */
genxAddCharacter(gw, '\n');
- } else if (strcmp(elem->name, "pub-title") == 0) {
+ }
+ else if (strcmp(elem->name, "pub-title") == 0) {
genxAddText(gw, (utf8) get_title(pub, r->pool));
- } else if (strcmp(elem->name, "updated") == 0) {
+ }
+ else if (strcmp(elem->name, "updated") == 0) {
genxStartElementLiteral(gw, NULL, (utf8) "div");
genxAddAttributeLiteral(gw, NULL, (utf8) "class",
(utf8) "atom-date-updated");
@@ -2159,7 +2214,7 @@
apr_xml_doc * template;
if (!is_html_enabled(r->pool, pub))
- return;
+ return;
html_tmp = apr_psprintf(r->pool, "%s/%s%ld-%ld", coll_base,
TEMP_PREFIX, arandom(), arandom());
@@ -2178,14 +2233,14 @@
/* open tempfiles which will become index.html and feed */
status = apr_file_open(&html_fp, html_tmp,
- APR_FOPEN_WRITE | APR_FOPEN_CREATE, PERMS,
r->pool);
+ APR_FOPEN_WRITE | APR_FOPEN_CREATE, PERMS,
r->pool);
if (status != APR_SUCCESS) {
ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
"Can't create tempfile for front page '%s'",
html_tmp);
return;
}
status = apr_file_open(&feed_fp, feed_tmp,
- APR_FOPEN_WRITE | APR_FOPEN_CREATE, PERMS,
r->pool);
+ APR_FOPEN_WRITE | APR_FOPEN_CREATE, PERMS,
r->pool);
if (status != APR_SUCCESS) {
ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
"Can't create tempfile for public feed '%s'",
feed_tmp);
@@ -2260,22 +2315,22 @@
/* OK, now we'll run through the entries from the feed */
namespaces = (char * *) coll->namespaces->elts;
for (count = 0, entry = coll->root->first_child;
- entry && (count < DEFAULT_ENTRIES_IN_FEED);
- entry = entry->next) {
+ entry && (count < DEFAULT_ENTRIES_IN_FEED);
+ entry = entry->next) {
text_construct_type_t type = TEXT_TYPE;
- apr_xml_elem * content;
+ apr_xml_elem * content;
/* skip non-entries */
if (entry->ns == APR_XML_NS_NONE ||
- strcmp(namespaces[entry->ns], ATOM_NS) != 0 ||
- strcmp(entry->name, "entry") != 0)
+ strcmp(namespaces[entry->ns], ATOM_NS) != 0 ||
+ strcmp(entry->name, "entry") != 0)
continue;
/* for each atom:entry in the feed */
/* if the type on its content is other than MEDIA_TYPE, we'll
keep it */
- content = atom_xml_child(coll, entry, ATOM_NS, "content");
- if (content)
- type = atom_text_construct_type(content);
+ content = atom_xml_child(coll, entry, ATOM_NS, "content");
+ if (content)
+ type = atom_text_construct_type(content);
if (type == MEDIA_TYPE)
continue;
@@ -2315,9 +2370,9 @@
char * draft_val = "no";
if ((control = atom_xml_child(doc, doc->root, APP_NS, "control")))
{
- apr_xml_elem * draft;
- if ((draft = atom_xml_child(doc, control, APP_NS, "draft")))
- draft_val = element_text(draft, pool);
+ apr_xml_elem * draft;
+ if ((draft = atom_xml_child(doc, control, APP_NS, "draft")))
+ draft_val = element_text(draft, pool);
}
return !strcmp(draft_val, "yes");
@@ -2351,9 +2406,9 @@
* 2. the file x/options/html does not exist
*/
if (is_draft(r->pool, e->xml))
- return;
+ return;
if (!is_html_enabled(r->pool, e->pub))
- return;
+ return;
filename = atom_join(r->pool, e->pub->dir, PUB_DIR, e->path,
NULL);
filename = apr_pstrcat(r->pool, filename, extension, NULL);
@@ -2371,45 +2426,46 @@
/* type could be HTML, XHTML, or TEXT. If TEXT, just dump the
sucker */
if (e->type_of_content == TEXT_TYPE) {
- apr_xml_elem * content;
- char * problem;
+ apr_xml_elem * content;
+ char * problem;
- content = atom_xml_child(e->xml, e->xml->root, ATOM_NS,
"content");
- if ((problem = to_file(tempname, element_text(content,
r->pool),
- r->pool)))
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
- "Can't write text file '%s': %s", tempname,
problem);
- } else {
+ content = atom_xml_child(e->xml, e->xml->root, ATOM_NS,
"content");
+ if ((problem = to_file(tempname, element_text(content,
r->pool),
+ r->pool)))
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
+ "Can't write text file '%s': %s", tempname,
problem);
+ }
+ else {
- /* HTML */
- status = apr_file_open(&fp, tempname,
- APR_FOPEN_WRITE | APR_FOPEN_CREATE,
PERMS,
- r->pool);
- if (status != APR_SUCCESS) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
- "Can't create HTML file '%s'", tempname);
- return;
- }
- writer = atom_genx_file_writer(r->pool, fp, &problem);
- if (!writer) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
- "Can't make XML writer for '%s': %s",
- tempname, problem);
- return;
- }
+ /* HTML */
+ status = apr_file_open(&fp, tempname,
+ APR_FOPEN_WRITE | APR_FOPEN_CREATE,
PERMS,
+ r->pool);
+ if (status != APR_SUCCESS) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
+ "Can't create HTML file '%s'", tempname);
+ return;
+ }
+ writer = atom_genx_file_writer(r->pool, fp, &problem);
+ if (!writer) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
+ "Can't make XML writer for '%s': %s",
+ tempname, problem);
+ return;
+ }
- gw = atom_genx_get_writer(writer);
+ gw = atom_genx_get_writer(writer);
- template_fn = atom_join(r->pool, e->pub->dir, PUB_DIR,
EXTRAS_DIR,
- TEMPLATES_DIR, ENTRY_TEMPLATE, NULL);
- if (xnarf(template_fn, &template, r->pool) != APR_SUCCESS) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
- "Can't parse entry template '%s'",
template_fn);
- return;
- }
- run_e_template(gw, template, r, e);
- apr_file_flush(fp);
- apr_file_close(fp);
+ template_fn = atom_join(r->pool, e->pub->dir, PUB_DIR,
EXTRAS_DIR,
+ TEMPLATES_DIR, ENTRY_TEMPLATE, NULL);
+ if (xnarf(template_fn, &template, r->pool) != APR_SUCCESS) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
+ "Can't parse entry template '%s'",
template_fn);
+ return;
+ }
+ run_e_template(gw, template, r, e);
+ apr_file_flush(fp);
+ apr_file_close(fp);
}
/* rename tempfile to final target */
@@ -2417,7 +2473,7 @@
if (status != APR_SUCCESS) {
ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
"Can't rename '%s' to '%s': %s", tempname,
filename,
- error_message(r->pool, status));
+ error_message(r->pool, status));
}
update_public_site(r, e->pub, e->coll_base);
@@ -2496,7 +2552,7 @@
int ns_ind, char * type,
char * content) {
apr_xml_elem * e =
- (apr_xml_elem *) apr_pcalloc(r->pool, sizeof
(apr_xml_elem));
+ (apr_xml_elem *) apr_pcalloc(r->pool, sizeof (apr_xml_elem));
e->ns = ns_ind;
e->name = type;
@@ -2575,11 +2631,11 @@
int i;
int atom_ns = -1, app_ns = -1, xhtml_ns = -1;
apr_xml_elem * updated = NULL, * author = NULL,
- * id = NULL, * edited = NULL, * alt_link = NULL, *
edit_link = NULL;
+ * id = NULL, * edited = NULL, * alt_link = NULL, * edit_link =
NULL;
apr_xml_elem * root = e->xml->root;
char * mtime;
[trimmed for length]
|
[subversion:17] Working lazy-creation hooks for index.html and feed.atom. |
TimBray | 11/05/2008 |





