A number of Australian employees of Hewlett-Packard are facing the loss of their jobs as the global computer giant looks to slash its worldwide workforce by up to 30,000.
read more
David M Williams
Tuesday, 11 December 2007 02:05
/*
* Simple menu program
*
* David M. Williams
*/
#include "menu.h"
// ----------------------------------------------------------------------------
int main (int argc, char **argv)
{
char *username;
char *password;
int access = -1;
ScriptTree theMenu = NULL;
#ifdef DISABLE_INTERRUPTS
signal (SIGINT, SIG_IGN);
#endif
username = (char *) malloc (sizeof (char) * 50);
password = (char *) malloc (sizeof (char) * 10);
// Ask for a login
login (username, password);
// Verify username and password, getting access level
if (verify (username, password, &access) < 0)
noAccess (username);
else
{
// Generate a list of menu options
buildMenu (access, &theMenu);
// Repeatedly display menu and process input
DoMenu (username, theMenu, 0);
// Tidy up
}
printf ("\nBye.\n");
free (username);
free (password);
Destroy (theMenu);
}
// ----------------------------------------------------------------------------
void clrscrn ()
{
#ifdef CLEAR_SCREEN
system ("/bin/clear");
#endif
}
// ----------------------------------------------------------------------------
void login (char *username, char *password)
{
char tempPassword [10];
clrscrn ();
#ifdef BANNER
if (strlen (BANNER) > 0)
puts (BANNER);
#endif
printf (" Login: ");
scanf ("%s", username);
#ifdef HIDE_PASSWORD
strcpy (tempPassword, getpass ("Password: "));
#else
printf ("Password: ");
scanf ("%s", tempPassword);
#endif
log ("Login attempt by %s\t%s\n", username, tempPassword);
strcpy (password, crypt (tempPassword, username));
}
// ----------------------------------------------------------------------------
void noAccess (char *username)
{
clrscrn ();
printf ("%s, you do not have permission to access this system\n"
"or your password was wrong.\n", username);
}
// ----------------------------------------------------------------------------
int verify (char *username, char *password, int *access)
{
FILE *fp;
int Found = 0;
char line [80];
char tempUser [50];
char tempPass [10];
int tempAccess;
*access = -1;
if ((fp = fopen (USERLIST, "r")) > 0)
{
while ((!Found) && (!feof (fp)))
{
fgets (line, 80, fp);
if ((line [0] != '\n') && (line [0] != '#'))
{
sscanf (line, "%s%s%d", tempUser, tempPass,
&tempAccess);
if ((strcmp (tempUser, username) == 0) &&
(strcmp (tempPass, password) == 0))
{
Found = 1;
*access = tempAccess;
}
}
}
fclose (fp);
}
else
log ("Cannot open %s\n", USERLIST);
log ("%s has an access level of %d\n", username, *access);
return *access;
}
// ----------------------------------------------------------------------------
void buildMenu (int access, ScriptTree *theMenu)
{
FILE *fp;
char *line;
char *line2;
char *scriptName;
char *LineType;
int userLevel;
int useSudo;
ScriptTree subMenu;
line = (char *) malloc (sizeof (char) * 80);
line2 = (char *) malloc (sizeof (char) * 80);
scriptName = (char *) malloc (sizeof (char) * 80);
LineType = (char *) malloc (sizeof (char) * 10);
subMenu = *theMenu;
if ((fp = fopen (MENULIST, "r")) > 0)
{
while (!feof (fp))
{
line [0] = '#';
while (((line [0] == '\n') || (line [0] == '#')) &&
(!feof (fp)))
fgets (line, 80, fp);
line2 [0] = '#';
while (((line2 [0] == '\n') || (line2 [0] == '#')) &&
(!feof (fp)))
fgets (line2, 80, fp);
if (!feof (fp))
{
sscanf (line, "%s", LineType);
if (strcmp (LineType, "Menu") == 0)
{
sscanf (line, "%s%d", LineType,
&userLevel);
if (userLevel <= access)
subMenu = AddMenu
(theMenu, line2);
}
else if (strcmp (LineType, "Submenu") == 0)
{
sscanf (line, "%s%d", LineType,
&userLevel);
if (userLevel <= access)
subMenu = AddMenu
(&subMenu, line2);
}
else if (strcmp (LineType, "Option") == 0)
{
sscanf (line, "%s%d%d%s", LineType,
&userLevel, &useSudo,
scriptName);
if (userLevel <= access)
AddNode (&subMenu, line2,
scriptName, useSudo);
}
}
}
fclose (fp);
}
else
log ("Cannot open %s\n", MENULIST);
#ifdef DEBUGGING
DumpMenu (0, *theMenu);
exit (0);
#endif
free (line);
free (line2);
free (scriptName);
free (LineType);
}
// ----------------------------------------------------------------------------
void DoMenu (char *username, ScriptTree theMenu, int InSub)
{
int DoExit = 0;
int userChoice;
int MenuItems;
while (!DoExit)
{
// Display the menu
MenuItems = DisplayMenu (theMenu, InSub);
// Get input
userChoice = getChoice (MenuItems);
// Process command
if (userChoice == 0)
DoExit = 1;
else
ProcessChoice (userChoice, theMenu, username, InSub);
}
}
// ----------------------------------------------------------------------------
ScriptTree AddMenu (ScriptTree *theMenu, char *ItemText)
{
// Make a new node
ScriptTree aNode;
aNode = (ScriptTree) malloc (sizeof (ScriptNode));
strcpy (aNode->MenuText, ItemText);
strcpy (aNode->ScriptName, "");
aNode->Next = NULL;
aNode->Submenu = NULL;
// Find the last node in the list and set its next pointer to this node.
if (*theMenu == NULL)
*theMenu = aNode;
else
{
ScriptTree iterator = *theMenu;
while (iterator->Submenu != NULL)
iterator = (void *) iterator->Submenu;
iterator->Submenu = aNode;
}
return aNode;
}
// ----------------------------------------------------------------------------
void AddNode (ScriptTree *theMenu, char *ItemText,
char *ScriptCommand, int UseSudo)
{
// Make a new node
ScriptTree aNode;
aNode = (ScriptTree) malloc (sizeof (ScriptNode));
strcpy (aNode->MenuText, ItemText);
strcpy (aNode->ScriptName, ScriptCommand);
aNode->RunAsRoot = UseSudo;
aNode->Next = NULL;
aNode->Submenu = NULL;
// Find the last node in the list and set its next pointer to this node.
if (*theMenu == NULL)
*theMenu = aNode;
else
{
ScriptTree iterator = *theMenu;
while (iterator->Next != NULL)
iterator = (void *) iterator->Next;
iterator->Next = aNode;
}
}
// ----------------------------------------------------------------------------
void Destroy (ScriptTree theMenu)
{
ScriptTree iterator = theMenu;
if (iterator != NULL)
{
Destroy (iterator->Next);
Destroy (iterator->Submenu);
free (iterator);
}
}
// ----------------------------------------------------------------------------
void DoCommand (char *username, char *ScriptName, int UseSudo)
{
char c = ' ';
char FullPath [PATH_MAX];
puts ("\n\n");
log ("%s is running %s %s sudo\n", username, ScriptName,
(UseSudo ? "with" : "without"));
if (strlen (ScriptName) > 0)
{
sprintf (FullPath, "%s/%s", SCRIPTSDIR, ScriptName);
if (fork () == 0)
{
#ifdef USE_EXECL
if (UseSudo)
execl (SUDO, SUDO, FullPath, NULL);
else
execl (FullPath, FullPath, NULL);
#else
if (UseSudo)
{
char SudoCmnd [PATH_MAX];
sprintf (SudoCmnd, "%s %s", SUDO, FullPath);
system (SudoCmnd);
}
else
system (FullPath);
#endif
exit (0);
}
#ifdef USE_EXECL
else
{
int status;
wait3 (&status, NULL, (struct rusage *) 0);
}
#endif
}
// Wait for a key to be pushed
printf ("\n\n\tPlease press return : ");
while (c != '\n')
c = getchar ();
}
// ----------------------------------------------------------------------------
void log (const char *format, ...)
{
#ifdef LOGGING_ENABLED
va_list args;
char logmsg [255];
FILE *fp;
time_t now;
char nowtime [30];
va_start (args, format);
vsprintf (logmsg, format, args);
if ((fp = fopen (LOGFILE, "a")) > 0)
{
time (&now);
strcpy (nowtime, ctime (&now));
nowtime [strlen (nowtime) - 1] = '\0';
fprintf (fp, "%s\t%s", nowtime, logmsg);
fclose (fp);
}
va_end (args);
#endif
}
// ----------------------------------------------------------------------------
int DisplayMenu (ScriptTree theMenu, int InSub)
{
int MenuItems = 0;
ScriptTree iterator;
clrscrn ();
if (!InSub)
puts ("\tAdministrative services main menu");
else
printf ("\tAdministative sub-menu\n\t%s", theMenu->MenuText);
puts ("\n\n");
if (!InSub)
puts ("\t0)\tExit the program\n");
else
puts ("\t0)\tExit this menu level\n");
if (theMenu != NULL)
{
if (!InSub)
{
MenuItems = 1;
printf ("\t1)\t%s", theMenu->MenuText);
}
if (!InSub)
{
iterator = (void *) theMenu->Submenu;
while (iterator != NULL)
{
MenuItems++;
printf ("\t%d)\t%s", MenuItems,
iterator->MenuText);
iterator = (void *) iterator->Submenu;
}
}
else
{
iterator = (void *) theMenu->Next;
while (iterator != NULL)
{
MenuItems++;
printf ("\t%d)\t%s", MenuItems,
iterator->MenuText);
iterator = (void *) iterator->Next;
}
}
}
return MenuItems;
}
// ----------------------------------------------------------------------------
int getChoice (int MenuItems)
{
int userChoice = -1;
char temp [5];
char c = ' ';
do
{
printf ("\n\t\tChoice (0-%d) : ", MenuItems);
scanf ("%s", temp);
userChoice = atoi (temp);
} while ((userChoice < 0) || (userChoice > MenuItems));
// Consume all remaining input
while (c != '\n')
c = getchar ();
return userChoice;
}
// ----------------------------------------------------------------------------
void ProcessChoice (int userChoice, ScriptTree theMenu, char *username,
int InSub)
{
int itemNum = 0;
ScriptTree iterator = theMenu;
ScriptTree theChoice = NULL;
if (!InSub)
{
if (userChoice == 1)
theChoice = theMenu;
else
itemNum = 1;
}
if ((theChoice == NULL) && (!InSub))
{
iterator = (void *) theMenu->Submenu;
while ((iterator != NULL) && (theChoice == NULL))
{
itemNum++;
if (userChoice == itemNum)
theChoice = iterator;
else
iterator = (void *) iterator->Submenu;
}
}
if ((theChoice == NULL) && (InSub))
{
iterator = (void *) theMenu->Next;
while ((iterator != NULL) && (theChoice == NULL))
{
itemNum++;
if (userChoice == itemNum)
theChoice = iterator;
else
iterator = (void *) iterator->Next;
}
}
if (theChoice == NULL)
puts ("\nInvalid choice.\n");
else
{
if (strcmp (theChoice->ScriptName, "") != 0)
DoCommand (username, theChoice->ScriptName,
theChoice->RunAsRoot);
else
DoMenu (username, theChoice, 1);
}
}
// ----------------------------------------------------------------------------
void DumpMenu (int level, ScriptTree theMenu)
{
ScriptTree iterator;
if (theMenu != NULL)
{
indent (level);
printf ("%d\t%s", level, theMenu->MenuText);
level++;
iterator = (void *) theMenu->Next;
while (iterator != NULL)
{
indent (level);
printf ("%d\t%s", level, iterator->MenuText);
iterator = (void *) iterator->Next;
}
level--;
iterator = (void *) theMenu->Submenu;
while (iterator != NULL)
{
DumpMenu (level, iterator);
iterator = (void *) iterator->Submenu;
}
}
}
// ----------------------------------------------------------------------------
void indent (int level)
{
int i;
for (i = 0; i < level * 2; i++)
putchar (' ');
}
Think again. Most businesses only have PART of a DR plan - and this spells business disaster in the event of an IT disaster.
Download The Seven Sins of Disaster Recovery White Paper now and find out how you can prevent this happening to you.