1 /* $OpenBSD: getcap.c,v 1.6 2015/10/10 05:43:48 deraadt Exp $ */ 2 3 /* 4 * Copyright (c) 2005 Todd C. Miller <Todd.Miller@courtesan.com> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #include <err.h> 20 #include <stdio.h> 21 #include <stdlib.h> 22 #include <string.h> 23 #include <unistd.h> 24 25 enum captype { 26 boolean, 27 number, 28 string, 29 raw 30 }; 31 32 void lookup_cap(char *, char *, enum captype, int); 33 __dead void usage(void); 34 35 int 36 main(int argc, char *argv[]) 37 { 38 int ch, aflag; 39 enum captype type; 40 char *cp, *buf, *cap = NULL, **pathvec = NULL; 41 size_t n; 42 43 if (pledge("stdio rpath", NULL) == -1) 44 err(1, "pledge"); 45 46 aflag = type = 0; 47 while ((ch = getopt(argc, argv, "ab:c:f:n:s:")) != -1) { 48 switch (ch) { 49 case 'a': 50 aflag = 1; 51 break; 52 case 'b': 53 if (*optarg == '\0') 54 usage(); 55 cap = optarg; 56 type = boolean; 57 break; 58 case 'n': 59 if (*optarg == '\0') 60 usage(); 61 cap = optarg; 62 type = number; 63 break; 64 case 's': 65 if (*optarg == '\0') 66 usage(); 67 cap = optarg; 68 type = string; 69 break; 70 case 'c': 71 if (*optarg == '\0') 72 usage(); 73 cap = optarg; 74 type = raw; 75 break; 76 case 'f': 77 if (pathvec != NULL) 78 errx(1, "only one -f option may be specified"); 79 for (n = 1, cp = optarg; (cp = strchr(cp, ':')); n++) 80 continue; 81 pathvec = calloc(n + 1, sizeof(char *)); 82 for (n = 0; (pathvec[n] = strsep(&optarg, ":"));) { 83 if (*pathvec[n] != '\0') 84 n++; 85 } 86 break; 87 default: 88 usage(); 89 } 90 } 91 argc -= optind; 92 argv += optind; 93 94 if (pathvec == NULL) { 95 warnx("no path specified"); 96 usage(); 97 } 98 if (!aflag && !argc) { 99 warnx("must specify -a or a record name"); 100 usage(); 101 } 102 103 if (aflag) { 104 while (cgetnext(&buf, pathvec) > 0) { 105 lookup_cap(buf, cap, type, 1); 106 free(buf); 107 } 108 } else { 109 while (*argv != NULL) { 110 if (cgetent(&buf, pathvec, *argv) != 0) 111 errx(1, "unable to lookup %s", *argv); /* XXX */ 112 lookup_cap(buf, cap, type, argc > 1); 113 free(buf); 114 argv++; 115 } 116 } 117 exit(0); 118 } 119 120 void 121 lookup_cap(char *buf, char *cap, enum captype type, int useprefix) 122 { 123 char *cp, *endp; 124 long l; 125 int ch, n, prefixlen; 126 127 if (cap == NULL) { 128 puts(buf); 129 return; 130 } 131 132 prefixlen = useprefix ? strcspn(buf, "|:") : 0; 133 134 switch (type) { 135 case boolean: 136 if (cgetcap(buf, cap, ':') == NULL) 137 return; 138 printf("%.*s%s%s\n", prefixlen, buf, 139 useprefix ? ": " : "", cap); 140 break; 141 case number: 142 if (cgetnum(buf, cap, &l) == -1) 143 return; 144 printf("%.*s%s%ld\n", prefixlen, buf, 145 useprefix ? ": " : "", l); 146 break; 147 case string: 148 if ((n = cgetstr(buf, cap, &cp)) == -1) 149 return; 150 else if (n == -2) 151 err(1, NULL); /* ENOMEM */ 152 printf("%.*s%s%s\n", prefixlen, buf, 153 useprefix ? ": " : "", cp); 154 break; 155 case raw: 156 n = strlen(cap) - 1; 157 ch = cap[n]; 158 cap[n] = '\0'; 159 cp = cgetcap(buf, cap, ch); 160 cap[n] = ch; 161 if (cp != NULL) { 162 if ((endp = strchr(cp, ':')) != NULL) 163 printf("%.*s%s%.*s\n", prefixlen, buf, 164 useprefix ? ": " : "", endp - cp, cp); 165 else 166 printf("%.*s%s%s\n", prefixlen, buf, 167 useprefix ? ": " : "", cp); 168 } 169 break; 170 } 171 } 172 173 __dead void 174 usage(void) 175 { 176 extern char *__progname; 177 178 fprintf(stderr, "usage: %s [-b boolean | -c capability | " 179 "-n number | -s string] -f path\n" 180 " -a | record ...\n", 181 __progname); 182 exit(1); 183 } 184