~tsimonq2/debian-cd/lubuntu-cosmic-changes

30 by Arch Librarian
Initial revision
1
#!/usr/bin/perl -w
2
#
3
# Copyright 1999 Raphaël Hertzog <hertzog@debian.org>
4
# See the README file for the license
5
#
6
# This script takes 2 arguments on input :
7
# - a filename listing all the packages to include
8
# - a size-limit for each CD
9
#
10
11
use strict;
12
13
my $list = shift;
83 by Arch Librarian
* Documentation updates.
14
my $deflimit = $ENV{'SIZELIMIT'} || shift || 639631360;
30 by Arch Librarian
Initial revision
15
my $limit = $ENV{'SIZELIMIT1'} || $deflimit;
16
17
my $nonfree = $ENV{'NONFREE'} || 0;
109 by Arch Librarian
* Added support for EXTRANONFREE. Hope it works :-)
18
my $extranonfree = $ENV{'EXTRANONFREE'} || 0;
30 by Arch Librarian
Initial revision
19
my $nonus = $ENV{'NONUS'} || 0;
118 by Arch Librarian
Added FORCENONUSONCD1 option - forces non-US packages/s...
20
my $forcenonusoncd1 = $ENV{'FORCENONUSONCD1'} || 0;
48 by Arch Librarian
* Many modifications to support the inclusion of local ...
21
my $local = $ENV{'LOCAL'} || 0;
30 by Arch Librarian
Initial revision
22
my $complete = $ENV{'COMPLETE'} || 0;
576 by Arch Librarian
Preprocess exclude files much like tasks files are. Clo...
23
my $exclude = "$list.exclude";
769 by Colin Watson
allow disabling dependency checks in list2cds
24
my $nodepends = $ENV{'NODEPENDS'} || 0;
279 by Arch Librarian
* Make the log output more consistent.
25
my $norecommends = $ENV{'NORECOMMENDS'} || 0;
297 by Arch Librarian
* Include languages packs.
26
my $nosuggests = $ENV{'NOSUGGESTS'} || 1;
607 by Arch Librarian
- Add MAXCDS config variable, which forces debian-cd to...
27
my $maxcds = $ENV{'MAXCDS'} || 0;
1104 by Colin Watson
disable overflow of binary CDs
28
my $overflowbincds = $ENV{'OVERFLOWBINCDS'} || 1;
30 by Arch Librarian
Initial revision
29
30
my $apt = "$ENV{'BASEDIR'}/tools/apt-selection";
1049 by Colin Watson
Add subarchitecture support
31
my $adir = "$ENV{'APTTMP'}/$ENV{'CODENAME'}-$ENV{'FULLARCH'}";
32
my $dir = "$ENV{'TDIR'}/$ENV{'CODENAME'}-$ENV{'FULLARCH'}";
30 by Arch Librarian
Initial revision
33
my $verbose = $ENV{'VERBOSE'} || 0;
34
35
$| = 1; # Autoflush for debugging
36
37
open(LOG, ">$dir/log.list2cds") || die "Can't write in $dir/log.list2cds !\n";
38
39
sub msg {
40
	my $level = shift;
41
	if ($verbose >= $level) {
42
		print @_;
43
	}
44
	print LOG @_;
45
}
46
47
my %included;
48
my %excluded;
49
my %packages;
50
445 by Arch Librarian
more or less cosmetic language fixes
51
msg(0, "======================================================================
52
Here are the settings you've chosen for making the list:
53
List of prefered packages: $list
54
Exclude file: $exclude
55
");
56
msg(0, "Complete selected packages with all the rest: "); msg(0, yesno($complete)."\n");
57
msg(0, "Include non-free packages: "); msg(0, yesno($nonfree)."\n");
58
msg(0, "Include non-US packages: "); msg(0, yesno($nonus)."\n");
59
msg(0, "======================================================================
30 by Arch Librarian
Initial revision
60
");
61
445 by Arch Librarian
more or less cosmetic language fixes
62
# Get the information on all packages
30 by Arch Librarian
Initial revision
63
my $oldrs = $/;
64
$/ = '';
65
open(AVAIL, "$apt cache dumpavail |") || die "Can't fork : $!\n";
66
my ($p, $re);
67
while (defined($_=<AVAIL>)) {
68
	next if not m/^Package: (\S+)\s*$/m;
69
	$p = $1;
70
	$included{$p} = 0;
71
	$packages{$p}{"Package"} = $p;
72
	foreach $re (qw(Version Priority Section Filename Size MD5sum)) {
73
		(m/^$re: (\S+)\s*$/m and $packages{$p}{$re} = $1)
74
		|| msg(1, "Header field '$re' missing for package '$p'.\n");
75
	}
76
	$packages{$p}{"Depends"} = [];
77
	$packages{$p}{"Suggests"} = [];
78
	$packages{$p}{"Recommends"} = [];
402 by Arch Librarian
* Include patches from Petter Reinholdtsen and Santiago...
79
	$packages{$p}{"IsUdeb"} = ($packages{$p}{"Filename"} =~ /.udeb$/) ? 1 : 0;
30 by Arch Librarian
Initial revision
80
}
81
close AVAIL or die "apt-cache failed : $@ ($!)\n";
82
$/ = $oldrs;
83
84
# Get the list of excluded packages
85
%excluded = %included;
86
my $count_excl = 0;
87
if (-e $exclude) {
88
	open (EXCL, "< $exclude") || die "Can't open $exclude : $!\n";
89
	while (defined($_=<EXCL>)) {
90
		chomp;
564 by Arch Librarian
Update list2cds to allow #-comments in the exclude file.
91
		s/\#.*$//;
92
		next if m/^\s*$/;
30 by Arch Librarian
Initial revision
93
		if (not exists $packages{$_}) {
194 by Arch Librarian
* Added exclude feature for source packages and un-excl...
94
			msg(1, "INIT: Package '$_' is in excluded but " .
95
			       "doesn't exist. Ignored.\n");
30 by Arch Librarian
Initial revision
96
			next;
97
		}
98
		$excluded{$_} = 'user choice';
99
		$count_excl++;
100
	}
101
	close EXCL;
102
}
103
104
# Now exclude more packages because of the non-free and non-us rules
105
if (not $nonfree) {
106
	foreach (grep { $packages{$_}{"Section"} =~ /non-free/ }
107
	              (keys %packages)) {
108
		$excluded{$_} = 'nonfree';
109
		$count_excl++;
110
	}
111
}
112
if (not $nonus) {
113
	foreach (grep { $packages{$_}{"Section"} =~ /non-US/ }
114
	              (keys %packages)) {
115
		$excluded{$_} = 'nonus';
116
		$count_excl++;
117
	}
118
}
119
445 by Arch Librarian
more or less cosmetic language fixes
120
msg(0, "Statistics:
121
Number of packages: @{ [scalar(keys %packages)] }
122
Number of excluded: $count_excl of @{ [scalar(keys %excluded)] }
30 by Arch Librarian
Initial revision
123
======================================================================
124
125
");
126
127
open(STATS, "> $dir/stats.excluded") 
128
			|| die "Can't write in stats.excluded: $!\n";
129
foreach (keys %excluded) {
130
	print STATS "$_ => $excluded{$_}\n";
131
}
132
close (STATS);
133
134
# Browse the list of packages to include
135
my ($total_size, $cd_size, $size, $cd) = (0, 0, 0, 1);
136
my %cds;
137
784 by Colin Watson
avoid generating dependency tree
138
=pod
30 by Arch Librarian
Initial revision
139
# Generate a dependency tree for each package
140
msg(0, "-- Generating dependencies tree with apt-cache depends...\n");
141
my (@list) = keys %packages;
142
while (@list) {
143
	my (@pkg) = splice(@list,0,200);
738 by Arch Librarian
- 1 line patch to fix a nasty (5 year old) bug. Closes:...
144
	$ENV{'LC_ALL'} = 'C'; # Required since apt is now translated
30 by Arch Librarian
Initial revision
145
	open (APT, "$apt cache depends @pkg |") || die "Can't fork : $!\n";
146
	my (@res) = (<APT>);
147
	close APT or die "« apt-cache depends » failed ... \n" . 
148
	                 "you must have apt >= 0.3.11.1 !\n";
149
	# Getting rid of conflicts/replaces/provides
150
	my $i = 0;
151
	my $nb_lines = scalar @res;
152
	push @res, ""; # Avoid warnings ...
153
	while ($i < $nb_lines) {
154
		if ($res[$i] !~ m/^(\S+)\s*$/) {
155
			msg(0, "UNEXPECTED: Line `$res[$i]' while parsing " .
156
			       "end of deptree from '$p'\n");
157
		}
158
		$p = $1; $i++;
159
		msg(2, "   Dependency tree of `$p' ...\n");
160
		read_depends (\$i, \@res, $p);
161
	}
162
	
163
}
784 by Colin Watson
avoid generating dependency tree
164
=cut
30 by Arch Librarian
Initial revision
165
402 by Arch Librarian
* Include patches from Petter Reinholdtsen and Santiago...
166
msg(0, "-- Adding standard, required, important and base packages \n" .
167
       "   on the first CD ...\n");
168
# Automatically include packages listed in the status file
169
open(STATUS, "< $adir/status") || die "Can't open status file : $!\n";
170
while (defined($_ = <STATUS>)) {
171
       next if not m/^Package: (\S+)/;
172
       $p = $1;
173
       if (not exists $packages{$p}) {
174
               msg(1, "WARNING: Package `$p' is listed in the status file "
175
                      . "but doesn't exist ! (ignored) \n",
176
                      "    TIP: Try to generate the status file with " .
177
                       "make (correct)status (after a make distclean)...\n");
178
                next;
179
       }
180
       next if $excluded{$p};
181
       add_package($p, ! $norecommends, ! $nosuggests);
182
}
183
close STATUS;
184
msg(0, "   Standard system already takes $cd_size bytes on the first CD.\n");
185
30 by Arch Librarian
Initial revision
186
# Now start to look for packages wanted by the user ...
187
msg(0, "-- Starting to add packages to the CDs ...\n");
188
open (LIST, "< $list") || die "Can't open $list : $!\n";
189
while (defined($_=<LIST>)) {
190
	chomp;
191
	next if m/^\s*$/;
1177 by Colin Watson
implement forced CD breaks using FORCE-CD-BREAK in a list
192
	if ($_ eq 'FORCE-CD-BREAK') {
193
	    msg(0, "CD break encountered at $cd_size bytes.\n");
194
	    new_cd();
195
	    next;
196
	}
30 by Arch Librarian
Initial revision
197
	if (not exists $packages{$_}) { 
198
	    msg(1, "WARNING: '$_' does not appear to be available ... " . 
199
	           "(ignored)\n");
200
	    next;
201
	}
202
	next if $excluded{$_};
203
	if ($included{$_}) {
204
	    msg(3, "$_ has already been included.\n");
205
	    next;
206
	}
402 by Arch Librarian
* Include patches from Petter Reinholdtsen and Santiago...
207
	# This is because udebs tend to have bad dependencies but work
208
	# nevertheless ... this may be removed once the udebs have a
209
	# better depencency system
210
	if ($packages{$_}{"IsUdeb"}) {
405 by Arch Librarian
- SKIPMIRRORCHECK=yes can disable the mirror check in b...
211
	    add_to_cd($cd, $packages{$_}{"Size"}, [$_]);
402 by Arch Librarian
* Include patches from Petter Reinholdtsen and Santiago...
212
	} else {
213
	    add_package ($_, ! $norecommends, ! $nosuggests);
214
	}
30 by Arch Librarian
Initial revision
215
}
216
close LIST;
217
218
# All requested packages have been included
219
# But we'll continue to add if $complete was requested
220
if ($complete) {
221
    msg(0, "-- Now we'll add all the packages not yet included ...\n");
222
    # Try to sort them by section even if packages from
223
    # other sections will get in through dependencies
224
    # With some luck, most of them will already be here
437 by Arch Librarian
shortened some silly-code :)
225
    foreach my $p (sort { ($packages{$a}{"Section"} cmp $packages{$b}{"Section"})
226
                       || ($a cmp $b) }
30 by Arch Librarian
Initial revision
227
             grep { not ($included{$_} or $excluded{$_}) } keys %packages) {
297 by Arch Librarian
* Include languages packs.
228
	add_package ($p, 0, 0);
30 by Arch Librarian
Initial revision
229
    }
230
}
231
msg(0, "CD $cd will only be filled with $cd_size bytes ...\n");
232
109 by Arch Librarian
* Added support for EXTRANONFREE. Hope it works :-)
233
# Now select the non-free packages for an extra CD
234
if ($extranonfree and (! $nonfree))
235
{
236
	my ($p, @toinclude);
237
	
238
	# Finally accept non-free packages ...
239
	foreach $p (grep { $excluded{$_} eq "nonfree" } (keys %excluded))
240
	{
241
		$excluded{$p} = 0;
242
		push @toinclude, $p;
243
	}
244
	
245
	# Start a new CD
246
	$cd++;
247
	$cd_size = 0;
248
	$limit = $ENV{"SIZELIMIT$cd"} || $deflimit;
249
	msg(0, "Limit for non-free CD $cd is $limit.\n");
250
	
251
	# Include non-free packages
252
	foreach $p (@toinclude)
253
	{
297 by Arch Librarian
* Include languages packs.
254
		add_package($p, 1, 1);
109 by Arch Librarian
* Added support for EXTRANONFREE. Hope it works :-)
255
	}
256
257
	# If a contrib package was listed in the list of packages to
258
	# include and if COMPLETE=0 there's a chance that the package
259
	# will not get included in any CD ... so I'm checking the complete
260
	# list again
261
	open (LIST, "< $list") || die "Can't open $list : $!\n";
262
	while (defined($_=<LIST>)) {
263
		chomp;
264
		next if m/^\s*$/;
1177 by Colin Watson
implement forced CD breaks using FORCE-CD-BREAK in a list
265
		next if $_ eq 'FORCE-CD-BREAK';
109 by Arch Librarian
* Added support for EXTRANONFREE. Hope it works :-)
266
		next if $included{$_};
267
		next if $excluded{$_};
268
		if (not exists $packages{$_}) { 
269
		  msg(1, "WARNING: '$_' does not appear to be available ... " . 
270
	          	 "(ignored)\n");
271
		  next;
272
		}
297 by Arch Librarian
* Include languages packs.
273
		add_package ($_, 1, 1);
109 by Arch Librarian
* Added support for EXTRANONFREE. Hope it works :-)
274
	}
275
	close LIST;
276
277
	# Try to include other packages that could not be included
278
	# before (because they depends on excluded non-free packages)
279
	if ($complete)
280
	{
281
	    foreach $p (sort { ($packages{$a}{"Section"} 
282
				cmp $packages{$b}{"Section"}) || ($a cmp $b) }
283
			grep { not ($included{$_} or $excluded{$_}) } 
284
			keys %packages) 
285
	    {
297 by Arch Librarian
* Include languages packs.
286
		add_package ($p, 0, 0);
109 by Arch Librarian
* Added support for EXTRANONFREE. Hope it works :-)
287
	    }
288
	}
289
290
	msg(0, "CD $cd will only be filled with $cd_size bytes ...\n");
291
}
292
30 by Arch Librarian
Initial revision
293
# Remove old files
294
foreach (glob("$dir/*.packages")) {
295
	unlink $_;
296
}
297
298
# Now write the lists down
607 by Arch Librarian
- Add MAXCDS config variable, which forces debian-cd to...
299
my $numcds=0;
512 by Arch Librarian
- Remove kernel cruft.
300
foreach (sort { $a <=> $b } keys %cds) {
607 by Arch Librarian
- Add MAXCDS config variable, which forces debian-cd to...
301
	if ($maxcds && $numcds+1 > $maxcds) {
302
		msg(0, "Stopping at CD $numcds\n");
303
		last;
304
	}
305
	$numcds++;
306
	
30 by Arch Librarian
Initial revision
307
	my $count = 0;
308
	open(CDLIST, "> $dir/$_.packages") 
309
			|| die "Can't write in $dir/$_.packages: $!\n";
310
	foreach (@{$cds{$_}}) {
311
		print CDLIST "$_\n";
312
		$count++;
313
	}
314
	close CDLIST;
315
	msg(0, "CD $_ will have $count packages.\n");
316
}
878 by Colin Watson
make sure 1.packages is always created even if there are no packages (live CD case)
317
if ($numcds == 0) {
318
	open(CDLIST, "> $dir/1.packages")
319
			|| die "Can't write in $dir/1.packages: $!\n";
320
	close CDLIST;
321
}
30 by Arch Librarian
Initial revision
322
323
close LOG;
324
325
## END OF MAIN
326
## BEGINNING OF SUBS
327
328
sub read_depends {
329
	my $i = shift;     # Ref
330
	my $lines = shift; # Ref
331
	my $pkg = shift;   # string
332
	my $types = "(?:Pre)?Depends|Suggests|Recommends|Replaces|Conflicts";
333
	my (@dep, @rec, @sug);
334
	my ($type, $or, $elt);
335
336
	while ($lines->[$$i] =~ m/^\s([\s\|])($types):/) {
337
		$type = $2; $or = $1;
338
		# Get rid of replaces and conflicts ...
339
		if (($type eq "Replaces") or ($type eq "Conflicts")) {
340
			$$i++;
341
			while ($lines->[$$i] =~ m/^\s{4}/) {
342
				$$i++;
343
			}
344
			next;
345
		}
346
		# Check the kind of depends : or, virtual, normal
347
		if ($or eq '|') {
348
			$elt = read_ordepends ($i, $lines);
349
		} elsif ($lines->[$$i] =~ m/^\s\s$type: <([^>]+)>/) {
350
			$elt = read_virtualdepends ($i, $lines);
351
		} elsif ($lines->[$$i] =~ m/^\s\s$type: (\S+)/) {
352
			$elt = $1; $$i++;
353
			# Special case for packages providing not
354
			# truely virtual packages
355
			if ($lines->[$$i] =~ m/^\s{4}/) {
356
				$elt = [ $elt ];
357
				while ($lines->[$$i] =~ m/\s{4}(\S+)/) {
358
					push @{$elt}, $1;
359
					$$i++;
360
				}
361
			}
362
		} else {
363
			msg(0, "ERROR: Unknown depends line : $lines->[$$i]\n");
364
			foreach ($$i - 3 .. $$i + 3) {
365
				msg(0, "      ", $lines->[$_]);
366
			}
367
		}
368
		$type =~ s/^Pre//; # PreDepends are like Depends for me 
369
		next if dep_satisfied($elt);
370
		push @{$packages{$pkg}{$type}}, $elt;
371
	}
372
}
373
374
sub dep_satisfied {
375
	my $p = shift;
376
	if (ref $p) {
377
		foreach (@{$p}) {
738 by Arch Librarian
- 1 line patch to fix a nasty (5 year old) bug. Closes:...
378
			return 1 if $included{$_};
30 by Arch Librarian
Initial revision
379
		}
380
	} else {
381
		return $included{$p};
382
	}
383
	return 0;
384
}
385
386
sub read_ordepends {
387
	my $i = shift;
388
	my $lines = shift;
389
	my @or = ();
390
	my ($val,$dep, $last) = ('','',0);
391
	
392
	while ($lines->[$$i] 
393
	            =~ m/^\s([\s\|])((?:Pre)?Depends|Suggests|Recommends): (\S+)/) {
394
		$val = $3;
395
		$last = 1 if $1 ne '|'; #Stop when no more '|'
396
		if ($val =~ m/^<.*>$/) {
397
			$dep = read_virtualdepends ($i, $lines);
398
			if (ref $dep) {
399
				push @or, @{$dep};
400
			} else {
401
				push @or, $dep;
402
			}
403
		} else {
404
			push @or, $val; $$i++;
405
			# Hack for packages providing not a truely
406
			# virtual package
407
			while ($lines->[$$i] =~ m/^\s{4}(\S+)/) {
408
				push @or, $1;
409
				$$i++;
410
			}
411
		}
412
		last if $last;
413
	}
414
	return \@or;
415
}
416
417
sub read_virtualdepends {
418
	my $i = shift;
419
	my $lines = shift;
420
	my $virtual;
421
	my @or = ();
422
423
	#Check for the lines with <>
424
	if ($lines->[$$i] 
425
	    =~ m/^\s[\s\|]((?:Pre)?Depends|Recommends|Suggests): <([^>]+)>/) {
426
	    $virtual = $2;
427
	    $$i++
428
	}
429
	# Now look at the alternatives on the following lines
430
	while ($lines->[$$i] =~ m/^\s{4}(\S+)/) {
431
		push @or, $1;
432
		$$i++;
433
	}
434
	if (@or) {
435
		return \@or;
436
	} else {
437
		return $virtual;
438
	}
439
}
440
1177 by Colin Watson
implement forced CD breaks using FORCE-CD-BREAK in a list
441
sub new_cd {
442
	$cd++;
443
	$cd_size = 0;
444
	# New limit
445
	$limit = $ENV{"SIZELIMIT$cd"} || $deflimit;
446
	msg(2, "Limit for CD $cd is $limit.\n");
447
448
	# Unexclude packages
449
	unexclude ($cd);
450
}
451
30 by Arch Librarian
Initial revision
452
sub add_package {
453
	my $p = shift;
297 by Arch Librarian
* Include languages packs.
454
	my $add_rec = shift; # Do we look for recommends
455
	my $add_sug = shift; # Do we look for suggests
30 by Arch Librarian
Initial revision
456
	
457
	msg(2, "+ Trying to add $p...\n");
458
	if ($included{$p}) {
459
		msg(2, "  Already included ...\n");
460
		return;
461
	}
462
	
463
	# Get all dependencies (not yet included) of each package
464
	my (@dep) = (get_missing ($p));
465
466
	# Stop here if apt failed
467
	if (not scalar(@dep)) {
468
		msg(2, "Can't add $p ... dependency problem.\n");
469
		return;
470
	}
471
	
472
	msg(3, "  \@dep before checklist = @dep\n");
473
	
474
	# Check if all packages are allowed (fail if one cannot)
475
	if (not check_list (\@dep, 1)) {
476
		msg(2, "Can't add $p ... one of the package needed has " .
477
		       "been refused.\n"); 
478
		return;
479
	}
480
	
481
	msg(3, "  \@dep after checklist = @dep\n");
482
	
483
	if ($add_rec) {
297 by Arch Librarian
* Include languages packs.
484
	    #TODO: Look for recommends (not yet included !!)
485
		add_recommends (\@dep);
486
	    	# Check again but doesn't fail if one of the package cannot be
487
	    	# installed, just ignore it (it will be removed from @dep)
488
	    	if (not check_list (\@dep, 0)) {
489
	    		msg(0, "UNEXPECTED: It shouldn't fail here !\n");
490
	    		return;
491
	    	}
492
		msg(3, "  \@dep after checklist2 = @dep\n");
493
	}
494
	
495
	if ($add_sug) {
496
	    #TODO: Look for suggests (not yet included !!)
30 by Arch Librarian
Initial revision
497
		add_suggests (\@dep);
498
	    	# Check again but doesn't fail if one of the package cannot be
499
	    	# installed, just ignore it (it will be removed from @dep)
500
	    	if (not check_list (\@dep, 0)) {
501
	    		msg(0, "UNEXPECTED: It shouldn't fail here !\n");
502
	    		return;
503
	    	}
297 by Arch Librarian
* Include languages packs.
504
		msg(3, "  \@dep after checklist3 = @dep\n");
30 by Arch Librarian
Initial revision
505
	}
506
	
507
	# All packages are ok, now check for the size issue
508
	$size = get_size (\@dep);
509
510
	# Creation of a new CD when needed
1104 by Colin Watson
disable overflow of binary CDs
511
	if ($overflowbincds and $cd_size + $size > $limit) {
976 by Colin Watson
merge from upstream up to patch-800
512
		my $try_size = $cd_size + $size;
30 by Arch Librarian
Initial revision
513
		msg(0, "CD $cd filled with $cd_size bytes ... ",
976 by Colin Watson
merge from upstream up to patch-800
514
		       "(limit was $limit, would have taken $try_size)\n");		
1177 by Colin Watson
implement forced CD breaks using FORCE-CD-BREAK in a list
515
		new_cd();
30 by Arch Librarian
Initial revision
516
	}
89 by Arch Librarian
PowerPC boot support
517
279 by Arch Librarian
* Make the log output more consistent.
518
	add_to_cd ($cd, $size, \@dep);
30 by Arch Librarian
Initial revision
519
}
520
521
sub accepted {
522
	my $p = shift;
523
	return not $excluded{$p} if (exists $excluded{$p});
524
	# Return false for a non-existant package ...
525
	msg(1, "WARNING: $p cannot be accepted, it doesn't exist ...\n");
526
	return 0;
527
}
528
529
sub add_suggests {
530
	my $list = shift;
531
	my $p; # = shift;
532
	my @copy = @{$list}; # A copy is needed since I'll modify the array
533
	
534
	foreach $p (@copy) {
297 by Arch Librarian
* Include languages packs.
535
		add_missing($list, $packages{$p}{"Suggests"});
536
	}
537
		
538
}
539
540
sub add_recommends {
541
	my $list = shift;
542
	my $p; # = shift;
543
	my @copy = @{$list}; # A copy is needed since I'll modify the array
544
	
545
	foreach $p (@copy) {
30 by Arch Librarian
Initial revision
546
		add_missing($list, $packages{$p}{"Recommends"});
547
	}
548
		
549
}
550
551
sub get_missing {
552
	my $p = shift;
553
	my @list = ($p);
554
	
555
	if (not add_missing (\@list, $packages{$p}{"Depends"})) {
556
		return ();
557
	}
558
	
559
	return (@list);
560
}
561
562
# Recursive function adding to the 
563
sub add_missing {
564
	my $list = shift;
565
	my $new = shift;
566
	my @backup = @{$list};
567
	my $ok = 1;
769 by Colin Watson
allow disabling dependency checks in list2cds
568
	return $ok if $nodepends;
30 by Arch Librarian
Initial revision
569
	
570
	# Check all dependencies 
571
	foreach (@{$new}) {
572
		next if dep_satisfied ($_);
573
		# If it's an OR
574
		if (ref) {
575
			my $or_ok = 0;
576
			# Loop over each package in the OR
577
			foreach my $pkg (@{$_}) {
578
				next if not accepted ($pkg);
579
				# If the package is already included
580
				# then don't worry
581
				if ($included{$pkg}) {
582
					$or_ok = 1;
583
					last;
584
				}
585
				# Check we don't already have the package
586
				if (is_in ($pkg, $list)) {
587
					$or_ok = 1;
588
					last;
589
				# Otherwise try to add it
590
				} else {
591
					#Instead of doing a bad choice I'm
592
					#including all packages that do
593
					#fit to the needs
594
					push (@{$list}, $pkg);
595
					if (add_missing ($list,
596
					         $packages{$pkg}{"Depends"})) 
597
					{
598
						$or_ok = 1;
599
					} else {
600
						pop @{$list};
601
					}
602
				}
603
			}
604
			$ok &&= $or_ok;
605
		# Else it's a simple dependency
606
		} else {
607
			if (not exists $packages{$_}) {
608
				msg(1, "$_ doesn't exist...\n");
609
				$ok = 0;
610
				last;
611
			}
612
			next if $included{$_}; # Already included, don't worry
613
			next if is_in ($_, $list);
614
			push @{$list}, $_;
615
			if (not add_missing ($list, $packages{$_}{"Depends"})) {
616
				pop @{$list};
617
				$ok = 0;
618
			}
619
		}
620
	}
621
	# If a problem has come up, then restore the original list
622
	if (not $ok) {
623
		@{$list} = @backup;
624
	}
625
	return $ok;
626
}
627
628
# Check if $value is in @{$array}
629
sub is_in {
630
	my $value = shift;
631
	my $array = shift;
437 by Arch Librarian
shortened some silly-code :)
632
	foreach my $key (@{$array}) {
30 by Arch Librarian
Initial revision
633
		return 1 if ($key eq $value);
634
	}
635
	return 0;		
636
}
637
638
# The size of a group of packages
639
sub get_size {
640
	my $arrayref = shift;
641
	my $size = 0;
642
	foreach (@{$arrayref}) {
643
		$size += $packages{$_}{"Size"};
644
	}
645
	return $size;
646
}
647
648
# Check a list of packages
649
sub check_list {
650
	my $ref = shift;
651
	my $fail = shift;
652
	my $ok = 1;
653
	my @to_remove = ();
654
	foreach (@{$ref}) {
655
		if (not exists $excluded{$_}) {
656
		  msg(1,"  $_ has been refused because it doesn't exist ...\n");
657
		  $ok = 0;
658
		  push @to_remove, $_;
659
		  next;
660
		}
661
		if (not accepted($_)) {
662
		  msg(1,"  $_ has been refused because of $excluded{$_} ...\n");
663
		  $ok = 0;
664
		  push @to_remove, $_;
665
		  next;
666
		}
667
		if ($included{$_}) {
668
		  msg(1, 
669
		      "  $_ has already been included in CD $included{$_}.\n");
670
		  push @to_remove, $_;
671
		  next;
672
		}
673
	}
437 by Arch Librarian
shortened some silly-code :)
674
	foreach my $removed (@to_remove) {
30 by Arch Librarian
Initial revision
675
		msg(2, "  Removing $removed ...\n");
676
		@{$ref} = grep { $_ ne $removed } @{$ref};
677
	}
678
	return ($fail ? $ok : 1);
679
}
680
681
# Add packages to the current CD number $cd
682
sub add_to_cd {
683
	my $cd = shift;
279 by Arch Librarian
* Make the log output more consistent.
684
	my $size = shift;
30 by Arch Librarian
Initial revision
685
	my $ref = shift;
279 by Arch Librarian
* Make the log output more consistent.
686
687
	msg(2, "  \$cd_size = $cd_size, \$size = $size\n");
688
689
	$cd_size += $size;
690
	$total_size += $size;
691
692
	foreach my $pkg (@{$ref}) {
693
	    $included{$pkg} = $cd;
694
	}
30 by Arch Librarian
Initial revision
695
	$cds{$cd} = [] if not ref $cds{$cd};
696
	msg(2, "  Adding @{$ref} to CD $cd ...\n");
697
	push(@{$cds{$cd}}, @{$ref});
698
}
699
194 by Arch Librarian
* Added exclude feature for source packages and un-excl...
700
# Unexclude packages before given CD is started
701
sub unexclude {
702
	my $cd = shift;
703
	my $unexclude = $ENV{"UNEXCLUDE$cd"} || "$list.unexclude$cd";
704
705
    if (-e $unexclude) {
706
	open (UNEXCL, "< $unexclude") || die "Can't open $unexclude : $!\n";
707
	while (defined($_=<UNEXCL>)) {
708
		chomp;
709
		if (not exists $packages{$_}) {
710
			msg(1, "Package '$_' is in unexcluded but " .
711
			       "doesn't exist. Ignored.\n");
712
			next;
713
		}
714
		$excluded{$_} = 0;
715
		msg(1, "Unexcluding package '$_'\n");
716
	}
717
	close UNEXCL;
718
    }
719
}
445 by Arch Librarian
more or less cosmetic language fixes
720
721
sub yesno {
722
  my $in = shift;
723
  return $in ? "yes" : "no";
724
}