diff --git a/mbfido/Makefile b/mbfido/Makefile index e835c956..fce06cc2 100644 --- a/mbfido/Makefile +++ b/mbfido/Makefile @@ -138,7 +138,7 @@ backalias.o: ../lib/libs.h ../lib/structs.h ../lib/common.h ../lib/clcomm.h ../l flock.o: ../lib/libs.h ../lib/clcomm.h flock.h hatch.o: ../lib/libs.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/common.h ../lib/clcomm.h ../lib/dbtic.h utic.h rollover.h hatch.h mbdiff.o: ../lib/libs.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/common.h ../lib/clcomm.h ../lib/dbcfg.h mbdiff.h -mgrutil.o: ../lib/libs.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/common.h ../lib/clcomm.h ../lib/dbnode.h sendmail.h mgrutil.h +mgrutil.o: ../lib/libs.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/common.h ../lib/clcomm.h ../lib/dbnode.h sendmail.h rollover.h addpkt.h mgrutil.h pack.o: ../lib/libs.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/common.h ../lib/dbftn.h ../lib/clcomm.h ../lib/dbnode.h pack.h ptic.o: ../lib/libs.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/common.h ../lib/dbtic.h ../lib/clcomm.h ../lib/dbnode.h ../lib/dbdupe.h ulock.h mover.h toberep.h tic.h utic.h addbbs.h magic.h forward.h rollover.h ptic.h magic.h virscan.h sendmail.o: ../lib/libs.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/common.h ../lib/dbnode.h ../lib/clcomm.h ../lib/dbmsgs.h addpkt.h rollover.h sendmail.h diff --git a/mbfido/areamgr.c b/mbfido/areamgr.c index 324cccb7..d078183e 100644 --- a/mbfido/areamgr.c +++ b/mbfido/areamgr.c @@ -765,10 +765,12 @@ void A_Disconnect(faddr *t, char *Area, FILE *tmp) void A_Connect(faddr *, char *, FILE *); void A_Connect(faddr *t, char *Area, FILE *tmp) { - int i, First; - char *Group; + int i, First, rc = 0; + long offset; + char *Group, *temp, *buf, *desc, *p, *tag; faddr *b; sysconnect Sys; + FILE *gp, *mp, *ap; Syslog('+', "AreaMgr: \"%s\"", printable(Area, 0)); @@ -778,16 +780,156 @@ void A_Connect(faddr *t, char *Area, FILE *tmp) Area[i]=toupper(Area[i]); if (!SearchMsgs(Area)) { - fprintf(tmp, "Area %s not found\n", Area); - Syslog('m', " Area not found"); - /* SHOULD CHECK FOR AREAS FILE AND ASK UPLINK - CHECK ALL GROUPRECORDS FOR AKA MATCH - IF MATCH CHECK FOR UPLINK AND AREAS FILE - IF FOUND, CREATE MSG AREA, CONNECT UPLINK - RESTORE NODERECORD (IS GONE!) - FALLTHRU TO CONNECT DOWNLINK - */ - return; + Syslog('m', " Area not found, trying to create"); + temp = calloc(PATH_MAX, sizeof(char)); + sprintf(temp, "%s/etc/mgroups.data", getenv("MBSE_ROOT")); + if ((gp = fopen(temp, "r")) == NULL) { + WriteError("$Can't open %s", temp); + free(temp); + return; + } + fread(&mgrouphdr, sizeof(mgrouphdr), 1, gp); + fseek(gp, mgrouphdr.hdrsize, SEEK_SET); + + while ((fread(&mgroup, mgrouphdr.recsize, 1, gp)) == 1) { + if ((mgroup.UseAka.zone == t->zone) && (mgroup.UseAka.net == t->net) && mgroup.UpLink.zone && + strlen(mgroup.AreaFile) && mgroup.Active && mgroup.UserChange) { + Syslog('m', "Checking echogroup %s %s", mgroup.Name, mgroup.Comment); + sprintf(temp, "%s/%s", CFG.alists_path , mgroup.AreaFile); + if ((ap = fopen(temp, "r")) == NULL) { + WriteError("$Can't open %s", temp); + } else { + buf = calloc(4097, sizeof(char)); + while (fgets(buf, 4096, ap)) { + tag = strtok(buf, "\t \r\n\0"); + p = strtok(NULL, "\r\n\0"); + desc = p; + while ((*desc == ' ') || (*desc == '\t')) + desc++; + if (strcmp(tag, Area) == 0) { + Syslog('m', "Found tag \"%s\" desc \"%s\"", tag, desc); + sprintf(temp, "%s/etc/mareas.data", getenv("MBSE_ROOT")); + if ((mp = fopen(temp, "r+")) == NULL) { + WriteError("$Can't open %s", temp); + fclose(ap); + fclose(gp); + free(buf); + free(temp); + return; + } + fread(&msgshdr, sizeof(msgshdr), 1, mp); + offset = msgshdr.hdrsize + ((mgroup.StartArea -1) * (msgshdr.recsize + msgshdr.syssize)); + if (fseek(mp, offset, SEEK_SET)) { + WriteError("$Can't seek in %s", temp); + fclose(ap); + fclose(gp); + fclose(mp); + free(buf); + free(temp); + return; + } + sprintf(temp, "+%s", Area); + if (UplinkRequest(fido2faddr(mgroup.UpLink), FALSE, temp)) { + WriteError("Can't send netmail to uplink"); + fclose(ap); + fclose(gp); + fclose(mp); + free(buf); + free(temp); + return; + } + while (fread(&msgs, sizeof(msgs), 1, mp) == 1) { + if (!msgs.Active) { + fseek(mp, - msgshdr.recsize, SEEK_CUR); + offset = ((ftell(mp) - msgshdr.hdrsize) / (msgshdr.recsize + msgshdr.syssize)) + 1; + Syslog('m', "Found free slot at %ld", offset); + rc = 1; + break; + } + /* + * Skip systems + */ + fseek(mp, msgshdr.syssize, SEEK_CUR); + } + if (!rc) { + Syslog('m', "No free slot, append after last record"); + fseek(mp, 0, SEEK_END); + if (ftell(mp) < msgshdr.hdrsize + ((mgroup.StartArea -1) * (msgshdr.recsize + msgshdr.syssize))) { + Syslog('m', "Database too small, expanding..."); + memset(&msgs, 0, sizeof(msgs)); + memset(&Sys, 0, sizeof(Sys)); + while (TRUE) { + fwrite(&msgs, sizeof(msgs), 1, mp); + for (i = 0; i < (msgshdr.syssize / sizeof(Sys)); i++) + fwrite(&Sys, sizeof(Sys), 1, mp); + if (ftell(mp) >= msgshdr.hdrsize + ((mgroup.StartArea -1) * (msgshdr.recsize + msgshdr.syssize))) + break; + } + } + rc = 1; + } + offset = ((ftell(mp) - msgshdr.hdrsize) / (msgshdr.recsize + msgshdr.syssize)) + 1; + memset(&msgs, 0, sizeof(msgs)); + strncpy(msgs.Tag, tag, 50); + strncpy(msgs.Name, desc, 40); + strncpy(msgs.QWKname, tag, 20); + msgs.MsgKinds = PUBLIC; + msgs.Type = ECHOMAIL; + msgs.DaysOld = CFG.defdays; + msgs.MaxMsgs = CFG.defmsgs; + msgs.UsrDelete = mgroup.UsrDelete; + msgs.RDSec = mgroup.RDSec; + msgs.WRSec = mgroup.WRSec; + msgs.SYSec = mgroup.SYSec; + strncpy(msgs.Group, mgroup.Name, 12); + msgs.Aka = mgroup.UseAka; + strncpy(msgs.Origin, CFG.origin, 50); + msgs.Aliases = mgroup.Aliases; + msgs.NetReply = mgroup.NetReply; + msgs.Active = TRUE; + msgs.Quotes = mgroup.Quotes; + msgs.Rfccode = CHRS_DEFAULT_RFC; + msgs.Ftncode = CHRS_DEFAULT_FTN; + msgs.MaxArticles = CFG.maxarticles; + tag = tl(tag); + for (i = 0; i < strlen(tag); i++) + if (tag[i] == '.') + tag[i] = '/'; + sprintf(msgs.Base, "%s/%s", mgroup.BasePath, tag); + fwrite(&msgs, sizeof(msgs), 1, mp); + + memset(&Sys, 0, sizeof(Sys)); + Sys.aka = mgroup.UpLink; + Sys.sendto = Sys.receivefrom = TRUE; + fwrite(&Sys, sizeof(Sys), 1, mp); + memset(&Sys, 0, sizeof(Sys)); + for (i = 1; i < (msgshdr.syssize / sizeof(Sys)); i++) + fwrite(&Sys, sizeof(Sys), 1, mp); + Syslog('+', "Created echo %s, group %s, area %ld, for node %s", + msgs.Tag, msgs.Group, offset, ascfnode(t, 0x1f)); + fclose(mp); + rc = 1; + } /* if (strcmp(tag, Area) == 0) */ + } /* while (fgets(buf, 4096, ap)) */ + free(buf); + fclose(ap); + } /* else ((ap = fopen(temp, "r")) == NULL) */ + if (rc) + break; + } /* if possible matching group */ + } + fclose(gp); + free(temp); + + /* + * Restore noderecord and try to load the area again + */ + SearchNodeFaddr(t); + if (!SearchMsgs(Area)) { + fprintf(tmp, "Area %s not found\n", Area); + Syslog('+', "Area %s not found", Area); + return; + } } Syslog('m', " Found %s group %s", msgs.Tag, mgroup.Name); diff --git a/mbfido/mgrutil.c b/mbfido/mgrutil.c index 396e42d0..909cbed4 100644 --- a/mbfido/mgrutil.c +++ b/mbfido/mgrutil.c @@ -36,6 +36,8 @@ #include "../lib/clcomm.h" #include "../lib/dbnode.h" #include "sendmail.h" +#include "rollover.h" +#include "addpkt.h" #include "mgrutil.h" @@ -233,3 +235,132 @@ void MgrNotify(faddr *t, char *Buf, FILE *tmp) } + +/* + * Create uplink areamgr request. One netmail per request. + * More is possible, cmd is then: "+area1\+area2\-area3" + * Return values: + * 0 - Ok + * 1 - Node not in setup + * 2 - No Uplink mgr program in setup + * 3 - No uplink password in setup + * 4 - Can't add mail to outbound + */ +int UplinkRequest(faddr *t, int FileMgr, char *cmd) +{ + FILE *qp; + time_t Now; + struct tm *tm; + fidoaddr Orig, Dest; + faddr From; + unsigned flags = M_PVT; + char ext[4], *mgrname, *bymgr, *subj; + int i; + + From = *bestaka_s(t); + memset(&Orig, 0, sizeof(Orig)); + Orig.zone = From.zone; + Orig.net = From.net; + Orig.node = From.node; + Orig.point = From.point; + sprintf(Orig.domain, "%s", From.domain); + + memset(&Dest, 0, sizeof(Dest)); + Dest.zone = t->zone; + Dest.net = t->net; + Dest.node = t->node; + Dest.point = t->point; + sprintf(Dest.domain, "%s", t->domain); + + if (!SearchNode(Dest)) { + Syslog('+', "Can't find node %s in setup", aka2str(Dest)); + return 1; + } + + if (FileMgr) { + if (strlen(nodes.UplFmgrPgm) == 0) { + Syslog('!', "FileMgr program not defined in setup of node %s", aka2str(Dest)); + return 2; + } + mgrname = xstrcpy(nodes.UplFmgrPgm); + bymgr = xstrcpy((char *)"FileMgr"); + } else { + if (strlen(nodes.UplAmgrPgm) == 0) { + Syslog('!', "AreaMgr program not defined in setup of node %s", aka2str(Dest)); + return 2; + } + mgrname = xstrcpy(nodes.UplAmgrPgm); + bymgr = xstrcpy((char *)"AreaMgr"); + } + + if (strlen(nodes.Apasswd) == 0) { + Syslog('!', "No %s password set for node %s", mgrname, aka2str(Dest)); + return 3; + } + subj = xstrcpy(nodes.Apasswd); + + Syslog('-', " Netmail from %s to %s", aka2str(Orig), ascfnode(t, 0x1f)); + + Now = time(NULL) - (gmt_offset((time_t)0) * 60); + flags |= (nodes.Crash) ? M_CRASH : 0; + flags |= (nodes.Hold) ? M_HOLD : 0; + + /* + * Increase counters, update record and reload. + */ + StatAdd(&nodes.MailSent, 1L); + UpdateNode(); + SearchNode(Dest); + + memset(&ext, 0, sizeof(ext)); + if (nodes.PackNetmail) + sprintf(ext, (char *)"qqq"); + else if (nodes.Crash) + sprintf(ext, (char *)"ccc"); + else if (nodes.Hold) + sprintf(ext, (char *)"hhh"); + else + sprintf(ext, (char *)"nnn"); + + if ((qp = OpenPkt(Orig, Dest, (char *)ext)) == NULL) + return 4; + + if (AddMsgHdr(qp, &From, t, flags, 0, Now, mgrname, bymgr, subj)) { + fclose(qp); + return 4; + } + + if (Dest.point) + fprintf(qp, "\001TOPT %d\r", Dest.point); + if (Orig.point) + fprintf(qp, "\001FMPT %d\r", Orig.point); + + fprintf(qp, "\001INTL %d:%d/%d %d:%d/%d\r", Dest.zone, Dest.net, Dest.node, Orig.zone, Orig.net, Orig.node); + + /* + * Add MSGID, REPLY and PID + */ + fprintf(qp, "\001MSGID: %s %08lx\r", aka2str(Orig), sequencer()); + fprintf(qp, "\001PID: MBSE-FIDO %s\r", VERSION); + fprintf(qp, "\001TZUTC: %s\r", gmtoffset(Now)); + + for (i = 0; i < strlen(cmd); i++) + putc(cmd[i], qp); + putc('\r', qp); + fprintf(qp, TearLine()); + + tm = gmtime(&Now); + fprintf(qp, "\001Via %s @%d%02d%02d.%02d%02d%02d.02.UTC %s\r", + ascfnode(bestaka_s(t), 0x1f), tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday, + tm->tm_hour, tm->tm_min, tm->tm_sec, VERSION); + + putc(0, qp); + fclose(qp); + + free(mgrname); + free(bymgr); + free(subj); + return 0; +} + + diff --git a/mbfido/mgrutil.h b/mbfido/mgrutil.h index 7fbd2fa8..4566a26e 100644 --- a/mbfido/mgrutil.h +++ b/mbfido/mgrutil.h @@ -1,3 +1,5 @@ +/* $Id$ */ + #ifndef _MGRUTIL_H #define _MGRUTIL_H @@ -9,7 +11,7 @@ void CleanBuf(char *); void ShiftBuf(char *, int); void MgrPasswd(faddr *, char *, FILE *, int); void MgrNotify(faddr *, char *, FILE *); - +int UplinkRequest(faddr *, int, char *); #endif