- initial import of revision 374 from cnc
[apt.git] / tools / cached_md5.cc
1 /*
2  * $Id: cached_md5.cc,v 1.4 2003/01/29 13:47:31 niemeyer Exp $
3  */
4 #include <alloca.h>
5 #include <ctype.h>
6 #include <dirent.h>
7 #include <errno.h>
8 #include <fcntl.h>
9 #include <rpm/rpmlib.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <sys/stat.h>
13 #include <unistd.h>
14 #include <assert.h>
15
16 #include "cached_md5.h"
17
18 #include <apt-pkg/error.h>
19 #include <apt-pkg/tagfile.h>
20 #include <apt-pkg/rpmhandler.h>
21 #include <apt-pkg/configuration.h>
22 #include <apt-pkg/md5.h>
23
24 #include <config.h>
25
26 CachedMD5::CachedMD5(string DirName, string Domain)
27 {
28    string fname = DirName;
29    for (string::iterator i = fname.begin(); i != fname.end(); ++i)
30       if ('/' == *i)
31          *i = '_';
32    CacheFileName = _config->FindDir("Dir::Cache", "/var/cache/apt") + '/' +
33                    Domain + '/' + fname + ".md5cache";
34
35    FILE *f = fopen(CacheFileName.c_str(), "r");
36    if (!f)
37       return;
38
39    while (1)
40    {
41       char buf[BUFSIZ];
42       if (!fgets(buf, sizeof(buf), f))
43          break;
44       char *p1 = strchr(buf, ' ');
45       assert(p1);
46
47       string File;
48       File = string(buf, p1++);
49       char *p2 = strchr(p1, ' ');
50       assert(p2);
51       
52       FileData Data;
53       Data.MD5 = string(p1, p2++);
54       Data.TimeStamp = atol(p2);
55       MD5Table[File] = Data;
56    }
57
58    fclose(f);
59 }
60
61
62 CachedMD5::~CachedMD5()
63 {
64    FILE *f = fopen(CacheFileName.c_str(), "w+");
65    if (f)
66    {
67       for (map<string,FileData>::const_iterator I = MD5Table.begin();
68            I != MD5Table.end(); I++ )
69       {
70          const string &File = (*I).first;
71          const FileData &Data = (*I).second;
72          fprintf(f, "%s %s %lu\n",
73                  File.c_str(), Data.MD5.c_str(), Data.TimeStamp );
74       }
75       fclose(f);
76    }
77 }
78
79 void CachedMD5::MD5ForFile(string FileName, time_t TimeStamp, char *buf)
80 {
81    if (MD5Table.find(FileName) != MD5Table.end()
82        && TimeStamp == MD5Table[FileName].TimeStamp )
83    {
84       strcpy(buf, MD5Table[FileName].MD5.c_str());
85    }
86    else
87    {
88       MD5Summation MD5;
89       FileFd File(FileName, FileFd::ReadOnly);
90       MD5.AddFD(File.Fd(), File.Size());
91       File.Close();
92       FileData Data;
93       Data.MD5 = MD5.Result().Value();
94       Data.TimeStamp = TimeStamp;
95       MD5Table[FileName] = Data;
96       strcpy(buf, Data.MD5.c_str());
97    }
98 }
99
100 // vim:sts=3:sw=3