]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blob - src/install+setup/install/main.c
Proxy.cgi changes for new squid.
[people/pmueller/ipfire-2.x.git] / src / install+setup / install / main.c
1 /* SmoothWall install program.
2 *
3 * This program is distributed under the terms of the GNU General Public
4 * Licence. See the file COPYING for details.
5 *
6 * (c) Lawrence Manning, 2001
7 * Contains main entry point, and misc functions.6
8 *
9 */
10
11 #include "install.h"
12 #define _GNU_SOURCE
13
14 #define INST_FILECOUNT 8400
15 #define UNATTENDED_CONF "/cdrom/boot/unattended.conf"
16
17 #define EXT2 0
18 #define REISERFS 2
19 #define EXT3 1
20
21 FILE *flog = NULL;
22 char *mylog;
23
24 char **ctr;
25
26 extern char url[STRING_SIZE];
27
28 struct nic nics[20] = { { "" , "" , "" } }; // only defined for compile
29 struct knic knics[20] = { { "" , "" , "" , "" } }; // only defined for compile
30
31 extern char *en_tr[];
32 extern char *es_tr[];
33 extern char *de_tr[];
34 extern char *fr_tr[];
35
36 int main(int argc, char *argv[])
37 {
38
39 char discl_msg[40000] = "Disclaimer\n";
40
41 char *langnames[] = { "Deutsch", "English", "Français", "Español", NULL };
42 char *shortlangnames[] = { "de", "en", "fr", "es", NULL };
43 char **langtrs[] = { de_tr, en_tr, fr_tr, es_tr, NULL };
44 char hdletter;
45 char harddrive[30], sourcedrive[5]; /* Device holder. */
46 struct devparams hdparams, cdromparams; /* Params for CDROM and HD */
47 int rc = 0;
48 char commandstring[STRING_SIZE];
49 char mkfscommand[STRING_SIZE];
50 char *fstypes[] = { "ext2", "ext3", "ReiserFS", NULL };
51 int fstype = REISERFS;
52 int choice;
53 int i;
54 int found = 0;
55 int firstrun = 0;
56 char shortlangname[10];
57 char message[1000];
58 char title[STRING_SIZE];
59 int allok = 0;
60 int allok_fastexit=0;
61 int raid_disk = 0;
62 struct keyvalue *ethernetkv = initkeyvalues();
63 FILE *handle, *cmdfile, *copying;
64 char line[STRING_SIZE];
65 char string[STRING_SIZE];
66 long memory = 0, disk = 0, free;
67 long system_partition, boot_partition, root_partition, swap_file;
68 int scsi_disk = 0;
69 char *yesnoharddisk[3]; // char *yesnoharddisk = { "NO", "YES", NULL };
70
71 int unattended = 0;
72 struct keyvalue *unattendedkv = initkeyvalues();
73 int hardyn = 0;
74 char restore_file[STRING_SIZE] = "";
75
76 setlocale (LC_ALL, "");
77 sethostname( SNAME , 10);
78
79 memset(&hdparams, 0, sizeof(struct devparams));
80 memset(&cdromparams, 0, sizeof(struct devparams));
81
82 /* Log file/terminal stuff. */
83 if (argc >= 2)
84 {
85 if (!(flog = fopen(argv[1], "w+")))
86 return 0;
87 }
88 else
89 return 0;
90
91 mylog = argv[1];
92
93 fprintf(flog, "Install program started.\n");
94
95 newtInit();
96 newtCls();
97
98 newtDrawRootText(14, 0, NAME " " VERSION " - " SLOGAN );
99 sprintf (title, "%s %s - %s", NAME, VERSION, SLOGAN);
100
101 if (! (cmdfile = fopen("/proc/cmdline", "r")))
102 {
103 fprintf(flog, "Couldn't open commandline: /proc/cmdline\n");
104 } else {
105 fgets(line, STRING_SIZE, cmdfile);
106
107 // check if we have to make an unattended install
108 if (strstr (line, "unattended") != NULL) {
109 unattended = 1;
110 runcommandwithstatus("/bin/sleep 10", "WARNING: Unattended installation will start in 10 seconds...");
111 }
112 }
113
114 // Read gpl ...
115 if (! (copying = fopen("/COPYING", "r")))
116 {
117 fprintf(flog, "Couldn't open gpl (/COPYING)\n");
118 sprintf(discl_msg, "Couldn't open gpl (/COPYING)\n");
119 } else {
120 fread(discl_msg, 1, 40000, copying);
121 fclose(copying);
122 }
123
124 // Load common modules
125 mysystem("/sbin/modprobe iso9660"); // CDROM
126 mysystem("/sbin/modprobe ext2"); // Boot patition
127 mysystem("/sbin/modprobe vfat"); // USB key
128
129 /* German is the default */
130 for (choice = 0; langnames[choice]; choice++)
131 {
132 if (strcmp(langnames[choice], "Deutsch") == 0)
133 break;
134 }
135 if (!langnames[choice])
136 goto EXIT;
137
138 if (!unattended) {
139 rc = newtWinMenu("Language selection", "Select the language you wish to use for the " NAME ".", 50, 5, 5, 8,
140 langnames, &choice, "Ok", NULL);
141 }
142
143 ctr = langtrs[choice];
144 strcpy(shortlangname, shortlangnames[choice]);
145
146 newtPushHelpLine(ctr[TR_HELPLINE]);
147
148 sprintf(message, ctr[TR_WELCOME], NAME);
149 newtWinMessage(title, ctr[TR_OK], message);
150
151 if (!unattended) {
152 if (disclaimerbox(discl_msg)==0) {
153 errorbox(ctr[TR_LICENSE_NOT_ACCEPTED]);
154 goto EXIT;
155 }
156 }
157
158 switch (mysystem("/bin/mountsource.sh")) {
159 case 0:
160 break;
161 case 10:
162 errorbox(ctr[TR_NO_CDROM]);
163 goto EXIT;
164 }
165
166 /* read source drive letter */
167 if ((handle = fopen("/tmp/source_device", "r")) == NULL) {
168 errorbox(ctr[TR_ERROR_PROBING_CDROM]);
169 goto EXIT;
170 }
171 fgets(sourcedrive, 5, handle);
172 fprintf(flog, "Source drive: %s\n", sourcedrive);
173 fclose(handle);
174
175 i = 0;
176 while (found == 0) {
177 i++;
178 fprintf(flog, "Harddisk scan pass %i\n", i);
179
180 switch (mysystem("/bin/mountdest.sh") % 255) {
181 case 0: // Found IDE disk
182 scsi_disk = 0;
183 raid_disk = 0;
184 found = 1;
185 break;
186 case 1: // Found SCSI disk
187 scsi_disk = 1;
188 raid_disk = 0;
189 found = 1;
190 break;
191 case 2: // Found RAID disk
192 scsi_disk = 0;
193 raid_disk= 1;
194 found = 1;
195 break;
196 case 10: // No harddisk found
197 if (firstrun == 1) {
198 errorbox(ctr[TR_NO_HARDDISK]);
199 goto EXIT;
200 }
201 // Do this if the kudzu-scan fails...
202 runcommandwithstatus("/bin/probehw.sh deep-scan", ctr[TR_PROBING_HARDWARE]);
203 firstrun = 1;
204 }
205 }
206
207 if ((handle = fopen("/tmp/dest_device", "r")) == NULL) {
208 errorbox(ctr[TR_NO_HARDDISK]);
209 goto EXIT;
210 }
211 fgets(harddrive, 30, handle);
212 fclose(handle);
213
214 /* load unattended configuration */
215 if (unattended) {
216 fprintf(flog, "unattended: Reading unattended.conf\n");
217
218 (void) readkeyvalues(unattendedkv, UNATTENDED_CONF);
219 findkey(unattendedkv, "RESTORE_FILE", restore_file);
220 }
221
222 /* Make the hdparms struct and print the contents.
223 With USB-KEY install and SCSI disk, while installing, the disk
224 is named 'sdb,sdc,...' (following keys)
225 On reboot, it will become 'sda'
226 To avoid many test, all names are built in the struct.
227 */
228 sprintf(hdparams.devnode_disk, "/dev/%s", harddrive);
229 /* Address the partition or raid partition (eg dev/sda or /dev/sdap1 */
230 sprintf(hdparams.devnode_part, "/dev/%s%s", harddrive,raid_disk ? "p" : "");
231 /* Now the names after the machine is booted. Only scsi is affected
232 and we only install on the first scsi disk. */
233
234 fprintf(flog, "Destination drive: %s\n", hdparams.devnode_disk);
235
236 sprintf(message, ctr[TR_PREPARE_HARDDISK], hdparams.devnode_disk);
237 if (unattended) {
238 hardyn = 1;
239 } else {
240 yesnoharddisk[0] = ctr[TR_NO];
241 yesnoharddisk[1] = ctr[TR_YES];
242 yesnoharddisk[2] = NULL;
243 }
244
245 while (! hardyn) {
246 rc = newtWinMenu(title, message,
247 50, 5, 5, 6, yesnoharddisk,
248 &hardyn, ctr[TR_OK],
249 ctr[TR_CANCEL], NULL);
250 if (rc == 2)
251 goto EXIT;
252 }
253 if (rc == 2)
254 goto EXIT;
255
256 if (!unattended) {
257 sprintf(message, ctr[TR_CHOOSE_FILESYSTEM]);
258 rc = newtWinMenu( ctr[TR_CHOOSE_FILESYSTEM], message,
259 50, 5, 5, 6, fstypes, &fstype, ctr[TR_OK],
260 ctr[TR_CANCEL], NULL);
261 } else {
262 rc = 1;
263 fstype = REISERFS;
264 }
265 if (rc == 2)
266 goto EXIT;
267
268 /* Calculate amount of memory in machine */
269 if ((handle = fopen("/proc/meminfo", "r")))
270 {
271 while (fgets(line, STRING_SIZE-1, handle)) {
272 if (sscanf (line, "MemTotal: %s kB", string)) {
273 memory = atoi(string) / 1024 ;
274 }
275 }
276 fclose(handle);
277 }
278
279 /* Partition, mkswp, mkfs.
280 * before partitioning, first determine the sizes of each
281 * partition. In order to do that we need to know the size of
282 * the disk.
283 */
284 /* Don't use mysystem here so we can redirect output */
285 sprintf(commandstring, "/sbin/sfdisk -s /dev/%s > /tmp/disksize 2> /dev/null", harddrive);
286 system(commandstring);
287
288 /* Calculate amount of disk space */
289 if ((handle = fopen("/tmp/disksize", "r"))) {
290 fgets(line, STRING_SIZE-1, handle);
291 if (sscanf (line, "%s", string)) {
292 disk = atoi(string) / 1024;
293 }
294 fclose(handle);
295 }
296
297 fprintf(flog, "Disksize = %ld, memory = %ld", disk, memory);
298
299 /* Calculating Swap-Size dependend of Ram Size */
300 if (memory <= 256)
301 swap_file = 128;
302 else if (memory <= 1024 && memory > 256)
303 swap_file = 256;
304 else
305 swap_file = memory / 4;
306
307 /* Calculating Root-Size dependend of Max Disk Space */
308 if ( disk < 756 )
309 root_partition = 200;
310 else if ( disk >= 756 && disk <= 3072 )
311 root_partition = 512;
312 else
313 root_partition = 2048;
314
315
316 /* Calculating the amount of free space */
317 boot_partition = 20; /* in MB */
318 system_partition = disk - ( root_partition + swap_file + boot_partition );
319
320 fprintf(flog, ", boot = %ld, swap = %ld, mylog = %ld, root = %ld\n",
321 boot_partition, swap_file, system_partition, root_partition);
322 rc = 0;
323
324 if ( (!unattended) && (((disk - (root_partition + swap_file + boot_partition)) < 256 ) && ((disk - (root_partition + boot_partition )) > 256)) ) {
325 rc = newtWinChoice(title, ctr[TR_OK], ctr[TR_CANCEL], ctr[TR_CONTINUE_NO_SWAP]);
326 if (rc == 1){
327 swap_file = 0;
328 system_partition = disk - ( root_partition + swap_file + boot_partition );
329 fprintf(flog, "Changing Swap Size to 0 MB.\n");
330 }
331 else if (rc == 2){
332 fprintf(flog, "Disk is too small.\n");
333 errorbox(ctr[TR_DISK_TOO_SMALL]);goto EXIT;
334 }
335 }
336 else if (disk - (root_partition + swap_file + boot_partition) >= 256) {
337
338 }
339 else {
340 fprintf(flog, "Disk is too small.\n");
341 errorbox(ctr[TR_DISK_TOO_SMALL]);goto EXIT;
342 }
343
344 handle = fopen("/tmp/partitiontable", "w");
345
346 /* Make swapfile */
347 if (swap_file) {
348 fprintf(handle, ",%ld,L,*\n,%ld,S,\n,%ld,L,\n,,L,\n",
349 boot_partition, swap_file, root_partition);
350 } else {
351 fprintf(handle, ",%ld,L,*\n,0,0,\n,%ld,L,\n,,L,\n",
352 boot_partition, root_partition);
353 }
354
355 fclose(handle);
356
357 snprintf(commandstring, STRING_SIZE, "/sbin/sfdisk -L -uM %s < /tmp/partitiontable", hdparams.devnode_disk);
358 if (runcommandwithstatus(commandstring, ctr[TR_PARTITIONING_DISK]))
359 {
360 errorbox(ctr[TR_UNABLE_TO_PARTITION]);
361 goto EXIT;
362 }
363
364 if (fstype == EXT2) {
365 mysystem("/sbin/modprobe ext2");
366 sprintf(mkfscommand, "/sbin/mke2fs -T ext2");
367 } else if (fstype == REISERFS) {
368 mysystem("/sbin/modprobe reiserfs");
369 sprintf(mkfscommand, "/sbin/mkreiserfs -f");
370 } else if (fstype == EXT3) {
371 mysystem("/sbin/modprobe ext3");
372 sprintf(mkfscommand, "/sbin/mke2fs -T ext3");
373 }
374
375 snprintf(commandstring, STRING_SIZE, "/sbin/mke2fs -T ext2 -I 128 %s1", hdparams.devnode_part);
376 if (runcommandwithstatus(commandstring, ctr[TR_MAKING_BOOT_FILESYSTEM]))
377 {
378 errorbox(ctr[TR_UNABLE_TO_MAKE_BOOT_FILESYSTEM]);
379 goto EXIT;
380 }
381
382 if (swap_file) {
383 snprintf(commandstring, STRING_SIZE, "/sbin/mkswap %s2", hdparams.devnode_part);
384 if (runcommandwithstatus(commandstring, ctr[TR_MAKING_SWAPSPACE]))
385 {
386 errorbox(ctr[TR_UNABLE_TO_MAKE_SWAPSPACE]);
387 goto EXIT;
388 }
389 }
390
391 snprintf(commandstring, STRING_SIZE, "%s %s3", mkfscommand, hdparams.devnode_part);
392 if (runcommandwithstatus(commandstring, ctr[TR_MAKING_ROOT_FILESYSTEM]))
393 {
394 errorbox(ctr[TR_UNABLE_TO_MAKE_ROOT_FILESYSTEM]);
395 goto EXIT;
396 }
397
398 snprintf(commandstring, STRING_SIZE, "%s %s4", mkfscommand, hdparams.devnode_part);
399 if (runcommandwithstatus(commandstring, ctr[TR_MAKING_LOG_FILESYSTEM]))
400 {
401 errorbox(ctr[TR_UNABLE_TO_MAKE_LOG_FILESYSTEM]);
402 goto EXIT;
403 }
404
405 snprintf(commandstring, STRING_SIZE, "/bin/mount %s3 /harddisk", hdparams.devnode_part);
406 if (runcommandwithstatus(commandstring, ctr[TR_MOUNTING_ROOT_FILESYSTEM]))
407 {
408 errorbox(ctr[TR_UNABLE_TO_MOUNT_ROOT_FILESYSTEM]);
409 goto EXIT;
410 }
411
412 mkdir("/harddisk/boot", S_IRWXU|S_IRWXG|S_IRWXO);
413 mkdir("/harddisk/var", S_IRWXU|S_IRWXG|S_IRWXO);
414 mkdir("/harddisk/var/log", S_IRWXU|S_IRWXG|S_IRWXO);
415
416 snprintf(commandstring, STRING_SIZE, "/bin/mount %s1 /harddisk/boot", hdparams.devnode_part);
417 if (runcommandwithstatus(commandstring, ctr[TR_MOUNTING_BOOT_FILESYSTEM]))
418 {
419 errorbox(ctr[TR_UNABLE_TO_MOUNT_BOOT_FILESYSTEM]);
420 goto EXIT;
421 }
422 if (swap_file) {
423 snprintf(commandstring, STRING_SIZE, "/sbin/swapon %s2", hdparams.devnode_part);
424 if (runcommandwithstatus(commandstring, ctr[TR_MOUNTING_SWAP_PARTITION]))
425 {
426 errorbox(ctr[TR_UNABLE_TO_MOUNT_SWAP_PARTITION]);
427 goto EXIT;
428 }
429 }
430 snprintf(commandstring, STRING_SIZE, "/bin/mount %s4 /harddisk/var", hdparams.devnode_part);
431 if (runcommandwithstatus(commandstring, ctr[TR_MOUNTING_LOG_FILESYSTEM]))
432 {
433 errorbox(ctr[TR_UNABLE_TO_MOUNT_LOG_FILESYSTEM]);
434 goto EXIT;
435 }
436
437 snprintf(commandstring, STRING_SIZE,
438 "/bin/tar -C /harddisk -xvf /cdrom/" SNAME "-" VERSION ".tlz --lzma 2>/dev/null");
439
440 if (runcommandwithprogress(60, 4, title, commandstring, INST_FILECOUNT,
441 ctr[TR_INSTALLING_FILES]))
442 {
443 errorbox(ctr[TR_UNABLE_TO_INSTALL_FILES]);
444 goto EXIT;
445 }
446
447 /* Save language und local settings */
448 write_lang_configs(shortlangname);
449
450 /* Rename uname */
451 rename ("/harddisk/bin/uname.bak", "/harddisk/bin/uname");
452
453 /* mount proc filesystem */
454 mysystem("mkdir /harddisk/proc");
455 mysystem("/bin/mount --bind /proc /harddisk/proc");
456 mysystem("/bin/mount --bind /dev /harddisk/dev");
457 mysystem("/bin/mount --bind /sys /harddisk/sys");
458
459 /* Build cache lang file */
460 snprintf(commandstring, STRING_SIZE, "/usr/sbin/chroot /harddisk /usr/bin/perl -e \"require '" CONFIG_ROOT "/lang.pl'; &Lang::BuildCacheLang\"");
461 if (runcommandwithstatus(commandstring, ctr[TR_INSTALLING_LANG_CACHE]))
462 {
463 errorbox(ctr[TR_UNABLE_TO_INSTALL_LANG_CACHE]);
464 goto EXIT;
465 }
466
467 /* Update /etc/fstab */
468 snprintf(commandstring, STRING_SIZE, "/bin/sed -i -e \"s#DEVICE1#UUID=$(/sbin/blkid %s1 -sUUID | /usr/bin/cut -d'\"' -f2)#g\" /harddisk/etc/fstab", hdparams.devnode_part);
469 system(commandstring);
470 snprintf(commandstring, STRING_SIZE, "/bin/sed -i -e \"s#DEVICE2#UUID=$(/sbin/blkid %s2 -sUUID | /usr/bin/cut -d'\"' -f2)#g\" /harddisk/etc/fstab", hdparams.devnode_part);
471 system(commandstring);
472 snprintf(commandstring, STRING_SIZE, "/bin/sed -i -e \"s#DEVICE3#UUID=$(/sbin/blkid %s3 -sUUID | /usr/bin/cut -d'\"' -f2)#g\" /harddisk/etc/fstab", hdparams.devnode_part);
473 system(commandstring);
474 snprintf(commandstring, STRING_SIZE, "/bin/sed -i -e \"s#DEVICE4#UUID=$(/sbin/blkid %s4 -sUUID | /usr/bin/cut -d'\"' -f2)#g\" /harddisk/etc/fstab", hdparams.devnode_part);
475 system(commandstring);
476
477 if (fstype == EXT2) {
478 replace("/harddisk/etc/fstab", "FSTYPE", "ext2");
479 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "ro");
480 } else if (fstype == REISERFS) {
481 replace("/harddisk/etc/fstab", "FSTYPE", "reiserfs");
482 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "ro");
483 } else if (fstype == EXT3) {
484 replace("/harddisk/etc/fstab", "FSTYPE", "ext3");
485 NOJOURNAL:
486 replace("/harddisk/boot/grub/grub.conf", "MOUNT", "ro");
487 }
488
489 replace("/harddisk/boot/grub/grub.conf", "KVER", KERNEL_VERSION);
490
491 snprintf(commandstring, STRING_SIZE, "/bin/sed -i -e \"s#root=ROOT#root=UUID=$(/sbin/blkid %s3 -sUUID | /usr/bin/cut -d'\"' -f2)#g\" /harddisk/boot/grub/grub.conf", hdparams.devnode_part);
492 system(commandstring);
493
494 mysystem("ln -s grub.conf /harddisk/boot/grub/menu.lst");
495
496 system("/bin/sed -e 's#/harddisk#/#g' -e 's#//#/#g' < /proc/mounts > /harddisk/etc/mtab");
497
498 snprintf(commandstring, STRING_SIZE,
499 "/usr/sbin/chroot /harddisk /usr/sbin/grub-install --no-floppy %s", hdparams.devnode_disk);
500 if (runcommandwithstatus(commandstring, ctr[TR_INSTALLING_GRUB])) {
501 errorbox(ctr[TR_UNABLE_TO_INSTALL_GRUB]);
502 goto EXIT;
503 }
504
505 /* Copy restore file from cdrom */
506 if (unattended && (strlen(restore_file) > 0)) {
507 fprintf(flog, "unattended: Copy restore file\n");
508 snprintf(commandstring, STRING_SIZE,
509 "cp /cdrom/%s /harddisk/var/ipfire/backup", restore_file);
510 mysystem(commandstring);
511 }
512
513 mysystem("umount /cdrom");
514 snprintf(commandstring, STRING_SIZE, "/usr/bin/eject /dev/%s", sourcedrive);
515 mysystem(commandstring);
516
517 if (!unattended) {
518 sprintf(message, ctr[TR_CONGRATULATIONS_LONG],
519 NAME, SNAME, NAME);
520 newtWinMessage(ctr[TR_CONGRATULATIONS], ctr[TR_OK], message);
521 }
522
523 allok = 1;
524
525 EXIT:
526 fprintf(flog, "Install program ended.\n");
527
528 if (!(allok))
529 newtWinMessage(title, ctr[TR_OK], ctr[TR_PRESS_OK_TO_REBOOT]);
530
531 freekeyvalues(ethernetkv);
532
533 if (allok && !allok_fastexit)
534 {
535 if (unattended) {
536 fprintf(flog, "Entering unattended setup\n");
537 if (unattended_setup(unattendedkv)) {
538 snprintf(commandstring, STRING_SIZE, "/bin/sleep 10");
539 runcommandwithstatus(commandstring, "Unattended installation finished, system will reboot");
540 } else {
541 errorbox("Unattended setup failed.");
542 goto EXIT;
543 }
544 }
545
546 fflush(flog);
547 fclose(flog);
548 newtFinished();
549
550 // if (!unattended) {
551 // if (system("/usr/sbin/chroot /harddisk /usr/local/sbin/setup /dev/tty2 INSTALL"))
552 // printf("Unable to run setup.\n");
553 // }
554
555 if (system("/bin/umount /harddisk/proc"))
556 printf("Unable to umount /harddisk/proc.\n");
557 } else {
558 fflush(flog);
559 fclose(flog);
560 newtFinished();
561 }
562
563 fcloseall();
564
565 if (swap_file) {
566 snprintf(commandstring, STRING_SIZE, "/bin/swapoff %s2", hdparams.devnode_part);
567 }
568
569 newtFinished();
570
571 system("/bin/umount /harddisk/proc");
572 system("/bin/umount /harddisk/dev");
573 system("/bin/umount /harddisk/sys");
574
575 system("/bin/umount /harddisk/var");
576 system("/bin/umount /harddisk/boot");
577 system("/bin/umount /harddisk");
578
579 if (!(allok))
580 system("/etc/halt");
581
582 return 0;
583 }