if ((replyBer = ber_init(replyBV)) == NULL) {
err = LDAP_OPERATIONS_ERROR;
- }
- else if (retData) {
+ } else if (retData) {
retOctStrLen = *retDataLen + 1;
retOctStr = (char*)SMB_MALLOC_ARRAY(char, retOctStrLen);
if (!retOctStr) {
err = LDAP_OPERATIONS_ERROR;
- }
- else if (ber_scanf(replyBer, "{iis}", serverVersion, &err, retOctStr, &retOctStrLen) != LBER_ERROR) {
+ } else if (ber_scanf(replyBer, "{iis}", serverVersion, &err, retOctStr, &retOctStrLen) != LBER_ERROR) {
if (*retDataLen >= retOctStrLen) {
memcpy(retData, retOctStr, retOctStrLen);
} else if (!err) {
if (err) {
;
} else if (!err && (err = ldap_extended_operation_s(ld, NMASLDAP_GET_LOGIN_CONFIG_REQUEST,
- requestBV, NULL, NULL, &replyOID, &replyBV))) {
+ requestBV, NULL, NULL, &replyOID, &replyBV))) {
/* Call the ldap_extended_operation (synchronously) */
;
} else if (!replyOID) {
int
readConfigFile( CacheDirVector& cachedir, const char* fn, FILE* debug )
- // purpose: read squid.conf file and extract cache_dir entries
- // paramtr: cachedir (OUT): vector with an entry for each cache_dir found
- // fn (IN): file name of squid.conf to use
- // returns: number of entries, or negative to warn of errors
+// purpose: read squid.conf file and extract cache_dir entries
+// paramtr: cachedir (OUT): vector with an entry for each cache_dir found
+// fn (IN): file name of squid.conf to use
+// returns: number of entries, or negative to warn of errors
{
- static const char* expression =
- "^[ \t]*cache_dir([ \t]+([[:alpha:]]+))?[ \t]+([[:graph:]]+)[ \t]+([0-9]+)[ \t]+([0-9]+)[ \t]+([0-9]+)";
-
- // try to open file
- if ( debug ) fprintf( debug, "# trying to open %s\n", fn ? fn : "(null)" );
- FILE* in = fopen( fn, "r" );
- if ( in == NULL ) {
- fprintf( stderr, "fopen %s: %s\n", fn, strerror(errno) );
- return -1;
- }
-
- // prepare regular expression for matching
- if ( debug ) fprintf( debug, "# trying to compile \"%s\"\n", expression );
- regex_t rexp;
- int result = regcomp( &rexp, expression, REG_EXTENDED );
- if ( result != 0 ) {
- char buffer[256];
- regerror( result, &rexp, buffer, sizeof(buffer) );
- fprintf( stderr, "regular expression \"%s\": %s\n", expression, buffer );
- return -1;
- }
-
- // read line by line
- if ( debug ) fputs( "# trying to read lines\n", debug );
-
- regmatch_t subs[8];
- char *s, line[1024];
- CacheDir cd;
- while ( fgets( line, sizeof(line), in ) ) {
- // FIXME: overly long lines
-
- // terminate line at start of comment
- if ( (s = (char*) memchr( line, '#', sizeof(line) )) ) *s = '\0';
-
- // quick skip
- if ( *line == '\0' || *line == '\n' ) continue;
-
- // test line
- if ( (result=regexec( &rexp, line, 7, subs, 0 )) != 0 ) {
- // error or no match
- if ( result != REG_NOMATCH ) {
- char buffer[256];
- regerror( result, &rexp, buffer, sizeof(buffer) );
- fprintf( stderr, "while matching \"%s\" against %s%s\n",
- expression, line, buffer );
- regfree(&rexp);
- fclose(in);
- return -1;
- }
- } else {
- // match, please record
- memset( &cd, 0, sizeof(cd) );
- if ( debug ) fprintf( debug, "# match from %d-%d on line %s",
- subs[0].rm_so, subs[0].rm_eo, line );
-
- // terminate line after matched expression
- line[ subs[0].rm_eo ] = '\0';
-
- // extract information. If 6th parenthesis is filled, this is
- // a new squid with disk types, otherwise it is an older version
- int offset = 2;
- if ( subs[6].rm_so == -1 ) {
- // old version, disk type at position 2 is always UFS
- cd.type = CacheDir::CDT_UFS;
- } else {
- // new version, disk type at position 2
- line[ subs[offset].rm_eo ] = '\0';
- if ( debug ) fprintf( debug, "# match from %d-%d on \"%s\"\n",
- subs[offset].rm_so, subs[offset].rm_eo,
- line+subs[offset].rm_so );
- if ( strcmp( line + subs[offset].rm_so, "ufs" ) == 0 )
- cd.type = CacheDir::CDT_UFS;
- else if ( strcmp( line + subs[offset].rm_so, "asyncufs" ) == 0 )
- cd.type = CacheDir::CDT_AUFS;
- else if ( strcmp( line + subs[offset].rm_so, "diskd" ) == 0 )
- cd.type = CacheDir::CDT_DISKD;
- else
- cd.type = CacheDir::CDT_OTHER;
- offset++;
- }
-
- // extract base directory
- line[ subs[offset].rm_eo ] = '\0';
- if ( debug ) fprintf( debug, "# match from %d-%d on \"%s\"\n",
- subs[offset].rm_so, subs[offset].rm_eo,
- line+subs[offset].rm_so );
- cd.base = strdup( line+subs[offset].rm_so );
- offset++;
-
- // extract size information
- line[ subs[offset].rm_eo ] = '\0';
- if ( debug ) fprintf( debug, "# match from %d-%d on \"%s\"\n",
- subs[offset].rm_so, subs[offset].rm_eo,
- line+subs[offset].rm_so );
- cd.size = strtoul( line+subs[offset].rm_so, 0, 10 );
- offset++;
-
- // extract 1st level directories
- line[ subs[offset].rm_eo ] = '\0';
- if ( debug ) fprintf( debug, "# match from %d-%d on \"%s\"\n",
- subs[offset].rm_so, subs[offset].rm_eo,
- line+subs[offset].rm_so );
- cd.level[0] = strtoul( line+subs[offset].rm_so, 0, 10 );
- offset++;
-
- // extract 2nd level directories
- line[ subs[offset].rm_eo ] = '\0';
- if ( debug ) fprintf( debug, "# match from %d-%d on \"%s\"\n",
- subs[offset].rm_so, subs[offset].rm_eo,
- line+subs[offset].rm_so );
- cd.level[1] = strtoul( line+subs[offset].rm_so, 0, 10 );
- offset++;
-
- cachedir.push_back( cd );
+ static const char* expression =
+ "^[ \t]*cache_dir([ \t]+([[:alpha:]]+))?[ \t]+([[:graph:]]+)[ \t]+([0-9]+)[ \t]+([0-9]+)[ \t]+([0-9]+)";
+
+ // try to open file
+ if ( debug ) fprintf( debug, "# trying to open %s\n", fn ? fn : "(null)" );
+ FILE* in = fopen( fn, "r" );
+ if ( in == NULL ) {
+ fprintf( stderr, "fopen %s: %s\n", fn, strerror(errno) );
+ return -1;
}
- }
- fclose(in);
- regfree(&rexp);
- return cachedir.size();
+ // prepare regular expression for matching
+ if ( debug ) fprintf( debug, "# trying to compile \"%s\"\n", expression );
+ regex_t rexp;
+ int result = regcomp( &rexp, expression, REG_EXTENDED );
+ if ( result != 0 ) {
+ char buffer[256];
+ regerror( result, &rexp, buffer, sizeof(buffer) );
+ fprintf( stderr, "regular expression \"%s\": %s\n", expression, buffer );
+ return -1;
+ }
+
+ // read line by line
+ if ( debug ) fputs( "# trying to read lines\n", debug );
+
+ regmatch_t subs[8];
+ char *s, line[1024];
+ CacheDir cd;
+ while ( fgets( line, sizeof(line), in ) ) {
+ // FIXME: overly long lines
+
+ // terminate line at start of comment
+ if ( (s = (char*) memchr( line, '#', sizeof(line) )) ) *s = '\0';
+
+ // quick skip
+ if ( *line == '\0' || *line == '\n' ) continue;
+
+ // test line
+ if ( (result=regexec( &rexp, line, 7, subs, 0 )) != 0 ) {
+ // error or no match
+ if ( result != REG_NOMATCH ) {
+ char buffer[256];
+ regerror( result, &rexp, buffer, sizeof(buffer) );
+ fprintf( stderr, "while matching \"%s\" against %s%s\n",
+ expression, line, buffer );
+ regfree(&rexp);
+ fclose(in);
+ return -1;
+ }
+ } else {
+ // match, please record
+ memset( &cd, 0, sizeof(cd) );
+ if ( debug ) fprintf( debug, "# match from %d-%d on line %s",
+ subs[0].rm_so, subs[0].rm_eo, line );
+
+ // terminate line after matched expression
+ line[ subs[0].rm_eo ] = '\0';
+
+ // extract information. If 6th parenthesis is filled, this is
+ // a new squid with disk types, otherwise it is an older version
+ int offset = 2;
+ if ( subs[6].rm_so == -1 ) {
+ // old version, disk type at position 2 is always UFS
+ cd.type = CacheDir::CDT_UFS;
+ } else {
+ // new version, disk type at position 2
+ line[ subs[offset].rm_eo ] = '\0';
+ if ( debug ) fprintf( debug, "# match from %d-%d on \"%s\"\n",
+ subs[offset].rm_so, subs[offset].rm_eo,
+ line+subs[offset].rm_so );
+ if ( strcmp( line + subs[offset].rm_so, "ufs" ) == 0 )
+ cd.type = CacheDir::CDT_UFS;
+ else if ( strcmp( line + subs[offset].rm_so, "asyncufs" ) == 0 )
+ cd.type = CacheDir::CDT_AUFS;
+ else if ( strcmp( line + subs[offset].rm_so, "diskd" ) == 0 )
+ cd.type = CacheDir::CDT_DISKD;
+ else
+ cd.type = CacheDir::CDT_OTHER;
+ offset++;
+ }
+
+ // extract base directory
+ line[ subs[offset].rm_eo ] = '\0';
+ if ( debug ) fprintf( debug, "# match from %d-%d on \"%s\"\n",
+ subs[offset].rm_so, subs[offset].rm_eo,
+ line+subs[offset].rm_so );
+ cd.base = strdup( line+subs[offset].rm_so );
+ offset++;
+
+ // extract size information
+ line[ subs[offset].rm_eo ] = '\0';
+ if ( debug ) fprintf( debug, "# match from %d-%d on \"%s\"\n",
+ subs[offset].rm_so, subs[offset].rm_eo,
+ line+subs[offset].rm_so );
+ cd.size = strtoul( line+subs[offset].rm_so, 0, 10 );
+ offset++;
+
+ // extract 1st level directories
+ line[ subs[offset].rm_eo ] = '\0';
+ if ( debug ) fprintf( debug, "# match from %d-%d on \"%s\"\n",
+ subs[offset].rm_so, subs[offset].rm_eo,
+ line+subs[offset].rm_so );
+ cd.level[0] = strtoul( line+subs[offset].rm_so, 0, 10 );
+ offset++;
+
+ // extract 2nd level directories
+ line[ subs[offset].rm_eo ] = '\0';
+ if ( debug ) fprintf( debug, "# match from %d-%d on \"%s\"\n",
+ subs[offset].rm_so, subs[offset].rm_eo,
+ line+subs[offset].rm_so );
+ cd.level[1] = strtoul( line+subs[offset].rm_so, 0, 10 );
+ offset++;
+
+ cachedir.push_back( cd );
+ }
+ }
+
+ fclose(in);
+ regfree(&rexp);
+ return cachedir.size();
}
#define SA struct sockaddr
#endif
-static const char* RCS_ID =
-"$Id: convert.cc,v 1.3 2000/06/20 09:43:01 voeckler Exp $";
+static const char* RCS_ID =
+ "$Id: convert.cc,v 1.3 2000/06/20 09:43:01 voeckler Exp $";
const char*
my_inet_ntoa( const struct in_addr& a, HostAddress output )
- // purpose: thread-safely convert IPv4 address -> ASCII representation
- // paramtr: a (IN): networked representation of IPv4 address
- // buffer (OUT): storage area to store representation into.
- // returns: pointer to buffer
- // goodies: INADDR_ANY will be converted to "*"
+// purpose: thread-safely convert IPv4 address -> ASCII representation
+// paramtr: a (IN): networked representation of IPv4 address
+// buffer (OUT): storage area to store representation into.
+// returns: pointer to buffer
+// goodies: INADDR_ANY will be converted to "*"
{
- if ( a.s_addr == ntohl(INADDR_ANY) ) {
- // 'default' or '*' or ...
- output[0] = '*';
- output[1] = '\0';
- } else {
- // ANSI C++ forbids casting to an array type, nag, nag, nag...
- unsigned char s[sizeof(a.s_addr)];
- memcpy( s, &a.s_addr, sizeof(a.s_addr) );
+ if ( a.s_addr == ntohl(INADDR_ANY) ) {
+ // 'default' or '*' or ...
+ output[0] = '*';
+ output[1] = '\0';
+ } else {
+ // ANSI C++ forbids casting to an array type, nag, nag, nag...
+ unsigned char s[sizeof(a.s_addr)];
+ memcpy( s, &a.s_addr, sizeof(a.s_addr) );
- sprintf( output, "%d.%d.%d.%d", s[0], s[1], s[2], s[3] );
- }
- return output;
+ sprintf( output, "%d.%d.%d.%d", s[0], s[1], s[2], s[3] );
+ }
+ return output;
}
const char*
my_sock_ntoa( const struct sockaddr_in& a, SockAddress buffer )
- // purpose: thread-safely convert IPv4 socket pair into ASCII rep.
- // paramtr: a (IN): sockaddr_in address
- // buffer (OUT): storage area to store representation into.
- // returns: pointer to buffer
+// purpose: thread-safely convert IPv4 socket pair into ASCII rep.
+// paramtr: a (IN): sockaddr_in address
+// buffer (OUT): storage area to store representation into.
+// returns: pointer to buffer
{
- HostAddress host;
- sprintf( buffer, "%s:%u",
- my_inet_ntoa(a.sin_addr,host), ntohs(a.sin_port) );
- return buffer;
+ HostAddress host;
+ sprintf( buffer, "%s:%u",
+ my_inet_ntoa(a.sin_addr,host), ntohs(a.sin_port) );
+ return buffer;
}
const char*
my_sock_fd2a( int fd, SockAddress buffer, bool peer )
- // purpose: thread-safely convert IPv4 socket FD associated address
- // to ASCII representation
- // paramtr: fd (IN): open socket FD
- // buffer (OUT): storage area
- // peer (IN): true, use peer (remote) socket pair
- // false, use own (local) socket pair
- // returns: NULL in case of error, or pointer to buffer otherwise
- // Refer to errno in case of error (usually unconnected fd...)
+// purpose: thread-safely convert IPv4 socket FD associated address
+// to ASCII representation
+// paramtr: fd (IN): open socket FD
+// buffer (OUT): storage area
+// peer (IN): true, use peer (remote) socket pair
+// false, use own (local) socket pair
+// returns: NULL in case of error, or pointer to buffer otherwise
+// Refer to errno in case of error (usually unconnected fd...)
{
- struct sockaddr_in socket;
- SOCKLEN len = sizeof(socket);
+ struct sockaddr_in socket;
+ SOCKLEN len = sizeof(socket);
- if ( (peer ? getpeername( fd, (SA*) &socket, &len ) :
- getsockname( fd, (SA*) &socket, &len )) == -1 )
- return NULL;
- else
- return my_sock_ntoa( socket, buffer );
+ if ( (peer ? getpeername( fd, (SA*) &socket, &len ) :
+ getsockname( fd, (SA*) &socket, &len )) == -1 )
+ return NULL;
+ else
+ return my_sock_ntoa( socket, buffer );
}
int
convertHostname( const char* host, in_addr& dst )
- // purpose: convert a numeric or symbolic hostname
- // paramtr: host (IN): host description to convert
- // dst (OUT): the internet address in network byteorder.
- // returns: -1 in case of error, see h_errno; 0 otherwise.
+// purpose: convert a numeric or symbolic hostname
+// paramtr: host (IN): host description to convert
+// dst (OUT): the internet address in network byteorder.
+// returns: -1 in case of error, see h_errno; 0 otherwise.
{
- if ( host == 0 ) return -1;
- unsigned long int h = inet_addr(host);
- if ( h == 0xFFFFFFFF && strncmp(host,"255.255.255.255",15) != 0 ) {
- // symbolic host
- struct hostent* dns = gethostbyname(host);
- if ( dns == NULL ) return -1;
- else memcpy( &dst.s_addr, dns->h_addr, dns->h_length );
- } else {
- // numeric host
- dst.s_addr = h;
- }
- return 0;
+ if ( host == 0 ) return -1;
+ unsigned long int h = inet_addr(host);
+ if ( h == 0xFFFFFFFF && strncmp(host,"255.255.255.255",15) != 0 ) {
+ // symbolic host
+ struct hostent* dns = gethostbyname(host);
+ if ( dns == NULL ) return -1;
+ else memcpy( &dst.s_addr, dns->h_addr, dns->h_length );
+ } else {
+ // numeric host
+ dst.s_addr = h;
+ }
+ return 0;
}
int
convertPortname( const char* port, unsigned short& dst )
- // purpose: convert a numeric or symbolic port number
- // paramtr: port (IN): port description to convert
- // dst (OUT): port number in network byteorder.
- // returns: -1 in case of error, see errno; 0 otherwise.
+// purpose: convert a numeric or symbolic port number
+// paramtr: port (IN): port description to convert
+// dst (OUT): port number in network byteorder.
+// returns: -1 in case of error, see errno; 0 otherwise.
{
- int p = strtoul(port,0,0);
+ int p = strtoul(port,0,0);
- if ( p == 0 ) {
- // symbolic port
- struct servent* proto = getservbyname( port, "tcp" );
- if ( proto == NULL ) return -1;
- else dst = proto->s_port;
- } else {
- // numeric port
- dst = htons(p);
- }
- return 0;
+ if ( p == 0 ) {
+ // symbolic port
+ struct servent* proto = getservbyname( port, "tcp" );
+ if ( proto == NULL ) return -1;
+ else dst = proto->s_port;
+ } else {
+ // numeric port
+ dst = htons(p);
+ }
+ return 0;
}
#include "copyout.hh"
static const char* RCS_ID =
-"$Id: copyout.cc,v 1.2 1999/06/16 13:05:26 voeckler Exp $";
+ "$Id: copyout.cc,v 1.2 1999/06/16 13:05:26 voeckler Exp $";
int
assert_copydir( const char* copydir )
- // purpose: check, if copydir is a directory and that we can write into it.
- // paramtr: copydir (IN): name of directory for copying bodies.
- // returns: 0 if ok, -1 otherwise.
- // further: errors are handled within. If the directory does not exist,
- // the assertion function will try to create it.
+// purpose: check, if copydir is a directory and that we can write into it.
+// paramtr: copydir (IN): name of directory for copying bodies.
+// returns: 0 if ok, -1 otherwise.
+// further: errors are handled within. If the directory does not exist,
+// the assertion function will try to create it.
{
- struct stat st;
- int status = stat( copydir, &st );
+ struct stat st;
+ int status = stat( copydir, &st );
- // check, if either "copydir" points to a valid directory,
- // or if copydir can be created.
- if ( status == 0 && ! S_ISDIR(st.st_mode) ) {
- // stat() returned true, but did not point to a directory
- fprintf( stderr, "copy dir \"%s\" is a file!\n", copydir );
- return -1;
- } else if ( S_ISDIR(st.st_mode) &&
- !( (st.st_uid == geteuid() && ( (st.st_mode & S_IWUSR) > 0 )) ||
- (st.st_gid == getegid() && ( (st.st_mode & S_IWGRP) > 0 )) ||
- ((st.st_mode & S_IWOTH) > 0) ) ) {
- fprintf( stderr, "copy dir \"%s\" is not accessible to me\n", copydir );
- return -1;
- } if ( status == -1 ) {
- // stat() returned with an error. 'File not found' is a legal error.
- if ( errno != ENOENT ) {
- // not a 'file not found' error, so this is hard error.
- fprintf( stderr, "accessing copy-out dir \"%s\": %s\n",
- copydir, strerror(errno) );
- return -1;
- } else {
- // directory does not exist. Try to create it.
- if ( mkdir( copydir, 0750 ) == -1 ) {
- fprintf( stderr, "mkdir(%s): %s\n", copydir, strerror(errno) );
- return -1;
- }
+ // check, if either "copydir" points to a valid directory,
+ // or if copydir can be created.
+ if ( status == 0 && ! S_ISDIR(st.st_mode) ) {
+ // stat() returned true, but did not point to a directory
+ fprintf( stderr, "copy dir \"%s\" is a file!\n", copydir );
+ return -1;
+ } else if ( S_ISDIR(st.st_mode) &&
+ !( (st.st_uid == geteuid() && ( (st.st_mode & S_IWUSR) > 0 )) ||
+ (st.st_gid == getegid() && ( (st.st_mode & S_IWGRP) > 0 )) ||
+ ((st.st_mode & S_IWOTH) > 0) ) ) {
+ fprintf( stderr, "copy dir \"%s\" is not accessible to me\n", copydir );
+ return -1;
+ }
+ if ( status == -1 ) {
+ // stat() returned with an error. 'File not found' is a legal error.
+ if ( errno != ENOENT ) {
+ // not a 'file not found' error, so this is hard error.
+ fprintf( stderr, "accessing copy-out dir \"%s\": %s\n",
+ copydir, strerror(errno) );
+ return -1;
+ } else {
+ // directory does not exist. Try to create it.
+ if ( mkdir( copydir, 0750 ) == -1 ) {
+ fprintf( stderr, "mkdir(%s): %s\n", copydir, strerror(errno) );
+ return -1;
+ }
+ }
}
- }
- // postcondition: copydir exists and is a directory.
- return 0;
+ // postcondition: copydir exists and is a directory.
+ return 0;
}
inline
unsigned
xlate( char ch )
{
- if ( ch == '\r' ) return 0u;
- else if ( ch == '\n' ) return 1u;
- else return 2u;
+ if ( ch == '\r' ) return 0u;
+ else if ( ch == '\n' ) return 1u;
+ else return 2u;
}
// shortcut for monotoneous typings...
bool
copy_out( size_t filesize, size_t metasize, unsigned debug,
- const char* fn, const char* url, const char* copydir,
- bool copyHdr )
- // purpose: copy content from squid disk file into separate file
- // paramtr: metasize (IN): size of metadata to skip
- // fn (IN): current filename of squid disk file
- // url (IN): currently looked at URL to generate separate file
- // copydir (IN): base directory where to generate the file
- // copyHdr (IN): copy HTTP header, too, if set to true.
- // returns: true, if successful, false otherwise.
+ const char* fn, const char* url, const char* copydir,
+ bool copyHdr )
+// purpose: copy content from squid disk file into separate file
+// paramtr: metasize (IN): size of metadata to skip
+// fn (IN): current filename of squid disk file
+// url (IN): currently looked at URL to generate separate file
+// copydir (IN): base directory where to generate the file
+// copyHdr (IN): copy HTTP header, too, if set to true.
+// returns: true, if successful, false otherwise.
{
- static const char* index = "index.html";
-
- // find hostname part after the scheme (okok, not counting port, etc.)
- char* ptr = strstr( url, "://" );
- if ( ptr == 0 || strlen(ptr) < 4 ) return false;
+ static const char* index = "index.html";
- // create filename to store contents into
- char *filename = new char[ strlen(url) + strlen(copydir) + strlen(index) ];
- assert( filename != 0 );
- strcpy( filename, copydir );
- strcat( filename, "/" );
- char* here = filename + strlen(filename);
- strcat( filename, ptr+3 );
+ // find hostname part after the scheme (okok, not counting port, etc.)
+ char* ptr = strstr( url, "://" );
+ if ( ptr == 0 || strlen(ptr) < 4 ) return false;
- // handle server root (e.g. "http://www.focus.de" )
- if ( strchr( ptr+3, '/' ) == 0 ) strcat( filename, "/" );
+ // create filename to store contents into
+ char *filename = new char[ strlen(url) + strlen(copydir) + strlen(index) ];
+ assert( filename != 0 );
+ strcpy( filename, copydir );
+ strcat( filename, "/" );
+ char* here = filename + strlen(filename);
+ strcat( filename, ptr+3 );
- // handle directories (e.g. "http://www.focus.de/A/" )
- if ( filename[strlen(filename)-1] == '/' ) strcat( filename, index );
+ // handle server root (e.g. "http://www.focus.de" )
+ if ( strchr( ptr+3, '/' ) == 0 ) strcat( filename, "/" );
- // create subdirectory structure
- for ( char* t = strchr(here,'/'); t; t = strchr(t,'/') ) {
- *t = 0;
- if ( mkdir( filename, 0775 ) == -1 && errno != EEXIST ) {
- fprintf( stderr, "mkdir(%s): %s\n", filename, strerror(errno) );
- delete[] filename;
- return false;
- } else if ( debug & 0x02 ) {
- fprintf( stderr, "# creating %s\n", filename );
+ // handle directories (e.g. "http://www.focus.de/A/" )
+ if ( filename[strlen(filename)-1] == '/' ) strcat( filename, index );
+
+ // create subdirectory structure
+ for ( char* t = strchr(here,'/'); t; t = strchr(t,'/') ) {
+ *t = 0;
+ if ( mkdir( filename, 0775 ) == -1 && errno != EEXIST ) {
+ fprintf( stderr, "mkdir(%s): %s\n", filename, strerror(errno) );
+ delete[] filename;
+ return false;
+ } else if ( debug & 0x02 ) {
+ fprintf( stderr, "# creating %s\n", filename );
+ }
+ *t++ = '/';
}
- *t++ = '/';
- }
- // create file
- int out = open( filename, O_CREAT | O_RDWR | O_TRUNC, 0664 );
- if ( out == -1 ) {
- fprintf( stderr, "open(%s,RDWR): %s\n", filename, strerror(errno) );
- delete[] filename;
- return false;
- } else if ( debug & 0x02 ) {
- fprintf( stderr, "# creating %s\n", filename );
- }
+ // create file
+ int out = open( filename, O_CREAT | O_RDWR | O_TRUNC, 0664 );
+ if ( out == -1 ) {
+ fprintf( stderr, "open(%s,RDWR): %s\n", filename, strerror(errno) );
+ delete[] filename;
+ return false;
+ } else if ( debug & 0x02 ) {
+ fprintf( stderr, "# creating %s\n", filename );
+ }
- // (re)open cache file
- int input = open( fn, O_RDONLY );
- if ( input == -1 ) {
- fprintf( stderr, "open(%s,RDONLY): %s\n", fn, strerror(errno) );
- delete[] filename;
- close(out);
- return false;
- }
+ // (re)open cache file
+ int input = open( fn, O_RDONLY );
+ if ( input == -1 ) {
+ fprintf( stderr, "open(%s,RDONLY): %s\n", fn, strerror(errno) );
+ delete[] filename;
+ close(out);
+ return false;
+ }
- // find double CRLF sequence (actually, look at the FSM below)
- // FIXME: this only looks at the already known buffer read previously,
- // which is globally passed (yuck)! As a limitation, the content data
- // *must* begin within the buffer size (that is: 16k)!
- if ( ! copyHdr ) {
- extern char* linebuffer; // import from purge.cc
- extern size_t buffersize; // import from purge.cc
+ // find double CRLF sequence (actually, look at the FSM below)
+ // FIXME: this only looks at the already known buffer read previously,
+ // which is globally passed (yuck)! As a limitation, the content data
+ // *must* begin within the buffer size (that is: 16k)!
+ if ( ! copyHdr ) {
+ extern char* linebuffer; // import from purge.cc
+ extern size_t buffersize; // import from purge.cc
- unsigned state = 0;
- char* s = linebuffer + metasize;
- while ( s < linebuffer + buffersize && state < 4 ) {
- // state transition machine
- static unsigned table[4][3] = { {3,2,0}, {0,4,0}, {1,4,0}, {4,2,0} };
- // old || \r | \n |else|
- // =====++====+====+====+
- // 0 || 3 | 2 | 0 |
- // 1 || 0 | 4 | 0 |
- // 2 || 1 | 4 | 0 |
- // 3 || 4 | 2 | 0 |
- state = table[ state ][ xlate(*s++) ];
- }
+ unsigned state = 0;
+ char* s = linebuffer + metasize;
+ while ( s < linebuffer + buffersize && state < 4 ) {
+ // state transition machine
+ static unsigned table[4][3] = { {3,2,0}, {0,4,0}, {1,4,0}, {4,2,0} };
+ // old || \r | \n |else|
+ // =====++====+====+====+
+ // 0 || 3 | 2 | 0 |
+ // 1 || 0 | 4 | 0 |
+ // 2 || 1 | 4 | 0 |
+ // 3 || 4 | 2 | 0 |
+ state = table[ state ][ xlate(*s++) ];
+ }
- if ( state < 4 )
- // complain bitterly, if the HTTP header was too large ( > 16k ).
- fprintf( stderr, "WARNING: %s will contain partial HTTP header data!\n",
- filename );
+ if ( state < 4 )
+ // complain bitterly, if the HTTP header was too large ( > 16k ).
+ fprintf( stderr, "WARNING: %s will contain partial HTTP header data!\n",
+ filename );
- // adjust to different seek size
- metasize = s - linebuffer;
- }
+ // adjust to different seek size
+ metasize = s - linebuffer;
+ }
- // no need to copy zero content files
- if ( filesize - metasize <= 0 ) {
- BAUTZ( filesize-metasize == 0 );
- }
+ // no need to copy zero content files
+ if ( filesize - metasize <= 0 ) {
+ BAUTZ( filesize-metasize == 0 );
+ }
#ifdef USE_REGULAR_COPY
- // position input at start of server answer (contains HTTP headers)
- if ( lseek( input, metasize, SEEK_SET ) == -1 ) {
- fprintf( stderr, "lseek(%s,%lu): %s\n", fn, metasize, strerror(errno) );
- BAUTZ(false);
- }
+ // position input at start of server answer (contains HTTP headers)
+ if ( lseek( input, metasize, SEEK_SET ) == -1 ) {
+ fprintf( stderr, "lseek(%s,%lu): %s\n", fn, metasize, strerror(errno) );
+ BAUTZ(false);
+ }
- // file copy input into output via buffer (regular io)
- char buffer[32768];
- int rsize, wsize;
- while ( (rsize=read(input,buffer,sizeof(buffer))) > 0 ) {
- if ( (wsize=write(out,buffer,rsize)) <= 0 ) break;
- }
- if ( rsize < 0 || wsize < 0 ) perror( "while copying" );
+ // file copy input into output via buffer (regular io)
+ char buffer[32768];
+ int rsize, wsize;
+ while ( (rsize=read(input,buffer,sizeof(buffer))) > 0 ) {
+ if ( (wsize=write(out,buffer,rsize)) <= 0 ) break;
+ }
+ if ( rsize < 0 || wsize < 0 ) perror( "while copying" );
#else // use mmap copy (compare: Stevens APUE 12.9)
- // precondition: filesize-metasize > 0
- // seek end of output file ...
- off_t position = lseek( out, filesize-metasize-1, SEEK_SET );
- if ( position == -1 ) {
- fprintf( stderr, "lseek(%s,%lu): %s\n", filename, filesize-metasize,
- strerror(errno) );
- BAUTZ(false);
- } else if ( debug & 0x02 ) {
- fprintf( stderr, "# filesize=%lu, metasize=%lu, filepos=%ld\n",
- filesize, metasize, position );
- }
-
- // ...and write 1 byte there (create a file that length)
- if ( write( out, "", 1 ) != 1 ) {
- perror( "write to output" );
- BAUTZ(false);
- }
+ // precondition: filesize-metasize > 0
+ // seek end of output file ...
+ off_t position = lseek( out, filesize-metasize-1, SEEK_SET );
+ if ( position == -1 ) {
+ fprintf( stderr, "lseek(%s,%lu): %s\n", filename, filesize-metasize,
+ strerror(errno) );
+ BAUTZ(false);
+ } else if ( debug & 0x02 ) {
+ fprintf( stderr, "# filesize=%lu, metasize=%lu, filepos=%ld\n",
+ filesize, metasize, position );
+ }
- // create source mmap to copy from (mmap complete file)
- caddr_t src = (caddr_t) mmap( 0, filesize, PROT_READ,
- MAP_FILE | MAP_SHARED, input, 0 );
- if ( src == (caddr_t) -1 ) {
- perror( "mmap input" );
- BAUTZ(false);
- }
+ // ...and write 1 byte there (create a file that length)
+ if ( write( out, "", 1 ) != 1 ) {
+ perror( "write to output" );
+ BAUTZ(false);
+ }
- // create destination mmap to copy into (mmap data portion)
- caddr_t dst = (caddr_t) mmap( 0, filesize-metasize, PROT_READ | PROT_WRITE,
- MAP_FILE | MAP_SHARED, out, 0 );
- if ( dst == (caddr_t) -1 ) {
- perror( "mmap output" );
- munmap( src, filesize );
- BAUTZ(false);
- }
+ // create source mmap to copy from (mmap complete file)
+ caddr_t src = (caddr_t) mmap( 0, filesize, PROT_READ,
+ MAP_FILE | MAP_SHARED, input, 0 );
+ if ( src == (caddr_t) -1 ) {
+ perror( "mmap input" );
+ BAUTZ(false);
+ }
+
+ // create destination mmap to copy into (mmap data portion)
+ caddr_t dst = (caddr_t) mmap( 0, filesize-metasize, PROT_READ | PROT_WRITE,
+ MAP_FILE | MAP_SHARED, out, 0 );
+ if ( dst == (caddr_t) -1 ) {
+ perror( "mmap output" );
+ munmap( src, filesize );
+ BAUTZ(false);
+ }
- // copy file (beware of offset into wanted data, skip meta data)
- memcpy( dst, src+metasize, filesize-metasize );
+ // copy file (beware of offset into wanted data, skip meta data)
+ memcpy( dst, src+metasize, filesize-metasize );
- // clean up
- munmap( dst, filesize-metasize );
- munmap( src, filesize );
+ // clean up
+ munmap( dst, filesize-metasize );
+ munmap( src, filesize );
#endif // USE_REGULAR_COPY
- BAUTZ(true);
+ BAUTZ(true);
}
unsigned char
xlate( unsigned char ch )
{
- return (isprint(ch & 0x7f) ? ch : '.');
+ return (isprint(ch & 0x7f) ? ch : '.');
}
typedef struct {
- int fd, rsize, cursor;
- size_t bufsize;
- unsigned char* buffer;
+ int fd, rsize, cursor;
+ size_t bufsize;
+ unsigned char* buffer;
} InputByByte;
int
in_open( InputByByte* this, const char* fn, size_t size )
{
- if ( (this->fd = open( fn, O_RDONLY )) == -1 ) return -1;
- if ( (this->buffer=(unsigned char*) malloc(size)) == 0 ) {
- close(this->fd);
- return -1;
- }
- this->bufsize = size;
- this->rsize = this->cursor = 0;
- return 0;
+ if ( (this->fd = open( fn, O_RDONLY )) == -1 ) return -1;
+ if ( (this->buffer=(unsigned char*) malloc(size)) == 0 ) {
+ close(this->fd);
+ return -1;
+ }
+ this->bufsize = size;
+ this->rsize = this->cursor = 0;
+ return 0;
}
int
in_get( InputByByte* this )
- /*
- * purpose: read next character
- * returns: 0..255 as valid character, -1 for error, -2 for EOF
- */
+/*
+ * purpose: read next character
+ * returns: 0..255 as valid character, -1 for error, -2 for EOF
+ */
{
- if ( this->cursor >= this->rsize ) {
- do {
- this->rsize = read( this->fd, this->buffer, this->bufsize );
- } while ( this->rsize == -1 && errno == EINTR );
- if ( this->rsize > 0 ) this->cursor = 0;
- else return ((-2) - this->rsize);
- }
+ if ( this->cursor >= this->rsize ) {
+ do {
+ this->rsize = read( this->fd, this->buffer, this->bufsize );
+ } while ( this->rsize == -1 && errno == EINTR );
+ if ( this->rsize > 0 ) this->cursor = 0;
+ else return ((-2) - this->rsize);
+ }
- return this->buffer[this->cursor++];
+ return this->buffer[this->cursor++];
}
int
in_close( InputByByte* this )
{
- free((void*) this->buffer);
- return close(this->fd);
+ free((void*) this->buffer);
+ return close(this->fd);
}
int
main( int argc, char* argv[] )
{
- int ch, i;
- unsigned line = 0;
- InputByByte in;
- char b2[20];
-
- if ( argc != 2 ) {
- fprintf( stderr, "Usage: %s filename\n", argv[0] );
- return 1;
- }
+ int ch, i;
+ unsigned line = 0;
+ InputByByte in;
+ char b2[20];
+
+ if ( argc != 2 ) {
+ fprintf( stderr, "Usage: %s filename\n", argv[0] );
+ return 1;
+ }
- if ( in_open(&in,argv[1],32768) == -1 ) {
- perror( "open" );
- return 1;
- }
+ if ( in_open(&in,argv[1],32768) == -1 ) {
+ perror( "open" );
+ return 1;
+ }
- for ( ch = in_get(&in); ch >= 0; ) {
- printf( "%08X: ", line );
- memset( b2, 0, sizeof(b2) );
- for ( i=0; i < 16 && ch >= 0; i++ ) {
- printf( "%02X%c", ch, ((i==7) ? '-' : ' ' ) );
- b2[i] = xlate(ch);
- ch = in_get(&in);
+ for ( ch = in_get(&in); ch >= 0; ) {
+ printf( "%08X: ", line );
+ memset( b2, 0, sizeof(b2) );
+ for ( i=0; i < 16 && ch >= 0; i++ ) {
+ printf( "%02X%c", ch, ((i==7) ? '-' : ' ' ) );
+ b2[i] = xlate(ch);
+ ch = in_get(&in);
+ }
+ line += i;
+ for ( ; i<16; i++ ) fputs(" ",stdout);
+ printf( " %s\n", b2 );
}
- line += i;
- for ( ; i<16; i++ ) fputs(" ",stdout);
- printf( " %s\n", b2 );
- }
-
- return in_close(&in);
+
+ return in_close(&in);
}
#endif // DEFAULTPORT
volatile sig_atomic_t term_flag = 0; // 'terminate' is a gcc 2.8.x internal...
- char* linebuffer = 0;
- size_t buffersize = 16834;
+char* linebuffer = 0;
+size_t buffersize = 16834;
static char* copydir = 0;
static unsigned debug = 0;
static unsigned purgeMode = 0;
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 $";
+ "$Id: purge.cc,v 1.17 2000/09/21 10:59:53 cached Exp $";
// ----------------------------------------------------------------------
struct REList {
- REList( const char* what, bool doCase );
- ~REList();
- bool match( const char* check ) const;
+ REList( const char* what, bool doCase );
+ ~REList();
+ bool match( const char* check ) const;
- REList* next;
- const char* data;
- regex_t rexp;
+ REList* next;
+ const char* data;
+ regex_t rexp;
};
REList::REList( const char* what, bool doCase )
- :next(0),data(strdup(what))
+ :next(0),data(strdup(what))
{
- int result = regcomp( &rexp, what,
- REG_EXTENDED | REG_NOSUB | (doCase ? 0 : REG_ICASE) );
- if ( result != 0 ) {
- char buffer[256];
- regerror( result, &rexp, buffer, 256 );
- fprintf( stderr, "unable to compile re \"%s\": %s\n", what, buffer );
- exit(1);
- }
+ int result = regcomp( &rexp, what,
+ REG_EXTENDED | REG_NOSUB | (doCase ? 0 : REG_ICASE) );
+ if ( result != 0 ) {
+ char buffer[256];
+ regerror( result, &rexp, buffer, 256 );
+ fprintf( stderr, "unable to compile re \"%s\": %s\n", what, buffer );
+ exit(1);
+ }
}
REList::~REList()
-{
- if ( next ) delete next;
- if ( data ) free((void*) data);
- regfree(&rexp);
+{
+ if ( next ) delete next;
+ if ( data ) free((void*) data);
+ regfree(&rexp);
}
bool
REList::match( const char* check ) const
{
- int result = regexec( &rexp, check, 0, 0, 0 );
- if ( result != 0 && result != REG_NOMATCH ) {
- char buffer[256];
- regerror( result, &rexp, buffer, 256 );
- fprintf( stderr, "unable to execute re \"%s\"\n+ on line \"%s\": %s\n",
- data, check, buffer );
- exit(1);
- }
- return ( result == 0 );
+ int result = regexec( &rexp, check, 0, 0, 0 );
+ if ( result != 0 && result != REG_NOMATCH ) {
+ char buffer[256];
+ regerror( result, &rexp, buffer, 256 );
+ fprintf( stderr, "unable to execute re \"%s\"\n+ on line \"%s\": %s\n",
+ data, check, buffer );
+ exit(1);
+ }
+ return ( result == 0 );
}
// ----------------------------------------------------------------------
char*
concat( const char* start, ... )
- // purpose: concatinate an arbitrary number of C strings.
- // paramtr: start (IN): first C string
- // ... (IN): further C strings, terminated with a NULL pointer
- // returns: memory allocated via new(), containing the concatinated string.
+// purpose: concatinate an arbitrary number of C strings.
+// paramtr: start (IN): first C string
+// ... (IN): further C strings, terminated with a NULL pointer
+// returns: memory allocated via new(), containing the concatinated string.
{
- va_list ap;
- const char* s;
-
- // 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 : "");
- va_end(ap);
-
- // allocate
- char* result = new char[size];
- if ( result == 0 ) {
- perror( "string memory allocation" );
- exit(1);
- }
-
- // second run: copy content
- strcpy( result, start );
- va_start( ap, start );
- while ( (s=va_arg(ap,const char*)) != NULL ) strcat( result, s );
- va_end(ap);
-
- return result;
+ va_list ap;
+ const char* s;
+
+ // 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 : "");
+ va_end(ap);
+
+ // allocate
+ char* result = new char[size];
+ if ( result == 0 ) {
+ perror( "string memory allocation" );
+ exit(1);
+ }
+
+ // second run: copy content
+ strcpy( result, start );
+ va_start( ap, start );
+ while ( (s=va_arg(ap,const char*)) != NULL ) strcat( result, s );
+ va_end(ap);
+
+ return result;
}
bool
isxstring( const char* s, size_t testlen )
- // purpose: test a string for conforming to xdigit
- // paramtr: s (IN): string to test
- // testlen (IN): length the string must have
- // returns: true, iff strlen(s)==testlen && all_x_chars(s), false otherwise
+// purpose: test a string for conforming to xdigit
+// paramtr: s (IN): string to test
+// testlen (IN): length the string must have
+// returns: true, iff strlen(s)==testlen && all_x_chars(s), false otherwise
{
- if ( strlen(s) != testlen ) return false;
+ if ( strlen(s) != testlen ) return false;
- size_t i=0;
- while ( i<testlen && isxdigit(s[i]) ) i++;
- return (i==testlen);
+ size_t i=0;
+ while ( i<testlen && isxdigit(s[i]) ) i++;
+ return (i==testlen);
}
inline
int
log_output( const char* fn, int code, long size, const char* url )
{
- return printf( "%s %3d %8ld %s\n", fn, code, size, url );
+ return printf( "%s %3d %8ld %s\n", fn, code, size, url );
}
static
int
log_extended( const char* fn, int code, long size, const SquidMetaList* meta )
{
- static const char hexdigit[] = "0123456789ABCDEF";
- char md5[34];
- const SquidTLV* findings = 0;
-
- if ( meta && (findings = meta->search( STORE_META_KEY_MD5 )) ) {
- unsigned char* s = (unsigned char*) findings->data;
- for ( int j=0; j<16; j++, s++ ) {
- md5[j*2+0] = hexdigit[ *s >> 4 ];
- md5[j*2+1] = hexdigit[ *s & 15 ];
+ static const char hexdigit[] = "0123456789ABCDEF";
+ char md5[34];
+ const SquidTLV* findings = 0;
+
+ if ( meta && (findings = meta->search( STORE_META_KEY_MD5 )) ) {
+ unsigned char* s = (unsigned char*) findings->data;
+ 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)" );
+ }
+
+ char timeb[64];
+ if ( meta && (findings = meta->search( STORE_META_STD )) ) {
+ 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 );
+ } 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 );
+ } else {
+ sprintf( timeb, "%08x %08x %08x %08x %04x %5hu ", -1, -1, -1, -1, 0, 0 );
+ }
+
+ // make sure that there is just one printf()
+ if ( meta && (findings = meta->search( STORE_META_URL )) ) {
+ return printf( "%s %3d %8ld %s %s %s\n",
+ fn, code, size, md5, timeb, findings->data );
+ } else {
+ return printf( "%s %3d %8ld %s %s strange_file\n",
+ fn, code, size, md5, timeb );
}
- md5[32] = '\0'; // terminate string
- } else {
- sprintf( md5, "%-32s", "(no_md5_data_available)" );
- }
-
- char timeb[64];
- if ( meta && (findings = meta->search( STORE_META_STD )) ) {
- 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 );
- } 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 );
- } else {
- sprintf( timeb, "%08x %08x %08x %08x %04x %5hu ", -1, -1, -1, -1, 0, 0 );
- }
-
- // make sure that there is just one printf()
- if ( meta && (findings = meta->search( STORE_META_URL )) ) {
- return printf( "%s %3d %8ld %s %s %s\n",
- fn, code, size, md5, timeb, findings->data );
- } else {
- return printf( "%s %3d %8ld %s %s strange_file\n",
- fn, code, size, md5, timeb );
- }
}
// o.k., this is pure lazyness...
bool
action( int fd, size_t metasize,
- const char* fn, const char* url, const SquidMetaList& meta )
- // purpose: if cmdline-requested, send the purge request to the cache
- // paramtr: fd (IN): open FD for the object file
- // metasize (IN): offset into data portion of file (meta data size)
- // fn (IN): name of the object file
- // url (IN): URL string stored in the object file
- // meta (IN): list containing further meta data
- // returns: true for a successful action, false otherwise. The action
- // may just print the file, send the purge request or even
- // remove unwanted files.
- // globals: ::purgeMode (IN): bit#0 set -> send purge request.
- // bit#1 set -> remove 404 object files.
- // ::serverHost (IN): cache host address
- // ::serverPort (IN): cache port number
+ const char* fn, const char* url, const SquidMetaList& meta )
+// purpose: if cmdline-requested, send the purge request to the cache
+// paramtr: fd (IN): open FD for the object file
+// metasize (IN): offset into data portion of file (meta data size)
+// fn (IN): name of the object file
+// url (IN): URL string stored in the object file
+// meta (IN): list containing further meta data
+// returns: true for a successful action, false otherwise. The action
+// may just print the file, send the purge request or even
+// remove unwanted files.
+// globals: ::purgeMode (IN): bit#0 set -> send purge request.
+// bit#1 set -> remove 404 object files.
+// ::serverHost (IN): cache host address
+// ::serverPort (IN): cache port number
{
- 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,
- fn, url, ::copydir, ::envelope );
-
- // do we need to PURGE the file, yes, if purgemode bit#0 was set.
- if ( ::purgeMode & 0x01 ) {
- unsigned long bufsize = strlen(url) + strlen(schablone) + 4;
- char* buffer = new char[bufsize];
-
- sprintf( buffer, schablone, url );
- int sockfd = connectTo( serverHost, serverPort, true );
- if ( sockfd == -1 ) {
- fprintf( stderr, "unable to connect to server: %s\n", strerror(errno) );
- delete[] buffer;
- return false;
- }
-
- int size = strlen(buffer);
- if ( write( sockfd, buffer, size ) != size ) {
- // error while talking to squid
- fprintf( stderr, "unable to talk to server: %s\n", strerror(errno) );
- close(sockfd);
- delete[] buffer;
- return false;
+ 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,
+ fn, url, ::copydir, ::envelope );
+
+ // do we need to PURGE the file, yes, if purgemode bit#0 was set.
+ if ( ::purgeMode & 0x01 ) {
+ unsigned long bufsize = strlen(url) + strlen(schablone) + 4;
+ char* buffer = new char[bufsize];
+
+ sprintf( buffer, schablone, url );
+ int sockfd = connectTo( serverHost, serverPort, true );
+ if ( sockfd == -1 ) {
+ fprintf( stderr, "unable to connect to server: %s\n", strerror(errno) );
+ delete[] buffer;
+ return false;
+ }
+
+ int size = strlen(buffer);
+ if ( write( sockfd, buffer, size ) != size ) {
+ // error while talking to squid
+ fprintf( stderr, "unable to talk to server: %s\n", strerror(errno) );
+ close(sockfd);
+ delete[] buffer;
+ return false;
+ }
+ memset( buffer+8, 0, 4 );
+ if ( read( sockfd, buffer, bufsize ) < 1 ) {
+ // error while reading squid's answer
+ fprintf( stderr, "unable to read answer: %s\n", strerror(errno) );
+ close(sockfd);
+ delete[] buffer;
+ return false;
+ }
+ close(sockfd);
+ status = strtol(buffer+8,0,10);
+ delete[] buffer;
}
- memset( buffer+8, 0, 4 );
- if ( read( sockfd, buffer, bufsize ) < 1 ) {
- // error while reading squid's answer
- fprintf( stderr, "unable to read answer: %s\n", strerror(errno) );
- close(sockfd);
- delete[] buffer;
- return false;
+
+ // log the output of our operation
+ bool flag = true;
+ if ( ::verbose ) flag = ( log_extended( fn, status, size, &meta ) >= 0 );
+ else flag = ( log_output( fn, status, size, url ) >= 0 );
+
+ // remove the file, if purgemode bit#1, and HTTP result status 404).
+ if ( (::purgeMode & 0x02) && status == 404 ) {
+ reminder = true;
+ if ( unlink(fn) == -1 )
+ // error while unlinking file, this may happen due to the cache
+ // unlinking a file while it is still in the readdir() cache of purge.
+ fprintf( stderr, "WARNING: unable to unlink %s: %s\n",
+ fn, strerror(errno) );
}
- close(sockfd);
- status = strtol(buffer+8,0,10);
- delete[] buffer;
- }
-
- // log the output of our operation
- bool flag = true;
- if ( ::verbose ) flag = ( log_extended( fn, status, size, &meta ) >= 0 );
- else flag = ( log_output( fn, status, size, url ) >= 0 );
-
- // remove the file, if purgemode bit#1, and HTTP result status 404).
- if ( (::purgeMode & 0x02) && status == 404 ) {
- reminder = true;
- if ( unlink(fn) == -1 )
- // error while unlinking file, this may happen due to the cache
- // unlinking a file while it is still in the readdir() cache of purge.
- fprintf( stderr, "WARNING: unable to unlink %s: %s\n",
- fn, strerror(errno) );
- }
-
- return flag;
+
+ return flag;
}
bool
match( const char* fn, const REList* list )
- // purpose: do something with the given cache content filename
- // paramtr: fn (IN): filename of cache file
- // returns: true for successful action, false otherwise.
- // warning: only return false, if you want the loop to terminate!
+// purpose: do something with the given cache content filename
+// paramtr: fn (IN): filename of cache file
+// returns: true for successful action, false otherwise.
+// warning: only return false, if you want the loop to terminate!
{
- static const size_t addon = sizeof(unsigned char) + sizeof(unsigned int);
- bool flag = true;
-
- if ( debug & 0x01 ) fprintf( stderr, "# [3] %s\n", fn );
- int fd = open( fn, O_RDONLY );
- if ( fd != -1 ) {
- if ( read(fd,::linebuffer,::buffersize-1) > 60 ) {
- ::linebuffer[ ::buffersize-1 ] = '\0'; // force-terminate string
-
- // check the offset into the start of object data. The offset is
- // stored in a host endianess after the first byte.
- unsigned int datastart;
- memcpy( &datastart, ::linebuffer + 1, sizeof(unsigned int) );
- if ( datastart > ::buffersize - addon - 1 ) {
- // check offset into server reply header (start of cache data).
- fputs( "WARNING: Using a truncated URL string.\n", stderr );
- datastart = ::buffersize - addon - 1;
- }
-
- // NEW: Parse squid meta data, which is a kind of linked list
- // flattened out into a file byte stream. Somewhere within is
- // the URL as part of the list. First, gobble all meta data.
- unsigned int offset = addon;
- SquidMetaList meta;
- while ( offset + addon <= datastart ) {
- unsigned int size = 0;
- memcpy( &size, linebuffer+offset+sizeof(char), sizeof(unsigned int) );
- meta.append( SquidMetaType(*(linebuffer+offset)),
- size, linebuffer+offset+addon );
- offset += ( addon + size );
- }
-
- // Now extract the key URL from the meta data.
- const SquidTLV* urlmeta = meta.search( STORE_META_URL );
- if ( urlmeta ) {
- // found URL in meta data. Try to process the URL
- if ( list == 0 )
- flag = action( fd, datastart, fn, (char*) urlmeta->data, meta );
- else {
- REList* head = (REList*) list; // YUCK!
- while ( head != 0 ) {
- if ( head->match( (char*) urlmeta->data ) ) break;
- head = head->next;
- }
- if ( head != 0 )
- flag = action( fd, datastart, fn, (char*) urlmeta->data, meta );
- else flag = true;
- }
- }
-
- // "meta" will be deleted when exiting from this block
+ static const size_t addon = sizeof(unsigned char) + sizeof(unsigned int);
+ bool flag = true;
+
+ if ( debug & 0x01 ) fprintf( stderr, "# [3] %s\n", fn );
+ int fd = open( fn, O_RDONLY );
+ if ( fd != -1 ) {
+ if ( read(fd,::linebuffer,::buffersize-1) > 60 ) {
+ ::linebuffer[ ::buffersize-1 ] = '\0'; // force-terminate string
+
+ // check the offset into the start of object data. The offset is
+ // stored in a host endianess after the first byte.
+ unsigned int datastart;
+ memcpy( &datastart, ::linebuffer + 1, sizeof(unsigned int) );
+ if ( datastart > ::buffersize - addon - 1 ) {
+ // check offset into server reply header (start of cache data).
+ fputs( "WARNING: Using a truncated URL string.\n", stderr );
+ datastart = ::buffersize - addon - 1;
+ }
+
+ // NEW: Parse squid meta data, which is a kind of linked list
+ // flattened out into a file byte stream. Somewhere within is
+ // the URL as part of the list. First, gobble all meta data.
+ unsigned int offset = addon;
+ SquidMetaList meta;
+ while ( offset + addon <= datastart ) {
+ unsigned int size = 0;
+ memcpy( &size, linebuffer+offset+sizeof(char), sizeof(unsigned int) );
+ meta.append( SquidMetaType(*(linebuffer+offset)),
+ size, linebuffer+offset+addon );
+ offset += ( addon + size );
+ }
+
+ // Now extract the key URL from the meta data.
+ const SquidTLV* urlmeta = meta.search( STORE_META_URL );
+ if ( urlmeta ) {
+ // found URL in meta data. Try to process the URL
+ if ( list == 0 )
+ flag = action( fd, datastart, fn, (char*) urlmeta->data, meta );
+ else {
+ REList* head = (REList*) list; // YUCK!
+ while ( head != 0 ) {
+ if ( head->match( (char*) urlmeta->data ) ) break;
+ head = head->next;
+ }
+ if ( head != 0 )
+ flag = action( fd, datastart, fn, (char*) urlmeta->data, meta );
+ else flag = true;
+ }
+ }
+
+ // "meta" will be deleted when exiting from this block
+ } else {
+ // weird file, FIXME: stat() it!
+ struct stat st;
+ long size = ( fstat(fd,&st) == -1 ? -1 : st.st_size );
+ if ( ::verbose ) flag = ( log_extended( fn, -1, size, 0 ) >= 0 );
+ else flag = ( log_output( fn, -1, size, "strange file" ) >= 0 );
+
+ if ( (::purgeMode & 0x04) ) {
+ reminder = true;
+ if ( unlink(fn) == -1 )
+ // error while unlinking file, this may happen due to the cache
+ // unlinking a file while it is in the readdir() cache of purge.
+ fprintf( stderr, "WARNING: unable to unlink %s: %s\n",
+ fn, strerror(errno) );
+ }
+ }
+ close(fd);
} else {
- // weird file, FIXME: stat() it!
- struct stat st;
- long size = ( fstat(fd,&st) == -1 ? -1 : st.st_size );
- if ( ::verbose ) flag = ( log_extended( fn, -1, size, 0 ) >= 0 );
- else flag = ( log_output( fn, -1, size, "strange file" ) >= 0 );
-
- if ( (::purgeMode & 0x04) ) {
- reminder = true;
- if ( unlink(fn) == -1 )
- // error while unlinking file, this may happen due to the cache
- // unlinking a file while it is in the readdir() cache of purge.
- fprintf( stderr, "WARNING: unable to unlink %s: %s\n",
- fn, strerror(errno) );
- }
+ // error while opening file, this may happen due to the cache
+ // unlinking a file while it is still in the readdir() cache of purge.
+ fprintf( stderr, "WARNING: open \"%s\": %s\n", fn, strerror(errno) );
}
- close(fd);
- } else {
- // error while opening file, this may happen due to the cache
- // unlinking a file while it is still in the readdir() cache of purge.
- fprintf( stderr, "WARNING: open \"%s\": %s\n", fn, strerror(errno) );
- }
-
- return flag;
+
+ return flag;
}
bool
filelevel( const char* directory, const REList* list )
- // purpose: from given starting point, look for squid xxxxxxxx files.
- // example: "/var/spool/cache/08/7F" as input, do action over files
- // paramtr: directory (IN): starting point
- // list (IN): list of rexps to match URLs against
- // returns: true, if every subdir && action was successful.
+// purpose: from given starting point, look for squid xxxxxxxx files.
+// example: "/var/spool/cache/08/7F" as input, do action over files
+// paramtr: directory (IN): starting point
+// list (IN): list of rexps to match URLs against
+// returns: true, if every subdir && action was successful.
{
- struct dirent* entry;
- if ( debug & 0x01 )
- fprintf( stderr, "# [2] %s\n", directory );
-
- DIR* dir = opendir( directory );
- if ( dir == NULL ) {
- fprintf( stderr, "unable to open directory \"%s\": %s\n",
- directory, strerror(errno) );
- return false;
- }
-
- // display a rotating character as "i am alive" signal (slows purge).
- 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 );
- }
-
- bool flag = true;
- while ( (entry=readdir(dir)) && flag ) {
- if ( isxstring(entry->d_name,8) ) {
- char* name = concat( directory, "/", entry->d_name, 0 );
- flag = match( name, list );
- delete[] name;
+ struct dirent* entry;
+ if ( debug & 0x01 )
+ fprintf( stderr, "# [2] %s\n", directory );
+
+ DIR* dir = opendir( directory );
+ if ( dir == NULL ) {
+ fprintf( stderr, "unable to open directory \"%s\": %s\n",
+ directory, strerror(errno) );
+ return false;
+ }
+
+ // display a rotating character as "i am alive" signal (slows purge).
+ 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 );
+ }
+
+ bool flag = true;
+ while ( (entry=readdir(dir)) && flag ) {
+ if ( isxstring(entry->d_name,8) ) {
+ char* name = concat( directory, "/", entry->d_name, 0 );
+ flag = match( name, list );
+ delete[] name;
+ }
}
- }
- closedir(dir);
- return flag;
+ closedir(dir);
+ return flag;
}
bool
dirlevel( const char* dirname, const REList* list, bool level=false )
- // purpose: from given starting point, look for squid 00..FF directories.
- // paramtr: dirname (IN): starting point
- // list (IN): list of rexps to match URLs against
- // level (IN): false==toplevel, true==1st level
- // example: "/var/spool/cache", false as input, traverse subdirs w/ action.
- // example: "/var/spool/cache/08", true as input, traverse subdirs w/ action.
- // returns: true, if every subdir && action was successful.
- // warning: this function is once-recursive, no deeper.
+// purpose: from given starting point, look for squid 00..FF directories.
+// paramtr: dirname (IN): starting point
+// list (IN): list of rexps to match URLs against
+// level (IN): false==toplevel, true==1st level
+// example: "/var/spool/cache", false as input, traverse subdirs w/ action.
+// example: "/var/spool/cache/08", true as input, traverse subdirs w/ action.
+// returns: true, if every subdir && action was successful.
+// warning: this function is once-recursive, no deeper.
{
- struct dirent* entry;
- if ( debug & 0x01 )
- fprintf( stderr, "# [%d] %s\n", (level ? 1 : 0), dirname );
-
- DIR* dir = opendir( dirname );
- if ( dir == NULL ) {
- fprintf( stderr, "unable to open directory \"%s\": %s\n",
- dirname, strerror(errno) );
- return false;
- }
-
- bool flag = true;
- while ( (entry=readdir(dir)) && flag ) {
- if ( strlen(entry->d_name) == 2 &&
- isxdigit(entry->d_name[0]) &&
- isxdigit(entry->d_name[1]) ) {
- char* name = concat( dirname, "/", entry->d_name, 0 );
- flag = level ? filelevel( name, list ) : dirlevel( name, list, true );
- delete[] name;
+ struct dirent* entry;
+ if ( debug & 0x01 )
+ fprintf( stderr, "# [%d] %s\n", (level ? 1 : 0), dirname );
+
+ DIR* dir = opendir( dirname );
+ if ( dir == NULL ) {
+ fprintf( stderr, "unable to open directory \"%s\": %s\n",
+ dirname, strerror(errno) );
+ return false;
}
- }
- closedir(dir);
- return flag;
+ bool flag = true;
+ while ( (entry=readdir(dir)) && flag ) {
+ if ( strlen(entry->d_name) == 2 &&
+ isxdigit(entry->d_name[0]) &&
+ isxdigit(entry->d_name[1]) ) {
+ char* name = concat( dirname, "/", entry->d_name, 0 );
+ flag = level ? filelevel( name, list ) : dirlevel( name, list, true );
+ delete[] name;
+ }
+ }
+
+ closedir(dir);
+ return flag;
}
int
checkForPortOnly( const char* optarg )
- // 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
+// 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 there is a period in there, it must be a valid hostname
+ if ( strchr( optarg, '.' ) != 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);
+ // 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);
#if 0
- // one last try, test for a symbolical service name
- struct servent* service = getservbyname( optarg, "tcp" );
- return service ? service->s_port : -1;
+ // one last try, test for a symbolical service name
+ struct servent* service = getservbyname( optarg, "tcp" );
+ return service ? service->s_port : -1;
#else
- return -1;
+ return -1;
#endif
}
void
helpMe( void )
- // purpuse: write help message and exit
+// purpuse: write help message and exit
{
- printf( "\n%s\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 );
- 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"
-" -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"
-" -F fn\tname of textfile like -f containing case sensitive REs.\n"
-" -H\tprepend HTTP reply header to destination files in copy-out mode.\n"
-" -n\tdo not fork() when using more than one cache_dir.\n"
-" -p h:p\tcache runs on host h and optional port p, default is %s:%u.\n"
-" -P #\tif 0, just print matches; otherwise OR the following purge modes:\n"
-"\t 0x01 really send PURGE to the cache.\n"
-"\t 0x02 remove all caches files reported as 404 (not found).\n"
-"\t 0x04 remove all weird (inaccessible or too small) cache files.\n"
-"\t0 and 1 are recommended - slow rebuild your cache with other modes.\n"
-" -s\tshow all options after option parsing, but before really starting.\n"
-" -v\tshow more information about the file, e.g. MD5, timestamps and flags.\n"
-"\n", DEFAULT_SQUID_CONF, DEFAULTHOST, DEFAULTPORT );
+ printf( "\n%s\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 );
+ 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"
+ " -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"
+ " -F fn\tname of textfile like -f containing case sensitive REs.\n"
+ " -H\tprepend HTTP reply header to destination files in copy-out mode.\n"
+ " -n\tdo not fork() when using more than one cache_dir.\n"
+ " -p h:p\tcache runs on host h and optional port p, default is %s:%u.\n"
+ " -P #\tif 0, just print matches; otherwise OR the following purge modes:\n"
+ "\t 0x01 really send PURGE to the cache.\n"
+ "\t 0x02 remove all caches files reported as 404 (not found).\n"
+ "\t 0x04 remove all weird (inaccessible or too small) cache files.\n"
+ "\t0 and 1 are recommended - slow rebuild your cache with other modes.\n"
+ " -s\tshow all options after option parsing, but before really starting.\n"
+ " -v\tshow more information about the file, e.g. MD5, timestamps and flags.\n"
+ "\n", DEFAULT_SQUID_CONF, DEFAULTHOST, DEFAULTPORT );
}
void
parseCommandline( int argc, char* argv[], REList*& head,
- char*& conffile, char*& copydir,
- struct in_addr& serverHost, unsigned short& serverPort )
- // paramtr: argc: see ::main().
- // argv: see ::main().
- // returns: Does terminate the program on errors!
- // purpose: suck in any commandline options, and set the global vars.
-{ int option, port, showme = 0;
- char* ptr, *colon;
- FILE* rfile;
-
- // program basename
- if ( (ptr = strrchr(argv[0],'/')) == NULL ) ptr=argv[0];
- else ptr++;
- ::programname = ptr;
-
- // extract commandline parameters
- REList* tail = head = 0;
- opterr = 0;
- while ( (option = getopt( argc, argv, "ac:C:d:E:e:F:f:Hnp:P:sv" )) != -1 ) {
- switch ( option ) {
- case 'a':
- ::iamalive = ! ::iamalive;
- break;
- case 'C':
- if ( optarg && *optarg ) {
- if ( copydir ) free( (void*) copydir );
- assert( (copydir = strdup(optarg)) );
- }
- break;
- case 'c':
- if ( optarg && *optarg ) {
- if ( *conffile ) free((void*) conffile );
- assert( (conffile = strdup(optarg)) );
- }
- break;
-
- case 'd':
- ::debug = strtoul( optarg, 0, 0 );
- break;
-
- case 'E':
- case 'e':
- if ( head == 0 ) tail = head = new REList( optarg, option=='E' );
- else {
- tail->next = new REList( optarg, option=='E' );
- tail = tail->next;
- }
- break;
-
- case 'f':
- if ( (rfile = fopen( optarg, "r" )) != NULL ) {
- unsigned long lineno = 0;
+ char*& conffile, char*& copydir,
+ struct in_addr& serverHost, unsigned short& serverPort )
+// paramtr: argc: see ::main().
+// argv: see ::main().
+// returns: Does terminate the program on errors!
+// purpose: suck in any commandline options, and set the global vars.
+{
+ int option, port, showme = 0;
+ char* ptr, *colon;
+ FILE* rfile;
+
+ // program basename
+ if ( (ptr = strrchr(argv[0],'/')) == NULL ) ptr=argv[0];
+ else ptr++;
+ ::programname = ptr;
+
+ // extract commandline parameters
+ REList* tail = head = 0;
+ opterr = 0;
+ while ( (option = getopt( argc, argv, "ac:C:d:E:e:F:f:Hnp:P:sv" )) != -1 ) {
+ switch ( option ) {
+ case 'a':
+ ::iamalive = ! ::iamalive;
+ break;
+ case 'C':
+ if ( optarg && *optarg ) {
+ if ( copydir ) free( (void*) copydir );
+ assert( (copydir = strdup(optarg)) );
+ }
+ break;
+ case 'c':
+ if ( optarg && *optarg ) {
+ if ( *conffile ) free((void*) conffile );
+ assert( (conffile = strdup(optarg)) );
+ }
+ break;
+
+ case 'd':
+ ::debug = strtoul( optarg, 0, 0 );
+ break;
+
+ case 'E':
+ case 'e':
+ if ( head == 0 ) tail = head = new REList( optarg, option=='E' );
+ else {
+ tail->next = new REList( optarg, option=='E' );
+ tail = tail->next;
+ }
+ break;
+
+ case 'f':
+ if ( (rfile = fopen( optarg, "r" )) != NULL ) {
+ unsigned long lineno = 0;
#define LINESIZE 512
- char line[LINESIZE];
- while ( fgets( line, LINESIZE, rfile ) != NULL ) {
- lineno++;
- int len = strlen(line)-1;
- if ( len+2 >= LINESIZE ) {
- fprintf( stderr, "%s:%lu: line too long, sorry.\n",
- optarg, lineno );
- exit(1);
- }
-
- // remove trailing line breaks
- while ( len > 0 && ( line[len] == '\n' || line[len] == '\r' ) )
- line[len--] = '\0';
-
- // insert into list of expressions
- if ( head == 0 ) tail = head = new REList(line,option=='F');
- else {
- tail->next = new REList(line,option=='F');
- tail = tail->next;
- }
- }
- fclose(rfile);
- } else
- fprintf( stderr, "unable to open %s: %s\n", optarg, strerror(errno));
- break;
-
- case 'H':
- ::envelope = ! ::envelope;
- break;
- case 'n':
- ::no_fork = ! ::no_fork;
- break;
- case 'p':
- colon = strchr( optarg, ':' );
- if ( colon == 0 ) {
- // no colon, only look at host
-
- // fix: see if somebody just put in there a port (no periods)
- // give port number precedence over host names
- port = checkForPortOnly( optarg );
- if ( port == -1 ) {
- // assume that main() did set the default port
- if ( convertHostname(optarg,serverHost) == -1 ) {
- fprintf( stderr, "unable to resolve host %s!\n", optarg );
- exit(1);
- }
- } else {
- // assume that main() did set the default host
- serverPort = port;
- }
- } else {
- // colon used, port is extra
- *colon++ = 0;
- if ( convertHostname(optarg,serverHost) == -1 ) {
- fprintf( stderr, "unable to resolve host %s!\n", optarg );
- exit(1);
- }
- if ( convertPortname(colon,serverPort) == -1 ) {
- fprintf( stderr, "unable to resolve port %s!\n", colon );
- exit(1);
- }
- }
- break;
- case 'P':
- ::purgeMode = ( strtol( optarg, 0, 0 ) & 0x07 );
- break;
- case 's':
- showme=1;
- break;
- case 'v':
- ::verbose = ! ::verbose;
- break;
- case '?':
- default:
- helpMe();
- exit(1);
+ char line[LINESIZE];
+ while ( fgets( line, LINESIZE, rfile ) != NULL ) {
+ lineno++;
+ int len = strlen(line)-1;
+ if ( len+2 >= LINESIZE ) {
+ fprintf( stderr, "%s:%lu: line too long, sorry.\n",
+ optarg, lineno );
+ exit(1);
+ }
+
+ // remove trailing line breaks
+ while ( len > 0 && ( line[len] == '\n' || line[len] == '\r' ) )
+ line[len--] = '\0';
+
+ // insert into list of expressions
+ if ( head == 0 ) tail = head = new REList(line,option=='F');
+ else {
+ tail->next = new REList(line,option=='F');
+ tail = tail->next;
+ }
+ }
+ fclose(rfile);
+ } else
+ fprintf( stderr, "unable to open %s: %s\n", optarg, strerror(errno));
+ break;
+
+ case 'H':
+ ::envelope = ! ::envelope;
+ break;
+ case 'n':
+ ::no_fork = ! ::no_fork;
+ break;
+ case 'p':
+ colon = strchr( optarg, ':' );
+ if ( colon == 0 ) {
+ // no colon, only look at host
+
+ // fix: see if somebody just put in there a port (no periods)
+ // give port number precedence over host names
+ port = checkForPortOnly( optarg );
+ if ( port == -1 ) {
+ // assume that main() did set the default port
+ if ( convertHostname(optarg,serverHost) == -1 ) {
+ fprintf( stderr, "unable to resolve host %s!\n", optarg );
+ exit(1);
+ }
+ } else {
+ // assume that main() did set the default host
+ serverPort = port;
+ }
+ } else {
+ // colon used, port is extra
+ *colon++ = 0;
+ if ( convertHostname(optarg,serverHost) == -1 ) {
+ fprintf( stderr, "unable to resolve host %s!\n", optarg );
+ exit(1);
+ }
+ if ( convertPortname(colon,serverPort) == -1 ) {
+ fprintf( stderr, "unable to resolve port %s!\n", colon );
+ exit(1);
+ }
+ }
+ break;
+ case 'P':
+ ::purgeMode = ( strtol( optarg, 0, 0 ) & 0x07 );
+ break;
+ case 's':
+ showme=1;
+ break;
+ case 'v':
+ ::verbose = ! ::verbose;
+ break;
+ case '?':
+ default:
+ helpMe();
+ exit(1);
+ }
+ }
+
+ // adjust
+ if ( ! isatty(fileno(stdout)) || (::debug & 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 );
+ exit(1);
}
- }
-
- // adjust
- if ( ! isatty(fileno(stdout)) || (::debug & 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 );
- exit(1);
- }
-
- // postcondition: head != 0
- assert( head != 0 );
-
- // make sure that the copy out directory is there and accessible
- if ( copydir && *copydir )
- if ( assert_copydir( copydir ) != 0 ) exit(1);
-
- // show results
- if ( showme ) {
- printf( "#\n# Currently active values for %s:\n# %s\n",
- ::programname, ::RCS_ID );
- printf( "# Debug level : " );
- if ( ::debug ) printf( "%#6.4hx", ::debug );
- 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 )
- 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 ) );
- 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 );
+
+ // postcondition: head != 0
+ assert( head != 0 );
+
+ // make sure that the copy out directory is there and accessible
+ if ( copydir && *copydir )
+ if ( assert_copydir( copydir ) != 0 ) exit(1);
+
+ // show results
+ if ( showme ) {
+ printf( "#\n# Currently active values for %s:\n# %s\n",
+ ::programname, ::RCS_ID );
+ printf( "# Debug level : " );
+ if ( ::debug ) printf( "%#6.4hx", ::debug );
+ 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 )
+ 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 ) );
+ 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 defined(LINUX) && putc==_IO_putc
- // I HATE BROKEN LINUX HEADERS!
- // purge.o(.text+0x1040): undefined reference to `_IO_putc'
- // If your compilation breaks here, remove the undefinition
-#undef putc
+ // I HATE BROKEN LINUX HEADERS!
+ // purge.o(.text+0x1040): undefined reference to `_IO_putc'
+ // If your compilation breaks here, remove the undefinition
+#undef putc
#endif
- else putchar('1');
- printf( " \"%s\"\n", tail->data );
+ else putchar('1');
+ printf( " \"%s\"\n", tail->data );
+ }
+ puts( "#" );
}
- puts( "#" );
- }
- fflush( stdout );
+ fflush( stdout );
}
extern "C" {
-static
-void
-exiter( void )
-{
- if ( ::term_flag ) psignal( ::term_flag, "received signal" );
- delete[] ::linebuffer;
- if ( ::reminder ) {
- fputs(
-"WARNING! Caches files were removed. Please shut down your cache, remove\n"
-"your swap.state files and restart your cache again, i.e. effictively do\n"
-"a slow rebuild your cache! Otherwise your squid *will* choke!\n", stderr );
- }
-}
+ static
+ void
+ exiter( void ) {
+ if ( ::term_flag ) psignal( ::term_flag, "received signal" );
+ delete[] ::linebuffer;
+ if ( ::reminder ) {
+ fputs(
+ "WARNING! Caches files were removed. Please shut down your cache, remove\n"
+ "your swap.state files and restart your cache again, i.e. effictively do\n"
+ "a slow rebuild your cache! Otherwise your squid *will* choke!\n", stderr );
+ }
+ }
-static
-void
-handler( int signo )
-{
- ::term_flag = signo;
- if ( getpid() == getpgrp() ) kill( -getpgrp(), signo );
- exit(1);
-}
+ static
+ void
+ handler( int signo ) {
+ ::term_flag = signo;
+ if ( getpid() == getpgrp() ) kill( -getpgrp(), signo );
+ exit(1);
+ }
} // extern "C"
static
int
makelinebuffered( FILE* fp, const char* fn = 0 )
- // purpose: make the given FILE line buffered
- // paramtr: fp (IO): file pointer which to put into line buffer mode
- // fn (IN): name of file to print in case of error
- // returns: 0 is ok, -1 to indicate an error
- // warning: error messages will already be printed
+// purpose: make the given FILE line buffered
+// paramtr: fp (IO): file pointer which to put into line buffer mode
+// fn (IN): name of file to print in case of error
+// returns: 0 is ok, -1 to indicate an error
+// warning: error messages will already be printed
{
- if ( setvbuf( fp, 0, _IOLBF, 0 ) == 0 ) {
- // ok
- return 0;
- } else {
- // error
- fprintf( stderr, "unable to make \"%s\" line buffered: %s\n",
- fn ? fn : "", strerror(errno) );
- return -1;
- }
+ if ( setvbuf( fp, 0, _IOLBF, 0 ) == 0 ) {
+ // ok
+ return 0;
+ } else {
+ // error
+ fprintf( stderr, "unable to make \"%s\" line buffered: %s\n",
+ fn ? fn : "", strerror(errno) );
+ return -1;
+ }
}
int
main( int argc, char* argv[] )
{
- // setup variables
- REList* list = 0;
- char* conffile = strdup( DEFAULT_SQUID_CONF );
- serverPort = htons(DEFAULTPORT);
- if ( convertHostname(DEFAULTHOST,serverHost) == -1 ) {
- fprintf( stderr, "unable to resolve host %s!\n", DEFAULTHOST );
- return 1;
- }
-
- // setup line buffer
- ::linebuffer = new char[ ::buffersize ];
- assert( ::linebuffer != 0 );
-
- // parse commandline
- puts( "### Use at your own risk! No guarantees whatsoever. You were warned. ###");
- parseCommandline( argc, argv, list, conffile, ::copydir,
- serverHost, serverPort );
-
- // prepare execution
- if ( atexit( exiter ) != 0 ||
- Signal( SIGTERM, handler, true ) == SIG_ERR ||
- Signal( SIGINT, handler, true ) == SIG_ERR ||
- Signal( SIGHUP, handler, true ) == SIG_ERR ) {
- perror( "unable to install signal/exit function" );
- return 1;
- }
-
- // try to read squid.conf file to determine all cache_dir locations
- CacheDirVector cdv(0);
- if ( readConfigFile( cdv, conffile, debug ? 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.
-
- if ( ::no_fork || cdv.size() == 1 ) {
- // linear mode, one cache_dir after the next
- for ( CacheDirVector::iterator i = cdv.begin(); i != cdv.end(); ++i ) {
- // execute OR complain
- if ( ! dirlevel(i->base,list) )
- fprintf( stderr, "program terminated due to error: %s",
- strerror(errno) );
- free((void*) i->base);
- }
+ // setup variables
+ REList* list = 0;
+ char* conffile = strdup( DEFAULT_SQUID_CONF );
+ serverPort = htons(DEFAULTPORT);
+ if ( convertHostname(DEFAULTHOST,serverHost) == -1 ) {
+ fprintf( stderr, "unable to resolve host %s!\n", DEFAULTHOST );
+ return 1;
+ }
+
+ // setup line buffer
+ ::linebuffer = new char[ ::buffersize ];
+ assert( ::linebuffer != 0 );
+
+ // parse commandline
+ puts( "### Use at your own risk! No guarantees whatsoever. You were warned. ###");
+ parseCommandline( argc, argv, list, conffile, ::copydir,
+ serverHost, serverPort );
+
+ // prepare execution
+ if ( atexit( exiter ) != 0 ||
+ Signal( SIGTERM, handler, true ) == SIG_ERR ||
+ Signal( SIGINT, handler, true ) == SIG_ERR ||
+ Signal( SIGHUP, handler, true ) == SIG_ERR ) {
+ perror( "unable to install signal/exit function" );
+ return 1;
+ }
+
+ // try to read squid.conf file to determine all cache_dir locations
+ CacheDirVector cdv(0);
+ if ( readConfigFile( cdv, conffile, debug ? 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.
+
+ if ( ::no_fork || cdv.size() == 1 ) {
+ // linear mode, one cache_dir after the next
+ for ( CacheDirVector::iterator i = cdv.begin(); i != cdv.end(); ++i ) {
+ // execute OR complain
+ if ( ! dirlevel(i->base,list) )
+ fprintf( stderr, "program terminated due to error: %s",
+ strerror(errno) );
+ free((void*) i->base);
+ }
+ } else {
+ // parallel mode, all cache_dir in parallel
+ pid_t* child = new pid_t[ cdv.size() ];
+
+ // make stdout/stderr line bufferd
+ makelinebuffered( stdout, "stdout" );
+ makelinebuffered( stderr, "stderr" );
+
+ // make parent process group leader for easier killings
+ if ( setpgid(getpid(), getpid()) != 0 ) {
+ perror( "unable to set process group leader" );
+ return 1;
+ }
+
+ // -a is mutually exclusive with fork mode
+ if ( ::iamalive ) {
+ puts( "# i-am-alive flag incompatible with fork mode, resetting" );
+ ::iamalive = false;
+ }
+
+ for ( int i=0; i < cdv.size(); ++i ) {
+ if ( getpid() == getpgrp() ) {
+ // only parent == group leader may fork off new processes
+ if ( (child[i]=fork()) < 0 ) {
+ // fork error, this is bad!
+ perror( "unable to fork" );
+ kill( -getpgrp(), SIGTERM );
+ return 1;
+ } else if ( child[i] == 0 ) {
+ // child mode
+ // execute OR complain
+ if ( ! dirlevel(cdv[i].base,list) )
+ fprintf( stderr, "program terminated due to error: %s\n",
+ strerror(errno) );
+ free((void*) cdv[i].base);
+ return 0;
+ } else {
+ // parent mode
+ if ( ::debug ) printf( "forked child %d\n", (int) child[i] );
+ }
+ }
+ }
+
+ // collect the garbase
+ pid_t temp;
+ int status;
+ for ( int 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 );
+ }
+ delete[] child;
+ }
} else {
- // parallel mode, all cache_dir in parallel
- pid_t* child = new pid_t[ cdv.size() ];
-
- // make stdout/stderr line bufferd
- makelinebuffered( stdout, "stdout" );
- makelinebuffered( stderr, "stderr" );
-
- // make parent process group leader for easier killings
- if ( setpgid(getpid(), getpid()) != 0 ) {
- perror( "unable to set process group leader" );
- return 1;
- }
-
- // -a is mutually exclusive with fork mode
- if ( ::iamalive ) {
- puts( "# i-am-alive flag incompatible with fork mode, resetting" );
- ::iamalive = false;
- }
-
- for ( int i=0; i < cdv.size(); ++i ) {
- if ( getpid() == getpgrp() ) {
- // only parent == group leader may fork off new processes
- if ( (child[i]=fork()) < 0 ) {
- // fork error, this is bad!
- perror( "unable to fork" );
- kill( -getpgrp(), SIGTERM );
- return 1;
- } else if ( child[i] == 0 ) {
- // child mode
- // execute OR complain
- if ( ! dirlevel(cdv[i].base,list) )
- fprintf( stderr, "program terminated due to error: %s\n",
- strerror(errno) );
- free((void*) cdv[i].base);
- return 0;
- } else {
- // parent mode
- if ( ::debug ) printf( "forked child %d\n", (int) child[i] );
- }
- }
- }
-
- // collect the garbase
- pid_t temp;
- int status;
- for ( int 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 );
- }
- delete[] child;
+ fprintf( stderr, "no cache_dir or error accessing \"%s\"\n", conffile );
}
- } else {
- fprintf( stderr, "no cache_dir or error accessing \"%s\"\n", conffile );
- }
-
- // clean up
- if ( copydir ) free( (void*) copydir );
- free((void*) conffile);
- delete list;
- return 0;
+
+ // clean up
+ if ( copydir ) free( (void*) copydir );
+ free((void*) conffile);
+ delete list;
+ return 0;
}
// File: signal.cc
// Date: Sat Feb 28 1998
// Compiler: gcc 2.7.2.x series
-//
+//
// Books: W. Richard Steven, "Advanced Programming in the UNIX Environment",
// Addison-Wesley, 1992.
-//
+//
// (c) 1998 Lehrgebiet Rechnernetze und Verteilte Systeme
// Universität Hannover, Germany
//
#include "signal.hh"
-static const char* RCS_ID =
-"$Id: signal.cc,v 1.3 1999/01/19 13:11:52 cached Exp $";
+static const char* RCS_ID =
+ "$Id: signal.cc,v 1.3 1999/01/19 13:11:52 cached Exp $";
#ifndef HAS_PSIGNAL
#ifdef AIX
void
psignal( int sig, const char* msg )
- // purpose: print message, colon, space, signal name and LF.
- // paramtr: sig (IN): signal number
- // msg (IN): message to prepend
+// purpose: print message, colon, space, signal name and LF.
+// paramtr: sig (IN): signal number
+// msg (IN): message to prepend
{
- if ( msg && *msg ) fprintf( stderr, "%s: ", msg );
- if ( sig > 0 && sig < _sys_nsig )
- fprintf( stderr, "%s\n", _sys_siglist[sig] );
- else
- fputs( "(unknown)\n", stderr );
+ if ( msg && *msg ) fprintf( stderr, "%s: ", msg );
+ if ( sig > 0 && sig < _sys_nsig )
+ fprintf( stderr, "%s\n", _sys_siglist[sig] );
+ else
+ fputs( "(unknown)\n", stderr );
}
#endif // !HAS_PSIGNAL
SigFunc*
Signal( int signo, SigFunc* newhandler, bool doInterrupt )
- // purpose: install reliable signals
- // paramtr: signo (IN): signal for which a handler is to be installed
- // newhandler (IN): function pointer to the signal handler
- // doInterrupt (IN): interrupted system calls wanted!
- // returns: the old signal handler, or SIG_ERR in case of error.
+// purpose: install reliable signals
+// paramtr: signo (IN): signal for which a handler is to be installed
+// newhandler (IN): function pointer to the signal handler
+// doInterrupt (IN): interrupted system calls wanted!
+// returns: the old signal handler, or SIG_ERR in case of error.
{
- struct sigaction action, old;
+ struct sigaction action, old;
- memset( &old, 0, sizeof(old) );
- memset( &action, 0, sizeof(action) );
+ memset( &old, 0, sizeof(old) );
+ memset( &action, 0, sizeof(action) );
- // action.sa_handler = newhandler; I HATE TYPE-OVERCORRECTNESS !
- memmove( &action.sa_handler, &newhandler, sizeof(SigFunc*) );
- sigemptyset( &action.sa_mask );
+ // action.sa_handler = newhandler; I HATE TYPE-OVERCORRECTNESS !
+ memmove( &action.sa_handler, &newhandler, sizeof(SigFunc*) );
+ sigemptyset( &action.sa_mask );
- if ( signo == SIGCHLD ) {
- action.sa_flags |= SA_NOCLDSTOP;
+ if ( signo == SIGCHLD ) {
+ action.sa_flags |= SA_NOCLDSTOP;
#ifdef SA_NODEFER
- action.sa_flags |= SA_NODEFER; // SYSV: don't block current signal
+ action.sa_flags |= SA_NODEFER; // SYSV: don't block current signal
#endif
- }
+ }
- if ( signo == SIGALRM || doInterrupt ) {
+ if ( signo == SIGALRM || doInterrupt ) {
#ifdef SA_INTERRUPT
- action.sa_flags |= SA_INTERRUPT; // SunOS, obsoleted by POSIX
+ action.sa_flags |= SA_INTERRUPT; // SunOS, obsoleted by POSIX
#endif
- } else {
+ } else {
#ifdef SA_RESTART
- action.sa_flags |= SA_RESTART; // BSD, SVR4
+ action.sa_flags |= SA_RESTART; // BSD, SVR4
#endif
- }
+ }
- return ( sigaction( signo, &action, &old ) < 0 ) ?
- (SigFunc*) SIG_ERR :
- (SigFunc*) old.sa_handler;
+ return ( sigaction( signo, &action, &old ) < 0 ) ?
+ (SigFunc*) SIG_ERR :
+ (SigFunc*) old.sa_handler;
}
SIGRETTYPE
sigChild( int signo )
- // purpose: supply ad hoc child handler with output on stderr
- // paramtr: signo (IN): == SIGCHLD
- // returns: only if OS uses a return type for signal handler
- // seealso: Stevens, UNP, figure 5.11 *and* Stevens, APUE, figure 8.3
+// purpose: supply ad hoc child handler with output on stderr
+// paramtr: signo (IN): == SIGCHLD
+// returns: only if OS uses a return type for signal handler
+// seealso: Stevens, UNP, figure 5.11 *and* Stevens, APUE, figure 8.3
{
- pid_t pid;
- int status = signo; // to stop GNU from complaining...
- char line[128];
-
- int saveerr = errno;
- while ( (pid = waitpid( -1, &status, WNOHANG )) > 0 ) {
- if ( WIFEXITED(status) ) {
- sprintf( line, "child (pid=%ld) reaped, status %d\n%c",
- (long) pid, WEXITSTATUS(status), 0 );
- } else if ( WIFSIGNALED(status) ) {
- sprintf( line, "child (pid=%ld) died on signal %d%s\n%c",
- (long) pid, WTERMSIG(status),
+ pid_t pid;
+ int status = signo; // to stop GNU from complaining...
+ char line[128];
+
+ int saveerr = errno;
+ while ( (pid = waitpid( -1, &status, WNOHANG )) > 0 ) {
+ if ( WIFEXITED(status) ) {
+ sprintf( line, "child (pid=%ld) reaped, status %d\n%c",
+ (long) pid, WEXITSTATUS(status), 0 );
+ } else if ( WIFSIGNALED(status) ) {
+ sprintf( line, "child (pid=%ld) died on signal %d%s\n%c",
+ (long) pid, WTERMSIG(status),
#ifdef WCOREDUMP
- WCOREDUMP(status) ? " (core generated)" : "",
+ WCOREDUMP(status) ? " (core generated)" : "",
#else
- "",
+ "",
#endif
- 0 );
- } else {
- sprintf( line, "detected dead child (pid=%ld), status %d\n%c",
- (long) pid, status, 0 );
+ 0 );
+ } else {
+ sprintf( line, "detected dead child (pid=%ld), status %d\n%c",
+ (long) pid, status, 0 );
+ }
+ write( STDERR_FILENO, line, strlen(line) );
}
- write( STDERR_FILENO, line, strlen(line) );
- }
- errno = saveerr;
+ errno = saveerr;
#if SIGRETTYPE != void
- return 0;
+ return 0;
#endif
}
#include "convert.hh"
static const char* RCS_ID =
-"$Id: socket.cc,v 1.3 1999/01/19 11:00:50 voeckler Exp $";
+ "$Id: socket.cc,v 1.3 1999/01/19 11:00:50 voeckler Exp $";
int
setSocketBuffers( int sockfd, int size )
- // purpose: set socket buffers for both directions to the specified size
- // paramtr: sockfd (IN): socket file descriptor
- // size (IN): new socket buffer size
- // returns: -1 on setsockopt() errors, 0 otherwise
- // warning: prints error message on stderr, errno will be changed
+// purpose: set socket buffers for both directions to the specified size
+// paramtr: sockfd (IN): socket file descriptor
+// size (IN): new socket buffer size
+// returns: -1 on setsockopt() errors, 0 otherwise
+// warning: prints error message on stderr, errno will be changed
{
- if ( setsockopt( sockfd, SOL_SOCKET, SO_RCVBUF,
- (char*) &size, sizeof(size) ) == -1 ) {
- perror( "setsockopt( SO_RCVBUF )" );
- return -1;
- }
+ if ( setsockopt( sockfd, SOL_SOCKET, SO_RCVBUF,
+ (char*) &size, sizeof(size) ) == -1 ) {
+ perror( "setsockopt( SO_RCVBUF )" );
+ return -1;
+ }
- if ( setsockopt( sockfd, SOL_SOCKET, SO_SNDBUF,
- (char*) &size, sizeof(size) ) == -1 ) {
- perror( "setsockopt( SO_SNDBUF )" );
- return -1;
- }
+ if ( setsockopt( sockfd, SOL_SOCKET, SO_SNDBUF,
+ (char*) &size, sizeof(size) ) == -1 ) {
+ perror( "setsockopt( SO_SNDBUF )" );
+ return -1;
+ }
- return 0;
+ return 0;
}
int
getSocketNoDelay( int sockfd )
- // purpose: get state of the TCP_NODELAY of the socket
- // paramtr: sockfd (IN): socket descriptor
- // returns: 1, if TCP_NODELAY is set,
- // 0, if TCP_NODELAY is not set,
- // -1, if an error occurred (e.g. datagram socket)
+// purpose: get state of the TCP_NODELAY of the socket
+// paramtr: sockfd (IN): socket descriptor
+// returns: 1, if TCP_NODELAY is set,
+// 0, if TCP_NODELAY is not set,
+// -1, if an error occurred (e.g. datagram socket)
{
- int delay = 0;
- SOCKLEN len = sizeof(delay);
- if ( getsockopt( sockfd, IPPROTO_TCP, TCP_NODELAY,
- (char*) &delay, &len ) == -1 ) {
- perror( "# getsockopt( TCP_NODELAY ) failed" );
- return -1;
- } else
- return ( delay ? 1 : 0 );
+ int delay = 0;
+ SOCKLEN len = sizeof(delay);
+ if ( getsockopt( sockfd, IPPROTO_TCP, TCP_NODELAY,
+ (char*) &delay, &len ) == -1 ) {
+ perror( "# getsockopt( TCP_NODELAY ) failed" );
+ return -1;
+ } else
+ return ( delay ? 1 : 0 );
}
int
setSocketNoDelay( int sockfd, bool nodelay )
- // purpose: get state of the TCP_NODELAY of the socket
- // paramtr: sockfd (IN): socket descriptor
- // nodelay (IN): true, if TCP_NODELAY is to be set, false otherwise.
- // returns: 0, if everything worked out o.k.
- // -1, if an error occurred (e.g. datagram socket)
+// purpose: get state of the TCP_NODELAY of the socket
+// paramtr: sockfd (IN): socket descriptor
+// nodelay (IN): true, if TCP_NODELAY is to be set, false otherwise.
+// returns: 0, if everything worked out o.k.
+// -1, if an error occurred (e.g. datagram socket)
{
- const int delay = 1;
- if ( setsockopt( sockfd, IPPROTO_TCP, TCP_NODELAY,
- (const char*) &delay, sizeof(delay) ) == -1 ) {
- perror( "setsockopt( TCP_NODELAY ) failed" );
- return -1;
- } else
- return 0;
+ const int delay = 1;
+ if ( setsockopt( sockfd, IPPROTO_TCP, TCP_NODELAY,
+ (const char*) &delay, sizeof(delay) ) == -1 ) {
+ perror( "setsockopt( TCP_NODELAY ) failed" );
+ return -1;
+ } else
+ return 0;
}
int
commonCode( int& sockfd, bool nodelay, int sendBufferSize, int recvBufferSize )
- // purpose: common code in server sockets and client sockets
- // paramtr: sockfd (IO): socket filedescriptor
- // nodelay (IN): true=set TCP_NODELAY option.
- // sendBufferSize (IN): don't set (use sys defaults) if < 0
- // recvBufferSize (IN): don't set (use sys defaults) if < 0
- // returns: 0 == if everthing went ok, -1 otherwise
- // warning: sockfd will be closed, if -1 is returned!
+// purpose: common code in server sockets and client sockets
+// paramtr: sockfd (IO): socket filedescriptor
+// nodelay (IN): true=set TCP_NODELAY option.
+// sendBufferSize (IN): don't set (use sys defaults) if < 0
+// recvBufferSize (IN): don't set (use sys defaults) if < 0
+// returns: 0 == if everthing went ok, -1 otherwise
+// warning: sockfd will be closed, if -1 is returned!
{
- // set TCP_NODELAY option, if that is wanted.
- // The socket API default is unset.
- if ( nodelay ) {
- const int delay = 1;
- if ( setsockopt( sockfd, IPPROTO_TCP, TCP_NODELAY,
- (const char*) &delay, sizeof(delay) ) == -1 ) {
- perror( "setsockopt( TCP_NODELAY ) failed" );
- close(sockfd);
- return -1;
+ // set TCP_NODELAY option, if that is wanted.
+ // The socket API default is unset.
+ if ( nodelay ) {
+ const int delay = 1;
+ if ( setsockopt( sockfd, IPPROTO_TCP, TCP_NODELAY,
+ (const char*) &delay, sizeof(delay) ) == -1 ) {
+ perror( "setsockopt( TCP_NODELAY ) failed" );
+ close(sockfd);
+ return -1;
+ }
}
- }
- // set the socket send buffer size explicitly, or use the system default
- if ( sendBufferSize >= 0 ) {
- if ( setsockopt( sockfd, SOL_SOCKET, SO_SNDBUF, (char*) &sendBufferSize,
- sizeof(sendBufferSize) ) == -1 ) {
- perror( "setsockopt( SO_SNDBUF )" );
- close(sockfd);
- return -1;
+ // set the socket send buffer size explicitly, or use the system default
+ if ( sendBufferSize >= 0 ) {
+ if ( setsockopt( sockfd, SOL_SOCKET, SO_SNDBUF, (char*) &sendBufferSize,
+ sizeof(sendBufferSize) ) == -1 ) {
+ perror( "setsockopt( SO_SNDBUF )" );
+ close(sockfd);
+ return -1;
+ }
}
- }
- // set the socket recv buffer size explicitly, or use the system default
- if ( recvBufferSize >= 0 ) {
- if ( setsockopt( sockfd, SOL_SOCKET, SO_RCVBUF, (char*) &recvBufferSize,
- sizeof(recvBufferSize) ) == -1 ) {
- perror( "setsockopt( SO_RCVBUF )" );
- close(sockfd);
- return -1;
+ // set the socket recv buffer size explicitly, or use the system default
+ if ( recvBufferSize >= 0 ) {
+ if ( setsockopt( sockfd, SOL_SOCKET, SO_RCVBUF, (char*) &recvBufferSize,
+ sizeof(recvBufferSize) ) == -1 ) {
+ perror( "setsockopt( SO_RCVBUF )" );
+ close(sockfd);
+ return -1;
+ }
}
- }
- return 0;
+ return 0;
}
int
connectTo( struct in_addr host, unsigned short port, bool nodelay,
- int sendBufferSize, int recvBufferSize )
- // purpose: connect to a server as a client
- // paramtr: host (IN): address describing the server
- // port (IN): port to connect at the server
- // nodelay (IN): true=set TCP_NODELAY option.
- // sendBufferSize (IN): don't set (use sys defaults) if < 0
- // recvBufferSize (IN): don't set (use sys defaults) if < 0
- // returns: >=0 is the descriptor of the opened, connected socket,
- // -1 is an indication of an error (errno may have been reset).
+ int sendBufferSize, int recvBufferSize )
+// purpose: connect to a server as a client
+// paramtr: host (IN): address describing the server
+// port (IN): port to connect at the server
+// nodelay (IN): true=set TCP_NODELAY option.
+// sendBufferSize (IN): don't set (use sys defaults) if < 0
+// recvBufferSize (IN): don't set (use sys defaults) if < 0
+// returns: >=0 is the descriptor of the opened, connected socket,
+// -1 is an indication of an error (errno may have been reset).
{
- int sockfd = socket( PF_INET, SOCK_STREAM, IPPROTO_TCP );
- if ( sockfd == -1 ) {
- perror( "socket() failed" );
- return -1;
- }
+ int sockfd = socket( PF_INET, SOCK_STREAM, IPPROTO_TCP );
+ if ( sockfd == -1 ) {
+ perror( "socket() failed" );
+ return -1;
+ }
+
+ if ( commonCode( sockfd, nodelay, sendBufferSize, recvBufferSize ) == -1 )
+ return -1;
+
+ struct sockaddr_in server;
+ memset( &server, 0, sizeof(server) );
+ server.sin_family = AF_INET;
+ server.sin_addr = host;
+ server.sin_port = port;
+ if ( connect( sockfd, (struct sockaddr*) &server, sizeof(server) ) == -1 ) {
+ perror( "connect() failure" );
+ close(sockfd);
+ return -1;
+ }
- if ( commonCode( sockfd, nodelay, sendBufferSize, recvBufferSize ) == -1 )
- return -1;
-
- struct sockaddr_in server;
- memset( &server, 0, sizeof(server) );
- server.sin_family = AF_INET;
- server.sin_addr = host;
- server.sin_port = port;
- if ( connect( sockfd, (struct sockaddr*) &server, sizeof(server) ) == -1 ) {
- perror( "connect() failure" );
- close(sockfd);
- return -1;
- }
-
- return sockfd;
+ return sockfd;
}
int
serverSocket( struct in_addr host, unsigned short port,
- int backlog, bool reuse, bool nodelay,
- int sendBufferSize, int recvBufferSize )
- // purpose: open a server socket for listening
- // paramtr: host (IN): host to bind locally to, use INADDRY_ANY for *
- // port (IN): port to bind to, use 0 for system assigned
- // backlog (IN): listen backlog queue length
- // reuse (IN): set SO_REUSEADDR option - default usefully
- // nodelay (IN): true=set TCP_NODELAY option.
- // SETTING TCP_NODELAY ON A SERVER SOCKET DOES NOT MAKE SENSE!
- // sendBufferSize (IN): don't set (use sys defaults) if < 0
- // recvBufferSize (IN): don't set (use sys defaults) if < 0
- // returns: opened listening fd, or -1 on error.
- // warning: error message will be printed on stderr and errno reset.
+ int backlog, bool reuse, bool nodelay,
+ int sendBufferSize, int recvBufferSize )
+// purpose: open a server socket for listening
+// paramtr: host (IN): host to bind locally to, use INADDRY_ANY for *
+// port (IN): port to bind to, use 0 for system assigned
+// backlog (IN): listen backlog queue length
+// reuse (IN): set SO_REUSEADDR option - default usefully
+// nodelay (IN): true=set TCP_NODELAY option.
+// SETTING TCP_NODELAY ON A SERVER SOCKET DOES NOT MAKE SENSE!
+// sendBufferSize (IN): don't set (use sys defaults) if < 0
+// recvBufferSize (IN): don't set (use sys defaults) if < 0
+// returns: opened listening fd, or -1 on error.
+// warning: error message will be printed on stderr and errno reset.
{
- int sockfd = socket( AF_INET, SOCK_STREAM, 0 );
- if ( sockfd == -1 ) {
- perror( "socket" );
- return -1;
- }
+ int sockfd = socket( AF_INET, SOCK_STREAM, 0 );
+ if ( sockfd == -1 ) {
+ perror( "socket" );
+ return -1;
+ }
- if ( reuse ) {
- int reuse = 1;
- if ( setsockopt( sockfd, SOL_SOCKET, SO_REUSEADDR,
- (char*) &reuse, sizeof(int) ) == -1) {
- perror( "setsockopt( SO_REUSEADDR )" );
- close( sockfd );
- return -1;
+ if ( reuse ) {
+ int reuse = 1;
+ if ( setsockopt( sockfd, SOL_SOCKET, SO_REUSEADDR,
+ (char*) &reuse, sizeof(int) ) == -1) {
+ perror( "setsockopt( SO_REUSEADDR )" );
+ close( sockfd );
+ return -1;
+ }
}
- }
- if ( commonCode( sockfd, nodelay, sendBufferSize, recvBufferSize ) == -1 )
- return -1;
+ if ( commonCode( sockfd, nodelay, sendBufferSize, recvBufferSize ) == -1 )
+ return -1;
- struct sockaddr_in server;
- memset( &server, 0, sizeof(server) );
- server.sin_family = AF_INET;
- server.sin_port = port;
- server.sin_addr = host;
- if ( bind( sockfd, (SA*) &server, sizeof(server) ) == -1 ) {
- SockAddress socket;
- fprintf( stderr, "bind(%s): %s\n",
- my_sock_ntoa(server,socket), strerror(errno) );
- close(sockfd);
- return -1;
- }
+ struct sockaddr_in server;
+ memset( &server, 0, sizeof(server) );
+ server.sin_family = AF_INET;
+ server.sin_port = port;
+ server.sin_addr = host;
+ if ( bind( sockfd, (SA*) &server, sizeof(server) ) == -1 ) {
+ SockAddress socket;
+ fprintf( stderr, "bind(%s): %s\n",
+ my_sock_ntoa(server,socket), strerror(errno) );
+ close(sockfd);
+ return -1;
+ }
- if ( listen( sockfd, backlog ) == -1 ) {
- perror( "listen" );
- close(sockfd);
- return -1;
- }
+ if ( listen( sockfd, backlog ) == -1 ) {
+ perror( "listen" );
+ close(sockfd);
+ return -1;
+ }
- return sockfd;
+ return sockfd;
}
#include "squid-tlv.hh"
static const char* RCS_ID =
-"$Id: squid-tlv.cc,v 1.1 1999/06/15 21:10:16 voeckler Exp $";
+ "$Id: squid-tlv.cc,v 1.1 1999/06/15 21:10:16 voeckler Exp $";
SquidTLV::SquidTLV( SquidMetaType _type, size_t _size, void* _data )
- :next(0),size(_size)
+ :next(0),size(_size)
{
- type = _type;
- data = (char*) _data;
+ type = _type;
+ data = (char*) _data;
}
SquidMetaList::SquidMetaList()
{
- head = tail = 0;
+ head = tail = 0;
}
SquidMetaList::~SquidMetaList()
{
- for ( SquidTLV* temp = head; temp; temp = head ) {
- head = temp->next;
- delete temp;
- }
+ for ( SquidTLV* temp = head; temp; temp = head ) {
+ head = temp->next;
+ delete temp;
+ }
}
void
SquidMetaList::append( SquidMetaType type, size_t size, void* data )
{
- SquidTLV* temp = new SquidTLV( type, size, data );
- if ( head == 0 ) head = tail = temp;
- else {
- tail->next = temp;
- tail = temp;
- }
+ SquidTLV* temp = new SquidTLV( type, size, data );
+ if ( head == 0 ) head = tail = temp;
+ else {
+ tail->next = temp;
+ tail = temp;
+ }
}
const SquidTLV*
SquidMetaList::search( SquidMetaType type ) const
{
- const SquidTLV* temp = head;
- while ( temp && temp->type != type ) temp = temp->next;
- return temp;
+ const SquidTLV* temp = head;
+ while ( temp && temp->type != type ) temp = temp->next;
+ return temp;
}