/******************************************************** * File: scan.c * Created at Sun Jan 28 22:10:32 MSK 2001 by raorn // raorn@binec.ru * SCAN * $Id: scan.c,v 1.9 2002/02/04 22:13:30 raorn Exp $ *******************************************************/ #include "crashecho.h" void LogScanResults(void) { printf("\n"); if (scan_total == 0) LogWrite(2, TOSSINGINFO, "No messages exported"); else if (scan_total == 1) LogWrite(2, TOSSINGINFO, "1 message exported"); else { LogWrite(2, TOSSINGINFO, "%lu messages exported", scan_total); } } bool ScanHandle(struct MemMessage *mm) { uchar buf[50]; ulong oldattr; if (mm->Area[0] == 0) { Print4D(&mm->DestNode, buf, 50); LogWrite(4, TOSSINGINFO, "Exporting message #%lu from \"%s\" to \"%s\" at %s", mm->msgnum, mm->From, mm->To, buf); } else { LogWrite(4, TOSSINGINFO, "Exporting message #%lu from \"%s\" to \"%s\" in %s", mm->msgnum, mm->From, mm->To, mm->Area); } if (config.cfg_Flags & CFG_ADDTID) AddTID(mm); oldattr = mm->Attr; if (HandleMessage(mm, FALSE)) { scan_total++; mm->Attr = oldattr; mm->Changed = TRUE; if (mm->Area[0] == 0) { if ((config.cfg_Flags & CFG_ALLOWKILLSENT) && (mm->Attr & FLAG_KILLSENT)) { LogWrite(2, TOSSINGINFO, "Deleting message with KILLSENT flag"); mm->Deleted = TRUE; } else { mm->Attr |= FLAG_SENT; } } else { mm->Attr |= FLAG_SENT; } return TRUE; } return FALSE; } bool ScanArea(uchar * tagname) { struct Area *area; for (area = (struct Area *) config.AreaList.First; area; area = area->Next) if (stricmp(area->Tagname, tagname) == 0) break; if (area) { if (area->AreaType != AREATYPE_ECHOMAIL && area->AreaType != AREATYPE_NETMAIL) { LogWrite(1, USERERR, "You cannot scan area %s, not an echomail or netmail area", tagname); } else if (!area->Messagebase) { LogWrite(1, USERERR, "You cannot scan area %s, area is pass-through", tagname); } else if (!area->Messagebase->scanfunc) { LogWrite(1, USERERR, "You cannot scan area %s, scanning is not supported for this type of messagebase", tagname); } else { printf("Scanning area %s\n", area->Tagname); return (*area->Messagebase->scanfunc) (area, TRUE, FALSE, 0, NULL, AcceptNotSent, ScanHandle); } } else { LogWrite(1, USERERR, "Unknown area %s", tagname); } return TRUE; } #ifdef MSGBASE_JAM static bool AddJamToList(struct jbList *scanlist, uchar *file) { ulong jbcpos; struct Area *area; struct ScanEntry *tmpscan; struct MsgEntry *tmpmsg; uchar base[200], buf[200], buf2[200]; ulong msgnum; FILE *fh; if ((fh=fopen(file, "rt")) != NULL) { while (fgets(buf2, 200, fh)) { jbcpos = 0; if(!(jbstrcpy(base, buf2, 200, &jbcpos))) /* Skip invalid line */ continue; if(!(jbstrcpy(buf, buf2, 200, &jbcpos))) /* Skip invalid line */ continue; msgnum = atoi(buf); for (area = (struct Area *) config.AreaList.First; area; area = area->Next) if (!stricmp(base, area->Path)) break; if (area) { for (tmpscan = (struct ScanEntry *) scanlist->First; tmpscan; tmpscan = tmpscan->Next) if (tmpscan->area == area) break; if (!tmpscan) { if ((tmpscan = calloc(1, sizeof(struct ScanEntry))) == NULL) { nomem = TRUE; return FALSE; } tmpscan->area = area; jbNewList(&tmpscan->msglist); jbAddNode(scanlist, (struct jbNode *) tmpscan); } if ((tmpmsg = calloc(1, sizeof(struct MsgEntry))) == NULL) { nomem = TRUE; return FALSE; } tmpmsg->num = msgnum; jbAddNode(&tmpscan->msglist, (struct jbNode *) tmpmsg); } } fclose(fh); } return TRUE; } static bool ScanJAMFile(uchar *file) { struct jbList scanlist; struct ScanEntry *tmpscan; jbNewList(&scanlist); if(!AddJamToList(&scanlist, file)) { for (tmpscan = (struct ScanEntry *) scanlist.First; tmpscan; tmpscan = tmpscan->Next) jbFreeList(&tmpscan->msglist); jbFreeList(&scanlist); return FALSE; } for (tmpscan = (struct ScanEntry *) scanlist.First; tmpscan; tmpscan = tmpscan->Next) { if (tmpscan->area->Messagebase && (tmpscan->area->AreaType == AREATYPE_ECHOMAIL || tmpscan->area->AreaType == AREATYPE_NETMAIL)) { if (tmpscan->area->Messagebase->scanfunc) { printf("Scanning area %s\n", tmpscan->area->Tagname); if (!(*tmpscan->area->Messagebase->scanfunc) (tmpscan->area, TRUE, FALSE, 0, (struct jbList *) &tmpscan->msglist, AcceptNotSent, ScanHandle)) { /* FIXME Previous elements already freed */ for (; tmpscan; tmpscan = tmpscan->Next) jbFreeList(&tmpscan->msglist); jbFreeList(&scanlist); return FALSE; } } } jbFreeList(&tmpscan->msglist); } jbFreeList(&scanlist); return TRUE; } #endif bool Scan(bool ignoreflags) { struct Area *area; LogWrite(2, ACTIONINFO, "Scanning areas for messages to export"); #ifdef MSGBASE_JAM if (ignoreflags) { #endif for (area = (struct Area *) config.AreaList.First; area; area = area->Next) if (area->Messagebase && (area->AreaType == AREATYPE_ECHOMAIL || area->AreaType == AREATYPE_NETMAIL)) { if (area->Messagebase->scanfunc) { printf("Scanning area %s\n", area->Tagname); if (!(*area->Messagebase->scanfunc) (area, TRUE, FALSE, 0, NULL, AcceptNotSent, ScanHandle)) { return (FALSE); } } } #ifdef MSGBASE_JAM } else { uchar buf[200]; bool existsany = FALSE; bool existsthis; /* FIXME ``netmail.jam'' looks ugly... Should we define it's name in config? */ MakeFullPath(config.cfg_jam_FlagsDir, "netmail.jam", buf, 200); if ((existsthis = Exists(buf))) { if (!ScanJAMFile(buf)) { return FALSE; } /* FIXME Hmm... */ unlink(buf); } existsany = existsany || existsthis; /* FIXME ``echomail.jam'' looks ugly... Should we define it's name in config? */ MakeFullPath(config.cfg_jam_FlagsDir, "echomail.jam", buf, 200); if ((existsthis = Exists(buf))) { if (!ScanJAMFile(buf)) { return FALSE; } /* FIXME Hmm... */ unlink(buf); } existsany = existsany || existsthis; if (!existsany) { /* Process all areas... */ for (area = (struct Area *) config.AreaList.First; area; area = area->Next) if (area->Messagebase && (area->AreaType == AREATYPE_ECHOMAIL || area->AreaType == AREATYPE_NETMAIL)) { if (area->Messagebase->scanfunc) { printf("Scanning area %s\n", area->Tagname); if (!(*area->Messagebase->scanfunc) (area, TRUE, FALSE, 0, NULL, AcceptNotSent, ScanHandle)) { return (FALSE); } } } } else { /* Process all other (MSG) areas... */ for (area = (struct Area *) config.AreaList.First; area; area = area->Next) if (area->Messagebase && stricmp(area->Messagebase->name, "JAM") && (area->AreaType == AREATYPE_ECHOMAIL || area->AreaType == AREATYPE_NETMAIL)) { if (area->Messagebase->scanfunc) { printf("Scanning area %s\n", area->Tagname); if (!(*area->Messagebase->scanfunc) (area, TRUE, FALSE, 0, NULL, AcceptNotSent, ScanHandle)) { return (FALSE); } } } } } #endif return (TRUE); } bool ScanList(uchar * file) { FILE *fh; uchar buf[100]; if (!(fh = fopen(file, "rt"))) { LogWrite(1, USERERR, "Unable to open %s", file); return (FALSE); } while (fgets(buf, 100, fh)) { if (strlen(buf) > 2) { if (buf[strlen(buf) - 1] < 32) buf[strlen(buf) - 1] = 0; if (!ScanArea(buf)) { fclose(fh); return (FALSE); } } } fclose(fh); return (TRUE); }