diff --git a/ChangeLog b/ChangeLog index ad15c948..f260ca3f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4626,6 +4626,10 @@ v0.33.20 10-Feb-2002 diesel.a New library for parsing macro templates. + msgbase.a: + Improved logging for opening message bases. + Added function to delete a JAM message base. + mbsetup: In message groups added default settings for auto area creation. @@ -4730,6 +4734,12 @@ v0.33.20 10-Feb-2002 The mbfido web command now uses macro templates. Areamgr uplink requests the sender name is now set to the sysop's name, so he/she will get to read the responses. + New command: areas. This will read all defined area lists for + files and mail groups that have the Auto Change set to Yes. + Missing areas are created, areas not present anymore are + removed if they are empty. Good for bulk areas create. + When missing areas are created, uplink requests are sent to + connect the areas. mbmsg: When creating non-existend message bases, the path is created diff --git a/lib/jammsg.c b/lib/jammsg.c index 5fab447c..01cfa00d 100644 --- a/lib/jammsg.c +++ b/lib/jammsg.c @@ -10,7 +10,7 @@ * MBSE BBS and utilities. * ***************************************************************************** - * Copyright (C) 1997-2001 + * Copyright (C) 1997-2002 * * Michiel Broek FIDO: 2:280/2802 * Beekmansbos 10 @@ -312,6 +312,28 @@ int JAM_Delete(unsigned long ulMsg) +/* + * Delete JAM area files + */ +void JAM_DeleteJAM(char *Base) +{ + char *temp; + + temp = calloc(PATH_MAX, sizeof(char)); + sprintf(temp, "%s%s", Base, EXT_HDRFILE); + unlink(temp); + sprintf(temp, "%s%s", Base, EXT_IDXFILE); + unlink(temp); + sprintf(temp, "%s%s", Base, EXT_TXTFILE); + unlink(temp); + sprintf(temp, "%s%s", Base, EXT_LRDFILE); + unlink(temp); + free(temp); + Syslog('+', "JAM deleted %s", Base); +} + + + /* * Search for requested LastRead record. */ @@ -528,6 +550,7 @@ int JAM_Open(char *Msgbase) lseek(fdHdr, 0, SEEK_SET); write(fdHdr, &jamHdrInfo, sizeof(JAMHDRINFO)); + Syslog('+', "JAM created %s", Msgbase); } if (jamHdrInfo.Signature[0] == Signature[0] && @@ -553,6 +576,9 @@ int JAM_Open(char *Msgbase) Msg.Id = 0L; free(File); + if (!RetVal) + WriteError("JAM error open %s", Msgbase); + return RetVal; } diff --git a/lib/jammsg.h b/lib/jammsg.h index a87e6493..53737fef 100644 --- a/lib/jammsg.h +++ b/lib/jammsg.h @@ -1,3 +1,5 @@ +/* $Id$ */ + #ifndef _JAMMSG_H #define _JAMMSG_H @@ -5,6 +7,7 @@ int JAM_AddMsg(void); void JAM_Close(void); int JAM_Delete(unsigned long); +void JAM_DeleteJAM(char *); int JAM_GetLastRead(lastread *); unsigned long JAM_Highest(void); int JAM_Lock(unsigned long); diff --git a/lib/msg.c b/lib/msg.c index eb68ade5..d8c37aaf 100644 --- a/lib/msg.c +++ b/lib/msg.c @@ -1,11 +1,10 @@ /***************************************************************************** * - * File ..................: msg.c + * $Id$ * Purpose ...............: Global message base functions - * Last modification date : 20-Dec-1998 * ***************************************************************************** - * Copyright (C) 1997-1998 + * Copyright (C) 1997-2002 * * Michiel Broek FIDO: 2:280/2802 * Beekmansbos 10 @@ -132,6 +131,16 @@ int Msg_Delete(unsigned long ulMsg) +/* + * Delete message base + */ +void Msg_DeleteMsgBase(char *Base) +{ + JAM_DeleteJAM(Base); +} + + + int Msg_GetLastRead(lastread *LR) { return JAM_GetLastRead(LR); diff --git a/lib/msg.h b/lib/msg.h index f5c4a0bb..4d342cbc 100644 --- a/lib/msg.h +++ b/lib/msg.h @@ -1,3 +1,5 @@ +/* $Id$ */ + #ifndef _MSG_H #define _MSG_H @@ -117,6 +119,7 @@ long tell(int); int Msg_AddMsg(void); void Msg_Close(void); int Msg_Delete(unsigned long); +void Msg_DeleteMsgBase(char *); int Msg_GetLastRead(lastread *); unsigned long Msg_Highest(void); int Msg_Lock(unsigned long); diff --git a/mbfido/mgrutil.c b/mbfido/mgrutil.c index dee7d855..8a8d973b 100644 --- a/mbfido/mgrutil.c +++ b/mbfido/mgrutil.c @@ -495,9 +495,9 @@ void fill_arealist(AreaList **fdp, char *tag, int DoDelete) int Areas(void) { FILE *gp, *ap, *fp; - char *temp, *buf, *tag; + char *temp, *buf, *tag, *desc, *p; AreaList *alist = NULL, *tmp; - int i, Found; + int i, count = 0, Found; sysconnect System; Syslog('+', "Process areas taglists"); @@ -583,7 +583,9 @@ int Areas(void) } /* - * Now remove deleted areas + * Now remove deleted areas. If there are messages in the area, + * the area is set to read-only and all links are disconnected. + * If the area is empty, it is removed from the setup. */ sprintf(temp, "%s/etc/mareas.data", getenv("MBSE_ROOT")); if ((fp = fopen(temp, "r+")) == NULL) { @@ -597,20 +599,33 @@ int Areas(void) while (fread(&msgs, msgshdr.recsize, 1, fp) == 1) { if (msgs.Active && !strcmp(msgs.Group, mgroup.Name) && !strcmp(msgs.Tag, tmp->Name)) { fseek(fp, - msgshdr.recsize, SEEK_CUR); - Syslog('+', "Removing message area %d, %s", - ((ftell(fp) - msgshdr.hdrsize) / (msgshdr.recsize + msgshdr.syssize)) + 1, msgs.Tag); - memset(&msgs, 0, sizeof(msgs)); - msgs.DaysOld = CFG.defdays; - msgs.MaxMsgs = CFG.defmsgs; - msgs.Type = ECHOMAIL; - msgs.MsgKinds = PUBLIC; - msgs.UsrDelete = TRUE; - msgs.Rfccode = CHRS_DEFAULT_RFC; - msgs.Ftncode = CHRS_DEFAULT_FTN; - msgs.MaxArticles = CFG.maxarticles; - strcpy(msgs.Origin, CFG.origin); - memset(&System, 0, sizeof(System)); + sprintf(temp, "%s.jhr", msgs.Base); + if (strlen(msgs.Base) && (file_size(temp) != 1024)) { + Syslog('+', "Marking message area %d, %s read-only", + ((ftell(fp) - msgshdr.hdrsize) / (msgshdr.recsize + msgshdr.syssize)) + 1, + msgs.Tag); + msgs.MsgKinds = RONLY; // Area read-only + sprintf(msgs.Group, "DELETED"); // Make groupname invalid + } else { + Syslog('+', "Removing empty message area %d, %s", + ((ftell(fp) - msgshdr.hdrsize) / (msgshdr.recsize + msgshdr.syssize)) + 1, + msgs.Tag); + memset(&msgs, 0, sizeof(msgs)); + msgs.DaysOld = CFG.defdays; + msgs.MaxMsgs = CFG.defmsgs; + msgs.Type = ECHOMAIL; + msgs.MsgKinds = PUBLIC; + msgs.UsrDelete = TRUE; + msgs.Rfccode = CHRS_DEFAULT_RFC; + msgs.Ftncode = CHRS_DEFAULT_FTN; + msgs.MaxArticles = CFG.maxarticles; + strcpy(msgs.Origin, CFG.origin); + } fwrite(&msgs, msgshdr.recsize, 1, fp); + /* + * Always clear all connections, the area doesn't exist anymore. + */ + memset(&System, 0, sizeof(System)); for (i = 0; i < (msgshdr.syssize / sizeof(sysconnect)); i++) fwrite(&System, sizeof(system), 1, fp); break; @@ -620,6 +635,7 @@ int Areas(void) } } } + fclose(fp); } tidy_arealist(&alist); } @@ -638,13 +654,183 @@ int Areas(void) while ((fread(&fgroup, fgrouphdr.recsize, 1, gp)) == 1) { if (fgroup.Active && fgroup.AutoChange && strlen(fgroup.AreaFile)) { Syslog('+', "Checking tic group %s, file %s", fgroup.Name, fgroup.AreaFile); + sprintf(temp, "%s/%s", CFG.alists_path, fgroup.AreaFile); + if ((ap = fopen(temp, "r")) == NULL) { + WriteError("Can't open %s", temp); + } else { + if (fgroup.FileGate) { + /* + * filegate.zxx format + */ + Found = FALSE; + while (fgets(buf, 4096, ap)) { + /* + * Each group starts with % FDN: FileGroup Descrition + */ + if (strlen(buf) && !strncmp(buf, "% FDN:", 6)) { + tag = strtok(buf, "\t \r\n\0"); + p = strtok(NULL, "\t \r\n\0"); + p = strtok(NULL, "\r\n\0"); + desc = p; + while ((*desc == ' ') || (*desc == '\t')) + desc++; + if (!strcmp(desc, fgroup.Comment)) { + Syslog('f', "Start of group \"%s\" found", desc); + while (fgets(buf, 4096, ap)) { + if (!strncasecmp(buf, "Area ", 5)) { + Syslog('f', "Area: %s", buf); + tag = strtok(buf, "\t \r\n\0"); + tag = strtok(NULL, "\t \r\n\0"); + Found = TRUE; + fill_arealist(&alist, tag, FALSE); + } + if (strlen(buf) && !strncmp(buf, "% FDN:", 6)) { + /* + * All entries in group are seen, the area wasn't there. + */ + Syslogp('f', buf); + break; + } + } + if (Found) + break; + } + } + } + } else { + /* + * Normal taglist format + */ + while (fgets(buf, 4096, ap)) { + if (strlen(buf) && isalnum(buf[0])) { + tag = strtok(buf, "\t \r\n\0"); + fill_arealist(&alist, tag, FALSE); + } + } + } + fclose(ap); + + /* + * Mark areas already present in the taglist. + */ + sprintf(temp, "%s/etc/tic.data", getenv("MBSE_ROOT")); + if ((fp = fopen(temp, "r")) == NULL) { + WriteError("Can't open %s", temp); + tidy_arealist(&alist); + free(buf); + free(temp); + return FALSE; + } + fread(&tichdr, sizeof(tichdr), 1, fp); + for (tmp = alist; tmp; tmp = tmp->next) { + fseek(fp, tichdr.hdrsize, SEEK_SET); + while (fread(&tic, tichdr.recsize, 1, fp) == 1) { + if (tic.Active && !strcmp(tic.Group, fgroup.Name) && !strcmp(tic.Name, tmp->Name)) + tmp->IsPresent = TRUE; + fseek(fp, tichdr.syssize, SEEK_CUR); + } + } + + /* + * Add areas to AreaList not in the taglist, they must be deleted. + */ + fseek(fp, tichdr.hdrsize, SEEK_SET); + while (fread(&tic, tichdr.recsize, 1, fp) == 1) { + if (tic.Active && !strcmp(tic.Group, fgroup.Name)) { + Found = FALSE; + for (tmp = alist; tmp; tmp = tmp->next) { + if (!strcmp(tic.Name, tmp->Name)) + Found = TRUE; + } + if (!Found) + fill_arealist(&alist, tic.Name, TRUE); + } + fseek(fp, tichdr.syssize, SEEK_CUR); + } + fclose(fp); + + /* + * Now we have a list of actions to perform + */ Syslog('f', "Area tag Oke Del"); for (tmp = alist; tmp; tmp = tmp->next) { Syslog('f', "%-20s %s %s", tmp->Name, tmp->IsPresent?"Yes":"No ", tmp->DoDelete?"Yes":"No "); } - tidy_arealist(&alist); + /* + * Make modification, first add missing areas + */ + for (tmp = alist; tmp; tmp = tmp->next) { + if (!tmp->IsPresent && !tmp->DoDelete) + CheckTicGroup(tmp->Name, TRUE, NULL); + } + /* + * Mark TIC areas for deletion. The original file areas + * are not deleted. They probably contain files and we + * may want to keep these. If the area was empty we are + * still warned about that by the "mbfile check" command. + */ + Found = FALSE; + sprintf(temp, "%s/etc/tic.data", getenv("MBSE_ROOT")); + if ((fp = fopen(temp, "r+")) == NULL) { + WriteError("Can't open %s for r/w"); + } else { + fread(&tichdr, sizeof(tichdr), 1, fp); + for (tmp = alist; tmp; tmp = tmp->next) { + if (!tmp->IsPresent && tmp->DoDelete) { + fseek(fp, tichdr.hdrsize, SEEK_SET); + Syslog('f', "Delete %s", tmp->Name); + while (fread(&tic, tichdr.recsize, 1, fp) == 1) { + if (tic.Active && !strcmp(tic.Group, fgroup.Name) && !strcmp(tic.Name, tmp->Name)) { + fseek(fp, - tichdr.recsize, SEEK_CUR); + Syslog('+', "Marked TIC area %s for deletion", tmp->Name); + tic.Deleted = TRUE; + tic.Active = FALSE; + fwrite(&tic, tichdr.recsize, 1, fp); + Found = TRUE; + } + fseek(fp, tichdr.syssize, SEEK_CUR); + } + } + } + fclose(fp); + } + if (Found) { + /* + * Purge marked records + */ + sprintf(buf, "%s/etc/tic.temp", getenv("MBSE_ROOT")); + if ((fp = fopen(temp, "r")) == NULL) { + WriteError("Can't open %s", temp); + } else if ((ap = fopen(buf, "w")) == NULL) { + WriteError("Can't create %s", buf); + fclose(fp); + } else { + fread(&tichdr, tichdr.hdrsize, 1, fp); + fwrite(&tichdr, tichdr.hdrsize, 1, ap); + while (fread(&tic, tichdr.recsize, 1, fp) == 1) { + if (tic.Deleted && !tic.Active) { + fseek(fp, tichdr.syssize, SEEK_CUR); + count++; + } else { + fwrite(&tic, tichdr.recsize, 1, ap); + for (i = 0; i < (tichdr.syssize / sizeof(System)); i++) { + fread(&System, sizeof(System), 1, fp); + fwrite(&System, sizeof(System), 1, ap); + } + } + } + fclose(fp); + fclose(ap); + unlink(temp); + rename(buf, temp); + Syslog('+', "Purged %d TIC records", count); + } + } + + tidy_arealist(&alist); + } } } fclose(gp); diff --git a/mbsetup/m_marea.c b/mbsetup/m_marea.c index 1d2e20fb..4a3a3123 100644 --- a/mbsetup/m_marea.c +++ b/mbsetup/m_marea.c @@ -304,25 +304,6 @@ void InitMsgRec(void) -void DeleteJAM(char *); -void DeleteJAM(char *Base) -{ - char *temp; - - temp = calloc(PATH_MAX, sizeof(char)); - sprintf(temp, "%s.jdt", Base); - unlink(temp); - sprintf(temp, "%s.jdx", Base); - unlink(temp); - sprintf(temp, "%s.jhr", Base); - unlink(temp); - sprintf(temp, "%s.jlr", Base); - unlink(temp); - free(temp); -} - - - int AppendMsgarea(void); int AppendMsgarea() { @@ -977,7 +958,7 @@ void MsgGlobal(void) break; case 12:if (msgs.Active) { msgs.Active = FALSE; - DeleteJAM(msgs.Base); + Msg_DeleteMsgBase(msgs.Base); memset(&msgs, 0, sizeof(msgs)); if (SaveMsgRec(marea, FALSE) == 0) { Done++; @@ -1189,7 +1170,7 @@ int EditMsgRec(int Area) /* * Make it so */ - DeleteJAM(msgs.Base); + Msg_DeleteMsgBase(msgs.Base); memset(&System, 0, sizeof(System)); fseek(tfil, 0, SEEK_SET); for (i = 0; i < (msgshdr.syssize / sizeof(sysconnect)); i++)