| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715 |
- /******************************************************************************
- * This file is part of TinTin++ *
- * *
- * Copyright 2004-2020 Igor van den Hoven *
- * *
- * TinTin++ is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 3 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with TinTin++. If not, see https://www.gnu.org/licenses. *
- ******************************************************************************/
- /******************************************************************************
- * T I N T I N + + *
- * *
- * coded by Igor van den Hoven 2004 *
- ******************************************************************************/
- #include "tintin.h"
- #define DO_LOG(log) void log (struct session *ses, char *arg, char *arg1, char *arg2)
- DO_LOG(log_append);
- DO_LOG(log_info);
- DO_LOG(log_make);
- DO_LOG(log_move);
- DO_LOG(log_overwrite);
- DO_LOG(log_off);
- DO_LOG(log_remove);
- DO_LOG(log_timestamp);
- typedef void LOG (struct session *ses, char *arg, char *arg1, char *arg2);
- struct log_type
- {
- char * name;
- LOG * fun;
- char * desc;
- };
- struct log_type log_table[] =
- {
- { "APPEND", log_append, "Start logging, appending to given file." },
- { "INFO", log_info, "Some logging related info." },
- { "MAKE", log_make, "Make the given directory." },
- { "MOVE", log_move, "Move the given file." },
- { "OFF", log_off, "Stop logging." },
- { "OVERWRITE", log_overwrite, "Start logging, overwriting the given file." },
- { "REMOVE", log_remove, "Remove the given file or directory." },
- { "TIMESTAMP", log_timestamp, "Timestamp prepended to each log line." },
- { "", NULL, "" }
- };
- DO_COMMAND(do_log)
- {
- int cnt;
- push_call("do_log(%p,%p)",ses,arg);
- arg = sub_arg_in_braces(ses, arg, arg1, GET_ONE, SUB_VAR|SUB_FUN);
- arg = sub_arg_in_braces(ses, arg, arg2, GET_ONE, SUB_VAR|SUB_FUN|SUB_ESC);
- if (*arg1 == 0)
- {
- info:
- tintin_header(ses, 80, " LOG OPTIONS ");
- for (cnt = 0 ; *log_table[cnt].fun != NULL ; cnt++)
- {
- if (*log_table[cnt].desc)
- {
- tintin_printf2(ses, " [%-13s] %s", log_table[cnt].name, log_table[cnt].desc);
- }
- }
- pop_call();
- return ses;
- }
- else
- {
- for (cnt = 0 ; *log_table[cnt].name ; cnt++)
- {
- if (is_abbrev(arg1, log_table[cnt].name))
- {
- break;
- }
- }
- if (*log_table[cnt].name == 0)
- {
- goto info;
- }
- else
- {
- log_table[cnt].fun(ses, arg, arg1, arg2);
- }
- }
- pop_call();
- return ses;
- }
- DO_LOG(log_append)
- {
- if (ses->log->file)
- {
- fclose(ses->log->file);
- }
- if ((ses->log->file = fopen(arg2, "a")))
- {
- SET_BIT(ses->log->mode, LOG_FLAG_APPEND);
- RESTRING(ses->log->name, arg2);
- logheader(ses, ses->log->file, ses->log->mode);
- show_message(ses, LIST_COMMAND, "#LOG: LOGGING OUTPUT TO '%s' FILESIZE: %ld", arg2, ftell(ses->log->file));
- }
- else
- {
- show_error(ses, LIST_COMMAND, "#ERROR: #LOG {%s} {%s}: COULDN'T OPEN FILE.", arg1, arg2);
- }
- }
- DO_LOG(log_info)
- {
- tintin_printf2(ses, "#LOG INFO: FILE = %s", ses->log->file ? ses->log->name : "");
- tintin_printf2(ses, "#LOG INFO: LEVEL = %s", HAS_BIT(ses->log->mode, LOG_FLAG_LOW) ? "LOW" : "HIGH");
- tintin_printf2(ses, "#LOG INFO: MODE = %s", HAS_BIT(ses->log->mode, LOG_FLAG_HTML) ? "HTML" : HAS_BIT(ses->log->mode, LOG_FLAG_PLAIN) ? "PLAIN" : HAS_BIT(ses->log->mode, LOG_FLAG_RAW) ? "RAW" : "UNSET");
- tintin_printf2(ses, "#LOG INFO: LINE = %s", ses->log->line_file ? ses->log->line_name : "");
- tintin_printf2(ses, "#LOG INFO: NEXT = %s", ses->log->next_file ? ses->log->next_name : "");
- }
- DO_LOG(log_make)
- {
- if (mkdir(arg2, 0755))
- {
- if (errno != EEXIST)
- {
- show_error(ses, LIST_COMMAND, "#ERROR: #LOG MAKE: FAILED TO CREATE DIRECTORY {%s} (%s).", arg2, strerror(errno));
- }
- else
- {
- show_message(ses, LIST_COMMAND, "#LOG MAKE: DIRECTORY {%s} ALREADY EXISTS.", arg2);
- }
- }
- else
- {
- show_message(ses, LIST_COMMAND, "#LOG MAKE: CREATED DIRECTORY {%s}.", arg2);
- }
- }
- DO_LOG(log_move)
- {
- char *arg3;
- int result;
- arg3 = str_alloc_stack(0);
- arg = sub_arg_in_braces(ses, arg, arg3, GET_ALL, SUB_VAR|SUB_FUN);
- result = rename(arg2, arg3);
- if (result == 0)
- {
- show_message(ses, LIST_COMMAND, "#LOG MOVE: FILE {%s} MOVED TO {%s}.", arg2, arg3);
- }
- else
- {
- show_error(ses, LIST_COMMAND, "#LOG MOVE: COULDN'T MOVE FILE {%s} TO {%s}.", arg2, arg3);
- }
- }
- DO_LOG(log_overwrite)
- {
- if (ses->log->file)
- {
- fclose(ses->log->file);
- }
- if ((ses->log->file = fopen(arg2, "w")))
- {
- SET_BIT(ses->log->mode, LOG_FLAG_OVERWRITE);
- RESTRING(ses->log->name, arg2);
- logheader(ses, ses->log->file, ses->log->mode);
- show_message(ses, LIST_COMMAND, "#LOG: LOGGING OUTPUT TO {%s}", arg2);
- }
- else
- {
- show_error(ses, LIST_COMMAND, "#ERROR: #LOG {%s} {%s}: COULDN'T OPEN FILE.", arg1, arg2);
- }
- }
- DO_LOG(log_off)
- {
- if (ses->log->file)
- {
- DEL_BIT(ses->log->mode, LOG_FLAG_APPEND|LOG_FLAG_OVERWRITE);
- fclose(ses->log->file);
- ses->log->file = NULL;
- show_message(ses, LIST_COMMAND, "#LOG {OFF}: LOGGING TURNED OFF.");
- }
- else
- {
- show_message(ses, LIST_COMMAND, "#LOG: LOGGING ALREADY TURNED OFF.");
- }
- }
- DO_LOG(log_remove)
- {
- int result = remove(arg2);
- if (result == 0)
- {
- show_message(ses, LIST_COMMAND, "#LOG REMOVE: FILE {%s} REMOVED.", arg2);
- }
- else
- {
- show_error(ses, LIST_COMMAND, "#LOG REMOVE: COULDN'T REMOVE FILE {%s}.", arg2);
- }
- }
- DO_LOG(log_timestamp)
- {
- RESTRING(ses->log->stamp_strf, arg2);
- ses->log->stamp_time = 0;
- show_message(ses, LIST_COMMAND, "#LOG TIMESTAMP: FORMAT SET TO {%s}.", arg2);
- }
- void init_log(struct session *ses)
- {
- ses->log->name = strdup("");
- ses->log->next_name = strdup("");
- ses->log->line_name = strdup("");
- ses->log->stamp_strf = strdup("");
- }
- void free_log(struct session *ses)
- {
- free(ses->log->name);
- free(ses->log->next_name);
- free(ses->log->line_name);
- free(ses->log->stamp_strf);
- free(ses->log);
- }
- void logit(struct session *ses, char *txt, FILE *file, int flags)
- {
- char out[BUFFER_SIZE];
- push_call("logit(%p,%p,%p,%d)",ses,txt,file,flags);
- if (*ses->log->stamp_strf && (HAS_BIT(ses->log->mode, LOG_FLAG_STAMP) || file == ses->log->file))
- {
- if (ses->log->stamp_time != gtd->time)
- {
- struct tm timeval_tm = *localtime(>d->time);
- ses->log->stamp_time = gtd->time;
- substitute(ses, ses->log->stamp_strf, out, SUB_COL|SUB_ESC|SUB_VAR|SUB_FUN);
- strftime(ses->log->stamp_text, 99, out, &timeval_tm);
- }
- fputs(ses->log->stamp_text, file);
- }
- if (HAS_BIT(ses->log->mode, LOG_FLAG_PLAIN) || HAS_BIT(flags, LOG_FLAG_PLAIN))
- {
- strip_vt102_codes(txt, out);
- }
- else if (HAS_BIT(ses->log->mode, LOG_FLAG_HTML))
- {
- vt102_to_html(ses, txt, out);
- }
- else
- {
- strcpy(out, txt);
- }
- if (HAS_BIT(flags, LOG_FLAG_LINEFEED))
- {
- strcat(out, "\n");
- }
- fputs(out, file);
- fflush(file);
- pop_call();
- return;
- }
- void logheader(struct session *ses, FILE *file, int flags)
- {
- push_call("logheader(%p,%p,%d)",ses,file,flags);
- if (HAS_BIT(flags, LOG_FLAG_APPEND))
- {
- if (HAS_BIT(flags, LOG_FLAG_HTML))
- {
- fseek(file, 0, SEEK_END);
- if (ftell(file) == 0)
- {
- write_html_header(ses, file);
- }
- }
- }
- else if (HAS_BIT(flags, LOG_FLAG_OVERWRITE) && HAS_BIT(flags, LOG_FLAG_HTML))
- {
- if (HAS_BIT(ses->log->mode, LOG_FLAG_HTML))
- {
- write_html_header(ses, file);
- }
- }
- pop_call();
- return;
- }
- char *get_charset_html(struct session *ses)
- {
- int index;
- for (index = 0 ; *charset_table[index].name ; index++)
- {
- if (ses->charset == charset_table[index].flags)
- {
- return charset_table[index].html;
- }
- }
- return "";
- }
- void write_html_header(struct session *ses, FILE *fp)
- {
- char header[BUFFER_SIZE];
- sprintf(header,
- "<!DOCTYPE html>\n"
- "<html>\n"
- "<head>\n"
- "<meta http-equiv='content-type' content='text/html; charset=%s'>\n"
- "<meta name='viewport' content='width=device-width, initial-scale=1.0'>\n"
- "<style type='text/css'>\n"
- "body {font-family:Consolas;font-size:12pt}\n"
- "a {text-decoration:none}\n"
- "a:link {color:#06b}\n"
- "a:visited {color:#6b0}\n"
- "a:hover {text-decoration:underline}\n"
- "a:active {color:#b06}\n"
- "</style>\n"
- "<body bgcolor='#000000'>\n"
- "</head>\n"
- "<pre>\n"
- "<span style='background-color:#000'><span style='color:#FFF'>\n",
- get_charset_html(ses));
- fputs(header, fp);
- }
- void vt102_to_html(struct session *ses, char *txt, char *out)
- {
- char tmp[BUFFER_SIZE], *pti, *pto;
- char xtc[6] = { '0', '6', '8', 'B', 'D', 'F' };
- char *ans[16] = { "000", "A00", "0A0", "AA0", "00A", "A0A", "0AA", "AAA", "555", "F55", "5F5", "FF5", "55F", "F5F", "5FF", "FFF" };
- int vtc, fgc, bgc, cnt;
- int rgb[6] = { 0, 0, 0, 0, 0, 0 };
- vtc = ses->vtc;
- fgc = ses->fgc;
- bgc = ses->bgc;
- pti = txt;
- pto = out;
- while (*pti)
- {
- while (skip_vt102_codes_non_graph(pti))
- {
- pti += skip_vt102_codes_non_graph(pti);
- }
- switch (*pti)
- {
- case 27:
- pti += 2;
- for (cnt = 0 ; pti[cnt] ; cnt++)
- {
- tmp[cnt] = pti[cnt];
- if (pti[cnt] == ';' || pti[cnt] == 'm')
- {
- tmp[cnt] = 0;
- cnt = -1;
- pti += 1 + strlen(tmp);
- if (HAS_BIT(vtc, COL_XTF_R))
- {
- fgc = URANGE(0, atoi(tmp), 255);
- DEL_BIT(vtc, COL_XTF_R);
- SET_BIT(vtc, COL_XTF);
- }
- else if (HAS_BIT(vtc, COL_XTB_R))
- {
- bgc = URANGE(0, atoi(tmp), 255);
- DEL_BIT(vtc, COL_XTB_R);
- SET_BIT(vtc, COL_XTB);
- }
- else if (HAS_BIT(vtc, COL_TCF_R))
- {
- if (rgb[0] == 256)
- {
- rgb[0] = URANGE(0, atoi(tmp), 255);
- }
- else if (rgb[1] == 256)
- {
- rgb[1] = URANGE(0, atoi(tmp), 255);
- }
- else if (rgb[2] == 256)
- {
- rgb[2] = URANGE(0, atoi(tmp), 255);
- fgc = rgb[0] * 256 * 256 + rgb[1] * 256 + rgb[2];
- DEL_BIT(vtc, COL_TCF_R);
- SET_BIT(vtc, COL_TCF);
- }
- }
- else if (HAS_BIT(vtc, COL_TCB_R))
- {
- if (rgb[3] == 256)
- {
- rgb[3] = URANGE(0, atoi(tmp), 255);
- }
- else if (rgb[4] == 256)
- {
- rgb[4] = URANGE(0, atoi(tmp), 255);
- }
- else if (rgb[5] == 256)
- {
- rgb[5] = URANGE(0, atoi(tmp), 255);
- bgc = rgb[3] * 256 * 256 + rgb[4] * 256 + rgb[5];
- DEL_BIT(vtc, COL_TCB_R);
- SET_BIT(vtc, COL_TCB);
- }
- }
- else
- {
- switch (atoi(tmp))
- {
- case 0:
- vtc = 0;
- fgc = 7;
- bgc = 0;
- break;
- case 1:
- SET_BIT(vtc, COL_BLD);
- break;
- case 2:
- if (HAS_BIT(vtc, COL_TCF_2))
- {
- DEL_BIT(vtc, COL_XTF_5|COL_TCF_2);
- SET_BIT(vtc, COL_TCF_R);
- rgb[0] = 256; rgb[1] = 256; rgb[2] = 256;
- }
- else if (HAS_BIT(vtc, COL_TCB_2))
- {
- DEL_BIT(vtc, COL_XTB_5|COL_TCF_2);
- SET_BIT(vtc, COL_TCB_R);
- rgb[3] = 256; rgb[4] = 256; rgb[5] = 256;
- }
- else
- {
- DEL_BIT(vtc, COL_BLD);
- }
- break;
- case 5:
- if (HAS_BIT(vtc, COL_XTF_5))
- {
- DEL_BIT(vtc, COL_XTF_5|COL_TCF_2);
- SET_BIT(vtc, COL_XTF_R);
- }
- else if (HAS_BIT(vtc, COL_XTB_5))
- {
- DEL_BIT(vtc, COL_XTB_5|COL_TCF_2);
- SET_BIT(vtc, COL_XTB_R);
- }
- break;
- case 7:
- SET_BIT(vtc, COL_REV);
- break;
- case 21:
- case 22:
- DEL_BIT(vtc, COL_BLD);
- break;
- case 27:
- DEL_BIT(vtc, COL_REV);
- break;
- case 38:
- case 39:
- SET_BIT(vtc, COL_XTF_5|COL_TCF_2);
- fgc = 7;
- break;
- case 48:
- case 49:
- SET_BIT(vtc, COL_XTB_5|COL_TCB_2);
- bgc = 0;
- break;
- default:
- switch (atoi(tmp) / 10)
- {
- case 3:
- case 9:
- DEL_BIT(vtc, COL_XTF|COL_TCF);
- break;
- case 4:
- case 10:
- DEL_BIT(vtc, COL_XTB|COL_TCB);
- break;
- }
- if (atoi(tmp) / 10 == 4)
- {
- bgc = atoi(tmp) % 10;
- }
- else if (atoi(tmp) / 10 == 10)
- {
- bgc = atoi(tmp) % 10;
- }
- else if (atoi(tmp) / 10 == 3)
- {
- fgc = atoi(tmp) % 10;
- }
- else if (atoi(tmp) / 10 == 9)
- {
- SET_BIT(vtc, COL_BLD);
- fgc = atoi(tmp) % 10;
- }
- break;
- }
- }
- }
- if (pti[-1] == 'm')
- {
- break;
- }
- }
- if (!HAS_BIT(vtc, COL_REV) && HAS_BIT(ses->vtc, COL_REV))
- {
- cnt = fgc;
- fgc = ses->fgc = bgc;
- bgc = ses->bgc = cnt;
- }
- if (bgc != ses->bgc || fgc != ses->fgc || vtc != ses->vtc)
- {
- sprintf(pto, "</span>");
- pto += strlen(pto);
- if (bgc != ses->bgc)
- {
- if (HAS_BIT(vtc, COL_XTB))
- {
- if (bgc < 16)
- {
- sprintf(pto, "</span><span style='background-color: #%s'>", ans[bgc]);
- }
- else if (bgc < 232)
- {
- sprintf(pto, "</span><span style='background-color: #%c%c%c'>", xtc[(bgc-16) / 36], xtc[(bgc-16) % 36 / 6], xtc[(bgc-16) % 6]);
- }
- else
- {
- sprintf(pto, "</span><span style='background-color: rgb(%d,%d,%d)'>", (bgc-232) * 10 + 8, (bgc-232) * 10 + 8, (bgc-232) * 10 + 8);
- }
- }
- else if (HAS_BIT(vtc, COL_TCB))
- {
- sprintf(pto, "</span><span style='background-color:#%02x%02x%02x'>", rgb[3], rgb[4], rgb[5]);
- }
- else
- {
- sprintf(pto, "</span><span style='background-color:#%s'>", ans[bgc]);
- }
- pto += strlen(pto);
- }
- if (HAS_BIT(vtc, COL_XTF))
- {
- if (fgc < 16)
- {
- sprintf(pto, "</span><span style='color:#%s'>", ans[fgc]);
- }
- else if (fgc < 232)
- {
- sprintf(pto, "<span style='color:#%c%c%c'>", xtc[(fgc-16) / 36], xtc[(fgc-16) % 36 / 6], xtc[(fgc-16) % 6]);
- }
- else
- {
- sprintf(pto, "<span style='color:rgb(%d,%d,%d)'>", (fgc-232) * 10 + 8, (fgc-232) * 10 + 8,(fgc-232) * 10 + 8);
- }
- }
- else if (HAS_BIT(vtc, COL_TCF))
- {
- sprintf(pto, "<span style='color:#%02x%02x%02x'>", rgb[0], rgb[1], rgb[2]);
- }
- else
- {
- if (HAS_BIT(vtc, COL_BLD))
- {
- sprintf(pto, "<span style='color:#%s'>", ans[fgc+8]);
- }
- else
- {
- sprintf(pto, "<span style='color:#%s'>", ans[fgc]);
- }
- }
- pto += strlen(pto);
- }
- if (HAS_BIT(vtc, COL_REV) && !HAS_BIT(ses->vtc, COL_REV))
- {
- cnt = fgc;
- fgc = ses->fgc = bgc;
- bgc = ses->bgc = cnt;
- }
- ses->vtc = vtc;
- ses->fgc = fgc;
- ses->bgc = bgc;
- break;
- case 6:
- *pto++ = '&';
- pti++;
- break;
- case 28:
- *pto++ = '<';
- pti++;
- break;
- case 30:
- *pto++ = '>';
- pti++;
- break;
- case '>':
- sprintf(pto, ">");
- pto += strlen(pto);
- pti++;
- break;
- case '<':
- sprintf(pto, "<");
- pto += strlen(pto);
- pti++;
- break;
- case '"':
- sprintf(pto, """);
- pto += strlen(pto);
- pti++;
- break;
- case '&':
- sprintf(pto, "&");
- pto += strlen(pto);
- pti++;
- break;
- case '$':
- sprintf(pto, "$");
- pto += strlen(pto);
- pti++;
- break;
- case '\\':
- sprintf(pto, "\");
- pto += strlen(pto);
- pti++;
- break;
- case 0:
- break;
- default:
- *pto++ = *pti++;
- break;
- }
- }
- *pto = 0;
- }
|