1 // -*- mode: cpp; mode: fold -*-
3 // $Id: apt-cdrom.cc,v 1.45 2003/11/19 23:50:51 mdz Exp $
4 /* ######################################################################
6 APT CDROM - Tool for handling APT's CDROM database.
8 Currently the only option is 'add' which will take the current CD
9 in the drive and add it into the database.
11 ##################################################################### */
13 // Include Files /*{{{*/
16 #include <apt-pkg/cmndline.h>
17 #include <apt-pkg/error.h>
18 #include <apt-pkg/init.h>
19 #include <apt-pkg/fileutl.h>
20 #include <apt-pkg/progress.h>
21 #include <apt-pkg/cdromutl.h>
22 #include <apt-pkg/strutl.h>
23 #include <apt-pkg/cdrom.h>
24 #include <apt-pkg/configuration.h>
25 #include <apt-pkg/pkgsystem.h>
33 #include <apt-private/private-cmndline.h>
34 #include <apt-private/private-output.h>
35 #include <apt-private/private-main.h>
42 class pkgCdromTextStatus
: public pkgCdromStatus
/*{{{*/
45 OpTextProgress Progress
;
46 void Prompt(const char *Text
);
47 string
PromptLine(const char *Text
);
48 bool AskCdromName(string
&name
) APT_OVERRIDE
;
51 virtual void Update(string text
, int current
) APT_OVERRIDE
;
52 virtual bool ChangeCdrom() APT_OVERRIDE
;
53 virtual OpProgress
* GetOpProgress() APT_OVERRIDE
;
56 void pkgCdromTextStatus::Prompt(const char *Text
)
59 cout
<< Text
<< ' ' << flush
;
60 if (read(STDIN_FILENO
,&C
,1) < 0)
61 _error
->Errno("pkgCdromTextStatus::Prompt",
62 "Failed to read from standard input (not a terminal?)");
67 string
pkgCdromTextStatus::PromptLine(const char *Text
)
69 cout
<< Text
<< ':' << endl
;
76 bool pkgCdromTextStatus::AskCdromName(string
&name
)
78 cout
<< _("Please provide a name for this Disc, such as 'Debian 5.0.3 Disk 1'") << flush
;
79 name
= PromptLine("");
85 void pkgCdromTextStatus::Update(string text
, int /*current*/)
88 cout
<< text
<< flush
;
91 bool pkgCdromTextStatus::ChangeCdrom()
93 Prompt(_("Please insert a Disc in the drive and press [Enter]"));
97 APT_CONST OpProgress
* pkgCdromTextStatus::GetOpProgress()
102 // AddOrIdent - Add or Ident a CDROM /*{{{*/
103 static bool AddOrIdent(bool const Add
)
105 pkgUdevCdromDevices UdevCdroms
;
106 pkgCdromTextStatus log
;
109 bool oneSuccessful
= false;
110 bool AutoDetect
= _config
->FindB("Acquire::cdrom::AutoDetect", true);
111 if (AutoDetect
== true && UdevCdroms
.Dlopen() == true)
113 bool const Debug
= _config
->FindB("Debug::Acquire::cdrom", false);
114 std::string
const CDMount
= _config
->Find("Acquire::cdrom::mount");
115 bool const NoMount
= _config
->FindB("APT::CDROM::NoMount", false);
116 if (NoMount
== false)
117 _config
->Set("APT::CDROM::NoMount", true);
119 vector
<struct CdromDevice
> const v
= UdevCdroms
.Scan();
120 for (std::vector
<struct CdromDevice
>::const_iterator cd
= v
.begin(); cd
!= v
.end(); ++cd
)
123 clog
<< "Looking at device:"
124 << "\tDeviveName: '" << cd
->DeviceName
<< "'"
125 << "\tIsMounted: '" << cd
->Mounted
<< "'"
126 << "\tMountPoint: '" << cd
->MountPath
<< "'"
129 std::string AptMountPoint
;
131 _config
->Set("Acquire::cdrom::mount", cd
->MountPath
);
132 else if (NoMount
== true)
136 AptMountPoint
= _config
->FindDir("Dir::Media::MountPath");
137 if (FileExists(AptMountPoint
) == false)
138 mkdir(AptMountPoint
.c_str(), 0750);
139 if(MountCdrom(AptMountPoint
, cd
->DeviceName
) == false)
141 _error
->Warning(_("Failed to mount '%s' to '%s'"), cd
->DeviceName
.c_str(), AptMountPoint
.c_str());
144 _config
->Set("Acquire::cdrom::mount", AptMountPoint
);
147 _error
->PushToStack();
149 oneSuccessful
= cdrom
.Add(&log
);
153 oneSuccessful
= cdrom
.Ident(id
, &log
);
155 _error
->MergeWithStack();
157 if (AptMountPoint
.empty() == false)
158 UnmountCdrom(AptMountPoint
);
160 if (NoMount
== false)
161 _config
->Set("APT::CDROM::NoMount", NoMount
);
162 _config
->Set("Acquire::cdrom::mount", CDMount
);
165 // fallback if auto-detect didn't work
166 if (oneSuccessful
== false)
168 _error
->PushToStack();
170 oneSuccessful
= cdrom
.Add(&log
);
174 oneSuccessful
= cdrom
.Ident(id
, &log
);
176 _error
->MergeWithStack();
179 if (oneSuccessful
== false)
180 _error
->Error("%s", _("No CD-ROM could be auto-detected or found using the default mount point.\n"
181 "You may try the --cdrom option to set the CD-ROM mount point.\n"
182 "See 'man apt-cdrom' for more information about the CD-ROM auto-detection and mount point."));
183 else if (Add
== true)
184 cout
<< _("Repeat this process for the rest of the CDs in your set.") << endl
;
186 return oneSuccessful
;
189 // DoAdd - Add a new CDROM /*{{{*/
190 // ---------------------------------------------------------------------
191 /* This does the main add bit.. We show some status and things. The
192 sequence is to mount/umount the CD, Ident it then scan it for package
193 files and reduce that list. Then we copy over the package files and
194 verify them. Then rewrite the database files */
195 static bool DoAdd(CommandLine
&)
197 return AddOrIdent(true);
200 // DoIdent - Ident a CDROM /*{{{*/
201 static bool DoIdent(CommandLine
&)
203 return AddOrIdent(false);
206 static bool ShowHelp(CommandLine
&) /*{{{*/
209 _("Usage: apt-cdrom [options] command\n"
211 "apt-cdrom is used to add CDROM's, USB flashdrives and other removable\n"
212 "media types as package sources to APT. The mount point and device\n"
213 "information is taken from apt.conf(5), udev(7) and fstab(5).\n");
217 static std::vector
<aptDispatchWithHelp
> GetCommands() /*{{{*/
220 {"add", &DoAdd
, "Add a CDROM"},
221 {"ident", &DoIdent
, "Report the identity of a CDROM"},
222 {nullptr, nullptr, nullptr}
226 int main(int argc
,const char *argv
[]) /*{{{*/
228 // Parse the command line and initialize the package library
230 auto const Cmds
= ParseCommandLine(CmdL
, APT_CMD::APT_CDROM
, &_config
, &_system
, argc
, argv
, &ShowHelp
, &GetCommands
);
234 return DispatchCommandLine(CmdL
, Cmds
);