[ekg2-commit] r4093 - trunk/plugins/logs: trunk/plugins/logs/main.c trunk/plugins/logs/main.h
SVN commit
svn w toxygen.net
Czw, 10 Lip 2008, 15:48:24 CEST
Author: darkjames
Date: 2008-07-10 15:48:24 +0200 (Thu, 10 Jul 2008)
New Revision: 4093
Modified:
trunk/plugins/logs/main.c
trunk/plugins/logs/main.h
Log:
- cleanup logs_fstring_to_string() and rename to fstring_reverse
- everything else is just cut && paste [_init() _destroy() at the end of file [not in the middle] before them queries...]
Modified: trunk/plugins/logs/main.c
===================================================================
--- trunk/plugins/logs/main.c 2008-07-10 11:02:52 UTC (rev 4092)
+++ trunk/plugins/logs/main.c 2008-07-10 13:48:24 UTC (rev 4093)
@@ -101,14 +101,6 @@
#define IRSSI_LOG_EKG2_CLOSED "--- Log closed %a %b %d %H:%M:%S %Y" /* defaultowy log_close_string irssi, jak cos to dodac zmienna... */
#define IRSSI_LOG_DAY_CHANGED "--- Day changed %a %b %d %Y" /* defaultowy log_day_changed irssi , jak cos to dodac zmienna... */
-static QUERY(logs_setvar_default) {
- xfree(config_logs_path);
- xfree(config_logs_timestamp);
- config_logs_path = xstrdup("~/.ekg2/logs/%S/%u");
- config_logs_timestamp = NULL;
- return 0;
-}
-
/*
* log_escape()
*
@@ -165,6 +157,98 @@
return res;
}
+static char *fstring_reverse(fstring_t *fstr) {
+ const char *str;
+ const short *attr;
+ string_t asc;
+ int i;
+
+ if (!fstr)
+ return NULL;
+
+ attr = fstr->attr;
+ str = fstr->str.b;
+
+ if (!attr || !str)
+ return NULL;
+
+ asc = string_init(NULL);
+
+ for (i = 0; str[i]; i++) {
+#define prev attr[i-1]
+#define cur attr[i]
+ int reset = 0;
+
+ if (i) {
+ if (!(cur & FSTR_BOLD) && (prev & FSTR_BOLD)) reset = 1;
+ if (!(cur & FSTR_BLINK) && (prev & FSTR_BLINK)) reset = 1;
+ if (!(cur & FSTR_UNDERLINE) && (prev & FSTR_UNDERLINE)) reset = 1;
+ if (!(cur & FSTR_REVERSE) && (prev & FSTR_REVERSE)) reset = 1;
+ if ((cur & FSTR_NORMAL) && !(prev & FSTR_NORMAL)) reset = 1; /* colors disappear */
+
+ if (reset)
+ string_append(asc, "%n");
+ } else
+ reset = 1;
+
+ /* attr */
+ if ((cur & FSTR_BLINK) && (reset || !(prev & FSTR_BLINK))) string_append(asc, "%i");
+// if ((cur & FSTR_UNDERLINE) && (reset || !(prev & FSTR_UNDERLINE))) string_append(asc, "%");
+// if ((cur & FSTR_REVERSE) && (reset || !(prev & FSTR_REVERSE))) string_append(asc, "%");
+
+ if (!(cur & FSTR_NORMAL)) {
+ /* background color XXX */
+#define BGCOLOR(x) -1
+ if (0 && ((reset || BGCOLOR(cur) != BGCOLOR(prev)))) {
+ string_append_c(asc, '%');
+ switch (BGCOLOR(cur)) {
+ case (0): string_append_c(asc, 'l'); break;
+ case (1): string_append_c(asc, 's'); break;
+ case (2): string_append_c(asc, 'h'); break;
+ case (3): string_append_c(asc, 'z'); break;
+ case (4): string_append_c(asc, 'e'); break;
+ case (5): string_append_c(asc, 'q'); break;
+ case (6): string_append_c(asc, 'd'); break;
+ case (7): string_append_c(asc, 'x'); break;
+ }
+ }
+#undef BGCOLOR
+
+ /* foreground color */
+#define FGCOLOR(x) ((!(x & FSTR_NORMAL)) ? (x & FSTR_FOREMASK) : -1)
+ if (((reset || FGCOLOR(cur) != FGCOLOR(prev)) || (i && (prev & FSTR_BOLD) != (cur & FSTR_BOLD)))) {
+ string_append_c(asc, '%');
+ switch ((cur & FSTR_FOREMASK)) {
+ case (0): string_append_c(asc, (cur & FSTR_BOLD) ? 'K' : 'k'); break;
+ case (1): string_append_c(asc, (cur & FSTR_BOLD) ? 'R' : 'r'); break;
+ case (2): string_append_c(asc, (cur & FSTR_BOLD) ? 'G' : 'g'); break;
+ case (3): string_append_c(asc, (cur & FSTR_BOLD) ? 'Y' : 'y'); break;
+ case (4): string_append_c(asc, (cur & FSTR_BOLD) ? 'B' : 'b'); break;
+ case (5): string_append_c(asc, (cur & FSTR_BOLD) ? 'M' : 'm'); break; /* | fioletowy | %m/%p | %M/%P | %q | */
+ case (6): string_append_c(asc, (cur & FSTR_BOLD) ? 'C' : 'c'); break;
+ case (7): string_append_c(asc, (cur & FSTR_BOLD) ? 'W' : 'w'); break;
+ }
+ }
+#undef FGCOLOR
+ } else { /* no color */
+ if ((cur & FSTR_BOLD) && (reset || !(prev & FSTR_BOLD)))
+ string_append(asc, "%T");
+ }
+
+ /* str */
+ if (str[i] == '%' || str[i] == '\\')
+ string_append_c(asc, '\\');
+ string_append_c(asc, str[i]);
+ }
+
+/* reset, and return. */
+ string_append(asc, "%n");
+ return string_free(asc, 0);
+
+#undef prev
+#undef cur
+}
+
/*
* zwraca irssi lub simple lub xml lub NULL
* w zaleznosci od ustawien log_format w sesji i log:logs
@@ -353,14 +437,6 @@
return f;
}
-static void logs_changed_maxfd(const char *var) {
- int maxfd = config_logs_max_files;
- if (in_autoexec)
- return;
- debug("maxfd limited to %d\n", maxfd);
-/* TODO: sprawdzic ile fd aktualnie jest otwartych jak cos to zamykac najstarsze... dodac kiedy otwarlismy plik i zapisalismy ostatnio cos do log_window_t ? */
-}
-
static void logs_changed_path(const char *var) {
list_t l;
if (in_autoexec || !log_logs)
@@ -387,19 +463,6 @@
buffer_free(&buffer_lograw);
}
-static QUERY(logs_postinit) {
- window_t *w;
- for (w = windows; w; w = w->next)
- logs_window_new(w);
- return 0;
-}
-
-static QUERY(logs_handler_killwin) {
- window_t *w = *(va_arg(ap, window_t **));
- logs_window_close(logs_log_find(w->session ? w->session->uid : NULL, w->target, 0), 1);
- return 0;
-}
-
static int logs_print_window(session_t *s, window_t *w, const char *line, time_t ts) {
static plugin_t *ui_plugin = NULL;
@@ -414,7 +477,7 @@
return -1;
}
- fline = format_string(line); /* format string */
+ fline = format_string(line); /* format string */
fstr = fstring_new(fline); /* create fstring */
fstr->ts = ts; /* sync timestamp */
@@ -422,7 +485,6 @@
query_emit_id(ui_plugin, UI_WINDOW_PRINT, &w, &fstr); /* let's rock */
xfree(fline); /* cleanup */
-
return 0;
}
@@ -507,151 +569,6 @@
return buffer_add_str(&buffer_lograw, file, line);
}
-static QUERY(logs_handler_newwin) {
- window_t *w = *(va_arg(ap, window_t **));
-
-/* w->floating */
-
- logs_window_new(w);
- if (config_logs_log_raw) {
- FILE *f;
- char *line;
- char *path;
-
- path = logs_prepare_path(w->id != 1 ? w->session : NULL, "~/.ekg2/logs/__internal__/%P/%S/%u", window_target(w), 0 /* time(NULL) */ );
- debug("logs_handler_newwin() loading buffer from: %s\n", __(path));
-
- f = logs_open_file(path, LOG_FORMAT_RAW);
-
- if (!f) {
- debug("[LOGS:%d] Cannot open/create file: %s\n", __LINE__, __(path));
- xfree(path);
- return 0;
- }
-
- /* XXX, in fjuczer it can be gzipped file, WARN HERE */
- while ((line = read_file(f, 0)))
- logs_buffer_raw_add_line(path, line);
-
- ftruncate(fileno(f), 0); /* works? */
- fclose(f);
-
-/* XXX, unlink file instead of truncating?
- if (unlink(path+'.raw') == -1) debug("[LOGS:%d] Cannot unlink file: %s (%d %s)\n", __LINE__, __(path), errno, strerror(errno));
-*/
-
- logs_buffer_raw_display(path, config_logs_remind_number);
- xfree(path);
- }
- return 0;
-}
-
-EXPORT int logs_plugin_init(int prio) {
-
- PLUGIN_CHECK_VER("logs");
-
- plugin_register(&logs_plugin, prio);
-
- query_connect_id(&logs_plugin, SET_VARS_DEFAULT,logs_setvar_default, NULL);
- query_connect_id(&logs_plugin, PROTOCOL_MESSAGE_POST, logs_handler, NULL);
- query_connect_id(&logs_plugin, IRC_PROTOCOL_MESSAGE, logs_handler_irc, NULL);
- query_connect_id(&logs_plugin, UI_WINDOW_NEW, logs_handler_newwin, NULL);
- query_connect_id(&logs_plugin, UI_WINDOW_PRINT, logs_handler_raw, NULL);
- query_connect_id(&logs_plugin, UI_WINDOW_KILL, logs_handler_killwin, NULL);
- query_connect_id(&logs_plugin, PROTOCOL_STATUS, logs_status_handler, NULL);
- query_connect_id(&logs_plugin, CONFIG_POSTINIT, logs_postinit, NULL);
- /* XXX, implement UI_WINDOW_TARGET_CHANGED, IMPORTANT!!!!!! */
-
- /* TODO: maksymalna ilosc plikow otwartych przez plugin logs */
- variable_add(&logs_plugin, ("log_max_open_files"), VAR_INT, 1, &config_logs_max_files, &logs_changed_maxfd, NULL, NULL);
- variable_add(&logs_plugin, ("log"), VAR_MAP, 1, &config_logs_log, &logs_changed_path,
- variable_map(3,
- LOG_FORMAT_NONE, 0, "none",
- LOG_FORMAT_SIMPLE, LOG_FORMAT_XML, "simple",
- LOG_FORMAT_XML, LOG_FORMAT_SIMPLE, "xml"),
- NULL);
- variable_add(&logs_plugin, ("log_raw"), VAR_BOOL, 1, &config_logs_log_raw, &logs_changed_raw, NULL, NULL);
- variable_add(&logs_plugin, ("log_ignored"), VAR_INT, 1, &config_logs_log_ignored, NULL, NULL, NULL);
- variable_add(&logs_plugin, ("log_status"), VAR_BOOL, 1, &config_logs_log_status, NULL, NULL, NULL);
- variable_add(&logs_plugin, ("path"), VAR_DIR, 1, &config_logs_path, &logs_changed_path, NULL, NULL);
- variable_add(&logs_plugin, ("remind_number"), VAR_INT, 1, &config_logs_remind_number, NULL, NULL, NULL);
- variable_add(&logs_plugin, ("timestamp"), VAR_STR, 1, &config_logs_timestamp, NULL, NULL, NULL);
-
- return 0;
-}
-
-static int logs_plugin_destroy() {
- list_t old_logs = log_logs;
- struct buffer *b;
-
- for (; log_logs; log_logs = log_logs->next) {
- logs_log_t *ll = log_logs->data;
- FILE *f = NULL;
- time_t t = time(NULL);
- int ff = (ll->lw) ? ll->lw->logformat : logs_log_format(session_find(ll->session));
-
- /* TODO: rewrite */
- if (ff == LOG_FORMAT_IRSSI && xstrlen(IRSSI_LOG_EKG2_CLOSED)) {
- char *path = (ll->lw) ? xstrdup(ll->lw->path) : logs_prepare_path(session_find(ll->session), config_logs_path, ll->uid, t);
- f = (ll->lw) ? logs_window_close(log_logs->data, 0) : NULL;
-
- if (!f)
- f = logs_open_file(path, ff);
- xfree(path);
- } else
- logs_window_close(log_logs->data, 1);
-
- if (f) {
- if (ff == LOG_FORMAT_IRSSI && xstrlen(IRSSI_LOG_EKG2_CLOSED)) {
- logs_irssi(f, ll->session, NULL,
- prepare_timestamp_format(IRSSI_LOG_EKG2_CLOSED, t), 0,
- LOG_IRSSI_INFO);
- }
- fclose(f);
- }
-
- xfree(ll->session);
- xfree(ll->uid);
- }
- list_destroy(old_logs, 1); log_logs = NULL;
-
- if (config_logs_log_raw) for (b = buffer_lograw.data; b;) {
- static FILE *f = NULL;
- static char *oldtarget = NULL;
- /*
- * path: b->target
- * ts: b->ts
- * str: b->line
- */
- if (f && !xstrcmp(b->target, oldtarget)); /* if file is already opened and current target match old one, use it */
- else {
- if (f) fclose(f); /* close file */
- f = logs_open_file(b->target, LOG_FORMAT_RAW); /* otherwise try to open new file/reopen */
- }
-
- if (f) {
- fprintf(f, "%i %s\n", (unsigned int) b->ts, b->line);
- } else debug("[LOGS:%d] Cannot open/create file: %s\n", __LINE__, __(b->target));
-
- xfree(b->line);
- xfree(oldtarget);
- oldtarget = b->target;
-
- b = LIST_REMOVE2(&(buffer_lograw.data), b, NULL);
-
- if (!b) {
- if (f) fclose(f);
- xfree(oldtarget);
- }
- }
- debug_error("[logs] 0x%x\n", buffer_lograw);
- /* just in case */
- buffer_free(&buffer_lograw);
-
- plugin_unregister(&logs_plugin);
- return 0;
-}
-
/*
* przygotowanie nazwy pliku bez rozszerzenia
* %S - sesja nasza
@@ -825,6 +742,193 @@
return fopen(fullname, "a+");
}
+/*
+ * zapis w formacie znanym z ekg1
+ * typ,uid,nickname,timestamp,{timestamp wyslania dla odleglych}, text
+ */
+
+static void logs_simple(FILE *file, const char *session, const char *uid, const char *text, time_t sent, msgclass_t class, const char *status) {
+ char *textcopy;
+ const char *timestamp = prepare_timestamp_format(config_logs_timestamp, time(0));
+
+ session_t *s = session_find((const char*)session);
+ const char *gotten_uid = get_uid(s, uid);
+ const char *gotten_nickname = get_nickname(s, uid);
+
+ if (!file)
+ return;
+ textcopy = log_escape(text);
+
+ if (!gotten_uid) gotten_uid = uid;
+ if (!gotten_nickname) gotten_nickname = uid;
+
+ switch (class) {
+ case EKG_MSGCLASS_MESSAGE : fputs("msgrecv,", file);
+ break;
+ case EKG_MSGCLASS_CHAT : fputs("chatrecv,", file);
+ break;
+ case EKG_MSGCLASS_SENT : fputs("msgsend,", file);
+ break;
+ case EKG_MSGCLASS_SENT_CHAT : fputs("chatsend,", file);
+ break;
+ case EKG_MSGCLASS_SYSTEM : fputs("msgsystem,", file);
+ break;
+ case EKG_MSGCLASS_PRIV_STATUS : fputs("status,", file);
+ break;
+ default : fputs("chatrecv,", file);
+ break;
+ };
+
+ /*
+ * chatsend,<numer>,<nick>,<czas>,<treść>
+ * chatrecv,<numer>,<nick>,<czas_otrzymania>,<czas_nadania>,<treść>
+ * status,<numer>,<nick>,[<ip>],<time>,<status>,<descr>
+ */
+
+ fputs(gotten_uid, file); fputc(',', file);
+ fputs(gotten_nickname, file); fputc(',', file);
+ if (class == EKG_MSGCLASS_PRIV_STATUS)
+ fputc(',', file);
+
+ fputs(timestamp, file); fputc(',', file);
+
+ if (class == EKG_MSGCLASS_MESSAGE || class == EKG_MSGCLASS_CHAT) {
+ const char *senttimestamp = prepare_timestamp_format(config_logs_timestamp, sent);
+ fputs(senttimestamp, file);
+ fputc(',', file);
+ } else if (class == EKG_MSGCLASS_PRIV_STATUS) {
+ fputs(status, file);
+ fputc(',', file);
+ }
+ if (textcopy) fputs(textcopy, file);
+ fputs("\n", file);
+
+ xfree(textcopy);
+ fflush(file);
+}
+
+/*
+ * zapis w formacie xml
+ */
+
+static void logs_xml(FILE *file, const char *session, const char *uid, const char *text, time_t sent, msgclass_t class) {
+ session_t *s;
+ char *textcopy;
+ const char *timestamp = prepare_timestamp_format(config_logs_timestamp, time(NULL));
+/* const char *senttimestamp = prepare_timestamp_format(config_logs_timestamp, sent); */
+ char *gotten_uid, *gotten_nickname;
+ const char *tmp;
+
+ if (!file)
+ return;
+
+ textcopy = xml_escape( text);
+
+ s = session_find((const char*)session);
+ gotten_uid = xml_escape( (tmp = get_uid(s, uid)) ? tmp : uid);
+ gotten_nickname = xml_escape( (tmp = get_nickname(s, uid)) ? tmp : uid);
+
+ fseek(file, -11, SEEK_END); /* wracamy przed </ekg2log> */
+
+ /*
+ * <message class="chatsend">
+ * <time>
+ * <sent>...</sent>
+ * <received>...</received>
+ * </time>
+ * <sender>
+ * <uid>...</uid>
+ * <nick>...</nick>
+ * </sender>
+ * <body>
+ * (#PCDATA)
+ * </body>
+ * </message>
+ */
+
+ fputs("<message class=\"",file);
+
+ switch (class) {
+ case EKG_MSGCLASS_MESSAGE : fputs("msgrecv", file); break;
+ case EKG_MSGCLASS_CHAT : fputs("chatrecv", file); break;
+ case EKG_MSGCLASS_SENT : fputs("msgsend", file); break;
+ case EKG_MSGCLASS_SENT_CHAT : fputs("chatsend", file); break;
+ case EKG_MSGCLASS_SYSTEM : fputs("msgsystem", file); break;
+ default : fputs("chatrecv", file); break;
+ };
+
+ fputs("\">\n", file);
+
+ fputs("\t<time>\n", file);
+ fputs("\t\t<received>", file); fputs(timestamp, file); fputs("</received>\n", file);
+ if (class == EKG_MSGCLASS_MESSAGE || class == EKG_MSGCLASS_CHAT) {
+ fputs("\t\t<sent>", file); fputs(timestamp, file); fputs("</sent>\n", file);
+ }
+ fputs("\t</time>\n", file);
+
+ fputs("\t<sender>\n", file);
+ fputs("\t\t<uid>", file); fputs(gotten_uid, file); fputs("</uid>\n", file);
+ fputs("\t\t<nick>", file); fputs(gotten_nickname, file); fputs("</nick>\n", file);
+ fputs("\t</sender>\n", file);
+
+ fputs("\t<body>\n", file);
+ if (textcopy) fputs(textcopy, file);
+ fputs("\t</body>\n", file);
+
+ fputs("</message>\n", file);
+ fputs("</ekg2log>\n", file);
+
+ xfree(textcopy);
+ xfree(gotten_uid);
+ xfree(gotten_nickname);
+ fflush(file);
+}
+
+/*
+ * zapis w formacie gaim'a
+ */
+
+#if 0
+static void logs_gaim()
+{
+}
+#endif
+
+/*
+ * write to file like irssi do.
+ */
+
+static void logs_irssi(FILE *file, const char *session, const char *uid, const char *text, time_t sent, int type) {
+ const char *nuid = NULL; /* get_nickname(session_find(session), uid) */
+
+ if (!file)
+ return;
+
+ switch (type) {
+ case LOG_IRSSI_STATUS: /* status message (other than @1) */
+ text = saprintf("reports status: %s /* {status} */", __(text));
+ case LOG_IRSSI_ACTION: /* irc ACTION messages */
+ fprintf(file, "%s * %s %s\n", prepare_timestamp_format(config_logs_timestamp, sent), nuid ? nuid : __(uid), __(text));
+ if (type == LOG_IRSSI_STATUS) xfree((char *) text);
+ break;
+ case LOG_IRSSI_INFO: /* other messages like session started, session closed and so on */
+ fprintf(file, "%s\n", __(text));
+ break;
+ case LOG_IRSSI_EVENT: /* text - join, part, quit, ... */
+ fprintf(file, "%s -!- %s has %s #%s\n",
+ prepare_timestamp_format(config_logs_timestamp, sent), nuid ? nuid : __(uid), __(text), __(session));
+ break;
+ case LOG_IRSSI_MESSAGE: /* just normal message */
+ fprintf(file, "%s <%s> %s\n", prepare_timestamp_format(config_logs_timestamp, sent), nuid ? nuid : __(uid), __(text));
+ break;
+ default: /* everythink else */
+ debug("[LOGS_IRSSI] UTYPE = %d\n", type);
+ return; /* to avoid flushisk file */
+ }
+ fflush(file);
+}
+
+
/*
* zwraca na przemian jeden z dwóch statycznych buforów, więc w obrębie
* jednego wyrażenia można wywołać tę funkcję dwukrotnie.
@@ -974,77 +1078,6 @@
return 0;
}
-static char *logs_fstring_to_string(const char *str, const short *attr) {
- int i;
- string_t asc = string_init(NULL);
-
- for (i = 0; i < xstrlen(str); i++) {
-#define ISBOLD(x) (x & 64)
-#define ISBLINK(x) (x & 256)
-#define ISUNDERLINE(x) (x & 512)
-#define ISREVERSE(x) (x & 1024)
-#define FGCOLOR(x) ((!(x & 128)) ? (x & 7) : -1)
-#define BGCOLOR(x) -1 /* XXX */
-
-#define prev attr[i-1]
-#define cur attr[i]
-
- int reset = 1;
-
- /* attr */
- if (i && !ISBOLD(cur) && ISBOLD(prev)); /* NOT BOLD */
- else if (i && !ISBLINK(cur) && ISBLINK(prev)); /* NOT BLINK */
- else if (i && !ISUNDERLINE(cur) && ISUNDERLINE(prev)); /* NOT UNDERLINE */
- else if (i && !ISREVERSE(cur) && ISREVERSE(prev)); /* NOT REVERSE */
- else if (i && FGCOLOR(cur) == -1 && FGCOLOR(prev) != -1);/* NO FGCOLOR */
- else if (i && BGCOLOR(cur) == -1 && BGCOLOR(prev) != -1);/* NO BGCOLOR */
- else reset = 0;
-
- if (reset) string_append(asc, ("%n"));
-
- if (ISBOLD(cur) && (!i || reset || ISBOLD(cur) != ISBOLD(prev)) && FGCOLOR(cur) == -1)
- string_append(asc, ("%T")); /* no color + bold. */
-
- if (ISBLINK(cur) && (!i || reset || ISBLINK(cur) != ISBLINK(prev))) string_append(asc, ("%i"));
-// if (ISUNDERLINE(cur) && (!i || reset || ISUNDERLINE(cur) != ISUNDERLINE(prev))); string_append(asc, ("%"));
-// if (ISREVERSE(cur) && (!i || reset || ISREVERSE(cur) != ISREVERSE(prev))); string_append(asc, ("%"));
-
- if (BGCOLOR(cur) != -1 && ((!i || reset || BGCOLOR(cur) != BGCOLOR(prev)))) { /* if there's a background color... add it */
- string_append_c(asc, '%');
- switch (BGCOLOR(cur)) {
- case (0): string_append_c(asc, 'l'); break;
- case (1): string_append_c(asc, 's'); break;
- case (2): string_append_c(asc, 'h'); break;
- case (3): string_append_c(asc, 'z'); break;
- case (4): string_append_c(asc, 'e'); break;
- case (5): string_append_c(asc, 'q'); break;
- case (6): string_append_c(asc, 'd'); break;
- case (7): string_append_c(asc, 'x'); break;
- }
- }
-
- if (FGCOLOR(cur) != -1 && ((!i || reset || FGCOLOR(cur) != FGCOLOR(prev)) || (i && ISBOLD(prev) != ISBOLD(cur)))) { /* if there's a foreground color... add it */
- string_append_c(asc, '%');
- switch (FGCOLOR(cur)) {
- case (0): string_append_c(asc, ISBOLD(cur) ? 'K' : 'k'); break;
- case (1): string_append_c(asc, ISBOLD(cur) ? 'R' : 'r'); break;
- case (2): string_append_c(asc, ISBOLD(cur) ? 'G' : 'g'); break;
- case (3): string_append_c(asc, ISBOLD(cur) ? 'Y' : 'y'); break;
- case (4): string_append_c(asc, ISBOLD(cur) ? 'B' : 'b'); break;
- case (5): string_append_c(asc, ISBOLD(cur) ? 'M' : 'm'); break; /* | fioletowy | %m/%p | %M/%P | %q | */
- case (6): string_append_c(asc, ISBOLD(cur) ? 'C' : 'c'); break;
- case (7): string_append_c(asc, ISBOLD(cur) ? 'W' : 'w'); break;
- }
- }
-
- /* str */
- if (str[i] == '%' || str[i] == '\\') string_append_c(asc, '\\'); /* escape chars.. */
- string_append_c(asc, str[i]); /* append current char */
- }
- string_append(asc, ("%n")); /* reset */
- return string_free(asc, 0);
-}
-
static QUERY(logs_handler_raw) {
window_t *w = *(va_arg(ap, window_t **));
fstring_t *line = *(va_arg(ap, fstring_t **));
@@ -1056,7 +1089,7 @@
/* line->str + line->attr == ascii str with formats */
path = logs_prepare_path(w->id != 1 ? w->session : NULL, "~/.ekg2/logs/__internal__/%P/%S/%u", window_target(w), 0);
- str = logs_fstring_to_string(line->str.b, line->attr);
+ str = fstring_reverse(line);
logs_buffer_raw_add(path, str);
@@ -1066,190 +1099,170 @@
return 0;
}
-/*
- * zapis w formacie znanym z ekg1
- * typ,uid,nickname,timestamp,{timestamp wyslania dla odleglych}, text
- */
+static QUERY(logs_handler_newwin) {
+ window_t *w = *(va_arg(ap, window_t **));
-static void logs_simple(FILE *file, const char *session, const char *uid, const char *text, time_t sent, msgclass_t class, const char *status) {
- char *textcopy;
- const char *timestamp = prepare_timestamp_format(config_logs_timestamp, time(0));
+/* w->floating */
- session_t *s = session_find((const char*)session);
- const char *gotten_uid = get_uid(s, uid);
- const char *gotten_nickname = get_nickname(s, uid);
+ logs_window_new(w);
+ if (config_logs_log_raw) {
+ FILE *f;
+ char *line;
+ char *path;
- if (!file)
- return;
- textcopy = log_escape(text);
+ path = logs_prepare_path(w->id != 1 ? w->session : NULL, "~/.ekg2/logs/__internal__/%P/%S/%u", window_target(w), 0 /* time(NULL) */ );
+ debug("logs_handler_newwin() loading buffer from: %s\n", __(path));
- if (!gotten_uid) gotten_uid = uid;
- if (!gotten_nickname) gotten_nickname = uid;
+ f = logs_open_file(path, LOG_FORMAT_RAW);
- switch (class) {
- case EKG_MSGCLASS_MESSAGE : fputs("msgrecv,", file);
- break;
- case EKG_MSGCLASS_CHAT : fputs("chatrecv,", file);
- break;
- case EKG_MSGCLASS_SENT : fputs("msgsend,", file);
- break;
- case EKG_MSGCLASS_SENT_CHAT : fputs("chatsend,", file);
- break;
- case EKG_MSGCLASS_SYSTEM : fputs("msgsystem,", file);
- break;
- case EKG_MSGCLASS_PRIV_STATUS : fputs("status,", file);
- break;
- default : fputs("chatrecv,", file);
- break;
- };
+ if (!f) {
+ debug("[LOGS:%d] Cannot open/create file: %s\n", __LINE__, __(path));
+ xfree(path);
+ return 0;
+ }
- /*
- * chatsend,<numer>,<nick>,<czas>,<treść>
- * chatrecv,<numer>,<nick>,<czas_otrzymania>,<czas_nadania>,<treść>
- * status,<numer>,<nick>,[<ip>],<time>,<status>,<descr>
- */
+ /* XXX, in fjuczer it can be gzipped file, WARN HERE */
+ while ((line = read_file(f, 0)))
+ logs_buffer_raw_add_line(path, line);
- fputs(gotten_uid, file); fputc(',', file);
- fputs(gotten_nickname, file); fputc(',', file);
- if (class == EKG_MSGCLASS_PRIV_STATUS)
- fputc(',', file);
+ ftruncate(fileno(f), 0); /* works? */
+ fclose(f);
- fputs(timestamp, file); fputc(',', file);
+/* XXX, unlink file instead of truncating?
+ if (unlink(path+'.raw') == -1) debug("[LOGS:%d] Cannot unlink file: %s (%d %s)\n", __LINE__, __(path), errno, strerror(errno));
+*/
- if (class == EKG_MSGCLASS_MESSAGE || class == EKG_MSGCLASS_CHAT) {
- const char *senttimestamp = prepare_timestamp_format(config_logs_timestamp, sent);
- fputs(senttimestamp, file);
- fputc(',', file);
- } else if (class == EKG_MSGCLASS_PRIV_STATUS) {
- fputs(status, file);
- fputc(',', file);
+ logs_buffer_raw_display(path, config_logs_remind_number);
+ xfree(path);
}
- if (textcopy) fputs(textcopy, file);
- fputs("\n", file);
+ return 0;
+}
- xfree(textcopy);
- fflush(file);
+static QUERY(logs_postinit) {
+ window_t *w;
+ for (w = windows; w; w = w->next)
+ logs_window_new(w);
+ return 0;
}
-/*
- * zapis w formacie xml
- */
+static QUERY(logs_handler_killwin) {
+ window_t *w = *(va_arg(ap, window_t **));
+ logs_window_close(logs_log_find(w->session ? w->session->uid : NULL, w->target, 0), 1);
+ return 0;
+}
-static void logs_xml(FILE *file, const char *session, const char *uid, const char *text, time_t sent, msgclass_t class) {
- session_t *s;
- char *textcopy;
- const char *timestamp = prepare_timestamp_format(config_logs_timestamp, time(NULL));
-/* const char *senttimestamp = prepare_timestamp_format(config_logs_timestamp, sent); */
- char *gotten_uid, *gotten_nickname;
- const char *tmp;
+static QUERY(logs_setvar_default) {
+ xfree(config_logs_path);
+ xfree(config_logs_timestamp);
+ config_logs_path = xstrdup("~/.ekg2/logs/%S/%u");
+ config_logs_timestamp = NULL;
+ return 0;
+}
- if (!file)
- return;
+EXPORT int logs_plugin_init(int prio) {
- textcopy = xml_escape( text);
+ PLUGIN_CHECK_VER("logs");
- s = session_find((const char*)session);
- gotten_uid = xml_escape( (tmp = get_uid(s, uid)) ? tmp : uid);
- gotten_nickname = xml_escape( (tmp = get_nickname(s, uid)) ? tmp : uid);
+ plugin_register(&logs_plugin, prio);
+
+ query_connect_id(&logs_plugin, SET_VARS_DEFAULT,logs_setvar_default, NULL);
+ query_connect_id(&logs_plugin, PROTOCOL_MESSAGE_POST, logs_handler, NULL);
+ query_connect_id(&logs_plugin, IRC_PROTOCOL_MESSAGE, logs_handler_irc, NULL);
+ query_connect_id(&logs_plugin, UI_WINDOW_NEW, logs_handler_newwin, NULL);
+ query_connect_id(&logs_plugin, UI_WINDOW_PRINT, logs_handler_raw, NULL);
+ query_connect_id(&logs_plugin, UI_WINDOW_KILL, logs_handler_killwin, NULL);
+ query_connect_id(&logs_plugin, PROTOCOL_STATUS, logs_status_handler, NULL);
+ query_connect_id(&logs_plugin, CONFIG_POSTINIT, logs_postinit, NULL);
+ /* XXX, implement UI_WINDOW_TARGET_CHANGED, IMPORTANT!!!!!! */
- fseek(file, -11, SEEK_END); /* wracamy przed </ekg2log> */
+ /* TODO: maksymalna ilosc plikow otwartych przez plugin logs */
+ variable_add(&logs_plugin, ("log_max_open_files"), VAR_INT, 1, &config_logs_max_files, NULL /* XXX: logs_changed_maxfd */, NULL, NULL);
+ variable_add(&logs_plugin, ("log"), VAR_MAP, 1, &config_logs_log, &logs_changed_path,
+ variable_map(3,
+ LOG_FORMAT_NONE, 0, "none",
+ LOG_FORMAT_SIMPLE, LOG_FORMAT_XML, "simple",
+ LOG_FORMAT_XML, LOG_FORMAT_SIMPLE, "xml"),
+ NULL);
+ variable_add(&logs_plugin, ("log_raw"), VAR_BOOL, 1, &config_logs_log_raw, &logs_changed_raw, NULL, NULL);
+ variable_add(&logs_plugin, ("log_ignored"), VAR_INT, 1, &config_logs_log_ignored, NULL, NULL, NULL);
+ variable_add(&logs_plugin, ("log_status"), VAR_BOOL, 1, &config_logs_log_status, NULL, NULL, NULL);
+ variable_add(&logs_plugin, ("path"), VAR_DIR, 1, &config_logs_path, &logs_changed_path, NULL, NULL);
+ variable_add(&logs_plugin, ("remind_number"), VAR_INT, 1, &config_logs_remind_number, NULL, NULL, NULL);
+ variable_add(&logs_plugin, ("timestamp"), VAR_STR, 1, &config_logs_timestamp, NULL, NULL, NULL);
- /*
- * <message class="chatsend">
- * <time>
- * <sent>...</sent>
- * <received>...</received>
- * </time>
- * <sender>
- * <uid>...</uid>
- * <nick>...</nick>
- * </sender>
- * <body>
- * (#PCDATA)
- * </body>
- * </message>
- */
+ return 0;
+}
- fputs("<message class=\"",file);
+static int logs_plugin_destroy() {
+ list_t old_logs = log_logs;
+ struct buffer *b;
- switch (class) {
- case EKG_MSGCLASS_MESSAGE : fputs("msgrecv", file); break;
- case EKG_MSGCLASS_CHAT : fputs("chatrecv", file); break;
- case EKG_MSGCLASS_SENT : fputs("msgsend", file); break;
- case EKG_MSGCLASS_SENT_CHAT : fputs("chatsend", file); break;
- case EKG_MSGCLASS_SYSTEM : fputs("msgsystem", file); break;
- default : fputs("chatrecv", file); break;
- };
+ for (; log_logs; log_logs = log_logs->next) {
+ logs_log_t *ll = log_logs->data;
+ FILE *f = NULL;
+ time_t t = time(NULL);
+ int ff = (ll->lw) ? ll->lw->logformat : logs_log_format(session_find(ll->session));
- fputs("\">\n", file);
+ /* TODO: rewrite */
+ if (ff == LOG_FORMAT_IRSSI && xstrlen(IRSSI_LOG_EKG2_CLOSED)) {
+ char *path = (ll->lw) ? xstrdup(ll->lw->path) : logs_prepare_path(session_find(ll->session), config_logs_path, ll->uid, t);
+ f = (ll->lw) ? logs_window_close(log_logs->data, 0) : NULL;
- fputs("\t<time>\n", file);
- fputs("\t\t<received>", file); fputs(timestamp, file); fputs("</received>\n", file);
- if (class == EKG_MSGCLASS_MESSAGE || class == EKG_MSGCLASS_CHAT) {
- fputs("\t\t<sent>", file); fputs(timestamp, file); fputs("</sent>\n", file);
- }
- fputs("\t</time>\n", file);
+ if (!f)
+ f = logs_open_file(path, ff);
+ xfree(path);
+ } else
+ logs_window_close(log_logs->data, 1);
- fputs("\t<sender>\n", file);
- fputs("\t\t<uid>", file); fputs(gotten_uid, file); fputs("</uid>\n", file);
- fputs("\t\t<nick>", file); fputs(gotten_nickname, file); fputs("</nick>\n", file);
- fputs("\t</sender>\n", file);
+ if (f) {
+ if (ff == LOG_FORMAT_IRSSI && xstrlen(IRSSI_LOG_EKG2_CLOSED)) {
+ logs_irssi(f, ll->session, NULL,
+ prepare_timestamp_format(IRSSI_LOG_EKG2_CLOSED, t), 0,
+ LOG_IRSSI_INFO);
+ }
+ fclose(f);
+ }
- fputs("\t<body>\n", file);
- if (textcopy) fputs(textcopy, file);
- fputs("\t</body>\n", file);
+ xfree(ll->session);
+ xfree(ll->uid);
+ }
+ list_destroy(old_logs, 1); log_logs = NULL;
- fputs("</message>\n", file);
- fputs("</ekg2log>\n", file);
+ if (config_logs_log_raw) for (b = buffer_lograw.data; b;) {
+ static FILE *f = NULL;
+ static char *oldtarget = NULL;
+ /*
+ * path: b->target
+ * ts: b->ts
+ * str: b->line
+ */
+ if (f && !xstrcmp(b->target, oldtarget)); /* if file is already opened and current target match old one, use it */
+ else {
+ if (f) fclose(f); /* close file */
+ f = logs_open_file(b->target, LOG_FORMAT_RAW); /* otherwise try to open new file/reopen */
+ }
- xfree(textcopy);
- xfree(gotten_uid);
- xfree(gotten_nickname);
- fflush(file);
-}
+ if (f) {
+ fprintf(f, "%i %s\n", (unsigned int) b->ts, b->line);
+ } else debug("[LOGS:%d] Cannot open/create file: %s\n", __LINE__, __(b->target));
-/*
- * zapis w formacie gaim'a
- */
+ xfree(b->line);
+ xfree(oldtarget);
+ oldtarget = b->target;
-#if 0
-static void logs_gaim()
-{
-}
-#endif
+ b = LIST_REMOVE2(&(buffer_lograw.data), b, NULL);
-/*
- * write to file like irssi do.
- */
+ if (!b) {
+ if (f) fclose(f);
+ xfree(oldtarget);
+ }
+ }
+ debug_error("[logs] 0x%x\n", buffer_lograw);
+ /* just in case */
+ buffer_free(&buffer_lograw);
-static void logs_irssi(FILE *file, const char *session, const char *uid, const char *text, time_t sent, int type) {
- const char *nuid = NULL; /* get_nickname(session_find(session), uid) */
-
- if (!file)
- return;
-
- switch (type) {
- case LOG_IRSSI_STATUS: /* status message (other than @1) */
- text = saprintf("reports status: %s /* {status} */", __(text));
- case LOG_IRSSI_ACTION: /* irc ACTION messages */
- fprintf(file, "%s * %s %s\n", prepare_timestamp_format(config_logs_timestamp, sent), nuid ? nuid : __(uid), __(text));
- if (type == LOG_IRSSI_STATUS) xfree((char *) text);
- break;
- case LOG_IRSSI_INFO: /* other messages like session started, session closed and so on */
- fprintf(file, "%s\n", __(text));
- break;
- case LOG_IRSSI_EVENT: /* text - join, part, quit, ... */
- fprintf(file, "%s -!- %s has %s #%s\n",
- prepare_timestamp_format(config_logs_timestamp, sent), nuid ? nuid : __(uid), __(text), __(session));
- break;
- case LOG_IRSSI_MESSAGE: /* just normal message */
- fprintf(file, "%s <%s> %s\n", prepare_timestamp_format(config_logs_timestamp, sent), nuid ? nuid : __(uid), __(text));
- break;
- default: /* everythink else */
- debug("[LOGS_IRSSI] UTYPE = %d\n", type);
- return; /* to avoid flushisk file */
- }
- fflush(file);
+ plugin_unregister(&logs_plugin);
+ return 0;
}
/*
Modified: trunk/plugins/logs/main.h
===================================================================
--- trunk/plugins/logs/main.h 2008-07-10 11:02:52 UTC (rev 4092)
+++ trunk/plugins/logs/main.h 2008-07-10 13:48:24 UTC (rev 4093)
@@ -43,7 +43,6 @@
log_window_t *lw;
} typedef logs_log_t;
-static char *log_escape(const char *str);
static char *logs_prepare_path(session_t *session, const char *logs_path, const char *uid, time_t sent);
static const char *prepare_timestamp_format(const char *format, time_t t);
@@ -51,11 +50,6 @@
static logs_log_t *logs_log_new(logs_log_t *l, const char *session, const char *uid);
static FILE *logs_open_file(char *path, int ff);
-static QUERY(logs_handler);
-static QUERY(logs_handler_newwin);
-static QUERY(logs_status_handler);
-static QUERY(logs_handler_irc);
-static QUERY(logs_handler_raw);
static void logs_simple(FILE *file, const char *session, const char *uid, const char *text, time_t sent, msgclass_t class, const char *status);
static void logs_xml (FILE *file, const char *session, const char *uid, const char *text, time_t sent, msgclass_t class);
Więcej informacji o liście dyskusyjnej ekg2-commit