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/acquire.h>
24 #include <apt-pkg/acquire-item.h>
25 #include <apt-pkg/cdrom.h>
26 #include <apt-pkg/configuration.h>
27 #include <apt-pkg/pkgsystem.h>
40 #include <apt-private/private-cmndline.h>
44 static const char *W_NO_CDROM_FOUND
= \
45 N_("No CD-ROM could be auto-detected or found using "
46 "the default mount point.\n"
47 "You may try the --cdrom option to set the CD-ROM mount point. "
48 "See 'man apt-cdrom' for more "
49 "information about the CD-ROM auto-detection and mount point.");
53 class pkgCdromTextStatus
: public pkgCdromStatus
/*{{{*/
56 OpTextProgress Progress
;
57 void Prompt(const char *Text
);
58 string
PromptLine(const char *Text
);
59 bool AskCdromName(string
&name
);
62 virtual void Update(string text
, int current
);
63 virtual bool ChangeCdrom();
64 virtual OpProgress
* GetOpProgress();
67 void pkgCdromTextStatus::Prompt(const char *Text
)
70 cout
<< Text
<< ' ' << flush
;
71 if (read(STDIN_FILENO
,&C
,1) < 0)
72 _error
->Errno("pkgCdromTextStatus::Prompt",
73 "Failed to read from standard input (not a terminal?)");
78 string
pkgCdromTextStatus::PromptLine(const char *Text
)
80 cout
<< Text
<< ':' << endl
;
87 bool pkgCdromTextStatus::AskCdromName(string
&name
)
89 cout
<< _("Please provide a name for this Disc, such as 'Debian 5.0.3 Disk 1'") << flush
;
90 name
= PromptLine("");
96 void pkgCdromTextStatus::Update(string text
, int current
)
99 cout
<< text
<< flush
;
102 bool pkgCdromTextStatus::ChangeCdrom()
104 Prompt(_("Please insert a Disc in the drive and press enter"));
108 OpProgress
* pkgCdromTextStatus::GetOpProgress()
113 // SetupAutoDetect /*{{{*/
114 bool AutoDetectCdrom(pkgUdevCdromDevices
&UdevCdroms
, unsigned int &i
, bool &automounted
)
116 bool Debug
= _config
->FindB("Debug::Acquire::cdrom", false);
120 vector
<struct CdromDevice
> v
= UdevCdroms
.Scan();
125 clog
<< "Looking at devce " << i
126 << " DeviveName: " << v
[i
].DeviceName
127 << " IsMounted: '" << v
[i
].Mounted
<< "'"
128 << " MountPoint: '" << v
[i
].MountPath
<< "'"
133 // set the right options
134 _config
->Set("Acquire::cdrom::mount", v
[i
].MountPath
);
135 _config
->Set("APT::CDROM::NoMount", true);
137 string AptMountPoint
= _config
->FindDir("Dir::Media::MountPath");
138 if (!FileExists(AptMountPoint
))
139 mkdir(AptMountPoint
.c_str(), 0750);
140 if(MountCdrom(AptMountPoint
, v
[i
].DeviceName
) == false)
141 _error
->Warning(_("Failed to mount '%s' to '%s'"), v
[i
].DeviceName
.c_str(), AptMountPoint
.c_str());
144 _config
->Set("Acquire::cdrom::mount", AptMountPoint
);
145 _config
->Set("APT::CDROM::NoMount", true);
152 // DoAdd - Add a new CDROM /*{{{*/
153 // ---------------------------------------------------------------------
154 /* This does the main add bit.. We show some status and things. The
155 sequence is to mount/umount the CD, Ident it then scan it for package
156 files and reduce that list. Then we copy over the package files and
157 verify them. Then rewrite the database files */
158 bool DoAdd(CommandLine
&)
160 pkgUdevCdromDevices UdevCdroms
;
161 pkgCdromTextStatus log
;
165 bool AutoDetect
= _config
->FindB("Acquire::cdrom::AutoDetect", true);
166 unsigned int count
= 0;
167 string AptMountPoint
= _config
->FindDir("Dir::Media::MountPath");
168 bool automounted
= false;
169 if (AutoDetect
&& UdevCdroms
.Dlopen())
170 while (AutoDetectCdrom(UdevCdroms
, count
, automounted
)) {
172 // begin loop with res false to detect any success using OR
176 // dump any warnings/errors from autodetect
177 if (_error
->empty() == false)
178 _error
->DumpErrors();
180 res
|= cdrom
.Add(&log
);
183 UnmountCdrom(AptMountPoint
);
185 // dump any warnings/errors from add/unmount
186 if (_error
->empty() == false)
187 _error
->DumpErrors();
191 res
= cdrom
.Add(&log
);
194 _error
->Error("%s", _(W_NO_CDROM_FOUND
));
196 cout
<< _("Repeat this process for the rest of the CDs in your set.") << endl
;
201 // DoIdent - Ident a CDROM /*{{{*/
202 // ---------------------------------------------------------------------
204 bool DoIdent(CommandLine
&)
206 pkgUdevCdromDevices UdevCdroms
;
208 pkgCdromTextStatus log
;
212 bool AutoDetect
= _config
->FindB("Acquire::cdrom::AutoDetect", true);
214 unsigned int count
= 0;
215 string AptMountPoint
= _config
->FindDir("Dir::Media::MountPath");
216 bool automounted
= false;
217 if (AutoDetect
&& UdevCdroms
.Dlopen())
218 while (AutoDetectCdrom(UdevCdroms
, count
, automounted
)) {
220 // begin loop with res false to detect any success using OR
224 // dump any warnings/errors from autodetect
225 if (_error
->empty() == false)
226 _error
->DumpErrors();
228 res
|= cdrom
.Ident(ident
, &log
);
231 UnmountCdrom(AptMountPoint
);
233 // dump any warnings/errors from add/unmount
234 if (_error
->empty() == false)
235 _error
->DumpErrors();
239 res
= cdrom
.Ident(ident
, &log
);
242 _error
->Error("%s", _(W_NO_CDROM_FOUND
));
247 // ShowHelp - Show the help screen /*{{{*/
248 // ---------------------------------------------------------------------
250 bool ShowHelp(CommandLine
&)
252 ioprintf(cout
,_("%s %s for %s compiled on %s %s\n"),PACKAGE
,PACKAGE_VERSION
,
253 COMMON_ARCH
,__DATE__
,__TIME__
);
254 if (_config
->FindB("version") == true)
258 "Usage: apt-cdrom [options] command\n"
260 "apt-cdrom is a tool to add CDROM's to APT's source list. The\n"
261 "CDROM mount point and device information is taken from apt.conf\n"
265 " add - Add a CDROM\n"
266 " ident - Report the identity of a CDROM\n"
269 " -h This help text\n"
270 " -d CD-ROM mount point\n"
271 " -r Rename a recognized CD-ROM\n"
273 " -f Fast mode, don't check package files\n"
274 " -a Thorough scan mode\n"
275 " --no-auto-detect Do not try to auto detect drive and mount point\n"
276 " -c=? Read this configuration file\n"
277 " -o=? Set an arbitrary configuration option, eg -o dir::cache=/tmp\n"
282 int main(int argc
,const char *argv
[]) /*{{{*/
284 CommandLine::Dispatch Cmds
[] = {
290 std::vector
<CommandLine::Args
> Args
= getCommandArgs("apt-cdrom", CommandLine::GetCommand(Cmds
, argc
, argv
));
292 // Set up gettext support
293 setlocale(LC_ALL
,"");
296 // Parse the command line and initialize the package library
297 CommandLine
CmdL(Args
.data(),_config
);
298 if (pkgInitConfig(*_config
) == false ||
299 CmdL
.Parse(argc
,argv
) == false ||
300 pkgInitSystem(*_config
,_system
) == false)
302 _error
->DumpErrors();
306 // See if the help should be shown
307 if (_config
->FindB("help") == true || _config
->FindB("version") == true ||
308 CmdL
.FileSize() == 0)
309 return ShowHelp(CmdL
);
311 // Deal with stdout not being a tty
312 if (isatty(STDOUT_FILENO
) && _config
->FindI("quiet", -1) == -1)
313 _config
->Set("quiet","1");
315 // Match the operation
316 CmdL
.DispatchArg(Cmds
);
318 // Print any errors or warnings found during parsing
319 bool const Errors
= _error
->PendingError();
320 if (_config
->FindI("quiet",0) > 0)
321 _error
->DumpErrors();
323 _error
->DumpErrors(GlobalError::DEBUG
);
324 return Errors
== true ? 100 : 0;