1 /* 2 * Copyright (c) 2004 The DragonFly Project. All rights reserved. 3 * 4 * This code is derived from software contributed to The DragonFly Project 5 * by Chris Pressey <cpressey@catseye.mine.nu>. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * 3. Neither the name of The DragonFly Project nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific, prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 25 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 26 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, 27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 31 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 */ 34 35 36 /* 37 * fspred.c 38 * Filesystem predicates. 39 * $Id: fspred.c,v 1.3 2005/02/10 03:33:49 cpressey Exp $ 40 */ 41 42 #include <sys/stat.h> 43 #include <sys/param.h> 44 #include <sys/ucred.h> 45 #include <sys/mount.h> 46 47 #include <stdarg.h> 48 #include <stdio.h> 49 #include <stdlib.h> 50 #include <string.h> 51 #include <unistd.h> 52 53 #include "fspred.h" 54 55 /** PREDICATES **/ 56 57 static void 58 vstatmod(mode_t *m, int *error, const char *fmt, ...) 59 { 60 char *filename; 61 struct stat sb; 62 va_list args; 63 64 memset(&sb, 0, sizeof(sb)); 65 66 va_start(args, fmt); 67 vasprintf(&filename, fmt, args); 68 va_end(args); 69 70 *error = stat(filename, &sb); 71 free(filename); 72 73 if (*error) 74 *m = 0; /* Do not leak fake mode */ 75 else 76 *m = sb.st_mode; 77 } 78 79 int 80 is_dir(const char *fmt, ...) 81 { 82 va_list args; 83 int error; 84 mode_t m; 85 86 va_start(args, fmt); 87 vstatmod(&m, &error, fmt, args); 88 va_end(args); 89 90 if (error == 0) 91 return(S_ISDIR(m)); 92 else 93 return(0); 94 } 95 96 int 97 is_file(const char *fmt, ...) 98 { 99 va_list args; 100 int error; 101 mode_t m; 102 103 va_start(args, fmt); 104 vstatmod(&m, &error, fmt, args); 105 va_end(args); 106 107 if (error == 0) 108 return(S_ISREG(m) ); 109 else 110 return(0); 111 112 } 113 114 int 115 is_program(const char *fmt, ...) 116 { 117 char *filename; 118 struct stat sb; 119 va_list args; 120 int error; 121 uid_t uid; 122 gid_t gid; 123 124 va_start(args, fmt); 125 vasprintf(&filename, fmt, args); 126 va_end(args); 127 128 error = stat(filename, &sb); 129 free(filename); 130 131 uid = getuid(); 132 gid = getgid(); 133 134 if (error == 0) { 135 /* Try to be more precise when identifying executable programs. 136 * Still this is subject to race conditions where the regular file 137 * might have its permissions/ownership changed during the test and 138 * thus provide inaccurate results. 139 * Also, effective uid/gid is not being checked. 140 */ 141 if ((S_ISREG(sb.st_mode)) && 142 ((sb.st_uid == uid && sb.st_mode & S_IXUSR) || 143 (sb.st_gid == gid && sb.st_mode & S_IXGRP) || 144 (sb.st_mode & S_IXOTH))) { 145 return 1; 146 } 147 } 148 149 return 0; 150 } 151 152 int 153 is_device(const char *fmt, ...) 154 { 155 va_list args; 156 int error; 157 mode_t m; 158 159 va_start(args, fmt); 160 vstatmod(&m, &error, fmt, args); 161 va_end(args); 162 163 if (error == 0) 164 return(S_ISBLK(m) || S_ISCHR(m)); 165 else 166 return(0); 167 } 168 169 int 170 is_named_pipe(const char *fmt, ...) 171 { 172 va_list args; 173 int error; 174 mode_t m; 175 176 va_start(args, fmt); 177 vstatmod(&m, &error, fmt, args); 178 va_end(args); 179 180 if (error == 0) 181 return(S_ISFIFO(m)); 182 else 183 return(0); 184 } 185 186 int 187 is_mountpoint_mounted(const char *mtpt) 188 { 189 struct statfs *mt_array, *mt_ptr; 190 int count; 191 192 count = getmntinfo(&mt_array, MNT_WAIT); 193 for (mt_ptr = mt_array; count > 0; mt_ptr++, count--) { 194 if (strncmp(mt_ptr->f_mntonname, mtpt, PATH_MAX) == 0) 195 return(1); 196 } 197 return(0); 198 } 199 200 int 201 is_device_mounted(const char *device) 202 { 203 struct statfs *mt_array, *mt_ptr; 204 int count; 205 206 count = getmntinfo(&mt_array, MNT_WAIT); 207 for (mt_ptr = mt_array; count > 0; mt_ptr++, count--) { 208 if (strncmp(mt_ptr->f_mntfromname, device, PATH_MAX) == 0) 209 return(1); 210 } 211 return(0); 212 } 213 214 int 215 is_any_slice_mounted(const char *diskdev) 216 { 217 struct statfs *mt_array, *mt_ptr; 218 int count; 219 220 count = getmntinfo(&mt_array, MNT_WAIT); 221 for (mt_ptr = mt_array; count > 0; mt_ptr++, count--) { 222 if (strstr(mt_ptr->f_mntfromname, diskdev) == 223 mt_ptr->f_mntfromname) 224 return(1); 225 } 226 return(0); 227 } 228