Expand PMF_FN_* macros.
[netbsd-mini2440.git] / share / examples / rump / img2cgd / img2cgd.c
blob4bcb04ccab76dcb42f3414220ad1f2a430f5b2aa
1 /* $NetBSD: img2cgd.c,v 1.2 2009/09/08 21:51:33 pooka Exp $ */
3 /*
4 * Copyright (c) 2009 Antti Kantee. All Rights Reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
16 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
28 #include <sys/types.h>
29 #include <sys/param.h>
31 #include <assert.h>
32 #include <err.h>
33 #include <fcntl.h>
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37 #include <unistd.h>
39 #include <rump/rump.h>
40 #include <rump/rump_syscalls.h>
42 #include "cgdconfig.h"
45 * We really should use disklabel. However, for the time being,
46 * use a endian independent magic number at offset == 0 and a
47 * 64bit size at offset == 8.
49 #define MYMAGIC 0x11000a00000a0011LL
50 #define MAGOFF 0
51 #define SIZEOFF 8
53 #define SKIPLABEL 8192
54 #define IMG_MINSIZE (120*1024) /* label/mbr/etc search looks here and there */
56 static void
57 usage(void)
60 fprintf(stderr, "usage: %s read|write cgd_image file\n", getprogname());
61 exit(1);
64 typedef ssize_t (*readfn)(int, void *, size_t);
65 typedef ssize_t (*writefn)(int, const void *, size_t);
67 #define BLOCKSIZE 512
68 #define BLKROUND(a) (((a)+(BLOCKSIZE-1)) & ~(BLOCKSIZE-1))
70 static void
71 doxfer(int fd_from, int fd_to, off_t nbytes, readfn rfn, writefn wfn,
72 int roundwrite)
74 char buf[8192];
75 ssize_t n;
77 assert(sizeof(buf) % BLOCKSIZE == 0);
78 if (roundwrite)
79 nbytes = BLKROUND(nbytes);
81 memset(buf, 0, sizeof(buf));
82 while (nbytes) {
83 n = rfn(fd_from, buf, sizeof(buf));
84 if (n == -1)
85 err(1, "read");
86 if (n == 0)
87 break;
88 n = MIN(n, nbytes);
89 if (roundwrite)
90 n = BLKROUND(n);
91 nbytes -= n;
92 if (wfn(fd_to, buf, n) == -1)
93 err(1, "write");
97 #define RFLAGS (O_RDONLY)
98 #define WFLAGS (O_WRONLY | O_CREAT | O_TRUNC)
99 int
100 main(int argc, char *argv[])
102 char *the_argv[10];
103 const char *cgd_file, *img_file;
104 struct stat sb_cgd, sb_file;
105 off_t nbytes;
106 int error;
107 int fd, fd_r;
108 int readmode;
110 setprogname(argv[0]);
112 if (argc != 4)
113 usage();
115 if (strcmp(argv[1], "read") == 0)
116 readmode = 1;
117 else if (strcmp(argv[1], "write") == 0)
118 readmode = 0;
119 else
120 usage();
122 cgd_file = argv[2];
123 img_file = argv[3];
125 if (stat(img_file, &sb_file) == -1) {
126 if (!readmode)
127 err(1, "cannot open file image %s", img_file);
128 } else {
129 if (!S_ISREG(sb_file.st_mode))
130 errx(1, "%s is not a regular file", img_file);
133 if (stat(cgd_file, &sb_cgd) == -1) {
134 if (readmode)
135 err(1, "cannot open cgd image %s", cgd_file);
136 } else {
137 if (!S_ISREG(sb_cgd.st_mode))
138 errx(1, "%s is not a regular file", cgd_file);
142 * Create a file big enough to hold the file we are encrypting.
143 * This is because cgd works on a device internally and does
144 * not know how to enlarge a device (surprisingly ...).
146 if (!readmode) {
147 uint64_t tmpval;
149 fd = open(cgd_file, WFLAGS, 0755);
150 if (fd == -1)
151 err(1, "fd");
152 ftruncate(fd,
153 MAX(IMG_MINSIZE, BLKROUND(sb_file.st_size)) + SKIPLABEL);
155 /* write magic info */
156 tmpval = MYMAGIC;
157 if (pwrite(fd, &tmpval, 8, MAGOFF) != 8)
158 err(1, "magic write failed");
159 tmpval = htole64(sb_file.st_size);
160 if (pwrite(fd, &tmpval, 8, SIZEOFF) != 8)
161 err(1, "size write failed");
163 close(fd);
165 nbytes = sb_file.st_size;
166 } else {
167 uint64_t tmpval;
169 fd = open(cgd_file, RFLAGS);
170 if (fd == -1)
171 err(1, "image open failed");
173 if (pread(fd, &tmpval, 8, MAGOFF) != 8)
174 err(1, "magic read failed");
175 if (tmpval != MYMAGIC)
176 errx(1, "%s is not a valid image", cgd_file);
177 if (pread(fd, &tmpval, 8, SIZEOFF) != 8)
178 errx(1, "size read failed");
179 close(fd);
181 nbytes = le64toh(tmpval);
184 rump_init();
185 if ((error = rump_pub_etfs_register("/cryptfile", cgd_file,
186 RUMP_ETFS_BLK)) != 0) {
187 printf("etfs: %d\n", error);
188 exit(1);
191 the_argv[0] = strdup("cgdconfig");
192 the_argv[1] = strdup("cgd0");
193 the_argv[2] = strdup("/cryptfile");
194 the_argv[3] = strdup("./cgd.conf");
195 the_argv[4] = NULL;
196 error = cgdconfig(4, the_argv);
197 if (error) {
198 fprintf(stderr, "cgdconfig failed: %d (%s)\n",
199 error, strerror(error));
200 exit(1);
203 fd = open(img_file, readmode ? WFLAGS : RFLAGS, 0755);
204 if (fd == -1)
205 err(1, "fd");
206 fd_r = rump_sys_open("/dev/rcgd0d", O_RDWR, 0755);
207 if (fd_r == -1)
208 err(1, "fd_r");
209 if (rump_sys_lseek(fd_r, SKIPLABEL, SEEK_SET) == -1)
210 err(1, "rump lseek");
212 if (readmode) {
213 doxfer(fd_r, fd, nbytes, rump_sys_read, write, 0);
214 } else {
215 doxfer(fd, fd_r, sb_file.st_size, read, rump_sys_write, 1);
218 return 0;