[Subject Prev][Subject Next][Thread Prev][Thread Next][Subject Index][Thread Index]
Fwd: Re: Shell-Creation. A simulation Code
Hi Madhu,
Please see the attached code of a very basic simulated shell which i had
written two yrs ago... It is just a basic code to make u understand.
I have mined this code from my old data CD and it is working at least. Still I
am in search of the code which is a complete shell (clone of csh) and written
by me in the early last year. As soon as I get it, I will give u the code.
Please compile the file using
$gcc sunix.c
under bash ... Linux
Please don't use Wall to compile as it will give u hell warning .... Currently
I don't have time to remove those :>)
Thanx
Archan Paul
Lateral Linux Labs
archanp@xxxxxxxxxxx
PS. Thaths, Please allow this mail to be posted in the list along with
attachment. :)
On Tue, 22 Aug 2000, you wrote:
> hi madhu
> i've a very simple, crude, barebones program that does a sort of
> create a shell. i remember i used it to escape the command logging by bash
> and also the display of commands by w.it's old and uses gets() which u r
> not supposed to.
> --------start of program------
> #include<stdio.h>
> void main()
> {
> do {
> printf("command:>");
> gets(str);
> if (strcmp(str,"exit")==0)
> exit(0);
> system(str);
> } while 1;
> }
> --------end------------
> me thinks it works( it worked long ago) , but i dont know if it
> has mistakes. *BUT YOU CANNOT USE ANY INTERNAL COMMANDS !!!!!! *. means
> cd also wont work ! hope this gives u the idea ;-)
>
> cheers
> cheedu
>
> On Mon, 14 Aug 2000, Madhu Sudhan.S wrote:
>
> > Hello Everybody,
> >
> > Can any one on the list please educate me on how to Create a private
> > Unix Shell of my own, allowing only a few basic simple commands on that
> > to work on that, like the ls, cd, etc.,. Other commands, like su, etc.,
> > should
> > throw an error "Command not found".
> >
> > Anticipating quick reply ......
> >
> > Regards
> > Madhu Sudhan.S
> >
> >
>
-------------------------------------------------------
/*
* Simulation of UNIX
* (c) Archan Paul' Dec1998 <archanp@xxxxxxxxxxx>
*/
/*
* Please don't compile this file using Wall, .......... It is give u hell warning ;)
* Just do
* $gcc suunix.c
*
* This is just my very very very OLD code in my early days.... Enjoy the simple shell simulation......
*
*
* Please create a file called alogin.dat in the same directory as the executable
* with the following content
* root root
* */
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
#define TRUE 1
#define FALSE 0
#define SIZE 256
int ttyOpenFlag = TRUE, aLoginFlag = FALSE, aLoginCount;
char vLoginName[10], fLoginName[10], vPassword[10], fPassword[10];
FILE *fpLoginFile;
/* veriables requred for shell */
char consoleInput[256], com[256], argument1[256], argument2[256];
int validCommandLineFlag;
int shellChildPID, shellPID;
int consoleCode, status;
int i, j, registerSpace[256];
/* veriables requred for functionCat */
char catBuffer[SIZE];
int catStatus;
int fpCatSource;
/* veriables requred for functionCp*/
char cpBuffer[SIZE];
int cpStatus;
int fpCpSource, fpCpDestination;
/* veriables used by functionDate*/
int tm;
/* veriables used by functionAddUser*/
char addUserName[10], addUserOldPassword[10], addUserNewPassword[10];
FILE *fpAddUser;
/*
* The following function simalutes the LOGIN process which is exec-ed by
* INIT when getty() succeeds by successfully opening the tty-line.
* In our Simulated UNIX it is considered that tty-line open is absolutely
* successful and it is denoted by making ttyOpenFlag = TRUE.
*
*/
alogin(void)
{
/* getty process executes */
/* set process group (setpgrp()) */
/* open tty line */
if (ttyOpenFlag == TRUE)
{
/* exec login program */
/* the user will be offered for login until 'aLoginFlag' becomes
* TRUE and the number of unsuccessful login is checked by
* 'aLoginCount'. When 'aLoginCount' becomes greater than 10,
* no more offer of login is granted and the system is Shutdown.
*/
printf("\nYou may use login name 'root' and password 'root'\n");
printf("\nUse 'man' to see the commands available and to quit, use 'shutdown' or 'logout'\n");
while ((aLoginFlag == FALSE) && (aLoginCount <= 10))
{
fpLoginFile = fopen("./alogin.dat", "r");
if (fpLoginFile == NULL)
{
printf("\nSystem Error !! Can't open ./alogin.dat File\n");
exit();
}
printf("\nLogin : ");
printf("\033[01;33m");
scanf("%s", &vLoginName);
printf("\033[m");
printf("Password : ");
printf("\033[30m");
scanf("%s", &vPassword);
printf("\033[m");
aLoginFlag = FALSE;
while(1)
{
if(feof(fpLoginFile)) break;
fscanf(fpLoginFile, "%s %s\n", fLoginName, fPassword);
if (strcmp(vLoginName, fLoginName) == 0)
{
if (strcmp(vPassword, fPassword) == 0)
{
aLoginFlag = TRUE;
break;
}
}
}
if (aLoginFlag == TRUE) /* login successful */
{
printf("\033[01;36mLogin successful\033[m\n");
/* INIT prcess exec-ed shell from here */
ashell();
aLoginFlag = FALSE;
aLoginCount = 0;
}
else
{
/* login is not successful */
printf("\033[01;31mLogin incorrect\033[m\n");
aLoginCount ++;
}
} /* while loop ends here */
if (aLoginCount > 10)
{
printf("\nNumber of Login Attempts exceeded.");
printf("\nSystem is Locked for possible Intrusion..\n");
printf("\nSending all the process term-end signal........");
printf("\nSimulated Unix has Shutdown.....");
kill(0, SIGKILL);
}
fclose(fpLoginFile);
}
}
/*
* The follwing function simulates the shell for the Simulated UNIX.
*/
ashell(void)
{
printf("Simulated INIT process has exec-ed shell having pid %d", getpid());
while (1)
{ printf("\n$>");
/* to parent to ignore the death of any child */
signal(SIGCLD, SIG_IGN);
perseInput();
extractCommand();
/* if the 'shutdown' command is entered, all the process which
* are the child of the simulated INIT process and the
* simulated INIT are killed and the Simulated UNIX environment
* comes to an end.
*/
if (strcmp(com, "shutdown") == 0)
{
printf("\nSending all the process term-end signal........");
printf("\nSimulated Unix has Shutdown.....");
kill(0, SIGKILL);
}
/*
* if the 'logout' command is entered, the program control is
* taken outside of the while-loop and the subsequent login
* process is initialised. Please check-out the control logic
* flow carefully.
*/
if (strcmp(com, "logout") == 0)
{
break;
}
if (strcmp(com, "date") == 0)
{
if (fork() == 0) functionDate();
wait(&status);
}
if (strcmp(com, "ls") == 0)
{
if (fork() == 0) functionLs();
wait(&status);
}
if (strcmp(com, "cat") == 0)
{
if (fork() == 0) functionCat();
wait(&status);
}
if (strcmp(com, "cp") == 0)
{
if (fork() == 0) functionCp();
wait(&status);
}
if (strcmp(com, "clear") == 0)
{
if (fork() == 0) functionClear();
wait(&status);
}
if (strcmp(com, "man") == 0)
{
if (fork() == 0) functionMan();
wait(&status);
}
if (strcmp(com, "adduser") == 0)
{
if (fork() == 0) functionAddUser();
wait(&status);
}
}
}
/*
* The follwing 4 functions i.e. 'perseInput()' , 'extractCommand()',
* 'extractArgument1()', 'extractArgument2()' are used for persing the
* console input of the command-line stored in 'consoleInput[]' array.
* 'perseInput()' -- This function is used to perse through the
* command line entered in the Simulated UNIX shell
* and to register the position of occurance of space
* in the command-line (as demarkation between the
* command and arguments) to another array 'registerSpace[]'
*
* 'extractCommand()' -- This function is used to extract the command
* from the whole command-line stored in the
* array 'consoleInput[]' by the efficient use of
* veriable 'registerSpace[0]'.
* Here 'register[0]' is used as it contains the
* first demarkation position located in the
* command-line 'consoleInput[]' and concerned
* command is transferred to 'com[]' as a string.
*
* 'extractArgument1() -- This function is used to extract the first
* argument from the 'consoleInput[]' to
* 'argument1[]' as a string, with the use of
* 'registerSpace[1]'. Here the 'registerSpace[1]'
* is used as it contains the position of the second
* demarkation in the command-line.
*
* 'extractArgument2()' -- This function is used to extract second argument
* from the command-line. The further expaltion is as
* as previous.
**/
perseInput(void)
{
/* read form the console */
i=0;
while ((consoleInput[i] = getchar()) != '\n') i++;
consoleInput[i]='\0';
for (i=0,j=0;i<256;i++)
{
if (consoleInput[i] == ' ' || consoleInput[i] == '\0')
{
registerSpace[j] = i;
j++;
}
}
}
extractCommand(void)
{
for(i=0;i< registerSpace[0]; i++)
{
com[i] = consoleInput[i];
}
com[i] = '\0';
}
extractArgument1(void)
{
for(i=(registerSpace[0]+1);i< registerSpace[1]; i++)
{
argument1[i-(registerSpace[0]+1)] = consoleInput[i];
}
argument1[i] = '\0';
}
extractArgument2(void)
{
for(i=(registerSpace[1]+1);i< registerSpace[2]; i++)
{
argument2[i-(registerSpace[1]+1)] = consoleInput[i];
}
argument2[i] = '\0';
}
/* The following function simulates CAT in the Simulated UNIX environment
* when it is invoked by CAT command with or without valid argument in the
* Simulated UNIX shell.
* Please refer to the 'printf()' statement for understanding of the process
* executing the cat-function.
* Here there is two instances of 'cat' command. When no argument is supplied
* with the 'cat' command, the source-file of the cat-command is taken as
* standard-input device. The corresponding code implemented here has a
* known bug. If user wants to quit from this by ^z then all the process
* terminates abruptly.
* Otherwise if argument is supplied with cat command, then the concerned
* file is opened and read and output is written in the standard-output
* device.
*/
functionCat(void)
{
printf("%s command is executed by child process (pid %d) of parent process (pid %d)", com, getpid(), getppid());
extractArgument1();
if (argument1[0] == '\0')
{
/*
* the first argument, 0 in the read function, depicts standard
* input device and the first argument, 1 in the write function
* depicts standard output device.
*/
while ( (catStatus = read(0, catBuffer, sizeof(catBuffer))) > 0)
write(1, catBuffer, catStatus);
}
else
{
if ( (fpCatSource = open(argument1, 0)) != -1)
{
printf("\n");
while ( (catStatus = read(fpCatSource, catBuffer, sizeof(catBuffer))) > 0)
write(1, catBuffer, catStatus);
}
else printf("\nERROR !! Unable to open file %s......", argument1);
close(fpCatSource);
}
exit(0);
}
/* The following function simalates the CP in the Simulated UNIX
* environment when it is invoked by 'cp' command in the Simulated UNIX shell.
* Please refer to the 'printf()' statement for understanding of the process
* executing the cp-function.
*/
functionCp(void)
{
printf("%s command is executed by child process (pid %d) of parent process (pid %d)", com, getpid(), getppid());
extractArgument1();
extractArgument2();
if ((fpCpSource = open(argument1, 0)) == -1)
{
printf("ERROR !! Can't open source %s", argument1);
exit(0);
}
if ((fpCpDestination = creat(argument2, 0666)) == -1)
if ((fpCpDestination = open(argument2, 1)) == -1)
{
printf("ERROR !! Can't creat or overwrite destination file %s", argument2);
exit(0);
}
while ( (cpStatus = read(fpCpSource, cpBuffer, sizeof(cpBuffer))) > 0)
write(fpCpDestination, cpBuffer, cpStatus);
printf("\nCopying from %s to %s is successful. ", argument1, argument2);
exit(0);
}
functionClear(void)
{
printf("%s command is executed by child process (pid %d) of parent process (pid %d)", com, getpid(), getppid());
system("tput clear");
exit(0);
}
/* The following function prints the date in the Simulated UNIX environment
* when it is invoked by date command in the Simulated UNIX shell.
* Please refer to the 'printf()' statement for understanding of the process
* executing the date-function.
*/
functionDate(void)
{
printf("%s command is executed by child process (pid %d) of parent process (pid %d)", com, getpid(), getppid());
time(&tm);
printf("\n %s", asctime(localtime(&tm)));
exit(0);
}
/* The following function simulates 'ls' in the Simulated UNIX environment
* when it is invoked by date command in the Simulated UNIX shell.
* Please refer to the 'printf()' statement for understanding of the process
* executing the ls-function.
*/
functionLs(void)
{
printf("%s command is executed by child process (pid %d) of parent process (pid %d)", com, getpid(), getppid());
system("ls");
exit(0);
}
/* The following function simulates the man-command in the Simulated UNIX
* environment.
*/
functionMan(void)
{
printf("%s command is executed by child process (pid %d) of parent process (pid %d)", com, getpid(), getppid());
printf("\n\nThe following Commands are avilable in the Simulated UNIX env");
printf("\nclear date ls cat cp clear man logout shutdown\n");
exit(0);
}
/*
* The following function simulates the adduser-function in simulated UNIX
* environment. This command is executed only when the user has login as
* root. No validity checking is implemented in the following code, if user
* is allready in the database.
*/
functionAddUser(void)
{
if (strcmp(vLoginName, "root") == 0)
{
if ( (fpAddUser = fopen("alogin.dat", "a+")) == NULL)
{
printf("\nERROR opening file 'alogin.dat'.....");
}
else
{
printf("\nEnter Login Name : ");
scanf("%s", &addUserName);
printf("Enter Password : ");
printf("\033[30m");
scanf("%s", &addUserOldPassword);
printf("\033[m");
printf("ReEnter Password : ");
printf("\033[30m");
scanf("%s", &addUserNewPassword);
printf("\033[m");
if (strcmp(addUserOldPassword, addUserNewPassword) == 0)
{
fprintf(fpAddUser, "%s %s\n", addUserName, addUserOldPassword);
printf("\nPassword File is updated.");
}
else
{
printf("\nDesparity in password rechecking");
}
}
fclose(fpAddUser);
}
else
{
printf("\nPermission Denied !! To use this command, login as root");
}
exit(0);
}
main(void)
{
system("tput clear");
while(1) {
printf("Here the simulated INIT process has pid %d ", getpid());
alogin();
}
}
root root