X-Git-Url: https://git.saurik.com/apt.git/blobdiff_plain/faa6596e09eec9535189c5baa7a6d2d4531f9239..56eb3b11976ad8a2fbba50772f0196df0ac2ac11:/apt-pkg/cdrom.cc diff --git a/apt-pkg/cdrom.cc b/apt-pkg/cdrom.cc index 17a4f184b..b8acf0cbe 100644 --- a/apt-pkg/cdrom.cc +++ b/apt-pkg/cdrom.cc @@ -1,14 +1,13 @@ /* */ -#ifdef __GNUG__ -#pragma implementation "apt-pkg/cdrom.h" -#endif #include #include #include #include #include +#include + #include #include #include @@ -18,7 +17,8 @@ #include #include #include - +#include +#include #include "indexcopy.h" @@ -30,12 +30,16 @@ using namespace std; 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 pkgCdrom::FindPackages(string CD,vector &List, - vector &SList, vector &SigList, +bool pkgCdrom::FindPackages(string CD, + vector &List, + vector &SList, + vector &SigList, + vector &TransList, string &InfoDir, pkgCdromStatus *log, unsigned int Depth) { static ino_t Inodes[9]; + DIR *D; // if we have a look we "pulse" now if(log) @@ -90,8 +94,28 @@ bool pkgCdrom::FindPackages(string CD,vector &List, if (_config->FindB("APT::CDROM::Thorough",false) == false) return true; } + + // see if we find translatin indexes + if (stat("i18n",&Buf) == 0) + { + D = opendir("i18n"); + for (struct dirent *Dir = readdir(D); Dir != 0; Dir = readdir(D)) + { + if(strstr(Dir->d_name,"Translation") != NULL) + { + if (_config->FindB("Debug::aptcdrom",false) == true) + std::clog << "found translations: " << Dir->d_name << "\n"; + string file = Dir->d_name; + if(file.substr(file.size()-3,file.size()) == ".gz") + file = file.substr(0,file.size()-3); + TransList.push_back(CD+"i18n/"+ file); + } + } + closedir(D); + } + - DIR *D = opendir("."); + D = opendir("."); if (D == 0) return _error->Errno("opendir","Unable to read %s",CD.c_str()); @@ -127,18 +151,22 @@ bool pkgCdrom::FindPackages(string CD,vector &List, Inodes[Depth] = Buf.st_ino; // Descend - if (FindPackages(CD + Dir->d_name,List,SList,SigList,InfoDir,log,Depth+1) == false) + if (FindPackages(CD + Dir->d_name,List,SList,SigList,TransList,InfoDir,log,Depth+1) == false) break; if (chdir(CD.c_str()) != 0) - return _error->Errno("chdir","Unable to change to %s",CD.c_str()); + { + _error->Errno("chdir","Unable to change to %s", CD.c_str()); + closedir(D); + return false; + } }; closedir(D); return !_error->PendingError(); } - + /*}}}*/ // Score - We compute a 'score' for a path /*{{{*/ // --------------------------------------------------------------------- /* Paths are scored based on how close they come to what I consider @@ -174,7 +202,7 @@ int pkgCdrom::Score(string Path) // a symlink gets a big penalty struct stat Buf; string statPath = flNotFile(Path); - string cdromPath = _config->FindDir("Acquire::cdrom::mount","/cdrom/"); + string cdromPath = _config->FindDir("Acquire::cdrom::mount"); while(statPath != cdromPath && statPath != "./") { statPath.resize(statPath.size()-1); // remove the trailing '/' if (lstat(statPath.c_str(),&Buf) == 0) { @@ -188,46 +216,34 @@ int pkgCdrom::Score(string Path) return Res; } - /*}}}*/ // DropBinaryArch - Dump dirs with a string like /binary-/ /*{{{*/ // --------------------------------------------------------------------- /* Here we drop everything that is not this machines arch */ bool pkgCdrom::DropBinaryArch(vector &List) { - char S[300]; - snprintf(S,sizeof(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) + const char *Start, *End; + if ((Start = 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 + // Between Start and End is the architecture + Start += 8; + if ((End = strstr(Start,"/")) != 0 && Start != End && + APT::Configuration::checkArchitecture(string(Start, End)) == true) + continue; // okay, architecture is accepted + + // not accepted -> Erase it List.erase(List.begin() + I); - I--; + --I; // the next entry is at the same index after the erase } return true; } - - + /*}}}*/ // DropRepeats - Drop repeated files resulting from symlinks /*{{{*/ // --------------------------------------------------------------------- /* Here we go and stat every file that we found and strip dup inodes. */ @@ -245,8 +261,10 @@ bool pkgCdrom::DropRepeats(vector &List,const char *Name) Inodes[I] = Buf.st_ino; } - if (_error->PendingError() == true) + if (_error->PendingError() == true) { + delete[] Inodes; return false; + } // Look for dups for (unsigned int I = 0; I != List.size(); I++) @@ -269,7 +287,8 @@ bool pkgCdrom::DropRepeats(vector &List,const char *Name) List[J] = string(); } } - + delete[] Inodes; + // Wipe erased entries for (unsigned int I = 0; I < List.size();) { @@ -282,7 +301,6 @@ bool pkgCdrom::DropRepeats(vector &List,const char *Name) return true; } /*}}}*/ - // ReduceSourceList - Takes the path list and reduces it /*{{{*/ // --------------------------------------------------------------------- /* This takes the list of source list expressed entires and collects @@ -292,7 +310,7 @@ void pkgCdrom::ReduceSourcelist(string CD,vector &List) sort(List.begin(),List.end()); // Collect similar entries - for (vector::iterator I = List.begin(); I != List.end(); I++) + for (vector::iterator I = List.begin(); I != List.end(); ++I) { // Find a space.. string::size_type Space = (*I).find(' '); @@ -304,7 +322,7 @@ void pkgCdrom::ReduceSourcelist(string CD,vector &List) string Word1 = string(*I,Space,SSpace-Space); string Prefix = string(*I,0,Space); - for (vector::iterator J = List.begin(); J != I; J++) + for (vector::iterator J = List.begin(); J != I; ++J) { // Find a space.. string::size_type Space2 = (*J).find(' '); @@ -371,7 +389,7 @@ bool pkgCdrom::WriteDatabase(Configuration &Cnf) Out.close(); - rename(DFile.c_str(),string(DFile + '~').c_str()); + link(DFile.c_str(),string(DFile + '~').c_str()); if (rename(NewFile.c_str(),DFile.c_str()) != 0) return _error->Errno("rename","Failed to rename %s.new to %s", DFile.c_str(),DFile.c_str()); @@ -387,7 +405,7 @@ bool pkgCdrom::WriteDatabase(Configuration &Cnf) that were the same. */ bool pkgCdrom::WriteSourceList(string Name,vector &List,bool Source) { - if (List.size() == 0) + if (List.empty() == true) return true; string File = _config->FindFile("Dir::Etc::sourcelist"); @@ -437,7 +455,7 @@ bool pkgCdrom::WriteSourceList(string Name,vector &List,bool Source) if (First == true) { - for (vector::iterator I = List.begin(); I != List.end(); I++) + for (vector::iterator I = List.begin(); I != List.end(); ++I) { string::size_type Space = (*I).find(' '); if (Space == string::npos) @@ -471,7 +489,7 @@ bool pkgCdrom::WriteSourceList(string Name,vector &List,bool Source) // Just in case the file was empty if (First == true) { - for (vector::iterator I = List.begin(); I != List.end(); I++) + for (vector::iterator I = List.begin(); I != List.end(); ++I) { string::size_type Space = (*I).find(' '); if (Space == string::npos) @@ -491,18 +509,18 @@ bool pkgCdrom::WriteSourceList(string Name,vector &List,bool Source) return true; } - - -bool pkgCdrom::Ident(string &ident, pkgCdromStatus *log) + /*}}}*/ +bool pkgCdrom::Ident(string &ident, pkgCdromStatus *log) /*{{{*/ { stringstream msg; // Startup - string CDROM = _config->FindDir("Acquire::cdrom::mount","/cdrom/"); + string CDROM = _config->FindDir("Acquire::cdrom::mount"); if (CDROM[0] == '.') CDROM= SafeGetCWD() + '/' + CDROM; - if(log) { + if (log != NULL) + { msg.str(""); ioprintf(msg, _("Using CD-ROM mount point %s\nMounting CD-ROM\n"), CDROM.c_str()); @@ -512,7 +530,7 @@ bool pkgCdrom::Ident(string &ident, pkgCdromStatus *log) return _error->Error("Failed to mount the cdrom."); // Hash the CD to get an ID - if(log) + if (log != NULL) log->Update(_("Identifying.. ")); @@ -522,10 +540,12 @@ bool pkgCdrom::Ident(string &ident, pkgCdromStatus *log) return false; } - msg.str(""); - ioprintf(msg, "[%s]\n",ident.c_str()); - log->Update(msg.str()); - + if (log != NULL) + { + msg.str(""); + ioprintf(msg, "[%s]\n",ident.c_str()); + log->Update(msg.str()); + } // Read the database Configuration Database; @@ -536,26 +556,36 @@ bool pkgCdrom::Ident(string &ident, pkgCdromStatus *log) return _error->Error("Unable to read the cdrom database %s", DFile.c_str()); } - if(log) { + if (log != NULL) + { msg.str(""); - ioprintf(msg, _("Stored label: %s \n"), - Database.Find("CD::"+ident).c_str()); + ioprintf(msg, _("Stored label: %s\n"), + Database.Find("CD::"+ident).c_str()); log->Update(msg.str()); } - return true; -} + // Unmount and finish + if (_config->FindB("APT::CDROM::NoMount",false) == false) + { + if (log != NULL) + log->Update(_("Unmounting CD-ROM...\n"), STEP_LAST); + UnmountCdrom(CDROM); + } -bool pkgCdrom::Add(pkgCdromStatus *log) + return true; +} + /*}}}*/ +bool pkgCdrom::Add(pkgCdromStatus *log) /*{{{*/ { stringstream msg; // Startup - string CDROM = _config->FindDir("Acquire::cdrom::mount","/cdrom/"); + string CDROM = _config->FindDir("Acquire::cdrom::mount"); if (CDROM[0] == '.') CDROM= SafeGetCWD() + '/' + CDROM; - if(log) { + if(log != NULL) + { log->SetTotal(STEP_LAST); msg.str(""); ioprintf(msg, _("Using CD-ROM mount point %s\n"), CDROM.c_str()); @@ -575,11 +605,12 @@ bool pkgCdrom::Add(pkgCdromStatus *log) // Unmount the CD and get the user to put in the one they want if (_config->FindB("APT::CDROM::NoMount",false) == false) { - if(log) + if(log != NULL) log->Update(_("Unmounting CD-ROM\n"), STEP_UNMOUNT); UnmountCdrom(CDROM); - if(log) { + if(log != NULL) + { log->Update(_("Waiting for disc...\n"), STEP_WAIT); if(!log->ChangeCdrom()) { // user aborted @@ -588,35 +619,40 @@ bool pkgCdrom::Add(pkgCdromStatus *log) } // Mount the new CDROM - log->Update(_("Mounting CD-ROM...\n"), STEP_MOUNT); + if(log != NULL) + log->Update(_("Mounting CD-ROM...\n"), STEP_MOUNT); + if (MountCdrom(CDROM) == false) return _error->Error("Failed to mount the cdrom."); } // Hash the CD to get an ID - if(log) + if(log != NULL) log->Update(_("Identifying.. "), STEP_IDENT); string ID; if (IdentCdrom(CDROM,ID) == false) { - log->Update("\n"); + if (log != NULL) + log->Update("\n"); return false; } - if(log) + if(log != NULL) + { log->Update("["+ID+"]\n"); - - if(log) log->Update(_("Scanning disc for index files..\n"),STEP_SCAN); - + } + // Get the CD structure vector List; vector SourceList; vector SigList; + vector TransList; string StartDir = SafeGetCWD(); string InfoDir; - if (FindPackages(CDROM,List,SourceList, SigList,InfoDir,log) == false) + if (FindPackages(CDROM,List,SourceList, SigList,TransList,InfoDir,log) == false) { - log->Update("\n"); + if (log != NULL) + log->Update("\n"); return false; } @@ -625,13 +661,13 @@ bool pkgCdrom::Add(pkgCdromStatus *log) if (_config->FindB("Debug::aptcdrom",false) == true) { cout << "I found (binary):" << endl; - for (vector::iterator I = List.begin(); I != List.end(); I++) + for (vector::iterator I = List.begin(); I != List.end(); ++I) cout << *I << endl; cout << "I found (source):" << endl; - for (vector::iterator I = SourceList.begin(); I != SourceList.end(); I++) + for (vector::iterator I = SourceList.begin(); I != SourceList.end(); ++I) cout << *I << endl; cout << "I found (Signatures):" << endl; - for (vector::iterator I = SigList.begin(); I != SigList.end(); I++) + for (vector::iterator I = SigList.begin(); I != SigList.end(); ++I) cout << *I << endl; } @@ -642,19 +678,21 @@ bool pkgCdrom::Add(pkgCdromStatus *log) DropRepeats(List,"Packages"); DropRepeats(SourceList,"Sources"); DropRepeats(SigList,"Release.gpg"); - if(log) { + DropRepeats(TransList,""); + if(log != NULL) { msg.str(""); - ioprintf(msg, _("Found %i package indexes, %i source indexes and " - "%i signatures\n"), - List.size(), SourceList.size(), SigList.size()); + ioprintf(msg, _("Found %zu package indexes, %zu source indexes, " + "%zu translation indexes and %zu signatures\n"), + List.size(), SourceList.size(), TransList.size(), + SigList.size()); log->Update(msg.str(), STEP_SCAN); } - if (List.size() == 0 && SourceList.size() == 0) + if (List.empty() == true && SourceList.empty() == true) { if (_config->FindB("APT::CDROM::NoMount",false) == false) UnmountCdrom(CDROM); - return _error->Error("Unable to locate any package files, perhaps this is not a Debian Disc"); + return _error->Error(_("Unable to locate any package files, perhaps this is not a Debian Disc or the wrong architecture?")); } // Check if the CD is in the database @@ -674,11 +712,12 @@ bool pkgCdrom::Add(pkgCdromStatus *log) { // Escape special characters string::iterator J = Name.begin(); - for (; J != Name.end(); J++) + for (; J != Name.end(); ++J) if (*J == '"' || *J == ']' || *J == '[') *J = '_'; - if(log) { + if(log != NULL) + { msg.str(""); ioprintf(msg, _("Found label '%s'\n"), Name.c_str()); log->Update(msg.str()); @@ -690,7 +729,7 @@ bool pkgCdrom::Add(pkgCdromStatus *log) if (_config->FindB("APT::CDROM::Rename",false) == true || Name.empty() == true) { - if(!log) + if(log == NULL) { if (_config->FindB("APT::CDROM::NoMount",false) == false) UnmountCdrom(CDROM); @@ -718,18 +757,18 @@ bool pkgCdrom::Add(pkgCdromStatus *log) // Escape special characters string::iterator J = Name.begin(); - for (; J != Name.end(); J++) + for (; J != Name.end(); ++J) if (*J == '"' || *J == ']' || *J == '[') *J = '_'; Database.Set("CD::" + ID,Name); - if(log) { + if(log != NULL) + { msg.str(""); ioprintf(msg, _("This disc is called: \n'%s'\n"), Name.c_str()); log->Update(msg.str()); + log->Update(_("Copying package lists..."), STEP_COPY); } - - log->Update(_("Copying package lists..."), STEP_COPY); // take care of the signatures and copy them if they are ok // (we do this before PackageCopy as it modifies "List" and "SourceList") SigVerify SignVerify; @@ -738,8 +777,10 @@ bool pkgCdrom::Add(pkgCdromStatus *log) // Copy the package files to the state directory PackageCopy Copy; SourceCopy SrcCopy; + TranslationsCopy TransCopy; if (Copy.CopyPackages(CDROM,Name,List, log) == false || - SrcCopy.CopyPackages(CDROM,Name,SourceList, log) == false) + SrcCopy.CopyPackages(CDROM,Name,SourceList, log) == false || + TransCopy.CopyTranslations(CDROM,Name,TransList, log) == false) return false; // reduce the List so that it takes less space in sources.list @@ -752,19 +793,18 @@ bool pkgCdrom::Add(pkgCdromStatus *log) if (WriteDatabase(Database) == false) return false; - if(log) { + if(log != NULL) log->Update(_("Writing new source list\n"), STEP_WRITE); - } if (WriteSourceList(Name,List,false) == false || WriteSourceList(Name,SourceList,true) == false) return false; } // Print the sourcelist entries - if(log) + if(log != NULL) log->Update(_("Source list entries for this disc are:\n")); - for (vector::iterator I = List.begin(); I != List.end(); I++) + for (vector::iterator I = List.begin(); I != List.end(); ++I) { string::size_type Space = (*I).find(' '); if (Space == string::npos) @@ -774,7 +814,8 @@ bool pkgCdrom::Add(pkgCdromStatus *log) return _error->Error("Internal error"); } - if(log) { + if(log != NULL) + { msg.str(""); msg << "deb cdrom:[" << Name << "]/" << string(*I,0,Space) << " " << string(*I,Space+1) << endl; @@ -782,7 +823,7 @@ bool pkgCdrom::Add(pkgCdromStatus *log) } } - for (vector::iterator I = SourceList.begin(); I != SourceList.end(); I++) + for (vector::iterator I = SourceList.begin(); I != SourceList.end(); ++I) { string::size_type Space = (*I).find(' '); if (Space == string::npos) @@ -792,7 +833,7 @@ bool pkgCdrom::Add(pkgCdromStatus *log) return _error->Error("Internal error"); } - if(log) { + if(log != NULL) { msg.str(""); msg << "deb-src cdrom:[" << Name << "]/" << string(*I,0,Space) << " " << string(*I,Space+1) << endl; @@ -800,13 +841,128 @@ bool pkgCdrom::Add(pkgCdromStatus *log) } } - - // Unmount and finish if (_config->FindB("APT::CDROM::NoMount",false) == false) { - log->Update(_("Unmounting CD-ROM...\n"), STEP_LAST); + if (log != NULL) + log->Update(_("Unmounting CD-ROM...\n"), STEP_LAST); UnmountCdrom(CDROM); } return true; } + /*}}}*/ +pkgUdevCdromDevices::pkgUdevCdromDevices() /*{{{*/ + : libudev_handle(NULL) +{ + +} + /*}}}*/ + +bool +pkgUdevCdromDevices::Dlopen() /*{{{*/ +{ + // alread open + if(libudev_handle != NULL) + return true; + + // see if we can get libudev + void *h = ::dlopen("libudev.so.0", RTLD_LAZY); + if(h == NULL) + return false; + + // get the pointers to the udev structs + libudev_handle = h; + udev_new = (udev* (*)(void)) dlsym(h, "udev_new"); + udev_enumerate_add_match_property = (int (*)(udev_enumerate*, const char*, const char*))dlsym(h, "udev_enumerate_add_match_property"); +#if 0 // FIXME: uncomment on next ABI break + udev_enumerate_add_match_sysattr = (int (*)(udev_enumerate*, const char*, const char*))dlsym(h, "udev_enumerate_add_match_sysattr"); +#endif + udev_enumerate_scan_devices = (int (*)(udev_enumerate*))dlsym(h, "udev_enumerate_scan_devices"); + udev_enumerate_get_list_entry = (udev_list_entry* (*)(udev_enumerate*))dlsym(h, "udev_enumerate_get_list_entry"); + udev_device_new_from_syspath = (udev_device* (*)(udev*, const char*))dlsym(h, "udev_device_new_from_syspath"); + udev_enumerate_get_udev = (udev* (*)(udev_enumerate*))dlsym(h, "udev_enumerate_get_udev"); + udev_list_entry_get_name = (const char* (*)(udev_list_entry*))dlsym(h, "udev_list_entry_get_name"); + udev_device_get_devnode = (const char* (*)(udev_device*))dlsym(h, "udev_device_get_devnode"); + udev_enumerate_new = (udev_enumerate* (*)(udev*))dlsym(h, "udev_enumerate_new"); + udev_list_entry_get_next = (udev_list_entry* (*)(udev_list_entry*))dlsym(h, "udev_list_entry_get_next"); + udev_device_get_property_value = (const char* (*)(udev_device *, const char *))dlsym(h, "udev_device_get_property_value"); + + return true; +} + /*}}}*/ + + /*{{{*/ +// compatiblity only with the old API/ABI, can be removed on the next +// ABI break +vector +pkgUdevCdromDevices::Scan() +{ + bool CdromOnly = _config->FindB("APT::cdrom::CdromOnly", true); + return ScanForRemovable(CdromOnly); +}; + /*}}}*/ + /*{{{*/ +vector +pkgUdevCdromDevices::ScanForRemovable(bool CdromOnly) +{ + vector cdrom_devices; + struct udev_enumerate *enumerate; + struct udev_list_entry *l, *devices; + struct udev *udev_ctx; + + if(libudev_handle == NULL) + return cdrom_devices; + + udev_ctx = udev_new(); + enumerate = udev_enumerate_new (udev_ctx); + if (CdromOnly) + udev_enumerate_add_match_property(enumerate, "ID_CDROM", "1"); + else { +#if 1 // FIXME: remove the next two lines on the next ABI break + int (*udev_enumerate_add_match_sysattr)(struct udev_enumerate *udev_enumerate, const char *property, const char *value); + udev_enumerate_add_match_sysattr = (int (*)(udev_enumerate*, const char*, const char*))dlsym(libudev_handle, "udev_enumerate_add_match_sysattr"); +#endif + udev_enumerate_add_match_sysattr(enumerate, "removable", "1"); + } + + udev_enumerate_scan_devices (enumerate); + devices = udev_enumerate_get_list_entry (enumerate); + for (l = devices; l != NULL; l = udev_list_entry_get_next (l)) + { + CdromDevice cdrom; + struct udev_device *udevice; + udevice = udev_device_new_from_syspath (udev_enumerate_get_udev (enumerate), udev_list_entry_get_name (l)); + if (udevice == NULL) + continue; + const char* devnode = udev_device_get_devnode(udevice); + + // try fstab_dir first + string mountpath; + const char* mp = udev_device_get_property_value(udevice, "FSTAB_DIR"); + if (mp) + mountpath = string(mp); + else + mountpath = FindMountPointForDevice(devnode); + + // fill in the struct + cdrom.DeviceName = string(devnode); + if (mountpath != "") { + cdrom.MountPath = mountpath; + string s = string(mountpath); + cdrom.Mounted = IsMounted(s); + } else { + cdrom.Mounted = false; + cdrom.MountPath = ""; + } + cdrom_devices.push_back(cdrom); + } + return cdrom_devices; +} + /*}}}*/ + +pkgUdevCdromDevices::~pkgUdevCdromDevices() /*{{{*/ +{ + if (libudev_handle != NULL) + dlclose(libudev_handle); +} + /*}}}*/