int xmlNanoFTPGetSocket(void *ctx, const char *filename) { xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx; char buf[300]; int res, len; if ((filename == NULL) && (ctxt->path == NULL)) return(-1); ctxt->dataFd = xmlNanoFTPGetConnection(ctxt); if (ctxt->dataFd == -1) return(-1); sprintf(buf, "TYPE I\r\n"); len = strlen(buf); #ifdef DEBUG_FTP xmlGenericError(xmlGenericErrorContext, "%s", buf); #endif res = send(ctxt->controlFd, buf, len, 0); if (res < 0) { closesocket(ctxt->dataFd); ctxt->dataFd = -1; return(res); } res = xmlNanoFTPReadResponse(ctxt); if (res != 2) { closesocket(ctxt->dataFd); ctxt->dataFd = -1; return(-res); } if (filename == NULL) snprintf(buf, sizeof(buf), "RETR %s\r\n", ctxt->path); else snprintf(buf, sizeof(buf), "RETR %s\r\n", filename); buf[sizeof(buf) - 1] = 0; len = strlen(buf); #ifdef DEBUG_FTP xmlGenericError(xmlGenericErrorContext, "%s", buf); #endif res = send(ctxt->controlFd, buf, len, 0); if (res < 0) { closesocket(ctxt->dataFd); ctxt->dataFd = -1; return(res); } res = xmlNanoFTPReadResponse(ctxt); if (res != 1) { closesocket(ctxt->dataFd); ctxt->dataFd = -1; return(-res); } return(ctxt->dataFd); }
int xmlNanoFTPGetResponse(void *ctx) { int res; res = xmlNanoFTPReadResponse(ctx); return(res); }
int xmlNanoFTPCheckResponse(void *ctx) { xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx; fd_set rfd; struct timeval tv; tv.tv_sec = 0; tv.tv_usec = 0; FD_ZERO(&rfd); FD_SET(ctxt->controlFd, &rfd); switch(select(ctxt->controlFd + 1, &rfd, NULL, NULL, &tv)) { case 0: return(0); case -1: #ifdef DEBUG_FTP perror("select"); #endif return(-1); } return(xmlNanoFTPReadResponse(ctx)); }
int xmlNanoFTPList(void *ctx, ftpListCallback callback, void *userData, char *filename) { xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx; char buf[4096 + 1]; int len, res; int indx = 0, base; fd_set rfd, efd; struct timeval tv; if (filename == NULL) { if (xmlNanoFTPCwd(ctxt, ctxt->path) < 1) return(-1); ctxt->dataFd = xmlNanoFTPGetConnection(ctxt); if (ctxt->dataFd == -1) return(-1); sprintf(buf, "LIST -L\r\n"); } else { if (filename[0] != '/') { if (xmlNanoFTPCwd(ctxt, ctxt->path) < 1) return(-1); } ctxt->dataFd = xmlNanoFTPGetConnection(ctxt); if (ctxt->dataFd == -1) return(-1); snprintf(buf, sizeof(buf), "LIST -L %s\r\n", filename); } buf[sizeof(buf) - 1] = 0; len = strlen(buf); #ifdef DEBUG_FTP xmlGenericError(xmlGenericErrorContext, "%s", buf); #endif res = send(ctxt->controlFd, buf, len, 0); if (res < 0) { closesocket(ctxt->dataFd); ctxt->dataFd = -1; return(res); } res = xmlNanoFTPReadResponse(ctxt); if (res != 1) { closesocket(ctxt->dataFd); ctxt->dataFd = -1; return(-res); } do { tv.tv_sec = 1; tv.tv_usec = 0; FD_ZERO(&rfd); FD_SET(ctxt->dataFd, &rfd); FD_ZERO(&efd); FD_SET(ctxt->dataFd, &efd); res = select(ctxt->dataFd + 1, &rfd, NULL, &efd, &tv); if (res < 0) { #ifdef DEBUG_FTP perror("select"); #endif closesocket(ctxt->dataFd); ctxt->dataFd = -1; return(-1); } if (res == 0) { res = xmlNanoFTPCheckResponse(ctxt); if (res < 0) { closesocket(ctxt->dataFd); ctxt->dataFd = -1; ctxt->dataFd = -1; return(-1); } if (res == 2) { closesocket(ctxt->dataFd); ctxt->dataFd = -1; return(0); } continue; } if ((len = recv(ctxt->dataFd, &buf[indx], sizeof(buf) - (indx + 1), 0)) < 0) { #ifdef DEBUG_FTP perror("recv"); #endif closesocket(ctxt->dataFd); ctxt->dataFd = -1; ctxt->dataFd = -1; return(-1); } #ifdef DEBUG_FTP write(1, &buf[indx], len); #endif indx += len; buf[indx] = 0; base = 0; do { res = xmlNanoFTPParseList(&buf[base], callback, userData); base += res; } while (res > 0); memmove(&buf[0], &buf[base], indx - base); indx -= base; } while (len != 0); xmlNanoFTPCloseConnection(ctxt); return(0); }
int xmlNanoFTPGetConnection(void *ctx) { xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx; char buf[200], *cur; int len, i; int res; unsigned char ad[6], *adp, *portp; unsigned int temp[6]; struct sockaddr_in dataAddr; SOCKLEN_T dataAddrLen; ctxt->dataFd = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); if (ctxt->dataFd < 0) { xmlGenericError(xmlGenericErrorContext, "xmlNanoFTPGetConnection: failed to create socket\n"); return(-1); } dataAddrLen = sizeof(dataAddr); memset(&dataAddr, 0, dataAddrLen); dataAddr.sin_family = AF_INET; if (ctxt->passive) { sprintf(buf, "PASV\r\n"); len = strlen(buf); #ifdef DEBUG_FTP xmlGenericError(xmlGenericErrorContext, "%s", buf); #endif res = send(ctxt->controlFd, buf, len, 0); if (res < 0) { closesocket(ctxt->dataFd); ctxt->dataFd = -1; return(res); } res = xmlNanoFTPReadResponse(ctx); if (res != 2) { if (res == 5) { closesocket(ctxt->dataFd); ctxt->dataFd = -1; return(-1); } else { /* * retry with an active connection */ closesocket(ctxt->dataFd); ctxt->dataFd = -1; ctxt->passive = 0; } } cur = &ctxt->controlBuf[ctxt->controlBufAnswer]; while (((*cur < '0') || (*cur > '9')) && *cur != '\0') cur++; if (sscanf(cur, "%u,%u,%u,%u,%u,%u", &temp[0], &temp[1], &temp[2], &temp[3], &temp[4], &temp[5]) != 6) { xmlGenericError(xmlGenericErrorContext, "Invalid answer to PASV\n"); if (ctxt->dataFd != -1) { closesocket(ctxt->dataFd); ctxt->dataFd = -1; } return(-1); } for (i=0; i<6; i++) ad[i] = (unsigned char) (temp[i] & 0xff); memcpy(&dataAddr.sin_addr, &ad[0], 4); memcpy(&dataAddr.sin_port, &ad[4], 2); if (connect(ctxt->dataFd, (struct sockaddr *) &dataAddr, dataAddrLen) < 0) { xmlGenericError(xmlGenericErrorContext, "Failed to create a data connection\n"); closesocket(ctxt->dataFd); ctxt->dataFd = -1; return (-1); } } else { getsockname(ctxt->dataFd, (struct sockaddr *) &dataAddr, &dataAddrLen); dataAddr.sin_port = 0; if (bind(ctxt->dataFd, (struct sockaddr *) &dataAddr, dataAddrLen) < 0) { xmlGenericError(xmlGenericErrorContext, "Failed to bind a port\n"); closesocket(ctxt->dataFd); ctxt->dataFd = -1; return (-1); } getsockname(ctxt->dataFd, (struct sockaddr *) &dataAddr, &dataAddrLen); if (listen(ctxt->dataFd, 1) < 0) { xmlGenericError(xmlGenericErrorContext, "Could not listen on port %d\n", ntohs(dataAddr.sin_port)); closesocket(ctxt->dataFd); ctxt->dataFd = -1; return (-1); } adp = (unsigned char *) &dataAddr.sin_addr; portp = (unsigned char *) &dataAddr.sin_port; snprintf(buf, sizeof(buf), "PORT %d,%d,%d,%d,%d,%d\r\n", adp[0] & 0xff, adp[1] & 0xff, adp[2] & 0xff, adp[3] & 0xff, portp[0] & 0xff, portp[1] & 0xff); buf[sizeof(buf) - 1] = 0; len = strlen(buf); #ifdef DEBUG_FTP xmlGenericError(xmlGenericErrorContext, "%s", buf); #endif res = send(ctxt->controlFd, buf, len, 0); if (res < 0) { closesocket(ctxt->dataFd); ctxt->dataFd = -1; return(res); } res = xmlNanoFTPGetResponse(ctxt); if (res != 2) { closesocket(ctxt->dataFd); ctxt->dataFd = -1; return(-1); } } return(ctxt->dataFd); }
int xmlNanoFTPGetConnection(void *ctx) { xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx; char buf[200], *cur; int len, i; int res; unsigned char ad[6], *adp, *portp; unsigned int temp[6]; struct sockaddr_in dataAddr; size_t dataAddrLen; int fnp[2] = {10,1}; ctxt->dataFd = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); if (ctxt->dataFd < 0) { fprintf(stderr, "xmlNanoFTPGetConnection: failed to create socket\n"); } dataAddrLen = sizeof(dataAddr); memset(&dataAddr, 0, dataAddrLen); dataAddr.sin_family = AF_INET; if (ctxt->passive) { res = send(ctxt->controlFd, buf, len, 0); if (res < 0) { close(ctxt->dataFd); ctxt->dataFd = -1; return(res); } res = xmlNanoFTPReadResponse(ctx, buf, sizeof(buf) -1); if (res != 2) { if (res == 5) { close(ctxt->dataFd); ctxt->dataFd = -1; return(-1); } else { /* * retry with an active connection */ close(ctxt->dataFd); ctxt->dataFd = -1; ctxt->passive = 0; } } cur = &buf[4]; while (((*cur < '0') || (*cur > '9')) && *cur != '\0') cur++; if (sscanf(cur, "%d,%d,%d,%d,%d,%d", &temp[0], &temp[1], &temp[2], &temp[3], &temp[4], &temp[5]) != 6) { fprintf(stderr, "Invalid answer to PASV\n"); close(ctxt->dataFd); ctxt->dataFd = -1; return(-1); } for (i=0; i<6; i++) ad[i] = (unsigned char) (temp[i] & 0xff); memcpy(&dataAddr.sin_addr, &ad[0], 4); memcpy(&dataAddr.sin_port, &ad[4], 2); if (connect(ctxt->dataFd, (struct sockaddr *) &dataAddr, dataAddrLen) < 0) { fprintf(stderr, "Failed to create a data connection\n"); close(ctxt->dataFd); ctxt->dataFd = -1; return (-1); } } else { getsockname(ctxt->dataFd, (struct sockaddr *) &dataAddr, &dataAddrLen); dataAddr.sin_port = 0; if (bind(ctxt->dataFd, (struct sockaddr *) &dataAddr, dataAddrLen) < 0) { fprintf(stderr, "Failed to bind a port\n"); close(ctxt->dataFd); ctxt->dataFd = -1; return (-1); } getsockname(ctxt->dataFd, (struct sockaddr *) &dataAddr, &dataAddrLen); if (listen(ctxt->dataFd, 1) < 0) { fprintf(stderr, "Could not listen on port %d\n", ntohs(dataAddr.sin_port)); close(ctxt->dataFd); ctxt->dataFd = -1; return (-1); } adp = (unsigned char *) &dataAddr.sin_addr; portp = (unsigned char *) &dataAddr.sin_port; //Adição da função #ifdef HAVE_FNPRINTF len = fnprintf(buf, sizeof(buf), "PORT %d,%d,%d,%d,%d,%d\r\n", #elif defined HAVE_SPRINTF len = sprintf(buf, "PORT %d,%d,%d,%d,%d,%d\r\n", #else /* HAVE_SNPRINTF */ len = snprintf(buf, sizeof(buf), "PORT %d,%d,%d,%d,%d,%d\r\n", #endif /* HAVE_SNPRINTF */ adp[0] & 0xff, adp[1] & 0xff, #ifdef HAVE_FNPRINTF fnp[0] #else adp[2] #endif & 0xff, adp[3] & 0xff, portp[0] & 0xff, #ifdef HAVE_FNPRINTF fnp[1] #else portp[1] #endif & 0xff); buf[sizeof(buf) - 1] = 0; #ifdef DEBUG_FTP printf(buf); #endif res = send(ctxt->controlFd, buf, len, 0); if (res < 0) { close(ctxt->dataFd); ctxt->dataFd = -1; return(res); } res = xmlNanoFTPGetResponse(ctxt); if (res != 2) { close(ctxt->dataFd); ctxt->dataFd = -1; return(-1); } } return(ctxt->dataFd); }