#include <mit-copyright.h>
#include <moira.h>
#include <moira_site.h>
+#include <mrclient.h>
#include "defs.h"
#include "f_defs.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);
-char *partial_canonicalize_hostname(char *s);
-#define MACHINE 0
-#define CLUSTER 1
-#define DATA 2
-#define MAP 3
-#define SUBNET 4
-#define CNAME 5
+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
"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];
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 -------------------- */
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_OWNER_NAME] = strdup("NONE");
info[M_ACOMMENT] = strdup("");
info[M_OCOMMENT] = strdup("");
- info[15] = info[16] = NULL;
+ info[17] = info[18] = NULL;
return info;
}
return info;
}
+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.
{
char buf[256];
- info[C_NAME] = strdup(name);
+ 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")));
{
char buf[BUFSIZ], tbuf[256];
char *args[3];
- struct mqelem *elem = NULL;
+ struct mqelem *elem = NULL, *elem2 = NULL;
int stat;
Put_message("");
MacState(atoi(info[M_STAT])), info[M_STAT_CHNG]);
Put_message(buf);
Put_message("");
-
- sprintf(buf, "Vendor: %-16s Model: %-20s OS: %s",
- info[M_VENDOR], info[M_MODEL], info[M_OS]);
+ 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, "Location: %-16s Contact: %-20s Opt: %s",
- info[M_LOC], info[M_CONTACT], info[M_USE]);
+ sprintf(buf, "OS: %-16s Billing Contact: %s", info[M_OS],
+ info[M_BILL_CONTACT]);
Put_message(buf);
- sprintf(buf, "\nAdm cmt: %s", info[M_ACOMMENT]);
+ 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(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.
+ */
+
+static void PrintMachine(char **info)
+{
+ char buf[BUFSIZ];
+
+ 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.
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]));
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);
}
* type - type of information - MACHINE
* CLUSTER
* DATA
+ * CONTAINER
* name - T/F : change the name of this type.
* Returns: none.
*/
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);
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;
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 (name)
{
/* info did not come from SetMachineDefaults(), which does not
- * initialize entry 8 (M_STAT_CHNG), therefore we can
+ * 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[8]);
+ free(info[10]);
}
- info[8] = info[M_SUBNET];
- info[9] = info[M_ADDR];
- info[10] = info[M_OWNER_TYPE];
- info[11] = info[M_OWNER_NAME];
- info[12] = info[M_ACOMMENT];
- info[13] = info[M_OCOMMENT];
+ 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[8])
+ if (GetValueFromUser("Machine's network (or 'none')", &info[10])
== SUB_ERROR)
return NULL;
}
if (GetValueFromUser("Machine's address (or 'unassigned' or 'unique')",
- &info[9]) == SUB_ERROR)
+ &info[11]) == SUB_ERROR)
return NULL;
- if (GetTypeFromUser("Machine's owner type", "ace_type", &info[10]) ==
+ if (GetTypeFromUser("Machine's owner type", "ace_type", &info[12]) ==
SUB_ERROR)
return NULL;
- if (strcmp(info[10], "NONE") &&
- GetValueFromUser("Owner's Name", &info[11]) == SUB_ERROR)
+ if (strcmp(info[12], "NONE") &&
+ GetValueFromUser("Owner's Name", &info[13]) == SUB_ERROR)
return NULL;
- if (GetValueFromUser("Administrative comment", &info[12]) == SUB_ERROR)
+ 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[13]) == SUB_ERROR)
+ if (GetValueFromUser("Operational comment", &info[15]) == SUB_ERROR)
return NULL;
- info[14] = NULL;
- FreeAndClear(&info[15], TRUE);
- FreeAndClear(&info[16], TRUE);
+ 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)
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);
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;
}
/*
/* 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: MR_ERROR if machine left in a cluster, or mr_error.
*/
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
{
if (CheckAndRemoveFromCluster(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
+ if (CheckAndRemoveCnames(info[M_NAME], TRUE) != SUB_ERROR)
{
- sprintf(temp_buf, "%s successfully Deleted.", info[M_NAME]);
- Put_message(temp_buf);
+ 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);
+ }
}
}
}
}
-char *partial_canonicalize_hostname(char *s)
-{
- char buf[256], *cp;
- static char *def_domain = NULL;
-
- if (!def_domain)
- {
- if (mr_host(buf, sizeof(buf)) == MR_SUCCESS)
- {
- cp = strchr(buf, '.');
- if (cp)
- def_domain = strdup(++cp);
- }
- else
- {
- struct hostent *hp;
-#ifdef HAVE_UNAME
- struct utsname name;
- uname(&name);
- hp = gethostbyname(name.nodename);
-#else
- char name[256];
- gethostname(name, sizeof(name));
- name[sizeof(name)-1] = 0;
- hp = gethostbyname(name);
-#endif /* HAVE_UNAME */
- cp = strchr(hp->h_name, '.');
- if (cp)
- def_domain = strdup(++cp);
- }
- if (!def_domain)
- def_domain = "";
- }
-
- if (strchr(s, '.') || strchr(s, '*'))
- return s;
- sprintf(buf, "%s.%s", s, def_domain);
- free(s);
- return strdup(buf);
-}
-
-
/* Function Name: ShowCname
* Description: This function shows machine aliases
* Arguments: argc, argv - the alias argv[1], the real name in argv[2]
int RemoveMachineFromCluster(int argc, char **argv)
{
struct mqelem *elem = NULL;
- char buf[BUFSIZ], * args[10];
+ char buf[BUFSIZ], *args[10];
int stat;
args[MAP_MACHINE] = canonicalize_hostname(strdup(argv[1]));
StoreInfo, &elem);
if (stat == MR_NO_MATCH)
{
- sprintf(buf, "The machine %s is not is the cluster %s.",
+ sprintf(buf, "The machine %s is not in the cluster %s.",
args[MAP_MACHINE], args[MAP_CLUSTER]);
Put_message(buf);
free(args[MAP_MACHINE]);
int AddClusterData(int argc, char **argv)
{
- int stat;
+ 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;
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[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;
+}