2 * cryptsetup - setup cryptographic volumes for dm-crypt
4 * Copyright (C) 2004, Christophe Saout <christophe@saout.de>
5 * Copyright (C) 2004-2007, Clemens Fruhwirth <clemens@endorphin.org>
6 * Copyright (C) 2009-2012, Red Hat, Inc. All rights reserved.
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 #include "cryptsetup.h"
27 int opt_batch_mode = 0;
29 /* interrupt handling */
30 volatile int quit = 0;
31 static int signals_blocked = 0;
33 static void int_handler(int sig __attribute__((__unused__)))
38 void set_int_block(int block)
40 sigset_t signals_open;
42 log_dbg("%slocking interruption on signal.", block ? "B" : "Unb");
44 sigemptyset(&signals_open);
45 sigaddset(&signals_open, SIGINT);
46 sigaddset(&signals_open, SIGTERM);
47 sigprocmask(block ? SIG_SETMASK : SIG_UNBLOCK, &signals_open, NULL);
48 signals_blocked = block;
52 void set_int_handler(int block)
54 struct sigaction sigaction_open;
56 log_dbg("Installing SIGINT/SIGTERM handler.");
57 memset(&sigaction_open, 0, sizeof(struct sigaction));
58 sigaction_open.sa_handler = int_handler;
59 sigaction(SIGINT, &sigaction_open, 0);
60 sigaction(SIGTERM, &sigaction_open, 0);
64 void check_signal(int *r)
70 /* crypt_get_key() with signal handler */
71 int tools_get_key(const char *prompt,
72 char **key, size_t *key_size,
73 size_t keyfile_offset, size_t keyfile_size_max,
75 int timeout, int verify,
76 struct crypt_device *cd)
80 block = signals_blocked;
84 r = crypt_get_key(prompt, key, key_size, keyfile_offset,
85 keyfile_size_max, key_file, timeout, verify, cd);
92 __attribute__((format(printf, 5, 6)))
93 void clogger(struct crypt_device *cd, int level, const char *file, int line,
94 const char *format, ...)
99 va_start(argp, format);
101 if (vasprintf(&target, format, argp) > 0) {
103 crypt_log(cd, level, target);
105 } else if (opt_debug)
106 printf("# %s:%d %s\n", file ?: "?", line, target);
108 } else if (opt_debug)
109 printf("# %s\n", target);
117 void tool_log(int level, const char *msg, void *usrptr __attribute__((unused)))
121 case CRYPT_LOG_NORMAL:
124 case CRYPT_LOG_VERBOSE:
128 case CRYPT_LOG_ERROR:
131 case CRYPT_LOG_DEBUG:
133 printf("# %s\n", msg);
136 fprintf(stderr, "Internal error on logging class for msg: %s", msg);
141 void quiet_log(int level, const char *msg, void *usrptr)
143 if (!opt_verbose && (level == CRYPT_LOG_ERROR || level == CRYPT_LOG_NORMAL))
144 level = CRYPT_LOG_VERBOSE;
145 tool_log(level, msg, usrptr);
148 int yesDialog(const char *msg, void *usrptr __attribute__((unused)))
154 block = signals_blocked;
158 if(isatty(STDIN_FILENO) && !opt_batch_mode) {
159 log_std("\nWARNING!\n========\n");
160 log_std("%s\n\nAre you sure? (Type uppercase yes): ", msg);
161 if(getline(&answer, &size, stdin) == -1) {
163 /* Aborted by signal */
165 log_err(_("Error reading response from terminal.\n"));
167 log_dbg("Query interrupted on signal.");
168 } else if(strcmp(answer, "YES\n"))
179 void show_status(int errcode)
181 char error[256], *error_;
187 log_std(_("Command successful.\n"));
191 crypt_get_error(error, sizeof(error));
194 error_ = strerror_r(-errcode, error, sizeof(error));
195 if (error_ != error) {
196 strncpy(error, error_, sizeof(error));
197 error[sizeof(error) - 1] = '\0';
201 log_err(_("Command failed with code %i"), -errcode);
203 log_err(": %s\n", error);
208 const char *uuid_or_device(const char *spec)
210 static char device[PATH_MAX];
212 int i = 0, uuid_len = 5;
214 /* Check if it is correct UUID=<LUKS_UUID> format */
215 if (spec && !strncmp(spec, "UUID=", uuid_len)) {
216 strcpy(device, "/dev/disk/by-uuid/");
217 ptr = &device[strlen(device)];
219 while ((s = spec[i++]) && i < PATH_MAX) {
220 if (!isxdigit(s) && s != '-')
221 return spec; /* Bail it out */
233 __attribute__ ((noreturn)) void usage(poptContext popt_context,
234 int exitcode, const char *error,
237 poptPrintUsage(popt_context, stderr, 0);
239 log_err("%s: %s\n", more, error);
240 poptFreeContext(popt_context);
244 void dbg_version_and_cmd(int argc, const char **argv)
248 log_std("# %s %s processing \"", PACKAGE_NAME, PACKAGE_VERSION);
249 for (i = 0; i < argc; i++) {
252 log_std("%s", argv[i]);
257 /* Translate exit code to simple codes */
258 int translate_errno(int r)
261 case 0: r = EXIT_SUCCESS; break;
263 case -EBUSY: r = 5; break;
265 case -ENODEV: r = 4; break;
266 case -ENOMEM: r = 3; break;
267 case -EPERM: r = 2; break;
271 default: r = EXIT_FAILURE;