summaryrefslogtreecommitdiff
path: root/apt-pkg/contrib
diff options
context:
space:
mode:
Diffstat (limited to 'apt-pkg/contrib')
-rw-r--r--apt-pkg/contrib/configuration.cc137
-rw-r--r--apt-pkg/contrib/configuration.h61
-rw-r--r--apt-pkg/contrib/error.cc74
-rw-r--r--apt-pkg/contrib/error.h15
-rw-r--r--apt-pkg/contrib/fileutl.cc5
-rw-r--r--apt-pkg/contrib/fileutl.h6
-rw-r--r--apt-pkg/contrib/mmap.cc6
-rw-r--r--apt-pkg/contrib/mmap.h6
-rw-r--r--apt-pkg/contrib/strutl.cc343
-rw-r--r--apt-pkg/contrib/strutl.h36
10 files changed, 661 insertions, 28 deletions
diff --git a/apt-pkg/contrib/configuration.cc b/apt-pkg/contrib/configuration.cc
new file mode 100644
index 000000000..6d937d657
--- /dev/null
+++ b/apt-pkg/contrib/configuration.cc
@@ -0,0 +1,137 @@
+// -*- mode: cpp; mode: fold -*-
+// Description /*{{{*/
+// $Id: configuration.cc,v 1.1 1998/07/07 04:17:10 jgg Exp $
+/* ######################################################################
+
+ Configuration Class
+
+ This class provides a configuration file and command line parser
+ for a tree-oriented configuration environment. All runtime configuration
+ is stored in here.
+
+ ##################################################################### */
+ /*}}}*/
+// Include files /*{{{*/
+#ifdef __GNUG__
+#pragma implementation "pkglib/configuration.h"
+#endif
+#include <pkglib/configuration.h>
+#include <strutl.h>
+
+#include <stdio.h>
+ /*}}}*/
+Configuration *_config;
+
+// Configuration::Configuration - Constructor /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+Configuration::Configuration()
+{
+ Root = new Item;
+}
+ /*}}}*/
+// Configuration::Lookup - Lookup a single item /*{{{*/
+// ---------------------------------------------------------------------
+/* This will lookup a single item by name below another item. It is a
+ helper function for the main lookup function */
+Configuration::Item *Configuration::Lookup(Item *Head,const char *S,
+ unsigned long Len,bool Create)
+{
+ int Res = 1;
+ Item *I = Head->Child;
+ Item **Last = &Head->Child;
+ for (; I != 0; Last = &I->Next, I = I->Next)
+ if ((Res = stringcasecmp(I->Value.begin(),I->Value.end(),S,S + Len)) == 0)
+ break;
+
+ if (Res == 0)
+ return I;
+ if (Create == false)
+ return 0;
+
+ I = new Item;
+ I->Value = string(S,Len);
+ I->Next = *Last;
+ *Last = I;
+ return I;
+}
+ /*}}}*/
+// Configuration::Lookup - Lookup a fully scoped item /*{{{*/
+// ---------------------------------------------------------------------
+/* This performs a fully scoped lookup of a given name, possibly creating
+ new items */
+Configuration::Item *Configuration::Lookup(const char *Name,bool Create)
+{
+ const char *Start = Name;
+ const char *End = Start + strlen(Name);
+ const char *TagEnd = Name;
+ Item *Itm = Root;
+ for (; End - TagEnd > 2; TagEnd++)
+ {
+ if (TagEnd[0] == ':' && TagEnd[1] == ':')
+ {
+ Itm = Lookup(Itm,Start,TagEnd - Start,Create);
+ if (Itm == 0)
+ return 0;
+ TagEnd = Start = TagEnd + 2;
+ }
+ }
+
+ Itm = Lookup(Itm,Start,End - Start,Create);
+ if (Itm == 0)
+ return 0;
+ return Itm;
+}
+ /*}}}*/
+// Configuration::Find - Find a value /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+string Configuration::Find(const char *Name,const char *Default)
+{
+ Item *Itm = Lookup(Name,false);
+ if (Itm == 0 || Itm->Value.empty() == true)
+ return Default;
+ return Itm->Value;
+}
+ /*}}}*/
+// Configuration::FindI - Find an integer value /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+int Configuration::FindI(const char *Name,int Default)
+{
+ Item *Itm = Lookup(Name,false);
+ if (Itm == 0 || Itm->Value.empty() == true)
+ return Default;
+
+ char *End;
+ int Res = strtol(Itm->Value.c_str(),&End,0);
+ if (End == Itm->Value.c_str())
+ return Default;
+
+ return Res;
+}
+ /*}}}*/
+// Configuration::Set - Set a value /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+void Configuration::Set(const char *Name,string Value)
+{
+ Item *Itm = Lookup(Name,true);
+ if (Itm == 0)
+ return;
+ Itm->Value = Value;
+}
+ /*}}}*/
+// Configuration::Set - Set an integer value /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+void Configuration::Set(const char *Name,int Value)
+{
+ Item *Itm = Lookup(Name,true);
+ if (Itm == 0)
+ return;
+ char S[300];
+ snprintf(S,sizeof(S),"%i",Value);
+ Itm->Value = S;
+}
+ /*}}}*/
diff --git a/apt-pkg/contrib/configuration.h b/apt-pkg/contrib/configuration.h
new file mode 100644
index 000000000..7476346ef
--- /dev/null
+++ b/apt-pkg/contrib/configuration.h
@@ -0,0 +1,61 @@
+// -*- mode: cpp; mode: fold -*-
+// Description /*{{{*/
+// $Id: configuration.h,v 1.1 1998/07/07 04:17:10 jgg Exp $
+/* ######################################################################
+
+ Configuration Class
+
+ This class provides a configuration file and command line parser
+ for a tree-oriented configuration environment. All runtime configuration
+ is stored in here.
+
+ Each configuration name is given as a fully scoped string such as
+ Foo::Bar
+ And has associated with it a text string. The Configuration class only
+ provides storage and lookup for this tree, other classes provide
+ configuration file formats (and parsers/emitters if needed).
+
+ Most things can get by quite happily with,
+ cout << _config->Find("Foo::Bar") << endl;
+
+ ##################################################################### */
+ /*}}}*/
+// Header section: pkglib
+#ifndef PKGLIB_TAGFILE_H
+#define PKGLIB_TAGFILE_H
+
+#ifdef __GNUG__
+#pragma interface "pkglib/configuration.h"
+#endif
+
+#include <string>
+
+class Configuration
+{
+ struct Item
+ {
+ string Value;
+ string Tag;
+ Item *Child;
+ Item *Next;
+ Item() : Child(0), Next(0) {};
+ };
+ Item *Root;
+
+ Item *Lookup(Item *Head,const char *S,unsigned long Len,bool Create);
+ Item *Lookup(const char *Name,bool Create);
+
+ public:
+
+ string Find(const char *Name,const char *Default = 0);
+ int FindI(const char *Name,int Default = 0);
+
+ void Set(const char *Name,string Value);
+ void Set(const char *Name,int Value);
+
+ Configuration();
+};
+
+extern Configuration *_config;
+
+#endif
diff --git a/apt-pkg/contrib/error.cc b/apt-pkg/contrib/error.cc
index 59d2b8c8b..d1ea1b87b 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.1 1998/07/02 02:58:13 jgg Exp $
+// $Id: error.cc,v 1.2 1998/07/07 04:17:10 jgg Exp $
/* ######################################################################
Global Erorr Class - Global error mechanism
@@ -14,6 +14,10 @@
##################################################################### */
/*}}}*/
// Include Files /*{{{*/
+#ifdef __GNUG__
+#pragma implementation "pkglib/error.h"
+#endif
+
#include <errno.h>
#include <stdio.h>
#include <string.h>
@@ -27,7 +31,7 @@ GlobalError *_error = new GlobalError;
// GlobalError::GlobalError - Constructor /*{{{*/
// ---------------------------------------------------------------------
/* */
-GlobalError::GlobalError() : PendingFlag(false)
+GlobalError::GlobalError() : List(0), PendingFlag(false)
{
}
/*}}}*/
@@ -49,10 +53,10 @@ bool GlobalError::Errno(const char *Function,const char *Description,...)
sprintf(S + strlen(S)," - %s (%i %s)",Function,errno,strerror(errno));
// Put it on the list
- Item Itm;
- Itm.Text = S;
- Itm.Error = true;
- List.push_back(Itm);
+ Item *Itm = new Item;
+ Itm->Text = S;
+ Itm->Error = true;
+ Insert(Itm);
PendingFlag = true;
@@ -72,10 +76,10 @@ bool GlobalError::Error(const char *Description,...)
vsprintf(S,Description,args);
// Put it on the list
- Item Itm;
- Itm.Text = S;
- Itm.Error = true;
- List.push_back(Itm);
+ Item *Itm = new Item;
+ Itm->Text = S;
+ Itm->Error = true;
+ Insert(Itm);
PendingFlag = true;
@@ -95,10 +99,10 @@ bool GlobalError::Warning(const char *Description,...)
vsprintf(S,Description,args);
// Put it on the list
- Item Itm;
- Itm.Text = S;
- Itm.Error = false;
- List.push_back(Itm);
+ Item *Itm = new Item;
+ Itm->Text = S;
+ Itm->Error = false;
+ Insert(Itm);
return false;
}
@@ -109,12 +113,17 @@ bool GlobalError::Warning(const char *Description,...)
true if the message is an error. */
bool GlobalError::PopMessage(string &Text)
{
- bool Ret = List.front().Error;
- Text = List.front().Text;
- List.erase(List.begin());
-
+ if (List == 0)
+ return false;
+
+ bool Ret = List->Error;
+ Text = List->Text;
+ Item *Old = List;
+ List = List->Next;
+ delete Old;
+
// This really should check the list to see if only warnings are left..
- if (empty())
+ if (List == 0)
PendingFlag = false;
return Ret;
@@ -137,3 +146,30 @@ void GlobalError::DumpErrors()
}
}
/*}}}*/
+// GlobalError::Discard - Discard /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+void GlobalError::Discard()
+{
+ while (List != 0)
+ {
+ Item *Old = List;
+ List = List->Next;
+ delete Old;
+ }
+
+ PendingFlag = false;
+};
+ /*}}}*/
+// GlobalError::Insert - Insert a new item at the end /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+void GlobalError::Insert(Item *Itm)
+{
+ Item **End = &List;
+ for (Item *I = List; I != 0; I = I->Next)
+ End = &I->Next;
+ Itm->Next = *End;
+ *End = Itm;
+}
+ /*}}}*/
diff --git a/apt-pkg/contrib/error.h b/apt-pkg/contrib/error.h
index 06b998e5e..06367592b 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.1 1998/07/02 02:58:13 jgg Exp $
+// $Id: error.h,v 1.2 1998/07/07 04:17:11 jgg Exp $
/* ######################################################################
Global Erorr Class - Global error mechanism
@@ -41,8 +41,11 @@
#ifndef PKGLIB_ERROR_H
#define PKGLIB_ERROR_H
+#ifdef __GNUG__
+#pragma interface "pkglib/error.h"
+#endif
+
#include <string>
-#include <vector.h>
class GlobalError
{
@@ -50,10 +53,12 @@ class GlobalError
{
string Text;
bool Error;
+ Item *Next;
};
- vector<Item> List;
+ Item *List;
bool PendingFlag;
+ void Insert(Item *I);
public:
@@ -67,9 +72,9 @@ class GlobalError
// Simple accessors
inline bool PendingError() {return PendingFlag;};
- inline bool empty() {return List.empty();};
+ inline bool empty() {return List == 0;};
bool PopMessage(string &Text);
- void Discard() {List.erase(List.begin(),List.end()); PendingFlag = false;};
+ void Discard();
// Usefull routine to dump to cerr
void DumpErrors();
diff --git a/apt-pkg/contrib/fileutl.cc b/apt-pkg/contrib/fileutl.cc
index 6c6441ef6..29b12bef1 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.2 1998/07/04 05:57:41 jgg Exp $
+// $Id: fileutl.cc,v 1.3 1998/07/07 04:17:12 jgg Exp $
/* ######################################################################
File Utilities
@@ -14,6 +14,9 @@
##################################################################### */
/*}}}*/
// Include Files /*{{{*/
+#ifdef __GNUG__
+#pragma implementation "pkglib/fileutl.h"
+#endif
#include <pkglib/fileutl.h>
#include <pkglib/error.h>
diff --git a/apt-pkg/contrib/fileutl.h b/apt-pkg/contrib/fileutl.h
index 1b6666843..aa2d2ee2e 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.1 1998/07/02 02:58:13 jgg Exp $
+// $Id: fileutl.h,v 1.2 1998/07/07 04:17:13 jgg Exp $
/* ######################################################################
File Utilities
@@ -22,6 +22,10 @@
#ifndef PKGLIB_FILEUTL_H
#define PKGLIB_FILEUTL_H
+#ifdef __GNUG__
+#pragma interface "pkglib/fileutl.h"
+#endif
+
#include <string>
class File
diff --git a/apt-pkg/contrib/mmap.cc b/apt-pkg/contrib/mmap.cc
index 41ea02aec..c0cc13f00 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.3 1998/07/04 22:32:15 jgg Exp $
+// $Id: mmap.cc,v 1.4 1998/07/07 04:17:14 jgg Exp $
/* ######################################################################
MMap Class - Provides 'real' mmap or a faked mmap using read().
@@ -21,6 +21,10 @@
##################################################################### */
/*}}}*/
// Include Files /*{{{*/
+#ifdef __GNUG__
+#pragma implementation "pkglib/mmap.h"
+#endif
+
#define _BSD_SOURCE
#include <pkglib/mmap.h>
#include <pkglib/error.h>
diff --git a/apt-pkg/contrib/mmap.h b/apt-pkg/contrib/mmap.h
index c7ddf685d..55feda741 100644
--- a/apt-pkg/contrib/mmap.h
+++ b/apt-pkg/contrib/mmap.h
@@ -1,6 +1,6 @@
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
-// $Id: mmap.h,v 1.2 1998/07/04 05:57:43 jgg Exp $
+// $Id: mmap.h,v 1.3 1998/07/07 04:17:15 jgg Exp $
/* ######################################################################
MMap Class - Provides 'real' mmap or a faked mmap using read().
@@ -26,6 +26,10 @@
#ifndef PKGLIB_MMAP_H
#define PKGLIB_MMAP_H
+#ifdef __GNUG__
+#pragma interface "pkglib/mmap.h"
+#endif
+
#include <string>
#include <pkglib/fileutl.h>
diff --git a/apt-pkg/contrib/strutl.cc b/apt-pkg/contrib/strutl.cc
new file mode 100644
index 000000000..14965f91e
--- /dev/null
+++ b/apt-pkg/contrib/strutl.cc
@@ -0,0 +1,343 @@
+// -*- mode: cpp; mode: fold -*-
+// Description /*{{{*/
+// $Id: strutl.cc,v 1.1 1998/07/07 04:17:16 jgg Exp $
+/* ######################################################################
+
+ String Util - Some usefull string functions.
+
+ strstrip - Remove whitespace from the front and end of a line.
+
+ This source is placed in the Public Domain, do with it what you will
+ It was originally written by Jason Gunthorpe <jgg@gpu.srv.ualberta.ca>
+
+ ##################################################################### */
+ /*}}}*/
+// Includes /*{{{*/
+#include <strutl.h>
+#include <ctype.h>
+#include <string.h>
+#include <stdio.h>
+ /*}}}*/
+
+// strstrip - Remove white space from the front and back of a string /*{{{*/
+// ---------------------------------------------------------------------
+/* This is handy to use when parsing a file. It also removes \n's left
+ over from fgets and company */
+char *_strstrip(char *String)
+{
+ for (;*String != 0 && (*String == ' ' || *String == '\t'); String++);
+
+ if (*String == 0)
+ return String;
+
+ char *End = String + strlen(String) - 1;
+ for (;End != String - 1 && (*End == ' ' || *End == '\t' || *End == '\n' ||
+ *End == '\r'); End--);
+ End++;
+ *End = 0;
+ return String;
+};
+ /*}}}*/
+// strtabexpand - Converts tabs into 8 spaces /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+char *_strtabexpand(char *String,size_t Len)
+{
+ for (char *I = String; I != I + Len && *I != 0; I++)
+ {
+ if (*I != '\t')
+ continue;
+ if (I + 8 > String + Len)
+ {
+ *I = 0;
+ return String;
+ }
+
+ /* Assume the start of the string is 0 and find the next 8 char
+ division */
+ int Len;
+ if (String == I)
+ Len = 1;
+ else
+ Len = 8 - ((String - I) % 8);
+ Len -= 2;
+ if (Len <= 0)
+ {
+ *I = ' ';
+ continue;
+ }
+
+ memmove(I + Len,I + 1,strlen(I) + 1);
+ for (char *J = I; J + Len != I; *I = ' ', I++);
+ }
+ return String;
+}
+ /*}}}*/
+// ParseQuoteWord - Parse a single word out of a string /*{{{*/
+// ---------------------------------------------------------------------
+/* This grabs a single word, converts any % escaped characters to their
+ proper values and advances the pointer. Double quotes are understood
+ and striped out as well. */
+bool ParseQuoteWord(const char *&String,string &Res)
+{
+ // Skip leading whitespace
+ const char *C = String;
+ for (;*C != 0 && *C == ' '; C++);
+ if (*C == 0)
+ return false;
+
+ // Jump to the next word
+ for (;*C != 0 && *C != ' '; C++)
+ {
+ if (*C == '"')
+ {
+ for (C++;*C != 0 && *C != '"'; C++);
+ if (*C == 0)
+ return false;
+ }
+ }
+
+ // Now de-quote characters
+ char Buffer[1024];
+ char Tmp[3];
+ const char *Start = String;
+ char *I;
+ for (I = Buffer; I < Buffer + sizeof(Buffer) && Start != C; I++)
+ {
+ if (*Start == '%' && Start + 2 < C)
+ {
+ Tmp[0] = Start[1];
+ Tmp[1] = Start[2];
+ Tmp[3] = 0;
+ *I = (char)strtol(Tmp,0,16);
+ Start += 3;
+ continue;
+ }
+ if (*Start != '"')
+ *I = *Start;
+ else
+ I--;
+ Start++;
+ }
+ *I = 0;
+ Res = Buffer;
+
+ // Skip ending white space
+ for (;*C != 0 && *C == ' '; C++);
+ String = C;
+ return true;
+}
+ /*}}}*/
+// QuoteString - Convert a string into quoted from /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+string QuoteString(string Str,const char *Bad)
+{
+ string Res;
+ for (string::iterator I = Str.begin(); I != Str.end(); I++)
+ {
+ if (strchr(Bad,*I) != 0 || isprint(*I) == 0 ||
+ *I <= 0x20 || *I >= 0x7F)
+ {
+ char Buf[10];
+ sprintf(Buf,"%%%02x",(int)*I);
+ Res += Buf;
+ }
+ else
+ Res += *I;
+ }
+ return Res;
+}
+ /*}}}*/
+// SizeToStr - Convert a long into a human readable size /*{{{*/
+// ---------------------------------------------------------------------
+/* A max of 4 digits are shown before conversion to the next highest unit. The
+ max length of the string will be 5 chars unless the size is > 10
+ YottaBytes (E24) */
+string SizeToStr(double Size)
+{
+ char S[300];
+ double ASize;
+ if (Size >= 0)
+ ASize = Size;
+ else
+ ASize = -1*Size;
+
+ /* bytes, KiloBytes, MegaBytes, GigaBytes, TeraBytes, PetaBytes,
+ ExaBytes, ZettaBytes, YottaBytes */
+ char Ext[] = {'b','k','M','G','T','P','E','Z','Y'};
+ int I = 0;
+ while (I <= 8)
+ {
+ if (ASize < 100 && I != 0)
+ {
+ sprintf(S,"%.1f%c",ASize,Ext[I]);
+ break;
+ }
+
+ if (ASize < 10000)
+ {
+ sprintf(S,"%.0f%c",ASize,Ext[I]);
+ break;
+ }
+ ASize /= 1000.0;
+ I++;
+ }
+
+ return S;
+}
+ /*}}}*/
+// TimeToStr - Convert the time into a string /*{{{*/
+// ---------------------------------------------------------------------
+/* Converts a number of seconds to a hms format */
+string TimeToStr(unsigned long Sec)
+{
+ char S[300];
+
+ while (1)
+ {
+ if (Sec > 60*60*24)
+ {
+ sprintf(S,"%lid %lih%lim%lis",Sec/60/60/24,(Sec/60/60) % 24,(Sec/60) % 60,Sec % 60);
+ break;
+ }
+
+ if (Sec > 60*60)
+ {
+ sprintf(S,"%lih%lim%lis",Sec/60/60,(Sec/60) % 60,Sec % 60);
+ break;
+ }
+
+ if (Sec > 60)
+ {
+ sprintf(S,"%lim%lis",Sec/60,Sec % 60);
+ break;
+ }
+
+ sprintf(S,"%lis",Sec);
+ break;
+ }
+
+ return S;
+}
+ /*}}}*/
+// SubstVar - Substitute a string for another string /*{{{*/
+// ---------------------------------------------------------------------
+/* This replaces all occurances of Subst with Contents in Str. */
+string SubstVar(string Str,string Subst,string Contents)
+{
+ string::size_type Pos;
+ string::size_type OldPos = 0;
+ string Temp;
+
+ while (OldPos < Str.length() &&
+ (Pos = Str.find(Subst,OldPos)) != string::npos)
+ {
+ Temp += string(Str,OldPos,Pos) + Contents;
+ OldPos = Pos + Subst.length();
+ }
+
+ if (OldPos == 0)
+ return Str;
+
+ return Temp + string(Str,OldPos);
+}
+ /*}}}*/
+// Base64Encode - Base64 Encoding routine for short strings /*{{{*/
+// ---------------------------------------------------------------------
+/* This routine performs a base64 transformation on a string. It was ripped
+ from wget and then patched and bug fixed.
+
+ This spec can be found in rfc2045 */
+string Base64Encode(string S)
+{
+ // Conversion table.
+ static char tbl[64] = {'A','B','C','D','E','F','G','H',
+ 'I','J','K','L','M','N','O','P',
+ 'Q','R','S','T','U','V','W','X',
+ 'Y','Z','a','b','c','d','e','f',
+ 'g','h','i','j','k','l','m','n',
+ 'o','p','q','r','s','t','u','v',
+ 'w','x','y','z','0','1','2','3',
+ '4','5','6','7','8','9','+','/'};
+
+ // Pre-allocate some space
+ string Final;
+ Final.reserve((4*S.length() + 2)/3 + 2);
+
+ /* Transform the 3x8 bits to 4x6 bits, as required by
+ base64. */
+ for (string::const_iterator I = S.begin(); I < S.end(); I += 3)
+ {
+ char Bits[3] = {0,0,0};
+ Bits[0] = I[0];
+ if (I + 1 < S.end())
+ Bits[1] = I[1];
+ if (I + 2 < S.end())
+ Bits[2] = I[2];
+
+ Final += tbl[Bits[0] >> 2];
+ Final += tbl[((Bits[0] & 3) << 4) + (Bits[1] >> 4)];
+
+ if (I + 1 >= S.end())
+ break;
+
+ Final += tbl[((Bits[1] & 0xf) << 2) + (Bits[2] >> 6)];
+
+ if (I + 2 >= S.end())
+ break;
+
+ Final += tbl[Bits[2] & 0x3f];
+ }
+
+ /* Apply the padding elements, this tells how many bytes the remote
+ end should discard */
+ if (S.length() % 3 == 2)
+ Final += '=';
+ if (S.length() % 3 == 1)
+ Final += "==";
+
+ return Final;
+}
+ /*}}}*/
+// stringcmp - Arbitary string compare /*{{{*/
+// ---------------------------------------------------------------------
+/* This safely compares two non-null terminated strings of arbitary
+ length */
+int stringcmp(const char *A,const char *AEnd,const char *B,const char *BEnd)
+{
+ for (; A != AEnd && B != BEnd; A++, B++)
+ if (*A != *B)
+ break;
+
+ if (A == AEnd && B == BEnd)
+ return 0;
+ if (A == AEnd)
+ return 1;
+ if (B == BEnd)
+ return -1;
+ if (*A < *B)
+ return -1;
+ return 1;
+}
+ /*}}}*/
+// stringcasecmp - Arbitary case insensitive string compare /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+int stringcasecmp(const char *A,const char *AEnd,const char *B,const char *BEnd)
+{
+ for (; A != AEnd && B != BEnd; A++, B++)
+ if (toupper(*A) != toupper(*B))
+ break;
+
+ if (A == AEnd && B == BEnd)
+ return 0;
+ if (A == AEnd)
+ return 1;
+ if (B == BEnd)
+ return -1;
+ if (toupper(*A) < toupper(*B))
+ return -1;
+ return 1;
+}
+ /*}}}*/
diff --git a/apt-pkg/contrib/strutl.h b/apt-pkg/contrib/strutl.h
new file mode 100644
index 000000000..44a10c2f3
--- /dev/null
+++ b/apt-pkg/contrib/strutl.h
@@ -0,0 +1,36 @@
+// -*- mode: cpp; mode: fold -*-
+// Description /*{{{*/
+// $Id: strutl.h,v 1.1 1998/07/07 04:17:16 jgg Exp $
+/* ######################################################################
+
+ String Util - These are some usefull string functions
+
+ _strstrip is a function to remove whitespace from the front and end
+ of a string.
+
+ This source is placed in the Public Domain, do with it what you will
+ It was originally written by Jason Gunthorpe <jgg@gpu.srv.ualberta.ca>
+
+ ##################################################################### */
+ /*}}}*/
+// This is a private header
+// Header section: /
+#ifndef STRUTL_H
+#define STRUTL_H
+
+#include <stdlib.h>
+#include <string>
+
+char *_strstrip(char *String);
+char *_strtabexpand(char *String,size_t Len);
+bool ParseQuoteWord(const char *&String,string &Res);
+string QuoteString(string Str,const char *Bad);
+string SizeToStr(double Bytes);
+string TimeToStr(unsigned long Sec);
+string SubstVar(string Str,string Subst,string Contents);
+string Base64Encode(string Str);
+
+int stringcmp(const char *A,const char *AEnd,const char *B,const char *BEnd);
+int stringcasecmp(const char *A,const char *AEnd,const char *B,const char *BEnd);
+
+#endif