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