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