diff --git a/.gitignore b/.gitignore index e78d0b3..9f346a5 100644 --- a/.gitignore +++ b/.gitignore @@ -103,3 +103,11 @@ deps/libuuid/Makefile.in deps/libuuid/aclocal.m4 deps/libuuid/ltmain.sh utils/qwknet/qwktoss +deps/libuuid/config.h.in~ +deps/libuuid/compile +deps/libuuid/config.guess +deps/libuuid/config.sub +deps/libuuid/config.h.in +deps/libuuid/depcomp +deps/libuuid/install-sh +deps/libuuid/missing diff --git a/STRINGS.CHANGES b/STRINGS.CHANGES index 415cdf5..ea77325 100644 --- a/STRINGS.CHANGES +++ b/STRINGS.CHANGES @@ -12,6 +12,10 @@ LINE 127 MODIFIED OLDSTRING: "\e[2J\e[1;1H\e[1;37;44m[MSG#] Subject From To Date \r\n\e[0m" NEWSTRING: "\e[1;37;44m[MSG#] Subject From To Date \r\n\e[0m" +LINE 64 MODIFIED +OLDSTRING: "\e[2J\e[1;1H\e[1;37;44m[MSG#] Subject From Date \r\n\e[0m" +NEWSTRING: "\e[1;37;44m[MSG#] Subject From Date \r\n\e[0m" + Changes from v0.10-alpha -> v0.11-alpha -------------------------------------------------------------- diff --git a/deps/aha/aha.c b/deps/aha/aha.c index bac96b0..194fd23 100644 --- a/deps/aha/aha.c +++ b/deps/aha/aha.c @@ -20,6 +20,7 @@ #include #include #include +#include "../../src/www_tree.h" extern void unmangle_ansi(char *body, int len, char **body_out, int *body_len); @@ -84,17 +85,7 @@ void deleteParse(pelem elem) } } -void append_output(char **output, char *stuff, int *size, int *at) { - while (*at + strlen(stuff) + 1 >= *size) { - *size += 256; - *output = realloc(*output, *size); - } - - strcat(*output, stuff); - *at += strlen(stuff); -} - -char * aha(char *input) +struct www_tag * aha(char *input, struct www_tag *parent) { //Searching Parameters char *unmangle_out; @@ -116,13 +107,11 @@ char * aha(char *input) int newline=-1; int temp; char *ptr = unmangle_out; - char *output = (char *)malloc(256); int size = 256; int outat = 0; char minibuf[2]; - - - memset(output, 0, 256); + struct www_tag *child = NULL; + stralloc data = EMPTY_STRALLOC; while (*ptr != '\0') { @@ -138,7 +127,7 @@ char * aha(char *input) //Searching the end (a letter) and safe the insert: c= *ptr++; if (c == '\0') { - return output; + return parent; } if ( c == '[' ) // CSI code, see https://en.wikipedia.org/wiki/ANSI_escape_code#Colors { @@ -149,7 +138,7 @@ char * aha(char *input) { c=*ptr++; if (c == '\0') { - return output; + return parent; } buffer[counter]=c; if (c=='>') //end of htop @@ -238,340 +227,201 @@ char * aha(char *input) //Checking the differences if ((fc!=ofc) || (bc!=obc) || (ul!=oul) || (bo!=obo) || (bl!=obl)) //ANY Change { - if ((ofc!=-1) || (obc!=-1) || (oul!=0) || (obo!=0) || (obl!=0)) - append_output(&output, "", &size, &outat); if ((fc!=-1) || (bc!=-1) || (ul!=0) || (bo!=0) || (bl!=0)) { - append_output(&output, " 0) { + stralloc_0(&data); + struct www_tag *datatag = www_tag_new(NULL, data.s); + free(data.s); + data = EMPTY_STRALLOC; + if (child == NULL) { + www_tag_add_child(parent, datatag); + } else { + www_tag_add_child(child, datatag); + www_tag_add_child(parent, child); + } + } + child = www_tag_new("span", NULL); + + stralloc output = EMPTY_STRALLOC; + switch (fc) { case 0: if (bo) { - append_output(&output, "color:dimgray;", &size, &outat); + stralloc_cats(&output, "color:dimgray;"); } else { - append_output(&output, "color:dimgray;", &size, &outat); + stralloc_cats(&output, "color:dimgray;"); } break; //Black case 1: if (bo) { - append_output(&output, "color:#FF8888;", &size, &outat); + stralloc_cats(&output, "color:#FF8888;"); } else { - append_output(&output, "color:red;", &size, &outat); + stralloc_cats(&output, "color:red;"); } break; //Red case 2: if (bo) { - append_output(&output, "color:lime;", &size, &outat); + stralloc_cats(&output, "color:lime;"); } else { - append_output(&output, "color:#00ff00;", &size, &outat); + stralloc_cats(&output, "color:#00FF00;"); } break; //Green case 3: if (bo) { - append_output(&output, "color:yellow;", &size, &outat); + stralloc_cats(&output, "color:yellow;"); } else { - append_output(&output, "color:olive;", &size, &outat); + stralloc_cats(&output, "color:olive;"); } break; //Yellow case 4: if (bo) { - append_output(&output, "color:#8888FF;", &size, &outat); + stralloc_cats(&output, "color:#8888FF;"); } else { - append_output(&output, "color:#0000FF;", &size, &outat); + stralloc_cats(&output, "color:#0000FF;"); } break; //Blue case 5: if (bo) { - append_output(&output, "color:fuchsia;", &size, &outat); + stralloc_cats(&output, "color:fuchsia;"); } else { - append_output(&output, "color:#FF00FF;", &size, &outat); + stralloc_cats(&output, "color:#FF00FF;"); } break; //Purple case 6: if (bo) { - append_output(&output, "color:aqua;", &size, &outat); + stralloc_cats(&output, "color:aqua;"); } else { - append_output(&output, "color:#008888;", &size, &outat); + stralloc_cats(&output, "color:#008888;"); } break; //Cyan case 7: if (bo) { - append_output(&output, "color:white;", &size, &outat); + stralloc_cats(&output, "color:white;"); } else { - append_output(&output, "color:grey;", &size, &outat); + stralloc_cats(&output, "color:grey;"); } break; //White case 8: - append_output(&output, "color:black;", &size, &outat); + stralloc_cats(&output, "color:black;"); break; //Background Colour case 9: - append_output(&output, "color:white;", &size, &outat); + stralloc_cats(&output, "color:white;"); break; //Foreground Color } switch (bc) { case 0: - append_output(&output, "background-color:black;", &size, &outat); + stralloc_cats(&output, "background-color:black;"); break; //Black case 1: - append_output(&output, "background-color:red;", &size, &outat); + stralloc_cats(&output, "background-color:red;"); break; //Red case 2: - append_output(&output, "background-color:lime;", &size, &outat); + stralloc_cats(&output, "background-color:lime;"); break; //Green case 3: - append_output(&output, "background-color:yellow;", &size, &outat); + stralloc_cats(&output, "background-color:yellow;"); break; //Yellow case 4: - append_output(&output, "background-color:#3333FF;", &size, &outat); + stralloc_cats(&output, "background-color:#3333FF;"); break; //Blue case 5: - append_output(&output, "background-color:fuchsia;", &size, &outat); + stralloc_cats(&output, "background-color:fuchsia;"); break; //Purple case 6: - append_output(&output, "background-color:aqua;", &size, &outat); + stralloc_cats(&output, "background-color:aqua;"); break; //Cyan case 7: - append_output(&output, "background-color:white;", &size, &outat); + stralloc_cats(&output, "background-color:white;"); break; //White case 8: - append_output(&output, "background-color:black;", &size, &outat); + stralloc_cats(&output, "background-color:black;"); break; //Background Colour case 9: - append_output(&output, "background-color:white;", &size, &outat); + stralloc_cats(&output, "background-color:white;"); break; //Foreground Colour } if (ul) { - append_output(&output, "text-decoration:underline;", &size, &outat); + stralloc_cats(&output, "text-decoration:underline;"); } if (bl) { - append_output(&output, "text-decoration:blink;", &size, &outat); + stralloc_cats(&output, "text-decoration:blink;"); } - append_output(&output, "\">", &size, &outat); + stralloc_0(&output); + www_tag_add_attrib(child, "style", output.s); + free(output.s); } } } } - else - if (c==13) - { - //for (;line<80;line++) - - // append_output(&output, " ", &size, &outat); - line=0; - momline++; - append_output(&output, "
\n", &size, &outat); - } else if (c!=8) { line++; - if (newline>=0) - { - while (newline>line) - { - append_output(&output, " ", &size, &outat); - line++; - } - newline=-1; - } switch (c) { - case '\x01' : append_output(&output, "☺", &size, &outat); break; - case '\x02' : append_output(&output, "☻", &size, &outat); break; - case '\x03' : append_output(&output, "♥", &size, &outat); break; - case '\x04' : append_output(&output, "♦", &size, &outat); break; - case '\x05' : append_output(&output, "♣", &size, &outat); break; - case '\x06' : append_output(&output, "♠", &size, &outat); break; - case '\x07' : append_output(&output, "•", &size, &outat); break; - case '\x08' : append_output(&output, "◘", &size, &outat); break; - case '\x09' : append_output(&output, "○", &size, &outat); break; - //case '\x0a' : append_output(&output, "◘", &size, &outat); break; - case '\x0b' : append_output(&output, "♂", &size, &outat); break; - case '\x0c' : append_output(&output, "♀", &size, &outat); break; - //case '\x0d' : append_output(&output, "♪", &size, &outat); break; - case '\x0e' : append_output(&output, "♫", &size, &outat); break; - case '\x0f' : append_output(&output, "☼", &size, &outat); break; - case '\x10' : append_output(&output, "▸", &size, &outat); break; - case '\x11' : append_output(&output, "◂", &size, &outat); break; - case '\x12' : append_output(&output, "↕", &size, &outat); break; - case '\x13' : append_output(&output, "‼", &size, &outat); break; - case '\x14' : append_output(&output, "¶", &size, &outat); break; - case '\x15' : append_output(&output, "§", &size, &outat); break; - case '\x16' : append_output(&output, "▬", &size, &outat); break; - case '\x17' : append_output(&output, "↨", &size, &outat); break; - case '\x18' : append_output(&output, "↑", &size, &outat); break; - case '\x19' : append_output(&output, "↓", &size, &outat); break; - case '\x1a' : append_output(&output, "→", &size, &outat); break; - case '\x1b' : append_output(&output, "←", &size, &outat); break; - case '\x1c' : append_output(&output, "∟", &size, &outat); break; - case '\x1d' : append_output(&output, "↔", &size, &outat); break; - case '\x1e' : append_output(&output, "▴", &size, &outat); break; - case '\x1f' : append_output(&output, "▾", &size, &outat); break; - case '\x21' : append_output(&output, "!", &size, &outat); break; - case '\x22' : append_output(&output, """, &size, &outat); break; - case '\x23' : append_output(&output, "#", &size, &outat); break; - case '\x24' : append_output(&output, "$", &size, &outat); break; - case '\x25' : append_output(&output, "%", &size, &outat); break; - case '\x26' : append_output(&output, "&", &size, &outat); break; - case '\x27' : append_output(&output, "'", &size, &outat); break; - case '\x28' : append_output(&output, "(", &size, &outat); break; - case '\x29' : append_output(&output, ")", &size, &outat); break; - case '\x2a' : append_output(&output, "*", &size, &outat); break; - case '\x2b' : append_output(&output, "+", &size, &outat); break; - case '\x2c' : append_output(&output, ",", &size, &outat); break; - case '\x2d' : append_output(&output, "-", &size, &outat); break; - case '\x2e' : append_output(&output, ".", &size, &outat); break; - case '\x2f' : append_output(&output, "/", &size, &outat); break; - case '\x7f' : append_output(&output, "⌂", &size, &outat); break; - case '\x80' : append_output(&output, "Ç", &size, &outat); break; - case '\x81' : append_output(&output, "ü", &size, &outat); break; - case '\x82' : append_output(&output, "é", &size, &outat); break; - case '\x83' : append_output(&output, "â", &size, &outat); break; - case '\x84' : append_output(&output, "ä", &size, &outat); break; - case '\x85' : append_output(&output, "à", &size, &outat); break; - case '\x86' : append_output(&output, "å", &size, &outat); break; - case '\x87' : append_output(&output, "ç", &size, &outat); break; - case '\x88' : append_output(&output, "ê", &size, &outat); break; - case '\x89' : append_output(&output, "ë", &size, &outat); break; - case '\x8a' : append_output(&output, "è", &size, &outat); break; - case '\x8b' : append_output(&output, "ï", &size, &outat); break; - case '\x8c' : append_output(&output, "î", &size, &outat); break; - case '\x8d' : append_output(&output, "ì", &size, &outat); break; - case '\x8e' : append_output(&output, "Ä", &size, &outat); break; - case '\x8f' : append_output(&output, "Å", &size, &outat); break; - case '\x90' : append_output(&output, "É", &size, &outat); break; - case '\x91' : append_output(&output, "æ", &size, &outat); break; - case '\x92' : append_output(&output, "Æ", &size, &outat); break; - case '\x93' : append_output(&output, "ô", &size, &outat); break; - case '\x94' : append_output(&output, "ö", &size, &outat); break; - case '\x95' : append_output(&output, "ò", &size, &outat); break; - case '\x96' : append_output(&output, "û", &size, &outat); break; - case '\x97' : append_output(&output, "ù", &size, &outat); break; - case '\x98' : append_output(&output, "ÿ", &size, &outat); break; - case '\x99' : append_output(&output, "Ö", &size, &outat); break; - case '\x9a' : append_output(&output, "Ü", &size, &outat); break; - case '\x9b' : append_output(&output, "¢", &size, &outat); break; - case '\x9c' : append_output(&output, "£", &size, &outat); break; - case '\x9d' : append_output(&output, "¥", &size, &outat); break; - case '\x9e' : append_output(&output, "₧", &size, &outat); break; - case '\x9f' : append_output(&output, "ƒ", &size, &outat); break; - case '\xa0' : append_output(&output, "á", &size, &outat); break; - case '\xa1' : append_output(&output, "í", &size, &outat); break; - case '\xa2' : append_output(&output, "ó", &size, &outat); break; - case '\xa3' : append_output(&output, "ú", &size, &outat); break; - case '\xa4' : append_output(&output, "ñ", &size, &outat); break; - case '\xa5' : append_output(&output, "Ñ", &size, &outat); break; - case '\xa6' : append_output(&output, "ª", &size, &outat); break; - case '\xa7' : append_output(&output, "º", &size, &outat); break; - case '\xa8' : append_output(&output, "¿", &size, &outat); break; - case '\xa9' : append_output(&output, "⌐", &size, &outat); break; - case '\xaa' : append_output(&output, "¬", &size, &outat); break; - case '\xab' : append_output(&output, "½", &size, &outat); break; - case '\xac' : append_output(&output, "¼", &size, &outat); break; - case '\xad' : append_output(&output, "¡", &size, &outat); break; - case '\xae' : append_output(&output, "«", &size, &outat); break; - case '\xaf' : append_output(&output, "»", &size, &outat); break; - case '\xb0' : append_output(&output, "░", &size, &outat); break; - case '\xb1' : append_output(&output, "▒", &size, &outat); break; - case '\xb2' : append_output(&output, "▓", &size, &outat); break; - case '\xb3' : append_output(&output, "│", &size, &outat); break; - case '\xb4' : append_output(&output, "┤", &size, &outat); break; - case '\xb5' : append_output(&output, "╡", &size, &outat); break; - case '\xb6' : append_output(&output, "╢", &size, &outat); break; - case '\xb7' : append_output(&output, "╖", &size, &outat); break; - case '\xb8' : append_output(&output, "╕", &size, &outat); break; - case '\xb9' : append_output(&output, "╣", &size, &outat); break; - case '\xba' : append_output(&output, "║", &size, &outat); break; - case '\xbb' : append_output(&output, "╗", &size, &outat); break; - case '\xbc' : append_output(&output, "╝", &size, &outat); break; - case '\xbd' : append_output(&output, "╜", &size, &outat); break; - case '\xbe' : append_output(&output, "╛", &size, &outat); break; - case '\xbf' : append_output(&output, "┐", &size, &outat); break; - case '\xc0' : append_output(&output, "└", &size, &outat); break; - case '\xc1' : append_output(&output, "┴", &size, &outat); break; - case '\xc2' : append_output(&output, "┬", &size, &outat); break; - case '\xc3' : append_output(&output, "├", &size, &outat); break; - case '\xc4' : append_output(&output, "─", &size, &outat); break; - case '\xc5' : append_output(&output, "┼", &size, &outat); break; - case '\xc6' : append_output(&output, "╞", &size, &outat); break; - case '\xc7' : append_output(&output, "╟", &size, &outat); break; - case '\xc8' : append_output(&output, "╚", &size, &outat); break; - case '\xc9' : append_output(&output, "╔", &size, &outat); break; - case '\xca' : append_output(&output, "╩", &size, &outat); break; - case '\xcb' : append_output(&output, "╦", &size, &outat); break; - case '\xcc' : append_output(&output, "╠", &size, &outat); break; - case '\xcd' : append_output(&output, "═", &size, &outat); break; - case '\xce' : append_output(&output, "╬", &size, &outat); break; - case '\xcf' : append_output(&output, "╧", &size, &outat); break; - case '\xd0' : append_output(&output, "╨", &size, &outat); break; - case '\xd1' : append_output(&output, "╤", &size, &outat); break; - case '\xd2' : append_output(&output, "╥", &size, &outat); break; - case '\xd3' : append_output(&output, "╙", &size, &outat); break; - case '\xd4' : append_output(&output, "╛", &size, &outat); break; - case '\xd5' : append_output(&output, "╒", &size, &outat); break; - case '\xd6' : append_output(&output, "╓", &size, &outat); break; - case '\xd7' : append_output(&output, "╫", &size, &outat); break; - case '\xd8' : append_output(&output, "╪", &size, &outat); break; - case '\xd9' : append_output(&output, "┘", &size, &outat); break; - case '\xda' : append_output(&output, "┌", &size, &outat); break; - case '\xdb' : append_output(&output, "█", &size, &outat); break; - case '\xdc' : append_output(&output, "▄", &size, &outat); break; - case '\xdd' : append_output(&output, "▌", &size, &outat); break; - case '\xde' : append_output(&output, "▐", &size, &outat); break; - case '\xdf' : append_output(&output, "▀", &size, &outat); break; - case '\xe0' : append_output(&output, "α", &size, &outat); break; - case '\xe1' : append_output(&output, "β", &size, &outat); break; - case '\xe2' : append_output(&output, "Γ", &size, &outat); break; - case '\xe3' : append_output(&output, "π", &size, &outat); break; - case '\xe4' : append_output(&output, "Σ", &size, &outat); break; - case '\xe5' : append_output(&output, "σ", &size, &outat); break; - case '\xe6' : append_output(&output, "µ", &size, &outat); break; - case '\xe7' : append_output(&output, "τ", &size, &outat); break; - case '\xe8' : append_output(&output, "Φ", &size, &outat); break; - case '\xe9' : append_output(&output, "Θ", &size, &outat); break; - case '\xea' : append_output(&output, "Ω", &size, &outat); break; - case '\xeb' : append_output(&output, "δ", &size, &outat); break; - case '\xec' : append_output(&output, "∞", &size, &outat); break; - case '\xed' : append_output(&output, "∅", &size, &outat); break; - case '\xee' : append_output(&output, "∈", &size, &outat); break; - case '\xef' : append_output(&output, "∩", &size, &outat); break; - case '\xf0' : append_output(&output, "≡", &size, &outat); break; - case '\xf1' : append_output(&output, "±", &size, &outat); break; - case '\xf2' : append_output(&output, "≥", &size, &outat); break; - case '\xf3' : append_output(&output, "≤", &size, &outat); break; - case '\xf4' : append_output(&output, "⌠", &size, &outat); break; - case '\xf5' : append_output(&output, "⌡", &size, &outat); break; - case '\xf6' : append_output(&output, "÷", &size, &outat); break; - case '\xf7' : append_output(&output, "≈", &size, &outat); break; - case '\xf8' : append_output(&output, "°", &size, &outat); break; - case '\xf9' : append_output(&output, "∙", &size, &outat); break; - case '\xfa' : append_output(&output, "·", &size, &outat); break; - case '\xfb' : append_output(&output, "√", &size, &outat); break; - case '\xfc' : append_output(&output, "ⁿ", &size, &outat); break; - case '\xfd' : append_output(&output, "²", &size, &outat); break; - case '\xfe' : append_output(&output, "▪", &size, &outat); break; - case '<': append_output(&output, "<", &size, &outat); break; - case '>': append_output(&output, ">", &size, &outat); break; - case '\n':case 13: momline++; - line=0; - append_output(&output, "
\n", &size, &outat); - break; - case ' ': append_output(&output, " ", &size, &outat); break; + + case '\n': + case 13: + momline++; + line=0; + struct www_tag *brtag = www_tag_new("br", NULL); + if (data.len > 0) { + if (child != NULL) { + stralloc_0(&data); + struct www_tag *datatag = www_tag_new(NULL, data.s); + free(data.s); + data = EMPTY_STRALLOC; + www_tag_add_child(child, datatag); + www_tag_add_child(child, brtag); + www_tag_add_child(parent, child); + child = www_tag_duplicate(child); + } else { + stralloc_0(&data); + struct www_tag *datatag = www_tag_new(NULL, data.s); + free(data.s); + data = EMPTY_STRALLOC; + www_tag_add_child(parent, datatag); + www_tag_add_child(parent, brtag); + } + } else { + + + if (child != NULL) { + www_tag_add_child(child, brtag); + www_tag_add_child(parent, child); + child = www_tag_duplicate(child); + + } else { + www_tag_add_child(parent, brtag); + } + } + break; default: { - sprintf(minibuf, "%c", c); - append_output(&output, minibuf, &size, &outat); + stralloc_append1(&data, c); + break; } } } } - - //Footer - if ((fc!=-1) || (bc!=-1) || (ul!=0) || (bo!=0) || (bl!=0)) - append_output(&output, "
\n", &size, &outat); + + if (data.len > 0) { + stralloc_0(&data); + struct www_tag *datatag = www_tag_new(NULL, data.s); + free(data.s); + data = EMPTY_STRALLOC; + if (child == NULL) { + www_tag_add_child(parent, datatag); + } else { + www_tag_add_child(child, datatag); + www_tag_add_child(parent, child); + } + } free(unmangle_out); - return output; + return parent; } diff --git a/dist/magicka.strings b/dist/magicka.strings index c0683a1..55a94c3 100644 --- a/dist/magicka.strings +++ b/dist/magicka.strings @@ -61,7 +61,7 @@ Non-STDIO door support on SSH is currently broken...\r\n \e[1;30m-------------------------------------------------------------------------------\e[0m\r\n \e[1;37mPress \e[1;36mR\e[1;37m to reply, \e[1;36mD\e[1;37m to delete \e[1;36mEnter\e[1;37m to quit...\e[0m\r\n \r\nYou have no email\r\n -\e[2J\e[1;1H\e[1;37;44m[MSG#] Subject From Date \r\n\e[0m +\e[1;37;44m[MSG#] Subject From Date \r\n\e[0m \e[1;30m[\e[1;34m%4d\e[1;30m]\e[1;32m*\e[1;37m%-39.39s \e[1;32m%-16.16s \e[1;35m%02d:%02d %02d-%02d-%02d\e[K\e[0m\r\n \e[1;30m[\e[1;34m%4d\e[1;30m] \e[1;37m%-39.39s \e[1;32m%-16.16s \e[1;35m%02d:%02d %02d-%02d-%02d\e[K\e[0m\r\n \e[1;37mEnter \e[1;36m# \e[1;37mto read, \e[1;36mQ \e[1;37mto quit or \e[1;36mEnter\e[1;37m to continue\e[0m\r\n diff --git a/src/GNUmakefile.common b/src/GNUmakefile.common index 8b16f71..c38f6e6 100644 --- a/src/GNUmakefile.common +++ b/src/GNUmakefile.common @@ -43,7 +43,7 @@ ${CDK}: ${UUID}: rm ${DEPSDIR}/libuuid/ltmain.sh ${DEPSDIR}/libuuid/libtool || true cd ${DEPSDIR}/libuuid/ && ${LIBTOOLIZE} - cd ${DEPSDIR}/libuuid/ && autoreconf + cd ${DEPSDIR}/libuuid/ && autoreconf -fi cd ${DEPSDIR}/libuuid/ && ./configure cd ${DEPSDIR}/libuuid/ && ${MAKE} CC=${CC} @@ -57,7 +57,7 @@ OBJS:= inih/ini.o bbs.o main.o users.o main_menu.o mail_menu.o \ nodelist.o blog.o util.o stralloc/stralloc.o ${EXTRAOBJS} WWWOBJS:= ../deps/aha/aha.o ../deps/hashids/hashids.o www.o www_email.o \ - www_msgs.o www_last10.o www_blog.o www_files.o ${OBJS} + www_msgs.o www_last10.o www_blog.o www_files.o www_tree.o ${OBJS} ifeq ($(MAKECMDGOALS), www) CFLAGS+= ${CFLAGS} -Istralloc -I${DEPSDIR}/libb64-1.2/include -DENABLE_WWW=1 @@ -67,7 +67,7 @@ endif ${CC} -c -o $@ $< ${CFLAGS} magickawww: ${OBJS} ${WWWOBJS} ${LUA} ${ZMODEM} ${B64} ${JAMLIB} ${JSMN} ${UUID} - ${CC} -o ../magicka $^ ${LIBS} -lmicrohttpd + ${CC} -o ../magicka $^ ${LIBS} -lmicrohttpd magicka: ${OBJS} ${LUA} ${ZMODEM} ${JAMLIB} ${JSMN} ${UUID} ${CC} -o ../magicka $^ ${LIBS} @@ -106,7 +106,7 @@ clean: rm -f ${OBJS} ${WWWOBJS} ../magicka cd ${DEPSDIR}/lua && ${MAKE} clean cd ${DEPSDIR}/jamlib && ${MAKE} -f ${DEPS_JAMLIB_MAKEFILE} clean - cd ${DEPSDIR}/Xmodem && ${MAKE} clean + cd ${DEPSDIR}/Xmodem && ${MAKE} clobber cd ${UTILSDIR}/magimail && ${MAKE} clean cd ${UTILSDIR}/magiedit && ${MAKE} clean cd ${DEPSDIR}/odoors && rm -rf libs-${OS} objs-${OS} exe-${OS} @@ -120,4 +120,6 @@ clean: cd ${UTILSDIR}/reset_pass && ${MAKE} clean cd ${UTILSDIR}/dosbox_shim && ${MAKE} clean cd ${DEPSDIR}/libuuid && ${MAKE} clean + cd ${DEPSDIR}/libuuid && rm -rf .libs cd ${DEPSDIR}/cutest-1.5 && ${MAKE} clean + cd ${DEPSDIR}/jsmn && ${MAKE} clean diff --git a/src/GNUmakefile.haiku b/src/GNUmakefile.haiku index 5b9d3a0..3e05fe5 100644 --- a/src/GNUmakefile.haiku +++ b/src/GNUmakefile.haiku @@ -1,9 +1,9 @@ CC:= cc -CFLAGS:= -std=gnu99 -DDISABLE_MQTT=1 +CFLAGS:= -std=gnu99 -DDISABLE_MQTT=1 LIBS:= -lm -lssl -lcrypto -liconv -lsqlite3 -lnetwork -lbsd -lssh -EXTRAOBJS:= strlcpy/strlcpy.o strlcpy/strlcat.o +EXTRAOBJS:= strlcpy/strlcpy.o strlcpy/strlcat.o -LIBTOOLIZE:= libtoolize +LIBTOOLIZE:= libtoolize DEPS_LUA_TARGET:= haiku DEPS_JAMLIB_MAKEFILE:= Makefile.linux diff --git a/src/bbs.c b/src/bbs.c index 6828517..5d86df4 100644 --- a/src/bbs.c +++ b/src/bbs.c @@ -725,15 +725,10 @@ void record_last10_callers(struct user_record *user) { void display_last10_callers(struct user_record *user) { struct last10_callers callers[10]; - char last10_path[PATH_MAX]; - - int i, z; + int i = 0; struct tm l10_time; - snprintf(last10_path, PATH_MAX, "%s/last10v2.dat", conf.bbs_path); - - FILE *fptr = fopen(last10_path, "rb"); - time_t l10_timet; + FILE *fptr = fopen_bbs_path("last10v2.dat", "rb"); s_printf("\e[2J\e[1;1H"); @@ -741,7 +736,6 @@ void display_last10_callers(struct user_record *user) { s_printf(get_string(3)); if (fptr != NULL) { - for (i = 0; i < 10; i++) { if (fread(&callers[i], sizeof(struct last10_callers), 1, fptr) < 1) { break; @@ -749,12 +743,10 @@ void display_last10_callers(struct user_record *user) { } fclose(fptr); - } else { - i = 0; } - for (z = 0; z < i; z++) { - l10_timet = callers[z].time; + for (int z = 0; z < i; z++) { + time_t l10_timet = callers[z].time; localtime_r(&l10_timet, &l10_time); if (conf.date_style == 1) { s_printf(get_string(4), callers[z].name, callers[z].location, l10_time.tm_hour, l10_time.tm_min, l10_time.tm_mon + 1, l10_time.tm_mday, l10_time.tm_year - 100, (callers[z].calls == 1 ? 'N' : ' ')); @@ -789,7 +781,6 @@ void automessage_write() { FILE *fptr; char automsg[450]; char buffer[76]; - char automsg_path[PATH_MAX]; int i; struct tm timenow; time_t timen; @@ -813,9 +804,7 @@ void automessage_write() { strlcat(automsg, "\r\n", sizeof automsg); } - snprintf(automsg_path, PATH_MAX, "%s/automessage.txt", conf.bbs_path); - - fptr = fopen(automsg_path, "w"); + fptr = fopen_bbs_path("automessage.txt", "w"); if (fptr) { fwrite(automsg, strlen(automsg), 1, fptr); fclose(fptr); @@ -826,32 +815,23 @@ void automessage_write() { } void automessage_display() { - struct stat s; - FILE *fptr; char buffer[90]; - char automsg_path[PATH_MAX]; int i; s_printf("\r\n\r\n"); - snprintf(automsg_path, PATH_MAX, "%s/automessage.txt", conf.bbs_path); - - if (stat(automsg_path, &s) == 0) { - fptr = fopen(automsg_path, "r"); - if (fptr) { - for (i = 0; i < 5; i++) { - memset(buffer, 0, 90); - fgets(buffer, 88, fptr); - buffer[strlen(buffer) - 1] = '\r'; - buffer[strlen(buffer)] = '\n'; - - s_printf(buffer); - } - fclose(fptr); - } else { - dolog("Error opening automessage.txt"); - } - } else { + FILE *fptr = fopen_bbs_path("automessage.txt", "r"); + if (fptr == NULL) { + dolog("Error opening automessage.txt"); s_printf(get_string(17)); + } else { + for (i = 0; i < 5; i++) { + memset(buffer, 0, 90); + fgets(buffer, 88, fptr); + buffer[strlen(buffer) - 1] = '\r'; + buffer[strlen(buffer)] = '\n'; + s_printf(buffer); + } + fclose(fptr); } s_printf(get_string(6)); s_getc(); diff --git a/src/bbs.h b/src/bbs.h index 1e51fab..b0da565 100644 --- a/src/bbs.h +++ b/src/bbs.h @@ -280,6 +280,8 @@ extern void ptr_vector_apply(struct ptr_vector *vec, void (*f)(void *arg)); extern void **ptr_vector_ptrs(struct ptr_vector *vec); extern void **consume_ptr_vector(struct ptr_vector *vec); extern void destroy_ptr_vector(struct ptr_vector *vec); +extern FILE *fopen_bbs_path(const char *filename, const char *mode); +extern FILE *fopen_node_path(const char *filename, const char *mode); extern char *str_replace(const char *orig, const char *rep, const char *with); extern int copy_file(char *src, char *dest); @@ -313,6 +315,8 @@ extern void gen_salt(char **s); extern char *hash_sha256(char *pass, char *salt); extern int save_user(struct user_record *user); extern int check_user(char *loginname); +extern int check_fullname_j(char *firstandlastname); +extern int check_fullname(char *firstname, char *lastname); extern struct user_record *new_user(); extern struct user_record *check_user_pass(char *loginname, char *password); extern void list_users(struct user_record *user); diff --git a/src/bbs_list.c b/src/bbs_list.c index ad86467..db63170 100644 --- a/src/bbs_list.c +++ b/src/bbs_list.c @@ -259,8 +259,9 @@ void bbs_list() { } redraw = 1; } else if (tolower(c) == 'd') { - struct bbs_list_entry_t *entry = ptr_vector_del(&entries, selected); + struct bbs_list_entry_t *entry = ptr_vector_get(&entries, selected); if (delete_bbs(entry->id)) { + ptr_vector_del(&entries, selected); free(entry->bbsname); free(entry->sysopname); free(entry->telnet); diff --git a/src/email.c b/src/email.c index 1d76790..9baaf09 100644 --- a/src/email.c +++ b/src/email.c @@ -423,7 +423,7 @@ void list_emails(struct user_record *user) { while (!closed) { if (redraw) { s_printf("\e[2J\e[1;1H"); - s_printf(get_string(126)); + s_printf(get_string(63)); for (i = start; i < start + 22 && i < email_count; i++) { localtime_r((time_t *)&emails[i]->date, &msg_date); if (i == position) { diff --git a/src/mail_menu.c b/src/mail_menu.c index b114759..ead0702 100644 --- a/src/mail_menu.c +++ b/src/mail_menu.c @@ -1594,6 +1594,16 @@ int read_message(struct user_record *user, struct msg_headers *msghs, int mailno s_printf(get_string(114)); s_readstring_inject(buffer, 32, msghs->msgs[mailno]->from); to = strdup(buffer); + if (ma->type == TYPE_LOCAL_AREA && (strcasecmp(to, "all") != 0 && check_user(to) && check_fullname_j(to))) { + s_printf(get_string(55)); + free(body); + free(subject); + free(to); + free(from); + ptr_vector_apply(&msg_lines, free); + destroy_ptr_vector(&msg_lines); + return 0; + } s_printf(get_string(115)); s_readstring_inject(buffer, 64, subject); free(subject); @@ -2026,6 +2036,11 @@ void post_message(struct user_record *user) { strlcpy(buffer, "ALL", sizeof(buffer)); } + if (ma->type == TYPE_LOCAL_AREA && (strcasecmp(buffer, "all") != 0 && check_user(buffer) && check_fullname_j(buffer))) { + s_printf(get_string(55)); + return; + } + if (ma->type == TYPE_NETMAIL_AREA) { s_printf(get_string(121)); s_readstring(buffer2, 32); diff --git a/src/users.c b/src/users.c index 147cbd8..5a2cd96 100644 --- a/src/users.c +++ b/src/users.c @@ -17,7 +17,7 @@ extern struct user_record *gUser; static void open_users_db_or_die(sqlite3 **db) { char *err_msg = NULL; - int rc = 0; + int rc = 0; static const char *create_sql = "CREATE TABLE IF NOT EXISTS users (" "Id INTEGER PRIMARY KEY," @@ -60,7 +60,7 @@ static void open_users_db_or_die(sqlite3 **db) { sqlite3_free(err_msg); sqlite3_close(*db); exit(1); - } + } } char *hash_sha256(char *pass, char *salt) { @@ -540,6 +540,27 @@ void list_users(struct user_record *user) { s_getc(); } +int check_fullname_j(char *firstandlastname) { + char *firstname = strdup(firstandlastname); + + if (!firstname) { + return 0; + } + + char *lastname = strchr(firstname, ' '); + int ret; + + if (lastname == NULL) { + return 0; + } + *lastname = '\0'; + lastname++; + ret = check_fullname(firstname, lastname); + + free(firstname); + return ret; +} + int check_fullname(char *firstname, char *lastname) { sqlite3 *db = NULL; sqlite3_stmt *res = NULL; @@ -561,7 +582,7 @@ int check_fullname(char *firstname, char *lastname) { sqlite3_finalize(res); sqlite3_close(db); - return (!(step == SQLITE_ROW)); + return (step != SQLITE_ROW); } int check_user(char *loginname) { @@ -576,7 +597,7 @@ int check_user(char *loginname) { if (rc != SQLITE_OK) { dolog("Failed to execute statement: %s", sqlite3_errmsg(db)); sqlite3_close(db); - return 1; + return 0; } sqlite3_bind_text(res, 1, loginname, -1, 0); int step = sqlite3_step(res); diff --git a/src/util.c b/src/util.c index d2d348f..c45fca0 100644 --- a/src/util.c +++ b/src/util.c @@ -7,9 +7,13 @@ #include #include #include +#include #include "bbs.h" +extern struct bbs_config conf; +extern int mynode; + void die(const char *msg) { dolog(msg); exit(-1); @@ -231,3 +235,19 @@ void destroy_ptr_vector(struct ptr_vector *vec) { vec->capacity = 0; vec->len = 0; } + +FILE *fopen_bbs_path(const char *filename, const char *mode) { + char buffer[PATH_MAX]; + + snprintf(buffer, PATH_MAX, "%s/%s", conf.bbs_path, filename); + + return fopen(buffer, mode); +} + +FILE *fopen_node_path(const char *filename, const char *mode) { + char buffer[PATH_MAX]; + + snprintf(buffer, PATH_MAX, "%s/node%d/%s", conf.bbs_path, mynode, filename); + + return fopen(buffer, mode); +} diff --git a/src/www_blog.c b/src/www_blog.c index 3f2f9d8..f2c6c9d 100644 --- a/src/www_blog.c +++ b/src/www_blog.c @@ -3,20 +3,34 @@ #include #include #include +#include "www_tree.h" #include "bbs.h" extern struct bbs_config conf; char *www_blog() { - stralloc page = EMPTY_STRALLOC; struct ptr_vector entries = blog_load(); - - stralloc_copys(&page, "

System Blog

\n"); + struct www_tag *page; + struct www_tag *cur_tag; + struct www_tag *child_tag; + struct www_tag *child_child_tag; + struct www_tag *child_child_child_tag; + + page = www_tag_new(NULL, ""); + cur_tag = www_tag_new("div", NULL); + www_tag_add_attrib(cur_tag, "class", "content-header"); + child_tag = www_tag_new("h2", NULL); + www_tag_add_child(cur_tag, child_tag); + www_tag_add_child(child_tag, www_tag_new(NULL, "System Blog")); + www_tag_add_child(page, cur_tag); if (ptr_vector_len(&entries) == 0) { - stralloc_cats(&page, "

No Entries

\n"); - stralloc_0(&page); - return page.s; + cur_tag = www_tag_new("p", NULL); + www_tag_add_child(cur_tag, www_tag_new(NULL, "No Entries")); + www_tag_add_child(page, cur_tag); + + + return www_tag_unwravel(page); } for (size_t i = 0; i < ptr_vector_len(&entries); i++) { struct blog_entry_t *entry = ptr_vector_get(&entries, i); @@ -30,37 +44,73 @@ char *www_blog() { strftime(timebuf, sizeof timebuf, "%l:%M", &entry_time); strftime(datebuf, sizeof datebuf, " %a, %e %b %Y", &entry_time); - stralloc_cats(&page, "

"); - stralloc_cats(&page, entry->subject); - stralloc_cats(&page, "

"); - stralloc_cats(&page, timebuf); - stralloc_cats(&page, hour >= 12 ? "pm" : "am"); - stralloc_cats(&page, datebuf); - stralloc_cats(&page, "
by "); - stralloc_cats(&page, entry->author); - stralloc_cats(&page, "
"); + cur_tag = www_tag_new("div", NULL); + www_tag_add_attrib(cur_tag, "class", "blog-header"); + www_tag_add_child(page, cur_tag); + + child_tag = www_tag_new("div", NULL); + www_tag_add_attrib(child_tag, "class", "blog-title"); + www_tag_add_child(cur_tag, child_tag); + + child_child_tag = www_tag_new("h3", NULL); + www_tag_add_child(child_tag, child_child_tag); + + child_child_child_tag = www_tag_new(NULL, entry->subject); + www_tag_add_child(child_child_tag, child_child_child_tag); + + child_tag = www_tag_new("div", NULL); + www_tag_add_attrib(child_tag, "class", "blog-date"); + www_tag_add_child(cur_tag, child_tag); + + child_child_tag = www_tag_new(NULL, timebuf); + www_tag_add_child(child_tag, child_child_tag); - stralloc_cats(&page, "

"); + child_child_tag = www_tag_new(NULL, hour >= 12 ? "pm" : "am"); + www_tag_add_child(child_tag, child_child_tag); + child_child_tag = www_tag_new(NULL, datebuf); + www_tag_add_child(child_tag, child_child_tag); + + child_tag = www_tag_new("div", NULL); + www_tag_add_attrib(child_tag, "class", "blog-author"); + www_tag_add_child(cur_tag, child_tag); + + child_child_tag = www_tag_new(NULL, "by "); + www_tag_add_child(child_tag, child_child_tag); + + child_child_tag = www_tag_new(NULL, entry->author); + www_tag_add_child(child_tag, child_child_tag); + + cur_tag = www_tag_new("div", NULL); + www_tag_add_attrib(cur_tag, "class", "blog-entry"); + www_tag_add_child(page, cur_tag); + + child_tag = www_tag_new("p", NULL); + www_tag_add_child(cur_tag, child_tag); + + stralloc blog_body = EMPTY_STRALLOC; + for (char *p = entry->body; *p != '\0'; ++p) { if (*p != '\r') { - stralloc_append1(&page, *p); + stralloc_append1(&blog_body, *p); continue; } if (p[1] != '\0' && p[1] != '\r') { - stralloc_append1(&page, ' '); + stralloc_append1(&blog_body, ' '); continue; } - ++p; - stralloc_cats(&page, "

"); } - stralloc_cats(&page, "

"); + + child_child_tag = www_tag_new(NULL, blog_body.s); + + free(blog_body.s); + + www_tag_add_child(child_tag, child_child_tag); } ptr_vector_apply(&entries, free); destroy_ptr_vector(&entries); - stralloc_0(&page); - - return page.s; + + return www_tag_unwravel(page); } #endif diff --git a/src/www_email.c b/src/www_email.c index 17b1159..e1c1b5a 100644 --- a/src/www_email.c +++ b/src/www_email.c @@ -5,9 +5,11 @@ #include #include #include +#include "www_tree.h" #include "bbs.h" extern struct bbs_config conf; +extern struct www_tag * aha(char *input, struct www_tag *parent); int www_email_delete(struct user_record *user, int id) { char buffer[PATH_MAX]; @@ -88,23 +90,14 @@ int www_send_email(struct user_record *user, char *recipient, char *subject, cha uname(&name); - for (char *p = ibody; *p != '\0'; ++p) - if (*p != '\n') + for (char *p = ibody; *p != '\0'; ++p) { + if ((*p & 0xff) == 0xc2 && (*(p + 1) & 0xff) == 0xa0) { + stralloc_append1(&sa, ' '); + p++; + } else if (*p != '\n') { stralloc_append1(&sa, *p); - - stralloc_cats(&sa, "\r--- MagickaBBS v"); - stralloc_cat_long(&sa, VERSION_MAJOR); - stralloc_append1(&sa, '.'); - stralloc_cat_long(&sa, VERSION_MINOR); - stralloc_cats(&sa, VERSION_STR); - stralloc_cats(&sa, " ("); - stralloc_cats(&sa, name.sysname); - stralloc_append1(&sa, '/'); - stralloc_cats(&sa, name.machine); - stralloc_cats(&sa, ")\r"); - stralloc_cats(&sa, " * Origin: "); - stralloc_cats(&sa, conf.default_tagline); - stralloc_cats(&sa, " \r"); + } + } stralloc_0(&sa); body = sa.s; @@ -147,24 +140,94 @@ int www_send_email(struct user_record *user, char *recipient, char *subject, cha } char *www_new_email() { - stralloc page = EMPTY_STRALLOC; + struct www_tag *page = www_tag_new(NULL, ""); + struct www_tag *cur_tag; + struct www_tag *child_tag; + struct www_tag *child_child_tag; + + cur_tag = www_tag_new("div", NULL); + www_tag_add_attrib(cur_tag, "class", "content-header"); + www_tag_add_child(page, cur_tag); + + child_tag = www_tag_new("h2", NULL); + www_tag_add_child(cur_tag, child_tag); + + child_child_tag = www_tag_new(NULL, "New Email"); + www_tag_add_child(child_tag, child_child_tag); - stralloc_copys(&page, "

New Email

\n"); - stralloc_cats(&page, "
\n"); - stralloc_cats(&page, "To :
\n"); - stralloc_cats(&page, "Subject :
\n"); - stralloc_cats(&page, "\n
"); - stralloc_cats(&page, "\n
"); - stralloc_cats(&page, "
\n"); - stralloc_0(&page); + cur_tag = www_tag_new("form", NULL); + + stralloc url = EMPTY_STRALLOC; - return page.s; + stralloc_cats(&url, conf.www_url); + stralloc_cats(&url, "email/"); + stralloc_0(&url); + + www_tag_add_attrib(cur_tag, "action", url.s); + free(url.s); + + www_tag_add_attrib(cur_tag, "method", "POST"); + www_tag_add_attrib(cur_tag, "onsubmit", "return validate()"); + www_tag_add_attrib(cur_tag, "enctype", "application/x-www-form-urlencoded"); + www_tag_add_child(page, cur_tag); + + child_tag = www_tag_new(NULL, "To : "); + www_tag_add_child(cur_tag, child_tag); + + child_tag = www_tag_new("input", NULL); + www_tag_add_attrib(child_tag, "type", "text"); + www_tag_add_attrib(child_tag, "name", "recipient"); + www_tag_add_attrib(child_tag, "id", "recipient"); + www_tag_add_child(cur_tag, child_tag); + + child_tag = www_tag_new("br", NULL); + www_tag_add_child(cur_tag, child_tag); + + + child_tag = www_tag_new(NULL, "Subject : "); + www_tag_add_child(cur_tag, child_tag); + + child_tag = www_tag_new("input", NULL); + www_tag_add_attrib(child_tag, "type", "text"); + www_tag_add_attrib(child_tag, "name", "subject"); + www_tag_add_attrib(child_tag, "id", "subject"); + www_tag_add_child(cur_tag, child_tag); + + child_tag = www_tag_new("br", NULL); + www_tag_add_child(cur_tag, child_tag); + + child_tag = www_tag_new("textarea", NULL); + www_tag_add_attrib(child_tag, "name", "body"); + www_tag_add_attrib(child_tag, "wrap", "hard"); + www_tag_add_attrib(child_tag, "rows", "25"); + www_tag_add_attrib(child_tag, "cols", "79"); + www_tag_add_attrib(child_tag, "id", "body"); + www_tag_add_child(cur_tag, child_tag); + + child_child_tag = www_tag_new(NULL, ""); + www_tag_add_child(child_tag, child_child_tag); + + child_tag = www_tag_new("br", NULL); + www_tag_add_child(cur_tag, child_tag); + + child_tag = www_tag_new("input", NULL); + www_tag_add_attrib(child_tag, "type", "submit"); + www_tag_add_attrib(child_tag, "name", "submit"); + www_tag_add_attrib(child_tag, "value", "Send"); + www_tag_add_child(cur_tag, child_tag); + + child_tag = www_tag_new("br", NULL); + www_tag_add_child(cur_tag, child_tag); + + return www_tag_unwravel(page); } char *www_email_display(struct user_record *user, int email) { - stralloc page = EMPTY_STRALLOC; + struct www_tag *page; + struct www_tag *cur_tag; + struct www_tag *child_tag; + struct www_tag *child_child_tag; + struct www_tag *child_child_child_tag; char pathbuf[PATH_MAX]; char datebuf[32]; sqlite3 *db; @@ -216,7 +279,19 @@ char *www_email_display(struct user_record *user, int email) { sqlite3_bind_int(res, 2, email - 1); if (sqlite3_step(res) != SQLITE_ROW) { - return strdup("

No Such Email

\n"); + page = www_tag_new(NULL, ""); + + cur_tag = www_tag_new("div", NULL); + www_tag_add_attrib(cur_tag, "class", "content-header"); + www_tag_add_child(page, cur_tag); + + child_tag = www_tag_new("h2", NULL); + www_tag_add_child(cur_tag, child_tag); + + child_child_tag = www_tag_new(NULL, "No such email!"); + www_tag_add_child(child_tag, child_child_tag); + + return www_tag_unwravel(page); } id = sqlite3_column_int(res, 0); from = (char *)sqlite3_column_text(res, 1); @@ -225,74 +300,161 @@ char *www_email_display(struct user_record *user, int email) { date = (time_t)sqlite3_column_int(res, 4); localtime_r(&date, &msg_date); - stralloc_copys(&page, "

Your Email

\n"); - stralloc_cats(&page, "
\n"); - stralloc_cats(&page, "
"); - stralloc_cats(&page, subject); - stralloc_cats(&page, "
\n"); - stralloc_cats(&page, "
From: "); - stralloc_cats(&page, from); - stralloc_cats(&page, "
\n"); - stralloc_cats(&page, "
Date: "); + page = www_tag_new(NULL, ""); + + cur_tag = www_tag_new("div", NULL); + www_tag_add_attrib(cur_tag, "class", "content-header"); + www_tag_add_child(page, cur_tag); + + child_tag = www_tag_new("h2", NULL); + www_tag_add_child(cur_tag, child_tag); + + child_child_tag = www_tag_new(NULL, "Your Email"); + www_tag_add_child(child_tag, child_child_tag); + + cur_tag = www_tag_new("div", NULL); + www_tag_add_attrib(cur_tag, "class", "email-view-header"); + www_tag_add_child(page, cur_tag); + + child_tag = www_tag_new("div", NULL); + www_tag_add_attrib(child_tag, "class", "email-view-subject"); + www_tag_add_child(cur_tag, child_tag); + + child_child_tag = www_tag_new(NULL, subject); + www_tag_add_child(child_tag, child_child_tag); + + child_tag = www_tag_new("div", NULL); + www_tag_add_attrib(child_tag, "class", "email-view-from"); + www_tag_add_child(cur_tag, child_tag); + + child_child_tag = www_tag_new(NULL, from); + www_tag_add_child(child_tag, child_child_tag); + + child_tag = www_tag_new("div", NULL); + www_tag_add_attrib(child_tag, "class", "email-view-date"); + www_tag_add_child(cur_tag, child_tag); + + child_child_tag = www_tag_new(NULL, "Date: "); + www_tag_add_child(child_tag, child_child_tag); + if (conf.date_style == 1) strftime(datebuf, sizeof datebuf, "%H:%M %m-%d-%y", &msg_date); else strftime(datebuf, sizeof datebuf, "%H:%M %d-%m-%y", &msg_date); - stralloc_cats(&page, datebuf); - stralloc_cats(&page, "
\n"); - stralloc_cats(&page, "
\n"); - stralloc_cats(&page, "
\n"); - for (char *p = body; *p != '\0'; ++p) { - switch (*p) { - case '\r': stralloc_cats(&page, "
"); break; - case '<': stralloc_cats(&page, "<"); break; - case '>': stralloc_cats(&page, ">"); break; - default: stralloc_append1(&page, *p); break; - } - } - stralloc_cats(&page, "
\n"); - stralloc_cats(&page, "
\n"); - stralloc_cats(&page, "

Reply

\n"); - stralloc_cats(&page, "
\n"); - stralloc_cats(&page, "\n"); - stralloc_cats(&page, "Subject :
\n"); - stralloc_cats(&page, "\n
"); - stralloc_cats(&page, "\n
"); - stralloc_cats(&page, "
\n"); - stralloc_cats(&page, "
\n"); - stralloc_0(&page); + + stralloc_0(&content); + + child_child_child_tag = www_tag_new(NULL, content.s); + free(content.s); + + www_tag_add_child(child_child_tag, child_child_child_tag); + + child_child_tag = www_tag_new("br", NULL); + www_tag_add_child(child_tag, child_child_tag); + + child_child_tag = www_tag_new("input", NULL); + www_tag_add_attrib(child_child_tag, "type", "submit"); + www_tag_add_attrib(child_child_tag, "name", "submit"); + www_tag_add_attrib(child_child_tag, "value", "reply"); + www_tag_add_child(child_tag, child_child_tag); + + child_child_tag = www_tag_new("br", NULL); + www_tag_add_child(child_tag, child_child_tag); sqlite3_finalize(res); rc = sqlite3_prepare_v2(db, update_seen_sql, -1, &res, 0); if (rc != SQLITE_OK) { sqlite3_finalize(res); sqlite3_close(db); - free(page.s); + www_tag_destroy(page); return NULL; } sqlite3_bind_int(res, 1, id); @@ -300,11 +462,16 @@ char *www_email_display(struct user_record *user, int email) { sqlite3_finalize(res); sqlite3_close(db); - return page.s; + return www_tag_unwravel(page); } char *www_email_summary(struct user_record *user) { - stralloc page = EMPTY_STRALLOC; + struct www_tag *page; + struct www_tag *cur_tag; + struct www_tag *child_tag; + struct www_tag *child_child_tag; + struct www_tag *child_child_child_tag; + struct www_tag *child_child_child_child_tag; char pathbuf[PATH_MAX]; sqlite3 *db; sqlite3_stmt *res; @@ -343,11 +510,40 @@ char *www_email_summary(struct user_record *user) { } sqlite3_bind_text(res, 1, user->loginname, -1, 0); - stralloc_copys(&page, "

Your Email

\n"); - stralloc_cats(&page, "\n"); - stralloc_cats(&page, "
\n"); + page = www_tag_new(NULL, ""); + + cur_tag = www_tag_new("div", NULL); + www_tag_add_attrib(cur_tag, "class", "content-header"); + www_tag_add_child(page, cur_tag); + + child_tag = www_tag_new("h2", NULL); + www_tag_add_child(cur_tag, child_tag); + + child_child_tag = www_tag_new(NULL, "Your Email"); + www_tag_add_child(child_tag, child_child_tag); + + cur_tag = www_tag_new("div", NULL); + www_tag_add_attrib(cur_tag, "class", "button"); + www_tag_add_child(page, cur_tag); + + child_tag = www_tag_new("a", NULL); + stralloc url = EMPTY_STRALLOC; + + stralloc_cats(&url, conf.www_url); + stralloc_cats(&url, "email/new"); + stralloc_0(&url); + + www_tag_add_attrib(child_tag, "href", url.s); + free(url.s); + www_tag_add_child(cur_tag, child_tag); + + child_child_tag = www_tag_new(NULL, "New Email"); + www_tag_add_child(child_tag, child_child_tag); + + cur_tag = www_tag_new("div", NULL); + www_tag_add_attrib(cur_tag, "class", "div-table"); + www_tag_add_child(page, cur_tag); + while (sqlite3_step(res) == SQLITE_ROW) { char datebuf[32]; @@ -360,39 +556,93 @@ char *www_email_summary(struct user_record *user) { time_t date = (time_t)sqlite3_column_int(res, 4); localtime_r(&date, &msg_date); - stralloc_cats(&page, "
"); - stralloc_cat_long(&page, msgid); - stralloc_cats(&page, "
"); - stralloc_cats(&page, from); - stralloc_cats(&page, "
"); + + www_tag_add_child(cur_tag, child_tag); + + child_child_tag = www_tag_new("div", NULL); + www_tag_add_attrib(child_child_tag, "class", "email-id"); + www_tag_add_child(child_tag, child_child_tag); + + url = EMPTY_STRALLOC; + stralloc_cat_long(&url, msgid); + stralloc_0(&url); + + child_child_child_tag = www_tag_new(NULL, url.s); + free(url.s); + + www_tag_add_child(child_child_tag, child_child_child_tag); + + child_child_tag = www_tag_new("div", NULL); + www_tag_add_attrib(child_child_tag, "class", "email-subject"); + www_tag_add_child(child_tag, child_child_tag); + + child_child_child_tag = www_tag_new("a", NULL); + url = EMPTY_STRALLOC; + stralloc_cats(&url, conf.www_url); + stralloc_cats(&url, "email/"); + stralloc_cat_long(&url, msgid); + stralloc_0(&url); + + www_tag_add_attrib(child_child_child_tag, "href", url.s); + free(url.s); + www_tag_add_child(child_child_tag, child_child_child_tag); + + child_child_child_child_tag = www_tag_new(NULL, subject); + www_tag_add_child(child_child_child_tag, child_child_child_child_tag); + + child_child_tag = www_tag_new("div", NULL); + www_tag_add_attrib(child_child_tag, "class", "email-from"); + www_tag_add_child(child_tag, child_child_tag); + + child_child_child_tag = www_tag_new(NULL, from); + www_tag_add_child(child_child_tag, child_child_child_tag); + + + child_child_tag = www_tag_new("div", NULL); + www_tag_add_attrib(child_child_tag, "class", "email-date"); + www_tag_add_child(child_tag, child_child_tag); + if (conf.date_style == 1) strftime(datebuf, sizeof datebuf, "%H:%M %m-%d-%y", &msg_date); else strftime(datebuf, sizeof datebuf, "%H:%M %d-%m-%y", &msg_date); - stralloc_cats(&page, datebuf); - stralloc_cats(&page, "
\n"); + + child_child_child_tag = www_tag_new(NULL, datebuf); + www_tag_add_child(child_child_tag, child_child_child_tag); + + child_child_tag = www_tag_new("a", NULL); + url = EMPTY_STRALLOC; + stralloc_cats(&url, conf.www_url); + stralloc_cats(&url, "email/delete/"); + stralloc_cat_long(&url, id); + stralloc_0(&url); + www_tag_add_attrib(child_child_tag, "href", url.s); + free(url.s); + + www_tag_add_child(child_tag, child_child_tag); + + child_child_child_tag = www_tag_new("div", NULL); + www_tag_add_attrib(child_child_child_tag, "class", "email-delete"); + www_tag_add_child(child_child_tag, child_child_child_tag); + + + child_child_child_child_tag = www_tag_new(NULL, ""); + www_tag_add_child(child_child_child_tag, child_child_child_child_tag); + } - stralloc_cats(&page, "
\n"); - stralloc_0(&page); sqlite3_finalize(res); sqlite3_close(db); - return page.s; + return www_tag_unwravel(page); } #endif diff --git a/src/www_files.c b/src/www_files.c index 260846c..8886da2 100644 --- a/src/www_files.c +++ b/src/www_files.c @@ -7,11 +7,12 @@ #include "../deps/hashids/hashids.h" +#include "www_tree.h" #include "bbs.h" extern struct bbs_config conf; extern struct user_record *gUser; -extern char *aha(char *input); +extern struct www_tag * aha(char *input, struct www_tag *parent); static int digit2nibble(int digit) { static const char *const hex = "0123456789abcdef"; @@ -295,10 +296,15 @@ char *www_create_link(int dir, int sub, int fid) { } char *www_files_display_listing(int dir, int sub) { static const char *sql = "select id, filename, description, size, dlcount, uploaddate from files where approved=1 ORDER BY filename"; - - stralloc page = EMPTY_STRALLOC; + struct www_tag *page = www_tag_new(NULL, ""); + struct www_tag *cur_tag; + struct www_tag *child_tag; + struct www_tag *child_child_tag; + struct www_tag *child_child_child_tag; + struct www_tag *child_child_child_child_tag; + struct www_tag *child_child_child_child_child_tag; + //stralloc page = EMPTY_STRALLOC; char pathbuf[PATH_MAX]; - char *aha_out = NULL; sqlite3 *db = NULL; sqlite3_stmt *res = NULL; int rc = 0; @@ -312,43 +318,107 @@ char *www_files_display_listing(int dir, int sub) { struct file_sub *fsub = ptr_vector_get(&fdir->file_subs, sub); assert(fsub != NULL); - stralloc_copys(&page, "

Files: "); - stralloc_cats(&page, fdir->name); - stralloc_cats(&page, " - "); - stralloc_cats(&page, fsub->name); - stralloc_cats(&page, "

\n"); + + cur_tag = www_tag_new("div", NULL); + www_tag_add_attrib(cur_tag, "class", "content-header"); + www_tag_add_child(page, cur_tag); + + child_tag = www_tag_new("h2", NULL); + www_tag_add_child(cur_tag, child_tag); + + child_child_tag = www_tag_new(NULL, "Files: "); + www_tag_add_child(child_tag, child_child_tag); + + child_child_tag = www_tag_new(NULL, fdir->name); + www_tag_add_child(child_tag, child_child_tag); + + child_child_tag = www_tag_new(NULL, " - "); + www_tag_add_child(child_tag, child_child_tag); + + child_child_tag = www_tag_new(NULL, fsub->name); + www_tag_add_child(child_tag, child_child_tag); snprintf(pathbuf, sizeof pathbuf, "%s/%s.sq3", conf.bbs_path, fsub->database); rc = sqlite3_open(pathbuf, &db); if (rc != SQLITE_OK) { - free(page.s); + www_tag_destroy(page); return NULL; } sqlite3_busy_timeout(db, 5000); rc = sqlite3_prepare_v2(db, sql, -1, &res, 0); if (rc != SQLITE_OK) { sqlite3_close(db); - free(page.s); + www_tag_destroy(page); return NULL; } - stralloc_cats(&page, "\n"); + + cur_tag = www_tag_new("table", NULL); + www_tag_add_attrib(cur_tag, "class", "fileentry"); + www_tag_add_child(page, cur_tag); + + child_tag = www_tag_new("thead", NULL); + www_tag_add_child(cur_tag, child_tag); + + child_child_tag = www_tag_new("tr", NULL); + www_tag_add_child(child_tag, child_child_tag); + + child_child_child_tag = www_tag_new("td", NULL); + www_tag_add_child(child_child_tag, child_child_child_tag); + + child_child_child_child_tag = www_tag_new(NULL, "Filename"); + www_tag_add_child(child_child_child_tag, child_child_child_child_tag); + + child_child_child_tag = www_tag_new("td", NULL); + www_tag_add_child(child_child_tag, child_child_child_tag); + + child_child_child_child_tag = www_tag_new(NULL, "Size"); + www_tag_add_child(child_child_child_tag, child_child_child_child_tag); + + child_child_child_tag = www_tag_new("td", NULL); + www_tag_add_child(child_child_tag, child_child_child_tag); + + child_child_child_child_tag = www_tag_new(NULL, "Description"); + www_tag_add_child(child_child_child_tag, child_child_child_child_tag); + + child_tag = www_tag_new("tbody", NULL); + www_tag_add_child(cur_tag, child_tag); + while (sqlite3_step(res) == SQLITE_ROW) { char *filename = strdup((char *)sqlite3_column_text(res, 1)); char *base_filename = basename(filename); - stralloc_cats(&page, ""); + child_child_tag = www_tag_new("tr", NULL); + www_tag_add_child(child_tag, child_child_tag); + + child_child_child_tag = www_tag_new("td", NULL); + www_tag_add_attrib(child_child_child_tag, "class", "filename"); + www_tag_add_child(child_child_tag, child_child_child_tag); + + child_child_child_child_tag = www_tag_new("a", NULL); + www_tag_add_child(child_child_child_tag, child_child_child_child_tag); + + stralloc url = EMPTY_STRALLOC; + + stralloc_cats(&url, conf.www_url); + stralloc_cats(&url, "files/areas/"); + stralloc_cat_long(&url, dir); + stralloc_append1(&url, '/'); + stralloc_cat_long(&url, sub); + stralloc_append1(&url, '/'); + www_encode(&url, base_filename); + + stralloc_0(&url); + + www_tag_add_attrib(child_child_child_child_tag, "href", url.s); + free(url.s); + + child_child_child_child_child_tag = www_tag_new(NULL, base_filename); + www_tag_add_child(child_child_child_child_tag, child_child_child_child_child_tag); int size = sqlite3_column_int(res, 3); - stralloc_cats(&page, ""); + + stralloc size_str = EMPTY_STRALLOC; + + stralloc_cat_long(&size_str, size); + stralloc_append1(&size_str, c); - stralloc_cats(&page, "\n"); } - stralloc_cats(&page, "
FilenameSizeDescription
"); - stralloc_cats(&page, base_filename); - stralloc_cats(&page, ""); + child_child_child_tag = www_tag_new("td", NULL); + www_tag_add_attrib(child_child_child_tag, "class", "filesize"); + www_tag_add_child(child_child_tag, child_child_child_tag); + int c = 'b'; if (size > 1024) { size /= 1024; @@ -362,60 +432,92 @@ char *www_files_display_listing(int dir, int sub) { size /= 1024; c = 'G'; } - stralloc_cat_long(&page, size); - stralloc_append1(&page, c); - stralloc_cats(&page, ""); + child_child_child_child_tag = www_tag_new(NULL, size_str.s); + www_tag_add_child(child_child_child_tag, child_child_child_child_tag); + free(size_str.s); + + child_child_child_tag = www_tag_new("td", NULL); + www_tag_add_attrib(child_child_child_tag, "class", "filedesc"); + www_tag_add_child(child_child_tag, child_child_child_tag); + char *description = strdup((char *)sqlite3_column_text(res, 2)); for (char *p = description; *p != '\0'; ++p) { if (*p == '\n') *p = '\r'; } - aha_out = aha(description); - stralloc_cats(&page, aha_out); - free(aha_out); + aha(description, child_child_child_tag); + free(description); free(filename); - - stralloc_cats(&page, "
\n"); - stralloc_0(&page); sqlite3_finalize(res); sqlite3_close(db); - return page.s; + return www_tag_unwravel(page); } char *www_files_areas() { - stralloc page = EMPTY_STRALLOC; + struct www_tag *page = www_tag_new(NULL, ""); + struct www_tag *cur_tag; + struct www_tag *child_tag; + struct www_tag *child_child_tag; + + cur_tag = www_tag_new("div", NULL); + www_tag_add_attrib(cur_tag, "class", "content-header"); + www_tag_add_child(page, cur_tag); + + child_tag = www_tag_new("h2", NULL); + www_tag_add_child(cur_tag, child_tag); + + child_child_tag = www_tag_new(NULL, "File Directories"); + www_tag_add_child(child_tag, child_child_tag); - stralloc_copys(&page, "

File Directories

\n"); for (size_t i = 0; i < ptr_vector_len(&conf.file_directories); ++i) { struct file_directory *dir = ptr_vector_get(&conf.file_directories, i); if (!dir->display_on_web) continue; - stralloc_cats(&page, "
"); - stralloc_cats(&page, dir->name); - stralloc_cats(&page, "
\n"); + + cur_tag = www_tag_new("div", NULL); + www_tag_add_attrib(cur_tag, "class", "conference-list-item"); + www_tag_add_child(page, cur_tag); + + child_tag = www_tag_new(NULL, dir->name); + www_tag_add_child(cur_tag, child_tag); + for (size_t j = 0; j < ptr_vector_len(&dir->file_subs); ++j) { struct file_sub *sub = ptr_vector_get(&dir->file_subs, j); - stralloc_cats(&page, "\n"); + cur_tag = www_tag_new("div", NULL); + www_tag_add_attrib(cur_tag, "class", "area-list-item"); + www_tag_add_child(page, cur_tag); + + child_tag = www_tag_new("a", NULL); + + stralloc url = EMPTY_STRALLOC; + + stralloc_cats(&url, conf.www_url); + stralloc_cats(&url, "files/areas/"); + stralloc_cat_long(&url, i); + stralloc_append1(&url, '/'); + stralloc_cat_long(&url, j); + stralloc_0(&url); + + www_tag_add_attrib(child_tag, "href", url.s); + free(url.s); + www_tag_add_child(cur_tag, child_tag); + + child_child_tag = www_tag_new(NULL, sub->name); + www_tag_add_child(child_tag, child_child_tag); } } - stralloc_0(&page); - return page.s; + return www_tag_unwravel(page); } char *www_files_get_from_area(int dir, int sub, char *clean_file) { diff --git a/src/www_last10.c b/src/www_last10.c index 3e666cc..75a448b 100644 --- a/src/www_last10.c +++ b/src/www_last10.c @@ -4,15 +4,22 @@ #include #include +#include "www_tree.h" #include "bbs.h" extern struct bbs_config conf; char *www_last10() { size_t n = 0; - stralloc page = EMPTY_STRALLOC; + //stralloc page = EMPTY_STRALLOC; struct last10_callers callers[10]; char last10_path[PATH_MAX]; + struct www_tag *page; + struct www_tag *cur_tag; + struct www_tag *child_tag; + struct www_tag *child_child_tag; + struct www_tag *child_child_child_tag; + snprintf(last10_path, PATH_MAX, "%s/last10v2.dat", conf.bbs_path); @@ -24,37 +31,77 @@ char *www_last10() { fclose(fptr); } - stralloc_copys(&page, "

Last 10 Callers

\n"); - stralloc_cats(&page, "
\n"); + page = www_tag_new(NULL, ""); + cur_tag = www_tag_new("div", NULL); + www_tag_add_attrib(cur_tag, "class", "content-header"); + www_tag_add_child(page, cur_tag); + + child_tag = www_tag_new("h2", NULL); + www_tag_add_child(cur_tag, child_tag); + + child_child_tag = www_tag_new(NULL, "Last 10 Callers"); + www_tag_add_child(child_tag, child_child_tag); + + cur_tag = www_tag_new("div", NULL); + www_tag_add_attrib(cur_tag, "class", "div-table"); + www_tag_add_child(page, cur_tag); + for (size_t i = 0; i < n; ++i) { struct tm called; char buffer[32]; - stralloc_cats(&page, "
"); - stralloc_cats(&page, callers[i].name); - stralloc_cats(&page, "
"); - stralloc_cats(&page, callers[i].location); - stralloc_cats(&page, "
"); - stralloc_cats(&page, "
"); + child_tag = www_tag_new("div", NULL); + www_tag_add_attrib(child_tag, "class", "last10-row"); + www_tag_add_child(cur_tag, child_tag); + + child_child_tag = www_tag_new("div", NULL); + www_tag_add_attrib(child_child_tag, "class", "last10-name"); + www_tag_add_child(child_tag, child_child_tag); + + child_child_child_tag = www_tag_new(NULL, callers[i].name); + www_tag_add_child(child_child_tag, child_child_child_tag); + + + child_child_tag = www_tag_new("div", NULL); + www_tag_add_attrib(child_child_tag, "class", "last10-location"); + www_tag_add_child(child_tag, child_child_tag); + + child_child_child_tag = www_tag_new(NULL, callers[i].location); + www_tag_add_child(child_child_tag, child_child_child_tag); + + child_child_tag = www_tag_new("div", NULL); + www_tag_add_attrib(child_child_tag, "class", "last10-date"); + www_tag_add_child(child_tag, child_child_tag); localtime_r(&callers[i].time, &called); if (conf.date_style == 1) strftime(buffer, sizeof buffer, "%H:%M %m-%d-%y", &called); else strftime(buffer, sizeof buffer, "%H:%M %d-%m-%y", &called); - stralloc_cats(&page, buffer); - stralloc_cats(&page, "
\n"); - if (callers[i].calls == 1) { - stralloc_cats(&page, "
"); - } - stralloc_cats(&page, "
\n"); - } - stralloc_cats(&page, "
\n"); - stralloc_0(&page); - return page.s; + child_child_child_tag = www_tag_new(NULL, buffer); + www_tag_add_child(child_child_tag, child_child_child_tag); + + if (callers[i].calls == 1) { + child_child_tag = www_tag_new("div", NULL); + www_tag_add_attrib(child_child_tag, "class", "last10-new"); + www_tag_add_child(child_tag, child_child_tag); + + + stralloc url = EMPTY_STRALLOC; + + stralloc_copys(&url, conf.www_url); + stralloc_cats(&url, "static/newuser.png"); + stralloc_0(&url); + + child_child_child_tag = www_tag_new("img", NULL); + www_tag_add_attrib(child_child_child_tag, "src", url.s); + free(url.s); + www_tag_add_child(child_child_tag, child_child_child_tag); + } + } + + return www_tag_unwravel(page); } #endif diff --git a/src/www_msgs.c b/src/www_msgs.c index 9654062..165eb38 100644 --- a/src/www_msgs.c +++ b/src/www_msgs.c @@ -6,19 +6,21 @@ #include #include #include - +#include "www_tree.h" #include "jamlib/jam.h" #include "libuuid/uuid.h" +#include "www_tree.h" + #include "bbs.h" #include "mail_utils.h" #define IN 0 #define OUT 1 -extern char *aha(char *input); extern struct bbs_config conf; - +extern struct www_tag * aha(char *input, struct www_tag *parent); static char *www_wordwrap(char *content, int cutoff); +/* char *www_sanitize(char *inp) { int i; char *result; @@ -59,7 +61,7 @@ char *www_sanitize(char *inp) { return result; } - +*/ char *www_msgs_arealist(struct user_record *user) { stralloc page = EMPTY_STRALLOC; @@ -95,7 +97,6 @@ char *www_msgs_arealist(struct user_record *user) { char *www_msgs_messagelist(struct user_record *user, int conference, int area, int skip) { struct msg_headers *mhrs; - stralloc page = EMPTY_STRALLOC; char buffer[4096]; int i; struct tm msg_date; @@ -107,7 +108,17 @@ char *www_msgs_messagelist(struct user_record *user, int conference, int area, i char *to; char *from; char *subject; + char datebuf[32]; + + stralloc url; + struct www_tag *page; + struct www_tag *cur_tag; + struct www_tag *child_tag; + struct www_tag *child_child_tag; + struct www_tag *child_child_child_tag; + struct www_tag *child_child_child_child_tag; + if (conference < 0 || conference >= ptr_vector_len(&conf.mail_conferences)) return NULL; struct mail_conference *mc = get_conf(conference); @@ -115,32 +126,62 @@ char *www_msgs_messagelist(struct user_record *user, int conference, int area, i return NULL; struct mail_area *ma = get_area(conference, area); - stralloc_copys(&page, "

"); - stralloc_cats(&page, mc->name); - stralloc_cats(&page, " - "); - stralloc_cats(&page, ma->name); - stralloc_cats(&page, "

\n"); + page = www_tag_new(NULL, ""); + cur_tag = www_tag_new("div", NULL); + www_tag_add_attrib(cur_tag, "class", "content-header"); + www_tag_add_child(page, cur_tag); + + child_tag = www_tag_new("h2", NULL); + www_tag_add_child(cur_tag, child_tag); + + child_child_tag = www_tag_new(NULL, mc->name); + www_tag_add_child(child_tag, child_child_tag); + + child_child_tag = www_tag_new(NULL, " - "); + www_tag_add_child(child_tag, child_child_tag); + + child_child_tag = www_tag_new(NULL, ma->name); + www_tag_add_child(child_tag, child_child_tag); if (ma->type != TYPE_NETMAIL_AREA) { - stralloc_cats(&page, "\n"); + cur_tag = www_tag_new("div", NULL); + www_tag_add_attrib(cur_tag, "class", "button"); + www_tag_add_child(page, cur_tag); + + child_tag = www_tag_new("a", NULL); + + url = EMPTY_STRALLOC; + stralloc_cats(&url, conf.www_url); + stralloc_cats(&url, "msgs/new/"); + stralloc_cat_long(&url, conference); + stralloc_append1(&url, '/'); + stralloc_cat_long(&url, area); + stralloc_0(&url); + + www_tag_add_attrib(child_tag, "href", url.s); + free(url.s); + + www_tag_add_child(cur_tag, child_tag); + + child_child_tag = www_tag_new(NULL, "New Message"); + www_tag_add_child(child_tag, child_child_tag); } mhrs = read_message_headers(conference, area, user, 0); if (mhrs == NULL) { - stralloc_cats(&page, "

No Messages

\n"); + cur_tag = www_tag_new("h3", NULL); + www_tag_add_child(page, cur_tag); + + child_tag = www_tag_new(NULL, "No Messages"); + www_tag_add_child(cur_tag, child_tag); } else { - - stralloc_cats(&page, "
\n"); + cur_tag = www_tag_new("div", NULL); + www_tag_add_attrib(cur_tag, "class", "div-table"); + www_tag_add_child(page, cur_tag); jb = open_jam_base(ma->path); if (!jb) { - free(page.s); + www_tag_destroy(page); free_message_headers(mhrs); return NULL; } @@ -159,56 +200,146 @@ char *www_msgs_messagelist(struct user_record *user, int conference, int area, i for (i = skip_f - 1; i >= skip_t; i--) { date = (time_t)mhrs->msgs[i]->msg_h->DateWritten; gmtime_r(&date, &msg_date); - to = www_sanitize(mhrs->msgs[i]->to); - from = www_sanitize(mhrs->msgs[i]->from); - subject = www_sanitize(mhrs->msgs[i]->subject); - if (msgbase_is_flagged(user, conference, area, mhrs->msgs[i]->msg_h->MsgNum)) { - if (conf.date_style == 1) { - snprintf(buffer, sizeof buffer, "
%d
%s
%s
%.2d:%.2d %.2d-%.2d-%.2d
\n", mhrs->msgs[i]->msg_no + 1, conf.www_url, conference, area, mhrs->msgs[i]->msg_h->MsgNum, subject, from, to, msg_date.tm_hour, msg_date.tm_min, msg_date.tm_mon + 1, msg_date.tm_mday, msg_date.tm_year - 100); - } else { - snprintf(buffer, sizeof buffer, "
%d
%s
%s
%.2d:%.2d %.2d-%.2d-%.2d
\n", mhrs->msgs[i]->msg_no + 1, conf.www_url, conference, area, mhrs->msgs[i]->msg_h->MsgNum, subject, from, to, msg_date.tm_hour, msg_date.tm_min, msg_date.tm_mday, msg_date.tm_mon + 1, msg_date.tm_year - 100); - } - } else if (mhrs->msgs[i]->msg_h->MsgNum > jlr.HighReadMsg) { - if (conf.date_style == 1) { - snprintf(buffer, sizeof buffer, "
%d
%s
%s
%.2d:%.2d %.2d-%.2d-%.2d
\n", mhrs->msgs[i]->msg_no + 1, conf.www_url, conference, area, mhrs->msgs[i]->msg_h->MsgNum, subject, from, to, msg_date.tm_hour, msg_date.tm_min, msg_date.tm_mon + 1, msg_date.tm_mday, msg_date.tm_year - 100); - } else { - snprintf(buffer, sizeof buffer, "
%d
%s
%s
%.2d:%.2d %.2d-%.2d-%.2d
\n", mhrs->msgs[i]->msg_no + 1, conf.www_url, conference, area, mhrs->msgs[i]->msg_h->MsgNum, subject, from, to, msg_date.tm_hour, msg_date.tm_min, msg_date.tm_mday, msg_date.tm_mon + 1, msg_date.tm_year - 100); - } - } else { - if (conf.date_style == 1) { - snprintf(buffer, sizeof buffer, "
%d
%s
%s
%.2d:%.2d %.2d-%.2d-%.2d
\n", mhrs->msgs[i]->msg_no + 1, conf.www_url, conference, area, mhrs->msgs[i]->msg_h->MsgNum, subject, from, to, msg_date.tm_hour, msg_date.tm_min, msg_date.tm_mon + 1, msg_date.tm_mday, msg_date.tm_year - 100); - } else { - snprintf(buffer, sizeof buffer, "
%d
%s
%s
%.2d:%.2d %.2d-%.2d-%.2d
\n", mhrs->msgs[i]->msg_no + 1, conf.www_url, conference, area, mhrs->msgs[i]->msg_h->MsgNum, subject, from, to, msg_date.tm_hour, msg_date.tm_min, msg_date.tm_mday, msg_date.tm_mon + 1, msg_date.tm_year - 100); - } - } + to = strdup(mhrs->msgs[i]->to); + from = strdup(mhrs->msgs[i]->from); + subject = strdup(mhrs->msgs[i]->subject); + child_tag = www_tag_new("div", NULL); + + if (msgbase_is_flagged(user, conference, area, mhrs->msgs[i]->msg_h->MsgNum)) { + www_tag_add_attrib(child_tag, "class", "msg-summary-flag"); + } else if (mhrs->msgs[i]->msg_h->MsgNum > jlr.HighReadMsg) { + www_tag_add_attrib(child_tag, "class", "msg-summary"); + } else { + www_tag_add_attrib(child_tag, "class", "msg-summary-seen"); + } + www_tag_add_child(cur_tag, child_tag); + + + child_child_tag = www_tag_new("div", NULL); + www_tag_add_attrib(child_child_tag, "class", "msg-summary-id"); + www_tag_add_child(child_tag, child_child_tag); + + url = EMPTY_STRALLOC; + stralloc_cat_long(&url, mhrs->msgs[i]->msg_no + 1); + stralloc_0(&url); + + child_child_child_tag = www_tag_new(NULL, url.s); + free(url.s); + www_tag_add_child(child_child_tag, child_child_child_tag); + + child_child_tag = www_tag_new("div", NULL); + www_tag_add_attrib(child_child_tag, "class", "msg-summary-subject"); + www_tag_add_child(child_tag, child_child_tag); + + url = EMPTY_STRALLOC; + stralloc_cats(&url, conf.www_url); + stralloc_cats(&url, "msgs/"); + stralloc_cat_long(&url, conference); + stralloc_append1(&url, '/'); + stralloc_cat_long(&url, area); + stralloc_append1(&url, '/'); + stralloc_cat_long(&url, mhrs->msgs[i]->msg_h->MsgNum); + stralloc_0(&url); + + child_child_child_tag = www_tag_new("a", NULL); + www_tag_add_attrib(child_child_child_tag, "href", url.s); + free(url.s); + www_tag_add_child(child_child_tag, child_child_child_tag); + + child_child_child_child_tag = www_tag_new(NULL, subject); + www_tag_add_child(child_child_child_tag, child_child_child_child_tag); + + child_child_tag = www_tag_new("div", NULL); + www_tag_add_attrib(child_child_tag, "class", "msg-summary-from"); + www_tag_add_child(child_tag, child_child_tag); + + child_child_child_tag = www_tag_new(NULL, from); + www_tag_add_child(child_child_tag, child_child_child_tag); + + child_child_tag = www_tag_new("div", NULL); + www_tag_add_attrib(child_child_tag, "class", "msg-summary-to"); + www_tag_add_child(child_tag, child_child_tag); + + child_child_child_tag = www_tag_new(NULL, to); + www_tag_add_child(child_child_tag, child_child_child_tag); + + child_child_tag = www_tag_new("div", NULL); + www_tag_add_attrib(child_child_tag, "class", "msg-summary-date"); + www_tag_add_child(child_tag, child_child_tag); + + if (conf.date_style == 1) + strftime(datebuf, sizeof datebuf, "%H:%M %m-%d-%y", &msg_date); + else + strftime(datebuf, sizeof datebuf, "%H:%M %d-%m-%y", &msg_date); + + child_child_child_tag = www_tag_new(NULL, datebuf); + www_tag_add_child(child_child_tag, child_child_child_tag); + free(to); free(from); free(subject); - stralloc_cats(&page, buffer); } - stralloc_cats(&page, "
\n"); if (skip + 50 <= mhrs->msg_count) { - snprintf(buffer, sizeof buffer, - "\n", - conf.www_url, conference, area, skip + 50); - stralloc_cats(&page, buffer); + cur_tag = www_tag_new("div", NULL); + www_tag_add_attrib(cur_tag, "class", "msg-summary-next"); + www_tag_add_child(page, cur_tag); + + child_tag = www_tag_new("a", NULL); + + url = EMPTY_STRALLOC; + + stralloc_cats(&url, conf.www_url); + stralloc_cats(&url, "msgs/"); + stralloc_cat_long(&url, conference); + stralloc_append1(&url, '/'); + stralloc_cat_long(&url, area); + stralloc_cats(&url, "/?skip="); + stralloc_cat_long(&url, skip + 50); + stralloc_0(&url); + + www_tag_add_attrib(child_tag, "href", url.s); + free(url.s); + www_tag_add_child(cur_tag, child_tag); + child_child_tag = www_tag_new(NULL, "Next"); + www_tag_add_child(child_tag, child_child_tag); } if (skip > 0) { + cur_tag = www_tag_new("div", NULL); + www_tag_add_attrib(cur_tag, "class", "msg-summary-prev"); + www_tag_add_child(page, cur_tag); + child_tag = www_tag_new("a", NULL); + url = EMPTY_STRALLOC; if (skip - 50 < 0) { - snprintf(buffer, sizeof buffer, "\n", conf.www_url, conference, area); + stralloc_cats(&url, conf.www_url); + stralloc_cats(&url, "msgs/"); + stralloc_cat_long(&url, conference); + stralloc_append1(&url, '/'); + stralloc_cat_long(&url, area); + stralloc_append1(&url, '/'); } else { - snprintf(buffer, sizeof buffer, "\n", conf.www_url, conference, area, skip - 50); + stralloc_cats(&url, conf.www_url); + stralloc_cats(&url, "msgs/"); + stralloc_cat_long(&url, conference); + stralloc_append1(&url, '/'); + stralloc_cat_long(&url, area); + stralloc_cats(&url, "/?skip="); + stralloc_cat_long(&url, skip - 50); } - stralloc_cats(&page, buffer); + stralloc_0(&url); + www_tag_add_attrib(child_tag, "href", url.s); + free(url.s); + + www_tag_add_child(cur_tag, child_tag); + child_child_tag = www_tag_new(NULL, "Prev"); + www_tag_add_child(child_tag, child_child_tag); } free_message_headers(mhrs); } - stralloc_0(&page); - return page.s; + return www_tag_unwravel(page); } char *www_msgs_messageview(struct user_record *user, int conference, int area, int msg) { @@ -232,7 +363,6 @@ char *www_msgs_messageview(struct user_record *user, int conference, int area, i int z; struct tm msg_date; time_t date; - stralloc page = EMPTY_STRALLOC; char buffer[4096]; int chars; int i; @@ -241,10 +371,15 @@ char *www_msgs_messageview(struct user_record *user, int conference, int area, i char *to_s; int l1, l2; char *aha_text; - char *aha_out; char *nodename; struct fido_addr *nodeno; + struct www_tag *page; + struct www_tag *cur_tag; + struct www_tag *child_tag; + struct www_tag *child_child_tag; + struct www_tag *child_child_child_tag; + if (conference < 0 || conference >= ptr_vector_len(&conf.mail_conferences)) return NULL; struct mail_conference *mc = get_conf(conference); @@ -339,135 +474,267 @@ char *www_msgs_messageview(struct user_record *user, int conference, int area, i JAM_WriteLastRead(jb, user->id, &jlr); JAM_CloseMB(jb); free(jb); + + page = www_tag_new(NULL, ""); - stralloc_copys(&page, "\n"); + cur_tag = www_tag_new("div", NULL); + www_tag_add_attrib(cur_tag, "class", "content-header"); + www_tag_add_child(page, cur_tag); + + child_tag = www_tag_new("a", NULL); + + stralloc url = EMPTY_STRALLOC; + + stralloc_cats(&url, conf.www_url); + stralloc_cats(&url, "msgs/"); + stralloc_cat_long(&url, conference); + stralloc_append1(&url, '/'); + stralloc_cat_long(&url, area); + stralloc_0(&url); + + www_tag_add_attrib(child_tag, "href", url.s); + free(url.s); + www_tag_add_child(cur_tag, child_tag); + child_child_tag = www_tag_new("h2", NULL); + www_tag_add_child(child_tag, child_child_tag); + + child_child_child_tag = www_tag_new(NULL, mc->name); + www_tag_add_child(child_child_tag, child_child_child_tag); + + child_child_child_tag = www_tag_new(NULL, " - "); + www_tag_add_child(child_child_tag, child_child_child_tag); + + child_child_child_tag = www_tag_new(NULL, ma->name); + www_tag_add_child(child_child_tag, child_child_child_tag); + + cur_tag = www_tag_new("div", NULL); + if (msgbase_is_flagged(user, conference, area, msg)) { - stralloc_cats(&page, "
\n"); + www_tag_add_attrib(cur_tag, "class", "msg-view-header-flagged"); } else { - stralloc_cats(&page, "
\n"); + www_tag_add_attrib(cur_tag, "class", "msg-view-header"); } + + www_tag_add_child(page, cur_tag); + + child_tag = www_tag_new("div", NULL); + www_tag_add_attrib(child_tag, "class", "msg-view-subject"); + www_tag_add_child(cur_tag, child_tag); - subject_s = www_sanitize(subject); - stralloc_cats(&page, "
"); - stralloc_cats(&page, subject_s); - stralloc_cats(&page, "
\n"); - free(subject_s); + child_child_tag = www_tag_new(NULL, subject); + www_tag_add_child(child_tag, child_child_tag); + + child_tag = www_tag_new("div", NULL); + www_tag_add_attrib(child_tag, "class", "msg-view-from"); + www_tag_add_child(cur_tag, child_tag); - from_s = www_sanitize(from); if (ma->type != TYPE_LOCAL_AREA && oaddress != NULL) { if (mc->nettype == NETWORK_MAGI) { - snprintf(buffer, sizeof buffer, "
From: %s (@%s)
\n", from_s, oaddress); + snprintf(buffer, sizeof buffer, "From: %s (@%s)", from, oaddress); + child_child_tag = www_tag_new(NULL, buffer); + www_tag_add_child(child_tag, child_child_tag); } else if (mc->nettype == NETWORK_FIDO) { nodeno = parse_fido_addr(oaddress); if (nodeno != NULL) { nodename = nl_get_bbsname(nodeno, mc->domain); if (strcmp(nodename, "Unknown") == 0) { - snprintf(buffer, sizeof buffer, "
From: %s (%s)
\n", from_s, oaddress); + snprintf(buffer, sizeof buffer, "From: %s (%s)", from, oaddress); + child_child_tag = www_tag_new(NULL, buffer); + www_tag_add_child(child_tag, child_child_tag); } else { - snprintf(buffer, sizeof buffer, - "
From: %s (%s - %s)
\n", - from_s, nodename, oaddress); + snprintf(buffer, sizeof buffer, "From: %s (", from); + child_child_tag = www_tag_new(NULL, buffer); + www_tag_add_child(child_tag, child_child_tag); + + child_child_tag = www_tag_new("span", NULL); + www_tag_add_attrib(child_child_tag, "class", "bbsname"); + www_tag_add_child(child_tag, child_child_tag); + + child_child_child_tag = www_tag_new(NULL, nodename); + www_tag_add_child(child_child_tag, child_child_child_tag); + + snprintf(buffer, sizeof buffer, " - %s)", oaddress); + child_child_tag = www_tag_new(NULL, buffer); + www_tag_add_child(child_tag, child_child_tag); } free(nodename); free(nodeno); } else { - snprintf(buffer, sizeof buffer, "
From: %s (%s)
\n", from_s, oaddress); + snprintf(buffer, sizeof buffer, "From: %s (%s)", from, oaddress); + child_child_tag = www_tag_new(NULL, buffer); + www_tag_add_child(child_tag, child_child_tag); } } else { - snprintf(buffer, sizeof buffer, "
From: %s (%s)
\n", from_s, oaddress); + snprintf(buffer, sizeof buffer, "From: %s (%s)", from, oaddress); + child_child_tag = www_tag_new(NULL, buffer); + www_tag_add_child(child_tag, child_child_tag); } } else { - snprintf(buffer, sizeof buffer, "
From: %s
\n", from_s); + snprintf(buffer, sizeof buffer, "From: %s", from); + child_child_tag = www_tag_new(NULL, buffer); + www_tag_add_child(child_tag, child_child_tag); } - free(from_s); - stralloc_cats(&page, buffer); + child_tag = www_tag_new("div", NULL); + www_tag_add_attrib(child_tag, "class", "msg-view-to"); + www_tag_add_child(cur_tag, child_tag); - to_s = www_sanitize(to); - stralloc_cats(&page, "
To: "); - stralloc_cats(&page, to_s); - stralloc_cats(&page, "
\n"); - free(to_s); + child_child_tag = www_tag_new(NULL, "To : "); + www_tag_add_child(child_tag, child_child_tag); + + child_child_tag = www_tag_new(NULL, to); + www_tag_add_child(child_tag, child_child_tag); + + child_tag = www_tag_new("div", NULL); + www_tag_add_attrib(child_tag, "class", "msg-view-date"); + www_tag_add_child(cur_tag, child_tag); date = (time_t)jmh.DateWritten; gmtime_r(&date, &msg_date); if (conf.date_style == 1) { - snprintf(buffer, sizeof buffer, "
Date: %.2d:%.2d %.2d-%.2d-%.2d
\n", + snprintf(buffer, sizeof buffer, "Date: %.2d:%.2d %.2d-%.2d-%.2d", msg_date.tm_hour, msg_date.tm_min, msg_date.tm_mon + 1, msg_date.tm_mday, msg_date.tm_year - 100); } else { - snprintf(buffer, sizeof buffer, "
Date: %.2d:%.2d %.2d-%.2d-%.2d
\n", + snprintf(buffer, sizeof buffer, "Date: %.2d:%.2d %.2d-%.2d-%.2d", msg_date.tm_hour, msg_date.tm_min, msg_date.tm_mday, msg_date.tm_mon + 1, msg_date.tm_year - 100); } - stralloc_cats(&page, buffer); + child_child_tag = www_tag_new(NULL, buffer); + www_tag_add_child(child_tag, child_child_tag); - snprintf(buffer, sizeof buffer, - "
", - conf.www_url, conference, area, msg, conf.www_url); - stralloc_cats(&page, buffer); + child_tag = www_tag_new("div", NULL); + www_tag_add_attrib(child_tag, "class", "msg-view-options"); + www_tag_add_child(cur_tag, child_tag); - stralloc_cats(&page, "
\n"); - stralloc_cats(&page, "
\n"); + child_child_tag = www_tag_new("a", NULL); + + url = EMPTY_STRALLOC; + + stralloc_cats(&url, conf.www_url); + stralloc_cats(&url, "msgs/flag/"); + stralloc_cat_long(&url, conference); + stralloc_append1(&url, '/'); + stralloc_cat_long(&url, area); + stralloc_append1(&url, '/'); + stralloc_cat_long(&url, msg); + stralloc_0(&url); + + www_tag_add_attrib(child_child_tag, "href", url.s); + free(url.s); + www_tag_add_child(child_tag, child_child_tag); + + child_child_child_tag = www_tag_new("img", NULL); + + url = EMPTY_STRALLOC; + + stralloc_cats(&url, conf.www_url); + stralloc_cats(&url, "static/flag.png"); + stralloc_0(&url); + www_tag_add_attrib(child_child_child_tag, "src", url.s); + free(url.s); + www_tag_add_child(child_child_tag, child_child_child_tag); + + cur_tag = www_tag_new("div", NULL); + + www_tag_add_attrib(cur_tag, "id", "msgbody"); + www_tag_add_child(page, cur_tag); aha_text = strndup(body, jmh.TxtLen); - aha_out = aha(aha_text); - stralloc_cats(&page, aha_out); - - free(aha_out); + aha(aha_text, cur_tag); free(aha_text); - stralloc_cats(&page, "
\n"); - stralloc_cats(&page, "
\n"); if (ma->write_sec_level <= user->sec_level && ma->type != TYPE_NETMAIL_AREA) { - stralloc_cats(&page, "

Reply

\n"); - stralloc_cats(&page, "
\n"); + cur_tag = www_tag_new("div", NULL); + www_tag_add_attrib(cur_tag, "class", "msg-reply-form"); + www_tag_add_child(page, cur_tag); + + child_tag = www_tag_new("h3", NULL); + www_tag_add_child(cur_tag, child_tag); + + child_child_tag = www_tag_new(NULL, "Reply"); + www_tag_add_child(child_tag, child_child_tag); + - stralloc_cats(&page, "\n"); + child_tag = www_tag_new("form", NULL); + url = EMPTY_STRALLOC; + stralloc_cats(&url, conf.www_url); + stralloc_cats(&url, "msgs/"); + stralloc_0(&url); + + www_tag_add_attrib(child_tag, "action", url.s); + free(url.s); + + www_tag_add_attrib(child_tag, "method", "POST"); + www_tag_add_attrib(child_tag, "enctype", "application/x-www-form-urlencoded;charset=UTF-8"); + www_tag_add_child(cur_tag, child_tag); - stralloc_cats(&page, "\n"); + child_child_tag = www_tag_new("input", NULL); + www_tag_add_attrib(child_child_tag, "type", "hidden"); + www_tag_add_attrib(child_child_tag, "name", "conference"); + snprintf(buffer, sizeof buffer, "%d", conference); + www_tag_add_attrib(child_child_tag, "value", buffer); + www_tag_add_child(child_tag, child_child_tag); - stralloc_cats(&page, "\n"); + www_tag_add_child(child_tag, child_child_tag); - stralloc_cats(&page, "To :
\n"); - - stralloc_cats(&page, "Subject :
\n"); + + www_tag_add_child(child_tag, child_child_tag); + + child_child_tag = www_tag_new("br", NULL); + www_tag_add_child(child_tag, child_child_tag); - stralloc_cats(&page, "\n
"); - stralloc_cats(&page, "\n
"); - stralloc_cats(&page, "
\n"); - stralloc_cats(&page, "
\n"); + + stralloc_0(&text); + + child_child_child_tag = www_tag_new(NULL, text.s); + www_tag_add_child(child_child_tag, child_child_child_tag); + + child_child_tag = www_tag_new("br", NULL); + www_tag_add_child(child_tag, child_child_tag); + + child_child_tag = www_tag_new("input", NULL); + www_tag_add_attrib(child_child_tag, "type", "submit"); + www_tag_add_attrib(child_child_tag, "name", "submit"); + www_tag_add_attrib(child_child_tag, "value", "Reply"); + www_tag_add_child(child_tag, child_child_tag); + child_child_tag = www_tag_new("br", NULL); + www_tag_add_child(child_tag, child_child_tag); } - stralloc_0(&page); free(subject); free(from); @@ -521,7 +803,7 @@ char *www_msgs_messageview(struct user_record *user, int conference, int area, i free(msgid); free(replyid); - return page.s; + return www_tag_unwravel(page); } static char *www_wordwrap(char *content, int cutoff) { @@ -683,6 +965,10 @@ int www_send_msg(struct user_record *user, char *to, char *subj, int conference, return 0; struct mail_area *ma = get_area(conference, area); + if (ma->type == TYPE_LOCAL_AREA && (strcasecmp(to, "all") != 0 && check_user(to) && check_fullname_j(to))) { + return 0; + } + if (ma->write_sec_level <= user->sec_level && ma->type != TYPE_NETMAIL_AREA) { jb = open_jam_base(ma->path); if (!jb) { @@ -831,7 +1117,27 @@ int www_send_msg(struct user_record *user, char *to, char *subj, int conference, } else { snprintf(buffer, sizeof buffer, "\r"); } - body2 = www_wordwrap(body, 73); + + char *p = body; + stralloc unhtmlized = EMPTY_STRALLOC; + + + // remove nbsp + while (*p != '\0') { + if ((*p & 0xff) == 0xc2 && (*(p + 1) & 0xff) == 0xa0) { + stralloc_append1(&unhtmlized, ' '); + p++; + } else { + stralloc_append1(&unhtmlized, *p); + } + + p++; + } + + stralloc_0(&unhtmlized); + + body2 = www_wordwrap(unhtmlized.s, 73); + free(unhtmlized.s); if (body2 == NULL) { JAM_UnlockMB(jb); JAM_DelSubPacket(jsp); @@ -839,6 +1145,9 @@ int www_send_msg(struct user_record *user, char *to, char *subj, int conference, free(jb); return 0; } + + + body3 = str2dup(body2, buffer); if (body3 == NULL) { free(body2); @@ -893,28 +1202,110 @@ int www_send_msg(struct user_record *user, char *to, char *subj, int conference, } char *www_new_msg(struct user_record *user, int conference, int area) { - stralloc page = EMPTY_STRALLOC; + struct www_tag *page = www_tag_new(NULL, ""); + struct www_tag *cur_tag; + struct www_tag *child_tag; + struct www_tag *child_child_tag; + + char buffer[10]; + + cur_tag = www_tag_new("div", NULL); + www_tag_add_attrib(cur_tag, "class", "content-header"); + www_tag_add_child(page, cur_tag); + + child_tag = www_tag_new("h2", NULL); + www_tag_add_child(cur_tag, child_tag); + + child_child_tag = www_tag_new(NULL, "New Message"); + www_tag_add_child(child_tag, child_child_tag); + - stralloc_copys(&page, "

New Message

\n"); - stralloc_cats(&page, "
\n"); - stralloc_cats(&page, "\n"); - stralloc_cats(&page, "\n"); - stralloc_cats(&page, "\n"); - stralloc_cats(&page, "To :
\n"); - stralloc_cats(&page, "Subject :
\n"); - stralloc_cats(&page, "\n
"); - stralloc_cats(&page, "\n
"); - stralloc_cats(&page, "
\n"); - stralloc_0(&page); + cur_tag = www_tag_new("form", NULL); + + stralloc url = EMPTY_STRALLOC; + + stralloc_cats(&url, conf.www_url); + stralloc_cats(&url, "msgs/"); + stralloc_0(&url); + + www_tag_add_attrib(cur_tag, "action", url.s); + free(url.s); - return page.s; + www_tag_add_attrib(cur_tag, "method", "POST"); + www_tag_add_attrib(cur_tag, "onsubmit", "return validate()"); + www_tag_add_attrib(cur_tag, "enctype", "application/x-www-form-urlencoded;charset=UTF-8"); + www_tag_add_child(page, cur_tag); + + child_tag = www_tag_new("input", NULL); + www_tag_add_attrib(child_tag, "type", "hidden"); + www_tag_add_attrib(child_tag, "name", "conference"); + snprintf(buffer, sizeof buffer, "%d", conference); + www_tag_add_attrib(child_tag, "value", buffer); + www_tag_add_child(cur_tag, child_tag); + + child_tag = www_tag_new("input", NULL); + www_tag_add_attrib(child_tag, "type", "hidden"); + www_tag_add_attrib(child_tag, "name", "area"); + snprintf(buffer, sizeof buffer, "%d", area); + www_tag_add_attrib(child_tag, "value", buffer); + www_tag_add_child(cur_tag, child_tag); + + child_tag = www_tag_new("input", NULL); + www_tag_add_attrib(child_tag, "type", "hidden"); + www_tag_add_attrib(child_tag, "name", "replyid"); + www_tag_add_attrib(child_tag, "value", "NULL"); + www_tag_add_child(cur_tag, child_tag); + + child_tag = www_tag_new(NULL, "To : "); + www_tag_add_child(cur_tag, child_tag); + + child_tag = www_tag_new("input", NULL); + www_tag_add_attrib(child_tag, "type", "text"); + www_tag_add_attrib(child_tag, "name", "recipient"); + www_tag_add_attrib(child_tag, "value", "All"); + www_tag_add_attrib(child_tag, "id", "recipient"); + www_tag_add_child(cur_tag, child_tag); + + child_tag = www_tag_new("br", NULL); + www_tag_add_child(cur_tag, child_tag); + + child_tag = www_tag_new(NULL, "Subject : "); + www_tag_add_child(cur_tag, child_tag); + + child_tag = www_tag_new("input", NULL); + www_tag_add_attrib(child_tag, "type", "text"); + www_tag_add_attrib(child_tag, "name", "subject"); + www_tag_add_attrib(child_tag, "id", "subject"); + www_tag_add_child(cur_tag, child_tag); + + child_tag = www_tag_new("br", NULL); + www_tag_add_child(cur_tag, child_tag); + + child_tag = www_tag_new("textarea", NULL); + www_tag_add_attrib(child_tag, "name", "body"); + www_tag_add_attrib(child_tag, "id", "body"); + www_tag_add_attrib(child_tag, "rows", "25"); + www_tag_add_attrib(child_tag, "cols", "79"); + www_tag_add_attrib(child_tag, "wrap", "soft"); + www_tag_add_child(cur_tag, child_tag); + + child_child_tag = www_tag_new(NULL, ""); + www_tag_add_child(child_tag, child_child_tag); + + + child_tag = www_tag_new("br", NULL); + www_tag_add_child(cur_tag, child_tag); + + child_tag = www_tag_new("input", NULL); + www_tag_add_attrib(child_tag, "type", "submit"); + www_tag_add_attrib(child_tag, "name", "submit"); + www_tag_add_attrib(child_tag, "value", "Send"); + www_tag_add_child(cur_tag, child_tag); + + child_tag = www_tag_new("br", NULL); + www_tag_add_child(cur_tag, child_tag); + + return www_tag_unwravel(page); } #endif diff --git a/src/www_tree.c b/src/www_tree.c new file mode 100644 index 0000000..456225d --- /dev/null +++ b/src/www_tree.c @@ -0,0 +1,671 @@ +#if defined(ENABLE_WWW) + +#include +#include "www_tree.h" +#include "bbs.h" + +static char *www_tag_sanatize(char *data, int isdata) { + stralloc str = EMPTY_STRALLOC; + for (char *p = data; *p != '\0'; ++p) { + switch (*p) { + case '&': + stralloc_cats(&str, "&"); + break; + case '<': + stralloc_cats(&str, "<"); + break; + case '>': + stralloc_cats(&str, ">"); + break; + case '\x01': + stralloc_cats(&str, "☺"); + break; + case '\x02': + stralloc_cats(&str, "☻"); + break; + case '\x03': + stralloc_cats(&str, "♥"); + break; + case '\x04': + stralloc_cats(&str, "♦"); + break; + case '\x05': + stralloc_cats(&str, "♣"); + break; + case '\x06': + stralloc_cats(&str, "♠"); + break; + case '\x07': + stralloc_cats(&str, "•"); + break; + case '\x08': + stralloc_cats(&str, "◘"); + break; + case '\x09': + stralloc_cats(&str, "○"); + break; + case '\x0b': + stralloc_cats(&str, "♂"); + break; + case '\x0c': + stralloc_cats(&str, "♀"); + break; + case '\x0e': + stralloc_cats(&str, "♫"); + break; + case '\x0f': + stralloc_cats(&str, "☼"); + break; + case '\x10': + stralloc_cats(&str, "▸"); + break; + case '\x11': + stralloc_cats(&str, "◂"); + break; + case '\x12': + stralloc_cats(&str, "↕"); + break; + case '\x13': + stralloc_cats(&str, "‼"); + break; + case '\x14': + stralloc_cats(&str, "¶"); + break; + case '\x15': + stralloc_cats(&str, "§"); + break; + case '\x16': + stralloc_cats(&str, "▬"); + break; + case '\x17': + stralloc_cats(&str, "↨"); + break; + case '\x18': + stralloc_cats(&str, "↑"); + break; + case '\x19': + stralloc_cats(&str, "↓"); + break; + case '\x1a': + stralloc_cats(&str, "→"); + break; + case '\x1b': + stralloc_cats(&str, "←"); + break; + case '\x1c': + stralloc_cats(&str, "∟"); + break; + case '\x1d': + stralloc_cats(&str, "↔"); + break; + case '\x1e': + stralloc_cats(&str, "▴"); + break; + case '\x1f': + stralloc_cats(&str, "▾"); + break; +/* + case '\x21': + stralloc_cats(&str, "!"); + break; + case '\x22': + stralloc_cats(&str, """); + break; + case '\x24': + stralloc_cats(&str, "$"); + break; + case '\x25': + stralloc_cats(&str, "%"); + break; + case '\x27': + stralloc_cats(&str, "'"); + break; + case '\x28': + stralloc_cats(&str, "("); + break; + case '\x29': + stralloc_cats(&str, ")"); + break; + case '\x2a': + stralloc_cats(&str, "*"); + break; + case '\x2b': + stralloc_cats(&str, "+"); + break; + case '\x2c': + stralloc_cats(&str, ","); + break; +*/ + case '\x7f': + stralloc_cats(&str, "⌂"); + break; + case '\x80': + stralloc_cats(&str, "Ç"); + break; + case '\x81': + stralloc_cats(&str, "ü"); + break; + case '\x82': + stralloc_cats(&str, "é"); + break; + case '\x83': + stralloc_cats(&str, "â"); + break; + case '\x84': + stralloc_cats(&str, "ä"); + break; + case '\x85': + stralloc_cats(&str, "à"); + break; + case '\x86': + stralloc_cats(&str, "å"); + break; + case '\x87': + stralloc_cats(&str, "ç"); + break; + case '\x88': + stralloc_cats(&str, "ê"); + break; + case '\x89': + stralloc_cats(&str, "ë"); + break; + case '\x8a': + stralloc_cats(&str, "è"); + break; + case '\x8b': + stralloc_cats(&str, "ï"); + break; + case '\x8c': + stralloc_cats(&str, "î"); + break; + case '\x8d': + stralloc_cats(&str, "ì"); + break; + case '\x8e': + stralloc_cats(&str, "Ä"); + break; + case '\x8f': + stralloc_cats(&str, "Å"); + break; + case '\x90': + stralloc_cats(&str, "É"); + break; + case '\x91': + stralloc_cats(&str, "æ"); + break; + case '\x92': + stralloc_cats(&str, "Æ"); + break; + case '\x93': + stralloc_cats(&str, "ô"); + break; + case '\x94': + stralloc_cats(&str, "ö"); + break; + case '\x95': + stralloc_cats(&str, "ò"); + break; + case '\x96': + stralloc_cats(&str, "û"); + break; + case '\x97': + stralloc_cats(&str, "ù"); + break; + case '\x98': + stralloc_cats(&str, "ÿ"); + break; + case '\x99': + stralloc_cats(&str, "Ö"); + break; + case '\x9a': + stralloc_cats(&str, "Ü"); + break; + case '\x9b': + stralloc_cats(&str, "¢"); + break; + case '\x9c': + stralloc_cats(&str, "£"); + break; + case '\x9d': + stralloc_cats(&str, "¥"); + break; + case '\x9e': + stralloc_cats(&str, "₧"); + break; + case '\x9f': + stralloc_cats(&str, "ƒ"); + break; + case '\xa0': + stralloc_cats(&str, "á"); + break; + case '\xa1': + stralloc_cats(&str, "í"); + break; + case '\xa2': + stralloc_cats(&str, "ó"); + break; + case '\xa3': + stralloc_cats(&str, "ú"); + break; + case '\xa4': + stralloc_cats(&str, "ñ"); + break; + case '\xa5': + stralloc_cats(&str, "Ñ"); + break; + case '\xa6': + stralloc_cats(&str, "ª"); + break; + case '\xa7': + stralloc_cats(&str, "º"); + break; + case '\xa8': + stralloc_cats(&str, "¿"); + break; + case '\xa9': + stralloc_cats(&str, "⌐"); + break; + case '\xaa': + stralloc_cats(&str, "¬"); + break; + case '\xab': + stralloc_cats(&str, "½"); + break; + case '\xac': + stralloc_cats(&str, "¼"); + break; + case '\xad': + stralloc_cats(&str, "¡"); + break; + case '\xae': + stralloc_cats(&str, "«"); + break; + case '\xaf': + stralloc_cats(&str, "»"); + break; + case '\xb0': + stralloc_cats(&str, "░"); + break; + case '\xb1': + stralloc_cats(&str, "▒"); + break; + case '\xb2': + stralloc_cats(&str, "▓"); + break; + case '\xb3': + stralloc_cats(&str, "│"); + break; + case '\xb4': + stralloc_cats(&str, "┤"); + break; + case '\xb5': + stralloc_cats(&str, "╡"); + break; + case '\xb6': + stralloc_cats(&str, "╢"); + break; + case '\xb7': + stralloc_cats(&str, "╖"); + break; + case '\xb8': + stralloc_cats(&str, "╕"); + break; + case '\xb9': + stralloc_cats(&str, "╣"); + break; + case '\xba': + stralloc_cats(&str, "║"); + break; + case '\xbb': + stralloc_cats(&str, "╗"); + break; + case '\xbc': + stralloc_cats(&str, "╝"); + break; + case '\xbd': + stralloc_cats(&str, "╜"); + break; + case '\xbe': + stralloc_cats(&str, "╛"); + break; + case '\xbf': + stralloc_cats(&str, "┐"); + break; + case '\xc0': + stralloc_cats(&str, "└"); + break; + case '\xc1': + stralloc_cats(&str, "┴"); + break; + case '\xc2': + stralloc_cats(&str, "┬"); + break; + case '\xc3': + stralloc_cats(&str, "├"); + break; + case '\xc4': + stralloc_cats(&str, "─"); + break; + case '\xc5': + stralloc_cats(&str, "┼"); + break; + case '\xc6': + stralloc_cats(&str, "╞"); + break; + case '\xc7': + stralloc_cats(&str, "╟"); + break; + case '\xc8': + stralloc_cats(&str, "╚"); + break; + case '\xc9': + stralloc_cats(&str, "╔"); + break; + case '\xca': + stralloc_cats(&str, "╩"); + break; + case '\xcb': + stralloc_cats(&str, "╦"); + break; + case '\xcc': + stralloc_cats(&str, "╠"); + break; + case '\xcd': + stralloc_cats(&str, "═"); + break; + case '\xce': + stralloc_cats(&str, "╬"); + break; + case '\xcf': + stralloc_cats(&str, "╧"); + break; + case '\xd0': + stralloc_cats(&str, "╨"); + break; + case '\xd1': + stralloc_cats(&str, "╤"); + break; + case '\xd2': + stralloc_cats(&str, "╥"); + break; + case '\xd3': + stralloc_cats(&str, "╙"); + break; + case '\xd4': + stralloc_cats(&str, "╛"); + break; + case '\xd5': + stralloc_cats(&str, "╒"); + break; + case '\xd6': + stralloc_cats(&str, "╓"); + break; + case '\xd7': + stralloc_cats(&str, "╫"); + break; + case '\xd8': + stralloc_cats(&str, "╪"); + break; + case '\xd9': + stralloc_cats(&str, "┘"); + break; + case '\xda': + stralloc_cats(&str, "┌"); + break; + case '\xdb': + stralloc_cats(&str, "█"); + break; + case '\xdc': + stralloc_cats(&str, "▄"); + break; + case '\xdd': + stralloc_cats(&str, "▌"); + break; + case '\xde': + stralloc_cats(&str, "▐"); + break; + case '\xdf': + stralloc_cats(&str, "▀"); + break; + case '\xe0': + stralloc_cats(&str, "α"); + break; + case '\xe1': + stralloc_cats(&str, "β"); + break; + case '\xe2': + stralloc_cats(&str, "Γ"); + break; + case '\xe3': + stralloc_cats(&str, "π"); + break; + case '\xe4': + stralloc_cats(&str, "Σ"); + break; + case '\xe5': + stralloc_cats(&str, "σ"); + break; + case '\xe6': + stralloc_cats(&str, "µ"); + break; + case '\xe7': + stralloc_cats(&str, "τ"); + break; + case '\xe8': + stralloc_cats(&str, "Φ"); + break; + case '\xe9': + stralloc_cats(&str, "Θ"); + break; + case '\xea': + stralloc_cats(&str, "Ω"); + break; + case '\xeb': + stralloc_cats(&str, "δ"); + break; + case '\xec': + stralloc_cats(&str, "∞"); + break; + case '\xed': + stralloc_cats(&str, "∅"); + break; + case '\xee': + stralloc_cats(&str, "∈"); + break; + case '\xef': + stralloc_cats(&str, "∩"); + break; + case '\xf0': + stralloc_cats(&str, "≡"); + break; + case '\xf1': + stralloc_cats(&str, "±"); + break; + case '\xf2': + stralloc_cats(&str, "≥"); + break; + case '\xf3': + stralloc_cats(&str, "≤"); + break; + case '\xf4': + stralloc_cats(&str, "⌠"); + break; + case '\xf5': + stralloc_cats(&str, "⌡"); + break; + case '\xf6': + stralloc_cats(&str, "÷"); + break; + case '\xf7': + stralloc_cats(&str, "≈"); + break; + case '\xf8': + stralloc_cats(&str, "°"); + break; + case '\xf9': + stralloc_cats(&str, "∙"); + break; + case '\xfa': + stralloc_cats(&str, "·"); + break; + case '\xfb': + stralloc_cats(&str, "√"); + break; + case '\xfc': + stralloc_cats(&str, "ⁿ"); + break; + case '\xfd': + stralloc_cats(&str, "²"); + break; + case '\xfe': + stralloc_cats(&str, "▪"); + break; + case ' ': + if (isdata) { + if (*(p+1) == ' ') { + stralloc_cats(&str, " "); + } else { + if (p > data && (*(p-1) == ' ' || *(p-1) == '\n')) { + stralloc_cats(&str, " "); + } else if (data == p) { + stralloc_cats(&str, " "); + } else { + stralloc_append1(&str, ' '); + } + } + } else { + stralloc_append1(&str, ' '); + } + break; + + default: + stralloc_append1(&str, *p); + break; + } + } + stralloc_0(&str); + return str.s; +} + +struct www_tag *www_tag_new(char *tag, char *data) { + struct www_tag *new_tag = malloz(sizeof(struct www_tag)); + + + new_tag->attribs = EMPTY_PTR_VECTOR; + new_tag->values = EMPTY_PTR_VECTOR; + new_tag->children = EMPTY_PTR_VECTOR; + + if (tag == NULL) { + new_tag->tag = NULL; + + /* SANATIZE DATA HERE */ + new_tag->data = www_tag_sanatize(data, 1); + } else { + new_tag->tag = strdup(tag); + new_tag->data = NULL; + + init_ptr_vector(&new_tag->attribs); + init_ptr_vector(&new_tag->values); + } + + init_ptr_vector(&new_tag->children); + + return new_tag; +} + +struct www_tag *www_tag_duplicate(struct www_tag *oldtag) { + struct www_tag *newtag = www_tag_new(oldtag->tag, oldtag->data); + for (int i=0;iattribs.len;i++) { + www_tag_add_attrib(newtag, strdup(ptr_vector_get(&oldtag->attribs, i)), strdup(ptr_vector_get(&oldtag->values, i))); + } + return newtag; +} + +void www_tag_add_attrib(struct www_tag *tag, char *attrib, char *value) { + ptr_vector_append(&tag->attribs, strdup(attrib)); + ptr_vector_append(&tag->values, www_tag_sanatize(value, 0)); +} + +void www_tag_add_child(struct www_tag *tag, struct www_tag *child) { + ptr_vector_append(&tag->children, child); +} + +char *www_tag_destroy(struct www_tag *tag) { + while (tag->children.len > 0) { + struct www_tag *child = ptr_vector_del(&tag->children, 0); + www_tag_destroy(child); + } + + if (tag->tag != NULL) { + ptr_vector_apply(&tag->attribs, free); + destroy_ptr_vector(&tag->attribs); + ptr_vector_apply(&tag->values, free); + destroy_ptr_vector(&tag->values); + } + destroy_ptr_vector(&tag->children); +} + +char *www_tag_unwravel(struct www_tag *tag) { + stralloc thedata = EMPTY_STRALLOC; + while (tag->children.len > 0) { + struct www_tag *child = ptr_vector_del(&tag->children, 0); + if (child->children.len > 0) { + if (child->tag != NULL) { + stralloc_append1(&thedata, '<'); + stralloc_cats(&thedata, child->tag); + for (int i = 0; i < child->attribs.len; i++) { + stralloc_append1(&thedata, ' '); + stralloc_cats(&thedata, (char *)ptr_vector_get(&child->attribs, i)); + stralloc_append1(&thedata, '='); + stralloc_append1(&thedata, '\"'); + stralloc_cats(&thedata, (char *)ptr_vector_get(&child->values, i)); + stralloc_append1(&thedata, '\"'); + } + + + stralloc_append1(&thedata, '>'); + } + char *data = www_tag_unwravel(child); + stralloc_cats(&thedata, data); + free(data); + + if (child->tag != NULL) { + stralloc_cats(&thedata, "tag); + stralloc_append1(&thedata, '>'); + ptr_vector_apply(&child->attribs, free); + destroy_ptr_vector(&child->attribs); + ptr_vector_apply(&child->values, free); + destroy_ptr_vector(&child->values); + } + } else { + if (child->tag != NULL) { + stralloc_append1(&thedata, '<'); + stralloc_cats(&thedata, child->tag); + for (int i = 0; i < child->attribs.len; i++) { + stralloc_append1(&thedata, ' '); + stralloc_cats(&thedata, (char *)ptr_vector_get(&child->attribs, i)); + stralloc_append1(&thedata, '='); + stralloc_append1(&thedata, '\"'); + stralloc_cats(&thedata, (char *)ptr_vector_get(&child->values, i)); + stralloc_append1(&thedata, '\"'); + } + stralloc_cats(&thedata, " />"); + ptr_vector_apply(&child->attribs, free); + destroy_ptr_vector(&child->attribs); + ptr_vector_apply(&child->values, free); + destroy_ptr_vector(&child->values); + } else { + stralloc_cats(&thedata, child->data); + } + } + destroy_ptr_vector(&child->children); + + } + + stralloc_0(&thedata); + + return thedata.s; +} + +#endif diff --git a/src/www_tree.h b/src/www_tree.h new file mode 100644 index 0000000..fbc7f41 --- /dev/null +++ b/src/www_tree.h @@ -0,0 +1,23 @@ +#if defined(ENABLE_WWW) +#ifndef __WWW_TREE_H__ +#define __WWW_TREE_H__ + +#include "bbs.h" + +struct www_tag { + char *tag; + char *data; + struct ptr_vector attribs; + struct ptr_vector values; + + struct ptr_vector children; +}; + +extern struct www_tag *www_tag_new(char *tag, char *data); +extern void www_tag_add_attrib(struct www_tag *tag, char *attrib, char *value); +extern struct www_tag *www_tag_duplicate(struct www_tag *oldtag); +extern void www_tag_add_child(struct www_tag *tag, struct www_tag *child); +extern char *www_tag_destroy(struct www_tag *tag); +extern char *www_tag_unwravel(struct www_tag *tag); +#endif +#endif diff --git a/utils/magiedit/magiedit.ans b/utils/magiedit/magiedit.ans index b06e7fb..f80bf1f 100644 --- a/utils/magiedit/magiedit.ans +++ b/utils/magiedit/magiedit.ans @@ -20,4 +20,4 @@ -----Ctrl Q Quote þ Ctrl X Abort þ Ctrl Z Save-----------------------MagiEdit2-- +---Ctrl Q Quote þ Ctrl X Abort þ Ctrl Z Save þ F9 Save Draft þ F10 Load Draft-- diff --git a/utils/magiedit/main.c b/utils/magiedit/main.c index 3df71a4..4a644b5 100644 --- a/utils/magiedit/main.c +++ b/utils/magiedit/main.c @@ -12,6 +12,9 @@ #include #include #include +#include +#include +#include char **quote_lines; int quote_line_count; @@ -22,6 +25,228 @@ char *msgsubj; char *msgarea; int msgpriv; +char *draft_filename = NULL; + + +char *load_draft() { + DIR *dirp; + struct dirent *dent; + char draft_path[PATH_MAX]; + char **filenames; + int filename_count = 0; + int redraw = 1; + int start = 0; + int selected = 0; + int i; + tODInputEvent ch; + + snprintf(draft_path, PATH_MAX, "drafts/%s", od_control_get()->user_name); + + dirp = opendir(draft_path); + + if (!dirp) { + od_clr_scr(); + od_printf("`bright red`You have no drafts!\r\n`white`"); + od_printf("Press a key..."); + + od_get_key(TRUE); + return NULL; + } + + while ((dent = readdir(dirp)) != NULL) { + if (strlen(dent->d_name) > 6 && strcmp(&dent->d_name[strlen(dent->d_name) - 6], ".draft") == 0) { + if (filename_count == 0) { + filenames = (char **)malloc(sizeof(char *)); + } else { + filenames = (char **)realloc(filenames, sizeof(char *) * (filename_count + 1)); + } + + filenames[filename_count] = strndup(dent->d_name, strlen(dent->d_name) - 6); + + filename_count++; + } + } + closedir(dirp); + + if (filename_count == 0) { + od_clr_scr(); + od_printf("`bright red`You have no drafts!\r\n`white`"); + od_printf("Press a key..."); + od_get_key(TRUE); + return NULL; + } + + + while (1) { + if (redraw) { + od_set_color(D_GREY, D_BLACK); + od_clr_scr(); + + od_set_color(D_BLACK, D_CYAN); + od_set_cursor(1, 1); + od_printf("Your Drafts:"); + od_clr_line(); + od_set_cursor(24, 1); + od_printf("Up/Down Select, Enter confirm, D to Delete, Esc to cancel"); + od_clr_line(); + + for (i = start;i < start + 22 && i < filename_count; i++) { + if (i == selected) { + od_set_cursor(i - start + 2, 1); + od_set_color(D_BLACK, D_MAGENTA); + od_printf("%s", filenames[i]); + od_clr_line(); + } else { + od_set_cursor(i - start + 2, 1); + od_set_color(D_GREY, D_BLACK); + od_printf("%s", filenames[i]); + od_clr_line(); + } + } + redraw = 0; + } + + od_get_input(&ch, OD_NO_TIMEOUT, GETIN_RAWCTRL); + if (ch.EventType == EVENT_EXTENDED_KEY) { + if (ch.chKeyPress == OD_KEY_UP) { + selected--; + if (selected < 0) { + selected = 0; + } + if (selected < start) { + start = start - 22; + if (start < 0) { + start = 0; + } + redraw = 1; + } + + if (!redraw) { + od_set_cursor(selected - start + 2, 1); + od_set_color(D_BLACK, D_MAGENTA); + od_printf("%s", filenames[selected]); + od_clr_line(); + + if (filename_count > selected + 1) { + od_set_cursor(selected + 1 - start + 2, 1); + od_set_color(D_GREY, D_BLACK); + od_printf("%s", filenames[selected + 1]); + od_clr_line(); + } + od_set_cursor(selected - start + 2, 1); + } + } + + if (ch.chKeyPress == OD_KEY_DOWN) { + selected++; + if (selected >= filename_count) { + selected = filename_count - 1; + } + + if (selected >= start + 22) { + start = start + 22; + if (start + 22 >= filename_count) { + start = filename_count - 22; + } + redraw = 1; + } + if (!redraw) { + od_set_cursor(selected - start + 2, 1); + od_set_color(D_BLACK, D_MAGENTA); + od_printf("%s", filenames[selected]); + od_clr_line(); + if (selected - 1 >= 0) { + od_set_cursor(selected - 1 - start + 2, 1); + od_set_color(D_GREY, D_BLACK); + od_printf("%s", filenames[selected - 1]); + od_clr_line(); + } + od_set_cursor(selected - start + 2, 1); + } + } + } else { + if (ch.chKeyPress == 27) { + // escape + for (i=0;iuser_name, filenames[selected]); + unlink(draft_path); + + free(filenames[selected]); + + for (i=selected;iuser_name, filename); + + unlink(draft_path); +} + +int check_draft_filename(char *filename) { + struct stat s; + char draft_path[PATH_MAX]; + int i; + + for (i=0;iuser_name); + + if (stat(draft_path, &s) != 0) { + mkdir(draft_path, 0700); + } + + snprintf(draft_path, PATH_MAX, "drafts/%s/%s.draft", od_control_get()->user_name, filename); + + if (stat(draft_path, &s) != 0) { + return 1; + } + return 0; +} + char *message_editor() { char **body_lines; int body_line_count; @@ -47,13 +272,18 @@ char *message_editor() { int old_top_of_screen = 0; int stage = 0; int qq_start; + int draft_ext; + char draft_path[PATH_MAX]; + FILE *fptr; + char d_draft; + position_x = 0; position_y = 0; body_line_count = 0; done = 0; q_position = 0; q_start = 0; - + memset(line, 0, 81); memset(line_cpy, 0, 81); @@ -163,6 +393,172 @@ char *message_editor() { } else if (ch.chKeyPress == OD_KEY_HOME) { position_x = 0; od_set_cursor(position_y - top_of_screen + 5, position_x + 1); + } else if (ch.chKeyPress == OD_KEY_F9) { + // save as draft + if (draft_filename == NULL) { + draft_filename = strdup(msgsubj); + if (!check_draft_filename(draft_filename)) { + draft_ext = 0; + do { + draft_ext++; + free(draft_filename); + + draft_filename = (char *)malloc(sizeof(char) * (strlen(msgsubj) + 4)); + + snprintf(draft_filename, strlen(msgsubj) + 4, "%s_%d", msgsubj, draft_ext); + } while (!check_draft_filename(draft_filename) && draft_ext < 999); + } + if (draft_ext == 1000) { + free(draft_filename); + draft_filename = NULL; + } + } + + if (draft_filename != NULL) { + // save + // save message + body_len = 0; + for (i=0;iuser_name, draft_filename); + fptr = fopen(draft_path, "w"); + + if (!fptr) { + od_printf("`bright red`Unable to save draft!\r\n`white`"); + } else { + fwrite(return_body, 1, strlen(return_body), fptr); + + fclose(fptr); + od_printf("`bright green`Draft saved as \"%s\".`white`\r\n", draft_filename); + } + free(return_body); + } else { + od_printf("`bright red`Unable to save draft!\r\n`white`"); + } + + od_printf("Press a key..."); + od_get_key(TRUE); + + od_set_color(D_GREY, D_BLACK); + // restore screen + od_clr_scr(); + od_set_cursor(1, 1); + od_send_file("magiedit.ans"); + od_set_color(D_GREY, D_BLACK); + od_set_cursor(2, 13); + od_printf("%-26.26s", msgto); + od_set_cursor(3, 13); + od_printf("%-26.26s", msgsubj); + od_set_cursor(2, 52); + od_printf("%-26.26s", msgarea); + od_set_cursor(5, 1); + + if (position_y - top_of_screen > 17) { + top_of_screen = position_y - 17; + } + + for (i=top_of_screen;iuser_name, draft_filename); + fptr = fopen(draft_path, "r"); + if (!fptr) { + // error loading draft + } else { + // free body lines; + if (body_line_count > 0) { + for (i=0;i 17) { + top_of_screen = position_y - 17; + } + + for (i=top_of_screen;i= 73 && ch.chKeyPress > 31 && ch.chKeyPress != 127)) { @@ -528,11 +924,12 @@ char *message_editor() { od_set_color(D_BLACK, D_MAGENTA); od_printf("%s", quote_lines[q_position]); od_clr_line(); - - od_set_cursor(q_position + 1 - q_start + 16, 1); - od_set_color(D_BLACK, D_MAGENTA); - od_printf("%s", quote_lines[q_position + 1]); - od_clr_line(); + if (q_position + 1 < quote_line_count) { + od_set_cursor(q_position + 1 - q_start + 16, 1); + od_set_color(D_BLACK, D_MAGENTA); + od_printf("%s", quote_lines[q_position + 1]); + od_clr_line(); + } } } if (ch.chKeyPress == OD_KEY_DOWN) { @@ -553,10 +950,12 @@ char *message_editor() { od_set_color(D_BLACK, D_MAGENTA); od_printf("%s", quote_lines[q_position]); od_clr_line(); - od_set_cursor(q_position - 1 - q_start + 16, 1); - od_set_color(D_BLACK, D_MAGENTA); - od_printf("%s", quote_lines[q_position - 1]); - od_clr_line(); + if (q_position - 1 >= 0) { + od_set_cursor(q_position - 1 - q_start + 16, 1); + od_set_color(D_BLACK, D_MAGENTA); + od_printf("%s", quote_lines[q_position - 1]); + od_clr_line(); + } } } } else { @@ -737,6 +1136,17 @@ char *message_editor() { free(body_lines); } + od_clr_scr(); + + if (draft_filename != NULL) { + od_printf("`bright white`Delete draft \"%s\"? (Y/N) ", draft_filename); + d_draft = od_get_answer("YyNn"); + + if (tolower(d_draft) == 'y') { + delete_draft(draft_filename); + } + } + return return_body; } else if (ch.chKeyPress != '\n' && ch.chKeyPress != 0x1b) { if (position_x >= strlen(line)) {