mirror of
https://github.com/libguestfs/libguestfs.git
synced 2026-03-21 22:53:37 +00:00
This command run over the source: perl -pi.bak -e 's/(20[01][0-9])-2018/$1-2019/g' `git ls-files`
187 lines
5.0 KiB
C
187 lines
5.0 KiB
C
/* guestfish - guest filesystem shell
|
||
* Copyright (C) 2010-2019 Red Hat Inc.
|
||
*
|
||
* This program is free software; you can redistribute it and/or modify
|
||
* it under the terms of the GNU General Public License as published by
|
||
* the Free Software Foundation; either version 2 of the License, or
|
||
* (at your option) any later version.
|
||
*
|
||
* 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.
|
||
*/
|
||
|
||
/**
|
||
* This file implements the guestfish I<-N> option for creating
|
||
* pre-prepared disk layouts.
|
||
*/
|
||
|
||
#include <config.h>
|
||
|
||
#include <stdio.h>
|
||
#include <stdlib.h>
|
||
#include <stdarg.h>
|
||
#include <string.h>
|
||
#include <unistd.h>
|
||
#include <errno.h>
|
||
#include <error.h>
|
||
#include <libintl.h>
|
||
|
||
#include "fish.h"
|
||
#include "prepopts.h"
|
||
|
||
static prep_data *parse_type_string (const char *type_string);
|
||
|
||
void
|
||
list_prepared_drives (void)
|
||
{
|
||
size_t i, j;
|
||
|
||
printf (_("List of available prepared disk images:\n\n"));
|
||
|
||
for (i = 0; i < NR_PREPS; ++i) {
|
||
printf (_("\
|
||
guestfish -N %-8s - %s\n\
|
||
\n\
|
||
%s\n"),
|
||
preps[i].name, preps[i].shortdesc, preps[i].longdesc);
|
||
|
||
if (preps[i].nr_params > 0) {
|
||
printf ("\n");
|
||
printf (_(" Optional parameters:\n"));
|
||
printf (" -N %s", preps[i].name);
|
||
for (j = 0; j < preps[i].nr_params; ++j)
|
||
printf (":<%s>", preps[i].params[j].pname);
|
||
printf ("\n");
|
||
for (j = 0; j < preps[i].nr_params; ++j) {
|
||
printf (" ");
|
||
printf (_("<%s> %s (default: %s)\n"),
|
||
preps[i].params[j].pname,
|
||
preps[i].params[j].pdesc,
|
||
preps[i].params[j].pdefault);
|
||
}
|
||
}
|
||
|
||
printf ("\n");
|
||
}
|
||
|
||
printf (_("\
|
||
Prepared disk images are written to file \"test1.img\" in the local\n\
|
||
directory. (\"test2.img\" etc if -N option is given multiple times).\n\
|
||
You can override the name by providing a filename before the type, eg:\n\
|
||
\n\
|
||
guestfish -N blank.img=fs\n\
|
||
\n\
|
||
For more information see the guestfish(1) manual.\n"));
|
||
}
|
||
|
||
/* Parse the type string (from the command line) and create the output
|
||
* file 'filename'. This is called before launch. Return the opaque
|
||
* prep_data which will be passed back to us in prepare_drive below.
|
||
*/
|
||
prep_data *
|
||
create_prepared_file (const char *type_string, const char *filename)
|
||
{
|
||
prep_data *data = parse_type_string (type_string);
|
||
if (data->prep->prelaunch)
|
||
data->prep->prelaunch (filename, data);
|
||
return data;
|
||
}
|
||
|
||
static prep_data *
|
||
parse_type_string (const char *type_string)
|
||
{
|
||
size_t i;
|
||
|
||
/* Match on the type part (without parameters). */
|
||
size_t len = strcspn (type_string, ":");
|
||
for (i = 0; i < NR_PREPS; ++i)
|
||
if (STRCASEEQLEN (type_string, preps[i].name, len))
|
||
break;
|
||
|
||
if (i == NR_PREPS)
|
||
error (EXIT_FAILURE, 0,
|
||
_("-N parameter ‘%s’: no such prepared disk image known.\n"
|
||
"Use 'guestfish -N help' to list possible values for the -N parameter."),
|
||
type_string);
|
||
|
||
prep_data *data = malloc (sizeof *data);
|
||
if (data == NULL)
|
||
error (EXIT_FAILURE, errno, "malloc");
|
||
data->prep = &preps[i];
|
||
data->orig_type_string = type_string;
|
||
|
||
/* Set up the optional parameters to all-defaults. */
|
||
data->params = malloc (data->prep->nr_params * sizeof (char *));
|
||
if (data->params == NULL)
|
||
error (EXIT_FAILURE, errno, "malloc");
|
||
|
||
for (i = 0; i < data->prep->nr_params; ++i)
|
||
data->params[i] = (char *) data->prep->params[i].pdefault;
|
||
|
||
/* Parse the optional parameters. */
|
||
const char *p = type_string + len;
|
||
if (*p) p++; /* skip colon char */
|
||
|
||
i = 0;
|
||
while (*p) {
|
||
len = strcspn (p, ":");
|
||
data->params[i] = strndup (p, len);
|
||
if (data->params[i] == NULL)
|
||
error (EXIT_FAILURE, errno, "strndup");
|
||
|
||
p += len;
|
||
if (*p) p++; /* skip colon char */
|
||
i++;
|
||
}
|
||
|
||
return data;
|
||
}
|
||
|
||
/* Prepare a drive. The appliance has been launched, and 'device' is
|
||
* the libguestfs device. 'data' is the requested type. 'filename'
|
||
* is just used for error messages.
|
||
*/
|
||
void
|
||
prepare_drive (const char *filename, prep_data *data,
|
||
const char *device)
|
||
{
|
||
if (data->prep->postlaunch)
|
||
data->prep->postlaunch (filename, data, device);
|
||
}
|
||
|
||
void
|
||
prep_error (prep_data *data, const char *filename, const char *fs, ...)
|
||
{
|
||
fprintf (stderr,
|
||
_("guestfish: error creating prepared disk image ‘%s’ on ‘%s’: "),
|
||
data->orig_type_string, filename);
|
||
|
||
va_list args;
|
||
va_start (args, fs);
|
||
vfprintf (stderr, fs, args);
|
||
va_end (args);
|
||
|
||
fprintf (stderr, "\n");
|
||
|
||
exit (EXIT_FAILURE);
|
||
}
|
||
|
||
void
|
||
free_prep_data (void *vp)
|
||
{
|
||
prep_data *data = vp;
|
||
size_t i;
|
||
|
||
for (i = 0; i < data->prep->nr_params; ++i)
|
||
if (data->params[i] != data->prep->params[i].pdefault)
|
||
free (data->params[i]);
|
||
free (data->params);
|
||
free (data);
|
||
}
|