]> git.saurik.com Git - apt.git/blame - apt-pkg/cdrom.cc
* merged the apt--curl-https branch
[apt.git] / apt-pkg / cdrom.cc
CommitLineData
a75c6a6e
MZ
1/*
2 */
3
4#ifdef __GNUG__
5#pragma implementation "apt-pkg/cdrom.h"
6#endif
7#include<apt-pkg/init.h>
8#include<apt-pkg/error.h>
9#include<apt-pkg/cdromutl.h>
10#include<apt-pkg/strutl.h>
11#include<apt-pkg/cdrom.h>
12#include<sstream>
13#include<fstream>
14#include<config.h>
15#include<apti18n.h>
16#include <sys/stat.h>
17#include <fcntl.h>
18#include <dirent.h>
19#include <unistd.h>
20#include <stdio.h>
21
22
23#include "indexcopy.h"
24
25using namespace std;
26
27// FindPackages - Find the package files on the CDROM /*{{{*/
28// ---------------------------------------------------------------------
29/* We look over the cdrom for package files. This is a recursive
30 search that short circuits when it his a package file in the dir.
31 This speeds it up greatly as the majority of the size is in the
32 binary-* sub dirs. */
22f8568d
MV
33bool pkgCdrom::FindPackages(string CD,
34 vector<string> &List,
35 vector<string> &SList,
36 vector<string> &SigList,
37 vector<string> &TransList,
a75c6a6e
MZ
38 string &InfoDir, pkgCdromStatus *log,
39 unsigned int Depth)
40{
41 static ino_t Inodes[9];
22f8568d 42 DIR *D;
a75c6a6e
MZ
43
44 // if we have a look we "pulse" now
45 if(log)
46 log->Update();
47
48 if (Depth >= 7)
49 return true;
50
51 if (CD[CD.length()-1] != '/')
52 CD += '/';
53
54 if (chdir(CD.c_str()) != 0)
55 return _error->Errno("chdir","Unable to change to %s",CD.c_str());
56
57 // Look for a .disk subdirectory
58 struct stat Buf;
59 if (stat(".disk",&Buf) == 0)
60 {
61 if (InfoDir.empty() == true)
62 InfoDir = CD + ".disk/";
63 }
64
65 // Don't look into directories that have been marked to ingore.
66 if (stat(".aptignr",&Buf) == 0)
67 return true;
68
69
70 /* Check _first_ for a signature file as apt-cdrom assumes that all files
71 under a Packages/Source file are in control of that file and stops
72 the scanning
73 */
74 if (stat("Release.gpg",&Buf) == 0)
75 {
76 SigList.push_back(CD);
77 }
78 /* Aha! We found some package files. We assume that everything under
79 this dir is controlled by those package files so we don't look down
80 anymore */
81 if (stat("Packages",&Buf) == 0 || stat("Packages.gz",&Buf) == 0)
82 {
83 List.push_back(CD);
84
85 // Continue down if thorough is given
86 if (_config->FindB("APT::CDROM::Thorough",false) == false)
87 return true;
88 }
89 if (stat("Sources.gz",&Buf) == 0 || stat("Sources",&Buf) == 0)
90 {
91 SList.push_back(CD);
92
93 // Continue down if thorough is given
94 if (_config->FindB("APT::CDROM::Thorough",false) == false)
95 return true;
96 }
22f8568d
MV
97
98 // see if we find translatin indexes
99 if (stat("i18n",&Buf) == 0)
100 {
101 D = opendir("i18n");
102 for (struct dirent *Dir = readdir(D); Dir != 0; Dir = readdir(D))
103 {
104 if(strstr(Dir->d_name,"Translation") != NULL)
105 {
106 if (_config->FindB("Debug::aptcdrom",false) == true)
107 std::clog << "found translations: " << Dir->d_name << "\n";
108 string file = Dir->d_name;
109 if(file.substr(file.size()-3,file.size()) == ".gz")
110 file = file.substr(0,file.size()-3);
111 TransList.push_back(CD+"i18n/"+ file);
112 }
113 }
114 closedir(D);
115 }
116
a75c6a6e 117
22f8568d 118 D = opendir(".");
a75c6a6e
MZ
119 if (D == 0)
120 return _error->Errno("opendir","Unable to read %s",CD.c_str());
121
122 // Run over the directory
123 for (struct dirent *Dir = readdir(D); Dir != 0; Dir = readdir(D))
124 {
125 // Skip some files..
126 if (strcmp(Dir->d_name,".") == 0 ||
127 strcmp(Dir->d_name,"..") == 0 ||
128 //strcmp(Dir->d_name,"source") == 0 ||
129 strcmp(Dir->d_name,".disk") == 0 ||
130 strcmp(Dir->d_name,"experimental") == 0 ||
131 strcmp(Dir->d_name,"binary-all") == 0 ||
132 strcmp(Dir->d_name,"debian-installer") == 0)
133 continue;
134
135 // See if the name is a sub directory
136 struct stat Buf;
137 if (stat(Dir->d_name,&Buf) != 0)
138 continue;
139
140 if (S_ISDIR(Buf.st_mode) == 0)
141 continue;
142
143 unsigned int I;
144 for (I = 0; I != Depth; I++)
145 if (Inodes[I] == Buf.st_ino)
146 break;
147 if (I != Depth)
148 continue;
149
150 // Store the inodes weve seen
151 Inodes[Depth] = Buf.st_ino;
152
153 // Descend
22f8568d 154 if (FindPackages(CD + Dir->d_name,List,SList,SigList,TransList,InfoDir,log,Depth+1) == false)
a75c6a6e
MZ
155 break;
156
157 if (chdir(CD.c_str()) != 0)
158 return _error->Errno("chdir","Unable to change to %s",CD.c_str());
159 };
160
161 closedir(D);
162
163 return !_error->PendingError();
164}
165
166// Score - We compute a 'score' for a path /*{{{*/
167// ---------------------------------------------------------------------
168/* Paths are scored based on how close they come to what I consider
169 normal. That is ones that have 'dist' 'stable' 'testing' will score
170 higher than ones without. */
171int pkgCdrom::Score(string Path)
172{
173 int Res = 0;
174 if (Path.find("stable/") != string::npos)
175 Res += 29;
176 if (Path.find("/binary-") != string::npos)
177 Res += 20;
178 if (Path.find("testing/") != string::npos)
179 Res += 28;
180 if (Path.find("unstable/") != string::npos)
181 Res += 27;
182 if (Path.find("/dists/") != string::npos)
183 Res += 40;
184 if (Path.find("/main/") != string::npos)
185 Res += 20;
186 if (Path.find("/contrib/") != string::npos)
187 Res += 20;
188 if (Path.find("/non-free/") != string::npos)
189 Res += 20;
190 if (Path.find("/non-US/") != string::npos)
191 Res += 20;
192 if (Path.find("/source/") != string::npos)
193 Res += 10;
194 if (Path.find("/debian/") != string::npos)
195 Res -= 10;
872b3d39
MV
196
197 // check for symlinks in the patch leading to the actual file
198 // a symlink gets a big penalty
199 struct stat Buf;
200 string statPath = flNotFile(Path);
201 string cdromPath = _config->FindDir("Acquire::cdrom::mount","/cdrom/");
202 while(statPath != cdromPath && statPath != "./") {
203 statPath.resize(statPath.size()-1); // remove the trailing '/'
204 if (lstat(statPath.c_str(),&Buf) == 0) {
205 if(S_ISLNK(Buf.st_mode)) {
206 Res -= 60;
207 break;
208 }
209 }
210 statPath = flNotFile(statPath); // descent
211 }
212
a75c6a6e
MZ
213 return Res;
214}
215
216 /*}}}*/
217// DropBinaryArch - Dump dirs with a string like /binary-<foo>/ /*{{{*/
218// ---------------------------------------------------------------------
219/* Here we drop everything that is not this machines arch */
220bool pkgCdrom::DropBinaryArch(vector<string> &List)
221{
222 char S[300];
223 snprintf(S,sizeof(S),"/binary-%s/",
224 _config->Find("Apt::Architecture").c_str());
225
226 for (unsigned int I = 0; I < List.size(); I++)
227 {
228 const char *Str = List[I].c_str();
229
230 const char *Res;
231 if ((Res = strstr(Str,"/binary-")) == 0)
232 continue;
233
234 // Weird, remove it.
235 if (strlen(Res) < strlen(S))
236 {
237 List.erase(List.begin() + I);
238 I--;
239 continue;
240 }
241
242 // See if it is our arch
243 if (stringcmp(Res,Res + strlen(S),S) == 0)
244 continue;
245
246 // Erase it
247 List.erase(List.begin() + I);
248 I--;
249 }
250
251 return true;
252}
253
254
255// DropRepeats - Drop repeated files resulting from symlinks /*{{{*/
256// ---------------------------------------------------------------------
257/* Here we go and stat every file that we found and strip dup inodes. */
258bool pkgCdrom::DropRepeats(vector<string> &List,const char *Name)
259{
260 // Get a list of all the inodes
261 ino_t *Inodes = new ino_t[List.size()];
262 for (unsigned int I = 0; I != List.size(); I++)
263 {
264 struct stat Buf;
265 if (stat((List[I] + Name).c_str(),&Buf) != 0 &&
266 stat((List[I] + Name + ".gz").c_str(),&Buf) != 0)
267 _error->Errno("stat","Failed to stat %s%s",List[I].c_str(),
268 Name);
269 Inodes[I] = Buf.st_ino;
270 }
271
272 if (_error->PendingError() == true)
273 return false;
274
275 // Look for dups
276 for (unsigned int I = 0; I != List.size(); I++)
277 {
278 for (unsigned int J = I+1; J < List.size(); J++)
279 {
280 // No match
281 if (Inodes[J] != Inodes[I])
282 continue;
283
284 // We score the two paths.. and erase one
285 int ScoreA = Score(List[I]);
286 int ScoreB = Score(List[J]);
287 if (ScoreA < ScoreB)
288 {
289 List[I] = string();
290 break;
291 }
292
293 List[J] = string();
294 }
295 }
296
297 // Wipe erased entries
298 for (unsigned int I = 0; I < List.size();)
299 {
300 if (List[I].empty() == false)
301 I++;
302 else
303 List.erase(List.begin()+I);
304 }
305
306 return true;
307}
308 /*}}}*/
309
310// ReduceSourceList - Takes the path list and reduces it /*{{{*/
311// ---------------------------------------------------------------------
312/* This takes the list of source list expressed entires and collects
313 similar ones to form a single entry for each dist */
314void pkgCdrom::ReduceSourcelist(string CD,vector<string> &List)
315{
316 sort(List.begin(),List.end());
317
318 // Collect similar entries
319 for (vector<string>::iterator I = List.begin(); I != List.end(); I++)
320 {
321 // Find a space..
322 string::size_type Space = (*I).find(' ');
323 if (Space == string::npos)
324 continue;
325 string::size_type SSpace = (*I).find(' ',Space + 1);
326 if (SSpace == string::npos)
327 continue;
328
329 string Word1 = string(*I,Space,SSpace-Space);
330 string Prefix = string(*I,0,Space);
331 for (vector<string>::iterator J = List.begin(); J != I; J++)
332 {
333 // Find a space..
334 string::size_type Space2 = (*J).find(' ');
335 if (Space2 == string::npos)
336 continue;
337 string::size_type SSpace2 = (*J).find(' ',Space2 + 1);
338 if (SSpace2 == string::npos)
339 continue;
340
341 if (string(*J,0,Space2) != Prefix)
342 continue;
343 if (string(*J,Space2,SSpace2-Space2) != Word1)
344 continue;
345
346 *J += string(*I,SSpace);
347 *I = string();
348 }
349 }
350
351 // Wipe erased entries
352 for (unsigned int I = 0; I < List.size();)
353 {
354 if (List[I].empty() == false)
355 I++;
356 else
357 List.erase(List.begin()+I);
358 }
359}
360 /*}}}*/
361// WriteDatabase - Write the CDROM Database file /*{{{*/
362// ---------------------------------------------------------------------
363/* We rewrite the configuration class associated with the cdrom database. */
364bool pkgCdrom::WriteDatabase(Configuration &Cnf)
365{
366 string DFile = _config->FindFile("Dir::State::cdroms");
367 string NewFile = DFile + ".new";
368
369 unlink(NewFile.c_str());
370 ofstream Out(NewFile.c_str());
371 if (!Out)
372 return _error->Errno("ofstream::ofstream",
373 "Failed to open %s.new",DFile.c_str());
374
375 /* Write out all of the configuration directives by walking the
376 configuration tree */
377 const Configuration::Item *Top = Cnf.Tree(0);
378 for (; Top != 0;)
379 {
380 // Print the config entry
381 if (Top->Value.empty() == false)
382 Out << Top->FullTag() + " \"" << Top->Value << "\";" << endl;
383
384 if (Top->Child != 0)
385 {
386 Top = Top->Child;
387 continue;
388 }
389
390 while (Top != 0 && Top->Next == 0)
391 Top = Top->Parent;
392 if (Top != 0)
393 Top = Top->Next;
394 }
395
396 Out.close();
397
398 rename(DFile.c_str(),string(DFile + '~').c_str());
399 if (rename(NewFile.c_str(),DFile.c_str()) != 0)
400 return _error->Errno("rename","Failed to rename %s.new to %s",
401 DFile.c_str(),DFile.c_str());
402
403 return true;
404}
405 /*}}}*/
406// WriteSourceList - Write an updated sourcelist /*{{{*/
407// ---------------------------------------------------------------------
408/* This reads the old source list and copies it into the new one. It
409 appends the new CDROM entires just after the first block of comments.
410 This places them first in the file. It also removes any old entries
411 that were the same. */
412bool pkgCdrom::WriteSourceList(string Name,vector<string> &List,bool Source)
413{
414 if (List.size() == 0)
415 return true;
416
417 string File = _config->FindFile("Dir::Etc::sourcelist");
418
419 // Open the stream for reading
420 ifstream F((FileExists(File)?File.c_str():"/dev/null"),
421 ios::in );
422 if (!F != 0)
423 return _error->Errno("ifstream::ifstream","Opening %s",File.c_str());
424
425 string NewFile = File + ".new";
426 unlink(NewFile.c_str());
427 ofstream Out(NewFile.c_str());
428 if (!Out)
429 return _error->Errno("ofstream::ofstream",
430 "Failed to open %s.new",File.c_str());
431
432 // Create a short uri without the path
433 string ShortURI = "cdrom:[" + Name + "]/";
434 string ShortURI2 = "cdrom:" + Name + "/"; // For Compatibility
435
436 string Type;
437 if (Source == true)
438 Type = "deb-src";
439 else
440 Type = "deb";
441
442 char Buffer[300];
443 int CurLine = 0;
444 bool First = true;
445 while (F.eof() == false)
446 {
447 F.getline(Buffer,sizeof(Buffer));
448 CurLine++;
13e8426f
MV
449 if (F.fail() && !F.eof())
450 return _error->Error(_("Line %u too long in source list %s."),
451 CurLine,File.c_str());
a75c6a6e
MZ
452 _strtabexpand(Buffer,sizeof(Buffer));
453 _strstrip(Buffer);
454
455 // Comment or blank
456 if (Buffer[0] == '#' || Buffer[0] == 0)
457 {
458 Out << Buffer << endl;
459 continue;
460 }
461
462 if (First == true)
463 {
464 for (vector<string>::iterator I = List.begin(); I != List.end(); I++)
465 {
466 string::size_type Space = (*I).find(' ');
467 if (Space == string::npos)
468 return _error->Error("Internal error");
469 Out << Type << " cdrom:[" << Name << "]/" << string(*I,0,Space) <<
470 " " << string(*I,Space+1) << endl;
471 }
472 }
473 First = false;
474
475 // Grok it
476 string cType;
477 string URI;
478 const char *C = Buffer;
479 if (ParseQuoteWord(C,cType) == false ||
480 ParseQuoteWord(C,URI) == false)
481 {
482 Out << Buffer << endl;
483 continue;
484 }
485
486 // Emit lines like this one
487 if (cType != Type || (string(URI,0,ShortURI.length()) != ShortURI &&
488 string(URI,0,ShortURI.length()) != ShortURI2))
489 {
490 Out << Buffer << endl;
491 continue;
492 }
493 }
494
495 // Just in case the file was empty
496 if (First == true)
497 {
498 for (vector<string>::iterator I = List.begin(); I != List.end(); I++)
499 {
500 string::size_type Space = (*I).find(' ');
501 if (Space == string::npos)
502 return _error->Error("Internal error");
503
504 Out << "deb cdrom:[" << Name << "]/" << string(*I,0,Space) <<
505 " " << string(*I,Space+1) << endl;
506 }
507 }
508
509 Out.close();
510
511 rename(File.c_str(),string(File + '~').c_str());
512 if (rename(NewFile.c_str(),File.c_str()) != 0)
513 return _error->Errno("rename","Failed to rename %s.new to %s",
514 File.c_str(),File.c_str());
515
516 return true;
517}
518
519
520bool pkgCdrom::Ident(string &ident, pkgCdromStatus *log)
521{
522 stringstream msg;
523
524 // Startup
525 string CDROM = _config->FindDir("Acquire::cdrom::mount","/cdrom/");
526 if (CDROM[0] == '.')
527 CDROM= SafeGetCWD() + '/' + CDROM;
528
529 if(log) {
530 msg.str("");
531 ioprintf(msg, _("Using CD-ROM mount point %s\nMounting CD-ROM\n"),
532 CDROM.c_str());
533 log->Update(msg.str());
534 }
535 if (MountCdrom(CDROM) == false)
536 return _error->Error("Failed to mount the cdrom.");
537
538 // Hash the CD to get an ID
539 if(log)
540 log->Update(_("Identifying.. "));
541
542
543 if (IdentCdrom(CDROM,ident) == false)
544 {
545 ident = "";
546 return false;
547 }
548
549 msg.str("");
550 ioprintf(msg, "[%s]\n",ident.c_str());
551 log->Update(msg.str());
552
553
554 // Read the database
555 Configuration Database;
556 string DFile = _config->FindFile("Dir::State::cdroms");
557 if (FileExists(DFile) == true)
558 {
559 if (ReadConfigFile(Database,DFile) == false)
560 return _error->Error("Unable to read the cdrom database %s",
561 DFile.c_str());
562 }
563 if(log) {
564 msg.str("");
db0db9fe 565 ioprintf(msg, _("Stored label: %s \n"),
a75c6a6e
MZ
566 Database.Find("CD::"+ident).c_str());
567 log->Update(msg.str());
568 }
569 return true;
570}
571
572
573bool pkgCdrom::Add(pkgCdromStatus *log)
574{
575 stringstream msg;
576
577 // Startup
578 string CDROM = _config->FindDir("Acquire::cdrom::mount","/cdrom/");
579 if (CDROM[0] == '.')
580 CDROM= SafeGetCWD() + '/' + CDROM;
581
582 if(log) {
583 log->SetTotal(STEP_LAST);
584 msg.str("");
585 ioprintf(msg, _("Using CD-ROM mount point %s\n"), CDROM.c_str());
586 log->Update(msg.str(), STEP_PREPARE);
587 }
588
589 // Read the database
590 Configuration Database;
591 string DFile = _config->FindFile("Dir::State::cdroms");
592 if (FileExists(DFile) == true)
593 {
cdadf54b 594 if (ReadConfigFile(Database,DFile) == false)
a75c6a6e
MZ
595 return _error->Error("Unable to read the cdrom database %s",
596 DFile.c_str());
597 }
598
599 // Unmount the CD and get the user to put in the one they want
600 if (_config->FindB("APT::CDROM::NoMount",false) == false)
601 {
602 if(log)
603 log->Update(_("Unmounting CD-ROM\n"), STEP_UNMOUNT);
604 UnmountCdrom(CDROM);
605
606 if(log) {
607 log->Update(_("Waiting for disc...\n"), STEP_WAIT);
608 if(!log->ChangeCdrom()) {
609 // user aborted
610 return false;
611 }
612 }
613
614 // Mount the new CDROM
615 log->Update(_("Mounting CD-ROM...\n"), STEP_MOUNT);
616 if (MountCdrom(CDROM) == false)
617 return _error->Error("Failed to mount the cdrom.");
618 }
619
620 // Hash the CD to get an ID
621 if(log)
622 log->Update(_("Identifying.. "), STEP_IDENT);
623 string ID;
624 if (IdentCdrom(CDROM,ID) == false)
625 {
626 log->Update("\n");
627 return false;
628 }
629 if(log)
630 log->Update("["+ID+"]\n");
631
632 if(log)
db0db9fe 633 log->Update(_("Scanning disc for index files..\n"),STEP_SCAN);
a75c6a6e
MZ
634
635 // Get the CD structure
636 vector<string> List;
637 vector<string> SourceList;
638 vector<string> SigList;
22f8568d 639 vector<string> TransList;
a75c6a6e
MZ
640 string StartDir = SafeGetCWD();
641 string InfoDir;
22f8568d 642 if (FindPackages(CDROM,List,SourceList, SigList,TransList,InfoDir,log) == false)
a75c6a6e
MZ
643 {
644 log->Update("\n");
645 return false;
646 }
647
648 chdir(StartDir.c_str());
649
650 if (_config->FindB("Debug::aptcdrom",false) == true)
651 {
652 cout << "I found (binary):" << endl;
653 for (vector<string>::iterator I = List.begin(); I != List.end(); I++)
654 cout << *I << endl;
655 cout << "I found (source):" << endl;
656 for (vector<string>::iterator I = SourceList.begin(); I != SourceList.end(); I++)
657 cout << *I << endl;
658 cout << "I found (Signatures):" << endl;
659 for (vector<string>::iterator I = SigList.begin(); I != SigList.end(); I++)
660 cout << *I << endl;
661 }
662
663 //log->Update(_("Cleaning package lists..."), STEP_CLEAN);
664
665 // Fix up the list
666 DropBinaryArch(List);
667 DropRepeats(List,"Packages");
668 DropRepeats(SourceList,"Sources");
669 DropRepeats(SigList,"Release.gpg");
22f8568d 670 DropRepeats(TransList,"");
a75c6a6e
MZ
671 if(log) {
672 msg.str("");
22f8568d
MV
673 ioprintf(msg, _("Found %i package indexes, %i source indexes, "
674 "%i translation indexes and %i signatures\n"),
675 List.size(), SourceList.size(), TransList.size(),
676 SigList.size());
a75c6a6e
MZ
677 log->Update(msg.str(), STEP_SCAN);
678 }
679
cdadf54b
MV
680 if (List.size() == 0 && SourceList.size() == 0)
681 {
682 UnmountCdrom(CDROM);
a75c6a6e 683 return _error->Error("Unable to locate any package files, perhaps this is not a Debian Disc");
cdadf54b 684 }
a75c6a6e
MZ
685
686 // Check if the CD is in the database
687 string Name;
688 if (Database.Exists("CD::" + ID) == false ||
689 _config->FindB("APT::CDROM::Rename",false) == true)
690 {
691 // Try to use the CDs label if at all possible
692 if (InfoDir.empty() == false &&
693 FileExists(InfoDir + "/info") == true)
694 {
695 ifstream F(string(InfoDir + "/info").c_str());
696 if (!F == 0)
697 getline(F,Name);
698
699 if (Name.empty() == false)
700 {
701 // Escape special characters
702 string::iterator J = Name.begin();
703 for (; J != Name.end(); J++)
704 if (*J == '"' || *J == ']' || *J == '[')
705 *J = '_';
706
707 if(log) {
708 msg.str("");
709 ioprintf(msg, "Found label '%s'\n", Name.c_str());
710 log->Update(msg.str());
711 }
712 Database.Set("CD::" + ID + "::Label",Name);
713 }
714 }
715
716 if (_config->FindB("APT::CDROM::Rename",false) == true ||
717 Name.empty() == true)
718 {
719 if(!log)
cdadf54b
MV
720 {
721 UnmountCdrom(CDROM);
a75c6a6e 722 return _error->Error("No disc name found and no way to ask for it");
cdadf54b 723 }
a75c6a6e
MZ
724
725 while(true) {
726 if(!log->AskCdromName(Name)) {
727 // user canceld
728 return false;
729 }
730 cout << "Name: '" << Name << "'" << endl;
731
732 if (Name.empty() == false &&
733 Name.find('"') == string::npos &&
734 Name.find('[') == string::npos &&
735 Name.find(']') == string::npos)
736 break;
737 log->Update(_("That is not a valid name, try again.\n"));
738 }
739 }
740 }
741 else
742 Name = Database.Find("CD::" + ID);
743
744 // Escape special characters
745 string::iterator J = Name.begin();
746 for (; J != Name.end(); J++)
747 if (*J == '"' || *J == ']' || *J == '[')
748 *J = '_';
749
750 Database.Set("CD::" + ID,Name);
751 if(log) {
752 msg.str("");
db0db9fe 753 ioprintf(msg, _("This disc is called: \n'%s'\n"), Name.c_str());
a75c6a6e
MZ
754 log->Update(msg.str());
755 }
756
757 log->Update(_("Copying package lists..."), STEP_COPY);
758 // take care of the signatures and copy them if they are ok
759 // (we do this before PackageCopy as it modifies "List" and "SourceList")
760 SigVerify SignVerify;
761 SignVerify.CopyAndVerify(CDROM, Name, SigList, List, SourceList);
762
763 // Copy the package files to the state directory
764 PackageCopy Copy;
765 SourceCopy SrcCopy;
22f8568d 766 TranslationsCopy TransCopy;
a75c6a6e 767 if (Copy.CopyPackages(CDROM,Name,List, log) == false ||
22f8568d
MV
768 SrcCopy.CopyPackages(CDROM,Name,SourceList, log) == false ||
769 TransCopy.CopyTranslations(CDROM,Name,TransList, log) == false)
a75c6a6e
MZ
770 return false;
771
772 // reduce the List so that it takes less space in sources.list
773 ReduceSourcelist(CDROM,List);
774 ReduceSourcelist(CDROM,SourceList);
775
776 // Write the database and sourcelist
777 if (_config->FindB("APT::cdrom::NoAct",false) == false)
778 {
779 if (WriteDatabase(Database) == false)
780 return false;
781
782 if(log) {
783 log->Update(_("Writing new source list\n"), STEP_WRITE);
784 }
785 if (WriteSourceList(Name,List,false) == false ||
786 WriteSourceList(Name,SourceList,true) == false)
787 return false;
788 }
789
790 // Print the sourcelist entries
791 if(log)
db0db9fe 792 log->Update(_("Source list entries for this disc are:\n"));
a75c6a6e
MZ
793
794 for (vector<string>::iterator I = List.begin(); I != List.end(); I++)
795 {
796 string::size_type Space = (*I).find(' ');
797 if (Space == string::npos)
cdadf54b
MV
798 {
799 UnmountCdrom(CDROM);
a75c6a6e 800 return _error->Error("Internal error");
cdadf54b 801 }
a75c6a6e
MZ
802
803 if(log) {
804 msg.str("");
805 msg << "deb cdrom:[" << Name << "]/" << string(*I,0,Space) <<
806 " " << string(*I,Space+1) << endl;
807 log->Update(msg.str());
808 }
809 }
810
811 for (vector<string>::iterator I = SourceList.begin(); I != SourceList.end(); I++)
812 {
813 string::size_type Space = (*I).find(' ');
814 if (Space == string::npos)
cdadf54b
MV
815 {
816 UnmountCdrom(CDROM);
a75c6a6e 817 return _error->Error("Internal error");
cdadf54b 818 }
a75c6a6e
MZ
819
820 if(log) {
821 msg.str("");
822 msg << "deb-src cdrom:[" << Name << "]/" << string(*I,0,Space) <<
823 " " << string(*I,Space+1) << endl;
824 log->Update(msg.str());
825 }
826 }
827
828
829
830 // Unmount and finish
831 if (_config->FindB("APT::CDROM::NoMount",false) == false) {
832 log->Update(_("Unmounting CD-ROM..."), STEP_LAST);
833 UnmountCdrom(CDROM);
834 }
835
836 return true;
837}