]> git.saurik.com Git - apt.git/blob - cmdline/apt-cdrom.cc
cleanup the hash iteration. unfortunately there is no 1:1 mapping from Hashes::Suppor...
[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
43 using namespace std;
44
45 class pkgCdromTextStatus : public pkgCdromStatus /*{{{*/
46 {
47 protected:
48 OpTextProgress Progress;
49 void Prompt(const char *Text);
50 string PromptLine(const char *Text);
51 bool AskCdromName(string &name);
52
53 public:
54 virtual void Update(string text, int current);
55 virtual bool ChangeCdrom();
56 virtual OpProgress* GetOpProgress();
57 };
58
59 void pkgCdromTextStatus::Prompt(const char *Text)
60 {
61 char C;
62 cout << Text << ' ' << flush;
63 read(STDIN_FILENO,&C,1);
64 if (C != '\n')
65 cout << endl;
66 }
67
68 string pkgCdromTextStatus::PromptLine(const char *Text)
69 {
70 cout << Text << ':' << endl;
71
72 string Res;
73 getline(cin,Res);
74 return Res;
75 }
76
77 bool pkgCdromTextStatus::AskCdromName(string &name)
78 {
79 cout << _("Please provide a name for this Disc, such as 'Debian 5.0.3 Disk 1'") << flush;
80 name = PromptLine("");
81
82 return true;
83 }
84
85
86 void pkgCdromTextStatus::Update(string text, int current)
87 {
88 if(text.size() > 0)
89 cout << text << flush;
90 }
91
92 bool pkgCdromTextStatus::ChangeCdrom()
93 {
94 Prompt(_("Please insert a Disc in the drive and press enter"));
95 return true;
96 }
97
98 OpProgress* pkgCdromTextStatus::GetOpProgress()
99 {
100 return &Progress;
101 };
102 /*}}}*/
103 // SetupAutoDetect /*{{{*/
104 bool AutoDetectCdrom(pkgUdevCdromDevices &UdevCdroms, unsigned int &i)
105 {
106 bool Debug = _config->FindB("Debug::Acquire::cdrom", false);
107
108 vector<struct CdromDevice> v = UdevCdroms.Scan();
109 if (i >= v.size())
110 return false;
111
112 if (Debug)
113 clog << "Looking at devce " << i
114 << " DeviveName: " << v[i].DeviceName
115 << " IsMounted: '" << v[i].Mounted << "'"
116 << " MountPoint: '" << v[i].MountPath << "'"
117 << endl;
118
119 if (v[i].Mounted)
120 {
121 // set the right options
122 _config->Set("Acquire::cdrom::mount", v[i].MountPath);
123 _config->Set("APT::CDROM::NoMount", true);
124 } else {
125 string AptMountPoint = _config->FindDir("Dir::Media::MountPath");
126 if (!FileExists(AptMountPoint))
127 mkdir(AptMountPoint.c_str(), 0750);
128 if(MountCdrom(AptMountPoint, v[i].DeviceName) == false)
129 _error->Warning(_("Failed to mount '%s' to '%s'"), v[i].DeviceName.c_str(), AptMountPoint.c_str());
130 _config->Set("Acquire::cdrom::mount", AptMountPoint);
131 _config->Set("APT::CDROM::NoMount", true);
132 }
133 i++;
134
135 return true;
136 }
137 /*}}}*/
138
139 // DoAdd - Add a new CDROM /*{{{*/
140 // ---------------------------------------------------------------------
141 /* This does the main add bit.. We show some status and things. The
142 sequence is to mount/umount the CD, Ident it then scan it for package
143 files and reduce that list. Then we copy over the package files and
144 verify them. Then rewrite the database files */
145 bool DoAdd(CommandLine &)
146 {
147 pkgUdevCdromDevices UdevCdroms;
148 pkgCdromTextStatus log;
149 pkgCdrom cdrom;
150 bool res = true;
151
152 bool AutoDetect = _config->FindB("Acquire::cdrom::AutoDetect", true);
153 if (AutoDetect && UdevCdroms.Dlopen())
154 {
155 unsigned int count = 0;
156 while (AutoDetectCdrom(UdevCdroms, count))
157 res &= cdrom.Add(&log);
158 } else {
159 res = cdrom.Add(&log);
160 }
161
162 if(res)
163 cout << _("Repeat this process for the rest of the CDs in your set.") << endl;
164
165 return res;
166 }
167 /*}}}*/
168 // DoIdent - Ident a CDROM /*{{{*/
169 // ---------------------------------------------------------------------
170 /* */
171 bool DoIdent(CommandLine &)
172 {
173 pkgUdevCdromDevices UdevCdroms;
174 string ident;
175 pkgCdromTextStatus log;
176 pkgCdrom cdrom;
177 bool res = true;
178
179 bool AutoDetect = _config->FindB("Acquire::cdrom::AutoDetect");
180
181 if (AutoDetect && UdevCdroms.Dlopen())
182 {
183 unsigned int count = 0;
184 while (AutoDetectCdrom(UdevCdroms, count))
185 res &= cdrom.Ident(ident, &log);
186 } else {
187 return cdrom.Ident(ident, &log);
188 }
189
190 return res;
191 }
192 /*}}}*/
193 // ShowHelp - Show the help screen /*{{{*/
194 // ---------------------------------------------------------------------
195 /* */
196 int ShowHelp()
197 {
198 ioprintf(cout,_("%s %s for %s compiled on %s %s\n"),PACKAGE,PACKAGE_VERSION,
199 COMMON_ARCH,__DATE__,__TIME__);
200 if (_config->FindB("version") == true)
201 return 0;
202
203 cout <<
204 "Usage: apt-cdrom [options] command\n"
205 "\n"
206 "apt-cdrom is a tool to add CDROM's to APT's source list. The\n"
207 "CDROM mount point and device information is taken from apt.conf\n"
208 "and /etc/fstab.\n"
209 "\n"
210 "Commands:\n"
211 " add - Add a CDROM\n"
212 " ident - Report the identity of a CDROM\n"
213 "\n"
214 "Options:\n"
215 " -h This help text\n"
216 " -d CD-ROM mount point\n"
217 " -r Rename a recognized CD-ROM\n"
218 " -m No mounting\n"
219 " -f Fast mode, don't check package files\n"
220 " -a Thorough scan mode\n"
221 " --auto-detect Auto detect drive and mount point\n"
222 " -c=? Read this configuration file\n"
223 " -o=? Set an arbitrary configuration option, eg -o dir::cache=/tmp\n"
224 "See fstab(5)\n";
225 return 0;
226 }
227 /*}}}*/
228 int main(int argc,const char *argv[]) /*{{{*/
229 {
230 CommandLine::Args Args[] = {
231 {'h',"help","help",0},
232 { 0,"auto-detect","Acquire::cdrom::AutoDetect",0},
233 {'v',"version","version",0},
234 {'d',"cdrom","Acquire::cdrom::mount",CommandLine::HasArg},
235 {'r',"rename","APT::CDROM::Rename",0},
236 {'m',"no-mount","APT::CDROM::NoMount",0},
237 {'f',"fast","APT::CDROM::Fast",0},
238 {'n',"just-print","APT::CDROM::NoAct",0},
239 {'n',"recon","APT::CDROM::NoAct",0},
240 {'n',"no-act","APT::CDROM::NoAct",0},
241 {'a',"thorough","APT::CDROM::Thorough",0},
242 {'c',"config-file",0,CommandLine::ConfigFile},
243 {'o',"option",0,CommandLine::ArbItem},
244 {0,0,0,0}};
245 CommandLine::Dispatch Cmds[] = {
246 {"add",&DoAdd},
247 {"ident",&DoIdent},
248 {0,0}};
249
250 // Set up gettext support
251 setlocale(LC_ALL,"");
252 textdomain(PACKAGE);
253
254 // Parse the command line and initialize the package library
255 CommandLine CmdL(Args,_config);
256 if (pkgInitConfig(*_config) == false ||
257 CmdL.Parse(argc,argv) == false ||
258 pkgInitSystem(*_config,_system) == false)
259 {
260 _error->DumpErrors();
261 return 100;
262 }
263
264 // See if the help should be shown
265 if (_config->FindB("help") == true || _config->FindB("version") == true ||
266 CmdL.FileSize() == 0)
267 return ShowHelp();
268
269 // Deal with stdout not being a tty
270 if (isatty(STDOUT_FILENO) && _config->FindI("quiet", -1) == -1)
271 _config->Set("quiet","1");
272
273 // Match the operation
274 CmdL.DispatchArg(Cmds);
275
276 // Print any errors or warnings found during parsing
277 bool const Errors = _error->PendingError();
278 if (_config->FindI("quiet",0) > 0)
279 _error->DumpErrors();
280 else
281 _error->DumpErrors(GlobalError::DEBUG);
282 return Errors == true ? 100 : 0;
283 }
284 /*}}}*/