TOList *next;
};
+#define MatchTypeQID 1
+#define MatchTypeRelLineNr 2
+
+typedef struct _MatchList MatchList;
+struct _MatchList {
+ unsigned int mtype;
+ char *id;
+ time_t ltime;
+ unsigned long rel_line_nr;
+ MatchList *next;
+};
+
#ifdef DEBUG
GHashTable *smtpd_debug_alloc;
GHashTable *qmgr_debug_alloc;
time_t start;
time_t end;
time_t ctime;
+ MatchList *match_list;
char *server;
char *msgid;
- char *qid;
char *strmatch;
unsigned long limit;
unsigned long count;
char *connect;
+ // time,rel_line_nr is used as cursor/ID
+ time_t ltime;
+ unsigned long rel_line_nr;
+
//unsigned int external:1; // not from local host
unsigned int disconnect:1;
unsigned int strmatch:1;
void loglist_print (LogList *loglist);
void loglist_add (EPool *ep, LogList *loglist, const char *text, int len, unsigned long linenr);
-SEntry *sentry_new (int pid);
-SEntry *sentry_get (LParser *parser, int pid);
+SEntry *sentry_new (int pid, time_t ltime, unsigned long rel_line_nr);
+SEntry *sentry_get (LParser *parser, int pid, time_t ltime, unsigned long rel_line_nr);
void sentry_ref_add (SEntry *sentry, QEntry *qentry);
int sentry_ref_del (SEntry *sentry, QEntry *qentry);
void sentry_ref_finalize (LParser *parser, SEntry *sentry);
}
SEntry*
-sentry_new (int pid)
+sentry_new (int pid, time_t ltime, unsigned long rel_line_nr)
{
SEntry *sentry;
SList *blocks;
sentry = (SEntry *)g_slice_alloc0(EPOOL_BLOCK_SIZE);
sentry->pid = pid;
+ sentry->ltime = ltime;
+ sentry->rel_line_nr = rel_line_nr;
#ifdef EPOOL_DEBUG
sentry->ep.allocated += EPOOL_BLOCK_SIZE;
}
SEntry *
-sentry_get (LParser *parser, int pid)
+sentry_get (LParser *parser, int pid, time_t ltime, unsigned long rel_line_nr)
{
SEntry *sentry;
return sentry;
} else {
- if ((sentry = sentry_new (pid))) {
+ if ((sentry = sentry_new (pid, ltime, rel_line_nr))) {
g_hash_table_insert (parser->smtpd_h, &sentry->pid, sentry);
}
{
NQList *nq;
- if (parser->msgid || parser->qid) return;
+ if (parser->msgid) return;
if (parser->server) {
if (!sentry->connect) return;
if (!strcasestr (sentry->connect, parser->server)) return;
}
+ MatchList *match = parser->match_list;
+ if (match) {
+ int found = 0;
+ while(match) {
+ if (match->mtype == MatchTypeQID) {
+ return;
+ } else if (match->mtype == MatchTypeRelLineNr) {
+ if (match->ltime == sentry->ltime && match->rel_line_nr == sentry->rel_line_nr) {
+ found = 1;
+ break;
+ }
+ } else {
+ g_error("implement me");
+ }
+ match = match->next;
+ }
+ if (!found) return;
+ }
+
if (parser->from || parser->to ||
parser->exclude_greylist || parser->exclude_ndrs) {
nq = sentry->nqlist;
nq = sentry->nqlist;
while (nq) {
if (nq->from && nq->to && nq->dstatus) {
- printf ("TO:%08lX:00000000000:%c: from <%s> to <%s>\n", nq->ltime, nq->dstatus, nq->from, nq->to);
+ printf ("TO:%08lX:T%08lXL%08lX:%c: from <%s> to <%s>\n", nq->ltime,
+ sentry->ltime, sentry->rel_line_nr, nq->dstatus,
+ nq->from, nq->to);
parser->count++;
}
nq = nq->next;
if (strcasecmp (parser->msgid, qentry->msgid)) return;
}
- if (parser->qid) {
+ MatchList *match = parser->match_list;
+ if (match) {
int found = 0;
- if (fe && !strcmp (fe->logid, parser->qid)) found = 1;
- if (!strcmp (qentry->qid, parser->qid)) found = 1;
-
- if (!found) return;
+ while(match) {
+ if (match->mtype == MatchTypeQID) {
+ if ((fe && !strcmp (fe->logid, match->id)) ||
+ (!strcmp (qentry->qid, match->id))) {
+ found = 1;
+ break;
+ }
+ } else if (match->mtype == MatchTypeRelLineNr) {
+ if (se && match->ltime == se->ltime && match->rel_line_nr == se->rel_line_nr) {
+ found = 1;
+ break;
+ }
+ } else {
+ g_error("implement me");
+ }
+ match = match->next;
+ }
+ if (!found) return;
}
if (parser->server) {
// parse month
int csum = (line[0]<<16) + (line[1]<<8) + line[2];
-
+
switch (csum) {
case 4874606: mon = 0; break;
case 4613474: mon = 1; break;
int found = 0;
int csum_prog;
unsigned long lines = 0;
+ unsigned long rel_line_nr = 0;
char qidbuf[30];
int i;
struct tm *ltime;
struct timeval tv;
- time_t ctime, start, end;
+ time_t ctime, next_ctime, start, end;
LParser *parser;
int opt;
} else if (opt == 'm') {
parser->msgid = epool_strdup (&parser->ep, optarg);
} else if (opt == 'q') {
- parser->qid = epool_strdup (&parser->ep, optarg);
+ time_t ltime;
+ unsigned long rel_line_nr;
+ MatchList *match = (MatchList *)epool_alloc(&parser->ep, sizeof(MatchList));
+ if (sscanf(optarg, "T%08lXL%08lX", <ime, &rel_line_nr) == 2) {
+ match->mtype = MatchTypeRelLineNr;
+ match->ltime = ltime;
+ match->rel_line_nr = rel_line_nr;
+ match->next = parser->match_list;
+ parser->match_list = match;
+ } else {
+ match->mtype = MatchTypeQID;
+ match->id = epool_strdup(&parser->ep, optarg);
+ match->next = parser->match_list;
+ parser->match_list = match;
+ }
} else if (opt == 'x') {
parser->strmatch = epool_strdup (&parser->ep, optarg);
} else if (opt == 'l') {
if (parser->to) printf ("# Recipient: %s\n", parser->to);
if (parser->server) printf ("# Server: %s\n", parser->server);
if (parser->msgid) printf ("# MsgID: %s\n", parser->msgid);
- if (parser->qid) printf ("# QID: %s\n", parser->qid);
+
+ MatchList *match = parser->match_list;
+ while (match) {
+ if (match->mtype == MatchTypeQID) {
+ printf ("# QID: %s\n", match->id);
+ } else if (match->mtype == MatchTypeRelLineNr) {
+ printf ("# QID: T%08lXL%08lX\n", match->ltime, match->rel_line_nr);
+ } else {
+ g_error("internal error - unknown match type %d\n", match->mtype);
+ }
+ match = match->next;
+ }
+
if (parser->strmatch) printf ("# Match: %s\n", parser->strmatch);
strftime (linebuf, 256, "%F %T", gmtime (&parser->start));
int pid = 0;
cpos = line;
- if (!(ctime = parse_time (&cpos, len))) {
+
+ next_ctime = parse_time (&cpos, len);
+
+ if (!next_ctime) {
continue;
- }
+ }
+
+ if (next_ctime != ctime) {
+ rel_line_nr = 0;
+ } else {
+ rel_line_nr++;
+ }
+
+ ctime = next_ctime;
if (ctime < start) continue;
if (ctime > end) break;
if (*cpos != '>') continue;
- if (!(se = sentry_get (parser, pid))) {
+ if (!(se = sentry_get (parser, pid, ctime, rel_line_nr))) {
continue;
}
continue;
}
- if (!(se = sentry_get (parser, pid))) {
+ if (!(se = sentry_get (parser, pid, ctime, rel_line_nr))) {
continue;
}