// This may look like C code, but it is really -*- C++ -*- // ------------------------------------------------------------------ // The Goldware Library // Copyright (C) 1999-2002 Alexander S. Aganichev // ------------------------------------------------------------------ // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Library General Public // License as published by the Free Software Foundation; either // version 2 of the License, or (at your option) any later version. // // This library 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 // Library General Public License for more details. // // You should have received a copy of the GNU Library General Public // License along with this program; if not, write to the Free // Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, // MA 02111-1307, USA // ------------------------------------------------------------------ // $Id$ // ------------------------------------------------------------------ // Read areas from Fidoconfig // ------------------------------------------------------------------ #include #include #include #include #include #if defined(__GOLD_GUI__) #include #include #endif #undef GCFG_NOFIDOCONF #include // ------------------------------------------------------------------ static char comment_char = '#'; // ------------------------------------------------------------------ bool gareafile::ReadHPTLine(gfile &f, std::string& str) { char buf[1024]; if (!f.Fgets(buf, ARRAYSIZE(buf))) return false; // eof str = buf; if (!str.empty() && (*(str.end() - 1) != '\n')) { while (f.Fgets(buf, ARRAYSIZE(buf))) { str += buf; if (*(str.end() - 1) == '\n') break; } } std::string::iterator ptr = str.begin(); std::string::iterator end = str.end(); bool state = false; // state 0: normal state // 1: between "" // 2: end // 3: whitespace for (; ptr != end; ptr++) { if (comment_char == *ptr) { if (!state) { str.erase(ptr, end); break; } } else if ('\"' == *ptr) { state = !state; } } strltrim(strtrim(str)); return true; } // ------------------------------------------------------------------ void gareafile::gettok(char** key, char** val) { char* p = strskip_wht(*val); // Get the keyword switch(*p) { // Strip "double" quotes case '\"': *key = ++p; do { p = strskip_to(p, '\"'); if(not *p or (*(p-1) != '\\')) break; else p++; } while(*p); break; // Strip 'single' quotes case '\'': *key = ++p; do { p = strskip_to(p, '\''); if(not *p or (*(p-1) != '\\')) break; else p++; } while(*p); break; // Strip round brackets case '(': /*)*/ *key = ++p; p = strskip_to(p, /*(*/ ')'); break; // Get straight keyword default: *key = p; while(*p and not isspace(*p)) p++; } // Nul-terminate keyword if(*p) *p++ = NUL; // Skip whitespace if any p = strskip_wht(p); // Get the value *val = p; } // ------------------------------------------------------------------ void gareafile::ReadHPTFile(char* path, char* file, char* origin, int group) { const word CRC_ADDRESS = 0xFDD6; const word CRC_INCLUDE = 0x379B; const word CRC_NETAREA = 0x8F1C; const word CRC_NETMAILAREA = 0xD2D7; const word CRC_LOCALAREA = 0xAEC1; const word CRC_ECHOAREA = 0x0D63; const word CRC_DUPEAREA = 0xD8B9; const word CRC_BADAREA = 0x8DA5; const word CRC_SYSOP = 0x967F; const word CRC_VERSION = 0xF78F; const word CRC_COMMENTCHAR = 0xE2CC; const word CRC_ECHOAREADEFAULTS = 0x2CBB; const word CRC_SET = 0x2FC2; AreaCfg aa; Path buf2; gfile fp(file, "rb", sharemode); if (fp.isopen()) { fp.SetvBuf(NULL, _IOFBF, 8192); if (not quiet) STD_PRINTNL("* Reading " << file); aa.reset(); aa.type = GMB_NONE; aa.basetype = fidomsgtype; aa.groupid = group; std::string s; while (ReadHPTLine(fp, s)) { if (not s.empty()) { char *alptr = throw_xstrdup(s.c_str()); char *ptr = alptr; char* key; char* val = ptr; gettok(&key, &val); switch (strCrc16(key)) { case CRC_SET: if (strchg(val, '[', '%') != 0) strchg(val, ']', '%'); putenv(val); break; case CRC_VERSION: { int ver_maj, ver_min; sscanf(val, "%d.%d", &ver_maj, &ver_min); if (((ver_maj << 16) + ver_min) > 0x00010009) { STD_PRINTNL("* Error: Unknown fidoconfig version " << ver_maj << '.' << ver_min << " - Skipping."); throw_xfree(alptr); goto skip_config; } } break; case CRC_ADDRESS: CfgAddress(val); break; case CRC_SYSOP: CfgUsername(val); break; case CRC_INCLUDE: strxcpy(buf2, val, sizeof(buf2)); if(strchg(buf2, '[', '%') != 0) strchg(buf2, ']', '%'); MakePathname(buf2, path, buf2); ReadHPTFile(path, buf2, origin, group); break; case CRC_COMMENTCHAR: if((strlen(val) == 3) and (val[0] == val[2]) and strpbrk(val, "\'\"")) comment_char = val[1]; else if(*val) comment_char = val[0]; break; case CRC_NETAREA: case CRC_NETMAILAREA: aa.type = GMB_NET; break; case CRC_LOCALAREA: case CRC_DUPEAREA: case CRC_BADAREA: aa = echoareadefaults; aa.type = GMB_LOCAL; break; case CRC_ECHOAREA: aa = echoareadefaults; aa.type = GMB_ECHO; break; case CRC_ECHOAREADEFAULTS: echoareadefaults.reset(); aa.type = GMB_DEFAULT; aa.basetype = fidomsgtype; aa.groupid = group; break; } if(aa.type != GMB_NONE) { if(aa.type == GMB_DEFAULT) { *key = NUL; } else { // Get echoid gettok(&key, &val); aa.setechoid(key); // Get path gettok(&key, &val); } // If not pass-through if (not strieql("Passthrough", key)) { if (strchg(key, '[', '%') != 0) strchg(key, ']', '%'); aa.setpath(key); gettok(&key, &val); for (;;) { if (*key == '-') { char *opt = key + 1; if (strieql(opt, "a")) { gettok(&key, &val); CfgAddress(key); aa.aka.set(key); } else if (strieql(opt, "g")) { gettok(&key, &val); if (isdigit(*key)) aa.groupid = 0x8000 + atoi(key); else if (g_isalpha(*key)) aa.groupid = g_toupper(*key); } else if (strieql(opt, "d")) { gettok(&key, &val); aa.setdesc(key); } else if (strieql(opt, "pass")) { aa.type = GMB_NONE; break; } else if (strieql(opt, "p") or strieql(opt, "$m") or strieql(opt, "lr") or strieql(opt, "lw") or strieql(opt, "dupeCheck") or strieql(opt, "dupehistory") or strieql(opt, "r") or strieql(opt, "w") or strieql(opt, "l") or strieql(opt, "fperm") or strieql(opt, "fowner") or strnieql(opt, "sbadd(", 6) or strnieql(opt, "sbign(", 6)) { gettok(&key, &val); } //else if(strieql(opt, "h") or strieql(opt, "manual") // or strieql(opt, "nopause") or strieql(opt, "mandatory") // or strieql(opt, "dosfile") or strieql(opt, "ccoff") // or strieql(opt, "b") or strieql(opt, "tinysb") // or strieql(opt, "killsb") or strieql(opt, "keepunread") // or strieql(opt, "killread") or strieql(opt, "h") // or strieql(opt, "nolink") or strieql(opt, "debug") // or strieql(opt, "nopack") or strieql(opt, "keepsb") // or strieql(opt, "$") or strieql(opt, "0")) //{ //} } else if (strieql(key, "Squish")) aa.basetype = "SQUISH"; else if (strieql(key, "Jam" )) aa.basetype = "JAM"; else if (strieql(key, "MSG" )) aa.basetype = fidomsgtype; else { break; } gettok(&key, &val); } aa.setorigin(origin); switch(aa.type) { case GMB_NET: aa.attr = attribsnet; if (aa.basetype.empty()) aa.basetype = fidomsgtype; AddNewArea(aa); break; case GMB_ECHO: aa.attr = attribsecho; if (aa.basetype.empty()) aa.basetype = fidomsgtype; AddNewArea(aa); break; case GMB_LOCAL: aa.attr = attribslocal; if (aa.basetype.empty()) aa.basetype = fidomsgtype; AddNewArea(aa); break; case GMB_DEFAULT: echoareadefaults = aa; break; default: break; } } aa.reset(); } throw_xfree(alptr); } } skip_config:; } else { STD_PRINTNL(" * AREAFILE FIDOCONFIG: Can't open file '" << path << GOLD_SLASH_STR << file << ": " << strerror(errno) ); } } // ------------------------------------------------------------------ // Read areas from HPT (echomail processor) void gareafile::ReadHPT(char* tag) { char origin[80]; char options[80]; word defaultgroup = 0; Path file, path; *origin = NUL; *file = NUL; strcpy(options, tag); char* ptr = strtok(tag, " \t"); while(ptr) { if(*ptr != '-') strcpy(file, ptr); else { if(g_toupper(*(++ptr)) == 'G') { if(*(++ptr) == '=') ptr++; if(*ptr == '#') defaultgroup = (word)(atoi(ptr+1)+0x8000u); else defaultgroup = (word)(g_isupper(*ptr) ? *ptr : 0); } } ptr = strtok(NULL, " \t"); } if(not *file and ((ptr = getenv("FIDOCONFIG"))!=NULL)) strcpy(file, ptr); extractdirname(path, file); CfgSquishuserpath(path); CfgJAMSMAPIHighwater(true); echoareadefaults.type = GMB_NONE; echoareadefaults.basetype = fidomsgtype; echoareadefaults.groupid = defaultgroup; ReadHPTFile(path, file, origin, defaultgroup); } // ------------------------------------------------------------------