Allow shell-style comments in the input file
[mspang/inapt.git] / magic.cc
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <iostream>
4 #include <cstdio>
5 #include <fstream>
6 #include <apt-pkg/pkgcache.h>
7 #include <apt-pkg/cachefile.h>
8 #include <apt-pkg/dpkgdb.h>
9 #include <apt-pkg/progress.h>
10 #include <apt-pkg/init.h>
11 #include <apt-pkg/error.h>
12 #include <apt-pkg/algorithms.h>
13 #include <apt-pkg/sptr.h>
14 #include <apt-pkg/acquire-item.h>
15
16 #include "acqprogress.h"
17 #include "awesome.h"
18
19 using namespace std;
20
21
22 bool InstallPackages(pkgCacheFile &Cache,bool ShwKept = false,bool Ask = true,
23                      bool Safety = true)
24 {
25    if (_config->FindB("APT::Get::Purge",false) == true)
26    {
27       pkgCache::PkgIterator I = Cache->PkgBegin();
28       for (; I.end() == false; I++)
29       {
30          if (I.Purge() == false && Cache[I].Mode == pkgDepCache::ModeDelete)
31             Cache->MarkDelete(I,true);
32       }
33    }
34
35    if (Cache->BrokenCount() != 0)
36    {
37       return _error->Error("Internal error, InstallPackages was called with broken packages!");
38    }
39
40    if (Cache->DelCount() == 0 && Cache->InstCount() == 0 &&
41        Cache->BadCount() == 0)
42       return true;
43
44    if (Cache->DelCount() != 0 && _config->FindB("APT::Get::Remove",true) == false)
45       return _error->Error(("Packages need to be removed but remove is disabled."));
46
47    pkgRecords Recs(Cache);
48    if (_error->PendingError() == true)
49       return false;
50
51    FileFd Lock;
52    if (_config->FindB("Debug::NoLocking",false) == false &&
53        _config->FindB("APT::Get::Print-URIs") == false)
54    {
55       Lock.Fd(GetLock(_config->FindDir("Dir::Cache::Archives") + "lock"));
56       if (_error->PendingError() == true)
57          return _error->Error(("Unable to lock the download directory"));
58    }
59
60    unsigned int width = 80;
61    AcqTextStatus status (width, 0);
62    pkgAcquire Fetcher (&status);
63
64    pkgSourceList List;
65    if (List.ReadMainList() == false)
66       return _error->Error(("The list of sources could not be read."));
67
68    SPtr<pkgPackageManager> PM= _system->CreatePM(Cache);
69    if (PM->GetArchives(&Fetcher, &List, &Recs) == false ||
70        _error->PendingError() == true)
71       return false;
72
73    if (_error->PendingError() == true)
74       return false;
75
76    while (1)
77    {
78       bool Transient = false;
79       if (_config->FindB("APT::Get::Download",true) == false)
80       {
81          for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); I < Fetcher.ItemsEnd();)
82          {
83             if ((*I)->Local == true)
84             {
85                I++;
86                continue;
87             }
88
89             // Close the item and check if it was found in cache
90             (*I)->Finished();
91             if ((*I)->Complete == false)
92                Transient = true;
93
94             // Clear it out of the fetch list
95             delete *I;
96             I = Fetcher.ItemsBegin();
97          }
98       }
99
100       if (Fetcher.Run() == pkgAcquire::Failed)
101          return false;
102
103       // Print out errors
104       bool Failed = false;
105       for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); I != Fetcher.ItemsEnd(); I++)
106       {
107          if ((*I)->Status == pkgAcquire::Item::StatDone &&
108              (*I)->Complete == true)
109             continue;
110
111          if ((*I)->Status == pkgAcquire::Item::StatIdle)
112          {
113             Transient = true;
114             // Failed = true;
115             continue;
116          }
117
118          fprintf(stderr,("Failed to fetch %s  %s\n"),(*I)->DescURI().c_str(),
119                  (*I)->ErrorText.c_str());
120          Failed = true;
121       }
122
123       /* If we are in no download mode and missing files and there were
124          'failures' then the user must specify -m. Furthermore, there
125          is no such thing as a transient error in no-download mode! */
126       if (Transient == true &&
127           _config->FindB("APT::Get::Download",true) == false)
128       {
129          Transient = false;
130          Failed = true;
131       }
132
133       if (_config->FindB("APT::Get::Download-Only",false) == true)
134       {
135          if (Failed == true && _config->FindB("APT::Get::Fix-Missing",false) == false)
136             return _error->Error(("Some files failed to download"));
137          //c1out << _("Download complete and in download only mode") << endl;
138          return true;
139       }
140
141       if (Failed == true && _config->FindB("APT::Get::Fix-Missing",false) == false)
142       {
143          return _error->Error(("Unable to fetch some archives, maybe run apt-get update or try with --fix-missing?"));
144       }
145
146       if (Transient == true && Failed == true)
147          return _error->Error(("--fix-missing and media swapping is not currently supported"));
148
149       // Try to deal with missing package files
150       if (Failed == true && PM->FixMissing() == false)
151       {
152          cerr << ("Unable to correct missing packages.") << endl;
153          return _error->Error(("Aborting install."));
154       }
155
156       _system->UnLock();
157       int status_fd = _config->FindI("APT::Status-Fd",-1);
158       pkgPackageManager::OrderResult Res = PM->DoInstall(status_fd);
159       if (Res == pkgPackageManager::Failed || _error->PendingError() == true)
160          return false;
161       if (Res == pkgPackageManager::Completed)
162          return true;
163
164       // Reload the fetcher object and loop again for media swapping
165       Fetcher.Shutdown();
166       if (PM->GetArchives(&Fetcher,&List,&Recs) == false)
167          return false;
168
169       _system->Lock();
170    }
171 }
172
173
174 int main(int argc, char *argv[]) {
175
176     vector<char *> add_list;
177     vector<char *> del_list;
178
179     pkgInitConfig(*_config);
180     pkgInitSystem(*_config, _system);
181
182      _config->Set("Debug::pkgProblemResolver", true);
183
184     OpTextProgress prog;
185     pkgCacheFile cachef;
186
187     if (cachef.Open(prog) == false) {
188         _error->DumpErrors();
189         exit(1);
190     }
191
192     pkgCache *cache = cachef;
193     pkgDepCache *DCache = cachef;
194
195     scanner(add_list, del_list);
196
197     for (vector<char *>::iterator i = add_list.begin(); i < add_list.end(); i++) {
198       printf("install %s\n", *i);
199       DCache->MarkInstall(cache->FindPkg(*i), true);
200     }
201     for (vector<char *>::iterator i = del_list.begin(); i < del_list.end(); i++) {
202       printf("remove %s\n", *i);
203       DCache->MarkDelete(cache->FindPkg(*i), false);
204     }
205     for (vector<char *>::iterator i = add_list.begin(); i < add_list.end(); i++) {
206       DCache->MarkInstall(cache->FindPkg(*i), false);
207     }
208
209     fprintf(stderr, "\n");
210     fprintf(stderr, "nondownloadable packages:\n");
211     for (pkgCache::PkgIterator i = cache->PkgBegin(); !i.end(); i++) {
212        if (i.CurrentVer() && !i.CurrentVer().Downloadable()) {
213                fprintf(stderr, "%s ", i.Name());
214                fprintf(stderr, "%s\n", DCache->GetCandidateVer(i).VerStr());
215        }
216     }
217
218     fprintf(stderr, "\n");
219     fprintf(stderr, "inst %lu del %lu keep %lu broken %lu bad %lu\n",
220                     DCache->InstCount(), DCache->DelCount(), DCache->KeepCount(),
221                     DCache->BrokenCount(), DCache->BadCount());
222
223     for (pkgCache::PkgIterator i = cache->PkgBegin(); !i.end(); i++) {
224        if ((*DCache)[i].Install())
225          fprintf(stderr, "inst %s\n", i.Name());
226        if ((*DCache)[i].InstBroken())
227          fprintf(stderr, "instbroken %s\n", i.Name());
228        if ((*DCache)[i].NowBroken())
229          fprintf(stderr, "nowbroken %s\n", i.Name());
230     }
231
232     fprintf(stderr, "\n");
233
234     pkgProblemResolver fix (DCache);
235
236     for (vector<char *>::iterator i = add_list.begin(); i < add_list.end(); i++)
237             fix.Protect(cache->FindPkg(*i));
238     for (vector<char *>::iterator i = del_list.begin(); i < del_list.end(); i++)
239             fix.Protect(cache->FindPkg(*i));
240     fix.Resolve();
241
242     fprintf(stderr, "\n");
243     fprintf(stderr, "inst %lu del %lu keep %lu broken %lu bad %lu\n",
244                     DCache->InstCount(), DCache->DelCount(), DCache->KeepCount(),
245                     DCache->BrokenCount(), DCache->BadCount());
246     for (pkgCache::PkgIterator i = cache->PkgBegin(); !i.end(); i++) {
247        if ((*DCache)[i].Install())
248          fprintf(stderr, "inst %s\n", i.Name());
249        if ((*DCache)[i].Delete())
250          fprintf(stderr, "del %s\n", i.Name());
251        if ((*DCache)[i].InstBroken())
252          fprintf(stderr, "instbroken %s\n", i.Name());
253        if ((*DCache)[i].NowBroken())
254          fprintf(stderr, "nowbroken %s\n", i.Name());
255     }
256
257     fprintf(stderr, "\n");
258
259     InstallPackages(cachef);
260 }