static int loadSingleUrlImage(struct iurlinfo * ui, char * file, char * dest, char * mntpoint, char * device, int silentErrors) { int fd; int rc = 0; char * newFile = NULL; char filepath[1024]; char *ehdrs = NULL; snprintf(filepath, sizeof(filepath), "%s", file); if (ui->protocol == URL_METHOD_HTTP) { ehdrs = (char *) malloc(24+strlen(VERSION)); sprintf(ehdrs, "User-Agent: anaconda/%s\r\n", VERSION); } fd = urlinstStartTransfer(ui, filepath, ehdrs); if (fd == -2) { if (ehdrs) free (ehdrs); return 2; } if (fd < 0) { /* file not found */ newFile = alloca(strlen(filepath) + 20); sprintf(newFile, "disc1/%s", filepath); fd = urlinstStartTransfer(ui, newFile, ehdrs); if (ehdrs) free (ehdrs); if (fd == -2) return 2; if (fd < 0) { if (!silentErrors) newtWinMessage(_("Error"), _("OK"), _("Unable to retrieve %s://%s/%s/%s."), (ui->protocol == URL_METHOD_FTP ? "ftp" : "http"), ui->address, ui->prefix, filepath); return 2; } } if (dest != NULL) { rc = copyFileAndLoopbackMount(fd, dest, device, mntpoint); } urlinstFinishTransfer(ui, fd); if (newFile) { newFile = malloc(strlen(ui->prefix) + 20); sprintf(newFile, "%s/disc1", ui->prefix); free(ui->prefix); ui->prefix = newFile; } return rc; }
static int loadSingleUrlImage(struct iurlinfo * ui, char *path, char * dest, char * mntpoint, char * device, int silentErrors) { int fd; int rc = 0; char *ehdrs = NULL; long long size; struct progressCBdata *data = NULL; if (ui->protocol == URL_METHOD_HTTP) { char *arch = getProductArch(); char *name = getProductName(); if (asprintf(&ehdrs, "User-Agent: anaconda/%s\r\n" "X-Anaconda-Architecture: %s\r\n" "X-Anaconda-System-Release: %s\r\n", VERSION, arch, name) == -1) { logMessage(CRITICAL, "%s: %d: %m", __func__, __LINE__); abort(); } } fd = urlinstStartTransfer(ui, path, ehdrs, &data, &size); if (fd == -2) { if (ehdrs) free (ehdrs); return 2; } else if (fd < 0) { if (!silentErrors) { newtWinMessage(_("Error"), _("OK"), _("Unable to retrieve %s://%s%s."), (ui->protocol == URL_METHOD_FTP ? "ftp" : "http"), ui->address, path); } if (ehdrs) free (ehdrs); return 2; } if (dest != NULL) { rc = copyFileAndLoopbackMount(fd, dest, device, mntpoint, progressCallback, data, size); } urlinstFinishTransfer(ui, fd, &data); return rc; }
/* 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 getFileFromUrl(char * url, char * dest, struct loaderData_s * loaderData) { int retval = 0; struct iurlinfo ui; enum urlprotocol_t proto = !strncmp(url, "ftp://", 6) ? URL_METHOD_FTP : URL_METHOD_HTTP; char * host = NULL, * file = NULL, * chptr = NULL, *login = NULL, *password = NULL; int fd, rc; iface_t iface; char *ehdrs = NULL, *ip = NULL; long long size; struct progressCBdata *data = NULL; iface_init_iface_t(&iface); if (kickstartNetworkUp(loaderData, &iface)) { logMessage(ERROR, "unable to bring up network"); return 1; } memset(&ui, 0, sizeof(ui)); ui.protocol = proto; getHostPathandLogin((proto == URL_METHOD_FTP ? url + 6 : url + 7), &host, &file, &login, &password, ip); logMessage(INFO, "file location: %s://%s%s", (proto == URL_METHOD_FTP ? "ftp" : "http"), host, file); chptr = strchr(host, '/'); if (chptr == NULL) { ui.address = strdup(host); ui.prefix = strdup("/"); } else { *chptr = '\0'; ui.address = strdup(host); host = chptr; *host = '/'; ui.prefix = strdup(host); } if (password[0] != '\0') ui.password = strdup (password); if (login[0] != '\0') ui.login = strdup (login); if (proto == URL_METHOD_HTTP) { char *arch = getProductArch(); char *name = getProductName(); if (asprintf(&ehdrs, "User-Agent: anaconda/%s\r\n" "X-Anaconda-Architecture: %s\r\n" "X-Anaconda-System-Release: %s\r\n", VERSION, arch, name) == -1) { logMessage(CRITICAL, "%s: %d: %m", __func__, __LINE__); abort(); } } if (proto == URL_METHOD_HTTP && FL_KICKSTART_SEND_MAC(flags)) { /* find all ethernet devices and make a header entry for each one */ int i; char *dev, *mac, *tmpstr; struct device **devices; devices = getDevices(DEVICE_NETWORK); for (i = 0; devices && devices[i]; i++) { dev = devices[i]->device; mac = iface_mac2str(dev); if (mac) { if (asprintf(&tmpstr, "X-RHN-Provisioning-MAC-%d: %s %s\r\n", i, dev, mac) == -1) { logMessage(CRITICAL, "%s: %d: %m", __func__, __LINE__); abort(); } if (!ehdrs) { ehdrs = strdup(tmpstr); } else { ehdrs = (char *) realloc(ehdrs, strlen(ehdrs)+strlen(tmpstr)+1); strcat(ehdrs, tmpstr); } free(mac); free(tmpstr); } } } fd = urlinstStartTransfer(&ui, file, ehdrs, &data, &size); if (fd < 0) { logMessage(ERROR, "failed to retrieve http://%s/%s%s", ui.address, ui.prefix, file); retval = 1; goto err; } rc = copyFileFd(fd, dest, progressCallback, data, size); if (rc) { unlink (dest); logMessage(ERROR, "failed to copy file to %s", dest); retval = 1; goto err; } urlinstFinishTransfer(&ui, fd, &data); err: if (file) free(file); if (ehdrs) free(ehdrs); if (host) free(host); if (login) free(login); if (password) free(password); return retval; }
int getFileFromUrl(char * url, char * dest, struct loaderData_s * loaderData) { char ret[47]; struct iurlinfo ui; enum urlprotocol_t proto = !strncmp(url, "ftp://", 6) ? URL_METHOD_FTP : URL_METHOD_HTTP; char * host = NULL, * file = NULL, * chptr = NULL; char * user = NULL, * password = NULL; int fd, rc; struct networkDeviceConfig netCfg; char * ehdrs = NULL; ip_addr_t *tip; #ifdef ROCKS char *drivername; #endif #ifdef ROCKS /* * Call non-interactive, exhaustive NetworkUp() if we are * a cluster appliance. */ if (!strlen(url)) { logMessage(INFO, "ROCKS:getFileFromUrl:calling rocksNetworkUp"); rc = rocksNetworkUp(loaderData, &netCfg); } else { logMessage(INFO, "ROCKS:getFileFromUrl:calling kickstartNetworkUp"); rc = kickstartNetworkUp(loaderData, &netCfg); } if (rc) return 1; fd = 0; /* * this will be used when starting up mini_httpd() * * Get the nextServer from PUMP if we DHCP, otherwise it * better be on the command line. */ if ( netCfg.dev.set & PUMP_INTFINFO_HAS_BOOTFILE ) { tip = &(netCfg.dev.nextServer); inet_ntop(tip->sa_family, IP_ADDR(tip), ret, IP_STRLEN(tip)); if (strlen(ret) > 0) { loaderData->nextServer = strdup(ret); } else { loaderData->nextServer = NULL; } } /* * If no nextServer use the gateway. */ if ( !loaderData->nextServer ) { loaderData->nextServer = strdup(loaderData->gateway); } logMessage(INFO, "%s: nextServer %s", "ROCKS:getFileFromUrl", loaderData->nextServer); #else if (kickstartNetworkUp(loaderData, &netCfg)) { logMessage(ERROR, "unable to bring up network"); return 1; } #endif /* ROCKS */ memset(&ui, 0, sizeof(ui)); ui.protocol = proto; #ifdef ROCKS { struct sockaddr_in *sin; int string_size; int ncpus; char np[16]; char *arch; char *base; #if defined(__i386__) arch = "i386"; #elif defined(__ia64__) arch = "ia64"; #elif defined(__x86_64__) arch = "x86_64"; #endif if (!strlen(url)) { base = strdup("install/sbin/kickstart.cgi"); host = strdup(loaderData->nextServer); } else { char *p, *q; base = NULL; host = NULL; p = strstr(url, "//"); if (p != NULL) { p += 2; /* * 'base' is the file name */ base = strchr(p, '/'); if (base != NULL) { base += 1; } /* * now get the host portion of the URL */ q = strchr(p, '/'); if (q != NULL) { *q = '\0'; host = strdup(p); } } if (!base || !host) { logMessage(ERROR, "kickstartFromUrl:url (%s) not well formed.\n", url); return(1); } } /* We always retrieve our kickstart file via HTTPS, * however the official install method (for *.img and rpms) * is still HTTP. */ ui.protocol = URL_METHOD_HTTPS; winStatus(40, 3, _("Secure Kickstart"), _("Looking for Kickstart keys...")); getCert(loaderData); newtPopWindow(); /* seed random number generator with our IP: unique for our purposes. * Used for nack backoff. */ tip = &(netCfg.dev.nextServer); sin = (struct sockaddr_in *)IP_ADDR(tip); if (sin == NULL) { srand(time(NULL)); } else { srand((unsigned int)sin->sin_addr.s_addr); } ncpus = num_cpus(); sprintf(np, "%d", ncpus); string_size = strlen(base) + strlen("?arch=") + strlen(arch) + strlen("&np=") + strlen(np) + 1; if ((file = alloca(string_size)) == NULL) { logMessage(ERROR, "kickstartFromUrl:alloca failed\n"); return(1); } memset(file, 0, string_size); sprintf(file, "/%s?arch=%s&np=%s", base, arch, np); } logMessage(INFO, "ks location: https://%s%s", host, file); #else tip = &(netCfg.dev.ip); inet_ntop(tip->sa_family, IP_ADDR(tip), ret, IP_STRLEN(tip)); getHostPathandLogin((proto == URL_METHOD_FTP ? url + 6 : url + 7), &host, &file, &user, &password, ret); logMessage(INFO, "file location: %s://%s/%s", (proto == URL_METHOD_FTP ? "ftp" : "http"), host, file); #endif /* ROCKS */ chptr = strchr(host, '/'); if (chptr == NULL) { ui.address = strdup(host); ui.prefix = strdup("/"); } else { *chptr = '\0'; ui.address = strdup(host); host = chptr; *host = '/'; ui.prefix = strdup(host); } if (user && strlen(user)) { ui.login = strdup(user); if (password && strlen(password)) ui.password = strdup(password); } if (proto == URL_METHOD_HTTP) { ehdrs = (char *) malloc(24+strlen(VERSION)); sprintf(ehdrs, "User-Agent: anaconda/%s\r\n", VERSION); } if (proto == URL_METHOD_HTTP && FL_KICKSTART_SEND_MAC(flags)) { /* find all ethernet devices and make a header entry for each one */ int i; unsigned int hdrlen; char *dev, *mac, tmpstr[128]; struct device ** devices; hdrlen = 0; devices = probeDevices(CLASS_NETWORK, BUS_UNSPEC, PROBE_LOADED); for (i = 0; devices && devices[i]; i++) { dev = devices[i]->device; mac = nl_mac2str(dev); #ifdef ROCKS drivername = get_driver_name(dev); #endif if (mac) { #ifdef ROCKS /* A hint as to our primary interface. */ if (!strcmp(dev, loaderData->netDev)) { snprintf(tmpstr, sizeof(tmpstr), "X-RHN-Provisioning-MAC-%d: %s %s %s ks\r\n", i, dev, mac, drivername); } else { snprintf(tmpstr, sizeof(tmpstr), "X-RHN-Provisioning-MAC-%d: %s %s %s\r\n", i, dev, mac, drivername); } #else snprintf(tmpstr, sizeof(tmpstr), "X-RHN-Provisioning-MAC-%d: %s %s\r\n", i, dev, mac); #endif /* ROCKS */ #ifdef ROCKS free(drivername); #endif free(mac); if (!ehdrs) { hdrlen = 128; ehdrs = (char *) malloc(hdrlen); *ehdrs = '\0'; } else if ( strlen(tmpstr) + strlen(ehdrs) + 2 > hdrlen) { hdrlen += 128; ehdrs = (char *) realloc(ehdrs, hdrlen); } strcat(ehdrs, tmpstr); } } } #ifdef ROCKS { /* Retrieve the kickstart file via HTTPS */ BIO *sbio; sbio = urlinstStartSSLTransfer(&ui, file, ehdrs, 1, flags, loaderData->nextServer); if (!sbio) { logMessage(ERROR, "failed to retrieve https://%s/%s", ui.address, file); return 1; } rc = copyFileSSL(sbio, dest); if (rc) { unlink (dest); logMessage(ERROR, "failed to copy file to %s", dest); return 1; } urlinstFinishSSLTransfer(sbio); if (haveCertificate()) umount("/mnt/rocks-disk"); } #else fd = urlinstStartTransfer(&ui, file, ehdrs); if (fd < 0) { logMessage(ERROR, "failed to retrieve http://%s/%s/%s", ui.address, ui.prefix, file); if (ehdrs) free(ehdrs); return 1; } rc = copyFileFd(fd, dest); if (rc) { unlink (dest); logMessage(ERROR, "failed to copy file to %s", dest); if (ehdrs) free(ehdrs); return 1; } urlinstFinishTransfer(&ui, fd); #endif /* ROCKS */ if (ehdrs) free(ehdrs); return 0; }