BBS水木清华站∶精华区

发信人: gluon (皮条客~垃圾人~12:30-13:30,19:30-20:30), 信区: Linux        
标  题: 发呆机器人-可以按模式聊天 
发信站: BBS 水木清华站 (Wed Sep 15 13:25:20 1999) 
 
这个程序是在ylsdd的防止发呆的程序的基础上改的. 
主要功能: 
防止发呆,过一段时间会发出一个Ctl+L; 
能按给定的模式响应聊天信息; 
可以自动回msg; 
把整个上bbs过程写在bbs.log里 
使用方法: 
把fd.c和bbs.rule放在同一目录下. 
gcc -o fd fd.c 
fd 
程序是缺省连smth的,如果用于其它bbs要做改动.请看相关注释行. 
bbs.rule的定义方法是每行一个规则. 
&表示空格..是匹配任何字符串的通配符,0,1,2,3,4用来存放匹配的子串. 
例如: 
==>.&把&++&踢的死去活来 /a&一运气,0的腿就折了 
这句话就是定义了,当有人对聊天id为++的作如下动作: 
==>rika 把 ++ 踢的死去活来 
那么就返回"/a 一运气,rika的腿就折了" 
"==>"是smth上用的聊天提示符,若用于别的bbs请按实际情形改动. 
//fd.c 
#include <unistd.h> 
#include <signal.h> 
#include <fcntl.h> 
#include <termios.h> 
#include <sys/time.h> 
#include <sys/types.h> 
#include <sys/stat.h> 
#include <stdio.h> 
struct termios tsave; 
int match2(char *mod,char *set,char *answer) 

 int i,j,k,c,sign; 
 char ar[5][50]; 
 c=0; 
 j=0;k=0; 
 sign=0; 
 for(i=0;mod[i];i++)if(mod[i]=='&')mod[i]=' '; 
 i=0; 
 while(mod[i]) 
 { 
  if(mod[i]!='.') 
  { 
    if(mod[i]!=set[j])return 0; 
    i++;j++; 
  } 
  else 
  { 
   for(k=j+1;set[k];k++) 
   { 
    if(mod[i+1]==set[k]&&(mod[i+2]==set[k+1]||set[k]>0)) 
    { 
      i+=2; 
      strncpy(ar[c],set+j,k-j); 
      ar[c][k-j]=0; 
      j=k+1; 
      c++; 
      break; 
    } 
   } 
   if(!set[k])return 0; 
  } 
 } 
 j=0; 
 for(i=0;answer[i];i++) 
 { 
  if(answer[i]>='0'&&answer[i]<'5') 
   for(k=0;ar[answer[i]-'0'][k];k++)set[j++]=ar[answer[i]-'0'][k]; 
  else 
  { 
   if(answer[i]=='&')set[j++]=' '; 
   else set[j++]=answer[i]; 
  } 
 } 
 set[j]=0; 
 return 1; 

int match(char *buf,int *l) 

 char mod[1024],answer[1024]; 
 FILE *rulefile; 
 int i; 
 for(i=0;buf[i];i++)if(buf[i]==7) 
 { 
  strcpy(buf,"\r对不起,现在我不在,若有事请给我写信!"); 
 //可以换成你自己要回的信息. 
  *l=strlen(buf); 
  buf[*l]=13; 
  return 1; 
 } 
 rulefile=fopen("bbs.rule","r"); 
 while(fscanf(rulefile,"%s %s\n",mod,answer)==2) 
 { 
  if(match2(mod,buf,answer)) 
  { 
   *l=strlen(buf); 
   buf[*l]=13; 
   fclose(rulefile); 
   return 1; 
  } 
 } 
 fclose(rulefile); 
 return 0; 

void scan_mode(void) 
{  struct termios tbuf; 
   if(!isatty(0)) exit(1); 
   if(tcgetattr(0,&tbuf)==-1) exit(1); 
   tsave=tbuf; 
   tbuf.c_lflag&=~(ECHO|ICANON|ISIG); 
   tbuf.c_cc[VMIN]=tbuf.c_cc[VTIME]=0; 
   if(tcsetattr(0,TCSANOW,&tbuf)==-1) exit(1); 

void restore_mode(int i) 
{  tcsetattr(0,TCSANOW,&tsave); 
   exit(1); 

main(int argc, char **argv) 
{  int fdin[2], fdout[2]; 
   int fdw, fdr, i,logfile,j,k,sign; 
   fd_set rdfds; 
   struct timeval timeout; 
   char bufer[1024], bufer2[1024],ch=12; 
   if(pipe(fdin)==-1) exit(1); 
   if(pipe(fdout)==-1) exit(1); 
   switch(fork()) 
   {  case -1: exit(1); 
      case 0: 
              //printf("son\n"); 
              close(0); 
              dup(fdin[0]); 
              close(fdin[0]); 
              close(fdin[1]); 
              close(1); 
              dup(fdout[1]); 
              close(fdout[0]); 
              close(fdout[1]); 
              execl("/usr/bin/telnet","telnet","202.112.58.200",0); 
              //这里你可以把202.112.58.200换成别的bbs地址. 
              printf("failed %s", argv[1]); 
              exit(1); 
       default: 
                //printf("parient"); 
                close(fdin[0]); 
                fdw=fdin[1]; 
                close(fdout[1]); 
                fdr=fdout[0]; 
   } 
   scan_mode(); 
   (void)signal(SIGPIPE, restore_mode); 
   fcntl(0,F_SETFL,O_NONBLOCK); 
   fcntl(fdr, F_SETFL, O_NONBLOCK); 
   timeout.tv_sec=600; 
   timeout.tv_usec=0; 
   logfile=open("bbs.log",O_WRONLY|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR); 
   bufer2[0]=0; 
   k=0; 
   sign=0; 
   while(1) 
   {  FD_ZERO(&rdfds); 
      FD_SET(0,&rdfds); 
      FD_SET(fdr,&rdfds); 
      if(select(fdr+1,&rdfds,NULL,NULL,&timeout)) 
      {  i=read(0,bufer,1024); 
         if(i>0) 
         {  timeout.tv_sec=600; 
            timeout.tv_usec=0; 
            write(fdw,bufer,i); 
         } 
         i=read(fdr,bufer,1024); 
         if(i>0) 
         { 
          write(1,bufer,i); 
          for(j=0;j<i;j++) 
          { 
           if(bufer[j]!=13) 
           { 
            if(!sign) { 
            if(bufer[j]==27)sign=1; 
            else bufer2[k++]=bufer[j]; 
            } 
            else 
            { 
            if((bufer[j]>='a'&&bufer[j]<='z')||(bufer[j]>='A'&&bufer[j]<='Z')) 
            sign=0; 
            } 
           } 
           else 
           { 
            bufer2[k]=0; 
            write(logfile,bufer2,k); 
            bufer2[k-1]=0; 
            if(match(bufer2,&k))write(fdw,bufer2,k+1); 
            k=0; 
           } 
          } 
         } 
      }else 
       { 
         timeout.tv_sec=600; 
         timeout.tv_usec=0; 
         write(fdw,&ch,1); 
       } 
   } 

//end 
bbs.rule(你可以定义适合自己的规则,这只是个例子) 
==>.&把&++&踢的死去活来 /a&一运气,0的腿就折了 
==>.&轻吻&++&的脸颊 /a&的脸也绿了,眼也直了,0,这是真的吗? 
==>.&跟&++&握手 //pure&0 
==>.&对&++&露出纯真的笑容 //hand&0 
==>.&努力的摇摇&++&,在其耳边大叫:“快醒醒,会着凉的!” 0,没办法,现在俺不在 
==>.&敲了敲&++&的木瓜脑袋 别敲!俺有log的,回头和你0算账! 
==>.&热情的拥抱&++ /a&被0抱得喘不过气来 
==>.&对著&++&流口水 /a&把0的口水抹了0一身.:) 
==>.&瞪大眼睛,天真地问:&++&,你说什麽我不懂耶.&:( 嘿嘿 
==>.&向&++&卑躬屈膝,摇尾乞怜 /a&叹道:0你这条狗! 
==>.&用力的把&++&拧的黑青 /a&皱眉道:0你怎么跟女孩子似的! 
==>.&无奈地向&++&耸了耸肩膀 看我昵称就知道我啥时在 
==>.&啪啪的巴了&++&一顿耳光 /a&跺脚道:0,你.你.怎么这样?哼!不理你了! 
==>.&对&++&神秘的眨眨眼睛 干什么?0,想勾引我?:P 
==>.&轻轻地拥抱&++ /a&用舌头舔0的脸 
==>.:.bye c&u&la&la! 
==>.:.再见 /a&向0挥手致意. 
==>.:.hi 0,你好! 
==>.:.++.~ /a&和0热情拥抱 
==>.++.? 我不告诉你! 
==>.++.! 嘿嘿 
 
-- 
思考的人不恋爱,恋爱的人不思考.//sigh 
 
※ 来源:·BBS 水木清华站 bbs.net.tsinghua.edu.cn·[FROM: 162.105.21.159] 

BBS水木清华站∶精华区