]>
Commit | Line | Data |
---|---|---|
80e8aa14 | 1 | /* |
2 | * Command line oriented Moira host tool. | |
3 | * | |
4 | * kolya@MIT.EDU, January 2000 | |
5 | * | |
6 | * Somewhat based on blanche | |
7 | * | |
8 | * Copyright (C) 2000 by the Massachusetts Institute of Technology. | |
9 | * For copying and distribution information, please see the file | |
10 | * <mit-copyright.h>. | |
11 | */ | |
12 | ||
13 | #include <mit-copyright.h> | |
14 | #include <moira.h> | |
15 | #include <moira_site.h> | |
16 | #include <mrclient.h> | |
17 | ||
18 | #include <ctype.h> | |
19 | #include <errno.h> | |
20 | #include <stdio.h> | |
21 | #include <stdlib.h> | |
22 | #include <string.h> | |
23 | ||
24 | RCSID("$Header$"); | |
25 | ||
26 | struct owner_type { | |
27 | int type; | |
28 | char *name; | |
29 | }; | |
30 | ||
31 | struct mqelem { | |
32 | struct mqelem *q_forw; | |
33 | struct mqelem *q_back; | |
34 | void *q_data; | |
35 | }; | |
36 | ||
37 | struct string_list { | |
38 | char *string; | |
39 | struct string_list *next; | |
40 | }; | |
41 | ||
80e8aa14 | 42 | #define M_ANY 0 |
43 | #define M_USER 1 | |
44 | #define M_LIST 2 | |
a547d259 | 45 | #define M_KERBEROS 3 |
46 | #define M_NONE 4 | |
80e8aa14 | 47 | |
48 | /* argument parsing macro */ | |
49 | #define argis(a, b) (!strcmp(*arg + 1, a) || !strcmp(*arg + 1, b)) | |
50 | ||
51 | /* flags from command line */ | |
52 | int info_flag, update_flag, create_flag, delete_flag, list_map_flag; | |
7e689fac | 53 | int update_alias_flag, update_map_flag, verbose, noauth; |
80e8aa14 | 54 | |
55 | struct string_list *alias_add_queue, *alias_remove_queue; | |
56 | struct string_list *map_add_queue, *map_remove_queue; | |
57 | ||
58 | char *hostname, *whoami; | |
59 | ||
60 | char *newname, *address, *network, *h_status, *vendor, *model; | |
080e5e2c | 61 | char *os, *location, *contact, *billing_contact, *adm_cmt, *op_cmt; |
80e8aa14 | 62 | |
63 | struct owner_type *owner; | |
64 | ||
65 | void usage(char **argv); | |
66 | int store_host_info(int argc, char **argv, void *hint); | |
67 | void show_host_info(char **argv); | |
68 | int show_machine_in_cluster(int argc, char **argv, void *hint); | |
69 | struct owner_type *parse_member(char *s); | |
70 | struct string_list *add_to_string_list(struct string_list *old_list, char *s); | |
71 | int wrap_mr_query(char *handle, int argc, char **argv, | |
72 | int (*callback)(int, char **, void *), void *callarg); | |
73 | void print_query(char *query_name, int argc, char **argv); | |
74 | ||
75 | int main(int argc, char **argv) | |
76 | { | |
77 | int status, success; | |
78 | char **arg = argv; | |
533bacb3 | 79 | char *server = NULL; |
80e8aa14 | 80 | |
81 | /* clear all flags & lists */ | |
82 | info_flag = update_flag = create_flag = list_map_flag = update_map_flag = 0; | |
7e689fac | 83 | update_alias_flag = verbose = noauth = 0; |
80e8aa14 | 84 | newname = address = network = h_status = vendor = model = NULL; |
080e5e2c | 85 | os = location = contact = billing_contact = adm_cmt = op_cmt = NULL; |
80e8aa14 | 86 | owner = NULL; |
87 | alias_add_queue = alias_remove_queue = NULL; | |
88 | map_add_queue = map_remove_queue = NULL; | |
89 | whoami = argv[0]; | |
90 | ||
91 | success = 1; | |
92 | ||
93 | /* parse args, building addlist, dellist, & synclist */ | |
94 | while (++arg - argv < argc) | |
95 | { | |
96 | if (**arg == '-') | |
97 | { | |
98 | if (argis("i", "info")) | |
99 | info_flag++; | |
100 | else if (argis("C", "create")) | |
101 | create_flag++; | |
102 | else if (argis("D", "delete")) | |
103 | delete_flag++; | |
104 | else if (argis("R", "rename")) { | |
105 | if (arg - argv < argc - 1) { | |
106 | arg++; | |
107 | update_flag++; | |
108 | newname = *arg; | |
109 | } else | |
110 | usage(argv); | |
111 | } | |
112 | else if (argis("A", "address")) { | |
113 | if (arg - argv < argc - 1) { | |
114 | arg++; | |
115 | update_flag++; | |
116 | address = *arg; | |
117 | } else | |
118 | usage(argv); | |
119 | } | |
120 | else if (argis("O", "owner")) { | |
121 | if (arg - argv < argc - 1) { | |
122 | arg++; | |
123 | update_flag++; | |
124 | owner = parse_member(*arg); | |
125 | } else | |
126 | usage(argv); | |
127 | } | |
128 | else if (argis("N", "network")) { | |
129 | if (arg - argv < argc - 1) { | |
130 | arg++; | |
131 | update_flag++; | |
132 | network = *arg; | |
133 | } else | |
134 | usage(argv); | |
135 | } | |
136 | else if (argis("S", "status")) { | |
137 | if (arg - argv < argc - 1) { | |
138 | int i; | |
533bacb3 | 139 | int len; |
80e8aa14 | 140 | |
141 | arg++; | |
142 | update_flag++; | |
143 | h_status = *arg; | |
144 | ||
533bacb3 | 145 | len = strlen(h_status); |
146 | for(i = 0; i < len; i++) { | |
80e8aa14 | 147 | if(!isdigit(h_status[i])) { |
148 | printf("Error: status code %s is not numeric.\n", h_status); | |
149 | exit(1); | |
150 | } | |
151 | } | |
152 | } else | |
153 | usage(argv); | |
154 | } | |
155 | else if (argis("V", "vendor")) { | |
156 | if (arg - argv < argc - 1) { | |
157 | arg++; | |
158 | update_flag++; | |
159 | vendor = *arg; | |
160 | } else | |
161 | usage(argv); | |
162 | } | |
163 | else if (argis("M", "model")) { | |
164 | if (arg - argv < argc - 1) { | |
165 | arg++; | |
166 | update_flag++; | |
167 | model = *arg; | |
168 | } else | |
169 | usage(argv); | |
170 | } | |
171 | else if (argis("o", "os")) { | |
172 | if (arg - argv < argc - 1) { | |
173 | arg++; | |
174 | update_flag++; | |
175 | os = *arg; | |
176 | } else | |
177 | usage(argv); | |
178 | } | |
179 | else if (argis("L", "location")) { | |
180 | if (arg - argv < argc - 1) { | |
181 | arg++; | |
182 | update_flag++; | |
183 | location = *arg; | |
184 | } else | |
185 | usage(argv); | |
186 | } | |
187 | else if (argis("c", "contact")) { | |
188 | if (arg - argv < argc - 1) { | |
189 | arg++; | |
190 | update_flag++; | |
191 | contact = *arg; | |
192 | } else | |
193 | usage(argv); | |
194 | } | |
080e5e2c | 195 | else if (argis("bc", "billingcontact")) { |
196 | if (arg - argv < argc - 1) { | |
197 | arg++; | |
198 | update_flag++; | |
199 | billing_contact = *arg; | |
200 | } else | |
201 | usage(argv); | |
202 | } | |
80e8aa14 | 203 | else if (argis("ac", "admcmt")) { |
204 | if (arg - argv < argc - 1) { | |
205 | arg++; | |
206 | update_flag++; | |
207 | adm_cmt = *arg; | |
208 | } else | |
209 | usage(argv); | |
210 | } | |
211 | else if (argis("oc", "opcmt")) { | |
212 | if (arg - argv < argc - 1) { | |
213 | arg++; | |
214 | update_flag++; | |
215 | op_cmt = *arg; | |
216 | } else | |
217 | usage(argv); | |
218 | } | |
219 | else if (argis("a", "aliasadd")) { | |
220 | if (arg - argv < argc - 1) { | |
221 | arg++; | |
222 | alias_add_queue=add_to_string_list(alias_add_queue, *arg); | |
223 | } else | |
224 | usage(argv); | |
7e689fac | 225 | update_alias_flag++; |
80e8aa14 | 226 | } |
227 | else if (argis("d", "aliasdelete")) { | |
228 | if (arg - argv < argc - 1) { | |
229 | arg++; | |
230 | alias_remove_queue=add_to_string_list(alias_remove_queue, *arg); | |
231 | } else | |
232 | usage(argv); | |
7e689fac | 233 | update_alias_flag++; |
80e8aa14 | 234 | } |
235 | else if (argis("am", "addmap")) { | |
236 | if (arg - argv < argc - 1) { | |
237 | arg++; | |
238 | map_add_queue=add_to_string_list(map_add_queue, *arg); | |
239 | } else | |
240 | usage(argv); | |
241 | update_map_flag++; | |
242 | } | |
243 | else if (argis("dm", "deletemap")) { | |
244 | if (arg - argv < argc - 1) { | |
245 | arg++; | |
246 | map_remove_queue=add_to_string_list(map_remove_queue, *arg); | |
247 | } else | |
248 | usage(argv); | |
249 | update_map_flag++; | |
250 | } | |
251 | else if (argis("lm", "listmap")) | |
252 | list_map_flag++; | |
253 | else if (argis("n", "noauth")) | |
254 | noauth++; | |
255 | else if (argis("v", "verbose")) | |
256 | verbose++; | |
257 | else if (argis("db", "database")) | |
258 | { | |
259 | if (arg - argv < argc - 1) | |
260 | { | |
261 | ++arg; | |
262 | server = *arg; | |
263 | } | |
264 | else | |
265 | usage(argv); | |
266 | } | |
267 | else | |
268 | usage(argv); | |
269 | } | |
270 | else if (hostname == NULL) | |
271 | hostname = *arg; | |
272 | else | |
273 | usage(argv); | |
274 | } | |
275 | if (hostname == NULL) | |
276 | usage(argv); | |
277 | ||
278 | /* default to info_flag if nothing else was specified */ | |
279 | if(!(info_flag || update_flag || create_flag || \ | |
7e689fac | 280 | delete_flag || list_map_flag || update_map_flag || \ |
281 | update_alias_flag)) { | |
80e8aa14 | 282 | info_flag++; |
283 | } | |
284 | ||
285 | /* fire up Moira */ | |
080e5e2c | 286 | status = mrcl_connect(server, "stella", 6, !noauth); |
80e8aa14 | 287 | if (status == MRCL_AUTH_ERROR) |
288 | { | |
289 | com_err(whoami, 0, "Try the -noauth flag if you don't " | |
290 | "need authentication."); | |
291 | } | |
292 | if (status) | |
293 | exit(2); | |
294 | ||
295 | /* create if needed */ | |
296 | if (create_flag) | |
297 | { | |
298 | char *argv[30]; | |
299 | int cnt; | |
300 | ||
080e5e2c | 301 | for (cnt = 0; cnt < 16; cnt++) { |
80e8aa14 | 302 | argv[cnt] = ""; |
303 | } | |
304 | ||
305 | argv[0] = canonicalize_hostname(strdup(hostname)); | |
306 | ||
307 | if (vendor) | |
308 | argv[1] = vendor; | |
309 | if (model) | |
310 | argv[2] = model; | |
311 | if (os) | |
312 | argv[3] = os; | |
313 | if (location) | |
314 | argv[4] = location; | |
315 | if (contact) | |
316 | argv[5] = contact; | |
080e5e2c | 317 | if (billing_contact) |
318 | argv[6] = billing_contact; | |
80e8aa14 | 319 | /* The use field always gets set to "0" */ |
080e5e2c | 320 | argv[7] = "0"; |
80e8aa14 | 321 | if (h_status) |
080e5e2c | 322 | argv[8] = h_status; |
80e8aa14 | 323 | else |
080e5e2c | 324 | argv[8] = "1"; |
80e8aa14 | 325 | if (network) |
080e5e2c | 326 | argv[9] = network; |
80e8aa14 | 327 | if (address) |
080e5e2c | 328 | argv[10] = address; |
d55f933a | 329 | else |
080e5e2c | 330 | argv[10] = "unique"; |
80e8aa14 | 331 | if (adm_cmt) |
080e5e2c | 332 | argv[13] = adm_cmt; |
80e8aa14 | 333 | if (op_cmt) |
080e5e2c | 334 | argv[14] = op_cmt; |
80e8aa14 | 335 | |
336 | if (owner) | |
337 | { | |
080e5e2c | 338 | argv[12] = owner->name; |
80e8aa14 | 339 | switch (owner->type) |
340 | { | |
341 | case M_ANY: | |
342 | case M_USER: | |
080e5e2c | 343 | argv[11] = "USER"; |
344 | status = wrap_mr_query("add_host", 15, argv, NULL, NULL); | |
80e8aa14 | 345 | if (owner->type != M_ANY || status != MR_USER) |
346 | break; | |
347 | ||
348 | case M_LIST: | |
080e5e2c | 349 | argv[11] = "LIST"; |
350 | status = wrap_mr_query("add_host", 15, argv, NULL, NULL); | |
80e8aa14 | 351 | break; |
352 | ||
353 | case M_KERBEROS: | |
080e5e2c | 354 | argv[11] = "KERBEROS"; |
df183ce8 | 355 | status = mrcl_validate_kerberos_member(argv[12], &argv[12]); |
356 | if (mrcl_get_message()) | |
357 | mrcl_com_err(whoami); | |
080e5e2c | 358 | status = wrap_mr_query("add_host", 15, argv, NULL, NULL); |
80e8aa14 | 359 | break; |
360 | ||
361 | case M_NONE: | |
080e5e2c | 362 | argv[11] = "NONE"; |
363 | status = wrap_mr_query("add_host", 15, argv, NULL, NULL); | |
80e8aa14 | 364 | break; |
365 | } | |
366 | } | |
367 | else | |
368 | { | |
80e8aa14 | 369 | argv[11] = "NONE"; |
080e5e2c | 370 | argv[12] = "NONE"; |
80e8aa14 | 371 | |
080e5e2c | 372 | status = wrap_mr_query("add_host", 15, argv, NULL, NULL); |
80e8aa14 | 373 | } |
374 | ||
375 | if (status) | |
376 | { | |
377 | com_err(whoami, status, "while creating host."); | |
378 | exit(1); | |
379 | } | |
380 | ||
381 | } | |
382 | else if (update_flag) | |
383 | { | |
384 | char *old_argv[30]; | |
385 | char *argv[16]; | |
386 | char *args[5]; | |
80e8aa14 | 387 | |
388 | args[0] = canonicalize_hostname(strdup(hostname)); | |
389 | args[1] = args[2] = args[3] = "*"; | |
390 | ||
391 | status = wrap_mr_query("get_host", 4, args, store_host_info, old_argv); | |
392 | if (status) | |
393 | { | |
394 | com_err(whoami, status, "while getting list information"); | |
395 | exit(1); | |
396 | } | |
397 | ||
398 | argv[1] = old_argv[0]; | |
399 | argv[2] = old_argv[1]; | |
400 | argv[3] = old_argv[2]; | |
401 | argv[4] = old_argv[3]; | |
402 | argv[5] = old_argv[4]; | |
403 | argv[6] = old_argv[5]; | |
404 | argv[7] = old_argv[6]; | |
405 | argv[8] = old_argv[7]; | |
080e5e2c | 406 | argv[9] = old_argv[8]; |
80e8aa14 | 407 | argv[10] = old_argv[10]; |
408 | argv[11] = old_argv[11]; | |
409 | argv[12] = old_argv[12]; | |
410 | argv[13] = old_argv[13]; | |
411 | argv[14] = old_argv[14]; | |
080e5e2c | 412 | argv[15] = old_argv[15]; |
80e8aa14 | 413 | |
414 | argv[0] = canonicalize_hostname(strdup(hostname)); | |
415 | if (newname) | |
6c114a34 | 416 | argv[1] = canonicalize_hostname(strdup(newname)); |
80e8aa14 | 417 | if (vendor) |
418 | argv[2] = vendor; | |
419 | if (model) | |
420 | argv[3] = model; | |
421 | if (os) | |
422 | argv[4] = os; | |
423 | if (location) | |
424 | argv[5] = location; | |
425 | if (contact) | |
426 | argv[6] = contact; | |
080e5e2c | 427 | if (billing_contact) |
428 | argv[7] = billing_contact; | |
80e8aa14 | 429 | if (h_status) |
080e5e2c | 430 | argv[9] = h_status; |
80e8aa14 | 431 | if (network) |
080e5e2c | 432 | argv[10] = network; |
80e8aa14 | 433 | if (address) |
080e5e2c | 434 | argv[11] = address; |
80e8aa14 | 435 | if (adm_cmt) |
080e5e2c | 436 | argv[14] = adm_cmt; |
80e8aa14 | 437 | if (op_cmt) |
080e5e2c | 438 | argv[15] = op_cmt; |
80e8aa14 | 439 | |
440 | if (owner) | |
441 | { | |
080e5e2c | 442 | argv[13] = owner->name; |
80e8aa14 | 443 | switch (owner->type) |
444 | { | |
445 | case M_ANY: | |
446 | case M_USER: | |
080e5e2c | 447 | argv[12] = "USER"; |
448 | status = wrap_mr_query("update_host", 16, argv, NULL, NULL); | |
80e8aa14 | 449 | if (owner->type != M_ANY || status != MR_USER) |
450 | break; | |
451 | ||
452 | case M_LIST: | |
080e5e2c | 453 | argv[12] = "LIST"; |
454 | status = wrap_mr_query("update_host", 16, argv, NULL, NULL); | |
80e8aa14 | 455 | break; |
456 | ||
457 | case M_KERBEROS: | |
080e5e2c | 458 | argv[12] = "KERBEROS"; |
df183ce8 | 459 | status = mrcl_validate_kerberos_member(argv[13], &argv[13]); |
460 | if (mrcl_get_message()) | |
461 | mrcl_com_err(whoami); | |
080e5e2c | 462 | status = wrap_mr_query("update_host", 16, argv, NULL, NULL); |
80e8aa14 | 463 | break; |
464 | ||
465 | case M_NONE: | |
080e5e2c | 466 | argv[12] = "NONE"; |
467 | status = wrap_mr_query("update_host", 16, argv, NULL, NULL); | |
80e8aa14 | 468 | break; |
469 | } | |
470 | } | |
471 | else | |
080e5e2c | 472 | status = wrap_mr_query("update_host", 16, argv, NULL, NULL); |
80e8aa14 | 473 | |
474 | if (status) | |
475 | com_err(whoami, status, "while updating host."); | |
476 | else if (newname) | |
477 | hostname = newname; | |
478 | } | |
479 | ||
480 | /* create aliases if necessary */ | |
481 | if (alias_add_queue) { | |
482 | struct string_list *q = alias_add_queue; | |
483 | ||
484 | while(q) { | |
485 | char *alias = q->string; | |
486 | char *args[2]; | |
487 | ||
5aa7fdfd | 488 | args[0] = partial_canonicalize_hostname(strdup(alias)); |
80e8aa14 | 489 | args[1] = canonicalize_hostname(strdup(hostname)); |
490 | status = wrap_mr_query("add_hostalias", 2, args, NULL, NULL); | |
491 | if (status) { | |
492 | com_err(whoami, status, "while adding host alias"); | |
493 | exit(1); | |
494 | } | |
495 | ||
496 | q = q->next; | |
497 | } | |
498 | } | |
499 | ||
500 | /* delete aliases if necessary */ | |
501 | if (alias_remove_queue) { | |
502 | struct string_list *q = alias_remove_queue; | |
503 | ||
504 | while(q) { | |
505 | char *alias = q->string; | |
506 | char *args[2]; | |
507 | ||
5aa7fdfd | 508 | args[0] = partial_canonicalize_hostname(strdup(alias)); |
80e8aa14 | 509 | args[1] = canonicalize_hostname(strdup(hostname)); |
510 | status = wrap_mr_query("delete_hostalias", 2, args, NULL, NULL); | |
511 | if (status) { | |
512 | com_err(whoami, status, "while deleting host alias"); | |
513 | exit(1); | |
514 | } | |
515 | ||
516 | q = q->next; | |
517 | } | |
518 | } | |
519 | ||
520 | /* create cluster mappings */ | |
521 | if (map_add_queue) { | |
522 | struct string_list *q = map_add_queue; | |
523 | ||
524 | while(q) { | |
525 | char *clustername = q->string; | |
526 | char *args[2]; | |
527 | ||
528 | args[0] = canonicalize_hostname(strdup(hostname)); | |
529 | args[1] = clustername; | |
530 | status = wrap_mr_query("add_machine_to_cluster", 2, args, NULL, NULL); | |
531 | if (status) { | |
532 | com_err(whoami, status, "while adding cluster mapping"); | |
533 | exit(1); | |
534 | } | |
535 | ||
536 | q = q->next; | |
537 | } | |
538 | } | |
539 | ||
540 | /* delete cluster mappings */ | |
541 | if (map_remove_queue) { | |
542 | struct string_list *q = map_remove_queue; | |
543 | ||
544 | while(q) { | |
545 | char *clustername = q->string; | |
546 | char *args[2]; | |
547 | ||
548 | args[0] = canonicalize_hostname(strdup(hostname)); | |
549 | args[1] = clustername; | |
550 | status = wrap_mr_query("delete_machine_from_cluster", 2, args, | |
551 | NULL, NULL); | |
552 | if (status) { | |
553 | com_err(whoami, status, "while deleting cluster mapping"); | |
554 | exit(1); | |
555 | } | |
556 | ||
557 | q = q->next; | |
558 | } | |
559 | } | |
560 | ||
561 | /* display list info if requested to */ | |
562 | if (info_flag) { | |
563 | struct mqelem *elem = NULL; | |
564 | char *args[5]; | |
565 | char *argv[30]; | |
566 | ||
567 | args[0] = canonicalize_hostname(strdup(hostname)); | |
568 | args[1] = args[2] = args[3] = "*"; | |
569 | status = wrap_mr_query("get_host", 4, args, store_host_info, argv); | |
570 | if (status) { | |
571 | com_err(whoami, status, "while getting host information"); | |
572 | exit(1); | |
573 | } | |
574 | show_host_info(argv); | |
575 | } | |
576 | ||
577 | /* list cluster mappings if needed */ | |
578 | if (list_map_flag) { | |
579 | char *args[3]; | |
580 | ||
581 | args[0] = canonicalize_hostname(strdup(hostname)); | |
582 | args[1] = "*"; | |
583 | status = wrap_mr_query("get_machine_to_cluster_map", 2, args, | |
584 | show_machine_in_cluster, NULL); | |
585 | if (status) | |
586 | if (status != MR_NO_MATCH) { | |
587 | com_err(whoami, status, "while getting cluster mappings"); | |
588 | exit(1); | |
589 | } | |
590 | } | |
591 | ||
592 | if (delete_flag) { | |
593 | char *argv[1]; | |
594 | ||
595 | argv[0] = canonicalize_hostname(strdup(hostname)); | |
596 | status = wrap_mr_query("delete_host", 1, argv, NULL, NULL); | |
597 | if (status) { | |
598 | com_err(whoami, status, "while deleting host"); | |
599 | exit(1); | |
600 | } | |
601 | } | |
602 | ||
603 | /* We're done! */ | |
604 | mr_disconnect(); | |
605 | exit(success ? 0 : 1); | |
606 | } | |
607 | ||
608 | void usage(char **argv) | |
609 | { | |
533bacb3 | 610 | #define USAGE_OPTIONS_FORMAT " %-39s%s\n" |
80e8aa14 | 611 | fprintf(stderr, "Usage: %s hostname [options]\n", argv[0]); |
612 | fprintf(stderr, "Options are\n"); | |
533bacb3 | 613 | fprintf(stderr, USAGE_OPTIONS_FORMAT, "-C | -create", |
80e8aa14 | 614 | "-O | -owner owner"); |
533bacb3 | 615 | fprintf(stderr, USAGE_OPTIONS_FORMAT, "-D | -delete", |
80e8aa14 | 616 | "-S | -status status"); |
533bacb3 | 617 | fprintf(stderr, USAGE_OPTIONS_FORMAT, "-R | -rename newname", |
80e8aa14 | 618 | "-V | -vendor vendor"); |
533bacb3 | 619 | fprintf(stderr, USAGE_OPTIONS_FORMAT, "-a | -addalias alias", |
80e8aa14 | 620 | "-M | -model model"); |
533bacb3 | 621 | fprintf(stderr, USAGE_OPTIONS_FORMAT, "-d | -deletealias alias", |
80e8aa14 | 622 | "-L | -location location"); |
533bacb3 | 623 | fprintf(stderr, USAGE_OPTIONS_FORMAT, "-i | -info", |
80e8aa14 | 624 | "-o | -os os"); |
533bacb3 | 625 | fprintf(stderr, USAGE_OPTIONS_FORMAT, "-oc | -opcmt op_cmt", |
80e8aa14 | 626 | "-c | -contact contact"); |
533bacb3 | 627 | fprintf(stderr, USAGE_OPTIONS_FORMAT, "-ac | -admcmt adm_cmt", |
080e5e2c | 628 | "-bc | -billingcontact billing_contact"); |
629 | fprintf(stderr, USAGE_OPTIONS_FORMAT, "-A | -address address", | |
80e8aa14 | 630 | "-N | -network network"); |
080e5e2c | 631 | fprintf(stderr, USAGE_OPTIONS_FORMAT, "-am | -addmap cluster", |
632 | "-dm | deletemap cluster"); | |
633 | fprintf(stderr, USAGE_OPTIONS_FORMAT, "-lm | -listmap", | |
634 | "-db | -database host[:port]"); | |
533bacb3 | 635 | fprintf(stderr, USAGE_OPTIONS_FORMAT, "-v | -verbose", |
080e5e2c | 636 | "-n | -noauth"); |
80e8aa14 | 637 | exit(1); |
638 | } | |
639 | ||
640 | /* Show alias information */ | |
641 | ||
642 | static int show_has_aliases; | |
643 | ||
644 | int show_alias_info(int argc, char **argv, void *hint) | |
645 | { | |
646 | if(!show_has_aliases++) | |
647 | printf("Aliases: %s", argv[0]); | |
648 | else | |
649 | printf(", %s", argv[0]); | |
650 | ||
651 | return MR_CONT; | |
652 | } | |
653 | ||
654 | static char *states[] = { | |
655 | "Reserved (0)", | |
656 | "Active (1)", | |
657 | "None (2)", | |
658 | "Deleted (3)" | |
659 | }; | |
660 | ||
661 | static char *MacState(int state) | |
662 | { | |
663 | static char buf[BUFSIZ]; | |
664 | ||
665 | if (state < 0 || state > 3) | |
666 | { | |
667 | sprintf(buf, "Unknown (%d)", state); | |
668 | return buf; | |
669 | } | |
670 | return states[state]; | |
671 | } | |
672 | ||
673 | /* Retrieve information about a host */ | |
674 | ||
675 | int store_host_info(int argc, char **argv, void *hint) | |
676 | { | |
677 | int i; | |
678 | char **nargv = hint; | |
679 | ||
680 | for(i=0; i<argc; i++) | |
681 | nargv[i] = strdup(argv[i]); | |
682 | ||
683 | return MR_CONT; | |
684 | } | |
685 | ||
686 | void show_host_info(char **argv) | |
687 | { | |
688 | char tbuf[256]; | |
689 | char *args[3]; | |
690 | struct mqelem *elem = NULL; | |
691 | int stat; | |
692 | ||
693 | printf("Machine: %s\n", argv[M_NAME]); | |
694 | args[0] = "*"; | |
695 | args[1] = argv[M_NAME]; | |
696 | show_has_aliases = 0; | |
697 | stat = wrap_mr_query("get_hostalias", 2, args, show_alias_info, &elem); | |
698 | printf("\n"); | |
699 | if (stat) { | |
700 | if (stat != MR_NO_MATCH) | |
701 | com_err(whoami, stat, "while getting aliases"); | |
702 | } else { | |
703 | printf("\n"); | |
704 | } | |
705 | sprintf(tbuf, "%s %s", argv[M_OWNER_TYPE], | |
706 | strcmp(argv[M_OWNER_TYPE], "NONE") ? argv[M_OWNER_NAME] : ""); | |
707 | printf("Address: %-16s Network: %-16s\n", | |
708 | argv[M_ADDR], argv[M_SUBNET]); | |
709 | printf("Owner: %-16s Use data: %s\n", tbuf, argv[M_INUSE]); | |
710 | printf("Status: %-16s Changed: %s\n", | |
711 | MacState(atoi(argv[M_STAT])), argv[M_STAT_CHNG]); | |
712 | printf("\n"); | |
080e5e2c | 713 | printf("Vendor: %-16s Location: %s\n", argv[M_VENDOR], |
714 | argv[M_LOC]); | |
715 | printf("Model: %-16s Contact: %s\n", argv[M_MODEL], | |
716 | argv[M_CONTACT]); | |
717 | printf("OS: %-16s Billing Contact: %s\n", argv[M_OS], | |
718 | argv[M_BILL_CONTACT]); | |
719 | printf("\nOpt: %s\n", argv[M_USE]); | |
80e8aa14 | 720 | printf("\nAdm cmt: %s\n", argv[M_ACOMMENT]); |
721 | printf("Op cmt: %s\n", argv[M_OCOMMENT]); | |
722 | printf("\n"); | |
723 | printf("Created by %s on %s\n", argv[M_CREATOR], argv[M_CREATED]); | |
724 | printf("Last mod by %s at %s with %s.\n", argv[M_MODBY], argv[M_MODTIME], argv[M_MODWITH]); | |
725 | } | |
726 | ||
727 | int show_machine_in_cluster(int argc, char **argv, void *hint) | |
728 | { | |
729 | printf("Machine: %-30s Cluster: %-30s\n", argv[0], argv[1]); | |
730 | ||
731 | return MR_CONT; | |
732 | } | |
733 | ||
734 | /* Parse a line of input, fetching a member. NULL is returned if a member | |
735 | * is not found. ';' is a comment character. | |
736 | */ | |
737 | ||
738 | struct owner_type *parse_member(char *s) | |
739 | { | |
740 | struct owner_type *m; | |
741 | char *p, *lastchar; | |
742 | ||
743 | while (*s && isspace(*s)) | |
744 | s++; | |
745 | lastchar = p = s; | |
746 | while (*p && *p != '\n' && *p != ';') | |
747 | { | |
748 | if (isprint(*p) && !isspace(*p)) | |
749 | lastchar = p++; | |
750 | else | |
751 | p++; | |
752 | } | |
753 | lastchar++; | |
754 | *lastchar = '\0'; | |
755 | if (p == s || strlen(s) == 0) | |
756 | return NULL; | |
757 | ||
758 | if (!(m = malloc(sizeof(struct owner_type)))) | |
759 | return NULL; | |
760 | ||
761 | if ((p = strchr(s, ':'))) | |
762 | { | |
763 | *p = '\0'; | |
764 | m->name = ++p; | |
765 | if (!strcasecmp("user", s)) | |
766 | m->type = M_USER; | |
767 | else if (!strcasecmp("list", s)) | |
768 | m->type = M_LIST; | |
80e8aa14 | 769 | else if (!strcasecmp("kerberos", s)) |
770 | m->type = M_KERBEROS; | |
771 | else if (!strcasecmp("none", s)) | |
772 | m->type = M_NONE; | |
773 | else | |
774 | { | |
775 | m->type = M_ANY; | |
776 | *(--p) = ':'; | |
777 | m->name = s; | |
778 | } | |
779 | m->name = strdup(m->name); | |
780 | } | |
781 | else | |
782 | { | |
783 | m->name = strdup(s); | |
784 | m->type = strcasecmp(s, "none") ? M_ANY : M_NONE; | |
785 | } | |
786 | return m; | |
787 | } | |
788 | ||
789 | struct string_list *add_to_string_list(struct string_list *old_list, char *s) { | |
790 | struct string_list *new_list; | |
791 | ||
792 | new_list = (struct string_list *)malloc(sizeof(struct string_list *)); | |
793 | new_list->next = old_list; | |
794 | new_list->string = s; | |
795 | ||
796 | return new_list; | |
797 | } | |
798 | ||
799 | int wrap_mr_query(char *handle, int argc, char **argv, | |
800 | int (*callback)(int, char **, void *), void *callarg) { | |
801 | if (verbose) | |
802 | print_query(handle, argc, argv); | |
803 | ||
804 | return mr_query(handle, argc, argv, callback, callarg); | |
805 | } | |
806 | ||
807 | void print_query(char *query_name, int argc, char **argv) { | |
808 | int cnt; | |
809 | ||
810 | printf("qy %s", query_name); | |
811 | for(cnt=0; cnt<argc; cnt++) | |
812 | printf(" <%s>", argv[cnt]); | |
813 | printf("\n"); | |
814 | } |