diff --git a/src/chat_log.c b/src/chat_log.c index 43ba820a..e1aa6865 100644 --- a/src/chat_log.c +++ b/src/chat_log.c @@ -129,8 +129,7 @@ chat_log_get_previous(const gchar * const login, const gchar * const recipient, char *filename = _get_log_filename(recipient, login, log_date, FALSE); FILE *logp = fopen(filename, "r"); - char *line = NULL; - size_t read = 0; + char *line; if (logp != NULL) { GString *gs_header = g_string_new(""); g_string_append_printf(gs_header, "%d/%d/%d:", @@ -141,16 +140,8 @@ chat_log_get_previous(const gchar * const login, const gchar * const recipient, history = g_slist_append(history, header); g_string_free(gs_header, TRUE); - size_t length = getline(&line, &read, logp); - while (length != -1) { - char *copy = malloc(length); - copy = strncpy(copy, line, length); - copy[length -1] = '\0'; - history = g_slist_append(history, copy); - free(line); - line = NULL; - read = 0; - length = getline(&line, &read, logp); + while ((line = prof_getline(logp)) != NULL) { + history = g_slist_append(history, line); } fclose(logp); diff --git a/src/common.c b/src/common.c index 840a0803..cdfa944c 100644 --- a/src/common.c +++ b/src/common.c @@ -29,6 +29,10 @@ #include "common.h" +// assume malloc stores at most 8 bytes for size of allocated memory +// and page size is at least 4KB +#define READ_BUF_SIZE 4088 + // backwards compatibility for GLib version < 2.28 void p_slist_free_full(GSList *items, GDestroyNotify free_func) @@ -118,3 +122,48 @@ encode_xml(const char * const xml) return coded_msg3; } + +char * +prof_getline(FILE *stream) +{ + char *buf; + size_t buf_size; + char *result; + char *s = NULL; + size_t s_size = 1; + int need_exit = 0; + + buf = (char *)malloc(READ_BUF_SIZE); + + while (TRUE) { + result = fgets(buf, READ_BUF_SIZE, stream); + if (result == NULL) + break; + buf_size = strlen(buf); + if (buf[buf_size - 1] == '\n') { + buf_size--; + buf[buf_size] = '\0'; + need_exit = 1; + } + + result = (char *)realloc(s, s_size + buf_size); + if (result == NULL) { + if (s != NULL) { + free(s); + s = NULL; + } + break; + } + s = result; + + memcpy(s + s_size - 1, buf, buf_size); + s_size += buf_size; + s[s_size - 1] = '\0'; + + if (need_exit != 0 || feof(stream) != 0) + break; + } + + free(buf); + return s; +} diff --git a/src/common.h b/src/common.h index 7ee774c4..47de27fb 100644 --- a/src/common.h +++ b/src/common.h @@ -23,6 +23,7 @@ #ifndef COMMON_H #define COMMON_H +#include #include #if !GLIB_CHECK_VERSION(2,28,0) @@ -41,5 +42,6 @@ char * str_replace(const char *string, const char *substr, const char *replacement); int str_contains(char str[], int size, char ch); char* encode_xml(const char * const xml); +char * prof_getline(FILE *stream); #endif