static char rcsid_module_c[] = "$Header$";
#endif lint
-/* This is the file utils.c for allmaint, the SMS client that allows
- * a user to maintaint most important parts of the SMS database.
- * It Contains: Many utilities used by allmaint.
+/* This is the file utils.c for the SMS Client, which allows a nieve
+ * user to quickly and easily maintain most parts of the SMS database.
+ * It Contains: Many useful utility functions.
*
* Created: 4/25/88
* By: Chris D. Peterson
* $Author$
* $Header$
*
- * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ * Copyright 1988 by the Massachusetts Institute of Technology.
*
* For further information on copyright and distribution
* see the file mit-copyright.h
*/
-
#include <stdio.h>
#include <strings.h>
#include <sms.h>
+#include <sms_app.h>
#include <menu.h>
+#include <ctype.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"
#include <netdb.h> /* for gethostbyname. */
-/* #include <ctype.h> */
-/* #include <varargs.h> */
-/* #include <sys/types.h> */
+
+/* Function Name: AddQueue
+ * Description: Adds an element to a queue
+ * Arguments: elem, pred - element and its predecessor.
+ * Returns: none.
+ */
+
+static void
+AddQueue(elem, pred)
+struct qelem * elem, *pred;
+{
+ if (pred == NULL) {
+ elem->q_forw = NULL;
+ elem->q_back = NULL;
+ return;
+ }
+ elem->q_back = pred;
+ elem->q_forw = pred->q_forw;
+ pred->q_forw = elem;
+}
+
+/* Function Name: RemoveQueue
+ * Description: removes an element from a queue.
+ * Arguments: elem.
+ * Returns: none.
+ */
+
+static void
+RemoveQueue(elem)
+struct qelem *elem;
+{
+ if (elem->q_forw != NULL)
+ (elem->q_forw)->q_back = elem->q_back;
+ if (elem->q_back != NULL)
+ (elem->q_back)->q_forw = elem->q_forw;
+}
/* Function Name: FreeInfo
* Description: Frees all elements of a NULL terminated arrary of char*'s
* Returns: none
*/
-void
+static void
FreeQueueElem(elem)
struct qelem * elem;
{
}
}
-/* Function Name: AddQueue
- * Description: Adds an element to a queue
- * Arguments: elem, pred - element and its predecessor.
- * Returns: none.
- */
-
-AddQueue(elem, pred)
-struct qelem * elem, *pred;
-{
- if (pred == NULL) {
- elem->q_forw = NULL;
- elem->q_back = NULL;
- return;
- }
- elem->q_back = pred;
- elem->q_forw = pred->q_forw;
- pred->q_forw = elem;
-}
-
-/* Function Name: RemoveQueue
- * Description: removes an element from a queue.
- * Arguments: elem.
- * Returns: none.
- */
-
-RemoveQueue(elem)
-struct qelem *elem;
-{
- if (elem->q_forw != NULL)
- (elem->q_forw)->q_back = elem->q_back;
- if (elem->q_back != NULL)
- (elem->q_back)->q_forw = elem->q_forw;
-}
-
/* Function Name: QueueCount
* Description: Counts the number of elements in a queue
* Arguments: elem - any element in the queue.
return(count);
}
+/* Function Name: StoreInfo
+ * Description: Stores information from an sms query into a queue.
+ * Arguments: argc, argv, - information returned from the query returned
+ * in argv.
+ * data - the previous element on the queue, this data will be
+ * stored in a qelem struct immediatly after this elem.
+ * If NULL then a new queue will be created. This value
+ * is updated to the current element at the end off the
+ * call.
+ * Returns: SMS_CONT, or SMS_ABORT if it has problems.
+ */
+
int
StoreInfo(argc, argv, data)
int argc;
(void) sprintf(tmp, "%s [%s]: ", prompt, def ? def : "");
ans = Prompt_input(tmp, buf, buflen);
+ if (ans == 0) {
+ if (YesNoQuestion("Are you sure you want to exit", 1)) {
+ Cleanup_menu();
+ exit(0);
+ }
+ Put_message("Continuing input...");
+ return(PromptWithDefault(prompt, buf, buflen, def));
+ }
if (IS_EMPTY(buf))
(void) strcpy(buf, def);
+ else if (!strcmp(buf, "\"\""))
+ *buf = 0;
return(ans);
}
char *prompt;
int bool_def;
{
- char ans;
+ char ans[2];
while (TRUE) {
- if (!PromptWithDefault(prompt, &ans, 1, bool_def ? "y" : "n"))
+ if (!PromptWithDefault(prompt, ans, 2, bool_def ? "y" : "n"))
return(-1);
- switch (ans) {
+ switch (ans[0]) {
case 'n':
case 'N':
return(FALSE);
char *prompt;
int bool_def;
{
- char ans;
+ char ans[2];
while (TRUE) {
- if (!PromptWithDefault(prompt, &ans, 1, bool_def ? "y" : "n"))
+ if (!PromptWithDefault(prompt, ans, 2, bool_def ? "y" : "n"))
return(-1);
- switch (ans) {
+ switch (ans[0]) {
case 'n':
case 'N':
return(FALSE);
* Returns: TRUE/FALSE - wether or not the confirmation occured.
*/
-int
+Bool
Confirm(prompt)
char * prompt;
{
- return( !verbose || YesNoQuestion(prompt,FALSE) );
+ return( !verbose || (YesNoQuestion(prompt,FALSE) == TRUE) );
}
/* Function Name: ValidName
Bool
ValidName(s)
- char *s;
+char *s;
{
if (IS_EMPTY(s))
Put_message("Please use a non-empty name.");
* big way.
*/
+void
SlipInNewName(info, name)
char ** info;
char * name;
* Arguments: prompt - prompt for user.
* pointer - pointer to default value, will be returned
* as new value.
- * Returns: none.
+ * Returns: SUB_ERROR if break hit (^C).
*/
-void
+int
GetValueFromUser(prompt, pointer)
char * prompt, ** pointer;
{
char buf[BUFSIZ];
- PromptWithDefault(prompt, buf, BUFSIZ, *pointer);
- if (*pointer != NULL)
- free(*pointer);
- *pointer = Strsave(buf);
-}
+ if (PromptWithDefault(prompt, buf, BUFSIZ, *pointer) == -1)
+ return(SUB_ERROR);
-/* Function Name: CanonicalizeHostname
- * Description: This function takes a machine name and canonicalize's it.
- * Arguments: machine - name of the machine to work on.
- * Returns: new name or NULL if nameserver returns error
+/*
+ * If these are the same then there is no need to allocate a new string.
+ *
+ * a difference that makes no difference, IS no difference.
*/
-char *
-CanonicalizeHostname(machine)
-char *machine;
-{
- struct hostent *hostinfo;
-
- hostinfo = gethostbyname(machine);
-/* If this fails then we just return what we were passed. */
- if (hostinfo != (struct hostent *) NULL)
- machine = hostinfo->h_name;
- return (machine);
+ if (strcmp(buf, *pointer) != 0) {
+ if (*pointer != NULL)
+ free(*pointer);
+ *pointer = Strsave(buf);
+ }
+ return(SUB_NORMAL);
}
-/* Function Name: Strsave
- * Description: save a string.
- * Arguments: string - the string to save.
- * Returns: The malloced string, now safely saved, or NULL.
+/* Function Name: GetYesNoValueFromUser
+ * Description: This function gets a value from a user for the field
+ * specified.
+ * Arguments: prompt - prompt for user.
+ * pointer - pointer to default value, will be returned
+ * as new value.
+ * Returns: SUB_ERROR if break hit (^C).
*/
-char *
-Strsave(str)
-char *str;
+int
+GetYesNoValueFromUser(prompt, pointer)
+char * prompt, ** pointer;
{
- register char *newstr = malloc((unsigned) strlen(str) + 1);
+ char user_prompt[BUFSIZ];
+ Bool default_val;
- if (newstr == (char *) NULL)
- return ((char *) NULL);
+ if ( strcmp (*pointer, DEFAULT_YES) == 0 )
+ default_val = TRUE;
else
- return (strcpy(newstr, str));
+ default_val = FALSE;
+
+ sprintf(user_prompt, "%s (y/n)", prompt);
+
+ switch (YesNoQuestion(user_prompt, default_val)) {
+ case TRUE:
+ if (*pointer != NULL)
+ free(*pointer);
+ *pointer = Strsave(DEFAULT_YES);
+ break;
+ case FALSE:
+ if (*pointer != NULL)
+ free(*pointer);
+ *pointer = Strsave(DEFAULT_NO);
+ break;
+ case -1:
+ default:
+ return(SUB_ERROR);
+ }
+ return(SUB_NORMAL);
}
-/* Function Name: EncryptMITID
- * Description: Encrypts an mit ID number.
- * Arguments: sbuf - the buffer to return the encrypted number in.
- * idnumber - the id number (string).
- * first, last - name of the person.
- * Returns: none.
+/* Function Name: GetFSVal
+ * Description: asks about a specific filesystem value.
+ * Arguments: name - string for this type of filesystem.
+ * mask - mask for this type of filesystem.
+ * current - current filesystem state. (for defaults).
+ * new - new filesystem state.
+ * Returns: TRUE if successful.
*/
-void
-EncryptMITID(sbuf, idnumber, first, last)
-char *sbuf, *idnumber, *first, *last;
+static Bool
+GetFSVal(name, mask, current, new)
+char * name;
+int mask, current, *new;
{
- char salt[3];
- extern char *crypt();
-
-#define _tolower(c) ((c)|0x60)
+ char temp_buf[BUFSIZ];
+ sprintf(temp_buf, "Is this a %s filsystem", name);
+ switch (YesNoQuestion(temp_buf, ( (mask & current) == mask) )) {
+ case TRUE:
+ *new |= mask;
+ break;
+ case FALSE:
+ break; /* zero by default. */
+ default:
+ return(FALSE);
+ }
+ return(TRUE);
+}
- salt[0] = _tolower(last[0]);
- salt[1] = _tolower(first[0]);
- salt[2] = 0;
+/* Function Name: GetFSTypes
+ * Description: Allows user to specify filsystem types.
+ * Arguments: current - current value of filsystem, freed here.
+ * Returns: SUB_ERROR on ^C.
+ */
- (void) strcpy(sbuf, crypt(&idnumber[2], salt));
+int
+GetFSTypes(current)
+char ** current;
+{
+ int c_value, new_val = 0; /* current value of filesys type (int). */
+ char ret_value[BUFSIZ];
+
+ if (*current == NULL)
+ c_value = 0;
+ else
+ c_value = atoi(*current);
+
+ if (GetFSVal("student", SMS_FS_STUDENT, c_value, &new_val) == FALSE)
+ return(SUB_ERROR);
+ if (GetFSVal("faculty", SMS_FS_FACULTY, c_value, &new_val) == FALSE)
+ return(SUB_ERROR);
+ if (GetFSVal("staff", SMS_FS_STAFF, c_value, &new_val) == FALSE)
+ return(SUB_ERROR);
+ if (GetFSVal("miscellaneous", SMS_FS_MISC, c_value, &new_val) == FALSE)
+ return(SUB_ERROR);
+
+ FreeAndClear(current, TRUE);
+ sprintf(ret_value, "%d", new_val);
+ *current = Strsave(ret_value);
+ return(SUB_NORMAL);
}
-/* Function Name: RemoveHyphens
- * Description: Removes all hyphens from the string passed to it.
- * Arguments: str - the string to remove the hyphes from
- * Returns: none
+/* Function Name: Strsave
+ * Description: save a string.
+ * Arguments: string - the string to save.
+ * Returns: The malloced string, now safely saved, or NULL.
*/
-void
-RemoveHyphens(str)
+char *
+Strsave(str)
char *str;
{
- char *hyphen;
+ register char *newstr = malloc((unsigned) strlen(str) + 1);
- while ((hyphen = index(str, '-')) != NULL)
- (void) strcpy(hyphen, hyphen + 1);
+ if (newstr == (char *) NULL)
+ return ((char *) NULL);
+ else
+ return (strcpy(newstr, str));
}
/* Function Name: Print
if (callback == NULL)
return( Print(argc, argv, callback) );
if (strcmp(argv[0], callback) == 0)
- return( Print(1, argv + 1, callback) );
+ return( Print(argc, argv, callback) );
return(SMS_CONT);
}
PrintHelp(message)
char ** message;
{
- Print(CountArgs(message), message, (char *) NULL);
+ register int i;
+
+ for (i = 0; i < CountArgs(message); i++)
+ Put_message(message[i]);
+
return(DM_NORMAL);
}
Bool one_item;
char temp_buf[BUFSIZ], *name;
+ elem = QueueTop(elem);
one_item = (QueueCount(elem) == 1);
while (elem != NULL) {
char **info = (char **) elem->q_data;
(*op_func) (info, one_item);
else {
name = (*print_func) (info); /* call print function. */
- sprintf(temp_buf,"%s %s (y/n/q) ?", query_string, name);
+ sprintf(temp_buf,"%s %s (y/n/q)", query_string, name);
switch(YesNoQuitQuestion(temp_buf, FALSE)) {
case TRUE:
(*op_func) (info, one_item);
return(info[NAME]);
}
-/*
- * 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:
+
+/* Function Name: GetTypeValues
+ * Description: gets legal values for a typed object, keeping a cache
+ * Arguments: type name
+ * Returns: argv of values
*/
+
+struct qelem *
+GetTypeValues(tname)
+char *tname;
+{
+ int stat;
+ char *argv[3], *p, **pp, *strsave();
+ struct qelem *elem, *oelem;
+ static struct qelem *cache = NULL;
+ struct cache_elem { char *cache_name; struct qelem *cache_data; } *ce;
+
+ for (elem = cache; elem; elem = elem->q_forw) {
+ ce = (struct cache_elem *)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_sms_query("get_alias", 3, argv, StoreInfo, (char *)&elem)) {
+ com_err(program_name, stat, " in GetTypeValues");
+ return(NULL);
+ }
+ oelem = elem;
+ for (elem = QueueTop(elem); elem; elem = elem->q_forw) {
+ pp = (char **) elem->q_data;
+ p = strsave(pp[2]);
+ FreeInfo(pp);
+ elem->q_data = p;
+ }
+ elem = (struct qelem *) malloc(sizeof(struct qelem));
+ ce = (struct cache_elem *) malloc(sizeof(struct cache_elem));
+ ce->cache_name = tname;
+ ce->cache_data = QueueTop(oelem);
+ elem->q_data = (char *)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:
+ */
+
+GetTypeFromUser(prompt, tname, pointer)
+char *prompt;
+char *tname;
+char **pointer;
+{
+ char def[BUFSIZ], buffer[BUFSIZ], *p, *argv[3];
+ struct qelem *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);
+ GetValueFromUser(buffer, pointer);
+ 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 = strsave(def);
+ return(GetTypeFromUser(prompt, tname, pointer));
+ }
+ for (elem = GetTypeValues(tname); elem; elem = elem->q_forw) {
+ if (!cistrcmp(elem->q_data, *pointer))
+ 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) &&
+ YesNoQuestion(buffer, 0)) {
+ argv[0] = tname;
+ argv[1] = "TYPE";
+ argv[2] = *pointer;
+ for (p = argv[2]; *p; p++)
+ if (islower(*p))
+ *p = toupper(*p);
+ if (stat = do_sms_query("add_alias", 3, argv, Scream, NULL)) {
+ com_err(program_name, stat, " in add_alias");
+ } else {
+ elem = (struct qelem *) malloc(sizeof(struct qelem));
+ elem->q_data = strsave(*pointer);
+ AddQueue(elem, GetTypeValues(tname));
+ Put_message("Done.");
+ }
+ }
+ *pointer = strsave(def);
+ return(GetTypeFromUser(prompt, tname, pointer));
+}
+
+
+do_sms_query(name, argc, argv, proc, hint)
+char *name;
+int argc;
+char **argv;
+int (*proc)();
+char *hint;
+{
+ int status;
+ extern char *whoami;
+
+ status = sms_query(name, argc, argv, proc, hint);
+ if (status != SMS_ABORTED && status != SMS_NOT_CONNECTED)
+ return(status);
+ status = sms_connect(SMS_SERVER);
+ if (status) {
+ com_err(whoami, status, " while re-connecting to server");
+ return(SMS_ABORTED);
+ }
+ status = sms_auth(whoami);
+ if (status) {
+ com_err(whoami, status, " while re-authenticating to server");
+ sms_disconnect();
+ return(SMS_ABORTED);
+ }
+ status = sms_query(name, argc, argv, proc, hint);
+ return(status);
+}
+