Christiano F. Haesbaert | d977421 | 2010-02-21 21:31:58 -0300 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (c) 2010 Christiano F. Haesbaert <haesbaert@haesbaert.org> |
| 3 | * Copyright (c) 2006 Michele Marchetto <mydecay@openbeer.it> |
| 4 | * Copyright (c) 2004 Esben Norby <norby@openbsd.org> |
| 5 | * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> |
| 6 | * |
| 7 | * Permission to use, copy, modify, and distribute this software for any |
| 8 | * purpose with or without fee is hereby granted, provided that the above |
| 9 | * copyright notice and this permission notice appear in all copies. |
| 10 | * |
| 11 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
| 12 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
| 13 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
| 14 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
| 15 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
| 16 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
| 17 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
| 18 | */ |
| 19 | |
| 20 | #include <sys/types.h> |
| 21 | #include <sys/socket.h> |
| 22 | #include <netinet/in.h> |
| 23 | #include <arpa/inet.h> |
Christiano F. Haesbaert | 36ff688 | 2010-03-10 00:15:04 -0300 | [diff] [blame] | 24 | #include <ctype.h> |
Christiano F. Haesbaert | d977421 | 2010-02-21 21:31:58 -0300 | [diff] [blame] | 25 | #include <err.h> |
| 26 | #include <errno.h> |
| 27 | #include <limits.h> |
| 28 | #include <stdio.h> |
Christiano F. Haesbaert | 259edee | 2010-10-25 22:35:27 -0200 | [diff] [blame] | 29 | #include <stdint.h> |
Christiano F. Haesbaert | d977421 | 2010-02-21 21:31:58 -0300 | [diff] [blame] | 30 | #include <stdlib.h> |
| 31 | #include <string.h> |
| 32 | |
Christiano F. Haesbaert | d977421 | 2010-02-21 21:31:58 -0300 | [diff] [blame] | 33 | #include "parser.h" |
| 34 | |
| 35 | enum token_type { |
| 36 | NOTOKEN, |
| 37 | ENDTOKEN, |
| 38 | KEYWORD, |
| 39 | ADDRESS, |
Christiano F. Haesbaert | 4268cc3 | 2010-05-01 00:48:07 -0300 | [diff] [blame] | 40 | FLAGS, |
Christiano F. Haesbaert | d977421 | 2010-02-21 21:31:58 -0300 | [diff] [blame] | 41 | HOSTNAME, |
Christiano F. Haesbaert | 4a7b105 | 2010-05-06 19:44:11 -0300 | [diff] [blame] | 42 | PROTO, |
Christiano F. Haesbaert | bd49de0 | 2010-06-01 19:51:50 -0300 | [diff] [blame] | 43 | APPPROTO, |
Christiano F. Haesbaert | d1a2082 | 2010-10-17 17:39:55 -0200 | [diff] [blame] | 44 | BRFLAGS, |
| 45 | SRVNAME, |
Christiano F. Haesbaert | 259edee | 2010-10-25 22:35:27 -0200 | [diff] [blame] | 46 | TXTSTRING, |
| 47 | PORT |
Christiano F. Haesbaert | d977421 | 2010-02-21 21:31:58 -0300 | [diff] [blame] | 48 | }; |
| 49 | |
| 50 | struct token { |
| 51 | enum token_type type; |
| 52 | const char *keyword; |
| 53 | int value; |
| 54 | const struct token *next; |
| 55 | }; |
| 56 | |
| 57 | static const struct token t_main[]; |
Christiano F. Haesbaert | 4093a2f | 2010-09-04 20:25:50 -0300 | [diff] [blame] | 58 | static const struct token t_lookup[]; |
| 59 | static const struct token t_rlookup[]; |
Christiano F. Haesbaert | 307df70 | 2010-05-25 20:40:58 -0300 | [diff] [blame] | 60 | static const struct token t_browse_proto[]; |
Christiano F. Haesbaert | 4a7b105 | 2010-05-06 19:44:11 -0300 | [diff] [blame] | 61 | static const struct token t_browse_app[]; |
Christiano F. Haesbaert | d1a2082 | 2010-10-17 17:39:55 -0200 | [diff] [blame] | 62 | static const struct token t_publish[]; |
| 63 | static const struct token t_publish_app[]; |
| 64 | static const struct token t_publish_app_proto[]; |
Christiano F. Haesbaert | 259edee | 2010-10-25 22:35:27 -0200 | [diff] [blame] | 65 | static const struct token t_publish_app_proto_port[]; |
| 66 | static const struct token t_publish_app_proto_port_txt[]; |
Christiano F. Haesbaert | d977421 | 2010-02-21 21:31:58 -0300 | [diff] [blame] | 67 | |
| 68 | static const struct token t_main[] = { |
Christiano F. Haesbaert | 4093a2f | 2010-09-04 20:25:50 -0300 | [diff] [blame] | 69 | {KEYWORD, "lookup", NONE, t_lookup}, |
| 70 | {KEYWORD, "rlookup", NONE, t_rlookup}, |
Christiano F. Haesbaert | 307df70 | 2010-05-25 20:40:58 -0300 | [diff] [blame] | 71 | {KEYWORD, "browse", NONE, t_browse_app}, |
Christiano F. Haesbaert | d1a2082 | 2010-10-17 17:39:55 -0200 | [diff] [blame] | 72 | {KEYWORD, "publish", NONE, t_publish}, |
Christiano F. Haesbaert | d977421 | 2010-02-21 21:31:58 -0300 | [diff] [blame] | 73 | {ENDTOKEN, "", NONE, NULL} |
| 74 | }; |
| 75 | |
Christiano F. Haesbaert | 4093a2f | 2010-09-04 20:25:50 -0300 | [diff] [blame] | 76 | static const struct token t_lookup[] = { |
| 77 | { FLAGS , "-", NONE, t_lookup}, |
Christiano F. Haesbaert | d812362 | 2010-07-17 20:42:40 -0300 | [diff] [blame] | 78 | { HOSTNAME, "", LOOKUP, NULL}, |
| 79 | { ENDTOKEN, "", NONE, NULL} |
| 80 | }; |
| 81 | |
Christiano F. Haesbaert | 4093a2f | 2010-09-04 20:25:50 -0300 | [diff] [blame] | 82 | static const struct token t_rlookup[] = { |
Christiano F. Haesbaert | d812362 | 2010-07-17 20:42:40 -0300 | [diff] [blame] | 83 | { ADDRESS, "", RLOOKUP, NULL}, |
Christiano F. Haesbaert | d977421 | 2010-02-21 21:31:58 -0300 | [diff] [blame] | 84 | { ENDTOKEN, "", NONE, NULL} |
| 85 | }; |
| 86 | |
Christiano F. Haesbaert | 307df70 | 2010-05-25 20:40:58 -0300 | [diff] [blame] | 87 | static const struct token t_browse_app[] = { |
Christiano F. Haesbaert | bd49de0 | 2010-06-01 19:51:50 -0300 | [diff] [blame] | 88 | { BRFLAGS, "-", NONE, t_browse_app}, |
| 89 | { KEYWORD, "all", BROWSE_PROTO, NULL}, |
Christiano F. Haesbaert | 307df70 | 2010-05-25 20:40:58 -0300 | [diff] [blame] | 90 | { APPPROTO, "", NONE, t_browse_proto}, |
Christiano F. Haesbaert | 4a7b105 | 2010-05-06 19:44:11 -0300 | [diff] [blame] | 91 | { ENDTOKEN, "", NONE, NULL} |
| 92 | }; |
| 93 | |
Christiano F. Haesbaert | 307df70 | 2010-05-25 20:40:58 -0300 | [diff] [blame] | 94 | static const struct token t_browse_proto[] = { |
| 95 | { PROTO, "tcp", BROWSE_PROTO, NULL}, |
| 96 | { PROTO, "udp", BROWSE_PROTO, NULL}, |
Christiano F. Haesbaert | 9d9d5ce | 2010-04-27 18:59:48 -0300 | [diff] [blame] | 97 | { ENDTOKEN, "", NONE, NULL} |
| 98 | }; |
Christiano F. Haesbaert | 0e2793e | 2010-02-22 20:13:59 -0300 | [diff] [blame] | 99 | |
Christiano F. Haesbaert | d1a2082 | 2010-10-17 17:39:55 -0200 | [diff] [blame] | 100 | static const struct token t_publish[] = { |
| 101 | { SRVNAME, "", NONE, t_publish_app}, |
| 102 | { ENDTOKEN, "", NONE, NULL} |
| 103 | }; |
| 104 | |
| 105 | static const struct token t_publish_app[] = { |
| 106 | { APPPROTO, "", NONE, t_publish_app_proto}, |
| 107 | { ENDTOKEN, "", NONE, NULL} |
| 108 | }; |
| 109 | |
| 110 | static const struct token t_publish_app_proto[] = { |
Christiano F. Haesbaert | 5f44bfe | 2010-10-27 18:16:37 -0200 | [diff] [blame] | 111 | { PROTO, "tcp", NONE, t_publish_app_proto_port}, |
| 112 | { PROTO, "udp", NONE, t_publish_app_proto_port}, |
Christiano F. Haesbaert | d1a2082 | 2010-10-17 17:39:55 -0200 | [diff] [blame] | 113 | { ENDTOKEN, "", NONE, NULL} |
| 114 | }; |
| 115 | |
Christiano F. Haesbaert | 259edee | 2010-10-25 22:35:27 -0200 | [diff] [blame] | 116 | static const struct token t_publish_app_proto_port[] = { |
Christiano F. Haesbaert | 5f44bfe | 2010-10-27 18:16:37 -0200 | [diff] [blame] | 117 | { PORT, "", NONE, t_publish_app_proto_port_txt}, |
| 118 | { ENDTOKEN, "", NONE, t_publish_app_proto_port_txt} |
Christiano F. Haesbaert | 259edee | 2010-10-25 22:35:27 -0200 | [diff] [blame] | 119 | }; |
| 120 | |
| 121 | static const struct token t_publish_app_proto_port_txt[] = { |
Christiano F. Haesbaert | d1a2082 | 2010-10-17 17:39:55 -0200 | [diff] [blame] | 122 | { TXTSTRING, "", PUBLISH, NULL}, |
| 123 | { ENDTOKEN, "", NONE, NULL} |
| 124 | }; |
| 125 | |
Christiano F. Haesbaert | d977421 | 2010-02-21 21:31:58 -0300 | [diff] [blame] | 126 | static struct parse_result res; |
| 127 | |
| 128 | struct parse_result * |
| 129 | parse(int argc, char *argv[]) |
| 130 | { |
| 131 | const struct token *table = t_main; |
| 132 | const struct token *match; |
| 133 | |
| 134 | bzero(&res, sizeof(res)); |
| 135 | |
| 136 | while (argc >= 0) { |
| 137 | if ((match = match_token(argv[0], table)) == NULL) { |
| 138 | fprintf(stderr, "valid commands/args:\n"); |
| 139 | show_valid_args(table); |
| 140 | return (NULL); |
| 141 | } |
| 142 | |
| 143 | argc--; |
| 144 | argv++; |
| 145 | |
| 146 | if (match->type == NOTOKEN || match->next == NULL) |
| 147 | break; |
| 148 | |
| 149 | table = match->next; |
| 150 | } |
| 151 | |
| 152 | if (argc > 0) { |
| 153 | fprintf(stderr, "superfluous argument: %s\n", argv[0]); |
| 154 | return (NULL); |
| 155 | } |
| 156 | |
| 157 | return (&res); |
| 158 | } |
| 159 | |
| 160 | const struct token * |
| 161 | match_token(const char *word, const struct token *table) |
| 162 | { |
| 163 | u_int i, match; |
Christiano F. Haesbaert | 259edee | 2010-10-25 22:35:27 -0200 | [diff] [blame] | 164 | const char *errstr; |
Christiano F. Haesbaert | d977421 | 2010-02-21 21:31:58 -0300 | [diff] [blame] | 165 | const struct token *t = NULL; |
| 166 | |
| 167 | match = 0; |
| 168 | |
| 169 | for (i = 0; table[i].type != ENDTOKEN; i++) { |
| 170 | switch (table[i].type) { |
| 171 | case NOTOKEN: |
| 172 | if (word == NULL || strlen(word) == 0) { |
| 173 | match++; |
| 174 | t = &table[i]; |
| 175 | } |
| 176 | break; |
Christiano F. Haesbaert | bd49de0 | 2010-06-01 19:51:50 -0300 | [diff] [blame] | 177 | case BRFLAGS: |
| 178 | if (parse_brflags(word, &res.flags)) { |
| 179 | match++; |
| 180 | t = &table[i]; |
| 181 | if (t->value) |
| 182 | res.action = t->value; |
| 183 | } |
| 184 | break; |
Christiano F. Haesbaert | 4268cc3 | 2010-05-01 00:48:07 -0300 | [diff] [blame] | 185 | case FLAGS: |
| 186 | if (parse_flags(word, &res.flags)) { |
| 187 | match++; |
| 188 | t = &table[i]; |
| 189 | if (t->value) |
| 190 | res.action = t->value; |
| 191 | } |
| 192 | break; |
Christiano F. Haesbaert | d977421 | 2010-02-21 21:31:58 -0300 | [diff] [blame] | 193 | case KEYWORD: |
Christiano F. Haesbaert | 0e2793e | 2010-02-22 20:13:59 -0300 | [diff] [blame] | 194 | if (word != NULL && strcmp(word, table[i].keyword) |
| 195 | == 0) { |
Christiano F. Haesbaert | d977421 | 2010-02-21 21:31:58 -0300 | [diff] [blame] | 196 | match++; |
| 197 | t = &table[i]; |
| 198 | if (t->value) |
| 199 | res.action = t->value; |
| 200 | } |
| 201 | break; |
Christiano F. Haesbaert | 4a7b105 | 2010-05-06 19:44:11 -0300 | [diff] [blame] | 202 | case PROTO: |
| 203 | if (word != NULL && strcmp(word, table[i].keyword) |
| 204 | == 0) { |
| 205 | res.proto = word; |
| 206 | match++; |
| 207 | t = &table[i]; |
| 208 | if (t->value) |
| 209 | res.action = t->value; |
| 210 | } |
| 211 | break; |
Christiano F. Haesbaert | d977421 | 2010-02-21 21:31:58 -0300 | [diff] [blame] | 212 | case ADDRESS: |
| 213 | if (parse_addr(word, &res.addr)) { |
| 214 | match++; |
| 215 | t = &table[i]; |
| 216 | if (t->value) |
| 217 | res.action = t->value; |
| 218 | } |
| 219 | break; |
| 220 | case HOSTNAME: |
| 221 | if (parse_hostname(word, res.hostname)) { |
| 222 | match++; |
| 223 | t = &table[i]; |
| 224 | if (t->value) |
| 225 | res.action = t->value; |
| 226 | } |
| 227 | break; |
Christiano F. Haesbaert | 4a7b105 | 2010-05-06 19:44:11 -0300 | [diff] [blame] | 228 | case APPPROTO: |
Christiano F. Haesbaert | bd49de0 | 2010-06-01 19:51:50 -0300 | [diff] [blame] | 229 | if (word && *word != '-' && |
| 230 | (strcmp(word, "all") != 0)) { |
Christiano F. Haesbaert | 307df70 | 2010-05-25 20:40:58 -0300 | [diff] [blame] | 231 | res.app = word; |
Christiano F. Haesbaert | 9d9d5ce | 2010-04-27 18:59:48 -0300 | [diff] [blame] | 232 | match++; |
| 233 | t = &table[i]; |
| 234 | if (t->value) |
| 235 | res.action = t->value; |
| 236 | } |
Christiano F. Haesbaert | d1a2082 | 2010-10-17 17:39:55 -0200 | [diff] [blame] | 237 | break; |
| 238 | case SRVNAME: /* match anything */ |
| 239 | if (word != NULL) { |
| 240 | res.srvname = word; |
| 241 | match++; |
| 242 | t = &table[i]; |
| 243 | if (t->value) |
| 244 | res.action = t->value; |
| 245 | } |
| 246 | break; |
| 247 | case TXTSTRING: |
| 248 | if (word != NULL) { |
| 249 | res.txtstring = word; |
| 250 | match++; |
| 251 | t = &table[i]; |
| 252 | if (t->value) |
| 253 | res.action = t->value; |
| 254 | } |
| 255 | break; |
Christiano F. Haesbaert | 259edee | 2010-10-25 22:35:27 -0200 | [diff] [blame] | 256 | case PORT: |
| 257 | if (word != NULL) { |
| 258 | res.port = strtonum(word, 1, UINT16_MAX, |
| 259 | &errstr); |
| 260 | if (errstr) |
| 261 | errx(1, "strtonum: %s", errstr); |
| 262 | match++; |
| 263 | t = &table[i]; |
| 264 | if (t->value) |
| 265 | res.action = t->value; |
| 266 | } |
| 267 | break; |
Christiano F. Haesbaert | d977421 | 2010-02-21 21:31:58 -0300 | [diff] [blame] | 268 | case ENDTOKEN: |
| 269 | break; |
| 270 | } |
| 271 | } |
| 272 | |
| 273 | if (match != 1) { |
| 274 | if (word == NULL) |
| 275 | fprintf(stderr, "missing argument:\n"); |
| 276 | else if (match > 1) |
| 277 | fprintf(stderr, "ambiguous argument: %s\n", word); |
| 278 | else if (match < 1) |
| 279 | fprintf(stderr, "unknown argument: %s\n", word); |
| 280 | return (NULL); |
| 281 | } |
| 282 | |
| 283 | return (t); |
| 284 | } |
| 285 | |
| 286 | void |
| 287 | show_valid_args(const struct token *table) |
| 288 | { |
| 289 | int i; |
| 290 | |
| 291 | for (i = 0; table[i].type != ENDTOKEN; i++) { |
| 292 | switch (table[i].type) { |
| 293 | case NOTOKEN: |
| 294 | fprintf(stderr, " <cr>\n"); |
| 295 | break; |
| 296 | case KEYWORD: |
Christiano F. Haesbaert | d977421 | 2010-02-21 21:31:58 -0300 | [diff] [blame] | 297 | fprintf(stderr, " %s\n", table[i].keyword); |
| 298 | break; |
Christiano F. Haesbaert | 4a7b105 | 2010-05-06 19:44:11 -0300 | [diff] [blame] | 299 | case PROTO: |
| 300 | fprintf(stderr, " %s\n", table[i].keyword); |
| 301 | break; |
Christiano F. Haesbaert | d977421 | 2010-02-21 21:31:58 -0300 | [diff] [blame] | 302 | case ADDRESS: |
| 303 | fprintf(stderr, " <address>\n"); |
| 304 | break; |
| 305 | case HOSTNAME: |
| 306 | fprintf(stderr, " <hostname.local>\n"); |
| 307 | break; |
Christiano F. Haesbaert | 4a7b105 | 2010-05-06 19:44:11 -0300 | [diff] [blame] | 308 | case APPPROTO: |
| 309 | fprintf(stderr, " <application protocol>\n"); |
Christiano F. Haesbaert | 9d9d5ce | 2010-04-27 18:59:48 -0300 | [diff] [blame] | 310 | break; |
Christiano F. Haesbaert | 4268cc3 | 2010-05-01 00:48:07 -0300 | [diff] [blame] | 311 | case FLAGS: |
| 312 | fprintf(stderr, " <-ahst>\n"); |
| 313 | break; |
Christiano F. Haesbaert | bd49de0 | 2010-06-01 19:51:50 -0300 | [diff] [blame] | 314 | case BRFLAGS: |
| 315 | fprintf(stderr, " <-r>\n"); |
| 316 | break; |
Christiano F. Haesbaert | d1a2082 | 2010-10-17 17:39:55 -0200 | [diff] [blame] | 317 | case SRVNAME: |
| 318 | fprintf(stderr, " <service name>\n"); |
| 319 | break; |
| 320 | case TXTSTRING: |
| 321 | fprintf(stderr, " <text string>\n"); |
| 322 | break; |
Christiano F. Haesbaert | 259edee | 2010-10-25 22:35:27 -0200 | [diff] [blame] | 323 | case PORT: |
| 324 | fprintf(stderr, " <port>\n"); |
| 325 | break; |
Christiano F. Haesbaert | d977421 | 2010-02-21 21:31:58 -0300 | [diff] [blame] | 326 | case ENDTOKEN: |
| 327 | break; |
| 328 | } |
| 329 | } |
| 330 | } |
| 331 | |
| 332 | int |
| 333 | parse_addr(const char *word, struct in_addr *addr) |
| 334 | { |
| 335 | struct in_addr ina; |
Christiano F. Haesbaert | beea466 | 2010-07-02 02:57:14 -0300 | [diff] [blame] | 336 | |
Christiano F. Haesbaert | 36ff688 | 2010-03-10 00:15:04 -0300 | [diff] [blame] | 337 | if (word == NULL || !isdigit(*word)) |
Christiano F. Haesbaert | d977421 | 2010-02-21 21:31:58 -0300 | [diff] [blame] | 338 | return (0); |
| 339 | |
| 340 | bzero(addr, sizeof(struct in_addr)); |
| 341 | bzero(&ina, sizeof(ina)); |
Christiano F. Haesbaert | d977421 | 2010-02-21 21:31:58 -0300 | [diff] [blame] | 342 | if (inet_pton(AF_INET, word, &ina)) { |
| 343 | addr->s_addr = ina.s_addr; |
| 344 | return (1); |
| 345 | } |
| 346 | |
| 347 | return (0); |
| 348 | } |
| 349 | |
| 350 | int |
| 351 | parse_hostname(const char *word, char hostname[MAXHOSTNAMELEN]) |
| 352 | { |
Christiano F. Haesbaert | b8ad911 | 2010-09-04 19:52:08 -0300 | [diff] [blame] | 353 | if (word == NULL || *word == '-') |
Christiano F. Haesbaert | d977421 | 2010-02-21 21:31:58 -0300 | [diff] [blame] | 354 | return (0); |
Christiano F. Haesbaert | b8ad911 | 2010-09-04 19:52:08 -0300 | [diff] [blame] | 355 | |
Christiano F. Haesbaert | 6162f3a | 2010-03-25 19:30:23 -0300 | [diff] [blame] | 356 | if (strlen(word) < 7 || /* shorter host is a.local */ |
| 357 | strcmp(&word[strlen(word) - 6], ".local") != 0) { |
Christiano F. Haesbaert | d977421 | 2010-02-21 21:31:58 -0300 | [diff] [blame] | 358 | fprintf(stderr, "Invalid domain, must be .local\n"); |
| 359 | return (0); |
| 360 | } |
Christiano F. Haesbaert | d977421 | 2010-02-21 21:31:58 -0300 | [diff] [blame] | 361 | strlcpy(hostname, word, MAXHOSTNAMELEN); |
Christiano F. Haesbaert | beea466 | 2010-07-02 02:57:14 -0300 | [diff] [blame] | 362 | |
Christiano F. Haesbaert | d977421 | 2010-02-21 21:31:58 -0300 | [diff] [blame] | 363 | return (1); |
| 364 | } |
| 365 | |
Christiano F. Haesbaert | 4268cc3 | 2010-05-01 00:48:07 -0300 | [diff] [blame] | 366 | int |
| 367 | parse_flags(const char *word, int *flags) |
| 368 | { |
| 369 | int r = 0; |
Christiano F. Haesbaert | b8ad911 | 2010-09-04 19:52:08 -0300 | [diff] [blame] | 370 | |
Christiano F. Haesbaert | 4268cc3 | 2010-05-01 00:48:07 -0300 | [diff] [blame] | 371 | if (word == NULL || *word != '-') |
| 372 | return (r); |
| 373 | word++; |
| 374 | while(*word) { |
| 375 | switch (*word) { |
| 376 | case 'a': |
| 377 | *flags |= F_A; |
| 378 | r++; |
| 379 | break; |
| 380 | case 'h': |
| 381 | *flags |= F_HINFO; |
| 382 | r++; |
| 383 | break; |
| 384 | case 's': |
| 385 | *flags |= F_SRV; |
| 386 | r++; |
| 387 | break; |
| 388 | case 't': |
| 389 | *flags |= F_TXT; |
| 390 | r++; |
| 391 | break; |
| 392 | default: |
| 393 | errx(1, "unknown flag -%c", *word); |
| 394 | } |
| 395 | word++; |
| 396 | } |
Christiano F. Haesbaert | beea466 | 2010-07-02 02:57:14 -0300 | [diff] [blame] | 397 | |
Christiano F. Haesbaert | 4268cc3 | 2010-05-01 00:48:07 -0300 | [diff] [blame] | 398 | return (r); |
| 399 | } |
Christiano F. Haesbaert | bd49de0 | 2010-06-01 19:51:50 -0300 | [diff] [blame] | 400 | |
| 401 | int |
| 402 | parse_brflags(const char *word, int *flags) |
| 403 | { |
| 404 | int r = 0; |
Christiano F. Haesbaert | beea466 | 2010-07-02 02:57:14 -0300 | [diff] [blame] | 405 | |
Christiano F. Haesbaert | bd49de0 | 2010-06-01 19:51:50 -0300 | [diff] [blame] | 406 | if (word == NULL || *word != '-') |
| 407 | return (r); |
| 408 | word++; |
| 409 | while(*word) { |
| 410 | switch (*word) { |
| 411 | case 'r': |
| 412 | *flags |= F_RESOLV; |
| 413 | r++; |
| 414 | break; |
| 415 | default: |
| 416 | errx(1, "unknown flag -%c", *word); |
| 417 | } |
| 418 | word++; |
| 419 | } |
Christiano F. Haesbaert | beea466 | 2010-07-02 02:57:14 -0300 | [diff] [blame] | 420 | |
Christiano F. Haesbaert | bd49de0 | 2010-06-01 19:51:50 -0300 | [diff] [blame] | 421 | return (r); |
| 422 | } |