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>
37 static const char *W_NO_CDROM_FOUND
= \
38 N_("No CD-ROM could be auto-detected or found using "
39 "the default mount point.\n"
40 "You may try the --cdrom option to set the CD-ROM mount point. "
41 "See 'man apt-cdrom' for more "
42 "information about the CD-ROM auto-detection and mount point.");
46 class pkgCdromTextStatus
: public pkgCdromStatus
/*{{{*/
49 OpTextProgress Progress
;
50 void Prompt(const char *Text
);
51 string
PromptLine(const char *Text
);
52 bool AskCdromName(string
&name
);
55 virtual void Update(string text
, int current
);
56 virtual bool ChangeCdrom();
57 virtual OpProgress
* GetOpProgress();
60 void pkgCdromTextStatus::Prompt(const char *Text
)
63 cout
<< Text
<< ' ' << flush
;
64 if (read(STDIN_FILENO
,&C
,1) < 0)
65 _error
->Errno("pkgCdromTextStatus::Prompt",
66 "Failed to read from standard input (not a terminal?)");
71 string
pkgCdromTextStatus::PromptLine(const char *Text
)
73 cout
<< Text
<< ':' << endl
;
80 bool pkgCdromTextStatus::AskCdromName(string
&name
)
82 cout
<< _("Please provide a name for this Disc, such as 'Debian 5.0.3 Disk 1'") << flush
;
83 name
= PromptLine("");
89 void pkgCdromTextStatus::Update(string text
, int /*current*/)
92 cout
<< text
<< flush
;
95 bool pkgCdromTextStatus::ChangeCdrom()
97 Prompt(_("Please insert a Disc in the drive and press enter"));
101 APT_CONST OpProgress
* pkgCdromTextStatus::GetOpProgress()
106 // SetupAutoDetect /*{{{*/
107 static bool AutoDetectCdrom(pkgUdevCdromDevices
&UdevCdroms
, unsigned int &i
, bool &automounted
)
109 bool Debug
= _config
->FindB("Debug::Acquire::cdrom", false);
113 vector
<struct CdromDevice
> v
= UdevCdroms
.Scan();
118 clog
<< "Looking at devce " << i
119 << " DeviveName: " << v
[i
].DeviceName
120 << " IsMounted: '" << v
[i
].Mounted
<< "'"
121 << " MountPoint: '" << v
[i
].MountPath
<< "'"
126 // set the right options
127 _config
->Set("Acquire::cdrom::mount", v
[i
].MountPath
);
128 _config
->Set("APT::CDROM::NoMount", true);
130 string AptMountPoint
= _config
->FindDir("Dir::Media::MountPath");
131 if (!FileExists(AptMountPoint
))
132 mkdir(AptMountPoint
.c_str(), 0750);
133 if(MountCdrom(AptMountPoint
, v
[i
].DeviceName
) == false)
134 _error
->Warning(_("Failed to mount '%s' to '%s'"), v
[i
].DeviceName
.c_str(), AptMountPoint
.c_str());
137 _config
->Set("Acquire::cdrom::mount", AptMountPoint
);
138 _config
->Set("APT::CDROM::NoMount", true);
145 // DoAdd - Add a new CDROM /*{{{*/
146 // ---------------------------------------------------------------------
147 /* This does the main add bit.. We show some status and things. The
148 sequence is to mount/umount the CD, Ident it then scan it for package
149 files and reduce that list. Then we copy over the package files and
150 verify them. Then rewrite the database files */
151 static bool DoAdd(CommandLine
&)
153 pkgUdevCdromDevices UdevCdroms
;
154 pkgCdromTextStatus log
;
158 bool AutoDetect
= _config
->FindB("Acquire::cdrom::AutoDetect", true);
159 unsigned int count
= 0;
160 string AptMountPoint
= _config
->FindDir("Dir::Media::MountPath");
161 bool automounted
= false;
162 if (AutoDetect
&& UdevCdroms
.Dlopen())
163 while (AutoDetectCdrom(UdevCdroms
, count
, automounted
)) {
165 // begin loop with res false to detect any success using OR
169 // dump any warnings/errors from autodetect
170 if (_error
->empty() == false)
171 _error
->DumpErrors();
173 res
|= cdrom
.Add(&log
);
176 UnmountCdrom(AptMountPoint
);
178 // dump any warnings/errors from add/unmount
179 if (_error
->empty() == false)
180 _error
->DumpErrors();
184 res
= cdrom
.Add(&log
);
187 _error
->Error("%s", _(W_NO_CDROM_FOUND
));
189 cout
<< _("Repeat this process for the rest of the CDs in your set.") << endl
;
194 // DoIdent - Ident a CDROM /*{{{*/
195 // ---------------------------------------------------------------------
197 static bool DoIdent(CommandLine
&)
199 pkgUdevCdromDevices UdevCdroms
;
201 pkgCdromTextStatus log
;
205 bool AutoDetect
= _config
->FindB("Acquire::cdrom::AutoDetect", true);
207 unsigned int count
= 0;
208 string AptMountPoint
= _config
->FindDir("Dir::Media::MountPath");
209 bool automounted
= false;
210 if (AutoDetect
&& UdevCdroms
.Dlopen())
211 while (AutoDetectCdrom(UdevCdroms
, count
, automounted
)) {
213 // begin loop with res false to detect any success using OR
217 // dump any warnings/errors from autodetect
218 if (_error
->empty() == false)
219 _error
->DumpErrors();
221 res
|= cdrom
.Ident(ident
, &log
);
224 UnmountCdrom(AptMountPoint
);
226 // dump any warnings/errors from add/unmount
227 if (_error
->empty() == false)
228 _error
->DumpErrors();
232 res
= cdrom
.Ident(ident
, &log
);
235 _error
->Error("%s", _(W_NO_CDROM_FOUND
));
240 // ShowHelp - Show the help screen /*{{{*/
241 // ---------------------------------------------------------------------
243 static bool ShowHelp(CommandLine
&)
245 ioprintf(cout
,_("%s %s for %s compiled on %s %s\n"),PACKAGE
,PACKAGE_VERSION
,
246 COMMON_ARCH
,__DATE__
,__TIME__
);
247 if (_config
->FindB("version") == true)
251 "Usage: apt-cdrom [options] command\n"
253 "apt-cdrom is a tool to add CDROM's to APT's source list. The\n"
254 "CDROM mount point and device information is taken from apt.conf\n"
258 " add - Add a CDROM\n"
259 " ident - Report the identity of a CDROM\n"
262 " -h This help text\n"
263 " -d CD-ROM mount point\n"
264 " -r Rename a recognized CD-ROM\n"
266 " -f Fast mode, don't check package files\n"
267 " -a Thorough scan mode\n"
268 " --no-auto-detect Do not try to auto detect drive and mount point\n"
269 " -c=? Read this configuration file\n"
270 " -o=? Set an arbitrary configuration option, eg -o dir::cache=/tmp\n"
275 int main(int argc
,const char *argv
[]) /*{{{*/
277 CommandLine::Dispatch Cmds
[] = {
283 std::vector
<CommandLine::Args
> Args
= getCommandArgs("apt-cdrom", CommandLine::GetCommand(Cmds
, argc
, argv
));
285 // Set up gettext support
286 setlocale(LC_ALL
,"");
289 // Parse the command line and initialize the package library
290 CommandLine
CmdL(Args
.data(),_config
);
291 if (pkgInitConfig(*_config
) == false ||
292 CmdL
.Parse(argc
,argv
) == false ||
293 pkgInitSystem(*_config
,_system
) == false)
295 _error
->DumpErrors();
299 // See if the help should be shown
300 if (_config
->FindB("help") == true || _config
->FindB("version") == true ||
301 CmdL
.FileSize() == 0)
302 return ShowHelp(CmdL
);
304 // Deal with stdout not being a tty
305 if (isatty(STDOUT_FILENO
) && _config
->FindI("quiet", -1) == -1)
306 _config
->Set("quiet","1");
308 // Match the operation
309 CmdL
.DispatchArg(Cmds
);
311 // Print any errors or warnings found during parsing
312 bool const Errors
= _error
->PendingError();
313 if (_config
->FindI("quiet",0) > 0)
314 _error
->DumpErrors();
316 _error
->DumpErrors(GlobalError::DEBUG
);
317 return Errors
== true ? 100 : 0;