]> git.ipfire.org Git - thirdparty/squid.git/blobdiff - tools/purge/purge.cc
SourceFormat Enforcement
[thirdparty/squid.git] / tools / purge / purge.cc
index c5d2a8ed5e8fc2f2e607469f9076d8c9adf94c97..558379e1ba9a46bcddf929956e40faa6532356db 100644 (file)
@@ -1,13 +1,10 @@
-//
-// $Id: purge.cc,v 1.17 2000/09/21 10:59:53 cached Exp $
-//
-// Author:  Jens-S. Vöckler <voeckler@rvs.uni-hannover.de>
+// Author:  Jens-S. V?ckler <voeckler@rvs.uni-hannover.de>
 //
 // File:    purge.cc
 //          Wed Jan 13 1999
 //
 // (c) 1999 Lehrgebiet Rechnernetze und Verteilte Systeme
-//          Universität Hannover, Germany
+//          Universit?t Hannover, Germany
 //
 // Permission to use, copy, modify, distribute, and sell this software
 // and its documentation for any purpose is hereby granted without fee,
@@ -31,7 +28,6 @@
 // ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
 // SOFTWARE.
 //
-// $Log: purge.cc,v $
 // Revision 1.17  2000/09/21 10:59:53  cached
 // *** empty log message ***
 //
 // Initial revision
 //
 //
-#if defined(__GNUC__) || defined(__GNUG__)
-#pragma implementation
-#else
-#ifndef HAS_BOOL
-#define HAS_BOOL
-typedef int bool;
-#define false 0
-#define true  1
-#endif
-#endif
+#include "squid.h"
+#include "util.h"
 
-#include <assert.h>
 #include <stdarg.h>
 #include <stdio.h>
 #include <dirent.h>
-#include <ctype.h>
 #include <string.h>
-#include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/wait.h>
 #include <fcntl.h>
@@ -121,22 +106,21 @@ typedef int bool;
 #include <signal.h>
 #include <errno.h>
 
-#if defined(HAS_PSIGNAL) && !defined(LINUX) && !defined(FREEBSD)
+#if HAVE_SIGINFO_H
 #include <siginfo.h>
-#endif // HAS_PSIGNAL
+#endif
 
 #include <netinet/in.h>
-#include <netinet/tcp.h>  // TCP_NODELAY
+#include <netinet/tcp.h>
 #include <arpa/inet.h>
-#include <netdb.h>        // gethostbyname()
-#include <regex.h>
+#include <netdb.h>
 
+#include "conffile.hh"
 #include "convert.hh"
-#include "socket.hh"
+#include "copyout.hh"
 #include "signal.hh"
+#include "socket.hh"
 #include "squid-tlv.hh"
-#include "copyout.hh"
-#include "conffile.hh"
 
 #ifndef DEFAULTHOST
 #define DEFAULTHOST "localhost"
@@ -148,9 +132,9 @@ typedef int bool;
 
 volatile sig_atomic_t term_flag = 0; // 'terminate' is a gcc 2.8.x internal...
 char*  linebuffer = 0;
-size_t buffersize = 16834;
+size_t buffersize = 128*1024;
 static char* copydir = 0;
-static unsigned debug = 0;
+static uint32_t debugFlag = 0;
 static unsigned purgeMode = 0;
 static bool iamalive = false;
 static bool reminder = false;
@@ -158,8 +142,6 @@ static bool verbose  = false;
 static bool envelope = false;
 static bool no_fork  = false;
 static const char* programname = 0;
-static const char* RCS_ID =
-    "$Id: purge.cc,v 1.17 2000/09/21 10:59:53 cached Exp $";
 
 // ----------------------------------------------------------------------
 
@@ -174,7 +156,7 @@ struct REList {
 };
 
 REList::REList( const char* what, bool doCase )
-        :next(0),data(strdup(what))
+        :next(0),data(xstrdup(what))
 {
     int result = regcomp( &rexp, what,
                           REG_EXTENDED | REG_NOSUB | (doCase ? 0 : REG_ICASE) );
@@ -189,7 +171,7 @@ REList::REList( const char* what, bool doCase )
 REList::~REList()
 {
     if ( next ) delete next;
-    if ( data ) free((void*) data);
+    if ( data ) xfree((void*) data);
     regfree(&rexp);
 }
 
@@ -222,7 +204,8 @@ concat( const char* start, ... )
     // first run: determine size
     unsigned size = strlen(start)+1;
     va_start( ap, start );
-    while ( (s=va_arg(ap,const char*)) != NULL ) size += strlen(s ? s : "");
+    while ( (s=va_arg(ap,const char*)) != NULL )
+        size += strlen(s);
     va_end(ap);
 
     // allocate
@@ -251,7 +234,8 @@ isxstring( const char* s, size_t testlen )
     if ( strlen(s) != testlen ) return false;
 
     size_t i=0;
-    while ( i<testlen && isxdigit(s[i]) ) i++;
+    while ( i<testlen && isxdigit(s[i]) )
+        ++i;
     return (i==testlen);
 }
 
@@ -272,13 +256,13 @@ log_extended( const char* fn, int code, long size, const SquidMetaList* meta )
 
     if ( meta && (findings = meta->search( STORE_META_KEY_MD5 )) ) {
         unsigned char* s = (unsigned char*) findings->data;
-        for ( int j=0; j<16; j++, s++ ) {
+        for ( int j=0; j<16; ++j, ++s ) {
             md5[j*2+0] = hexdigit[ *s >> 4 ];
             md5[j*2+1] = hexdigit[ *s & 15 ];
         }
         md5[32] = '\0'; // terminate string
     } else {
-        sprintf( md5, "%-32s", "(no_md5_data_available)" );
+        snprintf( md5, sizeof(md5), "%-32s", "(no_md5_data_available)" );
     }
 
     char timeb[64];
@@ -286,18 +270,20 @@ log_extended( const char* fn, int code, long size, const SquidMetaList* meta )
         StoreMetaStd temp;
         // make data aligned, avoid SIGBUS on RISC machines (ARGH!)
         memcpy( &temp, findings->data, sizeof(StoreMetaStd) );
-        sprintf( timeb, "%08x %08x %08x %08x %04x %5hu ",
-                 temp.timestamp, temp.lastref,
-                 temp.expires, temp.lastmod, temp.flags, temp.refcount );
+        snprintf( timeb, sizeof(timeb), "%08lx %08lx %08lx %08lx %04x %5hu ",
+                  (unsigned long)temp.timestamp, (unsigned long)temp.lastref,
+                  (unsigned long)temp.expires, (unsigned long)temp.lastmod, temp.flags, temp.refcount );
     } else if ( meta && (findings = meta->search( STORE_META_STD_LFS )) ) {
         StoreMetaStdLFS temp;
         // make data aligned, avoid SIGBUS on RISC machines (ARGH!)
         memcpy( &temp, findings->data, sizeof(StoreMetaStd) );
-        sprintf( timeb, "%08x %08x %08x %08x %04x %5hu ",
-                 temp.timestamp, temp.lastref,
-                 temp.expires, temp.lastmod, temp.flags, temp.refcount );
+        snprintf( timeb, sizeof(timeb), "%08lx %08lx %08lx %08lx %04x %5hu ",
+                  (unsigned long)temp.timestamp, (unsigned long)temp.lastref,
+                  (unsigned long)temp.expires, (unsigned long)temp.lastmod, temp.flags, temp.refcount );
     } else {
-        sprintf( timeb, "%08x %08x %08x %08x %04x %5hu ", -1, -1, -1, -1, 0, 0 );
+        unsigned long ul = ULONG_MAX;  // Match type of StoreMetaTLV fields
+        unsigned short hu = 0;  // Match type of StoreMetaTLV refcount fields
+        snprintf( timeb, sizeof(timeb), "%08lx %08lx %08lx %08lx %04x %5d ", ul, ul, ul, ul, 0, hu);
     }
 
     // make sure that there is just one printf()
@@ -334,19 +320,19 @@ action( int fd, size_t metasize,
     static const char* schablone = "PURGE %s HTTP/1.0\r\nAccept: */*\r\n\r\n";
     struct stat st;
     long size = ( fstat(fd,&st) == -1 ? -1 : long(st.st_size - metasize) );
-    int status = 0;
 
     // if we want to copy out the file, do that first of all.
     if ( ::copydir && *copydir && size > 0 )
-        copy_out( st.st_size, metasize, ::debug,
+        copy_out( st.st_size, metasize, ::debugFlag,
                   fn, url, ::copydir, ::envelope );
 
     // do we need to PURGE the file, yes, if purgemode bit#0 was set.
+    int status = 0;
     if ( ::purgeMode & 0x01 ) {
         unsigned long bufsize = strlen(url) + strlen(schablone) + 4;
         char* buffer = new char[bufsize];
 
-        sprintf( buffer, schablone, url );
+        snprintf( buffer, bufsize, schablone, url );
         int sockfd = connectTo( serverHost, serverPort, true );
         if ( sockfd == -1 ) {
             fprintf( stderr, "unable to connect to server: %s\n", strerror(errno) );
@@ -354,8 +340,8 @@ action( int fd, size_t metasize,
             return false;
         }
 
-        int size = strlen(buffer);
-        if ( write( sockfd, buffer, size ) != size ) {
+        int content_size = strlen(buffer);
+        if ( write( sockfd, buffer, content_size ) != content_size ) {
             // error while talking to squid
             fprintf( stderr, "unable to talk to server: %s\n", strerror(errno) );
             close(sockfd);
@@ -363,15 +349,23 @@ action( int fd, size_t metasize,
             return false;
         }
         memset( buffer+8, 0, 4 );
-        if ( read( sockfd, buffer, bufsize ) < 1 ) {
+        int readLen = read(sockfd, buffer, bufsize);
+        if (readLen < 1) {
             // error while reading squid's answer
             fprintf( stderr, "unable to read answer: %s\n", strerror(errno) );
             close(sockfd);
             delete[] buffer;
             return false;
         }
+        buffer[bufsize-1] = '\0';
         close(sockfd);
-        status = strtol(buffer+8,0,10);
+        int64_t s = strtol(buffer+8,0,10);
+        if (s > 0 && s < 1000)
+            status = s;
+        else {
+            // error while reading squid's answer
+            fprintf( stderr, "invalid HTTP status in reply: %s\n", buffer+8);
+        }
         delete[] buffer;
     }
 
@@ -403,10 +397,12 @@ match( const char* fn, const REList* list )
     static const size_t addon = sizeof(unsigned char) + sizeof(unsigned int);
     bool flag = true;
 
-    if ( debug & 0x01 ) fprintf( stderr, "# [3] %s\n", fn );
+    if ( debugFlag & 0x01 ) fprintf( stderr, "# [3] %s\n", fn );
     int fd = open( fn, O_RDONLY );
     if ( fd != -1 ) {
-        if ( read(fd,::linebuffer,::buffersize-1) > 60 ) {
+        memset(::linebuffer, 0, ::buffersize);
+        size_t readLen = read(fd,::linebuffer,::buffersize-1);
+        if ( readLen > 60 ) {
             ::linebuffer[ ::buffersize-1 ] = '\0'; // force-terminate string
 
             // check the offset into the start of object data. The offset is
@@ -427,6 +423,14 @@ match( const char* fn, const REList* list )
             while ( offset + addon <= datastart ) {
                 unsigned int size = 0;
                 memcpy( &size, linebuffer+offset+sizeof(char), sizeof(unsigned int) );
+                if (size+offset < size) {
+                    fputs("WARNING: file corruption detected. 32-bit overflow in size field.\n", stderr);
+                    break;
+                }
+                if (size+offset > readLen) {
+                    fputs( "WARNING: Partial meta data loaded.\n", stderr );
+                    break;
+                }
                 meta.append( SquidMetaType(*(linebuffer+offset)),
                              size, linebuffer+offset+addon );
                 offset += ( addon + size );
@@ -485,8 +489,8 @@ filelevel( const char* directory, const REList* list )
 //          list (IN): list of rexps to match URLs against
 // returns: true, if every subdir && action was successful.
 {
-    struct dirent* entry;
-    if ( debug & 0x01 )
+    dirent_t * entry;
+    if ( debugFlag & 0x01 )
         fprintf( stderr, "# [2] %s\n", directory );
 
     DIR* dir = opendir( directory );
@@ -500,7 +504,8 @@ filelevel( const char* directory, const REList* list )
     if ( ::iamalive ) {
         static char alivelist[4][3] = { "\\\b", "|\b", "/\b", "-\b" };
         static unsigned short alivecount = 0;
-        assert( write( STDOUT_FILENO, alivelist[alivecount++ & 3], 2 ) == 2 );
+        const int write_success = write(STDOUT_FILENO, alivelist[alivecount++ & 3], 2);
+        assert(write_success == 2);
     }
 
     bool flag = true;
@@ -527,8 +532,8 @@ dirlevel( const char* dirname, const REList* list, bool level=false )
 // returns: true, if every subdir && action was successful.
 // warning: this function is once-recursive, no deeper.
 {
-    struct dirent* entry;
-    if ( debug & 0x01 )
+    dirent_t* entry;
+    if ( debugFlag & 0x01 )
         fprintf( stderr, "# [%d] %s\n", (level ? 1 : 0), dirname );
 
     DIR* dir = opendir( dirname );
@@ -554,23 +559,23 @@ dirlevel( const char* dirname, const REList* list, bool level=false )
 }
 
 int
-checkForPortOnly( const char* optarg )
+checkForPortOnly( const char* arg )
 // purpose: see if somebody just put in a port instead of a hostname
 // paramtr: optarg (IN): argument from commandline
 // returns: 0..65535 is the valid port number in network byte order,
 //          -1 if not a port
 {
     // if there is a period in there, it must be a valid hostname
-    if ( strchr( optarg, '.' ) != 0 ) return -1;
+    if ( strchr( arg, '.' ) != 0 ) return -1;
 
     // if it is just a number between 0 and 65535, it must be a port
     char* errstr = 0;
-    unsigned long result = strtoul( optarg, &errstr, 0 );
-    if ( result < 65536 && errstr != optarg ) return htons(result);
+    unsigned long result = strtoul( arg, &errstr, 0 );
+    if ( result < 65536 && errstr != arg ) return htons(result);
 
 #if 0
     // one last try, test for a symbolical service name
-    struct servent* service = getservbyname( optarg, "tcp" );
+    struct servent* service = getservbyname( arg, "tcp" );
     return service ? service->s_port : -1;
 #else
     return -1;
@@ -581,14 +586,14 @@ void
 helpMe( void )
 // purpuse: write help message and exit
 {
-    printf( "\n%s\nUsage:\t%s\t[-a] [-c cf] [-d l] [-(f|F) fn | -(e|E) re] "
+    printf( "\nUsage:\t%s\t[-a] [-c cf] [-d l] [-(f|F) fn | -(e|E) re] "
             "[-p h[:p]]\n\t\t[-P #] [-s] [-v] [-C dir [-H]] [-n]\n\n",
-            ::RCS_ID, ::programname );
+            ::programname );
     printf(
         " -a\tdisplay a little rotating thingy to indicate that I am alive (tty only).\n"
         " -c c\tsquid.conf location, default \"%s\".\n"
         " -C dir\tbase directory for content extraction (copy-out mode).\n"
-        " -d l\tdebug level, an OR of different debug options.\n"
+        " -d l\tdebug level, an OR mask of different debug options.\n"
         " -e re\tsingle regular expression per -e instance (use quotes!).\n"
         " -E re\tsingle case sensitive regular expression like -e.\n"
         " -f fn\tname of textfile containing one regular expression per line.\n"
@@ -609,8 +614,8 @@ helpMe( void )
 
 void
 parseCommandline( int argc, char* argv[], REList*& head,
-                  char*& conffile, char*& copydir,
-                  struct in_addr& serverHost, unsigned short& serverPort )
+                  char*& conffile, char*& copyDirPath,
+                  struct in_addr& serverHostIp, unsigned short& serverHostPort )
 // paramtr: argc: see ::main().
 //          argv: see ::main().
 // returns: Does terminate the program on errors!
@@ -621,8 +626,10 @@ parseCommandline( int argc, char* argv[], REList*& head,
     FILE* rfile;
 
     // program basename
-    if ( (ptr = strrchr(argv[0],'/')) == NULL ) ptr=argv[0];
-    else ptr++;
+    if ( (ptr = strrchr(argv[0],'/')) == NULL )
+        ptr=argv[0];
+    else
+        ++ptr;
     ::programname = ptr;
 
     // extract commandline parameters
@@ -635,24 +642,37 @@ parseCommandline( int argc, char* argv[], REList*& head,
             break;
         case 'C':
             if ( optarg && *optarg ) {
-                if ( copydir ) free( (void*) copydir );
-                assert( (copydir = strdup(optarg)) );
+                if ( copyDirPath ) xfree( (void*) copyDirPath );
+                copyDirPath = xstrdup(optarg);
+                assert(copyDirPath);
             }
             break;
         case 'c':
-            if ( optarg && *optarg ) {
-                if ( *conffile ) free((void*) conffile );
-                assert( (conffile = strdup(optarg)) );
+            if ( !optarg || !*optarg ) {
+                fprintf( stderr, "%c requires a regex pattern argument!\n", option );
+                exit(1);
             }
+            if ( *conffile ) xfree((void*) conffile);
+            conffile = xstrdup(optarg);
+            assert(conffile);
             break;
 
         case 'd':
-            ::debug = strtoul( optarg, 0, 0 );
+            if ( !optarg || !*optarg ) {
+                fprintf( stderr, "%c expects a mask parameter. Debug disabled.\n", option );
+                ::debugFlag = 0;
+            } else
+                ::debugFlag = (strtoul(optarg, NULL, 0) & 0xFFFFFFFF);
             break;
 
         case 'E':
         case 'e':
-            if ( head == 0 ) tail = head = new REList( optarg, option=='E' );
+            if ( !optarg || !*optarg ) {
+                fprintf( stderr, "%c requires a regex pattern argument!\n", option );
+                exit(1);
+            }
+            if ( head == 0 )
+                tail = head = new REList( optarg, option=='E' );
             else {
                 tail->next = new REList( optarg, option=='E' );
                 tail = tail->next;
@@ -660,12 +680,16 @@ parseCommandline( int argc, char* argv[], REList*& head,
             break;
 
         case 'f':
+            if ( !optarg || !*optarg ) {
+                fprintf( stderr, "%c requires a filename argument!\n", option );
+                exit(1);
+            }
             if ( (rfile = fopen( optarg, "r" )) != NULL ) {
                 unsigned long lineno = 0;
 #define LINESIZE 512
                 char line[LINESIZE];
                 while ( fgets( line, LINESIZE, rfile ) != NULL ) {
-                    lineno++;
+                    ++lineno;
                     int len = strlen(line)-1;
                     if ( len+2 >= LINESIZE ) {
                         fprintf( stderr, "%s:%lu: line too long, sorry.\n",
@@ -674,8 +698,10 @@ parseCommandline( int argc, char* argv[], REList*& head,
                     }
 
                     // remove trailing line breaks
-                    while ( len > 0 && ( line[len] == '\n' || line[len] == '\r' ) )
-                        line[len--] = '\0';
+                    while ( len > 0 && ( line[len] == '\n' || line[len] == '\r' ) ) {
+                        line[len] = '\0';
+                        --len;
+                    }
 
                     // insert into list of expressions
                     if ( head == 0 ) tail = head = new REList(line,option=='F');
@@ -696,6 +722,10 @@ parseCommandline( int argc, char* argv[], REList*& head,
             ::no_fork = ! ::no_fork;
             break;
         case 'p':
+            if ( !optarg || !*optarg ) {
+                fprintf( stderr, "%c requires a port argument!\n", option );
+                exit(1);
+            }
             colon = strchr( optarg, ':' );
             if ( colon == 0 ) {
                 // no colon, only look at host
@@ -705,28 +735,33 @@ parseCommandline( int argc, char* argv[], REList*& head,
                 port = checkForPortOnly( optarg );
                 if ( port == -1 ) {
                     // assume that main() did set the default port
-                    if ( convertHostname(optarg,serverHost) == -1 ) {
+                    if ( convertHostname(optarg,serverHostIp) == -1 ) {
                         fprintf( stderr, "unable to resolve host %s!\n", optarg );
                         exit(1);
                     }
                 } else {
                     // assume that main() did set the default host
-                    serverPort = port;
+                    serverHostPort = port;
                 }
             } else {
                 // colon used, port is extra
-                *colon++ = 0;
-                if ( convertHostname(optarg,serverHost) == -1 ) {
+                *colon = 0;
+                ++colon;
+                if ( convertHostname(optarg,serverHostIp) == -1 ) {
                     fprintf( stderr, "unable to resolve host %s!\n", optarg );
                     exit(1);
                 }
-                if ( convertPortname(colon,serverPort) == -1 ) {
+                if ( convertPortname(colon,serverHostPort) == -1 ) {
                     fprintf( stderr, "unable to resolve port %s!\n", colon );
                     exit(1);
                 }
             }
             break;
         case 'P':
+            if ( !optarg || !*optarg ) {
+                fprintf( stderr, "%c requires a mode argument!\n", option );
+                exit(1);
+            }
             ::purgeMode = ( strtol( optarg, 0, 0 ) & 0x07 );
             break;
         case 's':
@@ -743,7 +778,7 @@ parseCommandline( int argc, char* argv[], REList*& head,
     }
 
     // adjust
-    if ( ! isatty(fileno(stdout)) || (::debug & 0x01) ) ::iamalive = false;
+    if ( ! isatty(fileno(stdout)) || (::debugFlag & 0x01) ) ::iamalive = false;
     if ( head == 0 ) {
         fputs( "There was no regular expression defined. If you intend\n", stderr );
         fputs( "to match all possible URLs, use \"-e .\" instead.\n", stderr );
@@ -754,35 +789,36 @@ parseCommandline( int argc, char* argv[], REList*& head,
     assert( head != 0 );
 
     // make sure that the copy out directory is there and accessible
-    if ( copydir && *copydir )
-        if ( assert_copydir( copydir ) != 0 ) exit(1);
+    if ( copyDirPath && *copyDirPath )
+        if ( assert_copydir( copyDirPath ) != 0 ) exit(1);
 
     // show results
     if ( showme ) {
-        printf( "#\n# Currently active values for %s:\n# %s\n",
-                ::programname, ::RCS_ID );
+        printf( "#\n# Currently active values for %s:\n",
+                ::programname);
         printf( "# Debug level       : " );
-        if ( ::debug ) printf( "%#6.4hx", ::debug );
+        if ( ::debugFlag ) printf( "%#6.4x", ::debugFlag );
         else printf( "production level" ); // printf omits 0x prefix for 0!
         printf( " + %s mode", ::no_fork ? "linear" : "parallel" );
         puts( ::verbose ? " + extra verbosity" : "" );
 
         printf( "# Copy-out directory: %s ",
-                copydir ? copydir : "copy-out mode disabled" );
-        if ( copydir )
+                copyDirPath ? copyDirPath : "copy-out mode disabled" );
+        if ( copyDirPath )
             printf( "(%s HTTP header)\n", ::envelope ? "prepend" : "no" );
         else
             puts("");
 
         printf( "# Squid config file : %s\n", conffile );
         printf( "# Cacheserveraddress: %s:%u\n",
-                inet_ntoa( serverHost ), ntohs( serverPort ) );
+                inet_ntoa( serverHostIp ), ntohs( serverHostPort ) );
         printf( "# purge mode        : 0x%02x\n", ::purgeMode );
         printf( "# Regular expression: " );
 
         unsigned count(0);
         for ( tail = head; tail != NULL; tail = tail->next ) {
-            if ( count++ ) printf( "#%22u", count );
+            if ( count++ )
+                printf( "#%22u", count );
 #if defined(LINUX) && putc==_IO_putc
             // I HATE BROKEN LINUX HEADERS!
             // purge.o(.text+0x1040): undefined reference to `_IO_putc'
@@ -847,7 +883,7 @@ main( int argc, char* argv[] )
 {
     // setup variables
     REList* list = 0;
-    char* conffile = strdup( DEFAULT_SQUID_CONF );
+    char* conffile = xstrdup( DEFAULT_SQUID_CONF );
     serverPort = htons(DEFAULTPORT);
     if ( convertHostname(DEFAULTHOST,serverHost) == -1 ) {
         fprintf( stderr, "unable to resolve host %s!\n", DEFAULTHOST );
@@ -874,7 +910,7 @@ main( int argc, char* argv[] )
 
     // try to read squid.conf file to determine all cache_dir locations
     CacheDirVector cdv(0);
-    if ( readConfigFile( cdv, conffile, debug ? stderr : 0 ) > 0 ) {
+    if ( readConfigFile( cdv, conffile, debugFlag ? stderr : 0 ) > 0 ) {
         // there are some valid cache_dir entries.
         // unless forking was forbidden by cmdline option,
         // for a process for each cache_dir entry to remove files.
@@ -886,7 +922,7 @@ main( int argc, char* argv[] )
                 if ( ! dirlevel(i->base,list) )
                     fprintf( stderr, "program terminated due to error: %s",
                              strerror(errno) );
-                free((void*) i->base);
+                xfree((void*) i->base);
             }
         } else {
             // parallel mode, all cache_dir in parallel
@@ -908,7 +944,7 @@ main( int argc, char* argv[] )
                 ::iamalive = false;
             }
 
-            for ( int i=0; i < cdv.size(); ++i ) {
+            for ( size_t i=0; i < cdv.size(); ++i ) {
                 if ( getpid() == getpgrp() ) {
                     // only parent == group leader may fork off new processes
                     if ( (child[i]=fork()) < 0 ) {
@@ -922,11 +958,11 @@ main( int argc, char* argv[] )
                         if ( ! dirlevel(cdv[i].base,list) )
                             fprintf( stderr, "program terminated due to error: %s\n",
                                      strerror(errno) );
-                        free((void*) cdv[i].base);
+                        xfree((void*) cdv[i].base);
                         return 0;
                     } else {
                         // parent mode
-                        if ( ::debug ) printf( "forked child %d\n", (int) child[i] );
+                        if ( ::debugFlag ) printf( "forked child %d\n", (int) child[i] );
                     }
                 }
             }
@@ -934,10 +970,10 @@ main( int argc, char* argv[] )
             // collect the garbase
             pid_t temp;
             int status;
-            for ( int i=0; i < cdv.size(); ++i ) {
+            for ( size_t i=0; i < cdv.size(); ++i ) {
                 while ( (temp=waitpid( (pid_t)-1, &status, 0 )) == -1 )
                     if ( errno == EINTR ) continue;
-                if ( ::debug ) printf( "collected child %d\n", (int) temp );
+                if ( ::debugFlag ) printf( "collected child %d\n", (int) temp );
             }
             delete[] child;
         }
@@ -946,8 +982,8 @@ main( int argc, char* argv[] )
     }
 
     // clean up
-    if ( copydir ) free( (void*) copydir );
-    free((void*) conffile);
+    if ( copydir ) xfree( (void*) copydir );
+    xfree((void*) conffile);
     delete list;
     return 0;
 }