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

📄 htftp.c

📁 www工具包
💻 C
📖 第 1 页 / 共 4 页
字号:
    return (*input->isa->put_block)(input, HTChunk_data(ctrl->cmd), len);}/*	HTFTPParseURL**	-------------**    	Scan URL for uid and passwd, and any data type indication. The**	expected format is [user[:password]@]host[:port].**	If no values are found then use defaults.**	Returns YES if OK, else NO*/PRIVATE BOOL HTFTPParseURL (HTRequest * request,			    char *url, ftp_ctrl *ctrl, ftp_data *data){    char *login = HTParse(url, "", PARSE_HOST);    char *path = HTParse(url, "", PARSE_PATH+PARSE_PUNCTUATION);    char *ptr = strchr(login, '@');    if (ptr) {				      /* Uid and/or passwd specified */	char *passwd;	*ptr = '\0';	if ((passwd = strchr(login, ':'))) {		 /* Passwd specified */	    *passwd++ = '\0';    	    HTUnEscape(passwd);	    StrAllocCopy(ctrl->passwd, passwd);	}	HTUnEscape(login);	StrAllocCopy(ctrl->uid, login);    } else if (g_FTPControlMode & FTP_ALWAYS_ASK_UID_PW) {/* Added by Marek Nagy. */	ctrl->uid=NULL;	ctrl->passwd=NULL;/* End of adding. */    } else {				    /* Use anonymous */	HTUserProfile * up = HTRequest_userProfile(request);        const char * mailaddress = HTUserProfile_email(up);	StrAllocCopy(ctrl->uid, "anonymous");	if (mailaddress)	    StrAllocCopy(ctrl->passwd, mailaddress);	else	    StrAllocCopy(ctrl->passwd, WWW_FTP_CLIENT);    }/* begin _GM_ *//* Note: libwww bug ID: GM6 */    {/*	char tempParams[512];	sprintf(tempParams, "Username='%s', Password='%s'", ctrl->uid, ctrl->passwd);	HTRequest_addError(request, ERR_INFO, NO, HTERR_OK,			   tempParams, strlen(tempParams), "HTFTPParseURL");*/  }/* end _GM_ */    HTTRACE(PROT_TRACE, "FTPParse.... uid `%s\' pw `%s\'\n" _ 		ctrl->uid ? ctrl->uid : "<null>" _ 		ctrl->passwd ? ctrl->passwd : "<null>");	    ptr = strchr(path, ';');    if (ptr) {	*ptr = '\0';	if (strncasecomp(ptr, ";type=", 6))		    /* Look for type */	    data->type = TOUPPER(*(ptr+6));	else if (*(ptr-1) == '/')	    data->type = 'N';    } else if (*(path+strlen(path)-1) == '/') {	*(path+strlen(path)-1) = '\0';	data->type = 'N';    }    HTTRACE(PROT_TRACE, "FTPParse.... Datatype %c\n" _ data->type ? data->type : '?');    StrAllocCopy(data->file, path);    data->offset = data->file;    HT_FREE(login);    HT_FREE(path);    return YES;}/*	Use LIST or NLST**	----------------**	This function sets the type field for what type of list we can use**	Returns YES if OK, else NO*/PRIVATE BOOL FTPListType (ftp_data * data, FTPServerType type){    if (!data) return NO;    switch (type) {      case FTP_GENERIC: 	data->type='N'; break;      case FTP_MACHTEN: 	data->type='L'; break;      case FTP_UNIX:		data->type='L'; break;      case FTP_VMS:		data->type='L'; break;      case FTP_CMS: 		data->type='N'; break;      case FTP_DCTS: 		data->type='N'; break;      case FTP_TCPC: 		data->type='N'; break;      case FTP_PETER_LEWIS:	data->type='L'; break;      case FTP_NCSA:		data->type='N'; break;      case FTP_WINNT:		data->type='L'; break;      default: 			data->type='N'; break;    }    return YES;}/*	Open a Data socket for listening on**	-----------------------------------**	Set up a port to listen for data**	Returns YES if OK, else NO*/PRIVATE BOOL ListenSocket (HTNet *cnet, HTNet *dnet, ftp_data *data){#ifdef FTP_POLL_PORTS    unsigned short old_DataPort = DataPort;    for (DataPort=old_DataPort+1;; DataPort++) {	if (DataPort > LAST_TCP_PORT)	    DataPort = FIRST_TCP_PORT;	if (DataPort == old_DataPort) {	    HTTRACE(PROT_TRACE, "FTP......... No data port found\n");	    return NO;	}	if (HTDoListen(dnet, DataPort, 1) == HT_OK)	    break;#if 0	if (HTNet_socket(dnet) != INVSOC) {	    NETCLOSE(HTNet_socket(dnet));	    HTNet_socket(dnet) = INVSOC;	}#else	HTDoClose(dnet);#endif    }#else    if (HTDoListen(dnet, 0, HTNet_socket(cnet), 1) != HT_OK) return NO;#endif /* FTP_POLL_PORTS */    /* Now we must find out who we are to tell the other guy */    {	SockA local_addr;	int addr_size = sizeof(local_addr);	memset((void *) &local_addr, '\0', sizeof(local_addr));	if (getsockname(HTNet_socket(dnet), (struct sockaddr *) &local_addr,			&addr_size) < 0) {	    HTRequest_addSystemError(HTNet_request(dnet), ERR_FATAL, socerrno,				     NO, "getsockname");	    return NO;	}	HTTRACE(PROT_TRACE, "FTP......... This host is `%s\'\n" _ 				HTInetString(&local_addr));	{	    u_long addr = local_addr.sin_addr.s_addr;	    u_short port = local_addr.sin_port;	    sprintf(data->host, "%d,%d,%d,%d,%d,%d",		    (int)*((unsigned char *)(&addr)+0),		    (int)*((unsigned char *)(&addr)+1),		    (int)*((unsigned char *)(&addr)+2),		    (int)*((unsigned char *)(&addr)+3),		    (int)*((unsigned char *)(&port)+0),		    (int)*((unsigned char *)(&port)+1));	}    }    return YES;}/*	HTFTPLogin**	-----------**    	This function makes a login to a ftp-server. It takes the user name**	and passwd specified in ctrl->user and if that fails or an additional**	account is needed, the user is prompted.**	Returns HT_OK, HT_ERROR, or HT_WOULD_BLOCK*/PRIVATE int HTFTPLogin (HTRequest *request, HTNet *cnet, ftp_ctrl *ctrl){    int status;    typedef enum _state {	SUB_ERROR = -2,	SUB_SUCCESS = -1,	NEED_SELECT = 0,	NEED_GREETING,	NEED_REIN,	NEED_UID,	NEED_PASSWD,	NEED_ACCOUNT,	PROMPT_USER    } state;    /* Jump into a second level state machine */    while (1) {	switch ((state) ctrl->substate) {	case NEED_SELECT:	    {		HTAlertCallback * cbf = HTAlert_find(HT_PROG_LOGIN);		if (cbf) (*cbf)(request, HT_PROG_LOGIN, HT_MSG_NULL, NULL, NULL, NULL);		HTTRACE(PROT_TRACE, "FTP Login.. now in state NEED_SELECT\n");		ctrl->substate = ctrl->reset ? NEED_REIN : NEED_GREETING;	    }	    break;	  case NEED_GREETING:	    HTTRACE(PROT_TRACE, "FTP Login.. now in state NEED_GREETING\n");	    status = HTHost_read(HTNet_host(cnet), cnet);	    if (status == HT_WOULD_BLOCK)		return HT_WOULD_BLOCK;	    else if (status == HT_LOADED) {		if (ctrl->repcode/100 == 2) {		    ctrl->substate = (ctrl->uid && *ctrl->uid) ?			NEED_UID : PROMPT_USER;		} else {		    ctrl->substate = SUB_ERROR;		}	    } else {		ctrl->substate = SUB_ERROR;	    }	    break;	  case NEED_REIN:	    HTTRACE(PROT_TRACE, "FTP Login.. now in state NEED_REIN\n");	    if (!ctrl->sent) {		status = SendCommand(request, ctrl, "REIN", NULL);		if (status == HT_WOULD_BLOCK)		    return HT_WOULD_BLOCK;		else if (status == HT_ERROR)		    ctrl->substate = SUB_ERROR;		ctrl->sent = YES;	    } else {		status = HTHost_read(HTNet_host(cnet), cnet);		if (status == HT_WOULD_BLOCK)		    return HT_WOULD_BLOCK;		else if (status == HT_LOADED) {/* begin _GM_ *//* Note: libwww bug ID: GM8 */		    /* if (ctrl->repcode/100 == 2) { */		    /* If the FTP server doesn't support the REIN command, then		       the return code will be 502 */		    if ((ctrl->repcode/100 == 2) || (ctrl->repcode == 502)) {/* end _GM_ */			ctrl->substate = (ctrl->uid && *ctrl->uid) ?			    NEED_UID : PROMPT_USER;		    } else {			ctrl->substate = SUB_SUCCESS;	    /* hope the best */		    }		} else {		    ctrl->substate = SUB_ERROR;		}		ctrl->sent = NO;	    }	    break;	  case NEED_UID:	    HTTRACE(PROT_TRACE, "FTP Login.. now in state NEED_UID\n");	    if (!ctrl->sent) {		status = SendCommand(request, ctrl, "USER", ctrl->uid);		if (status == HT_WOULD_BLOCK)		    return HT_WOULD_BLOCK;		else if (status == HT_ERROR)		    ctrl->substate = SUB_ERROR;		ctrl->sent = YES;	    } else {		status = HTHost_read(HTNet_host(cnet), cnet);		if (status == HT_WOULD_BLOCK)		    return HT_WOULD_BLOCK;		else if (status == HT_LOADED) {		    int code = ctrl->repcode/100;		    if (code == 2) 		    /* Logged in w/o passwd! */			ctrl->substate = SUB_SUCCESS;		    else if (code == 3) {	 	/* Password demanded */			ctrl->substate = (ctrl->passwd && *ctrl->passwd) ?			    NEED_PASSWD : PROMPT_USER;/* begin _GM_ *//* Note: libwww bug ID: GM3 */		    /* } else if (ctrl->repcode == 530) */			/* ctrl->substate = PROMPT_USER;*/        /* User unknown */		    } else if (ctrl->repcode == 530) {			if (ctrl->alreadyLoggedIn == YES) {			    ctrl->substate = SUB_SUCCESS;			    HTTRACE(PROT_TRACE, "FTP Login.. Already logged in\n");			} else {			    ctrl->substate = PROMPT_USER;			    HTTRACE(PROT_TRACE, "FTP Login.. User Unknown\n");			}		    }/* end _GM_ */		    else			ctrl->substate = SUB_ERROR;		} else		    ctrl->substate = SUB_ERROR;		ctrl->sent = NO;	    }	    break;	  case NEED_PASSWD:	    HTTRACE(PROT_TRACE, "FTP Login.. now in state NEED_PASSWD\n");	    if (!ctrl->sent) {		status = SendCommand(request, ctrl, "PASS", ctrl->passwd);		if (status == HT_WOULD_BLOCK)		    return HT_WOULD_BLOCK;		else if (status == HT_ERROR)		    ctrl->substate = SUB_ERROR;		ctrl->sent = YES;	    } else {		status = HTHost_read(HTNet_host(cnet), cnet);		if (status == HT_WOULD_BLOCK)		    return HT_WOULD_BLOCK;		else if (status == HT_LOADED) {		    int code = ctrl->repcode/100;		    if (code == 2)		    /* Logged in with passwd */			ctrl->substate = SUB_SUCCESS;		    else if (code == 3) {      		 /* Account required */			HTAlertCallback *cbf = HTAlert_find(HT_A_PROMPT);			HTAlertPar * reply = HTAlert_newReply();			if (cbf && (*cbf)(request, HT_A_PROMPT,					  HT_MSG_ACCOUNT, NULL, NULL, reply)) {			    ctrl->account = HTAlert_replyMessage(reply);			    ctrl->substate = NEED_ACCOUNT;			} else			    ctrl->substate = SUB_ERROR;			HTAlert_deleteReply(reply);		    } else if (ctrl->repcode == 530)			ctrl->substate = PROMPT_USER;		    else			ctrl->substate = SUB_ERROR;		} else		    ctrl->substate = SUB_ERROR;		ctrl->sent = NO;	    }	    break;	  case NEED_ACCOUNT:	    HTTRACE(PROT_TRACE, "FTP Login.. now in state NEED_ACCOUNT\n");	    if (!ctrl->sent) {		status = SendCommand(request, ctrl, "ACCT", ctrl->account);		if (status == HT_WOULD_BLOCK)		    return HT_WOULD_BLOCK;		else if (status == HT_ERROR)		    ctrl->substate = SUB_ERROR;		ctrl->sent = YES;	    } else {		status = HTHost_read(HTNet_host(cnet), cnet);		if (status == HT_WOULD_BLOCK)		    return HT_WOULD_BLOCK;		else if (status == HT_LOADED) {		    int code = ctrl->repcode/100;		    if (code == 2)		   /* Logged in with account */			ctrl->substate = SUB_SUCCESS;		    else			ctrl->substate = SUB_ERROR;		 /* hopeless */		} else		    ctrl->substate = SUB_ERROR;		ctrl->sent = NO;	    }	    break;	  case PROMPT_USER:	    HTTRACE(PROT_TRACE, "FTP Login.. now in state PROMPT_USER\n");	    {		HTAlertCallback *cbf = HTAlert_find(HT_A_USER_PW);		HTAlertPar * reply = HTAlert_newReply();		HT_FREE(ctrl->uid);		HT_FREE(ctrl->passwd);		if (cbf && (*cbf)(request, HT_A_USER_PW, HT_MSG_FTP_UID,				  NULL, NULL, reply)){		    ctrl->uid = HTAlert_replyMessage(reply);		    ctrl->passwd = HTAlert_replySecret(reply);		}		HTAlert_deleteReply(reply);		if (ctrl->uid && *ctrl->uid && ctrl->passwd && *ctrl->passwd)		    ctrl->substate = NEED_UID;		else		    ctrl->substate = SUB_ERROR;	    }	    break;	  case SUB_ERROR:	    HTTRACE(PROT_TRACE, "FTP Login.. now in state SUB_ERROR\n");	    HTRequest_addError(request, ERR_FATAL, NO,			       HTERR_FTP_LOGIN_FAILURE, NULL, 0, "HTFTPLogin");	    HTTRACE(PROT_TRACE, "FTP......... Login failed\n");	    ctrl->substate = 0;	    return HT_ERROR;	    break;	  case SUB_SUCCESS:	    HTTRACE(PROT_TRACE, "FTP Login.. now in state SUB_SUCCESS\n");	    HTTRACE(PROT_TRACE, "FTP......... Logged in as `%s\'\n" _ ctrl->uid);	    ctrl->substate = 0;	    return HT_OK;	    break;	}    }}/*	HTFTPDataConnection**	-------------------**    	Prepares a data connection to the server and initializes the**	transfer mode.**	Returns HT_OK, HT_ERROR, or HT_WOULD_BLOCK*/PRIVATE int HTFTPDataConnection (HTRequest * request, HTNet *cnet,				 ftp_ctrl *ctrl, ftp_data *data){    int status;    HTNet *dnet = ctrl->dnet;    typedef enum _state {	SUB_ERROR = -2,	SUB_SUCCESS = -1,	NEED_TYPE = 0,	NEED_SELECT,	NEED_PASV,	NEED_PORT    } state;        /* Jump into a second level state machine */    while (1) {

⌨️ 快捷键说明

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