/* * Copyright (c) 2005 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this * file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. * * @APPLE_LICENSE_HEADER_END@ */ #include #include #include #include #include #include #include #include #define FSTYP_PREFIX "fstyp_" #define MAX_PATH_LEN 80 #define MAX_CMD_LEN (MAX_PATH_LEN * 2) #define NULL_REDIRECTION ">/dev/null 2>&1" void usage(void); int select_fstyp(const struct dirent * dp); int test(const char *dir, const struct dirent * dp, const char *dev); void dealloc(struct dirent ** dpp, int numElems); char *progname; /* * The fstyp command iterates through the binary directories to look for * commands of the form fstyp_* and runs them, trying to find one that * matches the given device. Once one of the returns success, fstyp * prints out that file system type name and terminates. 1 is returned * if any match is found, and 0 is returned if no match is found. */ int main(int argc, char *argv[]) { /* NULL-terminated list of directories to search for fstyp_* commands */ const char *DIRS[] = { "/bin/", "/sbin/", "/usr/bin/", "/usr/sbin/", "/usr/local/bin/", "/usr/local/sbin/", NULL}; int numMatches, i, j, found; struct stat sb; struct dirent **dpp; numMatches = 0; i = 0; j = 0; found = 0; if ((progname = strrchr(*argv, '/'))) ++progname; else progname = *argv; if (argc != 2) { usage(); return EX_USAGE; } if (0 == stat(argv[1], &sb)) { for (i = 0; (!found && (NULL != DIRS[i])); i++) { /* * scan DIRS[i] for files that start with * "fstyp_" */ numMatches = scandir(DIRS[i], &dpp, select_fstyp, NULL); if (numMatches >= 0) { for (j = 0; (!found && (j < numMatches)); j++) { if (test(DIRS[i], dpp[j], argv[1]) == 1) { puts(dpp[j]->d_name + 6); found = 1; } } dealloc(dpp, numMatches); dpp = NULL; } } } return found; } int select_fstyp(const struct dirent * dp) { return ((dp != NULL) && ((dp->d_type == DT_REG) || (dp->d_type == DT_LNK)) && (dp->d_namlen > strlen(FSTYP_PREFIX)) && (!strncmp(FSTYP_PREFIX, dp->d_name, strlen(FSTYP_PREFIX)))); } /* return dp if successful, else return NULL */ int test(const char *dir, const struct dirent * dp, const char *dev) { char cmd[MAX_CMD_LEN + 1] = {0}; int status; FILE *fileptr; status = 0; /* + 1 for white space */ if ((strlen(dir) + dp->d_namlen + 1 + strlen(dev) + strlen(NULL_REDIRECTION)) > MAX_CMD_LEN) { return 0; } snprintf(cmd, sizeof(cmd), "%s%s %s", dir, dp->d_name, dev); if ((fileptr = popen(cmd, "r")) != NULL) { status = pclose(fileptr); if (WIFEXITED(status)) { if (WEXITSTATUS(status) == 1) { return 1; } } } return 0; } void dealloc(struct dirent ** dpp, int numElems) { int i; for (i = 0; i < numElems; i++) { free(dpp[i]); dpp[i] = NULL; } free(dpp); return; } void usage(void) { fprintf(stdout, "usage: %s device\n", progname); return; }