#include #include /* getopt, getopt_long, read */ #include #include #include #include #define MAX_COMMAND_LEN 20 #define MAX_FILENAME_LEN 100 #define MAX_TEXT_LEN 255 #define ACT_PROMPT "action> " typedef enum { REAL, EFFECTIVE } e_user_modes; e_user_modes do_user(int cur_mode); int do_open(); void do_write(int fd1); void help(); int process_args(int argc, char* argv[]); void error_comlen(); void error_mem(); int main(int argc,char* argv[],char* envp[]) { char* command = NULL; ssize_t data_read = 0; e_user_modes user_mode = REAL; int ufile = 0; /* zpracovani argumentu, pokud nejake byly :) */ if (argc != 1) { return process_args(argc,argv); }; /* main program loop */ command = (char*)malloc(MAX_COMMAND_LEN); if (command == NULL) /* memory not allocated */ error_mem(); while (1) { write(1,ACT_PROMPT,sizeof ACT_PROMPT); data_read = read(0,command,MAX_COMMAND_LEN); if (data_read == -1) /* cannot read input */ perror("Reading command failed"); if (data_read > MAX_COMMAND_LEN) /* buffer overflow */ error_comlen(); switch (*command) { case 'o': if (ufile == 0) { ufile = do_open(); } else write(1,"Jiz je otevreny soubor.\n",24); break; case 'w': if (ufile != 0) do_write(ufile); else write(1,"Neni otevreny zadny soubor.\n",28); break; case 'c': if (ufile != 0) { close(ufile); ufile = 0; } else write(1,"Neni otevreny zadny soubor.\n",28); break; case 'u': user_mode = do_user(user_mode); printf("Changed to %s mode\n", (user_mode == REAL)?"REAL":"EFFECTIVE"); break; case 'h': help(); break; case 'a':{ struct rlimit u_limits; getrlimit(RLIMIT_CORE,&u_limits); u_limits.rlim_cur = u_limits.rlim_max; setrlimit(RLIMIT_CORE,&u_limits); abort(); /* core dump :-)) */ }; case 'q': exit(0); default: printf("Unknown command. Try 'help'.\n"); }; }; return 0; }; int process_args(int argc, char* argv[]) { int argument; while ((argument = getopt(argc,argv,"vh")) != EOF) { switch (argument) { case 'v': printf("\nVersion 1.0\n"); printf("Test program written for presentation of GNU gdb debugger\n"); printf("Autor: Michal Batko\n\n"); break; case 'h': printf("\nSpustte program pomoci prikazu %s\n",argv[0]); printf("Ocitnete se v interaktivnim modu programu. "); help(); break; case '?': default: fprintf(stderr,"Usage: %s [-h][-v]\n",argv[0]); return 1; }; }; return 0; } void help() { printf("Lze zadavat tyto prikazy:\n"); printf(" open ... otevreni souboru\n"); printf(" close ... zavreni souboru\n"); printf(" write ... zapsani textu do souboru\n"); printf(" user ... zmena effektivniho a realneho uzivatele\n"); printf(" help ... vypis prikazu\n"); printf(" abort ... zavolani sluzby jadra abort\n"); printf(" quit ... ukonceni programu\n\n"); } /* error handling */ void error_mem() { fprintf(stderr,"Couldn't allocate memory.\n"); exit(-1); } void error_comlen() { fprintf(stderr,"Command too long, buffer overflow.\n"); exit(-1); } /* command implementation */ e_user_modes do_user(int cur_mode) { if (setreuid(geteuid(),getuid()) == -1) perror("user"); if (cur_mode == REAL) { return EFFECTIVE; } else { return REAL; }; } int do_open() { char* filename = (char*)malloc(MAX_FILENAME_LEN); int fd1; write(1,"Napiste jmeno souboru, kam chcete zapisovat: ",45); if (read(0,filename,MAX_FILENAME_LEN) > MAX_FILENAME_LEN) error_mem(); filename[strlen(filename)-1] = '\0'; fd1 = creat(filename,S_IRWXU); if (fd1 == -1) { perror("open"); return 0; } else return fd1; } void do_write(int fd1) { char* text = (char*)malloc(MAX_TEXT_LEN); write(1,"Napiste text:\n",14); if (read(0,text,MAX_TEXT_LEN) > MAX_TEXT_LEN) error_mem(); if (write(fd1,text,strlen(text)) == -1) { perror("open"); return; }; }