warning: non-ISO-standard escape sequence, '\e' [enabled by default]
[ntk/apt.git] / cmdline / apt-cdrom.cc
CommitLineData
83d89a9f
AL
1// -*- mode: cpp; mode: fold -*-
2// Description /*{{{*/
a3f6ea20 3// $Id: apt-cdrom.cc,v 1.45 2003/11/19 23:50:51 mdz Exp $
83d89a9f
AL
4/* ######################################################################
5
18444708
AL
6 APT CDROM - Tool for handling APT's CDROM database.
7
8 Currently the only option is 'add' which will take the current CD
9 in the drive and add it into the database.
83d89a9f
AL
10
11 ##################################################################### */
12 /*}}}*/
13// Include Files /*{{{*/
ea542140
DK
14#include<config.h>
15
83d89a9f
AL
16#include <apt-pkg/cmndline.h>
17#include <apt-pkg/error.h>
18#include <apt-pkg/init.h>
83d89a9f
AL
19#include <apt-pkg/fileutl.h>
20#include <apt-pkg/progress.h>
65ae8fab 21#include <apt-pkg/cdromutl.h>
cdcc6d34 22#include <apt-pkg/strutl.h>
a75c6a6e
MZ
23#include <apt-pkg/acquire.h>
24#include <apt-pkg/acquire-item.h>
25#include <apt-pkg/cdrom.h>
472ff00e
DK
26#include <apt-pkg/configuration.h>
27#include <apt-pkg/pkgsystem.h>
143abaeb 28
233c2b66 29#include <locale.h>
83d89a9f 30#include <iostream>
18444708 31#include <fstream>
83d89a9f
AL
32#include <vector>
33#include <algorithm>
83d89a9f
AL
34#include <sys/stat.h>
35#include <fcntl.h>
36#include <dirent.h>
37#include <unistd.h>
38#include <stdio.h>
ea542140 39
b9179170
MV
40#include <apt-private/private-cmndline.h>
41
ea542140 42#include <apti18n.h>
83d89a9f 43 /*}}}*/
0a83556b
MV
44static const char *W_NO_CDROM_FOUND = \
45 N_("No CD-ROM could be auto-detected or found using "
9d0c9e70
MV
46 "the default mount point.\n"
47 "You may try the --cdrom option to set the CD-ROM mount point. "
0a83556b 48 "See 'man apt-cdrom' for more "
9d0c9e70 49 "information about the CD-ROM auto-detection and mount point.");
83d89a9f 50
076d01b0
AL
51using namespace std;
52
92fcbfc1 53class pkgCdromTextStatus : public pkgCdromStatus /*{{{*/
83d89a9f 54{
a75c6a6e
MZ
55protected:
56 OpTextProgress Progress;
57 void Prompt(const char *Text);
58 string PromptLine(const char *Text);
59 bool AskCdromName(string &name);
60
61public:
62 virtual void Update(string text, int current);
63 virtual bool ChangeCdrom();
64 virtual OpProgress* GetOpProgress();
8a579291 65};
83d89a9f 66
a75c6a6e 67void pkgCdromTextStatus::Prompt(const char *Text)
83d89a9f 68{
a75c6a6e
MZ
69 char C;
70 cout << Text << ' ' << flush;
f52037d6 71 if (read(STDIN_FILENO,&C,1) < 0)
7dd5854b
MV
72 _error->Errno("pkgCdromTextStatus::Prompt",
73 "Failed to read from standard input (not a terminal?)");
a75c6a6e
MZ
74 if (C != '\n')
75 cout << endl;
83d89a9f 76}
4dfaa253 77
a75c6a6e 78string pkgCdromTextStatus::PromptLine(const char *Text)
83d89a9f 79{
a75c6a6e 80 cout << Text << ':' << endl;
83d89a9f 81
a75c6a6e
MZ
82 string Res;
83 getline(cin,Res);
83d89a9f
AL
84 return Res;
85}
18444708 86
a75c6a6e 87bool pkgCdromTextStatus::AskCdromName(string &name)
83d89a9f 88{
cdd5a135 89 cout << _("Please provide a name for this Disc, such as 'Debian 5.0.3 Disk 1'") << flush;
a75c6a6e 90 name = PromptLine("");
83d89a9f 91
83d89a9f
AL
92 return true;
93}
83d89a9f 94
83d89a9f 95
a75c6a6e 96void pkgCdromTextStatus::Update(string text, int current)
18444708 97{
a75c6a6e
MZ
98 if(text.size() > 0)
99 cout << text << flush;
18444708 100}
4dfaa253 101
8a579291 102bool pkgCdromTextStatus::ChangeCdrom()
83d89a9f 103{
4a5e5089 104 Prompt(_("Please insert a Disc in the drive and press enter"));
18444708
AL
105 return true;
106}
83d89a9f 107
8a579291 108OpProgress* pkgCdromTextStatus::GetOpProgress()
a75c6a6e
MZ
109{
110 return &Progress;
111};
83d89a9f 112 /*}}}*/
169413dc 113// SetupAutoDetect /*{{{*/
62dcbf84 114bool AutoDetectCdrom(pkgUdevCdromDevices &UdevCdroms, unsigned int &i, bool &automounted)
169413dc
MV
115{
116 bool Debug = _config->FindB("Debug::Acquire::cdrom", false);
117
62dcbf84
JO
118 automounted = false;
119
169413dc
MV
120 vector<struct CdromDevice> v = UdevCdroms.Scan();
121 if (i >= v.size())
122 return false;
123
124 if (Debug)
125 clog << "Looking at devce " << i
126 << " DeviveName: " << v[i].DeviceName
127 << " IsMounted: '" << v[i].Mounted << "'"
128 << " MountPoint: '" << v[i].MountPath << "'"
129 << endl;
130
131 if (v[i].Mounted)
132 {
133 // set the right options
134 _config->Set("Acquire::cdrom::mount", v[i].MountPath);
135 _config->Set("APT::CDROM::NoMount", true);
136 } else {
ffee221b 137 string AptMountPoint = _config->FindDir("Dir::Media::MountPath");
fb503892 138 if (!FileExists(AptMountPoint))
ffee221b 139 mkdir(AptMountPoint.c_str(), 0750);
fb503892 140 if(MountCdrom(AptMountPoint, v[i].DeviceName) == false)
ffee221b 141 _error->Warning(_("Failed to mount '%s' to '%s'"), v[i].DeviceName.c_str(), AptMountPoint.c_str());
62dcbf84
JO
142 else
143 automounted = true;
fb503892 144 _config->Set("Acquire::cdrom::mount", AptMountPoint);
169413dc
MV
145 _config->Set("APT::CDROM::NoMount", true);
146 }
147 i++;
148
149 return true;
150}
151 /*}}}*/
83d89a9f
AL
152// DoAdd - Add a new CDROM /*{{{*/
153// ---------------------------------------------------------------------
4dfaa253
AL
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 */
83d89a9f
AL
158bool DoAdd(CommandLine &)
159{
169413dc 160 pkgUdevCdromDevices UdevCdroms;
a75c6a6e
MZ
161 pkgCdromTextStatus log;
162 pkgCdrom cdrom;
fb503892 163 bool res = true;
169413dc 164
4df70e75 165 bool AutoDetect = _config->FindB("Acquire::cdrom::AutoDetect", true);
2ecf54d8 166 unsigned int count = 0;
62dcbf84
JO
167 string AptMountPoint = _config->FindDir("Dir::Media::MountPath");
168 bool automounted = false;
169413dc 169 if (AutoDetect && UdevCdroms.Dlopen())
62dcbf84
JO
170 while (AutoDetectCdrom(UdevCdroms, count, automounted)) {
171 if (count == 1) {
172 // begin loop with res false to detect any success using OR
173 res = false;
174 }
175
176 // dump any warnings/errors from autodetect
177 if (_error->empty() == false)
178 _error->DumpErrors();
179
180 res |= cdrom.Add(&log);
181
182 if (automounted)
183 UnmountCdrom(AptMountPoint);
184
185 // dump any warnings/errors from add/unmount
186 if (_error->empty() == false)
187 _error->DumpErrors();
0a83556b 188 }
169413dc 189
62dcbf84
JO
190 if (count == 0)
191 res = cdrom.Add(&log);
192
193 if (res == false)
194 _error->Error("%s", _(W_NO_CDROM_FOUND));
195 else
4a5e5089 196 cout << _("Repeat this process for the rest of the CDs in your set.") << endl;
169413dc 197
a75c6a6e 198 return res;
83d89a9f
AL
199}
200 /*}}}*/
b2e465d6
AL
201// DoIdent - Ident a CDROM /*{{{*/
202// ---------------------------------------------------------------------
203/* */
204bool DoIdent(CommandLine &)
205{
169413dc 206 pkgUdevCdromDevices UdevCdroms;
a75c6a6e
MZ
207 string ident;
208 pkgCdromTextStatus log;
209 pkgCdrom cdrom;
169413dc
MV
210 bool res = true;
211
62dcbf84 212 bool AutoDetect = _config->FindB("Acquire::cdrom::AutoDetect", true);
785412cf 213
2ecf54d8 214 unsigned int count = 0;
62dcbf84
JO
215 string AptMountPoint = _config->FindDir("Dir::Media::MountPath");
216 bool automounted = false;
169413dc 217 if (AutoDetect && UdevCdroms.Dlopen())
62dcbf84
JO
218 while (AutoDetectCdrom(UdevCdroms, count, automounted)) {
219 if (count == 1) {
220 // begin loop with res false to detect any success using OR
221 res = false;
222 }
223
224 // dump any warnings/errors from autodetect
225 if (_error->empty() == false)
226 _error->DumpErrors();
227
228 res |= cdrom.Ident(ident, &log);
229
230 if (automounted)
231 UnmountCdrom(AptMountPoint);
232
233 // dump any warnings/errors from add/unmount
234 if (_error->empty() == false)
235 _error->DumpErrors();
0a83556b 236 }
62dcbf84
JO
237
238 if (count == 0)
239 res = cdrom.Ident(ident, &log);
240
241 if (res == false)
242 _error->Error("%s", _(W_NO_CDROM_FOUND));
243
169413dc 244 return res;
b2e465d6
AL
245}
246 /*}}}*/
83d89a9f
AL
247// ShowHelp - Show the help screen /*{{{*/
248// ---------------------------------------------------------------------
249/* */
b9179170 250bool ShowHelp(CommandLine &)
83d89a9f 251{
9179f697 252 ioprintf(cout,_("%s %s for %s compiled on %s %s\n"),PACKAGE,PACKAGE_VERSION,
5b28c804 253 COMMON_ARCH,__DATE__,__TIME__);
04aa15a8 254 if (_config->FindB("version") == true)
b9179170 255 return true;
b2e465d6
AL
256
257 cout <<
258 "Usage: apt-cdrom [options] command\n"
259 "\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"
262 "and /etc/fstab.\n"
263 "\n"
264 "Commands:\n"
265 " add - Add a CDROM\n"
266 " ident - Report the identity of a CDROM\n"
267 "\n"
268 "Options:\n"
269 " -h This help text\n"
270 " -d CD-ROM mount point\n"
271 " -r Rename a recognized CD-ROM\n"
272 " -m No mounting\n"
273 " -f Fast mode, don't check package files\n"
274 " -a Thorough scan mode\n"
0a83556b 275 " --no-auto-detect Do not try to auto detect drive and mount point\n"
b2e465d6 276 " -c=? Read this configuration file\n"
a2884e32 277 " -o=? Set an arbitrary configuration option, eg -o dir::cache=/tmp\n"
b2e465d6 278 "See fstab(5)\n";
b9179170 279 return true;
83d89a9f
AL
280}
281 /*}}}*/
92fcbfc1 282int main(int argc,const char *argv[]) /*{{{*/
83d89a9f 283{
83d89a9f
AL
284 CommandLine::Dispatch Cmds[] = {
285 {"add",&DoAdd},
b2e465d6 286 {"ident",&DoIdent},
b9179170 287 {"help",&ShowHelp},
83d89a9f 288 {0,0}};
67111687 289
b9179170
MV
290 std::vector<CommandLine::Args> Args = getCommandArgs("apt-cdrom", CommandLine::GetCommand(Cmds, argc, argv));
291
67111687
AL
292 // Set up gettext support
293 setlocale(LC_ALL,"");
294 textdomain(PACKAGE);
295
83d89a9f 296 // Parse the command line and initialize the package library
b9179170 297 CommandLine CmdL(Args.data(),_config);
b2e465d6
AL
298 if (pkgInitConfig(*_config) == false ||
299 CmdL.Parse(argc,argv) == false ||
300 pkgInitSystem(*_config,_system) == false)
83d89a9f
AL
301 {
302 _error->DumpErrors();
303 return 100;
304 }
305
306 // See if the help should be shown
5633a7c2 307 if (_config->FindB("help") == true || _config->FindB("version") == true ||
83d89a9f 308 CmdL.FileSize() == 0)
b9179170 309 return ShowHelp(CmdL);
a9a5908d
AL
310
311 // Deal with stdout not being a tty
c340d185 312 if (isatty(STDOUT_FILENO) && _config->FindI("quiet", -1) == -1)
a9a5908d 313 _config->Set("quiet","1");
83d89a9f
AL
314
315 // Match the operation
316 CmdL.DispatchArg(Cmds);
317
318 // Print any errors or warnings found during parsing
65beb572
DK
319 bool const Errors = _error->PendingError();
320 if (_config->FindI("quiet",0) > 0)
83d89a9f 321 _error->DumpErrors();
65beb572
DK
322 else
323 _error->DumpErrors(GlobalError::DEBUG);
324 return Errors == true ? 100 : 0;
83d89a9f 325}
92fcbfc1 326 /*}}}*/