- initial import of revision 374 from cnc
[apt.git] / apt-pkg / clean.cc
1 // -*- mode: cpp; mode: fold -*-
2 // Description                                                          /*{{{*/
3 // $Id: clean.cc,v 1.1 2002/07/23 17:54:50 niemeyer Exp $
4 /* ######################################################################
5
6    Clean - Clean out downloaded directories
7    
8    ##################################################################### */
9                                                                         /*}}}*/
10 // Includes                                                             /*{{{*/
11 #ifdef __GNUG__
12 #pragma implementation "apt-pkg/clean.h"
13 #endif
14
15 #include <apt-pkg/clean.h>
16 #include <apt-pkg/strutl.h>
17 #include <apt-pkg/error.h>
18 #include <apt-pkg/configuration.h>
19
20 #include <apti18n.h>    
21
22 #include <dirent.h>
23 #include <sys/stat.h>
24 #include <unistd.h>
25                                                                         /*}}}*/
26
27 // ArchiveCleaner::Go - Perform smart cleanup of the archive            /*{{{*/
28 // ---------------------------------------------------------------------
29 /* Scan the directory for files to erase, we check the version information
30    against our database to see if it is interesting */
31 bool pkgArchiveCleaner::Go(string Dir,pkgCache &Cache)
32 {
33    bool CleanInstalled = _config->FindB("APT::Clean-Installed",true);
34    string MyArch = _config->Find("APT::Architecture");
35       
36    DIR *D = opendir(Dir.c_str());
37    if (D == 0)
38       return _error->Errno("opendir",_("Unable to read %s"),Dir.c_str());
39
40    string StartDir = SafeGetCWD();
41    if (chdir(Dir.c_str()) != 0)
42    {
43       closedir(D);
44       return _error->Errno("chdir",_("Unable to change to %s"),Dir.c_str());
45    }
46    
47    for (struct dirent *Dir = readdir(D); Dir != 0; Dir = readdir(D))
48    {
49       // Skip some files..
50       if (strcmp(Dir->d_name,"lock") == 0 ||
51           strcmp(Dir->d_name,"partial") == 0 ||
52           strcmp(Dir->d_name,".") == 0 ||
53           strcmp(Dir->d_name,"..") == 0)
54          continue;
55
56       struct stat St;
57       if (stat(Dir->d_name,&St) != 0)
58       {
59          chdir(StartDir.c_str());
60          closedir(D);
61          return _error->Errno("stat",_("Unable to stat %s."),Dir->d_name);
62       }
63       
64       // Grab the package name
65       const char *I = Dir->d_name;
66       for (; *I != 0 && *I != '_';I++);
67       if (*I != '_')
68          continue;
69       string Pkg = DeQuoteString(string(Dir->d_name,I-Dir->d_name));
70
71       // Grab the version
72       const char *Start = I + 1;
73       for (I = Start; *I != 0 && *I != '_';I++);
74       if (*I != '_')
75          continue;
76       string Ver = DeQuoteString(string(Start,I-Start));
77   
78       // Grab the arch
79       Start = I + 1;
80       for (I = Start; *I != 0 && *I != '.' ;I++);
81       if (*I != '.')
82          continue;
83       string Arch = DeQuoteString(string(Start,I-Start));
84       
85 // CNC:2004-04-19
86 #if 0
87       if (Arch != "all" && Arch != MyArch)
88          continue;
89 #endif
90       
91       // Lookup the package
92       pkgCache::PkgIterator P = Cache.FindPkg(Pkg);
93       if (P.end() != true)
94       {
95          pkgCache::VerIterator V = P.VersionList();
96          for (; V.end() == false; V++)
97          {
98             // See if we can fetch this version at all
99             bool IsFetchable = false;
100             for (pkgCache::VerFileIterator J = V.FileList(); 
101                  J.end() == false; J++)
102             {
103                if (CleanInstalled == true &&
104                    (J.File()->Flags & pkgCache::Flag::NotSource) != 0)
105                   continue;
106                IsFetchable = true;
107                break;
108             }
109             
110             // See if this verison matches the file
111             if (IsFetchable == true && Ver == V.VerStr())
112                break;
113          }
114          
115          // We found a match, keep the file
116          if (V.end() == false)
117             continue;
118       }
119             
120       Erase(Dir->d_name,Pkg,Ver,St);
121    };
122    
123    chdir(StartDir.c_str());
124    closedir(D);
125    return true;   
126 }
127                                                                         /*}}}*/