diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2006-12-26 01:25:48 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2006-12-26 01:25:48 +0000 |
commit | 64c54025842f205ad722675105b88044a5b6845a (patch) | |
tree | 9b5361a46d9174b8c4c12947b006acbca33dc24c /e2fsprogs/blkid | |
parent | d63c3a032ade4d7a1953031d787eed044811b78c (diff) | |
download | busybox-w32-64c54025842f205ad722675105b88044a5b6845a.tar.gz busybox-w32-64c54025842f205ad722675105b88044a5b6845a.tar.bz2 busybox-w32-64c54025842f205ad722675105b88044a5b6845a.zip |
remove e2fsprogs. Nobody volunteered to clean up that mess
Diffstat (limited to 'e2fsprogs/blkid')
-rw-r--r-- | e2fsprogs/blkid/Kbuild | 23 | ||||
-rw-r--r-- | e2fsprogs/blkid/blkid.h | 105 | ||||
-rw-r--r-- | e2fsprogs/blkid/blkidP.h | 187 | ||||
-rw-r--r-- | e2fsprogs/blkid/blkid_getsize.c | 179 | ||||
-rw-r--r-- | e2fsprogs/blkid/cache.c | 126 | ||||
-rw-r--r-- | e2fsprogs/blkid/dev.c | 214 | ||||
-rw-r--r-- | e2fsprogs/blkid/devname.c | 368 | ||||
-rw-r--r-- | e2fsprogs/blkid/devno.c | 223 | ||||
-rw-r--r-- | e2fsprogs/blkid/list.c | 110 | ||||
-rw-r--r-- | e2fsprogs/blkid/list.h | 73 | ||||
-rw-r--r-- | e2fsprogs/blkid/probe.c | 721 | ||||
-rw-r--r-- | e2fsprogs/blkid/probe.h | 375 | ||||
-rw-r--r-- | e2fsprogs/blkid/read.c | 462 | ||||
-rw-r--r-- | e2fsprogs/blkid/resolve.c | 139 | ||||
-rw-r--r-- | e2fsprogs/blkid/save.c | 189 | ||||
-rw-r--r-- | e2fsprogs/blkid/tag.c | 432 |
16 files changed, 0 insertions, 3926 deletions
diff --git a/e2fsprogs/blkid/Kbuild b/e2fsprogs/blkid/Kbuild deleted file mode 100644 index ddcfdfd9a..000000000 --- a/e2fsprogs/blkid/Kbuild +++ /dev/null | |||
@@ -1,23 +0,0 @@ | |||
1 | # Makefile for busybox | ||
2 | # | ||
3 | # Copyright (C) 1999-2005 by Erik Andersen <andersen@codepoet.org> | ||
4 | # | ||
5 | # Licensed under the GPL v2, see the file LICENSE in this tarball. | ||
6 | |||
7 | NEEDED-$(CONFIG_E2FSCK) = y | ||
8 | NEEDED-$(CONFIG_FSCK) = y | ||
9 | NEEDED-$(CONFIG_MKE2FS) = y | ||
10 | NEEDED-$(CONFIG_TUNE2FS) = y | ||
11 | |||
12 | lib-y:= | ||
13 | lib-$(NEEDED-y) += cache.o dev.o devname.o devno.o blkid_getsize.o \ | ||
14 | probe.o read.o resolve.o save.o tag.o list.o | ||
15 | |||
16 | CFLAGS_dev.o := -include $(srctree)/include/busybox.h | ||
17 | CFLAGS_devname.o := -include $(srctree)/include/busybox.h | ||
18 | CFLAGS_devno.o := -include $(srctree)/include/busybox.h | ||
19 | CFLAGS_blkid_getsize.o := -include $(srctree)/include/busybox.h | ||
20 | CFLAGS_probe.o := -include $(srctree)/include/busybox.h | ||
21 | CFLAGS_save.o := -include $(srctree)/include/busybox.h | ||
22 | CFLAGS_tag.o := -include $(srctree)/include/busybox.h | ||
23 | CFLAGS_list.o := -include $(srctree)/include/busybox.h | ||
diff --git a/e2fsprogs/blkid/blkid.h b/e2fsprogs/blkid/blkid.h deleted file mode 100644 index 4fa9f6fdf..000000000 --- a/e2fsprogs/blkid/blkid.h +++ /dev/null | |||
@@ -1,105 +0,0 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * blkid.h - Interface for libblkid, a library to identify block devices | ||
4 | * | ||
5 | * Copyright (C) 2001 Andreas Dilger | ||
6 | * Copyright (C) 2003 Theodore Ts'o | ||
7 | * | ||
8 | * %Begin-Header% | ||
9 | * This file may be redistributed under the terms of the | ||
10 | * GNU Lesser General Public License. | ||
11 | * %End-Header% | ||
12 | */ | ||
13 | |||
14 | #ifndef _BLKID_BLKID_H | ||
15 | #define _BLKID_BLKID_H | ||
16 | |||
17 | #include <sys/types.h> | ||
18 | #include <linux/types.h> | ||
19 | |||
20 | #ifdef __cplusplus | ||
21 | extern "C" { | ||
22 | #endif | ||
23 | |||
24 | #define BLKID_VERSION "1.0.0" | ||
25 | #define BLKID_DATE "12-Feb-2003" | ||
26 | |||
27 | typedef struct blkid_struct_dev *blkid_dev; | ||
28 | typedef struct blkid_struct_cache *blkid_cache; | ||
29 | typedef __s64 blkid_loff_t; | ||
30 | |||
31 | typedef struct blkid_struct_tag_iterate *blkid_tag_iterate; | ||
32 | typedef struct blkid_struct_dev_iterate *blkid_dev_iterate; | ||
33 | |||
34 | /* | ||
35 | * Flags for blkid_get_dev | ||
36 | * | ||
37 | * BLKID_DEV_CREATE Create an empty device structure if not found | ||
38 | * in the cache. | ||
39 | * BLKID_DEV_VERIFY Make sure the device structure corresponds | ||
40 | * with reality. | ||
41 | * BLKID_DEV_FIND Just look up a device entry, and return NULL | ||
42 | * if it is not found. | ||
43 | * BLKID_DEV_NORMAL Get a valid device structure, either from the | ||
44 | * cache or by probing the device. | ||
45 | */ | ||
46 | #define BLKID_DEV_FIND 0x0000 | ||
47 | #define BLKID_DEV_CREATE 0x0001 | ||
48 | #define BLKID_DEV_VERIFY 0x0002 | ||
49 | #define BLKID_DEV_NORMAL (BLKID_DEV_CREATE | BLKID_DEV_VERIFY) | ||
50 | |||
51 | /* cache.c */ | ||
52 | extern void blkid_put_cache(blkid_cache cache); | ||
53 | extern int blkid_get_cache(blkid_cache *cache, const char *filename); | ||
54 | |||
55 | /* dev.c */ | ||
56 | extern const char *blkid_dev_devname(blkid_dev dev); | ||
57 | |||
58 | extern blkid_dev_iterate blkid_dev_iterate_begin(blkid_cache cache); | ||
59 | extern int blkid_dev_set_search(blkid_dev_iterate iter, | ||
60 | char *search_type, char *search_value); | ||
61 | extern int blkid_dev_next(blkid_dev_iterate iterate, blkid_dev *dev); | ||
62 | extern void blkid_dev_iterate_end(blkid_dev_iterate iterate); | ||
63 | |||
64 | /* devno.c */ | ||
65 | extern char *blkid_devno_to_devname(dev_t devno); | ||
66 | |||
67 | /* devname.c */ | ||
68 | extern int blkid_probe_all(blkid_cache cache); | ||
69 | extern int blkid_probe_all_new(blkid_cache cache); | ||
70 | extern blkid_dev blkid_get_dev(blkid_cache cache, const char *devname, | ||
71 | int flags); | ||
72 | |||
73 | /* getsize.c */ | ||
74 | extern blkid_loff_t blkid_get_dev_size(int fd); | ||
75 | |||
76 | /* probe.c */ | ||
77 | int blkid_known_fstype(const char *fstype); | ||
78 | extern blkid_dev blkid_verify(blkid_cache cache, blkid_dev dev); | ||
79 | |||
80 | /* read.c */ | ||
81 | |||
82 | /* resolve.c */ | ||
83 | extern char *blkid_get_tag_value(blkid_cache cache, const char *tagname, | ||
84 | const char *devname); | ||
85 | extern char *blkid_get_devname(blkid_cache cache, const char *token, | ||
86 | const char *value); | ||
87 | |||
88 | /* tag.c */ | ||
89 | extern blkid_tag_iterate blkid_tag_iterate_begin(blkid_dev dev); | ||
90 | extern int blkid_tag_next(blkid_tag_iterate iterate, | ||
91 | const char **type, const char **value); | ||
92 | extern void blkid_tag_iterate_end(blkid_tag_iterate iterate); | ||
93 | extern int blkid_dev_has_tag(blkid_dev dev, const char *type, | ||
94 | const char *value); | ||
95 | extern blkid_dev blkid_find_dev_with_tag(blkid_cache cache, | ||
96 | const char *type, | ||
97 | const char *value); | ||
98 | extern int blkid_parse_tag_string(const char *token, char **ret_type, | ||
99 | char **ret_val); | ||
100 | |||
101 | #ifdef __cplusplus | ||
102 | } | ||
103 | #endif | ||
104 | |||
105 | #endif /* _BLKID_BLKID_H */ | ||
diff --git a/e2fsprogs/blkid/blkidP.h b/e2fsprogs/blkid/blkidP.h deleted file mode 100644 index c7cb8abe9..000000000 --- a/e2fsprogs/blkid/blkidP.h +++ /dev/null | |||
@@ -1,187 +0,0 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * blkidP.h - Internal interfaces for libblkid | ||
4 | * | ||
5 | * Copyright (C) 2001 Andreas Dilger | ||
6 | * Copyright (C) 2003 Theodore Ts'o | ||
7 | * | ||
8 | * %Begin-Header% | ||
9 | * This file may be redistributed under the terms of the | ||
10 | * GNU Lesser General Public License. | ||
11 | * %End-Header% | ||
12 | */ | ||
13 | |||
14 | #ifndef _BLKID_BLKIDP_H | ||
15 | #define _BLKID_BLKIDP_H | ||
16 | |||
17 | #include <sys/types.h> | ||
18 | #include <stdio.h> | ||
19 | |||
20 | #include "blkid.h" | ||
21 | #include "list.h" | ||
22 | |||
23 | #ifdef __GNUC__ | ||
24 | #define __BLKID_ATTR(x) __attribute__(x) | ||
25 | #else | ||
26 | #define __BLKID_ATTR(x) | ||
27 | #endif | ||
28 | |||
29 | |||
30 | /* | ||
31 | * This describes the attributes of a specific device. | ||
32 | * We can traverse all of the tags by bid_tags (linking to the tag bit_names). | ||
33 | * The bid_label and bid_uuid fields are shortcuts to the LABEL and UUID tag | ||
34 | * values, if they exist. | ||
35 | */ | ||
36 | struct blkid_struct_dev | ||
37 | { | ||
38 | struct list_head bid_devs; /* All devices in the cache */ | ||
39 | struct list_head bid_tags; /* All tags for this device */ | ||
40 | blkid_cache bid_cache; /* Dev belongs to this cache */ | ||
41 | char *bid_name; /* Device inode pathname */ | ||
42 | char *bid_type; /* Preferred device TYPE */ | ||
43 | int bid_pri; /* Device priority */ | ||
44 | dev_t bid_devno; /* Device major/minor number */ | ||
45 | time_t bid_time; /* Last update time of device */ | ||
46 | unsigned int bid_flags; /* Device status bitflags */ | ||
47 | char *bid_label; /* Shortcut to device LABEL */ | ||
48 | char *bid_uuid; /* Shortcut to binary UUID */ | ||
49 | }; | ||
50 | |||
51 | #define BLKID_BID_FL_VERIFIED 0x0001 /* Device data validated from disk */ | ||
52 | #define BLKID_BID_FL_INVALID 0x0004 /* Device is invalid */ | ||
53 | |||
54 | /* | ||
55 | * Each tag defines a NAME=value pair for a particular device. The tags | ||
56 | * are linked via bit_names for a single device, so that traversing the | ||
57 | * names list will get you a list of all tags associated with a device. | ||
58 | * They are also linked via bit_values for all devices, so one can easily | ||
59 | * search all tags with a given NAME for a specific value. | ||
60 | */ | ||
61 | struct blkid_struct_tag | ||
62 | { | ||
63 | struct list_head bit_tags; /* All tags for this device */ | ||
64 | struct list_head bit_names; /* All tags with given NAME */ | ||
65 | char *bit_name; /* NAME of tag (shared) */ | ||
66 | char *bit_val; /* value of tag */ | ||
67 | blkid_dev bit_dev; /* pointer to device */ | ||
68 | }; | ||
69 | typedef struct blkid_struct_tag *blkid_tag; | ||
70 | |||
71 | /* | ||
72 | * Minimum number of seconds between device probes, even when reading | ||
73 | * from the cache. This is to avoid re-probing all devices which were | ||
74 | * just probed by another program that does not share the cache. | ||
75 | */ | ||
76 | #define BLKID_PROBE_MIN 2 | ||
77 | |||
78 | /* | ||
79 | * Time in seconds an entry remains verified in the in-memory cache | ||
80 | * before being reverified (in case of long-running processes that | ||
81 | * keep a cache in memory and continue to use it for a long time). | ||
82 | */ | ||
83 | #define BLKID_PROBE_INTERVAL 200 | ||
84 | |||
85 | /* This describes an entire blkid cache file and probed devices. | ||
86 | * We can traverse all of the found devices via bic_list. | ||
87 | * We can traverse all of the tag types by bic_tags, which hold empty tags | ||
88 | * for each tag type. Those tags can be used as list_heads for iterating | ||
89 | * through all devices with a specific tag type (e.g. LABEL). | ||
90 | */ | ||
91 | struct blkid_struct_cache | ||
92 | { | ||
93 | struct list_head bic_devs; /* List head of all devices */ | ||
94 | struct list_head bic_tags; /* List head of all tag types */ | ||
95 | time_t bic_time; /* Last probe time */ | ||
96 | time_t bic_ftime; /* Mod time of the cachefile */ | ||
97 | unsigned int bic_flags; /* Status flags of the cache */ | ||
98 | char *bic_filename; /* filename of cache */ | ||
99 | }; | ||
100 | |||
101 | #define BLKID_BIC_FL_PROBED 0x0002 /* We probed /proc/partition devices */ | ||
102 | #define BLKID_BIC_FL_CHANGED 0x0004 /* Cache has changed from disk */ | ||
103 | |||
104 | extern char *blkid_strdup(const char *s); | ||
105 | extern char *blkid_strndup(const char *s, const int length); | ||
106 | |||
107 | #define BLKID_CACHE_FILE "/etc/blkid.tab" | ||
108 | extern const char *blkid_devdirs[]; | ||
109 | |||
110 | #define BLKID_ERR_IO 5 | ||
111 | #define BLKID_ERR_PROC 9 | ||
112 | #define BLKID_ERR_MEM 12 | ||
113 | #define BLKID_ERR_CACHE 14 | ||
114 | #define BLKID_ERR_DEV 19 | ||
115 | #define BLKID_ERR_PARAM 22 | ||
116 | #define BLKID_ERR_BIG 27 | ||
117 | |||
118 | /* | ||
119 | * Priority settings for different types of devices | ||
120 | */ | ||
121 | #define BLKID_PRI_EVMS 30 | ||
122 | #define BLKID_PRI_LVM 20 | ||
123 | #define BLKID_PRI_MD 10 | ||
124 | |||
125 | #if defined(TEST_PROGRAM) && !defined(CONFIG_BLKID_DEBUG) | ||
126 | #define CONFIG_BLKID_DEBUG | ||
127 | #endif | ||
128 | |||
129 | #define DEBUG_CACHE 0x0001 | ||
130 | #define DEBUG_DUMP 0x0002 | ||
131 | #define DEBUG_DEV 0x0004 | ||
132 | #define DEBUG_DEVNAME 0x0008 | ||
133 | #define DEBUG_DEVNO 0x0010 | ||
134 | #define DEBUG_PROBE 0x0020 | ||
135 | #define DEBUG_READ 0x0040 | ||
136 | #define DEBUG_RESOLVE 0x0080 | ||
137 | #define DEBUG_SAVE 0x0100 | ||
138 | #define DEBUG_TAG 0x0200 | ||
139 | #define DEBUG_INIT 0x8000 | ||
140 | #define DEBUG_ALL 0xFFFF | ||
141 | |||
142 | #ifdef CONFIG_BLKID_DEBUG | ||
143 | #include <stdio.h> | ||
144 | extern int blkid_debug_mask; | ||
145 | #define DBG(m,x) if ((m) & blkid_debug_mask) x; | ||
146 | #else | ||
147 | #define DBG(m,x) | ||
148 | #endif | ||
149 | |||
150 | #ifdef CONFIG_BLKID_DEBUG | ||
151 | extern void blkid_debug_dump_dev(blkid_dev dev); | ||
152 | extern void blkid_debug_dump_tag(blkid_tag tag); | ||
153 | #endif | ||
154 | |||
155 | /* lseek.c */ | ||
156 | /* extern blkid_loff_t blkid_llseek(int fd, blkid_loff_t offset, int whence); */ | ||
157 | #ifdef CONFIG_LFS | ||
158 | # define blkid_llseek lseek64 | ||
159 | #else | ||
160 | # define blkid_llseek lseek | ||
161 | #endif | ||
162 | |||
163 | /* read.c */ | ||
164 | extern void blkid_read_cache(blkid_cache cache); | ||
165 | |||
166 | /* save.c */ | ||
167 | extern int blkid_flush_cache(blkid_cache cache); | ||
168 | |||
169 | /* | ||
170 | * Functions to create and find a specific tag type: tag.c | ||
171 | */ | ||
172 | extern void blkid_free_tag(blkid_tag tag); | ||
173 | extern blkid_tag blkid_find_tag_dev(blkid_dev dev, const char *type); | ||
174 | extern int blkid_set_tag(blkid_dev dev, const char *name, | ||
175 | const char *value, const int vlength); | ||
176 | |||
177 | /* | ||
178 | * Functions to create and find a specific tag type: dev.c | ||
179 | */ | ||
180 | extern blkid_dev blkid_new_dev(void); | ||
181 | extern void blkid_free_dev(blkid_dev dev); | ||
182 | |||
183 | #ifdef __cplusplus | ||
184 | } | ||
185 | #endif | ||
186 | |||
187 | #endif /* _BLKID_BLKIDP_H */ | ||
diff --git a/e2fsprogs/blkid/blkid_getsize.c b/e2fsprogs/blkid/blkid_getsize.c deleted file mode 100644 index 941efa42c..000000000 --- a/e2fsprogs/blkid/blkid_getsize.c +++ /dev/null | |||
@@ -1,179 +0,0 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * getsize.c --- get the size of a partition. | ||
4 | * | ||
5 | * Copyright (C) 1995, 1995 Theodore Ts'o. | ||
6 | * | ||
7 | * %Begin-Header% | ||
8 | * This file may be redistributed under the terms of the | ||
9 | * GNU Lesser General Public License. | ||
10 | * %End-Header% | ||
11 | */ | ||
12 | |||
13 | /* include this before sys/queues.h! */ | ||
14 | #include "blkidP.h" | ||
15 | |||
16 | #include <stdio.h> | ||
17 | #include <unistd.h> | ||
18 | #ifdef HAVE_ERRNO_H | ||
19 | #include <errno.h> | ||
20 | #endif | ||
21 | #include <fcntl.h> | ||
22 | #ifdef HAVE_SYS_IOCTL_H | ||
23 | #include <sys/ioctl.h> | ||
24 | #endif | ||
25 | #ifdef HAVE_LINUX_FD_H | ||
26 | #include <linux/fd.h> | ||
27 | #endif | ||
28 | #ifdef HAVE_SYS_DISKLABEL_H | ||
29 | #include <sys/disklabel.h> | ||
30 | #include <sys/stat.h> | ||
31 | #endif | ||
32 | #ifdef HAVE_SYS_DISK_H | ||
33 | #ifdef HAVE_SYS_QUEUE_H | ||
34 | #include <sys/queue.h> /* for LIST_HEAD */ | ||
35 | #endif | ||
36 | #include <sys/disk.h> | ||
37 | #endif | ||
38 | #ifdef __linux__ | ||
39 | #include <sys/utsname.h> | ||
40 | #endif | ||
41 | |||
42 | #if defined(__linux__) && defined(_IO) && !defined(BLKGETSIZE) | ||
43 | #define BLKGETSIZE _IO(0x12,96) /* return device size */ | ||
44 | #endif | ||
45 | |||
46 | #if defined(__linux__) && defined(_IOR) && !defined(BLKGETSIZE64) | ||
47 | #define BLKGETSIZE64 _IOR(0x12,114,size_t) /* return device size in bytes (u64 *arg) */ | ||
48 | #endif | ||
49 | |||
50 | #ifdef APPLE_DARWIN | ||
51 | #define BLKGETSIZE DKIOCGETBLOCKCOUNT32 | ||
52 | #endif /* APPLE_DARWIN */ | ||
53 | |||
54 | static int valid_offset(int fd, blkid_loff_t offset) | ||
55 | { | ||
56 | char ch; | ||
57 | |||
58 | if (blkid_llseek(fd, offset, 0) < 0) | ||
59 | return 0; | ||
60 | if (read(fd, &ch, 1) < 1) | ||
61 | return 0; | ||
62 | return 1; | ||
63 | } | ||
64 | |||
65 | /* | ||
66 | * Returns the number of blocks in a partition | ||
67 | */ | ||
68 | blkid_loff_t blkid_get_dev_size(int fd) | ||
69 | { | ||
70 | int valid_blkgetsize64 = 1; | ||
71 | #ifdef __linux__ | ||
72 | struct utsname ut; | ||
73 | #endif | ||
74 | unsigned long long size64; | ||
75 | unsigned long size; | ||
76 | blkid_loff_t high, low; | ||
77 | #ifdef FDGETPRM | ||
78 | struct floppy_struct this_floppy; | ||
79 | #endif | ||
80 | #ifdef HAVE_SYS_DISKLABEL_H | ||
81 | int part = -1; | ||
82 | struct disklabel lab; | ||
83 | struct partition *pp; | ||
84 | char ch; | ||
85 | struct stat st; | ||
86 | #endif /* HAVE_SYS_DISKLABEL_H */ | ||
87 | |||
88 | #ifdef DKIOCGETBLOCKCOUNT /* For Apple Darwin */ | ||
89 | if (ioctl(fd, DKIOCGETBLOCKCOUNT, &size64) >= 0) { | ||
90 | if ((sizeof(blkid_loff_t) < sizeof(unsigned long long)) | ||
91 | && (size64 << 9 > 0xFFFFFFFF)) | ||
92 | return 0; /* EFBIG */ | ||
93 | return (blkid_loff_t) size64 << 9; | ||
94 | } | ||
95 | #endif | ||
96 | |||
97 | #ifdef BLKGETSIZE64 | ||
98 | #ifdef __linux__ | ||
99 | if ((uname(&ut) == 0) && | ||
100 | ((ut.release[0] == '2') && (ut.release[1] == '.') && | ||
101 | (ut.release[2] < '6') && (ut.release[3] == '.'))) | ||
102 | valid_blkgetsize64 = 0; | ||
103 | #endif | ||
104 | if (valid_blkgetsize64 && | ||
105 | ioctl(fd, BLKGETSIZE64, &size64) >= 0) { | ||
106 | if ((sizeof(blkid_loff_t) < sizeof(unsigned long long)) | ||
107 | && ((size64) > 0xFFFFFFFF)) | ||
108 | return 0; /* EFBIG */ | ||
109 | return size64; | ||
110 | } | ||
111 | #endif | ||
112 | |||
113 | #ifdef BLKGETSIZE | ||
114 | if (ioctl(fd, BLKGETSIZE, &size) >= 0) | ||
115 | return (blkid_loff_t)size << 9; | ||
116 | #endif | ||
117 | |||
118 | #ifdef FDGETPRM | ||
119 | if (ioctl(fd, FDGETPRM, &this_floppy) >= 0) | ||
120 | return (blkid_loff_t)this_floppy.size << 9; | ||
121 | #endif | ||
122 | #ifdef HAVE_SYS_DISKLABEL_H | ||
123 | #if 0 | ||
124 | /* | ||
125 | * This should work in theory but I haven't tested it. Anyone | ||
126 | * on a BSD system want to test this for me? In the meantime, | ||
127 | * binary search mechanism should work just fine. | ||
128 | */ | ||
129 | if ((fstat(fd, &st) >= 0) && S_ISBLK(st.st_mode)) | ||
130 | part = st.st_rdev & 7; | ||
131 | if (part >= 0 && (ioctl(fd, DIOCGDINFO, (char *)&lab) >= 0)) { | ||
132 | pp = &lab.d_partitions[part]; | ||
133 | if (pp->p_size) | ||
134 | return pp->p_size << 9; | ||
135 | } | ||
136 | #endif | ||
137 | #endif /* HAVE_SYS_DISKLABEL_H */ | ||
138 | |||
139 | /* | ||
140 | * OK, we couldn't figure it out by using a specialized ioctl, | ||
141 | * which is generally the best way. So do binary search to | ||
142 | * find the size of the partition. | ||
143 | */ | ||
144 | low = 0; | ||
145 | for (high = 1024; valid_offset(fd, high); high *= 2) | ||
146 | low = high; | ||
147 | while (low < high - 1) | ||
148 | { | ||
149 | const blkid_loff_t mid = (low + high) / 2; | ||
150 | |||
151 | if (valid_offset(fd, mid)) | ||
152 | low = mid; | ||
153 | else | ||
154 | high = mid; | ||
155 | } | ||
156 | return low + 1; | ||
157 | } | ||
158 | |||
159 | #ifdef TEST_PROGRAM | ||
160 | int main(int argc, char **argv) | ||
161 | { | ||
162 | blkid_loff_t bytes; | ||
163 | int fd; | ||
164 | |||
165 | if (argc < 2) { | ||
166 | fprintf(stderr, "Usage: %s device\n" | ||
167 | "Determine the size of a device\n", argv[0]); | ||
168 | return 1; | ||
169 | } | ||
170 | |||
171 | if ((fd = open(argv[1], O_RDONLY)) < 0) | ||
172 | perror(argv[0]); | ||
173 | |||
174 | bytes = blkid_get_dev_size(fd); | ||
175 | printf("Device %s has %lld 1k blocks.\n", argv[1], bytes >> 10); | ||
176 | |||
177 | return 0; | ||
178 | } | ||
179 | #endif | ||
diff --git a/e2fsprogs/blkid/cache.c b/e2fsprogs/blkid/cache.c deleted file mode 100644 index 9bae6fb67..000000000 --- a/e2fsprogs/blkid/cache.c +++ /dev/null | |||
@@ -1,126 +0,0 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * cache.c - allocation/initialization/free routines for cache | ||
4 | * | ||
5 | * Copyright (C) 2001 Andreas Dilger | ||
6 | * Copyright (C) 2003 Theodore Ts'o | ||
7 | * | ||
8 | * %Begin-Header% | ||
9 | * This file may be redistributed under the terms of the | ||
10 | * GNU Lesser General Public License. | ||
11 | * %End-Header% | ||
12 | */ | ||
13 | |||
14 | #include <stdlib.h> | ||
15 | #include <string.h> | ||
16 | #include <unistd.h> | ||
17 | #include "blkidP.h" | ||
18 | |||
19 | int blkid_debug_mask = 0; | ||
20 | |||
21 | int blkid_get_cache(blkid_cache *ret_cache, const char *filename) | ||
22 | { | ||
23 | blkid_cache cache; | ||
24 | |||
25 | #ifdef CONFIG_BLKID_DEBUG | ||
26 | if (!(blkid_debug_mask & DEBUG_INIT)) { | ||
27 | char *dstr = getenv("BLKID_DEBUG"); | ||
28 | |||
29 | if (dstr) | ||
30 | blkid_debug_mask = strtoul(dstr, 0, 0); | ||
31 | blkid_debug_mask |= DEBUG_INIT; | ||
32 | } | ||
33 | #endif | ||
34 | |||
35 | DBG(DEBUG_CACHE, printf("creating blkid cache (using %s)\n", | ||
36 | filename ? filename : "default cache")); | ||
37 | |||
38 | if (!(cache = (blkid_cache) calloc(1, sizeof(struct blkid_struct_cache)))) | ||
39 | return -BLKID_ERR_MEM; | ||
40 | |||
41 | INIT_LIST_HEAD(&cache->bic_devs); | ||
42 | INIT_LIST_HEAD(&cache->bic_tags); | ||
43 | |||
44 | if (filename && !strlen(filename)) | ||
45 | filename = 0; | ||
46 | if (!filename && (getuid() == geteuid())) | ||
47 | filename = getenv("BLKID_FILE"); | ||
48 | if (!filename) | ||
49 | filename = BLKID_CACHE_FILE; | ||
50 | cache->bic_filename = blkid_strdup(filename); | ||
51 | |||
52 | blkid_read_cache(cache); | ||
53 | |||
54 | *ret_cache = cache; | ||
55 | return 0; | ||
56 | } | ||
57 | |||
58 | void blkid_put_cache(blkid_cache cache) | ||
59 | { | ||
60 | if (!cache) | ||
61 | return; | ||
62 | |||
63 | (void) blkid_flush_cache(cache); | ||
64 | |||
65 | DBG(DEBUG_CACHE, printf("freeing cache struct\n")); | ||
66 | |||
67 | /* DBG(DEBUG_CACHE, blkid_debug_dump_cache(cache)); */ | ||
68 | |||
69 | while (!list_empty(&cache->bic_devs)) { | ||
70 | blkid_dev dev = list_entry(cache->bic_devs.next, | ||
71 | struct blkid_struct_dev, | ||
72 | bid_devs); | ||
73 | blkid_free_dev(dev); | ||
74 | } | ||
75 | |||
76 | while (!list_empty(&cache->bic_tags)) { | ||
77 | blkid_tag tag = list_entry(cache->bic_tags.next, | ||
78 | struct blkid_struct_tag, | ||
79 | bit_tags); | ||
80 | |||
81 | while (!list_empty(&tag->bit_names)) { | ||
82 | blkid_tag bad = list_entry(tag->bit_names.next, | ||
83 | struct blkid_struct_tag, | ||
84 | bit_names); | ||
85 | |||
86 | DBG(DEBUG_CACHE, printf("warning: unfreed tag %s=%s\n", | ||
87 | bad->bit_name, bad->bit_val)); | ||
88 | blkid_free_tag(bad); | ||
89 | } | ||
90 | blkid_free_tag(tag); | ||
91 | } | ||
92 | free(cache->bic_filename); | ||
93 | |||
94 | free(cache); | ||
95 | } | ||
96 | |||
97 | #ifdef TEST_PROGRAM | ||
98 | int main(int argc, char** argv) | ||
99 | { | ||
100 | blkid_cache cache = NULL; | ||
101 | int ret; | ||
102 | |||
103 | blkid_debug_mask = DEBUG_ALL; | ||
104 | if ((argc > 2)) { | ||
105 | fprintf(stderr, "Usage: %s [filename]\n", argv[0]); | ||
106 | exit(1); | ||
107 | } | ||
108 | |||
109 | if ((ret = blkid_get_cache(&cache, argv[1])) < 0) { | ||
110 | fprintf(stderr, "error %d parsing cache file %s\n", ret, | ||
111 | argv[1] ? argv[1] : BLKID_CACHE_FILE); | ||
112 | exit(1); | ||
113 | } | ||
114 | if ((ret = blkid_get_cache(&cache, bb_dev_null)) != 0) { | ||
115 | fprintf(stderr, "%s: error creating cache (%d)\n", | ||
116 | argv[0], ret); | ||
117 | exit(1); | ||
118 | } | ||
119 | if ((ret = blkid_probe_all(cache) < 0)) | ||
120 | fprintf(stderr, "error probing devices\n"); | ||
121 | |||
122 | blkid_put_cache(cache); | ||
123 | |||
124 | return ret; | ||
125 | } | ||
126 | #endif | ||
diff --git a/e2fsprogs/blkid/dev.c b/e2fsprogs/blkid/dev.c deleted file mode 100644 index eddbd02b7..000000000 --- a/e2fsprogs/blkid/dev.c +++ /dev/null | |||
@@ -1,214 +0,0 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * dev.c - allocation/initialization/free routines for dev | ||
4 | * | ||
5 | * Copyright (C) 2001 Andreas Dilger | ||
6 | * Copyright (C) 2003 Theodore Ts'o | ||
7 | * | ||
8 | * %Begin-Header% | ||
9 | * This file may be redistributed under the terms of the | ||
10 | * GNU Lesser General Public License. | ||
11 | * %End-Header% | ||
12 | */ | ||
13 | |||
14 | #include <stdlib.h> | ||
15 | #include <string.h> | ||
16 | |||
17 | #include "blkidP.h" | ||
18 | |||
19 | blkid_dev blkid_new_dev(void) | ||
20 | { | ||
21 | blkid_dev dev; | ||
22 | |||
23 | if (!(dev = (blkid_dev) calloc(1, sizeof(struct blkid_struct_dev)))) | ||
24 | return NULL; | ||
25 | |||
26 | INIT_LIST_HEAD(&dev->bid_devs); | ||
27 | INIT_LIST_HEAD(&dev->bid_tags); | ||
28 | |||
29 | return dev; | ||
30 | } | ||
31 | |||
32 | void blkid_free_dev(blkid_dev dev) | ||
33 | { | ||
34 | if (!dev) | ||
35 | return; | ||
36 | |||
37 | DBG(DEBUG_DEV, | ||
38 | printf(" freeing dev %s (%s)\n", dev->bid_name, dev->bid_type)); | ||
39 | DBG(DEBUG_DEV, blkid_debug_dump_dev(dev)); | ||
40 | |||
41 | list_del(&dev->bid_devs); | ||
42 | while (!list_empty(&dev->bid_tags)) { | ||
43 | blkid_tag tag = list_entry(dev->bid_tags.next, | ||
44 | struct blkid_struct_tag, | ||
45 | bit_tags); | ||
46 | blkid_free_tag(tag); | ||
47 | } | ||
48 | if (dev->bid_name) | ||
49 | free(dev->bid_name); | ||
50 | free(dev); | ||
51 | } | ||
52 | |||
53 | /* | ||
54 | * Given a blkid device, return its name | ||
55 | */ | ||
56 | const char *blkid_dev_devname(blkid_dev dev) | ||
57 | { | ||
58 | return dev->bid_name; | ||
59 | } | ||
60 | |||
61 | #ifdef CONFIG_BLKID_DEBUG | ||
62 | void blkid_debug_dump_dev(blkid_dev dev) | ||
63 | { | ||
64 | struct list_head *p; | ||
65 | |||
66 | if (!dev) { | ||
67 | printf(" dev: NULL\n"); | ||
68 | return; | ||
69 | } | ||
70 | |||
71 | printf(" dev: name = %s\n", dev->bid_name); | ||
72 | printf(" dev: DEVNO=\"0x%0llx\"\n", dev->bid_devno); | ||
73 | printf(" dev: TIME=\"%lu\"\n", dev->bid_time); | ||
74 | printf(" dev: PRI=\"%d\"\n", dev->bid_pri); | ||
75 | printf(" dev: flags = 0x%08X\n", dev->bid_flags); | ||
76 | |||
77 | list_for_each(p, &dev->bid_tags) { | ||
78 | blkid_tag tag = list_entry(p, struct blkid_struct_tag, bit_tags); | ||
79 | if (tag) | ||
80 | printf(" tag: %s=\"%s\"\n", tag->bit_name, | ||
81 | tag->bit_val); | ||
82 | else | ||
83 | printf(" tag: NULL\n"); | ||
84 | } | ||
85 | puts(""); | ||
86 | } | ||
87 | #endif | ||
88 | |||
89 | /* | ||
90 | * dev iteration routines for the public libblkid interface. | ||
91 | * | ||
92 | * These routines do not expose the list.h implementation, which are a | ||
93 | * contamination of the namespace, and which force us to reveal far, far | ||
94 | * too much of our internal implemenation. I'm not convinced I want | ||
95 | * to keep list.h in the long term, anyway. It's fine for kernel | ||
96 | * programming, but performance is not the #1 priority for this | ||
97 | * library, and I really don't like the tradeoff of type-safety for | ||
98 | * performance for this application. [tytso:20030125.2007EST] | ||
99 | */ | ||
100 | |||
101 | /* | ||
102 | * This series of functions iterate over all devices in a blkid cache | ||
103 | */ | ||
104 | #define DEV_ITERATE_MAGIC 0x01a5284c | ||
105 | |||
106 | struct blkid_struct_dev_iterate { | ||
107 | int magic; | ||
108 | blkid_cache cache; | ||
109 | struct list_head *p; | ||
110 | }; | ||
111 | |||
112 | blkid_dev_iterate blkid_dev_iterate_begin(blkid_cache cache) | ||
113 | { | ||
114 | blkid_dev_iterate iter; | ||
115 | |||
116 | iter = xmalloc(sizeof(struct blkid_struct_dev_iterate)); | ||
117 | iter->magic = DEV_ITERATE_MAGIC; | ||
118 | iter->cache = cache; | ||
119 | iter->p = cache->bic_devs.next; | ||
120 | return iter; | ||
121 | } | ||
122 | |||
123 | /* | ||
124 | * Return 0 on success, -1 on error | ||
125 | */ | ||
126 | extern int blkid_dev_next(blkid_dev_iterate iter, | ||
127 | blkid_dev *dev) | ||
128 | { | ||
129 | *dev = 0; | ||
130 | if (!iter || iter->magic != DEV_ITERATE_MAGIC || | ||
131 | iter->p == &iter->cache->bic_devs) | ||
132 | return -1; | ||
133 | *dev = list_entry(iter->p, struct blkid_struct_dev, bid_devs); | ||
134 | iter->p = iter->p->next; | ||
135 | return 0; | ||
136 | } | ||
137 | |||
138 | void blkid_dev_iterate_end(blkid_dev_iterate iter) | ||
139 | { | ||
140 | if (!iter || iter->magic != DEV_ITERATE_MAGIC) | ||
141 | return; | ||
142 | iter->magic = 0; | ||
143 | free(iter); | ||
144 | } | ||
145 | |||
146 | #ifdef TEST_PROGRAM | ||
147 | #ifdef HAVE_GETOPT_H | ||
148 | #include <getopt.h> | ||
149 | #else | ||
150 | extern char *optarg; | ||
151 | extern int optind; | ||
152 | #endif | ||
153 | |||
154 | void usage(char *prog) | ||
155 | { | ||
156 | fprintf(stderr, "Usage: %s [-f blkid_file] [-m debug_mask]\n", prog); | ||
157 | fprintf(stderr, "\tList all devices and exit\n", prog); | ||
158 | exit(1); | ||
159 | } | ||
160 | |||
161 | int main(int argc, char **argv) | ||
162 | { | ||
163 | blkid_dev_iterate iter; | ||
164 | blkid_cache cache = NULL; | ||
165 | blkid_dev dev; | ||
166 | int c, ret; | ||
167 | char *tmp; | ||
168 | char *file = NULL; | ||
169 | char *search_type = NULL; | ||
170 | char *search_value = NULL; | ||
171 | |||
172 | while ((c = getopt (argc, argv, "m:f:")) != EOF) | ||
173 | switch (c) { | ||
174 | case 'f': | ||
175 | file = optarg; | ||
176 | break; | ||
177 | case 'm': | ||
178 | blkid_debug_mask = strtoul (optarg, &tmp, 0); | ||
179 | if (*tmp) { | ||
180 | fprintf(stderr, "Invalid debug mask: %d\n", | ||
181 | optarg); | ||
182 | exit(1); | ||
183 | } | ||
184 | break; | ||
185 | case '?': | ||
186 | usage(argv[0]); | ||
187 | } | ||
188 | if (argc >= optind+2) { | ||
189 | search_type = argv[optind]; | ||
190 | search_value = argv[optind+1]; | ||
191 | optind += 2; | ||
192 | } | ||
193 | if (argc != optind) | ||
194 | usage(argv[0]); | ||
195 | |||
196 | if ((ret = blkid_get_cache(&cache, file)) != 0) { | ||
197 | fprintf(stderr, "%s: error creating cache (%d)\n", | ||
198 | argv[0], ret); | ||
199 | exit(1); | ||
200 | } | ||
201 | |||
202 | iter = blkid_dev_iterate_begin(cache); | ||
203 | if (search_type) | ||
204 | blkid_dev_set_search(iter, search_type, search_value); | ||
205 | while (blkid_dev_next(iter, &dev) == 0) { | ||
206 | printf("Device: %s\n", blkid_dev_devname(dev)); | ||
207 | } | ||
208 | blkid_dev_iterate_end(iter); | ||
209 | |||
210 | |||
211 | blkid_put_cache(cache); | ||
212 | return 0; | ||
213 | } | ||
214 | #endif | ||
diff --git a/e2fsprogs/blkid/devname.c b/e2fsprogs/blkid/devname.c deleted file mode 100644 index 3d11734d5..000000000 --- a/e2fsprogs/blkid/devname.c +++ /dev/null | |||
@@ -1,368 +0,0 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * devname.c - get a dev by its device inode name | ||
4 | * | ||
5 | * Copyright (C) Andries Brouwer | ||
6 | * Copyright (C) 1999, 2000, 2001, 2002, 2003 Theodore Ts'o | ||
7 | * Copyright (C) 2001 Andreas Dilger | ||
8 | * | ||
9 | * %Begin-Header% | ||
10 | * This file may be redistributed under the terms of the | ||
11 | * GNU Lesser General Public License. | ||
12 | * %End-Header% | ||
13 | */ | ||
14 | |||
15 | #include <stdio.h> | ||
16 | #include <string.h> | ||
17 | #ifdef HAVE_UNISTD_H | ||
18 | #include <unistd.h> | ||
19 | #endif | ||
20 | #include <stdlib.h> | ||
21 | #include <string.h> | ||
22 | #include <ctype.h> | ||
23 | #ifdef HAVE_SYS_TYPES_H | ||
24 | #include <sys/types.h> | ||
25 | #endif | ||
26 | #include <sys/stat.h> | ||
27 | #ifdef HAVE_ERRNO_H | ||
28 | #include <errno.h> | ||
29 | #endif | ||
30 | #ifdef HAVE_SYS_MKDEV_H | ||
31 | #include <sys/mkdev.h> | ||
32 | #endif | ||
33 | #include <time.h> | ||
34 | |||
35 | #include "blkidP.h" | ||
36 | |||
37 | /* | ||
38 | * Find a dev struct in the cache by device name, if available. | ||
39 | * | ||
40 | * If there is no entry with the specified device name, and the create | ||
41 | * flag is set, then create an empty device entry. | ||
42 | */ | ||
43 | blkid_dev blkid_get_dev(blkid_cache cache, const char *devname, int flags) | ||
44 | { | ||
45 | blkid_dev dev = NULL, tmp; | ||
46 | struct list_head *p; | ||
47 | |||
48 | if (!cache || !devname) | ||
49 | return NULL; | ||
50 | |||
51 | list_for_each(p, &cache->bic_devs) { | ||
52 | tmp = list_entry(p, struct blkid_struct_dev, bid_devs); | ||
53 | if (strcmp(tmp->bid_name, devname)) | ||
54 | continue; | ||
55 | |||
56 | DBG(DEBUG_DEVNAME, | ||
57 | printf("found devname %s in cache\n", tmp->bid_name)); | ||
58 | dev = tmp; | ||
59 | break; | ||
60 | } | ||
61 | |||
62 | if (!dev && (flags & BLKID_DEV_CREATE)) { | ||
63 | dev = blkid_new_dev(); | ||
64 | if (!dev) | ||
65 | return NULL; | ||
66 | dev->bid_name = blkid_strdup(devname); | ||
67 | dev->bid_cache = cache; | ||
68 | list_add_tail(&dev->bid_devs, &cache->bic_devs); | ||
69 | cache->bic_flags |= BLKID_BIC_FL_CHANGED; | ||
70 | } | ||
71 | |||
72 | if (flags & BLKID_DEV_VERIFY) | ||
73 | dev = blkid_verify(cache, dev); | ||
74 | return dev; | ||
75 | } | ||
76 | |||
77 | /* | ||
78 | * Probe a single block device to add to the device cache. | ||
79 | */ | ||
80 | static void probe_one(blkid_cache cache, const char *ptname, | ||
81 | dev_t devno, int pri) | ||
82 | { | ||
83 | blkid_dev dev = NULL; | ||
84 | struct list_head *p; | ||
85 | const char **dir; | ||
86 | char *devname = NULL; | ||
87 | |||
88 | /* See if we already have this device number in the cache. */ | ||
89 | list_for_each(p, &cache->bic_devs) { | ||
90 | blkid_dev tmp = list_entry(p, struct blkid_struct_dev, | ||
91 | bid_devs); | ||
92 | if (tmp->bid_devno == devno) { | ||
93 | dev = blkid_verify(cache, tmp); | ||
94 | break; | ||
95 | } | ||
96 | } | ||
97 | if (dev && dev->bid_devno == devno) | ||
98 | goto set_pri; | ||
99 | |||
100 | /* | ||
101 | * Take a quick look at /dev/ptname for the device number. We check | ||
102 | * all of the likely device directories. If we don't find it, or if | ||
103 | * the stat information doesn't check out, use blkid_devno_to_devname() | ||
104 | * to find it via an exhaustive search for the device major/minor. | ||
105 | */ | ||
106 | for (dir = blkid_devdirs; *dir; dir++) { | ||
107 | struct stat st; | ||
108 | char device[256]; | ||
109 | |||
110 | sprintf(device, "%s/%s", *dir, ptname); | ||
111 | if ((dev = blkid_get_dev(cache, device, BLKID_DEV_FIND)) && | ||
112 | dev->bid_devno == devno) | ||
113 | goto set_pri; | ||
114 | |||
115 | if (stat(device, &st) == 0 && S_ISBLK(st.st_mode) && | ||
116 | st.st_rdev == devno) { | ||
117 | devname = blkid_strdup(device); | ||
118 | break; | ||
119 | } | ||
120 | } | ||
121 | if (!devname) { | ||
122 | devname = blkid_devno_to_devname(devno); | ||
123 | if (!devname) | ||
124 | return; | ||
125 | } | ||
126 | dev = blkid_get_dev(cache, devname, BLKID_DEV_NORMAL); | ||
127 | free(devname); | ||
128 | |||
129 | set_pri: | ||
130 | if (!pri && !strncmp(ptname, "md", 2)) | ||
131 | pri = BLKID_PRI_MD; | ||
132 | if (dev) | ||
133 | dev->bid_pri = pri; | ||
134 | return; | ||
135 | } | ||
136 | |||
137 | #define PROC_PARTITIONS "/proc/partitions" | ||
138 | #define VG_DIR "/proc/lvm/VGs" | ||
139 | |||
140 | /* | ||
141 | * This function initializes the UUID cache with devices from the LVM | ||
142 | * proc hierarchy. We currently depend on the names of the LVM | ||
143 | * hierarchy giving us the device structure in /dev. (XXX is this a | ||
144 | * safe thing to do?) | ||
145 | */ | ||
146 | #ifdef VG_DIR | ||
147 | #include <dirent.h> | ||
148 | static dev_t lvm_get_devno(const char *lvm_device) | ||
149 | { | ||
150 | FILE *lvf; | ||
151 | char buf[1024]; | ||
152 | int ma, mi; | ||
153 | dev_t ret = 0; | ||
154 | |||
155 | DBG(DEBUG_DEVNAME, printf("opening %s\n", lvm_device)); | ||
156 | if ((lvf = fopen(lvm_device, "r")) == NULL) { | ||
157 | DBG(DEBUG_DEVNAME, printf("%s: (%d) %s\n", lvm_device, errno, | ||
158 | strerror(errno))); | ||
159 | return 0; | ||
160 | } | ||
161 | |||
162 | while (fgets(buf, sizeof(buf), lvf)) { | ||
163 | if (sscanf(buf, "device: %d:%d", &ma, &mi) == 2) { | ||
164 | ret = makedev(ma, mi); | ||
165 | break; | ||
166 | } | ||
167 | } | ||
168 | fclose(lvf); | ||
169 | |||
170 | return ret; | ||
171 | } | ||
172 | |||
173 | static void lvm_probe_all(blkid_cache cache) | ||
174 | { | ||
175 | DIR *vg_list; | ||
176 | struct dirent *vg_iter; | ||
177 | int vg_len = strlen(VG_DIR); | ||
178 | dev_t dev; | ||
179 | |||
180 | if ((vg_list = opendir(VG_DIR)) == NULL) | ||
181 | return; | ||
182 | |||
183 | DBG(DEBUG_DEVNAME, printf("probing LVM devices under %s\n", VG_DIR)); | ||
184 | |||
185 | while ((vg_iter = readdir(vg_list)) != NULL) { | ||
186 | DIR *lv_list; | ||
187 | char *vdirname; | ||
188 | char *vg_name; | ||
189 | struct dirent *lv_iter; | ||
190 | |||
191 | vg_name = vg_iter->d_name; | ||
192 | if (LONE_CHAR(vg_name, '.') || !strcmp(vg_name, "..")) | ||
193 | continue; | ||
194 | vdirname = xmalloc(vg_len + strlen(vg_name) + 8); | ||
195 | sprintf(vdirname, "%s/%s/LVs", VG_DIR, vg_name); | ||
196 | |||
197 | lv_list = opendir(vdirname); | ||
198 | free(vdirname); | ||
199 | if (lv_list == NULL) | ||
200 | continue; | ||
201 | |||
202 | while ((lv_iter = readdir(lv_list)) != NULL) { | ||
203 | char *lv_name, *lvm_device; | ||
204 | |||
205 | lv_name = lv_iter->d_name; | ||
206 | if (LONE_CHAR(lv_name, '.') || !strcmp(lv_name, "..")) | ||
207 | continue; | ||
208 | |||
209 | lvm_device = xmalloc(vg_len + strlen(vg_name) + | ||
210 | strlen(lv_name) + 8); | ||
211 | sprintf(lvm_device, "%s/%s/LVs/%s", VG_DIR, vg_name, | ||
212 | lv_name); | ||
213 | dev = lvm_get_devno(lvm_device); | ||
214 | sprintf(lvm_device, "%s/%s", vg_name, lv_name); | ||
215 | DBG(DEBUG_DEVNAME, printf("LVM dev %s: devno 0x%04X\n", | ||
216 | lvm_device, | ||
217 | (unsigned int) dev)); | ||
218 | probe_one(cache, lvm_device, dev, BLKID_PRI_LVM); | ||
219 | free(lvm_device); | ||
220 | } | ||
221 | closedir(lv_list); | ||
222 | } | ||
223 | closedir(vg_list); | ||
224 | } | ||
225 | #endif | ||
226 | |||
227 | #define PROC_EVMS_VOLUMES "/proc/evms/volumes" | ||
228 | |||
229 | static int | ||
230 | evms_probe_all(blkid_cache cache) | ||
231 | { | ||
232 | char line[100]; | ||
233 | int ma, mi, sz, num = 0; | ||
234 | FILE *procpt; | ||
235 | char device[110]; | ||
236 | |||
237 | procpt = fopen(PROC_EVMS_VOLUMES, "r"); | ||
238 | if (!procpt) | ||
239 | return 0; | ||
240 | while (fgets(line, sizeof(line), procpt)) { | ||
241 | if (sscanf (line, " %d %d %d %*s %*s %[^\n ]", | ||
242 | &ma, &mi, &sz, device) != 4) | ||
243 | continue; | ||
244 | |||
245 | DBG(DEBUG_DEVNAME, printf("Checking partition %s (%d, %d)\n", | ||
246 | device, ma, mi)); | ||
247 | |||
248 | probe_one(cache, device, makedev(ma, mi), BLKID_PRI_EVMS); | ||
249 | num++; | ||
250 | } | ||
251 | fclose(procpt); | ||
252 | return num; | ||
253 | } | ||
254 | |||
255 | /* | ||
256 | * Read the device data for all available block devices in the system. | ||
257 | */ | ||
258 | int blkid_probe_all(blkid_cache cache) | ||
259 | { | ||
260 | FILE *proc; | ||
261 | char line[1024]; | ||
262 | char ptname0[128], ptname1[128], *ptname = 0; | ||
263 | char *ptnames[2]; | ||
264 | dev_t devs[2]; | ||
265 | int ma, mi; | ||
266 | unsigned long long sz; | ||
267 | int lens[2] = { 0, 0 }; | ||
268 | int which = 0, last = 0; | ||
269 | |||
270 | ptnames[0] = ptname0; | ||
271 | ptnames[1] = ptname1; | ||
272 | |||
273 | if (!cache) | ||
274 | return -BLKID_ERR_PARAM; | ||
275 | |||
276 | if (cache->bic_flags & BLKID_BIC_FL_PROBED && | ||
277 | time(0) - cache->bic_time < BLKID_PROBE_INTERVAL) | ||
278 | return 0; | ||
279 | |||
280 | blkid_read_cache(cache); | ||
281 | evms_probe_all(cache); | ||
282 | #ifdef VG_DIR | ||
283 | lvm_probe_all(cache); | ||
284 | #endif | ||
285 | |||
286 | proc = fopen(PROC_PARTITIONS, "r"); | ||
287 | if (!proc) | ||
288 | return -BLKID_ERR_PROC; | ||
289 | |||
290 | while (fgets(line, sizeof(line), proc)) { | ||
291 | last = which; | ||
292 | which ^= 1; | ||
293 | ptname = ptnames[which]; | ||
294 | |||
295 | if (sscanf(line, " %d %d %llu %128[^\n ]", | ||
296 | &ma, &mi, &sz, ptname) != 4) | ||
297 | continue; | ||
298 | devs[which] = makedev(ma, mi); | ||
299 | |||
300 | DBG(DEBUG_DEVNAME, printf("read partition name %s\n", ptname)); | ||
301 | |||
302 | /* Skip whole disk devs unless they have no partitions | ||
303 | * If we don't have a partition on this dev, also | ||
304 | * check previous dev to see if it didn't have a partn. | ||
305 | * heuristic: partition name ends in a digit. | ||
306 | * | ||
307 | * Skip extended partitions. | ||
308 | * heuristic: size is 1 | ||
309 | * | ||
310 | * FIXME: skip /dev/{ida,cciss,rd} whole-disk devs | ||
311 | */ | ||
312 | |||
313 | lens[which] = strlen(ptname); | ||
314 | if (isdigit(ptname[lens[which] - 1])) { | ||
315 | DBG(DEBUG_DEVNAME, | ||
316 | printf("partition dev %s, devno 0x%04X\n", | ||
317 | ptname, (unsigned int) devs[which])); | ||
318 | |||
319 | if (sz > 1) | ||
320 | probe_one(cache, ptname, devs[which], 0); | ||
321 | lens[which] = 0; | ||
322 | lens[last] = 0; | ||
323 | } else if (lens[last] && strncmp(ptnames[last], ptname, | ||
324 | lens[last])) { | ||
325 | DBG(DEBUG_DEVNAME, | ||
326 | printf("whole dev %s, devno 0x%04X\n", | ||
327 | ptnames[last], (unsigned int) devs[last])); | ||
328 | probe_one(cache, ptnames[last], devs[last], 0); | ||
329 | lens[last] = 0; | ||
330 | } | ||
331 | } | ||
332 | |||
333 | /* Handle the last device if it wasn't partitioned */ | ||
334 | if (lens[which]) | ||
335 | probe_one(cache, ptname, devs[which], 0); | ||
336 | |||
337 | fclose(proc); | ||
338 | |||
339 | cache->bic_time = time(0); | ||
340 | cache->bic_flags |= BLKID_BIC_FL_PROBED; | ||
341 | blkid_flush_cache(cache); | ||
342 | return 0; | ||
343 | } | ||
344 | |||
345 | #ifdef TEST_PROGRAM | ||
346 | int main(int argc, char **argv) | ||
347 | { | ||
348 | blkid_cache cache = NULL; | ||
349 | int ret; | ||
350 | |||
351 | blkid_debug_mask = DEBUG_ALL; | ||
352 | if (argc != 1) { | ||
353 | fprintf(stderr, "Usage: %s\n" | ||
354 | "Probe all devices and exit\n", argv[0]); | ||
355 | exit(1); | ||
356 | } | ||
357 | if ((ret = blkid_get_cache(&cache, bb_dev_null)) != 0) { | ||
358 | fprintf(stderr, "%s: error creating cache (%d)\n", | ||
359 | argv[0], ret); | ||
360 | exit(1); | ||
361 | } | ||
362 | if (blkid_probe_all(cache) < 0) | ||
363 | printf("%s: error probing devices\n", argv[0]); | ||
364 | |||
365 | blkid_put_cache(cache); | ||
366 | return 0; | ||
367 | } | ||
368 | #endif | ||
diff --git a/e2fsprogs/blkid/devno.c b/e2fsprogs/blkid/devno.c deleted file mode 100644 index 13e7f1a87..000000000 --- a/e2fsprogs/blkid/devno.c +++ /dev/null | |||
@@ -1,223 +0,0 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * devno.c - find a particular device by its device number (major/minor) | ||
4 | * | ||
5 | * Copyright (C) 2000, 2001, 2003 Theodore Ts'o | ||
6 | * Copyright (C) 2001 Andreas Dilger | ||
7 | * | ||
8 | * %Begin-Header% | ||
9 | * This file may be redistributed under the terms of the | ||
10 | * GNU Lesser General Public License. | ||
11 | * %End-Header% | ||
12 | */ | ||
13 | |||
14 | #include <stdio.h> | ||
15 | #include <string.h> | ||
16 | #ifdef HAVE_UNISTD_H | ||
17 | #include <unistd.h> | ||
18 | #endif | ||
19 | #include <stdlib.h> | ||
20 | #include <string.h> | ||
21 | #ifdef HAVE_SYS_TYPES_H | ||
22 | #include <sys/types.h> | ||
23 | #endif | ||
24 | #include <sys/stat.h> | ||
25 | #include <dirent.h> | ||
26 | #ifdef HAVE_ERRNO_H | ||
27 | #include <errno.h> | ||
28 | #endif | ||
29 | #ifdef HAVE_SYS_MKDEV_H | ||
30 | #include <sys/mkdev.h> | ||
31 | #endif | ||
32 | |||
33 | #include "blkidP.h" | ||
34 | |||
35 | struct dir_list { | ||
36 | char *name; | ||
37 | struct dir_list *next; | ||
38 | }; | ||
39 | |||
40 | char *blkid_strndup(const char *s, int length) | ||
41 | { | ||
42 | char *ret; | ||
43 | |||
44 | if (!s) | ||
45 | return NULL; | ||
46 | |||
47 | if (!length) | ||
48 | length = strlen(s); | ||
49 | |||
50 | ret = xmalloc(length + 1); | ||
51 | strncpy(ret, s, length); | ||
52 | ret[length] = '\0'; | ||
53 | return ret; | ||
54 | } | ||
55 | |||
56 | char *blkid_strdup(const char *s) | ||
57 | { | ||
58 | return blkid_strndup(s, 0); | ||
59 | } | ||
60 | |||
61 | /* | ||
62 | * This function adds an entry to the directory list | ||
63 | */ | ||
64 | static void add_to_dirlist(const char *name, struct dir_list **list) | ||
65 | { | ||
66 | struct dir_list *dp; | ||
67 | |||
68 | dp = xmalloc(sizeof(struct dir_list)); | ||
69 | dp->name = blkid_strdup(name); | ||
70 | dp->next = *list; | ||
71 | *list = dp; | ||
72 | } | ||
73 | |||
74 | /* | ||
75 | * This function frees a directory list | ||
76 | */ | ||
77 | static void free_dirlist(struct dir_list **list) | ||
78 | { | ||
79 | struct dir_list *dp, *next; | ||
80 | |||
81 | for (dp = *list; dp; dp = next) { | ||
82 | next = dp->next; | ||
83 | free(dp->name); | ||
84 | free(dp); | ||
85 | } | ||
86 | *list = NULL; | ||
87 | } | ||
88 | |||
89 | static void scan_dir(char *dir_name, dev_t devno, struct dir_list **list, | ||
90 | char **devname) | ||
91 | { | ||
92 | DIR *dir; | ||
93 | struct dirent *dp; | ||
94 | char path[1024]; | ||
95 | int dirlen; | ||
96 | struct stat st; | ||
97 | |||
98 | if ((dir = opendir(dir_name)) == NULL) | ||
99 | return; | ||
100 | dirlen = strlen(dir_name) + 2; | ||
101 | while ((dp = readdir(dir)) != 0) { | ||
102 | if (dirlen + strlen(dp->d_name) >= sizeof(path)) | ||
103 | continue; | ||
104 | |||
105 | if (dp->d_name[0] == '.' && | ||
106 | ((dp->d_name[1] == 0) || | ||
107 | ((dp->d_name[1] == '.') && (dp->d_name[2] == 0)))) | ||
108 | continue; | ||
109 | |||
110 | sprintf(path, "%s/%s", dir_name, dp->d_name); | ||
111 | if (stat(path, &st) < 0) | ||
112 | continue; | ||
113 | |||
114 | if (S_ISDIR(st.st_mode)) | ||
115 | add_to_dirlist(path, list); | ||
116 | else if (S_ISBLK(st.st_mode) && st.st_rdev == devno) { | ||
117 | *devname = blkid_strdup(path); | ||
118 | DBG(DEBUG_DEVNO, | ||
119 | printf("found 0x%llx at %s (%p)\n", devno, | ||
120 | path, *devname)); | ||
121 | break; | ||
122 | } | ||
123 | } | ||
124 | closedir(dir); | ||
125 | return; | ||
126 | } | ||
127 | |||
128 | /* Directories where we will try to search for device numbers */ | ||
129 | const char *blkid_devdirs[] = { "/devices", "/devfs", "/dev", NULL }; | ||
130 | |||
131 | /* | ||
132 | * This function finds the pathname to a block device with a given | ||
133 | * device number. It returns a pointer to allocated memory to the | ||
134 | * pathname on success, and NULL on failure. | ||
135 | */ | ||
136 | char *blkid_devno_to_devname(dev_t devno) | ||
137 | { | ||
138 | struct dir_list *list = NULL, *new_list = NULL; | ||
139 | char *devname = NULL; | ||
140 | const char **dir; | ||
141 | |||
142 | /* | ||
143 | * Add the starting directories to search in reverse order of | ||
144 | * importance, since we are using a stack... | ||
145 | */ | ||
146 | for (dir = blkid_devdirs; *dir; dir++) | ||
147 | add_to_dirlist(*dir, &list); | ||
148 | |||
149 | while (list) { | ||
150 | struct dir_list *current = list; | ||
151 | |||
152 | list = list->next; | ||
153 | DBG(DEBUG_DEVNO, printf("directory %s\n", current->name)); | ||
154 | scan_dir(current->name, devno, &new_list, &devname); | ||
155 | free(current->name); | ||
156 | free(current); | ||
157 | if (devname) | ||
158 | break; | ||
159 | /* | ||
160 | * If we're done checking at this level, descend to | ||
161 | * the next level of subdirectories. (breadth-first) | ||
162 | */ | ||
163 | if (list == NULL) { | ||
164 | list = new_list; | ||
165 | new_list = NULL; | ||
166 | } | ||
167 | } | ||
168 | free_dirlist(&list); | ||
169 | free_dirlist(&new_list); | ||
170 | |||
171 | if (!devname) { | ||
172 | DBG(DEBUG_DEVNO, | ||
173 | printf("blkid: cannot find devno 0x%04lx\n", | ||
174 | (unsigned long) devno)); | ||
175 | } else { | ||
176 | DBG(DEBUG_DEVNO, | ||
177 | printf("found devno 0x%04llx as %s\n", devno, devname)); | ||
178 | } | ||
179 | |||
180 | |||
181 | return devname; | ||
182 | } | ||
183 | |||
184 | #ifdef TEST_PROGRAM | ||
185 | int main(int argc, char** argv) | ||
186 | { | ||
187 | char *devname, *tmp; | ||
188 | int major, minor; | ||
189 | dev_t devno; | ||
190 | const char *errmsg = "Cannot parse %s: %s\n"; | ||
191 | |||
192 | blkid_debug_mask = DEBUG_ALL; | ||
193 | if ((argc != 2) && (argc != 3)) { | ||
194 | fprintf(stderr, "Usage:\t%s device_number\n\t%s major minor\n" | ||
195 | "Resolve a device number to a device name\n", | ||
196 | argv[0], argv[0]); | ||
197 | exit(1); | ||
198 | } | ||
199 | if (argc == 2) { | ||
200 | devno = strtoul(argv[1], &tmp, 0); | ||
201 | if (*tmp) { | ||
202 | fprintf(stderr, errmsg, "device number", argv[1]); | ||
203 | exit(1); | ||
204 | } | ||
205 | } else { | ||
206 | major = strtoul(argv[1], &tmp, 0); | ||
207 | if (*tmp) { | ||
208 | fprintf(stderr, errmsg, "major number", argv[1]); | ||
209 | exit(1); | ||
210 | } | ||
211 | minor = strtoul(argv[2], &tmp, 0); | ||
212 | if (*tmp) { | ||
213 | fprintf(stderr, errmsg, "minor number", argv[2]); | ||
214 | exit(1); | ||
215 | } | ||
216 | devno = makedev(major, minor); | ||
217 | } | ||
218 | printf("Looking for device 0x%04Lx\n", devno); | ||
219 | devname = blkid_devno_to_devname(devno); | ||
220 | free(devname); | ||
221 | return 0; | ||
222 | } | ||
223 | #endif | ||
diff --git a/e2fsprogs/blkid/list.c b/e2fsprogs/blkid/list.c deleted file mode 100644 index 04d61a19b..000000000 --- a/e2fsprogs/blkid/list.c +++ /dev/null | |||
@@ -1,110 +0,0 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | |||
3 | #include "list.h" | ||
4 | |||
5 | /* | ||
6 | * Insert a new entry between two known consecutive entries. | ||
7 | * | ||
8 | * This is only for internal list manipulation where we know | ||
9 | * the prev/next entries already! | ||
10 | */ | ||
11 | void __list_add(struct list_head * add, | ||
12 | struct list_head * prev, | ||
13 | struct list_head * next) | ||
14 | { | ||
15 | next->prev = add; | ||
16 | add->next = next; | ||
17 | add->prev = prev; | ||
18 | prev->next = add; | ||
19 | } | ||
20 | |||
21 | /* | ||
22 | * list_add - add a new entry | ||
23 | * @add: new entry to be added | ||
24 | * @head: list head to add it after | ||
25 | * | ||
26 | * Insert a new entry after the specified head. | ||
27 | * This is good for implementing stacks. | ||
28 | */ | ||
29 | void list_add(struct list_head *add, struct list_head *head) | ||
30 | { | ||
31 | __list_add(add, head, head->next); | ||
32 | } | ||
33 | |||
34 | /* | ||
35 | * list_add_tail - add a new entry | ||
36 | * @add: new entry to be added | ||
37 | * @head: list head to add it before | ||
38 | * | ||
39 | * Insert a new entry before the specified head. | ||
40 | * This is useful for implementing queues. | ||
41 | */ | ||
42 | void list_add_tail(struct list_head *add, struct list_head *head) | ||
43 | { | ||
44 | __list_add(add, head->prev, head); | ||
45 | } | ||
46 | |||
47 | /* | ||
48 | * Delete a list entry by making the prev/next entries | ||
49 | * point to each other. | ||
50 | * | ||
51 | * This is only for internal list manipulation where we know | ||
52 | * the prev/next entries already! | ||
53 | */ | ||
54 | void __list_del(struct list_head * prev, struct list_head * next) | ||
55 | { | ||
56 | next->prev = prev; | ||
57 | prev->next = next; | ||
58 | } | ||
59 | |||
60 | /* | ||
61 | * list_del - deletes entry from list. | ||
62 | * @entry: the element to delete from the list. | ||
63 | * | ||
64 | * list_empty() on @entry does not return true after this, @entry is | ||
65 | * in an undefined state. | ||
66 | */ | ||
67 | void list_del(struct list_head *entry) | ||
68 | { | ||
69 | __list_del(entry->prev, entry->next); | ||
70 | } | ||
71 | |||
72 | /* | ||
73 | * list_del_init - deletes entry from list and reinitialize it. | ||
74 | * @entry: the element to delete from the list. | ||
75 | */ | ||
76 | void list_del_init(struct list_head *entry) | ||
77 | { | ||
78 | __list_del(entry->prev, entry->next); | ||
79 | INIT_LIST_HEAD(entry); | ||
80 | } | ||
81 | |||
82 | /* | ||
83 | * list_empty - tests whether a list is empty | ||
84 | * @head: the list to test. | ||
85 | */ | ||
86 | int list_empty(struct list_head *head) | ||
87 | { | ||
88 | return head->next == head; | ||
89 | } | ||
90 | |||
91 | /* | ||
92 | * list_splice - join two lists | ||
93 | * @list: the new list to add. | ||
94 | * @head: the place to add it in the first list. | ||
95 | */ | ||
96 | void list_splice(struct list_head *list, struct list_head *head) | ||
97 | { | ||
98 | struct list_head *first = list->next; | ||
99 | |||
100 | if (first != list) { | ||
101 | struct list_head *last = list->prev; | ||
102 | struct list_head *at = head->next; | ||
103 | |||
104 | first->prev = head; | ||
105 | head->next = first; | ||
106 | |||
107 | last->next = at; | ||
108 | at->prev = last; | ||
109 | } | ||
110 | } | ||
diff --git a/e2fsprogs/blkid/list.h b/e2fsprogs/blkid/list.h deleted file mode 100644 index 8b06d853b..000000000 --- a/e2fsprogs/blkid/list.h +++ /dev/null | |||
@@ -1,73 +0,0 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | #if !defined(_BLKID_LIST_H) && !defined(LIST_HEAD) | ||
3 | #define _BLKID_LIST_H | ||
4 | |||
5 | #ifdef __cplusplus | ||
6 | extern "C" { | ||
7 | #endif | ||
8 | |||
9 | /* | ||
10 | * Simple doubly linked list implementation. | ||
11 | * | ||
12 | * Some of the internal functions ("__xxx") are useful when | ||
13 | * manipulating whole lists rather than single entries, as | ||
14 | * sometimes we already know the next/prev entries and we can | ||
15 | * generate better code by using them directly rather than | ||
16 | * using the generic single-entry routines. | ||
17 | */ | ||
18 | |||
19 | struct list_head { | ||
20 | struct list_head *next, *prev; | ||
21 | }; | ||
22 | |||
23 | #define LIST_HEAD_INIT(name) { &(name), &(name) } | ||
24 | |||
25 | #define LIST_HEAD(name) \ | ||
26 | struct list_head name = LIST_HEAD_INIT(name) | ||
27 | |||
28 | #define INIT_LIST_HEAD(ptr) do { \ | ||
29 | (ptr)->next = (ptr); (ptr)->prev = (ptr); \ | ||
30 | } while (0) | ||
31 | |||
32 | void __list_add(struct list_head * add, struct list_head * prev, struct list_head * next); | ||
33 | void list_add(struct list_head *add, struct list_head *head); | ||
34 | void list_add_tail(struct list_head *add, struct list_head *head); | ||
35 | void __list_del(struct list_head * prev, struct list_head * next); | ||
36 | void list_del(struct list_head *entry); | ||
37 | void list_del_init(struct list_head *entry); | ||
38 | int list_empty(struct list_head *head); | ||
39 | void list_splice(struct list_head *list, struct list_head *head); | ||
40 | |||
41 | /** | ||
42 | * list_entry - get the struct for this entry | ||
43 | * @ptr: the &struct list_head pointer. | ||
44 | * @type: the type of the struct this is embedded in. | ||
45 | * @member: the name of the list_struct within the struct. | ||
46 | */ | ||
47 | #define list_entry(ptr, type, member) \ | ||
48 | ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member))) | ||
49 | |||
50 | /** | ||
51 | * list_for_each - iterate over elements in a list | ||
52 | * @pos: the &struct list_head to use as a loop counter. | ||
53 | * @head: the head for your list. | ||
54 | */ | ||
55 | #define list_for_each(pos, head) \ | ||
56 | for (pos = (head)->next; pos != (head); pos = pos->next) | ||
57 | |||
58 | /** | ||
59 | * list_for_each_safe - iterate over elements in a list, but don't dereference | ||
60 | * pos after the body is done (in case it is freed) | ||
61 | * @pos: the &struct list_head to use as a loop counter. | ||
62 | * @pnext: the &struct list_head to use as a pointer to the next item. | ||
63 | * @head: the head for your list (not included in iteration). | ||
64 | */ | ||
65 | #define list_for_each_safe(pos, pnext, head) \ | ||
66 | for (pos = (head)->next, pnext = pos->next; pos != (head); \ | ||
67 | pos = pnext, pnext = pos->next) | ||
68 | |||
69 | #ifdef __cplusplus | ||
70 | } | ||
71 | #endif | ||
72 | |||
73 | #endif /* _BLKID_LIST_H */ | ||
diff --git a/e2fsprogs/blkid/probe.c b/e2fsprogs/blkid/probe.c deleted file mode 100644 index 8c6e2aa33..000000000 --- a/e2fsprogs/blkid/probe.c +++ /dev/null | |||
@@ -1,721 +0,0 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * probe.c - identify a block device by its contents, and return a dev | ||
4 | * struct with the details | ||
5 | * | ||
6 | * Copyright (C) 1999 by Andries Brouwer | ||
7 | * Copyright (C) 1999, 2000, 2003 by Theodore Ts'o | ||
8 | * Copyright (C) 2001 by Andreas Dilger | ||
9 | * | ||
10 | * %Begin-Header% | ||
11 | * This file may be redistributed under the terms of the | ||
12 | * GNU Lesser General Public License. | ||
13 | * %End-Header% | ||
14 | */ | ||
15 | |||
16 | #include <stdio.h> | ||
17 | #include <string.h> | ||
18 | #include <stdlib.h> | ||
19 | #include <unistd.h> | ||
20 | #include <fcntl.h> | ||
21 | #include <sys/types.h> | ||
22 | #ifdef HAVE_SYS_STAT_H | ||
23 | #include <sys/stat.h> | ||
24 | #endif | ||
25 | #ifdef HAVE_SYS_MKDEV_H | ||
26 | #include <sys/mkdev.h> | ||
27 | #endif | ||
28 | #ifdef HAVE_ERRNO_H | ||
29 | #include <errno.h> | ||
30 | #endif | ||
31 | #include "blkidP.h" | ||
32 | #include "../uuid/uuid.h" | ||
33 | #include "probe.h" | ||
34 | |||
35 | /* | ||
36 | * This is a special case code to check for an MDRAID device. We do | ||
37 | * this special since it requires checking for a superblock at the end | ||
38 | * of the device. | ||
39 | */ | ||
40 | static int check_mdraid(int fd, unsigned char *ret_uuid) | ||
41 | { | ||
42 | struct mdp_superblock_s *md; | ||
43 | blkid_loff_t offset; | ||
44 | char buf[4096]; | ||
45 | |||
46 | if (fd < 0) | ||
47 | return -BLKID_ERR_PARAM; | ||
48 | |||
49 | offset = (blkid_get_dev_size(fd) & ~((blkid_loff_t)65535)) - 65536; | ||
50 | |||
51 | if (blkid_llseek(fd, offset, 0) < 0 || | ||
52 | read(fd, buf, 4096) != 4096) | ||
53 | return -BLKID_ERR_IO; | ||
54 | |||
55 | /* Check for magic number */ | ||
56 | if (memcmp("\251+N\374", buf, 4)) | ||
57 | return -BLKID_ERR_PARAM; | ||
58 | |||
59 | if (!ret_uuid) | ||
60 | return 0; | ||
61 | *ret_uuid = 0; | ||
62 | |||
63 | /* The MD UUID is not contiguous in the superblock, make it so */ | ||
64 | md = (struct mdp_superblock_s *)buf; | ||
65 | if (md->set_uuid0 || md->set_uuid1 || md->set_uuid2 || md->set_uuid3) { | ||
66 | memcpy(ret_uuid, &md->set_uuid0, 4); | ||
67 | memcpy(ret_uuid, &md->set_uuid1, 12); | ||
68 | } | ||
69 | return 0; | ||
70 | } | ||
71 | |||
72 | static void set_uuid(blkid_dev dev, uuid_t uuid) | ||
73 | { | ||
74 | char str[37]; | ||
75 | |||
76 | if (!uuid_is_null(uuid)) { | ||
77 | uuid_unparse(uuid, str); | ||
78 | blkid_set_tag(dev, "UUID", str, sizeof(str)); | ||
79 | } | ||
80 | } | ||
81 | |||
82 | static void get_ext2_info(blkid_dev dev, unsigned char *buf) | ||
83 | { | ||
84 | struct ext2_super_block *es = (struct ext2_super_block *) buf; | ||
85 | const char *label = 0; | ||
86 | |||
87 | DBG(DEBUG_PROBE, printf("ext2_sb.compat = %08X:%08X:%08X\n", | ||
88 | blkid_le32(es->s_feature_compat), | ||
89 | blkid_le32(es->s_feature_incompat), | ||
90 | blkid_le32(es->s_feature_ro_compat))); | ||
91 | |||
92 | if (strlen(es->s_volume_name)) | ||
93 | label = es->s_volume_name; | ||
94 | blkid_set_tag(dev, "LABEL", label, sizeof(es->s_volume_name)); | ||
95 | |||
96 | set_uuid(dev, es->s_uuid); | ||
97 | } | ||
98 | |||
99 | static int probe_ext3(int fd __BLKID_ATTR((unused)), | ||
100 | blkid_cache cache __BLKID_ATTR((unused)), | ||
101 | blkid_dev dev, | ||
102 | const struct blkid_magic *id __BLKID_ATTR((unused)), | ||
103 | unsigned char *buf) | ||
104 | { | ||
105 | struct ext2_super_block *es; | ||
106 | |||
107 | es = (struct ext2_super_block *)buf; | ||
108 | |||
109 | /* Distinguish between jbd and ext2/3 fs */ | ||
110 | if (blkid_le32(es->s_feature_incompat) & | ||
111 | EXT3_FEATURE_INCOMPAT_JOURNAL_DEV) | ||
112 | return -BLKID_ERR_PARAM; | ||
113 | |||
114 | /* Distinguish between ext3 and ext2 */ | ||
115 | if (!(blkid_le32(es->s_feature_compat) & | ||
116 | EXT3_FEATURE_COMPAT_HAS_JOURNAL)) | ||
117 | return -BLKID_ERR_PARAM; | ||
118 | |||
119 | get_ext2_info(dev, buf); | ||
120 | |||
121 | blkid_set_tag(dev, "SEC_TYPE", "ext2", sizeof("ext2")); | ||
122 | |||
123 | return 0; | ||
124 | } | ||
125 | |||
126 | static int probe_ext2(int fd __BLKID_ATTR((unused)), | ||
127 | blkid_cache cache __BLKID_ATTR((unused)), | ||
128 | blkid_dev dev, | ||
129 | const struct blkid_magic *id __BLKID_ATTR((unused)), | ||
130 | unsigned char *buf) | ||
131 | { | ||
132 | struct ext2_super_block *es; | ||
133 | |||
134 | es = (struct ext2_super_block *)buf; | ||
135 | |||
136 | /* Distinguish between jbd and ext2/3 fs */ | ||
137 | if (blkid_le32(es->s_feature_incompat) & | ||
138 | EXT3_FEATURE_INCOMPAT_JOURNAL_DEV) | ||
139 | return -BLKID_ERR_PARAM; | ||
140 | |||
141 | get_ext2_info(dev, buf); | ||
142 | |||
143 | return 0; | ||
144 | } | ||
145 | |||
146 | static int probe_jbd(int fd __BLKID_ATTR((unused)), | ||
147 | blkid_cache cache __BLKID_ATTR((unused)), | ||
148 | blkid_dev dev, | ||
149 | const struct blkid_magic *id __BLKID_ATTR((unused)), | ||
150 | unsigned char *buf) | ||
151 | { | ||
152 | struct ext2_super_block *es = (struct ext2_super_block *) buf; | ||
153 | |||
154 | if (!(blkid_le32(es->s_feature_incompat) & | ||
155 | EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)) | ||
156 | return -BLKID_ERR_PARAM; | ||
157 | |||
158 | get_ext2_info(dev, buf); | ||
159 | |||
160 | return 0; | ||
161 | } | ||
162 | |||
163 | static int probe_vfat(int fd __BLKID_ATTR((unused)), | ||
164 | blkid_cache cache __BLKID_ATTR((unused)), | ||
165 | blkid_dev dev, | ||
166 | const struct blkid_magic *id __BLKID_ATTR((unused)), | ||
167 | unsigned char *buf) | ||
168 | { | ||
169 | struct vfat_super_block *vs; | ||
170 | char serno[10]; | ||
171 | const char *label = 0; | ||
172 | int label_len = 0; | ||
173 | |||
174 | vs = (struct vfat_super_block *)buf; | ||
175 | |||
176 | if (strncmp(vs->vs_label, "NO NAME", 7)) { | ||
177 | char *end = vs->vs_label + sizeof(vs->vs_label) - 1; | ||
178 | |||
179 | while (*end == ' ' && end >= vs->vs_label) | ||
180 | --end; | ||
181 | if (end >= vs->vs_label) { | ||
182 | label = vs->vs_label; | ||
183 | label_len = end - vs->vs_label + 1; | ||
184 | } | ||
185 | } | ||
186 | |||
187 | /* We can't just print them as %04X, because they are unaligned */ | ||
188 | sprintf(serno, "%02X%02X-%02X%02X", vs->vs_serno[3], vs->vs_serno[2], | ||
189 | vs->vs_serno[1], vs->vs_serno[0]); | ||
190 | blkid_set_tag(dev, "LABEL", label, label_len); | ||
191 | blkid_set_tag(dev, "UUID", serno, sizeof(serno)); | ||
192 | |||
193 | return 0; | ||
194 | } | ||
195 | |||
196 | static int probe_msdos(int fd __BLKID_ATTR((unused)), | ||
197 | blkid_cache cache __BLKID_ATTR((unused)), | ||
198 | blkid_dev dev, | ||
199 | const struct blkid_magic *id __BLKID_ATTR((unused)), | ||
200 | unsigned char *buf) | ||
201 | { | ||
202 | struct msdos_super_block *ms = (struct msdos_super_block *) buf; | ||
203 | char serno[10]; | ||
204 | const char *label = 0; | ||
205 | int label_len = 0; | ||
206 | |||
207 | if (strncmp(ms->ms_label, "NO NAME", 7)) { | ||
208 | char *end = ms->ms_label + sizeof(ms->ms_label) - 1; | ||
209 | |||
210 | while (*end == ' ' && end >= ms->ms_label) | ||
211 | --end; | ||
212 | if (end >= ms->ms_label) { | ||
213 | label = ms->ms_label; | ||
214 | label_len = end - ms->ms_label + 1; | ||
215 | } | ||
216 | } | ||
217 | |||
218 | /* We can't just print them as %04X, because they are unaligned */ | ||
219 | sprintf(serno, "%02X%02X-%02X%02X", ms->ms_serno[3], ms->ms_serno[2], | ||
220 | ms->ms_serno[1], ms->ms_serno[0]); | ||
221 | blkid_set_tag(dev, "UUID", serno, 0); | ||
222 | blkid_set_tag(dev, "LABEL", label, label_len); | ||
223 | blkid_set_tag(dev, "SEC_TYPE", "msdos", sizeof("msdos")); | ||
224 | |||
225 | return 0; | ||
226 | } | ||
227 | |||
228 | static int probe_xfs(int fd __BLKID_ATTR((unused)), | ||
229 | blkid_cache cache __BLKID_ATTR((unused)), | ||
230 | blkid_dev dev, | ||
231 | const struct blkid_magic *id __BLKID_ATTR((unused)), | ||
232 | unsigned char *buf) | ||
233 | { | ||
234 | struct xfs_super_block *xs; | ||
235 | const char *label = 0; | ||
236 | |||
237 | xs = (struct xfs_super_block *)buf; | ||
238 | |||
239 | if (strlen(xs->xs_fname)) | ||
240 | label = xs->xs_fname; | ||
241 | blkid_set_tag(dev, "LABEL", label, sizeof(xs->xs_fname)); | ||
242 | set_uuid(dev, xs->xs_uuid); | ||
243 | return 0; | ||
244 | } | ||
245 | |||
246 | static int probe_reiserfs(int fd __BLKID_ATTR((unused)), | ||
247 | blkid_cache cache __BLKID_ATTR((unused)), | ||
248 | blkid_dev dev, | ||
249 | const struct blkid_magic *id, unsigned char *buf) | ||
250 | { | ||
251 | struct reiserfs_super_block *rs = (struct reiserfs_super_block *) buf; | ||
252 | unsigned int blocksize; | ||
253 | const char *label = 0; | ||
254 | |||
255 | blocksize = blkid_le16(rs->rs_blocksize); | ||
256 | |||
257 | /* If the superblock is inside the journal, we have the wrong one */ | ||
258 | if (id->bim_kboff/(blocksize>>10) > blkid_le32(rs->rs_journal_block)) | ||
259 | return -BLKID_ERR_BIG; | ||
260 | |||
261 | /* LABEL/UUID are only valid for later versions of Reiserfs v3.6. */ | ||
262 | if (!strcmp(id->bim_magic, "ReIsEr2Fs") || | ||
263 | !strcmp(id->bim_magic, "ReIsEr3Fs")) { | ||
264 | if (strlen(rs->rs_label)) | ||
265 | label = rs->rs_label; | ||
266 | set_uuid(dev, rs->rs_uuid); | ||
267 | } | ||
268 | blkid_set_tag(dev, "LABEL", label, sizeof(rs->rs_label)); | ||
269 | |||
270 | return 0; | ||
271 | } | ||
272 | |||
273 | static int probe_jfs(int fd __BLKID_ATTR((unused)), | ||
274 | blkid_cache cache __BLKID_ATTR((unused)), | ||
275 | blkid_dev dev, | ||
276 | const struct blkid_magic *id __BLKID_ATTR((unused)), | ||
277 | unsigned char *buf) | ||
278 | { | ||
279 | struct jfs_super_block *js; | ||
280 | const char *label = 0; | ||
281 | |||
282 | js = (struct jfs_super_block *)buf; | ||
283 | |||
284 | if (strlen((char *) js->js_label)) | ||
285 | label = (char *) js->js_label; | ||
286 | blkid_set_tag(dev, "LABEL", label, sizeof(js->js_label)); | ||
287 | set_uuid(dev, js->js_uuid); | ||
288 | return 0; | ||
289 | } | ||
290 | |||
291 | static int probe_romfs(int fd __BLKID_ATTR((unused)), | ||
292 | blkid_cache cache __BLKID_ATTR((unused)), | ||
293 | blkid_dev dev, | ||
294 | const struct blkid_magic *id __BLKID_ATTR((unused)), | ||
295 | unsigned char *buf) | ||
296 | { | ||
297 | struct romfs_super_block *ros; | ||
298 | const char *label = 0; | ||
299 | |||
300 | ros = (struct romfs_super_block *)buf; | ||
301 | |||
302 | if (strlen((char *) ros->ros_volume)) | ||
303 | label = (char *) ros->ros_volume; | ||
304 | blkid_set_tag(dev, "LABEL", label, 0); | ||
305 | return 0; | ||
306 | } | ||
307 | |||
308 | static int probe_cramfs(int fd __BLKID_ATTR((unused)), | ||
309 | blkid_cache cache __BLKID_ATTR((unused)), | ||
310 | blkid_dev dev, | ||
311 | const struct blkid_magic *id __BLKID_ATTR((unused)), | ||
312 | unsigned char *buf) | ||
313 | { | ||
314 | struct cramfs_super_block *csb; | ||
315 | const char *label = 0; | ||
316 | |||
317 | csb = (struct cramfs_super_block *)buf; | ||
318 | |||
319 | if (strlen((char *) csb->name)) | ||
320 | label = (char *) csb->name; | ||
321 | blkid_set_tag(dev, "LABEL", label, 0); | ||
322 | return 0; | ||
323 | } | ||
324 | |||
325 | static int probe_swap0(int fd __BLKID_ATTR((unused)), | ||
326 | blkid_cache cache __BLKID_ATTR((unused)), | ||
327 | blkid_dev dev, | ||
328 | const struct blkid_magic *id __BLKID_ATTR((unused)), | ||
329 | unsigned char *buf __BLKID_ATTR((unused))) | ||
330 | { | ||
331 | blkid_set_tag(dev, "UUID", 0, 0); | ||
332 | blkid_set_tag(dev, "LABEL", 0, 0); | ||
333 | return 0; | ||
334 | } | ||
335 | |||
336 | static int probe_swap1(int fd, | ||
337 | blkid_cache cache __BLKID_ATTR((unused)), | ||
338 | blkid_dev dev, | ||
339 | const struct blkid_magic *id __BLKID_ATTR((unused)), | ||
340 | unsigned char *buf __BLKID_ATTR((unused))) | ||
341 | { | ||
342 | struct swap_id_block *sws; | ||
343 | |||
344 | probe_swap0(fd, cache, dev, id, buf); | ||
345 | /* | ||
346 | * Version 1 swap headers are always located at offset of 1024 | ||
347 | * bytes, although the swap signature itself is located at the | ||
348 | * end of the page (which may vary depending on hardware | ||
349 | * pagesize). | ||
350 | */ | ||
351 | if (lseek(fd, 1024, SEEK_SET) < 0) return 1; | ||
352 | sws = xmalloc(1024); | ||
353 | if (read(fd, sws, 1024) != 1024) { | ||
354 | free(sws); | ||
355 | return 1; | ||
356 | } | ||
357 | |||
358 | /* arbitrary sanity check.. is there any garbage down there? */ | ||
359 | if (sws->sws_pad[32] == 0 && sws->sws_pad[33] == 0) { | ||
360 | if (sws->sws_volume[0]) | ||
361 | blkid_set_tag(dev, "LABEL", (const char*)sws->sws_volume, | ||
362 | sizeof(sws->sws_volume)); | ||
363 | if (sws->sws_uuid[0]) | ||
364 | set_uuid(dev, sws->sws_uuid); | ||
365 | } | ||
366 | free(sws); | ||
367 | |||
368 | return 0; | ||
369 | } | ||
370 | |||
371 | static const char | ||
372 | * const udf_magic[] = { "BEA01", "BOOT2", "CD001", "CDW02", "NSR02", | ||
373 | "NSR03", "TEA01", 0 }; | ||
374 | |||
375 | static int probe_udf(int fd, blkid_cache cache __BLKID_ATTR((unused)), | ||
376 | blkid_dev dev __BLKID_ATTR((unused)), | ||
377 | const struct blkid_magic *id __BLKID_ATTR((unused)), | ||
378 | unsigned char *buf __BLKID_ATTR((unused))) | ||
379 | { | ||
380 | int j, bs; | ||
381 | struct iso_volume_descriptor isosb; | ||
382 | const char * const * m; | ||
383 | |||
384 | /* determine the block size by scanning in 2K increments | ||
385 | (block sizes larger than 2K will be null padded) */ | ||
386 | for (bs = 1; bs < 16; bs++) { | ||
387 | lseek(fd, bs*2048+32768, SEEK_SET); | ||
388 | if (read(fd, (char *)&isosb, sizeof(isosb)) != sizeof(isosb)) | ||
389 | return 1; | ||
390 | if (isosb.id[0]) | ||
391 | break; | ||
392 | } | ||
393 | |||
394 | /* Scan up to another 64 blocks looking for additional VSD's */ | ||
395 | for (j = 1; j < 64; j++) { | ||
396 | if (j > 1) { | ||
397 | lseek(fd, j*bs*2048+32768, SEEK_SET); | ||
398 | if (read(fd, (char *)&isosb, sizeof(isosb)) | ||
399 | != sizeof(isosb)) | ||
400 | return 1; | ||
401 | } | ||
402 | /* If we find NSR0x then call it udf: | ||
403 | NSR01 for UDF 1.00 | ||
404 | NSR02 for UDF 1.50 | ||
405 | NSR03 for UDF 2.00 */ | ||
406 | if (!strncmp(isosb.id, "NSR0", 4)) | ||
407 | return 0; | ||
408 | for (m = udf_magic; *m; m++) | ||
409 | if (!strncmp(*m, isosb.id, 5)) | ||
410 | break; | ||
411 | if (*m == 0) | ||
412 | return 1; | ||
413 | } | ||
414 | return 1; | ||
415 | } | ||
416 | |||
417 | static int probe_ocfs(int fd __BLKID_ATTR((unused)), | ||
418 | blkid_cache cache __BLKID_ATTR((unused)), | ||
419 | blkid_dev dev, | ||
420 | const struct blkid_magic *id __BLKID_ATTR((unused)), | ||
421 | unsigned char *buf) | ||
422 | { | ||
423 | struct ocfs_volume_header ovh; | ||
424 | struct ocfs_volume_label ovl; | ||
425 | __u32 major; | ||
426 | |||
427 | memcpy(&ovh, buf, sizeof(ovh)); | ||
428 | memcpy(&ovl, buf+512, sizeof(ovl)); | ||
429 | |||
430 | major = ocfsmajor(ovh); | ||
431 | if (major == 1) | ||
432 | blkid_set_tag(dev,"SEC_TYPE","ocfs1",sizeof("ocfs1")); | ||
433 | else if (major >= 9) | ||
434 | blkid_set_tag(dev,"SEC_TYPE","ntocfs",sizeof("ntocfs")); | ||
435 | |||
436 | blkid_set_tag(dev, "LABEL", (const char*)ovl.label, ocfslabellen(ovl)); | ||
437 | blkid_set_tag(dev, "MOUNT", (const char*)ovh.mount, ocfsmountlen(ovh)); | ||
438 | set_uuid(dev, ovl.vol_id); | ||
439 | return 0; | ||
440 | } | ||
441 | |||
442 | static int probe_ocfs2(int fd __BLKID_ATTR((unused)), | ||
443 | blkid_cache cache __BLKID_ATTR((unused)), | ||
444 | blkid_dev dev, | ||
445 | const struct blkid_magic *id __BLKID_ATTR((unused)), | ||
446 | unsigned char *buf) | ||
447 | { | ||
448 | struct ocfs2_super_block *osb; | ||
449 | |||
450 | osb = (struct ocfs2_super_block *)buf; | ||
451 | |||
452 | blkid_set_tag(dev, "LABEL", (const char*)osb->s_label, sizeof(osb->s_label)); | ||
453 | set_uuid(dev, osb->s_uuid); | ||
454 | return 0; | ||
455 | } | ||
456 | |||
457 | static int probe_oracleasm(int fd __BLKID_ATTR((unused)), | ||
458 | blkid_cache cache __BLKID_ATTR((unused)), | ||
459 | blkid_dev dev, | ||
460 | const struct blkid_magic *id __BLKID_ATTR((unused)), | ||
461 | unsigned char *buf) | ||
462 | { | ||
463 | struct oracle_asm_disk_label *dl; | ||
464 | |||
465 | dl = (struct oracle_asm_disk_label *)buf; | ||
466 | |||
467 | blkid_set_tag(dev, "LABEL", dl->dl_id, sizeof(dl->dl_id)); | ||
468 | return 0; | ||
469 | } | ||
470 | |||
471 | /* | ||
472 | * BLKID_BLK_OFFS is at least as large as the highest bim_kboff defined | ||
473 | * in the type_array table below + bim_kbalign. | ||
474 | * | ||
475 | * When probing for a lot of magics, we handle everything in 1kB buffers so | ||
476 | * that we don't have to worry about reading each combination of block sizes. | ||
477 | */ | ||
478 | #define BLKID_BLK_OFFS 64 /* currently reiserfs */ | ||
479 | |||
480 | /* | ||
481 | * Various filesystem magics that we can check for. Note that kboff and | ||
482 | * sboff are in kilobytes and bytes respectively. All magics are in | ||
483 | * byte strings so we don't worry about endian issues. | ||
484 | */ | ||
485 | static const struct blkid_magic type_array[] = { | ||
486 | /* type kboff sboff len magic probe */ | ||
487 | { "oracleasm", 0, 32, 8, "ORCLDISK", probe_oracleasm }, | ||
488 | { "ntfs", 0, 3, 8, "NTFS ", 0 }, | ||
489 | { "jbd", 1, 0x38, 2, "\123\357", probe_jbd }, | ||
490 | { "ext3", 1, 0x38, 2, "\123\357", probe_ext3 }, | ||
491 | { "ext2", 1, 0x38, 2, "\123\357", probe_ext2 }, | ||
492 | { "reiserfs", 8, 0x34, 8, "ReIsErFs", probe_reiserfs }, | ||
493 | { "reiserfs", 64, 0x34, 9, "ReIsEr2Fs", probe_reiserfs }, | ||
494 | { "reiserfs", 64, 0x34, 9, "ReIsEr3Fs", probe_reiserfs }, | ||
495 | { "reiserfs", 64, 0x34, 8, "ReIsErFs", probe_reiserfs }, | ||
496 | { "reiserfs", 8, 20, 8, "ReIsErFs", probe_reiserfs }, | ||
497 | { "vfat", 0, 0x52, 5, "MSWIN", probe_vfat }, | ||
498 | { "vfat", 0, 0x52, 8, "FAT32 ", probe_vfat }, | ||
499 | { "vfat", 0, 0x36, 5, "MSDOS", probe_msdos }, | ||
500 | { "vfat", 0, 0x36, 8, "FAT16 ", probe_msdos }, | ||
501 | { "vfat", 0, 0x36, 8, "FAT12 ", probe_msdos }, | ||
502 | { "minix", 1, 0x10, 2, "\177\023", 0 }, | ||
503 | { "minix", 1, 0x10, 2, "\217\023", 0 }, | ||
504 | { "minix", 1, 0x10, 2, "\150\044", 0 }, | ||
505 | { "minix", 1, 0x10, 2, "\170\044", 0 }, | ||
506 | { "vxfs", 1, 0, 4, "\365\374\001\245", 0 }, | ||
507 | { "xfs", 0, 0, 4, "XFSB", probe_xfs }, | ||
508 | { "romfs", 0, 0, 8, "-rom1fs-", probe_romfs }, | ||
509 | { "bfs", 0, 0, 4, "\316\372\173\033", 0 }, | ||
510 | { "cramfs", 0, 0, 4, "E=\315\050", probe_cramfs }, | ||
511 | { "qnx4", 0, 4, 6, "QNX4FS", 0 }, | ||
512 | { "udf", 32, 1, 5, "BEA01", probe_udf }, | ||
513 | { "udf", 32, 1, 5, "BOOT2", probe_udf }, | ||
514 | { "udf", 32, 1, 5, "CD001", probe_udf }, | ||
515 | { "udf", 32, 1, 5, "CDW02", probe_udf }, | ||
516 | { "udf", 32, 1, 5, "NSR02", probe_udf }, | ||
517 | { "udf", 32, 1, 5, "NSR03", probe_udf }, | ||
518 | { "udf", 32, 1, 5, "TEA01", probe_udf }, | ||
519 | { "iso9660", 32, 1, 5, "CD001", 0 }, | ||
520 | { "iso9660", 32, 9, 5, "CDROM", 0 }, | ||
521 | { "jfs", 32, 0, 4, "JFS1", probe_jfs }, | ||
522 | { "hfs", 1, 0, 2, "BD", 0 }, | ||
523 | { "ufs", 8, 0x55c, 4, "T\031\001\000", 0 }, | ||
524 | { "hpfs", 8, 0, 4, "I\350\225\371", 0 }, | ||
525 | { "sysv", 0, 0x3f8, 4, "\020~\030\375", 0 }, | ||
526 | { "swap", 0, 0xff6, 10, "SWAP-SPACE", probe_swap0 }, | ||
527 | { "swap", 0, 0xff6, 10, "SWAPSPACE2", probe_swap1 }, | ||
528 | { "swap", 0, 0x1ff6, 10, "SWAP-SPACE", probe_swap0 }, | ||
529 | { "swap", 0, 0x1ff6, 10, "SWAPSPACE2", probe_swap1 }, | ||
530 | { "swap", 0, 0x3ff6, 10, "SWAP-SPACE", probe_swap0 }, | ||
531 | { "swap", 0, 0x3ff6, 10, "SWAPSPACE2", probe_swap1 }, | ||
532 | { "swap", 0, 0x7ff6, 10, "SWAP-SPACE", probe_swap0 }, | ||
533 | { "swap", 0, 0x7ff6, 10, "SWAPSPACE2", probe_swap1 }, | ||
534 | { "swap", 0, 0xfff6, 10, "SWAP-SPACE", probe_swap0 }, | ||
535 | { "swap", 0, 0xfff6, 10, "SWAPSPACE2", probe_swap1 }, | ||
536 | { "ocfs", 0, 8, 9, "OracleCFS", probe_ocfs }, | ||
537 | { "ocfs2", 1, 0, 6, "OCFSV2", probe_ocfs2 }, | ||
538 | { "ocfs2", 2, 0, 6, "OCFSV2", probe_ocfs2 }, | ||
539 | { "ocfs2", 4, 0, 6, "OCFSV2", probe_ocfs2 }, | ||
540 | { "ocfs2", 8, 0, 6, "OCFSV2", probe_ocfs2 }, | ||
541 | { NULL, 0, 0, 0, NULL, NULL } | ||
542 | }; | ||
543 | |||
544 | /* | ||
545 | * Verify that the data in dev is consistent with what is on the actual | ||
546 | * block device (using the devname field only). Normally this will be | ||
547 | * called when finding items in the cache, but for long running processes | ||
548 | * is also desirable to revalidate an item before use. | ||
549 | * | ||
550 | * If we are unable to revalidate the data, we return the old data and | ||
551 | * do not set the BLKID_BID_FL_VERIFIED flag on it. | ||
552 | */ | ||
553 | blkid_dev blkid_verify(blkid_cache cache, blkid_dev dev) | ||
554 | { | ||
555 | const struct blkid_magic *id; | ||
556 | unsigned char *bufs[BLKID_BLK_OFFS + 1], *buf; | ||
557 | const char *type; | ||
558 | struct stat st; | ||
559 | time_t diff, now; | ||
560 | int fd, idx; | ||
561 | |||
562 | if (!dev) | ||
563 | return NULL; | ||
564 | |||
565 | now = time(0); | ||
566 | diff = now - dev->bid_time; | ||
567 | |||
568 | if ((now < dev->bid_time) || | ||
569 | (diff < BLKID_PROBE_MIN) || | ||
570 | (dev->bid_flags & BLKID_BID_FL_VERIFIED && | ||
571 | diff < BLKID_PROBE_INTERVAL)) | ||
572 | return dev; | ||
573 | |||
574 | DBG(DEBUG_PROBE, | ||
575 | printf("need to revalidate %s (time since last check %lu)\n", | ||
576 | dev->bid_name, diff)); | ||
577 | |||
578 | if (((fd = open(dev->bid_name, O_RDONLY)) < 0) || | ||
579 | (fstat(fd, &st) < 0)) { | ||
580 | if (errno == ENXIO || errno == ENODEV || errno == ENOENT) { | ||
581 | blkid_free_dev(dev); | ||
582 | return NULL; | ||
583 | } | ||
584 | /* We don't have read permission, just return cache data. */ | ||
585 | DBG(DEBUG_PROBE, | ||
586 | printf("returning unverified data for %s\n", | ||
587 | dev->bid_name)); | ||
588 | return dev; | ||
589 | } | ||
590 | |||
591 | memset(bufs, 0, sizeof(bufs)); | ||
592 | |||
593 | /* | ||
594 | * Iterate over the type array. If we already know the type, | ||
595 | * then try that first. If it doesn't work, then blow away | ||
596 | * the type information, and try again. | ||
597 | * | ||
598 | */ | ||
599 | try_again: | ||
600 | type = 0; | ||
601 | if (!dev->bid_type || !strcmp(dev->bid_type, "mdraid")) { | ||
602 | uuid_t uuid; | ||
603 | |||
604 | if (check_mdraid(fd, uuid) == 0) { | ||
605 | set_uuid(dev, uuid); | ||
606 | type = "mdraid"; | ||
607 | goto found_type; | ||
608 | } | ||
609 | } | ||
610 | for (id = type_array; id->bim_type; id++) { | ||
611 | if (dev->bid_type && | ||
612 | strcmp(id->bim_type, dev->bid_type)) | ||
613 | continue; | ||
614 | |||
615 | idx = id->bim_kboff + (id->bim_sboff >> 10); | ||
616 | if (idx > BLKID_BLK_OFFS || idx < 0) | ||
617 | continue; | ||
618 | buf = bufs[idx]; | ||
619 | if (!buf) { | ||
620 | if (lseek(fd, idx << 10, SEEK_SET) < 0) | ||
621 | continue; | ||
622 | |||
623 | buf = xmalloc(1024); | ||
624 | |||
625 | if (read(fd, buf, 1024) != 1024) { | ||
626 | free(buf); | ||
627 | continue; | ||
628 | } | ||
629 | bufs[idx] = buf; | ||
630 | } | ||
631 | |||
632 | if (memcmp(id->bim_magic, buf + (id->bim_sboff&0x3ff), | ||
633 | id->bim_len)) | ||
634 | continue; | ||
635 | |||
636 | if ((id->bim_probe == NULL) || | ||
637 | (id->bim_probe(fd, cache, dev, id, buf) == 0)) { | ||
638 | type = id->bim_type; | ||
639 | goto found_type; | ||
640 | } | ||
641 | } | ||
642 | |||
643 | if (!id->bim_type && dev->bid_type) { | ||
644 | /* | ||
645 | * Zap the device filesystem type and try again | ||
646 | */ | ||
647 | blkid_set_tag(dev, "TYPE", 0, 0); | ||
648 | blkid_set_tag(dev, "SEC_TYPE", 0, 0); | ||
649 | blkid_set_tag(dev, "LABEL", 0, 0); | ||
650 | blkid_set_tag(dev, "UUID", 0, 0); | ||
651 | goto try_again; | ||
652 | } | ||
653 | |||
654 | if (!dev->bid_type) { | ||
655 | blkid_free_dev(dev); | ||
656 | return NULL; | ||
657 | } | ||
658 | |||
659 | found_type: | ||
660 | if (dev && type) { | ||
661 | dev->bid_devno = st.st_rdev; | ||
662 | dev->bid_time = time(0); | ||
663 | dev->bid_flags |= BLKID_BID_FL_VERIFIED; | ||
664 | cache->bic_flags |= BLKID_BIC_FL_CHANGED; | ||
665 | |||
666 | blkid_set_tag(dev, "TYPE", type, 0); | ||
667 | |||
668 | DBG(DEBUG_PROBE, printf("%s: devno 0x%04llx, type %s\n", | ||
669 | dev->bid_name, st.st_rdev, type)); | ||
670 | } | ||
671 | |||
672 | close(fd); | ||
673 | |||
674 | return dev; | ||
675 | } | ||
676 | |||
677 | int blkid_known_fstype(const char *fstype) | ||
678 | { | ||
679 | const struct blkid_magic *id; | ||
680 | |||
681 | for (id = type_array; id->bim_type; id++) { | ||
682 | if (strcmp(fstype, id->bim_type) == 0) | ||
683 | return 1; | ||
684 | } | ||
685 | return 0; | ||
686 | } | ||
687 | |||
688 | #ifdef TEST_PROGRAM | ||
689 | int main(int argc, char **argv) | ||
690 | { | ||
691 | blkid_dev dev; | ||
692 | blkid_cache cache; | ||
693 | int ret; | ||
694 | |||
695 | blkid_debug_mask = DEBUG_ALL; | ||
696 | if (argc != 2) { | ||
697 | fprintf(stderr, "Usage: %s device\n" | ||
698 | "Probe a single device to determine type\n", argv[0]); | ||
699 | exit(1); | ||
700 | } | ||
701 | if ((ret = blkid_get_cache(&cache, bb_dev_null)) != 0) { | ||
702 | fprintf(stderr, "%s: error creating cache (%d)\n", | ||
703 | argv[0], ret); | ||
704 | exit(1); | ||
705 | } | ||
706 | dev = blkid_get_dev(cache, argv[1], BLKID_DEV_NORMAL); | ||
707 | if (!dev) { | ||
708 | printf("%s: %s has an unsupported type\n", argv[0], argv[1]); | ||
709 | return 1; | ||
710 | } | ||
711 | printf("%s is type %s\n", argv[1], dev->bid_type ? | ||
712 | dev->bid_type : "(null)"); | ||
713 | if (dev->bid_label) | ||
714 | printf("\tlabel is '%s'\n", dev->bid_label); | ||
715 | if (dev->bid_uuid) | ||
716 | printf("\tuuid is %s\n", dev->bid_uuid); | ||
717 | |||
718 | blkid_free_dev(dev); | ||
719 | return 0; | ||
720 | } | ||
721 | #endif | ||
diff --git a/e2fsprogs/blkid/probe.h b/e2fsprogs/blkid/probe.h deleted file mode 100644 index 78f796419..000000000 --- a/e2fsprogs/blkid/probe.h +++ /dev/null | |||
@@ -1,375 +0,0 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * probe.h - constants and on-disk structures for extracting device data | ||
4 | * | ||
5 | * Copyright (C) 1999 by Andries Brouwer | ||
6 | * Copyright (C) 1999, 2000, 2003 by Theodore Ts'o | ||
7 | * Copyright (C) 2001 by Andreas Dilger | ||
8 | * | ||
9 | * %Begin-Header% | ||
10 | * This file may be redistributed under the terms of the | ||
11 | * GNU Lesser General Public License. | ||
12 | * %End-Header% | ||
13 | */ | ||
14 | |||
15 | #ifndef _BLKID_PROBE_H | ||
16 | #define _BLKID_PROBE_H | ||
17 | |||
18 | #include <linux/types.h> | ||
19 | |||
20 | struct blkid_magic; | ||
21 | |||
22 | typedef int (*blkid_probe_t)(int fd, blkid_cache cache, blkid_dev dev, | ||
23 | const struct blkid_magic *id, unsigned char *buf); | ||
24 | |||
25 | struct blkid_magic { | ||
26 | const char *bim_type; /* type name for this magic */ | ||
27 | long bim_kboff; /* kilobyte offset of superblock */ | ||
28 | unsigned bim_sboff; /* byte offset within superblock */ | ||
29 | unsigned bim_len; /* length of magic */ | ||
30 | const char *bim_magic; /* magic string */ | ||
31 | blkid_probe_t bim_probe; /* probe function */ | ||
32 | }; | ||
33 | |||
34 | /* | ||
35 | * Structures for each of the content types we want to extract information | ||
36 | * from. We do not necessarily need the magic field here, because we have | ||
37 | * already identified the content type before we get this far. It may still | ||
38 | * be useful if there are probe functions which handle multiple content types. | ||
39 | */ | ||
40 | struct ext2_super_block { | ||
41 | __u32 s_inodes_count; | ||
42 | __u32 s_blocks_count; | ||
43 | __u32 s_r_blocks_count; | ||
44 | __u32 s_free_blocks_count; | ||
45 | __u32 s_free_inodes_count; | ||
46 | __u32 s_first_data_block; | ||
47 | __u32 s_log_block_size; | ||
48 | __u32 s_dummy3[7]; | ||
49 | unsigned char s_magic[2]; | ||
50 | __u16 s_state; | ||
51 | __u32 s_dummy5[8]; | ||
52 | __u32 s_feature_compat; | ||
53 | __u32 s_feature_incompat; | ||
54 | __u32 s_feature_ro_compat; | ||
55 | unsigned char s_uuid[16]; | ||
56 | char s_volume_name[16]; | ||
57 | }; | ||
58 | #define EXT3_FEATURE_COMPAT_HAS_JOURNAL 0x00000004 | ||
59 | #define EXT3_FEATURE_INCOMPAT_RECOVER 0x00000004 | ||
60 | #define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV 0x00000008 | ||
61 | |||
62 | struct xfs_super_block { | ||
63 | unsigned char xs_magic[4]; | ||
64 | __u32 xs_blocksize; | ||
65 | __u64 xs_dblocks; | ||
66 | __u64 xs_rblocks; | ||
67 | __u32 xs_dummy1[2]; | ||
68 | unsigned char xs_uuid[16]; | ||
69 | __u32 xs_dummy2[15]; | ||
70 | char xs_fname[12]; | ||
71 | __u32 xs_dummy3[2]; | ||
72 | __u64 xs_icount; | ||
73 | __u64 xs_ifree; | ||
74 | __u64 xs_fdblocks; | ||
75 | }; | ||
76 | |||
77 | struct reiserfs_super_block { | ||
78 | __u32 rs_blocks_count; | ||
79 | __u32 rs_free_blocks; | ||
80 | __u32 rs_root_block; | ||
81 | __u32 rs_journal_block; | ||
82 | __u32 rs_journal_dev; | ||
83 | __u32 rs_orig_journal_size; | ||
84 | __u32 rs_dummy2[5]; | ||
85 | __u16 rs_blocksize; | ||
86 | __u16 rs_dummy3[3]; | ||
87 | unsigned char rs_magic[12]; | ||
88 | __u32 rs_dummy4[5]; | ||
89 | unsigned char rs_uuid[16]; | ||
90 | char rs_label[16]; | ||
91 | }; | ||
92 | |||
93 | struct jfs_super_block { | ||
94 | unsigned char js_magic[4]; | ||
95 | __u32 js_version; | ||
96 | __u64 js_size; | ||
97 | __u32 js_bsize; | ||
98 | __u32 js_dummy1; | ||
99 | __u32 js_pbsize; | ||
100 | __u32 js_dummy2[27]; | ||
101 | unsigned char js_uuid[16]; | ||
102 | unsigned char js_label[16]; | ||
103 | unsigned char js_loguuid[16]; | ||
104 | }; | ||
105 | |||
106 | struct romfs_super_block { | ||
107 | unsigned char ros_magic[8]; | ||
108 | __u32 ros_dummy1[2]; | ||
109 | unsigned char ros_volume[16]; | ||
110 | }; | ||
111 | |||
112 | struct cramfs_super_block { | ||
113 | __u8 magic[4]; | ||
114 | __u32 size; | ||
115 | __u32 flags; | ||
116 | __u32 future; | ||
117 | __u8 signature[16]; | ||
118 | struct cramfs_info { | ||
119 | __u32 crc; | ||
120 | __u32 edition; | ||
121 | __u32 blocks; | ||
122 | __u32 files; | ||
123 | } info; | ||
124 | __u8 name[16]; | ||
125 | }; | ||
126 | |||
127 | struct swap_id_block { | ||
128 | /* unsigned char sws_boot[1024]; */ | ||
129 | __u32 sws_version; | ||
130 | __u32 sws_lastpage; | ||
131 | __u32 sws_nrbad; | ||
132 | unsigned char sws_uuid[16]; | ||
133 | char sws_volume[16]; | ||
134 | unsigned char sws_pad[117]; | ||
135 | __u32 sws_badpg; | ||
136 | }; | ||
137 | |||
138 | /* Yucky misaligned values */ | ||
139 | struct vfat_super_block { | ||
140 | /* 00*/ unsigned char vs_ignored[3]; | ||
141 | /* 03*/ unsigned char vs_sysid[8]; | ||
142 | /* 0b*/ unsigned char vs_sector_size[2]; | ||
143 | /* 0d*/ __u8 vs_cluster_size; | ||
144 | /* 0e*/ __u16 vs_reserved; | ||
145 | /* 10*/ __u8 vs_fats; | ||
146 | /* 11*/ unsigned char vs_dir_entries[2]; | ||
147 | /* 13*/ unsigned char vs_sectors[2]; | ||
148 | /* 15*/ unsigned char vs_media; | ||
149 | /* 16*/ __u16 vs_fat_length; | ||
150 | /* 18*/ __u16 vs_secs_track; | ||
151 | /* 1a*/ __u16 vs_heads; | ||
152 | /* 1c*/ __u32 vs_hidden; | ||
153 | /* 20*/ __u32 vs_total_sect; | ||
154 | /* 24*/ __u32 vs_fat32_length; | ||
155 | /* 28*/ __u16 vs_flags; | ||
156 | /* 2a*/ __u8 vs_version[2]; | ||
157 | /* 2c*/ __u32 vs_root_cluster; | ||
158 | /* 30*/ __u16 vs_insfo_sector; | ||
159 | /* 32*/ __u16 vs_backup_boot; | ||
160 | /* 34*/ __u16 vs_reserved2[6]; | ||
161 | /* 40*/ unsigned char vs_unknown[3]; | ||
162 | /* 43*/ unsigned char vs_serno[4]; | ||
163 | /* 47*/ char vs_label[11]; | ||
164 | /* 52*/ unsigned char vs_magic[8]; | ||
165 | /* 5a*/ unsigned char vs_dummy2[164]; | ||
166 | /*1fe*/ unsigned char vs_pmagic[2]; | ||
167 | }; | ||
168 | |||
169 | /* Yucky misaligned values */ | ||
170 | struct msdos_super_block { | ||
171 | /* 00*/ unsigned char ms_ignored[3]; | ||
172 | /* 03*/ unsigned char ms_sysid[8]; | ||
173 | /* 0b*/ unsigned char ms_sector_size[2]; | ||
174 | /* 0d*/ __u8 ms_cluster_size; | ||
175 | /* 0e*/ __u16 ms_reserved; | ||
176 | /* 10*/ __u8 ms_fats; | ||
177 | /* 11*/ unsigned char ms_dir_entries[2]; | ||
178 | /* 13*/ unsigned char ms_sectors[2]; | ||
179 | /* 15*/ unsigned char ms_media; | ||
180 | /* 16*/ __u16 ms_fat_length; | ||
181 | /* 18*/ __u16 ms_secs_track; | ||
182 | /* 1a*/ __u16 ms_heads; | ||
183 | /* 1c*/ __u32 ms_hidden; | ||
184 | /* 20*/ __u32 ms_total_sect; | ||
185 | /* 24*/ unsigned char ms_unknown[3]; | ||
186 | /* 27*/ unsigned char ms_serno[4]; | ||
187 | /* 2b*/ char ms_label[11]; | ||
188 | /* 36*/ unsigned char ms_magic[8]; | ||
189 | /* 3d*/ unsigned char ms_dummy2[192]; | ||
190 | /*1fe*/ unsigned char ms_pmagic[2]; | ||
191 | }; | ||
192 | |||
193 | struct minix_super_block { | ||
194 | __u16 ms_ninodes; | ||
195 | __u16 ms_nzones; | ||
196 | __u16 ms_imap_blocks; | ||
197 | __u16 ms_zmap_blocks; | ||
198 | __u16 ms_firstdatazone; | ||
199 | __u16 ms_log_zone_size; | ||
200 | __u32 ms_max_size; | ||
201 | unsigned char ms_magic[2]; | ||
202 | __u16 ms_state; | ||
203 | __u32 ms_zones; | ||
204 | }; | ||
205 | |||
206 | struct mdp_superblock_s { | ||
207 | __u32 md_magic; | ||
208 | __u32 major_version; | ||
209 | __u32 minor_version; | ||
210 | __u32 patch_version; | ||
211 | __u32 gvalid_words; | ||
212 | __u32 set_uuid0; | ||
213 | __u32 ctime; | ||
214 | __u32 level; | ||
215 | __u32 size; | ||
216 | __u32 nr_disks; | ||
217 | __u32 raid_disks; | ||
218 | __u32 md_minor; | ||
219 | __u32 not_persistent; | ||
220 | __u32 set_uuid1; | ||
221 | __u32 set_uuid2; | ||
222 | __u32 set_uuid3; | ||
223 | }; | ||
224 | |||
225 | struct hfs_super_block { | ||
226 | char h_magic[2]; | ||
227 | char h_dummy[18]; | ||
228 | __u32 h_blksize; | ||
229 | }; | ||
230 | |||
231 | struct ocfs_volume_header { | ||
232 | unsigned char minor_version[4]; | ||
233 | unsigned char major_version[4]; | ||
234 | unsigned char signature[128]; | ||
235 | char mount[128]; | ||
236 | unsigned char mount_len[2]; | ||
237 | }; | ||
238 | |||
239 | struct ocfs_volume_label { | ||
240 | unsigned char disk_lock[48]; | ||
241 | char label[64]; | ||
242 | unsigned char label_len[2]; | ||
243 | unsigned char vol_id[16]; | ||
244 | unsigned char vol_id_len[2]; | ||
245 | }; | ||
246 | |||
247 | #define ocfsmajor(o) ((__u32)o.major_version[0] \ | ||
248 | + (((__u32) o.major_version[1]) << 8) \ | ||
249 | + (((__u32) o.major_version[2]) << 16) \ | ||
250 | + (((__u32) o.major_version[3]) << 24)) | ||
251 | #define ocfslabellen(o) ((__u32)o.label_len[0] + (((__u32) o.label_len[1]) << 8)) | ||
252 | #define ocfsmountlen(o) ((__u32)o.mount_len[0] + (((__u32) o.mount_len[1])<<8)) | ||
253 | |||
254 | #define OCFS_MAGIC "OracleCFS" | ||
255 | |||
256 | struct ocfs2_super_block { | ||
257 | unsigned char signature[8]; | ||
258 | unsigned char s_dummy1[184]; | ||
259 | unsigned char s_dummy2[80]; | ||
260 | char s_label[64]; | ||
261 | unsigned char s_uuid[16]; | ||
262 | }; | ||
263 | |||
264 | #define OCFS2_MIN_BLOCKSIZE 512 | ||
265 | #define OCFS2_MAX_BLOCKSIZE 4096 | ||
266 | |||
267 | #define OCFS2_SUPER_BLOCK_BLKNO 2 | ||
268 | |||
269 | #define OCFS2_SUPER_BLOCK_SIGNATURE "OCFSV2" | ||
270 | |||
271 | struct oracle_asm_disk_label { | ||
272 | char dummy[32]; | ||
273 | char dl_tag[8]; | ||
274 | char dl_id[24]; | ||
275 | }; | ||
276 | |||
277 | #define ORACLE_ASM_DISK_LABEL_MARKED "ORCLDISK" | ||
278 | #define ORACLE_ASM_DISK_LABEL_OFFSET 32 | ||
279 | |||
280 | #define ISODCL(from, to) (to - from + 1) | ||
281 | struct iso_volume_descriptor { | ||
282 | char type[ISODCL(1,1)]; /* 711 */ | ||
283 | char id[ISODCL(2,6)]; | ||
284 | char version[ISODCL(7,7)]; | ||
285 | char data[ISODCL(8,2048)]; | ||
286 | }; | ||
287 | |||
288 | /* | ||
289 | * Byte swap functions | ||
290 | */ | ||
291 | #ifdef __GNUC__ | ||
292 | #define _INLINE_ static __inline__ | ||
293 | #else /* For Watcom C */ | ||
294 | #define _INLINE_ static inline | ||
295 | #endif | ||
296 | |||
297 | static __u16 blkid_swab16(__u16 val); | ||
298 | static __u32 blkid_swab32(__u32 val); | ||
299 | static __u64 blkid_swab64(__u64 val); | ||
300 | |||
301 | #if ((defined __GNUC__) && \ | ||
302 | (defined(__i386__) || defined(__i486__) || defined(__i586__))) | ||
303 | |||
304 | #define _BLKID_HAVE_ASM_BITOPS_ | ||
305 | |||
306 | _INLINE_ __u32 blkid_swab32(__u32 val) | ||
307 | { | ||
308 | #ifdef EXT2FS_REQUIRE_486 | ||
309 | __asm__("bswap %0" : "=r" (val) : "0" (val)); | ||
310 | #else | ||
311 | __asm__("xchgb %b0,%h0\n\t" /* swap lower bytes */ | ||
312 | "rorl $16,%0\n\t" /* swap words */ | ||
313 | "xchgb %b0,%h0" /* swap higher bytes */ | ||
314 | :"=q" (val) | ||
315 | : "0" (val)); | ||
316 | #endif | ||
317 | return val; | ||
318 | } | ||
319 | |||
320 | _INLINE_ __u16 blkid_swab16(__u16 val) | ||
321 | { | ||
322 | __asm__("xchgb %b0,%h0" /* swap bytes */ \ | ||
323 | : "=q" (val) \ | ||
324 | : "0" (val)); \ | ||
325 | return val; | ||
326 | } | ||
327 | |||
328 | _INLINE_ __u64 blkid_swab64(__u64 val) | ||
329 | { | ||
330 | return blkid_swab32(val >> 32) | | ||
331 | ( ((__u64)blkid_swab32((__u32)val)) << 32 ); | ||
332 | } | ||
333 | #endif | ||
334 | |||
335 | #if !defined(_BLKID_HAVE_ASM_BITOPS_) | ||
336 | |||
337 | _INLINE_ __u16 blkid_swab16(__u16 val) | ||
338 | { | ||
339 | return (val >> 8) | (val << 8); | ||
340 | } | ||
341 | |||
342 | _INLINE_ __u32 blkid_swab32(__u32 val) | ||
343 | { | ||
344 | return (val>>24) | ((val>>8) & 0xFF00) | | ||
345 | ((val<<8) & 0xFF0000) | (val<<24); | ||
346 | } | ||
347 | |||
348 | _INLINE_ __u64 blkid_swab64(__u64 val) | ||
349 | { | ||
350 | return blkid_swab32(val >> 32) | | ||
351 | ( ((__u64)blkid_swab32((__u32)val)) << 32 ); | ||
352 | } | ||
353 | #endif | ||
354 | |||
355 | |||
356 | |||
357 | #if __BYTE_ORDER == __BIG_ENDIAN | ||
358 | #define blkid_le16(x) blkid_swab16(x) | ||
359 | #define blkid_le32(x) blkid_swab32(x) | ||
360 | #define blkid_le64(x) blkid_swab64(x) | ||
361 | #define blkid_be16(x) (x) | ||
362 | #define blkid_be32(x) (x) | ||
363 | #define blkid_be64(x) (x) | ||
364 | #else | ||
365 | #define blkid_le16(x) (x) | ||
366 | #define blkid_le32(x) (x) | ||
367 | #define blkid_le64(x) (x) | ||
368 | #define blkid_be16(x) blkid_swab16(x) | ||
369 | #define blkid_be32(x) blkid_swab32(x) | ||
370 | #define blkid_be64(x) blkid_swab64(x) | ||
371 | #endif | ||
372 | |||
373 | #undef _INLINE_ | ||
374 | |||
375 | #endif /* _BLKID_PROBE_H */ | ||
diff --git a/e2fsprogs/blkid/read.c b/e2fsprogs/blkid/read.c deleted file mode 100644 index bb02a2e21..000000000 --- a/e2fsprogs/blkid/read.c +++ /dev/null | |||
@@ -1,462 +0,0 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * read.c - read the blkid cache from disk, to avoid scanning all devices | ||
4 | * | ||
5 | * Copyright (C) 2001, 2003 Theodore Y. Ts'o | ||
6 | * Copyright (C) 2001 Andreas Dilger | ||
7 | * | ||
8 | * %Begin-Header% | ||
9 | * This file may be redistributed under the terms of the | ||
10 | * GNU Lesser General Public License. | ||
11 | * %End-Header% | ||
12 | */ | ||
13 | |||
14 | #include <stdio.h> | ||
15 | #include <ctype.h> | ||
16 | #include <string.h> | ||
17 | #include <time.h> | ||
18 | #include <sys/types.h> | ||
19 | #include <sys/stat.h> | ||
20 | #include <fcntl.h> | ||
21 | #include <unistd.h> | ||
22 | #include <errno.h> | ||
23 | |||
24 | #include "blkidP.h" | ||
25 | #include "../uuid/uuid.h" | ||
26 | |||
27 | #ifdef HAVE_STRTOULL | ||
28 | #define __USE_ISOC9X | ||
29 | #define STRTOULL strtoull /* defined in stdlib.h if you try hard enough */ | ||
30 | #else | ||
31 | /* FIXME: need to support real strtoull here */ | ||
32 | #define STRTOULL strtoul | ||
33 | #endif | ||
34 | |||
35 | #include <stdlib.h> | ||
36 | |||
37 | #ifdef TEST_PROGRAM | ||
38 | #define blkid_debug_dump_dev(dev) (debug_dump_dev(dev)) | ||
39 | static void debug_dump_dev(blkid_dev dev); | ||
40 | #endif | ||
41 | |||
42 | /* | ||
43 | * File format: | ||
44 | * | ||
45 | * <device [<NAME="value"> ...]>device_name</device> | ||
46 | * | ||
47 | * The following tags are required for each entry: | ||
48 | * <ID="id"> unique (within this file) ID number of this device | ||
49 | * <TIME="time"> (ascii time_t) time this entry was last read from disk | ||
50 | * <TYPE="type"> (detected) type of filesystem/data for this partition | ||
51 | * | ||
52 | * The following tags may be present, depending on the device contents | ||
53 | * <LABEL="label"> (user supplied) label (volume name, etc) | ||
54 | * <UUID="uuid"> (generated) universally unique identifier (serial no) | ||
55 | */ | ||
56 | |||
57 | static char *skip_over_blank(char *cp) | ||
58 | { | ||
59 | while (*cp && isspace(*cp)) | ||
60 | cp++; | ||
61 | return cp; | ||
62 | } | ||
63 | |||
64 | static char *skip_over_word(char *cp) | ||
65 | { | ||
66 | char ch; | ||
67 | |||
68 | while ((ch = *cp)) { | ||
69 | /* If we see a backslash, skip the next character */ | ||
70 | if (ch == '\\') { | ||
71 | cp++; | ||
72 | if (*cp == '\0') | ||
73 | break; | ||
74 | cp++; | ||
75 | continue; | ||
76 | } | ||
77 | if (isspace(ch) || ch == '<' || ch == '>') | ||
78 | break; | ||
79 | cp++; | ||
80 | } | ||
81 | return cp; | ||
82 | } | ||
83 | |||
84 | static char *strip_line(char *line) | ||
85 | { | ||
86 | char *p; | ||
87 | |||
88 | line = skip_over_blank(line); | ||
89 | |||
90 | p = line + strlen(line) - 1; | ||
91 | |||
92 | while (*line) { | ||
93 | if (isspace(*p)) | ||
94 | *p-- = '\0'; | ||
95 | else | ||
96 | break; | ||
97 | } | ||
98 | |||
99 | return line; | ||
100 | } | ||
101 | |||
102 | /* | ||
103 | * Start parsing a new line from the cache. | ||
104 | * | ||
105 | * line starts with "<device" return 1 -> continue parsing line | ||
106 | * line starts with "<foo", empty, or # return 0 -> skip line | ||
107 | * line starts with other, return -BLKID_ERR_CACHE -> error | ||
108 | */ | ||
109 | static int parse_start(char **cp) | ||
110 | { | ||
111 | char *p; | ||
112 | |||
113 | p = strip_line(*cp); | ||
114 | |||
115 | /* Skip comment or blank lines. We can't just NUL the first '#' char, | ||
116 | * in case it is inside quotes, or escaped. | ||
117 | */ | ||
118 | if (*p == '\0' || *p == '#') | ||
119 | return 0; | ||
120 | |||
121 | if (!strncmp(p, "<device", 7)) { | ||
122 | DBG(DEBUG_READ, printf("found device header: %8s\n", p)); | ||
123 | p += 7; | ||
124 | |||
125 | *cp = p; | ||
126 | return 1; | ||
127 | } | ||
128 | |||
129 | if (*p == '<') | ||
130 | return 0; | ||
131 | |||
132 | return -BLKID_ERR_CACHE; | ||
133 | } | ||
134 | |||
135 | /* Consume the remaining XML on the line (cosmetic only) */ | ||
136 | static int parse_end(char **cp) | ||
137 | { | ||
138 | *cp = skip_over_blank(*cp); | ||
139 | |||
140 | if (!strncmp(*cp, "</device>", 9)) { | ||
141 | DBG(DEBUG_READ, printf("found device trailer %9s\n", *cp)); | ||
142 | *cp += 9; | ||
143 | return 0; | ||
144 | } | ||
145 | |||
146 | return -BLKID_ERR_CACHE; | ||
147 | } | ||
148 | |||
149 | /* | ||
150 | * Allocate a new device struct with device name filled in. Will handle | ||
151 | * finding the device on lines of the form: | ||
152 | * <device foo=bar>devname</device> | ||
153 | * <device>devname<foo>bar</foo></device> | ||
154 | */ | ||
155 | static int parse_dev(blkid_cache cache, blkid_dev *dev, char **cp) | ||
156 | { | ||
157 | char *start, *tmp, *end, *name; | ||
158 | int ret; | ||
159 | |||
160 | if ((ret = parse_start(cp)) <= 0) | ||
161 | return ret; | ||
162 | |||
163 | start = tmp = strchr(*cp, '>'); | ||
164 | if (!start) { | ||
165 | DBG(DEBUG_READ, | ||
166 | printf("blkid: short line parsing dev: %s\n", *cp)); | ||
167 | return -BLKID_ERR_CACHE; | ||
168 | } | ||
169 | start = skip_over_blank(start + 1); | ||
170 | end = skip_over_word(start); | ||
171 | |||
172 | DBG(DEBUG_READ, printf("device should be %*s\n", end - start, start)); | ||
173 | |||
174 | if (**cp == '>') | ||
175 | *cp = end; | ||
176 | else | ||
177 | (*cp)++; | ||
178 | |||
179 | *tmp = '\0'; | ||
180 | |||
181 | if (!(tmp = strrchr(end, '<')) || parse_end(&tmp) < 0) { | ||
182 | DBG(DEBUG_READ, | ||
183 | printf("blkid: missing </device> ending: %s\n", end)); | ||
184 | } else if (tmp) | ||
185 | *tmp = '\0'; | ||
186 | |||
187 | if (end - start <= 1) { | ||
188 | DBG(DEBUG_READ, printf("blkid: empty device name: %s\n", *cp)); | ||
189 | return -BLKID_ERR_CACHE; | ||
190 | } | ||
191 | |||
192 | name = blkid_strndup(start, end-start); | ||
193 | if (name == NULL) | ||
194 | return -BLKID_ERR_MEM; | ||
195 | |||
196 | DBG(DEBUG_READ, printf("found dev %s\n", name)); | ||
197 | |||
198 | if (!(*dev = blkid_get_dev(cache, name, BLKID_DEV_CREATE))) | ||
199 | return -BLKID_ERR_MEM; | ||
200 | |||
201 | free(name); | ||
202 | return 1; | ||
203 | } | ||
204 | |||
205 | /* | ||
206 | * Extract a tag of the form NAME="value" from the line. | ||
207 | */ | ||
208 | static int parse_token(char **name, char **value, char **cp) | ||
209 | { | ||
210 | char *end; | ||
211 | |||
212 | if (!name || !value || !cp) | ||
213 | return -BLKID_ERR_PARAM; | ||
214 | |||
215 | if (!(*value = strchr(*cp, '='))) | ||
216 | return 0; | ||
217 | |||
218 | **value = '\0'; | ||
219 | *name = strip_line(*cp); | ||
220 | *value = skip_over_blank(*value + 1); | ||
221 | |||
222 | if (**value == '"') { | ||
223 | end = strchr(*value + 1, '"'); | ||
224 | if (!end) { | ||
225 | DBG(DEBUG_READ, | ||
226 | printf("unbalanced quotes at: %s\n", *value)); | ||
227 | *cp = *value; | ||
228 | return -BLKID_ERR_CACHE; | ||
229 | } | ||
230 | (*value)++; | ||
231 | *end = '\0'; | ||
232 | end++; | ||
233 | } else { | ||
234 | end = skip_over_word(*value); | ||
235 | if (*end) { | ||
236 | *end = '\0'; | ||
237 | end++; | ||
238 | } | ||
239 | } | ||
240 | *cp = end; | ||
241 | |||
242 | return 1; | ||
243 | } | ||
244 | |||
245 | /* | ||
246 | * Extract a tag of the form <NAME>value</NAME> from the line. | ||
247 | */ | ||
248 | /* | ||
249 | static int parse_xml(char **name, char **value, char **cp) | ||
250 | { | ||
251 | char *end; | ||
252 | |||
253 | if (!name || !value || !cp) | ||
254 | return -BLKID_ERR_PARAM; | ||
255 | |||
256 | *name = strip_line(*cp); | ||
257 | |||
258 | if ((*name)[0] != '<' || (*name)[1] == '/') | ||
259 | return 0; | ||
260 | |||
261 | FIXME: finish this. | ||
262 | } | ||
263 | */ | ||
264 | |||
265 | /* | ||
266 | * Extract a tag from the line. | ||
267 | * | ||
268 | * Return 1 if a valid tag was found. | ||
269 | * Return 0 if no tag found. | ||
270 | * Return -ve error code. | ||
271 | */ | ||
272 | static int parse_tag(blkid_cache cache, blkid_dev dev, char **cp) | ||
273 | { | ||
274 | char *name; | ||
275 | char *value; | ||
276 | int ret; | ||
277 | |||
278 | if (!cache || !dev) | ||
279 | return -BLKID_ERR_PARAM; | ||
280 | |||
281 | if ((ret = parse_token(&name, &value, cp)) <= 0 /* && | ||
282 | (ret = parse_xml(&name, &value, cp)) <= 0 */) | ||
283 | return ret; | ||
284 | |||
285 | /* Some tags are stored directly in the device struct */ | ||
286 | if (!strcmp(name, "DEVNO")) | ||
287 | dev->bid_devno = STRTOULL(value, 0, 0); | ||
288 | else if (!strcmp(name, "PRI")) | ||
289 | dev->bid_pri = strtol(value, 0, 0); | ||
290 | else if (!strcmp(name, "TIME")) | ||
291 | /* FIXME: need to parse a long long eventually */ | ||
292 | dev->bid_time = strtol(value, 0, 0); | ||
293 | else | ||
294 | ret = blkid_set_tag(dev, name, value, strlen(value)); | ||
295 | |||
296 | DBG(DEBUG_READ, printf(" tag: %s=\"%s\"\n", name, value)); | ||
297 | |||
298 | return ret < 0 ? ret : 1; | ||
299 | } | ||
300 | |||
301 | /* | ||
302 | * Parse a single line of data, and return a newly allocated dev struct. | ||
303 | * Add the new device to the cache struct, if one was read. | ||
304 | * | ||
305 | * Lines are of the form <device [TAG="value" ...]>/dev/foo</device> | ||
306 | * | ||
307 | * Returns -ve value on error. | ||
308 | * Returns 0 otherwise. | ||
309 | * If a valid device was read, *dev_p is non-NULL, otherwise it is NULL | ||
310 | * (e.g. comment lines, unknown XML content, etc). | ||
311 | */ | ||
312 | static int blkid_parse_line(blkid_cache cache, blkid_dev *dev_p, char *cp) | ||
313 | { | ||
314 | blkid_dev dev; | ||
315 | int ret; | ||
316 | |||
317 | if (!cache || !dev_p) | ||
318 | return -BLKID_ERR_PARAM; | ||
319 | |||
320 | *dev_p = NULL; | ||
321 | |||
322 | DBG(DEBUG_READ, printf("line: %s\n", cp)); | ||
323 | |||
324 | if ((ret = parse_dev(cache, dev_p, &cp)) <= 0) | ||
325 | return ret; | ||
326 | |||
327 | dev = *dev_p; | ||
328 | |||
329 | while ((ret = parse_tag(cache, dev, &cp)) > 0) { | ||
330 | ; | ||
331 | } | ||
332 | |||
333 | if (dev->bid_type == NULL) { | ||
334 | DBG(DEBUG_READ, | ||
335 | printf("blkid: device %s has no TYPE\n",dev->bid_name)); | ||
336 | blkid_free_dev(dev); | ||
337 | } | ||
338 | |||
339 | DBG(DEBUG_READ, blkid_debug_dump_dev(dev)); | ||
340 | |||
341 | return ret; | ||
342 | } | ||
343 | |||
344 | /* | ||
345 | * Parse the specified filename, and return the data in the supplied or | ||
346 | * a newly allocated cache struct. If the file doesn't exist, return a | ||
347 | * new empty cache struct. | ||
348 | */ | ||
349 | void blkid_read_cache(blkid_cache cache) | ||
350 | { | ||
351 | FILE *file; | ||
352 | char buf[4096]; | ||
353 | int fd, lineno = 0; | ||
354 | struct stat st; | ||
355 | |||
356 | if (!cache) | ||
357 | return; | ||
358 | |||
359 | /* | ||
360 | * If the file doesn't exist, then we just return an empty | ||
361 | * struct so that the cache can be populated. | ||
362 | */ | ||
363 | if ((fd = open(cache->bic_filename, O_RDONLY)) < 0) | ||
364 | return; | ||
365 | if (fstat(fd, &st) < 0) | ||
366 | goto errout; | ||
367 | if ((st.st_mtime == cache->bic_ftime) || | ||
368 | (cache->bic_flags & BLKID_BIC_FL_CHANGED)) { | ||
369 | DBG(DEBUG_CACHE, printf("skipping re-read of %s\n", | ||
370 | cache->bic_filename)); | ||
371 | goto errout; | ||
372 | } | ||
373 | |||
374 | DBG(DEBUG_CACHE, printf("reading cache file %s\n", | ||
375 | cache->bic_filename)); | ||
376 | |||
377 | file = fdopen(fd, "r"); | ||
378 | if (!file) | ||
379 | goto errout; | ||
380 | |||
381 | while (fgets(buf, sizeof(buf), file)) { | ||
382 | blkid_dev dev; | ||
383 | unsigned int end; | ||
384 | |||
385 | lineno++; | ||
386 | if (buf[0] == 0) | ||
387 | continue; | ||
388 | end = strlen(buf) - 1; | ||
389 | /* Continue reading next line if it ends with a backslash */ | ||
390 | while (buf[end] == '\\' && end < sizeof(buf) - 2 && | ||
391 | fgets(buf + end, sizeof(buf) - end, file)) { | ||
392 | end = strlen(buf) - 1; | ||
393 | lineno++; | ||
394 | } | ||
395 | |||
396 | if (blkid_parse_line(cache, &dev, buf) < 0) { | ||
397 | DBG(DEBUG_READ, | ||
398 | printf("blkid: bad format on line %d\n", lineno)); | ||
399 | continue; | ||
400 | } | ||
401 | } | ||
402 | fclose(file); | ||
403 | |||
404 | /* | ||
405 | * Initially we do not need to write out the cache file. | ||
406 | */ | ||
407 | cache->bic_flags &= ~BLKID_BIC_FL_CHANGED; | ||
408 | cache->bic_ftime = st.st_mtime; | ||
409 | |||
410 | return; | ||
411 | errout: | ||
412 | close(fd); | ||
413 | return; | ||
414 | } | ||
415 | |||
416 | #ifdef TEST_PROGRAM | ||
417 | static void debug_dump_dev(blkid_dev dev) | ||
418 | { | ||
419 | struct list_head *p; | ||
420 | |||
421 | if (!dev) { | ||
422 | printf(" dev: NULL\n"); | ||
423 | return; | ||
424 | } | ||
425 | |||
426 | printf(" dev: name = %s\n", dev->bid_name); | ||
427 | printf(" dev: DEVNO=\"0x%0llx\"\n", dev->bid_devno); | ||
428 | printf(" dev: TIME=\"%lu\"\n", dev->bid_time); | ||
429 | printf(" dev: PRI=\"%d\"\n", dev->bid_pri); | ||
430 | printf(" dev: flags = 0x%08X\n", dev->bid_flags); | ||
431 | |||
432 | list_for_each(p, &dev->bid_tags) { | ||
433 | blkid_tag tag = list_entry(p, struct blkid_struct_tag, bit_tags); | ||
434 | if (tag) | ||
435 | printf(" tag: %s=\"%s\"\n", tag->bit_name, | ||
436 | tag->bit_val); | ||
437 | else | ||
438 | printf(" tag: NULL\n"); | ||
439 | } | ||
440 | puts(""); | ||
441 | } | ||
442 | |||
443 | int main(int argc, char**argv) | ||
444 | { | ||
445 | blkid_cache cache = NULL; | ||
446 | int ret; | ||
447 | |||
448 | blkid_debug_mask = DEBUG_ALL; | ||
449 | if (argc > 2) { | ||
450 | fprintf(stderr, "Usage: %s [filename]\n" | ||
451 | "Test parsing of the cache (filename)\n", argv[0]); | ||
452 | exit(1); | ||
453 | } | ||
454 | if ((ret = blkid_get_cache(&cache, argv[1])) < 0) | ||
455 | fprintf(stderr, "error %d reading cache file %s\n", ret, | ||
456 | argv[1] ? argv[1] : BLKID_CACHE_FILE); | ||
457 | |||
458 | blkid_put_cache(cache); | ||
459 | |||
460 | return ret; | ||
461 | } | ||
462 | #endif | ||
diff --git a/e2fsprogs/blkid/resolve.c b/e2fsprogs/blkid/resolve.c deleted file mode 100644 index 7942de2cd..000000000 --- a/e2fsprogs/blkid/resolve.c +++ /dev/null | |||
@@ -1,139 +0,0 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * resolve.c - resolve names and tags into specific devices | ||
4 | * | ||
5 | * Copyright (C) 2001, 2003 Theodore Ts'o. | ||
6 | * Copyright (C) 2001 Andreas Dilger | ||
7 | * | ||
8 | * %Begin-Header% | ||
9 | * This file may be redistributed under the terms of the | ||
10 | * GNU Lesser General Public License. | ||
11 | * %End-Header% | ||
12 | */ | ||
13 | |||
14 | #include <stdio.h> | ||
15 | #ifdef HAVE_UNISTD_H | ||
16 | #include <unistd.h> | ||
17 | #endif | ||
18 | #include <stdlib.h> | ||
19 | #include <fcntl.h> | ||
20 | #include <string.h> | ||
21 | #include <sys/types.h> | ||
22 | #include <sys/stat.h> | ||
23 | #include "blkidP.h" | ||
24 | #include "probe.h" | ||
25 | |||
26 | /* | ||
27 | * Find a tagname (e.g. LABEL or UUID) on a specific device. | ||
28 | */ | ||
29 | char *blkid_get_tag_value(blkid_cache cache, const char *tagname, | ||
30 | const char *devname) | ||
31 | { | ||
32 | blkid_tag found; | ||
33 | blkid_dev dev; | ||
34 | blkid_cache c = cache; | ||
35 | char *ret = NULL; | ||
36 | |||
37 | DBG(DEBUG_RESOLVE, printf("looking for %s on %s\n", tagname, devname)); | ||
38 | |||
39 | if (!devname) | ||
40 | return NULL; | ||
41 | |||
42 | if (!cache) { | ||
43 | if (blkid_get_cache(&c, NULL) < 0) | ||
44 | return NULL; | ||
45 | } | ||
46 | |||
47 | if ((dev = blkid_get_dev(c, devname, BLKID_DEV_NORMAL)) && | ||
48 | (found = blkid_find_tag_dev(dev, tagname))) | ||
49 | ret = blkid_strdup(found->bit_val); | ||
50 | |||
51 | if (!cache) | ||
52 | blkid_put_cache(c); | ||
53 | |||
54 | return ret; | ||
55 | } | ||
56 | |||
57 | /* | ||
58 | * Locate a device name from a token (NAME=value string), or (name, value) | ||
59 | * pair. In the case of a token, value is ignored. If the "token" is not | ||
60 | * of the form "NAME=value" and there is no value given, then it is assumed | ||
61 | * to be the actual devname and a copy is returned. | ||
62 | */ | ||
63 | char *blkid_get_devname(blkid_cache cache, const char *token, | ||
64 | const char *value) | ||
65 | { | ||
66 | blkid_dev dev; | ||
67 | blkid_cache c = cache; | ||
68 | char *t = 0, *v = 0; | ||
69 | char *ret = NULL; | ||
70 | |||
71 | if (!token) | ||
72 | return NULL; | ||
73 | |||
74 | if (!cache) { | ||
75 | if (blkid_get_cache(&c, NULL) < 0) | ||
76 | return NULL; | ||
77 | } | ||
78 | |||
79 | DBG(DEBUG_RESOLVE, | ||
80 | printf("looking for %s%s%s %s\n", token, value ? "=" : "", | ||
81 | value ? value : "", cache ? "in cache" : "from disk")); | ||
82 | |||
83 | if (!value) { | ||
84 | if (!strchr(token, '=')) | ||
85 | return blkid_strdup(token); | ||
86 | blkid_parse_tag_string(token, &t, &v); | ||
87 | if (!t || !v) | ||
88 | goto errout; | ||
89 | token = t; | ||
90 | value = v; | ||
91 | } | ||
92 | |||
93 | dev = blkid_find_dev_with_tag(c, token, value); | ||
94 | if (!dev) | ||
95 | goto errout; | ||
96 | |||
97 | ret = blkid_strdup(blkid_dev_devname(dev)); | ||
98 | |||
99 | errout: | ||
100 | free(t); | ||
101 | free(v); | ||
102 | if (!cache) { | ||
103 | blkid_put_cache(c); | ||
104 | } | ||
105 | return ret; | ||
106 | } | ||
107 | |||
108 | #ifdef TEST_PROGRAM | ||
109 | int main(int argc, char **argv) | ||
110 | { | ||
111 | char *value; | ||
112 | blkid_cache cache; | ||
113 | |||
114 | blkid_debug_mask = DEBUG_ALL; | ||
115 | if (argc != 2 && argc != 3) { | ||
116 | fprintf(stderr, "Usage:\t%s tagname=value\n" | ||
117 | "\t%s tagname devname\n" | ||
118 | "Find which device holds a given token or\n" | ||
119 | "Find what the value of a tag is in a device\n", | ||
120 | argv[0], argv[0]); | ||
121 | exit(1); | ||
122 | } | ||
123 | if (blkid_get_cache(&cache, bb_dev_null) < 0) { | ||
124 | fprintf(stderr, "cannot get blkid cache\n"); | ||
125 | exit(1); | ||
126 | } | ||
127 | |||
128 | if (argv[2]) { | ||
129 | value = blkid_get_tag_value(cache, argv[1], argv[2]); | ||
130 | printf("%s has tag %s=%s\n", argv[2], argv[1], | ||
131 | value ? value : "<missing>"); | ||
132 | } else { | ||
133 | value = blkid_get_devname(cache, argv[1], NULL); | ||
134 | printf("%s has tag %s\n", value ? value : "<none>", argv[1]); | ||
135 | } | ||
136 | blkid_put_cache(cache); | ||
137 | return value ? 0 : 1; | ||
138 | } | ||
139 | #endif | ||
diff --git a/e2fsprogs/blkid/save.c b/e2fsprogs/blkid/save.c deleted file mode 100644 index cdbaabcb1..000000000 --- a/e2fsprogs/blkid/save.c +++ /dev/null | |||
@@ -1,189 +0,0 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * save.c - write the cache struct to disk | ||
4 | * | ||
5 | * Copyright (C) 2001 by Andreas Dilger | ||
6 | * Copyright (C) 2003 Theodore Ts'o | ||
7 | * | ||
8 | * %Begin-Header% | ||
9 | * This file may be redistributed under the terms of the | ||
10 | * GNU Lesser General Public License. | ||
11 | * %End-Header% | ||
12 | */ | ||
13 | |||
14 | #include <stdio.h> | ||
15 | #include <string.h> | ||
16 | #include <stdlib.h> | ||
17 | #include <unistd.h> | ||
18 | #include <sys/types.h> | ||
19 | #ifdef HAVE_SYS_STAT_H | ||
20 | #include <sys/stat.h> | ||
21 | #endif | ||
22 | #ifdef HAVE_SYS_MKDEV_H | ||
23 | #include <sys/mkdev.h> | ||
24 | #endif | ||
25 | #ifdef HAVE_ERRNO_H | ||
26 | #include <errno.h> | ||
27 | #endif | ||
28 | #include "blkidP.h" | ||
29 | |||
30 | static int save_dev(blkid_dev dev, FILE *file) | ||
31 | { | ||
32 | struct list_head *p; | ||
33 | |||
34 | if (!dev || dev->bid_name[0] != '/') | ||
35 | return 0; | ||
36 | |||
37 | DBG(DEBUG_SAVE, | ||
38 | printf("device %s, type %s\n", dev->bid_name, dev->bid_type)); | ||
39 | |||
40 | fprintf(file, | ||
41 | "<device DEVNO=\"0x%04lx\" TIME=\"%lu\"", | ||
42 | (unsigned long) dev->bid_devno, dev->bid_time); | ||
43 | if (dev->bid_pri) | ||
44 | fprintf(file, " PRI=\"%d\"", dev->bid_pri); | ||
45 | list_for_each(p, &dev->bid_tags) { | ||
46 | blkid_tag tag = list_entry(p, struct blkid_struct_tag, bit_tags); | ||
47 | fprintf(file, " %s=\"%s\"", tag->bit_name,tag->bit_val); | ||
48 | } | ||
49 | fprintf(file, ">%s</device>\n", dev->bid_name); | ||
50 | |||
51 | return 0; | ||
52 | } | ||
53 | |||
54 | /* | ||
55 | * Write out the cache struct to the cache file on disk. | ||
56 | */ | ||
57 | int blkid_flush_cache(blkid_cache cache) | ||
58 | { | ||
59 | struct list_head *p; | ||
60 | char *tmp = NULL; | ||
61 | const char *opened = NULL; | ||
62 | const char *filename; | ||
63 | FILE *file = NULL; | ||
64 | int fd, ret = 0; | ||
65 | struct stat st; | ||
66 | |||
67 | if (!cache) | ||
68 | return -BLKID_ERR_PARAM; | ||
69 | |||
70 | if (list_empty(&cache->bic_devs) || | ||
71 | !(cache->bic_flags & BLKID_BIC_FL_CHANGED)) { | ||
72 | DBG(DEBUG_SAVE, printf("skipping cache file write\n")); | ||
73 | return 0; | ||
74 | } | ||
75 | |||
76 | filename = cache->bic_filename ? cache->bic_filename: BLKID_CACHE_FILE; | ||
77 | |||
78 | /* If we can't write to the cache file, then don't even try */ | ||
79 | if (((ret = stat(filename, &st)) < 0 && errno != ENOENT) || | ||
80 | (ret == 0 && access(filename, W_OK) < 0)) { | ||
81 | DBG(DEBUG_SAVE, | ||
82 | printf("can't write to cache file %s\n", filename)); | ||
83 | return 0; | ||
84 | } | ||
85 | |||
86 | /* | ||
87 | * Try and create a temporary file in the same directory so | ||
88 | * that in case of error we don't overwrite the cache file. | ||
89 | * If the cache file doesn't yet exist, it isn't a regular | ||
90 | * file (e.g. /dev/null or a socket), or we couldn't create | ||
91 | * a temporary file then we open it directly. | ||
92 | */ | ||
93 | if (ret == 0 && S_ISREG(st.st_mode)) { | ||
94 | tmp = xmalloc(strlen(filename) + 8); | ||
95 | sprintf(tmp, "%s-XXXXXX", filename); | ||
96 | fd = mkstemp(tmp); | ||
97 | if (fd >= 0) { | ||
98 | file = fdopen(fd, "w"); | ||
99 | opened = tmp; | ||
100 | } | ||
101 | fchmod(fd, 0644); | ||
102 | } | ||
103 | |||
104 | if (!file) { | ||
105 | file = fopen(filename, "w"); | ||
106 | opened = filename; | ||
107 | } | ||
108 | |||
109 | DBG(DEBUG_SAVE, | ||
110 | printf("writing cache file %s (really %s)\n", | ||
111 | filename, opened)); | ||
112 | |||
113 | if (!file) { | ||
114 | ret = errno; | ||
115 | goto errout; | ||
116 | } | ||
117 | |||
118 | list_for_each(p, &cache->bic_devs) { | ||
119 | blkid_dev dev = list_entry(p, struct blkid_struct_dev, bid_devs); | ||
120 | if (!dev->bid_type) | ||
121 | continue; | ||
122 | if ((ret = save_dev(dev, file)) < 0) | ||
123 | break; | ||
124 | } | ||
125 | |||
126 | if (ret >= 0) { | ||
127 | cache->bic_flags &= ~BLKID_BIC_FL_CHANGED; | ||
128 | ret = 1; | ||
129 | } | ||
130 | |||
131 | fclose(file); | ||
132 | if (opened != filename) { | ||
133 | if (ret < 0) { | ||
134 | unlink(opened); | ||
135 | DBG(DEBUG_SAVE, | ||
136 | printf("unlinked temp cache %s\n", opened)); | ||
137 | } else { | ||
138 | char *backup; | ||
139 | |||
140 | backup = xmalloc(strlen(filename) + 5); | ||
141 | sprintf(backup, "%s.old", filename); | ||
142 | unlink(backup); | ||
143 | link(filename, backup); | ||
144 | free(backup); | ||
145 | rename(opened, filename); | ||
146 | DBG(DEBUG_SAVE, | ||
147 | printf("moved temp cache %s\n", opened)); | ||
148 | } | ||
149 | } | ||
150 | |||
151 | errout: | ||
152 | free(tmp); | ||
153 | return ret; | ||
154 | } | ||
155 | |||
156 | #ifdef TEST_PROGRAM | ||
157 | int main(int argc, char **argv) | ||
158 | { | ||
159 | blkid_cache cache = NULL; | ||
160 | int ret; | ||
161 | |||
162 | blkid_debug_mask = DEBUG_ALL; | ||
163 | if (argc > 2) { | ||
164 | fprintf(stderr, "Usage: %s [filename]\n" | ||
165 | "Test loading/saving a cache (filename)\n", argv[0]); | ||
166 | exit(1); | ||
167 | } | ||
168 | |||
169 | if ((ret = blkid_get_cache(&cache, bb_dev_null)) != 0) { | ||
170 | fprintf(stderr, "%s: error creating cache (%d)\n", | ||
171 | argv[0], ret); | ||
172 | exit(1); | ||
173 | } | ||
174 | if ((ret = blkid_probe_all(cache)) < 0) { | ||
175 | fprintf(stderr, "error (%d) probing devices\n", ret); | ||
176 | exit(1); | ||
177 | } | ||
178 | cache->bic_filename = blkid_strdup(argv[1]); | ||
179 | |||
180 | if ((ret = blkid_flush_cache(cache)) < 0) { | ||
181 | fprintf(stderr, "error (%d) saving cache\n", ret); | ||
182 | exit(1); | ||
183 | } | ||
184 | |||
185 | blkid_put_cache(cache); | ||
186 | |||
187 | return ret; | ||
188 | } | ||
189 | #endif | ||
diff --git a/e2fsprogs/blkid/tag.c b/e2fsprogs/blkid/tag.c deleted file mode 100644 index 9e862a50a..000000000 --- a/e2fsprogs/blkid/tag.c +++ /dev/null | |||
@@ -1,432 +0,0 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * tag.c - allocation/initialization/free routines for tag structs | ||
4 | * | ||
5 | * Copyright (C) 2001 Andreas Dilger | ||
6 | * Copyright (C) 2003 Theodore Ts'o | ||
7 | * | ||
8 | * %Begin-Header% | ||
9 | * This file may be redistributed under the terms of the | ||
10 | * GNU Lesser General Public License. | ||
11 | * %End-Header% | ||
12 | */ | ||
13 | |||
14 | #include <stdlib.h> | ||
15 | #include <string.h> | ||
16 | #include <stdio.h> | ||
17 | |||
18 | #include "blkidP.h" | ||
19 | |||
20 | static blkid_tag blkid_new_tag(void) | ||
21 | { | ||
22 | blkid_tag tag; | ||
23 | |||
24 | if (!(tag = (blkid_tag) calloc(1, sizeof(struct blkid_struct_tag)))) | ||
25 | return NULL; | ||
26 | |||
27 | INIT_LIST_HEAD(&tag->bit_tags); | ||
28 | INIT_LIST_HEAD(&tag->bit_names); | ||
29 | |||
30 | return tag; | ||
31 | } | ||
32 | |||
33 | #ifdef CONFIG_BLKID_DEBUG | ||
34 | void blkid_debug_dump_tag(blkid_tag tag) | ||
35 | { | ||
36 | if (!tag) { | ||
37 | printf(" tag: NULL\n"); | ||
38 | return; | ||
39 | } | ||
40 | |||
41 | printf(" tag: %s=\"%s\"\n", tag->bit_name, tag->bit_val); | ||
42 | } | ||
43 | #endif | ||
44 | |||
45 | void blkid_free_tag(blkid_tag tag) | ||
46 | { | ||
47 | if (!tag) | ||
48 | return; | ||
49 | |||
50 | DBG(DEBUG_TAG, printf(" freeing tag %s=%s\n", tag->bit_name, | ||
51 | tag->bit_val ? tag->bit_val : "(NULL)")); | ||
52 | DBG(DEBUG_TAG, blkid_debug_dump_tag(tag)); | ||
53 | |||
54 | list_del(&tag->bit_tags); /* list of tags for this device */ | ||
55 | list_del(&tag->bit_names); /* list of tags with this type */ | ||
56 | |||
57 | free(tag->bit_name); | ||
58 | free(tag->bit_val); | ||
59 | free(tag); | ||
60 | } | ||
61 | |||
62 | /* | ||
63 | * Find the desired tag on a device. If value is NULL, then the | ||
64 | * first such tag is returned, otherwise return only exact tag if found. | ||
65 | */ | ||
66 | blkid_tag blkid_find_tag_dev(blkid_dev dev, const char *type) | ||
67 | { | ||
68 | struct list_head *p; | ||
69 | |||
70 | if (!dev || !type) | ||
71 | return NULL; | ||
72 | |||
73 | list_for_each(p, &dev->bid_tags) { | ||
74 | blkid_tag tmp = list_entry(p, struct blkid_struct_tag, | ||
75 | bit_tags); | ||
76 | |||
77 | if (!strcmp(tmp->bit_name, type)) | ||
78 | return tmp; | ||
79 | } | ||
80 | return NULL; | ||
81 | } | ||
82 | |||
83 | /* | ||
84 | * Find the desired tag type in the cache. | ||
85 | * We return the head tag for this tag type. | ||
86 | */ | ||
87 | static blkid_tag blkid_find_head_cache(blkid_cache cache, const char *type) | ||
88 | { | ||
89 | blkid_tag head = NULL, tmp; | ||
90 | struct list_head *p; | ||
91 | |||
92 | if (!cache || !type) | ||
93 | return NULL; | ||
94 | |||
95 | list_for_each(p, &cache->bic_tags) { | ||
96 | tmp = list_entry(p, struct blkid_struct_tag, bit_tags); | ||
97 | if (!strcmp(tmp->bit_name, type)) { | ||
98 | DBG(DEBUG_TAG, | ||
99 | printf(" found cache tag head %s\n", type)); | ||
100 | head = tmp; | ||
101 | break; | ||
102 | } | ||
103 | } | ||
104 | return head; | ||
105 | } | ||
106 | |||
107 | /* | ||
108 | * Set a tag on an existing device. | ||
109 | * | ||
110 | * If value is NULL, then delete the tagsfrom the device. | ||
111 | */ | ||
112 | int blkid_set_tag(blkid_dev dev, const char *name, | ||
113 | const char *value, const int vlength) | ||
114 | { | ||
115 | blkid_tag t = 0, head = 0; | ||
116 | char *val = 0; | ||
117 | |||
118 | if (!dev || !name) | ||
119 | return -BLKID_ERR_PARAM; | ||
120 | |||
121 | if (!(val = blkid_strndup(value, vlength)) && value) | ||
122 | return -BLKID_ERR_MEM; | ||
123 | t = blkid_find_tag_dev(dev, name); | ||
124 | if (!value) { | ||
125 | blkid_free_tag(t); | ||
126 | } else if (t) { | ||
127 | if (!strcmp(t->bit_val, val)) { | ||
128 | /* Same thing, exit */ | ||
129 | free(val); | ||
130 | return 0; | ||
131 | } | ||
132 | free(t->bit_val); | ||
133 | t->bit_val = val; | ||
134 | } else { | ||
135 | /* Existing tag not present, add to device */ | ||
136 | if (!(t = blkid_new_tag())) | ||
137 | goto errout; | ||
138 | t->bit_name = blkid_strdup(name); | ||
139 | t->bit_val = val; | ||
140 | t->bit_dev = dev; | ||
141 | |||
142 | list_add_tail(&t->bit_tags, &dev->bid_tags); | ||
143 | |||
144 | if (dev->bid_cache) { | ||
145 | head = blkid_find_head_cache(dev->bid_cache, | ||
146 | t->bit_name); | ||
147 | if (!head) { | ||
148 | head = blkid_new_tag(); | ||
149 | if (!head) | ||
150 | goto errout; | ||
151 | |||
152 | DBG(DEBUG_TAG, | ||
153 | printf(" creating new cache tag head %s\n", name)); | ||
154 | head->bit_name = blkid_strdup(name); | ||
155 | if (!head->bit_name) | ||
156 | goto errout; | ||
157 | list_add_tail(&head->bit_tags, | ||
158 | &dev->bid_cache->bic_tags); | ||
159 | } | ||
160 | list_add_tail(&t->bit_names, &head->bit_names); | ||
161 | } | ||
162 | } | ||
163 | |||
164 | /* Link common tags directly to the device struct */ | ||
165 | if (!strcmp(name, "TYPE")) | ||
166 | dev->bid_type = val; | ||
167 | else if (!strcmp(name, "LABEL")) | ||
168 | dev->bid_label = val; | ||
169 | else if (!strcmp(name, "UUID")) | ||
170 | dev->bid_uuid = val; | ||
171 | |||
172 | if (dev->bid_cache) | ||
173 | dev->bid_cache->bic_flags |= BLKID_BIC_FL_CHANGED; | ||
174 | return 0; | ||
175 | |||
176 | errout: | ||
177 | blkid_free_tag(t); | ||
178 | if (!t) | ||
179 | free(val); | ||
180 | blkid_free_tag(head); | ||
181 | return -BLKID_ERR_MEM; | ||
182 | } | ||
183 | |||
184 | |||
185 | /* | ||
186 | * Parse a "NAME=value" string. This is slightly different than | ||
187 | * parse_token, because that will end an unquoted value at a space, while | ||
188 | * this will assume that an unquoted value is the rest of the token (e.g. | ||
189 | * if we are passed an already quoted string from the command-line we don't | ||
190 | * have to both quote and escape quote so that the quotes make it to | ||
191 | * us). | ||
192 | * | ||
193 | * Returns 0 on success, and -1 on failure. | ||
194 | */ | ||
195 | int blkid_parse_tag_string(const char *token, char **ret_type, char **ret_val) | ||
196 | { | ||
197 | char *name, *value, *cp; | ||
198 | |||
199 | DBG(DEBUG_TAG, printf("trying to parse '%s' as a tag\n", token)); | ||
200 | |||
201 | if (!token || !(cp = strchr(token, '='))) | ||
202 | return -1; | ||
203 | |||
204 | name = blkid_strdup(token); | ||
205 | if (!name) | ||
206 | return -1; | ||
207 | value = name + (cp - token); | ||
208 | *value++ = '\0'; | ||
209 | if (*value == '"' || *value == '\'') { | ||
210 | char c = *value++; | ||
211 | if (!(cp = strrchr(value, c))) | ||
212 | goto errout; /* missing closing quote */ | ||
213 | *cp = '\0'; | ||
214 | } | ||
215 | value = blkid_strdup(value); | ||
216 | if (!value) | ||
217 | goto errout; | ||
218 | |||
219 | *ret_type = name; | ||
220 | *ret_val = value; | ||
221 | |||
222 | return 0; | ||
223 | |||
224 | errout: | ||
225 | free(name); | ||
226 | return -1; | ||
227 | } | ||
228 | |||
229 | /* | ||
230 | * Tag iteration routines for the public libblkid interface. | ||
231 | * | ||
232 | * These routines do not expose the list.h implementation, which are a | ||
233 | * contamination of the namespace, and which force us to reveal far, far | ||
234 | * too much of our internal implemenation. I'm not convinced I want | ||
235 | * to keep list.h in the long term, anyway. It's fine for kernel | ||
236 | * programming, but performance is not the #1 priority for this | ||
237 | * library, and I really don't like the tradeoff of type-safety for | ||
238 | * performance for this application. [tytso:20030125.2007EST] | ||
239 | */ | ||
240 | |||
241 | /* | ||
242 | * This series of functions iterate over all tags in a device | ||
243 | */ | ||
244 | #define TAG_ITERATE_MAGIC 0x01a5284c | ||
245 | |||
246 | struct blkid_struct_tag_iterate { | ||
247 | int magic; | ||
248 | blkid_dev dev; | ||
249 | struct list_head *p; | ||
250 | }; | ||
251 | |||
252 | blkid_tag_iterate blkid_tag_iterate_begin(blkid_dev dev) | ||
253 | { | ||
254 | blkid_tag_iterate iter; | ||
255 | |||
256 | iter = xmalloc(sizeof(struct blkid_struct_tag_iterate)); | ||
257 | iter->magic = TAG_ITERATE_MAGIC; | ||
258 | iter->dev = dev; | ||
259 | iter->p = dev->bid_tags.next; | ||
260 | return iter; | ||
261 | } | ||
262 | |||
263 | /* | ||
264 | * Return 0 on success, -1 on error | ||
265 | */ | ||
266 | extern int blkid_tag_next(blkid_tag_iterate iter, | ||
267 | const char **type, const char **value) | ||
268 | { | ||
269 | blkid_tag tag; | ||
270 | |||
271 | *type = 0; | ||
272 | *value = 0; | ||
273 | if (!iter || iter->magic != TAG_ITERATE_MAGIC || | ||
274 | iter->p == &iter->dev->bid_tags) | ||
275 | return -1; | ||
276 | tag = list_entry(iter->p, struct blkid_struct_tag, bit_tags); | ||
277 | *type = tag->bit_name; | ||
278 | *value = tag->bit_val; | ||
279 | iter->p = iter->p->next; | ||
280 | return 0; | ||
281 | } | ||
282 | |||
283 | void blkid_tag_iterate_end(blkid_tag_iterate iter) | ||
284 | { | ||
285 | if (!iter || iter->magic != TAG_ITERATE_MAGIC) | ||
286 | return; | ||
287 | iter->magic = 0; | ||
288 | free(iter); | ||
289 | } | ||
290 | |||
291 | /* | ||
292 | * This function returns a device which matches a particular | ||
293 | * type/value pair. If there is more than one device that matches the | ||
294 | * search specification, it returns the one with the highest priority | ||
295 | * value. This allows us to give preference to EVMS or LVM devices. | ||
296 | * | ||
297 | * XXX there should also be an interface which uses an iterator so we | ||
298 | * can get all of the devices which match a type/value search parameter. | ||
299 | */ | ||
300 | extern blkid_dev blkid_find_dev_with_tag(blkid_cache cache, | ||
301 | const char *type, | ||
302 | const char *value) | ||
303 | { | ||
304 | blkid_tag head; | ||
305 | blkid_dev dev; | ||
306 | int pri; | ||
307 | struct list_head *p; | ||
308 | |||
309 | if (!cache || !type || !value) | ||
310 | return NULL; | ||
311 | |||
312 | blkid_read_cache(cache); | ||
313 | |||
314 | DBG(DEBUG_TAG, printf("looking for %s=%s in cache\n", type, value)); | ||
315 | |||
316 | try_again: | ||
317 | pri = -1; | ||
318 | dev = 0; | ||
319 | head = blkid_find_head_cache(cache, type); | ||
320 | |||
321 | if (head) { | ||
322 | list_for_each(p, &head->bit_names) { | ||
323 | blkid_tag tmp = list_entry(p, struct blkid_struct_tag, | ||
324 | bit_names); | ||
325 | |||
326 | if (!strcmp(tmp->bit_val, value) && | ||
327 | tmp->bit_dev->bid_pri > pri) { | ||
328 | dev = tmp->bit_dev; | ||
329 | pri = dev->bid_pri; | ||
330 | } | ||
331 | } | ||
332 | } | ||
333 | if (dev && !(dev->bid_flags & BLKID_BID_FL_VERIFIED)) { | ||
334 | dev = blkid_verify(cache, dev); | ||
335 | if (dev && (dev->bid_flags & BLKID_BID_FL_VERIFIED)) | ||
336 | goto try_again; | ||
337 | } | ||
338 | |||
339 | if (!dev && !(cache->bic_flags & BLKID_BIC_FL_PROBED)) { | ||
340 | if (blkid_probe_all(cache) < 0) | ||
341 | return NULL; | ||
342 | goto try_again; | ||
343 | } | ||
344 | return dev; | ||
345 | } | ||
346 | |||
347 | #ifdef TEST_PROGRAM | ||
348 | #ifdef HAVE_GETOPT_H | ||
349 | #include <getopt.h> | ||
350 | #else | ||
351 | extern char *optarg; | ||
352 | extern int optind; | ||
353 | #endif | ||
354 | |||
355 | void usage(char *prog) | ||
356 | { | ||
357 | fprintf(stderr, "Usage: %s [-f blkid_file] [-m debug_mask] device " | ||
358 | "[type value]\n", | ||
359 | prog); | ||
360 | fprintf(stderr, "\tList all tags for a device and exit\n", prog); | ||
361 | exit(1); | ||
362 | } | ||
363 | |||
364 | int main(int argc, char **argv) | ||
365 | { | ||
366 | blkid_tag_iterate iter; | ||
367 | blkid_cache cache = NULL; | ||
368 | blkid_dev dev; | ||
369 | int c, ret, found; | ||
370 | int flags = BLKID_DEV_FIND; | ||
371 | char *tmp; | ||
372 | char *file = NULL; | ||
373 | char *devname = NULL; | ||
374 | char *search_type = NULL; | ||
375 | char *search_value = NULL; | ||
376 | const char *type, *value; | ||
377 | |||
378 | while ((c = getopt (argc, argv, "m:f:")) != EOF) | ||
379 | switch (c) { | ||
380 | case 'f': | ||
381 | file = optarg; | ||
382 | break; | ||
383 | case 'm': | ||
384 | blkid_debug_mask = strtoul (optarg, &tmp, 0); | ||
385 | if (*tmp) { | ||
386 | fprintf(stderr, "Invalid debug mask: %d\n", | ||
387 | optarg); | ||
388 | exit(1); | ||
389 | } | ||
390 | break; | ||
391 | case '?': | ||
392 | usage(argv[0]); | ||
393 | } | ||
394 | if (argc > optind) | ||
395 | devname = argv[optind++]; | ||
396 | if (argc > optind) | ||
397 | search_type = argv[optind++]; | ||
398 | if (argc > optind) | ||
399 | search_value = argv[optind++]; | ||
400 | if (!devname || (argc != optind)) | ||
401 | usage(argv[0]); | ||
402 | |||
403 | if ((ret = blkid_get_cache(&cache, file)) != 0) { | ||
404 | fprintf(stderr, "%s: error creating cache (%d)\n", | ||
405 | argv[0], ret); | ||
406 | exit(1); | ||
407 | } | ||
408 | |||
409 | dev = blkid_get_dev(cache, devname, flags); | ||
410 | if (!dev) { | ||
411 | fprintf(stderr, "%s: cannot find device in blkid cache\n"); | ||
412 | exit(1); | ||
413 | } | ||
414 | if (search_type) { | ||
415 | found = blkid_dev_has_tag(dev, search_type, search_value); | ||
416 | printf("Device %s: (%s, %s) %s\n", blkid_dev_devname(dev), | ||
417 | search_type, search_value ? search_value : "NULL", | ||
418 | found ? "FOUND" : "NOT FOUND"); | ||
419 | return !found; | ||
420 | } | ||
421 | printf("Device %s...\n", blkid_dev_devname(dev)); | ||
422 | |||
423 | iter = blkid_tag_iterate_begin(dev); | ||
424 | while (blkid_tag_next(iter, &type, &value) == 0) { | ||
425 | printf("\tTag %s has value %s\n", type, value); | ||
426 | } | ||
427 | blkid_tag_iterate_end(iter); | ||
428 | |||
429 | blkid_put_cache(cache); | ||
430 | return 0; | ||
431 | } | ||
432 | #endif | ||