#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
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
#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
}
}
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;
} 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;
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
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);
}
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);
}
}