/*****************************************************************************/ /* ProxyMaint.c See PROXYCACHE.C for commentary. This module implements both the ROUTINE and REACTIVE purge maintenance for the proxy file cache. See PROXYCACHE.C module for information on cache management strategy. VERSION HISTORY --------------- 20-MAR-2021 MGD reduced to a shadow of its former self (caching obsolete) 28-APR-2018 MGD refactor Admin..() AST delivery 18-JAN-2010 JPP bugfix; ProxyMaintInit() use v10orPrev10() for scan spec 19-AUG-2007 MGD use PercentOf() to avoid divide-by-zero exceptions 12-APR-2005 MGD ProxyMaintSupervisor() return if caching not enabled 04-SEP-2004 MGD PROXYCACHE.C v9.0.0 cache file header date/time usage 30-APR-2004 MGD use QIO to erase cache file (save a few cycles) 13-JAN-2004 MGD DECC 6.2 objected to '$DESCRIPTOR(name,ptr->string)' 11-JUN-2003 MGD bugfix; ProxyMaintDeviceStats() volume count (set) handling 11-MAY-2003 MGD proxy unknown request fields 29-APR-2003 MGD add proxy cache device error count statistics 02-APR-2003 MGD maintain 'ProxyXForwardedFor', modify for 'ProxyForwarded' 20-FEB-2003 MGD ProxytMaintSupervisor() used instead of timers, background purge (set with '[ProxyCacheRoutineHourOfDay] 24') 03-JUN-2002 MGD bugfix; ensure sys$search() RMS channel is released 15-MAY-2002 MGD proxy gateway statistics 11-APR-2002 MGD make a reactive purge initially more agressive, bugfix; switch return not break with next reactive scan 04-APR-2002 MGD add command-line and menu STOP to cache scans, update admin and monitor status string with scan progress, bugfix; command-line cache maintenance reporting 02-FEB-2002 MGD rework POSTed query due to request body processing changes 22-SEP-2001 MGD InstanceLock/UnLock() to control access to cache 04-AUG-2001 MGD support module WATCHing 07-MAY-2001 MGD monitor global section accounting changes 05-APR-2001 MGD add boolean to prevent ProxyMaintCacheLock() lock status block overwriting if multiple scans intiated from Admin Menu 20-DEC-2000 MGD routine proxy maintainence optionally disabled/external 13-SEP-2000 MGD ProxyMaintReport() call refined to optionally provide host name cache entries 08-JUL-2000 MGD add VMS locking around cache scan (for clusters) 04-MAR-2000 MGD use FaolToBuffer(), et.al. 03-JAN-2000 MGD no changes required for ODS-5 compliance ... it's not (see note in PROXYCACHE.C) 30-DEC-1999 MGD change $GETDVI() to $GETDVIW() (potential bugfix) 04-DEC-1999 MGD rework startup cache device and report details 22-OCT-1999 MGD inaccessable cache device non-fatal during startup 20-JUN-1999 MGD allow for cache devices >9GB in space calculations, some refinement to statistics report 19-AUG-1998 MGD initial development (recommenced DEC 1998) */ /*****************************************************************************/ #ifdef WASD_VMS_V7 #undef _VMS__V6__SOURCE #define _VMS__V6__SOURCE #undef __VMS_VER #define __VMS_VER 70000000 #undef __CRTL_VER #define __CRTL_VER 70000000 #endif /* standard C header files */ #include #include #include #include /* VMS related header files */ #include #include #include #include #include #include #include #include #include #include #include /* application-related header files */ #include "wasd.h" #define WASD_MODULE "PROXYMAINT" /******************/ /* global storage */ /******************/ char ErrorProxyMaintTooManyDevices [] = "Volume set has too many members."; BOOL ProxyMaintChangeToReactive, ProxyMaintStopScan; int ProxyMaintAllocBlocks, ProxyMaintBackgroundFileCount, ProxyMaintBackgroundInterval, ProxyMaintBackgroundPurgeCount, ProxyMaintDeletedAllocBlocks, ProxyMaintDeletedCount, ProxyMaintDeletedUsedBlocks, ProxyMaintFileAllocBlocks, ProxyMaintFileCount, ProxyMaintFileUsedBlocks, ProxyMaintPurgeAtHour, ProxyMaintPurgeHoursIndex, ProxyMaintReactivePurgeCount, ProxyMaintResultFileNameLength, ProxyMaintRoutinePurgeCount, ProxyMaintRoutineHoursIndex, ProxyMaintScanFileSpecLength, ProxyMaintScanType, ProxyMaintStatScanCount, ProxyMaintTargetPercent; ProxyMaintUsedBlocks; unsigned long ProxyMaintScanStartTime64 [2]; char *ProxyMaintScanFileSpec; char ProxyMaintEraseFileName [256], ProxyMaintExpandedFileName [256], ProxyMaintStatusStringBckGrnd [128] = "none", ProxyMaintStatusStringReactive [196] = "none", ProxyMaintStatusStringRoutine [128] = "none", ProxyMaintStatusStringStatScan [128] = "none", ProxyMaintResultFileName [256]; /********************/ /* external storage */ /********************/ extern BOOL ProxyServingEnabled, ProxyUnknownRequestFields; extern int EfnWait, EfnNoWait, HttpdTickSecond, OpcomMessages, ProxyConnectPersistMax, ProxyConnectPersistSeconds, ProxyConnectTimeoutSeconds, ProxyForwardedBy, ProxyHostLookupRetryCount, ProxyNetConnectCount, ProxyVerifyRecordMax, ProxyXForwardedFor; extern int ToLowerCase[], ToUpperCase[]; extern char CliProxyMaint[], ErrorSanityCheck[], ServerHostPort[]; extern unsigned short HttpdTime7[]; extern ACCOUNTING_STRUCT *AccountingPtr; extern CONFIG_STRUCT Config; extern MSG_STRUCT Msgs; extern PROXY_ACCOUNTING_STRUCT *ProxyAccountingPtr; extern PROXYVERIFY_GBLSEC *ProxyVerifyGblSecPtr; extern WATCH_STRUCT Watch; /*****************************************************************************/ /* Return a report and control menu related proxy serving. */ ProxyMaintReport (REQUEST_STRUCT *rqptr) { int status; /*********/ /* begin */ /*********/ if (WATCHMOD (rqptr, WATCH_MOD_PROXY)) WatchThis (WATCHITM(rqptr), WATCH_MOD_PROXY, "ProxyMaintReport()"); AdminPageTitle (rqptr, "Proxy Report"); status = ProxyMaintStatsReport (rqptr, true); if (VMSnok (status)) { rqptr->rqResponse.ErrorTextPtr = "ProxyMaintStatisticsReport()"; ErrorVmsStatus (rqptr, status, FI_LI); AdminEnd (rqptr); return; } status = ProxyMaintFunctionReport (rqptr); if (VMSnok (status)) { rqptr->rqResponse.ErrorTextPtr = "ProxyMaintFunctionReport()"; ErrorVmsStatus (rqptr, status, FI_LI); AdminEnd (rqptr); return; } rqptr->rqResponse.PreExpired = PRE_EXPIRE_ADMIN; ResponseHeader200 (rqptr, "text/html", &rqptr->NetWriteBufferDsc); AdminEnd (rqptr); } /*****************************************************************************/ /* Return a report on proxy serving. */ int ProxyMaintStatsReport ( REQUEST_STRUCT *rqptr, BOOL StatisticsReport ) { static char ResponseFao [] = "

\n\ \n\ \ \ \n\
Statistics!AZ
\n\ \n\ \ \n\ \ \n\ \ \n\ \ \n\ \ \n\ \
\n\ \n\ \ \n\ \n\
Proxy Total
Requests:!&L
Bytes:!&,@SQ
\n\
 
\n\ \n\ \ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\
Method
CONNECT:!&L
DELETE:!&L
GET:!&L
HEAD:!&L
OPTIONS:!&L
POST:!&L
PUT:!&L
TRACE:!&L
WebDAV:!&L
Extension:!&L
(SSH):!&L
\n\
 
\n\ \n\ \ \n\ \n\ \n\
SOCKS5
Total:!&L
Success:!&L
Fail:!&L
\n\
\n\
\n\ \n\ \ \n\ \
\n\ \n\ \n\ \n\ \n\ \n\ \ !&@\n\ \n\ \n\ \ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \ \n\ \ \ \n\ \n\ \n\ \n\ \n\ \
Network
Requested:!&L
IPv4:!&L(!UL%)
IPv6:!&L(!UL%)
Persistent  /Current!&L
/Peak!&L
/Count!&L(!UL%)
Rx:!&,@SQ(!UL%)
Tx:!&,@SQ
1nn:!&L
2nn:!&L
3nn:!&L
4nn:!&L
5nn:!&L
none:!&L
 
\
Host Resolution
Literal:!&L
DNS:!&L(!UL%)
Cache:!&L
Error:!&L
\n\
\n\
\n"; int status, ConnectCountNetwork, PercentBytesNetwork, PercentCountIpv4, PercentCountIpv6, PercentCountNetwork, PercentCountPersist, PercentDnsName, TotalCount; int64 BytesRaw64, BytesRawRx64, BytesRawTx64, BytesTotal64; unsigned short Length; unsigned long FaoVector [64]; unsigned long *vecptr; char Buffer [2048]; $DESCRIPTOR (BufferDsc, Buffer); /*********/ /* begin */ /*********/ if (WATCHMOD (rqptr, WATCH_MOD_PROXY)) WatchThis (WATCHITM(rqptr), WATCH_MOD_PROXY, "ProxyMaintStatsReport()"); InstanceMutexLock (INSTANCE_MUTEX_HTTPD); /*********/ /* bytes */ /*********/ BytesRaw64 = ProxyAccountingPtr->BytesRawRx64 + ProxyAccountingPtr->BytesRawTx64; PercentBytesNetwork = PercentOf64 (&BytesRaw64, &BytesTotal64); /*********************/ /* counts percentage */ /*********************/ ConnectCountNetwork = ProxyAccountingPtr->ConnectIpv4Count + ProxyAccountingPtr->ConnectIpv6Count; PercentCountIpv4 = PercentOf32 (&ProxyAccountingPtr->ConnectIpv4Count, &ConnectCountNetwork); PercentCountIpv6 = PercentOf32 (&ProxyAccountingPtr->ConnectIpv6Count, &ConnectCountNetwork); PercentCountPersist = PercentOf32 (&ProxyAccountingPtr->ConnectPersistCount, &ConnectCountNetwork); /* get these values because of the locking requirements */ BytesRawRx64 = ProxyAccountingPtr->BytesRawRx64; BytesRawTx64 = ProxyAccountingPtr->BytesRawTx64; TotalCount = AccountingPtr->LookupDnsNameCount + AccountingPtr->LookupCacheNameCount; if (TotalCount) PercentDnsName = AccountingPtr->LookupDnsNameCount * 100 / TotalCount; else PercentDnsName = 0; /***********/ /* display */ /***********/ vecptr = FaoVector; if (ProxyServingEnabled) *vecptr++ = ""; else *vecptr++ = " ... DISABLED"; *vecptr++ = AccountingPtr->DoProxyCount; *vecptr++ = &BytesRaw64; *vecptr++ = ProxyAccountingPtr->MethodConnectCount; *vecptr++ = ProxyAccountingPtr->MethodDeleteCount; *vecptr++ = ProxyAccountingPtr->MethodGetCount; *vecptr++ = ProxyAccountingPtr->MethodHeadCount; *vecptr++ = ProxyAccountingPtr->MethodOptionsCount; *vecptr++ = ProxyAccountingPtr->MethodPostCount; *vecptr++ = ProxyAccountingPtr->MethodPutCount; *vecptr++ = ProxyAccountingPtr->MethodTraceCount; *vecptr++ = ProxyAccountingPtr->MethodWebDavCopyCount + ProxyAccountingPtr->MethodWebDavLockCount + ProxyAccountingPtr->MethodWebDavMkColCount + ProxyAccountingPtr->MethodWebDavMoveCount + ProxyAccountingPtr->MethodWebDavPropFindCount + ProxyAccountingPtr->MethodWebDavPropPatchCount + ProxyAccountingPtr->MethodWebDavUnLockCount; *vecptr++ = ProxyAccountingPtr->MethodExtensionCount; *vecptr++ = ProxyAccountingPtr->MethodSshCount; *vecptr++ = ProxyAccountingPtr->Socks5Count; *vecptr++ = ProxyAccountingPtr->Socks5SuccessCount; *vecptr++ = ProxyAccountingPtr->Socks5FailCount; *vecptr++ = ConnectCountNetwork; *vecptr++ = ProxyAccountingPtr->ConnectIpv4Count; *vecptr++ = PercentCountIpv4; *vecptr++ = ProxyAccountingPtr->ConnectIpv6Count; *vecptr++ = PercentCountIpv6; *vecptr++ = ProxyNetConnectCount; if (StatisticsReport) { *vecptr++ = "\ Report"; *vecptr++ = ADMIN_REPORT_PROXY_PERSISTENT; } else *vecptr++ = ""; *vecptr++ = ProxyAccountingPtr->ConnectPersistPeak; *vecptr++ = ProxyAccountingPtr->ConnectPersistCount; *vecptr++ = PercentCountPersist; *vecptr++ = &BytesRawRx64; *vecptr++ = PercentBytesNetwork; *vecptr++ = &BytesRawTx64; *vecptr++ = ProxyAccountingPtr->NetStatusCodeCount[1]; *vecptr++ = ProxyAccountingPtr->NetStatusCodeCount[2]; *vecptr++ = ProxyAccountingPtr->NetStatusCodeCount[3]; *vecptr++ = ProxyAccountingPtr->NetStatusCodeCount[4]; *vecptr++ = ProxyAccountingPtr->NetStatusCodeCount[5]; *vecptr++ = ProxyAccountingPtr->NetStatusCodeCount[0]; *vecptr++ = AccountingPtr->LookupLiteralCount; *vecptr++ = AccountingPtr->LookupDnsNameCount; *vecptr++ = PercentDnsName; *vecptr++ = AccountingPtr->LookupCacheNameCount; *vecptr++ = AccountingPtr->LookupDnsNameErrorCount; InstanceMutexUnLock (INSTANCE_MUTEX_HTTPD); *vecptr++ = AdminRefresh(); status = FaolToNet (rqptr, ResponseFao, &FaoVector); if (VMSnok (status)) ErrorNoticed (rqptr, status, NULL, FI_LI); return (status); } /*****************************************************************************/ /* Return a report on proxy special functionality. */ int ProxyMaintFunctionReport (REQUEST_STRUCT *rqptr) { static char ResponseFao [] = "

\n\ \n\ \n\
Function!AZ
\n\ \n\ \ \ \n\ \ \n\ \ \n\ \ \n\ \ \ \ \n\ \ \n\ \ \n\ \ \n\
\n\ \ \n\ \n\ \ \ \ \n\ \ \ \ \ \n\ \ \ \ \ \n\ \ \ \ \ \n\ \ \ \ \ \n\ \ \ \ \ \n\ \ \ \ \ \n\
Gateway
Out \\ In:HTTPHTTPS
HTTP!&L!&L
HTTPS!&L!&L
FTP!&L!&L
Out \\ In:IPv4IPv6
IPv4!&L!&L
IPv6!&L!&L
\n\
  \n\ \n\ \n\ \ \ \ \ \n\ \ \ \ \ \ \n\ \ \ \ \ \ \n\ \ \ \ \ \ \n\ \ \ \ \ \ \n\ \n\ \n\
Tunnel
Out \\ In:CONNECTFirewallRaw
CONNECT!&L!&L!&L
HTTP!&L!&L!&L
HTTPS!&L!&L!&L
Raw!&L!&L!&L
Current:!&L
\n\
\n\ \ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\
FTP
Total:!&LDELE:!&LDOS:!&L
Login Fail:!&LLIST:!&LUnix:!&L
RETR:!&LVMS:!&L
STOR:!&L?:!&L
\n\
  \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\
Verify
Max:!&LFull:!&L
Current:!&L200:!&L
Set:!&L403:!&L
Find:!&L404:!&L
\n\
  \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\
Rework
Count:!&L
No Type:!&L
Search:!&L
Replace:!&L
Too Big:!&L
\n\ \
\n\
\n"; int in, out, status; unsigned short Length; unsigned long FaoVector [64]; unsigned long *vecptr; char Buffer [2048]; $DESCRIPTOR (BufferDsc, Buffer); /*********/ /* begin */ /*********/ if (WATCHMOD (rqptr, WATCH_MOD_PROXY)) WatchThis (WATCHITM(rqptr), WATCH_MOD_PROXY, "ProxyMaintFunctionReport()"); InstanceMutexLock (INSTANCE_MUTEX_HTTPD); vecptr = FaoVector; if (ProxyServingEnabled) *vecptr++ = ""; else *vecptr++ = " ... DISABLED"; /* [http=0,https=1,ftp=2][http=0,https=1] */ *vecptr++ = ProxyAccountingPtr->GatewaySchemeCount[0][0]; *vecptr++ = ProxyAccountingPtr->GatewaySchemeCount[1][0]; *vecptr++ = ProxyAccountingPtr->GatewaySchemeCount[0][1]; *vecptr++ = ProxyAccountingPtr->GatewaySchemeCount[1][1]; *vecptr++ = ProxyAccountingPtr->GatewaySchemeCount[0][2]; *vecptr++ = ProxyAccountingPtr->GatewaySchemeCount[1][2]; /* [ipv4=0,ipv6=1][ipv4=0,ipv6=1] */ *vecptr++ = ProxyAccountingPtr->GatewayIpvCount[0][0]; *vecptr++ = ProxyAccountingPtr->GatewayIpvCount[1][0]; *vecptr++ = ProxyAccountingPtr->GatewayIpvCount[0][1]; *vecptr++ = ProxyAccountingPtr->GatewayIpvCount[1][1]; for (out = 0; out < TUNNEL_COUNT_MAX; out++) { if (out+1 == PROXY_TUNNEL_FIREWALL) continue; for (in = 0; in < TUNNEL_COUNT_MAX; in++) { if (in+1 == PROXY_TUNNEL_HTTP || in+1 == PROXY_TUNNEL_HTTPS) continue; *vecptr++ = ProxyAccountingPtr->TunnelCount[in][out]; } } *vecptr++ = ProxyAccountingPtr->TunnelCurrent; *vecptr++ = ProxyAccountingPtr->FtpCount; *vecptr++ = ProxyAccountingPtr->FtpDeleCount; *vecptr++ = ProxyAccountingPtr->FtpDosCount; *vecptr++ = ProxyAccountingPtr->FtpLoginFailCount; *vecptr++ = ProxyAccountingPtr->FtpListCount; *vecptr++ = ProxyAccountingPtr->FtpUnixCount; *vecptr++ = ProxyAccountingPtr->FtpRetrCount; *vecptr++ = ProxyAccountingPtr->FtpVmsCount; *vecptr++ = ProxyAccountingPtr->FtpStorCount; *vecptr++ = ProxyAccountingPtr->FtpUnknownCount; *vecptr++ = ProxyVerifyRecordMax; *vecptr++ = ProxyAccountingPtr->VerifyFullCount; *vecptr++ = ProxyAccountingPtr->VerifyCurrentCount; *vecptr++ = ProxyAccountingPtr->Verify200Count; *vecptr++ = ProxyAccountingPtr->VerifySetRecordCount; *vecptr++ = ProxyAccountingPtr->Verify403Count; *vecptr++ = ProxyAccountingPtr->VerifyFindRecordCount; *vecptr++ = ProxyAccountingPtr->Verify404Count; *vecptr++ = ProxyAccountingPtr->ReworkCount; *vecptr++ = ProxyAccountingPtr->ReworkNoType; *vecptr++ = ProxyAccountingPtr->ReworkReplaceSearch; *vecptr++ = ProxyAccountingPtr->ReworkReplaceCount; *vecptr++ = ProxyAccountingPtr->ReworkTooBig; InstanceMutexUnLock (INSTANCE_MUTEX_HTTPD); status = FaolToNet (rqptr, ResponseFao, &FaoVector); if (VMSnok (status)) ErrorNoticed (rqptr, status, NULL, FI_LI); return (status); } /*****************************************************************************/ /* Return a ontrol menu for dynamically adjusting proxy serving. */ ProxyMaintAdjust (REQUEST_STRUCT *rqptr) { static char ResponseFao [] = "!AZ\ \n\ \n\ !AZ\ !AZ\ WASD !AZ ... Proxy Report/Maintenance\n\ \n\ !AZ\n\

\n\

WASD !AZ

\n\

Proxy Report/Maintenance

\n\ !20&W\n\ \
\n\ \

\n\ \n\ \n\
Adjust Executing Server
\n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\
Serving:\n\ enabled\n\ disabled\n\
Unknown Request Fields:\n\ enabled\n\ disabled\n\
Add "Forwarded: by":\n\ \n\
Add "X-Forwarded-For:":\n\ \n\
Host Name Lookup Retry:\n\ \n\ attempts
Connect Timeout Seconds:\n\ \n\ hh:mm:ss
Connect Persist Max:\n\ \n\ connections
Connect Persist Seconds:\n\ \n\ hh:mm:ss

\n\ \n\ \n\
\n\
\n\ \

\n\ \ \n\ \n"; #define REPBOOL(b)\ if (b)\ {\ *vecptr++ = RadioButtonChecked;\ *vecptr++ = RadioButtonUnchecked;\ }\ else\ {\ *vecptr++ = RadioButtonUnchecked;\ *vecptr++ = RadioButtonChecked;\ } static char RadioButtonChecked [] = " CHECKED", RadioButtonUnchecked [] = ""; int status; unsigned long FaoVector [64]; unsigned long *vecptr; /*********/ /* begin */ /*********/ if (WATCHMOD (rqptr, WATCH_MOD_PROXY)) WatchThis (WATCHITM(rqptr), WATCH_MOD_PROXY, "ProxyMaintAdjustMenu()"); vecptr = FaoVector; *vecptr++ = WASD_DOCTYPE; *vecptr++ = HtmlMetaInfo (rqptr, NULL); *vecptr++ = AdminWasdCss (); *vecptr++ = ServerHostPort; *vecptr++ = ADMIN_BODY_TAG; *vecptr++ = ServerHostPort; *vecptr++ = &rqptr->rqTime.BeginTime64; *vecptr++ = ADMIN_CONTROL_PROXY_ADJUST_NOW; REPBOOL (ProxyServingEnabled) REPBOOL (ProxyUnknownRequestFields) if (ProxyForwardedBy == PROXY_FORWARDED_BY) *vecptr++ = "BY"; else if (ProxyForwardedBy == PROXY_FORWARDED_FOR) *vecptr++ = "FOR"; else *vecptr++ = "disabled"; if (ProxyXForwardedFor == PROXY_XFORWARDEDFOR_ENABLED) *vecptr++ = "ENABLED"; else if (ProxyXForwardedFor == PROXY_XFORWARDEDFOR_ADDRESS) *vecptr++ = "ADDRESS"; else if (ProxyXForwardedFor == PROXY_XFORWARDEDFOR_UNKNOWN) *vecptr++ = "UNKNOWN"; else *vecptr++ = "disabled"; *vecptr++ = ProxyHostLookupRetryCount; *vecptr++ = MetaConShowSeconds (rqptr, ProxyConnectTimeoutSeconds); *vecptr++ = ProxyConnectPersistMax; *vecptr++ = MetaConShowSeconds (rqptr, ProxyConnectPersistSeconds); status = FaolToNet (rqptr, ResponseFao, &FaoVector); if (VMSnok (status)) ErrorNoticed (rqptr, status, NULL, FI_LI); rqptr->rqResponse.PreExpired = PRE_EXPIRE_ADMIN; ResponseHeader200 (rqptr, "text/html", &rqptr->NetWriteBufferDsc); AdminEnd (rqptr); } /*****************************************************************************/ /* */ ProxyMaintControl (REQUEST_STRUCT *rqptr) { BOOL MakeChanges; int status; unsigned short Length; char *cptr, *qptr, *sptr, *zptr; char FieldName [128], FieldValue [256]; /*********/ /* begin */ /*********/ if (WATCHMOD (rqptr, WATCH_MOD_PROXY)) WatchThis (WATCHITM(rqptr), WATCH_MOD_PROXY, "ProxyMaintControl()"); MakeChanges = false; /**********************/ /* parse content body */ /**********************/ if (rqptr->rqHeader.Method == HTTP_METHOD_POST) { if (!rqptr->rqBody.DataPtr) { /* read all the request body (special case) then AST back */ BodyReadBegin (rqptr, &ProxyMaintControl, &BodyProcessReadAll); return; } qptr = rqptr->rqBody.DataPtr; } else qptr = rqptr->rqHeader.QueryStringPtr; while (*qptr) { status = StringParseQuery (&qptr, FieldName, sizeof(FieldName), FieldValue, sizeof(FieldValue)); if (VMSnok (status)) { /* error occured */ if (status == SS$_IVCHAR) rqptr->rqResponse.HttpStatus = 400; rqptr->rqResponse.ErrorTextPtr = "parsing query string"; ErrorVmsStatus (rqptr, status, FI_LI); AdminEnd (rqptr); return; } /************************/ /* action button fields */ /************************/ if (strsame (FieldName, "hostname", -1)) { TcpIpHostCacheSupervisor ((unsigned int)-1); ReportSuccess (rqptr, "Server !AZ host name cache purged.", ServerHostPort); } else if (strsame (FieldName, "makechanges", -1)) MakeChanges = true; else if (strsame (FieldName, "ProxyForwarded", -1)) { if (TOUP(FieldValue[0]) == 'B') ProxyForwardedBy = PROXY_FORWARDED_BY; else if (TOUP(FieldValue[0]) == 'F') ProxyForwardedBy = PROXY_FORWARDED_FOR; else ProxyForwardedBy = PROXY_FORWARDED_DISABLED; } else if (strsame (FieldName, "ProxyXForwardedFor", -1)) { if (TOUP(FieldValue[0]) == 'A') ProxyXForwardedFor = PROXY_XFORWARDEDFOR_ADDRESS; else if (TOUP(FieldValue[0]) == 'E') ProxyXForwardedFor = PROXY_XFORWARDEDFOR_ENABLED; else if (TOUP(FieldValue[0]) == 'U') ProxyXForwardedFor = PROXY_XFORWARDEDFOR_UNKNOWN; else ProxyXForwardedFor = PROXY_XFORWARDEDFOR_DISABLED; } else if (strsame (FieldName, "ProxyServingEnabled", -1)) { InstanceMutexLock (INSTANCE_MUTEX_HTTPD); if (TOUP(FieldValue[0]) == 'E') ProxyServingEnabled = ProxyAccountingPtr->ServingEnabled = true; else if (TOUP(FieldValue[0]) == 'D') ProxyServingEnabled = ProxyAccountingPtr->ServingEnabled = false; InstanceMutexUnLock (INSTANCE_MUTEX_HTTPD); } else if (strsame (FieldName, "ProxyHostLookupRetryCount", -1)) { ProxyHostLookupRetryCount = atoi(FieldValue); if (ProxyHostLookupRetryCount < 0 || ProxyHostLookupRetryCount > 100) ProxyHostLookupRetryCount = 0; } else if (strsame (FieldName, "ProxyConnectPersistMax", -1)) ProxyConnectPersistMax = atoi(FieldValue); else if (strsame (FieldName, "ProxyConnectPersistSeconds", -1)) ProxyConnectPersistSeconds = MetaConSetSeconds (NULL, FieldValue, 1); else if (strsame (FieldName, "ProxyConnectTimeoutSeconds", -1)) ProxyConnectTimeoutSeconds = MetaConSetSeconds (NULL, FieldValue, 1); else if (strsame (FieldName, "ProxyUnknownRequestFields", -1)) { if (TOUP(FieldValue[0]) == 'E') ProxyUnknownRequestFields = true; else if (TOUP(FieldValue[0]) == 'D') ProxyUnknownRequestFields = false; } else { /***********/ /* unknown */ /***********/ ErrorGeneral (rqptr, "Unknown query field.", FI_LI); return; } } if (MakeChanges) { ProxyNetInit (); ReportSuccess (rqptr, "Server !AZ new proxy values loaded.", ServerHostPort); } AdminEnd (rqptr); } /****************************************************************************/