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

📄 ftp.c

📁 linux下的网络下载工具prozilla的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
	    strcpy(dir, szBuffer);	    *r = ' ';	}    }    /*     * all ok      */    return FTPOK;}/* * connects to the ftp server  */uerr_t ftp_connect_to_server(int *sock, char *name, int port){    char szBuffer[FTP_BUFFER_SIZE];    uerr_t err;    err = connect_to_server(sock, name, port, rt.timeout);    if (err != NOCONERROR)    {	return err;    }    debug_prz("Entering ftp_get_reply\n");    err = ftp_get_reply(*sock, szBuffer);    if (err != FTPOK)    {	return err;    }    debug_prz("Exiting ftp_get_reply\n");    if (*szBuffer != '2')    {	return FTPCONREFUSED;    }    return FTPOK;}/* * this function will call bind to return a bound socket then the  ftp server  * will be connected with a port request and asked to connect  */uerr_t ftp_get_listen_socket(int control_sock, int *listen_sock){    /*     * get a fixed value      */    char command[MAX_MSG_SIZE];    int sockfd;    socklen_t len;    struct sockaddr_in TempAddr;    char *port, *ipaddr;    struct sockaddr_in serv_addr;    uerr_t err;    /*     * call bind to bind the sock      */    if (bind_socket(&sockfd) != BINDOK)    {	return LISTENERR;    }    len = sizeof(serv_addr);    if (getsockname(sockfd, (struct sockaddr *) &serv_addr, &len) < 0)    {	perror("getsockname");	close(sockfd);	return CONPORTERR;    }    /*     * now get hosts info      */    len = sizeof(TempAddr);    if (getsockname(control_sock, (struct sockaddr *) &TempAddr, &len) < 0)    {	perror("getsockname");	close(sockfd);	return CONPORTERR;    }    ipaddr = (char *) &TempAddr.sin_addr;    /*     * the port we obtained      */    port = (char *) &serv_addr.sin_port;#define  UC(b)  (((int)b)&0xff)    snprintf(command, sizeof(command), "PORT %d,%d,%d,%d,%d,%d\r\n",	     UC(ipaddr[0]), UC(ipaddr[1]), UC(ipaddr[2]), UC(ipaddr[3]),	     UC(port[0]), UC(port[1]));    /*     * handle error      */    err = ftp_port(control_sock, command);    if (err != FTPOK)    {	return err;    }    *listen_sock = sockfd;    return FTPOK;}uerr_t ftp_login(int control_sock, const char *username,		 const char *passwd){    uerr_t err;    char szBuffer[FTP_BUFFER_SIZE];    if (snprintf(szBuffer, sizeof(szBuffer),		 "USER %s\r\n",		 username) >= sizeof(szBuffer))    {        return NOTENOUGHMEM; /* FIXME: Better error */    }    err = ftp_send_msg(control_sock, szBuffer, strlen(szBuffer));    if (err != FTPOK)    {	return err;    }    err = ftp_get_reply(control_sock, szBuffer);    if (err != FTPOK)    {	return err;    }    /*     * An unprobable possibility of logging without a password.      */    if (*szBuffer == '2')    {	return FTPOK;    }    /*     * Else, only response 3 is appropriate.      */    if (*szBuffer != '3')    {	return FTPLOGREFUSED;    }    /*     * send password      */    if (snprintf(szBuffer, sizeof(szBuffer),		 "PASS %s\r\n",		 passwd) >= sizeof(szBuffer))    {        return NOTENOUGHMEM; /* FIXME: Better error */    }    err = ftp_send_msg(control_sock, szBuffer, strlen(szBuffer));    if (err != FTPOK)    {	return err;    }    err = ftp_get_reply(control_sock, szBuffer);    if (err != FTPOK)    {	return err;    }    if (*szBuffer != '2')    {	return FTPLOGREFUSED;    }    /*     * looks like everything is ok      */    return FTPOK;}/* * Gets info about the file from the ftp server */uerr_t ftp_get_file_info(int control_sock, char *fname, ftp_stat_t * fs){    char szBuffer[FTP_BUFFER_SIZE];    char *tmp;    unsigned char pasv_addr[6];	/*				 * for PASV 				 */    int listen_sock;    /*     * this will indicate whether we are using PASV or PORT      */    int passive_mode = FALSE;    int data_sock;    uerr_t err;    /*     * did we get a filename?     */    if (!fname || !(*fname))    {	message("No file specified.\n");	return -1;    }    /*     * Lets see whether it really is a file      */    err = ftp_cwd(control_sock, fname);    if (err == FTPOK)    {	/*	 * So fname  is a directory and not a file	 */	fs->fp.flagtrycwd = 1;	fs->fp.flagtryretr = 0;	return FTPOK;    } else	fs->fp.flagtrycwd = 0;	/*				 * can't be a directory 				 */    /*     * Hmmm.. so fname may be a file or may not exist atl all      */    /*     * It has allways been hard to get the file size in FTP * lets try the     * SIZE command and if the server doesn't support it * we fall back on     * the LIST command.....      */    if (snprintf(szBuffer, sizeof(szBuffer),		 "SIZE %s\r\n",		 fname) >= sizeof(szBuffer))    {        return NOTENOUGHMEM; /* FIXME: Better error */    }    err = ftp_send_msg(control_sock, szBuffer, strlen(szBuffer));    if (err != FTPOK)    {	return err;    }    err = ftp_get_reply(control_sock, szBuffer);    if (err != FTPOK)    {	return err;    }    /*     * Ok lets see what hapenned..     */    if (*szBuffer == '2')	/*				 * everything ok... 				 */    {#if SIZEOF_OFF_T == 4        sscanf(szBuffer + 3, "%ld", &(fs->fp.size));#elif SIZEOF_OFF_T == 8	sscanf(szBuffer + 3, "%Ld", &(fs->fp.size));#else	{	    err = NOTENOUGHMEM;	    return err;	}#endif	fs->fp.flagtryretr = 1;	return FTPOK;    } else if (*szBuffer == '5')  /** A error hapenned */    {	/*	 * is it due to the file being not found....	 */	if (strstr(szBuffer, "o such file")	    || strstr(szBuffer, "o Such File")	    || strstr(szBuffer, "ot found")	    || strstr(szBuffer, "ot Found"))	    return FTPNSFOD;    }    /*     * The server did not support the SIZE command, *  so lets try to get the      * file size through the LIST command      */    /*     * If enabled lets try PASV      */    if (rt.use_pasv == TRUE)    {	err = ftp_pasv(control_sock, pasv_addr);	/*	 * If the error is due to the server not supporting PASV then * set the	 * flag and lets try PORT 	 */	if (err == FTPNOPASV || err == FTPINVPASV)	{	    message("Server doesn't seem to support PASV");	    passive_mode = FALSE;	} else if (err == FTPOK)	/*					 * server supports PASV 					 */	{	    char dhost[256];	    unsigned short dport;	    snprintf(dhost, sizeof(dhost), "%d.%d.%d.%d",		     pasv_addr[0], pasv_addr[1], pasv_addr[2],		     pasv_addr[3]);	    dport = (pasv_addr[4] << 8) + pasv_addr[5];	    err = connect_to_server(&data_sock, dhost, dport, rt.timeout);	    if (err != NOCONERROR)	    {		return err;	    }	    /*	     * Everything seems to be ok 	     */	    passive_mode = TRUE;	} else	{	    return err;	}    } else    {	/*	 * Ok..since PASV is not to be used... 	 */	passive_mode = FALSE;    }    if (passive_mode == FALSE)	/*				 * try to use PORT instead 				 */    {	/*	 * obtain a listen socket	 */	err = ftp_get_listen_socket(control_sock, &listen_sock);	if (err != FTPOK)	{	    return err;	}    }    err = ftp_ascii(control_sock);    if (err != FTPOK)    {	return err;    }    err = ftp_list(control_sock, fname);    if (err != FTPOK)    {	return err;    }    if (passive_mode == FALSE)	/*				 * Then we have to accept the connection 				 */    {	err = accept_connection(listen_sock, &data_sock);	if (err != ACCEPTOK)	{	    return err;	}    }    /*     * Clear the data buffer     */    memset(szBuffer, 0, sizeof(szBuffer));    if (ftp_read_msg(data_sock, szBuffer, FTP_BUFFER_SIZE) == -1)	return FTPERR;    while ((tmp = strrchr(szBuffer, '\n'))	   || (tmp = strrchr(szBuffer, '\r')))    {	*tmp = 0;    };    /*     * close the data_socket       */    close(data_sock);    if (ftpparse(&(fs->fp), szBuffer, strlen(szBuffer)) == 1)	return FTPOK;    else	return FTPNSFOD;}/* connects to the server and checks wether the file exist   * it also checks wether REST is supported  * and if everything is OK it stores the length of the file in *len  */uerr_t ftp_get_info(urlinfo * u, ftp_stat_t * fs){    int control_sock;    uerr_t err;    char *user, *passwd;    netrc_entry *netrc_ent;    memset(fs, 0, sizeof(ftp_stat_t));    err = ftp_connect_to_server(&control_sock, u->host, u->port);    if (err != FTPOK)    {	message("Error connecting to %s", u->host);	return err;    }    message("connect ok");    user = u->user;    passwd = u->passwd;    /*     * Use .netrc if asked to do so.      */    if (rt.use_netrc == TRUE)    {	netrc_ent = search_netrc(rt.netrc_list, u->host);	if (netrc_ent != NULL)	{	    user = netrc_ent->account;	    passwd = netrc_ent->password;	}    }    user = user ? user : DEFAULT_FTP_USER;    passwd = passwd ? passwd : DEFAULT_FTP_PASSWD;    message("Logging in as user %s password %s", user, passwd);    err = ftp_login(control_sock, user, passwd);    if (err != FTPOK)    {	message("login failed");	close(control_sock);	return err;    } else	message("login ok");    err = ftp_binary(control_sock);    if (err != FTPOK)    {	message("binary failed");	close(control_sock);	return err;    } else	message("Type set to binary ok");    /*     * De we need to CWD      */    if (*u->dir)    {	err = ftp_cwd(control_sock, u->dir);	if (err != FTPOK)	{	    message("CWD failed to change to directory '%s'", u->dir);	    close(control_sock);	    return err;	} else	    message("CWD ok");    } else    {	message("CWD not needed");    }    err = ftp_rest(control_sock, 0);    if (err != FTPOK)    {	u->resume_support = FALSE;	message("REST failed");    } else    {	u->resume_support = TRUE;	message("REST ok");    }    err = ftp_get_file_info(control_sock, u->file, fs);    if (err != FTPOK)    {	message("Get file info failed");	close(control_sock);	return err;    }    u->file_size = fs->fp.size;    close(control_sock);    return FTPOK;}

⌨️ 快捷键说明

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