Changeset 3877 in MondoRescue for branches/3.3/mondo/src
- Timestamp:
- Mar 8, 2024, 3:59:07 AM (4 months ago)
- Location:
- branches/3.3/mondo/src/common
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/3.3/mondo/src/common/libmondo-archive.c
r3875 r3877 318 318 319 319 320 321 322 /** 323 * Finalize the backup. 324 * For streaming backups, this writes the closing block 325 * to the stream. For CD-based backups, this creates 326 * the final ISO image. 327 * @param bkpinfo The backup information structure, used only 328 * for the @c backup_media_type. 329 * @ingroup MLarchiveGroup 330 */ 331 int do_that_final_phase() 332 { 333 334 /*@ int ************************************** */ 335 int res = 0; 336 int retval = 0; 337 338 /*@ buffers ********************************** */ 339 340 assert(bkpinfo != NULL); 341 mvaddstr_and_log_it(g_currentY, 0, 342 "Writing any remaining data to media "); 343 344 log_msg(1, "Closing tape/CD/USB ... "); 345 if (IS_THIS_A_STREAMING_BACKUP(bkpinfo->backup_media_type)) { 346 /* write tape/cdstream */ 347 closeout_tape(); 348 } else { 349 /* write final ISO/USB */ 350 res = write_final_iso_if_necessary(); 351 retval += res; 352 if (res) { 353 log_msg(1, "write_final_iso_if_necessary returned an error"); 354 } 355 } 356 log_msg(2, "Fork is exiting ... "); 357 358 mvaddstr_and_log_it(g_currentY++, 74, "Done."); 359 360 /* final stuff */ 361 if (retval) { 362 mvaddstr_and_log_it(g_currentY++, 74, "Errors."); 363 } else { 364 mvaddstr_and_log_it(g_currentY++, 74, "Done."); 365 } 366 367 return (retval); 368 } 369 370 /** 371 * Wrapper around @c make_slices_and_images(). 372 * @param bkpinfo The backup information structure. Fields used: 373 * - @c backup_media_type 374 * - @c scratchdir 375 * - @c tmpdir 376 * @return The number of errors encountered (0 for success) 377 * @ingroup MLarchiveGroup 378 */ 379 int make_those_slices_phase() 380 { 381 382 /*@ int ***************************************************** */ 383 int res = 0; 384 int retval = 0; 385 386 /*@ buffers ************************************************** */ 387 char *biggielist = NULL; 388 char *command = NULL; 389 char *blah = NULL; 390 char *xattr_fname = NULL; 391 char *acl_fname = NULL; 392 393 assert(bkpinfo != NULL); 394 /* slice big files */ 395 mvaddstr_and_log_it(g_currentY, 0, "Archiving large files to media "); 396 mr_asprintf(biggielist, "%s/archives/biggielist.txt", bkpinfo->scratchdir); 397 if (g_getfattr) { 398 mr_asprintf(xattr_fname, XATTR_BIGGLST_FNAME_RAW_SZ, bkpinfo->tmpdir); 399 } 400 if (g_getfacl) { 401 mr_asprintf(acl_fname, ACL_BIGGLST_FNAME_RAW_SZ, bkpinfo->tmpdir); 402 } 403 404 mr_asprintf(command, "cp %s/biggielist.txt %s", bkpinfo->tmpdir, biggielist); 405 paranoid_system(command); 406 mr_free(command); 407 408 mr_asprintf(blah, "biggielist = %s", biggielist); 409 log_msg(2, blah); 410 mr_free(blah); 411 412 if (!does_file_exist(biggielist)) { 413 log_msg(1, "BTW, the biggielist does not exist"); 414 } 415 416 if (g_getfattr) { 417 get_fattr_list(biggielist, xattr_fname); 418 mr_asprintf(command, "cp %s %s/archives/", xattr_fname, bkpinfo->scratchdir); 419 paranoid_system(command); 420 mr_free(command); 421 } 422 if (g_getfacl) { 423 get_acl_list(biggielist, acl_fname); 424 mr_asprintf(command, "cp %s %s/archives/", acl_fname, bkpinfo->scratchdir); 425 paranoid_system(command); 426 mr_free(command); 427 } 428 429 if (IS_THIS_A_STREAMING_BACKUP(bkpinfo->backup_media_type)) { 430 res += write_EXAT_files_to_tape(xattr_fname, acl_fname); 431 mr_asprintf(blah, "%ld", count_lines_in_file(biggielist)); 432 write_header_block_to_stream((off_t)0, blah, BLK_START_BIGGIEFILES); 433 mr_free(blah); 434 } 435 res = make_slices_and_images(biggielist); 436 if (IS_THIS_A_STREAMING_BACKUP(bkpinfo->backup_media_type)) { 437 write_header_block_to_stream((off_t)0, "end-of-biggiefiles", BLK_STOP_BIGGIEFILES); 438 } 439 retval += res; 440 if (res) { 441 log_msg(1, "make_slices_and_images returned an error"); 442 mvaddstr_and_log_it(g_currentY++, 74, "Errors."); 443 } else { 444 mvaddstr_and_log_it(g_currentY++, 74, "Done."); 445 } 446 mr_free(biggielist); 447 mr_free(xattr_fname); 448 mr_free(acl_fname); 449 return (retval); 450 } 451 452 453 454 /** 455 * Wrapper around @c make_afioballs_and_images(). 456 * @param bkpinfo the backup information structure. Only the 457 * @c backup_media_type field is used within this function. 458 * @return return code of make_afioballs_and_images 459 * @see make_afioballs_and_images 460 * @ingroup MLarchiveGroup 461 */ 462 int make_those_afios_phase() 463 { 464 /*@ int ******************************************* */ 465 int res = 0; 466 int retval = 0; 467 468 assert(bkpinfo != NULL); 469 470 mvaddstr_and_log_it(g_currentY, 0, "Archiving regular files to media "); 471 472 if (IS_THIS_A_STREAMING_BACKUP(bkpinfo->backup_media_type)) { 473 write_header_block_to_stream((off_t)0, "start-of-afioballs", BLK_START_AFIOBALLS); 474 #if __FreeBSD__ == 5 475 log_msg(1, "Using single-threaded make_afioballs_and_images() to suit b0rken FreeBSD 5.0"); 476 res = make_afioballs_and_images_OLD(); 477 #else 478 res = make_afioballs_and_images_OLD(); 479 #endif 480 write_header_block_to_stream((off_t)0, "stop-afioballs", BLK_STOP_AFIOBALLS); 481 } else { 482 res = make_afioballs_and_images(); 483 } 484 485 retval += res; 486 if (res) { 487 mvaddstr_and_log_it(g_currentY++, 74, "Errors."); 488 log_msg(1, "make_afioballs_and_images returned an error"); 489 } else { 490 mvaddstr_and_log_it(g_currentY++, 74, "Done."); 491 } 492 return (retval); 493 } 320 494 321 495 … … 890 1064 891 1065 1066 /** 1067 * Set the <tt>N</tt>th bit of @c array to @c true_or_false. 1068 * @param array The bit array (as a @c char pointer). 1069 * @param N The bit number to set or reset. 1070 * @param true_or_false If TRUE then set bit @c N, if FALSE then reset bit @c N. 1071 * @see get_bit_N_of_array 1072 */ 1073 void set_bit_N_of_array(char *array, int N, bool true_or_false) 1074 { 1075 int bit_number; 1076 int mask, orig_val, to_add; 1077 int element_number; 1078 1079 assert(array != NULL); 1080 1081 element_number = N / 8; 1082 bit_number = N % 8; 1083 to_add = (1 << bit_number); 1084 mask = 255 - to_add; 1085 orig_val = array[element_number] & mask; 1086 // log_it("array[%d]=%02x; %02x&%02x = %02x", element_number, array[element_number], mask, orig_val); 1087 if (true_or_false) { 1088 array[element_number] = orig_val | to_add; 1089 } 1090 } 1091 1092 892 1093 893 1094 /** … … 1051 1252 1052 1253 1053 1054 1055 1056 /** 1057 * Finalize the backup. 1058 * For streaming backups, this writes the closing block 1059 * to the stream. For CD-based backups, this creates 1060 * the final ISO image. 1061 * @param bkpinfo The backup information structure, used only 1062 * for the @c backup_media_type. 1063 * @ingroup MLarchiveGroup 1064 */ 1065 int do_that_final_phase() 1254 /** 1255 * Write the final ISO image. 1256 * @param bkpinfo The backup information structure. Used only 1257 * in the call to @c write_iso_and_go_on(). 1258 * @return The number of errors encountered (0 for success) 1259 * @see write_iso_and_go_on 1260 * @see make_iso_fs 1261 * @bug The final ISO is written even if there are no files on it. In practice, 1262 * however, this occurs rarely. 1263 */ 1264 int write_final_iso_if_necessary() 1066 1265 { 1067 1068 /*@ int ************************************** */ 1069 int res = 0; 1070 int retval = 0; 1071 1072 /*@ buffers ********************************** */ 1266 /*@ int ***************************************************** */ 1267 int res; 1268 1269 /*@ buffers ************************************************** */ 1270 char *tmp = NULL; 1073 1271 1074 1272 assert(bkpinfo != NULL); 1075 mvaddstr_and_log_it(g_currentY, 0, 1076 "Writing any remaining data to media "); 1077 1078 log_msg(1, "Closing tape/CD/USB ... "); 1079 if (IS_THIS_A_STREAMING_BACKUP(bkpinfo->backup_media_type)) { 1080 /* write tape/cdstream */ 1081 closeout_tape(); 1082 } else { 1083 /* write final ISO/USB */ 1084 res = write_final_iso_if_necessary(); 1085 retval += res; 1086 if (res) { 1087 log_msg(1, "write_final_iso_if_necessary returned an error"); 1088 } 1089 } 1090 log_msg(2, "Fork is exiting ... "); 1091 1092 mvaddstr_and_log_it(g_currentY++, 74, "Done."); 1093 1094 /* final stuff */ 1095 if (retval) { 1096 mvaddstr_and_log_it(g_currentY++, 74, "Errors."); 1097 } else { 1098 mvaddstr_and_log_it(g_currentY++, 74, "Done."); 1099 } 1100 1101 return (retval); 1273 // I should really check if there are any slices or tarballs to be copied to CD-R(W)'s; the odds are approx. 1 in a million that there are no files here, so I'll just go ahead & make one more CD anyway 1274 1275 tmp = mr_center_string("Writing the final ISO", 80); 1276 log_msg(2, tmp); 1277 if (!g_text_mode) { 1278 newtPushHelpLine(tmp); 1279 } 1280 mr_free(tmp); 1281 res = write_iso_and_go_on(TRUE); 1282 if (!g_text_mode) { 1283 newtPopHelpLine(); 1284 } 1285 log_msg(2, "Returning from writing final ISO (res=%d)", res); 1286 return (res); 1287 } 1288 1289 1290 1291 1292 /** 1293 * Remove the archives in @c d. 1294 * This could possibly include any of: 1295 * - all afioballs (compressed and not) 1296 * - all filelists 1297 * - all slices 1298 * - all checksums 1299 * - a zero filler file 1300 * 1301 * @param d The directory to wipe the archives from. 1302 * @ingroup utilityGroup 1303 */ 1304 void wipe_archives(char *d) 1305 { 1306 /*@ buffers ********************************************* */ 1307 char *tmp = NULL; 1308 char *dir = NULL; 1309 1310 assert_string_is_neither_NULL_nor_zerolength(d); 1311 1312 mr_asprintf(dir, "%s/archives", d); 1313 mr_asprintf(tmp, "rm -f %s/*.afio.* %s/*.star.*", dir, dir); 1314 run_program_and_log_output(tmp, FALSE); 1315 mr_free(tmp); 1316 mr_asprintf(tmp, "rm -f %s/*list.[0-9]* %s/slice*", dir, dir); 1317 run_program_and_log_output(tmp, FALSE); 1318 mr_free(tmp); 1319 mr_asprintf(tmp, "rm -f %s/cklist* %s/zero", dir, dir); 1320 run_program_and_log_output(tmp, FALSE); 1321 mr_free(tmp); 1322 log_msg(1, "Wiped %s's archives", dir); 1323 mr_asprintf(tmp, "ls -l %s", dir); 1324 mr_free(dir); 1325 run_program_and_log_output(tmp, FALSE); 1326 mr_free(tmp); 1102 1327 } 1103 1328 … … 1212 1437 1213 1438 1214 1215 1216 1217 1439 /** 1440 * @addtogroup LLarchiveGroup 1441 * @{ 1442 */ 1443 /** 1444 * Function pointer to an appropriate @c move_files_to_stream routine. 1445 * You can set this to your own function (for example, one to 1446 * transfer files over the network) or leave it as is. 1447 */ 1448 int (*move_files_to_stream) (char *, ...) = 1449 _move_files_to_stream; 1450 1451 1452 /** 1453 * Function pointer to an appropriate @c move_files_to_cd routine. 1454 * You can set this to your own function (for example, one to 1455 * transfer files over the network) or leave it as is. 1456 */ 1457 int (*move_files_to_cd) (char *, ...) = 1458 _move_files_to_cd; 1218 1459 1219 1460 … … 1535 1776 1536 1777 /** 1778 * Asks the user to put a CD-R(W) in the drive. 1779 * @param ask_for_one_if_more_than_this (unused) 1780 * @param pmountable If non-NULL, pointed-to value is set to TRUE if the CD is mountable, FALSE otherwise. 1781 */ 1782 void pause_and_ask_for_cdr(int ask_for_one_if_more_than_this, bool * pmountable) { 1783 1784 /*@ buffers ********************************************* */ 1785 char *tmp = NULL; 1786 char *cdrom_dev = NULL; 1787 char *cd_dev = NULL; 1788 char *our_serial_str = NULL; 1789 bool ok_go_ahead_burn_it; 1790 int cd_number = -1; 1791 int attempt_to_mount_returned_this = 999; 1792 char *mtpt = NULL; 1793 char *szcdno = NULL; 1794 char *szserfname = NULL; 1795 char *szunmount = NULL; 1796 char *mds = NULL; 1797 1798 malloc_string(cd_dev); 1799 1800 mds = media_descriptor_string(g_backup_media_type); 1801 log_to_screen("I am about to burn %s #%d", mds, g_current_media_number); 1802 mr_free(mds); 1803 if (g_current_media_number < ask_for_one_if_more_than_this) { 1804 return; 1805 } 1806 log_to_screen("Scanning CD-ROM drive..."); 1807 mr_asprintf(mtpt, "%s/cd.mtpt", bkpinfo->tmpdir); 1808 make_hole_for_dir(mtpt); 1809 1810 gotos_make_me_puke: 1811 ok_go_ahead_burn_it = TRUE; 1812 mr_free(cdrom_dev); 1813 if ((cdrom_dev = find_optical_device()) != NULL) { 1814 /* When enabled, it made CD eject-and-retract when wrong CD inserted.. Weird 1815 log_msg(2, "paafcd: Retracting CD-ROM drive if possible" ); 1816 retract_CD_tray_and_defeat_autorun(); 1817 */ 1818 mr_asprintf(tmp, "umount %s", cdrom_dev); 1819 run_program_and_log_output(tmp, 1); 1820 mr_asprintf(szcdno, "%s/archives/THIS-CD-NUMBER", mtpt); 1821 mr_asprintf(szserfname, "%s/archives/SERIAL-STRING", mtpt); 1822 mr_asprintf(szunmount, "umount %s", mtpt); 1823 cd_number = -1; 1824 mr_asprintf(tmp, "mount %s %s", cdrom_dev, mtpt); 1825 mr_asprintf(our_serial_str, "%s", ""); 1826 attempt_to_mount_returned_this = run_program_and_log_output(tmp, 1); 1827 mr_free(tmp); 1828 1829 if (attempt_to_mount_returned_this) { 1830 log_msg(4, "Failed to mount %s at %s", cdrom_dev, mtpt); 1831 log_to_screen("If there's a CD/DVD in the drive, it's blank."); 1832 } else if (!does_file_exist(szcdno) || !does_file_exist(szserfname)) { 1833 mds = media_descriptor_string(g_backup_media_type); 1834 log_to_screen("%s has data on it but it's probably not a Mondo CD.", mds); 1835 mr_free(mds); 1836 } else { 1837 mds = media_descriptor_string(g_backup_media_type); 1838 log_to_screen("%s found in drive. It's a Mondo disk.", mds); 1839 mr_free(mds); 1840 1841 cd_number = atoi(last_line_of_file(szcdno)); 1842 mr_asprintf(tmp, "cat %s 2> /dev/null", szserfname); 1843 mr_free(our_serial_str); 1844 our_serial_str = call_program_and_get_last_line_of_output(tmp); 1845 mr_free(tmp); 1846 // FIXME - should be able to use last_line_of_file(), surely? 1847 } 1848 mr_free(szcdno); 1849 mr_free(szserfname); 1850 1851 run_program_and_log_output(szunmount, 1); 1852 mr_free(szunmount); 1853 1854 log_msg(2, "paafcd: cd_number = %d", cd_number); 1855 log_msg(2, "our serial str = %s; bkpinfo->serial_string = %s", our_serial_str, bkpinfo->serial_string); 1856 if (cd_number > 0 && !strcmp(our_serial_str, bkpinfo->serial_string)) { 1857 mds = media_descriptor_string(g_backup_media_type); 1858 log_msg(2, "This %s is part of this backup set!", mds); 1859 ok_go_ahead_burn_it = FALSE; 1860 if (cd_number == g_current_media_number - 1) { 1861 log_to_screen("I think you've left the previous %s in the drive.", mds); 1862 } else { 1863 log_to_screen("Please remove this %s. It is part of the backup set you're making now.", mds); 1864 } 1865 mr_free(mds); 1866 1867 } else { 1868 log_to_screen("...but not part of _our_ backup set."); 1869 } 1870 mr_free(our_serial_str); 1871 } else { 1872 mds = media_descriptor_string(g_backup_media_type); 1873 log_msg(2, 1874 "paafcd: Can't find CD-ROM drive. Perhaps it has a blank %s in it?", mds); 1875 if (interrogate_disk_currently_in_cddrive(cd_dev, FALSE)) { 1876 ok_go_ahead_burn_it = FALSE; 1877 log_to_screen("There isn't a writable %s in the drive.", mds); 1878 } 1879 mr_free(mds); 1880 } 1881 1882 if (!ok_go_ahead_burn_it) { 1883 if (!bkpinfo->please_dont_eject) { 1884 eject_device(cdrom_dev); 1885 } 1886 mds = media_descriptor_string(g_backup_media_type); 1887 mr_asprintf(tmp, "I am about to burn %s #%d of the backup set. Please insert %s and press Enter.", mds, g_current_media_number, mds); 1888 mr_free(mds); 1889 1890 popup_and_OK(tmp); 1891 mr_free(tmp); 1892 goto gotos_make_me_puke; 1893 } else { 1894 log_msg(2, "paafcd: OK, going ahead and burning it."); 1895 } 1896 1897 mds = media_descriptor_string(g_backup_media_type); 1898 log_msg(2, "paafcd: OK, I assume I have a blank/reusable %s in the drive...", mds); 1899 1900 log_to_screen("Proceeding w/ %s in drive.", mds); 1901 mr_free(mds); 1902 1903 mr_free(cdrom_dev); 1904 paranoid_free(cd_dev); 1905 mr_free(mtpt); 1906 if (pmountable) { 1907 if (attempt_to_mount_returned_this) { 1908 *pmountable = FALSE; 1909 } else { 1910 *pmountable = TRUE; 1911 } 1912 } 1913 1914 } 1915 1916 1917 /** 1537 1918 * Create an ISO image in @c destfile, from files in @c bkpinfo->scratchdir. 1538 1919 * … … 1847 2228 1848 2229 /** 2230 * Chop up @c filename. 2231 * @param bkpinfo The backup information structure. Fields used: 2232 * - @c backup_media_type 2233 * - @c compression_level 2234 * - @c optimal_set_size 2235 * - @c tmpdir 2236 * - @c use_lzo 2237 * - @c zip_exe 2238 * - @c zip_suffix 2239 * 2240 * @param biggie_filename The file to chop up. 2241 * @param ntfsprog_fifo The FIFO to ntfsclone if this is an imagedev, NULL otherwise. 2242 * @param biggie_file_number The sequence number of this biggie file (starting from 0). 2243 * @param noof_biggie_files The number of biggie files there are total. 2244 * @return The number of errors encountered (0 for success) 2245 * @see make_slices_and_images 2246 * @ingroup LLarchiveGroup 2247 */ 2248 int slice_up_file_etc(char *biggie_filename, char *ntfsprog_fifo, long biggie_file_number, long noof_biggie_files, bool use_ntfsprog) { 2249 2250 /*@ buffers ************************************************** */ 2251 char *tmp = NULL; 2252 char *checksum_line = NULL; 2253 char *command = NULL; 2254 char *tempblock = NULL; 2255 char *curr_slice_fname_uncompressed = NULL; 2256 char *curr_slice_fname_compressed = NULL; 2257 char *file_to_archive = NULL; 2258 char *file_to_openin = NULL; 2259 /*@ pointers ************************************************** */ 2260 char *pB = NULL; 2261 FILE *fin = NULL; 2262 FILE *fout = NULL; 2263 2264 /*@ bool ****************************************************** */ 2265 bool finished = FALSE; 2266 2267 /*@ long ****************************************************** */ 2268 size_t blksize = (size_t)0; 2269 long slice_num = 0L; 2270 long i = 0L; 2271 bool should_I_compress_slices = TRUE; 2272 char *suffix = NULL; // for compressed slices 2273 2274 /*@ long long ************************************************** */ 2275 off_t totalread = (off_t)0; 2276 off_t totallength = (off_t)0; 2277 2278 /*@ int ******************************************************** */ 2279 int retval = 0; 2280 int res = 0; 2281 2282 /*@ structures ************************************************** */ 2283 struct s_filename_and_lstat_info biggiestruct; 2284 2285 assert(bkpinfo != NULL); 2286 assert_string_is_neither_NULL_nor_zerolength(biggie_filename); 2287 2288 biggiestruct.for_backward_compatibility = '\n'; 2289 biggiestruct.use_ntfsprog = use_ntfsprog; 2290 if (is_this_file_compressed(biggie_filename) || bkpinfo->compression_level == 0) { 2291 mr_asprintf(suffix, "%s", ""); 2292 should_I_compress_slices = FALSE; 2293 } else { 2294 mr_asprintf(suffix, "%s", bkpinfo->zip_suffix); 2295 should_I_compress_slices = TRUE; 2296 } 2297 2298 if (bkpinfo->optimal_set_size < 999L) { 2299 fatal_error("bkpinfo->optimal_set_size is insanely small"); 2300 } 2301 2302 if (ntfsprog_fifo) { 2303 file_to_openin = ntfsprog_fifo; 2304 mr_asprintf(checksum_line, "IGNORE"); 2305 log_msg(2, "Not calculating checksum for %s: it would take too long", biggie_filename); 2306 if ((tmp = find_home_of_exe("ntfsresize")) == NULL) { 2307 fatal_error("ntfsresize not found"); 2308 } 2309 mr_asprintf(command, "%s --force --info %s|grep '^You might resize at '|cut -d' ' -f5", tmp, biggie_filename); 2310 mr_free(tmp); 2311 log_it("command = %s", command); 2312 tmp = call_program_and_get_last_line_of_output(command); 2313 mr_free(command); 2314 log_it("res of it = %s", tmp); 2315 totallength = (off_t)atoll(tmp); 2316 mr_free(tmp); 2317 } else { 2318 file_to_openin = biggie_filename; 2319 if (strchr(biggie_filename,'\'') != NULL) { 2320 mr_asprintf(command, "md5sum \"%s\"", biggie_filename); 2321 } else { 2322 mr_asprintf(command, "md5sum '%s'", biggie_filename); 2323 } 2324 if (!(fin = popen(command, "r"))) { 2325 log_OS_error("Unable to popen-in command"); 2326 mr_free(suffix); 2327 return (1); 2328 } 2329 mr_free(command); 2330 mr_getline(checksum_line, fin); 2331 pclose(fin); 2332 totallength = length_of_file(biggie_filename); 2333 } 2334 lstat(biggie_filename, &biggiestruct.properties); 2335 strcpy(biggiestruct.filename, biggie_filename); 2336 pB = strchr(checksum_line, ' '); 2337 if (!pB) { 2338 pB = strchr(checksum_line, '\t'); 2339 } 2340 if (pB) { 2341 *pB = '\0'; 2342 } 2343 strcpy(biggiestruct.checksum, checksum_line); 2344 mr_free(checksum_line); 2345 2346 mr_asprintf(tmp, "%s", slice_fname(biggie_file_number, 0, bkpinfo->tmpdir, "")); 2347 fout = fopen(tmp, "w"); 2348 if (fout == NULL) { 2349 log_msg(1, "Unable to open and write to %s", tmp); 2350 mr_free(tmp); 2351 mr_free(suffix); 2352 return (1); 2353 } 2354 res = fwrite((void *) &biggiestruct, 1, sizeof(biggiestruct), fout); 2355 paranoid_fclose(fout); 2356 mr_free(tmp); 2357 2358 log_msg(1, "Opening in %s; slicing it and writing to CD/tape", file_to_openin); 2359 if (!(fin = fopen(file_to_openin, "r"))) { 2360 log_OS_error("Unable to openin biggie_filename"); 2361 log_to_screen("Cannot archive bigfile '%s': not found", biggie_filename); 2362 2363 mr_free(suffix); 2364 return (1); 2365 } 2366 if (IS_THIS_A_STREAMING_BACKUP(bkpinfo->backup_media_type)) { 2367 res = move_files_to_stream(slice_fname(biggie_file_number, 0, bkpinfo->tmpdir, ""), NULL); 2368 } else { 2369 res = move_files_to_cd(slice_fname(biggie_file_number, 0, bkpinfo->tmpdir, ""), NULL); 2370 } 2371 i = bkpinfo->optimal_set_size / 256L; 2372 if (!(tempblock = (char *) malloc(256 * 1024))) { 2373 fatal_error("malloc error 256*1024"); 2374 } 2375 for (slice_num = 1; !finished; slice_num++) { 2376 mr_asprintf(curr_slice_fname_uncompressed, "%s", slice_fname(biggie_file_number, slice_num, bkpinfo->tmpdir, "")); 2377 mr_asprintf(curr_slice_fname_compressed, "%s", slice_fname(biggie_file_number, slice_num, bkpinfo->tmpdir, suffix)); 2378 2379 tmp = percent_media_full_comment(); 2380 update_progress_form(tmp); 2381 mr_free(tmp); 2382 2383 if (!(fout = fopen(curr_slice_fname_uncompressed, "w"))) { 2384 log_OS_error(curr_slice_fname_uncompressed); 2385 mr_free(suffix); 2386 return (1); 2387 } 2388 if ((i == bkpinfo->optimal_set_size / 256L) && (totalread < (off_t)1.1 * totallength)) { 2389 for (i = 0L; i < (bkpinfo->optimal_set_size / 256L); i++) { 2390 blksize = fread(tempblock, 1, 256 * 1024, fin); 2391 if (blksize > (size_t)0) { 2392 totalread = totalread + (off_t)blksize; 2393 res = fwrite(tempblock, 1, blksize, fout); 2394 } else { 2395 break; 2396 } 2397 } 2398 } else { 2399 i = 0L; 2400 } 2401 paranoid_fclose(fout); 2402 if (i > 0L) // length_of_file (curr_slice_fname_uncompressed) 2403 { 2404 if (!does_file_exist(curr_slice_fname_uncompressed)) { 2405 log_msg(2, "Warning - '%s' doesn't exist. How can I compress slice?", curr_slice_fname_uncompressed); 2406 } 2407 if (should_I_compress_slices && bkpinfo->compression_level > 0) { 2408 mr_asprintf(command, "%s -%d %s", bkpinfo->zip_exe, bkpinfo->compression_level, curr_slice_fname_uncompressed); 2409 log_msg(2, command); 2410 if ((res = system(command))) { 2411 log_OS_error(command); 2412 } 2413 // did_I_compress_slice = TRUE; 2414 } else { 2415 mr_asprintf(command, "mv %s %s 2>> %s", curr_slice_fname_uncompressed, curr_slice_fname_compressed, MONDO_LOGFILE); 2416 res = 0; // don't do it :) 2417 // did_I_compress_slice = FALSE; 2418 } 2419 mr_free(command); 2420 2421 retval += res; 2422 if (res) { 2423 log_msg(2, "Failed to compress the slice"); 2424 } 2425 if (bkpinfo->use_lzo && strcmp(curr_slice_fname_compressed, curr_slice_fname_uncompressed)) { 2426 unlink(curr_slice_fname_uncompressed); 2427 } 2428 if (res) { 2429 mr_asprintf(tmp, "Problem with slice # %ld", slice_num); 2430 } else { 2431 mr_asprintf(tmp, "%s - Bigfile #%ld, slice #%ld compressed OK ", biggie_filename, biggie_file_number + 1, slice_num); 2432 } 2433 if (!g_text_mode) { 2434 newtDrawRootText(0, g_noof_rows - 2, tmp); 2435 newtRefresh(); 2436 } else { 2437 log_msg(2, tmp); 2438 } 2439 mr_free(tmp); 2440 2441 mr_asprintf(file_to_archive, "%s", curr_slice_fname_compressed); 2442 g_current_progress++; 2443 } else { /* if i==0 then ... */ 2444 finished = TRUE; 2445 mr_asprintf(file_to_archive, "%s", curr_slice_fname_uncompressed); 2446 if (IS_THIS_A_STREAMING_BACKUP(bkpinfo->backup_media_type)) { 2447 break; 2448 } 2449 } 2450 mr_free(curr_slice_fname_uncompressed); 2451 mr_free(curr_slice_fname_compressed); 2452 2453 if (IS_THIS_A_STREAMING_BACKUP(bkpinfo->backup_media_type)) { 2454 register_in_tape_catalog(biggieslice, biggie_file_number, slice_num, file_to_archive); 2455 maintain_collection_of_recent_archives(bkpinfo->tmpdir, file_to_archive); 2456 res = move_files_to_stream(file_to_archive, NULL); 2457 } else { 2458 res = move_files_to_cd(file_to_archive, NULL); 2459 } 2460 mr_free(file_to_archive); 2461 2462 retval += res; 2463 if (res) { 2464 log_to_screen("Failed to add slice %ld of bigfile %ld to scratchdir", slice_num, biggie_file_number + 1); 2465 fatal_error("Hard disk full. You should have bought a bigger one."); 2466 } 2467 } 2468 mr_free(tempblock); 2469 mr_free(suffix); 2470 paranoid_fclose(fin); 2471 mr_asprintf(tmp, "Sliced bigfile #%ld", biggie_file_number + 1); 2472 if (retval) { 2473 mr_strcat(tmp, "...FAILED"); 2474 } else { 2475 mr_strcat(tmp, "...OK!"); 2476 } 2477 log_msg(1, tmp); 2478 mr_free(tmp); 2479 2480 return (retval); 2481 } 2482 2483 2484 /** 1849 2485 * Back up big files by chopping them up. 1850 2486 * This function backs up all "big" files (where "big" depends … … 2136 2772 /* @} - end of LLarchiveGroup */ 2137 2773 2138 2139 /** 2140 * Wrapper around @c make_afioballs_and_images(). 2141 * @param bkpinfo the backup information structure. Only the 2142 * @c backup_media_type field is used within this function. 2143 * @return return code of make_afioballs_and_images 2144 * @see make_afioballs_and_images 2145 * @ingroup MLarchiveGroup 2146 */ 2147 int make_those_afios_phase() 2148 { 2149 /*@ int ******************************************* */ 2150 int res = 0; 2151 int retval = 0; 2152 2153 assert(bkpinfo != NULL); 2154 2155 mvaddstr_and_log_it(g_currentY, 0, "Archiving regular files to media "); 2156 2157 if (IS_THIS_A_STREAMING_BACKUP(bkpinfo->backup_media_type)) { 2158 write_header_block_to_stream((off_t)0, "start-of-afioballs", BLK_START_AFIOBALLS); 2159 #if __FreeBSD__ == 5 2160 log_msg(1, "Using single-threaded make_afioballs_and_images() to suit b0rken FreeBSD 5.0"); 2161 res = make_afioballs_and_images_OLD(); 2162 #else 2163 res = make_afioballs_and_images_OLD(); 2164 #endif 2165 write_header_block_to_stream((off_t)0, "stop-afioballs", BLK_STOP_AFIOBALLS); 2166 } else { 2167 res = make_afioballs_and_images(); 2168 } 2169 2170 retval += res; 2171 if (res) { 2172 mvaddstr_and_log_it(g_currentY++, 74, "Errors."); 2173 log_msg(1, "make_afioballs_and_images returned an error"); 2174 } else { 2175 mvaddstr_and_log_it(g_currentY++, 74, "Done."); 2176 } 2177 return (retval); 2178 } 2179 2180 /** 2181 * Wrapper around @c make_slices_and_images(). 2774 /** 2775 * Write an ISO image to <tt>[bkpinfo->isodir]/bkpinfo->prefix-[g_current_media_number].iso</tt>. 2182 2776 * @param bkpinfo The backup information structure. Fields used: 2183 2777 * - @c backup_media_type 2778 * - @c prefix 2779 * - @c isodir 2780 * - @c manual_cd_tray 2781 * - @c media_size 2782 * - @c netfs_remote_dir 2184 2783 * - @c scratchdir 2185 * - @c tmpdir 2784 * - @c verify_data 2785 * 2786 * @param last_cd If TRUE, this is the last CD to write; if FALSE, it's not. 2186 2787 * @return The number of errors encountered (0 for success) 2187 * @ ingroup MLarchiveGroup2188 */ 2189 int make_those_slices_phase()2788 * @see make_iso_fs 2789 */ 2790 int write_iso_and_go_on(bool last_cd) 2190 2791 { 2191 2192 /*@ int ***************************************************** */ 2792 /*@ pointers **************************************************** */ 2793 FILE *fout; 2794 2795 /*@ buffers ***************************************************** */ 2796 char *tmp = NULL; 2797 char *tmp1 = NULL; 2798 char *cdno_fname = NULL; 2799 char *lastcd_fname = NULL; 2800 char *isofile = NULL; 2801 char *mds = NULL; 2802 2803 /*@ bool ******************************************************** */ 2804 bool that_one_was_ok; 2805 bool orig_vfy_flag_val; 2806 2807 /*@ int *********************************************************** */ 2193 2808 int res = 0; 2194 int retval = 0;2195 2196 /*@ buffers ************************************************** */2197 char *biggielist = NULL;2198 char *command = NULL;2199 char *blah = NULL;2200 char *xattr_fname = NULL;2201 char *acl_fname = NULL;2202 2809 2203 2810 assert(bkpinfo != NULL); 2204 /* slice big files */ 2205 mvaddstr_and_log_it(g_currentY, 0, "Archiving large files to media "); 2206 mr_asprintf(biggielist, "%s/archives/biggielist.txt", bkpinfo->scratchdir); 2207 if (g_getfattr) { 2208 mr_asprintf(xattr_fname, XATTR_BIGGLST_FNAME_RAW_SZ, bkpinfo->tmpdir); 2209 } 2210 if (g_getfacl) { 2211 mr_asprintf(acl_fname, ACL_BIGGLST_FNAME_RAW_SZ, bkpinfo->tmpdir); 2212 } 2213 2214 mr_asprintf(command, "cp %s/biggielist.txt %s", bkpinfo->tmpdir, biggielist); 2215 paranoid_system(command); 2216 mr_free(command); 2217 2218 mr_asprintf(blah, "biggielist = %s", biggielist); 2219 log_msg(2, blah); 2220 mr_free(blah); 2221 2222 if (!does_file_exist(biggielist)) { 2223 log_msg(1, "BTW, the biggielist does not exist"); 2224 } 2225 2226 if (g_getfattr) { 2227 get_fattr_list(biggielist, xattr_fname); 2228 mr_asprintf(command, "cp %s %s/archives/", xattr_fname, bkpinfo->scratchdir); 2229 paranoid_system(command); 2230 mr_free(command); 2231 } 2232 if (g_getfacl) { 2233 get_acl_list(biggielist, acl_fname); 2234 mr_asprintf(command, "cp %s %s/archives/", acl_fname, bkpinfo->scratchdir); 2235 paranoid_system(command); 2236 mr_free(command); 2237 } 2238 2239 if (IS_THIS_A_STREAMING_BACKUP(bkpinfo->backup_media_type)) { 2240 res += write_EXAT_files_to_tape(xattr_fname, acl_fname); 2241 mr_asprintf(blah, "%ld", count_lines_in_file(biggielist)); 2242 write_header_block_to_stream((off_t)0, blah, BLK_START_BIGGIEFILES); 2243 mr_free(blah); 2244 } 2245 res = make_slices_and_images(biggielist); 2246 if (IS_THIS_A_STREAMING_BACKUP(bkpinfo->backup_media_type)) { 2247 write_header_block_to_stream((off_t)0, "end-of-biggiefiles", BLK_STOP_BIGGIEFILES); 2248 } 2249 retval += res; 2250 if (res) { 2251 log_msg(1, "make_slices_and_images returned an error"); 2252 mvaddstr_and_log_it(g_currentY++, 74, "Errors."); 2253 } else { 2254 mvaddstr_and_log_it(g_currentY++, 74, "Done."); 2255 } 2256 mr_free(biggielist); 2257 mr_free(xattr_fname); 2258 mr_free(acl_fname); 2259 return (retval); 2811 orig_vfy_flag_val = bkpinfo->verify_data; 2812 if (bkpinfo->media_size <= 0) { 2813 fatal_error("write_iso_and_go_on() - unknown media size"); 2814 } 2815 2816 mds = media_descriptor_string(bkpinfo->backup_media_type); 2817 log_msg(1, "OK, time to make %s #%d", mds, g_current_media_number); 2818 mr_free(mds); 2819 2820 /* label the ISO with its number */ 2821 2822 mr_asprintf(cdno_fname, "%s/archives/THIS-CD-NUMBER", bkpinfo->scratchdir); 2823 fout = fopen(cdno_fname, "w"); 2824 mr_free(cdno_fname); 2825 2826 fprintf(fout, "%d", g_current_media_number); 2827 paranoid_fclose(fout); 2828 2829 mr_asprintf(tmp1, "cp -f %s/autorun %s/", g_mondo_home, bkpinfo->scratchdir); 2830 if (run_program_and_log_output(tmp1, FALSE)) { 2831 log_msg(2, "Warning - unable to copy autorun to scratchdir"); 2832 } 2833 mr_free(tmp1); 2834 2835 /* last CD or not? Label accordingly */ 2836 mr_asprintf(lastcd_fname, "%s/archives/NOT-THE-LAST", bkpinfo->scratchdir); 2837 if (last_cd) { 2838 unlink(lastcd_fname); 2839 log_msg(2, 2840 "OK, you're telling me this is the last CD. Fair enough."); 2841 } else { 2842 fout = fopen(lastcd_fname, "w"); 2843 fprintf(fout, 2844 "You're listening to 90.3 WPLN, Nashville Public Radio.\n"); 2845 paranoid_fclose(fout); 2846 } 2847 mr_free(lastcd_fname); 2848 2849 if (space_occupied_by_cd(bkpinfo->scratchdir) / 1024 > bkpinfo->media_size) { 2850 log_to_screen("Warning! CD is too big. It occupies %ld KB, which is more than the %ld MB allowed.",(long) space_occupied_by_cd(bkpinfo->scratchdir),(long) bkpinfo->media_size); 2851 } 2852 2853 if (bkpinfo->netfs_remote_dir != NULL) { 2854 // NETFS 2855 mr_asprintf(isofile, "%s/%s/%s-%d.iso", bkpinfo->isodir, bkpinfo->netfs_remote_dir, bkpinfo->prefix, g_current_media_number); 2856 } else { 2857 // ISO 2858 mr_asprintf(isofile, "%s/%s-%d.iso", bkpinfo->isodir, bkpinfo->prefix, g_current_media_number); 2859 } 2860 for (that_one_was_ok = FALSE; !that_one_was_ok;) { 2861 if (bkpinfo->backup_media_type != usb) { 2862 res = make_iso_fs(isofile); 2863 } else { 2864 res = make_usb_fs(); 2865 } 2866 if (g_current_media_number == 1 && !res 2867 && (bkpinfo->backup_media_type == cdr)) { 2868 if ((tmp = find_optical_device()) == NULL) { // make sure find_optical_device() finds, records CD-R's loc 2869 log_msg(3, "*Sigh* Mike, I hate your computer."); 2870 // if it can't be found then force pausing 2871 bkpinfo->manual_cd_tray = TRUE; 2872 } else { 2873 log_msg(3, "Great. Found Mike's CD-ROM drive."); 2874 } 2875 mr_free(tmp); 2876 } 2877 if (bkpinfo->verify_data && !res) { 2878 mds = media_descriptor_string(g_backup_media_type); 2879 log_to_screen("Please reboot from the 1st %s in Compare Mode, as a precaution.", mds); 2880 mr_free(mds); 2881 if (chdir("/")) { 2882 // FIXME 2883 } 2884 log_it("Before calling verification of image()"); 2885 if (bkpinfo->backup_media_type == usb) { 2886 res += verify_usb_image(); 2887 } else { 2888 res += verify_cd_image(); 2889 } 2890 log_it("After calling verification of image()"); 2891 } 2892 if (!res) { 2893 that_one_was_ok = TRUE; 2894 } else { 2895 mds = media_descriptor_string(bkpinfo->backup_media_type); 2896 mr_asprintf(tmp1, "Failed to create %s #%d. Retry?", mds, g_current_media_number); 2897 mr_free(mds); 2898 res = ask_me_yes_or_no(tmp1); 2899 mr_free(tmp1); 2900 2901 if (!res) { 2902 if (ask_me_yes_or_no("Abort the backup?")) { 2903 fatal_error("FAILED TO BACKUP"); 2904 } else { 2905 break; 2906 } 2907 } else { 2908 log_msg(2, "Retrying, at user's request..."); 2909 res = 0; 2910 } 2911 } 2912 } 2913 mr_free(isofile); 2914 2915 g_current_media_number++; 2916 wipe_archives(bkpinfo->scratchdir); 2917 mr_asprintf(tmp1, "rm -Rf %s/images/*gz %s/images/*data*img", bkpinfo->scratchdir, bkpinfo->scratchdir); 2918 if (system(tmp1)) { 2919 log_msg(2, "Error occurred when I tried to delete the redundant IMGs and GZs"); 2920 } 2921 mr_free(tmp1); 2922 2923 if (last_cd) { 2924 log_msg(2, "This was your last media."); 2925 } else { 2926 log_msg(2, "Continuing to backup your data..."); 2927 } 2928 2929 bkpinfo->verify_data = orig_vfy_flag_val; 2930 return (0); 2260 2931 } 2261 2932 2262 2263 /** 2264 * @addtogroup LLarchiveGroup 2265 * @{ 2266 */ 2267 /** 2268 * Function pointer to an appropriate @c move_files_to_cd routine. 2269 * You can set this to your own function (for example, one to 2270 * transfer files over the network) or leave it as is. 2271 */ 2272 int (*move_files_to_cd) (char *, ...) = 2273 _move_files_to_cd; 2933 /* @} - end of LLarchiveGroup */ 2274 2934 2275 2935 /** … … 2365 3025 /* @} - end of LLarchiveGroup */ 2366 3026 2367 2368 /**2369 * @addtogroup LLarchiveGroup2370 * @{2371 */2372 /**2373 * Function pointer to an appropriate @c move_files_to_stream routine.2374 * You can set this to your own function (for example, one to2375 * transfer files over the network) or leave it as is.2376 */2377 int (*move_files_to_stream) (char *, ...) =2378 _move_files_to_stream;2379 2380 3027 /** 2381 3028 * Copy some files to tape. … … 2497 3144 } 2498 3145 2499 2500 /**2501 * Asks the user to put a CD-R(W) in the drive.2502 * @param ask_for_one_if_more_than_this (unused)2503 * @param pmountable If non-NULL, pointed-to value is set to TRUE if the CD is mountable, FALSE otherwise.2504 */2505 void2506 pause_and_ask_for_cdr(int ask_for_one_if_more_than_this, bool * pmountable)2507 {2508 2509 /*@ buffers ********************************************* */2510 char *tmp = NULL;2511 char *cdrom_dev = NULL;2512 char *cd_dev = NULL;2513 char *our_serial_str = NULL;2514 bool ok_go_ahead_burn_it;2515 int cd_number = -1;2516 int attempt_to_mount_returned_this = 999;2517 char *mtpt = NULL;2518 char *szcdno = NULL;2519 char *szserfname = NULL;2520 char *szunmount = NULL;2521 char *mds = NULL;2522 2523 malloc_string(cd_dev);2524 2525 mds = media_descriptor_string(g_backup_media_type);2526 log_to_screen("I am about to burn %s #%d", mds, g_current_media_number);2527 mr_free(mds);2528 if (g_current_media_number < ask_for_one_if_more_than_this) {2529 return;2530 }2531 log_to_screen("Scanning CD-ROM drive...");2532 mr_asprintf(mtpt, "%s/cd.mtpt", bkpinfo->tmpdir);2533 make_hole_for_dir(mtpt);2534 2535 gotos_make_me_puke:2536 ok_go_ahead_burn_it = TRUE;2537 mr_free(cdrom_dev);2538 if ((cdrom_dev = find_optical_device()) != NULL) {2539 /* When enabled, it made CD eject-and-retract when wrong CD inserted.. Weird2540 log_msg(2, "paafcd: Retracting CD-ROM drive if possible" );2541 retract_CD_tray_and_defeat_autorun();2542 */2543 mr_asprintf(tmp, "umount %s", cdrom_dev);2544 run_program_and_log_output(tmp, 1);2545 mr_asprintf(szcdno, "%s/archives/THIS-CD-NUMBER", mtpt);2546 mr_asprintf(szserfname, "%s/archives/SERIAL-STRING", mtpt);2547 mr_asprintf(szunmount, "umount %s", mtpt);2548 cd_number = -1;2549 mr_asprintf(tmp, "mount %s %s", cdrom_dev, mtpt);2550 mr_asprintf(our_serial_str, "%s", "");2551 attempt_to_mount_returned_this = run_program_and_log_output(tmp, 1);2552 mr_free(tmp);2553 2554 if (attempt_to_mount_returned_this) {2555 log_msg(4, "Failed to mount %s at %s", cdrom_dev, mtpt);2556 log_to_screen("If there's a CD/DVD in the drive, it's blank.");2557 } else if (!does_file_exist(szcdno) || !does_file_exist(szserfname)) {2558 mds = media_descriptor_string(g_backup_media_type);2559 log_to_screen("%s has data on it but it's probably not a Mondo CD.", mds);2560 mr_free(mds);2561 } else {2562 mds = media_descriptor_string(g_backup_media_type);2563 log_to_screen("%s found in drive. It's a Mondo disk.", mds);2564 mr_free(mds);2565 2566 cd_number = atoi(last_line_of_file(szcdno));2567 mr_asprintf(tmp, "cat %s 2> /dev/null", szserfname);2568 mr_free(our_serial_str);2569 our_serial_str = call_program_and_get_last_line_of_output(tmp);2570 mr_free(tmp);2571 // FIXME - should be able to use last_line_of_file(), surely?2572 }2573 mr_free(szcdno);2574 mr_free(szserfname);2575 2576 run_program_and_log_output(szunmount, 1);2577 mr_free(szunmount);2578 2579 log_msg(2, "paafcd: cd_number = %d", cd_number);2580 log_msg(2, "our serial str = %s; bkpinfo->serial_string = %s", our_serial_str, bkpinfo->serial_string);2581 if (cd_number > 0 && !strcmp(our_serial_str, bkpinfo->serial_string)) {2582 mds = media_descriptor_string(g_backup_media_type);2583 log_msg(2, "This %s is part of this backup set!", mds);2584 ok_go_ahead_burn_it = FALSE;2585 if (cd_number == g_current_media_number - 1) {2586 log_to_screen("I think you've left the previous %s in the drive.", mds);2587 } else {2588 log_to_screen("Please remove this %s. It is part of the backup set you're making now.", mds);2589 }2590 mr_free(mds);2591 2592 } else {2593 log_to_screen("...but not part of _our_ backup set.");2594 }2595 mr_free(our_serial_str);2596 } else {2597 mds = media_descriptor_string(g_backup_media_type);2598 log_msg(2,2599 "paafcd: Can't find CD-ROM drive. Perhaps it has a blank %s in it?", mds);2600 if (interrogate_disk_currently_in_cddrive(cd_dev, FALSE)) {2601 ok_go_ahead_burn_it = FALSE;2602 log_to_screen("There isn't a writable %s in the drive.", mds);2603 }2604 mr_free(mds);2605 }2606 2607 if (!ok_go_ahead_burn_it) {2608 if (!bkpinfo->please_dont_eject) {2609 eject_device(cdrom_dev);2610 }2611 mds = media_descriptor_string(g_backup_media_type);2612 mr_asprintf(tmp, "I am about to burn %s #%d of the backup set. Please insert %s and press Enter.", mds, g_current_media_number, mds);2613 mr_free(mds);2614 2615 popup_and_OK(tmp);2616 mr_free(tmp);2617 goto gotos_make_me_puke;2618 } else {2619 log_msg(2, "paafcd: OK, going ahead and burning it.");2620 }2621 2622 mds = media_descriptor_string(g_backup_media_type);2623 log_msg(2, "paafcd: OK, I assume I have a blank/reusable %s in the drive...", mds);2624 2625 log_to_screen("Proceeding w/ %s in drive.", mds);2626 mr_free(mds);2627 2628 mr_free(cdrom_dev);2629 paranoid_free(cd_dev);2630 mr_free(mtpt);2631 if (pmountable) {2632 if (attempt_to_mount_returned_this) {2633 *pmountable = FALSE;2634 } else {2635 *pmountable = TRUE;2636 }2637 }2638 2639 }2640 2641 2642 /**2643 * Set the <tt>N</tt>th bit of @c array to @c true_or_false.2644 * @param array The bit array (as a @c char pointer).2645 * @param N The bit number to set or reset.2646 * @param true_or_false If TRUE then set bit @c N, if FALSE then reset bit @c N.2647 * @see get_bit_N_of_array2648 */2649 void set_bit_N_of_array(char *array, int N, bool true_or_false)2650 {2651 int bit_number;2652 int mask, orig_val, to_add;2653 int element_number;2654 2655 assert(array != NULL);2656 2657 element_number = N / 8;2658 bit_number = N % 8;2659 to_add = (1 << bit_number);2660 mask = 255 - to_add;2661 orig_val = array[element_number] & mask;2662 // log_it("array[%d]=%02x; %02x&%02x = %02x", element_number, array[element_number], mask, orig_val);2663 if (true_or_false) {2664 array[element_number] = orig_val | to_add;2665 }2666 }2667 2668 3146 /* @} - end of utilityGroup */ 2669 2670 2671 /**2672 * Chop up @c filename.2673 * @param bkpinfo The backup information structure. Fields used:2674 * - @c backup_media_type2675 * - @c compression_level2676 * - @c optimal_set_size2677 * - @c tmpdir2678 * - @c use_lzo2679 * - @c zip_exe2680 * - @c zip_suffix2681 *2682 * @param biggie_filename The file to chop up.2683 * @param ntfsprog_fifo The FIFO to ntfsclone if this is an imagedev, NULL otherwise.2684 * @param biggie_file_number The sequence number of this biggie file (starting from 0).2685 * @param noof_biggie_files The number of biggie files there are total.2686 * @return The number of errors encountered (0 for success)2687 * @see make_slices_and_images2688 * @ingroup LLarchiveGroup2689 */2690 int slice_up_file_etc(char *biggie_filename, char *ntfsprog_fifo, long biggie_file_number, long noof_biggie_files, bool use_ntfsprog) {2691 2692 /*@ buffers ************************************************** */2693 char *tmp = NULL;2694 char *checksum_line = NULL;2695 char *command = NULL;2696 char *tempblock = NULL;2697 char *curr_slice_fname_uncompressed = NULL;2698 char *curr_slice_fname_compressed = NULL;2699 char *file_to_archive = NULL;2700 char *file_to_openin = NULL;2701 /*@ pointers ************************************************** */2702 char *pB = NULL;2703 FILE *fin = NULL;2704 FILE *fout = NULL;2705 2706 /*@ bool ****************************************************** */2707 bool finished = FALSE;2708 2709 /*@ long ****************************************************** */2710 size_t blksize = (size_t)0;2711 long slice_num = 0L;2712 long i = 0L;2713 bool should_I_compress_slices = TRUE;2714 char *suffix = NULL; // for compressed slices2715 2716 /*@ long long ************************************************** */2717 off_t totalread = (off_t)0;2718 off_t totallength = (off_t)0;2719 2720 /*@ int ******************************************************** */2721 int retval = 0;2722 int res = 0;2723 2724 /*@ structures ************************************************** */2725 struct s_filename_and_lstat_info biggiestruct;2726 2727 assert(bkpinfo != NULL);2728 assert_string_is_neither_NULL_nor_zerolength(biggie_filename);2729 2730 biggiestruct.for_backward_compatibility = '\n';2731 biggiestruct.use_ntfsprog = use_ntfsprog;2732 if (is_this_file_compressed(biggie_filename) || bkpinfo->compression_level == 0) {2733 mr_asprintf(suffix, "%s", "");2734 should_I_compress_slices = FALSE;2735 } else {2736 mr_asprintf(suffix, "%s", bkpinfo->zip_suffix);2737 should_I_compress_slices = TRUE;2738 }2739 2740 if (bkpinfo->optimal_set_size < 999L) {2741 fatal_error("bkpinfo->optimal_set_size is insanely small");2742 }2743 2744 if (ntfsprog_fifo) {2745 file_to_openin = ntfsprog_fifo;2746 mr_asprintf(checksum_line, "IGNORE");2747 log_msg(2, "Not calculating checksum for %s: it would take too long", biggie_filename);2748 if ((tmp = find_home_of_exe("ntfsresize")) == NULL) {2749 fatal_error("ntfsresize not found");2750 }2751 mr_asprintf(command, "%s --force --info %s|grep '^You might resize at '|cut -d' ' -f5", tmp, biggie_filename);2752 mr_free(tmp);2753 log_it("command = %s", command);2754 tmp = call_program_and_get_last_line_of_output(command);2755 mr_free(command);2756 log_it("res of it = %s", tmp);2757 totallength = (off_t)atoll(tmp);2758 mr_free(tmp);2759 } else {2760 file_to_openin = biggie_filename;2761 if (strchr(biggie_filename,'\'') != NULL) {2762 mr_asprintf(command, "md5sum \"%s\"", biggie_filename);2763 } else {2764 mr_asprintf(command, "md5sum '%s'", biggie_filename);2765 }2766 if (!(fin = popen(command, "r"))) {2767 log_OS_error("Unable to popen-in command");2768 mr_free(suffix);2769 return (1);2770 }2771 mr_free(command);2772 mr_getline(checksum_line, fin);2773 pclose(fin);2774 totallength = length_of_file(biggie_filename);2775 }2776 lstat(biggie_filename, &biggiestruct.properties);2777 strcpy(biggiestruct.filename, biggie_filename);2778 pB = strchr(checksum_line, ' ');2779 if (!pB) {2780 pB = strchr(checksum_line, '\t');2781 }2782 if (pB) {2783 *pB = '\0';2784 }2785 strcpy(biggiestruct.checksum, checksum_line);2786 mr_free(checksum_line);2787 2788 mr_asprintf(tmp, "%s", slice_fname(biggie_file_number, 0, bkpinfo->tmpdir, ""));2789 fout = fopen(tmp, "w");2790 if (fout == NULL) {2791 log_msg(1, "Unable to open and write to %s", tmp);2792 mr_free(tmp);2793 mr_free(suffix);2794 return (1);2795 }2796 res = fwrite((void *) &biggiestruct, 1, sizeof(biggiestruct), fout);2797 paranoid_fclose(fout);2798 mr_free(tmp);2799 2800 log_msg(1, "Opening in %s; slicing it and writing to CD/tape", file_to_openin);2801 if (!(fin = fopen(file_to_openin, "r"))) {2802 log_OS_error("Unable to openin biggie_filename");2803 log_to_screen("Cannot archive bigfile '%s': not found", biggie_filename);2804 2805 mr_free(suffix);2806 return (1);2807 }2808 if (IS_THIS_A_STREAMING_BACKUP(bkpinfo->backup_media_type)) {2809 res = move_files_to_stream(slice_fname(biggie_file_number, 0, bkpinfo->tmpdir, ""), NULL);2810 } else {2811 res = move_files_to_cd(slice_fname(biggie_file_number, 0, bkpinfo->tmpdir, ""), NULL);2812 }2813 i = bkpinfo->optimal_set_size / 256L;2814 if (!(tempblock = (char *) malloc(256 * 1024))) {2815 fatal_error("malloc error 256*1024");2816 }2817 for (slice_num = 1; !finished; slice_num++) {2818 mr_asprintf(curr_slice_fname_uncompressed, "%s", slice_fname(biggie_file_number, slice_num, bkpinfo->tmpdir, ""));2819 mr_asprintf(curr_slice_fname_compressed, "%s", slice_fname(biggie_file_number, slice_num, bkpinfo->tmpdir, suffix));2820 2821 tmp = percent_media_full_comment();2822 update_progress_form(tmp);2823 mr_free(tmp);2824 2825 if (!(fout = fopen(curr_slice_fname_uncompressed, "w"))) {2826 log_OS_error(curr_slice_fname_uncompressed);2827 mr_free(suffix);2828 return (1);2829 }2830 if ((i == bkpinfo->optimal_set_size / 256L) && (totalread < (off_t)1.1 * totallength)) {2831 for (i = 0L; i < (bkpinfo->optimal_set_size / 256L); i++) {2832 blksize = fread(tempblock, 1, 256 * 1024, fin);2833 if (blksize > (size_t)0) {2834 totalread = totalread + (off_t)blksize;2835 res = fwrite(tempblock, 1, blksize, fout);2836 } else {2837 break;2838 }2839 }2840 } else {2841 i = 0L;2842 }2843 paranoid_fclose(fout);2844 if (i > 0L) // length_of_file (curr_slice_fname_uncompressed)2845 {2846 if (!does_file_exist(curr_slice_fname_uncompressed)) {2847 log_msg(2, "Warning - '%s' doesn't exist. How can I compress slice?", curr_slice_fname_uncompressed);2848 }2849 if (should_I_compress_slices && bkpinfo->compression_level > 0) {2850 mr_asprintf(command, "%s -%d %s", bkpinfo->zip_exe, bkpinfo->compression_level, curr_slice_fname_uncompressed);2851 log_msg(2, command);2852 if ((res = system(command))) {2853 log_OS_error(command);2854 }2855 // did_I_compress_slice = TRUE;2856 } else {2857 mr_asprintf(command, "mv %s %s 2>> %s", curr_slice_fname_uncompressed, curr_slice_fname_compressed, MONDO_LOGFILE);2858 res = 0; // don't do it :)2859 // did_I_compress_slice = FALSE;2860 }2861 mr_free(command);2862 2863 retval += res;2864 if (res) {2865 log_msg(2, "Failed to compress the slice");2866 }2867 if (bkpinfo->use_lzo && strcmp(curr_slice_fname_compressed, curr_slice_fname_uncompressed)) {2868 unlink(curr_slice_fname_uncompressed);2869 }2870 if (res) {2871 mr_asprintf(tmp, "Problem with slice # %ld", slice_num);2872 } else {2873 mr_asprintf(tmp, "%s - Bigfile #%ld, slice #%ld compressed OK ", biggie_filename, biggie_file_number + 1, slice_num);2874 }2875 if (!g_text_mode) {2876 newtDrawRootText(0, g_noof_rows - 2, tmp);2877 newtRefresh();2878 } else {2879 log_msg(2, tmp);2880 }2881 mr_free(tmp);2882 2883 mr_asprintf(file_to_archive, "%s", curr_slice_fname_compressed);2884 g_current_progress++;2885 } else { /* if i==0 then ... */2886 finished = TRUE;2887 mr_asprintf(file_to_archive, "%s", curr_slice_fname_uncompressed);2888 if (IS_THIS_A_STREAMING_BACKUP(bkpinfo->backup_media_type)) {2889 break;2890 }2891 }2892 mr_free(curr_slice_fname_uncompressed);2893 mr_free(curr_slice_fname_compressed);2894 2895 if (IS_THIS_A_STREAMING_BACKUP(bkpinfo->backup_media_type)) {2896 register_in_tape_catalog(biggieslice, biggie_file_number, slice_num, file_to_archive);2897 maintain_collection_of_recent_archives(bkpinfo->tmpdir, file_to_archive);2898 res = move_files_to_stream(file_to_archive, NULL);2899 } else {2900 res = move_files_to_cd(file_to_archive, NULL);2901 }2902 mr_free(file_to_archive);2903 2904 retval += res;2905 if (res) {2906 log_to_screen("Failed to add slice %ld of bigfile %ld to scratchdir", slice_num, biggie_file_number + 1);2907 fatal_error("Hard disk full. You should have bought a bigger one.");2908 }2909 }2910 mr_free(tempblock);2911 mr_free(suffix);2912 paranoid_fclose(fin);2913 mr_asprintf(tmp, "Sliced bigfile #%ld", biggie_file_number + 1);2914 if (retval) {2915 mr_strcat(tmp, "...FAILED");2916 } else {2917 mr_strcat(tmp, "...OK!");2918 }2919 log_msg(1, tmp);2920 mr_free(tmp);2921 2922 return (retval);2923 }2924 2925 2926 /**2927 * Remove the archives in @c d.2928 * This could possibly include any of:2929 * - all afioballs (compressed and not)2930 * - all filelists2931 * - all slices2932 * - all checksums2933 * - a zero filler file2934 *2935 * @param d The directory to wipe the archives from.2936 * @ingroup utilityGroup2937 */2938 void wipe_archives(char *d)2939 {2940 /*@ buffers ********************************************* */2941 char *tmp = NULL;2942 char *dir = NULL;2943 2944 assert_string_is_neither_NULL_nor_zerolength(d);2945 2946 mr_asprintf(dir, "%s/archives", d);2947 mr_asprintf(tmp, "rm -f %s/*.afio.* %s/*.star.*", dir, dir);2948 run_program_and_log_output(tmp, FALSE);2949 mr_free(tmp);2950 mr_asprintf(tmp, "rm -f %s/*list.[0-9]* %s/slice*", dir, dir);2951 run_program_and_log_output(tmp, FALSE);2952 mr_free(tmp);2953 mr_asprintf(tmp, "rm -f %s/cklist* %s/zero", dir, dir);2954 run_program_and_log_output(tmp, FALSE);2955 mr_free(tmp);2956 log_msg(1, "Wiped %s's archives", dir);2957 mr_asprintf(tmp, "ls -l %s", dir);2958 mr_free(dir);2959 run_program_and_log_output(tmp, FALSE);2960 mr_free(tmp);2961 }2962 3147 2963 3148 … … 2966 3151 * @{ 2967 3152 */ 2968 /**2969 * Write the final ISO image.2970 * @param bkpinfo The backup information structure. Used only2971 * in the call to @c write_iso_and_go_on().2972 * @return The number of errors encountered (0 for success)2973 * @see write_iso_and_go_on2974 * @see make_iso_fs2975 * @bug The final ISO is written even if there are no files on it. In practice,2976 * however, this occurs rarely.2977 */2978 int write_final_iso_if_necessary()2979 {2980 /*@ int ***************************************************** */2981 int res;2982 2983 /*@ buffers ************************************************** */2984 char *tmp = NULL;2985 2986 assert(bkpinfo != NULL);2987 // I should really check if there are any slices or tarballs to be copied to CD-R(W)'s; the odds are approx. 1 in a million that there are no files here, so I'll just go ahead & make one more CD anyway2988 2989 tmp = mr_center_string("Writing the final ISO", 80);2990 log_msg(2, tmp);2991 if (!g_text_mode) {2992 newtPushHelpLine(tmp);2993 }2994 mr_free(tmp);2995 res = write_iso_and_go_on(TRUE);2996 if (!g_text_mode) {2997 newtPopHelpLine();2998 }2999 log_msg(2, "Returning from writing final ISO (res=%d)", res);3000 return (res);3001 }3002 3003 3004 /**3005 * Write an ISO image to <tt>[bkpinfo->isodir]/bkpinfo->prefix-[g_current_media_number].iso</tt>.3006 * @param bkpinfo The backup information structure. Fields used:3007 * - @c backup_media_type3008 * - @c prefix3009 * - @c isodir3010 * - @c manual_cd_tray3011 * - @c media_size3012 * - @c netfs_remote_dir3013 * - @c scratchdir3014 * - @c verify_data3015 *3016 * @param last_cd If TRUE, this is the last CD to write; if FALSE, it's not.3017 * @return The number of errors encountered (0 for success)3018 * @see make_iso_fs3019 */3020 int write_iso_and_go_on(bool last_cd)3021 {3022 /*@ pointers **************************************************** */3023 FILE *fout;3024 3025 /*@ buffers ***************************************************** */3026 char *tmp = NULL;3027 char *tmp1 = NULL;3028 char *cdno_fname = NULL;3029 char *lastcd_fname = NULL;3030 char *isofile = NULL;3031 char *mds = NULL;3032 3033 /*@ bool ******************************************************** */3034 bool that_one_was_ok;3035 bool orig_vfy_flag_val;3036 3037 /*@ int *********************************************************** */3038 int res = 0;3039 3040 assert(bkpinfo != NULL);3041 orig_vfy_flag_val = bkpinfo->verify_data;3042 if (bkpinfo->media_size <= 0) {3043 fatal_error("write_iso_and_go_on() - unknown media size");3044 }3045 3046 mds = media_descriptor_string(bkpinfo->backup_media_type);3047 log_msg(1, "OK, time to make %s #%d", mds, g_current_media_number);3048 mr_free(mds);3049 3050 /* label the ISO with its number */3051 3052 mr_asprintf(cdno_fname, "%s/archives/THIS-CD-NUMBER", bkpinfo->scratchdir);3053 fout = fopen(cdno_fname, "w");3054 mr_free(cdno_fname);3055 3056 fprintf(fout, "%d", g_current_media_number);3057 paranoid_fclose(fout);3058 3059 mr_asprintf(tmp1, "cp -f %s/autorun %s/", g_mondo_home, bkpinfo->scratchdir);3060 if (run_program_and_log_output(tmp1, FALSE)) {3061 log_msg(2, "Warning - unable to copy autorun to scratchdir");3062 }3063 mr_free(tmp1);3064 3065 /* last CD or not? Label accordingly */3066 mr_asprintf(lastcd_fname, "%s/archives/NOT-THE-LAST", bkpinfo->scratchdir);3067 if (last_cd) {3068 unlink(lastcd_fname);3069 log_msg(2,3070 "OK, you're telling me this is the last CD. Fair enough.");3071 } else {3072 fout = fopen(lastcd_fname, "w");3073 fprintf(fout,3074 "You're listening to 90.3 WPLN, Nashville Public Radio.\n");3075 paranoid_fclose(fout);3076 }3077 mr_free(lastcd_fname);3078 3079 if (space_occupied_by_cd(bkpinfo->scratchdir) / 1024 > bkpinfo->media_size) {3080 log_to_screen("Warning! CD is too big. It occupies %ld KB, which is more than the %ld MB allowed.",(long) space_occupied_by_cd(bkpinfo->scratchdir),(long) bkpinfo->media_size);3081 }3082 3083 if (bkpinfo->netfs_remote_dir != NULL) {3084 // NETFS3085 mr_asprintf(isofile, "%s/%s/%s-%d.iso", bkpinfo->isodir, bkpinfo->netfs_remote_dir, bkpinfo->prefix, g_current_media_number);3086 } else {3087 // ISO3088 mr_asprintf(isofile, "%s/%s-%d.iso", bkpinfo->isodir, bkpinfo->prefix, g_current_media_number);3089 }3090 for (that_one_was_ok = FALSE; !that_one_was_ok;) {3091 if (bkpinfo->backup_media_type != usb) {3092 res = make_iso_fs(isofile);3093 } else {3094 res = make_usb_fs();3095 }3096 if (g_current_media_number == 1 && !res3097 && (bkpinfo->backup_media_type == cdr)) {3098 if ((tmp = find_optical_device()) == NULL) { // make sure find_optical_device() finds, records CD-R's loc3099 log_msg(3, "*Sigh* Mike, I hate your computer.");3100 // if it can't be found then force pausing3101 bkpinfo->manual_cd_tray = TRUE;3102 } else {3103 log_msg(3, "Great. Found Mike's CD-ROM drive.");3104 }3105 mr_free(tmp);3106 }3107 if (bkpinfo->verify_data && !res) {3108 mds = media_descriptor_string(g_backup_media_type);3109 log_to_screen("Please reboot from the 1st %s in Compare Mode, as a precaution.", mds);3110 mr_free(mds);3111 if (chdir("/")) {3112 // FIXME3113 }3114 log_it("Before calling verification of image()");3115 if (bkpinfo->backup_media_type == usb) {3116 res += verify_usb_image();3117 } else {3118 res += verify_cd_image();3119 }3120 log_it("After calling verification of image()");3121 }3122 if (!res) {3123 that_one_was_ok = TRUE;3124 } else {3125 mds = media_descriptor_string(bkpinfo->backup_media_type);3126 mr_asprintf(tmp1, "Failed to create %s #%d. Retry?", mds, g_current_media_number);3127 mr_free(mds);3128 res = ask_me_yes_or_no(tmp1);3129 mr_free(tmp1);3130 3131 if (!res) {3132 if (ask_me_yes_or_no("Abort the backup?")) {3133 fatal_error("FAILED TO BACKUP");3134 } else {3135 break;3136 }3137 } else {3138 log_msg(2, "Retrying, at user's request...");3139 res = 0;3140 }3141 }3142 }3143 mr_free(isofile);3144 3145 g_current_media_number++;3146 wipe_archives(bkpinfo->scratchdir);3147 mr_asprintf(tmp1, "rm -Rf %s/images/*gz %s/images/*data*img", bkpinfo->scratchdir, bkpinfo->scratchdir);3148 if (system(tmp1)) {3149 log_msg(2, "Error occurred when I tried to delete the redundant IMGs and GZs");3150 }3151 mr_free(tmp1);3152 3153 if (last_cd) {3154 log_msg(2, "This was your last media.");3155 } else {3156 log_msg(2, "Continuing to backup your data...");3157 }3158 3159 bkpinfo->verify_data = orig_vfy_flag_val;3160 return (0);3161 }3162 3163 /* @} - end of LLarchiveGroup */3164 3165 3166 3153 3167 3154 -
branches/3.3/mondo/src/common/libmondo-devices-EXT.h
r3876 r3877 24 24 extern char *make_vn(char *file); 25 25 extern int kick_vn(char *vn); 26 extern char which_boot_loader(c har *which_device);26 extern char which_boot_loader(const char *which_device); 27 27 28 28 extern int interactively_obtain_media_parameters_from_user(bool); -
branches/3.3/mondo/src/common/libmondo-devices.c
r3875 r3877 1164 1164 log_msg(3, "Mounting next media %d",cd_number_i_want); 1165 1165 g_current_media_number = cd_number_i_want; 1166 mount_media( );1166 mount_media(MNT_CDROM); 1167 1167 1168 1168 mds = media_descriptor_string(bkpinfo->backup_media_type); … … 1825 1825 1826 1826 /** 1827 * Ask user for details of backup/restore information.1828 * Called when @c mondoarchive doesn't get any parameters.1829 * @param bkpinfo The backup information structure to fill out with the user's data.1830 * @param archiving_to_media TRUE if archiving, FALSE if restoring.1831 * @return 0, always.1832 * @bug No point of `int' return value.1833 * @ingroup archiveGroup1834 */1835 int interactively_obtain_media_parameters_from_user(bool archiving_to_media)1836 // archiving_to_media is TRUE if I'm being called by mondoarchive1837 // archiving_to_media is FALSE if I'm being called by mondorestore1838 {1839 char *tmp = NULL;1840 char *sz = NULL;1841 char *tmpro = NULL;1842 char *tmp1 = NULL;1843 char *tmp2 = NULL;1844 char *mds = NULL;1845 char *oldtmp = NULL;1846 char *q = NULL;1847 char p[16*MAX_STR_LEN];1848 char *sz_size = NULL;1849 char *command = NULL;1850 char *compression_type = NULL;1851 char *comment = NULL;1852 int i;1853 FILE *fin;1854 1855 malloc_string(tmp1);1856 assert(bkpinfo != NULL);1857 bkpinfo->nonbootable_backup = FALSE;1858 1859 // Tape, CD, NETFS, ...?1860 srandom(getpid());1861 bkpinfo->backup_media_type =1862 (g_restoring_live_from_cd) ? cdr :1863 which_backup_media_type(bkpinfo->restore_data);1864 if (bkpinfo->backup_media_type == none) {1865 log_to_screen("User has chosen not to backup the machine");1866 finish(1);1867 }1868 log_msg(3, "media type = %s", bkptype_to_string(bkpinfo->backup_media_type));1869 1870 /* Why asking to remove the media with tape ?1871 if (bkpinfo->backup_media_type == tape && bkpinfo->restore_data) {1872 popup_and_OK("Please remove media from drive(s)");1873 }1874 */1875 if (archiving_to_media) {1876 // TODO: Should be common ?1877 setup_tmpdir(NULL);1878 /*1879 * Set the scratchdir to reside on the partition with the most free space.1880 * Automatically excludes DOS, NTFS, SMB, and NFS filesystems.1881 */1882 #ifdef __FreeBSD__1883 tmp = call_program_and_get_last_line_of_output("df -m -P -t nonfs,msdosfs,ntfs,ntfs-3g,vmhgfs,smbfs,smb,cifs,afs,gfs,ocfs,ocfs2,mvfs,nsspool,nssvol | grep -vE \"none|Filesystem\" | awk '{printf \"%s %s\\n\", $4, $6;}' | sort -nr | awk '{print $NF;}' | while read x ; do test -w $x && echo $x && break ; done");1884 #else1885 tmp = call_program_and_get_last_line_of_output("df -m -P -x nfs -x nfs4 -x fuse.sshfs -x fuse -x vfat -x ntfs -x ntfs-3g -x vmhgfs -x smbfs -x smb -x cifs -x afs -x gfs -x ocfs -x ocfs2 -x mvfs -x nsspool -x nssvol -x iso9660 | grep -vE \"none|Filesystem|/dev/shm\" | awk '{printf \"%s %s\\n\", $4, $6;}' | sort -nr | awk '{print $NF;}' | while read x ; do test -w $x && echo $x && break ; done");1886 #endif1887 1888 if (tmp[0] != '/') {1889 mr_asprintf(sz, "%s", tmp);1890 mr_free(tmp);1891 mr_asprintf(tmp, "/%s", sz);1892 mr_free(sz);1893 }1894 setup_scratchdir(tmp);1895 mr_free(tmp);1896 1897 if ((compression_type = which_compression_type()) == NULL) {1898 log_to_screen("User has chosen not to backup the machine");1899 finish(1);1900 }1901 1902 bkpinfo->compression_level = (bkpinfo->backup_media_type == cdstream) ? 1 : 5;1903 if ((bkpinfo->compression_level = which_compression_level()) == -1) {1904 log_to_screen("User has chosen not to backup the machine");1905 finish(1);1906 }1907 bkpinfo->cdrw_speed = (bkpinfo->backup_media_type == cdstream) ? 2 : 4;1908 bkpinfo->use_lzo = (bkpinfo->backup_media_type == cdstream) ? TRUE : FALSE;1909 }1910 mvaddstr_and_log_it(2, 0, " ");1911 1912 // Find device's /dev (or SCSI) entry1913 switch (bkpinfo->backup_media_type) {1914 case cdr:1915 case dvd:1916 case usb:1917 /* Never try to eject a USB device */1918 if (bkpinfo->backup_media_type == usb) {1919 bkpinfo->please_dont_eject = TRUE;1920 }1921 mds = media_descriptor_string(bkpinfo->backup_media_type);1922 if (bkpinfo->backup_media_type != usb) {1923 if (ask_me_yes_or_no("Is your computer a laptop type (manual insert of MondoRescue media)?")) {1924 bkpinfo->manual_cd_tray = TRUE;1925 }1926 }1927 1928 if (bkpinfo->media_device == NULL) {1929 bkpinfo->media_device = find_device(bkpinfo->backup_media_type);1930 if (bkpinfo->media_device != NULL) {1931 log_msg(1, "MondoRescue device found automatically for your %s is %s", mds, bkpinfo->media_device);1932 } else {1933 log_msg(1, "No MondoRescue device found yet for your %s", mds);1934 }1935 }1936 1937 if (archiving_to_media) {1938 if (bkpinfo->backup_media_type == dvd) {1939 strcpy(tmp1, "1");1940 mr_asprintf(sz_size, "%d", DEFAULT_DVD_DISK_SIZE); // 4.7 salesman's GB = 4.482 real GB = 4482 MB1941 log_msg(1, "Setting to DVD defaults");1942 } else {1943 strcpy(tmp1, "4");1944 mr_asprintf(sz_size, "%d", 650);1945 log_msg(1, "Setting to CD defaults");1946 }1947 1948 mr_asprintf(comment, "What speed is your %s writer?", mds);1949 if ((bkpinfo->backup_media_type != dvd) && (bkpinfo->backup_media_type != usb)) {1950 if (!popup_and_get_string("Speed", comment, tmp1, 4)) {1951 log_to_screen("User has chosen not to backup the machine");1952 mr_free(comment);1953 finish(1);1954 }1955 }1956 mr_free(comment);1957 bkpinfo->cdrw_speed = atoi(tmp1); // if DVD then this shouldn't ever be used anyway :)1958 1959 strcpy(tmp1, sz_size);1960 mr_asprintf(comment, "How much data (in Megabytes) will each %s store?", mds);1961 if (!popup_and_get_string("Size", comment, tmp1, 5)) {1962 log_to_screen("User has chosen not to backup the machine");1963 finish(1);1964 }1965 mr_asprintf(sz_size, "%s", tmp1);1966 bkpinfo->media_size = atoi(sz_size);1967 1968 if (bkpinfo->media_size <= 0) {1969 log_to_screen("User has chosen not to backup the machine");1970 finish(1);1971 }1972 }1973 /* No break because we continue even for usb */1974 case cdstream:1975 1976 // If media_device not found ask1977 if (bkpinfo->media_device == NULL) {1978 mr_asprintf(comment, "Please specify your Mondorescue %s media /dev entry", mds);1979 tmp2 = mr_popup_and_get_string("/dev entry?", comment, bkpinfo->media_device);1980 if (!tmp2) {1981 log_to_screen("User has chosen not to backup the machine");1982 finish(1);1983 } else {1984 mr_free(bkpinfo->media_device);1985 bkpinfo->media_device = tmp2;1986 }1987 }1988 log_msg(2, "%s device found at %s", mds, bkpinfo->media_device);1989 mr_asprintf(tmp, "MondoRescue thinks your %s media corresponds to %s. Is this correct?", mds, bkpinfo->media_device);1990 if (!ask_me_yes_or_no(tmp)) {1991 mr_free(bkpinfo->media_device);1992 }1993 mr_free(tmp);1994 1995 if (bkpinfo->media_device == NULL) {1996 mr_asprintf(tmp, "Please then specify your Mondorescue %s media /dev entry", mds);1997 tmp2 = mr_popup_and_get_string("/dev entry?", tmp, bkpinfo->media_device);1998 mr_free(tmp);1999 if (tmp2 == NULL) {2000 log_to_screen("User has chosen not to backup the machine");2001 finish(1);2002 } else {2003 mr_free(bkpinfo->media_device);2004 bkpinfo->media_device = tmp2;2005 }2006 }2007 mr_free(mds);2008 2009 if (bkpinfo->backup_media_type == cdstream) {2010 bkpinfo->media_size = 650;2011 }2012 break;2013 case udev:2014 if (!ask_me_yes_or_no2015 ("This option is for advanced users only. Are you sure?")) {2016 log_to_screen("User has chosen not to backup the machine");2017 finish(1);2018 }2019 case tape:2020 2021 bkpinfo->media_device = find_tape_device();2022 if (bkpinfo->media_device != NULL) {2023 if ((fin = fopen(bkpinfo->media_device, "r"))) {2024 paranoid_fclose(fin);2025 } else {2026 if (does_file_exist("/tmp/mondorestore.cfg")) {2027 read_cfg_var("/tmp/mondorestore.cfg", "media-dev", bkpinfo->media_device);2028 }2029 }2030 }2031 if (bkpinfo->media_device != NULL) {2032 mr_asprintf(tmp, "Mondorescue thinks your tape streamer at %s; is that correct?", bkpinfo->media_device);2033 if (!ask_me_yes_or_no(tmp)) {2034 mr_free(bkpinfo->media_device);2035 }2036 mr_free(tmp);2037 }2038 if (bkpinfo->media_device == NULL) {2039 tmp2 = mr_popup_and_get_string("Device name?", "What is the /dev entry of your tape streamer?", "");2040 if (tmp2 == NULL) {2041 log_to_screen("User has chosen not to backup the machine");2042 finish(1);2043 } else {2044 bkpinfo->media_device = tmp2;2045 }2046 }2047 mr_asprintf(tmp, "ls -l %s", bkpinfo->media_device);2048 if (run_program_and_log_output(tmp, FALSE)) {2049 log_to_screen("User has not specified a valid /dev entry");2050 finish(1);2051 }2052 mr_free(tmp);2053 2054 mr_asprintf(sz_size,"%ld",bkpinfo->internal_tape_block_size);2055 tmp = mr_popup_and_get_string("Tape block size?", "What is the block size of your tape streamer?", sz_size);2056 if (tmp == NULL) {2057 log_to_screen("User has chosen not to backup the machine");2058 finish(1);2059 }2060 bkpinfo->internal_tape_block_size = atol(tmp);2061 mr_free(sz_size);2062 mr_free(tmp);2063 2064 // log the block-size2065 log_msg(0,"Tape block size= %ld", bkpinfo->internal_tape_block_size);2066 2067 if (bkpinfo->internal_tape_block_size <= 0) {2068 log_to_screen("User has chosen not to backup the machine");2069 finish(1);2070 }2071 2072 bkpinfo->media_size = 0;2073 log_msg(4, "media_size = %ld", bkpinfo->media_size);2074 2075 if (archiving_to_media) {2076 bkpinfo->use_obdr = ask_me_yes_or_no("Do you want to activate OBDR support for your tapes ?");2077 if (bkpinfo->use_obdr) {2078 log_msg(4, "obdr mode = TRUE");2079 } else {2080 log_msg(4, "obdr mode = FALSE");2081 }2082 }2083 break;2084 2085 case netfs:2086 /* Never try to eject a NETFS device */2087 bkpinfo->please_dont_eject = TRUE;2088 /* Force NFS to be the protocol by default */2089 if (bkpinfo->netfs_proto == NULL) {2090 mr_asprintf(bkpinfo->netfs_proto, "nfs");2091 }2092 2093 /* Initiate bkpinfo netfs_mount path from running environment if not already done */2094 if (bkpinfo->netfs_mount == NULL) {2095 bkpinfo->netfs_mount = call_program_and_get_last_line_of_output("mount | grep \":\" | cut -d' ' -f1 | head -n1");2096 }2097 #ifdef __FreeBSD__2098 if (TRUE)2099 #else2100 if (!bkpinfo->disaster_recovery)2101 #endif2102 {2103 if (!popup_and_get_string("Network shared dir.", "Please enter path and directory where archives are stored remotely. (Mondo has taken a guess at the correct value. If it is incorrect, delete it and type the correct one.)", p,(MAX_STR_LEN / 4)-1)) {2104 log_to_screen("User has chosen not to backup the machine");2105 finish(1);2106 }2107 mr_free(bkpinfo->netfs_mount);2108 // check whether already mounted - we better remove2109 // surrounding spaces and trailing '/' for this2110 bkpinfo->netfs_mount = mr_strip_spaces(p);2111 if (bkpinfo->netfs_mount[strlen(bkpinfo->netfs_mount) - 1] == '/')2112 bkpinfo->netfs_mount[strlen(bkpinfo->netfs_mount) - 1] = '\0';2113 q = strchr(bkpinfo->netfs_mount, '@');2114 if (q != NULL) {2115 /* User found. Store the 2 values */2116 q++;2117 /* new netfs mount */2118 strcpy(tmp1,q);2119 } else {2120 strcpy(tmp1,bkpinfo->netfs_mount);2121 }2122 mr_asprintf(command, "mount | grep \"%s \" | cut -d' ' -f3", tmp1);2123 mr_free(bkpinfo->isodir);2124 bkpinfo->isodir = call_program_and_get_last_line_of_output(command);2125 mr_free(command);2126 2127 if (!bkpinfo->restore_data) {2128 mr_asprintf(sz_size, "%d", DEFAULT_DVD_DISK_SIZE); // 4.7 salesman's GB = 4.482 real GB = 4482 MB2129 mr_asprintf(comment, "How much data (in Megabytes) will each media store?");2130 strcpy(tmp1, sz_size);2131 mr_free(sz_size);2132 if (!popup_and_get_string("Size", comment, tmp1, 5)) {2133 log_to_screen("User has chosen not to backup the machine");2134 finish(1);2135 }2136 mr_free(comment);2137 mr_asprintf(sz_size, "%s", tmp1);2138 } else {2139 mr_asprintf(sz_size, "0");2140 }2141 bkpinfo->media_size = atoi(sz_size);2142 mr_free(sz_size);2143 2144 if (bkpinfo->media_size < 0) {2145 log_to_screen("User has chosen not to backup the machine");2146 finish(1);2147 }2148 }2149 /* TODO: Useless I think */2150 if (bkpinfo->disaster_recovery) {2151 mr_asprintf(command ,"umount %s/isodir 2> /dev/null", bkpinfo->tmpdir);2152 paranoid_system(command);2153 mr_free(command);2154 2155 }2156 strcpy(tmp1, bkpinfo->netfs_proto);2157 if (!popup_and_get_string("Network protocol", "Which protocol should I use (nfs/sshfs/smbfs) ?",tmp1, MAX_STR_LEN-1)) {2158 log_to_screen("User has chosen not to backup the machine");2159 finish(1);2160 }2161 mr_free(bkpinfo->netfs_proto);2162 mr_asprintf(bkpinfo->netfs_proto, "%s", tmp1);2163 2164 strcpy(tmp1, bkpinfo->netfs_mount);2165 if (!popup_and_get_string("Network share", "Which remote share should I mount?", tmp1, MAX_STR_LEN-1)) {2166 log_to_screen("User has chosen not to backup the machine");2167 finish(1);2168 }2169 mr_free(bkpinfo->netfs_mount);2170 mr_asprintf(bkpinfo->netfs_mount, "%s", tmp1);2171 2172 if (bkpinfo->netfs_user) {2173 strcpy(tmp1, bkpinfo->netfs_user);2174 } else {2175 strcpy(tmp1, "");2176 }2177 if (!popup_and_get_string("Network user", "Which user should I use if any ?",tmp1, MAX_STR_LEN-1)) {2178 log_to_screen("User has chosen not to backup the machine");2179 finish(1);2180 }2181 mr_free(bkpinfo->netfs_user);2182 if (strcmp(tmp1, "") != 0) {2183 mr_asprintf(bkpinfo->netfs_user, "%s", tmp1);2184 }2185 2186 /* Initiate bkpinfo isodir path from running environment if mount already done */2187 log_msg(3, "Testing mount for %s", bkpinfo->netfs_mount);2188 if (is_this_device_mounted(bkpinfo->netfs_mount)) {2189 mr_free(bkpinfo->isodir);2190 bkpinfo->isodir = call_program_and_get_last_line_of_output("mount | grep \":\" | cut -d' ' -f3 | head -n1");2191 } else {2192 // Why netfsdir ?2193 mr_asprintf(bkpinfo->isodir, "%s/netfsdir", bkpinfo->tmpdir);2194 mr_asprintf(command, "mkdir -p %s", bkpinfo->isodir);2195 run_program_and_log_output(command, 5);2196 mr_free(command);2197 2198 if (bkpinfo->restore_data) {2199 /* mount the FS read-only in restore mode to avoid any erase of whatever */2200 mr_asprintf(tmpro, "-o ro");2201 } else {2202 mr_asprintf(tmpro, "");2203 }2204 2205 /* Build the mount string */2206 if (strstr(bkpinfo->netfs_proto, "smbfs")) {2207 mr_asprintf(tmp, "mount -t cifs %s %s %s",bkpinfo->netfs_mount, bkpinfo->isodir,tmpro);2208 if (bkpinfo->netfs_user) {2209 mr_strcat(tmp, " -o user=%s", bkpinfo->netfs_user);2210 }2211 else {2212 if (strstr(bkpinfo->netfs_proto, "sshfs")) {2213 mr_asprintf(tmp, "sshfs %s ",tmpro);2214 } else {2215 mr_asprintf(tmp, "mount -t %s -o nolock %s ", bkpinfo->netfs_proto,tmpro);2216 }2217 if (bkpinfo->netfs_user) {2218 mr_strcat(tmp, "%s@", bkpinfo->netfs_user);2219 }2220 mr_strcat(tmp, "%s %s", bkpinfo->netfs_mount, bkpinfo->isodir);2221 }2222 run_program_and_log_output(tmp, 3);2223 mr_free(tmp);2224 2225 malloc_string(g_selfmounted_isodir);2226 strcpy(g_selfmounted_isodir, bkpinfo->isodir);2227 }2228 }2229 2230 log_msg(3, "Testing mount for %s", bkpinfo->netfs_mount);2231 if (!is_this_device_mounted(bkpinfo->netfs_mount)) {2232 popup_and_OK("Please mount that partition before you try to backup to or restore from it.");2233 finish(1);2234 }2235 if (bkpinfo->netfs_remote_dir == NULL) {2236 fatal_error("bkpinfo->netfs_remote_dir should not be NULL");2237 }2238 strcpy(tmp1, bkpinfo->netfs_remote_dir);2239 if (!popup_and_get_string ("Directory", "Which directory within that mountpoint?", tmp1, MAX_STR_LEN-1)) {2240 log_to_screen("User has chosen not to backup the machine");2241 finish(1);2242 }2243 mr_free(bkpinfo->netfs_remote_dir);2244 // check whether writable - we better remove surrounding spaces for this2245 bkpinfo->netfs_remote_dir = mr_strip_spaces(tmp1);2246 2247 tmp = mr_popup_and_get_string("Prefix.", "Please enter the prefix that will be prepended to your ISO filename. Example: machine1 to obtain machine1-[1-9]*.iso files", bkpinfo->prefix);2248 if (tmp == NULL) {2249 log_to_screen("User has chosen not to backup the machine");2250 finish(1);2251 }2252 mr_free(bkpinfo->prefix);2253 bkpinfo->prefix = tmp;2254 log_msg(3, "prefix set to %s", bkpinfo->prefix);2255 log_msg(3, "Just set netfs_remote_dir to %s", bkpinfo->netfs_remote_dir);2256 log_msg(3, "isodir is still %s", bkpinfo->isodir);2257 break;2258 2259 case iso:2260 if (!bkpinfo->disaster_recovery) {2261 tmp = mr_popup_and_get_string("Storage dir.", "Please enter the full path name to the directory for your ISO images. Example: /mnt/raid0_0", bkpinfo->isodir);2262 if (tmp == NULL) {2263 log_to_screen("User has chosen not to backup the machine");2264 finish(1);2265 } else {2266 mr_free(bkpinfo->isodir);2267 bkpinfo->isodir = tmp;2268 }2269 if (archiving_to_media) {2270 sprintf(tmp1, "%d", DEFAULT_DVD_DISK_SIZE); // 4.7 salesman's GB = 4.482 real GB = 4482 MB2271 if (!popup_and_get_string("ISO size.", "Please enter how big you want each ISO image to be (in megabytes). This should be less than or equal to the size of the CD-R[W]'s (700) or DVD's (4480) you plan to backup to.", tmp1, 16)) {2272 log_to_screen("User has chosen not to backup the machine");2273 finish(1);2274 }2275 bkpinfo->media_size = atoi(tmp1);2276 } else {2277 bkpinfo->media_size = 650;2278 }2279 }2280 tmp = mr_popup_and_get_string("Prefix.", "Please enter the prefix that will be prepended to your ISO filename. Example: machine1 to obtain machine1-[1-9]*.iso files", bkpinfo->prefix);2281 if (tmp == NULL) {2282 log_to_screen("User has chosen not to backup the machine");2283 finish(1);2284 }2285 mr_free(bkpinfo->prefix);2286 bkpinfo->prefix = tmp;2287 log_msg(3, "prefix set to %s", bkpinfo->prefix);2288 break;2289 default:2290 fatal_error("I, Mojo Jojo, shall defeat those pesky Powerpuff Girls!");2291 }2292 2293 if (archiving_to_media) {2294 /* Needs to be done before calling which_boot_loader */2295 bkpinfo->boot_type = mr_boot_type();2296 mr_free(bkpinfo->boot_device);2297 #ifdef __FreeBSD__2298 bkpinfo->boot_device = call_program_and_get_last_line_of_output("mount | grep ' / ' | head -1 | cut -d' ' -f1 | sed 's/\\([0-9]\\).*/\\1/'");2299 #else2300 bkpinfo->boot_device = call_program_and_get_last_line_of_output("mount | grep ' / ' | head -1 | cut -d' ' -f1 | sed 's/[0-9].*//'");2301 #endif2302 i = which_boot_loader(bkpinfo->boot_device);2303 if (i == 'U') // unknown2304 {2305 2306 #ifdef __FreeBSD__2307 if (!popup_and_get_string("Boot device", "What is your boot device? (e.g. /dev/ad0)", bkpinfo->boot_device,(MAX_STR_LEN / 4)-1)) {2308 log_to_screen("User has chosen not to backup the machine");2309 finish(1);2310 }2311 i = which_boot_loader(bkpinfo->boot_device);2312 #else2313 strcpy(tmp1, bkpinfo->boot_device);2314 if (!popup_and_get_string("Boot device", "What is your boot device? (e.g. /dev/hda)", tmp1,(MAX_STR_LEN / 4)-1)) {2315 log_to_screen("User has chosen not to backup the machine");2316 finish(1);2317 }2318 mr_free(bkpinfo->boot_device);2319 mr_asprintf(bkpinfo->boot_device, "%s", tmp1);2320 2321 if (does_string_exist_in_boot_block(bkpinfo->boot_device, "ELILO")) {2322 i = 'E';2323 } else2324 if (does_string_exist_in_boot_block(bkpinfo->boot_device, "LILO")) {2325 i = 'L';2326 } else2327 if (does_string_exist_in_boot_block(bkpinfo->boot_device, "GRUB")) {2328 i = 'G';2329 } else {2330 i = 'U';2331 }2332 #endif2333 if (i == 'U') {2334 if (ask_me_yes_or_no("Unidentified boot loader. Shall I restore it byte-for-byte at restore time and hope for the best?")) {2335 i = 'R'; // raw2336 } else {2337 log_to_screen("I cannot find your boot loader. Please run mondoarchive with parameters.");2338 finish(1);2339 }2340 }2341 }2342 bkpinfo->boot_loader = i;2343 /* TODO: Check consistency of boot type and boot loader */2344 2345 if (bkpinfo->include_paths) {2346 strcpy(tmp1, bkpinfo->include_paths);2347 mr_free(bkpinfo->include_paths);2348 } else {2349 strcpy(tmp1, "/");2350 }2351 if (!popup_and_get_string("Backup paths", "Please enter paths (separated by '|') which you want me to backup. The default is '/' (i.e. everything).", tmp1, MAX_STR_LEN-1)) {2352 log_to_screen("User has chosen not to backup the machine");2353 finish(1);2354 }2355 mr_asprintf(bkpinfo->include_paths, "%s", tmp1);2356 2357 tmp = list_of_NETFS_mounts_only();2358 if (strlen(tmp) > 2) {2359 mr_strcat(bkpinfo->exclude_paths, "|%s",tmp);2360 }2361 mr_free(tmp);2362 // NTFS2363 tmp = call_program_and_get_last_line_of_output("mr-parted2fdisk -l 2>/dev/null | grep -i ntfs | awk '{ print $1};' | tr -s '\\n' ' ' | awk '{ print $0};'");2364 strncpy(tmp1, tmp,(MAX_STR_LEN / 4)-1);2365 mr_free(tmp);2366 if (strlen(tmp1) > 2) {2367 if (!popup_and_get_string("NTFS partitions", "Please enter/confirm the NTFS partitions you wish to backup as well.", tmp1,(MAX_STR_LEN / 4)-1)) {2368 log_to_screen("User has chosen not to backup the machine");2369 finish(1);2370 }2371 mr_asprintf(bkpinfo->image_devs, "%s", tmp1);2372 }2373 2374 if (bkpinfo->exclude_paths != NULL ) {2375 mr_asprintf(p, "%s", bkpinfo->exclude_paths);2376 } else {2377 mr_asprintf(p, "%s", "");2378 }2379 tmp = mr_popup_and_get_string("Exclude paths", "Please enter paths which you do NOT want to backup. Separate them with '|'. NB: /tmp and /proc are always excluded. :-) Just hit 'Enter' if you want to do a full system backup.", p);2380 mr_free(p);2381 if (tmp == NULL) {2382 log_to_screen("User has chosen not to backup the machine");2383 finish(1);2384 }2385 mr_free(bkpinfo->exclude_paths);2386 bkpinfo->exclude_paths = tmp;2387 2388 mr_asprintf(oldtmp, "%s", bkpinfo->tmpdir);2389 if (bkpinfo->tmpdir != NULL ) {2390 mr_asprintf(p, "%s", bkpinfo->tmpdir);2391 } else {2392 mr_asprintf(p, "%s", "");2393 }2394 tmp = mr_popup_and_get_string("Temporary directory", "Please enter your temporary directory.", p);2395 mr_free(p);2396 if (tmp == NULL) {2397 mr_free(oldtmp);2398 log_to_screen("User has chosen not to backup the machine");2399 finish(1);2400 }2401 /* if modified to another path */2402 if (strcmp(tmp,oldtmp) != 0) {2403 setup_tmpdir(tmp);2404 }2405 mr_free(oldtmp);2406 2407 mr_asprintf(oldtmp, "%s", bkpinfo->scratchdir);2408 if (bkpinfo->scratchdir != NULL ) {2409 mr_asprintf(p, "%s", bkpinfo->scratchdir);2410 } else {2411 mr_asprintf(p, "%s", "");2412 }2413 tmp = mr_popup_and_get_string("Scratch directory", "Please enter your scratch directory.", p);2414 mr_free(p);2415 if (tmp == NULL) {2416 mr_free(oldtmp);2417 log_to_screen("User has chosen not to backup the machine");2418 finish(1);2419 }2420 /* if modified to another path */2421 if (strcmp(tmp,oldtmp) != 0) {2422 setup_scratchdir(tmp);2423 }2424 mr_free(oldtmp);2425 2426 if (ask_me_yes_or_no("Do you want to backup extended attributes?")) {2427 mr_free(g_getfattr);2428 g_getfattr = find_home_of_exe("getfattr");2429 mr_free(g_getfacl);2430 g_getfacl = find_home_of_exe("getfacl");2431 log_it("Backup of extended attributes");2432 }2433 // Interactive mode:2434 #ifdef __IA64__2435 bkpinfo->make_cd_use_lilo = TRUE;2436 #else2437 bkpinfo->make_cd_use_lilo = FALSE;2438 #endif2439 bkpinfo->backup_data = TRUE;2440 if (strcmp(compression_type,"lzo") == 0) {2441 mr_asprintf(bkpinfo->zip_exe, "%s", "lzop");2442 mr_asprintf(bkpinfo->zip_suffix, "%s", "lzo");2443 } else if (strcmp(compression_type,"gzip") == 0) {2444 mr_asprintf(bkpinfo->zip_exe, "%s", "gzip");2445 mr_asprintf(bkpinfo->zip_suffix, "%s", "gz");2446 } else if (strcmp(compression_type,"lzma") == 0) {2447 mr_asprintf(bkpinfo->zip_exe, "%s", "xz");2448 mr_asprintf(bkpinfo->zip_suffix, "%s", "xz");2449 } else if (strcmp(compression_type,"bzip2") == 0) {2450 mr_asprintf(bkpinfo->zip_exe, "%s", "bzip2");2451 mr_asprintf(bkpinfo->zip_suffix, "%s", "bz2");2452 } else {2453 mr_free(bkpinfo->zip_exe);2454 mr_free(bkpinfo->zip_suffix);2455 }2456 mr_free(compression_type);2457 2458 #if __FreeBSD__ == 52459 mr_asprintf(bkpinfo->kernel_path, "%s", "/boot/kernel/kernel");2460 #elif __FreeBSD__ == 42461 mr_asprintf(bkpinfo->kernel_path, "%s", "/kernel");2462 #elif linux2463 if (figure_out_kernel_path_interactively_if_necessary(bkpinfo->kernel_path)) {2464 fatal_error("Kernel not found. Please specify manually with the '-k' switch.");2465 }2466 #else2467 #error "I don't know about this system!"2468 #endif2469 2470 2471 bkpinfo->verify_data =2472 ask_me_yes_or_no2473 ("Will you want to verify your backups after Mondo has created them?");2474 2475 if (!ask_me_yes_or_no2476 ("Are you sure you want to proceed? Hit 'no' to abort.")) {2477 log_to_screen("User has chosen not to backup the machine");2478 finish(1);2479 }2480 } else {2481 bkpinfo->restore_data = TRUE; // probably...2482 }2483 2484 if (bkpinfo->backup_media_type == iso2485 || bkpinfo->backup_media_type == netfs) {2486 g_ISO_restore_mode = TRUE;2487 }2488 #ifdef __FreeSD__2489 // skip2490 #else2491 if (bkpinfo->backup_media_type == netfs) {2492 log_msg(3, "I think the Remote mount is mounted at %s", bkpinfo->isodir);2493 }2494 log_it("isodir = %s", bkpinfo->isodir);2495 if (bkpinfo->netfs_mount) {2496 log_it("netfs_mount = '%s'", bkpinfo->netfs_mount);2497 }2498 if (bkpinfo->netfs_user) {2499 log_it("netfs_user = '%s'", bkpinfo->netfs_user);2500 }2501 if (bkpinfo->netfs_proto) {2502 log_it("netfs_proto = '%s'", bkpinfo->netfs_proto);2503 }2504 #endif2505 2506 log_it("media device = %s", bkpinfo->media_device);2507 log_it("media size = %ld", bkpinfo->media_size);2508 log_it("media type = %s", bkptype_to_string(bkpinfo->backup_media_type));2509 if (bkpinfo->prefix != NULL) {2510 log_it("prefix = %s", bkpinfo->prefix);2511 }2512 log_it("compression = %ld", bkpinfo->compression_level);2513 log_it("exclude_path = %s", bkpinfo->exclude_paths);2514 if (bkpinfo->include_paths) {2515 log_it("include_path = %s", bkpinfo->include_paths);2516 }2517 2518 /* Handle devices passed in bkpinfo and print result */2519 /* the mr_make_devlist_from_pathlist function appends */2520 /* to the *_paths variables so copy before */2521 mr_make_devlist_from_pathlist(bkpinfo->exclude_paths, 'E');2522 mr_make_devlist_from_pathlist(bkpinfo->include_paths, 'I');2523 2524 log_it("scratchdir = '%s'", bkpinfo->scratchdir);2525 log_it("tmpdir = '%s'", bkpinfo->tmpdir);2526 if (bkpinfo->image_devs) {2527 log_it("image_devs = '%s'", bkpinfo->image_devs);2528 }2529 log_it("boot_device = '%s' (loader=%c)", bkpinfo->boot_device, bkpinfo->boot_loader);2530 if (bkpinfo->media_size < 0) {2531 if (archiving_to_media) {2532 fatal_error("Media size is less than zero.");2533 } else {2534 log_msg(2, "Warning - media size is less than zero.");2535 bkpinfo->media_size = 0;2536 }2537 }2538 paranoid_free(sz_size);2539 paranoid_free(tmp1);2540 return (0);2541 }2542 2543 2544 /**2545 * Get a |-separated list of NETFS mounts.2546 * @return The list created.2547 * @note The return value points to allocated string that needs to be freed by2548 * caller2549 * @bug Even though we only want the mounts, the devices are still checked.2550 */2551 char *list_of_NETFS_mounts_only(void)2552 {2553 char *exclude_these_directories = NULL;2554 2555 exclude_these_directories = call_program_and_get_last_line_of_output("mount -t coda,ncpfs,fuse.sshfs,nfs,nfs4,vmhgfs,smbfs,cifs,afs,gfs,ocfs,ocfs2,mvfs,nsspool,nssvol,fuse.boostfs | tr -s '\t' ' ' | cut -d' ' -f3 | tr -s '\n' '|' | awk '{print $0;}'");2556 log_msg(9,"list_of_NETFS_mounts_only returns %s",exclude_these_directories);2557 return(exclude_these_directories);2558 }2559 2560 /* @} - end of utilityGroup */2561 2562 2563 2564 2565 2566 /**2567 * Create a randomly-named FIFO. The format is @p stub "." [random] [random] where2568 * [random] is a random number between 1 and 32767.2569 * @param store_name_here Where to store the new filename.2570 * @param stub A random number will be appended to this to make the FIFO's name.2571 * @ingroup deviceGroup2572 */2573 void make_fifo(char *store_name_here, char *stub)2574 {2575 char *tmp = NULL;2576 2577 assert_string_is_neither_NULL_nor_zerolength(stub);2578 2579 sprintf(store_name_here, "%s%d%d", stub, (int) (random() % 32768),2580 (int) (random() % 32768));2581 make_hole_for_file(store_name_here);2582 mkfifo(store_name_here, S_IRWXU | S_IRWXG);2583 mr_asprintf(tmp, "chmod 770 %s", store_name_here);2584 paranoid_system(tmp);2585 mr_free(tmp);2586 }2587 2588 2589 2590 /**2591 * @addtogroup deviceGroup2592 * @{2593 */2594 /**2595 * If we can read @p dev, set @p output to it.2596 * If @p dev cannot be read, set @p output to "".2597 * @param dev The device to check for.2598 * @param output Set to @p dev if @p dev exists, "" otherwise.2599 * @return TRUE if @p dev exists, FALSE if it doesn't.2600 */2601 bool set_dev_to_this_if_rx_OK(char *output, char *dev)2602 {2603 char *command = NULL;2604 bool ret=FALSE;2605 2606 if (!dev || dev[0] == '\0') {2607 output[0] = '\0';2608 return(ret);2609 }2610 // assert_string_is_neither_NULL_nor_zerolength(dev);2611 if (!bkpinfo->please_dont_eject) {2612 log_msg(10, "Injecting %s", dev);2613 inject_device(dev);2614 }2615 if (!does_file_exist(dev)) {2616 log_msg(10, "%s doesn't exist. Returning FALSE.", dev);2617 return(ret);2618 }2619 mr_asprintf(command, "dd bs=%ld count=1 if=%s of=/dev/null &> /dev/null", 512L, dev);2620 if (!run_program_and_log_output(command, FALSE) && !run_program_and_log_output(command, FALSE)) {2621 strcpy(output, dev);2622 log_msg(4, "Found it - %s", dev);2623 ret = TRUE;2624 } else {2625 output[0] = '\0';2626 log_msg(4, "It's not %s", dev);2627 }2628 mr_free(command);2629 return(ret);2630 }2631 2632 2633 2634 2635 2636 /**2637 * Find out what number CD is in the drive.2638 * @param bkpinfo The backup information structure. The @c bkpinfo->media_device field is the only one used.2639 * @return The current CD number, or -1 if it could not be found.2640 * @note If the CD is not mounted, it will be mounted2641 * (and remain mounted after this function returns).2642 */2643 int what_number_cd_is_this(void) {2644 2645 int cd_number = -1;2646 char *mountdev = NULL;2647 char *tmp = NULL;2648 2649 assert(bkpinfo != NULL);2650 // log_it("Asking what_number_cd_is_this");2651 if ((g_ISO_restore_mode) || (g_restoring_live_from_cd)) {2652 tmp = call_program_and_get_last_line_of_output("mount | grep iso9660 | awk '{print $3;}'");2653 mr_asprintf(mountdev, "%s%s", tmp, "/archives/THIS-CD-NUMBER");2654 mr_free(tmp);2655 cd_number = atoi(last_line_of_file(mountdev));2656 mr_free(mountdev);2657 return (cd_number);2658 }2659 2660 if ((bkpinfo->media_device == NULL) || !does_file_exist(bkpinfo->media_device)) {2661 log_it("ERROR: bkpinfo->media_device shoulnd't be unaccessible here\n");2662 /* trying again ! */2663 bkpinfo->media_device = find_optical_device();2664 }2665 if ((bkpinfo->media_device == NULL) || !does_file_exist(bkpinfo->media_device)) {2666 fatal_error("ERROR: bkpinfo->media_device shoulnd't really be unaccessible here\n");2667 }2668 if (!is_this_device_mounted(bkpinfo->media_device, MNT_CDROM)) {2669 mount_media(MNT_CDROM);2670 }2671 2672 cd_number = atoi(last_line_of_file(MNT_CDROM "/archives/THIS-CD-NUMBER"));2673 return(cd_number);2674 }2675 2676 2677 /**2678 * Find out what device is mounted as root (/).2679 * @return Root device.2680 * @note The returned string points to storage that needs to be freed by2681 * caller2682 * @bug A bit of a misnomer; it's actually finding out the root device.2683 * The mountpoint (where it's mounted) will obviously be '/'.2684 */2685 char *where_is_root_mounted() {2686 2687 /*@ buffers **************** */2688 char *tmp = NULL;2689 2690 #ifdef __FreeBSD__2691 tmp = call_program_and_get_last_line_of_output("mount | grep \" on / \" | cut -d' ' -f1");2692 #else2693 tmp = call_program_and_get_last_line_of_output("mount | grep \" on / \" | cut -d' ' -f1 | sed s/[0-9]// | sed s/[0-9]//");2694 if (strstr(tmp, "/dev/cciss/")) {2695 mr_free(tmp);2696 tmp = call_program_and_get_last_line_of_output("mount | grep \" on / \" | cut -d' ' -f1 | cut -dp -f1");2697 }2698 if (strstr(tmp, "/dev/md")) {2699 mr_free(tmp);2700 tmp = call_program_and_get_last_line_of_output("mount | grep \" on / \" | cut -d' ' -f1");2701 }2702 #endif2703 2704 return (tmp);2705 }2706 2707 2708 /**2709 1827 * Find out which boot loader is in use. 2710 1828 * @param which_device Device to look for the boot loader on. … … 2713 1831 */ 2714 1832 #ifdef __FreeBSD__ 2715 char which_boot_loader(c har *which_device)1833 char which_boot_loader(const char *which_device) 2716 1834 { 2717 1835 int count_lilos = 0; … … 2757 1875 #else 2758 1876 2759 char which_boot_loader(c har *which_device)1877 char which_boot_loader(const char *which_device) 2760 1878 { 2761 1879 /*@ buffer ***************************************************** */ … … 2879 1997 } 2880 1998 #endif 1999 2000 2001 /** 2002 * Ask user for details of backup/restore information. 2003 * Called when @c mondoarchive doesn't get any parameters. 2004 * @param bkpinfo The backup information structure to fill out with the user's data. 2005 * @param archiving_to_media TRUE if archiving, FALSE if restoring. 2006 * @return 0, always. 2007 * @bug No point of `int' return value. 2008 * @ingroup archiveGroup 2009 */ 2010 int interactively_obtain_media_parameters_from_user(bool archiving_to_media) 2011 // archiving_to_media is TRUE if I'm being called by mondoarchive 2012 // archiving_to_media is FALSE if I'm being called by mondorestore 2013 { 2014 char *tmp = NULL; 2015 char *sz = NULL; 2016 char *tmpro = NULL; 2017 char *tmp1 = NULL; 2018 char *tmp2 = NULL; 2019 char *mds = NULL; 2020 char *oldtmp = NULL; 2021 char *q = NULL; 2022 char p[16*MAX_STR_LEN]; 2023 char *sz_size = NULL; 2024 char *command = NULL; 2025 char *compression_type = NULL; 2026 char *comment = NULL; 2027 char i = '\0'; 2028 FILE *fin; 2029 2030 malloc_string(tmp1); 2031 assert(bkpinfo != NULL); 2032 bkpinfo->nonbootable_backup = FALSE; 2033 2034 // Tape, CD, NETFS, ...? 2035 srandom(getpid()); 2036 bkpinfo->backup_media_type = 2037 (g_restoring_live_from_cd) ? cdr : 2038 which_backup_media_type(bkpinfo->restore_data); 2039 if (bkpinfo->backup_media_type == none) { 2040 log_to_screen("User has chosen not to backup the machine"); 2041 finish(1); 2042 } 2043 log_msg(3, "media type = %s", bkptype_to_string(bkpinfo->backup_media_type)); 2044 2045 /* Why asking to remove the media with tape ? 2046 if (bkpinfo->backup_media_type == tape && bkpinfo->restore_data) { 2047 popup_and_OK("Please remove media from drive(s)"); 2048 } 2049 */ 2050 if (archiving_to_media) { 2051 // TODO: Should be common ? 2052 setup_tmpdir(NULL); 2053 /* 2054 * Set the scratchdir to reside on the partition with the most free space. 2055 * Automatically excludes DOS, NTFS, SMB, and NFS filesystems. 2056 */ 2057 #ifdef __FreeBSD__ 2058 tmp = call_program_and_get_last_line_of_output("df -m -P -t nonfs,msdosfs,ntfs,ntfs-3g,vmhgfs,smbfs,smb,cifs,afs,gfs,ocfs,ocfs2,mvfs,nsspool,nssvol | grep -vE \"none|Filesystem\" | awk '{printf \"%s %s\\n\", $4, $6;}' | sort -nr | awk '{print $NF;}' | while read x ; do test -w $x && echo $x && break ; done"); 2059 #else 2060 tmp = call_program_and_get_last_line_of_output("df -m -P -x nfs -x nfs4 -x fuse.sshfs -x fuse -x vfat -x ntfs -x ntfs-3g -x vmhgfs -x smbfs -x smb -x cifs -x afs -x gfs -x ocfs -x ocfs2 -x mvfs -x nsspool -x nssvol -x iso9660 | grep -vE \"none|Filesystem|/dev/shm\" | awk '{printf \"%s %s\\n\", $4, $6;}' | sort -nr | awk '{print $NF;}' | while read x ; do test -w $x && echo $x && break ; done"); 2061 #endif 2062 2063 if (tmp[0] != '/') { 2064 mr_asprintf(sz, "%s", tmp); 2065 mr_free(tmp); 2066 mr_asprintf(tmp, "/%s", sz); 2067 mr_free(sz); 2068 } 2069 setup_scratchdir(tmp); 2070 mr_free(tmp); 2071 2072 if ((compression_type = which_compression_type()) == NULL) { 2073 log_to_screen("User has chosen not to backup the machine"); 2074 finish(1); 2075 } 2076 2077 bkpinfo->compression_level = (bkpinfo->backup_media_type == cdstream) ? 1 : 5; 2078 if ((bkpinfo->compression_level = which_compression_level()) == -1) { 2079 log_to_screen("User has chosen not to backup the machine"); 2080 finish(1); 2081 } 2082 bkpinfo->cdrw_speed = (bkpinfo->backup_media_type == cdstream) ? 2 : 4; 2083 bkpinfo->use_lzo = (bkpinfo->backup_media_type == cdstream) ? TRUE : FALSE; 2084 } 2085 mvaddstr_and_log_it(2, 0, " "); 2086 2087 // Find device's /dev (or SCSI) entry 2088 switch (bkpinfo->backup_media_type) { 2089 case cdr: 2090 case dvd: 2091 case usb: 2092 /* Never try to eject a USB device */ 2093 if (bkpinfo->backup_media_type == usb) { 2094 bkpinfo->please_dont_eject = TRUE; 2095 } 2096 mds = media_descriptor_string(bkpinfo->backup_media_type); 2097 if (bkpinfo->backup_media_type != usb) { 2098 if (ask_me_yes_or_no("Is your computer a laptop type (manual insert of MondoRescue media)?")) { 2099 bkpinfo->manual_cd_tray = TRUE; 2100 } 2101 } 2102 2103 if (bkpinfo->media_device == NULL) { 2104 bkpinfo->media_device = find_device(bkpinfo->backup_media_type); 2105 if (bkpinfo->media_device != NULL) { 2106 log_msg(1, "MondoRescue device found automatically for your %s is %s", mds, bkpinfo->media_device); 2107 } else { 2108 log_msg(1, "No MondoRescue device found yet for your %s", mds); 2109 } 2110 } 2111 2112 if (archiving_to_media) { 2113 if (bkpinfo->backup_media_type == dvd) { 2114 strcpy(tmp1, "1"); 2115 mr_asprintf(sz_size, "%d", DEFAULT_DVD_DISK_SIZE); // 4.7 salesman's GB = 4.482 real GB = 4482 MB 2116 log_msg(1, "Setting to DVD defaults"); 2117 } else { 2118 strcpy(tmp1, "4"); 2119 mr_asprintf(sz_size, "%d", 650); 2120 log_msg(1, "Setting to CD defaults"); 2121 } 2122 2123 mr_asprintf(comment, "What speed is your %s writer?", mds); 2124 if ((bkpinfo->backup_media_type != dvd) && (bkpinfo->backup_media_type != usb)) { 2125 if (!popup_and_get_string("Speed", comment, tmp1, 4)) { 2126 log_to_screen("User has chosen not to backup the machine"); 2127 mr_free(comment); 2128 finish(1); 2129 } 2130 } 2131 mr_free(comment); 2132 bkpinfo->cdrw_speed = atoi(tmp1); // if DVD then this shouldn't ever be used anyway :) 2133 2134 strcpy(tmp1, sz_size); 2135 mr_asprintf(comment, "How much data (in Megabytes) will each %s store?", mds); 2136 if (!popup_and_get_string("Size", comment, tmp1, 5)) { 2137 log_to_screen("User has chosen not to backup the machine"); 2138 finish(1); 2139 } 2140 mr_asprintf(sz_size, "%s", tmp1); 2141 bkpinfo->media_size = atoi(sz_size); 2142 2143 if (bkpinfo->media_size <= 0) { 2144 log_to_screen("User has chosen not to backup the machine"); 2145 finish(1); 2146 } 2147 } 2148 /* No break because we continue even for usb */ 2149 case cdstream: 2150 2151 // If media_device not found ask 2152 if (bkpinfo->media_device == NULL) { 2153 mr_asprintf(comment, "Please specify your Mondorescue %s media /dev entry", mds); 2154 tmp2 = mr_popup_and_get_string("/dev entry?", comment, bkpinfo->media_device); 2155 if (!tmp2) { 2156 log_to_screen("User has chosen not to backup the machine"); 2157 finish(1); 2158 } else { 2159 mr_free(bkpinfo->media_device); 2160 bkpinfo->media_device = tmp2; 2161 } 2162 } 2163 log_msg(2, "%s device found at %s", mds, bkpinfo->media_device); 2164 mr_asprintf(tmp, "MondoRescue thinks your %s media corresponds to %s. Is this correct?", mds, bkpinfo->media_device); 2165 if (!ask_me_yes_or_no(tmp)) { 2166 mr_free(bkpinfo->media_device); 2167 } 2168 mr_free(tmp); 2169 2170 if (bkpinfo->media_device == NULL) { 2171 mr_asprintf(tmp, "Please then specify your Mondorescue %s media /dev entry", mds); 2172 tmp2 = mr_popup_and_get_string("/dev entry?", tmp, bkpinfo->media_device); 2173 mr_free(tmp); 2174 if (tmp2 == NULL) { 2175 log_to_screen("User has chosen not to backup the machine"); 2176 finish(1); 2177 } else { 2178 mr_free(bkpinfo->media_device); 2179 bkpinfo->media_device = tmp2; 2180 } 2181 } 2182 mr_free(mds); 2183 2184 if (bkpinfo->backup_media_type == cdstream) { 2185 bkpinfo->media_size = 650; 2186 } 2187 break; 2188 case udev: 2189 if (!ask_me_yes_or_no 2190 ("This option is for advanced users only. Are you sure?")) { 2191 log_to_screen("User has chosen not to backup the machine"); 2192 finish(1); 2193 } 2194 case tape: 2195 2196 bkpinfo->media_device = find_tape_device(); 2197 if (bkpinfo->media_device != NULL) { 2198 if ((fin = fopen(bkpinfo->media_device, "r"))) { 2199 paranoid_fclose(fin); 2200 } else { 2201 if (does_file_exist("/tmp/mondorestore.cfg")) { 2202 read_cfg_var("/tmp/mondorestore.cfg", "media-dev", bkpinfo->media_device); 2203 } 2204 } 2205 } 2206 if (bkpinfo->media_device != NULL) { 2207 mr_asprintf(tmp, "Mondorescue thinks your tape streamer at %s; is that correct?", bkpinfo->media_device); 2208 if (!ask_me_yes_or_no(tmp)) { 2209 mr_free(bkpinfo->media_device); 2210 } 2211 mr_free(tmp); 2212 } 2213 if (bkpinfo->media_device == NULL) { 2214 tmp2 = mr_popup_and_get_string("Device name?", "What is the /dev entry of your tape streamer?", ""); 2215 if (tmp2 == NULL) { 2216 log_to_screen("User has chosen not to backup the machine"); 2217 finish(1); 2218 } else { 2219 bkpinfo->media_device = tmp2; 2220 } 2221 } 2222 mr_asprintf(tmp, "ls -l %s", bkpinfo->media_device); 2223 if (run_program_and_log_output(tmp, FALSE)) { 2224 log_to_screen("User has not specified a valid /dev entry"); 2225 finish(1); 2226 } 2227 mr_free(tmp); 2228 2229 mr_asprintf(sz_size,"%ld",bkpinfo->internal_tape_block_size); 2230 tmp = mr_popup_and_get_string("Tape block size?", "What is the block size of your tape streamer?", sz_size); 2231 if (tmp == NULL) { 2232 log_to_screen("User has chosen not to backup the machine"); 2233 finish(1); 2234 } 2235 bkpinfo->internal_tape_block_size = atol(tmp); 2236 mr_free(sz_size); 2237 mr_free(tmp); 2238 2239 // log the block-size 2240 log_msg(0,"Tape block size= %ld", bkpinfo->internal_tape_block_size); 2241 2242 if (bkpinfo->internal_tape_block_size <= 0) { 2243 log_to_screen("User has chosen not to backup the machine"); 2244 finish(1); 2245 } 2246 2247 bkpinfo->media_size = 0; 2248 log_msg(4, "media_size = %ld", bkpinfo->media_size); 2249 2250 if (archiving_to_media) { 2251 bkpinfo->use_obdr = ask_me_yes_or_no("Do you want to activate OBDR support for your tapes ?"); 2252 if (bkpinfo->use_obdr) { 2253 log_msg(4, "obdr mode = TRUE"); 2254 } else { 2255 log_msg(4, "obdr mode = FALSE"); 2256 } 2257 } 2258 break; 2259 2260 case netfs: 2261 /* Never try to eject a NETFS device */ 2262 bkpinfo->please_dont_eject = TRUE; 2263 /* Force NFS to be the protocol by default */ 2264 if (bkpinfo->netfs_proto == NULL) { 2265 mr_asprintf(bkpinfo->netfs_proto, "nfs"); 2266 } 2267 2268 /* Initiate bkpinfo netfs_mount path from running environment if not already done */ 2269 if (bkpinfo->netfs_mount == NULL) { 2270 bkpinfo->netfs_mount = call_program_and_get_last_line_of_output("mount | grep \":\" | cut -d' ' -f1 | head -n1"); 2271 } 2272 #ifdef __FreeBSD__ 2273 if (TRUE) 2274 #else 2275 if (!bkpinfo->disaster_recovery) 2276 #endif 2277 { 2278 if (!popup_and_get_string("Network shared dir.", "Please enter path and directory where archives are stored remotely. (Mondo has taken a guess at the correct value. If it is incorrect, delete it and type the correct one.)", p,(MAX_STR_LEN / 4)-1)) { 2279 log_to_screen("User has chosen not to backup the machine"); 2280 finish(1); 2281 } 2282 mr_free(bkpinfo->netfs_mount); 2283 // check whether already mounted - we better remove 2284 // surrounding spaces and trailing '/' for this 2285 bkpinfo->netfs_mount = mr_strip_spaces(p); 2286 if (bkpinfo->netfs_mount[strlen(bkpinfo->netfs_mount) - 1] == '/') 2287 bkpinfo->netfs_mount[strlen(bkpinfo->netfs_mount) - 1] = '\0'; 2288 q = strchr(bkpinfo->netfs_mount, '@'); 2289 if (q != NULL) { 2290 /* User found. Store the 2 values */ 2291 q++; 2292 /* new netfs mount */ 2293 strcpy(tmp1,q); 2294 } else { 2295 strcpy(tmp1,bkpinfo->netfs_mount); 2296 } 2297 mr_asprintf(command, "mount | grep \"%s \" | cut -d' ' -f3", tmp1); 2298 mr_free(bkpinfo->isodir); 2299 bkpinfo->isodir = call_program_and_get_last_line_of_output(command); 2300 mr_free(command); 2301 2302 if (!bkpinfo->restore_data) { 2303 mr_asprintf(sz_size, "%d", DEFAULT_DVD_DISK_SIZE); // 4.7 salesman's GB = 4.482 real GB = 4482 MB 2304 mr_asprintf(comment, "How much data (in Megabytes) will each media store?"); 2305 strcpy(tmp1, sz_size); 2306 mr_free(sz_size); 2307 if (!popup_and_get_string("Size", comment, tmp1, 5)) { 2308 log_to_screen("User has chosen not to backup the machine"); 2309 finish(1); 2310 } 2311 mr_free(comment); 2312 mr_asprintf(sz_size, "%s", tmp1); 2313 } else { 2314 mr_asprintf(sz_size, "0"); 2315 } 2316 bkpinfo->media_size = atoi(sz_size); 2317 mr_free(sz_size); 2318 2319 if (bkpinfo->media_size < 0) { 2320 log_to_screen("User has chosen not to backup the machine"); 2321 finish(1); 2322 } 2323 } 2324 /* TODO: Useless I think */ 2325 if (bkpinfo->disaster_recovery) { 2326 mr_asprintf(command ,"umount %s/isodir 2> /dev/null", bkpinfo->tmpdir); 2327 paranoid_system(command); 2328 mr_free(command); 2329 2330 } 2331 strcpy(tmp1, bkpinfo->netfs_proto); 2332 if (!popup_and_get_string("Network protocol", "Which protocol should I use (nfs/sshfs/smbfs) ?",tmp1, MAX_STR_LEN-1)) { 2333 log_to_screen("User has chosen not to backup the machine"); 2334 finish(1); 2335 } 2336 mr_free(bkpinfo->netfs_proto); 2337 mr_asprintf(bkpinfo->netfs_proto, "%s", tmp1); 2338 2339 strcpy(tmp1, bkpinfo->netfs_mount); 2340 if (!popup_and_get_string("Network share", "Which remote share should I mount?", tmp1, MAX_STR_LEN-1)) { 2341 log_to_screen("User has chosen not to backup the machine"); 2342 finish(1); 2343 } 2344 mr_free(bkpinfo->netfs_mount); 2345 mr_asprintf(bkpinfo->netfs_mount, "%s", tmp1); 2346 2347 if (bkpinfo->netfs_user) { 2348 strcpy(tmp1, bkpinfo->netfs_user); 2349 } else { 2350 strcpy(tmp1, ""); 2351 } 2352 if (!popup_and_get_string("Network user", "Which user should I use if any ?",tmp1, MAX_STR_LEN-1)) { 2353 log_to_screen("User has chosen not to backup the machine"); 2354 finish(1); 2355 } 2356 mr_free(bkpinfo->netfs_user); 2357 if (strcmp(tmp1, "") != 0) { 2358 mr_asprintf(bkpinfo->netfs_user, "%s", tmp1); 2359 } 2360 2361 /* Initiate bkpinfo isodir path from running environment if mount already done */ 2362 log_msg(3, "Testing mount for %s", bkpinfo->netfs_mount); 2363 if (is_this_device_mounted(bkpinfo->netfs_mount)) { 2364 mr_free(bkpinfo->isodir); 2365 bkpinfo->isodir = call_program_and_get_last_line_of_output("mount | grep \":\" | cut -d' ' -f3 | head -n1"); 2366 } else { 2367 // Why netfsdir ? 2368 mr_asprintf(bkpinfo->isodir, "%s/netfsdir", bkpinfo->tmpdir); 2369 mr_asprintf(command, "mkdir -p %s", bkpinfo->isodir); 2370 run_program_and_log_output(command, 5); 2371 mr_free(command); 2372 2373 if (bkpinfo->restore_data) { 2374 /* mount the FS read-only in restore mode to avoid any erase of whatever */ 2375 mr_asprintf(tmpro, "-o ro"); 2376 } else { 2377 mr_asprintf(tmpro, ""); 2378 } 2379 2380 /* Build the mount string */ 2381 if (strstr(bkpinfo->netfs_proto, "smbfs")) { 2382 mr_asprintf(tmp, "mount -t cifs %s %s %s",bkpinfo->netfs_mount, bkpinfo->isodir,tmpro); 2383 if (bkpinfo->netfs_user) { 2384 mr_strcat(tmp, " -o user=%s", bkpinfo->netfs_user); 2385 } 2386 else { 2387 if (strstr(bkpinfo->netfs_proto, "sshfs")) { 2388 mr_asprintf(tmp, "sshfs %s ",tmpro); 2389 } else { 2390 mr_asprintf(tmp, "mount -t %s -o nolock %s ", bkpinfo->netfs_proto,tmpro); 2391 } 2392 if (bkpinfo->netfs_user) { 2393 mr_strcat(tmp, "%s@", bkpinfo->netfs_user); 2394 } 2395 mr_strcat(tmp, "%s %s", bkpinfo->netfs_mount, bkpinfo->isodir); 2396 } 2397 run_program_and_log_output(tmp, 3); 2398 mr_free(tmp); 2399 2400 malloc_string(g_selfmounted_isodir); 2401 strcpy(g_selfmounted_isodir, bkpinfo->isodir); 2402 } 2403 } 2404 2405 log_msg(3, "Testing mount for %s", bkpinfo->netfs_mount); 2406 if (!is_this_device_mounted(bkpinfo->netfs_mount)) { 2407 popup_and_OK("Please mount that partition before you try to backup to or restore from it."); 2408 finish(1); 2409 } 2410 if (bkpinfo->netfs_remote_dir == NULL) { 2411 fatal_error("bkpinfo->netfs_remote_dir should not be NULL"); 2412 } 2413 strcpy(tmp1, bkpinfo->netfs_remote_dir); 2414 if (!popup_and_get_string ("Directory", "Which directory within that mountpoint?", tmp1, MAX_STR_LEN-1)) { 2415 log_to_screen("User has chosen not to backup the machine"); 2416 finish(1); 2417 } 2418 mr_free(bkpinfo->netfs_remote_dir); 2419 // check whether writable - we better remove surrounding spaces for this 2420 bkpinfo->netfs_remote_dir = mr_strip_spaces(tmp1); 2421 2422 tmp = mr_popup_and_get_string("Prefix.", "Please enter the prefix that will be prepended to your ISO filename. Example: machine1 to obtain machine1-[1-9]*.iso files", bkpinfo->prefix); 2423 if (tmp == NULL) { 2424 log_to_screen("User has chosen not to backup the machine"); 2425 finish(1); 2426 } 2427 mr_free(bkpinfo->prefix); 2428 bkpinfo->prefix = tmp; 2429 log_msg(3, "prefix set to %s", bkpinfo->prefix); 2430 log_msg(3, "Just set netfs_remote_dir to %s", bkpinfo->netfs_remote_dir); 2431 log_msg(3, "isodir is still %s", bkpinfo->isodir); 2432 break; 2433 2434 case iso: 2435 if (!bkpinfo->disaster_recovery) { 2436 tmp = mr_popup_and_get_string("Storage dir.", "Please enter the full path name to the directory for your ISO images. Example: /mnt/raid0_0", bkpinfo->isodir); 2437 if (tmp == NULL) { 2438 log_to_screen("User has chosen not to backup the machine"); 2439 finish(1); 2440 } else { 2441 mr_free(bkpinfo->isodir); 2442 bkpinfo->isodir = tmp; 2443 } 2444 if (archiving_to_media) { 2445 sprintf(tmp1, "%d", DEFAULT_DVD_DISK_SIZE); // 4.7 salesman's GB = 4.482 real GB = 4482 MB 2446 if (!popup_and_get_string("ISO size.", "Please enter how big you want each ISO image to be (in megabytes). This should be less than or equal to the size of the CD-R[W]'s (700) or DVD's (4480) you plan to backup to.", tmp1, 16)) { 2447 log_to_screen("User has chosen not to backup the machine"); 2448 finish(1); 2449 } 2450 bkpinfo->media_size = atoi(tmp1); 2451 } else { 2452 bkpinfo->media_size = 650; 2453 } 2454 } 2455 tmp = mr_popup_and_get_string("Prefix.", "Please enter the prefix that will be prepended to your ISO filename. Example: machine1 to obtain machine1-[1-9]*.iso files", bkpinfo->prefix); 2456 if (tmp == NULL) { 2457 log_to_screen("User has chosen not to backup the machine"); 2458 finish(1); 2459 } 2460 mr_free(bkpinfo->prefix); 2461 bkpinfo->prefix = tmp; 2462 log_msg(3, "prefix set to %s", bkpinfo->prefix); 2463 break; 2464 default: 2465 fatal_error("I, Mojo Jojo, shall defeat those pesky Powerpuff Girls!"); 2466 } 2467 2468 if (archiving_to_media) { 2469 /* Needs to be done before calling which_boot_loader */ 2470 bkpinfo->boot_type = mr_boot_type(); 2471 mr_free(bkpinfo->boot_device); 2472 #ifdef __FreeBSD__ 2473 bkpinfo->boot_device = call_program_and_get_last_line_of_output("mount | grep ' / ' | head -1 | cut -d' ' -f1 | sed 's/\\([0-9]\\).*/\\1/'"); 2474 #else 2475 bkpinfo->boot_device = call_program_and_get_last_line_of_output("mount | grep ' / ' | head -1 | cut -d' ' -f1 | sed 's/[0-9].*//'"); 2476 #endif 2477 i = which_boot_loader(bkpinfo->boot_device); 2478 if (i == 'U') // unknown 2479 { 2480 2481 #ifdef __FreeBSD__ 2482 if (!popup_and_get_string("Boot device", "What is your boot device? (e.g. /dev/ad0)", bkpinfo->boot_device,(MAX_STR_LEN / 4)-1)) { 2483 log_to_screen("User has chosen not to backup the machine"); 2484 finish(1); 2485 } 2486 i = which_boot_loader(bkpinfo->boot_device); 2487 #else 2488 strcpy(tmp1, bkpinfo->boot_device); 2489 if (!popup_and_get_string("Boot device", "What is your boot device? (e.g. /dev/hda)", tmp1,(MAX_STR_LEN / 4)-1)) { 2490 log_to_screen("User has chosen not to backup the machine"); 2491 finish(1); 2492 } 2493 mr_free(bkpinfo->boot_device); 2494 mr_asprintf(bkpinfo->boot_device, "%s", tmp1); 2495 2496 if (does_string_exist_in_boot_block(bkpinfo->boot_device, "ELILO")) { 2497 i = 'E'; 2498 } else 2499 if (does_string_exist_in_boot_block(bkpinfo->boot_device, "LILO")) { 2500 i = 'L'; 2501 } else 2502 if (does_string_exist_in_boot_block(bkpinfo->boot_device, "GRUB")) { 2503 i = 'G'; 2504 } else { 2505 i = 'U'; 2506 } 2507 #endif 2508 if (i == 'U') { 2509 if (ask_me_yes_or_no("Unidentified boot loader. Shall I restore it byte-for-byte at restore time and hope for the best?")) { 2510 i = 'R'; // raw 2511 } else { 2512 log_to_screen("I cannot find your boot loader. Please run mondoarchive with parameters."); 2513 finish(1); 2514 } 2515 } 2516 } 2517 bkpinfo->boot_loader = i; 2518 /* TODO: Check consistency of boot type and boot loader */ 2519 2520 if (bkpinfo->include_paths) { 2521 strcpy(tmp1, bkpinfo->include_paths); 2522 mr_free(bkpinfo->include_paths); 2523 } else { 2524 strcpy(tmp1, "/"); 2525 } 2526 if (!popup_and_get_string("Backup paths", "Please enter paths (separated by '|') which you want me to backup. The default is '/' (i.e. everything).", tmp1, MAX_STR_LEN-1)) { 2527 log_to_screen("User has chosen not to backup the machine"); 2528 finish(1); 2529 } 2530 mr_asprintf(bkpinfo->include_paths, "%s", tmp1); 2531 2532 tmp = list_of_NETFS_mounts_only(); 2533 if (strlen(tmp) > 2) { 2534 mr_strcat(bkpinfo->exclude_paths, "|%s",tmp); 2535 } 2536 mr_free(tmp); 2537 // NTFS 2538 tmp = call_program_and_get_last_line_of_output("mr-parted2fdisk -l 2>/dev/null | grep -i ntfs | awk '{ print $1};' | tr -s '\\n' ' ' | awk '{ print $0};'"); 2539 strncpy(tmp1, tmp,(MAX_STR_LEN / 4)-1); 2540 mr_free(tmp); 2541 if (strlen(tmp1) > 2) { 2542 if (!popup_and_get_string("NTFS partitions", "Please enter/confirm the NTFS partitions you wish to backup as well.", tmp1,(MAX_STR_LEN / 4)-1)) { 2543 log_to_screen("User has chosen not to backup the machine"); 2544 finish(1); 2545 } 2546 mr_asprintf(bkpinfo->image_devs, "%s", tmp1); 2547 } 2548 2549 if (bkpinfo->exclude_paths != NULL ) { 2550 mr_asprintf(p, "%s", bkpinfo->exclude_paths); 2551 } else { 2552 mr_asprintf(p, "%s", ""); 2553 } 2554 tmp = mr_popup_and_get_string("Exclude paths", "Please enter paths which you do NOT want to backup. Separate them with '|'. NB: /tmp and /proc are always excluded. :-) Just hit 'Enter' if you want to do a full system backup.", p); 2555 mr_free(p); 2556 if (tmp == NULL) { 2557 log_to_screen("User has chosen not to backup the machine"); 2558 finish(1); 2559 } 2560 mr_free(bkpinfo->exclude_paths); 2561 bkpinfo->exclude_paths = tmp; 2562 2563 mr_asprintf(oldtmp, "%s", bkpinfo->tmpdir); 2564 if (bkpinfo->tmpdir != NULL ) { 2565 mr_asprintf(p, "%s", bkpinfo->tmpdir); 2566 } else { 2567 mr_asprintf(p, "%s", ""); 2568 } 2569 tmp = mr_popup_and_get_string("Temporary directory", "Please enter your temporary directory.", p); 2570 mr_free(p); 2571 if (tmp == NULL) { 2572 mr_free(oldtmp); 2573 log_to_screen("User has chosen not to backup the machine"); 2574 finish(1); 2575 } 2576 /* if modified to another path */ 2577 if (strcmp(tmp,oldtmp) != 0) { 2578 setup_tmpdir(tmp); 2579 } 2580 mr_free(oldtmp); 2581 2582 mr_asprintf(oldtmp, "%s", bkpinfo->scratchdir); 2583 if (bkpinfo->scratchdir != NULL ) { 2584 mr_asprintf(p, "%s", bkpinfo->scratchdir); 2585 } else { 2586 mr_asprintf(p, "%s", ""); 2587 } 2588 tmp = mr_popup_and_get_string("Scratch directory", "Please enter your scratch directory.", p); 2589 mr_free(p); 2590 if (tmp == NULL) { 2591 mr_free(oldtmp); 2592 log_to_screen("User has chosen not to backup the machine"); 2593 finish(1); 2594 } 2595 /* if modified to another path */ 2596 if (strcmp(tmp,oldtmp) != 0) { 2597 setup_scratchdir(tmp); 2598 } 2599 mr_free(oldtmp); 2600 2601 if (ask_me_yes_or_no("Do you want to backup extended attributes?")) { 2602 mr_free(g_getfattr); 2603 g_getfattr = find_home_of_exe("getfattr"); 2604 mr_free(g_getfacl); 2605 g_getfacl = find_home_of_exe("getfacl"); 2606 log_it("Backup of extended attributes"); 2607 } 2608 // Interactive mode: 2609 #ifdef __IA64__ 2610 bkpinfo->make_cd_use_lilo = TRUE; 2611 #else 2612 bkpinfo->make_cd_use_lilo = FALSE; 2613 #endif 2614 bkpinfo->backup_data = TRUE; 2615 if (strcmp(compression_type,"lzo") == 0) { 2616 mr_asprintf(bkpinfo->zip_exe, "%s", "lzop"); 2617 mr_asprintf(bkpinfo->zip_suffix, "%s", "lzo"); 2618 } else if (strcmp(compression_type,"gzip") == 0) { 2619 mr_asprintf(bkpinfo->zip_exe, "%s", "gzip"); 2620 mr_asprintf(bkpinfo->zip_suffix, "%s", "gz"); 2621 } else if (strcmp(compression_type,"lzma") == 0) { 2622 mr_asprintf(bkpinfo->zip_exe, "%s", "xz"); 2623 mr_asprintf(bkpinfo->zip_suffix, "%s", "xz"); 2624 } else if (strcmp(compression_type,"bzip2") == 0) { 2625 mr_asprintf(bkpinfo->zip_exe, "%s", "bzip2"); 2626 mr_asprintf(bkpinfo->zip_suffix, "%s", "bz2"); 2627 } else { 2628 mr_free(bkpinfo->zip_exe); 2629 mr_free(bkpinfo->zip_suffix); 2630 } 2631 mr_free(compression_type); 2632 2633 #if __FreeBSD__ == 5 2634 mr_asprintf(bkpinfo->kernel_path, "%s", "/boot/kernel/kernel"); 2635 #elif __FreeBSD__ == 4 2636 mr_asprintf(bkpinfo->kernel_path, "%s", "/kernel"); 2637 #elif linux 2638 if (figure_out_kernel_path_interactively_if_necessary(bkpinfo->kernel_path)) { 2639 fatal_error("Kernel not found. Please specify manually with the '-k' switch."); 2640 } 2641 #else 2642 #error "I don't know about this system!" 2643 #endif 2644 2645 2646 bkpinfo->verify_data = 2647 ask_me_yes_or_no 2648 ("Will you want to verify your backups after Mondo has created them?"); 2649 2650 if (!ask_me_yes_or_no 2651 ("Are you sure you want to proceed? Hit 'no' to abort.")) { 2652 log_to_screen("User has chosen not to backup the machine"); 2653 finish(1); 2654 } 2655 } else { 2656 bkpinfo->restore_data = TRUE; // probably... 2657 } 2658 2659 if (bkpinfo->backup_media_type == iso 2660 || bkpinfo->backup_media_type == netfs) { 2661 g_ISO_restore_mode = TRUE; 2662 } 2663 #ifdef __FreeSD__ 2664 // skip 2665 #else 2666 if (bkpinfo->backup_media_type == netfs) { 2667 log_msg(3, "I think the Remote mount is mounted at %s", bkpinfo->isodir); 2668 } 2669 log_it("isodir = %s", bkpinfo->isodir); 2670 if (bkpinfo->netfs_mount) { 2671 log_it("netfs_mount = '%s'", bkpinfo->netfs_mount); 2672 } 2673 if (bkpinfo->netfs_user) { 2674 log_it("netfs_user = '%s'", bkpinfo->netfs_user); 2675 } 2676 if (bkpinfo->netfs_proto) { 2677 log_it("netfs_proto = '%s'", bkpinfo->netfs_proto); 2678 } 2679 #endif 2680 2681 log_it("media device = %s", bkpinfo->media_device); 2682 log_it("media size = %ld", bkpinfo->media_size); 2683 log_it("media type = %s", bkptype_to_string(bkpinfo->backup_media_type)); 2684 if (bkpinfo->prefix != NULL) { 2685 log_it("prefix = %s", bkpinfo->prefix); 2686 } 2687 log_it("compression = %ld", bkpinfo->compression_level); 2688 log_it("exclude_path = %s", bkpinfo->exclude_paths); 2689 if (bkpinfo->include_paths) { 2690 log_it("include_path = %s", bkpinfo->include_paths); 2691 } 2692 2693 /* Handle devices passed in bkpinfo and print result */ 2694 /* the mr_make_devlist_from_pathlist function appends */ 2695 /* to the *_paths variables so copy before */ 2696 mr_make_devlist_from_pathlist(bkpinfo->exclude_paths, 'E'); 2697 mr_make_devlist_from_pathlist(bkpinfo->include_paths, 'I'); 2698 2699 log_it("scratchdir = '%s'", bkpinfo->scratchdir); 2700 log_it("tmpdir = '%s'", bkpinfo->tmpdir); 2701 if (bkpinfo->image_devs) { 2702 log_it("image_devs = '%s'", bkpinfo->image_devs); 2703 } 2704 log_it("boot_device = '%s' (loader=%c)", bkpinfo->boot_device, bkpinfo->boot_loader); 2705 if (bkpinfo->media_size < 0) { 2706 if (archiving_to_media) { 2707 fatal_error("Media size is less than zero."); 2708 } else { 2709 log_msg(2, "Warning - media size is less than zero."); 2710 bkpinfo->media_size = 0; 2711 } 2712 } 2713 paranoid_free(sz_size); 2714 paranoid_free(tmp1); 2715 return (0); 2716 } 2717 2718 2719 /** 2720 * Get a |-separated list of NETFS mounts. 2721 * @return The list created. 2722 * @note The return value points to allocated string that needs to be freed by 2723 * caller 2724 * @bug Even though we only want the mounts, the devices are still checked. 2725 */ 2726 char *list_of_NETFS_mounts_only(void) 2727 { 2728 char *exclude_these_directories = NULL; 2729 2730 exclude_these_directories = call_program_and_get_last_line_of_output("mount -t coda,ncpfs,fuse.sshfs,nfs,nfs4,vmhgfs,smbfs,cifs,afs,gfs,ocfs,ocfs2,mvfs,nsspool,nssvol,fuse.boostfs | tr -s '\t' ' ' | cut -d' ' -f3 | tr -s '\n' '|' | awk '{print $0;}'"); 2731 log_msg(9,"list_of_NETFS_mounts_only returns %s",exclude_these_directories); 2732 return(exclude_these_directories); 2733 } 2734 2735 /* @} - end of utilityGroup */ 2736 2737 2738 2739 2740 2741 /** 2742 * Create a randomly-named FIFO. The format is @p stub "." [random] [random] where 2743 * [random] is a random number between 1 and 32767. 2744 * @param store_name_here Where to store the new filename. 2745 * @param stub A random number will be appended to this to make the FIFO's name. 2746 * @ingroup deviceGroup 2747 */ 2748 void make_fifo(char *store_name_here, char *stub) 2749 { 2750 char *tmp = NULL; 2751 2752 assert_string_is_neither_NULL_nor_zerolength(stub); 2753 2754 sprintf(store_name_here, "%s%d%d", stub, (int) (random() % 32768), 2755 (int) (random() % 32768)); 2756 make_hole_for_file(store_name_here); 2757 mkfifo(store_name_here, S_IRWXU | S_IRWXG); 2758 mr_asprintf(tmp, "chmod 770 %s", store_name_here); 2759 paranoid_system(tmp); 2760 mr_free(tmp); 2761 } 2762 2763 2764 2765 /** 2766 * @addtogroup deviceGroup 2767 * @{ 2768 */ 2769 /** 2770 * If we can read @p dev, set @p output to it. 2771 * If @p dev cannot be read, set @p output to "". 2772 * @param dev The device to check for. 2773 * @param output Set to @p dev if @p dev exists, "" otherwise. 2774 * @return TRUE if @p dev exists, FALSE if it doesn't. 2775 */ 2776 bool set_dev_to_this_if_rx_OK(char *output, char *dev) 2777 { 2778 char *command = NULL; 2779 bool ret=FALSE; 2780 2781 if (!dev || dev[0] == '\0') { 2782 output[0] = '\0'; 2783 return(ret); 2784 } 2785 // assert_string_is_neither_NULL_nor_zerolength(dev); 2786 if (!bkpinfo->please_dont_eject) { 2787 log_msg(10, "Injecting %s", dev); 2788 inject_device(dev); 2789 } 2790 if (!does_file_exist(dev)) { 2791 log_msg(10, "%s doesn't exist. Returning FALSE.", dev); 2792 return(ret); 2793 } 2794 mr_asprintf(command, "dd bs=%ld count=1 if=%s of=/dev/null &> /dev/null", 512L, dev); 2795 if (!run_program_and_log_output(command, FALSE) && !run_program_and_log_output(command, FALSE)) { 2796 strcpy(output, dev); 2797 log_msg(4, "Found it - %s", dev); 2798 ret = TRUE; 2799 } else { 2800 output[0] = '\0'; 2801 log_msg(4, "It's not %s", dev); 2802 } 2803 mr_free(command); 2804 return(ret); 2805 } 2806 2807 2808 2809 2810 2811 /** 2812 * Find out what number CD is in the drive. 2813 * @param bkpinfo The backup information structure. The @c bkpinfo->media_device field is the only one used. 2814 * @return The current CD number, or -1 if it could not be found. 2815 * @note If the CD is not mounted, it will be mounted 2816 * (and remain mounted after this function returns). 2817 */ 2818 int what_number_cd_is_this(void) { 2819 2820 int cd_number = -1; 2821 char *mountdev = NULL; 2822 char *tmp = NULL; 2823 2824 assert(bkpinfo != NULL); 2825 // log_it("Asking what_number_cd_is_this"); 2826 if ((g_ISO_restore_mode) || (g_restoring_live_from_cd)) { 2827 tmp = call_program_and_get_last_line_of_output("mount | grep iso9660 | awk '{print $3;}'"); 2828 mr_asprintf(mountdev, "%s%s", tmp, "/archives/THIS-CD-NUMBER"); 2829 mr_free(tmp); 2830 cd_number = atoi(last_line_of_file(mountdev)); 2831 mr_free(mountdev); 2832 return (cd_number); 2833 } 2834 2835 if ((bkpinfo->media_device == NULL) || !does_file_exist(bkpinfo->media_device)) { 2836 log_it("ERROR: bkpinfo->media_device shoulnd't be unaccessible here\n"); 2837 /* trying again ! */ 2838 bkpinfo->media_device = find_optical_device(); 2839 } 2840 if ((bkpinfo->media_device == NULL) || !does_file_exist(bkpinfo->media_device)) { 2841 fatal_error("ERROR: bkpinfo->media_device shoulnd't really be unaccessible here\n"); 2842 } 2843 if (!is_this_device_mounted(bkpinfo->media_device, MNT_CDROM)) { 2844 mount_media(MNT_CDROM); 2845 } 2846 2847 cd_number = atoi(last_line_of_file(MNT_CDROM "/archives/THIS-CD-NUMBER")); 2848 return(cd_number); 2849 } 2850 2851 2852 /** 2853 * Find out what device is mounted as root (/). 2854 * @return Root device. 2855 * @note The returned string points to storage that needs to be freed by 2856 * caller 2857 * @bug A bit of a misnomer; it's actually finding out the root device. 2858 * The mountpoint (where it's mounted) will obviously be '/'. 2859 */ 2860 char *where_is_root_mounted(void) { 2861 2862 /*@ buffers **************** */ 2863 char *tmp = NULL; 2864 2865 #ifdef __FreeBSD__ 2866 tmp = call_program_and_get_last_line_of_output("mount | grep \" on / \" | cut -d' ' -f1"); 2867 #else 2868 tmp = call_program_and_get_last_line_of_output("mount | grep \" on / \" | cut -d' ' -f1 | sed s/[0-9]// | sed s/[0-9]//"); 2869 if (strstr(tmp, "/dev/cciss/")) { 2870 mr_free(tmp); 2871 tmp = call_program_and_get_last_line_of_output("mount | grep \" on / \" | cut -d' ' -f1 | cut -dp -f1"); 2872 } 2873 if (strstr(tmp, "/dev/md")) { 2874 mr_free(tmp); 2875 tmp = call_program_and_get_last_line_of_output("mount | grep \" on / \" | cut -d' ' -f1"); 2876 } 2877 #endif 2878 2879 return (tmp); 2880 } 2881 2881 2882 2882 -
branches/3.3/mondo/src/common/libmondo-stream.c
r3872 r3877 200 200 return (retval); 201 201 } 202 203 204 205 /** 206 * Start to write to the next tape. Assume the user has already inserted it. 207 * @param bkpinfo The backup information structure. @c bkpinfo->media_device is the only field used. 208 * @return 0 for success, nonzero for failure. 209 */ 210 int start_to_write_to_next_tape() 211 { 212 int res = 0; 213 char *command = NULL; 214 215 if (bkpinfo->media_device == NULL) { 216 log_it("Unable to open out from NULL device"); 217 return (1); 218 } 219 220 paranoid_pclose(g_tape_stream); 221 sync(); 222 sync(); 223 sync(); 224 log_it("New tape requested."); 225 insist_on_this_tape_number(g_current_media_number + 1); // will increment g_current_media, too 226 if (bkpinfo->backup_media_type == cdstream) { 227 mr_asprintf(command, "cdrecord -eject dev=%s speed=%d fs=24m -waiti - >> %s 2>> %s", bkpinfo->media_device, bkpinfo->cdrw_speed, MONDO_LOGFILE, MONDO_LOGFILE); 228 log_it("Opening OUT to next CD with the command"); 229 log_it(command); 230 log_it("Let's see what happens, shall we?"); 231 g_tape_stream = popen(command, "w"); 232 mr_free(command); 233 234 if (!g_tape_stream) { 235 log_to_screen("Failed to openout to cdstream (fifo)"); 236 return (1); 237 } 238 } else { 239 log_it("Opening OUT to next tape"); 240 if (!(g_tape_stream = open_device_via_buffer(bkpinfo->media_device, 'w', bkpinfo->internal_tape_block_size))) { 241 log_OS_error(g_tape_fifo); 242 log_to_screen("Cannot openin stream device"); 243 return (1); 244 } 245 } 246 g_tape_posK = 0; 247 g_sigpipe = FALSE; 248 res += write_header_block_to_stream((off_t)0, "start-of-tape", BLK_START_OF_TAPE); /* just in case */ 249 res += write_header_block_to_stream((off_t)0, "start-of-backup", BLK_START_OF_BACKUP); /* just in case */ 250 return (res); 251 } 252 253 254 255 /** 256 * Decide whether we should start a new tape. This is TRUE if we've run out of tape 257 * (got SIGPIPE) or look like we will. 258 * @param mediasize The size of the tape in megabytes. 259 * @param length_of_incoming_file The length of the file we're about to write, in bytes. 260 * @bug This seems like it'll only work for media_size != autodetect, but Mondo only allows 261 * autodetecting the size. Huh? 262 */ 263 264 /* TODO: Should be reviewed for mediasize being a off_t ??? */ 265 bool 266 should_we_write_to_next_tape(long mediasize, 267 off_t length_of_incoming_file) 268 { 269 /*@ bool's ***************************************************** */ 270 bool we_need_a_new_tape = FALSE; 271 272 /*@ end vars *************************************************** */ 273 274 if (mediasize == 0) { 275 return (FALSE); 276 } 277 if (mediasize > 0 && (g_tape_posK >> 10 >= mediasize)) { 278 log_it("mediasize = %ld", mediasize); 279 we_need_a_new_tape = TRUE; 280 log_to_screen("Should have started a new tape/CD already"); 281 } 282 if ((g_tape_posK + length_of_incoming_file / 1024) >> 10 >= 283 mediasize - (SLICE_SIZE * 4 / 1024)) { 284 log_it("g_tape_posK = %ld\nmediasize = %ld\n", g_tape_posK, 285 mediasize); 286 we_need_a_new_tape = TRUE; 287 } 288 return (we_need_a_new_tape); 289 } 290 291 202 292 203 293 … … 354 444 355 445 446 /** 447 * Copy a file from the opened stream (CD or tape) to @p outfile. 448 * @param outfile The file to write to. 449 * @param size The size of the file in the input stream. 450 * @return 0 for success, nonzero for failure. 451 */ 452 int 453 read_file_from_stream_to_file(char *outfile, long long size) 454 { 455 456 /*@ int ******************************************************** */ 457 int res; 458 459 /*@ end vars *************************************************** */ 460 461 res = read_file_from_stream_FULL(outfile, NULL, size); 462 463 return (res); 464 } 465 466 467 468 356 469 int read_EXAT_files_from_tape(long long *ptmp_size, char *tmp_fname, 357 470 int *pctrl_chr, char *xattr_fname, … … 419 532 return (res); 420 533 } 534 535 536 /** 537 * Copy @p infile to the opened stream (CD or tape). 538 * @param bkpinfo The backup information structure. @c bkpinfo->media_size is the only field used. 539 * @param infile The file to write to the stream. 540 * @return 0 for success, nonzero for failure. 541 */ 542 int write_file_to_stream_from_file(char *infile) 543 { 544 /*@ buffers **************************************************** */ 545 char datablock[TAPE_BLOCK_SIZE]; 546 char *checksum = NULL; 547 char *infile_basename; 548 549 /*@ int ******************************************************** */ 550 int retval = 0; 551 int noof_blocks; 552 553 /* unsigned int ch; */ 554 unsigned int crc16; 555 unsigned int crctt; 556 557 /*@ pointers *************************************************** */ 558 FILE *fin; 559 char *p; 560 561 /*@ long ******************************************************* */ 562 long bytes_to_read = 0; 563 long i; 564 565 off_t filesize; 566 567 #ifdef EXTRA_TAPE_CHECKSUMS 568 int ch; 569 #endif 570 571 /*@ initialize ************************************************ */ 572 crc16 = 0; 573 crctt = 0; 574 575 576 577 /*@ end vars *************************************************** */ 578 579 infile_basename = strrchr(infile, '/'); 580 if (infile_basename) { 581 infile_basename++; 582 } else { 583 infile_basename = infile; 584 } 585 filesize = length_of_file(infile); 586 if (should_we_write_to_next_tape(bkpinfo->media_size, filesize)) { 587 start_to_write_to_next_tape(); 588 write_backcatalog_to_tape(); 589 } 590 p = strrchr(infile, '/'); 591 if (!p) { 592 p = infile; 593 } else { 594 p++; 595 } 596 log_it("Writing file '%s' to tape (%ld KB)", p, (long) filesize >> 10); 597 write_header_block_to_stream(filesize, infile_basename, BLK_START_FILE); 598 //go_here_to_restart_saving_of_file: 599 if (!(fin = fopen(infile, "r"))) { 600 log_OS_error(infile); 601 return (1); 602 } 603 for (noof_blocks = 0; filesize > 0; 604 noof_blocks++, filesize -= bytes_to_read) { 605 if (filesize < TAPE_BLOCK_SIZE) { 606 bytes_to_read = (long) filesize; 607 for (i = 0; i < TAPE_BLOCK_SIZE; i++) { 608 datablock[i] = '\0'; 609 } 610 } else { 611 bytes_to_read = TAPE_BLOCK_SIZE; 612 } 613 if (fread(datablock, 1, (size_t) bytes_to_read, fin)) { 614 // FIXME 615 } 616 g_tape_posK += 617 fwrite(datablock, 1, /*bytes_to_read */ 618 (size_t) TAPE_BLOCK_SIZE, 619 g_tape_stream) / 1024; 620 if (g_sigpipe) { 621 log_it("Sigpipe occurred recently. I'll start a new tape."); 622 fclose(fin); 623 g_sigpipe = FALSE; 624 start_to_write_to_next_tape(); 625 write_backcatalog_to_tape(); // kinda-sorta recursive :) 626 return (0); 627 } 628 #ifdef EXTRA_TAPE_CHECKSUMS 629 for (i = 0; i < bytes_to_read; i++) { 630 ch = datablock[i]; 631 crc16 = updcrcr(crc16, (unsigned) ch); 632 crctt = updcrc(crctt, (unsigned) ch); 633 } 634 #endif 635 } 636 paranoid_fclose(fin); 637 mr_asprintf(checksum, "%04x%04x", crc16, crctt); 638 /* TODO: what does it do ??? */ 639 write_header_block_to_stream((off_t)g_current_media_number, checksum, BLK_STOP_FILE); 640 mr_free(checksum); 641 642 // log_it("File '%s' written to tape.", infile); 643 return (retval); 644 } 645 646 647 648 649 650 421 651 422 652 … … 566 796 } 567 797 568 569 570 571 /**572 * Open the CD stream for input.573 * @param bkpinfo The backup information structure. Passed to openin_tape().574 * @return 0 for success, nonzero for failure.575 * @note Equivalent to openin_tape() for now, but don't count on this behavior.576 */577 int openin_cdstream()578 {579 return (openin_tape());580 }581 582 /**583 * FIFO used to read/write to the tape device.584 * @bug This seems obsolete now that we call an external @c buffer program. Please look onto this.585 */586 char g_tape_fifo[MAX_STR_LEN];587 588 589 590 int set_tape_block_size_with_mt(long internal_tape_block_size)591 {592 char *tmp = NULL;593 int res;594 595 if (bkpinfo->media_device == NULL) {596 return(1);597 }598 599 if (strncmp(bkpinfo->media_device, "/dev/", 5)) {600 log_msg(1, "Not using 'mt setblk'. This isn't an actual /dev entry.");601 return (0);602 }603 mr_asprintf(tmp, "mt -f %s setblk %ld", bkpinfo->media_device, internal_tape_block_size);604 res = run_program_and_log_output(tmp, 3);605 mr_free(tmp);606 return (res);607 }608 609 /**610 * Return the non-rewinding device when passed the normal one611 * @param tapedev The tape device to open for writing.612 * @note the caller needs to free the string returned613 */614 char *get_non_rewind_dev(char *tapedev)615 {616 617 char *ntapedev = NULL;618 char *p = NULL;619 char *q = NULL;620 char *r = NULL;621 622 ntapedev = (char *)mr_malloc(strlen(tapedev)+2*sizeof(char));623 p = strrchr(tapedev,'/');624 if (p == NULL) {625 log_it("Didn't find a '/' in %s",tapedev);626 return(NULL);627 }628 629 /* Copy tapedev content up to the last / */630 q = tapedev;631 r = ntapedev;632 while (q != p) {633 *r = *q;634 r++;635 q++;636 }637 /* Copy the '/' */638 *r = *q;639 r++;640 q++;641 /* Adds a 'n' - non-rewinding */642 *r = 'n';643 r++;644 /* Copy the rest of tapedev */645 while (*q != '\0') {646 *r = *q;647 r++;648 q++;649 }650 *r = '\0';651 if (mt_says_tape_exists(ntapedev)) {652 log_it("Non-rewinding tape device is %s",ntapedev);653 } else {654 log_it("Unable to find non-rewinding tape device.");655 ntapedev = NULL;656 }657 return(ntapedev);658 }659 660 661 662 /**663 * Handle OBDR if we were asked to do so664 * @param tapedev The tape device to open for reading.665 */666 int skip_obdr(void)667 {668 char *command = NULL;669 int res = 0;670 671 if (bkpinfo->media_device == NULL) {672 return(1);673 }674 675 log_it("Skipping OBDR headers");676 mr_asprintf(command, "mt -f %s rewind",bkpinfo->media_device);677 res = run_program_and_log_output(command, 1);678 paranoid_free(command);679 680 mr_asprintf(command, "mt -f %s fsf 2",bkpinfo->media_device);681 res = run_program_and_log_output(command, 1);682 paranoid_free(command);683 684 set_tape_block_size_with_mt(bkpinfo->internal_tape_block_size);685 return(res);686 }687 688 /**689 * Handle OBDR if we were asked to do so690 * @param tapedev The tape device to open for writing.691 * @return 0 for success, nonzero for failure.692 * @note This should be called ONLY from backup processes. It will OVERWRITE ANY693 * EXISTING DATA on the tape!694 */695 int create_obdr(void)696 {697 698 char *command = NULL;699 int res = 0;700 701 if (bkpinfo->media_device == NULL) {702 return(1);703 }704 705 log_it("Creating OBDR headers");706 /* OBDR: First block 10 kB of zero bs = 512 */707 mr_asprintf(command, "mt -f %s compression off",bkpinfo->media_device);708 res = run_program_and_log_output(command, 1);709 paranoid_free(command);710 711 mr_asprintf(command, "mt -f %s rewind",bkpinfo->media_device);712 res += run_program_and_log_output(command, 1);713 paranoid_free(command);714 715 set_tape_block_size_with_mt(512);716 717 mr_asprintf(command, "dd if=/dev/zero of=%s bs=512 count=20",bkpinfo->media_device);718 res += run_program_and_log_output(command, 1);719 paranoid_free(command);720 721 /* OBDR: then ISO boot image bs = 2048 */722 set_tape_block_size_with_mt(2048);723 724 mr_asprintf(command, "dd if=%s of=%s bs=2048",MINDI_CACHE"/mindi.iso",bkpinfo->media_device);725 res += run_program_and_log_output(command, 1);726 paranoid_free(command);727 728 set_tape_block_size_with_mt(bkpinfo->internal_tape_block_size);729 730 /* restore compression mode on */731 mr_asprintf(command, "mt -f %s compression on",bkpinfo->media_device);732 res = run_program_and_log_output(command, 1);733 paranoid_free(command);734 735 return(res);736 }737 798 738 799 … … 871 932 872 933 934 935 /** 936 * Open the CD stream for input. 937 * @param bkpinfo The backup information structure. Passed to openin_tape(). 938 * @return 0 for success, nonzero for failure. 939 * @note Equivalent to openin_tape() for now, but don't count on this behavior. 940 */ 941 int openin_cdstream() 942 { 943 return (openin_tape()); 944 } 945 946 /** 947 * FIFO used to read/write to the tape device. 948 * @bug This seems obsolete now that we call an external @c buffer program. Please look onto this. 949 */ 950 char g_tape_fifo[MAX_STR_LEN]; 951 952 953 954 int set_tape_block_size_with_mt(long internal_tape_block_size) 955 { 956 char *tmp = NULL; 957 int res; 958 959 if (bkpinfo->media_device == NULL) { 960 return(1); 961 } 962 963 if (strncmp(bkpinfo->media_device, "/dev/", 5)) { 964 log_msg(1, "Not using 'mt setblk'. This isn't an actual /dev entry."); 965 return (0); 966 } 967 mr_asprintf(tmp, "mt -f %s setblk %ld", bkpinfo->media_device, internal_tape_block_size); 968 res = run_program_and_log_output(tmp, 3); 969 mr_free(tmp); 970 return (res); 971 } 972 973 /** 974 * Return the non-rewinding device when passed the normal one 975 * @param tapedev The tape device to open for writing. 976 * @note the caller needs to free the string returned 977 */ 978 char *get_non_rewind_dev(char *tapedev) 979 { 980 981 char *ntapedev = NULL; 982 char *p = NULL; 983 char *q = NULL; 984 char *r = NULL; 985 986 ntapedev = (char *)mr_malloc(strlen(tapedev)+2*sizeof(char)); 987 p = strrchr(tapedev,'/'); 988 if (p == NULL) { 989 log_it("Didn't find a '/' in %s",tapedev); 990 return(NULL); 991 } 992 993 /* Copy tapedev content up to the last / */ 994 q = tapedev; 995 r = ntapedev; 996 while (q != p) { 997 *r = *q; 998 r++; 999 q++; 1000 } 1001 /* Copy the '/' */ 1002 *r = *q; 1003 r++; 1004 q++; 1005 /* Adds a 'n' - non-rewinding */ 1006 *r = 'n'; 1007 r++; 1008 /* Copy the rest of tapedev */ 1009 while (*q != '\0') { 1010 *r = *q; 1011 r++; 1012 q++; 1013 } 1014 *r = '\0'; 1015 if (mt_says_tape_exists(ntapedev)) { 1016 log_it("Non-rewinding tape device is %s",ntapedev); 1017 } else { 1018 log_it("Unable to find non-rewinding tape device."); 1019 ntapedev = NULL; 1020 } 1021 return(ntapedev); 1022 } 1023 1024 1025 1026 /** 1027 * Handle OBDR if we were asked to do so 1028 * @param tapedev The tape device to open for reading. 1029 */ 1030 int skip_obdr(void) 1031 { 1032 char *command = NULL; 1033 int res = 0; 1034 1035 if (bkpinfo->media_device == NULL) { 1036 return(1); 1037 } 1038 1039 log_it("Skipping OBDR headers"); 1040 mr_asprintf(command, "mt -f %s rewind",bkpinfo->media_device); 1041 res = run_program_and_log_output(command, 1); 1042 paranoid_free(command); 1043 1044 mr_asprintf(command, "mt -f %s fsf 2",bkpinfo->media_device); 1045 res = run_program_and_log_output(command, 1); 1046 paranoid_free(command); 1047 1048 set_tape_block_size_with_mt(bkpinfo->internal_tape_block_size); 1049 return(res); 1050 } 1051 1052 /** 1053 * Handle OBDR if we were asked to do so 1054 * @param tapedev The tape device to open for writing. 1055 * @return 0 for success, nonzero for failure. 1056 * @note This should be called ONLY from backup processes. It will OVERWRITE ANY 1057 * EXISTING DATA on the tape! 1058 */ 1059 int create_obdr(void) 1060 { 1061 1062 char *command = NULL; 1063 int res = 0; 1064 1065 if (bkpinfo->media_device == NULL) { 1066 return(1); 1067 } 1068 1069 log_it("Creating OBDR headers"); 1070 /* OBDR: First block 10 kB of zero bs = 512 */ 1071 mr_asprintf(command, "mt -f %s compression off",bkpinfo->media_device); 1072 res = run_program_and_log_output(command, 1); 1073 paranoid_free(command); 1074 1075 mr_asprintf(command, "mt -f %s rewind",bkpinfo->media_device); 1076 res += run_program_and_log_output(command, 1); 1077 paranoid_free(command); 1078 1079 set_tape_block_size_with_mt(512); 1080 1081 mr_asprintf(command, "dd if=/dev/zero of=%s bs=512 count=20",bkpinfo->media_device); 1082 res += run_program_and_log_output(command, 1); 1083 paranoid_free(command); 1084 1085 /* OBDR: then ISO boot image bs = 2048 */ 1086 set_tape_block_size_with_mt(2048); 1087 1088 mr_asprintf(command, "dd if=%s of=%s bs=2048",MINDI_CACHE"/mindi.iso",bkpinfo->media_device); 1089 res += run_program_and_log_output(command, 1); 1090 paranoid_free(command); 1091 1092 set_tape_block_size_with_mt(bkpinfo->internal_tape_block_size); 1093 1094 /* restore compression mode on */ 1095 mr_asprintf(command, "mt -f %s compression on",bkpinfo->media_device); 1096 res = run_program_and_log_output(command, 1); 1097 paranoid_free(command); 1098 1099 return(res); 1100 } 1101 1102 873 1103 /** 874 1104 * Start writing to a CD stream. … … 948 1178 } 949 1179 return (0); 950 }951 952 953 954 955 /**956 * Copy a file from the opened stream (CD or tape) to @p outfile.957 * @param outfile The file to write to.958 * @param size The size of the file in the input stream.959 * @return 0 for success, nonzero for failure.960 */961 int962 read_file_from_stream_to_file(char *outfile, long long size)963 {964 965 /*@ int ******************************************************** */966 int res;967 968 /*@ end vars *************************************************** */969 970 res = read_file_from_stream_FULL(outfile, NULL, size);971 972 return (res);973 }974 975 976 977 /**978 * Copy a file from the currently opened stream (CD or tape) to the stream indicated979 * by @p fout.980 * @param bkpinfo The backup information structure. @c bkpinfo->media_size is the only field used.981 * @param fout The stream to write the file to.982 * @param size The size of the file in bytes.983 * @return 0 for success, nonzero for failure.984 */985 int986 read_file_from_stream_to_stream(FILE * fout, long long size)987 {988 989 /*@ int ******************************************************** */990 int res;991 992 /*@ end vars *************************************************** */993 994 res = read_file_from_stream_FULL(NULL, fout, size);995 /* fflush(g_tape_stream);996 fflush(fout);*/997 return (res);998 1180 } 999 1181 … … 1147 1329 1148 1330 /** 1149 * Read a header block from the currently opened stream (CD or tape). 1150 * This block indicates the length of the following file (if it's file-related) 1151 * the filename (if it's file-related), and the block type. 1152 * @param plen Where to put the length of the file. Valid only for file-related header blocks. 1153 * @param filename Where to put the name of the file. Valid only for file-related header blocks. 1154 * @param pcontrol_char Where to put the type of block (e.g. start-file, end-file, start-tape, ...) 1155 * @return 0 for success, nonzero for failure. 1156 * @note If you read a marker (@p pcontrol_char) you're not expecting, you can call wrong_marker(). 1331 * Copy a file from the currently opened stream (CD or tape) to the stream indicated 1332 * by @p fout. 1333 * @param bkpinfo The backup information structure. @c bkpinfo->media_size is the only field used. 1334 * @param fout The stream to write the file to. 1335 * @param size The size of the file in bytes. 1336 * @return 0 for success, nonzero for failure. 1157 1337 */ 1158 1338 int 1159 read_header_block_from_stream(long long *plen, char *filename, 1160 int *pcontrol_char) 1161 { 1162 1163 /*@ buffers ***************************************************** */ 1164 char *tempblock; 1165 char *tmp = NULL; 1166 1167 /*@ int ********************************************************* */ 1168 int i, retval; 1339 read_file_from_stream_to_stream(FILE * fout, long long size) 1340 { 1341 1342 /*@ int ******************************************************** */ 1343 int res; 1169 1344 1170 1345 /*@ end vars *************************************************** */ 1171 1346 1172 tempblock = (char *) malloc((size_t) TAPE_BLOCK_SIZE); 1173 1174 for (i = 0; i < (int) TAPE_BLOCK_SIZE; i++) { 1175 tempblock[i] = 0; 1176 } 1177 while (!(*pcontrol_char = tempblock[7000])) { 1178 g_tape_posK += fread(tempblock, 1, (size_t) TAPE_BLOCK_SIZE, g_tape_stream) / 1024; 1179 } 1180 memcpy((char *) plen, tempblock + 7001, sizeof(long long)); 1181 if (strcmp(tempblock + 6000 + *pcontrol_char, STR_HEADER)) { 1182 log_it("Bad header block at %ld K", (long) g_tape_posK); 1183 } 1184 strcpy(filename, tempblock + 1000); 1185 if (*pcontrol_char == BLK_ABORTED_BACKUP) { 1186 log_to_screen("I can't verify an aborted backup."); 1187 retval = 1; 1188 } else { 1189 retval = 0; 1190 } 1191 for (i = 1000; i < 1020; i++) { 1192 if (tempblock[i] < 32 || tempblock[i] > 126) { 1193 tempblock[i] = ' '; 1194 } 1195 } 1196 tempblock[i] = '\0'; 1197 tmp = marker_to_string(*pcontrol_char); 1198 log_msg(6, "%s (fname=%s, size=%ld K)", tmp, tempblock + 1000, (long) (*plen) >> 10); 1199 mr_free(tmp); 1200 paranoid_free(tempblock); 1201 return (retval); 1202 } 1203 1204 1205 1206 /** 1207 * Add specified file/slice to the internal catalog of all archives written. 1208 * This lets us restart on a new CD/tape/whatever if it runs out of room. We just 1209 * write the last [buffer size] MB from the catalog to the new tape, so we know 1210 * we have @e all archives on some CD/tape/whatever. 1211 * @param type The type of file we're cataloging (afioball, slice, something else) 1212 * @param number The fileset number or biggiefile number. 1213 * @param aux The slice number if it's a biggiefile, or any other additional info. 1214 * @param fn The original full pathname of the file we're recording. 1215 * @return The index of the record we just added. 1216 */ 1217 int register_in_tape_catalog(t_archtype type, int number, long aux, 1218 char *fn) 1219 { 1220 int last; 1221 char fname[MAX_TAPECAT_FNAME_LEN+1]; 1222 char *p; 1223 1224 p = strrchr(fn, '/'); 1225 if (p) { 1226 p++; 1227 } else { 1228 p = fn; 1229 } 1230 strncpy(fname, p, MAX_TAPECAT_FNAME_LEN); 1231 fname[MAX_TAPECAT_FNAME_LEN] = '\0'; 1232 last = g_tapecatalog->entries; 1233 if (last >= MAX_TAPECATALOG_ENTRIES) { 1234 log_it 1235 ("Warning - can't log #%d in tape catalog - too many entries already", 1236 number); 1237 return (-1); 1238 } 1239 g_tapecatalog->el[last].type = type; 1240 g_tapecatalog->el[last].number = number; 1241 g_tapecatalog->el[last].aux = aux; 1242 g_tapecatalog->el[last].tape_posK = g_tape_posK; 1243 strcpy(g_tapecatalog->el[last].fname, fname); 1244 g_tapecatalog->entries++; 1245 return (last); // returns the index of the record we've jsut added 1246 } 1247 1248 1249 1250 1251 /** 1252 * Decide whether we should start a new tape. This is TRUE if we've run out of tape 1253 * (got SIGPIPE) or look like we will. 1254 * @param mediasize The size of the tape in megabytes. 1255 * @param length_of_incoming_file The length of the file we're about to write, in bytes. 1256 * @bug This seems like it'll only work for media_size != autodetect, but Mondo only allows 1257 * autodetecting the size. Huh? 1258 */ 1259 1260 /* TODO: Should be reviewed for mediasize being a off_t ??? */ 1261 bool 1262 should_we_write_to_next_tape(long mediasize, 1263 off_t length_of_incoming_file) 1264 { 1265 /*@ bool's ***************************************************** */ 1266 bool we_need_a_new_tape = FALSE; 1267 1268 /*@ end vars *************************************************** */ 1269 1270 if (mediasize == 0) { 1271 return (FALSE); 1272 } 1273 if (mediasize > 0 && (g_tape_posK >> 10 >= mediasize)) { 1274 log_it("mediasize = %ld", mediasize); 1275 we_need_a_new_tape = TRUE; 1276 log_to_screen("Should have started a new tape/CD already"); 1277 } 1278 if ((g_tape_posK + length_of_incoming_file / 1024) >> 10 >= 1279 mediasize - (SLICE_SIZE * 4 / 1024)) { 1280 log_it("g_tape_posK = %ld\nmediasize = %ld\n", g_tape_posK, 1281 mediasize); 1282 we_need_a_new_tape = TRUE; 1283 } 1284 return (we_need_a_new_tape); 1347 res = read_file_from_stream_FULL(NULL, fout, size); 1348 /* fflush(g_tape_stream); 1349 fflush(fout);*/ 1350 return (res); 1285 1351 } 1286 1352 … … 1448 1514 1449 1515 /** 1450 * Start to write to the next tape. Assume the user has already inserted it. 1451 * @param bkpinfo The backup information structure. @c bkpinfo->media_device is the only field used. 1452 * @return 0 for success, nonzero for failure. 1453 */ 1454 int start_to_write_to_next_tape() 1455 { 1456 int res = 0; 1457 char *command = NULL; 1458 1459 if (bkpinfo->media_device == NULL) { 1460 log_it("Unable to open out from NULL device"); 1461 return (1); 1462 } 1463 1464 paranoid_pclose(g_tape_stream); 1465 sync(); 1466 sync(); 1467 sync(); 1468 log_it("New tape requested."); 1469 insist_on_this_tape_number(g_current_media_number + 1); // will increment g_current_media, too 1470 if (bkpinfo->backup_media_type == cdstream) { 1471 mr_asprintf(command, "cdrecord -eject dev=%s speed=%d fs=24m -waiti - >> %s 2>> %s", bkpinfo->media_device, bkpinfo->cdrw_speed, MONDO_LOGFILE, MONDO_LOGFILE); 1472 log_it("Opening OUT to next CD with the command"); 1473 log_it(command); 1474 log_it("Let's see what happens, shall we?"); 1475 g_tape_stream = popen(command, "w"); 1476 mr_free(command); 1477 1478 if (!g_tape_stream) { 1479 log_to_screen("Failed to openout to cdstream (fifo)"); 1480 return (1); 1481 } 1482 } else { 1483 log_it("Opening OUT to next tape"); 1484 if (!(g_tape_stream = open_device_via_buffer(bkpinfo->media_device, 'w', bkpinfo->internal_tape_block_size))) { 1485 log_OS_error(g_tape_fifo); 1486 log_to_screen("Cannot openin stream device"); 1487 return (1); 1488 } 1489 } 1490 g_tape_posK = 0; 1491 g_sigpipe = FALSE; 1492 res += write_header_block_to_stream((off_t)0, "start-of-tape", BLK_START_OF_TAPE); /* just in case */ 1493 res += write_header_block_to_stream((off_t)0, "start-of-backup", BLK_START_OF_BACKUP); /* just in case */ 1494 return (res); 1516 * Read a header block from the currently opened stream (CD or tape). 1517 * This block indicates the length of the following file (if it's file-related) 1518 * the filename (if it's file-related), and the block type. 1519 * @param plen Where to put the length of the file. Valid only for file-related header blocks. 1520 * @param filename Where to put the name of the file. Valid only for file-related header blocks. 1521 * @param pcontrol_char Where to put the type of block (e.g. start-file, end-file, start-tape, ...) 1522 * @return 0 for success, nonzero for failure. 1523 * @note If you read a marker (@p pcontrol_char) you're not expecting, you can call wrong_marker(). 1524 */ 1525 int 1526 read_header_block_from_stream(long long *plen, char *filename, 1527 int *pcontrol_char) 1528 { 1529 1530 /*@ buffers ***************************************************** */ 1531 char *tempblock; 1532 char *tmp = NULL; 1533 1534 /*@ int ********************************************************* */ 1535 int i, retval; 1536 1537 /*@ end vars *************************************************** */ 1538 1539 tempblock = (char *) malloc((size_t) TAPE_BLOCK_SIZE); 1540 1541 for (i = 0; i < (int) TAPE_BLOCK_SIZE; i++) { 1542 tempblock[i] = 0; 1543 } 1544 while (!(*pcontrol_char = tempblock[7000])) { 1545 g_tape_posK += fread(tempblock, 1, (size_t) TAPE_BLOCK_SIZE, g_tape_stream) / 1024; 1546 } 1547 memcpy((char *) plen, tempblock + 7001, sizeof(long long)); 1548 if (strcmp(tempblock + 6000 + *pcontrol_char, STR_HEADER)) { 1549 log_it("Bad header block at %ld K", (long) g_tape_posK); 1550 } 1551 strcpy(filename, tempblock + 1000); 1552 if (*pcontrol_char == BLK_ABORTED_BACKUP) { 1553 log_to_screen("I can't verify an aborted backup."); 1554 retval = 1; 1555 } else { 1556 retval = 0; 1557 } 1558 for (i = 1000; i < 1020; i++) { 1559 if (tempblock[i] < 32 || tempblock[i] > 126) { 1560 tempblock[i] = ' '; 1561 } 1562 } 1563 tempblock[i] = '\0'; 1564 tmp = marker_to_string(*pcontrol_char); 1565 log_msg(6, "%s (fname=%s, size=%ld K)", tmp, tempblock + 1000, (long) (*plen) >> 10); 1566 mr_free(tmp); 1567 paranoid_free(tempblock); 1568 return (retval); 1569 } 1570 1571 1572 1573 /** 1574 * Add specified file/slice to the internal catalog of all archives written. 1575 * This lets us restart on a new CD/tape/whatever if it runs out of room. We just 1576 * write the last [buffer size] MB from the catalog to the new tape, so we know 1577 * we have @e all archives on some CD/tape/whatever. 1578 * @param type The type of file we're cataloging (afioball, slice, something else) 1579 * @param number The fileset number or biggiefile number. 1580 * @param aux The slice number if it's a biggiefile, or any other additional info. 1581 * @param fn The original full pathname of the file we're recording. 1582 * @return The index of the record we just added. 1583 */ 1584 int register_in_tape_catalog(t_archtype type, int number, long aux, 1585 char *fn) 1586 { 1587 int last; 1588 char fname[MAX_TAPECAT_FNAME_LEN+1]; 1589 char *p; 1590 1591 p = strrchr(fn, '/'); 1592 if (p) { 1593 p++; 1594 } else { 1595 p = fn; 1596 } 1597 strncpy(fname, p, MAX_TAPECAT_FNAME_LEN); 1598 fname[MAX_TAPECAT_FNAME_LEN] = '\0'; 1599 last = g_tapecatalog->entries; 1600 if (last >= MAX_TAPECATALOG_ENTRIES) { 1601 log_it 1602 ("Warning - can't log #%d in tape catalog - too many entries already", 1603 number); 1604 return (-1); 1605 } 1606 g_tapecatalog->el[last].type = type; 1607 g_tapecatalog->el[last].number = number; 1608 g_tapecatalog->el[last].aux = aux; 1609 g_tapecatalog->el[last].tape_posK = g_tape_posK; 1610 strcpy(g_tapecatalog->el[last].fname, fname); 1611 g_tapecatalog->entries++; 1612 return (last); // returns the index of the record we've jsut added 1495 1613 } 1496 1614 … … 1600 1718 1601 1719 1602 /**1603 * Copy @p infile to the opened stream (CD or tape).1604 * @param bkpinfo The backup information structure. @c bkpinfo->media_size is the only field used.1605 * @param infile The file to write to the stream.1606 * @return 0 for success, nonzero for failure.1607 */1608 int write_file_to_stream_from_file(char *infile)1609 {1610 /*@ buffers **************************************************** */1611 char datablock[TAPE_BLOCK_SIZE];1612 char *checksum = NULL;1613 char *infile_basename;1614 1615 /*@ int ******************************************************** */1616 int retval = 0;1617 int noof_blocks;1618 1619 /* unsigned int ch; */1620 unsigned int crc16;1621 unsigned int crctt;1622 1623 /*@ pointers *************************************************** */1624 FILE *fin;1625 char *p;1626 1627 /*@ long ******************************************************* */1628 long bytes_to_read = 0;1629 long i;1630 1631 off_t filesize;1632 1633 #ifdef EXTRA_TAPE_CHECKSUMS1634 int ch;1635 #endif1636 1637 /*@ initialize ************************************************ */1638 crc16 = 0;1639 crctt = 0;1640 1641 1642 1643 /*@ end vars *************************************************** */1644 1645 infile_basename = strrchr(infile, '/');1646 if (infile_basename) {1647 infile_basename++;1648 } else {1649 infile_basename = infile;1650 }1651 filesize = length_of_file(infile);1652 if (should_we_write_to_next_tape(bkpinfo->media_size, filesize)) {1653 start_to_write_to_next_tape();1654 write_backcatalog_to_tape();1655 }1656 p = strrchr(infile, '/');1657 if (!p) {1658 p = infile;1659 } else {1660 p++;1661 }1662 log_it("Writing file '%s' to tape (%ld KB)", p, (long) filesize >> 10);1663 write_header_block_to_stream(filesize, infile_basename, BLK_START_FILE);1664 //go_here_to_restart_saving_of_file:1665 if (!(fin = fopen(infile, "r"))) {1666 log_OS_error(infile);1667 return (1);1668 }1669 for (noof_blocks = 0; filesize > 0;1670 noof_blocks++, filesize -= bytes_to_read) {1671 if (filesize < TAPE_BLOCK_SIZE) {1672 bytes_to_read = (long) filesize;1673 for (i = 0; i < TAPE_BLOCK_SIZE; i++) {1674 datablock[i] = '\0';1675 }1676 } else {1677 bytes_to_read = TAPE_BLOCK_SIZE;1678 }1679 if (fread(datablock, 1, (size_t) bytes_to_read, fin)) {1680 // FIXME1681 }1682 g_tape_posK +=1683 fwrite(datablock, 1, /*bytes_to_read */1684 (size_t) TAPE_BLOCK_SIZE,1685 g_tape_stream) / 1024;1686 if (g_sigpipe) {1687 log_it("Sigpipe occurred recently. I'll start a new tape.");1688 fclose(fin);1689 g_sigpipe = FALSE;1690 start_to_write_to_next_tape();1691 write_backcatalog_to_tape(); // kinda-sorta recursive :)1692 return (0);1693 }1694 #ifdef EXTRA_TAPE_CHECKSUMS1695 for (i = 0; i < bytes_to_read; i++) {1696 ch = datablock[i];1697 crc16 = updcrcr(crc16, (unsigned) ch);1698 crctt = updcrc(crctt, (unsigned) ch);1699 }1700 #endif1701 }1702 paranoid_fclose(fin);1703 mr_asprintf(checksum, "%04x%04x", crc16, crctt);1704 /* TODO: what does it do ??? */1705 write_header_block_to_stream((off_t)g_current_media_number, checksum, BLK_STOP_FILE);1706 mr_free(checksum);1707 1708 // log_it("File '%s' written to tape.", infile);1709 return (retval);1710 }1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1720 1721 -
branches/3.3/mondo/src/common/libmondo-tools.c
r3874 r3877 650 650 651 651 /** 652 * Check the user's system for sanity. Checks performed: 653 * - make sure user has enough RAM (32mb required, 64mb recommended) 654 * - make sure user has enough free space in @c / 655 * - check kernel for ramdisk support 656 * - make sure afio, cdrecord, mkisofs, bzip2, awk, md5sum, strings, mindi, and buffer exist 657 * - make sure CD-ROM is unmounted 658 * - make sure user's mountlist is OK by running <tt>mindi --makemountlist</tt> 659 * 660 * @return number of problems with the user's setup (0 for success) 661 */ 662 int some_basic_system_sanity_checks() 663 { 664 665 /*@ buffers ************ */ 666 char *tmp = NULL; 667 668 /*@ int's *************** */ 669 int retval = 0; 670 671 mvaddstr_and_log_it(g_currentY, 0, "Checking sanity of your Linux distribution"); 672 #ifndef __FreeBSD__ 673 if (system("which mkfs.vfat 2> /dev/null 1> /dev/null") 674 && !system("which mkfs.msdos 2> /dev/null 1> /dev/null")) { 675 log_it("OK, you've got mkfs.msdos but not mkfs.vfat; time for the fairy to wave her magic wand..."); 676 run_program_and_log_output("ln -sf `which mkfs.msdos` /sbin/mkfs.vfat", FALSE); 677 } 678 tmp = call_program_and_get_last_line_of_output("free | grep Mem | head -n1 | tr -s ' ' '\t' | cut -f2"); 679 if (atol(tmp) < 35000) { 680 retval++; 681 log_to_screen("You must have at least 32MB of RAM to use Mondo."); 682 } 683 if (atol(tmp) < 66000) { 684 log_to_screen("WARNING! You have very little RAM. Please upgrade to 64MB or more."); 685 } 686 mr_free(tmp); 687 #endif 688 689 if (system("which " MKE2FS_OR_NEWFS " > /dev/null 2> /dev/null")) { 690 retval++; 691 log_to_screen("Unable to find " MKE2FS_OR_NEWFS " in system path."); 692 fatal_error("Please use \"su -\", not \"su\" to become root. OK?\n...and please don't e-mail the mailing list about this. Just read the message. :)"); 693 } 694 #ifndef __FreeBSD__ 695 if (run_program_and_log_output("grep ramdisk /proc/devices", FALSE)) { 696 /* Some SuSE have ramdisk as modules, so insert it first, then test again */ 697 run_program_and_log_output("modprobe brd 2> /dev/null > /dev/null",FALSE); 698 if (run_program_and_log_output("grep ramdisk /proc/devices", FALSE)) { 699 if (!ask_me_yes_or_no("Your kernel has no ramdisk support. That's mind-numbingly stupid but I'll allow it if you're planning to use another kernel. Are you?")) { 700 // retval++; 701 log_to_screen("It looks as if your kernel lacks ramdisk and initrd support."); 702 log_to_screen("I'll allow you to proceed but FYI, if I'm right, your kernel is broken."); 703 } 704 } 705 } 706 #endif 707 retval += whine_if_not_found(MKE2FS_OR_NEWFS); 708 if (system("which xorriso > /dev/null 2> /dev/null")) { 709 if (system("which genisoimage > /dev/null 2> /dev/null")) { 710 retval += whine_if_not_found("mkisofs"); 711 } 712 } 713 if (system("which wodim > /dev/null 2> /dev/null")) { 714 retval += whine_if_not_found("cdrecord"); 715 } 716 retval += whine_if_not_found("bzip2"); 717 retval += whine_if_not_found("gzip"); 718 retval += whine_if_not_found("cmp"); 719 retval += whine_if_not_found("awk"); 720 retval += whine_if_not_found("md5sum"); 721 retval += whine_if_not_found("strings"); 722 retval += whine_if_not_found("mindi"); 723 retval += whine_if_not_found("buffer"); 724 725 // abort if Windows partition but no ms-sys and parted 726 if (!run_program_and_log_output("mount | grep -Ew 'vfat|fat|dos' | grep -vE \"/dev/fd|nexdisk\"", 0)) { 727 if (!run_program_and_log_output("mount | grep -Ew 'vfat|fat|dos' | grep -Ew efi", 0)) { 728 log_to_screen("I think you have a EFI/UEFI partition."); 729 } else { 730 log_to_screen("I think you have a Windows 9x partition."); 731 } 732 retval += whine_if_not_found("parted"); 733 } 734 735 run_program_and_log_output("umount `mount | grep cdr | cut -d' ' -f3 | tr '\n' ' '`", 5); 736 tmp = call_program_and_get_last_line_of_output("mount | grep -E 'cdr(om|w)'"); 737 if (strcmp("", tmp)) { 738 if (strstr(tmp, "autofs")) { 739 log_to_screen("Your CD-ROM is mounted via autofs. I therefore cannot tell"); 740 log_to_screen("if a CD actually is inserted. If a CD is inserted, please"); 741 log_to_screen("eject it. Thank you."); 742 log_it("Ignoring autofs CD-ROM 'mount' since we hope nothing's in it."); 743 } else 744 if (run_program_and_log_output("uname -a | grep Knoppix", 5)) { 745 retval++; 746 mr_free(tmp); 747 fatal_error("Your CD-ROM drive is mounted. Please unmount it."); 748 } 749 } 750 mr_free(tmp); 751 752 run_program_and_log_output("cat /etc/fstab", 5); 753 #ifdef __FreeBSD__ 754 run_program_and_log_output("vinum printconfig", 5); 755 #else 756 run_program_and_log_output("cat /etc/raidtab", 5); 757 #endif 758 759 if (run_program_and_log_output("mindi -V", 1)) { 760 log_to_screen("Could not ascertain mindi's version number."); 761 log_to_screen("You have not installed Mondo and/or Mindi properly."); 762 log_to_screen("Please uninstall and reinstall them both."); 763 fatal_error("Please reinstall Mondo and Mindi."); 764 } 765 mr_asprintf(tmp, "mindi --makemountlist %s/mountlist.txt.test", bkpinfo->tmpdir); 766 if (run_program_and_log_output(tmp, 5)) { 767 log_to_screen("%s failed for some reason.", tmp); 768 mr_free(tmp); 769 log_to_screen("Please run that command by hand and examine "MINDI_LOGFILE); 770 log_to_screen("for more information. Perhaps your /etc/fstab file is insane."); 771 log_to_screen("Perhaps Mindi's MakeMountlist() subroutine has a bug. We'll see."); 772 retval++; 773 } 774 mr_free(tmp); 775 776 if (!run_program_and_log_output("mr-parted2fdisk -l 2>/dev/null | grep -i raid", 1) && !does_file_exist("/etc/raidtab")) { 777 log_to_screen("You have RAID partitions but no /etc/raidtab - creating one from /proc/mdstat"); 778 create_raidtab_from_mdstat(MDSTAT_FILE,"/etc/raidtab"); 779 } 780 781 if (retval) { 782 mvaddstr_and_log_it(g_currentY++, 74, "Failed."); 783 } else { 784 mvaddstr_and_log_it(g_currentY++, 74, "Done."); 785 } 786 return (retval); 787 } 788 789 790 791 /** 652 792 * Do some miscellaneous setup tasks to be performed before filling @c bkpinfo. 653 793 * Seeds the random-number generator, loads important modules, checks the sanity … … 897 1037 } 898 1038 899 900 901 /**902 * Check the user's system for sanity. Checks performed:903 * - make sure user has enough RAM (32mb required, 64mb recommended)904 * - make sure user has enough free space in @c /905 * - check kernel for ramdisk support906 * - make sure afio, cdrecord, mkisofs, bzip2, awk, md5sum, strings, mindi, and buffer exist907 * - make sure CD-ROM is unmounted908 * - make sure user's mountlist is OK by running <tt>mindi --makemountlist</tt>909 *910 * @return number of problems with the user's setup (0 for success)911 */912 int some_basic_system_sanity_checks()913 {914 915 /*@ buffers ************ */916 char *tmp = NULL;917 918 /*@ int's *************** */919 int retval = 0;920 921 mvaddstr_and_log_it(g_currentY, 0, "Checking sanity of your Linux distribution");922 #ifndef __FreeBSD__923 if (system("which mkfs.vfat 2> /dev/null 1> /dev/null")924 && !system("which mkfs.msdos 2> /dev/null 1> /dev/null")) {925 log_it("OK, you've got mkfs.msdos but not mkfs.vfat; time for the fairy to wave her magic wand...");926 run_program_and_log_output("ln -sf `which mkfs.msdos` /sbin/mkfs.vfat", FALSE);927 }928 tmp = call_program_and_get_last_line_of_output("free | grep Mem | head -n1 | tr -s ' ' '\t' | cut -f2");929 if (atol(tmp) < 35000) {930 retval++;931 log_to_screen("You must have at least 32MB of RAM to use Mondo.");932 }933 if (atol(tmp) < 66000) {934 log_to_screen("WARNING! You have very little RAM. Please upgrade to 64MB or more.");935 }936 mr_free(tmp);937 #endif938 939 if (system("which " MKE2FS_OR_NEWFS " > /dev/null 2> /dev/null")) {940 retval++;941 log_to_screen("Unable to find " MKE2FS_OR_NEWFS " in system path.");942 fatal_error("Please use \"su -\", not \"su\" to become root. OK?\n...and please don't e-mail the mailing list about this. Just read the message. :)");943 }944 #ifndef __FreeBSD__945 if (run_program_and_log_output("grep ramdisk /proc/devices", FALSE)) {946 /* Some SuSE have ramdisk as modules, so insert it first, then test again */947 run_program_and_log_output("modprobe brd 2> /dev/null > /dev/null",FALSE);948 if (run_program_and_log_output("grep ramdisk /proc/devices", FALSE)) {949 if (!ask_me_yes_or_no("Your kernel has no ramdisk support. That's mind-numbingly stupid but I'll allow it if you're planning to use another kernel. Are you?")) {950 // retval++;951 log_to_screen("It looks as if your kernel lacks ramdisk and initrd support.");952 log_to_screen("I'll allow you to proceed but FYI, if I'm right, your kernel is broken.");953 }954 }955 }956 #endif957 retval += whine_if_not_found(MKE2FS_OR_NEWFS);958 if (system("which xorriso > /dev/null 2> /dev/null")) {959 if (system("which genisoimage > /dev/null 2> /dev/null")) {960 retval += whine_if_not_found("mkisofs");961 }962 }963 if (system("which wodim > /dev/null 2> /dev/null")) {964 retval += whine_if_not_found("cdrecord");965 }966 retval += whine_if_not_found("bzip2");967 retval += whine_if_not_found("gzip");968 retval += whine_if_not_found("cmp");969 retval += whine_if_not_found("awk");970 retval += whine_if_not_found("md5sum");971 retval += whine_if_not_found("strings");972 retval += whine_if_not_found("mindi");973 retval += whine_if_not_found("buffer");974 975 // abort if Windows partition but no ms-sys and parted976 if (!run_program_and_log_output("mount | grep -Ew 'vfat|fat|dos' | grep -vE \"/dev/fd|nexdisk\"", 0)) {977 if (!run_program_and_log_output("mount | grep -Ew 'vfat|fat|dos' | grep -Ew efi", 0)) {978 log_to_screen("I think you have a EFI/UEFI partition.");979 } else {980 log_to_screen("I think you have a Windows 9x partition.");981 }982 retval += whine_if_not_found("parted");983 }984 985 run_program_and_log_output("umount `mount | grep cdr | cut -d' ' -f3 | tr '\n' ' '`", 5);986 tmp = call_program_and_get_last_line_of_output("mount | grep -E 'cdr(om|w)'");987 if (strcmp("", tmp)) {988 if (strstr(tmp, "autofs")) {989 log_to_screen("Your CD-ROM is mounted via autofs. I therefore cannot tell");990 log_to_screen("if a CD actually is inserted. If a CD is inserted, please");991 log_to_screen("eject it. Thank you.");992 log_it("Ignoring autofs CD-ROM 'mount' since we hope nothing's in it.");993 } else994 if (run_program_and_log_output("uname -a | grep Knoppix", 5)) {995 retval++;996 mr_free(tmp);997 fatal_error("Your CD-ROM drive is mounted. Please unmount it.");998 }999 }1000 mr_free(tmp);1001 1002 run_program_and_log_output("cat /etc/fstab", 5);1003 #ifdef __FreeBSD__1004 run_program_and_log_output("vinum printconfig", 5);1005 #else1006 run_program_and_log_output("cat /etc/raidtab", 5);1007 #endif1008 1009 if (run_program_and_log_output("mindi -V", 1)) {1010 log_to_screen("Could not ascertain mindi's version number.");1011 log_to_screen("You have not installed Mondo and/or Mindi properly.");1012 log_to_screen("Please uninstall and reinstall them both.");1013 fatal_error("Please reinstall Mondo and Mindi.");1014 }1015 mr_asprintf(tmp, "mindi --makemountlist %s/mountlist.txt.test", bkpinfo->tmpdir);1016 if (run_program_and_log_output(tmp, 5)) {1017 log_to_screen("%s failed for some reason.", tmp);1018 mr_free(tmp);1019 log_to_screen("Please run that command by hand and examine "MINDI_LOGFILE);1020 log_to_screen("for more information. Perhaps your /etc/fstab file is insane.");1021 log_to_screen("Perhaps Mindi's MakeMountlist() subroutine has a bug. We'll see.");1022 retval++;1023 }1024 mr_free(tmp);1025 1026 if (!run_program_and_log_output("mr-parted2fdisk -l 2>/dev/null | grep -i raid", 1) && !does_file_exist("/etc/raidtab")) {1027 log_to_screen("You have RAID partitions but no /etc/raidtab - creating one from /proc/mdstat");1028 create_raidtab_from_mdstat(MDSTAT_FILE,"/etc/raidtab");1029 }1030 1031 if (retval) {1032 mvaddstr_and_log_it(g_currentY++, 74, "Failed.");1033 } else {1034 mvaddstr_and_log_it(g_currentY++, 74, "Done.");1035 }1036 return (retval);1037 }1038 1039 1039 /** 1040 1040 * Retrieve the line containing @p label from the config file. -
branches/3.3/mondo/src/common/libmondo-verify.c
r3871 r3877 19 19 #include "libmondo-devices-EXT.h" 20 20 #include "libmondo-tools-EXT.h" 21 #include "libmondo-filelist-EXT.h" 21 22 22 23 … … 33 34 extern char *g_getfattr; 34 35 extern char *MONDO_LOGFILE; 36 extern int g_current_media_number; 37 extern long g_current_progress; 35 38 36 39 /* Reference to global bkpinfo */ … … 316 319 } else if (does_file_exist(slice_fname(bigfile_num, slice_num, mountpoint, "")) && 317 320 (length_of_file(slice_fname(bigfile_num, slice_num, mountpoint, "")) == 0)) { 318 log_msg(2, "ISO=%d bigfile=%ld ---END---", 319 g_current_media_number, bigfile_num); 321 log_msg(2, "ISO=%d bigfile=%ld ---END---", g_current_media_number, bigfile_num); 320 322 bigfile_num++; 321 323 paranoid_fclose(forig);
Note:
See TracChangeset
for help on using the changeset viewer.