]> git.saurik.com Git - apt.git/blobdiff - apt-pkg/contrib/configuration.cc
* some WS fixes
[apt.git] / apt-pkg / contrib / configuration.cc
index b3b425cda846affffc8eb7f93c138dbff46b8320..69f8d1dca61dc0d681356a278e6faf2078d13283 100644 (file)
@@ -1,6 +1,6 @@
 // -*- mode: cpp; mode: fold -*-
 // Description                                                         /*{{{*/
-// $Id: configuration.cc,v 1.15 2001/02/20 07:03:17 jgg Exp $
+// $Id: configuration.cc,v 1.28 2004/04/30 04:00:15 mdz Exp $
 /* ######################################################################
 
    Configuration Class
@@ -8,6 +8,9 @@
    This class provides a configuration file and command line parser
    for a tree-oriented configuration environment. All runtime configuration
    is stored in here.
+
+   This source is placed in the Public Domain, do with it what you will
+   It was originally written by Jason Gunthorpe <jgg@debian.org>.
    
    ##################################################################### */
                                                                        /*}}}*/
 #include <vector>
 #include <algorithm>
 #include <fstream>
+#include <iostream>
     
 #include <stdio.h>
 #include <dirent.h>
 #include <sys/stat.h>
 #include <unistd.h>
+
+using namespace std;
                                                                        /*}}}*/
 
 Configuration *_config = new Configuration;
@@ -92,7 +98,7 @@ Configuration::Item *Configuration::Lookup(Item *Head,const char *S,
    if (Len != 0)
    {
       for (; I != 0; Last = &I->Next, I = I->Next)
-        if ((Res = stringcasecmp(I->Tag.begin(),I->Tag.end(),S,S + Len)) == 0)
+        if ((Res = stringcasecmp(I->Tag,S,S + Len)) == 0)
            break;
    }
    else
@@ -276,7 +282,7 @@ string Configuration::FindAny(const char *Name,const char *Default) const
       case 'i': 
       {
         char buf[16];
-        snprintf(buf, sizeof(buf)-1, "%d", FindI(key, Default));
+        snprintf(buf, sizeof(buf)-1, "%d", FindI(key, Default ? atoi(Default) : 0 ));
         return buf;
       }
    }
@@ -377,13 +383,17 @@ bool Configuration::ExistsAny(const char *Name) const
 {
    string key = Name;
 
-   if (key.size() > 2 && key.end()[-2] == '/' &&
-       key.find_first_of("fdbi",key.size()-1) < key.size())
-   {
-      key.resize(key.size() - 2);
-      if (Exists(key.c_str()))
-        return true;
-   }
+   if (key.size() > 2 && key.end()[-2] == '/')
+      if (key.find_first_of("fdbi",key.size()-1) < key.size())
+      {
+         key.resize(key.size() - 2);
+         if (Exists(key.c_str()))
+            return true;
+      }
+      else
+      {
+         _error->Warning(_("Unrecognized type abbreviation: '%c'"), key.end()[-3]);
+      }
 
    return Exists(Name);
 }
@@ -391,14 +401,14 @@ bool Configuration::ExistsAny(const char *Name) const
 // Configuration::Dump - Dump the config                               /*{{{*/
 // ---------------------------------------------------------------------
 /* Dump the entire configuration space */
-void Configuration::Dump()
+void Configuration::Dump(ostream& str)
 {
    /* Write out all of the configuration directives by walking the 
       configuration tree */
    const Configuration::Item *Top = Tree(0);
    for (; Top != 0;)
    {
-      clog << Top->FullTag() << " \"" << Top->Value << "\";" << endl;
+      str << Top->FullTag() << " \"" << Top->Value << "\";" << endl;
       
       if (Top->Child != 0)
       {
@@ -433,16 +443,16 @@ string Configuration::Item::FullTag(const Item *Stop) const
    Sectional config files are like bind's named.conf where there are 
    sections like 'zone "foo.org" { .. };' This causes each section to be
    added in with a tag like "zone::foo.org" instead of being split 
-   tag/value. */
+   tag/value. AsSectional enables Sectional parsing.*/
 bool ReadConfigFile(Configuration &Conf,string FName,bool AsSectional,
                    unsigned Depth)
 {   
    // Open the stream for reading
-   ifstream F(FName.c_str(),ios::in | ios::nocreate);
+   ifstream F(FName.c_str(),ios::in); 
    if (!F != 0)
       return _error->Errno("ifstream::ifstream",_("Opening configuration file %s"),FName.c_str());
    
-   char Buffer[300];
+   char Buffer[1024];
    string LineBuffer;
    string Stack[100];
    unsigned int StackPos = 0;
@@ -456,6 +466,10 @@ bool ReadConfigFile(Configuration &Conf,string FName,bool AsSectional,
    {
       F.getline(Buffer,sizeof(Buffer));
       CurLine++;
+      // This should be made to work instead, but this is better than looping
+      if (F.fail() && !F.eof())
+         return _error->Error(_("Line %d too long (max %d)"), CurLine, sizeof(Buffer));
+
       _strtabexpand(Buffer,sizeof(Buffer));
       _strstrip(Buffer);
 
@@ -569,10 +583,11 @@ bool ReadConfigFile(Configuration &Conf,string FName,bool AsSectional,
            string Tag;
            const char *Pos = LineBuffer.c_str();
            if (ParseQuoteWord(Pos,Tag) == false)
-              return _error->Error(_("Syntax error %s:%u: Malformed Tag"),FName.c_str(),CurLine);
+              return _error->Error(_("Syntax error %s:%u: Malformed tag"),FName.c_str(),CurLine);
 
            // Parse off the word
            string Word;
+           bool NoWord = false;
            if (ParseCWord(Pos,Word) == false &&
                ParseQuoteWord(Pos,Word) == false)
            {
@@ -580,7 +595,9 @@ bool ReadConfigFile(Configuration &Conf,string FName,bool AsSectional,
               {
                  Word = Tag;
                  Tag = "";
-              }               
+              }
+              else
+                 NoWord = true;
            }
            if (strlen(Pos) != 0)
               return _error->Error(_("Syntax error %s:%u: Extra junk after value"),FName.c_str(),CurLine);
@@ -648,7 +665,8 @@ bool ReadConfigFile(Configuration &Conf,string FName,bool AsSectional,
            else
            {
               // Set the item in the configuration class
-              Conf.Set(Item,Word);
+              if (NoWord == false)
+                 Conf.Set(Item,Word);
            }
            
            // Empty the buffer
@@ -686,9 +704,6 @@ bool ReadConfigFile(Configuration &Conf,string FName,bool AsSectional,
 bool ReadConfigDir(Configuration &Conf,string Dir,bool AsSectional,
                    unsigned Depth)
 {   
-   static const char *BadExts[] = {".disabled",".dpkg-old",".dpkg-dist",
-                                  ".rpmsave",".rpmorig","~",",v",0};
-   
    DIR *D = opendir(Dir.c_str());
    if (D == 0)
       return _error->Errno("opendir",_("Unable to read %s"),Dir.c_str());
@@ -697,19 +712,15 @@ bool ReadConfigDir(Configuration &Conf,string Dir,bool AsSectional,
    
    for (struct dirent *Ent = readdir(D); Ent != 0; Ent = readdir(D))
    {
-      if (strcmp(Ent->d_name,".") == 0 ||
-         strcmp(Ent->d_name,"..") == 0)
+      if (Ent->d_name[0] == '.')
         continue;
       
-      // Skip bad extensions
-      const char **I;
-      for (I = BadExts; *I != 0; I++)
-      {
-        if (strcmp(Ent->d_name + strlen(Ent->d_name) - strlen(*I),*I) == 0)
+      // Skip bad file names ala run-parts
+      const char *C = Ent->d_name;
+      for (; *C != 0; C++)
+        if (isalpha(*C) == 0 && isdigit(*C) == 0 && *C != '_' && *C != '-')
            break;
-      }
-      
-      if (*I != 0)
+      if (*C != 0)
         continue;
       
       // Make sure it is a file and not something else