/* * Command line oriented Moira host tool. * * kolya@MIT.EDU, January 2000 * * Somewhat based on blanche * * Copyright (C) 2000 by the Massachusetts Institute of Technology. * For copying and distribution information, please see the file * . */ #include #include #include #include #include #include #include #include #include RCSID("$Header$"); struct owner_type { int type; char *name; }; struct mqelem { struct mqelem *q_forw; struct mqelem *q_back; void *q_data; }; struct string_list { char *string; struct string_list *next; }; /* It is important to membercmp that M_USER < M_LIST < M_STRING */ #define M_ANY 0 #define M_USER 1 #define M_LIST 2 #define M_STRING 3 #define M_KERBEROS 4 #define M_NONE 5 /* argument parsing macro */ #define argis(a, b) (!strcmp(*arg + 1, a) || !strcmp(*arg + 1, b)) /* flags from command line */ int info_flag, update_flag, create_flag, delete_flag, list_map_flag; int update_map_flag, verbose, noauth; struct string_list *alias_add_queue, *alias_remove_queue; struct string_list *map_add_queue, *map_remove_queue; char *hostname, *whoami; char *newname, *address, *network, *h_status, *vendor, *model; char *os, *location, *contact, *adm_cmt, *op_cmt; struct owner_type *owner; void usage(char **argv); int store_host_info(int argc, char **argv, void *hint); void show_host_info(char **argv); int show_machine_in_cluster(int argc, char **argv, void *hint); struct owner_type *parse_member(char *s); struct string_list *add_to_string_list(struct string_list *old_list, char *s); int wrap_mr_query(char *handle, int argc, char **argv, int (*callback)(int, char **, void *), void *callarg); void print_query(char *query_name, int argc, char **argv); int main(int argc, char **argv) { int status, success; char **arg = argv; char *server = NULL, *p; /* clear all flags & lists */ info_flag = update_flag = create_flag = list_map_flag = update_map_flag = 0; verbose = noauth = 0; newname = address = network = h_status = vendor = model = NULL; os = location = contact = adm_cmt = op_cmt = NULL; owner = NULL; alias_add_queue = alias_remove_queue = NULL; map_add_queue = map_remove_queue = NULL; whoami = argv[0]; success = 1; /* parse args, building addlist, dellist, & synclist */ while (++arg - argv < argc) { if (**arg == '-') { if (argis("i", "info")) info_flag++; else if (argis("C", "create")) create_flag++; else if (argis("D", "delete")) delete_flag++; else if (argis("R", "rename")) { if (arg - argv < argc - 1) { arg++; update_flag++; newname = *arg; } else usage(argv); } else if (argis("A", "address")) { if (arg - argv < argc - 1) { arg++; update_flag++; address = *arg; } else usage(argv); } else if (argis("O", "owner")) { if (arg - argv < argc - 1) { arg++; update_flag++; owner = parse_member(*arg); } else usage(argv); } else if (argis("N", "network")) { if (arg - argv < argc - 1) { arg++; update_flag++; network = *arg; } else usage(argv); } else if (argis("S", "status")) { if (arg - argv < argc - 1) { int i; arg++; update_flag++; h_status = *arg; for(i=0; iname; switch (owner->type) { case M_ANY: case M_USER: argv[10] = "USER"; status = wrap_mr_query("add_host", 14, argv, NULL, NULL); if (owner->type != M_ANY || status != MR_USER) break; case M_LIST: argv[10] = "LIST"; status = wrap_mr_query("add_host", 14, argv, NULL, NULL); break; case M_KERBEROS: argv[10] = "KERBEROS"; status = wrap_mr_query("add_host", 14, argv, NULL, NULL); break; case M_NONE: argv[10] = "NONE"; status = wrap_mr_query("add_host", 14, argv, NULL, NULL); break; } } else { argv[10] = "NONE"; argv[11] = "NONE"; status = wrap_mr_query("add_host", 14, argv, NULL, NULL); } if (status) { com_err(whoami, status, "while creating host."); exit(1); } } else if (update_flag) { char *old_argv[30]; char *argv[16]; char *args[5]; int cnt; args[0] = canonicalize_hostname(strdup(hostname)); args[1] = args[2] = args[3] = "*"; status = wrap_mr_query("get_host", 4, args, store_host_info, old_argv); if (status) { com_err(whoami, status, "while getting list information"); exit(1); } argv[1] = old_argv[0]; argv[2] = old_argv[1]; argv[3] = old_argv[2]; argv[4] = old_argv[3]; argv[5] = old_argv[4]; argv[6] = old_argv[5]; argv[7] = old_argv[6]; argv[8] = old_argv[7]; argv[9] = old_argv[9]; argv[10] = old_argv[10]; argv[11] = old_argv[11]; argv[12] = old_argv[12]; argv[13] = old_argv[13]; argv[14] = old_argv[14]; argv[0] = canonicalize_hostname(strdup(hostname)); if (newname) argv[1] = newname; if (vendor) argv[2] = vendor; if (model) argv[3] = model; if (os) argv[4] = os; if (location) argv[5] = location; if (contact) argv[6] = contact; if (h_status) argv[8] = h_status; if (network) argv[9] = network; if (address) argv[10] = address; if (adm_cmt) argv[13] = adm_cmt; if (op_cmt) argv[14] = op_cmt; if (owner) { argv[12] = owner->name; switch (owner->type) { case M_ANY: case M_USER: argv[11] = "USER"; status = wrap_mr_query("update_host", 15, argv, NULL, NULL); if (owner->type != M_ANY || status != MR_USER) break; case M_LIST: argv[11] = "LIST"; status = wrap_mr_query("update_host", 15, argv, NULL, NULL); break; case M_KERBEROS: argv[11] = "KERBEROS"; status = wrap_mr_query("update_host", 15, argv, NULL, NULL); break; case M_NONE: argv[11] = "NONE"; status = wrap_mr_query("update_host", 15, argv, NULL, NULL); break; } } else status = wrap_mr_query("update_host", 15, argv, NULL, NULL); if (status) com_err(whoami, status, "while updating host."); else if (newname) hostname = newname; } /* create aliases if necessary */ if (alias_add_queue) { struct string_list *q = alias_add_queue; while(q) { char *alias = q->string; char *args[2]; args[0] = canonicalize_hostname(strdup(alias)); args[1] = canonicalize_hostname(strdup(hostname)); status = wrap_mr_query("add_hostalias", 2, args, NULL, NULL); if (status) { com_err(whoami, status, "while adding host alias"); exit(1); } q = q->next; } } /* delete aliases if necessary */ if (alias_remove_queue) { struct string_list *q = alias_remove_queue; while(q) { char *alias = q->string; char *args[2]; args[0] = canonicalize_hostname(strdup(alias)); args[1] = canonicalize_hostname(strdup(hostname)); status = wrap_mr_query("delete_hostalias", 2, args, NULL, NULL); if (status) { com_err(whoami, status, "while deleting host alias"); exit(1); } q = q->next; } } /* create cluster mappings */ if (map_add_queue) { struct string_list *q = map_add_queue; while(q) { char *clustername = q->string; char *args[2]; args[0] = canonicalize_hostname(strdup(hostname)); args[1] = clustername; status = wrap_mr_query("add_machine_to_cluster", 2, args, NULL, NULL); if (status) { com_err(whoami, status, "while adding cluster mapping"); exit(1); } q = q->next; } } /* delete cluster mappings */ if (map_remove_queue) { struct string_list *q = map_remove_queue; while(q) { char *clustername = q->string; char *args[2]; args[0] = canonicalize_hostname(strdup(hostname)); args[1] = clustername; status = wrap_mr_query("delete_machine_from_cluster", 2, args, NULL, NULL); if (status) { com_err(whoami, status, "while deleting cluster mapping"); exit(1); } q = q->next; } } /* display list info if requested to */ if (info_flag) { struct mqelem *elem = NULL; char *args[5]; char *argv[30]; args[0] = canonicalize_hostname(strdup(hostname)); args[1] = args[2] = args[3] = "*"; status = wrap_mr_query("get_host", 4, args, store_host_info, argv); if (status) { com_err(whoami, status, "while getting host information"); exit(1); } show_host_info(argv); } /* list cluster mappings if needed */ if (list_map_flag) { char *args[3]; args[0] = canonicalize_hostname(strdup(hostname)); args[1] = "*"; status = wrap_mr_query("get_machine_to_cluster_map", 2, args, show_machine_in_cluster, NULL); if (status) if (status != MR_NO_MATCH) { com_err(whoami, status, "while getting cluster mappings"); exit(1); } } if (delete_flag) { char *argv[1]; argv[0] = canonicalize_hostname(strdup(hostname)); status = wrap_mr_query("delete_host", 1, argv, NULL, NULL); if (status) { com_err(whoami, status, "while deleting host"); exit(1); } } /* We're done! */ mr_disconnect(); exit(success ? 0 : 1); } void usage(char **argv) { fprintf(stderr, "Usage: %s hostname [options]\n", argv[0]); fprintf(stderr, "Options are\n"); fprintf(stderr, " %-39s%-39s\n", "-C | -create", "-O | -owner owner"); fprintf(stderr, " %-39s%-39s\n", "-D | -delete", "-S | -status status"); fprintf(stderr, " %-39s%-39s\n", "-R | -rename newname", "-V | -vendor vendor"); fprintf(stderr, " %-39s%-39s\n", "-a | -addalias alias", "-M | -model model"); fprintf(stderr, " %-39s%-39s\n", "-d | -deletealias alias", "-L | -location location"); fprintf(stderr, " %-39s%-39s\n", "-i | -info", "-o | -os os"); fprintf(stderr, " %-39s%-39s\n", "-oc | -opcmt op_cmt", "-c | -contact contact"); fprintf(stderr, " %-39s%-39s\n", "-ac | -admcmt adm_cmt", "-A | -address address"); fprintf(stderr, " %-39s%-39s\n", "-am | -addmap cluster", "-N | -network network"); fprintf(stderr, " %-39s%-39s\n", "-dm | -deletemap cluster", "-lm | -listmap"); fprintf(stderr, " %-39s%-39s\n", "-db | -database host[:port]", "-n | -noauth"); fprintf(stderr, " %-39s%-39s\n", "-v | -verbose", ""); exit(1); } /* Show alias information */ static int show_has_aliases; int show_alias_info(int argc, char **argv, void *hint) { if(!show_has_aliases++) printf("Aliases: %s", argv[0]); else printf(", %s", argv[0]); return MR_CONT; } static char *states[] = { "Reserved (0)", "Active (1)", "None (2)", "Deleted (3)" }; static char *MacState(int state) { static char buf[BUFSIZ]; if (state < 0 || state > 3) { sprintf(buf, "Unknown (%d)", state); return buf; } return states[state]; } /* Retrieve information about a host */ int store_host_info(int argc, char **argv, void *hint) { int i; char **nargv = hint; for(i=0; iname = ++p; if (!strcasecmp("user", s)) m->type = M_USER; else if (!strcasecmp("list", s)) m->type = M_LIST; else if (!strcasecmp("string", s)) m->type = M_STRING; else if (!strcasecmp("kerberos", s)) m->type = M_KERBEROS; else if (!strcasecmp("none", s)) m->type = M_NONE; else { m->type = M_ANY; *(--p) = ':'; m->name = s; } m->name = strdup(m->name); } else { m->name = strdup(s); m->type = strcasecmp(s, "none") ? M_ANY : M_NONE; } return m; } struct string_list *add_to_string_list(struct string_list *old_list, char *s) { struct string_list *new_list; new_list = (struct string_list *)malloc(sizeof(struct string_list *)); new_list->next = old_list; new_list->string = s; return new_list; } int wrap_mr_query(char *handle, int argc, char **argv, int (*callback)(int, char **, void *), void *callarg) { if (verbose) print_query(handle, argc, argv); return mr_query(handle, argc, argv, callback, callarg); } void print_query(char *query_name, int argc, char **argv) { int cnt; printf("qy %s", query_name); for(cnt=0; cnt", argv[cnt]); printf("\n"); }