Unix Shell Source Code

Unix Shell Source Code

Unix Source Code – CRA Shell

Coded By Conrad Brookes

Published under GNU Free Documentation License

This page contains a complete shell program together with a complete explanation on how to compile and run along with the testing.

This study is a code designed to construct a shell that runs on a UNIX operating system. The program should be able to mimic any other shell that runs on a UNIX machine such as BASH. This program is written in the c programming language and must be built and run from a UNIX operating system.

Installation

The shell program crash needs the files parser.c, parser.h, and main.c. Also a make file: Makefile if compiling from the shell command prompt. Either creating a project with an IDE or typing make within the directory with the files in it will build the program.

Discussion

The way I approached it was to use the command line parser that was supplied, and also the main that was supplied. I added a function to the inside the main.c file called proCom. This method processes all the arguments, for communication between the command line and the operating system. It handles any of the common functions that are performed by the shell. These tasks include handling piping, redirection, background processing, exit, prompt and directory walking. As per requirements the directory walk, prompt change and exit are built in commands, that is they are defined by myself and they do use any major external functions. The rest of the handling is achieved though the use of UNIX system calls such as fork and dup2.

The handling of sequential commands is processes within parser.c, in the function process_cmd_line. The way it is accomplished is by handling the ‘;’ in exactly the same way the pipe is handled. I quite literally cut and pasted the pervious code in that function.

Limitations

There are a number of limitations to this program. The program does not handle wildcard expansion, it was removed from the program because of the faults in the coding. Also there is no error handling in the command line. That is if a command is entered incorrectly there is no notification to the user. Signal handling is also not added to this program.

Testing

Testing Table
Assignment 2 b310 testing

yes = X
no = No
Reconfigurable Prompt X
prompt X
prompt $

Directory Walk

cd X
cd /mnt X

Redirection

ls > data1.txt X
cat < data2.txt X

Pipes

ls | more X
ls -la | more X

Background
sleep 10 & X
sleep 10 X

Sequential commands

ls ; cd /mnt X
ls ; cd /mnt ; ps X
ls ; cd /mnt ; ps ; sleep 10 & X
sleep 20; ps -l X

Exit
exit X

Miscellaneous Commands

ls X
ls -la X
pwd X
man index X
mkdir new X
chmod 777 data.txt X

Wildcards NO

Quoted Tokens
cat “topic 10” X

Screen Dump

$ prompt
no new prompt given
$ prompt ?
? pwd
/home/admin/Desktop/a2Unidevelop/a2Uni/a2unidev/a2unidev
? cd ..
? pwd
/home/admin/Desktop/a2Unidevelop/a2Uni/a2unidev
? cd
getenv(HOME): Success
? pwd
/home/admin
? cd /Desktop/a2Unidevelop/a2Uni/a2unidev
? pwd
/home/admin
? cd Desktop
? pwd
/home/admin/Desktop
? cd a2Unidevelop
? pwd
/home/admin/Desktop/a2Unidevelop
? cd a2Uni
? pwd
/home/admin/Desktop/a2Unidevelop/a2Uni
? cd a2unidev
? pwd
/home/admin/Desktop/a2Unidevelop/a2Uni/a2unidev
? cat > new
this is some text
? ls
Makefile a2unidev config.cache config.status missing stamp-h.in
Makefile.am a2unidev.kdevprj config.h configure mkinstalldirs
Makefile.dist acconfig.h config.h.in configure.in new
Makefile.in aclocal.m4 config.log install-sh stamp-h
? cat new
this is some text
? cat < new this is some text ? rm new ? ls Makefile a2unidev config.cache config.status missing Makefile.am a2unidev.kdevprj config.h configure mkinstalldirs Makefile.dist acconfig.h config.h.in configure.in stamp-h Makefile.in aclocal.m4 config.log install-sh stamp-h.in ? ls Makefile a2unidev config.cache config.status missing Makefile.am a2unidev.kdevprj config.h configure mkinstalldirs Makefile.dist acconfig.h config.h.in configure.in stamp-h Makefile.in aclocal.m4 config.log install-sh stamp-h.in ? ls | more Makefile Makefile.am Makefile.dist Makefile.in a2unidev a2unidev.kdevprj acconfig.h aclocal.m4 config.cache config.h config.h.in config.log config.status configure configure.in install-sh missing mkinstalldirs stamp-h stamp-h.in ? sleep 4 ? sleep 4 & PID: 1204 ? ps PID TTY TIME CMD 1173 pts/4 00:00:00 bash 1174 pts/4 00:00:00 a2unidev 1204 pts/4 00:00:00 sleep 1205 pts/4 00:00:00 ps ? ps PID TTY TIME CMD 1173 pts/4 00:00:00 bash 1174 pts/4 00:00:00 a2unidev 1204 pts/4 00:00:00 sleep
1206 pts/4 00:00:00 ps
? ls ; cd .. ; ps
Makefile a2unidev config.cache config.status missing
Makefile.am a2unidev.kdevprj config.h configure mkinstalldirs
Makefile.dist acconfig.h config.h.in configure.in stamp-h
Makefile.in aclocal.m4 config.log install-sh stamp-h.in
PID TTY TIME CMD
1173 pts/4 00:00:00 bash
1174 pts/4 00:00:00 a2unidev
1204 pts/4 00:00:00 sleep
1209 pts/4 00:00:00 ps
? sleep 4 ; ls
0 2 a2.html main.c makefile parser.h parser.o readme.txt
1 Makefile.txt a2unidev main.o parser.c parser.html parser_test
? cat > quoted 1
this is a quoted file
? ls
0 2 a2.html main.c makefile parser.h parser.o quoted 1
1 Makefile.txt a2unidev main.o parser.c parser.html parser_test readme.txt
? cat quote 1
cat: quote: No such file or directory
A simple Command Line Parser.
Author : Michael Roberts mroberts@it.net.au of Murdoch University
Last Modification : 14/08/01

Permission granted by Author for use in B310

Modified by Nick Nelissen, who separated the parser function from the main function
and provided a new Makefile and squashed the odd bug….
? cat “quote 1”
cat: quote 1: No such file or directory
? cat “quoted 1”
this is a quoted file
? mkdir newDir
? ls
0 2 a2.html main.c makefile parser.c parser.html parser_test readme.txt
1 Makefile.txt a2unidev main.o newDir parser.h parser.o quoted 1
? ls -la
total 124
drwxr-xr-x 4 admin admin 4096 Oct 31 13:39 .
drwx—— 3 admin admin 4096 Oct 4 13:21 ..
-rw——- 1 admin admin 12288 Oct 4 13:21 .main.c.swp
-rw-r–r– 1 admin admin 328 Oct 5 14:32 0
-rw-r–r– 1 admin admin 328 Oct 5 14:32 1
-rw-r–r– 1 admin admin 328 Oct 5 14:32 2
-rwxr-xr-x 1 admin admin 229 Oct 4 13:21 Makefile.txt
-rwxr-xr-x 1 admin admin 11267 Oct 4 13:21 a2.html
drwxr-xr-x 3 admin admin 4096 Oct 31 11:44 a2unidev
-rwxr-xr-x 1 admin admin 1148 Oct 4 13:21 main.c
-rw-r–r– 1 admin admin 1528 Oct 4 13:21 main.o
-rwxr-xr-x 1 admin admin 229 Oct 4 13:21 makefile
drwxr-xr-x 2 admin admin 4096 Oct 31 13:39 newDir
-rwxr-xr-x 1 admin admin 10288 Oct 4 13:21 parser.c
-rwxr-xr-x 1 admin admin 1063 Oct 4 13:21 parser.h
-rwxr-xr-x 1 admin admin 2749 Oct 4 13:21 parser.html
-rw-r–r– 1 admin admin 5624 Oct 4 13:21 parser.o
-rwxr-xr-x 1 admin admin 18194 Oct 4 13:21 parser_test
-rw-r–r– 1 admin admin 22 Oct 31 11:48 quoted 1
-rwxr-xr-x 1 admin admin 328 Oct 4 13:21 readme.txt
? chmod 777 newDir
? ls -la
total 124
drwxr-xr-x 4 admin admin 4096 Oct 31 13:39 .
drwx—— 3 admin admin 4096 Oct 4 13:21 ..
-rw——- 1 admin admin 12288 Oct 4 13:21 .main.c.swp
-rw-r–r– 1 admin admin 328 Oct 5 14:32 0
-rw-r–r– 1 admin admin 328 Oct 5 14:32 1
-rw-r–r– 1 admin admin 328 Oct 5 14:32 2
-rwxr-xr-x 1 admin admin 229 Oct 4 13:21 Makefile.txt
-rwxr-xr-x 1 admin admin 11267 Oct 4 13:21 a2.html
drwxr-xr-x 3 admin admin 4096 Oct 31 11:44 a2unidev
-rwxr-xr-x 1 admin admin 1148 Oct 4 13:21 main.c
-rw-r–r– 1 admin admin 1528 Oct 4 13:21 main.o
-rwxr-xr-x 1 admin admin 229 Oct 4 13:21 makefile
drwxrwxrwx 2 admin admin 4096 Oct 31 13:39 newDir
-rwxr-xr-x 1 admin admin 10288 Oct 4 13:21 parser.c
-rwxr-xr-x 1 admin admin 1063 Oct 4 13:21 parser.h
-rwxr-xr-x 1 admin admin 2749 Oct 4 13:21 parser.html
-rw-r–r– 1 admin admin 5624 Oct 4 13:21 parser.o
-rwxr-xr-x 1 admin admin 18194 Oct 4 13:21 parser_test
-rw-r–r– 1 admin admin 22 Oct 31 11:48 quoted 1
-rwxr-xr-x 1 admin admin 328 Oct 4 13:21 readme.txt
? ls new*
ls: new*: No such file or directory
? ls new?ir
ls: new?ir: No such file or directory
? exit

Press Enter to continue!

Source Code

include “parser.h”

/
** proCom.c
** Programmer: C Brookes
** Date: 10/09/02
*/

/*

  • main.c
  • Author of part of the main function : Michael Roberts mroberts@it.net.au
  • Modified 11/9/01 by Nick Nelissen, who speparated the main into a separate source
  • file
    / /
  • This function reads one line of 256 characters from stdin. THis line of
  • characters is then processed as a command line.
  • The resulting array of structures is then displayed to stdout.
    *
  • Arguments :
  • None.
    *
  • Returns :
  • An integer representing the exit status.
    *
    */
    char newProm[20];
    char readIn[20];
    //pocess commands
    void proCom(command * c)
    {

int p[2], status = 0;
int z = 0, indexA, comCount, pipeing, i, j, k;
char *pipeArg[20];
pid_t pid;

indexA = 0;
comCount = 0;
while(c->argv[indexA] != NULL)
{
comCount++;
indexA++;
}//end while

//The way i set the first 3 if statements was influenced from
//this web page
// www-instruct.wccnet.org/~chassel/linux275/ClassNotes/process/myshell.htm
if(strcmp(c->com_name, “cd”) == 0)//if the command is cd
{
if(comCount == 1)//if there is only cd with no arguments
{
//this method getenv(“HOME”) was from this site
//www.cs.bsu.edu/homepages/dlsills/davis_myshell.html
chdir(getenv(“HOME”));//goto home directory
perror(“getenv(HOME)”);
}//end if
else if(comCount > 2)//if there are more than 1 arguments after cd
{
printf(“Too many commands\n”);
}//end else if
else
{
chdir(c->argv[1]);//else change to the directory after the cd
}//end else
}
else if(strcmp(c->com_name, “exit”) == 0)//if the command is exit
{
exit(0);//die
}//end else if
else if(strcmp(c->com_name, “prompt”) == 0)//if the command is prompt
{
if(c->argv[1] == NULL)//if there are no following arguemtns following “prompt”
{
printf(“no new prompt given\n”);//error message
}//end if
else
{
strcpy(newProm, c->argv[1]);//put new prompt into prompt
}//end else
}//end elseif

//wild card procssing would go here
//wildcard(c);

//check for pipe
else if(c->pipe_to == 1)//if we have pipeing
{
z=0;//loop to get the first commands of the pipe
while(zargv[z];//copy the commands to be piped
z++;
}//end while
pipeArg[z] = NULL;//make sure last element is a NULL
pipeing = 1;//so the next loop it will have access to piping
return;//gets rid of bug
}//end if

if (pipeing == 1)
{
switch(fork())//switch to spawn a child process to execute commands (pipe)
{
case -1:
perror(“fork error”);//if there is an error
exit(2);//die
case 0: //child
break;//goto processing
default: //parent
wait((int *)0);//this gets rid of this looping bug
return;//dido
}//end switch
//open the pipe
//taken from Unix System Programming Haviland pg 156
//open up the pipe and sheck for error
if(pipe(p) == -1)
{
printf(“pipe call”);
exit(1);
}//end if

//the child does the piping
switch(fork())
{
case -1://check for error
exit(2);
case 0: //child
close(p[0]);//close read file descriptor
dup2(p[1],1);//write to the pipe

execvp(pipeArg[0], pipeArg);//the command to execute to the pipe
exit(1);//shouldnt get here
perror(“fork error”);//error message

default: //parent
//printf(“gets here\n”);
close(p[1]);//close the write descriptor
dup2(p[0],0);//read from the pipe
execvp(c->argv[0], c->argv);//the command that reads from the pipe
//wait((int *)0);
//return;
// exit(1);
perror(“fork error”);//mmm
}//end switch
pipeing = 0;
}//end if
//process redirection
//if redirect has been entered
if((c->redirect_out != NULL) || (c->redirect_in != NULL))
{
switch(pid = fork())//start a fork
{
case -1://case for error
printf(“error on redirect fork\n”);
exit(2);
case 0: //child process
//i found an example of redirection and writing to file similar to
//what i was looking for at this web site :
// www-instruct.wccnet.org/~chassel/linux275/ClassNotes/process/myshell.htm

if (c->redirect_out != NULL)//if redirection out do this
{
//this if statement will look to c if there is a space at the start if the redirect
if (c->redirect_out[0] == 32)
{
i = strlen(c->redirect_out);//get the length of string
k=1;
for(j=0;j<=(i-1);j++)//loop trough and get the chars minus the space { //and put them in the new sting readIn[j] = c->redirect_out[k];
k++;
}
k++;
readIn[k] = ‘\0’;//make the last char a \0
strcpy( c->redirect_out, readIn);//now copy the new string back
}//end if
//these fuctions and a similar example was found here
//www.umsl.edu/~s1002145/msdos.html
freopen(c->redirect_out, “w”, stdout);//open this file for writing
execvp(c->com_name, c->argv);//executethe command to write to this open file
exit(1);//kill this child process
}//end if

if (c->redirect_in != NULL)//if redirection in is found
{
//this if statement will look to c if there is a space at the start if the redirect
if (c->redirect_in[0] == 32)
{
i = strlen(c->redirect_in);//get the length of string
k=1;
for(j=0;j<=(i-1);j++)//loop trough and get the chars minus the space { //and put them in the new sting readIn[j] = c->redirect_in[k];
k++;
}
k++;
readIn[k] = ‘\0’;//make the last char a \0
strcpy( c->redirect_in, readIn);//now copy the new string back
}//end if
//these fuctions and a similar example was found here
//www.umsl.edu/~s1002145/msdos.html
if((freopen(c->redirect_in, “r”, stdin)) == NULL)//open this file for writing
{
printf(“Could not open file for redirection\n”);//check for error
exit(1);
}
execvp(c->com_name, c->argv);//executethe command to read to this
}//end if
default: //parent
}//end switch
}//end if
else
{
//process left over coomand that dont match the other criteria
switch(pid = fork())//forking a child
{
case -1://if error
printf(“error on redirect fork\n”);
exit(2);
case 0: //child
execvp(c->com_name, c->argv);
//printf(“%s”,newProm);
exit(1);
default: //parent
//wait((int *)0);
//wait(&status);
}//end switch
//
}//end else

//taken from Unix System Programming Haviland pg 113
//part of the smallsh program for handeling background
//processes.
if(c -> background == 1)
{
printf(“PID: %d\n”,pid);
return(0);
}
if(waitpid(pid, &status, 0) == -1)
return(-1);
else
return(status);

}//ed proCom

int
main(void)
{
char *cmd;
int lc = 0;
char *c;
command **cl;

strcpy(newProm, “$”);

for(;;)
{
cmd = (char *) malloc(CMD_LENGTH);

printf(“%s “,newProm);
cmd = fgets(cmd, CMD_LENGTH, stdin);
c = index(cmd, ‘\n’);
*c = ‘\0’;
//printf(“Command Line : [%s] [%d]\n”, cmd, strlen(cmd));

cl = process_cmd_line(cmd, 1);

lc = 0;
while (cl[lc] != NULL) {
//dump_structure(cl[lc], lc);
//print_human_readable(cl[lc], lc);
proCom(cl[lc]);
lc++;
}//end while

clean_up(cl);
free(cmd);

}//end for

return 0;
} /*End of main() */
/*

  • Parser.c
  • A simple Command Line Parser.
  • Author : Michael Roberts mroberts@it.net.au
  • Last Modification : 14/08/01
    *
    *Modified by C. Brookes in proccess_cmd_line.
    *The original code has been edited by cut and pasting the previous existing
    *code, created by the previous author.
    */

include “parser.h”

//#define DEBUG

/*

  • This function breakes the simple command token isolated in other functions
  • into a sequence of arguments. Each argument is bounded by white-spaces, and
  • there is no special character intepretation. The results are stored in the
  • argv array of the result command structure.
    *
  • Arguments :
  • cmd – the string to be processed.
  • result – the comand struct to store the results in.
    *
  • Returns :
  • None.
    *
    */
    void
    process_simple_cmd(char *cmd, command * result)
    {
    char *dc;
    int lpc = 1;
    int i,j = 0;
    char array1[CMD_LENGTH];
    char array2[CMD_LENGTH];
    char array3[CMD_LENGTH];
    strncpy(array1, cmd, CMD_LENGTH);

ifdef DEBUG

fprintf(stderr,”process_simple_cmd\n”);

endif

/*No Spaces Means No Arguments. */
if (((dc = index(cmd, white_space[0])) == NULL
&& (dc = index(cmd, white_space[1])) == NULL)
&& (dc = index(cmd, (char) 9)) == NULL) {
result->com_name = strdup(cmd);
result->argv = realloc((void *) result->argv, sizeof(char *));
result->argv[0] = strdup(cmd);
}
else {

// nick modified this
/*Pull out the Command Name (i.e First Token) */
dc = strtok(cmd, white_space);
//dc = cmd;

ifdef DEBUG

fprintf(stderr,”[%s][%s]\n”,dc,cmd);

endif

result->com_name = strdup(dc);
//result->com_name = strdup(cmd);
// end nick

ifdef DEBUG

fprintf(stderr,”{1}\n”);

endif

result->argv = realloc((void *) result->argv, sizeof(char *));

ifdef DEBUG

fprintf(stderr,”{2}\n”);

endif

result->argv[0] = strdup(dc);

if(index(array1,34) != NULL)//process quotes
{
strncpy(array2, index(array1, 34), CMD_LENGTH);
for(i=0;array2[i+1]!=34;i++)
{
array3[i] = array2[i+1];
}
array3[i] = 0;
result->argv = realloc((void *) result->argv, (lpc + 1) * sizeof(char *));
result->argv[lpc] = strdup(array3);
lpc++;
for(i=0;i<CMD_LENGTH;i++)
{
if(dc[i] == 34)
{
i++;
while(dc[i] != 34)
{
if(dc[i] == 32)
dc[i] = 33;
i++;
}
}
}
dc =strtok(NULL, white_space);
}

/*Loop through the remaining tokens, writing them to the struct. */
while ((dc = strtok(NULL, white_space)) != NULL) {

ifdef DEBUG

fprintf(stderr,”[%s]\n”,dc);

endif

result->argv = realloc((void *) result->argv, (lpc + 1) * sizeof(char )); result->argv[lpc] = strdup(dc); lpc++; } } /Set the final array element NULL. */
result->argv = realloc((void *) result->argv, (lpc + 1) * sizeof(char *));
result->argv[lpc] = NULL;

return;
} /*End of process_simple_cmd() */
/*

  • This function parses the commands isolated from the command line string in
  • other functions. It searches the string looking for input and output
  • redirection characters. The simple commands found are sent to
  • process_simple_comd(). The redirection information is stored in the result
  • command structure.
    *
  • Arguments :
  • cmd – the command string to be processed.
  • result – the command structure to store the results in.
    *
  • Returns :
  • None.
    *
    */
    void
    process_cmd(char *cmd, command * result)
    {
    char *pc, *mc;
    char *simple_cmd = NULL;

/*If no redirection found, then only a simple command present. */
if ((pc = index(cmd, ‘<‘)) == NULL) { if ((pc = index(cmd, ‘>’)) == NULL) {
process_simple_cmd(cmd, result);
result->redirect_in = NULL;
result->redirect_out = NULL;
}
else { /*Output Redirection in place */

if(index(pc,34) != NULL)//process quotes
{
process_simple_cmd(cmd,result);
result->redirect_out = NULL;
}
else
{
pc = strtok(cmd, “>”);
simple_cmd = strdup(pc);

pc = strtok(NULL, “\0”);
process_simple_cmd(simple_cmd, result);
result->redirect_out = strdup(pc);
}//end if else
}
}
else { /*Input Redirection */
if(index(pc,34) != NULL)//process quotes
{
process_simple_cmd(cmd,result);
result->redirect_out = NULL;
}
else
{
pc = strtok(cmd, “<“);
simple_cmd = strdup(pc);
pc = strtok(NULL, “\0”);

/*Output redirection may have been missed becuase input is checked

  • first.*/
    if ((mc = index(simple_cmd, ‘>’)) != NULL)
    process_cmd(simple_cmd, result);
    if ((mc = index(pc, ‘>’)) != NULL)
    process_cmd(pc, result);

process_simple_cmd(simple_cmd, result);
result->redirect_in = strdup(pc);
}//end if else
}

free(simple_cmd);
return;
} /*End of process_cmd() */

/*

  • This function processes the command line. It isolates tokens seperated by
  • the ‘&’ or the ‘|’ character. The tokens are then passed on to be processed
  • by other functions. Once the first token has been isolated this function is
  • called recursivly to process the rest of the command line. Once the entire
  • command line has been processed an array of command structures is created
  • and returned.
    *
  • Arguments :
  • cmd – the command line to be processed.
    *
  • Returns :
  • An array of pointers to command structures.
    *
    */

command **
process_cmd_line(char *cmd,int new)
{
char *rc, *mc;
char *rc_copy = NULL;
static command **cmd_line;
static int lc;

// nick nelissen added this 23/9/01
// ensures statics are null, when not recursively called
if(new==1)
{
lc=0;
cmd_line=NULL;
}//end if
/*

  • Check for the existance of delimitors.
  • If no delimitors exist, we only have one command on the command line.
  • Otherwise process accordingly.
    */

if ((rc = index(cmd, ‘&’)) == NULL)
{
if ((rc = index(cmd, ‘|’)) == NULL)
{
//cut and pasted from above
if ((rc = index(cmd, ‘;’)) == NULL)
{
//cmd_line = realloc((void *) cmd_line, (lc + 1) * sizeof(command *));
cmd_line = realloc(cmd_line, (lc + 1) * sizeof(command *));

if(cmd_line==NULL)
{
exit(-1);
}//end if

cmd_line[lc] = malloc(sizeof(command));
if(cmd_line[lc]==NULL)
{
exit(-1);
}//end if
// nick added this to NULL the new struct
cmd_line[lc]->argv=NULL;
cmd_line[lc]->redirect_in=NULL;
cmd_line[lc]->redirect_out=NULL;
cmd_line[lc]->com_name=NULL;
cmd_line[lc]->pipe_to=0;
cmd_line[lc]->background=0;
process_cmd(cmd, cmd_line[lc]);

lc++;
}//end if 3
else
{
//this piece of code is copied from the code below, its
//cut and pasted from below, it
//handels ‘;’ the with the same code as & or |.
rc = strtok(cmd, “;”);
rc = strtok(NULL, “”); /*Get the second token out */

cmd_line = realloc((void *) cmd_line, (lc + 1) * sizeof(command *));
// nick changed this, same as nulling each element
//cmd_line[lc] = malloc(sizeof(command));
cmd_line[lc] = calloc(1,sizeof(command));

process_cmd(cmd, cmd_line[lc]);
//cmd_line[lc]->pipe_to = lc + 1;
lc++;
if (rc != NULL)
{
process_cmd_line(rc,0); /*Process the Second Token */
}//end if
}

}//end if 2
else
{ /*A ‘|’ was found */

rc = strtok(cmd, “|”);
rc = strtok(NULL, “”); /*Get the second token out */

cmd_line = realloc((void *) cmd_line, (lc + 1) * sizeof(command *));
// nick changed this, same as nulling each element
//cmd_line[lc] = malloc(sizeof(command));
cmd_line[lc] = calloc(1,sizeof(command));

process_cmd(cmd, cmd_line[lc]);
cmd_line[lc]->pipe_to = lc + 1;
lc++;
if (rc != NULL)
{
process_cmd_line(rc,0); /*Process the Second Token */
}//end if

}//end else

}// end if
else
{ /*A ‘&’ was found */
rc = strtok(cmd, “&”);
rc_copy = strdup(rc); /*Make a copy of the first token */
rc = strtok(NULL, “”); /*Get the second token out */
if ((mc = index(rc_copy, ‘|’)) != NULL)
{
process_cmd_line(rc_copy,0);
}//end if
else
{
cmd_line = realloc((void *) cmd_line, (lc + 1) * sizeof(command *));
// nick changed this
//cmd_line[lc] = malloc(sizeof(command));
cmd_line[lc] = calloc(1,sizeof(command));

process_cmd(cmd, cmd_line[lc]);
cmd_line[lc]->background = 1;
lc++;
}//end if

if (rc != NULL)
process_cmd_line(rc,0); /*Process the Second Token */

}//end if

cmd_line = realloc((void *) cmd_line, (lc + 1) * sizeof(command *));
cmd_line[lc] = NULL;

free(rc_copy);

return cmd_line;
} /*End of Process Cmd Line */

/*

  • This function cleans up some of the dynamicly allocated memory. Each array
  • element is visited, and the contained data is free’d before the entire
  • structure is free’d.
    *
  • Arguments :
  • cmd – the array of pointers to command structures to be cleaned.
    *
  • Returns :
  • None.
    *
    */
    void
    clean_up(command ** cmd)
    {
    int lpc = 0;
    int ilpc = 0;

while (cmd[lpc] != NULL) {
ilpc = 0;
if (cmd[lpc]->com_name != NULL)
free(cmd[lpc]->com_name); /*Free Com_Name */
if (cmd[lpc]->argv != NULL) {
while (cmd[lpc]->argv[ilpc] != NULL) {
free(cmd[lpc]->argv[ilpc]); /*Free each pointer in Argv */
ilpc++;
}
free(cmd[lpc]->argv); /*Free Argv Itself */
}
if (cmd[lpc]->redirect_in != NULL)
free(cmd[lpc]->redirect_in); /*Free Redirect – In */
if (cmd[lpc]->redirect_out != NULL)
free(cmd[lpc]->redirect_out); /*Free Redirect – Out */
free(cmd[lpc]); /*Free the Command Structure */
lpc++;
}
free(cmd); /*Free the Array */
cmd = NULL;
return;
} /*End of clean_up() */
/*

  • This function dumps the contents of the structure to stdout.
    *
  • Arguments :
  • c – the structure to be displayed.
  • count – the array position of the structure.
    *
  • Returns :
  • None.
    *
    */
    void
    dump_structure(command * c, int count)
    {
    int lc = 0;

printf(“—- Command(%d) —-\n”, count);
printf(“%s\n”, c->com_name);
if (c->argv != NULL) {
while (c->argv[lc] != NULL) {
printf(“+-> argv[%d] = %s\n”, lc, c->argv[lc]);
lc++;
}
}
printf(“Background = %d\n”, c->background);
printf(“Redirect Input = %s\n”, c->redirect_in);
printf(“Redirect Output = %s\n”, c->redirect_out);
printf(“Pipe to Command = %d\n\n”, c->pipe_to);

return;
} /*End of dump_structure() */

/*

  • This function dumps the contents of the structure to stdout in a human
  • readable format..
    *
  • Arguments :
  • c – the structure to be displayed.
  • count – the array position of the structure.
    *
  • Returns :
  • None.
    *
    */
    void
    print_human_readable(command * c, int count)
    {
    int lc = 1;

printf(“Program : %s\n”, c->com_name);
if (c->argv != NULL) {
printf(“Parameters : “);
while (c->argv[lc] != NULL) {
printf(“%s “, c->argv[lc]);
lc++;
}
printf(“\n”);
}
if (c->background == 1)
printf(“Execution in Background.\n”);
if (c->redirect_in != NULL)
printf(“Redirect Input from %s.\n”, c->redirect_in);
if (c->redirect_out != NULL)
printf(“Redirect Output to %s.\n”, c->redirect_out);
if (c->pipe_to != 0)
printf(“Pipe Output to Command# %d\n”, c->pipe_to);
printf(“\n\n”);

return;
} /*End of print_human_readable() */
/
parser.h – description
——————-
begin : Fri Oct 4 2002
copyright : (C) 2002 by C Brookes
email :
/

/*

  • *
  • This program is free software; you can redistribute it and/or modify *
  • it under the terms of the GNU General Public License as published by *
  • the Free Software Foundation; either version 2 of the License, or *
  • (at your option) any later version. *
  • *
    */

ifndef _PARSER_H

define _PARSER_H

/*

  • Parser.h
  • Data structures and various defines for parser.c
  • Author : Michael Roberts mroberts@it.net.au
  • Last Update : 15/07/01
    */

include

include

include

/The length of the command line./

define CMD_LENGTH 256

/Whitespaces that are searched for/
// nick modified this
//static const char white_space[2] = { (char) 0x20, (char) 0x09 };
static const char white_space[3] = { (char) 0x20, (char) 0x09, (char) 0x00 };

/The Structure we create for the commands./
typedef struct Command_struct
{
char *com_name;
char **argv;
int background;
char *redirect_in;
char redirect_out; int pipe_to; } command; / Function prototypes added by Nick Nelissen 11/9/2001 */
command ** process_cmd_line(char *cmd,int);
void process_cmd(char *cmd, command * result);
void process_simple_cmd(char *cmd, command * result);
void clean_up(command ** cmd);
void clean_up(command ** cmd);
void clean_up(command ** cmd);

endif

References:

  1. Page 10 line 38: www-instruct.wccnet.org/~chassel/linux275/ClassNotes/process/myshell.htm
  2. Page 10 line 44: www.cs.bsu.edu/homepages/dlsills/davis_myshell.html
  3. Page 12 line 14: Unix System Programming Haviland pg 156
  4. Page 013 line 12: www-instruct.wccnet.org/~chassel/linux275/ClassNotes/process/myshell.htm
  5. Page 013 line 31: www.umsl.edu/~s1002145/msdos.html
  6. Page 14 line 9: www.umsl.edu/~s1002145/msdos.html
  7. Page 14 Line 37: Unix System Programming Haviland pg 113

bypass the Microsoft Account requirement during Windows setup

bypass the Microsoft Account requirement during Windows

bypass the Microsoft Account

Every few years, Microsoft is making it more difficult to create a local account during setup of the Windows operating system.

I described one option in How to use local accounts on Windows 11 version 22H2 devices. While written for that specific version, the described method works in other versions of Windows 11 as well.

The following two methods do not require a Microsoft account at all.

Bypass 1: OOBE\BYPASSNRO

This bypass is the easiest option right now, as it requires just a few steps during setup to skip the Microsoft account creation.

Here is how it works:

  1. Disable the Internet connection before starting setup, e.g., by disconnecting the LAN cable or disabling Wi-Fi.
  2. Windows will display a “Let’s connect you to a network” or similar screen. The upcoming Windows 11 version 22H2 does not allow you to skip this anymore to create a local account.
  3. On the screen, use Shift-F10 to open a command prompt window.
  4. Type OOBE\BYPASSNRO and hit the Enter-key.
  5. Windows will reboot and return to the “Let’s connect you to a network” screen. Only this time, you may select “I don’t have Internet” to skip this.
  6. Then you select “Continue with limited setup” to then create a local account during setup.

Bypass 2: Use a banned email address

Microsoft has banned email addresses that were used too often in the account creation process. You may use this to your advantage, as it allows you to skip the Microsoft account creation or sign-in phase during setup.

Here is how this method works (thanks Neowin):

  1. Select Sign-In when asked to create or sign-in to a Microsoft account during setup.
  2. Use the email address no@thankyou.com.
  3. Type any password on the next screen.
  4. Windows will display “Oops, something went wrong” on the next screen.
  5. Clicking Next opens a screen that allows you to create a local account.
  6. You can assign a password to the account, or leave it empty.

Reference

Clear Windows Event Viewer Logs

Clear Event Viewer Logs

how to erase the log files

Way 1. Clear All Event Logs in Event Viewer

Step 1. Press Win + R keys to open the Run dialog box, and then type eventvwr.msc in it and hit Enter.

open Event Viewer via the Run box

Step 2. Expand the Windows Logs category from the left sidebar, and then right-click a log (ex: Application) and select Clear Log.

select Clear Log in Event Viewer

Step 3. Click on Clear in the pop-up confirmation window.

click on Clear in the Event Viewer window

Here’s how to clear all event logs Windows 11. Also, you can try the following 4 methods.

Way 2. Clear Event Logs Using Command Prompt

Step 1. Type cmd in the search box, and then right-click the Command Prompt from the top result and select Run as administrator. Then click on Yes in the UAC window to confirm it.

open an elevated Command Prompt window

Step 2. In the elevated Command Prompt, type the following command and hit Enter.

for /F “tokens=*” %1 in (‘wevtutil.exe el’) DO wevtutil.exe cl “%1”

clear all event logs using the elevated Command Prompt

Once you clear all event logs Windows 11, you can close the Command Prompt window.

Way 3. Clear Event Logs Using Windows PowerShell

In addition to using Command Prompt, Windows PowerShell can help you clear event logs in Windows 11/10. Here’s how:

Step 1. Type powershell in the search box, and then right-click Windows PowerShell from the top result and select Run as administrator. Then click on Yes in the UAC window.

Step 2. In the elevated PowerShell window, type the following command and hit Enter to clear all event logs. Once done, close Windows PowerShell.

Get-EventLog -LogName * | ForEach { Clear-EventLog $_.Log }

clear event logs via Windows PowerShell

Way 4. Clear Event Logs Using a BAT File

You also can clear event logs in Windows 11/10 directly using a BAT file. For that:

Step 1. Clear here to download the Clear_Event_Viewer_Logs.bat file and save it to your desktop.

Step 2. Double click the bat file and click on Run in the pop-up window to unblock the file.

Step 3. Right-click the .bat file and select Run as administrator. Click on Yes if you are prompted by UAC. After that, an elevated Command Prompt will start clearing the event logs. Once finished, the Command Prompt window will automatically close.

run clear event logs bat file as administrator

How to clear all event logs Windows 11/10? The top 4 methods have been illustrated. Now, it’s your turn to have a try.

thanks to:

https://www.partitionwizard.com/partitionmanager/clear-all-event-logs-in-event-viewer.html

mx records cmd windows command line

mx records cmd windows command line

To use NSLOOKUP to view MX records:

  1. Open a command prompt.
  2. Type “nslookup” then press Enter.You will see the following:Default Server: <FQDN of your server>
    Address: <server IP address>
  3. Type “set type=mx” then press Enter.
  4. Type the domain name that you want to look up, then press Enter.The MX records of that domain will appear.

Clean MBR Partition Table with CMD

Remove clean MBR Partition Table via CMD command Prompt

To run Diskpart, you need to first open Command Prompt. Press Windows + R key combination to start Run box. This will take delete internal hard disk MBR partition for example.

  • Type “diskpart” in Run box and press Enter. Please run CMD as administrator.
  • Type “list disk”
  • Type “select disk X”. X is the disk number you want to convert.
  • Type “clean”. This will delete all partitions or volumes on the disk.
  • Type “convert gpt”.
  • Type “exit” to exit the Command Prompt

Reset Windows 10 password without utilman.exe

  • Boot from the Windows installation disk/USB stick with Windows setup.
  • Wait for the “Windows Setup” screen:
Windows 10 setup screen

  • Press Shift + F10 keys together on the keyboard. This will open the command prompt window:
  • In the command prompt, type regedit and press the Enter key. This will open Reg Editor
Windows 10 setup run regedit
  • Select HKEY_LOCAL_MACHINE key on the left.
  • After you select it, run the File -> Load Hive… menu command.
Windows 10 file load hive
  • In the load hive dialog, select the following file:
DRIVE:\Windows\System32\config\SYSTEM
  1. Enter any desired name for the hive you are loading. For example, I gave it a name 111:
  2. Go to the following key:HKEY_LOCAL_MACHINE\111\Setup
Windows 10 file named loaded hive
  • Edit the cmdline parameter and set it to cmd.exe
Windows 10 edit cmdline parameter
  • Change the SetupType DWORD parameter value to 2.
Windows 10 edit setuptype parameter
  • Now select 111 on the left and run the File -> Unload hive menu item in Regedit.
Windows 10 unload hive
  • Close Registry Editor and all open windows.
  • Reboot Windows and you will see the following command prompt at boot:
Windows 10 password reset mode
  • Type “net user”
  • Use the a current administrator account to reset password with the following command:
  • net user ‘username’ ‘newPassword’
  • e.g. net user chris apples123
  • Type “regedit” to open Regisry Editor.
  • Go to the following key:HKEY_LOCAL_MACHINE\System\Setup
  • Edit the cmdline parameter and set it to the empty value.
  • Change the SetupType DWORD parameter value to 0. See this screenshot:
Windows 10 reset registry values
  • Close that off and reset the power on the PC and next time you log in with that account use your new password.


Source ” https://winaero.com/blog/reset-windows-10-password-without-using-third-party-tools/


Call Now Button