2 * cryptsetup - setup cryptographic volumes for dm-crypt
4 * Copyright (C) 2004, Jana Saout <jana@saout.de>
5 * Copyright (C) 2004-2007, Clemens Fruhwirth <clemens@endorphin.org>
6 * Copyright (C) 2009-2012, Red Hat, Inc. All rights reserved.
7 * Copyright (C) 2009-2014, Milan Broz
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 #include "cryptsetup.h"
29 int opt_batch_mode = 0;
31 /* interrupt handling */
32 volatile int quit = 0;
33 static int signals_blocked = 0;
35 static void int_handler(int sig __attribute__((__unused__)))
40 int tools_signals_blocked(void)
42 return signals_blocked;
45 void set_int_block(int block)
47 sigset_t signals_open;
49 log_dbg("%slocking interruption on signal.", block ? "B" : "Unb");
51 sigemptyset(&signals_open);
52 sigaddset(&signals_open, SIGINT);
53 sigaddset(&signals_open, SIGTERM);
54 sigprocmask(block ? SIG_SETMASK : SIG_UNBLOCK, &signals_open, NULL);
55 signals_blocked = block;
59 void set_int_handler(int block)
61 struct sigaction sigaction_open;
63 log_dbg("Installing SIGINT/SIGTERM handler.");
64 memset(&sigaction_open, 0, sizeof(struct sigaction));
65 sigaction_open.sa_handler = int_handler;
66 sigaction(SIGINT, &sigaction_open, 0);
67 sigaction(SIGTERM, &sigaction_open, 0);
71 void check_signal(int *r)
77 __attribute__((format(printf, 5, 6)))
78 void clogger(struct crypt_device *cd, int level, const char *file, int line,
79 const char *format, ...)
84 va_start(argp, format);
86 if (vasprintf(&target, format, argp) > 0) {
88 crypt_log(cd, level, target);
91 printf("# %s:%d %s\n", file ?: "?", line, target);
94 printf("# %s\n", target);
102 void tool_log(int level, const char *msg, void *usrptr __attribute__((unused)))
106 case CRYPT_LOG_NORMAL:
109 case CRYPT_LOG_VERBOSE:
113 case CRYPT_LOG_ERROR:
116 case CRYPT_LOG_DEBUG:
118 printf("# %s\n", msg);
121 fprintf(stderr, "Internal error on logging class for msg: %s", msg);
126 void quiet_log(int level, const char *msg, void *usrptr)
128 if (!opt_verbose && (level == CRYPT_LOG_ERROR || level == CRYPT_LOG_NORMAL))
129 level = CRYPT_LOG_VERBOSE;
130 tool_log(level, msg, usrptr);
133 int yesDialog(const char *msg, void *usrptr __attribute__((unused)))
139 block = tools_signals_blocked();
143 if(isatty(STDIN_FILENO) && !opt_batch_mode) {
144 log_std("\nWARNING!\n========\n");
145 log_std("%s\n\nAre you sure? (Type uppercase yes): ", msg);
147 if(getline(&answer, &size, stdin) == -1) {
149 /* Aborted by signal */
151 log_err(_("Error reading response from terminal.\n"));
153 log_dbg("Query interrupted on signal.");
154 } else if(strcmp(answer, "YES\n"))
165 void show_status(int errcode)
173 log_std(_("Command successful.\n"));
177 crypt_get_error(error, sizeof(error));
180 #ifdef STRERROR_R_CHAR_P /* GNU-specific strerror_r */
181 char *error_ = strerror_r(-errcode, error, sizeof(error));
183 strncpy(error, error_, sizeof(error));
184 #else /* POSIX strerror_r variant */
185 if (strerror_r(-errcode, error, sizeof(error)))
188 error[sizeof(error) - 1] = '\0';
191 log_err(_("Command failed with code %i"), -errcode);
193 log_err(": %s\n", error);
198 const char *uuid_or_device(const char *spec)
200 static char device[PATH_MAX];
202 int i = 0, uuid_len = 5;
204 /* Check if it is correct UUID=<LUKS_UUID> format */
205 if (spec && !strncmp(spec, "UUID=", uuid_len)) {
206 strcpy(device, "/dev/disk/by-uuid/");
207 ptr = &device[strlen(device)];
209 while ((s = spec[i++]) && i < PATH_MAX) {
210 if (!isxdigit(s) && s != '-')
211 return spec; /* Bail it out */
223 __attribute__ ((noreturn)) void usage(poptContext popt_context,
224 int exitcode, const char *error,
227 poptPrintUsage(popt_context, stderr, 0);
229 log_err("%s: %s\n", more, error);
230 poptFreeContext(popt_context);
234 void dbg_version_and_cmd(int argc, const char **argv)
238 log_std("# %s %s processing \"", PACKAGE_NAME, PACKAGE_VERSION);
239 for (i = 0; i < argc; i++) {
242 log_std("%s", argv[i]);
247 /* Translate exit code to simple codes */
248 int translate_errno(int r)
251 case 0: r = EXIT_SUCCESS; break;
253 case -EBUSY: r = 5; break;
255 case -ENODEV: r = 4; break;
256 case -ENOMEM: r = 3; break;
257 case -EPERM: r = 2; break;
261 default: r = EXIT_FAILURE;