- initial import of revision 374 from cnc
[apt.git] / methods / file.cc
1 // -*- mode: cpp; mode: fold -*-
2 // Description                                                          /*{{{*/
3 // $Id: file.cc,v 1.9 2003/02/10 07:34:41 doogie Exp $
4 /* ######################################################################
5
6    File URI method for APT
7    
8    This simply checks that the file specified exists, if so the relevent
9    information is returned. If a .gz filename is specified then the file
10    name with .gz removed will also be checked and information about it
11    will be returned in Alt-*
12    
13    ##################################################################### */
14                                                                         /*}}}*/
15 // Include Files                                                        /*{{{*/
16 #include <apt-pkg/acquire-method.h>
17 #include <apt-pkg/error.h>
18
19 #include <sys/stat.h>
20 #include <unistd.h>
21
22 // CNC:2003-02-20 - Moved header to fix compilation error when
23 //                  --disable-nls is used.
24 #include <apti18n.h>
25                                                                         /*}}}*/
26
27 class FileMethod : public pkgAcqMethod
28 {
29    virtual bool Fetch(FetchItem *Itm);
30    
31    public:
32    
33    FileMethod() : pkgAcqMethod("1.0",SingleInstance | LocalOnly) {};
34 };
35
36 // FileMethod::Fetch - Fetch a file                                     /*{{{*/
37 // ---------------------------------------------------------------------
38 /* */
39 bool FileMethod::Fetch(FetchItem *Itm)
40 {
41    URI Get = Itm->Uri;
42    string File = Get.Path;
43    FetchResult Res;
44    if (Get.Host.empty() == false)
45       return _error->Error(_("Invalid URI, local URIS must not start with //"));
46
47    // See if the file exists
48    struct stat Buf;
49    if (stat(File.c_str(),&Buf) == 0)
50    {
51       Res.Size = Buf.st_size;
52       Res.Filename = File;
53       Res.LastModified = Buf.st_mtime;
54       Res.IMSHit = false;
55       if (Itm->LastModified == Buf.st_mtime && Itm->LastModified != 0)
56          Res.IMSHit = true;
57    }
58    
59    // CNC:2003-11-04
60    // See if we can compute a file without a .gz/.bz2/etc extension
61    string ComprExtension = _config->Find("Acquire::ComprExtension", ".bz2");
62    string::size_type Pos = File.rfind(ComprExtension);
63    if (Pos + ComprExtension.length() == File.length())
64    {
65       File = string(File,0,Pos);
66       if (stat(File.c_str(),&Buf) == 0)
67       {
68          FetchResult AltRes;
69          AltRes.Size = Buf.st_size;
70          AltRes.Filename = File;
71          AltRes.LastModified = Buf.st_mtime;
72          AltRes.IMSHit = false;
73          if (Itm->LastModified == Buf.st_mtime && Itm->LastModified != 0)
74             AltRes.IMSHit = true;
75          
76          URIDone(Res,&AltRes);
77          return true;
78       }      
79    }
80    
81    if (Res.Filename.empty() == true)
82       return _error->Error(_("File not found"));
83    
84    URIDone(Res);
85    return true;
86 }
87                                                                         /*}}}*/
88
89 int main()
90 {
91    FileMethod Mth;
92    return Mth.Run();
93 }