+int MachineToClusterMap(int argc, char **argv)
+{
+ struct mqelem *elem, *top;
+ char *tmpname, temp_buf[256];
+
+ tmpname = canonicalize_hostname(strdup(argv[1]));
+ if (strcasecmp(tmpname, argv[1]) && *argv[1] != '"')
+ {
+ sprintf(temp_buf, "Warning: '%s' canonicalized to '%s'.",
+ argv[1], tmpname);
+ Put_message(temp_buf);
+ }
+ top = elem = GetMCInfo(MAP, tmpname, argv[2]);
+
+ Put_message(""); /* blank line on screen */
+ while (elem)
+ {
+ char **info = elem->q_data;
+ PrintMCMap(info);
+ elem = elem->q_forw;
+ }
+
+ FreeQueue(top);
+ free(tmpname);
+ return DM_NORMAL;
+}
+
+/* Function Name: MachineByOwner
+ * Description: This function prints all machines which are owned by
+ * a given user or group.
+ * Arguments: none.
+ * Returns: DM_NORMAL.
+ */
+
+int MachineByOwner(int argc, char **argv)
+{
+ char buf[BUFSIZ], temp_buf[BUFSIZ], *type, *name;
+ struct mqelem *top;
+
+ type = strdup("USER");
+ if (GetTypeFromUser("Type of owner", "ace_type", &type) == SUB_ERROR)
+ return DM_NORMAL;
+
+ sprintf(buf, "Name of %s", type);
+ name = strdup(user);
+ if (GetValueFromUser(buf, &name) == SUB_ERROR)
+ return DM_NORMAL;
+
+ switch (YesNoQuestion("Do you want a recursive search (y/n)", FALSE))
+ {
+ case TRUE:
+ sprintf(temp_buf, "R%s", type); /* "USER to "RUSER", etc. */
+ free(type);
+ type = strdup(temp_buf);
+ break;
+ case FALSE:
+ break;
+ default:
+ return DM_NORMAL;
+ }
+
+ top = GetMachineByOwner(type, name);
+ Loop(top, PrintMachine);
+
+ FreeQueue(top);
+ return DM_NORMAL;
+}
+
+/* Function Name: GetMachineByOwner
+ * Description: This function stores information retrieved by
+ * the get_host_by_owner query
+ * Arguments: type - an ace_type, argv[0] for the query
+ * name - name of machine, argv[1] for the query
+ * Returns: the top element of a queue returning the data, or NULL.
+ */
+
+struct mqelem *GetMachineByOwner(char *type, char *name)
+{
+ char *args[2];
+ struct mqelem *elem = NULL;
+ int status;
+
+ args[0] = type;
+ args[1] = name;
+ if ((status = do_mr_query("get_host_by_owner", 2, args, StoreInfo, &elem)))
+ {
+ com_err(program_name, status, " in get_host_by_owner");
+ return NULL;
+ }
+ return QueueTop(elem);
+}
+
+int MachineByAcctNumber(int argc, char **argv)
+{
+ char *args[0], *account_number;
+ int status;
+ struct mqelem *elem = NULL;
+
+ if (GetValueFromUser("Account Number", &account_number) == SUB_ERROR)
+ return DM_NORMAL;
+
+ args[0] = account_number;
+ if (status = do_mr_query("get_host_by_account_number", 1, args, StoreInfo,
+ &elem))
+ {
+ com_err(program_name, status, " in get_host_by_account_number");
+ return DM_NORMAL;
+ }
+ Loop(QueueTop(elem), (void (*)(char **)) PrintMachInfo);
+ FreeQueue(elem);
+
+ return DM_NORMAL;
+}
+
+int ShowContainerInfo(int argc, char **argv)
+{
+ struct mqelem *top;
+
+ top = GetMCInfo(CONTAINER, argv[1], NULL);
+ Loop(top, (void (*)(char **)) PrintContainerInfo);
+ FreeQueue(top);
+ return DM_NORMAL;
+}
+
+static char *PrintContainerInfo(char **info)
+{
+ char buf[BUFSIZ], tbuf[256];
+
+ Put_message("");
+ sprintf(buf, "Container: %-16s", info[CON_NAME]);
+ Put_message(buf);
+ sprintf(buf, "Description: %-16s", info[CON_DESCRIPT]);
+ Put_message(buf);
+ sprintf(buf, "Location: %-16s Contact: %s", info[CON_LOCATION],
+ info[CON_CONTACT]);
+ Put_message(buf);
+ sprintf(tbuf, "%s %s", info[CON_OWNER_TYPE],
+ strcmp(info[CON_OWNER_TYPE], "NONE") ? info[CON_OWNER_NAME] : "");
+ sprintf(buf, "Owner: %-16s", tbuf);
+ Put_message(buf);
+ sprintf(tbuf, "%s %s", info[CON_MEMACE_TYPE],
+ strcmp(info[CON_MEMACE_TYPE], "NONE") ? info[CON_MEMACE_NAME] : "");
+ sprintf(buf, "Membership ACL: %-16s", tbuf);
+ Put_message(buf);
+ Put_message("");
+ sprintf(buf, MOD_FORMAT, info[CON_MODBY], info[CON_MODTIME],
+ info[CON_MODWITH]);
+ Put_message(buf);
+ return info[CON_NAME];
+}
+
+static char *PrintContainer(char **info)
+{
+ char buf[BUFSIZ];
+
+ sprintf(buf, "Container: %s", info[CON_NAME]);
+ Put_message(buf);
+}
+
+static char *PrintMContMap(char **info)
+{
+ char buf[BUFSIZ];
+ sprintf(buf, "Container: %-30s Machine: %-20s",
+ info[1], info[0]);
+ Put_message(buf);
+ return "";
+}
+
+int AddContainer(int argc, char **argv)
+{
+ char **args, *info[MAX_ARGS_SIZE], *name = argv[1];
+ int stat;
+
+ /* Can't use ValidName() because spaces are allowed in container names */
+ if (IS_EMPTY(name))
+ {
+ Put_message("Please use a non-empty name.");
+ return DM_NORMAL;
+ }
+
+ if (strchr(name, '*') || strchr(name, '?'))
+ {
+ Put_message("Wildcards not accepted here.");
+ return DM_NORMAL;
+ }
+
+ /* Check if this cluster already exists. */
+ if ((stat = do_mr_query("get_container", 1, &name, NULL, NULL))
+ == MR_SUCCESS)
+ {
+ Put_message("This container already exists.");
+ return DM_NORMAL;
+ }
+ else if (stat != MR_NO_MATCH)
+ {
+ com_err(program_name, stat, " in AddContainer.");
+ return DM_NORMAL;
+ }
+ if (!(args = AskMCDInfo(SetContainerDefaults(info, name), CONTAINER, FALSE)))
+ {
+ Put_message("Aborted.");
+ FreeInfo(info);
+ return DM_NORMAL;
+ }
+
+ /* Create the new container. */
+ if ((stat = do_mr_query("add_container", CountArgs(args), args, NULL, NULL)))
+ com_err(program_name, stat, " in AddContainer.");
+
+ FreeInfo(info);
+ return DM_NORMAL;
+}
+
+int UpdateContainer(int argc, char **argv)
+{
+ struct mqelem *top;
+ top = GetMCInfo(CONTAINER, argv[1], NULL);
+ QueryLoop(top, NullPrint, RealUpdateContainer, "Update the container");
+
+ FreeQueue(top);
+ return DM_NORMAL;
+}
+
+static void RealUpdateContainer(char **info, Bool junk)