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

📄 ftpdlib.c

📁 ftp源代码。大名鼎鼎的嵌入式操作系统vxworks的完整的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
        if (ftpdWindowSize < 0 || ftpdWindowSize > 65536)            ftpdWindowSize = FTPD_WINDOW_SIZE;        /* set the window size  */        if (setsockopt(newSock, SOL_SOCKET, SO_SNDBUF,            (char *)&ftpdWindowSize, sizeof (ftpdWindowSize)))                printf("Couldn't set the Send Window to 10k\n");        if (setsockopt(newSock, SOL_SOCKET, SO_RCVBUF,            (char *)&ftpdWindowSize, sizeof (ftpdWindowSize)))                printf("Couldn't set the Send Window to 10k\n");	    /* replace the dataSock with our new connection */	    (void) close (pSlot->dataSock);	    pSlot->dataSock = newSock;	    /* N.B.: we stay passive */            if (ftpdCmdSend (pSlot, pSlot->cmdSock,                             150, "Opening %s mode data connection",                             pSlot->status & FTPD_ASCII_TYPE ? (int) "ASCII"                             : (int) "BINARY", 0, 0, 0, 0, 0) == ERROR)		{		(void) close (pSlot->dataSock);		return (ERROR);		}	    return (OK);	    }	else	    {	    /* reuse the old connection -- it's still useful */            if (ftpdCmdSend (pSlot, pSlot->cmdSock,                              125, "Using existing data connection",                             0, 0, 0, 0, 0, 0) == ERROR)		{	    	ftpdSockFree (&pSlot->dataSock);		return (ERROR);		}	    return (OK);	    }	}    else        {        /* Determine address for local end of connection. */        addrLen = sizeof (struct sockaddr);        if (getsockname (pSlot->cmdSock, (struct sockaddr *) &addr, &addrLen)                < 0)            {            return (ERROR);            }        /* Replace control port with default data port. */        addr.sin_port = htons (FTP_DATA_PORT);	/* open a new data socket */	if ((pSlot->dataSock = socket (AF_INET, SOCK_STREAM, 0)) < 0)	    { 	    return (ERROR);	    }	if (setsockopt (pSlot->dataSock, SOL_SOCKET,			SO_REUSEADDR, (char *) &on, sizeof (on)) < 0 ||	    bind (pSlot->dataSock, (struct sockaddr *) &addr,		  sizeof (addr)) < 0)	    {	    ftpdSockFree (&pSlot->dataSock);	    return (ERROR);	    }        /* Set socket address to PORT command values or default. */        bcopy ( (char *)&pSlot->dataAddr, (char *)&addr,                sizeof (struct sockaddr_in));	/* try until we get a connection to the client's port */	while (connect (pSlot->dataSock,			(struct sockaddr *) &addr, sizeof (addr)) < 0)	    {	    if ((errno & 0xffff) == EADDRINUSE && retry < FTPD_WAIT_MAX)	        {		taskDelay (FTPD_WAIT_INTERVAL * sysClkRateGet ());		retry += FTPD_WAIT_INTERVAL;		continue;		}	    /* timeout -- we give up */            ftpdCmdSend (pSlot, pSlot->cmdSock,                         425, "Can't build data connection",                         0, 0, 0, 0, 0, 0);	    ftpdSockFree (&pSlot->dataSock);	    return (ERROR);	    }            /*             * Enable the keep alive option to prevent misbehaving clients             * from locking the secondary task during file transfers.             */            if (setsockopt (pSlot->dataSock, SOL_SOCKET, SO_KEEPALIVE,                             (char *) &on, sizeof (on)) != 0)                {                ftpdSockFree (&pSlot->dataSock);                return (ERROR);                }	    /* Check for window size validity */	    if (ftpdWindowSize < 0 || ftpdWindowSize > 65536)		ftpdWindowSize = FTPD_WINDOW_SIZE;	    /* set the window size  */	    if (setsockopt(pSlot->dataSock, SOL_SOCKET, SO_SNDBUF,		(char *)&ftpdWindowSize, sizeof (ftpdWindowSize)))		    printf("Couldn't set the Send Window to 10k\n");	    if (setsockopt(pSlot->dataSock, SOL_SOCKET, SO_RCVBUF,		(char *)&ftpdWindowSize, sizeof (ftpdWindowSize)))		    printf("Couldn't set the Send Window to 10k\n");            if (ftpdCmdSend (pSlot, pSlot->cmdSock,                              150, "Opening %s mode data connection",                             pSlot->status & FTPD_ASCII_TYPE ? (int) "ASCII" :                             (int) "BINARY", 0, 0, 0, 0, 0) == ERROR)		{		ftpdSockFree (&pSlot->dataSock);		return (ERROR);		}	}    return (OK);    }/********************************************************************************* ftpdDataStreamSend - send FTP data over data connection** When our FTP client does a "RETR" (send me a file) and we find an existing* file, ftpdWorkTask() will call us to perform the actual shipment of the* file in question over the data connection.** We do the initialization of the new data connection ourselves here* and make sure that everything is fine and dandy before shipping the* contents of the file.  Special attention is given to the type of* the file representation -- ASCII or BINARY.  If it's binary, we* don't perform the prepending of "\r" character in front of each* "\n" character.  Otherwise, we have to do this for the ASCII files.** SEE ALSO:* ftpdDataStreamReceive  which is symmetric to this function.*/LOCAL void ftpdDataStreamSend    (    FTPD_SESSION_DATA   *pSlot,         /* pointer to our session slot */    FILE                *inStream       /* pointer to the input file stream */    )    {    FAST char	*pBuf;			/* pointer to the session buffer */    FAST int	netFd;			/* output socket */    FAST int	fileFd;			/* input file descriptor */    FAST char	ch;			/* character holder */    FAST int	cnt;			/* number of chars read/written */    FAST FILE	*outStream;		/* buffered output socket stream */    int		retval = 0;    /* get a fresh connection or reuse the old one */    if (ftpdDataConnGet (pSlot) == ERROR)	{	dataError (pSlot);	return;	}    pBuf = &pSlot->buf [0];    if (pSlot->status & FTPD_ASCII_TYPE)	{	/* ASCII representation */	/* get a buffered I/O stream for this output data socket */	if ((outStream = fdopen (pSlot->dataSock, "w")) == NULL)	    {	    dataError (pSlot);	    return;	    }	/* write out the contents of the file and do the '\r' prepending */	while ((ch = getc (inStream)) != (char) EOF)	    {	    pSlot->byteCount++;	    /* if '\n' is encountered, we prepend a '\r' */	    if (ch == '\n')		{		if (ferror (outStream))		    {		    dataError (pSlot);		    fclose (outStream);		    return;		    }		if (putc ('\r', outStream) == EOF)		    {		    dataError (pSlot);		    fclose (outStream);		    return;		    }		}	    	if (putc (ch, outStream) == EOF)		{		dataError (pSlot);		fclose (outStream);		return;		}            /* Abort the file transfer if a shutdown is in progress. */            if (ch == '\n' && ftpsShutdownFlag)                {		dataError (pSlot);                fclose (outStream);                return;                }	    }	/* flush it out */	(void) fflush (outStream);	if (ferror (inStream))	    {	    /* error in reading the file */	    fileError (pSlot);	    fclose (outStream);	    return;	    }	if (ferror (outStream))	    {	    /* error in sending the file */	    dataError (pSlot);	    fclose (outStream);	    return;	    }	fclose (outStream);	/* everything is okay */	transferOkay (pSlot);	}    else if (pSlot->status & FTPD_BINARY_TYPE)	{	/* BINARY representation */	netFd = pSlot->dataSock;	/* get a raw descriptor for this input file */	fileFd = fileno (inStream);	/* unbuffered block I/O between file and network */	while ((cnt = read (fileFd, pBuf, BUFSIZE)) > 0 &&	       (retval = write (netFd, pBuf, cnt)) == cnt)            {	    pSlot->byteCount += cnt;            if (ftpsShutdownFlag)                {                /* Abort the file transfer if a shutdown is in progress. */                cnt = 1;                break;                }            }	/* cnt should be zero if the transfer ended normally */	if (cnt != 0)	    {	    if (cnt < 0)		{		fileError (pSlot);		return;		}	    ftpdDebugMsg ("read %d bytes, wrote %d bytes\n", cnt, retval,0,0);	    dataError (pSlot);	    return;	    }	transferOkay (pSlot);	}    else	unImplementedType (pSlot);	/* invalide representation type */    }/********************************************************************************* ftpdDataStreamReceive - receive FTP data over data connection** When our FTP client requests "STOR" command and we were able to* create a file requested, ftpdWorkTask() will call ftpdDataStreamReceive* to actually carry out the request -- receiving the contents of the* named file and storing it in the new file created.** We do the initialization of the new data connection ourselves here* and make sure that everything is fine and dandy before receiving the* contents of the file.  Special attention is given to the type of* the file representation -- ASCII or BINARY.  If it's binary, we* don't perform the handling of '\r' character in front of each* '\n' character.  Otherwise, we have to do this for the ASCII files.** SEE ALSO:* ftpdDataStreamSend which is symmetric to this function.*/LOCAL void ftpdDataStreamReceive    (    FTPD_SESSION_DATA   *pSlot,    FILE                *outStream    )    {    FAST char	*pBuf;		/* pointer to the session buffer */    FAST char 	ch;		/* character holder */    FAST FILE	*inStream;	/* buffered input file stream for data socket */    FAST int	fileFd;		/* output file descriptor */    FAST int	netFd;		/* network file descriptor */    FAST BOOL	dontPutc;	/* flag to prevent bogus chars */    FAST int	cnt;		/* number of chars read/written */    /* get a fresh data connection or reuse the old one */    if (ftpdDataConnGet (pSlot) == ERROR)	{	dataError (pSlot);	return;	}    pBuf = &pSlot->buf [0];    if (pSlot->status & FTPD_ASCII_TYPE)	{	/* ASCII representation */	/* get a buffer I/O stream for the input data socket connection */	if ((inStream = fdopen (pSlot->dataSock, "r")) == NULL)	    {	    dataError (pSlot);	    return;	    }	/* read in the contents of the file while doing the '\r' handling */	while ((ch = getc (inStream)) != (char) EOF)	    {	    dontPutc = FALSE;	    pSlot->byteCount++;	    /* a rather strange handling of sequences of '\r' chars */	    while (ch == '\r')		{		if (ferror (outStream))		    {		    dataError (pSlot);		    fclose (inStream);		    return;		    }		/* replace bogus chars between '\r' and '\n' chars with '\r' */		if ((ch = getc (inStream)) != '\n')		    {		    (void) putc ('\r', outStream);		    if (ch == '\0' || ch == (char) EOF)			{			dontPutc = TRUE;			break;			}		    }		}	    if (dontPutc == FALSE)		(void) putc (ch, outStream);            /* Abort file transfer if a shutdown is in progress. */            if (ch == '\n' && ftpsShutdownFlag)	        {	        dataError (pSlot);	        fclose (inStream);	        return;                }            }	/* flush out to the file */	(void) fflush (outStream);	if (ferror (inStream))	    {	    /* network input error */	    dataError (pSlot);	    fclose (inStream);	    return;	    }	if (ferror (outStream))	    {	    /* file output error */	    fileError (pSlot);	    fclose (inStream);	    retur

⌨️ 快捷键说明

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