121c1c48aSSascha Wildner /* 221c1c48aSSascha Wildner * Copyright (c) 2004 The DragonFly Project. All rights reserved. 321c1c48aSSascha Wildner * 421c1c48aSSascha Wildner * This code is derived from software contributed to The DragonFly Project 521c1c48aSSascha Wildner * by Chris Pressey <cpressey@catseye.mine.nu>. 621c1c48aSSascha Wildner * 721c1c48aSSascha Wildner * Redistribution and use in source and binary forms, with or without 821c1c48aSSascha Wildner * modification, are permitted provided that the following conditions 921c1c48aSSascha Wildner * are met: 1021c1c48aSSascha Wildner * 1121c1c48aSSascha Wildner * 1. Redistributions of source code must retain the above copyright 1221c1c48aSSascha Wildner * notice, this list of conditions and the following disclaimer. 1321c1c48aSSascha Wildner * 2. Redistributions in binary form must reproduce the above copyright 1421c1c48aSSascha Wildner * notice, this list of conditions and the following disclaimer in 1521c1c48aSSascha Wildner * the documentation and/or other materials provided with the 1621c1c48aSSascha Wildner * distribution. 1721c1c48aSSascha Wildner * 3. Neither the name of The DragonFly Project nor the names of its 1821c1c48aSSascha Wildner * contributors may be used to endorse or promote products derived 1921c1c48aSSascha Wildner * from this software without specific, prior written permission. 2021c1c48aSSascha Wildner * 2121c1c48aSSascha Wildner * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2221c1c48aSSascha Wildner * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2321c1c48aSSascha Wildner * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 2421c1c48aSSascha Wildner * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 2521c1c48aSSascha Wildner * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 2621c1c48aSSascha Wildner * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, 2721c1c48aSSascha Wildner * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 2821c1c48aSSascha Wildner * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 2921c1c48aSSascha Wildner * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 3021c1c48aSSascha Wildner * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 3121c1c48aSSascha Wildner * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3221c1c48aSSascha Wildner * SUCH DAMAGE. 3321c1c48aSSascha Wildner */ 3421c1c48aSSascha Wildner 3521c1c48aSSascha Wildner 3621c1c48aSSascha Wildner /* 3721c1c48aSSascha Wildner * fspred.c 3821c1c48aSSascha Wildner * Filesystem predicates. 39d3d461a5SAntonio Huete Jimenez * $Id: fspred.c,v 1.3 2005/02/10 03:33:49 cpressey Exp $ 4021c1c48aSSascha Wildner */ 4121c1c48aSSascha Wildner 4221c1c48aSSascha Wildner #include <sys/stat.h> 4321c1c48aSSascha Wildner #include <sys/param.h> 4421c1c48aSSascha Wildner #include <sys/ucred.h> 4521c1c48aSSascha Wildner #include <sys/mount.h> 4621c1c48aSSascha Wildner 4721c1c48aSSascha Wildner #include <stdarg.h> 4821c1c48aSSascha Wildner #include <stdio.h> 4921c1c48aSSascha Wildner #include <stdlib.h> 5021c1c48aSSascha Wildner #include <string.h> 51eb5e0aceSAntonio Huete Jimenez #include <unistd.h> 5221c1c48aSSascha Wildner 5321c1c48aSSascha Wildner #include "fspred.h" 5421c1c48aSSascha Wildner 5521c1c48aSSascha Wildner /** PREDICATES **/ 5621c1c48aSSascha Wildner 57eb5e0aceSAntonio Huete Jimenez static void 58eb5e0aceSAntonio Huete Jimenez vstatmod(mode_t *m, int *error, const char *fmt, ...) 59eb5e0aceSAntonio Huete Jimenez { 60eb5e0aceSAntonio Huete Jimenez char *filename; 61eb5e0aceSAntonio Huete Jimenez struct stat sb; 629571bf02SAntonio Huete Jimenez va_list args; 63eb5e0aceSAntonio Huete Jimenez 64eb5e0aceSAntonio Huete Jimenez memset(&sb, 0, sizeof(sb)); 65eb5e0aceSAntonio Huete Jimenez 669571bf02SAntonio Huete Jimenez va_start(args, fmt); 679571bf02SAntonio Huete Jimenez vasprintf(&filename, fmt, args); 689571bf02SAntonio Huete Jimenez va_end(args); 69eb5e0aceSAntonio Huete Jimenez 70eb5e0aceSAntonio Huete Jimenez *error = stat(filename, &sb); 71eb5e0aceSAntonio Huete Jimenez free(filename); 72eb5e0aceSAntonio Huete Jimenez 73eb5e0aceSAntonio Huete Jimenez if (*error) 74eb5e0aceSAntonio Huete Jimenez *m = 0; /* Do not leak fake mode */ 75eb5e0aceSAntonio Huete Jimenez else 76eb5e0aceSAntonio Huete Jimenez *m = sb.st_mode; 77eb5e0aceSAntonio Huete Jimenez } 78eb5e0aceSAntonio Huete Jimenez 7921c1c48aSSascha Wildner int 8021c1c48aSSascha Wildner is_dir(const char *fmt, ...) 8121c1c48aSSascha Wildner { 829571bf02SAntonio Huete Jimenez va_list args; 83eb5e0aceSAntonio Huete Jimenez int error; 84eb5e0aceSAntonio Huete Jimenez mode_t m; 8521c1c48aSSascha Wildner 869571bf02SAntonio Huete Jimenez va_start(args, fmt); 879571bf02SAntonio Huete Jimenez vstatmod(&m, &error, fmt, args); 889571bf02SAntonio Huete Jimenez va_end(args); 8921c1c48aSSascha Wildner 90eb5e0aceSAntonio Huete Jimenez if (error == 0) 91eb5e0aceSAntonio Huete Jimenez return(S_ISDIR(m)); 9221c1c48aSSascha Wildner else 9321c1c48aSSascha Wildner return(0); 9421c1c48aSSascha Wildner } 9521c1c48aSSascha Wildner 9621c1c48aSSascha Wildner int 9721c1c48aSSascha Wildner is_file(const char *fmt, ...) 9821c1c48aSSascha Wildner { 999571bf02SAntonio Huete Jimenez va_list args; 100eb5e0aceSAntonio Huete Jimenez int error; 101eb5e0aceSAntonio Huete Jimenez mode_t m; 10221c1c48aSSascha Wildner 1039571bf02SAntonio Huete Jimenez va_start(args, fmt); 1049571bf02SAntonio Huete Jimenez vstatmod(&m, &error, fmt, args); 1059571bf02SAntonio Huete Jimenez va_end(args); 10621c1c48aSSascha Wildner 107eb5e0aceSAntonio Huete Jimenez if (error == 0) 108eb5e0aceSAntonio Huete Jimenez return(S_ISREG(m) ); 10921c1c48aSSascha Wildner else 11021c1c48aSSascha Wildner return(0); 111eb5e0aceSAntonio Huete Jimenez 11221c1c48aSSascha Wildner } 11321c1c48aSSascha Wildner 11421c1c48aSSascha Wildner int 11521c1c48aSSascha Wildner is_program(const char *fmt, ...) 11621c1c48aSSascha Wildner { 11721c1c48aSSascha Wildner char *filename; 11821c1c48aSSascha Wildner struct stat sb; 1199571bf02SAntonio Huete Jimenez va_list args; 120eb5e0aceSAntonio Huete Jimenez int error; 121eb5e0aceSAntonio Huete Jimenez uid_t uid; 122eb5e0aceSAntonio Huete Jimenez gid_t gid; 12321c1c48aSSascha Wildner 1249571bf02SAntonio Huete Jimenez va_start(args, fmt); 1259571bf02SAntonio Huete Jimenez vasprintf(&filename, fmt, args); 1269571bf02SAntonio Huete Jimenez va_end(args); 12721c1c48aSSascha Wildner 128eb5e0aceSAntonio Huete Jimenez error = stat(filename, &sb); 12921c1c48aSSascha Wildner free(filename); 13021c1c48aSSascha Wildner 131eb5e0aceSAntonio Huete Jimenez uid = getuid(); 132eb5e0aceSAntonio Huete Jimenez gid = getgid(); 133eb5e0aceSAntonio Huete Jimenez 134eed82809SAntonio Huete Jimenez if (error == 0) { 135eb5e0aceSAntonio Huete Jimenez /* Try to be more precise when identifying executable programs. 136eb5e0aceSAntonio Huete Jimenez * Still this is subject to race conditions where the regular file 137eb5e0aceSAntonio Huete Jimenez * might have its permissions/ownership changed during the test and 138eb5e0aceSAntonio Huete Jimenez * thus provide inaccurate results. 139eb5e0aceSAntonio Huete Jimenez * Also, effective uid/gid is not being checked. 140eb5e0aceSAntonio Huete Jimenez */ 141eb5e0aceSAntonio Huete Jimenez if ((S_ISREG(sb.st_mode)) && 142eb5e0aceSAntonio Huete Jimenez ((sb.st_uid == uid && sb.st_mode & S_IXUSR) || 143eb5e0aceSAntonio Huete Jimenez (sb.st_gid == gid && sb.st_mode & S_IXGRP) || 144eb5e0aceSAntonio Huete Jimenez (sb.st_mode & S_IXOTH))) { 145eb5e0aceSAntonio Huete Jimenez return 1; 146eb5e0aceSAntonio Huete Jimenez } 14721c1c48aSSascha Wildner } 14821c1c48aSSascha Wildner 149eed82809SAntonio Huete Jimenez return 0; 150eed82809SAntonio Huete Jimenez } 151eed82809SAntonio Huete Jimenez 15221c1c48aSSascha Wildner int 15321c1c48aSSascha Wildner is_device(const char *fmt, ...) 15421c1c48aSSascha Wildner { 1559571bf02SAntonio Huete Jimenez va_list args; 156eb5e0aceSAntonio Huete Jimenez int error; 157eb5e0aceSAntonio Huete Jimenez mode_t m; 15821c1c48aSSascha Wildner 1599571bf02SAntonio Huete Jimenez va_start(args, fmt); 1609571bf02SAntonio Huete Jimenez vstatmod(&m, &error, fmt, args); 1619571bf02SAntonio Huete Jimenez va_end(args); 16221c1c48aSSascha Wildner 163eb5e0aceSAntonio Huete Jimenez if (error == 0) 164eb5e0aceSAntonio Huete Jimenez return(S_ISBLK(m) || S_ISCHR(m)); 16521c1c48aSSascha Wildner else 16621c1c48aSSascha Wildner return(0); 16721c1c48aSSascha Wildner } 16821c1c48aSSascha Wildner 16921c1c48aSSascha Wildner int 17021c1c48aSSascha Wildner is_named_pipe(const char *fmt, ...) 17121c1c48aSSascha Wildner { 1729571bf02SAntonio Huete Jimenez va_list args; 173eb5e0aceSAntonio Huete Jimenez int error; 174eb5e0aceSAntonio Huete Jimenez mode_t m; 17521c1c48aSSascha Wildner 1769571bf02SAntonio Huete Jimenez va_start(args, fmt); 1779571bf02SAntonio Huete Jimenez vstatmod(&m, &error, fmt, args); 1789571bf02SAntonio Huete Jimenez va_end(args); 17921c1c48aSSascha Wildner 180eb5e0aceSAntonio Huete Jimenez if (error == 0) 181eb5e0aceSAntonio Huete Jimenez return(S_ISFIFO(m)); 18221c1c48aSSascha Wildner else 18321c1c48aSSascha Wildner return(0); 18421c1c48aSSascha Wildner } 18521c1c48aSSascha Wildner 18621c1c48aSSascha Wildner int 18721c1c48aSSascha Wildner is_mountpoint_mounted(const char *mtpt) 18821c1c48aSSascha Wildner { 18921c1c48aSSascha Wildner struct statfs *mt_array, *mt_ptr; 19021c1c48aSSascha Wildner int count; 19121c1c48aSSascha Wildner 19221c1c48aSSascha Wildner count = getmntinfo(&mt_array, MNT_WAIT); 19321c1c48aSSascha Wildner for (mt_ptr = mt_array; count > 0; mt_ptr++, count--) { 194*1536c7b8SAntonio Huete Jimenez if (strncmp(mt_ptr->f_mntonname, mtpt, PATH_MAX) == 0) 19521c1c48aSSascha Wildner return(1); 19621c1c48aSSascha Wildner } 19721c1c48aSSascha Wildner return(0); 19821c1c48aSSascha Wildner } 19921c1c48aSSascha Wildner 20021c1c48aSSascha Wildner int 20121c1c48aSSascha Wildner is_device_mounted(const char *device) 20221c1c48aSSascha Wildner { 20321c1c48aSSascha Wildner struct statfs *mt_array, *mt_ptr; 20421c1c48aSSascha Wildner int count; 20521c1c48aSSascha Wildner 20621c1c48aSSascha Wildner count = getmntinfo(&mt_array, MNT_WAIT); 20721c1c48aSSascha Wildner for (mt_ptr = mt_array; count > 0; mt_ptr++, count--) { 208*1536c7b8SAntonio Huete Jimenez if (strncmp(mt_ptr->f_mntfromname, device, PATH_MAX) == 0) 20921c1c48aSSascha Wildner return(1); 21021c1c48aSSascha Wildner } 21121c1c48aSSascha Wildner return(0); 21221c1c48aSSascha Wildner } 21321c1c48aSSascha Wildner 21421c1c48aSSascha Wildner int 21521c1c48aSSascha Wildner is_any_slice_mounted(const char *diskdev) 21621c1c48aSSascha Wildner { 21721c1c48aSSascha Wildner struct statfs *mt_array, *mt_ptr; 21821c1c48aSSascha Wildner int count; 21921c1c48aSSascha Wildner 22021c1c48aSSascha Wildner count = getmntinfo(&mt_array, MNT_WAIT); 22121c1c48aSSascha Wildner for (mt_ptr = mt_array; count > 0; mt_ptr++, count--) { 22221c1c48aSSascha Wildner if (strstr(mt_ptr->f_mntfromname, diskdev) == 22321c1c48aSSascha Wildner mt_ptr->f_mntfromname) 22421c1c48aSSascha Wildner return(1); 22521c1c48aSSascha Wildner } 22621c1c48aSSascha Wildner return(0); 22721c1c48aSSascha Wildner } 228