荔园在线

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

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


发信人: Rog (我要开始努力学习), 信区: InstallBBS
标  题: [转载] [转寄] 自动发文章程序                         STW
发信站: BBS 荔园晨风站 (Fri Dec 18 23:52:54 1998), 站内信件

【 以下文字转载自 Linux 讨论区 】
【 原文由 Lg 所发表 】
【 以下文字转载自 Lg 的信箱 】
发信人: STW (蓝快), 信区: BBSbuild
标  题: 自动发文章程序
发信站: 广州蓝天站 (Mon Feb  9 20:52:10 1998), 转信
[转载]

/* 这是一个向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 M     26
#define N     5
#define SIZE  4096
#define TRUE  -1
#define FALSE 0

/* 下面的字符串就是你自己上bbs站时的按键序列,需要修改以符合自己的情况 */
/* 左边的一列是server传过来的,右边的一列是需要自己从键盘输入的     */
char *command1[ M ]={
                     "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",          "9\r\n",        /*分类讨论区菜单下按9*/
                     "Test",           "k\r\n",        /*按k键选下一个讨论区*/
                     "[Test]",         "^P",           /*在Test版按^P发文章 */
                     "]",              "test\r\n",     /*文章题目           */
                     "T",              "\r\n"          /*确定               */
                    };
/* 下面的字符是文章输入完之后的情况                            */
/* 左边的一列是需要自己从键盘输入的,右边的一列是server传过来的 */
char *command2[ N ]={
                    "^W",              "]:",        /*文章输完后按Ctrl-W存盘*/
                    "s\r\n",           "[h]",       /*按s转信               */
                    "!\r\n"                         /*旋风离站              */
                 };
int                     sockfd=-1;                 /*管套描述符            */
void                    expect(char *string);      /*等待一个特定字符串    */

unsigned char  readChar(void)       //从socket读取server发来的一个字节
{ char tmp;
  if(read(sockfd,& tmp,1)<=0 ) { printf("read socket error.\n"); exit(-1);}
  return tmp;
}

void writeChar(char ch)           //从socket向server发送一个字节
{
  if( write(sockfd,& ch,1)<0 ) { printf("write socket error.\n"); exit(-1); }
}

void writeString(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<2 ) { printf("Usage: %s  fileName\n",argv[0]); exit(0); }

        f=open(argv[1],O_RDONLY);                       /*打开本地磁盘文件   */
        if( f< 0) { printf("open file error\n"); exit(-1); }

        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< M;  )     /*登录进bbs站  */
        {  expect( command1[commandCounter ++] );
           writeString( 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< N -1; ) /* 存盘离站        */
        {  writeString( command2[ commandCounter ++] );
           expect( command2[ commandCounter ++ ]);
        }
        writeString(command2[N-1] );
        sleep(1);
        close(sockfd);
        printf("\npost ok.\n");
}

void expect( 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 = readChar();         //读入命令
                opt = readChar();         //读入选项

                switch(opt) {
                        case 1:          // echo协商选项,本程序未处理
                        break;

                        case 3:          // supress go-ahead(抑制向前选项)
                        break;

                        case 24:        // terminal type(终端类型选项)
                        if (cmd == 253) {
                                 // IAC WILL terminal-type 将告诉server终端类型
                                writeChar((char)255);
                                writeChar((char)251);
                                writeChar((char)24);
                                 // IAC SB terminal-type IS <term> IAC SE
                                writeChar((char)255); //传送终端类型字符串
                                writeChar((char)250);
                                writeChar((char)24);
                                writeChar((char)0);
                                writeString(term);
                                writeChar((char)255);
                                writeChar((char)240);
                                }
                        else if (cmd == 250) {          //SB和SE要配对出现
                                while(readChar() != 240)
                                        ;
                                }
                        break;

                        default:        // some other command1
                        if (cmd == 253) {
                                // IAC DONT whatever
                                writeChar((char)255); //其它的协商选项均不同意
                                writeChar((char)252);
                                writeChar((char)opt);
                                }
                 }
            }
            else                                     //处理字符数据
            { putchar(c);
              if( *(string+m)==c ) { m++; equal=TRUE; } //相等则匹配下一字符
              else                 { m=0; equal=FALSE; }//不等则从头再来
              if(equal==TRUE  && m>=len)  return;      //找到期待的字符串就返回
            }
     }
}

--
※ 修改:.STW 于 Feb  9 20:52:38 修改本文.[FROM: 172.21.81.5]
※ 转载:.广州蓝天站 bbs.[FROM: 172.21.81.5]
--
※ 转寄:.广州蓝天站 bbs.gznet.com.[FROM: 172.21.24.100]
--
※ 转载:.BBS 荔园晨风站 bbs.szu.edu.cn.[FROM: 192.168.0.1]
--
※ 转载:.BBS 荔园晨风站 bbs.szu.edu.cn.[FROM: 192.168.0.141]
※ 修改:·jjk 於 Dec  3 15:21:42 修改本文·[FROM: 192.168.0.146]


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

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