/*****************************************************************************/ /* Admin.c Server administration support functions for HTTPd. Many of the reports and forms used for revision are produced by functions within the core-function module. The control function allow server restart, exit, abort, mapping file reload, authorization path reload and authentication cache purging. VERSION HISTORY --------------- 16-DEC-2017 MGD note decade-old border-collapse bug in Chrome (Firefox, MS Edge, Safari render correctly) 10-OCT-2017 MGD SesolaReport..() relax from SSL-only to any service 14-NOV-2015 MGD excise much of the twenty years of reporting HTML cruft AdminRefresh() allow selection of a page refresh interval lift the GZIP restriction for all but main menu and WATCHing 28-SEP-2014 MGD AdminLookYouUp() and associated Server Admin item 12-MAR-2014 MGD "no module involved" datum 30-JAN-2014 MGD tweaks to menu layout to try and get MSIE 9 to behave 27-JUN-2010 MGD WebSockReport() 23-AUG-2009 MGD WasdCss[] and some refinements 26-JUL-2007 MGD bugfix; AdminMenu() JavaScript doIt() call 02-JUN-2007 MGD WebDAV and Cluster reports, remove file cache, authorization and proxy items from Server Statistics report (keeping it more-to-the-point) 27-OCT-2006 MGD AdminReportServerStat() quota percentages in use 23-SEP-2006 MGD AdminReportServerStat() last exit time 15-JUL-2006 MGD AdminMenu() instance [Active][Passive] functionality (service item) network connection [Purge][All] 04-JUL-2006 MGD AdminMenu() status panel (time, connect, request) mods use PercentOf() for more accurate percentages 26-MAY-2005 MGD [/DO=] button/field and supporting functionality 03-MAR-2005 MGD AdminMetaConSource() changes to support search lists 30-NOV-2004 MGD zero proxy accounting 12-OCT-2004 MGD add status info (currently only access log write fail) to Server Admin page (beneath dates and accounting) 28-JUL-2004 MGD HTTP/1.1 items, server admin reports now have the response header generated after the report body so that the buffer length can be used as a content length (allowing connections to persist) 20-MAY-2004 MGD remove 'supervisor' from report menu 28-JAN-2004 MGD make process input/output reports plain-text, service access log report (via LoggingReport()), make some accomodations in reports for our old friend Netscape 3.03/Gold (on VMS) which doesn't render some table formatting correctly (or the way we intended anyway) 26-AUG-2003 MGD rework access to server configuration files, service directory located authorization databases 15-AUG-2003 MGD where CDATA constraints make using entity impossible use a field name of hidden$lf and ^ substituted for it 22-JUL-2003 MGD allow for CMKRNL when warning on privileges 08-JUN-2003 MGD cache statistics include permanent/volatile changes 31-JAN-2002 MGD no menu difference between category and module WATCHing 12-OCT-2002 MGD refine metacon reporting 16-JUN-2002 MGD greater hour granularity to activity report selection 30-MAY-2002 MGD restart when quiet 17-MAY-2002 MGD activity reports changed inline with GRAPH.C changes 04-APR-2002 MGD proxy cache STOP scan 28-DEC-2001 MGD add 'instance' selection 29-OCT-2001 MGD PERSONA_MACRO reporting 29-SEP-2001 MGD instance support 04-AUG-2001 MGD support module WATCHing 13-MAR-2001 MGD add throttle and supervisor reports 22-DEC-2000 MGD HTL list admin (partially implemented by HTADMIN.C), SSL client certificate CA verification 02-OCT-2000 MGD DETACH now an allowed privilege 13-SEP-2000 MGD ProxyMainReport() call refined 26-AUG-2000 MGD consolidated WATCH processing and peek 18-JUN-2000 MGD "All Services" directives, site log item, service configuration, add a little JavaScript to enhance the admin menu 28-MAY-2000 MGD use $getjpi ...lm values from server startup 04-MAR-2000 MGD use FaolToNet(), et.al. 13-JAN-2000 MGD improve log messages, add OPCOM messaging 30-OCT-1999 MGD unbundled WATCH functionality to its own module 10-OCT-1999 MGD show process report, move service statistics report to NET.C module, CacheReport() now only optionally reports cached files 04-SEP-1999 MGD remove WatchRequestHeader() 11-JUN-1999 MGD bugfix; WatchFilter() 12-APR-1999 MGD WatchDataDump() for request and response bodies 10-JAN-1999 MGD add proxy items to WATCH menu, add proxy report 07-NOV-1998 MGD WATCH facility 16-MAR-1998 MGD server abort changed to "exit NOW", added "restart NOW" 05-OCT-1997 MGD file cache 28-SEP-1997 MGD request durations 06-SEP-1997 MGD service list 09-AUG-1997 MGD message database 07-JUL-1997 MGD activity report and logging control functions, reworked the control function (it was getting untidy) 08-JUN-1997 MGD "Other" menu item, with "Clients" and "Scripting" reports, AdminRequestReport() and DclScriptingReport() functions 01-FEB-1997 MGD new for HTTPd version 4 */ /*****************************************************************************/ #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 /* application related header files */ #include "wasd.h" #define WASD_MODULE "ADMIN" /********************/ /* external storage */ /********************/ extern BOOL CacheEnabled, DclScriptDetachProcess, DclPersonaServicesAvailable, GzipAvailable, Http2Enabled, HttpdAlignFaultReport, InstanceNodeSupervisor, LoggingEnabled, LoggingFileError, NetInstancePassive, OperateWithSysPrv, PersonaMacro, ProtocolHttpsConfigured, SesolaVerifyCAConfigured, WebDavEnabled; extern int ActivityTotalMinutes, CacheEntryCount, CacheEntriesMax, CacheHits0, CacheHits10, CacheHits100, CacheHits1000, CacheHits1000plus, CacheHitCount, CacheLoadCount, CacheMemoryInUse, CachePermEntryCount, CachePermMemoryInUse, CacheTotalKBytesMax, EfnWait, ExitStatus, GblPageCount, GblPagePermCount, GblSectionCount, GblSectionPermCount, GzipFindImageStatus, HttpdAlignFaultCount, InstanceEnvNumber, InstanceNodeCurrent, InstanceNumber, OpcomMessages, ProxyServiceCount, RequestHistoryMax, ServiceCount; extern int ToLowerCase[], ToUpperCase[]; extern unsigned long HttpdStartTime64[]; extern char BuildInfo[], CommandLine[], ErrorSanityCheck[], HttpdScriptAsUserName[], ServerHostPort[], SoftwareID[], TcpIpAgentInfo[], TimeGmtString[]; extern char *AuthConfigHtaDirectory, *GzipZlibNamePtr, *GzipZlibVersionPtr; #define acptr AccountingPtr extern ACCOUNTING_STRUCT *AccountingPtr; extern ACTIVITY_GBLSEC *ActivityGblSecPtr; extern CONFIG_STRUCT Config; extern HTTPD_GBLSEC *HttpdGblSecPtr; extern HTTPD_PROCESS HttpdProcess; extern IPADDRESS TcpIpEmptyAddress; extern MSG_STRUCT Msgs; extern MAPPING_META *MappingMetaPtr; extern PROXY_ACCOUNTING_STRUCT *ProxyAccountingPtr; extern SERVICE_STRUCT *ServiceListHead; extern SERVICE_STRUCT *SesolaListHead; extern SYS_INFO SysInfo; extern TCPIP_HOST_CACHE *TcpIpHostCachePtr; extern WATCH_STRUCT Watch; /*****************************************************************************/ /* Begin HTTPd server administration. */ AdminBegin ( REQUEST_STRUCT *rqptr, REQUEST_AST NextTaskFunction ) { BOOL ClusterDo, SlashDo, UseServerDatabase; int status; unsigned short Length; char *cptr; char DoThis [128], FieldName [128], FieldValue [256], FilePath [ODS_MAX_FILE_NAME_LENGTH+1], Http2Connection [33], Md5HashHexString [33], NumberString [16], Path [ODS_MAX_FILE_NAME_LENGTH+1], ProcessIdString [16], ProcessIdUserName [13], RefreshInterval [16], VirtualHostPort [128]; /*********/ /* begin */ /*********/ if (WATCHMOD (rqptr, WATCH_MOD__OTHER)) WatchThis (WATCHITM(rqptr), WATCH_MOD__OTHER, "AdminBegin() !&A", NextTaskFunction); if (WATCHING (rqptr, WATCH_RESPONSE)) WatchThis (WATCHITM(rqptr), WATCH_RESPONSE, "ADMIN !AZ", rqptr->rqHeader.PathInfoPtr); if (!rqptr->AccountingDone++) InstanceGblSecIncrLong (&acptr->DoServerAdminCount); if (!rqptr->RemoteUser[0]) { rqptr->rqResponse.HttpStatus = 403; ErrorGeneral (rqptr, MsgFor(rqptr,MSG_AUTH_REQUIRED), FI_LI); SysDclAst (NextTaskFunction, rqptr); return; } /* for admin activities supply a full error report regardless */ rqptr->rqPathSet.ReportType = ERROR_REPORT_DETAILED; /* disable GZIP compression for the main menu and when WATCHing */ if (strsame (rqptr->rqHeader.RequestUriPtr, HTTPD_ADMIN, -1)) rqptr->rqResponse.NoGzip = true; else if (strsame (rqptr->rqHeader.RequestUriPtr, ADMIN_REPORT_WATCH, -1)) rqptr->rqResponse.NoGzip = true; /*********************/ /* per-service admin */ /*********************/ #ifdef NOT_FULLY_IMPLEMENTED_YET if (strsame (rqptr->rqHeader.PathInfoPtr, HTTPD_VS_ADMIN, -1)) { AdminVirtualServerMenu (rqptr, NextTaskFunction); return; } if (strsame (rqptr->rqHeader.PathInfoPtr, ADMIN_VS_REVISE_HTA, sizeof(ADMIN_VS_REVISE_HTA)-1)) { if (VMSnok (status = AdminParsePath (rqptr, NULL))) SysDclAst (NextTaskFunction, rqptr); else HTAdminBegin (rqptr, NextTaskFunction); return; } if (strsame (rqptr->rqHeader.PathInfoPtr, ADMIN_VS_REVISE_HTL, sizeof(ADMIN_VS_REVISE_HTL)-1)) { if (VMSnok (status = AdminParsePath (rqptr, NULL))) SysDclAst (NextTaskFunction, rqptr); else if (rqptr->rqHeader.Method == HTTP_METHOD_POST) PutBegin (rqptr, NextTaskFunction); else if ((rqptr->rqHeader.PathInfoPtr+sizeof(ADMIN_VS_REVISE_HTL)-1)[0]) if (rqptr->rqHeader.QueryStringLength) HTAdminBegin (rqptr, NextTaskFunction); else FileBegin (rqptr, NextTaskFunction, NULL, NULL, rqptr->ParseOds.ExpFileName, "text/plain"); else HTAdminBegin (rqptr, NextTaskFunction); return; } if (strsame (rqptr->rqHeader.PathInfoPtr, ADMIN_VS_CONTROL, sizeof(ADMIN_VS_CONTROL)-1)) { AdminControl (rqptr, NextTaskFunction, NULL, true); return; } #endif /** NOT_FULLY_IMPLEMENTED_YET **/ /********************************************/ /* modules that parse their own query field */ /********************************************/ if (strsame (rqptr->rqHeader.PathInfoPtr, ADMIN_REVISE_HTA, sizeof(ADMIN_REVISE_HTA)-1)) { if (VMSnok (status = AdminParsePath (rqptr, NULL))) SysDclAst (NextTaskFunction, rqptr); else HTAdminBegin (rqptr, NextTaskFunction); return; } if (strsame (rqptr->rqHeader.PathInfoPtr, ADMIN_REVISE_HTL, sizeof(ADMIN_REVISE_HTL)-1)) { if (VMSnok (status = AdminParsePath (rqptr, NULL))) SysDclAst (NextTaskFunction, rqptr); else if (rqptr->rqHeader.Method == HTTP_METHOD_POST) PutBegin (rqptr, NextTaskFunction); else if ((rqptr->rqHeader.PathInfoPtr+sizeof(ADMIN_REVISE_HTL)-1)[0]) if (rqptr->rqHeader.QueryStringLength) HTAdminBegin (rqptr, NextTaskFunction); else FileBegin (rqptr, NextTaskFunction, NULL, NULL, rqptr->ParseOds.ExpFileName, "text/plain"); else HTAdminBegin (rqptr, NextTaskFunction); return; } if (strsame (rqptr->rqHeader.PathInfoPtr, ADMIN_REVISE_SITELOG, sizeof(ADMIN_REVISE_SITELOG)-1)) { if (VMSnok (status = AdminParsePath (rqptr, NULL))) SysDclAst (NextTaskFunction, rqptr); else if (rqptr->rqHeader.Method == HTTP_METHOD_POST) PutBegin (rqptr, NextTaskFunction); else if (rqptr->rqHeader.QueryStringLength) UpdBegin (rqptr, NextTaskFunction); else FileBegin (rqptr, NextTaskFunction, NULL, NULL, rqptr->ParseOds.ExpFileName, "text/plain"); return; } if (strsame (rqptr->rqHeader.PathInfoPtr, ADMIN_REPORT_ACTIVITY, -1)) { GraphActivityReport (rqptr, NextTaskFunction); return; } if (strsame (rqptr->rqHeader.PathInfoPtr, ADMIN_REPORT_MATCH, -1)) { StringMatchReport (rqptr, NextTaskFunction); return; } if (strsame (rqptr->rqHeader.PathInfoPtr, ADMIN_REPORT_PROCESS, -1)) { WatchProcessReport (rqptr, NextTaskFunction); return; } if (strsame (rqptr->rqHeader.PathInfoPtr, ADMIN_REPORT_WATCH, -1)) { if (rqptr->rqHeader.QueryStringLength) WatchBegin (rqptr, NextTaskFunction); else WatchReport (rqptr, NextTaskFunction); return; } if (strsame (rqptr->rqHeader.PathInfoPtr, ADMIN_REPORT_WATCH_STRUCT, -1)) { WatchReportStruct (rqptr, NextTaskFunction); return; } if (strsame (rqptr->rqHeader.PathInfoPtr, ADMIN_REPORT_WEBDAV, -1)) { DavWebReport (rqptr); return; } if (strsame (rqptr->rqHeader.PathInfoPtr, ADMIN_REPORT_WEBDAV_XML, -1)) { DavXmlReport (rqptr); return; } if (strsame (rqptr->rqHeader.PathInfoPtr, ADMIN_REPORT_WEBSOCKET, -1)) { WebSockReport (rqptr, NextTaskFunction); return; } if (strsame (rqptr->rqHeader.PathInfoPtr, ADMIN_CONTROL_DELETE_PROCESS, -1)) { /********************/ /* delete a process */ /********************/ WatchDeleteProcess (rqptr, NextTaskFunction); return; } /**********************/ /* parse query string */ /**********************/ ClusterDo = SlashDo = false; UseServerDatabase = true; DoThis[0] = FilePath[0] = Http2Connection[0] = Md5HashHexString[0] = \ NumberString[0] = Path[0] = ProcessIdString[0] = ProcessIdUserName[0] = RefreshInterval[0] = VirtualHostPort[0] = '\0'; if (rqptr->rqHeader.QueryStringLength) cptr = rqptr->rqHeader.QueryStringPtr; else cptr = ""; while (*cptr) { status = StringParseQuery (&cptr, 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); SysDclAst (NextTaskFunction, rqptr); return; } if (strsame (FieldName, "at", -1) || strsame (FieldName, "this", -1)) strzcpy (NumberString, FieldValue, sizeof(NumberString)); else if (strsame (FieldName, "cxr", -1)) { /* 'cxr' can be generated from an UPD edit window */ strzcpy (DoThis, "edit", sizeof(DoThis)); } else if (strsame (FieldName, "do", -1)) strzcpy (DoThis, FieldValue, sizeof(DoThis)); else if (strsame (FieldName, "edit", -1)) strzcpy (FilePath, FieldValue, sizeof(FilePath)); else if (strsame (FieldName, "entry", -1)) strzcpy (Md5HashHexString, FieldValue, sizeof(Md5HashHexString)); else if (strsame (FieldName, "file", -1)) { if (TOUP(FieldValue[0]) == 'Y') UseServerDatabase = false; else if (TOUP(FieldValue[0]) == 'N') UseServerDatabase = true; } else if (strsame (FieldName, "http2", -1)) strzcpy (Http2Connection, FieldValue, sizeof(Http2Connection)); else if (strsame (FieldName, "refresh", -1)) strzcpy (RefreshInterval, FieldValue, sizeof(RefreshInterval)); else if (strsame (FieldName, "puser", -1)) strzcpy (ProcessIdUserName, FieldValue, sizeof(ProcessIdUserName)); else if (strsame (FieldName, "path", -1)) strzcpy (Path, FieldValue, sizeof(Path)); else if (strsame (FieldName, "pid", -1)) strzcpy (ProcessIdString, FieldValue, sizeof(ProcessIdString)); else if (strsame (FieldName, "puser", -1)) strzcpy (ProcessIdUserName, FieldValue, sizeof(ProcessIdUserName)); else if (strsame (FieldName, "scope", -1)) { if (strsame (FieldValue, "cluster", -1)) ClusterDo = true; } else if (strsame (FieldName, "service", -1)) strzcpy (VirtualHostPort, FieldValue, sizeof(VirtualHostPort)); else if (strsame (FieldName, "server", -1)) { if (TOUP(FieldValue[0]) == 'Y') UseServerDatabase = true; else if (TOUP(FieldValue[0]) == 'N') UseServerDatabase = false; } else if (strsame (FieldName, "slashdo", -1)) { SlashDo = true; strzcpy (DoThis, FieldValue, sizeof(DoThis)); } else if (strsame (FieldName, "virtual", -1)) strzcpy (VirtualHostPort, FieldValue, sizeof(VirtualHostPort)); else { rqptr->rqResponse.HttpStatus = 400; ErrorGeneral (rqptr, "Unknown query field.", FI_LI); SysDclAst (NextTaskFunction, rqptr); return; } } /***************/ /* do function */ /***************/ if (SlashDo) { if (strsame (DoThis, "HELP", -1)) ControlDoHelp (rqptr, NextTaskFunction); else if (strsame (DoThis, "STATUS", -1)) InstanceStatusCliReport (rqptr, NextTaskFunction); else AdminControl (rqptr, NextTaskFunction, DoThis, ClusterDo); return; } else if (strsame (rqptr->rqHeader.PathInfoPtr, HTTPD_ADMIN, -1) || strsame (rqptr->rqHeader.PathInfoPtr, ADMIN_REPORT, -1) || strsame (rqptr->rqHeader.PathInfoPtr, ADMIN_REVISE, -1) || strsame (rqptr->rqHeader.PathInfoPtr, ADMIN_CONTROL, -1)) { /********/ /* menu */ /********/ AdminMenu (rqptr, NextTaskFunction); return; } else if (strsame (rqptr->rqHeader.PathInfoPtr, ADMIN_REPORT_ALIGN, -1)) { HttpdAlignReport (rqptr, NextTaskFunction); return; } else if (strsame (rqptr->rqHeader.PathInfoPtr, ADMIN_REPORT_AUTH_USER, -1)) { AuthCacheReport (rqptr, NextTaskFunction); return; } else if (strsame (rqptr->rqHeader.PathInfoPtr, ADMIN_REPORT_CACHE, -1)) { CacheReport (rqptr, NextTaskFunction, false); return; } else if (strsame (rqptr->rqHeader.PathInfoPtr, ADMIN_REPORT_CACHE_ENTRIES, -1)) { if (Md5HashHexString[0]) CacheReportEntry (rqptr, NextTaskFunction, Md5HashHexString); else CacheReport (rqptr, NextTaskFunction, true); return; } else if (strsame (rqptr->rqHeader.PathInfoPtr, ADMIN_REPORT_CLUSTER, -1)) { WatchShowCluster (rqptr, NextTaskFunction); return; } else if (strsame (rqptr->rqHeader.PathInfoPtr, ADMIN_REPORT_CONFIG, -1) || strsame (rqptr->rqHeader.PathInfoPtr, ADMIN_REVISE_CONFIG, -1)) { if (VMSnok (status = AdminParsePath (rqptr, NULL))) SysDclAst (NextTaskFunction, rqptr); else if (rqptr->rqHeader.Method == HTTP_METHOD_POST) PutBegin (rqptr, NextTaskFunction); else if (rqptr->rqHeader.QueryStringLength) { if (strsame (DoThis, "edit", -1)) UpdBegin (rqptr, NextTaskFunction); else if (strsame (rqptr->rqHeader.PathInfoPtr, ADMIN_REPORT_CONFIG, -1)) ConfigReport (rqptr, NextTaskFunction, UseServerDatabase); else ConfigRevise (rqptr, NextTaskFunction, UseServerDatabase); } else FileBegin (rqptr, NextTaskFunction, NULL, NULL, rqptr->ParseOds.ExpFileName, "text/plain"); return; } else if (strsame (rqptr->rqHeader.PathInfoPtr, ADMIN_REPORT_DCL, -1)) { DclScriptingReport (rqptr, NextTaskFunction); return; } else if (strsame (rqptr->rqHeader.PathInfoPtr, ADMIN_REPORT_HOSTCACHE, -1)) { TcpIpHostCacheReport (rqptr, NextTaskFunction); return; } else if (strsame (rqptr->rqHeader.PathInfoPtr, ADMIN_REPORT_PROCESS, -1)) { WatchShowProcess (rqptr, NextTaskFunction, ProcessIdString, ProcessIdUserName); return; } else if (strsame (rqptr->rqHeader.PathInfoPtr, ADMIN_REPORT_DECNET, -1)) { DECnetScriptingReport (rqptr, NextTaskFunction); return; } else if (strsame (rqptr->rqHeader.PathInfoPtr, ADMIN_REPORT_HTTP, -1)) { Http2Report (rqptr, NextTaskFunction); return; } else if (strsame (rqptr->rqHeader.PathInfoPtr, ADMIN_REPORT_HPACK, -1)) { HpackReport (rqptr, Http2Connection, NextTaskFunction); return; } else if (strsame (rqptr->rqHeader.PathInfoPtr, ADMIN_REPORT_LOCK, -1)) { InstanceLockReport (rqptr, NextTaskFunction); return; } else if (strsame (rqptr->rqHeader.PathInfoPtr, ADMIN_REPORT_PROCESS_INPUT, -1)) { AdminServerProcessInput (rqptr, NextTaskFunction); return; } else if (strsame (rqptr->rqHeader.PathInfoPtr, ADMIN_REPORT_PROCESS_OUTPUT, -1)) { AdminServerProcessOutput (rqptr, NextTaskFunction); return; } else if (strsame (rqptr->rqHeader.PathInfoPtr, ADMIN_REPORT_MEMORY, -1)) { VmReport (rqptr, NextTaskFunction); return; } else if (strsame (rqptr->rqHeader.PathInfoPtr, ADMIN_REPORT_MESSAGES, -1) || strsame (rqptr->rqHeader.PathInfoPtr, ADMIN_REVISE_MESSAGES, -1)) { if (VMSnok (status = AdminParsePath (rqptr, NULL))) SysDclAst (NextTaskFunction, rqptr); else if (rqptr->rqHeader.Method == HTTP_METHOD_POST) PutBegin (rqptr, NextTaskFunction); else if (rqptr->rqHeader.QueryStringLength) { if (strsame (DoThis, "edit", -1)) UpdBegin (rqptr, NextTaskFunction); else if (strsame (rqptr->rqHeader.PathInfoPtr, ADMIN_REPORT_MESSAGES, -1)) MsgConfigReport (rqptr, NextTaskFunction, UseServerDatabase); else MsgConfigRevise (rqptr, NextTaskFunction, UseServerDatabase); } else FileBegin (rqptr, NextTaskFunction, NULL, NULL, rqptr->ParseOds.ExpFileName, "text/plain"); return; } else if (strsame (rqptr->rqHeader.PathInfoPtr, ADMIN_REPORT_AUTH_PATHS, -1) || strsame (rqptr->rqHeader.PathInfoPtr, ADMIN_REVISE_AUTH_PATHS, -1)) { if (VMSnok (status = AdminParsePath (rqptr, NULL))) SysDclAst (NextTaskFunction, rqptr); else if (rqptr->rqHeader.Method == HTTP_METHOD_POST) PutBegin (rqptr, NextTaskFunction); else if (rqptr->rqHeader.QueryStringLength) if (strsame (DoThis, "edit", -1)) UpdBegin (rqptr, NextTaskFunction); else AuthConfigReport (rqptr, NextTaskFunction, UseServerDatabase, VirtualHostPort); else FileBegin (rqptr, NextTaskFunction, NULL, NULL, rqptr->ParseOds.ExpFileName, "text/plain"); return; } else if (strsame (rqptr->rqHeader.PathInfoPtr, ADMIN_REPORT_PROXY, -1)) { ProxyMaintReport (rqptr, NextTaskFunction); return; } else if (strsame (rqptr->rqHeader.PathInfoPtr, ADMIN_REPORT_PROXY_PERSISTENT, -1)) { ProxyNetPersistentReport (rqptr, NextTaskFunction); return; } else if (strsame (rqptr->rqHeader.PathInfoPtr, ADMIN_REPORT_REQUEST, sizeof(ADMIN_REPORT_REQUEST)-1)) { RequestReport (rqptr, NextTaskFunction); return; } else if (strsame (rqptr->rqHeader.PathInfoPtr, ADMIN_REPORT_SERVICES, -1) || strsame (rqptr->rqHeader.PathInfoPtr, ADMIN_REVISE_SERVICES, -1)) { if (VMSnok (status = AdminParsePath (rqptr, NULL))) SysDclAst (NextTaskFunction, rqptr); else if (rqptr->rqHeader.Method == HTTP_METHOD_POST) PutBegin (rqptr, NextTaskFunction); else if (rqptr->rqHeader.QueryStringLength) { if (strsame (DoThis, "edit", -1)) UpdBegin (rqptr, NextTaskFunction); else if (strsame (rqptr->rqHeader.PathInfoPtr, ADMIN_REPORT_SERVICES, -1)) ServiceReport (rqptr, NextTaskFunction, UseServerDatabase); else ServiceConfigRevise (rqptr, NextTaskFunction, UseServerDatabase); } else FileBegin (rqptr, NextTaskFunction, NULL, NULL, rqptr->ParseOds.ExpFileName, "text/plain"); return; } else if (strsame (rqptr->rqHeader.PathInfoPtr, ADMIN_REPORT_SERVICE_LOG, -1)) { LoggingReport (rqptr, &RequestEnd, VirtualHostPort); return; } else if (strsame (rqptr->rqHeader.PathInfoPtr, ADMIN_REPORT_SHOW_PROCESS, -1)) { WatchShowProcess (rqptr, NextTaskFunction, ProcessIdString, ProcessIdUserName); return; } else if (strsame (rqptr->rqHeader.PathInfoPtr, ADMIN_REPORT_STATS, -1)) { AdminReportServerStats (rqptr, NextTaskFunction); return; } else if (strsame (rqptr->rqHeader.PathInfoPtr, ADMIN_REPORT_MAPPING, -1) || strsame (rqptr->rqHeader.PathInfoPtr, ADMIN_REVISE_MAPPING, -1)) { if (VMSnok (status = AdminParsePath (rqptr, NULL))) SysDclAst (NextTaskFunction, rqptr); else if (rqptr->rqHeader.Method == HTTP_METHOD_POST) PutBegin (rqptr, NextTaskFunction); else if (rqptr->rqHeader.QueryStringLength) if (strsame (DoThis, "edit", -1)) UpdBegin (rqptr, NextTaskFunction); else MapUrl_Report (rqptr, NextTaskFunction, UseServerDatabase, VirtualHostPort); else FileBegin (rqptr, NextTaskFunction, NULL, NULL, rqptr->ParseOds.ExpFileName, "text/plain"); return; } else if (strsame (rqptr->rqHeader.PathInfoPtr, ADMIN_REPORT_SSL, -1) || strsame (rqptr->rqHeader.PathInfoPtr, ADMIN_REPORT_SSL_CLIENT, -1)) { SesolaReport (rqptr, NextTaskFunction, VirtualHostPort); return; } else if (strsame (rqptr->rqHeader.PathInfoPtr, ADMIN_REPORT_SSL_CA, -1) || strsame (rqptr->rqHeader.PathInfoPtr, ADMIN_REVISE_SSL_CA, -1)) { if (VMSnok (status = AdminParsePath (rqptr, VirtualHostPort))) SysDclAst (NextTaskFunction, rqptr); else if (rqptr->rqHeader.Method == HTTP_METHOD_POST) PutBegin (rqptr, NextTaskFunction); else if (strsame (DoThis, "edit", -1)) UpdBegin (rqptr, NextTaskFunction); else if (strsame (DoThis, "report", -1)) SesolaReportCA (rqptr, NextTaskFunction, VirtualHostPort); else FileBegin (rqptr, NextTaskFunction, NULL, NULL, rqptr->ParseOds.ExpFileName, "text/plain"); return; } else if (strsame (rqptr->rqHeader.PathInfoPtr, ADMIN_REPORT_SUPERVISOR, -1)) { HttpdSupervisorReport (rqptr, NextTaskFunction); return; } else if (strsame (rqptr->rqHeader.PathInfoPtr, ADMIN_REPORT_SYSTEM, -1)) { WatchShowSystem (rqptr, NextTaskFunction); return; } else if (strsame (rqptr->rqHeader.PathInfoPtr, ADMIN_REPORT_THROTTLE, -1)) { ThrottleReport (rqptr, NextTaskFunction); return; } else if (strsame (rqptr->rqHeader.PathInfoPtr, ADMIN_CONTROL, sizeof(ADMIN_CONTROL)-1)) { /******************/ /* server control */ /******************/ AdminControl (rqptr, NextTaskFunction, NULL, ClusterDo); return; } /********************/ /* unknown function */ /********************/ rqptr->rqResponse.HttpStatus = 400; ErrorGeneral (rqptr, "Unknown function.", FI_LI); SysDclAst (NextTaskFunction, rqptr); } /*****************************************************************************/ /* Compare the path info to each administration path and parses the corresponding real file represented by that path into the request ODS parse structure so that modules that expect this to be filled out appropriately (e.g. UPD.C and PUT.C) can use it. Returns a VMS status. */ int AdminParsePath ( REQUEST_STRUCT *rqptr, char *VirtualHostPort ) { int status; char *cptr, *dnaptr, *sptr, *zptr; char FileSpec [ODS_MAX_FILE_NAME_LENGTH+1]; SERVICE_STRUCT *svptr; /*********/ /* begin */ /*********/ if (WATCHMOD (rqptr, WATCH_MOD__OTHER)) WatchThis (WATCHITM(rqptr), WATCH_MOD__OTHER, "AdminParsePath() !&Z !&Z", rqptr->rqHeader.PathInfoPtr, VirtualHostPort); dnaptr = NULL; cptr = rqptr->rqHeader.PathInfoPtr; if (strsame (cptr, ADMIN_REPORT_CONFIG, -1) || strsame (cptr, ADMIN_REVISE_CONFIG, -1)) sptr = v10orPrev10(CONFIG_FILE_NAME,-1); else if (strsame (cptr, ADMIN_REPORT_MESSAGES, -1) || strsame (cptr, ADMIN_REVISE_MESSAGES, -1)) sptr = v10orPrev10(CONFIG_MSG_FILE_NAME,-1); else if (strsame (cptr, ADMIN_REPORT_AUTH_PATHS, -1) || strsame (cptr, ADMIN_REVISE_AUTH_PATHS, -1)) sptr = v10orPrev10(CONFIG_AUTH_FILE_NAME,-1); else if (strsame (cptr, ADMIN_REPORT_MAPPING, -1) || strsame (cptr, ADMIN_REVISE_MAPPING, -1)) sptr = v10orPrev10(CONFIG_MAP_FILE_NAME,-1); else if (strsame (cptr, ADMIN_REPORT_SERVICES, -1) || strsame (cptr, ADMIN_REVISE_SERVICES, -1)) sptr = v10orPrev10(CONFIG_SERVICE_FILE_NAME,-1); else if (strsame (cptr, ADMIN_REVISE_SITELOG, -1) || strsame (cptr, ADMIN_REVISE_SITELOG_ENTRY, -1)) { if (!(sptr = v10orPrev10(CONFIG_SITELOG_FILE_NAME,0))) sptr = v10orPrev10(DEFAULT_SITELOG_FILE_NAME,0); } else if (strsame (cptr, ADMIN_REPORT_SSL_CA, -1) || strsame (cptr, ADMIN_REVISE_SSL_CA, -1)) { if (VirtualHostPort[0]) { for (svptr = SesolaListHead; svptr; svptr = svptr->NextPtr) if (strsame (svptr->ServerHostPort, VirtualHostPort, -1)) break; if (svptr) sptr = ((SESOLA_CONTEXT*)svptr->SSLserverPtr)->CaFilePtr; else sptr = v10orPrev10(CONFIG_SSL_CAFILE,-1); } else sptr = v10orPrev10(CONFIG_SSL_CAFILE,-1); } else if (strsame (cptr, ADMIN_REVISE_HTA, sizeof(ADMIN_REVISE_HTA)-1)) { /* server admin of HTA database(s) */ zptr = (sptr = FileSpec) + sizeof(FileSpec)-1; if (rqptr->ConfigDirectoryLength) cptr = rqptr->ConfigDirectory; else cptr = AuthConfigHtaDirectory; while (*cptr && sptr < zptr) *sptr++ = *cptr++; cptr = rqptr->rqHeader.PathInfoPtr + sizeof(ADMIN_REVISE_HTA)-1; while (*cptr && sptr < zptr) *sptr++ = *cptr++; *sptr = '\0'; sptr = FileSpec; dnaptr = HTA_FILE_TYPE; } else if (strsame (cptr, ADMIN_VS_REVISE_HTA, sizeof(ADMIN_VS_REVISE_HTA)-1)) { /* per-service admin of HTA database(s) */ if (!rqptr->ConfigDirectoryLength) { rqptr->rqResponse.HttpStatus = 403; ErrorGeneral (rqptr, "Service not configured to allow this.", FI_LI); return (STS$K_ERROR); } zptr = (sptr = FileSpec) + sizeof(FileSpec)-1; for (cptr = rqptr->ConfigDirectory; *cptr && sptr < zptr; *sptr++ = *cptr++); cptr = rqptr->rqHeader.PathInfoPtr + sizeof(ADMIN_VS_REVISE_HTA)-1; while (*cptr && sptr < zptr) *sptr++ = *cptr++; *sptr = '\0'; sptr = FileSpec; dnaptr = HTA_FILE_TYPE; } else if (strsame (cptr, ADMIN_REVISE_HTL, sizeof(ADMIN_REVISE_HTL)-1)) { /* server admin of HTL list(s) */ zptr = (sptr = FileSpec) + sizeof(FileSpec)-1; if (rqptr->ConfigDirectoryLength) cptr = rqptr->ConfigDirectory; else cptr = AuthConfigHtaDirectory; while (*cptr && sptr < zptr) *sptr++ = *cptr++; cptr = rqptr->rqHeader.PathInfoPtr + sizeof(ADMIN_REVISE_HTL)-1; while (*cptr && sptr < zptr) *sptr++ = *cptr++; *sptr = '\0'; sptr = FileSpec; dnaptr = HTL_FILE_TYPE; } else if (strsame (cptr, ADMIN_VS_REVISE_HTL, sizeof(ADMIN_VS_REVISE_HTL)-1)) { /* per-service admin of HTL list(s) */ if (!rqptr->ConfigDirectoryLength) { rqptr->rqResponse.HttpStatus = 403; ErrorGeneral (rqptr, "Service not configured to allow this.", FI_LI); return (STS$K_ERROR); } zptr = (sptr = FileSpec) + sizeof(FileSpec)-1; for (cptr = rqptr->ConfigDirectory; *cptr && sptr < zptr; *sptr++ = *cptr++); cptr = rqptr->rqHeader.PathInfoPtr + sizeof(ADMIN_VS_REVISE_HTL)-1; while (*cptr && sptr < zptr) *sptr++ = *cptr++; *sptr = '\0'; sptr = FileSpec; dnaptr = HTL_FILE_TYPE; } else return (SS$_NORMAL); status = OdsParse (&rqptr->ParseOds, sptr, strlen(sptr), dnaptr, dnaptr ? strlen(dnaptr) : 0, NAM$M_SYNCHK, NULL, rqptr); if (VMSok(status)) status = rqptr->ParseOds.Fab.fab$l_sts; if (VMSok(status)) status = OdsParseTerminate (&rqptr->ParseOds); if (VMSok(status)) { if (WATCHING (rqptr, WATCH_RESPONSE)) WatchThis (WATCHITM(rqptr), WATCH_RESPONSE, "FILE !AZ !AZ", sptr, rqptr->ParseOds.ExpFileName); return (status); } rqptr->rqResponse.ErrorTextPtr = cptr; rqptr->rqResponse.ErrorOtherTextPtr = sptr; ErrorVmsStatus (rqptr, status, FI_LI); return (status); } /*****************************************************************************/ /* Execute server administration menu control actions. */ AdminControl ( REQUEST_STRUCT *rqptr, REQUEST_AST NextTaskFunction, char *DoThis, BOOL ClusterDo ) { int cnt, status, LockIndex; char *cptr, *sptr, *zptr; char String [256]; /*********/ /* begin */ /*********/ if (WATCHMOD (rqptr, WATCH_MOD__OTHER)) WatchThis (WATCHITM(rqptr), WATCH_MOD__OTHER, "AdminControl() !&A !BZ !&B !&Z", NextTaskFunction, DoThis, ClusterDo, rqptr->rqHeader.PathInfoPtr); cptr = rqptr->rqHeader.PathInfoPtr; if (strsame (cptr, ADMIN_CONTROL_PROXY_ADJUST, -1)) { /* proxy serving adjustment menu */ ProxyMaintAdjust (rqptr, NextTaskFunction); return; } if (strsame (cptr, ADMIN_CONTROL_PROXY_ADJUST_NOW, -1)) { /* adjust proxy serving configuration */ ProxyMaintControl (rqptr, NextTaskFunction); return; } sptr = NULL; if (DoThis) sptr = DoThis; else if (strsame (cptr, ADMIN_CONTROL_AUTH_LOAD, -1)) sptr = CONTROL_AUTH_LOAD1; else if (strsame (cptr, ADMIN_CONTROL_AUTH_PURGE, -1)) sptr = CONTROL_AUTH_PURGE; else if (strsame (cptr, ADMIN_VS_CONTROL_AUTH_PURGE, -1)) sptr = CONTROL_AUTH_PURGE; else if (strsame (cptr, ADMIN_CONTROL_CACHE_ON, -1)) sptr = CONTROL_CACHE_ON; else if (strsame (cptr, ADMIN_CONTROL_CACHE_OFF, -1)) sptr = CONTROL_CACHE_OFF; else if (strsame (cptr, ADMIN_CONTROL_CACHE_PURGE, -1)) sptr = CONTROL_CACHE_PURGE; else if (strsame (cptr, ADMIN_CONTROL_DCL_PURGE, -1)) sptr = CONTROL_DCL_PURGE; else if (strsame (cptr, ADMIN_CONTROL_DCL_DELETE, -1)) sptr = CONTROL_DCL_DELETE; else if (strsame (cptr, ADMIN_CONTROL_DECNET_DISCONNECT, -1)) sptr = CONTROL_DECNET_DISCONNECT; else if (strsame (cptr, ADMIN_CONTROL_DECNET_PURGE, -1)) sptr = CONTROL_DECNET_PURGE; else if (strsame (cptr, ADMIN_CONTROL_EXIT, -1)) sptr = CONTROL_EXIT; else if (strsame (cptr, ADMIN_CONTROL_EXIT_NOW, -1)) sptr = CONTROL_EXIT_NOW; else if (strsame (cptr, ADMIN_CONTROL_HTTP2_PURGE, -1)) sptr = CONTROL_HTTP2_PURGE; else if (strsame (cptr, ADMIN_CONTROL_HTTP2_PURGE_ALL, -1)) sptr = CONTROL_HTTP2_PURGE_ALL; else if (strsame (cptr, ADMIN_CONTROL_INSTANCE_ACTIVE, -1)) sptr = CONTROL_INSTANCE_ACTIVE; else if (strsame (cptr, ADMIN_CONTROL_INSTANCE_PASSIVE, -1)) sptr = CONTROL_INSTANCE_PASSIVE; else if (strsame (cptr, ADMIN_CONTROL_INSTANCE, sizeof(ADMIN_CONTROL_INSTANCE)-1)) { sptr = cptr; while (*cptr) cptr++; while (cptr > sptr && *cptr != '/') cptr--; if (*cptr == '/') { cptr++; FaoToBuffer (String, sizeof(String), NULL, "!AZ!AZ", CONTROL_INSTANCE, cptr); sptr = String; } } else if (strsame (cptr, ADMIN_CONTROL_LOG_OPEN, -1)) sptr = CONTROL_LOG_OPEN; else if (strsame (cptr, ADMIN_CONTROL_LOG_CLOSE, -1)) sptr = CONTROL_LOG_CLOSE; else if (strsame (cptr, ADMIN_CONTROL_LOG_FLUSH, -1)) sptr = CONTROL_LOG_FLUSH; else if (strsame (cptr, ADMIN_CONTROL_MAP, -1)) sptr = CONTROL_MAP_LOAD1; else if (strsame (cptr, ADMIN_CONTROL_NET_PURGE, -1)) sptr = CONTROL_NET_PURGE; else if (strsame (cptr, ADMIN_CONTROL_NET_PURGE_ALL, -1)) sptr = CONTROL_NET_PURGE_ALL; else if (strsame (cptr, ADMIN_CONTROL_PROXY_ON, -1)) sptr = CONTROL_PROXY_ON; else if (strsame (cptr, ADMIN_CONTROL_PROXY_OFF, -1)) sptr = CONTROL_PROXY_OFF; else if (strsame (cptr, ADMIN_CONTROL_PROXY_PURGE_BCKGRND, -1)) sptr = CONTROL_PROXY_PURGE_BCKGRND; else if (strsame (cptr, ADMIN_CONTROL_PROXY_PURGE_REACTIVE, -1)) sptr = CONTROL_PROXY_PURGE_REACTIVE; else if (strsame (cptr, ADMIN_CONTROL_PROXY_PURGE_ROUTINE, -1)) sptr = CONTROL_PROXY_PURGE_ROUTINE; else if (strsame (cptr, ADMIN_CONTROL_PROXY_PURGE_HOST, -1)) sptr = CONTROL_PROXY_PURGE_HOST; else if (strsame (cptr, ADMIN_CONTROL_PROXY_STATISTICS, -1)) sptr = CONTROL_PROXY_STATISTICS; else if (strsame (cptr, ADMIN_CONTROL_PROXY_STOP_SCAN, -1)) sptr = CONTROL_PROXY_STOP_SCAN; else if (strsame (cptr, ADMIN_CONTROL_RESTART, -1)) sptr = CONTROL_RESTART; else if (strsame (cptr, ADMIN_CONTROL_RESTART_NOW, -1)) sptr = CONTROL_RESTART_NOW; else if (strsame (cptr, ADMIN_CONTROL_RESTART_QUIET, -1)) sptr = CONTROL_RESTART_QUIET; else if (strsame (cptr, ADMIN_CONTROL_SSL_CA_LOAD, -1)) sptr = CONTROL_SSL_CA_LOAD; else if (strsame (cptr, ADMIN_CONTROL_THROTTLE_RELEASE, -1)) sptr = CONTROL_THROTTLE_RELEASE; else if (strsame (cptr, ADMIN_CONTROL_THROTTLE_TERMINATE, -1)) sptr = CONTROL_THROTTLE_TERMINATE; else if (strsame (cptr, ADMIN_CONTROL_WEBSOCKET_DISCONNECT, -1)) sptr = CONTROL_WEBSOCKET_DISCONNECT; else if (strsame (cptr, ADMIN_CONTROL_THROTTLE_ZERO, -1)) sptr = CONTROL_THROTTLE_ZERO; else if (strsame (cptr, ADMIN_CONTROL_ZERO_NOTICED, -1)) sptr = CONTROL_ZERO_NOTICED; else if (strsame (cptr, ADMIN_CONTROL_ZERO_PROXY, -1)) sptr = CONTROL_ZERO_PROXY; else if (strsame (cptr, ADMIN_CONTROL_ZERO, -1)) sptr = CONTROL_ZERO; if (!sptr) { /* unknown function */ rqptr->rqResponse.HttpStatus = 400; ErrorGeneral (rqptr, "Unknown control function.", FI_LI); SysDclAst (NextTaskFunction, rqptr); return; } if (ClusterDo) LockIndex = INSTANCE_CLUSTER_DO; else LockIndex = INSTANCE_NODE_DO; cptr = ControlEnqueueCommand (LockIndex, sptr); strcat (cptr, "."); if (*cptr == '!') { rqptr->rqResponse.HttpStatus = 403; cptr[1] = TOUP(cptr[1]); ErrorGeneral (rqptr, cptr+1, FI_LI); } else { cptr[0] = TOUP(cptr[0]); ReportSuccess (rqptr, "Command !AZ", cptr); } SysDclAst (NextTaskFunction, rqptr); } /*****************************************************************************/ /* Provide a menu of HTTPd server administration functions. */ AdminMenu ( REQUEST_STRUCT *rqptr, REQUEST_AST NextTaskFunction ) { static int ActHours [] = { 1, 2, 4, 8, 16, 24, 72, 168, 336, 504, 672, 0 }; static char BeginPageFao [] = "!AZ\ \n\ \n\ !AZ\ !AZ\ !&@\ WASD !AZ ... Server Administration\n\ \n\ \n\ \n\ !AZ\n\
\n\

WASD !AZ

\n\

Server Administration!&@

\n\

\n\ \

\n\ \ \n\ \ \n\ \ \n\ \n\ \ \n\ \n\ \n"; static char EndPageFao [] = "
Configuration
\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\ \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\ \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\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \
|Report|Revise|Action|
ServerStatistics!&@Site-LogEditZero
ConfigurationServerFileServerFileEdit
ServicesServerFileServerFileEditPurgeAll
MessagesServerFileServerFileEdit
Path MappingServerFileEditReload
Path AuthorizationServerFileEditReload
User AuthenticationServerHTA\ HTLPurge
Secure Sockets!&@!&@!&@!&@
Other Reports\n\ !&@\n\ !&@\n\ !&@\n\ !&@\n\ !&@\n\ !&@\n\
\n\ !&@\n\ !&@\n\ !&@\n\ !&@\n\ !&@\n\ !&@\n\
\n\ !&@\n\ !&@\n\ !&@\n\ !&@\n\ !&@\n\ !&@\n\
\n\ !&@!&@!&@!&@!&@!&@!&@!&@!&@!&@!&@ \ hours activity\n\
\n\ \
Control\n\ \n\ \ \n\ \n\ \n\ \ \n\ \ \n\ \ \n\ \ \n\ \ \n\ \ \n\ \ \n\ \ \n\ \ \n\ \ \n\ \ \n\ \ \n\ \ \n\ \ \n\ \ \n\ \ !&@\ \
\ !20&W
!AZ (!AZ)
!&@
Time!AZ::!%D
!AZ:!%D
Image:!%D
CPU:!UL !2ZL:!2ZL:!2ZL.!2ZL
ConnectCurrent:!&L
Peak:!&L
Total:!&L
RequestCurrent:!&L
Peak:!&L
Total:!&L
Bytes:!&,@SQ
\n\ \
\n\ \ \n\ \n\ \n\
\n\ \ \n\ \n\ \n\ \n\ \n\ \n\
\ RESTART\
\ \ RESTARTNOW\ \
\ \ RESTARTQuiet\ \
\ EXIT\
\ \ EXITNOW\ \
\n\ \
\n\ \ \n\ \n\ \n\ \n\ \n\ \n\
Log!&@
Cache!&@
Proxy!&@
Instance\ !&@\ !&@"; static char EndInstanceFao [] = "
!&@
\n\ \
\ \ \
\n\
\n\ \
\n\ \ \n\ !AZ\ \
\n\ \n\ \n"; static unsigned long LibDeltaHours = LIB$K_DELTA_HOURS; static unsigned short SyiClusterNodes; static unsigned long JpiCpuTime, Pid = 0; static unsigned long ActivityUpTime [QUAD2], CurrentTime64 [QUAD2], ImageUpTime [QUAD2], JpiLoginTime [QUAD2], ProcessUpTime [QUAD2], SystemUpTime [QUAD2]; static VMS_ITEM_LIST3 JpiItems [] = { { sizeof(JpiCpuTime), JPI$_CPUTIM, &JpiCpuTime, 0 }, { sizeof(JpiLoginTime), JPI$_LOGINTIM, &JpiLoginTime, 0 }, {0,0,0,0} }; static VMS_ITEM_LIST3 SyiItem [] = { { sizeof(SyiClusterNodes), SYI$_CLUSTER_NODES, &SyiClusterNodes, 0 }, { 0,0,0,0 } }; int cnt, idx, status, total, ClusterInstanceCount, InstanceStartupMax, NodeInstanceCount; unsigned short Length; unsigned long ActivityDeltaHours; unsigned long *vecptr; unsigned long BytesTotal [QUAD2], FaoVector [192]; char *cptr, *ClusterInstancePtr, *NodeInstancePtr; IO_SB IOsb; /*********/ /* begin */ /*********/ if (WATCHMOD (rqptr, WATCH_MOD__OTHER)) WatchThis (WATCHITM(rqptr), WATCH_MOD__OTHER, "AdminMenu() !&A", NextTaskFunction); if (HTTP2_REQUEST(rqptr)) Http2Ping (rqptr->Http2Stream.Http2Ptr, 0, NULL, 0); status = sys$getjpiw (EfnWait, &Pid, 0, &JpiItems, &IOsb, 0, 0); if (VMSok (status)) status = IOsb.Status; if (VMSnok (status)) { rqptr->rqResponse.ErrorTextPtr = "sys$getjpiw()"; ErrorVmsStatus (rqptr, status, FI_LI); SysDclAst (NextTaskFunction, rqptr); return; } status = sys$getsyiw (EfnWait, 0, 0, &SyiItem, &IOsb, 0, 0); if (VMSok (status)) status = IOsb.Status; if (VMSnok (status)) { rqptr->rqResponse.ErrorTextPtr = "sys$getsyiw()"; ErrorVmsStatus (rqptr, status, FI_LI); SysDclAst (NextTaskFunction, rqptr); return; } sys$gettim (&CurrentTime64); lib$sub_times (&CurrentTime64, &SysInfo.BootTime64, &SystemUpTime); lib$sub_times (&CurrentTime64, &HttpdStartTime64, &ImageUpTime); lib$sub_times (&CurrentTime64, &JpiLoginTime, &ProcessUpTime); if (ActivityTotalMinutes) { InstanceMutexLock (INSTANCE_MUTEX_HTTPD); lib$sub_times (&CurrentTime64, &ActivityGblSecPtr->StartTime64, &ActivityUpTime); InstanceMutexUnLock (INSTANCE_MUTEX_HTTPD); lib$cvt_from_internal_time (&LibDeltaHours, &ActivityDeltaHours, &ActivityUpTime); } else ActivityDeltaHours = 0; /* get the number (if any) of other HTTP servers on this node/cluster */ NodeInstanceCount = InstanceLockList (INSTANCE_NODE_SUPERVISOR, "\n", &NodeInstancePtr); ClusterInstanceCount = InstanceLockList (INSTANCE_CLUSTER, "\n", &ClusterInstancePtr); vecptr = FaoVector; *vecptr++ = WASD_DOCTYPE; *vecptr++ = HtmlMetaInfo (rqptr, NULL); *vecptr++ = AdminWasdCss (); if (rqptr->rqPathSet.StyleSheetPtr) { *vecptr++ = "\n"; *vecptr++ = rqptr->rqPathSet.StyleSheetPtr; } else *vecptr++ = ""; *vecptr++ = ServerHostPort; if (SyiClusterNodes > 1 && ClusterInstanceCount > NodeInstanceCount) { *vecptr++ = " scope = \"node instance!&?s\r\r\";\n\ if (document.doallForm.scope[1].checked) {\n\ if (link.href.indexOf(\"?\") >= 0) link.href = \ link.href.substring(0,link.href.indexOf(\"?\"));\n\ link.href = link.href + \"?scope=cluster\";\n\ scope = \"cluster instances\";\n\ }\n"; *vecptr++ = (NodeInstanceCount > 1); } else { *vecptr++ = "scope = \"node instance!&?s\r\r\";\n"; *vecptr++ = (NodeInstanceCount > 1); } *vecptr++ = Config.cfServer.AdminBodyTag; *vecptr++ = ServerHostPort; if (InstanceNodeCurrent > 1) { if (rqptr->ServicePtr->AdminService) *vecptr++ = "  -  !AZ"; else *vecptr++ = "    (!AZ)"; *vecptr++ = HttpdProcess.PrcNam; } else *vecptr++ = ""; /* statistics */ *vecptr++ = ADMIN_REPORT_STATS; if (HttpdProcess.SysOutputFile) { *vecptr++ = "Log"; *vecptr++ = ADMIN_REPORT_PROCESS_OUTPUT; } else *vecptr++ = "Log"; *vecptr++ = ADMIN_REVISE_SITELOG_ENTRY; *vecptr++ = ADMIN_REVISE_SITELOG; *vecptr++ = ADMIN_CONTROL_ZERO; /* configuration */ *vecptr++ = ADMIN_REPORT_CONFIG; *vecptr++ = ADMIN_REPORT_CONFIG; *vecptr++ = ADMIN_REVISE_CONFIG; *vecptr++ = ADMIN_REVISE_CONFIG; *vecptr++ = ADMIN_REVISE_CONFIG; /* services */ *vecptr++ = ADMIN_REPORT_SERVICES; *vecptr++ = ADMIN_REPORT_SERVICES; *vecptr++ = ADMIN_REVISE_SERVICES; *vecptr++ = ADMIN_REVISE_SERVICES; *vecptr++ = ADMIN_REVISE_SERVICES; *vecptr++ = ADMIN_CONTROL_NET_PURGE; *vecptr++ = ADMIN_CONTROL_NET_PURGE_ALL; /* messages */ *vecptr++ = ADMIN_REPORT_MESSAGES; *vecptr++ = ADMIN_REPORT_MESSAGES; *vecptr++ = ADMIN_REVISE_MESSAGES; *vecptr++ = ADMIN_REVISE_MESSAGES; *vecptr++ = ADMIN_REVISE_MESSAGES; /* mapping */ *vecptr++ = ADMIN_REPORT_MAPPING; *vecptr++ = ADMIN_REPORT_MAPPING; *vecptr++ = ADMIN_REVISE_MAPPING; *vecptr++ = ADMIN_CONTROL_MAP; /* authorization */ *vecptr++ = ADMIN_REPORT_AUTH_PATHS; *vecptr++ = ADMIN_REPORT_AUTH_PATHS; *vecptr++ = ADMIN_REVISE_AUTH_PATHS; *vecptr++ = ADMIN_CONTROL_AUTH_LOAD; /* authentication */ *vecptr++ = ADMIN_REPORT_AUTH_USER; *vecptr++ = ADMIN_REVISE_HTA; *vecptr++ = ADMIN_REVISE_HTL; *vecptr++ = ADMIN_CONTROL_AUTH_PURGE; /* secure socket layer */ if (ProtocolHttpsConfigured) { *vecptr++ = "Service"; *vecptr++ = ADMIN_REPORT_SSL; if (SesolaVerifyCAConfigured) { *vecptr++ = "CA"; *vecptr++ = ADMIN_REPORT_SSL_CA; *vecptr++ = rqptr->ServicePtr->ServerHostPort; *vecptr++ = "Edit-CA"; *vecptr++ = ADMIN_REVISE_SSL_CA; *vecptr++ = "Load-CA"; *vecptr++ = ADMIN_CONTROL_SSL_CA_LOAD; } else { *vecptr++ = "CA"; *vecptr++ = "Edit-CA"; *vecptr++ = "Load-CA"; } } else { *vecptr++ = "Service"; *vecptr++ = "CA"; *vecptr++ = "Edit-CA"; *vecptr++ = "Load-CA"; } /* other */ if (HttpdAlignFaultReport) { *vecptr++ = "AlnFlt"; *vecptr++ = ADMIN_REPORT_ALIGN; } else *vecptr++ = "AlnFlt"; *vecptr++ = "Cache"; *vecptr++ = ADMIN_REPORT_CACHE; if (SyiClusterNodes > 1) { *vecptr++ = "Cluster"; *vecptr++ = ADMIN_REPORT_CLUSTER; } else *vecptr++ = "Cluster"; *vecptr++ = "DCL"; *vecptr++ = ADMIN_REPORT_DCL; *vecptr++ = "DECnet"; *vecptr++ = ADMIN_REPORT_DECNET; if (TcpIpHostCachePtr) { *vecptr++ = "Host"; *vecptr++ = ADMIN_REPORT_HOSTCACHE; } else *vecptr++ = "Host"; *vecptr++ = "HTTP"; *vecptr++ = ADMIN_REPORT_HTTP; *vecptr++ = "Lock"; *vecptr++ = ADMIN_REPORT_LOCK; *vecptr++ = "Match"; *vecptr++ = ADMIN_REPORT_MATCH; *vecptr++ = "Memory"; *vecptr++ = ADMIN_REPORT_MEMORY; *vecptr++ = "Process"; *vecptr++ = ADMIN_REPORT_PROCESS; if (ProxyServiceCount) { *vecptr++ = "Proxy"; *vecptr++ = ADMIN_REPORT_PROXY; } else *vecptr++ = "Proxy"; *vecptr++ = "Request"; *vecptr++ = ADMIN_REPORT_REQUEST; *vecptr++ = "System"; *vecptr++ = ADMIN_REPORT_SYSTEM; if (MappingMetaPtr->ThrottleTotal) { *vecptr++ = "Throttle"; *vecptr++ = ADMIN_REPORT_THROTTLE; } else *vecptr++ = "Throttle"; if (WATCH_CAT || !Watch.Disabled) { *vecptr++ = "WATCH"; *vecptr++ = ADMIN_REPORT_WATCH; } else *vecptr++ = "WATCH"; if (WebDavEnabled) { *vecptr++ = "WebDAV"; *vecptr++ = ADMIN_REPORT_WEBDAV; } else *vecptr++ = "WebDAV"; *vecptr++ = "WebSocket"; *vecptr++ = ADMIN_REPORT_WEBSOCKET; for (idx = 0; ActHours[idx]; idx++) { if (ActivityTotalMinutes && ActivityDeltaHours >= ActHours[idx]-1) { *vecptr++ = "!-!UL"; *vecptr++ = ADMIN_REPORT_ACTIVITY; *vecptr++ = ActHours[idx]; } else { *vecptr++ = "!UL"; *vecptr++ = ActHours[idx]; } } *vecptr++ = &rqptr->rqTime.BeginTime64; *vecptr++ = rqptr->rqTime.GmDateTime; *vecptr++ = TimeGmtString; /* client using the Server Admin */ if (MATCH8 (&rqptr->ClientPtr->IpAddressString, rqptr->ClientPtr->Lookup.HostName)) { /* client IP address DNS lookup is disabled */ cptr = AdminLookYouUp (&rqptr->ClientPtr->IpAddress); if (cptr && *cptr) { *vecptr++ = "!AZ (!AZ) !&@"; *vecptr++ = cptr; } else *vecptr++ = "!AZ !&@"; } else { *vecptr++ = "!AZ (!AZ) !&@"; *vecptr++ = rqptr->ClientPtr->Lookup.HostName; } *vecptr++ = &rqptr->ClientPtr->IpAddressString; if (HTTP2_REQUEST(rqptr)) { if (rqptr->Http2Stream.Http2Ptr->PingMicroSeconds) { *vecptr++ = "HTTP/2 !UL.!ULmS"; *vecptr++ = rqptr->Http2Stream.Http2Ptr->PingMicroSeconds / 1000; *vecptr++ = rqptr->Http2Stream.Http2Ptr->PingMicroSeconds % 1000; } else *vecptr++ = "HTTP/2"; } else if (rqptr->rqResponse.HttpVersion == HTTP_VERSION_1_1) *vecptr++ = "HTTP/1.1"; else *vecptr++ = "HTTP/1.0"; /* informational accounting */ *vecptr++ = SysInfo.NodeName; *vecptr++ = &SystemUpTime; if (NodeInstanceCount > 1) *vecptr++ = HttpdProcess.PrcNam; else *vecptr++ = "Process"; *vecptr++ = &ProcessUpTime; *vecptr++ = &ImageUpTime; *vecptr++ = JpiCpuTime / 8640000; /* CPU day */ *vecptr++ = (JpiCpuTime % 8640000) / 360000; /* CPU hour */ *vecptr++ = (JpiCpuTime % 360000) / 6000; /* CPU minute */ *vecptr++ = (JpiCpuTime % 6000 ) / 100; /* CPU second */ *vecptr++ = JpiCpuTime % 100; /* CPU 10 milliseconds */ *vecptr++ = acptr->CurrentConnected[HTTP12]; *vecptr++ = acptr->ConnectPeak[HTTP12]; *vecptr++ = acptr->ConnectCount[HTTP12]; *vecptr++ = acptr->CurrentProcessing[HTTP12]; *vecptr++ = acptr->ProcessingPeak[HTTP12]; *vecptr++ = acptr->ProcessingTotalCount[HTTP12]; PLUS_QUAD_QUAD (acptr->BytesRawRx[HTTP12], acptr->BytesRawTx[HTTP12], BytesTotal); *vecptr++ = &BytesTotal; if (LoggingFileError) *vecptr++ = "Problem writing access logs!!"; else *vecptr++ = ""; /* server control menu items */ *vecptr++ = ADMIN_CONTROL_RESTART; *vecptr++ = ADMIN_CONTROL_RESTART_NOW; *vecptr++ = ADMIN_CONTROL_RESTART_QUIET; *vecptr++ = ADMIN_CONTROL_EXIT; *vecptr++ = ADMIN_CONTROL_EXIT_NOW; /* logging control menu items */ if (LoggingEnabled) { *vecptr++ = "On\ Off\ Flush"; *vecptr++ = ADMIN_CONTROL_LOG_CLOSE; *vecptr++ = ADMIN_CONTROL_LOG_FLUSH; } else { *vecptr++ = "On\ Off\ Flush"; *vecptr++ = ADMIN_CONTROL_LOG_OPEN; } /* cache control menu items */ if (CacheEnabled) { *vecptr++ = "On\ Off\ Purge"; *vecptr++ = ADMIN_CONTROL_CACHE_OFF; *vecptr++ = ADMIN_CONTROL_CACHE_PURGE; } else { *vecptr++ = "On\ Off\ Flush"; *vecptr++ = ADMIN_CONTROL_CACHE_ON; } /* proxy control */ if (ProxyServiceCount) { *vecptr++ = "Adjust\ Zero"; *vecptr++ = ADMIN_CONTROL_PROXY_ADJUST; *vecptr++ = ADMIN_CONTROL_ZERO_PROXY; } else *vecptr++ = "Adjust\ Zero"; InstanceMutexLock (INSTANCE_MUTEX_HTTPD); InstanceStartupMax = HttpdGblSecPtr->InstanceStartupMax; InstanceMutexUnLock (INSTANCE_MUTEX_HTTPD); if (!InstanceStartupMax) { *vecptr++ = "Max"; *vecptr++ = ADMIN_CONTROL_INSTANCE; } else *vecptr++ = "Max"; if (InstanceStartupMax != INSTANCE_PER_CPU) { *vecptr++ = "CPU"; *vecptr++ = ADMIN_CONTROL_INSTANCE; } else *vecptr++ = "CPU"; FaoCheck (sizeof(FaoVector), &FaoVector, vecptr, FI_LI); status = FaolToNet (rqptr, BeginPageFao, &FaoVector); if (VMSnok (status)) ErrorNoticed (rqptr, status, NULL, FI_LI); for (cnt = 1; cnt <= INSTANCE_MAX; cnt++) { vecptr = FaoVector; if (cnt == InstanceStartupMax) { *vecptr++ = cnt; status = FaolToNet (rqptr, "!UL", &FaoVector); } else { *vecptr++ = ADMIN_CONTROL_INSTANCE; *vecptr++ = cnt; status = FaolToNet (rqptr, "!-!UL", &FaoVector); } if (VMSnok (status)) ErrorNoticed (rqptr, status, NULL, FI_LI); if (cnt == 2) FaolToNet (rqptr, "
\n", NULL); } vecptr = FaoVector; /* instance active/pass control menu items */ if (InstanceNodeCurrent == 1) { *vecptr++ = "Active\ Passive"; } else if (NetInstancePassive) { *vecptr++ = "Active\ Passive"; *vecptr++ = ADMIN_CONTROL_INSTANCE_ACTIVE; } else { *vecptr++ = "Active\ Passive"; *vecptr++ = ADMIN_CONTROL_INSTANCE_PASSIVE; } status = FaolToNet (rqptr, EndInstanceFao, &FaoVector); if (VMSnok (status)) ErrorNoticed (rqptr, status, NULL, FI_LI); InstanceStatusAdminReport (rqptr); status = FaoToNet (rqptr, EndPageFao, AdminRefresh()); if (VMSnok (status)) ErrorNoticed (rqptr, status, NULL, FI_LI); if (NodeInstancePtr) VmFree (NodeInstancePtr, FI_LI); if (ClusterInstancePtr) VmFree (ClusterInstancePtr, FI_LI); rqptr->rqResponse.PreExpired = PRE_EXPIRE_ADMIN; ResponseHeader200 (rqptr, "text/html", &rqptr->NetWriteBufferDsc); SysDclAst (NextTaskFunction, rqptr); } /*****************************************************************************/ /* Provide a menu of HTTPd per-service administration functions. */ AdminVirtualServerMenu ( REQUEST_STRUCT *rqptr, REQUEST_AST NextTaskFunction ) { char BeginPageFao [] = "!AZ\ \n\ \n\ !AZ\ WASD !AZ ... Virtual Server Administration\n\ \n\ !AZ\n\

WASD !AZ

\n\

Virtual Server Administration

\n\

\n\ \ \n\ \n\
\n\ \ \n\ \ \ \n\ \n\ \n\ \n\ \ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \
TimeLocal: !20&W
Universal:!AZ (!AZ)
System-Up:!%D
Authentication  HTA:[Access]
HTL:[Access]
Cache:[Purge]
\n\ \
\n\ \ \n\ \ \n\ \n\ \n"; static unsigned long LibDeltaHours = LIB$K_DELTA_HOURS; static unsigned long Pid = 0; static unsigned long CurrentTime64 [QUAD2], JpiLoginTime [QUAD2], SystemUpTime [QUAD2]; static VMS_ITEM_LIST3 JpiItems [] = { { sizeof(JpiLoginTime), JPI$_LOGINTIM, &JpiLoginTime, 0 }, {0,0,0,0} }; int status; unsigned short Length; unsigned long *vecptr; unsigned long FaoVector [32]; IO_SB IOsb; /*********/ /* begin */ /*********/ if (WATCHMOD (rqptr, WATCH_MOD__OTHER)) WatchThis (WATCHITM(rqptr), WATCH_MOD__OTHER, "AdminVirtualServerMenu() !&A", NextTaskFunction); status = sys$getjpiw (EfnWait, &Pid, 0, &JpiItems, &IOsb, 0, 0); if (VMSok (status)) status = IOsb.Status; if (VMSnok (status)) { rqptr->rqResponse.ErrorTextPtr = "sys$getjpiw()"; ErrorVmsStatus (rqptr, status, FI_LI); SysDclAst (NextTaskFunction, rqptr); return; } sys$gettim (&CurrentTime64); lib$sub_times (&CurrentTime64, &SysInfo.BootTime64, &SystemUpTime); vecptr = FaoVector; *vecptr++ = WASD_DOCTYPE; *vecptr++ = HtmlMetaInfo (rqptr, NULL); *vecptr++ = ServerHostPort; *vecptr++ = Config.cfServer.AdminBodyTag; *vecptr++ = ServerHostPort; *vecptr++ = &rqptr->rqTime.BeginTime64; *vecptr++ = rqptr->rqTime.GmDateTime; *vecptr++ = TimeGmtString; *vecptr++ = &SystemUpTime; *vecptr++ = ADMIN_VS_REVISE_HTA; *vecptr++ = ADMIN_VS_REVISE_HTL; *vecptr++ = ADMIN_VS_CONTROL_AUTH_PURGE; FaoCheck (sizeof(FaoVector), &FaoVector, vecptr, FI_LI); status = FaolToNet (rqptr, BeginPageFao, &FaoVector); if (VMSnok (status)) ErrorNoticed (rqptr, status, NULL, FI_LI); rqptr->rqResponse.PreExpired = PRE_EXPIRE_ADMIN; ResponseHeader200 (rqptr, "text/html", &rqptr->NetWriteBufferDsc); SysDclAst (NextTaskFunction, rqptr); } /*****************************************************************************/ /* The 'InstanceList' comprises a string containing instance process names in the format 'node::WASD:port' (e.g. DELTA::WASD:80") separated by newlines (the string is generated by InstanceLockList()). Parse this list using the process names to interogate locks taken out by each process to contain their per-instance administration IP address and port. Use this information to return a count of how many such ports are available. */ int AdminMenuInstanceCount ( REQUEST_STRUCT *rqptr, char *InstanceList ) { int status, AdminPortCount; char ch; char *cptr, *sptr; /*********/ /* begin */ /*********/ if (WATCHMOD (rqptr, WATCH_MOD__OTHER)) WatchThis (WATCHITM(rqptr), WATCH_MOD__OTHER, "AdminMenuInstanceCount() !&Z", InstanceList); AdminPortCount = 0; cptr = InstanceList; while (*cptr) { sptr = cptr; while (*cptr && *cptr != '\n') cptr++; ch = *cptr; if (*cptr) *cptr = '\0'; status = InstanceSocketForAdmin (sptr, NULL); if (VMSok (status)) AdminPortCount++; if (*cptr = ch) cptr++; } return (AdminPortCount); } /*****************************************************************************/ /* The 'InstanceList' comprises a string containing instance process names in the format 'node::WASD:port' (e.g. DELTA::WASD:80") separated by newlines (the string is generated by InstanceLockList()). Parse this list using the process names to interogate locks taken out by each process to contain their per-instance administration IP address and port. Use this information to generate links to each of the instances. */ AdminMenuInstanceList ( REQUEST_STRUCT *rqptr, char *InstanceList ) { BOOL InsrancePassive; int status; unsigned short IpPort; unsigned long *vecptr; unsigned long FaoVector [16]; char ch; char *aptr, *cptr, *sptr, *zptr; /*********/ /* begin */ /*********/ if (WATCHMOD (rqptr, WATCH_MOD__OTHER)) WatchThis (WATCHITM(rqptr), WATCH_MOD__OTHER, "AdminMenuInstanceList() !&Z", InstanceList); cptr = InstanceList; while (*cptr) { sptr = cptr; while (*cptr && *cptr != '\n') cptr++; ch = *cptr; if (*cptr) *cptr = '\0'; vecptr = FaoVector; status = InstanceSocketForAdmin (sptr, &IpPort); if (VMSnok (status)) ErrorNoticed (rqptr, status, NULL, FI_LI); aptr = ""; if (NetInstancePassive) { /* node::prcnam */ for (zptr = sptr; *zptr != ':'; zptr++); if (*zptr) { *zptr = '\0'; if (!strcmp (sptr, SysInfo.NodeName)) { if (InstanceNodeSupervisor && !strcmp (zptr+2, HttpdProcess.PrcNam)) aptr = "  active"; else aptr = "  passive"; } *zptr = ':'; } } if (IpPort) { *vecptr++ = "!AZ!AZ
\n"; *vecptr++ = rqptr->ServicePtr->RequestSchemeNamePtr; *vecptr++ = strchr(sptr,':') - sptr; *vecptr++ = sptr; *vecptr++ = IpPort; *vecptr++ = rqptr->rqHeader.PathInfoPtr; } else *vecptr++ = "!AZ!AZ
\n"; *vecptr++ = sptr; *vecptr++ = aptr; FaoCheck (sizeof(FaoVector), &FaoVector, vecptr, FI_LI); status = FaolToNet (rqptr, "!&@", &FaoVector); if (VMSnok (status)) ErrorNoticed (rqptr, status, NULL, FI_LI); if (*cptr = ch) cptr++; } } /*****************************************************************************/ /* Return report on the HTTPd server's activities. */ AdminReportServerStats ( REQUEST_STRUCT *rqptr, REQUEST_AST NextTaskFunction ) { /* ALTPRI and SETPRI synonyms? */ #define IMAG_PRIV_0_ALLOWED \ (~(PRV$M_ALTPRI | PRV$M_CMKRNL | PRV$M_DETACH | PRV$M_PRMGBL | \ PRV$M_PRMMBX | PRV$M_SHMEM | PRV$M_SYSGBL | PRV$M_SYSNAM | \ PRV$M_SYSLCK | PRV$M_SYSPRV | PRV$M_PSWAPM | PRV$M_WORLD)) #define IMAG_PRIV_1_ALLOWED (~(0x40 /* PRV$M_SECURITY */)) /* VAX VMS does not seem to like "!@UQ" and must be made "!@UJ"!!! The VAX version not supporting this doesn't seem to be documented, but at run-time returns a %X00000014 status (%SYSTEM-F-BADPARAM). Implication: VAX version can only report a maximum of 2^32-1 bytes, or 4,294,967,295 before overflow, AXP 2^64-1 (calculator gave an ERROR :^) */ static char BeginPageFao [] = "

\n\ \n\ \n\
Environment!AZ
\n\ \n\ \n\ \n\ \n\ !&@\ \n\ \ \n\ \n\ \n\
Version:!AZ
Build:!AZ
SSL:!AZ
TCP/IP:!AZ
System:!AZ with !UL CPU!%s and !ULMB running VMS !AZ
Startup:!&;AZ
!#AZ:!&;AZ
\n\
\n\ \

\n\ \n\ \n\
Instances
\n\ \n\ \n\ \n\ \n\
NodeCluster
!AZ!AZ
!AZ
\n\
\n\ \

\n\ \n\ \n\
!&?Server\rInstance\r Process
\n\ \n\ \ \ \ \ \n\ \ \ \ \ \n\ \ \ \ \ \n\ \ \ \ \n\ \n\ \ \n\ \ \ \n\ \ \ \n\ \ \n\ \ \ \ \ \n\ \ \ \ \ \n\ \ \ \ \n\ \n\ \ \n\ \ \n\
Name:!AZPID:!8XLUser:!AZ
AuthPriv:!AZImagPriv:!AZCurPriv:!AZ
Last Exit:!AZExit Time:!AZExit PID:!AZ
Image:!%DProcess:!%DCPU:!UL !2ZL:!2ZL:!2ZL.!2ZL
Pg.Faults:!ULStartup:!ULMode:!AZ
WsSize:!ULWsPeak:!ULVirtPeak:!UL
AST:!UL / !UL (!UL%)BIO:!UL / !UL (!UL%)BYT:!UL / !UL (!UL%)
DIO:!UL / !UL (!UL%)ENQ:!UL / !UL (!UL%)FIL:!UL / !UL (!UL%)
PGFL:!UL / !UL (!UL%)PRC:!&@TQ:!UL / !UL (!UL%)
Input:!&@
Output:!&@
\n\
\n\ \

\n\ \n\ \n\
System Resources
\n\ \n\ \ \n\ \n\ \n\ \n\
GBLPAGESGBLSECTIONS
Temporary:!UL!UL
Permanent:!UL!UL
Total:!UL!UL
\n\
\n"; static char StatisticsFao [] = "\n\

\n\ \n\ \n\
Request Processing
\n\ \n\ \n\ \ \n\ \n\
\n\ \ \n\ \n\ \n\ \n\ \n\ \n\ \ \n\ \ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \
Connection
Total:!&L
Current:!&L
Peak:!&L
Busy:!&L
HTTP2  /Total:!&L(!UL%)
/Current:!&L(!UL%)
/Peak:!&L
Persistent  /Current:!&L
/Peak:!&L
IPv4:!&L(!UL%)
IPv6:!&L(!UL%)
SSL:!&L(!UL%)
Total  /Rx:!&,@SQ
/Tx:!&,@SQ
Error  /Rx:!&L
/Tx:!&L
\n\ \
\n\ \ \n\ \n\ \n\ \n\ \n\ \n\ \ \n\ \ \n\ \n\ \n\ \n\ \ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \ \n\ \
Request
Total:!&L
Current:!&L
Peak:!&L
Busy:!&L
HTTP2  /Total:!&L(!UL%)
/Current:!&L(!UL%)
/Peak:!&L
WebSocket  /Current:!&L
/Total:!&L
Raw  /Current:!&L(!UL%)
/Total:!&L(!UL%)
Throttle  /Queued:!&L
/Processing:!&L
/Busy:!UL%
Persistent  /Total:!&L
/Max:!&L
Pipeline  /Total:!&L
/Max:!&L!#AZ
\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\
HTTP
2:!&L(!UL%)
1.1:!&L(!UL%)
1.0:!&L(!UL%)
0.9:!&L(!UL%)
 
Method
CONNECT:!&L
COPY:!&L
DELETE:!&L
GET:!&L
HEAD:!&L
LOCK:!&L
MKCOL:!&L
MOVE:!&L
OPTIONS:!&L
POST:!&L
PROPFIND:!&L
PROPPATCH:!&L
PUT:!&L
TRACE:!&L
UNLOCK:!&L
Extension:!&L
(SSH):!&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\
\ Response Status
1nn:!&L  2nn:!&L  3nn:!&L  4nn:!&L  5nn:!&L
100:!&L200:!&L300:!&L400:!&L500:!&L
101:!&L201:!&L301:!&L401:!&L501:!&L
102:!&L202:!&L302:!&L402:!&L502:!&L
203:!&L303:!&L403:!&L503:!&L
204:!&L304:!&L404:!&L504:!&L
205:!&L305:!&L405:!&L505:!&L
206:!&L306:!&L406:!&L
207:!&L307:!&L407:!&L507:!&L
408:!&L
409:!&L410:!&L411:!&L
412:!&L413:!&L414:!&L
415:!&L416:!&L417:!&L
421:!&L422:!&L423:!&L
424:!&L
000:!&L???:!&L
\n\ \
 \n\ \ \n\ \n\ \n\ \n\ \n\ \n\ \ \n\ \ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\
\ *Duration
Min:!AZ
Max:!AZ
Ave:!AZ
Total:!AZ
 
\ *Bytes/Second
Min  /Bps:!&L
/Bytes:!&,@SQ
/Duration:!AZ
Max  /Bps:!&L
/Bytes:!&,@SQ
/Duration:!AZ
Ave  /Bps:!&L
/Bytes:!&L
/Duration:!AZ
\ *excludes WebSocket and
 \ Proxy-Tunnel requests
\n\ \
\n\
\n\
\n\ \

\n\ \n\ \n\
Processing Modules
\n\ \n\ \n\ \
\n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\
Admin:!&L
Cache  /Load:!&L
/Hit:!&L
/304:!&L
Directory:!&L
File  /All:!&L
/304:!&L
Put:!&L
Proxy:!&L
SSI:!&L
Update:!&L
WebDAV:!&L
WebSocket:!&L
none:!&L
\n\
\n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\
DCL
 As: !AZ
CGI:!&L
CGIplus  /All:!&L
/Reused:!&L
RTE  /All:!&L
/Reused:!&L
Autoscript:!&L
CLI:!&L
Proctor:!&L
WebSocket:!&L
$CREPRC:!&L
  $PERSONA!&?_MACRO\r\r  /All:!&L
/Default:!&L
/Invalid:!&L
/Privileged:!&L
$FORCEX:!&L
$DELPRC:!&L
\n\ \
\n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\
DECnet
 As: !AZ
Connect  /All:!&L
/Reused:!&L
CGI:!&L
OSU:!&L
\n\
\n\
\n"; static char GzipFao [] = "

\n\ \n\ \n\
Gzip Encoding!&?\r - DISABLED\r
\n\ \n\ \ \ \ \ \ \ \n\ \ \ \ \ \ \ \n\ \ \ \ \ \ \ \n\ \ \ \ \ \ \ \n\
CountOf TotalBytes InBytes OutRatio
Deflate:!&L!UL%!&,@SQ!&,@SQ!UL%
Inflate:!&L!UL%!&,@SQ!&,@SQ!UL%
Total Tx:!&L100%!&,@SQ!&,@SQ!UL%
\n\
\n"; static char LookupFao [] = "

\n\ \n\ \n\
Host Resolution
\n\ \n\ \ \ \ \ \ \n\ \ \ \ \ \ \ \n\ \ \ \ \ \ \ \n\ \ \ \ \ \ \ \n\
LiteralDNSCacheError
Address:!&L!&L
Address-to-name:!&L(!UL%)!&L!&L
Name-to-address:!&L(!UL%)!&L!&L
\n\
\n\ \

\n\ \n\ \n\
Other
\n\ \n\ \n\ \n\ \n\ \ \n\ \ \n\ \ \n\ \ \n\
Statistics Zeroed:!&L
Alignment Fault:!&L
Path Alert:!&L
NCS Conversion:!&L / !&L
StreamLF File Conversion:!&L
Errors Noticed:!&L!&@!&@!AZ
$HIBER spurious wake:!&L
\n\
\n\ \ \n\ \n\ \n"; static char SysPrvWarning[] = "SYSPRV"; static char PrivWarning[] = "WARNING"; static char PrivExpected[] = "as expected"; static char JpiPrcNam [16], JpiUserName [13], LastExitPid [13], LastExitStatus [16], LastExitTime [21]; static unsigned short SyiClusterNodes; static unsigned long JpiAstCnt, JpiBioCnt, JpiBytCnt, JpiCpuTime, JpiDioCnt, JpiEnqCnt, JpiFilCnt, JpiPageFlts, JpiPagFilCnt, JpiPid, JpiPrcCnt, JpiTqCnt, JpiVirtPeak, JpiWsSize, JpiWsPeak, Pid; static unsigned long CurrentTime64 [QUAD2], ImageUpTime [QUAD2], JpiAuthPriv [QUAD2], JpiCurPriv [QUAD2], JpiImagPriv [QUAD2], JpiLoginTime [QUAD2], ProcessUpTime [QUAD2]; static $DESCRIPTOR (LastExitPidDsc, LastExitPid); static $DESCRIPTOR (LastExitStatusDsc, LastExitStatus); static $DESCRIPTOR (LastExitPidFaoDsc, "!8XL\0"); static $DESCRIPTOR (LastExitStatusFaoDsc, "%X!XL\0"); static $DESCRIPTOR (LastExitTimeDsc, LastExitTime); static $DESCRIPTOR (LastExitTimeFaoDsc, "!20%D\0"); static VMS_ITEM_LIST3 JpiItems [] = { { sizeof(JpiAstCnt), JPI$_ASTCNT, &JpiAstCnt, 0 }, { sizeof(JpiAuthPriv), JPI$_AUTHPRIV, &JpiAuthPriv, 0 }, { sizeof(JpiBioCnt), JPI$_BIOCNT, &JpiBioCnt, 0 }, { sizeof(JpiBytCnt), JPI$_BYTCNT, &JpiBytCnt, 0 }, { sizeof(JpiCpuTime), JPI$_CPUTIM, &JpiCpuTime, 0 }, { sizeof(JpiCurPriv), JPI$_CURPRIV, &JpiCurPriv, 0 }, { sizeof(JpiDioCnt), JPI$_DIOCNT, &JpiDioCnt, 0 }, { sizeof(JpiEnqCnt), JPI$_ENQCNT, &JpiEnqCnt, 0 }, { sizeof(JpiFilCnt), JPI$_FILCNT, &JpiFilCnt, 0 }, { sizeof(JpiImagPriv), JPI$_IMAGPRIV, &JpiImagPriv, 0 }, { sizeof(JpiLoginTime), JPI$_LOGINTIM, &JpiLoginTime, 0 }, { sizeof(JpiPageFlts), JPI$_PAGEFLTS, &JpiPageFlts, 0 }, { sizeof(JpiPagFilCnt), JPI$_PAGFILCNT, &JpiPagFilCnt, 0 }, { sizeof(JpiPid), JPI$_PID, &JpiPid, 0 }, { sizeof(JpiPrcCnt), JPI$_PRCCNT, &JpiPrcCnt, 0 }, { sizeof(JpiPrcNam), JPI$_PRCNAM, &JpiPrcNam, 0 }, { sizeof(JpiTqCnt), JPI$_TQCNT, &JpiTqCnt, 0 }, { sizeof(JpiUserName), JPI$_USERNAME, &JpiUserName, 0 }, { sizeof(JpiVirtPeak), JPI$_VIRTPEAK, &JpiVirtPeak, 0 }, { sizeof(JpiWsSize), JPI$_WSSIZE, &JpiWsSize, 0 }, { sizeof(JpiWsPeak), JPI$_WSPEAK, &JpiWsPeak, 0 }, {0,0,0,0} }; static VMS_ITEM_LIST3 SyiItem [] = { { sizeof(SyiClusterNodes), SYI$_CLUSTER_NODES, &SyiClusterNodes, 0 }, { 0,0,0,0 } }; int cnt, idx, status, total, ConnectTotalCount, GzipDeflatePercent, GzipInflatePercent, MatchPercent, RequestHttpCount, StringTotal, TotalCount; unsigned int bit; unsigned long Remainder, Seconds, SubSeconds; unsigned long *vecptr; unsigned long FaoVector [180], ResponseDuration [QUAD2]; char *cptr, *sptr, *AuthPrivPtr, *CurPrivPtr, *ImagPrivPtr, *ClusterInstancePtr, *NodeInstancePtr, *SesolaVersionPtr; char EnvNumber [16]; IO_SB IOsb; ODS_STRUCT WasdRootOds; /*********/ /* begin */ /*********/ if (WATCHMOD (rqptr, WATCH_MOD__OTHER)) WatchThis (WATCHITM(rqptr), WATCH_MOD__OTHER, "AdminReportServerStats() !&A", NextTaskFunction); SesolaVersionPtr = SesolaVersion (false); status = sys$getjpiw (EfnWait, &Pid, 0, &JpiItems, &IOsb, 0, 0); if (VMSok (status)) status = IOsb.Status; if (VMSnok (status)) { rqptr->rqResponse.ErrorTextPtr = "sys$getjpiw()"; ErrorVmsStatus (rqptr, status, FI_LI); SysDclAst (NextTaskFunction, rqptr); return; } status = sys$getsyiw (EfnWait, 0, 0, &SyiItem, &IOsb, 0, 0); if (VMSok (status)) status = IOsb.Status; if (VMSnok (status)) { rqptr->rqResponse.ErrorTextPtr = "sys$getsyiw()"; ErrorVmsStatus (rqptr, status, FI_LI); SysDclAst (NextTaskFunction, rqptr); return; } InstanceLockList (INSTANCE_NODE_SUPERVISOR, "
", &NodeInstancePtr); InstanceLockList (INSTANCE_CLUSTER, "
", &ClusterInstancePtr); JpiUserName[12] = '\0'; for (cptr = JpiUserName; *cptr && *cptr != ' '; cptr++); *cptr = '\0'; JpiPrcNam[15] = '\0'; for (cptr = JpiPrcNam; *cptr && *cptr != ' '; cptr++); *cptr = '\0'; sys$gettim (&CurrentTime64); lib$sub_times (&CurrentTime64, &HttpdStartTime64, &ImageUpTime); lib$sub_times (&CurrentTime64, &JpiLoginTime, &ProcessUpTime); if ((JpiAuthPriv[0] & ~(PRV$M_NETMBX | PRV$M_TMPMBX)) || JpiAuthPriv[1]) AuthPrivPtr = PrivWarning; else AuthPrivPtr = PrivExpected; if ((JpiImagPriv[0] & IMAG_PRIV_0_ALLOWED) || (JpiImagPriv[1] & IMAG_PRIV_1_ALLOWED)) ImagPrivPtr = PrivWarning; else ImagPrivPtr = PrivExpected; if (OperateWithSysPrv) { if ((JpiCurPriv[0] & ~(PRV$M_NETMBX | PRV$M_TMPMBX | PRV$M_SYSPRV)) || JpiCurPriv[1]) CurPrivPtr = PrivWarning; else CurPrivPtr = SysPrvWarning; } else if ((JpiCurPriv[0] & ~(PRV$M_NETMBX | PRV$M_TMPMBX)) || JpiCurPriv[1]) CurPrivPtr = PrivWarning; else CurPrivPtr = PrivExpected; AdminPageTitle (rqptr, "Server Statistics"); InstanceMutexLock (INSTANCE_MUTEX_HTTPD); ConnectTotalCount = acptr->ConnectCount[HTTP12]; if (acptr->LastExitStatus) sys$fao (&LastExitStatusFaoDsc, 0, &LastExitStatusDsc, acptr->LastExitStatus); else strcpy (LastExitStatus, "(none)"); if (QUAD_NOT_ZERO (acptr->LastExitTime64)) sys$fao (&LastExitTimeFaoDsc, 0, &LastExitTimeDsc, &acptr->LastExitTime64); else strcpy (LastExitTime, "(none)"); if (acptr->LastExitPid) sys$fao (&LastExitPidFaoDsc, 0, &LastExitPidDsc, acptr->LastExitPid); else strcpy (LastExitPid, "(none)"); /***************/ /* environment */ /***************/ vecptr = FaoVector; if (InstanceEnvNumber > 1) sprintf (*vecptr++ = EnvNumber, " %d", InstanceEnvNumber); else *vecptr++ = ""; *vecptr++ = SoftwareID; *vecptr++ = BuildInfo; if (SesolaVersionPtr[0]) *vecptr++ = SesolaVersionPtr; else *vecptr++ = "(none)"; if (Config.cfMisc.GzipResponseCompLevel) { *vecptr++ = "ZLIB:!&@\n"; if (VMSok(GzipFindImageStatus)) { *vecptr++ = "!AZ V!AZ"; *vecptr++ = GzipZlibNamePtr; *vecptr++ = GzipZlibVersionPtr; } else if (GzipFindImageStatus == RMS$_FNF) *vecptr++ = "%HTTPD-W-GZIP, shareable image not found"; else { *vecptr++ = "!AZ %!&M"; *vecptr++ = GzipZlibNamePtr; *vecptr++ = GzipFindImageStatus; } } else *vecptr++ = ""; *vecptr++ = TcpIpAgentInfo; *vecptr++ = SysInfo.HwName; *vecptr++ = SysInfo.AvailCpuCnt; *vecptr++ = SysInfo.MemoryMB; *vecptr++ = SysInfo.Version; *vecptr++ = CommandLine; cptr = v10orPrev10(CONFIG_WASD_ROOT,-1); OdsParse (&WasdRootOds, cptr, strlen(cptr), NULL, 0, NAM$M_NOCONCEAL | NAM$M_SYNCHK, 0, 0); sptr = strstr (WasdRootOds.ExpFileName, ".][000000]"); if (sptr) SET2(sptr,']\0'); *vecptr++ = strchr(cptr,':') - cptr; *vecptr++ = cptr; *vecptr++ = WasdRootOds.ExpFileName; /*************/ /* instances */ /*************/ *vecptr++ = NodeInstancePtr; if (SyiClusterNodes > 1) *vecptr++ = ClusterInstancePtr; else *vecptr++ = "(n/a)"; if (HttpdGblSecPtr->InstancePassive) *vecptr++ = "Node instances are currently PASSIVE."; else *vecptr++ = "Node instances are currently ACTIVE."; /***********/ /* process */ /***********/ *vecptr++ = (InstanceNodeCurrent <= 1); *vecptr++ = JpiPrcNam; *vecptr++ = ADMIN_REPORT_SHOW_PROCESS; *vecptr++ = JpiPid; if (DclPersonaServicesAvailable || HttpdScriptAsUserName[0]) { *vecptr++ = "&puser=!AZ"; *vecptr++ = (unsigned long)JpiUserName; } else *vecptr++ = ""; *vecptr++ = JpiPid; *vecptr++ = (unsigned long)JpiUserName; *vecptr++ = AuthPrivPtr; *vecptr++ = ImagPrivPtr; *vecptr++ = CurPrivPtr; *vecptr++ = LastExitStatus; *vecptr++ = LastExitTime; *vecptr++ = LastExitPid; *vecptr++ = &ImageUpTime; *vecptr++ = &ProcessUpTime; *vecptr++ = JpiCpuTime / 8640000; /* CPU day */ *vecptr++ = (JpiCpuTime % 8640000) / 360000; /* CPU hour */ *vecptr++ = (JpiCpuTime % 360000) / 6000; /* CPU minute */ *vecptr++ = (JpiCpuTime % 6000 ) / 100; /* CPU second */ *vecptr++ = JpiCpuTime % 100; /* CPU 10 milliseconds */ *vecptr++ = JpiPageFlts; *vecptr++ = acptr->StartupCount; *vecptr++ = HttpdProcess.ModeName; *vecptr++ = JpiWsSize; *vecptr++ = JpiWsPeak; *vecptr++ = JpiVirtPeak; *vecptr++ = JpiAstCnt; *vecptr++ = HttpdProcess.AstLm; *vecptr++ = 100 - PercentOf(JpiAstCnt,HttpdProcess.AstLm); *vecptr++ = JpiBioCnt; *vecptr++ = HttpdProcess.BioLm; *vecptr++ = 100 - PercentOf(JpiBioCnt,HttpdProcess.BioLm); *vecptr++ = JpiBytCnt; *vecptr++ = HttpdProcess.BytLm; *vecptr++ = 100 - PercentOf(JpiBytCnt,HttpdProcess.BytLm); *vecptr++ = JpiDioCnt; *vecptr++ = HttpdProcess.DioLm; *vecptr++ = 100 - PercentOf(JpiDioCnt,HttpdProcess.DioLm); *vecptr++ = JpiEnqCnt; *vecptr++ = HttpdProcess.EnqLm; *vecptr++ = 100 - PercentOf(JpiEnqCnt,HttpdProcess.EnqLm); *vecptr++ = JpiFilCnt; *vecptr++ = HttpdProcess.FilLm; *vecptr++ = 100 - PercentOf(JpiFilCnt,HttpdProcess.FilLm); *vecptr++ = JpiPagFilCnt; *vecptr++ = HttpdProcess.PgFlQuo; *vecptr++ = 100 - PercentOf(JpiPagFilCnt,HttpdProcess.PgFlQuo); if (DclScriptDetachProcess) *vecptr++ = "(detached)"; else { *vecptr++ = "!&L / !&L (!UL%)"; *vecptr++ = HttpdProcess.PrcLm - JpiPrcCnt; *vecptr++ = HttpdProcess.PrcLm; *vecptr++ = 100 - PercentOf(HttpdProcess.PrcLm-JpiPrcCnt, HttpdProcess.PrcLm); } *vecptr++ = JpiTqCnt; *vecptr++ = HttpdProcess.TqLm; *vecptr++ = 100 - PercentOf(JpiTqCnt,HttpdProcess.TqLm); if (HttpdProcess.SysInputFile) { *vecptr++ = "!AZ"; *vecptr++ = ADMIN_REPORT_PROCESS_INPUT; } *vecptr++ = HttpdProcess.SysInput; if (HttpdProcess.SysOutputFile) { *vecptr++ = "!AZ"; *vecptr++ = ADMIN_REPORT_PROCESS_OUTPUT; } *vecptr++ = HttpdProcess.SysOutput; InstanceMutexUnLock (INSTANCE_MUTEX_HTTPD); *vecptr++ = GblPageCount; *vecptr++ = GblSectionCount; *vecptr++ = GblPagePermCount; *vecptr++ = GblSectionPermCount; *vecptr++ = GblPageCount + GblPagePermCount; *vecptr++ = GblSectionCount + GblSectionPermCount; FaoCheck (sizeof(FaoVector), &FaoVector, vecptr, FI_LI); status = FaolToNet (rqptr, BeginPageFao, &FaoVector); if (VMSnok (status)) ErrorNoticed (rqptr, status, NULL, FI_LI); /************/ /* services */ /************/ NetServiceReportStats (rqptr); /**************/ /* statistics */ /**************/ InstanceMutexLock (INSTANCE_MUTEX_HTTPD); vecptr = FaoVector; /* connections */ *vecptr++ = acptr->ConnectCount[HTTP12]; *vecptr++ = acptr->CurrentConnected[HTTP12]; *vecptr++ = acptr->ConnectPeak[HTTP12]; *vecptr++ = acptr->ConnectTooBusyCount; *vecptr++ = acptr->ConnectCount[HTTP2]; *vecptr++ = PercentOf(acptr->ConnectCount[HTTP2], acptr->ConnectCount[HTTP12]); *vecptr++ = acptr->CurrentConnected[HTTP2]; *vecptr++ = PercentOf(acptr->CurrentConnected[HTTP2], acptr->CurrentConnected[HTTP12]); *vecptr++ = acptr->ConnectPeak[HTTP2]; *vecptr++ = acptr->CurrentHttp1Persistent; *vecptr++ = acptr->ConnectPeakPersistent; *vecptr++ = acptr->ConnectIpv4Count; *vecptr++ = PercentOf(acptr->ConnectIpv4Count, acptr->ConnectCount[HTTP12]); *vecptr++ = acptr->ConnectIpv6Count; *vecptr++ = PercentOf(acptr->ConnectIpv6Count, acptr->ConnectCount[HTTP12]); *vecptr++ = acptr->ConnectSslCount; *vecptr++ = PercentOf(acptr->ConnectSslCount, acptr->ConnectCount[HTTP12]); *vecptr++ = &acptr->BytesRawRx; *vecptr++ = &acptr->BytesRawTx; *vecptr++ = acptr->NetReadErrorCount; *vecptr++ = acptr->NetWriteErrorCount; /* requests */ *vecptr++ = acptr->ProcessingTotalCount[HTTP12]; *vecptr++ = acptr->CurrentProcessing[HTTP12]; *vecptr++ = acptr->ProcessingPeak[HTTP12]; *vecptr++ = acptr->ProcessingTooBusyCount; *vecptr++ = acptr->ProcessingTotalCount[HTTP2]; *vecptr++ = PercentOf(acptr->ProcessingTotalCount[HTTP2], acptr->ProcessingTotalCount[HTTP12]); *vecptr++ = acptr->CurrentProcessing[HTTP2]; *vecptr++ = PercentOf(acptr->CurrentProcessing[HTTP2], acptr->CurrentProcessing[HTTP12]); *vecptr++ = acptr->ProcessingPeak[HTTP2]; for (total = cnt = 0; cnt <= InstanceNodeCurrent; cnt++) total += acptr->CurrentWebSockets[cnt]; *vecptr++ = total; StringTotal = total; *vecptr++ = acptr->WebSocketCount; for (total = cnt = 0; cnt <= InstanceNodeCurrent; cnt++) total += acptr->CurrentWebSocketsRaw[cnt]; *vecptr++ = total; *vecptr++ = PercentOf(StringTotal,total); *vecptr++ = acptr->WebSocketRawCount; *vecptr++ = PercentOf(acptr->WebSocketCount,acptr->WebSocketRawCount); for (total = cnt = 0; cnt <= InstanceNodeCurrent; cnt++) total += acptr->CurrentThrottleQueued[cnt]; *vecptr++ = total; for (total = cnt = 0; cnt <= InstanceNodeCurrent; cnt++) total += acptr->CurrentThrottleProcessing[cnt]; *vecptr++ = total; *vecptr++ = acptr->ThrottleBusyMetric; *vecptr++ = acptr->RequestPersistentCount; *vecptr++ = acptr->RequestPersistentMax; *vecptr++ = acptr->PipelineRequestCount; *vecptr++ = acptr->PipelineRequestMax; #ifndef __VAX /* force it to the left because of the following 'duration' width */ if (ConnectTotalCount < 10) *vecptr++ = 36; else if (ConnectTotalCount < 100) *vecptr++ = 30; else if (ConnectTotalCount < 1000) *vecptr++ = 24; else if (ConnectTotalCount < 10000) *vecptr++ = 18; else if (ConnectTotalCount < 100000) *vecptr++ = 12; else if (ConnectTotalCount < 1000000) *vecptr++ = 6; else #endif /* __VAX */ *vecptr++ = 0; *vecptr++ = "      "; /* HTTP versions */ RequestHttpCount = acptr->RequestHttp2Count + acptr->RequestHttp11Count + acptr->RequestHttp10Count + acptr->RequestHttp09Count; *vecptr++ = acptr->RequestHttp2Count; *vecptr++ = PercentOf (acptr->RequestHttp2Count, RequestHttpCount); *vecptr++ = acptr->RequestHttp11Count; *vecptr++ = PercentOf (acptr->RequestHttp11Count, RequestHttpCount); *vecptr++ = acptr->RequestHttp10Count; *vecptr++ = PercentOf (acptr->RequestHttp10Count, RequestHttpCount); *vecptr++ = acptr->RequestHttp09Count; *vecptr++ = PercentOf (acptr->RequestHttp09Count, RequestHttpCount); /* HTTP methods */ *vecptr++ = acptr->MethodConnectCount; *vecptr++ = acptr->MethodWebDavCopyCount; *vecptr++ = acptr->MethodDeleteCount; *vecptr++ = acptr->MethodGetCount; *vecptr++ = acptr->MethodHeadCount; *vecptr++ = acptr->MethodWebDavLockCount; *vecptr++ = acptr->MethodWebDavMkColCount; *vecptr++ = acptr->MethodWebDavMoveCount; *vecptr++ = acptr->MethodOptionsCount; *vecptr++ = acptr->MethodPostCount; *vecptr++ = acptr->MethodWebDavPropFindCount; *vecptr++ = acptr->MethodWebDavPropPatchCount; *vecptr++ = acptr->MethodPutCount; *vecptr++ = acptr->MethodTraceCount; *vecptr++ = acptr->MethodWebDavUnLockCount; *vecptr++ = acptr->MethodExtensionCount; *vecptr++ = acptr->MethodSshCount; /* responses */ *vecptr++ = acptr->ResponseStatusCodeGroup[1]; *vecptr++ = acptr->ResponseStatusCodeGroup[2]; *vecptr++ = acptr->ResponseStatusCodeGroup[3]; *vecptr++ = acptr->ResponseStatusCodeGroup[4]; *vecptr++ = acptr->ResponseStatusCodeGroup[5]; /* see ResponseHttpStatusCode() for making sense of this array */ #define RHSI(n) RequestHttpStatusIndex(n) *vecptr++ = acptr->ResponseStatusCodeCount[RHSI(100)]; *vecptr++ = acptr->ResponseStatusCodeCount[RHSI(200)]; *vecptr++ = acptr->ResponseStatusCodeCount[RHSI(300)]; *vecptr++ = acptr->ResponseStatusCodeCount[RHSI(400)]; *vecptr++ = acptr->ResponseStatusCodeCount[RHSI(500)]; *vecptr++ = acptr->ResponseStatusCodeCount[RHSI(101)]; *vecptr++ = acptr->ResponseStatusCodeCount[RHSI(201)]; *vecptr++ = acptr->ResponseStatusCodeCount[RHSI(301)]; *vecptr++ = acptr->ResponseStatusCodeCount[RHSI(401)]; *vecptr++ = acptr->ResponseStatusCodeCount[RHSI(501)]; *vecptr++ = acptr->ResponseStatusCodeCount[RHSI(102)]; *vecptr++ = acptr->ResponseStatusCodeCount[RHSI(202)]; *vecptr++ = acptr->ResponseStatusCodeCount[RHSI(302)]; *vecptr++ = acptr->ResponseStatusCodeCount[RHSI(402)]; *vecptr++ = acptr->ResponseStatusCodeCount[RHSI(502)]; *vecptr++ = acptr->ResponseStatusCodeCount[RHSI(203)]; *vecptr++ = acptr->ResponseStatusCodeCount[RHSI(303)]; *vecptr++ = acptr->ResponseStatusCodeCount[RHSI(403)]; *vecptr++ = acptr->ResponseStatusCodeCount[RHSI(503)]; *vecptr++ = acptr->ResponseStatusCodeCount[RHSI(204)]; *vecptr++ = acptr->ResponseStatusCodeCount[RHSI(304)]; *vecptr++ = acptr->ResponseStatusCodeCount[RHSI(404)]; *vecptr++ = acptr->ResponseStatusCodeCount[RHSI(504)]; *vecptr++ = acptr->ResponseStatusCodeCount[RHSI(205)]; *vecptr++ = acptr->ResponseStatusCodeCount[RHSI(305)]; *vecptr++ = acptr->ResponseStatusCodeCount[RHSI(405)]; *vecptr++ = acptr->ResponseStatusCodeCount[RHSI(505)]; *vecptr++ = acptr->ResponseStatusCodeCount[RHSI(206)]; *vecptr++ = acptr->ResponseStatusCodeCount[RHSI(306)]; *vecptr++ = acptr->ResponseStatusCodeCount[RHSI(406)]; *vecptr++ = acptr->ResponseStatusCodeCount[RHSI(207)]; *vecptr++ = acptr->ResponseStatusCodeCount[RHSI(307)]; *vecptr++ = acptr->ResponseStatusCodeCount[RHSI(407)]; *vecptr++ = acptr->ResponseStatusCodeCount[RHSI(507)]; *vecptr++ = acptr->ResponseStatusCodeCount[RHSI(408)]; *vecptr++ = acptr->ResponseStatusCodeCount[RHSI(409)]; *vecptr++ = acptr->ResponseStatusCodeCount[RHSI(410)]; *vecptr++ = acptr->ResponseStatusCodeCount[RHSI(411)]; *vecptr++ = acptr->ResponseStatusCodeCount[RHSI(412)]; *vecptr++ = acptr->ResponseStatusCodeCount[RHSI(413)]; *vecptr++ = acptr->ResponseStatusCodeCount[RHSI(414)]; *vecptr++ = acptr->ResponseStatusCodeCount[RHSI(415)]; *vecptr++ = acptr->ResponseStatusCodeCount[RHSI(416)]; *vecptr++ = acptr->ResponseStatusCodeCount[RHSI(417)]; *vecptr++ = acptr->ResponseStatusCodeCount[RHSI(421)]; *vecptr++ = acptr->ResponseStatusCodeCount[RHSI(422)]; *vecptr++ = acptr->ResponseStatusCodeCount[RHSI(423)]; *vecptr++ = acptr->ResponseStatusCodeCount[RHSI(424)]; *vecptr++ = acptr->ResponseStatusCodeGroup[0]; /* 000 */ *vecptr++ = acptr->ResponseStatusCodeCount[0]; /* ??? */ #undef RHSI /* response duration */ *vecptr++ = DurationString (rqptr, &acptr->ResponseDurationMin[HTTP12]); *vecptr++ = DurationString (rqptr, &acptr->ResponseDurationMax[HTTP12]); *vecptr++ = AverageDurationString (rqptr, &acptr->ResponseDuration[HTTP12], acptr->ResponseDurationCount[HTTP12]); *vecptr++ = DurationString (rqptr, &acptr->ResponseDuration[HTTP12]); /* bytes per second */ *vecptr++ = acptr->BytesPerSecondMin[HTTP12]; *vecptr++ = &acptr->BytesPerSecondMinBytes[HTTP12]; *vecptr++ = DurationString (rqptr, &acptr->BytesPerSecondMinDuration[HTTP12]); *vecptr++ = acptr->BytesPerSecondMax[HTTP12]; *vecptr++ = &acptr->BytesPerSecondMaxBytes[HTTP12]; *vecptr++ = DurationString (rqptr, &acptr->BytesPerSecondMaxDuration[HTTP12]); *vecptr++ = acptr->BytesPerSecondAve[HTTP12]; *vecptr++ = (ulong)(FLOAT_FROM_QUAD(acptr->BytesPerSecondRawTotal[HTTP12]) / (float)(acptr->RequestHttp2Count + acptr->RequestHttp11Count + acptr->RequestHttp10Count)); *vecptr++ = DurationString (rqptr, &acptr->ResponseDuration[HTTP12]); /* modules */ *vecptr++ = acptr->DoServerAdminCount; *vecptr++ = acptr->CacheLoadCount; *vecptr++ = acptr->CacheHitCount; *vecptr++ = acptr->CacheHitNotModifiedCount; *vecptr++ = acptr->DoDirectoryCount; *vecptr++ = acptr->DoFileCount; *vecptr++ = acptr->DoFileNotModifiedCount; *vecptr++ = acptr->DoPutCount; *vecptr++ = acptr->DoProxyCount; *vecptr++ = acptr->DoSsiCount; *vecptr++ = acptr->DoUpdateCount; *vecptr++ = acptr->DoWebDavCount; *vecptr++ = acptr->DoWebSockCount; *vecptr++ = acptr->DoNoModuleCount; if (HttpdScriptAsUserName[0]) *vecptr++ = HttpdScriptAsUserName; else *vecptr++ = HttpdProcess.UserName; *vecptr++ = acptr->DoScriptCount; *vecptr++ = acptr->DoCgiPlusScriptCount; *vecptr++ = acptr->DclCgiPlusReusedCount; *vecptr++ = acptr->DoRteScriptCount; *vecptr++ = acptr->DclRteReusedCount; *vecptr++ = acptr->DoAutoScriptCount; *vecptr++ = acptr->DoDclCommandCount; *vecptr++ = acptr->DclProctorCount; *vecptr++ = acptr->DclWebSocketCount; *vecptr++ = acptr->DclCrePrcCount; *vecptr++ = PersonaMacro; *vecptr++ = acptr->DclCrePrcPersonaCount; *vecptr++ = acptr->DclCrePrcPersonaDefaultCount; *vecptr++ = acptr->DclCrePrcPersonaInvUserCount; *vecptr++ = acptr->DclCrePrcPersonaPrvUserCount; *vecptr++ = acptr->DclForceXCount; *vecptr++ = acptr->DclDelPrcCount; if (HttpdScriptAsUserName[0]) *vecptr++ = HttpdScriptAsUserName; else *vecptr++ = HttpdProcess.UserName; *vecptr++ = acptr->DoDECnetCount; *vecptr++ = acptr->DoDECnetCount - acptr->DoDECnetCgiCount - acptr->DoDECnetOsuCount; *vecptr++ = acptr->DoDECnetCgiCount; *vecptr++ = acptr->DoDECnetOsuCount; InstanceMutexUnLock (INSTANCE_MUTEX_HTTPD); FaoCheck (sizeof(FaoVector), &FaoVector, vecptr, FI_LI); status = FaolToNet (rqptr, StatisticsFao, &FaoVector); if (VMSnok (status)) ErrorNoticed (rqptr, status, NULL, FI_LI); InstanceMutexLock (INSTANCE_MUTEX_HTTPD); if (Config.cfMisc.GzipResponseCompLevel) { /* GZIP compression (if enabled) */ unsigned long ResponseBytes [QUAD2]; vecptr = FaoVector; *vecptr++ = GzipAvailable; *vecptr++ = acptr->GzipDeflateCount; *vecptr++ = PercentOf (acptr->GzipDeflateCount, acptr->ProcessingTotalCount[HTTP12]); *vecptr++ = &acptr->GzipDeflateBytesIn; *vecptr++ = &acptr->GzipDeflateBytesOut; *vecptr++ = QuadPercentOf (&acptr->GzipDeflateBytesOut, &acptr->GzipDeflateBytesIn); *vecptr++ = acptr->GzipInflateCount; *vecptr++ = PercentOf (acptr->GzipInflateCount, acptr->ProcessingTotalCount[HTTP12]); *vecptr++ = &acptr->GzipInflateBytesIn; *vecptr++ = &acptr->GzipInflateBytesOut; *vecptr++ = QuadPercentOf (&acptr->GzipInflateBytesIn, &acptr->GzipInflateBytesOut); PLUS_QUAD_QUAD (acptr->GzipDeflateBytesIn, acptr->BytesRawTx, ResponseBytes); SUB_QUAD_QUAD (acptr->GzipDeflateBytesOut, ResponseBytes); *vecptr++ = acptr->ProcessingTotalCount[HTTP12]; *vecptr++ = &ResponseBytes; *vecptr++ = &acptr->BytesRawTx; *vecptr++ = QuadPercentOf (&acptr->BytesRawTx, &ResponseBytes); FaoCheck (sizeof(FaoVector), &FaoVector, vecptr, FI_LI); status = FaolToNet (rqptr, GzipFao, &FaoVector); if (VMSnok (status)) ErrorNoticed (rqptr, status, NULL, FI_LI); } /* lookup and other */ vecptr = FaoVector; *vecptr++ = acptr->LookupLiteralCount; *vecptr++ = acptr->LookupLiteralErrorCount; *vecptr++ = acptr->LookupDnsAddressCount; *vecptr++ = PercentOf (acptr->LookupDnsAddressCount, acptr->LookupDnsAddressCount + acptr->LookupCacheAddressCount); *vecptr++ = acptr->LookupCacheAddressCount; *vecptr++ = acptr->LookupDnsAddressErrorCount; *vecptr++ = acptr->LookupDnsNameCount; *vecptr++ = PercentOf (acptr->LookupDnsNameCount, acptr->LookupDnsNameCount + acptr->LookupCacheNameCount); *vecptr++ = acptr->LookupCacheNameCount; *vecptr++ = acptr->LookupDnsNameErrorCount; *vecptr++ = acptr->ZeroedCount; *vecptr++ = HttpdAlignFaultCount; *vecptr++ = acptr->PathAlertCount; *vecptr++ = acptr->NcsCount; *vecptr++ = acptr->NcsConvertCount; *vecptr++ = acptr->StreamLfConversionCount; *vecptr++ = acptr->ErrorsNoticedCount; if (acptr->ErrorsNoticedCount) { *vecptr++ = "(!20%D"; *vecptr++ = &acptr->ErrorsNoticedTime64; if (HttpdProcess.SysOutputFile) { *vecptr++ = ", see Log"; *vecptr++ = ADMIN_REPORT_PROCESS_OUTPUT; } else *vecptr++ = ""; *vecptr++ = ")"; } else { *vecptr++ = ""; *vecptr++ = ""; *vecptr++ = ""; } *vecptr++ = acptr->SpuriousWakeCount; InstanceMutexUnLock (INSTANCE_MUTEX_HTTPD); FaoCheck (sizeof(FaoVector), &FaoVector, vecptr, FI_LI); status = FaolToNet (rqptr, LookupFao, &FaoVector); if (VMSnok (status)) ErrorNoticed (rqptr, status, NULL, FI_LI); VmFree (NodeInstancePtr, FI_LI); VmFree (ClusterInstancePtr, FI_LI); rqptr->rqResponse.PreExpired = PRE_EXPIRE_ADMIN; ResponseHeader200 (rqptr, "text/html", &rqptr->NetWriteBufferDsc); SysDclAst (NextTaskFunction, rqptr); } /*****************************************************************************/ /* Get the file module to output the server process log. */ AdminServerProcessInput ( REQUEST_STRUCT *rqptr, REQUEST_AST NextTaskFunction ) { int status; /*********/ /* begin */ /*********/ if (WATCHMOD (rqptr, WATCH_MOD__OTHER)) WatchThis (WATCHITM(rqptr), WATCH_MOD__OTHER, "AdminServerProcessInput()"); if (!HttpdProcess.SysInputFile) { rqptr->rqResponse.HttpStatus = 500; ErrorGeneral (rqptr, HttpdProcess.SysInput, FI_LI); SysDclAst (NextTaskFunction, rqptr); return; } rqptr->rqResponse.PreExpired = PRE_EXPIRE_ADMIN; ResponseHeader200 (rqptr, "text/plain", NULL); FileSetCacheAllowed (rqptr, false); FileSetAuthorizePath (rqptr, false); FileBegin (rqptr, NextTaskFunction, NULL, NULL, HttpdProcess.SysInput, "text/plain"); } /*****************************************************************************/ /* Get the file module to output the server process log. */ AdminServerProcessOutput ( REQUEST_STRUCT *rqptr, REQUEST_AST NextTaskFunction ) { /*********/ /* begin */ /*********/ if (WATCHMOD (rqptr, WATCH_MOD__OTHER)) WatchThis (WATCHITM(rqptr), WATCH_MOD__OTHER, "AdminServerProcessOutput()"); if (!HttpdProcess.SysOutputFile) { rqptr->rqResponse.HttpStatus = 500; ErrorGeneral (rqptr, HttpdProcess.SysOutput, FI_LI); SysDclAst (NextTaskFunction, rqptr); return; } rqptr->rqResponse.PreExpired = PRE_EXPIRE_ADMIN; ResponseHeader200 (rqptr, "text/plain", NULL); FileSetCacheAllowed (rqptr, false); FileSetAuthorizePath (rqptr, false); FileBegin (rqptr, NextTaskFunction, NULL, NULL, HttpdProcess.SysOutput, "text/plain"); } /*****************************************************************************/ /* Provide administration menu/report page titles. Will accept a small number of variable arguments to provide text following the titles themselves. */ int AdminPageTitle ( REQUEST_STRUCT *rqptr, char *Title, ... ) { static char PageTitleFao [] = "!AZ\ \n\ \n\ !AZ\ !AZ\ !&@\ WASD !AZ ... !AZ\n\ \n\ !AZ\n\

\n\

WASD !AZ

\n\

!AZ!&@

\n\ !20&W\n\ !&@"; int argcnt, status; unsigned long *vecptr; unsigned long FaoVector [32+16]; va_list argptr; /*********/ /* begin */ /*********/ va_count (argcnt); if (WATCHMOD (rqptr, WATCH_MOD__OTHER)) WatchThis (WATCHITM(rqptr), WATCH_MOD__OTHER, "AdminPageTitle() !UL !&Z", argcnt, Title); if (argcnt > 32+4) { ErrorNoticed (rqptr, SS$_OVRMAXARG, NULL, FI_LI); return (SS$_OVRMAXARG); } vecptr = FaoVector; *vecptr++ = WASD_DOCTYPE; *vecptr++ = HtmlMetaInfo (rqptr, NULL); *vecptr++ = AdminWasdCss (); if (rqptr->rqPathSet.StyleSheetPtr) { *vecptr++ = "\n"; *vecptr++ = rqptr->rqPathSet.StyleSheetPtr; } else *vecptr++ = ""; *vecptr++ = ServerHostPort; *vecptr++ = Title; *vecptr++ = Config.cfServer.AdminBodyTag; *vecptr++ = ServerHostPort; *vecptr++ = Title; if (InstanceNodeCurrent > 1) { if (rqptr->ServicePtr->AdminService) *vecptr++ = "  -  !AZ"; else *vecptr++ = "    (!AZ)"; *vecptr++ = HttpdProcess.PrcNam; } else *vecptr++ = ""; *vecptr++ = &rqptr->rqTime.BeginTime64; if (argcnt > 2) { va_start (argptr, Title); for (argcnt -= 2; argcnt; argcnt--) *vecptr++ = va_arg (argptr, unsigned long); va_end (argptr); } else *vecptr++ = ""; FaoCheck (sizeof(FaoVector), &FaoVector, vecptr, FI_LI); status = FaolToNet (rqptr, PageTitleFao, &FaoVector); if (VMSnok (status)) ErrorNoticed (rqptr, status, NULL, FI_LI); return (status); } /*****************************************************************************/ /* Provide a list of problems reported during a meta-config load in standard admininistration menu/report format. */ AdminMetaConReport ( REQUEST_STRUCT *rqptr, META_CONFIG *mcptr, META_CONFIG *MetaConStartupPtr ) { static char ReportFao [] = "

\n\ \n\ \n\
\   !UL Informational,  !UL Warning,  \ !&?\r\r!-!UL Error!%s !-!&?\r\r \\ !&?At Startup\rDuring Load\r  
!AZ
\n"; int status; unsigned long *vecptr; unsigned long FaoVector [16]; /*********/ /* begin */ /*********/ if (WATCHMOD (rqptr, WATCH_MOD__OTHER)) WatchThis (WATCHITM(rqptr), WATCH_MOD__OTHER, "AdminMetaConReport()"); if (!mcptr->LoadReport.ItemCount) return; vecptr = FaoVector; *vecptr++ = mcptr->LoadReport.InformCount; *vecptr++ = mcptr->LoadReport.WarningCount; *vecptr++ = mcptr->LoadReport.ErrorCount; *vecptr++ = (mcptr == MetaConStartupPtr); *vecptr++ = mcptr->LoadReport.TextPtr; FaoCheck (sizeof(FaoVector), &FaoVector, vecptr, FI_LI); status = FaolToNet (rqptr, ReportFao, &FaoVector); if (VMSnok (status)) ErrorNoticed (rqptr, status, NULL, FI_LI); } /*****************************************************************************/ /* Provide a description of the source of this configuration in an administration standard menu/report format. */ AdminMetaConSource ( REQUEST_STRUCT *rqptr, META_CONFIG *mcptr, META_CONFIG *MetaConStartupPtr ) { static char SourceFao [] = "

\n\ \n\ \n\
Source: "!&?Server\rFile\r"
\n\ \n\ !&@\n\ \n\ !&@\
File:!AZ
!AZ!20&W
\n\
\n"; int status; unsigned long *vecptr; unsigned long FaoVector [16]; char *cptr; /*********/ /* begin */ /*********/ if (WATCHMOD (rqptr, WATCH_MOD__OTHER)) WatchThis (WATCHITM(rqptr), WATCH_MOD__OTHER, "AdminMetaConSource()"); vecptr = FaoVector; *vecptr++ = (mcptr == MetaConStartupPtr); *vecptr++ = mcptr->LoadReport.FileName; if (mcptr->LnmCount > 1) *vecptr++ = "(search list)"; else { *vecptr++ = "\ View\ Edit"; *vecptr++ = cptr = rqptr->rqHeader.PathInfoPtr; *vecptr++ = cptr; } if (mcptr == MetaConStartupPtr) { *vecptr++ = "Loaded:"; *vecptr++ = &mcptr->LoadReport.LoadTime64; } else { *vecptr++ = "Revised:"; *vecptr++ = &mcptr->LoadReport.FileTime64; } if (mcptr->IncludeFile) *vecptr++ = "\ Configuration derived from multiple files (e.g. [IncludeFile])

\ CAUTION: Using this interface will overwrite that!!\ \n"; else *vecptr++ = ""; FaoCheck (sizeof(FaoVector), &FaoVector, vecptr, FI_LI); status = FaolToNet (rqptr, SourceFao, &FaoVector); if (VMSnok (status)) ErrorNoticed (rqptr, status, NULL, FI_LI); } /*****************************************************************************/ /* For administration menu configuration update pages provide the element and some leading, commented-out descriptive text for the configuration file. */ AdminMetaConBeginUpdateForm (REQUEST_STRUCT *rqptr) { static char BeginFormFao [] = "

\n\ "; int status; unsigned long *vecptr; unsigned long FaoVector [16]; /*********/ /* begin */ /*********/ if (WATCHMOD (rqptr, WATCH_MOD__OTHER)) WatchThis (WATCHITM(rqptr), WATCH_MOD__OTHER, "AdminMetaConBeginUpdateForm()"); vecptr = FaoVector; *vecptr++ = rqptr->rqHeader.PathInfoPtr; *vecptr++ = ServerHostPort; *vecptr++ = SoftwareID; *vecptr++ = &rqptr->rqTime.BeginTime64; *vecptr++ = rqptr->RemoteUser; *vecptr++ = rqptr->rqAuth.RealmDescrPtr; *vecptr++ = rqptr->ClientPtr->Lookup.HostName; FaoCheck (sizeof(FaoVector), &FaoVector, vecptr, FI_LI); status = FaolToNet (rqptr, BeginFormFao, &FaoVector); if (VMSnok (status)) ErrorNoticed (rqptr, status, NULL, FI_LI); } /*****************************************************************************/ /* For administration menu configuration update pages provide the update buttons and the
tag (complements AdminMetaConEndUpdateForm()). */ AdminMetaConEndUpdateForm (REQUEST_STRUCT *rqptr) { static char EndForm [] = "

\n\

\n\ \n\ \n"; int status; /*********/ /* begin */ /*********/ if (WATCHMOD (rqptr, WATCH_MOD__OTHER)) WatchThis (WATCHITM(rqptr), WATCH_MOD__OTHER, "AdminMetaConEndUpdateForm()"); status = FaolToNet (rqptr, EndForm, NULL); if (VMSnok (status)) ErrorNoticed (rqptr, status, NULL, FI_LI); } /*****************************************************************************/ /* For administration menu configuration update pages provide the update buttons and the tag (complements AdminMetaConEndUpdateForm()). */ AdminVirtualServiceForm ( REQUEST_STRUCT *rqptr, char *FormAction, char *VirtualService, BOOL UseServerDatabase ) { static char BeginFormFao [] = "

\n\ \n\ \n\ \n\
\n"; int status; unsigned long *vecptr; unsigned long FaoVector [16]; SERVICE_STRUCT *svptr; /*********/ /* begin */ /*********/ if (WATCHMOD (rqptr, WATCH_MOD__OTHER)) WatchThis (WATCHITM(rqptr), WATCH_MOD__OTHER, "AdminVirtualServiceForm()"); vecptr = FaoVector; *vecptr++ = FormAction; *vecptr++ = UseServerDatabase; *vecptr++ = VirtualService[0]; *vecptr++ = (ServiceCount == 1); FaoCheck (sizeof(FaoVector), &FaoVector, vecptr, FI_LI); status = FaolToNet (rqptr, BeginFormFao, &FaoVector); if (VMSnok (status)) ErrorNoticed (rqptr, status, NULL, FI_LI); if (ServiceCount > 1) { for (svptr = ServiceListHead; svptr; svptr = svptr->NextPtr) { vecptr = FaoVector; *vecptr++ = svptr->ServerHostPort; *vecptr++ = strsame (svptr->ServerHostPort, VirtualService, -1); *vecptr++ = svptr->ServerHostPort; FaoCheck (sizeof(FaoVector), &FaoVector, vecptr, FI_LI); status = FaolToNet (rqptr, "