35#define WHO "ezmlm-cgi"
45#define SUBSCRIBE "-subscribe"
47#define TXT_CGI_SUBSCRIBE "\">[Subscribe To List]</a>\n"
48#define TXT_CGI_FAQ "\">[List FAQ]</a>\n"
60 "content-transfer-encoding\\mime-version";
83#define MAXULONG 0xffffffff
98#define DIRECT "psnpnz"
101#define DIRECT_PREV -1
102#define DIRECT_FIRST 3
113char strnum[FMT_ULONG];
185void oput(
const char *s,
unsigned int l)
187 if (buffer_put(&
bo,s,l) == -1)
200 logmsg(
WHO,100,FATAL,B(
"program error (please send bug report to ezmlmx@fehcom.de): ",s,
" Command: ",
cntl));
209void cgierr(
const char *s,
const char *s1,
const char *s2)
211 logmsg(
WHO,0,WARN,B(
"cgierr: ",s,s1,s2));
212 oputs(
"Content-type: text/html\n");
213 oputs(
"Status: 404 \n\n");
214 oputs(
"<html>\n <head> </head> <body> \n");
215 oputs(
"<h3><strong>ezmlm-cgi</strong>: <tt> ");
219 oputs(
"</tt></h3>\n</body>\n</html>\n");
247 if (case_startb(s,l,
"iso-8859") || case_startb(s,l,
"us-ascii") ||
248 case_startb(s,l,
"utf"))
250 if (case_startb(s,l,
"x-cp") ||
251 case_startb(s,l,
"cp") ||
252 case_startb(s,l,
"x-mac") ||
253 case_startb(s,l,
"koi8"))
return CS_NONE;
254 if (!l || *s ==
'x' || *s ==
'X')
return CS_BAD;
255 if (case_startb(s,l,
"iso-2022")) {
256 if (case_startb(s+8,l-8,
"-cn"))
258 if (case_startb(s+8,l-8,
"-jp"))
262 if (case_startb(s,l,
"cn-") ||
263 case_startb(s,l,
"hz-gb") ||
264 case_startb(s,l,
"gb") ||
265 case_startb(s,l,
"big5"))
267 if (case_startb(s,l,
"iso_8859") ||
268 case_startb(s,l,
"latin") ||
269 case_startb(s,l,
"windows"))
return CS_NONE;
300 case '>':
oputs(
">");
break;
301 case '<':
oputs(
"<");
break;
302 case '"':
oputs(
""");
break;
303 case '&':
oputs(
"&");
break;
311 default:
oput(s,1);
break;
318 else {
cn2 = 0;
cn1 = *s & 0x80; }
321 case '>':
oputs(
">");
break;
322 case '<':
oputs(
"<");
break;
323 case '"':
oputs(
""");
break;
324 case '&':
oputs(
"&");
break;
332 default:
oput(s,1);
break;
351 case SI:
so = 0;
break;
359 case '>':
oputs(
">");
break;
360 case '<':
oputs(
"<");
break;
361 case '"':
oputs(
""");
break;
362 case '&':
oputs(
"&");
break;
372 case SO:
so = 1;
break;
374 case SI:
so = 0;
break;
390 case 3:
switch (*s) {
393 case '(':
state = 20;
so = 0;
break;
395 case '.':
state = 10;
396 default:
state = 0;
break;
399 case 4:
switch (*s) {
406 case 5:
state = 0;
break;
407 case 11:
state = 0;
break;
408 case 21:
state = 0;
break;
409 default:
die_prog(
"bad state in html_put");
break;
436char hexchar[] =
"0123456789ABCDEF";
443 ch = (
unsigned char) *s;
444 if (ch <= 32 || ch > 127 || byte_chr(
"?<>=/:%+#\"",10,ch) != 10) {
445 enc_url[2] = hexchar[ch & 0xf];
446 enc_url[1] = hexchar[(ch >> 4) & 0xf];
460 unsigned char *cpl, *cpafter, *cpstart, *cpend;
463 pos = byte_chr(s,l,
':');
464 if (pos + 3 >= l || !pos) {
472 cpstart = (
char *) 0;
473 if (s[pos + 1] ==
'/' && s[pos + 2] ==
'/') {
476 for (i = pos - 1; (i < l && i + 6 >= pos); i--) {
477 if ((s[i] <
'a' || s[i] >
'z') && (s[i] <
'A' || s[i] >
'Z')) {
481 if (!i && i + 6 < pos) {
488 while (cpend < cpafter && str_chr(
" \t\n",*cpend) == 3)
491 while (cpend > cpstart && str_chr(
".,;])>\"\'",*cpend) != 8)
495 oput(cpstart,cpend - cpstart + 1);
497 html_put(cpstart,cpend - cpstart + 1);
501 if (pos >= l)
return;
505 pos += byte_chr(s + pos,l - pos,
':');
517 if (*s <
'a' || *s >
'p')
return 0;
531int uri2fn(stralloc *sa,
char item,
unsigned long n,
const char *hash)
533 if (!stralloc_copys(sa,
"archive/"))
die_nomem();
535 if (!stralloc_catb(sa,strnum,fmt_ulong(strnum,n/100)))
die_nomem();
537 if (!stralloc_catb(sa,strnum,fmt_uint0(strnum,(
unsigned int) (n%100),2)))
die_nomem();
539 if (!stralloc_cats(sa,
"threads/"))
die_nomem();
540 if (!stralloc_catb(sa,strnum,fmt_ulong(strnum,n)))
543 if (!stralloc_catb(sa,strnum,fmt_ulong(strnum,n/100)))
die_nomem();
544 if (!stralloc_cats(sa,
"/index"))
die_nomem();
547 if (!stralloc_cats(sa,
"authors/"))
die_nomem();
549 if (!stralloc_cats(sa,
"subjects/"))
die_nomem();
552 if (!stralloc_catb(sa,hash,2))
die_nomem();
572 unsigned long msgnum,
const char *
data,
unsigned int l)
576 cp = (
const char *) 0;
578 oputs(
"<a name=\"b\"></a>");
597 oput(strnum,fmt_ulong(strnum,infop->
date));
607 default:
oputs(
"#b\">");
break;
627 unsigned char c =
navstr[2];
628 if (c !=
's' && c !=
'p' && c !=
'n')
navstr[2] =
'p';
635 oput(strnum,fmt_ulong(strnum,infop->
date));
667 unsigned char c =
navstr[2];
668 if (c !=
's' && c !=
'p' && c !=
'n')
navstr[2] =
'p';
676 if (infop->
subjnav[direction]) {
684 if (infop->
authnav[direction]) {
689 acc = infop->
author;
break;
711 const char *
cp, *cp1, *cp2;
717 while (*cp1 && *cp1 !=
'=')
721 while (*cp2 && *cp2 !=
',') cp2++;
723 oput(cp1 + 1,cp2 - cp1 - 1);
735 oputs(
"<a href=\"mailto:");
742 oputs(
"<a href=\"mailto:");
758 oputs(
"<div class=msglinks><strong>Messages by: \n");
761 oputs(
"[←</a> ");
763 oputs(
">topic</a> ");
765 oputs(
"→]</a> \n");
768 oputs(
"[←</a> ");
772 oputs(
"→]</a> \n");
775 oputs(
"[←</a> ");
777 oputs(
">author</a> ");
779 oputs(
"→]</a> |\n");
782 oputs(
">[Topics]</a>\n");
786 oputs(
"</strong></div>\n");
798void html_header(
const char *
t,
const char *s,
unsigned int l,
const char *
class,
int flagspecial)
800 oputs(
"Content-Type: text/html; charset=");
803 oputs(
"\nCache-Control: ");
805 case 0:
oputs(
"no-cache");
break;
806 case 1:
oputs(
"max-age=300");
break;
807 case 2:
oputs(
"max-age=1209600");
break;
810 oputs(
"<!DOCTYPE html>\n<html>\n<head>\n<title>");
822 oputs(
"<link href=\"");
824 oputs(
"\" rel=\"stylesheet\" type=\"text/css\" />\n");
827 oputs(
"<meta name=\"robots\" content=\"noindex\" />\n");
829 oputs(
"<meta name=\"robots\" content=\"nofollow\" />\n");
833 if (
class && *
class) {
834 oputs(
"<body class=");
845 oputs(
"<div class=\"banner\">\n");
851 logmsg(
WHO,100,ERROR,
"Sorry - banner programs not supported");
854 oputs(
"</body>\n</html>\n");
877 oput(strnum,fmt_ulong(strnum,d));
900 unsigned long ddate, startdate;
901 unsigned long below, above;
905 startdate = infop->
date;
906 archivedir = opendir(
"archive/threads/");
913 while ((d = readdir(archivedir))) {
914 if (str_equal(d->d_name,
"."))
continue;
915 if (str_equal(d->d_name,
".."))
continue;
916 scan_ulong(d->d_name,&ddate);
917 if (!ddate)
continue;
919 if (ddate > startdate && ddate < above) above = ddate;
920 if (ddate < startdate && ddate > below) below = ddate;
922 if (ddate < above) above = ddate;
923 if (ddate > below) below = ddate;
926 closedir(archivedir);
940 infop->
date = ((
unsigned long)
dt.year + 2000) * 100 +
dt.mon + 1;
966 if (infop->
date%100 > 12) infop->
date += (100 - 12);
969 if (!infop->
date%100) infop->
date -= (100 - 12);
978 unsigned long tmpmsg;
982 oputs(
"<div class=idxlinks><strong>\n");
984 oputs(
">[⇐]</a>\n");
985 if (tmpmsg >= 100) infop->
target = tmpmsg - 100;
987 oputs(
">[←]</a>\n");
988 infop->
target = tmpmsg + 100;
990 oputs(
">[→]</a>\n");
993 oputs(
">[⇒]</a> |\n");
996 oputs(
">[Topics by date]</a>\n");
999 oputs(
"</strong></div>\n");
1004 unsigned long thismsg;
1010 if ((
fd = open_read(
fname.s)) == -1) {
1011 if (errno == ENOENT)
1018 if (!stralloc_copyb(&line,strnum,fmt_ulong(strnum,(
unsigned long) (infop->
target/100))))
1020 if (!stralloc_cats(&line,
"xx"))
die_nomem();
1023 oputs(
"<div><hr /></div><h1 id=\"idxhdr\">");
1025 oput(line.s,line.len);
1027 oputs(
"<div class=\"idx\"><hr />\n");
1030 if (getln(&
bi,&line,&
match,
'\n') == -1)
1033 pos = scan_ulong(line.s,&thismsg);
1037 if (line.len < pos + 1 +
HASHLEN)
1038 logmsg(
WHO,100,ERROR,
"index line with truncated subject entry");
1043 oput(strnum,fmt_uint0(strnum,(
unsigned int) thismsg % 100,2));
1048 if (getln(&
bi,&line,&
match,
'\n') == -1)
1051 pos = byte_chr(line.s,line.len,
';');
1052 if (pos != line.len) {
1062 oputs(
"\n<hr /></div>\n");
1071 oputs(
"<div class=objlinks><strong>\n");
1081 oputs(
">[Topics by date]</a>\n");
1085 oputs(
">[Messages by date]</a>\n");
1089 oputs(
"</strong></div>\n");
1100 unsigned long lastdate, thisdate, thismsg;
1113 default:
die_prog(
"Bad object type in show_object");
1116 if ((
fd = open_read(
fname.s)) == -1) {
1117 if (errno == ENOENT)
1125 if (getln(&
bi,&line,&
match,
'\n') == -1)
1134 oputs(
"<div><hr /></div><h1>On: ");
1141 oputs(
"<hr><h1>By: ");
1151 oputs(
"<hr>\n<h1>Topics for ");
1156 default:
die_prog(
"unrecognized object type in show_object");
1159 oputs(
"<div class=obj>\n");
1163 if (getln(&
bi,&line,&
match,
'\n') == -1)
1166 pos = scan_ulong(line.s,&thismsg);
1167 if (line.s[pos++] !=
':')
1168 logmsg(
WHO,100,ERROR,B(
"entry in ",
fname.s,
" lacks message number"));
1170 pos += scan_ulong(line.s + pos,&thisdate);
1171 infop->
date = thisdate;
1172 if (line.s[pos++] !=
':')
1175 if (line.len < pos +
HASHLEN + 2)
1178 if (thisdate != lastdate) {
1179 oputs(
"</ul><hr>\n");
1181 lastdate = thisdate;
1189 alink(infop,targetitem,linkitem,thismsg,line.s + pos,line.len - pos - 1);
1242 char *
cp, *cpafter, *cpnext;
1244 if (!*l || !**s)
return;
1247 cp = *s; cpnext =
cp + *l; cpafter = cpnext;
1248 while (
cp < cpafter) {
1249 if (*
cp ==
'"')
break;
1254 cp = *s; cpnext =
cp + *l; cpafter = cpnext;
1255 while (
cp < cpafter) {
1256 if (*
cp ==
' ' || *
cp ==
'\t' || *
cp ==
'\n' || *
cp ==
';')
break;
1263 *l = cpafter - cpnext;
1281 while (l && (*s ==
' ' || *s ==
'\t')) { s++; l--; }
1285 if (case_startb(st,lt,
"text")) {
1287 if (case_startb(st,lt,
"/plain")) {
1289 }
else if (case_startb(st,lt,
"/html")) {
1291 }
else if (case_startb(st,lt,
"/enriched")) {
1293 }
else if (case_startb(st,lt,
"/x-vcard")) {
1296 }
else if (case_startb(st,lt,
"multipart")) {
1298 if (case_startb(st,lt,
"/alternative")) {
1300 }
else if (case_startb(st,lt,
"/mixed")) {
1302 }
else if (case_startb(st,lt,
"/digest")) {
1304 }
else if (case_startb(st,lt,
"/signed")) {
1307 }
else if (case_startb(st,lt,
"message")) {
1309 if (case_startb(st,lt,
"/rfc822")) {
1316 while (l && (*s ==
' ' || *s ==
'\t' || *s ==
';' || *s ==
'\n')) {
1318 if (case_startb(s,l,
"boundary=")) {
1321 }
else if (case_startb(s,l,
"charset=")) {
1334 while (l && *s !=
'"') { s++, l--; }
1335 if (l) { s++, l--; }
1338 if (!l || *s ==
' ' || *s ==
'\t' || *s ==
'\n')
break;
1355 while (l && (*s ==
' ' || *s ==
'\t')) { s++; l--; }
1357 if (case_startb(s,l,
"quoted-printable")) {
1359 }
else if (case_startb(s,l,
"base64")) {
1375 if (*line.s !=
'-' || line.s[1] !=
'-')
return 0;
1379 if (line.len > tmp->
boundary.len + 2 &&
1381 if (line.s[tmp->
boundary.len + 2] ==
'-' &&
1382 line.s[tmp->
boundary.len + 3] ==
'-') {
1422 if (!stralloc_copyb(&
decline,strnum,fmt_ulong(strnum,infop->
target)))
1435 oputs(
"<div class=\"message\">\n");
1454 unsigned int colpos;
1463 for (flaghtml = whatheader = 0;;) {
1465 if (getln(&
bi,&line,&
match,
'\n') == -1)
1489 if (!flagstartseen)
continue;
1491 if (line.len == 1) {
1492 if (flagshowheaders) {
1495 oputs(
"<div class=\"rfc822hdr\"><hr />\n");
1497 for (i = 0; i <
NO_HDRS; i++) {
1500 oputs(
"<span class=\"subject\">");
1506 oputs(
"<a class=\"relk\" href=\"mailto:");
1525 oputs(
"</a></span>");
1552 flagshowheaders = 1;
1560 oputs(
"<strong>[\"");
1562 oputs(
"\" not shown]</strong>\n");
1574 default:
oputs(
"<hr><strong>[\"");
1576 oputs(
"\" not shown]</strong>\n");
1580 }
else if (line.s[0] !=
' ' && line.s[0] !=
'\t') {
1583 colpos = byte_chr(line.s,line.len,
':');
1584 if ((whatheader = constmap_index(&
headermap,line.s,colpos))) {
1586 if (!stralloc_copyb(&
hdr[whatheader - 1],line.s + colpos + 1,
1591 if (!stralloc_catb(&
hdr[whatheader - 1],line.s,line.len))
1595 if (flaggoodfield) {
1608 oput(line.s,line.len);
1626 if (*psz ==
'\\') *psz =
'\0';
1634 if ((
fd = open_read(
fname.s)) == -1) {
1635 if (errno == ENOENT)
1651 oputs(
"<hr /></div>\n");
1666 default:
cgierr(
"Navigation command contains ",
"illegal item code",
"");
1677 default:
cgierr(
"Navigation command contains ",
"illegal direction code",
"");
1701 infop->
author = (
char *)0;
1703 infop->
cgiarg = (
char *)0;
1705 if (!cmd || !*cmd) {
1715 if (ch >=
'0' && ch <=
'9') {
1726 if (*(cmd++) !=
':')
return 0;
1728 cmd += scan_ulong(cmd,&(infop->
source));
1729 if (*(cmd++) !=
':')
return 0;
1730 if (*cmd >=
'0' && *cmd <=
'9') {
1731 cmd += scan_ulong(cmd,&(infop->
date));
1732 if (!*cmd++)
return 1;
1745 unsigned long tmpmsg;
1750 if ((
fd = open_read(
fname.s)) == -1) {
1751 if (errno == ENOENT)
1759 if (getln(&
bi,&line,&
match,
'\n') == -1)
1764 if (*line.s ==
'\t')
continue;
1765 pos = scan_ulong(line.s,&tmpmsg);
1767 if (tmpmsg == infop->
source) {
1768 if (line.s[pos++] !=
':' || line.s[pos++] !=
' ')
1775 if (getln(&
bi,&line,&
match,
'\n') == -1)
1779 pos = byte_chr(line.s,line.len,
';');
1780 if (pos == line.len)
1817 if ((
fd = open_read(
fname.s)) == -1) {
1818 if (errno == ENOENT)
1826 if (getln(&
bi,&line,&
match,
'\n') == -1)
1836 if (getln(&
bi,&line,&
match,
'\n') == -1)
1841 pos = scan_ulong(line.s,&(
msgnav[2]));
1843 if (pos +
HASHLEN + 1 < line.len)
1849 if (getln(&
bi,&line,&
match,
'\n') == -1)
1852 scan_ulong(line.s,&(
msgnav[3]));
1853 if (getln(&
bi,&line,&
match,
'\n') == -1)
1856 scan_ulong(line.s,&(
msgnav[4]));
1862 switch (infop->
view) {
1874 infop->
author = (
char *)0;
1879 infop->
author = (
char *)0;
1881 default:
die_prog(
"Bad item in set_message");
1915 cgierr(
"Sorry, there are no more messages in the archive",
"",
"");
1917 scan_ulong(line.s,&(infop->
target));
1934 switch (infop->
item) {
2022 unsigned long msgset;
2025 archivedir = opendir(
"archive/");
2027 if (errno != ENOENT)
2033 html_header(
"Robot index for message sets in list",0,0,0,0);
2035 while ((d = readdir(archivedir))) {
2036 if (d->d_name[scan_ulong(d->d_name,&msgset)])
2038 oputs(
"<a href=\"../");
2042 oputs(
"\">[link]</a>\n");
2044 closedir(archivedir);
2050 unsigned int msgfirst,msgmax;
2051 unsigned long lastset;
2055 if (!stralloc_copys(&line,
"<a href=\"../"))
die_nomem();
2056 if (!stralloc_catb(&line,strnum,fmt_ulong(strnum,msgset)))
die_nomem();
2063 if (msgset > lastset) {
2066 }
else if (msgset == lastset) {
2070 html_header(
"Robot index for messages in set",0,0,0,0);
2071 while (msgfirst <= msgmax) {
2072 oput(line.s,line.len);
2073 oput(strnum,fmt_uint0(strnum,msgfirst,2));
2074 oputs(
"\">[link]</a>\n");
2086 if (chroot(
dir) == -1)
2088 if (setuid(
uid) == -1)
2091 euid = (
unsigned long) geteuid();
2100 char *thislistname = 0;
2101 unsigned long tmpuid, msgset;
2102 unsigned long msgnum = 0;
2103 unsigned long port = 0L;
2104 unsigned long tmptarget;
2113 uid = (
unsigned long) getuid();
2114 euid = (
unsigned long) geteuid();
2116 if ((ezcgirc = env_get(
"EZCGIRC"))) {
2117 if ((
fd = open_read(ezcgirc)) == -1)
2129 cntl = env_get(
"QUERY_STRING");
2130 cppath = env_get(
"PATH_INFO");
2132 if (!
cntl && !cppath) {
2136 if (!cppath || !*cppath) {
2138 pos = str_chr(
cntl,
'+');
2139 if (
cntl[pos] ==
'+') {
2141 thislistname =
cntl;
2145 }
else if (*cppath ==
'/') {
2147 thislistname = cppath;
2148 pos = str_chr(cppath,
'/');
2149 if (thislistname[pos] ==
'/') {
2150 thislistname[pos] =
'\0';
2155 if (!thislistname || !*thislistname) {
2158 cgierr(
"Sorry, no mailing list requested",
"",
"");
2168 pos = str_chr(
cfline.s,sep);
2172 if (
cfline.s[++pos] ==
'-') {
2176 pos += scan_ulong(
cfline.s + pos,&tmpuid);
2177 if (tmpuid)
uid = tmpuid;
2178 if (
cfline.s[pos++] != sep)
2179 die_syntax(
"missing separator after user id");
2180 if (
cfline.s[pos] !=
'/')
2183 if (l ==
cfline.len - pos)
2196 if (chdir(
dir) == -1)
2206 if (
cfline.s[pos] ==
'-') {
2212 if (l <
cfline.len - pos) {
2217 if (l <
cfline.len - pos) {
2222 if (l <
cfline.len - pos) {
2227 if (l <
cfline.len - pos) {
2241 pos = str_rchr(
local,
'@');
2242 if (
local[pos] !=
'@')
2244 local[pos++] =
'\0';
2250 if (*(cppath++) ==
'/') {
2251 cppath += scan_ulong(cppath,&msgset);
2258 if (cppath && *cppath) {
2260 scan_ulong(cppath,&
msgnum);
2267 if (!stralloc_copys(&
base,
"<base href=\"http://"))
die_nomem();
2270 cp = env_get(
"SERVER_PORT");
2272 (void) scan_ulong(
cp,&port);
2273 if ((
unsigned int) port == 443) {
2274 if (!stralloc_copys(&
base,
"<base href=\"https://"))
die_nomem();
2277 if ((
cp = env_get(
"HTTP_HOST")) || (
cp = env_get(
"SERVER_NAME"))) {
2279 if (port && (
unsigned int) port != 80 && (
unsigned int) port != 443) {
2281 if (!stralloc_catb(&
base,strnum,fmt_ulong(strnum,port)))
die_nomem();
2284 if ((
cp = env_get(
"SCRIPT_NAME")) != 0) {
2286 pos = str_rchr(
cp,
'/');
2307 cgierr(
"I'm sorry, Cpt. Nelson ... I can't navigate towards that, Cpt. Nelson ...",
"",
"");
2320 cgierr(
"I couldn't find the author for that message",
"",
"");
2323 cgierr(
"I couldn't find the subject for that message",
"",
"");
2346 default:
logmsg(
WHO,100,ERROR,
"bad item in main");
#define MIME_MESSAGE_RFC822
#define MIME_MULTI_DIGEST
#define MIME_MULTI_SIGNED
#define MIME_APPLICATION_OCTETSTREAM
#define MIME_MULTI_ALTERNATIVE
#define MIME_TEXT_ENRICHED
Error messages. If you translate these, I would urge you to keep the English version as well....
int getconf_line(stralloc *sa, const char *fn, int flagrequired, const char *dir)
unsigned int author_name(char **sout, char *s, unsigned int l)
void decode_b64(const char *cpfrom, unsigned int n, stralloc *outdata)
void decode_transfer_encoding(char *s, unsigned int l)
void findlastmsg(struct msginfo *infop)
int show_index(struct msginfo *infop)
void show_part(struct msginfo *infop, int flagshowheaders, int flagstartseen)
if flagshowheaders we display headers, otherwise not if flagstartseen we've already see the start bou...
void html_put(const char *s, unsigned int l)
At this time, us-ascii, iso-8859-? create no problems. We just encode some html chars....
void html_header(const char *t, const char *s, unsigned int l, const char *class, int flagspecial)
flagspecial: 0x1 => robot index; no style sheet, no BASE flagspecial: 0x2 => banner,...
void cgierr(const char *s, const char *s1, const char *s2)
void index_messages(struct msginfo *infop, unsigned char item)
for links from message view back to author/subject/threads index
void list_set(unsigned long msgset)
int navigate(struct msginfo *infop)
interprets msginfo to create msginfo. Upon return, msginfo can be trusted to have all info needed,...
int show_message(struct msginfo *infop)
void html_footer(int flagspecial)
char decode_item(char ch)
int uri2fn(stralloc *sa, char item, unsigned long n, const char *hash)
from the inputs: item, num, and hash the normalized and relative file name URI of the target message ...
struct constmap headermap
void urlencode_puts(const char *s)
void message_links(struct msginfo *infop)
Creates the html for all links from one message view.
int check_boundary()
return 0 if no boundary, 1 if start, 2 if end
void toggle_flagpre(int flag)
int show_object(struct msginfo *infop, char item)
shows thread, threads, author infop has the info needed to access the author/subject/thread file
void oput(const char *s, unsigned int l)
char decode_direction(char ch)
void set_message(struct msginfo *infop)
Reads the file corresponding to infop->view and assumes fname.s is set correctly for this....
#define TXT_CGI_SUBSCRIBE
int msg2hash(struct msginfo *infop)
void date2msg(struct msginfo *infop)
void gtdate(struct msginfo *infop, int flagfail)
infop->date has to be 0 or valid on entry. Month outside of [1-12] on entry causes GIGO
int checkhash(const char *s)
void list_list(const char *listname)
Make one link [for list_set()] per set of 100 archive messages. Assumption: Any directory DIR/archive...
void die_prog(const char *s)
void firstdate(struct msginfo *infop)
void auth2msg(struct msginfo *infop)
void anchor_put(unsigned char *s, unsigned int l)
void latestdate(struct msginfo *infop, int flagfail)
int decode_cmd(char *cmd, struct msginfo *infop)
decodes cmd into infop. Assures that no security problems slip through by checking everything cmd: iv...
void index_links(struct msginfo *infop)
void oputs(const char *s)
void urlencode_put(const char *s, unsigned int l)
void date_links(struct msginfo *infop, unsigned long d, char direction)
output a date with link back to thread index
void decode_mime_type(char *s, unsigned int l, unsigned int flagmime)
void subj2msg(struct msginfo *infop)
void nav_links(struct msginfo *infop, unsigned char view, unsigned char direction)
Creates using a maximum of available information only for links where the target is a message.
void start_message_page(struct msginfo *infop)
header etc for message. Delayed to collect subject so that we can put that in TITLE....
unsigned int decode_charset(const char *s, unsigned int l)
return charset code. CS_BAD: Means that base charset should be used, i.e. that charset is empty or li...
void drop_priv(int flagchroot)
void object_links(struct msginfo *infop, char item)
void finddate(struct msginfo *infop)
DIRECT_SAME works as DIRECT_PREV, dvs returns previous date or last date.
void alink(struct msginfo *infop, unsigned char item, unsigned char view, unsigned long msgnum, const char *data, unsigned int l)
links with targets other msgnum -> msgnum. If the link is for author, we still supply subject,...
void mime_getarg(stralloc *sa, char **s, unsigned int *l)
opies next token or "token" into sa and sets s & l appropriately for continuing the search
void decode_hdr(const char *indata, unsigned int n, stralloc *outdata)
int dateline(stralloc *dt, unsigned long d)
void datetime_tai(struct datetime *dt, datetime_sec t)
unsigned int date2yyyymm(const char *s)
void decode_qp(const char *cpfrom, unsigned int n, stralloc *outdata)
const char * logmsg(const char *dir, unsigned long num, unsigned long listno, unsigned long subs, int done)