-//
-// $Id: conffile.cc,v 1.1 2000/09/21 09:44:53 voeckler Exp $
-//
-// Author: Jens-S. Vöckler <voeckler@rvs.uni-hannover.de>
+/*
+ * Copyright (C) 1996-2016 The Squid Software Foundation and contributors
+ *
+ * Squid software is distributed under GPLv2+ license and includes
+ * contributions from numerous individuals and organizations.
+ * Please see the COPYING and CONTRIBUTORS files for details.
+ */
+
+// Author: Jens-S. V?ckler <voeckler@rvs.uni-hannover.de>
//
// File: conffile.cc
// Fri Sep 15 2000
//
// (c) 2000 Lehrgebiet Rechnernetze und Verteilte Systeme
-// Universität Hannover, Germany
+// Universit?t Hannover, Germany
//
// Permission to use, copy, modify, distribute, and sell this software
// and its documentation for any purpose is hereby granted without fee,
// ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
// SOFTWARE.
//
-// $Log: conffile.cc,v $
// Revision 1.1 2000/09/21 09:44:53 voeckler
// Initial revision
//
-//
-#if defined(__GNUC__) || defined(__GNUG__)
-#pragma implementation
-#endif
+#include "squid.h"
#include "conffile.hh"
+
+#include <cerrno>
+#include <cstdlib>
+#include <cstring>
+#include <fstream>
+#include <regex>
#include <sys/types.h>
-#include <errno.h>
#include <memory.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <regex.h>
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 );
+ // try to open file
+ if ( debug ) fprintf( debug, "# trying to open %s\n", fn ? fn : "(null)" );
+ std::ifstream cfgin(fn);
+ if (!cfgin) {
+ fprintf( stderr, "fopen %s: %s\n", fn, strerror(errno) );
+ return -1;
}
- }
- fclose(in);
- regfree(&rexp);
- return cachedir.size();
+ // prepare regular expression for matching
+ static const char * expression = "^[ \t]*cache_dir([ \t]+([[:alpha:]]+))?[ \t]+([[:graph:]]+)[ \t]+([0-9]+)[ \t]+([0-9]+)[ \t]+([0-9]+)";
+ if ( debug ) fprintf( debug, "# trying to compile \"%s\"\n", expression );
+
+ static const std::regex rexp(expression, std::regex::extended);
+
+ // read line by line
+ if ( debug ) fputs( "# trying to read lines\n", debug );
+
+ std::smatch subs; // set of std::string so we can use ==
+ char *s, line[1024];
+ CacheDir cd;
+ while ( cfgin.getline( line, sizeof(line)) ) {
+ // 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
+ std::string tmpLine(line);
+ if (!std::regex_search(tmpLine, subs, rexp))
+ continue;
+
+ // match, please record
+ memset( &cd, 0, sizeof(cd) );
+ if ( debug ) fprintf( debug, "# match '%s' on line %s", subs[0].str().c_str(), line);
+
+ // 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].str().empty()) {
+ // old version, disk type at position 2 is always UFS
+ cd.type = CacheDir::CDT_UFS;
+ } else {
+ // new version, disk type at position 2
+ if ( debug ) fprintf( debug, "# match '%s' in \"%s\"\n", subs[offset].str().c_str(), subs[0].str().c_str());
+ static const std::string ufsDir("ufs",3);
+ static const std::string aufsDir("aufs",4);
+ static const std::string asyncUfsDir("asyncufs",8);
+ static const std::string diskdDir("diskd",5);
+ if (subs[offset] == ufsDir)
+ cd.type = CacheDir::CDT_UFS;
+ else if (subs[offset] == aufsDir || subs[offset] == asyncUfsDir)
+ cd.type = CacheDir::CDT_AUFS;
+ else if (subs[offset] == diskdDir)
+ cd.type = CacheDir::CDT_DISKD;
+ else
+ cd.type = CacheDir::CDT_OTHER;
+ ++offset;
+ }
+
+ // extract base directory
+ if ( debug ) fprintf( debug, "# match '%s' in \"%s\"\n", subs[offset].str().c_str(), subs[0].str().c_str());
+ cd.base = xstrdup(subs[offset].str().c_str());
+ ++offset;
+
+ // extract size information
+ if ( debug ) fprintf( debug, "# match '%s' in \"%s\"\n", subs[offset].str().c_str(), subs[0].str().c_str());
+ cd.size = strtoul(subs[offset].str().c_str(), 0, 10);
+ ++offset;
+
+ // extract 1st level directories
+ if ( debug ) fprintf( debug, "# match '%s' in \"%s\"\n", subs[offset].str().c_str(), subs[0].str().c_str());
+ cd.level[0] = strtoul(subs[offset].str().c_str(), 0, 10);
+ ++offset;
+
+ // extract 2nd level directories
+ if ( debug ) fprintf( debug, "# match '%s' in \"%s\"\n", subs[offset].str().c_str(), subs[0].str().c_str());
+ cd.level[1] = strtoul(subs[offset].str().c_str(), 0, 10);
+ ++offset;
+
+ cachedir.push_back( cd );
+ }
+
+ cfgin.close();
+ return cachedir.size();
}
+