]>
Commit | Line | Data |
---|---|---|
d6aaa55d MT |
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.5 2006/02/10 06:53:57 gespinasse 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() { | |
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 | upgrade_v12_v13(); | |
193 | upgrade_v130_v140(); | |
194 | /* Upgrade configuration files starting from 1.4.11 */ | |
195 | mysystem("/bin/chroot /harddisk /usr/local/bin/upgrade"); | |
196 | } | |
197 | ||
198 | int main(int argc, char *argv[]) { | |
199 | #define LANG argv[1] | |
200 | #define DEST_DEV argv[2] | |
201 | #define WGET argv[3] | |
202 | ||
203 | #ifdef LANG_EN_ONLY | |
204 | char **langtrs[] = { en_tr, NULL }; | |
205 | #else | |
206 | 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 }; | |
207 | #endif | |
208 | char message[1000]; | |
209 | char title[STRING_SIZE]; | |
210 | char commandstring[STRING_SIZE]; | |
211 | ||
212 | setlocale (LC_ALL, ""); | |
213 | /* Log file/terminal stuff. */ | |
214 | mylog = "/dev/tty2"; | |
215 | ctr = langtrs[ atoi(LANG) ]; | |
216 | ||
217 | if (!(flog = fopen(mylog, "w+"))) | |
218 | { | |
219 | printf("Couldn't open log terminal\n"); | |
220 | return 0; | |
221 | } | |
222 | fprintf(flog, "Install2 program started.\n"); | |
223 | newtInit(); | |
224 | newtCls(); | |
225 | strcpy (title, NAME " v" VERSION " - " SLOGAN); | |
226 | newtDrawRootText(14, 0, title); | |
227 | newtPushHelpLine(ctr[TR_HELPLINE]); | |
228 | ||
229 | /* working dirs... */ | |
230 | mkdir(MOUNT_BACKUP, S_IRWXU|S_IRWXG|S_IRWXO); | |
231 | ||
232 | //create the GUI screen and objects | |
233 | newtComponent form, header, labelfile, labelkey, file, key, radio0, radio1, radio2, radio3, radio4, ok; | |
234 | ||
235 | newtCenteredWindow (55,20,ctr[TR_RESTORE]); | |
236 | form = newtForm (NULL, NULL,0); | |
237 | ||
238 | sprintf(message, ctr[TR_RESTORE_CONFIGURATION], NAME); | |
239 | header = newtTextboxReflowed (2,1,message,51,0,0,0); | |
240 | newtFormAddComponent(form, header); | |
241 | ||
242 | // The four method of restauration | |
243 | int start1=1, start2=0, start3=0, start4=0; | |
244 | radio1 = newtRadiobutton (17, 5, ctr[TR_SKIP], start1, NULL); | |
245 | radio2 = newtRadiobutton (17, 6, "Floppy (legacy)", start2, radio1); | |
246 | radio3 = newtRadiobutton (17, 7, "Usb-storage/CDROM", start3, radio2); | |
247 | if (strcmp(WGET,"none")) | |
248 | radio4 = newtRadiobutton (17, 8, "HTTP/FTP", start4, radio3); | |
249 | else | |
250 | radio4 = NULL; | |
251 | newtFormAddComponents(form, radio1, radio2, radio3, radio4, NULL); | |
252 | ||
253 | // The optionnal filename for 'backup' | |
254 | labelfile=newtTextbox(12, 10, 35, 1, 0); | |
255 | newtTextboxSetText (labelfile, "Filename"); | |
256 | newtFormAddComponent(form, labelfile); | |
257 | char *filevalue; | |
258 | char fileinit[STRING_SIZE] = "backup"; | |
259 | file = newtEntry (17, 11, fileinit, 20, &filevalue, 0); | |
260 | newtFormAddComponent(form, file); | |
261 | ||
262 | // The optionnal password for the key | |
263 | labelkey=newtTextbox(12, 13, 35, 1, 0); | |
264 | newtTextboxSetText (labelkey, "Backup key password"); | |
265 | newtFormAddComponent(form, labelkey); | |
266 | char *keyvalue; | |
267 | char keyinit[STRING_SIZE] = ""; | |
268 | key = newtEntry (17, 14, keyinit, 20, &keyvalue, 0); | |
269 | newtFormAddComponent(form, key); | |
270 | ||
271 | // The OK button | |
272 | ok=newtButton (23, 16, ctr[TR_OK]); | |
273 | newtFormAddComponent(form, ok); | |
274 | ||
275 | /* loop until succeeds or user skips out */ | |
276 | int retcode = -1; | |
277 | while ( retcode<0 ) { | |
278 | ||
279 | // run the windows | |
280 | struct newtExitStruct reponse; | |
281 | newtFormRun (form, &reponse); | |
282 | radio0 = newtRadioGetCurrent(radio1); | |
283 | int radio; | |
284 | radio = radio0 == radio1 ? 1 : radio0 == radio2 ? 2 : radio0 == radio3 ? 3 : radio0 == radio4 ? 4 : 0; | |
285 | strcpy(keyinit,keyvalue); //reuse actual value | |
286 | strcpy(fileinit,filevalue); | |
287 | ||
288 | if (radio==1) { | |
289 | retcode = 1; // no restore: nothing special | |
290 | break; // out of the while loop | |
291 | } | |
292 | ||
293 | mkdir(TMP_EXTRACT, S_IRWXU|S_IRWXG|S_IRWXO); | |
294 | statuswindow(45, 4, title, ctr[TR_INSTALLING_FILES]); | |
295 | switch (radio) { | |
296 | case 4: // network | |
297 | sprintf(commandstring,"/bin/wget -P " TMP_EXTRACT " %s/%s.dat", WGET, filevalue); | |
298 | mysystem (commandstring); | |
299 | sprintf(commandstring,"/bin/wget -P " TMP_EXTRACT " %s/%s.key", WGET, filevalue); | |
300 | if (mysystem (commandstring)) { | |
301 | errorbox(ctr[TR_FAILED_TO_FIND]); | |
302 | break; | |
303 | }; | |
304 | goto COMMON; | |
305 | case 3: // normal backup | |
306 | if (mountbackup( filevalue, DEST_DEV )) { | |
307 | errorbox(ctr[TR_UNABLE_TO_INSTALL_FILES]);//mess=no device with backup found | |
308 | break; | |
309 | }; | |
310 | // link files to a COMMON location | |
311 | sprintf (commandstring, "chroot /harddisk ln -s "MOUNT_BACKUP_CH"/%s.dat " TMP_EXTRACT_CH "/%s.dat", filevalue, filevalue); | |
312 | mysystem (commandstring); | |
313 | sprintf (commandstring, "chroot /harddisk ln -s "MOUNT_BACKUP_CH"/%s.key " TMP_EXTRACT_CH "/%s.key", filevalue, filevalue); | |
314 | mysystem (commandstring); | |
315 | ||
316 | COMMON: // DECRYPT THE TARBALL | |
317 | // Copy the key to a new location because we decrypt it! | |
318 | if (strcmp(keyvalue, "")) { // password provided: decrypt the key | |
319 | sprintf(commandstring, "/bin/chroot /harddisk /usr/bin/openssl enc" | |
320 | " -a -d -aes256 -salt" | |
321 | " -pass pass:%s" | |
322 | " -in " TMP_EXTRACT_CH "/%s.key" | |
323 | " -out " TMP_EXTRACT_CH "/__tmp.key", | |
324 | keyvalue, filevalue); | |
325 | } else { //just copy to new name | |
326 | sprintf(commandstring, "/bin/chroot /harddisk cp" | |
327 | " " TMP_EXTRACT_CH "/%s.key" | |
328 | " " TMP_EXTRACT_CH "/__tmp.key", | |
329 | filevalue); | |
330 | } | |
331 | mysystem (commandstring); | |
332 | ||
333 | sprintf(commandstring, "/bin/chroot /harddisk /usr/bin/openssl des3" | |
334 | " -d -salt" | |
335 | " -in " TMP_EXTRACT_CH "/%s.dat" | |
336 | " -out " TMP_EXTRACT_CH "/backup.tgz" | |
337 | " -kfile " TMP_EXTRACT_CH "/__tmp.key", | |
338 | filevalue); | |
339 | ||
340 | if (mysystem (commandstring)) { | |
341 | errorbox(ctr[TR_UNABLE_TO_INSTALL_FILES]);//mess=decrypt error:invalid key? | |
342 | break; | |
343 | } | |
344 | strcpy(commandstring, "/bin/chroot /harddisk /bin/tar" | |
345 | " -X " CONFIG_ROOT "/backup/exclude.system" | |
346 | " -C " TMP_EXTRACT_CH | |
347 | " -xzf " TMP_EXTRACT_CH "/backup.tgz"); | |
348 | ||
349 | if (mysystem(commandstring)) { | |
350 | errorbox(ctr[TR_UNABLE_TO_INSTALL_FILES]); | |
351 | break; | |
352 | } | |
353 | sprintf(commandstring, TMP_EXTRACT "/%s.dat", filevalue); | |
354 | unlink(commandstring ); //dont need them anymore | |
355 | unlink( TMP_EXTRACT "/backup.tgz"); | |
356 | sprintf(commandstring, TMP_EXTRACT "/%s.key", filevalue); | |
357 | unlink(commandstring ); | |
358 | unlink( TMP_EXTRACT "/__tmp.key"); | |
359 | ||
360 | /* Now copy to correct location */ | |
361 | do_copy_files(); | |
362 | retcode = 0; /* successfully restored */ | |
363 | break; | |
364 | case 2: | |
365 | // diskette change | |
366 | if (floppy_locate()) { | |
367 | retcode = 2; // this an error! | |
368 | break; | |
369 | } | |
370 | ||
371 | /* Always extract to /tmp/ipcop for temporary extraction | |
372 | just in case floppy fails. | |
373 | try a compressed backup first because it's quicker to fail. | |
374 | In exclude.system, files name must be without leading / or | |
375 | on extraction, name will never match | |
376 | */ | |
377 | sprintf(commandstring, | |
378 | "/bin/chroot /harddisk /bin/tar -X " CONFIG_ROOT "/backup/exclude.system -C "TMP_EXTRACT_CH" -xvzf /dev/floppy > %s 2> /dev/null", mylog); | |
379 | if (system(commandstring)) { | |
380 | /* if it's not compressed, try uncompressed first before failing*/ | |
381 | sprintf(commandstring, | |
382 | "/bin/chroot /harddisk /bin/tar -X " CONFIG_ROOT "/backup/exclude.system -C "TMP_EXTRACT_CH" -xvf /dev/floppy > %s 2> /dev/null", mylog); | |
383 | if (system(commandstring)) { | |
384 | /* command failed trying to read from floppy */ | |
385 | errorbox(ctr[TR_UNABLE_TO_INSTALL_FILES]); | |
386 | break; | |
387 | } | |
388 | } | |
389 | /* Now copy to correct location */ | |
390 | do_copy_files(); | |
391 | retcode = 0; /* successfully restored */ | |
392 | }//switch | |
393 | /* remove possible badly restored files */ | |
394 | mysystem("/bin/chroot /harddisk /bin/rm -rf " TMP_EXTRACT_CH ); | |
395 | newtPopWindow(); // close windows | |
396 | }//while | |
397 | newtFormDestroy(form); | |
398 | ||
399 | /* cleanup */ | |
400 | mysystem("/bin/umount " MOUNT_BACKUP); | |
401 | mysystem("/bin/chroot /harddisk /bin/rmdir " MOUNT_BACKUP_CH); | |
402 | ||
403 | /* others operations moved from install to install2 */ | |
404 | fixup_squidacl(); | |
405 | fixup_initrd(); | |
406 | ||
407 | fprintf(flog, "Install2 program ended.\n"); | |
408 | fflush(flog); | |
409 | fclose(flog); | |
410 | newtFinished(); | |
411 | return retcode; | |
412 | } | |
413 |