]>
git.saurik.com Git - apt.git/blob - cmdline/apt-mark.cc
1 // -*- mode: cpp; mode: fold -*-
3 /* #####################################################################
4 apt-mark - show and change auto-installed bit information
5 ##################################################################### */
7 // Include Files /*{{{*/
8 #include <apt-pkg/cachefile.h>
9 #include <apt-pkg/cacheset.h>
10 #include <apt-pkg/cmndline.h>
11 #include <apt-pkg/error.h>
12 #include <apt-pkg/init.h>
13 #include <apt-pkg/strutl.h>
25 ofstream
devnull("/dev/null");
26 /* DoAuto - mark packages as automatically/manually installed {{{*/
27 bool DoAuto(CommandLine
&CmdL
)
29 pkgCacheFile CacheFile
;
30 pkgCache
*Cache
= CacheFile
.GetPkgCache();
31 pkgDepCache
*DepCache
= CacheFile
.GetDepCache();
32 if (unlikely(Cache
== NULL
|| DepCache
== NULL
))
35 APT::PackageSet pkgset
= APT::PackageSet::FromCommandLine(CacheFile
, CmdL
.FileList
+ 1);
36 if (pkgset
.empty() == true)
37 return _error
->Error(_("No packages found"));
39 bool MarkAuto
= strcasecmp(CmdL
.FileList
[0],"auto") == 0;
40 int AutoMarkChanged
= 0;
42 for (APT::PackageSet::const_iterator Pkg
= pkgset
.begin(); Pkg
!= pkgset
.end(); ++Pkg
)
44 if (Pkg
->CurrentVer
== 0)
46 ioprintf(c1out
,_("%s can not be marked as it is not installed.\n"), Pkg
.FullName(true).c_str());
49 else if ((((*DepCache
)[Pkg
].Flags
& pkgCache::Flag::Auto
) == pkgCache::Flag::Auto
) == MarkAuto
)
51 if (MarkAuto
== false)
52 ioprintf(c1out
,_("%s was already set to manually installed.\n"), Pkg
.FullName(true).c_str());
54 ioprintf(c1out
,_("%s was already set to automatically installed.\n"), Pkg
.FullName(true).c_str());
58 if (MarkAuto
== false)
59 ioprintf(c1out
,_("%s set to manually installed.\n"), Pkg
.FullName(true).c_str());
61 ioprintf(c1out
,_("%s set to automatically installed.\n"), Pkg
.FullName(true).c_str());
63 DepCache
->MarkAuto(Pkg
, MarkAuto
);
66 if (AutoMarkChanged
> 0 && _config
->FindB("APT::Mark::Simulate", false) == false)
67 return DepCache
->writeStateFile(NULL
);
71 /* DoMarkAuto - mark packages as automatically/manually installed {{{*/
72 /* Does the same as DoAuto but tries to do it exactly the same why as
73 the python implementation did it so it can be a drop-in replacement */
74 bool DoMarkAuto(CommandLine
&CmdL
)
76 pkgCacheFile CacheFile
;
77 pkgCache
*Cache
= CacheFile
.GetPkgCache();
78 pkgDepCache
*DepCache
= CacheFile
.GetDepCache();
79 if (unlikely(Cache
== NULL
|| DepCache
== NULL
))
82 APT::PackageSet pkgset
= APT::PackageSet::FromCommandLine(CacheFile
, CmdL
.FileList
+ 1);
83 if (pkgset
.empty() == true)
84 return _error
->Error(_("No packages found"));
86 bool const MarkAuto
= strcasecmp(CmdL
.FileList
[0],"markauto") == 0;
87 bool const Verbose
= _config
->FindB("APT::MarkAuto::Verbose", false);
88 int AutoMarkChanged
= 0;
90 for (APT::PackageSet::const_iterator Pkg
= pkgset
.begin(); Pkg
!= pkgset
.end(); ++Pkg
)
92 if (Pkg
->CurrentVer
== 0 ||
93 (((*DepCache
)[Pkg
].Flags
& pkgCache::Flag::Auto
) == pkgCache::Flag::Auto
) == MarkAuto
)
97 ioprintf(c1out
, "changing %s to %d\n", Pkg
.Name(), (MarkAuto
== false) ? 0 : 1);
99 DepCache
->MarkAuto(Pkg
, MarkAuto
);
102 if (AutoMarkChanged
> 0 && _config
->FindB("APT::Mark::Simulate", false) == false)
103 return DepCache
->writeStateFile(NULL
);
105 _error
->Notice(_("This command is deprecated. Please use 'apt-mark auto' and 'apt-mark manual' instead."));
110 /* ShowAuto - show automatically installed packages (sorted) {{{*/
111 bool ShowAuto(CommandLine
&CmdL
)
113 pkgCacheFile CacheFile
;
114 pkgCache
*Cache
= CacheFile
.GetPkgCache();
115 pkgDepCache
*DepCache
= CacheFile
.GetDepCache();
116 if (unlikely(Cache
== NULL
|| DepCache
== NULL
))
119 std::vector
<string
> packages
;
121 bool const ShowAuto
= strcasecmp(CmdL
.FileList
[0],"showauto") == 0;
123 if (CmdL
.FileList
[1] == 0)
125 packages
.reserve(Cache
->HeaderP
->PackageCount
/ 3);
126 for (pkgCache::PkgIterator P
= Cache
->PkgBegin(); P
.end() == false; ++P
)
127 if (P
->CurrentVer
!= 0 &&
128 (((*DepCache
)[P
].Flags
& pkgCache::Flag::Auto
) == pkgCache::Flag::Auto
) == ShowAuto
)
129 packages
.push_back(P
.FullName(true));
133 APT::CacheSetHelper
helper(false); // do not show errors
134 APT::PackageSet pkgset
= APT::PackageSet::FromCommandLine(CacheFile
, CmdL
.FileList
+ 1, helper
);
135 packages
.reserve(pkgset
.size());
136 for (APT::PackageSet::const_iterator P
= pkgset
.begin(); P
!= pkgset
.end(); ++P
)
137 if (P
->CurrentVer
!= 0 &&
138 (((*DepCache
)[P
].Flags
& pkgCache::Flag::Auto
) == pkgCache::Flag::Auto
) == ShowAuto
)
139 packages
.push_back(P
.FullName(true));
142 std::sort(packages
.begin(), packages
.end());
144 for (vector
<string
>::const_iterator I
= packages
.begin(); I
!= packages
.end(); ++I
)
145 std::cout
<< *I
<< std::endl
;
150 /* DoHold - mark packages as hold by dpkg {{{*/
151 bool DoHold(CommandLine
&CmdL
)
153 pkgCacheFile CacheFile
;
154 pkgCache
*Cache
= CacheFile
.GetPkgCache();
155 if (unlikely(Cache
== NULL
))
158 APT::PackageSet pkgset
= APT::PackageSet::FromCommandLine(CacheFile
, CmdL
.FileList
+ 1);
159 if (pkgset
.empty() == true)
160 return _error
->Error(_("No packages found"));
162 bool const MarkHold
= strcasecmp(CmdL
.FileList
[0],"hold") == 0;
164 for (APT::PackageSet::iterator Pkg
= pkgset
.begin(); Pkg
!= pkgset
.end(); ++Pkg
)
166 if ((Pkg
->SelectedState
== pkgCache::State::Hold
) == MarkHold
)
168 if (MarkHold
== true)
169 ioprintf(c1out
,_("%s was already set on hold.\n"), Pkg
.FullName(true).c_str());
171 ioprintf(c1out
,_("%s was already not hold.\n"), Pkg
.FullName(true).c_str());
177 if (pkgset
.empty() == true)
180 if (_config
->FindB("APT::Mark::Simulate", false) == true)
182 for (APT::PackageSet::iterator Pkg
= pkgset
.begin(); Pkg
!= pkgset
.end(); ++Pkg
)
184 if (MarkHold
== false)
185 ioprintf(c1out
,_("%s set on hold.\n"), Pkg
.FullName(true).c_str());
187 ioprintf(c1out
,_("Canceled hold on %s.\n"), Pkg
.FullName(true).c_str());
192 string dpkgcall
= _config
->Find("Dir::Bin::dpkg", "dpkg");
193 std::vector
<string
> const dpkgoptions
= _config
->FindVector("DPkg::options");
194 for (std::vector
<string
>::const_iterator o
= dpkgoptions
.begin();
195 o
!= dpkgoptions
.end(); ++o
)
196 dpkgcall
.append(" ").append(*o
);
197 dpkgcall
.append(" --set-selections");
198 FILE *dpkg
= popen(dpkgcall
.c_str(), "w");
200 return _error
->Errno("DoHold", "fdopen on dpkg stdin failed");
202 for (APT::PackageSet::iterator Pkg
= pkgset
.begin(); Pkg
!= pkgset
.end(); ++Pkg
)
204 if (MarkHold
== true)
206 fprintf(dpkg
, "%s hold\n", Pkg
.FullName(true).c_str());
207 ioprintf(c1out
,_("%s set on hold.\n"), Pkg
.FullName(true).c_str());
211 fprintf(dpkg
, "%s install\n", Pkg
.FullName(true).c_str());
212 ioprintf(c1out
,_("Canceled hold on %s.\n"), Pkg
.FullName(true).c_str());
216 int const status
= pclose(dpkg
);
218 return _error
->Errno("DoHold", "dpkg execution failed in the end");
219 if (WIFEXITED(status
) == false || WEXITSTATUS(status
) != 0)
220 return _error
->Error(_("Executing dpkg failed. Are you root?"));
224 /* ShowHold - show packages set on hold in dpkg status {{{*/
225 bool ShowHold(CommandLine
&CmdL
)
227 pkgCacheFile CacheFile
;
228 pkgCache
*Cache
= CacheFile
.GetPkgCache();
229 if (unlikely(Cache
== NULL
))
232 std::vector
<string
> packages
;
234 if (CmdL
.FileList
[1] == 0)
236 packages
.reserve(50); // how many holds are realistic? I hope just a few…
237 for (pkgCache::PkgIterator P
= Cache
->PkgBegin(); P
.end() == false; ++P
)
238 if (P
->SelectedState
== pkgCache::State::Hold
)
239 packages
.push_back(P
.FullName(true));
243 APT::CacheSetHelper
helper(false); // do not show errors
244 APT::PackageSet pkgset
= APT::PackageSet::FromCommandLine(CacheFile
, CmdL
.FileList
+ 1, helper
);
245 packages
.reserve(pkgset
.size());
246 for (APT::PackageSet::const_iterator P
= pkgset
.begin(); P
!= pkgset
.end(); ++P
)
247 if (P
->SelectedState
== pkgCache::State::Hold
)
248 packages
.push_back(P
.FullName(true));
251 std::sort(packages
.begin(), packages
.end());
253 for (vector
<string
>::const_iterator I
= packages
.begin(); I
!= packages
.end(); ++I
)
254 std::cout
<< *I
<< std::endl
;
259 // ShowHelp - Show a help screen /*{{{*/
260 // ---------------------------------------------------------------------
262 bool ShowHelp(CommandLine
&CmdL
)
264 ioprintf(cout
,_("%s %s for %s compiled on %s %s\n"),PACKAGE
,VERSION
,
265 COMMON_ARCH
,__DATE__
,__TIME__
);
268 _("Usage: apt-mark [options] {auto|manual} pkg1 [pkg2 ...]\n"
270 "apt-mark is a simple command line interface for marking packages\n"
271 "as manual or automatical installed. It can also list marks.\n"
274 " auto - Mark the given packages as automatically installed\n"
275 " manual - Mark the given packages as manually installed\n"
278 " -h This help text.\n"
279 " -q Loggable output - no progress indicator\n"
280 " -qq No output except for errors\n"
281 " -s No-act. Just prints what would be done.\n"
282 " -f read/write auto/manual marking in the given file\n"
283 " -c=? Read this configuration file\n"
284 " -o=? Set an arbitrary configuration option, eg -o dir::cache=/tmp\n"
285 "See the apt-mark(8) and apt.conf(5) manual pages for more information.")
290 int main(int argc
,const char *argv
[]) /*{{{*/
292 CommandLine::Args Args
[] = {
293 {'h',"help","help",0},
294 {0,"version","version",0},
295 {'q',"quiet","quiet",CommandLine::IntLevel
},
296 {'q',"silent","quiet",CommandLine::IntLevel
},
297 {'v',"verbose","APT::MarkAuto::Verbose",0},
298 {'s',"simulate","APT::Mark::Simulate",0},
299 {'s',"just-print","APT::Mark::Simulate",0},
300 {'s',"recon","APT::Mark::Simulate",0},
301 {'s',"dry-run","APT::Mark::Simulate",0},
302 {'s',"no-act","APT::Mark::Simulate",0},
303 {'f',"file","Dir::State::extended_states",CommandLine::HasArg
},
304 {'c',"config-file",0,CommandLine::ConfigFile
},
305 {'o',"option",0,CommandLine::ArbItem
},
307 CommandLine::Dispatch Cmds
[] = {{"help",&ShowHelp
},
312 {"showauto",&ShowAuto
},
313 {"showmanual",&ShowAuto
},
314 {"showhold",&ShowHold
},
315 // be nice and forgive the typo
316 {"showholds",&ShowHold
},
317 // be nice and forgive it as it is technical right
319 // obsolete commands for compatibility
320 {"markauto", &DoMarkAuto
},
321 {"unmarkauto", &DoMarkAuto
},
324 // Set up gettext support
325 setlocale(LC_ALL
,"");
328 // Parse the command line and initialize the package library
329 CommandLine
CmdL(Args
,_config
);
330 if (pkgInitConfig(*_config
) == false ||
331 CmdL
.Parse(argc
,argv
) == false ||
332 pkgInitSystem(*_config
,_system
) == false)
334 if (_config
->FindB("version") == true)
336 _error
->DumpErrors();
340 // See if the help should be shown
341 if (_config
->FindB("help") == true ||
342 _config
->FindB("version") == true ||
343 CmdL
.FileSize() == 0)
349 // Deal with stdout not being a tty
350 if (!isatty(STDOUT_FILENO
) && _config
->FindI("quiet", -1) == -1)
351 _config
->Set("quiet","1");
353 // Setup the output streams
354 c0out
.rdbuf(cout
.rdbuf());
355 c1out
.rdbuf(cout
.rdbuf());
356 c2out
.rdbuf(cout
.rdbuf());
357 if (_config
->FindI("quiet",0) > 0)
358 c0out
.rdbuf(devnull
.rdbuf());
359 if (_config
->FindI("quiet",0) > 1)
360 c1out
.rdbuf(devnull
.rdbuf());
362 // Match the operation
363 CmdL
.DispatchArg(Cmds
);
365 // Print any errors or warnings found during parsing
366 bool const Errors
= _error
->PendingError();
367 if (_config
->FindI("quiet",0) > 0)
368 _error
->DumpErrors();
370 _error
->DumpErrors(GlobalError::DEBUG
);
371 return Errors
== true ? 100 : 0;