getfacl.c revision 74465
1/*- 2 * Copyright (c) 1999-2001 Robert N M Watson 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * $FreeBSD: head/bin/getfacl/getfacl.c 74465 2001-03-19 18:09:25Z rwatson $ 27 */ 28/* 29 * getfacl -- POSIX.1e utility to extract ACLs from files and directories 30 * and send the results to stdout 31 */ 32 33#include <sys/types.h> 34#include <sys/param.h> 35#include <sys/acl.h> 36#include <sys/stat.h> 37#include <err.h> 38#include <errno.h> 39#include <stdio.h> 40#include <unistd.h> 41 42int more_than_one = 0; 43 44static void 45usage(void) 46{ 47 48 fprintf(stderr, "getfacl [-d] [files ...]\n"); 49} 50 51static acl_t 52acl_from_stat(struct stat sb) 53{ 54 acl_t acl; 55 56 acl = acl_init(3); 57 if (!acl) 58 return(NULL); 59 60 acl->acl_entry[0].ae_tag = ACL_USER_OBJ; 61 acl->acl_entry[0].ae_id = sb.st_uid; 62 acl->acl_entry[0].ae_perm = 0; 63 if (sb.st_mode & S_IRUSR) 64 acl->acl_entry[0].ae_perm |= ACL_PERM_READ; 65 if (sb.st_mode & S_IWUSR) 66 acl->acl_entry[0].ae_perm |= ACL_PERM_WRITE; 67 if (sb.st_mode & S_IXUSR) 68 acl->acl_entry[0].ae_perm |= ACL_PERM_EXEC; 69 70 acl->acl_entry[1].ae_tag = ACL_GROUP_OBJ; 71 acl->acl_entry[1].ae_id = sb.st_gid; 72 acl->acl_entry[1].ae_perm = 0; 73 if (sb.st_mode & S_IRGRP) 74 acl->acl_entry[1].ae_perm |= ACL_PERM_READ; 75 if (sb.st_mode & S_IWGRP) 76 acl->acl_entry[1].ae_perm |= ACL_PERM_WRITE; 77 if (sb.st_mode & S_IXGRP) 78 acl->acl_entry[1].ae_perm |= ACL_PERM_EXEC; 79 80 acl->acl_entry[2].ae_tag = ACL_OTHER_OBJ; 81 acl->acl_entry[2].ae_id = 0; 82 acl->acl_entry[2].ae_perm = 0; 83 if (sb.st_mode & S_IROTH) 84 acl->acl_entry[2].ae_perm |= ACL_PERM_READ; 85 if (sb.st_mode & S_IWOTH) 86 acl->acl_entry[2].ae_perm |= ACL_PERM_WRITE; 87 if (sb.st_mode & S_IXOTH) 88 acl->acl_entry[2].ae_perm |= ACL_PERM_EXEC; 89 90 acl->acl_cnt = 3; 91 92 return(acl); 93} 94 95static int 96print_acl(char *path, acl_type_t type) 97{ 98 struct stat sb; 99 acl_t acl; 100 char *acl_text; 101 int error; 102 103 error = stat(path, &sb); 104 if (error == -1) { 105 perror(path); 106 return(-1); 107 } 108 109 if (more_than_one) 110 printf("\n"); 111 else 112 more_than_one++; 113 114 printf("#file:%s\n#owner:%d\n#group:%d\n", path, sb.st_uid, sb.st_gid); 115 116 acl = acl_get_file(path, type); 117 if (!acl) { 118 if (errno != EOPNOTSUPP) { 119 warn("%s", path); 120 return(-1); 121 } 122 errno = 0; 123 if (type != ACL_TYPE_ACCESS) 124 return(0); 125 acl = acl_from_stat(sb); 126 if (!acl) { 127 perror("acl_from_stat()"); 128 return(-1); 129 } 130 } 131 132 acl_text = acl_to_text(acl, 0); 133 if (!acl_text) { 134 perror(path); 135 return(-1); 136 } 137 138 printf("%s", acl_text); 139 140 acl_free(acl); 141 acl_free(acl_text); 142 143 return(0); 144} 145 146static int 147print_acl_from_stdin(acl_type_t type) 148{ 149 char pathname[PATH_MAX]; 150 int carried_error = 0; 151 152 pathname[sizeof(pathname) - 1] = '\0'; 153 while (fgets(pathname, sizeof(pathname), stdin)) { 154 /* remove the \n */ 155 pathname[strlen(pathname) - 1] = '\0'; 156 if (print_acl(pathname, type) == -1) { 157 carried_error = -1; 158 } 159 } 160 161 return(carried_error); 162} 163 164int 165main(int argc, char *argv[]) 166{ 167 acl_type_t type = ACL_TYPE_ACCESS; 168 int carried_error = 0; 169 int ch, error, i; 170 171 while ((ch = getopt(argc, argv, "d")) != -1) 172 switch(ch) { 173 case 'd': 174 type = ACL_TYPE_DEFAULT; 175 break; 176 default: 177 usage(); 178 return(-1); 179 } 180 argc -= optind; 181 argv += optind; 182 183 if (argc == 0) { 184 error = print_acl_from_stdin(type); 185 return(error); 186 } 187 188 for (i = 0; i < argc; i++) { 189 if (!strcmp(argv[i], "-")) { 190 error = print_acl_from_stdin(type); 191 if (error == -1) 192 carried_error = -1; 193 } else { 194 error = print_acl(argv[i], type); 195 if (error == -1) 196 carried_error = -1; 197 } 198 } 199 200 return(carried_error); 201} 202