]> git.saurik.com Git - apt.git/blob - cmdline/apt-cdrom.cc
ensure partial dirs are 0700 and owned by _apt:root
[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/cdrom.h>
24 #include <apt-pkg/configuration.h>
25 #include <apt-pkg/pkgsystem.h>
26
27 #include <iostream>
28 #include <vector>
29 #include <string>
30 #include <sys/stat.h>
31 #include <unistd.h>
32
33 #include <apt-private/private-cmndline.h>
34
35 #include <apti18n.h>
36 /*}}}*/
37
38 using namespace std;
39
40 class pkgCdromTextStatus : public pkgCdromStatus /*{{{*/
41 {
42 protected:
43 OpTextProgress Progress;
44 void Prompt(const char *Text);
45 string PromptLine(const char *Text);
46 bool AskCdromName(string &name);
47
48 public:
49 virtual void Update(string text, int current);
50 virtual bool ChangeCdrom();
51 virtual OpProgress* GetOpProgress();
52 };
53
54 void pkgCdromTextStatus::Prompt(const char *Text)
55 {
56 char C;
57 cout << Text << ' ' << flush;
58 if (read(STDIN_FILENO,&C,1) < 0)
59 _error->Errno("pkgCdromTextStatus::Prompt",
60 "Failed to read from standard input (not a terminal?)");
61 if (C != '\n')
62 cout << endl;
63 }
64
65 string pkgCdromTextStatus::PromptLine(const char *Text)
66 {
67 cout << Text << ':' << endl;
68
69 string Res;
70 getline(cin,Res);
71 return Res;
72 }
73
74 bool pkgCdromTextStatus::AskCdromName(string &name)
75 {
76 cout << _("Please provide a name for this Disc, such as 'Debian 5.0.3 Disk 1'") << flush;
77 name = PromptLine("");
78
79 return true;
80 }
81
82
83 void pkgCdromTextStatus::Update(string text, int /*current*/)
84 {
85 if(text.size() > 0)
86 cout << text << flush;
87 }
88
89 bool pkgCdromTextStatus::ChangeCdrom()
90 {
91 Prompt(_("Please insert a Disc in the drive and press enter"));
92 return true;
93 }
94
95 APT_CONST OpProgress* pkgCdromTextStatus::GetOpProgress()
96 {
97 return &Progress;
98 }
99 /*}}}*/
100 // AddOrIdent - Add or Ident a CDROM /*{{{*/
101 static bool AddOrIdent(bool const Add)
102 {
103 pkgUdevCdromDevices UdevCdroms;
104 pkgCdromTextStatus log;
105 pkgCdrom cdrom;
106
107 bool oneSuccessful = false;
108 bool AutoDetect = _config->FindB("Acquire::cdrom::AutoDetect", true);
109 if (AutoDetect == true && UdevCdroms.Dlopen() == true)
110 {
111 bool const Debug = _config->FindB("Debug::Acquire::cdrom", false);
112 std::string const CDMount = _config->Find("Acquire::cdrom::mount");
113 bool const NoMount = _config->FindB("APT::CDROM::NoMount", false);
114 if (NoMount == false)
115 _config->Set("APT::CDROM::NoMount", true);
116
117 vector<struct CdromDevice> const v = UdevCdroms.Scan();
118 for (std::vector<struct CdromDevice>::const_iterator cd = v.begin(); cd != v.end(); ++cd)
119 {
120 if (Debug)
121 clog << "Looking at device:"
122 << "\tDeviveName: '" << cd->DeviceName << "'"
123 << "\tIsMounted: '" << cd->Mounted << "'"
124 << "\tMountPoint: '" << cd->MountPath << "'"
125 << endl;
126
127 std::string AptMountPoint;
128 if (cd->Mounted)
129 _config->Set("Acquire::cdrom::mount", cd->MountPath);
130 else if (NoMount == true)
131 continue;
132 else
133 {
134 AptMountPoint = _config->FindDir("Dir::Media::MountPath");
135 if (FileExists(AptMountPoint) == false)
136 mkdir(AptMountPoint.c_str(), 0750);
137 if(MountCdrom(AptMountPoint, cd->DeviceName) == false)
138 {
139 _error->Warning(_("Failed to mount '%s' to '%s'"), cd->DeviceName.c_str(), AptMountPoint.c_str());
140 continue;
141 }
142 _config->Set("Acquire::cdrom::mount", AptMountPoint);
143 }
144
145 _error->PushToStack();
146 if (Add == true)
147 oneSuccessful = cdrom.Add(&log);
148 else
149 {
150 std::string id;
151 oneSuccessful = cdrom.Ident(id, &log);
152 }
153 _error->MergeWithStack();
154
155 if (AptMountPoint.empty() == false)
156 UnmountCdrom(AptMountPoint);
157 }
158 if (NoMount == false)
159 _config->Set("APT::CDROM::NoMount", NoMount);
160 _config->Set("Acquire::cdrom::mount", CDMount);
161 }
162
163 // fallback if auto-detect didn't work
164 if (oneSuccessful == false)
165 {
166 _error->PushToStack();
167 if (Add == true)
168 oneSuccessful = cdrom.Add(&log);
169 else
170 {
171 std::string id;
172 oneSuccessful = cdrom.Ident(id, &log);
173 }
174 _error->MergeWithStack();
175 }
176
177 if (oneSuccessful == false)
178 _error->Error("%s", _("No CD-ROM could be auto-detected or found using the default mount point.\n"
179 "You may try the --cdrom option to set the CD-ROM mount point.\n"
180 "See 'man apt-cdrom' for more information about the CD-ROM auto-detection and mount point."));
181 else if (Add == true)
182 cout << _("Repeat this process for the rest of the CDs in your set.") << endl;
183
184 return oneSuccessful;
185 }
186 /*}}}*/
187 // DoAdd - Add a new CDROM /*{{{*/
188 // ---------------------------------------------------------------------
189 /* This does the main add bit.. We show some status and things. The
190 sequence is to mount/umount the CD, Ident it then scan it for package
191 files and reduce that list. Then we copy over the package files and
192 verify them. Then rewrite the database files */
193 static bool DoAdd(CommandLine &)
194 {
195 return AddOrIdent(true);
196 }
197 /*}}}*/
198 // DoIdent - Ident a CDROM /*{{{*/
199 static bool DoIdent(CommandLine &)
200 {
201 return AddOrIdent(false);
202 }
203 /*}}}*/
204 // ShowHelp - Show the help screen /*{{{*/
205 static bool ShowHelp(CommandLine &)
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 true;
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 true;
235 }
236 /*}}}*/
237 int main(int argc,const char *argv[]) /*{{{*/
238 {
239 CommandLine::Dispatch Cmds[] = {
240 {"add",&DoAdd},
241 {"ident",&DoIdent},
242 {"help",&ShowHelp},
243 {0,0}};
244
245 std::vector<CommandLine::Args> Args = getCommandArgs("apt-cdrom", CommandLine::GetCommand(Cmds, argc, argv));
246
247 // Set up gettext support
248 setlocale(LC_ALL,"");
249 textdomain(PACKAGE);
250
251 // Parse the command line and initialize the package library
252 CommandLine CmdL(Args.data(),_config);
253 if (pkgInitConfig(*_config) == false ||
254 CmdL.Parse(argc,argv) == false ||
255 pkgInitSystem(*_config,_system) == false)
256 {
257 _error->DumpErrors();
258 return 100;
259 }
260
261 // See if the help should be shown
262 if (_config->FindB("help") == true || _config->FindB("version") == true ||
263 CmdL.FileSize() == 0)
264 return ShowHelp(CmdL);
265
266 // Deal with stdout not being a tty
267 if (isatty(STDOUT_FILENO) && _config->FindI("quiet", -1) == -1)
268 _config->Set("quiet","1");
269
270 // Match the operation
271 bool returned = CmdL.DispatchArg(Cmds);
272
273 if (_config->FindI("quiet",0) > 0)
274 _error->DumpErrors();
275 else
276 _error->DumpErrors(GlobalError::DEBUG);
277 return returned == true ? 0 : 100;
278 }
279 /*}}}*/