📄 ftplib.cpp.svn-base
字号:
perror("bind"); net_close(sData); return 0; } if (listen(sData, 1) < 0) { perror("listen"); net_close(sData); return 0; } if (getsockname(sData, &sin.sa, (socklen_t*)&l) < 0) return 0; sprintf(buf, "PORT %d,%d,%d,%d,%d,%d", (unsigned char) sin.sa.sa_data[2], (unsigned char) sin.sa.sa_data[3], (unsigned char) sin.sa.sa_data[4], (unsigned char) sin.sa.sa_data[5], (unsigned char) sin.sa.sa_data[0], (unsigned char) sin.sa.sa_data[1]); if (!FtpSendCmd(buf,'2',nControl)) { net_close(sData); return 0; } } ctrl = (NetBuf*)calloc(1,sizeof(netbuf)); if (ctrl == NULL) { perror("calloc"); net_close(sData); return -1; } if ((mode == 'A') && ((ctrl->buf = (char*)malloc(FTPLIB_BUFSIZ)) == NULL)) { perror("calloc"); net_close(sData); free(ctrl); return -1; } ctrl->handle = sData; ctrl->dir = dir; ctrl->idletime = nControl->idletime; ctrl->idlearg = nControl->idlearg; ctrl->xfered = 0; ctrl->xfered1 = 0; ctrl->cbbytes = nControl->cbbytes; if (ctrl->idletime.tv_sec || ctrl->idletime.tv_usec || ctrl->cbbytes) ctrl->idlecb = nControl->idlecb; else ctrl->idlecb = NULL; *nData = ctrl; return 1;}
/* * FtpAcceptConnection - accept connection from server * * return 1 if successful, 0 otherwise */int FtpAcceptConnection(netbuf *nData, netbuf *nControl){ int sData; struct sockaddr addr; socklen_t l; int i; struct timeval tv; fd_set mask; int rv; FD_ZERO(&mask); FD_SET(nControl->handle, &mask); FD_SET(nData->handle, &mask); tv.tv_usec = 0; tv.tv_sec = ACCEPT_TIMEOUT; i = nControl->handle; if ((unsigned int)i < nData->handle) i = nData->handle; i = select(i+1, &mask, NULL, NULL, &tv); if (i == -1) { strncpy(nControl->response, strerror(errno), sizeof(nControl->response)); net_close(nData->handle); nData->handle = 0; rv = 0; } else if (i == 0) { strcpy(nControl->response, "timed out waiting for connection"); net_close(nData->handle); nData->handle = 0; rv = 0; } else { if (FD_ISSET(nData->handle, &mask)) { l = sizeof(addr); sData = accept(nData->handle, &addr, (socklen_t*)&l); i = errno; net_close(nData->handle); if (sData > 0) { rv = 1; nData->handle = sData; } else { strncpy(nControl->response, strerror(i), sizeof(nControl->response)); nData->handle = 0; rv = 0; } } else if (FD_ISSET(nControl->handle, &mask)) { net_close(nData->handle); nData->handle = 0; readresp('2', nControl); rv = 0; } } return rv; }
/* * FtpAccess - return a handle for a data stream * * return 1 if successful, 0 otherwise */int FtpAccess(const char *path, int typ, int mode, netbuf *nControl, netbuf **nData){ char buf[256]; int dir; if ((path == NULL) && ((typ == FTPLIB_FILE_WRITE) || (typ == FTPLIB_FILE_READ))) { sprintf(nControl->response, "Missing path argument for file transfer\n"); return 0; } sprintf(buf, "TYPE %c", mode); if (!FtpSendCmd(buf, '2', nControl)) return 0; switch (typ) { case FTPLIB_DIR: strcpy(buf,"NLST"); dir = FTPLIB_READ; break; case FTPLIB_DIR_VERBOSE: strcpy(buf,"LIST"); dir = FTPLIB_READ; break; case FTPLIB_FILE_READ: strcpy(buf,"RETR"); dir = FTPLIB_READ; break; case FTPLIB_FILE_WRITE: strcpy(buf,"STOR"); dir = FTPLIB_WRITE; break; default: sprintf(nControl->response, "Invalid open type %d\n", typ); return 0; } if (path != NULL) { int i = strlen(buf); buf[i++] = ' '; if ((strlen(path) + i) >= sizeof(buf)) return 0; strcpy(&buf[i],path); } if (FtpOpenPort(nControl, nData, mode, dir) == -1) return 0; if (!FtpSendCmd(buf, '1', nControl)) { FtpClose(*nData); *nData = NULL; return 0; } (*nData)->ctrl = nControl; nControl->data = *nData; if (nControl->cmode == FTPLIB_PORT) { if (!FtpAcceptConnection(*nData,nControl)) { FtpClose(*nData); *nData = NULL; nControl->data = NULL; return 0; } } return 1;}
/* * FtpRead - read from a data connection */int FtpRead(void *buf, int max, netbuf *nData){ int i; if (nData->dir != FTPLIB_READ) return 0; if (nData->buf) i = readline((char*)buf, max, nData); else { i = socket_wait(nData); if (i != 1) return 0; i = net_read(nData->handle, (char*)buf, max); } if (i == -1) return 0; nData->xfered += i; if (nData->idlecb && nData->cbbytes) { nData->xfered1 += i; if (nData->xfered1 > nData->cbbytes) { if (nData->idlecb(nData, nData->xfered, nData->idlearg) == 0) return 0; nData->xfered1 = 0; } } return i;}
/* * FtpWrite - write to a data connection */int FtpWrite(void *buf, int len, netbuf *nData){ int i; if (nData->dir != FTPLIB_WRITE) return 0; if (nData->buf) i = writeline((char*)buf, len, nData); else { socket_wait(nData); i = net_write(nData->handle, (char*)buf, len); } if (i == -1) return 0; nData->xfered += i; if (nData->idlecb && nData->cbbytes) { nData->xfered1 += i; if (nData->xfered1 > nData->cbbytes) { nData->idlecb(nData, nData->xfered, nData->idlearg); nData->xfered1 = 0; } } return i;}
/* * FtpClose - close a data connection */int FtpClose(netbuf *nData){ netbuf *ctrl; switch (nData->dir) { case FTPLIB_WRITE: /* potential problem - if buffer flush fails, how to notify user? */ if (nData->buf != NULL) writeline(NULL, 0, nData); case FTPLIB_READ: if (nData->buf) free(nData->buf); shutdown(nData->handle,2); net_close(nData->handle); ctrl = nData->ctrl; free(nData); if (ctrl) { ctrl->data = NULL; return(readresp('2', ctrl)); } return 1; case FTPLIB_CONTROL: if (nData->data) { nData->ctrl = NULL; FtpClose(nData); } net_close(nData->handle); free(nData); return 0; } return 1;}
/* * FtpSite - send a SITE command * * return 1 if command successful, 0 otherwise */int FtpSite(const char *cmd, netbuf *nControl){ char buf[256]; if ((strlen(cmd) + 7) > sizeof(buf)) return 0; sprintf(buf,"SITE %s",cmd); if (!FtpSendCmd(buf,'2',nControl)) return 0; return 1;}
/* * FtpSysType - send a SYST command * * Fills in the user buffer with the remote system type. If more * information from the response is required, the user can parse * it out of the response buffer returned by FtpLastResponse(). * * return 1 if command successful, 0 otherwise */int FtpSysType(char *buf, int max, netbuf *nControl){ int l = max; char *b = buf; char *s; if (!FtpSendCmd("SYST",'2',nControl)) return 0; s = &nControl->response[4]; while ((--l) && (*s != ' ')) *b++ = *s++; *b++ = '\0'; return 1;}
/* * FtpMkdir - create a directory at server * * return 1 if successful, 0 otherwise */int FtpMkdir(const char *path, netbuf *nControl){ char buf[256]; if ((strlen(path) + 6) > sizeof(buf)) return 0; sprintf(buf,"MKD %s",path); if (!FtpSendCmd(buf,'2', nControl)) return 0; return 1;}
/* * FtpChdir - change path at remote * * return 1 if successful, 0 otherwise */int FtpChdir(const char *path, netbuf *nControl){ char buf[256]; if ((strlen(path) + 6) > sizeof(buf)) return 0; sprintf(buf,"CWD %s",path); if (!FtpSendCmd(buf,'2',nControl)) return 0; return 1;}
/* * FtpCDUp - move to parent directory at remote * * return 1 if successful, 0 otherwise */int FtpCDUp(netbuf *nControl){ if (!FtpSendCmd("CDUP",'2',nControl)) return 0; return 1;}
/* * FtpRmdir - remove directory at remote * * return 1 if successful, 0 otherwise */int FtpRmdir(const char *path, netbuf *nControl){ char buf[256]; if ((strlen(path) + 6) > sizeof(buf)) return 0; sprintf(buf,"RMD %s",path); if (!FtpSendCmd(buf,'2',nControl)) return 0; return 1;}
/* * FtpPwd - get working directory at remote * * return 1 if successful, 0 otherwise */int FtpPwd(char *path, int max, netbuf *nControl){ int l = max; char *b = path; char *s; if (!FtpSendCmd("PWD",'2',nControl)) return 0; s = strchr(nControl->response, '"'); if (s == NULL) return 0; s++; while ((--l) && (*s) && (*s != '"')) *b++ = *s++; *b++ = '\0'; return 1;}
/* * FtpXfer - issue a command and transfer data * * return 1 if successful, 0 otherwise */int FtpXfer(const char *localfile, const char *path, netbuf *nControl, int typ, int mode){ int l,c; char *dbuf; FILE *local = NULL; netbuf *nData; int rv=1; if (localfile != NULL) { char ac[4] = "w"; if (typ == FTPLIB_FILE_WRITE) ac[0] = 'r'; if (mode == FTPLIB_IMAGE) ac[1] = 'b'; local = fopen(localfile, ac); if (local == NULL) { strncpy(nControl->response, strerror(errno), sizeof(nControl->response)); return 0; } } if (local == NULL) local = (typ == FTPLIB_FILE_WRITE) ? stdin : stdout; if (!FtpAccess(path, typ, mode, nControl, &nData)) return 0; dbuf = (char*)malloc(FTPLIB_BUFSIZ); if (typ == FTPLIB_FILE_WRITE) { while ((l = fread(dbuf, 1, FTPLIB_BUFSIZ, local)) > 0) if ((c = FtpWrite(dbuf, l, nData)) < l) { printf("short write: passed %d, wrote %d\n", l, c); rv = 0; break; } } else { while ((l = FtpRead(dbuf, FTPLIB_BUFSIZ, nData)) > 0) if (fwrite(dbuf, 1, l, local) <= 0) { perror("localfile write"); rv = 0; break; } } free(dbuf); fflush(local); if (localfile != NULL) fclose(local); FtpClose(nData); return rv;}
/* * FtpNlst - issue an NLST command and write response to output * * return 1 if successful, 0 otherwise */int FtpNlst(const char *outputfile, const char *path, netbuf *nControl){ return FtpXfer(outputfile, path, nControl, FTPLIB_DIR, FTPLIB_ASCII);}
/* * FtpDir - issue a LIST command and write response to output * * return 1 if successful, 0 otherwise */int FtpDir(const char *outputfile, const char *path, netbuf *nControl){ return FtpXfer(outputfile, path, nControl, FTPLIB_DIR_VERBOSE, FTPLIB_ASCII);}
/* * FtpSize - determine the size of a remote file * * return 1 if successful, 0 otherwise */int FtpSize(const char *path, int *size, char mode, netbuf *nControl){ char cmd[256]; int resp,sz,rv=1; if ((strlen(path) + 7) > sizeof(cmd)) return 0; sprintf(cmd, "TYPE %c", mode); if (!FtpSendCmd(cmd, '2', nControl)) return 0; sprintf(cmd,"SIZE %s",path); if (!FtpSendCmd(cmd,'2',nControl)) rv = 0; else { if (sscanf(nControl->response, "%d %d", &resp, &sz) == 2) *size = sz; else rv = 0; } return rv;}
/* * FtpModDate - determine the modification date of a remote file * * return 1 if successful, 0 otherwise */int FtpModDate(const char *path, char *dt, int max, netbuf *nControl){ char buf[256]; int rv = 1; if ((strlen(path) + 7) > sizeof(buf)) return 0; sprintf(buf,"MDTM %s",path); if (!FtpSendCmd(buf,'2',nControl)) rv = 0; else strncpy(dt, &nControl->response[4], max); return rv;}
/* * FtpGet - issue a GET command and write received data to output * * return 1 if successful, 0 otherwise */int FtpGet(const char *outputfile, const char *path, char mode, netbuf *nControl){ return FtpXfer(outputfile, path, nControl, FTPLIB_FILE_READ, mode);}
/* * FtpPut - issue a PUT command and send data from input * * return 1 if successful, 0 otherwise */int FtpPut(const char *inputfile, const char *path, char mode, netbuf *nControl){ return FtpXfer(inputfile, path, nControl, FTPLIB_FILE_WRITE, mode);}
/* * FtpRename - rename a file at remote * * return 1 if successful, 0 otherwise */int FtpRename(const char *src, const char *dst, netbuf *nControl){ char cmd[256]; if (((strlen(src) + 7) > sizeof(cmd)) || ((strlen(dst) + 7) > sizeof(cmd))) return 0; sprintf(cmd,"RNFR %s",src); if (!FtpSendCmd(cmd,'3',nControl)) return 0; sprintf(cmd,"RNTO %s",dst); if (!FtpSendCmd(cmd,'2',nControl)) return 0; return 1;}
/* * FtpDelete - delete a file at remote * * return 1 if successful, 0 otherwise */int FtpDelete(const char *fnm, netbuf *nControl){ char cmd[256]; if ((strlen(fnm) + 7) > sizeof(cmd)) return 0; sprintf(cmd,"DELE %s",fnm); if (!FtpSendCmd(cmd,'2', nControl)) return 0; return 1;}
/* * FtpQuit - disconnect from remote * * return 1 if successful, 0 otherwise */void FtpQuit(netbuf *nControl){ if (nControl->dir != FTPLIB_CONTROL) return; FtpSendCmd("QUIT",'2',nControl); net_close(nControl->handle); free(nControl->buf); free(nControl);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -