#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ioccom.h>
#include <sys/vnioctl.h>
#include <sys/fcntl.h>
#include <sys/stat.h>
#include <mach/boolean.h>
#include <sys/disk.h>
void
usage()
{
fprintf(stderr, "usage: vncontrol <command> <args>\n"
"vncontrol attach <dev_node> <image_file>\n"
"vncontrol shadow <dev_node> <shadow_file>\n"
"vncontrol detach <dev_node>\n");
exit(1);
}
enum {
kAttach,
kDetach,
kShadow,
};
int
main(int argc, char * argv[])
{
int fd;
struct vn_ioctl vn;
int op = kAttach;
struct stat sb;
if (argc < 2) {
usage();
}
if (strcmp(argv[1], "attach") == 0) {
if (argc < 4) {
usage();
}
op = kAttach;
}
else if (strcmp(argv[1], "detach") == 0) {
if (argc < 3) {
usage();
}
op = kDetach;
}
else if (strcmp(argv[1], "shadow") == 0) {
if (argc < 4) {
usage();
}
op = kShadow;
}
else {
usage();
}
fd = open(argv[2], O_RDONLY, 0);
if (fd < 0) {
perror(argv[2]);
exit(2);
}
switch (op) {
case kAttach:
case kShadow:
if (stat(argv[3], &sb) < 0) {
perror(argv[3]);
exit(2);
}
break;
default:
break;
}
bzero(&vn, sizeof(vn));
switch (op) {
case kAttach:
vn.vn_file = argv[3];
vn.vn_control = vncontrol_readwrite_io_e;
if (ioctl(fd, VNIOCATTACH, &vn) < 0) {
perror("VNIOCATTACH");
exit(2);
}
break;
case kDetach:
if (ioctl(fd, VNIOCDETACH, &vn) < 0) {
perror("VNIOCDETACH");
exit(2);
}
break;
case kShadow:
vn.vn_file = argv[3];
if (ioctl(fd, VNIOCSHADOW, &vn) < 0) {
perror("VNIOCSHADOW");
exit(2);
}
break;
}
close(fd);
exit(0);
return (0);
}