荔园在线

荔园之美,在春之萌芽,在夏之绽放,在秋之收获,在冬之沉淀

[回到开始] [上一篇][下一篇]


发信人: jjk (UNIX+C+XML+?? 傻了?), 信区: Linux
标  题: bbs post                               guru (转寄)[转载]
发信站: 荔园晨风BBS站 (Thu Apr 25 10:25:40 2002), 转信

【 以下文字转载自 jjk 的信箱 】
【 原文由 jjk.bbs@apue.dhs.org 所发表 】
/* 这是一个向bbs自动发文章的程序,它可以把硬盘上的一篇文章发到bbs server的  *
/
/* 某个版中,适合于网络速度慢的情况下发表文章,减少等待时间                  *
/
/* 只是本程序依赖于具体的上站按键序列,自然要因bbs server的不同和你在       *
/
/* bbs server上的ID的不同而加以修改                                        *
/
/* 另外下面的字符 ^W的输入方法如下: 左手按住Ctrl键不放,右手先按V,再按W     *
/
/* ^P的输入方法相同. 为了不影响我发这篇文章,我把它们都改成了两个字符,即    *
/
/* ^W改为^和W,^P改为^和P,编译之前需要改回来                                *
/
/* 不要把本程序用来干坏事,那不是本人所希望看到的                           *
/
/* 作者: Netguy                             1998.1.3                       *
/
/* 本程序适用于UNIX系统,编译方法为:                                        *
/
/* Linux: cc -lbsd -o post  post.c                                         *
/
/* SunOS: cc -lsocket -lnsl -lucb -o post post.c                           *
/
#include <stdio.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/socket.h>
#include <sys/signal.h>
#include <sys/time.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#define N      26
#define M      5
#define BOARD  19
#define TITLE  23
#define SIZE   1024
#define TRUE   -1
#define FALSE  0
#define NUM_OF_BOARD  105
char *boardName[NUM_OF_BOARD]={
"211",                               /*   1 */
"Campus",                            /*   2 */
"Education",                         /*   3 */
"Endusers",                          /*   4 */
"Schools",                           /*   5 */
"Student",                           /*   6 */
"Tsinghua",                          /*   7 */
"UESTC",                             /*   8 */
"Office12",                          /*   9 */
"Office11",                          /*  10 */
"Office13",                          /*  11 */
"Office9",                           /*  12 */
"Office5",                           /*  13 */
"Office6",                           /*  14 */
"Office4",                           /*  15 */
"Office2",                           /*  16 */
"Office15",                          /*  17 */
"Office10",                          /*  18 */
"Office1",                           /*  19 */
"Office17",                          /*  20 */
"Office16",                          /*  21 */
"Office8",                           /*  22 */
"Office3",                           /*  23 */
"Office14",                          /*  24 */
"AR",                                /*  25 */
"Chemistry",                         /*  26 */
"CS",                                /*  27 */
"EE",                                /*  28 */
"Graduate",                          /*  29 */
"Material",                          /*  30 */
"MBA",                               /*  31 */
"Office7",                           /*  32 */
"PPCenter",                          /*  33 */
"Transportation",                    /*  34 */
"3com",                              /*  35 */
"AIX",                               /*  36 */
"IBMNetwork",                        /*  37 */
"IntelNetwork",                      /*  38 */
"Modem",                             /*  39 */
"Netscape",                          /*  40 */
"Oracle",                            /*  41 */
"Router",                            /*  42 */
"Solaris",                           /*  43 */
"Sybase",                            /*  44 */
"Telecom",                           /*  45 */
"3D",                                /*  46 */
"Browser",                           /*  47 */
"CAD",                               /*  48 */
"Database",                          /*  49 */
"Freeware",                          /*  50 */
"Game",                              /*  51 */
"Hacker",                            /*  52 */
"Hardware",                          /*  53 */
"iNet",                              /*  54 */
"JAVA",                              /*  55 */
"MultiMedia",                        /*  56 */
"NetSoftware",                       /*  57 */
"NetTech",                           /*  58 */
"NT",                                /*  59 */
"OS2",                               /*  60 */
"Programming",                       /*  61 */
"Unix",                              /*  62 */
"Virus",                             /*  63 */
"Visual",                            /*  64 */
"Windows",                           /*  65 */
"Astrology",                         /*  66 */
"Automobile",                        /*  67 */
"Chess",                             /*  68 */
"Connoisseur",                       /*  69 */
"Economy",                           /*  70 */
"Feelings",                          /*  71 */
"Film",                              /*  72 */
"Friend",                            /*  73 */
"Gathering",                         /*  74 */
"IQ_park",                           /*  75 */
"Joke",                              /*  76 */
"Life",                              /*  77 */
"Memory",                            /*  78 */
"Military",                          /*  79 */
"Photography",                       /*  80 */
"Tour",                              /*  81 */
"Digest",                            /*  82 */
"Emprise",                           /*  83 */
"Literature",                        /*  84 */
"Music",                             /*  85 */
"Poetry",                            /*  86 */
"Reading",                           /*  87 */
"Story",                             /*  88 */
"Badminton",                         /*  89 */
"Basketball",                        /*  90 */
"Football",                          /*  91 */
"Health",                            /*  92 */
"Ping-pong",                         /*  93 */
"Sports",                            /*  94 */
"Tennis",                            /*  95 */
"Progwork",                          /*  96 */
"TipWorld",                          /*  97 */
"English",                           /*  98 */
"Mathematics",                       /*  99 */
"Phylosophy",                        /* 100 */
"Physics",                           /* 101 */
"Advice",                            /* 102 */
"Help",                              /* 103 */
"sysop",                             /* 104 */
"Test"                               /* 105 */
};
/* 下面的字符串就是你自己上bbs站时的按键序列,需要修改以符合自己的情况 */
/* 左边的一列是server传过来的,右边的一列是需要自己从键盘输入的     */
char command1[ N ][80]={
                     "login:",         "bbs\r\n",      /* 以bbs登录
*/
                     "):",             "yourID\r\n",    /* 自己的bbs ID
 */
                     ":",              "passWord\r\n",  /* 密码
 */
                     "<ENTER>",        "\r\n",         /* server要你按回车键
*/
                     " ..",            "\r\n",         /*按任何键继续..
*/
                     " ..",            "\r\n",         /*按任何键继续..
*/
                     " ..",            "\r\n",         /*按任何键继续..
*/
                     "G)oodBye",       "e\r\n",        /*主菜单下按e键
*/
                     "E)xit",          "b\r\n",        /*分类讨论区菜单下按b
*/
                     "[h]",            ",",            /* 版名
*/
                     "[h]",            "^P",           /* 按^P发文章
*/
                     "]",              "   ",          /* 文章题目
*/
                     "T",              "\r\n"          /*确定
*/
                    };
/* 下面的字符是文章输入完之后的情况                            */
/* 左边的一列是需要自己从键盘输入的,右边的一列是server传过来的 */
char command2[ M ][20]={
                    "^W",              "]:",        /*文章输完后按Ctrl-W存盘
*/
                    "s\r\n",           "[h]",       /*按s转信
*/
                    "!\r\n"                         /*旋风离站
*/
                 };
int                     sockfd=-1;                 /*管套描述符            *
/
void                    waitString(char *string);      /*等待一个特定字符串
   *
unsigned char  receiveChar(void)       //从socket读取server发来的一个字节
{ char tmp;
  if(read(sockfd,& tmp,1)<=0 ) { printf("read socket error.\n"); exit(-1);}
  return tmp;
}
void sendChar(char ch)           //从socket向server发送一个字节
{
  if( write(sockfd,& ch,1)<0 ) { printf("write socket error.\n"); exit(-1);
}
}
void sendString(char p[])       //从socket向server发送一个字符串
{
if(write(sockfd,p,strlen(p))<0) { printf("write socket error.\n"); exit(-1);
 };
}
void killHandle(void)        //信号处理函数
{
   close(sockfd);
   exit(0);
}
/*==========================================================================
=*/
main(int argc,char **argv)
{
        struct sockaddr_in      host;
        struct hostent          *hp;
        int                     commandCounter;
        int                     status;
        int                     f,k;
        char                    fileBuf[SIZE];
        if( argc<4) { printf("Usage: %s  fileName  boardName title\n",argv[0
]);
                       exit(0);
                    }
        f=open(argv[1],O_RDONLY);                       /*打开本地磁盘文件
 */
        if( f< 0) { printf("open file error\n"); exit(-1); }
        for(k=0; k< NUM_OF_BOARD; k++)
        {
          if( strcmp(argv[2],boardName[k])==0)
          { sprintf(& (command1[BOARD][0]),"%d\r\n\r\n",k+1);
            break;
          }
        }
        if(k>=NUM_OF_BOARD) { printf("Bad boardName: %s\n",argv[2]);
                              exit(0);
                            }
        strcpy(& (command1[TITLE][0]),argv[3]);
        strcat(& (command1[TITLE][0]),"\r\n");
        signal(SIGTERM,killHandle);                     /* 设回调函数
 */
        signal(SIGINT,killHandle);
        hp = gethostbyname("bbs.gznet.edu.cn");           /* bbs服务器的名字
 */
        if(hp==NULL) { printf("Unkonwn host\n"); exit(-1); }
        bzero((char *)& host,sizeof(host));
        bcopy(hp->h_addr,(char *)& host.sin_addr,hp->h_length);
        host.sin_family=AF_INET;
        host.sin_port=htons(23);                         /*telnet标准端口  *
/
        if ( (sockfd=socket(AF_INET,SOCK_STREAM,0))<0 )  /* 阻塞式socket */
        { printf(" Error open socket\n");
          exit(-1);
        }
        status=connect(sockfd,(struct sockaddr *)& host,sizeof(host));/*连接
*/
        if(status<0) { printf("Connect error\n"); exit(-1); }
        for(commandCounter=0; commandCounter< N;  )     /*登录进bbs站  */
        {  waitString( command1[commandCounter ++] );
           sendString( command1[commandCounter ++] );
        }
        while( (status=read(f,fileBuf,SIZE) )>0 )      /*把文件内容发往bbs *
/
        {  for(k=0; k< status; k++)
           { write(sockfd,&(fileBuf[k]),1);
             if( fileBuf[k]==0x0A ) write(sockfd,"\0x0D",1);
           }
        }
        sleep(1);
        close(f);
        for(commandCounter=0; commandCounter< M -1; ) /* 存盘离站        */
        {  sendString( command2[ commandCounter ++] );
           waitString( command2[ commandCounter ++ ]);
        }
        sendString(command2[M-1] );
        sleep(1);
        close(sockfd);
        printf("\npost ok.\n");
}
/*==========================================================================
=*/
void waitString( char *string) /*从server发来的字节流中匹配特定串,找到就返回
  */
{
    int                     m,n;
    int                     len;
    char                    equal;
    char                    term[]="dumb";     /* 终端类型: 哑终端   */
    int                     status;
    struct timeval          timeout;
    struct fd_set           mask;
    unsigned char           c,cmd,opt;
    len=strlen(string);                    /* 欲匹配的串的长度       */
    m=0;                                   /* 串中的当前匹配位置     */
    equal=FALSE;                           /* 布尔变量               */
    for(;;)
    {      n=read(sockfd,& c,1);           /* 读取一个字节           */
           if( n<=0 ) { printf("socket read error.\n"); exit(-1); }
           if (c == 255)                  // IAC字符,后跟telnet命令和协商选项

           {
                cmd = receiveChar();         //读入命令
                opt = receiveChar();         //读入选项
                switch(opt) {
                        case 1:          // echo协商选项,本程序未处理
                        break;
                        case 3:          // supress go-ahead(抑制向前选项)
                        break;
                        case 24:        // terminal type(终端类型选项)
                        if (cmd == 253) {
                                 // IAC WILL terminal-type 将告诉server终端类

                                sendChar((char)255);
                                sendChar((char)251);
                                sendChar((char)24);
                                 // IAC SB terminal-type IS <term> IAC SE
                                sendChar((char)255); //传送终端类型字符串
                                sendChar((char)250);
                                sendChar((char)24);
                                sendChar((char)0);
                                sendString(term);
                                sendChar((char)255);
                                sendChar((char)240);
                                }
                        else if (cmd == 250) {          //SB和SE要配对出现
                                while(receiveChar() != 240)
                                        ;
                                }
                        break;
                        default:        // some other command1
                        if (cmd == 253) {
                                // IAC DONT whatever
                                sendChar((char)255); //其它的协商选项均不同意

                                sendChar((char)252);
                                sendChar((char)opt);
                                }
                 }
            }
            else                                     //处理字符数据
            { putchar(c);
              if( *(string+m)==c ) { m++; equal=TRUE; } //相等则匹配下一字符

              else                 { m=0; equal=FALSE; }//不等则从头再来
              if(equal==TRUE  && m>=len)  return;      //找到期待的字符串就返

            }
     }
}
--
※ 来源:.华南网木棉站 bbs.gznet.edu.cn.[FROM: 202.38.198.197]
--
--
※ 转寄:·UNIX编程 apue.dhs.org·[FROM: 210.39.3.50]
--
※ 转载:·荔园晨风BBS站 bbs.szu.edu.cn·[FROM: 192.168.0.146]


[回到开始] [上一篇][下一篇]

荔园在线首页 友情链接:深圳大学 深大招生 荔园晨风BBS S-Term软件 网络书店