static int getHostAddress(const char * host, void * address, int family) { char *hostname, *port; splitHostname((char *) host, &hostname, &port); if (family == AF_INET) { if (isdigit(host[0])) { if (inet_pton(AF_INET, hostname, (struct in_addr *)address) >= 1) { return 0; } else { return FTPERR_BAD_HOST_ADDR; } } else { if (mygethostbyname(hostname, (struct in_addr *)address, AF_INET)) { errno = h_errno; return FTPERR_BAD_HOSTNAME; } else { return 0; } } } else if (family == AF_INET6) { if (strchr(hostname, ':')) { if (inet_pton(AF_INET6, hostname, (struct in_addr6 *)address) >= 1) { return 0; } else return FTPERR_BAD_HOST_ADDR; } else { /* FIXME: implement me */ logMessage(ERROR, "we don't have reverse DNS for IPv6 yet"); return FTPERR_BAD_HOSTNAME; } } else { return FTPERR_UNSUPPORTED_FAMILY; } }
char * addrToIp(char * hostname) { struct in_addr ad; struct in6_addr ad6; char *ret; if ((ret = malloc(48)) == NULL) return hostname; if (inet_ntop(AF_INET, &ad, ret, INET_ADDRSTRLEN) != NULL) return ret; else if (inet_ntop(AF_INET6, &ad6, ret, INET6_ADDRSTRLEN) != NULL) return ret; else if (mygethostbyname(hostname, &ad, AF_INET) == 0) return hostname; else if (mygethostbyname(hostname, &ad6, AF_INET6) == 0) return hostname; else return NULL; }
static int get_host_address(const char * host, struct in_addr * address) { if (isdigit(host[0])) { if (!inet_aton(host, address)) { return FTPERR_BAD_HOST_ADDR; } } else { if (mygethostbyname(host, address)) return FTPERR_BAD_HOSTNAME; } return 0; }
/* set to NULL if not needed */ int urlinstStartTransfer(struct iurlinfo * ui, char * filename, char *extraHeaders) { char * buf; int fd, port; int family = -1; char * finalPrefix; struct in_addr addr; struct in6_addr addr6; char *hostname, *portstr; if (!strcmp(ui->prefix, "/")) finalPrefix = ""; else finalPrefix = ui->prefix; buf = alloca(strlen(finalPrefix) + strlen(filename) + 20); if (*filename == '/') sprintf(buf, "%s%s", finalPrefix, filename); else sprintf(buf, "%s/%s", finalPrefix, filename); logMessage(INFO, "transferring %s://%s/%s to a fd", ui->protocol == URL_METHOD_FTP ? "ftp" : "http", ui->address, buf); splitHostname(ui->address, &hostname, &portstr); if (portstr == NULL) port = -1; else port = atoi(portstr); if (inet_pton(AF_INET, hostname, &addr) >= 1) family = AF_INET; else if (inet_pton(AF_INET6, hostname, &addr6) >= 1) family = AF_INET6; else { if (mygethostbyname(hostname, &addr, AF_INET) == 0) { family = AF_INET; } else if (mygethostbyname(hostname, &addr6, AF_INET6) == 0) { family = AF_INET6; } else { logMessage(ERROR, "cannot determine address family of %s", hostname); } } if (ui->protocol == URL_METHOD_FTP) { ui->ftpPort = ftpOpen(hostname, family, ui->login ? ui->login : "******", ui->password ? ui->password : "******", NULL, port); if (ui->ftpPort < 0) return -2; fd = ftpGetFileDesc(ui->ftpPort, addr6, family, buf); if (fd < 0) { close(ui->ftpPort); return -1; } } else { #ifdef ROCKS { /* * try harder to start HTTP transfer */ int tries = 1; int rc; logMessage(INFO, "ROCKS:urlinstStartTransfer:http://%s/%s\n" "Headers:%s\n", ui->address, filename, extraHeaders); fd = -1; while ((fd < 0) && (tries < 10)) { fd = httpGetFileDesc(ui->address, -1, buf, extraHeaders); if (fd == FTPERR_FAILED_DATA_CONNECT) { /* Server busy, backoff */ sleep(60); tries = 1; continue; } logMessage(INFO, "ROCKS:urlinstStartTransfer:attempt (%d)", tries); sleep(1); ++tries; } if (fd < 0) { logMessage(ERROR, "ROCKS:urlinstStartTransfer:Failed"); rc = newtWinChoice(_("GET File Error"), _("Retry"), _("Cancel"), _("Could not get file:\n\nhttp://%s/%s\n\n%s"), ui->address, filename, ftpStrerror(fd, URL_METHOD_HTTP)); if (rc == 1) return urlinstStartTransfer(ui, filename, extraHeaders); else return -1; } } #else fd = httpGetFileDesc(hostname, port, buf, extraHeaders); if (fd < 0) return -1; #endif /* ROCKS */ } if (!FL_CMDLINE(flags)) winStatus(70, 3, _("Retrieving"), "%s %s...", _("Retrieving"), filename); return fd; }
int main(int argc, char **argv) { int sock, ch, rc, retval = EXIT_FAILURE; int port = SERVERPORT; char *server = BOSSNODE; struct sockaddr_in sin; whoami_t whoami; while ((ch = getopt(argc, argv, "ds:p:")) != -1) switch(ch) { case 's': server = optarg; break; case 'p': port = atoi(optarg); break; case 'd': debug++; break; case 'h': case '?': default: usage(); } argc -= optind; argv += optind; if (argc != 1) usage(); if (strlen(argv[0]) >= sizeof(whoami.name)) fprintf(stderr, "Name too long: %s\n", argv[0]); if (getuid() != 0) fprintf(stderr, "Must be run as root\n"); memset(&whoami, 0, sizeof(whoami)); strcpy(whoami.name, argv[0]); whoami.portnum = -1; if (!mygethostbyname(&sin, server, port)) fprintf(stderr, "Bad server name: %s\n", server); if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) perror("socket"); else if (bindresvport(sock, NULL) < 0) perror("bindresvport"); else if (connect(sock, (struct sockaddr *)&sin, sizeof(sin)) < 0) perror("connect"); else if (write(sock, &whoami, sizeof(whoami)) != sizeof(whoami)) perror("write"); else if ((rc = read(sock, &port, sizeof(port))) != sizeof(port)) perror("read"); else { printf("%d\n", port); retval = EXIT_SUCCESS; } close(sock); return retval; }