]> git.saurik.com Git - apt.git/blob - cmdline/apt-cdrom.cc
Merge branch 'debian/sid' of git://git.debian.org/git/apt/apt into debian/sid
[apt.git] / cmdline / apt-cdrom.cc
1 // -*- mode: cpp; mode: fold -*-
2 // Description /*{{{*/
3 // $Id: apt-cdrom.cc,v 1.45 2003/11/19 23:50:51 mdz Exp $
4 /* ######################################################################
5
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.
10
11 ##################################################################### */
12 /*}}}*/
13 // Include Files /*{{{*/
14 #include<config.h>
15
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>
28
29 #include <locale.h>
30 #include <iostream>
31 #include <fstream>
32 #include <vector>
33 #include <algorithm>
34 #include <sys/stat.h>
35 #include <fcntl.h>
36 #include <dirent.h>
37 #include <unistd.h>
38 #include <stdio.h>
39
40 #include <apti18n.h>
41 /*}}}*/
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.");
48
49 using namespace std;
50
51 class pkgCdromTextStatus : public pkgCdromStatus /*{{{*/
52 {
53 protected:
54 OpTextProgress Progress;
55 void Prompt(const char *Text);
56 string PromptLine(const char *Text);
57 bool AskCdromName(string &name);
58
59 public:
60 virtual void Update(string text, int current);
61 virtual bool ChangeCdrom();
62 virtual OpProgress* GetOpProgress();
63 };
64
65 void pkgCdromTextStatus::Prompt(const char *Text)
66 {
67 char C;
68 cout << Text << ' ' << flush;
69 if (read(STDIN_FILENO,&C,1) < 0)
70 _error->Errno("pkgCdromTextStatus::Prompt", "failed to prompt");
71 if (C != '\n')
72 cout << endl;
73 }
74
75 string pkgCdromTextStatus::PromptLine(const char *Text)
76 {
77 cout << Text << ':' << endl;
78
79 string Res;
80 getline(cin,Res);
81 return Res;
82 }
83
84 bool pkgCdromTextStatus::AskCdromName(string &name)
85 {
86 cout << _("Please provide a name for this Disc, such as 'Debian 5.0.3 Disk 1'") << flush;
87 name = PromptLine("");
88
89 return true;
90 }
91
92
93 void pkgCdromTextStatus::Update(string text, int current)
94 {
95 if(text.size() > 0)
96 cout << text << flush;
97 }
98
99 bool pkgCdromTextStatus::ChangeCdrom()
100 {
101 Prompt(_("Please insert a Disc in the drive and press enter"));
102 return true;
103 }
104
105 OpProgress* pkgCdromTextStatus::GetOpProgress()
106 {
107 return &Progress;
108 };
109 /*}}}*/
110 // SetupAutoDetect /*{{{*/
111 bool AutoDetectCdrom(pkgUdevCdromDevices &UdevCdroms, unsigned int &i)
112 {
113 bool Debug = _config->FindB("Debug::Acquire::cdrom", false);
114
115 vector<struct CdromDevice> v = UdevCdroms.Scan();
116 if (i >= v.size())
117 return false;
118
119 if (Debug)
120 clog << "Looking at devce " << i
121 << " DeviveName: " << v[i].DeviceName
122 << " IsMounted: '" << v[i].Mounted << "'"
123 << " MountPoint: '" << v[i].MountPath << "'"
124 << endl;
125
126 if (v[i].Mounted)
127 {
128 // set the right options
129 _config->Set("Acquire::cdrom::mount", v[i].MountPath);
130 _config->Set("APT::CDROM::NoMount", true);
131 } else {
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);
139 }
140 i++;
141
142 return true;
143 }
144 /*}}}*/
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 &)
152 {
153 pkgUdevCdromDevices UdevCdroms;
154 pkgCdromTextStatus log;
155 pkgCdrom cdrom;
156 bool res = true;
157
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);
163 if (count == 0) {
164 res = cdrom.Add(&log);
165 if (res == false) {
166 _error->Error("%s", _(W_NO_CDROM_FOUND));
167 }
168 }
169
170 if(res)
171 cout << _("Repeat this process for the rest of the CDs in your set.") << endl;
172
173 return res;
174 }
175 /*}}}*/
176 // DoIdent - Ident a CDROM /*{{{*/
177 // ---------------------------------------------------------------------
178 /* */
179 bool DoIdent(CommandLine &)
180 {
181 pkgUdevCdromDevices UdevCdroms;
182 string ident;
183 pkgCdromTextStatus log;
184 pkgCdrom cdrom;
185 bool res = true;
186
187 bool AutoDetect = _config->FindB("Acquire::cdrom::AutoDetect");
188
189 unsigned int count = 0;
190 if (AutoDetect && UdevCdroms.Dlopen())
191 while (AutoDetectCdrom(UdevCdroms, count))
192 res &= cdrom.Ident(ident, &log);
193 if (count == 0) {
194 res = cdrom.Ident(ident, &log);
195 if (res == false) {
196 _error->Error("%s", _(W_NO_CDROM_FOUND));
197 }
198 }
199 return res;
200 }
201 /*}}}*/
202 // ShowHelp - Show the help screen /*{{{*/
203 // ---------------------------------------------------------------------
204 /* */
205 int ShowHelp()
206 {
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)
210 return 0;
211
212 cout <<
213 "Usage: apt-cdrom [options] command\n"
214 "\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"
217 "and /etc/fstab.\n"
218 "\n"
219 "Commands:\n"
220 " add - Add a CDROM\n"
221 " ident - Report the identity of a CDROM\n"
222 "\n"
223 "Options:\n"
224 " -h This help text\n"
225 " -d CD-ROM mount point\n"
226 " -r Rename a recognized CD-ROM\n"
227 " -m No mounting\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"
233 "See fstab(5)\n";
234 return 0;
235 }
236 /*}}}*/
237 int main(int argc,const char *argv[]) /*{{{*/
238 {
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},
253 {0,0,0,0}};
254 CommandLine::Dispatch Cmds[] = {
255 {"add",&DoAdd},
256 {"ident",&DoIdent},
257 {0,0}};
258
259 // Set up gettext support
260 setlocale(LC_ALL,"");
261 textdomain(PACKAGE);
262
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)
268 {
269 _error->DumpErrors();
270 return 100;
271 }
272
273 // See if the help should be shown
274 if (_config->FindB("help") == true || _config->FindB("version") == true ||
275 CmdL.FileSize() == 0)
276 return ShowHelp();
277
278 // Deal with stdout not being a tty
279 if (isatty(STDOUT_FILENO) && _config->FindI("quiet", -1) == -1)
280 _config->Set("quiet","1");
281
282 // Match the operation
283 CmdL.DispatchArg(Cmds);
284
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();
289 else
290 _error->DumpErrors(GlobalError::DEBUG);
291 return Errors == true ? 100 : 0;
292 }
293 /*}}}*/