Browse Source

apt-cdrom

Author: jgg
Date: 1998-11-27 01:52:53 GMT
apt-cdrom
debian/1.8.y
Arch Librarian 18 years ago
parent
commit
83d89a9f6a
  1. 30
      cmdline/apt-cache.cc
  2. 706
      cmdline/apt-cdrom.cc
  3. 29
      cmdline/apt-config.cc
  4. 85
      cmdline/apt-get.cc
  5. 6
      cmdline/makefile

30
cmdline/apt-cache.cc

@ -1,6 +1,6 @@
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
// $Id: apt-cache.cc,v 1.12 1998/11/14 07:20:29 jgg Exp $
// $Id: apt-cache.cc,v 1.13 1998/11/27 01:52:53 jgg Exp $
/* ######################################################################
apt-cache - Manages the cache files
@ -219,6 +219,27 @@ bool Stats(pkgCache &Cache)
return true;
}
/*}}}*/
// Check - Check some things about the cache /*{{{*/
// ---------------------------------------------------------------------
/* Debug aide mostly */
bool Check(pkgCache &Cache)
{
pkgCache::PkgIterator Pkg = Cache.PkgBegin();
for (;Pkg.end() != true; Pkg++)
{
if (Pkg.Section() == 0 && Pkg->VersionList != 0)
cout << "Bad section " << Pkg.Name() << endl;
for (pkgCache::VerIterator Cur = Pkg.VersionList();
Cur.end() != true; Cur++)
{
if (Cur->Priority < 1 || Cur->Priority > 5)
cout << "Bad prio " << Pkg.Name() << ',' << Cur.VerStr() << " == " << (int)Cur->Priority << endl;
}
}
return true;
}
/*}}}*/
// Dump - show everything /*{{{*/
// ---------------------------------------------------------------------
/* */
@ -382,6 +403,7 @@ int ShowHelp()
cout << " dump - Show the entire file in a terse form" << endl;
cout << " dumpavail - Print an available file to stdout" << endl;
cout << " unmet - Show unmet dependencies" << endl;
cout << " check - Check the cache a bit" << endl;
cout << endl;
cout << "Options:" << endl;
cout << " -h This help text." << endl;
@ -487,6 +509,12 @@ int main(int argc,const char *argv[])
UnMet(Cache);
break;
}
if (strcmp(CmdL.FileList[0],"check") == 0)
{
Check(Cache);
break;
}
_error->Error("Invalid operation %s", CmdL.FileList[0]);
break;

706
cmdline/apt-cdrom.cc

@ -0,0 +1,706 @@
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
// $Id: apt-cdrom.cc,v 1.1 1998/11/27 01:52:56 jgg Exp $
/* ######################################################################
##################################################################### */
/*}}}*/
// Include Files /*{{{*/
#include <apt-pkg/cmndline.h>
#include <apt-pkg/error.h>
#include <apt-pkg/init.h>
#include <apt-pkg/md5.h>
#include <apt-pkg/fileutl.h>
#include <apt-pkg/progress.h>
#include <apt-pkg/tagfile.h>
#include <strutl.h>
#include <config.h>
#include <iostream>
#include <vector>
#include <algorithm>
#include <sys/wait.h>
#include <sys/errno.h>
#include <sys/vfs.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dirent.h>
#include <unistd.h>
#include <stdio.h>
/*}}}*/
// UnmountCdrom - Unmount a cdrom /*{{{*/
// ---------------------------------------------------------------------
/* */
bool UnmountCdrom(string Path)
{
int Child = fork();
if (Child < -1)
return _error->Errno("fork","Failed to fork");
// The child
if (Child == 0)
{
// Make all the fds /dev/null
for (int I = 0; I != 10;)
close(I);
for (int I = 0; I != 3;)
dup2(open("/dev/null",O_RDWR),I);
const char *Args[10];
Args[0] = "umount";
Args[1] = Path.c_str();
Args[2] = 0;
execvp(Args[0],(char **)Args);
exit(100);
}
// Wait for mount
int Status = 0;
while (waitpid(Child,&Status,0) != Child)
{
if (errno == EINTR)
continue;
return _error->Errno("waitpid","Couldn't wait for subprocess");
}
// Check for an error code.
if (WIFEXITED(Status) == 0 || WEXITSTATUS(Status) != 0)
return false;
return true;
}
/*}}}*/
// MountCdrom - Mount a cdrom /*{{{*/
// ---------------------------------------------------------------------
/* We fork mount.. */
bool MountCdrom(string Path)
{
int Child = fork();
if (Child < -1)
return _error->Errno("fork","Failed to fork");
// The child
if (Child == 0)
{
// Make all the fds /dev/null
for (int I = 0; I != 10;)
close(I);
for (int I = 0; I != 3;)
dup2(open("/dev/null",O_RDWR),I);
const char *Args[10];
Args[0] = "mount";
Args[1] = Path.c_str();
Args[2] = 0;
execvp(Args[0],(char **)Args);
exit(100);
}
// Wait for mount
int Status = 0;
while (waitpid(Child,&Status,0) != Child)
{
if (errno == EINTR)
continue;
return _error->Errno("waitpid","Couldn't wait for subprocess");
}
// Check for an error code.
if (WIFEXITED(Status) == 0 || WEXITSTATUS(Status) != 0)
return false;
return true;
}
/*}}}*/
// IdentCdrom - Generate a unique string for this CD /*{{{*/
// ---------------------------------------------------------------------
/* We convert everything we hash into a string, this prevents byte size/order
from effecting the outcome. */
bool IdentCdrom(string CD,string &Res)
{
MD5Summation Hash;
string StartDir = SafeGetCWD();
if (chdir(CD.c_str()) != 0)
return _error->Errno("chdir","Unable to change to %s",CD.c_str());
DIR *D = opendir(".");
if (D == 0)
return _error->Errno("opendir","Unable to read %s",CD.c_str());
// Run over the directory
char S[300];
for (struct dirent *Dir = readdir(D); Dir != 0; Dir = readdir(D))
{
// Skip some files..
if (strcmp(Dir->d_name,".") == 0 ||
strcmp(Dir->d_name,"..") == 0)
continue;
sprintf(S,"%lu",Dir->d_ino);
Hash.Add(S);
Hash.Add(Dir->d_name);
};
chdir(StartDir.c_str());
closedir(D);
// Some stats from the fsys
struct statfs Buf;
if (statfs(CD.c_str(),&Buf) != 0)
return _error->Errno("statfs","Failed to stat the cdrom");
sprintf(S,"%u %u",Buf.f_blocks,Buf.f_bfree);
Hash.Add(S);
Res = Hash.Result().Value();
return true;
}
/*}}}*/
// FindPackage - Find the package files on the CDROM /*{{{*/
// ---------------------------------------------------------------------
/* We look over the cdrom for package files. This is a recursive
search that short circuits when it his a package file in the dir.
This speeds it up greatly as the majority of the size is in the
binary-* sub dirs. */
bool FindPackages(string CD,vector<string> &List, int Depth = 0)
{
if (Depth >= 5)
return true;
if (CD[CD.length()-1] != '/')
CD += '/';
if (chdir(CD.c_str()) != 0)
return _error->Errno("chdir","Unable to change to %s",CD.c_str());
/* Aha! We found some package files. We assume that everything under
this dir is controlled by those package files so we don't look down
anymore */
struct stat Buf;
if (stat("Packages",&Buf) == 0 ||
stat("Packages.gz",&Buf) == 0)
{
List.push_back(CD);
return true;
}
DIR *D = opendir(".");
if (D == 0)
return _error->Errno("opendir","Unable to read %s",CD.c_str());
// Run over the directory
for (struct dirent *Dir = readdir(D); Dir != 0; Dir = readdir(D))
{
// Skip some files..
if (strcmp(Dir->d_name,".") == 0 ||
strcmp(Dir->d_name,"..") == 0 ||
strcmp(Dir->d_name,"source") == 0 ||
strcmp(Dir->d_name,"experimental") == 0 ||
strcmp(Dir->d_name,"binary-all") == 0)
continue;
// See if the name is a sub directory
struct stat Buf;
if (stat(Dir->d_name,&Buf) != 0)
{
_error->Errno("Stat","Stat failed for %s",Dir->d_name);
break;
}
if (S_ISDIR(Buf.st_mode) == 0)
continue;
// Descend
if (FindPackages(CD + Dir->d_name,List,Depth+1) == false)
break;
if (chdir(CD.c_str()) != 0)
return _error->Errno("chdir","Unable to change to ",CD.c_str());
};
closedir(D);
return !_error->PendingError();
}
/*}}}*/
// CopyPackages - Copy the package files from the CD /*{{{*/
// ---------------------------------------------------------------------
/* */
bool CopyPackages(string CDROM,string Name,vector<string> &List)
{
OpTextProgress Progress;
bool NoStat = _config->FindB("APT::CDROM::Fast",false);
// Prepare the progress indicator
unsigned long TotalSize = 0;
for (vector<string>::iterator I = List.begin(); I != List.end(); I++)
{
struct stat Buf;
if (stat(string(*I + "Packages").c_str(),&Buf) != 0)
return _error->Errno("stat","Stat failed for %s",
string(*I + "Packages").c_str());
TotalSize += Buf.st_size;
}
unsigned long CurrentSize = 0;
unsigned int NotFound = 0;
unsigned int WrongSize = 0;
unsigned int Packages = 0;
for (vector<string>::iterator I = List.begin(); I != List.end(); I++)
{
// Open the package file
FileFd Pkg(*I + "Packages",FileFd::ReadOnly);
pkgTagFile Parser(Pkg);
if (_error->PendingError() == true)
return false;
// Open the output file
char S[400];
sprintf(S,"cdrom:%s/%sPackages",Name.c_str(),(*I).c_str() + CDROM.length());
string TargetF = _config->FindDir("Dir::State::lists") + "partial/";
FileFd Target(TargetF + URItoFileName(S),FileFd::WriteEmpty);
if (_error->PendingError() == true)
return false;
// Setup the progress meter
Progress.OverallProgress(CurrentSize,TotalSize,Pkg.Size(),
"Reading Package Lists");
// Parse
Progress.SubProgress(Pkg.Size());
pkgTagSection Section;
while (Parser.Step(Section) == true)
{
Progress.Progress(Parser.Offset());
string File = Section.FindS("Filename");
unsigned long Size = Section.FindI("Size");
if (File.empty() || Size == 0)
return _error->Error("Cannot find filename or size tag");
// See if the file exists
if (NoStat == false)
{
struct stat Buf;
File = CDROM + File;
if (stat(File.c_str(),&Buf) != 0)
{
NotFound++;
continue;
}
// Size match
if ((unsigned)Buf.st_size != Size)
{
WrongSize++;
continue;
}
}
Packages++;
// Copy it to the target package file
const char *Start;
const char *Stop;
Section.GetSection(Start,Stop);
if (Target.Write(Start,Stop-Start) == false)
return false;
}
CurrentSize += Pkg.Size();
}
Progress.Done();
// Some stats
cout << "Wrote " << Packages << " package records" ;
if (NotFound != 0)
cout << " with " << NotFound << " missing files";
if (NotFound != 0 && WrongSize != 0)
cout << " and";
if (WrongSize != 0)
cout << " with " << WrongSize << " mismatched files";
cout << '.' << endl;
if (NotFound + WrongSize > 10)
cout << "Alot of package entires were discarded, perhaps this CD is funny?" << endl;
}
/*}}}*/
// DropBinaryArch - Dump dirs with a string like /binary-<foo>/ /*{{{*/
// ---------------------------------------------------------------------
/* Here we drop everything that is not this machines arch */
bool DropBinaryArch(vector<string> &List)
{
char S[300];
sprintf(S,"/binary-%s/",_config->Find("Apt::Architecture").c_str());
for (unsigned int I = 0; I < List.size(); I++)
{
const char *Str = List[I].c_str();
const char *Res;
if ((Res = strstr(Str,"/binary-")) == 0)
continue;
// Weird, remove it.
if (strlen(Res) < strlen(S))
{
List.erase(List.begin() + I);
I--;
continue;
}
// See if it is our arch
if (stringcmp(Res,Res + strlen(S),S) == 0)
continue;
// Erase it
List.erase(List.begin() + I);
I--;
}
return true;
}
/*}}}*/
// Score - We compute a 'score' for a path /*{{{*/
// ---------------------------------------------------------------------
/* Paths are scored based on how close they come to what I consider
normal. That is ones that have 'dist' 'stable' 'frozen' will score
higher than ones without. */
int Score(string Path)
{
int Res = 0;
if (Path.find("stable/") != string::npos)
Res += 2;
if (Path.find("frozen/") != string::npos)
Res += 2;
if (Path.find("/dists/") != string::npos)
Res += 4;
if (Path.find("/main/") != string::npos)
Res += 2;
if (Path.find("/contrib/") != string::npos)
Res += 2;
if (Path.find("/non-free/") != string::npos)
Res += 2;
if (Path.find("/non-US/") != string::npos)
Res += 2;
return Res;
}
/*}}}*/
// DropRepeats - Drop repeated files resulting from symlinks /*{{{*/
// ---------------------------------------------------------------------
/* Here we go and stat every file that we found and strip dup inodes. */
bool DropRepeats(vector<string> &List)
{
// Get a list of all the inodes
ino_t *Inodes = new ino_t[List.size()];
for (unsigned int I = 0; I != List.size(); I++)
{
struct stat Buf;
if (stat(List[I].c_str(),&Buf) != 0)
_error->Errno("stat","Failed to stat %s",List[I].c_str());
Inodes[I] = Buf.st_ino;
}
// Look for dups
for (unsigned int I = 0; I != List.size(); I++)
{
for (unsigned int J = I+1; J < List.size(); J++)
{
// No match
if (Inodes[J] != Inodes[I])
continue;
// We score the two paths.. and erase one
int ScoreA = Score(List[I]);
int ScoreB = Score(List[J]);
if (ScoreA < ScoreB)
{
List[I] = string();
break;
}
List[J] = string();
}
}
// Wipe erased entries
for (unsigned int I = 0; I < List.size();)
{
if (List[I].empty() == false)
I++;
else
List.erase(List.begin()+I);
}
return true;
}
/*}}}*/
// ConvertToSourceList - Takes the path list and converts it /*{{{*/
// ---------------------------------------------------------------------
/* This looks at each element and decides if it can be expressed using
dists/ form or if it requires an absolute specficiation. It also
strips the leading CDROM path from the paths. */
bool ConvertToSourcelist(string CD,vector<string> &List)
{
char S[300];
sprintf(S,"binary-%s",_config->Find("Apt::Architecture").c_str());
sort(List.begin(),List.end());
// Convert to source list notation
for (vector<string>::iterator I = List.begin(); I != List.end(); I++)
{
// Strip the cdrom base path
*I = string(*I,CD.length());
// Too short to be a dists/ type
if ((*I).length() < strlen("dists/"))
continue;
// Not a dists type.
if (stringcmp((*I).begin(),(*I).begin()+strlen("dists/"),"dists/") != 0)
continue;
// Isolate the dist
string::size_type Slash = strlen("dists/");
string::size_type Slash2 = (*I).find('/',Slash + 1);
if (Slash2 == string::npos || Slash2 + 2 >= (*I).length())
continue;
string Dist = string(*I,Slash,Slash2 - Slash);
// Isolate the component
Slash = (*I).find('/',Slash2+1);
if (Slash == string::npos || Slash + 2 >= (*I).length())
continue;
string Comp = string(*I,Slash2+1,Slash - Slash2-1);
// Verify the trailing binar - bit
Slash2 = (*I).find('/',Slash + 1);
if (Slash == string::npos)
continue;
string Binary = string(*I,Slash+1,Slash2 - Slash-1);
if (Binary != S)
continue;
*I = Dist + ' ' + Comp;
}
// Collect similar entries
for (vector<string>::iterator I = List.begin(); I != List.end(); I++)
{
// Find a space..
string::size_type Space = (*I).find(' ');
if (Space == string::npos)
continue;
string Word1 = string(*I,0,Space);
for (vector<string>::iterator J = List.begin(); J != I; J++)
{
// Find a space..
string::size_type Space2 = (*J).find(' ');
if (Space2 == string::npos)
continue;
if (string(*J,0,Space2) != Word1)
continue;
*J += string(*I,Space);
*I = string();
}
}
// Wipe erased entries
for (unsigned int I = 0; I < List.size();)
{
if (List[I].empty() == false)
I++;
else
List.erase(List.begin()+I);
}
}
/*}}}*/
// Prompt - Simple prompt /*{{{*/
// ---------------------------------------------------------------------
/* */
void Prompt(const char *Text)
{
char C;
cout << Text << ' ' << flush;
read(STDIN_FILENO,&C,1);
if (C != '\n')
cout << endl;
}
/*}}}*/
// PromptLine - Prompt for an input line /*{{{*/
// ---------------------------------------------------------------------
/* */
string PromptLine(const char *Text)
{
cout << Text << ':' << endl;
string Res;
getline(cin,Res);
return Res;
}
/*}}}*/
// DoAdd - Add a new CDROM /*{{{*/
// ---------------------------------------------------------------------
/* */
bool DoAdd(CommandLine &)
{
// Startup
string CDROM = _config->FindDir("Acquire::cdrom::mount","/cdrom/");
cout << "Using CD-ROM mount point " << CDROM << endl;
// Read the database
Configuration Database;
string DFile = _config->FindFile("Dir::State::cdroms");
if (FileExists(DFile) == true)
{
if (ReadConfigFile(Database,DFile) == false)
return _error->Error("Unable to read the cdrom database %s",
DFile.c_str());
}
// Unmount the CD and get the user to put in the one they want
if (_config->FindB("APT::CDROM::NoMount",false) == false)
{
cout << "Unmounting CD-ROM" << endl;
UnmountCdrom(CDROM);
// Mount the new CDROM
Prompt("Please insert a CD-ROM and press any key");
cout << "Mounting CD-ROM" << endl;
if (MountCdrom(CDROM) == false)
{
cout << "Failed to mount the cdrom." << endl;
return false;
}
}
// Hash the CD to get an ID
cout << "Indentifying.. " << flush;
string ID;
if (IdentCdrom(CDROM,ID) == false)
return false;
cout << '[' << ID << ']' << endl;
cout << "Scanning Disc for index files.. " << flush;
// Get the CD structure
vector<string> List;
string StartDir = SafeGetCWD();
if (FindPackages(CDROM,List) == false)
return false;
chdir(StartDir.c_str());
// Fix up the list
DropBinaryArch(List);
DropRepeats(List);
cout << "Found " << List.size() << " package index files." << endl;
if (List.size() == 0)
return _error->Error("Unable to locate any package files, perhaps this is not a debian CD-ROM");
// Check if the CD is in the database
string Name;
if (Database.Exists("CD::" + ID) == false ||
_config->FindB("APT::CDROM::Rename",false) == true)
{
cout << "Please provide a name for this CD-ROM, such as 'Debian 2.1r1 Disk 1'";
Name = PromptLine("");
}
else
Name = Database.Find("CD::" + ID);
cout << "This Disc is called '" << Name << "'" << endl;
// Copy the package files to the state directory
if (CopyPackages(CDROM,Name,List) == false)
return false;
ConvertToSourcelist(CDROM,List);
// Print the sourcelist entries
cout << "Source List entires for this Disc are:" << endl;
for (vector<string>::iterator I = List.begin(); I != List.end(); I++)
cout << "deb \"cdrom:" << Name << "/\" " << *I << endl;
return true;
}
/*}}}*/
// ShowHelp - Show the help screen /*{{{*/
// ---------------------------------------------------------------------
/* */
int ShowHelp()
{
cout << PACKAGE << ' ' << VERSION << " for " << ARCHITECTURE <<
" compiled on " << __DATE__ << " " << __TIME__ << endl;
cout << "Usage: apt-cdrom [options] command" << endl;
cout << endl;
cout << "apt-cdrom is a tool to add CDROM's to APT's source list. The " << endl;
cout << "CDROM mount point and device information is taken from apt.conf" << endl;
cout << "and /etc/fstab." << endl;
cout << endl;
cout << "Commands:" << endl;
cout << " add - Add a CDROM" << endl;
cout << endl;
cout << "Options:" << endl;
cout << " -h This help text" << endl;
cout << " -d CD-ROM mount point" << endl;
cout << " -r Rename a recognized CD-ROM" << endl;
cout << " -m No mounting" << endl;
cout << " -c=? Read this configuration file" << endl;
cout << " -o=? Set an arbitary configuration option, ie -o dir::cache=/tmp" << endl;
cout << "See fstab(5)" << endl;
return 100;
}
/*}}}*/
int main(int argc,const char *argv[])
{
CommandLine::Args Args[] = {
{'h',"help","help",0},
{'d',"cdrom","Acquire::cdrom::mount",CommandLine::HasArg},
{'r',"rename","APT::CDROM::Rename",0},
{'m',"no-mount","APT::CDROM::NoMount",0},
{'f',"fast","APT::CDROM::Fast",0},
{'c',"config-file",0,CommandLine::ConfigFile},
{'o',"option",0,CommandLine::ArbItem},
{0,0,0,0}};
CommandLine::Dispatch Cmds[] = {
{"add",&DoAdd},
{0,0}};
// Parse the command line and initialize the package library
CommandLine CmdL(Args,_config);
if (pkgInitialize(*_config) == false ||
CmdL.Parse(argc,argv) == false)
{
_error->DumpErrors();
return 100;
}
// See if the help should be shown
if (_config->FindB("help") == true ||
CmdL.FileSize() == 0)
return ShowHelp();
// Match the operation
CmdL.DispatchArg(Cmds);
// Print any errors or warnings found during parsing
if (_error->empty() == false)
{
bool Errors = _error->PendingError();
_error->DumpErrors();
return Errors == true?100:0;
}
return 0;
}

29
cmdline/apt-config.cc

@ -1,6 +1,6 @@
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
// $Id: apt-config.cc,v 1.1 1998/11/22 23:37:07 jgg Exp $
// $Id: apt-config.cc,v 1.2 1998/11/27 01:52:57 jgg Exp $
/* ######################################################################
APT Config - Program to manipulate APT configuration files
@ -70,6 +70,8 @@ int main(int argc,const char *argv[])
{'c',"config-file",0,CommandLine::ConfigFile},
{'o',"option",0,CommandLine::ArbItem},
{0,0,0,0}};
CommandLine::Dispatch Cmds[] = {{"shell",&DoShell},
{0,0}};
// Parse the command line and initialize the package library
CommandLine CmdL(Args,_config);
@ -84,29 +86,10 @@ int main(int argc,const char *argv[])
if (_config->FindB("help") == true ||
CmdL.FileSize() == 0)
return ShowHelp();
// Match the operation
struct
{
const char *Match;
bool (*Handler)(CommandLine &);
} Map[] = {{"shell",&DoShell},
{0,0}};
int I;
for (I = 0; Map[I].Match != 0; I++)
{
if (strcmp(CmdL.FileList[0],Map[I].Match) == 0)
{
if (Map[I].Handler(CmdL) == false && _error->PendingError() == false)
_error->Error("Handler silently failed");
break;
}
}
// No matching name
if (Map[I].Match == 0)
_error->Error("Invalid operation %s", CmdL.FileList[0]);
// Match the operation
CmdL.DispatchArg(Cmds);
// Print any errors or warnings found during parsing
if (_error->empty() == false)
{

85
cmdline/apt-get.cc

@ -1,6 +1,6 @@
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
// $Id: apt-get.cc,v 1.19 1998/11/24 02:35:32 jgg Exp $
// $Id: apt-get.cc,v 1.20 1998/11/27 01:52:58 jgg Exp $
/* ######################################################################
apt-get - Cover for dpkg
@ -79,10 +79,10 @@ bool YnPrompt()
// ---------------------------------------------------------------------
/* This prints out a string of space seperated words with a title and
a two space indent line wraped to the current screen width. */
void ShowList(ostream &out,string Title,string List)
bool ShowList(ostream &out,string Title,string List)
{
if (List.empty() == true)
return;
return true;
// Acount for the leading space
int ScreenWidth = ::ScreenWidth - 3;
@ -102,6 +102,7 @@ void ShowList(ostream &out,string Title,string List)
out << " " << string(List,Start,End - Start) << endl;
Start = End + 1;
}
return false;
}
/*}}}*/
// ShowBroken - Debugging aide /*{{{*/
@ -250,7 +251,7 @@ void ShowUpgraded(ostream &out,pkgDepCache &Dep)
// ShowHold - Show held but changed packages /*{{{*/
// ---------------------------------------------------------------------
/* */
void ShowHold(ostream &out,pkgDepCache &Dep)
bool ShowHold(ostream &out,pkgDepCache &Dep)
{
pkgCache::PkgIterator I = Dep.PkgBegin();
string List;
@ -261,7 +262,7 @@ void ShowHold(ostream &out,pkgDepCache &Dep)
List += string(I.Name()) + " ";
}
ShowList(out,"The following held packages will be changed:",List);
return ShowList(out,"The following held packages will be changed:",List);
}
/*}}}*/
// ShowEssential - Show an essential package warning /*{{{*/
@ -269,7 +270,7 @@ void ShowHold(ostream &out,pkgDepCache &Dep)
/* This prints out a warning message that is not to be ignored. It shows
all essential packages and their dependents that are to be removed.
It is insanely risky to remove the dependents of an essential package! */
void ShowEssential(ostream &out,pkgDepCache &Dep)
bool ShowEssential(ostream &out,pkgDepCache &Dep)
{
pkgCache::PkgIterator I = Dep.PkgBegin();
string List;
@ -317,11 +318,10 @@ void ShowEssential(ostream &out,pkgDepCache &Dep)
}
}
delete [] Added;
if (List.empty() == false)
out << "WARNING: The following essential packages will be removed" << endl;
ShowList(out,"This should NOT be done unless you know exactly what you are doing!",List);
delete [] Added;
return ShowList(out,"This should NOT be done unless you know exactly what you are doing!",List);
}
/*}}}*/
// Stats - Show some statistics /*{{{*/
@ -461,15 +461,17 @@ bool CacheFile::Open()
happen and then calls the download routines */
bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask = true)
{
bool Fail = false;
// Show all the various warning indicators
ShowDel(c1out,Cache);
ShowNew(c1out,Cache);
if (ShwKept == true)
ShowKept(c1out,Cache);
ShowHold(c1out,Cache);
Fail |= ShowHold(c1out,Cache);
if (_config->FindB("APT::Get::Show-Upgraded",false) == true)
ShowUpgraded(c1out,Cache);
ShowEssential(c1out,Cache);
Fail |= ShowEssential(c1out,Cache);
Stats(c1out,Cache);
// Sanity check
@ -492,7 +494,9 @@ bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask = true)
// Create the text record parser
pkgRecords Recs(Cache);
if (_error->PendingError() == true)
return false;
// Lock the archive directory
if (_config->FindB("Debug::NoLocking",false) == false)
{
@ -542,16 +546,24 @@ bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask = true)
if (_error->PendingError() == true)
return false;
// Fail safe check
if (_config->FindB("APT::Get::Assume-Yes",false) == true)
{
if (Fail == true && _config->FindB("APT::Get::Force-Yes",false) == false)
return _error->Error("There are problems and -y was used without --force-yes");
}
// Prompt to continue
if (Ask == true)
{
if (_config->FindI("quiet",0) < 2 ||
{
if (_config->FindI("quiet",0) < 2 ||
_config->FindB("APT::Get::Assume-Yes",false) == false)
c2out << "Do you want to continue? [Y/n] " << flush;
c2out << "Do you want to continue? [Y/n] " << flush;
if (YnPrompt() == false)
exit(1);
}
// Run it
if (Fetcher.Run() == false)
return false;
@ -975,6 +987,7 @@ void GetInitialize()
_config->Set("APT::Get::Simulate",false);
_config->Set("APT::Get::Assume-Yes",false);
_config->Set("APT::Get::Fix-Broken",false);
_config->Set("APT::Get::Force-Yes",false);
}
/*}}}*/
// SigWinch - Window size change signal handler /*{{{*/
@ -1010,10 +1023,20 @@ int main(int argc,const char *argv[])
{'m',"ignore-missing","APT::Get::Fix-Missing",0},
{0,"fix-missing","APT::Get::Fix-Missing",0},
{0,"ignore-hold","APT::Ingore-Hold",0},
{0,"no-upgrade","APT::Get::no-upgrade",0},
{0,"no-upgrade","APT::Get::no-upgrade",0},
{0,"force-yes","APT::Get::force-yes",0},
{'c',"config-file",0,CommandLine::ConfigFile},
{'o',"option",0,CommandLine::ArbItem},
{0,0,0,0}};
CommandLine::Dispatch Cmds[] = {{"update",&DoUpdate},
{"upgrade",&DoUpgrade},
{"install",&DoInstall},
{"remove",&DoInstall},
{"dist-upgrade",&DoDistUpgrade},
{"dselect-upgrade",&DoDSelectUpgrade},
{"clean",&DoClean},
{"check",&DoCheck},
{0,0}};
// Parse the command line and initialize the package library
CommandLine CmdL(Args,_config);
@ -1044,33 +1067,7 @@ int main(int argc,const char *argv[])
SigWinch(0);
// Match the operation
struct
{
const char *Match;
bool (*Handler)(CommandLine &);
} Map[] = {{"update",&DoUpdate},
{"upgrade",&DoUpgrade},
{"install",&DoInstall},
{"remove",&DoInstall},
{"dist-upgrade",&DoDistUpgrade},
{"dselect-upgrade",&DoDSelectUpgrade},
{"clean",&DoClean},
{"check",&DoCheck},
{0,0}};
int I;
for (I = 0; Map[I].Match != 0; I++)
{
if (strcmp(CmdL.FileList[0],Map[I].Match) == 0)
{
if (Map[I].Handler(CmdL) == false && _error->PendingError() == false)
_error->Error("Handler silently failed");
break;
}
}
// No matching name
if (Map[I].Match == 0)
_error->Error("Invalid operation %s", CmdL.FileList[0]);
CmdL.DispatchArg(Cmds);
// Print any errors or warnings found during parsing
if (_error->empty() == false)

6
cmdline/makefile

@ -22,3 +22,9 @@ PROGRAM=apt-config
SLIBS = -lapt-pkg
SOURCE = apt-config.cc
include $(PROGRAM_H)
# The apt-cdrom program
PROGRAM=apt-cdrom
SLIBS = -lapt-pkg
SOURCE = apt-cdrom.cc
include $(PROGRAM_H)

Loading…
Cancel
Save