1 /* This procedure examines a file system and figures out whether it is 2 * version 1 or version 2. It returns the result as an int. If the 3 * file system is neither, it returns -1. A typical call is: 4 * 5 * n = fsversion("/dev/hd1", "df"); 6 * 7 * The first argument is the special file for the file system. 8 * The second is the program name, which is used in error messages. 9 */ 10 11 #include <sys/types.h> 12 #include <minix/config.h> 13 #include <minix/const.h> 14 #include <minix/minlib.h> 15 #include <minix/type.h> 16 #include <fcntl.h> 17 #include <unistd.h> 18 #include <stdio.h> 19 #include <string.h> 20 21 #include "mfs/const.h" 22 23 static char super[SUPER_BLOCK_BYTES]; 24 25 #define MAGIC_OFFSET_MFS 0x18 26 #define MAGIC_OFFSET_EXT 0x38 27 #define MAGIC_OFFSET_ISO9660 0x8000 28 #define MAGIC_VALUE_EXT2 0xef53 29 30 static int check_super(off_t offset, unsigned short magic) 31 { 32 return (memcmp(super + offset, &magic, sizeof(magic)) == 0) ? 1 : 0; 33 } 34 35 int fsversion(char *dev, char *prog) 36 { 37 int result = -1, fd; 38 39 if ((fd = open(dev, O_RDONLY)) < 0) { 40 std_err(prog); 41 std_err(" cannot open "); 42 perror(dev); 43 return(-1); 44 } 45 46 lseek(fd, (off_t) SUPER_BLOCK_BYTES, SEEK_SET); /* skip boot block */ 47 if (read(fd, (char *) &super, sizeof(super)) != sizeof(super)) { 48 std_err(prog); 49 std_err(" cannot read super block on "); 50 perror(dev); 51 close(fd); 52 return(-1); 53 } 54 55 /* first check MFS, a valid MFS may look like EXT but not vice versa */ 56 if (check_super(MAGIC_OFFSET_MFS, SUPER_MAGIC)) { 57 result = FSVERSION_MFS1; 58 goto done; 59 } 60 else if (check_super(MAGIC_OFFSET_MFS, SUPER_V2)) { 61 result = FSVERSION_MFS2; 62 goto done; 63 } 64 else if (check_super(MAGIC_OFFSET_MFS, SUPER_V3)) { 65 result = FSVERSION_MFS3; 66 goto done; 67 } 68 69 /* check ext2 */ 70 if (check_super(MAGIC_OFFSET_EXT, MAGIC_VALUE_EXT2)) { 71 result = FSVERSION_EXT2; 72 goto done; 73 } 74 75 /* check ISO 9660 */ 76 lseek(fd, (off_t) MAGIC_OFFSET_ISO9660, SEEK_SET); 77 if (read(fd, (char *) &super, sizeof(super)) == sizeof(super)) { 78 if (memcmp(super+1, "CD001", 5) == 0) { 79 result = FSVERSION_ISO9660; 80 goto done; 81 } 82 } 83 84 done: 85 close(fd); 86 return result; 87 } 88