X-Git-Url: https://git.saurik.com/apt.git/blobdiff_plain/ac49a1e5b9b1ac67d66de25072a5a197432bece3..281daf46d178d4fb6f43e8b13b9b51736db84d74:/cmdline/apt-cdrom.cc diff --git a/cmdline/apt-cdrom.cc b/cmdline/apt-cdrom.cc index 1985c22a6..67c3bc7e4 100644 --- a/cmdline/apt-cdrom.cc +++ b/cmdline/apt-cdrom.cc @@ -1,6 +1,6 @@ // -*- mode: cpp; mode: fold -*- // Description /*{{{*/ -// $Id: apt-cdrom.cc,v 1.7 1998/12/04 23:33:18 jgg Exp $ +// $Id: apt-cdrom.cc,v 1.26 1999/07/03 03:10:35 jgg Exp $ /* ###################################################################### APT CDROM - Tool for handling APT's CDROM database. @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include #include @@ -38,8 +38,10 @@ 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 &List, int Depth = 0) +bool FindPackages(string CD,vector &List,string &InfoDir, + unsigned int Depth = 0) { + static ino_t Inodes[9]; if (Depth >= 7) return true; @@ -49,17 +51,26 @@ bool FindPackages(string CD,vector &List, int Depth = 0) if (chdir(CD.c_str()) != 0) return _error->Errno("chdir","Unable to change to %s",CD.c_str()); + // Look for a .disk subdirectory + struct stat Buf; + if (stat(".disk",&Buf) == 0) + { + if (InfoDir.empty() == true) + InfoDir = CD + ".disk/"; + } + /* 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) + if (stat("Packages",&Buf) == 0) { List.push_back(CD); - return true; + + // Continue down if thorough is given + if (_config->FindB("APT::CDROM::Thorough",false) == false) + return true; } - + DIR *D = opendir("."); if (D == 0) return _error->Errno("opendir","Unable to read %s",CD.c_str()); @@ -83,8 +94,18 @@ bool FindPackages(string CD,vector &List, int Depth = 0) if (S_ISDIR(Buf.st_mode) == 0) continue; + unsigned int I; + for (I = 0; I != Depth; I++) + if (Inodes[I] == Buf.st_ino) + break; + if (I != Depth) + continue; + + // Store the inodes weve seen + Inodes[Depth] = Buf.st_ino; + // Descend - if (FindPackages(CD + Dir->d_name,List,Depth+1) == false) + if (FindPackages(CD + Dir->d_name,List,InfoDir,Depth+1) == false) break; if (chdir(CD.c_str()) != 0) @@ -142,6 +163,8 @@ int Score(string Path) int Res = 0; if (Path.find("stable/") != string::npos) Res += 2; + if (Path.find("/binary-") != string::npos) + Res += 2; if (Path.find("frozen/") != string::npos) Res += 2; if (Path.find("/dists/") != string::npos) @@ -167,11 +190,14 @@ bool DropRepeats(vector &List) 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()); + if (stat((List[I] + "Packages").c_str(),&Buf) != 0) + _error->Errno("stat","Failed to stat %sPackages",List[I].c_str()); Inodes[I] = Buf.st_ino; } + if (_error->PendingError() == true) + return false; + // Look for dups for (unsigned int I = 0; I != List.size(); I++) { @@ -422,6 +448,7 @@ bool CopyPackages(string CDROM,string Name,vector &List) File = OrigPath + ChopDirs(File,Chop); // See if the file exists + bool Mangled = false; if (NoStat == false || Hits < 10) { // Attempt to fix broken structure @@ -430,6 +457,8 @@ bool CopyPackages(string CDROM,string Name,vector &List) if (ReconstructPrefix(Prefix,OrigPath,CDROM,File) == false && ReconstructChop(Chop,*I,File) == false) { + if (Debug == true) + clog << "Missed: " << File << endl; NotFound++; continue; } @@ -439,15 +468,34 @@ bool CopyPackages(string CDROM,string Name,vector &List) // Get the size struct stat Buf; - if (stat(string(CDROM + Prefix + File).c_str(),&Buf) != 0) + if (stat(string(CDROM + Prefix + File).c_str(),&Buf) != 0 || + Buf.st_size == 0) { - NotFound++; - continue; + // Attempt to fix busted symlink support for one instance + string OrigFile = File; + string::size_type Start = File.find("binary-"); + string::size_type End = File.find("/",Start+3); + if (Start != string::npos && End != string::npos) + { + File.replace(Start,End-Start,"binary-all"); + Mangled = true; + } + + if (Mangled == false || + stat(string(CDROM + Prefix + File).c_str(),&Buf) != 0) + { + if (Debug == true) + clog << "Missed(2): " << OrigFile << endl; + NotFound++; + continue; + } } // Size match if ((unsigned)Buf.st_size != Size) { + if (Debug == true) + clog << "Wrong Size: " << File << endl; WrongSize++; continue; } @@ -459,7 +507,7 @@ bool CopyPackages(string CDROM,string Name,vector &List) // Copy it to the target package file const char *Start; const char *Stop; - if (Chop != 0) + if (Chop != 0 || Mangled == true) { // Mangle the output filename const char *Filename; @@ -480,8 +528,13 @@ bool CopyPackages(string CDROM,string Name,vector &List) return false; } else + { if (Target.Write(Start,Stop-Start) == false) - return false; + return false; + if (Stop[-1] != '\n') + if (Target.Write("\n",1) == false) + return false; + } } if (Target.Write("\n",1) == false) return false; @@ -557,7 +610,7 @@ bool CopyPackages(string CDROM,string Name,vector &List) return _error->Error("No valid package records were found."); if (NotFound + WrongSize > 10) - cout << "Alot of package entires were discarded, perhaps this CD is funny?" << endl; + cout << "Alot of package entries were discarded, perhaps this CD is funny?" << endl; return true; } @@ -813,13 +866,10 @@ bool DoAdd(CommandLine &) UnmountCdrom(CDROM); // Mount the new CDROM - Prompt("Please insert a Disc in the drive and press any key"); + Prompt("Please insert a Disc in the drive and press enter"); cout << "Mounting CD-ROM" << endl; if (MountCdrom(CDROM) == false) - { - cout << "Failed to mount the cdrom." << endl; - return false; - } + return _error->Error("Failed to mount the cdrom."); } // Hash the CD to get an ID @@ -837,7 +887,8 @@ bool DoAdd(CommandLine &) // Get the CD structure vector List; string StartDir = SafeGetCWD(); - if (FindPackages(CDROM,List) == false) + string InfoDir; + if (FindPackages(CDROM,List,InfoDir) == false) { cout << endl; return false; @@ -868,9 +919,10 @@ bool DoAdd(CommandLine &) _config->FindB("APT::CDROM::Rename",false) == true) { // Try to use the CDs label if at all possible - if (FileExists(CDROM + "/.disk/info") == true) + if (InfoDir.empty() == false && + FileExists(InfoDir + "/info") == true) { - ifstream F(string(CDROM+ "/.disk/info").c_str()); + ifstream F(string(InfoDir + "/info").c_str()); if (!F == 0) getline(F,Name); @@ -889,15 +941,22 @@ bool DoAdd(CommandLine &) { Name = PromptLine(""); if (Name.empty() == false && + Name.find('"') == string::npos && + Name.find(':') == string::npos && Name.find('/') == string::npos) break; cout << "That is not a valid name, try again " << endl; - } - + } } } else Name = Database.Find("CD::" + ID); + + string::iterator J = Name.begin(); + for (; J != Name.end(); J++) + if (*J == '/' || *J == '"' || *J == ':') + *J = '_'; + Database.Set("CD::" + ID,Name); cout << "This Disc is called '" << Name << "'" << endl; @@ -919,7 +978,7 @@ bool DoAdd(CommandLine &) } // Print the sourcelist entries - cout << "Source List entires for this Disc are:" << endl; + cout << "Source List entries for this Disc are:" << endl; for (vector::iterator I = List.begin(); I != List.end(); I++) { string::size_type Space = (*I).find(' '); @@ -929,7 +988,8 @@ bool DoAdd(CommandLine &) cout << "deb \"cdrom:" << Name << "/" << string(*I,0,Space) << "\" " << string(*I,Space+1) << endl; } - + + cout << "Repeat this process for the rest of the CDs in your set." << endl; return true; } /*}}}*/ @@ -941,6 +1001,8 @@ int ShowHelp() { cout << PACKAGE << ' ' << VERSION << " for " << ARCHITECTURE << " compiled on " << __DATE__ << " " << __TIME__ << endl; + if (_config->FindB("version") == true) + return 100; cout << "Usage: apt-cdrom [options] command" << endl; cout << endl; @@ -957,8 +1019,9 @@ int ShowHelp() cout << " -r Rename a recognized CD-ROM" << endl; cout << " -m No mounting" << endl; cout << " -f Fast mode, don't check package files" << endl; + cout << " -a Thorough scan mode" << endl; cout << " -c=? Read this configuration file" << endl; - cout << " -o=? Set an arbitary configuration option, ie -o dir::cache=/tmp" << endl; + cout << " -o=? Set an arbitary configuration option, eg -o dir::cache=/tmp" << endl; cout << "See fstab(5)" << endl; return 100; } @@ -968,13 +1031,15 @@ int main(int argc,const char *argv[]) { CommandLine::Args Args[] = { {'h',"help","help",0}, + {'v',"version","version",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}, - {'n',"just-print","APT::CDROM::NoAct",0}, + {'n',"just-print","APT::CDROM::NoAct",0}, {'n',"recon","APT::CDROM::NoAct",0}, - {'n',"no-act","APT::CDROM::NoAct",0}, + {'n',"no-act","APT::CDROM::NoAct",0}, + {'a',"thorough","APT::CDROM::Thorough",0}, {'c',"config-file",0,CommandLine::ConfigFile}, {'o',"option",0,CommandLine::ArbItem}, {0,0,0,0}}; @@ -995,6 +1060,10 @@ int main(int argc,const char *argv[]) if (_config->FindB("help") == true || CmdL.FileSize() == 0) return ShowHelp(); + + // Deal with stdout not being a tty + if (ttyname(STDOUT_FILENO) == 0 && _config->FindI("quiet",0) < 1) + _config->Set("quiet","1"); // Match the operation CmdL.DispatchArg(Cmds);