// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
-// $Id: strutl.cc,v 1.16 1998/12/31 05:45:26 jgg Exp $
+// $Id: strutl.cc,v 1.30 1999/10/17 07:30:23 jgg Exp $
/* ######################################################################
String Util - Some usefull string functions.
/*}}}*/
// Includes /*{{{*/
#ifdef __GNUG__
-#pragma implementation "strutl.h"
+#pragma implementation "apt-pkg/strutl.h"
#endif
-#include <strutl.h>
+#include <apt-pkg/strutl.h>
#include <apt-pkg/fileutl.h>
#include <ctype.h>
#include <string.h>
#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
/*}}}*/
// strstrip - Remove white space from the front and back of a string /*{{{*/
return false;
// Jump to the next word
- for (;*C != 0 && *C != ' '; C++)
+ for (;*C != 0 && isspace(*C) == 0; C++)
{
if (*C == '"')
{
{
Tmp[0] = Start[1];
Tmp[1] = Start[2];
- Tmp[3] = 0;
+ Tmp[2] = 0;
*I = (char)strtol(Tmp,0,16);
Start += 3;
continue;
Res = Buffer;
// Skip ending white space
- for (;*C != 0 && *C == ' '; C++);
+ for (;*C != 0 && isspace(*C) != 0; C++);
String = C;
return true;
}
*I <= 0x20 || *I >= 0x7F)
{
char Buf[10];
- sprintf(Buf,"%%%02x",(unsigned int)((unsigned char)*I));
+ sprintf(Buf,"%%%02x",(int)*I);
Res += Buf;
}
else
return Res;
}
/*}}}*/
+// DeQuoteString - Convert a string from quoted from /*{{{*/
+// ---------------------------------------------------------------------
+/* This undoes QuoteString */
+string DeQuoteString(string Str)
+{
+ string Res;
+ for (string::iterator I = Str.begin(); I != Str.end(); I++)
+ {
+ if (*I == '%' && I + 2 < Str.end())
+ {
+ char Tmp[3];
+ Tmp[0] = I[1];
+ Tmp[1] = I[2];
+ Tmp[2] = 0;
+ Res += (char)strtol(Tmp,0,16);
+ I += 2;
+ continue;
+ }
+ 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.
/* bytes, KiloBytes, MegaBytes, GigaBytes, TeraBytes, PetaBytes,
ExaBytes, ZettaBytes, YottaBytes */
- char Ext[] = {'b','k','M','G','T','P','E','Z','Y'};
+ char Ext[] = {'\0','k','M','G','T','P','E','Z','Y'};
int I = 0;
while (I <= 8)
{
file name should be unique and never occur again for a different file */
string URItoFileName(string URI)
{
- string::const_iterator I = URI.begin() + URI.find(':') + 1;
- for (; I < URI.end() && *I == '/'; I++);
-
+ // Nuke 'sensitive' items
+ ::URI U(URI);
+ U.User = string();
+ U.Password = string();
+ U.Access = "";
+
// "\x00-\x20{}|\\\\^\\[\\]<>\"\x7F-\xFF";
- URI = QuoteString(string(I,URI.end() - I),"\\|{}[]<>\"^~_=!@#$%^&*");
+ URI = QuoteString(U,"\\|{}[]<>\"^~_=!@#$%^&*");
string::iterator J = URI.begin();
for (; J != URI.end(); J++)
if (*J == '/')
if (strcasecmp(Text.c_str(),"no") == 0 ||
strcasecmp(Text.c_str(),"false") == 0 ||
strcasecmp(Text.c_str(),"without") == 0 ||
+ strcasecmp(Text.c_str(),"off") == 0 ||
strcasecmp(Text.c_str(),"disable") == 0)
return 0;
if (strcasecmp(Text.c_str(),"yes") == 0 ||
strcasecmp(Text.c_str(),"true") == 0 ||
strcasecmp(Text.c_str(),"with") == 0 ||
+ strcasecmp(Text.c_str(),"on") == 0 ||
strcasecmp(Text.c_str(),"enable") == 0)
return 1;
while (1)
{
int Res = read(Fd,End,sizeof(Buffer) - (End-Buffer));
+ if (Res < 0 && errno == EINTR)
+ continue;
// Process is dead, this is kind of bad..
if (Res == 0)
}
}
/*}}}*/
+// timegm - Internal timegm function if gnu is not available /*{{{*/
+// ---------------------------------------------------------------------
+/* Ripped this evil little function from wget - I prefer the use of
+ GNU timegm if possible as this technique will have interesting problems
+ with leap seconds, timezones and other.
+
+ Converts struct tm to time_t, assuming the data in tm is UTC rather
+ than local timezone (mktime assumes the latter).
+
+ Contributed by Roger Beeman <beeman@cisco.com>, with the help of
+ Mark Baushke <mdb@cisco.com> and the rest of the Gurus at CISCO. */
+#ifndef __USE_MISC // glib sets this
+static time_t timegm(struct tm *t)
+{
+ time_t tl, tb;
+
+ tl = mktime (t);
+ if (tl == -1)
+ return -1;
+ tb = mktime (gmtime (&tl));
+ return (tl <= tb ? (tl + (tl - tb)) : (tl - (tb - tl)));
+}
+#endif
+ /*}}}*/
// StrToTime - Converts a string into a time_t /*{{{*/
// ---------------------------------------------------------------------
/* This handles all 3 populare time formats including RFC 1123, RFC 1036
return true;
}
/*}}}*/
+// StrToNum - Convert a fixed length string to a number /*{{{*/
+// ---------------------------------------------------------------------
+/* This is used in decoding the crazy fixed length string headers in
+ tar and ar files. */
+bool StrToNum(const char *Str,unsigned long &Res,unsigned Len,unsigned Base)
+{
+ char S[30];
+ if (Len >= sizeof(S))
+ return false;
+ memcpy(S,Str,Len);
+ S[Len] = 0;
+
+ // All spaces is a zero
+ Res = 0;
+ unsigned I;
+ for (I = 0; S[I] == ' '; I++);
+ if (S[I] == 0)
+ return true;
+
+ char *End;
+ Res = strtoul(S,&End,Base);
+ if (End == S)
+ return false;
+
+ return true;
+}
+ /*}}}*/
+// HexDigit - Convert a hex character into an integer /*{{{*/
+// ---------------------------------------------------------------------
+/* Helper for Hex2Num */
+static int HexDigit(int c)
+{
+ if (c >= '0' && c <= '9')
+ return c - '0';
+ if (c >= 'a' && c <= 'f')
+ return c - 'a' + 10;
+ if (c >= 'A' && c <= 'F')
+ return c - 'A' + 10;
+ return 0;
+}
+ /*}}}*/
+// Hex2Num - Convert a long hex number into a buffer /*{{{*/
+// ---------------------------------------------------------------------
+/* The length of the buffer must be exactly 1/2 the length of the string. */
+bool Hex2Num(const char *Start,const char *End,unsigned char *Num,
+ unsigned int Length)
+{
+ if (End - Start != (signed)(Length*2))
+ return false;
+
+ // Convert each digit. We store it in the same order as the string
+ int J = 0;
+ for (const char *I = Start; I < End;J++, I += 2)
+ {
+ if (isxdigit(*I) == 0 || isxdigit(I[1]) == 0)
+ return false;
+
+ Num[J] = HexDigit(I[0]) << 4;
+ Num[J] += HexDigit(I[1]);
+ }
+
+ return true;
+}
+ /*}}}*/
// URI::CopyFrom - Copy from an object /*{{{*/
// ---------------------------------------------------------------------
if (FirstColon > SingleSlash)
FirstColon = SingleSlash;
- // Search for the @
- I = FirstColon;
+ // Find the colon...
+ I = FirstColon + 1;
+ if (I > SingleSlash)
+ I = SingleSlash;
+ for (; I < SingleSlash && *I != ':'; I++);
+ string::const_iterator SecondColon = I;
+
+ // Search for the @ after the colon
for (; I < SingleSlash && *I != '@'; I++);
string::const_iterator At = I;
- // Colon in the @ section
- I = FirstColon + 1;
- for (; I < At && *I != ':'; I++);
- string::const_iterator SecondColon = I;
-
// Now write the host and user/pass
if (At == SingleSlash)
{
Password = string(U,SecondColon - U.begin() + 1,At - SecondColon - 1);
}
- // Now we parse off a pot number from the hostname
+ // Now we parse off a port number from the hostname
Port = 0;
string::size_type Pos = Host.rfind(':');
if (Pos == string::npos)
/* */
URI::operator string()
{
- string Res = Access + ':';
+ string Res;
+
+ if (Access.empty() == false)
+ Res = Access + ':';
+
if (Host.empty() == false)
{
- Res += "//";
+ if (Access.empty() == false)
+ Res += "//";
+
if (User.empty() == false)
{
- Res += "//" + User;
+ Res += User;
if (Password.empty() == false)
Res += ":" + Password;
Res += "@";
}
+
Res += Host;
if (Port != 0)
{