📄 ftplib.c
字号:
/***************************************************************************//* *//* ftplib.c - Part of Open C FTP Client *//* *//* Copyright (C) 2007 Nokia Corporation *//* *//* Open C FTP Client is based on ftplib and qftp by Thomas Pfau. *//* *//* Copyright (C) 1996-2001 Thomas Pfau, pfau@eclipse.net *//* 1407 Thomas Ave, North Brunswick, NJ, 08902 *//* *//* This program is free software; you can redistribute it and/or *//* modify it under the terms of the GNU Library General Public *//* License as published by the Free Software Foundation; either *//* version 2 of the License, or (at your option) any later version. *//* *//* This program is distributed in the hope that it will be useful, *//* but WITHOUT ANY WARRANTY; without even the implied warranty of *//* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *//* Library General Public License for more details. *//* *//* You should have received a copy of the GNU Library General Public *//* License along with this program; if not, write to the *//* Free Software Foundation, Inc., 59 Temple Place - Suite 330, *//* Boston, MA 02111-1307, USA. *//* *//***************************************************************************/ /* * ============================================================================ * Name : FTPLIB from ftplib.c * Part of : Open C FTP Client * Created : 03/12/2007 by Forum Nokia * Version : 1.0 * ============================================================================*//* This original code is commented out due to the conversion changes *///#if defined(__unix__) || defined(__VMS)#include <unistd.h>/* This original code is commented out due to the conversion changes *//*#endif#if defined(_WIN32)#include <windows.h>#endif*/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <errno.h>#include <ctype.h>/* This original code is commented out due to the conversion changes *///#if defined(__unix__)#include <sys/time.h>#include <sys/select.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <netdb.h>#include <arpa/inet.h>/* This original code is commented out due to the conversion changes *//*#elif defined(VMS)#include <types.h>#include <socket.h>#include <in.h>#include <netdb.h>#include <inet.h>#elif defined(_WIN32)#include <winsock.h>#endif*/#define BUILDING_LIBRARY#include "ftplib.h"/* This original code is commented out due to the conversion changes *///#if defined(_WIN32)//#define SETSOCKOPT_OPTVAL_TYPE (const char *)//#else#define SETSOCKOPT_OPTVAL_TYPE (void *)/* This original code is commented out due to the conversion changes *///#endif#define FTPLIB_BUFSIZ 8192#define ACCEPT_TIMEOUT 30#define FTPLIB_CONTROL 0#define FTPLIB_READ 1#define FTPLIB_WRITE 2#if !defined FTPLIB_DEFMODE#define FTPLIB_DEFMODE FTPLIB_PASSIVE#endifstruct NetBuf { char *cput,*cget; int handle; int cavail,cleft; char *buf; int dir; netbuf *ctrl; netbuf *data; int cmode; struct timeval idletime; FtpCallback idlecb; void *idlearg; int xfered; int cbbytes; int xfered1; char response[256];};/* This original code is commented out due to the conversion changes *///static char *version = "ftplib Release 3.1-1 9/16/00, copyright 1996-2000 Thomas Pfau";//GLOBALDEF int ftplib_debug = 0;int ftplib_debug = 0;/* This original code is commented out due to the conversion changes *///#if defined(__unix__) || defined(VMS)#define net_read read#define net_write write#define net_close close/* This original code is commented out due to the conversion changes *//*#elif defined(_WIN32)#define net_read(x,y,z) recv(x,y,z,0)#define net_write(x,y,z) send(x,y,z,0)#define net_close closesocket#endif*/#if defined(NEED_MEMCCPY)/* * VAX C does not supply a memccpy routine so I provide my own */void *memccpy(void *dest, const void *src, int c, size_t n){ int i=0; const unsigned char *ip=src; unsigned char *op=dest; while (i < n) { if ((*op++ = *ip++) == c) break; i++; } if (i == n) return NULL; return op;}#endif#if defined(NEED_STRDUP)/* * strdup - return a malloc'ed copy of a string */char *strdup(const char *src){ int l = strlen(src) + 1; char *dst = malloc(l); if (dst) strcpy(dst,src); return dst;}#endif/* * socket_wait - wait for socket to receive or flush data * * return 1 if no user callback, otherwise, return value returned by * user callback */static int socket_wait(netbuf *ctl){ fd_set fd,*rfd = NULL,*wfd = NULL; struct timeval tv; int rv = 0; if ((ctl->dir == FTPLIB_CONTROL) || (ctl->idlecb == NULL)) return 1; if (ctl->dir == FTPLIB_WRITE) wfd = &fd; else rfd = &fd; FD_ZERO(&fd); do { FD_SET(ctl->handle,&fd); tv = ctl->idletime; rv = select(ctl->handle+1, rfd, wfd, NULL, &tv); if (rv == -1) { rv = 0; strncpy(ctl->ctrl->response, strerror(errno), sizeof(ctl->ctrl->response)); break; } else if (rv > 0) { rv = 1; break; } } while ((rv = ctl->idlecb(ctl, ctl->xfered, ctl->idlearg))); return rv;}/* * read a line of text * * return -1 on error or bytecount */static int readline(char *buf,int max,netbuf *ctl){ int x,retval = 0; char *end,*bp=buf; int eof = 0; if ((ctl->dir != FTPLIB_CONTROL) && (ctl->dir != FTPLIB_READ)) { return -1; } if (max == 0) return 0; do { if (ctl->cavail > 0) { x = (max >= ctl->cavail) ? ctl->cavail : max-1; end = memccpy(bp,ctl->cget,'\n',x); if (end != NULL) x = end - bp; retval += x; bp += x; *bp = '\0'; max -= x; ctl->cget += x; ctl->cavail -= x; if (end != NULL) { bp -= 2; if (strcmp(bp,"\r\n") == 0) { *bp++ = '\n'; *bp++ = '\0'; --retval; } break; } } if (max == 1) { *buf = '\0'; break; } if (ctl->cput == ctl->cget) { ctl->cput = ctl->cget = ctl->buf; ctl->cavail = 0; ctl->cleft = FTPLIB_BUFSIZ; } if (eof) { if (retval == 0) retval = -1; break; } if (!socket_wait(ctl)) { return retval; } if ((x = net_read(ctl->handle,ctl->cput,ctl->cleft)) == -1) {// For some reason at the end of file -1 is returned instead of expected 0/* This original code is commented out due to the conversion changes */// perror("read"); retval = -1; break; } if (x == 0) { eof = 1; } ctl->cleft -= x; ctl->cavail += x; ctl->cput += x; } while (1); return retval;}/* * write lines of text * * return -1 on error or bytecount */static int writeline(char *buf, int len, netbuf *nData){ int x, nb=0, w; char *ubp = buf, *nbp; char lc=0; if (nData->dir != FTPLIB_WRITE) return -1; nbp = nData->buf; for (x=0; x < len; x++) { if ((*ubp == '\n') && (lc != '\r')) { if (nb == FTPLIB_BUFSIZ) { if (!socket_wait(nData)) return x; w = net_write(nData->handle, nbp, FTPLIB_BUFSIZ); if (w != FTPLIB_BUFSIZ) {/* This original code is commented out due to the conversion changes */// printf("net_write(1) returned %d, errno = %d\n", w, errno); return(-1); } nb = 0; } nbp[nb++] = '\r'; } if (nb == FTPLIB_BUFSIZ) { if (!socket_wait(nData)) return x; w = net_write(nData->handle, nbp, FTPLIB_BUFSIZ); if (w != FTPLIB_BUFSIZ) {/* This original code is commented out due to the conversion changes */// printf("net_write(2) returned %d, errno = %d\n", w, errno); return(-1); } nb = 0; } nbp[nb++] = lc = *ubp++; } if (nb) { if (!socket_wait(nData)) return x; w = net_write(nData->handle, nbp, nb); if (w != nb) {/* This original code is commented out due to the conversion changes */// printf("net_write(3) returned %d, errno = %d\n", w, errno); return(-1); } } return len;}/* * read a response from the server * * return 0 if first char doesn't match * return 1 if first char matches */static int readresp(char c, netbuf *nControl){ char match[5]; if (readline(nControl->response,256,nControl) == -1) {/* This original code is commented out due to the conversion changes */// perror("Control socket read failed"); return 0; }/* This original code is commented out due to the conversion changes *//* if (ftplib_debug > 1) fprintf(stderr,"%s",nControl->response);*/ if (nControl->response[3] == '-') { strncpy(match,nControl->response,3); match[3] = ' '; match[4] = '\0'; do { if (readline(nControl->response,256,nControl) == -1) {/* This original code is commented out due to the conversion changes */// perror("Control socket read failed"); return 0; }/* This original code is commented out due to the conversion changes *//* if (ftplib_debug > 1) fprintf(stderr,"%s",nControl->response);*/ } while (strncmp(nControl->response,match,4)); } if (nControl->response[0] == c) { return 1; } return 0;}/* * FtpInit for stupid operating systems that require it (Windows NT) *//* This original code is commented out due to the conversion changes *///GLOBALDEF void FtpInit(void)void FtpInit(){/* This original code is commented out due to the conversion changes *//*#if defined(_WIN32) WORD wVersionRequested; WSADATA wsadata; int err; wVersionRequested = MAKEWORD(1,1); if ((err = WSAStartup(wVersionRequested,&wsadata)) != 0) fprintf(stderr,"Network failed to start: %d\n",err);#endif*/}/* * FtpLastResponse - return a pointer to the last response received *//* This original code is commented out due to the conversion changes *///GLOBALDEF char *FtpLastResponse(netbuf *nControl)char *FtpLastResponse(netbuf *nControl){ if ((nControl) && (nControl->dir == FTPLIB_CONTROL)) return nControl->response; return NULL;}/* * FtpConnect - connect to remote server * * return 1 if connected, 0 if not *//* This original code is commented out due to the conversion changes *///GLOBALDEF int FtpConnect(const char *host, netbuf **nControl)int FtpConnect(const char *host, netbuf **nControl){ int sControl; struct sockaddr_in sin; struct hostent *phe; struct servent *pse; int on=1; netbuf *ctrl; char *lhost; char *pnum; memset(&sin,0,sizeof(sin)); sin.sin_family = AF_INET; lhost = strdup(host); pnum = strchr(lhost,':'); if (pnum == NULL) {/* This original code is commented out due to the conversion changes *//*#if defined(VMS) sin.sin_port = htons(21);#else*/ if ((pse = getservbyname("ftp","tcp")) == NULL) {/* This original code is commented out due to the conversion changes */// perror("getservbyname"); return 0; } sin.sin_port = pse->s_port;/* This original code is commented out due to the conversion changes *///#endif } else { *pnum++ = '\0'; if (isdigit(*pnum)) sin.sin_port = htons((short)atoi(pnum)); else { pse = getservbyname(pnum,"tcp"); sin.sin_port = pse->s_port; } } if ((sin.sin_addr.s_addr = inet_addr(lhost)) == -1) { if ((phe = gethostbyname(lhost)) == NULL) {/* This original code is commented out due to the conversion changes */// perror("gethostbyname"); return 0; } memcpy((char *)&sin.sin_addr, phe->h_addr, phe->h_length); } free(lhost); sControl = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); if (sControl == -1) {/* This original code is commented out due to the conversion changes */// perror("socket"); return 0; } if (setsockopt(sControl,SOL_SOCKET,SO_REUSEADDR, SETSOCKOPT_OPTVAL_TYPE &on, sizeof(on)) == -1) {/* This original code is commented out due to the conversion changes */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -