extattrctl.c revision 59446
1234370Sjasone/*- 2234370Sjasone * Copyright (c) 1999, 2000 Robert N. M. Watson 3234370Sjasone * All rights reserved. 4234370Sjasone * 5234370Sjasone * Redistribution and use in source and binary forms, with or without 6234370Sjasone * modification, are permitted provided that the following conditions 7234370Sjasone * are met: 8234370Sjasone * 1. Redistributions of source code must retain the above copyright 9234370Sjasone * notice, this list of conditions and the following disclaimer. 10234370Sjasone * 2. Redistributions in binary form must reproduce the above copyright 11234370Sjasone * notice, this list of conditions and the following disclaimer in the 12234370Sjasone * documentation and/or other materials provided with the distribution. 13234370Sjasone * 14234370Sjasone * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15234370Sjasone * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16234370Sjasone * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17234370Sjasone * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18234370Sjasone * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19234370Sjasone * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20234370Sjasone * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21234370Sjasone * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22234370Sjasone * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23234370Sjasone * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24234370Sjasone * SUCH DAMAGE. 25234370Sjasone * 26234370Sjasone * $FreeBSD: head/usr.sbin/extattrctl/extattrctl.c 59446 2000-04-20 20:32:43Z rwatson $ 27234370Sjasone */ 28234370Sjasone/* 29234370Sjasone * TrustedBSD Project - extended attribute support for UFS-like file systems 30234370Sjasone */ 31234370Sjasone 32234370Sjasone#include <sys/types.h> 33234370Sjasone#include <sys/uio.h> 34234370Sjasone#include <sys/extattr.h> 35234370Sjasone#include <sys/param.h> 36234370Sjasone#include <sys/mount.h> 37234370Sjasone 38234370Sjasone#include <ufs/ufs/extattr.h> 39234370Sjasone 40234370Sjasone#include <fcntl.h> 41234370Sjasone#include <stdio.h> 42234370Sjasone#include <stdlib.h> 43234370Sjasone#include <string.h> 44234370Sjasone#include <unistd.h> 45234370Sjasone 46234370Sjasoneextern char *optarg; 47234370Sjasoneextern int optind; 48234370Sjasone 49234370Sjasonevoid 50234370Sjasoneusage(void) 51234370Sjasone{ 52234370Sjasone 53234370Sjasone fprintf(stderr, 54234370Sjasone "usage:\n" 55234370Sjasone " extattrctl start [path]\n" 56234370Sjasone " extattrctl stop [path]\n" 57234370Sjasone " extattrctl initattr [-p path] [-r [kroa]] [-w [kroa]] " 58234370Sjasone "[attrsize] [attrfile]\n" 59234370Sjasone " extattrctl enable [path] [attrname] [attrfile]\n" 60234370Sjasone " extattrctl disable [path] [attrname]\n"); 61234370Sjasone exit(-1); 62234370Sjasone} 63234370Sjasone 64234370Sjasone/* 65234370Sjasone * Return a level, or -1 66234370Sjasone */ 67234370Sjasoneint 68234370Sjasoneextattr_level_from_string(char *string) 69234370Sjasone{ 70234370Sjasone 71234370Sjasone if (strlen(string) != 1) 72234370Sjasone return (-1); 73234370Sjasone 74234370Sjasone switch(string[0]) { 75234370Sjasone case 'k': 76234370Sjasone case 'K': 77234370Sjasone return (UFS_EXTATTR_PERM_KERNEL); 78234370Sjasone case 'r': 79234370Sjasone case 'R': 80234370Sjasone return (UFS_EXTATTR_PERM_ROOT); 81234370Sjasone case 'o': 82234370Sjasone case 'O': 83234370Sjasone return (UFS_EXTATTR_PERM_OWNER); 84234370Sjasone case 'a': 85234370Sjasone case 'A': 86234370Sjasone return (UFS_EXTATTR_PERM_ANYONE); 87234370Sjasone default: 88234370Sjasone return (-1); 89234370Sjasone } 90234370Sjasone} 91234370Sjasone 92234370Sjasonelong 93234370Sjasonenum_inodes_by_path(char *path) 94234370Sjasone{ 95234370Sjasone struct statfs buf; 96234370Sjasone int error; 97234370Sjasone 98234370Sjasone error = statfs(path, &buf); 99234370Sjasone if (error) { 100234370Sjasone perror("statfs"); 101234370Sjasone return (-1); 102234370Sjasone } 103234370Sjasone 104234370Sjasone return (buf.f_files); 105234370Sjasone} 106234370Sjasone 107234370Sjasoneint 108234370Sjasoneinitattr(int argc, char *argv[]) 109234370Sjasone{ 110234370Sjasone struct ufs_extattr_fileheader uef; 111234370Sjasone char *fs_path = NULL; 112234370Sjasone char *zero_buf = NULL; 113234370Sjasone long loop, num_inodes; 114234370Sjasone int initattr_rlevel = UFS_EXTATTR_PERM_ROOT; 115234370Sjasone int initattr_wlevel = UFS_EXTATTR_PERM_ROOT; 116 int ch, i, error; 117 118 optind = 0; 119 while ((ch = getopt(argc, argv, "p:rw")) != -1) 120 switch (ch) { 121 case 'p': 122 fs_path = strdup(optarg); 123 break; 124 case 'r': 125 initattr_rlevel = extattr_level_from_string(optarg); 126 if (initattr_rlevel == -1) 127 usage(); 128 break; 129 case 'w': 130 initattr_wlevel = extattr_level_from_string(optarg); 131 if (initattr_wlevel == -1) 132 usage(); 133 break; 134 case '?': 135 default: 136 usage(); 137 } 138 139 argc -= optind; 140 argv += optind; 141 142 if (argc != 2) 143 usage(); 144 145 error = 0; 146 if ((i = open(argv[1], O_CREAT | O_EXCL | O_WRONLY, 0600)) != -1) { 147 uef.uef_magic = UFS_EXTATTR_MAGIC; 148 uef.uef_version = UFS_EXTATTR_VERSION; 149 uef.uef_write_perm = initattr_wlevel; 150 uef.uef_read_perm = initattr_rlevel; 151 uef.uef_size = atoi(argv[0]); 152 if (write(i, &uef, sizeof(uef)) == -1) 153 error = -1; 154 else if (fs_path) { 155 zero_buf = (char *) (malloc(uef.uef_size)); 156 if (zero_buf == NULL) { 157 perror("malloc"); 158 unlink(argv[1]); 159 return (-1); 160 } 161 memset(zero_buf, 0, uef.uef_size); 162 num_inodes = num_inodes_by_path(fs_path); 163 for (loop = 0; loop < num_inodes; loop++) { 164 error = write(i, zero_buf, uef.uef_size); 165 if (error != uef.uef_size) { 166 perror("write"); 167 unlink(argv[1]); 168 return (-1); 169 } 170 } 171 } 172 } 173 if (i == -1 || error == -1) { 174 perror(argv[1]); 175 unlink(argv[1]); 176 return (-1); 177 } 178 179 return (0); 180} 181 182int 183main(int argc, char *argv[]) 184{ 185 int error = 0; 186 187 if (argc < 2) 188 usage(); 189 190 if (!strcmp(argv[1], "start")) { 191 if (argc != 3) 192 usage(); 193 error = extattrctl(argv[2], UFS_EXTATTR_CMD_START, 0, 0); 194 } else if (!strcmp(argv[1], "stop")) { 195 if (argc != 3) 196 usage(); 197 error = extattrctl(argv[2], UFS_EXTATTR_CMD_STOP, 0, 0); 198 } else if (!strcmp(argv[1], "enable")) { 199 if (argc != 5) 200 usage(); 201 error = extattrctl(argv[2], UFS_EXTATTR_CMD_ENABLE, argv[3], 202 argv[4]); 203 } else if (!strcmp(argv[1], "disable")) { 204 if (argc != 4) 205 usage(); 206 error = extattrctl(argv[2], UFS_EXTATTR_CMD_DISABLE, argv[3], 207 NULL); 208 } else if (!strcmp(argv[1], "initattr")) { 209 argc -= 2; 210 argv += 2; 211 error = initattr(argc, argv); 212 } else 213 usage(); 214 215 if (error) 216 perror(argv[1]); 217 218 return(error); 219} 220