Exemplo n.º 1
0
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;
}
Exemplo n.º 2
0
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;
}