1 /* $NetBSD: img2cgd.c,v 1.2 2009/09/08 21:51:33 pooka Exp $ */
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
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
28 #include <sys/types.h>
29 #include <sys/param.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
53 #define SKIPLABEL 8192
54 #define IMG_MINSIZE (120*1024) /* label/mbr/etc search looks here and there */
60 fprintf(stderr
, "usage: %s read|write cgd_image file\n", getprogname());
64 typedef ssize_t (*readfn
)(int, void *, size_t);
65 typedef ssize_t (*writefn
)(int, const void *, size_t);
68 #define BLKROUND(a) (((a)+(BLOCKSIZE-1)) & ~(BLOCKSIZE-1))
71 doxfer(int fd_from
, int fd_to
, off_t nbytes
, readfn rfn
, writefn wfn
,
77 assert(sizeof(buf
) % BLOCKSIZE
== 0);
79 nbytes
= BLKROUND(nbytes
);
81 memset(buf
, 0, sizeof(buf
));
83 n
= rfn(fd_from
, buf
, sizeof(buf
));
92 if (wfn(fd_to
, buf
, n
) == -1)
97 #define RFLAGS (O_RDONLY)
98 #define WFLAGS (O_WRONLY | O_CREAT | O_TRUNC)
100 main(int argc
, char *argv
[])
103 const char *cgd_file
, *img_file
;
104 struct stat sb_cgd
, sb_file
;
110 setprogname(argv
[0]);
115 if (strcmp(argv
[1], "read") == 0)
117 else if (strcmp(argv
[1], "write") == 0)
125 if (stat(img_file
, &sb_file
) == -1) {
127 err(1, "cannot open file image %s", img_file
);
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) {
135 err(1, "cannot open cgd image %s", cgd_file
);
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 ...).
149 fd
= open(cgd_file
, WFLAGS
, 0755);
153 MAX(IMG_MINSIZE
, BLKROUND(sb_file
.st_size
)) + SKIPLABEL
);
155 /* write magic info */
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");
165 nbytes
= sb_file
.st_size
;
169 fd
= open(cgd_file
, RFLAGS
);
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");
181 nbytes
= le64toh(tmpval
);
185 if ((error
= rump_pub_etfs_register("/cryptfile", cgd_file
,
186 RUMP_ETFS_BLK
)) != 0) {
187 printf("etfs: %d\n", error
);
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");
196 error
= cgdconfig(4, the_argv
);
198 fprintf(stderr
, "cgdconfig failed: %d (%s)\n",
199 error
, strerror(error
));
203 fd
= open(img_file
, readmode
? WFLAGS
: RFLAGS
, 0755);
206 fd_r
= rump_sys_open("/dev/rcgd0d", O_RDWR
, 0755);
209 if (rump_sys_lseek(fd_r
, SKIPLABEL
, SEEK_SET
) == -1)
210 err(1, "rump lseek");
213 doxfer(fd_r
, fd
, nbytes
, rump_sys_read
, write
, 0);
215 doxfer(fd
, fd_r
, sb_file
.st_size
, read
, rump_sys_write
, 1);