Update the service_name global to an SBuf and use Tokenizer to validate
the -n argument is a pure alphanumeric.
Amos
=== modified file 'src/WinSvc.cc'
--- src/WinSvc.cc 2014-01-24 01:57:15 +0000
+++ src/WinSvc.cc 2014-06-14 14:20:56 +0000
@@ -493,41 +493,41 @@
#if defined(_MSC_VER) /* Microsoft C Compiler ONLY */
newHandler = Squid_Win32InvalidParameterHandler;
oldHandler = _set_invalid_parameter_handler(newHandler);
_CrtSetReportMode(_CRT_ASSERT, 0);
#endif
#if USE_WIN32_SERVICE
if (WIN32_run_mode == _WIN_SQUID_RUN_MODE_SERVICE) {
char path[512];
HKEY hndKey;
if (signal(SIGABRT, WIN32_Abort) == SIG_ERR)
return 1;
/* Register the service Handler function */
- svcHandle = RegisterServiceCtrlHandler(service_name, WIN32_svcHandler);
+ svcHandle = RegisterServiceCtrlHandler(service_name.c_str(),
WIN32_svcHandler);
if (svcHandle == 0)
return 1;
/* Set Process work dir to directory cointaining squid.exe */
GetModuleFileName(NULL, path, 512);
WIN32_module_name=xstrdup(path);
path[strlen(path) - 10] = '\0';
if (SetCurrentDirectory(path) == 0)
return 1;
safe_free(ConfigFile);
/* get config file from Windows Registry */
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, REGKEY, 0, KEY_QUERY_VALUE,
&hndKey) == ERROR_SUCCESS) {
DWORD Type = 0;
DWORD Size = 0;
@@ -654,192 +654,195 @@
status = GetLastError();
debugs(1, DBG_IMPORTANT, "SetServiceStatus error " << status);
}
debugs(1, DBG_IMPORTANT, "Leaving Squid service");
break;
default:
debugs(1, DBG_IMPORTANT, "Unrecognized opcode " << Opcode);
}
return;
}
void
WIN32_RemoveService()
{
SC_HANDLE schService;
SC_HANDLE schSCManager;
- if (!service_name)
- service_name = xstrdup(APP_SHORTNAME);
+ if (service_name.isEmpty())
+ service_name = SBuf(APP_SHORTNAME);
- strcat(REGKEY, service_name);
+ const char *service = service_name.c_str();
+ strcat(REGKEY, service);
- keys[4] = service_name;
+ keys[4] = service;
schSCManager = OpenSCManager(NULL, /* machine (NULL == local) */
NULL, /* database (NULL ==
default) */
SC_MANAGER_ALL_ACCESS /* access required
*/
);
if (!schSCManager)
fprintf(stderr, "OpenSCManager failed\n");
else {
- schService = OpenService(schSCManager, service_name,
SERVICE_ALL_ACCESS);
+ schService = OpenService(schSCManager, service, SERVICE_ALL_ACCESS);
if (schService == NULL)
fprintf(stderr, "OpenService failed\n");
/* Could not open the service */
else {
/* try to stop the service */
if (ControlService(schService, _WIN_SQUID_SERVICE_CONTROL_STOP,
&svcStatus)) {
sleep(1);
while (QueryServiceStatus(schService, &svcStatus)) {
if (svcStatus.dwCurrentState == SERVICE_STOP_PENDING)
sleep(1);
else
break;
}
}
/* now remove the service */
if (DeleteService(schService) == 0)
fprintf(stderr, "DeleteService failed.\n");
else
- printf("Service %s deleted successfully.\n", service_name);
+ printf("Service " SQUIDSBUFPH " deleted successfully.\n",
SQUIDSBUFPRINT(service_name));
CloseServiceHandle(schService);
}
CloseServiceHandle(schSCManager);
}
}
void
WIN32_SetServiceCommandLine()
{
- if (!service_name)
- service_name = xstrdup(APP_SHORTNAME);
+ if (service_name.isEmpty())
+ service_name = SBuf(APP_SHORTNAME);
- strcat(REGKEY, service_name);
+ const char *service = servie_name.c_str();
+ strcat(REGKEY, service);
- keys[4] = service_name;
+ keys[4] = service;
/* Now store the Service Command Line in the registry */
WIN32_StoreKey(COMMANDLINE, REG_SZ, (unsigned char *) WIN32_Command_Line,
strlen(WIN32_Command_Line) + 1);
}
void
WIN32_InstallService()
{
SC_HANDLE schService;
SC_HANDLE schSCManager;
char ServicePath[512];
char szPath[512];
int lenpath;
- if (!service_name)
- service_name = xstrdup(APP_SHORTNAME);
+ if (service_name.isEmpty())
+ service_name = SBuf(APP_SHORTNAME);
- strcat(REGKEY, service_name);
+ const char *service = service_name.c_str();
+ strcat(REGKEY, service);
- keys[4] = service_name;
+ keys[4] = service;
if ((lenpath = GetModuleFileName(NULL, ServicePath, 512)) == 0) {
fprintf(stderr, "Can't get executable path\n");
exit(1);
}
- snprintf(szPath, sizeof(szPath), "%s %s:%s", ServicePath,
_WIN_SQUID_SERVICE_OPTION, service_name);
+ snprintf(szPath, sizeof(szPath), "%s %s:" SQUIDSBUFPH, ServicePath,
_WIN_SQUID_SERVICE_OPTION, SQUIDSBUFPRINT(service_name));
schSCManager = OpenSCManager(NULL, /* machine (NULL == local) */
NULL, /* database (NULL ==
default) */
SC_MANAGER_ALL_ACCESS /* access required
*/
);
if (!schSCManager) {
fprintf(stderr, "OpenSCManager failed\n");
exit(1);
} else {
schService = CreateService(schSCManager, /* SCManager database
*/
- service_name, /*
name of service */
- service_name, /*
name to display */
+ service, /* name of
service */
+ service, /* name to
display */
SERVICE_ALL_ACCESS, /*
desired access */
SERVICE_WIN32_OWN_PROCESS, /*
service type */
SERVICE_AUTO_START, /*
start type */
SERVICE_ERROR_NORMAL, /*
error control type */
(const char *) szPath, /*
service's binary */
NULL, /*
no load ordering group */
NULL, /*
no tag identifier */
"Tcpip\0AFD\0", /*
dependencies */
NULL, /*
LocalSystem account */
NULL); /*
no password */
if (schService) {
if (WIN32_OS_version > _WIN_OS_WINNT) {
HMODULE ADVAPI32Handle;
PFChangeServiceConfig2 ChangeServiceConfig2;
DWORD dwInfoLevel = SERVICE_CONFIG_DESCRIPTION;
ADVAPI32Handle = GetModuleHandle("advapi32");
ChangeServiceConfig2 = (PFChangeServiceConfig2)
GetProcAddress(ADVAPI32Handle, CHANGESERVICECONFIG2);
ChangeServiceConfig2(schService, dwInfoLevel,
&Squid_ServiceDescription);
dwInfoLevel = SERVICE_CONFIG_FAILURE_ACTIONS;
ChangeServiceConfig2(schService, dwInfoLevel,
&Squid_ServiceFailureActions);
}
CloseServiceHandle(schService);
/* Now store the config file location in the registry */
if (!ConfigFile)
ConfigFile = xstrdup(DefaultConfigFile);
WIN32_StoreKey(CONFIGFILE, REG_SZ, (unsigned char *) ConfigFile,
strlen(ConfigFile) + 1);
printf("Squid Cache version %s for %s\n", version_string,
CONFIG_HOST_TYPE);
- printf("installed successfully as %s Windows System Service.\n",
service_name);
+ printf("installed successfully as " SQUIDSBUFPH " Windows System
Service.\n", SQUIDSBUFPRINT(service_name));
printf("To run, start it from the Services Applet of Control
Panel.\n");
printf("Don't forget to edit squid.conf before starting it.\n\n");
} else {
fprintf(stderr, "CreateService failed\n");
exit(1);
}
CloseServiceHandle(schSCManager);
}
}
void
WIN32_sendSignal(int WIN32_signal)
{
SERVICE_STATUS ssStatus;
DWORD fdwAccess, fdwControl;
SC_HANDLE schService;
SC_HANDLE schSCManager;
- if (!service_name)
- service_name = xstrdup(APP_SHORTNAME);
+ if (service_name.isEmpty())
+ service_name = SBuf(APP_SHORTNAME);
schSCManager = OpenSCManager(NULL, /* machine (NULL == local) */
NULL, /* database (NULL ==
default) */
SC_MANAGER_ALL_ACCESS /* access required
*/
);
if (!schSCManager) {
fprintf(stderr, "OpenSCManager failed\n");
exit(1);
}
/* The required service object access depends on the control. */
switch (WIN32_signal) {
case 0: /* SIGNULL */
fdwAccess = SERVICE_INTERROGATE;
fdwControl = _WIN_SQUID_SERVICE_CONTROL_INTERROGATE;
break;
case SIGUSR1:
@@ -858,100 +861,101 @@
break;
case SIGTERM:
fdwAccess = SERVICE_STOP;
fdwControl = _WIN_SQUID_SERVICE_CONTROL_STOP;
break;
case SIGINT:
case SIGKILL:
fdwAccess = SERVICE_USER_DEFINED_CONTROL;
fdwControl = _WIN_SQUID_SERVICE_CONTROL_INTERRUPT;
break;
default:
exit(1);
}
/* Open a handle to the service. */
schService = OpenService(schSCManager, /* SCManager database */
- service_name, /* name of service */
+ service_name.c_str(), /* name of service */
fdwAccess); /* specify access */
if (schService == NULL) {
- fprintf(stderr, "%s: ERROR: Could not open Service %s\n",
APP_SHORTNAME, service_name);
+ fprintf(stderr, "%s: ERROR: Could not open Service " SQUIDSBUFPH "\n",
APP_SHORTNAME, SQUIDSBUFPRINT(service_name));
exit(1);
} else {
/* Send a control value to the service. */
if (!ControlService(schService, /* handle of service */
fdwControl, /* control value to send */
&ssStatus)) { /* address of status info */
- fprintf(stderr, "%s: ERROR: Could not Control Service %s\n",
- APP_SHORTNAME, service_name);
+ fprintf(stderr, "%s: ERROR: Could not Control Service "
SQUIDSBUFPH "\n",
+ APP_SHORTNAME, SQUIDSBUFPRINT(service_name));
exit(1);
} else {
/* Print the service status. */
- printf("\nStatus of %s Service:\n", service_name);
+ printf("\nStatus of " SQUIDSBUFPH " Service:\n",
SQUIDSBUFPRINT(service_name));
printf(" Service Type: 0x%lx\n", ssStatus.dwServiceType);
printf(" Current State: 0x%lx\n", ssStatus.dwCurrentState);
printf(" Controls Accepted: 0x%lx\n",
ssStatus.dwControlsAccepted);
printf(" Exit Code: %ld\n", ssStatus.dwWin32ExitCode);
printf(" Service Specific Exit Code: %ld\n",
ssStatus.dwServiceSpecificExitCode);
printf(" Check Point: %ld\n", ssStatus.dwCheckPoint);
printf(" Wait Hint: %ld\n", ssStatus.dwWaitHint);
}
CloseServiceHandle(schService);
}
CloseServiceHandle(schSCManager);
}
int main(int argc, char **argv)
{
SERVICE_TABLE_ENTRY DispatchTable[] = {
{NULL, SquidWinSvcMain},
{NULL, NULL}
};
char *c;
char stderr_path[256];
SetErrorMode(SEM_NOGPFAULTERRORBOX);
if ((argc == 2) && strstr(argv[1], _WIN_SQUID_SERVICE_OPTION)) {
strcpy(stderr_path, argv[0]);
strcat(stderr_path,".log");
freopen(stderr_path, "w", stderr);
setmode(fileno(stderr), O_TEXT);
WIN32_run_mode = _WIN_SQUID_RUN_MODE_SERVICE;
if (!(c=strchr(argv[1],':'))) {
fprintf(stderr, "Bad Service Parameter: %s\n", argv[1]);
return 1;
}
- service_name = xstrdup(c+1);
- DispatchTable[0].lpServiceName=service_name;
- strcat(REGKEY, service_name);
- keys[4] = service_name;
+ service_name = SBuf(c+1);
+ const char *service = service_name.c_str();
+ DispatchTable[0].lpServiceName=service;
+ strcat(REGKEY, service);
+ keys[4] = service;
if (!StartServiceCtrlDispatcher(DispatchTable)) {
fprintf(stderr, "StartServiceCtrlDispatcher error = %ld\n",
GetLastError());
return 1;
}
} else {
WIN32_run_mode = _WIN_SQUID_RUN_MODE_INTERACTIVE;
opt_no_daemon = 1;
return SquidMain(argc, argv);
}
return 0;
}
#endif /* USE_WIN32_SERVICE */
static int Win32SockInit(void)
{
=== modified file 'src/cache_cf.cc'
--- src/cache_cf.cc 2014-06-02 06:23:12 +0000
+++ src/cache_cf.cc 2014-06-14 06:44:00 +0000
@@ -365,41 +365,41 @@
// copy new substring in place
memcpy(str + substrIdx, newSubstr, newSubstrLen);
len = strlen(str);
}
static void
SubstituteMacro(char*& line, int& len, const char* macroName, const char*
substStr)
{
assert(line != NULL);
assert(macroName != NULL);
assert(substStr != NULL);
unsigned macroNameLen = strlen(macroName);
while (const char* macroPos = strstr(line, macroName)) // we would replace
all occurrences
ReplaceSubstr(line, len, macroPos - line, macroNameLen, substStr);
}
static void
ProcessMacros(char*& line, int& len)
{
- SubstituteMacro(line, len, "${service_name}", service_name);
+ SubstituteMacro(line, len, "${service_name}", service_name.c_str());
SubstituteMacro(line, len, "${process_name}", TheKidName);
SubstituteMacro(line, len, "${process_number}", xitoa(KidIdentifier));
}
static void
trim_trailing_ws(char* str)
{
assert(str != NULL);
unsigned i = strlen(str);
while ((i > 0) && xisspace(str[i - 1]))
--i;
str[i] = '\0';
}
static const char*
FindStatement(const char* line, const char* statement)
{
assert(line != NULL);
assert(statement != NULL);
=== modified file 'src/globals.h'
--- src/globals.h 2014-03-23 02:56:12 +0000
+++ src/globals.h 2014-06-14 06:37:05 +0000
@@ -19,57 +19,58 @@
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
*
*/
#ifndef SQUID_GLOBALS_H
#define SQUID_GLOBALS_H
#include "acl/AclDenyInfoList.h"
#include "CacheDigest.h"
#include "defines.h"
#include "hash.h"
#include "IoStats.h"
#include "rfc2181.h"
+#include "SBuf.h"
extern char *ConfigFile; /* NULL */
extern char *IcpOpcodeStr[];
extern char tmp_error_buf[ERROR_BUF_SZ];
extern char ThisCache[RFC2181_MAXHOSTNAMELEN << 1];
extern char ThisCache2[RFC2181_MAXHOSTNAMELEN << 1];
extern char config_input_line[BUFSIZ];
/// During parsing, the name of the current squid.conf directive being parsed.
extern const char *cfg_directive; /* NULL */
extern const char *DefaultConfigFile; /* DEFAULT_CONFIG_FILE */
extern const char *cfg_filename; /* NULL */
extern const char *dash_str; /* "-" */
extern const char *null_string; /* "" */
extern const char *version_string; /* VERSION */
extern const char *appname_string; /* PACKAGE */
extern char const *visible_appname_string; /* NULL */
-extern char *service_name; /* xstrdup(APP_SHORTNAME) */
+extern SBuf service_name; /* SBuf(APP_SHORTNAME) */
extern const char *fdTypeStr[];
extern const char *hier_strings[];
extern const char *memStatusStr[];
extern const char *pingStatusStr[];
extern const char *storeStatusStr[];
extern const char *swapStatusStr[];
extern int Biggest_FD; /* -1 */
extern int Number_FD; /* 0 */
extern int Opening_FD; /* 0 */
extern int NDnsServersAlloc; /* 0 */
extern int RESERVED_FD;
extern int Squid_MaxFD; /* SQUID_MAXFD */
extern int config_lineno; /* 0 */
extern int opt_reuseaddr; /* 1 */
extern int neighbors_do_private_keys; /* 1 */
extern int opt_catch_signals; /* 1 */
extern int opt_foreground_rebuild; /* 0 */
extern char *opt_forwarded_for; /* NULL */
extern int opt_reload_hit_only; /* 0 */
=== modified file 'src/ipc/Port.cc'
--- src/ipc/Port.cc 2014-06-05 14:57:58 +0000
+++ src/ipc/Port.cc 2014-06-14 06:45:23 +0000
@@ -29,54 +29,54 @@
void Ipc::Port::doListen()
{
debugs(54, 6, HERE);
buf.prepForReading();
typedef CommCbMemFunT<Port, CommIoCbParams> Dialer;
AsyncCall::Pointer readHandler = JobCallback(54, 6,
Dialer, this, Port::noteRead);
comm_read(conn(), buf.raw(), buf.size(), readHandler);
}
bool Ipc::Port::doneAll() const
{
return false; // listen forever
}
String Ipc::Port::MakeAddr(const char* processLabel, int id)
{
assert(id >= 0);
String addr = channelPathPfx;
- addr.append(service_name);
+ addr.append(service_name.c_str());
addr.append(processLabel);
addr.append('-');
addr.append(xitoa(id));
addr.append(".ipc");
return addr;
}
String
Ipc::Port::CoordinatorAddr()
{
static String coordinatorAddr;
if (!coordinatorAddr.size()) {
coordinatorAddr= channelPathPfx;
- coordinatorAddr.append(service_name);
+ coordinatorAddr.append(service_name.c_str());
coordinatorAddr.append(coordinatorAddrLabel);
coordinatorAddr.append(".ipc");
}
return coordinatorAddr;
}
void Ipc::Port::noteRead(const CommIoCbParams& params)
{
debugs(54, 6, HERE << params.conn << " flag " << params.flag <<
" [" << this << ']');
if (params.flag == Comm::OK) {
assert(params.buf == buf.raw());
receive(buf);
}
// TODO: if there was a fatal error on our socket, close the socket before
// trying to listen again and print a level-1 error message.
doListen();
}
=== modified file 'src/main.cc'
--- src/main.cc 2014-06-02 07:19:35 +0000
+++ src/main.cc 2014-06-15 05:23:25 +0000
@@ -56,40 +56,41 @@
#include "fqdncache.h"
#include "fs/Module.h"
#include "FwdState.h"
#include "globals.h"
#include "htcp.h"
#include "HttpHeader.h"
#include "HttpReply.h"
#include "icmp/IcmpSquid.h"
#include "icmp/net_db.h"
#include "ICP.h"
#include "ident/Ident.h"
#include "ip/tools.h"
#include "ipc/Coordinator.h"
#include "ipc/Kids.h"
#include "ipc/Strand.h"
#include "ipcache.h"
#include "Mem.h"
#include "MemPool.h"
#include "mime.h"
#include "neighbors.h"
+#include "parser/Tokenizer.h"
#include "pconn.h"
#include "peer_sourcehash.h"
#include "peer_userhash.h"
#include "PeerSelectState.h"
#include "profiler/Profiler.h"
#include "redirect.h"
#include "refresh.h"
#include "send-announce.h"
#include "SquidConfig.h"
#include "SquidDns.h"
#include "SquidTime.h"
#include "stat.h"
#include "StatCounters.h"
#include "Store.h"
#include "store_log.h"
#include "StoreFileSystem.h"
#include "SwapDir.h"
#include "tools.h"
#include "unlinkd.h"
#include "URL.h"
@@ -489,44 +490,50 @@
break;
case 'm':
/** \par m
* Set global malloc_debug_level to the value given following the
option.
* if none is given it toggles the xmalloc_trace option on/off */
if (optarg) {
#if MALLOC_DBG
malloc_debug_level = atoi(optarg);
#else
fatal("Need to add -DMALLOC_DBG when compiling to use -mX
option");
#endif
}
break;
case 'n':
/** \par n
* Set global option opt_signal_service (to true).
* Stores the additional parameter given in global service_name */
- // XXX: verify that the new name has ONLY alphanumeric characters
- xfree(service_name);
- service_name = xstrdup(optarg);
- opt_signal_service = true;
+ if (optarg) {
+ SBuf t(optarg);
+ ::Parser::Tokenizer tok(t);
+ const CharacterSet chr =
CharacterSet::ALPHA+CharacterSet::DIGIT;
+ if (!tok.prefix(service_name, chr) || !tok.atEnd())
+ fatal("Need to provide alphanumeric service name when
using -n option");
+ opt_signal_service = true;
+ } else {
+ fatal("Need to provide alphanumeric service name when using -n
option");
+ }
break;
#if USE_WIN32_SERVICE
case 'r':
/** \par r
* Set global option opt_remove_service (to TRUE) */
opt_remove_service = TRUE;
break;
#endif
case 'l':
/** \par l
* Stores the syslog facility name in global opt_syslog_facility
* then performs actions for -s option. */
xfree(opt_syslog_facility); // ignore any previous options sent
opt_syslog_facility = xstrdup(optarg);
@@ -544,41 +551,41 @@
fatal("Logging to syslog not available on this platform");
/* NOTREACHED */
#endif
case 'u':
/** \par u
* Store the ICP port number given in global option
icpPortNumOverride
* ensuring its a positive number. */
icpPortNumOverride = atoi(optarg);
if (icpPortNumOverride < 0)
icpPortNumOverride = 0;
break;
case 'v':
/** \par v
* Display squid version and build information. Then exit. */
printf("Squid Cache: Version %s\n" ,version_string);
- printf("Service Name: %s\n", service_name);
+ printf("Service Name: " SQUIDSBUFPH "\n",
SQUIDSBUFPRINT(service_name));
if (strlen(SQUID_BUILD_INFO))
printf("%s\n",SQUID_BUILD_INFO);
printf( "configure options: %s\n", SQUID_CONFIGURE_OPTIONS);
#if USE_WIN32_SERVICE
printf("Compiled as Windows System Service.\n");
#endif
exit(0);
/* NOTREACHED */
case 'z':
/** \par z
* Set global option Debug::log_stderr and opt_create_swap_dirs */
Debug::log_stderr = 1;
opt_create_swap_dirs = 1;
break;
=== modified file 'src/stat.cc'
--- src/stat.cc 2014-03-30 12:00:34 +0000
+++ src/stat.cc 2014-06-14 14:20:27 +0000
@@ -608,47 +608,47 @@
}
stats.max_fd = Squid_MaxFD;
stats.biggest_fd = Biggest_FD;
stats.number_fd = Number_FD;
stats.opening_fd = Opening_FD;
stats.num_fd_free = fdNFree();
stats.reserved_fd = RESERVED_FD;
}
void
DumpInfo(Mgr::InfoActionData& stats, StoreEntry* sentry)
{
storeAppendPrintf(sentry, "Squid Object Cache: Version %s\n",
version_string);
storeAppendPrintf(sentry, "Build Info: " SQUID_BUILD_INFO "\n");
#if _SQUID_WINDOWS_
if (WIN32_run_mode == _WIN_SQUID_RUN_MODE_SERVICE) {
- storeAppendPrintf(sentry,"\nRunning as %s Windows System Service on
%s\n",
- Service_name, WIN32_OS_string);
+ storeAppendPrintf(sentry,"\nRunning as " SQUIDSBUFPH " Windows System
Service on %s\n",
+ SQUIDBUFPRINT(service_name), WIN32_OS_string);
storeAppendPrintf(sentry,"Service command line is: %s\n",
WIN32_Service_Command_Line);
} else
storeAppendPrintf(sentry,"Running on %s\n",WIN32_OS_string);
#else
- storeAppendPrintf(sentry,"Service Name: %s\n", service_name);
+ storeAppendPrintf(sentry,"Service Name: " SQUIDSBUFPH "\n",
SQUIDSBUFPRINT(service_name));
#endif
storeAppendPrintf(sentry, "Start Time:\t%s\n",
mkrfc1123(stats.squid_start.tv_sec));
storeAppendPrintf(sentry, "Current Time:\t%s\n",
mkrfc1123(stats.current_time.tv_sec));
storeAppendPrintf(sentry, "Connection information for
%s:\n",APP_SHORTNAME);
storeAppendPrintf(sentry, "\tNumber of clients accessing cache:\t%.0f\n",
stats.client_http_clients);
storeAppendPrintf(sentry, "\tNumber of HTTP requests received:\t%.0f\n",
stats.client_http_requests);
storeAppendPrintf(sentry, "\tNumber of ICP messages received:\t%.0f\n",
stats.icp_pkts_recv);
storeAppendPrintf(sentry, "\tNumber of ICP messages sent:\t%.0f\n",