Changeset 2369 in MondoRescue
- Timestamp:
- Sep 7, 2009, 6:03:40 PM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/2.2.9/mondo/src/common/libmondo-filelist.c
r2366 r2369 1269 1269 1270 1270 /** 1271 * Create the filelist for the backup. It will be stored in [scratchdir]/archives/filelist.full.1272 * @param logfile Unused.1273 * @param tmpdir The tmpdir of the backup.1274 * @param scratchdir The scratchdir of the backup.1275 * @param include_paths The paths to back up, or NULL if you're using a user-defined filelist.1276 * @param excp The paths to NOT back up.1277 * @param differential The differential level (currently only 0 and 1 are supported).1278 * @param userdef_filelist The user-defined filelist, or NULL if you're using @p include_paths.1279 * @return 0, always.1280 * @bug @p logfile is unused.1281 * @bug Return value is meaningless.1282 */1283 int mondo_makefilelist(char *logfile, char *tmpdir, char *scratchdir,1284 char *include_paths, char *excp, int differential,1285 char *userdef_filelist)1286 {1287 char *p, *q;1288 char *sz_datefile;1289 char *sz_filelist, *exclude_paths, *tmp;1290 int i;1291 FILE *fout;1292 char *command;1293 time_t time_of_last_full_backup = 0;1294 struct stat statbuf;1295 char *tmp1 = NULL;1296 char *tmp2 = NULL;1297 1298 malloc_string(command);1299 malloc_string(tmp);1300 malloc_string(g_skeleton_filelist);1301 if (!(exclude_paths = malloc(8*MAX_STR_LEN))) {1302 fatal_error("Cannot malloc exclude_paths");1303 }1304 mr_asprintf(&sz_datefile,MONDO_CACHE"/difflevel.%d" , 0);1305 if (!include_paths && !userdef_filelist) {1306 fatal_error1307 ("Please supply either include_paths or userdef_filelist");1308 }1309 // make hole for filelist1310 sprintf(command, "mkdir -p %s/archives", scratchdir);1311 paranoid_system(command);1312 mr_asprintf(&sz_filelist, "%s/tmpfs/filelist.full", tmpdir);1313 make_hole_for_file(sz_filelist);1314 1315 if (differential == 0) {1316 // restore last good datefile if it exists1317 sprintf(command, "cp -f %s.aborted %s", sz_datefile, sz_datefile);1318 run_program_and_log_output(command, 3);1319 // backup last known good datefile just in case :)1320 if (does_file_exist(sz_datefile)) {1321 sprintf(command, "mv -f %s %s.aborted", sz_datefile,1322 sz_datefile);1323 paranoid_system(command);1324 }1325 make_hole_for_file(sz_datefile);1326 write_one_liner_data_file(sz_datefile,1327 call_program_and_get_last_line_of_output1328 ("date +%s"));1329 } else if (lstat(sz_datefile, &statbuf)) {1330 log_msg(2,1331 "Warning - unable to find date of previous backup. Full backup instead.");1332 differential = 0;1333 time_of_last_full_backup = 0;1334 } else {1335 time_of_last_full_backup = statbuf.st_mtime;1336 log_msg(2, "Differential backup. Yay.");1337 }1338 paranoid_free(sz_datefile);1339 1340 // use user-specified filelist (if specified)1341 if (userdef_filelist) {1342 log_msg(1,1343 "Using the user-specified filelist - %s - instead of calculating one",1344 userdef_filelist);1345 sprintf(command, "cp -f %s %s", userdef_filelist, sz_filelist);1346 if (run_program_and_log_output(command, 3)) {1347 fatal_error("Failed to copy user-specified filelist");1348 }1349 } else {1350 log_msg(2, "include_paths = '%s'", include_paths);1351 log_msg(1, "Calculating filelist");1352 mr_asprintf(&tmp2, "%s", call_program_and_get_last_line_of_output("mount | grep -Ew 'ntfs|ntfs-3g|fat|vfat|dos' | awk '{print $3}'"));1353 if (strlen(tmp2) < 1) {1354 mr_asprintf(&tmp1," ");1355 } else {1356 log_msg(2, "Found windows FS: %s",tmp2);1357 mr_asprintf(&tmp1, "find %s -name '/win386.swp' -o -name '/hiberfil.sys' -o -name '/pagefile.sys' 2> /dev/null\n",tmp2);1358 paranoid_free(tmp2);1359 mr_asprintf(&tmp2, "%s", call_program_and_get_last_line_of_output(tmp1));1360 log_msg(2, "Found windows files: %s",tmp2);1361 }1362 paranoid_free(tmp1);1363 1364 snprintf(exclude_paths, (size_t)8*MAX_STR_LEN," %s %s %s %s %s . .. \1365 " MNT_CDROM " " MNT_FLOPPY " /media /tmp \1366 /proc /sys " MINDI_CACHE, MONDO_CACHE, excp, tmp2, (tmpdir[0] == '/' && tmpdir[1] == '/') ? (tmpdir + 1) : tmpdir, (scratchdir[0] == '/' && scratchdir[1] == '/') ? (scratchdir + 1) : scratchdir);1367 paranoid_free(tmp2);1368 1369 log_msg(2, "Excluding paths = '%s'", exclude_paths);1370 log_msg(2,1371 "Generating skeleton filelist so that we can track our progress");1372 sprintf(g_skeleton_filelist, "%s/tmpfs/skeleton.txt", tmpdir);1373 make_hole_for_file(g_skeleton_filelist);1374 log_msg(4, "g_skeleton_entries = %ld", g_skeleton_entries);1375 log_msg(2, "Opening out filelist to %s", sz_filelist);1376 if (!(fout = fopen(sz_filelist, "w"))) {1377 fatal_error("Cannot openout to sz_filelist");1378 }1379 i = 0;1380 if (strlen(include_paths) == 0) {1381 log_msg(1, "Including only '/' in %s", sz_filelist);1382 open_and_list_dir("/", exclude_paths, fout,1383 time_of_last_full_backup);1384 } else {1385 p = include_paths;1386 while (*p) {1387 q = next_entry(p);1388 log_msg(1, "Including %s in filelist %s", q, sz_filelist);1389 open_and_list_dir(q, exclude_paths, fout,1390 time_of_last_full_backup);1391 p += strlen(q);1392 paranoid_free(q);1393 while (*p == ' ') {1394 p++;1395 }1396 }1397 }1398 paranoid_fclose(fout);1399 }1400 log_msg(2, "Copying new filelist to scratchdir");1401 sprintf(command, "mkdir -p %s/archives", scratchdir);1402 paranoid_system(command);1403 sprintf(command, "cp -f %s %s/archives/", sz_filelist, scratchdir);1404 paranoid_system(command);1405 sprintf(command, "mv -f %s %s", sz_filelist, tmpdir);1406 paranoid_system(command);1407 paranoid_free(sz_filelist);1408 log_msg(2, "Freeing variables");1409 paranoid_free(command);1410 paranoid_free(exclude_paths);1411 paranoid_free(tmp);1412 paranoid_free(g_skeleton_filelist);1413 log_msg(2, "Exiting");1414 return (0);1415 }1416 1417 1418 1419 1420 1421 1422 1423 /**1424 1271 * The pathname to the skeleton filelist, used to give better progress reporting for mondo_makefilelist(). 1425 1272 */ 1426 1273 char *g_skeleton_filelist = NULL; 1427 1274 1275 1276 1277 /** 1278 * Get the next entry in the space-separated list in @p incoming. 1279 * So if @p incoming was '"one and two" three four', we would 1280 * return "one and two". 1281 * @param incoming The list to get the next entry from. 1282 * @return The first item in the list (respecting double quotes). 1283 * @note The returned string points to static data that will be overwritten with each call. 1284 */ 1285 char *next_entry(char *incoming) 1286 { 1287 char *sz_res; 1288 char *p; 1289 bool in_quotes = FALSE; 1290 1291 mr_asprintf(&sz_res, "%s", incoming); 1292 p = sz_res; 1293 while ((*p != ' ' || in_quotes) && *p != '\0') { 1294 if (*p == '\"') { 1295 in_quotes = !in_quotes; 1296 } 1297 p++; 1298 } 1299 *p = '\0'; 1300 return (sz_res); 1301 } 1302 1303 1304 1305 1428 1306 /** 1429 1307 * Number of entries in the skeleton filelist. 1430 1308 */ 1431 1309 long g_skeleton_entries = 0; 1432 1433 /**1434 * Wrapper around mondo_makefilelist().1435 * @param bkpinfo The backup information structure. Fields used:1436 * - @c bkpinfo->differential1437 * - @c bkpinfo->exclude_paths1438 * - @c bkpinfo->include_paths1439 * - @c bkpinfo->make_filelist1440 * - @c bkpinfo->scratchdir1441 * - @c bkpinfo->tmpdir1442 * @return 0 for success, nonzero for failure.1443 * @see mondo_makefilelist1444 */1445 int prepare_filelist()1446 {1447 1448 /*@ int **************************************************** */1449 int res = 0;1450 1451 assert(bkpinfo != NULL);1452 log_it("tmpdir=%s; scratchdir=%s", bkpinfo->tmpdir,1453 bkpinfo->scratchdir);1454 if (bkpinfo->make_filelist) {1455 mvaddstr_and_log_it(g_currentY, 0,1456 "Making catalog of files to be backed up");1457 } else {1458 mvaddstr_and_log_it(g_currentY, 0,1459 "Using supplied catalog of files to be backed up");1460 }1461 1462 if (bkpinfo->make_filelist) {1463 res =1464 mondo_makefilelist(MONDO_LOGFILE, bkpinfo->tmpdir,1465 bkpinfo->scratchdir, bkpinfo->include_paths,1466 bkpinfo->exclude_paths,1467 bkpinfo->differential, NULL);1468 } else {1469 res =1470 mondo_makefilelist(MONDO_LOGFILE, bkpinfo->tmpdir,1471 bkpinfo->scratchdir, NULL,1472 bkpinfo->exclude_paths,1473 bkpinfo->differential,1474 bkpinfo->include_paths);1475 }1476 1477 if (res) {1478 log_OS_error("Call to mondo_makefilelist failed");1479 mvaddstr_and_log_it(g_currentY++, 74, "Failed.");1480 } else {1481 mvaddstr_and_log_it(g_currentY++, 74, "Done.");1482 }1483 return (res);1484 }1485 1310 1486 1311 … … 1678 1503 1679 1504 /** 1680 * Get the next entry in the space-separated list in @p incoming. 1681 * So if @p incoming was '"one and two" three four', we would 1682 * return "one and two". 1683 * @param incoming The list to get the next entry from. 1684 * @return The first item in the list (respecting double quotes). 1685 * @note The returned string points to static data that will be overwritten with each call. 1686 */ 1687 char *next_entry(char *incoming) 1688 { 1689 char *sz_res; 1690 char *p; 1691 bool in_quotes = FALSE; 1692 1693 mr_asprintf(&sz_res, "%s", incoming); 1694 p = sz_res; 1695 while ((*p != ' ' || in_quotes) && *p != '\0') { 1696 if (*p == '\"') { 1697 in_quotes = !in_quotes; 1698 } 1699 p++; 1700 } 1701 *p = '\0'; 1702 return (sz_res); 1703 } 1704 1505 * Create the filelist for the backup. It will be stored in [scratchdir]/archives/filelist.full. 1506 * @param logfile Unused. 1507 * @param tmpdir The tmpdir of the backup. 1508 * @param scratchdir The scratchdir of the backup. 1509 * @param include_paths The paths to back up, or NULL if you're using a user-defined filelist. 1510 * @param excp The paths to NOT back up. 1511 * @param differential The differential level (currently only 0 and 1 are supported). 1512 * @param userdef_filelist The user-defined filelist, or NULL if you're using @p include_paths. 1513 * @return 0, always. 1514 * @bug @p logfile is unused. 1515 * @bug Return value is meaningless. 1516 */ 1517 int mondo_makefilelist(char *logfile, char *tmpdir, char *scratchdir, 1518 char *include_paths, char *excp, int differential, 1519 char *userdef_filelist) 1520 { 1521 char *p, *q; 1522 char *sz_datefile; 1523 char *sz_filelist, *exclude_paths, *tmp; 1524 int i; 1525 FILE *fout; 1526 char *command; 1527 time_t time_of_last_full_backup = 0; 1528 struct stat statbuf; 1529 char *tmp1 = NULL; 1530 char *tmp2 = NULL; 1531 1532 malloc_string(command); 1533 malloc_string(tmp); 1534 malloc_string(g_skeleton_filelist); 1535 if (!(exclude_paths = malloc(8*MAX_STR_LEN))) { 1536 fatal_error("Cannot malloc exclude_paths"); 1537 } 1538 mr_asprintf(&sz_datefile,MONDO_CACHE"/difflevel.%d" , 0); 1539 if (!include_paths && !userdef_filelist) { 1540 fatal_error 1541 ("Please supply either include_paths or userdef_filelist"); 1542 } 1543 // make hole for filelist 1544 sprintf(command, "mkdir -p %s/archives", scratchdir); 1545 paranoid_system(command); 1546 mr_asprintf(&sz_filelist, "%s/tmpfs/filelist.full", tmpdir); 1547 make_hole_for_file(sz_filelist); 1548 1549 if (differential == 0) { 1550 // restore last good datefile if it exists 1551 sprintf(command, "cp -f %s.aborted %s", sz_datefile, sz_datefile); 1552 run_program_and_log_output(command, 3); 1553 // backup last known good datefile just in case :) 1554 if (does_file_exist(sz_datefile)) { 1555 sprintf(command, "mv -f %s %s.aborted", sz_datefile, 1556 sz_datefile); 1557 paranoid_system(command); 1558 } 1559 make_hole_for_file(sz_datefile); 1560 write_one_liner_data_file(sz_datefile, 1561 call_program_and_get_last_line_of_output 1562 ("date +%s")); 1563 } else if (lstat(sz_datefile, &statbuf)) { 1564 log_msg(2, 1565 "Warning - unable to find date of previous backup. Full backup instead."); 1566 differential = 0; 1567 time_of_last_full_backup = 0; 1568 } else { 1569 time_of_last_full_backup = statbuf.st_mtime; 1570 log_msg(2, "Differential backup. Yay."); 1571 } 1572 paranoid_free(sz_datefile); 1573 1574 // use user-specified filelist (if specified) 1575 if (userdef_filelist) { 1576 log_msg(1, 1577 "Using the user-specified filelist - %s - instead of calculating one", 1578 userdef_filelist); 1579 sprintf(command, "cp -f %s %s", userdef_filelist, sz_filelist); 1580 if (run_program_and_log_output(command, 3)) { 1581 fatal_error("Failed to copy user-specified filelist"); 1582 } 1583 } else { 1584 log_msg(2, "include_paths = '%s'", include_paths); 1585 log_msg(1, "Calculating filelist"); 1586 mr_asprintf(&tmp2, "%s", call_program_and_get_last_line_of_output("mount | grep -Ew 'ntfs|ntfs-3g|fat|vfat|dos' | awk '{print $3}'")); 1587 if (strlen(tmp2) < 1) { 1588 mr_asprintf(&tmp1," "); 1589 } else { 1590 log_msg(2, "Found windows FS: %s",tmp2); 1591 mr_asprintf(&tmp1, "find %s -name '/win386.swp' -o -name '/hiberfil.sys' -o -name '/pagefile.sys' 2> /dev/null\n",tmp2); 1592 paranoid_free(tmp2); 1593 mr_asprintf(&tmp2, "%s", call_program_and_get_last_line_of_output(tmp1)); 1594 log_msg(2, "Found windows files: %s",tmp2); 1595 } 1596 paranoid_free(tmp1); 1597 1598 snprintf(exclude_paths, (size_t)8*MAX_STR_LEN," %s %s %s %s %s . .. \ 1599 " MNT_CDROM " " MNT_FLOPPY " /media /tmp \ 1600 /proc /sys " MINDI_CACHE, MONDO_CACHE, excp, tmp2, (tmpdir[0] == '/' && tmpdir[1] == '/') ? (tmpdir + 1) : tmpdir, (scratchdir[0] == '/' && scratchdir[1] == '/') ? (scratchdir + 1) : scratchdir); 1601 paranoid_free(tmp2); 1602 1603 log_msg(2, "Excluding paths = '%s'", exclude_paths); 1604 log_msg(2, 1605 "Generating skeleton filelist so that we can track our progress"); 1606 sprintf(g_skeleton_filelist, "%s/tmpfs/skeleton.txt", tmpdir); 1607 make_hole_for_file(g_skeleton_filelist); 1608 log_msg(4, "g_skeleton_entries = %ld", g_skeleton_entries); 1609 log_msg(2, "Opening out filelist to %s", sz_filelist); 1610 if (!(fout = fopen(sz_filelist, "w"))) { 1611 fatal_error("Cannot openout to sz_filelist"); 1612 } 1613 i = 0; 1614 if (strlen(include_paths) == 0) { 1615 log_msg(1, "Including only '/' in %s", sz_filelist); 1616 open_and_list_dir("/", exclude_paths, fout, 1617 time_of_last_full_backup); 1618 } else { 1619 p = include_paths; 1620 while (*p) { 1621 q = next_entry(p); 1622 log_msg(1, "Including %s in filelist %s", q, sz_filelist); 1623 open_and_list_dir(q, exclude_paths, fout, 1624 time_of_last_full_backup); 1625 p += strlen(q); 1626 paranoid_free(q); 1627 while (*p == ' ') { 1628 p++; 1629 } 1630 } 1631 } 1632 paranoid_fclose(fout); 1633 } 1634 log_msg(2, "Copying new filelist to scratchdir"); 1635 sprintf(command, "mkdir -p %s/archives", scratchdir); 1636 paranoid_system(command); 1637 sprintf(command, "cp -f %s %s/archives/", sz_filelist, scratchdir); 1638 paranoid_system(command); 1639 sprintf(command, "mv -f %s %s", sz_filelist, tmpdir); 1640 paranoid_system(command); 1641 paranoid_free(sz_filelist); 1642 log_msg(2, "Freeing variables"); 1643 paranoid_free(command); 1644 paranoid_free(exclude_paths); 1645 paranoid_free(tmp); 1646 paranoid_free(g_skeleton_filelist); 1647 log_msg(2, "Exiting"); 1648 return (0); 1649 } 1650 1651 /** 1652 * Wrapper around mondo_makefilelist(). 1653 * @param bkpinfo The backup information structure. Fields used: 1654 * - @c bkpinfo->differential 1655 * - @c bkpinfo->exclude_paths 1656 * - @c bkpinfo->include_paths 1657 * - @c bkpinfo->make_filelist 1658 * - @c bkpinfo->scratchdir 1659 * - @c bkpinfo->tmpdir 1660 * @return 0 for success, nonzero for failure. 1661 * @see mondo_makefilelist 1662 */ 1663 int prepare_filelist() 1664 { 1665 1666 /*@ int **************************************************** */ 1667 int res = 0; 1668 1669 assert(bkpinfo != NULL); 1670 log_it("tmpdir=%s; scratchdir=%s", bkpinfo->tmpdir, 1671 bkpinfo->scratchdir); 1672 if (bkpinfo->make_filelist) { 1673 mvaddstr_and_log_it(g_currentY, 0, 1674 "Making catalog of files to be backed up"); 1675 } else { 1676 mvaddstr_and_log_it(g_currentY, 0, 1677 "Using supplied catalog of files to be backed up"); 1678 } 1679 1680 if (bkpinfo->make_filelist) { 1681 res = 1682 mondo_makefilelist(MONDO_LOGFILE, bkpinfo->tmpdir, 1683 bkpinfo->scratchdir, bkpinfo->include_paths, 1684 bkpinfo->exclude_paths, 1685 bkpinfo->differential, NULL); 1686 } else { 1687 res = 1688 mondo_makefilelist(MONDO_LOGFILE, bkpinfo->tmpdir, 1689 bkpinfo->scratchdir, NULL, 1690 bkpinfo->exclude_paths, 1691 bkpinfo->differential, 1692 bkpinfo->include_paths); 1693 } 1694 1695 if (res) { 1696 log_OS_error("Call to mondo_makefilelist failed"); 1697 mvaddstr_and_log_it(g_currentY++, 74, "Failed."); 1698 } else { 1699 mvaddstr_and_log_it(g_currentY++, 74, "Done."); 1700 } 1701 return (res); 1702 } 1705 1703 1706 1704
Note:
See TracChangeset
for help on using the changeset viewer.