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, va_list args) 59 { 60 char *filename; 61 struct stat sb; 62 63 memset(&sb, 0, sizeof(sb)); 64 65 vasprintf(&filename, fmt, args); 66 67 *error = stat(filename, &sb); 68 free(filename); 69 70 if (*error) 71 *m = 0; /* Do not leak fake mode */ 72 else 73 *m = sb.st_mode; 74 } 75 76 int 77 is_dir(const char *fmt, ...) 78 { 79 va_list args; 80 int error; 81 mode_t m; 82 83 va_start(args, fmt); 84 vstatmod(&m, &error, fmt, args); 85 va_end(args); 86 87 if (error == 0) 88 return(S_ISDIR(m)); 89 else 90 return(0); 91 } 92 93 int 94 is_file(const char *fmt, ...) 95 { 96 va_list args; 97 int error; 98 mode_t m; 99 100 va_start(args, fmt); 101 vstatmod(&m, &error, fmt, args); 102 va_end(args); 103 104 if (error == 0) 105 return(S_ISREG(m) ); 106 else 107 return(0); 108 109 } 110 111 int 112 is_program(const char *fmt, ...) 113 { 114 char *filename; 115 struct stat sb; 116 va_list args; 117 int error; 118 uid_t uid; 119 gid_t gid; 120 121 va_start(args, fmt); 122 vasprintf(&filename, fmt, args); 123 va_end(args); 124 125 error = stat(filename, &sb); 126 free(filename); 127 128 uid = getuid(); 129 gid = getgid(); 130 131 if (error == 0) { 132 /* Try to be more precise when identifying executable programs. 133 * Still this is subject to race conditions where the regular file 134 * might have its permissions/ownership changed during the test and 135 * thus provide inaccurate results. 136 * Also, effective uid/gid is not being checked. 137 */ 138 if ((S_ISREG(sb.st_mode)) && 139 ((sb.st_uid == uid && sb.st_mode & S_IXUSR) || 140 (sb.st_gid == gid && sb.st_mode & S_IXGRP) || 141 (sb.st_mode & S_IXOTH))) { 142 return 1; 143 } 144 } 145 146 return 0; 147 } 148 149 int 150 is_device(const char *fmt, ...) 151 { 152 va_list args; 153 int error; 154 mode_t m; 155 156 va_start(args, fmt); 157 vstatmod(&m, &error, fmt, args); 158 va_end(args); 159 160 if (error == 0) 161 return(S_ISBLK(m) || S_ISCHR(m)); 162 else 163 return(0); 164 } 165 166 int 167 is_named_pipe(const char *fmt, ...) 168 { 169 va_list args; 170 int error; 171 mode_t m; 172 173 va_start(args, fmt); 174 vstatmod(&m, &error, fmt, args); 175 va_end(args); 176 177 if (error == 0) 178 return(S_ISFIFO(m)); 179 else 180 return(0); 181 } 182 183 int 184 is_mountpoint_mounted(const char *mtpt) 185 { 186 struct statfs *mt_array, *mt_ptr; 187 int count; 188 189 count = getmntinfo(&mt_array, MNT_WAIT); 190 for (mt_ptr = mt_array; count > 0; mt_ptr++, count--) { 191 if (strncmp(mt_ptr->f_mntonname, mtpt, PATH_MAX) == 0) 192 return(1); 193 } 194 return(0); 195 } 196 197 int 198 is_device_mounted(const char *device) 199 { 200 struct statfs *mt_array, *mt_ptr; 201 int count; 202 203 count = getmntinfo(&mt_array, MNT_WAIT); 204 for (mt_ptr = mt_array; count > 0; mt_ptr++, count--) { 205 if (strncmp(mt_ptr->f_mntfromname, device, PATH_MAX) == 0) 206 return(1); 207 } 208 return(0); 209 } 210 211 int 212 is_any_slice_mounted(const char *diskdev) 213 { 214 struct statfs *mt_array, *mt_ptr; 215 int count; 216 217 count = getmntinfo(&mt_array, MNT_WAIT); 218 for (mt_ptr = mt_array; count > 0; mt_ptr++, count--) { 219 if (strstr(mt_ptr->f_mntfromname, diskdev) == 220 mt_ptr->f_mntfromname) 221 return(1); 222 } 223 return(0); 224 } 225