X-Git-Url: https://git.saurik.com/apt.git/blobdiff_plain/b1a6d48bb4a5644ad9b76718f66d8aa7e00af902..cc0a4c82b3c132abba9b9ec35fd61bc8b45a1b80:/cmdline/apt-cdrom.cc diff --git a/cmdline/apt-cdrom.cc b/cmdline/apt-cdrom.cc index d804c55e5..bac808a41 100644 --- a/cmdline/apt-cdrom.cc +++ b/cmdline/apt-cdrom.cc @@ -11,6 +11,8 @@ ##################################################################### */ /*}}}*/ // Include Files /*{{{*/ +#include + #include #include #include @@ -18,24 +20,21 @@ #include #include #include -#include -#include #include -#include -#include - -//#include "indexcopy.h" +#include +#include -#include #include -#include #include -#include +#include #include -#include -#include #include -#include + +#include +#include +#include + +#include /*}}}*/ using namespace std; @@ -44,21 +43,23 @@ class pkgCdromTextStatus : public pkgCdromStatus /*{{{*/ { protected: OpTextProgress Progress; - void Prompt(const char *Text); + void Prompt(const char *Text); string PromptLine(const char *Text); - bool AskCdromName(string &name); + bool AskCdromName(string &name) APT_OVERRIDE; public: - virtual void Update(string text, int current); - virtual bool ChangeCdrom(); - virtual OpProgress* GetOpProgress(); + virtual void Update(string text, int current) APT_OVERRIDE; + virtual bool ChangeCdrom() APT_OVERRIDE; + virtual OpProgress* GetOpProgress() APT_OVERRIDE; }; -void pkgCdromTextStatus::Prompt(const char *Text) +void pkgCdromTextStatus::Prompt(const char *Text) { char C; cout << Text << ' ' << flush; - read(STDIN_FILENO,&C,1); + if (read(STDIN_FILENO,&C,1) < 0) + _error->Errno("pkgCdromTextStatus::Prompt", + "Failed to read from standard input (not a terminal?)"); if (C != '\n') cout << endl; } @@ -66,155 +67,170 @@ void pkgCdromTextStatus::Prompt(const char *Text) string pkgCdromTextStatus::PromptLine(const char *Text) { cout << Text << ':' << endl; - + string Res; getline(cin,Res); return Res; } -bool pkgCdromTextStatus::AskCdromName(string &name) +bool pkgCdromTextStatus::AskCdromName(string &name) { cout << _("Please provide a name for this Disc, such as 'Debian 5.0.3 Disk 1'") << flush; name = PromptLine(""); - + return true; } - -void pkgCdromTextStatus::Update(string text, int current) + +void pkgCdromTextStatus::Update(string text, int /*current*/) { if(text.size() > 0) cout << text << flush; } -bool pkgCdromTextStatus::ChangeCdrom() +bool pkgCdromTextStatus::ChangeCdrom() { - Prompt(_("Please insert a Disc in the drive and press enter")); + Prompt(_("Please insert a Disc in the drive and press [Enter]")); return true; } -OpProgress* pkgCdromTextStatus::GetOpProgress() -{ - return &Progress; -}; +APT_CONST OpProgress* pkgCdromTextStatus::GetOpProgress() +{ + return &Progress; +} + /*}}}*/ +// AddOrIdent - Add or Ident a CDROM /*{{{*/ +static bool AddOrIdent(bool const Add) +{ + pkgUdevCdromDevices UdevCdroms; + pkgCdromTextStatus log; + pkgCdrom cdrom; + + bool oneSuccessful = false; + bool AutoDetect = _config->FindB("Acquire::cdrom::AutoDetect", true); + if (AutoDetect == true && UdevCdroms.Dlopen() == true) + { + bool const Debug = _config->FindB("Debug::Acquire::cdrom", false); + std::string const CDMount = _config->Find("Acquire::cdrom::mount"); + bool const NoMount = _config->FindB("APT::CDROM::NoMount", false); + if (NoMount == false) + _config->Set("APT::CDROM::NoMount", true); + + vector const v = UdevCdroms.Scan(); + for (std::vector::const_iterator cd = v.begin(); cd != v.end(); ++cd) + { + if (Debug) + clog << "Looking at device:" + << "\tDeviveName: '" << cd->DeviceName << "'" + << "\tIsMounted: '" << cd->Mounted << "'" + << "\tMountPoint: '" << cd->MountPath << "'" + << endl; + + std::string AptMountPoint; + if (cd->Mounted) + _config->Set("Acquire::cdrom::mount", cd->MountPath); + else if (NoMount == true) + continue; + else + { + AptMountPoint = _config->FindDir("Dir::Media::MountPath"); + if (FileExists(AptMountPoint) == false) + mkdir(AptMountPoint.c_str(), 0750); + if(MountCdrom(AptMountPoint, cd->DeviceName) == false) + { + _error->Warning(_("Failed to mount '%s' to '%s'"), cd->DeviceName.c_str(), AptMountPoint.c_str()); + continue; + } + _config->Set("Acquire::cdrom::mount", AptMountPoint); + } + + _error->PushToStack(); + if (Add == true) + oneSuccessful = cdrom.Add(&log); + else + { + std::string id; + oneSuccessful = cdrom.Ident(id, &log); + } + _error->MergeWithStack(); + + if (AptMountPoint.empty() == false) + UnmountCdrom(AptMountPoint); + } + if (NoMount == false) + _config->Set("APT::CDROM::NoMount", NoMount); + _config->Set("Acquire::cdrom::mount", CDMount); + } + + // fallback if auto-detect didn't work + if (oneSuccessful == false) + { + _error->PushToStack(); + if (Add == true) + oneSuccessful = cdrom.Add(&log); + else + { + std::string id; + oneSuccessful = cdrom.Ident(id, &log); + } + _error->MergeWithStack(); + } + + if (oneSuccessful == false) + _error->Error("%s", _("No CD-ROM could be auto-detected or found using the default mount point.\n" + "You may try the --cdrom option to set the CD-ROM mount point.\n" + "See 'man apt-cdrom' for more information about the CD-ROM auto-detection and mount point.")); + else if (Add == true) + cout << _("Repeat this process for the rest of the CDs in your set.") << endl; + + return oneSuccessful; +} /*}}}*/ // DoAdd - Add a new CDROM /*{{{*/ // --------------------------------------------------------------------- /* This does the main add bit.. We show some status and things. The - sequence is to mount/umount the CD, Ident it then scan it for package + sequence is to mount/umount the CD, Ident it then scan it for package files and reduce that list. Then we copy over the package files and verify them. Then rewrite the database files */ -bool DoAdd(CommandLine &) +static bool DoAdd(CommandLine &) { - bool res = false; - pkgCdromTextStatus log; - pkgCdrom cdrom; - res = cdrom.Add(&log); - if(res) - cout << _("Repeat this process for the rest of the CDs in your set.") << endl; - return res; + return AddOrIdent(true); } /*}}}*/ // DoIdent - Ident a CDROM /*{{{*/ -// --------------------------------------------------------------------- -/* */ -bool DoIdent(CommandLine &) +static bool DoIdent(CommandLine &) { - string ident; - pkgCdromTextStatus log; - pkgCdrom cdrom; - return cdrom.Ident(ident, &log); + return AddOrIdent(false); } /*}}}*/ -// ShowHelp - Show the help screen /*{{{*/ -// --------------------------------------------------------------------- -/* */ -int ShowHelp() +static bool ShowHelp(CommandLine &) /*{{{*/ { - ioprintf(cout,_("%s %s for %s compiled on %s %s\n"),PACKAGE,VERSION, - COMMON_ARCH,__DATE__,__TIME__); - if (_config->FindB("version") == true) - return 0; - - cout << - "Usage: apt-cdrom [options] command\n" - "\n" - "apt-cdrom is a tool to add CDROM's to APT's source list. The\n" - "CDROM mount point and device information is taken from apt.conf\n" - "and /etc/fstab.\n" + std::cout << + _("Usage: apt-cdrom [options] command\n" "\n" - "Commands:\n" - " add - Add a CDROM\n" - " ident - Report the identity of a CDROM\n" - "\n" - "Options:\n" - " -h This help text\n" - " -d CD-ROM mount point\n" - " -r Rename a recognized CD-ROM\n" - " -m No mounting\n" - " -f Fast mode, don't check package files\n" - " -a Thorough scan mode\n" - " -c=? Read this configuration file\n" - " -o=? Set an arbitrary configuration option, eg -o dir::cache=/tmp\n" - "See fstab(5)\n"; - return 0; + "apt-cdrom is used to add CDROM's, USB flashdrives and other removable\n" + "media types as package sources to APT. The mount point and device\n" + "information is taken from apt.conf(5), udev(7) and fstab(5).\n"); + return true; +} + /*}}}*/ +static std::vector GetCommands() /*{{{*/ +{ + return { + {"add", &DoAdd, "Add a CDROM"}, + {"ident", &DoIdent, "Report the identity of a CDROM"}, + {nullptr, nullptr, nullptr} + }; } /*}}}*/ 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',"recon","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}}; - CommandLine::Dispatch Cmds[] = { - {"add",&DoAdd}, - {"ident",&DoIdent}, - {0,0}}; - - // Set up gettext support - setlocale(LC_ALL,""); - textdomain(PACKAGE); - // Parse the command line and initialize the package library - CommandLine CmdL(Args,_config); - if (pkgInitConfig(*_config) == false || - CmdL.Parse(argc,argv) == false || - pkgInitSystem(*_config,_system) == false) - { - _error->DumpErrors(); - return 100; - } - - // See if the help should be shown - if (_config->FindB("help") == true || _config->FindB("version") == true || - CmdL.FileSize() == 0) - return ShowHelp(); + CommandLine CmdL; + auto const Cmds = ParseCommandLine(CmdL, APT_CMD::APT_CDROM, &_config, &_system, argc, argv, &ShowHelp, &GetCommands); - // Deal with stdout not being a tty - if (isatty(STDOUT_FILENO) && _config->FindI("quiet",0) < 1) - _config->Set("quiet","1"); - - // Match the operation - CmdL.DispatchArg(Cmds); + InitOutput(); - // 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; + return DispatchCommandLine(CmdL, Cmds); } /*}}}*/