// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
-// $Id: acquire-worker.cc,v 1.4 1998/10/22 04:56:40 jgg Exp $
+// $Id: acquire-worker.cc,v 1.5 1998/10/23 00:49:58 jgg Exp $
/* ######################################################################
Acquire Worker
return true;
}
/*}}}*/
-
// Worker::RunMessage - Empty the message queue /*{{{*/
// ---------------------------------------------------------------------
/* This takes the messages from the message queue and runs them through
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
-// $Id: strutl.cc,v 1.6 1998/10/22 04:56:48 jgg Exp $
+// $Id: strutl.cc,v 1.7 1998/10/23 00:49:59 jgg Exp $
/* ######################################################################
String Util - Some usefull string functions.
- strstrip - Remove whitespace from the front and end of a line.
+ 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
+ especially in APT methods.
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>
+ It was originally written by Jason Gunthorpe <jgg@gpu.srv.ualberta.ca>
##################################################################### */
/*}}}*/
/*}}}*/
// 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
+/* 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)
{
}
}
/*}}}*/
+// MonthConv - Converts a month string into a number /*{{{*/
+// ---------------------------------------------------------------------
+/* This was lifted from the boa webserver which lifted it from 'wn-v1.07'
+ Made it a bit more robust with a few touppers though. */
+static int MonthConv(char *Month)
+{
+ switch (toupper(*Month))
+ {
+ case 'A':
+ return toupper(Month[1]) == 'P'?3:7;
+ case 'D':
+ return 11;
+ case 'F':
+ return 1;
+ case 'J':
+ if (toupper(Month[1]) == 'A')
+ return 0;
+ return toupper(Month[2]) == 'N'?5:6;
+ case 'M':
+ return toupper(Month[2]) == 'R'?2:4;
+ case 'N':
+ return 10;
+ case 'O':
+ return 9;
+ case 'S':
+ return 8;
+
+ // Pretend it is January..
+ default:
+ return 0;
+ }
+}
+ /*}}}*/
+// StrToTime - Converts a string into a time_t /*{{{*/
+// ---------------------------------------------------------------------
+/* This handles all 3 populare time formats including RFC 1123, RFC 1036
+ and the C library asctime format. It requires the GNU library function
+ 'timegm' to convert a struct tm in UTC to a time_t. For some bizzar
+ reason the C library does not provide any such function :<*/
+bool StrToTime(string Val,time_t &Result)
+{
+ struct tm Tm;
+ char Month[10];
+ const char *I = Val.c_str();
+
+ // Skip the day of the week
+ for (;*I != 0 && *I != ' '; I++);
+
+ // Handle RFC 1123 time
+ if (sscanf(I," %d %3s %d %d:%d:%d GMT",&Tm.tm_mday,Month,&Tm.tm_year,
+ &Tm.tm_hour,&Tm.tm_min,&Tm.tm_sec) != 6)
+ {
+ // Handle RFC 1036 time
+ if (sscanf(I," %d-%3s-%d %d:%d:%d GMT",&Tm.tm_mday,Month,
+ &Tm.tm_year,&Tm.tm_hour,&Tm.tm_min,&Tm.tm_sec) == 6)
+ Tm.tm_year += 1900;
+ else
+ {
+ // asctime format
+ if (sscanf(I," %3s %d %d:%d:%d %d",Month,&Tm.tm_mday,
+ &Tm.tm_hour,&Tm.tm_min,&Tm.tm_sec,&Tm.tm_year) != 6)
+ return false;
+ }
+ }
+
+ Tm.tm_isdst = 0;
+ Tm.tm_mon = MonthConv(Month);
+ Tm.tm_year -= 1900;
+
+ // Convert to local time and then to GMT
+ Result = timegm(&Tm);
+ return true;
+}
+ /*}}}*/
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
-// $Id: strutl.h,v 1.6 1998/10/22 04:56:49 jgg Exp $
+// $Id: strutl.h,v 1.7 1998/10/23 00:50:00 jgg Exp $
/* ######################################################################
String Util - These are some usefull string functions
string URItoFileName(string URI);
string URIAccess(string URI);
string TimeRFC1123(time_t Date);
+bool StrToTime(string Val,time_t &Result);
string LookupTag(string Message,const char *Tag,const char *Default = 0);
int StringToBool(string Text,int Default = -1);
bool ReadMessages(int Fd, vector<string> &List);
+// -*- mode: cpp; mode: fold -*-
+// Description /*{{{*/
+// $Id: file.cc,v 1.3 1998/10/23 00:50:02 jgg Exp $
+/* ######################################################################
+
+ File URI method for APT
+
+ This simply checks that the file specified exists, if so the relevent
+ information is returned. If a .gz filename is specified then the file
+ name with .gz removed will also be checked and information about it
+ will be returned in Alt-*
+
+ ##################################################################### */
+ /*}}}*/
+// Include Files /*{{{*/
+#include <apt-pkg/fileutl.h>
+#include <strutl.h>
+
+#include <sys/stat.h>
+#include <unistd.h>
#include <stdio.h>
+ /*}}}*/
+
+// Fail - Generate a failure message /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+void Fail(string URI)
+{
+ printf("400 URI Failure\n"
+ "URI: %s\n"
+ "Message: File does not exist\n\n",URI.c_str());
+}
+ /*}}}*/
int main()
{
+ setlinebuf(stdout);
+ SetNonBlock(STDIN_FILENO,true);
+
printf("100 Capabilities\n"
"Version: 1.0\n"
- "Pre-Scan: true\n\n");
- fflush(stdout);
- sleep(10);
+ "Pipeline: true\n\n");
+
+ vector<string> Messages;
+ while (1)
+ {
+ if (WaitFd(STDIN_FILENO) == false ||
+ ReadMessages(STDIN_FILENO,Messages) == false)
+ return 0;
+
+ while (Messages.empty() == false)
+ {
+ string Message = Messages.front();
+ Messages.erase(Messages.begin());
+
+ // Fetch the message number
+ char *End;
+ int Number = strtol(Message.c_str(),&End,10);
+ if (End == Message.c_str())
+ {
+ cerr << "Malformed message!" << endl;
+ return 100;
+ }
+
+ // We only understand 600 URI Fetch messages
+ if (Number != 600)
+ continue;
+
+ // Grab the URI bit
+ string URI = LookupTag(Message,"URI");
+
+ // Grab the filename
+ string::size_type Pos = URI.find(':');
+ if (Pos == string::npos)
+ {
+ Fail(URI);
+ continue;
+ }
+ string File = string(URI,Pos+1);
+
+ // Grab the modification time
+ time_t LastMod;
+ string LTime = LookupTag(Message,"Last-Modified");
+ if (LTime.empty() == false && StrToTime(LTime,LastMod) == false)
+ LTime = string();
+
+ // Start the reply message
+ string Result = "201 URI Done";
+ Result += "\nURI: " + URI;
+
+ // See if the file exists
+ struct stat Buf;
+ bool Ok = false;
+ if (stat(File.c_str(),&Buf) == 0)
+ {
+ char S[300];
+ sprintf(S,"\nSize: %ld",Buf.st_size);
+
+ Result += "\nFilename: " + File;
+ Result += S;
+ Result += "\nLast-Modified: " + TimeRFC1123(Buf.st_mtime);
+ if (LTime.empty() == false && LastMod == Buf.st_mtime)
+ Result += "\nIMS-Hit: true";
+
+ Ok = true;
+ }
+
+ // See if we can compute a file without a .gz exentsion
+ Pos = File.rfind(".gz");
+ if (Pos + 3 == File.length())
+ {
+ File = string(File,0,Pos);
+ if (stat(File.c_str(),&Buf) == 0)
+ {
+ char S[300];
+ sprintf(S,"\nAlt-Size: %ld",Buf.st_size);
+
+ Result += "\nAlt-Filename: " + File;
+ Result += S;
+ Result += "\nAlt-Last-Modified: " + TimeRFC1123(Buf.st_mtime);
+ if (LTime.empty() == false && LastMod == Buf.st_mtime)
+ Result += "\nAlt-IMS-Hit: true";
+
+ Ok = true;
+ }
+ }
+
+ // Did we find something?
+ if (Ok == false)
+ {
+ Fail(URI);
+ continue;
+ }
+ Result += "\n\n";
+
+ // Send the message
+ if (write(STDOUT_FILENO,Result.begin(),Result.length()) !=
+ (signed)Result.length())
+ return 100;
+ }
+ }
+
+ return 0;
}