*␊ |
* Created by Zenith432 on November 19th, 2014.␊ |
* Copyright (c) 2014 Zenith432. All rights reserved.␊ |
*␊ |
* Modified December 5th, 2014 by Micky1979: Added -u option to force umount.␊ |
*/␊ |
␊ |
#include <assert.h>␊ |
|
}␊ |
␊ |
static␊ |
int umount(char const* pathName)␊ |
int umount(char const* pathName, int forceUmount)␊ |
{␊ |
␉DASessionRef session;␊ |
␉DADiskRef disk;␊ |
|
␉␉return -1;␊ |
␉rc = 0;␊ |
␉DASessionScheduleWithRunLoop(session, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);␊ |
␉DADiskUnmount(disk, kDADiskUnmountOptionDefault, umountCallback, &rc);␊ |
␉DADiskUnmount(disk, forceUmount ? kDADiskUnmountOptionForce : kDADiskUnmountOptionDefault, umountCallback, &rc);␊ |
␉CFRunLoopRun();␊ |
␉DASessionUnscheduleFromRunLoop(session, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);␊ |
␉CFRelease(disk);␊ |
|
␉assert(pathName);␊ |
␉if (strncmp(pathName, &devdisk[0], 9) != 0 &&␊ |
␉␉strncmp(pathName, &devrdisk[0], 10) != 0) {␊ |
␉␉fprintf(stderr, "disk must be of form /dev/rdiskUsS or /dev/diskUsS\n");␊ |
␉␉fprintf(stderr, "disk must be of form /dev/rdiskUsS or /dev/diskUsS\ndisk is %s\n", pathName);␊ |
␉␉return -1;␊ |
␉}␊ |
␉if (stat(pathName, &buf) < 0) {␊ |
|
void usage(char const* self)␊ |
{␊ |
␉assert(self);␊ |
␉fprintf(stderr, "Usage: %s [-yM] [-f boot_code_file] disk\n", self);␊ |
␉fprintf(stderr, "Usage: %s [-yMu] [-f boot_code_file] disk\n", self);␊ |
␉fprintf(stderr, " boot_code_file is an optional boot template\n");␊ |
␉fprintf(stderr, " -y: don't ask any questions\n");␊ |
␉fprintf(stderr, " -M: keep volume mounted while proceeding (useful for root filesystem)\n");␊ |
␉fprintf(stderr, " -u: force umount (suppresses -M option if given)\n");␊ |
␉fprintf(stderr, "disk is of the form /dev/rdiskUsS or /dev/diskUsS\n");␊ |
␉fprintf(stderr, "default boot files are\n");␊ |
␉fprintf(stderr, " boot1h for HFS+\n");␊ |
|
␉char const* devicePath = NULL;␊ |
␉int dontAsk = 0;␊ |
␉int keepMounted = 0;␊ |
␉int forceUmount = 0;␊ |
␊ |
␉while ((ch = getopt(argc, argv, "yMf:")) != -1)␊ |
␉while ((ch = getopt(argc, argv, "yMuf:")) != -1)␊ |
␉␉switch (ch) {␊ |
␉␉␉case 'y':␊ |
␉␉␉␉dontAsk = 1;␊ |
|
␉␉␉case 'M':␊ |
␉␉␉␉keepMounted = 1;␊ |
␉␉␉␉break;␊ |
␉␉␉case 'u':␊ |
␉␉␉␉forceUmount = 1;␊ |
␉␉␉␉break;␊ |
␉␉␉case 'f':␊ |
␉␉␉␉bootFile = optarg;␊ |
␉␉␉␉break;␊ |
|
␉␉fprintf(stderr, "This program must be run as root\n");␊ |
␉␉return -1;␊ |
␉}␊ |
␉if (forceUmount)␊ |
␉␉keepMounted = 0;␊ |
#if 0␊ |
␉printf("bootFile %s, devicePath %s, dontAsk %d\n", bootFile, devicePath, dontAsk);␊ |
#endif␊ |
|
␉␉}␊ |
␉␉if (isVolumeMounted && keepMounted)␊ |
␉␉␉isVolumeMounted = 0;␊ |
␉␉if (isVolumeMounted && umount(devicePath) < 0) {␊ |
␉␉␉fprintf(stderr, "Unable to umount %s, please 'diskutil umount' manually before running this program\n", devicePath);␊ |
␉␉if (isVolumeMounted && umount(devicePath, forceUmount) < 0) {␊ |
␉␉␉if (forceUmount)␊ |
␉␉␉␉fprintf(stderr, "Unable to force umount %s, please try to umount it manually or reboot\n", devicePath);␊ |
␉␉␉else␊ |
␉␉␉␉fprintf(stderr, "Unable to umount %s, please 'diskutil umount' manually before running this program,\nor pass -u option to force umount it\n", devicePath);␊ |
␉␉␉return -1;␊ |
␉␉}␊ |
␉}␊ |