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

📄 htftp.c

📁 www工具包
💻 C
📖 第 1 页 / 共 4 页
字号:
	    HTTRACE(PROT_TRACE, "FTP Get Data now in state NEED_SEGMENT\n");	    {		char *ptr;		if (data->offset == data->file) {		    if (ctrl->server == FTP_VMS) {	   /* Change to root */			if ((segment = (char  *) HT_MALLOC(strlen(ctrl->uid)+3)) == NULL)			    HT_OUTOFMEM("segment ");			sprintf(segment, "[%s]", ctrl->uid);		    } else			StrAllocCopy(segment, "/");		    data->offset++;		    ctrl->substate = NEED_CWD;		} else {		    if ((ptr = strchr(data->offset, '/'))) {			*ptr='\0';			StrAllocCopy(segment, data->offset);			*ptr='/';			data->offset = ++ptr;			HTUnEscape(segment);			HTCleanTelnetString(segment);			ctrl->substate = NEED_CWD;		    } else			ctrl->substate = NEED_ACTION;		}	    }	    break;	  case NEED_CWD:	    HTTRACE(PROT_TRACE, "FTP Get Data now in state NEED_CWD\n");	    if (!ctrl->sent) {		status = SendCommand(request, ctrl, "CWD", segment);		HT_FREE(segment);		if (status == HT_WOULD_BLOCK)		    return HT_WOULD_BLOCK;		else if (status == HT_ERROR)		    ctrl->substate = SUB_ERROR;		ctrl->cwd = YES;		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) {		    if (ctrl->repcode/100 == 2)			ctrl->substate = NEED_SEGMENT;		    else			ctrl->substate = SUB_ERROR;		} else		    ctrl->substate = SUB_ERROR;		ctrl->sent = NO;	    }	    break;	case NEED_STREAM:	    HTTRACE(PROT_TRACE, "FTP Get Data now in state NEED_STREAM\n");	    /* 	    ** Create the stream pipe FROM the channel to the application.	    ** The target for the input stream pipe is set up using the	    ** stream stack.	    */	    {		HTStream * target = FTP_DIR(data) ?		    HTFTPDir_new(request, ctrl->server, data->type) :		    HTStreamStack(HTAnchor_format(HTRequest_anchor(request)),				  HTRequest_outputFormat(request),				  HTRequest_outputStream(request),				  request, YES);		HTNet_setReadStream(dnet, target);	    }	    HTRequest_setOutputConnected(request, YES);	    data_is_active = YES;	    ctrl->substate = NEED_BODY;	    break;	  case NEED_BODY:	      HTTRACE(PROT_TRACE, "FTP Get Data now in state NEED_BODY\n");	      if (data_is_active) {		  status = HTHost_read(HTNet_host(dnet), dnet);		  if (status == HT_WOULD_BLOCK)		      return HT_WOULD_BLOCK;		  else if (status == HT_LOADED || status == HT_CLOSED) {		      data->complete |= 1; 		      if (data->complete >= 3)			  ctrl->substate = SUB_SUCCESS;		      else			  data_is_active = NO;		  } else {		      ctrl->substate = SUB_ERROR;		      data->stream_error = YES;		  }	      } else {		  status = HTHost_read(HTNet_host(cnet), cnet);		  if (status == HT_WOULD_BLOCK)		      return HT_WOULD_BLOCK;		  else if (status == HT_LOADED || status == HT_CLOSED) {		      if (ctrl->repcode/100 == 2) {			  data->complete |= 2;			  if (data->complete >= 3)			      ctrl->substate = SUB_SUCCESS;			  else			      data_is_active = YES;		      } else			  ctrl->substate = SUB_ERROR;		  } else		      ctrl->substate = SUB_ERROR;	      }	      break;	  case SUB_ERROR:	    HTTRACE(PROT_TRACE, "FTP Get Data now in state SUB_ERROR\n");	    HTRequest_addError(request, ERR_FATAL, NO, HTERR_NOT_FOUND,			       NULL, 0, "HTFTPGetData");	    ctrl->substate = 0;	    HT_FREE(segment);	    return HT_ERROR;	    break;	  case SUB_SUCCESS:	    HTTRACE(PROT_TRACE, "FTP Get Data now in state SUB_SUCCESS\n");	    ctrl->substate = 0;	    HT_FREE(segment);	    return HT_LOADED;	    break;	}    }}/* ------------------------------------------------------------------------- *//*	Retrieve File from Server as an atomic action. **	-----------------------------------------------**	Given a hypertext address, this routine loads a document.**** On entry,**      request		This is the request structure**	returns		HT_ERROR	Error has occured in call back**			HT_OK		Call back was OK*/PRIVATE int FTPEvent (SOCKET soc, void * pVoid, HTEventType type);PUBLIC int HTLoadFTP (SOCKET soc, HTRequest * request){    HTNet * cnet = HTRequest_net(request);    ftp_ctrl * ctrl = NULL;    ftp_data * data = NULL;    HTParentAnchor * anchor = HTRequest_anchor(request);    char * url = HTAnchor_physical(anchor);    /*    ** Initiate a new FTP ctrl and data structure and bind to request structure    ** This is actually state FTP_BEGIN, but it can't be in the state    ** machine as we need the structure first.    */    HTTRACE(PROT_TRACE, "FTP......... Looking for `%s\'\n" _ url);    if ((ctrl = (ftp_ctrl *) HT_CALLOC(1, sizeof(ftp_ctrl))) == NULL ||	(data = (ftp_data *) HT_CALLOC(1, sizeof(ftp_data))) == NULL)	HT_OUTOFMEM("HTLoadFTP");    ctrl->cmd = HTChunk_new(128);    ctrl->state = FTP_BEGIN;    ctrl->server = FTP_UNSURE;    ctrl->dnet = HTNet_dup(cnet);    ctrl->cnet = cnet;    HTNet_setContext(cnet, ctrl);    HTNet_setEventCallback(cnet, FTPEvent);    HTNet_setEventParam(cnet, ctrl);    HTNet_setRawBytesCount(ctrl->dnet, YES);    /* for now, the dnet comes back to the same place    ** - vestigial from when the callback was from the request object    */    HTNet_setContext(ctrl->dnet, data);    HTNet_setEventCallback(ctrl->dnet, FTPEvent);    HTNet_setEventParam(ctrl->dnet, ctrl);    return FTPEvent(soc, ctrl, HTEvent_BEGIN);}PRIVATE int FTPEvent (SOCKET soc, void * pVoid, HTEventType type){    ftp_ctrl * ctrl = (ftp_ctrl *) pVoid;    ftp_data * data = (ftp_data *) HTNet_context(ctrl->dnet);    int status = HT_ERROR;    HTNet * cnet = ctrl->cnet;    HTRequest * request = HTNet_request(cnet);    HTParentAnchor * anchor = HTRequest_anchor(request);    char * url = HTAnchor_physical(anchor);    HTHost *host = HTNet_host(cnet);    if (type == HTEvent_CLOSE) {			      /* Interrupted */        if (soc == HTNet_socket(cnet))	    FTPCleanup(request, HT_INTERRUPTED);	else	    FTPCleanup(request, HT_LOADED);	return HT_OK;    } else if (type == HTEvent_TIMEOUT) {	HTRequest_addError(request, ERR_FATAL, NO, HTERR_TIME_OUT,			   NULL, 0, "HTLoadHTTP");	FTPCleanup(request, HT_TIMEOUT);	return HT_OK;    } else {	ctrl = (ftp_ctrl *) HTNet_context(cnet);	/* Get existing copy */	data = (ftp_data *) HTNet_context(ctrl->dnet);    }    /* Now jump into the machine. We know the state from the previous run */    while (1) {	switch (ctrl->state) {	  case FTP_BEGIN:	      HTTRACE(PROT_TRACE, "FTP Event... now in state FTP_BEGIN\n");	      /* Only handle GET requests for now */	      if (HTRequest_method(request) != METHOD_GET) {		  HTTRACE(PROT_TRACE, "FTP Event... This module only supports the GET method\n");		  ctrl->state = FTP_ERROR;		  break;	      }	      HTFTPParseURL(request, url, ctrl, data);	      /* The following is added by Neil Griffin, GAIN Software */	      /*	      ** If the user hasn't specified a permanent transfer type, then	      ** use the transfer type specified at the end of the URL.	      */	      if (g_FTPTransferMode == FTP_DEFAULT_TRANSFER_MODE) {		  switch (data->type) {		  case 'a' : data->type = 'A'; break;		  case 'A' : data->type = 'A'; break;		  case 'i' : data->type = 'I'; break;		  case 'I' : data->type = 'I'; break;		  case 'd' : FTPListType(data, ctrl->server); break;		  case 'D' : FTPListType(data, ctrl->server); break;		  default  : data->type = 'I'; break;		  }		  /* Otherwise, use the permanent transfer type specified by the user. */	      } else {		  switch (g_FTPTransferMode) {		  case FTP_ASCII_TRANSFER_MODE  : data->type = 'A'; break;		  case FTP_BINARY_TRANSFER_MODE : data->type = 'I'; break;		  case FTP_DIR_TRANSFER_MODE    : FTPListType(data, ctrl->server); break;		  default                       : data->type = 'I'; break;		  }	      }	      HTTRACE(PROT_TRACE, "FTP Event... Transfer mode set to '%c'\n" _ data->type);	      /*	      **  See if we can get any hints to what we might expect content wise.	      */	      if (!FTP_DIR(data)) HTBind_getAnchorBindings(anchor);              /* Ready for next state */              ctrl->state = FTP_NEED_CCON;              break;	case FTP_NEED_CCON:	    HTTRACE(PROT_TRACE, "FTP Event... now in state FTP_NEED_CONN\n");	    status = HTHost_connect(host, cnet, url, FTP_PORT);	    host = HTNet_host(cnet);	    if (status == HT_OK) {		/*		** Check the protocol class to see if we have connected to a		** the right class of server, in this case HTTP.		*/		{		    char * s_class = HTHost_class(host);		    if (s_class && strcasecomp(s_class, "ftp")) {			HTRequest_addError(request, ERR_FATAL, NO, HTERR_CLASS,					   NULL, 0, "HTLoadNews");			ctrl->state = FTP_ERROR;			break;		    }		    HTHost_setClass(host, "ftp");		}		/* Check persistent connection */		if (HTNet_persistent(cnet)) {		    ctrl->server = HTHost_version(host);		    HTTRACE(PROT_TRACE, "FTP Server.. Cache says type %d server\n" _ 				ctrl->server);		    ctrl->reset = 1;		} else		    HTNet_setPersistent(cnet, YES, HT_TP_SINGLE);		/* 		** Create the stream pipe FROM the channel to the application.		** The target for the input stream pipe is set up using the		** stream stack.		*/		{		    HTStream * readstream = FTPStatus_new(request, ctrl, host);		    HTNet_setReadStream(cnet, readstream);		}		/*		** Create the stream pipe TO the channel from the application		** and hook it up to the request object		*/		{		    HTOutputStream * output = HTNet_getOutput(cnet, NULL, 0);		    HTRequest_setInputStream(request, (HTStream *) output);		}		/*		** Set up concurrent read/write if this request isn't the		** source for a PUT or POST. As source we don't start reading		** before all destinations are ready. If destination then		** register the input stream and get ready for read		*/		if (HTRequest_isPostWeb(request)) {		    HTEvent * event = HTNet_event(cnet);		    HTEvent_register(HTNet_socket(cnet), HTEvent_READ, event);		    HTRequest_linkDestination(request);		}		ctrl->state = FTP_NEED_LOGIN;	    } else if (status == HT_WOULD_BLOCK || status == HT_PENDING)		return HT_OK;	    else		ctrl->state = FTP_ERROR;	       /* Error or interrupt */	    break;	  case FTP_NEED_LOGIN:	    HTTRACE(PROT_TRACE, "FTP Event... now in state FTP_NEED_LOGIN\n");	    status = HTFTPLogin(request, cnet, ctrl); 	    if (status == HT_WOULD_BLOCK) return HT_OK;	    ctrl->state = (status == HT_OK) ? FTP_NEED_DCON : FTP_ERROR;	    break;	  case FTP_NEED_DCON:	    HTTRACE(PROT_TRACE, "FTP Event... now in state FTP_NEED_DCON\n");	    status = HTFTPDataConnection(request, cnet, ctrl, data);	    if (status == HT_WOULD_BLOCK) return HT_OK;	    if (status == HT_OK)		ctrl->state = (data->type=='N') ?		    FTP_NEED_SERVER : FTP_NEED_DATA;	    else		ctrl->state = FTP_ERROR;	    break;	  case FTP_NEED_DATA:	    HTTRACE(PROT_TRACE, "FTP Event... now in state FTP_NEED_DATA\n");	    status = HTFTPGetData(request, cnet, soc, ctrl, data); 	    if (status == HT_WOULD_BLOCK) return HT_OK;	    if (status == HT_LOADED)		ctrl->state = FTP_SUCCESS;	    else if (status == HT_OK)		ctrl->state = FTP_NEED_DCON;	    else if (!FTP_DIR(data) && !data->stream_error) {		FTPListType(data, ctrl->server);		ctrl->state = FTP_NEED_SERVER;         /* Try a dir instead? */	    } else		ctrl->state = FTP_ERROR;	    break;	  case FTP_NEED_SERVER:	    HTTRACE(PROT_TRACE, "FTP Event... now in state FTP_NEED_SERVER\n");	    status = HTFTPServerInfo(request, cnet, ctrl, data);	    if (status == HT_WOULD_BLOCK) return HT_OK;	    ctrl->state = FTP_NEED_DATA;	    break;	  case FTP_SUCCESS:	    HTTRACE(PROT_TRACE, "FTP Event... now in state FTP_SUCCESS\n");	    FTPCleanup(request, HT_LOADED);	    return HT_OK;	    break;	    	  case FTP_ERROR:	    HTTRACE(PROT_TRACE, "FTP Event... now in state FTP_ERROR\n");	    FTPCleanup(request, HT_ERROR);	    return HT_OK;	    break;	}    } /* End of while(1) */}PUBLIC void HTFTP_setTransferMode(FTPTransferMode mode){    g_FTPTransferMode = mode;}PUBLIC FTPTransferMode HTFTP_transferMode (void){    return g_FTPTransferMode;}PUBLIC void HTFTP_setControlMode (FTPControlMode mode){    g_FTPControlMode = mode;}PUBLIC FTPControlMode HTFTP_controlMode (void){    return g_FTPControlMode;}

⌨️ 快捷键说明

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