mirror of
https://git.kernel.org/pub/scm/fs/ext2/e2fsprogs.git
synced 2024-11-24 18:43:53 +08:00
5599c2fa87
"ext3,ext2", etc. Added support for only searching for a specified list of filesystems. Also add support for identifying reiserfs filesystems.
111 lines
2.5 KiB
C
111 lines
2.5 KiB
C
/*
|
|
* fstype.c
|
|
*
|
|
* Copyright (C) 2001 Theodore Ts'o.
|
|
*
|
|
* %Begin-Header%
|
|
* This file may be redistributed under the terms of the GNU Public
|
|
* License.
|
|
* %End-Header%
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#if HAVE_UNISTD_H
|
|
#include <unistd.h>
|
|
#endif
|
|
#include <fcntl.h>
|
|
#include <sys/types.h>
|
|
|
|
#include "fsck.h"
|
|
|
|
struct fs_magic {
|
|
const char *fs_name;
|
|
int offset;
|
|
int len;
|
|
const char *magic;
|
|
};
|
|
|
|
#define REISERFS_SUPER_MAGIC_STRING "ReIsErFs"
|
|
#define REISER2FS_SUPER_MAGIC_STRING "ReIsEr2Fs"
|
|
#define REISERFS_DISK_OFFSET_IN_BYTES ((64 * 1024) + 52)
|
|
/* the spot for the super in versions 3.5 - 3.5.10 (inclusive) */
|
|
#define REISERFS_OLD_DISK_OFFSET_IN_BYTES ((8 * 1024) + 52)
|
|
|
|
struct fs_magic type_array[] = {
|
|
{ "ext2", 1024+56, 2, "\123\357" },
|
|
{ "ext3", 1024+56, 2, "\123\357" },
|
|
{ "reiserfs", REISERFS_DISK_OFFSET_IN_BYTES, 9,
|
|
REISER2FS_SUPER_MAGIC_STRING },
|
|
{ "reiserfs", REISERFS_DISK_OFFSET_IN_BYTES, 8,
|
|
REISERFS_SUPER_MAGIC_STRING },
|
|
{ "reiserfs", REISERFS_OLD_DISK_OFFSET_IN_BYTES, 9,
|
|
REISER2FS_SUPER_MAGIC_STRING },
|
|
{ "reiserfs", REISERFS_OLD_DISK_OFFSET_IN_BYTES, 8,
|
|
REISERFS_SUPER_MAGIC_STRING },
|
|
{ "minix", 1040, 2, "\177\023" },
|
|
{ "minix", 1040, 2, "\217\023" },
|
|
{ "minix", 1040, 2, "\150\044" },
|
|
{ "minix", 1040, 2, "\170\044" },
|
|
{ "xfs", 0, 4, "XFSB" },
|
|
{ 0, 0, 0, 0 }
|
|
};
|
|
|
|
const char *identify_fs(const char *fs_name, const char *fs_types)
|
|
{
|
|
char buf[73728], *s;
|
|
const char *t;
|
|
struct fs_magic *p;
|
|
int fd;
|
|
|
|
fd = open(fs_name, O_RDONLY);
|
|
if (fd < 0)
|
|
return NULL;
|
|
if (lseek(fd, 0, SEEK_SET) < 0)
|
|
return NULL;
|
|
if (read(fd, buf, sizeof(buf)) != sizeof(buf))
|
|
return NULL;
|
|
close(fd);
|
|
if (!fs_types || !strcmp(fs_types, "auto")) {
|
|
for (p = type_array; p->fs_name; p++) {
|
|
if (memcmp(p->magic, buf+p->offset, p->len) == 0)
|
|
return p->fs_name;
|
|
}
|
|
} else {
|
|
s = string_copy(fs_types);
|
|
for (t = strtok(s, ","); t; t = strtok(NULL, ",")) {
|
|
for (p = type_array; p->fs_name; p++) {
|
|
if (strcmp(p->fs_name, t))
|
|
continue;
|
|
if (memcmp(p->magic, buf+p->offset,
|
|
p->len) == 0) {
|
|
free(s);
|
|
return p->fs_name;
|
|
}
|
|
}
|
|
}
|
|
free(s);
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
#ifdef TEST_PROGRAM
|
|
int main(int argc, char **argv)
|
|
{
|
|
const char *type;
|
|
|
|
if (argc < 2 || argc > 3) {
|
|
fprintf(stderr, "Usage: %s [type list] device\n", argv[0]);
|
|
exit(1);
|
|
}
|
|
if (argc == 2) {
|
|
type = identify_fs(argv[1], NULL);
|
|
printf("%s is a %s filesystem\n", argv[1], type);
|
|
} else {
|
|
type = identify_fs(argv[2],argv[1]);
|
|
printf("%s is a %s filesystem\n", argv[2], type);
|
|
}
|
|
return (0);
|
|
}
|
|
#endif
|