mirror of
https://gitlab.com/cryptsetup/cryptsetup.git
synced 2025-12-14 12:20:00 +01:00
202 lines
4.4 KiB
C
202 lines
4.4 KiB
C
/*
|
|
* cryptsetup - setup cryptographic volumes for dm-crypt
|
|
*
|
|
* Copyright (C) 2004, Christophe Saout <christophe@saout.de>
|
|
* Copyright (C) 2004-2007, Clemens Fruhwirth <clemens@endorphin.org>
|
|
* Copyright (C) 2009-2012, Red Hat, Inc. All rights reserved.
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* version 2 as published by the Free Software Foundation.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
*/
|
|
|
|
#include "cryptsetup.h"
|
|
|
|
int opt_verbose = 0;
|
|
int opt_debug = 0;
|
|
int opt_batch_mode = 0;
|
|
|
|
__attribute__((format(printf, 5, 6)))
|
|
void clogger(struct crypt_device *cd, int level, const char *file, int line,
|
|
const char *format, ...)
|
|
{
|
|
va_list argp;
|
|
char *target = NULL;
|
|
|
|
va_start(argp, format);
|
|
|
|
if (vasprintf(&target, format, argp) > 0) {
|
|
if (level >= 0) {
|
|
crypt_log(cd, level, target);
|
|
#ifdef CRYPT_DEBUG
|
|
} else if (opt_debug)
|
|
printf("# %s:%d %s\n", file ?: "?", line, target);
|
|
#else
|
|
} else if (opt_debug)
|
|
printf("# %s\n", target);
|
|
#endif
|
|
}
|
|
|
|
va_end(argp);
|
|
free(target);
|
|
}
|
|
|
|
void tool_log(int level, const char *msg, void *usrptr __attribute__((unused)))
|
|
{
|
|
switch(level) {
|
|
|
|
case CRYPT_LOG_NORMAL:
|
|
fputs(msg, stdout);
|
|
break;
|
|
case CRYPT_LOG_VERBOSE:
|
|
if (opt_verbose)
|
|
fputs(msg, stdout);
|
|
break;
|
|
case CRYPT_LOG_ERROR:
|
|
fputs(msg, stderr);
|
|
break;
|
|
case CRYPT_LOG_DEBUG:
|
|
if (opt_debug)
|
|
printf("# %s\n", msg);
|
|
break;
|
|
default:
|
|
fprintf(stderr, "Internal error on logging class for msg: %s", msg);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void quiet_log(int level, const char *msg, void *usrptr)
|
|
{
|
|
if (!opt_verbose && (level == CRYPT_LOG_ERROR || level == CRYPT_LOG_NORMAL))
|
|
level = CRYPT_LOG_VERBOSE;
|
|
tool_log(level, msg, usrptr);
|
|
}
|
|
|
|
int yesDialog(const char *msg, void *usrptr __attribute__((unused)))
|
|
{
|
|
char *answer = NULL;
|
|
size_t size = 0;
|
|
int r = 1;
|
|
|
|
if(isatty(STDIN_FILENO) && !opt_batch_mode) {
|
|
log_std("\nWARNING!\n========\n");
|
|
log_std("%s\n\nAre you sure? (Type uppercase yes): ", msg);
|
|
if(getline(&answer, &size, stdin) == -1) {
|
|
perror("getline");
|
|
free(answer);
|
|
return 0;
|
|
}
|
|
if(strcmp(answer, "YES\n"))
|
|
r = 0;
|
|
free(answer);
|
|
}
|
|
|
|
return r;
|
|
}
|
|
|
|
void show_status(int errcode)
|
|
{
|
|
char error[256], *error_;
|
|
|
|
if(!opt_verbose)
|
|
return;
|
|
|
|
if(!errcode) {
|
|
log_std(_("Command successful.\n"));
|
|
return;
|
|
}
|
|
|
|
crypt_get_error(error, sizeof(error));
|
|
|
|
if (!error[0]) {
|
|
error_ = strerror_r(-errcode, error, sizeof(error));
|
|
if (error_ != error) {
|
|
strncpy(error, error_, sizeof(error));
|
|
error[sizeof(error) - 1] = '\0';
|
|
}
|
|
}
|
|
|
|
log_err(_("Command failed with code %i"), -errcode);
|
|
if (*error)
|
|
log_err(": %s\n", error);
|
|
else
|
|
log_err(".\n");
|
|
}
|
|
|
|
const char *uuid_or_device(const char *spec)
|
|
{
|
|
static char device[PATH_MAX];
|
|
char s, *ptr;
|
|
int i = 0, uuid_len = 5;
|
|
|
|
/* Check if it is correct UUID=<LUKS_UUID> format */
|
|
if (spec && !strncmp(spec, "UUID=", uuid_len)) {
|
|
strcpy(device, "/dev/disk/by-uuid/");
|
|
ptr = &device[strlen(device)];
|
|
i = uuid_len;
|
|
while ((s = spec[i++]) && i < PATH_MAX) {
|
|
if (!isxdigit(s) && s != '-')
|
|
return spec; /* Bail it out */
|
|
if (isalpha(s))
|
|
s = tolower(s);
|
|
*ptr++ = s;
|
|
}
|
|
*ptr = '\0';
|
|
return device;
|
|
}
|
|
|
|
return spec;
|
|
}
|
|
|
|
__attribute__ ((noreturn)) void usage(poptContext popt_context,
|
|
int exitcode, const char *error,
|
|
const char *more)
|
|
{
|
|
poptPrintUsage(popt_context, stderr, 0);
|
|
if (error)
|
|
log_err("%s: %s\n", more, error);
|
|
poptFreeContext(popt_context);
|
|
exit(exitcode);
|
|
}
|
|
|
|
void dbg_version_and_cmd(int argc, const char **argv)
|
|
{
|
|
int i;
|
|
|
|
log_std("# %s %s processing \"", PACKAGE_NAME, PACKAGE_VERSION);
|
|
for (i = 0; i < argc; i++) {
|
|
if (i)
|
|
log_std(" ");
|
|
log_std("%s", argv[i]);
|
|
}
|
|
log_std("\"\n");
|
|
}
|
|
|
|
/* Translate exit code to simple codes */
|
|
int translate_errno(int r)
|
|
{
|
|
switch (r) {
|
|
case 0: r = EXIT_SUCCESS; break;
|
|
case -EEXIST:
|
|
case -EBUSY: r = 5; break;
|
|
case -ENOTBLK:
|
|
case -ENODEV: r = 4; break;
|
|
case -ENOMEM: r = 3; break;
|
|
case -EPERM: r = 2; break;
|
|
case -EINVAL:
|
|
case -ENOENT:
|
|
case -ENOSYS:
|
|
default: r = EXIT_FAILURE;
|
|
}
|
|
return r;
|
|
}
|