extattrctl.c revision 86429
1/*- 2 * Copyright (c) 1999-2001 Robert N. M. Watson 3 * All rights reserved. 4 * 5 * This software was developed by Robert Watson for the TrustedBSD Project. 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 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 * 28 * $FreeBSD: head/usr.sbin/extattrctl/extattrctl.c 86429 2001-11-15 22:56:40Z rwatson $ 29 */ 30/* 31 * Developed by the TrustedBSD Project. 32 * Support for file system extended attribute. 33 */ 34 35#include <sys/types.h> 36#include <sys/uio.h> 37#include <sys/extattr.h> 38#include <sys/param.h> 39#include <sys/mount.h> 40 41#include <ufs/ufs/extattr.h> 42 43#include <errno.h> 44#include <fcntl.h> 45#include <libutil.h> 46#include <stdio.h> 47#include <stdlib.h> 48#include <string.h> 49#include <unistd.h> 50 51extern char *optarg; 52extern int optind; 53 54void 55usage(void) 56{ 57 58 fprintf(stderr, 59 "usage:\n" 60 " extattrctl start [path]\n" 61 " extattrctl stop [path]\n" 62 " extattrctl initattr [-f] [-p path] [attrsize] [attrfile]\n" 63 " extattrctl enable [path] [attrnamespace] [attrname] [attrfile]\n" 64 " extattrctl disable [path] [attrnamespace] [attrname]\n"); 65 exit(-1); 66} 67 68long 69num_inodes_by_path(char *path) 70{ 71 struct statfs buf; 72 int error; 73 74 error = statfs(path, &buf); 75 if (error) { 76 perror("statfs"); 77 return (-1); 78 } 79 80 return (buf.f_files); 81} 82 83int 84initattr(int argc, char *argv[]) 85{ 86 struct ufs_extattr_fileheader uef; 87 char *fs_path = NULL; 88 char *zero_buf = NULL; 89 long loop, num_inodes; 90 int ch, i, error, chunksize, overwrite = 0, flags; 91 92 optind = 0; 93 while ((ch = getopt(argc, argv, "fp:r:w:")) != -1) 94 switch (ch) { 95 case 'f': 96 overwrite = 1; 97 break; 98 case 'p': 99 if ((fs_path = strdup(optarg)) == NULL) { 100 perror("strdup"); 101 return(-1); 102 } 103 break; 104 case '?': 105 default: 106 usage(); 107 } 108 109 argc -= optind; 110 argv += optind; 111 112 if (argc != 2) 113 usage(); 114 115 if (overwrite) 116 flags = O_CREAT | O_WRONLY; 117 else 118 flags = O_CREAT | O_EXCL | O_WRONLY; 119 120 error = 0; 121 if ((i = open(argv[1], flags, 0600)) != -1) { 122 uef.uef_magic = UFS_EXTATTR_MAGIC; 123 uef.uef_version = UFS_EXTATTR_VERSION; 124 uef.uef_size = atoi(argv[0]); 125 if (write(i, &uef, sizeof(uef)) == -1) 126 error = -1; 127 else if (fs_path) { 128 chunksize = sizeof(struct ufs_extattr_header) + 129 uef.uef_size; 130 zero_buf = (char *) (malloc(chunksize)); 131 if (zero_buf == NULL) { 132 perror("malloc"); 133 unlink(argv[1]); 134 return (-1); 135 } 136 memset(zero_buf, 0, chunksize); 137 num_inodes = num_inodes_by_path(fs_path); 138 for (loop = 0; loop < num_inodes; loop++) { 139 error = write(i, zero_buf, chunksize); 140 if (error != chunksize) { 141 perror("write"); 142 unlink(argv[1]); 143 return (-1); 144 } 145 } 146 } 147 } 148 if (i == -1) { 149 /* unable to open file */ 150 perror(argv[1]); 151 return (-1); 152 } 153 if (error == -1) { 154 perror(argv[1]); 155 unlink(argv[1]); 156 return (-1); 157 } 158 159 return (0); 160} 161 162int 163main(int argc, char *argv[]) 164{ 165 int error = 0, attrnamespace; 166 167 if (argc < 2) 168 usage(); 169 170 if (!strcmp(argv[1], "start")) { 171 if (argc != 3) 172 usage(); 173 error = extattrctl(argv[2], UFS_EXTATTR_CMD_START, NULL, 0, 174 NULL); 175 if (error) { 176 perror("extattrctl start"); 177 return (-1); 178 } 179 return (0); 180 } else if (!strcmp(argv[1], "stop")) { 181 if (argc != 3) 182 usage(); 183 error = extattrctl(argv[2], UFS_EXTATTR_CMD_STOP, NULL, 0, 184 NULL); 185 if (error) { 186 perror("extattrctl stop"); 187 return (-1); 188 } 189 return (0); 190 } else if (!strcmp(argv[1], "enable")) { 191 if (argc != 6) 192 usage(); 193 error = extattr_string_to_namespace(argv[3], &attrnamespace); 194 if (error) { 195 perror("extattrctl enable"); 196 return (-1); 197 } 198 error = extattrctl(argv[2], UFS_EXTATTR_CMD_ENABLE, argv[5], 199 attrnamespace, argv[4]); 200 if (error) { 201 perror("extattrctl enable"); 202 return (-1); 203 } 204 return (0); 205 } else if (!strcmp(argv[1], "disable")) { 206 if (argc != 5) 207 usage(); 208 error = extattr_string_to_namespace(argv[3], &attrnamespace); 209 if (error) { 210 perror("extattrctl disable"); 211 return (-1); 212 } 213 error = extattrctl(argv[2], UFS_EXTATTR_CMD_DISABLE, NULL, 214 attrnamespace, argv[4]); 215 if (error) { 216 perror("extattrctl disable"); 217 return (-1); 218 } 219 return (0); 220 } else if (!strcmp(argv[1], "initattr")) { 221 argc -= 2; 222 argv += 2; 223 error = initattr(argc, argv); 224 if (error) 225 return (-1); 226 return (0); 227 } else 228 usage(); 229} 230