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/cdrom.h>
24 #include <apt-pkg/configuration.h>
25 #include <apt-pkg/pkgsystem.h>
33 #include <apt-private/private-cmndline.h>
40 class pkgCdromTextStatus
: public pkgCdromStatus
/*{{{*/
43 OpTextProgress Progress
;
44 void Prompt(const char *Text
);
45 string
PromptLine(const char *Text
);
46 bool AskCdromName(string
&name
);
49 virtual void Update(string text
, int current
);
50 virtual bool ChangeCdrom();
51 virtual OpProgress
* GetOpProgress();
54 void pkgCdromTextStatus::Prompt(const char *Text
)
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?)");
65 string
pkgCdromTextStatus::PromptLine(const char *Text
)
67 cout
<< Text
<< ':' << endl
;
74 bool pkgCdromTextStatus::AskCdromName(string
&name
)
76 cout
<< _("Please provide a name for this Disc, such as 'Debian 5.0.3 Disk 1'") << flush
;
77 name
= PromptLine("");
83 void pkgCdromTextStatus::Update(string text
, int /*current*/)
86 cout
<< text
<< flush
;
89 bool pkgCdromTextStatus::ChangeCdrom()
91 Prompt(_("Please insert a Disc in the drive and press enter"));
95 APT_CONST OpProgress
* pkgCdromTextStatus::GetOpProgress()
100 // AddOrIdent - Add or Ident a CDROM /*{{{*/
101 static bool AddOrIdent(bool const Add
)
103 pkgUdevCdromDevices UdevCdroms
;
104 pkgCdromTextStatus log
;
107 bool oneSuccessful
= false;
108 bool AutoDetect
= _config
->FindB("Acquire::cdrom::AutoDetect", true);
109 if (AutoDetect
== true && UdevCdroms
.Dlopen() == true)
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);
117 vector
<struct CdromDevice
> const v
= UdevCdroms
.Scan();
118 for (std::vector
<struct CdromDevice
>::const_iterator cd
= v
.begin(); cd
!= v
.end(); ++cd
)
121 clog
<< "Looking at device:"
122 << "\tDeviveName: '" << cd
->DeviceName
<< "'"
123 << "\tIsMounted: '" << cd
->Mounted
<< "'"
124 << "\tMountPoint: '" << cd
->MountPath
<< "'"
127 std::string AptMountPoint
;
129 _config
->Set("Acquire::cdrom::mount", cd
->MountPath
);
130 else if (NoMount
== true)
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)
139 _error
->Warning(_("Failed to mount '%s' to '%s'"), cd
->DeviceName
.c_str(), AptMountPoint
.c_str());
142 _config
->Set("Acquire::cdrom::mount", AptMountPoint
);
145 _error
->PushToStack();
147 oneSuccessful
= cdrom
.Add(&log
);
151 oneSuccessful
= cdrom
.Ident(id
, &log
);
153 _error
->MergeWithStack();
155 if (AptMountPoint
.empty() == false)
156 UnmountCdrom(AptMountPoint
);
158 if (NoMount
== false)
159 _config
->Set("APT::CDROM::NoMount", NoMount
);
160 _config
->Set("Acquire::cdrom::mount", CDMount
);
163 // fallback if auto-detect didn't work
164 if (oneSuccessful
== false)
166 _error
->PushToStack();
168 oneSuccessful
= cdrom
.Add(&log
);
172 oneSuccessful
= cdrom
.Ident(id
, &log
);
174 _error
->MergeWithStack();
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
;
184 return oneSuccessful
;
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
&)
195 return AddOrIdent(true);
198 // DoIdent - Ident a CDROM /*{{{*/
199 static bool DoIdent(CommandLine
&)
201 return AddOrIdent(false);
204 // ShowHelp - Show the help screen /*{{{*/
205 static bool ShowHelp(CommandLine
&)
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::Dispatch Cmds
[] = {
245 std::vector
<CommandLine::Args
> Args
= getCommandArgs("apt-cdrom", CommandLine::GetCommand(Cmds
, argc
, argv
));
247 // Set up gettext support
248 setlocale(LC_ALL
,"");
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)
257 _error
->DumpErrors();
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
);
266 // Deal with stdout not being a tty
267 if (isatty(STDOUT_FILENO
) && _config
->FindI("quiet", -1) == -1)
268 _config
->Set("quiet","1");
270 // Match the operation
271 bool returned
= CmdL
.DispatchArg(Cmds
);
273 if (_config
->FindI("quiet",0) > 0)
274 _error
->DumpErrors();
276 _error
->DumpErrors(GlobalError::DEBUG
);
277 return returned
== true ? 0 : 100;