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