summaryrefslogtreecommitdiff
path: root/apt-pkg/contrib
diff options
context:
space:
mode:
Diffstat (limited to 'apt-pkg/contrib')
-rw-r--r--apt-pkg/contrib/cdromutl.cc14
-rw-r--r--apt-pkg/contrib/cmndline.cc30
-rw-r--r--apt-pkg/contrib/configuration.cc406
-rw-r--r--apt-pkg/contrib/configuration.h57
-rw-r--r--apt-pkg/contrib/error.cc4
-rw-r--r--apt-pkg/contrib/error.h22
-rw-r--r--apt-pkg/contrib/fileutl.cc107
-rw-r--r--apt-pkg/contrib/fileutl.h7
-rw-r--r--apt-pkg/contrib/md5.h4
-rw-r--r--apt-pkg/contrib/mmap.cc23
-rw-r--r--apt-pkg/contrib/progress.cc14
-rw-r--r--apt-pkg/contrib/sptr.h66
-rw-r--r--apt-pkg/contrib/strutl.cc163
-rw-r--r--apt-pkg/contrib/strutl.h38
14 files changed, 788 insertions, 167 deletions
diff --git a/apt-pkg/contrib/cdromutl.cc b/apt-pkg/contrib/cdromutl.cc
index dae6f0528..ab170ec5a 100644
--- a/apt-pkg/contrib/cdromutl.cc
+++ b/apt-pkg/contrib/cdromutl.cc
@@ -1,6 +1,6 @@
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
-// $Id: cdromutl.cc,v 1.11 1999/12/10 23:40:29 jgg Exp $
+// $Id: cdromutl.cc,v 1.12 2001/02/20 07:03:17 jgg Exp $
/* ######################################################################
CDROM Utilities - Some functions to manipulate CDROM mounts.
@@ -19,6 +19,8 @@
#include <apt-pkg/fileutl.h>
#include <apt-pkg/configuration.h>
+#include <apti18n.h>
+
#include <sys/wait.h>
#include <sys/errno.h>
#include <sys/statvfs.h>
@@ -50,7 +52,7 @@ bool IsMounted(string &Path)
struct stat Buf,Buf2;
if (stat(Path.c_str(),&Buf) != 0 ||
stat((Path + "../").c_str(),&Buf2) != 0)
- return _error->Errno("stat","Unable to stat the mount point %s",Path.c_str());
+ return _error->Errno("stat",_("Unable to stat the mount point %s"),Path.c_str());
if (Buf.st_dev == Buf2.st_dev)
return false;
@@ -93,7 +95,7 @@ bool UnmountCdrom(string Path)
}
// Wait for mount
- return ExecWait(Child,"mount",true);
+ return ExecWait(Child,"umount",true);
}
/*}}}*/
// MountCdrom - Mount a cdrom /*{{{*/
@@ -144,11 +146,11 @@ bool IdentCdrom(string CD,string &Res,unsigned int Version)
string StartDir = SafeGetCWD();
if (chdir(CD.c_str()) != 0)
- return _error->Errno("chdir","Unable to change to %s",CD.c_str());
+ return _error->Errno("chdir",_("Unable to change to %s"),CD.c_str());
DIR *D = opendir(".");
if (D == 0)
- return _error->Errno("opendir","Unable to read %s",CD.c_str());
+ return _error->Errno("opendir",_("Unable to read %s"),CD.c_str());
/* Run over the directory, we assume that the reader order will never
change as the media is read-only. In theory if the kernel did
@@ -185,7 +187,7 @@ bool IdentCdrom(string CD,string &Res,unsigned int Version)
{
struct statvfs Buf;
if (statvfs(CD.c_str(),&Buf) != 0)
- return _error->Errno("statfs","Failed to stat the cdrom");
+ return _error->Errno("statfs",_("Failed to stat the cdrom"));
// We use a kilobyte block size to advoid overflow
sprintf(S,"%lu %lu",(long)(Buf.f_blocks*(Buf.f_bsize/1024)),
diff --git a/apt-pkg/contrib/cmndline.cc b/apt-pkg/contrib/cmndline.cc
index 36039c3b8..ea15ae05d 100644
--- a/apt-pkg/contrib/cmndline.cc
+++ b/apt-pkg/contrib/cmndline.cc
@@ -1,6 +1,6 @@
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
-// $Id: cmndline.cc,v 1.10 1999/05/14 02:57:48 jgg Exp $
+// $Id: cmndline.cc,v 1.11 2001/02/20 07:03:17 jgg Exp $
/* ######################################################################
Command Line Class - Sophisticated command line parser
@@ -14,6 +14,8 @@
#include <apt-pkg/cmndline.h>
#include <apt-pkg/error.h>
#include <apt-pkg/strutl.h>
+
+#include <apti18n.h>
/*}}}*/
// CommandLine::CommandLine - Constructor /*{{{*/
@@ -68,7 +70,7 @@ bool CommandLine::Parse(int argc,const char **argv)
Args *A;
for (A = ArgList; A->end() == false && A->ShortOpt != *Opt; A++);
if (A->end() == true)
- return _error->Error("Command line option '%c' [from %s] is not known.",*Opt,argv[I]);
+ return _error->Error(_("Command line option '%c' [from %s] is not known."),*Opt,argv[I]);
if (HandleOpt(I,argc,argv,Opt,A) == false)
return false;
@@ -94,7 +96,7 @@ bool CommandLine::Parse(int argc,const char **argv)
for (; Opt != OptEnd && *Opt != '-'; Opt++);
if (Opt == OptEnd)
- return _error->Error("Command line option %s is not understood",argv[I]);
+ return _error->Error(_("Command line option %s is not understood"),argv[I]);
Opt++;
for (A = ArgList; A->end() == false &&
@@ -102,7 +104,7 @@ bool CommandLine::Parse(int argc,const char **argv)
// Failed again..
if (A->end() == true && OptEnd - Opt != 1)
- return _error->Error("Command line option %s is not understood",argv[I]);
+ return _error->Error(_("Command line option %s is not understood"),argv[I]);
// The option could be a single letter option prefixed by a no-..
if (A->end() == true)
@@ -110,12 +112,12 @@ bool CommandLine::Parse(int argc,const char **argv)
for (A = ArgList; A->end() == false && A->ShortOpt != *Opt; A++);
if (A->end() == true)
- return _error->Error("Command line option %s is not understood",argv[I]);
+ return _error->Error(_("Command line option %s is not understood"),argv[I]);
}
// The option is not boolean
if (A->IsBoolean() == false)
- return _error->Error("Command line option %s is not boolean",argv[I]);
+ return _error->Error(_("Command line option %s is not boolean"),argv[I]);
PreceedMatch = true;
}
@@ -154,7 +156,7 @@ bool CommandLine::HandleOpt(int &I,int argc,const char *argv[],
// Equals was specified but we fell off the end!
if (Opt[1] == '=' && Argument == 0)
- return _error->Error("Option %s requires an argument.",argv[I]);
+ return _error->Error(_("Option %s requires an argument."),argv[I]);
if (Opt[1] == '=')
CertainArg = true;
@@ -175,7 +177,7 @@ bool CommandLine::HandleOpt(int &I,int argc,const char *argv[],
if ((A->Flags & HasArg) == HasArg)
{
if (Argument == 0)
- return _error->Error("Option %s requires an argument.",argv[I]);
+ return _error->Error(_("Option %s requires an argument."),argv[I]);
Opt += strlen(Opt);
I += IncI;
@@ -189,13 +191,13 @@ bool CommandLine::HandleOpt(int &I,int argc,const char *argv[],
const char *J;
for (J = Argument; *J != 0 && *J != '='; J++);
if (*J == 0)
- return _error->Error("Option %s: Configuration item sepecification must have an =<val>.",argv[I]);
+ return _error->Error(_("Option %s: Configuration item sepecification must have an =<val>."),argv[I]);
// = is trailing
if (J[1] == 0)
{
if (I+1 >= argc)
- return _error->Error("Option %s: Configuration item sepecification must have an =<val>.",argv[I]);
+ return _error->Error(_("Option %s: Configuration item sepecification must have an =<val>."),argv[I]);
Conf->Set(string(Argument,J-Argument),string(argv[I++ +1]));
}
else
@@ -225,7 +227,7 @@ bool CommandLine::HandleOpt(int &I,int argc,const char *argv[],
// Conversion failed and the argument was specified with an =s
if (EndPtr == Argument && CertainArg == true)
- return _error->Error("Option %s requires an integer argument, not '%s'",argv[I],Argument);
+ return _error->Error(_("Option %s requires an integer argument, not '%s'"),argv[I],Argument);
// Conversion was ok, set the value and return
if (EndPtr != 0 && EndPtr != Argument && *EndPtr == 0)
@@ -256,7 +258,7 @@ bool CommandLine::HandleOpt(int &I,int argc,const char *argv[],
break;
if (strlen(argv[I]) >= sizeof(Buffer))
- return _error->Error("Option '%s' is too long",argv[I]);
+ return _error->Error(_("Option '%s' is too long"),argv[I]);
// Skip the leading dash
const char *J = argv[I];
@@ -289,7 +291,7 @@ bool CommandLine::HandleOpt(int &I,int argc,const char *argv[],
}
if (CertainArg == true)
- return _error->Error("Sense %s is not understood, try true or false.",Argument);
+ return _error->Error(_("Sense %s is not understood, try true or false."),Argument);
Argument = 0;
}
@@ -339,7 +341,7 @@ bool CommandLine::DispatchArg(Dispatch *Map,bool NoMatch)
if (Map[I].Match == 0)
{
if (NoMatch == true)
- _error->Error("Invalid operation %s",FileList[0]);
+ _error->Error(_("Invalid operation %s"),FileList[0]);
}
return false;
diff --git a/apt-pkg/contrib/configuration.cc b/apt-pkg/contrib/configuration.cc
index 302feee6e..b3b425cda 100644
--- a/apt-pkg/contrib/configuration.cc
+++ b/apt-pkg/contrib/configuration.cc
@@ -1,6 +1,6 @@
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
-// $Id: configuration.cc,v 1.14 2000/01/16 05:36:17 jgg Exp $
+// $Id: configuration.cc,v 1.15 2001/02/20 07:03:17 jgg Exp $
/* ######################################################################
Configuration Class
@@ -18,9 +18,17 @@
#include <apt-pkg/configuration.h>
#include <apt-pkg/error.h>
#include <apt-pkg/strutl.h>
+#include <apt-pkg/fileutl.h>
+#include <apti18n.h>
+#include <vector>
+#include <algorithm>
+#include <fstream>
+
#include <stdio.h>
-#include <fstream.h>
+#include <dirent.h>
+#include <sys/stat.h>
+#include <unistd.h>
/*}}}*/
Configuration *_config = new Configuration;
@@ -28,10 +36,46 @@ Configuration *_config = new Configuration;
// Configuration::Configuration - Constructor /*{{{*/
// ---------------------------------------------------------------------
/* */
-Configuration::Configuration()
+Configuration::Configuration() : ToFree(true)
{
Root = new Item;
}
+Configuration::Configuration(const Item *Root) : Root((Item *)Root), ToFree(false)
+{
+};
+
+ /*}}}*/
+// Configuration::~Configuration - Destructor /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+Configuration::~Configuration()
+{
+ if (ToFree == false)
+ return;
+
+ Item *Top = Root;
+ for (; Top != 0;)
+ {
+ if (Top->Child != 0)
+ {
+ Top = Top->Child;
+ continue;
+ }
+
+ while (Top != 0 && Top->Next == 0)
+ {
+ Item *Parent = Top->Parent;
+ delete Top;
+ Top = Parent;
+ }
+ if (Top != 0)
+ {
+ Item *Next = Top->Next;
+ delete Top;
+ Top = Next;
+ }
+ }
+}
/*}}}*/
// Configuration::Lookup - Lookup a single item /*{{{*/
// ---------------------------------------------------------------------
@@ -105,9 +149,9 @@ Configuration::Item *Configuration::Lookup(const char *Name,bool Create)
// Configuration::Find - Find a value /*{{{*/
// ---------------------------------------------------------------------
/* */
-string Configuration::Find(const char *Name,const char *Default)
+string Configuration::Find(const char *Name,const char *Default) const
{
- Item *Itm = Lookup(Name,false);
+ const Item *Itm = Lookup(Name);
if (Itm == 0 || Itm->Value.empty() == true)
{
if (Default == 0)
@@ -124,9 +168,9 @@ string Configuration::Find(const char *Name,const char *Default)
/* Directories are stored as the base dir in the Parent node and the
sub directory in sub nodes with the final node being the end filename
*/
-string Configuration::FindFile(const char *Name,const char *Default)
+string Configuration::FindFile(const char *Name,const char *Default) const
{
- Item *Itm = Lookup(Name,false);
+ const Item *Itm = Lookup(Name);
if (Itm == 0 || Itm->Value.empty() == true)
{
if (Default == 0)
@@ -135,26 +179,35 @@ string Configuration::FindFile(const char *Name,const char *Default)
return Default;
}
- // Absolute path
- if (Itm->Value[0] == '/' || Itm->Parent == 0)
- return Itm->Value;
-
- // ./ is also considered absolute as is anything with ~ in it
- if (Itm->Value[0] != 0 &&
- ((Itm->Value[0] == '.' && Itm->Value[1] == '/') ||
- (Itm->Value[0] == '~' && Itm->Value[1] == '/')))
- return Itm->Value;
-
- if (Itm->Parent->Value.end()[-1] == '/')
- return Itm->Parent->Value + Itm->Value;
- else
- return Itm->Parent->Value + '/' + Itm->Value;
+ string val = Itm->Value;
+ while (Itm->Parent != 0 && Itm->Parent->Value.empty() == false)
+ {
+ // Absolute
+ if (val.length() >= 1 && val[0] == '/')
+ break;
+
+ // ~/foo or ./foo
+ if (val.length() >= 2 && (val[0] == '~' || val[0] == '.') && val[1] == '/')
+ break;
+
+ // ../foo
+ if (val.length() >= 3 && val[0] == '.' && val[1] == '.' && val[2] == '/')
+ break;
+
+ if (Itm->Parent->Value.end()[-1] != '/')
+ val.insert(0, "/");
+
+ val.insert(0, Itm->Parent->Value);
+ Itm = Itm->Parent;
+ }
+
+ return val;
}
/*}}}*/
// Configuration::FindDir - Find a directory name /*{{{*/
// ---------------------------------------------------------------------
/* This is like findfile execept the result is terminated in a / */
-string Configuration::FindDir(const char *Name,const char *Default)
+string Configuration::FindDir(const char *Name,const char *Default) const
{
string Res = FindFile(Name,Default);
if (Res.end()[-1] != '/')
@@ -165,9 +218,9 @@ string Configuration::FindDir(const char *Name,const char *Default)
// Configuration::FindI - Find an integer value /*{{{*/
// ---------------------------------------------------------------------
/* */
-int Configuration::FindI(const char *Name,int Default)
+int Configuration::FindI(const char *Name,int Default) const
{
- Item *Itm = Lookup(Name,false);
+ const Item *Itm = Lookup(Name);
if (Itm == 0 || Itm->Value.empty() == true)
return Default;
@@ -182,15 +235,68 @@ int Configuration::FindI(const char *Name,int Default)
// Configuration::FindB - Find a boolean type /*{{{*/
// ---------------------------------------------------------------------
/* */
-bool Configuration::FindB(const char *Name,bool Default)
+bool Configuration::FindB(const char *Name,bool Default) const
{
- Item *Itm = Lookup(Name,false);
+ const Item *Itm = Lookup(Name);
if (Itm == 0 || Itm->Value.empty() == true)
return Default;
return StringToBool(Itm->Value,Default);
}
/*}}}*/
+// Configuration::FindAny - Find an arbitrary type /*{{{*/
+// ---------------------------------------------------------------------
+/* a key suffix of /f, /d, /b or /i calls Find{File,Dir,B,I} */
+string Configuration::FindAny(const char *Name,const char *Default) const
+{
+ string key = Name;
+ char type = 0;
+
+ if (key.size() > 2 && key.end()[-2] == '/')
+ {
+ type = key.end()[-1];
+ key.resize(key.size() - 2);
+ }
+
+ switch (type)
+ {
+ // file
+ case 'f':
+ return FindFile(key.c_str(), Default);
+
+ // directory
+ case 'd':
+ return FindDir(key.c_str(), Default);
+
+ // bool
+ case 'b':
+ return FindB(key, Default) ? "true" : "false";
+
+ // int
+ case 'i':
+ {
+ char buf[16];
+ snprintf(buf, sizeof(buf)-1, "%d", FindI(key, Default));
+ return buf;
+ }
+ }
+
+ // fallback
+ return Find(Name, Default);
+}
+ /*}}}*/
+// Configuration::CndSet - Conditinal Set a value /*{{{*/
+// ---------------------------------------------------------------------
+/* This will not overwrite */
+void Configuration::CndSet(const char *Name,string Value)
+{
+ Item *Itm = Lookup(Name,true);
+ if (Itm == 0)
+ return;
+ if (Itm->Value.empty() == true)
+ Itm->Value = Value;
+}
+ /*}}}*/
// Configuration::Set - Set a value /*{{{*/
// ---------------------------------------------------------------------
/* */
@@ -215,17 +321,73 @@ void Configuration::Set(const char *Name,int Value)
Itm->Value = S;
}
/*}}}*/
+// Configuration::Clear - Clear an entire tree /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+void Configuration::Clear(string Name)
+{
+ Item *Top = Lookup(Name.c_str(),false);
+ if (Top == 0)
+ return;
+
+ Top->Value = string();
+ Item *Stop = Top;
+ Top = Top->Child;
+ Stop->Child = 0;
+ for (; Top != 0;)
+ {
+ if (Top->Child != 0)
+ {
+ Top = Top->Child;
+ continue;
+ }
+
+ while (Top != 0 && Top->Next == 0)
+ {
+ Item *Tmp = Top;
+ Top = Top->Parent;
+ delete Tmp;
+
+ if (Top == Stop)
+ return;
+ }
+
+ Item *Tmp = Top;
+ if (Top != 0)
+ Top = Top->Next;
+ delete Tmp;
+ }
+}
+ /*}}}*/
// Configuration::Exists - Returns true if the Name exists /*{{{*/
// ---------------------------------------------------------------------
/* */
-bool Configuration::Exists(const char *Name)
+bool Configuration::Exists(const char *Name) const
{
- Item *Itm = Lookup(Name,false);
+ const Item *Itm = Lookup(Name);
if (Itm == 0)
return false;
return true;
}
/*}}}*/
+// Configuration::ExistsAny - Returns true if the Name, possibly /*{{{*/
+// ---------------------------------------------------------------------
+/* qualified by /[fdbi] exists */
+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;
+ }
+
+ return Exists(Name);
+}
+ /*}}}*/
// Configuration::Dump - Dump the config /*{{{*/
// ---------------------------------------------------------------------
/* Dump the entire configuration space */
@@ -233,7 +395,7 @@ void Configuration::Dump()
{
/* Write out all of the configuration directives by walking the
configuration tree */
- const Configuration::Item *Top = _config->Tree(0);
+ const Configuration::Item *Top = Tree(0);
for (; Top != 0;)
{
clog << Top->FullTag() << " \"" << Top->Value << "\";" << endl;
@@ -248,31 +410,37 @@ void Configuration::Dump()
Top = Top->Parent;
if (Top != 0)
Top = Top->Next;
- }
+ }
}
/*}}}*/
// Configuration::Item::FullTag - Return the fully scoped tag /*{{{*/
// ---------------------------------------------------------------------
-/* */
-string Configuration::Item::FullTag() const
+/* Stop sets an optional max recursion depth if this item is being viewed as
+ part of a sub tree. */
+string Configuration::Item::FullTag(const Item *Stop) const
{
- if (Parent == 0 || Parent->Parent == 0)
+ if (Parent == 0 || Parent->Parent == 0 || Parent == Stop)
return Tag;
- return Parent->FullTag() + "::" + Tag;
+ return Parent->FullTag(Stop) + "::" + Tag;
}
/*}}}*/
// ReadConfigFile - Read a configuration file /*{{{*/
// ---------------------------------------------------------------------
/* The configuration format is very much like the named.conf format
- used in bind8, in fact this routine can parse most named.conf files. */
-bool ReadConfigFile(Configuration &Conf,string FName)
-{
+ used in bind8, in fact this routine can parse most named.conf files.
+ 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. */
+bool ReadConfigFile(Configuration &Conf,string FName,bool AsSectional,
+ unsigned Depth)
+{
// Open the stream for reading
ifstream F(FName.c_str(),ios::in | ios::nocreate);
if (!F != 0)
- return _error->Errno("ifstream::ifstream","Opening configuration file %s",FName.c_str());
+ return _error->Errno("ifstream::ifstream",_("Opening configuration file %s"),FName.c_str());
char Buffer[300];
string LineBuffer;
@@ -366,7 +534,7 @@ bool ReadConfigFile(Configuration &Conf,string FName)
if (InQuote == false && (*I == '{' || *I == ';' || *I == '}'))
{
- // Put the last fragement into the buffer
+ // Put the last fragment into the buffer
char *Start = Buffer;
char *Stop = I;
for (; Start != I && isspace(*Start) != 0; Start++);
@@ -379,51 +547,65 @@ bool ReadConfigFile(Configuration &Conf,string FName)
char TermChar = *I;
memmove(Buffer,I + 1,strlen(I + 1) + 1);
I = Buffer;
-
- // Move up a tag
- if (TermChar == '}')
- {
- if (StackPos == 0)
- ParentTag = string();
- else
- ParentTag = Stack[--StackPos];
- }
// Syntax Error
if (TermChar == '{' && LineBuffer.empty() == true)
- return _error->Error("Syntax error %s:%u: Block starts with no name.",FName.c_str(),CurLine);
+ return _error->Error(_("Syntax error %s:%u: Block starts with no name."),FName.c_str(),CurLine);
+ // No string on this line
if (LineBuffer.empty() == true)
+ {
+ if (TermChar == '}')
+ {
+ if (StackPos == 0)
+ ParentTag = string();
+ else
+ ParentTag = Stack[--StackPos];
+ }
continue;
-
+ }
+
// Parse off the tag
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;
+ if (ParseCWord(Pos,Word) == false &&
+ ParseQuoteWord(Pos,Word) == false)
+ {
+ if (TermChar != '{')
+ {
+ Word = Tag;
+ Tag = "";
+ }
+ }
+ if (strlen(Pos) != 0)
+ return _error->Error(_("Syntax error %s:%u: Extra junk after value"),FName.c_str(),CurLine);
+
// Go down a level
if (TermChar == '{')
{
if (StackPos <= 100)
Stack[StackPos++] = ParentTag;
+
+ /* Make sectional tags incorperate the section into the
+ tag string */
+ if (AsSectional == true && Word.empty() == false)
+ {
+ Tag += "::" ;
+ Tag += Word;
+ Word = "";
+ }
+
if (ParentTag.empty() == true)
ParentTag = Tag;
else
ParentTag += string("::") + Tag;
Tag = string();
}
-
- // Parse off the word
- string Word;
- if (ParseCWord(Pos,Word) == false)
- {
- if (TermChar != '{')
- {
- Word = Tag;
- Tag = "";
- }
- }
// Generate the item name
string Item;
@@ -437,11 +619,50 @@ bool ReadConfigFile(Configuration &Conf,string FName)
Item = ParentTag;
}
- // Set the item in the configuration class
- Conf.Set(Item,Word);
-
+ // Specials
+ if (Tag.length() >= 1 && Tag[0] == '#')
+ {
+ if (ParentTag.empty() == false)
+ return _error->Error(_("Syntax error %s:%u: Directives can only be done at the top level"),FName.c_str(),CurLine);
+ Tag.erase(Tag.begin());
+ if (Tag == "clear")
+ Conf.Clear(Word);
+ else if (Tag == "include")
+ {
+ if (Depth > 10)
+ return _error->Error(_("Syntax error %s:%u: Too many nested includes"),FName.c_str(),CurLine);
+ if (Word.length() > 2 && Word.end()[-1] == '/')
+ {
+ if (ReadConfigDir(Conf,Word,AsSectional,Depth+1) == false)
+ return _error->Error(_("Syntax error %s:%u: Included from here"),FName.c_str(),CurLine);
+ }
+ else
+ {
+ if (ReadConfigFile(Conf,Word,AsSectional,Depth+1) == false)
+ return _error->Error(_("Syntax error %s:%u: Included from here"),FName.c_str(),CurLine);
+ }
+ }
+ else
+ return _error->Error(_("Syntax error %s:%u: Unsupported directive '%s'"),FName.c_str(),CurLine,Tag.c_str());
+ }
+ else
+ {
+ // Set the item in the configuration class
+ Conf.Set(Item,Word);
+ }
+
// Empty the buffer
LineBuffer = string();
+
+ // Move up a tag, but only if there is no bit to parse
+ if (TermChar == '}')
+ {
+ if (StackPos == 0)
+ ParentTag = string();
+ else
+ ParentTag = Stack[--StackPos];
+ }
+
}
else
I++;
@@ -453,7 +674,60 @@ bool ReadConfigFile(Configuration &Conf,string FName)
LineBuffer += " ";
LineBuffer += Stripd;
}
+
+ if (LineBuffer.empty() == false)
+ return _error->Error(_("Syntax error %s:%u: Extra junk at end of file"),FName.c_str(),CurLine);
+ return true;
+}
+ /*}}}*/
+// ReadConfigDir - Read a directory of config files /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+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());
+
+ vector<string> List;
+
+ for (struct dirent *Ent = readdir(D); Ent != 0; Ent = readdir(D))
+ {
+ if (strcmp(Ent->d_name,".") == 0 ||
+ strcmp(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)
+ break;
+ }
+
+ if (*I != 0)
+ continue;
+
+ // Make sure it is a file and not something else
+ string File = flCombine(Dir,Ent->d_name);
+ struct stat St;
+ if (stat(File.c_str(),&St) != 0 || S_ISREG(St.st_mode) == 0)
+ continue;
+
+ List.push_back(File);
+ }
+ closedir(D);
+ sort(List.begin(),List.end());
+
+ // Read the files
+ for (vector<string>::const_iterator I = List.begin(); I != List.end(); I++)
+ if (ReadConfigFile(Conf,*I,AsSectional,Depth) == false)
+ return false;
return true;
}
/*}}}*/
diff --git a/apt-pkg/contrib/configuration.h b/apt-pkg/contrib/configuration.h
index aeb181c7a..643e0f628 100644
--- a/apt-pkg/contrib/configuration.h
+++ b/apt-pkg/contrib/configuration.h
@@ -1,6 +1,6 @@
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
-// $Id: configuration.h,v 1.11 1999/04/03 00:34:33 jgg Exp $
+// $Id: configuration.h,v 1.12 2001/02/20 07:03:17 jgg Exp $
/* ######################################################################
Configuration Class
@@ -36,6 +36,8 @@
class Configuration
{
+ public:
+
struct Item
{
string Value;
@@ -44,42 +46,61 @@ class Configuration
Item *Child;
Item *Next;
- string FullTag() const;
+ string FullTag(const Item *Stop = 0) const;
Item() : Parent(0), Child(0), Next(0) {};
};
+
+ private:
+
Item *Root;
+ bool ToFree;
Item *Lookup(Item *Head,const char *S,unsigned long Len,bool Create);
- Item *Lookup(const char *Name,bool Create);
-
+ Item *Lookup(const char *Name,bool Create);
+ inline const Item *Lookup(const char *Name) const
+ {
+ return ((Configuration *)this)->Lookup(Name,false);
+ }
+
public:
- string Find(const char *Name,const char *Default = 0);
- string Find(string Name,const char *Default = 0) {return Find(Name.c_str(),Default);};
- string FindFile(const char *Name,const char *Default = 0);
- string FindDir(const char *Name,const char *Default = 0);
- int FindI(const char *Name,int Default = 0);
- int FindI(string Name,bool Default = 0) {return FindI(Name.c_str(),Default);};
- bool FindB(const char *Name,bool Default = false);
- bool FindB(string Name,bool Default = false) {return FindB(Name.c_str(),Default);};
+ string Find(const char *Name,const char *Default = 0) const;
+ string Find(string Name,const char *Default = 0) const {return Find(Name.c_str(),Default);};
+ string FindFile(const char *Name,const char *Default = 0) const;
+ string FindDir(const char *Name,const char *Default = 0) const;
+ int FindI(const char *Name,int Default = 0) const;
+ int FindI(string Name,bool Default = 0) const {return FindI(Name.c_str(),Default);};
+ bool FindB(const char *Name,bool Default = false) const;
+ bool FindB(string Name,bool Default = false) const {return FindB(Name.c_str(),Default);};
+ string FindAny(const char *Name,const char *Default = 0) const;
inline void Set(string Name,string Value) {Set(Name.c_str(),Value);};
+ void CndSet(const char *Name,string Value);
void Set(const char *Name,string Value);
void Set(const char *Name,int Value);
- inline bool Exists(string Name) {return Exists(Name.c_str());};
- bool Exists(const char *Name);
-
- inline const Item *Tree(const char *Name) {return Lookup(Name,false);};
+ inline bool Exists(string Name) const {return Exists(Name.c_str());};
+ bool Exists(const char *Name) const;
+ bool ExistsAny(const char *Name) const;
- void Dump();
+ void Clear(string Name);
+ inline const Item *Tree(const char *Name) const {return Lookup(Name);};
+
+ void Dump();
+
+ Configuration(const Item *Root);
Configuration();
+ ~Configuration();
};
extern Configuration *_config;
-bool ReadConfigFile(Configuration &Conf,string File);
+bool ReadConfigFile(Configuration &Conf,string FName,bool AsSectional = false,
+ unsigned Depth = 0);
+
+bool ReadConfigDir(Configuration &Conf,string Dir,bool AsSectional = false,
+ unsigned Depth = 0);
#endif
diff --git a/apt-pkg/contrib/error.cc b/apt-pkg/contrib/error.cc
index e8b71fa7d..b60bd09a7 100644
--- a/apt-pkg/contrib/error.cc
+++ b/apt-pkg/contrib/error.cc
@@ -1,6 +1,6 @@
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
-// $Id: error.cc,v 1.8 1999/08/08 07:24:54 jgg Exp $
+// $Id: error.cc,v 1.9 2001/02/20 07:03:17 jgg Exp $
/* ######################################################################
Global Erorr Class - Global error mechanism
@@ -34,7 +34,7 @@
is compiled to be thread safe otherwise a non-safe version is used. A
Per-Thread error object is maintained in much the same manner as libc
manages errno */
-#if _POSIX_THREADS == 1 && defined(HAVE_PTHREAD)
+#if defined(_POSIX_THREADS) && defined(HAVE_PTHREAD)
#include <pthread.h>
static pthread_key_t ErrorKey;
diff --git a/apt-pkg/contrib/error.h b/apt-pkg/contrib/error.h
index bb42e73ba..0dc57927a 100644
--- a/apt-pkg/contrib/error.h
+++ b/apt-pkg/contrib/error.h
@@ -1,6 +1,6 @@
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
-// $Id: error.h,v 1.6 1999/01/18 06:20:08 jgg Exp $
+// $Id: error.h,v 1.7 2001/02/20 07:03:17 jgg Exp $
/* ######################################################################
Global Erorr Class - Global error mechanism
@@ -44,6 +44,15 @@
#pragma interface "apt-pkg/error.h"
#endif
+#ifdef __GNUG__
+// Methods have a hidden this parameter that is visible to this attribute
+#define APT_MFORMAT1 __attribute__ ((format (printf, 2, 3)))
+#define APT_MFORMAT2 __attribute__ ((format (printf, 3, 4)))
+#else
+#define APT_MFORMAT1
+#define APT_MFORMAT2
+#endif
+
#include <string>
class GlobalError
@@ -62,13 +71,13 @@ class GlobalError
public:
// Call to generate an error from a library call.
- bool Errno(const char *Function,const char *Description,...);
- bool WarningE(const char *Function,const char *Description,...);
+ bool Errno(const char *Function,const char *Description,...) APT_MFORMAT2;
+ bool WarningE(const char *Function,const char *Description,...) APT_MFORMAT2;
/* A warning should be considered less severe than an error, and may be
ignored by the client. */
- bool Error(const char *Description,...);
- bool Warning(const char *Description,...);
+ bool Error(const char *Description,...) APT_MFORMAT1;
+ bool Warning(const char *Description,...) APT_MFORMAT1;
// Simple accessors
inline bool PendingError() {return PendingFlag;};
@@ -86,4 +95,7 @@ class GlobalError
GlobalError *_GetErrorObj();
#define _error _GetErrorObj()
+#undef APT_MFORMAT1
+#undef APT_MFORMAT2
+
#endif
diff --git a/apt-pkg/contrib/fileutl.cc b/apt-pkg/contrib/fileutl.cc
index 65c19ea92..0907f4dcd 100644
--- a/apt-pkg/contrib/fileutl.cc
+++ b/apt-pkg/contrib/fileutl.cc
@@ -1,6 +1,6 @@
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
-// $Id: fileutl.cc,v 1.34 2000/01/17 07:11:49 jgg Exp $
+// $Id: fileutl.cc,v 1.35 2001/02/20 07:03:17 jgg Exp $
/* ######################################################################
File Utilities
@@ -19,6 +19,9 @@
#endif
#include <apt-pkg/fileutl.h>
#include <apt-pkg/error.h>
+#include <apt-pkg/sptr.h>
+
+#include <apti18n.h>
#include <unistd.h>
#include <fcntl.h>
@@ -39,7 +42,7 @@ bool CopyFile(FileFd &From,FileFd &To)
return false;
// Buffered copy between fds
- unsigned char *Buf = new unsigned char[64000];
+ SPtrArray<unsigned char> Buf = new unsigned char[64000];
unsigned long Size = From.Size();
while (Size != 0)
{
@@ -49,15 +52,11 @@ bool CopyFile(FileFd &From,FileFd &To)
if (From.Read(Buf,ToRead) == false ||
To.Write(Buf,ToRead) == false)
- {
- delete [] Buf;
return false;
- }
Size -= ToRead;
}
- delete [] Buf;
return true;
}
/*}}}*/
@@ -72,11 +71,22 @@ int GetLock(string File,bool Errors)
int FD = open(File.c_str(),O_RDWR | O_CREAT | O_TRUNC,0640);
if (FD < 0)
{
+ // Read only .. cant have locking problems there.
+ if (errno == EROFS)
+ {
+ _error->Warning(_("Not using locking for read only lock file %s"),File.c_str());
+ return dup(0); // Need something for the caller to close
+ }
+
if (Errors == true)
- _error->Errno("open","Could not open lock file %s",File.c_str());
+ _error->Errno("open",_("Could not open lock file %s"),File.c_str());
+
+ // Feh.. We do this to distinguish the lock vs open case..
+ errno = EPERM;
return -1;
}
-
+ SetCloseExec(FD,true);
+
// Aquire a write lock
struct flock fl;
fl.l_type = F_WRLCK;
@@ -87,12 +97,15 @@ int GetLock(string File,bool Errors)
{
if (errno == ENOLCK)
{
- _error->Warning("Not using locking for nfs mounted lock file %s",File.c_str());
- return true;
+ _error->Warning(_("Not using locking for nfs mounted lock file %s"),File.c_str());
+ return dup(0); // Need something for the caller to close
}
if (Errors == true)
- _error->Errno("open","Could not get lock %s",File.c_str());
+ _error->Errno("open",_("Could not get lock %s"),File.c_str());
+
+ int Tmp = errno;
close(FD);
+ errno = Tmp;
return -1;
}
@@ -150,6 +163,18 @@ string flNotFile(string File)
return string(File,0,Res);
}
/*}}}*/
+// flExtension - Return the extension for the file /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+string flExtension(string File)
+{
+ string::size_type Res = File.rfind('.');
+ if (Res == string::npos)
+ return File;
+ Res++;
+ return string(File,Res,Res - File.length());
+}
+ /*}}}*/
// flNoLink - If file is a symlink then deref it /*{{{*/
// ---------------------------------------------------------------------
/* If the name is not a link then the returned path is the input. */
@@ -189,6 +214,24 @@ string flNoLink(string File)
}
}
/*}}}*/
+// flCombine - Combine a file and a directory /*{{{*/
+// ---------------------------------------------------------------------
+/* If the file is an absolute path then it is just returned, otherwise
+ the directory is pre-pended to it. */
+string flCombine(string Dir,string File)
+{
+ if (File.empty() == true)
+ return string();
+
+ if (File[0] == '/' || Dir.empty() == true)
+ return File;
+ if (File.length() >= 2 && File[0] == '.' && File[1] == '/')
+ return File;
+ if (Dir[Dir.length()-1] == '/')
+ return Dir + File;
+ return Dir + '/' + File;
+}
+ /*}}}*/
// SetCloseExec - Set the close on exec flag /*{{{*/
// ---------------------------------------------------------------------
/* */
@@ -216,7 +259,7 @@ void SetNonBlock(int Fd,bool Block)
/*}}}*/
// WaitFd - Wait for a FD to become readable /*{{{*/
// ---------------------------------------------------------------------
-/* This waits for a FD to become readable using select. It is usefull for
+/* This waits for a FD to become readable using select. It is useful for
applications making use of non-blocking sockets. The timeout is
in seconds. */
bool WaitFd(int Fd,bool write,unsigned long timeout)
@@ -309,7 +352,7 @@ bool ExecWait(int Pid,const char *Name,bool Reap)
if (Reap == true)
return false;
- return _error->Error("Waited, for %s but it wasn't there",Name);
+ return _error->Error(_("Waited, for %s but it wasn't there"),Name);
}
@@ -319,12 +362,12 @@ bool ExecWait(int Pid,const char *Name,bool Reap)
if (Reap == true)
return false;
if (WIFSIGNALED(Status) != 0 && WTERMSIG(Status) == SIGSEGV)
- return _error->Error("Sub-process %s recieved a segmentation fault.",Name);
+ return _error->Error(_("Sub-process %s received a segmentation fault."),Name);
if (WIFEXITED(Status) != 0)
- return _error->Error("Sub-process %s returned an error code (%u)",Name,WEXITSTATUS(Status));
+ return _error->Error(_("Sub-process %s returned an error code (%u)"),Name,WEXITSTATUS(Status));
- return _error->Error("Sub-process %s exited unexpectedly",Name);
+ return _error->Error(_("Sub-process %s exited unexpectedly"),Name);
}
return true;
@@ -363,7 +406,7 @@ bool FileFd::Open(string FileName,OpenMode Mode, unsigned long Perms)
}
if (iFd < 0)
- return _error->Errno("open","Could not open file %s",FileName.c_str());
+ return _error->Errno("open",_("Could not open file %s"),FileName.c_str());
this->FileName = FileName;
SetCloseExec(iFd,true);
@@ -395,7 +438,7 @@ bool FileFd::Read(void *To,unsigned long Size,bool AllowEof)
if (Res < 0)
{
Flags |= Fail;
- return _error->Errno("read","Read error");
+ return _error->Errno("read",_("Read error"));
}
To = (char *)To + Res;
@@ -414,7 +457,7 @@ bool FileFd::Read(void *To,unsigned long Size,bool AllowEof)
}
Flags |= Fail;
- return _error->Error("read, still have %u to read but none left",Size);
+ return _error->Error(_("read, still have %lu to read but none left"),Size);
}
/*}}}*/
// FileFd::Write - Write to the file /*{{{*/
@@ -432,7 +475,7 @@ bool FileFd::Write(const void *From,unsigned long Size)
if (Res < 0)
{
Flags |= Fail;
- return _error->Errno("write","Write error");
+ return _error->Errno("write",_("Write error"));
}
From = (char *)From + Res;
@@ -444,7 +487,7 @@ bool FileFd::Write(const void *From,unsigned long Size)
return true;
Flags |= Fail;
- return _error->Error("write, still have %u to write but couldn't",Size);
+ return _error->Error(_("write, still have %lu to write but couldn't"),Size);
}
/*}}}*/
// FileFd::Seek - Seek in the file /*{{{*/
@@ -455,7 +498,7 @@ bool FileFd::Seek(unsigned long To)
if (lseek(iFd,To,SEEK_SET) != (signed)To)
{
Flags |= Fail;
- return _error->Error("Unable to seek to %u",To);
+ return _error->Error("Unable to seek to %lu",To);
}
return true;
@@ -469,7 +512,7 @@ bool FileFd::Skip(unsigned long Over)
if (lseek(iFd,Over,SEEK_CUR) < 0)
{
Flags |= Fail;
- return _error->Error("Unable to seek ahead %u",Over);
+ return _error->Error("Unable to seek ahead %lu",Over);
}
return true;
@@ -483,7 +526,7 @@ bool FileFd::Truncate(unsigned long To)
if (ftruncate(iFd,To) != 0)
{
Flags |= Fail;
- return _error->Error("Unable to truncate to %u",To);
+ return _error->Error("Unable to truncate to %lu",To);
}
return true;
@@ -519,13 +562,25 @@ bool FileFd::Close()
bool Res = true;
if ((Flags & AutoClose) == AutoClose)
if (iFd >= 0 && close(iFd) != 0)
- Res &= _error->Errno("close","Problem closing the file");
+ Res &= _error->Errno("close",_("Problem closing the file"));
iFd = -1;
if ((Flags & Fail) == Fail && (Flags & DelOnFail) == DelOnFail &&
FileName.empty() == false)
if (unlink(FileName.c_str()) != 0)
- Res &= _error->Warning("unlnk","Problem unlinking the file");
+ Res &= _error->WarningE("unlnk",_("Problem unlinking the file"));
return Res;
}
/*}}}*/
+// FileFd::Sync - Sync the file /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool FileFd::Sync()
+{
+#ifdef _POSIX_SYNCHRONIZED_IO
+ if (fsync(iFd) != 0)
+ return _error->Errno("sync",_("Problem syncing the file"));
+#endif
+ return true;
+}
+ /*}}}*/
diff --git a/apt-pkg/contrib/fileutl.h b/apt-pkg/contrib/fileutl.h
index 7ad630ce3..9cf351d0b 100644
--- a/apt-pkg/contrib/fileutl.h
+++ b/apt-pkg/contrib/fileutl.h
@@ -1,6 +1,6 @@
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
-// $Id: fileutl.h,v 1.22 1999/09/30 06:30:34 jgg Exp $
+// $Id: fileutl.h,v 1.23 2001/02/20 07:03:17 jgg Exp $
/* ######################################################################
File Utilities
@@ -49,7 +49,8 @@ class FileFd
unsigned long Size();
bool Open(string FileName,OpenMode Mode,unsigned long Perms = 0666);
bool Close();
-
+ bool Sync();
+
// Simple manipulators
inline int Fd() {return iFd;};
inline void Fd(int fd) {iFd = fd;};
@@ -84,5 +85,7 @@ bool ExecWait(int Pid,const char *Name,bool Reap = false);
string flNotDir(string File);
string flNotFile(string File);
string flNoLink(string File);
+string flExtension(string File);
+string flCombine(string Dir,string File);
#endif
diff --git a/apt-pkg/contrib/md5.h b/apt-pkg/contrib/md5.h
index 19b5bac6c..8b809729b 100644
--- a/apt-pkg/contrib/md5.h
+++ b/apt-pkg/contrib/md5.h
@@ -1,6 +1,6 @@
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
-// $Id: md5.h,v 1.4 1999/08/02 03:07:47 jgg Exp $
+// $Id: md5.h,v 1.5 2001/02/20 07:03:17 jgg Exp $
/* ######################################################################
MD5SumValue - Storage for a MD5Sum
@@ -33,7 +33,7 @@ class MD5Summation;
class MD5SumValue
{
- friend MD5Summation;
+ friend class MD5Summation;
unsigned char Sum[4*4];
public:
diff --git a/apt-pkg/contrib/mmap.cc b/apt-pkg/contrib/mmap.cc
index 230e133a5..cfe476763 100644
--- a/apt-pkg/contrib/mmap.cc
+++ b/apt-pkg/contrib/mmap.cc
@@ -1,6 +1,6 @@
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
-// $Id: mmap.cc,v 1.20 1999/10/02 04:14:54 jgg Exp $
+// $Id: mmap.cc,v 1.21 2001/02/20 07:03:17 jgg Exp $
/* ######################################################################
MMap Class - Provides 'real' mmap or a faked mmap using read().
@@ -29,6 +29,8 @@
#include <apt-pkg/mmap.h>
#include <apt-pkg/error.h>
+#include <apti18n.h>
+
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>
@@ -77,12 +79,12 @@ bool MMap::Map(FileFd &Fd)
Map = MAP_PRIVATE;
if (iSize == 0)
- return _error->Error("Can't mmap an empty file");
+ return _error->Error(_("Can't mmap an empty file"));
// Map it.
Base = mmap(0,iSize,Prot,Map,Fd.Fd(),0);
if (Base == (void *)-1)
- return _error->Errno("mmap","Couldn't make mmap of %u bytes",iSize);
+ return _error->Errno("mmap",_("Couldn't make mmap of %lu bytes"),iSize);
return true;
}
@@ -102,6 +104,7 @@ bool MMap::Close(bool DoSync)
_error->Warning("Unable to munmap");
iSize = 0;
+ Base = 0;
return true;
}
/*}}}*/
@@ -150,9 +153,15 @@ DynamicMMap::DynamicMMap(FileFd &F,unsigned long Flags,unsigned long WorkSpace)
return;
unsigned long EndOfFile = Fd->Size();
- Fd->Seek(WorkSpace);
- char C = 0;
- Fd->Write(&C,sizeof(C));
+ if (EndOfFile > WorkSpace)
+ WorkSpace = EndOfFile;
+ else
+ {
+ Fd->Seek(WorkSpace);
+ char C = 0;
+ Fd->Write(&C,sizeof(C));
+ }
+
Map(F);
iSize = EndOfFile;
}
@@ -182,11 +191,9 @@ DynamicMMap::~DynamicMMap()
}
unsigned long EndOfFile = iSize;
- Sync();
iSize = WorkSpace;
Close(false);
ftruncate(Fd->Fd(),EndOfFile);
- Fd->Close();
}
/*}}}*/
// DynamicMMap::RawAllocate - Allocate a raw chunk of unaligned space /*{{{*/
diff --git a/apt-pkg/contrib/progress.cc b/apt-pkg/contrib/progress.cc
index dfa978485..70e488d5f 100644
--- a/apt-pkg/contrib/progress.cc
+++ b/apt-pkg/contrib/progress.cc
@@ -1,6 +1,6 @@
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
-// $Id: progress.cc,v 1.9 2000/06/05 04:22:25 jgg Exp $
+// $Id: progress.cc,v 1.10 2001/02/20 07:03:17 jgg Exp $
/* ######################################################################
OpProgress - Operation Progress
@@ -14,6 +14,9 @@
#include <apt-pkg/progress.h>
#include <apt-pkg/error.h>
#include <apt-pkg/configuration.h>
+
+#include <apti18n.h>
+
#include <stdio.h>
/*}}}*/
@@ -110,6 +113,9 @@ bool OpProgress::CheckChange(float Interval)
if ((int)LastPercent == (int)Percent)
return false;
+ if (Interval == 0)
+ return false;
+
// Check time delta
struct timeval Now;
gettimeofday(&Now,0);
@@ -142,9 +148,9 @@ void OpTextProgress::Done()
{
char S[300];
if (_error->PendingError() == true)
- snprintf(S,sizeof(S),"\r%s... Error!",OldOp.c_str());
+ snprintf(S,sizeof(S),_("\r%s... Error!"),OldOp.c_str());
else
- snprintf(S,sizeof(S),"\r%s... Done",OldOp.c_str());
+ snprintf(S,sizeof(S),_("\r%s... Done"),OldOp.c_str());
Write(S);
cout << endl;
OldOp = string();
@@ -162,7 +168,7 @@ void OpTextProgress::Done()
/* */
void OpTextProgress::Update()
{
- if (CheckChange() == false)
+ if (CheckChange((NoUpdate == true?0:0.7)) == false)
return;
// No percent spinner
diff --git a/apt-pkg/contrib/sptr.h b/apt-pkg/contrib/sptr.h
new file mode 100644
index 000000000..a9347edf9
--- /dev/null
+++ b/apt-pkg/contrib/sptr.h
@@ -0,0 +1,66 @@
+// -*- mode: cpp; mode: fold -*-
+// Description /*{{{*/
+// $Id: sptr.h,v 1.2 2001/02/20 07:03:17 jgg Exp $
+/* ######################################################################
+
+ Trivial non-ref counted 'smart pointer'
+
+ This is really only good to eliminate
+ {
+ delete Foo;
+ return;
+ }
+
+ Blocks from functions.
+
+ I think G++ has become good enough that doing this won't have much
+ code size implications.
+
+ ##################################################################### */
+ /*}}}*/
+#ifndef SMART_POINTER_H
+#define SMART_POINTER_H
+
+template <class T>
+class SPtr
+{
+ public:
+ T *Ptr;
+
+ inline T *operator ->() {return Ptr;};
+ inline T &operator *() {return *Ptr;};
+ inline operator T *() {return Ptr;};
+ inline operator void *() {return Ptr;};
+ inline T *UnGuard() {T *Tmp = Ptr; Ptr = 0; return Tmp;};
+ inline void operator =(T *N) {Ptr = N;};
+ inline bool operator ==(T *lhs) const {return Ptr == lhs;};
+ inline bool operator !=(T *lhs) const {return Ptr != lhs;};
+ inline T*Get() {return Ptr;};
+
+ inline SPtr(T *Ptr) : Ptr(Ptr) {};
+ inline SPtr() : Ptr(0) {};
+ inline ~SPtr() {delete Ptr;};
+};
+
+template <class T>
+class SPtrArray
+{
+ public:
+ T *Ptr;
+
+ inline T &operator *() {return *Ptr;};
+ inline operator T *() {return Ptr;};
+ inline operator void *() {return Ptr;};
+ inline T *UnGuard() {T *Tmp = Ptr; Ptr = 0; return Tmp;};
+ inline T &operator [](signed long I) {return Ptr[I];};
+ inline void operator =(T *N) {Ptr = N;};
+ inline bool operator ==(T *lhs) const {return Ptr == lhs;};
+ inline bool operator !=(T *lhs) const {return Ptr != lhs;};
+ inline T*Get() {return Ptr;};
+
+ inline SPtrArray(T *Ptr) : Ptr(Ptr) {};
+ inline SPtrArray() : Ptr(0) {};
+ inline ~SPtrArray() {delete []Ptr;};
+};
+
+#endif
diff --git a/apt-pkg/contrib/strutl.cc b/apt-pkg/contrib/strutl.cc
index f8a3f8e2b..c1a1cb4db 100644
--- a/apt-pkg/contrib/strutl.cc
+++ b/apt-pkg/contrib/strutl.cc
@@ -1,12 +1,12 @@
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
-// $Id: strutl.cc,v 1.34 2000/01/16 05:36:17 jgg Exp $
+// $Id: strutl.cc,v 1.35 2001/02/20 07:03:17 jgg Exp $
/* ######################################################################
- String Util - Some usefull string functions.
+ String Util - Some useful string functions.
- These have been collected from here and there to do all sorts of usefull
- things to strings. They are usefull in file parsers, URI handlers and
+ These have been collected from here and there to do all sorts of useful
+ things to strings. They are useful in file parsers, URI handlers and
especially in APT methods.
This source is placed in the Public Domain, do with it what you will
@@ -21,12 +21,17 @@
#include <apt-pkg/strutl.h>
#include <apt-pkg/fileutl.h>
+#include <apt-pkg/error.h>
+#include <apti18n.h>
+
#include <ctype.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
+#include <regex.h>
#include <errno.h>
+#include <stdarg.h>
/*}}}*/
// strstrip - Remove white space from the front and back of a string /*{{{*/
@@ -147,9 +152,9 @@ bool ParseQuoteWord(const char *&String,string &Res)
/*}}}*/
// ParseCWord - Parses a string like a C "" expression /*{{{*/
// ---------------------------------------------------------------------
-/* This expects a series of space seperated strings enclosed in ""'s.
+/* This expects a series of space separated strings enclosed in ""'s.
It concatenates the ""'s into a single string. */
-bool ParseCWord(const char *String,string &Res)
+bool ParseCWord(const char *&String,string &Res)
{
// Skip leading whitespace
const char *C = String;
@@ -180,9 +185,10 @@ bool ParseCWord(const char *String,string &Res)
if (isspace(*C) == 0)
return false;
*Buf++ = ' ';
- }
+ }
*Buf = 0;
Res = Buffer;
+ String = C;
return true;
}
/*}}}*/
@@ -325,6 +331,13 @@ string SubstVar(string Str,string Subst,string Contents)
return Temp + string(Str,OldPos);
}
+
+string SubstVar(string Str,const struct SubstVar *Vars)
+{
+ for (; Vars->Subst != 0; Vars++)
+ Str = SubstVar(Str,Vars->Subst,*Vars->Contents);
+ return Str;
+}
/*}}}*/
// URItoFileName - Convert the uri into a unique file name /*{{{*/
// ---------------------------------------------------------------------
@@ -548,9 +561,11 @@ bool ReadMessages(int Fd, vector<string> &List)
return false;
// No data
- if (Res <= 0)
+ if (Res < 0 && errno == EAGAIN)
return true;
-
+ if (Res < 0)
+ return false;
+
End += Res;
// Look for the end of the message
@@ -749,6 +764,121 @@ bool Hex2Num(const char *Start,const char *End,unsigned char *Num,
return true;
}
/*}}}*/
+// TokSplitString - Split a string up by a given token /*{{{*/
+// ---------------------------------------------------------------------
+/* This is intended to be a faster splitter, it does not use dynamic
+ memories. Input is changed to insert nulls at each token location. */
+bool TokSplitString(char Tok,char *Input,char **List,
+ unsigned long ListMax)
+{
+ // Strip any leading spaces
+ char *Start = Input;
+ char *Stop = Start + strlen(Start);
+ for (; *Start != 0 && isspace(*Start) != 0; Start++);
+
+ unsigned long Count = 0;
+ char *Pos = Start;
+ while (Pos != Stop)
+ {
+ // Skip to the next Token
+ for (; Pos != Stop && *Pos != Tok; Pos++);
+
+ // Back remove spaces
+ char *End = Pos;
+ for (; End > Start && (End[-1] == Tok || isspace(End[-1]) != 0); End--);
+ *End = 0;
+
+ List[Count++] = Start;
+ if (Count >= ListMax)
+ {
+ List[Count-1] = 0;
+ return false;
+ }
+
+ // Advance pos
+ for (; Pos != Stop && (*Pos == Tok || isspace(*Pos) != 0 || *Pos == 0); Pos++);
+ Start = Pos;
+ }
+
+ List[Count] = 0;
+ return true;
+}
+ /*}}}*/
+// RegexChoice - Simple regex list/list matcher /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+unsigned long RegexChoice(RxChoiceList *Rxs,const char **ListBegin,
+ const char **ListEnd)
+{
+ for (RxChoiceList *R = Rxs; R->Str != 0; R++)
+ R->Hit = false;
+
+ unsigned long Hits = 0;
+ for (; ListBegin != ListEnd; ListBegin++)
+ {
+ // Check if the name is a regex
+ const char *I;
+ bool Regex = true;
+ for (I = *ListBegin; *I != 0; I++)
+ if (*I == '.' || *I == '?' || *I == '*' || *I == '|')
+ break;
+ if (*I == 0)
+ Regex = false;
+
+ // Compile the regex pattern
+ regex_t Pattern;
+ if (Regex == true)
+ if (regcomp(&Pattern,*ListBegin,REG_EXTENDED | REG_ICASE |
+ REG_NOSUB) != 0)
+ Regex = false;
+
+ // Search the list
+ bool Done = false;
+ for (RxChoiceList *R = Rxs; R->Str != 0; R++)
+ {
+ if (R->Str[0] == 0)
+ continue;
+
+ if (strcasecmp(R->Str,*ListBegin) != 0)
+ {
+ if (Regex == false)
+ continue;
+ if (regexec(&Pattern,R->Str,0,0,0) != 0)
+ continue;
+ }
+ Done = true;
+
+ if (R->Hit == false)
+ Hits++;
+
+ R->Hit = true;
+ }
+
+ if (Regex == true)
+ regfree(&Pattern);
+
+ if (Done == false)
+ _error->Warning(_("Selection %s not found"),*ListBegin);
+ }
+
+ return Hits;
+}
+ /*}}}*/
+// ioprintf - C format string outputter to C++ iostreams /*{{{*/
+// ---------------------------------------------------------------------
+/* This is used to make the internationalization strinc easier to translate
+ and to allow reordering of parameters */
+void ioprintf(ostream &out,const char *format,...)
+{
+ va_list args;
+ va_start(args,format);
+
+ // sprintf the description
+ char S[400];
+ vsnprintf(S,sizeof(S),format,args);
+ out << S;
+}
+ /*}}}*/
// URI::CopyFrom - Copy from an object /*{{{*/
// ---------------------------------------------------------------------
@@ -757,7 +887,7 @@ void URI::CopyFrom(string U)
{
string::const_iterator I = U.begin();
- // Locate the first colon, this seperates the scheme
+ // Locate the first colon, this separates the scheme
for (; I < U.end() && *I != ':' ; I++);
string::const_iterator FirstColon = I;
@@ -912,3 +1042,16 @@ URI::operator string()
return Res;
}
/*}}}*/
+// URI::SiteOnly - Return the schema and site for the URI /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+string URI::SiteOnly(string URI)
+{
+ ::URI U(URI);
+ U.User = string();
+ U.Password = string();
+ U.Path = string();
+ U.Port = 0;
+ return U;
+}
+ /*}}}*/
diff --git a/apt-pkg/contrib/strutl.h b/apt-pkg/contrib/strutl.h
index 14293ae05..5549673a1 100644
--- a/apt-pkg/contrib/strutl.h
+++ b/apt-pkg/contrib/strutl.h
@@ -1,9 +1,9 @@
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
-// $Id: strutl.h,v 1.15 1999/08/02 03:07:48 jgg Exp $
+// $Id: strutl.h,v 1.16 2001/02/20 07:03:17 jgg Exp $
/* ######################################################################
- String Util - These are some usefull string functions
+ String Util - These are some useful string functions
_strstrip is a function to remove whitespace from the front and end
of a string.
@@ -25,15 +25,21 @@
#include <vector>
#include <time.h>
+#ifdef __GNUG__
+// Methods have a hidden this parameter that is visible to this attribute
+#define APT_FORMAT2 __attribute__ ((format (printf, 2, 3)))
+#else
+#define APT_FORMAT2
+#endif
+
char *_strstrip(char *String);
char *_strtabexpand(char *String,size_t Len);
bool ParseQuoteWord(const char *&String,string &Res);
-bool ParseCWord(const char *String,string &Res);
+bool ParseCWord(const char *&String,string &Res);
string QuoteString(string Str,const char *Bad);
string DeQuoteString(string Str);
string SizeToStr(double Bytes);
string TimeToStr(unsigned long Sec);
-string SubstVar(string Str,string Subst,string Contents);
string Base64Encode(string Str);
string URItoFileName(string URI);
string TimeRFC1123(time_t Date);
@@ -44,6 +50,9 @@ bool ReadMessages(int Fd, vector<string> &List);
bool StrToNum(const char *Str,unsigned long &Res,unsigned Len,unsigned Base = 0);
bool Hex2Num(const char *Start,const char *End,unsigned char *Num,
unsigned int Length);
+bool TokSplitString(char Tok,char *Input,char **List,
+ unsigned long ListMax);
+void ioprintf(ostream &out,const char *format,...) APT_FORMAT2;
int stringcmp(const char *A,const char *AEnd,const char *B,const char *BEnd);
inline int stringcmp(const char *A,const char *AEnd,const char *B) {return stringcmp(A,AEnd,B,B+strlen(B));};
@@ -51,6 +60,7 @@ inline int stringcmp(string A,const char *B) {return stringcmp(A.begin(),A.end()
int stringcasecmp(const char *A,const char *AEnd,const char *B,const char *BEnd);
inline int stringcasecmp(const char *A,const char *AEnd,const char *B) {return stringcasecmp(A,AEnd,B,B+strlen(B));};
inline int stringcasecmp(string A,const char *B) {return stringcasecmp(A.begin(),A.end(),B,B+strlen(B));};
+inline int stringcasecmp(string A,string B) {return stringcasecmp(A.begin(),A.end(),B.begin(),B.end());};
class URI
{
@@ -68,9 +78,29 @@ class URI
operator string();
inline void operator =(string From) {CopyFrom(From);};
inline bool empty() {return Access.empty();};
+ static string SiteOnly(string URI);
URI(string Path) {CopyFrom(Path);};
URI() : Port(0) {};
};
+struct SubstVar
+{
+ const char *Subst;
+ const string *Contents;
+};
+string SubstVar(string Str,const struct SubstVar *Vars);
+string SubstVar(string Str,string Subst,string Contents);
+
+struct RxChoiceList
+{
+ void *UserData;
+ const char *Str;
+ bool Hit;
+};
+unsigned long RegexChoice(RxChoiceList *Rxs,const char **ListBegin,
+ const char **ListEnd);
+
+#undef APT_FORMAT2
+
#endif