/* *advsh The Adventure Shell - re-implemented in C for great justice * *[not to mention speed]. *[and just for the exercise] */ #include #include #include #include #include #include #include #include void changedir(char *nextdir,char *curdir); void displayhelp(); char *getverb(char *command); char *gjlbasename(char *fullpath); int main(int argc, char **argv) { extern int errno; char curdir[BUFSIZ],nextdir[BUFSIZ],*homedir,command[BUFSIZ],noun[BUFSIZ],verb[BUFSIZ],spell[BUFSIZ],invv[5][BUFSIZ],movefile[BUFSIZ]; glob_t globresults; int status,knownflag; unsigned int i,j,invc; struct stat filestat; pid_t spellpid; homedir=getenv("HOME"); strcpy(nextdir,homedir); strcpy(curdir,"/"); /*We first change to the / directory, on the basis that it exists. *Then try to change to the user's home directory, in case that doesn't. */ if(chdir(curdir)) { fprintf(stderr,"advsh: could not cd to /: %s\n",strerror(errno)); fprintf(stderr,"advsh: in my book, that's a bit fatal.\n"); exit(EXIT_FAILURE); } changedir(nextdir,curdir); invc=0; printf("This is advsh - the Adventure Shell\n"); printf("Inspired by a shell script by John \"Unix God\" Coker\n"); printf("Implemented in C by Acolyte Leeg\n\n"); printf("Do you require instructions (y/n)? "); fgets(command,BUFSIZ,stdin); if(!strncmp(command,"y",1) || !strncmp(command,"Y",1)) { displayhelp(); } while(!feof(stdin)) { strcpy(command,""); if(!strcmp(curdir,homedir)) { printf("You are standing in your house.\n"); } else { printf("You are currently in %s\n",curdir); } status=glob("*",0,NULL,&globresults); printf("Available exits:\n"); if(strcmp(curdir,"/")) printf("up/\t"); j=0; for(i=0;i70) {printf("\n"); j=0;} } } printf("\n\nObjects here are:\n"); j=0; for(i=0;i70) {printf("\n"); j=0;} } } globfree(&globresults); printf("\n? "); fgets(command,BUFSIZ,stdin); command[strlen(command)-1]='\0'; if(!strcmp(command,"quit game") || feof(stdin)) { printf("OK, thanks for playing advsh! Goodbye!\n"); exit(EXIT_SUCCESS); } knownflag=0; strcpy(verb,getverb(command)); if(!strcmp(verb,"go")) { knownflag=1; strcpy(noun,&command[3]); if(!strcmp(noun,"up")) strcpy(noun,".."); if(!strcmp(noun,"~")) strcpy(noun,homedir); changedir(noun,curdir); } if(!strcmp(verb,"cast")) { knownflag=1; strcpy(noun,&command[5]); if(!strcmp(noun,"spell")) { printf("Enter the spell to cast: "); fgets(spell,BUFSIZ,stdin); spell[strlen(spell)-1]='\0'; status=system(spell); if(status==-1) { fprintf(stderr,"Your spell fizzles in the humid air and does nothing.\n"); } else { printf("\nYour spell causes those around you to see '%d' projected against the sky.\n\n",status); } } else fprintf(stderr,"I have no smegging clue how to cast one of THOSE.\n\n"); } if(!strcmp(verb,"invoke")) { knownflag=1; strcpy(noun,&command[7]); if(!strcmp(noun,"spell")) { printf("Enter the spell to invoke: "); fgets(spell,BUFSIZ,stdin); spell[strlen(spell)-1]='\0'; spellpid=fork(); if(spellpid==-1) { fprintf(stderr,"Your spell fizzles in the air and does nothing.\n"); fprintf(stderr,"A representative from the Wights and Spectres Union gives you a message.\nIt reads: %s\n\n",strerror(errno)); } else { if(spellpid==0) { /* work out how to separate the string into an arg list */ /* execl() the above */ } else { printf("Your invocation succeeds, and scuttles into the distance. It seems to have\nleft some marking on the ground, which reads: %d\n\n",spellpid); } } } else { fprintf(stderr,"I'm not invoking that, I can't remember the symbol of Yog-Sothoth.\n\n"); } } if(!strcmp(verb,"speak")) { knownflag=1; strcpy(noun,&command[6]); if(!strcmp(noun,"help")) { displayhelp(); } else { printf("I don't know what you want me to say!\n\n"); } } if(!strcmp(verb,"search")) { knownflag=1; strcpy(noun,&command[7]); if(!strcmp(noun,"carefully")) { printf("You scrabble around the area for hidden items.\n"); #ifdef GLOB_PERIOD status=glob(".*",GLOB_PERIOD,NULL,&globresults); #else status=glob(".*",NULL,NULL,&globresults); #endif /*GLOB_PERIOD*/ j=0; printf("You have found:\n"); if(globresults.gl_pathc) { printf("\n"); for(i=0;i70) { j=0; printf("\n"); } } } } else printf("naff all.\n\n"); } else { printf("You find nothing of interest.\n\n"); } } if(!strcmp(verb,"attack")) { knownflag=1; strcpy(noun,&command[7]); printf("You bash at the evil %s with all of your might.\n",noun); status=unlink(noun); if(status==-1) { printf("But your attempts are in vain.\n"); printf("A wicked jester appears! He cackles maniacally, and says\n\"%s\"\n\n",strerror(errno)); } else { printf("The evil %s crumples and disappears in a puff of smoke!\n",noun); printf("You gain an experience point.\n\n"); } } if(!strcmp(verb,"create")) { knownflag=1; strcpy(noun,&command[7]); printf("You mumble an arcane incantation.\n"); status=mknod(noun,S_IFREG|0666,0); if(status==-1) { printf("Nothing happens for a while, then a face appears in the wall!\n"); printf("Its crude caricature of a mouth snarls and says\n"); printf("%s\n\n",strerror(errno)); } else { printf("Your attempt to create a %s was successful.\n\n",noun); } } if(!strcmp(verb,"take")) { knownflag=1; strcpy(noun,&command[5]); if(!strcmp(noun,"inventory")) { if(!invc) { printf("You are not carrying anything.\n"); } else { printf("You are carrying: \n"); for(i=0;i:\t\tuse an exit\n"); printf("speak help:\t\tspeak this verse\n"); printf("cast spell:\t\tcast a UNIX spell\n"); printf("invoke spell:\t\tlike casting but it happens in the background\n"); printf("search carefully:\texamine the surroundings for hidden objects\n"); printf("attack :\tattempt to destroy an evil entity\n"); printf("create :\tattempt to generate an object\n"); printf("get :\t\tput an object into your inventory\n"); printf("drop :\t\tleave an object in your current location\n"); printf("take inventory:\t\tshows what is being carried (useful!)\n"); printf("quit game:\t\texit advsh\n\n"); printf("Press return to continue with the adventure!\n"); fgets(snafu,BUFSIZ,stdin); } char *getverb(char *command) { char *noun; unsigned int i; noun=(char *)malloc(BUFSIZ*sizeof(char)); strcpy(noun,command); for(i=0;ifullpath-1;i--) { if(*i=='/') { return(i+1); } } return fullpath; }