/* * cryptsetup - setup cryptographic volumes for dm-crypt * * Copyright (C) 2004, Christophe Saout * Copyright (C) 2004-2007, Clemens Fruhwirth * 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= 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; }