#include <apt-pkg/progress.h>
#include <apt-pkg/cdromutl.h>
#include <apt-pkg/strutl.h>
-#include <apt-pkg/acquire.h>
-#include <apt-pkg/acquire-item.h>
#include <apt-pkg/cdrom.h>
#include <apt-pkg/configuration.h>
#include <apt-pkg/pkgsystem.h>
-#include <locale.h>
#include <iostream>
-#include <fstream>
#include <vector>
-#include <algorithm>
+#include <string>
#include <sys/stat.h>
-#include <fcntl.h>
-#include <dirent.h>
#include <unistd.h>
-#include <stdio.h>
+
+#include <apt-private/private-cmndline.h>
+#include <apt-private/private-output.h>
+#include <apt-private/private-main.h>
#include <apti18n.h>
/*}}}*/
{
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;
}
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;
+}
/*}}}*/
-// SetupAutoDetect /*{{{*/
-bool AutoDetectCdrom(pkgUdevCdromDevices &UdevCdroms, unsigned int &i)
+// AddOrIdent - Add or Ident a CDROM /*{{{*/
+static bool AddOrIdent(bool const Add)
{
- bool Debug = _config->FindB("Debug::Acquire::cdrom", false);
-
- vector<struct CdromDevice> v = UdevCdroms.Scan();
- if (i >= v.size())
- return false;
+ pkgUdevCdromDevices UdevCdroms;
+ pkgCdromTextStatus log;
+ pkgCdrom cdrom;
- if (Debug)
- clog << "Looking at devce " << i
- << " DeviveName: " << v[i].DeviceName
- << " IsMounted: '" << v[i].Mounted << "'"
- << " MountPoint: '" << v[i].MountPath << "'"
- << endl;
+ 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<struct CdromDevice> const v = UdevCdroms.Scan();
+ for (std::vector<struct CdromDevice>::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);
+ }
- if (v[i].Mounted)
+ // fallback if auto-detect didn't work
+ if (oneSuccessful == false)
{
- // set the right options
- _config->Set("Acquire::cdrom::mount", v[i].MountPath);
- _config->Set("APT::CDROM::NoMount", true);
- } else {
- string AptMountPoint = _config->FindDir("Dir::Media::MountPath");
- if (!FileExists(AptMountPoint))
- mkdir(AptMountPoint.c_str(), 0750);
- if(MountCdrom(AptMountPoint, v[i].DeviceName) == false)
- _error->Warning(_("Failed to mount '%s' to '%s'"), v[i].DeviceName.c_str(), AptMountPoint.c_str());
- _config->Set("Acquire::cdrom::mount", AptMountPoint);
- _config->Set("APT::CDROM::NoMount", true);
+ _error->PushToStack();
+ if (Add == true)
+ oneSuccessful = cdrom.Add(&log);
+ else
+ {
+ std::string id;
+ oneSuccessful = cdrom.Ident(id, &log);
+ }
+ _error->MergeWithStack();
}
- i++;
- return true;
+ 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 &)
{
- pkgUdevCdromDevices UdevCdroms;
- pkgCdromTextStatus log;
- pkgCdrom cdrom;
- bool res = true;
-
- bool AutoDetect = _config->FindB("Acquire::cdrom::AutoDetect", true);
- if (AutoDetect && UdevCdroms.Dlopen())
- {
- unsigned int count = 0;
- while (AutoDetectCdrom(UdevCdroms, count))
- res &= cdrom.Add(&log);
- } else {
- 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 &)
{
- pkgUdevCdromDevices UdevCdroms;
- string ident;
- pkgCdromTextStatus log;
- pkgCdrom cdrom;
- bool res = true;
-
- bool AutoDetect = _config->FindB("Acquire::cdrom::AutoDetect");
-
- if (AutoDetect && UdevCdroms.Dlopen())
- {
- unsigned int count = 0;
- while (AutoDetectCdrom(UdevCdroms, count))
- res &= cdrom.Ident(ident, &log);
- } else {
- return cdrom.Ident(ident, &log);
- }
-
- return res;
+ 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"
- " --auto-detect Auto detect drive and mount point\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<aptDispatchWithHelp> 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},
- { 0,"auto-detect","Acquire::cdrom::AutoDetect",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", -1) == -1)
- _config->Set("quiet","1");
-
- // Match the operation
- CmdL.DispatchArg(Cmds);
+ InitOutput();
- // Print any errors or warnings found during parsing
- bool const Errors = _error->PendingError();
- if (_config->FindI("quiet",0) > 0)
- _error->DumpErrors();
- else
- _error->DumpErrors(GlobalError::DEBUG);
- return Errors == true ? 100 : 0;
+ return DispatchCommandLine(CmdL, Cmds);
}
/*}}}*/