Ignore:
Timestamp:
Sep 28, 2009, 4:33:14 PM (15 years ago)
Author:
Bruno Cornec
Message:

Compiler warning fixed

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/2.2.9/mondo/src/common/libmondo-devices.c

    r2424 r2434  
    1010#include "my-stuff.h"
    1111#include "mr_mem.h"
     12#include "mr_str.h"
    1213#include "mondostructures.h"
    1314#include "libmondo-files-EXT.h"
     
    14601461
    14611462
    1462 
    1463 
    1464 
    1465 /**
    1466  * Ask user for details of backup/restore information.
    1467  * Called when @c mondoarchive doesn't get any parameters.
    1468  * @param bkpinfo The backup information structure to fill out with the user's data.
    1469  * @param archiving_to_media TRUE if archiving, FALSE if restoring.
    1470  * @return 0, always.
    1471  * @bug No point of `int' return value.
    1472  * @ingroup archiveGroup
    1473  */
    1474 int interactively_obtain_media_parameters_from_user(bool archiving_to_media)
    1475 // archiving_to_media is TRUE if I'm being called by mondoarchive
    1476 // archiving_to_media is FALSE if I'm being called by mondorestore
    1477 {
    1478     char *tmp = NULL;
    1479     char *tmp1 = NULL;
    1480     char *mds = NULL;
    1481     char *sz_size;
    1482     char *command;
    1483     char *comment;
    1484     char *prompt;
    1485     int i;
    1486     FILE *fin;
    1487 
    1488     malloc_string(sz_size);
    1489     malloc_string(command);
    1490     malloc_string(comment);
    1491     malloc_string(prompt);
    1492     malloc_string(tmp1);
    1493     assert(bkpinfo != NULL);
    1494     sz_size[0] = '\0';
    1495     bkpinfo->nonbootable_backup = FALSE;
    1496 
    1497     // Tape, CD, NETFS, ...?
    1498     srandom(getpid());
    1499     bkpinfo->backup_media_type =
    1500         (g_restoring_live_from_cd) ? cdr :
    1501         which_backup_media_type(bkpinfo->restore_data);
    1502     if (bkpinfo->backup_media_type == none) {
    1503         log_to_screen("User has chosen not to backup the PC");
    1504         finish(1);
    1505     }
    1506     /* Why asking to remove the media with tape ?
    1507     if (bkpinfo->backup_media_type == tape && bkpinfo->restore_data) {
    1508         popup_and_OK("Please remove media from drive(s)");
    1509     }
    1510     */
    1511     log_msg(3, "media type = %s",
    1512             bkptype_to_string(bkpinfo->backup_media_type));
    1513     if (archiving_to_media) {
    1514         sensibly_set_tmpdir_and_scratchdir();
    1515     }
    1516     bkpinfo->cdrw_speed = (bkpinfo->backup_media_type == cdstream) ? 2 : 4;
    1517     bkpinfo->compression_level =
    1518         (bkpinfo->backup_media_type == cdstream) ? 1 : 5;
    1519     bkpinfo->use_lzo =
    1520         (bkpinfo->backup_media_type == cdstream) ? TRUE : FALSE;
    1521     mvaddstr_and_log_it(2, 0, " ");
    1522 
    1523     // Find device's /dev (or SCSI) entry
    1524     switch (bkpinfo->backup_media_type) {
    1525     case cdr:
    1526     case cdrw:
    1527     case dvd:
    1528     case usb:
    1529         /* Never try to eject a USB device */
    1530         if (bkpinfo->backup_media_type == usb) {
    1531             bkpinfo->please_dont_eject = TRUE;
    1532         }
    1533         if (archiving_to_media) {
    1534             if ((bkpinfo->backup_media_type != dvd) && (bkpinfo->backup_media_type != usb)) {
    1535                 if (ask_me_yes_or_no
    1536                     ("Is your computer a laptop, or does the CD writer incorporate BurnProof technology?"))
    1537                 {
    1538                     bkpinfo->manual_cd_tray = TRUE;
    1539                 }
    1540             }
    1541             if ((bkpinfo->compression_level =
    1542                  which_compression_level()) == -1) {
    1543                 log_to_screen("User has chosen not to backup the PC");
    1544                 finish(1);
    1545             }
    1546             mds = media_descriptor_string(bkpinfo->backup_media_type);
    1547             sprintf(comment, "What speed is your %s (re)writer?", mds);
    1548             if (bkpinfo->backup_media_type == dvd) {
    1549                 find_dvd_device(bkpinfo->media_device, FALSE);
    1550                 strcpy(tmp1, "1");
    1551                 sprintf(sz_size, "%d", DEFAULT_DVD_DISK_SIZE);  // 4.7 salesman's GB = 4.482 real GB = 4482 MB
    1552                 log_msg(1, "Setting to DVD defaults");
    1553             } else {
    1554                 strcpy(bkpinfo->media_device, VANILLA_SCSI_CDROM);
    1555                 strcpy(tmp1, "4");
    1556                 strcpy(sz_size, "650");
    1557                 log_msg(1, "Setting to CD defaults");
    1558             }
    1559             if ((bkpinfo->backup_media_type != dvd) && (bkpinfo->backup_media_type != usb)) {
    1560                 if (!popup_and_get_string("Speed", comment, tmp1, 4)) {
    1561                     log_to_screen("User has chosen not to backup the PC");
    1562                     finish(1);
    1563                 }
    1564             }
    1565             bkpinfo->cdrw_speed = atoi(tmp1);   // if DVD then this shouldn't ever be used anyway :)
    1566 
    1567             sprintf(comment,
    1568                     "How much data (in Megabytes) will each %s store?", mds);
    1569             mr_free(mds);
    1570             if (!popup_and_get_string("Size", comment, sz_size, 5)) {
    1571                 log_to_screen("User has chosen not to backup the PC");
    1572                 finish(1);
    1573             }
    1574             for (i = 0; i <= MAX_NOOF_MEDIA; i++) {
    1575                 bkpinfo->media_size[i] = atoi(sz_size);
    1576             }
    1577             if (bkpinfo->media_size[0] <= 0) {
    1578                 log_to_screen("User has chosen not to backup the PC");
    1579                 finish(1);
    1580             }
    1581         }
    1582         /* No break because we continue even for usb */
    1583     case cdstream:
    1584         mds = media_descriptor_string(bkpinfo->backup_media_type);
    1585 
    1586         if ((bkpinfo->disaster_recovery) && (bkpinfo->backup_media_type != usb)) {
    1587             strcpy(bkpinfo->media_device, "/dev/cdrom");
    1588             log_msg(2, "CD-ROM device assumed to be at %s",
    1589                     bkpinfo->media_device);
    1590         } else if ((bkpinfo->restore_data && (bkpinfo->backup_media_type != usb))
    1591                    || bkpinfo->backup_media_type == dvd) {
    1592             if (!bkpinfo->media_device[0]) {
    1593                 strcpy(bkpinfo->media_device, "/dev/cdrom");
    1594             }                   // just for the heck of it :)
    1595             log_msg(1, "bkpinfo->media_device = %s",
    1596                     bkpinfo->media_device);
    1597             if (bkpinfo->backup_media_type == dvd
    1598                 || find_cdrom_device(bkpinfo->media_device, FALSE)) {
    1599                 log_msg(1, "bkpinfo->media_device = %s",
    1600                         bkpinfo->media_device);
    1601                 sprintf(comment,
    1602                         "Please specify your %s drive's /dev entry", mds);
    1603                 if (!popup_and_get_string
    1604                     ("Device?", comment, bkpinfo->media_device,
    1605                      MAX_STR_LEN / 4)) {
    1606                     log_to_screen("User has chosen not to backup the PC");
    1607                     finish(1);
    1608                 }
    1609             }
    1610             log_msg(2, "%s device found at %s", mds, bkpinfo->media_device);
    1611         } else {
    1612             if ((find_cdrw_device(bkpinfo->media_device)) && (bkpinfo->backup_media_type != usb)) {
    1613                 bkpinfo->media_device[0] = '\0';
    1614             }
    1615             if (bkpinfo->media_device[0]) {
    1616                 if (bkpinfo->backup_media_type == usb) {
    1617                     mr_asprintf(&tmp, "I think your %s media corresponds to %s. Is this correct?", mds, bkpinfo->media_device);
    1618                 } else {
    1619                     mr_asprintf(&tmp, "I think I've found your %s burner at SCSI node %s. Is this correct? (Say no if you have an IDE burner and you are running a 2.6 kernel. You will then be prompted for further details.)", mds, bkpinfo->media_device);
    1620                 }
    1621                 if (!ask_me_yes_or_no(tmp)) {
    1622                     bkpinfo->media_device[0] = '\0';
    1623                 }
    1624                 mr_free(tmp);
    1625             }
    1626             if (!bkpinfo->media_device[0]) {
    1627                 if (bkpinfo->backup_media_type == usb) {
    1628                     i = popup_and_get_string("/dev entry?",
    1629                                          "What is the /dev entry of your USB Disk/Key, please?",
    1630                                          bkpinfo->media_device,
    1631                                          MAX_STR_LEN / 4);
    1632                 } else {
    1633                     if (g_kernel_version < 2.6) {
    1634                         i = popup_and_get_string("Device node?",
    1635                                              "What is the SCSI node of your CD (re)writer, please?",
    1636                                              bkpinfo->media_device,
    1637                                              MAX_STR_LEN / 4);
    1638                     } else {
    1639                         i = popup_and_get_string("/dev entry?",
    1640                                              "What is the /dev entry of your CD (re)writer, please?",
    1641                                              bkpinfo->media_device,
    1642                                              MAX_STR_LEN / 4);
    1643                     }
    1644                 }
    1645                 if (!i) {
    1646                     log_to_screen("User has chosen not to backup the PC");
    1647                     finish(1);
    1648                 }
    1649             }
    1650         }
    1651         mr_free(mds);
    1652 
    1653         if (bkpinfo->backup_media_type == cdstream) {
    1654             for (i = 0; i <= MAX_NOOF_MEDIA; i++) {
    1655                 bkpinfo->media_size[i] = 650;
    1656             }
    1657         }
    1658         break;
    1659     case udev:
    1660         if (!ask_me_yes_or_no
    1661             ("This option is for advanced users only. Are you sure?")) {
    1662             log_to_screen("User has chosen not to backup the PC");
    1663             finish(1);
    1664         }
    1665     case tape:
    1666 
    1667         if ((!bkpinfo->restore_mode) && (find_tape_device_and_size(bkpinfo->media_device, sz_size))) {
    1668             log_msg(3, "Ok, using vanilla scsi tape.");
    1669             strcpy(bkpinfo->media_device, VANILLA_SCSI_TAPE);
    1670             if ((fin = fopen(bkpinfo->media_device, "r"))) {
    1671                 paranoid_fclose(fin);
    1672             } else {
    1673                 strcpy(bkpinfo->media_device, "/dev/osst0");
    1674             }
    1675         }
    1676         if (bkpinfo->media_device[0]) {
    1677             if ((fin = fopen(bkpinfo->media_device, "r"))) {
    1678                 paranoid_fclose(fin);
    1679             } else {
    1680                 if (does_file_exist("/tmp/mondo-restore.cfg")) {
    1681                     read_cfg_var("/tmp/mondo-restore.cfg", "media-dev",
    1682                                  bkpinfo->media_device);
    1683                 }
    1684             }
    1685         }
    1686         if (bkpinfo->media_device[0]) {
    1687             mr_asprintf(&tmp, "I think I've found your tape streamer at %s; am I right on the money?", bkpinfo->media_device);
    1688             if (!ask_me_yes_or_no(tmp)) {
    1689                 bkpinfo->media_device[0] = '\0';
    1690             }
    1691             mr_free(tmp);
    1692         }
    1693         if (!bkpinfo->media_device[0]) {
    1694             if (!popup_and_get_string
    1695                 ("Device name?",
    1696                  "What is the /dev entry of your tape streamer?",
    1697                  bkpinfo->media_device, MAX_STR_LEN / 4)) {
    1698                 log_to_screen("User has chosen not to backup the PC");
    1699                 finish(1);
    1700             }
    1701         }
    1702         mr_asprintf(&tmp, "ls -l %s", bkpinfo->media_device);
    1703         if (run_program_and_log_output(tmp, FALSE)) {
    1704             log_to_screen("User has not specified a valid /dev entry");
    1705             finish(1);
    1706         }
    1707         mr_free(tmp);
    1708         log_msg(4, "sz_size = %s", sz_size);
    1709         sz_size[0] = '\0';
    1710 
    1711         bkpinfo->use_obdr = ask_me_yes_or_no
    1712             ("Do you want to activate OBDR support for your tapes ?");
    1713         if (sz_size[0] == '\0') {
    1714             bkpinfo->media_size[0] = 0;
    1715         } else {
    1716             bkpinfo->media_size[0] =
    1717                 friendly_sizestr_to_sizelong(sz_size) / 2 - 50;
    1718         }
    1719         log_msg(4, "media_size[0] = %ld", bkpinfo->media_size[0]);
    1720         if (bkpinfo->media_size[0] <= 0) {
    1721             bkpinfo->media_size[0] = 0;
    1722         }
    1723         for (i = 1; i <= MAX_NOOF_MEDIA; i++) {
    1724             bkpinfo->media_size[i] = bkpinfo->media_size[0];
    1725         }
    1726         if (archiving_to_media) {
    1727             if ((bkpinfo->compression_level =
    1728                  which_compression_level()) == -1) {
    1729                 log_to_screen("User has chosen not to backup the PC");
    1730                 finish(1);
    1731             }
    1732         }
    1733         break;
    1734 
    1735 
    1736 
    1737     case netfs:
    1738         /* Never try to eject a NETFS device */
    1739         bkpinfo->please_dont_eject = TRUE;
    1740 
    1741         /* Initiate bkpinfo netfs_mount path from running environment if not already done */
    1742         if (!bkpinfo->netfs_mount[0]) {
    1743             strcpy(bkpinfo->netfs_mount,
    1744                    call_program_and_get_last_line_of_output
    1745                    ("mount | grep \":\" | cut -d' ' -f1 | head -n1"));
    1746         }
    1747 #ifdef __FreeBSD__
    1748         if (TRUE)
    1749 #else
    1750         if (!bkpinfo->disaster_recovery)
    1751 #endif
    1752         {
    1753             if (!popup_and_get_string
    1754                 ("Network shared dir.",
    1755                  "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.)",
    1756                  bkpinfo->netfs_mount, MAX_STR_LEN / 4)) {
    1757                 log_to_screen("User has chosen not to backup the PC");
    1758                 finish(1);
    1759             }
    1760             if (!bkpinfo->restore_data) {
    1761                 if ((bkpinfo->compression_level =
    1762                      which_compression_level()) == -1) {
    1763                     log_to_screen("User has chosen not to backup the PC");
    1764                     finish(1);
    1765                 }
    1766             }
    1767             // check whether already mounted - we better remove
    1768             // surrounding spaces and trailing '/' for this
    1769             strip_spaces(bkpinfo->netfs_mount);
    1770             if (bkpinfo->netfs_mount[strlen(bkpinfo->netfs_mount) - 1] == '/')
    1771                 bkpinfo->netfs_mount[strlen(bkpinfo->netfs_mount) - 1] = '\0';
    1772             sprintf(command, "mount | grep \"%s \" | cut -d' ' -f3",
    1773                     bkpinfo->netfs_mount);
    1774             strcpy(bkpinfo->isodir,
    1775                    call_program_and_get_last_line_of_output(command));
    1776 
    1777             if (!bkpinfo->restore_data) {
    1778                 sprintf(comment,
    1779                     "How much data (in Megabytes) will each media store?");
    1780                 if (!popup_and_get_string("Size", comment, sz_size, 5)) {
    1781                     log_to_screen("User has chosen not to backup the PC");
    1782                     finish(1);
    1783                 }
    1784             } else {
    1785                 strcpy(sz_size, "0");
    1786             }
    1787             for (i = 0; i <= MAX_NOOF_MEDIA; i++) {
    1788                 bkpinfo->media_size[i] = atoi(sz_size);
    1789             }
    1790             if (bkpinfo->media_size[0] < 0) {
    1791                 log_to_screen("User has chosen not to backup the PC");
    1792                 finish(1);
    1793             }
    1794         }
    1795         if (bkpinfo->disaster_recovery) {
    1796             sprintf(command ,"umount %s/isodir 2> /dev/null", bkpinfo->tmpdir);
    1797             (void)system(command);
    1798             strcpy(tmp1, bkpinfo->netfs_proto);
    1799             if (!popup_and_get_string
    1800                 ("Network protocol", "Which protocol should I use?",
    1801                  tmp1, MAX_STR_LEN)) {
    1802                 log_to_screen("User has chosen not to backup the PC");
    1803                 finish(1);
    1804             }
    1805             mr_free(bkpinfo->netfs_proto);
    1806             mr_asprintf(&(bkpinfo->netfs_proto), "%s", tmp1);
    1807             if (!popup_and_get_string
    1808                 ("Network share", "Which remote share should I mount?",
    1809                  bkpinfo->netfs_mount, MAX_STR_LEN)) {
    1810                 log_to_screen("User has chosen not to backup the PC");
    1811                 finish(1);
    1812             }
    1813         }
    1814         /* Initiate bkpinfo isodir path from running environment if mount already done */
    1815         if (is_this_device_mounted(bkpinfo->netfs_mount)) {
    1816             strcpy(bkpinfo->isodir,
    1817                    call_program_and_get_last_line_of_output
    1818                    ("mount | grep \":\" | cut -d' ' -f3 | head -n1"));
    1819         } else {
    1820             sprintf(bkpinfo->isodir, "%s/netfsdir", bkpinfo->tmpdir);
    1821             sprintf(command, "mkdir -p %s", bkpinfo->isodir);
    1822             run_program_and_log_output(command, 5);
    1823             if (bkpinfo->restore_data) {
    1824                 if (strstr(bkpinfo->netfs_proto, "sshfs")) {
    1825                     mr_asprintf(&tmp, "sshfs -o ro %s %s", bkpinfo->netfs_mount, bkpinfo->isodir);
    1826                 } else {
    1827                     mr_asprintf(&tmp, "mount -t %s -o nolock,ro %s %s", bkpinfo->netfs_proto, bkpinfo->netfs_mount, bkpinfo->isodir);
    1828                 }
    1829             } else {
    1830                 if (strstr(bkpinfo->netfs_proto, "sshfs")) {
    1831                     mr_asprintf(&tmp, "sshfs %s %s", bkpinfo->netfs_mount, bkpinfo->isodir);
    1832                 } else {
    1833                     mr_asprintf(&tmp, "mount -t %s -o nolock %s %s", bkpinfo->netfs_proto, bkpinfo->netfs_mount, bkpinfo->isodir);
    1834                 }
    1835             }
    1836             run_program_and_log_output(tmp, 3);
    1837             mr_free(tmp);
    1838 
    1839             malloc_string(g_selfmounted_isodir);
    1840             strcpy(g_selfmounted_isodir, bkpinfo->isodir);
    1841         }
    1842         if (!is_this_device_mounted(bkpinfo->netfs_mount)) {
    1843             popup_and_OK
    1844                 ("Please mount that partition before you try to backup to or restore from it.");
    1845             finish(1);
    1846         }
    1847         strcpy(tmp1, bkpinfo->netfs_remote_dir);
    1848         if (!popup_and_get_string
    1849             ("Directory", "Which directory within that mountpoint?", tmp1,
    1850              MAX_STR_LEN)) {
    1851             log_to_screen("User has chosen not to backup the PC");
    1852             finish(1);
    1853         }
    1854         strcpy(bkpinfo->netfs_remote_dir, tmp1);
    1855 
    1856         // check whether writable - we better remove surrounding spaces for this
    1857         strip_spaces(bkpinfo->netfs_remote_dir);
    1858 
    1859         if (!popup_and_get_string
    1860             ("Prefix.",
    1861              "Please enter the prefix that will be prepended to your ISO filename.  Example: machine1 to obtain machine1-[1-9]*.iso files",
    1862             bkpinfo->prefix, MAX_STR_LEN / 4)) {
    1863             log_to_screen("User has chosen not to backup the PC");
    1864             finish(1);
    1865         }
    1866         log_msg(3, "prefix set to %s", bkpinfo->prefix);
    1867 
    1868         for (i = 0; i <= MAX_NOOF_MEDIA; i++) {
    1869             bkpinfo->media_size[i] = 650;
    1870         }
    1871         log_msg(3, "Just set netfs_remote_dir to %s",
    1872                 bkpinfo->netfs_remote_dir);
    1873         log_msg(3, "isodir is still %s", bkpinfo->isodir);
    1874         break;
    1875 
    1876     case iso:
    1877         if (!bkpinfo->disaster_recovery) {
    1878             if (!popup_and_get_string
    1879                 ("Storage dir.",
    1880                  "Please enter the full path name to the directory for your ISO images.  Example: /mnt/raid0_0",
    1881                  bkpinfo->isodir, MAX_STR_LEN / 4)) {
    1882                 log_to_screen("User has chosen not to backup the PC");
    1883                 finish(1);
    1884             }
    1885             if (archiving_to_media) {
    1886                 if ((bkpinfo->compression_level =
    1887                      which_compression_level()) == -1) {
    1888                     log_to_screen("User has chosen not to backup the PC");
    1889                     finish(1);
    1890                 }
    1891                 if (!popup_and_get_string
    1892                     ("ISO size.",
    1893                      "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 or DVD's you plan to backup to.",
    1894                      sz_size, 16)) {
    1895                     log_to_screen("User has chosen not to backup the PC");
    1896                     finish(1);
    1897                 }
    1898                 for (i = 0; i <= MAX_NOOF_MEDIA; i++) {
    1899                     bkpinfo->media_size[i] = atoi(sz_size);
    1900                 }
    1901             } else {
    1902                 for (i = 0; i <= MAX_NOOF_MEDIA; i++) {
    1903                     bkpinfo->media_size[i] = 650;
    1904                 }
    1905             }
    1906         }
    1907         if (!popup_and_get_string
    1908             ("Prefix.",
    1909              "Please enter the prefix that will be prepended to your ISO filename.  Example: machine1 to obtain machine1-[1-9]*.iso files",
    1910              bkpinfo->prefix, MAX_STR_LEN / 4)) {
    1911             log_to_screen("User has chosen not to backup the PC");
    1912             finish(1);
    1913         }
    1914         log_msg(3, "prefix set to %s", bkpinfo->prefix);
    1915         break;
    1916     default:
    1917         fatal_error
    1918             ("I, Mojo Jojo, shall defeat those pesky Powerpuff Girls!");
    1919     }
    1920 
    1921     if (archiving_to_media) {
    1922 
    1923 #ifdef __FreeBSD__
    1924         strcpy(bkpinfo->boot_device,
    1925                call_program_and_get_last_line_of_output
    1926                ("mount | grep ' / ' | head -1 | cut -d' ' -f1 | sed 's/\\([0-9]\\).*/\\1/'"));
    1927 #else
    1928         strcpy(bkpinfo->boot_device,
    1929                call_program_and_get_last_line_of_output
    1930                ("mount | grep ' / ' | head -1 | cut -d' ' -f1 | sed 's/[0-9].*//'"));
    1931 #endif
    1932         i = which_boot_loader(bkpinfo->boot_device);
    1933         if (i == 'U')           // unknown
    1934         {
    1935 
    1936 #ifdef __FreeBSD__
    1937             if (!popup_and_get_string
    1938                 ("Boot device",
    1939                  "What is your boot device? (e.g. /dev/ad0)",
    1940                  bkpinfo->boot_device, MAX_STR_LEN / 4)) {
    1941                 log_to_screen("User has chosen not to backup the PC");
    1942                 finish(1);
    1943             }
    1944             i = which_boot_loader(bkpinfo->boot_device);
    1945 #else
    1946             if (!popup_and_get_string
    1947                 ("Boot device",
    1948                  "What is your boot device? (e.g. /dev/hda)",
    1949                  bkpinfo->boot_device, MAX_STR_LEN / 4)) {
    1950                 log_to_screen("User has chosen not to backup the PC");
    1951                 finish(1);
    1952             }
    1953             if (does_string_exist_in_boot_block
    1954                 (bkpinfo->boot_device, "LILO")) {
    1955                 i = 'L';
    1956             } else
    1957                 if (does_string_exist_in_boot_block
    1958                     (bkpinfo->boot_device, "ELILO")) {
    1959                 i = 'E';
    1960             } else
    1961                 if (does_string_exist_in_boot_block
    1962                     (bkpinfo->boot_device, "GRUB")) {
    1963                 i = 'G';
    1964             } else {
    1965                 i = 'U';
    1966             }
    1967 #endif
    1968             if (i == 'U') {
    1969                 if (ask_me_yes_or_no
    1970                     ("Unidentified boot loader. Shall I restore it byte-for-byte at restore time and hope for the best?"))
    1971                 {
    1972                     i = 'R';    // raw
    1973                 } else {
    1974                     log_to_screen
    1975                         ("I cannot find your boot loader. Please run mondoarchive with parameters.");
    1976                     finish(1);
    1977                 }
    1978             }
    1979         }
    1980         bkpinfo->boot_loader = i;
    1981         strcpy(bkpinfo->include_paths, "/");
    1982         if (!popup_and_get_string
    1983             ("Backup paths",
    1984              "Please enter paths which you want me to backup. The default is '/' (i.e. everything).",
    1985              bkpinfo->include_paths, MAX_STR_LEN)) {
    1986             log_to_screen("User has chosen not to backup the PC");
    1987             finish(1);
    1988         }
    1989         mr_asprintf(&tmp, "%s", list_of_NETFS_mounts_only());
    1990         if (strlen(tmp) > 2) {
    1991             if (bkpinfo->exclude_paths[0]) {
    1992                 strcat(bkpinfo->exclude_paths, " ");
    1993             }
    1994             strncpy(bkpinfo->exclude_paths, tmp, MAX_STR_LEN);
    1995         }
    1996         mr_free(tmp);
    1997 // NTFS
    1998         strcpy(tmp1, call_program_and_get_last_line_of_output("parted2fdisk -l | grep -i ntfs | awk '{ print $1};' | tr -s '\\n' ' ' | awk '{ print $0};'"));
    1999         if (strlen(tmp1) > 2) {
    2000             if (!popup_and_get_string
    2001                 ("NTFS partitions",
    2002                  "Please enter/confirm the NTFS partitions you wish to backup as well.",
    2003                  tmp1, MAX_STR_LEN / 4)) {
    2004                 log_to_screen("User has chosen not to backup the PC");
    2005                 finish(1);
    2006             }
    2007             strncpy(bkpinfo->image_devs, tmp1, MAX_STR_LEN / 4);
    2008         }
    2009 
    2010 
    2011         if (!popup_and_get_string
    2012             ("Exclude paths",
    2013              "Please enter paths which you do NOT want to backup. Separate them with spaces. NB: /tmp and /proc are always excluded. :-) Just hit 'Enter' if you want to do a full system backup.",
    2014              bkpinfo->exclude_paths, (4*MAX_STR_LEN)-1)) {
    2015             log_to_screen("User has chosen not to backup the PC");
    2016             finish(1);
    2017         }
    2018         if (!popup_and_get_string
    2019             ("Temporary directory",
    2020              "Please enter your temporary directory.",
    2021              bkpinfo->tmpdir, (4*MAX_STR_LEN)-1)) {
    2022             log_to_screen("User has chosen not to backup the PC");
    2023             finish(1);
    2024         }
    2025         if (!popup_and_get_string
    2026             ("Scratch directory",
    2027              "Please enter your scratch directory.",
    2028              bkpinfo->scratchdir, (4*MAX_STR_LEN)-1)) {
    2029             log_to_screen("User has chosen not to backup the PC");
    2030             finish(1);
    2031         }
    2032 // Interactive mode:
    2033 #ifdef __IA64__
    2034         bkpinfo->make_cd_use_lilo = TRUE;
    2035 #else
    2036         bkpinfo->make_cd_use_lilo = FALSE;
    2037 #endif
    2038         bkpinfo->backup_data = TRUE;
    2039         bkpinfo->verify_data =
    2040             ask_me_yes_or_no
    2041             ("Will you want to verify your backups after Mondo has created them?");
    2042 
    2043 #ifndef __FreeBSD__
    2044         if (!ask_me_yes_or_no
    2045             ("Are you confident that your kernel is a sane, sensible, standard Linux kernel? Say 'no' if you are using a Gentoo <1.4 or Debian <3.0, please."))
    2046 #endif
    2047         {
    2048             strcpy(bkpinfo->kernel_path, "FAILSAFE");
    2049         }
    2050 
    2051         if (!ask_me_yes_or_no
    2052             ("Are you sure you want to proceed? Hit 'no' to abort.")) {
    2053             log_to_screen("User has chosen not to backup the PC");
    2054             finish(1);
    2055         }
     1463/**
     1464 * Creates a singly linked list of all of the non-NETFS mounted file systems.
     1465 * @param DSFptr A pointer  to the structure MOUNTED_FS_STRUCT used to hold
     1466 * the list of mounted file systems.
     1467 * @return None.
     1468 */
     1469static void add_mounted_fs_struct (MOUNTED_FS_STRUCT *DSFptr)
     1470{
     1471    assert (DSFptr);
     1472    if (DSF_Head == NULL) {
     1473        DSF_Head = DSFptr;
    20561474    } else {
    2057         bkpinfo->restore_data = TRUE;   // probably...
    2058     }
    2059 
    2060     if (bkpinfo->backup_media_type == iso
    2061         || bkpinfo->backup_media_type == netfs) {
    2062         g_ISO_restore_mode = TRUE;
    2063     }
    2064 #ifdef __FreeSD__
    2065 // skip
    2066 #else
    2067     if (bkpinfo->backup_media_type == netfs) {
    2068         log_msg(3, "I think the Remote mount is mounted at %s",
    2069                 bkpinfo->isodir);
    2070     }
    2071     log_it("isodir = %s", bkpinfo->isodir);
    2072     log_it("netfs_mount = '%s'", bkpinfo->netfs_mount);
    2073     log_it("netfs_proto = '%s'", bkpinfo->netfs_proto);
    2074     if (bkpinfo->netfs_user) {
    2075         log_it("netfs_user = '%s'", bkpinfo->netfs_user);
    2076     }
    2077 #endif
    2078 
    2079     log_it("media device = %s", bkpinfo->media_device);
    2080     log_it("media size = %ld", bkpinfo->media_size[1]);
    2081     log_it("media type = %s",
    2082            bkptype_to_string(bkpinfo->backup_media_type));
    2083     log_it("prefix = %s", bkpinfo->prefix);
    2084     log_it("compression = %ld", bkpinfo->compression_level);
    2085 
    2086     /* Handle devices passed in bkpinfo and print result */
    2087     mr_make_devlist_from_pathlist(bkpinfo->exclude_paths, 'E');
    2088     mr_make_devlist_from_pathlist(bkpinfo->include_paths, 'I');
    2089 
    2090     log_it("scratchdir = '%s'", bkpinfo->scratchdir);
    2091     log_it("tmpdir = '%s'", bkpinfo->tmpdir);
    2092     log_it("image_devs = '%s'", bkpinfo->image_devs);
    2093     log_it("boot_device = '%s' (loader=%c)", bkpinfo->boot_device,
    2094            bkpinfo->boot_loader);
    2095     if (bkpinfo->media_size[0] < 0) {
    2096         if (archiving_to_media) {
    2097             fatal_error("Media size is less than zero.");
    2098         } else {
    2099             log_msg(2, "Warning - media size is less than zero.");
    2100             bkpinfo->media_size[0] = 0;
    2101         }
    2102     }
    2103     paranoid_free(sz_size);
    2104     paranoid_free(tmp1);
    2105     paranoid_free(command);
    2106     paranoid_free(comment);
    2107     paranoid_free(prompt);
    2108     return (0);
    2109 }
    2110 
    2111 
    2112 
    2113 
    2114 /**
    2115  * @addtogroup utilityGroup
    2116  * @{
    2117  */
    2118 /**
    2119  * Get a space-separated list of NETFS devices and mounts.
    2120  * @return The list created.
    2121  * @note The return value points to static data that will be overwritten with each call.
    2122  */
    2123 char *list_of_NETFS_devices_and_mounts(void)
    2124 {
    2125     char *exclude_these_devices = NULL;
    2126     char *exclude_these_directories = NULL;
    2127     static char result_sz[1024];
    2128 
    2129     mr_asprintf(&exclude_these_directories,"%s",list_of_NETFS_mounts_only());
    2130     mr_asprintf(&exclude_these_devices,"%s", call_program_and_get_last_line_of_output("tr -s '\t' ' ' < /etc/fstab | grep -E '( (coda|ncpfs|sshfs|nfs|nfs4|smbfs|cifs|afs|gfs|ocfs|ocfs2|mvfs|nsspool|nsvol) )' | cut -d' ' -f1 | tr -s '\n' ' ' | awk '{print $0;}'"));
    2131     snprintf(result_sz, 1023, "%s %s", exclude_these_directories, exclude_these_devices);
    2132     mr_free(exclude_these_devices);
    2133     mr_free(exclude_these_directories);
    2134     return (result_sz);
    2135 }
    2136 
    2137 
    2138 
    2139 
    2140 /**
    2141  * Get a space-separated list of NETFS mounts.
    2142  * @return The list created.
    2143  * @note The return value points to static data that will be overwritten with each call.
    2144  * @bug Even though we only want the mounts, the devices are still checked.
    2145  */
    2146 char *list_of_NETFS_mounts_only(void)
    2147 {
    2148     char *exclude_these_directories = NULL;
    2149     static char result_sz[512];
    2150 
    2151     mr_asprintf(&exclude_these_directories,"%s", call_program_and_get_last_line_of_output("mount -t coda,ncpfs,fuse.sshfs,nfs,nfs4,smbfs,cifs,afs,gfs,ocfs,ocfs2,mvfs,nsspool,nssvol | tr -s '\t' ' ' | cut -d' ' -f3 | tr -s '\n' ' ' | awk '{print $0;}'"));
    2152     snprintf(result_sz, 511, "%s", exclude_these_directories);
    2153     mr_free(exclude_these_directories);
    2154     return (result_sz);
    2155 }
    2156 
    2157 /* @} - end of utilityGroup */
    2158 
    2159 
    2160 
    2161 
    2162 
    2163 /**
    2164  * Create a randomly-named FIFO. The format is @p stub "." [random] [random] where
    2165  * [random] is a random number between 1 and 32767.
    2166  * @param store_name_here Where to store the new filename.
    2167  * @param stub A random number will be appended to this to make the FIFO's name.
    2168  * @ingroup deviceGroup
    2169  */
    2170 void make_fifo(char *store_name_here, char *stub)
    2171 {
    2172     char *tmp;
    2173 
    2174     malloc_string(tmp);
    2175     assert_string_is_neither_NULL_nor_zerolength(stub);
    2176 
    2177     sprintf(store_name_here, "%s%d%d", stub, (int) (random() % 32768),
    2178             (int) (random() % 32768));
    2179     make_hole_for_file(store_name_here);
    2180     mkfifo(store_name_here, S_IRWXU | S_IRWXG);
    2181     sprintf(tmp, "chmod 770 %s", store_name_here);
    2182     paranoid_system(tmp);
    2183     paranoid_free(tmp);
    2184 }
    2185 
    2186 
    2187 
    2188 
    2189 
    2190 
    2191 /**
    2192  * Set the tmpdir and scratchdir to reside on the partition with the most free space.
    2193  * Automatically excludes DOS, NTFS, SMB, and NFS filesystems.
    2194  * @param bkpinfo The backup information structure. @c bkpinfo->tmpdir and @c bkpinfo->scratchdir will be set.
    2195  * @ingroup utilityGroup
    2196  */
    2197 void sensibly_set_tmpdir_and_scratchdir()
    2198 {
    2199     char *tmp = NULL;
    2200     char *command = NULL;
    2201     char *sz = NULL;
    2202 
    2203     assert(bkpinfo != NULL);
    2204 
    2205 #ifdef __FreeBSD__
    2206     mr_asprintf(&tmp, "%s", call_program_and_get_last_line_of_output("LANGUAGE=C df -m -P -t nonfs,msdosfs,ntfs,ntfs-3g,smbfs,smb,cifs,afs,gfs,ocfs,ocfs2,mvfs,nsspool,nssvol | grep -vE \"none|Filesystem\" | awk '{printf \"%s %s\\n\", $4, $6;}' | sort -n | tail -n1 | awk '{print $NF;}'"));
    2207 #else
    2208     mr_asprintf(&tmp, "%s", call_program_and_get_last_line_of_output("LANGUAGE=C df -m -P -x nfs -x nfs4 -x fuse.sshfs -x vfat -x ntfs -x ntfs-3g -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 -n | tail -n1 | awk '{print $NF;}'"));
    2209 #endif
    2210 
    2211     if (tmp[0] != '/') {
    2212         mr_asprintf(&sz, "%s", tmp);
    2213         paranoid_free(tmp);
    2214         mr_asprintf(&tmp, "/%s", sz);
    2215         mr_free(sz);
    2216     }
    2217     if (!tmp[0]) {
    2218         fatal_error("I couldn't figure out the tempdir!");
    2219     }
    2220     setup_tmpdir(tmp);
    2221     log_it("bkpinfo->tmpdir is being set to %s", bkpinfo->tmpdir);
    2222 
    2223     sprintf(bkpinfo->scratchdir, "%s/mondo.scratch.%d", tmp,
    2224             (int) (random() % 32768));
    2225     log_it("bkpinfo->scratchdir is being set to %s", bkpinfo->scratchdir);
    2226 
    2227     mr_asprintf(&command, "rm -Rf %s/tmp.mondo.* %s/mondo.scratch.*", tmp, tmp);
    2228     paranoid_free(tmp);
    2229 
    2230     paranoid_system(command);
    2231     mr_free(command);
    2232 }
    2233 
    2234 
    2235 
    2236 
    2237 
    2238 
    2239 /**
    2240  * @addtogroup deviceGroup
    2241  * @{
    2242  */
    2243 /**
    2244  * If we can read @p dev, set @p output to it.
    2245  * If @p dev cannot be read, set @p output to "".
    2246  * @param dev The device to check for.
    2247  * @param output Set to @p dev if @p dev exists, "" otherwise.
    2248  * @return TRUE if @p dev exists, FALSE if it doesn't.
    2249  */
    2250 bool set_dev_to_this_if_rx_OK(char *output, char *dev)
    2251 {
    2252     char *command;
    2253 
    2254     malloc_string(command);
    2255     if (!dev || dev[0] == '\0') {
    2256         output[0] = '\0';
    2257         return (FALSE);
    2258     }
    2259 //  assert_string_is_neither_NULL_nor_zerolength(dev);
    2260     log_msg(10, "Injecting %s", dev);
    2261     inject_device(dev);
    2262     if (!does_file_exist(dev)) {
    2263         log_msg(10, "%s doesn't exist. Returning FALSE.", dev);
    2264         return (FALSE);
    2265     }
    2266     sprintf(command, "dd bs=%ld count=1 if=%s of=/dev/null &> /dev/null",
    2267             512L, dev);
    2268     if (!run_program_and_log_output(command, FALSE)
    2269         && !run_program_and_log_output(command, FALSE)) {
    2270         strcpy(output, dev);
    2271         log_msg(4, "Found it - %s", dev);
    2272         return (TRUE);
    2273     } else {
    2274         output[0] = '\0';
    2275         log_msg(4, "It's not %s", dev);
    2276         return (FALSE);
    2277     }
    2278 }
    2279 
    2280 
    2281 
    2282 
    2283 
    2284 /**
    2285  * Find out what number CD is in the drive.
    2286  * @param bkpinfo The backup information structure. The @c bkpinfo->media_device field is the only one used.
    2287  * @return The current CD number, or -1 if it could not be found.
    2288  * @note If the CD is not mounted, it will be mounted
    2289  * (and remain mounted after this function returns).
    2290  */
    2291 int what_number_cd_is_this()
    2292 {
    2293     int cd_number = -1;
    2294     char *mountdev = NULL;
    2295     char *tmp = NULL;
    2296 
    2297     assert(bkpinfo != NULL);
    2298 //  log_it("Asking what_number_cd_is_this");
    2299     if (g_ISO_restore_mode) {
    2300         mr_asprintf(&tmp, "mount | grep iso9660 | awk '{print $3;}'");
    2301 
    2302         mr_asprintf(&mountdev, "%s%s", call_program_and_get_last_line_of_output(tmp), "/archives/THIS-CD-NUMBER");
    2303         cd_number = atoi(last_line_of_file(mountdev));
    2304         paranoid_free(mountdev);
    2305         paranoid_free(tmp);
    2306 
    2307         return (cd_number);
    2308     }
    2309 
    2310     mr_asprintf(&mountdev, "%s", bkpinfo->media_device);
    2311     if (!mountdev[0]) {
    2312         log_it
    2313             ("(what_number_cd_is_this) Warning - media_device unknown. Finding out...");
    2314         find_cdrom_device(bkpinfo->media_device, FALSE);
    2315     }
    2316     if (!is_this_device_mounted(MNT_CDROM)) {
    2317         if (bkpinfo->backup_media_type == usb) {
    2318             mount_USB_here(mountdev, MNT_CDROM);
    2319         } else {
    2320             mount_CDROM_here(mountdev, MNT_CDROM);
    2321         }
    2322     }
    2323     paranoid_free(mountdev);
    2324 
    2325     cd_number = atoi(last_line_of_file(MNT_CDROM "/archives/THIS-CD-NUMBER"));
    2326     return (cd_number);
    2327 }
    2328 
    2329 
    2330 
    2331 
    2332 
    2333 
    2334 
    2335 /**
    2336  * Find out what device is mounted as root (/).
    2337  * @return Root device.
    2338  * @note The returned string points to static storage and will be overwritten with every call.
    2339  * @bug A bit of a misnomer; it's actually finding out the root device.
    2340  * The mountpoint (where it's mounted) will obviously be '/'.
    2341  */
    2342 char *where_is_root_mounted()
    2343 {
    2344     /*@ buffers **************** */
    2345     static char tmp[MAX_STR_LEN];
    2346 
    2347 
    2348 #ifdef __FreeBSD__
    2349     strcpy(tmp, call_program_and_get_last_line_of_output
    2350            ("mount | grep \" on / \" | cut -d' ' -f1"));
    2351 #else
    2352     strcpy(tmp, call_program_and_get_last_line_of_output
    2353            ("mount | grep \" on / \" | cut -d' ' -f1 | sed s/[0-9]// | sed s/[0-9]//"));
    2354     if (strstr(tmp, "/dev/cciss/")) {
    2355         strcpy(tmp, call_program_and_get_last_line_of_output
    2356                ("mount | grep \" on / \" | cut -d' ' -f1 | cut -dp -f1"));
    2357     }
    2358     if (strstr(tmp, "/dev/md")) {
    2359         strcpy(tmp,
    2360                call_program_and_get_last_line_of_output
    2361                ("mount | grep \" on / \" | cut -d' ' -f1"));
    2362     }
    2363 #endif
    2364 
    2365     return (tmp);
    2366 }
    2367 
    2368 
    2369 /**
    2370  * Find out which boot loader is in use.
    2371  * @param which_device Device to look for the boot loader on.
    2372  * @return 'L' for LILO, 'E'for ELILO, 'G' for GRUB, 'B' or 'D' for FreeBSD boot loaders, or 'U' for Unknown.
    2373  * @note Under Linux, all drives are examined, not just @p which_device.
    2374  */
    2375 #ifdef __FreeBSD__
    2376 char which_boot_loader(char *which_device)
    2377 {
    2378     int count_lilos = 0;
    2379     int count_grubs = 0;
    2380     int count_boot0s = 0;
    2381     int count_dangerouslydedicated = 0;
    2382 
    2383     log_it("looking at drive %s's MBR", which_device);
    2384     if (does_string_exist_in_boot_block(which_device, "GRUB")) {
    2385         count_grubs++;
    2386     }
    2387     if (does_string_exist_in_boot_block(which_device, "LILO")) {
    2388         count_lilos++;
    2389     }
    2390     if (does_string_exist_in_boot_block(which_device, "Drive")) {
    2391         count_boot0s++;
    2392     }
    2393     if (does_string_exist_in_first_N_blocks
    2394         (which_device, "FreeBSD/i386", 17)) {
    2395         count_dangerouslydedicated++;
    2396     }
    2397     log_it("%d grubs and %d lilos and %d elilos and %d boot0s and %d DD\n",
    2398            count_grubs, count_lilos, count_elilos, count_boot0s,
    2399            count_dangerouslydedicated);
    2400 
    2401     if (count_grubs && !count_lilos) {
    2402         return ('G');
    2403     } else if (count_lilos && !count_grubs) {
    2404         return ('L');
    2405     } else if (count_grubs == 1 && count_lilos == 1) {
    2406         log_it("I'll bet you used to use LILO but switched to GRUB...");
    2407         return ('G');
    2408     } else if (count_boot0s == 1) {
    2409         return ('B');
    2410     } else if (count_dangerouslydedicated) {
    2411         return ('D');
    2412     } else {
    2413         log_it("Unknown boot loader");
    2414         return ('U');
    2415     }
    2416 }
    2417 
    2418 #else
    2419 
    2420 char which_boot_loader(char *which_device)
    2421 {
    2422     /*@ buffer ***************************************************** */
    2423     char *list_drives_cmd = NULL;
    2424     char *current_drive;
    2425 
    2426     /*@ pointers *************************************************** */
    2427     FILE *pdrives;
    2428 
    2429     /*@ int ******************************************************** */
    2430     int count_lilos = 0;
    2431     int count_grubs = 0;
    2432 
    2433     /*@ end vars *************************************************** */
    2434 
    2435     malloc_string(current_drive);
    2436 
    2437 #ifdef __IA64__
    2438     /* No choice for it */
    2439     return ('E');
    2440 #endif
    2441     assert(which_device != NULL);
    2442 
    2443     mr_asprintf(&list_drives_cmd, "parted2fdisk -l 2>/dev/null | grep \"/dev/.*:\" | tr -s ':' ' ' | tr -s ' ' '\n' | grep /dev/; echo %s", where_is_root_mounted());
    2444     log_it("list_drives_cmd = %s", list_drives_cmd);
    2445 
    2446     if (!(pdrives = popen(list_drives_cmd, "r"))) {
    2447         log_OS_error("Unable to open list of drives");
    2448         mr_free(list_drives_cmd);
    2449         paranoid_free(current_drive);
    2450         return ('\0');
    2451     }
    2452     mr_free(list_drives_cmd);
    2453 
    2454     for ((void)fgets(current_drive, MAX_STR_LEN, pdrives); !feof(pdrives);
    2455          (void)fgets(current_drive, MAX_STR_LEN, pdrives)) {
    2456         strip_spaces(current_drive);
    2457         log_it("looking at drive %s's MBR", current_drive);
    2458         if (does_string_exist_in_boot_block(current_drive, "GRUB")) {
    2459             count_grubs++;
    2460             strcpy(which_device, current_drive);
     1475        DSF_Tail->next = DSFptr;
     1476    }
     1477    DSFptr->next = NULL;
     1478    DSF_Tail = DSFptr;
     1479}
     1480
     1481/**
     1482 * Find the structure, in the singly linked list of all of the non-NETFS
     1483 * mounted file systems, that contains the specified device.
     1484 * @param device The device to find
     1485 * @return NULL if it didn't find the device, a pointer to the
     1486 * structure if it did.
     1487 */
     1488static MOUNTED_FS_STRUCT *find_device_in_list (char *device)
     1489{
     1490    MOUNTED_FS_STRUCT *DSFptr = NULL;
     1491
     1492    DSFptr = DSF_Head;
     1493    while (DSFptr != NULL) {
     1494        if (!strcmp(DSFptr->device, device)) {
    24611495            break;
    24621496        }
    2463         if (does_string_exist_in_boot_block(current_drive, "LILO")) {
    2464             count_lilos++;
    2465             strcpy(which_device, current_drive);
     1497        DSFptr = DSFptr->next;
     1498    }
     1499    return (DSFptr);
     1500}
     1501
     1502/**
     1503 * Find the structure, in the singly linked list of all of the non-NETFS
     1504 * mounted file systems, that contains the specified mount point.
     1505 * @param mount_point The mount point to find
     1506 * @return NULL is it didn't find the mount point, a pointer to the
     1507 * structure if it did.
     1508 */
     1509static MOUNTED_FS_STRUCT *find_mount_point_in_list (char *mount_point)
     1510{
     1511    MOUNTED_FS_STRUCT *DSFptr = NULL;
     1512
     1513    DSFptr = DSF_Head;
     1514    while (DSFptr != NULL) {
     1515        if (!strcmp(DSFptr->mount_point, mount_point)) {
    24661516            break;
    24671517        }
    2468     }
    2469     if (pclose(pdrives)) {
    2470         log_OS_error("Cannot pclose pdrives");
    2471     }
    2472     log_it("%d grubs and %d lilos\n", count_grubs, count_lilos);
    2473     if (count_grubs && !count_lilos) {
    2474         paranoid_free(current_drive);
    2475         return ('G');
    2476     } else if (count_lilos && !count_grubs) {
    2477         paranoid_free(current_drive);
    2478         return ('L');
    2479     } else if (count_grubs == 1 && count_lilos == 1) {
    2480         log_it("I'll bet you used to use LILO but switched to GRUB...");
    2481         paranoid_free(current_drive);
    2482         return ('G');
    2483     } else {
    2484         // We need to look on each partition then
    2485         mr_asprintf(&list_drives_cmd, "parted2fdisk -l 2>/dev/null | grep -E \"^/dev/\" | tr -s ':' ' ' | tr -s ' ' '\n' | grep /dev/");
    2486         log_it("list_drives_cmd = %s", list_drives_cmd);
    2487 
    2488         if (!(pdrives = popen(list_drives_cmd, "r"))) {
    2489             log_OS_error("Unable to open list of drives");
    2490             mr_free(list_drives_cmd);
    2491             paranoid_free(current_drive);
    2492             return ('\0');
    2493         }
    2494         mr_free(list_drives_cmd);
    2495 
    2496         for ((void)fgets(current_drive, MAX_STR_LEN, pdrives); !feof(pdrives);
    2497             (void)fgets(current_drive, MAX_STR_LEN, pdrives)) {
    2498             strip_spaces(current_drive);
    2499             log_it("looking at partition %s's BR", current_drive);
    2500             if (does_string_exist_in_boot_block(current_drive, "GRUB")) {
    2501                 count_grubs++;
    2502                 strcpy(which_device, current_drive);
    2503                 break;
    2504             }
    2505             if (does_string_exist_in_boot_block(current_drive, "LILO")) {
    2506                 count_lilos++;
    2507                 strcpy(which_device, current_drive);
    2508                 break;
    2509             }
    2510         }
    2511         if (pclose(pdrives)) {
    2512             log_OS_error("Cannot pclose pdrives");
    2513         }
    2514         log_it("%d grubs and %d lilos\n", count_grubs, count_lilos);
    2515         paranoid_free(current_drive);
    2516         if (count_grubs && !count_lilos) {
    2517             return ('G');
    2518         } else if (count_lilos && !count_grubs) {
    2519             return ('L');
    2520         } else if (count_grubs == 1 && count_lilos == 1) {
    2521             log_it("I'll bet you used to use LILO but switched to GRUB...");
    2522             return ('G');
    2523         } else {
    2524             log_it("Unknown boot loader");
    2525             return ('U');
    2526         }
    2527     }
    2528 }
    2529 #endif
    2530 
    2531 
    2532 
    2533 
    2534 /**
    2535  * Write zeroes over the first 16K of @p device.
    2536  * @param device The device to zero.
    2537  * @return 0 for success, 1 for failure.
    2538  */
    2539 int zero_out_a_device(char *device)
    2540 {
    2541     FILE *fout;
    2542     int i;
    2543 
    2544     assert_string_is_neither_NULL_nor_zerolength(device);
    2545 
    2546     log_it("Zeroing drive %s", device);
    2547     if (!(fout = fopen(device, "w"))) {
    2548         log_OS_error("Unable to open/write to device");
    2549         return (1);
    2550     }
    2551     for (i = 0; i < 16384; i++) {
    2552         fputc('\0', fout);
    2553     }
    2554     paranoid_fclose(fout);
    2555     log_it("Device successfully zeroed.");
    2556     return (0);
    2557 }
    2558 
    2559 /**
    2560  * Return the device pointed to by @p incoming.
    2561  * @param incoming The device to resolve symlinks for.
    2562  * @return The path to the real device file.
    2563  * @note The returned string points to static storage that will be overwritten with each call.
    2564  * @bug Won't work with file v4.0; needs to be written in C.
    2565  */
    2566 char *resolve_softlinks_to_get_to_actual_device_file(char *incoming)
    2567 {
    2568     static char output[MAX_STR_LEN];
    2569     char *command;
    2570     char *curr_fname;
    2571     char *scratch = NULL;
    2572     char *tmp = NULL;
    2573     char *p;
    2574 
    2575     struct stat statbuf;
    2576     command = malloc(1000);
    2577     malloc_string(curr_fname);
    2578     if (!does_file_exist(incoming)) {
    2579         log_it
    2580             ("resolve_softlinks_to_get_to_actual_device_file --- device not found");
    2581         strcpy(output, incoming);
    2582     } else {
    2583         strcpy(curr_fname, incoming);
    2584         lstat(curr_fname, &statbuf);
    2585         while (S_ISLNK(statbuf.st_mode)) {
    2586             log_msg(1, "curr_fname = %s", curr_fname);
    2587             sprintf(command, "file %s", curr_fname);
    2588             mr_asprintf(&tmp, "%s", call_program_and_get_last_line_of_output(command));
    2589             for (p = tmp + strlen(tmp); p != tmp && *p != '`' && *p != ' ';
    2590                  p--);
    2591             p++;
    2592             mr_asprintf(&scratch, "%s", p);
    2593             for (p = scratch; *p != '\0' && *p != '\''; p++);
    2594             *p = '\0';
    2595             log_msg(0, "curr_fname %s --> '%s' --> %s", curr_fname, tmp, scratch);
    2596             mr_free(tmp);
    2597 
    2598             if (scratch[0] == '/') {
    2599                 strcpy(curr_fname, scratch);    // copy whole thing because it's an absolute softlink
    2600             } else {            // copy over the basename cos it's a relative softlink
    2601                 p = curr_fname + strlen(curr_fname);
    2602                 while (p != curr_fname && *p != '/') {
    2603                     p--;
    2604                 }
    2605                 if (*p == '/') {
    2606                     p++;
    2607                 }
    2608                 strcpy(p, scratch);
    2609             }
    2610             mr_free(scratch);
    2611             lstat(curr_fname, &statbuf);
    2612         }
    2613         strcpy(output, curr_fname);
    2614         log_it("resolved %s to %s", incoming, output);
    2615     }
    2616     paranoid_free(command);
    2617     paranoid_free(curr_fname);
    2618     return (output);
    2619 }
    2620 
    2621 /* @} - end of deviceGroup */
    2622 
    2623 /**
    2624  * Return the type of partition format (GPT or MBR)
    2625  */
    2626 char *which_partition_format(const char *drive)
    2627 {
    2628     static char output[4];
    2629     char *tmp = NULL;
    2630     char *command;
    2631     char *fdisk;
    2632 #ifdef __IA64__
    2633     struct stat buf;
    2634 #endif
    2635     malloc_string(command);
    2636     malloc_string(fdisk);
    2637     sprintf(fdisk, "/sbin/parted2fdisk");
    2638     sprintf(command, "%s -l %s | grep 'EFI GPT'", fdisk, drive);
    2639     mr_asprintf(&tmp, "%s", call_program_and_get_last_line_of_output(command));
    2640     if (strstr(tmp, "GPT") == NULL) {
    2641         strcpy(output, "MBR");
    2642     } else {
    2643         strcpy(output, "GPT");
    2644     }
    2645     mr_free(tmp);
    2646 
    2647     log_msg(0, "Found %s partition table format type", output);
    2648     paranoid_free(command);
    2649     paranoid_free(fdisk);
    2650     return (output);
     1518        DSFptr = DSFptr->next;
     1519    }
     1520    return (DSFptr);
    26511521}
    26521522
     
    26691539}
    26701540
    2671 /**
    2672  * Creates a singly linked list of all of the non-NETFS mounted file systems.
    2673  * @param DSFptr A pointer  to the structure MOUNTED_FS_STRUCT used to hold
    2674  * the list of mounted file systems.
    2675  * @return None.
    2676  */
    2677 static void add_mounted_fs_struct (MOUNTED_FS_STRUCT *DSFptr)
    2678 {
    2679     assert (DSFptr);
    2680     if (DSF_Head == NULL) {
    2681         DSF_Head = DSFptr;
    2682     } else {
    2683         DSF_Tail->next = DSFptr;
    2684     }
    2685     DSFptr->next = NULL;
    2686     DSF_Tail = DSFptr;
    2687 }
    2688 
    2689 /**
    2690  * Find the structure, in the singly linked list of all of the non-NETFS
    2691  * mounted file systems, that contains the specified device.
    2692  * @param device The device to find
    2693  * @return NULL if it didn't find the device, a pointer to the
    2694  * structure if it did.
    2695  */
    2696 static MOUNTED_FS_STRUCT *find_device_in_list (char *device)
    2697 {
    2698     MOUNTED_FS_STRUCT *DSFptr = NULL;
    2699 
    2700     DSFptr = DSF_Head;
    2701     while (DSFptr != NULL) {
    2702         if (!strcmp(DSFptr->device, device)) {
    2703             break;
    2704         }
    2705         DSFptr = DSFptr->next;
    2706     }
    2707     return (DSFptr);
    2708 }
    2709 
    2710 /**
    2711  * Find the structure, in the singly linked list of all of the non-NETFS
    2712  * mounted file systems, that contains the specified mount point.
    2713  * @param mount_point The mount point to find
    2714  * @return NULL is it didn't find the mount point, a pointer to the
    2715  * structure if it did.
    2716  */
    2717 static MOUNTED_FS_STRUCT *find_mount_point_in_list (char *mount_point)
    2718 {
    2719     MOUNTED_FS_STRUCT *DSFptr = NULL;
    2720 
    2721     DSFptr = DSF_Head;
    2722     while (DSFptr != NULL) {
    2723         if (!strcmp(DSFptr->mount_point, mount_point)) {
    2724             break;
    2725         }
    2726         DSFptr = DSFptr->next;
    2727     }
    2728     return (DSFptr);
    2729 }
    27301541
    27311542/**
     
    31161927
    31171928
     1929
     1930
     1931
    31181932/* Update the bkpinfo structure for exclude & include paths
    31191933 * in order to handle correctly paths corresponding to devices */
     
    31912005
    31922006
     2007/**
     2008 * Ask user for details of backup/restore information.
     2009 * Called when @c mondoarchive doesn't get any parameters.
     2010 * @param bkpinfo The backup information structure to fill out with the user's data.
     2011 * @param archiving_to_media TRUE if archiving, FALSE if restoring.
     2012 * @return 0, always.
     2013 * @bug No point of `int' return value.
     2014 * @ingroup archiveGroup
     2015 */
     2016int interactively_obtain_media_parameters_from_user(bool archiving_to_media)
     2017// archiving_to_media is TRUE if I'm being called by mondoarchive
     2018// archiving_to_media is FALSE if I'm being called by mondorestore
     2019{
     2020    char *tmp = NULL;
     2021    char *tmp1 = NULL;
     2022    char *mds = NULL;
     2023    char *sz_size;
     2024    char *command;
     2025    char *comment;
     2026    char *prompt;
     2027    int i;
     2028    FILE *fin;
     2029
     2030    malloc_string(sz_size);
     2031    malloc_string(command);
     2032    malloc_string(comment);
     2033    malloc_string(prompt);
     2034    malloc_string(tmp1);
     2035    assert(bkpinfo != NULL);
     2036    sz_size[0] = '\0';
     2037    bkpinfo->nonbootable_backup = FALSE;
     2038
     2039    // Tape, CD, NETFS, ...?
     2040    srandom(getpid());
     2041    bkpinfo->backup_media_type =
     2042        (g_restoring_live_from_cd) ? cdr :
     2043        which_backup_media_type(bkpinfo->restore_data);
     2044    if (bkpinfo->backup_media_type == none) {
     2045        log_to_screen("User has chosen not to backup the PC");
     2046        finish(1);
     2047    }
     2048    /* Why asking to remove the media with tape ?
     2049    if (bkpinfo->backup_media_type == tape && bkpinfo->restore_data) {
     2050        popup_and_OK("Please remove media from drive(s)");
     2051    }
     2052    */
     2053    log_msg(3, "media type = %s",
     2054            bkptype_to_string(bkpinfo->backup_media_type));
     2055    if (archiving_to_media) {
     2056        sensibly_set_tmpdir_and_scratchdir();
     2057    }
     2058    bkpinfo->cdrw_speed = (bkpinfo->backup_media_type == cdstream) ? 2 : 4;
     2059    bkpinfo->compression_level =
     2060        (bkpinfo->backup_media_type == cdstream) ? 1 : 5;
     2061    bkpinfo->use_lzo =
     2062        (bkpinfo->backup_media_type == cdstream) ? TRUE : FALSE;
     2063    mvaddstr_and_log_it(2, 0, " ");
     2064
     2065    // Find device's /dev (or SCSI) entry
     2066    switch (bkpinfo->backup_media_type) {
     2067    case cdr:
     2068    case cdrw:
     2069    case dvd:
     2070    case usb:
     2071        /* Never try to eject a USB device */
     2072        if (bkpinfo->backup_media_type == usb) {
     2073            bkpinfo->please_dont_eject = TRUE;
     2074        }
     2075        if (archiving_to_media) {
     2076            if ((bkpinfo->backup_media_type != dvd) && (bkpinfo->backup_media_type != usb)) {
     2077                if (ask_me_yes_or_no
     2078                    ("Is your computer a laptop, or does the CD writer incorporate BurnProof technology?"))
     2079                {
     2080                    bkpinfo->manual_cd_tray = TRUE;
     2081                }
     2082            }
     2083            if ((bkpinfo->compression_level =
     2084                 which_compression_level()) == -1) {
     2085                log_to_screen("User has chosen not to backup the PC");
     2086                finish(1);
     2087            }
     2088            mds = media_descriptor_string(bkpinfo->backup_media_type);
     2089            sprintf(comment, "What speed is your %s (re)writer?", mds);
     2090            if (bkpinfo->backup_media_type == dvd) {
     2091                find_dvd_device(bkpinfo->media_device, FALSE);
     2092                strcpy(tmp1, "1");
     2093                sprintf(sz_size, "%d", DEFAULT_DVD_DISK_SIZE);  // 4.7 salesman's GB = 4.482 real GB = 4482 MB
     2094                log_msg(1, "Setting to DVD defaults");
     2095            } else {
     2096                strcpy(bkpinfo->media_device, VANILLA_SCSI_CDROM);
     2097                strcpy(tmp1, "4");
     2098                strcpy(sz_size, "650");
     2099                log_msg(1, "Setting to CD defaults");
     2100            }
     2101            if ((bkpinfo->backup_media_type != dvd) && (bkpinfo->backup_media_type != usb)) {
     2102                if (!popup_and_get_string("Speed", comment, tmp1, 4)) {
     2103                    log_to_screen("User has chosen not to backup the PC");
     2104                    finish(1);
     2105                }
     2106            }
     2107            bkpinfo->cdrw_speed = atoi(tmp1);   // if DVD then this shouldn't ever be used anyway :)
     2108
     2109            sprintf(comment,
     2110                    "How much data (in Megabytes) will each %s store?", mds);
     2111            mr_free(mds);
     2112            if (!popup_and_get_string("Size", comment, sz_size, 5)) {
     2113                log_to_screen("User has chosen not to backup the PC");
     2114                finish(1);
     2115            }
     2116            for (i = 0; i <= MAX_NOOF_MEDIA; i++) {
     2117                bkpinfo->media_size[i] = atoi(sz_size);
     2118            }
     2119            if (bkpinfo->media_size[0] <= 0) {
     2120                log_to_screen("User has chosen not to backup the PC");
     2121                finish(1);
     2122            }
     2123        }
     2124        /* No break because we continue even for usb */
     2125    case cdstream:
     2126        mds = media_descriptor_string(bkpinfo->backup_media_type);
     2127
     2128        if ((bkpinfo->disaster_recovery) && (bkpinfo->backup_media_type != usb)) {
     2129            strcpy(bkpinfo->media_device, "/dev/cdrom");
     2130            log_msg(2, "CD-ROM device assumed to be at %s",
     2131                    bkpinfo->media_device);
     2132        } else if ((bkpinfo->restore_data && (bkpinfo->backup_media_type != usb))
     2133                   || bkpinfo->backup_media_type == dvd) {
     2134            if (!bkpinfo->media_device[0]) {
     2135                strcpy(bkpinfo->media_device, "/dev/cdrom");
     2136            }                   // just for the heck of it :)
     2137            log_msg(1, "bkpinfo->media_device = %s",
     2138                    bkpinfo->media_device);
     2139            if (bkpinfo->backup_media_type == dvd
     2140                || find_cdrom_device(bkpinfo->media_device, FALSE)) {
     2141                log_msg(1, "bkpinfo->media_device = %s",
     2142                        bkpinfo->media_device);
     2143                sprintf(comment,
     2144                        "Please specify your %s drive's /dev entry", mds);
     2145                if (!popup_and_get_string
     2146                    ("Device?", comment, bkpinfo->media_device,
     2147                     MAX_STR_LEN / 4)) {
     2148                    log_to_screen("User has chosen not to backup the PC");
     2149                    finish(1);
     2150                }
     2151            }
     2152            log_msg(2, "%s device found at %s", mds, bkpinfo->media_device);
     2153        } else {
     2154            if ((find_cdrw_device(bkpinfo->media_device)) && (bkpinfo->backup_media_type != usb)) {
     2155                bkpinfo->media_device[0] = '\0';
     2156            }
     2157            if (bkpinfo->media_device[0]) {
     2158                if (bkpinfo->backup_media_type == usb) {
     2159                    mr_asprintf(&tmp, "I think your %s media corresponds to %s. Is this correct?", mds, bkpinfo->media_device);
     2160                } else {
     2161                    mr_asprintf(&tmp, "I think I've found your %s burner at SCSI node %s. Is this correct? (Say no if you have an IDE burner and you are running a 2.6 kernel. You will then be prompted for further details.)", mds, bkpinfo->media_device);
     2162                }
     2163                if (!ask_me_yes_or_no(tmp)) {
     2164                    bkpinfo->media_device[0] = '\0';
     2165                }
     2166                mr_free(tmp);
     2167            }
     2168            if (!bkpinfo->media_device[0]) {
     2169                if (bkpinfo->backup_media_type == usb) {
     2170                    i = popup_and_get_string("/dev entry?",
     2171                                         "What is the /dev entry of your USB Disk/Key, please?",
     2172                                         bkpinfo->media_device,
     2173                                         MAX_STR_LEN / 4);
     2174                } else {
     2175                    if (g_kernel_version < 2.6) {
     2176                        i = popup_and_get_string("Device node?",
     2177                                             "What is the SCSI node of your CD (re)writer, please?",
     2178                                             bkpinfo->media_device,
     2179                                             MAX_STR_LEN / 4);
     2180                    } else {
     2181                        i = popup_and_get_string("/dev entry?",
     2182                                             "What is the /dev entry of your CD (re)writer, please?",
     2183                                             bkpinfo->media_device,
     2184                                             MAX_STR_LEN / 4);
     2185                    }
     2186                }
     2187                if (!i) {
     2188                    log_to_screen("User has chosen not to backup the PC");
     2189                    finish(1);
     2190                }
     2191            }
     2192        }
     2193        mr_free(mds);
     2194
     2195        if (bkpinfo->backup_media_type == cdstream) {
     2196            for (i = 0; i <= MAX_NOOF_MEDIA; i++) {
     2197                bkpinfo->media_size[i] = 650;
     2198            }
     2199        }
     2200        break;
     2201    case udev:
     2202        if (!ask_me_yes_or_no
     2203            ("This option is for advanced users only. Are you sure?")) {
     2204            log_to_screen("User has chosen not to backup the PC");
     2205            finish(1);
     2206        }
     2207    case tape:
     2208
     2209        if ((!bkpinfo->restore_mode) && (find_tape_device_and_size(bkpinfo->media_device, sz_size))) {
     2210            log_msg(3, "Ok, using vanilla scsi tape.");
     2211            strcpy(bkpinfo->media_device, VANILLA_SCSI_TAPE);
     2212            if ((fin = fopen(bkpinfo->media_device, "r"))) {
     2213                paranoid_fclose(fin);
     2214            } else {
     2215                strcpy(bkpinfo->media_device, "/dev/osst0");
     2216            }
     2217        }
     2218        if (bkpinfo->media_device[0]) {
     2219            if ((fin = fopen(bkpinfo->media_device, "r"))) {
     2220                paranoid_fclose(fin);
     2221            } else {
     2222                if (does_file_exist("/tmp/mondo-restore.cfg")) {
     2223                    read_cfg_var("/tmp/mondo-restore.cfg", "media-dev",
     2224                                 bkpinfo->media_device);
     2225                }
     2226            }
     2227        }
     2228        if (bkpinfo->media_device[0]) {
     2229            mr_asprintf(&tmp, "I think I've found your tape streamer at %s; am I right on the money?", bkpinfo->media_device);
     2230            if (!ask_me_yes_or_no(tmp)) {
     2231                bkpinfo->media_device[0] = '\0';
     2232            }
     2233            mr_free(tmp);
     2234        }
     2235        if (!bkpinfo->media_device[0]) {
     2236            if (!popup_and_get_string
     2237                ("Device name?",
     2238                 "What is the /dev entry of your tape streamer?",
     2239                 bkpinfo->media_device, MAX_STR_LEN / 4)) {
     2240                log_to_screen("User has chosen not to backup the PC");
     2241                finish(1);
     2242            }
     2243        }
     2244        mr_asprintf(&tmp, "ls -l %s", bkpinfo->media_device);
     2245        if (run_program_and_log_output(tmp, FALSE)) {
     2246            log_to_screen("User has not specified a valid /dev entry");
     2247            finish(1);
     2248        }
     2249        mr_free(tmp);
     2250        log_msg(4, "sz_size = %s", sz_size);
     2251        sz_size[0] = '\0';
     2252
     2253        bkpinfo->use_obdr = ask_me_yes_or_no
     2254            ("Do you want to activate OBDR support for your tapes ?");
     2255        if (sz_size[0] == '\0') {
     2256            bkpinfo->media_size[0] = 0;
     2257        } else {
     2258            bkpinfo->media_size[0] =
     2259                friendly_sizestr_to_sizelong(sz_size) / 2 - 50;
     2260        }
     2261        log_msg(4, "media_size[0] = %ld", bkpinfo->media_size[0]);
     2262        if (bkpinfo->media_size[0] <= 0) {
     2263            bkpinfo->media_size[0] = 0;
     2264        }
     2265        for (i = 1; i <= MAX_NOOF_MEDIA; i++) {
     2266            bkpinfo->media_size[i] = bkpinfo->media_size[0];
     2267        }
     2268        if (archiving_to_media) {
     2269            if ((bkpinfo->compression_level =
     2270                 which_compression_level()) == -1) {
     2271                log_to_screen("User has chosen not to backup the PC");
     2272                finish(1);
     2273            }
     2274        }
     2275        break;
     2276
     2277
     2278
     2279    case netfs:
     2280        /* Never try to eject a NETFS device */
     2281        bkpinfo->please_dont_eject = TRUE;
     2282
     2283        /* Initiate bkpinfo netfs_mount path from running environment if not already done */
     2284        if (!bkpinfo->netfs_mount[0]) {
     2285            strcpy(bkpinfo->netfs_mount,
     2286                   call_program_and_get_last_line_of_output
     2287                   ("mount | grep \":\" | cut -d' ' -f1 | head -n1"));
     2288        }
     2289#ifdef __FreeBSD__
     2290        if (TRUE)
     2291#else
     2292        if (!bkpinfo->disaster_recovery)
     2293#endif
     2294        {
     2295            if (!popup_and_get_string
     2296                ("Network shared dir.",
     2297                 "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.)",
     2298                 bkpinfo->netfs_mount, MAX_STR_LEN / 4)) {
     2299                log_to_screen("User has chosen not to backup the PC");
     2300                finish(1);
     2301            }
     2302            if (!bkpinfo->restore_data) {
     2303                if ((bkpinfo->compression_level =
     2304                     which_compression_level()) == -1) {
     2305                    log_to_screen("User has chosen not to backup the PC");
     2306                    finish(1);
     2307                }
     2308            }
     2309            // check whether already mounted - we better remove
     2310            // surrounding spaces and trailing '/' for this
     2311            strip_spaces(bkpinfo->netfs_mount);
     2312            if (bkpinfo->netfs_mount[strlen(bkpinfo->netfs_mount) - 1] == '/')
     2313                bkpinfo->netfs_mount[strlen(bkpinfo->netfs_mount) - 1] = '\0';
     2314            sprintf(command, "mount | grep \"%s \" | cut -d' ' -f3",
     2315                    bkpinfo->netfs_mount);
     2316            strcpy(bkpinfo->isodir,
     2317                   call_program_and_get_last_line_of_output(command));
     2318
     2319            if (!bkpinfo->restore_data) {
     2320                sprintf(comment,
     2321                    "How much data (in Megabytes) will each media store?");
     2322                if (!popup_and_get_string("Size", comment, sz_size, 5)) {
     2323                    log_to_screen("User has chosen not to backup the PC");
     2324                    finish(1);
     2325                }
     2326            } else {
     2327                strcpy(sz_size, "0");
     2328            }
     2329            for (i = 0; i <= MAX_NOOF_MEDIA; i++) {
     2330                bkpinfo->media_size[i] = atoi(sz_size);
     2331            }
     2332            if (bkpinfo->media_size[0] < 0) {
     2333                log_to_screen("User has chosen not to backup the PC");
     2334                finish(1);
     2335            }
     2336        }
     2337        if (bkpinfo->disaster_recovery) {
     2338            sprintf(command ,"umount %s/isodir 2> /dev/null", bkpinfo->tmpdir);
     2339            (void)system(command);
     2340            strcpy(tmp1, bkpinfo->netfs_proto);
     2341            if (!popup_and_get_string
     2342                ("Network protocol", "Which protocol should I use?",
     2343                 tmp1, MAX_STR_LEN)) {
     2344                log_to_screen("User has chosen not to backup the PC");
     2345                finish(1);
     2346            }
     2347            mr_free(bkpinfo->netfs_proto);
     2348            mr_asprintf(&(bkpinfo->netfs_proto), "%s", tmp1);
     2349            if (!popup_and_get_string
     2350                ("Network share", "Which remote share should I mount?",
     2351                 bkpinfo->netfs_mount, MAX_STR_LEN)) {
     2352                log_to_screen("User has chosen not to backup the PC");
     2353                finish(1);
     2354            }
     2355        }
     2356        /* Initiate bkpinfo isodir path from running environment if mount already done */
     2357        if (is_this_device_mounted(bkpinfo->netfs_mount)) {
     2358            strcpy(bkpinfo->isodir,
     2359                   call_program_and_get_last_line_of_output
     2360                   ("mount | grep \":\" | cut -d' ' -f3 | head -n1"));
     2361        } else {
     2362            sprintf(bkpinfo->isodir, "%s/netfsdir", bkpinfo->tmpdir);
     2363            sprintf(command, "mkdir -p %s", bkpinfo->isodir);
     2364            run_program_and_log_output(command, 5);
     2365            if (bkpinfo->restore_data) {
     2366                if (strstr(bkpinfo->netfs_proto, "sshfs")) {
     2367                    mr_asprintf(&tmp, "sshfs -o ro %s %s", bkpinfo->netfs_mount, bkpinfo->isodir);
     2368                } else {
     2369                    mr_asprintf(&tmp, "mount -t %s -o nolock,ro %s %s", bkpinfo->netfs_proto, bkpinfo->netfs_mount, bkpinfo->isodir);
     2370                }
     2371            } else {
     2372                if (strstr(bkpinfo->netfs_proto, "sshfs")) {
     2373                    mr_asprintf(&tmp, "sshfs %s %s", bkpinfo->netfs_mount, bkpinfo->isodir);
     2374                } else {
     2375                    mr_asprintf(&tmp, "mount -t %s -o nolock %s %s", bkpinfo->netfs_proto, bkpinfo->netfs_mount, bkpinfo->isodir);
     2376                }
     2377            }
     2378            run_program_and_log_output(tmp, 3);
     2379            mr_free(tmp);
     2380
     2381            malloc_string(g_selfmounted_isodir);
     2382            strcpy(g_selfmounted_isodir, bkpinfo->isodir);
     2383        }
     2384        if (!is_this_device_mounted(bkpinfo->netfs_mount)) {
     2385            popup_and_OK
     2386                ("Please mount that partition before you try to backup to or restore from it.");
     2387            finish(1);
     2388        }
     2389        strcpy(tmp1, bkpinfo->netfs_remote_dir);
     2390        if (!popup_and_get_string
     2391            ("Directory", "Which directory within that mountpoint?", tmp1,
     2392             MAX_STR_LEN)) {
     2393            log_to_screen("User has chosen not to backup the PC");
     2394            finish(1);
     2395        }
     2396        strcpy(bkpinfo->netfs_remote_dir, tmp1);
     2397
     2398        // check whether writable - we better remove surrounding spaces for this
     2399        strip_spaces(bkpinfo->netfs_remote_dir);
     2400
     2401        if (!popup_and_get_string
     2402            ("Prefix.",
     2403             "Please enter the prefix that will be prepended to your ISO filename.  Example: machine1 to obtain machine1-[1-9]*.iso files",
     2404            bkpinfo->prefix, MAX_STR_LEN / 4)) {
     2405            log_to_screen("User has chosen not to backup the PC");
     2406            finish(1);
     2407        }
     2408        log_msg(3, "prefix set to %s", bkpinfo->prefix);
     2409
     2410        for (i = 0; i <= MAX_NOOF_MEDIA; i++) {
     2411            bkpinfo->media_size[i] = 650;
     2412        }
     2413        log_msg(3, "Just set netfs_remote_dir to %s",
     2414                bkpinfo->netfs_remote_dir);
     2415        log_msg(3, "isodir is still %s", bkpinfo->isodir);
     2416        break;
     2417
     2418    case iso:
     2419        if (!bkpinfo->disaster_recovery) {
     2420            if (!popup_and_get_string
     2421                ("Storage dir.",
     2422                 "Please enter the full path name to the directory for your ISO images.  Example: /mnt/raid0_0",
     2423                 bkpinfo->isodir, MAX_STR_LEN / 4)) {
     2424                log_to_screen("User has chosen not to backup the PC");
     2425                finish(1);
     2426            }
     2427            if (archiving_to_media) {
     2428                if ((bkpinfo->compression_level =
     2429                     which_compression_level()) == -1) {
     2430                    log_to_screen("User has chosen not to backup the PC");
     2431                    finish(1);
     2432                }
     2433                if (!popup_and_get_string
     2434                    ("ISO size.",
     2435                     "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 or DVD's you plan to backup to.",
     2436                     sz_size, 16)) {
     2437                    log_to_screen("User has chosen not to backup the PC");
     2438                    finish(1);
     2439                }
     2440                for (i = 0; i <= MAX_NOOF_MEDIA; i++) {
     2441                    bkpinfo->media_size[i] = atoi(sz_size);
     2442                }
     2443            } else {
     2444                for (i = 0; i <= MAX_NOOF_MEDIA; i++) {
     2445                    bkpinfo->media_size[i] = 650;
     2446                }
     2447            }
     2448        }
     2449        if (!popup_and_get_string
     2450            ("Prefix.",
     2451             "Please enter the prefix that will be prepended to your ISO filename.  Example: machine1 to obtain machine1-[1-9]*.iso files",
     2452             bkpinfo->prefix, MAX_STR_LEN / 4)) {
     2453            log_to_screen("User has chosen not to backup the PC");
     2454            finish(1);
     2455        }
     2456        log_msg(3, "prefix set to %s", bkpinfo->prefix);
     2457        break;
     2458    default:
     2459        fatal_error
     2460            ("I, Mojo Jojo, shall defeat those pesky Powerpuff Girls!");
     2461    }
     2462
     2463    if (archiving_to_media) {
     2464
     2465#ifdef __FreeBSD__
     2466        strcpy(bkpinfo->boot_device,
     2467               call_program_and_get_last_line_of_output
     2468               ("mount | grep ' / ' | head -1 | cut -d' ' -f1 | sed 's/\\([0-9]\\).*/\\1/'"));
     2469#else
     2470        strcpy(bkpinfo->boot_device,
     2471               call_program_and_get_last_line_of_output
     2472               ("mount | grep ' / ' | head -1 | cut -d' ' -f1 | sed 's/[0-9].*//'"));
     2473#endif
     2474        i = which_boot_loader(bkpinfo->boot_device);
     2475        if (i == 'U')           // unknown
     2476        {
     2477
     2478#ifdef __FreeBSD__
     2479            if (!popup_and_get_string
     2480                ("Boot device",
     2481                 "What is your boot device? (e.g. /dev/ad0)",
     2482                 bkpinfo->boot_device, MAX_STR_LEN / 4)) {
     2483                log_to_screen("User has chosen not to backup the PC");
     2484                finish(1);
     2485            }
     2486            i = which_boot_loader(bkpinfo->boot_device);
     2487#else
     2488            if (!popup_and_get_string
     2489                ("Boot device",
     2490                 "What is your boot device? (e.g. /dev/hda)",
     2491                 bkpinfo->boot_device, MAX_STR_LEN / 4)) {
     2492                log_to_screen("User has chosen not to backup the PC");
     2493                finish(1);
     2494            }
     2495            if (does_string_exist_in_boot_block
     2496                (bkpinfo->boot_device, "LILO")) {
     2497                i = 'L';
     2498            } else
     2499                if (does_string_exist_in_boot_block
     2500                    (bkpinfo->boot_device, "ELILO")) {
     2501                i = 'E';
     2502            } else
     2503                if (does_string_exist_in_boot_block
     2504                    (bkpinfo->boot_device, "GRUB")) {
     2505                i = 'G';
     2506            } else {
     2507                i = 'U';
     2508            }
     2509#endif
     2510            if (i == 'U') {
     2511                if (ask_me_yes_or_no
     2512                    ("Unidentified boot loader. Shall I restore it byte-for-byte at restore time and hope for the best?"))
     2513                {
     2514                    i = 'R';    // raw
     2515                } else {
     2516                    log_to_screen
     2517                        ("I cannot find your boot loader. Please run mondoarchive with parameters.");
     2518                    finish(1);
     2519                }
     2520            }
     2521        }
     2522        bkpinfo->boot_loader = i;
     2523        strcpy(bkpinfo->include_paths, "/");
     2524        if (!popup_and_get_string
     2525            ("Backup paths",
     2526             "Please enter paths which you want me to backup. The default is '/' (i.e. everything).",
     2527             bkpinfo->include_paths, MAX_STR_LEN)) {
     2528            log_to_screen("User has chosen not to backup the PC");
     2529            finish(1);
     2530        }
     2531        mr_asprintf(&tmp, "%s", list_of_NETFS_mounts_only());
     2532        if (strlen(tmp) > 2) {
     2533            if (bkpinfo->exclude_paths[0]) {
     2534                strcat(bkpinfo->exclude_paths, " ");
     2535            }
     2536            strncpy(bkpinfo->exclude_paths, tmp, MAX_STR_LEN);
     2537        }
     2538        mr_free(tmp);
     2539// NTFS
     2540        strcpy(tmp1, call_program_and_get_last_line_of_output("parted2fdisk -l | grep -i ntfs | awk '{ print $1};' | tr -s '\\n' ' ' | awk '{ print $0};'"));
     2541        if (strlen(tmp1) > 2) {
     2542            if (!popup_and_get_string
     2543                ("NTFS partitions",
     2544                 "Please enter/confirm the NTFS partitions you wish to backup as well.",
     2545                 tmp1, MAX_STR_LEN / 4)) {
     2546                log_to_screen("User has chosen not to backup the PC");
     2547                finish(1);
     2548            }
     2549            strncpy(bkpinfo->image_devs, tmp1, MAX_STR_LEN / 4);
     2550        }
     2551
     2552
     2553        if (!popup_and_get_string
     2554            ("Exclude paths",
     2555             "Please enter paths which you do NOT want to backup. Separate them with spaces. NB: /tmp and /proc are always excluded. :-) Just hit 'Enter' if you want to do a full system backup.",
     2556             bkpinfo->exclude_paths, (4*MAX_STR_LEN)-1)) {
     2557            log_to_screen("User has chosen not to backup the PC");
     2558            finish(1);
     2559        }
     2560        if (!popup_and_get_string
     2561            ("Temporary directory",
     2562             "Please enter your temporary directory.",
     2563             bkpinfo->tmpdir, (4*MAX_STR_LEN)-1)) {
     2564            log_to_screen("User has chosen not to backup the PC");
     2565            finish(1);
     2566        }
     2567        if (!popup_and_get_string
     2568            ("Scratch directory",
     2569             "Please enter your scratch directory.",
     2570             bkpinfo->scratchdir, (4*MAX_STR_LEN)-1)) {
     2571            log_to_screen("User has chosen not to backup the PC");
     2572            finish(1);
     2573        }
     2574// Interactive mode:
     2575#ifdef __IA64__
     2576        bkpinfo->make_cd_use_lilo = TRUE;
     2577#else
     2578        bkpinfo->make_cd_use_lilo = FALSE;
     2579#endif
     2580        bkpinfo->backup_data = TRUE;
     2581        bkpinfo->verify_data =
     2582            ask_me_yes_or_no
     2583            ("Will you want to verify your backups after Mondo has created them?");
     2584
     2585#ifndef __FreeBSD__
     2586        if (!ask_me_yes_or_no
     2587            ("Are you confident that your kernel is a sane, sensible, standard Linux kernel? Say 'no' if you are using a Gentoo <1.4 or Debian <3.0, please."))
     2588#endif
     2589        {
     2590            strcpy(bkpinfo->kernel_path, "FAILSAFE");
     2591        }
     2592
     2593        if (!ask_me_yes_or_no
     2594            ("Are you sure you want to proceed? Hit 'no' to abort.")) {
     2595            log_to_screen("User has chosen not to backup the PC");
     2596            finish(1);
     2597        }
     2598    } else {
     2599        bkpinfo->restore_data = TRUE;   // probably...
     2600    }
     2601
     2602    if (bkpinfo->backup_media_type == iso
     2603        || bkpinfo->backup_media_type == netfs) {
     2604        g_ISO_restore_mode = TRUE;
     2605    }
     2606#ifdef __FreeSD__
     2607// skip
     2608#else
     2609    if (bkpinfo->backup_media_type == netfs) {
     2610        log_msg(3, "I think the Remote mount is mounted at %s",
     2611                bkpinfo->isodir);
     2612    }
     2613    log_it("isodir = %s", bkpinfo->isodir);
     2614    log_it("netfs_mount = '%s'", bkpinfo->netfs_mount);
     2615    log_it("netfs_proto = '%s'", bkpinfo->netfs_proto);
     2616    if (bkpinfo->netfs_user) {
     2617        log_it("netfs_user = '%s'", bkpinfo->netfs_user);
     2618    }
     2619#endif
     2620
     2621    log_it("media device = %s", bkpinfo->media_device);
     2622    log_it("media size = %ld", bkpinfo->media_size[1]);
     2623    log_it("media type = %s",
     2624           bkptype_to_string(bkpinfo->backup_media_type));
     2625    log_it("prefix = %s", bkpinfo->prefix);
     2626    log_it("compression = %ld", bkpinfo->compression_level);
     2627
     2628    /* Handle devices passed in bkpinfo and print result */
     2629    mr_make_devlist_from_pathlist(bkpinfo->exclude_paths, 'E');
     2630    mr_make_devlist_from_pathlist(bkpinfo->include_paths, 'I');
     2631
     2632    log_it("scratchdir = '%s'", bkpinfo->scratchdir);
     2633    log_it("tmpdir = '%s'", bkpinfo->tmpdir);
     2634    log_it("image_devs = '%s'", bkpinfo->image_devs);
     2635    log_it("boot_device = '%s' (loader=%c)", bkpinfo->boot_device,
     2636           bkpinfo->boot_loader);
     2637    if (bkpinfo->media_size[0] < 0) {
     2638        if (archiving_to_media) {
     2639            fatal_error("Media size is less than zero.");
     2640        } else {
     2641            log_msg(2, "Warning - media size is less than zero.");
     2642            bkpinfo->media_size[0] = 0;
     2643        }
     2644    }
     2645    paranoid_free(sz_size);
     2646    paranoid_free(tmp1);
     2647    paranoid_free(command);
     2648    paranoid_free(comment);
     2649    paranoid_free(prompt);
     2650    return (0);
     2651}
     2652
     2653
     2654
     2655
     2656/**
     2657 * @addtogroup utilityGroup
     2658 * @{
     2659 */
     2660/**
     2661 * Get a space-separated list of NETFS devices and mounts.
     2662 * @return The list created.
     2663 * @note The return value points to static data that will be overwritten with each call.
     2664 */
     2665char *list_of_NETFS_devices_and_mounts(void)
     2666{
     2667    char *exclude_these_devices = NULL;
     2668    char *exclude_these_directories = NULL;
     2669    static char result_sz[1024];
     2670
     2671    mr_asprintf(&exclude_these_directories,"%s",list_of_NETFS_mounts_only());
     2672    mr_asprintf(&exclude_these_devices,"%s", call_program_and_get_last_line_of_output("tr -s '\t' ' ' < /etc/fstab | grep -E '( (coda|ncpfs|sshfs|nfs|nfs4|smbfs|cifs|afs|gfs|ocfs|ocfs2|mvfs|nsspool|nsvol) )' | cut -d' ' -f1 | tr -s '\n' ' ' | awk '{print $0;}'"));
     2673    snprintf(result_sz, 1023, "%s %s", exclude_these_directories, exclude_these_devices);
     2674    mr_free(exclude_these_devices);
     2675    mr_free(exclude_these_directories);
     2676    return (result_sz);
     2677}
     2678
     2679
     2680
     2681
     2682/**
     2683 * Get a space-separated list of NETFS mounts.
     2684 * @return The list created.
     2685 * @note The return value points to static data that will be overwritten with each call.
     2686 * @bug Even though we only want the mounts, the devices are still checked.
     2687 */
     2688char *list_of_NETFS_mounts_only(void)
     2689{
     2690    char *exclude_these_directories = NULL;
     2691    static char result_sz[512];
     2692
     2693    mr_asprintf(&exclude_these_directories,"%s", call_program_and_get_last_line_of_output("mount -t coda,ncpfs,fuse.sshfs,nfs,nfs4,smbfs,cifs,afs,gfs,ocfs,ocfs2,mvfs,nsspool,nssvol | tr -s '\t' ' ' | cut -d' ' -f3 | tr -s '\n' ' ' | awk '{print $0;}'"));
     2694    snprintf(result_sz, 511, "%s", exclude_these_directories);
     2695    mr_free(exclude_these_directories);
     2696    return (result_sz);
     2697}
     2698
     2699/* @} - end of utilityGroup */
     2700
     2701
     2702
     2703
     2704
     2705/**
     2706 * Create a randomly-named FIFO. The format is @p stub "." [random] [random] where
     2707 * [random] is a random number between 1 and 32767.
     2708 * @param store_name_here Where to store the new filename.
     2709 * @param stub A random number will be appended to this to make the FIFO's name.
     2710 * @ingroup deviceGroup
     2711 */
     2712void make_fifo(char *store_name_here, char *stub)
     2713{
     2714    char *tmp;
     2715
     2716    malloc_string(tmp);
     2717    assert_string_is_neither_NULL_nor_zerolength(stub);
     2718
     2719    sprintf(store_name_here, "%s%d%d", stub, (int) (random() % 32768),
     2720            (int) (random() % 32768));
     2721    make_hole_for_file(store_name_here);
     2722    mkfifo(store_name_here, S_IRWXU | S_IRWXG);
     2723    sprintf(tmp, "chmod 770 %s", store_name_here);
     2724    paranoid_system(tmp);
     2725    paranoid_free(tmp);
     2726}
     2727
     2728
     2729
     2730
     2731
     2732
     2733/**
     2734 * Set the tmpdir and scratchdir to reside on the partition with the most free space.
     2735 * Automatically excludes DOS, NTFS, SMB, and NFS filesystems.
     2736 * @param bkpinfo The backup information structure. @c bkpinfo->tmpdir and @c bkpinfo->scratchdir will be set.
     2737 * @ingroup utilityGroup
     2738 */
     2739void sensibly_set_tmpdir_and_scratchdir()
     2740{
     2741    char *tmp = NULL;
     2742    char *command = NULL;
     2743    char *sz = NULL;
     2744
     2745    assert(bkpinfo != NULL);
     2746
     2747#ifdef __FreeBSD__
     2748    mr_asprintf(&tmp, "%s", call_program_and_get_last_line_of_output("LANGUAGE=C df -m -P -t nonfs,msdosfs,ntfs,ntfs-3g,smbfs,smb,cifs,afs,gfs,ocfs,ocfs2,mvfs,nsspool,nssvol | grep -vE \"none|Filesystem\" | awk '{printf \"%s %s\\n\", $4, $6;}' | sort -n | tail -n1 | awk '{print $NF;}'"));
     2749#else
     2750    mr_asprintf(&tmp, "%s", call_program_and_get_last_line_of_output("LANGUAGE=C df -m -P -x nfs -x nfs4 -x fuse.sshfs -x vfat -x ntfs -x ntfs-3g -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 -n | tail -n1 | awk '{print $NF;}'"));
     2751#endif
     2752
     2753    if (tmp[0] != '/') {
     2754        mr_asprintf(&sz, "%s", tmp);
     2755        paranoid_free(tmp);
     2756        mr_asprintf(&tmp, "/%s", sz);
     2757        mr_free(sz);
     2758    }
     2759    if (!tmp[0]) {
     2760        fatal_error("I couldn't figure out the tempdir!");
     2761    }
     2762    setup_tmpdir(tmp);
     2763    log_it("bkpinfo->tmpdir is being set to %s", bkpinfo->tmpdir);
     2764
     2765    sprintf(bkpinfo->scratchdir, "%s/mondo.scratch.%d", tmp,
     2766            (int) (random() % 32768));
     2767    log_it("bkpinfo->scratchdir is being set to %s", bkpinfo->scratchdir);
     2768
     2769    mr_asprintf(&command, "rm -Rf %s/tmp.mondo.* %s/mondo.scratch.*", tmp, tmp);
     2770    paranoid_free(tmp);
     2771
     2772    paranoid_system(command);
     2773    mr_free(command);
     2774}
     2775
     2776
     2777
     2778
     2779
     2780
     2781/**
     2782 * @addtogroup deviceGroup
     2783 * @{
     2784 */
     2785/**
     2786 * If we can read @p dev, set @p output to it.
     2787 * If @p dev cannot be read, set @p output to "".
     2788 * @param dev The device to check for.
     2789 * @param output Set to @p dev if @p dev exists, "" otherwise.
     2790 * @return TRUE if @p dev exists, FALSE if it doesn't.
     2791 */
     2792bool set_dev_to_this_if_rx_OK(char *output, char *dev)
     2793{
     2794    char *command;
     2795
     2796    malloc_string(command);
     2797    if (!dev || dev[0] == '\0') {
     2798        output[0] = '\0';
     2799        return (FALSE);
     2800    }
     2801//  assert_string_is_neither_NULL_nor_zerolength(dev);
     2802    log_msg(10, "Injecting %s", dev);
     2803    inject_device(dev);
     2804    if (!does_file_exist(dev)) {
     2805        log_msg(10, "%s doesn't exist. Returning FALSE.", dev);
     2806        return (FALSE);
     2807    }
     2808    sprintf(command, "dd bs=%ld count=1 if=%s of=/dev/null &> /dev/null",
     2809            512L, dev);
     2810    if (!run_program_and_log_output(command, FALSE)
     2811        && !run_program_and_log_output(command, FALSE)) {
     2812        strcpy(output, dev);
     2813        log_msg(4, "Found it - %s", dev);
     2814        return (TRUE);
     2815    } else {
     2816        output[0] = '\0';
     2817        log_msg(4, "It's not %s", dev);
     2818        return (FALSE);
     2819    }
     2820}
     2821
     2822
     2823
     2824
     2825
     2826/**
     2827 * Find out what number CD is in the drive.
     2828 * @param bkpinfo The backup information structure. The @c bkpinfo->media_device field is the only one used.
     2829 * @return The current CD number, or -1 if it could not be found.
     2830 * @note If the CD is not mounted, it will be mounted
     2831 * (and remain mounted after this function returns).
     2832 */
     2833int what_number_cd_is_this()
     2834{
     2835    int cd_number = -1;
     2836    char *mountdev = NULL;
     2837    char *tmp = NULL;
     2838
     2839    assert(bkpinfo != NULL);
     2840//  log_it("Asking what_number_cd_is_this");
     2841    if (g_ISO_restore_mode) {
     2842        mr_asprintf(&tmp, "mount | grep iso9660 | awk '{print $3;}'");
     2843
     2844        mr_asprintf(&mountdev, "%s%s", call_program_and_get_last_line_of_output(tmp), "/archives/THIS-CD-NUMBER");
     2845        cd_number = atoi(last_line_of_file(mountdev));
     2846        paranoid_free(mountdev);
     2847        paranoid_free(tmp);
     2848
     2849        return (cd_number);
     2850    }
     2851
     2852    mr_asprintf(&mountdev, "%s", bkpinfo->media_device);
     2853    if (!mountdev[0]) {
     2854        log_it
     2855            ("(what_number_cd_is_this) Warning - media_device unknown. Finding out...");
     2856        find_cdrom_device(bkpinfo->media_device, FALSE);
     2857    }
     2858    if (!is_this_device_mounted(MNT_CDROM)) {
     2859        if (bkpinfo->backup_media_type == usb) {
     2860            mount_USB_here(mountdev, MNT_CDROM);
     2861        } else {
     2862            mount_CDROM_here(mountdev, MNT_CDROM);
     2863        }
     2864    }
     2865    paranoid_free(mountdev);
     2866
     2867    cd_number = atoi(last_line_of_file(MNT_CDROM "/archives/THIS-CD-NUMBER"));
     2868    return (cd_number);
     2869}
     2870
     2871
     2872
     2873
     2874
     2875
     2876
     2877/**
     2878 * Find out what device is mounted as root (/).
     2879 * @return Root device.
     2880 * @note The returned string points to static storage and will be overwritten with every call.
     2881 * @bug A bit of a misnomer; it's actually finding out the root device.
     2882 * The mountpoint (where it's mounted) will obviously be '/'.
     2883 */
     2884char *where_is_root_mounted()
     2885{
     2886    /*@ buffers **************** */
     2887    static char tmp[MAX_STR_LEN];
     2888
     2889
     2890#ifdef __FreeBSD__
     2891    strcpy(tmp, call_program_and_get_last_line_of_output
     2892           ("mount | grep \" on / \" | cut -d' ' -f1"));
     2893#else
     2894    strcpy(tmp, call_program_and_get_last_line_of_output
     2895           ("mount | grep \" on / \" | cut -d' ' -f1 | sed s/[0-9]// | sed s/[0-9]//"));
     2896    if (strstr(tmp, "/dev/cciss/")) {
     2897        strcpy(tmp, call_program_and_get_last_line_of_output
     2898               ("mount | grep \" on / \" | cut -d' ' -f1 | cut -dp -f1"));
     2899    }
     2900    if (strstr(tmp, "/dev/md")) {
     2901        strcpy(tmp,
     2902               call_program_and_get_last_line_of_output
     2903               ("mount | grep \" on / \" | cut -d' ' -f1"));
     2904    }
     2905#endif
     2906
     2907    return (tmp);
     2908}
     2909
     2910
     2911/**
     2912 * Find out which boot loader is in use.
     2913 * @param which_device Device to look for the boot loader on.
     2914 * @return 'L' for LILO, 'E'for ELILO, 'G' for GRUB, 'B' or 'D' for FreeBSD boot loaders, or 'U' for Unknown.
     2915 * @note Under Linux, all drives are examined, not just @p which_device.
     2916 */
     2917#ifdef __FreeBSD__
     2918char which_boot_loader(char *which_device)
     2919{
     2920    int count_lilos = 0;
     2921    int count_grubs = 0;
     2922    int count_boot0s = 0;
     2923    int count_dangerouslydedicated = 0;
     2924
     2925    log_it("looking at drive %s's MBR", which_device);
     2926    if (does_string_exist_in_boot_block(which_device, "GRUB")) {
     2927        count_grubs++;
     2928    }
     2929    if (does_string_exist_in_boot_block(which_device, "LILO")) {
     2930        count_lilos++;
     2931    }
     2932    if (does_string_exist_in_boot_block(which_device, "Drive")) {
     2933        count_boot0s++;
     2934    }
     2935    if (does_string_exist_in_first_N_blocks
     2936        (which_device, "FreeBSD/i386", 17)) {
     2937        count_dangerouslydedicated++;
     2938    }
     2939    log_it("%d grubs and %d lilos and %d elilos and %d boot0s and %d DD\n",
     2940           count_grubs, count_lilos, count_elilos, count_boot0s,
     2941           count_dangerouslydedicated);
     2942
     2943    if (count_grubs && !count_lilos) {
     2944        return ('G');
     2945    } else if (count_lilos && !count_grubs) {
     2946        return ('L');
     2947    } else if (count_grubs == 1 && count_lilos == 1) {
     2948        log_it("I'll bet you used to use LILO but switched to GRUB...");
     2949        return ('G');
     2950    } else if (count_boot0s == 1) {
     2951        return ('B');
     2952    } else if (count_dangerouslydedicated) {
     2953        return ('D');
     2954    } else {
     2955        log_it("Unknown boot loader");
     2956        return ('U');
     2957    }
     2958}
     2959
     2960#else
     2961
     2962char which_boot_loader(char *which_device)
     2963{
     2964    /*@ buffer ***************************************************** */
     2965    char *list_drives_cmd = NULL;
     2966    char *current_drive;
     2967
     2968    /*@ pointers *************************************************** */
     2969    FILE *pdrives;
     2970
     2971    /*@ int ******************************************************** */
     2972    int count_lilos = 0;
     2973    int count_grubs = 0;
     2974
     2975    /*@ end vars *************************************************** */
     2976
     2977    malloc_string(current_drive);
     2978
     2979#ifdef __IA64__
     2980    /* No choice for it */
     2981    return ('E');
     2982#endif
     2983    assert(which_device != NULL);
     2984
     2985    mr_asprintf(&list_drives_cmd, "parted2fdisk -l 2>/dev/null | grep \"/dev/.*:\" | tr -s ':' ' ' | tr -s ' ' '\n' | grep /dev/; echo %s", where_is_root_mounted());
     2986    log_it("list_drives_cmd = %s", list_drives_cmd);
     2987
     2988    if (!(pdrives = popen(list_drives_cmd, "r"))) {
     2989        log_OS_error("Unable to open list of drives");
     2990        mr_free(list_drives_cmd);
     2991        paranoid_free(current_drive);
     2992        return ('\0');
     2993    }
     2994    mr_free(list_drives_cmd);
     2995
     2996    for ((void)fgets(current_drive, MAX_STR_LEN, pdrives); !feof(pdrives);
     2997         (void)fgets(current_drive, MAX_STR_LEN, pdrives)) {
     2998        strip_spaces(current_drive);
     2999        log_it("looking at drive %s's MBR", current_drive);
     3000        if (does_string_exist_in_boot_block(current_drive, "GRUB")) {
     3001            count_grubs++;
     3002            strcpy(which_device, current_drive);
     3003            break;
     3004        }
     3005        if (does_string_exist_in_boot_block(current_drive, "LILO")) {
     3006            count_lilos++;
     3007            strcpy(which_device, current_drive);
     3008            break;
     3009        }
     3010    }
     3011    if (pclose(pdrives)) {
     3012        log_OS_error("Cannot pclose pdrives");
     3013    }
     3014    log_it("%d grubs and %d lilos\n", count_grubs, count_lilos);
     3015    if (count_grubs && !count_lilos) {
     3016        paranoid_free(current_drive);
     3017        return ('G');
     3018    } else if (count_lilos && !count_grubs) {
     3019        paranoid_free(current_drive);
     3020        return ('L');
     3021    } else if (count_grubs == 1 && count_lilos == 1) {
     3022        log_it("I'll bet you used to use LILO but switched to GRUB...");
     3023        paranoid_free(current_drive);
     3024        return ('G');
     3025    } else {
     3026        // We need to look on each partition then
     3027        mr_asprintf(&list_drives_cmd, "parted2fdisk -l 2>/dev/null | grep -E \"^/dev/\" | tr -s ':' ' ' | tr -s ' ' '\n' | grep /dev/");
     3028        log_it("list_drives_cmd = %s", list_drives_cmd);
     3029
     3030        if (!(pdrives = popen(list_drives_cmd, "r"))) {
     3031            log_OS_error("Unable to open list of drives");
     3032            mr_free(list_drives_cmd);
     3033            paranoid_free(current_drive);
     3034            return ('\0');
     3035        }
     3036        mr_free(list_drives_cmd);
     3037
     3038        for ((void)fgets(current_drive, MAX_STR_LEN, pdrives); !feof(pdrives);
     3039            (void)fgets(current_drive, MAX_STR_LEN, pdrives)) {
     3040            strip_spaces(current_drive);
     3041            log_it("looking at partition %s's BR", current_drive);
     3042            if (does_string_exist_in_boot_block(current_drive, "GRUB")) {
     3043                count_grubs++;
     3044                strcpy(which_device, current_drive);
     3045                break;
     3046            }
     3047            if (does_string_exist_in_boot_block(current_drive, "LILO")) {
     3048                count_lilos++;
     3049                strcpy(which_device, current_drive);
     3050                break;
     3051            }
     3052        }
     3053        if (pclose(pdrives)) {
     3054            log_OS_error("Cannot pclose pdrives");
     3055        }
     3056        log_it("%d grubs and %d lilos\n", count_grubs, count_lilos);
     3057        paranoid_free(current_drive);
     3058        if (count_grubs && !count_lilos) {
     3059            return ('G');
     3060        } else if (count_lilos && !count_grubs) {
     3061            return ('L');
     3062        } else if (count_grubs == 1 && count_lilos == 1) {
     3063            log_it("I'll bet you used to use LILO but switched to GRUB...");
     3064            return ('G');
     3065        } else {
     3066            log_it("Unknown boot loader");
     3067            return ('U');
     3068        }
     3069    }
     3070}
     3071#endif
     3072
     3073
     3074
     3075
     3076/**
     3077 * Write zeroes over the first 16K of @p device.
     3078 * @param device The device to zero.
     3079 * @return 0 for success, 1 for failure.
     3080 */
     3081int zero_out_a_device(char *device)
     3082{
     3083    FILE *fout;
     3084    int i;
     3085
     3086    assert_string_is_neither_NULL_nor_zerolength(device);
     3087
     3088    log_it("Zeroing drive %s", device);
     3089    if (!(fout = fopen(device, "w"))) {
     3090        log_OS_error("Unable to open/write to device");
     3091        return (1);
     3092    }
     3093    for (i = 0; i < 16384; i++) {
     3094        fputc('\0', fout);
     3095    }
     3096    paranoid_fclose(fout);
     3097    log_it("Device successfully zeroed.");
     3098    return (0);
     3099}
     3100
     3101/**
     3102 * Return the device pointed to by @p incoming.
     3103 * @param incoming The device to resolve symlinks for.
     3104 * @return The path to the real device file.
     3105 * @note The returned string points to static storage that will be overwritten with each call.
     3106 * @bug Won't work with file v4.0; needs to be written in C.
     3107 */
     3108char *resolve_softlinks_to_get_to_actual_device_file(char *incoming)
     3109{
     3110    static char output[MAX_STR_LEN];
     3111    char *command;
     3112    char *curr_fname;
     3113    char *scratch = NULL;
     3114    char *tmp = NULL;
     3115    char *p;
     3116
     3117    struct stat statbuf;
     3118    command = malloc(1000);
     3119    malloc_string(curr_fname);
     3120    if (!does_file_exist(incoming)) {
     3121        log_it
     3122            ("resolve_softlinks_to_get_to_actual_device_file --- device not found");
     3123        strcpy(output, incoming);
     3124    } else {
     3125        strcpy(curr_fname, incoming);
     3126        lstat(curr_fname, &statbuf);
     3127        while (S_ISLNK(statbuf.st_mode)) {
     3128            log_msg(1, "curr_fname = %s", curr_fname);
     3129            sprintf(command, "file %s", curr_fname);
     3130            mr_asprintf(&tmp, "%s", call_program_and_get_last_line_of_output(command));
     3131            for (p = tmp + strlen(tmp); p != tmp && *p != '`' && *p != ' ';
     3132                 p--);
     3133            p++;
     3134            mr_asprintf(&scratch, "%s", p);
     3135            for (p = scratch; *p != '\0' && *p != '\''; p++);
     3136            *p = '\0';
     3137            log_msg(0, "curr_fname %s --> '%s' --> %s", curr_fname, tmp, scratch);
     3138            mr_free(tmp);
     3139
     3140            if (scratch[0] == '/') {
     3141                strcpy(curr_fname, scratch);    // copy whole thing because it's an absolute softlink
     3142            } else {            // copy over the basename cos it's a relative softlink
     3143                p = curr_fname + strlen(curr_fname);
     3144                while (p != curr_fname && *p != '/') {
     3145                    p--;
     3146                }
     3147                if (*p == '/') {
     3148                    p++;
     3149                }
     3150                strcpy(p, scratch);
     3151            }
     3152            mr_free(scratch);
     3153            lstat(curr_fname, &statbuf);
     3154        }
     3155        strcpy(output, curr_fname);
     3156        log_it("resolved %s to %s", incoming, output);
     3157    }
     3158    paranoid_free(command);
     3159    paranoid_free(curr_fname);
     3160    return (output);
     3161}
     3162
    31933163/* @} - end of deviceGroup */
     3164
     3165/**
     3166 * Return the type of partition format (GPT or MBR)
     3167 */
     3168char *which_partition_format(const char *drive)
     3169{
     3170    static char output[4];
     3171    char *tmp = NULL;
     3172    char *command;
     3173    char *fdisk;
     3174#ifdef __IA64__
     3175    struct stat buf;
     3176#endif
     3177    malloc_string(command);
     3178    malloc_string(fdisk);
     3179    sprintf(fdisk, "/sbin/parted2fdisk");
     3180    sprintf(command, "%s -l %s | grep 'EFI GPT'", fdisk, drive);
     3181    mr_asprintf(&tmp, "%s", call_program_and_get_last_line_of_output(command));
     3182    if (strstr(tmp, "GPT") == NULL) {
     3183        strcpy(output, "MBR");
     3184    } else {
     3185        strcpy(output, "GPT");
     3186    }
     3187    mr_free(tmp);
     3188
     3189    log_msg(0, "Found %s partition table format type", output);
     3190    paranoid_free(command);
     3191    paranoid_free(fdisk);
     3192    return (output);
     3193}
     3194/* @} - end of deviceGroup */
Note: See TracChangeset for help on using the changeset viewer.