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;
42 /* It is important to membercmp that M_USER < M_LIST < M_STRING */
50 /* argument parsing macro */
51 #define argis(a, b) (!strcmp(*arg + 1, a) || !strcmp(*arg + 1, b))
53 /* flags from command line */
54 int info_flag, update_flag, create_flag, delete_flag, list_map_flag;
55 int update_map_flag, verbose, noauth;
57 struct string_list *alias_add_queue, *alias_remove_queue;
58 struct string_list *map_add_queue, *map_remove_queue;
60 char *hostname, *whoami;
62 char *newname, *address, *network, *h_status, *vendor, *model;
63 char *os, *location, *contact, *adm_cmt, *op_cmt;
65 struct owner_type *owner;
67 void usage(char **argv);
68 int store_host_info(int argc, char **argv, void *hint);
69 void show_host_info(char **argv);
70 int show_machine_in_cluster(int argc, char **argv, void *hint);
71 struct owner_type *parse_member(char *s);
72 struct string_list *add_to_string_list(struct string_list *old_list, char *s);
73 int wrap_mr_query(char *handle, int argc, char **argv,
74 int (*callback)(int, char **, void *), void *callarg);
75 void print_query(char *query_name, int argc, char **argv);
77 int main(int argc, char **argv)
81 char *server = NULL, *p;
83 /* clear all flags & lists */
84 info_flag = update_flag = create_flag = list_map_flag = update_map_flag = 0;
86 newname = address = network = h_status = vendor = model = NULL;
87 os = location = contact = adm_cmt = op_cmt = NULL;
89 alias_add_queue = alias_remove_queue = NULL;
90 map_add_queue = map_remove_queue = NULL;
95 /* parse args, building addlist, dellist, & synclist */
96 while (++arg - argv < argc)
100 if (argis("i", "info"))
102 else if (argis("C", "create"))
104 else if (argis("D", "delete"))
106 else if (argis("R", "rename")) {
107 if (arg - argv < argc - 1) {
114 else if (argis("A", "address")) {
115 if (arg - argv < argc - 1) {
122 else if (argis("O", "owner")) {
123 if (arg - argv < argc - 1) {
126 owner = parse_member(*arg);
130 else if (argis("N", "network")) {
131 if (arg - argv < argc - 1) {
138 else if (argis("S", "status")) {
139 if (arg - argv < argc - 1) {
146 for(i=0; i<strlen(h_status); 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("ac", "admcmt")) {
196 if (arg - argv < argc - 1) {
203 else if (argis("oc", "opcmt")) {
204 if (arg - argv < argc - 1) {
211 else if (argis("a", "aliasadd")) {
212 if (arg - argv < argc - 1) {
214 alias_add_queue=add_to_string_list(alias_add_queue, *arg);
218 else if (argis("d", "aliasdelete")) {
219 if (arg - argv < argc - 1) {
221 alias_remove_queue=add_to_string_list(alias_remove_queue, *arg);
225 else if (argis("am", "addmap")) {
226 if (arg - argv < argc - 1) {
228 map_add_queue=add_to_string_list(map_add_queue, *arg);
233 else if (argis("dm", "deletemap")) {
234 if (arg - argv < argc - 1) {
236 map_remove_queue=add_to_string_list(map_remove_queue, *arg);
241 else if (argis("lm", "listmap"))
243 else if (argis("n", "noauth"))
245 else if (argis("v", "verbose"))
247 else if (argis("db", "database"))
249 if (arg - argv < argc - 1)
260 else if (hostname == NULL)
265 if (hostname == NULL)
268 /* default to info_flag if nothing else was specified */
269 if(!(info_flag || update_flag || create_flag || \
270 delete_flag || list_map_flag || update_map_flag )) {
275 status = mrcl_connect(server, "stella", 2, !noauth);
276 if (status == MRCL_AUTH_ERROR)
278 com_err(whoami, 0, "Try the -noauth flag if you don't "
279 "need authentication.");
284 /* create if needed */
290 for (cnt = 0; cnt < 15; cnt++) {
294 argv[0] = canonicalize_hostname(strdup(hostname));
306 /* The use field always gets set to "0" */
323 argv[11] = owner->name;
329 status = wrap_mr_query("add_host", 14, argv, NULL, NULL);
330 if (owner->type != M_ANY || status != MR_USER)
335 status = wrap_mr_query("add_host", 14, argv, NULL, NULL);
339 argv[10] = "KERBEROS";
340 status = wrap_mr_query("add_host", 14, argv, NULL, NULL);
345 status = wrap_mr_query("add_host", 14, argv, NULL, NULL);
354 status = wrap_mr_query("add_host", 14, argv, NULL, NULL);
359 com_err(whoami, status, "while creating host.");
364 else if (update_flag)
371 args[0] = canonicalize_hostname(strdup(hostname));
372 args[1] = args[2] = args[3] = "*";
374 status = wrap_mr_query("get_host", 4, args, store_host_info, old_argv);
377 com_err(whoami, status, "while getting list information");
381 argv[1] = old_argv[0];
382 argv[2] = old_argv[1];
383 argv[3] = old_argv[2];
384 argv[4] = old_argv[3];
385 argv[5] = old_argv[4];
386 argv[6] = old_argv[5];
387 argv[7] = old_argv[6];
388 argv[8] = old_argv[7];
389 argv[9] = old_argv[9];
390 argv[10] = old_argv[10];
391 argv[11] = old_argv[11];
392 argv[12] = old_argv[12];
393 argv[13] = old_argv[13];
394 argv[14] = old_argv[14];
396 argv[0] = canonicalize_hostname(strdup(hostname));
422 argv[12] = owner->name;
428 status = wrap_mr_query("update_host", 15, argv, NULL, NULL);
429 if (owner->type != M_ANY || status != MR_USER)
434 status = wrap_mr_query("update_host", 15, argv, NULL, NULL);
438 argv[11] = "KERBEROS";
439 status = wrap_mr_query("update_host", 15, argv, NULL, NULL);
444 status = wrap_mr_query("update_host", 15, argv, NULL, NULL);
449 status = wrap_mr_query("update_host", 15, argv, NULL, NULL);
452 com_err(whoami, status, "while updating host.");
457 /* create aliases if necessary */
458 if (alias_add_queue) {
459 struct string_list *q = alias_add_queue;
462 char *alias = q->string;
465 args[0] = canonicalize_hostname(strdup(alias));
466 args[1] = canonicalize_hostname(strdup(hostname));
467 status = wrap_mr_query("add_hostalias", 2, args, NULL, NULL);
469 com_err(whoami, status, "while adding host alias");
477 /* delete aliases if necessary */
478 if (alias_remove_queue) {
479 struct string_list *q = alias_remove_queue;
482 char *alias = q->string;
485 args[0] = canonicalize_hostname(strdup(alias));
486 args[1] = canonicalize_hostname(strdup(hostname));
487 status = wrap_mr_query("delete_hostalias", 2, args, NULL, NULL);
489 com_err(whoami, status, "while deleting host alias");
497 /* create cluster mappings */
499 struct string_list *q = map_add_queue;
502 char *clustername = q->string;
505 args[0] = canonicalize_hostname(strdup(hostname));
506 args[1] = clustername;
507 status = wrap_mr_query("add_machine_to_cluster", 2, args, NULL, NULL);
509 com_err(whoami, status, "while adding cluster mapping");
517 /* delete cluster mappings */
518 if (map_remove_queue) {
519 struct string_list *q = map_remove_queue;
522 char *clustername = q->string;
525 args[0] = canonicalize_hostname(strdup(hostname));
526 args[1] = clustername;
527 status = wrap_mr_query("delete_machine_from_cluster", 2, args,
530 com_err(whoami, status, "while deleting cluster mapping");
538 /* display list info if requested to */
540 struct mqelem *elem = NULL;
544 args[0] = canonicalize_hostname(strdup(hostname));
545 args[1] = args[2] = args[3] = "*";
546 status = wrap_mr_query("get_host", 4, args, store_host_info, argv);
548 com_err(whoami, status, "while getting host information");
551 show_host_info(argv);
554 /* list cluster mappings if needed */
558 args[0] = canonicalize_hostname(strdup(hostname));
560 status = wrap_mr_query("get_machine_to_cluster_map", 2, args,
561 show_machine_in_cluster, NULL);
563 if (status != MR_NO_MATCH) {
564 com_err(whoami, status, "while getting cluster mappings");
572 argv[0] = canonicalize_hostname(strdup(hostname));
573 status = wrap_mr_query("delete_host", 1, argv, NULL, NULL);
575 com_err(whoami, status, "while deleting host");
582 exit(success ? 0 : 1);
585 void usage(char **argv)
587 fprintf(stderr, "Usage: %s hostname [options]\n", argv[0]);
588 fprintf(stderr, "Options are\n");
589 fprintf(stderr, " %-39s%-39s\n", "-C | -create",
590 "-O | -owner owner");
591 fprintf(stderr, " %-39s%-39s\n", "-D | -delete",
592 "-S | -status status");
593 fprintf(stderr, " %-39s%-39s\n", "-R | -rename newname",
594 "-V | -vendor vendor");
595 fprintf(stderr, " %-39s%-39s\n", "-a | -addalias alias",
596 "-M | -model model");
597 fprintf(stderr, " %-39s%-39s\n", "-d | -deletealias alias",
598 "-L | -location location");
599 fprintf(stderr, " %-39s%-39s\n", "-i | -info",
601 fprintf(stderr, " %-39s%-39s\n", "-oc | -opcmt op_cmt",
602 "-c | -contact contact");
603 fprintf(stderr, " %-39s%-39s\n", "-ac | -admcmt adm_cmt",
604 "-A | -address address");
605 fprintf(stderr, " %-39s%-39s\n", "-am | -addmap cluster",
606 "-N | -network network");
607 fprintf(stderr, " %-39s%-39s\n", "-dm | -deletemap cluster",
609 fprintf(stderr, " %-39s%-39s\n", "-db | -database host[:port]",
611 fprintf(stderr, " %-39s%-39s\n", "-v | -verbose",
616 /* Show alias information */
618 static int show_has_aliases;
620 int show_alias_info(int argc, char **argv, void *hint)
622 if(!show_has_aliases++)
623 printf("Aliases: %s", argv[0]);
625 printf(", %s", argv[0]);
630 static char *states[] = {
637 static char *MacState(int state)
639 static char buf[BUFSIZ];
641 if (state < 0 || state > 3)
643 sprintf(buf, "Unknown (%d)", state);
646 return states[state];
649 /* Retrieve information about a host */
651 int store_host_info(int argc, char **argv, void *hint)
656 for(i=0; i<argc; i++)
657 nargv[i] = strdup(argv[i]);
662 void show_host_info(char **argv)
666 struct mqelem *elem = NULL;
669 printf("Machine: %s\n", argv[M_NAME]);
671 args[1] = argv[M_NAME];
672 show_has_aliases = 0;
673 stat = wrap_mr_query("get_hostalias", 2, args, show_alias_info, &elem);
676 if (stat != MR_NO_MATCH)
677 com_err(whoami, stat, "while getting aliases");
681 sprintf(tbuf, "%s %s", argv[M_OWNER_TYPE],
682 strcmp(argv[M_OWNER_TYPE], "NONE") ? argv[M_OWNER_NAME] : "");
683 printf("Address: %-16s Network: %-16s\n",
684 argv[M_ADDR], argv[M_SUBNET]);
685 printf("Owner: %-16s Use data: %s\n", tbuf, argv[M_INUSE]);
686 printf("Status: %-16s Changed: %s\n",
687 MacState(atoi(argv[M_STAT])), argv[M_STAT_CHNG]);
690 printf("Vendor: %-16s Model: %-20s OS: %s\n",
691 argv[M_VENDOR], argv[M_MODEL], argv[M_OS]);
692 printf("Location: %-16s Contact: %-20s Opt: %s\n",
693 argv[M_LOC], argv[M_CONTACT], argv[M_USE]);
694 printf("\nAdm cmt: %s\n", argv[M_ACOMMENT]);
695 printf("Op cmt: %s\n", argv[M_OCOMMENT]);
697 printf("Created by %s on %s\n", argv[M_CREATOR], argv[M_CREATED]);
698 printf("Last mod by %s at %s with %s.\n", argv[M_MODBY], argv[M_MODTIME], argv[M_MODWITH]);
701 int show_machine_in_cluster(int argc, char **argv, void *hint)
703 printf("Machine: %-30s Cluster: %-30s\n", argv[0], argv[1]);
708 /* Parse a line of input, fetching a member. NULL is returned if a member
709 * is not found. ';' is a comment character.
712 struct owner_type *parse_member(char *s)
714 struct owner_type *m;
717 while (*s && isspace(*s))
720 while (*p && *p != '\n' && *p != ';')
722 if (isprint(*p) && !isspace(*p))
729 if (p == s || strlen(s) == 0)
732 if (!(m = malloc(sizeof(struct owner_type))))
735 if ((p = strchr(s, ':')))
739 if (!strcasecmp("user", s))
741 else if (!strcasecmp("list", s))
743 else if (!strcasecmp("string", s))
745 else if (!strcasecmp("kerberos", s))
746 m->type = M_KERBEROS;
747 else if (!strcasecmp("none", s))
755 m->name = strdup(m->name);
760 m->type = strcasecmp(s, "none") ? M_ANY : M_NONE;
765 struct string_list *add_to_string_list(struct string_list *old_list, char *s) {
766 struct string_list *new_list;
768 new_list = (struct string_list *)malloc(sizeof(struct string_list *));
769 new_list->next = old_list;
770 new_list->string = s;
775 int wrap_mr_query(char *handle, int argc, char **argv,
776 int (*callback)(int, char **, void *), void *callarg) {
778 print_query(handle, argc, argv);
780 return mr_query(handle, argc, argv, callback, callarg);
783 void print_query(char *query_name, int argc, char **argv) {
786 printf("qy %s", query_name);
787 for(cnt=0; cnt<argc; cnt++)
788 printf(" <%s>", argv[cnt]);