/*********************************************************************/ /* file: main.c - main module - signal setup/shutdown etc */ /* TINTIN III */ /* (T)he K(I)cki(N) (T)ickin D(I)kumud Clie(N)t */ /* coded by peter unold 1992 */ /*********************************************************************/ #include <stdio.h> #include <string.h> #include <signal.h> #include "tintin.h" #ifndef BADSIG #define BADSIG (void (*)())-1 #endif /*************** globals ******************/ int term_echoing=TRUE; int echo=DEFAULT_ECHO; int ignore=DEFAULT_IGNORE; int speedwalk=DEFAULT_SPEEDWALK; int sessionsstarted; struct session *sessionlist, *activesession; struct listnode *common_aliases, *common_actions, *common_subs; char vars[10][BUFFER_SIZE]; /* the &0, &1, &2,....&9 variables */ char tintin_char=DEFAULT_TINTIN_CHAR; /************ externs *************/ extern int ticker_interrupted, time0; extern int tick_size, sec_to_tick; extern int ignore; /**************************************************************************/ /* main() - show title - setup signals - init lists - readcoms - tintin() */ /**************************************************************************/ main(int argc, char *argv[]) { puts("##################################################"); puts("# T I N T I N #"); puts("# version III #"); puts("# (T)he k(I)cki(N) (T)ickin d(I)kumud clie(N)t #"); puts("# a DIKU-mud client coded by peter unold 1992. #"); puts("##################################################"); prompt(NULL); if(signal(SIGTERM, myquitsig)==BADSIG) syserr("signal SIGTERM"); if(signal(SIGINT, myquitsig)==BADSIG) syserr("signal SIGINT"); if(signal(SIGALRM, tick_func)==BADSIG) syserr("signal SIGALRM"); time0=time(NULL); alarm(1); common_aliases=init_list(); common_actions=init_list(); common_subs=init_list(); if(argv[1]) activesession=read_command(argv[1], NULL); tintin(); } /***************************/ /* the main loop of tintin */ /***************************/ void tintin() { char buffer[BUFFER_SIZE]; int didget; int readfdmask; struct session *sesptr; while(TRUE) { readfdmask=1; for(sesptr=sessionlist; sesptr; sesptr=sesptr->next) readfdmask|=sesptr->socketbit; ticker_interrupted=FALSE; if(select(32, &readfdmask, 0, 0, 0)<0 && !ticker_interrupted) syserr("select"); if(ticker_interrupted) ticker_interrupted=FALSE; else { if(readfdmask&1) { if((didget=read(0, buffer, sizeof(buffer)))<0) syserr("read from fd 0"); *(buffer+didget-1)='\0'; if(activesession && term_echoing) do_history(buffer, activesession); activesession=parse_input(buffer, activesession); } for(sesptr=sessionlist; sesptr; sesptr=sesptr->next) if(sesptr->socketbit&readfdmask) read_mud(sesptr); } } } /*************************************************************/ /* read text from mud and test for actions/snoop/substitutes */ /*************************************************************/ void read_mud(struct session *ses) { char buffer[BUFFER_SIZE], subresult[BUFFER_SIZE], linebuffer[BUFFER_SIZE], *cp, *cpsource, *cpdest; int didget; if(!(didget=read_buffer_mud(buffer, ses))) { cleanup_session(ses); if(ses==activesession) activesession=newactive_session(); } else { if(ses->logfile) fwrite(buffer, didget, 1, ses->logfile); do_all_subs(buffer, subresult, ses); if(ses==activesession) write(1, subresult, strlen(subresult)); else if(ses->snoopstatus) snoop(buffer, ses); if(!ignore) split_check_all_actions(buffer, ses); } } /**********************************************************/ /* snoop session ses - chop up lines and put'em in buffer */ /**********************************************************/ void snoop(char *buffer, struct session *ses) { int n; char *cpsource, *cpdest, linebuffer[BUFFER_SIZE]; putchar('\n'); cpsource=buffer; cpdest=linebuffer; while(*cpsource) { /*cut out each of the lines and sub'em if a sub is triggered*/ if(*cpsource=='\n' || *cpsource=='\r') { *cpdest='\0'; if(*linebuffer!='\0') printf("%s%% %s\n", ses->name, linebuffer); if(*cpsource=='\n' || *cpsource=='\r') cpsource++; cpdest=linebuffer; } else *cpdest++=*cpsource++; } *cpdest='\0'; if(*linebuffer!='\0') printf("%s%% %s\n", ses->name, linebuffer); } /*****************************************************/ /* output to screen should go throught this function */ /* text gets checked for actions */ /*****************************************************/ void tintin_puts(char *cptr, struct session *ses) { if(ses==activesession || ses==NULL) { printf("%s\n\r", cptr); prompt(ses); } if(ses) check_all_actions(cptr, ses); } /****************************************/ /* alarm signal handler used for ticker */ /****************************************/ static void tick_func() { ticker_interrupted=TRUE; alarm(1); if(signal(SIGALRM, tick_func)==BADSIG) syserr("signal SIGALRM"); sec_to_tick=tick_size-((time(NULL)-time0)%tick_size); if(sec_to_tick==tick_size || sec_to_tick==10) { struct session *sesptr; for(sesptr=sessionlist; sesptr; sesptr=sesptr->next) if(sesptr->tickstatus) if(sec_to_tick==tick_size) tintin_puts("#TICK!!!", sesptr); else tintin_puts("#10 SECONDS TO TICK!!!", sesptr); } } /**********************************************************/ /* Here's where we go when we wanna quit TINTIN FAAAAAAST */ /**********************************************************/ static void myquitsig() { struct session *sesptr; for(sesptr=sessionlist; sesptr; sesptr=sesptr->next) cleanup_session(sesptr); puts("\n\rYour fireball hits TINTIN with full force, causing an immediate death."); puts("TINTIN is dead! R.I.P."); puts("Your blood freezes as you hear TINTIN's death cry."); exit(0); }