1 | /* rpackage.cc - wrapper for accessing package information |
---|
2 | * |
---|
3 | * Copyright (c) 2000-2003 Conectiva S/A |
---|
4 | * 2002 Michael Vogt <mvo@debian.org> |
---|
5 | * |
---|
6 | * Author: Alfredo K. Kojima <kojima@conectiva.com.br> |
---|
7 | * Michael Vogt <mvo@debian.org> |
---|
8 | * |
---|
9 | * Portions Taken from Gnome APT |
---|
10 | * Copyright (C) 1998 Havoc Pennington <hp@pobox.com> |
---|
11 | * |
---|
12 | * |
---|
13 | * This program is free software; you can redistribute it and/or |
---|
14 | * modify it under the terms of the GNU General Public License as |
---|
15 | * published by the Free Software Foundation; either version 2 of the |
---|
16 | * License, or (at your option) any later version. |
---|
17 | * |
---|
18 | * This program is distributed in the hope that it will be useful, |
---|
19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
21 | * GNU General Public License for more details. |
---|
22 | * |
---|
23 | * You should have received a copy of the GNU General Public License |
---|
24 | * along with this program; if not, write to the Free Software |
---|
25 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 |
---|
26 | * USA |
---|
27 | */ |
---|
28 | |
---|
29 | |
---|
30 | #include "config.h" |
---|
31 | |
---|
32 | #include "rpackage.h" |
---|
33 | #include "rpackagelister.h" |
---|
34 | #include "pkg_acqfile.h" |
---|
35 | |
---|
36 | #include "i18n.h" |
---|
37 | |
---|
38 | #include <map> |
---|
39 | #include <algorithm> |
---|
40 | #include <fstream> |
---|
41 | #include <cstdio> |
---|
42 | #include <unistd.h> |
---|
43 | #include <sys/stat.h> |
---|
44 | #include <sys/types.h> |
---|
45 | #include <assert.h> |
---|
46 | #include <sstream> |
---|
47 | |
---|
48 | |
---|
49 | |
---|
50 | #include <apt-pkg/pkgrecords.h> |
---|
51 | #include <apt-pkg/depcache.h> |
---|
52 | #include <apt-pkg/srcrecords.h> |
---|
53 | #include <apt-pkg/algorithms.h> |
---|
54 | #include <apt-pkg/error.h> |
---|
55 | #include <apt-pkg/configuration.h> |
---|
56 | #include <apt-pkg/tagfile.h> |
---|
57 | #include <apt-pkg/policy.h> |
---|
58 | #include <apt-pkg/sptr.h> |
---|
59 | #include <apt-pkg/strutl.h> |
---|
60 | #include <apt-pkg/cacheiterators.h> |
---|
61 | #include <apt-pkg/pkgcache.h> |
---|
62 | #include <apt-pkg/versionmatch.h> |
---|
63 | #include <apt-pkg/version.h> |
---|
64 | #include <apt-pkg/policy.h> |
---|
65 | |
---|
66 | #ifdef WITH_LUA |
---|
67 | #include <apt-pkg/luaiface.h> |
---|
68 | #endif |
---|
69 | |
---|
70 | #include "raptoptions.h" |
---|
71 | |
---|
72 | |
---|
73 | static char descrBuffer[8192]; |
---|
74 | |
---|
75 | static char *parseDescription(string descr); |
---|
76 | |
---|
77 | |
---|
78 | RPackage::RPackage(RPackageLister *lister, pkgDepCache *depcache, |
---|
79 | pkgRecords *records, pkgCache::PkgIterator &pkg) |
---|
80 | : _lister(lister), _records(records), _depcache(depcache), |
---|
81 | _notify(true), _boolFlags(0) |
---|
82 | { |
---|
83 | _package = new pkgCache::PkgIterator(pkg); |
---|
84 | |
---|
85 | pkgDepCache::StateCache & State = (*_depcache)[*_package]; |
---|
86 | if (State.CandVersion != NULL) |
---|
87 | _defaultCandVer = State.CandVersion; |
---|
88 | } |
---|
89 | |
---|
90 | |
---|
91 | RPackage::~RPackage() |
---|
92 | { |
---|
93 | delete _package; |
---|
94 | } |
---|
95 | |
---|
96 | #if 0 |
---|
97 | void RPackage::addVirtualPackage(pkgCache::PkgIterator dep) |
---|
98 | { |
---|
99 | _virtualPackages.push_back(dep); |
---|
100 | _provides.push_back(dep.Name()); |
---|
101 | } |
---|
102 | #endif |
---|
103 | |
---|
104 | const char *RPackage::section() |
---|
105 | { |
---|
106 | const char *s = _package->Section(); |
---|
107 | if (s != NULL) |
---|
108 | return s; |
---|
109 | else |
---|
110 | return _("Unknown"); |
---|
111 | } |
---|
112 | |
---|
113 | const char *RPackage::srcPackage() |
---|
114 | { |
---|
115 | static string _srcPkg; |
---|
116 | |
---|
117 | pkgCache::VerIterator ver = _package->VersionList(); |
---|
118 | pkgRecords::Parser &rec=_records->Lookup(ver.FileList()); |
---|
119 | _srcPkg = rec.SourcePkg().empty()?name():rec.SourcePkg(); |
---|
120 | |
---|
121 | return _srcPkg.c_str();; |
---|
122 | } |
---|
123 | |
---|
124 | |
---|
125 | const char *RPackage::summary() |
---|
126 | { |
---|
127 | static string _summary; |
---|
128 | |
---|
129 | pkgCache::VerIterator ver = _package->VersionList(); |
---|
130 | |
---|
131 | if (!ver.end()) { |
---|
132 | pkgRecords::Parser & parser = _records->Lookup(ver.FileList()); |
---|
133 | |
---|
134 | _summary = parser.ShortDesc(); |
---|
135 | return _summary.c_str(); |
---|
136 | } |
---|
137 | return ""; |
---|
138 | } |
---|
139 | |
---|
140 | |
---|
141 | const char *RPackage::maintainer() |
---|
142 | { |
---|
143 | static string _maintainer; |
---|
144 | |
---|
145 | pkgCache::VerIterator ver = _package->VersionList(); |
---|
146 | |
---|
147 | if (!ver.end()) { |
---|
148 | pkgRecords::Parser & parser = _records->Lookup(ver.FileList()); |
---|
149 | _maintainer = parser.Maintainer(); |
---|
150 | return _maintainer.c_str(); |
---|
151 | } |
---|
152 | return ""; |
---|
153 | } |
---|
154 | |
---|
155 | |
---|
156 | const char *RPackage::vendor() |
---|
157 | { |
---|
158 | return "dunno"; |
---|
159 | } |
---|
160 | |
---|
161 | const char *RPackage::installedVersion() |
---|
162 | { |
---|
163 | if ((*_package)->CurrentVer == 0) |
---|
164 | return NULL; |
---|
165 | return _package->CurrentVer().VerStr(); |
---|
166 | } |
---|
167 | |
---|
168 | const char *RPackage::availableVersion() |
---|
169 | { |
---|
170 | pkgDepCache::StateCache & State = (*_depcache)[*_package]; |
---|
171 | if (State.CandidateVer == 0) |
---|
172 | return NULL; |
---|
173 | return State.CandidateVerIter(*_depcache).VerStr(); |
---|
174 | } |
---|
175 | |
---|
176 | const char *RPackage::priority() |
---|
177 | { |
---|
178 | pkgCache::VerIterator ver = _package->VersionList(); |
---|
179 | |
---|
180 | if (ver != 0) |
---|
181 | return ver.PriorityType(); |
---|
182 | else |
---|
183 | return NULL; |
---|
184 | } |
---|
185 | |
---|
186 | #ifndef HAVE_RPM |
---|
187 | const char *RPackage::installedFiles() |
---|
188 | { |
---|
189 | static string filelist; |
---|
190 | string s; |
---|
191 | |
---|
192 | filelist.erase(filelist.begin(), filelist.end()); |
---|
193 | |
---|
194 | string f = "/var/lib/dpkg/info/" + string(name()) + ".list"; |
---|
195 | if (FileExists(f)) { |
---|
196 | ifstream in(f.c_str()); |
---|
197 | if (!in != 0) |
---|
198 | return ""; |
---|
199 | while (in.eof() == false) { |
---|
200 | getline(in, s); |
---|
201 | filelist += s + "\n"; |
---|
202 | } |
---|
203 | |
---|
204 | in >> filelist; |
---|
205 | return filelist.c_str(); |
---|
206 | } |
---|
207 | filelist = _("The list of installed files is only available for installed packages"); |
---|
208 | |
---|
209 | return filelist.c_str(); |
---|
210 | } |
---|
211 | #else |
---|
212 | const char *RPackage::installedFiles() |
---|
213 | { |
---|
214 | return ""; |
---|
215 | } |
---|
216 | #endif |
---|
217 | |
---|
218 | |
---|
219 | const char *RPackage::description() |
---|
220 | { |
---|
221 | static string _description; |
---|
222 | |
---|
223 | pkgCache::VerIterator ver = _package->VersionList(); |
---|
224 | |
---|
225 | if (!ver.end()) { |
---|
226 | pkgRecords::Parser & parser = _records->Lookup(ver.FileList()); |
---|
227 | _description = parseDescription(parser.LongDesc()); |
---|
228 | return _description.c_str(); |
---|
229 | } else { |
---|
230 | return ""; |
---|
231 | } |
---|
232 | } |
---|
233 | |
---|
234 | long RPackage::installedSize() |
---|
235 | { |
---|
236 | pkgCache::VerIterator ver = _package->CurrentVer(); |
---|
237 | |
---|
238 | if (!ver.end()) |
---|
239 | return ver->InstalledSize; |
---|
240 | else |
---|
241 | return -1; |
---|
242 | } |
---|
243 | |
---|
244 | long RPackage::availableInstalledSize() |
---|
245 | { |
---|
246 | pkgDepCache::StateCache & State = (*_depcache)[*_package]; |
---|
247 | if (State.CandidateVer == 0) |
---|
248 | return -1; |
---|
249 | return State.CandidateVerIter(*_depcache)->InstalledSize; |
---|
250 | } |
---|
251 | |
---|
252 | long RPackage::availablePackageSize() |
---|
253 | { |
---|
254 | pkgDepCache::StateCache & State = (*_depcache)[*_package]; |
---|
255 | if (State.CandidateVer == 0) |
---|
256 | return -1; |
---|
257 | return State.CandidateVerIter(*_depcache)->Size; |
---|
258 | } |
---|
259 | |
---|
260 | int RPackage::getFlags() |
---|
261 | { |
---|
262 | int flags = 0; |
---|
263 | |
---|
264 | pkgDepCache::StateCache &state = (*_depcache)[*_package]; |
---|
265 | pkgCache::VerIterator ver = _package->CurrentVer(); |
---|
266 | |
---|
267 | if (state.Install()) |
---|
268 | flags |= FInstall; |
---|
269 | |
---|
270 | if (state.iFlags & pkgDepCache::ReInstall) { |
---|
271 | flags |= FReInstall; |
---|
272 | } else if (state.NewInstall()) { // Order matters here. |
---|
273 | flags |= FNewInstall; |
---|
274 | } else if (state.Upgrade()) { |
---|
275 | flags |= FUpgrade; |
---|
276 | } else if (state.Downgrade()) { |
---|
277 | flags |= FDowngrade; |
---|
278 | } else if (state.Delete()) { |
---|
279 | flags |= FRemove; |
---|
280 | if (state.iFlags & pkgDepCache::Purge) |
---|
281 | flags |= FPurge; |
---|
282 | } else if (state.Keep()) { |
---|
283 | flags |= FKeep; |
---|
284 | } |
---|
285 | |
---|
286 | if (!ver.end()) { |
---|
287 | flags |= FInstalled; |
---|
288 | |
---|
289 | if (state.Upgradable() && state.CandidateVer != NULL) { |
---|
290 | flags |= FOutdated; |
---|
291 | if (state.Keep()) |
---|
292 | flags |= FHeld; |
---|
293 | } |
---|
294 | |
---|
295 | if (state.Downgrade()) |
---|
296 | flags |= FDowngrade; |
---|
297 | } |
---|
298 | |
---|
299 | if (state.NowBroken()) |
---|
300 | flags |= FNowBroken; |
---|
301 | |
---|
302 | if (state.InstBroken()) |
---|
303 | flags |= FInstBroken; |
---|
304 | |
---|
305 | if ((*_package)->Flags & (pkgCache::Flag::Important | |
---|
306 | pkgCache::Flag::Essential)) |
---|
307 | flags |= FImportant; |
---|
308 | |
---|
309 | if ((*_package)->CurrentState == pkgCache::State::ConfigFiles) |
---|
310 | flags |= FResidualConfig; |
---|
311 | |
---|
312 | if (state.CandidateVer == 0 || |
---|
313 | !state.CandidateVerIter(*_depcache).Downloadable()) |
---|
314 | flags |= FNotInstallable; |
---|
315 | |
---|
316 | return flags | _boolFlags; |
---|
317 | } |
---|
318 | |
---|
319 | #if 0 |
---|
320 | bool RPackage::isWeakDep(pkgCache::DepIterator &dep) |
---|
321 | { |
---|
322 | if (dep->Type != pkgCache::Dep::Suggests |
---|
323 | && dep->Type != pkgCache::Dep::Recommends) |
---|
324 | return false; |
---|
325 | else |
---|
326 | return true; |
---|
327 | } |
---|
328 | |
---|
329 | |
---|
330 | bool RPackage::enumWDeps(const char *&type, const char *&what, |
---|
331 | bool &satisfied) |
---|
332 | { |
---|
333 | pkgCache::VerIterator ver; |
---|
334 | pkgDepCache::StateCache & state = (*_depcache)[*_package]; |
---|
335 | |
---|
336 | |
---|
337 | if (state.Keep() || state.Held()) { |
---|
338 | ver = (*_depcache)[*_package].InstVerIter(*_depcache); |
---|
339 | |
---|
340 | if (ver.end()) |
---|
341 | ver = _package->VersionList(); |
---|
342 | } else { |
---|
343 | ver = _package->VersionList(); |
---|
344 | } |
---|
345 | if (ver.end()) |
---|
346 | return false; |
---|
347 | |
---|
348 | _wdepI = ver.DependsList(); |
---|
349 | // uninitialized but doesn't matter, they just have to be equal |
---|
350 | _wdepStart = _wdepEnd; |
---|
351 | |
---|
352 | return nextWDeps(type, what, satisfied); |
---|
353 | } |
---|
354 | |
---|
355 | |
---|
356 | bool RPackage::nextWDeps(const char *&type, const char *&what, |
---|
357 | bool &satisfied) |
---|
358 | { |
---|
359 | static char buffer[32]; |
---|
360 | |
---|
361 | while (1) { |
---|
362 | if (_wdepStart == _wdepEnd) { |
---|
363 | if (_wdepI.end()) |
---|
364 | return false; |
---|
365 | |
---|
366 | _wdepI.GlobOr(_wdepStart, _wdepEnd); |
---|
367 | |
---|
368 | snprintf(buffer, sizeof(buffer), "%s", _wdepEnd.DepType()); |
---|
369 | } else { |
---|
370 | _wdepStart++; |
---|
371 | |
---|
372 | snprintf(buffer, sizeof(buffer), "| %s", _wdepEnd.DepType()); |
---|
373 | } |
---|
374 | |
---|
375 | satisfied = false; |
---|
376 | if (!isWeakDep(_wdepEnd)) |
---|
377 | continue; |
---|
378 | |
---|
379 | if (((*_depcache)[_wdepStart] & pkgDepCache::DepGInstall) == |
---|
380 | pkgDepCache::DepGInstall) |
---|
381 | satisfied = true; |
---|
382 | |
---|
383 | type = buffer; |
---|
384 | |
---|
385 | pkgCache::PkgIterator depPkg = _wdepStart.TargetPkg(); |
---|
386 | what = depPkg.Name(); |
---|
387 | |
---|
388 | break; |
---|
389 | } |
---|
390 | return true; |
---|
391 | } |
---|
392 | #endif |
---|
393 | |
---|
394 | vector<DepInformation> RPackage::enumRDeps() |
---|
395 | { |
---|
396 | vector<DepInformation> deps; |
---|
397 | DepInformation dep; |
---|
398 | pkgCache::VerIterator Cur; |
---|
399 | |
---|
400 | for(pkgCache::DepIterator D = _package->RevDependsList(); D.end() != true; D++) { |
---|
401 | // clear old values |
---|
402 | dep.isOr=dep.isVirtual=false; |
---|
403 | dep.name=dep.version=dep.versionComp=NULL; |
---|
404 | |
---|
405 | // check target and or-depends status |
---|
406 | pkgCache::PkgIterator Trg = D.TargetPkg(); |
---|
407 | if ((D->CompareOp & pkgCache::Dep::Or) == pkgCache::Dep::Or) { |
---|
408 | dep.version = _("or dependency"); |
---|
409 | dep.versionComp = ""; |
---|
410 | } |
---|
411 | |
---|
412 | //FIXME: HACK ALARM, we need a "RDepends" type, so we use the last |
---|
413 | // one in pkg-dep |
---|
414 | dep.type = (pkgCache::Dep::DepType)(pkgCache::Dep::Obsoletes+1); |
---|
415 | dep.name = D.ParentPkg().Name(); |
---|
416 | |
---|
417 | if(Trg->VersionList == 0) |
---|
418 | dep.isVirtual=true; |
---|
419 | |
---|
420 | deps.push_back(dep); |
---|
421 | } |
---|
422 | return deps; |
---|
423 | } |
---|
424 | |
---|
425 | #if 0 |
---|
426 | bool RPackage::enumRDeps(const char *&dep, const char *&what) |
---|
427 | { |
---|
428 | _rdepI = _package->RevDependsList(); |
---|
429 | |
---|
430 | _vpackI = 0; |
---|
431 | |
---|
432 | return nextRDeps(dep, what); |
---|
433 | } |
---|
434 | |
---|
435 | |
---|
436 | bool RPackage::nextRDeps(const char *&dep, const char *&what) |
---|
437 | { |
---|
438 | while (_rdepI.end()) { |
---|
439 | if ((unsigned)_vpackI == _virtualPackages.size()) |
---|
440 | return false; |
---|
441 | |
---|
442 | _rdepI = _virtualPackages[_vpackI].RevDependsList(); |
---|
443 | _vpackI++; |
---|
444 | } |
---|
445 | what = _rdepI.TargetPkg().Name(); |
---|
446 | dep = _rdepI.ParentPkg().Name(); |
---|
447 | |
---|
448 | _rdepI++; |
---|
449 | |
---|
450 | return true; |
---|
451 | } |
---|
452 | #endif |
---|
453 | |
---|
454 | #if 0 |
---|
455 | bool RPackage::enumAvailDeps(const char *&type, const char *&what, |
---|
456 | const char *&pkg, const char *&which, |
---|
457 | char *&summary, bool &satisfied) |
---|
458 | { |
---|
459 | pkgCache::VerIterator ver; |
---|
460 | // pkgDepCache::StateCache & state = (*_depcache)[*_package]; |
---|
461 | |
---|
462 | //ver = _package->VersionList(); |
---|
463 | ver = (*_depcache)[*_package].CandidateVerIter(*_depcache); |
---|
464 | |
---|
465 | if (ver.end()) |
---|
466 | return false; |
---|
467 | |
---|
468 | _depI = ver.DependsList(); |
---|
469 | // uninitialized but doesn't matter, they just have to be equal |
---|
470 | _depStart = _depEnd; |
---|
471 | |
---|
472 | return nextDeps(type, what, pkg, which, summary, satisfied); |
---|
473 | } |
---|
474 | |
---|
475 | |
---|
476 | vector<RPackage *> RPackage::getInstalledDeps() |
---|
477 | { |
---|
478 | vector < RPackage *>deps; |
---|
479 | pkgCache::VerIterator ver; |
---|
480 | |
---|
481 | ver = (*_depcache)[*_package].InstVerIter(*_depcache); |
---|
482 | |
---|
483 | if (ver.end()) |
---|
484 | ver = _package->VersionList(); |
---|
485 | |
---|
486 | if (ver.end()) |
---|
487 | return deps; |
---|
488 | |
---|
489 | _depI = ver.DependsList(); |
---|
490 | // uninitialized but doesn't matter, they just have to be equal |
---|
491 | |
---|
492 | pkgCache::DepIterator depIter = _depI; |
---|
493 | while (!depIter.end()) { |
---|
494 | pkgCache::PkgIterator depPkg = depIter.TargetPkg(); |
---|
495 | string name = depPkg.Name(); |
---|
496 | deps.push_back(_lister->getPackage(name)); |
---|
497 | depIter++; |
---|
498 | } |
---|
499 | |
---|
500 | return deps; |
---|
501 | } |
---|
502 | |
---|
503 | #endif |
---|
504 | |
---|
505 | |
---|
506 | |
---|
507 | /* Mostly taken from apt-get.cc:ShowBroken() */ |
---|
508 | string RPackage::showWhyInstBroken() |
---|
509 | { |
---|
510 | pkgCache::DepIterator depI; |
---|
511 | pkgCache::VerIterator Ver; |
---|
512 | bool First = true; |
---|
513 | ostringstream out; |
---|
514 | |
---|
515 | pkgDepCache::StateCache & State = (*_depcache)[*_package]; |
---|
516 | Ver = State.CandidateVerIter(*_depcache); |
---|
517 | |
---|
518 | // check if there is actually something to install |
---|
519 | if (Ver == 0) { |
---|
520 | ioprintf(out, |
---|
521 | _ |
---|
522 | ("\nPackage %s has no available version, but exists in the database.\n" |
---|
523 | "This typically means that the package was mentioned in a dependency and " |
---|
524 | "never uploaded, has been obsoleted or is not available with the contents " |
---|
525 | "of sources.list\n"), _package->Name()); |
---|
526 | return out.str(); |
---|
527 | } |
---|
528 | |
---|
529 | for (pkgCache::DepIterator D = Ver.DependsList(); D.end() == false;) { |
---|
530 | // Compute a single dependency element (glob or) |
---|
531 | pkgCache::DepIterator Start; |
---|
532 | pkgCache::DepIterator End; |
---|
533 | D.GlobOr(Start, End); |
---|
534 | |
---|
535 | if (_depcache->IsImportantDep(End) == false) |
---|
536 | continue; |
---|
537 | |
---|
538 | if (((*_depcache)[End] & pkgDepCache::DepGInstall) == |
---|
539 | pkgDepCache::DepGInstall) |
---|
540 | continue; |
---|
541 | |
---|
542 | bool FirstOr = true; |
---|
543 | while (1) { |
---|
544 | /* Show a summary of the target package if possible. In the case |
---|
545 | of virtual packages we show nothing */ |
---|
546 | pkgCache::PkgIterator Targ = Start.TargetPkg(); |
---|
547 | if (Targ->ProvidesList == 0) { |
---|
548 | ioprintf(out, " "); |
---|
549 | pkgCache::VerIterator Ver = |
---|
550 | (*_depcache)[Targ].InstVerIter(*_depcache); |
---|
551 | // add minimal version information |
---|
552 | string requiredVersion; |
---|
553 | if(Start.TargetVer() != 0) |
---|
554 | requiredVersion = "("+string(Start.CompType())+string(Start.TargetVer())+")"; |
---|
555 | if (Ver.end() == false) { |
---|
556 | if (FirstOr == false) |
---|
557 | // TRANSLATORS: dependency error message, example: |
---|
558 | // "apt 0.5.4 but 0.5.3 is to be installed" |
---|
559 | ioprintf(out, _("\t%s %s but %s is to be installed"), |
---|
560 | Start.TargetPkg().Name(), requiredVersion.c_str(), |
---|
561 | Ver.VerStr()); |
---|
562 | else |
---|
563 | // TRANSLATORS: dependency error message, example: |
---|
564 | // "Depends: apt 0.5.4 but 0.5.3 is to be installed" |
---|
565 | ioprintf(out, _(" %s: %s %s but %s is to be installed"), |
---|
566 | End.DepType(), Start.TargetPkg().Name(), |
---|
567 | requiredVersion.c_str(), Ver.VerStr()); |
---|
568 | } else { |
---|
569 | if ((*_depcache)[Targ].CandidateVerIter(*_depcache).end() == |
---|
570 | true) { |
---|
571 | if (Targ->ProvidesList == 0) |
---|
572 | if (FirstOr == false) |
---|
573 | // TRANSLATORS: dependency error message, example: |
---|
574 | // "apt 0.5.4 but it is not installable" |
---|
575 | ioprintf(out, _("\t%s %s but it is not installable"), |
---|
576 | Start.TargetPkg().Name(), |
---|
577 | requiredVersion.c_str()); |
---|
578 | else |
---|
579 | // TRANSLATORS: dependency error message, example: |
---|
580 | // "Depends: apt 0.5.4 but it is not installable", |
---|
581 | ioprintf(out, "%s: %s %s but it is not installable", |
---|
582 | End.DepType(), Start.TargetPkg().Name(), |
---|
583 | requiredVersion.c_str()); |
---|
584 | else if (FirstOr == false) |
---|
585 | // TRANSLATORS: dependency error message, example: |
---|
586 | // "apt but it is a virtual package" |
---|
587 | ioprintf(out, _("\t%s but it is a virtual package"), |
---|
588 | Start.TargetPkg().Name()); |
---|
589 | else |
---|
590 | // TRANSLATORS: dependency error message, example: |
---|
591 | // "Depends: apt but it is a virtual package" |
---|
592 | ioprintf(out, _("%s: %s but it is a virtual package"), |
---|
593 | End.DepType(), Start.TargetPkg().Name()); |
---|
594 | } else if (FirstOr == false) |
---|
595 | // TRANSLATORS: dependency error message, example: |
---|
596 | // "apt but it is not going to be installed" |
---|
597 | ioprintf(out, _("\t%s but it is not going to be installed"), |
---|
598 | Start.TargetPkg().Name()); |
---|
599 | else |
---|
600 | // TRANSLATORS: dependency error message, example: |
---|
601 | // "Depends: apt but it is not going to be installed" |
---|
602 | ioprintf(out, _("%s: %s but it is not going to be installed"), |
---|
603 | End.DepType(), Start.TargetPkg().Name()); |
---|
604 | } |
---|
605 | } else { |
---|
606 | // virtual pkgs |
---|
607 | if (FirstOr == false) |
---|
608 | ioprintf(out, "\t%s", Start.TargetPkg().Name()); |
---|
609 | else |
---|
610 | ioprintf(out, " %s: %s", End.DepType(), |
---|
611 | Start.TargetPkg().Name()); |
---|
612 | // Show a quick summary of the version requirements |
---|
613 | if (Start.TargetVer() != 0) |
---|
614 | ioprintf(out, " (%s %s)", Start.CompType(), Start.TargetVer()); |
---|
615 | } |
---|
616 | |
---|
617 | First = false; |
---|
618 | FirstOr = false; |
---|
619 | |
---|
620 | if (Start != End) |
---|
621 | ioprintf(out, _(" or")); |
---|
622 | ioprintf(out, "\n"); |
---|
623 | |
---|
624 | if (Start == End) |
---|
625 | break; |
---|
626 | Start++; |
---|
627 | } |
---|
628 | } |
---|
629 | return out.str(); |
---|
630 | } |
---|
631 | |
---|
632 | |
---|
633 | vector<DepInformation> RPackage::enumDeps(bool useCanidateVersion) |
---|
634 | { |
---|
635 | vector<DepInformation> deps; |
---|
636 | DepInformation dep; |
---|
637 | pkgCache::VerIterator Cur; |
---|
638 | |
---|
639 | if(!useCanidateVersion) |
---|
640 | Cur = (*_depcache)[*_package].InstVerIter(*_depcache); |
---|
641 | if(useCanidateVersion || Cur.end()) |
---|
642 | Cur = (*_depcache)[*_package].CandidateVerIter(*_depcache); |
---|
643 | |
---|
644 | // no information found |
---|
645 | if(Cur.end()) |
---|
646 | return deps; |
---|
647 | |
---|
648 | for(pkgCache::DepIterator D = Cur.DependsList(); D.end() != true; D++) { |
---|
649 | |
---|
650 | // clear old values |
---|
651 | dep.isOr=dep.isVirtual=dep.isSatisfied=false; |
---|
652 | dep.name=dep.version=dep.versionComp=NULL; |
---|
653 | |
---|
654 | // check target and or-depends status |
---|
655 | pkgCache::PkgIterator Trg = D.TargetPkg(); |
---|
656 | if ((D->CompareOp & pkgCache::Dep::Or) == pkgCache::Dep::Or) |
---|
657 | dep.isOr=true; |
---|
658 | |
---|
659 | // common information |
---|
660 | dep.type = (pkgCache::Dep::DepType)D->Type; |
---|
661 | dep.name = Trg.Name(); |
---|
662 | |
---|
663 | // satisfied |
---|
664 | if (((*_depcache)[D] & pkgDepCache::DepGInstall) == |
---|
665 | pkgDepCache::DepGInstall) |
---|
666 | dep.isSatisfied = true; |
---|
667 | if (Trg->VersionList == 0) { |
---|
668 | dep.isVirtual = true; |
---|
669 | } else { |
---|
670 | dep.version=D.TargetVer(); |
---|
671 | dep.versionComp=D.CompType(); |
---|
672 | } |
---|
673 | deps.push_back(dep); |
---|
674 | } |
---|
675 | |
---|
676 | return deps; |
---|
677 | } |
---|
678 | |
---|
679 | bool RPackage::dependsOn(const char *pkgname) |
---|
680 | { |
---|
681 | vector<DepInformation> deps = enumDeps(); |
---|
682 | for(unsigned int i=0;i<deps.size();i++) |
---|
683 | if(strcmp(pkgname, deps[i].name) == 0) |
---|
684 | return true; |
---|
685 | return false; |
---|
686 | } |
---|
687 | |
---|
688 | #ifdef WITH_APT_AUTH |
---|
689 | bool RPackage::isTrusted() |
---|
690 | { |
---|
691 | pkgCache::VerIterator Ver; |
---|
692 | pkgDepCache::StateCache & State = (*_depcache)[*_package]; |
---|
693 | Ver = State.CandidateVerIter(*_depcache); |
---|
694 | if (Ver == 0) { |
---|
695 | cerr << "CanidateVer == 0" << endl; |
---|
696 | return false; |
---|
697 | } |
---|
698 | pkgSourceList *Sources=_lister->getCache()->list(); |
---|
699 | for (pkgCache::VerFileIterator i = Ver.FileList(); i.end() == false; i++) |
---|
700 | { |
---|
701 | pkgIndexFile *Index; |
---|
702 | if (Sources->FindIndex(i.File(),Index) == false) |
---|
703 | continue; |
---|
704 | if (_config->FindB("Debug::pkgAcquire::Auth", false)) |
---|
705 | { |
---|
706 | std::cerr << "Checking index: " << Index->Describe() |
---|
707 | << "(Trusted=" << Index->IsTrusted() << ")\n"; |
---|
708 | } |
---|
709 | if (Index->IsTrusted()) |
---|
710 | return true; |
---|
711 | } |
---|
712 | |
---|
713 | return false; |
---|
714 | } |
---|
715 | #else |
---|
716 | // with apt-authentication we always trust that the package come from |
---|
717 | // a trusted source |
---|
718 | bool RPackage::isTrusted() |
---|
719 | { |
---|
720 | return true; |
---|
721 | }; |
---|
722 | #endif |
---|
723 | |
---|
724 | bool RPackage::wouldBreak() |
---|
725 | { |
---|
726 | int flags = getFlags(); |
---|
727 | if ((flags & FRemove) || (!(flags & FInstalled) && (flags & FKeep))) |
---|
728 | return false; |
---|
729 | return flags & FInstBroken; |
---|
730 | } |
---|
731 | |
---|
732 | void RPackage::setNotify(bool flag) |
---|
733 | { |
---|
734 | _notify = flag; |
---|
735 | } |
---|
736 | |
---|
737 | void RPackage::setKeep() |
---|
738 | { |
---|
739 | _depcache->MarkKeep(*_package, false); |
---|
740 | if (_notify) |
---|
741 | _lister->notifyChange(this); |
---|
742 | setReInstall(false); |
---|
743 | } |
---|
744 | |
---|
745 | |
---|
746 | void RPackage::setInstall() |
---|
747 | { |
---|
748 | _depcache->MarkInstall(*_package, true); |
---|
749 | pkgDepCache::StateCache & State = (*_depcache)[*_package]; |
---|
750 | |
---|
751 | // FIXME: can't we get rid of it here? |
---|
752 | // if there is something wrong, try to fix it |
---|
753 | if (!State.Install() || _depcache->BrokenCount() > 0) { |
---|
754 | pkgProblemResolver Fix(_depcache); |
---|
755 | Fix.Clear(*_package); |
---|
756 | Fix.Protect(*_package); |
---|
757 | Fix.Resolve(true); |
---|
758 | } |
---|
759 | |
---|
760 | |
---|
761 | #ifdef WITH_LUA |
---|
762 | _lua->SetDepCache(_depcache); |
---|
763 | _lua->SetGlobal("package", ((pkgCache::Package *) * _package)); |
---|
764 | _lua->RunScripts("Scripts::Synaptic::SetInstall", true); |
---|
765 | _lua->ResetGlobals(); |
---|
766 | _lua->ResetCaches(); |
---|
767 | #endif |
---|
768 | |
---|
769 | if (_notify) |
---|
770 | _lister->notifyChange(this); |
---|
771 | } |
---|
772 | |
---|
773 | void RPackage::setReInstall(bool flag) |
---|
774 | { |
---|
775 | _depcache->SetReInstall(*_package, flag); |
---|
776 | if (_notify) |
---|
777 | _lister->notifyChange(this); |
---|
778 | } |
---|
779 | |
---|
780 | |
---|
781 | void RPackage::setRemove(bool purge) |
---|
782 | { |
---|
783 | pkgProblemResolver Fix(_depcache); |
---|
784 | |
---|
785 | Fix.Clear(*_package); |
---|
786 | Fix.Protect(*_package); |
---|
787 | Fix.Remove(*_package); |
---|
788 | |
---|
789 | Fix.InstallProtect(); |
---|
790 | Fix.Resolve(true); |
---|
791 | |
---|
792 | _depcache->SetReInstall(*_package, false); |
---|
793 | _depcache->MarkDelete(*_package, purge); |
---|
794 | |
---|
795 | if (_notify) |
---|
796 | _lister->notifyChange(this); |
---|
797 | } |
---|
798 | |
---|
799 | |
---|
800 | string RPackage::getChangelogFile(pkgAcquire *fetcher) |
---|
801 | { |
---|
802 | string prefix; |
---|
803 | string srcpkg = srcPackage(); |
---|
804 | string descr("Changelog for "); |
---|
805 | descr+=name(); |
---|
806 | |
---|
807 | string src_section=section(); |
---|
808 | if(src_section.find('/')!=src_section.npos) |
---|
809 | src_section=string(src_section, 0, src_section.find('/')); |
---|
810 | else |
---|
811 | src_section="main"; |
---|
812 | |
---|
813 | prefix+=srcpkg[0]; |
---|
814 | if(srcpkg.size()>3 && srcpkg[0]=='l' && srcpkg[1]=='i' && srcpkg[2]=='b') |
---|
815 | prefix=std::string("lib")+srcpkg[3]; |
---|
816 | |
---|
817 | string verstr; |
---|
818 | if(availableVersion() != NULL) |
---|
819 | verstr = availableVersion(); |
---|
820 | |
---|
821 | if(verstr.find(':')!=verstr.npos) |
---|
822 | verstr=string(verstr, verstr.find(':')+1); |
---|
823 | char uri[512]; |
---|
824 | snprintf(uri,512,"http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog", |
---|
825 | src_section.c_str(), |
---|
826 | prefix.c_str(), |
---|
827 | srcpkg.c_str(), |
---|
828 | srcpkg.c_str(), |
---|
829 | verstr.c_str()); |
---|
830 | |
---|
831 | //cout << "uri is: " << uri << endl; |
---|
832 | |
---|
833 | // no need to translate this, the changelog is in english anyway |
---|
834 | string filename = RTmpDir()+"/tmp_cl"; |
---|
835 | ofstream out(filename.c_str()); |
---|
836 | out << "Failed to fetch the changelog for " << name() << endl; |
---|
837 | out << "URI was: " << uri << endl; |
---|
838 | out.close(); |
---|
839 | new pkgAcqFileSane(fetcher, uri, descr, name(), filename); |
---|
840 | |
---|
841 | fetcher->Run(); |
---|
842 | |
---|
843 | return filename; |
---|
844 | } |
---|
845 | |
---|
846 | string RPackage::getCanidateOrigin() |
---|
847 | { |
---|
848 | for(pkgCache::VerIterator Ver = _package->VersionList(); Ver.end() == false; Ver++) { |
---|
849 | // we always take the first available version |
---|
850 | pkgCache::VerFileIterator VF = Ver.FileList(); |
---|
851 | if(!VF.end()) { |
---|
852 | return VF.File().Site(); |
---|
853 | } |
---|
854 | } |
---|
855 | return ""; |
---|
856 | } |
---|
857 | |
---|
858 | |
---|
859 | void RPackage::setPinned(bool flag) |
---|
860 | { |
---|
861 | struct stat stat_buf; |
---|
862 | |
---|
863 | string File =RStateDir() + "/preferences"; |
---|
864 | |
---|
865 | _boolFlags = flag ? (_boolFlags | FPinned) : (_boolFlags & FPinned); |
---|
866 | |
---|
867 | if (flag) { |
---|
868 | // pkg already in pin-file |
---|
869 | if (_roptions->getPackageLock(name())) |
---|
870 | return; |
---|
871 | |
---|
872 | // write to pin-file |
---|
873 | ofstream out(File.c_str(), ios::app); |
---|
874 | out << "Package: " << name() << endl; |
---|
875 | // if the package is not installed, we pin it to the available version |
---|
876 | // and prevent installation of this package this way |
---|
877 | if(installedVersion() != NULL) |
---|
878 | out << "Pin: version " << installedVersion() << endl; |
---|
879 | else |
---|
880 | out << "Pin: version " << " 0.0 " << endl; |
---|
881 | out << "Pin-Priority: " |
---|
882 | << _config->FindI("Synaptic::DefaultPinPriority", 1001) |
---|
883 | << endl << endl; |
---|
884 | } else { |
---|
885 | // delete package from pinning file |
---|
886 | stat(File.c_str(), &stat_buf); |
---|
887 | // create a tmp_pin file in the internal dir |
---|
888 | string filename = RTmpDir()+"/tmp_pin"; |
---|
889 | FILE *out = fopen(filename.c_str(),"w"); |
---|
890 | if (out == NULL) |
---|
891 | cerr << "error opening tmpfile: " << filename << endl; |
---|
892 | FileFd Fd(File, FileFd::ReadOnly); |
---|
893 | pkgTagFile TF(&Fd); |
---|
894 | if (_error->PendingError() == true) |
---|
895 | return; |
---|
896 | pkgTagSection Tags; |
---|
897 | while (TF.Step(Tags) == true) { |
---|
898 | string Name = Tags.FindS("Package"); |
---|
899 | if (Name.empty() == true) { |
---|
900 | _error-> |
---|
901 | Error(_ |
---|
902 | ("Invalid record in the preferences file, no Package header")); |
---|
903 | return; |
---|
904 | } |
---|
905 | if (Name != name()) { |
---|
906 | TFRewriteData tfrd; |
---|
907 | tfrd.Tag = 0; |
---|
908 | tfrd.Rewrite = 0; |
---|
909 | tfrd.NewTag = 0; |
---|
910 | TFRewrite(out, Tags, TFRewritePackageOrder, &tfrd); |
---|
911 | fprintf(out, "\n"); |
---|
912 | } |
---|
913 | } |
---|
914 | fflush(out); |
---|
915 | rename(filename.c_str(), File.c_str()); |
---|
916 | chmod(File.c_str(), stat_buf.st_mode); |
---|
917 | fclose(out); |
---|
918 | } |
---|
919 | } |
---|
920 | |
---|
921 | |
---|
922 | // FIXME: this function is broken right now (and it never really wasn't :/ |
---|
923 | bool RPackage::isShallowDependency(RPackage *pkg) |
---|
924 | { |
---|
925 | #if 0 |
---|
926 | pkgCache::DepIterator rdepI; |
---|
927 | |
---|
928 | // check whether someone else depends on a virtual pkg of this |
---|
929 | for (int i = -1; i < (int)pkg->_virtualPackages.size(); i++) { |
---|
930 | if (i < 0) { |
---|
931 | rdepI = pkg->_package->RevDependsList(); |
---|
932 | } else { |
---|
933 | pkgCache::PkgIterator it = pkg->_virtualPackages[i]; |
---|
934 | rdepI = it.RevDependsList(); |
---|
935 | } |
---|
936 | |
---|
937 | while (!rdepI.end()) { |
---|
938 | |
---|
939 | // check whether the dependant is installed |
---|
940 | if (rdepI.ParentPkg().CurrentVer().end()) { // not installed |
---|
941 | // XXX check whether its marked for install |
---|
942 | rdepI++; |
---|
943 | continue; |
---|
944 | } |
---|
945 | // check whether the dependant isn't the own package |
---|
946 | if (rdepI.ParentPkg() == *_package) { |
---|
947 | rdepI++; |
---|
948 | continue; |
---|
949 | } |
---|
950 | // XXX should check for dependencies that depend on |
---|
951 | // dependencies of the same package |
---|
952 | |
---|
953 | return false; |
---|
954 | } |
---|
955 | } |
---|
956 | |
---|
957 | #endif |
---|
958 | return true; |
---|
959 | } |
---|
960 | |
---|
961 | // format: first version, second archives |
---|
962 | vector<pair<string, string> > RPackage::getAvailableVersions() |
---|
963 | { |
---|
964 | string VerTag; |
---|
965 | vector<pair<string, string> > versions; |
---|
966 | |
---|
967 | // Get available Versions. |
---|
968 | for (pkgCache::VerIterator Ver = _package->VersionList(); |
---|
969 | Ver.end() == false; Ver++) { |
---|
970 | |
---|
971 | // We always take the first available version. |
---|
972 | pkgCache::VerFileIterator VF = Ver.FileList(); |
---|
973 | if (!VF.end()) { |
---|
974 | pkgCache::PkgFileIterator File = VF.File(); |
---|
975 | |
---|
976 | if (File->Archive != 0) |
---|
977 | versions.push_back(pair < string, |
---|
978 | string > (Ver.VerStr(), File.Archive())); |
---|
979 | else |
---|
980 | versions.push_back(pair < string, |
---|
981 | string > (Ver.VerStr(), File.Site())); |
---|
982 | } |
---|
983 | } |
---|
984 | |
---|
985 | return versions; |
---|
986 | } |
---|
987 | |
---|
988 | |
---|
989 | bool RPackage::setVersion(string verTag) |
---|
990 | { |
---|
991 | pkgVersionMatch Match(verTag, pkgVersionMatch::Version); |
---|
992 | pkgCache::VerIterator Ver = Match.Find(*_package); |
---|
993 | |
---|
994 | if (Ver.end() == true) |
---|
995 | return false; |
---|
996 | |
---|
997 | _depcache->SetCandidateVersion(Ver); |
---|
998 | |
---|
999 | _boolFlags |= FOverrideVersion; |
---|
1000 | |
---|
1001 | return true; |
---|
1002 | } |
---|
1003 | |
---|
1004 | void RPackage::unsetVersion() |
---|
1005 | { |
---|
1006 | //cout << "set version to " << _defaultCandVer << endl; |
---|
1007 | setVersion(_defaultCandVer); |
---|
1008 | _boolFlags &= ~FOverrideVersion; |
---|
1009 | } |
---|
1010 | |
---|
1011 | vector<string> RPackage::provides() |
---|
1012 | { |
---|
1013 | vector<string> provides; |
---|
1014 | |
---|
1015 | pkgDepCache::StateCache & State = (*_depcache)[*_package]; |
---|
1016 | if (State.CandidateVer == 0) |
---|
1017 | return provides; |
---|
1018 | |
---|
1019 | for (pkgCache::PrvIterator Prv = |
---|
1020 | State.CandidateVerIter(*_depcache).ProvidesList(); Prv.end() != true; |
---|
1021 | Prv++) { |
---|
1022 | provides.push_back(Prv.Name()); |
---|
1023 | } |
---|
1024 | |
---|
1025 | return provides; |
---|
1026 | } |
---|
1027 | |
---|
1028 | /* mvo: actually shallow = false does not make a lot of sense as it |
---|
1029 | * will remove packages very brutally (like removing libc6) |
---|
1030 | */ |
---|
1031 | void RPackage::setRemoveWithDeps(bool shallow, bool purge) |
---|
1032 | { |
---|
1033 | setRemove(); |
---|
1034 | |
---|
1035 | // remove packages that this one depends on, including this |
---|
1036 | pkgCache::DepIterator deps = _package->VersionList().DependsList(); |
---|
1037 | pkgCache::DepIterator start, end; |
---|
1038 | |
---|
1039 | deps.GlobOr(start, end); |
---|
1040 | |
---|
1041 | while (1) { |
---|
1042 | if (start == end) { |
---|
1043 | deps++; |
---|
1044 | if (deps.end()) |
---|
1045 | break; |
---|
1046 | deps.GlobOr(start, end); |
---|
1047 | } else { |
---|
1048 | start++; |
---|
1049 | } |
---|
1050 | |
---|
1051 | if (!_depcache->IsImportantDep(start)) |
---|
1052 | continue; |
---|
1053 | |
---|
1054 | |
---|
1055 | pkgCache::PkgIterator depPkg = start.TargetPkg(); |
---|
1056 | |
---|
1057 | // get the real package, in case this is a virtual pkg |
---|
1058 | // mvo: does this actually work :) ? |
---|
1059 | if (depPkg->VersionList == 0) { |
---|
1060 | if (depPkg->ProvidesList != 0) { |
---|
1061 | depPkg = depPkg.ProvidesList().OwnerPkg(); |
---|
1062 | } else { |
---|
1063 | continue; |
---|
1064 | } |
---|
1065 | } |
---|
1066 | |
---|
1067 | RPackage *depackage = _lister->getPackage(depPkg); |
---|
1068 | //cout << "testing(RPackage): " << depackage->name() << endl; |
---|
1069 | |
---|
1070 | if (!depackage) |
---|
1071 | continue; |
---|
1072 | |
---|
1073 | // skip important packages |
---|
1074 | if (depackage->getFlags() & FImportant) |
---|
1075 | continue; |
---|
1076 | |
---|
1077 | // skip dependencies that are dependants of other packages |
---|
1078 | // if shallow=true |
---|
1079 | if (shallow && !isShallowDependency(depackage)) { |
---|
1080 | continue; |
---|
1081 | } |
---|
1082 | // set this package for removal |
---|
1083 | depackage->setRemove(purge); |
---|
1084 | } |
---|
1085 | } |
---|
1086 | |
---|
1087 | |
---|
1088 | // description parser stuff |
---|
1089 | static char *debParser(string descr) |
---|
1090 | { |
---|
1091 | unsigned int i; |
---|
1092 | string::size_type nlpos=0; |
---|
1093 | |
---|
1094 | nlpos = descr.find('\n'); |
---|
1095 | // delete first line |
---|
1096 | if (nlpos != string::npos) |
---|
1097 | descr.erase(0, nlpos + 2); // del "\n " too |
---|
1098 | |
---|
1099 | while (nlpos < descr.length()) { |
---|
1100 | nlpos = descr.find('\n', nlpos); |
---|
1101 | if (nlpos == string::npos) |
---|
1102 | break; |
---|
1103 | |
---|
1104 | i = nlpos; |
---|
1105 | // del char after '\n' (always " ") |
---|
1106 | i++; |
---|
1107 | descr.erase(i, 1); |
---|
1108 | |
---|
1109 | // delete lines likes this: " .", makeing it a \n |
---|
1110 | if (descr[i] == '.') { |
---|
1111 | descr.erase(i, 1); |
---|
1112 | nlpos++; |
---|
1113 | continue; |
---|
1114 | } |
---|
1115 | // skip ws |
---|
1116 | while (descr[++i] == ' '); |
---|
1117 | |
---|
1118 | // // not a list, erase nl |
---|
1119 | // if(!(descr[i] == '*' || descr[i] == '-' || descr[i] == 'o')) |
---|
1120 | // descr.erase(nlpos,1); |
---|
1121 | |
---|
1122 | nlpos++; |
---|
1123 | } |
---|
1124 | strcpy(descrBuffer, descr.c_str()); |
---|
1125 | return descrBuffer; |
---|
1126 | } |
---|
1127 | static char *rpmParser(string descr) |
---|
1128 | { |
---|
1129 | string::size_type pos = descr.find('\n'); |
---|
1130 | // delete first line |
---|
1131 | if (pos != string::npos) |
---|
1132 | descr.erase(0, pos + 2); // del "\n " too |
---|
1133 | |
---|
1134 | strcpy(descrBuffer, descr.c_str()); |
---|
1135 | return descrBuffer; |
---|
1136 | } |
---|
1137 | |
---|
1138 | static char *stripWsParser(string descr) |
---|
1139 | { |
---|
1140 | const char *end; |
---|
1141 | const char *p; |
---|
1142 | |
---|
1143 | p = descr.c_str(); |
---|
1144 | end = p + descr.size(); // mvo: hackish, but works |
---|
1145 | |
---|
1146 | |
---|
1147 | int state = 0; |
---|
1148 | char *pp = (char *)descrBuffer; |
---|
1149 | |
---|
1150 | while (p != end) { |
---|
1151 | switch (state) { |
---|
1152 | case 0: |
---|
1153 | if (*p == '\n') |
---|
1154 | state = 1; |
---|
1155 | else |
---|
1156 | *pp++ = *p; |
---|
1157 | break; |
---|
1158 | |
---|
1159 | case 1: |
---|
1160 | if (*p == ' ') |
---|
1161 | state = 2; |
---|
1162 | else { |
---|
1163 | *pp++ = *p; |
---|
1164 | state = 0; |
---|
1165 | } |
---|
1166 | break; |
---|
1167 | |
---|
1168 | case 2: |
---|
1169 | if (!(*p == '\n' || *p == '.')) { |
---|
1170 | *pp++ = ' '; |
---|
1171 | *pp++ = *p; |
---|
1172 | } |
---|
1173 | state = 0; |
---|
1174 | break; |
---|
1175 | } |
---|
1176 | p++; |
---|
1177 | } |
---|
1178 | *pp = '\0'; |
---|
1179 | |
---|
1180 | return descrBuffer; |
---|
1181 | } |
---|
1182 | |
---|
1183 | |
---|
1184 | static char *parseDescription(string descr) |
---|
1185 | { |
---|
1186 | |
---|
1187 | if (descr.size() > sizeof(descrBuffer)) |
---|
1188 | return "Description Too Long"; |
---|
1189 | |
---|
1190 | #ifdef HAVE_RPM |
---|
1191 | int parser = _config->FindI("Synaptic::descriptionParser", NO_PARSER); |
---|
1192 | #else |
---|
1193 | int parser = _config->FindI("Synaptic::descriptionParser", DEB_PARSER); |
---|
1194 | #endif |
---|
1195 | switch (parser) { |
---|
1196 | case DEB_PARSER: |
---|
1197 | return debParser(descr); |
---|
1198 | case STRIP_WS_PARSER: |
---|
1199 | return stripWsParser(descr); |
---|
1200 | case RPM_PARSER: |
---|
1201 | return rpmParser(descr); |
---|
1202 | case NO_PARSER: |
---|
1203 | default: |
---|
1204 | strcpy(descrBuffer, descr.c_str()); |
---|
1205 | return descrBuffer; |
---|
1206 | } |
---|
1207 | } |
---|
1208 | |
---|
1209 | string RPackage::component() |
---|
1210 | { |
---|
1211 | string res; |
---|
1212 | #ifdef WITH_APT_AUTH |
---|
1213 | // the apt-secure patch breaks File.Component |
---|
1214 | const char *s = _package->Section(); |
---|
1215 | if(s == NULL) |
---|
1216 | return ""; |
---|
1217 | |
---|
1218 | string src_section(s); |
---|
1219 | if(src_section.find('/')!=src_section.npos) |
---|
1220 | src_section=string(src_section, 0, src_section.find('/')); |
---|
1221 | else |
---|
1222 | src_section="main"; |
---|
1223 | res = src_section; |
---|
1224 | #else |
---|
1225 | pkgCache::VerIterator Ver; |
---|
1226 | pkgDepCache::StateCache & State = (*_depcache)[*_package]; |
---|
1227 | if (State.CandidateVer == 0) { |
---|
1228 | //cout << "CanidateVer == 0" << endl; |
---|
1229 | return ""; |
---|
1230 | } |
---|
1231 | Ver = State.CandidateVerIter(*_depcache); |
---|
1232 | pkgCache::VerFileIterator VF = Ver.FileList(); |
---|
1233 | pkgCache::PkgFileIterator File = VF.File(); |
---|
1234 | |
---|
1235 | if(File.Component() == NULL) { |
---|
1236 | //cout << "File.Component() == NULL" << endl; |
---|
1237 | return ""; |
---|
1238 | } |
---|
1239 | |
---|
1240 | res = File.Component(); |
---|
1241 | #endif |
---|
1242 | return res; |
---|
1243 | } |
---|
1244 | |
---|
1245 | |
---|
1246 | |
---|
1247 | string RPackage::label() |
---|
1248 | { |
---|
1249 | string res; |
---|
1250 | pkgCache::VerIterator Ver; |
---|
1251 | pkgDepCache::StateCache & State = (*_depcache)[*_package]; |
---|
1252 | if (State.CandidateVer == 0) { |
---|
1253 | //cout << "CanidateVer == 0" << endl; |
---|
1254 | return ""; |
---|
1255 | } |
---|
1256 | Ver = State.CandidateVerIter(*_depcache); |
---|
1257 | pkgCache::VerFileIterator VF = Ver.FileList(); |
---|
1258 | pkgCache::PkgFileIterator File = VF.File(); |
---|
1259 | |
---|
1260 | if(File.Label() == NULL) { |
---|
1261 | //cout << "File.Component() == NULL" << endl; |
---|
1262 | return ""; |
---|
1263 | } |
---|
1264 | |
---|
1265 | res = File.Label(); |
---|
1266 | |
---|
1267 | return res; |
---|
1268 | } |
---|
1269 | |
---|
1270 | |
---|
1271 | // class that finds out what do display to get user |
---|
1272 | void RPackageStatus::init() |
---|
1273 | { |
---|
1274 | char *status_short[N_STATUS_COUNT] = { |
---|
1275 | "install", "reinstall", "upgrade", "downgrade", "remove", |
---|
1276 | "purge", "available", "available-locked", |
---|
1277 | "installed-updated", "installed-outdated", "installed-locked", |
---|
1278 | "broken", "new" |
---|
1279 | }; |
---|
1280 | memcpy(PackageStatusShortString, status_short, sizeof(status_short)); |
---|
1281 | |
---|
1282 | char *status_long[N_STATUS_COUNT] = { |
---|
1283 | _("Marked for installation"), |
---|
1284 | _("Marked for re-installation"), |
---|
1285 | _("Marked for upgrade"), |
---|
1286 | _("Marked for downgrade"), |
---|
1287 | _("Marked for removal"), |
---|
1288 | _("Marked for complete removal"), |
---|
1289 | _("Not installed"), |
---|
1290 | _("Not installed (locked)"), |
---|
1291 | _("Installed"), |
---|
1292 | _("Installed (upgradable)"), |
---|
1293 | _("Installed (locked to the current version)"), |
---|
1294 | _("Broken"), |
---|
1295 | _("Not installed (new in repository)") |
---|
1296 | }; |
---|
1297 | memcpy(PackageStatusLongString, status_long, sizeof(status_long)); |
---|
1298 | |
---|
1299 | |
---|
1300 | // check for unsupported stuff |
---|
1301 | if(_config->FindB("Synaptic::mark-unsupported",true)) { |
---|
1302 | string s, labels, components; |
---|
1303 | markUnsupported = true; |
---|
1304 | |
---|
1305 | // read supported labels |
---|
1306 | labels = _config->Find("Synaptic::supported-label", "Debian Debian-Security"); |
---|
1307 | stringstream sst1(labels); |
---|
1308 | while(!sst1.eof()) { |
---|
1309 | sst1 >> s; |
---|
1310 | supportedLabels.push_back(s); |
---|
1311 | } |
---|
1312 | |
---|
1313 | // read supported components |
---|
1314 | components = _config->Find("Synaptic::supported-components", "main updates/main"); |
---|
1315 | stringstream sst2(components); |
---|
1316 | while(!sst2.eof()) { |
---|
1317 | sst2 >> s; |
---|
1318 | supportedComponents.push_back(s); |
---|
1319 | } |
---|
1320 | } |
---|
1321 | |
---|
1322 | } |
---|
1323 | |
---|
1324 | bool RPackageStatus::isSupported(RPackage *pkg) |
---|
1325 | { |
---|
1326 | bool res = true; |
---|
1327 | |
---|
1328 | if(markUnsupported) { |
---|
1329 | bool sc, sl; |
---|
1330 | |
---|
1331 | sc=sl=false; |
---|
1332 | |
---|
1333 | string component = pkg->component(); |
---|
1334 | string label = pkg->label(); |
---|
1335 | |
---|
1336 | for(unsigned int i=0;i<supportedComponents.size();i++) { |
---|
1337 | if(supportedComponents[i] == component) { |
---|
1338 | sc = true; |
---|
1339 | break; |
---|
1340 | } |
---|
1341 | } |
---|
1342 | for(unsigned int i=0;i<supportedLabels.size();i++) { |
---|
1343 | if(supportedLabels[i] == label) { |
---|
1344 | sl = true; |
---|
1345 | break; |
---|
1346 | } |
---|
1347 | } |
---|
1348 | res = (sc & sl); |
---|
1349 | } |
---|
1350 | |
---|
1351 | return res; |
---|
1352 | } |
---|
1353 | |
---|
1354 | int RPackageStatus::getStatus(RPackage *pkg) |
---|
1355 | { |
---|
1356 | int flags = pkg->getFlags(); |
---|
1357 | int ret = NotInstalled; |
---|
1358 | |
---|
1359 | if (pkg->wouldBreak()) { |
---|
1360 | ret = IsBroken; |
---|
1361 | } else if (flags & RPackage::FNewInstall) { |
---|
1362 | ret = ToInstall; |
---|
1363 | } else if (flags & RPackage::FUpgrade) { |
---|
1364 | ret = ToUpgrade; |
---|
1365 | } else if (flags & RPackage::FReInstall) { |
---|
1366 | ret = ToReInstall; |
---|
1367 | } else if (flags & RPackage::FDowngrade) { |
---|
1368 | ret = ToDowngrade; |
---|
1369 | } else if (flags & RPackage::FPurge) { |
---|
1370 | ret = ToPurge; |
---|
1371 | } else if (flags & RPackage::FRemove) { |
---|
1372 | ret = ToRemove; |
---|
1373 | } else if (flags & RPackage::FInstalled) { |
---|
1374 | if (flags & RPackage::FPinned) |
---|
1375 | ret = InstalledLocked; |
---|
1376 | else if (flags & RPackage::FOutdated) |
---|
1377 | ret = InstalledOutdated; |
---|
1378 | else |
---|
1379 | ret = InstalledUpdated; |
---|
1380 | } else { |
---|
1381 | if (flags & RPackage::FPinned) |
---|
1382 | ret = NotInstalledLocked; |
---|
1383 | else if (flags & RPackage::FNew) |
---|
1384 | ret = IsNew; |
---|
1385 | else |
---|
1386 | ret = NotInstalled; |
---|
1387 | } |
---|
1388 | |
---|
1389 | return ret; |
---|
1390 | } |
---|
1391 | |
---|
1392 | |
---|
1393 | // vim:ts=3:sw=3:et |
---|