chiark / gitweb /
volume_id: add squashfs detection
[elogind.git] / extras / volume_id / libvolume_id / volume_id.c
1 /*
2  * volume_id - reads filesystem label and uuid
3  *
4  * Copyright (C) 2005 Kay Sievers <kay.sievers@vrfy.org>
5  *
6  *      This program is free software; you can redistribute it and/or modify it
7  *      under the terms of the GNU General Public License as published by the
8  *      Free Software Foundation version 2 of the License.
9  */
10
11 #ifndef _GNU_SOURCE
12 #define _GNU_SOURCE 1
13 #endif
14
15 #ifdef HAVE_CONFIG_H
16 #  include <config.h>
17 #endif
18
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <unistd.h>
22 #include <string.h>
23 #include <errno.h>
24 #include <errno.h>
25 #include <ctype.h>
26 #include <fcntl.h>
27 #include <sys/stat.h>
28
29 #include "volume_id.h"
30 #include "logging.h"
31 #include "util.h"
32
33
34 int volume_id_probe_raid(struct volume_id *id, uint64_t off, uint64_t size)
35 {
36         if (id == NULL)
37                 return -EINVAL;
38
39         /* probe for raid first, cause fs probes may be successful on raid members */
40         if (size) {
41                 if (volume_id_probe_linux_raid(id, off, size) == 0)
42                         goto found;
43
44                 if (volume_id_probe_intel_software_raid(id, off, size) == 0)
45                         goto found;
46
47                 if (volume_id_probe_lsi_mega_raid(id, off, size) == 0)
48                         goto found;
49
50                 if (volume_id_probe_via_raid(id, off, size) == 0)
51                         goto found;
52
53                 if (volume_id_probe_silicon_medley_raid(id, off, size) == 0)
54                         goto found;
55
56                 if (volume_id_probe_nvidia_raid(id, off, size) == 0)
57                         goto found;
58
59                 if (volume_id_probe_promise_fasttrack_raid(id, off, size) == 0)
60                         goto found;
61
62                 if (volume_id_probe_highpoint_45x_raid(id, off, size) == 0)
63                         goto found;
64         }
65
66         if (volume_id_probe_lvm1(id, off) == 0)
67                 goto found;
68
69         if (volume_id_probe_lvm2(id, off) == 0)
70                 goto found;
71
72         if (volume_id_probe_highpoint_37x_raid(id, off) == 0)
73                 goto found;
74
75         return -1;
76
77 found:
78         /* If recognized, we free the allocated buffers */
79         volume_id_free_buffer(id);
80         return 0;
81 }
82
83 int volume_id_probe_filesystem(struct volume_id *id, uint64_t off, uint64_t size)
84 {
85         if (id == NULL)
86                 return -EINVAL;
87
88         if (volume_id_probe_luks(id, off) == 0)
89                 goto found;
90
91         /* signature in the first block, only small buffer needed */
92         if (volume_id_probe_vfat(id, off) == 0)
93                 goto found;
94
95         if (volume_id_probe_xfs(id, off) == 0)
96                 goto found;
97
98         /* fill buffer with maximum */
99         volume_id_get_buffer(id, 0, SB_BUFFER_SIZE);
100
101         if (volume_id_probe_linux_swap(id, off) == 0)
102                 goto found;
103
104         if (volume_id_probe_ext(id, off) == 0)
105                 goto found;
106
107         if (volume_id_probe_reiserfs(id, off) == 0)
108                 goto found;
109
110         if (volume_id_probe_jfs(id, off) == 0)
111                 goto found;
112
113         if (volume_id_probe_udf(id, off) == 0)
114                 goto found;
115
116         if (volume_id_probe_iso9660(id, off) == 0)
117                 goto found;
118
119         if (volume_id_probe_hfs_hfsplus(id, off) == 0)
120                 goto found;
121
122         if (volume_id_probe_ufs(id, off) == 0)
123                 goto found;
124
125         if (volume_id_probe_ntfs(id, off)  == 0)
126                 goto found;
127
128         if (volume_id_probe_cramfs(id, off) == 0)
129                 goto found;
130
131         if (volume_id_probe_romfs(id, off) == 0)
132                 goto found;
133
134         if (volume_id_probe_hpfs(id, off) == 0)
135                 goto found;
136
137         if (volume_id_probe_sysv(id, off) == 0)
138                 goto found;
139
140         if (volume_id_probe_minix(id, off) == 0)
141                 goto found;
142
143         if (volume_id_probe_ocfs1(id, off) == 0)
144                 goto found;
145
146         if (volume_id_probe_ocfs2(id, off) == 0)
147                 goto found;
148
149         if (volume_id_probe_vxfs(id, off) == 0)
150                 goto found;
151
152         if (volume_id_probe_squashfs(id, off) == 0)
153                 goto found;
154
155         return -1;
156
157 found:
158         /* If recognized, we free the allocated buffers */
159         volume_id_free_buffer(id);
160         return 0;
161 }
162
163 int volume_id_probe_all(struct volume_id *id, uint64_t off, uint64_t size)
164 {
165         if (id == NULL)
166                 return -EINVAL;
167
168         if (volume_id_probe_raid(id, off, size) == 0)
169                 return 0;
170
171         if (volume_id_probe_filesystem(id, off, size) == 0)
172                 return 0;
173
174         return -1;
175 }
176
177 /* open volume by already open file descriptor */
178 struct volume_id *volume_id_open_fd(int fd)
179 {
180         struct volume_id *id;
181
182         id = malloc(sizeof(struct volume_id));
183         if (id == NULL)
184                 return NULL;
185         memset(id, 0x00, sizeof(struct volume_id));
186
187         id->fd = fd;
188
189         return id;
190 }
191
192 /* open volume by device node */
193 struct volume_id *volume_id_open_node(const char *path)
194 {
195         struct volume_id *id;
196         int fd;
197
198         fd = open(path, O_RDONLY);
199         if (fd < 0) {
200                 dbg("unable to open '%s'", path);
201                 return NULL;
202         }
203
204         id = volume_id_open_fd(fd);
205         if (id == NULL)
206                 return NULL;
207
208         /* close fd on device close */
209         id->fd_close = 1;
210
211         return id;
212 }
213
214 void volume_id_close(struct volume_id *id)
215 {
216         if (id == NULL)
217                 return;
218
219         if (id->fd_close != 0)
220                 close(id->fd);
221
222         volume_id_free_buffer(id);
223
224         if (id->partitions != NULL)
225                 free(id->partitions);
226
227         free(id);
228 }