summaryrefslogtreecommitdiffstats
path: root/perl-install/partition_table.pm
blob: 5e26718abc04261709f5147f8ce15e3e1ef40573 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
package partition_table; # $Id$

use diagnostics;
use strict;
use vars qw(@ISA %EXPORT_TAGS @EXPORT_OK @important_types @important_types2 @fields2save @bad_types);

@ISA = qw(Exporter);
%EXPORT_TAGS = (
    types => [ qw(type2name type2fs name2type fs2type isExtended isExt2 isThisFs isTrueFS isSwap isDos isWin isFat isFat_or_NTFS isSunOS isOtherAvailableFS isPrimary isRawLVM isRawRAID isRAID isLVM isMountableRW isNonMountable isPartOfLVM isPartOfRAID isPartOfLoopback isLoopback isMounted isBusy isSpecial maybeFormatted isApple isAppleBootstrap) ],
);
@EXPORT_OK = map { @$_ } values %EXPORT_TAGS;


use common;
use partition_table::raw;
use detect_devices;
use log;

@important_types = ('Linux native', 'Linux swap', 
		    if_(arch() =~ /i.86/, 'Journalised FS: ext3', 'Journalised FS: ReiserFS', 'Journalised FS: JFS', 'Journalised FS: XFS', 'DOS FAT16', 'FAT32'),
			if_(arch() =~ /ia64/, 'Journalised FS: ext3', 'Journalised FS: ReiserFS', 'Journalised FS: XFS', 'FAT32'),
		    if_(arch() =~ /ppc/, 'Journalised FS: ext3', 'Journalised FS: ReiserFS', 'Journalised FS: JFS', 'Journalised FS: XFS', 'Apple HFS Partition', 'Apple Bootstrap'));
@important_types2 = ('Linux RAID', 'Linux Logical Volume Manager partition');

@fields2save = qw(primary extended totalsectors isDirty needKernelReread);

@bad_types = ('Empty', 'DOS 3.3+ Extended Partition', 'Win95: Extended partition, LBA-mapped', 'Linux extended partition');

my %types = (
  0x0 => 'Empty',
if_(arch() =~ /^ppc/, 
  0x183 => 'Journalised FS: ReiserFS',
  0x283 => 'Journalised FS: XFS',
  0x383 => 'Journalised FS: JFS',
  0x483 => 'Journalised FS: ext3',
  0x401	=> 'Apple Partition',
  0x401	=> 'Apple Bootstrap',
  0x402	=> 'Apple HFS Partition',
), if_(arch() =~ /^i.86/,
  0x183 => 'Journalised FS: ReiserFS',
  0x283 => 'Journalised FS: XFS',
  0x383 => 'Journalised FS: JFS',
  0x483 => 'Journalised FS: ext3',
), if_(arch() =~ /^ia64/,
  0x100 => 'Various',
  0x183 => 'Journalised FS: ReiserFS',
  0x283 => 'Journalised FS: XFS',
  0x483 => 'Journalised FS: ext3',
), if_(arch() =~ /^sparc/,
  0x1 => 'SunOS boot',
  0x2 => 'SunOS root',
  0x3 => 'SunOS swap',
  0x4 => 'SunOS usr',
  0x5 => 'Whole disk',
  0x6 => 'SunOS stand',
  0x7 => 'SunOS var',
  0x8 => 'SunOS home',
), if_(arch() =~ /^i.86/,
  0x1 => 'DOS 12-bit FAT',
  0x2 => 'XENIX root',
  0x3 => 'XENIX /usr',
  0x4 => 'DOS 16-bit FAT (up to 32M)',
  0x5 => 'DOS 3.3+ Extended Partition',
  0x6 => 'DOS FAT16',
  0x7 => 'NTFS',
  0x8 => 'OS/2 (v1.0-1.3 only) / AIX boot partition / SplitDrive / Commodore DOS / DELL partition spanning multiple drives / QNX 1.x and 2.x ("qny")',
),
  0x9 => 'AIX data partition / Coherent filesystem / QNX 1.x and 2.x ("qnz")',
  0xa => 'OS/2 Boot Manager / Coherent swap partition / OPUS',
  0xb => 'FAT32',
  0xc => 'Win98 FAT32, LBA-mapped',
  0xe => 'Win95: DOS 16-bit FAT, LBA-mapped',
  0xf => 'Win95: Extended partition, LBA-mapped',
  0x10 => 'OPUS (?)',
  0x11 => 'Hidden DOS 12-bit FAT',
  0x12 => 'Compaq/HP config partition',
  0x14 => 'Hidden DOS 16-bit FAT <32M',
  0x16 => 'Hidden DOS 16-bit FAT >=32M',
  0x17 => 'Hidden IFS (e.g., HPFS)',
  0x18 => 'AST Windows swapfile',
  0x1b => 'Hidden WIN95 OSR2 32-bit FAT',
  0x1c => 'Hidden WIN95 OSR2 32-bit FAT, LBA-mapped',
  0x1e => 'Hidden FAT95',
  0x22 => 'Used for Oxygen Extended Partition Table by ekstazya@sprint.ca.',
  0x24 => 'NEC DOS 3.x',
  0x35 => 'JFS (OS/2)',
  0x38 => 'THEOS ver 3.2 2gb partition',
  0x39 => 'THEOS ver 4 spanned partition',
  0x3a => 'THEOS ver 4 4gb partition',
  0x3b => 'THEOS ver 4 extended partition',
  0x3c => 'PartitionMagic recovery partition',
  0x40 => 'Venix 80286',
  0x41 => 'Linux/MINIX (sharing disk with DRDOS) / Personal RISC Boot / PPC PReP (Power PC Reference Platform) Boot',
  0x42 => 'Windows Dynamic Partition',
  0x43 => 'Linux native (sharing disk with DRDOS)',
  0x45 => 'EUMEL/Elan',
  0x46 => 'EUMEL/Elan 0x46',
  0x47 => 'EUMEL/Elan 0x47',
  0x48 => 'EUMEL/Elan 0x48',
  0x4d => 'QNX4.x',
  0x4e => 'QNX4.x 2nd part',
  0x4f => 'QNX4.x 3rd part / Oberon partition',
  0x50 => 'OnTrack Disk Manager (older versions) RO',
  0x51 => 'OnTrack Disk Manager RW (DM6 Aux1) / Novell',
  0x52 => 'CP/M / Microport SysV/AT',
  0x53 => 'Disk Manager 6.0 Aux3',
  0x54 => 'Disk Manager 6.0 Dynamic Drive Overlay',
  0x55 => 'EZ-Drive',
  0x56 => 'Golden Bow VFeature Partitioned Volume. / DM converted to EZ-BIOS',
  0x57 => 'DrivePro',
  0x5c => 'Priam EDisk',
  0x61 => 'SpeedStor',
  0x63 => 'Unix System V (SCO, ISC Unix, UnixWare, ...), Mach, GNU Hurd',
  0x64 => 'PC-ARMOUR protected partition / Novell Netware 2.xx',
  0x65 => 'Novell Netware 3.xx or 4.xx',
  0x67 => 'Novell',
  0x68 => 'Novell 0x68',
  0x69 => 'Novell 0x69',
  0x70 => 'DiskSecure Multi-Boot',
  0x75 => 'IBM PC/IX',
  0x80 => 'MINIX until 1.4a',
  0x81 => 'MINIX since 1.4b, early Linux / Mitac disk manager',
  0x82 => 'Linux swap',
  0x83 => 'Linux native',
  0x84 => 'OS/2 hidden C: drive / Hibernation partition',
  0x85 => 'Linux extended partition',
  0x86 => 'Old Linux RAID partition superblock / NTFS volume set',
  0x87 => 'NTFS volume set',
  0x8a => 'Linux Kernel Partition (used by AiR-BOOT)',
  0x8e => 'Linux Logical Volume Manager partition',
  0x93 => 'Amoeba',
  0x94 => 'Amoeba bad block table',
  0x99 => 'DCE376 logical drive',
  0xa0 => 'IBM Thinkpad hibernation partition / Phoenix NoteBIOS Power Management "Save-to-Disk" partition',
  0xa5 => 'BSD/386, 386BSD, NetBSD, FreeBSD',
  0xa6 => 'OpenBSD',
  0xa7 => 'NEXTSTEP',
  0xa9 => 'NetBSD',
  0xaa => 'Olivetti Fat 12 1.44Mb Service Partition',
  0xb7 => 'BSDI filesystem',
  0xb8 => 'BSDI swap partition',
  0xbe => 'Solaris boot partition',
  0xc0 => 'CTOS / REAL/32 secure small partition',
  0xc1 => 'DRDOS/secured (FAT-12)',
  0xc4 => 'DRDOS/secured (FAT-16, < 32M)',
  0xc6 => 'DRDOS/secured (FAT-16, >= 32M) / Windows NT corrupted FAT16 volume/stripe set',
  0xc7 => 'Windows NT corrupted NTFS volume/stripe set / Syrinx boot',
  0xcb => 'reserved for DRDOS/secured (FAT32)',
  0xcc => 'reserved for DRDOS/secured (FAT32, LBA)',
  0xcd => 'CTOS Memdump?',
  0xce => 'reserved for DRDOS/secured (FAT16, LBA)',
  0xd0 => 'REAL/32 secure big partition',
  0xd1 => 'Old Multiuser DOS secured FAT12',
  0xd4 => 'Old Multiuser DOS secured FAT16 <32M',
  0xd5 => 'Old Multiuser DOS secured extended partition',
  0xd6 => 'Old Multiuser DOS secured FAT16 >=32M',
  0xd8 => 'CP/M-86',
  0xdb => 'Digital Research CP/M, Concurrent CP/M, Concurrent DOS / CTOS (Convergent Technologies OS -Unisys) / KDG Telemetry SCPU boot',
  0xdd => 'Hidden CTOS Memdump?',
  0xe1 => 'DOS access or SpeedStor 12-bit FAT extended partition',
  0xe3 => 'DOS R/O or SpeedStor',
  0xe4 => 'SpeedStor 16-bit FAT extended partition < 1024 cyl.',
  0xeb => 'BeOS',
  0xee => 'EFI GPT',
  0xef => 'EFI (FAT-12/16/32)',
  0xf1 => 'SpeedStor 0xf1',
  0xf2 => 'DOS 3.3+ secondary partition',
  0xf4 => 'SpeedStor large partition / Prologue single-volume partition',
  0xf5 => 'Prologue multi-volume partition',
  0xfd => 'Linux RAID',
  0xfe => 'SpeedStor > 1024 cyl. or LANstep / IBM PS/2 IML (Initial Microcode Load) partition, located at the end of the disk. / Windows NT Disk Administrator hidden partition / Linux Logical Volume Manager partition (old)',
  0xff => 'Xenix Bad Block Table',
);

my %type2fs = (
arch() =~ /^ppc/ ? (
  0x07 => 'hpfs',
) : (
  0x07 => 'ntfs',
),
arch() !~ /sparc/ ? (
  0x01 => 'vfat',
  0x04 => 'vfat',
  0x05 => 'ignore',
  0x06 => 'vfat',
) : (
  0x01 => 'ufs',
  0x02 => 'ufs',
  0x04 => 'ufs',
  0x06 => 'ufs',
  0x07 => 'ufs',
  0x08 => 'ufs',
),
  0x0b => 'vfat',
  0x0c => 'vfat',
  0x0e => 'vfat',
  0x1b => 'vfat',
  0x1c => 'vfat',
  0x1e => 'vfat',
  0x82 => 'swap',
  0x83 => 'ext2',
  0x183 => 'reiserfs',
  0x283 => 'xfs',
  0x383 => 'jfs',
  0x483 => 'ext3',
  0x401 => 'apple',
  0x402 => 'hfs',
);

my %types_rev = reverse %types;
my %fs2type = reverse %type2fs;


1;

sub important_types { 
    my @l = (@important_types, if_($::expert, @important_types2, sort values %types));
    difference2(\@l, \@bad_types);
}

sub type2fs { $type2fs{$_[0]{type}} || $_[0]{type} }
sub fs2type { $fs2type{$_[0]} || $_[0] }
sub type2name { $types{$_[0]} || $_[0] }
sub name2type { 
    local ($_) = @_;
    /0x(.*)/ ? hex $1 : $types_rev{$_} || $_;
}

sub isWholedisk { arch() =~ /^sparc/ && $_[0]{type} == 5 }
sub isExtended { arch() !~ /^sparc/ && ($_[0]{type} == 5 || $_[0]{type} == 0xf || $_[0]{type} == 0x85) }
sub isRawLVM { $_[0]{type} == 0x8e }
sub isRawRAID { $_[0]{type} == 0xfd }
sub isSwap { type2fs($_[0]) eq 'swap' }
sub isExt2 { type2fs($_[0]) eq 'ext2' }
sub isDos { arch() !~ /^sparc/ && ${{ 1 => 1, 4 => 1, 6 => 1 }}{$_[0]{type}} }
sub isWin { ${{ 0xb => 1, 0xc => 1, 0xe => 1, 0x1b => 1, 0x1c => 1, 0x1e => 1 }}{$_[0]{type}} }
sub isFat { isDos($_[0]) || isWin($_[0]) }
sub isFat_or_NTFS { isDos($_[0]) || isWin($_[0]) || $_[0]{type} == 0x7 }
sub isSunOS { arch() =~ /sparc/ && ${{ 0x1 => 1, 0x2 => 1, 0x4 => 1, 0x6 => 1, 0x7 => 1, 0x8 => 1 }}{$_[0]{type}} }
sub isApple { type2fs($_[0]) eq 'apple' && defined $_[0]{isDriver} }
sub isAppleBootstrap { type2fs($_[0]) eq 'apple' && defined $_[0]{isBoot} }
sub isHiddenMacPart { defined $_[0]{isMap} }

sub isThisFs { type2fs($_[1]) eq $_[0] }
sub isTrueFS { member(type2fs($_[0]), qw(ext2 reiserfs xfs jfs ext3)) }

sub isOtherAvailableFS { isFat_or_NTFS($_[0]) || isSunOS($_[0]) || isThisFs('hfs', $_[0]) } #- other OS that linux can access its filesystem
sub isMountableRW { (isTrueFS($_[0]) || isOtherAvailableFS($_[0])) && !isThisFs('ntfs', $_[0]) }
sub isNonMountable { isRawRAID($_[0]) || isRawLVM($_[0]) }

sub isPartOfLVM { defined $_[0]{lvm} }
sub isPartOfRAID { defined $_[0]{raid} }
sub isPartOfLoopback { defined $_[0]{loopback} }
sub isRAID { $_[0]{device} =~ /^md/ }
sub isUBD { $_[0]{device} =~ /^ubd/ } #- should be always true during an $::uml_install
sub isLVM { $_[0]{VG_name} }
sub isLoopback { defined $_[0]{loopback_file} }
sub isMounted { $_[0]{isMounted} }
sub isBusy { isMounted($_[0]) || isPartOfRAID($_[0]) || isPartOfLVM($_[0]) || isPartOfLoopback($_[0]) }
sub isSpecial { isRAID($_[0]) || isLVM($_[0]) || isLoopback($_[0]) || isUBD($_[0]) }
sub maybeFormatted { $_[0]{isFormatted} || !$_[0]{notFormatted} }


#- works for both hard drives and partitions ;p
sub description {
    my ($hd) = @_;
    my $win = $hd->{device_windobe};

    sprintf "%s%s (%s%s%s%s)", 
      $hd->{device}, 
      $win && " [$win:]", 
      formatXiB($hd->{totalsectors} || $hd->{size}, 512),
      $hd->{info} && ", $hd->{info}",
      $hd->{mntpoint} && ", " . $hd->{mntpoint},
      $hd->{type} && ", " . type2name($hd->{type});
}

sub isPrimary {
    my ($part, $hd) = @_;
    foreach (@{$hd->{primary}{raw}}) { $part eq $_ and return 1 }
    0;
}

sub adjustStartAndEnd {
    my ($hd, $part) = @_;

    $hd->adjustStart($part);
    $hd->adjustEnd($part);
}

sub verifyNotOverlap {
    my ($a, $b) = @_;
    $a->{start} + $a->{size} <= $b->{start} || $b->{start} + $b->{size} <= $a->{start};
}
sub verifyInside {
    my ($a, $b) = @_;
    $b->{start} <= $a->{start} && $a->{start} + $a->{size} <= $b->{start} + $b->{size};
}

sub verifyParts_ {
    foreach my $i (@_) {
	foreach (@_) {
	    next if !$i || !$_ || $i == $_ || isWholedisk($i) || isExtended($i); #- avoid testing twice for simplicity :-)
	    if (isWholedisk($_)) {
		verifyInside($i, $_) or
		  cdie sprintf("partition sector #$i->{start} (%s) is not inside whole disk (%s)!",
			       formatXiB($i->{size}, 512), formatXiB($_->{size}, 512));
	    } elsif (isExtended($_)) {
		verifyNotOverlap($i, $_) or
		  log::l(sprintf("warning partition sector #$i->{start} (%s) is overlapping with extended partition!",
				 formatXiB($i->{size}, 512))); #- only warning for this one is acceptable
	    } else {
		verifyNotOverlap($i, $_) or
		  cdie sprintf("partitions sector #$i->{start} (%s) and sector #$_->{start} (%s) are overlapping!",
			       formatXiB($i->{size}, 512), formatXiB($_->{size}, 512));
	    }
	}
    }
}
sub verifyParts {
    my ($hd) = @_;
    verifyParts_(get_normal_parts($hd));
}
sub verifyPrimary {
    my ($pt) = @_;
    $_->{start} > 0 || arch() =~ /^sparc/ || die "partition must NOT start at sector 0" foreach @{$pt->{normal}};
    verifyParts_(@{$pt->{normal}}, $pt->{extended});
}

sub assign_device_numbers {
    my ($hd) = @_;

    my $i = 1;
    my $start = 1; 
    
    #- on PPC we need to assign device numbers to the holes too - big FUN!
    #- not if it's an IBM machine using a DOS partition table though
    if (arch() =~ /ppc/ && detect_devices::get_mac_model() !~ /^IBM/) {
	#- first sort the normal parts
	$hd->{primary}{normal} = [ sort { $a->{start} <=> $b->{start} } @{$hd->{primary}{normal}} ];
    
	#- now loop through them, assigning partition numbers - reserve one for the holes
	foreach (@{$hd->{primary}{normal}}) {
	    if ($_->{start} > $start) {
		log::l("PPC: found a hole on $hd->{prefix} before $_->{start}, skipping device..."); 
		$i++;
	    }
	    $_->{device} = $hd->{prefix} . $i;
	    $_->{devfs_device} = $hd->{devfs_prefix} . '/part' . $i;
	    $start = $_->{start} + $_->{size};
	    $i++;
	}
    } else {
	foreach (@{$hd->{primary}{raw}}) {
	    $_->{device} = $hd->{prefix} . $i;
	    $_->{devfs_device} = $hd->{devfs_prefix} . '/part' . $i;
	    $i++;
	}
	foreach (map { $_->{normal} } @{$hd->{extended} || []}) {
	    my $dev = $hd->{prefix} . $i;
	    push @{$hd->{partitionsRenumbered}}, [ $_->{device}, $dev ] if $_->{device} && $dev ne $_->{device};
	    $_->{device} = $dev;
	    $_->{devfs_device} = $hd->{devfs_prefix} . '/part' . $i;
	    $i++;
	}
    }

    #- try to figure what the windobe drive letter could be!
    #
    #- first verify there's at least one primary dos partition, otherwise it
    #- means it is a secondary disk and all will be false :(
    my ($c, @others) = grep { isFat_or_NTFS($_) } @{$hd->{primary}{normal}};

    $i = ord 'C';
    $c->{device_windobe} = chr($i++) if $c;
    $_->{device_windobe} = chr($i++) foreach grep { isFat_or_NTFS($_) } map { $_->{normal} } @{$hd->{extended}};
    $_->{device_windobe} = chr($i++) foreach @others;
}

sub remove_empty_extended {
    my ($hd) = @_;
    my $last = $hd->{primary}{extended} or return;
    @{$hd->{extended}} = grep {
	if ($_->{normal}) {
	    $last = $_;
	} else {
	    %{$last->{extended}} = $_->{extended} ? %{$_->{extended}} : ();
	}
	$_->{normal};
    } @{$hd->{extended}};
    adjust_main_extended($hd);
}

sub adjust_main_extended {
    my ($hd) = @_;

    if (!is_empty_array_ref $hd->{extended}) {
	my ($l, @l) = @{$hd->{extended}};

	# the first is a special case, must recompute its real size
	my $start = round_down($l->{normal}{start} - 1, $hd->{geom}{sectors});
	my $end = $l->{normal}{start} + $l->{normal}{size};
	my $only_linux = 1; my $has_win_lba = 0;
	foreach (map { $_->{normal} } $l, @l) {
	    $start = min($start, $_->{start});
	    $end = max($end, $_->{start} + $_->{size});
	    $only_linux &&= isTrueFS($_) || isSwap($_);
	    $has_win_lba ||= $_->{type} == 0xc || $_->{type} == 0xe;
	}
	$l->{start} = $hd->{primary}{extended}{start} = $start;
	$l->{size} = $hd->{primary}{extended}{size} = $end - $start;
    }
    if (!@{$hd->{extended} || []} && $hd->{primary}{extended}) {
	%{$hd->{primary}{extended}} = (); #- modify the raw entry
	delete $hd->{primary}{extended};
    }
    verifyParts($hd); #- verify everything is all right
}

sub adjust_local_extended {
    my ($hd, $part) = @_;

    my $extended = find { $_->{normal} == $part } @{$hd->{extended} || []} or return;
    $extended->{size} = $part->{size} + $part->{start} - $extended->{start};

    #- must write it there too because values are not shared
    my $prev = find { $_->{extended}{start} == $extended->{start} } @{$hd->{extended} || []} or return;
    $prev->{extended}{size} = $part->{size} + $part->{start} - $prev->{extended}{start};
}

sub get_normal_parts {
    my ($hd) = @_;

    @{$hd->{primary}{normal} || []}, map { $_->{normal} } @{$hd->{extended} || []}
}

sub get_normal_parts_and_holes {
    my ($hd) = @_;
    my ($start, $last) = ($hd->first_usable_sector, $hd->last_usable_sector);

    ref($hd) or print("get_normal_parts_and_holes: bad hd" . backtrace(), "\n");

    my @l = map {
	my $current = $start;
	$start = $_->{start} + $_->{size};
	my $hole = { start => $current, size => $_->{start} - $current, type => 0, rootDevice => $hd->{device} };
	$hole, $_;
    } sort { $a->{start} <=> $b->{start} } grep { !isWholedisk($_) } get_normal_parts($hd);

    push @l, { start => $start, size => $last - $start, type => 0, rootDevice => $hd->{device} };
    grep { $_->{type} || $_->{size} >= $hd->cylinder_size } @l;
}

sub read_one($$) {
    my ($hd, $sector) = @_;
    my ($pt, $info);

    #- it can be safely considered that the first sector is used to probe the partition table
    #- but other sectors (typically for extended partition ones) have to match this type!
    if (!$sector) {
	my @parttype = (
	  if_(arch() =~ /^ia64/, 'gpt'),
	  arch() =~ /^sparc/ ? ('sun', 'bsd') : ('dos', 'bsd', 'sun', 'mac'),
	);
	foreach ('empty', @parttype, 'lvm_PV', 'unknown') {
	    /unknown/ and die "unknown partition table format on disk " . $hd->{file};
	    eval {
		# perl_checker: require partition_table::bsd
		# perl_checker: require partition_table::dos
		# perl_checker: require partition_table::empty
		# perl_checker: require partition_table::gpt
		# perl_checker: require partition_table::lvm_PV
		# perl_checker: require partition_table::mac
		# perl_checker: require partition_table::sun
		require "partition_table/$_.pm";
		bless $hd, "partition_table::$_";
		($pt, $info) = $hd->read($sector);
		log::l("found a $_ partition table on $hd->{file} at sector $sector");
	    };
	    $@ or last;
	}
    } else {
	#- keep current blessed object for that, this means it is neccessary to read sector 0 before.
	($pt, $info) = $hd->read($sector);
    }

    my @extended = $hd->hasExtended ? grep { isExtended($_) } @$pt : ();
    my @normal = grep { $_->{size} && $_->{type} && !isExtended($_) } @$pt;

    @extended > 1 and die "more than one extended partition";

    $_->{rootDevice} = $hd->{device} foreach @normal, @extended;
    { raw => $pt, extended => $extended[0], normal => \@normal, info => $info };
}

sub read {
    my ($hd) = @_;
    my $pt = read_one($hd, 0) or return 0;
    $hd->{primary} = $pt;
    undef $hd->{extended};
    verifyPrimary($pt);
    eval {
	my $need_removing_empty_extended;
	$pt->{extended} and read_extended($hd, $pt->{extended}, \$need_removing_empty_extended) || return 0;

	if ($need_removing_empty_extended) {
	    #- special case when hda5 is empty, it must be skipped
	    #- (windows XP generates such partition tables)
	    remove_empty_extended($hd); #- includes adjust_main_extended
	}
	
    }; 
    die "extended partition: $@" if $@;

    assign_device_numbers($hd);
    remove_empty_extended($hd);
    1;
}

sub read_extended {
    my ($hd, $extended, $need_removing_empty_extended) = @_;

    my $pt = read_one($hd, $extended->{start}) or return 0;
    $pt = { %$extended, %$pt };

    push @{$hd->{extended}}, $pt;
    @{$hd->{extended}} > 100 and die "oops, seems like we're looping here :(  (or you have more than 100 extended partitions!)";

    if (@{$pt->{normal}} == 0) {
	$$need_removing_empty_extended = 1;
	delete $pt->{normal};
	print "need_removing_empty_extended\n";
    } elsif (@{$pt->{normal}} > 1) {
	die "more than one normal partition in extended partition";
    } else {
	$pt->{normal} = $pt->{normal}[0];
	#- in case of extended partitions, the start sector is local to the partition or to the first extended_part!
	$pt->{normal}{start} += $pt->{start};

	#- the following verification can broke an existing partition table that is
	#- correctly read by fdisk or cfdisk. maybe the extended partition can be
	#- recomputed to get correct size.
	if (!verifyInside($pt->{normal}, $extended)) {
	    $extended->{size} = $pt->{normal}{start} + $pt->{normal}{size};
	    verifyInside($pt->{normal}, $extended) or die "partition $pt->{normal}{device} is not inside its extended partition";
	}
    }

    if ($pt->{extended}) {
	$pt->{extended}{start} += $hd->{primary}{extended}{start};
	return read_extended($hd, $pt->{extended}, $need_removing_empty_extended);
    } else {
	1;
    }
}

# write the partition table
sub write {
    my ($hd) = @_;
    $hd->{isDirty} or return;
    $hd->{readonly} and die "a read-only partition table should not be dirty!";

    #- set first primary partition active if no primary partitions are marked as active.
    if (my @l = @{$hd->{primary}{raw}}) {
	foreach (@l) { 
	    $_->{local_start} = $_->{start}; 
	    $_->{active} ||= 0;
	}
	$l[0]{active} = 0x80 if !any { $_->{active} } @l;
    }

    #- last chance for verification, this make sure if an error is detected,
    #- it will never be writed back on partition table.
    verifyParts($hd);

    $hd->write(0, $hd->{primary}{raw}, $hd->{primary}{info}) or die "writing of partition table failed";

    #- should be fixed but a extended exist with no real extended partition, that blanks mbr!
    if (arch() !~ /^sparc/) {
	foreach (@{$hd->{extended}}) {
	    # in case of extended partitions, the start sector must be local to the partition
	    $_->{normal}{local_start} = $_->{normal}{start} - $_->{start};
	    $_->{extended} and $_->{extended}{local_start} = $_->{extended}{start} - $hd->{primary}{extended}{start};

	    $hd->write($_->{start}, $_->{raw}) or die "writing of partition table failed";
	}
    }
    $hd->{isDirty} = 0;
    $hd->{hasBeenDirty} = 1; #- used in undo (to know if undo should believe isDirty or not)

    if ($hd->{needKernelReread} && ref($hd->{needKernelReread}) eq 'ARRAY' && $::isStandalone) {
	#- we've only been adding partitions. Try special add_partition (using BLKPG_ADD_PARTITION)
	local *F;
	partition_table::raw::openit($hd, *F) or goto force_reread;

	foreach (@{$hd->{needKernelReread}}) {
	    c::add_partition(fileno F, $_->{start}, $_->{size}, $_->{device} =~ /(\d+)$/)
		or goto force_reread;
	}
    } elsif ($hd->{needKernelReread}) {
      force_reread:
	#- now sync disk and re-read the partition table
	common::sync();

	my @magic_parts = grep { $_->{isMounted} && $_->{real_mntpoint} } get_normal_parts($hd);
	foreach (@magic_parts) {
	    syscall_('umount', $_->{real_mntpoint}) or log::l(N("error unmounting %s: %s", $_->{real_mntpoint}, $!));
	}
	$hd->kernel_read;
	foreach (@magic_parts) {
	    syscall_('mount', $_->{real_mntpoint}, type2fs($_), c::MS_MGC_VAL()) or log::l(N("mount failed: ") . $!);
	}
    }
    $hd->{needKernelReread} = 0;
}

sub active {
    my ($hd, $part) = @_;

    $_->{active} = 0 foreach @{$hd->{primary}{normal}};
    $part->{active} = 0x80;
    $hd->{isDirty} = 1;
}


# remove a normal partition from hard drive hd
sub remove {
    my ($hd, $part) = @_;
    my $i;

    #- first search it in the primary partitions
    $i = 0; foreach (@{$hd->{primary}{normal}}) {
	if ($_ eq $part) {
	    splice(@{$hd->{primary}{normal}}, $i, 1);
	    %$_ = (); #- blank it

	    $hd->raw_removed($hd->{primary}{raw});
	    return $hd->{isDirty} = $hd->{needKernelReread} = 1;
	}
	$i++;
    }

    my ($first, $second, $third) = map { $_->{normal} } @{$hd->{extended} || []};
    if ($third && $first eq $part) {
	die "Can't handle removing hda5 when hda6 is not the second partition" if $second->{start} > $third->{start};
    }      

    #- otherwise search it in extended partitions
    foreach (@{$hd->{extended} || []}) {
	$_->{normal} eq $part or next;

	delete $_->{normal}; #- remove it
	remove_empty_extended($hd);
	assign_device_numbers($hd);

	return $hd->{isDirty} = $hd->{needKernelReread} = 1;
    }
    0;
}

# create of partition at starting at `start', of size `size' and of type `type' (nice comment, uh?)
sub add_primary {
    my ($hd, $part) = @_;

    {
	local $hd->{primary}{normal}; #- save it to fake an addition of $part, that way add_primary do not modify $hd if it fails
	push @{$hd->{primary}{normal}}, $part;
	adjust_main_extended($hd); #- verify
	$hd->raw_add($hd->{primary}{raw}, $part);
    }
    push @{$hd->{primary}{normal}}, $part; #- really do it
}

sub add_extended {
    arch() =~ /^sparc|ppc/ and die N("Extended partition not supported on this platform");

    my ($hd, $part, $extended_type) = @_;
    $extended_type =~ s/Extended_?//;

    my $e = $hd->{primary}{extended};

    if ($e && !verifyInside($part, $e)) {
	#-die "sorry, can't add outside the main extended partition" unless $::unsafe;
	my $end = $e->{start} + $e->{size};
	my $start = min($e->{start}, $part->{start});
	$end = max($end, $part->{start} + $part->{size}) - $start;

	{ #- faking a resizing of the main extended partition to test for problems
	    local $e->{start} = $start;
	    local $e->{size} = $end - $start;
	    eval { verifyPrimary($hd->{primary}) };
	    $@ and die
N("You have a hole in your partition table but I can't use it.
The only solution is to move your primary partitions to have the hole next to the extended partitions.");
	}
    }

    if ($e && $part->{start} < $e->{start}) {
	my $l = first(@{$hd->{extended}});

	#- the first is a special case, must recompute its real size
	$l->{start} = round_down($l->{normal}{start} - 1, $hd->cylinder_size());
	$l->{size} = $l->{normal}{start} + $l->{normal}{size} - $l->{start};
	my $ext = { %$l };
	unshift @{$hd->{extended}}, { type => 5, raw => [ $part, $ext, {}, {} ], normal => $part, extended => $ext };
	#- size will be autocalculated :)
    } else {
	my ($ext, $ext_size) = is_empty_array_ref($hd->{extended}) ?
	  ($hd->{primary}, -1) : #- -1 size will be computed by adjust_main_extended
	  (top(@{$hd->{extended}}), $part->{size});
	my %ext = (type => $extended_type || 5, start => $part->{start}, size => $ext_size);

	$hd->raw_add($ext->{raw}, \%ext);
	$ext->{extended} = \%ext;
	push @{$hd->{extended}}, { %ext, raw => [ $part, {}, {}, {} ], normal => $part };
    }
    $part->{start}++; $part->{size}--; #- let it start after the extended partition sector
    adjustStartAndEnd($hd, $part);

    adjust_main_extended($hd);
}

sub add {
    my ($hd, $part, $primaryOrExtended, $forceNoAdjust) = @_;

    get_normal_parts($hd) >= ($hd->{device} =~ /^rd/ ? 7 : $hd->{device} =~ /^(sd|ida|cciss|ataraid)/ ? 15 : 63) and cdie "maximum number of partitions handled by linux reached";

    $part->{notFormatted} = 1;
    $part->{isFormatted} = 0;
    $part->{rootDevice} = $hd->{device};
    $part->{start} ||= 1 if arch() !~ /^sparc/; #- starting at sector 0 is not allowed
    adjustStartAndEnd($hd, $part) unless $forceNoAdjust;

    my $nb_primaries = $hd->{device} =~ /^rd/ ? 3 : 1;

    if (arch() =~ /^sparc|ppc/ ||
	$primaryOrExtended eq 'Primary' ||
	$primaryOrExtended !~ /Extended/ && @{$hd->{primary}{normal} || []} < $nb_primaries) {
	eval { add_primary($hd, $part) };
	goto success if !$@;
    }
    if ($hd->hasExtended) {
	eval { add_extended($hd, $part, $primaryOrExtended) };
	goto success if !$@;
    }
    {
	add_primary($hd, $part);
    }
  success:
    assign_device_numbers($hd);
    $hd->{isDirty} = 1;
    push @{$hd->{needKernelReread} ||= []}, $part if !$hd->{needKernelReread} || ref($hd->{needKernelReread}) eq 'ARRAY'
}

# search for the next partition
sub next {
    my ($hd, $part) = @_;

    first(
	  sort { $a->{start} <=> $b->{start} }
	  grep { $_->{start} >= $part->{start} + $part->{size} }
	  get_normal_parts($hd)
	 );
}
sub next_start {
    my ($hd, $part) = @_;
    my $next = &next($hd, $part);
    $next ? $next->{start} : $hd->{totalsectors};
}

sub load {
    my ($hd, $file, $force) = @_;

    local *F;
    open F, $file or die N("Error reading file %s", $file);

    my $h;
    {
	local $/ = "\0";
	eval <F>;
    }
    $@ and die N("Restoring from file %s failed: %s", $file, $@);

    ref $h eq 'ARRAY' or die N("Bad backup file");

    my %h; @h{@fields2save} = @$h;

    $h{totalsectors} == $hd->{totalsectors} or $force or cdie "bad totalsectors";

    #- unsure we don't modify totalsectors
    local $hd->{totalsectors};

    @{$hd}{@fields2save} = @$h;

    delete @$_{qw(isMounted isFormatted notFormatted toFormat toFormatUnsure)} foreach get_normal_parts($hd);
    $hd->{isDirty} = $hd->{needKernelReread} = 1;
}

sub save {
    my ($hd, $file) = @_;
    my @h = @{$hd}{@fields2save};
    require Data::Dumper;
    eval { output($file, Data::Dumper->Dump([\@h], ['$h']), "\0") }
      or die N("Error writing to file %s", $file);
}
- использовать указанный synthesis вместо urpmi db.\n" #: ../urpm.pm:1 #, c-format msgid "wget is missing\n" msgstr "wget отсутствует\n" #: ../urpme:1 #, c-format msgid "Checking to remove the following packages" msgstr "Проверяется возможность удаления следующих пакетов" #: ../urpm.pm:1 #, c-format msgid "unrequested" msgstr "незапрошенный" #: ../urpm.pm:1 #, c-format msgid "unable to access rpm file [%s]" msgstr "нет доступа к rpm файлу [%s]" #: ../urpmf:1 #, c-format msgid " --files - print tag files: all files.\n" msgstr " --files - выводить тэг files: все файлы.\n" #: ../urpm.pm:1 #, c-format msgid "unable to parse \"%s\" in file [%s]" msgstr "невозможно разобрать \"%s\" в файле [%s]" #: ../urpmi:1 #, c-format msgid "Do you want to continue installation ?" msgstr "Желаете продолжить установку?" #: ../urpm.pm:1 #, c-format msgid "unable to read rpm file [%s] from medium \"%s\"" msgstr "невозможно прочитать rpm файл [%s] из источника \"%s\"" #: ../urpm.pm:1 #, c-format msgid "built hdlist synthesis file for medium \"%s\"" msgstr "создан файл hdlist synthesis для источника \"%s\"" #: ../urpmi.addmedia:1 #, c-format msgid "" " --version - use specified distribution version, the default is taken\n" " from the version of the distribution told by the\n" " installed mandrake-release package.\n" msgstr "" " --version - использовать указанную версию дистрибутива, по умолчанию\n" " используется версия дистрибутива, сообщенная\n" " установленным пакетом mandrake-release.\n" #: ../urpmi.addmedia:1 #, c-format msgid "" " --from - use specified url for list of mirrors, the default is\n" " %s\n" msgstr "" " --from - использовать указанный url для списка зеркал, по\n" " умолчанию используется %s\n" #: ../urpmf:1 #, c-format msgid " ! - unary NOT, true if expression is false.\n" msgstr "" " ! - унарный NOT, возвращает true, если выражение false.\n" #: ../urpm.pm:1 #, c-format msgid "unmounting %s" msgstr "отмонтируется %s" #: ../urpmi.update:1 #, c-format msgid "nothing to update (use urpmi.addmedia to add a media)\n" msgstr "" "нечего обновлять (используйте urpmi.addmedia чтобы добавить источник)\n" #: ../urpm.pm:1 ../urpmi:1 #, c-format msgid " %s%% completed, speed = %s" msgstr " выполнено %s%%, скорость = %s" #: ../urpm.pm:1 #, c-format msgid "examining synthesis file [%s]" msgstr "проверяется файл synthesis [%s]" #: ../urpmi:1 #, c-format msgid "Try installation even more strongly (--force)? (y/N) " msgstr "Попытаться установить насильно (--force)? (y/N)." #: ../urpm.pm:1 #, c-format msgid "...copying failed" msgstr "...копирование не удалось" #: ../urpm.pm:1 #, c-format msgid "unable to access hdlist file of \"%s\", medium ignored" msgstr "нет доступа к файлу hdlist для \"%s\", источник игнорируется" #: ../urpmi:1 #, c-format msgid " -q - quiet mode.\n" msgstr " -q - тихий режим (quiet).\n" #: ../urpmf:1 #, c-format msgid " --verbose - verbose mode.\n" msgstr " --verbose - подробный режим.\n" #: ../urpmq:1 #, c-format msgid "" " --sources - give all source packages before downloading (root only).\n" msgstr "" " --sources - вывести все исходные пакеты перед скачиванием\n" " (только для root).\n" #: ../urpmq:1 #, c-format msgid "" " --headers - extract headers for package listed from urpmi db to\n" " stdout (root only).\n" msgstr "" " --headers - извлечь заголовки пакетов, перечисленных в urpmi db\n" " в stdout (только для root).\n" #: ../urpme:1 #, c-format msgid "unknown packages" msgstr "неизвестные пакеты" #: ../urpm.pm:1 #, c-format msgid "selecting multiple media: %s" msgstr "выбирается составной источник: %s" #: ../urpmf:1 ../urpmq:1 #, c-format msgid " -f - print version, release and arch with name.\n" msgstr " -f - выводить версию, релиз и архитектуру с названием.\n" #: ../urpm.pm:1 #, c-format msgid "file [%s] already used in the same medium \"%s\"" msgstr "файл [%s] уже используется в похожем источнике \"%s\"" #: ../urpmi.removemedia:1 #, c-format msgid "nothing to remove (use urpmi.addmedia to add a media)\n" msgstr "нечего удалять (используйте urpmi.addmedia чтобы добавить источник)\n" #: ../urpm.pm:1 #, c-format msgid "unable to find list file for \"%s\", medium ignored" msgstr "не получается найти файл списка для \"%s\", источник игнорируется" #: ../urpm.pm:1 #, c-format msgid "curl is missing\n" msgstr "curl отсутствует\n" #: ../urpm.pm:1 #, c-format msgid "found parallel handler for nodes: %s" msgstr "найден параллельный обработчик для узлов: %s" #: ../urpmf:1 #, c-format msgid "" "callback is :\n" "%s\n" msgstr "" "обратный вызов :\n" "%s\n" #: ../urpmq:1 #, c-format msgid " -R - reverse search to what requires package.\n" msgstr " -R - искать требуемые пакеты в обратном порядке.\n" #: ../urpmf:1 #, c-format msgid "" "urpmf version %s\n" "Copyright (C) 2002 MandrakeSoft.\n" "This is free software and may be redistributed under the terms of the GNU " "GPL.\n" "\n" "usage:\n" msgstr "" "urpmf версия %s\n" "Copyright (C) 2002 MandrakeSoft.\n" "Это открытое программное обеспечение и оно может распространяться при " "соблюдении условий GNU GPL.\n" "\n" "использование:\n" #: ../urpmf:1 #, c-format msgid "" " --name - print tag name: rpm filename (assumed if no tag given on\n" " command line but without package name).\n" msgstr "" " --name - выводить тэг name: имя файла rpm (применим, если тэг не\n" " задан в командной строке, но без имени пакета).\n" #: ../urpm.pm:1 #, c-format msgid "Unknown webfetch `%s' !!!\n" msgstr "Неизвестный webfetch `%s' !!!\n" #: ../urpmf:1 #, c-format msgid "" " --quiet - do not print tag name (default if no tag given on " "command\n" " line, incompatible with interactive mode).\n" msgstr "" " --quiet - не выводить тэг name (по умолчанию включен, если тэг не\n" " задан в командной строке, несовместим с интерактивным \n" " режимом).\n" #: ../urpmf:1 #, c-format msgid " --uniq - do not print identical lines.\n" msgstr " --uniq - не выводить идентичные строки.\n" #: ../urpm.pm:1 #, c-format msgid "" "--synthesis cannot be used with --media, --excludemedia, --sortmedia, --" "update or --parallel" msgstr "" "--synthesis не может быть использован с --media, --excludemedia, --" "sortmedia, --update или --parallel" #: ../urpmi.addmedia:1 #, c-format msgid "" " --arch - use specified architecture, the default is arch of\n" " mandrake-release package installed.\n" msgstr "" " --arch - использовать указанную архитектуру, по умолчанию\n" " используется архитектура установленного пакета\n" " mandrake-release.\n" #: ../_irpm:1 ../urpme:1 ../urpmi:1 #, c-format msgid "Is this OK?" msgstr "Это правильно?" #: ../urpmf:1 ../urpmq:1 #, c-format msgid " --synthesis - use the synthesis given instead of urpmi db.\n" msgstr " --synthesis - использовать synthesis вместо urpmi db.\n" #: ../urpmi:1 #, c-format msgid "" "To satisfy dependencies, the following packages are going to be installed (%" "d MB)" msgstr "" "Для удовлетворения зависимостей будут установлены следующие пакеты (%d MB)" #: ../urpm.pm:1 #, c-format msgid "examining parallel handler in file [%s]" msgstr "проверяется параллельный обработчик в файле [%s]" #: ../urpme:1 #, c-format msgid "Nothing to remove" msgstr "Нечего удалять" #: ../urpm.pm:1 #, fuzzy, c-format msgid "...imported key %s from pubkey file of \"%s\"" msgstr "...импортируется файл открытого ключа для \"%s\"" #: ../urpmq:1 #, c-format msgid " -d - extend query to package dependencies.\n" msgstr " -d - расширенный запрос к зависимостям пакета.\n" #: ../urpmi:1 #, c-format msgid "" " --bug - output a bug report in directory indicated by\n" " next arg.\n" msgstr "" " --bug - выводить отчет об ошибках в каталог, определенный\n" " следующим аргументом.\n" #: ../urpm.pm:1 #, c-format msgid "reading headers from medium \"%s\"" msgstr "читаются заголовки из источника \"%s\"" #: ../urpm.pm:1 #, c-format msgid "medium \"%s\" does not define any location for rpm files" msgstr "источник \"%s\" не определяет местонахождение файлов rpm" #: ../urpm.pm:1 #, c-format msgid "wget failed: exited with %d or signal %d\n" msgstr "wget дал сбой: завершен с %d или сигналом %d\n" #: ../urpm.pm:1 #, c-format msgid "copy failed: %s" msgstr "копирование завершилось неудачей: %s" #: ../urpmf:1 #, c-format msgid " --sourcerpm - print tag sourcerpm: source rpm.\n" msgstr " --sourcerpm - выводить тэг sourcerpm: исходный rpm.\n" #: ../urpmf:1 #, c-format msgid " --requires - print tag requires: all requires.\n" msgstr " --requires - выводить тэг requires: все зависимости.\n" #: ../urpm.pm:1 #, c-format msgid "unable to write list file of \"%s\"" msgstr "не удается записать файл списка для \"%s\"" #: ../urpme:1 #, c-format msgid "urpme: unknown option \"-%s\", check usage with --help\n" msgstr "urpme: неизвестная опция \"-%s\", список опций см. --help\n" #: ../urpm.pm:1 #, c-format msgid "trying to select nonexistent medium \"%s\"" msgstr "попытка выбрать несуществующий источник \"%s\"" #: ../urpmf:1 #, c-format msgid " --description - print tag description: description.\n" msgstr " --description - выводить тэг description: описание.\n" #: ../urpmi.addmedia:1 #, c-format msgid "" "%s\n" "`with' missing for network media\n" msgstr "" "%s\n" "`with' отсутствует для сетевого источника\n" #: ../urpmi.addmedia:1 ../urpmi.update:1 #, c-format msgid " -f - force generation of hdlist files.\n" msgstr " -f - принудительно создать файлы hdlist.\n" #: ../urpmq:1 #, c-format msgid "--list-nodes can only be used with --parallel" msgstr "--list-nodes может использоваться только с --parallel" #: ../urpm.pm:1 #, c-format msgid "no hdlist file found for medium \"%s\"" msgstr "не найден файл hdlist для источника \"%s\"" #: ../urpmi:1 ../urpmq:1 #, c-format msgid " -s - next package is a source package (same as --src).\n" msgstr "" " -s - следующий пакет это исходный пакет (аналогично --src).\n" #: ../urpmi:1 #, c-format msgid "installing %s" msgstr "устанавливается %s" #: ../urpm.pm:1 #, c-format msgid "reading rpm files from [%s]" msgstr "читаются rpm файлы из [%s]" #: ../urpm.pm:1 #, c-format msgid "copying description file of \"%s\"..." msgstr "копируется файл описания для \"%s\"..." #: ../urpme:1 ../urpmi:1 #, c-format msgid " --auto - automatically select a package in choices.\n" msgstr " --auto - автоматически выбрать пакет из предложенных.\n" #: ../urpme:1 #, c-format msgid "Removing failed" msgstr "Удаление завершилось неудачей" #: ../urpmi.addmedia:1 #, c-format msgid "" " --virtual - create virtual media wich are always up-to-date,\n" " only file:// protocol is allowed.\n" msgstr "" " --virtual - создать виртуальный источник, который всегда up-to-date,\n" " допускается только протокол file://.\n" #: ../urpm.pm:1 #, c-format msgid "package %s is not found." msgstr "пакет %s не найден." #: ../urpm.pm:1 #, c-format msgid "removing medium \"%s\"" msgstr "удаляется источник \"%s\"" #: ../_irpm:1 ../urpmi:1 #, c-format msgid "Cancel" msgstr "Отмена" #: ../urpmi:1 ../urpmq:1 #, c-format msgid " --src - next package is a source package (same as -s).\n" msgstr "" " --src - следующий пакет является исходным пакетом (аналогично -" "s).\n" #: ../urpmf:1 ../urpmi:1 ../urpmq:1 #, c-format msgid "" " --env - use specific environment (typically a bug\n" " report).\n" msgstr "" " --env - использовать специфическое окружение (обычно отчет\n" " об ошибке).\n" #: ../urpm.pm:1 #, c-format msgid "ssh is missing\n" msgstr "ssh отсутствует\n" #: ../urpmf:1 ../urpmi:1 ../urpmq:1 #, c-format msgid "" " --sortmedia - sort media according to substrings separated by comma.\n" msgstr "" " --sortmedia - сортировать источники по подстрокам, разделенным\n" " запятой.\n" #: ../urpm.pm:1 #, c-format msgid "unable to access medium \"%s\"" msgstr "нет доступа к источнику \"%s\"" #: ../urpmi.addmedia:1 #, c-format msgid "unable to create medium \"%s\"\n" msgstr "невозможно создать источник \"%s\"\n" #: ../urpmf:1 #, c-format msgid " --packager - print tag packager: packager.\n" msgstr " --packager - вывести тэг packager: создатель пакета.\n" #: ../urpmi:1 #, c-format msgid "" "You need to be root to install the following dependencies:\n" "%s\n" msgstr "" "Вам необходимо иметь права root, чтобы установить следующие зависимости:\n" "%s\n" #: ../urpm.pm:1 #, c-format msgid "unable to access list file of \"%s\", medium ignored" msgstr "нет доступа к файлу списка источника \"%s\", источник игнорируется" #: ../urpmf:1 #, c-format msgid " ) - right parenthesis to close group expression.\n" msgstr " ) - правая скобка, закрывающая группу выражений.\n" #: ../urpm.pm:1 #, c-format msgid "examining hdlist file [%s]" msgstr "проверяется файл hdlist [%s]" #: ../urpm.pm:1 #, c-format msgid "copying hdlists file..." msgstr "копируется файл hdlists..." #: ../urpm.pm:1 #, c-format msgid "virtual medium \"%s\" should have a clear url, medium ignored" msgstr "" "виртуальный источник \"%s\" должен содержать пустой url, источник " "игнорируется" #: ../urpmf:1 #, c-format msgid " --buildhost - print tag buildhost: build host.\n" msgstr " --buildhost - вывести тэг buildhost: хост, на котором создан.\n" #: ../urpm.pm:1 #, c-format msgid "writing list file for medium \"%s\"" msgstr "записывается файл списка для источника \"%s\"" #: ../urpme:1 ../urpmi:1 ../urpmq:1 #, c-format msgid " --parallel - distributed urpmi accross machines of alias.\n" msgstr " --parallel - urpmi, распределенный по алиасам машин.\n" #: ../urpm.pm:1 #, c-format msgid "using associated media for parallel mode: %s" msgstr "используется связанный носитель для параллельного режима: %s" #: ../urpm.pm:1 #, c-format msgid "mounting %s" msgstr "монтируется %s" #: ../urpm.pm:1 #, c-format msgid "" "unable to take care of medium \"%s\" as list file is already used by another " "medium" msgstr "" "невозможно сберечь источник \"%s\" так как файл списка уже используется " "другим источником" #: ../urpmi:1 ../urpmq:1 #, c-format msgid "unable to get source packages, aborting" msgstr "невозможно получить исходные пакеты, аварийное завершение" #: ../urpm.pm:1 #, c-format msgid "rsync failed: exited with %d or signal %d\n" msgstr "rsync дал сбой: завершен с %d или сигналом %d\n" #: ../urpm.pm:1 ../urpmi:1 #, c-format msgid " %s%% of %s completed, ETA = %s, speed = %s" msgstr " выполнено %s%% из %s, ETA = %s, скорость = %s" #: ../urpm.pm:1 #, c-format msgid "computing md5sum of retrieved source hdlist (or synthesis)" msgstr "вычисляется md5sum полученного исходного hdlist (или synthesis)" #: ../urpm.pm:1 #, c-format msgid "unable to import pubkey file of \"%s\"" msgstr "невозможно импортировать файл открытого ключа \"%s\"" #: ../urpmi:1 #, c-format msgid "" " --no-uninstall - never ask to uninstall a package, abort the " "installation.\n" msgstr "" " --no-uninstall - никогда не предлагать удалять пакет, прервать установку.\n" #: ../urpmq:1 #, c-format msgid "" "urpmq version %s\n" "Copyright (C) 2000, 2001, 2002 MandrakeSoft.\n" "This is free software and may be redistributed under the terms of the GNU " "GPL.\n" "\n" "usage:\n" msgstr "" "urpmq версия %s\n" "Copyright (C) 2000, 2001, 2002 MandrakeSoft.\n" "Это открытое программное обеспечение и оно может распространяться при " "соблюдении условий GNU GPL.\n" "\n" "использование:\n" #: ../urpm.pm:1 #, c-format msgid "retrieving source hdlist (or synthesis) of \"%s\"..." msgstr "получение исходного hdlist (или synthesis) из \"%s\"..." #: ../urpmq:1 #, c-format msgid " -g - print groups with name also.\n" msgstr " -g - вывести группы вместе с названиями.\n" #: ../urpm.pm:1 #, c-format msgid "medium \"%s\" is not selected" msgstr "источник \"%s\" не выбран" #: ../urpmi:1 #, c-format msgid "Only superuser is allowed to install packages" msgstr "Только суперпользователю разрешается устанавливать пакеты" #: ../urpmf:1 ../urpmi:1 ../urpmq:1 #, c-format msgid "using specific environment on %s\n" msgstr "используется специфическое окружение для %s\n" #: ../urpm.pm:1 #, c-format msgid "unable to find hdlist file for \"%s\", medium ignored" msgstr "не получается найти hdlist файл для \"%s\", источник игнорируется" #: ../urpmi:1 #, c-format msgid " --split-length - small transaction length, default is %d.\n" msgstr " --split-length - длина маленькой транзакции, по умолчанию %d.\n" #: ../urpmf:1 #, c-format msgid " ( - left parenthesis to open group expression.\n" msgstr " ( - левая скобка, открывающая группу выражений.\n" #: ../urpm.pm:1 #, c-format msgid "too many mount points for removable medium \"%s\"" msgstr "слишком много точек монтирования для съемного источника \"%s\"" #: ../urpmf:1 #, c-format msgid "" " -a - binary AND operator, true if both expression are true.\n" msgstr "" " -a - двоичный оператор AND, возвращает true, если оба\n" " выражения истинны.\n" #: ../urpm.pm:1 #, c-format msgid "" "unable to access medium \"%s\",\n" "this could happen if you mounted manually the directory when creating the " "medium." msgstr "" "нет доступа к источнику \"%s\",\n" "так бывает если вы вручную монтировали каталог когда создавали источник." #: ../urpmf:1 #, c-format msgid " --group - print tag group: group.\n" msgstr " --group - выводить тэг group: группа.\n" #: ../urpmf:1 ../urpmi:1 ../urpmq:1 #, c-format msgid " --media - use only the given media, separated by comma.\n" msgstr "" " --media - использовать только указанные источники, разделенные " "запятыми.\n" #: ../urpm.pm:1 #, c-format msgid "unable to create transaction" msgstr "невозможно создать транзакцию" #: ../urpmi.addmedia:1 #, c-format msgid "" "%s\n" "<relative path of hdlist> missing\n" msgstr "" "%s\n" "<относительный путь к hdlist> отсутствует\n" #: ../urpm.pm:1 #, c-format msgid "retrieving rpm files from medium \"%s\"..." msgstr "идет получение файлов rpm из источника \"%s\"..." #: ../urpmi:1 #, c-format msgid "distributing %s" msgstr "разбрасывается %s" #: ../urpmi:1 #, c-format msgid "Installation failed" msgstr "Установка завершилась неудачей" #: ../urpm.pm:1 #, c-format msgid "write config file [%s]" msgstr "записать config файл [%s]" #: ../urpmi.update:1 #, c-format msgid " -a - select all non-removable media.\n" msgstr " -a - выбрать все не-съемные источники данных.\n" #: ../urpmf:1 #, c-format msgid " --epoch - print tag epoch: epoch.\n" msgstr " --epoch - выводить тег epoch: epoch.\n" #: ../urpmi:1 #, c-format msgid "" " --verify-rpm - verify rpm signature before installation\n" " (--no-verify-rpm disable it, default is enabled).\n" msgstr "" " --verify-rpm - проверять подпись rpm перед установкой\n" " (--no-verify-rpm отключит ее, по умолчанию включена).\n" #: ../urpmi:1 #, c-format msgid "Please insert the medium named \"%s\" on device [%s]" msgstr "Пожалуйста, вставьте источник под названием \"%s\" в устройство [%s]" #: ../urpmi.addmedia:1 #, c-format msgid " --update - create an update medium.\n" msgstr " --update - создать источник для обновления.\n" #: ../urpmi:1 ../urpmq:1 #, c-format msgid " -y - impose fuzzy search (same as --fuzzy).\n" msgstr "" " -y - задать поиск на основе нечеткой логики(аналогично --" "fuzzy).\n" #: ../_irpm:1 ../urpmi:1 #, c-format msgid "Ok" msgstr "OК" #: ../urpm.pm:1 #, c-format msgid "invalid hdlist description \"%s\" in hdlists file" msgstr "неверное описание hdlist \"%s\" в файле hdlists " #: ../urpme:1 ../urpmi:1 #, c-format msgid "removing %s" msgstr "удаляется %s" #: ../urpmi.addmedia:1 #, c-format msgid "" " --distrib-XXX - automatically create a medium for XXX part of a\n" " distribution, XXX may be main, contrib, updates or\n" " anything else that has been configured ;-)\n" msgstr "" " --distrib-XXX - автоматически создать источник для части ХХХ\n" " дистрибутива, XXX может быть main, contrib, updates или\n" " что угодно, что уже было настроено ;-)\n" #: ../urpmf:1 #, c-format msgid " --size - print tag size: size.\n" msgstr " --size - выводить тэг size: размер.\n" #: ../urpm.pm:1 #, c-format msgid "in order to keep %s" msgstr "чтобы сохранить %s" #: ../urpm.pm:1 #, c-format msgid "due to unsatisfied %s" msgstr "из-за неудовлетворенности %s" #: ../_irpm:1 #, c-format msgid "" "Automatic installation of packages...\n" "You requested installation of package %s\n" msgstr "" "Автоматическая установка пакетов...\n" "Вы запросили установку пакета %s\n" #: ../urpm.pm:1 #, c-format msgid "urpmi database locked" msgstr "база данных urpmi заблокирована" #: ../urpm.pm:1 #, c-format msgid "copy of [%s] failed" msgstr "копия [%s] не получилась" #: ../urpm.pm:1 #, c-format msgid "taking removable device as \"%s\"" msgstr "принимается съемное устройство как \"%s\"" #: ../urpm.pm:1 #, c-format msgid "examining pubkey file of \"%s\"..." msgstr "проверяется файл открытого ключа для \"%s\"..." #: ../urpmi:1 ../urpmq:1 #, c-format msgid " --fuzzy - impose fuzzy search (same as -y).\n" msgstr "" " --fuzzy - задать поиск на основе нечеткой логики (аналогично -y).\n" #: ../urpmq:1 #, c-format msgid "" " -u - remove package if a more recent version is already " "installed.\n" msgstr "" " -u - удалить пакет если уже установлена более новая версия.\n" #: ../urpmi.addmedia:1 #, c-format msgid " --probe-hdlist - try to find and use hdlist file.\n" msgstr " --probe-hdlist - попытаться найти и использовать файл hdlist.\n" #: ../urpm.pm:1 #, c-format msgid "due to missing %s" msgstr "из-за отсутствия %s" #: ../urpmf:1 ../urpmi:1 ../urpmq:1 #, c-format msgid " --update - use only update media.\n" msgstr " --update - использовать только источник обновления.\n" # #: ../urpmi.update:1 #, c-format msgid "" "usage: urpmi.update [options] <name> ...\n" "where <name> is a medium name to update.\n" msgstr "" "использование: urpmi.update [опции] <имя> ...\n" "где <имя> - имя обновляемого источника.\n" #: ../urpm.pm:1 #, c-format msgid "trying to bypass existing medium \"%s\", avoiding" msgstr "попытка обойти существующий источник \"%s\", отменяется" #: ../urpme:1 ../urpmi:1 #, c-format msgid "" " --test - verify if the installation can be achieved correctly.\n" msgstr " --test - проверять на возможность корректной установки.\n" #~ msgid "urpmf version %s" #~ msgstr "urpmf версия %s" #~ msgid "Copyright (C) 1999, 2000, 2001, 2002 MandrakeSoft." #~ msgstr "Copyright (C) 1999, 2000, 2001, 2002 MandrakeSoft." #~ msgid "" #~ "This is free software and may be redistributed under the terms of the GNU " #~ "GPL." #~ msgstr "" #~ "Это открытое программное обеспечение и может распространяться согласно " #~ "условиям GNU GPL" #~ msgid "usage: urpmf [options] <file>" #~ msgstr "использование: urpmf [опции] <файл>" #~ msgid "" #~ " --quiet - do not print tag name (default if no tag given on " #~ "command" #~ msgstr "" #~ " --quiet - не выводить тэг name (по умолчанию, если тэг не задан " #~ "в командной" #~ msgid " line, incompatible with interactive mode)." #~ msgstr " строке, не совместим с интерактивным режимом)." #~ msgid " --all - print all tags." #~ msgstr " --all - вывод всех тэгов." #~ msgid "" #~ " --name - print tag name: rpm filename (assumed if no tag given " #~ "on" #~ msgstr "" #~ " --name - вывод тэга name: имя файла rpm (применим, если тэг не " #~ "задан" #~ msgid " command line but without package name)." #~ msgstr " в командной строке, но без имени пакета)." #~ msgid " --group - print tag group: group." #~ msgstr " --group - вывод тэга group: группа." #~ msgid " --size - print tag size: size." #~ msgstr " --size - вывод тэга size: размер." #~ msgid " --serial - print tag serial: serial." #~ msgstr " --serial - вывод тэга serial: серийный номер." #~ msgid " --summary - print tag summary: summary." #~ msgstr " --summary - вывод тэга summary: сводка." #~ msgid " --description - print tag description: description." #~ msgstr " --description - вывод тэга description: описание." #~ msgid "" #~ " --provides - print tag provides: all provides (multiple lines)." #~ msgstr "" #~ " --provides - вывод тэга provides: все поставляемые файлы (в " #~ "несколько строк)." #~ msgid "" #~ " --requires - print tag requires: all requires (multiple lines)." #~ msgstr "" #~ " --requires - вывод тэга requires: все требуемые файлы (в несколько " #~ "строк)." #~ msgid " --files - print tag files: all files (multiple lines)." #~ msgstr "" #~ " --files - вывод тэга files: все файлы (в несколько строк)." #~ msgid "" #~ " --conflicts - print tag conflicts: all conflicts (multiple lines)." #~ msgstr "" #~ " --conflicts - вывод тэга conflicts: все конфликтующие файлы (в " #~ "несколько строк)." #~ msgid "" #~ " --obsoletes - print tag obsoletes: all obsoletes (multiple lines)." #~ msgstr "" #~ " --obsoletes - вывод тэга obsoletes: все устаревшие файлы (в " #~ "несколько строк)." #~ msgid " --prereqs - print tag prereqs: all prereqs (multiple lines)." #~ msgstr "" #~ " --preregs - вывод тэга preregs: все предварительно запрашиваемые " #~ "файлы (в несколько строк)." #~ msgid "try urpmf --help for more options" #~ msgstr "попробуйте urpmf --help для дополнительных опций" #~ msgid "no full media list was found" #~ msgstr "был найден неполный список носителей" #~ msgid "copying source list of \"%s\"..." #~ msgstr "копируется исходный список \"%s\"..." #~ msgid "mput failed, maybe a node is unreacheable" #~ msgstr "mput завершился неудачей, возможно узел недоступен" #~ msgid "on node %s" #~ msgstr "на узле %s" #~ msgid "host %s does not have a good version of urpmi" #~ msgstr "на хосте %s отсутствует хорошая версия urpi" #~ msgid "Installation failed on node %s" #~ msgstr "Установка на узел %s не завершилась." #~ msgid "rshp failed, maybe a node is unreacheable" #~ msgstr "rshp завершился неудачей, возможно узел недоступен" #~ msgid "scp failed on host %s" #~ msgstr "scp завершился неудачей на хосте %s" #~ msgid "" #~ "medium \"%s\" uses an invalid list file:\n" #~ " mirror is problably not up-to-date, trying to use alternate method" #~ msgstr "" #~ "носитель \"%s\" использует неверный файл списка:\n" #~ " возможно зеркало устарело, выполняется попытка использовать " #~ "альтернативный метод"