2 * Command line oriented Moira host tool.
4 * kolya@MIT.EDU, January 2000
6 * Somewhat based on blanche
8 * Copyright (C) 2000 by the Massachusetts Institute of Technology.
9 * For copying and distribution information, please see the file
13 #include <mit-copyright.h>
15 #include <moira_site.h>
32 struct mqelem *q_forw;
33 struct mqelem *q_back;
39 struct string_list *next;
48 /* argument parsing macro */
49 #define argis(a, b) (!strcmp(*arg + 1, a) || !strcmp(*arg + 1, b))
51 /* flags from command line */
52 int info_flag, update_flag, create_flag, delete_flag, list_map_flag;
53 int update_alias_flag, update_map_flag, verbose, noauth;
55 struct string_list *alias_add_queue, *alias_remove_queue;
56 struct string_list *map_add_queue, *map_remove_queue;
58 char *hostname, *whoami;
60 char *newname, *address, *network, *h_status, *vendor, *model;
61 char *os, *location, *contact, *billing_contact, *adm_cmt, *op_cmt;
63 struct owner_type *owner;
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);
75 int main(int argc, char **argv)
81 /* clear all flags & lists */
82 info_flag = update_flag = create_flag = list_map_flag = update_map_flag = 0;
83 update_alias_flag = verbose = noauth = 0;
84 newname = address = network = h_status = vendor = model = NULL;
85 os = location = contact = billing_contact = adm_cmt = op_cmt = NULL;
87 alias_add_queue = alias_remove_queue = NULL;
88 map_add_queue = map_remove_queue = NULL;
93 /* parse args, building addlist, dellist, & synclist */
94 while (++arg - argv < argc)
98 if (argis("i", "info"))
100 else if (argis("C", "create"))
102 else if (argis("D", "delete"))
104 else if (argis("R", "rename")) {
105 if (arg - argv < argc - 1) {
112 else if (argis("A", "address")) {
113 if (arg - argv < argc - 1) {
120 else if (argis("O", "owner")) {
121 if (arg - argv < argc - 1) {
124 owner = parse_member(*arg);
128 else if (argis("N", "network")) {
129 if (arg - argv < argc - 1) {
136 else if (argis("S", "status")) {
137 if (arg - argv < argc - 1) {
145 len = strlen(h_status);
146 for(i = 0; i < len; i++) {
147 if(!isdigit(h_status[i])) {
148 printf("Error: status code %s is not numeric.\n", h_status);
155 else if (argis("V", "vendor")) {
156 if (arg - argv < argc - 1) {
163 else if (argis("M", "model")) {
164 if (arg - argv < argc - 1) {
171 else if (argis("o", "os")) {
172 if (arg - argv < argc - 1) {
179 else if (argis("L", "location")) {
180 if (arg - argv < argc - 1) {
187 else if (argis("c", "contact")) {
188 if (arg - argv < argc - 1) {
195 else if (argis("bc", "billingcontact")) {
196 if (arg - argv < argc - 1) {
199 billing_contact = *arg;
203 else if (argis("ac", "admcmt")) {
204 if (arg - argv < argc - 1) {
211 else if (argis("oc", "opcmt")) {
212 if (arg - argv < argc - 1) {
219 else if (argis("a", "aliasadd")) {
220 if (arg - argv < argc - 1) {
222 alias_add_queue=add_to_string_list(alias_add_queue, *arg);
227 else if (argis("d", "aliasdelete")) {
228 if (arg - argv < argc - 1) {
230 alias_remove_queue=add_to_string_list(alias_remove_queue, *arg);
235 else if (argis("am", "addmap")) {
236 if (arg - argv < argc - 1) {
238 map_add_queue=add_to_string_list(map_add_queue, *arg);
243 else if (argis("dm", "deletemap")) {
244 if (arg - argv < argc - 1) {
246 map_remove_queue=add_to_string_list(map_remove_queue, *arg);
251 else if (argis("lm", "listmap"))
253 else if (argis("n", "noauth"))
255 else if (argis("v", "verbose"))
257 else if (argis("db", "database"))
259 if (arg - argv < argc - 1)
270 else if (hostname == NULL)
275 if (hostname == NULL)
278 /* default to info_flag if nothing else was specified */
279 if(!(info_flag || update_flag || create_flag || \
280 delete_flag || list_map_flag || update_map_flag || \
281 update_alias_flag)) {
286 status = mrcl_connect(server, "stella", 6, !noauth);
287 if (status == MRCL_AUTH_ERROR)
289 com_err(whoami, 0, "Try the -noauth flag if you don't "
290 "need authentication.");
295 /* create if needed */
301 for (cnt = 0; cnt < 16; cnt++) {
305 argv[0] = canonicalize_hostname(strdup(hostname));
318 argv[6] = billing_contact;
319 /* The use field always gets set to "0" */
338 argv[12] = owner->name;
344 status = wrap_mr_query("add_host", 15, argv, NULL, NULL);
345 if (owner->type != M_ANY || status != MR_USER)
350 status = wrap_mr_query("add_host", 15, argv, NULL, NULL);
354 argv[11] = "KERBEROS";
355 status = mrcl_validate_kerberos_member(argv[12], &argv[12]);
356 if (mrcl_get_message())
357 mrcl_com_err(whoami);
358 status = wrap_mr_query("add_host", 15, argv, NULL, NULL);
363 status = wrap_mr_query("add_host", 15, argv, NULL, NULL);
372 status = wrap_mr_query("add_host", 15, argv, NULL, NULL);
377 com_err(whoami, status, "while creating host.");
382 else if (update_flag)
388 args[0] = canonicalize_hostname(strdup(hostname));
389 args[1] = args[2] = args[3] = "*";
391 status = wrap_mr_query("get_host", 4, args, store_host_info, old_argv);
394 com_err(whoami, status, "while getting list information");
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];
406 argv[9] = old_argv[8];
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];
412 argv[15] = old_argv[15];
414 argv[0] = canonicalize_hostname(strdup(hostname));
416 argv[1] = canonicalize_hostname(strdup(newname));
428 argv[7] = billing_contact;
442 argv[13] = owner->name;
448 status = wrap_mr_query("update_host", 16, argv, NULL, NULL);
449 if (owner->type != M_ANY || status != MR_USER)
454 status = wrap_mr_query("update_host", 16, argv, NULL, NULL);
458 argv[12] = "KERBEROS";
459 status = mrcl_validate_kerberos_member(argv[13], &argv[13]);
460 if (mrcl_get_message())
461 mrcl_com_err(whoami);
462 status = wrap_mr_query("update_host", 16, argv, NULL, NULL);
467 status = wrap_mr_query("update_host", 16, argv, NULL, NULL);
472 status = wrap_mr_query("update_host", 16, argv, NULL, NULL);
475 com_err(whoami, status, "while updating host.");
480 /* create aliases if necessary */
481 if (alias_add_queue) {
482 struct string_list *q = alias_add_queue;
485 char *alias = q->string;
488 args[0] = partial_canonicalize_hostname(strdup(alias));
489 args[1] = canonicalize_hostname(strdup(hostname));
490 status = wrap_mr_query("add_hostalias", 2, args, NULL, NULL);
492 com_err(whoami, status, "while adding host alias");
500 /* delete aliases if necessary */
501 if (alias_remove_queue) {
502 struct string_list *q = alias_remove_queue;
505 char *alias = q->string;
508 args[0] = partial_canonicalize_hostname(strdup(alias));
509 args[1] = canonicalize_hostname(strdup(hostname));
510 status = wrap_mr_query("delete_hostalias", 2, args, NULL, NULL);
512 com_err(whoami, status, "while deleting host alias");
520 /* create cluster mappings */
522 struct string_list *q = map_add_queue;
525 char *clustername = q->string;
528 args[0] = canonicalize_hostname(strdup(hostname));
529 args[1] = clustername;
530 status = wrap_mr_query("add_machine_to_cluster", 2, args, NULL, NULL);
532 com_err(whoami, status, "while adding cluster mapping");
540 /* delete cluster mappings */
541 if (map_remove_queue) {
542 struct string_list *q = map_remove_queue;
545 char *clustername = q->string;
548 args[0] = canonicalize_hostname(strdup(hostname));
549 args[1] = clustername;
550 status = wrap_mr_query("delete_machine_from_cluster", 2, args,
553 com_err(whoami, status, "while deleting cluster mapping");
561 /* display list info if requested to */
563 struct mqelem *elem = NULL;
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);
571 com_err(whoami, status, "while getting host information");
574 show_host_info(argv);
577 /* list cluster mappings if needed */
581 args[0] = canonicalize_hostname(strdup(hostname));
583 status = wrap_mr_query("get_machine_to_cluster_map", 2, args,
584 show_machine_in_cluster, NULL);
586 if (status != MR_NO_MATCH) {
587 com_err(whoami, status, "while getting cluster mappings");
595 argv[0] = canonicalize_hostname(strdup(hostname));
596 status = wrap_mr_query("delete_host", 1, argv, NULL, NULL);
598 com_err(whoami, status, "while deleting host");
605 exit(success ? 0 : 1);
608 void usage(char **argv)
610 #define USAGE_OPTIONS_FORMAT " %-39s%s\n"
611 fprintf(stderr, "Usage: %s hostname [options]\n", argv[0]);
612 fprintf(stderr, "Options are\n");
613 fprintf(stderr, USAGE_OPTIONS_FORMAT, "-C | -create",
614 "-O | -owner owner");
615 fprintf(stderr, USAGE_OPTIONS_FORMAT, "-D | -delete",
616 "-S | -status status");
617 fprintf(stderr, USAGE_OPTIONS_FORMAT, "-R | -rename newname",
618 "-V | -vendor vendor");
619 fprintf(stderr, USAGE_OPTIONS_FORMAT, "-a | -addalias alias",
620 "-M | -model model");
621 fprintf(stderr, USAGE_OPTIONS_FORMAT, "-d | -deletealias alias",
622 "-L | -location location");
623 fprintf(stderr, USAGE_OPTIONS_FORMAT, "-i | -info",
625 fprintf(stderr, USAGE_OPTIONS_FORMAT, "-oc | -opcmt op_cmt",
626 "-c | -contact contact");
627 fprintf(stderr, USAGE_OPTIONS_FORMAT, "-ac | -admcmt adm_cmt",
628 "-bc | -billingcontact billing_contact");
629 fprintf(stderr, USAGE_OPTIONS_FORMAT, "-A | -address address",
630 "-N | -network network");
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]");
635 fprintf(stderr, USAGE_OPTIONS_FORMAT, "-v | -verbose",
640 /* Show alias information */
642 static int show_has_aliases;
644 int show_alias_info(int argc, char **argv, void *hint)
646 if(!show_has_aliases++)
647 printf("Aliases: %s", argv[0]);
649 printf(", %s", argv[0]);
654 static char *states[] = {
661 static char *MacState(int state)
663 static char buf[BUFSIZ];
665 if (state < 0 || state > 3)
667 sprintf(buf, "Unknown (%d)", state);
670 return states[state];
673 /* Retrieve information about a host */
675 int store_host_info(int argc, char **argv, void *hint)
680 for(i=0; i<argc; i++)
681 nargv[i] = strdup(argv[i]);
686 void show_host_info(char **argv)
690 struct mqelem *elem = NULL;
693 printf("Machine: %s\n", argv[M_NAME]);
695 args[1] = argv[M_NAME];
696 show_has_aliases = 0;
697 stat = wrap_mr_query("get_hostalias", 2, args, show_alias_info, &elem);
700 if (stat != MR_NO_MATCH)
701 com_err(whoami, stat, "while getting aliases");
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]);
713 printf("Vendor: %-16s Location: %s\n", argv[M_VENDOR],
715 printf("Model: %-16s Contact: %s\n", argv[M_MODEL],
717 printf("OS: %-16s Billing Contact: %s\n", argv[M_OS],
718 argv[M_BILL_CONTACT]);
719 printf("\nOpt: %s\n", argv[M_USE]);
720 printf("\nAdm cmt: %s\n", argv[M_ACOMMENT]);
721 printf("Op cmt: %s\n", argv[M_OCOMMENT]);
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]);
727 int show_machine_in_cluster(int argc, char **argv, void *hint)
729 printf("Machine: %-30s Cluster: %-30s\n", argv[0], argv[1]);
734 /* Parse a line of input, fetching a member. NULL is returned if a member
735 * is not found. ';' is a comment character.
738 struct owner_type *parse_member(char *s)
740 struct owner_type *m;
743 while (*s && isspace(*s))
746 while (*p && *p != '\n' && *p != ';')
748 if (isprint(*p) && !isspace(*p))
755 if (p == s || strlen(s) == 0)
758 if (!(m = malloc(sizeof(struct owner_type))))
761 if ((p = strchr(s, ':')))
765 if (!strcasecmp("user", s))
767 else if (!strcasecmp("list", s))
769 else if (!strcasecmp("kerberos", s))
770 m->type = M_KERBEROS;
771 else if (!strcasecmp("none", s))
779 m->name = strdup(m->name);
784 m->type = strcasecmp(s, "none") ? M_ANY : M_NONE;
789 struct string_list *add_to_string_list(struct string_list *old_list, char *s) {
790 struct string_list *new_list;
792 new_list = (struct string_list *)malloc(sizeof(struct string_list *));
793 new_list->next = old_list;
794 new_list->string = s;
799 int wrap_mr_query(char *handle, int argc, char **argv,
800 int (*callback)(int, char **, void *), void *callarg) {
802 print_query(handle, argc, argv);
804 return mr_query(handle, argc, argv, callback, callarg);
807 void print_query(char *query_name, int argc, char **argv) {
810 printf("qy %s", query_name);
811 for(cnt=0; cnt<argc; cnt++)
812 printf(" <%s>", argv[cnt]);