aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/libufs/libufs.h1
-rw-r--r--lib/libufs/type.c42
2 files changed, 41 insertions, 2 deletions
diff --git a/lib/libufs/libufs.h b/lib/libufs/libufs.h
index c2f11a922b43..266f787421f6 100644
--- a/lib/libufs/libufs.h
+++ b/lib/libufs/libufs.h
@@ -80,6 +80,7 @@ struct uufsd {
/* superblock as buffer */
} d_sbunion;
const char *d_error; /* human readable disk error */
+ int d_mine; /* internal flags */
#define d_fs d_sbunion.d_fs
#define d_sb d_sbunion.d_sb
};
diff --git a/lib/libufs/type.c b/lib/libufs/type.c
index 622cba8577d7..d3182d3f5403 100644
--- a/lib/libufs/type.c
+++ b/lib/libufs/type.c
@@ -39,6 +39,8 @@ __FBSDID("$FreeBSD$");
#include <errno.h>
#include <fcntl.h>
+#include <fstab.h>
+#include <paths.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -46,6 +48,9 @@ __FBSDID("$FreeBSD$");
#include <libufs.h>
+/* Internally, track the 'name' value, it's ours. */
+#define MINE_NAME 0x01
+
struct uufsd *
ufs_disk_ctor(const char *name)
{
@@ -96,19 +101,42 @@ ufs_disk_close(struct uufsd *disk)
free(disk->d_inoblock);
disk->d_inoblock = NULL;
}
+ if (disk->d_mine & MINE_NAME) {
+ free((char *)(uintptr_t)disk->d_name);
+ disk->d_name = NULL;
+ }
return 0;
}
int
ufs_disk_fillout(struct uufsd *disk, const char *name)
{
+ struct stat st;
+ struct fstab *fs;
+ const char *oname;
+ char dev[MAXPATHLEN];
int fd;
ERROR(disk, NULL);
+ oname = name;
+ fs = getfsfile(name);
+ if (fs != NULL)
+ name = fs->fs_spec;
+again: if (stat(name, &st) < 0) {
+ if (*name != '/') {
+ if (*name == 'r')
+ name++;
+ snprintf(dev, sizeof(dev), "%s%s", _PATH_DEV, name);
+ name = dev;
+ goto again;
+ }
+ ERROR(disk, "could not find special device");
+ return -1;
+ }
fd = open(name, O_RDONLY);
if (fd == -1) {
- ERROR(disk, "failed to open disk for reading");
+ ERROR(disk, "could not open special device");
return -1;
}
@@ -117,10 +145,20 @@ ufs_disk_fillout(struct uufsd *disk, const char *name)
disk->d_inoblock = NULL;
disk->d_inomin = 0;
disk->d_inomax = 0;
- disk->d_name = name;
+ disk->d_mine = 0;
disk->d_ufs = 0;
disk->d_error = NULL;
+ if (oname != name) {
+ name = strdup(name);
+ if (name == NULL) {
+ ERROR(disk, "could not allocate memory for disk name");
+ return -1;
+ }
+ disk->d_mine |= MINE_NAME;
+ }
+ disk->d_name = name;
+
if (sbread(disk) == -1) {
ERROR(disk, "could not read superblock to fill out disk");
return -1;