Telstra has revealed the addition of almost one million new mobile services in the six months to December 2011, but Sensis revenues plummeted 24 percent in 12 months.
read more
David M Williams
Tuesday, 11 December 2007 03: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 (' ');
}
Loading comments ...

|
Microsoft Office 365Try an easy-to-use set of web-enabled tools for business-class productivity services. Office 365 provides anywhere-access to email, important documents, contacts, and calendars on almost any device. |