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>
42 static const char *W_NO_CDROM_FOUND
= \
43 N_("No CD-ROM could be auto-detected or found using "
44 "the default mount point.\n"
45 "You may try the --cdrom option to set the CD-ROM mount point. "
46 "See 'man apt-cdrom' for more "
47 "information about the CD-ROM auto-detection and mount point.");
51 class pkgCdromTextStatus
: public pkgCdromStatus
/*{{{*/
54 OpTextProgress Progress
;
55 void Prompt(const char *Text
);
56 string
PromptLine(const char *Text
);
57 bool AskCdromName(string
&name
);
60 virtual void Update(string text
, int current
);
61 virtual bool ChangeCdrom();
62 virtual OpProgress
* GetOpProgress();
65 void pkgCdromTextStatus::Prompt(const char *Text
)
68 cout
<< Text
<< ' ' << flush
;
69 if (read(STDIN_FILENO
,&C
,1) < 0)
70 _error
->Errno("pkgCdromTextStatus::Prompt", "failed to prompt");
75 string
pkgCdromTextStatus::PromptLine(const char *Text
)
77 cout
<< Text
<< ':' << endl
;
84 bool pkgCdromTextStatus::AskCdromName(string
&name
)
86 cout
<< _("Please provide a name for this Disc, such as 'Debian 5.0.3 Disk 1'") << flush
;
87 name
= PromptLine("");
93 void pkgCdromTextStatus::Update(string text
, int current
)
96 cout
<< text
<< flush
;
99 bool pkgCdromTextStatus::ChangeCdrom()
101 Prompt(_("Please insert a Disc in the drive and press enter"));
105 OpProgress
* pkgCdromTextStatus::GetOpProgress()
110 // SetupAutoDetect /*{{{*/
111 bool AutoDetectCdrom(pkgUdevCdromDevices
&UdevCdroms
, unsigned int &i
)
113 bool Debug
= _config
->FindB("Debug::Acquire::cdrom", false);
115 vector
<struct CdromDevice
> v
= UdevCdroms
.Scan();
120 clog
<< "Looking at devce " << i
121 << " DeviveName: " << v
[i
].DeviceName
122 << " IsMounted: '" << v
[i
].Mounted
<< "'"
123 << " MountPoint: '" << v
[i
].MountPath
<< "'"
128 // set the right options
129 _config
->Set("Acquire::cdrom::mount", v
[i
].MountPath
);
130 _config
->Set("APT::CDROM::NoMount", true);
132 string AptMountPoint
= _config
->FindDir("Dir::Media::MountPath");
133 if (!FileExists(AptMountPoint
))
134 mkdir(AptMountPoint
.c_str(), 0750);
135 if(MountCdrom(AptMountPoint
, v
[i
].DeviceName
) == false)
136 _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 bool DoAdd(CommandLine
&)
153 pkgUdevCdromDevices UdevCdroms
;
154 pkgCdromTextStatus log
;
158 bool AutoDetect
= _config
->FindB("Acquire::cdrom::AutoDetect", true);
159 unsigned int count
= 0;
160 if (AutoDetect
&& UdevCdroms
.Dlopen())
161 while (AutoDetectCdrom(UdevCdroms
, count
))
162 res
&= cdrom
.Add(&log
);
164 res
= cdrom
.Add(&log
);
166 _error
->Error("%s", _(W_NO_CDROM_FOUND
));
171 cout
<< _("Repeat this process for the rest of the CDs in your set.") << endl
;
176 // DoIdent - Ident a CDROM /*{{{*/
177 // ---------------------------------------------------------------------
179 bool DoIdent(CommandLine
&)
181 pkgUdevCdromDevices UdevCdroms
;
183 pkgCdromTextStatus log
;
187 bool AutoDetect
= _config
->FindB("Acquire::cdrom::AutoDetect");
189 unsigned int count
= 0;
190 if (AutoDetect
&& UdevCdroms
.Dlopen())
191 while (AutoDetectCdrom(UdevCdroms
, count
))
192 res
&= cdrom
.Ident(ident
, &log
);
194 res
= cdrom
.Ident(ident
, &log
);
196 _error
->Error("%s", _(W_NO_CDROM_FOUND
));
202 // ShowHelp - Show the help screen /*{{{*/
203 // ---------------------------------------------------------------------
207 ioprintf(cout
,_("%s %s for %s compiled on %s %s\n"),PACKAGE
,PACKAGE_VERSION
,
208 COMMON_ARCH
,__DATE__
,__TIME__
);
209 if (_config
->FindB("version") == true)
213 "Usage: apt-cdrom [options] command\n"
215 "apt-cdrom is a tool to add CDROM's to APT's source list. The\n"
216 "CDROM mount point and device information is taken from apt.conf\n"
220 " add - Add a CDROM\n"
221 " ident - Report the identity of a CDROM\n"
224 " -h This help text\n"
225 " -d CD-ROM mount point\n"
226 " -r Rename a recognized CD-ROM\n"
228 " -f Fast mode, don't check package files\n"
229 " -a Thorough scan mode\n"
230 " --no-auto-detect Do not try to auto detect drive and mount point\n"
231 " -c=? Read this configuration file\n"
232 " -o=? Set an arbitrary configuration option, eg -o dir::cache=/tmp\n"
237 int main(int argc
,const char *argv
[]) /*{{{*/
239 CommandLine::Args Args
[] = {
240 {'h',"help","help",0},
241 { 0,"auto-detect","Acquire::cdrom::AutoDetect", CommandLine::Boolean
},
242 {'v',"version","version",0},
243 {'d',"cdrom","Acquire::cdrom::mount",CommandLine::HasArg
},
244 {'r',"rename","APT::CDROM::Rename",0},
245 {'m',"no-mount","APT::CDROM::NoMount",0},
246 {'f',"fast","APT::CDROM::Fast",0},
247 {'n',"just-print","APT::CDROM::NoAct",0},
248 {'n',"recon","APT::CDROM::NoAct",0},
249 {'n',"no-act","APT::CDROM::NoAct",0},
250 {'a',"thorough","APT::CDROM::Thorough",0},
251 {'c',"config-file",0,CommandLine::ConfigFile
},
252 {'o',"option",0,CommandLine::ArbItem
},
254 CommandLine::Dispatch Cmds
[] = {
259 // Set up gettext support
260 setlocale(LC_ALL
,"");
263 // Parse the command line and initialize the package library
264 CommandLine
CmdL(Args
,_config
);
265 if (pkgInitConfig(*_config
) == false ||
266 CmdL
.Parse(argc
,argv
) == false ||
267 pkgInitSystem(*_config
,_system
) == false)
269 _error
->DumpErrors();
273 // See if the help should be shown
274 if (_config
->FindB("help") == true || _config
->FindB("version") == true ||
275 CmdL
.FileSize() == 0)
278 // Deal with stdout not being a tty
279 if (isatty(STDOUT_FILENO
) && _config
->FindI("quiet", -1) == -1)
280 _config
->Set("quiet","1");
282 // Match the operation
283 CmdL
.DispatchArg(Cmds
);
285 // Print any errors or warnings found during parsing
286 bool const Errors
= _error
->PendingError();
287 if (_config
->FindI("quiet",0) > 0)
288 _error
->DumpErrors();
290 _error
->DumpErrors(GlobalError::DEBUG
);
291 return Errors
== true ? 100 : 0;