export.c revision ce30c8dcb41dfe9264f79f30c7f51c0e74576638
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye/***
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye This file is part of systemd.
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye Copyright 2015 Lennart Poettering
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye systemd is free software; you can redistribute it and/or modify it
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye under the terms of the GNU Lesser General Public License as published by
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye the Free Software Foundation; either version 2.1 of the License, or
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye (at your option) any later version.
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye systemd is distributed in the hope that it will be useful, but
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye WITHOUT ANY WARRANTY; without even the implied warranty of
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye Lesser General Public License for more details.
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye You should have received a copy of the GNU Lesser General Public License
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye along with systemd; If not, see <http://www.gnu.org/licenses/>.
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye***/
fe80b749cd764b1f0f72b2f913b1fe10581911c3Knut Anders Hatlen
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye#include <getopt.h>
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye
cf1f7b5e81583dfca30972cfef322266a6928e7fKnut Anders Hatlen#include "sd-event.h"
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye#include "event-util.h"
d4ce228a333ba2daa19ad8b0672a704c8e42a2dcTrond Norbye#include "signal-util.h"
d4ce228a333ba2daa19ad8b0672a704c8e42a2dcTrond Norbye#include "verbs.h"
6d7c6f82e644c205bc679ee5b1fa2929ec949963Lubos Kosco#include "build.h"
7e33e87b7d6c9a61ff11d23e37c02274b1223ce1Jens Elkner#include "machine-image.h"
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye#include "import-util.h"
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye#include "export-tar.h"
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye#include "export-raw.h"
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye
64b763950bf11e9357facbd2b5666631a895c085Trond Norbyestatic ImportCompressType arg_compress = IMPORT_COMPRESS_UNKNOWN;
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye
64b763950bf11e9357facbd2b5666631a895c085Trond Norbyestatic void determine_compression_from_filename(const char *p) {
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye if (arg_compress != IMPORT_COMPRESS_UNKNOWN)
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye return;
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye if (!p) {
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye arg_compress = IMPORT_COMPRESS_UNCOMPRESSED;
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye return;
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye }
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye if (endswith(p, ".xz"))
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye arg_compress = IMPORT_COMPRESS_XZ;
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye else if (endswith(p, ".gz"))
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye arg_compress = IMPORT_COMPRESS_GZIP;
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye else if (endswith(p, ".bz2"))
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye arg_compress = IMPORT_COMPRESS_BZIP2;
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye else
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye arg_compress = IMPORT_COMPRESS_UNCOMPRESSED;
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye}
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye
64b763950bf11e9357facbd2b5666631a895c085Trond Norbyestatic int interrupt_signal_handler(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) {
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye log_notice("Transfer aborted.");
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye sd_event_exit(sd_event_source_get_event(s), EINTR);
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye return 0;
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye}
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye
64b763950bf11e9357facbd2b5666631a895c085Trond Norbyestatic void on_tar_finished(TarExport *export, int error, void *userdata) {
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye sd_event *event = userdata;
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye assert(export);
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye if (error == 0)
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye log_info("Operation completed successfully.");
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye sd_event_exit(event, abs(error));
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye}
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye
64b763950bf11e9357facbd2b5666631a895c085Trond Norbyestatic int export_tar(int argc, char *argv[], void *userdata) {
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye _cleanup_(tar_export_unrefp) TarExport *export = NULL;
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye _cleanup_event_unref_ sd_event *event = NULL;
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye _cleanup_(image_unrefp) Image *image = NULL;
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye const char *path = NULL, *local = NULL;
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye _cleanup_close_ int open_fd = -1;
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye int r, fd;
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye if (machine_name_is_valid(argv[1])) {
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye r = image_find(argv[1], &image);
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye if (r < 0)
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye return log_error_errno(r, "Failed to look for machine %s: %m", argv[1]);
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye if (r == 0) {
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye log_error("Machine image %s not found.", argv[1]);
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye return -ENOENT;
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye }
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye local = image->path;
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye } else
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye local = argv[1];
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye
0a0811923cbbd2976425db6f4c78eed811c2825bKnut Anders Hatlen if (argc >= 3)
6d7c6f82e644c205bc679ee5b1fa2929ec949963Lubos Kosco path = argv[2];
a07b2874263e3c5f0cd2e83441719415d53059c2Knut Anders Hatlen if (isempty(path) || streq(path, "-"))
7e33e87b7d6c9a61ff11d23e37c02274b1223ce1Jens Elkner path = NULL;
7e33e87b7d6c9a61ff11d23e37c02274b1223ce1Jens Elkner
c7eb123c8b2081a261deff3c401fbf92ddba1b58Jorgen Austvik determine_compression_from_filename(path);
c7eb123c8b2081a261deff3c401fbf92ddba1b58Jorgen Austvik
49f592091468eac515dde6139fbc8efa26056b0aJorgen Austvik if (path) {
945f4c3c36a15447913781dfb1894b34f2941c57Jorgen Austvik open_fd = open(path, O_WRONLY|O_CREAT|O_TRUNC|O_CLOEXEC|O_NOCTTY, 0666);
5a0c5ad4116f5a4dd0dd5a0a4e6d02973cd5eef9Lubos Kosco if (open_fd < 0)
780cc7d1b57609ff15fb283201e93cb501ebe9e6Jorgen Austvik return log_error_errno(errno, "Failed to open tar image for export: %m");
780cc7d1b57609ff15fb283201e93cb501ebe9e6Jorgen Austvik
780cc7d1b57609ff15fb283201e93cb501ebe9e6Jorgen Austvik fd = open_fd;
d3d2404f9a49bf70b124053feabe666f85ef5361Knut Anders Hatlen
d3d2404f9a49bf70b124053feabe666f85ef5361Knut Anders Hatlen log_info("Exporting '%s', saving to '%s' with compression '%s'.", local, path, import_compress_type_to_string(arg_compress));
780cc7d1b57609ff15fb283201e93cb501ebe9e6Jorgen Austvik } else {
780cc7d1b57609ff15fb283201e93cb501ebe9e6Jorgen Austvik _cleanup_free_ char *pretty = NULL;
7b9f9a1761f76744fc3772181877d5e301f122adKnut Anders Hatlen
5a0c5ad4116f5a4dd0dd5a0a4e6d02973cd5eef9Lubos Kosco fd = STDOUT_FILENO;
0466de7c67573e1ce5e0733325c1e5383270f5d5Knut Anders Hatlen
0466de7c67573e1ce5e0733325c1e5383270f5d5Knut Anders Hatlen (void) readlink_malloc("/proc/self/fd/1", &pretty);
0466de7c67573e1ce5e0733325c1e5383270f5d5Knut Anders Hatlen log_info("Exporting '%s', saving to '%s' with compression '%s'.", local, strna(pretty), import_compress_type_to_string(arg_compress));
d4ce228a333ba2daa19ad8b0672a704c8e42a2dcTrond Norbye }
d4ce228a333ba2daa19ad8b0672a704c8e42a2dcTrond Norbye
5a0c5ad4116f5a4dd0dd5a0a4e6d02973cd5eef9Lubos Kosco r = sd_event_default(&event);
5a0c5ad4116f5a4dd0dd5a0a4e6d02973cd5eef9Lubos Kosco if (r < 0)
1ed6b730409d4740e941142599767d5eac7e7d92Lubos Kosco return log_error_errno(r, "Failed to allocate event loop: %m");
7ecd52b03dc1f0b03ff8f522b4891c8531896c3dJorgen Austvik
7ecd52b03dc1f0b03ff8f522b4891c8531896c3dJorgen Austvik assert_se(sigprocmask_many(SIG_BLOCK, SIGTERM, SIGINT, -1) == 0);
7ecd52b03dc1f0b03ff8f522b4891c8531896c3dJorgen Austvik sd_event_add_signal(event, NULL, SIGTERM, interrupt_signal_handler, NULL);
d4ce228a333ba2daa19ad8b0672a704c8e42a2dcTrond Norbye sd_event_add_signal(event, NULL, SIGINT, interrupt_signal_handler, NULL);
d4ce228a333ba2daa19ad8b0672a704c8e42a2dcTrond Norbye
7ecd52b03dc1f0b03ff8f522b4891c8531896c3dJorgen Austvik r = tar_export_new(&export, event, on_tar_finished, event);
7ecd52b03dc1f0b03ff8f522b4891c8531896c3dJorgen Austvik if (r < 0)
7ecd52b03dc1f0b03ff8f522b4891c8531896c3dJorgen Austvik return log_error_errno(r, "Failed to allocate exporter: %m");
c7eb123c8b2081a261deff3c401fbf92ddba1b58Jorgen Austvik
5a0c5ad4116f5a4dd0dd5a0a4e6d02973cd5eef9Lubos Kosco r = tar_export_start(export, local, fd, arg_compress);
7ecd52b03dc1f0b03ff8f522b4891c8531896c3dJorgen Austvik if (r < 0)
7ecd52b03dc1f0b03ff8f522b4891c8531896c3dJorgen Austvik return log_error_errno(r, "Failed to export image: %m");
7ecd52b03dc1f0b03ff8f522b4891c8531896c3dJorgen Austvik
49f592091468eac515dde6139fbc8efa26056b0aJorgen Austvik r = sd_event_loop(event);
49f592091468eac515dde6139fbc8efa26056b0aJorgen Austvik if (r < 0)
5a0c5ad4116f5a4dd0dd5a0a4e6d02973cd5eef9Lubos Kosco return log_error_errno(r, "Failed to run event loop: %m");
49f592091468eac515dde6139fbc8efa26056b0aJorgen Austvik
49f592091468eac515dde6139fbc8efa26056b0aJorgen Austvik log_info("Exiting.");
945f4c3c36a15447913781dfb1894b34f2941c57Jorgen Austvik return -r;
945f4c3c36a15447913781dfb1894b34f2941c57Jorgen Austvik}
5a0c5ad4116f5a4dd0dd5a0a4e6d02973cd5eef9Lubos Kosco
945f4c3c36a15447913781dfb1894b34f2941c57Jorgen Austvikstatic void on_raw_finished(RawExport *export, int error, void *userdata) {
945f4c3c36a15447913781dfb1894b34f2941c57Jorgen Austvik sd_event *event = userdata;
945f4c3c36a15447913781dfb1894b34f2941c57Jorgen Austvik assert(export);
1ed6b730409d4740e941142599767d5eac7e7d92Lubos Kosco
7ecd52b03dc1f0b03ff8f522b4891c8531896c3dJorgen Austvik if (error == 0)
1ed6b730409d4740e941142599767d5eac7e7d92Lubos Kosco log_info("Operation completed successfully.");
7ecd52b03dc1f0b03ff8f522b4891c8531896c3dJorgen Austvik
4d93e73b35c5009898b59c9bd7e6629ac5942c2cLubos Kosco sd_event_exit(event, abs(error));
4d93e73b35c5009898b59c9bd7e6629ac5942c2cLubos Kosco}
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye
b34561d2c3d92fac37dbced05ba6a8738e3d20e9Lubos Koscostatic int export_raw(int argc, char *argv[], void *userdata) {
d4ce228a333ba2daa19ad8b0672a704c8e42a2dcTrond Norbye _cleanup_(raw_export_unrefp) RawExport *export = NULL;
b34561d2c3d92fac37dbced05ba6a8738e3d20e9Lubos Kosco _cleanup_event_unref_ sd_event *event = NULL;
b34561d2c3d92fac37dbced05ba6a8738e3d20e9Lubos Kosco _cleanup_(image_unrefp) Image *image = NULL;
b34561d2c3d92fac37dbced05ba6a8738e3d20e9Lubos Kosco const char *path = NULL, *local = NULL;
b34561d2c3d92fac37dbced05ba6a8738e3d20e9Lubos Kosco _cleanup_close_ int open_fd = -1;
b34561d2c3d92fac37dbced05ba6a8738e3d20e9Lubos Kosco int r, fd;
b34561d2c3d92fac37dbced05ba6a8738e3d20e9Lubos Kosco
b34561d2c3d92fac37dbced05ba6a8738e3d20e9Lubos Kosco if (machine_name_is_valid(argv[1])) {
b34561d2c3d92fac37dbced05ba6a8738e3d20e9Lubos Kosco r = image_find(argv[1], &image);
ecc9697029dc3bde02537b914756f7c49eb7cd1eLubos Kosco if (r < 0)
ecc9697029dc3bde02537b914756f7c49eb7cd1eLubos Kosco return log_error_errno(r, "Failed to look for machine %s: %m", argv[1]);
45909b3ef8c6e568a87482cb890fec7b5dbb7733Lubos Kosco if (r == 0) {
45909b3ef8c6e568a87482cb890fec7b5dbb7733Lubos Kosco log_error("Machine image %s not found.", argv[1]);
fcb68bae47907ba23c545e379c81c3ee6e19f778Lubos Kosco return -ENOENT;
fcb68bae47907ba23c545e379c81c3ee6e19f778Lubos Kosco }
d4ce228a333ba2daa19ad8b0672a704c8e42a2dcTrond Norbye
d4ce228a333ba2daa19ad8b0672a704c8e42a2dcTrond Norbye local = image->path;
b34561d2c3d92fac37dbced05ba6a8738e3d20e9Lubos Kosco } else
b34561d2c3d92fac37dbced05ba6a8738e3d20e9Lubos Kosco local = argv[1];
b34561d2c3d92fac37dbced05ba6a8738e3d20e9Lubos Kosco
b34561d2c3d92fac37dbced05ba6a8738e3d20e9Lubos Kosco if (argc >= 3)
b34561d2c3d92fac37dbced05ba6a8738e3d20e9Lubos Kosco path = argv[2];
b34561d2c3d92fac37dbced05ba6a8738e3d20e9Lubos Kosco if (isempty(path) || streq(path, "-"))
b34561d2c3d92fac37dbced05ba6a8738e3d20e9Lubos Kosco path = NULL;
b34561d2c3d92fac37dbced05ba6a8738e3d20e9Lubos Kosco
b34561d2c3d92fac37dbced05ba6a8738e3d20e9Lubos Kosco determine_compression_from_filename(path);
b34561d2c3d92fac37dbced05ba6a8738e3d20e9Lubos Kosco
b34561d2c3d92fac37dbced05ba6a8738e3d20e9Lubos Kosco if (path) {
b34561d2c3d92fac37dbced05ba6a8738e3d20e9Lubos Kosco open_fd = open(path, O_WRONLY|O_CREAT|O_TRUNC|O_CLOEXEC|O_NOCTTY, 0666);
b34561d2c3d92fac37dbced05ba6a8738e3d20e9Lubos Kosco if (open_fd < 0)
e3bec3188dc818cc194cd67e6871c6d0af0d6b26Felix Annan return log_error_errno(errno, "Failed to open raw image for export: %m");
e3bec3188dc818cc194cd67e6871c6d0af0d6b26Felix Annan
d7375a57cb329e3ca4984fc3b2923b177ddff562haufelex fd = open_fd;
d7375a57cb329e3ca4984fc3b2923b177ddff562haufelex
b34561d2c3d92fac37dbced05ba6a8738e3d20e9Lubos Kosco log_info("Exporting '%s', saving to '%s' with compression '%s'.", local, path, import_compress_type_to_string(arg_compress));
b34561d2c3d92fac37dbced05ba6a8738e3d20e9Lubos Kosco } else {
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye _cleanup_free_ char *pretty = NULL;
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye
7b046969a1b2565787df8ae3a8126359e8cd6fafTrond Norbye fd = STDOUT_FILENO;
a5cc1506d5c0704805c6733a46c7f1f8f91ae724Knut Anders Hatlen
a5cc1506d5c0704805c6733a46c7f1f8f91ae724Knut Anders Hatlen (void) readlink_malloc("/proc/self/fd/1", &pretty);
a5cc1506d5c0704805c6733a46c7f1f8f91ae724Knut Anders Hatlen log_info("Exporting '%s', saving to '%s' with compression '%s'.", local, strna(pretty), import_compress_type_to_string(arg_compress));
a5cc1506d5c0704805c6733a46c7f1f8f91ae724Knut Anders Hatlen }
a5cc1506d5c0704805c6733a46c7f1f8f91ae724Knut Anders Hatlen
a5cc1506d5c0704805c6733a46c7f1f8f91ae724Knut Anders Hatlen r = sd_event_default(&event);
7b046969a1b2565787df8ae3a8126359e8cd6fafTrond Norbye if (r < 0)
7b046969a1b2565787df8ae3a8126359e8cd6fafTrond Norbye return log_error_errno(r, "Failed to allocate event loop: %m");
7b046969a1b2565787df8ae3a8126359e8cd6fafTrond Norbye
3d35131df8607ae05b064219b9448afc5c4b550aKnut Anders Hatlen assert_se(sigprocmask_many(SIG_BLOCK, SIGTERM, SIGINT, -1) == 0);
3d35131df8607ae05b064219b9448afc5c4b550aKnut Anders Hatlen sd_event_add_signal(event, NULL, SIGTERM, interrupt_signal_handler, NULL);
7b046969a1b2565787df8ae3a8126359e8cd6fafTrond Norbye sd_event_add_signal(event, NULL, SIGINT, interrupt_signal_handler, NULL);
7b046969a1b2565787df8ae3a8126359e8cd6fafTrond Norbye
7b046969a1b2565787df8ae3a8126359e8cd6fafTrond Norbye r = raw_export_new(&export, event, on_raw_finished, event);
a5cc1506d5c0704805c6733a46c7f1f8f91ae724Knut Anders Hatlen if (r < 0)
a5cc1506d5c0704805c6733a46c7f1f8f91ae724Knut Anders Hatlen return log_error_errno(r, "Failed to allocate exporter: %m");
a5cc1506d5c0704805c6733a46c7f1f8f91ae724Knut Anders Hatlen
a5cc1506d5c0704805c6733a46c7f1f8f91ae724Knut Anders Hatlen r = raw_export_start(export, local, fd, arg_compress);
d4ce228a333ba2daa19ad8b0672a704c8e42a2dcTrond Norbye if (r < 0)
a5cc1506d5c0704805c6733a46c7f1f8f91ae724Knut Anders Hatlen return log_error_errno(r, "Failed to export image: %m");
a5cc1506d5c0704805c6733a46c7f1f8f91ae724Knut Anders Hatlen
a5cc1506d5c0704805c6733a46c7f1f8f91ae724Knut Anders Hatlen r = sd_event_loop(event);
a5cc1506d5c0704805c6733a46c7f1f8f91ae724Knut Anders Hatlen if (r < 0)
a5cc1506d5c0704805c6733a46c7f1f8f91ae724Knut Anders Hatlen return log_error_errno(r, "Failed to run event loop: %m");
a5cc1506d5c0704805c6733a46c7f1f8f91ae724Knut Anders Hatlen
a5cc1506d5c0704805c6733a46c7f1f8f91ae724Knut Anders Hatlen log_info("Exiting.");
a5cc1506d5c0704805c6733a46c7f1f8f91ae724Knut Anders Hatlen return -r;
a5cc1506d5c0704805c6733a46c7f1f8f91ae724Knut Anders Hatlen}
d4ce228a333ba2daa19ad8b0672a704c8e42a2dcTrond Norbye
d4ce228a333ba2daa19ad8b0672a704c8e42a2dcTrond Norbyestatic int help(int argc, char *argv[], void *userdata) {
d4ce228a333ba2daa19ad8b0672a704c8e42a2dcTrond Norbye
a5cc1506d5c0704805c6733a46c7f1f8f91ae724Knut Anders Hatlen printf("%s [OPTIONS...] {COMMAND} ...\n\n"
a5cc1506d5c0704805c6733a46c7f1f8f91ae724Knut Anders Hatlen "Export container or virtual machine images.\n\n"
d4ce228a333ba2daa19ad8b0672a704c8e42a2dcTrond Norbye " -h --help Show this help\n"
a5cc1506d5c0704805c6733a46c7f1f8f91ae724Knut Anders Hatlen " --version Show package version\n"
a5cc1506d5c0704805c6733a46c7f1f8f91ae724Knut Anders Hatlen " --format=FORMAT Select format\n\n"
a5cc1506d5c0704805c6733a46c7f1f8f91ae724Knut Anders Hatlen "Commands:\n"
a5cc1506d5c0704805c6733a46c7f1f8f91ae724Knut Anders Hatlen " tar NAME [FILE] Export a TAR image\n"
7b046969a1b2565787df8ae3a8126359e8cd6fafTrond Norbye " raw NAME [FILE] Export a RAW image\n",
7b046969a1b2565787df8ae3a8126359e8cd6fafTrond Norbye program_invocation_short_name);
7b046969a1b2565787df8ae3a8126359e8cd6fafTrond Norbye
7b046969a1b2565787df8ae3a8126359e8cd6fafTrond Norbye return 0;
7b046969a1b2565787df8ae3a8126359e8cd6fafTrond Norbye}
7b046969a1b2565787df8ae3a8126359e8cd6fafTrond Norbye
7b046969a1b2565787df8ae3a8126359e8cd6fafTrond Norbyestatic int parse_argv(int argc, char *argv[]) {
7b046969a1b2565787df8ae3a8126359e8cd6fafTrond Norbye
2e3c025fdd5908a27cc82eb1d5346368a8be4e0dJorgen Austvik enum {
6d7c6f82e644c205bc679ee5b1fa2929ec949963Lubos Kosco ARG_VERSION = 0x100,
81a83bbf0a20e99b5b27be2bcc34c5dbb703c898jel+opengrok ARG_FORMAT,
81a83bbf0a20e99b5b27be2bcc34c5dbb703c898jel+opengrok };
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye
b34561d2c3d92fac37dbced05ba6a8738e3d20e9Lubos Kosco static const struct option options[] = {
2dbc1835e0ae88ad102e2b9a85e5c7b5298b14b6Knut Anders Hatlen { "help", no_argument, NULL, 'h' },
2e3c025fdd5908a27cc82eb1d5346368a8be4e0dJorgen Austvik { "version", no_argument, NULL, ARG_VERSION },
d3d2404f9a49bf70b124053feabe666f85ef5361Knut Anders Hatlen { "format", required_argument, NULL, ARG_FORMAT },
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye {}
6d7c6f82e644c205bc679ee5b1fa2929ec949963Lubos Kosco };
6d7c6f82e644c205bc679ee5b1fa2929ec949963Lubos Kosco
6d7c6f82e644c205bc679ee5b1fa2929ec949963Lubos Kosco int c;
6d7c6f82e644c205bc679ee5b1fa2929ec949963Lubos Kosco
6d7c6f82e644c205bc679ee5b1fa2929ec949963Lubos Kosco assert(argc >= 0);
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye assert(argv);
9cf297d9a579835e9336d587eaee187ca0954767Knut Anders Hatlen
2dbc1835e0ae88ad102e2b9a85e5c7b5298b14b6Knut Anders Hatlen while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0)
2dbc1835e0ae88ad102e2b9a85e5c7b5298b14b6Knut Anders Hatlen
9cf297d9a579835e9336d587eaee187ca0954767Knut Anders Hatlen switch (c) {
2dbc1835e0ae88ad102e2b9a85e5c7b5298b14b6Knut Anders Hatlen
2dbc1835e0ae88ad102e2b9a85e5c7b5298b14b6Knut Anders Hatlen case 'h':
d4ce228a333ba2daa19ad8b0672a704c8e42a2dcTrond Norbye return help(0, NULL, NULL);
2dbc1835e0ae88ad102e2b9a85e5c7b5298b14b6Knut Anders Hatlen
2dbc1835e0ae88ad102e2b9a85e5c7b5298b14b6Knut Anders Hatlen case ARG_VERSION:
5a0c5ad4116f5a4dd0dd5a0a4e6d02973cd5eef9Lubos Kosco puts(PACKAGE_STRING);
2dbc1835e0ae88ad102e2b9a85e5c7b5298b14b6Knut Anders Hatlen puts(SYSTEMD_FEATURES);
2dbc1835e0ae88ad102e2b9a85e5c7b5298b14b6Knut Anders Hatlen return 0;
2dbc1835e0ae88ad102e2b9a85e5c7b5298b14b6Knut Anders Hatlen
2dbc1835e0ae88ad102e2b9a85e5c7b5298b14b6Knut Anders Hatlen case ARG_FORMAT:
2dbc1835e0ae88ad102e2b9a85e5c7b5298b14b6Knut Anders Hatlen if (streq(optarg, "uncompressed"))
2dbc1835e0ae88ad102e2b9a85e5c7b5298b14b6Knut Anders Hatlen arg_compress = IMPORT_COMPRESS_UNCOMPRESSED;
d4ce228a333ba2daa19ad8b0672a704c8e42a2dcTrond Norbye else if (streq(optarg, "xz"))
d4ce228a333ba2daa19ad8b0672a704c8e42a2dcTrond Norbye arg_compress = IMPORT_COMPRESS_XZ;
d4ce228a333ba2daa19ad8b0672a704c8e42a2dcTrond Norbye else if (streq(optarg, "gzip"))
d4ce228a333ba2daa19ad8b0672a704c8e42a2dcTrond Norbye arg_compress = IMPORT_COMPRESS_GZIP;
d4ce228a333ba2daa19ad8b0672a704c8e42a2dcTrond Norbye else if (streq(optarg, "bzip2"))
d4ce228a333ba2daa19ad8b0672a704c8e42a2dcTrond Norbye arg_compress = IMPORT_COMPRESS_BZIP2;
d4ce228a333ba2daa19ad8b0672a704c8e42a2dcTrond Norbye else {
81a83bbf0a20e99b5b27be2bcc34c5dbb703c898jel+opengrok log_error("Unknown format: %s", optarg);
81a83bbf0a20e99b5b27be2bcc34c5dbb703c898jel+opengrok return -EINVAL;
2dbc1835e0ae88ad102e2b9a85e5c7b5298b14b6Knut Anders Hatlen }
2dbc1835e0ae88ad102e2b9a85e5c7b5298b14b6Knut Anders Hatlen break;
2dbc1835e0ae88ad102e2b9a85e5c7b5298b14b6Knut Anders Hatlen
2dbc1835e0ae88ad102e2b9a85e5c7b5298b14b6Knut Anders Hatlen case '?':
d4ce228a333ba2daa19ad8b0672a704c8e42a2dcTrond Norbye return -EINVAL;
d4ce228a333ba2daa19ad8b0672a704c8e42a2dcTrond Norbye
752fbd3cf33aada419c8258959ff5574d2d2047dTrond Norbye default:
d4ce228a333ba2daa19ad8b0672a704c8e42a2dcTrond Norbye assert_not_reached("Unhandled option");
2dbc1835e0ae88ad102e2b9a85e5c7b5298b14b6Knut Anders Hatlen }
2dbc1835e0ae88ad102e2b9a85e5c7b5298b14b6Knut Anders Hatlen
7b046969a1b2565787df8ae3a8126359e8cd6fafTrond Norbye return 1;
2dbc1835e0ae88ad102e2b9a85e5c7b5298b14b6Knut Anders Hatlen}
2dbc1835e0ae88ad102e2b9a85e5c7b5298b14b6Knut Anders Hatlen
2dbc1835e0ae88ad102e2b9a85e5c7b5298b14b6Knut Anders Hatlenstatic int export_main(int argc, char *argv[]) {
2dbc1835e0ae88ad102e2b9a85e5c7b5298b14b6Knut Anders Hatlen
2dbc1835e0ae88ad102e2b9a85e5c7b5298b14b6Knut Anders Hatlen static const Verb verbs[] = {
2dbc1835e0ae88ad102e2b9a85e5c7b5298b14b6Knut Anders Hatlen { "help", VERB_ANY, VERB_ANY, 0, help },
2dbc1835e0ae88ad102e2b9a85e5c7b5298b14b6Knut Anders Hatlen { "tar", 2, 3, 0, export_tar },
d4ce228a333ba2daa19ad8b0672a704c8e42a2dcTrond Norbye { "raw", 2, 3, 0, export_raw },
d4ce228a333ba2daa19ad8b0672a704c8e42a2dcTrond Norbye {}
d4ce228a333ba2daa19ad8b0672a704c8e42a2dcTrond Norbye };
d4ce228a333ba2daa19ad8b0672a704c8e42a2dcTrond Norbye
d4ce228a333ba2daa19ad8b0672a704c8e42a2dcTrond Norbye return dispatch_verb(argc, argv, verbs, NULL);
d4ce228a333ba2daa19ad8b0672a704c8e42a2dcTrond Norbye}
9cf297d9a579835e9336d587eaee187ca0954767Knut Anders Hatlen
6d7c6f82e644c205bc679ee5b1fa2929ec949963Lubos Koscoint main(int argc, char *argv[]) {
6d7c6f82e644c205bc679ee5b1fa2929ec949963Lubos Kosco int r;
6d7c6f82e644c205bc679ee5b1fa2929ec949963Lubos Kosco
6d7c6f82e644c205bc679ee5b1fa2929ec949963Lubos Kosco setlocale(LC_ALL, "");
6d7c6f82e644c205bc679ee5b1fa2929ec949963Lubos Kosco log_parse_environment();
6d7c6f82e644c205bc679ee5b1fa2929ec949963Lubos Kosco log_open();
6d7c6f82e644c205bc679ee5b1fa2929ec949963Lubos Kosco
6d7c6f82e644c205bc679ee5b1fa2929ec949963Lubos Kosco r = parse_argv(argc, argv);
6d7c6f82e644c205bc679ee5b1fa2929ec949963Lubos Kosco if (r <= 0)
6d7c6f82e644c205bc679ee5b1fa2929ec949963Lubos Kosco goto finish;
6d7c6f82e644c205bc679ee5b1fa2929ec949963Lubos Kosco
6d7c6f82e644c205bc679ee5b1fa2929ec949963Lubos Kosco (void) ignore_signals(SIGPIPE, -1);
6d7c6f82e644c205bc679ee5b1fa2929ec949963Lubos Kosco
6d7c6f82e644c205bc679ee5b1fa2929ec949963Lubos Kosco r = export_main(argc, argv);
6d7c6f82e644c205bc679ee5b1fa2929ec949963Lubos Kosco
6d7c6f82e644c205bc679ee5b1fa2929ec949963Lubos Koscofinish:
6d7c6f82e644c205bc679ee5b1fa2929ec949963Lubos Kosco return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
6d7c6f82e644c205bc679ee5b1fa2929ec949963Lubos Kosco}
6d7c6f82e644c205bc679ee5b1fa2929ec949963Lubos Kosco