Changeset View
Changeset View
Standalone View
Standalone View
usr.sbin/fstyp/fstyp.c
- This file was copied to lib/libfstyp/fstyp.c.
Show All 32 Lines | |||||
#include <sys/capsicum.h> | #include <sys/capsicum.h> | ||||
#include <sys/disk.h> | #include <sys/disk.h> | ||||
#include <sys/ioctl.h> | #include <sys/ioctl.h> | ||||
#include <sys/stat.h> | #include <sys/stat.h> | ||||
#include <capsicum_helpers.h> | #include <capsicum_helpers.h> | ||||
#include <err.h> | #include <err.h> | ||||
#include <errno.h> | #include <errno.h> | ||||
#ifdef WITH_ICONV | |||||
#include <iconv.h> | |||||
#endif | |||||
#include <locale.h> | #include <locale.h> | ||||
#include <stdbool.h> | #include <stdbool.h> | ||||
#include <stddef.h> | #include <stddef.h> | ||||
#include <stdio.h> | #include <stdio.h> | ||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#include <string.h> | #include <string.h> | ||||
#include <unistd.h> | #include <unistd.h> | ||||
#include <vis.h> | #include <vis.h> | ||||
#include "fstyp.h" | #include <fstyp.h> | ||||
#define LABEL_LEN 256 | #define LABEL_LEN 256 | ||||
bool show_label = false; | bool show_label = false; | ||||
typedef int (*fstyp_function)(FILE *, char *, size_t); | |||||
static struct { | |||||
const char *name; | |||||
fstyp_function function; | |||||
bool unmountable; | |||||
char *precache_encoding; | |||||
} fstypes[] = { | |||||
{ "apfs", &fstyp_apfs, true, NULL }, | |||||
{ "cd9660", &fstyp_cd9660, false, NULL }, | |||||
{ "exfat", &fstyp_exfat, false, EXFAT_ENC }, | |||||
{ "ext2fs", &fstyp_ext2fs, false, NULL }, | |||||
{ "geli", &fstyp_geli, true, NULL }, | |||||
{ "hammer", &fstyp_hammer, true, NULL }, | |||||
{ "hammer2", &fstyp_hammer2, true, NULL }, | |||||
{ "hfs+", &fstyp_hfsp, false, NULL }, | |||||
{ "msdosfs", &fstyp_msdosfs, false, NULL }, | |||||
{ "ntfs", &fstyp_ntfs, false, NTFS_ENC }, | |||||
{ "ufs", &fstyp_ufs, false, NULL }, | |||||
#ifdef HAVE_ZFS | |||||
{ "zfs", &fstyp_zfs, true, NULL }, | |||||
#endif | |||||
{ NULL, NULL, NULL, NULL } | |||||
}; | |||||
void * | |||||
read_buf(FILE *fp, off_t off, size_t len) | |||||
{ | |||||
int error; | |||||
size_t nread; | |||||
void *buf; | |||||
error = fseek(fp, off, SEEK_SET); | |||||
if (error != 0) { | |||||
warn("cannot seek to %jd", (uintmax_t)off); | |||||
return (NULL); | |||||
} | |||||
buf = malloc(len); | |||||
if (buf == NULL) { | |||||
warn("cannot malloc %zd bytes of memory", len); | |||||
return (NULL); | |||||
} | |||||
nread = fread(buf, len, 1, fp); | |||||
if (nread != 1) { | |||||
free(buf); | |||||
if (feof(fp) == 0) | |||||
warn("fread"); | |||||
return (NULL); | |||||
} | |||||
return (buf); | |||||
} | |||||
char * | |||||
checked_strdup(const char *s) | |||||
{ | |||||
char *c; | |||||
c = strdup(s); | |||||
if (c == NULL) | |||||
err(1, "strdup"); | |||||
return (c); | |||||
} | |||||
void | |||||
rtrim(char *label, size_t size) | |||||
{ | |||||
ptrdiff_t i; | |||||
for (i = size - 1; i >= 0; i--) { | |||||
if (label[i] == '\0') | |||||
continue; | |||||
else if (label[i] == ' ') | |||||
label[i] = '\0'; | |||||
else | |||||
break; | |||||
} | |||||
} | |||||
static void | static void | ||||
usage(void) | usage(void) | ||||
{ | { | ||||
fprintf(stderr, "usage: fstyp [-l] [-s] [-u] special\n"); | fprintf(stderr, "usage: fstyp [-l] [-s] [-u] special\n"); | ||||
exit(1); | exit(1); | ||||
} | } | ||||
static void | static void | ||||
type_check(const char *path, FILE *fp) | type_check(const char *path, FILE *fp) | ||||
{ | { | ||||
int error, fd; | int error, fd; | ||||
Show All 12 Lines | type_check(const char *path, FILE *fp) | ||||
error = ioctl(fd, DIOCGMEDIASIZE, &mediasize); | error = ioctl(fd, DIOCGMEDIASIZE, &mediasize); | ||||
if (error != 0) | if (error != 0) | ||||
errx(1, "%s: not a disk", path); | errx(1, "%s: not a disk", path); | ||||
} | } | ||||
int | int | ||||
main(int argc, char **argv) | main(int argc, char **argv) | ||||
{ | { | ||||
int ch, error, i, nbytes; | int ch, error, nbytes; | ||||
bool ignore_type = false, show_unmountable = false; | bool ignore_type = false, show_unmountable = false; | ||||
char label[LABEL_LEN + 1], strvised[LABEL_LEN * 4 + 1]; | char label[LABEL_LEN + 1], strvised[LABEL_LEN * 4 + 1]; | ||||
char *path; | char *path; | ||||
FILE *fp; | FILE *fp; | ||||
fstyp_function fstyp_f; | |||||
while ((ch = getopt(argc, argv, "lsu")) != -1) { | while ((ch = getopt(argc, argv, "lsu")) != -1) { | ||||
switch (ch) { | switch (ch) { | ||||
case 'l': | case 'l': | ||||
show_label = true; | show_label = true; | ||||
break; | break; | ||||
case 's': | case 's': | ||||
ignore_type = true; | ignore_type = true; | ||||
break; | break; | ||||
Show All 11 Lines | if (argc != 1) | ||||
usage(); | usage(); | ||||
path = argv[0]; | path = argv[0]; | ||||
if (setlocale(LC_CTYPE, "") == NULL) | if (setlocale(LC_CTYPE, "") == NULL) | ||||
err(1, "setlocale"); | err(1, "setlocale"); | ||||
caph_cache_catpages(); | caph_cache_catpages(); | ||||
#ifdef WITH_ICONV | |||||
/* Cache iconv conversion data before entering capability mode. */ | |||||
if (show_label) { | |||||
for (i = 0; i < nitems(fstypes); i++) { | |||||
iconv_t cd; | |||||
if (fstypes[i].precache_encoding == NULL) | if (show_label) { | ||||
continue; | enable_encodings(); | ||||
cd = iconv_open("", fstypes[i].precache_encoding); | |||||
if (cd == (iconv_t)-1) | |||||
err(1, "%s: iconv_open %s", fstypes[i].name, | |||||
fstypes[i].precache_encoding); | |||||
/* Iconv keeps a small cache of unused encodings. */ | |||||
iconv_close(cd); | |||||
} | } | ||||
} | |||||
#endif | |||||
fp = fopen(path, "r"); | fp = fopen(path, "r"); | ||||
if (fp == NULL) | if (fp == NULL) | ||||
err(1, "%s", path); | err(1, "%s", path); | ||||
if (caph_enter() < 0) | if (caph_enter() < 0) | ||||
err(1, "cap_enter"); | err(1, "cap_enter"); | ||||
if (ignore_type == false) | if (ignore_type == false) | ||||
type_check(path, fp); | type_check(path, fp); | ||||
memset(label, '\0', sizeof(label)); | memset(label, '\0', sizeof(label)); | ||||
for (i = 0;; i++) { | struct fstype const *result; | ||||
if (show_unmountable == false && fstypes[i].unmountable == true) | error = fstypef(fp, label, sizeof(label), show_unmountable, &result); | ||||
continue; | |||||
fstyp_f = fstypes[i].function; | |||||
if (fstyp_f == NULL) | |||||
break; | |||||
error = fstyp_f(fp, label, sizeof(label)); | if (error == -1) { | ||||
if (error == 0) | |||||
break; | |||||
} | |||||
if (fstypes[i].name == NULL) { | |||||
warnx("%s: filesystem not recognized", path); | warnx("%s: filesystem not recognized", path); | ||||
return (1); | return (1); | ||||
} | } | ||||
if (show_label && label[0] != '\0') { | if (show_label && label[0] != '\0') { | ||||
/* | /* | ||||
* XXX: I'd prefer VIS_HTTPSTYLE, but it unconditionally | * XXX: I'd prefer VIS_HTTPSTYLE, but it unconditionally | ||||
* encodes spaces. | * encodes spaces. | ||||
*/ | */ | ||||
nbytes = strsnvis(strvised, sizeof(strvised), label, | nbytes = strsnvis(strvised, sizeof(strvised), label, | ||||
VIS_GLOB | VIS_NL, "\"'$"); | VIS_GLOB | VIS_NL, "\"'$"); | ||||
if (nbytes == -1) | if (nbytes == -1) | ||||
err(1, "strsnvis"); | err(1, "strsnvis"); | ||||
printf("%s %s\n", fstypes[i].name, strvised); | printf("%s %s\n", result->name, strvised); | ||||
} else { | } else { | ||||
printf("%s\n", fstypes[i].name); | printf("%s\n", result->name); | ||||
} | } | ||||
return (0); | return (0); | ||||
} | } |