diff --git a/align/Makefile.am b/align/Makefile.am index 285f9f1b9..b24382391 100644 --- a/align/Makefile.am +++ b/align/Makefile.am @@ -38,7 +38,9 @@ SHARED_SOURCE_FILES = \ ../fish/inspect.c \ ../fish/keys.c \ ../fish/options.h \ - ../fish/options.c + ../fish/options.c \ + ../fish/uri.h \ + ../fish/uri.c virt_alignment_scan_SOURCES = \ $(SHARED_SOURCE_FILES) \ diff --git a/cat/Makefile.am b/cat/Makefile.am index 5f6c2fca0..b9df9cd65 100644 --- a/cat/Makefile.am +++ b/cat/Makefile.am @@ -35,7 +35,9 @@ SHARED_SOURCE_FILES = \ ../fish/inspect.c \ ../fish/keys.c \ ../fish/options.h \ - ../fish/options.c + ../fish/options.c \ + ../fish/uri.h \ + ../fish/uri.c virt_cat_SOURCES = \ $(SHARED_SOURCE_FILES) \ diff --git a/cat/virt-cat.c b/cat/virt-cat.c index f752a1a90..e86ecf37a 100644 --- a/cat/virt-cat.c +++ b/cat/virt-cat.c @@ -186,7 +186,11 @@ main (int argc, char *argv[]) exit (EXIT_FAILURE); } drv->type = drv_a; - drv->a.filename = argv[optind]; + drv->a.filename = strdup (argv[optind]); + if (!drv->a.filename) { + perror ("strdup"); + exit (EXIT_FAILURE); + } drv->next = drvs; drvs = drv; } else { /* simulate -d option */ diff --git a/cat/virt-ls.c b/cat/virt-ls.c index 3ebd633cc..1c449c286 100644 --- a/cat/virt-ls.c +++ b/cat/virt-ls.c @@ -291,7 +291,11 @@ main (int argc, char *argv[]) exit (EXIT_FAILURE); } drv->type = drv_a; - drv->a.filename = argv[optind]; + drv->a.filename = strdup (argv[optind]); + if (!drv->a.filename) { + perror ("strdup"); + exit (EXIT_FAILURE); + } drv->next = drvs; drvs = drv; } else { /* simulate -d option */ diff --git a/df/Makefile.am b/df/Makefile.am index 1288d10c7..38a628c97 100644 --- a/df/Makefile.am +++ b/df/Makefile.am @@ -33,7 +33,9 @@ SHARED_SOURCE_FILES = \ ../fish/inspect.c \ ../fish/keys.c \ ../fish/options.h \ - ../fish/options.c + ../fish/options.c \ + ../fish/uri.h \ + ../fish/uri.c virt_df_SOURCES = \ $(SHARED_SOURCE_FILES) \ diff --git a/df/main.c b/df/main.c index 55240707a..0eee3cb31 100644 --- a/df/main.c +++ b/df/main.c @@ -220,7 +220,11 @@ main (int argc, char *argv[]) exit (EXIT_FAILURE); } drv->type = drv_a; - drv->a.filename = argv[optind]; + drv->a.filename = strdup (argv[optind]); + if (!drv->a.filename) { + perror ("strdup"); + exit (EXIT_FAILURE); + } drv->next = drvs; drvs = drv; } else { /* simulate -d option */ diff --git a/edit/Makefile.am b/edit/Makefile.am index 01828a714..9d92be752 100644 --- a/edit/Makefile.am +++ b/edit/Makefile.am @@ -31,7 +31,9 @@ SHARED_SOURCE_FILES = \ ../fish/inspect.c \ ../fish/keys.c \ ../fish/options.h \ - ../fish/options.c + ../fish/options.c \ + ../fish/uri.h \ + ../fish/uri.c virt_edit_SOURCES = \ $(SHARED_SOURCE_FILES) \ diff --git a/edit/virt-edit.c b/edit/virt-edit.c index 05e88e2fd..5690f8dbd 100644 --- a/edit/virt-edit.c +++ b/edit/virt-edit.c @@ -223,7 +223,11 @@ main (int argc, char *argv[]) exit (EXIT_FAILURE); } drv->type = drv_a; - drv->a.filename = argv[optind]; + drv->a.filename = strdup (argv[optind]); + if (!drv->a.filename) { + perror ("strdup"); + exit (EXIT_FAILURE); + } drv->next = drvs; drvs = drv; } else { /* simulate -d option */ diff --git a/fish/Makefile.am b/fish/Makefile.am index 3e4995cc9..0c8ad17ea 100644 --- a/fish/Makefile.am +++ b/fish/Makefile.am @@ -70,7 +70,9 @@ SHARED_SOURCE_FILES = \ options.h \ options.c \ progress.h \ - progress.c + progress.c \ + uri.h \ + uri.c guestfish_SOURCES = \ $(generator_built) \ diff --git a/fish/fish.c b/fish/fish.c index 63e030da8..c724808ec 100644 --- a/fish/fish.c +++ b/fish/fish.c @@ -446,7 +446,11 @@ main (int argc, char *argv[]) exit (EXIT_FAILURE); } drv->type = drv_a; - drv->a.filename = argv[optind]; + drv->a.filename = strdup (argv[optind]); + if (!drv->a.filename) { + perror ("strdup"); + exit (EXIT_FAILURE); + } drv->next = drvs; drvs = drv; } else { /* simulate -d option */ diff --git a/fish/options.c b/fish/options.c index 5c55b389b..6d63afaa2 100644 --- a/fish/options.c +++ b/fish/options.c @@ -25,22 +25,15 @@ #include #include -#include - -#include "c-ctype.h" - #include "guestfs.h" #include "options.h" - -static int is_uri (const char *arg); -static void parse_uri (const char *arg, const char *format, struct drv *drv); -static char *query_get (xmlURIPtr uri, const char *search_name); -static char **make_server (xmlURIPtr uri, const char *socket); +#include "uri.h" /* Handle the '-a' option when passed on the command line. */ void option_a (const char *arg, const char *format, struct drv **drvsp) { + struct uri uri; struct drv *drv; drv = calloc (1, sizeof (struct drv)); @@ -49,268 +42,39 @@ option_a (const char *arg, const char *format, struct drv **drvsp) exit (EXIT_FAILURE); } - /* Does it look like a URI? */ - if (is_uri (arg)) - parse_uri (arg, format, drv); - else { + if (parse_uri (arg, &uri) == -1) + exit (EXIT_FAILURE); + + if (STREQ (uri.protocol, "file")) { /* Ordinary file. */ - if (access (arg, R_OK) != 0) { - perror (arg); + if (access (uri.path, R_OK) != 0) { + perror (uri.path); exit (EXIT_FAILURE); } drv->type = drv_a; drv->nr_drives = -1; - drv->a.filename = (char *) arg; + drv->a.filename = uri.path; drv->a.format = format; + + free (uri.protocol); + } + else { + /* Remote storage. */ + drv->type = drv_uri; + drv->nr_drives = -1; + drv->uri.path = uri.path; + drv->uri.protocol = uri.protocol; + drv->uri.server = uri.server; + drv->uri.username = uri.username; + drv->uri.format = format; + drv->uri.orig_uri = arg; } drv->next = *drvsp; *drvsp = drv; } -/* Does it "look like" a URI? A short lower-case ASCII string - * followed by "://" will do. Note that we properly parse the URI - * later on using libxml2. - */ -static int -is_uri (const char *arg) -{ - const char *p; - - p = strstr (arg, "://"); - if (!p) - return 0; - - if (p - arg >= 8) - return 0; - - for (p--; p >= arg; p--) { - if (!c_islower (*p)) - return 0; - } - - return 1; -} - -static void -parse_uri (const char *arg, const char *format, struct drv *drv) -{ - CLEANUP_XMLFREEURI xmlURIPtr uri = NULL; - CLEANUP_FREE char *socket = NULL; - char *path; - char *protocol; - char **server; - char *username; - - uri = xmlParseURI (arg); - if (!uri) { - fprintf (stderr, _("%s: --add: could not parse URI '%s'\n"), - program_name, arg); - exit (EXIT_FAILURE); - } - - /* Note we don't do much checking of the parsed URI, since the - * underlying function 'guestfs_add_drive_opts' will check for us. - * So just the basics here. - */ - if (uri->scheme == NULL) { - /* Probably can never happen. */ - fprintf (stderr, _("%s: --add %s: scheme of URI is NULL\n"), - program_name, arg); - exit (EXIT_FAILURE); - } - - socket = query_get (uri, "socket"); - - if (uri->server && STRNEQ (uri->server, "") && socket) { - fprintf (stderr, _("%s: --add %s: cannot both a server name and a socket query parameter\n"), - program_name, arg); - exit (EXIT_FAILURE); - } - - /* Is this needed? XXX - if (socket && socket[0] != '/') { - fprintf (stderr, _("%s: --add %s: socket query parameter must be an absolute path\n"), - program_name, arg); - exit (EXIT_FAILURE); - } - */ - - protocol = strdup (uri->scheme); - if (protocol == NULL) { - perror ("strdup"); - exit (EXIT_FAILURE); - } - - server = make_server (uri, socket); - - if (uri->user && STRNEQ (uri->user, "")) { - username = strdup (uri->user); - if (!username) { - perror ("username"); - exit (EXIT_FAILURE); - } - } - else username = NULL; - - path = strdup (uri->path ? uri->path : ""); - if (!path) { - perror ("path"); - exit (EXIT_FAILURE); - } - - drv->type = drv_uri; - drv->nr_drives = -1; - drv->uri.path = path; - drv->uri.protocol = protocol; - drv->uri.server = server; - drv->uri.username = username; - drv->uri.format = format; - drv->uri.orig_uri = arg; -} - -/* Code inspired by libvirt src/util/viruri.c, written by danpb, - * released under a compatible license. - */ -static char * -query_get (xmlURIPtr uri, const char *search_name) -{ - /* XXX libvirt uses deprecated uri->query field. Why? */ - const char *query = uri->query_raw; - const char *end, *eq; - - if (!query || STREQ (query, "")) - return NULL; - - while (*query) { - CLEANUP_FREE char *name = NULL; - char *value = NULL; - - /* Find the next separator, or end of the string. */ - end = strchr (query, '&'); - if (!end) - end = strchr(query, ';'); - if (!end) - end = query + strlen (query); - - /* Find the first '=' character between here and end. */ - eq = strchr(query, '='); - if (eq && eq >= end) eq = NULL; - - /* Empty section (eg. "&&"). */ - if (end == query) - goto next; - - /* If there is no '=' character, then we have just "name" - * and consistent with CGI.pm we assume value is "". - */ - else if (!eq) { - name = xmlURIUnescapeString (query, end - query, NULL); - if (!name) goto no_memory; - } - /* Or if we have "name=" here (works around annoying - * problem when calling xmlURIUnescapeString with len = 0). - */ - else if (eq+1 == end) { - name = xmlURIUnescapeString (query, eq - query, NULL); - if (!name) goto no_memory; - } - /* If the '=' character is at the beginning then we have - * "=value" and consistent with CGI.pm we _ignore_ this. - */ - else if (query == eq) - goto next; - - /* Otherwise it's "name=value". */ - else { - name = xmlURIUnescapeString (query, eq - query, NULL); - if (!name) - goto no_memory; - value = xmlURIUnescapeString (eq+1, end - (eq+1), NULL); - if (!value) { - goto no_memory; - } - } - - /* Is it the name we're looking for? */ - if (STREQ (name, search_name)) { - if (!value) { - value = strdup (""); - if (!value) - goto no_memory; - } - return value; - } - - free (value); - - next: - query = end; - if (*query) - query++; /* skip '&' separator */ - } - - /* search_name not found */ - return NULL; - - no_memory: - perror ("malloc"); - exit (EXIT_FAILURE); -} - -/* Construct either a tcp: server list of a unix: server list or - * nothing at all from '-a' option URI. - */ -static char ** -make_server (xmlURIPtr uri, const char *socket) -{ - char **ret; - char *server; - - /* If the server part of the URI is specified, then this is a TCP - * connection. - */ - if (uri->server && STRNEQ (uri->server, "")) { - if (uri->port == 0) { - if (asprintf (&server, "tcp:%s", uri->server) == -1) { - perror ("asprintf"); - exit (EXIT_FAILURE); - } - } - else { - if (asprintf (&server, "tcp:%s:%d", uri->server, uri->port) == -1) { - perror ("asprintf"); - exit (EXIT_FAILURE); - } - } - } - /* Otherwise, ?socket query parameter means it's a Unix domain - * socket connection. - */ - else if (socket != NULL) { - if (asprintf (&server, "unix:%s", socket) == -1) { - perror ("asprintf"); - exit (EXIT_FAILURE); - } - } - /* Otherwise, no server parameter is needed. */ - else return NULL; - - /* The .server parameter is in fact a list of strings, although - * only a singleton is passed by us. - */ - ret = malloc (sizeof (char *) * 2); - if (ret == NULL) { - perror ("malloc"); - exit (EXIT_FAILURE); - } - ret[0] = server; - ret[1] = NULL; - - return ret; -} - char add_drives (struct drv *drv, char next_drive) { @@ -488,7 +252,8 @@ free_drives (struct drv *drv) switch (drv->type) { case drv_a: - /* a.filename and a.format are optargs, don't free them */ + free (drv->a.filename); + /* a.format is an optarg, so don't free it */ break; case drv_uri: free (drv->uri.path); diff --git a/fish/uri.c b/fish/uri.c new file mode 100644 index 000000000..9c0892f71 --- /dev/null +++ b/fish/uri.c @@ -0,0 +1,318 @@ +/* libguestfs - mini library for parsing -a URI parameters + * Copyright (C) 2013 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. + */ + +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "c-ctype.h" + +#include "guestfs.h" +#include "guestfs-internal-frontend.h" +#include "uri.h" + +static int is_uri (const char *arg); +static int parse (const char *arg, char **path_ret, char **protocol_ret, char ***server_ret, char **username_ret); +static char *query_get (xmlURIPtr uri, const char *search_name); +static int make_server (xmlURIPtr uri, const char *socket, char ***ret); + +int +parse_uri (const char *arg, struct uri *uri_ret) +{ + char *path; + char *protocol; + char **server; + char *username; + + /* Does it look like a URI? */ + if (is_uri (arg)) { + if (parse (arg, &path, &protocol, &server, &username) == -1) + return -1; + } + else { + /* Ordinary file. */ + path = strdup (arg); + if (!path) { + perror ("strdup"); + return -1; + } + protocol = strdup ("file"); + if (!protocol) { + perror ("strdup"); + free (path); + return -1; + } + server = NULL; + username = NULL; + } + + uri_ret->path = path; + uri_ret->protocol = protocol; + uri_ret->server = server; + uri_ret->username = username; + return 0; +} + +/* Does it "look like" a URI? A short lower-case ASCII string + * followed by "://" will do. Note that we properly parse the URI + * later on using libxml2. + */ +static int +is_uri (const char *arg) +{ + const char *p; + + p = strstr (arg, "://"); + if (!p) + return 0; + + if (p - arg >= 8) + return 0; + + for (p--; p >= arg; p--) { + if (!c_islower (*p)) + return 0; + } + + return 1; +} + +static int +parse (const char *arg, char **path_ret, char **protocol_ret, + char ***server_ret, char **username_ret) +{ + CLEANUP_XMLFREEURI xmlURIPtr uri = NULL; + CLEANUP_FREE char *socket = NULL; + + uri = xmlParseURI (arg); + if (!uri) { + fprintf (stderr, _("%s: --add: could not parse URI '%s'\n"), + program_name, arg); + return -1; + } + + /* Note we don't do much checking of the parsed URI, since the + * underlying function 'guestfs_add_drive_opts' will check for us. + * So just the basics here. + */ + if (uri->scheme == NULL || STREQ (uri->scheme, "")) { + /* Probably can never happen. */ + fprintf (stderr, _("%s: %s: scheme of URI is NULL or empty\n"), + program_name, arg); + return -1; + } + + socket = query_get (uri, "socket"); + + if (uri->server && STRNEQ (uri->server, "") && socket) { + fprintf (stderr, _("%s: %s: cannot both a server name and a socket query parameter\n"), + program_name, arg); + return -1; + } + + /* Is this needed? XXX + if (socket && socket[0] != '/') { + fprintf (stderr, _("%s: --add %s: socket query parameter must be an absolute path\n"), + program_name, arg); + return -1; + } + */ + + *protocol_ret = strdup (uri->scheme); + if (*protocol_ret == NULL) { + perror ("strdup"); + return -1; + } + + if (make_server (uri, socket, server_ret) == -1) { + free (*protocol_ret); + return -1; + } + + if (uri->user && STRNEQ (uri->user, "")) { + *username_ret = strdup (uri->user); + if (*username_ret == NULL) { + perror ("username"); + free (*protocol_ret); + guestfs___free_string_list (*server_ret); + return -1; + } + } + else *username_ret = NULL; + + *path_ret = strdup (uri->path ? uri->path : ""); + if (!*path_ret) { + perror ("path"); + free (*protocol_ret); + guestfs___free_string_list (*server_ret); + free (*username_ret); + return -1; + } + + return 0; +} + +/* Code inspired by libvirt src/util/viruri.c, written by danpb, + * released under a compatible license. + */ +static char * +query_get (xmlURIPtr uri, const char *search_name) +{ + /* XXX libvirt uses deprecated uri->query field. Why? */ + const char *query = uri->query_raw; + const char *end, *eq; + + if (!query || STREQ (query, "")) + return NULL; + + while (*query) { + CLEANUP_FREE char *name = NULL; + char *value = NULL; + + /* Find the next separator, or end of the string. */ + end = strchr (query, '&'); + if (!end) + end = strchr(query, ';'); + if (!end) + end = query + strlen (query); + + /* Find the first '=' character between here and end. */ + eq = strchr(query, '='); + if (eq && eq >= end) eq = NULL; + + /* Empty section (eg. "&&"). */ + if (end == query) + goto next; + + /* If there is no '=' character, then we have just "name" + * and consistent with CGI.pm we assume value is "". + */ + else if (!eq) { + name = xmlURIUnescapeString (query, end - query, NULL); + if (!name) goto no_memory; + } + /* Or if we have "name=" here (works around annoying + * problem when calling xmlURIUnescapeString with len = 0). + */ + else if (eq+1 == end) { + name = xmlURIUnescapeString (query, eq - query, NULL); + if (!name) goto no_memory; + } + /* If the '=' character is at the beginning then we have + * "=value" and consistent with CGI.pm we _ignore_ this. + */ + else if (query == eq) + goto next; + + /* Otherwise it's "name=value". */ + else { + name = xmlURIUnescapeString (query, eq - query, NULL); + if (!name) + goto no_memory; + value = xmlURIUnescapeString (eq+1, end - (eq+1), NULL); + if (!value) { + goto no_memory; + } + } + + /* Is it the name we're looking for? */ + if (STREQ (name, search_name)) { + if (!value) { + value = strdup (""); + if (!value) + goto no_memory; + } + return value; + } + + free (value); + + next: + query = end; + if (*query) + query++; /* skip '&' separator */ + } + + /* search_name not found */ + return NULL; + + no_memory: + perror ("malloc"); + return NULL; +} + +/* Construct either a tcp: server list of a unix: server list or + * nothing at all from '-a' option URI. + */ +static int +make_server (xmlURIPtr uri, const char *socket, char ***ret) +{ + char *server; + + /* If the server part of the URI is specified, then this is a TCP + * connection. + */ + if (uri->server && STRNEQ (uri->server, "")) { + if (uri->port == 0) { + if (asprintf (&server, "tcp:%s", uri->server) == -1) { + perror ("asprintf"); + return -1; + } + } + else { + if (asprintf (&server, "tcp:%s:%d", uri->server, uri->port) == -1) { + perror ("asprintf"); + return -1; + } + } + } + /* Otherwise, ?socket query parameter means it's a Unix domain + * socket connection. + */ + else if (socket != NULL) { + if (asprintf (&server, "unix:%s", socket) == -1) { + perror ("asprintf"); + return -1; + } + } + /* Otherwise, no server parameter is needed. */ + else { + *ret = NULL; + return 0; + } + + /* The .server parameter is in fact a list of strings, although + * only a singleton is passed by us. + */ + *ret = malloc (sizeof (char *) * 2); + if (*ret == NULL) { + perror ("malloc"); + return -1; + } + (*ret)[0] = server; + (*ret)[1] = NULL; + + return 0; +} diff --git a/fish/uri.h b/fish/uri.h new file mode 100644 index 000000000..420d20c3b --- /dev/null +++ b/fish/uri.h @@ -0,0 +1,46 @@ +/* libguestfs - mini library for parsing -a URI parameters + * Copyright (C) 2013 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. + */ + +#include + +#ifndef FISH_URI_H +#define FISH_URI_H + +struct uri { + char *path; /* disk path */ + char *protocol; /* protocol (eg. "file", "nbd") */ + char **server; /* server(s) - can be NULL */ + char *username; /* username - can be NULL */ +}; + +/* Parse the '-a' option parameter 'arg', and place the result in + * '*uri_ret'. + * + * If it doesn't look like a URI then uri_ret->path will be the same + * as 'arg' (copied) and uri_ret->protocol will be "file". + * + * If it looks like a URI and can be parsed, then the other fields will + * be filled in as appropriate. + * + * The caller should free the fields from the struct after use. + * + * Returns 0 if parsing went OK, or -1 if there was an error. + */ +extern int parse_uri (const char *arg, struct uri *uri_ret); + +#endif /* FISH_URI_H */ diff --git a/format/Makefile.am b/format/Makefile.am index a0d1ed437..c93edc9bf 100644 --- a/format/Makefile.am +++ b/format/Makefile.am @@ -30,7 +30,9 @@ SHARED_SOURCE_FILES = \ ../fish/inspect.c \ ../fish/keys.c \ ../fish/options.h \ - ../fish/options.c + ../fish/options.c \ + ../fish/uri.h \ + ../fish/uri.c virt_format_SOURCES = \ $(SHARED_SOURCE_FILES) \ diff --git a/fuse/Makefile.am b/fuse/Makefile.am index 6335bbb34..d10ff7deb 100644 --- a/fuse/Makefile.am +++ b/fuse/Makefile.am @@ -42,7 +42,9 @@ SHARED_SOURCE_FILES = \ ../fish/inspect.c \ ../fish/keys.c \ ../fish/options.h \ - ../fish/options.c + ../fish/options.c \ + ../fish/uri.h \ + ../fish/uri.c # guestmount diff --git a/inspector/Makefile.am b/inspector/Makefile.am index 1967fe897..a5aa3c1ec 100644 --- a/inspector/Makefile.am +++ b/inspector/Makefile.am @@ -57,7 +57,9 @@ SHARED_SOURCE_FILES = \ ../fish/inspect.c \ ../fish/keys.c \ ../fish/options.h \ - ../fish/options.c + ../fish/options.c \ + ../fish/uri.h \ + ../fish/uri.c virt_inspector_SOURCES = \ $(SHARED_SOURCE_FILES) \ diff --git a/inspector/virt-inspector.c b/inspector/virt-inspector.c index 146f21144..a070a3a22 100644 --- a/inspector/virt-inspector.c +++ b/inspector/virt-inspector.c @@ -199,7 +199,11 @@ main (int argc, char *argv[]) exit (EXIT_FAILURE); } drv->type = drv_a; - drv->a.filename = argv[optind]; + drv->a.filename = strdup (argv[optind]); + if (!drv->a.filename) { + perror ("strdup"); + exit (EXIT_FAILURE); + } drv->next = drvs; drvs = drv; } else { /* simulate -d option */ diff --git a/po/POTFILES b/po/POTFILES index dc000a4e0..976f14689 100644 --- a/po/POTFILES +++ b/po/POTFILES @@ -145,6 +145,7 @@ fish/setenv.c fish/supported.c fish/tilde.c fish/time.c +fish/uri.c format/format.c fuse/guestmount.c fuse/guestunmount.c diff --git a/rescue/Makefile.am b/rescue/Makefile.am index f6942232d..7d23ee267 100644 --- a/rescue/Makefile.am +++ b/rescue/Makefile.am @@ -31,7 +31,9 @@ SHARED_SOURCE_FILES = \ ../fish/inspect.c \ ../fish/keys.c \ ../fish/options.h \ - ../fish/options.c + ../fish/options.c \ + ../fish/uri.h \ + ../fish/uri.c virt_rescue_SOURCES = \ $(SHARED_SOURCE_FILES) \ diff --git a/rescue/virt-rescue.c b/rescue/virt-rescue.c index 6c6e30683..65dd473c4 100644 --- a/rescue/virt-rescue.c +++ b/rescue/virt-rescue.c @@ -256,7 +256,11 @@ main (int argc, char *argv[]) exit (EXIT_FAILURE); } drv->type = drv_a; - drv->a.filename = argv[optind]; + drv->a.filename = strdup (argv[optind]); + if (!drv->a.filename) { + perror ("strdup"); + exit (EXIT_FAILURE); + } drv->next = drvs; drvs = drv; } else { /* simulate -d option */ @@ -570,7 +574,11 @@ add_scratch_disk (struct drv **drvs) } drv->type = drv_a; drv->nr_drives = -1; - drv->a.filename = filename; + drv->a.filename = strdup (filename); + if (!drv->a.filename) { + perror ("strdup"); + exit (EXIT_FAILURE); + } drv->a.format = "raw"; drv->next = *drvs; *drvs = drv;