-#ifndef lint
- static char rcsid_module_c[] = "$Header$";
-#endif lint
-
-/* This is the file cluseter.c for allmaint, the SMS client that allows
- * a user to maintaint most important parts of the SMS database.
- * It Contains:
- *
+/* $Id$
+ *
+ * This is the file cluster.c for the Moira Client, which allows users
+ * to quickly and easily maintain most parts of the Moira database.
+ * It Contains:
+ *
* Created: 4/22/88
* By: Chris D. Peterson
- * Based upon: Clusermaint.c by marcus: 87/07/22
*
- * $Source$
- * $Author$
- * $Header$
- *
- * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
- *
- * For further information on copyright and distribution
- * see the file mit-copyright.h
+ * Copyright (C) 1988-1998 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
*/
/* BTW: for anyone who cares MCD is short for Machine, Cluster, Data. */
-#include <stdio.h>
-#include <strings.h>
-#include <sms.h>
-#include <menu.h>
+#include <mit-copyright.h>
+#include <moira.h>
+#include <moira_site.h>
+#include <mrclient.h>
-#include "mit-copyright.h"
-#include "allmaint.h"
-#include "allmaint_funcs.h"
+#include "defs.h"
+#include "f_defs.h"
#include "globals.h"
-#include "infodefs.h"
-#define MACHINE 0
-#define CLUSTER 1
-#define DATA 2
-#define MAP 3
+#include <sys/types.h>
+
+#ifdef HAVE_UNAME
+#include <sys/utsname.h>
+#endif
+
+#ifndef _WIN32
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#endif /* _WIN32 */
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+void PrintAliases(char **info);
+static void PrintMachine(char **info);
+struct mqelem *GetMCInfo(int type, char *name1, char *name2);
+struct mqelem *GetMachineByOwner(char *type, char *name);
+char **AskMCDInfo(char **info, int type, Bool name);
+int CheckAndRemoveFromCluster(char *name, Bool ask_user);
+int CheckAndRemoveCnames(char *name, Bool ask_user);
+int CheckAndRemoveMachines(char *name, Bool ask_first);
+
+static char *PrintContainerInfo(char **info);
+static void RealUpdateContainer(char **info, Bool junk);
+static void RealDeleteContainer(char **info, Bool one_container);
+static void RealRemoveMachineFromContainer(char **info, Bool one_contmap);
+
+#define MACHINE 0
+#define CLUSTER 1
+#define DATA 2
+#define MAP 3
+#define SUBNET 4
+#define CNAME 5
+#define CONTAINER 6
+#define CONTMAP 7
#define M_DEFAULT_TYPE DEFAULT_NONE
#define C_DEFAULT_DESCRIPT DEFAULT_NONE
#define C_DEFAULT_LOCATION DEFAULT_NONE
+#define CON_DEFAULT_TYPE DEFAULT_NONE
+
#define CD_DEFAULT_LABEL DEFAULT_NONE
#define CD_DEFAULT_DATA DEFAULT_NONE
+#define S_DEFAULT_LOW "18.0.0.20"
+#define S_DEFAULT_HIGH "18.0.2.249"
+
+static char *states[] = {
+ "Reserved (0)",
+ "Active (1)",
+ "None (2)",
+ "Deleted (3)"
+};
+
+static char *subnet_states[] = {
+ "Reserved (0)",
+ "Billable (1)",
+ "Private, 10 Mbps (2)",
+ "Private, 100 Mbps (3)",
+ "Private, Other (4)",
+ "Resnet, Dorm (5)",
+ "Infrastructure (6)",
+ "Private, 1000 Mbps (7)",
+ "Resnet, FSILG (8)"
+};
+
+static char *MacState(int state)
+{
+ static char buf[BUFSIZ];
+
+ if (state < 0 || state > 3)
+ {
+ sprintf(buf, "Unknown (%d)", state);
+ return buf;
+ }
+ return states[state];
+}
+
+static char *SubnetState(int state)
+{
+ static char buf[BUFSIZ];
+
+ if (state < 0 || state > 8)
+ {
+ sprintf(buf, "Unknown (%d)", state);
+ return buf;
+ }
+ return subnet_states[state];
+}
+
/* -------------------- Set Defaults -------------------- */
/* Function Name: SetMachineDefaults
* Returns: info - the array.
*/
-char **
-SetMachineDefaults(info, name)
-char ** info, *name;
+static char **SetMachineDefaults(char **info, char *name)
{
- info[M_NAME] = Strsave(name);
- info[M_TYPE] = Strsave(M_DEFAULT_TYPE);
- info[M_MODBY] = info[M_MODTIME] = info[M_MODWITH] = info[M_END] = NULL;
- return(info);
+ info[M_NAME] = strdup(name);
+ info[M_VENDOR] = strdup(M_DEFAULT_TYPE);
+ info[M_MODEL] = strdup(M_DEFAULT_TYPE);
+ info[M_OS] = strdup(M_DEFAULT_TYPE);
+ info[M_LOC] = strdup(M_DEFAULT_TYPE);
+ info[M_CONTACT] = strdup(M_DEFAULT_TYPE);
+ info[M_BILL_CONTACT] = strdup(M_DEFAULT_TYPE);
+ info[M_ACCT_NUMBER] = strdup("");
+ info[M_USE] = strdup("0");
+ info[M_STAT] = strdup("1");
+ info[M_SUBNET] = strdup("NONE");
+ info[M_ADDR] = strdup("unique");
+ info[M_OWNER_TYPE] = strdup("NONE");
+ info[M_OWNER_NAME] = strdup("NONE");
+ info[M_ACOMMENT] = strdup("");
+ info[M_OCOMMENT] = strdup("");
+ info[17] = info[18] = NULL;
+ return info;
}
/* Function Name: SetClusterDefaults
* Returns: info - the array.
*/
-char **
-SetClusterDefaults(info, name)
-char ** info, *name;
+static char **SetClusterDefaults(char **info, char *name)
{
- info[C_NAME] = Strsave(name);
- info[C_DESCRIPT] = Strsave(C_DEFAULT_DESCRIPT);
- info[C_LOCATION] = Strsave(C_DEFAULT_LOCATION);
- info[C_MODBY] = info[C_MODTIME] = info[C_MODWITH] = info[C_END] = NULL;
- return(info);
+ info[C_NAME] = strdup(name);
+ info[C_DESCRIPT] = strdup(C_DEFAULT_DESCRIPT);
+ info[C_LOCATION] = strdup(C_DEFAULT_LOCATION);
+ info[C_MODBY] = info[C_MODTIME] = info[C_MODWITH] = info[C_END] = NULL;
+ return info;
}
-/* Function Name: SetClusterDataDefaults
- * Description: Sets cluster data defaults.
+static char **SetContainerDefaults(char **info, char *name)
+{
+ info[CON_NAME] = strdup(name);
+ info[CON_PUBLIC] = strdup(DEFAULT_NO);
+ info[CON_DESCRIPT] = strdup(CON_DEFAULT_TYPE);
+ info[CON_LOCATION] = strdup(CON_DEFAULT_TYPE);
+ info[CON_CONTACT] = strdup(CON_DEFAULT_TYPE);
+ info[CON_OWNER_TYPE] = strdup("NONE");
+ info[CON_OWNER_NAME] = strdup("NONE");
+ info[CON_MEMACE_TYPE] = strdup("NONE");
+ info[CON_MEMACE_NAME] = strdup("NONE");
+ info[CON_MODBY] = info[CON_MODTIME] = info[CON_MODWITH] = NULL;
+ info[CON_END] = NULL;
+ return info;
+}
+
+/* Function Name: SetSubnetDefaults
+ * Description: sets Subnet defaults.
* Arguments: info - an array to put the defaults into.
- * name - name of the Cluster.
+ * name - name of the Subnet.
* Returns: info - the array.
*/
-char **
-SetClusterDataDefaults(info, name)
-char ** info, *name;
+static char **SetSubnetDefaults(char **info, char *name)
{
- info[CD_NAME] = Strsave(name);
- info[CD_LABEL] = Strsave(CD_DEFAULT_LABEL);
- info[CD_DATA] = Strsave(CD_DEFAULT_DATA);
-/*info[CD_MODBY] = info[CD_MODTIME] = info[CD_MODWITH] = info[CD_END] = NULL;*/
- info[CD_END] = NULL;
- return(info);
+ char buf[256];
+
+ info[SN_NAME] = strdup(name);
+ info[SN_DESC] = strdup("");
+ info[SN_STATUS] = strdup("1");
+ info[SN_CONTACT] = strdup(DEFAULT_NONE);
+ info[SN_ACCT_NUMBER] = strdup("");
+ sprintf(buf, "%ld", ntohl(inet_addr("18.255.0.0")));
+ info[SN_ADDRESS] = strdup(buf);
+ sprintf(buf, "%ld", ntohl(inet_addr("255.255.0.0")));
+ info[SN_MASK] = strdup(buf);
+ sprintf(buf, "%ld", ntohl(inet_addr(S_DEFAULT_LOW)));
+ info[SN_LOW] = strdup(buf);
+ sprintf(buf, "%ld", ntohl(inet_addr(S_DEFAULT_HIGH)));
+ info[SN_HIGH] = strdup(buf);
+ info[SN_PREFIX] = strdup("");
+ info[SN_ACE_TYPE] = strdup("LIST");
+ info[SN_ACE_NAME] = strdup("network");
+ info[SN_MODBY] = info[SN_MODTIME] = info[SN_MODWITH] = info[SN_END] = NULL;
+ return info;
}
/* -------------------- General Functions -------------------- */
+static char aliasbuf[256];
+
+void PrintAliases(char **info)
+{
+ if (strlen(aliasbuf) == 0)
+ sprintf(aliasbuf, "Aliases: %s", info[0]);
+ else
+ {
+ strcat(aliasbuf, ", ");
+ strcat(aliasbuf, info[0]);
+ }
+}
+
+
/* Function Name: PrintMachInfo
- * Description: This function Prints out the Machine info in
+ * Description: This function Prints out the Machine info in
* a coherent form.
* Arguments: info - array of information about a machine.
- * Returns: none.
+ * Returns: The name of the Machine
+ */
+
+static char *PrintMachInfo(char **info)
+{
+ char buf[BUFSIZ], tbuf[256];
+ char *args[3];
+ struct mqelem *elem = NULL, *elem2 = NULL;
+ int stat;
+
+ Put_message("");
+ sprintf(buf, "Machine: %s", info[M_NAME]);
+ Put_message(buf);
+ args[0] = "*";
+ args[1] = info[M_NAME];
+ if ((stat = do_mr_query("get_hostalias", 2, args, StoreInfo, &elem)))
+ {
+ if (stat != MR_NO_MATCH)
+ com_err(program_name, stat, " looking up aliases");
+ }
+ else
+ {
+ aliasbuf[0] = 0;
+ Loop(QueueTop(elem), (void (*)(char **)) PrintAliases);
+ FreeQueue(elem);
+ Put_message(aliasbuf);
+ }
+ sprintf(tbuf, "%s %s", info[M_OWNER_TYPE],
+ strcmp(info[M_OWNER_TYPE], "NONE") ? info[M_OWNER_NAME] : "");
+ sprintf(buf, "Address: %-16s Network: %-16s",
+ info[M_ADDR], info[M_SUBNET]);
+ Put_message(buf);
+ sprintf(buf, "Owner: %-16s Use data: %s", tbuf, info[M_INUSE]);
+ Put_message(buf);
+ sprintf(buf, "Status: %-16s Changed: %s",
+ MacState(atoi(info[M_STAT])), info[M_STAT_CHNG]);
+ Put_message(buf);
+ Put_message("");
+ sprintf(buf, "Vendor: %-16s Location: %s", info[M_VENDOR],
+ info[M_LOC]);
+ Put_message(buf);
+ sprintf(buf, "Model: %-16s Contact: %s", info[M_MODEL],
+ info[M_CONTACT]);
+ Put_message(buf);
+ sprintf(buf, "OS: %-16s Billing Contact: %s", info[M_OS],
+ info[M_BILL_CONTACT]);
+ Put_message(buf);
+ sprintf(buf, "Opt: %-16s Account Number: %s", info[M_USE],
+ info[M_ACCT_NUMBER]);
+ Put_message(buf);
+ Put_message("");
+ sprintf(buf, "Adm cmt: %s", info[M_ACOMMENT]);
+ Put_message(buf);
+ sprintf(buf, "Op cmt: %s", info[M_OCOMMENT]);
+ Put_message(buf);
+ Put_message("");
+ sprintf(buf, "Created by %s on %s", info[M_CREATOR], info[M_CREATED]);
+ Put_message(buf);
+ sprintf(buf, MOD_FORMAT, info[M_MODBY], info[M_MODTIME], info[M_MODWITH]);
+ Put_message(buf);
+ /* Do a get_subnet for the machine's subnet. We need to know if it's
+ * Private.
+ */
+ args[0] = info[M_SUBNET];
+ stat = do_mr_query("get_subnet", 1, args, StoreInfo, &elem2);
+ if (stat)
+ com_err(program_name, stat, " looking up subnet info");
+ else if (atoi(((char **)elem2->q_data)[2]) == SNET_STATUS_PRIVATE_10MBPS ||
+ atoi(((char **)elem2->q_data)[2]) == SNET_STATUS_PRIVATE_100MBPS ||
+ atoi(((char **)elem2->q_data)[2]) == SNET_STATUS_PRIVATE_1000MBPS)
+ {
+ Put_message("");
+ sprintf(buf, "Warning: This host is on a private subnet.");
+ Put_message(buf);
+ sprintf(buf, "Billing information shown is superseded by billing information for the subnet.");
+ Put_message(buf);
+ FreeQueue(elem2);
+ }
+
+ return info[M_NAME];
+}
+
+/* Function Name: PrintMachine
+ * Description: Prints the name of a machine record
+ * Arguments: info - array of information about the machine.
+ * Returns: nothing.
*/
-void
-PrintMachInfo(info)
-char ** info;
+static void PrintMachine(char **info)
{
- char buf[BUFSIZ];
+ char buf[BUFSIZ];
- Put_message("");
- sprintf(buf, "Machine: %-30s Type: %s", info[M_NAME], info[M_TYPE]);
- Put_message(buf);
- sprintf(buf, "Last Modified at %s, by %s with %s",info[M_MODTIME],
- info[M_MODBY], info[M_MODWITH]);
- Put_message(buf);
+ sprintf(buf, "Machine: %s", info[M_NAME]);
+ Put_message(buf);
+}
+
+/* Function Name: PrintCname
+ * Description: Prints the Data on a host alias
+ * Arguments: info a pointer to the data array.
+ * Returns: The name of the alias.
+ */
+
+static char *PrintCname(char **info)
+{
+ char buf[BUFSIZ];
+
+ sprintf(buf, "Alias: %-32s Canonical Name: %s", info[0], info[1]);
+ Put_message(buf);
+ return info[0];
}
/* Function Name: PrintClusterInfo
- * Description: This function Prints out the cluster info
+ * Description: This function Prints out the cluster info
* in a coherent form.
* Arguments: info - array of information about a cluster.
- * Returns: none.
+ * Returns: The name of the cluster.
*/
-void
-PrintClusterInfo(info)
-char ** info;
+static char *PrintClusterInfo(char **info)
{
- char buf[BUFSIZ];
-
- Put_message("");
- sprintf(buf, "Cluster: %s", info[C_NAME]);
- Put_message(buf);
- sprintf(buf, "Description: %s", info[C_DESCRIPT]);
- Put_message(buf);
- sprintf(buf, "Location: %s", info[C_LOCATION]);
- Put_message(buf);
- sprintf(buf, "Last Modified at %s, by %s with %s",info[C_MODTIME],
- info[C_MODBY], info[C_MODWITH]);
- Put_message(buf);
+ char buf[BUFSIZ];
+
+ Put_message("");
+ sprintf(buf, "Cluster: %s", info[C_NAME]);
+ Put_message(buf);
+ sprintf(buf, "Description: %s", info[C_DESCRIPT]);
+ Put_message(buf);
+ sprintf(buf, "Location: %s", info[C_LOCATION]);
+ Put_message(buf);
+ sprintf(buf, MOD_FORMAT, info[C_MODBY], info[C_MODTIME], info[C_MODWITH]);
+ Put_message(buf);
+ return info[C_NAME];
}
/* Function Name: PrintClusterData
* Description: Prints the Data on a cluster
* Arguments: info a pointer to the data array.
- * Returns: none
+ * Returns: The name of the cluster.
*/
-void
-PrintClusterData(info)
-char ** info;
+static char *PrintClusterData(char **info)
{
- char buf[BUFSIZ];
+ char buf[BUFSIZ];
- Put_message("");
- sprintf(buf, "Cluster: %-20s Label: %-15s Data: %s",
- info[CD_NAME], info[CD_LABEL], info[CD_DATA]);
- Put_message(buf);
+ Put_message("");
+ sprintf(buf, "Cluster: %-20s Label: %-15s Data: %s",
+ info[CD_NAME], info[CD_LABEL], info[CD_DATA]);
+ Put_message(buf);
+ return info[CD_NAME];
}
/* Function Name: PrintMCMap
* Returns: none
*/
-void
-PrintMCMap(info)
-char ** info;
+static char *PrintMCMap(char **info)
+{
+ char buf[BUFSIZ];
+ sprintf(buf, "Cluster: %-30s Machine: %-20s",
+ info[MAP_CLUSTER], info[MAP_MACHINE]);
+ Put_message(buf);
+ return ""; /* Used by QueryLoop(). */
+}
+
+/* Function Name: PrintSubnetInfo
+ * Description: This function Prints out the subnet info
+ * in a coherent form.
+ * Arguments: info - array of information about a subnet.
+ * Returns: The name of the subnet.
+ */
+
+static char *PrintSubnetInfo(char **info)
{
- char buf[BUFSIZ];
- sprintf(buf, "Cluster: %-30s Machine: %-20s",
- info[MAP_CLUSTER], info[MAP_MACHINE]);
- Put_message(buf);
+ char buf[BUFSIZ];
+ struct in_addr addr, mask, low, high;
+
+ Put_message("");
+ sprintf(buf, " Network: %s", info[SN_NAME]);
+ Put_message(buf);
+ sprintf(buf, " Description: %s", info[SN_DESC]);
+ Put_message(buf);
+ sprintf(buf, " Status: %s", SubnetState(atoi(info[SN_STATUS])));
+ Put_message(buf);
+ sprintf(buf, " Contact: %s", info[SN_CONTACT]);
+ Put_message(buf);
+ sprintf(buf, " Account Number: %s", info[SN_ACCT_NUMBER]);
+ Put_message(buf);
+ addr.s_addr = htonl(atoi(info[SN_ADDRESS]));
+ mask.s_addr = htonl(atoi(info[SN_MASK]));
+ low.s_addr = htonl(atoi(info[SN_LOW]));
+ high.s_addr = htonl(atoi(info[SN_HIGH]));
+ /* screwy sequence is here because inet_ntoa returns a pointer to
+ a static buf. If it were all one sprintf, the last value would
+ appear 4 times. */
+ sprintf(buf, " Address: %s Mask: ", inet_ntoa(addr));
+ strcat(buf, inet_ntoa(mask));
+ strcat(buf, "\n High: ");
+ strcat(buf, inet_ntoa(high));
+ strcat(buf, " Low: ");
+ strcat(buf, inet_ntoa(low));
+ Put_message(buf);
+ sprintf(buf, "Hostname prefix: %s", info[SN_PREFIX]);
+ Put_message(buf);
+ sprintf(buf, " Owner: %s %s\n", info[SN_ACE_TYPE],
+ strcmp(info[SN_ACE_TYPE], "NONE") ? info[SN_ACE_NAME] : "");
+ Put_message(buf);
+ sprintf(buf, MOD_FORMAT, info[SN_MODBY], info[SN_MODTIME], info[SN_MODWITH]);
+ Put_message(buf);
+ return info[SN_NAME];
}
/* Function Name: GetMCInfo.
* Returns: the top element of a queue containing the data or NULL.
*/
-struct qelem *
-GetMCInfo(type, name1, name2)
-int type;
-char * name1, *name2;
+struct mqelem *GetMCInfo(int type, char *name1, char *name2)
{
+ int stat;
+ struct mqelem *elem = NULL;
+ char *args[5];
- int stat;
- struct qelem * elem = NULL;
- char * args[2];
-
- switch (type) {
+ switch (type)
+ {
case MACHINE:
- if ( (stat = sms_query("get_machine", 1, &name1,
- StoreInfo, &elem)) != 0) {
+ args[0] = name1;
+ args[1] = args[2] = args[3] = "*";
+ if ((stat = do_mr_query("get_host", 4, args, StoreInfo, &elem)))
+ {
+ if (stat == MR_NO_MATCH)
+ {
+ char buf[128];
+ sprintf(buf, "Machine '%s' is not in the database.", name1);
+ Put_message(buf);
+ }
+ else
com_err(program_name, stat, " in get_machine.");
- return(NULL);
+ return NULL;
+ }
+ break;
+ case CNAME:
+ args[0] = name1;
+ args[1] = name2;
+ if ((stat = do_mr_query("get_hostalias", 2, args, StoreInfo, &elem)))
+ {
+ com_err(program_name, stat, " in get_hostalias.");
+ return NULL;
}
- break;
+ break;
+ case SUBNET:
+ if ((stat = do_mr_query("get_subnet", 1, &name1, StoreInfo, &elem)))
+ {
+ if (stat == MR_NO_MATCH)
+ {
+ char buf[128];
+ sprintf(buf, "Network '%s' is not in the database.", name1);
+ Put_message(buf);
+ }
+ else
+ com_err(program_name, stat, " in get_subnet.");
+ return NULL;
+ }
+ break;
case CLUSTER:
- if ( (stat = sms_query("get_cluster", 1, &name1,
- StoreInfo, &elem)) != 0) {
- com_err(program_name, stat, " in get_cluster.");
- return(NULL);
+ if ((stat = do_mr_query("get_cluster", 1, &name1, StoreInfo, &elem)))
+ {
+ com_err(program_name, stat, " in get_cluster.");
+ return NULL;
}
- break;
+ break;
case MAP:
- args[MAP_MACHINE] = name1;
- args[MAP_CLUSTER] = name2;
- if ( (stat = sms_query("get_machine_to_cluster_map", 2, args,
- StoreInfo, &elem)) != 0) {
- com_err(program_name, stat, " in get_machine_to_cluster_map.");
- return(NULL);
+ args[MAP_MACHINE] = name1;
+ args[MAP_CLUSTER] = name2;
+ if ((stat = do_mr_query("get_machine_to_cluster_map", 2, args,
+ StoreInfo, &elem)))
+ {
+ com_err(program_name, stat, " in get_machine_to_cluster_map.");
+ return NULL;
}
- break;
+ break;
case DATA:
- args[CD_NAME] = name1;
- args[CD_LABEL] = name2;
- if ( (stat = sms_query("get_cluster_data", 2, args,
- StoreInfo, &elem)) != 0) {
- com_err(program_name, stat, " in get_cluster_data.");
- return(NULL);
+ args[CD_NAME] = name1;
+ args[CD_LABEL] = name2;
+ if ((stat = do_mr_query("get_cluster_data", 2, args, StoreInfo, &elem)))
+ {
+ com_err(program_name, stat, " in get_cluster_data.");
+ return NULL;
+ }
+ break;
+ case CONTAINER:
+ args[CON_NAME] = name1;
+ if ((stat = do_mr_query("get_container", 1, &name1, StoreInfo, &elem)))
+ {
+ com_err(program_name, stat, " in get_container.");
+ return NULL;
+ }
+ break;
+ case CONTMAP:
+ args[0] = name1;
+ if ((stat = do_mr_query("get_machine_to_container_map", 1, &name1,
+ StoreInfo, &elem)))
+ {
+ com_err(program_name, stat, " in get_machine_to_container_map.");
+ return NULL;
}
}
- return(QueueTop(elem));
+ return QueueTop(elem);
}
/* Function Name: AskMCDInfo.
- * Description: This function askes the user for information about a
+ * Description: This function askes the user for information about a
* machine and saves it into a structure.
* Arguments: info - a pointer the information to ask about
* type - type of information - MACHINE
* CLUSTER
* DATA
+ * CONTAINER
* name - T/F : change the name of this type.
* Returns: none.
*/
-char **
-AskMCDInfo(info, type, name)
-char ** info;
-int type;
-Bool name;
+char **AskMCDInfo(char **info, int type, Bool name)
{
- char temp_buf[BUFSIZ], *newname;
+ char temp_buf[BUFSIZ], *newname, *oldnewname;
- switch (type) {
+ switch (type)
+ {
case MACHINE:
- sprintf(temp_buf, "Setting the information for the Machine %s.",
- info[M_NAME]);
- break;
+ sprintf(temp_buf, "\nSetting the information for the Machine %s...",
+ info[M_NAME]);
+ break;
+ case SUBNET:
+ sprintf(temp_buf, "Setting the information for the Network %s...",
+ info[SN_NAME]);
+ break;
case CLUSTER:
- sprintf(temp_buf, "Setting the information for the Cluster %s.",
- info[C_NAME]);
- break;
+ sprintf(temp_buf, "Setting the information for the Cluster %s...",
+ info[C_NAME]);
+ break;
case DATA:
- sprintf(temp_buf, "Setting the Data for the Cluster %s.",
- info[CD_NAME]);
- break;
+ sprintf(temp_buf, "Setting the Data for the Cluster %s...",
+ info[CD_NAME]);
+ break;
+ case CONTAINER:
+ sprintf(temp_buf, "Setting the Data for the Container %s...",
+ info[CON_NAME]);
+ break;
}
- Put_message(temp_buf);
+ Put_message(temp_buf);
- if (name) {
- switch (type) {
+ if (name)
+ {
+ switch (type)
+ {
case MACHINE:
- newname = Strsave(info[M_NAME]);
- GetValueFromUser("The new name for this machine? ", &newname);
- strcpy(temp_buf, CanonicalizeHostname(newname));
- free(newname);
- newname = Strsave(temp_buf);
- break;
+ newname = strdup(info[M_NAME]);
+ if (GetValueFromUser("The new name for this machine? ", &newname) ==
+ SUB_ERROR)
+ return NULL;
+ oldnewname = strdup(newname);
+ newname = canonicalize_hostname(newname);
+ if (strcasecmp(newname, oldnewname) && *oldnewname != '"')
+ {
+ sprintf(temp_buf, "Warning: '%s' canonicalized to '%s'\n",
+ oldnewname, newname);
+ Put_message(temp_buf);
+ }
+ free(oldnewname);
+ break;
+ case SUBNET:
+ newname = strdup(info[SN_NAME]);
+ if (GetValueFromUser("The new name for this network? ", &newname) ==
+ SUB_ERROR)
+ return NULL;
+ break;
case CLUSTER:
- newname = Strsave(info[C_NAME]);
- GetValueFromUser("The new name for this cluster? ",
- &newname);
- break;
+ newname = strdup(info[C_NAME]);
+ if (GetValueFromUser("The new name for this cluster? ", &newname) ==
+ SUB_ERROR)
+ return NULL;
+ break;
+ case CONTAINER:
+ newname = strdup(info[CON_NAME]);
+ if (GetValueFromUser("The new name for this container? ", &newname)
+ == SUB_ERROR)
+ return NULL;
+ break;
default:
- Put_message("Unknown type in AskMCDInfo, programmer botch");
- return(NULL);
+ Put_message("Unknown type in AskMCDInfo, programmer botch");
+ return NULL;
}
}
- switch(type) {
+ switch (type)
+ {
case MACHINE:
- GetValueFromUser("Machine's Type:", &info[M_TYPE]);
- FreeAndClear(&info[M_MODTIME], TRUE);
- FreeAndClear(&info[M_MODBY], TRUE);
- FreeAndClear(&info[M_MODWITH], TRUE);
- break;
+ if (GetValueFromUser("Machine's vendor", &info[M_VENDOR]) == SUB_ERROR)
+ return NULL;
+ if (GetValueFromUser("Machine's model", &info[M_MODEL]) == SUB_ERROR)
+ return NULL;
+ if (GetValueFromUser("Machine's operating system", &info[M_OS]) ==
+ SUB_ERROR)
+ return NULL;
+ if (GetValueFromUser("Machine's location", &info[M_LOC]) == SUB_ERROR)
+ return NULL;
+ if (GetValueFromUser("Machine's contact", &info[M_CONTACT]) ==
+ SUB_ERROR)
+ return NULL;
+ if (GetValueFromUser("Machine's billing contact",
+ &info[M_BILL_CONTACT]) == SUB_ERROR)
+ return NULL;
+ if (GetValueFromUser("Machine's billing account number",
+ &info[M_ACCT_NUMBER]) == SUB_ERROR)
+ return NULL;
+ while (1)
+ {
+ int i;
+ if (GetValueFromUser("Machine's status (? for help)",
+ &info[M_STAT]) == SUB_ERROR)
+ return NULL;
+ if (isdigit(info[M_STAT][0]))
+ break;
+ Put_message("Valid status numbers:");
+ for (i = 0; i < 4; i++)
+ Put_message(states[i]);
+ }
+
+ /* there appears to be some argument mismatch between the client
+ * and the server.. so here is this argument shuffler.
+ * I have since modified this to always shuffle the arguments..
+ * not just do so when performing a modify all fields request.
+ * The SetMachinedefaults() has been changed to reflect this.
+ * pray for us and may we attain enlightenment through structures.
+ */
+
+ if (name)
+ {
+ /* info did not come from SetMachineDefaults(), which does not
+ * initialize entry 10 (M_STAT_CHNG), therefore we can
+ * free it.
+ */
+ /* This is an update of an existing machine and the structure
+ * was filled in thru a query to the db which does fill in this
+ * field.
+ */
+ free(info[10]);
+ }
+
+ info[10] = info[M_SUBNET];
+ info[11] = info[M_ADDR];
+ info[12] = info[M_OWNER_TYPE];
+ info[13] = info[M_OWNER_NAME];
+ info[14] = info[M_ACOMMENT];
+ info[15] = info[M_OCOMMENT];
+
+ if (name)
+ {
+ if (GetValueFromUser("Machine's network (or 'none')", &info[10])
+ == SUB_ERROR)
+ return NULL;
+ }
+ if (GetValueFromUser("Machine's address (or 'unassigned' or 'unique')",
+ &info[11]) == SUB_ERROR)
+ return NULL;
+ if (GetTypeFromUser("Machine's owner type", "ace_type", &info[12]) ==
+ SUB_ERROR)
+ return NULL;
+ if (strcmp(info[12], "NONE") &&
+ GetValueFromUser("Owner's Name", &info[13]) == SUB_ERROR)
+ return NULL;
+ if (!strcmp(info[12], "KERBEROS"))
+ {
+ char *canon;
+
+ mrcl_validate_kerberos_member(info[13], &canon);
+ if (mrcl_get_message())
+ Put_message(mrcl_get_message());
+ free(info[13]);
+ info[13] = canon;
+ }
+ if (GetValueFromUser("Administrative comment", &info[14]) == SUB_ERROR)
+ return NULL;
+ if (GetValueFromUser("Operational comment", &info[15]) == SUB_ERROR)
+ return NULL;
+ info[16] = NULL;
+ FreeAndClear(&info[17], TRUE);
+ FreeAndClear(&info[18], TRUE);
+ break;
+ case SUBNET:
+ if (GetValueFromUser("Network description", &info[SN_DESC]) == SUB_ERROR)
+ return NULL;
+ while (1)
+ {
+ int i;
+ if (GetValueFromUser("Network's status (? for help)",
+ &info[SN_STATUS]) == SUB_ERROR)
+ return NULL;
+ if (isdigit(info[SN_STATUS][0]))
+ break;
+ Put_message("Valid status numbers:");
+ for (i = 0; i < 9; i++)
+ Put_message(subnet_states[i]);
+ }
+ if (GetValueFromUser("Network's contact", &info[SN_CONTACT]) == SUB_ERROR)
+ return NULL;
+ if (GetValueFromUser("Network's billing account number",
+ &info[SN_ACCT_NUMBER]) == SUB_ERROR)
+ return NULL;
+ if (GetAddressFromUser("Network address", &info[SN_ADDRESS]) == SUB_ERROR)
+ return NULL;
+ if (GetAddressFromUser("Network mask", &info[SN_MASK]) == SUB_ERROR)
+ return NULL;
+ if (atoi(info[SN_LOW]) == (int)ntohl(inet_addr(S_DEFAULT_LOW)))
+ {
+ struct in_addr low;
+ unsigned long mask, addr;
+
+ addr = atoi(info[SN_ADDRESS]);
+ mask = atoi(info[SN_MASK]);
+ low.s_addr = atoi(info[SN_LOW]);
+ low.s_addr = (low.s_addr & ~mask) | (addr & mask);
+ free(info[SN_LOW]);
+ sprintf(temp_buf, "%ld", low.s_addr);
+ info[SN_LOW] = strdup(temp_buf);
+ }
+ if (GetAddressFromUser("Lowest assignable address", &info[SN_LOW]) ==
+ SUB_ERROR)
+ return NULL;
+ if (atoi(info[SN_HIGH]) == (int)ntohl(inet_addr(S_DEFAULT_HIGH)))
+ {
+ struct in_addr high;
+ unsigned long mask, addr;
+
+ addr = atoi(info[SN_ADDRESS]);
+ mask = atoi(info[SN_MASK]);
+ high.s_addr = atoi(info[SN_HIGH]);
+ high.s_addr = (high.s_addr & ~mask) | (addr & mask);
+ free(info[SN_HIGH]);
+ sprintf(temp_buf, "%ld", high.s_addr);
+ info[SN_HIGH] = strdup(temp_buf);
+ }
+ if (GetAddressFromUser("Highest assignable address", &info[SN_HIGH]) ==
+ SUB_ERROR)
+ return NULL;
+ if (GetValueFromUser("Hostname prefix", &info[SN_PREFIX]) == SUB_ERROR)
+ return NULL;
+ if (GetTypeFromUser("Owner type", "ace_type", &info[SN_ACE_TYPE]) ==
+ SUB_ERROR)
+ return NULL;
+ if (strcmp(info[SN_ACE_TYPE], "NONE") &&
+ GetValueFromUser("Owner name", &info[SN_ACE_NAME]) == SUB_ERROR)
+ return NULL;
+ if (!strcmp(info[SN_ACE_TYPE], "KERBEROS"))
+ {
+ char *canon;
+
+ mrcl_validate_kerberos_member(info[SN_ACE_NAME], &canon);
+ if (mrcl_get_message())
+ Put_message(mrcl_get_message());
+ free(info[SN_ACE_NAME]);
+ info[SN_ACE_NAME] = canon;
+ }
+ FreeAndClear(&info[SN_MODTIME], TRUE);
+ FreeAndClear(&info[SN_MODBY], TRUE);
+ FreeAndClear(&info[SN_MODWITH], TRUE);
+ break;
case CLUSTER:
- GetValueFromUser("Cluster's Description:", &info[C_DESCRIPT]);
- GetValueFromUser("Cluster's Location:", &info[C_LOCATION]);
- FreeAndClear(&info[C_MODTIME], TRUE);
- FreeAndClear(&info[C_MODBY], TRUE);
- FreeAndClear(&info[C_MODWITH], TRUE);
- break;
+ if (GetValueFromUser("Cluster's Description:", &info[C_DESCRIPT]) ==
+ SUB_ERROR)
+ return NULL;
+ if (GetValueFromUser("Cluster's Location:", &info[C_LOCATION]) ==
+ SUB_ERROR)
+ return NULL;
+ FreeAndClear(&info[C_MODTIME], TRUE);
+ FreeAndClear(&info[C_MODBY], TRUE);
+ FreeAndClear(&info[C_MODWITH], TRUE);
+ break;
case DATA:
- GetValueFromUser("Label defining this data?", &info[CD_LABEL]);
- GetValueFromUser("The data itself ? ", &info[CD_DATA]);
- break;
+ if (GetValueFromUser("Label defining this data?", &info[CD_LABEL]) ==
+ SUB_ERROR)
+ return NULL;
+ if (GetValueFromUser("The data itself ? ", &info[CD_DATA]) == SUB_ERROR)
+ return NULL;
+ break;
+ case CONTAINER:
+ if (GetYesNoValueFromUser("Is this a public container",
+ &info[CON_PUBLIC]) == SUB_ERROR)
+ return NULL;
+ if (GetValueFromUser("Container's Description:", &info[CON_DESCRIPT]) ==
+ SUB_ERROR)
+ return NULL;
+ if (GetValueFromUser("Container's Location:", &info[CON_LOCATION]) ==
+ SUB_ERROR)
+ return NULL;
+ if (GetValueFromUser("Container's Contact:", &info[CON_CONTACT]) ==
+ SUB_ERROR)
+ return NULL;
+ if (GetTypeFromUser("Container's owner type", "ace_type",
+ &info[CON_OWNER_TYPE]) == SUB_ERROR)
+ return NULL;
+ if (strcmp(info[CON_OWNER_TYPE], "NONE") &&
+ GetValueFromUser("Owner's Name", &info[CON_OWNER_NAME]) == SUB_ERROR)
+ return NULL;
+ if (!strcmp(info[CON_OWNER_TYPE], "KERBEROS"))
+ {
+ char *canon;
+
+ mrcl_validate_kerberos_member(info[CON_OWNER_NAME], &canon);
+ if (mrcl_get_message())
+ Put_message(mrcl_get_message());
+ free(info[CON_OWNER_NAME]);
+ info[CON_OWNER_NAME] = canon;
+ }
+ if (GetTypeFromUser("Container's Membership ACL", "ace_type",
+ &info[CON_MEMACE_TYPE]) == SUB_ERROR)
+ return NULL;
+ if (strcmp(info[CON_MEMACE_TYPE], "NONE") &&
+ GetValueFromUser("Membership ACL", &info[CON_MEMACE_NAME])
+ == SUB_ERROR)
+ return NULL;
+ if (!strcmp(info[CON_MEMACE_TYPE], "KERBEROS"))
+ {
+ char *canon;
+
+ mrcl_validate_kerberos_member(info[CON_MEMACE_NAME], &canon);
+ if (mrcl_get_message())
+ Put_message(mrcl_get_message());
+ free(info[CON_MEMACE_NAME]);
+ info[CON_MEMACE_NAME] = canon;
+ }
+ FreeAndClear(&info[CON_MODTIME], TRUE);
+ FreeAndClear(&info[CON_MODBY], TRUE);
+ FreeAndClear(&info[CON_MODWITH], TRUE);
+ break;
}
-/*
- * Slide the newname into the #2 slot, this screws up all future references
- * to this list.
- */
- if (name)
- SlipInNewName(info, newname);
+ /*
+ * Slide the newname into the #2 slot, this screws up all future references
+ * to this list.
+ */
+ if (name)
+ SlipInNewName(info, newname);
- return(info);
+ return info;
}
/* ----------- Machine Menu ----------- */
* Returns: DM_NORMAL.
*/
-/* ARGSUSED */
-int
-ShowMachineInfo(argc, argv)
-int argc;
-char **argv;
+int ShowMachineInfo(int argc, char **argv)
{
- struct qelem *elem, *top;
+ struct mqelem *top;
+ char *tmpname;
+
+ tmpname = canonicalize_hostname(strdup(argv[1]));
+ top = GetMCInfo(MACHINE, tmpname, NULL);
+ Loop(top, ((void (*)(char **)) PrintMachInfo));
+ FreeQueue(top);
+ return DM_NORMAL;
+}
- top = elem = GetMCInfo(MACHINE, CanonicalizeHostname(argv[1]),
- (char *) NULL);
+/* Function Name: ShowMachineQuery
+ * Description: This function shows the information about a machine.
+ * or group of machines, which may be selected through a
+ * number of criteria.
+ * Arguments: argc, argv - the name of the machine in argv[1],
+ * the address of the machine in argv[2],
+ * the location of the machine in argv[3],
+ * and the contact name in argv[4].
+ * any of these may be wildcards.
+ * Returns: DM_NORMAL.
+ */
- while (elem != NULL) {
- char **info = (char **) elem->q_data;
- PrintMachInfo(info);
- elem = elem->q_forw;
+int ShowMachineQuery(int argc, char **argv)
+{
+ int stat;
+ struct mqelem *top, *elem = NULL;
+ char *args[5];
+
+ if (!strcmp(argv[1], "") && !strcmp(argv[2], "") &&
+ !strcmp(argv[3], "") && !strcmp(argv[4], ""))
+ {
+ Put_message("You must specify at least one parameter of the query.");
+ return DM_NORMAL;
}
- FreeQueue(top);
- return(DM_NORMAL);
+ if (*argv[1])
+ args[0] = canonicalize_hostname(strdup(argv[1]));
+ else
+ args[0] = "*";
+ if (*argv[2])
+ args[1] = argv[2];
+ else
+ args[1] = "*";
+ if (*argv[3])
+ args[2] = argv[3];
+ else
+ args[2] = "*";
+ if (*argv[4])
+ args[3] = argv[4];
+ else
+ args[3] = "*";
+
+ if ((stat = do_mr_query("get_host", 4, args, StoreInfo, &elem)))
+ {
+ if (stat == MR_NO_MATCH)
+ Put_message("No machine(s) found matching query in the database.");
+ else
+ com_err(program_name, stat, " in get_machine.");
+ return DM_NORMAL;
+ }
+ top = QueueTop(elem);
+ Loop(top, ((void (*)(char **)) PrintMachInfo));
+ FreeQueue(top);
+ return DM_NORMAL;
}
/* Function Name: AddMachine
* Description: This function adds a new machine to the database.
- * Arguments: argc, argv - the name of the machine in argv[1].
+ * Arguments: argc, argv - the name of the network in argv[1].
* Returns: DM_NORMAL.
*/
-/* ARGSUSED */
-int
-AddMachine(argc, argv)
-int argc;
-char **argv;
+int AddMachine(int argc, char **argv)
{
- char **args, *info[MAX_ARGS_SIZE], *name;
- int stat;
-/*
- * Check to see if this machine already exists.
- */
- name = CanonicalizeHostname(argv[1]);
+ char **args, *info[MAX_ARGS_SIZE], *name, buf[256], *xargs[5];
+ char **rinfo;
+ struct mqelem *elem = NULL;
+ int stat;
+
+ if (!ValidName(argv[1])) /* Checks for wildcards. */
+ return DM_NORMAL;
+
+ /*
+ * get the network record
+ */
+
+ if (strcasecmp(argv[1], "none") &&
+ (stat = do_mr_query("get_subnet", 1, &argv[1], StoreInfo, &elem)))
+ {
+ if (stat == MR_NO_MATCH)
+ {
+ char buf[128];
+ sprintf(buf, "Network '%s' is not in the database.", argv[1]);
+ Put_message(buf);
+ } else
+ com_err(program_name, stat, " in get_subnet.");
+ return DM_NORMAL;
+ }
+
+ /*
+ * Check to see if this machine already exists.
+ */
+
+ name = strdup(""); /* want to put prefix here */
+ if (GetValueFromUser("Machine name", &name) == SUB_ERROR)
+ return 0;
+
+ name = canonicalize_hostname(strdup(name));
- if ( (stat = sms_query("get_machine", 1, &name, NullFunc, NULL)) == 0) {
- Put_message("This machine already exists.");
- return(DM_NORMAL);
+ xargs[0] = name;
+ xargs[1] = xargs[2] = xargs[3] = "*";
+ if (!(stat = do_mr_query("get_host", 4, xargs, NULL, NULL)))
+ {
+ sprintf(buf, "The machine '%s' already exists.", name);
+ Put_message(buf);
+ free(name);
+ return DM_NORMAL;
}
- else if (stat != SMS_NO_MATCH) {
- com_err(program_name, stat, " in AddMachine.");
- return(DM_NORMAL);
+ else if (stat != MR_NO_MATCH)
+ {
+ com_err(program_name, stat,
+ " while checking machine '%s' in AddMachine.", name);
+ free(name);
+ return DM_NORMAL;
}
+ rinfo = SetMachineDefaults(info, name);
+ rinfo[M_SUBNET] = strdup(argv[1]);
+ if (!(args = AskMCDInfo(rinfo, MACHINE, FALSE)))
+ {
+ Put_message("Aborted.");
+ return DM_NORMAL;
+ }
+
+ /*
+ * Actually create the new Machine.
+ */
- args = AskMCDInfo(SetMachineDefaults(info, name), MACHINE, FALSE);
+ if ((stat = do_mr_query("add_host", CountArgs(args), args, NULL, NULL)))
+ com_err(program_name, stat, " in AddMachine.");
+
+ FreeInfo(info);
+ free(name);
+ return DM_NORMAL;
+}
-/*
- * Actually create the new Machine.
+/* Function Name: RealUpdateMachine
+ * Description: Performs the actual update of the machine data.
+ * Arguments: info - the information on the machine to update.
+ * junk - an UNUSED Boolean.
+ * Returns: none.
*/
-
- if ( (stat = sms_query("add_machine", CountArgs(args),
- args, Scream, NULL)) != 0)
- com_err(program_name, stat, " in AddMachine.");
- FreeInfo(info);
- return(DM_NORMAL);
+static void RealUpdateMachine(char **info, Bool junk)
+{
+ int stat;
+ char **args = AskMCDInfo(info, MACHINE, TRUE);
+ if (!args)
+ {
+ Put_message("Aborted.");
+ return;
+ }
+ if ((stat = do_mr_query("update_host", CountArgs(args), args, NULL, NULL)))
+ com_err(program_name, stat, " in UpdateMachine.");
+ else
+ Put_message("Machine successfully updated.");
}
/* Function Name: UpdateMachine
* Returns: DM_NORMAL.
*/
-/* ARGSUSED */
-int
-UpdateMachine(argc, argv)
-int argc;
-char **argv;
-{
- struct qelem *elem, *top;
- int stat;
- char **args, **info, temp_buf[BUFSIZ];
- Bool one_machine, update_it;
-
- elem = top = GetMCInfo( MACHINE, CanonicalizeHostname(argv[1]),
- (char *) NULL);
-
- one_machine = (QueueCount(top) == 1);
- while (elem != NULL) {
- info = (char **) elem->q_data;
- if (one_machine)
- update_it = TRUE;
- else {
- sprintf(temp_buf, "Update %s (y/n/q) ? ", info[M_NAME]);
- switch(YesNoQuitQuestion(temp_buf, FALSE)) {
- case TRUE:
- update_it = TRUE;
- break;
- case FALSE:
- update_it = FALSE;
- break;
- default:
- Put_message("Aborting...");
- FreeQueue(top);
- return(DM_NORMAL);
- }
- }
- if (update_it) {
- args = AskMCDInfo(info, MACHINE, TRUE);
- if ( (stat = sms_query("update_machine", CountArgs(args),
- args, Scream, NULL)) != 0)
- com_err(program_name, stat, " in UpdateMachine.");
- }
- elem = elem->q_forw;
- }
- FreeQueue(top);
- return(DM_NORMAL);
+int UpdateMachine(int argc, char **argv)
+{
+ struct mqelem *top;
+ char *tmpname;
+
+ tmpname = canonicalize_hostname(strdup(argv[1]));
+ top = GetMCInfo(MACHINE, tmpname, NULL);
+ QueryLoop(top, NullPrint, RealUpdateMachine, "Update the machine");
+
+ FreeQueue(top);
+ free(tmpname);
+ return DM_NORMAL;
}
/* Function Name: CheckAndRemoveFromCluster
* Description: This func tests to see if a machine is in a cluster.
* and if so then removes it
- * Arguments: name - name of the machine (already Canonocalized).
+ * Arguments: name - name of the machine (already Canonicalized).
* ask_user- query the user before removing if from clusters?
- * Returns: SMS_ERROR if machine left in a cluster, or sms_error.
+ * Returns: MR_ERROR if machine left in a cluster, or mr_error.
*/
-int
-CheckAndRemoveFromCluster(name, ask_user)
-char * name;
-Bool ask_user;
-{
- register int stat, ret_value;
- Bool delete_it;
- char *args[10], temp_buf[BUFSIZ], *ptr;
- struct qelem *top, *elem = NULL;
-
- ret_value = SUB_NORMAL;
- args[0] = name;
- args[1] = "*";
- stat = sms_query("get_machine_to_cluster_map", 2, args,
- StoreInfo, &elem);
- if (stat && stat != SMS_NO_MATCH) {
- com_err(program_name, stat, " in get_machine_to_cluster_map.");
- return(DM_NORMAL);
- }
- if (stat == 0) {
- elem = top = QueueTop(elem);
- if (ask_user) {
- sprintf(temp_buf, "%s is assigned to the following clusters.",
- name);
- Put_message(temp_buf);
- while (elem != NULL) {
- char **info = (char **) elem->q_data;
- Print(1, &info[MAP_CLUSTER], (char *) NULL);
- elem = elem->q_forw;
+int CheckAndRemoveFromCluster(char *name, Bool ask_user)
+{
+ int stat, ret_value;
+ Bool delete_it;
+ char *args[10], temp_buf[BUFSIZ], *ptr;
+ struct mqelem *top, *elem = NULL;
+
+ ret_value = SUB_NORMAL; /* initialize ret_value. */
+ args[0] = name;
+ args[1] = "*";
+ stat = do_mr_query("get_machine_to_cluster_map", 2, args, StoreInfo, &elem);
+ if (stat && stat != MR_NO_MATCH)
+ {
+ com_err(program_name, stat, " in get_machine_to_cluster_map.");
+ return DM_NORMAL;
+ }
+ if (stat == MR_SUCCESS)
+ {
+ elem = top = QueueTop(elem);
+ if (ask_user)
+ {
+ sprintf(temp_buf, "%s is assigned to the following clusters.", name);
+ Put_message(temp_buf);
+ Loop(top, (void (*)(char **)) PrintMCMap);
+ ptr = "Remove this machine from ** ALL ** these clusters?";
+ if (YesNoQuestion(ptr, FALSE) == TRUE) /* may return -1. */
+ delete_it = TRUE;
+ else
+ {
+ Put_message("Aborting...");
+ FreeQueue(top);
+ return SUB_ERROR;
}
- ptr = "Remove this machine from ** ALL ** these clusters?";
-
- if (YesNoQuestion(ptr, FALSE) == TRUE) /* may return -1. */
- delete_it = TRUE;
- else {
- Put_message("Aborting...");
- FreeQueue(top);
- return(SUB_ERROR);
+ }
+ else
+ delete_it = TRUE;
+
+ if (delete_it)
+ {
+ while (elem)
+ {
+ char **info = elem->q_data;
+ if ((stat = do_mr_query("delete_machine_from_cluster",
+ 2, info, NULL, NULL)))
+ {
+ ret_value = SUB_ERROR;
+ com_err(program_name, stat,
+ " in delete_machine_from_cluster.");
+ sprintf(temp_buf,
+ "Machine %s ** NOT ** removed from cluster %s.",
+ info[MAP_MACHINE], info[MAP_CLUSTER]);
+ Put_message(temp_buf);
+ }
+ elem = elem->q_forw;
}
}
- else
+ }
+ return ret_value;
+}
+
+/* Function Name: CheckAndRemoveCnames
+ * Description: This func tests to see if a machine has cnames,
+ * and if so then removes them.
+ * Arguments: name - name of the machine (already Canonicalized).
+ * ask_user- query the user before removing cnames?
+ * Returns: MR_ERROR if machine left with a cname, or mr_error.
+ */
+
+int CheckAndRemoveCnames(char *name, Bool ask_user)
+{
+ int stat, ret_value;
+ Bool delete_it;
+ char *args[10], temp_buf[BUFSIZ], *ptr;
+ struct mqelem *top, *elem = NULL;
+
+ ret_value = SUB_NORMAL;
+ args[0] = "*";
+ args[1] = name;
+ stat = do_mr_query("get_hostalias", 2, args, StoreInfo, &elem);
+ if (stat && stat != MR_NO_MATCH)
+ {
+ com_err(program_name, stat, " in get_hostalias.");
+ return DM_NORMAL;
+ }
+ if (stat == MR_SUCCESS)
+ {
+ elem = top = QueueTop(elem);
+ if (ask_user)
+ {
+ sprintf(temp_buf, "%s has the following cnames.", name);
+ Put_message(temp_buf);
+ Loop(top, (void (*)(char **)) PrintCname);
+ ptr = "Remove ** ALL ** these cnames?";
+ if (YesNoQuestion(ptr, FALSE) == TRUE) /* may return -1. */
delete_it = TRUE;
+ else
+ {
+ Put_message("Aborting...");
+ FreeQueue(top);
+ return SUB_ERROR;
+ }
+ }
+ else
+ delete_it = TRUE;
+
+ if (delete_it)
+ {
+ while (elem)
+ {
+ char **info = elem->q_data;
+ if ((stat = do_mr_query("delete_hostalias", 2, info,
+ NULL, NULL)))
+ {
+ ret_value = SUB_ERROR;
+ com_err(program_name, stat, " in delete_hostalias.");
+ sprintf(temp_buf,
+ "Cname %s ** NOT ** removed from host %s.",
+ info[0], info[1]);
+ Put_message(temp_buf);
+ }
+ elem = elem->q_forw;
+ }
+ }
+ }
+ return ret_value;
+}
+
+/* Function Name: RealDeleteMachine
+ * Description: Actually Deletes the Machine.
+ * Arguments: info - nescessary information stored as an array of char *'s
+ * one_machine - a boolean, true if there is only one item in
+ * the query.
+ * Returns: none.
+ */
- if (delete_it) {
- elem = top;
- while (elem != 0) {
- char **info = (char **) elem->q_data;
- if ( (stat = sms_query( "delete_machine_from_cluster",
- 2, info, Scream, NULL)) != 0) {
- ret_value = SUB_ERROR;
- com_err(program_name, stat,
- " in delete_machine_from_cluster.");
- sprintf(temp_buf,
- "Machine %s ** NOT ** removed from cluster %s.",
- info[MAP_MACHINE], info[MAP_CLUSTER]);
- Put_message(temp_buf);
+static void RealDeleteMachine(char **info, Bool one_machine)
+{
+ int stat;
+ char temp_buf[BUFSIZ];
+
+ sprintf(temp_buf, "Are you sure you want to delete the machine %s (y/n)? ",
+ info[M_NAME]);
+ if (!one_machine || Confirm(temp_buf))
+ {
+ if (CheckAndRemoveFromCluster(info[M_NAME], TRUE) != SUB_ERROR)
+ {
+ if (CheckAndRemoveCnames(info[M_NAME], TRUE) != SUB_ERROR)
+ {
+ if ((stat = do_mr_query("delete_host", 1,
+ &info[M_NAME], NULL, NULL)))
+ {
+ com_err(program_name, stat, " in DeleteMachine.");
+ sprintf(temp_buf, "%s ** NOT ** deleted.",
+ info[M_NAME]);
+ Put_message(temp_buf);
+ }
+ else
+ {
+ sprintf(temp_buf, "%s successfully Deleted.", info[M_NAME]);
+ Put_message(temp_buf);
}
- elem = elem->q_forw;
}
}
}
- return(ret_value);
}
/* Function Name: DeleteMachine
/* Perhaps we should remove the cluster if it has no machine now. */
-/* ARGSUSED */
-int
-DeleteMachine(argc, argv)
-int argc;
-char **argv;
-{
- int stat;
- Bool one_machine, delete_it = FALSE;
- char *name, temp_buf[BUFSIZ];
- struct qelem *top, *elem = NULL;
-
- name = CanonicalizeHostname(argv[1]);
- top = elem = GetMCInfo(MACHINE, name, (char *) NULL);
-
- one_machine = (QueueCount(top) == 1);
- while (elem != NULL) {
- char **info = (char **) elem->q_data;
- if (one_machine) {
- if(Confirm("Are you sure that you want to delete this machine?"))
- delete_it = TRUE;
- }
- else {
- sprintf(temp_buf, "Delete the machine %s (y/n/q)? ", info[M_NAME]);
- switch (YesNoQuitQuestion(temp_buf, FALSE)) {
- case TRUE:
- delete_it = TRUE;
- break;
- case FALSE:
- delete_it = FALSE;
- sprintf(temp_buf, "%s not Deleted.", info[M_NAME]);
- Put_message(temp_buf);
- break;
- default: /* quit. */
- Put_message("Aborting...");
- FreeQueue(top);
- return(DM_NORMAL);
- }
- }
- if (delete_it) {
- if (CheckAndRemoveFromCluster(info[M_NAME], TRUE) != SUB_ERROR) {
- if ( (stat = sms_query("delete_machine", 1,
- &info[M_NAME], Scream, NULL)) != 0) {
- com_err(program_name, stat, " in DeleteMachine.");
- sprintf(temp_buf, "%s ** NOT ** deleted.",
- info[M_NAME]);
- Put_message(temp_buf);
- }
- else {
- sprintf(temp_buf, "%s sucesfully Deleted.", info[M_NAME]);
- Put_message(temp_buf);
- }
- }
- }
- elem = elem->q_forw;
+int DeleteMachine(int argc, char **argv)
+{
+ struct mqelem *top;
+ char *tmpname;
+
+ tmpname = canonicalize_hostname(strdup(argv[1]));
+ top = GetMCInfo(MACHINE, tmpname, (char *) NULL);
+ QueryLoop(top, PrintMachInfo, RealDeleteMachine, "Delete the machine");
+ FreeQueue(top);
+ free(tmpname);
+ return DM_NORMAL;
+}
+
+
+/* Function Name: ShowCname
+ * Description: This function shows machine aliases
+ * Arguments: argc, argv - the alias argv[1], the real name in argv[2]
+ * Returns: DM_NORMAL.
+ */
+
+int ShowCname(int argc, char **argv)
+{
+ struct mqelem *top;
+ char *tmpalias, *tmpname;
+
+ tmpalias = partial_canonicalize_hostname(strdup(argv[1]));
+ tmpname = canonicalize_hostname(strdup(argv[2]));
+ top = GetMCInfo(CNAME, tmpalias, tmpname);
+ Put_message(""); /* blank line on screen */
+ Loop(top, ((void (*)(char **)) PrintCname));
+ FreeQueue(top);
+ return DM_NORMAL;
+}
+
+
+int AddCname(int argc, char **argv)
+{
+ int stat;
+ char *args[10];
+
+ args[0] = partial_canonicalize_hostname(strdup(argv[1]));
+ args[1] = canonicalize_hostname(strdup(argv[2]));
+ stat = do_mr_query("add_hostalias", 2, args, NULL, NULL);
+ switch (stat)
+ {
+ case MR_SUCCESS:
+ break;
+ case MR_EXISTS:
+ Put_message("That alias name is already in use.");
+ break;
+ case MR_PERM:
+ Put_message("Permission denied. "
+ "(Regular users can only add two aliases to a host.");
+ break;
+ default:
+ com_err(program_name, stat, " in add_hostalias");
}
- FreeQueue(top);
- return(DM_NORMAL);
+ return DM_NORMAL;
}
+
+int DeleteCname(int argc, char **argv)
+{
+ int stat;
+ char *args[10];
+
+ args[0] = partial_canonicalize_hostname(strdup(argv[1]));
+ args[1] = canonicalize_hostname(strdup(argv[2]));
+ stat = do_mr_query("delete_hostalias", 2, args, NULL, NULL);
+ if (stat)
+ com_err(program_name, stat, " in delete_hostalias");
+ return DM_NORMAL;
+}
+
+
/* Function Name: AddMachineToCluster
* Description: This function adds a machine to a cluster
* Arguments: argc, argv - The machine name is argv[1].
* Returns: DM_NORMAL.
*/
-/* ARGSUSED */
-int
-AddMachineToCluster(argc, argv)
-int argc;
-char ** argv;
-{
- int stat;
- char *machine, *cluster, temp_buf[BUFSIZ], *args[10];
- Bool add_it, one_machine, one_cluster;
- struct qelem * melem, *mtop, *celem, *ctop;
-
- machine = CanonicalizeHostname(argv[1]);
- cluster = argv[2];
-
- celem = ctop = GetMCInfo(CLUSTER, cluster, (char *) NULL);
- melem = mtop = GetMCInfo(MACHINE, machine, (char *) NULL);
-
- one_machine = (QueueCount(mtop) == 1);
- one_cluster = (QueueCount(ctop) == 1);
-
- while (melem != NULL) {
- char ** minfo = (char **) melem->q_data;
- while (celem != NULL) {
- char ** cinfo = (char **) celem->q_data;
- if (one_machine && one_cluster)
- add_it = TRUE;
- else {
- sprintf(temp_buf,"Add machine %s to cluster %s (y/n/q) ?",
- minfo[M_NAME], cinfo[C_NAME]);
- switch (YesNoQuitQuestion(temp_buf, FALSE)) {
+int AddMachineToCluster(int argc, char **argv)
+{
+ int stat;
+ char *machine, *cluster, temp_buf[BUFSIZ], *args[10];
+ Bool add_it, one_machine, one_cluster;
+ struct mqelem *melem, *mtop, *celem, *ctop;
+
+ machine = canonicalize_hostname(strdup(argv[1]));
+ if (strcasecmp(machine, argv[1]) && *argv[1] != '"')
+ {
+ sprintf(temp_buf, "Warning: '%s' canonicalized to '%s'.",
+ argv[1], machine);
+ Put_message(temp_buf);
+ }
+ cluster = argv[2];
+
+ celem = ctop = GetMCInfo(CLUSTER, cluster, NULL);
+ melem = mtop = GetMCInfo(MACHINE, machine, NULL);
+ free(machine);
+
+ one_machine = (QueueCount(mtop) == 1);
+ one_cluster = (QueueCount(ctop) == 1);
+
+ /* No good way to use QueryLoop() here, sigh */
+
+ while (melem)
+ {
+ char **minfo = melem->q_data;
+ while (celem)
+ {
+ char **cinfo = celem->q_data;
+ if (one_machine && one_cluster)
+ add_it = TRUE;
+ else
+ {
+ sprintf(temp_buf, "Add machine %s to cluster %s (y/n/q) ?",
+ minfo[M_NAME], cinfo[C_NAME]);
+ switch (YesNoQuitQuestion(temp_buf, FALSE))
+ {
case TRUE:
- add_it = TRUE;
- break;
+ add_it = TRUE;
+ break;
case FALSE:
- add_it = FALSE;
- break;
+ add_it = FALSE;
+ break;
default:
- Put_message("Aborting...");
- FreeQueue(ctop);
- FreeQueue(mtop);
- return(DM_NORMAL);
+ Put_message("Aborting...");
+ FreeQueue(ctop);
+ FreeQueue(mtop);
+ return DM_NORMAL;
}
}
- if (add_it) {
- args[0] = minfo[M_NAME];
- args[1] = cinfo[C_NAME];
- stat = sms_query("add_machine_to_cluster", 2, args,
- Scream, NULL);
- switch (stat) {
- case SMS_SUCCESS:
- break;
- case SMS_EXISTS:
- sprintf(temp_buf, "%s is already in cluster %s",
- minfo[M_NAME], cinfo[C_NAME]);
- Put_message(temp_buf);
- break;
+ if (add_it)
+ {
+ args[0] = minfo[M_NAME];
+ args[1] = cinfo[C_NAME];
+ stat = do_mr_query("add_machine_to_cluster", 2, args,
+ NULL, NULL);
+ switch (stat)
+ {
+ case MR_SUCCESS:
+ break;
+ case MR_EXISTS:
+ sprintf(temp_buf, "%s is already in cluster %s",
+ minfo[M_NAME], cinfo[C_NAME]);
+ Put_message(temp_buf);
+ break;
default:
- com_err(program_name, stat, " in AddMachineToCluster.");
- break;
+ com_err(program_name, stat, " in AddMachineToCluster.");
+ break;
}
}
- celem = celem->q_forw;
+ celem = celem->q_forw;
}
- celem = ctop; /* reset cluster element. */
- melem = melem->q_forw;
+ celem = ctop; /* reset cluster element. */
+ melem = melem->q_forw;
}
- FreeQueue(ctop);
- FreeQueue(mtop);
- return(DM_NORMAL);
+ FreeQueue(ctop);
+ FreeQueue(mtop);
+ return DM_NORMAL;
+}
+
+/* Function Name: RealRemoveMachineFromCluster
+ * Description: This function actually removes the machine from its
+ * cluster.
+ * Arguments: info - all information nescessary to perform the removal.
+ * one_map - True if there is only one case, and we should
+ * confirm.
+ * Returns: none.
+ */
+
+static void RealRemoveMachineFromCluster(char **info, Bool one_map)
+{
+ char temp_buf[BUFSIZ];
+ int stat;
+
+ sprintf(temp_buf, "Remove %s from the cluster %s",
+ info[MAP_MACHINE], info[MAP_CLUSTER]);
+ if (!one_map || Confirm(temp_buf))
+ {
+ if ((stat = do_mr_query("delete_machine_from_cluster", 2,
+ info, NULL, NULL)))
+ com_err(program_name, stat, " in delete_machine_from_cluster");
+ else
+ {
+ sprintf(temp_buf, "%s has been removed from the cluster %s.",
+ info[MAP_MACHINE], info[MAP_CLUSTER]);
+ Put_message(temp_buf);
+ }
+ }
+ else
+ Put_message("Machine not removed.");
}
/* Function Name: RemoveMachineFromCluster
* Returns: none.
*/
-/* ARGSUSED */
-int
-RemoveMachineFromCluster(argc, argv)
-int argc;
-char ** argv;
+int RemoveMachineFromCluster(int argc, char **argv)
{
- int stat;
- Bool remove_machine, one_item;
- struct qelem *top, *elem = NULL;
- char buf[BUFSIZ], * args[10];
-
- args[MAP_MACHINE] = CanonicalizeHostname(argv[1]);
- args[MAP_CLUSTER] = argv[2];
- args[MAP_END] = NULL;
+ struct mqelem *elem = NULL;
+ char buf[BUFSIZ], *args[10];
+ int stat;
+
+ args[MAP_MACHINE] = canonicalize_hostname(strdup(argv[1]));
+ if (strcasecmp(args[MAP_MACHINE], argv[1]) && *argv[1] != '"')
+ {
+ sprintf(buf, "Warning: '%s' canonicalized to '%s'.",
+ argv[1], args[MAP_MACHINE]);
+ Put_message(buf);
+ }
+ args[MAP_CLUSTER] = argv[2];
+ args[MAP_END] = NULL;
- stat = sms_query("get_machine_to_cluster_map", CountArgs(args), args,
+ stat = do_mr_query("get_machine_to_cluster_map", CountArgs(args), args,
StoreInfo, &elem);
- if (stat == SMS_NO_MATCH) {
- sprintf(buf, "The machine %s is not is the cluster %s.",
- args[MAP_MACHINE], args[MAP_CLUSTER]);
- Put_message(buf);
- return(DM_NORMAL);
+ if (stat == MR_NO_MATCH)
+ {
+ sprintf(buf, "The machine %s is not in the cluster %s.",
+ args[MAP_MACHINE], args[MAP_CLUSTER]);
+ Put_message(buf);
+ free(args[MAP_MACHINE]);
+ return DM_NORMAL;
}
- if (stat)
- com_err(program_name, stat, " in delete_machine_from_cluster");
+ if (stat != MR_SUCCESS)
+ com_err(program_name, stat, " in delete_machine_from_cluster");
- top = elem = QueueTop(elem);
- one_item = (QueueCount(top) == 1);
- while (elem != NULL) {
- char **info = (char **) elem->q_data;
- if (one_item)
- remove_machine = TRUE;
- else {
- sprintf(buf, "Remove %s from the cluster %s? (y/n/q)",
- info[MAP_MACHINE], info[MAP_CLUSTER]);
- switch (YesNoQuitQuestion(buf, FALSE)) {
- case TRUE:
- remove_machine = TRUE;
- break;
- case FALSE:
- remove_machine = FALSE;
- break;
- default:
- Put_message("Aborting");
- FreeQueue(top);
- return(DM_NORMAL);
- }
+ elem = QueueTop(elem);
+ QueryLoop(elem, PrintMCMap, RealRemoveMachineFromCluster,
+ "Remove this machine from this cluster");
+
+ FreeQueue(elem);
+ free(args[MAP_MACHINE]);
+ return DM_NORMAL;
+}
+
+/* ---------- Subnet Menu -------- */
+
+/* Function Name: ShowSubnetInfo
+ * Description: Gets information about a subnet given its name.
+ * Arguments: argc, argc - the name of the subnet in in argv[1].
+ * Returns: DM_NORMAL.
+ */
+
+int ShowSubnetInfo(int argc, char **argv)
+{
+ struct mqelem *top;
+
+ top = GetMCInfo(SUBNET, argv[1], (char *) NULL);
+ Loop(top, (void (*)(char **)) PrintSubnetInfo);
+ FreeQueue(top);
+ return DM_NORMAL;
+}
+
+/* Function Name: AddSubnet
+ * Description: Creates a new subnet.
+ * Arguments: argc, argv - the name of the new subnet is argv[1].
+ * Returns: DM_NORMAL.
+ */
+
+int AddSubnet(int argc, char **argv)
+{
+ char **args, *info[MAX_ARGS_SIZE], *name = argv[1];
+ int stat;
+
+ /*
+ * Check to see if this subnet already exists.
+ */
+ if (!ValidName(name))
+ return DM_NORMAL;
+
+ if ((stat = do_mr_query("get_subnet", 1, &name, NULL, NULL)) == MR_SUCCESS)
+ {
+ Put_message("This subnet already exists.");
+ return DM_NORMAL;
+ }
+ else if (stat != MR_NO_MATCH)
+ {
+ com_err(program_name, stat, " in AddSubnet.");
+ return DM_NORMAL;
+ }
+ if (!(args = AskMCDInfo(SetSubnetDefaults(info, name), SUBNET, FALSE)))
+ {
+ Put_message("Aborted.");
+ FreeInfo(info);
+ return DM_NORMAL;
+ }
+
+ /*
+ * Actually create the new Subnet.
+ */
+ if ((stat = do_mr_query("add_subnet", CountArgs(args), args, NULL, NULL)))
+ com_err(program_name, stat, " in AddSubnet.");
+
+ FreeInfo(info);
+ return DM_NORMAL;
+}
+
+/* Function Name: RealUpdateSubnet
+ * Description: This function actually performs the subnet update.
+ * Arguments: info - all information nesc. for updating the subnet.
+ * junk - an UNUSED boolean.
+ * Returns: none.
+ */
+
+static void RealUpdateSubnet(char **info, Bool junk)
+{
+ int stat;
+ char **args = AskMCDInfo(info, SUBNET, TRUE);
+ if (!args)
+ {
+ Put_message("Aborted.");
+ return;
+ }
+ if ((stat = do_mr_query("update_subnet", CountArgs(args), args, NULL, NULL)))
+ com_err(program_name, stat, " in UpdateSubnet.");
+ else
+ Put_message("Subnet successfully updated.");
+}
+
+/* Function Name: UpdateSubnet
+ * Description: This Function Updates a subnet
+ * Arguments: name of the subnet in argv[1].
+ * Returns: DM_NORMAL.
+ */
+
+int UpdateSubnet(int argc, char **argv)
+{
+ struct mqelem *top;
+ top = GetMCInfo(SUBNET, argv[1], NULL);
+ QueryLoop(top, NullPrint, RealUpdateSubnet, "Update the subnet");
+
+ FreeQueue(top);
+ return DM_NORMAL;
+}
+
+/* Function Name: RealDeleteSubnet
+ * Description: Actually performs the subnet deletion.
+ * Arguments: info - all information about this subnet.
+ * one_subnet - If true then there was only one subnet in
+ * the queue, and we should confirm.
+ * Returns: none.
+ */
+
+static void RealDeleteSubnet(char **info, Bool one_subnet)
+{
+ int stat;
+ char temp_buf[BUFSIZ];
+
+ sprintf(temp_buf,
+ "Are you sure the you want to delete the subnet %s (y/n) ?",
+ info[C_NAME]);
+ if (!one_subnet || Confirm(temp_buf))
+ {
+ if ((stat = do_mr_query("delete_subnet", 1, &info[C_NAME], NULL, NULL)))
+ {
+ com_err(program_name, stat, " in delete_subnet.");
+ sprintf(temp_buf, "Subnet %s ** NOT ** deleted.", info[C_NAME]);
+ Put_message(temp_buf);
+ }
+ else
+ {
+ sprintf(temp_buf, "subnet %s successfully deleted.",
+ info[C_NAME]);
+ Put_message(temp_buf);
}
- if (remove_machine)
- if ( (stat = sms_query("delete_machine_from_cluster", 2,
- info, Scream, NULL)) != 0 )
- com_err(program_name, stat,
- " in delete_machine_from_cluster");
- else {
- sprintf(buf, "%s has been removed from the cluster %s.",
- info[MAP_MACHINE], info[MAP_CLUSTER]);
- Put_message(buf);
- }
- elem = elem->q_forw;
}
- FreeQueue(top);
- return(DM_NORMAL);
+}
+
+/* Function Name: DeleteSubnet
+ * Description: This function removes a subnet from the database.
+ * Arguments: argc, argv - the name of the subnet is stored in argv[1].
+ * Returns: DM_NORMAL.
+ */
+
+int DeleteSubnet(int argc, char **argv)
+{
+ struct mqelem *top;
+
+ top = GetMCInfo(SUBNET, argv[1], NULL);
+ QueryLoop(top, PrintSubnetInfo, RealDeleteSubnet, "Delete the subnet");
+
+ FreeQueue(top);
+ return DM_NORMAL;
}
/* ---------- Cluster Menu -------- */
* Returns: DM_NORMAL.
*/
-/* ARGSUSED */
-int
-ShowClusterInfo(argc, argv)
-int argc;
-char ** argv;
+int ShowClusterInfo(int argc, char **argv)
{
- char **info;
- struct qelem *elem, *top;
+ struct mqelem *top;
- top = elem = GetMCInfo( CLUSTER, CanonicalizeHostname(argv[1]),
- (char *) NULL);
- while (elem != NULL) {
- info = (char **) elem->q_data;
- PrintClusterInfo(info);
- elem = elem->q_forw;
- }
- FreeQueue(top);
- return(DM_NORMAL);
+ top = GetMCInfo(CLUSTER, argv[1], NULL);
+ Loop(top, (void (*)(char **)) PrintClusterInfo);
+ FreeQueue(top);
+ return DM_NORMAL;
}
/* Function Name: AddCluster
* Returns: DM_NORMAL.
*/
-/* ARGSUSED */
-int
-AddCluster(argc, argv)
-int argc;
-char ** argv;
+int AddCluster(int argc, char **argv)
{
- char **args, *info[MAX_ARGS_SIZE], *name;
- int stat;
-/*
- * Check to see if this machine already exists.
- */
- name = argv[1];
-
- if ( (stat = sms_query("get_cluster", 1, &name, NullFunc, NULL)) == 0) {
- Put_message("This cluster already exists.");
- return(DM_NORMAL);
+ char **args, *info[MAX_ARGS_SIZE], *name = argv[1];
+ int stat;
+
+ /*
+ * Check to see if this cluster already exists.
+ */
+ if (!ValidName(name))
+ return DM_NORMAL;
+
+ if ((stat = do_mr_query("get_cluster", 1, &name, NULL, NULL)) == MR_SUCCESS)
+ {
+ Put_message("This cluster already exists.");
+ return DM_NORMAL;
+ }
+ else if (stat != MR_NO_MATCH)
+ {
+ com_err(program_name, stat, " in AddCluster.");
+ return DM_NORMAL;
}
- else if (stat != SMS_NO_MATCH) {
- com_err(program_name, stat, " in AddCluster.");
- return(DM_NORMAL);
+ if (!(args = AskMCDInfo(SetClusterDefaults(info, name), CLUSTER, FALSE)))
+ {
+ Put_message("Aborted.");
+ FreeInfo(info);
+ return DM_NORMAL;
}
- args = AskMCDInfo(SetClusterDefaults(info, name), CLUSTER, FALSE);
+ /*
+ * Actually create the new Cluster.
+ */
+ if ((stat = do_mr_query("add_cluster", CountArgs(args), args, NULL, NULL)))
+ com_err(program_name, stat, " in AddCluster.");
-/*
- * Actually create the new Cluster.
+ FreeInfo(info);
+ return DM_NORMAL;
+}
+
+/* Function Name: RealUpdateCluster
+ * Description: This function actually performs the cluster update.
+ * Arguments: info - all information nesc. for updating the cluster.
+ * junk - an UNUSED boolean.
+ * Returns: none.
*/
-
- if ( (stat = sms_query("add_cluster", CountArgs(args),
- args, Scream, NULL)) != 0)
- com_err(program_name, stat, " in AddCluster.");
- FreeInfo(info);
- return(DM_NORMAL);
+static void RealUpdateCluster(char **info, Bool junk)
+{
+ int stat;
+ char **args = AskMCDInfo(info, CLUSTER, TRUE);
+
+ if (!args)
+ {
+ Put_message("Aborted.");
+ return;
+ }
+ if ((stat = do_mr_query("update_cluster", CountArgs(args),
+ args, NULL, NULL)))
+ com_err(program_name, stat, " in UpdateCluster.");
+ else
+ Put_message("Cluster successfully updated.");
}
/* Function Name: UpdateCluster
* Returns: DM_NORMAL.
*/
-/* ARGSUSED */
-int
-UpdateCluster(argc, argv)
-int argc;
-char ** argv;
-{
- struct qelem *elem, *top;
- char **args, **info, temp_buf[BUFSIZ];
- int stat;
- Bool one_cluster, update_it;
-
- elem = top = GetMCInfo( CLUSTER, argv[1], (char *) NULL );
-
- one_cluster = (QueueCount(top) == 1);
- while (elem != NULL) {
- info = (char **) elem->q_data;
- if (one_cluster)
- update_it = TRUE;
- else {
- sprintf(temp_buf, "Update Cluster %s (y/n/q) ? ", info[C_NAME]);
- switch(YesNoQuitQuestion(temp_buf, FALSE)) {
- case TRUE:
- update_it = TRUE;
- break;
- case FALSE:
- update_it = FALSE;
- break;
- default:
- Put_message("Aborting...");
- FreeQueue(top);
- return(DM_NORMAL);
- }
- }
- if (update_it) {
- args = AskMCDInfo(info, CLUSTER, TRUE);
- if ( (stat = sms_query("update_cluster", CountArgs(args),
- args, Scream, NULL)) != 0)
- com_err(program_name, stat, " in UpdateCluster.");
- }
- elem = elem->q_forw;
- }
- FreeQueue(top);
- return(DM_NORMAL);
+int UpdateCluster(int argc, char **argv)
+{
+ struct mqelem *top;
+ top = GetMCInfo(CLUSTER, argv[1], NULL);
+ QueryLoop(top, NullPrint, RealUpdateCluster, "Update the cluster");
+
+ FreeQueue(top);
+ return DM_NORMAL;
}
/* Function Name: CheckAndRemoveMachine
* Returns: SUB_ERROR if all machines not removed.
*/
-int
-CheckAndRemoveMachines(name, ask_first)
-char * name;
-Bool ask_first;
-{
- register int stat, ret_value;
- Bool delete_it;
- char *args[10], temp_buf[BUFSIZ], *ptr;
- struct qelem *top, *elem = NULL;
-
- ret_value = SUB_NORMAL;
- args[MAP_MACHINE] = "*";
- args[MAP_CLUSTER] = name;
- stat = sms_query("get_machine_to_cluster_map", 2, args,
- StoreInfo, &elem);
- if (stat && stat != SMS_NO_MATCH) {
- com_err(program_name, stat, " in get_machine_to_cluster_map.");
- return(DM_NORMAL);
- }
- if (stat == 0) {
- elem = top = QueueTop(elem);
- if (ask_first) {
- sprintf(temp_buf,
- "The cluster %s has the following machines in it:",
- name);
- Put_message(temp_buf);
- while (elem != NULL) {
- char **info = (char **) elem->q_data;
- Print(1, &info[MAP_MACHINE], (char *) NULL);
- elem = elem->q_forw;
+int CheckAndRemoveMachines(char *name, Bool ask_first)
+{
+ int stat, ret_value;
+ Bool delete_it;
+ char *args[10], temp_buf[BUFSIZ], *ptr;
+ struct mqelem *top, *elem = NULL;
+
+ ret_value = SUB_NORMAL;
+ args[MAP_MACHINE] = "*";
+ args[MAP_CLUSTER] = name;
+ stat = do_mr_query("get_machine_to_cluster_map", 2, args, StoreInfo, &elem);
+ if (stat && stat != MR_NO_MATCH)
+ {
+ com_err(program_name, stat, " in get_machine_to_cluster_map.");
+ return DM_NORMAL;
+ }
+ if (stat == MR_SUCCESS)
+ {
+ elem = top = QueueTop(elem);
+ if (ask_first)
+ {
+ sprintf(temp_buf, "The cluster %s has the following machines in it:",
+ name);
+ Put_message(temp_buf);
+ while (elem)
+ {
+ char **info = elem->q_data;
+ Print(1, &info[MAP_MACHINE], (char *) NULL);
+ elem = elem->q_forw;
}
- ptr = "Remove ** ALL ** these machines from this cluster?";
-
- if (YesNoQuestion(ptr, FALSE) == TRUE) /* may return -1. */
- delete_it = TRUE;
- else {
- Put_message("Aborting...");
- FreeQueue(top);
- return(SUB_ERROR);
+ ptr = "Remove ** ALL ** these machines from this cluster?";
+
+ if (YesNoQuestion(ptr, FALSE) == TRUE) /* may return -1. */
+ delete_it = TRUE;
+ else
+ {
+ Put_message("Aborting...");
+ FreeQueue(top);
+ return SUB_ERROR;
}
}
- else
- delete_it = TRUE;
-
- if (delete_it) {
- elem = top;
- while (elem != 0) {
- char **info = (char **) elem->q_data;
- if ( (stat = sms_query( "delete_machine_from_cluster",
- 2, info, Scream, NULL)) != 0) {
- ret_value = SUB_ERROR;
- com_err(program_name, stat,
- " in delete_machine_from_cluster.");
- sprintf(temp_buf,
- "Machine %s ** NOT ** removed from cluster %s.",
- info[MAP_MACHINE], info[MAP_CLUSTER]);
- Put_message(temp_buf);
+ else
+ delete_it = TRUE;
+
+ if (delete_it)
+ {
+ elem = top;
+ while (elem)
+ {
+ char **info = elem->q_data;
+ if ((stat = do_mr_query("delete_machine_from_cluster",
+ 2, info, NULL, NULL)))
+ {
+ ret_value = SUB_ERROR;
+ com_err(program_name, stat,
+ " in delete_machine_from_cluster.");
+ sprintf(temp_buf,
+ "Machine %s ** NOT ** removed from cluster %s.",
+ info[MAP_MACHINE], info[MAP_CLUSTER]);
+ Put_message(temp_buf);
}
- elem = elem->q_forw;
+ elem = elem->q_forw;
}
}
}
- return(ret_value);
+ return ret_value;
}
+/* Function Name: RealDeleteCluster
+ * Description: Actually performs the cluster deletion.
+ * Arguments: info - all information about this cluster.
+ * one_cluster - If true then there was only one cluster in
+ * the queue, and we should confirm.
+ * Returns: none.
+ */
+
+static void RealDeleteCluster(char **info, Bool one_cluster)
+{
+ int stat;
+ char temp_buf[BUFSIZ];
+
+ sprintf(temp_buf,
+ "Are you sure the you want to delete the cluster %s (y/n) ?",
+ info[C_NAME]);
+ if (!one_cluster || Confirm(temp_buf))
+ {
+ if (CheckAndRemoveMachines(info[C_NAME], TRUE) != SUB_ERROR)
+ {
+ if ((stat = do_mr_query("delete_cluster", 1,
+ &info[C_NAME], NULL, NULL)))
+ {
+ com_err(program_name, stat, " in delete_cluster.");
+ sprintf(temp_buf, "Cluster %s ** NOT ** deleted.", info[C_NAME]);
+ Put_message(temp_buf);
+ }
+ else
+ {
+ sprintf(temp_buf, "cluster %s successfully deleted.",
+ info[C_NAME]);
+ Put_message(temp_buf);
+ }
+ }
+ }
+}
/* Function Name: DeleteCluster
* Description: This function removes a cluster from the database.
* Returns: DM_NORMAL.
*/
-/* ARGSUSED */
-int
-DeleteCluster(argc, argv)
-int argc;
-char ** argv;
-{
- char temp_buf[BUFSIZ];
- int stat;
- Bool one_cluster, delete_it = FALSE;
- struct qelem *elem, *top;
-
- top = elem = GetMCInfo( CLUSTER, argv[1], (char *) NULL );
-
- one_cluster = (QueueCount(top) == 1);
- while (elem != NULL) {
- char **info = (char **) elem->q_data;
- if (one_cluster) {
- if(Confirm("Are you sure that you want to delete this cluster?"))
- delete_it = TRUE;
- }
- else {
- PrintClusterInfo(info);
- sprintf(temp_buf, "Delete the cluster %s (y/n/q)? ", info[C_NAME]);
- switch (YesNoQuitQuestion(temp_buf, FALSE)) {
- case TRUE:
- delete_it = TRUE;
- break;
- case FALSE:
- delete_it = FALSE;
- sprintf(temp_buf, "%s not Deleted.", info[C_NAME]);
- Put_message(temp_buf);
- break;
- default: /* quit. */
- Put_message("Aborting...");
- FreeQueue(top);
- return(DM_NORMAL);
- }
- }
- if (delete_it) {
- if (CheckAndRemoveMachines(info[C_NAME], TRUE) != SUB_ERROR) {
- if ( (stat = sms_query("delete_cluster", 1,
- &info[C_NAME], Scream, NULL)) != 0) {
- com_err(program_name, stat, " in DeleteCluster.");
- sprintf(temp_buf, "Cluster %s ** NOT ** deleted.",
- info[C_NAME]);
- Put_message(temp_buf);
- }
- else {
- sprintf(temp_buf, "cluster %s sucesfully Deleted.",
- info[C_NAME]);
- Put_message(temp_buf);
- }
- }
- }
- elem = elem->q_forw;
- }
- FreeQueue(top);
- return(DM_NORMAL);
+int DeleteCluster(int argc, char **argv)
+{
+ struct mqelem *top;
+
+ top = GetMCInfo(CLUSTER, argv[1], NULL);
+ QueryLoop(top, PrintClusterInfo, RealDeleteCluster, "Delete the cluster");
+
+ FreeQueue(top);
+ return DM_NORMAL;
}
/* ----------- Cluster Data Menu -------------- */
* Returns: DM_NORMAL.
*/
-/* ARGSUSED */
-int
-ShowClusterData(argc, argv)
-int argc;
-char ** argv;
-{
- struct qelem *elem, *top;
- char **info;
-
- top = elem = GetMCInfo(DATA, argv[1], argv[2]);
- while (elem != NULL) {
- info = (char **) elem->q_data;
- PrintClusterData(info);
- elem = elem->q_forw;
+int ShowClusterData(int argc, char **argv)
+{
+ struct mqelem *elem, *top;
+ char **info;
+
+ top = elem = GetMCInfo(DATA, argv[1], argv[2]);
+ while (elem)
+ {
+ info = elem->q_data;
+ PrintClusterData(info);
+ elem = elem->q_forw;
}
- FreeQueue(top);
- return(DM_NORMAL);
+ FreeQueue(top);
+ return DM_NORMAL;
}
/* Function Name: AddClusterData
* Returns: DM_NORMAL.
*/
-/* ARGSUSED */
-int
-AddClusterData(argc, argv)
-int argc;
-char ** argv;
-{
- int stat;
+int AddClusterData(int argc, char **argv)
+{
+ int stat, i;
+
+ for (i = 1; i < 4; i++)
+ {
+ if (IS_EMPTY(argv[i]))
+ {
+ Put_message("Cluster data cannot be an empty string.");
+ return DM_NORMAL;
+ }
+ }
+ if ((stat = do_mr_query("add_cluster_data", 3, argv + 1, NULL, NULL)))
+ com_err(program_name, stat, " in AddClusterData.");
+ return DM_NORMAL;
+}
- if( (stat = sms_query("add_cluster_data", 3, argv + 1,
- Scream, (char *) NULL)) != 0)
- com_err(program_name, stat, " in AddClusterData.");
+/* Function Name: RealRemoveClusterData
+ * Description: actually removes the cluster data.
+ * Arguments: info - all info necessary to remove the cluster, in an array
+ * of strings.
+ * one_item - if true then the queue has only one elem and we
+ * should confirm.
+ * Returns: none.
+ */
+static void RealRemoveClusterData(char **info, Bool one_item)
+{
+ int stat;
+ char *temp_ptr;
+
+ Put_message(" ");
+ temp_ptr = "Are you sure that you want to remove this cluster data (y/n) ?";
+ PrintClusterData(info);
+ if (!one_item || Confirm(temp_ptr))
+ {
+ if ((stat = do_mr_query("delete_cluster_data", 3, info, NULL, NULL)))
+ {
+ com_err(program_name, stat, " in DeleteClusterData.");
+ Put_message("Data not removed.");
+ }
+ else
+ Put_message("Removal successful.");
+ }
}
/* Function Name: RemoveClusterData
* Returns: DM_NORMAL.
*/
-/* ARGSUSED */
-int
-RemoveClusterData(argc, argv)
-int argc;
-char ** argv;
-{
- Bool one_piece_of_data, remove_it;
- int stat;
- struct qelem *elem, *top;
-
- top = elem = GetMCInfo(DATA, argv[1], argv[2]);
-
- one_piece_of_data = (QueueCount(elem) == 1);
- while (elem != NULL) {
- char **info = (char **) elem->q_data;
- if (one_piece_of_data) {
- if(Confirm("Do you really want to remove this data?"))
- remove_it = TRUE;
- else
- Put_message("Operation aborted.\n");
- }
- else {
- PrintClusterData(info);
- switch (YesNoQuitQuestion
- ("Remove this piece of cluster data (y/n/q) ? ", FALSE)) {
- case TRUE:
- remove_it = TRUE;
- break;
- case FALSE:
- remove_it = FALSE;
- break;
- default:
- Put_message("Aborting");
- FreeQueue(top);
- return(DM_NORMAL);
- }
- }
- if (remove_it) {
- if( (stat = sms_query("delete_cluster_data", 3, info,
- Scream, (char *) NULL)) != 0) {
- com_err(program_name, stat, " in DeleteClusterData.");
- Put_message("Data not removed.");
- }
- else
- Put_message("Removal sucessful.");
- }
- elem = elem->q_forw;
- }
- FreeQueue(top);
- return(DM_NORMAL);
-}
+int RemoveClusterData(int argc, char **argv)
+{
+ struct mqelem *top;
-/* Perhaps an interactive delete cluster data would be nice. */
+ top = GetMCInfo(DATA, argv[1], argv[2]);
+ QueryLoop(top, PrintClusterData, RealRemoveClusterData,
+ "Remove data from cluster");
+
+ FreeQueue(top);
+ return DM_NORMAL;
+}
/* Function Name: MachineToClusterMap
* Description: This Retrieves the mapping between machine and cluster
* Returns: none.
*/
-/* ARGSUSED */
-int
-MachineToClusterMap(argc,argv)
-int argc;
-char **argv;
+int MachineToClusterMap(int argc, char **argv)
{
- struct qelem *elem, *top;
-
- top = elem = GetMCInfo(MAP, CanonicalizeHostname(argv[1]), argv[2]);
-
- Put_message(""); /* blank line on screen */
- while (elem != NULL) {
- char ** info = (char **) elem->q_data;
- PrintMCMap(info);
- elem = elem->q_forw;
+ 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);
- return(DM_NORMAL);
+ FreeQueue(top);
+ free(tmpname);
+ return DM_NORMAL;
}
-/* Function Name: MachinesInCluster
- * Description: Shows all machines in a give cluster.
- * Arguments: argv, argc - name of cluster in argv[1].
- * Returns: 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.
*/
-/* ARGSUSED */
-int
-MachinesInCluster(argc, argv)
-int argc;
-char **argv;
-{
- char *info[10];
- info[0] = argv[0];
- info[2] = argv[1];
- info[1] = "*";
- return(MachineToClusterMap(3, info));
-}
-
-/*
- * Local Variables:
- * mode: c
- * c-indent-level: 4
- * c-continued-statement-offset: 4
- * c-brace-offset: -4
- * c-argdecl-indent: 4
- * c-label-offset: -4
- * End:
+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[1], *account_number;
+ int status;
+ struct mqelem *elem = NULL;
+
+ account_number = strdup("");
+ 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];
+ char *args[2];
+ struct mqelem *elem = NULL;
+ int stat;
+
+ Put_message("");
+ sprintf(buf, "Container: %-16s Public: %s", info[CON_NAME],
+ atoi(info[CON_PUBLIC]) ? "Yes" : "No");
+ Put_message(buf);
+ /* Do a get_container_list to see what the associated list is. */
+ args[0] = info[CON_NAME];
+ if (stat = do_mr_query("get_container_list", 1, args, StoreInfo, &elem))
+ {
+ if (stat != MR_NO_MATCH)
+ com_err(program_name, stat, " looking up container list");
+ }
+ else
+ {
+ sprintf(buf, "Container's associated list is: LIST %s",
+ ((char **)elem->q_data)[1]);
+ Put_message(buf);
+ FreeQueue(elem);
+ }
+ 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);
+ return "";
+}
+
+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)
+{
+ int stat;
+ char **args = AskMCDInfo(info, CONTAINER, TRUE);
+
+ if (!args)
+ {
+ Put_message("Aborted.");
+ return;
+ }
+ if ((stat = do_mr_query("update_container", CountArgs(args), args,
+ NULL, NULL)))
+ com_err(program_name, stat, " in UpdateContainer.");
+ else
+ Put_message("Container successfully updated.");
+}
+
+int DeleteContainer(int argc, char **argv)
+{
+ struct mqelem *top;
+
+ top = GetMCInfo(CONTAINER, argv[1], NULL);
+ QueryLoop(top, PrintClusterInfo, RealDeleteContainer,
+ "Delete the container");
+
+ FreeQueue(top);
+ return DM_NORMAL;
+}
+
+static void RealDeleteContainer(char **info, Bool one_container)
+{
+ int stat;
+ char temp_buf[BUFSIZ];
+
+ sprintf(temp_buf,
+ "Are you sure you want to delete the container %s (y/n) ?",
+ info[CON_NAME]);
+ if (!one_container || Confirm(temp_buf))
+ {
+ if (CheckAndRemoveMachinesFromContainer(info[CON_NAME], TRUE)
+ != SUB_ERROR)
+ {
+ if ((stat = do_mr_query("delete_container", 1, &info[CON_NAME],
+ NULL, NULL)))
+ {
+ com_err(program_name, stat, " in delete_container.");
+ sprintf(temp_buf, "Container %s ** NOT ** deleted.",
+ info[CON_NAME]);
+ Put_message(temp_buf);
+ }
+ else
+ {
+ sprintf(temp_buf, "Container %s successfully deleted.",
+ info[CON_NAME]);
+ Put_message(temp_buf);
+ }
+ }
+ }
+}
+
+int CheckAndRemoveMachinesFromContainer(char *name, Bool ask_first)
+{
+ int stat, ret_value;
+ Bool delete_it;
+ char *args[10], temp_buf[BUFSIZ], *ptr;
+ struct mqelem *top, *elem = NULL;
+
+ ret_value = SUB_NORMAL;
+ args[0] = name;
+ args[1] = "0";
+ stat = do_mr_query("get_machines_of_container", 2, args, StoreInfo,
+ &elem);
+ if (stat && stat != MR_NO_MATCH)
+ {
+ com_err(program_name, stat, " in get_machines_of_container");
+ return DM_NORMAL;
+ }
+ if (stat == MR_SUCCESS)
+ {
+ elem = top = QueueTop(elem);
+ if (ask_first)
+ {
+ sprintf(temp_buf,
+ "The container %s has the following machines in it:", name);
+ Put_message(temp_buf);
+ while (elem)
+ {
+ char **info = elem->q_data;
+ Print(1, &info[0], (char *) NULL);
+ elem = elem->q_forw;
+ }
+ ptr = "Remove ** ALL ** these machines from this container?";
+
+ if (YesNoQuestion(ptr, FALSE) == TRUE) /* may return -1. */
+ delete_it = TRUE;
+ else
+ {
+ Put_message("Aborting...");
+ FreeQueue(top);
+ return SUB_ERROR;
+ }
+ }
+ else
+ delete_it = TRUE;
+
+ if (delete_it)
+ {
+ elem = top;
+ while (elem)
+ {
+ char **info = elem->q_data;
+ if ((stat = do_mr_query("delete_machine_from_container",
+ 2, info, NULL, NULL)))
+ {
+ ret_value = SUB_ERROR;
+ com_err(program_name, stat,
+ " in delete_machine_from_container.");
+ sprintf(temp_buf,
+ "Machine %s ** NOT ** removed from container %s.",
+ info[0], info[1]);
+ Put_message(temp_buf);
+ }
+ elem = elem->q_forw;
+ }
+ }
+ }
+ return ret_value;
+}
+
+int GetSubContainers(int argc, char **argv)
+{
+ char *args[2];
+ struct mqelem *elem = NULL, *top = NULL;
+ int stat;
+
+ args[0] = argv[1];
+
+ if (YesNoQuestion("Do you want a recursive search?", TRUE) == TRUE)
+ args[1] = "1";
+ else
+ args[1] = "0";
+
+ if (stat = do_mr_query("get_subcontainers_of_container", 2, args,
+ StoreInfo, &elem))
+ com_err(program_name, stat, " in get_subcontainers_of_container");
+
+ top = QueueTop(elem);
+ Loop(top, ((void (*)(char **)) PrintContainer));
+ FreeQueue(top);
+ return DM_NORMAL;
+}
+
+int MachineToContainerMap(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(CONTMAP, tmpname, NULL);
+
+ Put_message("");
+ while (elem)
+ {
+ char **info = elem->q_data;
+ PrintMContMap(info);
+ elem = elem->q_forw;
+ }
+
+ FreeQueue(top);
+ free(tmpname);
+ return DM_NORMAL;
+}
+
+int AddMachineToContainer(int argc, char **argv)
+{
+ int stat;
+ char *machine, *container, temp_buf[BUFSIZ], *args[10];
+ Bool add_it, one_machine, one_container;
+ struct mqelem *melem, *mtop, *celem, *ctop;
+
+ machine = canonicalize_hostname(strdup(argv[1]));
+ if (strcasecmp(machine, argv[1]) && *argv[1] != '"')
+ {
+ sprintf(temp_buf, "Warning: '%s' canonicalized to '%s'.",
+ argv[1], machine);
+ Put_message(temp_buf);
+ }
+ container = argv[2];
+
+ celem = ctop = GetMCInfo(CONTAINER, container, NULL);
+ melem = mtop = GetMCInfo(MACHINE, machine, NULL);
+ free(machine);
+
+ one_machine = (QueueCount(mtop) == 1);
+ one_container = (QueueCount(ctop) == 1);
+
+ while (melem)
+ {
+ char **minfo = melem->q_data;
+ while (celem)
+ {
+ char **cinfo = celem->q_data;
+ if (one_machine && one_container)
+ add_it = TRUE;
+ else
+ {
+ sprintf(temp_buf, "Add machine %s to container %s (y/n/q) ?",
+ minfo[M_NAME], cinfo[CON_NAME]);
+ switch (YesNoQuestion(temp_buf, FALSE))
+ {
+ case TRUE:
+ add_it = TRUE;
+ break;
+ case FALSE:
+ add_it = FALSE;
+ break;
+ default:
+ Put_message("Aborting...");
+ FreeQueue(ctop);
+ FreeQueue(mtop);
+ return DM_NORMAL;
+ }
+ }
+ if (add_it)
+ {
+ args[0] = minfo[M_NAME];
+ args[1] = cinfo[CON_NAME];
+ stat = do_mr_query("add_machine_to_container", 2, args, NULL,
+ NULL);
+ switch (stat)
+ {
+ case MR_SUCCESS:
+ break;
+ case MR_EXISTS:
+ sprintf(temp_buf, "%s is already in container %s",
+ minfo[M_NAME], cinfo[CON_NAME]);
+ Put_message(temp_buf);
+ break;
+ default:
+ com_err(program_name, stat, " in AddMachineToContainer.");
+ break;
+ }
+ }
+ celem = celem->q_forw;
+ }
+ celem = ctop;
+ melem = melem->q_forw;
+ }
+ FreeQueue(ctop);
+ FreeQueue(mtop);
+ return DM_NORMAL;
+}
+
+int RemoveMachineFromContainer(int argc, char **argv)
+{
+ struct mqelem *elem = NULL;
+ char buf[BUFSIZ], *args[10];
+ int stat;
+
+ args[0] = canonicalize_hostname(strdup(argv[1]));
+ if (strcasecmp(args[0], argv[1]) && *argv[1] != '"')
+ {
+ sprintf(buf, "Warning: '%s' canonicalized to '%s'.",
+ argv[1], args[0]);
+ Put_message(buf);
+ }
+ args[1] = argv[2];
+ args[2] = NULL;
+
+ stat = do_mr_query("get_machine_to_container_map", 1, args, StoreInfo,
+ &elem);
+ if (stat == MR_NO_MATCH)
+ {
+ sprintf(buf, "The machine %s is not in the container %s.",
+ args[0], args[1]);
+ Put_message(buf);
+ free(args[0]);
+ return DM_NORMAL;
+ }
+ if (stat != MR_SUCCESS)
+ com_err(program_name, stat, " in deleter_machine_from_container");
+
+ elem = QueueTop(elem);
+ QueryLoop(elem, PrintMContMap, RealRemoveMachineFromContainer,
+ "Remove this machine from this container");
+
+ FreeQueue(elem);
+ free(args[0]);
+ return DM_NORMAL;
+}
+
+static void RealRemoveMachineFromContainer(char **info, Bool one_contmap)
+{
+ char temp_buf[BUFSIZ];
+ int stat;
+
+ sprintf(temp_buf, "Remove %s from the container %s",
+ info[0], info[1]);
+ if (!one_contmap || Confirm(temp_buf))
+ {
+ if ((stat = do_mr_query("delete_machine_from_container", 2,
+ info, NULL, NULL)))
+ com_err(program_name, stat, " in delete_machine_from_container");
+ else
+ {
+ sprintf(temp_buf, "%s has been removed from the container %s.",
+ info[0], info[1]);
+ Put_message(temp_buf);
+ }
+ }
+ else
+ Put_message("Machine not removed.");
+}
+
+int GetMachinesOfContainer(int argc, char **argv)
+{
+ char *args[2];
+ struct mqelem *elem = NULL, *top = NULL;
+ int stat;
+
+ args[0] = argv[1];
+ if (YesNoQuestion("Do you want a recursive search?", TRUE) == TRUE)
+ args[1] = "1";
+ else
+ args[1] = "0";
+ if (stat = do_mr_query("get_machines_of_container", 2, args,
+ StoreInfo, &elem))
+ com_err(program_name, stat, " in get_machines_of_container");
+
+ top = QueueTop(elem);
+ Loop(top, ((void (*)(char **)) PrintMContMap));
+ FreeQueue(top);
+ return DM_NORMAL;
+}
+
+int GetTopLevelCont(int argc, char **argv)
+{
+ int status;
+ struct mqelem *elem = NULL;
+ if (status = do_mr_query("get_toplevel_containers", 0, NULL, StoreInfo,
+ &elem))
+ {
+ com_err(program_name, status, " in get_toplevel_containers");
+ return DM_NORMAL;
+ }
+ Loop(QueueTop(elem), (void(*)(char **)) PrintContainer);
+ FreeQueue(elem);
+ return DM_NORMAL;
+}