mirror of
https://github.com/libguestfs/libguestfs.git
synced 2026-03-22 07:03:38 +00:00
edit: move windows path code to common file
Move the code handling Windows paths from virt-edit to a common file, so that can be shared by various tools. Mostly code motion, with a minimum touch (the additional guestfs_h* parameter in mount_drive_letter) to make it build and work.
This commit is contained in:
@@ -33,7 +33,9 @@ SHARED_SOURCE_FILES = \
|
||||
../fish/options.h \
|
||||
../fish/options.c \
|
||||
../fish/uri.h \
|
||||
../fish/uri.c
|
||||
../fish/uri.c \
|
||||
../fish/windows.h \
|
||||
../fish/windows.c
|
||||
|
||||
virt_edit_SOURCES = \
|
||||
$(SHARED_SOURCE_FILES) \
|
||||
|
||||
104
edit/edit.c
104
edit/edit.c
@@ -37,6 +37,7 @@
|
||||
|
||||
#include "guestfs.h"
|
||||
#include "options.h"
|
||||
#include "windows.h"
|
||||
|
||||
/* Currently open libguestfs handle. */
|
||||
guestfs_h *g;
|
||||
@@ -56,8 +57,6 @@ static void edit_files (int argc, char *argv[]);
|
||||
static void edit (const char *filename, const char *root);
|
||||
static char *edit_interactively (const char *tmpfile);
|
||||
static char *edit_non_interactively (const char *tmpfile);
|
||||
static int is_windows (guestfs_h *g, const char *root);
|
||||
static char *windows_path (guestfs_h *g, const char *root, const char *filename);
|
||||
static char *generate_random_name (const char *filename);
|
||||
static char *generate_backup_name (const char *filename);
|
||||
|
||||
@@ -527,107 +526,6 @@ edit_non_interactively (const char *tmpfile)
|
||||
return ret; /* caller will free */
|
||||
}
|
||||
|
||||
static int
|
||||
is_windows (guestfs_h *g, const char *root)
|
||||
{
|
||||
int w;
|
||||
CLEANUP_FREE char *type = guestfs_inspect_get_type (g, root);
|
||||
if (!type)
|
||||
return 0;
|
||||
|
||||
w = STREQ (type, "windows");
|
||||
return w;
|
||||
}
|
||||
|
||||
static void mount_drive_letter (char drive_letter, const char *root);
|
||||
|
||||
static char *
|
||||
windows_path (guestfs_h *g, const char *root, const char *path)
|
||||
{
|
||||
char *ret;
|
||||
size_t i;
|
||||
|
||||
/* If there is a drive letter, rewrite the path. */
|
||||
if (c_isalpha (path[0]) && path[1] == ':') {
|
||||
char drive_letter = c_tolower (path[0]);
|
||||
/* This returns the newly allocated string. */
|
||||
mount_drive_letter (drive_letter, root);
|
||||
ret = strdup (path + 2);
|
||||
if (ret == NULL) {
|
||||
perror ("strdup");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
else if (!*path) {
|
||||
ret = strdup ("/");
|
||||
if (ret == NULL) {
|
||||
perror ("strdup");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
else {
|
||||
ret = strdup (path);
|
||||
if (ret == NULL) {
|
||||
perror ("strdup");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
/* Blindly convert any backslashes into forward slashes. Is this good? */
|
||||
for (i = 0; i < strlen (ret); ++i)
|
||||
if (ret[i] == '\\')
|
||||
ret[i] = '/';
|
||||
|
||||
char *t = guestfs_case_sensitive_path (g, ret);
|
||||
free (ret);
|
||||
ret = t;
|
||||
if (ret == NULL)
|
||||
exit (EXIT_FAILURE);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
mount_drive_letter (char drive_letter, const char *root)
|
||||
{
|
||||
char *device;
|
||||
size_t i;
|
||||
|
||||
/* Resolve the drive letter using the drive mappings table. */
|
||||
CLEANUP_FREE_STRING_LIST char **drives =
|
||||
guestfs_inspect_get_drive_mappings (g, root);
|
||||
if (drives == NULL || drives[0] == NULL) {
|
||||
fprintf (stderr, _("%s: to use Windows drive letters, this must be a Windows guest\n"),
|
||||
program_name);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
device = NULL;
|
||||
for (i = 0; drives[i] != NULL; i += 2) {
|
||||
if (c_tolower (drives[i][0]) == drive_letter && drives[i][1] == '\0') {
|
||||
device = drives[i+1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (device == NULL) {
|
||||
fprintf (stderr, _("%s: drive '%c:' not found.\n"),
|
||||
program_name, drive_letter);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Unmount current disk and remount device. */
|
||||
if (guestfs_umount_all (g) == -1)
|
||||
exit (EXIT_FAILURE);
|
||||
|
||||
if (guestfs_mount (g, device, "/") == -1)
|
||||
exit (EXIT_FAILURE);
|
||||
|
||||
/* Don't need to free (device) because that string was in the
|
||||
* drives array.
|
||||
*/
|
||||
}
|
||||
|
||||
static char
|
||||
random_char (void)
|
||||
{
|
||||
|
||||
135
fish/windows.c
Normal file
135
fish/windows.c
Normal file
@@ -0,0 +1,135 @@
|
||||
/* libguestfs - shared Windows path for tools
|
||||
* Copyright (C) 2009-2014 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 <config.h>
|
||||
|
||||
#include "windows.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <locale.h>
|
||||
#include <langinfo.h>
|
||||
#include <libintl.h>
|
||||
|
||||
#include "guestfs-internal-frontend.h"
|
||||
|
||||
#include "c-ctype.h"
|
||||
|
||||
static void mount_drive_letter (guestfs_h *g, char drive_letter,
|
||||
const char *root);
|
||||
|
||||
int
|
||||
is_windows (guestfs_h *g, const char *root)
|
||||
{
|
||||
int w;
|
||||
CLEANUP_FREE char *type = guestfs_inspect_get_type (g, root);
|
||||
if (!type)
|
||||
return 0;
|
||||
|
||||
w = STREQ (type, "windows");
|
||||
return w;
|
||||
}
|
||||
|
||||
char *
|
||||
windows_path (guestfs_h *g, const char *root, const char *path)
|
||||
{
|
||||
char *ret;
|
||||
size_t i;
|
||||
|
||||
/* If there is a drive letter, rewrite the path. */
|
||||
if (c_isalpha (path[0]) && path[1] == ':') {
|
||||
char drive_letter = c_tolower (path[0]);
|
||||
/* This returns the newly allocated string. */
|
||||
mount_drive_letter (g, drive_letter, root);
|
||||
ret = strdup (path + 2);
|
||||
if (ret == NULL) {
|
||||
perror ("strdup");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
else if (!*path) {
|
||||
ret = strdup ("/");
|
||||
if (ret == NULL) {
|
||||
perror ("strdup");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
else {
|
||||
ret = strdup (path);
|
||||
if (ret == NULL) {
|
||||
perror ("strdup");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
/* Blindly convert any backslashes into forward slashes. Is this good? */
|
||||
for (i = 0; i < strlen (ret); ++i)
|
||||
if (ret[i] == '\\')
|
||||
ret[i] = '/';
|
||||
|
||||
char *t = guestfs_case_sensitive_path (g, ret);
|
||||
free (ret);
|
||||
ret = t;
|
||||
if (ret == NULL)
|
||||
exit (EXIT_FAILURE);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
mount_drive_letter (guestfs_h *g, char drive_letter, const char *root)
|
||||
{
|
||||
char *device;
|
||||
size_t i;
|
||||
|
||||
/* Resolve the drive letter using the drive mappings table. */
|
||||
CLEANUP_FREE_STRING_LIST char **drives =
|
||||
guestfs_inspect_get_drive_mappings (g, root);
|
||||
if (drives == NULL || drives[0] == NULL) {
|
||||
fprintf (stderr, _("%s: to use Windows drive letters, this must be a Windows guest\n"),
|
||||
program_name);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
device = NULL;
|
||||
for (i = 0; drives[i] != NULL; i += 2) {
|
||||
if (c_tolower (drives[i][0]) == drive_letter && drives[i][1] == '\0') {
|
||||
device = drives[i+1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (device == NULL) {
|
||||
fprintf (stderr, _("%s: drive '%c:' not found.\n"),
|
||||
program_name, drive_letter);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Unmount current disk and remount device. */
|
||||
if (guestfs_umount_all (g) == -1)
|
||||
exit (EXIT_FAILURE);
|
||||
|
||||
if (guestfs_mount (g, device, "/") == -1)
|
||||
exit (EXIT_FAILURE);
|
||||
|
||||
/* Don't need to free (device) because that string was in the
|
||||
* drives array.
|
||||
*/
|
||||
}
|
||||
44
fish/windows.h
Normal file
44
fish/windows.h
Normal file
@@ -0,0 +1,44 @@
|
||||
/* libguestfs - shared Windows path for tools
|
||||
* Copyright (C) 2009-2014 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.
|
||||
*/
|
||||
|
||||
#ifndef FISH_WINDOWS_H
|
||||
#define FISH_WINDOWS_H
|
||||
|
||||
#include <guestfs.h>
|
||||
|
||||
/**
|
||||
* Checks whether 'root' is a Windows installation.
|
||||
*
|
||||
* This relies on an already being done introspection.
|
||||
*/
|
||||
extern int is_windows (guestfs_h *g, const char *root);
|
||||
|
||||
/**
|
||||
* Resolves 'path' as possible Windows path according to 'root',
|
||||
* giving a new path that can be used in libguestfs API calls.
|
||||
*
|
||||
* Notes:
|
||||
* - 'root' must be a Windows installation
|
||||
* - relies on an already being done introspection
|
||||
* - will unmount all the existing mount points and mount the Windows root
|
||||
* - will exit() on memory allocation failures, and if it is not possible
|
||||
* to get the true path on case-insensitive filesystems
|
||||
*/
|
||||
extern char *windows_path (guestfs_h *g, const char *root, const char *path);
|
||||
|
||||
#endif
|
||||
@@ -160,6 +160,7 @@ fish/supported.c
|
||||
fish/tilde.c
|
||||
fish/time.c
|
||||
fish/uri.c
|
||||
fish/windows.c
|
||||
format/format.c
|
||||
fuse/guestmount.c
|
||||
fuse/guestunmount.c
|
||||
|
||||
Reference in New Issue
Block a user