changeset 20921:b2b16843851b

A patch from QuLogic to eliminate some duplication in the aMSN code, also from QuLogic. Fixes #3497 (again).
author Richard Laager <rlaager@wiktel.com>
date Sat, 13 Oct 2007 21:55:41 +0000
parents ef44eb0859fe
children d9cbd249619b 309eb010efd1 5e46cdf9ef2b c5f9e1eb59d5 789ed158a50a
files libpurple/plugins/log_reader.c
diffstat 1 files changed, 143 insertions(+), 148 deletions(-) [+]
line wrap: on
line diff
--- a/libpurple/plugins/log_reader.c	Sat Oct 13 21:36:50 2007 +0000
+++ b/libpurple/plugins/log_reader.c	Sat Oct 13 21:55:41 2007 +0000
@@ -2095,159 +2095,54 @@
 #define AMSN_LOG_CONV_END "|\"LRED[You have closed the window on "
 #define AMSN_LOG_CONV_EXTRA "01 Aug 2001 00:00:00]"
 
-/* `log_dir`/username@hotmail.com/logs/buddyname@hotmail.com.log */
-/* `log_dir`/username@hotmail.com/logs/Month Year/buddyname@hotmail.com.log */
-static GList *amsn_logger_list(PurpleLogType type, const char *sn, PurpleAccount *account)
+static GList *amsn_logger_parse_file(char *filename, const char *sn, PurpleAccount *account)
 {
 	GList *list = NULL;
-	struct amsn_logger_data *data;
-	const char *logdir;
-	char *username;
-	char *log_path;
-	char *buddy_log;
-	char *filename;
-	GDir *dir;
-	const char *name;
 	GError *error;
 	char *contents;
+	struct amsn_logger_data *data;
 	PurpleLog *log;
-	GList *files = NULL;
-	GList *f;
-
-	logdir = purple_prefs_get_string("/plugins/core/log_reader/amsn/log_directory");
-
-	/* By clearing the log directory path, this logger can be (effectively) disabled. */
-	if (!logdir || !*logdir)
-		return NULL;
-
-	/* aMSN only works with MSN/WLM */
-	if (strcmp(account->protocol_id, "prpl-msn"))
-		return NULL;
-
-	username = g_strdup(purple_normalize(account, account->username));
-	buddy_log = g_strdup_printf("%s.log", purple_normalize(account, sn));
-	log_path = g_build_filename(logdir, username, "logs", NULL);
-
-	/* First check in the top-level */
-	filename = g_build_filename(log_path, buddy_log, NULL);
-	if (g_file_test(filename, G_FILE_TEST_EXISTS))
-		files = g_list_prepend(files, filename);
-	else
-		g_free(filename);
-
-	/* Check in previous months */
-	dir = g_dir_open(log_path, 0, NULL);
-	if (dir) {
-		while ((name = g_dir_read_name(dir)) != NULL) {
-			filename = g_build_filename(log_path, name, buddy_log, NULL);
-			if (g_file_test(filename, G_FILE_TEST_EXISTS))
-				files = g_list_prepend(files, filename);
-			else
-				g_free(filename);
-		}
-		g_dir_close(dir);
-	}
-
-	g_free(log_path);
-
-	/* New versions use 'friendlier' directory names */
-	purple_util_chrreplace(username, '@', '_');
-	purple_util_chrreplace(username, '.', '_');
-
-	log_path = g_build_filename(logdir, username, "logs", NULL);
-
-	/* First check in the top-level */
-	filename = g_build_filename(log_path, buddy_log, NULL);
-	if (g_file_test(filename, G_FILE_TEST_EXISTS))
-		files = g_list_prepend(files, filename);
-	else
-		g_free(filename);
-
-	/* Check in previous months */
-	dir = g_dir_open(log_path, 0, NULL);
-	if (dir) {
-		while ((name = g_dir_read_name(dir)) != NULL) {
-			filename = g_build_filename(log_path, name, buddy_log, NULL);
-			if (g_file_test(filename, G_FILE_TEST_EXISTS))
-				files = g_list_prepend(files, filename);
-			else
-				g_free(filename);
-		}
-		g_dir_close(dir);
-	}
-
-	g_free(log_path);
-	g_free(username);
-	g_free(buddy_log);
-
-	/* Loop through files looking for logs */
-	for(f = g_list_first(files); f; f = g_list_next(f)) {
-		filename = f->data;
-		purple_debug_info("aMSN logger", "Reading %s\n", filename);
-		error = NULL;
-		if (!g_file_get_contents(filename, &contents, NULL, &error)) {
-			purple_debug_error("aMSN logger",
-			                   "Couldn't read file %s: %s \n", filename,
-			                   (error && error->message) ?
-			                    error->message : "Unknown error");
-			if (error)
-				g_error_free(error);
-		} else {
-			char *c = contents;
-			gboolean found_start = FALSE;
-			char *start_log = c;
-			int offset = 0;
-			struct tm tm;
-			while (c && *c) {
-				if (purple_str_has_prefix(c, AMSN_LOG_CONV_START)) {
-					char month[4];
-					if (sscanf(c + strlen(AMSN_LOG_CONV_START),
-					           "%u %3s %u %u:%u:%u",
-					           &tm.tm_mday, (char*)&month, &tm.tm_year,
-					           &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) {
-						found_start = FALSE;
-						purple_debug_error("aMSN logger",
-						                   "Error parsing start date for %s\n",
-						                   filename);
-					} else {
-						tm.tm_year -= 1900;
-
-						/* Let the C library deal with
-						 * daylight savings time.
-						 */
-						tm.tm_isdst = -1;
-						tm.tm_mon = get_month(month);
-
-						found_start = TRUE;
-						offset = c - contents;
-						start_log = c;
-					}
-				} else if (purple_str_has_prefix(c, AMSN_LOG_CONV_END) && found_start) {
-					data = g_new0(struct amsn_logger_data, 1);
-					data->path = g_strdup(filename);
-					data->offset = offset;
-					data->length = c - start_log
-					             + strlen(AMSN_LOG_CONV_END)
-					             + strlen(AMSN_LOG_CONV_EXTRA);
-					log = purple_log_new(PURPLE_LOG_IM, sn, account, NULL, mktime(&tm), NULL);
-					log->logger = amsn_logger;
-					log->logger_data = data;
-					list = g_list_prepend(list, log);
+
+	purple_debug_info("aMSN logger", "Reading %s\n", filename);
+	error = NULL;
+	if (!g_file_get_contents(filename, &contents, NULL, &error)) {
+		purple_debug_error("aMSN logger",
+		                   "Couldn't read file %s: %s \n", filename,
+		                   (error && error->message) ?
+		                    error->message : "Unknown error");
+		if (error)
+			g_error_free(error);
+	} else {
+		char *c = contents;
+		gboolean found_start = FALSE;
+		char *start_log = c;
+		int offset = 0;
+		struct tm tm;
+		while (c && *c) {
+			if (purple_str_has_prefix(c, AMSN_LOG_CONV_START)) {
+				char month[4];
+				if (sscanf(c + strlen(AMSN_LOG_CONV_START),
+				           "%u %3s %u %u:%u:%u",
+				           &tm.tm_mday, (char*)&month, &tm.tm_year,
+				           &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) {
 					found_start = FALSE;
-
-					purple_debug_info("aMSN logger",
-					                  "Found log for %s:"
-					                  " path = (%s),"
-					                  " offset = (%d),"
-					                  " length = (%d)\n",
-					                  sn, data->path, data->offset, data->length);
+					purple_debug_error("aMSN logger",
+					                   "Error parsing start date for %s\n",
+					                   filename);
+				} else {
+					tm.tm_year -= 1900;
+
+					/* Let the C library deal with
+					 * daylight savings time.
+					 */
+					tm.tm_isdst = -1;
+					tm.tm_mon = get_month(month);
+
+					found_start = TRUE;
+					offset = c - contents;
+					start_log = c;
 				}
-				c = strstr(c, "\n");
-				c++;
-			}
-
-			/* I've seen the file end without the AMSN_LOG_CONV_END bit */
-			if (found_start) {
+			} else if (purple_str_has_prefix(c, AMSN_LOG_CONV_END) && found_start) {
 				data = g_new0(struct amsn_logger_data, 1);
 				data->path = g_strdup(filename);
 				data->offset = offset;
@@ -2267,12 +2162,112 @@
 				                  " length = (%d)\n",
 				                  sn, data->path, data->offset, data->length);
 			}
-			g_free(contents);
+			c = strstr(c, "\n");
+			c++;
+		}
+
+		/* I've seen the file end without the AMSN_LOG_CONV_END bit */
+		if (found_start) {
+			data = g_new0(struct amsn_logger_data, 1);
+			data->path = g_strdup(filename);
+			data->offset = offset;
+			data->length = c - start_log
+				             + strlen(AMSN_LOG_CONV_END)
+				             + strlen(AMSN_LOG_CONV_EXTRA);
+			log = purple_log_new(PURPLE_LOG_IM, sn, account, NULL, mktime(&tm), NULL);
+			log->logger = amsn_logger;
+			log->logger_data = data;
+			list = g_list_prepend(list, log);
+			found_start = FALSE;
+
+			purple_debug_info("aMSN logger",
+			                  "Found log for %s:"
+			                  " path = (%s),"
+			                  " offset = (%d),"
+			                  " length = (%d)\n",
+			                  sn, data->path, data->offset, data->length);
 		}
+		g_free(contents);
+	}
+
+	return list;
+}
+
+/* `log_dir`/username@hotmail.com/logs/buddyname@hotmail.com.log */
+/* `log_dir`/username@hotmail.com/logs/Month Year/buddyname@hotmail.com.log */
+static GList *amsn_logger_list(PurpleLogType type, const char *sn, PurpleAccount *account)
+{
+	GList *list = NULL;
+	const char *logdir;
+	char *username;
+	char *log_path;
+	char *buddy_log;
+	char *filename;
+	GDir *dir;
+	const char *name;
+
+	logdir = purple_prefs_get_string("/plugins/core/log_reader/amsn/log_directory");
+
+	/* By clearing the log directory path, this logger can be (effectively) disabled. */
+	if (!logdir || !*logdir)
+		return NULL;
+
+	/* aMSN only works with MSN/WLM */
+	if (strcmp(account->protocol_id, "prpl-msn"))
+		return NULL;
+
+	username = g_strdup(purple_normalize(account, account->username));
+	buddy_log = g_strdup_printf("%s.log", purple_normalize(account, sn));
+	log_path = g_build_filename(logdir, username, "logs", NULL);
+
+	/* First check in the top-level */
+	filename = g_build_filename(log_path, buddy_log, NULL);
+	if (g_file_test(filename, G_FILE_TEST_EXISTS))
+		list = amsn_logger_parse_file(filename, sn, account);
+	else
 		g_free(filename);
+
+	/* Check in previous months */
+	dir = g_dir_open(log_path, 0, NULL);
+	if (dir) {
+		while ((name = g_dir_read_name(dir)) != NULL) {
+			filename = g_build_filename(log_path, name, buddy_log, NULL);
+			if (g_file_test(filename, G_FILE_TEST_EXISTS))
+				list = g_list_concat(list, amsn_logger_parse_file(filename, sn, account));
+			g_free(filename);
+		}
+		g_dir_close(dir);
 	}
 
-	g_list_free(files);
+	g_free(log_path);
+
+	/* New versions use 'friendlier' directory names */
+	purple_util_chrreplace(username, '@', '_');
+	purple_util_chrreplace(username, '.', '_');
+
+	log_path = g_build_filename(logdir, username, "logs", NULL);
+
+	/* First check in the top-level */
+	filename = g_build_filename(log_path, buddy_log, NULL);
+	if (g_file_test(filename, G_FILE_TEST_EXISTS))
+		list = g_list_concat(list, amsn_logger_parse_file(filename, sn, account));
+	g_free(filename);
+
+	/* Check in previous months */
+	dir = g_dir_open(log_path, 0, NULL);
+	if (dir) {
+		while ((name = g_dir_read_name(dir)) != NULL) {
+			filename = g_build_filename(log_path, name, buddy_log, NULL);
+			if (g_file_test(filename, G_FILE_TEST_EXISTS))
+				list = g_list_concat(list, amsn_logger_parse_file(filename, sn, account));
+			g_free(filename);
+		}
+		g_dir_close(dir);
+	}
+
+	g_free(log_path);
+	g_free(username);
+	g_free(buddy_log);
 
 	return list;
 }