1 /* $OpenBSD: getcap.c,v 1.3 2009/10/27 23:59:38 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 24 enum captype { 25 boolean, 26 number, 27 string, 28 raw 29 }; 30 31 void lookup_cap(char *, char *, enum captype, int); 32 __dead void usage(void); 33 34 int 35 main(int argc, char *argv[]) 36 { 37 int ch, aflag; 38 enum captype type; 39 char *cp, *buf, *cap = NULL, **pathvec = NULL; 40 size_t n; 41 42 aflag = type = 0; 43 while ((ch = getopt(argc, argv, "ab:c:f:n:s:")) != -1) { 44 switch (ch) { 45 case 'a': 46 aflag = 1; 47 break; 48 case 'b': 49 if (*optarg == '\0') 50 usage(); 51 cap = optarg; 52 type = boolean; 53 break; 54 case 'n': 55 if (*optarg == '\0') 56 usage(); 57 cap = optarg; 58 type = number; 59 break; 60 case 's': 61 if (*optarg == '\0') 62 usage(); 63 cap = optarg; 64 type = string; 65 break; 66 case 'c': 67 if (*optarg == '\0') 68 usage(); 69 cap = optarg; 70 type = raw; 71 break; 72 case 'f': 73 if (pathvec != NULL) 74 errx(1, "only one -f option may be specified"); 75 for (n = 1, cp = optarg; (cp = strchr(cp, ':')); n++) 76 continue; 77 pathvec = calloc(n + 1, sizeof(char *)); 78 for (n = 0; (pathvec[n] = strsep(&optarg, ":"));) { 79 if (*pathvec[n] != '\0') 80 n++; 81 } 82 break; 83 default: 84 usage(); 85 } 86 } 87 argc -= optind; 88 argv += optind; 89 90 if (pathvec == NULL) { 91 warnx("no path specified"); 92 usage(); 93 } 94 if (!aflag && !argc) { 95 warnx("must specify -a or a record name"); 96 usage(); 97 } 98 99 if (aflag) { 100 while (cgetnext(&buf, pathvec) > 0) { 101 lookup_cap(buf, cap, type, 1); 102 free(buf); 103 } 104 } else { 105 while (*argv != NULL) { 106 if (cgetent(&buf, pathvec, *argv) != 0) 107 errx(1, "unable to lookup %s", *argv); /* XXX */ 108 lookup_cap(buf, cap, type, argc > 1); 109 free(buf); 110 argv++; 111 } 112 } 113 exit(0); 114 } 115 116 void 117 lookup_cap(char *buf, char *cap, enum captype type, int useprefix) 118 { 119 char *cp, *endp; 120 long l; 121 int ch, n, prefixlen; 122 123 if (cap == NULL) { 124 puts(buf); 125 return; 126 } 127 128 prefixlen = useprefix ? strcspn(buf, "|:") : 0; 129 130 switch (type) { 131 case boolean: 132 if (cgetcap(buf, cap, ':') == NULL) 133 return; 134 printf("%.*s%s%s\n", prefixlen, buf, 135 useprefix ? ": " : "", cap); 136 break; 137 case number: 138 if (cgetnum(buf, cap, &l) == -1) 139 return; 140 printf("%.*s%s%ld\n", prefixlen, buf, 141 useprefix ? ": " : "", l); 142 break; 143 case string: 144 if ((n = cgetstr(buf, cap, &cp)) == -1) 145 return; 146 else if (n == -2) 147 err(1, NULL); /* ENOMEM */ 148 printf("%.*s%s%s\n", prefixlen, buf, 149 useprefix ? ": " : "", cp); 150 break; 151 case raw: 152 n = strlen(cap) - 1; 153 ch = cap[n]; 154 cap[n] = '\0'; 155 cp = cgetcap(buf, cap, ch); 156 cap[n] = ch; 157 if (cp != NULL) { 158 if ((endp = strchr(cp, ':')) != NULL) 159 printf("%.*s%s%.*s\n", prefixlen, buf, 160 useprefix ? ": " : "", endp - cp, cp); 161 else 162 printf("%.*s%s%s\n", prefixlen, buf, 163 useprefix ? ": " : "", cp); 164 } 165 break; 166 } 167 } 168 169 __dead void 170 usage(void) 171 { 172 extern char *__progname; 173 174 fprintf(stderr, "usage: %s [-b boolean | -c capability | -n number | -s string] -a -f path\n" 175 " %s [-b boolean | -c capability | -n number | -s string] -f path record ...\n", 176 __progname, __progname); 177 exit(1); 178 } 179