diff --git a/exec/make_areas_ini.js b/exec/make_areas_ini.js new file mode 100644 index 0000000000000000000000000000000000000000..8248dcbfc290a6b25dec632ff8b2dbed44b56d99 --- /dev/null +++ b/exec/make_areas_ini.js @@ -0,0 +1,35 @@ +// Export legacy areas.bbs file to (new/modern) areas.ini format + +var areas_bbs = argv[0] || file_getcase(system.data_dir + "areas.bbs"); +var areas_ini = system.data_dir + "areas.ini"; +if(file_exists(areas_ini) && deny("Overwrite " + areas_ini)) + exit(0); + +var fin = new File(areas_bbs); +if(!fin.open("r")) + throw new Error("Error " + fin.error + " opening " + fin.name); +var fout = new File(areas_ini); +if(!fout.open("w")) + throw new Error("Error " + fout.error + " opening " + fout.name); +var text = fin.readAll(); +var areas = 0; +for(var i in text) { + var line = text[i]; + var match = line.match(/(\S+)\s+(\S+)\s+(.*)$/); + if(!match || match.length < 3) + continue; + if(match[1][0] == ';') // comment + continue; + var tag = match[2]; + var sub = match[1]; + var links = match[3]; + fout.writeln(format("[%s]", tag)); + if(sub.toUpperCase() == "P") + fout.writeln("pass-through = true"); + else + fout.writeln(format("sub = %s", sub)); + fout.writeln(format("links = %s", links)); + fout.writeln(); + ++areas; +} +print(areas + " areas from " + areas_bbs + " exported to " + areas_ini); \ No newline at end of file diff --git a/src/sbbs3/sbbsecho.c b/src/sbbs3/sbbsecho.c index 6a0ea1591fbaafcd957d87d5cac0e6d1a89aebb2..d4b1d50e9df23942afa5d98728064340a6bf78f0 100644 --- a/src/sbbs3/sbbsecho.c +++ b/src/sbbs3/sbbsecho.c @@ -1303,6 +1303,18 @@ bool area_is_linked(unsigned area_num, const fidoaddr_t* addr) return false; } +void link_area(unsigned area_num, const fidoaddr_t* addr) +{ + area_t* area = &cfg.area[area_num]; + if((area->link = realloc_or_free(area->link, (sizeof *addr) * (area->links + 1))) == NULL) { + lprintf(LOG_ERR,"ERROR line %d allocating memory for area " + "#%u links.",__LINE__, area_num + 1); + bail(1); + return; + } + memcpy(&area->link[area->links++], &addr, sizeof *addr); +} + /* Returns area index */ uint find_area(const char* echotag) { @@ -1556,49 +1568,131 @@ int check_elists(const char *areatag, fidoaddr_t addr) } return(match); } -/****************************************************************************** - Used by AREAFIX to add/remove/change areas in the areas file -******************************************************************************/ -void alter_areas(str_list_t add_area, str_list_t del_area, nodecfg_t* nodecfg, const char* to, bool rescan) + +// areafile is in (new) .ini format (e.g. data/areas.ini) +bool areafile_is_ini = false; + +const char* strSub = "sub"; +const char* strLinks = "links"; +const char* strLinkSep = " "; +const char* strPassthrough = "pass-through"; + +void add_areas_from_echolists(FILE* afileout, FILE* nmfile + ,str_list_t add_area, size_t* added + ,nodecfg_t* nodecfg); + +void alter_areas_ini(FILE* afilein, FILE* afileout, FILE* nmfile + ,str_list_t add_area, size_t* added + ,str_list_t del_area, size_t* deleted + ,nodecfg_t* nodecfg, const char* to, bool rescan) { - FILE *nmfile,*afilein,*afileout,*fwdfile; - char str[1024],fields[1024],code[LEN_EXTCODE+1],echotag[FIDO_AREATAG_LEN+1],comment[256] - ,outpath[MAX_PATH+1] - ,*p,*tp,nomatch=0,match=0; - int file; - unsigned j,k,x,y; + bool nomatch = false; + unsigned j; + faddr_t addr = nodecfg->addr; + const char* addr_str = smb_faddrtoa(&addr,NULL); + + str_list_t ini = iniReadFile(afilein); + str_list_t areas = iniGetSectionList(ini, /* prefix: */NULL); + fclose(afilein); + + for(int i = 0; areas != NULL && areas[i] != NULL; ++i) { + const char* echotag = areas[i]; /* Areatag Field */ + if(echotag[0] == '*') { + /* Don't allow down-links to our "Unknown area" */ + continue; + } + if(del_area[0] != NULL) { /* Check for areas to remove */ + bool disconnect_all = (stricmp(del_area[0], "-ALL") == 0); + if(disconnect_all || strListFind(del_area, echotag, /* case-sensitive */false) >= 0) { + uint areanum = find_area(echotag); + if(!area_is_valid(areanum)) { + lprintf(LOG_ERR, "Invalid area num on line %d", __LINE__); + continue; + } + if(!area_is_linked(areanum, &addr)) { + if(!disconnect_all) { + fprintf(nmfile,"%s not connected.\r\n",echotag); + lprintf(LOG_NOTICE, "AreaFix (for %s) Unlink-requested area already unlinked: %s" + ,addr_str, echotag); + } + continue; + } + lprintf(LOG_INFO,"AreaFix (for %s) Unlinking area: %s", addr_str, echotag); + str_list_t links = iniGetStringList(ini, echotag, strLinks, strLinkSep, ""); + int link = strListFind(links, addr_str, /* case-sensitive */true); + if(link >= 0 && strListFastDelete(links, link, 1)) { + iniSetStringList(&ini, echotag, strLinks, strLinkSep, links, &sbbsecho_ini_style); + fprintf(nmfile,"%s removed.\r\n",echotag); + (*deleted)++; + } + strListFree(&links); + continue; + } + } + if(add_area[0] != NULL) { /* Check for areas to add */ + bool add_all = (stricmp(add_area[0], "+ALL") == 0); + j = strListFind(add_area, echotag, /* case-sensitive */false); + if(add_all || j >= 0) { + if(j >= 0) + add_area[j][0]=0; /* So we can check other lists */ + uint areanum = find_area(echotag); + if(!area_is_valid(areanum)) { + lprintf(LOG_ERR, "Invalid area num on line %d", __LINE__); + continue; + } + if(area_is_linked(areanum, &addr)) { + fprintf(nmfile,"%s already connected.\r\n",echotag); + lprintf(LOG_NOTICE, "AreaFix (for %s) Link-requested area is already connected: %s" + ,addr_str, echotag); + } else if(cfg.add_from_echolists_only && !check_elists(echotag,addr)) { + lprintf(LOG_NOTICE, "AreaFix (for %s) Link-requested area not found in EchoLists: %s" + ,addr_str, echotag); + continue; + } else { + lprintf(LOG_INFO,"AreaFix (for %s) Linking area: %s", addr_str, echotag); + link_area(areanum, &addr); + char value[INI_MAX_VALUE_LEN] = ""; + iniGetString(ini, echotag, strLinks, "", value); + if(*value != '\0') + SAFECAT(value, strLinkSep); + SAFECAT(value, addr_str); + iniSetString(&ini, echotag, strLinks, value, &sbbsecho_ini_style); + fprintf(nmfile,"%s added.\r\n",echotag); + (*added)++; + } + if(rescan && area_is_linked(areanum, &addr) && is_valid_subnum(&scfg, cfg.area[areanum].sub)) { + ulong exported = export_echomail(scfg.sub[cfg.area[areanum].sub]->code, nodecfg, true); + fprintf(nmfile,"%s rescanned and %lu messages exported.\r\n", echotag, exported); + } + continue; + } + } + nomatch = true; /* This area wasn't in there */ + } + strListWriteFile(afileout, ini, "\n"); + strListFree(&ini); + strListFree(&areas); + if(nomatch || (add_area[0] != NULL && stricmp(add_area[0],"+ALL") == 0)) + add_areas_from_echolists(afileout, nmfile, add_area, added, nodecfg); +} + +void alter_areas_bbs(FILE* afilein, FILE* afileout, FILE* nmfile + ,str_list_t add_area, size_t* added + ,str_list_t del_area, size_t* deleted + ,nodecfg_t* nodecfg, const char* to, bool rescan) +{ + char fields[1024],code[LEN_EXTCODE+1],echotag[FIDO_AREATAG_LEN+1],comment[256] + ,*p,*tp; + bool nomatch = false; + unsigned j; unsigned u; - size_t add_count, added = 0; - size_t del_count, deleted = 0; - struct stat st = {0}; + size_t add_count; + size_t del_count; faddr_t addr = nodecfg->addr; add_count = strListCount(add_area); del_count = strListCount(del_area); - if((nmfile=tmpfile())==NULL) { - lprintf(LOG_ERR,"ERROR in tmpfile()"); - return; - } - SAFECOPY(outpath,cfg.areafile); - *getfname(outpath)=0; - SAFECAT(outpath, "AREASXXXXXX"); - if((file = mkstemp(outpath)) == -1) { - lprintf(LOG_ERR, "ERROR %u (%s) line %d opening %s", errno, strerror(errno), __LINE__, outpath); - fclose(nmfile); - return; - } - if((afileout=fdopen(file, "w+"))==NULL) { - lprintf(LOG_ERR,"ERROR %u (%s) line %d fdopening %s",errno,strerror(errno),__LINE__,outpath); - fclose(nmfile); - return; - } - if((afilein=fopen(cfg.areafile,"r"))==NULL) { - lprintf(LOG_ERR,"ERROR %u (%s) line %d opening areafile: %s",errno,strerror(errno),__LINE__,cfg.areafile); - fclose(afileout); - fclose(nmfile); - return; - } while(!feof(afilein)) { if(!fgets(fields,sizeof(fields),afilein)) break; @@ -1661,7 +1755,7 @@ void alter_areas(str_list_t add_area, str_list_t del_area, nodecfg_t* nodecfg, c fprintf(afileout,"%s",comment); fprintf(afileout,"\n"); fprintf(nmfile,"%s removed.\r\n",echotag); - deleted++; + (*deleted)++; break; } } @@ -1697,17 +1791,7 @@ void alter_areas(str_list_t add_area, str_list_t del_area, nodecfg_t* nodecfg, c lprintf(LOG_INFO,"AreaFix (for %s) Linking area: %s", smb_faddrtoa(&addr,NULL), echotag); /* Added 12/4/95 to add link to connected links */ - - ++cfg.area[u].links; - if((cfg.area[u].link=(fidoaddr_t *) - realloc_or_free(cfg.area[u].link,sizeof(fidoaddr_t) - *(cfg.area[u].links)))==NULL) { - lprintf(LOG_ERR,"ERROR line %d allocating memory for area " - "#%u links.",__LINE__,u+1); - bail(1); - return; - } - memcpy(&cfg.area[u].link[cfg.area[u].links-1],&addr,sizeof(fidoaddr_t)); + link_area(u, &addr); fprintf(afileout,"%-*s %-*s " ,LEN_EXTCODE, code @@ -1719,7 +1803,7 @@ void alter_areas(str_list_t add_area, str_list_t del_area, nodecfg_t* nodecfg, c fprintf(afileout,"%s",comment); fprintf(afileout,"\n"); fprintf(nmfile,"%s added.\r\n",echotag); - added++; + (*added)++; break; } } @@ -1736,48 +1820,73 @@ void alter_areas(str_list_t add_area, str_list_t del_area, nodecfg_t* nodecfg, c fprintf(afileout,"%s\n",fields); /* No match so write back line */ } fclose(afilein); - if(nomatch || (add_count && stricmp(add_area[0],"+ALL") == 0)) { - for(j=0;j<cfg.listcfgs;j++) { - match=0; - for(k=0; cfg.listcfg[j].keys[k] ;k++) { - if(match) break; - for(x=0; nodecfg->keys[x] ;x++) { - if(!stricmp(cfg.listcfg[j].keys[k] - ,nodecfg->keys[x])) { - if((fwdfile=tmpfile())==NULL) { - lprintf(LOG_ERR,"ERROR line %d opening forward temp " - "file",__LINE__); - match=1; - break; - } - if((afilein=fopen(cfg.listcfg[j].listpath,"r"))==NULL) { - lprintf(LOG_ERR,"ERROR %u (%s) line %d opening %s" - ,errno,strerror(errno),__LINE__,cfg.listcfg[j].listpath); - fclose(fwdfile); - match=1; + if(nomatch || (add_area[0] != NULL && stricmp(add_area[0],"+ALL") == 0)) + add_areas_from_echolists(afileout, nmfile, add_area, added, nodecfg); +} + +void add_areas_from_echolists(FILE* afileout, FILE* nmfile + ,str_list_t add_area, size_t* added + ,nodecfg_t* nodecfg) +{ + char str[1024]; + char echotag[FIDO_AREATAG_LEN+1]; + char* p; + char* tp; + bool match = false; + FILE* afilein; + FILE* fwdfile; + uint j, k, x, y; + faddr_t addr = nodecfg->addr; + + for(j=0;j<cfg.listcfgs;j++) { + match=0; + for(k=0; cfg.listcfg[j].keys[k] ;k++) { + if(match) break; + for(x=0; nodecfg->keys[x] ;x++) { + if(!stricmp(cfg.listcfg[j].keys[k] + ,nodecfg->keys[x])) { + if((fwdfile=tmpfile())==NULL) { + lprintf(LOG_ERR,"ERROR line %d opening forward temp " + "file",__LINE__); + match=1; + break; + } + if((afilein=fopen(cfg.listcfg[j].listpath,"r"))==NULL) { + lprintf(LOG_ERR,"ERROR %u (%s) line %d opening %s" + ,errno,strerror(errno),__LINE__,cfg.listcfg[j].listpath); + fclose(fwdfile); + match=1; + break; + } + while(!feof(afilein)) { + if(!fgets(str,sizeof(str),afilein)) break; + p=str; + SKIP_WHITESPACE(p); + if(*p==';') /* Ignore Comment Lines */ + continue; + tp=p; + FIND_WHITESPACE(tp); + *tp=0; + SAFECOPY(echotag, p); + if(add_area[0]!=NULL && stricmp(add_area[0],"+ALL")==0) { + if(area_is_valid(find_area(p))) + continue; } - while(!feof(afilein)) { - if(!fgets(str,sizeof(str),afilein)) + for(y=0;add_area[y]!=NULL;y++) + if((!stricmp(add_area[y], echotag) && + add_area[y][0]) || + !stricmp(add_area[0],"+ALL")) break; - p=str; - SKIP_WHITESPACE(p); - if(*p==';') /* Ignore Comment Lines */ - continue; - tp=p; - FIND_WHITESPACE(tp); - *tp=0; - SAFECOPY(echotag, p); - if(add_area[0]!=NULL && stricmp(add_area[0],"+ALL")==0) { - if(area_is_valid(find_area(p))) - continue; - } - for(y=0;add_area[y]!=NULL;y++) - if((!stricmp(add_area[y], echotag) && - add_area[y][0]) || - !stricmp(add_area[0],"+ALL")) - break; - if(add_area[y]!=NULL) { + if(add_area[y]!=NULL) { + if(areafile_is_ini) { + fprintf(afileout,"\n[%s]\n%s = true", echotag, strPassthrough); + fprintf(afileout,"\n%s = ", strLinks); + if(cfg.listcfg[j].hub.zone) + fprintf(afileout,"%s%s" + ,smb_faddrtoa(&cfg.listcfg[j].hub,NULL), strLinkSep); + fprintf(afileout,"%s\n",smb_faddrtoa(&addr,NULL)); + } else { fprintf(afileout,"%-*s %-*s" ,LEN_EXTCODE, "P" ,FIDO_AREATAG_LEN, echotag); @@ -1785,30 +1894,75 @@ void alter_areas(str_list_t add_area, str_list_t del_area, nodecfg_t* nodecfg, c fprintf(afileout," %s" ,smb_faddrtoa(&cfg.listcfg[j].hub,NULL)); fprintf(afileout," %s\n",smb_faddrtoa(&addr,NULL)); - fprintf(nmfile,"%s added.\r\n", echotag); - if(stricmp(add_area[0],"+ALL")) - add_area[y][0]=0; - if(cfg.listcfg[j].forward - && cfg.listcfg[j].hub.zone) - fprintf(fwdfile,"%s\r\n", echotag); - added++; - lprintf(LOG_NOTICE, "AreaFix (for %s) Adding area from EchoList (%s): %s" - , smb_faddrtoa(&addr,NULL), cfg.listcfg[j].listpath, echotag); } + fprintf(nmfile,"%s added.\r\n", echotag); + if(stricmp(add_area[0],"+ALL")) + add_area[y][0]=0; + if(cfg.listcfg[j].forward + && cfg.listcfg[j].hub.zone) + fprintf(fwdfile,"%s\r\n", echotag); + (*added)++; + lprintf(LOG_NOTICE, "AreaFix (for %s) Adding area from EchoList (%s): %s" + , smb_faddrtoa(&addr,NULL), cfg.listcfg[j].listpath, echotag); } - fclose(afilein); - if(cfg.listcfg[j].forward && ftell(fwdfile)>0) - file_to_netmail(fwdfile,cfg.listcfg[j].password - ,cfg.listcfg[j].hub,/* To: */cfg.listcfg[j].areamgr); - fclose(fwdfile); - match=1; - break; } + fclose(afilein); + if(cfg.listcfg[j].forward && ftell(fwdfile)>0) + file_to_netmail(fwdfile,cfg.listcfg[j].password + ,cfg.listcfg[j].hub,/* To: */cfg.listcfg[j].areamgr); + fclose(fwdfile); + match=1; + break; } } } } - if(add_count && stricmp(add_area[0],"+ALL")) { +} + +/****************************************************************************** + Used by AREAFIX to add/remove/change areas in the areas file +******************************************************************************/ +void alter_areas(str_list_t add_area, str_list_t del_area, nodecfg_t* nodecfg, const char* to, bool rescan) +{ + FILE *nmfile,*afilein,*afileout; + char outpath[MAX_PATH+1]; + int file; + unsigned u; + size_t added = 0; + size_t deleted = 0; + struct stat st = {0}; + faddr_t addr = nodecfg->addr; + + if((nmfile=tmpfile())==NULL) { + lprintf(LOG_ERR,"ERROR in tmpfile()"); + return; + } + SAFECOPY(outpath,cfg.areafile); + *getfname(outpath)=0; + SAFECAT(outpath, "AREASXXXXXX"); + if((file = mkstemp(outpath)) == -1) { + lprintf(LOG_ERR, "ERROR %u (%s) line %d opening %s", errno, strerror(errno), __LINE__, outpath); + fclose(nmfile); + return; + } + if((afileout=fdopen(file, "w+"))==NULL) { + lprintf(LOG_ERR,"ERROR %u (%s) line %d fdopening %s",errno,strerror(errno),__LINE__,outpath); + fclose(nmfile); + return; + } + if((afilein=fopen(cfg.areafile,"r"))==NULL) { + lprintf(LOG_ERR,"ERROR %u (%s) line %d opening areafile: %s",errno,strerror(errno),__LINE__,cfg.areafile); + fclose(afileout); + fclose(nmfile); + return; + } + + if(areafile_is_ini) + alter_areas_bbs(afilein, afileout, nmfile, add_area, &added, del_area, &deleted, nodecfg, to, rescan); + else + alter_areas_ini(afilein, afileout, nmfile, add_area, &added, del_area, &deleted, nodecfg, to, rescan); + + if(add_area[0] != NULL && stricmp(add_area[0],"+ALL")) { for(u=0;add_area[u]!=NULL;u++) if(add_area[u][0]) { fprintf(nmfile,"%s not found.\r\n",add_area[u]); @@ -1876,8 +2030,11 @@ bool add_sub_to_arealist(sub_t* sub, fidoaddr_t uplink) if(last_ch != '\n') fputc('\n', fp); - fprintf(fp, "%-*s %-*s %s\n" - ,LEN_EXTCODE, sub->code, FIDO_AREATAG_LEN, echotag, smb_faddrtoa(&uplink, NULL)); + if(areafile_is_ini) + fprintf(fp, "\n[%s]\n%s = %s\n%s = %s\n", echotag, strSub, sub->code, strLinks, smb_faddrtoa(&uplink, NULL)); + else + fprintf(fp, "%-*s %-*s %s\n" + ,LEN_EXTCODE, sub->code, FIDO_AREATAG_LEN, echotag, smb_faddrtoa(&uplink, NULL)); fclose(fp); } @@ -6152,17 +6309,160 @@ void check_free_diskspace(const char* path) } } +void read_areafile_ini(FILE* stream) +{ + char value[INI_MAX_VALUE_LEN]; + str_list_t ini = iniReadFile(stream); + str_list_t areas = iniGetSectionList(ini, /* prefix: */NULL); + + for(size_t u = 0; areas != NULL && areas[u] != NULL; ++u) { + char* area_tag = areas[u]; + int areanum = cfg.areas; + if(!new_area(/* tag: */NULL, /* Pass-through by default: */INVALID_SUB, /* link: */NULL)) { + lprintf(LOG_ERR,"ERROR allocating memory for area #%u.",cfg.areas + 1); + bail(1); + return; + } + str_list_t keys = iniGetSection(ini, area_tag); + if(!iniGetBool(keys, ROOT_SECTION, strPassthrough, false)) { + if((cfg.area[areanum].sub = getsubnum(&scfg, iniGetString(keys, ROOT_SECTION, strSub, "", value))) >= scfg.total_subs) { + printf("\n"); + lprintf(LOG_WARNING,"%s: Unrecognized internal code, assumed passthru", value); + } + } + if(area_tag[0]=='*') /* UNKNOWN-ECHO area */ + cfg.badecho = areanum; + if((cfg.area[areanum].tag=strdup(area_tag))==NULL) { + printf("\n"); + lprintf(LOG_ERR,"ERROR allocating memory for area #%u tag." + ,areanum+1); + bail(1); + return; + } + str_list_t links = iniGetStringList(keys, ROOT_SECTION, strLinks, strLinkSep, NULL); + cfg.area[areanum].links = strListCount(links); + if((cfg.area[areanum].link = malloc(sizeof(fidoaddr_t) * (cfg.area[areanum].links))) == NULL) { + printf("\n"); + lprintf(LOG_ERR,"ERROR allocating memory for area #%u links." + ,areanum+1); + bail(1); + return; + } + cfg.area[areanum].links = 0; + for(size_t l = 0; links != NULL && links[l] != NULL; ++l) { + fidoaddr_t link = atofaddr(links[l]); + if(findnodecfg(&cfg, link, /* exact: */cfg.require_linked_node_cfg) == NULL) { + printf("\n"); + lprintf(LOG_WARNING, "Configuration for %s-linked-node (%s) not found in %s" + ,cfg.area[areanum].tag, faddrtoa(&link), cfg.cfgfile); + } else { + cfg.area[areanum].link[cfg.area[areanum].links++] = link; + } + } + strListFree(&links); + strListFree(&keys); + } + strListFree(&areas); + strListFree(&ini); +} + +void read_areafile_bbs(FILE* stream) +{ + char str[1025] + ,*p,*tp; + char tmp_code[LEN_EXTCODE+1]; + char area_tag[FIDO_AREATAG_LEN+1]; + int i; + + while(!terminated) { + if(!fgets(str,sizeof(str),stream)) + break; + truncsp(str); + p=str; + SKIP_WHITESPACE(p); /* Find first printable char */ + if(*p==';' || !*p) /* Ignore blank lines or start with ; */ + continue; + int areanum = cfg.areas; + if(!new_area(/* tag: */NULL, /* Pass-through by default: */INVALID_SUB, /* link: */NULL)) { + lprintf(LOG_ERR,"ERROR allocating memory for area #%u.",cfg.areas + 1); + bail(1); + return; + } + sprintf(tmp_code,"%-.*s",LEN_EXTCODE,p); + tp=tmp_code; + FIND_WHITESPACE(tp); + *tp=0; + for(i=0;i<scfg.total_subs;i++) + if(!stricmp(tmp_code,scfg.sub[i]->code)) + break; + if(i<scfg.total_subs) + cfg.area[areanum].sub = i; + else if(stricmp(tmp_code,"P")) { + printf("\n"); + lprintf(LOG_WARNING,"%s: Unrecognized internal code, assumed passthru",tmp_code); + } + + FIND_WHITESPACE(p); /* Skip code */ + SKIP_WHITESPACE(p); /* Skip white space */ + SAFECOPY(area_tag,p); /* Area tag */ + truncstr(area_tag,"\t "); + strupr(area_tag); + if(area_tag[0]=='*') /* UNKNOWN-ECHO area */ + cfg.badecho=areanum; + if(areanum > 0 && area_is_valid(find_area(area_tag))) { + printf("\n"); + lprintf(LOG_WARNING, "DUPLICATE AREA (%s) in area file (%s), IGNORED!", area_tag, cfg.areafile); + cfg.areas--; + continue; + } + if((cfg.area[areanum].tag=strdup(area_tag))==NULL) { + printf("\n"); + lprintf(LOG_ERR,"ERROR allocating memory for area #%u tag." + ,areanum+1); + bail(1); + return; + } + + FIND_WHITESPACE(p); /* Skip tag */ + SKIP_WHITESPACE(p); /* Skip white space */ + + while(*p && *p!=';') { + if(!IS_DIGIT(*p)) { + printf("\n"); + lprintf(LOG_WARNING, "Invalid Area File line, expected link address(es) after echo-tag: '%s'", str); + break; + } + if((cfg.area[areanum].link=(fidoaddr_t *) + realloc_or_free(cfg.area[areanum].link + ,sizeof(fidoaddr_t)*(cfg.area[areanum].links+1)))==NULL) { + printf("\n"); + lprintf(LOG_ERR,"ERROR allocating memory for area #%u links." + ,areanum+1); + bail(1); + return; + } + fidoaddr_t link = atofaddr(p); + cfg.area[areanum].link[cfg.area[areanum].links] = link; + if(findnodecfg(&cfg, link, /* exact: */cfg.require_linked_node_cfg) == NULL) { + printf("\n"); + lprintf(LOG_WARNING, "Configuration for %s-linked-node (%s) not found in %s" + ,cfg.area[areanum].tag, faddrtoa(&link), cfg.cfgfile); + } else + cfg.area[areanum].links++; + FIND_WHITESPACE(p); /* Skip address */ + SKIP_WHITESPACE(p); /* Skip white space */ + } + } +} + /***********************************/ /* Synchronet/FidoNet Message util */ /***********************************/ int main(int argc, char **argv) { FILE* fidomsg; - char str[1025],path[MAX_PATH+1] - ,*p,*tp; + char str[1025],path[MAX_PATH+1]; char* sub_code = NULL; - char tmp_code[LEN_EXTCODE+1]; - char area_tag[FIDO_AREATAG_LEN+1]; char cmdline[256]; int i,j,fmsg; size_t f; @@ -6465,94 +6765,17 @@ int main(int argc, char **argv) cfg.area=NULL; (void)fexistcase(cfg.areafile); + char *ext = getfext(cfg.areafile); + areafile_is_ini = (ext != NULL && stricmp(ext, ".ini") == 0); + if((stream = fopen(cfg.areafile,"r")) == NULL) { lprintf(LOG_NOTICE, "Could not open Area File (%s): %s", cfg.areafile, strerror(errno)); } else { printf("Reading %s",cfg.areafile); - while(!terminated) { - if(!fgets(str,sizeof(str),stream)) - break; - truncsp(str); - p=str; - SKIP_WHITESPACE(p); /* Find first printable char */ - if(*p==';' || !*p) /* Ignore blank lines or start with ; */ - continue; - int areanum = cfg.areas; - if(!new_area(/* tag: */NULL, /* Pass-through by default: */INVALID_SUB, /* link: */NULL)) { - lprintf(LOG_ERR,"ERROR allocating memory for area #%u.",cfg.areas + 1); - bail(1); - return -1; - } - sprintf(tmp_code,"%-.*s",LEN_EXTCODE,p); - tp=tmp_code; - FIND_WHITESPACE(tp); - *tp=0; - for(i=0;i<scfg.total_subs;i++) - if(!stricmp(tmp_code,scfg.sub[i]->code)) - break; - if(i<scfg.total_subs) - cfg.area[areanum].sub = i; - else if(stricmp(tmp_code,"P")) { - printf("\n"); - lprintf(LOG_WARNING,"%s: Unrecognized internal code, assumed passthru",tmp_code); - } - - FIND_WHITESPACE(p); /* Skip code */ - SKIP_WHITESPACE(p); /* Skip white space */ - SAFECOPY(area_tag,p); /* Area tag */ - truncstr(area_tag,"\t "); - strupr(area_tag); - if(area_tag[0]=='*') /* UNKNOWN-ECHO area */ - cfg.badecho=areanum; - if(areanum > 0 && area_is_valid(find_area(area_tag))) { - printf("\n"); - lprintf(LOG_WARNING, "DUPLICATE AREA (%s) in area file (%s), IGNORED!", area_tag, cfg.areafile); - cfg.areas--; - continue; - } - if((cfg.area[areanum].tag=strdup(area_tag))==NULL) { - printf("\n"); - lprintf(LOG_ERR,"ERROR allocating memory for area #%u tag." - ,areanum+1); - bail(1); - return -1; - } - - FIND_WHITESPACE(p); /* Skip tag */ - SKIP_WHITESPACE(p); /* Skip white space */ - - while(*p && *p!=';') { - if(!IS_DIGIT(*p)) { - printf("\n"); - lprintf(LOG_WARNING, "Invalid Area File line, expected link address(es) after echo-tag: '%s'", str); - break; - } - if((cfg.area[areanum].link=(fidoaddr_t *) - realloc_or_free(cfg.area[areanum].link - ,sizeof(fidoaddr_t)*(cfg.area[areanum].links+1)))==NULL) { - printf("\n"); - lprintf(LOG_ERR,"ERROR allocating memory for area #%u links." - ,areanum+1); - bail(1); - return -1; - } - fidoaddr_t link = atofaddr(p); - cfg.area[areanum].link[cfg.area[areanum].links] = link; - if(findnodecfg(&cfg, link, /* exact: */cfg.require_linked_node_cfg) == NULL) { - printf("\n"); - lprintf(LOG_WARNING, "Configuration for %s-linked-node (%s) not found in %s" - ,cfg.area[areanum].tag, faddrtoa(&link), cfg.cfgfile); - } else - cfg.area[areanum].links++; - FIND_WHITESPACE(p); /* Skip address */ - SKIP_WHITESPACE(p); /* Skip white space */ - } - - #if 0 - if(cfg.area[areanum].sub!=INVALID_SUB || cfg.area[areanum].links) - cfg.areas++; /* Don't allocate if no tossing */ - #endif - } + if(areafile_is_ini) + read_areafile_ini(stream); + else + read_areafile_bbs(stream); fclose(stream); printf("\n"); lprintf(LOG_DEBUG, "Read %u areas from %s", cfg.areas, cfg.areafile); diff --git a/src/sbbs3/sbbsecho.h b/src/sbbs3/sbbsecho.h index 11452d0ea1b4fb745549e1b2abedf6e4a8a92ad0..3c1edccb837ae7d9f9e064619a45433362954d86 100644 --- a/src/sbbs3/sbbsecho.h +++ b/src/sbbs3/sbbsecho.h @@ -28,7 +28,7 @@ #include "ini_file.h" #define SBBSECHO_VERSION_MAJOR 3 -#define SBBSECHO_VERSION_MINOR 22 +#define SBBSECHO_VERSION_MINOR 23 #define SBBSECHO_PRODUCT_CODE 0x12FF /* from http://ftsc.org/docs/ftscprod.013 */ @@ -65,7 +65,7 @@ enum pkt_type { #define SBBSECHO_MAX_TICPWD_LEN 40 /* FRL-1039: no restrictions on the length ... of the password */ typedef struct { - uint sub; /* Set to INVALID_SUB if pass-thru */ + int sub; /* Set to INVALID_SUB if pass-thru */ char* tag; /* AreaTag, a.k.a. 'EchoTag' */ uint imported; /* Total messages imported this run */ uint exported; /* Total messages exported this run */