/***************************************************************************** * * $Id$ * Purpose ...............: AreaMgr * ***************************************************************************** * Copyright (C) 1997-2002 * * Michiel Broek FIDO: 2:280/2802 * Beekmansbos 10 * 1971 BV IJmuiden * the Netherlands * * This file is part of MBSE BBS. * * This BBS is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2, or (at your option) any * later version. * * MBSE BBS is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with MBSE BBS; see the file COPYING. If not, write to the Free * Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. *****************************************************************************/ #include "../lib/libs.h" #include "../lib/structs.h" #include "../lib/users.h" #include "../lib/records.h" #include "../lib/common.h" #include "../lib/clcomm.h" #include "../lib/msg.h" #include "../lib/msgtext.h" #include "../lib/dbcfg.h" #include "../lib/dbnode.h" #include "../lib/dbmsgs.h" #include "../lib/dbdupe.h" #include "../lib/dbuser.h" #include "../lib/dbftn.h" #include "sendmail.h" #include "mgrutil.h" #include "scan.h" #include "areamgr.h" /* * External declarations */ extern int do_quiet; extern char *tearline; /* * Global variables */ extern int net_in; /* Netmails received */ extern int net_out; /* Netmails forwarded */ extern int net_bad; /* Bad netmails (tracking errors */ extern int echo_in; /* Echomail received */ extern int echo_imp; /* Echomail imported */ extern int echo_out; /* Echomail forwarded */ extern int echo_bad; /* Bad echomail */ extern int echo_dupe; /* Dupe echomail */ int areamgr = 0; /* Nr of AreaMgr messages */ int a_help = FALSE; int a_list = FALSE; int a_query = FALSE; int a_stat = FALSE; int a_unlnk = FALSE; int a_flow = FALSE; unsigned long a_msgs = 0; void A_Help(faddr *, char *); void A_Help(faddr *t, char *replyid) { FILE *fp; Syslog('+', "AreaMgr: Help"); if ((fp = SendMgrMail(t, CFG.ct_KeepMgr, FALSE, (char *)"Areamgr", (char *)"AreaMgr help", replyid)) != NULL) { fprintf(fp, "Address all requests to '%s' (without quotes)\r", (char *)"Areamgr"); fprintf(fp, "Youre AreaMgr password goes on the subject line.\r\r"); fprintf(fp, "In the body of the message to AreaMgr:\r\r"); fprintf(fp, "+ To connect to an echomail area\r"); fprintf(fp, "- To disconnect from an echomail area\r"); fprintf(fp, "%%+ALL To connect to all echomail areas\r"); fprintf(fp, "%%-ALL To disconnect from all echomail areas\r"); fprintf(fp, "%%+ To connect all echomail areas of a group\r"); fprintf(fp, "%%- To disconnect from all echomail areas of a group\r"); fprintf(fp, "%%HELP To request this help message\r"); fprintf(fp, "%%LIST To request a list of echomail areas available to you\r"); fprintf(fp, "%%QUERY To request a list of echomail areas for which you are active\r"); fprintf(fp, "%%UNLINKED To request a list of echomail areas available to you\r"); fprintf(fp, " to which you are not already connected\r"); fprintf(fp, "%%FLOW To request a flow report of available areas\r"); fprintf(fp, "%%STATUS To request a status report for your system\r"); // fprintf(fp, "%%PAUSE To temporary disconnect from the connected echomail areas\r"); // fprintf(fp, "%%RESUME To reconnect the temporary disconnected echomail areas\r"); fprintf(fp, "%%PWD=newpwd To set a new AreaMgr and FileMgr password\r"); fprintf(fp, "%%MSGS To set max. number of messages to be rescanned\r"); fprintf(fp, "%%RESCAN To request messages from 'area' again\r"); fprintf(fp, "%%NOTIFY=On/Off To switch the notify function on or off\r"); fprintf(fp, "[---] Everything below the tearline is ignored\r\r"); fprintf(fp, "Example:\r\r"); fprintf(fp, " By: %s\r", nodes.Sysop); fprintf(fp, " To: %s, %s\r", (char *)"Areamgr", ascfnode(bestaka_s(t), 0xf)); fprintf(fp, " Re: %s\r", nodes.Apasswd); fprintf(fp, " St: Pvt Local Kill\r"); fprintf(fp, " ----------------------------------------------------------\r"); fprintf(fp, " +SYSOPS\r"); fprintf(fp, " -GENERAL\r"); fprintf(fp, " %%QUERY\r"); fprintf(fp, " %%LIST\r\r"); fprintf(fp, "%s\r", tearline); CloseMail(fp, t); net_out++; } else WriteError("Can't create netmail"); } void A_Query(faddr *, char *); void A_Query(faddr *t, char *replyid) { FILE *qp, *gp, *mp; char *temp, *Group; int i, First = TRUE, SubTot, Total = 0, Cons; char Stat[5]; faddr *f; sysconnect System; Syslog('+', "AreaMgr: Query"); f = bestaka_s(t); if ((qp = SendMgrMail(t, CFG.ct_KeepMgr, FALSE, (char *)"Areamgr", (char *)"Your query request", replyid)) != NULL) { temp = calloc(128, sizeof(char)); sprintf(temp, "%s/etc/mareas.data", getenv("MBSE_ROOT")); mp = fopen(temp, "r"); fread(&msgshdr, sizeof(msgshdr), 1, mp); Cons = msgshdr.syssize / sizeof(System); sprintf(temp, "%s/etc/mgroups.data", getenv("MBSE_ROOT")); gp = fopen(temp, "r"); fread(&mgrouphdr, sizeof(mgrouphdr), 1, gp); fprintf(qp, "The following is a list of all connected message areas\r\r"); while (TRUE) { Group = GetNodeMailGrp(First); if (Group == NULL) break; First = FALSE; fseek(gp, mgrouphdr.hdrsize, SEEK_SET); while (fread(&mgroup, mgrouphdr.recsize, 1, gp) == 1) { if ((!strcmp(mgroup.Name, Group)) && (mgroup.UseAka.zone == f->zone) && (mgroup.UseAka.net == f->net) && (mgroup.UseAka.node == f->node) && (mgroup.UseAka.point == f->point)) { SubTot = 0; fprintf(qp, "Group %s - %s\r\r", mgroup.Name, mgroup.Comment); fprintf(qp, "Con Message area Description\r"); fprintf(qp, "----------------------------------------------------------------------------\r"); fseek(mp, msgshdr.hdrsize, SEEK_SET); while (fread(&msgs, msgshdr.recsize, 1, mp) == 1) { if (!strcmp(Group, msgs.Group) && msgs.Active) { memset(&Stat, ' ', sizeof(Stat)); Stat[sizeof(Stat)-1] = '\0'; /* * Now check if this node is connected, * if so, set the Stat bits */ for (i = 0; i < Cons; i++) { fread(&System, sizeof(System), 1, mp); if ((t->zone == System.aka.zone) && (t->net == System.aka.net) && (t->node == System.aka.node) && (t->point == System.aka.point)) { if (System.receivefrom) Stat[0] = 'S'; if (System.sendto) Stat[1] = 'R'; if (System.pause) Stat[2] = 'P'; if (System.cutoff) Stat[3] = 'C'; } } if (Stat[0] == 'S' || Stat[1] == 'R') { fprintf(qp, "%s %-25s %s\r", Stat, msgs.Tag, msgs.Name); SubTot++; Total++; } } else fseek(mp, msgshdr.syssize, SEEK_CUR); } fprintf(qp, "----------------------------------------------------------------------------\r"); fprintf(qp, "%d connected area(s)\r\r\r", SubTot); } } } fprintf(qp, "Total: %d connected area(s)\r\r\r", Total); fclose(mp); fclose(gp); fprintf(qp, "Con means:\r"); fprintf(qp, " R - You receive mail from my system\r"); fprintf(qp, " S - You may send mail to my system\r"); fprintf(qp, " P - The message area is temporary paused\r"); fprintf(qp, " C - You are cutoff from this area\r\r"); fprintf(qp, "With regards, %s\r\r", CFG.sysop_name); fprintf(qp, "%s\r", tearline); CloseMail(qp, t); net_out++; free(temp); } else WriteError("Can't create netmail"); } void A_List(faddr *t, char *replyid, int Notify) { FILE *qp, *gp, *mp; char *temp, *Group; int i, First = TRUE, SubTot, Total = 0, Cons; char Stat[5]; faddr *f; sysconnect System; if (Notify) Syslog('+', "AreaMgr: Notify to %s", ascfnode(t, 0xff)); else Syslog('+', "AreaMgr: List"); f = bestaka_s(t); if ((qp = SendMgrMail(t, CFG.ct_KeepMgr, FALSE, (char *)"Areamgr", (char *)"AreaMgr List", replyid)) != NULL) { WriteMailGroups(qp, f); temp = calloc(128, sizeof(char)); sprintf(temp, "%s/etc/mareas.data", getenv("MBSE_ROOT")); mp = fopen(temp, "r"); fread(&msgshdr, sizeof(msgshdr), 1, mp); Cons = msgshdr.syssize / sizeof(System); sprintf(temp, "%s/etc/mgroups.data", getenv("MBSE_ROOT")); gp = fopen(temp, "r"); fread(&mgrouphdr, sizeof(mgrouphdr), 1, gp); fprintf(qp, "The following is a list of all message areas\r\r"); while (TRUE) { Group = GetNodeMailGrp(First); if (Group == NULL) break; First = FALSE; fseek(gp, mgrouphdr.hdrsize, SEEK_SET); while (fread(&mgroup, mgrouphdr.recsize, 1, gp) == 1) { if ((!strcmp(mgroup.Name, Group)) && (mgroup.UseAka.zone == f->zone) && (mgroup.UseAka.net == f->net) && (mgroup.UseAka.node == f->node) && (mgroup.UseAka.point == f->point)) { SubTot = 0; fprintf(qp, "Group %s - %s\r\r", mgroup.Name, mgroup.Comment); fprintf(qp, "Con Message area Description\r"); fprintf(qp, "----------------------------------------------------------------------------\r"); fseek(mp, msgshdr.hdrsize, SEEK_SET); while (fread(&msgs, msgshdr.recsize, 1, mp) == 1) { if (!strcmp(Group, msgs.Group) && msgs.Active) { memset(&Stat, ' ', sizeof(Stat)); Stat[sizeof(Stat)-1] = '\0'; /* * Now check if this node is connected, * if so, set the Stat bits */ for (i = 0; i < Cons; i++) { fread(&System, sizeof(System), 1, mp); if ((t->zone == System.aka.zone) && (t->net == System.aka.net) && (t->node == System.aka.node) && (t->point == System.aka.point)) { if (System.receivefrom) Stat[0] = 'S'; if (System.sendto) Stat[1] = 'R'; if (System.pause) Stat[2] = 'P'; if (System.cutoff) Stat[3] = 'C'; } } fprintf(qp, "%s %-25s %s\r", Stat, msgs.Tag, msgs.Name); SubTot++; Total++; } else fseek(mp, msgshdr.syssize, SEEK_CUR); } fprintf(qp, "----------------------------------------------------------------------------\r"); fprintf(qp, "%d available area(s)\r\r\r", SubTot); } } } fprintf(qp, "Total: %d available area(s)\r\r\r", Total); fclose(mp); fclose(gp); fprintf(qp, "Con means:\r"); fprintf(qp, " R - You receive mail from my system\r"); fprintf(qp, " S - You may send mail to my system\r"); fprintf(qp, " P - The message area is temporary paused\r"); fprintf(qp, " C - You are cutoff from this area\r\r"); fprintf(qp, "With regards, %s\r\r", CFG.sysop_name); fprintf(qp, "%s\r", tearline); CloseMail(qp, t); net_out++; free(temp); } else WriteError("Can't create netmail"); } void A_Flow(faddr *t, char *replyid, int Notify) { FILE *qp, *gp, *mp; char *temp, *Group; int i, First = TRUE, Cons; char Stat[2]; faddr *f; sysconnect System; time_t Now; struct tm *tt; int lmonth; long lw, lm; Now = time(NULL); tt = localtime(&Now); lmonth = tt->tm_mon; if (lmonth) lmonth--; else lmonth = 11; if (Notify) Syslog('+', "AreaMgr: Flow report to %s", ascfnode(t, 0xff)); else Syslog('+', "AreaMgr: Flow report"); f = bestaka_s(t); if ((qp = SendMgrMail(t, CFG.ct_KeepMgr, FALSE, (char *)"Areamgr", (char *)"AreaMgr Flow report", replyid)) != NULL) { temp = calloc(128, sizeof(char)); sprintf(temp, "%s/etc/mareas.data", getenv("MBSE_ROOT")); mp = fopen(temp, "r"); fread(&msgshdr, sizeof(msgshdr), 1, mp); Cons = msgshdr.syssize / sizeof(System); sprintf(temp, "%s/etc/mgroups.data", getenv("MBSE_ROOT")); gp = fopen(temp, "r"); fread(&mgrouphdr, sizeof(mgrouphdr), 1, gp); fprintf(qp, "The following is a flow report of all message areas\r\r"); while (TRUE) { Group = GetNodeMailGrp(First); if (Group == NULL) break; First = FALSE; lm = lw = 0; fseek(gp, mgrouphdr.hdrsize, SEEK_SET); while (fread(&mgroup, mgrouphdr.recsize, 1, gp) == 1) { if ((!strcmp(mgroup.Name, Group)) && (mgroup.UseAka.zone == f->zone) && (mgroup.UseAka.net == f->net) && (mgroup.UseAka.node == f->node) && (mgroup.UseAka.point == f->point)) { fprintf(qp, "Group %s - %s\r\r", mgroup.Name, mgroup.Comment); // 1 2 3 4 5 6 7 // 12345678901234567890123456789012345678901234567890123456789012345678901234567890 fprintf(qp, "Con Message area Last week Last Month\r"); fprintf(qp, "---------------------------------------------------------------------------\r"); fseek(mp, msgshdr.hdrsize, SEEK_SET); while (fread(&msgs, msgshdr.recsize, 1, mp) == 1) { if (!strcmp(Group, msgs.Group) && msgs.Active) { memset(&Stat, ' ', sizeof(Stat)); Stat[sizeof(Stat)-1] = '\0'; /* * Now check if this node is connected, * if so, set the Stat bits */ for (i = 0; i < Cons; i++) { fread(&System, sizeof(System), 1, mp); if ((t->zone == System.aka.zone) && (t->net == System.aka.net) && (t->node == System.aka.node) && (t->point == System.aka.point)) { if ((System.receivefrom || System.sendto) && (!System.pause) && (!System.cutoff)) Stat[0] = 'C'; } } fprintf(qp, "%s %s %9lu %10lu\r", Stat, padleft(msgs.Tag, 50, ' '), msgs.Received.lweek, msgs.Received.month[lmonth]); lm += msgs.Received.month[lmonth]; lw += msgs.Received.lweek; } else fseek(mp, msgshdr.syssize, SEEK_CUR); } fprintf(qp, "---------------------------------------------------------------------------\r"); fprintf(qp, "Total %58lu %10lu\r\r\r", lw, lm); } } } fclose(mp); fclose(gp); fprintf(qp, "Con means:\r"); fprintf(qp, " C - You connected to this area\r"); fprintf(qp, "With regards, %s\r\r", CFG.sysop_name); fprintf(qp, "%s\r", tearline); CloseMail(qp, t); net_out++; free(temp); } else WriteError("Can't create netmail"); } void A_Status(faddr *, char *); void A_Status(faddr *t, char *replyid) { FILE *fp; int i; Syslog('+', "AreaMgr: Status"); if (Miy == 0) i = 11; else i = Miy - 1; if ((fp = SendMgrMail(t, CFG.ct_KeepMgr, FALSE, (char *)"Areamgr", (char *)"AreaMgr status", replyid)) != NULL) { fprintf(fp, "Here is your (echo)mail status:\r\r"); fprintf(fp, "Netmail direct %s\r", GetBool(nodes.Direct)); fprintf(fp, "Netmail crash %s\r", GetBool(nodes.Crash)); fprintf(fp, "Netmail hold %s\r", GetBool(nodes.Hold)); if (nodes.RouteVia.zone) fprintf(fp, "Route via %s\r", aka2str(nodes.RouteVia)); fprintf(fp, "\r\rMailflow:\r\r"); fprintf(fp, " Last week Last month Total ever\r"); fprintf(fp, " ---------- ---------- ----------\r"); fprintf(fp, "Messages to you %-10ld %-10ld %-10ld\r", nodes.MailSent.lweek, nodes.MailSent.month[i], nodes.MailSent.total); fprintf(fp, "Messages from you %-10ld %-10ld %-10ld\r", nodes.MailRcvd.lweek, nodes.MailRcvd.month[i], nodes.MailRcvd.total); fprintf(fp, "\rWith regards, %s\r\r", CFG.sysop_name); fprintf(fp, "%s\r", tearline); CloseMail(fp, t); net_out++; } else WriteError("Can't create netmail"); } void A_Unlinked(faddr *, char *); void A_Unlinked(faddr *t, char *replyid) { FILE *qp, *gp, *mp; char *temp, *Group; int i, First = TRUE, SubTot, Total = 0, Cons; char Stat[5]; faddr *f; sysconnect System; Syslog('+', "AreaMgr: Unlinked"); f = bestaka_s(t); if ((qp = SendMgrMail(t, CFG.ct_KeepMgr, FALSE, (char *)"Areamgr", (char *)"Your unlinked request", replyid)) != NULL) { WriteMailGroups(qp, f); temp = calloc(128, sizeof(char)); sprintf(temp, "%s/etc/mareas.data", getenv("MBSE_ROOT")); mp = fopen(temp, "r"); fread(&msgshdr, sizeof(msgshdr), 1, mp); Cons = msgshdr.syssize / sizeof(System); sprintf(temp, "%s/etc/mgroups.data", getenv("MBSE_ROOT")); gp = fopen(temp, "r"); fread(&mgrouphdr, sizeof(mgrouphdr), 1, gp); fprintf(qp, "The following is a list of all available message areas\r\r"); while (TRUE) { Group = GetNodeMailGrp(First); if (Group == NULL) break; First = FALSE; fseek(gp, mgrouphdr.hdrsize, SEEK_SET); while (fread(&mgroup, mgrouphdr.recsize, 1, gp) == 1) { if ((!strcmp(mgroup.Name, Group)) && (mgroup.UseAka.zone == f->zone) && (mgroup.UseAka.net == f->net) && (mgroup.UseAka.node == f->node) && (mgroup.UseAka.point == f->point)) { SubTot = 0; fprintf(qp, "Group %s - %s\r\r", mgroup.Name, mgroup.Comment); fprintf(qp, "Con Message area Description\r"); fprintf(qp, "----------------------------------------------------------------------------\r"); fseek(mp, msgshdr.hdrsize, SEEK_SET); while (fread(&msgs, msgshdr.recsize, 1, mp) == 1) { if (!strcmp(Group, msgs.Group) && msgs.Active) { memset(&Stat, ' ', sizeof(Stat)); Stat[sizeof(Stat)-1] = '\0'; /* * Now check if this node is connected, * if so, set the Stat bits */ for (i = 0; i < Cons; i++) { fread(&System, sizeof(System), 1, mp); if ((t->zone == System.aka.zone) && (t->net == System.aka.net) && (t->node == System.aka.node) && (t->point == System.aka.point)) { if (System.receivefrom) Stat[0] = 'S'; if (System.sendto) Stat[1] = 'R'; if (System.pause) Stat[2] = 'P'; if (System.cutoff) Stat[3] = 'C'; } } if ((!System.sendto) && (!System.receivefrom)) { fprintf(qp, "%s %-25s %s\r", Stat, msgs.Tag, msgs.Name); SubTot++; Total++; } } else fseek(mp, msgshdr.syssize, SEEK_CUR); } fprintf(qp, "----------------------------------------------------------------------------\r"); fprintf(qp, "%d available area(s)\r\r\r", SubTot); } } } fclose(mp); fclose(gp); fprintf(qp, "Con means:\r"); fprintf(qp, " R - You receive mail from my system\r"); fprintf(qp, " S - You may send mail to my system\r"); fprintf(qp, " P - The message area is temporary paused\r"); fprintf(qp, " C - You are cutoff from this area\r\r"); fprintf(qp, "With regards, %s\r\r", CFG.sysop_name); fprintf(qp, "%s\r", tearline); CloseMail(qp, t); net_out++; free(temp); } else WriteError("Can't create netmail"); } void A_Global(faddr *, char *, FILE *); void A_Global(faddr *t, char *Cmd, FILE *tmp) { ShiftBuf(Cmd, 1); Syslog('m', " AreaMgr node %s global %s", ascfnode(t, 0x1f), Cmd); } void A_Disconnect(faddr *, char *, FILE *); void A_Disconnect(faddr *t, char *Area, FILE *tmp) { int i, First; char *Group; faddr *b; sysconnect Sys; Syslog('+', "AreaMgr: \"%s\"", Area); ShiftBuf(Area, 1); for (i=0; i < strlen(Area); i++ ) Area[i]=toupper(Area[i]); if (!SearchMsgs(Area)) { fprintf(tmp, "Area %s not found\n", Area); Syslog('m', " Area not found"); return; } Syslog('m', " Found %s group %s", msgs.Tag, mgroup.Name); First = TRUE; while ((Group = GetNodeMailGrp(First)) != NULL) { First = FALSE; if (strcmp(Group, mgroup.Name) == 0) break; } if (Group == NULL) { fprintf(tmp, "You may not disconnect from area %s\n", Area); Syslog('m', " Group %s not available for node", mgroup.Name); return; } b = bestaka_s(t); i = metric(b, fido2faddr(mgroup.UseAka)); Syslog('m', "Aka match level is %d", i); if (i > METRIC_POINT) { fprintf(tmp, "You may not disconnect area %s with nodenumber %s\n", Area, ascfnode(t, 0x1f)); Syslog('m', " Node may not disconnect from group %s", mgroup.Name); return; } memset(&Sys, 0, sizeof(Sys)); memcpy(&Sys.aka, faddr2fido(t), sizeof(fidoaddr)); Sys.sendto = FALSE; Sys.receivefrom = FALSE; if (!MsgSystemConnected(Sys)) { fprintf(tmp, "You are not connected to %s\n", Area); Syslog('m', " Node is not connected to %s", Area); return; } if (MsgSystemConnect(&Sys, FALSE)) { /* * Make sure to write an overview afterwards. */ a_list = TRUE; Syslog('+', "Disconnected echo area %s", Area); fprintf(tmp, "Disconnected from area %s\n", Area); return; } fprintf(tmp, "You may not disconnect area %s\n", Area); Syslog('+', "Didn't disconnect %s from mandatory or cutoff echo area %s", ascfnode(t, 0x1f), Area); } void A_Connect(faddr *, char *, FILE *); void A_Connect(faddr *t, char *Area, FILE *tmp) { int i, First; char *Group; faddr *b; sysconnect Sys; Syslog('+', "AreaMgr: \"%s\"", printable(Area, 0)); if (Area[0] == '+') ShiftBuf(Area, 1); for (i=0; i < strlen(Area); i++ ) 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', " Found %s group %s", msgs.Tag, mgroup.Name); First = TRUE; while ((Group = GetNodeMailGrp(First)) != NULL) { First = FALSE; if (strcmp(Group, mgroup.Name) == 0) break; } if (Group == NULL) { fprintf(tmp, "You may not connect to area %s\n", Area); Syslog('m', " Group %s not available for node %s", mgroup.Name); return; } b = bestaka_s(t); i = metric(b, fido2faddr(mgroup.UseAka)); Syslog('m', "Aka match level is %d", i); if (i > METRIC_POINT) { fprintf(tmp, "You may not connect area %s with nodenumber %s\n", Area, ascfnode(t, 0x1f)); Syslog('m', " Node may not connect to group %s", mgroup.Name); return; } memset(&Sys, 0, sizeof(Sys)); memcpy(&Sys.aka, faddr2fido(t), sizeof(fidoaddr)); Sys.sendto = TRUE; Sys.receivefrom = TRUE; if (MsgSystemConnected(Sys)) { fprintf(tmp, "You are already connected to %s\n", Area); Syslog('m', " Node is already connected to %s", Area); return; } if (MsgSystemConnect(&Sys, TRUE)) { /* * Make sure to write an overview afterwards. */ a_list = TRUE; Syslog('+', "Connected echo area %s", Area); fprintf(tmp, "Connected to area %s\n", Area); return; } fprintf(tmp, "Not connected to %s, this is not allowed\n", Area); WriteError("Can't connect node %s to echo area %s", ascfnode(t, 0x1f), Area); } void A_All(faddr *, int, FILE *, char *); void A_All(faddr *t, int Connect, FILE *tmp, char *Grp) { FILE *mp, *gp; char *Group, temp[81]; faddr *f; int i, Link, First = TRUE, Cons; sysconnect Sys; long Pos; if (Grp == NULL) { if (Connect) Syslog('+', "AreaMgr: Connect All"); else Syslog('+', "AreaMgr: Disconnect All"); } else { if (Connect) Syslog('+', "AreaMgr: Connect group %s", Grp); else Syslog('+', "AreaMgr: Disconnect group %s", Grp); } f = bestaka_s(t); Syslog('m', "Bestaka for %s is %s", ascfnode(t, 0x1f), ascfnode(f, 0x1f)); sprintf(temp, "%s/etc/mareas.data", getenv("MBSE_ROOT")); mp = fopen(temp, "r+"); fread(&msgshdr, sizeof(msgshdr), 1, mp); Cons = msgshdr.syssize / sizeof(Sys); sprintf(temp, "%s/etc/mgroups.data", getenv("MBSE_ROOT")); gp = fopen(temp, "r"); fread(&mgrouphdr, sizeof(mgrouphdr), 1, gp); while (TRUE) { Group = GetNodeMailGrp(First); if (Group == NULL) break; First = FALSE; fseek(gp, mgrouphdr.hdrsize, SEEK_SET); while (fread(&mgroup, mgrouphdr.recsize, 1, gp) == 1) { if ((!strcmp(mgroup.Name, Group)) && ((Grp == NULL) || (!strcmp(Group, Grp)))) { fseek(mp, msgshdr.hdrsize, SEEK_SET); while (fread(&msgs, msgshdr.recsize, 1, mp) == 1) { if ((!strcmp(Group, msgs.Group)) && (msgs.Active) && (!msgs.Mandatory) && (metric(fido2faddr(mgroup.UseAka), f) == METRIC_EQUAL)) { if (Connect) { Link = FALSE; for (i = 0; i < Cons; i++) { fread(&Sys, sizeof(Sys), 1, mp); if (metric(fido2faddr(Sys.aka), t) == METRIC_EQUAL) Link = TRUE; } if (!Link) { Pos = ftell(mp); fseek(mp, - msgshdr.syssize, SEEK_CUR); for (i = 0; i < Cons; i++) { fread(&Sys, sizeof(Sys), 1, mp); if (!Sys.aka.zone) { memset(&Sys, 0, sizeof(Sys)); memcpy(&Sys.aka, faddr2fido(t), sizeof(fidoaddr)); Sys.sendto = TRUE; Sys.receivefrom = TRUE; fseek(mp, - sizeof(Sys), SEEK_CUR); fwrite(&Sys, sizeof(Sys), 1, mp); Syslog('+', "AreaMgr: Connected %s", msgs.Tag); fprintf(tmp, "Connected area %s\n", msgs.Tag); a_list = TRUE; break; } } fseek(mp, Pos, SEEK_SET); } } else { for (i = 0; i < Cons; i++) { fread(&Sys, sizeof(Sys), 1, mp); if ((metric(fido2faddr(Sys.aka), t) == METRIC_EQUAL) && (!Sys.cutoff)) { memset(&Sys, 0, sizeof(Sys)); fseek(mp, - sizeof(Sys), SEEK_CUR); fwrite(&Sys, sizeof(Sys), 1, mp); Syslog('+', "AreaMgr: Disconnected %s", msgs.Tag); fprintf(tmp, "Disconnected area %s\n", msgs.Tag); a_list = TRUE; } } } } else fseek(mp, msgshdr.syssize, SEEK_CUR); } } } } fclose(gp); fclose(mp); } void A_Group(faddr *, char *, int, FILE *); void A_Group(faddr *t, char *Area, int Connect, FILE *tmp) { int i; ShiftBuf(Area, 2); CleanBuf(Area); for (i=0; i < strlen(Area); i++ ) Area[i]=toupper(Area[i]); A_All(t, Connect, tmp, Area); } void A_Pause(faddr *, int, FILE *); void A_Pause(faddr *t, int Pause, FILE *tmp) { return; if (Pause) Syslog('+', "AreaMgr: Pause"); else Syslog('+', "AreaMgr: Resume"); } void A_Rescan(faddr *, char *, FILE *); void A_Rescan(faddr *t, char *Area, FILE *tmp) { int i,result; /* * First strip leading garbage */ ShiftBuf(Area, 7); CleanBuf(Area); for (i=0; i < strlen(Area); i++ ) Area[i]=toupper(Area[i]); Syslog('+', "AreaMgr: Rescan %s, MSGS=%lu", Area, a_msgs); result=RescanOne(t, Area, a_msgs); if (result==0){ if (a_msgs>0) fprintf(tmp, "Rescan area %s, %lu last msgs.\n", Area, a_msgs); else fprintf(tmp, "Rescan area %s \n", Area); } else if (result==1) fprintf(tmp, "Can't rescan unknown area %s\n", Area); else if (result==2) fprintf(tmp, "%s can't rescan area %s\n", ascfnode(t, 0x1f), Area); else fprintf(tmp, "Fatal Error Rescanning area %s\n", Area); } void A_Msgs(char *, int); void A_Msgs(char *Buf, int skip) { /* * First strip leading garbage */ ShiftBuf(Buf, skip); CleanBuf(Buf); a_msgs = strtoul( Buf, (char **)NULL, 10 ); Syslog('+', "AreaMgr: msgs %s ", Buf ); } int AreaMgr(faddr *f, faddr *t, char *replyid, char *subj, time_t mdate, int flags, FILE *fp) { int i, rc = 0, spaces; char *Buf; FILE *tmp, *np; fidoaddr Node; a_help = a_stat = a_unlnk = a_list = a_query = FALSE; areamgr++; if (SearchFidonet(f->zone)) f->domain = xstrcpy(fidonet.domain); Syslog('+', "AreaMgr msg from %s", ascfnode(f, 0xff)); /* * If the password failed, we return silently and don't respond. */ if ((!strlen(subj)) || (strcasecmp(subj, nodes.Apasswd))) { WriteError("AreaMgr: password expected \"%s\", got \"%s\"", nodes.Apasswd, subj); net_bad++; return FALSE; } if ((tmp = tmpfile()) == NULL) { WriteError("$AreaMgr: Can't open tmpfile()"); net_bad++; return FALSE; } Buf = calloc(2049, sizeof(char)); rewind(fp); while ((fgets(Buf, 2048, fp)) != NULL) { /* * Make sure we have the nodes record loaded */ memcpy(&Node, faddr2fido(f), sizeof(fidoaddr)); SearchNode(Node); spaces = 0; for (i = 0; i < strlen(Buf); i++) { if (*(Buf + i) == ' ') spaces++; if (*(Buf + i) == '\t') spaces++; if (*(Buf + i) == '\0') break; if (*(Buf + i) == '\n') *(Buf + i) = '\0'; if (*(Buf + i) == '\r') *(Buf + i) = '\0'; } if (!strncmp(Buf, "---", 3)) break; if (strlen(Buf) && (*(Buf) != '\001') && (spaces <= 1)) { if (!strncasecmp(Buf, "%help", 5)) a_help = TRUE; else if (!strncasecmp(Buf, "%query", 6)) a_query = TRUE; else if (!strncasecmp(Buf, "%linked", 7)) a_query = TRUE; else if (!strncasecmp(Buf, "%list", 5)) a_list = TRUE; else if (!strncasecmp(Buf, "%status", 7)) a_stat = TRUE; else if (!strncasecmp(Buf, "%unlinked", 9)) a_unlnk = TRUE; else if (!strncasecmp(Buf, "%flow", 5)) a_flow = TRUE; else if (!strncasecmp(Buf, "%msgs", 5)) A_Msgs(Buf, 5); else if (!strncasecmp(Buf, "%rescan", 7)) A_Rescan(f, Buf, tmp); else if (!strncasecmp(Buf, "%+all", 5)) A_All(f, TRUE, tmp, NULL); else if (!strncasecmp(Buf, "%-all", 5)) A_All(f, FALSE, tmp, NULL); else if (!strncasecmp(Buf, "%+*", 3)) A_All(f, TRUE, tmp, NULL); else if (!strncasecmp(Buf, "%-*", 3)) A_All(f, FALSE, tmp, NULL); else if (!strncasecmp(Buf, "%+", 2)) A_Group(f, Buf, TRUE, tmp); else if (!strncasecmp(Buf, "%-", 2)) A_Group(f, Buf, FALSE, tmp); else if (!strncasecmp(Buf, "%pause", 6)) A_Pause(f, TRUE, tmp); else if (!strncasecmp(Buf, "%resume", 7)) A_Pause(f, FALSE, tmp); else if (!strncasecmp(Buf, "%password", 9)) MgrPasswd(f, Buf, tmp, 9); else if (!strncasecmp(Buf, "%pwd", 4)) MgrPasswd(f, Buf, tmp, 4); else if (!strncasecmp(Buf, "%notify", 7)) MgrNotify(f, Buf, tmp); else if (*(Buf) == '%') A_Global(f, Buf, tmp); else if (*(Buf) == '-') A_Disconnect(f, Buf, tmp); else A_Connect(f, Buf, tmp); } } /* * If the temporary response file isn't empty, * create a response netmail about what we did. */ if (ftell(tmp)) { if ((np = SendMgrMail(f, CFG.ct_KeepMgr, FALSE, (char *)"Areamgr", (char *)"Your AreaMgr request", replyid)) != NULL) { fprintf(np, " Dear %s\r\r", nodes.Sysop); fprintf(np, "Here is the result of your AreaMgr request:\r\r"); fseek(tmp, 0, SEEK_SET); while ((fgets(Buf, 2048, tmp)) != NULL) { Buf[strlen(Buf)-1] = '\0'; fprintf(np, "%s\r", Buf); Syslog('m', "Rep: %s", Buf); } fprintf(np, "\rWith regards, %s\r\r", CFG.sysop_name); fprintf(np, "%s\r", tearline); CloseMail(np, t); net_out++; } else WriteError("Can't create netmail"); } free(Buf); fclose(tmp); if (a_stat) A_Status(f, replyid); if (a_query) A_Query(f, replyid); if (a_list) A_List(f, replyid, FALSE); if (a_flow) A_Flow(f, replyid, FALSE); if (a_unlnk) A_Unlinked(f, replyid); if (a_help) A_Help(f, replyid); return rc; }