From d3cf5b2a64a8bf3d4c6af6420f73d7c996e4d8ea Mon Sep 17 00:00:00 2001 From: Michiel Broek Date: Sat, 3 Aug 2002 22:12:37 +0000 Subject: [PATCH] Implemented directory outbound queueing --- ChangeLog | 2 +- mbfido/Makefile | 4 +- mbfido/dirsession.c | 3 - mbfido/dirsession.h | 6 +- mbfido/forward.c | 543 +++++++++++++++++---------------- mbfido/pack.c | 720 +++++++++++++++++++++++++------------------- 6 files changed, 708 insertions(+), 570 deletions(-) diff --git a/ChangeLog b/ChangeLog index cca5bda6..8bdf045a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -29,7 +29,7 @@ v0.35.03 06-Jul-2002 Added routing tables for special cases. Most systems don't need this. The route test command now works exactly as netmails do. - Implemented directory inbound tossing. + Implemented directory inbound tossing and outbound queueing. newuser: Check for Unix accounts is now case sensitive. diff --git a/mbfido/Makefile b/mbfido/Makefile index ca176193..2c3889e3 100644 --- a/mbfido/Makefile +++ b/mbfido/Makefile @@ -140,13 +140,13 @@ flock.o: ../config.h ../lib/libs.h ../lib/memwatch.h ../lib/clcomm.h flock.h hatch.o: ../config.h ../lib/libs.h ../lib/memwatch.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: ../config.h ../lib/libs.h ../lib/memwatch.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/common.h ../lib/clcomm.h ../lib/dbcfg.h mbdiff.h mgrutil.o: ../config.h ../lib/libs.h ../lib/memwatch.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/common.h ../lib/clcomm.h ../lib/dbnode.h ../lib/diesel.h sendmail.h rollover.h addpkt.h pack.h createm.h createf.h mgrutil.h -pack.o: ../config.h ../lib/libs.h ../lib/memwatch.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/common.h ../lib/dbftn.h ../lib/clcomm.h ../lib/dbnode.h pack.h +pack.o: ../config.h ../lib/libs.h ../lib/memwatch.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/common.h ../lib/dbftn.h ../lib/clcomm.h ../lib/dbnode.h dirsession.h pack.h ptic.o: ../config.h ../lib/libs.h ../lib/memwatch.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 createf.h virscan.h sendmail.o: ../config.h ../lib/libs.h ../lib/memwatch.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 tracker.o: ../config.h ../lib/libs.h ../lib/memwatch.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/common.h ../lib/clcomm.h ../lib/dbnode.h ../lib/dbftn.h tracker.h addpkt.o: ../config.h ../lib/libs.h ../lib/memwatch.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/clcomm.h ../lib/common.h ../lib/dbnode.h ../lib/dbmsgs.h pack.h addpkt.h bwrite.o: ../config.h ../lib/libs.h ../lib/memwatch.h bwrite.h -forward.o: ../config.h ../lib/libs.h ../lib/memwatch.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/common.h ../lib/clcomm.h ../lib/dbnode.h ../lib/dbtic.h ../lib/diesel.h tic.h sendmail.h rollover.h mgrutil.h forward.h +forward.o: ../config.h ../lib/libs.h ../lib/memwatch.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/common.h ../lib/clcomm.h ../lib/dbnode.h ../lib/dbtic.h ../lib/diesel.h tic.h sendmail.h rollover.h mgrutil.h forward.h dirsession.h lhash.o: ../config.h ../lib/libs.h ../lib/memwatch.h ../lib/clcomm.h lhash.h mbfido.o: ../config.h ../lib/libs.h ../lib/memwatch.h ../lib/mbse.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/common.h ../lib/clcomm.h ../lib/dbdupe.h ../lib/dbcfg.h ../lib/dbnode.h ../lib/dbmsgs.h ../lib/dbuser.h ../lib/dbftn.h ../lib/dbtic.h ../lib/msg.h flock.h tosspkt.h pack.h ulock.h tic.h fsort.h scan.h mbfido.h tracker.h notify.h rollover.h hatch.h scannews.h maketags.h makestat.h newspost.h rnews.h mgrutil.h backalias.h rfc2ftn.h dirsession.h mkftnhdr.o: ../config.h ../lib/libs.h ../lib/memwatch.h ../lib/structs.h ../lib/users.h ../lib/records.h ../lib/common.h ../lib/clcomm.h ../lib/dbcfg.h atoul.h hash.h msgflags.h aliasdb.h mkftnhdr.h diff --git a/mbfido/dirsession.c b/mbfido/dirsession.c index 4e95a045..6b0c0b15 100644 --- a/mbfido/dirsession.c +++ b/mbfido/dirsession.c @@ -45,7 +45,6 @@ extern int do_unprot; /* * Check for lock, return TRUE if node is locked. */ -int islocked(char *, int, int); int islocked(char *lockfile, int chklck, int waitclr) { int i; @@ -104,7 +103,6 @@ int islocked(char *lockfile, int chklck, int waitclr) * Create a 1 byte lockfile if create is TRUE. * Returns FALSE if failed. */ -int setlock(char *, int); int setlock(char *lockfile, int create) { FILE *fp; @@ -130,7 +128,6 @@ int setlock(char *lockfile, int create) /* * Removing lockfile */ -void remlock(char *, int); void remlock(char *lockfile, int create) { if (create) { diff --git a/mbfido/dirsession.h b/mbfido/dirsession.h index 2539590b..94d5bf95 100644 --- a/mbfido/dirsession.h +++ b/mbfido/dirsession.h @@ -4,7 +4,9 @@ /* $Id$ */ -void dirinbound(void); - +int islocked(char *, int, int); /* Is directory locked */ +int setlock(char *, int); /* Lock directory */ +void remlock(char *, int); /* Unlock directory */ +void dirinbound(void); /* Process nodes */ #endif diff --git a/mbfido/forward.c b/mbfido/forward.c index f0ef4cf0..f5354e22 100644 --- a/mbfido/forward.c +++ b/mbfido/forward.c @@ -44,289 +44,322 @@ #include "rollover.h" #include "mgrutil.h" #include "forward.h" - +#include "dirsession.h" void ForwardFile(fidoaddr Node, fa_list *sbl) { - char *subject = NULL, *temp, *fwdfile = NULL, *ticfile = NULL, fname[PATH_MAX], *ticname; - FILE *fp, *fi, *net; - char flavor; - faddr *dest, *routeto, *Fa, *Temp, *ba; - int i, z, n; - time_t now, ftime; - fa_list *tmp; + char *subject = NULL, *temp, *fwdfile = NULL, *ticfile = NULL, fname[PATH_MAX], *ticname, flavor; + FILE *fp, *fi, *net; + faddr *dest, *routeto, *Fa, *Temp, *ba; + int i, z, n; + time_t now, ftime; + fa_list *tmp; - if (!SearchNode(Node)) { - WriteError("TIC forward in %s, node %s not in setup but defined in area setup", TIC.TicIn.Area, aka2str(Node)); - return; - } - Syslog('+', "Forward file to %s, %s netmail", aka2str(Node), nodes.Message?"with":"without"); + if (!SearchNode(Node)) { + WriteError("TIC forward in %s, node %s not in setup but defined in area setup", TIC.TicIn.Area, aka2str(Node)); + return; + } + Syslog('+', "Forward file to %s, %s netmail", aka2str(Node), nodes.Message?"with":"without"); + /* + * Hier moet een nieuwe SEEN-BY check komen, maar dan wel zo dat + * de net toegevoegde seenby niet getest wordt. + */ + + /* + * If Costsharing active for this node + */ + if (nodes.Billing) { /* - * Hier moet een nieuwe SEEN-BY check komen, maar dan wel zo dat - * de net toegevoegde seenby niet getest wordt. + * Check if this node has enough credits for this file. */ - - /* - * If Costsharing active for this node - */ - if (nodes.Billing) { - /* - * Check if this node has enough credits for this file. - */ - T_File.Cost = TIC.FileCost + (TIC.FileCost * nodes.AddPerc / 1000); - if ((nodes.Credit < (nodes.StopLevel + T_File.Cost)) && (!TIC.Charge)) { - Syslog('!', "No forward to %s, not enough credit left", aka2str(Node)); - exit; - } - - /* - * Check if we are passing the warning level - */ - if ((nodes.Credit > nodes.WarnLevel) && ((nodes.Credit - T_File.Cost) <= nodes.WarnLevel)) { - Syslog('+', "Low credit warning to %s", aka2str(Node)); - /* CREATE NETMAIL */ - } + T_File.Cost = TIC.FileCost + (TIC.FileCost * nodes.AddPerc / 1000); + if ((nodes.Credit < (nodes.StopLevel + T_File.Cost)) && (!TIC.Charge)) { + Syslog('!', "No forward to %s, not enough credit left", aka2str(Node)); + exit; } - fwdfile = calloc(PATH_MAX, sizeof(char)); /* - * Create the full filename + * Check if we are passing the warning level */ - if (TIC.SendOrg) { - sprintf(fwdfile, "%s/%s", TIC.Inbound, TIC.RealName); - subject = xstrcpy(TIC.RealName); + if ((nodes.Credit > nodes.WarnLevel) && ((nodes.Credit - T_File.Cost) <= nodes.WarnLevel)) { + Syslog('+', "Low credit warning to %s", aka2str(Node)); + /* CREATE NETMAIL */ + } + } + + fwdfile = calloc(PATH_MAX, sizeof(char)); + + /* + * Create the full filename + */ + if (TIC.SendOrg) { + sprintf(fwdfile, "%s/%s", TIC.Inbound, TIC.RealName); + subject = xstrcpy(TIC.RealName); + } else { + sprintf(fwdfile, "%s/%s", TIC.BBSpath, TIC.NewName); + subject = xstrcpy(TIC.NewName); + } + + flavor = 'f'; + if (nodes.Crash) + flavor = 'c'; + if (nodes.Hold) + flavor = 'h'; + + if (nodes.RouteVia.zone) + routeto = fido2faddr(nodes.RouteVia); + else + routeto = fido2faddr(Node); + dest = fido2faddr(Node); + if (nodes.Session_out == S_DIR) { + if (islocked(nodes.Dir_out_clock, nodes.Dir_out_chklck, nodes.Dir_out_waitclr)) { + /* + * Not good, should go to a queue + */ + attach(*routeto, fwdfile, LEAVE, flavor); } else { - sprintf(fwdfile, "%s/%s", TIC.BBSpath, TIC.NewName); - subject = xstrcpy(TIC.NewName); + if (! setlock(nodes.Dir_out_mlock, nodes.Dir_out_mklck)) { + /* + * Not good again + */ + attach(*routeto, fwdfile, LEAVE, flavor); + } else { + /* + * Node locked, copy file to destination directory + */ + ticfile = calloc(PATH_MAX, sizeof(char)); + sprintf(ticfile, "%s/%s", nodes.Dir_out_path, subject); + if (file_cp(fwdfile, ticfile)) + WriteError("$Can't copy %s to %s", fwdfile, ticfile); + else + chmod(ticfile, 0660); + free(ticfile); + } } - - flavor = 'f'; - if (nodes.Crash) - flavor = 'c'; - if (nodes.Hold) - flavor = 'h'; - - if (nodes.RouteVia.zone) - routeto = fido2faddr(nodes.RouteVia); - else - routeto = fido2faddr(Node); - dest = fido2faddr(Node); + } else { attach(*routeto, fwdfile, LEAVE, flavor); + } - ticfile = calloc(PATH_MAX, sizeof(char)); - ticname = calloc(15, sizeof(char)); - if (nodes.Tic) { - sprintf(ticname, "%08lx.tic", sequencer()); - subject = xstrcat(subject, (char *)" "); - subject = xstrcat(subject, ticname); - sprintf(ticfile, "%s/%s", CFG.ticout, ticname); + ticfile = calloc(PATH_MAX, sizeof(char)); + ticname = calloc(15, sizeof(char)); + if (nodes.Tic) { + sprintf(ticname, "%08lx.tic", sequencer()); + subject = xstrcat(subject, (char *)" "); + subject = xstrcat(subject, ticname); + if (nodes.Session_out == S_DIR) + sprintf(ticfile, "%s/%s", nodes.Dir_out_path, ticname); + else + sprintf(ticfile, "%s/%s", CFG.ticout, ticname); + } + free(ticname); + + /* + * Send netmail message if the node has it turned on. + */ + if (nodes.Message) { + Temp = fido2faddr(Node); + if ((net = SendMgrMail(Temp, CFG.ct_KeepMgr, TRUE, (char *)"Filemgr", subject, NULL)) != NULL) { + if ((fi = OpenMacro("forward.tic", nodes.Language, FALSE)) != NULL) { + ftime = TIC.FileDate; + MacroVars("a", "s", TIC.TicIn.Area); + MacroVars("b", "s", tic.Comment); + MacroVars("c", "d", TIC.FileCost); + MacroVars("d", "s", fgroup.Comment); + MacroVars("f", "s", TIC.TicIn.FullName); + MacroVars("g", "d", TIC.FileSize); + MacroVars("h", "d", (TIC.FileSize / 1024)); + MacroVars("i", "s", TIC.TicIn.Crc); + MacroVars("j", "s", TIC.TicIn.Origin); + MacroVars("m", "s", rfcdate(ftime)); + MacroVars("n", "s", TIC.TicIn.Desc); + MacroVars("s", "s", nodes.Sysop); + if (TIC.SendOrg) + MacroVars("e", "s", TIC.RealName); + else + MacroVars("e", "s", TIC.NewName); + if (strlen(TIC.TicIn.Magic)) + MacroVars("k", "s", TIC.TicIn.Magic); + if (strlen(TIC.TicIn.Replace)) + MacroVars("l", "s", TIC.TicIn.Replace); + MacroRead(fi, net); + fprintf(net, "%s\r", TearLine()); + CloseMail(net, Temp); + } + } else { + WriteError("$Can't create netmail"); } - free(ticname); + tidy_faddr(Temp); + } + free(subject); - /* - * Send netmail message if the node has it turned on. - */ - if (nodes.Message) { - Temp = fido2faddr(Node); - if ((net = SendMgrMail(Temp, CFG.ct_KeepMgr, TRUE, (char *)"Filemgr", subject, NULL)) != NULL) { - if ((fi = OpenMacro("forward.tic", nodes.Language, FALSE)) != NULL) { - ftime = TIC.FileDate; - MacroVars("a", "s", TIC.TicIn.Area); - MacroVars("b", "s", tic.Comment); - MacroVars("c", "d", TIC.FileCost); - MacroVars("d", "s", fgroup.Comment); - MacroVars("f", "s", TIC.TicIn.FullName); - MacroVars("g", "d", TIC.FileSize); - MacroVars("h", "d", (TIC.FileSize / 1024)); - MacroVars("i", "s", TIC.TicIn.Crc); - MacroVars("j", "s", TIC.TicIn.Origin); - MacroVars("m", "s", rfcdate(ftime)); - MacroVars("n", "s", TIC.TicIn.Desc); - MacroVars("s", "s", nodes.Sysop); - if (TIC.SendOrg) - MacroVars("e", "s", TIC.RealName); - else - MacroVars("e", "s", TIC.NewName); - if (strlen(TIC.TicIn.Magic)) - MacroVars("k", "s", TIC.TicIn.Magic); - if (strlen(TIC.TicIn.Replace)) - MacroVars("l", "s", TIC.TicIn.Replace); - MacroRead(fi, net); - fprintf(net, "%s\r", TearLine()); - CloseMail(net, Temp); + /* + * If we need a .TIC file, start creating it. + */ + if (nodes.Tic) { + mkdirs(ticfile, 0770); + if ((fp = fopen(ticfile, "a+")) != NULL) { + fprintf(fp, "Area %s\r\n", TIC.TicIn.Area); + fprintf(fp, "Origin %s\r\n", TIC.TicIn.Origin); + Fa = fido2faddr(tic.Aka); + fprintf(fp, "From %s\r\n", ascfnode(Fa, 0x0f)); + free(Fa); + if (strlen(TIC.TicIn.Replace)) + fprintf(fp, "Replaces %s\r\n", TIC.TicIn.Replace); + if (strlen(TIC.TicIn.Magic)) + fprintf(fp, "Magic %s\r\n", TIC.TicIn.Magic); + + if ((TIC.PassThru) || (TIC.SendOrg)) + subject = xstrcpy(TIC.RealName); + else + subject = xstrcpy(TIC.NewName); + /* + * Create 8.3 filename if this is a long filename. In normal + * cases mbcico will transmit the long filename to the other + * node. If they can't process the TIC files which has a short + * 8.3 filename and they have a long filename in the inbound + * then in mbsetup these nodes need to be set to 8.3 filenames. + * The mailer will then transmit the file with a 8.3 name. + * Thank the inventors of the 8.3 filenames for this. + */ + temp = xstrcpy(subject); + name_mangle(temp); + fprintf(fp, "File %s\r\n", temp); + fprintf(fp, "Fullname %s\r\n", subject); + free(temp); + free(subject); + + fprintf(fp, "Size %ld\r\n", (long)(TIC.FileSize)); + fprintf(fp, "Desc %s\r\n", TIC.TicIn.Desc); + fprintf(fp, "Crc %s\r\n", TIC.TicIn.Crc); + if (nodes.AdvTic) { + fprintf(fp, "To %s, %s\r\n", nodes.Sysop, ascfnode(dest, 0x1f)); + fprintf(fp, "Areadesc %s\r\n", tic.Comment); + fprintf(fp, "Fdn %s\r\n", fgroup.Comment); + /* + * According to Harald Harms this field must + * be multiplied with 100. + */ + if (TIC.FileCost && nodes.Billing) + fprintf(fp, "Cost %ld.00\r\n", T_File.Cost); + if (TIC.TicIn.TotLDesc) + for (i = 0; i < TIC.TicIn.TotLDesc; i++) + fprintf(fp, "LDesc %s\r\n", TIC.TicIn.LDesc[i]); + } + fprintf(fp, "Created by MBSE BBS %s %s\r\n", VERSION, SHORTRIGHT); + if (TIC.TicIn.TotPath) + for (i = 0; i < TIC.TicIn.TotPath; i++) + fprintf(fp, "Path %s\r\n", TIC.TicIn.Path[i]); + /* + * Add our system to the path + */ + now = time(NULL); + subject = ctime(&now); + Striplf(subject); + ba = bestaka_s(dest); + fprintf(fp, "Path %s %lu %s %s\r\n", ascfnode(ba, 0x1f), mktime(localtime(&now)), subject, tzname[0]); + tidy_faddr(ba); + + if (nodes.AdvTic) { + /* + * In advanced TIC mode we send multiple seenby + * addresses on one line in stead of one line + * per system. + */ + z = 0; + n = 0; + subject = xstrcpy((char *)"Seenby"); + for (tmp = sbl; tmp; tmp = tmp->next) { + if (strlen(subject) > 70) { + fprintf(fp, "%s\r\n", subject); + z = 0; + n = 0; + free(subject); + subject = xstrcpy((char *)"Seenby "); + } else { + subject = xstrcat(subject, (char *)" "); + } + + if (z != tmp->addr->zone) { + subject = xstrcat(subject, ascfnode(tmp->addr, 0x0e)); + z = tmp->addr->zone; + } else { + if (n != tmp->addr->net) { + subject = xstrcat(subject, ascfnode(tmp->addr, 0x06)); + n = tmp->addr->net; + } else { + subject = xstrcat(subject, ascfnode(tmp->addr, 0x02)); + } + } + } + if (strlen(subject) > 7) { + fprintf(fp, "%s\r\n", subject); + free(subject); } } else { - WriteError("$Can't create netmail"); - } - tidy_faddr(Temp); - } - free(subject); - - /* - * If we need a .TIC file, start creating it. - */ - if (nodes.Tic) { - mkdirs(ticfile, 0770); - if ((fp = fopen(ticfile, "a+")) != NULL) { - fprintf(fp, "Area %s\r\n", TIC.TicIn.Area); - fprintf(fp, "Origin %s\r\n", TIC.TicIn.Origin); - Fa = fido2faddr(tic.Aka); - fprintf(fp, "From %s\r\n", ascfnode(Fa, 0x0f)); - free(Fa); - if (strlen(TIC.TicIn.Replace)) - fprintf(fp, "Replaces %s\r\n", TIC.TicIn.Replace); - if (strlen(TIC.TicIn.Magic)) - fprintf(fp, "Magic %s\r\n", TIC.TicIn.Magic); - - if ((TIC.PassThru) || (TIC.SendOrg)) - subject = xstrcpy(TIC.RealName); - else - subject = xstrcpy(TIC.NewName); - /* - * Create 8.3 filename if this is a long filename. In normal - * cases mbcico will transmit the long filename to the other - * node. If they can't process the TIC files which has a short - * 8.3 filename and they have a long filename in the inbound - * then in mbsetup these nodes need to be set to 8.3 filenames. - * The mailer will then transmit the file with a 8.3 name. - * Thank the inventors of the 8.3 filenames for this. - */ - temp = xstrcpy(subject); - name_mangle(temp); - fprintf(fp, "File %s\r\n", temp); - fprintf(fp, "Fullname %s\r\n", subject); - free(temp); - free(subject); - - fprintf(fp, "Size %ld\r\n", (long)(TIC.FileSize)); - fprintf(fp, "Desc %s\r\n", TIC.TicIn.Desc); - fprintf(fp, "Crc %s\r\n", TIC.TicIn.Crc); - if (nodes.AdvTic) { - fprintf(fp, "To %s, %s\r\n", nodes.Sysop, ascfnode(dest, 0x1f)); - fprintf(fp, "Areadesc %s\r\n", tic.Comment); - fprintf(fp, "Fdn %s\r\n", fgroup.Comment); - /* - * According to Harald Harms this field must - * be multiplied with 100. - */ - if (TIC.FileCost && nodes.Billing) - fprintf(fp, "Cost %ld.00\r\n", T_File.Cost); - if (TIC.TicIn.TotLDesc) - for (i = 0; i < TIC.TicIn.TotLDesc; i++) - fprintf(fp, "LDesc %s\r\n", TIC.TicIn.LDesc[i]); - } - fprintf(fp, "Created by MBSE BBS %s %s\r\n", VERSION, SHORTRIGHT); - if (TIC.TicIn.TotPath) - for (i = 0; i < TIC.TicIn.TotPath; i++) - fprintf(fp, "Path %s\r\n", TIC.TicIn.Path[i]); - /* - * Add our system to the path - */ - now = time(NULL); - subject = ctime(&now); - Striplf(subject); - ba = bestaka_s(dest); - fprintf(fp, "Path %s %lu %s %s\r\n", ascfnode(ba, 0x1f), - mktime(localtime(&now)), subject, tzname[0]); - tidy_faddr(ba); - - if (nodes.AdvTic) { - /* - * In advanced TIC mode we send multiple seenby - * addresses on one line in stead of one line - * per system. - */ - z = 0; - n = 0; - subject = xstrcpy((char *)"Seenby"); - for (tmp = sbl; tmp; tmp = tmp->next) { - if (strlen(subject) > 70) { - fprintf(fp, "%s\r\n", subject); - z = 0; - n = 0; - free(subject); - subject = xstrcpy((char *)"Seenby "); - } else { - subject = xstrcat(subject, (char *)" "); - } - - if (z != tmp->addr->zone) { - subject = xstrcat(subject, ascfnode(tmp->addr, 0x0e)); - z = tmp->addr->zone; - } else { - if (n != tmp->addr->net) { - subject = xstrcat(subject, ascfnode(tmp->addr, 0x06)); - n = tmp->addr->net; - } else { - subject = xstrcat(subject, ascfnode(tmp->addr, 0x02)); - } - } - } - if (strlen(subject) > 7) { - fprintf(fp, "%s\r\n", subject); - free(subject); - } - } else { - /* - * Old style seenby lines - */ - for (tmp = sbl; tmp; tmp = tmp->next) { - fprintf(fp, "Seenby %s\r\n", ascfnode(tmp->addr, 0x0f)); - } - } - - /* - * Now append all passthru ticlines - */ - if (TIC.TicIn.Unknowns) - for (i = 0; i < TIC.TicIn.Unknowns; i++) - fprintf(fp, "%s\r\n", TIC.TicIn.Unknown[i]); - - fprintf(fp, "Pw %s\r\n", nodes.Fpasswd); - fclose(fp); - attach(*routeto, ticfile, KFS, flavor); - } else { - WriteError("$Can't create %s", ticfile); - } - } - - if (TIC.Charge && nodes.Billing) { - nodes.Credit -= TIC.FileCost; - Syslog('-', "Cost: %d Left: %d", TIC.FileCost, nodes.Credit); - /* - * Add an entry to the billing file, each node has his own - * billing file. + * Old style seenby lines */ - sprintf(fname, "%s/tmp/%d.%d.%d.%d.bill", getenv("MBSE_ROOT"), - nodes.Aka[0].zone, nodes.Aka[0].net, nodes.Aka[0].node, nodes.Aka[0].point); - if ((fp = fopen(fname, "a+")) != NULL) { - memset(&bill, 0, sizeof(bill)); - bill.Node = nodes.Aka[0]; - strcpy(bill.FileName, TIC.NewName); - strcpy(bill.FileEcho, TIC.TicIn.Area); - bill.Size = TIC.FileSize; - bill.Cost = TIC.FileCost; - fwrite(&bill, sizeof(bill), 1, fp); - fclose(fp); - } else { - WriteError("$Can't create %s", fname); + for (tmp = sbl; tmp; tmp = tmp->next) { + fprintf(fp, "Seenby %s\r\n", ascfnode(tmp->addr, 0x0f)); } + } + + /* + * Now append all passthru ticlines + */ + if (TIC.TicIn.Unknowns) + for (i = 0; i < TIC.TicIn.Unknowns; i++) + fprintf(fp, "%s\r\n", TIC.TicIn.Unknown[i]); + + fprintf(fp, "Pw %s\r\n", nodes.Fpasswd); + fclose(fp); + if (nodes.Session_out == S_DIRECT) + attach(*routeto, ticfile, KFS, flavor); + } else { + WriteError("$Can't create %s", ticfile); } + } + + if (TIC.Charge && nodes.Billing) { + nodes.Credit -= TIC.FileCost; + Syslog('-', "Cost: %d Left: %d", TIC.FileCost, nodes.Credit); /* - * Update the nodes statistic counters + * Add an entry to the billing file, each node has his own + * billing file. */ - StatAdd(&nodes.FilesSent, 1L); - StatAdd(&nodes.F_KbSent, T_File.SizeKb); - UpdateNode(); - SearchNode(Node); - free(ticfile); - free(fwdfile); - tidy_faddr(routeto); + sprintf(fname, "%s/tmp/%d.%d.%d.%d.bill", getenv("MBSE_ROOT"), + nodes.Aka[0].zone, nodes.Aka[0].net, nodes.Aka[0].node, nodes.Aka[0].point); + if ((fp = fopen(fname, "a+")) != NULL) { + memset(&bill, 0, sizeof(bill)); + bill.Node = nodes.Aka[0]; + strcpy(bill.FileName, TIC.NewName); + strcpy(bill.FileEcho, TIC.TicIn.Area); + bill.Size = TIC.FileSize; + bill.Cost = TIC.FileCost; + fwrite(&bill, sizeof(bill), 1, fp); + fclose(fp); + } else { + WriteError("$Can't create %s", fname); + } + } + + if (nodes.Session_out == S_DIR) + remlock(nodes.Dir_out_mlock, nodes.Dir_out_mklck); + + /* + * Update the nodes statistic counters + */ + StatAdd(&nodes.FilesSent, 1L); + StatAdd(&nodes.F_KbSent, T_File.SizeKb); + UpdateNode(); + SearchNode(Node); + free(ticfile); + free(fwdfile); + tidy_faddr(routeto); } diff --git a/mbfido/pack.c b/mbfido/pack.c index af5100dd..481d3826 100644 --- a/mbfido/pack.c +++ b/mbfido/pack.c @@ -38,12 +38,17 @@ #include "../lib/dbftn.h" #include "../lib/clcomm.h" #include "../lib/dbnode.h" +#include "dirsession.h" #include "pack.h" extern int do_quiet; /* Quiet flag */ +static char *dow[] = {(char *)"su", (char *)"mo", (char *)"tu", (char *)"we", + (char *)"th", (char *)"fr", (char *)"sa"}; + + /* * Pack queued arcmail mail for a node. If the node is locked, the mail won't * be packed, and the queue stays as it is. The mail will then be packed @@ -51,227 +56,296 @@ extern int do_quiet; /* Quiet flag */ */ int pack_queue(char *name) { - FILE *fp; - faddr noden; - fidoaddr nodenr; - char flavor, nr, oldnr, maxnr; - char srcfile[128], *arcfile, *pktfile; - int Attach, fage; - long fsize; - time_t Now; + FILE *fp; + faddr noden, *bestaka; + fidoaddr nodenr; + char flavor, nr, oldnr, maxnr, *ext, srcfile[128], *arcfile, *pktfile; + int Attach, fage; + long fsize; + time_t Now; + struct tm *ptm; - sprintf(srcfile, "%s", name); + sprintf(srcfile, "%s", name); + /* + * Get the nodenumber from the filename + */ + noden.domain = NULL; + noden.name = NULL; + noden.zone = atoi(strtok(name, ".")); + noden.net = atoi(strtok(NULL, ".")); + noden.node = atoi(strtok(NULL, ".")); + noden.point = atoi(strtok(NULL, ".")); + if (SearchFidonet(noden.zone)) + noden.domain = xstrcpy(fidonet.domain); + + memset(&nodenr, 0, sizeof(nodenr)); + nodenr.zone = noden.zone; + nodenr.net = noden.net; + nodenr.node = noden.node; + nodenr.point = noden.point; + sprintf(nodenr.domain, "%s", noden.domain); + + if (!SearchNode(nodenr)) { + WriteError("Downlink %s not found", aka2str(nodenr)); + if (noden.domain) + free(noden.domain); + return FALSE; + } + + /* + * If we route via another aka, change everything. + */ + if (nodes.RouteVia.zone) { + Syslog('p', "Route Via %s", aka2str(nodes.RouteVia)); + noden.zone = nodes.RouteVia.zone; + noden.net = nodes.RouteVia.net; + noden.node = nodes.RouteVia.node; + noden.point = nodes.RouteVia.point; + if (noden.domain) + free(noden.domain); + noden.domain = xstrcpy(nodes.RouteVia.domain); /* - * Get the nodenumber from the filename + * Load routevia noderecord to get the correct flavor. + * If there is no noderecord, reload the old one. */ - noden.domain = NULL; - noden.name = NULL; - noden.zone = atoi(strtok(name, ".")); - noden.net = atoi(strtok(NULL, ".")); - noden.node = atoi(strtok(NULL, ".")); - noden.point = atoi(strtok(NULL, ".")); - if (SearchFidonet(noden.zone)) - noden.domain = xstrcpy(fidonet.domain); + if (!SearchNode(nodes.RouteVia)) + SearchNode(nodenr); + } - memset(&nodenr, 0, sizeof(nodenr)); - nodenr.zone = noden.zone; - nodenr.net = noden.net; - nodenr.node = noden.node; - nodenr.point = noden.point; - sprintf(nodenr.domain, "%s", noden.domain); + Syslog('+', "Pack ARCmail for %s, via %s", aka2str(nodenr), ascfnode(&noden, 0x1f)); - if (!SearchNode(nodenr)) { - WriteError("Downlink %s not found", aka2str(nodenr)); - if (noden.domain) - free(noden.domain); - return FALSE; - } + if (!do_quiet) { + printf("\rAdding ARCmail for %s ", ascfnode(&noden, 0x1f)); + fflush(stdout); + } - /* - * If we route via another aka, change everything. - */ - if (nodes.RouteVia.zone) { - Syslog('p', "Route Via %s", aka2str(nodes.RouteVia)); - noden.zone = nodes.RouteVia.zone; - noden.net = nodes.RouteVia.net; - noden.node = nodes.RouteVia.node; - noden.point = nodes.RouteVia.point; - if (noden.domain) - free(noden.domain); - noden.domain = xstrcpy(nodes.RouteVia.domain); - /* - * Load routevia noderecord to get the correct flavor. - * If there is no noderecord, reload the old one. - */ - if (!SearchNode(nodes.RouteVia)) - SearchNode(nodenr); - } + if (getarchiver((char *)"ZIP")) { + flavor = 'f'; + if (nodes.Crash) + flavor = 'c'; + if (nodes.Hold) + flavor = 'h'; + } else { + WriteError("Archiver ZIP not found"); + if (noden.domain) + free(noden.domain); + return FALSE; + } - Syslog('+', "Pack ARCmail for %s, via %s", aka2str(nodenr), ascfnode(&noden, 0x1f)); + /* + * Generate ARCmail filename and .PKT filename, + */ + arcfile = calloc(PATH_MAX, sizeof(char)); + if (nodes.Session_out == S_DIR) { - if (!do_quiet) { - printf("\rAdding ARCmail for %s ", ascfnode(&noden, 0x1f)); - fflush(stdout); - } + Now = time(NULL); + ptm = localtime(&Now); + ext = dow[ptm->tm_wday]; - if (getarchiver((char *)"ZIP")) { - flavor = 'f'; - if (nodes.Crash) - flavor = 'c'; - if (nodes.Hold) - flavor = 'h'; + if (!nodes.ARCmailCompat && (nodes.Aka[0].zone != noden.zone)) { + /* + * Generate ARCfile name from the CRC of the ASCII string + * of the node address. + */ + sprintf(arcfile, "%s/%08lx.%s0", nodes.Dir_out_path, StringCRC32(ascfnode(&noden, 0x1f)), ext); } else { - WriteError("Archiver ZIP not found"); - if (noden.domain) - free(noden.domain); - return FALSE; + bestaka = bestaka_s(&noden); + + if (noden.point) { + sprintf(arcfile, "%s/%04x%04x.%s0", nodes.Dir_out_path, ((bestaka->net) - (noden.net)) & 0xffff, + ((bestaka->node) - (noden.node) + (noden.point)) & 0xffff, ext); + } else if (bestaka->point) { + /* + * Inserted the next code for if we are a point, + * I hope this is ARCmail 0.60 compliant. 21-May-1999 + */ + sprintf(arcfile, "%s/%04x%04x.%s0", nodes.Dir_out_path, ((bestaka->net) - (noden.net)) & 0xffff, + ((bestaka->node) - (noden.node) - (bestaka->point)) & 0xffff, ext); + } else { + sprintf(arcfile, "%s/%04x%04x.%s0", nodes.Dir_out_path, ((bestaka->net) - (noden.net)) & 0xffff, + ((bestaka->node) - (noden.node)) &0xffff, ext); + } } - - /* - * Generate ARCmail filename and .PKT filename, - */ - arcfile = calloc(PATH_MAX, sizeof(char)); + Syslog('m', "Arcmail file %s", arcfile); + } else { sprintf(arcfile, "%s", arcname(&noden, nodes.Aka[0].zone, nodes.ARCmailCompat)); - pktfile = calloc(40, sizeof(char)); - sprintf(pktfile, "%08lx.pkt", sequencer()); + } + pktfile = calloc(40, sizeof(char)); + sprintf(pktfile, "%08lx.pkt", sequencer()); - if (nodelock(&noden)) { + if (nodes.Session_out == S_DIR) { + if (islocked(nodes.Dir_out_clock, nodes.Dir_out_chklck, nodes.Dir_out_waitclr)) { + Syslog('+', "Mail stays in queue, will be added later"); + if (noden.domain) + free(noden.domain); + free(arcfile); + free(pktfile); + return FALSE; + } else { + if (! setlock(nodes.Dir_out_mlock, nodes.Dir_out_mklck)) { Syslog('+', "Mail stays in queue, will be added later"); if (noden.domain) - free(noden.domain); + free(noden.domain); free(arcfile); free(pktfile); return FALSE; + } } - - if (rename(srcfile, pktfile)) { - WriteError("$Can't rename %s to %s", srcfile, pktfile); - nodeulock(&noden); - if (noden.domain) - free(noden.domain); - free(arcfile); - free(pktfile); - return FALSE; + } else { + if (nodelock(&noden)) { + Syslog('+', "Mail stays in queue, will be added later"); + if (noden.domain) + free(noden.domain); + free(arcfile); + free(pktfile); + return FALSE; } + } - /* - * Add zero word at the end of the .pkt file - */ - if ((fp = fopen(pktfile, "a+")) == NULL) { - WriteError("$Can't open %s", pktfile); - nodeulock(&noden); - if (noden.domain) - free(noden.domain); - free(arcfile); - free(pktfile); - return FALSE; - } - putc('\0', fp); - putc('\0', fp); - fsync(fileno(fp)); - fclose(fp); - - /* - * Check the size of the existing archive if there is a size limit. - * Change to new archive names if the existing is too large. - * If the archive size is zero, it's an already sent archive, the - * number will be bumped also. - * If the archive is older then 6 days, the name is also bumped. - * Do this until we find a new name or if the last digit is a '9' or 'z'. - * Purge archives older then toss_days. - */ - nr = oldnr = '0'; - Now = time(NULL); - if (nodes.ARCmailAlpha) - maxnr = 'z'; + if (rename(srcfile, pktfile)) { + WriteError("$Can't rename %s to %s", srcfile, pktfile); + if (nodes.Session_out == S_DIR) + remlock(nodes.Dir_out_mlock, nodes.Dir_out_mklck); else - maxnr = '9'; - Attach = FALSE; + nodeulock(&noden); + if (noden.domain) + free(noden.domain); + free(arcfile); + free(pktfile); + return FALSE; + } - for (;;) { - fsize = file_size(arcfile); - fage = (int)((Now - file_time(arcfile)) / 86400); + /* + * Add zero word at the end of the .pkt file + */ + if ((fp = fopen(pktfile, "a+")) == NULL) { + WriteError("$Can't open %s", pktfile); + if (nodes.Session_out == S_DIR) + remlock(nodes.Dir_out_mlock, nodes.Dir_out_mklck); + else + nodeulock(&noden); + if (noden.domain) + free(noden.domain); + free(arcfile); + free(pktfile); + return FALSE; + } + putc('\0', fp); + putc('\0', fp); + fsync(fileno(fp)); + fclose(fp); - if (fsize == -1L) { - Attach = TRUE; - break; - } + /* + * Check the size of the existing archive if there is a size limit. + * Change to new archive names if the existing is too large. + * If the archive size is zero, it's an already sent archive, the + * number will be bumped also. + * If the archive is older then 6 days, the name is also bumped. + * Do this until we find a new name or if the last digit is a '9' or 'z'. + * Purge archives older then toss_days. + */ + nr = oldnr = '0'; + Now = time(NULL); + if (nodes.ARCmailAlpha) + maxnr = 'z'; + else + maxnr = '9'; + Attach = FALSE; - if (fsize == 0L) { - if ((fage > 6) && (nr < maxnr)) { - /* - * Remove truncated ARCmail files older then 6 days. - */ - unlink(arcfile); - fsize = -1L; - Attach = TRUE; - break; - } - /* - * Increase filename extension if there is a truncated file of today. - */ - nr++; - if (nr == ('9' +1)) - nr = 'a'; - arcfile[strlen(arcfile) -1] = nr; + for (;;) { + fsize = file_size(arcfile); + fage = (int)((Now - file_time(arcfile)) / 86400); - } else if (CFG.maxarcsize && (fsize > (CFG.maxarcsize * 1024)) && (nr < maxnr)) { - /* - * Use a new ARCmail file if the last one is too big. - */ - nr++; - if (nr == ('9' +1)) - nr = 'a'; - arcfile[strlen(arcfile) -1] = nr; - } + if (fsize == -1L) { + Attach = TRUE; + break; + } - fsize = file_size(arcfile); - fage = (int)((Now - file_time(arcfile)) / 86400); + if (fsize == 0L) { + if ((fage > 6) && (nr < maxnr)) { + /* + * Remove truncated ARCmail files older then 6 days. + */ + unlink(arcfile); + fsize = -1L; + Attach = TRUE; + break; + } + /* + * Increase filename extension if there is a truncated file of today. + */ + nr++; + if (nr == ('9' +1)) + nr = 'a'; + arcfile[strlen(arcfile) -1] = nr; - if ((fsize > 0L) && (fage > 6) && (nr < maxnr)) { - /* - * If there is ARCmail of a week old or older, add mail - * to a new ARCmail bundle. - */ - nr++; - if (nr == ('9' +1)) - nr = 'a'; - arcfile[strlen(arcfile) -1] = nr; - } - - if (oldnr == nr) - break; - else - oldnr = nr; + } else if (CFG.maxarcsize && (fsize > (CFG.maxarcsize * 1024)) && (nr < maxnr)) { + /* + * Use a new ARCmail file if the last one is too big. + */ + nr++; + if (nr == ('9' +1)) + nr = 'a'; + arcfile[strlen(arcfile) -1] = nr; } fsize = file_size(arcfile); - if (execute(archiver.marc, arcfile, pktfile, (char *)"/dev/null", (char *)"/dev/null", (char *)"/dev/null") == 0) { - unlink(pktfile); - } else { - sync(); - sleep(1); - Syslog('+', "Create ARCmail failed, trying again after sync()"); - if (execute(archiver.marc, arcfile, pktfile, (char *)"/dev/null", (char *)"/dev/null", (char *)"/dev/null") == 0) { - unlink(pktfile); - } else { - WriteError("Can't add %s to ARCmail archive", pktfile); - } + fage = (int)((Now - file_time(arcfile)) / 86400); + + if ((fsize > 0L) && (fage > 6) && (nr < maxnr)) { + /* + * If there is ARCmail of a week old or older, add mail + * to a new ARCmail bundle. + */ + nr++; + if (nr == ('9' +1)) + nr = 'a'; + arcfile[strlen(arcfile) -1] = nr; } - /* - * Attach file to .flo - */ - if (Attach) - attach(noden, arcfile, TFS, flavor); + if (oldnr == nr) + break; + else + oldnr = nr; + } + fsize = file_size(arcfile); + if (execute(archiver.marc, arcfile, pktfile, (char *)"/dev/null", (char *)"/dev/null", (char *)"/dev/null") == 0) { + unlink(pktfile); + } else { + sync(); + sleep(1); + Syslog('+', "Create ARCmail failed, trying again after sync()"); + if (execute(archiver.marc, arcfile, pktfile, (char *)"/dev/null", (char *)"/dev/null", (char *)"/dev/null") == 0) { + unlink(pktfile); + } else { + WriteError("Can't add %s to ARCmail archive", pktfile); + } + } + + if (nodes.Session_out == S_DIR) { + /* + * Change filemode so downlink has rights to the file. + */ + chmod(arcfile, 0660); + } + + /* + * Attach file to .flo, not for FTP or Directory sessions. + */ + if (Attach && nodes.Session_out == S_DIRECT) + attach(noden, arcfile, TFS, flavor); + + if (nodes.Session_out == S_DIR) + remlock(nodes.Dir_out_mlock, nodes.Dir_out_mklck); + else nodeulock(&noden); - if (noden.domain) - free(noden.domain); - free(arcfile); - free(pktfile); - return TRUE; + if (noden.domain) + free(noden.domain); + free(arcfile); + free(pktfile); + return TRUE; } @@ -282,95 +356,128 @@ int pack_queue(char *name) */ int add_queue(char *name) { - faddr noden; - char flavor; - char srcfile[128], *outfile; - char *buf; - FILE *inf, *ouf; - int bread; + faddr noden; + char flavor, srcfile[128], *outfile, *buf; + FILE *inf, *ouf; + int bread; - sprintf(srcfile, "%s", name); + sprintf(srcfile, "%s", name); - /* - * Get the nodenumber from the filename - */ - noden.domain = NULL; - noden.name = NULL; - noden.zone = atoi(strtok(name, ".")); - noden.net = atoi(strtok(NULL, ".")); - noden.node = atoi(strtok(NULL, ".")); - noden.point = atoi(strtok(NULL, ".")); - if (SearchFidonet(noden.zone)) - noden.domain = xstrcpy(fidonet.domain); + /* + * Get the nodenumber from the filename + */ + noden.domain = NULL; + noden.name = NULL; + noden.zone = atoi(strtok(name, ".")); + noden.net = atoi(strtok(NULL, ".")); + noden.node = atoi(strtok(NULL, ".")); + noden.point = atoi(strtok(NULL, ".")); + if (SearchFidonet(noden.zone)) + noden.domain = xstrcpy(fidonet.domain); - Syslog('+', "Add Netmail for %s", ascfnode(&noden, 0x1f)); - if (!do_quiet) { - printf("\rAdding Netmail for %s ", ascfnode(&noden, 0x1f)); - fflush(stdout); - } + Syslog('+', "Add Netmail for %s", ascfnode(&noden, 0x1f)); + if (!do_quiet) { + printf("\rAdding Netmail for %s ", ascfnode(&noden, 0x1f)); + fflush(stdout); + } - outfile = calloc(128, sizeof(char)); - if (strstr(srcfile, ".iii")) - flavor = 'i'; - else if (strstr(srcfile, ".ccc")) - flavor = 'c'; - else if (strstr(srcfile, ".hhh")) - flavor = 'h'; + outfile = calloc(PATH_MAX, sizeof(char)); + if (strstr(srcfile, ".iii")) + flavor = 'i'; + else if (strstr(srcfile, ".ccc")) + flavor = 'c'; + else if (strstr(srcfile, ".hhh")) + flavor = 'h'; + else + flavor = 'f'; + if (nodes.Session_out == S_DIR) { + if (flavor == 'f') + flavor = 'o'; + if (noden.point) + sprintf(outfile, "%s/%08x.%cut", nodes.Dir_out_path, noden.point, flavor); else - flavor = 'f'; + sprintf(outfile, "%s/%04x%04x.%cut", nodes.Dir_out_path, noden.net, noden.node, flavor); + } else { sprintf(outfile, "%s", pktname(&noden, flavor)); - Syslog('p', "Outfile: %s", outfile); + } + Syslog('p', "Outfile: %s", outfile); - if (nodelock(&noden)) { - Syslog('+', "Mail stays in queue, will be added later"); - free(outfile); - if (noden.domain) - free(noden.domain); - return FALSE; - } - - /* - * Now we must see if there is already mail in the outbound. - * If that's the case, we must skip the .pkt header from the queue - * because there is already a .pkt header also, append to the - * outbound 2 bytes before the end of file, this is the zero word. - */ - if ((inf = fopen(srcfile, "r")) != NULL) { - if (access(outfile, R_OK) == -1) { - ouf = fopen(outfile, "w"); /* create new */ - Syslog('p', "Create new %s", outfile); - } else { - ouf = fopen(outfile, "r+"); /* open R/W */ - fseek(ouf, -2, SEEK_END); /* b4 0 word */ - fseek(inf, 58, SEEK_SET); /* skip header */ - Syslog('p', "Append to %s", outfile); - } - if (ouf != NULL) { - buf = malloc(16384); - - do { - bread = fread(buf, 1, 16384, inf); - fwrite(buf, 1, bread, ouf); - } while (bread); - - free(buf); - putc('\0', ouf); - putc('\0', ouf); - fsync(fileno(ouf)); - fclose(ouf); - fclose(inf); - unlink(srcfile); - } else { - WriteError("$Can't open %s", outfile); - fclose(inf); - } - } - - nodeulock(&noden); - if (noden.domain) + if (nodes.Session_out == S_DIR) { + if (islocked(nodes.Dir_out_clock, nodes.Dir_out_chklck, nodes.Dir_out_waitclr)) { + Syslog('+', "Mail stays in queue, will be added later"); + if (noden.domain) free(noden.domain); - free(outfile); - return TRUE; + return FALSE; + } else { + if (! setlock(nodes.Dir_out_mlock, nodes.Dir_out_mklck)) { + Syslog('+', "Mail stays in queue, will be added later"); + if (noden.domain) + free(noden.domain); + return FALSE; + } + } + } else { + if (nodelock(&noden)) { + Syslog('+', "Mail stays in queue, will be added later"); + free(outfile); + if (noden.domain) + free(noden.domain); + return FALSE; + } + } + + /* + * Now we must see if there is already mail in the outbound. + * If that's the case, we must skip the .pkt header from the queue + * because there is already a .pkt header also, append to the + * outbound 2 bytes before the end of file, this is the zero word. + */ + if ((inf = fopen(srcfile, "r")) != NULL) { + if (access(outfile, R_OK) == -1) { + ouf = fopen(outfile, "w"); /* create new */ + Syslog('p', "Create new %s", outfile); + } else { + ouf = fopen(outfile, "r+"); /* open R/W */ + fseek(ouf, -2, SEEK_END); /* b4 0 word */ + fseek(inf, 58, SEEK_SET); /* skip header */ + Syslog('p', "Append to %s", outfile); + } + if (ouf != NULL) { + buf = malloc(16384); + + do { + bread = fread(buf, 1, 16384, inf); + fwrite(buf, 1, bread, ouf); + } while (bread); + + free(buf); + putc('\0', ouf); + putc('\0', ouf); + fsync(fileno(ouf)); + fclose(ouf); + fclose(inf); + unlink(srcfile); + } else { + WriteError("$Can't open %s", outfile); + fclose(inf); + } + } + + if (nodes.Session_out == S_DIR) { + /* + * Change filemode so downlink has rights to the file. + */ + chmod(outfile, 0660); + } + + if (nodes.Session_out == S_DIR) + remlock(nodes.Dir_out_mlock, nodes.Dir_out_mklck); + else + nodeulock(&noden); + if (noden.domain) + free(noden.domain); + free(outfile); + return TRUE; } @@ -380,53 +487,52 @@ int add_queue(char *name) */ void packmail() { - char *temp; - struct dirent *de; - DIR *dp; + char *temp; + struct dirent *de; + DIR *dp; - if (!diskfree(CFG.freespace)) - return; + if (!diskfree(CFG.freespace)) + return; - IsDoing("Packing mail"); - if (!do_quiet) { - colour(9, 0); - printf("Packing mail\n"); - colour(3, 0); - } + IsDoing("Packing mail"); + if (!do_quiet) { + colour(9, 0); + printf("Packing mail\n"); + colour(3, 0); + } - temp = calloc(PATH_MAX, sizeof(char)); - sprintf(temp, "%s/tmp", getenv("MBSE_ROOT")); + temp = calloc(PATH_MAX, sizeof(char)); + sprintf(temp, "%s/tmp", getenv("MBSE_ROOT")); - if (chdir(temp) == -1) { - WriteError("$Error chdir to %s", temp); - free(temp); - return; - } - - if ((dp = opendir(temp)) == NULL) { - WriteError("$Error opendir %s", temp); - free(temp); - return; - } - - /* - * Scan the $MBSE_ROOT/tmp directory for .qqq or .nnn files - */ - while ((de = readdir(dp))) { - if (strstr(de->d_name, ".qqq")) - pack_queue(de->d_name); - if (strstr(de->d_name, ".nnn") || strstr(de->d_name, ".iii") || - strstr(de->d_name, ".ccc") || strstr(de->d_name, ".hhh")) - add_queue(de->d_name); - } - - closedir(dp); + if (chdir(temp) == -1) { + WriteError("$Error chdir to %s", temp); free(temp); + return; + } - if (!do_quiet) { - printf("\r \r"); - fflush(stdout); - } + if ((dp = opendir(temp)) == NULL) { + WriteError("$Error opendir %s", temp); + free(temp); + return; + } + + /* + * Scan the $MBSE_ROOT/tmp directory for .qqq or .nnn files + */ + while ((de = readdir(dp))) { + if (strstr(de->d_name, ".qqq")) + pack_queue(de->d_name); + if (strstr(de->d_name, ".nnn") || strstr(de->d_name, ".iii") || strstr(de->d_name, ".ccc") || strstr(de->d_name, ".hhh")) + add_queue(de->d_name); + } + + closedir(dp); + free(temp); + + if (!do_quiet) { + printf("\r \r"); + fflush(stdout); + } }