⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ftp.c

📁 简单的linux客户端命令行的
💻 C
📖 第 1 页 / 共 2 页
字号:

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <math.h>
#include <assert.h>
#include <netdb.h>        //gethostbyname
#include <stdlib.h> //malloc
#include <stdarg.h> //va_list


//数据段的结构
struct bindex{
        unsigned long start;
        unsigned long end;
};

pthread_t                 g_tid[10];        //工作线程的tid,最多10个
struct bindex        g_tsk[10];        //工作线程的任务起点和终点

//工作线程传入结构
struct antsdata{
        char* serverip;
        char* user;
        char* pass;
        char* enfile;
        int        port;
        unsigned long *spos;
        unsigned long *epos;
};

//统一的消息输出
void logmsg(char* fmt,...)
{
        va_list args;
        va_start(args,fmt);
        vprintf(fmt, args);
        va_end(args);
}

//ftp://user:pass@111.111.111.111:21/file/files.c
//返回1正确,返回0错误
int islegalurl(char *url)
{
        char h[7];
        memcpy(h,url,6);
        h[6]=0;
        return strcmp("ftp://",h)==0?1:0;
}


//域名解析函数,把例如www.xxx.com翻译成ip地址
//如果输入的是IP地址,返回同样的地址。
//返回1成功,返回0失败
//server 服务器名
//sip 存放ip地址的空间
//buflen sip空间长度
//本函数用到头文件为netdb.h
int getserverip(char *server,char *sip,int buflen)
{

        struct hostent *host; 

        if((host=gethostbyname(server))==NULL) {
                logmsg("==>获取ip地址失败,可能是查询DNS的问题。\n");
                return 0;
        } else {
                if(NULL != inet_ntop(AF_INET,(void*)(host->h_addr),sip,buflen))        {
                        logmsg("==>获取ip地址成功。\n");
                        return 1;
                }else{
                        logmsg("==>获取ip地址失败,可能是地址缓冲不够的问题。\n");
                        return 0;
                }
        }
}

//通过url提取用户名和口令信息
//返回1成功,0失败
int getuserandpassbyurl(char *url,char *user,int ulen,char *pass,int plen)
{
        //寻找@,如果有则服务器从@后开始,到/结束
        //如果没有,则从ftp://开始
        char *p=url;
        while(*p!='@' && *p!=0) p++;

        if(*p=='@'){
                char *e=p-1;
                char *p=e;
                while(*p!='/' && p>url) p--;
                if(p==url) {
                        logmsg("找到@,但没找到前面的/,错误。\n");
                        return 0; //没找到前面的斜杠
                }else {
                        char *s=p+1;
                        assert(e>s);
                        int len=e-s+1;
                        //search ':'
                        while(*p!=':' && p<e) p++;
                        if(p==e) {
                                logmsg("没找到分割用户和密码的冒号,错误。\n");
                                return 0; //无冒号分割
                        }
                        if(ulen < p-s+1) {
                                logmsg("用户名的空间不够,错误。\n");
                                return 0;
                        }
                        memcpy(user,s,p-s);
                        user[p-s]=0;
                        if(plen < e-p+1) {
                                logmsg("口令空间不够,错误。\n");
                                return 0;
                        }

                        memcpy(pass,p+1,e-p);
                        pass[e-p]=0;
                        return 1;
                }
        }else{

                if(ulen < 11 || plen < 8 ) {
                        logmsg("用户名或口令空间不够,错误。\n");
                        return 0;
                }
                strcpy(user,"anonymous");
                strcpy(pass,"miniftp");
                return 1;
        }
}


int getserverandportbyurl(char *url,char *server,int *port,int buflen /*server长度*/)
{
        //寻找@,如果有则服务器从@后开始,到/结束
        //如果没有,则从ftp://开始
        char *p=url;
        while(*p!='@' && *p!=0) p++;

        if(*p=='@')
        {
                char *s=p+1;
                while(*p!='/' && *p!=0) p++;
                if(*p=='/')
                {
                        int len=p-s;        //包含端口在内的长度
                        //检查是否包含了端口在内
                        char *ck=p-1;
                        while(*ck!=':' && ck >s ) ck--;
                        if(ck==s) {//无端口
                                if(buflen < len+1) return 0;
                                memcpy(server,s,len);
                                server[len]=0;
                                *port=21;
                                return 1;        

                        }else {
                                //有端口
                                int slen=ck-s;
                                int plen=len-slen-1;
                                if(buflen < slen) return 0;
                                memcpy(server,s,slen);
                                server[slen]=0;

                                char prt[8];
                                memcpy(prt,ck+1,plen);
                                prt[plen]=0;
                                *port=atoi(prt);
                                return 1;
                        }

                }
                else
                {
                        return 0;
                }
        }
        else //到了结尾没有@
        {
                p=url;
                while(*p!='/' && *p!=0) p++;
                p++;
                while(*p!='/' && *p!=0) p++;
                p++;
                char *s=p;
                while(*p!='/' && *p!=0) p++;
                printf("3\n");
                if(*p=='/') {
                        int len=p-s;        //包含端口在内的长度
                        //检查是否包含了端口在内
                        char *ck=p-1;
                        while(*ck!=':' && ck >s ) ck--;
                        if(ck==s) {//无端口
                                if(buflen < len+1) return 0;
                                memcpy(server,s,len);
                                server[len]=0;
                                *port=21;
                                return 1;        

                        }else {
                                //有端口
                                int slen=ck-s;
                                int plen=len-slen-1;
                                if(buflen < slen) return 0;
                                memcpy(server,s,slen);
                                server[slen]=0;

                                char prt[8];
                                memcpy(prt,ck+1,plen);
                                prt[plen]=0;
                                *port=atoi(prt);
                                return 1;
                        }
                }else{
                        return 0;
                }                
        }        
}

//从url中获得文件段的数据
//不检查是否为目录,也不进行编码
int getfilebyurl(char* url,char *fn,int buflen)
{
        //ftp://dfasdfas.com/dfad/dfs
        //找第三个'/'
        char *p=url;
        while(*p!='/' && *p!=0) p++;
        if(*p==0) {
                logmsg("url格式不对\n");
                return 0;
        }
        p++;
        while(*p!='/' && *p!=0) p++;
        if(*p==0) {
                logmsg("url格式不对\n");
                return 0;
        }
        p++;
        while(*p!='/' && *p!=0) p++;
        if(*p==0) {
                logmsg("url格式不对\n");
                return 0;
        }
        
        if(buflen< strlen(url)-(p-url)) {
                logmsg("文件名空间不够。\n");
                return 0;
        }
        
        memcpy(fn,p,strlen(url)-(p-url));
        fn[strlen(url)-(p-url)]=0;
        return 1;
}

//建立物理连接,成功返回socket,失败<0
int makeconn(char *server,int port)
{
        struct sockaddr_in servaddr;
        int sock=socket(AF_INET,SOCK_STREAM,0);
        if(sock<0) {
                logmsg("建立socket失败\n");
                return -1;
        }

        memset(&servaddr,0,sizeof(struct sockaddr_in));
        servaddr.sin_family=AF_INET;
        servaddr.sin_port=htons(port);

        //inet_aton(server,&servaddr.sin_addr)<=0);
        if(inet_pton(AF_INET,server,&servaddr.sin_addr)<=0)
        {
                logmsg("不正确的ip地址\n");
                return -2;/*Ip Error*/
        }

        if(connect(sock,(struct sockaddr*)&servaddr,sizeof(struct sockaddr_in))<0)
        {
                logmsg("连接失败,可能是网络不可达。\n");
                return -3;/*connect error*/
        }

        return sock; 
}

/*
建立ftp控制连接,成功返回socket,失败<0
*/
int makectrlconn(char *server,int port)
{
        int sock;
        if((sock=makeconn(server,port))<0) {
                return sock;
        }else{
                if(220==getretcode(sock))
                {
                        return sock;        //connect ok
                }
                else
                {
                        logmsg("服务器回应了应用失败\n");
                        close(sock);
                        return -4;        
                }
        }

}

/*
FTP登录
fail if <0
*/
int login(int sock,char *user,char *pass)
{

        int nret;

        char buffer[256];
        sprintf(buffer,"USER %s\r\n",user);
        if(sendout(sock,buffer,strlen(buffer))<0) {
                logmsg("网络发送失败\n");
                return -1; //write data error
        }

        nret=getretcode(sock);
        if(nret>=500)        {
                logmsg("拒绝用户登录\n");
                return -2;
        }

        if(nret==230)         return 0;

        sprintf(buffer,"PASS %s\r\n",pass);
        if(sendout(sock,buffer,strlen(buffer))<0) {
                logmsg("网络发送失败\n");
                return -1; //write data error
        }
        
        nret=getretcode(sock);

        if(nret!=230) {
                logmsg("用户或密码无效,登录失败\n");
                return -3;
        }
        
        return 0;
}

//获得返回的命令码
int getretcode(int sock)
{
        int nret;
        char buffer[1024];
        int movepos=0;                
        while(linefeedpos(buffer,movepos)==-1) //没有结束一行
        {
                if(movepos>1000) return -3; //buffer runs out
                if((nret=read(sock,buffer+movepos,1024-movepos))<=0) {
                        logmsg("网络失败");
                        return -2; //read data error
                }
                movepos+=nret;                
        }

        if(movepos<5) {
                logmsg("服务器返回的数据无效\n");
                return -2;
        }

        //读返回码
        char code[4];
        memcpy(code,buffer,3);
        code[4]=0;
        return atoi(code);
}

//发出数据
int sendout(int sock,char *buf,int len)
{
        int pos=0;
        int nRet=0;
        while(pos<len)
        {

                nRet=write(sock,buf+pos,len-pos);
                
                if(nRet==0)
                {
                        logmsg("对方关闭连接,发送失败。\n");
                        return -2;
                }
                else if(nRet==-1)
                {
                        logmsg("网络故障发送失败\n");
                        return -1;
                }
                else
                {
                        pos+=nRet;
                        if(pos!=len)
                        {
                                continue;
                        }
                        else
                        {
                                return pos;
                        }
                }
        }
}

//if no linefeed return -1
//数据中是否有回车换行?
int linefeedpos(char *buffer,int movepos)
{
        int i;

        for(i=0;i<=movepos-2;i++)
                if(buffer[i]=='\r' && buffer[i+1]=='\n')
                        return i;
        
        return -1;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -