40 #include <http_core.h>
50 #ifdef HAVE_SYS_TYPES_H
51 #include <sys/types.h>
60 static const char const Gfavicon[] =
"sound.png";
61 static const char const Gcd_icon[] =
"general.png";
62 static const char const Gorigcss[] =
"musicindex.css";
97 register unsigned short fld = 0, j = 0;
98 const char * restrict current = NULL, * restrict
new = NULL;
99 char * restrict codeduri = NULL;
100 unsigned long tlength = 0, tsize = pack->
fsize;
101 #ifdef HAVE_SETLOCALE
102 struct lconv *clconv = localeconv();
105 ap_rputs(
" <tr class=\"title\">\n", r);
109 ap_rvputs(r,
" <th class=\"Select\">",
_(
"Select"),
"</th>\n", NULL);
116 for (fld = 0; conf->
fields[fld]; fld++) {
117 switch (conf->
fields[fld]) {
155 current =
"Filetype";
167 current =
"Filename";
175 if ((current == NULL) || (
new == NULL))
184 ap_rvputs(r,
" <th class=\"", current,
"\">", NULL);
185 if ((customlist == 0) && !(conf->
search))
186 ap_rprintf(r,
"<a href=\"?sort=%d\">%s</a>", conf->
fields[fld],
new);
189 ap_rputs(
"</th>\n", r);
193 ap_rputs(
" </tr>\n", r);
199 for (q=pack->
fhead; q!= NULL; q=q->
next) {
201 if ((conf->
search != NULL) && (customlist == 0) &&
203 new = ap_make_dirstr_parent(r->pool, q->
file);
207 if (strcmp(current,
new)) {
209 ap_rprintf(r,
" <tr class=\"title\">\n"
210 " <th align=\"left\" colspan=\"%d\">", fld+1);
211 if ((current[0] ==
'\0') || (current[1] ==
'\0'))
212 ap_rputs(
_(
"In Current Directory"), r);
214 ap_rvputs(r,
_(
"In"),
" <a href=\"", ap_escape_html(r->pool, ap_escape_uri(r->pool, current)),
"\">", ap_escape_html(r->pool, current),
"</a>", NULL);
223 ap_rputs(
" <tr class=\"odd\">\n", r);
225 ap_rputs(
" <tr class=\"even\">\n", r);
233 ap_rputs(
" <td class=\"Select\">\n", r);
239 ap_rvputs(r,
" <input type=\"checkbox\" name=\"file\" value=\"",
240 codeduri,
"\" />\n", NULL);
245 ap_rvputs(r,
" <a class=\"dld\" href=\"", ap_escape_html(r->pool, ap_escape_uri(r->pool, q->
file)),
"\" title=\"",
_(
"Download"),
"\"> </a>\n", NULL);
248 ap_rvputs(r,
" <a class=\"stream\" href=\"", ap_escape_html(r->pool, ap_escape_uri(r->pool, q->
file)),
"?stream\" title=\"",
_(
"Stream"),
"\"> </a>\n", NULL);
251 ap_rvputs(r,
" <span class=\"dldok\" title=\"",
_(
"Download Allowed"),
"\"> </span>\n", NULL);
254 ap_rvputs(r,
" <span class=\"streamok\" title=\"",
_(
"Stream Allowed"),
"\"> </span>\n", NULL);
257 ap_rputs(
" </td>\n", r);
261 for (fld = 0; conf->
fields[fld]; fld++) {
262 switch (conf->
fields[fld]) {
264 ap_rvputs(r,
" <td class=\"Title\">", ap_escape_html(r->pool, q->
title),
"</td>\n", NULL);
268 ap_rprintf(r,
" <td class=\"Track\">%d</td>\n", q->
track);
270 ap_rputs(
" <td></td>\n", r);
274 ap_rprintf(r,
" <td class=\"Disc\">%d</td>\n", q->
posn);
276 ap_rputs(
" <td></td>\n", r);
279 ap_rprintf(r,
" <td class=\"Artist\">%s</td>\n", q->
artist ? ap_escape_html(r->pool, q->
artist) :
"");
285 ap_rprintf(r,
" <td class=\"Length\">%d:%.2d</td>\n", q->
length / 60, q->
length % 60);
288 ap_rputs(
" <td></td>\n", r);
294 ap_rprintf(r,
" <td class=\"Bitrate\"><acronym title=\"kbps%s\">%ld</acronym></td>\n", (q->
flags &
EF_VBR) ?
" VBR" :
"", q->
bitrate >> 10);
296 ap_rputs(
" <td></td>\n", r);
302 #ifdef HAVE_SETLOCALE
303 ap_rprintf(r,
" <td class=\"Freq\"><acronym title=\"kHz\">%d%s%d</acronym></td>\n", q->
freq / 1000, clconv->decimal_point, q->
freq % 1000 / 100);
305 ap_rprintf(r,
" <td class=\"Freq\"><acronym title=\"kHz\">%d.%d</acronym></td>\n", q->
freq / 1000, q->
freq % 1000 / 100);
308 ap_rputs(
" <td></td>\n", r);
312 ap_rprintf(r,
" <td class=\"Date\">%d </td>\n", q->
date);
314 ap_rputs(
" <td></td>\n", r);
317 ap_rprintf(r,
" <td class=\"Album\">%s</td>\n", q->
album ? ap_escape_html(r->pool, q->
album) :
"");
323 ap_rprintf(r,
" <td class=\"Genre\">%s</td>\n", q->
genre ? ap_escape_html(r->pool, q->
genre) :
"");
326 #ifdef HAVE_SETLOCALE
327 ap_rprintf(r,
" <td class=\"Size\"><acronym title=\"MB\">%ld%s%ld</acronym></td>\n", q->
size>>20, clconv->decimal_point, (((q->
size>>10)%1024)*10)>>10);
329 ap_rprintf(r,
" <td class=\"Size\"><acronym title=\"MB\">%ld.%ld</acronym></td>\n", q->
size>>20, (((q->
size>>10)%1024)*10)>>10);
333 ap_rvputs(r,
" <td class=\"Filename\">", ap_escape_html(r->pool, q->
filename),
"</td>\n", NULL);
340 ap_rputs(
" </tr>\n", r);
347 ap_rprintf(r,
" <tr class=\"stfoot\">\n <th align=\"left\" colspan=\"%d\">", fld+1);
351 ap_rvputs(r,
"<input type=\"checkbox\" name=\"all\" onclick=\"selall(this)\" />",
352 _(
"Select All"),
" - ", NULL);
354 ap_rprintf(r,
"%s: %ld:%.2ld:%.2ld - %s: %ld%s%ld MB</th>\n </tr>\n",
355 _(
"Total Length"), tlength / 60 / 60, tlength / 60 % 60, tlength % 60,
356 _(
"Total Size"), tsize >> 20,
357 #ifdef HAVE_SETLOCALE
358 clconv->decimal_point,
362 (((tsize >> 10) % 1024) * 10) >> 10);
388 static void send_url(request_rec *r,
const char *
const restrict uri,
const char *
const restrict command,
393 static char str_port[7], strtmp[6];
395 char * restrict bufcoded, * restrict decoded;
397 unsigned short l = 0;
398 unsigned register i=0, j=6;
404 strcpy(prefix,
"http://");
408 strcat(prefix, ap_get_server_name(r));
413 strcpy(prefix, ap_http_method(r));
414 strcat(prefix,
"://");
420 const char *
const auth =
apr_table_get(r->headers_in,
"Authorization");
422 bufcoded = strrchr(auth,
' ');
426 strncat(prefix, decoded, l);
443 strcat(prefix, ap_get_server_name(r));
451 l = ap_get_server_port(r);
453 strtmp[i++] =
"0123456789"[l%10];
458 str_port[j] = strtmp[--i];
460 strcat(prefix, str_port);
465 ap_rvputs(r, prefix, ap_escape_html(r->pool, ap_escape_uri(r->pool, uri)), NULL);
467 ap_rvputs(r, prefix, ap_escape_uri(r->pool, uri), NULL);
469 ap_rputs(command, r);
488 request_rec *subreq = NULL;
493 #ifdef HAVE_SETLOCALE
494 if ((uri = setlocale(LC_ALL, NULL))) {
496 if ((u = strchr(uri,
'.')))
503 ap_rvputs(r,
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
504 "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" "
505 "\"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">\n"
506 "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"", uri,
"\" lang=\"", uri,
"\">\n"
515 struct dirent *dstruct;
518 if ((dir = opendir(subreq->filename))) {
519 while ((dstruct = readdir(dir))) {
520 if ((dstruct->d_name[0] !=
'.') &&
521 (ext = strrchr(dstruct->d_name,
'.')) &&
522 (!strncmp(ext+1,
"css", 3))) {
524 if (!strcmp(dstruct->d_name,
Gorigcss))
526 if (!strcmp(dstruct->d_name, conf->
css))
527 ap_rputs(
" <link rel=\"stylesheet\" title=\"default\"", r);
529 ap_rvputs(r,
" <link rel=\"alternate stylesheet\" title=\"",
530 ap_escape_html(r->pool, ap_escape_uri(r->pool, dstruct->d_name)),
533 ap_rvputs(r,
" type=\"text/css\" href=\"", conf->
directory,
"/",
534 ap_escape_html(r->pool, ap_escape_uri(r->pool, dstruct->d_name)),
540 ap_destroy_sub_req(subreq);
545 ap_rputs(
" <link rel=\"stylesheet\" title=\"default\"", r);
547 ap_rputs(
" <link rel=\"alternate stylesheet\" title=\"Original\"", r);
548 ap_rvputs(r,
" type=\"text/css\" href=\"", conf->
directory,
"/",
Gorigcss,
"\" />\n", NULL);
552 ap_rvputs(r,
" <link rel=\"alternate\" type=\"application/rss+xml\" "
553 "title=\"",
_(
"Latest titles"),
"\" href=\"?action=RSS\" />\n", NULL);
554 ap_rputs(
" <link rel=\"alternate\" type=\"application/rss+xml\" "
555 "title=\"Podcast\" href=\"?action=podcast\" />\n", r);
559 ap_rputs(
" <script type=\"text/javascript\">\n"
561 " function selall(mine) {\n"
562 " for(var i=0; i<mine.form.elements.length; i++) {\n"
563 " var inpt = mine.form.elements[i];\n"
564 " var m = inpt.name.match(/-/g);\n"
565 " if ((inpt.name.substr(0,4) == 'file') && (m < 1)) {\n"
566 " inpt.checked = mine.form.all.checked;\n"
574 ap_rvputs(r,
" <link rel=\"shortcut icon\" href=\"", conf->
directory,
"/",
Gfavicon,
"\" />\n"
575 " <link rel=\"icon\" href=\"", conf->
directory,
"/",
Gfavicon,
"\" type=\"image/ico\" />\n"
576 " <title>",
_(
"Musical index of"),
" ", ap_escape_html(r->pool, r->uri),
"</title>\n"
579 "<!-- begin header -->\n", NULL);
581 ap_rputs(
"<div id=\"header\">\n"
582 " <div id=\"mainicon\">\n"
583 " <img alt=\"Dir\" src=\"", r);
605 ap_rputs(
" <div id=\"maintitle\">\n"
611 for (u = uri; *u !=
'\0'; u++) {
613 while ((*u !=
'/') && (*u !=
'\0'))
616 if (conf->
title == NULL) {
629 if ((u == uri) && (localconf->
title != NULL))
630 dir = localconf->
title;
633 ap_rvputs(r,
" <a href=\"", ap_escape_html(r->pool, ap_escape_uri(r->pool, uri)),
"/\">", ap_escape_html(r->pool, dir),
"</a>\n", NULL);
637 ap_rputs(
" <span class=\"rarrow\"> </span>\n", r);
641 ap_destroy_sub_req(subreq);
644 ap_rputs(
" </h1>\n", r);
647 ap_rvputs(r,
" <a class=\"shuffle\" "
648 "href=\"?option=recursive&option=shuffle&action=playall\""
649 " title=\"",
_(
"Shuffle All"),
"\"> </a>\n"
650 " <a class=\"stream\" "
651 "href=\"?option=recursive&action=playall\""
652 " title=\"",
_(
"Stream All"),
"\"> </a>\n", NULL);
656 ap_rvputs(r,
" <a class=\"tarball\" "
657 "href=\"?option=recursive&action=tarball\""
658 " title=\"",
_(
"Download All"),
"\"> </a>\n", NULL);
662 ap_rvputs(r,
" <a class=\"rss\" "
663 "href=\"?action=RSS\""
664 " title=\"",
_(
"RSS"),
"\"> </a>\n", NULL);
668 ap_rvputs(r,
" <br /><a class=\"rdir\" "
669 "href=\"?action=randomdir\">[",
670 _(
"Random subdirectory..."),
"]</a>\n </div>\n", NULL);
676 " <form method=\"post\" action=\"", ap_escape_html(r->pool, ap_escape_uri(r->pool, r->uri)),
"\""
677 " enctype=\"application/x-www-form-urlencoded\""
678 " id=\"searching\">\n"
680 " <input type=\"text\" name=\"search\" />\n"
682 " <button type=\"submit\" name=\"action\" value=\"Search\">",
_(
"Search"),
"</button>\n"
683 " <button type=\"submit\" name=\"action\" value=\"RecursiveSearch\">",
_(
"Recursive Search"),
"</button>\n"
684 " <input type=\"hidden\" name=\"action\" value=\"Search\" />\n"
692 "<!-- end header -->\n\n", r);
717 unsigned short dircnt = 0, nb = pack->
dirnb;
722 ap_rputs(
"<!-- begin subdirs -->\n<h2>",r);
723 ap_rprintf(r,
_(
"Music Directories (%d)"), nb);
724 ap_rputs(
"</h2>\n\n<table id=\"directories\">\n", r);
729 ap_rputs(
" <tr>\n", r);
731 ap_rvputs(r,
" <td>\n"
732 " <a href=\"", ap_escape_html(r->pool, ap_escape_uri(r->pool, q->
file)),
733 "\" class=\"bigdir\" title=\"",
_(
"Open"),
"\"> </a>\n"
735 " <a href=\"", ap_escape_html(r->pool, ap_escape_uri(r->pool, q->
file)),
"\">",
736 ap_escape_html(r->pool, q->
title),
"</a>", NULL);
740 ap_rputs(
"<br />\n", r);
742 ap_rvputs(r,
" <a class=\"shuffle\" href=\"",
743 ap_escape_html(r->pool, ap_escape_uri(r->pool, q->
file)),
744 "?option=recursive&option=shuffle&action=playall\""
745 " title=\"",
_(
"Shuffle"),
"\"> </a>\n"
746 " <a class=\"stream\" href=\"",
747 ap_escape_html(r->pool, ap_escape_uri(r->pool, q->
file)),
748 "?option=recursive&action=playall\""
749 " title=\"",
_(
"Stream"),
"\"> </a>\n", NULL);
753 ap_rvputs(r,
" <a class=\"tarball\" href=\"",
754 ap_escape_html(r->pool, ap_escape_uri(r->pool, q->
file)),
755 "?option=recursive&action=tarball\""
756 " title=\"",
_(
"Download"),
"\"> </a>\n", NULL);
760 ap_rvputs(r,
" <a class=\"rss\" href=\"",
761 ap_escape_html(r->pool, ap_escape_uri(r->pool, q->
file)),
763 " title=\"",
_(
"RSS"),
"\"> </a>\n", NULL);
767 ap_rputs(
"\n </div>\n"
773 ap_rputs(
" </tr>\n", r);
779 ap_rputs(
"</tr>\n", r);
781 ap_rputs(
"</table>\n<hr />\n<!-- end subdirs -->\n\n", r);
797 register unsigned short nb = 0;
798 unsigned long fnb = pack->
filenb;
799 const unsigned char *
const restrict order = conf->
order;
804 ap_rputs(
"<!-- begin tracks -->\n<h2>", r);
807 ap_rprintf(r,
_(
"Result List (%ld)"), fnb);
809 ap_rprintf(r,
_(
"Song List (%ld)"), fnb);
811 ap_rvputs(r,
"</h2>\n\n<form method=\"post\" action=\"", ap_escape_html(r->pool, ap_escape_uri(r->pool, r->uri)),
"\" "
812 "enctype=\"application/x-www-form-urlencoded\" id=\"tracks\">\n <table>\n", NULL);
816 ap_rputs(
" </table>\n", r);
821 " <input type=\"hidden\" name=\"sort\" value=\"", r);
822 for(nb=0; order[nb] && (nb<
SB_MAX); nb++)
823 ap_rprintf(r,
"%c", order[nb]+
'`');
824 ap_rvputs(r,
"\" />\n"
825 " <button type=\"submit\" name=\"action\" value=\"AddToPlaylist\" class=\"playlist\">",
826 _(
"Add To Playlist"),
"</button>\n", NULL);
828 if (conf->
search == NULL) {
829 ap_rvputs(r,
" <button type=\"submit\" name=\"action\" value=\"AddAllToPlaylist\" class=\"playlist\">",
830 _(
"Add All To Playlist"),
"</button>\n", NULL);
832 ap_rvputs(r,
" <button type=\"submit\" name=\"action\" value=\"ShuffleAll\">",
833 _(
"Shuffle All"),
"</button>\n"
834 " <button type=\"submit\" name=\"action\" value=\"PlayAll\">",
835 _(
"Play All"),
"</button>\n", NULL);
837 ap_rvputs(r,
" <button type=\"submit\" name=\"action\" value=\"DownloadAll\">",
838 _(
"Download All"),
"</button>\n", NULL);
842 ap_rvputs(r,
" <button type=\"submit\" name=\"action\" value=\"PlaySelected\">",
843 _(
"Play Selected"),
"</button>\n", NULL);
846 ap_rvputs(r,
" <button type=\"submit\" name=\"action\" value=\"DownloadSelected\">",
847 _(
"Download Selected"),
"</button>\n", NULL);
849 ap_rputs(
" </div>\n", r);
854 "<!-- end tracks -->\n\n", r);
875 register unsigned short nb = pack->
filenb;
880 ap_rputs(
"<!-- begin custom -->\n"
882 ap_rprintf(r,
_(
"Custom Playlist (%d)"), nb);
883 ap_rputs(
"</h2>\n\n", r);
885 ap_rvputs(r,
" <form method=\"post\" action=\"", ap_escape_html(r->pool, ap_escape_uri(r->pool, r->uri)),
"\" "
886 "enctype=\"application/x-www-form-urlencoded\" id=\"custom\">\n <table>\n", NULL);
890 ap_rvputs(r,
" </table>\n"
891 " <div>\n <button type=\"submit\" name=\"action\" value=\"RemoveFromPlaylist\" class=\"playlist\">",
892 _(
"Remove From Playlist"),
"</button>\n"
893 " <button type=\"submit\" name=\"action\" value=\"ClearPlaylist\" class=\"playlist\">",
894 _(
"Clear Playlist"),
"</button>\n"
895 " <button type=\"submit\" name=\"action\" value=\"StreamPlaylist\" class=\"playlist\">",
896 _(
"Stream Playlist"),
"</button>\n"
897 #ifdef ENABLE_OUTPUT_ARCHIVE
898 " <button type=\"submit\" name=\"action\" value=\"DownloadPlaylist\" class=\"playlist\">",
899 _(
"Download Playlist"),
"</button>\n"
906 "<!-- end custom -->\n\n", r);
925 ap_rputs(
"#EXTM3U\n", r);
927 for (; q; q = q->
next) {
932 ap_rprintf(r,
"#EXTINF:%i,", q->
length);
934 ap_rvputs(r, q->
artist,
" - ", NULL);
935 ap_rvputs(r, q->
title, NULL);
937 ap_rvputs(r,
" (", q->
album,
")", NULL);
964 ap_rputs(
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
968 ap_rputs(
"xmlns:itunes=\"http://www.itunes.com/dtds/podcast-1.0.dtd\" ", r);
970 ap_rvputs(r,
"version=\"2.0\">\n"
972 " <title>",
_(
"RSS Feed for "), ap_escape_html(r->pool, r->uri),
"</title>\n"
976 ap_rputs(
"</link>\n <description>", r);
977 ap_rprintf(r,
_(
"%d most recent songs from %s"), conf->
rss_items, ap_escape_html(r->pool, r->uri));
978 ap_rputs(
"</description>\n", r);
981 ap_rputs(
" <itunes:summary>", r);
982 ap_rprintf(r,
_(
"%d most recent songs from %s"), conf->
rss_items, ap_escape_html(r->pool, r->uri));
983 ap_rputs(
"</itunes:summary>\n", r);
987 " <docs>http://backend.userland.com/rss</docs>\n"
991 for (; limit && q; q = q->
next) {
992 ap_rvputs(r,
" <item>\n"
993 " <title>", ap_escape_html(r->pool, q->title),
"</title>\n", NULL);
996 ap_rputs(
" <link>", r);
998 ap_rputs(
"</link>\n", r);
1002 ap_rputs(
" <enclosure url=\"", r);
1004 ap_rprintf(r,
"\" length=\"%lu\" type=\"%s\" />\n",
1008 ap_rputs(
" <guild>", r);
1010 ap_rputs(
"</guild>\n", r);
1011 localtime_r(&q->mtime, &time_buf);
1012 strftime(date_buf, 32,
"%a, %e %b %Y %H:%M:%S %z", &time_buf);
1013 ap_rprintf(r,
" <pubDate>%s</pubDate>\n", date_buf);
1015 ap_rprintf(r,
"<itunes:duration>%u:%.2u</itunes:duration>",
1016 q->length / 60, q->length % 60);
1020 ap_rvputs(r,
" <description>\n ",
_(
"Artist"),
" | ",
_(
"Album"),
" | ",
_(
"Track"),
" | ",
_(
"Disc"),
1021 " | ",
_(
"Length"),
" | ",
_(
"Genre"),
" | ",
_(
"Bitrate"),
" | ",
_(
"Freq"),
" | ",
_(
"Filetype"),
1022 " | ",
_(
"Size"),
"<br />\n", NULL);
1023 ap_rprintf(r,
" %s | %s | ", q->artist ? ap_escape_html(r->pool, q->artist) :
"",
1024 q->album ? ap_escape_html(r->pool, q->album) :
"");
1026 ap_rprintf(r,
"%u", q->track);
1029 ap_rprintf(r,
"%u", q->posn);
1032 ap_rprintf(r,
"%u:%.2u", q->length / 60, q->length % 60);
1034 ap_rprintf(r,
"%s | ", q->genre ? ap_escape_html(r->pool, q->genre) :
"");
1036 ap_rprintf(r,
"%lu %s", q->bitrate >> 10, (q->flags &
EF_VBR) ?
"VBR" :
"");
1039 ap_rprintf(r,
"%u", q->freq);
1042 ap_rputs(
" </description>\n"
1047 ap_rputs(
" </channel>\n"
1069 const char *filename, *uri, *nextfile, *nexturi;
1070 unsigned short nb, test, i;
1071 unsigned int seed = time(NULL);
1073 struct dirent *dirent;
1080 filename =
apr_pstrcat(r->pool, filename,
"/", NULL);
1083 dir = opendir(filename);
1088 while ((dirent = readdir(dir)))
1089 if ((dirent->d_name[0] !=
'.') && (access(r->filename, R_OK|X_OK) == 0))
1095 apr_table_setn(r->headers_out,
"Location", ap_construct_url(r->pool, ap_escape_uri(r->pool, uri), r));
1103 test = (int)(1.0*nb*rand_r(&seed)/(RAND_MAX+1.0));
1107 while((i <= test) && (dirent = readdir(dir)))
1108 if ((dirent->d_name[0] !=
'.') && (access(r->filename, R_OK|X_OK) == 0))
1112 nextfile =
apr_pstrcat(r->pool, filename, dirent->d_name, NULL);
1113 nexturi =
apr_pstrcat(r->pool, uri, dirent->d_name, NULL);
1121 apr_table_setn(r->headers_out,
"Location", ap_construct_url(r->pool, ap_escape_uri(r->pool, uri), r));
1126 filename = nextfile;
1148 #ifdef HAVE_GETTIMEOFDAY
1149 struct timeval tvend, tvres;
1150 #ifdef HAVE_SETLOCALE
1151 struct lconv *tlconv = NULL;
1155 ap_rputs(
"<!-- begin footer -->\n"
1158 "<div id=\"footer\">\n"
1159 " <div id=\"valid\">\n", r);
1162 if (subreq && !access(
apr_pstrcat(r->pool, subreq->filename,
"/valid-xhtml11", NULL), R_OK)) {
1164 ap_rvputs(r,
" <img src=\"", icn,
"\" alt=\"Valid XHTML 1.1!\" />\n", NULL);
1167 ap_rputs(
" <a href=\"http://validator.w3.org/check?uri=referer\">\n"
1168 " <img src=\"http://www.w3.org/Icons/valid-xhtml11\"\n"
1169 " alt=\"Valid XHTML 1.1!\" height=\"31\" width=\"88\" />\n"
1172 if (subreq && !access(
apr_pstrcat(r->pool, subreq->filename,
"/vcss", NULL), R_OK)) {
1174 ap_rvputs(r,
" <img src=\"", icn,
"\" alt=\"Valid CSS!\" />\n", NULL);
1177 ap_rputs(
" <a href=\"http://jigsaw.w3.org/css-validator/check/referer\">\n"
1178 " <img src=\"http://jigsaw.w3.org/css-validator/images/vcss\"\n"
1179 " alt=\"Valid CSS!\" height=\"31\" width=\"88\" />\n"
1182 if (subreq && !access(
apr_pstrcat(r->pool, subreq->filename,
"/valid-rss.png", NULL), R_OK)) {
1184 ap_rvputs(r,
" <img src=\"", icn,
"\" alt=\"[Valid RSS]\" title=\"Validate my RSS feed\" />\n", NULL);
1187 ap_rputs(
" <a href=\"http://validator.w3.org/feed/check.cgi?uri=referer\">\n"
1188 " <img src=\"http://validator.w3.org/feed/images/valid-rss.png\"\n"
1189 " alt=\"[Valid RSS]\" title=\"Validate my RSS feed\" />\n"
1191 ap_rputs(
" </div>\n", r);
1193 #ifdef HAVE_GETTIMEOFDAY
1195 gettimeofday(&tvend, NULL);
1196 timersub(&tvend, tvbegin, &tvres);
1197 ap_rputs(
" <div id=\"timing\">", r);
1198 ap_rprintf(r,
"<!-- processing completed in %u.%.6u s -->", tvprocess->tv_sec, tvprocess->tv_usec);
1199 #ifdef HAVE_SETLOCALE
1200 tlconv = localeconv();
1201 ap_rprintf(r,
_(
"in %u%s%.6u s"), tvres.tv_sec, tlconv->decimal_point, tvres.tv_usec);
1203 ap_rprintf(r,
_(
"in %u.%.6u s"), tvres.tv_sec, tvres.tv_usec);
1205 ap_rputs(
"</div>\n", r);
1209 ap_rputs(
" <div id=\"name\">"
1210 "<a href=\"http://freecode.com/projects/musicindex/\">"
1213 "<!-- end footer -->\n\n"