]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blob - src/install+setup/install/install2.c
git-svn-id: http://svn.ipfire.org/svn/ipfire/IPFire/source@16 ea5c0bd1-69bd-2848...
[people/pmueller/ipfire-2.x.git] / src / install+setup / install / install2.c
1 /* IPCop install2 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 * (c) Franck Bourdonnec, 2006
8 * Contains update/restore code
9 *
10 * $Id: install2.c,v 1.1.2.3 2006/01/31 00:51:50 franck78 Exp $
11 *
12 */
13 #include "install.h"
14
15 FILE *flog = NULL;
16 char *mylog;
17 char **ctr;
18
19 /*
20 To include a translated string in the final installer, you must reference
21 it here with a simplr comment. This save a lot a space in the installer
22 */
23
24 /* TR_BUILDING_INITRD */
25 /* TR_HELPLINE */
26 /* TR_SKIP */
27 /* TR_RESTORE_CONFIGURATION */
28 /* TR_RESTORE */
29 /* TR_OK */
30 /* TR_CANCEL */
31 /* TR_ERROR */
32 /* TR_INSTALLING_FILES */
33 /* TR_FAILED_TO_FIND */
34 /* TR_UNABLE_TO_INSTALL_FILES */
35 /* TR_LOADING_PCMCIA */
36
37 //libsmooth
38 /* TR_INTERFACE */
39 /* TR_ENTER_THE_IP_ADDRESS_INFORMATION */
40 /* TR_STATIC */
41 /* TR_DHCP_HOSTNAME */
42 /* TR_IP_ADDRESS_PROMPT */
43 /* TR_NETMASK_PROMPT */
44 /* TR_INVALID_FIELDS */
45 /* TR_IP_ADDRESS_CR */
46 /* TR_NETWORK_MASK_CR */
47 /* TR_DHCP_HOSTNAME_CR */
48 /* TR_LOOKING_FOR_NIC */
49 /* TR_MANUAL */
50 /* TR_SELECT_NETWORK_DRIVER */
51 /* TR_SELECT_NETWORK_DRIVER_LONG */
52 /* TR_UNABLE_TO_LOAD_DRIVER_MODULE */
53 /* TR_THIS_DRIVER_MODULE_IS_ALREADY_LOADED */
54 /* TR_MODULE_PARAMETERS */
55 /* TR_LOADING_MODULE */
56 /* TR_MODULE_NAME_CANNOT_BE_BLANK */
57
58 //upgrade 120
59 /* TR_UNABLE_TO_OPEN_SETTINGS_FILE */
60 /* TR_DOMAINNAME */
61 /* TR_ENTER_DOMAINNAME */
62 /* TR_DOMAINNAME_CANNOT_CONTAIN_SPACES */
63 /* TR_UNABLE_TO_MOUNT_PROC_FILESYSTEM */
64 /* TR_UNABLE_TO_WRITE_ETC_FSTAB */
65
66 // dir to find files, chrooted or not...
67 #define TMP_EXTRACT_CH "/tmp/ipcop"
68 #define TMP_EXTRACT "/harddisk" TMP_EXTRACT_CH
69 #define MOUNT_BACKUP_CH "/mnt/usb"
70 #define MOUNT_BACKUP "/harddisk" MOUNT_BACKUP_CH
71 /*
72 return 0 when dev contains a backup set
73 leave dev mounted
74 */
75 int try_mount (char *dev, char *testfile) {
76 char commandstring[STRING_SIZE];
77 mysystem("/bin/umount " MOUNT_BACKUP);
78 sprintf(commandstring, "/bin/mount -t vfat -o ro %s " MOUNT_BACKUP, dev);
79 mysystem(commandstring);
80
81 /*verify it's what we want */
82 sprintf(commandstring, MOUNT_BACKUP "/%s.dat", testfile);
83 FILE *handle = fopen(commandstring, "r");
84 if (handle == NULL) {
85 return 1; /* bad disk ! */
86 }
87 fclose(handle);
88
89 handle = fopen(MOUNT_BACKUP "/backup.key", "r");
90 if (handle == NULL) {
91 return 1; /* bad disk ! */
92 }
93 fclose(handle);
94 return 0; //success
95 }
96
97 /* try to mount usb device until backup.tgz is found except the
98 destination device (scsi names are identical with usb key)
99 check "sda sdb sdc sdd"
100 */
101 int mountbackup (char *testfile, char *destination_device) {
102 char sourcedev[30];
103 char i,j;
104 for (i = 'a'; i < 'e'; i++) {
105 sprintf (sourcedev,"/dev/sd%c ",i);
106 if (strcmp (destination_device, sourcedev) != 0) {
107 if (!try_mount (sourcedev, testfile)) return 0;
108 }
109 for (j = '1'; j < '5'; j++) {
110 sourcedev[8] = j;
111 if (strcmp (destination_device, sourcedev) != 0) {
112 if (!try_mount (sourcedev, testfile)) return 0;
113 }
114 }
115 }
116 return 1;
117 }
118
119 int floppy_locate() {
120 /* Temporarily mount /proc under /harddisk/proc,
121 run updfstab to locate the floppy, and unmount /harddisk/proc
122 again. This should be run each time the user tries to restore
123 so it can properly detect removable devices */
124 if (mysystem("/bin/mount -n -t proc /proc /harddisk/proc")) {
125 errorbox(ctr[TR_UNABLE_TO_MOUNT_PROC_FILESYSTEM]);
126 return 1;
127 }
128 if (mysystem("/bin/chroot /harddisk /usr/sbin/updfstab")) {
129 errorbox(ctr[TR_UNABLE_TO_WRITE_ETC_FSTAB]);
130 return 1;
131 }
132 mysystem("/bin/umount /harddisk/proc");
133 return 0;
134 }
135
136 /* Check the SQUID acl file exists, if not use our 1.4 copy */
137 void fixup_squidacl() {
138 FILE *aclreadfile;
139 if ((aclreadfile = fopen ("/harddisk" CONFIG_ROOT "/proxy/acl", "r"))) {
140 unlink ("/harddisk" CONFIG_ROOT "/proxy/acl-1.4");
141 fclose(aclreadfile);
142 } else {
143 rename ("/harddisk" CONFIG_ROOT "/proxy/acl-1.4",
144 "/harddisk" CONFIG_ROOT "/proxy/acl");
145 }
146 chown ("/harddisk" CONFIG_ROOT "/proxy/acl", 99, 99);
147 }
148 /* if we detected SCSI then fixup */
149 void fixup_initrd() {
150 FILE *handle;
151 char line[STRING_SIZE];
152 char commandstring[STRING_SIZE];
153
154 if (!(handle = fopen("/scsidriver", "r")))
155 return;
156
157 char *driver;
158 fgets(line, STRING_SIZE-1, handle);
159 fclose(handle);
160 line[strlen(line) - 1] = 0;
161 driver = strtok(line, ".");
162 fprintf(flog, "Detected SCSI driver %s\n", driver);
163 if (!strlen(driver) > 1)
164 return;
165
166 fprintf(flog, "Fixing up ipcoprd.img\n");
167 mysystem("/bin/chroot /harddisk /sbin/modprobe loop");
168 mkdir("/harddisk/initrd", S_IRWXU|S_IRWXG|S_IRWXO);
169 sprintf(commandstring, "/bin/chroot /harddisk /sbin/mkinitrd"
170 " --with=scsi_mod --with=%s --with=sd_mod"
171 " --with=sr_mod --with=libata"
172 " --with=ataraid /boot/ipcoprd.img "KERNEL_VERSION,
173 driver );
174 runcommandwithstatus(commandstring, ctr[TR_BUILDING_INITRD]);
175 #ifdef __i386__
176 sprintf(commandstring, "/bin/chroot /harddisk /sbin/mkinitrd"
177 " --with=scsi_mod --with=%s --with=sd_mod"
178 " --with=sr_mod --with=libata"
179 " --with=ataraid /boot/ipcoprd-smp.img "KERNEL_VERSION"-smp",
180 driver );
181 runcommandwithstatus(commandstring, ctr[TR_BUILDING_INITRD]);
182 mysystem("/bin/chroot /harddisk /bin/mv /boot/grub/scsigrub.conf /boot/grub/grub.conf");
183 #endif
184 #ifdef __alpha__
185 runcommandwithstatus("/bin/chroot /harddisk /bin/mv /boot/etc/scsiaboot.conf /boot/etc/aboot.conf", ctr[TR_BUILDING_INITRD]);
186 #endif
187 }
188 /* when backup is ready in tmpdir, move files to definitive location */
189 void do_copy_files(int upgrade_level) {
190 mysystem("/bin/chroot /harddisk /bin/cp -af "TMP_EXTRACT_CH"/. /");
191 /* Upgrade necessary files from v1.2 to v1.3 to v1.4 */
192 switch (upgrade_level) {
193 case 1:
194 upgrade_v12_v13();
195 upgrade_v130_v140();
196 case 2: //some 1.4 files format changed
197 //between 1.4.0 & 1.4.11 If possible de determine backup/version
198 //the update code should go here
199 }
200 }
201
202 int main(int argc, char *argv[]) {
203 #define LANG argv[1]
204 #define DEST_DEV argv[2]
205 #define WGET argv[3]
206
207 #ifdef LANG_EN_ONLY
208 char **langtrs[] = { en_tr, NULL };
209 #else
210 char **langtrs[] = { bz_tr, cs_tr, da_tr, de_tr, en_tr, es_tr, fr_tr, el_tr, it_tr, la_tr, hu_tr, nl_tr, no_tr, pl_tr, pt_tr, sk_tr, so_tr, fi_tr, sv_tr, tr_tr, vi_tr, NULL };
211 #endif
212 char message[1000];
213 char title[STRING_SIZE];
214 char commandstring[STRING_SIZE];
215
216 setlocale (LC_ALL, "");
217 /* Log file/terminal stuff. */
218 mylog = "/dev/tty2";
219 ctr = langtrs[ atoi(LANG) ];
220
221 if (!(flog = fopen(mylog, "w+")))
222 {
223 printf("Couldn't open log terminal\n");
224 return 0;
225 }
226 fprintf(flog, "Install2 program started.\n");
227 newtInit();
228 newtCls();
229 strcpy (title, NAME " v" VERSION " - " SLOGAN);
230 newtDrawRootText(14, 0, title);
231 newtPushHelpLine(ctr[TR_HELPLINE]);
232 /*
233 // build now the device node
234 runcommandwithstatus("echo 'cd /dev; ./make_devices'>/harddisk/X;"
235 "chroot /harddisk chmod +x /X;"
236 "chroot /harddisk /X;"
237 "chroot /harddisk rm /X"
238 , ctr[TR_INSTALLING_FILES]);
239 */
240 /* working dirs... */
241 mkdir(MOUNT_BACKUP, S_IRWXU|S_IRWXG|S_IRWXO);
242
243 //create the GUI screen and objects
244 newtComponent form, header, labelfile, labelkey, file, key, radio0, radio1, radio2, radio3, radio4, ok;
245
246 newtCenteredWindow (55,20,ctr[TR_RESTORE]);
247 form = newtForm (NULL, NULL,0);
248
249 sprintf(message, ctr[TR_RESTORE_CONFIGURATION], NAME);
250 header = newtTextboxReflowed (2,1,message,51,0,0,0);
251 newtFormAddComponent(form, header);
252
253 // The four method of restauration
254 int start1=1, start2=0, start3=0, start4=0;
255 radio1 = newtRadiobutton (17, 5, ctr[TR_SKIP], start1, NULL);
256 radio2 = newtRadiobutton (17, 6, "Floppy (legacy)", start2, radio1);
257 radio3 = newtRadiobutton (17, 7, "Usb-storage/CDROM", start3, radio2);
258 if (strcmp(WGET,"none"))
259 radio4 = newtRadiobutton (17, 8, "HTTP/FTP", start4, radio3);
260 else
261 radio4 = NULL;
262 newtFormAddComponents(form, radio1, radio2, radio3, radio4, NULL);
263
264 // The optionnal filename for 'backup'
265 labelfile=newtTextbox(12, 10, 35, 1, 0);
266 newtTextboxSetText (labelfile, "Filename");
267 newtFormAddComponent(form, labelfile);
268 char *filevalue;
269 char fileinit[STRING_SIZE] = "backup";
270 file = newtEntry (17, 11, fileinit, 20, &filevalue, 0);
271 newtFormAddComponent(form, file);
272
273 // The optionnal password for the key
274 labelkey=newtTextbox(12, 13, 35, 1, 0);
275 newtTextboxSetText (labelkey, "Backup key password");
276 newtFormAddComponent(form, labelkey);
277 char *keyvalue;
278 char keyinit[STRING_SIZE] = "";
279 key = newtEntry (17, 14, keyinit, 20, &keyvalue, 0);
280 newtFormAddComponent(form, key);
281
282 // The OK button
283 ok=newtButton (23, 16, ctr[TR_OK]);
284 newtFormAddComponent(form, ok);
285
286 /* loop until succeeds or user skips out */
287 int retcode = -1;
288 while ( retcode<0 ) {
289
290 // run the windows
291 struct newtExitStruct reponse;
292 newtFormRun (form, &reponse);
293 radio0 = newtRadioGetCurrent(radio1);
294 int radio;
295 radio = radio0 == radio1 ? 1 : radio0 == radio2 ? 2 : radio0 == radio3 ? 3 : radio0 == radio4 ? 4 : 0;
296 strcpy(keyinit,keyvalue); //reuse actual value
297 strcpy(fileinit,filevalue);
298
299 if (radio==1) {
300 retcode = 1; // no restore: nothing special
301 break; // out of the while loop
302 }
303
304 mkdir(TMP_EXTRACT, S_IRWXU|S_IRWXG|S_IRWXO);
305 statuswindow(45, 4, title, ctr[TR_INSTALLING_FILES]);
306 switch (radio) {
307 case 4: // network
308 sprintf(commandstring,"/bin/wget -P " TMP_EXTRACT " %s/%s.dat", WGET, filevalue);
309 mysystem (commandstring);
310 sprintf(commandstring,"/bin/wget -P " TMP_EXTRACT " %s/%s.key", WGET, filevalue);
311 if (mysystem (commandstring)) {
312 errorbox(ctr[TR_FAILED_TO_FIND]);
313 break;
314 };
315 goto COMMON;
316 case 3: // normal backup
317 if (mountbackup( filevalue, DEST_DEV )) {
318 errorbox(ctr[TR_UNABLE_TO_INSTALL_FILES]);//mess=no device with backup found
319 break;
320 };
321 // link files to a COMMON location
322 sprintf (commandstring, "chroot /harddisk ln -s "MOUNT_BACKUP_CH"/%s.dat " TMP_EXTRACT_CH "/%s.dat", filevalue, filevalue);
323 mysystem (commandstring);
324 sprintf (commandstring, "chroot /harddisk ln -s "MOUNT_BACKUP_CH"/%s.key " TMP_EXTRACT_CH "/%s.key", filevalue, filevalue);
325 mysystem (commandstring);
326
327 COMMON: // DECRYPT THE TARBALL
328 // Copy the key to a new location because we decrypt it!
329 if (strcmp(keyvalue, "")) { // password provided: decrypt the key
330 sprintf(commandstring, "/bin/chroot /harddisk /usr/bin/openssl enc"
331 " -a -d -aes256 -salt"
332 " -pass pass:%s"
333 " -in " TMP_EXTRACT_CH "/%s.key"
334 " -out " TMP_EXTRACT_CH "/__tmp.key",
335 keyvalue, filevalue);
336 } else { //just copy to new name
337 sprintf(commandstring, "/bin/chroot /harddisk cp"
338 " " TMP_EXTRACT_CH "/%s.key"
339 " " TMP_EXTRACT_CH "/__tmp.key",
340 filevalue);
341 }
342 mysystem (commandstring);
343
344 sprintf(commandstring, "/bin/chroot /harddisk /usr/bin/openssl des3"
345 " -d -salt"
346 " -in " TMP_EXTRACT_CH "/%s.dat"
347 " -out " TMP_EXTRACT_CH "/backup.tgz"
348 " -kfile " TMP_EXTRACT_CH "/__tmp.key",
349 filevalue);
350
351 if (mysystem (commandstring)) {
352 errorbox(ctr[TR_UNABLE_TO_INSTALL_FILES]);//mess=decrypt error:invalid key?
353 break;
354 }
355 strcpy(commandstring, "/bin/chroot /harddisk /bin/tar"
356 " -X " CONFIG_ROOT "/backup/exclude.system"
357 " -C " TMP_EXTRACT_CH
358 " -xzf " TMP_EXTRACT_CH "/backup.tgz");
359
360 if (mysystem(commandstring)) {
361 errorbox(ctr[TR_UNABLE_TO_INSTALL_FILES]);
362 break;
363 }
364 sprintf(commandstring, TMP_EXTRACT "/%s.dat", filevalue);
365 unlink(commandstring ); //dont need them anymore
366 unlink( TMP_EXTRACT "/backup.tgz");
367 sprintf(commandstring, TMP_EXTRACT "/%s.key", filevalue);
368 unlink(commandstring );
369 unlink( TMP_EXTRACT "/__tmp.key");
370
371 /* Now copy to correct location */
372 do_copy_files(0);
373 retcode = 0; /* successfully restored */
374 break;
375 case 2:
376 // diskette change
377 if (floppy_locate()) {
378 retcode = 2; // this an error!
379 break;
380 }
381
382 /* Always extract to /tmp/ipcop for temporary extraction
383 just in case floppy fails.
384 try a compressed backup first because it's quicker to fail.
385 In exclude.system, files name must be without leading / or
386 on extraction, name will never match
387 */
388 sprintf(commandstring,
389 "/bin/chroot /harddisk /bin/tar -X " CONFIG_ROOT "/backup/exclude.system -C "TMP_EXTRACT_CH" -xvzf /dev/floppy > %s 2> /dev/null", mylog);
390 if (system(commandstring)) {
391 /* if it's not compressed, try uncompressed first before failing*/
392 sprintf(commandstring,
393 "/bin/chroot /harddisk /bin/tar -X " CONFIG_ROOT "/backup/exclude.system -C "TMP_EXTRACT_CH" -xvf /dev/floppy > %s 2> /dev/null", mylog);
394 if (system(commandstring)) {
395 /* command failed trying to read from floppy */
396 errorbox(ctr[TR_UNABLE_TO_INSTALL_FILES]);
397 break;
398 }
399 }
400 /* Now copy to correct location */
401 do_copy_files(1);
402 retcode = 0; /* successfully restored */
403 }//switch
404 /* remove possible badly restored files */
405 mysystem("/bin/chroot /harddisk /bin/rm -rf " TMP_EXTRACT_CH );
406 newtPopWindow(); // close windows
407 }//while
408 newtFormDestroy(form);
409
410 /* cleanup */
411 mysystem("/bin/umount " MOUNT_BACKUP);
412 mysystem("/bin/chroot /harddisk /bin/rmdir " MOUNT_BACKUP_CH);
413
414 /* others operations moved from install to install2 */
415 fixup_squidacl();
416 fixup_initrd();
417
418 fprintf(flog, "Install2 program ended.\n");
419 fflush(flog);
420 fclose(flog);
421 newtFinished();
422 return retcode;
423 }
424