+
+/* Function Name: GetTypeValues
+ * Description: gets legal values for a typed object, keeping a cache
+ * Arguments: type name
+ * Returns: argv of values
+ */
+
+struct mqelem *GetTypeValues(char *tname)
+{
+ int stat;
+ char *argv[3], *p, **pp;
+ struct mqelem *elem, *oelem;
+ static struct mqelem *cache = NULL;
+ struct cache_elem {
+ char *cache_name;
+ struct mqelem *cache_data;
+ } *ce;
+
+ for (elem = cache; elem; elem = elem->q_forw)
+ {
+ ce = elem->q_data;
+ if (!strcmp(ce->cache_name, tname))
+ return ce->cache_data;
+ }
+
+ argv[0] = tname;
+ argv[1] = "TYPE";
+ argv[2] = "*";
+ elem = NULL;
+ if ((stat = do_mr_query("get_alias", 3, argv, StoreInfo, &elem)))
+ {
+ com_err(program_name, stat, " in GetTypeValues");
+ return NULL;
+ }
+ oelem = elem;
+ for (elem = QueueTop(elem); elem; elem = elem->q_forw)
+ {
+ pp = elem->q_data;
+ p = strdup(pp[2]);
+ FreeInfo(pp);
+ elem->q_data = p;
+ }
+ elem = malloc(sizeof(struct mqelem));
+ ce = malloc(sizeof(struct cache_elem));
+ ce->cache_name = strdup(tname);
+ ce->cache_data = QueueTop(oelem);
+ elem->q_data = ce;
+ AddQueue(elem, cache);
+ cache = QueueTop(elem);
+ return ce->cache_data;
+}
+
+
+/* Function Name: GetTypeFromUser
+ * Description: gets a typed value from the user
+ * Arguments: prompt string, type name, buffer pointer
+ * Returns: SUB_ERROR if ^C, SUB_NORMAL otherwise
+ */
+
+int GetTypeFromUser(char *prompt, char *tname, char **pointer)
+{
+ char def[BUFSIZ], buffer[BUFSIZ], *p, *argv[3];
+ struct mqelem *elem;
+ int stat;
+
+ strcpy(def, *pointer);
+ strcpy(buffer, prompt);
+ strcat(buffer, " (");
+ for (elem = GetTypeValues(tname); elem; elem = elem->q_forw)
+ {
+ strcat(buffer, elem->q_data);
+ if (elem->q_forw)
+ strcat(buffer, ", ");
+ }
+ strcat(buffer, ")");
+ if (strlen(buffer) > 64)
+ sprintf(buffer, "%s (? for help)", prompt);
+ if (GetValueFromUser(buffer, pointer) == SUB_ERROR)
+ return SUB_ERROR;
+ if (**pointer == '?')
+ {
+ sprintf(buffer, "Type %s is one of:", tname);
+ Put_message(buffer);
+ for (elem = GetTypeValues(tname); elem; elem = elem->q_forw)
+ Put_message(elem->q_data);
+ *pointer = strdup(def);
+ return GetTypeFromUser(prompt, tname, pointer);
+ }
+ for (elem = GetTypeValues(tname); elem; elem = elem->q_forw)
+ {
+ if (!strcasecmp(elem->q_data, *pointer))
+ {
+ strcpy(*pointer, elem->q_data);
+ return SUB_NORMAL;
+ }
+ }
+ sprintf(buffer, "\"%s\" is not a legal value for %s. Use one of:",
+ *pointer, tname);
+ Put_message(buffer);
+ for (elem = GetTypeValues(tname); elem; elem = elem->q_forw)
+ Put_message(elem->q_data);
+ sprintf(buffer, "Are you sure you want \"%s\" to be a legal %s",
+ *pointer, tname);
+ if (YesNoQuestion("Do you want this to be a new legal value", 0) == TRUE &&
+ YesNoQuestion(buffer, 0) == TRUE)
+ {
+ argv[0] = tname;
+ argv[1] = "TYPE";
+ argv[2] = *pointer;
+ /* don't uppercase access flags. Do uppercase everything else */
+ if (strncmp(tname, "fs_access", 9))
+ {
+ for (p = argv[2]; *p; p++)
+ {
+ if (islower(*p))
+ *p = toupper(*p);
+ }
+ }
+ if ((stat = do_mr_query("add_alias", 3, argv, NULL, NULL)))
+ com_err(program_name, stat, " in add_alias");
+ else
+ {
+ elem = malloc(sizeof(struct mqelem));
+ elem->q_data = strdup(*pointer);
+ AddQueue(elem, GetTypeValues(tname));
+ Put_message("Done.");
+ }
+ }
+ *pointer = strdup(def);
+ return GetTypeFromUser(prompt, tname, pointer);
+}
+
+
+/* Function Name: GetAddressFromUser
+ * Description: gets an IP address from the user
+ * Arguments: prompt string, buffer pointer
+ * buffer contains default value as long int
+ * Returns: SUB_ERROR if ^C, SUB_NORMAL otherwise