Changeset 3877 in MondoRescue for branches/3.3/mondo/src/common/libmondo-archive.c
- Timestamp:
- Mar 8, 2024, 3:59:07 AM (4 months ago)
- File:
-
- 1 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
Note:
See TracChangeset
for help on using the changeset viewer.