/******************************************************************** * wilkinson * 3.36VMS-2 * 1996/01/28 14:00 * gopher_root1:[gopher.g2.vms2_13.gopherd]gopherdconf.c,v * Exp * * Paul Lindner, University of Minnesota CIS. * * Copyright 1991, 1992 by the Regents of the University of Minnesota * see the file "Copyright" in the distribution for conditions of use. ********************************************************************* * MODULE: gopherdconf.c * Routines to parse the gopherd.conf file. ********************************************************************* * Revision History: * gopherdconf.c,v * Revision 3.36VMS-2 1996/01/28 14:00 wilkinson * Allow OPCOM message console selection configuration to have spaces * * Revision 3.36VMS-1 1996/01/24 11:00 wilkinson * Made OPCOM message console selection configurable * * Revision 3.36VMS 1995/09/25 14:31 wilkinson * Consolodate VMS/Unix source code for server as well as client * * Revision 3.36 1995/02/16 22:32:39 lindner * HTML icon support * * Revision 3.35 1995/02/13 19:07:06 lindner * Add MaxConnection limit for total server * * Revision 3.34 1995/02/11 06:21:26 lindner * remove pid junk * * Revision 3.33 1995/02/06 22:14:50 lindner * remove unused variables * * Revision 3.32 1995/02/02 17:13:54 lindner * Fix memory leaks * * Revision 3.31 1994/12/15 17:33:19 lindner * Add BlockScript: keyword support * * Revision 3.30 1994/12/08 05:23:00 lindner * Fix wording problem in integrity check * * Revision 3.29 1994/10/10 18:39:36 lindner * Change auxconf: to use regular expressions * * Revision 3.28 1994/09/29 19:59:16 lindner * Force people to update their gopherd.conf files * * Revision 3.27 1994/08/18 22:28:17 lindner * Abstract for top level and malloc casts * * Revision 3.26 1994/08/03 03:33:25 lindner * Include files in SERVERDIR * * Revision 3.25 1994/07/22 22:56:18 lindner * More NO_AUTH stuff.. * * Revision 3.24 1994/07/22 22:26:25 lindner * NO_AUTHENTICATION mods * * Revision 3.23 1994/07/22 16:37:07 lindner * Add INCLUDE directive for gopherd.conf files * * Revision 3.22 1994/07/21 17:23:05 lindner * Add File Separator code * * Revision 3.21 1994/06/29 05:30:08 lindner * Add code to handle lists of authscripts and authitems * * Revision 3.20 1994/03/31 22:46:26 lindner * Allow whitespace in the gopherd.conf file before tokens * * Revision 3.19 1994/03/17 21:18:39 lindner * Massive reworking of access limits * * Revision 3.18 1994/03/17 04:30:17 lindner * VMS fixes gopherd.h * * Revision 3.17 1994/03/08 15:56:01 lindner * gcc -Wall fixes * * Revision 3.16 1994/01/21 03:59:11 lindner * Add support for timezone variable and fix return type * * Revision 3.15 1993/12/09 20:48:16 lindner * Debug fixes * * Revision 3.14 1993/10/27 20:36:59 lindner * Plug memory leak * * Revision 3.13 1993/10/20 03:18:17 lindner * Code for ignore_patt: * * Revision 3.12 1993/10/11 04:39:49 lindner * Allow quotes in dirname for auxconf * * Revision 3.11 1993/10/07 05:19:54 lindner * Update for gateway items and GDCevalDir * * Revision 3.10 1993/10/04 06:48:57 lindner * mods to support auxconf files * * Revision 3.9 1993/09/30 17:05:11 lindner * start of subconf * * Revision 3.8 1993/09/21 04:16:50 lindner * Move cache settings into gopherd.conf * * Revision 3.7 1993/08/23 18:46:17 lindner * Crude addition of a veronica top-level block * * Revision 3.6 1993/08/20 18:03:07 lindner * Mods to allow gopherd.conf files control ftp gateway access * * Revision 3.5 1993/07/27 05:27:49 lindner * Mondo Debug overhaul from Mitra * * Revision 3.4 1993/07/23 03:19:20 lindner * Mods for using decoder:'s * * Revision 3.3 1993/04/15 17:09:22 lindner * none * * Revision 3.2 1993/03/24 20:25:14 lindner * Addition for secureusers file * * Revision 3.1.1.1 1993/02/11 18:02:51 lindner * Gopher+1.2beta release * * Revision 1.3 1993/02/09 22:30:56 lindner * Additions for multi-languages * * Revision 1.2 1993/01/30 23:57:44 lindner * Gopher+ stuff * * Revision 1.1 1992/12/10 23:13:27 lindner * gopher 1.1 release * * *********************************************************************/ #ifdef VMS_SERVER #define GSGOPHEROBJ_C #endif #include "gopherdconf.h" #ifdef VMS_SERVER #undef GSGOPHEROBJ_C #include #include "fileio.h" #include #endif #include "Malloc.h" #include "String.h" #include #include "util.h" #include "Debug.h" #include "conf.h" #ifdef VMS_SERVER /* To avoid compliation errors when #including "gopherd.h" or "globals.h" to get these external variables, we'll just define them as external here... */ extern int vms_OPC$M_num; extern int vms_OPC$M_NM[]; extern char *vms_OPC$M_TXT[]; #endif /*********************************************/ GDCobj * GDCnew() { GDCobj *gdc; gdc = (GDCobj *) malloc(sizeof(GDCobj)); gdc->Extensions = EXAnew(); #ifndef NO_AUTHENTICATION gdc->Sites = SiteArrayNew(); gdc->Securityon = FALSE; gdc->Authroutines = AUTHAnew(5); gdc->Authitems = AUTHITEMSnew(5); gdc->Serverpw = STRnew(); #endif gdc->RunFromInetd = FALSE; gdc->Caching = TRUE; gdc->Cachetime = 180; /** Three minutes ***/ gdc->Logfile = STRnew(); gdc->Errorfile = STRnew(); #ifndef VMS_SERVER gdc->Data_Dir = STRnew(); #else gdc->DataDir = STRnew(); #endif gdc->Hostname = STRnew(); gdc->Port = 0; gdc->chroot = TRUE; gdc->Defaccess = ACC_FULL; gdc->BummerMsg = STRnew(); gdc->Admin = STRnew(); gdc->AdminEmail = STRnew(); gdc->Abstract = STRnew(); gdc->Site = STRnew(); gdc->Org = STRnew(); gdc->Geog = STRnew(); gdc->Loc = STRnew(); gdc->Lang = STRnew(); gdc->TZ = 0; gdc->VeronicaIndex = TRUE; gdc->Tixfile = STRnew(); STRset(gdc->Logfile, ""); STRset(gdc->Errorfile, ""); STRset(gdc->BummerMsg, ""); STRset(gdc->Hostname, ""); gdc->other_dirs = STAnew(2); gdc->other_gdcs = STAnew(2); gdc->FileSeparators = STAnew(5); gdc->BlkScriptBlocks = STAnew(5); gdc->BlkScripts = STAnew(5); gdc->MaxConnections = -1; #ifdef VMS_SERVER /* Override Unix defaults w/ VMS ones, or provide initialization when it's omitted under Unix */ gdc->Port = GOPHER_PORT; gdc->chroot = FALSE; gdc->TZ = -1; gdc->TimeZoneText = STRnew(); gdc->MaxLoad = 0.0; /* New VMS configuration options */ gdc->IsGplus = FALSE; gdc->IgnoreAll = FALSE; gdc->SortDir = TRUE; gdc->FTPPort = -1; gdc->EXECPort = -1; gdc->SRCHPort = -1; gdc->OVERPort = -1; gdc->OVERSize = -1; gdc->SortShell = TRUE; gdc->SortGREP = TRUE; gdc->SortCMD1 = TRUE; gdc->ReadTimeout = READTIMEOUT; gdc->OPCOM = OPC$M_NM_CENTRL | OPC$M_NM_NTWORK; gdc->Hidden_Prefix= STRnew(); gdc->Link_Prefix = STRnew(); gdc->LookAside = STRnew(); gdc->DName = STRnew(); gdc->DHead = STRnew(); gdc->DFoot = STRnew(); gdc->Scratch_Dir = STRnew(); gdc->Support_Dir = STRnew(); gdc->Spawn_Init = STRnew(); gdc->RestartLnm = STRnew(); gdc->ConfigFile = STRnew(); gdc->LogFileTag = STRnew(); gdc->rollover = ROLLOVER_NEVER; /* Initialize strings for VMS */ STRset(gdc->DataDir, DATA_DIRECTORY); STRset(gdc->Admin, ""); STRset(gdc->AdminEmail, ""); STRset(gdc->Site, ""); STRset(gdc->Org, ""); STRset(gdc->Geog, ""); STRset(gdc->Lang, ""); STRset(gdc->Loc, ""); STRset(gdc->TimeZoneText,""); STRset(gdc->Hidden_Prefix, "_"); STRset(gdc->Link_Prefix, "."); STRset(gdc->LookAside, ".cap"); STRset(gdc->DName, ""); STRset(gdc->DHead, ""); STRset(gdc->DFoot, ""); STRset(gdc->Scratch_Dir,"sys$scratch:"); STRset(gdc->Support_Dir,"sys$disk:"); STRset(gdc->Spawn_Init, LOGINCOM); STRset(gdc->RestartLnm, RESTART); STRset(gdc->ConfigFile, CONF_FILE); STRset(gdc->LogFileTag, ""); #endif return(gdc); } void GDCdestroy(gdc) GDCobj *gdc; { #ifdef VMS_SERVER /* Oops... did this get misplaced for unix? */ EXAdestroy(gdc->Extensions); #endif #ifndef NO_AUTHENTICATION #ifndef VMS_SERVER /* Oops... did this get misplaced for unix? */ EXAdestroy(gdc->Extensions); #endif SiteArrDestroy(gdc->Sites); AUTHAdestroy(gdc->Authroutines); AUTHITEMSdestroy(gdc->Authitems); STRdestroy(gdc->Serverpw); #endif STRdestroy(gdc->Logfile); STRdestroy(gdc->BummerMsg); STRdestroy(gdc->Hostname); STRdestroy(gdc->Lang); STRdestroy(gdc->Tixfile); STRdestroy(gdc->Abstract); /** etc..**/ STAdestroy(gdc->other_dirs); STAdestroy(gdc->other_gdcs); STAdestroy(gdc->FileSeparators); STAdestroy(gdc->BlkScriptBlocks); STAdestroy(gdc->BlkScripts); #ifdef VMS_SERVER STRdestroy(gdc->Hidden_Prefix); STRdestroy(gdc->Link_Prefix); STRdestroy(gdc->LookAside); STRdestroy(gdc->DName); STRdestroy(gdc->DHead); STRdestroy(gdc->DFoot); STRdestroy(gdc->Scratch_Dir); STRdestroy(gdc->Support_Dir); STRdestroy(gdc->Spawn_Init); STRdestroy(gdc->RestartLnm); STRdestroy(gdc->ConfigFile); STRdestroy(gdc->LogFileTag); /* Don't forget these; they're strings, too */ STRdestroy(gdc->Errorfile); STRdestroy(gdc->DataDir); STRdestroy(gdc->Admin); STRdestroy(gdc->AdminEmail); STRdestroy(gdc->Site); STRdestroy(gdc->Org); STRdestroy(gdc->Loc); STRdestroy(gdc->Geog); STRdestroy(gdc->TimeZoneText); #endif free(gdc); } #define MAXGDCFLEVEL 10 static FILE *GDCfiles[MAXGDCFLEVEL]; /* can 'include' up to ten levels deep */ static int GDCfilenum = -1; static void GDCfilePush(f) FILE *f; { if ((++GDCfilenum) < MAXGDCFLEVEL) GDCfiles[GDCfilenum] = f; else { #ifndef VMS_SERVER fprintf(stderr, "Nesting level too deep for include directive\n"); exit(-1); #else VMS$fprintf(stderr, "Nesting level too deep for include directive\n"); gopherd_exit(-1); #endif } } static char * GDCfileGetline(inputline, size) char *inputline; int size; { char* farg; while (NULL == (farg = fgets(inputline, size, GDCfiles[GDCfilenum]))) { if (GDCfilenum == 0) { fclose(GDCfiles[GDCfilenum]); return(farg); } /** Try popping up to the previous file.. **/ fclose(GDCfiles[GDCfilenum]); GDCfilenum--; } return(farg); } /* * Parse Gopherd.conf tokens.. */ static boolean GDCtokens(gdc, token, rest) GDCobj *gdc; char *token; char *rest; { boolean success = TRUE; #ifdef VMS_SERVER Debug("GDC: %s: ", token); Debug("%s\n", rest); if ((strcasecmp(token, "ACCESS") != 0) && (strcasecmp(token, "ABSTRACT") != 0) && /* Add here any other selections which we don't want to allow a "!" to terminate the line as traditional OpenVMS DCL-style commentary */ (strcasecmp(token, "ADMINEMAIL") != 0)) { char *cp; if ((cp = strchr(rest, '!')) != NULL) { *cp = '\0'; /* Allow VMS-style "!" commentary as well */ for(--cp;isspace(*cp)||!isprint(*cp);cp--) *cp = '\0'; /* Strip trailing non-text */ } } #endif if (strcasecmp(token, "ADMIN")==0) GDCsetAdmin(gdc, rest); #ifndef NO_AUTHENTICATION else if (strcasecmp(token, "ACCESS") == 0) { Accesslevel moo; success = SiteProcessLine(gdc->Sites, rest, gdc->Defaccess); moo = SiteDefAccess(gdc->Sites); if (moo != ACC_UNKNOWN) gdc->Defaccess = moo; gdc->Securityon = TRUE; } else if (strcasecmp(token, "AUTHSCRIPT")==0) { success = AUTHAprocessLine(gdc->Authroutines, rest); } else if (strcasecmp(token, "AUTHITEM")==0) { success = AUTHITEMSprocessLine(gdc->Authitems, rest); } else if (strcasecmp(token, "SERVERPW")==0) { GDCsetPW(gdc, rest); } #endif else if (strcasecmp(token, "ADMINEMAIL")==0) GDCsetAdminEmail(gdc, rest); else if (strcasecmp(token, "HOSTALIAS")==0) GDCsetHostname(gdc, rest); else if (strcasecmp(token, "SITE")==0) GDCsetSite(gdc, rest); else if (strcasecmp(token, "ORG")==0) GDCsetOrg(gdc, rest); else if (strcasecmp(token, "LOC")==0) GDCsetLoc(gdc, rest); else if (strcasecmp(token, "LOGFILE")==0) GDCsetLogfile(gdc, rest); else if (strcasecmp(token, "ERRORFILE")==0) GDCsetErrorfile(gdc, rest); else if (strcasecmp(token, "GEOG")==0) GDCsetGeog(gdc, rest); else if (strcasecmp(token, "BUMMERMSG")==0) GDCsetBummerMsg(gdc, rest); else if (strcasecmp(token, "LANGUAGE")==0) { rest = skip_whitespace(rest); GDCsetLang(gdc, rest); } #ifndef VMS_SERVER /* Do TimeZones differently for OpenVMS */ else if (strcasecmp(token, "TZ") == 0) GDCsetTZ(gdc,atoi(rest)); #endif else if (strcasecmp(token, "VIEWEXT")==0) { success = EXAprocessLine(gdc->Extensions, EXT_VIEW, rest, GDCgetLang(gdc)); } else if (strcasecmp(token, "BLOCKEXT")==0) { success = EXAprocessLine(gdc->Extensions, EXT_BLOCK, rest, NULL); } else if (strcasecmp(token, "BLOCKREFEXT")==0) { success = EXAprocessLine(gdc->Extensions, EXT_BLOCKREF, rest, NULL); } else if (strcasecmp(token, "IGNORE")==0) { success = EXAprocessLine(gdc->Extensions, EXT_IGNORE, rest, NULL); } else if (strcasecmp(token, "IGNORE_PATT")==0) { success = EXAprocessLine(gdc->Extensions, EXT_IGNOREPAT, rest, NULL); } else if (strcasecmp(token, "DECODER")==0) { success = EXAprocessLine(gdc->Extensions, EXT_DECODER, rest, NULL); } else if (strcasecmp(token, "ABSTRACT") == 0) { GDCsetAbstract(gdc, rest); } else if (strcasecmp(token, "VERONICAINDEX")==0) { if (strcasecmp(rest, "no")==0) GDCsetShouldIndex(gdc, FALSE); else GDCsetShouldIndex(gdc, TRUE); } else if (strcasecmp(token, "CACHETIME")==0) { GDCsetCachetime(gdc, atoi(rest)); } else if (strcasecmp(token, "FILESEP")==0) { GDCaddFileSep(gdc, rest); } else if (strcasecmp(token, "INCLUDE") == 0) { /** Check to see if we can open the file.. **/ /** Then push it onto the stack.. **/ FILE *gdcfile; #ifndef VMS_SERVER if (*rest != '/') { char tmpstr[256]; sprintf(tmpstr, "%s/%s", GDCDIR, rest); strcpy(rest, tmpstr); } #endif if ((gdcfile = fopen(rest, "r")) == (FILE *) NULL) { #ifndef VMS_SERVER fprintf(stderr,"Cannot open file '%s'\n", rest); exit(-1); #else VMS$fprintf(stderr,"Cannot open file '%s'\n", rest); gopherd_exit(-1); #endif } GDCfilePush(gdcfile); } else if (strcasecmp(token, "BLOCKSCRIPT") == 0) { char *cp; /** Block name is first argument, script to run is second **/ cp = strchr(rest, ' '); if (cp != NULL) { *cp = '\0'; cp++; GDCpushBlockScript(gdc, rest, cp); } else { success = FALSE; } } #ifndef VMS_SERVER else if (strcasecmp(token, "AUXCONF")==0) { /** Directory is first arg, conf file is second **/ char *cp; if (*rest == '\"') { /*** " Dir is in quotes.. ***/ rest++; cp = strchr(rest, '\"'); /* " Fix for hilit19 */ if (cp != NULL) { *cp = '\0'; cp ++; } } else { cp = strchr(rest, ' '); } if (cp == NULL) success = FALSE; else { *cp = '\0'; GDCpushOtherGDC(gdc, rest, cp+1); } } #endif else if (strcasecmp(token, "MAXCONNECTIONS")==0) { int numconns = atoi(rest); if (numconns > 1) GDCsetMaxconns(gdc, atoi(rest)); } #ifdef VMS_SERVER /* VMS configuration options follow */ /* Although these first few options probably ought to be configurable for Unix as well, oughtn't they? */ else if (strcasecmp(token, "EXT")==0) { success = EXAprocessLine(gdc->Extensions, EXT_MISC, rest, NULL); } else if (strcasecmp(token, "DataDirectory")==0) GDCsetDatadir(gdc, rest); else if (strcasecmp(token, "Port")==0) GDCsetPort(gdc, atoi(rest)); else if (strcasecmp(token, "INETD")==0) { if (strcasecmp(rest, "True")==0) GDCsetInetdActive(gdc,TRUE); else GDCsetInetdActive(gdc, FALSE); } else if (strcasecmp(token, "MaxLoad")==0) GDCsetMaxLoad(gdc, atof(rest)); else if ((strcasecmp(token, "TimeZone")==0) || (strcasecmp(token, "TZ")==0)) { if ( (strncmp(rest, "-", 1)==0) && isdigit(*(rest+1)) ) GDCsetTZ(gdc, -atoi(rest+1)); else if ( (strncmp(rest, "+", 1)==0) && isdigit(*(rest+1)) ) GDCsetTZ(gdc, atoi(rest+1)); else if (isdigit(*rest)) GDCsetTZ(gdc, atoi(rest)); else { /* Mnemonic Timezone */ GDCsetTZ(gdc,-1); GDCsetTimeZone(gdc,rest); return(success); } if (abs(GDCgetTZ(gdc))<100) GDCsetTZ(gdc,GDCgetTZ(gdc)*100); } /* Now these remaining options are actually VMS specific */ else if (strcasecmp(token, "IsGplus")==0) { if (strcasecmp(rest, "True")==0) GDCsetIsGplus(gdc,TRUE); else GDCsetIsGplus(gdc, FALSE); } else if (strcasecmp(token, "IgnoreAll")==0) { if (strcasecmp(rest, "True")==0) GDCsetIgnoreAll(gdc,TRUE); else GDCsetIgnoreAll(gdc, FALSE); } else if (strcasecmp(token, "SortDir")==0) { if (strcasecmp(rest, "True")==0) GDCsetSortDir(gdc,TRUE); else GDCsetSortDir(gdc, FALSE); } else if (strcasecmp(token, "FTPPort")==0) { if (strcasecmp(rest, "None")==0) GDCsetFTPPort(gdc,0); else GDCsetFTPPort(gdc, atoi(rest)); } else if (strcasecmp(token, "EXECPort")==0) { if (strcasecmp(rest, "None")==0) GDCsetEXECPort(gdc,0); else GDCsetEXECPort(gdc, atoi(rest)); } else if (strcasecmp(token, "SRCHPort")==0) { if (strcasecmp(rest, "None")==0) GDCsetSRCHPort(gdc,0); else GDCsetSRCHPort(gdc, atoi(rest)); } else if (strcasecmp(token, "OVERPort")==0) { int threshold; char *cp = strchr(rest,','); GDCsetOVERSize(gdc,-1); if (strcasecmp(rest, "None")==0) GDCsetOVERPort(gdc,0); else { GDCsetOVERPort(gdc, atoi(rest)); if (cp) { while (*(++cp)==' '); GDCsetOVERSize(gdc, (threshold=atoi(cp))?threshold:-1); } } } else if (strcasecmp(token, "SortShell")==0) { if (strcasecmp(rest, "True")==0) GDCsetSortShell(gdc,TRUE); else GDCsetSortShell(gdc, FALSE); } else if (strcasecmp(token, "SortGREP")==0) { if (strcasecmp(rest, "True")==0) GDCsetSortGREP(gdc,TRUE); else GDCsetSortGREP(gdc, FALSE); } else if (strcasecmp(token, "SortCMD1")==0) { if (strcasecmp(rest, "True")==0) GDCsetSortCMD1(gdc,TRUE); else GDCsetSortCMD1(gdc, FALSE); } else if (strcasecmp(token, "ReadTimeout")==0) GDCsetReadTimeout(gdc, atoi(rest)); else if (strcasecmp(token, "Console")==0) { int opc; int ox; char *cp = strchr(rest,'+'); GDCsetOPCOM(gdc, opc = 0); while (rest) { if (cp) *cp = '\0'; while (*rest==' ') rest++; ox = strlen(rest) - 1; while (*(rest+ox)==' ') *(rest+ox--) = '\0'; for (ox=0; ox 1) && inputline[inputlen-1] == GDCcontinue) { inputline[inputlen-1] = '\n'; if (!GDCfileGetline(inputline + inputlen, sizeof(inputline)-inputlen)) break; ZapCRLF(inputline+inputlen); inputlen += strlen(inputline+inputlen); } /** Eat whitespace **/ linestart= inputline; for ( ; *linestart != '\0' && *linestart <= ' '; linestart++) ; if (*linestart == '#' || *linestart == '\0') /** Ignore comments **/ continue; cp = strchr(linestart, ':'); if (cp == NULL) { #ifndef VMS_SERVER fprintf(stderr, "Bad line '%s'\n", inputline); fprintf(stderr, "Line needs a colon\n"); exit(-1); #else VMS$fprintf(stderr, "Bad line '%s'\nLine needs a colon\n", inputline); bad_cfg++; continue; #endif } *cp = '\0'; token = linestart; restofline = cp+1; while (*restofline == ' ' || *restofline == '\t') restofline++; success = GDCtokens(gdc, token, restofline); if (!success) { #ifndef VMS_SERVER fprintf(stderr, "Bad line '%s'\n", inputline); if (strcasecmp(inputline, "ext")==0) fprintf(stderr, "please upgrade your gopherd.conf file\n"); exit(-1); #else VMS$fprintf(stderr, "Bad line '%s'\n", inputline); *cp = ':'; bad_cfg++; continue; #endif } } #ifdef VMS_SERVER fclose(gdcfile); if (bad_cfg) { VMS$fprintf(stderr, "\n\t%d configuration errors detected\n",bad_cfg); VMS$fprintf(stderr, "\tplease upgrade your configuration file\n"); /* exit(-1) from detached server would just */ if (gdc->RunFromInetd) /* loop; so ignore the errors now, have */ gopherd_exit(-1); /* the user fix them & restart */ VMS$fprintf(stderr, "\tand restart this detached server with the new cfg\n"); } #endif } void GDCpushOtherGDC(gdc, dir, conffile) GDCobj *gdc; char *dir; char *conffile; { String *temp; temp = STRnew(); STRset(temp, dir); STApush(gdc->other_dirs, temp); STRset(temp, conffile); STApush(gdc->other_gdcs, temp); STRdestroy(temp); } void GDCpushBlockScript(gdc, blockname, scriptname) GDCobj *gdc; char *blockname; char *scriptname; { String *temp; temp = STRnew(); STRset(temp, blockname); STApush(gdc->BlkScriptBlocks, temp); STRset(temp, scriptname); STApush(gdc->BlkScripts, temp); STRdestroy(temp); } /* * Search for otherdir gdcs */ char * GDCfindOtherGDC(gdc, dir) GDCobj *gdc; char *dir; { int i; for (i=0; iother_dirs); i++) if (strcmp(STAgetText(gdc->other_dirs, i), dir)) return(STAgetText(gdc->other_gdcs, i)); return(NULL); } boolean GDCevalDir(gdc, dir) GDCobj *gdc; char *dir; { int i, gdcdirlen; char *gdcdir, *conf; int dirlen; if (dir == NULL) return(FALSE); dirlen = strlen(dir); for (i=0; iother_dirs); i++) { gdcdir = STAgetText(gdc->other_dirs, i); gdcdirlen = strlen(gdcdir); /* if (gdcdirlen <= dirlen && strncmp(dir, gdcdir, gdcdirlen)==0) {*/ if (re_comp(gdcdir)) return(TRUE); if (re_exec(dir)) { conf = STAgetText(gdc->other_gdcs, i); GDCfromFile(gdc, conf); Debug("Loading up aux gopherd.conf file %s", conf); Debug("For item %s\n", gdcdir); } } return(TRUE); } #ifndef NO_AUTHENTICATION AccessResult GDCCanSearch(gdc, hostname, ipnum, sessions) GDCobj *gdc; char *hostname, *ipnum; int sessions; { AccessResult test; Debug("Testing %s/", hostname); Debug("%s for searching\n", ipnum); if (gdc->Securityon == FALSE) return(SITE_OK); test = SiteAccess(gdc->Sites, hostname, ipnum, ACC_SEARCH, sessions); return(test); } AccessResult GDCCanRead(gdc, hostname, ipnum, sessions) GDCobj *gdc; char *hostname, *ipnum; int sessions; { AccessResult test; Debug("Testing %s/", hostname); Debug("%s for reading\n", ipnum); if (gdc->Securityon == FALSE) return(SITE_OK); test = SiteAccess(gdc->Sites, hostname, ipnum, ACC_READ, sessions); return(test); } AccessResult GDCCanBrowse(gdc, hostname, ipnum, sessions) GDCobj *gdc; char *hostname, *ipnum; int sessions; { AccessResult test; Debug("Testing %s/", hostname); Debug("%s for browsing\n", ipnum); if (gdc->Securityon == FALSE) return(SITE_OK); test = SiteAccess(gdc->Sites, hostname, ipnum, ACC_BROWSE, sessions); return(test); } AccessResult GDCCanFTP(gdc, hostname, ipnum, sessions) GDCobj *gdc; char *hostname, *ipnum; int sessions; { AccessResult test; Debug("Testing %s/", hostname); Debug("%s for ftping\n", ipnum); if (gdc->Securityon == FALSE) return(SITE_OK); test = SiteAccess(gdc->Sites, hostname, ipnum, ACC_FTP, sessions); return(test); } #ifdef VMS_SERVER AccessResult GDCCanEXEC(gdc, hostname, ipnum, sessions) GDCobj *gdc; char *hostname, *ipnum; int sessions; { AccessResult test; Debug("Testing %s/", hostname); Debug("%s for exec\n", ipnum); if (gdc->Securityon == FALSE) return(SITE_OK); test = SiteAccess(gdc->Sites, hostname, ipnum, ACC_EXEC, sessions); return(test); } AccessResult GDCcanAccess(gdc, hostname, ipnum, sessions, access) GDCobj *gdc; char *hostname, *ipnum; int sessions, access; { if (gdc->Securityon == FALSE) return(SITE_OK); switch(access) { case ACC_READ: return(GDCCanRead(gdc, hostname, ipnum, sessions)); case ACC_BROWSE: return(GDCCanBrowse(gdc, hostname, ipnum, sessions)); case ACC_SEARCH: return(GDCCanSearch(gdc, hostname, ipnum, sessions)); case ACC_FTP: return(GDCCanFTP(gdc, hostname, ipnum, sessions)); case ACC_EXEC: return(GDCCanEXEC(gdc, hostname, ipnum, sessions)); default: return(SITE_OK); } } #endif char * GDCauthType(gdc, item) GDCobj *gdc; char *item; { if (item == NULL) return(NULL); return(AUTHITEMSfindType(gdc->Authitems, item)); } AUTHresult GDCvalidate(gdc, type, username, password, hostname, hostip) GDCobj *gdc; char *type; char *username, *password, *hostname, *hostip; { if (type == NULL) return(AUTHRES_OK); /* If no auth method then it's okay. */ return(AUTHAvalidate(gdc->Authroutines,type, username, password, hostname, hostip)); } /* * Find the ask block for an authenticated item.. */ char ** GDCauthAsk(gdc, path) GDCobj *gdc; char *path; { AUTH *auth; Debug("Looking for %s\n", path); auth = AUTHITEMSfindAUTH(gdc->Authitems, gdc->Authroutines, path); if (auth == NULL) { Debug("Couldn't find %s\n", path); return(NULL); } return(AUTHgetAskFcn(auth)(path, "", "")); } #endif /** Is this file ignored? **/ boolean GDCignore(gdc, fname) GDCobj *gdc; char *fname; { Extobj *ext; ext = EXnew(); if (EXAsearch(gdc->Extensions, ext, fname, EXT_IGNORE)) { EXdestroy(ext); return(TRUE); } else { EXdestroy(ext); return(FALSE); } } boolean GDCViewExtension(gdc, fext, extin) GDCobj *gdc; char *fext; Extobj **extin; { Extobj *ext; ext = EXnew(); if (EXAsearch(gdc->Extensions, ext, fext, EXT_VIEW)) { *extin = ext; return(TRUE); } else { EXdestroy(ext); return(FALSE); } } boolean GDCBlockExtension(gdc, fext, ext) GDCobj *gdc; char *fext; Extobj *ext; { if (EXAsearch(gdc->Extensions, ext, fext, EXT_BLOCK)) { return(TRUE); } else return(FALSE); } void GDCaddFileSep(gdc, expr) GDCobj *gdc; char *expr; { String *temp; temp = STRnew(); if (temp == NULL) return; STRset(temp, expr); STApush(gdc->FileSeparators, temp); STRdestroy(temp); } static boolean GDCisBlank(string) char *string; { if (string == NULL || strncmp(string, "blank", 5) == 0) return TRUE; else return(FALSE); } void GDCintegrityCheck(gdc) GDCobj *gdc; { #ifdef VMS_SERVER #ifdef fprintf #define hold_fprintf fprintf #undef fprintf #endif #define fprintf VMS$fprintf #endif if (GDCisBlank(GDCgetSite(gdc))) fprintf(stderr, "** Please set the Site: line in your configuration file!\n"); if (GDCisBlank(GDCgetOrg(gdc))) fprintf(stderr, "** Please set the Org: line in your configuration file!\n"); if (GDCisBlank(GDCgetLoc(gdc))) fprintf(stderr, "** Please set the Loc: line in your configuration file!\n"); if (GDCisBlank(GDCgetAbstract(gdc))) fprintf(stderr, "** Please set the Abstract: line in your configuration file!\n"); if (GDCisBlank(GDCgetAdmin(gdc))) fprintf(stderr, "** Please set the Admin: line in your configuration file!\n"); if (GDCisBlank(GDCgetAdminEmail(gdc))) fprintf(stderr, "** Please set the AdminEmail: line in configuration file!\n"); #ifdef VMS_SERVER #ifdef hold_fprintf #define fprintf hold_fprintf #undef hold_fprintf #endif #endif } #ifdef VMS_SERVER /** VMS version supports logfile rollover, so we can't just pick up a string and return it like the UNIX macro does -- we need real code which builds the current timestamped value and returns it. **/ char *GDCgetLogfile(gdc) GDCobj *gdc; { static char rollover[256]; char insert[11]; time_t Now; char *mx; int i; char cdate[26]; extern char log_alq[10]; extern char log_deq[10]; static char *DaysofWeek="SunMonTueWedThuFriSat"; static char *Months = "JanFebMarAprMayJunJulAugSepOctNovDec"; #define DOW (cdate+0) #define MMM (cdate+4) #define DD (cdate+8) #define HH (cdate+11) #define YYYY (cdate+20) if (!gdc) return(NULL); if (!(mx=STRget(gdc->Logfile))) return(NULL); if (!strlen(mx)) return(NULL); time(&Now); strcpy(cdate,(char *)ctime(&Now)); cdate[3] = cdate[7]= cdate[10]= cdate[13] = cdate[24]= '\0'; if (GDCgetRollover(gdc)==ROLLOVER_WEEKLY) { mx=strstr(DaysofWeek,DOW); if (i = ((mx - DaysofWeek)/3)) { Now -= (i * (24 * 60 * 60)); strcpy(cdate,(char *)ctime(&Now)); cdate[3] = cdate[7]= cdate[10]= cdate[13] = cdate[24]= '\0'; } } if (cdate[8]==' ') cdate[8] = '0'; mx=strstr(Months,MMM); i = mx - Months; sprintf(insert,"%s%02d%s%s",YYYY,(i/3)+1,DD,HH); switch(GDCgetRollover(gdc)) { case ROLLOVER_ANNUALLY: insert[4] = '\0'; i = ALQ_ANNUAL; break; case ROLLOVER_MONTHLY: insert[6] = '\0'; i = ALQ_MONTH; break; case ROLLOVER_WEEKLY: insert[8] = '\0'; i = ALQ_WEEK; break; case ROLLOVER_DAILY: insert[8] = '\0'; i = ALQ_DAY; break; case ROLLOVER_HOURLY: insert[10]= '\0'; i = ALQ_HOUR; break; case ROLLOVER_NEVER: default: insert[0] = '\0'; i = ALQ_NEVER; } sprintf(log_alq,"alq=%d",i); sprintf(log_deq,"deq=%d",i); strcpy(rollover,STRget(gdc->Logfile)); strcat(rollover,insert); return(rollover); } void GDCfromLink(gdc, fio, sep) GDCobj *gdc; FileIO *fio; char sep; { char inputline[512]; char *cp, *linestart, *token, *restofline; int inputlen; boolean success; int position; position = FIOtell(fio); while (inputlen = FIOreadlinezap(fio, inputline, sizeof(inputline))) { while ((inputlen > 1) && inputline[inputlen-1] == GDCcontinue) { inputline[inputlen-1] = '\n'; if (inputlen += FIOreadlinezap(fio, inputline + inputlen, sizeof(inputline)-inputlen)) break; } ZapCRLF(inputline); inputlen = strlen(inputline); /** Eat whitespace **/ linestart= inputline; for ( ; *linestart != '\0' && *linestart <= ' '; linestart++) ; if (*linestart == '#' || *linestart == '\0') /** Ignore comments **/ continue; if (!(cp = strchr(linestart, sep))) { FIOseek(fio, position); /* Back up to beginning of this line */ return; } *cp = '\0'; token = linestart; restofline = cp+1; while (*restofline == ' ' || *restofline == '\t') restofline++; success = GDCtokens(gdc, token, restofline); if (!success) { FIOseek(fio, position); /* Back up to beginning of this line */ return; } position = FIOtell(fio); } } GDCobj * GDCcpy(orig) GDCobj *orig; { GDCobj *dest = GDCnew(); EXAcpy(dest->Extensions, orig->Extensions); #ifndef NO_AUTHENTICATION SiteArrayCopy(dest->Sites, orig->Sites); dest->Securityon = orig->Securityon; AUTHAcpy(dest->Authroutines, orig->Authroutines); AUTHITEMScpy(dest->Authitems, orig->Authitems); STRcpy(dest->Serverpw, orig->Serverpw); #endif dest->RunFromInetd = orig->RunFromInetd; dest->Caching = orig->Caching; dest->Cachetime = orig->Cachetime; STRcpy(dest->Logfile, orig->Logfile); STRcpy(dest->Errorfile, orig->Errorfile); STRcpy(dest->DataDir, orig->DataDir); STRcpy(dest->Hostname, orig->Hostname); dest->Port = orig->Port; dest->chroot = orig->chroot; dest->Defaccess = orig->Defaccess; STRcpy(dest->BummerMsg, orig->BummerMsg); STRcpy(dest->Admin, orig->Admin); STRcpy(dest->AdminEmail, orig->AdminEmail); STRcpy(dest->Abstract, orig->Abstract); STRcpy(dest->Site, orig->Site); STRcpy(dest->Org, orig->Org); STRcpy(dest->Geog, orig->Geog); STRcpy(dest->Loc, orig->Loc); STRcpy(dest->Lang, orig->Lang); dest->TZ = orig->TZ; dest->VeronicaIndex = orig->VeronicaIndex; STRcpy(dest->Tixfile, orig->Tixfile); STAcpy(dest->other_dirs, orig->other_dirs); STAcpy(dest->other_gdcs, orig->other_gdcs); STAcpy(dest->FileSeparators, orig->FileSeparators); STAcpy(dest->BlkScriptBlocks, orig->BlkScriptBlocks); STAcpy(dest->BlkScripts, orig->BlkScripts); dest->MaxConnections = orig->MaxConnections; STRcpy(dest->TimeZoneText, orig->TimeZoneText); dest->MaxLoad = orig->MaxLoad; /* New VMS configuration options */ dest->IsGplus = orig->IsGplus; dest->IgnoreAll = orig->IgnoreAll; dest->SortDir = orig->SortDir; dest->FTPPort = orig->FTPPort; dest->EXECPort = orig->EXECPort; dest->SRCHPort = orig->SRCHPort; dest->OVERPort = orig->OVERPort; dest->OVERSize = orig->OVERSize; dest->SortShell = orig->SortShell; dest->SortGREP = orig->SortGREP; dest->SortCMD1 = orig->SortCMD1; dest->ReadTimeout = orig->ReadTimeout; dest->OPCOM = orig->OPCOM; STRcpy(dest->Hidden_Prefix, orig->Hidden_Prefix); STRcpy(dest->Link_Prefix, orig->Link_Prefix); STRcpy(dest->LookAside, orig->LookAside); STRcpy(dest->DName, orig->DName); STRcpy(dest->DHead, orig->DHead); STRcpy(dest->DFoot, orig->DFoot); STRcpy(dest->Scratch_Dir, orig->Scratch_Dir); STRcpy(dest->Support_Dir, orig->Support_Dir); STRcpy(dest->Spawn_Init, orig->Spawn_Init); STRcpy(dest->RestartLnm, orig->RestartLnm); STRcpy(dest->ConfigFile, orig->ConfigFile); STRcpy(dest->LogFileTag, orig->LogFileTag); dest->rollover = orig->rollover; return(dest); } #endif .