mile1982
09-13-2004, 01:45 AM
hey there
well i have a small problem with my code. when for example :
" /bin/sleep 10 & ls -l mila > xyz " is entered, the program is supposed to separate the two commands 1) /bin/sleep 10 & and 2) ls -l mila > xyz. im not sure of how to achieve this. my current program stores both commands as one, eg: the same command is entered as above:
Command[0]:
com_pathname=/bin/sleep
argc=5
argv[0]=/bin/sleep
argv[1]=10
argv[2]=ls
argv[3]=-lt
argv[4]=mila
#######
redirect_in=NULL
redirect_out=pero
com_suffix=
the correct version would be:
Command[0]:
com_pathname=/bin/sleep
argc=2
argv[0]=/bin/sleep
argv[1]=10
#######
redirect_in=NULL
redirect_out=pero
com_suffix= &
Command[1]:
com_pathname=ls
argc=3
argv[0]=ls
argv[1]=-lt
argv[2]=mila
#######
redirect_in=NULL
redirect_out=pero
com_suffix=
---
when only one command is entered, the program stores correctly.
here's the code so if anyone could help, would appreciate it:
//---------------------------------------------------------------------------------------------------
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
/*function prototypes*/
void student_details();
void option_exit();
void printComStruct(struct command *com);
//---------------------------------------------------------------------------------------------------
struct command {
char *com_pathname; // what is the path name of the command
int argc; // the number of arguments to the command
// including the command itself
char *argv[40]; // pointers to strings, each string
// is an argument for the command, including
// argument "0". The last pointer should
// be set to NULL.
char *redirect_in; // if this is not NULL, then the standard input
// is redirected to the given file name
char *redirect_out; // if this is not NULL, then the standard output
// is redirected to the given file name
char *com_suffix; // ' ' - no command suffix (last command);
// '&' - the command is followed by '&'
// ';' - the command is followed by ';';
// '|' - the command is followed by '|'.
};
//---------------------------------------------------------------------------------------------------
int main() {
/*declaration*/
char *guess = "exit";
char line[256];
char *break_set = "\n\f\v\\\"~!@#$%^*()_=+'' [] {}:?,";
int nCommands = 0; // number of commands in a command line
int state = 0; // if a file has been redirected either way
// this changes to 1
int i = 0;
int c;
struct command com[10]; // storage for each command
com->argc = 0;
student_details(); /*present information about the user*/
/*introduction of what the program is supposed to do*/
printf(" Hello and welcome to my program\n");
printf("\n");
printf(" This program will repeatedly take one line of input \n");
printf(" from the console until the input line is 'exit'. For \n");
printf(" each input line, break it down into tokens. The input \n");
printf(" line should result in a 'dump' of the raw contents of \n");
printf(" several structures, depending on how many commands \n");
printf(" were given.\n");
printf("\n");
printf(" Mila's Shell> ");
// increment number of commands by 1 because
// it is start of the program
nCommands++;
while (gets (line)) {
char *tokp;
char *sp = line;
while ((tokp = strtok(sp,break_set)) != NULL) {
if (strlen(tokp)==1) { /* if the length of the character is 1 */
switch (*tokp) { /* switch on the first char */
case '>': /* output is redirected */
state = 1;
break;
case '<': /* output is redirected */
state = 2;
break;
case '|': /* directs the standard output of one Unix command into the
standard input of another Unix command. */
com[nCommands-1].com_suffix = tokp;
break;
case '&': /* a command shall run in the background */
// save in suffix
com[nCommands-1].com_suffix = tokp;
break;
case ';': /* end of command */
// save in suffix
com[nCommands-1].com_suffix = tokp;
break;
} // end switch
} // end if
// ---------------------
else {
if (state == 1) {
com[nCommands-1].redirect_out = tokp;
}
if (state == 2) {
com[nCommands-1].redirect_in = tokp;
}
else if (state == 0) {
// save token as argument for command
// argv = arguments for commands
// argc = number of arguments to the command;
com->argc++;
com->argv[com->argc -1] = tokp;
/*
* everytime the program is started the first argument of
* the input line is stored as the first command
*/
if (com->argc == 1) {
com[0].com_pathname = tokp;
}
// -------------------------
com[nCommands-1].redirect_in = NULL;
com[nCommands-1].redirect_out = NULL;
com[nCommands-1].com_suffix = NULL;
// ---------------------------
sp = NULL; // continue in this string
} // end else if
} // end else
} // end while
/*
* checks if the input line equals 'exit'. if it does
* the function option_exit is called and the
* program terminated. if it does not, another
* prompt is displayed to allow the user to enter
* more commands
*/
if(strcmp(line,guess) == 0) {
option_exit();
}
else {
com->argv[com->argc] = NULL;
// print command structures
printf("\n");
fprintf(stderr, "*** ICT310 construct dump begin ***\n");
for (i = 0; i < nCommands; ++i) {
fprintf(stderr, " Command[%d]: \n", i);
printComStruct(&com[i]);
for (c = 0; c < com->argc; c++) {
com->argv[c] = NULL;
}
com->argc = 0;
nCommands = 0;
state = 0;
}
fprintf(stderr, "*** ICT310 construct dump end ***\n");
for (c = 0; c < com->argc; c++) {
com->argv[c] = NULL;
}
com->argc = 0;
nCommands = 0;
state = 0;
printf("\n");
printf("\n Mila's Shell> ");
nCommands++;
// everytime a user is presented the prompt, increment
// the number of comamnds by 1;
} // end else
} // end while
return 0;
} // end function main()
//---------------------------------------------------------------------------------------------------
void student_details() { /*function definition*/
/*student's details*/
printf("\n");
printf("\n");
printf(" Student's Name: Milos Zdravic\n");
printf("\n");
} /*end of function*/
//---------------------------------------------------------------------------------------------------
void option_exit() { /* exit option*/
printf("\n");
printf("\n");
printf(" Thanks for using my program. Wasn't too bad I hope!!!");
fflush(stdin);
printf("\n");
exit(0);
} /*end of function*/
//---------------------------------------------------------------------------------------------------
void printComStruct(struct command *com) { /* print function */
int i;
fprintf(stderr,"com_pathname=%s\n", com->com_pathname);
fprintf(stderr,"argc=%d\n", com->argc);
for(i=0; com->argv[i] != NULL; i++) {
fprintf(stderr,"argv[%d]=%s\n", i, com->argv[i]);
}
fprintf(stderr,"#######\n");
if (com->redirect_in == NULL)
fprintf(stderr,"redirect_in=NULL\n");
else
fprintf(stderr,"redirect_in=%s\n", com->redirect_in);
if (com->redirect_out == NULL)
fprintf(stderr,"redirect_out=NULL\n");
else
fprintf(stderr,"redirect_out=%s\n", com->redirect_out);
fprintf(stderr,"com_suffix=%c\n\n", com->com_suffix);
} /*end of function*/
//---------------------------------------------------------------------------------------------------
well i have a small problem with my code. when for example :
" /bin/sleep 10 & ls -l mila > xyz " is entered, the program is supposed to separate the two commands 1) /bin/sleep 10 & and 2) ls -l mila > xyz. im not sure of how to achieve this. my current program stores both commands as one, eg: the same command is entered as above:
Command[0]:
com_pathname=/bin/sleep
argc=5
argv[0]=/bin/sleep
argv[1]=10
argv[2]=ls
argv[3]=-lt
argv[4]=mila
#######
redirect_in=NULL
redirect_out=pero
com_suffix=
the correct version would be:
Command[0]:
com_pathname=/bin/sleep
argc=2
argv[0]=/bin/sleep
argv[1]=10
#######
redirect_in=NULL
redirect_out=pero
com_suffix= &
Command[1]:
com_pathname=ls
argc=3
argv[0]=ls
argv[1]=-lt
argv[2]=mila
#######
redirect_in=NULL
redirect_out=pero
com_suffix=
---
when only one command is entered, the program stores correctly.
here's the code so if anyone could help, would appreciate it:
//---------------------------------------------------------------------------------------------------
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
/*function prototypes*/
void student_details();
void option_exit();
void printComStruct(struct command *com);
//---------------------------------------------------------------------------------------------------
struct command {
char *com_pathname; // what is the path name of the command
int argc; // the number of arguments to the command
// including the command itself
char *argv[40]; // pointers to strings, each string
// is an argument for the command, including
// argument "0". The last pointer should
// be set to NULL.
char *redirect_in; // if this is not NULL, then the standard input
// is redirected to the given file name
char *redirect_out; // if this is not NULL, then the standard output
// is redirected to the given file name
char *com_suffix; // ' ' - no command suffix (last command);
// '&' - the command is followed by '&'
// ';' - the command is followed by ';';
// '|' - the command is followed by '|'.
};
//---------------------------------------------------------------------------------------------------
int main() {
/*declaration*/
char *guess = "exit";
char line[256];
char *break_set = "\n\f\v\\\"~!@#$%^*()_=+'' [] {}:?,";
int nCommands = 0; // number of commands in a command line
int state = 0; // if a file has been redirected either way
// this changes to 1
int i = 0;
int c;
struct command com[10]; // storage for each command
com->argc = 0;
student_details(); /*present information about the user*/
/*introduction of what the program is supposed to do*/
printf(" Hello and welcome to my program\n");
printf("\n");
printf(" This program will repeatedly take one line of input \n");
printf(" from the console until the input line is 'exit'. For \n");
printf(" each input line, break it down into tokens. The input \n");
printf(" line should result in a 'dump' of the raw contents of \n");
printf(" several structures, depending on how many commands \n");
printf(" were given.\n");
printf("\n");
printf(" Mila's Shell> ");
// increment number of commands by 1 because
// it is start of the program
nCommands++;
while (gets (line)) {
char *tokp;
char *sp = line;
while ((tokp = strtok(sp,break_set)) != NULL) {
if (strlen(tokp)==1) { /* if the length of the character is 1 */
switch (*tokp) { /* switch on the first char */
case '>': /* output is redirected */
state = 1;
break;
case '<': /* output is redirected */
state = 2;
break;
case '|': /* directs the standard output of one Unix command into the
standard input of another Unix command. */
com[nCommands-1].com_suffix = tokp;
break;
case '&': /* a command shall run in the background */
// save in suffix
com[nCommands-1].com_suffix = tokp;
break;
case ';': /* end of command */
// save in suffix
com[nCommands-1].com_suffix = tokp;
break;
} // end switch
} // end if
// ---------------------
else {
if (state == 1) {
com[nCommands-1].redirect_out = tokp;
}
if (state == 2) {
com[nCommands-1].redirect_in = tokp;
}
else if (state == 0) {
// save token as argument for command
// argv = arguments for commands
// argc = number of arguments to the command;
com->argc++;
com->argv[com->argc -1] = tokp;
/*
* everytime the program is started the first argument of
* the input line is stored as the first command
*/
if (com->argc == 1) {
com[0].com_pathname = tokp;
}
// -------------------------
com[nCommands-1].redirect_in = NULL;
com[nCommands-1].redirect_out = NULL;
com[nCommands-1].com_suffix = NULL;
// ---------------------------
sp = NULL; // continue in this string
} // end else if
} // end else
} // end while
/*
* checks if the input line equals 'exit'. if it does
* the function option_exit is called and the
* program terminated. if it does not, another
* prompt is displayed to allow the user to enter
* more commands
*/
if(strcmp(line,guess) == 0) {
option_exit();
}
else {
com->argv[com->argc] = NULL;
// print command structures
printf("\n");
fprintf(stderr, "*** ICT310 construct dump begin ***\n");
for (i = 0; i < nCommands; ++i) {
fprintf(stderr, " Command[%d]: \n", i);
printComStruct(&com[i]);
for (c = 0; c < com->argc; c++) {
com->argv[c] = NULL;
}
com->argc = 0;
nCommands = 0;
state = 0;
}
fprintf(stderr, "*** ICT310 construct dump end ***\n");
for (c = 0; c < com->argc; c++) {
com->argv[c] = NULL;
}
com->argc = 0;
nCommands = 0;
state = 0;
printf("\n");
printf("\n Mila's Shell> ");
nCommands++;
// everytime a user is presented the prompt, increment
// the number of comamnds by 1;
} // end else
} // end while
return 0;
} // end function main()
//---------------------------------------------------------------------------------------------------
void student_details() { /*function definition*/
/*student's details*/
printf("\n");
printf("\n");
printf(" Student's Name: Milos Zdravic\n");
printf("\n");
} /*end of function*/
//---------------------------------------------------------------------------------------------------
void option_exit() { /* exit option*/
printf("\n");
printf("\n");
printf(" Thanks for using my program. Wasn't too bad I hope!!!");
fflush(stdin);
printf("\n");
exit(0);
} /*end of function*/
//---------------------------------------------------------------------------------------------------
void printComStruct(struct command *com) { /* print function */
int i;
fprintf(stderr,"com_pathname=%s\n", com->com_pathname);
fprintf(stderr,"argc=%d\n", com->argc);
for(i=0; com->argv[i] != NULL; i++) {
fprintf(stderr,"argv[%d]=%s\n", i, com->argv[i]);
}
fprintf(stderr,"#######\n");
if (com->redirect_in == NULL)
fprintf(stderr,"redirect_in=NULL\n");
else
fprintf(stderr,"redirect_in=%s\n", com->redirect_in);
if (com->redirect_out == NULL)
fprintf(stderr,"redirect_out=NULL\n");
else
fprintf(stderr,"redirect_out=%s\n", com->redirect_out);
fprintf(stderr,"com_suffix=%c\n\n", com->com_suffix);
} /*end of function*/
//---------------------------------------------------------------------------------------------------