[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