1/* 2 * Copyright (c) 2005 Apple Computer, Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24#include <sys/types.h> 25#include <sys/stat.h> 26#include <dirent.h> 27#include <stdio.h> 28#include <string.h> 29#include <stdlib.h> 30#include <unistd.h> 31#include <sysexits.h> 32 33#define FSTYP_PREFIX "fstyp_" 34#define MAX_PATH_LEN 80 35#define MAX_CMD_LEN (MAX_PATH_LEN * 2) 36#define NULL_REDIRECTION ">/dev/null 2>&1" 37 38void usage(void); 39int select_fstyp(const struct dirent * dp); 40int test(const char *dir, const struct dirent * dp, const char *dev); 41void dealloc(struct dirent ** dpp, int numElems); 42 43char *progname; 44 45/* 46 * The fstyp command iterates through the binary directories to look for 47 * commands of the form fstyp_* and runs them, trying to find one that 48 * matches the given device. Once one of the returns success, fstyp 49 * prints out that file system type name and terminates. 1 is returned 50 * if any match is found, and 0 is returned if no match is found. 51 */ 52 53int 54main(int argc, char *argv[]) 55{ 56 /* NULL-terminated list of directories to search for fstyp_* commands */ 57 const char *DIRS[] = { "/bin/", 58 "/sbin/", 59 "/usr/bin/", 60 "/usr/sbin/", 61 "/usr/local/bin/", 62 "/usr/local/sbin/", 63 NULL}; 64 65 int numMatches, i, j, found; 66 struct stat sb; 67 struct dirent **dpp; 68 69 numMatches = 0; 70 i = 0; 71 j = 0; 72 found = 0; 73 74 if ((progname = strrchr(*argv, '/'))) 75 ++progname; 76 else 77 progname = *argv; 78 79 if (argc != 2) { 80 usage(); 81 return EX_USAGE; 82 } 83 if (0 == stat(argv[1], &sb)) { 84 for (i = 0; (!found && (NULL != DIRS[i])); i++) { 85 /* 86 * scan DIRS[i] for files that start with 87 * "fstyp_" 88 */ 89 numMatches = scandir(DIRS[i], &dpp, select_fstyp, NULL); 90 91 if (numMatches >= 0) { 92 for (j = 0; (!found && (j < numMatches)); j++) { 93 if (test(DIRS[i], dpp[j], argv[1]) == 1) { 94 puts(dpp[j]->d_name + 6); 95 96 found = 1; 97 } 98 } 99 100 dealloc(dpp, numMatches); 101 dpp = NULL; 102 } 103 } 104 } 105 return found; 106} 107 108int 109select_fstyp(const struct dirent * dp) 110{ 111 return ((dp != NULL) && 112 ((dp->d_type == DT_REG) || (dp->d_type == DT_LNK)) && 113 (dp->d_namlen > strlen(FSTYP_PREFIX)) && 114 (!strncmp(FSTYP_PREFIX, dp->d_name, strlen(FSTYP_PREFIX)))); 115} 116 117/* return dp if successful, else return NULL */ 118int 119test(const char *dir, const struct dirent * dp, const char *dev) 120{ 121 char cmd[MAX_CMD_LEN + 1] = {0}; 122 int status; 123 FILE *fileptr; 124 125 status = 0; 126 127 /* + 1 for white space */ 128 if ((strlen(dir) + dp->d_namlen + 1 + strlen(dev) + 129 strlen(NULL_REDIRECTION)) > MAX_CMD_LEN) { 130 return 0; 131 } 132 snprintf(cmd, sizeof(cmd), "%s%s %s", dir, dp->d_name, dev); 133 134 if ((fileptr = popen(cmd, "r")) != NULL) { 135 status = pclose(fileptr); 136 137 if (WIFEXITED(status)) { 138 if (WEXITSTATUS(status) == 1) { 139 return 1; 140 } 141 } 142 } 143 return 0; 144} 145 146void 147dealloc(struct dirent ** dpp, int numElems) 148{ 149 int i; 150 151 for (i = 0; i < numElems; i++) { 152 free(dpp[i]); 153 dpp[i] = NULL; 154 } 155 156 free(dpp); 157 158 return; 159} 160 161 162void 163usage(void) 164{ 165 fprintf(stdout, "usage: %s device\n", progname); 166 return; 167} 168