summaryrefslogtreecommitdiffstats
path: root/po/de.po
blob: 0531ba531c9940c9c4c924d5e7fb0ed3935e88c2 (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
# German version of urpmi
# Copyright (C) 1999-2001 MandrakeSoft.
# Stefan Siegel <siegel@linux-mandrake.de>, 1999-2001.
#
msgid ""
msgstr ""
"Project-Id-Version: urpmi 1.5\n"
"POT-Creation-Date: 2001-07-03 21:02+0200\n"
"PO-Revision-Date: 2001-07-11 09:21+0200\n"
"Last-Translator: Stefan Siegel <siegel@linux-mandrake.com>\n"
"Language-Team: German <de@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"

#: _irpm:21
msgid "installing $rpm\n"
msgstr "Installiere $rpm\n"

#: _irpm:31
msgid ""
"Automatic installation of packages...\n"
"You requested installation of package $rpm\n"
msgstr ""
"Automatische Installation von Paketen ...\n"
"Sie wünschen die Installation von Paket „$rpm“\n"

#: _irpm:31 po/placeholder.h:129 urpmi:239
msgid "Is it ok?"
msgstr "Ist das in Ordnung?"

#: _irpm:33 po/placeholder.h:135 urpmi:242 urpmi:272
msgid "Ok"
msgstr "Ok"

#: _irpm:34 po/placeholder.h:99 urpmi:243 urpmi:273
msgid "Cancel"
msgstr "Abbruch"

#: _irpm:40 po/placeholder.h:136 urpmi:247 urpmi:305
msgid "Nn"
msgstr "Nn"

#: _irpm:41 po/placeholder.h:130 urpmi:248 urpmi:306
msgid "Yy"
msgstr "JjYy"

#: _irpm:42 po/placeholder.h:101 urpmi:249
msgid " (Y/n) "
msgstr " (J/n) "

#: _irpm:61
msgid "$rpm: command not found\n"
msgstr "$rpm: Befehl nicht gefunden\n"

#: po/placeholder.h:6
msgid "usage: rpmf [<file>]"
msgstr "Verwendung: rpmf [<Datei>]"

#: po/placeholder.h:7
msgid "urpmi is not installed"
msgstr "urpmi ist nicht installiert."

#: po/placeholder.h:8 urpm.pm:231
#, c-format
msgid "incoherent list file for \"%s\", medium ignored"
msgstr "Die Dateiliste für „%s“ ist inkonsistent, das Medium wird ignoriert."

#: po/placeholder.h:9 urpm.pm:894
#, c-format
msgid "relocated %s entries in depslist"
msgstr ""

#: po/placeholder.h:10
#, c-format
msgid "copy of [%s] failed"
msgstr "Kopieren von „%s“ schlug fehl."

#: po/placeholder.h:11 urpm.pm:1573
#, c-format
msgid "unable to read rpm file [%s] from medium \"%s\""
msgstr "Ich kann das RPM-Paket „%s“ von Medium „%s“ nicht lesen."

#: po/placeholder.h:12 urpm.pm:906
#, c-format
msgid "invalid rpm file name [%s]"
msgstr "Ungültiger RPM Name „%s“"

#: po/placeholder.h:13
#, c-format
msgid "source of [%s] not found as [%s]"
msgstr ""

#: po/placeholder.h:14 urpm.pm:795
#, c-format
msgid "unable to write compss file [%s]"
msgstr "Ich kann die Datei „%s“ nicht anlegen."

#: po/placeholder.h:15 urpm.pm:1709
#, c-format
msgid "selecting %s using obsoletes"
msgstr ""

#: po/placeholder.h:16 urpm.pm:738
#, c-format
msgid "unmounting %s"
msgstr "Aushängen von „%s“"

#: po/placeholder.h:17 urpm.pm:191
#, c-format
msgid "unable to access list file of \"%s\", medium ignored"
msgstr ""

#: po/placeholder.h:18 urpm.pm:798
#, c-format
msgid "write compss file [%s]"
msgstr ""

#: po/placeholder.h:19
#, fuzzy, c-format
msgid "trying to remove inexistant medium \"%s\""
msgstr "Ich kann das Medium „%s“ nicht anlegen.\n"

#: po/placeholder.h:20 urpm.pm:1585
#, c-format
msgid "medium \"%s\" is not selected"
msgstr "Das Medium „%s“ wurde nicht ausgewählt."

#: po/placeholder.h:21 urpm.pm:752
#, c-format
msgid "read depslist file [%s]"
msgstr "Lesen der Depslist-Datei „%s“"

#: po/placeholder.h:22
#, c-format
msgid "built hdlist synthesis file for medium \"%s\""
msgstr ""

#: po/placeholder.h:23 urpm.pm:764
#, c-format
msgid "read provides file [%s]"
msgstr ""

#: po/placeholder.h:24 urpm.pm:161
#, c-format
msgid ""
"unable to take care of medium \"%s\" as list file is already used by another "
"medium"
msgstr ""

#: po/placeholder.h:25
#, c-format
msgid "nothing written in list file for \"%s\""
msgstr ""

#: po/placeholder.h:26 urpm.pm:785
#, fuzzy, c-format
msgid "unable to write depslist file [%s]"
msgstr "Ich kann das Medium „%s“ nicht anlegen.\n"

#: po/placeholder.h:27
msgid "computing dependencies"
msgstr "Berechnen der Abhängigkeiten"

#: po/placeholder.h:28 urpm.pm:790
#, fuzzy, c-format
msgid "unable to write provides file [%s]"
msgstr "Ich kann das Medium „%s“ nicht anlegen.\n"

#: po/placeholder.h:29 urpm.pm:1646
#, c-format
msgid "wget of [%s] failed"
msgstr ""

#: po/placeholder.h:30 urpm.pm:1589
#, c-format
msgid "incoherent medium \"%s\" marked removable but not really"
msgstr ""

#: po/placeholder.h:31 urpm.pm:788
#, c-format
msgid "write depslist file [%s]"
msgstr ""

#: po/placeholder.h:32
msgid "keeping only provides files"
msgstr ""

#: po/placeholder.h:33
#, fuzzy, c-format
msgid "trying to select inexistant medium \"%s\""
msgstr "Ich kann das Medium „%s“ nicht anlegen.\n"

#: po/placeholder.h:34
#, c-format
msgid "no hdlist file found for medium \"%s\""
msgstr ""

#: po/placeholder.h:35 urpm.pm:1007
#, c-format
msgid "no package named %s"
msgstr ""

#: po/placeholder.h:36 urpm.pm:1010
#, fuzzy, c-format
msgid "The following packages contain %s: %s"
msgstr "Die folgenden Pakete enthalten „%s“: %s"

#: po/placeholder.h:37 urpm.pm:793
#, c-format
msgid "write provides file [%s]"
msgstr ""

#: po/placeholder.h:38 urpm.pm:143
#, c-format
msgid "medium \"%s\" try to use an already used hdlist, medium ignored"
msgstr ""

#: po/placeholder.h:39 urpm.pm:1820
#, c-format
msgid "avoid selecting %s as its locales language is not already selected"
msgstr ""

#: po/placeholder.h:40
#, c-format
msgid "wget of [%s] failed (maybe wget is missing?)"
msgstr ""

#: po/placeholder.h:41 urpm.pm:914
msgid "mismatch arch for registering rpm file"
msgstr ""

#: po/placeholder.h:42
#, fuzzy, c-format
msgid "unable to write list file of \"%s\""
msgstr "Ich kann das Medium „%s“ nicht anlegen.\n"

#: po/placeholder.h:43
#, c-format
msgid "removing %d obsolete headers in cache"
msgstr ""

#: po/placeholder.h:44 urpm.pm:921
msgid "error registering local packages"
msgstr ""

#: po/placeholder.h:45 urpm.pm:205
#, c-format
msgid "trying to bypass existing medium \"%s\", avoiding"
msgstr ""

#: po/placeholder.h:46
#, fuzzy, c-format
msgid "unable to build synthesis file for medium \"%s\""
msgstr "Ich kann das Medium „%s“ nicht aktualisieren.\n"

#: po/placeholder.h:47 urpm.pm:1732
#, c-format
msgid ""
"removing %s to upgrade ...\n"
" to %s since it will not be updated otherwise"
msgstr ""

#: po/placeholder.h:51
#, c-format
msgid "no rpm files found from [%s]"
msgstr ""

#: po/placeholder.h:52 urpm.pm:776
#, c-format
msgid "read compss file [%s]"
msgstr ""

#: po/placeholder.h:53 urpm.pm:239
#, c-format
msgid "unable to inspect list file for \"%s\", medium ignored"
msgstr ""

#: po/placeholder.h:54
#, fuzzy, c-format
msgid "unable to build hdlist: %s"
msgstr "Ich kann das Medium „%s“ nicht aktualisieren.\n"

#: po/placeholder.h:55 urpm.pm:1817
#, c-format
msgid "selecting %s by selection on files"
msgstr ""

#: po/placeholder.h:56 urpm.pm:256
#, c-format
msgid "unable to write config file [%s]"
msgstr ""

#: po/placeholder.h:57
#, c-format
msgid "found %d headers in cache"
msgstr ""

#: po/placeholder.h:58 urpm.pm:749
#, fuzzy, c-format
msgid "unable to read depslist file [%s]"
msgstr "Ich kann das Medium „%s“ nicht anlegen.\n"

#: po/placeholder.h:59
#, c-format
msgid "unable to copy source of [%s] from [%s]"
msgstr ""

#: po/placeholder.h:60 urpm.pm:1639
#, c-format
msgid "malformed input: [%s]"
msgstr ""

#: po/placeholder.h:61 urpm.pm:268
#, c-format
msgid "write config file [%s]"
msgstr ""

#: po/placeholder.h:62 urpm.pm:761
#, fuzzy, c-format
msgid "unable to read provides file [%s]"
msgstr "Ich kann das Medium „%s“ nicht anlegen.\n"

#: po/placeholder.h:63 urpm.pm:122 urpm.pm:134
#, c-format
msgid "syntax error in config file at line %s"
msgstr ""

#: po/placeholder.h:64 urpm.pm:1566
msgid "removable medium not selected"
msgstr ""

#: po/placeholder.h:65 urpm.pm:189
#, c-format
msgid "unable to access hdlist file of \"%s\", medium ignored"
msgstr ""

#: po/placeholder.h:66 urpm.pm:1533
#, c-format
msgid "package %s is not found."
msgstr ""

#: po/placeholder.h:67 urpm.pm:178
#, c-format
msgid "unable to determine medium of this hdlist file [%s]"
msgstr ""

#: po/placeholder.h:68 urpm.pm:1233
#, c-format
msgid "unknown data associated with %s"
msgstr ""

#: po/placeholder.h:69 urpm.pm:146
#, c-format
msgid "medium \"%s\" try to use an already used list, medium ignored"
msgstr ""

#: po/placeholder.h:70 urpm.pm:174
#, c-format
msgid "unable to take medium \"%s\" into account as no list file [%s] exists"
msgstr ""

#: po/placeholder.h:71 urpm.pm:918
msgid "rpmtools package is too old, please upgrade it"
msgstr ""

#: po/placeholder.h:72
#, c-format
msgid "building hdlist [%s]"
msgstr ""

#: po/placeholder.h:73 urpm.pm:300 urpm.pm:1600
#, fuzzy, c-format
msgid "unable to access medium \"%s\""
msgstr "Ich kann das Medium „%s“ nicht aktualisieren.\n"

#: po/placeholder.h:74 urpm.pm:738
#, fuzzy, c-format
msgid "mounting %s"
msgstr "Installiere %s\n"

#: po/placeholder.h:75 urpm.pm:167
#, c-format
msgid "unable to use name \"%s\" for unamed medium because it is already used"
msgstr ""

#: po/placeholder.h:76 urpm.pm:1202
msgid "unable to find all synthesis file, using parsehdlist server"
msgstr ""

#: po/placeholder.h:77 urpm.pm:907
#, fuzzy, c-format
msgid "unable to access rpm file [%s]"
msgstr "Ich kann das Medium „%s“ nicht anlegen.\n"

#: po/placeholder.h:78 urpm.pm:1810
#, c-format
msgid "avoid selecting %s as not enough files will be updated"
msgstr ""

#: po/placeholder.h:79
#, fuzzy, c-format
msgid "unable to parse hdlist file of \"%s\""
msgstr "Ich kann das Medium „%s“ nicht aktualisieren.\n"

#: po/placeholder.h:80 urpm.pm:1644
#, c-format
msgid "retrieving [%s]"
msgstr ""

#: po/placeholder.h:81 urpm.pm:216
#, c-format
msgid "unable to find list file for \"%s\", medium ignored"
msgstr ""

#: po/placeholder.h:82 urpm.pm:913
msgid "mismatch release for registering rpm file"
msgstr ""

#: po/placeholder.h:83 urpm.pm:1740
#, c-format
msgid ""
"removing %s to upgrade ...\n"
" to %s since it will not upgrade correctly!"
msgstr ""

#: po/placeholder.h:87
#, c-format
msgid "reading hdlist file [%s]"
msgstr ""

#: po/placeholder.h:88 urpm.pm:829 urpm.pm:1479 urpm.pm:1521
#, c-format
msgid "unable to parse correctly [%s] on value \"%s\""
msgstr ""

#: po/placeholder.h:89 urpm.pm:912
msgid "mismatch version for registering rpm file"
msgstr ""

#: po/placeholder.h:90
#, c-format
msgid "nothing to write in list file for \"%s\""
msgstr ""

#: po/placeholder.h:91 urpm.pm:211
#, c-format
msgid "unable to find hdlist file for \"%s\", medium ignored"
msgstr ""

#: po/placeholder.h:92 urpm.pm:773
#, fuzzy, c-format
msgid "unable to read compss file [%s]"
msgstr "Ich kann das Medium „%s“ nicht anlegen.\n"

#: po/placeholder.h:93 urpm.pm:822 urpm.pm:1473
#, fuzzy, c-format
msgid "unable to parse correctly [%s]"
msgstr "Ich kann das Medium „%s“ nicht aktualisieren.\n"

#: po/placeholder.h:94 urpm.pm:1490 urpm.pm:1512
#, c-format
msgid "there are multiples packages with the same rpm filename \"%s\""
msgstr ""

#: po/placeholder.h:95 urpm.pm:284
#, c-format
msgid "medium \"%s\" already exists"
msgstr ""

#: po/placeholder.h:96 urpmi:190
#, c-format
msgid "What is your choice? (1-%d) "
msgstr "Ihre Wahl? (1-%d) "

#: po/placeholder.h:97 urpmi:182
msgid "One of the following packages is needed:"
msgstr "Eines der folgenden Pakete wird benötigt:"

#: po/placeholder.h:98 urpmi:270
msgid "Press enter when it's done..."
msgstr "Bestätigen Sie dies durch drücken der Return Taste ..."

#: po/placeholder.h:100 urpmi:284
msgid "everything already installed"
msgstr "Alles bereits installiert"

#: po/placeholder.h:102 urpmi:238
#, c-format
msgid ""
"To satisfy dependencies, the following packages are going to be installed (%"
"d MB)"
msgstr ""
"Um die Abhängigkeiten zu erfüllen, werden die folgenden Pakete installiert (%"
"d MB)"

#: po/placeholder.h:103 po/placeholder.h:215 urpmi:259 urpmq:154
msgid "unable to get source packages, aborting"
msgstr "Ich kann die Quellpakete nicht finden, Abbruch."

#: po/placeholder.h:104 urpmi:307
msgid "Try installation without checking dependencies? (y/N) "
msgstr "Soll ich eine Installation ohne Abhängigkeitstest versuchen? (j/N) "

#: po/placeholder.h:105 urpmi:269
#, c-format
msgid "Please insert the medium named \"%s\" on device [%s]"
msgstr "Bitte legen Sie das Medium mit Namen „%s“ in Gerät „%s“."

#: po/placeholder.h:106
#, fuzzy, c-format
msgid ""
"urpmi version %s\n"
"Copyright (C) 1999, 2000, 2001 MandrakeSoft.\n"
"This is free software and may be redistributed under the terms of the GNU "
"GPL.\n"
"usage:\n"
"  --help           - print this help message.\n"
"  --update         - use only update media.\n"
"  --auto           - automatically select a good package in choices.\n"
"  --auto-select    - automatically select packages for upgrading the "
"system.\n"
"  --force          - force invocation even if some package do not exist.\n"
"  --X              - use X interface.\n"
"  --best-output    - choose best interface according to the environment:\n"
"                     X or text mode.\n"
"  -a               - select all matches on command line.\n"
"  -m               - choose minimum closure of requires (default).\n"
"  -M               - choose maximun closure of requires.\n"
"  -c               - choose complete method for resolving requires closure.\n"
"  -p               - allow search in provides to find package.\n"
"  -q               - quiet mode.\n"
"  -v               - verbose mode.\n"
"  names or rpm files (only for root) given on command line are installed.\n"
msgstr ""
"urpmi Version %s\n"
"Copyright © 1999-2001 MandrakeSoft.\n"
"Dieses Programm wird in der Hoffnung verteilt, dass es nützlich ist.\n"
"Es gibt KEINERLEI Garantie, nicht einmal für die TAUGLICHKEIT oder die,\n"
"VERWENDBARKEIT FÜR EINEN BESTIMMTEN ZWECK. In den Quellen befindet sich die\n"
"Lizenz- und Kopierbedingung; die Einzelheiten sind in der Datei COPYING\n"
"(GNU General Public License) beschrieben.\n"
"\n"
"Verwendung:\n"
"  --help           - Anzeigen dieser Hilfe und beenden.\n"
"  --auto           - Automatische Wahl eines guten Pakets.\n"
"  --auto-select    - Automatische Wahl der Pakete zur Aktualisierung des "
"Systems.\n"
"  --force          - Führe den Befehl aus, selbst wenn einige Pakete nicht "
"existieren.\n"
"  --X              - Verwende die grafische Oberfläche (X11).\n"
"  --best-output    - Verwende beste Oberfläche anhand der Umgebung:\n"
"                     X11 oder Text-Modus.\n"
"  -a               - Wähle alle Treffer in der Kommandozeile.\n"
"  -m               - Wähle minimale Auflösung von Abhängigkeiten "
"(standard).\n"
"  -M               - Wähle maximale Auflösung von Abhängigkeiten.\n"
"  -c               - Wähle komplette Methode zum Auflösen von "
"Abhängigkeiten.\n"
"  -q               - Vermeide Ausgaben (quiet).\n"
"  -v               - Erzeuge aufwendigere Ausgaben (verbose).\n"
"Namen oder RPM-Dateien (nur für das privileg. Kennzeichen) die auf der "
"Kommandozeile angegeben werden, werden installiert.\n"

#: po/placeholder.h:128 urpmi:193
msgid "Sorry, bad choice, try again\n"
msgstr "Eine schlechte Wahl, versuchen Sie es erneut\n"

#: po/placeholder.h:131 urpmi:315
msgid "Try installation even more strongly (--force)? (y/N) "
msgstr "Soll ich eine Installation mit Gewalt (--force) versuchen? (j/N) "

#: po/placeholder.h:132 urpmi:295
#, c-format
msgid "installing %s\n"
msgstr "Installiere %s\n"

#: po/placeholder.h:133 urpmi:300 urpmi:314
msgid "Installation failed"
msgstr "Die Installation schlug Fehl"

#: po/placeholder.h:134 urpmi:144
msgid "Only superuser is allowed to install local packages"
msgstr ""
"Nur der Systemadministrator mit dem privilegierten \n"
"Benutzerkennzeichen darf Pakete installieren."

#: po/placeholder.h:137 urpmi.addmedia:46
#, c-format
msgid ""
"%s\n"
"`with' missing for ftp media\n"
msgstr ""
"%s\n"
"„with“ fehlt für FTP-Medien.\n"

#: po/placeholder.h:141 urpmi.addmedia:58
#, c-format
msgid "unable to update medium \"%s\"\n"
msgstr "Ich kann das Medium „%s“ nicht aktualisieren.\n"

#: po/placeholder.h:142 urpmi.addmedia:42
#, c-format
msgid ""
"%s\n"
"device `%s' do not exist\n"
msgstr ""
"%s\n"
"Das Gerät „%s“ existiert nicht.\n"

#: po/placeholder.h:146 urpmi.addmedia:57
#, c-format
msgid "unable to create medium \"%s\"\n"
msgstr "Ich kann das Medium „%s“ nicht anlegen.\n"

#: po/placeholder.h:147
#, fuzzy
msgid ""
"usage: urpmi.addmedia [--update] <name> <url>\n"
"where <url> is one of\n"
"       file://<path>\n"
"       ftp://<login>:<password>@<host>/<path> with <relative filename of "
"hdlist>\n"
"       ftp://<host>/<path> with <relative filename of hdlist>\n"
"       http://<host>/<path> with <relative filename of hdlist>\n"
"       removable_<device>://<path>\n"
msgstr ""
"Verwendung: urpmi.addmedia <Name> <URL>\n"
"Mit <URL> aus folgender Menge:\n"
"       file://<Pfad>\n"
"       ftp://<Login>:<Passwort>@<Rechner>/<Pfad> with <relativer Pfad zur HD-"
"Liste>\n"
"       ftp://<Rechner>/<Pfad> with <relativer Pfad zur HD-Liste>\n"
"       http://<Rechner>/<Pfad> with <relativer Pfad zur HD-Liste>\n"
"       removable_<Gerät>://<Pfad>\n"

#: po/placeholder.h:156 urpmi.addmedia:44
#, c-format
msgid ""
"%s\n"
"<relative path of hdlist> missing\n"
msgstr ""
"%s\n"
"<relativer Pfad zur HD-Liste> fehlt.\n"

#: po/placeholder.h:160 urpmi.update:52
#, c-format
msgid ""
"the entry to update is missing\n"
"(one of %s)\n"
msgstr ""
"Was soll aktualisiert werden?\n"
"(eins aus %s)\n"

#: po/placeholder.h:164 urpmi.update:50
msgid "nothing to update (use urpmi.addmedia to add a media)\n"
msgstr ""
"Es gibt nichts zu aktualisieren (verwenden Sie „urpmi.addmedia“, \n"
"um neue Medien hinzuzufügen)\n"

#: po/placeholder.h:165
#, fuzzy, c-format
msgid ""
"usage: urpmi.update [-a] <name> ...\n"
"where <name> is a medium name to update.\n"
"   -a    select all non-removable media.\n"
"   -c    clean headers cache directory.\n"
"   -f    force generation of base files, use another -f for hdlist files.\n"
"\n"
"unknown options '%s'\n"
msgstr ""
"Verwendung: urpmi.update [-a] <Name> ...\n"
"Wobei <Name> das zu aktualisierende Medium ist.\n"
"   -a    Alle nicht-entfernbaren Medien wählen.\n"
"   -c    Den Header-Cache leeren.\n"
"   -f    Erzwinge die Erzeugung von „hdlist“ oder „base“ Dateien.\n"
"\n"
"Unbekannte Option „%s\n"

#: po/placeholder.h:174
#, c-format
msgid ""
"usage: urpmi.removemedia [-a] <name> ...\n"
"where <name> is a medium name to remove.\n"
"   -a    select all media.\n"
"\n"
"unknown options '%s'\n"
msgstr ""
"Verwendung: urpmi.removemedia [-a] <Name> ...\n"
"Wobei <Name> das zu entfernende Medium ist.\n"
"   -a     Alle Medien wählen.\n"
"\n"
"Unbekannte Option „%s\n"

#: po/placeholder.h:181 urpmi.removemedia:44
msgid "nothing to remove (use urpmi.addmedia to add a media)\n"
msgstr ""
"Es gibt nichts zu entfernen (verwenden Sie „urpmi.addmedia“, \n"
"um neue Medien hinzuzufügen)\n"

#: po/placeholder.h:182 urpmi.removemedia:46
#, c-format
msgid ""
"the entry to remove is missing\n"
"(one of %s)\n"
msgstr ""
"Was soll entfernt werden?\n"
"(eins aus %s)\n"

#: po/placeholder.h:186 urpmq:85
#, fuzzy, c-format
msgid "urpmq: unknown option \"-%s\", check usage with --help\n"
msgstr ""
"urpmq: unbekannte Option „-$1“. Weitere Infos erhalten Sie \n"
"mittels „urpmq --help“\n"

#: po/placeholder.h:187
#, c-format
msgid ""
"urpmq version %s\n"
"Copyright (C) 2000, 2001 MandrakeSoft.\n"
"This is free software and may be redistributed under the terms of the GNU "
"GPL.\n"
"usage:\n"
"  -h             - print this help message.\n"
"  -v             - verbose mode.\n"
"  -d             - extend query to package dependencies.\n"
"  -u             - remove package if a better version is already installed.\n"
"  -m             - extend query to package dependencies, remove already\n"
"                   installed package that provide what is necessary, add\n"
"                   packages that may be block the upgrade.\n"
"  -M             - extend query to package dependencies and remove already\n"
"                   installed package only if they are newer or the same.\n"
"  -c             - choose complete method for resolving requires closure.\n"
"  -p             - allow search in provides to find package.\n"
"  -g             - print groups too with name.\n"
"  -r             - print version and release too with name.\n"
"  --update       - use only update media.\n"
"  --auto-select  - automatically select packages for upgrading the system.\n"
"  --headers      - extract headers for package listed from urpmi db to\n"
"                   stdout (root only).\n"
"  --sources      - give all source packages before downloading (root only).\n"
"  --force        - force invocation even if some package do not exist.\n"
"  names or rpm files given on command line are queried.\n"
msgstr ""

#: po/placeholder.h:213 urpmq:132
msgid ""
"some package have to be removed for being upgraded, this is not supported "
"yet\n"
msgstr ""
"Einige Pakete müssen entfernt werden, bevor die diese Aktualisierungen \n"
"durchführen können. Diese Funktionalität wird noch nicht angeboten.\n"

#: po/placeholder.h:214 urpmq:87
#, fuzzy, c-format
msgid "urpmq: cannot read rpm file \"%s\"\n"
msgstr "urpmq: Ich kann die Datei „$_“ nicht lesen.\n"

#: urpmi:48
#, c-format
msgid "urpmi version %s"
msgstr "urpmi Version %s"

#: urpmi.addmedia:30
#, fuzzy
msgid "usage: urpmi.addmedia [--update] <name> <url>"
msgstr "Verwendung: urpmi.addmedia <Name> <URL>"

#. <path>
#. <login>:<password>@<host>/<path> with <relative filename of hdlist>
#. <host>/<path> with <relative filename of hdlist>
#. <host>/<path> with <relative filename of hdlist>
#. <path>
#: urpmi.addmedia:37
msgid ");"
msgstr ");"

#: urpmi.update:37
msgid "usage: urpmi.update [-a] <name> ..."
msgstr "Verwendung: urpmi.update [-a] <Name> ..."

#: urpmi.removemedia:32
msgid "usage: urpmi.removemedia [-a] <name> ..."
msgstr "Verwendung: urpmi.removemedia [-a] <Name> ..."

#: urpmi.removemedia:35
msgid ", $_);"
msgstr ", $_);"

#: urpmq:34
#, c-format
msgid "urpmq version %s"
msgstr "urpmq Version %s"

#~ msgid "));"
#~ msgstr "));"

#~ msgid "), $_);"
#~ msgstr "), $_);"
wb">$main_method (main_method_choices()) { my $f = $bootloader::{"read_$main_method"} or die "unknown bootloader method $main_method (read)"; my $bootloader = $f->($fstab); cleanup_entries($bootloader); # handle raid-extra-boot (lilo) my @devs = $bootloader->{boot}; if ($bootloader->{'raid-extra-boot'} =~ /mbr/ && (my $md = fs::get::device2part($bootloader->{boot}, $all_hds->{raids}))) { @devs = map { $_->{rootDevice} } @{$md->{disks}}; } elsif ($bootloader->{'raid-extra-boot'} =~ m!/dev/!) { @devs = split(',', $bootloader->{'raid-extra-boot'}); } my ($type) = map { if (m!/fd\d+$!) { warn "not checking the method on floppy, assuming $main_method is right\n"; $main_method; } elsif (member($main_method, qw(yaboot cromwell silo pmon2000 uboot))) { #- not checking, there's only one bootloader anyway :) $main_method; } elsif (my $type = partition_table::raw::typeOfMBR($_)) { warn "typeOfMBR $type on $_ for method $main_method\n" if $ENV{DEBUG}; $type; } else { () } } @devs; if ($type eq $main_method) { my @prefered_entries = map { get_label($_, $bootloader) } $bootloader->{default}, 'linux'; if (my $default = find { $_ && $_->{type} eq 'image' } (@prefered_entries, @{$bootloader->{entries}})) { $bootloader->{default_options} = $default; $bootloader->{perImageAppend} ||= $default->{append}; log::l("perImageAppend is now $bootloader->{perImageAppend}"); } else { $bootloader->{default_options} = {}; } return $bootloader; } } } sub read_grub { my ($fstab) = @_; my $grub2dev = read_grub_device_map(); my $boot_root = read_grub_install_sh(); _may_fix_grub2dev($fstab, $grub2dev, $boot_root->{boot_part}); my $bootloader = read_grub_menu_lst($fstab, $grub2dev) or return; if ($boot_root->{boot}) { $bootloader->{boot} = grub2dev($boot_root->{boot}, $grub2dev); } $bootloader; } # adapts device.map (aka $grub2dev) when for example hda is now sda # nb: # - $boot_part comes from /boot/grub/install.sh "root (hd...)" line # - $grub2dev is /boot/grub/device.map sub _may_fix_grub2dev { my ($fstab, $grub2dev, $boot_part) = @_; $boot_part or log::l("install.sh does not contain 'root (hd...)' line, no way to magically adapt device.map"), return; my $real_boot_part = fs::get::root_($fstab, 'boot') or log::l("argh... the fstab given is useless, it doesn't contain '/'"), return; my $real_boot_dev = $real_boot_part->{rootDevice} or return; # if /boot is on Linux RAID 1, hope things are all right... if (my $prev_boot_part = fs::get::device2part(grub2dev($boot_part, $grub2dev), $fstab)) { # the boot_device as far as grub config files say $real_boot_part == $prev_boot_part and return; } log::l("WARNING: we have detected that device.map is inconsistent with the system"); my ($hd_grub, undef, undef) = parse_grub_file($boot_part); # extract hdX if (my $prev_hd_grub = find { $grub2dev->{$_} eq $real_boot_dev } keys %$grub2dev) { $grub2dev->{$prev_hd_grub} = $grub2dev->{$hd_grub}; log::l("swapping result: $hd_grub/$real_boot_dev and $prev_hd_grub/$grub2dev->{$hd_grub}"); } else { log::l("argh... can't swap, setting $hd_grub to $real_boot_dev anyway"); } $grub2dev->{$hd_grub} = $real_boot_dev; } sub read_grub_install_sh() { my $s = cat_("$::prefix/boot/grub/install.sh"); my %h; #- matches either: #- setup (hd0) #- install (hd0,0)/boot/grub/stage1 d (hd0) (hd0,0)/boot/grub/stage2 p (hd0,0)/boot/grub/menu.lst if ($s =~ /^(?:setup.*|install\s.*\sd)\s+(\(.*?\))/m) { $h{boot} = $1; } if ($s =~ /^root\s+(\(.*?\))/m) { $h{boot_part} = $1; } \%h; } sub _parse_grub_menu_lst() { my $global = 1; my ($e, %b); my $menu_lst_file = "$::prefix/boot/grub/menu.lst"; -e $menu_lst_file or return; foreach (MDK::Common::File::cat_utf8($menu_lst_file)) { my $verbatim = $_; chomp; s/^\s*//; s/\s*$//; next if /^#/ || /^$/; my ($keyword, $v) = split('[ \t=]+', $_, 2) or warn qq(unknown line in /boot/grub/menu.lst: "$_"\n), next; if ($keyword eq 'root') { #- rename to avoid name conflict $keyword = 'grub_root'; } if ($keyword eq 'title') { push @{$b{entries}}, $e = { label => $v }; $global = 0; } elsif ($global) { $b{$keyword} = $v; } else { if ($keyword eq 'kernel') { $e->{type} = 'image'; $e->{kernel} = $v; } elsif ($keyword eq 'chainloader') { $e->{type} = 'other'; $e->{append} = ""; } elsif ($keyword eq 'configfile') { $e->{type} = 'grub_configfile'; $e->{configfile} = $v; } elsif ($keyword eq 'map') { $e->{mapdrive}{$2} = $1 if $v =~ m/\((.*)\) \((.*)\)/; } elsif ($keyword eq 'module') { push @{$e->{modules}}, $v; } else { $e->{$keyword} = $v eq '' ? 1 : $v; } } $e and $e->{verbatim} .= $verbatim; } %b; } sub is_already_crypted { my ($password) = @_; $password =~ /^--md5 (.*)/; } sub read_grub_menu_lst { my ($fstab, $grub2dev) = @_; my %b = _parse_grub_menu_lst(); foreach my $keyword (grep { $_ ne 'entries' } keys %b) { $b{$keyword} = $b{$keyword} eq '' ? 1 : grub2file($b{$keyword}, $grub2dev, $fstab, \%b); } #- sanitize foreach my $e (@{$b{entries}}) { if (member($e->{type}, 'other', 'grub_configfile')) { eval { $e->{kernel_or_dev} = grub2dev($e->{rootnoverify} || $e->{grub_root}, $grub2dev) }; $e->{keep_verbatim} = 1 unless $e->{kernel_or_dev}; } elsif ($e->{initrd}) { my $initrd; eval { $initrd = grub2file($e->{initrd}, $grub2dev, $fstab, $e) }; if ($initrd) { $e->{initrd} = $initrd; } else { $e->{keep_verbatim} = 1; } } if ($e->{kernel} =~ /xen/ && @{$e->{modules} || []} == 2 && $e->{modules}[1] =~ /initrd/) { (my $xen, $e->{xen_append}) = split(' ', $e->{kernel}, 2); ($e->{kernel}, my $initrd) = @{delete $e->{modules}}; $e->{xen} = grub2file($xen, $grub2dev, $fstab, $e); $e->{initrd} = grub2file($initrd, $grub2dev, $fstab, $e); } if (my $v = delete $e->{kernel}) { (my $kernel, $e->{append}) = split(' ', $v, 2); $e->{append} = join(' ', grep { !/^BOOT_IMAGE=/ } split(' ', $e->{append})); $e->{root} = $1 if $e->{append} =~ s/root=(\S*)\s*//; eval { $e->{kernel_or_dev} = grub2file($kernel, $grub2dev, $fstab, $e) }; $e->{keep_verbatim} = 1 unless $e->{kernel_or_dev} && dirname($e->{kernel_or_dev}) eq '/boot'; } my ($vga, $other) = partition { /^vga=/ } split(' ', $e->{append}); if (@$vga) { $e->{vga} = $vga->[0] =~ /vga=(.*)/ && $1; $e->{append} = join(' ', @$other); } } $b{nowarn} = 1; # handle broken installkernel -r: if (@{$b{entries}}) { $b{default} = min($b{default}, scalar(@{$b{entries}}) - 1); $b{default} = $b{entries}[$b{default}]{label}; } $b{method} = $b{gfxmenu} ? 'grub-graphic' : 'grub-menu'; \%b; } sub yaboot2dev { my ($of_path) = @_; find { dev2yaboot($_) eq $of_path } map { "/dev/$_->{dev}" } fs::proc_partitions::read_raw(); } # assumes file is in /boot # to do: use yaboot2dev for files as well #- example of of_path: /pci@f4000000/ata-6@d/disk@0:3,/initrd-2.6.8.1-8mdk.img sub yaboot2file { my ($of_path) = @_; if ($of_path =~ /,/) { "$::prefix/boot/" . basename($of_path); } else { yaboot2dev($of_path); } } sub read_silo() { my $bootloader = read_lilo_like("/boot/silo.conf", sub { my ($f) = @_; "/boot$f"; }); $bootloader->{method} = 'silo'; $bootloader; } # FIXME: actually read back previous conf sub read_pmon2000() { +{ method => 'pmon2000' }; } sub read_uboot() { +{ method => 'uboot' }; } sub read_cromwell() { +{ method => 'cromwell' }; } sub read_yaboot() { my $bootloader = read_lilo_like("/etc/yaboot.conf", \&yaboot2file); $bootloader->{method} = 'yaboot'; $bootloader; } sub read_lilo() { my $bootloader = read_lilo_like("/etc/lilo.conf", sub { $_[0] }); delete $bootloader->{timeout} unless $bootloader->{prompt}; $bootloader->{timeout} = $bootloader->{timeout} / 10 if $bootloader->{timeout}; my $submethod = member($bootloader->{install}, 'text', 'menu') ? $bootloader->{install} : 'menu'; $bootloader->{method} = "lilo-$submethod"; $bootloader; } sub read_lilo_like { my ($file, $filter_file) = @_; my $global = 1; my ($e); my %b; -e "$::prefix$file" or return; foreach my $line (cat_("$::prefix$file")) { next if $line =~ /^\s*#/ || $line =~ /^\s*$/; my ($cmd, $v) = $line =~ /^\s*([^=\s]+)\s*(?:=\s*(.*?))?\s*$/ or log::l("unknown line in $file: $line"), next; if ($cmd =~ /^(?:image|other|macos|macosx|bsd|darwin)$/) { $v = $filter_file->($v); push @{$b{entries}}, $e = { type => $cmd, kernel_or_dev => $v }; $global = 0; } elsif ($global) { if ($cmd eq 'disk' && $v =~ /(\S+)\s+bios\s*=\s*(\S+)/) { $b{bios}{$1} = $2; } elsif ($cmd eq 'bios') { $b{bios}{$b{disk}} = $v; } elsif ($cmd eq 'init-message') { $v =~ s/\\n//g; $v =~ s/"//g; $b{'init-message'} = $v; } else { $b{$cmd} = $v eq '' ? 1 : $v; } } else { if (($cmd eq 'map-drive' .. $cmd eq 'to') && $cmd eq 'to') { $e->{mapdrive}{$e->{'map-drive'}} = $v; } else { if ($cmd eq 'initrd') { $v = $filter_file->($v); } $e->{$cmd} = $v || 1; } } } sub remove_quotes_and_spaces { local ($_) = @_; s/^\s*//; s/\s*$//; s/^"(.*?)"$/$1/; s/\\"/"/g; s/^\s*//; s/\s*$//; #- do it again for append=" foo" $_; } foreach ('append', 'root', 'default', 'raid-extra-boot') { $b{$_} = remove_quotes_and_spaces($b{$_}) if $b{$_}; } foreach my $entry (@{$b{entries}}) { foreach ('append', 'root', 'label') { $entry->{$_} = remove_quotes_and_spaces($entry->{$_}) if $entry->{$_}; } if ($entry->{kernel_or_dev} =~ /\bmbootpack\b/) { $entry->{initrd} = $entry->{kernel_or_dev}; $entry->{initrd} =~ s/\bmbootpack/initrd/; $entry->{kernel_or_dev} =~ s/\bmbootpack/vmlinuz/; $entry->{kernel_or_dev} =~ s/.img$//; #- assume only xen is configured with mbootpack $entry->{xen} = '/boot/xen.gz'; $entry->{root} = $1 if $entry->{append} =~ s/root=(\S*)\s*//; ($entry->{xen_append}, $entry->{append}) = split '\s*--\s*', $entry->{append}, 2; } } # cleanup duplicate labels (in case file is corrupted) @{$b{entries}} = uniq_ { $_->{label} } @{$b{entries}}; \%b; } sub cleanup_entries { my ($bootloader) = @_; #- cleanup bad entries (in case file is corrupted) @{$bootloader->{entries}} = grep { my $pb = $_->{type} eq 'image' && !$_->{keep_verbatim} && ! -e "$::prefix$_->{kernel_or_dev}"; log::l("dropping bootloader entry $_->{label} since $_->{kernel_or_dev} doesn't exist") if $pb; !$pb; } @{$bootloader->{entries}}; } sub suggest_onmbr { my ($hd) = @_; my ($onmbr, $unsafe) = (1, 1); if (my $type = partition_table::raw::typeOfMBR($hd->{device})) { if (member($type, qw(dos dummy empty))) { $unsafe = 0; } elsif (!member($type, qw(lilo grub))) { $onmbr = 0; } log::l("bootloader::suggest_onmbr: type $type, onmbr $onmbr, unsafe $unsafe"); } ($onmbr, $unsafe); } # list of places where we can install the bootloader sub allowed_boot_parts { my ($bootloader, $all_hds) = @_; ( @{$all_hds->{hds}}, # MBR if_($bootloader->{method} =~ /lilo/, grep { $_->{level} eq '1' } @{$all_hds->{raids}} ), (grep { !isFat_or_NTFS($_) } fs::get::fstab($all_hds)), # filesystems except those who do not leave space for our bootloaders detect_devices::floppies(), ); } sub same_entries { my ($a, $b) = @_; foreach (uniq(keys %$a, keys %$b)) { if (member($_, 'label', 'append', 'mapdrive', 'readonly', 'makeactive', 'verbatim')) { next; } elsif ($_ eq 'grub_root' && (!$a->{$_} || !$b->{$_})) { #- grub_root is mostly internal stuff. if it misses, it's ok next; } else { next if $a->{$_} eq $b->{$_}; my ($inode_a, $inode_b) = map { (stat "$::prefix$_")[1] } ($a->{$_}, $b->{$_}); next if $inode_a && $inode_b && $inode_a == $inode_b; } log::l("entries $a->{label} do not have same $_: $a->{$_} ne $b->{$_}"); return; } 1; } sub add_entry { my ($bootloader, $v) = @_; my $to_add = $v; my $label = $v->{label}; for (my $i = 0; $i < 10;) { my $conflicting = get_label($label, $bootloader); $to_add->{label} = $label; if ($conflicting) { #- replacing $conflicting with $to_add @{$bootloader->{entries}} = map { $_ == $conflicting ? $to_add : $_ } @{$bootloader->{entries}}; #- we will keep $conflicting, but not with same symlinks if used by the entry to add expand_entry_symlinks($bootloader, $conflicting); } else { #- we have found an unused label push @{$bootloader->{entries}}, $to_add; } if (!$conflicting || same_entries($conflicting, $to_add)) { log::l("current labels: " . join(" ", map { $_->{label} } @{$bootloader->{entries}})); return $v; } $to_add = $conflicting; if ($to_add->{label} eq 'linux') { $label = kernel_str2label(vmlinuz2kernel_str($to_add->{kernel_or_dev}), 'use_long_name'); } else { $label =~ s/^alt\d*_//; $label = 'alt' . ($i++ ? $i : '') . "_$label"; } } die 'add_entry'; } sub expand_entry_symlinks { my ($bootloader, $entry) = @_; foreach my $kind ('kernel_or_dev', 'initrd') { my $old_long_name = $bootloader->{old_long_names} && $bootloader->{old_long_names}{$entry->{$kind}} or next; #- replace all the {$kind} using this symlink to the real file log::l("replacing $entry->{$kind} with $old_long_name for bootloader label $entry->{label}"); $entry->{$kind} = $old_long_name; } } sub _do_the_symlink { my ($bootloader, $link, $long_name) = @_; my $existing_link = readlink("$::prefix$link"); if ($existing_link && $existing_link eq $long_name) { #- nothing to do :) return; } if ($existing_link) { #- the symlink is going to change! #- replace all the {$kind} using this symlink to the real file my $old_long_name = $existing_link =~ m!^/! ? $existing_link : "/boot/$existing_link"; if (-e "$::prefix$old_long_name") { $bootloader->{old_long_names}{$link} = $old_long_name; } else { log::l("ERROR: $link points to $old_long_name which does not exist"); } } elsif (-e "$::prefix$link") { log::l("ERROR: $link is not a symbolic link"); } #- changing the symlink symlinkf($long_name, "$::prefix$link") or cp_af("$::prefix/boot/$long_name", "$::prefix$link"); } # for lilo & xen sub get_mbootpack_filename { my ($entry) = @_; my $mbootpack_file = $entry->{initrd}; $mbootpack_file =~ s/\binitrd/mbootpack/; $entry->{xen} && $mbootpack_file; } # for lilo & xen sub build_mbootpack { my ($entry) = @_; my $mbootpack = '/usr/bin/mbootpack'; -f $::prefix . $entry->{kernel_or_dev} && -f $::prefix . $entry->{initrd} or return; my $mbootpack_file = get_mbootpack_filename($entry); -f ($::prefix . $mbootpack_file) and return 1; my $error; my $xen_kernel = '/tmp/xen_kernel'; my $xen_vmlinux = '/tmp/xen_vmlinux'; my $_b = before_leaving { unlink $::prefix . $_ foreach $xen_kernel, $xen_vmlinux }; run_program::rooted($::prefix, '/bin/gzip', '>', $xen_kernel, '2>', \$error, '-dc', $entry->{xen}) or die "unable to uncompress xen kernel"; run_program::rooted($::prefix, '/bin/gzip', '>', $xen_vmlinux, '2>', \$error, '-dc', $entry->{kernel_or_dev}) or die "unable to uncompress xen vmlinuz"; run_program::rooted($::prefix, $mbootpack, "2>", \$error, '-o', $mbootpack_file, '-m', $xen_vmlinux, '-m', $entry->{initrd}, $xen_kernel) or die "mbootpack failed: $error"; 1; } sub add_kernel { my ($bootloader, $kernel_str, $v, $b_nolink, $b_no_initrd) = @_; #- eg: for /boot/vmlinuz-2.6.17-13mdvxen0 (pkg kernel-xen0-xxx) #- or /boot/vmlinuz-2.6.18-xen (pkg kernel-xen-uptodate) if ($kernel_str->{version} =~ /xen/ && -f '/boot/xen.gz') { $v->{xen} = '/boot/xen.gz'; } add2hash($v, { type => 'image', label => kernel_str2label($kernel_str), }); #- normalize append and handle special options { my ($simple, $dict) = unpack_append("$bootloader->{perImageAppend} $v->{append}"); if ($v->{label} eq 'failsafe') { #- perImageAppend contains resume=/dev/xxx which we don't want @$dict = grep { $_->[0] ne 'resume' } @$dict; } $v->{append} = pack_append($simple, $dict); } #- new versions of yaboot do not handle symlinks $b_nolink ||= arch() =~ /ppc/; $b_no_initrd //= (arch() =~ /mips|arm/) && !detect_devices::is_mips_gdium(); $b_nolink ||= $kernel_str->{use_long_name}; #- do not link /boot/vmlinuz to xen $b_nolink ||= $v->{xen}; my $vmlinuz_long = kernel_str2vmlinuz_long($kernel_str); my $initrd_long = kernel_str2initrd_long($kernel_str); $v->{kernel_or_dev} = "/boot/$vmlinuz_long"; -e "$::prefix$v->{kernel_or_dev}" or log::l("unable to find kernel image $::prefix$v->{kernel_or_dev}"), return; log::l("adding $v->{kernel_or_dev}"); if (!$b_no_initrd) { $v->{initrd} = mkinitrd($kernel_str->{version}, $bootloader, $v, "/boot/$initrd_long"); } if (!$b_nolink) { $v->{kernel_or_dev} = '/boot/' . kernel_str2vmlinuz_short($kernel_str); if (arch() =~ /mips/) { log::l("link $::prefix/boot/$vmlinuz_long -> $::prefix$v->{kernel_or_dev}"); linkf("$::prefix/boot/$vmlinuz_long", $::prefix . $v->{kernel_or_dev}); linkf("$::prefix/boot/$vmlinuz_long", $::prefix . $v->{kernel_or_dev} . ".32"); } else { _do_the_symlink($bootloader, $v->{kernel_or_dev}, $vmlinuz_long); } if ($v->{initrd}) { $v->{initrd} = '/boot/' . kernel_str2initrd_short($kernel_str); if (arch() =~ /mips/) { log::l("link $::prefix/boot/$initrd_long -> $::prefix$v->{initrd}"); linkf("$::prefix/boot/$initrd_long", $::prefix . $v->{initrd}); if ($v->{initrd} =~ s/.img$/.gz/) { linkf("$::prefix/boot/$initrd_long", $::prefix . $v->{initrd}); } } else { _do_the_symlink($bootloader, $v->{initrd}, $initrd_long); } } } add_entry($bootloader, $v); } sub rebuild_initrds { my ($bootloader) = @_; my %done; foreach my $v (grep { $_->{initrd} } @{$bootloader->{entries}}) { my $kernel_str = vmlinuz2kernel_str($v->{kernel_or_dev}) or next; my $initrd_long = '/boot/' . kernel_str2initrd_long($kernel_str); next if $done{$initrd_long}++; rebuild_initrd($kernel_str->{version}, $bootloader, $v, $initrd_long); } } # unused (?) sub duplicate_kernel_entry { my ($bootloader, $new_label) = @_; get_label($new_label, $bootloader) and return; my $entry = { %{ get_label('linux', $bootloader) }, label => $new_label }; add_entry($bootloader, $entry); } my $uniq_dict_appends = join('|', qw(acpi pci resume PROFILE XFree)); sub unpack_append { my ($s) = @_; my @l = "$s " =~ /((?:[^"\s]+|".*?")*)\s+/g; [ grep { !/=/ } @l ], [ map { if_(/(.*?)=(.*)/, [$1, $2]) } @l ]; } sub pack_append { my ($simple, $dict) = @_; #- normalize $simple = [ reverse(uniq(reverse @$simple)) ]; $dict = [ reverse(uniq_ { my ($k, $v) = @$_; $k =~ /^($uniq_dict_appends)$/ ? $k : "$k=$v"; } reverse @$dict) ]; join(' ', @$simple, map { "$_->[0]=$_->[1]" } @$dict); } sub modify_append { my ($b, $f) = @_; my @l = grep { $_->{type} eq 'image' && !$_->{keep_verbatim} && !($::isStandalone && $_->{label} eq 'failsafe') } @{$b->{entries}}; foreach (\$b->{perImageAppend}, map { \$_->{append} } @l) { my ($simple, $dict) = unpack_append($$_); $f->($simple, $dict); $$_ = pack_append($simple, $dict); log::l("modify_append: $$_"); } } sub get_append_simple { my ($b, $key) = @_; my ($simple, $_dict) = unpack_append($b->{perImageAppend}); member($key, @$simple); } sub get_append_with_key { my ($b, $key) = @_; my ($_simple, $dict) = unpack_append($b->{perImageAppend}); my @l = map { $_->[1] } grep { $_->[0] eq $key } @$dict; log::l("more than one $key in $b->{perImageAppend}") if @l > 1; $l[0]; } sub remove_append_simple { my ($b, $key) = @_; modify_append($b, sub { my ($simple, $_dict) = @_; @$simple = grep { $_ ne $key } @$simple; }); } sub set_append_with_key { my ($b, $key, $val) = @_; modify_append($b, sub { my ($_simple, $dict) = @_; if ($val eq '') { @$dict = grep { $_->[0] ne $key } @$dict; } else { push @$dict, [ $key, $val ]; } }); } sub set_append_simple { my ($b, $key) = @_; modify_append($b, sub { my ($simple, $_dict) = @_; @$simple = uniq(@$simple, $key); }); } sub may_append_with_key { my ($b, $key, $val) = @_; set_append_with_key($b, $key, $val) if !get_append_with_key($b, $key); } sub get_append_netprofile { my ($e) = @_; my ($simple, $dict) = unpack_append($e->{append}); my ($p, $dict_) = partition { $_->[0] eq 'PROFILE' } @$dict; pack_append($simple, $dict_), $p->[0][1]; } sub set_append_netprofile { my ($e, $append, $profile) = @_; my ($simple, $dict) = unpack_append($append); push @$dict, [ 'PROFILE', $profile ] if $profile; $e->{append} = pack_append($simple, $dict); } # used when a bootloader $entry has been modified (eg: $entry->{vga}) sub configure_entry { my ($bootloader, $entry) = @_; $entry->{type} eq 'image' or return; if (my $kernel_str = vmlinuz2kernel_str($entry->{kernel_or_dev})) { $entry->{initrd} = mkinitrd($kernel_str->{version}, $bootloader, $entry, $entry->{initrd} || '/boot/' . kernel_str2initrd_short($kernel_str)); } } sub get_kernels_and_labels_before_kernel_remove { my ($to_remove_kernel) = @_; my @kernels = grep { $_ ne $to_remove_kernel } installed_vmlinuz(); map { kernel_str2label($_) => $_ } get_kernel_labels(\@kernels); } sub get_kernels_and_labels() { get_kernel_labels([ installed_vmlinuz() ]); } sub get_kernel_labels { my ($kernels) = @_; my @kernels_str = sort { common::cmp_kernel_versions($b->{version_no_ext}, $a->{version_no_ext}) } grep { -d "$::prefix/lib/modules/$_->{version}" } map { vmlinuz2kernel_str($_) } @$kernels; my %labels; foreach (@kernels_str) { if ($labels{$_->{ext}}) { $_->{use_long_name} = 1; } else { $labels{$_->{ext}} = 1; } } $kernels_str[0]{ext} = ''; @kernels_str; } sub short_ext { my ($kernel_str) = @_; my $short_ext = { 'i586-up-1GB' => 'i586', 'i686-up-4GB' => '4GB', 'xen0' => 'xen', }->{$kernel_str->{ext}}; $short_ext || $kernel_str->{ext}; } # deprecated, only for compatibility (nov 2007) sub sanitize_ver { my ($_name, $kernel_str) = @_; _sanitize_ver($kernel_str); } sub _sanitize_ver { my ($kernel_str) = @_; my $name = $kernel_str->{basename}; $name = '' if $name eq 'vmlinuz'; my $v = $kernel_str->{version_no_ext}; if ($v =~ s/-\d+\.mm\././) { $name = join(' ', grep { $_ } $name, 'multimedia'); } $v =~ s!(md[kv]|mnb)$!!; $v =~ s!-0\.(pre|rc)(\d+)\.!$1$2-!; my $return = join(' ', grep { $_ } $name, short_ext($kernel_str), $v); length($return) < 30 or $return =~ s!secure!sec!; length($return) < 30 or $return =~ s!enterprise!ent!; length($return) < 30 or $return =~ s!multimedia!mm!; $return; } # for lilo sub suggest_message_text { my ($bootloader) = @_; if (!$bootloader->{message} && !$bootloader->{message_text} && arch() !~ /ia64/) { my $msg_en = #-PO: these messages will be displayed at boot time in the BIOS, use only ASCII (7bit) N_("Welcome to the operating system chooser! Choose an operating system from the list above or wait for default boot. "); my $msg = translate($msg_en); #- use the english version if more than 40% of 8bits chars #- else, use the translation but force a conversion to ascii #- to be sure there won't be undisplayable characters if (int(grep { $_ & 0x80 } unpack "c*", $msg) / length($msg) > 0.4) { $msg = $msg_en; } else { $msg = Locale::gettext::iconv($msg, "utf-8", "ascii//TRANSLIT"); } $bootloader->{message_text} = $msg; } } sub suggest { my ($bootloader, $all_hds, %options) = @_; my $fstab = [ fs::get::fstab($all_hds) ]; my $root_part = fs::get::root($fstab); my $root = isLoopback($root_part) ? '/dev/loop7' : fs::wild_device::from_part('', $root_part); my $boot = fs::get::root($fstab, 'boot')->{device}; #- PPC xfs module requires enlarged initrd my $xfsroot = $root_part->{fs_type} eq 'xfs'; my $mbr; # If installing onto an USB drive, put the mbr there, else on the first non removable drive if ($root_part->{is_removable}) { $mbr = fs::get::part2hd($root_part, $all_hds); } else { $mbr = find { !$_->{is_removable} } @{$all_hds->{hds}}; } my ($onmbr, $unsafe) = $bootloader->{crushMbr} ? (1, 0) : suggest_onmbr($mbr); add2hash_($bootloader, arch() =~ /ppc/ ? { defaultos => "linux", entries => [], 'init-message' => "Welcome to %s!", delay => 30, #- OpenFirmware delay timeout => 50, enableofboot => 1, enablecdboot => 1, if_(detect_devices::get_mac_model() =~ /IBM/, boot => "/dev/sda1", ), xfsroot => $xfsroot, } : { bootUnsafe => $unsafe, entries => [], timeout => $onmbr && 10, nowarn => 1, if_(arch() !~ /ia64/, boot => "/dev/" . ($onmbr ? $mbr->{device} : $boot), map => "/boot/map", compact => 1, 'large-memory' => 1, color => 'black/cyan yellow/cyan', 'menu-scheme' => 'wb:bw:wb:bw' ), }); suggest_message_text($bootloader); add2hash_($bootloader, { memsize => $1 }) if cat_("/proc/cmdline") =~ /\bmem=(\d+[KkMm]?)(?:\s.*)?$/; if (my ($s, $port, $speed) = cat_("/proc/cmdline") =~ /console=(ttyS(\d),(\d+)\S*)/) { log::l("serial console $s $port $speed"); set_append_with_key($bootloader, console => $s); any::set_login_serial_console($port, $speed); } my @kernels = get_kernels_and_labels() or die "no kernel installed"; my %old_kernels = map { vmlinuz2version($_->{kernel_or_dev}) => 1 } @{$bootloader->{entries}}; @kernels = grep { !$old_kernels{$_->{version}} } @kernels; #- remove existing failsafe and linux-nonfb, do not care if the previous one was modified by the user? @{$bootloader->{entries}} = grep { !member($_->{label}, qw(failsafe linux-nonfb)) } @{$bootloader->{entries}}; foreach my $kernel (@kernels) { my $e = add_kernel($bootloader, $kernel, { root => $root, if_($options{vga_fb}, vga => $options{vga_fb}), #- using framebuffer if_($options{vga_fb} && $options{splash}, append => "splash"), if_($options{quiet}, append => "quiet"), }); if ($options{vga_fb} && $e->{label} eq 'linux') { add_kernel($bootloader, $kernel, { root => $root, label => 'linux-nonfb' }); } } add_kernel($bootloader, $kernels[0], { root => $root, label => 'failsafe', append => 'failsafe' }) if @kernels; if (arch() =~ /ppc/) { #- if we identified a MacOS partition earlier - add it if (defined $partition_table::mac::macos_part) { add_entry($bootloader, { type => "macos", kernel_or_dev => $partition_table::mac::macos_part }); } } elsif (arch() !~ /ia64/) { #- search for dos (or windows) boot partition. Do not look in extended partitions! my @windows_boot_parts = grep { $_->{active} && isFat_or_NTFS($_) && member(fs::type::fs_type_from_magic($_), 'vfat', 'ntfs', 'ntfs-3g') && !$_->{is_removable} && !isRecovery($_); } map { @{$_->{primary}{normal}} } @{$all_hds->{hds}}; each_index { add_entry($bootloader, { type => 'other', kernel_or_dev => "/dev/$_->{device}", label => 'windows' . ($::i || ''), table => "/dev/$_->{rootDevice}", makeactive => 1, }); } @windows_boot_parts; } my @preferred = map { "linux-$_" } 'p3-smp-64GB', 'secure', 'enterprise', 'smp', 'i686-up-4GB'; if (my $preferred = find { get_label($_, $bootloader) } @preferred) { $bootloader->{default} ||= $preferred; } $bootloader->{default} ||= "linux"; $bootloader->{method} ||= first(method_choices($all_hds, 1), # best installed method_choices($all_hds, 0)); # or best if no valid one is installed if (main_method($bootloader->{method}) eq 'grub') { foreach my $c (find_other_distros_grub_conf($fstab)) { add_entry($bootloader, { type => 'grub_configfile', label => $c->{name}, kernel_or_dev => "/dev/$c->{bootpart}{device}", configfile => $c->{grub_conf}, }); } } } sub detect_main_method { my ($all_hds) = @_; my $bootloader = &read($all_hds); $bootloader && main_method($bootloader->{method}); } sub main_method { my ($method) = @_; $method =~ /(\w+)/ && $1; } sub config_files() { my %files = ( lilo => '/etc/lilo.conf', grub => '/boot/grub/menu.lst', grub_install => '/boot/grub/install.sh', ); map_each { my $content = cat_("$::prefix/$::b"); { main_method => main_method($::a), name => $::a, file => $::b, content => $content }; } %files; } sub method2text { my ($method) = @_; +{ 'lilo-menu' => N("LILO with text menu"), 'grub-graphic' => N("GRUB with graphical menu"), 'grub-menu' => N("GRUB with text menu"), 'yaboot' => N("Yaboot"), 'silo' => N("SILO"), }->{$method}; } sub method_choices_raw { my ($b_prefix_mounted) = @_; detect_devices::is_xbox() ? 'cromwell' : arch() =~ /ppc/ ? 'yaboot' : arch() =~ /ia64/ ? 'lilo' : arch() =~ /sparc/ ? 'silo' : arch() =~ /mips/ ? 'pmon2000' : arch() =~ /arm/ ? 'uboot' : ( if_(!$b_prefix_mounted || whereis_binary('grub', $::prefix), 'grub-graphic', 'grub-menu'), if_(!$b_prefix_mounted || whereis_binary('lilo', $::prefix), 'lilo-menu'), ); } sub method_choices { my ($all_hds, $b_prefix_mounted) = @_; my $fstab = [ fs::get::fstab($all_hds) ]; my $root_part = fs::get::root($fstab); my $boot_part = fs::get::root($fstab, 'boot'); my $have_dmraid = find { fs::type::is_dmraid($_) } @{$all_hds->{hds}}; grep { !(/lilo/ && (isLoopback($root_part) || $have_dmraid)) && !(/grub/ && isRAID($boot_part)) && !(/grub-graphic/ && cat_("/proc/cmdline") =~ /console=ttyS/); } method_choices_raw($b_prefix_mounted); } sub main_method_choices { my ($b_prefix_mounted) = @_; uniq(map { main_method($_) } method_choices_raw($b_prefix_mounted)); } sub configured_main_methods() { my @bad_main_methods = map { if_(!$_->{content}, $_->{main_method}) } config_files(); difference2([ main_method_choices(1) ], \@bad_main_methods); } # for lilo sub keytable { my ($f) = @_; $f or return; if ($f !~ /\.klt$/) { my $file = "/boot/$f.klt"; run_program::rooted($::prefix, "keytab-lilo.pl", ">", $file, $f) or return; $f = $file; } -r "$::prefix/$f" && $f; } sub create_link_source() { #- we simply do it for all kernels :) #- so this can be used in %post of kernel and also of kernel-source foreach (all("$::prefix/usr/src")) { my ($version) = /^linux-(\d+\.\d+.*)/ or next; foreach (glob("$::prefix/lib/modules/$version*")) { -d $_ or next; log::l("creating symlink $_/build"); symlink "/usr/src/linux-$version", "$_/build"; log::l("creating symlink $_/source"); symlink "/usr/src/linux-$version", "$_/source"; } } } sub dev2yaboot { my ($dev) = @_; devices::make("$::prefix$dev"); #- create it in the chroot my $of_dev; run_program::rooted_or_die($::prefix, "/usr/sbin/ofpath", ">", \$of_dev, $dev); chomp($of_dev); log::l("OF Device: $of_dev"); $of_dev; } sub check_enough_space() { my $e = "$::prefix/boot/.enough_space"; output $e, 1; -s $e or die N("not enough room in /boot"); unlink $e; } sub write_yaboot { my ($bootloader, $all_hds) = @_; my $fstab = [ fs::get::fstab($all_hds) ]; my $file2yaboot = sub { my ($part, $file) = fs::get::file2part($fstab, $_[0]); dev2yaboot('/dev/' . $part->{device}) . "," . $file; }; #- do not write yaboot.conf for old-world macs my $mac_type = detect_devices::get_mac_model(); return if $mac_type =~ /Power Macintosh/; $bootloader->{prompt} ||= $bootloader->{timeout}; if ($bootloader->{message_text}) { eval { output("$::prefix/boot/message", $bootloader->{message_text}) } and $bootloader->{message} = '/boot/message'; } my @conf; if (!get_label($bootloader->{default}, $bootloader)) { log::l("default bootloader entry $bootloader->{default} is invalid, choosing another one"); $bootloader->{default} = $bootloader->{entries}[0]{label}; } push @conf, "# yaboot.conf - generated by DrakX/drakboot"; push @conf, "# WARNING: do not forget to run ybin after modifying this file\n"; push @conf, "default=" . make_label_lilo_compatible($bootloader->{default}) if $bootloader->{default}; push @conf, sprintf('init-message="\n%s\n"', $bootloader->{'init-message'}) if $bootloader->{'init-message'}; if ($bootloader->{boot}) { push @conf, "boot=$bootloader->{boot}"; push @conf, "ofboot=" . dev2yaboot($bootloader->{boot}) if $mac_type !~ /IBM/; } else { die "no bootstrap partition defined."; } push @conf, map { "$_=$bootloader->{$_}" } grep { $bootloader->{$_} } (qw(delay timeout), if_($mac_type !~ /IBM/, 'defaultos')); push @conf, "install=/usr/lib/yaboot/yaboot"; if ($mac_type =~ /IBM/) { push @conf, 'nonvram'; } else { push @conf, 'magicboot=/usr/lib/yaboot/ofboot'; push @conf, grep { $bootloader->{$_} } qw(enablecdboot enableofboot); } foreach my $entry (@{$bootloader->{entries}}) { if ($entry->{type} eq "image") { push @conf, "$entry->{type}=" . $file2yaboot->($entry->{kernel_or_dev}); my @entry_conf; push @entry_conf, "label=" . make_label_lilo_compatible($entry->{label}); push @entry_conf, "root=$entry->{root}"; push @entry_conf, "initrd=" . $file2yaboot->($entry->{initrd}) if $entry->{initrd}; #- xfs module on PPC requires larger initrd - say 6MB? push @entry_conf, "initrd-size=6144" if $bootloader->{xfsroot}; push @entry_conf, qq(append=" $entry->{append}") if $entry->{append}; push @entry_conf, grep { $entry->{$_} } qw(read-write read-only); push @conf, map { "\t$_" } @entry_conf; } else { my $of_dev = dev2yaboot($entry->{kernel_or_dev}); push @conf, "$entry->{type}=$of_dev"; } } my $f = "$::prefix/etc/yaboot.conf"; log::l("writing yaboot config to $f"); renamef($f, "$f.old"); output($f, map { "$_\n" } @conf); } sub install_yaboot { my ($bootloader, $all_hds) = @_; log::l("Installing boot loader..."); write_yaboot($bootloader, $all_hds); when_config_changed_yaboot($bootloader); } sub when_config_changed_yaboot { my ($bootloader) = @_; $::testing and return; if (defined $partition_table::mac::new_bootstrap) { run_program::run("hformat", $bootloader->{boot}) or die "hformat failed"; } my $error; run_program::rooted($::prefix, "/usr/sbin/ybin", "2>", \$error) or die "ybin failed: $error"; } sub install_pmon2000 { my ($_bootloader, $_all_hds) = @_; log::l("Mips/pmon2000 - nothing to install..."); } sub write_pmon2000 { my ($_bootloader, $_all_hds) = @_; log::l("Mips/pmon2000 - nothing to write..."); } sub when_config_changed_pmon2000 { my ($_bootloader) = @_; log::l("Mips/pmon2000 - nothing to do..."); } sub install_uboot { my ($_bootloader, $_all_hds) = @_; log::l("uboot - nothing to install..."); } sub write_uboot { my ($_bootloader, $_all_hds) = @_; log::l("uboot - nothing to write..."); } sub when_config_changed_uboot { my ($_bootloader) = @_; log::l("uboot - nothing to do..."); } sub install_cromwell { my ($_bootloader, $_all_hds) = @_; log::l("XBox/Cromwell - nothing to install..."); } sub write_cromwell { my ($_bootloader, $_all_hds) = @_; log::l("XBox/Cromwell - nothing to write..."); } sub when_config_changed_cromwell { my ($_bootloader) = @_; log::l("XBox/Cromwell - nothing to do..."); } sub simplify_label { my ($label) = @_; length($label) < 31 or $label =~ s/\.//g; $label = substr($label, 0, 31); #- lilo does not handle more than 31 char long labels $label =~ s/ /_/g; #- lilo does not support blank character in image names, labels or aliases $label; } sub make_label_lilo_compatible { my ($label) = @_; '"' . simplify_label($label) . '"'; } sub write_lilo { my ($bootloader, $all_hds, $o_backup_extension) = @_; $bootloader->{prompt} ||= $bootloader->{timeout}; my $file2fullname = sub { my ($file) = @_; if (arch() =~ /ia64/) { my $fstab = [ fs::get::fstab($all_hds) ]; (my $part, $file) = fs::get::file2part($fstab, $file); my %hds = map_index { $_ => "hd$::i" } map { $_->{device} } sort { my ($a_is_fat, $b_is_fat) = ($a->{fs_type} eq 'vfat', $b->{fs_type} eq 'vfat'); $a_is_fat <=> $b_is_fat || $a->{device} cmp $b->{device}; } @$fstab; $hds{$part->{device}} . ":" . $file; } else { $file; } }; my $quotes = sub { my ($s) = @_; $s =~ s/"/\\"/g; qq("$s"); }; my $quotes_if_needed = sub { my ($s) = @_; $s =~ /["=\s]/ ? $quotes->($s) : $s; }; my @sorted_hds = sort_hds_according_to_bios($bootloader, $all_hds); if (is_empty_hash_ref($bootloader->{bios} ||= {}) && $all_hds->{hds}[0] != $sorted_hds[0]) { log::l("Since we're booting on $sorted_hds[0]{device}, make it bios=0x80"); $bootloader->{bios} = { "/dev/$sorted_hds[0]{device}" => '0x80' }; } my @conf; #- normalize: RESTRICTED and MANDATORY are only valid if PASSWORD is set if ($bootloader->{password}) { # lilo defaults to mandatory, use restricted by default to have # the same behaviour as with grub $bootloader->{restricted} = 1; } else { delete $bootloader->{mandatory} if !$bootloader->{password}; delete $bootloader->{restricted} if !$bootloader->{password}; } foreach my $entry (@{$bootloader->{entries}}) { delete $entry->{mandatory} if !$entry->{password} && !$bootloader->{password}; delete $entry->{restricted} if !$entry->{password} && !$bootloader->{password}; } if (get_append_with_key($bootloader, 'console') =~ /ttyS(.*)/) { $bootloader->{serial} ||= $1; } if (!get_label($bootloader->{default}, $bootloader)) { log::l("default bootloader entry $bootloader->{default} is invalid, choosing another one"); $bootloader->{default} = $bootloader->{entries}[0]{label}; } push @conf, "# File generated by DrakX/drakboot"; push @conf, "# WARNING: do not forget to run lilo after modifying this file\n"; push @conf, "default=" . make_label_lilo_compatible($bootloader->{default}) if $bootloader->{default}; push @conf, map { $_ . '=' . $quotes_if_needed->($bootloader->{$_}) } grep { $bootloader->{$_} } qw(boot root map install serial vga keytable raid-extra-boot menu-scheme vmdefault); push @conf, grep { $bootloader->{$_} } qw(linear geometric compact prompt mandatory nowarn restricted static-bios-codes large-memory); push @conf, "append=" . $quotes->($bootloader->{append}) if $bootloader->{append}; push @conf, "password=" . $bootloader->{password} if $bootloader->{password}; #- also done by msec push @conf, "timeout=" . round(10 * $bootloader->{timeout}) if $bootloader->{timeout}; push @conf, "message=$bootloader->{message}" if $bootloader->{message}; push @conf, "ignore-table" if any { $_->{unsafe} && $_->{table} } @{$bootloader->{entries}}; push @conf, map_each { "disk=$::a bios=$::b" } %{$bootloader->{bios}}; foreach my $entry (@{$bootloader->{entries}}) { my $mbootpack_file = get_mbootpack_filename($entry); if ($mbootpack_file && !build_mbootpack($entry)) { warn "mbootpack is required for xen but unavailable, skipping\n"; next; } if ($entry->{type} eq 'grub_configfile') { next; } push @conf, "$entry->{type}=" . $file2fullname->($mbootpack_file || $entry->{kernel_or_dev}); my @entry_conf; push @entry_conf, "label=" . make_label_lilo_compatible($entry->{label}) if $entry->{label}; if ($entry->{type} eq "image") { push @entry_conf, 'root=' . $quotes_if_needed->($entry->{root}) if $entry->{root} && !$entry->{xen}; push @entry_conf, "initrd=" . $file2fullname->($entry->{initrd}) if $entry->{initrd} && !$mbootpack_file; my $append = join(' ', if_($entry->{xen_append}, $entry->{xen_append}), if_($entry->{xen}, '--', 'root=' . $entry->{root}), if_($entry->{append}, $entry->{append})); push @entry_conf, "append=" . $quotes->($append) if $append; push @entry_conf, "vga=$entry->{vga}" if $entry->{vga}; push @entry_conf, grep { $entry->{$_} } qw(read-write read-only optional); push @entry_conf, "mandatory" if $entry->{lock}; } else { delete $entry->{unsafe} if $entry->{table}; #- we can't have both push @entry_conf, map { "$_=$entry->{$_}" } grep { $entry->{$_} } qw(table boot-as); push @entry_conf, grep { $entry->{$_} } qw(unsafe master-boot); if ($entry->{table}) { #- hum, things like table=c: are needed for some os2 cases, #- in that case $hd below is undef my $hd = fs::get::device2part($entry->{table}, $all_hds->{hds}); if ($hd && $hd != $sorted_hds[0]) { #- boot off the nth drive, so reverse the BIOS maps my $nb = sprintf("0x%x", 0x80 + (find_index { $hd == $_ } @sorted_hds)); $entry->{mapdrive} ||= { '0x80' => $nb, $nb => '0x80' }; } } if ($entry->{mapdrive}) { push @entry_conf, map_each { "map-drive=$::a", " to=$::b" } %{$entry->{mapdrive}}; } } push @entry_conf, "password=$entry->{password}" if $entry->{password}; push @entry_conf, grep { $entry->{$_} } qw(mandatory vmwarn vmdisable); push @conf, map { "\t$_" } @entry_conf; } my $f = arch() =~ /ia64/ ? "$::prefix/boot/efi/elilo.conf" : "$::prefix/etc/lilo.conf"; log::l("writing lilo config to $f"); renamef($f, $f . ($o_backup_extension || '.old')); output_with_perm($f, $bootloader->{password} ? 0600 : 0644, map { "$_\n" } @conf); } sub install_lilo { my ($bootloader, $all_hds) = @_; if (my ($install) = $bootloader->{method} =~ /lilo-(text|menu)/) { $bootloader->{install} = $install; } else { delete $bootloader->{install}; } if ($bootloader->{message_text}) { output("$::prefix/boot/message-text", $bootloader->{message_text}); } my $message = "message-text"; if (-r "$::prefix/boot/$message") { symlinkf $message, "$::prefix/boot/message"; $bootloader->{message} = '/boot/message'; } #- ensure message does not contain the old graphic format if ($bootloader->{message} && -s "$::prefix$bootloader->{message}" > 65_000) { output("$::prefix$bootloader->{message}", ''); } write_lilo($bootloader, $all_hds); when_config_changed_lilo($bootloader); configure_kdm_BootManager('Lilo'); } sub install_raw_lilo { my ($o_force_answer) = @_; my $error; my $answer = $o_force_answer || ''; run_program::rooted($::prefix, "echo $answer | lilo", '2>', \$error) or die "lilo failed: $error"; } sub when_config_changed_lilo { my ($bootloader) = @_; if (!$::testing && arch() !~ /ia64/ && $bootloader->{method} =~ /lilo/) { log::l("Installing boot loader on $bootloader->{boot}..."); install_raw_lilo($bootloader->{force_lilo_answer}); } } #- NB: ide is lower than scsi, this is important for sort_hds_according_to_bios() sub hd2bios_kind { my ($hd) = @_; lc(join('_', $hd->{bus}, $hd->{host})); } sub ensafe_first_bios_drive { my ($hds) = @_; mixed_kind_of_disks($hds) || @$hds > 1 && _not_first_bios_drive($hds->[0]); } sub mixed_kind_of_disks { my ($hds) = @_; (uniq_ { hd2bios_kind($_) } @$hds) > 1; } sub _not_first_bios_drive { my ($hd) = @_; my $bios = $hd && $hd->{bios_from_edd}; $bios && $bios ne '80'; } sub sort_hds_according_to_bios { my ($bootloader, $all_hds) = @_; my $boot_hd = fs::get::device2part($bootloader->{first_hd_device} || $bootloader->{boot}, $all_hds->{hds}); #- $boot_hd is undefined when installing on floppy my $boot_kind = $boot_hd && hd2bios_kind($boot_hd); my $translate = sub { my ($hd) = @_; my $kind = hd2bios_kind($hd); $boot_hd ? ($hd == $boot_hd ? 0 : $kind eq $boot_kind ? 1 : 2) . "_$kind" : $kind; }; sort { $translate->($a) cmp $translate->($b) } @{$all_hds->{hds}}; } sub device_string2grub { my ($dev, $legacy_floppies, $sorted_hds) = @_; if (my $device = fs::get::device2part($dev, [ @$sorted_hds, fs::get::hds_fstab(@$sorted_hds) ])) { device2grub($device, $sorted_hds); } elsif (my $floppy = fs::get::device2part($dev, $legacy_floppies)) { my $bios = find_index { $floppy eq $_ } @$legacy_floppies; "(fd$bios)"; } else { internal_error("unknown device $dev"); } } sub device2grub { my ($device, $sorted_hds) = @_; if (isRAID($device) && $device->{level} == 1) { #- we can take any disk $device = $device->{disks}[0]; } my ($hd, $part_nb) = $device->{rootDevice} ? (fs::get::device2part($device->{rootDevice}, $sorted_hds), $device->{device} =~ /(\d+)$/) : $device; my $bios = eval { find_index { $hd eq $_ } @$sorted_hds }; if (defined $bios) { my $part_string = defined $part_nb ? ',' . ($part_nb - 1) : ''; "(hd$bios$part_string)"; } else { undef; } } sub read_grub_device_map() { my %grub2dev = map { m!\((.*)\)\s+/dev/(.*)$! } cat_("$::prefix/boot/grub/device.map"); \%grub2dev; } sub write_grub_device_map { my ($legacy_floppies, $sorted_hds) = @_; my $f = "$::prefix/boot/grub/device.map"; renamef($f, "$f.old"); output($f, (map_index { "(fd$::i) /dev/$_->{device}\n" } @$legacy_floppies), (map_index { "(hd$::i) /dev/$_->{device}\n" } @$sorted_hds)); } # parses things like "(hd0,4)/boot/vmlinuz" # returns: ("hd0", 4, "boot/vmlinuz") sub parse_grub_file { my ($grub_file) = @_; my ($grub_dev, $rel_file) = $grub_file =~ m!\((.*?)\)/?(.*)! or return; my ($hd, $part) = split(',', $grub_dev); ($hd, $part, $rel_file); } # takes things like "(hd0,4)/boot/vmlinuz" # returns: ("/dev/sda5", "boot/vmlinuz") sub grub2dev_and_file { my ($grub_file, $grub2dev, $o_block_device) = @_; my ($hd, $part, $rel_file) = parse_grub_file($grub_file) or return; $grub2dev->{$hd} or internal_error("$hd has no mapping in device.map (when translating $grub_file)"); $part = $o_block_device ? '' : defined $part && $part + 1; #- grub wants "(hdX,Y)" where lilo just want "hdY+1" my $device = '/dev/' . ($part eq '' ? $grub2dev->{$hd} : devices::prefix_for_dev($grub2dev->{$hd}) . $part); $device, $rel_file; } # takes things like "(hd0,4)/boot/vmlinuz" # returns: "/dev/sda5" sub grub2dev { my ($grub_file, $grub2dev, $o_block_device) = @_; first(grub2dev_and_file($grub_file, $grub2dev, $o_block_device)); } # replaces # - "/vmlinuz" with "/boot/vmlinuz" when "root" or "rootnoverify" is set for the entry # - "(hdX,Y)" in "(hdX,Y)/boot/vmlinuz..." by appropriate path if possible/needed sub grub2file { my ($grub_file, $grub2dev, $fstab, $o_entry) = @_; if ($grub_file =~ m!^/!) { my $root = $o_entry && ($o_entry->{rootnoverify} || $o_entry->{grub_root}); $root and $grub_file = "$root$grub_file"; } if (my ($device, $rel_file) = grub2dev_and_file($grub_file, $grub2dev)) { my $part = fs::get::device2part($device, $fstab); if (my $mntpoint = $part && $part->{mntpoint}) { ($mntpoint eq '/' ? '' : $mntpoint) . '/' . $rel_file; } else { log::l("ERROR: unknown device $device (computed from $grub_file)"); $grub_file; } } else { $grub_file; } } sub boot_copies_dir() { '/boot/copied' } sub create_copy_in_boot { my ($file) = @_; my $s = $file; $s =~ s!/!_!g; my $file2 = boot_copies_dir() . "/$s"; log::l("$file is not available at boot time, creating a copy ($file2)"); mkdir_p(boot_copies_dir()); output("$file2.link", $file . "\n"); update_copy_in_boot("$file2.link"); $file2; } sub update_copy_in_boot { my ($link) = @_; my $orig = chomp_(cat_("$::prefix$link")); (my $dest = $link) =~ s/\.link$// or internal_error("update_copy_in_boot: $link"); if (-e "$::prefix$orig") { log::l("updating $dest from $orig"); cp_af("$::prefix$orig", "$::prefix$dest"); } else { log::l("removing $dest since $orig does not exist anymore"); unlink "$::prefix$link", "$::prefix$orig"; } } sub crypt_grub_password { my ($password) = @_; require IPC::Open2; local $ENV{LC_ALL} = 'C'; my ($his_out, $his_in); my $cmd = ($::prefix ? "chroot $::prefix " : "") . "/sbin/grub-md5-crypt"; my $pid = IPC::Open2::open2($his_out, $his_in, $cmd); my ($line, $res); while (sysread($his_out, $line, 100)) { if ($line =~ /Password/i) { syswrite($his_in, "$password\n"); } else { $res = $line; } } waitpid($pid, 0); my $status = $? >> 8; die "failed to encrypt password (status=$status)" if $status != 0; chomp_($res); } sub write_grub { my ($bootloader, $all_hds, $o_backup_extension) = @_; my $fstab = [ fs::get::fstab($all_hds) ]; my @legacy_floppies = detect_devices::floppies(); my @sorted_hds = sort_hds_according_to_bios($bootloader, $all_hds); write_grub_device_map(\@legacy_floppies, \@sorted_hds); my $file2grub; $file2grub = sub { my ($file) = @_; if ($file =~ m!^\(.*\)/!) { $file; #- it's already in grub format } else { my ($part, $rel_file) = fs::get::file2part($fstab, $file, 'keep_simple_symlinks'); if (my $grub = device2grub($part, \@sorted_hds)) { $grub . $rel_file; } elsif (!begins_with($file, '/boot/')) { log::l("$file is on device $part->{device} which is not available at boot time. Copying it"); $file2grub->(create_copy_in_boot($file)); } else { log::l("ERROR: $file is on device $part->{device} which is not available at boot time. Defaulting to a dumb value"); "(hd0,0)$file"; } } }; if (get_append_with_key($bootloader, 'console') =~ /ttyS(\d),(\d+)/) { $bootloader->{serial} ||= "--unit=$1 --speed=$2"; $bootloader->{terminal} ||= "--timeout=" . ($bootloader->{timeout} || 0) . " console serial"; } elsif ($bootloader->{method} eq 'grub-graphic') { my $bin = '/usr/sbin/grub-gfxmenu'; if ($bootloader->{gfxmenu} eq '' && -x "$::prefix$bin") { my $locale = $::o->{locale} || do { require lang; lang::read() }; run_program::rooted($::prefix, $bin, '--lang', $locale->{lang}, '--update-gfxmenu'); $bootloader->{gfxmenu} ||= '/boot/gfxmenu'; } #- not handled anymore delete $bootloader->{$_} foreach qw(splashimage viewport shade); } else { delete $bootloader->{gfxmenu}; } my $format = sub { map { "$_ $bootloader->{$_}" } @_ }; { my @conf; if ($bootloader->{password}) { if (!is_already_crypted($bootloader->{password})) { my $encrypted = crypt_grub_password($bootloader->{password}); $bootloader->{password} = "--md5 $encrypted"; } } push @conf, $format->(grep { defined $bootloader->{$_} } qw(timeout)); push @conf, $format->(grep { $bootloader->{$_} } qw(color password serial shade terminal viewport background foreground)); push @conf, map { $_ . ' ' . $file2grub->($bootloader->{$_}) } grep { $bootloader->{$_} } qw(gfxmenu); eval { push @conf, "default " . (find_index { $_->{label} eq $bootloader->{default} } @{$bootloader->{entries}}); }; foreach my $entry (@{$bootloader->{entries}}) { my $title = "\ntitle $entry->{label}"; if ($entry->{keep_verbatim}) { push @conf, '', $entry->{verbatim}; } elsif ($entry->{type} eq "image") { push @conf, $title; push @conf, grep { $entry->{$_} } 'lock'; push @conf, join(' ', 'kernel', $file2grub->($entry->{xen}), $entry->{xen_append}) if $entry->{xen}; my $vga = $entry->{vga} || $bootloader->{vga}; push @conf, join(' ', $entry->{xen} ? 'module' : 'kernel', $file2grub->($entry->{kernel_or_dev}), $entry->{xen} ? () : 'BOOT_IMAGE=' . simplify_label($entry->{label}), if_($entry->{root}, $entry->{root} =~ /loop7/ ? "root=707" : "root=$entry->{root}"), #- special to workaround bug in kernel (see #ifdef CONFIG_BLK_DEV_LOOP) $entry->{append}, if_($entry->{'read-write'}, 'rw'), if_($vga && $vga ne "normal", "vga=$vga")); push @conf, "module " . $_ foreach @{$entry->{modules} || []}; push @conf, join(' ', $entry->{xen} ? 'module' : 'initrd', $file2grub->($entry->{initrd})) if $entry->{initrd}; } else { my $dev = eval { device_string2grub($entry->{kernel_or_dev}, \@legacy_floppies, \@sorted_hds) }; if (!$dev) { log::l("dropping bad entry $entry->{label} for unknown device $entry->{kernel_or_dev}"); next; } push @conf, $title; push @conf, grep { $entry->{$_} } 'lock'; push @conf, join(' ', $entry->{rootnoverify} ? 'rootnoverify' : 'root', $dev);