| 1271 | */ |
| 1272 | |
| 1273 | SOCKET |
| 1274 | xmlNanoFTPGetConnection(void *ctx) { |
| 1275 | xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx; |
| 1276 | char buf[200], *cur; |
| 1277 | int len, i; |
| 1278 | int res; |
| 1279 | unsigned char ad[6], *adp, *portp; |
| 1280 | unsigned int temp[6]; |
| 1281 | #ifdef SUPPORT_IP6 |
| 1282 | struct sockaddr_storage dataAddr; |
| 1283 | #else |
| 1284 | struct sockaddr_in dataAddr; |
| 1285 | #endif |
| 1286 | XML_SOCKLEN_T dataAddrLen; |
| 1287 | |
| 1288 | if (ctxt == NULL) return INVALID_SOCKET; |
| 1289 | |
| 1290 | memset (&dataAddr, 0, sizeof(dataAddr)); |
| 1291 | #ifdef SUPPORT_IP6 |
| 1292 | if ((ctxt->ftpAddr).ss_family == AF_INET6) { |
| 1293 | ctxt->dataFd = socket (AF_INET6, SOCK_STREAM, IPPROTO_TCP); |
| 1294 | ((struct sockaddr_in6 *)&dataAddr)->sin6_family = AF_INET6; |
| 1295 | dataAddrLen = sizeof(struct sockaddr_in6); |
| 1296 | } else |
| 1297 | #endif |
| 1298 | { |
| 1299 | ctxt->dataFd = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); |
| 1300 | ((struct sockaddr_in *)&dataAddr)->sin_family = AF_INET; |
| 1301 | dataAddrLen = sizeof (struct sockaddr_in); |
| 1302 | } |
| 1303 | |
| 1304 | if (ctxt->dataFd == INVALID_SOCKET) { |
| 1305 | __xmlIOErr(XML_FROM_FTP, 0, "socket failed"); |
| 1306 | return INVALID_SOCKET; |
| 1307 | } |
| 1308 | |
| 1309 | if (ctxt->passive) { |
| 1310 | #ifdef SUPPORT_IP6 |
| 1311 | if ((ctxt->ftpAddr).ss_family == AF_INET6) |
| 1312 | snprintf (buf, sizeof(buf), "EPSV\r\n"); |
| 1313 | else |
| 1314 | #endif |
| 1315 | snprintf (buf, sizeof(buf), "PASV\r\n"); |
| 1316 | len = strlen (buf); |
| 1317 | res = send(ctxt->controlFd, SEND_ARG2_CAST buf, len, 0); |
| 1318 | if (res < 0) { |
| 1319 | __xmlIOErr(XML_FROM_FTP, 0, "send failed"); |
| 1320 | closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET; |
| 1321 | return INVALID_SOCKET; |
| 1322 | } |
| 1323 | res = xmlNanoFTPReadResponse(ctx); |
| 1324 | if (res != 2) { |
| 1325 | if (res == 5) { |
| 1326 | closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET; |
| 1327 | return INVALID_SOCKET; |
| 1328 | } else { |
| 1329 | /* |
| 1330 | * retry with an active connection |
no test coverage detected