荔园在线

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

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


发信人: yaomaohua.bbs@bbs.qxntc.edu.cn (〆ゞ毛毛), 信区: InstallBBS
标  题: linux下下载文章的程序
发信站: 笔山书院_BBS (Wed Nov  3 21:59:06 2004)
转信站: SZU!news.szu.edu.cn!news.uestc.edu.cn!QXNTC

寄信人: sdymhua.bbs@bbs.uestc.edu.cn
标  题: Linux下下载文章的程序                  activity (转寄)
发信站: 笔山书院 BBS (Wed Nov  3 21:54:11 2004)

发信人: activity (狂魔☆我爱竹林), 信区: BBSDev
标  题: Linux下下载文章的程序
发信站: 一网深情 (Tue Jul 18 17:32:56 2000), 转信

/* Redhat 6.1下通过---仍然不是很完善,可以凑合着用:)
   用法:到要下载的文章标题前按Ctrl+T,写上要存的文件名就OK了
   能下载信件,精华区文章,讨论区文章
   有自动回信功能
  gcc -o bbs bbs.c
  ./bbs <ip or host> [port]
*/
#include <sys/signal.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <netinet/in.h>
#include <netdb.h>
#include <fcntl.h>
#include <string.h>
#include <termios.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdarg.h>
#include <unistd.h>
#include <errno.h>
#define BUFSIZE 2048
extern int errno;
int     servfd;
int     nCanDel;
int     Auto=0;/*自动回信息*/
int     port=23;
struct  termios oldtty,newtty;
int     dowith(char*,short);
void    writeFile(int,char*,size_t);
void    GetFile();
void    PostFile();
void    autoReply();
void    source(char *,int);
int     handleopt();
int     errexit(const char *format,...);
int main(int argc,char **argv)
{
        if((argc!=2)&& (argc!=3))
                errexit("Usage:%s <host> [port]\n",argv[0]);
        if (argc==3) port=atoi(argv[2]);
        tcgetattr(0,&oldtty);
        signal(SIGINT,SIG_IGN);
        signal(SIGQUIT,SIG_IGN);
        newtty = oldtty;
        newtty.c_cc[VINTR] = _POSIX_VDISABLE;
        newtty.c_cc[VQUIT] = _POSIX_VDISABLE;
        newtty.c_cc[VSUSP] = _POSIX_VDISABLE;
        newtty.c_lflag &= 0;//!(ECHO|ECHOE|ECHOK|ECHONL);
        dowith(argv[1],port);
        tcsetattr(0,TCSANOW,&oldtty);
        return 1;
}
int dowith(char* host,short port)
{
        int i,datalen,nfds,ch,fd=0;
        char buf[4096],key[64];
        fd_set  aset,rset;   /* active file discriptor */
        struct  hostent* phe;
        struct sockaddr_in saddr;
        if((servfd=socket(AF_INET,SOCK_STREAM,0))<0)
                errexit("socket:%s\n",strerror(errno));
        memset(&saddr,0,sizeof(saddr));
        saddr.sin_family = AF_INET;
        if(phe = gethostbyname(host))
                memcpy(&saddr.sin_addr,phe->h_addr,phe->h_length);
        else if(inet_pton(AF_INET,host,&saddr.sin_addr)==0)
                errexit("inet_pton:%s\n",strerror(errno));
        saddr.sin_port = htons(port);
        inet_ntop(AF_INET,&saddr.sin_addr,key,64);
        printf("Connecting to %s(%s)\n",host,key);
        if((i=connect(servfd,(struct sockaddr*)&saddr,sizeof(saddr)))<0)
                errexit("connect:%s\n",strerror(errno));
        FD_ZERO(&aset);
        FD_SET(servfd,&aset);
        FD_SET(fd,&aset);
        nfds=fd>servfd?(fd+1):(servfd+1);
        if(handleopt()==-1) return -1;
        tcsetattr(0,TCSANOW,&newtty);//修改标准输入0的属性
        while(1)
        {
        memcpy(&rset,&aset,sizeof(rset));
        if(select(nfds,&rset,(fd_set *)0,(fd_set *)0,(struct timeval*)
            0)<0)
                if(errno==EINTR)
                        continue;
                else
                        errexit("select: %s\n",strerror(errno));
        if(FD_ISSET(0,&rset))
        {
                ch=read(0,key,64);
                switch(key[0])
                {
                case    '\x14': //自定义的热键Ctrl+T
                                GetFile();break;
                case    '\xf':  //Ctrl+O
                                PostFile();break;
                case    '\x1d': //Ctrl+],quit
                                tcsetattr(0,TCSANOW,&oldtty);
                                close(servfd);
                                exit(0);
                case    2:      /* Ctr+b */
                                source(buf,datalen);
                                break;
                case    3:      /* Ctr+c */
                                Auto = !(Auto);
                                printf("\x1b[s\x1b[25;1H\x1b[1;32m");
                                if(Auto)
                                        printf("自动回信功能开启了");
                                else
                                        printf("自动回信功能关闭了");
                                printf("\x1b[m\x1b[s");
                                fflush(stdout);
                                break;
                default:
                        if(write(servfd,key,ch)==-1)
                                errexit("write:%s\n",strerror(errno));
                }
        }
        if(FD_ISSET(servfd,&rset))
            if((datalen=read(servfd,buf,4095))>=0)
            {
                if(datalen==0)
                        break;
                if(Auto==1&&*buf==7)
                        autoReply();
                else
                {
                        buf[datalen] = NULL;
                        if(write(1,buf,datalen)==-1)
                                errexit("write:%s\n",strerror(errno));
                        fflush(stdout);
                }
            }
        }
        return 0;
}
void    autoReply()
{
        char    buf[100];
        char    *msg="\x1a(ZH自动回信):抱歉,我不在这里!\r\n";
        write(servfd,msg,strlen(msg));
        read(servfd,buf,100);
}
void    source(char *buf,int len)
{
        char *p;
        printf("\x1b[1;1H\x1b[J");
        p = buf;
        while(p-buf<len)
        {
                if(*p==27)
                        printf("^[");
                else
                        printf("%c",*p);
                p++;
        }
        fflush(stdout);
        getchar();
        write(servfd,"\xc",1);
}
void    GetFile()
{
        int nFile,size;
        char    filename[256],*pstr,buf[BUFSIZE],*p;
        printf("\x1b[25;1H\x1b[K\x1b[1;31mSave as:\x1b[m");
        tcsetattr(0,TCSANOW,&oldtty);
        scanf("%s",filename);
        tcsetattr(0,TCSANOW,&newtty);
        if(!strcmp(filename,"cancel"))
        {
                write(servfd,"\xc",1);//Ctrl+L 重绘屏幕
                return;
        }
        if((nFile=open(filename,O_CREAT|O_WRONLY,S_IRUSR|S_IWUSR))<0)
        {
                printf("\x1b[s\x1b[1;32mopen:%s\x1b[m\x1b[u",strerror(errno));
                return;
        }
        write(servfd,"\x1b[C",3);
        nCanDel = 0;
        while(1)
        {
                if((size=read(servfd,buf,BUFSIZE-1))<=0)
                {
                        close(servfd);
                        printf("read error\n");
                        close(nFile);
                        exit(0);
                }
                write(1,buf,size);
                buf[size] = '\0';
                if((pstr=strstr(buf,"\x1b[1;44;32m下面还有喔"))==NULL)
                {
                        if((pstr=strstr(buf,"\x1b[1;44;31m[阅读文章]"))!=NULL)
                        {
                                while(*pstr--!='[');
                                while(*pstr--!='\x1b');//找到文章的结束
                                writeFile(nFile,buf,pstr-buf+1);
                                break;
                        }
                        if((pstr=strstr(buf,"(G)继续?"))!=NULL)
                        {
                                while(*pstr--!='R');
                                pstr--;
                                writeFile(nFile,buf,pstr-buf+1);
                                break;
                        }
                        if((pstr=strstr(buf,"按任何键继续"))!=NULL)
                        {
                                pstr--;
                                writeFile(nFile,buf,pstr-buf+1);
                                break;
                        }
                        pstr = &buf[size-1];
                        writeFile(nFile,buf,pstr-buf+1);
                }else
                {
                        write(servfd,"\x1b[C",3);
                        while(*pstr--!='\x1b');//去掉屏幕最低端的信息
                        if((p=strstr(buf,"\x1b[H\x1b[J")))
                                while(*p++!='\xd');//cut one line
                        else
                                p = buf;
                        writeFile(nFile,p,pstr-p+1);
                }
        }
        close(nFile);
        write(servfd,"\x1b[D",3);
        printf("\x1b[s\x1b[25;1H\x1b[K\x1b[1;31mGetting complete\x1b[m\x1b[u");
}
void    writeFile(int fd,char* buf,size_t size)
{
        char    *pstr,*p,ret=0;
        if((p=strstr(buf,"\x1b[5;1H"))!=NULL||(p=strstr(buf,"\x1b[6;1H"))!=NULL)
        {
                p[0] = 0;
                p[1] = 0;
                p[2] = 0;
                p[3] = 0;
                p[4] = '\n';
                p[5] = '\n';
        }
        p=buf;
        pstr = buf+size-1;
        while(p<=pstr)
        {
                if(*p=='\x1b')
                {//删除所有控制字符串,规则是以ESC开始,以一个字母结束的串
                        while(!((*p>='A'&&*p<='Z')||(*p>='a'&&*p<='z')))
                                *p++='\0';
                        if(*p=='H')
                                *p='\n';
                        if(*p!='J')
                                *p='\0';
                        else if(nCanDel)
                        {
                                while(*p!='\n'&&*p!='\x1b')
                                        *p++='\0';
                                if(*p=='\x1b')
                                        p--;
                        }else
                                *p = '\0';
                }
                if(*p=='\xd')
                        *p = '\0';
                p++;
        }
        p = buf;
        while(p<=pstr)
        {
                if(*p!='\0')
                        if(!(*p=='\n'&&ret==1))/* 删除多余的回车符 */
                                write(fd,p,1);
                if(*p=='\n')
                        ret = 1;
                else
                        ret = 0;
                p++;
        }
        nCanDel = 1;
}
void    PostFile()
{
        int     nFile,size;
        char    name[256],buf[BUFSIZE];
        printf("\x1b[25;1H\x1b[1;31mOpen filename:\x1b[m");
        tcsetattr(0,TCSANOW,&oldtty);
        scanf("%s",name);
        tcsetattr(0,TCSANOW,&newtty);
        if(!strcmp(name,"cancel"))
        {
                write(servfd,"\xc",1);//Ctrl+L 重绘屏幕
                return;
        }
        if((nFile=open(name,O_RDONLY))<0)
        {
                printf("\x1b[s\x1b[25;1HCannot open this file\x1b[u\xc");
                return;
        }
        if((size=read(nFile,&buf,BUFSIZE))<0)
        {
                printf("read:%s\n",strerror(errno));
                close(nFile);
                return;
        }
        write(servfd,buf,size);
        while(size>0)
        {
                if((size=read(nFile,&buf,BUFSIZE))<0)
                {
                        printf("read:%s\n",strerror(errno));
                        close(nFile);
                        return;
                }
                write(servfd,buf,size);
        }
        close(nFile);
        write(servfd,"\xc",1);//Ctrl+L
}
/* errexit - print a error message and exit */
int errexit(const char *format,...)
{
        va_list args;
        if(errno==EINTR)
                return;
        va_start(args,format);
        vfprintf(stderr,format,args);
        va_end(args);
        exit(1);
}
int handleopt()
{
        int n;
        char term[]="linux";//"VT100";"dumb";
        unsigned char c,cmd,opt,ch;
        for(;;)
        {
                n=read(servfd,&c,1);
                if( n<=0 ) {printf("socket read error.\n",n); return -1;exit(-1)
; }
                if (c == 255)
                {
                    read(servfd,&cmd,1);
                    read(servfd,&opt,1);
                    switch(opt)
                    {
                    case 1:
                    case 3:
                           break;
                    case 24:
                           if (cmd == 253)
                           {
                                 write(servfd,"\xff\xfb\x18\xff\xfa\x18\x0",7);
                                 write(servfd,term,strlen(term));
                                 write(servfd,"\xff\xf0",2);
                           }
                           else if (cmd == 250)
                           {
                                        read(servfd,&ch,1);
                                        while(ch!= 240)
                                        read(servfd,&ch,1);
                            }
                            break;
                     default:
                            if (cmd == 253)
                            {
                                write(servfd,"\xff\xfc",2);
                                write(servfd,&opt,1);
                             }
                     }//end switch
                }//end if c==255
                else return 1;
        }//end for
}

--
※ 修改:.activity 于 Aug  7 23:01:09 修改本文.[FROM: 202.115.52.56]
※ 来源:.一网深情 bbs.uestc.edu.cn.[FROM: 202.115.52.56]
--
※ 转寄:·一网深情 bbs.uestc.edu.cn·[FROM: bbs.qxntc.edu.cn]

--
※———————※
 | 〆ゞ毛毛 ^0^ |
 |xztu.3322.org |
※———————※

※ 来源:.笔山书院 BBS bbs.qxntc.edu.cn.[FROM: 219.141.120.*]


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

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