/********************************************************************
* 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 <ctype.h>
#include "fileio.h"
#include <opcdef.h>
#endif
#include "Malloc.h"
#include "String.h"
#include <stdio.h>
#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<vms_OPC$M_num; ox++) {
if (strcasecmp(rest, vms_OPC$M_TXT[ox])==0)
GDCsetOPCOM(gdc, opc |= vms_OPC$M_NM[ox]);
}
if (cp) {
rest = cp+1;
cp = strchr(rest,'+');
}
else
rest = NULL;
}
if (opc==0)
GDCsetOPCOM(gdc, opc = (OPC$M_NM_CENTRL | OPC$M_NM_NTWORK));
}
else if (strcasecmp(token, "Hidden")==0)
GDCsetHiddenPrefix(gdc, rest);
else if (strcasecmp(token, "Link")==0)
GDCsetLinkPrefix(gdc, rest);
else if (strcasecmp(token, "LookAside")==0)
GDCsetLookAside(gdc, rest);
else if (strcasecmp(token, "DName")==0)
GDCsetDName(gdc, rest);
else if (strcasecmp(token, "DHead")==0)
GDCsetDHead(gdc, rest);
else if (strcasecmp(token, "DFoot")==0)
GDCsetDFoot(gdc, rest);
else if (strcasecmp(token, "ScratchDir")==0)
GDCsetScratchDir(gdc, rest);
else if (strcasecmp(token, "SupportDir")==0)
GDCsetSupportDir(gdc, rest);
else if (strcasecmp(token, "SpawnInit")==0)
GDCsetSpawnInit(gdc, rest);
else if (strcasecmp(token, "Restart")==0)
GDCsetRestart(gdc, rest);
else if (strcasecmp(token, "LogTag")==0)
GDCsetLogTag(gdc, rest);
else if (strcasecmp(token, "Rollover")==0) {
if (strcasecmp(rest, "Daily")==0)
GDCsetRollover(gdc,ROLLOVER_DAILY);
if (strcasecmp(rest, "Monthly")==0)
GDCsetRollover(gdc,ROLLOVER_MONTHLY);
if (strcasecmp(rest, "Hourly")==0)
GDCsetRollover(gdc,ROLLOVER_HOURLY);
if (strcasecmp(rest, "Annually")==0)
GDCsetRollover(gdc,ROLLOVER_ANNUALLY);
if (strcasecmp(rest, "Weekly")==0)
GDCsetRollover(gdc,ROLLOVER_WEEKLY);
else
GDCsetRollover(gdc, ROLLOVER_NEVER);
}
else if (strcasecmp(token, "CACHE")==0) {
if (strncasecmp(rest, "TRUE", 4)==0)
GDCsetCaching(gdc,TRUE);
else
GDCsetCaching(gdc, FALSE);
}
else if (strcasecmp(token, "DO_CHROOT")==0) {
if (strncasecmp(rest, "TRUE", 4)==0)
GDCsetchroot(gdc,TRUE);
else
GDCsetchroot(gdc, FALSE);
}
#endif
else
success = FALSE;
return(success);
}
void
GDCfromFile(gdc, filename)
GDCobj *gdc;
char *filename;
{
FILE *gdcfile;
char inputline[512];
char *cp, *linestart, *token, *restofline;
boolean success;
#ifdef VMS_SERVER
int bad_cfg=0;
#endif
if ((gdcfile = fopen(filename, "r")) == (FILE *) NULL) {
#ifndef VMS_SERVER
printf("Cannot open file '%s'\n", filename);
exit(-1);
#else
VMS$fprintf(stderr,"Cannot open file '%s'\n", filename);
bad_cfg++;
#endif
}
GDCfilePush(gdcfile);
#ifdef VMS_SERVER
if (!GDCfilenum) /* Only record the topmost config file */
GDCsetConfig(gdc, fgetname(gdcfile, inputline));
#endif
while (GDCfileGetline(inputline, sizeof(inputline))) {
int inputlen;
ZapCRLF(inputline);
inputlen = strlen(inputline);
while ((inputlen > 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; i<STAgetTop(gdc->other_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; i<STAgetTop(gdc->other_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
.
Response:
text/plain