]> andersk Git - moira.git/commitdiff
add bella, a command line client for container manipulation, and associated man page...
authorzacheiss <zacheiss>
Thu, 23 Jan 2003 19:41:32 +0000 (19:41 +0000)
committerzacheiss <zacheiss>
Thu, 23 Jan 2003 19:41:32 +0000 (19:41 +0000)
clients/Makefile.in
clients/bella/Makefile.in [new file with mode: 0644]
clients/bella/bella.c [new file with mode: 0644]
configure
configure.in
man/Makefile.in
man/bella.1 [new file with mode: 0644]

index cbc3d1ca7da9f726d8503f3b3a5b7556838a95af..1f157464531d1910b877a0395983ebf699463980 100644 (file)
@@ -7,7 +7,7 @@ srcdir=@srcdir@
 VPATH=@srcdir@
 
 CURSES_SUBDIRS=mailmaint
-SUBDIRS=lib addusr blanche chfn chpobox chsh moira mrcheck mrtest stanley stella @CURSES_SUBDIRS@
+SUBDIRS=lib addusr bella blanche chfn chpobox chsh moira mrcheck mrtest stanley stella @CURSES_SUBDIRS@
 
 all:
        @for d in $(SUBDIRS); do (echo "### Making $@ in clients/$$d"; cd $$d; $(MAKE) $@) || exit 1; done
diff --git a/clients/bella/Makefile.in b/clients/bella/Makefile.in
new file mode 100644 (file)
index 0000000..badacdf
--- /dev/null
@@ -0,0 +1,46 @@
+# $Id$
+
+SHELL=/bin/sh
+@SET_MAKE@
+
+CC=@CC@
+CPPFLAGS=@CPPFLAGS@
+CFLAGS=@CFLAGS@
+DEFS=@DEFS@
+ALL_CFLAGS=$(CPPFLAGS) $(CFLAGS) $(DEFS)
+LDFLAGS=@LDFLAGS@
+LIBS=../lib/libmrclient.a @LIBS@
+MR_LIBDEP=@MR_LIBDEP@
+INSTALL=@INSTALL@
+INSTALL_PROGRAM=@INSTALL_PROGRAM@
+
+srcdir=@srcdir@
+VPATH=@srcdir@
+SRCTOP=@top_srcdir@
+BUILDTOP=../..
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+bindir=@bindir@
+
+OBJS=bella.o
+
+TARGET=bella
+
+.c.o:
+       $(CC) -c $(ALL_CFLAGS) $<
+
+all: $(TARGET)
+
+clean:
+       rm -f $(OBJS) $(TARGET)
+
+cleandir distclean: clean
+       rm -f Makefile
+
+depend:
+
+install: all
+       $(INSTALL_PROGRAM) bella $(bindir)
+
+$(TARGET): $(OBJS) ../lib/libmrclient.a $(MR_LIBDEP)
+       $(CC) -o $@ $(LDFLAGS) $(OBJS) $(LIBS)
diff --git a/clients/bella/bella.c b/clients/bella/bella.c
new file mode 100644 (file)
index 0000000..f6ab9e5
--- /dev/null
@@ -0,0 +1,742 @@
+/*
+ * Command line oriented Moira containers tool.
+ *
+ * Garry Zacheiss <zacheiss@mit.edu>, January 2003
+ *
+ * Inspired by blanche
+ *
+ * Copyright (C) 2002 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
+ */
+
+#include <mit-copyright.h>
+#include <moira.h>
+#include <moira_site.h>
+#include <mrclient.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+RCSID("$Id$");
+
+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;
+};
+
+#define M_ANY          0
+#define M_USER         1
+#define M_LIST         2
+#define M_KERBEROS     3
+#define M_NONE         4
+
+char *typename[] = { "ANY", "USER", "LIST", "KERBEROS", "NONE" };
+
+/* 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_subcon_flag;
+int list_mach_flag, update_mach_flag, verbose, noauth, unformatted_flag;
+int recurse_flag;
+
+struct string_list *container_add_queue, *container_remove_queue;
+
+char *containername, *whoami;
+
+char *newname, *desc, *location, *contact;
+int public;
+struct owner_type *owner, *memacl;
+
+void usage(char **argv);
+int store_container_info(int argc, char **argv, void *hint);
+void show_container_info(char **argv);
+int show_container_list(int argc, char **argv, void *hint);
+void show_container_info_unformatted(char **argv);
+int show_container_list_unformatted(int argc, char **argv, void *hint);
+int show_machine_in_container(int argc, char **argv, void *hint);
+int show_subcontainers_of_container(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;
+
+  /* clear all flags & lists */
+  info_flag = update_flag = create_flag = delete_flag = list_subcon_flag = 0;
+  list_mach_flag = update_mach_flag = verbose = noauth = unformatted_flag = 0;
+  recurse_flag = 0;
+  public = -1;
+  container_add_queue = container_remove_queue = NULL;
+  newname = desc = location = contact = NULL;
+  owner = memacl = NULL;
+  whoami = argv[0];
+
+  success = 1;
+
+  /* parse args */
+  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("d", "desc")) {
+           if (arg - argv < argc - 1) {
+             arg++;
+             update_flag++;
+             desc = *arg;
+           } else
+             usage(argv);
+         }
+         else if (argis("L", "location")) {
+           if (arg - argv < argc - 1) {
+             arg++;
+             update_flag++;
+             location = *arg;
+           } else
+             usage(argv);
+         }
+         else if (argis("c", "contact")) {
+           if (arg - argv < argc - 1) {
+             arg++;
+             update_flag++;
+             contact = *arg;
+           } else
+             usage(argv);
+         }
+         else if (argis("P", "public"))
+           {
+             update_flag++;
+             public = 1;
+           }
+         else if (argis("NP", "private"))
+           {
+             update_flag++;
+             public = 0;
+           }
+         else if (argis("O", "owner")) {
+           if (arg - argv < argc - 1) {
+             arg++;
+             update_flag++;
+             owner = parse_member(*arg);
+           } else
+             usage(argv);
+         }
+         else if (argis("MA", "memacl")) {
+           if (arg - argv < argc - 1) {
+             arg++;
+             update_flag++;
+             memacl = parse_member(*arg);
+           } else
+             usage(argv);
+         }
+         else if (argis("ls", "listsub"))
+           list_subcon_flag++;
+         else if (argis("lm", "listmach"))
+           list_mach_flag++;
+         else if (argis("am", "addmach")) {
+           if (arg - argv < argc - 1) {
+             arg++;
+             container_add_queue = 
+               add_to_string_list(container_add_queue, *arg);
+           } else
+             usage(argv);
+           update_mach_flag++;
+         }
+         else if (argis("dm", "deletemach")) {
+           if (arg - argv < argc - 1) {
+             arg++;
+             container_remove_queue =
+               add_to_string_list(container_remove_queue, *arg);
+           } else
+             usage(argv);
+           update_mach_flag++;
+         }
+         else if (argis("r", "recursive"))
+           recurse_flag++;
+         else if (argis("u", "unformatted"))
+           unformatted_flag++;
+         else if (argis("n", "noauth"))
+           noauth++;
+         else if (argis("v", "verbose"))
+           verbose++;
+         else if (argis("db", "database"))
+           {
+             if (arg - argv < argc - 1)
+               {
+                 ++arg;
+                 server = *arg;
+               }
+             else
+               usage(argv);
+           }
+         else
+           usage(argv);
+       }
+      else if (containername == NULL)
+       containername = *arg;
+      else
+       usage(argv);
+    }
+  if (containername == NULL)
+    usage(argv);
+
+  /* default to info_flag if nothing else was specified */
+  if(!(info_flag        || update_flag    || create_flag || delete_flag || \
+       list_subcon_flag || list_mach_flag || update_mach_flag)) {
+    info_flag++;
+  }
+
+  /* fire up Moira */
+  status = mrcl_connect(server, "bella", 9, !noauth);
+  if (status == MRCL_AUTH_ERROR)
+    {
+      com_err(whoami, 0, "Try the -noauth flag if you don't "
+             "need authentication.");
+    }
+  if (status)
+    exit(2);
+
+  /* create if needed */
+  if (create_flag)
+    {
+      char *argv[15];
+      int cnt;
+
+      for (cnt = 0; cnt < 11; cnt ++) {
+       argv[cnt] = "";
+      }
+
+      argv[CON_NAME] = containername;
+      argv[CON_PUBLIC] = (public == 1) ? "1" : "0";
+      argv[CON_DESCRIPT] = desc ? desc : "none";
+      if (location)
+       argv[CON_LOCATION] = location;
+      if (contact)
+       argv[CON_CONTACT] = contact;
+
+      if (memacl)
+       {
+         if (memacl->type == M_ANY)
+           {
+             status = wrap_mr_query("get_user_account_by_login", 1,
+                                    &memacl->name, NULL, NULL);
+             if (status == MR_NO_MATCH)
+               memacl->type = M_LIST;
+             else
+               memacl->type = M_USER;
+           }
+         argv[CON_MEMACE_TYPE] = typename[memacl->type];
+         argv[CON_MEMACE_NAME] = memacl->name;
+         if (memacl->type == M_KERBEROS)
+           {
+             status = mrcl_validate_kerberos_member(argv[CON_MEMACE_NAME],
+                                                    &argv[CON_MEMACE_NAME]);
+             if (mrcl_get_message())
+               mrcl_com_err(whoami);
+             if (status == MRCL_REJECT)
+               exit(1);
+           }
+       }
+      else
+       argv[CON_MEMACE_TYPE] = argv[CON_MEMACE_NAME] = "NONE";
+
+      if (owner)
+       {
+         argv[CON_OWNER_NAME] = owner->name;
+         switch (owner->type)
+           {
+           case M_ANY:
+           case M_USER:
+             argv[CON_OWNER_TYPE] = "USER";
+             status = wrap_mr_query("add_container", 9, argv, NULL, NULL);
+             if (owner->type != M_ANY || status != MR_USER)
+               break;
+
+           case M_LIST:
+             argv[CON_OWNER_TYPE] = "LIST";
+             status = wrap_mr_query("add_container", 9, argv, NULL, NULL);
+             break;
+
+           case M_KERBEROS:
+             argv[CON_OWNER_TYPE] = "KERBEROS";
+             status = mrcl_validate_kerberos_member(argv[CON_OWNER_TYPE],
+                                                    &argv[CON_OWNER_TYPE]);
+             if (mrcl_get_message())
+               mrcl_com_err(whoami);
+             if (status == MRCL_REJECT)
+               exit(1);
+             status = wrap_mr_query("add_container", 9, argv, NULL, NULL);
+             break;
+           case M_NONE:
+             argv[CON_OWNER_TYPE] = argv[CON_OWNER_NAME] = "NONE";
+             status = wrap_mr_query("add_containr", 9, argv, NULL, NULL);
+             break;
+           }
+       }
+      else
+       {
+         argv[CON_OWNER_TYPE] = argv[CON_OWNER_NAME] = "NONE";
+         status = wrap_mr_query("add_container", 9, argv, NULL, NULL);
+       }
+
+      if (status)
+       {
+         com_err(whoami, status, "while creating container.");
+         exit(1);
+       }
+    }
+  else if (update_flag)
+    {
+      char *old_argv[15];
+      char *argv[15];
+      char *args[2];
+
+      args[0] = containername;
+
+      status = wrap_mr_query("get_container", 1, args, store_container_info,
+                            old_argv);
+      if (status)
+       {
+         com_err(whoami, status, "while getting container 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[8];
+
+      argv[CON_NAME] = containername;
+      if (newname)
+       argv[CON_NAME + 1] = newname;
+      argv[CON_PUBLIC + 1] = (public == 1) ? "1" : "0";
+      if (desc)
+       argv[CON_DESCRIPT + 1] = desc;
+      if (location)
+       argv[CON_LOCATION + 1] = location;
+      if (contact)
+       argv[CON_CONTACT + 1] = contact;
+
+      if (memacl)
+       {
+         if (memacl->type == M_ANY)
+           {
+             status = wrap_mr_query("get_user_account_by_login", 1,
+                                    &memacl->name, NULL, NULL);
+             if (status == MR_NO_MATCH)
+               memacl->type = M_LIST;
+             else
+               memacl->type = M_USER;
+           }
+         argv[CON_MEMACE_TYPE + 1] = typename[memacl->type];
+         argv[CON_MEMACE_NAME + 1] = memacl->name;
+         if (memacl->type == M_KERBEROS)
+           {
+             status = mrcl_validate_kerberos_member(argv[CON_MEMACE_NAME + 1],
+                                                    &argv[CON_MEMACE_NAME + 1]);
+             if (mrcl_get_message())
+               mrcl_com_err(whoami);
+             if (status == MRCL_REJECT)
+               exit(1);
+           }
+       }
+
+      if (owner)
+       {
+         argv[CON_OWNER_NAME + 1] = owner->name;
+         switch (owner->type)
+           {
+           case M_ANY:
+           case M_USER:
+             argv[CON_OWNER_TYPE + 1] = "USER";
+             status = wrap_mr_query("update_container", 10, argv, NULL, NULL);
+             if (owner->type != M_ANY || status != MR_USER)
+               break;
+
+           case M_LIST:
+             argv[CON_OWNER_TYPE + 1] = "LIST";
+             status = wrap_mr_query("update_container", 10, argv, NULL, NULL);
+             break;
+
+           case M_KERBEROS:
+             argv[CON_OWNER_TYPE + 1] = "KERBEROS";
+             status = mrcl_validate_kerberos_member(argv[CON_OWNER_NAME + 1],
+                                                    &argv[CON_OWNER_NAME + 1]);
+             if (mrcl_get_message())
+               mrcl_com_err(whoami);
+             if (status == MRCL_REJECT)
+               exit(1);
+             status = wrap_mr_query("update_container", 10, argv, NULL, NULL);
+             break;
+             
+           case M_NONE:
+             argv[CON_OWNER_TYPE + 1] = argv[CON_OWNER_NAME + 1] = "NONE";
+             status = wrap_mr_query("update_container", 10, argv, NULL, NULL);
+             break;
+           }
+       }
+      else
+       status = wrap_mr_query("update_container", 10, argv, NULL, NULL);
+
+      if (status)
+       {
+         com_err(whoami, status, "while updating container.");
+         success = 0;
+       }
+      else if (newname)
+       containername = newname;
+    }
+
+  /* add machines to container */
+  if (container_add_queue) {
+    struct string_list *q = container_add_queue;
+
+    while (q) {
+      char *args[2];
+
+      args[0] = canonicalize_hostname(strdup(q->string));
+      args[1] = containername;
+      status = wrap_mr_query("add_machine_to_container", 2, args, NULL, NULL);
+      if (status)
+       {
+         com_err(whoami, status, "while adding machine to container.");
+         exit(1);
+       }
+
+      q = q->next;
+    }
+  }
+
+  /* delete machines from container */
+  if (container_remove_queue) {
+    struct string_list *q = container_remove_queue;
+
+    while (q) {
+      char *args[2];
+
+      args[0] = canonicalize_hostname(strdup(q->string));
+      args[1] = containername;
+      status = wrap_mr_query("delete_machine_from_container", 2, args, NULL,
+                            NULL);
+      if (status)
+       {
+         com_err(whoami, status, "while removing machine from container.");
+         exit(1);
+       }
+
+      q = q->next;
+    }
+  }
+
+  if (info_flag)
+    {
+      char *args[2];
+      char *argv[20];
+
+      args[0] = containername;
+      status = wrap_mr_query("get_container", 1, args, store_container_info,
+                            argv);
+      if (status)
+       {
+         com_err(whoami, status, "while getting container information.");
+         exit(1);
+       }
+
+      if (unformatted_flag)
+       show_container_info_unformatted(argv);
+      else
+       show_container_info(argv);
+    }
+
+  if (delete_flag)
+    {
+      char *args[2];
+
+      args[0] = containername;
+      status = wrap_mr_query("delete_container", 1, args, NULL, NULL);
+      if (status)
+       {
+         com_err(whoami, status, "while deleting container.");
+         exit(1);
+       }
+    }
+
+  if (list_mach_flag)
+    {
+      char *args[3];
+
+      args[0] = containername;
+      args[1] = (recurse_flag == 1) ? "1" : "0";
+      status = wrap_mr_query("get_machines_of_container", 2, args,
+                            show_machine_in_container, NULL);
+      if (status)
+       {
+         com_err(whoami, status, "while getting machines of container.");
+         exit(1);
+       }
+    }
+
+  if (list_subcon_flag)
+    {
+      char *args[3];
+
+      args[0] = containername;
+      args[1] = (recurse_flag == 1) ? "1" : "0";
+      status = wrap_mr_query("get_subcontainers_of_container", 2, args,
+                            show_subcontainers_of_container, NULL);
+      if (status)
+       {
+         com_err(whoami, status, "while getting subcontainers of container.");
+         exit(1);
+       }
+    }
+
+  mr_disconnect();
+  exit(success ? 0 : 1);
+}
+
+void usage(char **argv)
+{
+#define USAGE_OPTIONS_FORMAT "  %-39s%s\n"
+  fprintf(stderr, "Usage: %s containername [options]\n", argv[0]);
+  fprintf(stderr, "Options are\n");
+  fprintf(stderr, USAGE_OPTIONS_FORMAT, "-C   | -create",
+         "-O   | -owner owner");
+  fprintf(stderr, USAGE_OPTIONS_FORMAT, "-D   | -delete",
+         "-d   | -desc description");
+  fprintf(stderr, USAGE_OPTIONS_FORMAT, "-R   | -rename newname",
+         "-L   | -location location");
+  fprintf(stderr, USAGE_OPTIONS_FORMAT, "-i   | -info",
+         "-c   | -contact contact");
+  fprintf(stderr, USAGE_OPTIONS_FORMAT, "-P   | -public",
+         "-NP  | -private");
+  fprintf(stderr, USAGE_OPTIONS_FORMAT, "-O   | -owner owner",
+         "-MA  | -memacl membership_acl");
+  fprintf(stderr, USAGE_OPTIONS_FORMAT, "-ls  | -listsub",
+         "-lm  | -listmach");
+  fprintf(stderr, USAGE_OPTIONS_FORMAT, "-am  | -addmach hostname",
+         "-dm  | -deletemach hostname");
+  fprintf(stderr, USAGE_OPTIONS_FORMAT, "-r   | -recursive",
+         "-u   | -unformatted");
+  fprintf(stderr, USAGE_OPTIONS_FORMAT, "-v   | -verbose",
+         "-n   | -noauth");
+  fprintf(stderr, "  %-39s\n" , "-db  | -database host[:port]");
+  exit(1);
+}
+
+/* Retrieve information about a container */
+int store_container_info(int argc, char **argv, void *hint)
+{
+  int i;
+  char **nargv = hint;
+
+  for(i = 0; i < argc; i++)
+    nargv[i] = strdup(argv[i]);
+
+  return MR_CONT;
+}
+
+void show_container_info(char **argv)
+{
+  char tbuf[256];
+  char *args[2];
+  struct mqelem *elem = NULL;
+  int status;
+
+  printf("Container:      %-16s    Public:      %s\n", argv[CON_NAME], 
+        argv[CON_PUBLIC]);
+  args[0] = argv[CON_NAME];
+  status = wrap_mr_query("get_container_list", 1, args, show_container_list,
+                        &elem);
+  if (status && status != MR_NO_MATCH)
+    com_err(whoami, status, "while getting container list.");
+  printf("Description:    %-16s\n", argv[CON_DESCRIPT]);
+  printf("Location:       %-16s    Contact:     %s\n", argv[CON_LOCATION],
+        argv[CON_CONTACT]);
+  sprintf(tbuf, "%s %s", argv[CON_OWNER_TYPE],
+         strcmp(argv[CON_OWNER_TYPE], "NONE") ? argv[CON_OWNER_NAME] : "");
+  printf("Owner:          %-16s\n", tbuf);
+  sprintf(tbuf, "%s %s", argv[CON_MEMACE_TYPE],
+         strcmp(argv[CON_MEMACE_TYPE], "NONE") ? argv[CON_MEMACE_NAME] : "");
+  printf("Membership ACL: %-16s\n", tbuf);
+  printf("\n");
+  printf("Last mod by %s at %s with %s.\n", argv[CON_MODBY], argv[CON_MODTIME],
+        argv[CON_MODWITH]);
+}
+
+int show_container_list(int argc, char **argv, void *hint)
+{
+  printf("Container's associated list is: LIST %s\n", argv[1]);
+
+  return MR_CONT;
+}
+
+void show_container_info_unformatted(char **argv)
+{
+  char *args[2];
+  struct mqelem *elem = NULL;
+  int status;
+
+  printf("Container:       %s\n", argv[CON_NAME]);
+  args[0] = argv[CON_NAME];
+  status = wrap_mr_query("get_container_list", 1, args,
+                        show_container_list_unformatted, &elem);
+  if (status && status != MR_NO_MATCH)
+    com_err(whoami, status, "while getting container list.");
+  else
+    printf("\n");
+  printf("Public:          %s\n", argv[CON_PUBLIC]);
+  printf("Description:     %s\n", argv[CON_DESCRIPT]);
+  printf("Location:        %s\n", argv[CON_LOCATION]);
+  printf("Contact:         %s\n", argv[CON_CONTACT]);
+  printf("Owner Type:      %s\n", argv[CON_OWNER_TYPE]);
+  printf("Owner:           %s\n", argv[CON_OWNER_NAME]);
+  printf("Memacl Type:     %s\n", argv[CON_MEMACE_TYPE]);
+  printf("Memacl:          %s\n", argv[CON_MEMACE_NAME]);
+  printf("Last mod by:     %s\n", argv[CON_MODBY]);
+  printf("Last mod on:     %s\n", argv[CON_MODTIME]);
+  printf("Last mod with:   %s\n", argv[CON_MODWITH]);
+}
+
+int show_container_list_unformatted(int argc, char **argv, void *hint)
+{
+  printf("Associated list: %s", argv[1]);
+
+  return MR_CONT;
+}
+
+int show_machine_in_container(int argc, char **argv, void *hint)
+{
+  printf("Machine: %-30s Container: %-25s\n", argv[0], argv[1]); 
+
+  return MR_CONT;
+}
+
+int show_subcontainers_of_container(int argc, char **argv, void *hint)
+{
+  printf("Container: %-25s\n", argv[0]);
+
+  return MR_CONT;
+}
+
+/* Parse a line of input, fetching a member.  NULL is returned if a member
+ * is not found.  ';' is a comment character.
+ */
+
+struct owner_type *parse_member(char *s)
+{
+  struct owner_type *m;
+  char *p, *lastchar;
+
+  while (*s && isspace(*s))
+    s++;
+  lastchar = p = s;
+  while (*p && *p != '\n' && *p != ';')
+    {
+      if (isprint(*p) && !isspace(*p))
+       lastchar = p++;
+      else
+       p++;
+    }
+  lastchar++;
+  *lastchar = '\0';
+  if (p == s || strlen(s) == 0)
+    return NULL;
+
+  if (!(m = malloc(sizeof(struct owner_type))))
+    return NULL;
+
+  if ((p = strchr(s, ':')))
+    {
+      *p = '\0';
+      m->name = ++p;
+      if (!strcasecmp("user", s))
+       m->type = M_USER;
+      else if (!strcasecmp("list", s))
+       m->type = M_LIST;
+      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<argc; cnt++)
+    printf(" <%s>", argv[cnt]);
+  printf("\n");
+}
index f3799133aa7a2dd49c2d0bfb951d4b42506baea8..30d029b74ba092d372f1a08bc0a8c79481d6a97b 100755 (executable)
--- a/configure
+++ b/configure
@@ -2965,14 +2965,14 @@ ac_given_INSTALL="$INSTALL"
 
 trap 'rm -fr `echo "Makefile lib/Makefile include/Makefile clients/Makefile \
          clients/lib/Makefile clients/addusr/Makefile \
-         clients/blanche/Makefile clients/chfn/Makefile \
-         clients/chpobox/Makefile clients/chsh/Makefile \
-         clients/mailmaint/Makefile clients/moira/Makefile \
-         clients/mrcheck/Makefile clients/mrtest/Makefile \
-         clients/stanley/Makefile clients/stella/Makefile \
-          update/Makefile man/Makefile $WEBMOIRA_OUTPUT_FILES \
-         $SERVER_OUTPUT_FILES $WINAD_OUTPUT_FILES $AFS_OUTPUT_FILES \
-         $RSAREF_OUTPUT_FILES" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+         clients/bella/Makefile clients/blanche/Makefile \
+         clients/chfn/Makefile clients/chpobox/Makefile \
+         clients/chsh/Makefile clients/mailmaint/Makefile \
+         clients/moira/Makefile clients/mrcheck/Makefile \
+         clients/mrtest/Makefile clients/stanley/Makefile \
+         clients/stella/Makefile update/Makefile man/Makefile \
+         $WEBMOIRA_OUTPUT_FILES $SERVER_OUTPUT_FILES $WINAD_OUTPUT_FILES \
+         $AFS_OUTPUT_FILES $RSAREF_OUTPUT_FILES" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
 EOF
 cat >> $CONFIG_STATUS <<EOF
 
@@ -3095,14 +3095,14 @@ cat >> $CONFIG_STATUS <<EOF
 
 CONFIG_FILES=\${CONFIG_FILES-"Makefile lib/Makefile include/Makefile clients/Makefile \
          clients/lib/Makefile clients/addusr/Makefile \
-         clients/blanche/Makefile clients/chfn/Makefile \
-         clients/chpobox/Makefile clients/chsh/Makefile \
-         clients/mailmaint/Makefile clients/moira/Makefile \
-         clients/mrcheck/Makefile clients/mrtest/Makefile \
-         clients/stanley/Makefile clients/stella/Makefile \
-          update/Makefile man/Makefile $WEBMOIRA_OUTPUT_FILES \
-         $SERVER_OUTPUT_FILES $WINAD_OUTPUT_FILES $AFS_OUTPUT_FILES \
-         $RSAREF_OUTPUT_FILES"}
+         clients/bella/Makefile clients/blanche/Makefile \
+         clients/chfn/Makefile clients/chpobox/Makefile \
+         clients/chsh/Makefile clients/mailmaint/Makefile \
+         clients/moira/Makefile clients/mrcheck/Makefile \
+         clients/mrtest/Makefile clients/stanley/Makefile \
+         clients/stella/Makefile update/Makefile man/Makefile \
+         $WEBMOIRA_OUTPUT_FILES $SERVER_OUTPUT_FILES $WINAD_OUTPUT_FILES \
+         $AFS_OUTPUT_FILES $RSAREF_OUTPUT_FILES"}
 EOF
 cat >> $CONFIG_STATUS <<\EOF
 for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
index 0a44fafb3a074f5f9859895992a368278931a8f2..d478628992cc3bd183ee26f3408de38eacf3563c 100755 (executable)
@@ -453,11 +453,11 @@ AC_SUBST(MR_LIBDEP)
 
 AC_OUTPUT(Makefile lib/Makefile include/Makefile clients/Makefile \
          clients/lib/Makefile clients/addusr/Makefile \
-         clients/blanche/Makefile clients/chfn/Makefile \
-         clients/chpobox/Makefile clients/chsh/Makefile \
-         clients/mailmaint/Makefile clients/moira/Makefile \
-         clients/mrcheck/Makefile clients/mrtest/Makefile \
-         clients/stanley/Makefile clients/stella/Makefile \
-          update/Makefile man/Makefile $WEBMOIRA_OUTPUT_FILES \
-         $SERVER_OUTPUT_FILES $WINAD_OUTPUT_FILES $AFS_OUTPUT_FILES \
-         $RSAREF_OUTPUT_FILES)
+         clients/bella/Makefile clients/blanche/Makefile \
+         clients/chfn/Makefile clients/chpobox/Makefile \
+         clients/chsh/Makefile clients/mailmaint/Makefile \
+         clients/moira/Makefile clients/mrcheck/Makefile \
+         clients/mrtest/Makefile clients/stanley/Makefile \
+         clients/stella/Makefile update/Makefile man/Makefile \
+         $WEBMOIRA_OUTPUT_FILES $SERVER_OUTPUT_FILES $WINAD_OUTPUT_FILES \
+         $AFS_OUTPUT_FILES $RSAREF_OUTPUT_FILES)
index 11773e7c536754b5b4d7af5795199bc142832c3f..fbd5ec9553af89ed9bfe7c3c8ac22c288094d075 100644 (file)
@@ -11,7 +11,7 @@ VPATH=@srcdir@
 prefix=@prefix@
 mandir=@mandir@
 
-MAN1=  blanche.1 chfn.1 chpobox.1 chsh.1 dcmmaint.1 listmaint.1 \
+MAN1=  bella.1 blanche.1 chfn.1 chpobox.1 chsh.1 dcmmaint.1 listmaint.1 \
        mailmaint.1 moira.1 mrcheck.1 stanley.1 stella.1 usermaint.1 userreg.1
 MAN3=  canonicalize_hostname.3 format_filesys_type.3 moira.3 \
        mr_access.3 mr_auth.3 mr_connect.3 mr_disconnect.3 \
diff --git a/man/bella.1 b/man/bella.1
new file mode 100644 (file)
index 0000000..bc43821
--- /dev/null
@@ -0,0 +1,113 @@
+.TH BELLA 1 "22 Jan 2003" "MIT Athena"
+\" RCSID: $Header$
+.SH NAME
+bella \- examine and modify informtion about containers in Moira
+.SH SYNOPSIS
+.B bella containername [options]
+.SH DESCRIPTION
+.I Bella
+is a tool for updating information about containers in Moira.  It
+supports all container modification commands and options to list, add,
+and remove machines to and from containers.
+
+If no options are specified, it will assume \fI-info\fR, which will
+result in all information about the specified user being displayed.
+
+.SH OPTIONS
+
+.IP \fB-info\ \fRor\ \fB-i\fR
+Display information about a container. This is the default mode if no
+other options are given. The output is similar to that of moira.
+
+.IP \fB-desc\ \fIdescription\ \fRor\ \fB-d\ \fIdescription\fR
+Update the description field for the specified container to \fIdescription\fR.
+.IP \fB-location\ \fIlocation\ \fRor\ \fB-l\ \fIlocation\fR
+Update the location field for the specified container to \fIlocation\fR.
+.IP \fB-contact\ \fIcontact\ \fRor\ \fB-c\ \fIcontact\fR
+Update the contact field for the specified container to\fIcontainct\fR.
+
+.IP \fB-owner\ \fIowner\ \fRor\ \fB-O\ \fIowner\fR
+Set the owner of the specified container to \fIowner\fR.
+
+You may specify an owner explicitly, as user:username, list:listname, or
+kerberos:principal_name; or the type may be left off if the owner name
+is non ambiguous.
+.B Bella
+will try first as a user, and if that fails will try the member as a
+list.
+
+.IP \fB-memacl\ \fImembership_acl\ \fRor\ \fB-MA\ \fImembership_acl\fR
+Set the mebership acl of the container; members of this acl will be
+allowed to add and remove members of the container, but not update any
+other characteristics. The membership acl is specified like a list
+member, except that it can never be a string.  To return a list to
+having default membership access control conditions, set the membership
+acl to "NONE".
+
+.IP \fB-public\ \fR(\fB-P\fR)\ \fRor\ \fB-private\ \fR(\fB-NP\fR)
+Make the container public or private. (Anyone can add a machine to a
+public container.)
+
+.IP \fB-unformatted\ \fRor\ \fB-u\fR
+Display container information with each field on a seperate line, in the
+form "fieldname: value".
+.IP \fB-verbose\ \fRor\ \fB-v\fR
+Give more information.  With this flag, stanley will display the
+queries it is making to the moira server.
+.IP \fB-noauth\ \fRor\ \fB-n\fR
+Do not attempt to perform Kerberos authentication with the Moira server.
+Most lookup operations should be still possible without tickets.
+.IP \fB-database\ \fIhost:port\ \fRor\ \fB-db\ \fIhost:port\fR
+Use the specified host and port to contact the Moira database instead of
+the default server.  Both may be symbolic names or numbers.  If the
+port is left off, the default Moira server port will be assumed.  The
+database chosen will be the one specified on the command line, specified
+in the MOIRASERVER environment variable, the hesiod "moira" sloc entry,
+or the compiled in default, in that order or preference.
+
+.IP \fB-create\ \fRor\ \fB-C\fR
+This will create the specified container, with information provided by
+other options.
+.IP \fB-delete\ \fRor\ \fB-D\fR
+This will delete the specified container, if the container contains no
+machines.
+.IP \fB-rename\ \fInewname\ \fRor\ \fB-R\ \fInewname\fR
+This will rename the specified container to \fInewname\fR.
+
+.IP \fB-recursive\ \fRor\ \fB-r\fR
+When specified along with the
+\fB-listmach\fR
+or
+\fB-listsub\fR
+options, will provide a recursive listing.
+
+.IP \fB-listmach\ \fRor\ \fB-lm\fR
+This will list the machines that are members of the container. Use the
+\fB-r\fR
+flag for a recursive listing.
+.IP \fB-addmach\ \fIhostname\ \fRor\ \fB-am\ \fIhostname\fR
+This will add \fIhostname\fR to the specified container.
+.IP \fB-deletemach\ \fIhostname\fRor \ \fB-dm\ \fIhostname\fR
+This will remove \fIhostname\fR from the specified container.
+
+.IP \fB-listsub\ \fRor\ \fB-ls\fR
+This will list subcontainers of the specified container.  Use the
+\fB-r\fR
+flag for a recursive listing.
+
+.SH AUTHORS
+Garry Zacheiss, MIT Information Systems.
+.SH SEE ALSO
+moira(1)
+
+.SH DIAGNOSTICS
+An exit status of 2 indicates a problem contacting the server. An exit
+status of 1 indicates that the arguments could not be parsed or some
+query to the moira server returned an error. An exit status of 0
+indicates that all operations requested completed successfully.
+
+.SH NOTES
+The container name doesn't actually have to be the first argument, but
+if you put it anywhere else, it's easy to get the other arguments in the
+wrong order and do something other than what you intended.
+
This page took 0.112885 seconds and 5 git commands to generate.