2 * Copyright (c) 2009 The DragonFly Project. All rights reserved.
4 * This code is derived from software contributed to The DragonFly Project
5 * by Alex Hornung <ahornung@gmail.com>
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
17 * 3. Neither the name of The DragonFly Project nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific, prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
42 #include <libcryptsetup.h>
44 #define iswhitespace(X) ((((X) == ' ') || ((X) == '\t'))?1:0)
46 #define CRYPTDISKS_START 1
47 #define CRYPTDISKS_STOP 2
49 static void syntax_error(const char *, ...) __printflike(1, 2);
51 static int line_no = 1;
53 static int yesDialog(char *msg __unused)
58 static void cmdLineLog(int level __unused, char *msg)
63 static struct interface_callbacks cmd_icb = {
64 .yesDialog = yesDialog,
69 syntax_error(const char *fmt, ...)
75 vsnprintf(buf, sizeof(buf), fmt, ap);
77 errx(1, "crypttab: syntax error on line %d: %s\n", line_no, buf);
82 entry_check_num_args(char **tokens, int num)
86 for (i = 0; tokens[i] != NULL; i++)
90 syntax_error("at least %d tokens were expected but only %d were found", num, i);
97 entry_parser(char **tokens, int type)
99 struct crypt_options co;
102 if (entry_check_num_args(tokens, 2) != 0)
105 bzero(&co, sizeof(co));
109 co.device = tokens[1];
111 error = crypt_isLuks(&co);
113 printf("crypttab: line %d: device %s is not a luks device\n",
118 if (type == CRYPTDISKS_STOP) {
119 /* Check if the device is active */
120 r = crypt_query_device(&co);
122 /* If r > 0, then the device is active */
126 /* Actually close the device */
127 crypt_remove_device(&co);
128 } else if (type == CRYPTDISKS_START) {
129 if ((tokens[2] != NULL) && (strcmp(tokens[2], "none") != 0)) {
130 /* We got a keyfile */
131 co.key_file = tokens[2];
134 /* Open the device */
142 process_line(FILE* fd, int type)
150 while (((c = fgetc(fd)) != EOF) && (c != '\n')) {
151 buffer[i++] = (char)c;
152 if (i == (sizeof(buffer) -1))
157 if (feof(fd) || ferror(fd))
160 while (((buffer[c] == ' ') || (buffer[c] == '\t')) && (c < i)) c++;
162 * If this line effectively (after indentation) begins with the comment
163 * character #, we ignore the rest of the line.
165 if (buffer[c] == '#')
168 tokens[0] = &buffer[c];
169 for (n = 1; c < i; c++) {
170 if (buffer[c] == '"') {
173 if ((c >= 1) && (&buffer[c] != tokens[n-1])) {
174 syntax_error("stray opening quote not at beginning of token");
177 tokens[n-1] = &buffer[c+1];
179 if ((c < i-1) && (!iswhitespace(buffer[c+1]))) {
180 syntax_error("stray closing quote not at end of token");
191 if ((buffer[c] == ' ') || (buffer[c] == '\t')) {
193 while ((iswhitespace(buffer[c])) && (c < i)) c++;
194 tokens[n++] = &buffer[c--];
200 * If there are not enough arguments for any function or it is
201 * a line full of whitespaces, we just return here. Or if a
202 * quote wasn't closed.
204 if ((quote) || (n < 2) || (tokens[0][0] == '\0'))
207 entry_parser(tokens, type);
214 main(int argc, char *argv[])
217 int ch, start = 0, stop = 0;
219 while ((ch = getopt(argc, argv, "01")) != -1) {
235 if ((start && stop) || (!start && !stop))
236 errx(1, "please specify exactly one of -0 and -1");
238 fd = fopen("/etc/crypttab", "r");
243 while (process_line(fd, (start) ? CRYPTDISKS_START : CRYPTDISKS_STOP) == 0)