1/*
2 * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24/*
25 * History:
26 * March 25, 2002	Dieter Siegmund (dieter@apple.com)
27 * - created
28 */
29
30#include <stdio.h>
31#include <unistd.h>
32#include <stdlib.h>
33#include <string.h>
34#include <sys/types.h>
35#include <sys/ioccom.h>
36#include <sys/vnioctl.h>
37#include <sys/fcntl.h>
38#include <sys/stat.h>
39#include <mach/boolean.h>
40#include <sys/disk.h>
41
42void
43usage()
44{
45    fprintf(stderr, "usage: vncontrol <command> <args>\n"
46	    "vncontrol attach <dev_node> <image_file>\n"
47	    "vncontrol shadow <dev_node> <shadow_file>\n"
48	    "vncontrol detach <dev_node>\n");
49    exit(1);
50}
51
52enum {
53  kAttach,
54  kDetach,
55  kShadow,
56};
57
58int
59main(int argc, char * argv[])
60{
61    int fd;
62    struct vn_ioctl vn;
63    int op = kAttach;
64    struct stat sb;
65
66    if (argc < 2) {
67	usage();
68    }
69    if (strcmp(argv[1], "attach") == 0) {
70	if (argc < 4) {
71	    usage();
72	}
73	op = kAttach;
74    }
75    else if (strcmp(argv[1], "detach") == 0) {
76	if (argc < 3) {
77	    usage();
78	}
79	op = kDetach;
80    }
81    else if (strcmp(argv[1], "shadow") == 0) {
82	if (argc < 4) {
83	    usage();
84	}
85	op = kShadow;
86    }
87    else {
88	usage();
89    }
90    fd = open(argv[2], O_RDONLY, 0);
91    if (fd < 0) {
92	perror(argv[2]);
93	exit(2);
94    }
95    switch (op) {
96    case kAttach:
97    case kShadow:
98	if (stat(argv[3], &sb) < 0) {
99	    perror(argv[3]);
100	    exit(2);
101	}
102	break;
103    default:
104	break;
105    }
106    bzero(&vn, sizeof(vn));
107    switch (op) {
108    case kAttach:
109	vn.vn_file = argv[3];
110	vn.vn_control = vncontrol_readwrite_io_e;
111
112	if (ioctl(fd, VNIOCATTACH, &vn) < 0) {
113	    perror("VNIOCATTACH");
114	    exit(2);
115	}
116	break;
117    case kDetach:
118	if (ioctl(fd, VNIOCDETACH, &vn) < 0) {
119	    perror("VNIOCDETACH");
120	    exit(2);
121	}
122	break;
123    case kShadow:
124	vn.vn_file = argv[3];
125	if (ioctl(fd, VNIOCSHADOW, &vn) < 0) {
126	    perror("VNIOCSHADOW");
127	    exit(2);
128	}
129	break;
130    }
131    close(fd);
132    exit(0);
133    return (0);
134}
135