Last active
December 15, 2015 19:03
-
-
Save mniip/37ae9e58cbb6e0b625bf to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <time.h> | |
#include <limits.h> | |
#include <string.h> | |
char *channel_path; | |
char *channel_name; | |
int raw; | |
int hosts; | |
char **greplist; | |
size_t *greplistsz; | |
inline char *strappstr(char *dest, const char *s) | |
{ | |
*dest = *s; | |
while(*s) | |
*++dest = *++s; | |
return dest; | |
} | |
#define S strappstr | |
inline char *strappnstr(char *dest, const char *s, size_t sz) | |
{ | |
size_t i; | |
for(i = 0; i < sz; i++) | |
*dest = *s, dest++, s++; | |
*dest = 0; | |
return dest; | |
} | |
#define N strappnstr | |
#define H strappnhtml | |
char *strappnhtml(char *dest, const char *s, size_t sz) | |
{ | |
int fg = -1; | |
int bg = -1; | |
int italic = 0; | |
int bold = 0; | |
int underline = 0; | |
size_t i; | |
for(i = 0; i < sz; ) | |
{ | |
int protocol = 0; | |
if(!strncmp(s, "http://", 7)) | |
protocol = 7; | |
else if(!strncmp(s, "https://", 8)) | |
protocol = 8; | |
else if(!strncmp(s, "ftp://", 6)) | |
protocol = 6; | |
else if(!strncmp(s, "ptsave:", 7)) | |
protocol = 7; | |
if(protocol && i + protocol < sz) | |
{ | |
const char *start = s; | |
s += protocol; | |
i += protocol; | |
while(*s && *s != ' ' && *s != '"' && i < sz) | |
{ | |
s++; i++; | |
} | |
dest = N(H(N(N(N(N(dest, "<a href=\"", 9), start, s - start), "\">", 2), start, protocol), start + protocol, s - start - protocol), "</a>", 4); | |
continue; | |
} | |
switch(*s) | |
{ | |
case '\x02': | |
if(italic) | |
dest = N(dest, "</i>", 4); | |
if(underline) | |
dest = N(dest, "</u>", 4); | |
if(bold) | |
dest = N(dest, "</b>", 4); | |
else | |
dest = N(dest, "<b>", 3); | |
if(underline) | |
dest = N(dest, "<u>", 3); | |
if(italic) | |
dest = N(dest, "<i>", 3); | |
bold = !bold; | |
s++; i++; | |
break; | |
case '\x03': | |
s++; i++; | |
if(*s >= '0' && *s <= '9') | |
{ | |
if(italic) | |
dest = N(dest, "</i>", 4); | |
if(underline) | |
dest = N(dest, "</u>", 4); | |
if(bold) | |
dest = N(dest, "</b>", 4); | |
if(bg != -1 || fg != -1) | |
dest = N(dest, "</span>", 7); | |
fg = *s - '0'; | |
s++; i++; | |
if(*s >='0' && *s <= '9') | |
{ | |
fg = fg * 10 + (*s - '0'); | |
s++; i++; | |
if(*s == ',' && s[1] >= '0' && s[1] <= '9') | |
{ | |
s++; i++; | |
bg = *s - '0'; | |
s++; i++; | |
if(*s >='0' && *s <= '9') | |
{ | |
bg = bg * 10 + (*s - '0'); | |
s++; i++; | |
} | |
} | |
} | |
else | |
if(*s == ',' && s[1] >= '0' && s[1] <= '9') | |
{ | |
s++; i++; | |
bg = *s - '0'; | |
s++; i++; | |
if(*s >='0' && *s <= '9') | |
{ | |
bg = bg * 10 + (*s - '0'); | |
s++; i++; | |
} | |
} | |
char buffg[2]; | |
if(fg == -2) | |
{ | |
buffg[0] = 'r'; | |
buffg[1] = 'v'; | |
} | |
else | |
{ | |
buffg[0] = fg / 10 + '0'; | |
buffg[1] = fg % 10 + '0'; | |
} | |
char bufbg[2]; | |
if(bg == -2) | |
{ | |
bufbg[0] = 'r'; | |
bufbg[1] = 'v'; | |
} | |
else | |
{ | |
bufbg[0] = bg / 10 + '0'; | |
bufbg[1] = bg % 10 + '0'; | |
} | |
if(fg != -1) | |
if(bg != -1) | |
dest = N(N(N(N(N(dest, "<span class=\"f", 14), buffg, 2), " b", 2), bufbg, 2), "\">", 2); | |
else | |
dest = N(N(N(dest, "<span class=\"f", 14), buffg, 2), "\">", 2); | |
else | |
if(bg != -1) | |
dest = N(N(N(dest, "<span class=\"b", 14), bufbg, 2), "\">", 2); | |
if(bold) | |
dest = N(dest, "<b>", 3); | |
if(underline) | |
dest = N(dest, "<u>", 3); | |
if(italic) | |
dest = N(dest, "<i>", 3); | |
} | |
else | |
{ | |
if(italic) | |
dest = N(dest, "</i>", 4); | |
if(underline) | |
dest = N(dest, "</u>", 4); | |
if(bold) | |
dest = N(dest, "</b>", 4); | |
if(fg != -1 || bg != -1) | |
{ | |
dest = N(dest, "</span>", 7); | |
} | |
if(bold) | |
dest = N(dest, "<b>", 3); | |
if(underline) | |
dest = N(dest, "<u>", 3); | |
if(italic) | |
dest = N(dest, "<i>", 3); | |
fg = bg = -1; | |
} | |
break; | |
case '\x0F': | |
if(italic) | |
dest = N(dest, "</i>", 4); | |
if(underline) | |
dest = N(dest, "</u>", 4); | |
if(bold) | |
dest = N(dest, "</b>", 4); | |
if(bg != -1 || fg != -1) | |
dest = N(dest, "</span>", 7); | |
bold = underline = italic = 0; | |
fg = bg = -1; | |
s++; i++; | |
break; | |
case '\x16': | |
if(italic) | |
dest = N(dest, "</i>", 4); | |
if(underline) | |
dest = N(dest, "</u>", 4); | |
if(bold) | |
dest = N(dest, "</b>", 4); | |
if(bg != -1 || fg != -1) | |
dest = N(dest, "</span>", 7); | |
if(bg == -1) | |
bg = -2; | |
else if(bg == -2) | |
bg = -1; | |
if(fg == -1) | |
fg = -2; | |
else if(fg == -2) | |
fg = -1; | |
int tmp = bg; | |
bg = fg; | |
fg = tmp; | |
char buffg[2]; | |
if(fg == -2) | |
{ | |
buffg[0] = 'r'; | |
buffg[1] = 'v'; | |
} | |
else | |
{ | |
buffg[0] = fg / 10 + '0'; | |
buffg[1] = fg % 10 + '0'; | |
} | |
char bufbg[2]; | |
if(bg == -2) | |
{ | |
bufbg[0] = 'r'; | |
bufbg[1] = 'v'; | |
} | |
else | |
{ | |
bufbg[0] = bg / 10 + '0'; | |
bufbg[1] = bg % 10 + '0'; | |
} | |
if(fg != -1) | |
if(bg != -1) | |
dest = N(N(N(N(N(dest, "<span class=\"f", 14), buffg, 2), " b", 2), bufbg, 2), "\">", 2); | |
else | |
dest = N(N(N(dest, "<span class=\"f", 14), buffg, 2), "\">", 2); | |
else | |
if(bg != -1) | |
dest = N(N(N(dest, "<span class=\"b", 14), bufbg, 2), "\">", 2); | |
if(bold) | |
dest = N(dest, "<b>", 3); | |
if(underline) | |
dest = N(dest, "<u>", 3); | |
if(italic) | |
dest = N(dest, "<i>", 3); | |
s++; i++; | |
break; | |
case '\x1D': | |
if(italic) | |
dest = N(dest, "</i>", 4); | |
else | |
dest = N(dest, "<i>", 3); | |
italic = !italic; | |
s++; i++; | |
break; | |
case '\x1F': | |
if(italic) | |
dest = N(dest, "</i>", 4); | |
if(underline) | |
dest = N(dest, "</u>", 4); | |
else | |
dest = N(dest, "<u>", 3); | |
if(italic) | |
dest = N(dest, "<i>", 3); | |
underline = !underline; | |
s++; i++; | |
break; | |
case '&': dest = N(dest, "&", 5); s++; i++; break; | |
case '<': dest = N(dest, "<", 4); s++; i++; break; | |
case '>': dest = N(dest, ">", 4); s++; i++; break; | |
default: *dest = *s; dest++; s++; i++; break; | |
} | |
} | |
if(italic) | |
dest = N(dest, "</i>", 4); | |
if(underline) | |
dest = N(dest, "</u>", 4); | |
if(bold) | |
dest = N(dest, "</b>", 4); | |
if(bg != -1 || fg != -1) | |
dest = N(dest, "</span>", 7); | |
*dest = 0; | |
return dest; | |
} | |
char *strappnplain(char *dest, const char *s, size_t sz) | |
{ | |
size_t i; | |
for(i = 0; i < sz; i++) | |
switch(*s) | |
{ | |
case '\x03': | |
s++; | |
if(*s < '0' || *s > '9') | |
break; | |
s++; | |
if(*s < '0' || *s > '9') | |
break; | |
s++; | |
if(*s != ',' || s[1] < '0' || s[1] > '9') | |
break; | |
s += 2; | |
if(*s < '0' || *s > '9') | |
break; | |
s++; | |
break; | |
case '\x02': case '\x0F': case '\x16': case '\x1F': | |
s++; | |
break; | |
default: | |
*dest = *s; | |
dest++; s++; | |
break; | |
} | |
*dest = 0; | |
return dest; | |
} | |
#define P strappnplain | |
inline int grep(const char *s, size_t sz) | |
{ | |
const char **g = greplist; | |
if(!g) | |
return 1; | |
const size_t *gs = greplistsz; | |
while(*g) | |
if(sz == *gs && !strncasecmp(s, *g, sz)) | |
return 1; | |
else | |
g++, gs++; | |
return 0; | |
} | |
void output(const char *line) | |
{ | |
fputs(line, stdout); | |
if(raw) | |
putchar('\n'); | |
} | |
char *renderTS(char *dest, const struct tm *t) | |
{ | |
dest[0] = t->tm_hour / 10 + '0'; | |
dest[1] = t->tm_hour % 10 + '0'; | |
dest[2] = ':'; | |
dest[3] = t->tm_min / 10 + '0'; | |
dest[4] = t->tm_min % 10 + '0'; | |
dest[5] = ':'; | |
dest[6] = t->tm_sec / 10 + '0'; | |
dest[7] = t->tm_sec % 10 + '0'; | |
return dest + 8; | |
} | |
char *renderTSDate(char *dest, const struct tm *t) | |
{ | |
dest[0] = (t->tm_year + 1900) / 1000 + '0'; | |
dest[1] = (t->tm_year + 900) / 100 % 10 + '0'; | |
dest[2] = t->tm_year / 10 % 10 + '0'; | |
dest[3] = t->tm_year % 10 + '0'; | |
dest[4] = '.'; | |
dest[5] = (t->tm_mon + 1) / 10 + '0'; | |
dest[6] = (t->tm_mon + 1) % 10 + '0'; | |
dest[7] = '.'; | |
dest[8] = t->tm_mday / 10 + '0'; | |
dest[9] = t->tm_mday % 10 + '0'; | |
return dest + 10; | |
} | |
void processLine(const struct tm *t, const char *line) | |
{ | |
char rbuffer[65536]; | |
char *buffer; | |
if(raw) | |
buffer = N(renderTS(N(rbuffer, "[", 1), t), "] ", 2); | |
else | |
buffer = N(renderTS(N(renderTSDate(N(rbuffer, "<span class=\"t\" data-date=\"", 27), t), "\" >[", 4), t), "]</span> ", 9); | |
int filter = 0; | |
// [00:00:00] *** | |
// [00:00:00] * nickname | |
// [00:00:00] -nickname- | |
// [00:00:00] <nickname> | |
// 0123456789012 | |
if(line[11] == '*') | |
if(line[12] == '*') | |
// [00:00:00] *** Quits: | |
// [00:00:00] *** Parts: | |
// [00:00:00] *** Joins: | |
// [00:00:00] *** nickname is now known as | |
// [00:00:00] *** nickname sets mode: | |
// [00:00:00] *** nickname was kicked by | |
// [00:00:00] *** nickname changes topic to | |
// 012345678901234567890 | |
// 01 | |
if(line[20] == ':') | |
switch(line[15]) | |
{ | |
case 'Q': | |
{ | |
// [00:00:00] *** Quits: nickname (host) (reason) | |
// 01234567890123456789012 | |
// 012 | |
// 0123 | |
// -10 | |
const char *nickname = line + 22; | |
const char *nickend = strchr(nickname, ' '); | |
const char *host = nickend + 2; | |
const char *hostend = strchr(host, ')'); | |
const char *reason = hostend + 3; | |
const char *reasonend = reason + strlen(reason) - 1; | |
if(grep(nickname, nickend - nickname)) | |
{ | |
filter = 1; | |
if(raw) | |
if(hosts) | |
N(P(N(N(N(N(N(buffer, "*** ", 4), nickname, nickend - nickname), " (", 2), host, hostend - host), ") has quit (", 12), reason, reasonend - reason), ")", 1); | |
else | |
N(P(N(N(N(buffer, "*** ", 4), nickname, nickend - nickname), " has quit (", 11), reason, reasonend - reason), ")", 1); | |
else | |
if(hosts) | |
N(H(N(N(N(N(N(buffer, "<span class=\"q\">*** ", 20), nickname, nickend - nickname), " (", 2), host, hostend - host), ") has quit (", 12), reason, reasonend - reason), ")</span><br />", 14); | |
else | |
N(H(N(N(N(buffer, "<span class=\"q\">*** ", 20), nickname, nickend - nickname), " has quit (", 11), reason, reasonend - reason), ")</span><br />", 14); | |
} | |
break; | |
} | |
case 'P': | |
{ | |
// [00:00:00] *** Parts: nickname (host) (reason) | |
// 01234567890123456789012 | |
// -1012 | |
// -10123 | |
// -10 | |
const char *nickname = line + 22; | |
const char *nickend = strchr(nickname, ' '); | |
const char *host = nickend + 2; | |
const char *hostend = strchr(host, ')'); | |
const char *reason = hostend + 3; | |
const char *reasonend = reason + strlen(reason) - 1; | |
if(grep(nickname, nickend - nickname)) | |
{ | |
filter = 1; | |
if(raw) | |
if(hosts) | |
N(P(N(S(N(N(N(N(N(buffer, "*** ", 4), nickname, nickend - nickname), " (", 2), host, hostend - host), ") has left ", 11), channel_name), " (", 2), reason, reasonend - reason), ")", 1); | |
else | |
N(P(N(S(N(N(N(buffer, "*** ", 4), nickname, nickend - nickname), " has left ", 10), channel_name), " (", 2), reason, reasonend - reason), ")", 1); | |
else | |
if(hosts) | |
N(H(N(S(N(N(N(N(N(buffer, "<span class=\"l\">*** ", 20), nickname, nickend - nickname), " (", 2), host, hostend - host), ") has left ", 11), channel_name), " (", 2), reason, reasonend - reason), ")</span><br />", 14); | |
else | |
N(H(N(S(N(N(N(buffer, "<span class=\"l\">*** ", 20), nickname, nickend - nickname), " has left ", 10), channel_name), " (", 2), reason, reasonend - reason), ")</span><br />", 14); | |
} | |
break; | |
} | |
case 'J': | |
{ | |
// [00:00:00] *** Joins: nickname (host) | |
// 01234567890123456789012 | |
// -1012 | |
// -10 | |
const char *nickname = line + 22; | |
const char *nickend = strchr(nickname, ' '); | |
const char *host = nickend + 2; | |
const char *hostend = host + strlen(host) - 1; | |
if(grep(nickname, nickend - nickname)) | |
{ | |
filter = 1; | |
if(raw) | |
if(hosts) | |
S(N(N(N(N(N(buffer, "*** ", 4), nickname, nickend - nickname), " (", 2), host, hostend - host), ") has joined ", 13), channel_name); | |
else | |
S(N(N(N(buffer, "*** ", 4), nickname, nickend - nickname), " has joined ", 12), channel_name); | |
else | |
if(hosts) | |
N(S(N(N(N(N(N(buffer, "<span class=\"j\">*** ", 20), nickname, nickend - nickname), " (", 2), host, hostend - host), ") has joined ", 13), channel_name), "</span><br />", 13); | |
else | |
N(S(N(N(N(buffer, "<span class=\"j\">*** ", 20), nickname, nickend - nickname), " has joined ", 12), channel_name), "</span><br />", 13); | |
} | |
break; | |
} | |
} | |
else | |
{ | |
const char *nickname = line + 15; | |
const char *nickend = strchr(nickname, ' '); | |
switch(nickend[1]) | |
{ | |
case 'i': | |
{ | |
// [00:00:00] *** nickname is now known as nickname | |
// 012345678901234567 | |
const char *newnick = nickend + 17; | |
if(grep(nickname, nickend - nickname) || grep(newnick, strlen(newnick))) | |
{ | |
filter = 1; | |
if(raw) | |
S(N(N(N(buffer, "*** ", 4), nickname, nickend - nickname), " has changed nick to ", 21), newnick); | |
else | |
N(S(N(N(N(buffer, "<span class=\"z\">*** ", 20), nickname, nickend - nickname), " has changed nick to ", 21), newnick), "</span><br />", 13); | |
} | |
break; | |
} | |
case 's': | |
{ | |
// [00:00:00] *** nickname sets mode: +mode | |
// 0123456789012 | |
const char *mode = nickend + 12; | |
if(grep(nickname, nickend - nickname)) | |
{ | |
filter = 1; | |
if(raw) | |
S(N(S(N(N(N(buffer, "*** ", 4), nickname, nickend - nickname), " set mode ", 10), mode), " on ", 4), channel_name); | |
else | |
N(S(N(S(N(N(N(buffer, "<span class=\"m\">*** ", 20), nickname, nickend - nickname), " set mode <span class=\"r\">", 26), mode), "</span> on ", 11), channel_name), "</span><br />", 13); | |
} | |
break; | |
} | |
case 'w': | |
{ | |
// [00:00:00] *** nickname was kicked by nickname (reason) | |
// 0123456789012345 | |
// 012 | |
// -10 | |
const char *kicker = nickend + 15; | |
const char *kickerend = strchr(kicker, ' '); | |
const char *reason = kickerend + 2; | |
const char *reasonend = reason + strlen(reason) - 1; | |
if(grep(kicker, kickerend - kicker) || grep(nickname, nickend - nickname)) | |
{ | |
filter = 1; | |
if(raw) | |
N(P(N(S(N(N(N(N(N(buffer, "*** ", 4), nickname, nickend - nickname), " was kicked by ", 15), kicker, kickerend - kicker), " from ", 6), channel_name), " (", 2), reason, reasonend - reason), ")", 1); | |
else | |
N(H(N(S(N(N(N(N(N(buffer, "<span class=\"k\">*** ", 20), nickname, nickend - nickname), " was kicked by ", 15), kicker, kickerend - kicker), " from ", 6), channel_name), " (", 2), reason, reasonend - reason), ")</span><br />", 14); | |
} | |
break; | |
} | |
case 'c': | |
{ | |
// [00:00:00] *** nickname changes topic to 'topic' | |
// 01234567890123456789 | |
// -10 | |
const char *topic = nickend + 19; | |
const char *topicend = topic + strlen(topic) - 1; | |
if(grep(nickname, nickend - nickname)) | |
{ | |
filter = 1; | |
if(raw) | |
P(N(S(N(N(N(buffer, "*** ", 4), nickname, nickend - nickname), " has changed topic of ", 22), channel_name), " to: ", 5), topic, topicend - topic); | |
else | |
N(H(N(S(N(N(N(buffer, "<span class=\"h\">*** ", 20), nickname, nickend - nickname), " has changed topic of ", 22), channel_name), " to: <span class=\"r\">", 21), topic, topicend - topic), "</span></span><br />", 20); | |
} | |
break; | |
} | |
} | |
} | |
else | |
{ | |
// [00:00:00] * nickname Text | |
// 01234567890123 | |
// 01 | |
const char *nickname = line + 13; | |
const char *nickend = strchr(nickname, ' '); | |
const char *text = nickend + 1; | |
if(grep(nickname, nickend - nickname)) | |
{ | |
filter = 1; | |
if(raw) | |
P(N(N(N(buffer, "* ", 2), nickname, nickend - nickname), " ", 1), text, strlen(text)); | |
else | |
N(H(N(N(N(buffer, "<span class=\"a\">* ", 18), nickname, nickend - nickname), " ", 1), text, strlen(text)), "</span><br />", 13); | |
} | |
} | |
else if (line[11] == '-') | |
{ | |
// [00:00:00] -nickname- Text | |
// 0123456789012 | |
// 012 | |
const char *nickname = line + 12; | |
const char *nickend = strchr(nickname, ' ') - 1; | |
const char *text = nickend + 2; | |
if(grep(nickname, nickend - nickname)) | |
{ | |
filter = 1; | |
if(raw) | |
P(N(N(N(buffer, "--", 2), nickname, nickend - nickname), "-- ", 3), text, strlen(text)); | |
else | |
N(H(N(N(N(buffer, "<span class=\"b\">--", 18), nickname, nickend - nickname), "--</span> ", 10), text, strlen(text)), "<br />", 6); | |
} | |
} | |
else | |
{ | |
// [00:00:00] <nickname> Text | |
// 0123456789012 | |
// 012 | |
const char *nickname = line + 12; | |
const char *nickend = strchr(nickname, '>'); | |
const char *text = nickend + 2; | |
if(grep(nickname, nickend - nickname)) | |
{ | |
filter = 1; | |
if(raw) | |
P(N(N(N(buffer, "<", 1), nickname, nickend - nickname), "> ", 2), text, strlen(text)); | |
else | |
N(H(N(N(N(buffer, "<span class=\"b\"><", 20), nickname, nickend - nickname), "></span> ", 12), text, strlen(text)), "<br />", 6); | |
} | |
} | |
if(filter) | |
output(rbuffer); | |
} | |
static char fn[PATH_MAX]; | |
const char *makeFilename(const struct tm *v) | |
{ | |
strcpy(fn, channel_path); | |
ssize_t base = strlen(channel_path) - 1; | |
char *p = fn + base; | |
*++p = (v->tm_year + 1900) / 1000 + '0'; | |
*++p = (v->tm_year + 900) / 100 % 10 + '0'; | |
*++p = v->tm_year / 10 % 10 + '0'; | |
*++p = v->tm_year % 10 + '0'; | |
*++p = (v->tm_mon + 1) / 10 % 10 + '0'; | |
*++p = (v->tm_mon + 1) % 10 + '0'; | |
*++p = v->tm_mday / 10 % 10 + '0'; | |
*++p = v->tm_mday % 10 + '0'; | |
*++p = '.'; *++p = 'l'; *++p = 'o'; *++p = 'g'; | |
return fn; | |
} | |
inline int checkTSAbove(const struct tm *v, const struct tm *H) | |
{ | |
if(v->tm_hour > H->tm_hour) return 1; | |
if(v->tm_hour < H->tm_hour) return 0; | |
if(v->tm_min > H->tm_min) return 1; | |
if(v->tm_min < H->tm_min) return 0; | |
if(v->tm_sec >= H->tm_sec) return 1; | |
return 0; | |
} | |
inline int checkTSBelow(const struct tm *v, const struct tm *t) | |
{ | |
if(v->tm_hour > t->tm_hour) return 0; | |
if(v->tm_hour < t->tm_hour) return 1; | |
if(v->tm_min > t->tm_min) return 0; | |
if(v->tm_min < t->tm_min) return 1; | |
if(v->tm_sec > t->tm_sec) return 0; | |
return 1; | |
} | |
static struct tm t; | |
const struct tm *mergeTS(const char *line, const struct tm *T) | |
{ | |
// [00:00:00 | |
// 012345678 | |
int hour = (line[1] - '0') * 10 + (line[2] - '0'); | |
int minute = (line[4] - '0') * 10 + (line[5] - '0'); | |
int second = (line[7] - '0') * 10 + (line[8] - '0'); | |
t.tm_year = T->tm_year; | |
t.tm_mon = T->tm_mon; | |
t.tm_mday = T->tm_mday; | |
t.tm_hour = hour; | |
t.tm_min = minute; | |
t.tm_sec = second; | |
return &t; | |
} | |
inline void processFile(const char *name, const struct tm *H) | |
{ | |
FILE *f = fopen(name, "r"); | |
if(f) | |
{ | |
char *line = NULL; | |
size_t len = 0; | |
ssize_t read; | |
while(0 < (read = getline(&line, &len, f))) | |
{ | |
line[read - 1] = 0; | |
processLine(mergeTS(line, H), line); | |
} | |
free(line); | |
fclose(f); | |
} | |
} | |
inline void processFileH(const char *name, const struct tm *H) | |
{ | |
FILE *f = fopen(name, "r"); | |
if(f) | |
{ | |
char *line = NULL; | |
size_t len = 0; | |
ssize_t read; | |
while(0 < (read = getline(&line, &len, f))) | |
{ | |
const struct tm *v = mergeTS(line, H); | |
if(checkTSAbove(v, H)) | |
{ | |
line[read - 1] = 0; | |
processLine(v, line); | |
break; | |
} | |
} | |
while(0 < (read = getline(&line, &len, f))) | |
{ | |
line[read - 1] = 0; | |
processLine(mergeTS(line, H), line); | |
} | |
free(line); | |
fclose(f); | |
} | |
} | |
inline void processFileT(const char *name, const struct tm *T) | |
{ | |
FILE *f = fopen(name, "r"); | |
if(f) | |
{ | |
char *line = NULL; | |
size_t len = 0; | |
ssize_t read; | |
while(0 < (read = getline(&line, &len, f))) | |
{ | |
const struct tm *v = mergeTS(line, T); | |
if(!checkTSBelow(v, T)) | |
break; | |
line[read - 1] = 0; | |
processLine(v, line); | |
} | |
free(line); | |
fclose(f); | |
} | |
} | |
inline void processFileHT(const char *name, const struct tm *H, const struct tm *T) | |
{ | |
FILE *f = fopen(name, "r"); | |
if(f) | |
{ | |
char *line = NULL; | |
size_t len = 0; | |
ssize_t read; | |
while(0 < (read = getline(&line, &len, f))) | |
{ | |
const struct tm *v = mergeTS(line, H); | |
if(checkTSAbove(v, H)) | |
{ | |
line[read - 1] = 0; | |
processLine(v, line); | |
break; | |
} | |
} | |
while(0 < (read = getline(&line, &len, f))) | |
{ | |
const struct tm *v = mergeTS(line, T); | |
if(!checkTSBelow(v, T)) | |
break; | |
line[read - 1] = 0; | |
processLine(v, line); | |
} | |
free(line); | |
fclose(f); | |
} | |
} | |
void process(const struct tm *H, const struct tm *T) | |
{ | |
if(H->tm_mday == T->tm_mday && H->tm_mon == T->tm_mon && H->tm_year == T->tm_year) | |
processFileHT(makeFilename(H), H, T); | |
else | |
{ | |
processFileH(makeFilename(H), H); | |
struct tm v = *H; | |
v.tm_mday++; | |
mktime(&v); | |
while(v.tm_mday != T->tm_mday || v.tm_mon != T->tm_mon || v.tm_year != T->tm_year) | |
{ | |
processFile(makeFilename(&v), &v); | |
v.tm_mday++; | |
mktime(&v); | |
} | |
processFileT(makeFilename(T), T); | |
} | |
} | |
int main(int argc, char *argv[]) | |
{ | |
channel_path = malloc(PATH_MAX); | |
strcpy(channel_path, "/var/log/irc/freenode/"); | |
strcat(channel_path, argv[1]); | |
strcat(channel_path, "/"); | |
channel_name = malloc(120); | |
strcpy(channel_name, argv[1]); | |
if(*argv[4]) | |
{ | |
greplist = malloc(128 * sizeof(char *)); | |
greplistsz = malloc(128 * sizeof(size_t)); | |
int n = 0; | |
char *list = argv[4]; | |
do | |
{ | |
greplist[n] = strsep(&list, ","); | |
if(greplist[n]) | |
greplistsz[n] = strlen(greplist[n]); | |
n++; | |
} | |
while(list); | |
} | |
else | |
greplist = NULL; | |
time_t tH = atoll(argv[2]), tT = atoll(argv[3]); | |
if(tH > tT) | |
return 0; | |
raw = strchr(argv[5], 'r') ? 1 : 0; | |
hosts = strchr(argv[5], 'h') ? 1 : 0; | |
struct tm H = *gmtime(&tH), T = *gmtime(&tT); | |
process(&H, &T); | |
free(channel_path); | |
free(channel_name); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment