int getFileFromNfs(char * url, char * dest, struct loaderData_s * loaderData) { char * host = NULL, *path = NULL, * file = NULL, * opts = NULL; char * chk = NULL, *ip = NULL; int failed = 0; iface_t iface; if (kickstartNetworkUp(loaderData, &iface)) { logMessage(ERROR, "unable to bring up network"); return 1; } /* if they just did 'linux ks', they want us to figure it out from * the dhcp/bootp information */ /* XXX: fixme NetworkManager integration */ /* if (url == NULL) { char ret[47]; ip_addr_t *tip; if (!(netCfg.dev.set & PUMP_INTFINFO_HAS_NEXTSERVER)) { logMessage(ERROR, "no bootserver was found"); return 1; } tip = &(netCfg.dev.nextServer); if (!(netCfg.dev.set & PUMP_INTFINFO_HAS_BOOTFILE)) { inet_ntop(tip->sa_family, IP_ADDR(tip), ret, IP_STRLEN(tip)); if (asprintf(&url, "%s:%s", ret, "/kickstart/") == -1) { logMessage(CRITICAL, "%s: %d: %m", __func__, __LINE__); abort(); } logMessage(ERROR, "bootp: no bootfile received"); } else { inet_ntop(tip->sa_family, IP_ADDR(tip), ret, IP_STRLEN(tip)); if (asprintf(&url, "%s:%s", ret, netCfg.dev.bootFile) == -1) { logMessage(CRITICAL, "%s: %d: %m", __func__, __LINE__); abort(); } logMessage(INFO, "bootp: bootfile is %s", netCfg.dev.bootFile); } } */ /* get the IP of the target system */ if ((ip = iface_ip2str(loaderData->netDev, AF_INET)) == NULL) { logMessage(ERROR, "nl_ip2str returned NULL"); return 1; } logMessage(INFO, "url is %s", url); getHostandPath(url, &host, &path, ip); opts = strchr(host, ':'); if (opts && (strlen(opts) > 1)) { char * c = opts; opts = host; host = c + 1; *c = '\0'; } else { opts = NULL; } /* nfs has to be a little bit different... split off the last part as * the file and then concatenate host + dir path */ file = strrchr(path, '/'); if (!file) { file = path; } else { *file++ ='\0'; chk = host + strlen(host)-1; if (*chk == '/' || *path == '/') { if (asprintf(&host, "%s%s", host, path) == -1) { logMessage(CRITICAL, "%s: %d: %m", __func__, __LINE__); abort(); } } else { if (asprintf(&host, "%s/%s", host, path) == -1) { logMessage(CRITICAL, "%s: %d: %m", __func__, __LINE__); abort(); } } } logMessage(INFO, "file location: nfs:%s/%s", host, file); if (!doPwMount(host, "/tmp/mnt", "nfs", opts, NULL)) { char * buf; if (asprintf(&buf, "/tmp/mnt/%s", file) == -1) { logMessage(CRITICAL, "%s: %d: %m", __func__, __LINE__); abort(); } if (copyFile(buf, dest)) { logMessage(ERROR, "failed to copy file to %s", dest); failed = 1; } free(buf); } else { logMessage(ERROR, "failed to mount nfs source"); failed = 1; } free(host); free(path); if (ip) free(ip); umount("/tmp/mnt"); unlink("/tmp/mnt"); return failed; }
void getKickstartFile(struct loaderData_s *loaderData) { char *c; int rc = 1; /* Chop off the parameter name, if given. */ if (!strncmp(loaderData->ksFile, "ks=", 3)) c = loaderData->ksFile+3; else c = loaderData->ksFile; while (rc != 0) { if (!strncmp(c, "ks", 2)) { #ifdef STACKI /* * make the default kickstart method the URL method */ rc = kickstartFromUrl("", loaderData); if (rc) { return; } #else rc = kickstartFromNfs(NULL, loaderData); #endif loaderData->ksFile = strdup("/tmp/ks.cfg"); } else if (!strncmp(c, "http", 4) || !strncmp(c, "ftp://", 6)) { rc = kickstartFromUrl(c, loaderData); loaderData->ksFile = strdup("/tmp/ks.cfg"); } else if (!strncmp(c, "nfs:", 4)) { rc = kickstartFromNfs(c+4, loaderData); loaderData->ksFile = strdup("/tmp/ks.cfg"); } else if (!strncmp(c, "floppy", 6)) { rc = kickstartFromRemovable(c); loaderData->ksFile = strdup("/tmp/ks.cfg"); } else if (!strncmp(c, "hd:", 3)) { rc = kickstartFromHD(c); loaderData->ksFile = strdup("/tmp/ks.cfg"); #ifdef STACKI { /* * bring the network up, even if it a hard disk based install */ iface_t iface; iface_init_iface_t(&iface); kickstartNetworkUp(loaderData, &iface); } #endif } else if (!strncmp(c, "bd:", 3)) { rc = kickstartFromBD(c); loaderData->ksFile = strdup("/tmp/ks.cfg"); } else if (!strncmp(c, "cdrom", 5)) { rc = kickstartFromCD(c); loaderData->ksFile = strdup("/tmp/ks.cfg"); #ifdef STACKI { /* * bring the network up, even if it a CD-based install */ iface_t iface; iface_init_iface_t(&iface); kickstartNetworkUp(loaderData, &iface); } #endif } else if (!strncmp(c, "file:", 5)) { loaderData->ksFile = c+5; break; } if (rc != 0) { char *newLocation; if (!strcmp(c, "ks")) newLocation = newKickstartLocation(""); else newLocation = newKickstartLocation(c); if (loaderData->ksFile != NULL) free(loaderData->ksFile); if (newLocation != NULL) { loaderData->ksFile = strdup(newLocation); free(newLocation); return getKickstartFile(loaderData); } else return; } } #ifdef STACKI /* * if we get a kickstart file, try to write the '/tmp/interfaces' file */ writeInterfacesFile(loaderData); #endif flags |= LOADER_FLAGS_KICKSTART; return; }
int getFileFromNfs(char * url, char * dest, struct loaderData_s * loaderData) { char ret[47]; char * host = NULL, *path = NULL, * file = NULL, * opts = NULL; int failed = 0; struct networkDeviceConfig netCfg; ip_addr_t *tip, *u; if (kickstartNetworkUp(loaderData, &netCfg)) { logMessage(ERROR, "unable to bring up network"); return 1; } /* if they just did 'linux ks', they want us to figure it out from * the dhcp/bootp information */ if (url == NULL) { if (!(netCfg.dev.set & PUMP_INTFINFO_HAS_NEXTSERVER)) { logMessage(ERROR, "no bootserver was found"); return 1; } tip = &(netCfg.dev.nextServer); if (!(netCfg.dev.set & PUMP_INTFINFO_HAS_BOOTFILE)) { inet_ntop(tip->sa_family, IP_ADDR(tip), ret, IP_STRLEN(tip)); url = sdupprintf("%s:%s", ret, "/kickstart/"); logMessage(ERROR, "bootp: no bootfile received"); } else { inet_ntop(tip->sa_family, IP_ADDR(tip), ret, IP_STRLEN(tip)); url = sdupprintf("%s:%s", ret, netCfg.dev.bootFile); logMessage(INFO, "bootp: bootfile is %s", netCfg.dev.bootFile); } } /* get the IP of the target system */ if (FL_HAVE_CMSCONF(flags)) { if (loaderData->ip == NULL) { logMessage(ERROR, "getFileFromNfs: no client IP information"); return 1; } else { sprintf(ret, "%s", loaderData->ip); } } else { tip = &(netCfg.dev.ipv4); u = &(netCfg.dev.ip); if ((inet_ntop(tip->sa_family, IP_ADDR(tip), ret, IP_STRLEN(tip)) == NULL) && (inet_ntop(u->sa_family, IP_ADDR(u), ret, IP_STRLEN(u)) == NULL)) { logMessage(ERROR, "getFileFromNfs: no client IP information"); return 1; } } logMessage(INFO, "url is %s", url); getHostandPath(url, &host, &path, ret); opts = strchr(host, ':'); if (opts && (strlen(opts) > 1)) { char * c = opts; opts = host; host = c + 1; *c = '\0'; } else { opts = NULL; } /* nfs has to be a little bit different... split off the last part as * the file and then concatenate host + dir path */ file = strrchr(path, '/'); if (!file) { file = path; } else { *file++ ='\0'; host = sdupprintf("%s/%s", host, path); } logMessage(INFO, "file location: nfs://%s/%s", host, file); if (!doPwMount(host, "/tmp/mnt", "nfs", IMOUNT_RDONLY, opts)) { char * buf; buf = alloca(strlen(file) + 10); sprintf(buf, "/tmp/mnt/%s", file); if (copyFile(buf, dest)) { logMessage(ERROR, "failed to copy file to %s", dest); failed = 1; } } else { logMessage(ERROR, "failed to mount nfs source"); failed = 1; } umount("/tmp/mnt"); unlink("/tmp/mnt"); return failed; }
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; }