📄 ftp.c
字号:
/* parse out the port */ for (ptr = ftp->inbuf; *ptr && *ptr != '('; ptr++); if (!*ptr) return 0; delimiter = *++ptr; for (n = 0; *ptr && n < 3; ptr++) { if (*ptr == delimiter) n++; } sin6->sin6_port = htons((unsigned short) strtoul(ptr, &endptr, 10)); if (ptr == endptr || *endptr != delimiter) return 0; ftp->pasv = 2; return 1; } } /* fall back to PASV */#endif if (!ftp_putcmd(ftp, "PASV", NULL)) return 0; if (!ftp_getresp(ftp) || ftp->resp != 227) return 0; /* parse out the IP and port */ for (ptr = ftp->inbuf; *ptr && !isdigit(*ptr); ptr++); n = sscanf(ptr, "%lu,%lu,%lu,%lu,%lu,%lu", &b[0], &b[1], &b[2], &b[3], &b[4], &b[5]); if (n != 6) return 0; for (n=0; n<6; n++) ipbox.c[n] = (unsigned char) b[n]; sin = (struct sockaddr_in *) sa; sin->sin_family = AF_INET; sin->sin_addr = ipbox.ia[0]; sin->sin_port = ipbox.s[2]; ftp->pasv = 2; return 1;}/* }}} *//* {{{ ftp_get */intftp_get(ftpbuf_t *ftp, php_stream *outstream, const char *path, ftptype_t type, int resumepos){ databuf_t *data = NULL; int lastch; size_t rcvd; char arg[11]; TSRMLS_FETCH(); if (ftp == NULL) return 0; if (!ftp_type(ftp, type)) { goto bail; } if ((data = ftp_getdata(ftp TSRMLS_CC)) == NULL) { goto bail; } ftp->data = data; if (resumepos>0) { if (resumepos > 2147483647) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "PHP cannot handle files greater then 2147483647 bytes.\n"); goto bail; } sprintf(arg, "%u", resumepos); if (!ftp_putcmd(ftp, "REST", arg)) { goto bail; } if (!ftp_getresp(ftp) || (ftp->resp != 350)) { goto bail; } } if (!ftp_putcmd(ftp, "RETR", path)) { goto bail; } if (!ftp_getresp(ftp) || (ftp->resp != 150 && ftp->resp != 125)) { goto bail; } if ((data = data_accept(data, ftp)) == NULL) { goto bail; } lastch = 0; while ((rcvd = my_recv(ftp, data->fd, data->buf, FTP_BUFSIZE))) { if (rcvd == -1) { goto bail; } if (type == FTPTYPE_ASCII) {#ifndef PHP_WIN32 char *s;#endif char *ptr = data->buf; char *e = ptr + rcvd; /* logic depends on the OS EOL * Win32 -> \r\n * Everything Else \n */#ifdef PHP_WIN32 php_stream_write(outstream, ptr, (e - ptr)); ptr = e;#else while (e > ptr && (s = memchr(ptr, '\r', (e - ptr)))) { php_stream_write(outstream, ptr, (s - ptr)); if (*(s + 1) == '\n') { s++; php_stream_putc(outstream, '\n'); } ptr = s + 1; }#endif if (ptr < e) { php_stream_write(outstream, ptr, (e - ptr)); } } else { if (rcvd != php_stream_write(outstream, data->buf, rcvd)) goto bail; } } ftp->data = data = data_close(ftp, data); if (!ftp_getresp(ftp) || (ftp->resp != 226 && ftp->resp != 250)) { goto bail; } return 1;bail: ftp->data = data_close(ftp, data); return 0;}/* }}} *//* {{{ ftp_put */intftp_put(ftpbuf_t *ftp, const char *path, php_stream *instream, ftptype_t type, int startpos){ databuf_t *data = NULL; int size; char *ptr; int ch; char arg[11]; TSRMLS_FETCH(); if (ftp == NULL) return 0; if (!ftp_type(ftp, type)) goto bail; if ((data = ftp_getdata(ftp TSRMLS_CC)) == NULL) goto bail; ftp->data = data; if (startpos>0) { if (startpos > 2147483647) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "PHP cannot handle files with a size greater then 2147483647 bytes.\n"); goto bail; } sprintf(arg, "%u", startpos); if (!ftp_putcmd(ftp, "REST", arg)) { goto bail; } if (!ftp_getresp(ftp) || (ftp->resp != 350)) { goto bail; } } if (!ftp_putcmd(ftp, "STOR", path)) goto bail; if (!ftp_getresp(ftp) || (ftp->resp != 150 && ftp->resp != 125)) goto bail; if ((data = data_accept(data, ftp)) == NULL) goto bail; size = 0; ptr = data->buf; while (!php_stream_eof(instream) && (ch = php_stream_getc(instream))!=EOF) { /* flush if necessary */ if (FTP_BUFSIZE - size < 2) { if (my_send(ftp, data->fd, data->buf, size) != size) goto bail; ptr = data->buf; size = 0; } if (ch == '\n' && type == FTPTYPE_ASCII) { *ptr++ = '\r'; size++; } *ptr++ = ch; size++; } if (size && my_send(ftp, data->fd, data->buf, size) != size) goto bail; ftp->data = data = data_close(ftp, data); if (!ftp_getresp(ftp) || (ftp->resp != 226 && ftp->resp != 250)) goto bail; return 1;bail: ftp->data = data_close(ftp, data); return 0;}/* }}} *//* {{{ ftp_size */intftp_size(ftpbuf_t *ftp, const char *path){ if (ftp == NULL) return -1; if (!ftp_type(ftp, FTPTYPE_IMAGE)) return -1; if (!ftp_putcmd(ftp, "SIZE", path)) return -1; if (!ftp_getresp(ftp) || ftp->resp != 213) return -1; return atoi(ftp->inbuf);}/* }}} *//* {{{ ftp_mdtm */time_tftp_mdtm(ftpbuf_t *ftp, const char *path){ time_t stamp; struct tm *gmt, tmbuf; struct tm tm; char *ptr; int n; if (ftp == NULL) return -1; if (!ftp_putcmd(ftp, "MDTM", path)) return -1; if (!ftp_getresp(ftp) || ftp->resp != 213) return -1; /* parse out the timestamp */ for (ptr = ftp->inbuf; *ptr && !isdigit(*ptr); ptr++); n = sscanf(ptr, "%4u%2u%2u%2u%2u%2u", &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec); if (n != 6) return -1; tm.tm_year -= 1900; tm.tm_mon--; tm.tm_isdst = -1; /* figure out the GMT offset */ stamp = time(NULL); gmt = php_gmtime_r(&stamp, &tmbuf); gmt->tm_isdst = -1; /* apply the GMT offset */ tm.tm_sec += stamp - mktime(gmt); tm.tm_isdst = gmt->tm_isdst; stamp = mktime(&tm); return stamp;}/* }}} *//* {{{ ftp_delete */intftp_delete(ftpbuf_t *ftp, const char *path){ if (ftp == NULL) return 0; if (!ftp_putcmd(ftp, "DELE", path)) return 0; if (!ftp_getresp(ftp) || ftp->resp != 250) return 0; return 1;}/* }}} *//* {{{ ftp_rename */intftp_rename(ftpbuf_t *ftp, const char *src, const char *dest){ if (ftp == NULL) return 0; if (!ftp_putcmd(ftp, "RNFR", src)) return 0; if (!ftp_getresp(ftp) || ftp->resp != 350) return 0; if (!ftp_putcmd(ftp, "RNTO", dest)) return 0; if (!ftp_getresp(ftp) || ftp->resp != 250) return 0; return 1;}/* }}} *//* {{{ ftp_site */intftp_site(ftpbuf_t *ftp, const char *cmd){ if (ftp == NULL) return 0; if (!ftp_putcmd(ftp, "SITE", cmd)) return 0; if (!ftp_getresp(ftp) || ftp->resp < 200 || ftp->resp >= 300) return 0; return 1;}/* }}} *//* static functions *//* {{{ ftp_putcmd */intftp_putcmd(ftpbuf_t *ftp, const char *cmd, const char *args){ int size; char *data; if (strpbrk(cmd, "\r\n")) { return 0; } /* build the output buffer */ if (args && args[0]) { /* "cmd args\r\n\0" */ if (strlen(cmd) + strlen(args) + 4 > FTP_BUFSIZE) return 0; if (strpbrk(args, "\r\n")) { return 0; } size = sprintf(ftp->outbuf, "%s %s\r\n", cmd, args); } else { /* "cmd\r\n\0" */ if (strlen(cmd) + 3 > FTP_BUFSIZE) return 0; size = sprintf(ftp->outbuf, "%s\r\n", cmd); } data = ftp->outbuf; if (my_send(ftp, ftp->fd, data, size) != size) return 0; return 1;}/* }}} *//* {{{ ftp_readline */intftp_readline(ftpbuf_t *ftp){ int size, rcvd; char *data, *eol; /* shift the extra to the front */ size = FTP_BUFSIZE; rcvd = 0; if (ftp->extra) { memmove(ftp->inbuf, ftp->extra, ftp->extralen); rcvd = ftp->extralen; } data = ftp->inbuf; do { size -= rcvd; for (eol = data; rcvd; rcvd--, eol++) { if (*eol == '\r') { *eol = 0; ftp->extra = eol + 1; if (rcvd > 1 && *(eol + 1) == '\n') { ftp->extra++; rcvd--; } if ((ftp->extralen = --rcvd) == 0) ftp->extra = NULL; return 1; } else if (*eol == '\n') { *eol = 0; ftp->extra = eol + 1; if ((ftp->extralen = --rcvd) == 0) ftp->extra = NULL; return 1; } } data = eol; if ((rcvd = my_recv(ftp, ftp->fd, data, size)) < 1) { return 0; } } while (size); return 0;}/* }}} *//* {{{ ftp_getresp */intftp_getresp(ftpbuf_t *ftp){ char *buf; if (ftp == NULL) return 0; buf = ftp->inbuf; ftp->resp = 0; while (1) { if (!ftp_readline(ftp)) { return 0; } /* Break out when the end-tag is found */ if (isdigit(ftp->inbuf[0]) && isdigit(ftp->inbuf[1]) && isdigit(ftp->inbuf[2]) && ftp->inbuf[3] == ' ') { break; } } /* translate the tag */ if (!isdigit(ftp->inbuf[0]) || !isdigit(ftp->inbuf[1]) || !isdigit(ftp->inbuf[2])) { return 0; } ftp->resp = 100 * (ftp->inbuf[0] - '0') + 10 * (ftp->inbuf[1] - '0') + (ftp->inbuf[2] - '0'); memmove(ftp->inbuf, ftp->inbuf + 4, FTP_BUFSIZE - 4); if (ftp->extra) ftp->extra -= 4; return 1;}/* }}} *//* {{{ my_send */intmy_send(ftpbuf_t *ftp, int s, void *buf, size_t len){ fd_set write_set; struct timeval tv; int n, size, sent; size = len; while (size) { tv.tv_sec = ftp->timeout_sec; tv.tv_usec = 0; FD_ZERO(&write_set); FD_SET(s, &write_set); n = select(s + 1, NULL, &write_set, NULL, &tv); if (n < 1) {#if !defined(PHP_WIN32) && !(defined(NETWARE) && defined(USE_WINSOCK)) if (n == 0) errno = ETIMEDOUT;#endif return -1; }#ifdef HAVE_OPENSSL_EXT if (ftp->use_ssl && ftp->fd == s && ftp->ssl_active) { sent = SSL_write(ftp->ssl_handle, buf, size); } else if (ftp->use_ssl && ftp->fd != s && ftp->use_ssl_for_data && ftp->data->ssl_active) { sent = SSL_write(ftp->data->ssl_handle, buf, size); } else#endif sent = send(s, buf, size, 0); if (sent == -1) return -1; buf = (char*) buf + sent; size -= sent; } return len;}/* }}} *//* {{{ my_recv */intmy_recv(ftpbuf_t *ftp, int s, void *buf, size_t len){ fd_set read_set; struct timeval tv; int n, nr_bytes; tv.tv_sec = ftp->timeout_sec; tv.tv_usec = 0; FD_ZERO(&read_set); FD_SET(s, &read_set); n = select(s + 1, &read_set, NULL, NULL, &tv); if (n < 1) {#if !defined(PHP_WIN32) && !(defined(NETWARE) && defined(USE_WINSOCK)) if (n == 0) errno = ETIMEDOUT;#endif return -1; }#ifdef HAVE_OPENSSL_EXT if (ftp->use_ssl && ftp->fd == s && ftp->ssl_active) { nr_bytes = SSL_read(ftp->ssl_handle, buf, len); } else if (ftp->use_ssl && ftp->fd != s && ftp->use_ssl_for_data && ftp->data->ssl_active) { nr_bytes = SSL_read(ftp->data->ssl_handle, buf, len); } else#endif nr_bytes = recv(s, buf, len, 0); return (nr_bytes);}/* }}} *//* {{{ data_available */intdata_available(ftpbuf_t *ftp, int s){ fd_set read_set; struct timeval tv; int n; tv.tv_sec = 0; tv.tv_usec = 1; FD_ZERO(&read_set); FD_SET(s, &read_set); n = select(s + 1, &read_set, NULL, NULL, &tv); if (n < 1) {#if !defined(PHP_WIN32) && !(defined(NETWARE) && defined(USE_WINSOCK)) if (n == 0) errno = ETIMEDOUT;#endif return 0; } return 1;}/* }}} *//* {{{ data_writeable */intdata_writeable(ftpbuf_t *ftp, int s){ fd_set write_set; struct timeval tv;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -