/* * fat_label - A utility to read the volume label off of a FAT filesystem. * * This utility will print out the volume label of a FAT filesystem if * it can find one. It knows how to cope with FAT12, FAT16, and FAT32 * filesystems. The filesystem may be a device or a plain file * containing a filesystem. * * Copyright (c) 2007 Jeramey Crawford * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include #include #include #include #include #include #include #include int fs_type (int); int main (int argc, char ** argv) { int i, fd, sr, fst; struct stat sb; char label[12]; if (argc != 2) { printf("usage: fat_label filename\n"); exit(0); } if ((sr = stat(argv[1], &sb)) == -1) { perror("fat_label"); exit(1); } fd = open(argv[1], O_RDONLY, 0777); fst = fs_type(fd); bzero(&label, 12); /* seek to the right place to read the label */ if (fst == 1) { /* FAT12/16 */ if (lseek(fd, 0x2b, SEEK_SET) == -1) { perror("fat_label"); exit(2); } } else if (fst == 2) { /* FAT32 */ if (lseek(fd, 0x47, SEEK_SET) == -1) { perror("fat_label"); exit(2); } } else { fprintf(stderr, "fat_label: Not a FAT filesystem\n"); exit(3); } if (read(fd, &label, 11) == -1) { perror("fat_label"); exit(2); } /* Strip out 0x20 padding at the end of the label. */ for (i = 10; i; i--) { if (label[i] == 0x20) label[i] = 0; else break; } if (!strlen(label)) fprintf(stderr, "fat_label: No label found\n"); else printf("%s\n", label); } int fs_type (int fd) /* * Return an integer describing the type of FAT found. * * 0 = No FAT * 1 = FAT12 or FAT16 * 2 = FAT32 * */ { char *fst; fst = (char *)calloc(9, sizeof(char)); if (!fst) { perror("fat_label: fstype"); exit(2); } /* Try FAT12 or FAT16 first */ if (lseek(fd, 0x36, SEEK_SET) == -1) { perror("fat_label: fs_type"); exit(2); } if (read(fd, fst, 8) == -1) { perror("fat_label: fs_type"); exit(2); } if (!strncmp(fst, "FAT12", 5) || !strncmp(fst, "FAT16", 5)) return 1; /* Maybe FAT32? */ if (lseek(fd, 0x52, SEEK_SET) == -1) { perror("fat_label: fs_type"); exit(2); } if (read(fd, fst, 8) == -1) { perror("fat_label: fs_type"); exit(2); } if (!strncmp(fst, "FAT32", 5)) return 2; return 0; /* no FAT type found */ }