If we're saying to use a particular coding style, we should at least try to do something close to it everywhere. --- isys/auditd.c | 142 +- isys/cpio.c | 39 +- isys/cpio.h | 37 +- isys/dasd.c | 245 ++-- isys/devices.c | 352 +++-- isys/devices.h | 22 +- isys/eddsupport.c | 451 +++--- isys/eddsupport.h | 4 +- isys/ethtool.c | 151 +- isys/ethtool.h | 18 +- isys/iface.c | 744 +++++----- isys/iface.h | 113 +- isys/imount.c | 475 +++--- isys/imount.h | 2 +- isys/isofs.c | 55 +- isys/isys.c | 1055 +++++++------ isys/isys.h | 8 +- isys/lang.c | 270 ++-- isys/lang.h | 14 +- isys/linkdetect.c | 203 ++-- isys/minifind.c | 73 +- isys/minifind.h | 14 +- isys/str.c | 91 +- isys/uncpio.c | 1282 ++++++++------- isys/vio.c | 127 +- loader/cdinstall.c | 851 ++++++----- loader/cdinstall.h | 9 +- loader/copy.c | 228 ++-- loader/copy.h | 4 +- loader/devices.h | 120 +- loader/dirbrowser.c | 271 ++-- loader/dirbrowser.h | 4 +- loader/driverdisk.c | 1112 +++++++------- loader/driverdisk.h | 9 +- loader/driverselect.c | 419 +++--- loader/fwloader.c | 1013 ++++++------ loader/getparts.c | 265 ++-- loader/getparts.h | 2 +- loader/hardware.c | 273 ++-- loader/hdinstall.c | 819 +++++----- loader/hdinstall.h | 12 +- loader/ibft.c | 45 +- loader/ibft.h | 17 +- loader/init.c | 1423 +++++++++-------- loader/kbd.c | 207 ++-- loader/kbd.h | 6 +- loader/kickstart.c | 868 ++++++----- loader/kickstart.h | 8 +- loader/lang.c | 631 ++++---- loader/lang.h | 15 +- loader/loader.c | 4072 +++++++++++++++++++++++++----------------------- loader/loader.h | 84 +- loader/loadermisc.c | 201 ++-- loader/loadermisc.h | 8 +- loader/log.c | 177 ++- loader/log.h | 8 +- loader/mediacheck.c | 148 +- loader/method.c | 813 +++++----- loader/method.h | 37 +- loader/mkctype.c | 71 +- loader/moduleinfo.c | 469 +++--- loader/moduleinfo.h | 52 +- loader/modules.c | 677 ++++---- loader/modules.h | 4 +- loader/net.c | 3861 ++++++++++++++++++++++++---------------------- loader/net.h | 43 +- loader/nfsinstall.c | 1043 +++++++------ loader/nfsinstall.h | 20 +- loader/selinux.c | 29 +- loader/shutdown.c | 98 +- loader/telnet.c | 344 +++-- loader/telnet.h | 10 +- loader/telnetd.c | 333 ++-- loader/telnetd.h | 2 +- loader/udelay.h | 203 ++-- loader/undomounts.c | 368 +++-- loader/urlinstall.c | 700 +++++---- loader/urlinstall.h | 12 +- loader/urls.c | 626 ++++---- loader/urls.h | 8 +- loader/windows.c | 134 +- loader/windows.h | 11 +- mini-wm.c | 135 +- utils/geninitrdsz.c | 46 +- utils/mapshdr.c | 58 +- utils/mk-s390-cdboot.c | 546 ++++--- utils/modlist.c | 232 ++-- utils/readmap.c | 152 +- utils/snarffont.c | 113 +- xutils.c | 393 +++--- 90 files changed, 16064 insertions(+), 14895 deletions(-) diff --git a/isys/auditd.c b/isys/auditd.c index f050550..ee90122 100644 --- a/isys/auditd.c +++ b/isys/auditd.c @@ -40,93 +40,95 @@ static int done; static void sig_done(int sig) { - done = 1; + done = 1; } -static void do_auditd(int fd) { - struct audit_reply rep; - sigset_t sigs; - struct sigaction sa; - struct pollfd pds = { - .events = POLLIN, - .revents = 0, - .fd = fd, - }; - - if (audit_set_pid(fd, getpid(), WAIT_YES) < 0) - return; - - if (audit_set_enabled(fd, 1) < 0) - return; - - memset(&sa, '\0', sizeof (sa)); - sa.sa_handler = sig_done; - sigaction(SIGTERM, &sa, NULL); - sigaction(SIGINT, &sa, NULL); - sigaction(SIGHUP, &sa, NULL); - - sigfillset(&sigs); - sigdelset(&sigs, SIGTERM); - sigdelset(&sigs, SIGINT); - sigdelset(&sigs, SIGHUP); - - while (1) { - int retval; - - memset(&rep, 0, sizeof(rep)); - - do { - retval = ppoll(&pds, 1, NULL, &sigs); - } while (retval == -1 && errno == EINTR && !done); - - if (done) - break; - - if (audit_get_reply(fd, &rep, GET_REPLY_NONBLOCKING, 0) > 0) { - /* we don't actually want to do anything here. */ - ; - } - } - return; +static void do_auditd(int fd) +{ + struct audit_reply rep; + sigset_t sigs; + struct sigaction sa; + struct pollfd pds = { + .events = POLLIN, + .revents = 0, + .fd = fd, + }; + + if (audit_set_pid(fd, getpid(), WAIT_YES) < 0) + return; + + if (audit_set_enabled(fd, 1) < 0) + return; + + memset(&sa, '\0', sizeof(sa)); + sa.sa_handler = sig_done; + sigaction(SIGTERM, &sa, NULL); + sigaction(SIGINT, &sa, NULL); + sigaction(SIGHUP, &sa, NULL); + + sigfillset(&sigs); + sigdelset(&sigs, SIGTERM); + sigdelset(&sigs, SIGINT); + sigdelset(&sigs, SIGHUP); + + while (1) { + int retval; + + memset(&rep, 0, sizeof(rep)); + + do { + retval = ppoll(&pds, 1, NULL, &sigs); + } while (retval == -1 && errno == EINTR && !done); + + if (done) + break; + + if (audit_get_reply(fd, &rep, GET_REPLY_NONBLOCKING, 0) > 0) { + /* we don't actually want to do anything here. */ + ; + } + } + return; } #endif /* USESELINUX */ -int audit_daemonize(void) { +int audit_daemonize(void) +{ #ifdef USESELINUX - int fd; -#ifndef STANDALONE - int i; - pid_t child; - - if ((child = fork()) > 0) - return 0; + int fd; +#ifndef STANDALONE + int i; + pid_t child; - for (i = 0; i < getdtablesize(); i++) - close(i); + if ((child = fork()) > 0) + return 0; - signal(SIGTTOU, SIG_IGN); - signal(SIGTTIN, SIG_IGN); - signal(SIGTSTP, SIG_IGN); + for (i = 0; i < getdtablesize(); i++) + close(i); - if ((fd = open("/proc/self/oom_adj", O_RDWR)) >= 0) { - i = write(fd, "-17", 3); - close(fd); - } + signal(SIGTTOU, SIG_IGN); + signal(SIGTTIN, SIG_IGN); + signal(SIGTSTP, SIG_IGN); + if ((fd = open("/proc/self/oom_adj", O_RDWR)) >= 0) { + i = write(fd, "-17", 3); + close(fd); + } #endif /* !defined(STANDALONE) */ - fd = audit_open(); - do_auditd(fd); - audit_close(fd); + fd = audit_open(); + do_auditd(fd); + audit_close(fd); #ifndef STANDALONE - exit(0); + exit(0); #endif /* !defined(STANDALONE) */ #endif /* USESELINUX */ - return 0; + return 0; } #ifdef STANDALONE -int main(void) { - return audit_daemonize(); +int main(void) +{ + return audit_daemonize(); } #endif /* STANDALONE */ diff --git a/isys/cpio.c b/isys/cpio.c index bebc795..acb613f 100644 --- a/isys/cpio.c +++ b/isys/cpio.c @@ -24,25 +24,26 @@ #include "cpio.h" -int installCpioFile(gzFile fd, char * cpioName, char * outName, int inWin) { - struct cpioFileMapping map; - int rc; - const char * failedFile; - - if (outName) { - map.archivePath = cpioName; - map.fsPath = outName; - map.mapFlags = CPIO_MAP_PATH; - } - - rc = myCpioInstallArchive(fd, outName ? &map : NULL, 1, NULL, NULL, - &failedFile); - - if (rc || access(outName, R_OK)) { - return -1; - } - - return 0; +int installCpioFile(gzFile fd, char *cpioName, char *outName, int inWin) +{ + struct cpioFileMapping map; + int rc; + const char *failedFile; + + if (outName) { + map.archivePath = cpioName; + map.fsPath = outName; + map.mapFlags = CPIO_MAP_PATH; + } + + rc = myCpioInstallArchive(fd, outName ? &map : NULL, 1, NULL, NULL, + &failedFile); + + if (rc || access(outName, R_OK)) { + return -1; + } + + return 0; } /* vim:set sw=8 noet */ diff --git a/isys/cpio.h b/isys/cpio.h index 6f76a6d..573f65b 100644 --- a/isys/cpio.h +++ b/isys/cpio.h @@ -50,7 +50,6 @@ #define CPIOERR_HDR_SIZE (21 ) #define CPIOERR_UNKNOWN_FILETYPE (22 ) - /* Don't think this behaves just like standard cpio. It's pretty close, but it has some behaviors which are more to RPM's liking. I tried to document them inline in cpio.c, but I may have missed some. */ @@ -59,26 +58,26 @@ #define CPIO_MAP_MODE (1 << 1) #define CPIO_MAP_UID (1 << 2) #define CPIO_MAP_GID (1 << 3) -#define CPIO_FOLLOW_SYMLINKS (1 << 4) /* only for building */ +#define CPIO_FOLLOW_SYMLINKS (1 << 4) /* only for building */ struct cpioFileMapping { - char * archivePath; - char * fsPath; - mode_t finalMode; - uid_t finalUid; - gid_t finalGid; - int mapFlags; + char *archivePath; + char *fsPath; + mode_t finalMode; + uid_t finalUid; + gid_t finalGid; + int mapFlags; }; /* on cpio building, only "file" is filled in */ struct cpioCallbackInfo { - char * file; - long fileSize; /* total file size */ - long fileComplete; /* amount of file unpacked */ - long bytesProcessed; /* bytes in archive read */ + char *file; + long fileSize; /* total file size */ + long fileComplete; /* amount of file unpacked */ + long bytesProcessed; /* bytes in archive read */ }; -typedef void (*cpioCallback)(struct cpioCallbackInfo * filespec, void * data); +typedef void (*cpioCallback) (struct cpioCallbackInfo * filespec, void *data); /* If no mappings are passed, this installs everything! If one is passed it should be sorted according to cpioFileMapCmp() and only files included @@ -87,17 +86,17 @@ typedef void (*cpioCallback)(struct cpioCallbackInfo * filespec, void * data); directory. The mode mapping is only used for the permission bits, not for the file type. The owner/group mappings are ignored for the nonroot user. If *failedFile is non-NULL on return, it should be free()d. */ -int myCpioInstallArchive(gzFile stream, struct cpioFileMapping * mappings, - int numMappings, cpioCallback cb, void * cbData, - const char ** failedFile); -int myCpioFilterArchive(gzFile inStream, gzFile outStream, char ** pattern); +int myCpioInstallArchive(gzFile stream, struct cpioFileMapping *mappings, + int numMappings, cpioCallback cb, void *cbData, + const char **failedFile); +int myCpioFilterArchive(gzFile inStream, gzFile outStream, char **pattern); /* This is designed to be qsort/bsearch compatible */ -int myCpioFileMapCmp(const void * a, const void * b); +int myCpioFileMapCmp(const void *a, const void *b); const char *myCpioStrerror(int rc); -int installCpioFile(gzFile fd, char * cpioName, char * outName, int inWin); +int installCpioFile(gzFile fd, char *cpioName, char *outName, int inWin); #endif diff --git a/isys/dasd.c b/isys/dasd.c index 3b07f25..17f4783 100644 --- a/isys/dasd.c +++ b/isys/dasd.c @@ -41,139 +41,150 @@ #if defined(__s390__) || defined(__s390x__) /* s390 stuff to detect DASDs */ -static int read_vlabel(dasd_information_t *dasd_info, int fd, int blksize, - volume_label_t *vlabel) { - int rc; - unsigned long vlabel_start = dasd_info->label_block * blksize; +static int read_vlabel(dasd_information_t * dasd_info, int fd, int blksize, + volume_label_t * vlabel) +{ + int rc; + unsigned long vlabel_start = dasd_info->label_block * blksize; - memset(vlabel, 0, sizeof(volume_label_t)); + memset(vlabel, 0, sizeof(volume_label_t)); - if (lseek(fd, vlabel_start, SEEK_SET) < 0) { - return 2; - } + if (lseek(fd, vlabel_start, SEEK_SET) < 0) { + return 2; + } - rc = read(fd, vlabel, sizeof(volume_label_t)); - if (rc != sizeof(volume_label_t)) { - return 1; - } + rc = read(fd, vlabel, sizeof(volume_label_t)); + if (rc != sizeof(volume_label_t)) { + return 1; + } - return 0; + return 0; } #endif -int isUsableDasd(char *device) { +int isUsableDasd(char *device) +{ #if !defined(__s390__) && !defined(__s390x__) - return 0; + return 0; #else - char devname[16]; - char label[5], v4_hex[9]; - char l4ebcdic_hex[] = "d3d5e7f1"; /* LNX1 */ - char cms1_hex[] = "c3d4e2f1"; /* CMS1 */ - int f, ret, blksize; - dasd_information_t dasd_info; - volume_label_t vlabel; - - memset(&dasd_info, 0, sizeof(dasd_info)); - strcpy(devname, "/dev/"); - strcat(devname, device); - - if ((f = open(devname, O_RDONLY)) == -1) - return 0; - - if (ioctl(f, BLKSSZGET, &blksize) != 0) { - close(f); - return 0; - } - - if (ioctl(f, BIODASDINFO, &dasd_info) != 0) { - close(f); - return 0; - } - - ret = read_vlabel(&dasd_info, f, blksize, &vlabel); - close(f); - - if (ret == 2) - return 0; - else if (ret == 1) /* probably unformatted DASD */ - return 1; - - memset(label, 0, 5); - memset(v4_hex, 0, 9); - strncpy(label, vlabel.volkey, 4); - - ret = sprintf(v4_hex, "%02x%02x%02x%02x", label[0], label[1], - label[2], label[3]); - if (ret < 0 || ret < strlen(cms1_hex)) - return 3; - - if (!strncmp(v4_hex, cms1_hex, 9)) - return 0; - - if (!strncmp(v4_hex, l4ebcdic_hex, 9)) - return 2; - - return 1; + char devname[16]; + char label[5], v4_hex[9]; + char l4ebcdic_hex[] = "d3d5e7f1"; /* LNX1 */ + char cms1_hex[] = "c3d4e2f1"; /* CMS1 */ + int f, ret, blksize; + dasd_information_t dasd_info; + volume_label_t vlabel; + + memset(&dasd_info, 0, sizeof(dasd_info)); + strcpy(devname, "/dev/"); + strcat(devname, device); + + if ((f = open(devname, O_RDONLY)) == -1) + return 0; + + if (ioctl(f, BLKSSZGET, &blksize) != 0) { + close(f); + return 0; + } + + if (ioctl(f, BIODASDINFO, &dasd_info) != 0) { + close(f); + return 0; + } + + ret = read_vlabel(&dasd_info, f, blksize, &vlabel); + close(f); + + if (ret == 2) + return 0; + else if (ret == 1) /* probably unformatted DASD */ + return 1; + + memset(label, 0, 5); + memset(v4_hex, 0, 9); + strncpy(label, vlabel.volkey, 4); + + ret = sprintf(v4_hex, "%02x%02x%02x%02x", label[0], label[1], + label[2], label[3]); + if (ret < 0 || ret < strlen(cms1_hex)) + return 3; + + if (!strncmp(v4_hex, cms1_hex, 9)) + return 0; + + if (!strncmp(v4_hex, l4ebcdic_hex, 9)) + return 2; + + return 1; #endif } -int isLdlDasd(char * device) { - return (isUsableDasd(device) == 2); +int isLdlDasd(char *device) +{ + return (isUsableDasd(device) == 2); } -char *getDasdPorts() { +char *getDasdPorts() +{ #if !defined(__s390__) && !defined(__s390x__) - return 0; + return 0; #else - char * line, *ports = NULL; - char devname[7]; - char port[10]; - FILE *fd; - int ret, sz; - - fd = fopen("/proc/dasd/devices", "r"); - if (!fd) - return NULL; - - if ((line = (char *)malloc(100 * sizeof(char))) == NULL) { - fclose(fd); - return NULL; - } - - while (fgets(line, 100, fd) != NULL) { - if ((strstr(line, "unknown") != NULL)) - continue; - - if (strstr(line, "(FBA )") != NULL) - ret = sscanf(line, "%[A-Za-z.0-9](FBA ) at ( %*d: %*d) is %s : %*s", port, devname); - else - ret = sscanf(line, "%[A-Za-z.0-9](ECKD) at ( %*d: %*d) is %s : %*s", port, devname); - - if (ret == 2) { - if (!ports) { - sz = strlen(port) + 1; - if ((ports = (char *) malloc(sz)) == NULL) { - fclose(fd); - return NULL; - } - - ports = strcpy(ports, port); - } else { - sz = strlen(ports) + strlen(port) + 2; - if ((ports = (char *) realloc(ports, sz)) == NULL) { - fclose(fd); - return NULL; - } - - ports = strcat(ports, ","); - ports = strcat(ports, port); - } - } - } - - fclose(fd); - - return ports; + char *line, *ports = NULL; + char devname[7]; + char port[10]; + FILE *fd; + int ret, sz; + + fd = fopen("/proc/dasd/devices", "r"); + if (!fd) + return NULL; + + if ((line = (char *)malloc(100 * sizeof(char))) == NULL) { + fclose(fd); + return NULL; + } + + while (fgets(line, 100, fd) != NULL) { + if ((strstr(line, "unknown") != NULL)) + continue; + + if (strstr(line, "(FBA )") != NULL) + ret = + sscanf(line, + "%[A-Za-z.0-9](FBA ) at ( %*d: %*d) is %s : %*s", + port, devname); + else + ret = + sscanf(line, + "%[A-Za-z.0-9](ECKD) at ( %*d: %*d) is %s : %*s", + port, devname); + + if (ret == 2) { + if (!ports) { + sz = strlen(port) + 1; + if ((ports = (char *)malloc(sz)) == NULL) { + fclose(fd); + return NULL; + } + + ports = strcpy(ports, port); + } else { + sz = strlen(ports) + strlen(port) + 2; + if ((ports = + (char *)realloc(ports, sz)) == NULL) { + fclose(fd); + return NULL; + } + + ports = strcat(ports, ","); + ports = strcat(ports, port); + } + } + } + + fclose(fd); + + return ports; #endif } diff --git a/isys/devices.c b/isys/devices.c index ef4384d..56f562b 100644 --- a/isys/devices.c +++ b/isys/devices.c @@ -34,7 +34,7 @@ #include "devices.h" /* for 'disks', to filter out weird stuff */ -#define MINIMUM_INTERESTING_SIZE 32*1024 /* 32MB */ +#define MINIMUM_INTERESTING_SIZE 32*1024 /* 32MB */ /* from genhd.h, kernel side */ #define GENHD_FL_REMOVABLE 1 @@ -45,175 +45,193 @@ #define GENHD_FL_SUPPRESS_PARTITION_INFO 32 #define GENHD_FL_FAIL 64 - -struct device **getDevices(enum deviceType type) { - struct device **ret = NULL; - struct device *new; - int numdevices = 0; - - if (type & (DEVICE_DISK | DEVICE_CDROM)) { - DIR *dir; - struct dirent *ent; - - dir = opendir("/sys/block"); - - if (!dir) goto storagedone; - - while ((ent = readdir(dir))) { - char path[64]; - char buf[64]; - int fd, caps, devtype; - - snprintf(path, 64, "/sys/block/%s/capability", ent->d_name); - fd = open(path, O_RDONLY); - if (fd == -1) - continue; - if (read(fd, buf, 63) <= 0) { - close(fd); - continue; - } - - close(fd); - errno = 0; - caps = strtol(buf, NULL, 16); - - if ((errno == ERANGE && (caps == LONG_MIN || caps == LONG_MAX)) || - (errno != 0 && caps == 0)) { - return NULL; - } - - if (caps & GENHD_FL_CD) - devtype = DEVICE_CDROM; - else - devtype = DEVICE_DISK; - if (!(devtype & type)) - continue; - - if (devtype == DEVICE_DISK && !(caps & GENHD_FL_REMOVABLE)) { - int size; - - snprintf(path, 64, "/sys/block/%s/size", ent->d_name); - fd = open(path, O_RDONLY); - - if (fd == -1) - continue; - if (read(fd, buf, 63) <= 0) { - close(fd); - continue; - } - - close(fd); - errno = 0; - size = strtol(buf, NULL, 10); - - if ((errno == ERANGE && (size == LONG_MIN || - size == LONG_MAX)) || - (errno != 0 && size == 0)) { - return NULL; - } - - if (size < MINIMUM_INTERESTING_SIZE) - continue; - } - - new = calloc(1, sizeof(struct device)); - new->device = strdup(ent->d_name); - /* FIXME */ - if (asprintf(&new->description, "Storage device %s", - new->device) == -1) { - fprintf(stderr, "%s: %d: %s\n", __func__, __LINE__, - strerror(errno)); - fflush(stderr); - abort(); - } - new->type = devtype; - if (caps & GENHD_FL_REMOVABLE) { - new->priv.removable = 1; - } - ret = realloc(ret, (numdevices+2) * sizeof(struct device)); - ret[numdevices] = new; - ret[numdevices+1] = NULL; - numdevices++; - } - } +struct device **getDevices(enum deviceType type) +{ + struct device **ret = NULL; + struct device *new; + int numdevices = 0; + + if (type & (DEVICE_DISK | DEVICE_CDROM)) { + DIR *dir; + struct dirent *ent; + + dir = opendir("/sys/block"); + + if (!dir) + goto storagedone; + + while ((ent = readdir(dir))) { + char path[64]; + char buf[64]; + int fd, caps, devtype; + + snprintf(path, 64, "/sys/block/%s/capability", + ent->d_name); + fd = open(path, O_RDONLY); + if (fd == -1) + continue; + if (read(fd, buf, 63) <= 0) { + close(fd); + continue; + } + + close(fd); + errno = 0; + caps = strtol(buf, NULL, 16); + + if ((errno == ERANGE + && (caps == LONG_MIN || caps == LONG_MAX)) + || (errno != 0 && caps == 0)) { + return NULL; + } + + if (caps & GENHD_FL_CD) + devtype = DEVICE_CDROM; + else + devtype = DEVICE_DISK; + if (!(devtype & type)) + continue; + + if (devtype == DEVICE_DISK + && !(caps & GENHD_FL_REMOVABLE)) { + int size; + + snprintf(path, 64, "/sys/block/%s/size", + ent->d_name); + fd = open(path, O_RDONLY); + + if (fd == -1) + continue; + if (read(fd, buf, 63) <= 0) { + close(fd); + continue; + } + + close(fd); + errno = 0; + size = strtol(buf, NULL, 10); + + if ((errno == ERANGE && (size == LONG_MIN || + size == LONG_MAX)) || + (errno != 0 && size == 0)) { + return NULL; + } + + if (size < MINIMUM_INTERESTING_SIZE) + continue; + } + + new = calloc(1, sizeof(struct device)); + new->device = strdup(ent->d_name); + /* FIXME */ + if (asprintf(&new->description, "Storage device %s", + new->device) == -1) { + fprintf(stderr, "%s: %d: %s\n", __func__, + __LINE__, strerror(errno)); + fflush(stderr); + abort(); + } + new->type = devtype; + if (caps & GENHD_FL_REMOVABLE) { + new->priv.removable = 1; + } + ret = + realloc(ret, + (numdevices + 2) * sizeof(struct device)); + ret[numdevices] = new; + ret[numdevices + 1] = NULL; + numdevices++; + } + } storagedone: - if (type & DEVICE_NETWORK) { - DIR *dir; - struct dirent *ent; - - dir = opendir("/sys/class/net"); - - if (!dir) goto netdone; - - while ((ent = readdir(dir))) { - char path[64]; - int fd, type; - char buf[64]; - - snprintf(path, 64, "/sys/class/net/%s/type", ent->d_name); - fd = open(path, O_RDONLY); - if (fd == -1) - continue; - if (read(fd, buf, 63) <= 0) { - close(fd); - continue; - } - - close(fd); - errno = 0; - type = strtol(buf, NULL, 10); - - if ((errno == ERANGE && (type == LONG_MIN || type == LONG_MAX)) || - (errno != 0 && type == 0)) { - return NULL; - } - - if (type != 1) - continue; - - new = calloc(1, sizeof(struct device)); - new->device = strdup(ent->d_name); - /* FIXME */ - snprintf(path, 64, "/sys/class/net/%s/address", ent->d_name); - fd = open(path, O_RDONLY); - if (fd != -1) { - memset(buf, '\0', 64); - if (read(fd, buf, 63) > 0) { - int i; - for (i = (strlen(buf)-1); isspace(buf[i]); i--) - buf[i] = '\0'; - new->priv.hwaddr = strdup(buf); - } - } - - if (new->priv.hwaddr) { - if (asprintf(&new->description, "Ethernet device %s - %s", - new->device, new->priv.hwaddr) == -1) { - fprintf(stderr, "%s: %d: %s\n", __func__, __LINE__, - strerror(errno)); - fflush(stderr); - abort(); - } - } else { - if (asprintf(&new->description, "Ethernet device %s", - new->device) == -1) { - fprintf(stderr, "%s: %d: %s\n", __func__, __LINE__, - strerror(errno)); - fflush(stderr); - abort(); - } - } - - ret = realloc(ret, (numdevices+2) * sizeof(struct device)); - ret[numdevices] = new; - ret[numdevices+1] = NULL; - numdevices++; - } - } + if (type & DEVICE_NETWORK) { + DIR *dir; + struct dirent *ent; + + dir = opendir("/sys/class/net"); + + if (!dir) + goto netdone; + + while ((ent = readdir(dir))) { + char path[64]; + int fd, type; + char buf[64]; + + snprintf(path, 64, "/sys/class/net/%s/type", + ent->d_name); + fd = open(path, O_RDONLY); + if (fd == -1) + continue; + if (read(fd, buf, 63) <= 0) { + close(fd); + continue; + } + + close(fd); + errno = 0; + type = strtol(buf, NULL, 10); + + if ((errno == ERANGE + && (type == LONG_MIN || type == LONG_MAX)) + || (errno != 0 && type == 0)) { + return NULL; + } + + if (type != 1) + continue; + + new = calloc(1, sizeof(struct device)); + new->device = strdup(ent->d_name); + /* FIXME */ + snprintf(path, 64, "/sys/class/net/%s/address", + ent->d_name); + fd = open(path, O_RDONLY); + if (fd != -1) { + memset(buf, '\0', 64); + if (read(fd, buf, 63) > 0) { + int i; + for (i = (strlen(buf) - 1); + isspace(buf[i]); i--) + buf[i] = '\0'; + new->priv.hwaddr = strdup(buf); + } + } + + if (new->priv.hwaddr) { + if (asprintf + (&new->description, + "Ethernet device %s - %s", new->device, + new->priv.hwaddr) == -1) { + fprintf(stderr, "%s: %d: %s\n", + __func__, __LINE__, + strerror(errno)); + fflush(stderr); + abort(); + } + } else { + if (asprintf + (&new->description, "Ethernet device %s", + new->device) == -1) { + fprintf(stderr, "%s: %d: %s\n", + __func__, __LINE__, + strerror(errno)); + fflush(stderr); + abort(); + } + } + + ret = + realloc(ret, + (numdevices + 2) * sizeof(struct device)); + ret[numdevices] = new; + ret[numdevices + 1] = NULL; + numdevices++; + } + } netdone: - return ret; + return ret; } - /* vim:set sw=8 noet */ diff --git a/isys/devices.h b/isys/devices.h index 9f636ad..7262ce1 100644 --- a/isys/devices.h +++ b/isys/devices.h @@ -21,20 +21,20 @@ #define DEVICES_H enum deviceType { - DEVICE_ANY = ~0, - DEVICE_NETWORK = (1 << 0), - DEVICE_DISK = (1 << 1), - DEVICE_CDROM = (1 << 2) + DEVICE_ANY = ~0, + DEVICE_NETWORK = (1 << 0), + DEVICE_DISK = (1 << 1), + DEVICE_CDROM = (1 << 2) }; struct device { - char *device; - char *description; - enum deviceType type; - union { - char *hwaddr; - int removable; - } priv; + char *device; + char *description; + enum deviceType type; + union { + char *hwaddr; + int removable; + } priv; }; struct device **getDevices(enum deviceType type); diff --git a/isys/eddsupport.c b/isys/eddsupport.c index c2b7a3c..1f310f0 100644 --- a/isys/eddsupport.c +++ b/isys/eddsupport.c @@ -36,7 +36,6 @@ #include <sys/types.h> #include <linux/types.h> - #include "eddsupport.h" #include "devices.h" #include "isys.h" @@ -47,30 +46,27 @@ #define HASH_TABLE_SIZE 17 - -struct diskMapEntry{ - uint32_t key; - char *diskname; - struct diskMapEntry *next; +struct diskMapEntry { + uint32_t key; + char *diskname; + struct diskMapEntry *next; }; struct diskMapTable { - struct diskMapEntry **table; - int tableSize; + struct diskMapEntry **table; + int tableSize; }; static struct diskMapTable *mbrSigToName = NULL; static int diskHashInit = 0; - - -static struct diskMapTable* initializeHashTable(int); +static struct diskMapTable *initializeHashTable(int); static int insertHashItem(struct diskMapTable *, struct diskMapEntry *); -static struct diskMapEntry* lookupHashItem(struct diskMapTable *, uint32_t); -static int addToHashTable(struct diskMapTable *, uint32_t , char *); -static struct device ** createDiskList(); -static int mapBiosDisks(struct device ** , const char *); -static int readDiskSig(char *, uint32_t *); +static struct diskMapEntry *lookupHashItem(struct diskMapTable *, uint32_t); +static int addToHashTable(struct diskMapTable *, uint32_t, char *); +static struct device **createDiskList(); +static int mapBiosDisks(struct device **, const char *); +static int readDiskSig(char *, uint32_t *); static int readMbrSig(char *, uint32_t *); /* This is the top level function that creates a disk list present in the @@ -79,263 +75,274 @@ static int readMbrSig(char *, uint32_t *); * corresponding hd/sd device names. Otherwise, we'll avoid mapping drives. */ -int probeBiosDisks() { - struct device ** devices = NULL; +int probeBiosDisks() +{ + struct device **devices = NULL; - devices = createDiskList(); - if(!devices){ + devices = createDiskList(); + if (!devices) { #ifdef STANDALONE - fprintf(stderr, "No disks!\n"); + fprintf(stderr, "No disks!\n"); #endif - return -1; - } + return -1; + } - if(!mapBiosDisks(devices, EDD_DIR)){ + if (!mapBiosDisks(devices, EDD_DIR)) { #ifdef STANDALONE - fprintf(stderr, "WARNING: couldn't map BIOS disks\n"); + fprintf(stderr, "WARNING: couldn't map BIOS disks\n"); #endif - return -1; - } - return 0; + return -1; + } + return 0; } - -static struct device ** createDiskList(){ - return getDevices (DEVICE_DISK); +static struct device **createDiskList() +{ + return getDevices(DEVICE_DISK); } -static int readDiskSig(char *device, uint32_t *disksig) { - int fd, rc; - char devnodeName[64]; +static int readDiskSig(char *device, uint32_t * disksig) +{ + int fd, rc; + char devnodeName[64]; - snprintf(devnodeName, sizeof(devnodeName), "/dev/%s", device); - fd = open(devnodeName, O_RDONLY); - if (fd < 0) { -#ifdef STANDALONE - fprintf(stderr, "Error opening device %s: %s\n ", device, - strerror(errno)); -#endif - return -errno; - } + snprintf(devnodeName, sizeof(devnodeName), "/dev/%s", device); + fd = open(devnodeName, O_RDONLY); + if (fd < 0) { +#ifdef STANDALONE + fprintf(stderr, "Error opening device %s: %s\n ", device, + strerror(errno)); +#endif + return -errno; + } - rc = lseek(fd, MBRSIG_OFFSET, SEEK_SET); - if (rc < 0){ - close(fd); + rc = lseek(fd, MBRSIG_OFFSET, SEEK_SET); + if (rc < 0) { + close(fd); #ifdef STANDALONE - fprintf(stderr, "Error seeking to MBRSIG_OFFSET in %s: %s\n", - device, strerror(errno)); + fprintf(stderr, "Error seeking to MBRSIG_OFFSET in %s: %s\n", + device, strerror(errno)); #endif - return -1; - } + return -1; + } - rc = read(fd, disksig, sizeof(uint32_t)); - if (rc < sizeof(uint32_t)) { - close(fd); + rc = read(fd, disksig, sizeof(uint32_t)); + if (rc < sizeof(uint32_t)) { + close(fd); #ifdef STANDALONE - fprintf(stderr, "Failed to read signature from %s\n", device); + fprintf(stderr, "Failed to read signature from %s\n", device); #endif - return -1; - } + return -1; + } - close(fd); - return 0; + close(fd); + return 0; } -static int mapBiosDisks(struct device** devices,const char *path) { - DIR *dirHandle; - struct dirent *entry; - char * sigFileName; - uint32_t mbrSig, biosNum, currentSig; - struct device **currentDev, **foundDisk; - int i, rc, ret, dm_nr, highest_dm; - - dirHandle = opendir(path); - if(!dirHandle){ +static int mapBiosDisks(struct device **devices, const char *path) +{ + DIR *dirHandle; + struct dirent *entry; + char *sigFileName; + uint32_t mbrSig, biosNum, currentSig; + struct device **currentDev, **foundDisk; + int i, rc, ret, dm_nr, highest_dm; + + dirHandle = opendir(path); + if (!dirHandle) { #ifdef STANDALONE - fprintf(stderr, "Failed to open directory %s: %s\n", path, - strerror(errno)); + fprintf(stderr, "Failed to open directory %s: %s\n", path, + strerror(errno)); #endif - return 0; - } + return 0; + } - mbrSigToName = initializeHashTable(HASH_TABLE_SIZE); - if(!mbrSigToName){ + mbrSigToName = initializeHashTable(HASH_TABLE_SIZE); + if (!mbrSigToName) { #ifdef STANDALONE - fprintf(stderr, "Error initializing mbrSigToName table\n"); + fprintf(stderr, "Error initializing mbrSigToName table\n"); #endif - closedir(dirHandle); - return 0; - } - - while ((entry = readdir(dirHandle)) != NULL) { - if(!strncmp(entry->d_name,".",1) || !strncmp(entry->d_name,"..",2)) { - continue; - } - ret = sscanf((entry->d_name+9), "%x", &biosNum); - - sigFileName = malloc(strlen(path) + strlen(entry->d_name) + 20); - sprintf(sigFileName, "%s/%s/%s", path, entry->d_name, SIG_FILE); - if (readMbrSig(sigFileName, &mbrSig) == 0) { - for (currentDev = devices, i = 0, foundDisk=NULL, highest_dm=-1; - (*currentDev) != NULL; - currentDev++) { - if (!(*currentDev)->device) - continue; - - if ((rc=readDiskSig((*currentDev)->device, ¤tSig)) < 0) { - if (rc == -ENOMEDIUM || rc == -ENXIO) - continue; - closedir(dirHandle); - return 0; - } - - if (mbrSig == currentSig) { - /* When we have a fakeraid setup we will find multiple hits - a number for the raw disks (1 when striping, 2 when - mirroring, more with raid on raid like raid 01 or 10) - and a number for the dm devices (normally only one dm - device will match, but more with raid on raid). - Since with raid on raid the last dm device created - will be the top layer raid, we want the highest matching - dm device. */ - if (!strncmp((*currentDev)->device, "dm-", 3) && - sscanf((*currentDev)->device+3, "%d", &dm_nr) == 1) { - if (dm_nr > highest_dm) { - highest_dm = dm_nr; - foundDisk=currentDev; - i = 1; - } - } else if (!foundDisk || - strncmp((*foundDisk)->device, "dm-", 3)) { - foundDisk=currentDev; - i++; - } - } - } - - if (i==1) { - if(!addToHashTable(mbrSigToName, (uint32_t)biosNum, - (*foundDisk)->device)) { - closedir(dirHandle); - return 0; - } - } - } - } - closedir(dirHandle); - return 1; -} - - -static int readMbrSig(char *filename, uint32_t *int_sig){ - FILE* fh; - - fh = fopen(filename,"r"); - if(fh == NULL) { + closedir(dirHandle); + return 0; + } + + while ((entry = readdir(dirHandle)) != NULL) { + if (!strncmp(entry->d_name, ".", 1) + || !strncmp(entry->d_name, "..", 2)) { + continue; + } + ret = sscanf((entry->d_name + 9), "%x", &biosNum); + + sigFileName = malloc(strlen(path) + strlen(entry->d_name) + 20); + sprintf(sigFileName, "%s/%s/%s", path, entry->d_name, SIG_FILE); + if (readMbrSig(sigFileName, &mbrSig) == 0) { + for (currentDev = devices, i = 0, foundDisk = + NULL, highest_dm = -1; (*currentDev) != NULL; + currentDev++) { + if (!(*currentDev)->device) + continue; + + if ((rc = + readDiskSig((*currentDev)->device, + ¤tSig)) < 0) { + if (rc == -ENOMEDIUM || rc == -ENXIO) + continue; + closedir(dirHandle); + return 0; + } + + if (mbrSig == currentSig) { + /* When we have a fakeraid setup we will find multiple hits + a number for the raw disks (1 when striping, 2 when + mirroring, more with raid on raid like raid 01 or 10) + and a number for the dm devices (normally only one dm + device will match, but more with raid on raid). + Since with raid on raid the last dm device created + will be the top layer raid, we want the highest matching + dm device. */ + if (!strncmp + ((*currentDev)->device, "dm-", 3) + && sscanf((*currentDev)->device + 3, + "%d", &dm_nr) == 1) { + if (dm_nr > highest_dm) { + highest_dm = dm_nr; + foundDisk = currentDev; + i = 1; + } + } else if (!foundDisk || + strncmp((*foundDisk)->device, + "dm-", 3)) { + foundDisk = currentDev; + i++; + } + } + } + + if (i == 1) { + if (!addToHashTable + (mbrSigToName, (uint32_t) biosNum, + (*foundDisk)->device)) { + closedir(dirHandle); + return 0; + } + } + } + } + closedir(dirHandle); + return 1; +} + +static int readMbrSig(char *filename, uint32_t * int_sig) +{ + FILE *fh; + + fh = fopen(filename, "r"); + if (fh == NULL) { #ifdef STANDALONE - fprintf(stderr, "Error opening mbr_signature file %s: %s\n", filename, - strerror(errno)); + fprintf(stderr, "Error opening mbr_signature file %s: %s\n", + filename, strerror(errno)); #endif - return -1; - } - fseek(fh, 0, SEEK_SET); - if (fscanf(fh, "%x", int_sig) != 1) { + return -1; + } + fseek(fh, 0, SEEK_SET); + if (fscanf(fh, "%x", int_sig) != 1) { #ifdef STANDALONE - fprintf(stderr, "Error reading %s\n", filename); + fprintf(stderr, "Error reading %s\n", filename); #endif - fclose(fh); - return -1; - } - - fclose(fh); - return 0; -} + fclose(fh); + return -1; + } + fclose(fh); + return 0; +} -static struct diskMapTable* initializeHashTable(int size) { - struct diskMapTable *hashTable; +static struct diskMapTable *initializeHashTable(int size) +{ + struct diskMapTable *hashTable; - hashTable = malloc(sizeof(struct diskMapTable)); - hashTable->tableSize = size; - hashTable->table = malloc(sizeof(struct diskMapEntry *) * size); - memset(hashTable->table,0,(sizeof(struct diskMapEntry *) * size)); - return hashTable; + hashTable = malloc(sizeof(struct diskMapTable)); + hashTable->tableSize = size; + hashTable->table = malloc(sizeof(struct diskMapEntry *) * size); + memset(hashTable->table, 0, (sizeof(struct diskMapEntry *) * size)); + return hashTable; } - static int insertHashItem(struct diskMapTable *hashTable, - struct diskMapEntry *hashItem) { - int index; - - index = (hashItem->key) % (hashTable->tableSize); - - if(hashTable->table[index] == NULL){ - hashTable->table[index] = hashItem; - return index; - } else { - hashItem->next = hashTable->table[index]; - hashTable->table[index] = hashItem; - return index; - } + struct diskMapEntry *hashItem) +{ + int index; + + index = (hashItem->key) % (hashTable->tableSize); + + if (hashTable->table[index] == NULL) { + hashTable->table[index] = hashItem; + return index; + } else { + hashItem->next = hashTable->table[index]; + hashTable->table[index] = hashItem; + return index; + } } - -static struct diskMapEntry * lookupHashItem(struct diskMapTable *hashTable, - uint32_t itemKey) { - int index; - struct diskMapEntry *hashItem; - - index = itemKey % (hashTable->tableSize); - for (hashItem = hashTable->table[index]; - (hashItem != NULL) && (hashItem->key != itemKey); - hashItem = hashItem->next) { - ; - } - return hashItem; +static struct diskMapEntry *lookupHashItem(struct diskMapTable *hashTable, + uint32_t itemKey) +{ + int index; + struct diskMapEntry *hashItem; + + index = itemKey % (hashTable->tableSize); + for (hashItem = hashTable->table[index]; + (hashItem != NULL) && (hashItem->key != itemKey); + hashItem = hashItem->next) { + ; + } + return hashItem; } +static int addToHashTable(struct diskMapTable *hashTable, + uint32_t itemKey, char *diskName) +{ + int index; + struct diskMapEntry *diskSigToNameEntry; -static int addToHashTable(struct diskMapTable *hashTable, - uint32_t itemKey, char *diskName) { - int index; - struct diskMapEntry *diskSigToNameEntry; + diskSigToNameEntry = malloc(sizeof(struct diskMapEntry)); + diskSigToNameEntry->next = NULL; + diskSigToNameEntry->key = itemKey; + diskSigToNameEntry->diskname = diskName; - diskSigToNameEntry = malloc(sizeof(struct diskMapEntry)); - diskSigToNameEntry->next = NULL; - diskSigToNameEntry->key = itemKey; - diskSigToNameEntry->diskname = diskName; - - if ((index = insertHashItem(hashTable, diskSigToNameEntry)) < 0){ + if ((index = insertHashItem(hashTable, diskSigToNameEntry)) < 0) { #ifdef STANDALONE - fprintf(stderr, "Unable to insert item\n"); + fprintf(stderr, "Unable to insert item\n"); #endif - return 0; - } else { - return 1; - } + return 0; + } else { + return 1; + } } +char *getBiosDisk(char *biosStr) +{ + uint32_t biosNum; + struct diskMapEntry *disk; + int ret; -char * getBiosDisk(char *biosStr) { - uint32_t biosNum; - struct diskMapEntry * disk; - int ret; - - if (diskHashInit == 0) { - probeBiosDisks(); - diskHashInit = 1; - } + if (diskHashInit == 0) { + probeBiosDisks(); + diskHashInit = 1; + } - if (mbrSigToName == NULL) - return NULL; + if (mbrSigToName == NULL) + return NULL; - ret = sscanf(biosStr,"%x",&biosNum); - disk = lookupHashItem(mbrSigToName, biosNum); - if (disk) return disk->diskname; + ret = sscanf(biosStr, "%x", &biosNum); + disk = lookupHashItem(mbrSigToName, biosNum); + if (disk) + return disk->diskname; - return NULL; + return NULL; } /* vim:set sw=8 noet */ diff --git a/isys/eddsupport.h b/isys/eddsupport.h index ec7d3f4..51427bd 100644 --- a/isys/eddsupport.h +++ b/isys/eddsupport.h @@ -21,10 +21,8 @@ #define EDDSUPPORT_H int probeBiosDisks(); -char* getBiosDisk(char *); +char *getBiosDisk(char *); #endif - - /* vim:set sw=8 noet */ diff --git a/isys/ethtool.c b/isys/ethtool.c index eb4e592..657c2f6 100644 --- a/isys/ethtool.c +++ b/isys/ethtool.c @@ -33,89 +33,92 @@ #include <linux/sockios.h> #include "ethtool.h" -static int set_intf_up(struct ifreq ifr, int sock) { - if (ioctl(sock, SIOCGIFFLAGS, &ifr) < 0) { - return (-1); - } - ifr.ifr_flags |= (IFF_UP | IFF_RUNNING); - if (ioctl(sock, SIOCSIFFLAGS, &ifr) < 0) { - fprintf(stderr, "failed to bring up interface %s: %s", ifr.ifr_name, - strerror(errno)); - return -1; - } - return (0); +static int set_intf_up(struct ifreq ifr, int sock) +{ + if (ioctl(sock, SIOCGIFFLAGS, &ifr) < 0) { + return (-1); + } + ifr.ifr_flags |= (IFF_UP | IFF_RUNNING); + if (ioctl(sock, SIOCSIFFLAGS, &ifr) < 0) { + fprintf(stderr, "failed to bring up interface %s: %s", + ifr.ifr_name, strerror(errno)); + return -1; + } + return (0); } -int setEthtoolSettings(char * dev, ethtool_speed speed, - ethtool_duplex duplex) { - int sock, err; - struct ethtool_cmd ecmd; - struct ifreq ifr; - - if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { - perror("Unable to create socket"); - return -1; - } - - /* Setup our control structures. */ - memset(&ifr, 0, sizeof(ifr)); - strcpy(ifr.ifr_name, dev); - - if (set_intf_up(ifr, sock) == -1) { - fprintf(stderr, "unable to bring up interface %s: %s", dev, - strerror(errno)); - return -1; - } - - ecmd.cmd = ETHTOOL_GSET; - ifr.ifr_data = (caddr_t)&ecmd; - err = ioctl(sock, SIOCETHTOOL, &ifr); - if (err < 0) { - perror("Unable to get settings via ethtool. Not setting"); - return -1; - } - - if (speed != ETHTOOL_SPEED_UNSPEC) - ecmd.speed = speed; - if (duplex != ETHTOOL_DUPLEX_UNSPEC) - ecmd.duplex = duplex; - if ((duplex != ETHTOOL_DUPLEX_UNSPEC) || (speed != ETHTOOL_SPEED_UNSPEC)) - ecmd.autoneg = AUTONEG_DISABLE; - - ecmd.cmd = ETHTOOL_SSET; - ifr.ifr_data = (caddr_t)&ecmd; - err = ioctl(sock, SIOCETHTOOL, &ifr); - if (err < 0) { - // perror("Unable to set settings via ethtool. Not setting"); - return -1; - } - - return 0; +int setEthtoolSettings(char *dev, ethtool_speed speed, ethtool_duplex duplex) +{ + int sock, err; + struct ethtool_cmd ecmd; + struct ifreq ifr; + + if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + perror("Unable to create socket"); + return -1; + } + + /* Setup our control structures. */ + memset(&ifr, 0, sizeof(ifr)); + strcpy(ifr.ifr_name, dev); + + if (set_intf_up(ifr, sock) == -1) { + fprintf(stderr, "unable to bring up interface %s: %s", dev, + strerror(errno)); + return -1; + } + + ecmd.cmd = ETHTOOL_GSET; + ifr.ifr_data = (caddr_t) & ecmd; + err = ioctl(sock, SIOCETHTOOL, &ifr); + if (err < 0) { + perror("Unable to get settings via ethtool. Not setting"); + return -1; + } + + if (speed != ETHTOOL_SPEED_UNSPEC) + ecmd.speed = speed; + if (duplex != ETHTOOL_DUPLEX_UNSPEC) + ecmd.duplex = duplex; + if ((duplex != ETHTOOL_DUPLEX_UNSPEC) + || (speed != ETHTOOL_SPEED_UNSPEC)) + ecmd.autoneg = AUTONEG_DISABLE; + + ecmd.cmd = ETHTOOL_SSET; + ifr.ifr_data = (caddr_t) & ecmd; + err = ioctl(sock, SIOCETHTOOL, &ifr); + if (err < 0) { + // perror("Unable to set settings via ethtool. Not setting"); + return -1; + } + + return 0; } -int identifyNIC(char *iface, int seconds) { - int sock; - struct ethtool_value edata; - struct ifreq ifr; +int identifyNIC(char *iface, int seconds) +{ + int sock; + struct ethtool_value edata; + struct ifreq ifr; - if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { - perror("Unable to create socket"); - return -1; - } + if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + perror("Unable to create socket"); + return -1; + } - memset(&ifr, 0, sizeof(ifr)); - memset(&edata, 0, sizeof(edata)); + memset(&ifr, 0, sizeof(ifr)); + memset(&edata, 0, sizeof(edata)); - strcpy(ifr.ifr_name, iface); - edata.cmd = ETHTOOL_PHYS_ID; - edata.data = seconds; - ifr.ifr_data = (caddr_t) &edata; + strcpy(ifr.ifr_name, iface); + edata.cmd = ETHTOOL_PHYS_ID; + edata.data = seconds; + ifr.ifr_data = (caddr_t) & edata; - if (ioctl(sock, SIOCETHTOOL, &ifr) < 0) { - perror("Unable to identify NIC"); - } + if (ioctl(sock, SIOCETHTOOL, &ifr) < 0) { + perror("Unable to identify NIC"); + } - return 0; + return 0; } /* vim:set sw=8 noet */ diff --git a/isys/ethtool.h b/isys/ethtool.h index e661ceb..d63177e 100644 --- a/isys/ethtool.h +++ b/isys/ethtool.h @@ -26,16 +26,18 @@ /* returns 1 for link, 0 for no link, -1 for unknown */ int get_link_status(char *ifname); -typedef enum ethtool_speed_t { ETHTOOL_SPEED_UNSPEC = -1, - ETHTOOL_SPEED_10 = SPEED_10, - ETHTOOL_SPEED_100 = SPEED_100, - ETHTOOL_SPEED_1000 = SPEED_1000 } ethtool_speed; -typedef enum ethtool_duplex_t { ETHTOOL_DUPLEX_UNSPEC = -1, - ETHTOOL_DUPLEX_HALF = DUPLEX_HALF, - ETHTOOL_DUPLEX_FULL = DUPLEX_FULL } ethtool_duplex; +typedef enum ethtool_speed_t { ETHTOOL_SPEED_UNSPEC = -1, + ETHTOOL_SPEED_10 = SPEED_10, + ETHTOOL_SPEED_100 = SPEED_100, + ETHTOOL_SPEED_1000 = SPEED_1000 +} ethtool_speed; +typedef enum ethtool_duplex_t { ETHTOOL_DUPLEX_UNSPEC = -1, + ETHTOOL_DUPLEX_HALF = DUPLEX_HALF, + ETHTOOL_DUPLEX_FULL = DUPLEX_FULL +} ethtool_duplex; /* set ethtool settings */ -int setEthtoolSettings(char * dev, ethtool_speed speed, ethtool_duplex duplex); +int setEthtoolSettings(char *dev, ethtool_speed speed, ethtool_duplex duplex); int identifyNIC(char *iface, int seconds); #endif diff --git a/isys/iface.c b/isys/iface.c index 1af53ef..cb48236 100644 --- a/isys/iface.c +++ b/isys/iface.c @@ -63,93 +63,97 @@ static int _iface_redirect_io(char *device, int fd, int mode); /* * Return a libnl handle for NETLINK_ROUTE. */ -static struct nl_handle *_iface_get_handle(void) { - struct nl_handle *handle = NULL; +static struct nl_handle *_iface_get_handle(void) +{ + struct nl_handle *handle = NULL; - if ((handle = nl_handle_alloc()) == NULL) { - return NULL; - } + if ((handle = nl_handle_alloc()) == NULL) { + return NULL; + } - if (nl_connect(handle, NETLINK_ROUTE)) { - nl_handle_destroy(handle); - return NULL; - } + if (nl_connect(handle, NETLINK_ROUTE)) { + nl_handle_destroy(handle); + return NULL; + } - return handle; + return handle; } /* * Return an NETLINK_ROUTE cache. */ -static struct nl_cache *_iface_get_link_cache(struct nl_handle **handle) { - struct nl_cache *cache = NULL; +static struct nl_cache *_iface_get_link_cache(struct nl_handle **handle) +{ + struct nl_cache *cache = NULL; - if ((*handle = _iface_get_handle()) == NULL) { - return NULL; - } + if ((*handle = _iface_get_handle()) == NULL) { + return NULL; + } - if ((cache = rtnl_link_alloc_cache(*handle)) == NULL) { - nl_close(*handle); - nl_handle_destroy(*handle); - return NULL; - } + if ((cache = rtnl_link_alloc_cache(*handle)) == NULL) { + nl_close(*handle); + nl_handle_destroy(*handle); + return NULL; + } - return cache; + return cache; } /* * Determine if a struct in_addr or struct in6_addr contains a valid address. */ -static int _iface_have_valid_addr(void *addr, int family, int length) { - char buf[length+1]; - - if ((addr == NULL) || (family != AF_INET && family != AF_INET6)) { - return 0; - } - - memset(buf, '\0', sizeof(buf)); - - if (inet_ntop(family, addr, buf, length) == NULL) { - return 0; - } else { - /* check for unknown addresses */ - if (family == AF_INET) { - if (!strncmp(buf, "0.0.0.0", 7)) { - return 0; - } - } else if (family == AF_INET6) { - if (!strncmp(buf, "::", 2)) { - return 0; - } - } - } - - return 1; +static int _iface_have_valid_addr(void *addr, int family, int length) +{ + char buf[length + 1]; + + if ((addr == NULL) || (family != AF_INET && family != AF_INET6)) { + return 0; + } + + memset(buf, '\0', sizeof(buf)); + + if (inet_ntop(family, addr, buf, length) == NULL) { + return 0; + } else { + /* check for unknown addresses */ + if (family == AF_INET) { + if (!strncmp(buf, "0.0.0.0", 7)) { + return 0; + } + } else if (family == AF_INET6) { + if (!strncmp(buf, "::", 2)) { + return 0; + } + } + } + + return 1; } /* * Redirect I/O to another device (e.g., stdout to /dev/tty5) */ -int _iface_redirect_io(char *device, int fd, int mode) { - int io = -1; +int _iface_redirect_io(char *device, int fd, int mode) +{ + int io = -1; - if ((io = open(device, mode)) == -1) { - return 1; - } + if ((io = open(device, mode)) == -1) { + return 1; + } - if (close(fd) == -1) { - return 2; - } + if (close(fd) == -1) { + return 2; + } - if (dup2(io, fd) == -1) { - return 3; - } + if (dup2(io, fd) == -1) { + return 3; + } - if (close(io) == -1) { - return 4; - } + if (close(io) == -1) { + return 4; + } - return 0; + return 0; } /* @@ -157,388 +161,402 @@ int _iface_redirect_io(char *device, int fd, int mode) { * return the IP address in human readable format (i.e., the output from * inet_ntop()). Return NULL for no match or error. */ -char *iface_ip2str(char *ifname, int family) { - int i; - NMClient *client = NULL; - NMIP4Config *ip4config = NULL; - NMIP4Address *ipaddr = NULL; - NMDevice *candidate = NULL; - struct in_addr tmp_addr; - const GPtrArray *devices; - const char *iface; - char ipstr[INET_ADDRSTRLEN+1]; - - if (ifname == NULL) { - return NULL; - } - - /* DCFIXME: add IPv6 once NM gains support */ - if (family != AF_INET) { - return NULL; - } - - g_type_init(); - - client = nm_client_new(); - if (!client) { - return NULL; - } - - if (nm_client_get_state(client) != NM_STATE_CONNECTED) { - g_object_unref(client); - return NULL; - } - - devices = nm_client_get_devices(client); - for (i=0; i < devices->len; i++) { - candidate = g_ptr_array_index(devices, i); - iface = nm_device_get_iface(candidate); - - if (nm_device_get_state(candidate) != NM_DEVICE_STATE_ACTIVATED) - continue; - - if (!iface || strcmp(iface, ifname)) - continue; - - if (!(ip4config = nm_device_get_ip4_config(candidate))) - continue; - - if (!(ipaddr = nm_ip4_config_get_addresses(ip4config)->data)) - continue; - - memset(&ipstr, '\0', sizeof(ipstr)); - tmp_addr.s_addr = nm_ip4_address_get_address(ipaddr); - - if (inet_ntop(AF_INET, &tmp_addr, ipstr, INET_ADDRSTRLEN) == NULL) { - g_object_unref(client); - return NULL; - } - - g_object_unref(client); - return g_strdup(ipstr); - } - - g_object_unref(client); - return NULL; +char *iface_ip2str(char *ifname, int family) +{ + int i; + NMClient *client = NULL; + NMIP4Config *ip4config = NULL; + NMIP4Address *ipaddr = NULL; + NMDevice *candidate = NULL; + struct in_addr tmp_addr; + const GPtrArray *devices; + const char *iface; + char ipstr[INET_ADDRSTRLEN + 1]; + + if (ifname == NULL) { + return NULL; + } + + /* DCFIXME: add IPv6 once NM gains support */ + if (family != AF_INET) { + return NULL; + } + + g_type_init(); + + client = nm_client_new(); + if (!client) { + return NULL; + } + + if (nm_client_get_state(client) != NM_STATE_CONNECTED) { + g_object_unref(client); + return NULL; + } + + devices = nm_client_get_devices(client); + for (i = 0; i < devices->len; i++) { + candidate = g_ptr_array_index(devices, i); + iface = nm_device_get_iface(candidate); + + if (nm_device_get_state(candidate) != NM_DEVICE_STATE_ACTIVATED) + continue; + + if (!iface || strcmp(iface, ifname)) + continue; + + if (!(ip4config = nm_device_get_ip4_config(candidate))) + continue; + + if (!(ipaddr = nm_ip4_config_get_addresses(ip4config)->data)) + continue; + + memset(&ipstr, '\0', sizeof(ipstr)); + tmp_addr.s_addr = nm_ip4_address_get_address(ipaddr); + + if (inet_ntop(AF_INET, &tmp_addr, ipstr, INET_ADDRSTRLEN) == + NULL) { + g_object_unref(client); + return NULL; + } + + g_object_unref(client); + return g_strdup(ipstr); + } + + g_object_unref(client); + return NULL; } /* Given an interface's MAC address, return the name (e.g., eth0) in human * readable format. Return NULL for no match */ -char *iface_mac2device(char *mac) { - struct nl_handle *handle = NULL; - struct nl_cache *cache = NULL; - struct rtnl_link *link = NULL; - struct nl_addr *mac_as_nl_addr = NULL; - char *retval = NULL; - int i, n; - - if (mac == NULL) { - return NULL; - } - - if ((mac_as_nl_addr = nl_addr_parse(mac, AF_LLC)) == NULL) { - return NULL; - } - - if ((cache = _iface_get_link_cache(&handle)) == NULL) { - return NULL; - } - - n = nl_cache_nitems(cache); - for (i = 0; i <= n; i++) { - struct nl_addr *addr; - - if ((link = rtnl_link_get(cache, i)) == NULL) { - continue; - } - - addr = rtnl_link_get_addr(link); - - if (!nl_addr_cmp(mac_as_nl_addr, addr)) { - retval = strdup(rtnl_link_get_name(link)); - rtnl_link_put(link); - break; - } - - rtnl_link_put(link); - } - - nl_close(handle); - nl_handle_destroy(handle); - - return retval; +char *iface_mac2device(char *mac) +{ + struct nl_handle *handle = NULL; + struct nl_cache *cache = NULL; + struct rtnl_link *link = NULL; + struct nl_addr *mac_as_nl_addr = NULL; + char *retval = NULL; + int i, n; + + if (mac == NULL) { + return NULL; + } + + if ((mac_as_nl_addr = nl_addr_parse(mac, AF_LLC)) == NULL) { + return NULL; + } + + if ((cache = _iface_get_link_cache(&handle)) == NULL) { + return NULL; + } + + n = nl_cache_nitems(cache); + for (i = 0; i <= n; i++) { + struct nl_addr *addr; + + if ((link = rtnl_link_get(cache, i)) == NULL) { + continue; + } + + addr = rtnl_link_get_addr(link); + + if (!nl_addr_cmp(mac_as_nl_addr, addr)) { + retval = strdup(rtnl_link_get_name(link)); + rtnl_link_put(link); + break; + } + + rtnl_link_put(link); + } + + nl_close(handle); + nl_handle_destroy(handle); + + return retval; } /* * Given an interface name (e.g., eth0), return the MAC address in human * readable format (e.g., 00:11:52:12:D9:A0). Return NULL for no match. */ -char *iface_mac2str(char *ifname) { - int buflen = 20; - char *buf = NULL; - struct nl_handle *handle = NULL; - struct nl_cache *cache = NULL; - struct rtnl_link *link = NULL; - struct nl_addr *addr = NULL; - - if (ifname == NULL) { - return NULL; - } - - if ((cache = _iface_get_link_cache(&handle)) == NULL) { - return NULL; - } - - if ((link = rtnl_link_get_by_name(cache, ifname)) == NULL) { - goto mac2str_error2; - } - - if ((addr = rtnl_link_get_addr(link)) == NULL) { - goto mac2str_error3; - } - - if ((buf = calloc(sizeof(char *), buflen)) == NULL) { - goto mac2str_error4; - } - - if ((buf = nl_addr2str(addr, buf, buflen)) != NULL) { - buf = str2upper(buf); - } +char *iface_mac2str(char *ifname) +{ + int buflen = 20; + char *buf = NULL; + struct nl_handle *handle = NULL; + struct nl_cache *cache = NULL; + struct rtnl_link *link = NULL; + struct nl_addr *addr = NULL; + + if (ifname == NULL) { + return NULL; + } + + if ((cache = _iface_get_link_cache(&handle)) == NULL) { + return NULL; + } + + if ((link = rtnl_link_get_by_name(cache, ifname)) == NULL) { + goto mac2str_error2; + } + + if ((addr = rtnl_link_get_addr(link)) == NULL) { + goto mac2str_error3; + } + + if ((buf = calloc(sizeof(char *), buflen)) == NULL) { + goto mac2str_error4; + } + + if ((buf = nl_addr2str(addr, buf, buflen)) != NULL) { + buf = str2upper(buf); + } mac2str_error4: - nl_addr_destroy(addr); + nl_addr_destroy(addr); mac2str_error3: - rtnl_link_put(link); + rtnl_link_put(link); mac2str_error2: - nl_close(handle); - nl_handle_destroy(handle); + nl_close(handle); + nl_handle_destroy(handle); - return buf; + return buf; } /* * Convert an IPv4 CIDR prefix to a dotted-quad netmask. Return NULL on * failure. */ -struct in_addr *iface_prefix2netmask(int prefix) { - int mask = 0; - char *buf = NULL; - struct in_addr *ret; +struct in_addr *iface_prefix2netmask(int prefix) +{ + int mask = 0; + char *buf = NULL; + struct in_addr *ret; - if ((buf = calloc(sizeof(char *), INET_ADDRSTRLEN + 1)) == NULL) { - return NULL; - } + if ((buf = calloc(sizeof(char *), INET_ADDRSTRLEN + 1)) == NULL) { + return NULL; + } - mask = htonl(~((1 << (32 - prefix)) - 1)); + mask = htonl(~((1 << (32 - prefix)) - 1)); - if (inet_ntop(AF_INET, (struct in_addr *) &mask, buf, - INET_ADDRSTRLEN) == NULL) { - return NULL; - } + if (inet_ntop(AF_INET, (struct in_addr *)&mask, buf, + INET_ADDRSTRLEN) == NULL) { + return NULL; + } - if ((ret = calloc(sizeof(struct in_addr), 1)) == NULL) { - return NULL; - } + if ((ret = calloc(sizeof(struct in_addr), 1)) == NULL) { + return NULL; + } - memcpy(ret, (struct in_addr *) &mask, sizeof(struct in_addr)); - return ret; + memcpy(ret, (struct in_addr *)&mask, sizeof(struct in_addr)); + return ret; } /* * Initialize a new iface_t structure to default values. */ -void iface_init_iface_t(iface_t *iface) { - int i; - - memset(&iface->device, '\0', sizeof(iface->device)); - memset(&iface->ipaddr, 0, sizeof(iface->ipaddr)); - memset(&iface->netmask, 0, sizeof(iface->netmask)); - memset(&iface->broadcast, 0, sizeof(iface->broadcast)); - memset(&iface->ip6addr, 0, sizeof(iface->ip6addr)); - memset(&iface->gateway, 0, sizeof(iface->gateway)); - memset(&iface->gateway6, 0, sizeof(iface->gateway6)); - - for (i = 0; i < MAXNS; i++) { - iface->dns[i] = NULL; - } - - iface->macaddr = NULL; - iface->ip6prefix = 0; - iface->nextserver = NULL; - iface->bootfile = NULL; - iface->numdns = 0; - iface->hostname = NULL; - iface->domain = NULL; - iface->search = NULL; - iface->dhcptimeout = 0; - iface->vendorclass = NULL; - iface->ssid = NULL; - iface->wepkey = NULL; - iface->mtu = 0; - iface->subchannels = NULL; - iface->portname = NULL; - iface->peerid = NULL; - iface->nettype = NULL; - iface->ctcprot = NULL; - iface->layer2 = NULL; - iface->portno = NULL; - iface->flags = 0; - iface->ipv4method = IPV4_UNUSED_METHOD; - iface->ipv6method = IPV6_UNUSED_METHOD; - - return; +void iface_init_iface_t(iface_t * iface) +{ + int i; + + memset(&iface->device, '\0', sizeof(iface->device)); + memset(&iface->ipaddr, 0, sizeof(iface->ipaddr)); + memset(&iface->netmask, 0, sizeof(iface->netmask)); + memset(&iface->broadcast, 0, sizeof(iface->broadcast)); + memset(&iface->ip6addr, 0, sizeof(iface->ip6addr)); + memset(&iface->gateway, 0, sizeof(iface->gateway)); + memset(&iface->gateway6, 0, sizeof(iface->gateway6)); + + for (i = 0; i < MAXNS; i++) { + iface->dns[i] = NULL; + } + + iface->macaddr = NULL; + iface->ip6prefix = 0; + iface->nextserver = NULL; + iface->bootfile = NULL; + iface->numdns = 0; + iface->hostname = NULL; + iface->domain = NULL; + iface->search = NULL; + iface->dhcptimeout = 0; + iface->vendorclass = NULL; + iface->ssid = NULL; + iface->wepkey = NULL; + iface->mtu = 0; + iface->subchannels = NULL; + iface->portname = NULL; + iface->peerid = NULL; + iface->nettype = NULL; + iface->ctcprot = NULL; + iface->layer2 = NULL; + iface->portno = NULL; + iface->flags = 0; + iface->ipv4method = IPV4_UNUSED_METHOD; + iface->ipv6method = IPV6_UNUSED_METHOD; + + return; } /* * Given a pointer to a struct in_addr, return 1 if it contains a valid * address, 0 otherwise. */ -int iface_have_in_addr(struct in_addr *addr) { - return _iface_have_valid_addr(addr, AF_INET, INET_ADDRSTRLEN); +int iface_have_in_addr(struct in_addr *addr) +{ + return _iface_have_valid_addr(addr, AF_INET, INET_ADDRSTRLEN); } /* * Given a pointer to a struct in6_addr, return 1 if it contains a valid * address, 0 otherwise. */ -int iface_have_in6_addr(struct in6_addr *addr6) { - return _iface_have_valid_addr(addr6, AF_INET6, INET6_ADDRSTRLEN); +int iface_have_in6_addr(struct in6_addr *addr6) +{ + return _iface_have_valid_addr(addr6, AF_INET6, INET6_ADDRSTRLEN); } /* Check if NM has an active connection */ -gboolean is_nm_connected(void) { - NMState state; - NMClient *client = NULL; +gboolean is_nm_connected(void) +{ + NMState state; + NMClient *client = NULL; - g_type_init(); + g_type_init(); - client = nm_client_new(); - if (!client) - return FALSE; + client = nm_client_new(); + if (!client) + return FALSE; - state = nm_client_get_state(client); - g_object_unref(client); + state = nm_client_get_state(client); + g_object_unref(client); - if (state == NM_STATE_CONNECTED) - return TRUE; - else - return FALSE; + if (state == NM_STATE_CONNECTED) + return TRUE; + else + return FALSE; } /* Check if NM is already running */ -gboolean is_nm_running(void) { - gboolean running; - NMClient *client = NULL; +gboolean is_nm_running(void) +{ + gboolean running; + NMClient *client = NULL; - g_type_init(); + g_type_init(); - client = nm_client_new(); - if (!client) - return FALSE; + client = nm_client_new(); + if (!client) + return FALSE; - running = nm_client_get_manager_running(client); - g_object_unref(client); - return running; + running = nm_client_get_manager_running(client); + g_object_unref(client); + return running; } /* * Wait for NetworkManager to appear on the system bus */ -int wait_for_nm(void) { - int count = 0; +int wait_for_nm(void) +{ + int count = 0; - /* send message and block until a reply or error comes back */ - while (count < 45) { - if (is_nm_running()) - return 0; + /* send message and block until a reply or error comes back */ + while (count < 45) { + if (is_nm_running()) + return 0; - sleep(1); - count++; - } + sleep(1); + count++; + } - return 1; + return 1; } /* * Start NetworkManager -- requires that you have already written out the * control files in /etc/sysconfig for the interface. */ -int iface_start_NetworkManager(void) { - pid_t pid; - - if (is_nm_running()) - return 0; /* already running */ - - /* Start NetworkManager */ - pid = fork(); - if (pid == 0) { - if (setpgrp() == -1) { - exit(1); - } - - if (_iface_redirect_io("/dev/null", STDIN_FILENO, O_RDONLY) || - _iface_redirect_io(OUTPUT_TERMINAL, STDOUT_FILENO, O_WRONLY) || - _iface_redirect_io(OUTPUT_TERMINAL, STDERR_FILENO, O_WRONLY)) { - exit(2); - } - - if (execl(NETWORKMANAGER, NETWORKMANAGER, - "--pid-file=/var/run/NetworkManager/NetworkManager.pid", - NULL) == -1) { - exit(3); - } - } else if (pid == -1) { - return 1; - } else { - return wait_for_nm(); - } - - return 0; +int iface_start_NetworkManager(void) +{ + pid_t pid; + + if (is_nm_running()) + return 0; /* already running */ + + /* Start NetworkManager */ + pid = fork(); + if (pid == 0) { + if (setpgrp() == -1) { + exit(1); + } + + if (_iface_redirect_io("/dev/null", STDIN_FILENO, O_RDONLY) || + _iface_redirect_io(OUTPUT_TERMINAL, STDOUT_FILENO, O_WRONLY) + || _iface_redirect_io(OUTPUT_TERMINAL, STDERR_FILENO, + O_WRONLY)) { + exit(2); + } + + if (execl(NETWORKMANAGER, NETWORKMANAGER, + "--pid-file=/var/run/NetworkManager/NetworkManager.pid", + NULL) == -1) { + exit(3); + } + } else if (pid == -1) { + return 1; + } else { + return wait_for_nm(); + } + + return 0; } /* * Set the MTU on the specified device. */ -int iface_set_interface_mtu(char *ifname, int mtu) { - int ret = 0; - struct nl_handle *handle = NULL; - struct nl_cache *cache = NULL; - struct rtnl_link *link = NULL; - struct rtnl_link *request = NULL; - - if (ifname == NULL) { - return -1; - } - - if (mtu <= 0) { - return -2; - } - - if ((cache = _iface_get_link_cache(&handle)) == NULL) { - return -3; - } - - if ((link = rtnl_link_get_by_name(cache, ifname)) == NULL) { - ret = -4; - goto ifacemtu_error1; - } - - request = rtnl_link_alloc(); - rtnl_link_set_mtu(request, mtu); - - if (rtnl_link_change(handle, link, request, 0)) { - ret = -5; - goto ifacemtu_error2; - } +int iface_set_interface_mtu(char *ifname, int mtu) +{ + int ret = 0; + struct nl_handle *handle = NULL; + struct nl_cache *cache = NULL; + struct rtnl_link *link = NULL; + struct rtnl_link *request = NULL; + + if (ifname == NULL) { + return -1; + } + + if (mtu <= 0) { + return -2; + } + + if ((cache = _iface_get_link_cache(&handle)) == NULL) { + return -3; + } + + if ((link = rtnl_link_get_by_name(cache, ifname)) == NULL) { + ret = -4; + goto ifacemtu_error1; + } + + request = rtnl_link_alloc(); + rtnl_link_set_mtu(request, mtu); + + if (rtnl_link_change(handle, link, request, 0)) { + ret = -5; + goto ifacemtu_error2; + } ifacemtu_error2: - rtnl_link_put(link); + rtnl_link_put(link); ifacemtu_error1: - nl_close(handle); - nl_handle_destroy(handle); + nl_close(handle); + nl_handle_destroy(handle); - return ret; + return ret; } /* vim:set sw=8 noet */ diff --git a/isys/iface.h b/isys/iface.h index 17696ec..1fe9ecc 100644 --- a/isys/iface.h +++ b/isys/iface.h @@ -31,9 +31,12 @@ /* Enumerated types used in iface.c as well as loader's network code */ enum { IPUNUSED, IPV4, IPV6 }; -enum { IPV4_UNUSED_METHOD, IPV4_DHCP_METHOD, IPV4_MANUAL_METHOD, IPV4_IBFT_METHOD, IPV4_IBFT_DHCP_METHOD }; +enum { IPV4_UNUSED_METHOD, IPV4_DHCP_METHOD, IPV4_MANUAL_METHOD, + IPV4_IBFT_METHOD, IPV4_IBFT_DHCP_METHOD +}; enum { IPV6_UNUSED_METHOD, IPV6_AUTO_METHOD, IPV6_DHCP_METHOD, - IPV6_MANUAL_METHOD }; + IPV6_MANUAL_METHOD +}; #define IPV4_FIRST_METHOD IPV4_DHCP_METHOD #define IPV4_LAST_METHOD IPV4_MANUAL_METHOD @@ -50,59 +53,59 @@ enum { IPV6_UNUSED_METHOD, IPV6_AUTO_METHOD, IPV6_DHCP_METHOD, /* Per-interface configuration information */ typedef struct _iface_t { - /* device name (e.g., eth0) */ - char device[IF_NAMESIZE]; - - /* MAC address as xx:xx:xx:xx:xx:xx */ - char *macaddr; - - /* IPv4 (store addresses in in_addr format, use inet_pton() to display) */ - struct in_addr ipaddr; - struct in_addr netmask; - struct in_addr broadcast; - - /* IPv6 (store addresses in in6_addr format, prefix is just an int) */ - struct in6_addr ip6addr; - int ip6prefix; - - /* Gateway settings */ - struct in_addr gateway; - struct in6_addr gateway6; - - /* BOOTP (these can be IPv4 or IPv6, store human-readable version as str) */ - char *nextserver; - char *bootfile; - - /* DNS (these can be IPv4 or IPv6, store human-readable version as str) */ - char *dns[MAXNS]; - int numdns; - char *hostname; - char *domain; - char *search; - - /* Misc DHCP settings */ - int dhcptimeout; - char *vendorclass; - - /* Wireless settings */ - char *ssid; - char *wepkey; - - /* s390 specifics */ - int mtu; - char *subchannels; - char *portname; - char *peerid; - char *nettype; - char *ctcprot; - char *layer2; - char *portno; - - /* flags */ - uint64_t flags; - int ipv4method; - int ipv6method; - int isiBFT; + /* device name (e.g., eth0) */ + char device[IF_NAMESIZE]; + + /* MAC address as xx:xx:xx:xx:xx:xx */ + char *macaddr; + + /* IPv4 (store addresses in in_addr format, use inet_pton() to display) */ + struct in_addr ipaddr; + struct in_addr netmask; + struct in_addr broadcast; + + /* IPv6 (store addresses in in6_addr format, prefix is just an int) */ + struct in6_addr ip6addr; + int ip6prefix; + + /* Gateway settings */ + struct in_addr gateway; + struct in6_addr gateway6; + + /* BOOTP (these can be IPv4 or IPv6, store human-readable version as str) */ + char *nextserver; + char *bootfile; + + /* DNS (these can be IPv4 or IPv6, store human-readable version as str) */ + char *dns[MAXNS]; + int numdns; + char *hostname; + char *domain; + char *search; + + /* Misc DHCP settings */ + int dhcptimeout; + char *vendorclass; + + /* Wireless settings */ + char *ssid; + char *wepkey; + + /* s390 specifics */ + int mtu; + char *subchannels; + char *portname; + char *peerid; + char *nettype; + char *ctcprot; + char *layer2; + char *portno; + + /* flags */ + uint64_t flags; + int ipv4method; + int ipv6method; + int isiBFT; } iface_t; /* Function prototypes */ diff --git a/isys/imount.c b/isys/imount.c index 1dffa54..a9db2c9 100644 --- a/isys/imount.c +++ b/isys/imount.c @@ -32,223 +32,235 @@ #define _(foo) foo -static int mkdirIfNone(char * directory); - -static int readFD(int fd, char **buf) { - char *p; - size_t size = 4096; - int s, filesize = 0; - - *buf = calloc(4096, sizeof (char)); - if (*buf == NULL) - abort(); - - do { - p = &(*buf)[filesize]; - s = read(fd, p, 4096); - if (s < 0) - break; - - filesize += s; - if (s == 0) - break; - - size += s; - *buf = realloc(*buf, size); - if (*buf == NULL) - abort(); - } while (1); - - if (filesize == 0 && s < 0) { - free(*buf); - *buf = NULL; - return -1; - } - - return filesize; +static int mkdirIfNone(char *directory); + +static int readFD(int fd, char **buf) +{ + char *p; + size_t size = 4096; + int s, filesize = 0; + + *buf = calloc(4096, sizeof(char)); + if (*buf == NULL) + abort(); + + do { + p = &(*buf)[filesize]; + s = read(fd, p, 4096); + if (s < 0) + break; + + filesize += s; + if (s == 0) + break; + + size += s; + *buf = realloc(*buf, size); + if (*buf == NULL) + abort(); + } while (1); + + if (filesize == 0 && s < 0) { + free(*buf); + *buf = NULL; + return -1; + } + + return filesize; } int mountCommandWrapper(int mode, char *dev, char *where, char *fs, - char *options, char **err) { - int rc, child, status, pipefd[2]; - char *opts = NULL, *device = NULL, *cmd = NULL; - int programLogFD; - - if (mode == IMOUNT_MODE_MOUNT) { - cmd = "/bin/mount"; - } else if (mode == IMOUNT_MODE_UMOUNT) { - cmd = "/bin/umount"; - } else { - return IMOUNT_ERR_MODE; - } - - if (mode == IMOUNT_MODE_MOUNT) { - if (mkdirChain(where)) - return IMOUNT_ERR_ERRNO; - - if (strstr(fs, "nfs")) { - if (options) { - if (asprintf(&opts, "%s,nolock", options) == -1) { - fprintf(stderr, "%s: %d: %s\n", __func__, __LINE__, - strerror(errno)); - fflush(stderr); - abort(); - } - } else { - opts = strdup("nolock"); - } - - device = strdup(dev); - } else { - if ((options && strstr(options, "bind") == NULL) && - strncmp(dev, "LABEL=", 6) && strncmp(dev, "UUID=", 5) && - *dev != '/') { - if (asprintf(&device, "/dev/%s", dev) == -1) { - fprintf(stderr, "%s: %d: %s\n", __func__, __LINE__, - strerror(errno)); - fflush(stderr); - abort(); - } - } else { - device = strdup(dev); - } - - if (options) - opts = strdup(options); - } - } - - programLogFD = open("/tmp/program.log", - O_APPEND|O_CREAT|O_WRONLY, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); - - if (pipe(pipefd)) - return IMOUNT_ERR_ERRNO; - - if (!(child = fork())) { - int fd; - - close(pipefd[0]); - - /* Close stdin entirely, redirect stdout to /tmp/program.log, and - * redirect stderr to a pipe so we can put error messages into - * exceptions. We'll only use these messages should mount also - * return an error code. - */ - fd = open("/dev/tty5", O_RDONLY); - close(STDIN_FILENO); - dup2(fd, STDIN_FILENO); - close(fd); - - close(STDOUT_FILENO); - dup2(programLogFD, STDOUT_FILENO); - - dup2(pipefd[1], STDERR_FILENO); - - if (mode == IMOUNT_MODE_MOUNT) { - if (opts) { - fprintf(stdout, "Running... %s -n -t %s -o %s %s %s\n", - cmd, fs, opts, device, where); - rc = execl(cmd, cmd, - "-n", "-t", fs, "-o", opts, device, where, NULL); - exit(1); - } else { - fprintf(stdout, "Running... %s -n -t %s %s %s\n", - cmd, fs, device, where); - rc = execl(cmd, cmd, "-n", "-t", fs, device, where, NULL); - exit(1); - } - } else if (mode == IMOUNT_MODE_UMOUNT) { - fprintf(stdout, "Running... %s %s\n", cmd, where); - rc = execl(cmd, cmd, where, NULL); - exit(1); - } else { - fprintf(stdout, "Running... Unknown imount mode: %d\n", mode); - exit(1); - } - } - - close(pipefd[1]); - - if (err != NULL) { - if (*err != NULL) { - rc = readFD(pipefd[0], err); - rc = write(programLogFD, *err, 4096); - } - } - - close(pipefd[0]); - waitpid(child, &status, 0); - - close(programLogFD); - - if (opts) { - free(opts); - } - - if (device) { - free(device); - } - - if (!WIFEXITED(status)) - return IMOUNT_ERR_OTHER; - else if ( (rc = WEXITSTATUS(status)) ) { - /* Refer to 'man mount' for the meaning of the error codes. */ - switch (rc) { - case 1: - return IMOUNT_ERR_PERMISSIONS; - case 2: - return IMOUNT_ERR_SYSTEM; - case 4: - return IMOUNT_ERR_MOUNTINTERNAL; - case 8: - return IMOUNT_ERR_USERINTERRUPT; - case 16: - return IMOUNT_ERR_MTAB; - case 32: - return IMOUNT_ERR_MOUNTFAILURE; - case 64: - return IMOUNT_ERR_PARTIALSUCC; - default: - return IMOUNT_ERR_OTHER; - } - } - - return 0; -} + char *options, char **err) +{ + int rc, child, status, pipefd[2]; + char *opts = NULL, *device = NULL, *cmd = NULL; + int programLogFD; + + if (mode == IMOUNT_MODE_MOUNT) { + cmd = "/bin/mount"; + } else if (mode == IMOUNT_MODE_UMOUNT) { + cmd = "/bin/umount"; + } else { + return IMOUNT_ERR_MODE; + } -int doPwMount(char *dev, char *where, char *fs, char *options, char **err) { - return mountCommandWrapper(IMOUNT_MODE_MOUNT, - dev, where, fs, options, err); -} + if (mode == IMOUNT_MODE_MOUNT) { + if (mkdirChain(where)) + return IMOUNT_ERR_ERRNO; + + if (strstr(fs, "nfs")) { + if (options) { + if (asprintf(&opts, "%s,nolock", options) == -1) { + fprintf(stderr, "%s: %d: %s\n", + __func__, __LINE__, + strerror(errno)); + fflush(stderr); + abort(); + } + } else { + opts = strdup("nolock"); + } + + device = strdup(dev); + } else { + if ((options && strstr(options, "bind") == NULL) && + strncmp(dev, "LABEL=", 6) + && strncmp(dev, "UUID=", 5) && *dev != '/') { + if (asprintf(&device, "/dev/%s", dev) == -1) { + fprintf(stderr, "%s: %d: %s\n", + __func__, __LINE__, + strerror(errno)); + fflush(stderr); + abort(); + } + } else { + device = strdup(dev); + } + + if (options) + opts = strdup(options); + } + } -int doPwUmount(char *where, char **err) { - return mountCommandWrapper(IMOUNT_MODE_UMOUNT, - NULL, where, NULL, NULL, err); -} + programLogFD = open("/tmp/program.log", + O_APPEND | O_CREAT | O_WRONLY, + S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); + + if (pipe(pipefd)) + return IMOUNT_ERR_ERRNO; + + if (!(child = fork())) { + int fd; + + close(pipefd[0]); + + /* Close stdin entirely, redirect stdout to /tmp/program.log, and + * redirect stderr to a pipe so we can put error messages into + * exceptions. We'll only use these messages should mount also + * return an error code. + */ + fd = open("/dev/tty5", O_RDONLY); + close(STDIN_FILENO); + dup2(fd, STDIN_FILENO); + close(fd); + + close(STDOUT_FILENO); + dup2(programLogFD, STDOUT_FILENO); + + dup2(pipefd[1], STDERR_FILENO); + + if (mode == IMOUNT_MODE_MOUNT) { + if (opts) { + fprintf(stdout, + "Running... %s -n -t %s -o %s %s %s\n", + cmd, fs, opts, device, where); + rc = execl(cmd, cmd, "-n", "-t", fs, "-o", opts, + device, where, NULL); + exit(1); + } else { + fprintf(stdout, + "Running... %s -n -t %s %s %s\n", cmd, + fs, device, where); + rc = execl(cmd, cmd, "-n", "-t", fs, device, + where, NULL); + exit(1); + } + } else if (mode == IMOUNT_MODE_UMOUNT) { + fprintf(stdout, "Running... %s %s\n", cmd, where); + rc = execl(cmd, cmd, where, NULL); + exit(1); + } else { + fprintf(stdout, "Running... Unknown imount mode: %d\n", + mode); + exit(1); + } + } + + close(pipefd[1]); -int mkdirChain(char * origChain) { - char * chain; - char * chptr; + if (err != NULL) { + if (*err != NULL) { + rc = readFD(pipefd[0], err); + rc = write(programLogFD, *err, 4096); + } + } + + close(pipefd[0]); + waitpid(child, &status, 0); - chain = alloca(strlen(origChain) + 1); - strcpy(chain, origChain); - chptr = chain; + close(programLogFD); - while ((chptr = strchr(chptr, '/'))) { - *chptr = '\0'; - if (mkdirIfNone(chain)) { - *chptr = '/'; - return IMOUNT_ERR_ERRNO; + if (opts) { + free(opts); } - *chptr = '/'; - chptr++; - } + if (device) { + free(device); + } - if (mkdirIfNone(chain)) - return IMOUNT_ERR_ERRNO; + if (!WIFEXITED(status)) + return IMOUNT_ERR_OTHER; + else if ((rc = WEXITSTATUS(status))) { + /* Refer to 'man mount' for the meaning of the error codes. */ + switch (rc) { + case 1: + return IMOUNT_ERR_PERMISSIONS; + case 2: + return IMOUNT_ERR_SYSTEM; + case 4: + return IMOUNT_ERR_MOUNTINTERNAL; + case 8: + return IMOUNT_ERR_USERINTERRUPT; + case 16: + return IMOUNT_ERR_MTAB; + case 32: + return IMOUNT_ERR_MOUNTFAILURE; + case 64: + return IMOUNT_ERR_PARTIALSUCC; + default: + return IMOUNT_ERR_OTHER; + } + } + + return 0; +} + +int doPwMount(char *dev, char *where, char *fs, char *options, char **err) +{ + return mountCommandWrapper(IMOUNT_MODE_MOUNT, + dev, where, fs, options, err); +} + +int doPwUmount(char *where, char **err) +{ + return mountCommandWrapper(IMOUNT_MODE_UMOUNT, + NULL, where, NULL, NULL, err); +} + +int mkdirChain(char *origChain) +{ + char *chain; + char *chptr; + + chain = alloca(strlen(origChain) + 1); + strcpy(chain, origChain); + chptr = chain; + + while ((chptr = strchr(chptr, '/'))) { + *chptr = '\0'; + if (mkdirIfNone(chain)) { + *chptr = '/'; + return IMOUNT_ERR_ERRNO; + } + + *chptr = '/'; + chptr++; + } - return 0; + if (mkdirIfNone(chain)) + return IMOUNT_ERR_ERRNO; + + return 0; } /* Returns true iff it is possible that the mount command that have returned @@ -256,37 +268,42 @@ int mkdirChain(char * origChain) { * device, etc.) */ int mountMightSucceedLater(int mountRc) { - int rc; - switch (mountRc) { - case IMOUNT_ERR_MOUNTFAILURE: - rc = 1; - break; - default: - rc = 0; - } - return rc; + int rc; + switch (mountRc) { + case IMOUNT_ERR_MOUNTFAILURE: + rc = 1; + break; + default: + rc = 0; + } + return rc; } -static int mkdirIfNone(char * directory) { - int rc, mkerr; - char * chptr; +static int mkdirIfNone(char *directory) +{ + int rc, mkerr; + char *chptr; - /* If the file exists it *better* be a directory -- I'm not going to - actually check or anything */ - if (!access(directory, X_OK)) return 0; + /* If the file exists it *better* be a directory -- I'm not going to + actually check or anything */ + if (!access(directory, X_OK)) + return 0; - /* if the path is '/' we get ENOFILE not found" from mkdir, rather - then EEXIST which is weird */ - for (chptr = directory; *chptr; chptr++) - if (*chptr != '/') break; - if (!*chptr) return 0; + /* if the path is '/' we get ENOFILE not found" from mkdir, rather + then EEXIST which is weird */ + for (chptr = directory; *chptr; chptr++) + if (*chptr != '/') + break; + if (!*chptr) + return 0; - rc = mkdir(directory, 0755); - mkerr = errno; + rc = mkdir(directory, 0755); + mkerr = errno; - if (!rc || mkerr == EEXIST) return 0; + if (!rc || mkerr == EEXIST) + return 0; - return IMOUNT_ERR_ERRNO; + return IMOUNT_ERR_ERRNO; } /* vim:set sw=8 noet */ diff --git a/isys/imount.h b/isys/imount.h index 108f535..95b99ef 100644 --- a/isys/imount.h +++ b/isys/imount.h @@ -42,7 +42,7 @@ int doPwMount(char *dev, char *where, char *fs, char *options, char **err); int doPwUmount(char *where, char **err); -int mkdirChain(char * origChain); +int mkdirChain(char *origChain); int mountMightSucceedLater(int mountRc); #endif diff --git a/isys/isofs.c b/isys/isofs.c index 404283e..1579d42 100644 --- a/isys/isofs.c +++ b/isys/isofs.c @@ -22,36 +22,37 @@ #include <unistd.h> #define BLOCK_SIZE 2048 - -/* returns 1 if file is an ISO, 0 otherwise */ -int fileIsIso(const char * file) { - int blkNum; - char magic[5]; - int fd; - - fd = open(file, O_RDONLY); - if (fd < 0) - return 0; - - for (blkNum = 16; blkNum < 100; blkNum++) { - if (lseek(fd, blkNum * BLOCK_SIZE + 1, SEEK_SET) < 0) { - close(fd); - return 0; - } - if (read(fd, magic, sizeof(magic)) != sizeof(magic)) { - close(fd); - return 0; - } - - if (!strncmp(magic, "CD001", 5)) { - close(fd); - return 1; +/* returns 1 if file is an ISO, 0 otherwise */ +int fileIsIso(const char *file) +{ + int blkNum; + char magic[5]; + int fd; + + fd = open(file, O_RDONLY); + if (fd < 0) + return 0; + + for (blkNum = 16; blkNum < 100; blkNum++) { + if (lseek(fd, blkNum * BLOCK_SIZE + 1, SEEK_SET) < 0) { + close(fd); + return 0; + } + + if (read(fd, magic, sizeof(magic)) != sizeof(magic)) { + close(fd); + return 0; + } + + if (!strncmp(magic, "CD001", 5)) { + close(fd); + return 1; + } } - } - close(fd); - return 0; + close(fd); + return 0; } /* vim:set sw=8 noet */ diff --git a/isys/isys.c b/isys/isys.c index 997f37e..64a3d83 100644 --- a/isys/isys.c +++ b/isys/isys.c @@ -81,90 +81,95 @@ #define CDROMEJECT 0x5309 #endif -static PyObject * doMount(PyObject * s, PyObject * args); -static PyObject * doUMount(PyObject * s, PyObject * args); -static PyObject * doSwapon(PyObject * s, PyObject * args); -static PyObject * doSwapoff(PyObject * s, PyObject * args); -static PyObject * doLoSetup(PyObject * s, PyObject * args); -static PyObject * doUnLoSetup(PyObject * s, PyObject * args); -static PyObject * doLoChangeFd(PyObject * s, PyObject * args); -static PyObject * doWipeRaidSuperblock(PyObject * s, PyObject * args); -static PyObject * doGetRaidChunkSize(PyObject * s, PyObject * args); -static PyObject * doDevSpaceFree(PyObject * s, PyObject * args); -static PyObject * doResetResolv(PyObject * s, PyObject * args); -static PyObject * doLoadKeymap(PyObject * s, PyObject * args); -static PyObject * doExt2Dirty(PyObject * s, PyObject * args); -static PyObject * doExt2HasJournal(PyObject * s, PyObject * args); -static PyObject * doEjectCdrom(PyObject * s, PyObject * args); -static PyObject * doVtActivate(PyObject * s, PyObject * args); -static PyObject * doisPseudoTTY(PyObject * s, PyObject * args); -static PyObject * doisVioConsole(PyObject * s); -static PyObject * doSync(PyObject * s, PyObject * args); -static PyObject * doisIsoImage(PyObject * s, PyObject * args); -static PyObject * printObject(PyObject * s, PyObject * args); -static PyObject * py_bind_textdomain_codeset(PyObject * o, PyObject * args); -static PyObject * py_getDasdPorts(PyObject * s, PyObject * args); -static PyObject * py_isUsableDasd(PyObject * s, PyObject * args); -static PyObject * py_isLdlDasd(PyObject * s, PyObject * args); -static PyObject * doProbeBiosDisks(PyObject * s, PyObject * args); -static PyObject * doGetBiosDisk(PyObject * s, PyObject * args); -static PyObject * doSegvHandler(PyObject *s, PyObject *args); -static PyObject * doAuditDaemon(PyObject *s); -static PyObject * doPrefixToNetmask(PyObject *s, PyObject *args); -static PyObject * doGetBlkidData(PyObject * s, PyObject * args); -static PyObject * doIsCapsLockEnabled(PyObject * s, PyObject * args); -static PyObject * doGetLinkStatus(PyObject * s, PyObject * args); -static PyObject * doGetAnacondaVersion(PyObject * s, PyObject * args); +static PyObject *doMount(PyObject * s, PyObject * args); +static PyObject *doUMount(PyObject * s, PyObject * args); +static PyObject *doSwapon(PyObject * s, PyObject * args); +static PyObject *doSwapoff(PyObject * s, PyObject * args); +static PyObject *doLoSetup(PyObject * s, PyObject * args); +static PyObject *doUnLoSetup(PyObject * s, PyObject * args); +static PyObject *doLoChangeFd(PyObject * s, PyObject * args); +static PyObject *doWipeRaidSuperblock(PyObject * s, PyObject * args); +static PyObject *doGetRaidChunkSize(PyObject * s, PyObject * args); +static PyObject *doDevSpaceFree(PyObject * s, PyObject * args); +static PyObject *doResetResolv(PyObject * s, PyObject * args); +static PyObject *doLoadKeymap(PyObject * s, PyObject * args); +static PyObject *doExt2Dirty(PyObject * s, PyObject * args); +static PyObject *doExt2HasJournal(PyObject * s, PyObject * args); +static PyObject *doEjectCdrom(PyObject * s, PyObject * args); +static PyObject *doVtActivate(PyObject * s, PyObject * args); +static PyObject *doisPseudoTTY(PyObject * s, PyObject * args); +static PyObject *doisVioConsole(PyObject * s); +static PyObject *doSync(PyObject * s, PyObject * args); +static PyObject *doisIsoImage(PyObject * s, PyObject * args); +static PyObject *printObject(PyObject * s, PyObject * args); +static PyObject *py_bind_textdomain_codeset(PyObject * o, PyObject * args); +static PyObject *py_getDasdPorts(PyObject * s, PyObject * args); +static PyObject *py_isUsableDasd(PyObject * s, PyObject * args); +static PyObject *py_isLdlDasd(PyObject * s, PyObject * args); +static PyObject *doProbeBiosDisks(PyObject * s, PyObject * args); +static PyObject *doGetBiosDisk(PyObject * s, PyObject * args); +static PyObject *doSegvHandler(PyObject * s, PyObject * args); +static PyObject *doAuditDaemon(PyObject * s); +static PyObject *doPrefixToNetmask(PyObject * s, PyObject * args); +static PyObject *doGetBlkidData(PyObject * s, PyObject * args); +static PyObject *doIsCapsLockEnabled(PyObject * s, PyObject * args); +static PyObject *doGetLinkStatus(PyObject * s, PyObject * args); +static PyObject *doGetAnacondaVersion(PyObject * s, PyObject * args); static PyMethodDef isysModuleMethods[] = { - { "ejectcdrom", (PyCFunction) doEjectCdrom, METH_VARARGS, NULL }, - { "e2dirty", (PyCFunction) doExt2Dirty, METH_VARARGS, NULL }, - { "e2hasjournal", (PyCFunction) doExt2HasJournal, METH_VARARGS, NULL }, - { "devSpaceFree", (PyCFunction) doDevSpaceFree, METH_VARARGS, NULL }, - { "wiperaidsb", (PyCFunction) doWipeRaidSuperblock, METH_VARARGS, NULL }, - { "getraidchunk", (PyCFunction) doGetRaidChunkSize, METH_VARARGS, NULL }, - { "lochangefd", (PyCFunction) doLoChangeFd, METH_VARARGS, NULL }, - { "losetup", (PyCFunction) doLoSetup, METH_VARARGS, NULL }, - { "unlosetup", (PyCFunction) doUnLoSetup, METH_VARARGS, NULL }, - { "mount", (PyCFunction) doMount, METH_VARARGS, NULL }, - { "umount", (PyCFunction) doUMount, METH_VARARGS, NULL }, - { "resetresolv", (PyCFunction) doResetResolv, METH_VARARGS, NULL }, - { "swapon", (PyCFunction) doSwapon, METH_VARARGS, NULL }, - { "swapoff", (PyCFunction) doSwapoff, METH_VARARGS, NULL }, - { "loadKeymap", (PyCFunction) doLoadKeymap, METH_VARARGS, NULL }, - { "vtActivate", (PyCFunction) doVtActivate, METH_VARARGS, NULL}, - { "isPseudoTTY", (PyCFunction) doisPseudoTTY, METH_VARARGS, NULL}, - { "isVioConsole", (PyCFunction) doisVioConsole, METH_NOARGS, NULL}, - { "sync", (PyCFunction) doSync, METH_VARARGS, NULL}, - { "isisoimage", (PyCFunction) doisIsoImage, METH_VARARGS, NULL}, - { "printObject", (PyCFunction) printObject, METH_VARARGS, NULL}, - { "bind_textdomain_codeset", (PyCFunction) py_bind_textdomain_codeset, METH_VARARGS, NULL}, - { "getDasdPorts", (PyCFunction) py_getDasdPorts, METH_VARARGS, NULL}, - { "isUsableDasd", (PyCFunction) py_isUsableDasd, METH_VARARGS, NULL}, - { "isLdlDasd", (PyCFunction) py_isLdlDasd, METH_VARARGS, NULL}, - { "biosDiskProbe", (PyCFunction) doProbeBiosDisks, METH_VARARGS,NULL}, - { "getbiosdisk",(PyCFunction) doGetBiosDisk, METH_VARARGS,NULL}, - { "handleSegv", (PyCFunction) doSegvHandler, METH_VARARGS, NULL }, - { "auditdaemon", (PyCFunction) doAuditDaemon, METH_NOARGS, NULL }, - { "prefix2netmask", (PyCFunction) doPrefixToNetmask, METH_VARARGS, NULL }, - { "getblkid", (PyCFunction) doGetBlkidData, METH_VARARGS, NULL }, - { "isCapsLockEnabled", (PyCFunction) doIsCapsLockEnabled, METH_VARARGS, NULL }, - { "getLinkStatus", (PyCFunction) doGetLinkStatus, METH_VARARGS, NULL }, - { "getAnacondaVersion", (PyCFunction) doGetAnacondaVersion, METH_VARARGS, NULL }, - { NULL, NULL, 0, NULL } -} ; - -static PyObject * doUnLoSetup(PyObject * s, PyObject * args) { - int loopfd; - - if (!PyArg_ParseTuple(args, "i", &loopfd)) return NULL; - if (ioctl(loopfd, LOOP_CLR_FD, 0)) { - PyErr_SetFromErrno(PyExc_SystemError); - return NULL; - } + {"ejectcdrom", (PyCFunction) doEjectCdrom, METH_VARARGS, NULL}, + {"e2dirty", (PyCFunction) doExt2Dirty, METH_VARARGS, NULL}, + {"e2hasjournal", (PyCFunction) doExt2HasJournal, METH_VARARGS, NULL}, + {"devSpaceFree", (PyCFunction) doDevSpaceFree, METH_VARARGS, NULL}, + {"wiperaidsb", (PyCFunction) doWipeRaidSuperblock, METH_VARARGS, NULL}, + {"getraidchunk", (PyCFunction) doGetRaidChunkSize, METH_VARARGS, NULL}, + {"lochangefd", (PyCFunction) doLoChangeFd, METH_VARARGS, NULL}, + {"losetup", (PyCFunction) doLoSetup, METH_VARARGS, NULL}, + {"unlosetup", (PyCFunction) doUnLoSetup, METH_VARARGS, NULL}, + {"mount", (PyCFunction) doMount, METH_VARARGS, NULL}, + {"umount", (PyCFunction) doUMount, METH_VARARGS, NULL}, + {"resetresolv", (PyCFunction) doResetResolv, METH_VARARGS, NULL}, + {"swapon", (PyCFunction) doSwapon, METH_VARARGS, NULL}, + {"swapoff", (PyCFunction) doSwapoff, METH_VARARGS, NULL}, + {"loadKeymap", (PyCFunction) doLoadKeymap, METH_VARARGS, NULL}, + {"vtActivate", (PyCFunction) doVtActivate, METH_VARARGS, NULL}, + {"isPseudoTTY", (PyCFunction) doisPseudoTTY, METH_VARARGS, NULL}, + {"isVioConsole", (PyCFunction) doisVioConsole, METH_NOARGS, NULL}, + {"sync", (PyCFunction) doSync, METH_VARARGS, NULL}, + {"isisoimage", (PyCFunction) doisIsoImage, METH_VARARGS, NULL}, + {"printObject", (PyCFunction) printObject, METH_VARARGS, NULL}, + {"bind_textdomain_codeset", (PyCFunction) py_bind_textdomain_codeset, + METH_VARARGS, NULL}, + {"getDasdPorts", (PyCFunction) py_getDasdPorts, METH_VARARGS, NULL}, + {"isUsableDasd", (PyCFunction) py_isUsableDasd, METH_VARARGS, NULL}, + {"isLdlDasd", (PyCFunction) py_isLdlDasd, METH_VARARGS, NULL}, + {"biosDiskProbe", (PyCFunction) doProbeBiosDisks, METH_VARARGS, NULL}, + {"getbiosdisk", (PyCFunction) doGetBiosDisk, METH_VARARGS, NULL}, + {"handleSegv", (PyCFunction) doSegvHandler, METH_VARARGS, NULL}, + {"auditdaemon", (PyCFunction) doAuditDaemon, METH_NOARGS, NULL}, + {"prefix2netmask", (PyCFunction) doPrefixToNetmask, METH_VARARGS, NULL}, + {"getblkid", (PyCFunction) doGetBlkidData, METH_VARARGS, NULL}, + {"isCapsLockEnabled", (PyCFunction) doIsCapsLockEnabled, METH_VARARGS, + NULL}, + {"getLinkStatus", (PyCFunction) doGetLinkStatus, METH_VARARGS, NULL}, + {"getAnacondaVersion", (PyCFunction) doGetAnacondaVersion, METH_VARARGS, + NULL}, + {NULL, NULL, 0, NULL} +}; + +static PyObject *doUnLoSetup(PyObject * s, PyObject * args) +{ + int loopfd; + + if (!PyArg_ParseTuple(args, "i", &loopfd)) + return NULL; + if (ioctl(loopfd, LOOP_CLR_FD, 0)) { + PyErr_SetFromErrno(PyExc_SystemError); + return NULL; + } - Py_INCREF(Py_None); - return Py_None; + Py_INCREF(Py_None); + return Py_None; } /* XXX - msw */ @@ -172,565 +177,637 @@ static PyObject * doUnLoSetup(PyObject * s, PyObject * args) { #define LOOP_CHANGE_FD 0x4C06 #endif -static PyObject * doLoChangeFd(PyObject * s, PyObject * args) { - int loopfd; - int targfd; +static PyObject *doLoChangeFd(PyObject * s, PyObject * args) +{ + int loopfd; + int targfd; - if (!PyArg_ParseTuple(args, "ii", &loopfd, &targfd)) - return NULL; - if (ioctl(loopfd, LOOP_CHANGE_FD, targfd)) { - PyErr_SetFromErrno(PyExc_SystemError); - return NULL; - } + if (!PyArg_ParseTuple(args, "ii", &loopfd, &targfd)) + return NULL; + if (ioctl(loopfd, LOOP_CHANGE_FD, targfd)) { + PyErr_SetFromErrno(PyExc_SystemError); + return NULL; + } - Py_INCREF(Py_None); - return Py_None; + Py_INCREF(Py_None); + return Py_None; } -static PyObject * doLoSetup(PyObject * s, PyObject * args) { - int loopfd; - int targfd; - struct loop_info loopInfo; - char * loopName; +static PyObject *doLoSetup(PyObject * s, PyObject * args) +{ + int loopfd; + int targfd; + struct loop_info loopInfo; + char *loopName; - if (!PyArg_ParseTuple(args, "iis", &loopfd, &targfd, &loopName)) - return NULL; - if (ioctl(loopfd, LOOP_SET_FD, targfd)) { - PyErr_SetFromErrno(PyExc_SystemError); - return NULL; - } + if (!PyArg_ParseTuple(args, "iis", &loopfd, &targfd, &loopName)) + return NULL; + if (ioctl(loopfd, LOOP_SET_FD, targfd)) { + PyErr_SetFromErrno(PyExc_SystemError); + return NULL; + } - memset(&loopInfo, 0, sizeof(loopInfo)); - strncpy(loopInfo.lo_name, basename(loopName), 63); + memset(&loopInfo, 0, sizeof(loopInfo)); + strncpy(loopInfo.lo_name, basename(loopName), 63); - if (ioctl(loopfd, LOOP_SET_STATUS, &loopInfo)) { - PyErr_SetFromErrno(PyExc_SystemError); - return NULL; - } + if (ioctl(loopfd, LOOP_SET_STATUS, &loopInfo)) { + PyErr_SetFromErrno(PyExc_SystemError); + return NULL; + } - Py_INCREF(Py_None); - return Py_None; + Py_INCREF(Py_None); + return Py_None; } -static PyObject * doUMount(PyObject * s, PyObject * args) { - char *err = NULL, *mntpoint = NULL; - int rc; +static PyObject *doUMount(PyObject * s, PyObject * args) +{ + char *err = NULL, *mntpoint = NULL; + int rc; - if (!PyArg_ParseTuple(args, "s", &mntpoint)) { - return NULL; - } + if (!PyArg_ParseTuple(args, "s", &mntpoint)) { + return NULL; + } - rc = doPwUmount(mntpoint, &err); - if (rc == IMOUNT_ERR_ERRNO) { - PyErr_SetFromErrno(PyExc_SystemError); - } else if (rc) { - PyObject *tuple = PyTuple_New(2); + rc = doPwUmount(mntpoint, &err); + if (rc == IMOUNT_ERR_ERRNO) { + PyErr_SetFromErrno(PyExc_SystemError); + } else if (rc) { + PyObject *tuple = PyTuple_New(2); - PyTuple_SetItem(tuple, 0, PyInt_FromLong(rc)); + PyTuple_SetItem(tuple, 0, PyInt_FromLong(rc)); - if (err == NULL) { - Py_INCREF(Py_None); - PyTuple_SetItem(tuple, 1, Py_None); - } else { - PyTuple_SetItem(tuple, 1, PyString_FromString(err)); - } + if (err == NULL) { + Py_INCREF(Py_None); + PyTuple_SetItem(tuple, 1, Py_None); + } else { + PyTuple_SetItem(tuple, 1, PyString_FromString(err)); + } - PyErr_SetObject(PyExc_SystemError, tuple); - } + PyErr_SetObject(PyExc_SystemError, tuple); + } - if (rc) { - return NULL; - } + if (rc) { + return NULL; + } - Py_INCREF(Py_None); - return Py_None; + Py_INCREF(Py_None); + return Py_None; } -static PyObject * doMount(PyObject * s, PyObject * args) { - char *err = NULL, *fs, *device, *mntpoint, *flags = NULL; - int rc; +static PyObject *doMount(PyObject * s, PyObject * args) +{ + char *err = NULL, *fs, *device, *mntpoint, *flags = NULL; + int rc; - if (!PyArg_ParseTuple(args, "sss|z", &fs, &device, &mntpoint, - &flags)) return NULL; + if (!PyArg_ParseTuple(args, "sss|z", &fs, &device, &mntpoint, &flags)) + return NULL; - rc = doPwMount(device, mntpoint, fs, flags, &err); - if (rc == IMOUNT_ERR_ERRNO) - PyErr_SetFromErrno(PyExc_SystemError); - else if (rc) { - PyObject *tuple = PyTuple_New(2); + rc = doPwMount(device, mntpoint, fs, flags, &err); + if (rc == IMOUNT_ERR_ERRNO) + PyErr_SetFromErrno(PyExc_SystemError); + else if (rc) { + PyObject *tuple = PyTuple_New(2); - PyTuple_SetItem(tuple, 0, PyInt_FromLong(rc)); + PyTuple_SetItem(tuple, 0, PyInt_FromLong(rc)); - if (err == NULL) { - Py_INCREF(Py_None); - PyTuple_SetItem(tuple, 1, Py_None); - } else { - PyTuple_SetItem(tuple, 1, PyString_FromString(err)); - } + if (err == NULL) { + Py_INCREF(Py_None); + PyTuple_SetItem(tuple, 1, Py_None); + } else { + PyTuple_SetItem(tuple, 1, PyString_FromString(err)); + } - PyErr_SetObject(PyExc_SystemError, tuple); - } + PyErr_SetObject(PyExc_SystemError, tuple); + } - if (rc) return NULL; + if (rc) + return NULL; - Py_INCREF(Py_None); - return Py_None; + Py_INCREF(Py_None); + return Py_None; } #define BOOT_SIGNATURE 0xaa55 /* boot signature */ #define BOOT_SIG_OFFSET 510 /* boot signature offset */ -int swapoff(const char * path); -int swapon(const char * path, int priorty); +int swapoff(const char *path); +int swapon(const char *path, int priorty); -static PyObject * doSwapoff (PyObject * s, PyObject * args) { - char * path; +static PyObject *doSwapoff(PyObject * s, PyObject * args) +{ + char *path; - if (!PyArg_ParseTuple(args, "s", &path)) return NULL; + if (!PyArg_ParseTuple(args, "s", &path)) + return NULL; - if (swapoff (path)) { - PyErr_SetFromErrno(PyExc_SystemError); - return NULL; - } - - Py_INCREF(Py_None); - return Py_None; + if (swapoff(path)) { + PyErr_SetFromErrno(PyExc_SystemError); + return NULL; + } + + Py_INCREF(Py_None); + return Py_None; } -static PyObject * doSwapon (PyObject * s, PyObject * args) { - char * path; +static PyObject *doSwapon(PyObject * s, PyObject * args) +{ + char *path; - if (!PyArg_ParseTuple(args, "s", &path)) return NULL; + if (!PyArg_ParseTuple(args, "s", &path)) + return NULL; - if (swapon (path, 0)) { - PyErr_SetFromErrno(PyExc_SystemError); - return NULL; - } - - Py_INCREF(Py_None); - return Py_None; + if (swapon(path, 0)) { + PyErr_SetFromErrno(PyExc_SystemError); + return NULL; + } + + Py_INCREF(Py_None); + return Py_None; } -void init_isys(void) { - PyObject * m, * d; +void init_isys(void) +{ + PyObject *m, *d; - m = Py_InitModule("_isys", isysModuleMethods); - d = PyModule_GetDict(m); + m = Py_InitModule("_isys", isysModuleMethods); + d = PyModule_GetDict(m); - PyDict_SetItemString(d, "MIN_RAM", PyInt_FromLong(MIN_RAM)); - PyDict_SetItemString(d, "MIN_GUI_RAM", PyInt_FromLong(MIN_GUI_RAM)); - PyDict_SetItemString(d, "EARLY_SWAP_RAM", PyInt_FromLong(EARLY_SWAP_RAM)); + PyDict_SetItemString(d, "MIN_RAM", PyInt_FromLong(MIN_RAM)); + PyDict_SetItemString(d, "MIN_GUI_RAM", PyInt_FromLong(MIN_GUI_RAM)); + PyDict_SetItemString(d, "EARLY_SWAP_RAM", + PyInt_FromLong(EARLY_SWAP_RAM)); } -static PyObject * doPrefixToNetmask (PyObject * s, PyObject * args) { - int prefix = 0; - struct in_addr *mask = NULL; - char dst[INET_ADDRSTRLEN+1]; +static PyObject *doPrefixToNetmask(PyObject * s, PyObject * args) +{ + int prefix = 0; + struct in_addr *mask = NULL; + char dst[INET_ADDRSTRLEN + 1]; - if (!PyArg_ParseTuple(args, "i", &prefix)) - return NULL; + if (!PyArg_ParseTuple(args, "i", &prefix)) + return NULL; - if ((mask = iface_prefix2netmask(prefix)) == NULL) - return NULL; + if ((mask = iface_prefix2netmask(prefix)) == NULL) + return NULL; - if (inet_ntop(AF_INET, mask, dst, INET_ADDRSTRLEN) == NULL) - return NULL; + if (inet_ntop(AF_INET, mask, dst, INET_ADDRSTRLEN) == NULL) + return NULL; - return Py_BuildValue("s", dst); + return Py_BuildValue("s", dst); } -static PyObject * doResetResolv(PyObject * s, PyObject * args) { - if (!PyArg_ParseTuple(args, "")) { - return NULL; - } +static PyObject *doResetResolv(PyObject * s, PyObject * args) +{ + if (!PyArg_ParseTuple(args, "")) { + return NULL; + } - /* reinit the resolver so DNS changes take affect */ - res_init(); + /* reinit the resolver so DNS changes take affect */ + res_init(); - Py_INCREF(Py_None); - return Py_None; + Py_INCREF(Py_None); + return Py_None; } -static PyObject * doWipeRaidSuperblock(PyObject * s, PyObject * args) { - int fd; - unsigned long size; - struct mdp_super_t * sb; +static PyObject *doWipeRaidSuperblock(PyObject * s, PyObject * args) +{ + int fd; + unsigned long size; + struct mdp_super_t *sb; - if (!PyArg_ParseTuple(args, "i", &fd)) return NULL; + if (!PyArg_ParseTuple(args, "i", &fd)) + return NULL; - if (ioctl(fd, BLKGETSIZE, &size)) { - PyErr_SetFromErrno(PyExc_SystemError); - return NULL; - } + if (ioctl(fd, BLKGETSIZE, &size)) { + PyErr_SetFromErrno(PyExc_SystemError); + return NULL; + } - /* put the size in 1k blocks */ - size >>= 1; + /* put the size in 1k blocks */ + size >>= 1; - if (lseek64(fd, ((off64_t) 512) * (off64_t) MD_NEW_SIZE_SECTORS(size), SEEK_SET) < 0) { - PyErr_SetFromErrno(PyExc_SystemError); - return NULL; - } + if (lseek64 + (fd, ((off64_t) 512) * (off64_t) MD_NEW_SIZE_SECTORS(size), + SEEK_SET) < 0) { + PyErr_SetFromErrno(PyExc_SystemError); + return NULL; + } - sb = malloc(sizeof(mdp_super_t)); - sb = memset(sb, '\0', sizeof(mdp_super_t)); + sb = malloc(sizeof(mdp_super_t)); + sb = memset(sb, '\0', sizeof(mdp_super_t)); - if (write(fd, sb, sizeof(sb)) != sizeof(sb)) { - PyErr_SetFromErrno(PyExc_SystemError); - return NULL; - } + if (write(fd, sb, sizeof(sb)) != sizeof(sb)) { + PyErr_SetFromErrno(PyExc_SystemError); + return NULL; + } - return Py_None; + return Py_None; } -static PyObject * doGetRaidChunkSize(PyObject * s, PyObject * args) { - int fd; - unsigned long size; - mdp_super_t sb; +static PyObject *doGetRaidChunkSize(PyObject * s, PyObject * args) +{ + int fd; + unsigned long size; + mdp_super_t sb; + + if (!PyArg_ParseTuple(args, "i", &fd)) + return NULL; + + if (ioctl(fd, BLKGETSIZE, &size)) { + PyErr_SetFromErrno(PyExc_SystemError); + return NULL; + } + + /* put the size in 1k blocks */ + size >>= 1; + + if (lseek64 + (fd, ((off64_t) 512) * (off64_t) MD_NEW_SIZE_SECTORS(size), + SEEK_SET) < 0) { + PyErr_SetFromErrno(PyExc_SystemError); + return NULL; + } + + if (read(fd, &sb, sizeof(sb)) != sizeof(sb)) { + PyErr_SetFromErrno(PyExc_SystemError); + return NULL; + } + + if (sb.md_magic != MD_SB_MAGIC) { + PyErr_SetString(PyExc_ValueError, "bad md magic on device"); + return NULL; + } + + return Py_BuildValue("i", sb.chunk_size / 1024); +} + +static int get_bits(unsigned long long v) +{ + int b = 0; + + if (v & 0xffffffff00000000LLU) { + b += 32; + v >>= 32; + } + if (v & 0xffff0000LLU) { + b += 16; + v >>= 16; + } + if (v & 0xff00LLU) { + b += 8; + v >>= 8; + } + if (v & 0xf0LLU) { + b += 4; + v >>= 4; + } + if (v & 0xcLLU) { + b += 2; + v >>= 2; + } + if (v & 0x2LLU) + b++; + + return v ? b + 1 : b; +} + +static PyObject *doDevSpaceFree(PyObject * s, PyObject * args) +{ + char *path; + struct statfs sb; + unsigned long long size; + + if (!PyArg_ParseTuple(args, "s", &path)) + return NULL; + + if (statfs(path, &sb)) { + PyErr_SetFromErrno(PyExc_SystemError); + return NULL; + } + + /* Calculate a saturated addition to prevent oveflow. */ + if (get_bits(sb.f_bfree) + get_bits(sb.f_bsize) <= 64) + size = (unsigned long long)sb.f_bfree * sb.f_bsize; + else + size = ~0LLU; + + return PyLong_FromUnsignedLongLong(size >> 20); +} + +static PyObject *doLoadKeymap(PyObject * s, PyObject * args) +{ + char *keymap; + int ret; + + if (!PyArg_ParseTuple(args, "s", &keymap)) + return NULL; + + ret = isysLoadKeymap(keymap); + if (ret) { + errno = -ret; + PyErr_SetFromErrno(PyExc_SystemError); + return NULL; + } - if (!PyArg_ParseTuple(args, "i", &fd)) return NULL; + Py_INCREF(Py_None); + return Py_None; +} - if (ioctl(fd, BLKGETSIZE, &size)) { - PyErr_SetFromErrno(PyExc_SystemError); - return NULL; - } +static PyObject *doExt2Dirty(PyObject * s, PyObject * args) +{ + char *device; + ext2_filsys fsys; + int rc; + int clean; - /* put the size in 1k blocks */ - size >>= 1; + if (!PyArg_ParseTuple(args, "s", &device)) + return NULL; - if (lseek64(fd, ((off64_t) 512) * (off64_t) MD_NEW_SIZE_SECTORS(size), SEEK_SET) < 0) { - PyErr_SetFromErrno(PyExc_SystemError); - return NULL; - } + rc = ext2fs_open(device, EXT2_FLAG_FORCE, 0, 0, unix_io_manager, &fsys); + if (rc) { + Py_INCREF(Py_None); + return Py_None; + } - if (read(fd, &sb, sizeof(sb)) != sizeof(sb)) { - PyErr_SetFromErrno(PyExc_SystemError); - return NULL; - } + clean = fsys->super->s_state & EXT2_VALID_FS; - if (sb.md_magic != MD_SB_MAGIC) { - PyErr_SetString(PyExc_ValueError, "bad md magic on device"); - return NULL; - } - - return Py_BuildValue("i", sb.chunk_size / 1024); -} + ext2fs_close(fsys); -static int get_bits(unsigned long long v) { - int b = 0; - - if ( v & 0xffffffff00000000LLU ) { b += 32; v >>= 32; } - if ( v & 0xffff0000LLU ) { b += 16; v >>= 16; } - if ( v & 0xff00LLU ) { b += 8; v >>= 8; } - if ( v & 0xf0LLU ) { b += 4; v >>= 4; } - if ( v & 0xcLLU ) { b += 2; v >>= 2; } - if ( v & 0x2LLU ) b++; - - return v ? b + 1 : b; + return Py_BuildValue("i", !clean); } -static PyObject * doDevSpaceFree(PyObject * s, PyObject * args) { - char * path; - struct statfs sb; - unsigned long long size; +static PyObject *doExt2HasJournal(PyObject * s, PyObject * args) +{ + char *device; + ext2_filsys fsys; + int rc; + int hasjournal; - if (!PyArg_ParseTuple(args, "s", &path)) return NULL; + if (!PyArg_ParseTuple(args, "s", &device)) + return NULL; + rc = ext2fs_open(device, EXT2_FLAG_FORCE, 0, 0, unix_io_manager, &fsys); + if (rc) { + Py_INCREF(Py_None); + return Py_None; + } - if (statfs(path, &sb)) { - PyErr_SetFromErrno(PyExc_SystemError); - return NULL; - } + hasjournal = + fsys->super->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL; - /* Calculate a saturated addition to prevent oveflow. */ - if ( get_bits(sb.f_bfree) + get_bits(sb.f_bsize) <= 64 ) - size = (unsigned long long)sb.f_bfree * sb.f_bsize; - else - size = ~0LLU; + ext2fs_close(fsys); - return PyLong_FromUnsignedLongLong(size>>20); + return Py_BuildValue("i", hasjournal); } -static PyObject * doLoadKeymap (PyObject * s, PyObject * args) { - char * keymap; - int ret; - - if (!PyArg_ParseTuple(args, "s", &keymap)) return NULL; +static PyObject *doEjectCdrom(PyObject * s, PyObject * args) +{ + int fd; - ret = isysLoadKeymap (keymap); - if (ret) { - errno = -ret; - PyErr_SetFromErrno(PyExc_SystemError); - return NULL; - } - - Py_INCREF(Py_None); - return Py_None; -} + if (!PyArg_ParseTuple(args, "i", &fd)) + return NULL; -static PyObject * doExt2Dirty(PyObject * s, PyObject * args) { - char * device; - ext2_filsys fsys; - int rc; - int clean; + if (ioctl(fd, CDROMEJECT, 1)) { + PyErr_SetFromErrno(PyExc_SystemError); + return NULL; + } - if (!PyArg_ParseTuple(args, "s", &device)) return NULL; - - rc = ext2fs_open(device, EXT2_FLAG_FORCE, 0, 0, unix_io_manager, - &fsys); - if (rc) { Py_INCREF(Py_None); return Py_None; - } +} - clean = fsys->super->s_state & EXT2_VALID_FS; +static PyObject *doVtActivate(PyObject * s, PyObject * args) +{ + int vtnum; - ext2fs_close(fsys); + if (!PyArg_ParseTuple(args, "i", &vtnum)) + return NULL; - return Py_BuildValue("i", !clean); -} -static PyObject * doExt2HasJournal(PyObject * s, PyObject * args) { - char * device; - ext2_filsys fsys; - int rc; - int hasjournal; + if (ioctl(0, VT_ACTIVATE, vtnum)) { + PyErr_SetFromErrno(PyExc_SystemError); + return NULL; + } - if (!PyArg_ParseTuple(args, "s", &device)) return NULL; - rc = ext2fs_open(device, EXT2_FLAG_FORCE, 0, 0, unix_io_manager, - &fsys); - if (rc) { Py_INCREF(Py_None); return Py_None; - } +} - hasjournal = fsys->super->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL; +static PyObject *doisPseudoTTY(PyObject * s, PyObject * args) +{ + int fd; + struct stat sb; - ext2fs_close(fsys); + if (!PyArg_ParseTuple(args, "i", &fd)) + return NULL; + fstat(fd, &sb); - return Py_BuildValue("i", hasjournal); + /* XXX close enough for now */ + return Py_BuildValue("i", ((major(sb.st_rdev) >= 136) + && (major(sb.st_rdev) <= 143))); } -static PyObject * doEjectCdrom(PyObject * s, PyObject * args) { - int fd; +static PyObject *doisVioConsole(PyObject * s) +{ + return Py_BuildValue("i", isVioConsole()); +} - if (!PyArg_ParseTuple(args, "i", &fd)) return NULL; +static PyObject *doSync(PyObject * s, PyObject * args) +{ + int fd; - if (ioctl(fd, CDROMEJECT, 1)) { - PyErr_SetFromErrno(PyExc_SystemError); - return NULL; - } + if (!PyArg_ParseTuple(args, "", &fd)) + return NULL; + sync(); - Py_INCREF(Py_None); - return Py_None; + Py_INCREF(Py_None); + return Py_None; } -static PyObject * doVtActivate(PyObject * s, PyObject * args) { - int vtnum; +int fileIsIso(const char *file); - if (!PyArg_ParseTuple(args, "i", &vtnum)) return NULL; +static PyObject *doisIsoImage(PyObject * s, PyObject * args) +{ + char *fn; + int rc; - if (ioctl(0, VT_ACTIVATE, vtnum)) { - PyErr_SetFromErrno(PyExc_SystemError); - return NULL; - } + if (!PyArg_ParseTuple(args, "s", &fn)) + return NULL; - Py_INCREF(Py_None); - return Py_None; -} + rc = fileIsIso(fn); -static PyObject * doisPseudoTTY(PyObject * s, PyObject * args) { - int fd; - struct stat sb; + return Py_BuildValue("i", rc); +} - if (!PyArg_ParseTuple(args, "i", &fd)) return NULL; - fstat(fd, &sb); +static PyObject *py_getDasdPorts(PyObject * o, PyObject * args) +{ + if (!PyArg_ParseTuple(args, "")) + return NULL; - /* XXX close enough for now */ - return Py_BuildValue("i", ((major(sb.st_rdev) >= 136) && (major(sb.st_rdev) <= 143))); + return Py_BuildValue("s", getDasdPorts()); } -static PyObject * doisVioConsole(PyObject * s) { - return Py_BuildValue("i", isVioConsole()); +static PyObject *py_isUsableDasd(PyObject * o, PyObject * args) +{ + char *devname; + if (!PyArg_ParseTuple(args, "s", &devname)) + return NULL; + return Py_BuildValue("i", isUsableDasd(devname)); } -static PyObject * doSync(PyObject * s, PyObject * args) { - int fd; - - if (!PyArg_ParseTuple(args, "", &fd)) return NULL; - sync(); - - Py_INCREF(Py_None); - return Py_None; +static PyObject *py_isLdlDasd(PyObject * o, PyObject * args) +{ + char *devname; + if (!PyArg_ParseTuple(args, "s", &devname)) + return NULL; + return Py_BuildValue("i", isLdlDasd(devname)); } -int fileIsIso(const char * file); +static PyObject *printObject(PyObject * o, PyObject * args) +{ + PyObject *obj; + char buf[256]; -static PyObject * doisIsoImage(PyObject * s, PyObject * args) { - char * fn; - int rc; + if (!PyArg_ParseTuple(args, "O", &obj)) + return NULL; - if (!PyArg_ParseTuple(args, "s", &fn)) return NULL; + snprintf(buf, 256, "<%s object at %lx>", obj->ob_type->tp_name, + (long)obj); - rc = fileIsIso(fn); - - return Py_BuildValue("i", rc); + return PyString_FromString(buf); } -static PyObject * py_getDasdPorts(PyObject * o, PyObject * args) { - if (!PyArg_ParseTuple(args, "")) return NULL; +static PyObject *py_bind_textdomain_codeset(PyObject * o, PyObject * args) +{ + char *domain, *codeset, *ret; - return Py_BuildValue("s", getDasdPorts()); -} - -static PyObject * py_isUsableDasd(PyObject * o, PyObject * args) { - char *devname; - if (!PyArg_ParseTuple(args, "s", &devname)) - return NULL; - return Py_BuildValue("i", isUsableDasd(devname)); -} - -static PyObject * py_isLdlDasd(PyObject * o, PyObject * args) { - char *devname; - if (!PyArg_ParseTuple(args, "s", &devname)) - return NULL; - return Py_BuildValue("i", isLdlDasd(devname)); -} + if (!PyArg_ParseTuple(args, "ss", &domain, &codeset)) + return NULL; + ret = bind_textdomain_codeset(domain, codeset); -static PyObject * printObject (PyObject * o, PyObject * args) { - PyObject * obj; - char buf[256]; + if (ret) + return PyString_FromString(ret); - if (!PyArg_ParseTuple(args, "O", &obj)) + PyErr_SetFromErrno(PyExc_SystemError); return NULL; - - snprintf(buf, 256, "<%s object at %lx>", obj->ob_type->tp_name, - (long) obj); - - return PyString_FromString(buf); } -static PyObject * -py_bind_textdomain_codeset(PyObject * o, PyObject * args) { - char *domain, *codeset, *ret; - - if (!PyArg_ParseTuple(args, "ss", &domain, &codeset)) - return NULL; - - ret = bind_textdomain_codeset(domain, codeset); - - if (ret) - return PyString_FromString(ret); +static PyObject *doProbeBiosDisks(PyObject * s, PyObject * args) +{ + if (!PyArg_ParseTuple(args, "")) + return NULL; - PyErr_SetFromErrno(PyExc_SystemError); - return NULL; + return Py_BuildValue("i", probeBiosDisks()); } -static PyObject * doProbeBiosDisks(PyObject * s, PyObject * args) { - if (!PyArg_ParseTuple(args, "")) return NULL; +static PyObject *doGetBiosDisk(PyObject * s, PyObject * args) +{ + char *mbr_sig; + char *diskname; + if (!PyArg_ParseTuple(args, "s", &mbr_sig)) + return NULL; - return Py_BuildValue("i", probeBiosDisks()); + if ((diskname = getBiosDisk(mbr_sig))) + return Py_BuildValue("s", diskname); + + Py_INCREF(Py_None); + return Py_None; } -static PyObject * doGetBiosDisk(PyObject * s, PyObject * args) { - char *mbr_sig; - char *diskname; - - if (!PyArg_ParseTuple(args, "s", &mbr_sig)) return NULL; +static PyObject *doSegvHandler(PyObject * s, PyObject * args) +{ + void *array[20]; + size_t size; + char **strings; + size_t i; - if ((diskname = getBiosDisk(mbr_sig))) - return Py_BuildValue("s", diskname); + signal(SIGSEGV, SIG_DFL); /* back to default */ - Py_INCREF(Py_None); - return Py_None; -} + size = backtrace(array, 20); + strings = backtrace_symbols(array, size); -static PyObject * doSegvHandler(PyObject *s, PyObject *args) { - void *array[20]; - size_t size; - char **strings; - size_t i; + printf("Anaconda received SIGSEGV!. Backtrace:\n"); + for (i = 0; i < size; i++) + printf("%s\n", strings[i]); - signal(SIGSEGV, SIG_DFL); /* back to default */ - - size = backtrace (array, 20); - strings = backtrace_symbols (array, size); - - printf ("Anaconda received SIGSEGV!. Backtrace:\n"); - for (i = 0; i < size; i++) - printf ("%s\n", strings[i]); - - free (strings); - exit(1); + free(strings); + exit(1); } -static PyObject * doAuditDaemon(PyObject *s) { - audit_daemonize(); - Py_INCREF(Py_None); - return Py_None; +static PyObject *doAuditDaemon(PyObject * s) +{ + audit_daemonize(); + Py_INCREF(Py_None); + return Py_None; } -static PyObject * doGetBlkidData(PyObject * s, PyObject * args) { - char * dev, * key; - blkid_cache cache; - blkid_dev bdev = NULL; - blkid_tag_iterate titer; - const char * type, * data; - - if (!PyArg_ParseTuple(args, "ss", &dev, &key)) return NULL; - - blkid_get_cache(&cache, NULL); - - bdev = blkid_get_dev(cache, dev, BLKID_DEV_NORMAL); - if (bdev == NULL) - goto out; - titer = blkid_tag_iterate_begin(bdev); - while (blkid_tag_next(titer, &type, &data) >= 0) { - if (!strcmp(type, key)) { - blkid_tag_iterate_end(titer); - return Py_BuildValue("s", data); - } - } - blkid_tag_iterate_end(titer); - - out: - Py_INCREF(Py_None); - return Py_None; +static PyObject *doGetBlkidData(PyObject * s, PyObject * args) +{ + char *dev, *key; + blkid_cache cache; + blkid_dev bdev = NULL; + blkid_tag_iterate titer; + const char *type, *data; + + if (!PyArg_ParseTuple(args, "ss", &dev, &key)) + return NULL; + + blkid_get_cache(&cache, NULL); + + bdev = blkid_get_dev(cache, dev, BLKID_DEV_NORMAL); + if (bdev == NULL) + goto out; + titer = blkid_tag_iterate_begin(bdev); + while (blkid_tag_next(titer, &type, &data) >= 0) { + if (!strcmp(type, key)) { + blkid_tag_iterate_end(titer); + return Py_BuildValue("s", data); + } + } + blkid_tag_iterate_end(titer); + +out: + Py_INCREF(Py_None); + return Py_None; } -static PyObject * doIsCapsLockEnabled(PyObject * s, PyObject * args) { - Display *d = NULL; - XkbStateRec state; +static PyObject *doIsCapsLockEnabled(PyObject * s, PyObject * args) +{ + Display *d = NULL; + XkbStateRec state; - if ((d = XOpenDisplay(NULL)) == NULL) { - return NULL; - } + if ((d = XOpenDisplay(NULL)) == NULL) { + return NULL; + } - memset(&state, 0, sizeof(state)); - XkbGetState(d, XkbUseCoreKbd, &state); + memset(&state, 0, sizeof(state)); + XkbGetState(d, XkbUseCoreKbd, &state); - if (XCloseDisplay(d)) { - return NULL; - } + if (XCloseDisplay(d)) { + return NULL; + } - return PyBool_FromLong(state.locked_mods & LockMask); + return PyBool_FromLong(state.locked_mods & LockMask); } -static PyObject * doGetLinkStatus(PyObject * s, PyObject * args) { - char *dev = NULL; +static PyObject *doGetLinkStatus(PyObject * s, PyObject * args) +{ + char *dev = NULL; - if (!PyArg_ParseTuple(args, "s", &dev)) { - return NULL; - } + if (!PyArg_ParseTuple(args, "s", &dev)) { + return NULL; + } - if (get_link_status(dev) == 1) { - return PyBool_FromLong(1); - } + if (get_link_status(dev) == 1) { + return PyBool_FromLong(1); + } - return PyBool_FromLong(0); + return PyBool_FromLong(0); } -static PyObject * doGetAnacondaVersion(PyObject * s, PyObject * args) { - return Py_BuildValue("s", VERSION); +static PyObject *doGetAnacondaVersion(PyObject * s, PyObject * args) +{ + return Py_BuildValue("s", VERSION); } /* vim:set sw=8 noet */ diff --git a/isys/isys.h b/isys/isys.h index 439896c..f8698c0 100644 --- a/isys/isys.h +++ b/isys/isys.h @@ -26,18 +26,18 @@ #define OUTPUT_TERMINAL "/dev/tty5" -int insmod(char * modName, char * path, char ** args); -int rmmod(char * modName); +int insmod(char *modName, char *path, char **args); +int rmmod(char *modName); /* returns 0 for true, !0 for false */ -int fileIsIso(const char * file); +int fileIsIso(const char *file); /* returns 1 if on an iSeries vio console, 0 otherwise */ int isVioConsole(void); /* dasd functions */ char *getDasdPorts(); -int isLdlDasd(char * dev); +int isLdlDasd(char *dev); int isUsableDasd(char *device); #endif diff --git a/isys/lang.c b/isys/lang.c index b038bb4..17a4abf 100644 --- a/isys/lang.c +++ b/isys/lang.c @@ -40,170 +40,182 @@ #include "lang.h" #include "stubs.h" -int isysLoadFont(void) { - unsigned char font[65536]; - struct console_font_op cfo; - unsigned short map[E_TABSZ]; - struct unimapdesc d; - struct unimapinit u; - struct unipair desc[2048]; - gzFile stream; - int rc; +int isysLoadFont(void) +{ + unsigned char font[65536]; + struct console_font_op cfo; + unsigned short map[E_TABSZ]; + struct unimapdesc d; + struct unimapinit u; + struct unipair desc[2048]; + gzFile stream; + int rc; #if defined (__s390__) || defined (__s390x__) - return 0; + return 0; #endif - stream = gunzip_open("/etc/screenfont.gz"); - if (!stream) - return -EACCES; - - gunzip_read(stream, &cfo, sizeof(cfo)); - gunzip_read(stream, font, sizeof(font)); - gunzip_read(stream, map, sizeof(map)); - gunzip_read(stream, &d.entry_ct, sizeof(d.entry_ct)); - d.entries = desc; - gunzip_read(stream, desc, d.entry_ct * sizeof(desc[0])); - gunzip_close(stream); - - cfo.data = font; - cfo.op = KD_FONT_OP_SET; - - rc = ioctl(1, KDFONTOP, &cfo); - if (rc) return rc; - rc = ioctl(1, PIO_UNIMAPCLR, &u); - if (rc) return rc; - rc = ioctl(1, PIO_UNIMAP, &d); - if (rc) return rc; - rc = ioctl(1, PIO_UNISCRNMAP, map); - if (rc) return rc; - /* activate the font map */ - fprintf(stderr, "\033(K"); - return 0; + stream = gunzip_open("/etc/screenfont.gz"); + if (!stream) + return -EACCES; + + gunzip_read(stream, &cfo, sizeof(cfo)); + gunzip_read(stream, font, sizeof(font)); + gunzip_read(stream, map, sizeof(map)); + gunzip_read(stream, &d.entry_ct, sizeof(d.entry_ct)); + d.entries = desc; + gunzip_read(stream, desc, d.entry_ct * sizeof(desc[0])); + gunzip_close(stream); + + cfo.data = font; + cfo.op = KD_FONT_OP_SET; + + rc = ioctl(1, KDFONTOP, &cfo); + if (rc) + return rc; + rc = ioctl(1, PIO_UNIMAPCLR, &u); + if (rc) + return rc; + rc = ioctl(1, PIO_UNIMAP, &d); + if (rc) + return rc; + rc = ioctl(1, PIO_UNISCRNMAP, map); + if (rc) + return rc; + /* activate the font map */ + fprintf(stderr, "\033(K"); + return 0; } -int isysSetUnicodeKeymap(void) { - int console; +int isysSetUnicodeKeymap(void) +{ + int console; #if defined (__s390__) || defined (__s390x__) - return 0; + return 0; #endif - console = open("/dev/console", O_RDWR); - if (console < 0) - return -EACCES; - - /* place keyboard in unicode mode */ - ioctl(console, KDSKBMODE, K_UNICODE); - close(console); - return 0; + console = open("/dev/console", O_RDWR); + if (console < 0) + return -EACCES; + + /* place keyboard in unicode mode */ + ioctl(console, KDSKBMODE, K_UNICODE); + close(console); + return 0; } /* the file pointer must be at the beginning of the section already! */ -int loadKeymap(gzFile stream) { - int console; - int kmap, key; - struct kbentry entry; - int keymaps[MAX_NR_KEYMAPS]; - int count = 0; - unsigned int magic; - short keymap[NR_KEYS]; - struct stat sb; +int loadKeymap(gzFile stream) +{ + int console; + int kmap, key; + struct kbentry entry; + int keymaps[MAX_NR_KEYMAPS]; + int count = 0; + unsigned int magic; + short keymap[NR_KEYS]; + struct stat sb; #if defined (__s390__) || defined (__s390x__) - return 0; + return 0; #endif - if (isVioConsole()) - return 0; + if (isVioConsole()) + return 0; - /* assume that if we're already on a pty loading a keymap is silly */ - fstat(0, &sb); - if (major(sb.st_rdev) == 3 || major(sb.st_rdev) == 136) - return 0; + /* assume that if we're already on a pty loading a keymap is silly */ + fstat(0, &sb); + if (major(sb.st_rdev) == 3 || major(sb.st_rdev) == 136) + return 0; - if (gunzip_read(stream, &magic, sizeof(magic)) != sizeof(magic)) - return -EIO; + if (gunzip_read(stream, &magic, sizeof(magic)) != sizeof(magic)) + return -EIO; - if (magic != KMAP_MAGIC) return -EINVAL; + if (magic != KMAP_MAGIC) + return -EINVAL; - if (gunzip_read(stream, keymaps, sizeof(keymaps)) != sizeof(keymaps)) - return -EINVAL; + if (gunzip_read(stream, keymaps, sizeof(keymaps)) != sizeof(keymaps)) + return -EINVAL; - console = open("/dev/tty0", O_RDWR); - if (console < 0) - return -EACCES; + console = open("/dev/tty0", O_RDWR); + if (console < 0) + return -EACCES; - for (kmap = 0; kmap < MAX_NR_KEYMAPS; kmap++) { - if (!keymaps[kmap]) continue; + for (kmap = 0; kmap < MAX_NR_KEYMAPS; kmap++) { + if (!keymaps[kmap]) + continue; - if (gunzip_read(stream, keymap, sizeof(keymap)) != sizeof(keymap)) { - close(console); - return -EIO; - } + if (gunzip_read(stream, keymap, sizeof(keymap)) != + sizeof(keymap)) { + close(console); + return -EIO; + } - count++; - for (key = 0; key < NR_KEYS; key++) { - entry.kb_index = key; - entry.kb_table = kmap; - entry.kb_value = keymap[key]; - if (KTYP(entry.kb_value) != KT_SPEC) { - if (ioctl(console, KDSKBENT, &entry)) { - int ret = errno; - close(console); - return ret; + count++; + for (key = 0; key < NR_KEYS; key++) { + entry.kb_index = key; + entry.kb_table = kmap; + entry.kb_value = keymap[key]; + if (KTYP(entry.kb_value) != KT_SPEC) { + if (ioctl(console, KDSKBENT, &entry)) { + int ret = errno; + close(console); + return ret; + } + } } - } } - } - close(console); - return 0; + close(console); + return 0; } -int isysLoadKeymap(char * keymap) { - int num = -1; - int rc; - gzFile f; - struct kmapHeader hdr; - struct kmapInfo * infoTable; - char buf[16384]; /* I hope this is big enough */ - int i; - - f = gunzip_open("/etc/keymaps.gz"); - if (!f) return -EACCES; +int isysLoadKeymap(char *keymap) +{ + int num = -1; + int rc; + gzFile f; + struct kmapHeader hdr; + struct kmapInfo *infoTable; + char buf[16384]; /* I hope this is big enough */ + int i; + + f = gunzip_open("/etc/keymaps.gz"); + if (!f) + return -EACCES; + + if (gunzip_read(f, &hdr, sizeof(hdr)) != sizeof(hdr)) { + gunzip_close(f); + return -EINVAL; + } - if (gunzip_read(f, &hdr, sizeof(hdr)) != sizeof(hdr)) { - gunzip_close(f); - return -EINVAL; - } + i = hdr.numEntries * sizeof(*infoTable); + infoTable = alloca(i); + if (gunzip_read(f, infoTable, i) != i) { + gunzip_close(f); + return -EIO; + } - i = hdr.numEntries * sizeof(*infoTable); - infoTable = alloca(i); - if (gunzip_read(f, infoTable, i) != i) { - gunzip_close(f); - return -EIO; - } + for (i = 0; i < hdr.numEntries; i++) + if (!strcmp(infoTable[i].name, keymap)) { + num = i; + break; + } - for (i = 0; i < hdr.numEntries; i++) - if (!strcmp(infoTable[i].name, keymap)) { - num = i; - break; + if (num == -1) { + gunzip_close(f); + return -ENOENT; } - if (num == -1) { - gunzip_close(f); - return -ENOENT; - } - - for (i = 0; i < num; i++) { - if (gunzip_read(f, buf, infoTable[i].size) != infoTable[i].size) { - gunzip_close(f); - return -EIO; + for (i = 0; i < num; i++) { + if (gunzip_read(f, buf, infoTable[i].size) != infoTable[i].size) { + gunzip_close(f); + return -EIO; + } } - } - rc = loadKeymap(f); + rc = loadKeymap(f); - gunzip_close(f); + gunzip_close(f); - return rc; + return rc; } /* vim:set sw=8 noet */ diff --git a/isys/lang.h b/isys/lang.h index 5002091..1de654b 100644 --- a/isys/lang.h +++ b/isys/lang.h @@ -24,21 +24,21 @@ /* define ask johnsonm@xxxxxxxxxx where this came from */ #define KMAP_MAGIC 0x8B39C07F -#define KMAP_NAMELEN 40 /* including '\0' */ +#define KMAP_NAMELEN 40 /* including '\0' */ struct kmapHeader { - int magic; - int numEntries; + int magic; + int numEntries; }; - + struct kmapInfo { - int size; - char name[KMAP_NAMELEN]; + int size; + char name[KMAP_NAMELEN]; }; int loadKeymap(gzFile stream); int isysLoadFont(void); -int isysLoadKeymap(char * keymap); +int isysLoadKeymap(char *keymap); int isysSetUnicodeKeymap(void); #endif diff --git a/isys/linkdetect.c b/isys/linkdetect.c index 672fe1e..8215fd0 100644 --- a/isys/linkdetect.c +++ b/isys/linkdetect.c @@ -44,160 +44,161 @@ static struct ifreq ifr; static int mdio_read(int skfd, uint16_t location) { - struct mii_ioctl_data mii; + struct mii_ioctl_data mii; - memset(&mii, 0, sizeof(mii)); - memcpy(&mii, &ifr.ifr_data, sizeof(mii)); - mii.reg_num = location; - memcpy(&ifr.ifr_data, &mii, sizeof(mii)); + memset(&mii, 0, sizeof(mii)); + memcpy(&mii, &ifr.ifr_data, sizeof(mii)); + mii.reg_num = location; + memcpy(&ifr.ifr_data, &mii, sizeof(mii)); - if (ioctl(skfd, SIOCGMIIREG, &ifr) < 0) { + if (ioctl(skfd, SIOCGMIIREG, &ifr) < 0) { #ifdef STANDALONE - fprintf(stderr, "SIOCGMIIREG on %s failed: %s\n", ifr.ifr_name, - strerror(errno)); + fprintf(stderr, "SIOCGMIIREG on %s failed: %s\n", ifr.ifr_name, + strerror(errno)); #endif - return -1; - } else { - memcpy(&mii, &ifr.ifr_data, sizeof(mii)); - } + return -1; + } else { + memcpy(&mii, &ifr.ifr_data, sizeof(mii)); + } - return mii.val_out; + return mii.val_out; } /* we don't need writing right now */ #if 0 static void mdio_write(int skfd, int location, int value) { - struct mii_ioctl_data *mii = (struct mii_ioctl_data *)&ifr.ifr_data; - mii->reg_num = location; - mii->val_in = value; - if (ioctl(skfd, SIOCSMIIREG, &ifr) < 0) { + struct mii_ioctl_data *mii = (struct mii_ioctl_data *)&ifr.ifr_data; + mii->reg_num = location; + mii->val_in = value; + if (ioctl(skfd, SIOCSMIIREG, &ifr) < 0) { #ifdef STANDALONE - fprintf(stderr, "SIOCSMIIREG on %s failed: %s\n", ifr.ifr_name, - strerror(errno)); + fprintf(stderr, "SIOCSMIIREG on %s failed: %s\n", ifr.ifr_name, + strerror(errno)); #endif - } + } } #endif +static int get_mii_link_status(int sock) +{ + int i, mii_val[32]; - -static int get_mii_link_status(int sock) { - int i, mii_val[32]; - - if (ioctl(sock, SIOCGMIIPHY, &ifr) < 0) { - if (errno != ENODEV) + if (ioctl(sock, SIOCGMIIPHY, &ifr) < 0) { + if (errno != ENODEV) #ifdef STANDALONE - fprintf(stderr, "SIOCGMIIPHY on '%s' failed: %s\n", - ifr.ifr_name, strerror(errno)); + fprintf(stderr, "SIOCGMIIPHY on '%s' failed: %s\n", + ifr.ifr_name, strerror(errno)); #endif - return -1; - } + return -1; + } - /* Some bits in the BMSR are latched, but we can't rely on being - the only reader, so only the current values are meaningful */ - mdio_read(sock, MII_BMSR); - for (i = 0; i < 8; i++) - mii_val[i] = mdio_read(sock, i); + /* Some bits in the BMSR are latched, but we can't rely on being + the only reader, so only the current values are meaningful */ + mdio_read(sock, MII_BMSR); + for (i = 0; i < 8; i++) + mii_val[i] = mdio_read(sock, i); - if (mii_val[MII_BMCR] == 0xffff) { + if (mii_val[MII_BMCR] == 0xffff) { #ifdef STANDALONE - fprintf(stderr, " No MII transceiver present!.\n"); + fprintf(stderr, " No MII transceiver present!.\n"); #endif - return -1; - } + return -1; + } - if (mii_val[MII_BMSR] & BMSR_LSTATUS) - return 1; - else - return 0; + if (mii_val[MII_BMSR] & BMSR_LSTATUS) + return 1; + else + return 0; } -static int get_ethtool_link_status(int sock) { - struct ethtool_value edata; - int rc; - - edata.cmd = ETHTOOL_GLINK; - ifr.ifr_data = (caddr_t)&edata; - rc = ioctl(sock, SIOCETHTOOL, &ifr); - if (rc == 0) { - return edata.data; - } else if (errno != EOPNOTSUPP) { +static int get_ethtool_link_status(int sock) +{ + struct ethtool_value edata; + int rc; + + edata.cmd = ETHTOOL_GLINK; + ifr.ifr_data = (caddr_t) & edata; + rc = ioctl(sock, SIOCETHTOOL, &ifr); + if (rc == 0) { + return edata.data; + } else if (errno != EOPNOTSUPP) { #ifdef STANDALONE - fprintf(stderr, "Cannot get link status (%d): %s\n", errno, strerror(errno)); + fprintf(stderr, "Cannot get link status (%d): %s\n", errno, + strerror(errno)); #endif - } + } - return -1; + return -1; } +int get_link_status(char *devname) +{ + int sock, rc; - -int get_link_status(char * devname) { - int sock, rc; - - if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { #ifdef STANDALONE - fprintf(stderr, "Error creating socket: %s\n", strerror(errno)); + fprintf(stderr, "Error creating socket: %s\n", strerror(errno)); #endif - return -1; - } + return -1; + } - /* make sure interface is up and activated */ - memset(&ifr, 0, sizeof(ifr)); - strcpy(ifr.ifr_name, devname); + /* make sure interface is up and activated */ + memset(&ifr, 0, sizeof(ifr)); + strcpy(ifr.ifr_name, devname); - if (ioctl(sock, SIOCGIFFLAGS, &ifr) < 0) { - return -1; - } + if (ioctl(sock, SIOCGIFFLAGS, &ifr) < 0) { + return -1; + } - ifr.ifr_flags |= (IFF_UP | IFF_RUNNING); + ifr.ifr_flags |= (IFF_UP | IFF_RUNNING); - if (ioctl(sock, SIOCSIFFLAGS, &ifr) < 0) { - return -1; - } + if (ioctl(sock, SIOCSIFFLAGS, &ifr) < 0) { + return -1; + } - /* Setup our control structures. */ - memset(&ifr, 0, sizeof(ifr)); - strcpy(ifr.ifr_name, devname); + /* Setup our control structures. */ + memset(&ifr, 0, sizeof(ifr)); + strcpy(ifr.ifr_name, devname); - /* check for link with both ethtool and mii registers. ethtool is - * supposed to be the One True Way (tm), but it seems to not work - * with much yet :/ */ + /* check for link with both ethtool and mii registers. ethtool is + * supposed to be the One True Way (tm), but it seems to not work + * with much yet :/ */ - rc = get_ethtool_link_status(sock); + rc = get_ethtool_link_status(sock); #ifdef STANDALONE - printf("ethtool link status of %s is: %d\n", devname, rc); + printf("ethtool link status of %s is: %d\n", devname, rc); #endif - if (rc == 1) { - close(sock); - return 1; - } + if (rc == 1) { + close(sock); + return 1; + } - rc = get_mii_link_status(sock); + rc = get_mii_link_status(sock); #ifdef STANDALONE - printf("MII link status of %s is: %d\n", devname, rc); + printf("MII link status of %s is: %d\n", devname, rc); #endif - if (rc == 1) { - close(sock); - return 1; - } + if (rc == 1) { + close(sock); + return 1; + } - return 0; + return 0; } #ifdef STANDALONE /* hooray for stupid test programs! */ -int main(int argc, char **argv) { - char * dev; +int main(int argc, char **argv) +{ + char *dev; - if (argc >= 2) - dev = argv[1]; - else - dev = strdup("eth0"); + if (argc >= 2) + dev = argv[1]; + else + dev = strdup("eth0"); - printf("link status of %s is %d\n", dev, get_link_status(dev)); - return 0; + printf("link status of %s is %d\n", dev, get_link_status(dev)); + return 0; } #endif diff --git a/isys/minifind.c b/isys/minifind.c index d45ef73..305f30f 100644 --- a/isys/minifind.c +++ b/isys/minifind.c @@ -17,63 +17,62 @@ // insert a node at head of linked-list void insert_node(struct pathNode *n, char *path) { - struct pathNode *new = (struct pathNode *) malloc(sizeof(struct pathNode)); - new->path = path; - new->next = n->next; - n->next = new; + struct pathNode *new = + (struct pathNode *)malloc(sizeof(struct pathNode)); + new->path = path; + new->next = n->next; + n->next = new; } // return input strip less last character char *stripLastChar(char *in) { - char *out = malloc(sizeof(char)*strlen(in)); + char *out = malloc(sizeof(char) * strlen(in)); snprintf(out, strlen(in) - 1, "%s", in); - return out; + return out; } // do the work char *minifind(char *dir, char *search, struct findNode *list) { - char *d = NULL; - int n; - struct dirent **namelist; - struct stat buf; - - if (dir[strlen(dir)-1] == '/') - dir = stripLastChar(dir); + char *d = NULL; + int n; + struct dirent **namelist; + struct stat buf; + + if (dir[strlen(dir) - 1] == '/') + dir = stripLastChar(dir); // check is there is an exact filematch to dir // when search is not specified - if (search == NULL) - { + if (search == NULL) { if (lstat(dir, &buf) == 0) insert_node(list->result, dir); return 0; } - n = scandir(dir, &namelist, 0, alphasort); - if (n >= 0) - { - while (n--) - { - d = malloc(sizeof(char) * (strlen(dir) \ - + strlen(namelist[n]->d_name)+1)); - sprintf(d, "%s/%s", dir, namelist[n]->d_name); + n = scandir(dir, &namelist, 0, alphasort); + if (n >= 0) { + while (n--) { + d = malloc(sizeof(char) * (strlen(dir) + + + strlen(namelist[n]->d_name) + + 1)); + sprintf(d, "%s/%s", dir, namelist[n]->d_name); if (strstr(namelist[n]->d_name, search)) - insert_node(list->result, d); - - if ((lstat(d, &buf) == 0) && S_ISDIR(buf.st_mode)) - { - if (strcmp(namelist[n]->d_name, ".") && - strcmp(namelist[n]->d_name, "..")) - d = minifind(d, search, list); - } - free(namelist[n]); - } - free(namelist); - return d; - } - return 0; + insert_node(list->result, d); + + if ((lstat(d, &buf) == 0) && S_ISDIR(buf.st_mode)) { + if (strcmp(namelist[n]->d_name, ".") && + strcmp(namelist[n]->d_name, "..")) + d = minifind(d, search, list); + } + free(namelist[n]); + } + free(namelist); + return d; + } + return 0; } /* vim:set sw=8 noet */ diff --git a/isys/minifind.h b/isys/minifind.h index 5ec18e0..20b2edf 100644 --- a/isys/minifind.h +++ b/isys/minifind.h @@ -23,16 +23,14 @@ #include <sys/stat.h> #include <sys/types.h> -struct pathNode -{ - char *path; - struct pathNode *next; +struct pathNode { + char *path; + struct pathNode *next; }; -struct findNode -{ - struct pathNode *result; - struct pathNode *exclude; +struct findNode { + struct pathNode *result; + struct pathNode *exclude; }; void insert_node(struct pathNode *n, char *path); diff --git a/isys/str.c b/isys/str.c index b887ca7..3d8a00c 100644 --- a/isys/str.c +++ b/isys/str.c @@ -33,22 +33,23 @@ * @param shift Shift value (32 for lowercase, -32 for uppercase). * @return Pointer to str. */ -char *str2case(char *str, char lower, char upper, int shift) { - char *tmp; +char *str2case(char *str, char lower, char upper, int shift) +{ + char *tmp; - if (str == NULL) - return NULL; + if (str == NULL) + return NULL; - /* man ascii(7) */ - tmp = str; - while (*tmp != '\0') { - if (*tmp >= lower && *tmp <= upper) - *tmp += shift; + /* man ascii(7) */ + tmp = str; + while (*tmp != '\0') { + if (*tmp >= lower && *tmp <= upper) + *tmp += shift; - tmp++; - } + tmp++; + } - return str; + return str; } /** @@ -61,8 +62,9 @@ char *str2case(char *str, char lower, char upper, int shift) { * @param str String to convert to uppercase. * @return Pointer to str. */ -char *str2upper(char *str) { - return str2case(str, 'a', 'z', -32); +char *str2upper(char *str) +{ + return str2case(str, 'a', 'z', -32); } /** @@ -75,8 +77,9 @@ char *str2upper(char *str) { * @param str String to convert to lowercase. * @return Pointer to str. */ -char *str2lower(char *str) { - return str2case(str, 'A', 'Z', 32); +char *str2lower(char *str) +{ + return str2case(str, 'A', 'Z', 32); } /** @@ -85,18 +88,19 @@ char *str2lower(char *str) { * @param ch Character to scan for. * @return Position of ch in str, NULL if not found. */ -char *strindex(char *str, int ch) { - if (str == NULL) - return NULL; - - do { - if (*str == ch) - return str; - else - str++; - } while (*str != '\0'); - - return NULL; +char *strindex(char *str, int ch) +{ + if (str == NULL) + return NULL; + + do { + if (*str == ch) + return str; + else + str++; + } while (*str != '\0'); + + return NULL; } /** @@ -105,21 +109,22 @@ char *strindex(char *str, int ch) { * @param ch Character to scan for. * @return Number of occurrences of ch in str. */ -int strcount(char *str, int ch) { - int retval = 0; - char *tmp = str; - - if (tmp == NULL) - return retval; - - do { - if ((tmp = strindex(tmp, ch)) != NULL) { - tmp++; - retval++; - } - } while (tmp != NULL); - - return retval; +int strcount(char *str, int ch) +{ + int retval = 0; + char *tmp = str; + + if (tmp == NULL) + return retval; + + do { + if ((tmp = strindex(tmp, ch)) != NULL) { + tmp++; + retval++; + } + } while (tmp != NULL); + + return retval; } /* vim:set sw=8 noet */ diff --git a/isys/uncpio.c b/isys/uncpio.c index 410ae82..9607f44 100644 --- a/isys/uncpio.c +++ b/isys/uncpio.c @@ -40,9 +40,9 @@ #include "cpio.h" #include "stubs.h" -#if MAJOR_IN_SYSMACROS +#if MAJOR_IN_SYSMACROS #include <sys/sysmacros.h> -#elif MAJOR_IN_MKDEV +#elif MAJOR_IN_MKDEV #include <sys/mkdev.h> #endif @@ -56,100 +56,104 @@ /* We need to maintain our oun file pointer to allow padding */ struct ourfd { - gzFile fd; - size_t pos; + gzFile fd; + size_t pos; }; struct hardLink { - struct hardLink * next; - char ** files; /* there are nlink of these, used by install */ - int * fileMaps; /* used by build */ - dev_t dev; - ino_t inode; - int nlink; - int linksLeft; - int createdPath; - struct stat sb; + struct hardLink *next; + char **files; /* there are nlink of these, used by install */ + int *fileMaps; /* used by build */ + dev_t dev; + ino_t inode; + int nlink; + int linksLeft; + int createdPath; + struct stat sb; }; struct cpioCrcPhysicalHeader { - char magic[6]; - char inode[8]; - char mode[8]; - char uid[8]; - char gid[8]; - char nlink[8]; - char mtime[8]; - char filesize[8]; - char devMajor[8]; - char devMinor[8]; - char rdevMajor[8]; - char rdevMinor[8]; - char namesize[8]; - char checksum[8]; /* ignored !! */ + char magic[6]; + char inode[8]; + char mode[8]; + char uid[8]; + char gid[8]; + char nlink[8]; + char mtime[8]; + char filesize[8]; + char devMajor[8]; + char devMinor[8]; + char rdevMajor[8]; + char rdevMinor[8]; + char namesize[8]; + char checksum[8]; /* ignored !! */ }; -#define PHYS_HDR_SIZE 110 /* don't depend on sizeof(struct) */ +#define PHYS_HDR_SIZE 110 /* don't depend on sizeof(struct) */ struct cpioHeader { - ino_t inode; - mode_t mode; - uid_t uid; - gid_t gid; - int nlink; - time_t mtime; - unsigned long size; - dev_t dev, rdev; - char * path; + ino_t inode; + mode_t mode; + uid_t uid; + gid_t gid; + int nlink; + time_t mtime; + unsigned long size; + dev_t dev, rdev; + char *path; }; -static inline off_t ourread(struct ourfd * thefd, void * buf, size_t size) { - off_t i; +static inline off_t ourread(struct ourfd *thefd, void *buf, size_t size) +{ + off_t i; + + i = gunzip_read(thefd->fd, buf, size); + thefd->pos += i; - i = gunzip_read(thefd->fd, buf, size); - thefd->pos += i; - - return i; + return i; } -static inline void padinfd(struct ourfd * fd, int modulo) { - int buf[10]; - int amount; - - amount = (modulo - fd->pos % modulo) % modulo; - ourread(fd, buf, amount); +static inline void padinfd(struct ourfd *fd, int modulo) +{ + int buf[10]; + int amount; + + amount = (modulo - fd->pos % modulo) % modulo; + ourread(fd, buf, amount); } -static inline int padoutfd(struct ourfd * fd, size_t * where, int modulo) { - /*static int buf[10] = { '\0', '\0', '\0', '\0', '\0', - '\0', '\0', '\0', '\0', '\0' };*/ - int amount; - static int buf[512]; +static inline int padoutfd(struct ourfd *fd, size_t * where, int modulo) +{ + /*static int buf[10] = { '\0', '\0', '\0', '\0', '\0', + '\0', '\0', '\0', '\0', '\0' }; */ + int amount; + static int buf[512]; - amount = (modulo - *where % modulo) % modulo; - *where += amount; + amount = (modulo - *where % modulo) % modulo; + *where += amount; - if (gzip_write(fd->fd, buf, amount) != amount) - return CPIOERR_WRITE_FAILED; + if (gzip_write(fd->fd, buf, amount) != amount) + return CPIOERR_WRITE_FAILED; - return 0; + return 0; } -static int strntoul(const char * str, char ** endptr, int base, int num) { - char * buf, * end; - unsigned long ret; +static int strntoul(const char *str, char **endptr, int base, int num) +{ + char *buf, *end; + unsigned long ret; - buf = alloca(num + 1); - strncpy(buf, str, num); - buf[num] = '\0'; + buf = alloca(num + 1); + strncpy(buf, str, num); + buf[num] = '\0'; - ret = strtoul(buf, &end, base); - if (*end) - *endptr = (char *)(str + (end - buf)); /* XXX discards const */ - else - *endptr = ""; + ret = strtoul(buf, &end, base); + if (*end) + *endptr = (char *)(str + (end - buf)); /* XXX discards const */ + else + *endptr = ""; - return strtoul(buf, endptr, base); + return strtoul(buf, endptr, base); } #define GET_NUM_FIELD(phys, log) \ @@ -159,642 +163,722 @@ static int strntoul(const char * str, char ** endptr, int base, int num) { sprintf(space, "%8.8lx", (unsigned long) (val)); \ memcpy(phys, space, 8); -static int getNextHeader(struct ourfd * fd, struct cpioHeader * chPtr, - struct cpioCrcPhysicalHeader * physHeaderPtr) { - struct cpioCrcPhysicalHeader physHeader; - int nameSize; - char * end; - int major, minor; - - if (ourread(fd, &physHeader, PHYS_HDR_SIZE) != PHYS_HDR_SIZE) - return CPIOERR_READ_FAILED; - - if (physHeaderPtr) - memcpy(physHeaderPtr, &physHeader, PHYS_HDR_SIZE); - - if (strncmp(CPIO_CRC_MAGIC, physHeader.magic, strlen(CPIO_CRC_MAGIC)) && - strncmp(CPIO_NEWC_MAGIC, physHeader.magic, strlen(CPIO_NEWC_MAGIC))) - return CPIOERR_BAD_MAGIC; - - GET_NUM_FIELD(physHeader.inode, chPtr->inode); - GET_NUM_FIELD(physHeader.mode, chPtr->mode); - GET_NUM_FIELD(physHeader.uid, chPtr->uid); - GET_NUM_FIELD(physHeader.gid, chPtr->gid); - GET_NUM_FIELD(physHeader.nlink, chPtr->nlink); - GET_NUM_FIELD(physHeader.mtime, chPtr->mtime); - GET_NUM_FIELD(physHeader.filesize, chPtr->size); - - GET_NUM_FIELD(physHeader.devMajor, major); - GET_NUM_FIELD(physHeader.devMinor, minor); - chPtr->dev = makedev(major, minor); - - GET_NUM_FIELD(physHeader.rdevMajor, major); - GET_NUM_FIELD(physHeader.rdevMinor, minor); - chPtr->rdev = makedev(major, minor); - - GET_NUM_FIELD(physHeader.namesize, nameSize); - - chPtr->path = malloc(nameSize + 1); - if (ourread(fd, chPtr->path, nameSize) != nameSize) { - free(chPtr->path); - return CPIOERR_BAD_HEADER; - } +static int getNextHeader(struct ourfd *fd, struct cpioHeader *chPtr, + struct cpioCrcPhysicalHeader *physHeaderPtr) +{ + struct cpioCrcPhysicalHeader physHeader; + int nameSize; + char *end; + int major, minor; + + if (ourread(fd, &physHeader, PHYS_HDR_SIZE) != PHYS_HDR_SIZE) + return CPIOERR_READ_FAILED; + + if (physHeaderPtr) + memcpy(physHeaderPtr, &physHeader, PHYS_HDR_SIZE); + + if (strncmp(CPIO_CRC_MAGIC, physHeader.magic, strlen(CPIO_CRC_MAGIC)) && + strncmp(CPIO_NEWC_MAGIC, physHeader.magic, strlen(CPIO_NEWC_MAGIC))) + return CPIOERR_BAD_MAGIC; + + GET_NUM_FIELD(physHeader.inode, chPtr->inode); + GET_NUM_FIELD(physHeader.mode, chPtr->mode); + GET_NUM_FIELD(physHeader.uid, chPtr->uid); + GET_NUM_FIELD(physHeader.gid, chPtr->gid); + GET_NUM_FIELD(physHeader.nlink, chPtr->nlink); + GET_NUM_FIELD(physHeader.mtime, chPtr->mtime); + GET_NUM_FIELD(physHeader.filesize, chPtr->size); + + GET_NUM_FIELD(physHeader.devMajor, major); + GET_NUM_FIELD(physHeader.devMinor, minor); + chPtr->dev = makedev(major, minor); + + GET_NUM_FIELD(physHeader.rdevMajor, major); + GET_NUM_FIELD(physHeader.rdevMinor, minor); + chPtr->rdev = makedev(major, minor); + + GET_NUM_FIELD(physHeader.namesize, nameSize); + + chPtr->path = malloc(nameSize + 1); + if (ourread(fd, chPtr->path, nameSize) != nameSize) { + free(chPtr->path); + return CPIOERR_BAD_HEADER; + } - /* this is unecessary chPtr->path[nameSize] = '\0'; */ + /* this is unecessary chPtr->path[nameSize] = '\0'; */ - padinfd(fd, 4); + padinfd(fd, 4); - return 0; + return 0; } -int myCpioFileMapCmp(const void * a, const void * b) { - const struct cpioFileMapping * first = a; - const struct cpioFileMapping * second = b; +int myCpioFileMapCmp(const void *a, const void *b) +{ + const struct cpioFileMapping *first = a; + const struct cpioFileMapping *second = b; - return (strcmp(first->archivePath, second->archivePath)); + return (strcmp(first->archivePath, second->archivePath)); } /* This could trash files in the path! I'm not sure that's a good thing */ -static int createDirectory(char * path, mode_t perms) { - struct stat sb; - int dounlink; - - if (!lstat(path, &sb)) { - if (S_ISDIR(sb.st_mode)) { - return 0; - } else if (S_ISLNK(sb.st_mode)) { - if (stat(path, &sb)) { - if (errno != ENOENT) - return CPIOERR_STAT_FAILED; - dounlink = 1; - } else { - if (S_ISDIR(sb.st_mode)) - return 0; - dounlink = 1; - } - } else { - dounlink = 1; - } +static int createDirectory(char *path, mode_t perms) +{ + struct stat sb; + int dounlink; + + if (!lstat(path, &sb)) { + if (S_ISDIR(sb.st_mode)) { + return 0; + } else if (S_ISLNK(sb.st_mode)) { + if (stat(path, &sb)) { + if (errno != ENOENT) + return CPIOERR_STAT_FAILED; + dounlink = 1; + } else { + if (S_ISDIR(sb.st_mode)) + return 0; + dounlink = 1; + } + } else { + dounlink = 1; + } - if (dounlink && unlink(path)) { - return CPIOERR_UNLINK_FAILED; + if (dounlink && unlink(path)) { + return CPIOERR_UNLINK_FAILED; + } } - } - if (mkdir(path, 000)) - return CPIOERR_MKDIR_FAILED; + if (mkdir(path, 000)) + return CPIOERR_MKDIR_FAILED; - if (chmod(path, perms)) - return CPIOERR_CHMOD_FAILED; + if (chmod(path, perms)) + return CPIOERR_CHMOD_FAILED; - return 0; + return 0; } -static int setInfo(struct cpioHeader * hdr) { - int rc = 0; - struct utimbuf stamp; - - stamp.actime = hdr->mtime; - stamp.modtime = hdr->mtime; - - if (!S_ISLNK(hdr->mode)) { - if (!getuid() && chown(hdr->path, hdr->uid, hdr->gid)) - rc = CPIOERR_CHOWN_FAILED; - if (!rc && chmod(hdr->path, hdr->mode & 07777)) - rc = CPIOERR_CHMOD_FAILED; - if (!rc && utime(hdr->path, &stamp)) - rc = CPIOERR_UTIME_FAILED; - } else { +static int setInfo(struct cpioHeader *hdr) +{ + int rc = 0; + struct utimbuf stamp; + + stamp.actime = hdr->mtime; + stamp.modtime = hdr->mtime; + + if (!S_ISLNK(hdr->mode)) { + if (!getuid() && chown(hdr->path, hdr->uid, hdr->gid)) + rc = CPIOERR_CHOWN_FAILED; + if (!rc && chmod(hdr->path, hdr->mode & 07777)) + rc = CPIOERR_CHMOD_FAILED; + if (!rc && utime(hdr->path, &stamp)) + rc = CPIOERR_UTIME_FAILED; + } else { # if ! CHOWN_FOLLOWS_SYMLINK - if (!getuid() && !rc && lchown(hdr->path, hdr->uid, hdr->gid)) - rc = CPIOERR_CHOWN_FAILED; + if (!getuid() && !rc && lchown(hdr->path, hdr->uid, hdr->gid)) + rc = CPIOERR_CHOWN_FAILED; # endif - } + } - return rc; + return rc; } -static int checkDirectory(char * filename) { - static char * lastDir = NULL; - static int lastDirLength = 0; - static int lastDirAlloced = 0; - int length = strlen(filename); - char * buf; - char * chptr; - int rc = 0; - - buf = alloca(length + 1); - strcpy(buf, filename); - - for (chptr = buf + length - 1; chptr > buf; chptr--) { - if (*chptr == '/') break; - } +static int checkDirectory(char *filename) +{ + static char *lastDir = NULL; + static int lastDirLength = 0; + static int lastDirAlloced = 0; + int length = strlen(filename); + char *buf; + char *chptr; + int rc = 0; + + buf = alloca(length + 1); + strcpy(buf, filename); + + for (chptr = buf + length - 1; chptr > buf; chptr--) { + if (*chptr == '/') + break; + } - if (chptr == buf) return 0; /* /filename - no directories */ + if (chptr == buf) + return 0; /* /filename - no directories */ - *chptr = '\0'; /* buffer is now just directories */ + *chptr = '\0'; /* buffer is now just directories */ - length = strlen(buf); - if (lastDirLength == length && !strcmp(buf, lastDir)) return 0; + length = strlen(buf); + if (lastDirLength == length && !strcmp(buf, lastDir)) + return 0; - if (lastDirAlloced < (length + 1)) { - lastDirAlloced = length + 100; - lastDir = realloc(lastDir, lastDirAlloced); - } + if (lastDirAlloced < (length + 1)) { + lastDirAlloced = length + 100; + lastDir = realloc(lastDir, lastDirAlloced); + } - strcpy(lastDir, buf); - lastDirLength = length; + strcpy(lastDir, buf); + lastDirLength = length; - for (chptr = buf + 1; *chptr; chptr++) { - if (*chptr == '/') { - *chptr = '\0'; - rc = createDirectory(buf, 0755); - *chptr = '/'; - if (rc) return rc; + for (chptr = buf + 1; *chptr; chptr++) { + if (*chptr == '/') { + *chptr = '\0'; + rc = createDirectory(buf, 0755); + *chptr = '/'; + if (rc) + return rc; + } } - } - rc = createDirectory(buf, 0755); + rc = createDirectory(buf, 0755); - return rc; + return rc; } -static int expandRegular(struct ourfd * fd, struct cpioHeader * hdr, - cpioCallback cb, void * cbData) { - int out; - char buf[8192]; - int bytesRead; - unsigned long left = hdr->size; - int rc = 0; - struct cpioCallbackInfo cbInfo; - struct stat sb; - - if (!lstat(hdr->path, &sb)) - if (unlink(hdr->path)) - return CPIOERR_UNLINK_FAILED; - - out = open(hdr->path, O_CREAT | O_WRONLY, 0); - if (out < 0) - return CPIOERR_OPEN_FAILED; - - cbInfo.file = hdr->path; - cbInfo.fileSize = hdr->size; - - while (left) { - bytesRead = ourread(fd, buf, left < sizeof(buf) ? left : sizeof(buf)); - if (bytesRead <= 0) { - rc = CPIOERR_READ_FAILED; - break; - } +static int expandRegular(struct ourfd *fd, struct cpioHeader *hdr, + cpioCallback cb, void *cbData) +{ + int out; + char buf[8192]; + int bytesRead; + unsigned long left = hdr->size; + int rc = 0; + struct cpioCallbackInfo cbInfo; + struct stat sb; + + if (!lstat(hdr->path, &sb)) + if (unlink(hdr->path)) + return CPIOERR_UNLINK_FAILED; + + out = open(hdr->path, O_CREAT | O_WRONLY, 0); + if (out < 0) + return CPIOERR_OPEN_FAILED; + + cbInfo.file = hdr->path; + cbInfo.fileSize = hdr->size; + + while (left) { + bytesRead = + ourread(fd, buf, left < sizeof(buf) ? left : sizeof(buf)); + if (bytesRead <= 0) { + rc = CPIOERR_READ_FAILED; + break; + } - if (write(out, buf, bytesRead) != bytesRead) { - rc = CPIOERR_COPY_FAILED; - break; - } + if (write(out, buf, bytesRead) != bytesRead) { + rc = CPIOERR_COPY_FAILED; + break; + } - left -= bytesRead; + left -= bytesRead; - /* don't call this with fileSize == fileComplete */ - if (!rc && cb && left) { - cbInfo.fileComplete = hdr->size - left; - cbInfo.bytesProcessed = fd->pos; - cb(&cbInfo, cbData); + /* don't call this with fileSize == fileComplete */ + if (!rc && cb && left) { + cbInfo.fileComplete = hdr->size - left; + cbInfo.bytesProcessed = fd->pos; + cb(&cbInfo, cbData); + } } - } - - close(out); - - return rc; -} -static int expandSymlink(struct ourfd * fd, struct cpioHeader * hdr) { - char buf[2048], buf2[2048]; - struct stat sb; - int len; + close(out); - if ((hdr->size + 1)> sizeof(buf)) - return CPIOERR_INTERNAL; - - if (ourread(fd, buf, hdr->size) != hdr->size) - return CPIOERR_READ_FAILED; + return rc; +} - buf[hdr->size] = '\0'; +static int expandSymlink(struct ourfd *fd, struct cpioHeader *hdr) +{ + char buf[2048], buf2[2048]; + struct stat sb; + int len; + + if ((hdr->size + 1) > sizeof(buf)) + return CPIOERR_INTERNAL; + + if (ourread(fd, buf, hdr->size) != hdr->size) + return CPIOERR_READ_FAILED; + + buf[hdr->size] = '\0'; + + if (!lstat(hdr->path, &sb)) { + if (S_ISLNK(sb.st_mode)) { + len = readlink(hdr->path, buf2, sizeof(buf2) - 1); + if (len > 0) { + buf2[len] = '\0'; + if (!strcmp(buf, buf2)) + return 0; + } + } - if (!lstat(hdr->path, &sb)) { - if (S_ISLNK(sb.st_mode)) { - len = readlink(hdr->path, buf2, sizeof(buf2) - 1); - if (len > 0) { - buf2[len] = '\0'; - if (!strcmp(buf, buf2)) return 0; - } + if (unlink(hdr->path)) + return CPIOERR_UNLINK_FAILED; } - if (unlink(hdr->path)) - return CPIOERR_UNLINK_FAILED; - } - - if (symlink(buf, hdr->path) < 0) - return CPIOERR_SYMLINK_FAILED; + if (symlink(buf, hdr->path) < 0) + return CPIOERR_SYMLINK_FAILED; - return 0; + return 0; } -static int expandFifo(struct ourfd * fd, struct cpioHeader * hdr) { - struct stat sb; +static int expandFifo(struct ourfd *fd, struct cpioHeader *hdr) +{ + struct stat sb; - if (!lstat(hdr->path, &sb)) { - if (S_ISFIFO(sb.st_mode)) return 0; + if (!lstat(hdr->path, &sb)) { + if (S_ISFIFO(sb.st_mode)) + return 0; - if (unlink(hdr->path)) - return CPIOERR_UNLINK_FAILED; - } + if (unlink(hdr->path)) + return CPIOERR_UNLINK_FAILED; + } - if (mkfifo(hdr->path, 0)) - return CPIOERR_MKFIFO_FAILED; + if (mkfifo(hdr->path, 0)) + return CPIOERR_MKFIFO_FAILED; - return 0; + return 0; } -static int expandDevice(struct ourfd * fd, struct cpioHeader * hdr) { - struct stat sb; - - if (!lstat(hdr->path, &sb)) { - if ((S_ISCHR(sb.st_mode) || S_ISBLK(sb.st_mode)) && - (sb.st_rdev == hdr->rdev)) - return 0; - if (unlink(hdr->path)) - return CPIOERR_UNLINK_FAILED; - } - - if (mknod(hdr->path, hdr->mode & (~0777), hdr->rdev)) - return CPIOERR_MKNOD_FAILED; - - return 0; -} +static int expandDevice(struct ourfd *fd, struct cpioHeader *hdr) +{ + struct stat sb; + + if (!lstat(hdr->path, &sb)) { + if ((S_ISCHR(sb.st_mode) || S_ISBLK(sb.st_mode)) && + (sb.st_rdev == hdr->rdev)) + return 0; + if (unlink(hdr->path)) + return CPIOERR_UNLINK_FAILED; + } -static void freeLink(struct hardLink * li) { - int i; + if (mknod(hdr->path, hdr->mode & (~0777), hdr->rdev)) + return CPIOERR_MKNOD_FAILED; - for (i = 0; i < li->nlink; i++) { - if (li->files[i]) free(li->files[i]); - } - free(li->files); + return 0; } -static int createLinks(struct hardLink * li, const char ** failedFile) { - int i; - struct stat sb; - - for (i = 0; i < li->nlink; i++) { - if (i == li->createdPath) continue; - if (!li->files[i]) continue; +static void freeLink(struct hardLink *li) +{ + int i; - if (!lstat(li->files[i], &sb)) { - if (unlink(li->files[i])) { - *failedFile = strdup(li->files[i]); - return CPIOERR_UNLINK_FAILED; - } + for (i = 0; i < li->nlink; i++) { + if (li->files[i]) + free(li->files[i]); } + free(li->files); +} - if (link(li->files[li->createdPath], li->files[i])) { - *failedFile = strdup(li->files[i]); - return CPIOERR_LINK_FAILED; - } +static int createLinks(struct hardLink *li, const char **failedFile) +{ + int i; + struct stat sb; + + for (i = 0; i < li->nlink; i++) { + if (i == li->createdPath) + continue; + if (!li->files[i]) + continue; + + if (!lstat(li->files[i], &sb)) { + if (unlink(li->files[i])) { + *failedFile = strdup(li->files[i]); + return CPIOERR_UNLINK_FAILED; + } + } - free(li->files[i]); - li->files[i] = NULL; - li->linksLeft--; - } + if (link(li->files[li->createdPath], li->files[i])) { + *failedFile = strdup(li->files[i]); + return CPIOERR_LINK_FAILED; + } - return 0; -} + free(li->files[i]); + li->files[i] = NULL; + li->linksLeft--; + } -static int eatBytes(struct ourfd * fd, unsigned long amount) { - char buf[4096]; - unsigned long bite; - - while (amount) { - bite = (amount > sizeof(buf)) ? sizeof(buf) : amount; - if (ourread(fd, buf, bite) != bite) - return CPIOERR_READ_FAILED; - amount -= bite; - } - - return 0; + return 0; } -int myCpioInstallArchive(gzFile stream, struct cpioFileMapping * mappings, - int numMappings, cpioCallback cb, void * cbData, - const char ** failedFile) { - struct cpioHeader ch; - struct ourfd fd; - int rc = 0; - int linkNum = 0; - struct cpioFileMapping * map = NULL; - struct cpioFileMapping needle; - mode_t cpioMode; - int olderr; - struct cpioCallbackInfo cbInfo; - struct hardLink * links = NULL; - struct hardLink * li = NULL; - - fd.fd = stream; - fd.pos = 0; - - *failedFile = NULL; - - do { - if ((rc = getNextHeader(&fd, &ch, NULL))) { - fprintf(stderr, _("error %d reading header: %s\n"), rc, - myCpioStrerror(rc)); - return CPIOERR_BAD_HEADER; +static int eatBytes(struct ourfd *fd, unsigned long amount) +{ + char buf[4096]; + unsigned long bite; + + while (amount) { + bite = (amount > sizeof(buf)) ? sizeof(buf) : amount; + if (ourread(fd, buf, bite) != bite) + return CPIOERR_READ_FAILED; + amount -= bite; } - if (!strcmp(ch.path, TRAILER)) { - free(ch.path); - break; - } + return 0; +} - if (mappings) { - needle.archivePath = ch.path; - map = bsearch(&needle, mappings, numMappings, sizeof(needle), - myCpioFileMapCmp); - } +int myCpioInstallArchive(gzFile stream, struct cpioFileMapping *mappings, + int numMappings, cpioCallback cb, void *cbData, + const char **failedFile) +{ + struct cpioHeader ch; + struct ourfd fd; + int rc = 0; + int linkNum = 0; + struct cpioFileMapping *map = NULL; + struct cpioFileMapping needle; + mode_t cpioMode; + int olderr; + struct cpioCallbackInfo cbInfo; + struct hardLink *links = NULL; + struct hardLink *li = NULL; + + fd.fd = stream; + fd.pos = 0; + + *failedFile = NULL; + + do { + if ((rc = getNextHeader(&fd, &ch, NULL))) { + fprintf(stderr, _("error %d reading header: %s\n"), rc, + myCpioStrerror(rc)); + return CPIOERR_BAD_HEADER; + } - if (mappings && !map) { - eatBytes(&fd, ch.size); - } else { - cpioMode = ch.mode; - - if (map) { - if (map->mapFlags & CPIO_MAP_PATH) { - free(ch.path); - ch.path = strdup(map->fsPath); - } - - if (map->mapFlags & CPIO_MAP_MODE) - ch.mode = map->finalMode; - if (map->mapFlags & CPIO_MAP_UID) - ch.uid = map->finalUid; - if (map->mapFlags & CPIO_MAP_GID) - ch.gid = map->finalGid; - } - - /* This won't get hard linked symlinks right, but I can't seem - to create those anyway */ - - if (S_ISREG(ch.mode) && ch.nlink > 1) { - li = links; - for (li = links; li; li = li->next) { - if (li->inode == ch.inode && li->dev == ch.dev) break; + if (!strcmp(ch.path, TRAILER)) { + free(ch.path); + break; } - if (!li) { - li = malloc(sizeof(*li)); - li->inode = ch.inode; - li->dev = ch.dev; - li->nlink = ch.nlink; - li->linksLeft = ch.nlink; - li->createdPath = -1; - li->files = calloc(sizeof(char *), li->nlink); - li->next = links; - links = li; + if (mappings) { + needle.archivePath = ch.path; + map = + bsearch(&needle, mappings, numMappings, + sizeof(needle), myCpioFileMapCmp); } - for (linkNum = 0; linkNum < li->nlink; linkNum++) - if (!li->files[linkNum]) break; - li->files[linkNum] = strdup(ch.path); - } - - if ((ch.nlink > 1) && S_ISREG(ch.mode) && !ch.size && - li->createdPath == -1) { - /* defer file creation */ - } else if ((ch.nlink > 1) && S_ISREG(ch.mode) && - (li->createdPath != -1)) { - createLinks(li, failedFile); - - /* this only happens for cpio archives which contain - hardlinks w/ the contents of each hardlink being - listed (intead of the data being given just once. This - shouldn't happen, but I've made it happen w/ buggy - code, so what the heck? GNU cpio handles this well fwiw */ - if (ch.size) eatBytes(&fd, ch.size); - } else { - rc = checkDirectory(ch.path); - - if (!rc) { - if (S_ISREG(ch.mode)) - rc = expandRegular(&fd, &ch, cb, cbData); - else if (S_ISDIR(ch.mode)) - rc = createDirectory(ch.path, 000); - else if (S_ISLNK(ch.mode)) - rc = expandSymlink(&fd, &ch); - else if (S_ISFIFO(ch.mode)) - rc = expandFifo(&fd, &ch); - else if (S_ISCHR(ch.mode) || S_ISBLK(ch.mode)) - rc = expandDevice(&fd, &ch); - else if (S_ISSOCK(ch.mode)) { - /* this mimicks cpio but probably isnt' right */ - rc = expandFifo(&fd, &ch); - } else { - rc = CPIOERR_INTERNAL; - } + if (mappings && !map) { + eatBytes(&fd, ch.size); + } else { + cpioMode = ch.mode; + + if (map) { + if (map->mapFlags & CPIO_MAP_PATH) { + free(ch.path); + ch.path = strdup(map->fsPath); + } + + if (map->mapFlags & CPIO_MAP_MODE) + ch.mode = map->finalMode; + if (map->mapFlags & CPIO_MAP_UID) + ch.uid = map->finalUid; + if (map->mapFlags & CPIO_MAP_GID) + ch.gid = map->finalGid; + } + + /* This won't get hard linked symlinks right, but I can't seem + to create those anyway */ + + if (S_ISREG(ch.mode) && ch.nlink > 1) { + li = links; + for (li = links; li; li = li->next) { + if (li->inode == ch.inode + && li->dev == ch.dev) + break; + } + + if (!li) { + li = malloc(sizeof(*li)); + li->inode = ch.inode; + li->dev = ch.dev; + li->nlink = ch.nlink; + li->linksLeft = ch.nlink; + li->createdPath = -1; + li->files = + calloc(sizeof(char *), li->nlink); + li->next = links; + links = li; + } + + for (linkNum = 0; linkNum < li->nlink; + linkNum++) + if (!li->files[linkNum]) + break; + li->files[linkNum] = strdup(ch.path); + } + + if ((ch.nlink > 1) && S_ISREG(ch.mode) && !ch.size && + li->createdPath == -1) { + /* defer file creation */ + } else if ((ch.nlink > 1) && S_ISREG(ch.mode) && + (li->createdPath != -1)) { + createLinks(li, failedFile); + + /* this only happens for cpio archives which contain + hardlinks w/ the contents of each hardlink being + listed (intead of the data being given just once. This + shouldn't happen, but I've made it happen w/ buggy + code, so what the heck? GNU cpio handles this well fwiw */ + if (ch.size) + eatBytes(&fd, ch.size); + } else { + rc = checkDirectory(ch.path); + + if (!rc) { + if (S_ISREG(ch.mode)) + rc = expandRegular(&fd, &ch, cb, + cbData); + else if (S_ISDIR(ch.mode)) + rc = createDirectory(ch.path, + 000); + else if (S_ISLNK(ch.mode)) + rc = expandSymlink(&fd, &ch); + else if (S_ISFIFO(ch.mode)) + rc = expandFifo(&fd, &ch); + else if (S_ISCHR(ch.mode) + || S_ISBLK(ch.mode)) + rc = expandDevice(&fd, &ch); + else if (S_ISSOCK(ch.mode)) { + /* this mimicks cpio but probably isnt' right */ + rc = expandFifo(&fd, &ch); + } else { + rc = CPIOERR_INTERNAL; + } + } + + if (!rc) + rc = setInfo(&ch); + + if (S_ISREG(ch.mode) && ch.nlink > 1) { + li->createdPath = linkNum; + li->linksLeft--; + rc = createLinks(li, failedFile); + } + } + + if (rc && !*failedFile) { + *failedFile = strdup(ch.path); + + olderr = errno; + unlink(ch.path); + errno = olderr; + } } - if (!rc) - rc = setInfo(&ch); + padinfd(&fd, 4); - if (S_ISREG(ch.mode) && ch.nlink > 1) { - li->createdPath = linkNum; - li->linksLeft--; - rc = createLinks(li, failedFile); + if (!rc && cb) { + cbInfo.file = ch.path; + cbInfo.fileSize = ch.size; + cbInfo.fileComplete = ch.size; + cbInfo.bytesProcessed = fd.pos; + cb(&cbInfo, cbData); } - } - if (rc && !*failedFile) { - *failedFile = strdup(ch.path); + free(ch.path); + } while (1 && !rc); - olderr = errno; - unlink(ch.path); - errno = olderr; - } - } + li = links; + while (li && !rc) { + if (li->linksLeft) { + if (li->createdPath == -1) + rc = CPIOERR_INTERNAL; + else + rc = createLinks(li, failedFile); + } - padinfd(&fd, 4); + freeLink(li); - if (!rc && cb) { - cbInfo.file = ch.path; - cbInfo.fileSize = ch.size; - cbInfo.fileComplete = ch.size; - cbInfo.bytesProcessed = fd.pos; - cb(&cbInfo, cbData); + links = li; + li = li->next; + free(links); + links = li; } - free(ch.path); - } while (1 && !rc); - - li = links; - while (li && !rc) { - if (li->linksLeft) { - if (li->createdPath == -1) - rc = CPIOERR_INTERNAL; - else - rc = createLinks(li, failedFile); + li = links; + /* if an error got us here links will still be eating some memory */ + while (li) { + freeLink(li); + links = li; + li = li->next; + free(links); } - freeLink(li); + return rc; +} + +const char *myCpioStrerror(int rc) +{ + static char msg[256]; + char *s; + int l, myerrno = errno; + + strcpy(msg, "cpio: "); + switch (rc) { + default: + s = msg + strlen(msg); + sprintf(s, _("(error 0x%x)"), rc); + s = NULL; + break; + case CPIOERR_BAD_MAGIC: + s = _("Bad magic"); + break; + case CPIOERR_BAD_HEADER: + s = _("Bad header"); + break; - links = li; - li = li->next; - free(links); - links = li; - } + case CPIOERR_OPEN_FAILED: + s = "open"; + break; + case CPIOERR_CHMOD_FAILED: + s = "chmod"; + break; + case CPIOERR_CHOWN_FAILED: + s = "chown"; + break; + case CPIOERR_WRITE_FAILED: + s = "write"; + break; + case CPIOERR_UTIME_FAILED: + s = "utime"; + break; + case CPIOERR_UNLINK_FAILED: + s = "unlink"; + break; + case CPIOERR_SYMLINK_FAILED: + s = "symlink"; + break; + case CPIOERR_STAT_FAILED: + s = "stat"; + break; + case CPIOERR_MKDIR_FAILED: + s = "mkdir"; + break; + case CPIOERR_MKNOD_FAILED: + s = "mknod"; + break; + case CPIOERR_MKFIFO_FAILED: + s = "mkfifo"; + break; + case CPIOERR_LINK_FAILED: + s = "link"; + break; + case CPIOERR_READLINK_FAILED: + s = "readlink"; + break; + case CPIOERR_READ_FAILED: + s = "read"; + break; + case CPIOERR_COPY_FAILED: + s = "copy"; + break; - li = links; - /* if an error got us here links will still be eating some memory */ - while (li) { - freeLink(li); - links = li; - li = li->next; - free(links); - } + case CPIOERR_INTERNAL: + s = _("Internal error"); + break; + case CPIOERR_HDR_SIZE: + s = _("Header size too big"); + break; + case CPIOERR_UNKNOWN_FILETYPE: + s = _("Unknown file type"); + break; + } - return rc; + l = sizeof(msg) - strlen(msg) - 1; + if (s != NULL) { + if (l > 0) + strncat(msg, s, l); + l -= strlen(s); + } + if (rc & CPIOERR_CHECK_ERRNO) { + s = _(" failed - "); + if (l > 0) + strncat(msg, s, l); + l -= strlen(s); + if (l > 0) + strncat(msg, strerror(myerrno), l); + } + return msg; } -const char * myCpioStrerror(int rc) +static int copyFile(struct ourfd *inFd, struct ourfd *outFd, + struct cpioHeader *chp, struct cpioCrcPhysicalHeader *pHdr) { - static char msg[256]; - char *s; - int l, myerrno = errno; - - strcpy(msg, "cpio: "); - switch (rc) { - default: - s = msg + strlen(msg); - sprintf(s, _("(error 0x%x)"), rc); - s = NULL; - break; - case CPIOERR_BAD_MAGIC: s = _("Bad magic"); break; - case CPIOERR_BAD_HEADER: s = _("Bad header"); break; - - case CPIOERR_OPEN_FAILED: s = "open"; break; - case CPIOERR_CHMOD_FAILED: s = "chmod"; break; - case CPIOERR_CHOWN_FAILED: s = "chown"; break; - case CPIOERR_WRITE_FAILED: s = "write"; break; - case CPIOERR_UTIME_FAILED: s = "utime"; break; - case CPIOERR_UNLINK_FAILED: s = "unlink"; break; - case CPIOERR_SYMLINK_FAILED: s = "symlink"; break; - case CPIOERR_STAT_FAILED: s = "stat"; break; - case CPIOERR_MKDIR_FAILED: s = "mkdir"; break; - case CPIOERR_MKNOD_FAILED: s = "mknod"; break; - case CPIOERR_MKFIFO_FAILED: s = "mkfifo"; break; - case CPIOERR_LINK_FAILED: s = "link"; break; - case CPIOERR_READLINK_FAILED: s = "readlink"; break; - case CPIOERR_READ_FAILED: s = "read"; break; - case CPIOERR_COPY_FAILED: s = "copy"; break; - - case CPIOERR_INTERNAL: s = _("Internal error"); break; - case CPIOERR_HDR_SIZE: s = _("Header size too big"); break; - case CPIOERR_UNKNOWN_FILETYPE: s = _("Unknown file type"); break; - } - - l = sizeof(msg) - strlen(msg) - 1; - if (s != NULL) { - if (l > 0) strncat(msg, s, l); - l -= strlen(s); - } - if (rc & CPIOERR_CHECK_ERRNO) { - s = _(" failed - "); - if (l > 0) strncat(msg, s, l); - l -= strlen(s); - if (l > 0) strncat(msg, strerror(myerrno), l); - } - return msg; -} - -static int copyFile(struct ourfd * inFd, struct ourfd * outFd, - struct cpioHeader * chp, struct cpioCrcPhysicalHeader * pHdr) { - char buf[8192]; - int amount; - size_t size = chp->size; + char buf[8192]; + int amount; + size_t size = chp->size; - amount = strlen(chp->path) + 1; - memcpy(pHdr->magic, CPIO_NEWC_MAGIC, sizeof(pHdr->magic)); + amount = strlen(chp->path) + 1; + memcpy(pHdr->magic, CPIO_NEWC_MAGIC, sizeof(pHdr->magic)); - gzip_write(outFd->fd, pHdr, PHYS_HDR_SIZE); - gzip_write(outFd->fd, chp->path, amount); + gzip_write(outFd->fd, pHdr, PHYS_HDR_SIZE); + gzip_write(outFd->fd, chp->path, amount); - outFd->pos += PHYS_HDR_SIZE + amount; + outFd->pos += PHYS_HDR_SIZE + amount; - padoutfd(outFd, &outFd->pos, 4); + padoutfd(outFd, &outFd->pos, 4); - while (size) { - amount = ourread(inFd, buf, size > sizeof(buf) ? sizeof(buf) : size); - gzip_write(outFd->fd, buf, amount); - size -= amount; - } + while (size) { + amount = + ourread(inFd, buf, size > sizeof(buf) ? sizeof(buf) : size); + gzip_write(outFd->fd, buf, amount); + size -= amount; + } - outFd->pos += chp->size; + outFd->pos += chp->size; - padoutfd(outFd, &outFd->pos, 4); + padoutfd(outFd, &outFd->pos, 4); - return 0; + return 0; } -int myCpioFilterArchive(gzFile inStream, gzFile outStream, char ** patterns) { - struct ourfd inFd, outFd; - char ** aPattern; - struct cpioHeader ch; - int rc; - struct cpioCrcPhysicalHeader pHeader; - - inFd.fd = inStream; - inFd.pos = 0; - outFd.fd = outStream; - outFd.pos = 0; - - do { - if ((rc = getNextHeader(&inFd, &ch, &pHeader))) { - fprintf(stderr, _("error %d reading header: %s\n"), rc, - myCpioStrerror(rc)); - return CPIOERR_BAD_HEADER; - } +int myCpioFilterArchive(gzFile inStream, gzFile outStream, char **patterns) +{ + struct ourfd inFd, outFd; + char **aPattern; + struct cpioHeader ch; + int rc; + struct cpioCrcPhysicalHeader pHeader; + + inFd.fd = inStream; + inFd.pos = 0; + outFd.fd = outStream; + outFd.pos = 0; + + do { + if ((rc = getNextHeader(&inFd, &ch, &pHeader))) { + fprintf(stderr, _("error %d reading header: %s\n"), rc, + myCpioStrerror(rc)); + return CPIOERR_BAD_HEADER; + } - if (!strcmp(ch.path, TRAILER)) { - free(ch.path); - break; - } + if (!strcmp(ch.path, TRAILER)) { + free(ch.path); + break; + } - for (aPattern = patterns; *aPattern; aPattern++) - if (!fnmatch(*aPattern, ch.path, FNM_PATHNAME | FNM_PERIOD)) - break; + for (aPattern = patterns; *aPattern; aPattern++) + if (!fnmatch + (*aPattern, ch.path, FNM_PATHNAME | FNM_PERIOD)) + break; - if (!*aPattern) - eatBytes(&inFd, ch.size); - else - copyFile(&inFd, &outFd, &ch, &pHeader); + if (!*aPattern) + eatBytes(&inFd, ch.size); + else + copyFile(&inFd, &outFd, &ch, &pHeader); - padinfd(&inFd, 4); + padinfd(&inFd, 4); - free(ch.path); - } while (1 && !rc); + free(ch.path); + } while (1 && !rc); - memset(&pHeader, '0', sizeof(pHeader)); - memcpy(pHeader.magic, CPIO_NEWC_MAGIC, sizeof(pHeader.magic)); - memcpy(pHeader.nlink, "00000001", 8); - memcpy(pHeader.namesize, "0000000b", 8); - gzip_write(outFd.fd, &pHeader, PHYS_HDR_SIZE); - gzip_write(outFd.fd, "TRAILER!!!", 11); + memset(&pHeader, '0', sizeof(pHeader)); + memcpy(pHeader.magic, CPIO_NEWC_MAGIC, sizeof(pHeader.magic)); + memcpy(pHeader.nlink, "00000001", 8); + memcpy(pHeader.namesize, "0000000b", 8); + gzip_write(outFd.fd, &pHeader, PHYS_HDR_SIZE); + gzip_write(outFd.fd, "TRAILER!!!", 11); - outFd.pos += PHYS_HDR_SIZE + 11; + outFd.pos += PHYS_HDR_SIZE + 11; - if ((rc = padoutfd(&outFd, &outFd.pos, 4))) - return rc; + if ((rc = padoutfd(&outFd, &outFd.pos, 4))) + return rc; - if ((rc = padoutfd(&outFd, &outFd.pos, 512))) - return rc; + if ((rc = padoutfd(&outFd, &outFd.pos, 512))) + return rc; - return 0; + return 0; } /* vim:set sw=8 noet */ diff --git a/isys/vio.c b/isys/vio.c index a7ea344..0f2c419 100644 --- a/isys/vio.c +++ b/isys/vio.c @@ -28,80 +28,83 @@ #include <unistd.h> #if defined(__powerpc__) -static int readFD (int fd, char **buf) +static int readFD(int fd, char **buf) { - char *p; - size_t size = 4096; - int s, filesize; + char *p; + size_t size = 4096; + int s, filesize; - *buf = malloc (size); - if (*buf == 0) - return -1; + *buf = malloc(size); + if (*buf == 0) + return -1; - filesize = 0; - do { - p = &(*buf) [filesize]; - s = read (fd, p, 4096); - if (s < 0) - break; - filesize += s; - if (s == 0) - break; - size += 4096; - *buf = realloc (*buf, size); - } while (1); + filesize = 0; + do { + p = &(*buf)[filesize]; + s = read(fd, p, 4096); + if (s < 0) + break; + filesize += s; + if (s == 0) + break; + size += 4096; + *buf = realloc(*buf, size); + } while (1); - if (filesize == 0 && s < 0) { - free (*buf); - *buf = NULL; - return -1; - } + if (filesize == 0 && s < 0) { + free(*buf); + *buf = NULL; + return -1; + } - return filesize; + return filesize; } #endif -int isVioConsole(void) { +int isVioConsole(void) +{ #if !defined(__powerpc__) - return 0; + return 0; #else - int fd, i; - char *buf, *start; - char driver[50], device[50]; - static int isviocons = -1; + int fd, i; + char *buf, *start; + char driver[50], device[50]; + static int isviocons = -1; - if (isviocons != -1) - return isviocons; - - fd = open("/proc/tty/drivers", O_RDONLY); - if (fd < 0) { - fprintf(stderr, "failed to open /proc/tty/drivers!\n"); - return 0; - } - i = readFD(fd, &buf); - if (i < 1) { - close(fd); - fprintf(stderr, "error reading /proc/tty/drivers!\n"); - return 0; - } - close(fd); - buf[i] = '\0'; + if (isviocons != -1) + return isviocons; + + fd = open("/proc/tty/drivers", O_RDONLY); + if (fd < 0) { + fprintf(stderr, "failed to open /proc/tty/drivers!\n"); + return 0; + } + i = readFD(fd, &buf); + if (i < 1) { + close(fd); + fprintf(stderr, "error reading /proc/tty/drivers!\n"); + return 0; + } + close(fd); + buf[i] = '\0'; - isviocons = 0; - start = buf; - while (start && *start) { - if (sscanf(start, "%s %s", (char *) &driver, (char *) &device) == 2) { - if (!strcmp(driver, "vioconsole") && !strcmp(device, "/dev/tty")) { - isviocons = 1; - break; - } - } - start = strchr(start, '\n'); - if (start) - start++; - } - free(buf); - return isviocons; + isviocons = 0; + start = buf; + while (start && *start) { + if (sscanf(start, "%s %s", (char *)&driver, (char *)&device) == + 2) { + if (!strcmp(driver, "vioconsole") + && !strcmp(device, "/dev/tty")) { + isviocons = 1; + break; + } + } + start = strchr(start, '\n'); + if (start) + start++; + } + free(buf); + return isviocons; #endif } diff --git a/loader/cdinstall.c b/loader/cdinstall.c index ba5c2a3..4996c5a 100644 --- a/loader/cdinstall.c +++ b/loader/cdinstall.c @@ -38,7 +38,7 @@ /* Hack both __BIG_ENDIAN and __LITTLE_ENDIAN get defined by glibc, the kernel headers we need do not like this! */ #if __BYTE_ORDER == __LITTLE_ENDIAN -#undef __BIG_ENDIAN +#undef __BIG_ENDIAN #else #undef __LITTLE_ENDIAN #endif @@ -64,223 +64,240 @@ extern uint64_t flags; /* ejects the CD device the device node points at */ -static void ejectCdrom(char *device) { - int ejectfd; - - if (!device) return; - logMessage(INFO, "ejecting %s...",device); - if ((ejectfd = open(device, O_RDONLY | O_NONBLOCK, 0)) >= 0) { - ioctl(ejectfd, CDROM_LOCKDOOR, 0); - if (ioctl(ejectfd, CDROMEJECT, 0)) - logMessage(ERROR, "eject failed on device %s: %m", device); - close(ejectfd); - } else { - logMessage(ERROR, "could not open device %s: %m", device); - } +static void ejectCdrom(char *device) +{ + int ejectfd; + + if (!device) + return; + logMessage(INFO, "ejecting %s...", device); + if ((ejectfd = open(device, O_RDONLY | O_NONBLOCK, 0)) >= 0) { + ioctl(ejectfd, CDROM_LOCKDOOR, 0); + if (ioctl(ejectfd, CDROMEJECT, 0)) + logMessage(ERROR, "eject failed on device %s: %m", + device); + close(ejectfd); + } else { + logMessage(ERROR, "could not open device %s: %m", device); + } } -static char *cdrom_drive_status(int rc) { - struct { - int code; - char *str; - } status_codes[] = - { - { CDS_NO_INFO, "CDS_NO_INFO" }, - { CDS_NO_DISC, "CDS_NO_DISC" }, - { CDS_TRAY_OPEN, "CDS_TRAY_OPEN" }, - { CDS_DRIVE_NOT_READY, "CDS_DRIVE_NOT_READY" }, - { CDS_DISC_OK, "CDS_DISC_OK" }, - { CDS_AUDIO, "CDS_AUDIO" }, - { CDS_DATA_1, "CDS_DATA_1" }, - { CDS_DATA_2, "CDS_DATA_2" }, - { CDS_XA_2_1, "CDS_XA_2_1" }, - { CDS_XA_2_2, "CDS_XA_2_2" }, - { CDS_MIXED, "CDS_MIXED" }, - { INT_MAX, NULL }, - }; - int i; - - if (rc < 0) - return strerror(-rc); - - for (i = 0; status_codes[i].code != INT_MAX; i++) { - if (status_codes[i].code == rc) - return status_codes[i].str; - } - return NULL; +static char *cdrom_drive_status(int rc) +{ + struct { + int code; + char *str; + } status_codes[] = { + { + CDS_NO_INFO, "CDS_NO_INFO"}, { + CDS_NO_DISC, "CDS_NO_DISC"}, { + CDS_TRAY_OPEN, "CDS_TRAY_OPEN"}, { + CDS_DRIVE_NOT_READY, "CDS_DRIVE_NOT_READY"}, { + CDS_DISC_OK, "CDS_DISC_OK"}, { + CDS_AUDIO, "CDS_AUDIO"}, { + CDS_DATA_1, "CDS_DATA_1"}, { + CDS_DATA_2, "CDS_DATA_2"}, { + CDS_XA_2_1, "CDS_XA_2_1"}, { + CDS_XA_2_2, "CDS_XA_2_2"}, { + CDS_MIXED, "CDS_MIXED"}, { + INT_MAX, NULL},}; + int i; + + if (rc < 0) + return strerror(-rc); + + for (i = 0; status_codes[i].code != INT_MAX; i++) { + if (status_codes[i].code == rc) + return status_codes[i].str; + } + return NULL; } -static int waitForCdromTrayClose(int fd) { - int rc; - int prev = INT_MAX; - - do { - char *status = NULL; - rc = ioctl(fd, CDROM_DRIVE_STATUS, CDSL_CURRENT); - if (rc < 0) - rc = -errno; - - /* only bother to print the status if it changes */ - if (prev == INT_MAX || prev != rc) { - status = cdrom_drive_status(rc); - if (status != NULL) { - logMessage(INFO, "drive status is %s", status); - } else { - logMessage(INFO, "drive status is unknown status code %d", rc); - } - } - prev = rc; - if (rc == CDS_DRIVE_NOT_READY) - usleep(100000); - } while (rc == CDS_DRIVE_NOT_READY); - return rc; +static int waitForCdromTrayClose(int fd) +{ + int rc; + int prev = INT_MAX; + + do { + char *status = NULL; + rc = ioctl(fd, CDROM_DRIVE_STATUS, CDSL_CURRENT); + if (rc < 0) + rc = -errno; + + /* only bother to print the status if it changes */ + if (prev == INT_MAX || prev != rc) { + status = cdrom_drive_status(rc); + if (status != NULL) { + logMessage(INFO, "drive status is %s", status); + } else { + logMessage(INFO, + "drive status is unknown status code %d", + rc); + } + } + prev = rc; + if (rc == CDS_DRIVE_NOT_READY) + usleep(100000); + } while (rc == CDS_DRIVE_NOT_READY); + return rc; } -static void closeCdromTray(char *device) { - int fd; - - if (!device || !*device) - return; - - logMessage(INFO, "closing CD tray on %s .", device); - if ((fd = open(device, O_RDONLY | O_NONBLOCK, 0)) >= 0) { - if (ioctl(fd, CDROMCLOSETRAY, 0)) { - logMessage(ERROR, "closetray failed on device %s: %m", device); - } else { - waitForCdromTrayClose(fd); - ioctl(fd, CDROM_LOCKDOOR, 1); - } - close(fd); - } else { - logMessage(ERROR, "could not open device %s: %m", device); - } +static void closeCdromTray(char *device) +{ + int fd; + + if (!device || !*device) + return; + + logMessage(INFO, "closing CD tray on %s .", device); + if ((fd = open(device, O_RDONLY | O_NONBLOCK, 0)) >= 0) { + if (ioctl(fd, CDROMCLOSETRAY, 0)) { + logMessage(ERROR, "closetray failed on device %s: %m", + device); + } else { + waitForCdromTrayClose(fd); + ioctl(fd, CDROM_LOCKDOOR, 1); + } + close(fd); + } else { + logMessage(ERROR, "could not open device %s: %m", device); + } } /* Given cd device cddriver, this function will attempt to check its internal * checksum. */ -static void mediaCheckCdrom(char *cddriver) { - int rc; - int first; - - first = 1; - do { - char *descr; - char *tstamp; - int ejectcd; - - /* init every pass */ - ejectcd = 0; - descr = NULL; - - closeCdromTray(cddriver); - - /* if first time through, see if they want to eject the CD */ - /* currently in the drive (most likely the CD they booted from) */ - /* and test a different disk. Otherwise just test the disk in */ - /* the drive since it was inserted in the previous pass through */ - /* this loop, so they want it tested. */ - if (first) { - first = 0; - rc = newtWinChoice(_("Media Check"), _("Test"), _("Eject Disc"), - _("Choose \"%s\" to test the disc currently in " - "the drive, or \"%s\" to eject the disc and " - "insert another for testing."), _("Test"), - _("Eject Disc")); - - if (rc == 2) - ejectcd = 1; - } - - if (!ejectcd) { - /* XXX MSFFIXME: should check return code for error */ - readStampFileFromIso(cddriver, &tstamp, &descr); - doMediaCheck(cddriver, descr); - - if (descr) - free(descr); - } - - ejectCdrom(cddriver); - - rc = newtWinChoice(_("Media Check"), _("Test"), _("Continue"), - _("If you would like to test additional media, " - "insert the next disc and press \"%s\". " - "Testing each disc is not strictly required, however " - "it is highly recommended. Minimally, the discs should " - "be tested prior to using them for the first time. " - "After they have been successfully tested, it is not " - "required to retest each disc prior to using it again."), - _("Test"), _("Continue")); - - if (rc == 2) { - closeCdromTray(cddriver); - return; - } else { - continue; - } - } while (1); +static void mediaCheckCdrom(char *cddriver) +{ + int rc; + int first; + + first = 1; + do { + char *descr; + char *tstamp; + int ejectcd; + + /* init every pass */ + ejectcd = 0; + descr = NULL; + + closeCdromTray(cddriver); + + /* if first time through, see if they want to eject the CD */ + /* currently in the drive (most likely the CD they booted from) */ + /* and test a different disk. Otherwise just test the disk in */ + /* the drive since it was inserted in the previous pass through */ + /* this loop, so they want it tested. */ + if (first) { + first = 0; + rc = newtWinChoice(_("Media Check"), _("Test"), + _("Eject Disc"), + _ + ("Choose \"%s\" to test the disc currently in " + "the drive, or \"%s\" to eject the disc and " + "insert another for testing."), + _("Test"), _("Eject Disc")); + + if (rc == 2) + ejectcd = 1; + } + + if (!ejectcd) { + /* XXX MSFFIXME: should check return code for error */ + readStampFileFromIso(cddriver, &tstamp, &descr); + doMediaCheck(cddriver, descr); + + if (descr) + free(descr); + } + + ejectCdrom(cddriver); + + rc = newtWinChoice(_("Media Check"), _("Test"), _("Continue"), + _ + ("If you would like to test additional media, " + "insert the next disc and press \"%s\". " + "Testing each disc is not strictly required, however " + "it is highly recommended. Minimally, the discs should " + "be tested prior to using them for the first time. " + "After they have been successfully tested, it is not " + "required to retest each disc prior to using it again."), + _("Test"), _("Continue")); + + if (rc == 2) { + closeCdromTray(cddriver); + return; + } else { + continue; + } + } while (1); } /* output an error message when CD in drive is not the correct one */ /* Used by mountCdromStage2() */ -static void wrongCDMessage(void) { - newtWinMessage(_("Error"), _("OK"), - _("The %s disc was not found " - "in any of your drives. Please insert " - "the %s disc and press %s to retry."), - getProductName(), getProductName(), _("OK")); +static void wrongCDMessage(void) +{ + newtWinMessage(_("Error"), _("OK"), + _("The %s disc was not found " + "in any of your drives. Please insert " + "the %s disc and press %s to retry."), + getProductName(), getProductName(), _("OK")); } /* ask about doing media check */ -static void queryCDMediaCheck(char *dev, char *location) { - int rc; - char *stage2loc; - - /* dont bother to test in automated installs */ - if (FL_KICKSTART(flags) && !FL_MEDIACHECK(flags)) - return; - - /* see if we should check image(s) */ - /* in rescue mode only test if they explicitly asked to */ - if (!FL_RESCUE(flags) || FL_MEDIACHECK(flags)) { - startNewt(); - rc = newtWinChoice(_("Disc Found"), _("OK"), _("Skip"), - _("To begin testing the media before installation press %s.\n\n" - "Choose %s to skip the media test and start the installation."), - _("OK"), _("Skip")); - - if (rc != 2) { - /* We already mounted the CD earlier to verify there's at least a - * stage2 image. Now we need to unmount to perform the check, then - * remount to pretend nothing ever happened. - */ - umount(location); - mediaCheckCdrom(dev); - - do { - if (doPwMount(dev, location, "iso9660", "ro", NULL)) { - ejectCdrom(dev); - wrongCDMessage(); - continue; - } - - checked_asprintf(&stage2loc, "%s/images/install.img", - location); - - if (access(stage2loc, R_OK)) { - free(stage2loc); - umount(location); - ejectCdrom(dev); - wrongCDMessage(); - continue; - } - - free(stage2loc); - break; - } while (1); - } - } +static void queryCDMediaCheck(char *dev, char *location) +{ + int rc; + char *stage2loc; + + /* dont bother to test in automated installs */ + if (FL_KICKSTART(flags) && !FL_MEDIACHECK(flags)) + return; + + /* see if we should check image(s) */ + /* in rescue mode only test if they explicitly asked to */ + if (!FL_RESCUE(flags) || FL_MEDIACHECK(flags)) { + startNewt(); + rc = newtWinChoice(_("Disc Found"), _("OK"), _("Skip"), + _ + ("To begin testing the media before installation press %s.\n\n" + "Choose %s to skip the media test and start the installation."), + _("OK"), _("Skip")); + + if (rc != 2) { + /* We already mounted the CD earlier to verify there's at least a + * stage2 image. Now we need to unmount to perform the check, then + * remount to pretend nothing ever happened. + */ + umount(location); + mediaCheckCdrom(dev); + + do { + if (doPwMount + (dev, location, "iso9660", "ro", NULL)) { + ejectCdrom(dev); + wrongCDMessage(); + continue; + } + + checked_asprintf(&stage2loc, + "%s/images/install.img", + location); + + if (access(stage2loc, R_OK)) { + free(stage2loc); + umount(location); + ejectCdrom(dev); + wrongCDMessage(); + continue; + } + + free(stage2loc); + break; + } while (1); + } + } } /* Set up a CD/DVD drive to mount the stage2 image from. If successful, the @@ -292,218 +309,254 @@ static void queryCDMediaCheck(char *dev, char *location) { * mediaCheck: Do we run media check or not? */ static char *setupCdrom(char *location, struct loaderData_s *loaderData, - int interactive, int mediaCheck) { - int i, rc; - int stage2inram = 0; - char *retbuf = NULL, *stage2loc, *stage2img; - struct device ** devices; - char *cddev = NULL; - - devices = getDevices(DEVICE_CDROM); - if (!devices) { - logMessage(ERROR, "got to setupCdrom without a CD device"); - return NULL; - } - - checked_asprintf(&stage2loc, "%s/images/install.img", location); - - /* JKFIXME: ASSERT -- we have a cdrom device when we get here */ - do { - for (i = 0; devices[i]; i++) { - char *tmp = NULL; - int fd; - - if (!devices[i]->device) - continue; - - if (strncmp("/dev/", devices[i]->device, 5)) { - checked_asprintf(&tmp, "/dev/%s", devices[i]->device); - - free(devices[i]->device); - devices[i]->device = tmp; - } - - logMessage(INFO, "trying to mount CD device %s on %s", - devices[i]->device, location); - - if (!FL_CMDLINE(flags)) - winStatus(60, 3, _("Scanning"), _("Looking for installation images on CD device %s\n"), devices[i]->device); - else - printf(_("Looking for installation images on CD device %s"), devices[i]->device); - - fd = open(devices[i]->device, O_RDONLY | O_NONBLOCK); - if (fd < 0) { - logMessage(ERROR, "Couldn't open %s: %m", devices[i]->device); - if (!FL_CMDLINE(flags)) - newtPopWindow(); - continue; - } - - rc = waitForCdromTrayClose(fd); - close(fd); - switch (rc) { - case CDS_NO_INFO: - logMessage(ERROR, "Drive tray reports CDS_NO_INFO"); - break; - case CDS_NO_DISC: - if (!FL_CMDLINE(flags)) - newtPopWindow(); - continue; - case CDS_TRAY_OPEN: - logMessage(ERROR, "Drive tray reports open when it should be closed"); - break; - default: - break; - } - - if (!FL_CMDLINE(flags)) - newtPopWindow(); - - if (!(rc=doPwMount(devices[i]->device, location, "iso9660", "ro", NULL))) { - cddev = devices[i]->device; - if (!access(stage2loc, R_OK)) { - char *updpath; - - if (mediaCheck) - queryCDMediaCheck(devices[i]->device, location); - - /* if in rescue mode lets copy stage 2 into RAM so we can */ - /* free up the CD drive and user can have it avaiable to */ - /* aid system recovery. */ - if (FL_RESCUE(flags) && !FL_TEXT(flags) && - totalMemory() > MIN_GUI_RAM ) { - rc = copyFile(stage2loc, "/tmp/install.img"); - stage2img = strdup("/tmp/install.img"); - stage2inram = 1; - } else { - stage2img = strdup(stage2loc); - stage2inram = 0; - } - - rc = mountStage2(stage2img); - free(stage2img); - - if (rc) { - logMessage(INFO, "mounting stage2 failed"); - umount(location); - continue; - } - - checked_asprintf(&updpath, "%s/images/updates.img", location); - - logMessage(INFO, "Looking for updates in %s", updpath); - copyUpdatesImg(updpath); - free(updpath); - - checked_asprintf(&updpath, "%s/images/product.img", location); - - logMessage(INFO, "Looking for product in %s", updpath); - copyProductImg(updpath); - free(updpath); - - /* if in rescue mode and we copied stage2 to RAM */ - /* we can now unmount the CD */ - if (FL_RESCUE(flags) && stage2inram) { - umount(location); - } - - checked_asprintf(&retbuf, "cdrom://%s:%s", - devices[i]->device, location); - } else { - /* this wasnt the CD we were looking for, clean up and */ - /* try the next CD drive */ - umount(location); - } - } - } - - if (!retbuf) { - if (interactive) { - char * buf; - - checked_asprintf(&buf, _("The %s disc was not found in any of your " - "CDROM drives. Please insert the %s disc " - "and press %s to retry."), - getProductName(), getProductName(), _("OK")); - - ejectCdrom(cddev); - rc = newtWinChoice(_("Disc Not Found"), - _("OK"), _("Back"), buf, _("OK")); - free(buf); - if (rc == 2) - goto err; - } else { - /* we can't ask them about it, so just return not found */ - goto err; - } - } - } while (!retbuf); + int interactive, int mediaCheck) +{ + int i, rc; + int stage2inram = 0; + char *retbuf = NULL, *stage2loc, *stage2img; + struct device **devices; + char *cddev = NULL; + + devices = getDevices(DEVICE_CDROM); + if (!devices) { + logMessage(ERROR, "got to setupCdrom without a CD device"); + return NULL; + } + + checked_asprintf(&stage2loc, "%s/images/install.img", location); + + /* JKFIXME: ASSERT -- we have a cdrom device when we get here */ + do { + for (i = 0; devices[i]; i++) { + char *tmp = NULL; + int fd; + + if (!devices[i]->device) + continue; + + if (strncmp("/dev/", devices[i]->device, 5)) { + checked_asprintf(&tmp, "/dev/%s", + devices[i]->device); + + free(devices[i]->device); + devices[i]->device = tmp; + } + + logMessage(INFO, "trying to mount CD device %s on %s", + devices[i]->device, location); + + if (!FL_CMDLINE(flags)) + winStatus(60, 3, _("Scanning"), + _ + ("Looking for installation images on CD device %s\n"), + devices[i]->device); + else + printf(_ + ("Looking for installation images on CD device %s"), + devices[i]->device); + + fd = open(devices[i]->device, O_RDONLY | O_NONBLOCK); + if (fd < 0) { + logMessage(ERROR, "Couldn't open %s: %m", + devices[i]->device); + if (!FL_CMDLINE(flags)) + newtPopWindow(); + continue; + } + + rc = waitForCdromTrayClose(fd); + close(fd); + switch (rc) { + case CDS_NO_INFO: + logMessage(ERROR, + "Drive tray reports CDS_NO_INFO"); + break; + case CDS_NO_DISC: + if (!FL_CMDLINE(flags)) + newtPopWindow(); + continue; + case CDS_TRAY_OPEN: + logMessage(ERROR, + "Drive tray reports open when it should be closed"); + break; + default: + break; + } + + if (!FL_CMDLINE(flags)) + newtPopWindow(); + + if (! + (rc = + doPwMount(devices[i]->device, location, "iso9660", + "ro", NULL))) { + cddev = devices[i]->device; + if (!access(stage2loc, R_OK)) { + char *updpath; + + if (mediaCheck) + queryCDMediaCheck(devices + [i]->device, + location); + + /* if in rescue mode lets copy stage 2 into RAM so we can */ + /* free up the CD drive and user can have it avaiable to */ + /* aid system recovery. */ + if (FL_RESCUE(flags) && !FL_TEXT(flags) + && totalMemory() > MIN_GUI_RAM) { + rc = copyFile(stage2loc, + "/tmp/install.img"); + stage2img = + strdup("/tmp/install.img"); + stage2inram = 1; + } else { + stage2img = strdup(stage2loc); + stage2inram = 0; + } + + rc = mountStage2(stage2img); + free(stage2img); + + if (rc) { + logMessage(INFO, + "mounting stage2 failed"); + umount(location); + continue; + } + + checked_asprintf(&updpath, + "%s/images/updates.img", + location); + + logMessage(INFO, + "Looking for updates in %s", + updpath); + copyUpdatesImg(updpath); + free(updpath); + + checked_asprintf(&updpath, + "%s/images/product.img", + location); + + logMessage(INFO, + "Looking for product in %s", + updpath); + copyProductImg(updpath); + free(updpath); + + /* if in rescue mode and we copied stage2 to RAM */ + /* we can now unmount the CD */ + if (FL_RESCUE(flags) && stage2inram) { + umount(location); + } + + checked_asprintf(&retbuf, + "cdrom://%s:%s", + devices[i]->device, + location); + } else { + /* this wasnt the CD we were looking for, clean up and */ + /* try the next CD drive */ + umount(location); + } + } + } + + if (!retbuf) { + if (interactive) { + char *buf; + + checked_asprintf(&buf, + _ + ("The %s disc was not found in any of your " + "CDROM drives. Please insert the %s disc " + "and press %s to retry."), + getProductName(), + getProductName(), _("OK")); + + ejectCdrom(cddev); + rc = newtWinChoice(_("Disc Not Found"), + _("OK"), _("Back"), buf, + _("OK")); + free(buf); + if (rc == 2) + goto err; + } else { + /* we can't ask them about it, so just return not found */ + goto err; + } + } + } while (!retbuf); err: - free(stage2loc); - return retbuf; + free(stage2loc); + return retbuf; } /* try to find a install CD non-interactively */ -char * findAnacondaCD(char *location) { - return setupCdrom(location, NULL, 0, 1); +char *findAnacondaCD(char *location) +{ + return setupCdrom(location, NULL, 0, 1); } /* look for a CD and mount it. if we have problems, ask */ -char * mountCdromImage(struct installMethod * method, - char * location, struct loaderData_s * loaderData) { - return setupCdrom(location, loaderData, 1, 1); +char *mountCdromImage(struct installMethod *method, + char *location, struct loaderData_s *loaderData) +{ + return setupCdrom(location, loaderData, 1, 1); } -void setKickstartCD(struct loaderData_s * loaderData, int argc, char ** argv) { +void setKickstartCD(struct loaderData_s *loaderData, int argc, char **argv) +{ - logMessage(INFO, "kickstartFromCD"); - loaderData->method = METHOD_CDROM; + logMessage(INFO, "kickstartFromCD"); + loaderData->method = METHOD_CDROM; } -int kickstartFromCD(char *kssrc) { - int rc, i; - char *p, *kspath; - struct device ** devices; - - logMessage(INFO, "getting kickstart file from first CDROM"); - - devices = getDevices(DEVICE_CDROM); - /* usb can take some time to settle, even with the various hacks we - * have in place. some systems use portable USB CD-ROM drives, try to - * make sure there really isn't one before bailing */ - for (i = 0; !devices && i < 10; ++i) { - logMessage(INFO, "sleeping to wait for a USB CD-ROM"); - sleep(2); - devices = getDevices(DEVICE_CDROM); - } - if (!devices) { - logMessage(ERROR, "No CDROM devices found!"); - return 1; - } - - /* format is cdrom:[/path/to/ks.cfg] */ - kspath = ""; - p = strchr(kssrc, ':'); - if (p) - kspath = p + 1; - - if (!p || strlen(kspath) < 1) - kspath = "/ks.cfg"; - - for (i=0; devices[i]; i++) { - if (!devices[i]->device) - continue; - - rc = getKickstartFromBlockDevice(devices[i]->device, kspath); - if (rc == 0) - return 0; - } - - startNewt(); - newtWinMessage(_("Error"), _("OK"), - _("Cannot find kickstart file on CDROM.")); - return 1; +int kickstartFromCD(char *kssrc) +{ + int rc, i; + char *p, *kspath; + struct device **devices; + + logMessage(INFO, "getting kickstart file from first CDROM"); + + devices = getDevices(DEVICE_CDROM); + /* usb can take some time to settle, even with the various hacks we + * have in place. some systems use portable USB CD-ROM drives, try to + * make sure there really isn't one before bailing */ + for (i = 0; !devices && i < 10; ++i) { + logMessage(INFO, "sleeping to wait for a USB CD-ROM"); + sleep(2); + devices = getDevices(DEVICE_CDROM); + } + if (!devices) { + logMessage(ERROR, "No CDROM devices found!"); + return 1; + } + + /* format is cdrom:[/path/to/ks.cfg] */ + kspath = ""; + p = strchr(kssrc, ':'); + if (p) + kspath = p + 1; + + if (!p || strlen(kspath) < 1) + kspath = "/ks.cfg"; + + for (i = 0; devices[i]; i++) { + if (!devices[i]->device) + continue; + + rc = getKickstartFromBlockDevice(devices[i]->device, kspath); + if (rc == 0) + return 0; + } + + startNewt(); + newtWinMessage(_("Error"), _("OK"), + _("Cannot find kickstart file on CDROM.")); + return 1; } /* vim:set sw=8 noet */ diff --git a/loader/cdinstall.h b/loader/cdinstall.h index ceafcb0..440eba9 100644 --- a/loader/cdinstall.h +++ b/loader/cdinstall.h @@ -22,13 +22,12 @@ #include "method.h" -char * mountCdromImage(struct installMethod * method, - char * location, struct loaderData_s * loaderData); +char *mountCdromImage(struct installMethod *method, + char *location, struct loaderData_s *loaderData); -char * findAnacondaCD(char * location); +char *findAnacondaCD(char *location); -void setKickstartCD(struct loaderData_s * loaderData, int argc, - char ** argv); +void setKickstartCD(struct loaderData_s *loaderData, int argc, char **argv); int kickstartFromCD(char *kssrc); #endif diff --git a/loader/copy.c b/loader/copy.c index 5edb753..66eb1d1 100644 --- a/loader/copy.c +++ b/loader/copy.c @@ -31,113 +31,127 @@ #include "lang.h" /* Recursive */ -int copyDirectory(char * from, char * to, void (*warnFn)(char *), - void (*errorFn)(char *)) { - char *msg; - DIR * dir; - struct dirent * ent; - int fd, outfd; - char buf[4096]; - int i; - struct stat sb; - char filespec[256]; - char filespec2[256]; - char link[1024]; - - mkdir(to, 0755); - - if (!(dir = opendir(from))) { - if (errorFn) { - if (asprintf(&msg, N_("Failed to read directory %s: %m"), from) == -1) { - fprintf(stderr, "%s: %d: %m\n", __func__, __LINE__); - fflush(stderr); - abort(); - } - - errorFn(msg); - free(msg); - } - - return 1; - } - - errno = 0; - while ((ent = readdir(dir))) { - if (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..")) - continue; - - sprintf(filespec, "%s/%s", from, ent->d_name); - sprintf(filespec2, "%s/%s", to, ent->d_name); - - lstat(filespec, &sb); - - if (S_ISDIR(sb.st_mode)) { - if (copyDirectory(filespec, filespec2, warnFn, errorFn)) { - closedir(dir); - return 1; - } - } else if (S_ISLNK(sb.st_mode)) { - i = readlink(filespec, link, sizeof(link) - 1); - link[i] = '\0'; - if (symlink(link, filespec2)) { - if (warnFn) { - if (asprintf(&msg, "Failed to symlink %s to %s: %m", - filespec2, link) == -1) { - fprintf(stderr, "%s: %d: %m\n", __func__, __LINE__); - fflush(stderr); - abort(); - } - - warnFn(msg); - free(msg); - } - } - } else { - fd = open(filespec, O_RDONLY); - if (fd == -1) { - if (errorFn) { - if (asprintf(&msg, "Failed to open %s: %m", filespec) == -1) { - fprintf(stderr, "%s: %d: %m\n", __func__, __LINE__); - fflush(stderr); - abort(); - } - - errorFn(msg); - free(msg); - } - - closedir(dir); - return 1; - } - outfd = open(filespec2, O_RDWR | O_TRUNC | O_CREAT, 0644); - if (outfd == -1) { - if (warnFn) { - if (asprintf(&msg, "Failed to create %s: %m", filespec2) == -1) { - fprintf(stderr, "%s: %d: %m\n", __func__, __LINE__); - fflush(stderr); - abort(); - } - - warnFn(msg); - free(msg); - } - } else { - fchmod(outfd, sb.st_mode & 07777); - - while ((i = read(fd, buf, sizeof(buf))) > 0) - i = write(outfd, buf, i); - close(outfd); - } - - close(fd); - } - - errno = 0; - } - - closedir(dir); - - return 0; +int copyDirectory(char *from, char *to, void (*warnFn) (char *), + void (*errorFn) (char *)) +{ + char *msg; + DIR *dir; + struct dirent *ent; + int fd, outfd; + char buf[4096]; + int i; + struct stat sb; + char filespec[256]; + char filespec2[256]; + char link[1024]; + + mkdir(to, 0755); + + if (!(dir = opendir(from))) { + if (errorFn) { + if (asprintf + (&msg, N_("Failed to read directory %s: %m"), + from) == -1) { + fprintf(stderr, "%s: %d: %m\n", __func__, + __LINE__); + fflush(stderr); + abort(); + } + + errorFn(msg); + free(msg); + } + + return 1; + } + + errno = 0; + while ((ent = readdir(dir))) { + if (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..")) + continue; + + sprintf(filespec, "%s/%s", from, ent->d_name); + sprintf(filespec2, "%s/%s", to, ent->d_name); + + lstat(filespec, &sb); + + if (S_ISDIR(sb.st_mode)) { + if (copyDirectory(filespec, filespec2, warnFn, errorFn)) { + closedir(dir); + return 1; + } + } else if (S_ISLNK(sb.st_mode)) { + i = readlink(filespec, link, sizeof(link) - 1); + link[i] = '\0'; + if (symlink(link, filespec2)) { + if (warnFn) { + if (asprintf + (&msg, + "Failed to symlink %s to %s: %m", + filespec2, link) == -1) { + fprintf(stderr, "%s: %d: %m\n", + __func__, __LINE__); + fflush(stderr); + abort(); + } + + warnFn(msg); + free(msg); + } + } + } else { + fd = open(filespec, O_RDONLY); + if (fd == -1) { + if (errorFn) { + if (asprintf + (&msg, "Failed to open %s: %m", + filespec) == -1) { + fprintf(stderr, "%s: %d: %m\n", + __func__, __LINE__); + fflush(stderr); + abort(); + } + + errorFn(msg); + free(msg); + } + + closedir(dir); + return 1; + } + outfd = + open(filespec2, O_RDWR | O_TRUNC | O_CREAT, 0644); + if (outfd == -1) { + if (warnFn) { + if (asprintf + (&msg, "Failed to create %s: %m", + filespec2) == -1) { + fprintf(stderr, "%s: %d: %m\n", + __func__, __LINE__); + fflush(stderr); + abort(); + } + + warnFn(msg); + free(msg); + } + } else { + fchmod(outfd, sb.st_mode & 07777); + + while ((i = read(fd, buf, sizeof(buf))) > 0) + i = write(outfd, buf, i); + close(outfd); + } + + close(fd); + } + + errno = 0; + } + + closedir(dir); + + return 0; } /* vim:set sw=8 noet */ diff --git a/loader/copy.h b/loader/copy.h index 289bab7..b11b23a 100644 --- a/loader/copy.h +++ b/loader/copy.h @@ -20,8 +20,8 @@ #ifndef H_COPY #define H_COPY -int copyDirectory (char *from, char *to, void (*warnFn)(char *), - void (*errorFn)(char *)); +int copyDirectory(char *from, char *to, void (*warnFn) (char *), + void (*errorFn) (char *)); #endif diff --git a/loader/devices.h b/loader/devices.h index 6b7f758..31d049a 100644 --- a/loader/devices.h +++ b/loader/devices.h @@ -21,13 +21,13 @@ #define LOADER_INIT_DEVICES_H struct devnode { - char * devname; - int type; - int major; - int minor; - int perms; - char * owner; - char * group; + char *devname; + int type; + int major; + int minor; + int perms; + char *owner; + char *group; }; #define CHARDEV 0 @@ -35,69 +35,69 @@ struct devnode { #define DIRTYPE 2 struct devnode devnodes[] = { - /* consoles */ - {"console", CHARDEV, 5, 1, 0600, "root", "root"}, - {"ttyS0", CHARDEV, 4, 64, 0600, "root", "root"}, - {"ttyS1", CHARDEV, 4, 65, 0600, "root", "root"}, - {"ttyS2", CHARDEV, 4, 66, 0600, "root", "root"}, - {"ttyS3", CHARDEV, 4, 67, 0600, "root", "root"}, + /* consoles */ + {"console", CHARDEV, 5, 1, 0600, "root", "root"}, + {"ttyS0", CHARDEV, 4, 64, 0600, "root", "root"}, + {"ttyS1", CHARDEV, 4, 65, 0600, "root", "root"}, + {"ttyS2", CHARDEV, 4, 66, 0600, "root", "root"}, + {"ttyS3", CHARDEV, 4, 67, 0600, "root", "root"}, #ifdef __ia64__ - {"ttySG0", CHARDEV, 204, 40, 0600, "root", "root"}, + {"ttySG0", CHARDEV, 204, 40, 0600, "root", "root"}, #endif #ifdef __powerpc__ - {"hvsi0", CHARDEV, 229, 128, 0600, "root", "root"}, - {"hvsi1", CHARDEV, 229, 129, 0600, "root", "root"}, - {"hvsi2", CHARDEV, 229, 130, 0600, "root", "root"}, + {"hvsi0", CHARDEV, 229, 128, 0600, "root", "root"}, + {"hvsi1", CHARDEV, 229, 129, 0600, "root", "root"}, + {"hvsi2", CHARDEV, 229, 130, 0600, "root", "root"}, #endif - {"hvc0", CHARDEV, 229, 0, 0600, "root", "root"}, + {"hvc0", CHARDEV, 229, 0, 0600, "root", "root"}, #if defined(__i386__) || defined(__x86_64__) || defined(__ia64__) - {"xvc0", CHARDEV, 204, 191, 0600, "root", "root"}, + {"xvc0", CHARDEV, 204, 191, 0600, "root", "root"}, #endif - /* base unix */ - {"null", CHARDEV, 1, 3, 0666, "root", "root"}, - {"zero", CHARDEV, 1, 5, 0666, "root", "root"}, - {"mem", CHARDEV, 1, 1, 0600, "root", "root"}, - /* ttys */ - {"pts", DIRTYPE, 0, 0, 0755, "root", "root"}, - {"ptmx", CHARDEV, 5, 2, 0666, "root", "root"}, - {"tty", CHARDEV, 5, 0, 0666, "root", "root"}, - {"tty0", CHARDEV, 4, 0, 0600, "root", "tty"}, - {"tty1", CHARDEV, 4, 1, 0600, "root", "tty"}, - {"tty2", CHARDEV, 4, 2, 0600, "root", "tty"}, - {"tty3", CHARDEV, 4, 3, 0600, "root", "tty"}, - {"tty4", CHARDEV, 4, 4, 0600, "root", "tty"}, - {"tty5", CHARDEV, 4, 5, 0600, "root", "tty"}, - {"tty6", CHARDEV, 4, 6, 0600, "root", "tty"}, - {"tty7", CHARDEV, 4, 7, 0600, "root", "tty"}, - {"tty8", CHARDEV, 4, 8, 0600, "root", "tty"}, - {"tty9", CHARDEV, 4, 9, 0600, "root", "tty"}, - /* fb */ - {"fb0", CHARDEV, 29, 0, 0600, "root", "tty"}, - /* sparc specific */ + /* base unix */ + {"null", CHARDEV, 1, 3, 0666, "root", "root"}, + {"zero", CHARDEV, 1, 5, 0666, "root", "root"}, + {"mem", CHARDEV, 1, 1, 0600, "root", "root"}, + /* ttys */ + {"pts", DIRTYPE, 0, 0, 0755, "root", "root"}, + {"ptmx", CHARDEV, 5, 2, 0666, "root", "root"}, + {"tty", CHARDEV, 5, 0, 0666, "root", "root"}, + {"tty0", CHARDEV, 4, 0, 0600, "root", "tty"}, + {"tty1", CHARDEV, 4, 1, 0600, "root", "tty"}, + {"tty2", CHARDEV, 4, 2, 0600, "root", "tty"}, + {"tty3", CHARDEV, 4, 3, 0600, "root", "tty"}, + {"tty4", CHARDEV, 4, 4, 0600, "root", "tty"}, + {"tty5", CHARDEV, 4, 5, 0600, "root", "tty"}, + {"tty6", CHARDEV, 4, 6, 0600, "root", "tty"}, + {"tty7", CHARDEV, 4, 7, 0600, "root", "tty"}, + {"tty8", CHARDEV, 4, 8, 0600, "root", "tty"}, + {"tty9", CHARDEV, 4, 9, 0600, "root", "tty"}, + /* fb */ + {"fb0", CHARDEV, 29, 0, 0600, "root", "tty"}, + /* sparc specific */ #ifdef __sparc__ - {"openprom", CHARDEV, 10, 139, 0644, "root", "root"}, - {"sunmouse", CHARDEV, 10, 6, 0644, "root", "root"}, - {"kbd", CHARDEV, 11, 0, 0644, "root", "root"}, + {"openprom", CHARDEV, 10, 139, 0644, "root", "root"}, + {"sunmouse", CHARDEV, 10, 6, 0644, "root", "root"}, + {"kbd", CHARDEV, 11, 0, 0644, "root", "root"}, #endif - /* X */ - {"agpgart", CHARDEV, 10, 175, 0664, "root", "root"}, - {"psaux", CHARDEV, 10, 1, 0644, "root", "root"}, - {"input", DIRTYPE, 0, 0, 0755, "root", "root"}, - {"input/mice", CHARDEV, 13, 63, 0664, "root", "root"}, - /* floppies */ - {"fd0", BLOCKDEV, 2, 0, 0644, "root", "root"}, - {"fd1", BLOCKDEV, 2, 1, 0644, "root", "root"}, - /* random */ - {"random", CHARDEV, 1, 8, 0644, "root", "root"}, - {"urandom", CHARDEV, 1, 9, 0644, "root", "root"}, - /* mac stuff */ + /* X */ + {"agpgart", CHARDEV, 10, 175, 0664, "root", "root"}, + {"psaux", CHARDEV, 10, 1, 0644, "root", "root"}, + {"input", DIRTYPE, 0, 0, 0755, "root", "root"}, + {"input/mice", CHARDEV, 13, 63, 0664, "root", "root"}, + /* floppies */ + {"fd0", BLOCKDEV, 2, 0, 0644, "root", "root"}, + {"fd1", BLOCKDEV, 2, 1, 0644, "root", "root"}, + /* random */ + {"random", CHARDEV, 1, 8, 0644, "root", "root"}, + {"urandom", CHARDEV, 1, 9, 0644, "root", "root"}, + /* mac stuff */ #ifdef __powerpc__ - {"nvram", CHARDEV, 10, 144, 0644, "root", "root"}, - {"adb", CHARDEV, 56, 0, 0644, "root", "root"}, - {"iseries", DIRTYPE, 0, 0, 0755, "root", "root" }, + {"nvram", CHARDEV, 10, 144, 0644, "root", "root"}, + {"adb", CHARDEV, 56, 0, 0644, "root", "root"}, + {"iseries", DIRTYPE, 0, 0, 0755, "root", "root"}, #endif - {"rtc", CHARDEV, 10, 135, 0644, "root", "root"}, - { NULL, 0, 0, 0, 0, NULL, NULL }, + {"rtc", CHARDEV, 10, 135, 0644, "root", "root"}, + {NULL, 0, 0, 0, 0, NULL, NULL}, }; #endif diff --git a/loader/dirbrowser.c b/loader/dirbrowser.c index 32dab06..cc9fa9d 100644 --- a/loader/dirbrowser.c +++ b/loader/dirbrowser.c @@ -40,50 +40,54 @@ #ifdef STANDALONE #define _(x) x -static int simpleStringCmp(const void * a, const void * b) { - const char * first = *((const char **) a); - const char * second = *((const char **) b); +static int simpleStringCmp(const void *a, const void *b) +{ + const char *first = *((const char **)a); + const char *second = *((const char **)b); - return strcmp(first, second); + return strcmp(first, second); } #endif #define FSTEP 10 -static char ** get_file_list(char * dirname, - int (*filterfunc)(char *, struct dirent *)) { - DIR * dir; - struct dirent *entry; - char ** files; - int numfiles = FSTEP, i = 0; - - dir = opendir(dirname); - if (dir == NULL) { - fprintf(stderr, "error opening %s: %m", dirname); - return NULL; - } - - files = malloc(numfiles * sizeof(char *)); - - while ((entry = readdir(dir))) { - if ((strlen(entry->d_name) == 1) && !strncmp(entry->d_name, ".", 1)) - continue; - if ((strlen(entry->d_name) == 2) && !strncmp(entry->d_name, "..", 2)) - continue; - if (filterfunc && filterfunc(dirname, entry)) - continue; - - files[i] = strdup(entry->d_name); - if (i++ >= (numfiles - 1)) { - numfiles += FSTEP; - files = realloc(files, numfiles * sizeof(char *)); - } - } - files[i] = NULL; - closedir(dir); - - qsort(files, i, sizeof(*files), simpleStringCmp); - return files; +static char **get_file_list(char *dirname, + int (*filterfunc) (char *, struct dirent *)) +{ + DIR *dir; + struct dirent *entry; + char **files; + int numfiles = FSTEP, i = 0; + + dir = opendir(dirname); + if (dir == NULL) { + fprintf(stderr, "error opening %s: %m", dirname); + return NULL; + } + + files = malloc(numfiles * sizeof(char *)); + + while ((entry = readdir(dir))) { + if ((strlen(entry->d_name) == 1) + && !strncmp(entry->d_name, ".", 1)) + continue; + if ((strlen(entry->d_name) == 2) + && !strncmp(entry->d_name, "..", 2)) + continue; + if (filterfunc && filterfunc(dirname, entry)) + continue; + + files[i] = strdup(entry->d_name); + if (i++ >= (numfiles - 1)) { + numfiles += FSTEP; + files = realloc(files, numfiles * sizeof(char *)); + } + } + files[i] = NULL; + closedir(dir); + + qsort(files, i, sizeof(*files), simpleStringCmp); + return files; } /* Browse through a directory structure looking for a file. @@ -98,102 +102,107 @@ static char ** get_file_list(char * dirname, * Function should take arguments of the directory name and * the dirent for the file. */ -char * newt_select_file(char * title, char * text, char * dirname, - int (*filterfunc)(char *, struct dirent *)) { - char ** files; - char * fn = NULL; - int i, done = 0; - char * topdir = dirname; - char * dir = malloc(PATH_MAX); - char * path = NULL; - newtGrid grid, buttons; - newtComponent f, tb, listbox, ok, cancel; - struct stat sb; - struct newtExitStruct es; - - dir = realpath(dirname, dir); - - do { - files = get_file_list(dir, filterfunc); - - f = newtForm(NULL, NULL, 0); - grid = newtCreateGrid(1, 4); - - tb = newtTextboxReflowed(-1, -1, text, 60, 0, 10, 0); - - listbox = newtListbox(12, 65, 10, - NEWT_FLAG_SCROLL | NEWT_FLAG_RETURNEXIT); - - newtListboxSetWidth(listbox, 55); - buttons = newtButtonBar(_("OK"), &ok, _("Cancel"), &cancel, NULL); - newtGridSetField(grid, 0, 0, NEWT_GRID_COMPONENT, tb, - 0, 0, 0, 1, 0, 0); - newtGridSetField(grid, 0, 1, NEWT_GRID_COMPONENT, listbox, - 0, 0, 0, 1, 0, 0); - newtGridSetField(grid, 0, 3, NEWT_GRID_SUBGRID, buttons, - 0, 0, 0, 0, 0, NEWT_GRID_FLAG_GROWX); - - /* if this isn't our topdir, we want to let them go up a dir */ - if (strcmp(topdir, dir)) - newtListboxAppendEntry(listbox, "../", ".."); - - for (i = 0; (files[i] != NULL); i++) { - if ((files[i] == NULL) || (strlen(files[i]) == 0)) continue; - path = malloc(strlen(files[i]) + strlen(dir) + 2); - sprintf(path, "%s/%s", dir, files[i]); - stat(path, &sb); - free(path); - if (S_ISDIR(sb.st_mode)) { - char *dir = malloc(strlen(files[i]) + 2); - sprintf(dir, "%s/", files[i]); - newtListboxAppendEntry(listbox, dir, files[i]); - } else { - newtListboxAppendEntry(listbox, files[i], files[i]); - } - } - - newtGridWrappedWindow(grid, title); - newtGridAddComponentsToForm(grid, f, 1); - newtFormRun(f, &es); - - if (es.reason == NEWT_EXIT_COMPONENT && es.u.co == cancel) { - fn = NULL; - done = -1; - } else { - fn = (char *) newtListboxGetCurrent(listbox); - path = malloc(strlen(fn) + strlen(dir) + 2); - sprintf(path, "%s/%s", dir, fn); - - stat(path, &sb); - if (!S_ISDIR(sb.st_mode)) { - fn = path; - done = 1; - } else { - dir = realpath(path, dir); - free(path); - } - } - - newtGridFree(grid, 1); - newtFormDestroy(f); - newtPopWindow(); - } while (done == 0); - - return fn; +char *newt_select_file(char *title, char *text, char *dirname, + int (*filterfunc) (char *, struct dirent *)) +{ + char **files; + char *fn = NULL; + int i, done = 0; + char *topdir = dirname; + char *dir = malloc(PATH_MAX); + char *path = NULL; + newtGrid grid, buttons; + newtComponent f, tb, listbox, ok, cancel; + struct stat sb; + struct newtExitStruct es; + + dir = realpath(dirname, dir); + + do { + files = get_file_list(dir, filterfunc); + + f = newtForm(NULL, NULL, 0); + grid = newtCreateGrid(1, 4); + + tb = newtTextboxReflowed(-1, -1, text, 60, 0, 10, 0); + + listbox = newtListbox(12, 65, 10, + NEWT_FLAG_SCROLL | NEWT_FLAG_RETURNEXIT); + + newtListboxSetWidth(listbox, 55); + buttons = + newtButtonBar(_("OK"), &ok, _("Cancel"), &cancel, NULL); + newtGridSetField(grid, 0, 0, NEWT_GRID_COMPONENT, tb, 0, 0, 0, + 1, 0, 0); + newtGridSetField(grid, 0, 1, NEWT_GRID_COMPONENT, listbox, 0, 0, + 0, 1, 0, 0); + newtGridSetField(grid, 0, 3, NEWT_GRID_SUBGRID, buttons, 0, 0, + 0, 0, 0, NEWT_GRID_FLAG_GROWX); + + /* if this isn't our topdir, we want to let them go up a dir */ + if (strcmp(topdir, dir)) + newtListboxAppendEntry(listbox, "../", ".."); + + for (i = 0; (files[i] != NULL); i++) { + if ((files[i] == NULL) || (strlen(files[i]) == 0)) + continue; + path = malloc(strlen(files[i]) + strlen(dir) + 2); + sprintf(path, "%s/%s", dir, files[i]); + stat(path, &sb); + free(path); + if (S_ISDIR(sb.st_mode)) { + char *dir = malloc(strlen(files[i]) + 2); + sprintf(dir, "%s/", files[i]); + newtListboxAppendEntry(listbox, dir, files[i]); + } else { + newtListboxAppendEntry(listbox, files[i], + files[i]); + } + } + + newtGridWrappedWindow(grid, title); + newtGridAddComponentsToForm(grid, f, 1); + newtFormRun(f, &es); + + if (es.reason == NEWT_EXIT_COMPONENT && es.u.co == cancel) { + fn = NULL; + done = -1; + } else { + fn = (char *)newtListboxGetCurrent(listbox); + path = malloc(strlen(fn) + strlen(dir) + 2); + sprintf(path, "%s/%s", dir, fn); + + stat(path, &sb); + if (!S_ISDIR(sb.st_mode)) { + fn = path; + done = 1; + } else { + dir = realpath(path, dir); + free(path); + } + } + + newtGridFree(grid, 1); + newtFormDestroy(f); + newtPopWindow(); + } while (done == 0); + + return fn; } #ifdef STANDALONE -int main(int argc, char ** argv) { - char * foo; - - newtInit(); - newtCls(); - - foo = newt_select_file("Get File Name", "foo, blah blah blah", - "/etc", NULL); - newtFinished(); - printf("got %s\n", foo); - return 0; +int main(int argc, char **argv) +{ + char *foo; + + newtInit(); + newtCls(); + + foo = newt_select_file("Get File Name", "foo, blah blah blah", + "/etc", NULL); + newtFinished(); + printf("got %s\n", foo); + return 0; } #endif diff --git a/loader/dirbrowser.h b/loader/dirbrowser.h index 613f8e7..a6be0f9 100644 --- a/loader/dirbrowser.h +++ b/loader/dirbrowser.h @@ -22,8 +22,8 @@ #include <dirent.h> -char * newt_select_file(char * title, char * text, char * dirname, - int (*filterfunc)(char *, struct dirent *)); +char *newt_select_file(char *title, char *text, char *dirname, + int (*filterfunc) (char *, struct dirent *)); #endif diff --git a/loader/driverdisk.c b/loader/driverdisk.c index 2dbce61..7ae41ac 100644 --- a/loader/driverdisk.c +++ b/loader/driverdisk.c @@ -55,115 +55,123 @@ /* boot flags */ extern uint64_t flags; -static char * driverDiskFiles[] = { "modinfo", "modules.dep", - "modules.cgz", "modules.alias", NULL }; - -static int verifyDriverDisk(char *mntpt) { - char ** fnPtr; - char file[200]; - struct stat sb; - - for (fnPtr = driverDiskFiles; *fnPtr; fnPtr++) { - sprintf(file, "%s/%s", mntpt, *fnPtr); - if (access(file, R_OK)) { - logMessage(ERROR, "cannot find %s, bad driver disk", file); - return LOADER_BACK; - } - } - - /* check for both versions */ - sprintf(file, "%s/rhdd", mntpt); - if (access(file, R_OK)) { - logMessage(DEBUGLVL, "not a new format driver disk, checking for old"); - sprintf(file, "%s/rhdd-6.1", mntpt); - if (access(file, R_OK)) { - logMessage(ERROR, "can't find either driver disk identifier, bad " - "driver disk"); - } - } - - /* side effect: file is still mntpt/ddident */ - stat(file, &sb); - if (!sb.st_size) - return LOADER_BACK; - - return LOADER_OK; +static char *driverDiskFiles[] = { "modinfo", "modules.dep", + "modules.cgz", "modules.alias", NULL +}; + +static int verifyDriverDisk(char *mntpt) +{ + char **fnPtr; + char file[200]; + struct stat sb; + + for (fnPtr = driverDiskFiles; *fnPtr; fnPtr++) { + sprintf(file, "%s/%s", mntpt, *fnPtr); + if (access(file, R_OK)) { + logMessage(ERROR, "cannot find %s, bad driver disk", + file); + return LOADER_BACK; + } + } + + /* check for both versions */ + sprintf(file, "%s/rhdd", mntpt); + if (access(file, R_OK)) { + logMessage(DEBUGLVL, + "not a new format driver disk, checking for old"); + sprintf(file, "%s/rhdd-6.1", mntpt); + if (access(file, R_OK)) { + logMessage(ERROR, + "can't find either driver disk identifier, bad " + "driver disk"); + } + } + + /* side effect: file is still mntpt/ddident */ + stat(file, &sb); + if (!sb.st_size) + return LOADER_BACK; + + return LOADER_OK; } -static void copyWarnFn (char *msg) { - logMessage(WARNING, msg); +static void copyWarnFn(char *msg) +{ + logMessage(WARNING, msg); } -static void copyErrorFn (char *msg) { - newtWinMessage(_("Error"), _("OK"), _(msg)); +static void copyErrorFn(char *msg) +{ + newtWinMessage(_("Error"), _("OK"), _(msg)); } /* this copies the contents of the driver disk to a ramdisk and loads * the moduleinfo, etc. assumes a "valid" driver disk mounted at mntpt */ -static int loadDriverDisk(struct loaderData_s *loaderData, char *mntpt) { - moduleInfoSet modInfo = loaderData->modInfo; - char file[200], dest[200]; - char *title; - char *fwdir = NULL; - struct moduleBallLocation * location; - struct stat sb; - static int disknum = 0; - int version = 1; - int fd, ret; - - /* check for both versions */ - sprintf(file, "%s/rhdd", mntpt); - if (access(file, R_OK)) { - version = 0; - sprintf(file, "%s/rhdd-6.1", mntpt); - if (access(file, R_OK)) { - /* this can't happen, we already verified it! */ - return LOADER_BACK; - } - } - stat(file, &sb); - title = malloc(sb.st_size + 1); - - fd = open(file, O_RDONLY); - ret = read(fd, title, sb.st_size); - if (title[sb.st_size - 1] == '\n') - sb.st_size--; - title[sb.st_size] = '\0'; - close(fd); - - sprintf(file, "/tmp/DD-%d", disknum); - mkdirChain(file); - - if (!FL_CMDLINE(flags)) { - startNewt(); - winStatus(40, 3, _("Loading"), _("Reading driver disk")); - } - - sprintf(dest, "/tmp/DD-%d", disknum); - copyDirectory(mntpt, dest, copyWarnFn, copyErrorFn); - - location = malloc(sizeof(struct moduleBallLocation)); - location->title = strdup(title); - location->version = version; - - checked_asprintf(&location->path, "/tmp/DD-%d/modules.cgz", disknum); - checked_asprintf(&fwdir, "/tmp/DD-%d/firmware", disknum); - - if (!access(fwdir, R_OK|X_OK)) { - add_fw_search_dir(loaderData, fwdir); - stop_fw_loader(loaderData); - start_fw_loader(loaderData); - } - free(fwdir); - - sprintf(file, "%s/modinfo", mntpt); - readModuleInfo(file, modInfo, location, 1); - - if (!FL_CMDLINE(flags)) - newtPopWindow(); - - disknum++; - return 0; +static int loadDriverDisk(struct loaderData_s *loaderData, char *mntpt) +{ + moduleInfoSet modInfo = loaderData->modInfo; + char file[200], dest[200]; + char *title; + char *fwdir = NULL; + struct moduleBallLocation *location; + struct stat sb; + static int disknum = 0; + int version = 1; + int fd, ret; + + /* check for both versions */ + sprintf(file, "%s/rhdd", mntpt); + if (access(file, R_OK)) { + version = 0; + sprintf(file, "%s/rhdd-6.1", mntpt); + if (access(file, R_OK)) { + /* this can't happen, we already verified it! */ + return LOADER_BACK; + } + } + stat(file, &sb); + title = malloc(sb.st_size + 1); + + fd = open(file, O_RDONLY); + ret = read(fd, title, sb.st_size); + if (title[sb.st_size - 1] == '\n') + sb.st_size--; + title[sb.st_size] = '\0'; + close(fd); + + sprintf(file, "/tmp/DD-%d", disknum); + mkdirChain(file); + + if (!FL_CMDLINE(flags)) { + startNewt(); + winStatus(40, 3, _("Loading"), _("Reading driver disk")); + } + + sprintf(dest, "/tmp/DD-%d", disknum); + copyDirectory(mntpt, dest, copyWarnFn, copyErrorFn); + + location = malloc(sizeof(struct moduleBallLocation)); + location->title = strdup(title); + location->version = version; + + checked_asprintf(&location->path, "/tmp/DD-%d/modules.cgz", disknum); + checked_asprintf(&fwdir, "/tmp/DD-%d/firmware", disknum); + + if (!access(fwdir, R_OK | X_OK)) { + add_fw_search_dir(loaderData, fwdir); + stop_fw_loader(loaderData); + start_fw_loader(loaderData); + } + free(fwdir); + + sprintf(file, "%s/modinfo", mntpt); + readModuleInfo(file, modInfo, location, 1); + + if (!FL_CMDLINE(flags)) + newtPopWindow(); + + disknum++; + return 0; } /* Get the list of removable devices (floppy/cdrom) available. Used to @@ -171,25 +179,28 @@ static int loadDriverDisk(struct loaderData_s *loaderData, char *mntpt) { * Returns the number of devices. ***devNames will be a NULL-terminated list * of device names */ -int getRemovableDevices(char *** devNames) { - struct device **devs; - int numDevices = 0; - int i = 0; - - devs = getDevices(DEVICE_DISK | DEVICE_CDROM); - - for (i = 0; devs[i] ; i++) { - if (devs[i]->priv.removable) { - *devNames = realloc(*devNames, (numDevices + 2) * sizeof(char *)); - (*devNames)[numDevices] = strdup(devs[i]->device); - (*devNames)[numDevices+1] = NULL; - numDevices ++; - } - } - if (!numDevices) { - logMessage(ERROR, "no devices found to load drivers from"); - } - return numDevices; +int getRemovableDevices(char ***devNames) +{ + struct device **devs; + int numDevices = 0; + int i = 0; + + devs = getDevices(DEVICE_DISK | DEVICE_CDROM); + + for (i = 0; devs[i]; i++) { + if (devs[i]->priv.removable) { + *devNames = + realloc(*devNames, + (numDevices + 2) * sizeof(char *)); + (*devNames)[numDevices] = strdup(devs[i]->device); + (*devNames)[numDevices + 1] = NULL; + numDevices++; + } + } + if (!numDevices) { + logMessage(ERROR, "no devices found to load drivers from"); + } + return numDevices; } /* Prompt for loading a driver from "media" @@ -198,430 +209,475 @@ int getRemovableDevices(char *** devNames) { * usecancel: if 1, use cancel instead of back */ int loadDriverFromMedia(int class, struct loaderData_s *loaderData, - int usecancel, int noprobe) { - char * device = NULL, * part = NULL, * ddfile = NULL; - char ** devNames = NULL; - enum { DEV_DEVICE, DEV_PART, DEV_CHOOSEFILE, DEV_LOADFILE, - DEV_INSERT, DEV_LOAD, DEV_PROBE, - DEV_DONE } stage = DEV_DEVICE; - int rc, num = 0; - int dir = 1; - int found = 0, before = 0; - - while (stage != DEV_DONE) { - switch(stage) { - case DEV_DEVICE: - rc = getRemovableDevices(&devNames); - if (rc == 0) - return LOADER_BACK; - - /* we don't need to ask which to use if they only have one */ - if (rc == 1) { - device = strdup(devNames[0]); - free(devNames); - if (dir == -1) - return LOADER_BACK; - - stage = DEV_PART; - break; - } - dir = 1; - - startNewt(); - rc = newtWinMenu(_("Driver Disk Source"), - _("You have multiple devices which could serve " - "as sources for a driver disk. Which would " - "you like to use?"), 40, 10, 10, - rc < 6 ? rc : 6, devNames, - &num, _("OK"), - (usecancel) ? _("Cancel") : _("Back"), NULL); - - if (rc == 2) { - free(devNames); - return LOADER_BACK; - } - device = strdup(devNames[num]); - free(devNames); - - stage = DEV_PART; - case DEV_PART: { - char ** part_list = getPartitionsList(device); - int nump = 0, num = 0; - - if (part != NULL) free(part); - - if ((nump = lenPartitionsList(part_list)) == 0) { - if (dir == -1) - stage = DEV_DEVICE; - else - stage = DEV_INSERT; - break; - } - dir = 1; - - startNewt(); - rc = newtWinMenu(_("Driver Disk Source"), - _("There are multiple partitions on this device " - "which could contain the driver disk image. " - "Which would you like to use?"), 40, 10, 10, - nump < 6 ? nump : 6, part_list, &num, _("OK"), - _("Back"), NULL); - - if (rc == 2) { - freePartitionsList(part_list); - stage = DEV_DEVICE; - dir = -1; - break; - } - - part = strdup(part_list[num]); - stage = DEV_CHOOSEFILE; - - } - - case DEV_CHOOSEFILE: { - if (part == NULL) { - logMessage(ERROR, "somehow got to choosing file with a NULL part, going back"); - stage = DEV_PART; - break; - } - /* make sure nothing is mounted when we get here */ - num = umount("/tmp/dpart"); - if (num == -1) { - logMessage(ERROR, "error unmounting: %m"); - if ((errno != EINVAL) && (errno != ENOENT)) - exit(1); - } - - logMessage(INFO, "trying to mount %s as partition", part); - if (doPwMount(part, "/tmp/dpart", "auto", "ro", NULL)) { - newtWinMessage(_("Error"), _("OK"), - _("Failed to mount partition.")); - stage = DEV_PART; - break; - } - - ddfile = newt_select_file(_("Select driver disk image"), - _("Select the file which is your driver " - "disk image."), - "/tmp/dpart", NULL); - if (ddfile == NULL) { - umount("/tmp/dpart"); - stage = DEV_PART; - dir = -1; - break; - } - dir = 1; - - stage = DEV_LOADFILE; - } - - case DEV_LOADFILE: { - if(ddfile == NULL) { - logMessage(DEBUGLVL, "trying to load dd from NULL"); - stage = DEV_CHOOSEFILE; - break; - } - if (dir == -1) { - umountLoopback("/tmp/drivers", "/dev/loop6"); - unlink("/tmp/drivers"); - ddfile = NULL; - stage = DEV_CHOOSEFILE; - break; - } - if (mountLoopback(ddfile, "/tmp/drivers", "/dev/loop6")) { - newtWinMessage(_("Error"), _("OK"), - _("Failed to load driver disk from file.")); - stage = DEV_CHOOSEFILE; - break; - } - stage = DEV_LOAD; - break; - } - - case DEV_INSERT: { - char * buf; - - checked_asprintf(&buf, - _("Insert your driver disk into /dev/%s " - "and press \"OK\" to continue."), device); - - rc = newtWinChoice(_("Insert Driver Disk"), _("OK"), _("Back"), - buf); - free(buf); - if (rc == 2) { - stage = DEV_DEVICE; - dir = -1; - break; - } - dir = 1; - - logMessage(INFO, "trying to mount %s", device); - if (doPwMount(device, "/tmp/drivers", "auto", "ro", NULL)) { - newtWinMessage(_("Error"), _("OK"), - _("Failed to mount driver disk.")); - stage = DEV_INSERT; - break; - } - - rc = verifyDriverDisk("/tmp/drivers"); - if (rc == LOADER_BACK) { - newtWinMessage(_("Error"), _("OK"), - _("Driver disk is invalid for this " - "release of %s."), getProductName()); - umount("/tmp/drivers"); - stage = DEV_INSERT; - break; - } - - stage = DEV_LOAD; - break; - } - case DEV_LOAD: { - struct device ** devices; - - before = 0; - found = 0; - - devices = getDevices(class); - if (devices) - for(; devices[before]; before++); - - rc = loadDriverDisk(loaderData, "/tmp/drivers"); - umount("/tmp/drivers"); - if (rc == LOADER_BACK) { - dir = -1; - if (ddfile != NULL) - stage = DEV_CHOOSEFILE; - else - stage = DEV_INSERT; - break; - } - /* fall through to probing */ - stage = DEV_PROBE; - - if (ddfile != NULL) { - umountLoopback("/tmp/drivers", "/dev/loop6"); - unlink("/tmp/drivers"); - umount("/tmp/dpart"); - } - } - - case DEV_PROBE: { - struct device ** devices; - - /* if they didn't specify that we should probe, then we should - * just fall out */ - if (noprobe) { - stage = DEV_DONE; - break; - } - - busProbe(0); - - devices = getDevices(class); - if (devices) - for(; devices[found]; found++); - - if (found > before) { - stage = DEV_DONE; - break; - } - - /* we don't have any more modules of the proper class. ask - * them to manually load */ - rc = newtWinTernary(_("Error"), _("Manually choose"), - _("Continue"), _("Load another disk"), - _("No devices of the appropriate type were " - "found on this driver disk. Would you " - "like to manually select the driver, " - "continue anyway, or load another " - "driver disk?")); - - if (rc == 2) { - /* if they choose to continue, just go ahead and continue */ - stage = DEV_DONE; - } else if (rc == 3) { - /* if they choose to load another disk, back to the - * beginning with them */ - stage = DEV_DEVICE; - } else { - rc = chooseManualDriver(class, loaderData); - /* if they go back from a manual driver, we'll ask again. - * if they load something, assume it's what we need */ - if (rc == LOADER_OK) { - stage = DEV_DONE; - } - } - - break; - } - - case DEV_DONE: - break; - } - } - - return LOADER_OK; + int usecancel, int noprobe) +{ + char *device = NULL, *part = NULL, *ddfile = NULL; + char **devNames = NULL; + enum { DEV_DEVICE, DEV_PART, DEV_CHOOSEFILE, DEV_LOADFILE, + DEV_INSERT, DEV_LOAD, DEV_PROBE, + DEV_DONE + } stage = DEV_DEVICE; + int rc, num = 0; + int dir = 1; + int found = 0, before = 0; + + while (stage != DEV_DONE) { + switch (stage) { + case DEV_DEVICE: + rc = getRemovableDevices(&devNames); + if (rc == 0) + return LOADER_BACK; + + /* we don't need to ask which to use if they only have one */ + if (rc == 1) { + device = strdup(devNames[0]); + free(devNames); + if (dir == -1) + return LOADER_BACK; + + stage = DEV_PART; + break; + } + dir = 1; + + startNewt(); + rc = newtWinMenu(_("Driver Disk Source"), + _ + ("You have multiple devices which could serve " + "as sources for a driver disk. Which would " + "you like to use?"), 40, 10, 10, + rc < 6 ? rc : 6, devNames, &num, + _("OK"), + (usecancel) ? _("Cancel") : _("Back"), + NULL); + + if (rc == 2) { + free(devNames); + return LOADER_BACK; + } + device = strdup(devNames[num]); + free(devNames); + + stage = DEV_PART; + case DEV_PART:{ + char **part_list = getPartitionsList(device); + int nump = 0, num = 0; + + if (part != NULL) + free(part); + + if ((nump = lenPartitionsList(part_list)) == 0) { + if (dir == -1) + stage = DEV_DEVICE; + else + stage = DEV_INSERT; + break; + } + dir = 1; + + startNewt(); + rc = newtWinMenu(_("Driver Disk Source"), + _ + ("There are multiple partitions on this device " + "which could contain the driver disk image. " + "Which would you like to use?"), + 40, 10, 10, + nump < 6 ? nump : 6, part_list, + &num, _("OK"), _("Back"), + NULL); + + if (rc == 2) { + freePartitionsList(part_list); + stage = DEV_DEVICE; + dir = -1; + break; + } + + part = strdup(part_list[num]); + stage = DEV_CHOOSEFILE; + + } + + case DEV_CHOOSEFILE:{ + if (part == NULL) { + logMessage(ERROR, + "somehow got to choosing file with a NULL part, going back"); + stage = DEV_PART; + break; + } + /* make sure nothing is mounted when we get here */ + num = umount("/tmp/dpart"); + if (num == -1) { + logMessage(ERROR, + "error unmounting: %m"); + if ((errno != EINVAL) + && (errno != ENOENT)) + exit(1); + } + + logMessage(INFO, + "trying to mount %s as partition", + part); + if (doPwMount + (part, "/tmp/dpart", "auto", "ro", NULL)) { + newtWinMessage(_("Error"), _("OK"), + _ + ("Failed to mount partition.")); + stage = DEV_PART; + break; + } + + ddfile = + newt_select_file(_ + ("Select driver disk image"), + _ + ("Select the file which is your driver " + "disk image."), + "/tmp/dpart", NULL); + if (ddfile == NULL) { + umount("/tmp/dpart"); + stage = DEV_PART; + dir = -1; + break; + } + dir = 1; + + stage = DEV_LOADFILE; + } + + case DEV_LOADFILE:{ + if (ddfile == NULL) { + logMessage(DEBUGLVL, + "trying to load dd from NULL"); + stage = DEV_CHOOSEFILE; + break; + } + if (dir == -1) { + umountLoopback("/tmp/drivers", + "/dev/loop6"); + unlink("/tmp/drivers"); + ddfile = NULL; + stage = DEV_CHOOSEFILE; + break; + } + if (mountLoopback + (ddfile, "/tmp/drivers", "/dev/loop6")) { + newtWinMessage(_("Error"), _("OK"), + _ + ("Failed to load driver disk from file.")); + stage = DEV_CHOOSEFILE; + break; + } + stage = DEV_LOAD; + break; + } + + case DEV_INSERT:{ + char *buf; + + checked_asprintf(&buf, + _ + ("Insert your driver disk into /dev/%s " + "and press \"OK\" to continue."), + device); + + rc = newtWinChoice(_("Insert Driver Disk"), + _("OK"), _("Back"), buf); + free(buf); + if (rc == 2) { + stage = DEV_DEVICE; + dir = -1; + break; + } + dir = 1; + + logMessage(INFO, "trying to mount %s", device); + if (doPwMount + (device, "/tmp/drivers", "auto", "ro", + NULL)) { + newtWinMessage(_("Error"), _("OK"), + _ + ("Failed to mount driver disk.")); + stage = DEV_INSERT; + break; + } + + rc = verifyDriverDisk("/tmp/drivers"); + if (rc == LOADER_BACK) { + newtWinMessage(_("Error"), _("OK"), + _ + ("Driver disk is invalid for this " + "release of %s."), + getProductName()); + umount("/tmp/drivers"); + stage = DEV_INSERT; + break; + } + + stage = DEV_LOAD; + break; + } + case DEV_LOAD:{ + struct device **devices; + + before = 0; + found = 0; + + devices = getDevices(class); + if (devices) + for (; devices[before]; before++) ; + + rc = loadDriverDisk(loaderData, "/tmp/drivers"); + umount("/tmp/drivers"); + if (rc == LOADER_BACK) { + dir = -1; + if (ddfile != NULL) + stage = DEV_CHOOSEFILE; + else + stage = DEV_INSERT; + break; + } + /* fall through to probing */ + stage = DEV_PROBE; + + if (ddfile != NULL) { + umountLoopback("/tmp/drivers", + "/dev/loop6"); + unlink("/tmp/drivers"); + umount("/tmp/dpart"); + } + } + + case DEV_PROBE:{ + struct device **devices; + + /* if they didn't specify that we should probe, then we should + * just fall out */ + if (noprobe) { + stage = DEV_DONE; + break; + } + + busProbe(0); + + devices = getDevices(class); + if (devices) + for (; devices[found]; found++) ; + + if (found > before) { + stage = DEV_DONE; + break; + } + + /* we don't have any more modules of the proper class. ask + * them to manually load */ + rc = newtWinTernary(_("Error"), + _("Manually choose"), + _("Continue"), + _("Load another disk"), + _ + ("No devices of the appropriate type were " + "found on this driver disk. Would you " + "like to manually select the driver, " + "continue anyway, or load another " + "driver disk?")); + + if (rc == 2) { + /* if they choose to continue, just go ahead and continue */ + stage = DEV_DONE; + } else if (rc == 3) { + /* if they choose to load another disk, back to the + * beginning with them */ + stage = DEV_DEVICE; + } else { + rc = chooseManualDriver(class, + loaderData); + /* if they go back from a manual driver, we'll ask again. + * if they load something, assume it's what we need */ + if (rc == LOADER_OK) { + stage = DEV_DONE; + } + } + + break; + } + + case DEV_DONE: + break; + } + } + + return LOADER_OK; } - /* looping way to load driver disks */ -int loadDriverDisks(int class, struct loaderData_s *loaderData) { - int rc; - - rc = newtWinChoice(_("Driver disk"), _("Yes"), _("No"), - _("Do you have a driver disk?")); - if (rc != 1) - return LOADER_OK; - - rc = loadDriverFromMedia(DEVICE_ANY, loaderData, 1, 0); - if (rc == LOADER_BACK) - return LOADER_OK; - - do { - rc = newtWinChoice(_("More Driver Disks?"), _("Yes"), _("No"), - _("Do you wish to load any more driver disks?")); - if (rc != 1) - break; - loadDriverFromMedia(DEVICE_ANY, loaderData, 0, 0); - } while (1); - - return LOADER_OK; +int loadDriverDisks(int class, struct loaderData_s *loaderData) +{ + int rc; + + rc = newtWinChoice(_("Driver disk"), _("Yes"), _("No"), + _("Do you have a driver disk?")); + if (rc != 1) + return LOADER_OK; + + rc = loadDriverFromMedia(DEVICE_ANY, loaderData, 1, 0); + if (rc == LOADER_BACK) + return LOADER_OK; + + do { + rc = newtWinChoice(_("More Driver Disks?"), _("Yes"), _("No"), + _ + ("Do you wish to load any more driver disks?")); + if (rc != 1) + break; + loadDriverFromMedia(DEVICE_ANY, loaderData, 0, 0); + } while (1); + + return LOADER_OK; } -static void loadFromLocation(struct loaderData_s * loaderData, char * dir) { - if (verifyDriverDisk(dir) == LOADER_BACK) { - logMessage(ERROR, "not a valid driver disk"); - return; - } +static void loadFromLocation(struct loaderData_s *loaderData, char *dir) +{ + if (verifyDriverDisk(dir) == LOADER_BACK) { + logMessage(ERROR, "not a valid driver disk"); + return; + } - loadDriverDisk(loaderData, dir); - busProbe(0); + loadDriverDisk(loaderData, dir); + busProbe(0); } -void getDDFromSource(struct loaderData_s * loaderData, char * src) { - char *path = "/tmp/dd.img"; - int unlinkf = 0; - - if (!strncmp(src, "nfs:", 4)) { - unlinkf = 1; - if (getFileFromNfs(src + 4, "/tmp/dd.img", loaderData)) { - logMessage(ERROR, "unable to retrieve driver disk: %s", src); - return; - } - } else if (!strncmp(src, "ftp://", 6) || !strncmp(src, "http", 4)) { - unlinkf = 1; - if (getFileFromUrl(src, "/tmp/dd.img", loaderData)) { - logMessage(ERROR, "unable to retrieve driver disk: %s", src); - return; - } - /* FIXME: this is a hack so that you can load a driver disk from, eg, - * scsi cdrom drives */ +void getDDFromSource(struct loaderData_s *loaderData, char *src) +{ + char *path = "/tmp/dd.img"; + int unlinkf = 0; + + if (!strncmp(src, "nfs:", 4)) { + unlinkf = 1; + if (getFileFromNfs(src + 4, "/tmp/dd.img", loaderData)) { + logMessage(ERROR, "unable to retrieve driver disk: %s", + src); + return; + } + } else if (!strncmp(src, "ftp://", 6) || !strncmp(src, "http", 4)) { + unlinkf = 1; + if (getFileFromUrl(src, "/tmp/dd.img", loaderData)) { + logMessage(ERROR, "unable to retrieve driver disk: %s", + src); + return; + } + /* FIXME: this is a hack so that you can load a driver disk from, eg, + * scsi cdrom drives */ #if !defined(__s390__) && !defined(__s390x__) - } else if (!strncmp(src, "cdrom", 5)) { - loadDriverDisks(DEVICE_ANY, loaderData); - return; + } else if (!strncmp(src, "cdrom", 5)) { + loadDriverDisks(DEVICE_ANY, loaderData); + return; #endif - } else if (!strncmp(src, "path:", 5)) { - path = src + 5; - } else { - newtWinMessage(_("Kickstart Error"), _("OK"), - _("Unknown driver disk kickstart source: %s"), src); - return; - } - - if (!mountLoopback(path, "/tmp/drivers", "/dev/loop6")) { - loadFromLocation(loaderData, "/tmp/drivers"); - umountLoopback("/tmp/drivers", "/dev/loop6"); - unlink("/tmp/drivers"); - if (unlinkf) unlink(path); - } + } else if (!strncmp(src, "path:", 5)) { + path = src + 5; + } else { + newtWinMessage(_("Kickstart Error"), _("OK"), + _("Unknown driver disk kickstart source: %s"), + src); + return; + } + + if (!mountLoopback(path, "/tmp/drivers", "/dev/loop6")) { + loadFromLocation(loaderData, "/tmp/drivers"); + umountLoopback("/tmp/drivers", "/dev/loop6"); + unlink("/tmp/drivers"); + if (unlinkf) + unlink(path); + } } -static void getDDFromDev(struct loaderData_s * loaderData, char * dev); - -void useKickstartDD(struct loaderData_s * loaderData, - int argc, char ** argv) { - char * dev = NULL; - char * biospart = NULL, * p = NULL; - gchar *fstype = NULL, *src = NULL; - gint usebiosdev = 0; - gchar **remaining = NULL; - GOptionContext *optCon = g_option_context_new(NULL); - GError *optErr = NULL; - GOptionEntry ksDDOptions[] = { - /* The --type option is deprecated and now has no effect. */ - { "type", 0, 0, G_OPTION_ARG_STRING, &fstype, NULL, NULL }, - { "source", 0, 0, G_OPTION_ARG_STRING, &src, NULL, NULL }, - { "biospart", 0, 0, G_OPTION_ARG_INT, &usebiosdev, NULL, NULL }, - { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &remaining, - NULL, NULL }, - { NULL }, - }; - - g_option_context_set_help_enabled(optCon, FALSE); - g_option_context_add_main_entries(optCon, ksDDOptions, NULL); - - if (!g_option_context_parse(optCon, &argc, &argv, &optErr)) { - newtWinMessage(_("Kickstart Error"), _("OK"), - _("The following invalid argument was specified for " - "the kickstart driver disk command: %s"), - optErr->message); - g_error_free(optErr); - g_option_context_free(optCon); - g_strfreev(remaining); - return; - } - - g_option_context_free(optCon); - - if ((remaining != NULL) && (g_strv_length(remaining) == 1)) { - dev = remaining[0]; - } - - if (!dev && !src) { - logMessage(ERROR, "bad arguments to kickstart driver disk command"); - return; - } - - if (usebiosdev != 0) { - p = strchr(dev,'p'); - if (!p){ - logMessage(ERROR, "Bad argument for biospart"); - return; - } - *p = '\0'; - - biospart = getBiosDisk(dev); - if (biospart == NULL) { - logMessage(ERROR, "Unable to locate BIOS dev %s",dev); - return; - } - dev = malloc(strlen(biospart) + strlen(p + 1) + 2); - sprintf(dev, "%s%s", biospart, p + 1); - } - - if (dev) { - getDDFromDev(loaderData, dev); - } else { - getDDFromSource(loaderData, src); - } - - g_strfreev(remaining); - return; +static void getDDFromDev(struct loaderData_s *loaderData, char *dev); + +void useKickstartDD(struct loaderData_s *loaderData, int argc, char **argv) +{ + char *dev = NULL; + char *biospart = NULL, *p = NULL; + gchar *fstype = NULL, *src = NULL; + gint usebiosdev = 0; + gchar **remaining = NULL; + GOptionContext *optCon = g_option_context_new(NULL); + GError *optErr = NULL; + GOptionEntry ksDDOptions[] = { + /* The --type option is deprecated and now has no effect. */ + {"type", 0, 0, G_OPTION_ARG_STRING, &fstype, NULL, NULL}, + {"source", 0, 0, G_OPTION_ARG_STRING, &src, NULL, NULL}, + {"biospart", 0, 0, G_OPTION_ARG_INT, &usebiosdev, NULL, NULL}, + {G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, + &remaining, + NULL, NULL}, + {NULL}, + }; + + g_option_context_set_help_enabled(optCon, FALSE); + g_option_context_add_main_entries(optCon, ksDDOptions, NULL); + + if (!g_option_context_parse(optCon, &argc, &argv, &optErr)) { + newtWinMessage(_("Kickstart Error"), _("OK"), + _ + ("The following invalid argument was specified for " + "the kickstart driver disk command: %s"), + optErr->message); + g_error_free(optErr); + g_option_context_free(optCon); + g_strfreev(remaining); + return; + } + + g_option_context_free(optCon); + + if ((remaining != NULL) && (g_strv_length(remaining) == 1)) { + dev = remaining[0]; + } + + if (!dev && !src) { + logMessage(ERROR, + "bad arguments to kickstart driver disk command"); + return; + } + + if (usebiosdev != 0) { + p = strchr(dev, 'p'); + if (!p) { + logMessage(ERROR, "Bad argument for biospart"); + return; + } + *p = '\0'; + + biospart = getBiosDisk(dev); + if (biospart == NULL) { + logMessage(ERROR, "Unable to locate BIOS dev %s", dev); + return; + } + dev = malloc(strlen(biospart) + strlen(p + 1) + 2); + sprintf(dev, "%s%s", biospart, p + 1); + } + + if (dev) { + getDDFromDev(loaderData, dev); + } else { + getDDFromSource(loaderData, src); + } + + g_strfreev(remaining); + return; } -static void getDDFromDev(struct loaderData_s * loaderData, char * dev) { - if (doPwMount(dev, "/tmp/drivers", "auto", "ro", NULL)) { - logMessage(ERROR, "unable to mount driver disk %s", dev); - return; - } +static void getDDFromDev(struct loaderData_s *loaderData, char *dev) +{ + if (doPwMount(dev, "/tmp/drivers", "auto", "ro", NULL)) { + logMessage(ERROR, "unable to mount driver disk %s", dev); + return; + } - loadFromLocation(loaderData, "/tmp/drivers"); - umount("/tmp/drivers"); - unlink("/tmp/drivers"); + loadFromLocation(loaderData, "/tmp/drivers"); + umount("/tmp/drivers"); + unlink("/tmp/drivers"); } /* vim:set sw=8 noet */ diff --git a/loader/driverdisk.h b/loader/driverdisk.h index 965abbe..09025da 100644 --- a/loader/driverdisk.h +++ b/loader/driverdisk.h @@ -27,17 +27,16 @@ extern char *ddFsTypes[]; int loadDriverFromMedia(int class, struct loaderData_s *loaderData, - int usecancel, int noprobe); + int usecancel, int noprobe); int loadDriverDisks(int class, struct loaderData_s *loaderData); -int getRemovableDevices(char *** devNames); +int getRemovableDevices(char ***devNames); int chooseManualDriver(int class, struct loaderData_s *loaderData); -void useKickstartDD(struct loaderData_s * loaderData, int argc, - char ** argv); +void useKickstartDD(struct loaderData_s *loaderData, int argc, char **argv); -void getDDFromSource(struct loaderData_s * loaderData, char * src); +void getDDFromSource(struct loaderData_s *loaderData, char *src); #endif diff --git a/loader/driverselect.c b/loader/driverselect.c index c7ad957..775f540 100644 --- a/loader/driverselect.c +++ b/loader/driverselect.c @@ -37,216 +37,229 @@ #include "driverdisk.h" struct sortModuleList { - int index; - moduleInfoSet modInfo; + int index; + moduleInfoSet modInfo; }; -static int sortDrivers(const void * a, const void * b) { - const struct sortModuleList * one = a; - const struct sortModuleList * two = b; +static int sortDrivers(const void *a, const void *b) +{ + const struct sortModuleList *one = a; + const struct sortModuleList *two = b; - return strcmp(one->modInfo->moduleList[one->index].description, - one->modInfo->moduleList[two->index].description); + return strcmp(one->modInfo->moduleList[one->index].description, + one->modInfo->moduleList[two->index].description); } -static int getManualModuleArgs(struct moduleInfo * mod, gchar *** moduleArgs) { - newtGrid grid, buttons; - newtComponent text, f, ok, back, entry; - struct newtExitStruct es; - int done = 0, i; - char * buf; - char *argsEntry = ""; - - if (*moduleArgs) { - for (i = 0; (*moduleArgs)[i]; i++) - argsEntry = strcat(argsEntry, (*moduleArgs)[i]); - } - - f = newtForm(NULL, NULL, 0); - checked_asprintf(&buf, - _("Please enter any parameters which you wish to pass " - "to the %s module separated by spaces. If you don't " - "know what parameters to supply, skip this screen " - "by pressing the \"OK\" button."), mod->moduleName); - - text = newtTextboxReflowed(-1, -1, buf, 60, 0, 10, 0); - entry = newtEntry(-1, -1, argsEntry, 50, (const char **) &argsEntry, - NEWT_ENTRY_SCROLL); - - newtFormAddHotKey(f, NEWT_KEY_F12); - - buttons = newtButtonBar(_("OK"), &ok, _("Back"), &back, NULL); - - grid = newtCreateGrid(1, 3); - newtGridSetField(grid, 0, 0, NEWT_GRID_COMPONENT, text, - 0, 0, 0, 1, 0, 0); - newtGridSetField(grid, 0, 1, NEWT_GRID_COMPONENT, entry, - 0, 0, 0, 1, 0, 0); - newtGridSetField(grid, 0, 2, NEWT_GRID_SUBGRID, buttons, - 0, 0, 0, 0, 0, NEWT_GRID_FLAG_GROWX); - - newtGridWrappedWindow(grid, _("Enter Module Parameters")); - newtGridAddComponentsToForm(grid, f, 1); - - do { - newtFormRun(f, &es); - - if (es.reason == NEWT_EXIT_COMPONENT && es.u.co == back) { - done = -1; - } else { - done = 1; - } - } while (done == 0); - - free(buf); - newtGridFree(grid, 1); - - if (done == -1) { - newtFormDestroy(f); - newtPopWindow(); - - return LOADER_BACK; - } - logMessage(INFO, "specified args of %s for %s", argsEntry, mod->moduleName); - - if (strlen(argsEntry) > 0) { - *moduleArgs = g_strsplit(argsEntry, " ", 0); - } - - newtFormDestroy(f); - newtPopWindow(); - - return LOADER_OK; +static int getManualModuleArgs(struct moduleInfo *mod, gchar *** moduleArgs) +{ + newtGrid grid, buttons; + newtComponent text, f, ok, back, entry; + struct newtExitStruct es; + int done = 0, i; + char *buf; + char *argsEntry = ""; + + if (*moduleArgs) { + for (i = 0; (*moduleArgs)[i]; i++) + argsEntry = strcat(argsEntry, (*moduleArgs)[i]); + } + + f = newtForm(NULL, NULL, 0); + checked_asprintf(&buf, + _("Please enter any parameters which you wish to pass " + "to the %s module separated by spaces. If you don't " + "know what parameters to supply, skip this screen " + "by pressing the \"OK\" button."), mod->moduleName); + + text = newtTextboxReflowed(-1, -1, buf, 60, 0, 10, 0); + entry = newtEntry(-1, -1, argsEntry, 50, (const char **)&argsEntry, + NEWT_ENTRY_SCROLL); + + newtFormAddHotKey(f, NEWT_KEY_F12); + + buttons = newtButtonBar(_("OK"), &ok, _("Back"), &back, NULL); + + grid = newtCreateGrid(1, 3); + newtGridSetField(grid, 0, 0, NEWT_GRID_COMPONENT, text, + 0, 0, 0, 1, 0, 0); + newtGridSetField(grid, 0, 1, NEWT_GRID_COMPONENT, entry, + 0, 0, 0, 1, 0, 0); + newtGridSetField(grid, 0, 2, NEWT_GRID_SUBGRID, buttons, + 0, 0, 0, 0, 0, NEWT_GRID_FLAG_GROWX); + + newtGridWrappedWindow(grid, _("Enter Module Parameters")); + newtGridAddComponentsToForm(grid, f, 1); + + do { + newtFormRun(f, &es); + + if (es.reason == NEWT_EXIT_COMPONENT && es.u.co == back) { + done = -1; + } else { + done = 1; + } + } while (done == 0); + + free(buf); + newtGridFree(grid, 1); + + if (done == -1) { + newtFormDestroy(f); + newtPopWindow(); + + return LOADER_BACK; + } + logMessage(INFO, "specified args of %s for %s", argsEntry, + mod->moduleName); + + if (strlen(argsEntry) > 0) { + *moduleArgs = g_strsplit(argsEntry, " ", 0); + } + + newtFormDestroy(f); + newtPopWindow(); + + return LOADER_OK; } -int chooseManualDriver(int class, struct loaderData_s *loaderData) { - int i, numSorted, num = 0, done = 0; - enum driverMajor type; - struct sortModuleList * sortedOrder; - char giveArgs = ' '; - gchar **moduleArgs = NULL; - moduleInfoSet modInfo = loaderData->modInfo; - - newtComponent text, f, ok, back, argcheckbox, listbox; - newtGrid grid, buttons; - struct newtExitStruct es; - - if (class == DEVICE_NETWORK) - type = DRIVER_NET; - else if (class == DEVICE_DISK || class == DEVICE_CDROM) - type = DRIVER_SCSI; - else - type = DRIVER_ANY; - - do { - sortedOrder = malloc(sizeof(*sortedOrder) * modInfo->numModules); - numSorted = 0; - - for (i = 0; i < modInfo->numModules; i++) { - sortedOrder[numSorted].index = i; - sortedOrder[numSorted++].modInfo = modInfo; - } - - if (numSorted == 0) { - i = newtWinChoice(_("No drivers found"), _("Load driver disk"), - _("Back"), _("No drivers were found to manually " - "insert. Would you like to use " - "a driver disk?")); - if (i != 1) - return LOADER_BACK; - - loadDriverFromMedia(class, loaderData, 1, 1); - continue; - } else { - break; - } - } while (1); - - qsort(sortedOrder, numSorted, sizeof(*sortedOrder), sortDrivers); - - f = newtForm(NULL, NULL, 0); - - text = newtTextboxReflowed(-1, -1, - _("Please select the driver below which you " - "wish to load. If it does not appear and " - "you have a driver disk, press F2."), - 60, 0, 10, 0); - - listbox = newtListbox(-1, -1, 6, NEWT_FLAG_SCROLL | NEWT_FLAG_RETURNEXIT); - newtListboxSetWidth(listbox, 55); - - buttons = newtButtonBar(_("OK"), &ok, _("Back"), &back, NULL); - argcheckbox = newtCheckbox(-1, -1, _("Specify optional module arguments"), - giveArgs, NULL, &giveArgs); - - newtFormAddHotKey(f, NEWT_KEY_F2); - newtFormAddHotKey(f, NEWT_KEY_F12); - - for (i = 0; i < numSorted; i++) { - char *buf = NULL; - - checked_asprintf(&buf, "%s (%s)", - modInfo->moduleList[sortedOrder[i].index].description, - modInfo->moduleList[sortedOrder[i].index].moduleName); - - newtListboxAppendEntry(listbox, buf, - INT_TO_POINTER(sortedOrder[i].index)); - } - - grid = newtCreateGrid(1, 4); - newtGridSetField(grid, 0, 0, NEWT_GRID_COMPONENT, text, 0, 0, 0, 1, 0, 0); - newtGridSetField(grid, 0, 1, NEWT_GRID_COMPONENT, listbox, - 0, 0, 0, 1, 0, 0); - newtGridSetField(grid, 0, 2, NEWT_GRID_COMPONENT, argcheckbox, - 0, 0, 0, 1, 0, 0); - newtGridSetField(grid, 0, 3, NEWT_GRID_SUBGRID, buttons, - 0, 0, 0, 0, 0, NEWT_GRID_FLAG_GROWX); - newtGridWrappedWindow(grid, _("Select Device Driver to Load")); - - newtGridAddComponentsToForm(grid, f, 1); - - do { - newtFormRun(f, &es); - - num = POINTER_TO_INT(newtListboxGetCurrent(listbox)); - - if (es.reason == NEWT_EXIT_COMPONENT && es.u.co == back) { - done = -1; - } else if (es.reason == NEWT_EXIT_HOTKEY && es.u.key == NEWT_KEY_F2) { - done = -2; - } else { - if (giveArgs != ' ') { - i = getManualModuleArgs(&(modInfo->moduleList[num]), - &moduleArgs); - if (i == LOADER_BACK) - done = 0; - else - done = 1; - } else { - done = 1; - } - } - } while (done == 0); - - newtGridFree(grid, 1); - newtFormDestroy(f); - newtPopWindow(); - - if (done == -1) - return LOADER_BACK; - if (done == -2) { - loadDriverFromMedia(class, loaderData, 1, 1); - return chooseManualDriver(class, loaderData); - } - - mlLoadModule(modInfo->moduleList[num].moduleName, moduleArgs); - free(sortedOrder); - - if (moduleArgs) { - g_strfreev(moduleArgs); - } - - return LOADER_OK; +int chooseManualDriver(int class, struct loaderData_s *loaderData) +{ + int i, numSorted, num = 0, done = 0; + enum driverMajor type; + struct sortModuleList *sortedOrder; + char giveArgs = ' '; + gchar **moduleArgs = NULL; + moduleInfoSet modInfo = loaderData->modInfo; + + newtComponent text, f, ok, back, argcheckbox, listbox; + newtGrid grid, buttons; + struct newtExitStruct es; + + if (class == DEVICE_NETWORK) + type = DRIVER_NET; + else if (class == DEVICE_DISK || class == DEVICE_CDROM) + type = DRIVER_SCSI; + else + type = DRIVER_ANY; + + do { + sortedOrder = + malloc(sizeof(*sortedOrder) * modInfo->numModules); + numSorted = 0; + + for (i = 0; i < modInfo->numModules; i++) { + sortedOrder[numSorted].index = i; + sortedOrder[numSorted++].modInfo = modInfo; + } + + if (numSorted == 0) { + i = newtWinChoice(_("No drivers found"), + _("Load driver disk"), _("Back"), + _("No drivers were found to manually " + "insert. Would you like to use " + "a driver disk?")); + if (i != 1) + return LOADER_BACK; + + loadDriverFromMedia(class, loaderData, 1, 1); + continue; + } else { + break; + } + } while (1); + + qsort(sortedOrder, numSorted, sizeof(*sortedOrder), sortDrivers); + + f = newtForm(NULL, NULL, 0); + + text = newtTextboxReflowed(-1, -1, + _("Please select the driver below which you " + "wish to load. If it does not appear and " + "you have a driver disk, press F2."), + 60, 0, 10, 0); + + listbox = + newtListbox(-1, -1, 6, NEWT_FLAG_SCROLL | NEWT_FLAG_RETURNEXIT); + newtListboxSetWidth(listbox, 55); + + buttons = newtButtonBar(_("OK"), &ok, _("Back"), &back, NULL); + argcheckbox = + newtCheckbox(-1, -1, _("Specify optional module arguments"), + giveArgs, NULL, &giveArgs); + + newtFormAddHotKey(f, NEWT_KEY_F2); + newtFormAddHotKey(f, NEWT_KEY_F12); + + for (i = 0; i < numSorted; i++) { + char *buf = NULL; + + checked_asprintf(&buf, "%s (%s)", + modInfo->moduleList[sortedOrder[i]. + index].description, + modInfo->moduleList[sortedOrder[i]. + index].moduleName); + + newtListboxAppendEntry(listbox, buf, + INT_TO_POINTER(sortedOrder[i].index)); + } + + grid = newtCreateGrid(1, 4); + newtGridSetField(grid, 0, 0, NEWT_GRID_COMPONENT, text, 0, 0, 0, 1, 0, + 0); + newtGridSetField(grid, 0, 1, NEWT_GRID_COMPONENT, listbox, 0, 0, 0, 1, + 0, 0); + newtGridSetField(grid, 0, 2, NEWT_GRID_COMPONENT, argcheckbox, 0, 0, 0, + 1, 0, 0); + newtGridSetField(grid, 0, 3, NEWT_GRID_SUBGRID, buttons, 0, 0, 0, 0, 0, + NEWT_GRID_FLAG_GROWX); + newtGridWrappedWindow(grid, _("Select Device Driver to Load")); + + newtGridAddComponentsToForm(grid, f, 1); + + do { + newtFormRun(f, &es); + + num = POINTER_TO_INT(newtListboxGetCurrent(listbox)); + + if (es.reason == NEWT_EXIT_COMPONENT && es.u.co == back) { + done = -1; + } else if (es.reason == NEWT_EXIT_HOTKEY + && es.u.key == NEWT_KEY_F2) { + done = -2; + } else { + if (giveArgs != ' ') { + i = getManualModuleArgs(& + (modInfo->moduleList + [num]), &moduleArgs); + if (i == LOADER_BACK) + done = 0; + else + done = 1; + } else { + done = 1; + } + } + } while (done == 0); + + newtGridFree(grid, 1); + newtFormDestroy(f); + newtPopWindow(); + + if (done == -1) + return LOADER_BACK; + if (done == -2) { + loadDriverFromMedia(class, loaderData, 1, 1); + return chooseManualDriver(class, loaderData); + } + + mlLoadModule(modInfo->moduleList[num].moduleName, moduleArgs); + free(sortedOrder); + + if (moduleArgs) { + g_strfreev(moduleArgs); + } + + return LOADER_OK; } /* vim:set sw=8 noet */ diff --git a/loader/fwloader.c b/loader/fwloader.c index f9874bb..9f54e8e 100644 --- a/loader/fwloader.c +++ b/loader/fwloader.c @@ -50,199 +50,201 @@ #endif struct fw_loader { - int netlinkfd; - sigset_t sigmask; - char *fw_pathz; - size_t fw_pathz_len; - struct pollfd *fds; + int netlinkfd; + sigset_t sigmask; + char *fw_pathz; + size_t fw_pathz_len; + struct pollfd *fds; }; int done = 0; static inline int set_fd_coe(int fd, int enable) { - int rc; - long flags = 0; + int rc; + long flags = 0; - rc = fcntl(fd, F_GETFD, &flags); - if (rc < 0) - return rc; + rc = fcntl(fd, F_GETFD, &flags); + if (rc < 0) + return rc; - if (enable) - flags |= FD_CLOEXEC; - else - flags &= ~FD_CLOEXEC; + if (enable) + flags |= FD_CLOEXEC; + else + flags &= ~FD_CLOEXEC; - rc = fcntl(fd, F_SETFD, flags); - return rc; + rc = fcntl(fd, F_SETFD, flags); + return rc; } static int open_uevent_socket(struct fw_loader *fwl) { - int fd, rc; - struct sockaddr_nl sa; - - fd = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT); - if (fd < 0) - return -1; - set_fd_coe(fd, 1); - - memset(&sa, '\0', sizeof (sa)); - sa.nl_family = AF_NETLINK; - sa.nl_pid = getpid(); - sa.nl_groups = -1; - - if (bind(fd, (struct sockaddr *)&sa, sizeof (sa)) < 0) { - close(fd); - return -1; - } - - fwl->netlinkfd = fd; - - fd = open("/proc/sys/kernel/hotplug", O_RDWR); - if (fd >= 0) { - rc = ftruncate(fd, 0); - rc = write(fd, "\n", 1); - close(fd); - } - - fd = open("/sys/class/firmware/timeout", O_RDWR); - if (fd >= 0) { - rc = write(fd, "10", 2); - close(fd); - } - - return 0; + int fd, rc; + struct sockaddr_nl sa; + + fd = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT); + if (fd < 0) + return -1; + set_fd_coe(fd, 1); + + memset(&sa, '\0', sizeof(sa)); + sa.nl_family = AF_NETLINK; + sa.nl_pid = getpid(); + sa.nl_groups = -1; + + if (bind(fd, (struct sockaddr *)&sa, sizeof(sa)) < 0) { + close(fd); + return -1; + } + + fwl->netlinkfd = fd; + + fd = open("/proc/sys/kernel/hotplug", O_RDWR); + if (fd >= 0) { + rc = ftruncate(fd, 0); + rc = write(fd, "\n", 1); + close(fd); + } + + fd = open("/sys/class/firmware/timeout", O_RDWR); + if (fd >= 0) { + rc = write(fd, "10", 2); + close(fd); + } + + return 0; } extern void loaderSegvHandler(int signum); static void kill_hotplug_signal(int signum) { - signal(signum, kill_hotplug_signal); - logMessage(DEBUGLVL, "fwloader: got exit signal, quitting"); - done = 1; + signal(signum, kill_hotplug_signal); + logMessage(DEBUGLVL, "fwloader: got exit signal, quitting"); + done = 1; } static int daemonize(struct fw_loader *fwl) { - int fd; - int rc; - - signal(SIGTERM, kill_hotplug_signal); - signal(SIGSEGV, loaderSegvHandler); - signal(SIGTTOU, SIG_IGN); - signal(SIGTTIN, SIG_IGN); - signal(SIGTSTP, SIG_IGN); - - sigfillset(&fwl->sigmask); - sigdelset(&fwl->sigmask, SIGTERM); - sigdelset(&fwl->sigmask, SIGSEGV); - sigemptyset(&fwl->sigmask); - - prctl(PR_SET_NAME, "hotplug", 0, 0, 0); - rc = chdir("/"); - - fd = open("/proc/self/oom_adj", O_RDWR); - if (fd >= 0) { - rc = write(fd, "-17", 3); - close(fd); - } - - for (fd = 0; fd < getdtablesize(); fd++) { - if (fd == STDIN_FILENO || fd == STDOUT_FILENO || fd == STDERR_FILENO) - continue; - if (fd == tty_logfd || fd == file_logfd) - continue; - close(fd); - } - - setsid(); - fd = open("/dev/null", O_RDONLY); - close(STDIN_FILENO); - dup2(fd, STDIN_FILENO); - set_fd_coe(STDIN_FILENO, 1); - close(fd); - fd = open("/dev/null", O_WRONLY); - close(STDOUT_FILENO); - dup2(fd, STDOUT_FILENO); - set_fd_coe(STDOUT_FILENO, 1); - close(STDERR_FILENO); - dup2(fd, STDERR_FILENO); - set_fd_coe(STDERR_FILENO, 1); - close(fd); - - logMessage(DEBUGLVL, "fwloader: starting up (pid %d)", getpid()); - return 0; + int fd; + int rc; + + signal(SIGTERM, kill_hotplug_signal); + signal(SIGSEGV, loaderSegvHandler); + signal(SIGTTOU, SIG_IGN); + signal(SIGTTIN, SIG_IGN); + signal(SIGTSTP, SIG_IGN); + + sigfillset(&fwl->sigmask); + sigdelset(&fwl->sigmask, SIGTERM); + sigdelset(&fwl->sigmask, SIGSEGV); + sigemptyset(&fwl->sigmask); + + prctl(PR_SET_NAME, "hotplug", 0, 0, 0); + rc = chdir("/"); + + fd = open("/proc/self/oom_adj", O_RDWR); + if (fd >= 0) { + rc = write(fd, "-17", 3); + close(fd); + } + + for (fd = 0; fd < getdtablesize(); fd++) { + if (fd == STDIN_FILENO || fd == STDOUT_FILENO + || fd == STDERR_FILENO) + continue; + if (fd == tty_logfd || fd == file_logfd) + continue; + close(fd); + } + + setsid(); + fd = open("/dev/null", O_RDONLY); + close(STDIN_FILENO); + dup2(fd, STDIN_FILENO); + set_fd_coe(STDIN_FILENO, 1); + close(fd); + fd = open("/dev/null", O_WRONLY); + close(STDOUT_FILENO); + dup2(fd, STDOUT_FILENO); + set_fd_coe(STDOUT_FILENO, 1); + close(STDERR_FILENO); + dup2(fd, STDERR_FILENO); + set_fd_coe(STDERR_FILENO, 1); + close(fd); + + logMessage(DEBUGLVL, "fwloader: starting up (pid %d)", getpid()); + return 0; } struct uevent { - char *msg; - char *path; - char *envz; - size_t envz_len; + char *msg; + char *path; + char *envz; + size_t envz_len; }; static int get_netlink_msg(struct fw_loader *fwl, struct uevent *uevent) { - size_t len; - ssize_t size; - static char buffer[2560]; - char *pos; - char *msg = NULL, *path = NULL, *envz = NULL; - char *argv[] = { NULL }; - size_t envz_len; - error_t errnum; - - size = recv(fwl->netlinkfd, &buffer, sizeof (buffer), 0); - if (size < 0) - return -1; - - if ((size_t)size > sizeof (buffer) - 1) - size = sizeof (buffer) - 1; - buffer[size] = '\0'; - - len = strcspn(buffer, "@"); - if (!buffer[len]) - return -1; - - if ((errnum = argz_create(argv, &envz, &envz_len)) > 0) - goto err; - - pos = buffer; - msg = strndup(pos, len++); - pos += len; - path = strdup(pos); - - pos += strlen(pos) + 1; - if (len < size + 1) { - while (pos[0]) { - char *value = strchr(pos, '='); - if (value) - *(value++) = '\0'; - - if ((errnum = envz_add(&envz, &envz_len, pos, value)) > 0) - goto err; - pos += strlen(pos) + 1; - if (*pos) - pos += strlen(pos) + 1; - } - } - - uevent->msg = msg; - uevent->path = path; - uevent->envz = envz; - uevent->envz_len = envz_len; - return 0; + size_t len; + ssize_t size; + static char buffer[2560]; + char *pos; + char *msg = NULL, *path = NULL, *envz = NULL; + char *argv[] = { NULL }; + size_t envz_len; + error_t errnum; + + size = recv(fwl->netlinkfd, &buffer, sizeof(buffer), 0); + if (size < 0) + return -1; + + if ((size_t) size > sizeof(buffer) - 1) + size = sizeof(buffer) - 1; + buffer[size] = '\0'; + + len = strcspn(buffer, "@"); + if (!buffer[len]) + return -1; + + if ((errnum = argz_create(argv, &envz, &envz_len)) > 0) + goto err; + + pos = buffer; + msg = strndup(pos, len++); + pos += len; + path = strdup(pos); + + pos += strlen(pos) + 1; + if (len < size + 1) { + while (pos[0]) { + char *value = strchr(pos, '='); + if (value) + *(value++) = '\0'; + + if ((errnum = + envz_add(&envz, &envz_len, pos, value)) > 0) + goto err; + pos += strlen(pos) + 1; + if (*pos) + pos += strlen(pos) + 1; + } + } + + uevent->msg = msg; + uevent->path = path; + uevent->envz = envz; + uevent->envz_len = envz_len; + return 0; err: - if (msg) - free(msg); - if (path) - free(path); - while(envz) - argz_delete(&envz, &envz_len, envz); - errno = errnum; - return -1; + if (msg) + free(msg); + if (path) + free(path); + while (envz) + argz_delete(&envz, &envz_len, envz); + errno = errnum; + return -1; } /* Set the 'loading' attribute for a firmware device. @@ -250,421 +252,424 @@ err: * 0 == done loading * -1 == error */ -static int -get_loading_fd(const char *device) +static int get_loading_fd(const char *device) { - int fd = -1; - char *loading_path = NULL; - - if (asprintf(&loading_path, "%s/loading", device) < 0) { - logMessage(ERROR, "fwloader: device %s: asprintf: %m", device); - return -1; - } - logMessage(DEBUGLVL, "fwloader: looking for loading file at %s", loading_path); - fd = open(loading_path, O_RDWR | O_SYNC ); - if (fd < 0) - logMessage(ERROR, "fwloader: open %s: %m", loading_path); - free(loading_path); - return fd; + int fd = -1; + char *loading_path = NULL; + + if (asprintf(&loading_path, "%s/loading", device) < 0) { + logMessage(ERROR, "fwloader: device %s: asprintf: %m", device); + return -1; + } + logMessage(DEBUGLVL, "fwloader: looking for loading file at %s", + loading_path); + fd = open(loading_path, O_RDWR | O_SYNC); + if (fd < 0) + logMessage(ERROR, "fwloader: open %s: %m", loading_path); + free(loading_path); + return fd; } -static int -set_loading(int fd, int value) +static int set_loading(int fd, int value) { - int rc = 0; - - if (value == -1) - rc = write(fd, "-1", 3); - else if (value == 0) - rc = write(fd, "0", 2); - else if (value == 1) - rc = write(fd, "1", 2); - fsync(fd); - fdatasync(fd); - - return rc < 0 ? rc : 0; + int rc = 0; + + if (value == -1) + rc = write(fd, "-1", 3); + else if (value == 0) + rc = write(fd, "0", 2); + else if (value == 1) + rc = write(fd, "1", 2); + fsync(fd); + fdatasync(fd); + + return rc < 0 ? rc : 0; } -static int -fd_map(int fd, char **buf, size_t *bufsize) +static int fd_map(int fd, char **buf, size_t * bufsize) { - struct stat stats; - int en = 0; - - if (fstat(fd, &stats) < 0) { - en = errno; - close(fd); - errno = en; - return -1; - } - - *buf = mmap(NULL, stats.st_size, PROT_READ, MAP_SHARED, fd, 0); - if (*buf == MAP_FAILED) { - *buf = NULL; - en = errno; - close(fd); - errno = en; - return -1; - } - *bufsize = stats.st_size; - return 0; + struct stat stats; + int en = 0; + + if (fstat(fd, &stats) < 0) { + en = errno; + close(fd); + errno = en; + return -1; + } + + *buf = mmap(NULL, stats.st_size, PROT_READ, MAP_SHARED, fd, 0); + if (*buf == MAP_FAILED) { + *buf = NULL; + en = errno; + close(fd); + errno = en; + return -1; + } + *bufsize = stats.st_size; + return 0; } static int -file_map(const char *filename, char **buf, size_t *bufsize, int flags) +file_map(const char *filename, char **buf, size_t * bufsize, int flags) { - int fd, en, rc = 0; + int fd, en, rc = 0; - if ((fd = open(filename, flags ? flags : O_RDONLY)) < 0) - return -1; + if ((fd = open(filename, flags ? flags : O_RDONLY)) < 0) + return -1; - if (fd_map(fd, buf, bufsize) < 0) - rc = -1; + if (fd_map(fd, buf, bufsize) < 0) + rc = -1; - en = errno; - close(fd); - errno = en; + en = errno; + close(fd); + errno = en; - return rc; + return rc; } -static void -file_unmap(void *buf, size_t bufsize) +static void file_unmap(void *buf, size_t bufsize) { - munmap(buf, bufsize); + munmap(buf, bufsize); } -static int -fetcher(char *inpath, int outfd) +static int fetcher(char *inpath, int outfd) { - char *inbuf = NULL; - size_t inlen; - int count; - int en = 0; - int rc; - - errno = 0; - if (access(inpath, F_OK)) - goto out; - - if (file_map(inpath, &inbuf, &inlen, O_RDONLY) < 0) - goto out; - - lseek(outfd, 0, SEEK_SET); - rc = ftruncate(outfd, 0); - rc = ftruncate(outfd, inlen); - - count = 0; - while (count < inlen) { - ssize_t c; - c = write(outfd, inbuf + count, inlen - count); - if (c <= 0) - goto out; - count += c; - } + char *inbuf = NULL; + size_t inlen; + int count; + int en = 0; + int rc; + + errno = 0; + if (access(inpath, F_OK)) + goto out; + + if (file_map(inpath, &inbuf, &inlen, O_RDONLY) < 0) + goto out; + + lseek(outfd, 0, SEEK_SET); + rc = ftruncate(outfd, 0); + rc = ftruncate(outfd, inlen); + + count = 0; + while (count < inlen) { + ssize_t c; + c = write(outfd, inbuf + count, inlen - count); + if (c <= 0) + goto out; + count += c; + } out: - en = errno; - if (inbuf) - file_unmap(inbuf, inlen); - if (en) { - errno = en; - return -1; - } - return 0; + en = errno; + if (inbuf) + file_unmap(inbuf, inlen); + if (en) { + errno = en; + return -1; + } + return 0; } - static int _load_firmware(struct fw_loader *fwl, int fw_fd, char *sysdir, int timeout) { - int rc = 0; - char *fw_buf = NULL, *data = NULL; - size_t fw_len = 0; - int dfd = -1, lfd = -1; - int loading = -2; - size_t count; - - logMessage(DEBUGLVL, "fwloader: waiting for firmware dir at %s", sysdir); - timeout *= 1000000; - while (access(sysdir, F_OK) && timeout) { - udelay(100); - timeout -= 100; - } - if (!timeout) { - logMessage(ERROR, "fwloader: never found firmware dir at %s", sysdir); - return -ENOENT; - } - - if ((lfd = get_loading_fd(sysdir)) < 0) - return lfd; - - set_loading(lfd, 1); - loading = -1; - - if (fd_map(fw_fd, &fw_buf, &fw_len) < 0) { - rc = -errno; - goto out; - } - - if (asprintf(&data, "%s/data", sysdir) < 0) { - rc = -errno; - goto out; - } - if ((dfd = open(data, O_RDWR)) < 0) { - rc = -errno; - goto out; - } - count = 0; - while (count < fw_len) { - ssize_t c; - if ((c = write(dfd, fw_buf + count, fw_len - count)) <= 0) - goto out; - count += c; - } - loading = 0; + int rc = 0; + char *fw_buf = NULL, *data = NULL; + size_t fw_len = 0; + int dfd = -1, lfd = -1; + int loading = -2; + size_t count; + + logMessage(DEBUGLVL, "fwloader: waiting for firmware dir at %s", + sysdir); + timeout *= 1000000; + while (access(sysdir, F_OK) && timeout) { + udelay(100); + timeout -= 100; + } + if (!timeout) { + logMessage(ERROR, "fwloader: never found firmware dir at %s", + sysdir); + return -ENOENT; + } + + if ((lfd = get_loading_fd(sysdir)) < 0) + return lfd; + + set_loading(lfd, 1); + loading = -1; + + if (fd_map(fw_fd, &fw_buf, &fw_len) < 0) { + rc = -errno; + goto out; + } + + if (asprintf(&data, "%s/data", sysdir) < 0) { + rc = -errno; + goto out; + } + if ((dfd = open(data, O_RDWR)) < 0) { + rc = -errno; + goto out; + } + count = 0; + while (count < fw_len) { + ssize_t c; + if ((c = write(dfd, fw_buf + count, fw_len - count)) <= 0) + goto out; + count += c; + } + loading = 0; out: - if (dfd >= 0) - close(dfd); - if (fw_buf) - file_unmap(fw_buf, fw_len); - if (loading != -2) - set_loading(lfd, loading); - if (lfd >= 0) - close(lfd); - if (data) - free(data); - - return rc; + if (dfd >= 0) + close(dfd); + if (fw_buf) + file_unmap(fw_buf, fw_len); + if (loading != -2) + set_loading(lfd, loading); + if (lfd >= 0) + close(lfd); + if (data) + free(data); + + return rc; } static void load_firmware(struct fw_loader *fwl, struct uevent *uevent) { - char *devpath = NULL, *firmware = NULL, *timeout; - char *fw_file = NULL, *sys_file = NULL; - char *entry; - int timeout_secs; - char *tempfile; - int fd = -1; - - tempfile = strdup("/tmp/fw-XXXXXX"); - fd = mkstemp(tempfile); - if (fd < 0) { - logMessage(ERROR, "fwloader: mkstemp(\"%s\") failed: %m", tempfile); - free(tempfile); - return; - } - unlink(tempfile); - free(tempfile); - - devpath = envz_get(uevent->envz, uevent->envz_len, "DEVPATH"); - firmware = envz_get(uevent->envz, uevent->envz_len, "FIRMWARE"); - timeout = envz_get(uevent->envz, uevent->envz_len, "TIMEOUT"); - - if (!devpath || !firmware) { - argz_stringify(uevent->envz, uevent->envz_len, ' '); - logMessage(ERROR, "fwloader: environment: %s", uevent->envz); - return; - } - - errno = 0; - timeout_secs = strtol(timeout, NULL, 10); - - if ((errno == ERANGE && (timeout_secs == LONG_MIN || - timeout_secs == LONG_MAX)) || - (errno != 0 && timeout_secs == 0)) { - logMessage(ERROR, "%s: %d: %m", __func__, __LINE__); - abort(); - } - - /* find the file */ - for (entry = fwl->fw_pathz; entry; - entry = argz_next(fwl->fw_pathz, fwl->fw_pathz_len, entry)) { - if (asprintf(&fw_file, "%s/%s", entry, firmware) < 0) - return; - - logMessage(INFO, "fwloader: trying to find %s at %s", firmware, fw_file); - - if (fetcher(fw_file, fd) >= 0) - break; - - free(fw_file); - fw_file = NULL; - if (errno == ENOENT || errno == EPERM) - continue; - break; - } - if (!fw_file) - goto out; - - if (asprintf(&sys_file, "/sys%s/", devpath) < 0) - goto out; - - _load_firmware(fwl, fd, sys_file, timeout_secs); + char *devpath = NULL, *firmware = NULL, *timeout; + char *fw_file = NULL, *sys_file = NULL; + char *entry; + int timeout_secs; + char *tempfile; + int fd = -1; + + tempfile = strdup("/tmp/fw-XXXXXX"); + fd = mkstemp(tempfile); + if (fd < 0) { + logMessage(ERROR, "fwloader: mkstemp(\"%s\") failed: %m", + tempfile); + free(tempfile); + return; + } + unlink(tempfile); + free(tempfile); + + devpath = envz_get(uevent->envz, uevent->envz_len, "DEVPATH"); + firmware = envz_get(uevent->envz, uevent->envz_len, "FIRMWARE"); + timeout = envz_get(uevent->envz, uevent->envz_len, "TIMEOUT"); + + if (!devpath || !firmware) { + argz_stringify(uevent->envz, uevent->envz_len, ' '); + logMessage(ERROR, "fwloader: environment: %s", uevent->envz); + return; + } + + errno = 0; + timeout_secs = strtol(timeout, NULL, 10); + + if ((errno == ERANGE && (timeout_secs == LONG_MIN || + timeout_secs == LONG_MAX)) || + (errno != 0 && timeout_secs == 0)) { + logMessage(ERROR, "%s: %d: %m", __func__, __LINE__); + abort(); + } + + /* find the file */ + for (entry = fwl->fw_pathz; entry; + entry = argz_next(fwl->fw_pathz, fwl->fw_pathz_len, entry)) { + if (asprintf(&fw_file, "%s/%s", entry, firmware) < 0) + return; + + logMessage(INFO, "fwloader: trying to find %s at %s", firmware, + fw_file); + + if (fetcher(fw_file, fd) >= 0) + break; + + free(fw_file); + fw_file = NULL; + if (errno == ENOENT || errno == EPERM) + continue; + break; + } + if (!fw_file) + goto out; + + if (asprintf(&sys_file, "/sys%s/", devpath) < 0) + goto out; + + _load_firmware(fwl, fd, sys_file, timeout_secs); out: - if (fw_file) - free(fw_file); - if (sys_file) - free(sys_file); - if (fd != -1) - close(fd); + if (fw_file) + free(fw_file); + if (sys_file) + free(sys_file); + if (fd != -1) + close(fd); } static void handle_single_uevent(struct fw_loader *fwl, struct uevent *uevent) { - char *action = NULL; - char *subsystem = NULL; + char *action = NULL; + char *subsystem = NULL; - action = envz_get(uevent->envz, uevent->envz_len, "ACTION"); - subsystem = envz_get(uevent->envz, uevent->envz_len, "SUBSYSTEM"); + action = envz_get(uevent->envz, uevent->envz_len, "ACTION"); + subsystem = envz_get(uevent->envz, uevent->envz_len, "SUBSYSTEM"); - logMessage(DEBUGLVL, "fwloader: subsystem %s got action %s", subsystem, action); - if (!strcmp(action, "add") && !strcmp(subsystem, "firmware")) - load_firmware(fwl, uevent); + logMessage(DEBUGLVL, "fwloader: subsystem %s got action %s", subsystem, + action); + if (!strcmp(action, "add") && !strcmp(subsystem, "firmware")) + load_firmware(fwl, uevent); } static void handle_events(struct fw_loader *fwl) { - int rc; - struct uevent uevent; - if (fwl->fds == NULL) - fwl->fds = calloc(1, sizeof (struct pollfd)); - - do { - do { - if (done) - exit(0); - fwl->fds[0].events = POLLIN | POLLPRI; - fwl->fds[0].revents = 0; - fwl->fds[0].fd = fwl->netlinkfd; - - //logMessage(DEBUGLVL, "fwloader: polling on netlink socket"); - errno = 0; - rc = poll(fwl->fds, 1, -1); - //logMessage(DEBUGLVL, "fwloader: poll returned %d", rc); - - if (done) - exit(0); - } while (rc < 1 || (rc < 0 && errno == EINTR)); - - memset(&uevent, '\0', sizeof (uevent)); - if (get_netlink_msg(fwl, &uevent) < 0) - continue; - - handle_single_uevent(fwl, &uevent); - } while (1); - - if (fwl->fds) { - free(fwl->fds); - fwl->fds = NULL; - } + int rc; + struct uevent uevent; + if (fwl->fds == NULL) + fwl->fds = calloc(1, sizeof(struct pollfd)); + + do { + do { + if (done) + exit(0); + fwl->fds[0].events = POLLIN | POLLPRI; + fwl->fds[0].revents = 0; + fwl->fds[0].fd = fwl->netlinkfd; + + //logMessage(DEBUGLVL, "fwloader: polling on netlink socket"); + errno = 0; + rc = poll(fwl->fds, 1, -1); + //logMessage(DEBUGLVL, "fwloader: poll returned %d", rc); + + if (done) + exit(0); + } while (rc < 1 || (rc < 0 && errno == EINTR)); + + memset(&uevent, '\0', sizeof(uevent)); + if (get_netlink_msg(fwl, &uevent) < 0) + continue; + + handle_single_uevent(fwl, &uevent); + } while (1); + + if (fwl->fds) { + free(fwl->fds); + fwl->fds = NULL; + } } void set_fw_search_path(struct loaderData_s *loaderData, char *path) { - char *old = loaderData->fw_search_pathz, *new = NULL; - size_t old_len = loaderData->fw_search_pathz_len; - - loaderData->fw_search_pathz = NULL; - loaderData->fw_search_pathz_len = -1; - if (!path) { - if (old) - free(old); - return; - } - - if ((new = strdup(path)) == NULL) - goto out; - - loaderData->fw_search_pathz = NULL; - loaderData->fw_search_pathz_len = 0; - if (argz_create_sep(new, ':', &loaderData->fw_search_pathz, - &loaderData->fw_search_pathz_len) != 0) - goto out; - - if (old) - free(old); - - return; + char *old = loaderData->fw_search_pathz, *new = NULL; + size_t old_len = loaderData->fw_search_pathz_len; + + loaderData->fw_search_pathz = NULL; + loaderData->fw_search_pathz_len = -1; + if (!path) { + if (old) + free(old); + return; + } + + if ((new = strdup(path)) == NULL) + goto out; + + loaderData->fw_search_pathz = NULL; + loaderData->fw_search_pathz_len = 0; + if (argz_create_sep(new, ':', &loaderData->fw_search_pathz, + &loaderData->fw_search_pathz_len) != 0) + goto out; + + if (old) + free(old); + + return; out: - if (new) - free(new); - loaderData->fw_search_pathz = old; - loaderData->fw_search_pathz_len = old_len; + if (new) + free(new); + loaderData->fw_search_pathz = old; + loaderData->fw_search_pathz_len = old_len; - return; + return; } void add_fw_search_dir(struct loaderData_s *loaderData, char *dir) { - argz_add(&loaderData->fw_search_pathz, &loaderData->fw_search_pathz_len, - dir); + argz_add(&loaderData->fw_search_pathz, &loaderData->fw_search_pathz_len, + dir); } void do_fw_loader(struct loaderData_s *loaderData) { - struct fw_loader fwl; - int rc; + struct fw_loader fwl; + int rc; - memset(&fwl, '\0', sizeof (fwl)); - fwl.netlinkfd = -1; + memset(&fwl, '\0', sizeof(fwl)); + fwl.netlinkfd = -1; - fwl.fw_pathz = loaderData->fw_search_pathz; - fwl.fw_pathz_len = loaderData->fw_search_pathz_len; + fwl.fw_pathz = loaderData->fw_search_pathz; + fwl.fw_pathz_len = loaderData->fw_search_pathz_len; - logMessage(INFO, "fwloader: starting firmware loader"); + logMessage(INFO, "fwloader: starting firmware loader"); - rc = daemonize(&fwl); - if (rc < 0) { - logMessage(ERROR, "fwloader: daemonize() failed with %d: %m", rc); - exit(1); - } + rc = daemonize(&fwl); + if (rc < 0) { + logMessage(ERROR, "fwloader: daemonize() failed with %d: %m", + rc); + exit(1); + } - if (open_uevent_socket(&fwl) < 0) { - logMessage(ERROR, "fwloader: open_uevent_socket() failed: %m"); - exit(1); - } + if (open_uevent_socket(&fwl) < 0) { + logMessage(ERROR, "fwloader: open_uevent_socket() failed: %m"); + exit(1); + } - logMessage(DEBUGLVL, "fwloader: entering event loop"); - handle_events(&fwl); + logMessage(DEBUGLVL, "fwloader: entering event loop"); + handle_events(&fwl); - exit(1); + exit(1); } +void start_fw_loader(struct loaderData_s *loaderData) +{ + pid_t loader; -void start_fw_loader(struct loaderData_s *loaderData) { - pid_t loader; + loader = fork(); + if (loader > 0) + loaderData->fw_loader_pid = loader; + if (loader != 0) + return; - loader = fork(); - if (loader > 0) - loaderData->fw_loader_pid = loader; - if (loader != 0) - return; - - do_fw_loader(loaderData); + do_fw_loader(loaderData); } -void stop_fw_loader(struct loaderData_s *loaderData) { - int x = 0, rc; - siginfo_t siginfo; - if (loaderData->fw_loader_pid > 0) - kill(loaderData->fw_loader_pid, SIGTERM); - while (x <= 100) { - if (x > 90) - kill(loaderData->fw_loader_pid, SIGKILL); - memset(&siginfo, '\0', sizeof (siginfo)); - rc = waitid(P_PID, loaderData->fw_loader_pid, &siginfo, WNOHANG|WEXITED); - if (rc < 0 && errno == ECHILD) - return; - else if (rc == 0 && siginfo.si_pid != 0) - return; - else if (rc == 0) - x++; - usleep(10000); - } - return; +void stop_fw_loader(struct loaderData_s *loaderData) +{ + int x = 0, rc; + siginfo_t siginfo; + if (loaderData->fw_loader_pid > 0) + kill(loaderData->fw_loader_pid, SIGTERM); + while (x <= 100) { + if (x > 90) + kill(loaderData->fw_loader_pid, SIGKILL); + memset(&siginfo, '\0', sizeof(siginfo)); + rc = waitid(P_PID, loaderData->fw_loader_pid, &siginfo, + WNOHANG | WEXITED); + if (rc < 0 && errno == ECHILD) + return; + else if (rc == 0 && siginfo.si_pid != 0) + return; + else if (rc == 0) + x++; + usleep(10000); + } + return; } /* vim:set sw=8 noet */ diff --git a/loader/getparts.c b/loader/getparts.c index db4d671..7d2345f 100644 --- a/loader/getparts.c +++ b/loader/getparts.c @@ -32,151 +32,170 @@ #include "log.h" /* see if this is a partition name or not */ -static int isPartitionName(char *pname) { - - /* if it doesnt start with a alpha its not one */ - if (!isalpha(*pname) || strstr(pname, "ram")) - return 0; - - /* if it has a '/' in it then treat it specially */ - if (strchr(pname, '/') && !strstr(pname, "iseries") && - !strstr(pname, "i2o")) { - /* assume its either a /dev/ida/ or /dev/cciss device */ - /* these have form of c?d?p? if its a partition */ - return strchr(pname, 'p') != NULL; - } else { - /* if it ends with a digit we're ok */ - return isdigit(pname[strlen(pname)-1]); - } +static int isPartitionName(char *pname) +{ + + /* if it doesnt start with a alpha its not one */ + if (!isalpha(*pname) || strstr(pname, "ram")) + return 0; + + /* if it has a '/' in it then treat it specially */ + if (strchr(pname, '/') && !strstr(pname, "iseries") && + !strstr(pname, "i2o")) { + /* assume its either a /dev/ida/ or /dev/cciss device */ + /* these have form of c?d?p? if its a partition */ + return strchr(pname, 'p') != NULL; + } else { + /* if it ends with a digit we're ok */ + return isdigit(pname[strlen(pname) - 1]); + } } /* return NULL terminated array of pointers to names of partitons in * /proc/partitions */ -char **getPartitionsList(char * disk) { - FILE *f; - int numfound = 0; - char **rc=NULL; - - f = fopen("/proc/partitions", "r"); - if (!f) { - logMessage(ERROR, "getPartitionsList: could not open /proc/partitions"); - return NULL; - } - - /* read through /proc/partitions and parse out partitions */ - while (1) { - char *tmpptr, *pptr; - char tmpstr[4096]; - - tmpptr = fgets(tmpstr, sizeof(tmpstr), f); - - if (tmpptr) { - char *a, *b; - int toknum = 0; - - a = tmpstr; - while (1) { - b = strsep(&a, " \n"); - - /* if no fields left abort */ - if (!b) - break; - - /* if field was empty means we hit another delimiter */ - if (!*b) - continue; - - /* make sure this is a valid partition line, should start */ - /* with a numeral */ - if (toknum == 0) { - if (!isdigit(*b)) - break; - } else if (toknum == 2) { - /* if size is exactly 1 then ignore it as an extended */ - if (!strcmp(b, "1")) - break; - } else if (toknum == 3) { - /* this should be the partition name */ - /* now we need to see if this is the block device or */ - /* actually a partition name */ - if (!isPartitionName(b)) - break; +char **getPartitionsList(char *disk) +{ + FILE *f; + int numfound = 0; + char **rc = NULL; + + f = fopen("/proc/partitions", "r"); + if (!f) { + logMessage(ERROR, + "getPartitionsList: could not open /proc/partitions"); + return NULL; + } - /* make sure that either we don't care about the disk - * or it's this one */ - if ((disk != NULL) && (strncmp(disk, b, strlen(disk)))) - break; - - /* we found a partition! */ - pptr = (char *) malloc(strlen(b) + 7); - sprintf(pptr, "/dev/%s", b); - - if (!rc) { - rc = (char **) malloc(2*sizeof(char *)); - rc[0] = pptr; - rc[1] = NULL; - } else { - int idx; - - rc = (char **) realloc(rc, (numfound+2)*sizeof(char *)); - idx = 0; - while (idx < numfound) { - if (strcmp(pptr, rc[idx]) < 0) - break; - - idx++; + /* read through /proc/partitions and parse out partitions */ + while (1) { + char *tmpptr, *pptr; + char tmpstr[4096]; + + tmpptr = fgets(tmpstr, sizeof(tmpstr), f); + + if (tmpptr) { + char *a, *b; + int toknum = 0; + + a = tmpstr; + while (1) { + b = strsep(&a, " \n"); + + /* if no fields left abort */ + if (!b) + break; + + /* if field was empty means we hit another delimiter */ + if (!*b) + continue; + + /* make sure this is a valid partition line, should start */ + /* with a numeral */ + if (toknum == 0) { + if (!isdigit(*b)) + break; + } else if (toknum == 2) { + /* if size is exactly 1 then ignore it as an extended */ + if (!strcmp(b, "1")) + break; + } else if (toknum == 3) { + /* this should be the partition name */ + /* now we need to see if this is the block device or */ + /* actually a partition name */ + if (!isPartitionName(b)) + break; + + /* make sure that either we don't care about the disk + * or it's this one */ + if ((disk != NULL) + && (strncmp(disk, b, strlen(disk)))) + break; + + /* we found a partition! */ + pptr = (char *)malloc(strlen(b) + 7); + sprintf(pptr, "/dev/%s", b); + + if (!rc) { + rc = (char **)malloc(2 * + sizeof(char + *)); + rc[0] = pptr; + rc[1] = NULL; + } else { + int idx; + + rc = (char **)realloc(rc, + (numfound + + + 2) * + sizeof + (char *)); + idx = 0; + while (idx < numfound) { + if (strcmp + (pptr, rc[idx]) < 0) + break; + + idx++; + } + + /* move existing out of way if necessary */ + if (idx != numfound) + memmove(rc + idx + 1, + rc + idx, + (numfound - + idx) * + sizeof(char *)); + + rc[idx] = pptr; + rc[numfound + 1] = NULL; + } + numfound++; + break; + } + toknum++; } - - /* move existing out of way if necessary */ - if (idx != numfound) - memmove(rc+idx+1, rc+idx, (numfound-idx)*sizeof(char *)); - - rc[idx] = pptr; - rc[numfound+1] = NULL; - } - numfound++; - break; + } else { + break; } - toknum++; - } - } else { - break; } - } - fclose(f); + fclose(f); - return rc; + return rc; } /* returns length of partitionlist */ -int lenPartitionsList(char **list) { - char **part; - int rc; +int lenPartitionsList(char **list) +{ + char **part; + int rc; - if (!list) return 0; - for (rc = 0, part = list; *part; rc++, part++); + if (!list) + return 0; + for (rc = 0, part = list; *part; rc++, part++) ; - return rc; + return rc; } /* frees partition list */ -void freePartitionsList(char **list) { - char **part; +void freePartitionsList(char **list) +{ + char **part; - if (!list) - return; + if (!list) + return; - for (part = list; *part; part++) { - if (*part) { - free(*part); - *part = NULL; - } - } + for (part = list; *part; part++) { + if (*part) { + free(*part); + *part = NULL; + } + } - free(list); - list = NULL; + free(list); + list = NULL; } /* vim:set sw=8 noet */ diff --git a/loader/getparts.h b/loader/getparts.h index ce82921..f01022e 100644 --- a/loader/getparts.h +++ b/loader/getparts.h @@ -20,7 +20,7 @@ #ifndef GETPARTS_H #define GETPARTS_H -char **getPartitionsList(char * disk); +char **getPartitionsList(char *disk); int lenPartitionsList(char **list); void freePartitionsList(char **list); diff --git a/loader/hardware.c b/loader/hardware.c index 553e66e..647794f 100644 --- a/loader/hardware.c +++ b/loader/hardware.c @@ -45,62 +45,63 @@ /* boot flags */ extern uint64_t flags; -static int detectHardware() { - int child, rc, status; - int timeout = 0; /* FIXME: commandline option for this */ - - fprintf(stderr, "detecting hardware...\n"); - logMessage(DEBUGLVL, "probing buses"); - - if (!(child = fork())) { - int fd = open("/dev/tty3", O_RDWR); - - dup2(fd, 0); - dup2(fd, 1); - dup2(fd, 2); - close(fd); - - rc = execl("/sbin/udevadm", "udevadm", "trigger", NULL); - _exit(1); - } - - waitpid(child, &status, 0); - if (!WIFEXITED(status) || (WIFEXITED(status) && WEXITSTATUS(status))) { - rc = 1; - } else { - rc = 0; - } - - fprintf(stderr, "waiting for hardware to initialize...\n"); - logMessage(DEBUGLVL, "waiting for hardware to initialize"); - - if (!(child = fork())) { - char *args[] = { "/sbin/udevadm", "settle", NULL, NULL }; - int fd = open("/dev/tty3", O_RDWR); - - dup2(fd, 0); - dup2(fd, 1); - dup2(fd, 2); - close(fd); - - if (timeout) { - checked_asprintf(&args[2], "--timeout=%d", timeout); - } - - rc = execv("/sbin/udevadm", args); - _exit(1); - } - - waitpid(child, &status, 0); - if (!WIFEXITED(status) || (WIFEXITED(status) && WEXITSTATUS(status))) { - rc = 1; - } else { - rc = 0; - } - if (rc) { - return LOADER_ERROR; - } - return LOADER_OK; +static int detectHardware() +{ + int child, rc, status; + int timeout = 0; /* FIXME: commandline option for this */ + + fprintf(stderr, "detecting hardware...\n"); + logMessage(DEBUGLVL, "probing buses"); + + if (!(child = fork())) { + int fd = open("/dev/tty3", O_RDWR); + + dup2(fd, 0); + dup2(fd, 1); + dup2(fd, 2); + close(fd); + + rc = execl("/sbin/udevadm", "udevadm", "trigger", NULL); + _exit(1); + } + + waitpid(child, &status, 0); + if (!WIFEXITED(status) || (WIFEXITED(status) && WEXITSTATUS(status))) { + rc = 1; + } else { + rc = 0; + } + + fprintf(stderr, "waiting for hardware to initialize...\n"); + logMessage(DEBUGLVL, "waiting for hardware to initialize"); + + if (!(child = fork())) { + char *args[] = { "/sbin/udevadm", "settle", NULL, NULL }; + int fd = open("/dev/tty3", O_RDWR); + + dup2(fd, 0); + dup2(fd, 1); + dup2(fd, 2); + close(fd); + + if (timeout) { + checked_asprintf(&args[2], "--timeout=%d", timeout); + } + + rc = execv("/sbin/udevadm", args); + _exit(1); + } + + waitpid(child, &status, 0); + if (!WIFEXITED(status) || (WIFEXITED(status) && WEXITSTATUS(status))) { + rc = 1; + } else { + rc = 0; + } + if (rc) { + return LOADER_ERROR; + } + return LOADER_OK; } /* this allows us to do an early load of modules specified on the @@ -109,44 +110,48 @@ static int detectHardware() { * FIXME: this syntax is likely to change in a future release * but is done as a quick hack for the present. */ -int earlyModuleLoad(int justProbe) { - int fd, len, i; - char buf[1024], *cmdLine; - gint argc = 0; - gchar **argv = NULL; - GError *optErr = NULL; - - /* FIXME: reparsing /proc/cmdline to avoid major loader changes. - * should probably be done in loader.c:parseCmdline() like everything - * else - */ - if ((fd = open("/proc/cmdline", O_RDONLY)) < 0) return 1; - len = read(fd, buf, sizeof(buf) - 1); - close(fd); - if (len <= 0) return 1; - - buf[len] = '\0'; - cmdLine = buf; - - if (!g_shell_parse_argv(cmdLine, &argc, &argv, &optErr)) { - g_error_free(optErr); - return 1; - } - - for (i=0; i < argc; i++) { - if (!strncasecmp(argv[i], "driverload=", 11)) { - logMessage(INFO, "loading %s early", argv[i] + 11); - mlLoadModuleSet(argv[i] + 11); - } - } - return 0; +int earlyModuleLoad(int justProbe) +{ + int fd, len, i; + char buf[1024], *cmdLine; + gint argc = 0; + gchar **argv = NULL; + GError *optErr = NULL; + + /* FIXME: reparsing /proc/cmdline to avoid major loader changes. + * should probably be done in loader.c:parseCmdline() like everything + * else + */ + if ((fd = open("/proc/cmdline", O_RDONLY)) < 0) + return 1; + len = read(fd, buf, sizeof(buf) - 1); + close(fd); + if (len <= 0) + return 1; + + buf[len] = '\0'; + cmdLine = buf; + + if (!g_shell_parse_argv(cmdLine, &argc, &argv, &optErr)) { + g_error_free(optErr); + return 1; + } + + for (i = 0; i < argc; i++) { + if (!strncasecmp(argv[i], "driverload=", 11)) { + logMessage(INFO, "loading %s early", argv[i] + 11); + mlLoadModuleSet(argv[i] + 11); + } + } + return 0; } -int busProbe(int justProbe) { - /* autodetect whatever we can */ - if (justProbe) - return 0; - return detectHardware(); +int busProbe(int justProbe) +{ + /* autodetect whatever we can */ + if (justProbe) + return 0; + return detectHardware(); } /* check if the system has been booted with dasd parameters */ @@ -154,49 +159,51 @@ int busProbe(int justProbe) { /* are visible to Linux. Otherwise load dasd modules probeonly, */ /* then parse proc to find active DASDs */ /* Reload dasd_mod with correct range of DASD ports */ -void dasdSetup() { +void dasdSetup() +{ #if !defined(__s390__) && !defined(__s390x__) - return; + return; #else - char **dasd_parms; - char *line; - char *parms = NULL, *parms_end; - FILE *fd; - - dasd_parms = malloc(sizeof(*dasd_parms) * 2); - dasd_parms[0] = NULL; - dasd_parms[1] = NULL; - - fd = fopen ("/tmp/dasd_ports", "r"); - if(fd) { - line = (char *)malloc(sizeof(char) * 200); - while (fgets (line, 199, fd) != NULL) { - if((parms = strstr(line, "dasd=")) || - (parms = strstr(line, "DASD="))) { - strncpy(parms, "dasd", 4); - parms_end = parms; - while(*parms_end && !(isspace(*parms_end))) parms_end++; - *parms_end = '\0'; - break; - } - } - fclose(fd); - if (strlen(parms) > 5) - dasd_parms[0] = strdup(parms); - free(line); - } - if(dasd_parms[0]) { - mlLoadModule("dasd_mod", dasd_parms); - - mlLoadModuleSet("dasd_diag_mod:dasd_fba_mod:dasd_eckd_mod"); - free(dasd_parms); - return; - } else { - dasd_parms[0] = "dasd=autodetect"; - mlLoadModule("dasd_mod", dasd_parms); - mlLoadModuleSet("dasd_diag_mod:dasd_fba_mod:dasd_eckd_mod"); - free(dasd_parms); - } + char **dasd_parms; + char *line; + char *parms = NULL, *parms_end; + FILE *fd; + + dasd_parms = malloc(sizeof(*dasd_parms) * 2); + dasd_parms[0] = NULL; + dasd_parms[1] = NULL; + + fd = fopen("/tmp/dasd_ports", "r"); + if (fd) { + line = (char *)malloc(sizeof(char) * 200); + while (fgets(line, 199, fd) != NULL) { + if ((parms = strstr(line, "dasd=")) || + (parms = strstr(line, "DASD="))) { + strncpy(parms, "dasd", 4); + parms_end = parms; + while (*parms_end && !(isspace(*parms_end))) + parms_end++; + *parms_end = '\0'; + break; + } + } + fclose(fd); + if (strlen(parms) > 5) + dasd_parms[0] = strdup(parms); + free(line); + } + if (dasd_parms[0]) { + mlLoadModule("dasd_mod", dasd_parms); + + mlLoadModuleSet("dasd_diag_mod:dasd_fba_mod:dasd_eckd_mod"); + free(dasd_parms); + return; + } else { + dasd_parms[0] = "dasd=autodetect"; + mlLoadModule("dasd_mod", dasd_parms); + mlLoadModuleSet("dasd_diag_mod:dasd_fba_mod:dasd_eckd_mod"); + free(dasd_parms); + } #endif } diff --git a/loader/hdinstall.c b/loader/hdinstall.c index f421a56..a54b6e6 100644 --- a/loader/hdinstall.c +++ b/loader/hdinstall.c @@ -55,432 +55,455 @@ extern uint64_t flags; /* given a partition device and directory, tries to mount hd install image */ -static char * setupIsoImages(char * device, char * dirName, char * location) { - int rc = 0; - char *url = NULL, *dirspec, *updpath, *path; +static char *setupIsoImages(char *device, char *dirName, char *location) +{ + int rc = 0; + char *url = NULL, *dirspec, *updpath, *path; - logMessage(INFO, "mounting device %s for hard drive install", device); + logMessage(INFO, "mounting device %s for hard drive install", device); - if (doPwMount(device, "/mnt/isodir", "auto", "ro", NULL)) - return NULL; + if (doPwMount(device, "/mnt/isodir", "auto", "ro", NULL)) + return NULL; - checked_asprintf(&dirspec, "/mnt/isodir%.*s", - (int) (strrchr(dirName, '/') - dirName), dirName); - checked_asprintf(&path, "/mnt/isodir%s", dirName); + checked_asprintf(&dirspec, "/mnt/isodir%.*s", + (int)(strrchr(dirName, '/') - dirName), dirName); + checked_asprintf(&path, "/mnt/isodir%s", dirName); - if (path) { - logMessage(INFO, "Path to stage2 image is %s", path); + if (path) { + logMessage(INFO, "Path to stage2 image is %s", path); - rc = copyFile(path, "/tmp/install.img"); - rc = mountStage2("/tmp/install.img"); + rc = copyFile(path, "/tmp/install.img"); + rc = mountStage2("/tmp/install.img"); - free(path); + free(path); - if (rc) { - umountLoopback("/mnt/runtime", "/dev/loop0"); - umount("/mnt/isodir"); - goto err; - } + if (rc) { + umountLoopback("/mnt/runtime", "/dev/loop0"); + umount("/mnt/isodir"); + goto err; + } - checked_asprintf(&updpath, "%s/updates.img", dirspec); + checked_asprintf(&updpath, "%s/updates.img", dirspec); - logMessage(INFO, "Looking for updates for HD in %s", updpath); - copyUpdatesImg(updpath); - free(updpath); + logMessage(INFO, "Looking for updates for HD in %s", updpath); + copyUpdatesImg(updpath); + free(updpath); - checked_asprintf(&updpath, "%s/product.img", dirspec); + checked_asprintf(&updpath, "%s/product.img", dirspec); - logMessage(INFO, "Looking for product for HD in %s", updpath); - copyProductImg(updpath); + logMessage(INFO, "Looking for product for HD in %s", updpath); + copyProductImg(updpath); - free(updpath); - free(dirspec); - umount("/mnt/isodir"); + free(updpath); + free(dirspec); + umount("/mnt/isodir"); - checked_asprintf(&url, "hd:%s:/%s", device, - dirName ? dirName : "."); + checked_asprintf(&url, "hd:%s:/%s", device, + dirName ? dirName : "."); - return url; - } else { - free(dirspec); - free(path); + return url; + } else { + free(dirspec); + free(path); - if (rc) { - umount("/mnt/isodir"); - return NULL; - } - } + if (rc) { + umount("/mnt/isodir"); + return NULL; + } + } err: - newtWinMessage(_("Error"), _("OK"), - _("An error occured finding the installation image " - "on your hard drive. Please check your images and " - "try again.")); - return NULL; + newtWinMessage(_("Error"), _("OK"), + _("An error occured finding the installation image " + "on your hard drive. Please check your images and " + "try again.")); + return NULL; } /* setup hard drive based install from a partition with a filesystem and * ISO images on that filesystem */ -char * mountHardDrive(struct installMethod * method, - char * location, struct loaderData_s * loaderData) { - int rc; - int i; - - newtComponent listbox, label, dirEntry, form, okay, back, text; - struct newtExitStruct es; - newtGrid entryGrid, grid, buttons; - - int done = 0; - char * dir = strdup(""); - char * tmpDir; - char * url = NULL; - char * buf, *substr; - int numPartitions; - - char **partition_list; - char *selpart; - char *kspartition = NULL, *ksdirectory = NULL; - - /* handle kickstart/stage2= data first if available */ - if (loaderData->method == METHOD_HD && loaderData->stage2Data) { - kspartition = ((struct hdInstallData *)loaderData->stage2Data)->partition; - ksdirectory = ((struct hdInstallData *)loaderData->stage2Data)->directory; - logMessage(INFO, "partition is %s, dir is %s", kspartition, ksdirectory); - - /* if exist, duplicate */ - if (kspartition) - kspartition = strdup(kspartition); - if (ksdirectory) - ksdirectory = strdup(ksdirectory); - - if (!kspartition || !ksdirectory) { - logMessage(ERROR, "missing partition or directory specification"); - loaderData->method = -1; - - if (loaderData->inferredStage2) - loaderData->invalidRepoParam = 1; - } else { - /* if we start with /dev, strip it (#121486) */ - char *kspart = kspartition; - if (!strncmp(kspart, "/dev/", 5)) - kspart = kspart + 5; - - url = setupIsoImages(kspart, ksdirectory, location); - if (!url) { - logMessage(ERROR, "unable to find %s installation images on hd", - getProductName()); - loaderData->method = -1; - - if (loaderData->inferredStage2) - loaderData->invalidRepoParam = 1; - } else { - free(kspartition); - free(ksdirectory); - return url; - } - } - } else { - kspartition = NULL; - ksdirectory = NULL; - } - - /* if we're here its either because this is interactive, or the */ - /* hd kickstart directive was faulty and we have to prompt for */ - /* location of harddrive image */ - - partition_list = NULL; - while (!done) { - /* if we're doing another pass free this up first */ - if (partition_list) - freePartitionsList(partition_list); - - partition_list = getPartitionsList(NULL); - numPartitions = lenPartitionsList(partition_list); - - /* no partitions found, try to load a device driver disk for storage */ - if (!numPartitions) { - rc = newtWinChoice(_("Hard Drives"), _("Yes"), _("Back"), - _("You don't seem to have any hard drives on " - "your system! Would you like to configure " - "additional devices?")); - if (rc == 2) { - loaderData->stage2Data = NULL; - return NULL; - } - - rc = loadDriverFromMedia(DEVICE_DISK, loaderData, 0, 0); - continue; - } - - /* now find out which partition has the stage2 image */ - checked_asprintf(&buf, _("What partition and directory on that " - "partition holds the installation image " - "for %s? If you don't see the disk drive " - "you're using listed here, press F2 to " - "configure additional devices."), - getProductName()); - - text = newtTextboxReflowed(-1, -1, buf, 62, 5, 5, 0); - free(buf); - - listbox = newtListbox(-1, -1, numPartitions > 5 ? 5 : numPartitions, - NEWT_FLAG_RETURNEXIT | - (numPartitions > 5 ? NEWT_FLAG_SCROLL : 0)); - - for (i = 0; i < numPartitions; i++) - newtListboxAppendEntry(listbox,partition_list[i],partition_list[i]); - - /* if we had ks data around use it to prime entry, then get rid of it*/ - if (kspartition) { - newtListboxSetCurrentByKey(listbox, kspartition); - free(kspartition); - kspartition = NULL; - } - - label = newtLabel(-1, -1, _("Directory holding image:")); - - dirEntry = newtEntry(28, 11, dir, 28, (const char **) &tmpDir, - NEWT_ENTRY_SCROLL); - - /* if we had ks data around use it to prime entry, then get rid of it*/ - if (ksdirectory) { - newtEntrySet(dirEntry, ksdirectory, 1); - free(ksdirectory); - ksdirectory = NULL; - } - - entryGrid = newtGridHStacked(NEWT_GRID_COMPONENT, label, - NEWT_GRID_COMPONENT, dirEntry, - NEWT_GRID_EMPTY); - - buttons = newtButtonBar(_("OK"), &okay, _("Back"), &back, NULL); - - grid = newtCreateGrid(1, 4); - newtGridSetField(grid, 0, 0, NEWT_GRID_COMPONENT, text, - 0, 0, 0, 1, 0, 0); - newtGridSetField(grid, 0, 1, NEWT_GRID_COMPONENT, listbox, - 0, 0, 0, 1, 0, 0); - newtGridSetField(grid, 0, 2, NEWT_GRID_SUBGRID, entryGrid, - 0, 0, 0, 1, 0, 0); - newtGridSetField(grid, 0, 3, NEWT_GRID_SUBGRID, buttons, - 0, 0, 0, 0, 0, NEWT_GRID_FLAG_GROWX); - - newtGridWrappedWindow(grid, _("Select Partition")); - - form = newtForm(NULL, NULL, 0); - newtFormAddHotKey(form, NEWT_KEY_F2); - newtFormAddHotKey(form, NEWT_KEY_F12); - - newtGridAddComponentsToForm(grid, form, 1); - newtGridFree(grid, 1); - - newtFormRun(form, &es); - - selpart = newtListboxGetCurrent(listbox); - - free(dir); - if (tmpDir && *tmpDir) { - /* Protect from form free. */ - dir = strdup(tmpDir); - } else { - dir = strdup(""); - } - - newtFormDestroy(form); - newtPopWindow(); - - if (es.reason == NEWT_EXIT_COMPONENT && es.u.co == back) { - loaderData->stage2Data = NULL; - return NULL; - } else if (es.reason == NEWT_EXIT_HOTKEY && es.u.key == NEWT_KEY_F2) { - rc = loadDriverFromMedia(DEVICE_DISK, loaderData, 0, 0); - continue; - } - - logMessage(INFO, "partition %s selected", selpart); - - /* If the user-provided URL points at a repo instead of a stage2 - * image, fix that up now. - */ - substr = strstr(dir, ".img"); - if (!substr || (substr && *(substr+4) != '\0')) { - checked_asprintf(&dir, "%s/images/install.img", dir); - } - - loaderData->invalidRepoParam = 1; - - url = setupIsoImages(selpart, dir, location); - if (!url) { - newtWinMessage(_("Error"), _("OK"), - _("Device %s does not appear to contain " - "an installation image."), selpart, getProductName()); - continue; - } - - done = 1; - } - - free(dir); - - return url; +char *mountHardDrive(struct installMethod *method, + char *location, struct loaderData_s *loaderData) +{ + int rc; + int i; + + newtComponent listbox, label, dirEntry, form, okay, back, text; + struct newtExitStruct es; + newtGrid entryGrid, grid, buttons; + + int done = 0; + char *dir = strdup(""); + char *tmpDir; + char *url = NULL; + char *buf, *substr; + int numPartitions; + + char **partition_list; + char *selpart; + char *kspartition = NULL, *ksdirectory = NULL; + + /* handle kickstart/stage2= data first if available */ + if (loaderData->method == METHOD_HD && loaderData->stage2Data) { + kspartition = + ((struct hdInstallData *)loaderData->stage2Data)->partition; + ksdirectory = + ((struct hdInstallData *)loaderData->stage2Data)->directory; + logMessage(INFO, "partition is %s, dir is %s", kspartition, + ksdirectory); + + /* if exist, duplicate */ + if (kspartition) + kspartition = strdup(kspartition); + if (ksdirectory) + ksdirectory = strdup(ksdirectory); + + if (!kspartition || !ksdirectory) { + logMessage(ERROR, + "missing partition or directory specification"); + loaderData->method = -1; + + if (loaderData->inferredStage2) + loaderData->invalidRepoParam = 1; + } else { + /* if we start with /dev, strip it (#121486) */ + char *kspart = kspartition; + if (!strncmp(kspart, "/dev/", 5)) + kspart = kspart + 5; + + url = setupIsoImages(kspart, ksdirectory, location); + if (!url) { + logMessage(ERROR, + "unable to find %s installation images on hd", + getProductName()); + loaderData->method = -1; + + if (loaderData->inferredStage2) + loaderData->invalidRepoParam = 1; + } else { + free(kspartition); + free(ksdirectory); + return url; + } + } + } else { + kspartition = NULL; + ksdirectory = NULL; + } + + /* if we're here its either because this is interactive, or the */ + /* hd kickstart directive was faulty and we have to prompt for */ + /* location of harddrive image */ + + partition_list = NULL; + while (!done) { + /* if we're doing another pass free this up first */ + if (partition_list) + freePartitionsList(partition_list); + + partition_list = getPartitionsList(NULL); + numPartitions = lenPartitionsList(partition_list); + + /* no partitions found, try to load a device driver disk for storage */ + if (!numPartitions) { + rc = newtWinChoice(_("Hard Drives"), _("Yes"), + _("Back"), + _ + ("You don't seem to have any hard drives on " + "your system! Would you like to configure " + "additional devices?")); + if (rc == 2) { + loaderData->stage2Data = NULL; + return NULL; + } + + rc = loadDriverFromMedia(DEVICE_DISK, loaderData, 0, 0); + continue; + } + + /* now find out which partition has the stage2 image */ + checked_asprintf(&buf, _("What partition and directory on that " + "partition holds the installation image " + "for %s? If you don't see the disk drive " + "you're using listed here, press F2 to " + "configure additional devices."), + getProductName()); + + text = newtTextboxReflowed(-1, -1, buf, 62, 5, 5, 0); + free(buf); + + listbox = + newtListbox(-1, -1, numPartitions > 5 ? 5 : numPartitions, + NEWT_FLAG_RETURNEXIT | (numPartitions > + 5 ? NEWT_FLAG_SCROLL : + 0)); + + for (i = 0; i < numPartitions; i++) + newtListboxAppendEntry(listbox, partition_list[i], + partition_list[i]); + + /* if we had ks data around use it to prime entry, then get rid of it */ + if (kspartition) { + newtListboxSetCurrentByKey(listbox, kspartition); + free(kspartition); + kspartition = NULL; + } + + label = newtLabel(-1, -1, _("Directory holding image:")); + + dirEntry = newtEntry(28, 11, dir, 28, (const char **)&tmpDir, + NEWT_ENTRY_SCROLL); + + /* if we had ks data around use it to prime entry, then get rid of it */ + if (ksdirectory) { + newtEntrySet(dirEntry, ksdirectory, 1); + free(ksdirectory); + ksdirectory = NULL; + } + + entryGrid = newtGridHStacked(NEWT_GRID_COMPONENT, label, + NEWT_GRID_COMPONENT, dirEntry, + NEWT_GRID_EMPTY); + + buttons = newtButtonBar(_("OK"), &okay, _("Back"), &back, NULL); + + grid = newtCreateGrid(1, 4); + newtGridSetField(grid, 0, 0, NEWT_GRID_COMPONENT, text, + 0, 0, 0, 1, 0, 0); + newtGridSetField(grid, 0, 1, NEWT_GRID_COMPONENT, listbox, + 0, 0, 0, 1, 0, 0); + newtGridSetField(grid, 0, 2, NEWT_GRID_SUBGRID, entryGrid, + 0, 0, 0, 1, 0, 0); + newtGridSetField(grid, 0, 3, NEWT_GRID_SUBGRID, buttons, + 0, 0, 0, 0, 0, NEWT_GRID_FLAG_GROWX); + + newtGridWrappedWindow(grid, _("Select Partition")); + + form = newtForm(NULL, NULL, 0); + newtFormAddHotKey(form, NEWT_KEY_F2); + newtFormAddHotKey(form, NEWT_KEY_F12); + + newtGridAddComponentsToForm(grid, form, 1); + newtGridFree(grid, 1); + + newtFormRun(form, &es); + + selpart = newtListboxGetCurrent(listbox); + + free(dir); + if (tmpDir && *tmpDir) { + /* Protect from form free. */ + dir = strdup(tmpDir); + } else { + dir = strdup(""); + } + + newtFormDestroy(form); + newtPopWindow(); + + if (es.reason == NEWT_EXIT_COMPONENT && es.u.co == back) { + loaderData->stage2Data = NULL; + return NULL; + } else if (es.reason == NEWT_EXIT_HOTKEY + && es.u.key == NEWT_KEY_F2) { + rc = loadDriverFromMedia(DEVICE_DISK, loaderData, 0, 0); + continue; + } + + logMessage(INFO, "partition %s selected", selpart); + + /* If the user-provided URL points at a repo instead of a stage2 + * image, fix that up now. + */ + substr = strstr(dir, ".img"); + if (!substr || (substr && *(substr + 4) != '\0')) { + checked_asprintf(&dir, "%s/images/install.img", dir); + } + + loaderData->invalidRepoParam = 1; + + url = setupIsoImages(selpart, dir, location); + if (!url) { + newtWinMessage(_("Error"), _("OK"), + _("Device %s does not appear to contain " + "an installation image."), selpart, + getProductName()); + continue; + } + + done = 1; + } + + free(dir); + + return url; } -void setKickstartHD(struct loaderData_s * loaderData, int argc, - char ** argv) { - char *p; - gchar *biospart = NULL, *partition = NULL, *dir = NULL; - GOptionContext *optCon = g_option_context_new(NULL); - GError *optErr = NULL; - GOptionEntry ksHDOptions[] = { - { "biospart", 0, 0, G_OPTION_ARG_STRING, &biospart, NULL, NULL }, - { "partition", 0, 0, G_OPTION_ARG_STRING, &partition, NULL, NULL }, - { "dir", 0, 0, G_OPTION_ARG_STRING, &dir, NULL, NULL }, - { NULL }, - }; - - logMessage(INFO, "kickstartFromHD"); - - g_option_context_set_help_enabled(optCon, FALSE); - g_option_context_add_main_entries(optCon, ksHDOptions, NULL); - - if (!g_option_context_parse(optCon, &argc, &argv, &optErr)) { - startNewt(); - newtWinMessage(_("Kickstart Error"), _("OK"), - _("Bad argument to HD kickstart method " - "command: %s"), optErr->message); - g_error_free(optErr); - g_option_context_free(optCon); - return; - } - - g_option_context_free(optCon); - - if (biospart) { - char * dev; - - p = strchr(biospart,'p'); - if(!p){ - logMessage(ERROR, "Bad argument for --biospart"); - return; - } - *p = '\0'; - dev = getBiosDisk(biospart); - if (dev == NULL) { - logMessage(ERROR, "Unable to location BIOS partition %s", biospart); - return; - } - partition = malloc(strlen(dev) + strlen(p + 1) + 2); - sprintf(partition, "%s%s", dev, p + 1); - } - - loaderData->method = METHOD_HD; - loaderData->stage2Data = calloc(sizeof(struct hdInstallData *), 1); - if (partition) - ((struct hdInstallData *)loaderData->stage2Data)->partition = partition; - if (dir) - ((struct hdInstallData *)loaderData->stage2Data)->directory = dir; - - logMessage(INFO, "results of hd ks, partition is %s, dir is %s", partition, - dir); +void setKickstartHD(struct loaderData_s *loaderData, int argc, char **argv) +{ + char *p; + gchar *biospart = NULL, *partition = NULL, *dir = NULL; + GOptionContext *optCon = g_option_context_new(NULL); + GError *optErr = NULL; + GOptionEntry ksHDOptions[] = { + {"biospart", 0, 0, G_OPTION_ARG_STRING, &biospart, NULL, NULL}, + {"partition", 0, 0, G_OPTION_ARG_STRING, &partition, NULL, + NULL}, + {"dir", 0, 0, G_OPTION_ARG_STRING, &dir, NULL, NULL}, + {NULL}, + }; + + logMessage(INFO, "kickstartFromHD"); + + g_option_context_set_help_enabled(optCon, FALSE); + g_option_context_add_main_entries(optCon, ksHDOptions, NULL); + + if (!g_option_context_parse(optCon, &argc, &argv, &optErr)) { + startNewt(); + newtWinMessage(_("Kickstart Error"), _("OK"), + _("Bad argument to HD kickstart method " + "command: %s"), optErr->message); + g_error_free(optErr); + g_option_context_free(optCon); + return; + } + + g_option_context_free(optCon); + + if (biospart) { + char *dev; + + p = strchr(biospart, 'p'); + if (!p) { + logMessage(ERROR, "Bad argument for --biospart"); + return; + } + *p = '\0'; + dev = getBiosDisk(biospart); + if (dev == NULL) { + logMessage(ERROR, + "Unable to location BIOS partition %s", + biospart); + return; + } + partition = malloc(strlen(dev) + strlen(p + 1) + 2); + sprintf(partition, "%s%s", dev, p + 1); + } + + loaderData->method = METHOD_HD; + loaderData->stage2Data = calloc(sizeof(struct hdInstallData *), 1); + if (partition) + ((struct hdInstallData *)loaderData->stage2Data)->partition = + partition; + if (dir) + ((struct hdInstallData *)loaderData->stage2Data)->directory = + dir; + + logMessage(INFO, "results of hd ks, partition is %s, dir is %s", + partition, dir); } -int kickstartFromHD(char *kssrc) { - int rc; - char *p, *np = NULL, *tmpstr, *ksdev, *kspath; - - logMessage(INFO, "getting kickstart file from harddrive"); - - /* format is hd:[device]:/path/to/ks.cfg */ - /* split up pieces */ - tmpstr = strdup(kssrc); - p = strchr(tmpstr, ':'); - if (p) - np = strchr(p+1, ':'); - - /* no second colon, assume its the old format of */ - /* hd:[device]/path/to/ks.cfg */ - /* this format is bad however because some devices have '/' in them! */ - if (!np) - np = strchr(p+1, '/'); - - if (!p || !np) { - logMessage(WARNING, "Format of command line is ks=hd:[device]:/path/to/ks.cfg"); - free(tmpstr); - return 1; - } - - *np = '\0'; - ksdev = p+1; - kspath = np+1; - - logMessage(INFO, "Loading ks from device %s on path %s", ksdev, kspath); - if ((rc=getKickstartFromBlockDevice(ksdev, kspath))) { - if (rc == 3) { - startNewt(); - newtWinMessage(_("Error"), _("OK"), - _("Cannot find kickstart file on hard drive.")); - } - return 1; - } - - return 0; +int kickstartFromHD(char *kssrc) +{ + int rc; + char *p, *np = NULL, *tmpstr, *ksdev, *kspath; + + logMessage(INFO, "getting kickstart file from harddrive"); + + /* format is hd:[device]:/path/to/ks.cfg */ + /* split up pieces */ + tmpstr = strdup(kssrc); + p = strchr(tmpstr, ':'); + if (p) + np = strchr(p + 1, ':'); + + /* no second colon, assume its the old format of */ + /* hd:[device]/path/to/ks.cfg */ + /* this format is bad however because some devices have '/' in them! */ + if (!np) + np = strchr(p + 1, '/'); + + if (!p || !np) { + logMessage(WARNING, + "Format of command line is ks=hd:[device]:/path/to/ks.cfg"); + free(tmpstr); + return 1; + } + + *np = '\0'; + ksdev = p + 1; + kspath = np + 1; + + logMessage(INFO, "Loading ks from device %s on path %s", ksdev, kspath); + if ((rc = getKickstartFromBlockDevice(ksdev, kspath))) { + if (rc == 3) { + startNewt(); + newtWinMessage(_("Error"), _("OK"), + _ + ("Cannot find kickstart file on hard drive.")); + } + return 1; + } + + return 0; } - -int kickstartFromBD(char *kssrc) { - int rc; - char *p, *np = NULL, *r = NULL, *tmpstr, *ksdev, *kspath, *biosksdev; - - logMessage(INFO, "getting kickstart file from biosdrive"); - - /* format is bd:[device]:/path/to/ks.cfg */ - /* split of pieces */ - tmpstr = strdup(kssrc); - p = strchr(tmpstr, ':'); - if (p) - np = strchr(p+1, ':'); - - if (!p || !np) { - logMessage(WARNING, "Format of command line is ks=bd:device:/path/to/ks.cfg"); - free(tmpstr); - return 1; - } - - *np = '\0'; - kspath = np+1; - - r = strchr(p+1,'p'); - if(!r){ - logMessage(INFO, "Format of biosdisk is 80p1"); - free(tmpstr); - return 1; - } - - *r = '\0'; - biosksdev = getBiosDisk((p + 1)); - if(!biosksdev){ - startNewt(); - newtWinMessage(_("Error"), _("OK"), - _("Cannot find hard drive for BIOS disk %s"), - p + 1); - return 1; - } - - - ksdev = malloc(strlen(biosksdev) + 3); - sprintf(ksdev, "%s%s", biosksdev, r + 1); - logMessage(INFO, "Loading ks from device %s on path %s", ksdev, kspath); - if ((rc=getKickstartFromBlockDevice(ksdev, kspath))) { - if (rc == 3) { - startNewt(); - newtWinMessage(_("Error"), _("OK"), - _("Cannot find kickstart file on hard drive.")); - } - return 1; - } - - return 0; +int kickstartFromBD(char *kssrc) +{ + int rc; + char *p, *np = NULL, *r = NULL, *tmpstr, *ksdev, *kspath, *biosksdev; + + logMessage(INFO, "getting kickstart file from biosdrive"); + + /* format is bd:[device]:/path/to/ks.cfg */ + /* split of pieces */ + tmpstr = strdup(kssrc); + p = strchr(tmpstr, ':'); + if (p) + np = strchr(p + 1, ':'); + + if (!p || !np) { + logMessage(WARNING, + "Format of command line is ks=bd:device:/path/to/ks.cfg"); + free(tmpstr); + return 1; + } + + *np = '\0'; + kspath = np + 1; + + r = strchr(p + 1, 'p'); + if (!r) { + logMessage(INFO, "Format of biosdisk is 80p1"); + free(tmpstr); + return 1; + } + + *r = '\0'; + biosksdev = getBiosDisk((p + 1)); + if (!biosksdev) { + startNewt(); + newtWinMessage(_("Error"), _("OK"), + _("Cannot find hard drive for BIOS disk %s"), + p + 1); + return 1; + } + + ksdev = malloc(strlen(biosksdev) + 3); + sprintf(ksdev, "%s%s", biosksdev, r + 1); + logMessage(INFO, "Loading ks from device %s on path %s", ksdev, kspath); + if ((rc = getKickstartFromBlockDevice(ksdev, kspath))) { + if (rc == 3) { + startNewt(); + newtWinMessage(_("Error"), _("OK"), + _ + ("Cannot find kickstart file on hard drive.")); + } + return 1; + } + + return 0; } /* vim:set sw=8 noet */ diff --git a/loader/hdinstall.h b/loader/hdinstall.h index 47229e9..5e85d2c 100644 --- a/loader/hdinstall.h +++ b/loader/hdinstall.h @@ -23,15 +23,13 @@ #include "method.h" struct hdInstallData { - char * partition; - char * directory; + char *partition; + char *directory; }; - -void setKickstartHD(struct loaderData_s * loaderData, int argc, - char ** argv); -char * mountHardDrive(struct installMethod * method, - char * location, struct loaderData_s * loaderData); +void setKickstartHD(struct loaderData_s *loaderData, int argc, char **argv); +char *mountHardDrive(struct installMethod *method, + char *location, struct loaderData_s *loaderData); int kickstartFromHD(char *kssrc); int kickstartFromBD(char *kssrc); diff --git a/loader/ibft.c b/loader/ibft.c index afb3707..dd2ddf8 100644 --- a/loader/ibft.c +++ b/loader/ibft.c @@ -21,7 +21,6 @@ 02139, USA. */ - #include <stddef.h> #include <stdio.h> #include <string.h> @@ -35,38 +34,38 @@ int ibft_initialized = 0; int ibft_init(void) { - int ret; + int ret; - memset(&ibft_context, 0, sizeof(ibft_context)); + memset(&ibft_context, 0, sizeof(ibft_context)); - ret = libiscsi_get_firmware_network_config(&ibft_context); + ret = libiscsi_get_firmware_network_config(&ibft_context); - /* ret == 0 -> OK */ - ibft_ispresent = !ret; - ibft_initialized = 1; + /* ret == 0 -> OK */ + ibft_ispresent = !ret; + ibft_initialized = 1; - return ibft_initialized; + return ibft_initialized; } /* Is iBFT available on this system */ int ibft_present() { - if(!ibft_initialized) - ibft_init(); + if (!ibft_initialized) + ibft_init(); - return ibft_ispresent; + return ibft_ispresent; } /* Is the iBFT network configured to use DHCP */ int ibft_iface_dhcp() { - if(!ibft_initialized) - ibft_init(); + if (!ibft_initialized) + ibft_init(); - if(!ibft_present()) - return -1; + if (!ibft_present()) + return -1; - return ibft_context.dhcp; + return ibft_context.dhcp; } #define ibft_iface_charfunc(name, var) char* ibft_iface_##name()\ @@ -83,25 +82,23 @@ int ibft_iface_dhcp() return ibft_context.var;\ } - /* Get the iBFT MAC address */ ibft_iface_charfunc(mac, mac_address) /* Get the iBFT ip address */ -ibft_iface_charfunc(ip, ip_address) + ibft_iface_charfunc(ip, ip_address) /* Get the iBFT subnet mask */ -ibft_iface_charfunc(mask, netmask) + ibft_iface_charfunc(mask, netmask) /* Get the iBFT gateway */ -ibft_iface_charfunc(gw, gateway) + ibft_iface_charfunc(gw, gateway) /* Get the iBFT iface name */ -ibft_iface_charfunc(iface, iface_name) + ibft_iface_charfunc(iface, iface_name) /* Get the iBFT dns servers */ -ibft_iface_charfunc(dns1, primary_dns) -ibft_iface_charfunc(dns2, secondary_dns) - + ibft_iface_charfunc(dns1, primary_dns) + ibft_iface_charfunc(dns2, secondary_dns) /* vim:set sw=8 noet */ diff --git a/loader/ibft.h b/loader/ibft.h index 118f3a4..586dd4c 100644 --- a/loader/ibft.h +++ b/loader/ibft.h @@ -21,24 +21,21 @@ 02139, USA. */ - #ifndef __IBFT_H__ #define __IBFT_H__ - int ibft_init(); int ibft_present(); int ibft_iface_dhcp(); -char* ibft_iface_mac(); -char* ibft_iface_ip(); -char* ibft_iface_mask(); -char* ibft_iface_gw(); -char* ibft_iface_iface(); -char* ibft_iface_dns1(); -char* ibft_iface_dns2(); - +char *ibft_iface_mac(); +char *ibft_iface_ip(); +char *ibft_iface_mask(); +char *ibft_iface_gw(); +char *ibft_iface_iface(); +char *ibft_iface_dns1(); +char *ibft_iface_dns2(); #endif diff --git a/loader/init.c b/loader/init.c index 6b07ab8..ce78087 100644 --- a/loader/init.c +++ b/loader/init.c @@ -25,7 +25,7 @@ #include "minilibc.h" #ifndef SOCK_STREAM # define SOCK_STREAM 1 -#endif +#endif #else #include <ctype.h> #include <dirent.h> @@ -79,26 +79,26 @@ #define ENV_MALLOC_CHECK 7 #define ENV_MALLOC_PERTURB 8 -char * env[] = { - "PATH=/usr/bin:/bin:/sbin:/usr/sbin:/mnt/sysimage/bin:" - "/mnt/sysimage/usr/bin:/mnt/sysimage/usr/sbin:/mnt/sysimage/sbin:" - "/mnt/sysimage/usr/X11R6/bin", +char *env[] = { + "PATH=/usr/bin:/bin:/sbin:/usr/sbin:/mnt/sysimage/bin:" + "/mnt/sysimage/usr/bin:/mnt/sysimage/usr/sbin:/mnt/sysimage/sbin:" + "/mnt/sysimage/usr/X11R6/bin", - /* we set a nicer ld library path specifically for bash -- a full - one makes anaconda unhappy */ + /* we set a nicer ld library path specifically for bash -- a full + one makes anaconda unhappy */ #if defined(__x86_64__) || defined(__s390x__) || defined(__ppc64__) - "LD_LIBRARY_PATH=/lib64:/usr/lib64:/lib:/usr/lib", + "LD_LIBRARY_PATH=/lib64:/usr/lib64:/lib:/usr/lib", #else - "LD_LIBRARY_PATH=/lib:/usr/lib", + "LD_LIBRARY_PATH=/lib:/usr/lib", #endif - "HOME=/", - "TERM=linux", - "DEBUG=", - "TERMINFO=/etc/linux-terminfo", - "PYTHONPATH=/tmp/updates", - "MALLOC_CHECK_=2", - "MALLOC_PERTURB_=204", - NULL + "HOME=/", + "TERM=linux", + "DEBUG=", + "TERMINFO=/etc/linux-terminfo", + "PYTHONPATH=/tmp/updates", + "MALLOC_CHECK_=2", + "MALLOC_PERTURB_=204", + NULL }; /* @@ -120,751 +120,790 @@ static int expected_exit = 0; static void doExit(int) __attribute__ ((noreturn)); static void doExit(int result) { - expected_exit = 1; - exit(result); + expected_exit = 1; + exit(result); } -static void printstr(char * string) { - int ret; - ret = write(1, string, strlen(string)); +static void printstr(char *string) +{ + int ret; + ret = write(1, string, strlen(string)); } -static void fatal_error(int usePerror) { - printf("failed.\n"); +static void fatal_error(int usePerror) +{ + printf("failed.\n"); - printf("\nI can't recover from this.\n"); + printf("\nI can't recover from this.\n"); #if !defined(__s390__) && !defined(__s390x__) - while (1) ; + while (1) ; #endif } -static int logChunk(int len, char *inbuf, char *outbuf) { - int inctr, outctr; - - for (inctr = 0, outctr = 0; inctr < len; inctr++) { - /* If the character is a NULL that's immediately followed by a open - * bracket, we've found the beginning of a new kernel message. Put in - * a line separator. - */ - if (inbuf[inctr] == '\0' && inctr+1 < len && inbuf[inctr+1] == '<') { - outbuf[outctr] = '\n'; - outctr++; - } - - /* Or, if we see a NULL right before the end of the chunk, that's also - * a good place to add a separator. - */ - else if (inbuf[inctr] == '\0' && inctr+1 == len) { - outbuf[outctr] = '\n'; - outctr++; - } - - /* Otherwise, simply output the character as long as it's not NULL. */ - else if (inbuf[inctr] != '\0') { - outbuf[outctr] = inbuf[inctr]; - outctr++; - } - } - - return outctr; +static int logChunk(int len, char *inbuf, char *outbuf) +{ + int inctr, outctr; + + for (inctr = 0, outctr = 0; inctr < len; inctr++) { + /* If the character is a NULL that's immediately followed by a open + * bracket, we've found the beginning of a new kernel message. Put in + * a line separator. + */ + if (inbuf[inctr] == '\0' && inctr + 1 < len + && inbuf[inctr + 1] == '<') { + outbuf[outctr] = '\n'; + outctr++; + } + + /* Or, if we see a NULL right before the end of the chunk, that's also + * a good place to add a separator. + */ + else if (inbuf[inctr] == '\0' && inctr + 1 == len) { + outbuf[outctr] = '\n'; + outctr++; + } + + /* Otherwise, simply output the character as long as it's not NULL. */ + else if (inbuf[inctr] != '\0') { + outbuf[outctr] = inbuf[inctr]; + outctr++; + } + } + + return outctr; } -static void doklog(char * fn) { - fd_set readset, unixs; - int in, out, i; - int log; - socklen_t s; - int sock = -1; - struct sockaddr_un sockaddr; - char inbuf[1024], outbuf[1024]; - int readfd; - int ret; - - in = open("/proc/kmsg", O_RDONLY,0); - if (in < 0) { - /* FIXME: was perror */ - printstr("open /proc/kmsg"); - return; - } - - out = open(fn, O_WRONLY, 0); - if (out < 0) - printf("couldn't open %s for syslog -- still using /tmp/syslog\n", fn); - - log = open("/tmp/syslog", O_WRONLY | O_CREAT, 0644); - if (log < 0) { - /* FIXME: was perror */ - printstr("error opening /tmp/syslog"); - sleep(5); - - close(in); - return; - } - - /* if we get this far, we should be in good shape */ - - if (fork()) { - /* parent */ - close(in); - close(out); - close(log); - return; - } - close(0); - close(1); - close(2); - - dup2(1, log); +static void doklog(char *fn) +{ + fd_set readset, unixs; + int in, out, i; + int log; + socklen_t s; + int sock = -1; + struct sockaddr_un sockaddr; + char inbuf[1024], outbuf[1024]; + int readfd; + int ret; + + in = open("/proc/kmsg", O_RDONLY, 0); + if (in < 0) { + /* FIXME: was perror */ + printstr("open /proc/kmsg"); + return; + } + + out = open(fn, O_WRONLY, 0); + if (out < 0) + printf + ("couldn't open %s for syslog -- still using /tmp/syslog\n", + fn); + + log = open("/tmp/syslog", O_WRONLY | O_CREAT, 0644); + if (log < 0) { + /* FIXME: was perror */ + printstr("error opening /tmp/syslog"); + sleep(5); + + close(in); + return; + } + + /* if we get this far, we should be in good shape */ + + if (fork()) { + /* parent */ + close(in); + close(out); + close(log); + return; + } + close(0); + close(1); + close(2); + + dup2(1, log); #if defined(USE_LOGDEV) - /* now open the syslog socket */ - sockaddr.sun_family = AF_UNIX; - strcpy(sockaddr.sun_path, "/dev/log"); - sock = socket(AF_UNIX, SOCK_STREAM, 0); - if (sock < 0) { - printf("error creating socket: %d\n", errno); - sleep(5); - } - printstr("got socket\n"); - if (bind(sock, (struct sockaddr *) &sockaddr, sizeof(sockaddr.sun_family) + - strlen(sockaddr.sun_path))) { - printf("bind error: %d\n", errno); - sleep(5); - } - printstr("bound socket\n"); - chmod("/dev/log", 0666); - if (listen(sock, 5)) { - printf("listen error: %d\n", errno); - sleep(5); - } + /* now open the syslog socket */ + sockaddr.sun_family = AF_UNIX; + strcpy(sockaddr.sun_path, "/dev/log"); + sock = socket(AF_UNIX, SOCK_STREAM, 0); + if (sock < 0) { + printf("error creating socket: %d\n", errno); + sleep(5); + } + printstr("got socket\n"); + if (bind + (sock, (struct sockaddr *)&sockaddr, + sizeof(sockaddr.sun_family) + strlen(sockaddr.sun_path))) { + printf("bind error: %d\n", errno); + sleep(5); + } + printstr("bound socket\n"); + chmod("/dev/log", 0666); + if (listen(sock, 5)) { + printf("listen error: %d\n", errno); + sleep(5); + } #endif - syslog(8, NULL, 1); - - FD_ZERO(&unixs); - while (1) { - memcpy(&readset, &unixs, sizeof(unixs)); - - if (sock >= 0) - FD_SET(sock, &readset); - - FD_SET(in, &readset); - - i = select(20, &readset, NULL, NULL, NULL); - if (i <= 0) continue; - - if (FD_ISSET(in, &readset)) { - i = read(in, inbuf, sizeof(inbuf)); - if (i > 0) { - int loggedLen = logChunk(i, inbuf, outbuf); - - if (out >= 0) - ret = write(out, outbuf, loggedLen); - ret = write(log, outbuf, loggedLen); - } - } - - for (readfd = 0; readfd < 20; ++readfd) { - if (FD_ISSET(readfd, &readset) && FD_ISSET(readfd, &unixs)) { - i = read(readfd, inbuf, sizeof(inbuf)); - if (i > 0) { - int loggedLen = logChunk(i, inbuf, outbuf); - - if (out >= 0) - ret = write(out, outbuf, loggedLen); - - ret = write(log, outbuf, loggedLen); - } else if (i == 0) { - /* socket closed */ - close(readfd); - FD_CLR(readfd, &unixs); - } - } - } - - if (sock >= 0 && FD_ISSET(sock, &readset)) { - s = sizeof(sockaddr); - readfd = accept(sock, (struct sockaddr *) &sockaddr, &s); - if (readfd < 0) { - if (out >= 0) - ret = write(out, "error in accept\n", 16); - ret = write(log, "error in accept\n", 16); - close(sock); - sock = -1; - } else { - FD_SET(readfd, &unixs); - } - } - } + syslog(8, NULL, 1); + + FD_ZERO(&unixs); + while (1) { + memcpy(&readset, &unixs, sizeof(unixs)); + + if (sock >= 0) + FD_SET(sock, &readset); + + FD_SET(in, &readset); + + i = select(20, &readset, NULL, NULL, NULL); + if (i <= 0) + continue; + + if (FD_ISSET(in, &readset)) { + i = read(in, inbuf, sizeof(inbuf)); + if (i > 0) { + int loggedLen = logChunk(i, inbuf, outbuf); + + if (out >= 0) + ret = write(out, outbuf, loggedLen); + ret = write(log, outbuf, loggedLen); + } + } + + for (readfd = 0; readfd < 20; ++readfd) { + if (FD_ISSET(readfd, &readset) + && FD_ISSET(readfd, &unixs)) { + i = read(readfd, inbuf, sizeof(inbuf)); + if (i > 0) { + int loggedLen = + logChunk(i, inbuf, outbuf); + + if (out >= 0) + ret = + write(out, outbuf, + loggedLen); + + ret = write(log, outbuf, loggedLen); + } else if (i == 0) { + /* socket closed */ + close(readfd); + FD_CLR(readfd, &unixs); + } + } + } + + if (sock >= 0 && FD_ISSET(sock, &readset)) { + s = sizeof(sockaddr); + readfd = accept(sock, (struct sockaddr *)&sockaddr, &s); + if (readfd < 0) { + if (out >= 0) + ret = + write(out, "error in accept\n", 16); + ret = write(log, "error in accept\n", 16); + close(sock); + sock = -1; + } else { + FD_SET(readfd, &unixs); + } + } + } } -static int setupTerminal(int fd) { - struct winsize winsize; - int fdn, len; - char buf[65535]; - - if (ioctl(fd, TIOCGWINSZ, &winsize)) { - printf("failed to get winsize"); - fatal_error(1); - } - - winsize.ws_row = 24; - winsize.ws_col = 80; - - if (ioctl(fd, TIOCSWINSZ, &winsize)) { - printf("failed to set winsize"); - fatal_error(1); - } - - if (!strcmp(ttyname(fd), "/dev/hvc0")) { - /* using an HMC on a POWER system, use vt320 */ - env[ENV_TERM] = "TERM=vt320"; - } else { - /* use the no-advanced-video vt100 definition */ - env[ENV_TERM] = "TERM=vt100-nav"; - - /* unless the user specifies that they want utf8 */ - if ((fdn = open("/proc/cmdline", O_RDONLY, 0)) != -1) { - len = read(fdn, buf, sizeof(buf) - 1); - close(fdn); - if (len > 0 && strstr(buf, "utf8")) - env[ENV_TERM] = "TERM=vt100"; - } - } - - return 0; +static int setupTerminal(int fd) +{ + struct winsize winsize; + int fdn, len; + char buf[65535]; + + if (ioctl(fd, TIOCGWINSZ, &winsize)) { + printf("failed to get winsize"); + fatal_error(1); + } + + winsize.ws_row = 24; + winsize.ws_col = 80; + + if (ioctl(fd, TIOCSWINSZ, &winsize)) { + printf("failed to set winsize"); + fatal_error(1); + } + + if (!strcmp(ttyname(fd), "/dev/hvc0")) { + /* using an HMC on a POWER system, use vt320 */ + env[ENV_TERM] = "TERM=vt320"; + } else { + /* use the no-advanced-video vt100 definition */ + env[ENV_TERM] = "TERM=vt100-nav"; + + /* unless the user specifies that they want utf8 */ + if ((fdn = open("/proc/cmdline", O_RDONLY, 0)) != -1) { + len = read(fdn, buf, sizeof(buf) - 1); + close(fdn); + if (len > 0 && strstr(buf, "utf8")) + env[ENV_TERM] = "TERM=vt100"; + } + } + + return 0; } + #if defined(__sparc__) -static int termcmp(struct termios *a, struct termios *b) { - if (a->c_iflag != b->c_iflag || a->c_oflag != b->c_oflag || - a->c_cflag != b->c_cflag || a->c_lflag != b->c_lflag) - return 1; - return memcmp(a->c_cc, b->c_cc, sizeof(a->c_cc)); +static int termcmp(struct termios *a, struct termios *b) +{ + if (a->c_iflag != b->c_iflag || a->c_oflag != b->c_oflag || + a->c_cflag != b->c_cflag || a->c_lflag != b->c_lflag) + return 1; + return memcmp(a->c_cc, b->c_cc, sizeof(a->c_cc)); } #endif #if !defined(__s390__) && !defined(__s390x__) && !defined(__sparc__) -static int termcmp(struct termios *a, struct termios *b) { - if (a->c_iflag != b->c_iflag || a->c_oflag != b->c_oflag || - a->c_cflag != b->c_cflag || a->c_lflag != b->c_lflag || - a->c_ispeed != b->c_ispeed || a->c_ospeed != b->c_ospeed) - return 1; - return memcmp(a->c_cc, b->c_cc, sizeof(a->c_cc)); +static int termcmp(struct termios *a, struct termios *b) +{ + if (a->c_iflag != b->c_iflag || a->c_oflag != b->c_oflag || + a->c_cflag != b->c_cflag || a->c_lflag != b->c_lflag || + a->c_ispeed != b->c_ispeed || a->c_ospeed != b->c_ospeed) + return 1; + return memcmp(a->c_cc, b->c_cc, sizeof(a->c_cc)); } #endif -static void createDevices(void) { - int i; - - /* unset the umask so devices are created with correct perms - and not complemented by the previous umask call */ - - mode_t previous_umask = umask(0); - - for (i = 0; devnodes[i].devname != NULL; i++) { - char devname[64]; - int type = -1; - - snprintf(devname, 63, "/dev/%s", devnodes[i].devname); - switch (devnodes[i].type) { - case DIRTYPE: - if (mkdir(devname, devnodes[i].perms) < 0) { - fprintf(stderr, "Unable to create directory %s: %m\n", - devname); - } - break; - case CHARDEV: - type = S_IFCHR; - break; - case BLOCKDEV: - type = S_IFBLK; - break; - } - if (type == -1) continue; - - if (mknod(devname, type | devnodes[i].perms, - makedev(devnodes[i].major, devnodes[i].minor)) < 0) - fprintf(stderr, "Unable to create device %s: %m\n", devname); - } - - /* Hurray for hacks, this stops /lib/udev/rules.d/65-md-incremental.rules - from medling with mdraid sets. */ - i = creat("/dev/.in_sysinit", 0644); - close(i); - - /* Restore umask for minimal side affects */ - umask(previous_umask); +static void createDevices(void) +{ + int i; + + /* unset the umask so devices are created with correct perms + and not complemented by the previous umask call */ + + mode_t previous_umask = umask(0); + + for (i = 0; devnodes[i].devname != NULL; i++) { + char devname[64]; + int type = -1; + + snprintf(devname, 63, "/dev/%s", devnodes[i].devname); + switch (devnodes[i].type) { + case DIRTYPE: + if (mkdir(devname, devnodes[i].perms) < 0) { + fprintf(stderr, + "Unable to create directory %s: %m\n", + devname); + } + break; + case CHARDEV: + type = S_IFCHR; + break; + case BLOCKDEV: + type = S_IFBLK; + break; + } + if (type == -1) + continue; + + if (mknod(devname, type | devnodes[i].perms, + makedev(devnodes[i].major, devnodes[i].minor)) < 0) + fprintf(stderr, "Unable to create device %s: %m\n", + devname); + } + + /* Hurray for hacks, this stops /lib/udev/rules.d/65-md-incremental.rules + from medling with mdraid sets. */ + i = creat("/dev/.in_sysinit", 0644); + close(i); + + /* Restore umask for minimal side affects */ + umask(previous_umask); } -static void termReset(void) { - /* change to tty1 */ - ioctl(0, VT_ACTIVATE, 1); - /* reset terminal */ - tcsetattr(0, TCSANOW, &ts); - /* Shift in, default color, move down 100 lines */ - /* ^O ^[[0m ^[[100E */ - printf("\017\033[0m\033[100E\n"); +static void termReset(void) +{ + /* change to tty1 */ + ioctl(0, VT_ACTIVATE, 1); + /* reset terminal */ + tcsetattr(0, TCSANOW, &ts); + /* Shift in, default color, move down 100 lines */ + /* ^O ^[[0m ^[[100E */ + printf("\017\033[0m\033[100E\n"); } /* reboot handler */ -static void sigintHandler(int signum) { - termReset(); +static void sigintHandler(int signum) +{ + termReset(); shouldReboot = 1; - shutDown(getKillPolicy(), REBOOT); + shutDown(getKillPolicy(), REBOOT); } /* halt handler */ -static void sigUsr1Handler(int signum) { - termReset(); - shutDown(getKillPolicy(), HALT); +static void sigUsr1Handler(int signum) +{ + termReset(); + shutDown(getKillPolicy(), HALT); } /* poweroff handler */ -static void sigUsr2Handler(int signum) { - termReset(); - shutDown(getKillPolicy(), POWEROFF); +static void sigUsr2Handler(int signum) +{ + termReset(); + shutDown(getKillPolicy(), POWEROFF); } -static int getKillPolicy(void) { - int fd; - int len; - char buf[1024]; - - /* look through /proc/cmdline for special options */ - if ((fd = open("/proc/cmdline", O_RDONLY,0)) > 0) { - len = read(fd, buf, sizeof(buf) - 1); - close(fd); - if ((len > 0) && strstr(buf, "nokill")) - return 0; - } - return 1; +static int getKillPolicy(void) +{ + int fd; + int len; + char buf[1024]; + + /* look through /proc/cmdline for special options */ + if ((fd = open("/proc/cmdline", O_RDONLY, 0)) > 0) { + len = read(fd, buf, sizeof(buf) - 1); + close(fd); + if ((len > 0) && strstr(buf, "nokill")) + return 0; + } + return 1; } -static int getInitPid(void) { - int fd = 0, pid = -1, ret; - char * buf = calloc(1, 10); - - fd = open("/var/run/init.pid", O_RDONLY); - if (fd < 0) { - fprintf(stderr, "Unable to find pid of init!!!\n"); - return -1; - } - ret = read(fd, buf, 9); - close(fd); - ret = sscanf(buf, "%d", &pid); - return pid; +static int getInitPid(void) +{ + int fd = 0, pid = -1, ret; + char *buf = calloc(1, 10); + + fd = open("/var/run/init.pid", O_RDONLY); + if (fd < 0) { + fprintf(stderr, "Unable to find pid of init!!!\n"); + return -1; + } + ret = read(fd, buf, 9); + close(fd); + ret = sscanf(buf, "%d", &pid); + return pid; } -static void copyErrorFn (char *msg) { - printf(msg); +static void copyErrorFn(char *msg) +{ + printf(msg); } -void initSegvHandler(int signum) { - void *array[30]; - size_t i; - const char const * const errmsgs[] = { - "init received SIG", - "! Backtrace:\n", - "init exited unexpectedly! Backtrace:\n", - }; - - /* XXX This should really be in a glibc header somewhere... */ - extern const char *const sys_sigabbrev[NSIG]; - - signal(signum, SIG_DFL); /* back to default */ - - if (signum == 0) { - i = write(STDERR_FILENO, errmsgs[2], strlen(errmsgs[2])); - } else { - i = write(STDERR_FILENO, errmsgs[0], strlen(errmsgs[0])); - i = write(STDERR_FILENO, sys_sigabbrev[signum], - strlen(sys_sigabbrev[signum])); - i = write(STDERR_FILENO, errmsgs[1], strlen(errmsgs[1])); - } - - i = backtrace (array, 30); - backtrace_symbols_fd(array, i, STDERR_FILENO); - _exit(1); +void initSegvHandler(int signum) +{ + void *array[30]; + size_t i; + const char const *const errmsgs[] = { + "init received SIG", + "! Backtrace:\n", + "init exited unexpectedly! Backtrace:\n", + }; + + /* XXX This should really be in a glibc header somewhere... */ + extern const char *const sys_sigabbrev[NSIG]; + + signal(signum, SIG_DFL); /* back to default */ + + if (signum == 0) { + i = write(STDERR_FILENO, errmsgs[2], strlen(errmsgs[2])); + } else { + i = write(STDERR_FILENO, errmsgs[0], strlen(errmsgs[0])); + i = write(STDERR_FILENO, sys_sigabbrev[signum], + strlen(sys_sigabbrev[signum])); + i = write(STDERR_FILENO, errmsgs[1], strlen(errmsgs[1])); + } + + i = backtrace(array, 30); + backtrace_symbols_fd(array, i, STDERR_FILENO); + _exit(1); } void initExitHandler(void) { - if (expected_exit) - return; + if (expected_exit) + return; - initSegvHandler(0); + initSegvHandler(0); } static void setupBacktrace(void) { - void *array; + void *array; - signal(SIGSEGV, initSegvHandler); - signal(SIGABRT, initSegvHandler); - atexit(initExitHandler); + signal(SIGSEGV, initSegvHandler); + signal(SIGABRT, initSegvHandler); + atexit(initExitHandler); - /* Turns out, there's an initializer at the top of backtrace() that - * (on some arches) calls dlopen(). dlopen(), unsurprisingly, calls - * malloc(). So, call backtrace() early in signal handler setup so - * we can later safely call it from the signal handler itself. */ - backtrace(&array, 1); + /* Turns out, there's an initializer at the top of backtrace() that + * (on some arches) calls dlopen(). dlopen(), unsurprisingly, calls + * malloc(). So, call backtrace() early in signal handler setup so + * we can later safely call it from the signal handler itself. */ + backtrace(&array, 1); } -int main(int argc, char **argv) { - pid_t installpid, childpid; - int waitStatus; - int fd = -1; - int doReboot = 0; - int doShutdown =0; - int isSerial = 0; - char * console = NULL; - int doKill = 1; - char * argvc[15]; - char ** argvp = argvc; - char twelve = 12; - struct serial_struct si; - int i, disable_keys; - - if (!strncmp(basename(argv[0]), "poweroff", 8)) { - printf("Running poweroff...\n"); - fd = getInitPid(); - if (fd > 0) - kill(fd, SIGUSR2); - doExit(0); - } else if (!strncmp(basename(argv[0]), "halt", 4)) { - printf("Running halt...\n"); - fd = getInitPid(); - if (fd > 0) - kill(fd, SIGUSR1); - doExit(0); - } else if (!strncmp(basename(argv[0]), "reboot", 6)) { - printf("Running reboot...\n"); - fd = getInitPid(); - if (fd > 0) - kill(fd, SIGINT); - doExit(0); - } - - /* turn off screen blanking */ - printstr("\033[9;0]"); - printstr("\033[8]"); - - umask(022); - - /* set up signal handler */ - setupBacktrace(); - - printstr("\nGreetings.\n"); - - printf("anaconda installer init version %s starting\n", VERSION); - - printf("mounting /proc filesystem... "); - if (mount("/proc", "/proc", "proc", 0, NULL)) - fatal_error(1); - printf("done\n"); - - printf("creating /dev filesystem... "); - if (mount("/dev", "/dev", "tmpfs", 0, NULL)) - fatal_error(1); - createDevices(); - printf("done\n"); - printf("starting udev..."); - if ((childpid = fork()) == 0) { - execl("/sbin/udevd", "/sbin/udevd", "--daemon", NULL); - exit(1); - } - - /* wait at least until the udevd process that we forked exits */ - do { - pid_t retpid; - int waitstatus; - - retpid = waitpid(childpid, &waitstatus, 0); - if (retpid == -1) { - if (errno == EINTR) - continue; - /* if the child exited before we called waitpid, we can get - * ECHILD without anything really being wrong; we just lost - * the race.*/ - if (errno == ECHILD) - break; - printf("init: error waiting on udevd: %m\n"); - exit(1); - } else if (WIFEXITED(waitstatus)) { - break; - } - } while (1); - - if (fork() == 0) { - execl("/sbin/udevadm", "udevadm", "control", "--env=ANACONDA=1", NULL); - exit(1); - } - printf("done\n"); - - printf("mounting /dev/pts (unix98 pty) filesystem... "); - if (mount("/dev/pts", "/dev/pts", "devpts", 0, NULL)) - fatal_error(1); - printf("done\n"); - - printf("mounting /sys filesystem... "); - if (mount("/sys", "/sys", "sysfs", 0, NULL)) - fatal_error(1); - printf("done\n"); - - /* these args are only for testing from commandline */ - for (i = 1; i < argc; i++) { - if (!strcmp (argv[i], "serial")) { - isSerial = 1; - break; - } - } - - doKill = getKillPolicy(); +int main(int argc, char **argv) +{ + pid_t installpid, childpid; + int waitStatus; + int fd = -1; + int doReboot = 0; + int doShutdown = 0; + int isSerial = 0; + char *console = NULL; + int doKill = 1; + char *argvc[15]; + char **argvp = argvc; + char twelve = 12; + struct serial_struct si; + int i, disable_keys; + + if (!strncmp(basename(argv[0]), "poweroff", 8)) { + printf("Running poweroff...\n"); + fd = getInitPid(); + if (fd > 0) + kill(fd, SIGUSR2); + doExit(0); + } else if (!strncmp(basename(argv[0]), "halt", 4)) { + printf("Running halt...\n"); + fd = getInitPid(); + if (fd > 0) + kill(fd, SIGUSR1); + doExit(0); + } else if (!strncmp(basename(argv[0]), "reboot", 6)) { + printf("Running reboot...\n"); + fd = getInitPid(); + if (fd > 0) + kill(fd, SIGINT); + doExit(0); + } + + /* turn off screen blanking */ + printstr("\033[9;0]"); + printstr("\033[8]"); + + umask(022); + + /* set up signal handler */ + setupBacktrace(); + + printstr("\nGreetings.\n"); + + printf("anaconda installer init version %s starting\n", VERSION); + + printf("mounting /proc filesystem... "); + if (mount("/proc", "/proc", "proc", 0, NULL)) + fatal_error(1); + printf("done\n"); + + printf("creating /dev filesystem... "); + if (mount("/dev", "/dev", "tmpfs", 0, NULL)) + fatal_error(1); + createDevices(); + printf("done\n"); + printf("starting udev..."); + if ((childpid = fork()) == 0) { + execl("/sbin/udevd", "/sbin/udevd", "--daemon", NULL); + exit(1); + } + + /* wait at least until the udevd process that we forked exits */ + do { + pid_t retpid; + int waitstatus; + + retpid = waitpid(childpid, &waitstatus, 0); + if (retpid == -1) { + if (errno == EINTR) + continue; + /* if the child exited before we called waitpid, we can get + * ECHILD without anything really being wrong; we just lost + * the race.*/ + if (errno == ECHILD) + break; + printf("init: error waiting on udevd: %m\n"); + exit(1); + } else if (WIFEXITED(waitstatus)) { + break; + } + } while (1); + + if (fork() == 0) { + execl("/sbin/udevadm", "udevadm", "control", "--env=ANACONDA=1", + NULL); + exit(1); + } + printf("done\n"); + + printf("mounting /dev/pts (unix98 pty) filesystem... "); + if (mount("/dev/pts", "/dev/pts", "devpts", 0, NULL)) + fatal_error(1); + printf("done\n"); + + printf("mounting /sys filesystem... "); + if (mount("/sys", "/sys", "sysfs", 0, NULL)) + fatal_error(1); + printf("done\n"); + + /* these args are only for testing from commandline */ + for (i = 1; i < argc; i++) { + if (!strcmp(argv[i], "serial")) { + isSerial = 1; + break; + } + } + + doKill = getKillPolicy(); #if !defined(__s390__) && !defined(__s390x__) - static struct termios orig_cmode; - struct termios cmode, mode; - int cfd; - - cfd = open("/dev/console", O_RDONLY); - tcgetattr(cfd,&orig_cmode); - close(cfd); - - cmode = orig_cmode; - cmode.c_lflag &= (~ECHO); - - cfd = open("/dev/console", O_WRONLY); - tcsetattr(cfd,TCSANOW,&cmode); - close(cfd); - - /* handle weird consoles */ + static struct termios orig_cmode; + struct termios cmode, mode; + int cfd; + + cfd = open("/dev/console", O_RDONLY); + tcgetattr(cfd, &orig_cmode); + close(cfd); + + cmode = orig_cmode; + cmode.c_lflag &= (~ECHO); + + cfd = open("/dev/console", O_WRONLY); + tcsetattr(cfd, TCSANOW, &cmode); + close(cfd); + + /* handle weird consoles */ #if defined(__powerpc__) - char * consoles[] = { "/dev/hvc0", /* hvc for JS20 */ + char *consoles[] = { "/dev/hvc0", /* hvc for JS20 */ - "/dev/hvsi0", "/dev/hvsi1", - "/dev/hvsi2", /* hvsi for POWER5 */ - NULL }; + "/dev/hvsi0", "/dev/hvsi1", + "/dev/hvsi2", /* hvsi for POWER5 */ + NULL + }; #elif defined (__ia64__) - char * consoles[] = { "/dev/ttySG0", "/dev/xvc0", "/dev/hvc0", NULL }; + char *consoles[] = { "/dev/ttySG0", "/dev/xvc0", "/dev/hvc0", NULL }; #elif defined (__i386__) || defined (__x86_64__) - char * consoles[] = { "/dev/xvc0", "/dev/hvc0", NULL }; + char *consoles[] = { "/dev/xvc0", "/dev/hvc0", NULL }; #else - char * consoles[] = { NULL }; + char *consoles[] = { NULL }; #endif - for (i = 0; consoles[i] != NULL; i++) { - if ((fd = open(consoles[i], O_RDWR)) >= 0 && !tcgetattr(fd, &mode) && !termcmp(&cmode, &mode)) { - printf("anaconda installer init version %s using %s as console\n", - VERSION, consoles[i]); - isSerial = 3; - console = strdup(consoles[i]); - break; - } - close(fd); - } - - cfd = open("/dev/console", O_WRONLY); - tcsetattr(cfd,TCSANOW,&orig_cmode); - close(cfd); - - if ((fd < 0) && (ioctl (0, TIOCLINUX, &twelve) < 0)) { - isSerial = 2; - - if (ioctl(0, TIOCGSERIAL, &si) == -1) { - isSerial = 0; - } - } - - if (isSerial && (isSerial != 3)) { - char *device = "/dev/ttyS0"; - - printf("anaconda installer init version %s using a serial console\n", - VERSION); - - if (isSerial == 2) - device = "/dev/console"; - fd = open(device, O_RDWR, 0); - if (fd < 0) - device = "/dev/tts/0"; - - if (fd < 0) { - printf("failed to open %s\n", device); - fatal_error(1); - } - - setupTerminal(fd); - } else if (isSerial == 3) { - setupTerminal(fd); - } else if (fd < 0) { - fd = open("/dev/tty1", O_RDWR, 0); - if (fd < 0) - fd = open("/dev/vc/1", O_RDWR, 0); - - if (fd < 0) { - printf("failed to open /dev/tty1 and /dev/vc/1"); - fatal_error(1); - } - } - - setsid(); - if (ioctl(0, TIOCSCTTY, NULL)) { - printf("could not set new controlling tty\n"); - } - - dup2(fd, 0); - dup2(fd, 1); - dup2(fd, 2); - if (fd > 2) - close(fd); + for (i = 0; consoles[i] != NULL; i++) { + if ((fd = open(consoles[i], O_RDWR)) >= 0 + && !tcgetattr(fd, &mode) && !termcmp(&cmode, &mode)) { + printf + ("anaconda installer init version %s using %s as console\n", + VERSION, consoles[i]); + isSerial = 3; + console = strdup(consoles[i]); + break; + } + close(fd); + } + + cfd = open("/dev/console", O_WRONLY); + tcsetattr(cfd, TCSANOW, &orig_cmode); + close(cfd); + + if ((fd < 0) && (ioctl(0, TIOCLINUX, &twelve) < 0)) { + isSerial = 2; + + if (ioctl(0, TIOCGSERIAL, &si) == -1) { + isSerial = 0; + } + } + + if (isSerial && (isSerial != 3)) { + char *device = "/dev/ttyS0"; + + printf + ("anaconda installer init version %s using a serial console\n", + VERSION); + + if (isSerial == 2) + device = "/dev/console"; + fd = open(device, O_RDWR, 0); + if (fd < 0) + device = "/dev/tts/0"; + + if (fd < 0) { + printf("failed to open %s\n", device); + fatal_error(1); + } + + setupTerminal(fd); + } else if (isSerial == 3) { + setupTerminal(fd); + } else if (fd < 0) { + fd = open("/dev/tty1", O_RDWR, 0); + if (fd < 0) + fd = open("/dev/vc/1", O_RDWR, 0); + + if (fd < 0) { + printf("failed to open /dev/tty1 and /dev/vc/1"); + fatal_error(1); + } + } + + setsid(); + if (ioctl(0, TIOCSCTTY, NULL)) { + printf("could not set new controlling tty\n"); + } + + dup2(fd, 0); + dup2(fd, 1); + dup2(fd, 2); + if (fd > 2) + close(fd); #else - dup2(0, 1); - dup2(0, 2); + dup2(0, 1); + dup2(0, 2); #endif - /* disable Ctrl+Z, Ctrl+C, etc ... but not in rescue mode */ - disable_keys = 1; - if (argc > 1) - if (strstr(argv[1], "rescue")) - disable_keys = 0; - - if (disable_keys) { - tcgetattr(0, &ts); - ts.c_iflag &= ~BRKINT; - ts.c_iflag |= IGNBRK; - ts.c_iflag &= ~ISIG; - tcsetattr(0, TCSANOW, &ts); - } - - int ret; - ret = sethostname("localhost.localdomain", 21); - /* the default domainname (as of 2.0.35) is "(none)", which confuses - glibc */ - ret = setdomainname("", 0); - - printf("trying to remount root filesystem read write... "); - if (mount("/", "/", "ext2", MS_REMOUNT | MS_MGC_VAL, NULL)) { - fatal_error(1); - } - printf("done\n"); - - /* we want our /tmp to be tmpfs, but we also want to let people hack - * their initrds to add things like a ks.cfg, so this has to be a little - * tricky */ - rename("/tmp", "/oldtmp"); - mkdir("/tmp", 0755); - - printf("mounting /tmp as tmpfs... "); - if (mount("none", "/tmp", "tmpfs", 0, "size=250m")) - fatal_error(1); - printf("done\n"); - - copyDirectory("/oldtmp", "/tmp", copyErrorFn, copyErrorFn); - unlink("/oldtmp"); - - /* Now we have some /tmp space set up, and /etc and /dev point to - it. We should be in pretty good shape. */ - doklog("/dev/tty4"); - - /* write out a pid file */ - if ((fd = open("/var/run/init.pid", O_WRONLY|O_CREAT, 0644)) > 0) { - char * buf = malloc(10); - int ret; - - snprintf(buf, 9, "%d", getpid()); - ret = write(fd, buf, strlen(buf)); - close(fd); - free(buf); - } else { - printf("unable to write init.pid (%d): %m\n", errno); - sleep(2); - } - - /* D-Bus */ - if (fork() == 0) { - execl("/sbin/dbus-uuidgen", "/sbin/dbus-uuidgen", "--ensure", NULL); - doExit(1); - } - - if (fork() == 0) { - execl("/sbin/dbus-daemon", "/sbin/dbus-daemon", "--system", NULL); - doExit(1); - } - - sleep(2); - - /* Go into normal init mode - keep going, and then do a orderly shutdown - when: - - 1) /bin/install exits - 2) we receive a SIGHUP - */ - - printf("running install...\n"); - - setsid(); - - if (!(installpid = fork())) { - /* child */ - *argvp++ = "/sbin/loader"; - - if (isSerial == 3) { - *argvp++ = "--virtpconsole"; - *argvp++ = console; - } - - *argvp++ = NULL; - - printf("running %s\n", argvc[0]); - execve(argvc[0], argvc, env); - - shutDown(1, HALT); - } - - /* signal handlers for halt/poweroff */ - signal(SIGUSR1, sigUsr1Handler); - signal(SIGUSR2, sigUsr2Handler); - - /* set up the ctrl+alt+delete handler to kill our pid, not pid 1 */ - signal(SIGINT, sigintHandler); - if ((fd = open("/proc/sys/kernel/cad_pid", O_WRONLY)) != -1) { - char buf[7]; - size_t count; - sprintf(buf, "%d", getpid()); - count = write(fd, buf, strlen(buf)); - close(fd); - /* if we succeeded in writing our pid, turn off the hard reboot - ctrl-alt-del handler */ - if (count == strlen(buf) && - (fd = open("/proc/sys/kernel/ctrl-alt-del", O_WRONLY)) != -1) { - int ret; - - ret = write(fd, "0", 1); - close(fd); - } - } - - while (!doShutdown) { - pid_t childpid; - childpid = waitpid(-1, &waitStatus, 0); - - if (childpid == installpid) - doShutdown = 1; - } - - if (!WIFEXITED(waitStatus) || - (WIFEXITED(waitStatus) && WEXITSTATUS(waitStatus))) { - printf("install exited abnormally [%d/%d] ", WIFEXITED(waitStatus), - WEXITSTATUS(waitStatus)); - if (WIFSIGNALED(waitStatus)) { - printf("-- received signal %d", WTERMSIG(waitStatus)); - } - printf("\n"); - } else { - doReboot = 1; - } - - shutDown(doKill, doReboot?REBOOT:HALT); - - return 0; + /* disable Ctrl+Z, Ctrl+C, etc ... but not in rescue mode */ + disable_keys = 1; + if (argc > 1) + if (strstr(argv[1], "rescue")) + disable_keys = 0; + + if (disable_keys) { + tcgetattr(0, &ts); + ts.c_iflag &= ~BRKINT; + ts.c_iflag |= IGNBRK; + ts.c_iflag &= ~ISIG; + tcsetattr(0, TCSANOW, &ts); + } + + int ret; + ret = sethostname("localhost.localdomain", 21); + /* the default domainname (as of 2.0.35) is "(none)", which confuses + glibc */ + ret = setdomainname("", 0); + + printf("trying to remount root filesystem read write... "); + if (mount("/", "/", "ext2", MS_REMOUNT | MS_MGC_VAL, NULL)) { + fatal_error(1); + } + printf("done\n"); + + /* we want our /tmp to be tmpfs, but we also want to let people hack + * their initrds to add things like a ks.cfg, so this has to be a little + * tricky */ + rename("/tmp", "/oldtmp"); + mkdir("/tmp", 0755); + + printf("mounting /tmp as tmpfs... "); + if (mount("none", "/tmp", "tmpfs", 0, "size=250m")) + fatal_error(1); + printf("done\n"); + + copyDirectory("/oldtmp", "/tmp", copyErrorFn, copyErrorFn); + unlink("/oldtmp"); + + /* Now we have some /tmp space set up, and /etc and /dev point to + it. We should be in pretty good shape. */ + doklog("/dev/tty4"); + + /* write out a pid file */ + if ((fd = open("/var/run/init.pid", O_WRONLY | O_CREAT, 0644)) > 0) { + char *buf = malloc(10); + int ret; + + snprintf(buf, 9, "%d", getpid()); + ret = write(fd, buf, strlen(buf)); + close(fd); + free(buf); + } else { + printf("unable to write init.pid (%d): %m\n", errno); + sleep(2); + } + + /* D-Bus */ + if (fork() == 0) { + execl("/sbin/dbus-uuidgen", "/sbin/dbus-uuidgen", "--ensure", + NULL); + doExit(1); + } + + if (fork() == 0) { + execl("/sbin/dbus-daemon", "/sbin/dbus-daemon", "--system", + NULL); + doExit(1); + } + + sleep(2); + + /* Go into normal init mode - keep going, and then do a orderly shutdown + when: + + 1) /bin/install exits + 2) we receive a SIGHUP + */ + + printf("running install...\n"); + + setsid(); + + if (!(installpid = fork())) { + /* child */ + *argvp++ = "/sbin/loader"; + + if (isSerial == 3) { + *argvp++ = "--virtpconsole"; + *argvp++ = console; + } + + *argvp++ = NULL; + + printf("running %s\n", argvc[0]); + execve(argvc[0], argvc, env); + + shutDown(1, HALT); + } + + /* signal handlers for halt/poweroff */ + signal(SIGUSR1, sigUsr1Handler); + signal(SIGUSR2, sigUsr2Handler); + + /* set up the ctrl+alt+delete handler to kill our pid, not pid 1 */ + signal(SIGINT, sigintHandler); + if ((fd = open("/proc/sys/kernel/cad_pid", O_WRONLY)) != -1) { + char buf[7]; + size_t count; + sprintf(buf, "%d", getpid()); + count = write(fd, buf, strlen(buf)); + close(fd); + /* if we succeeded in writing our pid, turn off the hard reboot + ctrl-alt-del handler */ + if (count == strlen(buf) && + (fd = + open("/proc/sys/kernel/ctrl-alt-del", O_WRONLY)) != -1) { + int ret; + + ret = write(fd, "0", 1); + close(fd); + } + } + + while (!doShutdown) { + pid_t childpid; + childpid = waitpid(-1, &waitStatus, 0); + + if (childpid == installpid) + doShutdown = 1; + } + + if (!WIFEXITED(waitStatus) || + (WIFEXITED(waitStatus) && WEXITSTATUS(waitStatus))) { + printf("install exited abnormally [%d/%d] ", + WIFEXITED(waitStatus), WEXITSTATUS(waitStatus)); + if (WIFSIGNALED(waitStatus)) { + printf("-- received signal %d", WTERMSIG(waitStatus)); + } + printf("\n"); + } else { + doReboot = 1; + } + + shutDown(doKill, doReboot ? REBOOT : HALT); + + return 0; } /* vim:set sw=8 noet */ diff --git a/loader/kbd.c b/loader/kbd.c index db75260..d71e73d 100644 --- a/loader/kbd.c +++ b/loader/kbd.c @@ -41,126 +41,135 @@ /* boot flags */ extern uint64_t flags; -int chooseKeyboard(struct loaderData_s * loaderData, char ** kbdtypep) { - int num = -1; - int rc; - gzFile f; - struct kmapHeader hdr; - struct kmapInfo * infoTable; - struct langInfo * languages; - int numLanguages; - char ** kbds; - char buf[16384]; /* I hope this is big enough */ - int i; - char * defkbd = loaderData->kbd ? loaderData->kbd : NULL; - char *lang; +int chooseKeyboard(struct loaderData_s *loaderData, char **kbdtypep) +{ + int num = -1; + int rc; + gzFile f; + struct kmapHeader hdr; + struct kmapInfo *infoTable; + struct langInfo *languages; + int numLanguages; + char **kbds; + char buf[16384]; /* I hope this is big enough */ + int i; + char *defkbd = loaderData->kbd ? loaderData->kbd : NULL; + char *lang; #if defined(__s390__) || defined(__s390x__) - return LOADER_NOOP; + return LOADER_NOOP; #endif - if (FL_SERIAL (flags) || FL_VIRTPCONSOLE(flags)) return LOADER_NOOP; + if (FL_SERIAL(flags) || FL_VIRTPCONSOLE(flags)) + return LOADER_NOOP; - numLanguages = getLangInfo(&languages); + numLanguages = getLangInfo(&languages); - lang = getenv("LANG"); - if (!lang) - lang = loaderData->lang; + lang = getenv("LANG"); + if (!lang) + lang = loaderData->lang; - if (!defkbd && lang) { - for (i = 0; i < numLanguages; i++) { - if (!strncmp(languages[i].lc_all, lang, 2)) { - defkbd = languages[i].keyboard; - break; - } + if (!defkbd && lang) { + for (i = 0; i < numLanguages; i++) { + if (!strncmp(languages[i].lc_all, lang, 2)) { + defkbd = languages[i].keyboard; + break; + } + } } - } - - if (!defkbd) - defkbd = "us"; - - f = gunzip_open("/etc/keymaps.gz"); - if (!f) { - errorWindow("cannot open /etc/keymaps.gz: %s"); - return LOADER_ERROR; - } - - if (gunzip_read(f, &hdr, sizeof(hdr)) != sizeof(hdr)) { - errorWindow("failed to read keymaps header: %s"); - gunzip_close(f); - return LOADER_ERROR; - } - - logMessage(INFO, "%d keymaps are available", hdr.numEntries); - - i = hdr.numEntries * sizeof(*infoTable); - infoTable = alloca(i); - if (gunzip_read(f, infoTable, i) != i) { - errorWindow("failed to read keymap information: %s"); - gunzip_close(f); - return LOADER_ERROR; - } - - if (num == -1 ) { - kbds = alloca(sizeof(*kbds) * (hdr.numEntries + 1)); - for (i = 0; i < hdr.numEntries; i++) { - kbds[i] = infoTable[i].name; + + if (!defkbd) + defkbd = "us"; + + f = gunzip_open("/etc/keymaps.gz"); + if (!f) { + errorWindow("cannot open /etc/keymaps.gz: %s"); + return LOADER_ERROR; } - kbds[i] = NULL; - qsort(kbds, i, sizeof(*kbds), simpleStringCmp); + if (gunzip_read(f, &hdr, sizeof(hdr)) != sizeof(hdr)) { + errorWindow("failed to read keymaps header: %s"); + gunzip_close(f); + return LOADER_ERROR; + } - for (i = 0; i < hdr.numEntries; i++) - if (!strcmp(kbds[i], defkbd)) + logMessage(INFO, "%d keymaps are available", hdr.numEntries); + + i = hdr.numEntries * sizeof(*infoTable); + infoTable = alloca(i); + if (gunzip_read(f, infoTable, i) != i) { + errorWindow("failed to read keymap information: %s"); + gunzip_close(f); + return LOADER_ERROR; + } + + if (num == -1) { + kbds = alloca(sizeof(*kbds) * (hdr.numEntries + 1)); + for (i = 0; i < hdr.numEntries; i++) { + kbds[i] = infoTable[i].name; + } + + kbds[i] = NULL; + qsort(kbds, i, sizeof(*kbds), simpleStringCmp); + + for (i = 0; i < hdr.numEntries; i++) + if (!strcmp(kbds[i], defkbd)) + num = i; + + rc = newtWinMenu(_("Keyboard Type"), + _("What type of keyboard do you have?"), + 40, 5, 5, 8, kbds, &num, _("OK"), _("Back"), + NULL); + if (rc == 2) + return LOADER_BACK; + + /* num needs to index the right keyboard infoTable */ + for (i = 0; i < hdr.numEntries; i++) + if (!strcmp(kbds[num], infoTable[i].name)) + break; num = i; + } - rc = newtWinMenu(_("Keyboard Type"), - _("What type of keyboard do you have?"), - 40, 5, 5, 8, kbds, &num, _("OK"), _("Back"), NULL); - if (rc == 2) return LOADER_BACK; - - /* num needs to index the right keyboard infoTable */ - for (i = 0; i < hdr.numEntries; i++) - if (!strcmp(kbds[num], infoTable[i].name)) break; - num = i; - } - - rc = 0; - - for (i = 0; i < num; i++) { - if (gunzip_read(f, buf, infoTable[i].size) != infoTable[i].size) { - logMessage(ERROR, "error reading %d bytes from file: %m", - infoTable[i].size); - gunzip_close(f); - rc = LOADER_ERROR; + rc = 0; + + for (i = 0; i < num; i++) { + if (gunzip_read(f, buf, infoTable[i].size) != infoTable[i].size) { + logMessage(ERROR, + "error reading %d bytes from file: %m", + infoTable[i].size); + gunzip_close(f); + rc = LOADER_ERROR; + } } - } - if (!rc) rc = loadKeymap(f); + if (!rc) + rc = loadKeymap(f); - /* normalize the error condition */ - /* MSWFIXME - do we want to warn the user that setting the - keyboard didn't work? - */ - if (rc != 0) - rc = LOADER_ERROR; - else - gunzip_close(f); + /* normalize the error condition */ + /* MSWFIXME - do we want to warn the user that setting the + keyboard didn't work? + */ + if (rc != 0) + rc = LOADER_ERROR; + else + gunzip_close(f); - loaderData->kbd = strdup(infoTable[num].name); + loaderData->kbd = strdup(infoTable[num].name); - return rc; + return rc; } -void setKickstartKeyboard(struct loaderData_s * loaderData, int argc, - char ** argv) { - if (argc < 2) { - logMessage(ERROR, "no argument passed to keyboard kickstart command"); - return; - } +void setKickstartKeyboard(struct loaderData_s *loaderData, int argc, + char **argv) +{ + if (argc < 2) { + logMessage(ERROR, + "no argument passed to keyboard kickstart command"); + return; + } - loaderData->kbd = argv[1]; - loaderData->kbd_set = 1; + loaderData->kbd = argv[1]; + loaderData->kbd_set = 1; } /* vim:set sw=8 noet */ diff --git a/loader/kbd.h b/loader/kbd.h index e9478c2..77695d6 100644 --- a/loader/kbd.h +++ b/loader/kbd.h @@ -20,9 +20,9 @@ #ifndef H_KBD #define H_KBD -int chooseKeyboard(struct loaderData_s * loaderData, char ** kbdtypep); -void setKickstartKeyboard(struct loaderData_s * loaderData, int argc, - char ** argv); +int chooseKeyboard(struct loaderData_s *loaderData, char **kbdtypep); +void setKickstartKeyboard(struct loaderData_s *loaderData, int argc, + char **argv); #endif diff --git a/loader/kickstart.c b/loader/kickstart.c index f1cf962..5eefeb4 100644 --- a/loader/kickstart.c +++ b/loader/kickstart.c @@ -58,250 +58,262 @@ extern uint64_t flags; struct ksCommandNames { - int code; - char * name; - void (*setupData) (struct loaderData_s *loaderData, - int argc, char ** argv); -} ; + int code; + char *name; + void (*setupData) (struct loaderData_s * loaderData, + int argc, char **argv); +}; struct ksCommand { - int code, argc; - char ** argv; + int code, argc; + char **argv; }; -static void setTextMode(struct loaderData_s * loaderData, int argc, - char ** argv); -static void setGraphicalMode(struct loaderData_s * loaderData, int argc, - char ** argv); -static void setCmdlineMode(struct loaderData_s * loaderData, int argc, - char ** argv); -static void setSELinux(struct loaderData_s * loaderData, int argc, - char ** argv); -static void setPowerOff(struct loaderData_s * loaderData, int argc, - char ** argv); -static void setHalt(struct loaderData_s * loaderData, int argc, - char ** argv); -static void setShutdown(struct loaderData_s * loaderData, int argc, - char ** argv); -static void setMediaCheck(struct loaderData_s * loaderData, int argc, - char ** argv); -static void setUpdates(struct loaderData_s * loaderData, int argc, - char ** argv); +static void setTextMode(struct loaderData_s *loaderData, int argc, char **argv); +static void setGraphicalMode(struct loaderData_s *loaderData, int argc, + char **argv); +static void setCmdlineMode(struct loaderData_s *loaderData, int argc, + char **argv); +static void setSELinux(struct loaderData_s *loaderData, int argc, char **argv); +static void setPowerOff(struct loaderData_s *loaderData, int argc, char **argv); +static void setHalt(struct loaderData_s *loaderData, int argc, char **argv); +static void setShutdown(struct loaderData_s *loaderData, int argc, char **argv); +static void setMediaCheck(struct loaderData_s *loaderData, int argc, + char **argv); +static void setUpdates(struct loaderData_s *loaderData, int argc, char **argv); struct ksCommandNames ksTable[] = { - { KS_CMD_NFS, "nfs", setKickstartNfs }, - { KS_CMD_CDROM, "cdrom", setKickstartCD }, - { KS_CMD_HD, "harddrive", setKickstartHD }, - { KS_CMD_TEXT, "text", setTextMode }, - { KS_CMD_GRAPHICAL, "graphical", setGraphicalMode }, - { KS_CMD_URL, "url", setKickstartUrl }, - { KS_CMD_NETWORK, "network", setKickstartNetwork }, - { KS_CMD_KEYBOARD, "keyboard", setKickstartKeyboard }, - { KS_CMD_LANG, "lang", setKickstartLanguage }, - { KS_CMD_DD, "driverdisk", useKickstartDD }, - { KS_CMD_DEVICE, "device", loadKickstartModule }, - { KS_CMD_CMDLINE, "cmdline", setCmdlineMode }, - { KS_CMD_SELINUX, "selinux", setSELinux }, - { KS_CMD_POWEROFF, "poweroff", setPowerOff }, - { KS_CMD_HALT, "halt", setHalt }, - { KS_CMD_SHUTDOWN, "shutdown", setShutdown }, - { KS_CMD_MEDIACHECK, "mediacheck", setMediaCheck }, - { KS_CMD_UPDATES, "updates", setUpdates }, - { KS_CMD_NONE, NULL, NULL } + {KS_CMD_NFS, "nfs", setKickstartNfs}, + {KS_CMD_CDROM, "cdrom", setKickstartCD}, + {KS_CMD_HD, "harddrive", setKickstartHD}, + {KS_CMD_TEXT, "text", setTextMode}, + {KS_CMD_GRAPHICAL, "graphical", setGraphicalMode}, + {KS_CMD_URL, "url", setKickstartUrl}, + {KS_CMD_NETWORK, "network", setKickstartNetwork}, + {KS_CMD_KEYBOARD, "keyboard", setKickstartKeyboard}, + {KS_CMD_LANG, "lang", setKickstartLanguage}, + {KS_CMD_DD, "driverdisk", useKickstartDD}, + {KS_CMD_DEVICE, "device", loadKickstartModule}, + {KS_CMD_CMDLINE, "cmdline", setCmdlineMode}, + {KS_CMD_SELINUX, "selinux", setSELinux}, + {KS_CMD_POWEROFF, "poweroff", setPowerOff}, + {KS_CMD_HALT, "halt", setHalt}, + {KS_CMD_SHUTDOWN, "shutdown", setShutdown}, + {KS_CMD_MEDIACHECK, "mediacheck", setMediaCheck}, + {KS_CMD_UPDATES, "updates", setUpdates}, + {KS_CMD_NONE, NULL, NULL} }; -struct ksCommand * commands = NULL; +struct ksCommand *commands = NULL; int numCommands = 0; -int ksReadCommands(char * cmdFile) { - int fd; - char * buf; - struct stat sb; - char * start, * end, * chptr; - char oldch; - int line = 0; - gint argc = 0; - gchar **argv = NULL; - GError *optErr = NULL; - int inSection = 0; /* in a section such as %post, %pre or %packages */ - struct ksCommandNames * cmd; - int commandsAlloced = 5; - - if ((fd = open(cmdFile, O_RDONLY)) < 0) { - startNewt(); - newtWinMessage(_("Kickstart Error"), _("OK"), - _("Error opening kickstart file %s: %m"), - cmdFile); - return LOADER_ERROR; - } - - fstat(fd, &sb); - buf = alloca(sb.st_size + 1); - if (read(fd, buf, sb.st_size) != sb.st_size) { - startNewt(); - newtWinMessage(_("Kickstart Error"), _("OK"), - _("Error reading contents of kickstart file %s: %m"), - cmdFile); - close(fd); - return LOADER_ERROR; - } - - close(fd); - - buf[sb.st_size] = '\0'; - - commands = malloc(sizeof(*commands) * commandsAlloced); - - start = buf; - while (*start && !inSection) { - line++; - if (!(end = strchr(start, '\n'))) - end = start + strlen(start); - - oldch = *end; - *end = '\0'; - - while (*start && isspace(*start)) start++; - - chptr = end - 1; - while (chptr > start && isspace(*chptr)) chptr--; - - if (isspace(*chptr)) - *chptr = '\0'; - else - *(chptr + 1) = '\0'; - - if (!*start || *start == '#' || !strncmp(start, "%include", 8)) { - /* keep parsing the file */ - } else if (*start == '%') { - /* assumed - anything starting with %something is a section */ - inSection = 1; - } else if (*chptr == '\\') { - /* JKFIXME: this should be handled better, but at least we - * won't segfault now */ - } else { - if (!g_shell_parse_argv(start, &argc, &argv, &optErr) && argc) { - newtWinMessage(_("Kickstart Error"), _("OK"), - _("Error in %s on line %d of kickstart " - "file %s."), argv[0], line, cmdFile); - g_error_free(optErr); - } else if (!argc) { - newtWinMessage(_("Kickstart Error"), _("OK"), - _("Missing options on line %d of kickstart " - "file %s."), line, cmdFile); - } else { - for (cmd = ksTable; cmd->name; cmd++) - if (!strcmp(cmd->name, argv[0])) break; - - if (cmd->name) { - if (numCommands == commandsAlloced) { - commandsAlloced += 5; - commands = realloc(commands, - sizeof(*commands) * commandsAlloced); - } - - commands[numCommands].code = cmd->code; - commands[numCommands].argc = argc; - commands[numCommands].argv = argv; - numCommands++; - } - } - } - - if (oldch) - start = end + 1; - else - start = end; - } - - return 0; -} - +int ksReadCommands(char *cmdFile) +{ + int fd; + char *buf; + struct stat sb; + char *start, *end, *chptr; + char oldch; + int line = 0; + gint argc = 0; + gchar **argv = NULL; + GError *optErr = NULL; + int inSection = 0; /* in a section such as %post, %pre or %packages */ + struct ksCommandNames *cmd; + int commandsAlloced = 5; + + if ((fd = open(cmdFile, O_RDONLY)) < 0) { + startNewt(); + newtWinMessage(_("Kickstart Error"), _("OK"), + _("Error opening kickstart file %s: %m"), + cmdFile); + return LOADER_ERROR; + } -int ksHasCommand(int cmd) { - int i; + fstat(fd, &sb); + buf = alloca(sb.st_size + 1); + if (read(fd, buf, sb.st_size) != sb.st_size) { + startNewt(); + newtWinMessage(_("Kickstart Error"), _("OK"), + _ + ("Error reading contents of kickstart file %s: %m"), + cmdFile); + close(fd); + return LOADER_ERROR; + } - for(i = 0; i < numCommands; i++) - if (commands[i].code == cmd) return 1; + close(fd); + + buf[sb.st_size] = '\0'; + + commands = malloc(sizeof(*commands) * commandsAlloced); + + start = buf; + while (*start && !inSection) { + line++; + if (!(end = strchr(start, '\n'))) + end = start + strlen(start); + + oldch = *end; + *end = '\0'; + + while (*start && isspace(*start)) + start++; + + chptr = end - 1; + while (chptr > start && isspace(*chptr)) + chptr--; + + if (isspace(*chptr)) + *chptr = '\0'; + else + *(chptr + 1) = '\0'; + + if (!*start || *start == '#' || !strncmp(start, "%include", 8)) { + /* keep parsing the file */ + } else if (*start == '%') { + /* assumed - anything starting with %something is a section */ + inSection = 1; + } else if (*chptr == '\\') { + /* JKFIXME: this should be handled better, but at least we + * won't segfault now */ + } else { + if (!g_shell_parse_argv(start, &argc, &argv, &optErr) + && argc) { + newtWinMessage(_("Kickstart Error"), _("OK"), + _ + ("Error in %s on line %d of kickstart " + "file %s."), argv[0], line, + cmdFile); + g_error_free(optErr); + } else if (!argc) { + newtWinMessage(_("Kickstart Error"), _("OK"), + _ + ("Missing options on line %d of kickstart " + "file %s."), line, cmdFile); + } else { + for (cmd = ksTable; cmd->name; cmd++) + if (!strcmp(cmd->name, argv[0])) + break; + + if (cmd->name) { + if (numCommands == commandsAlloced) { + commandsAlloced += 5; + commands = realloc(commands, + sizeof + (*commands) * + commandsAlloced); + } + + commands[numCommands].code = cmd->code; + commands[numCommands].argc = argc; + commands[numCommands].argv = argv; + numCommands++; + } + } + } + + if (oldch) + start = end + 1; + else + start = end; + } - return 0; + return 0; } -int ksGetCommand(int cmd, char ** last, int * argc, char *** argv) { - int i = 0; - - if (last) { - for (i = 0; i < numCommands; i++) { - if (commands[i].argv == last) break; - } - - i++; - } - - for (; i < numCommands; i++) { - if (commands[i].code == cmd) { - if (argv) *argv = commands[i].argv; - if (argc) *argc = commands[i].argc; - return 0; - } - } - - return 1; +int ksHasCommand(int cmd) +{ + int i; + + for (i = 0; i < numCommands; i++) + if (commands[i].code == cmd) + return 1; + + return 0; } -int kickstartFromRemovable(char *kssrc) { - struct device ** devices; - char *p, *kspath; - int i, rc; - - logMessage(INFO, "doing kickstart from removable media"); - devices = getDevices(DEVICE_DISK); - /* usb can take some time to settle, even with the various hacks we - * have in place. some systems use portable USB CD-ROM drives, try to - * make sure there really isn't one before bailing. */ - for (i = 0; !devices && i < 10; ++i) { - logMessage(INFO, "sleeping to wait for a USB disk"); - sleep(2); - devices = getDevices(DEVICE_DISK); - } - if (!devices) { - logMessage(ERROR, "no disks"); - return 1; - } - - for (i = 0; devices[i]; i++) { - if (devices[i]->priv.removable == 1) { - logMessage(INFO, "first removable media is %s", devices[i]->device); - break; - } - } - - if (!devices[i] || (devices[i]->priv.removable == 0)) { - logMessage(ERROR, "no removable devices"); - return 1; - } - - /* format is floppy:[/path/to/ks.cfg] */ - kspath = ""; - p = strchr(kssrc, ':'); - if (p) - kspath = p + 1; - - if (!p || strlen(kspath) < 1) - kspath = "/ks.cfg"; - - if ((rc=getKickstartFromBlockDevice(devices[i]->device, kspath))) { - if (rc == 3) { - startNewt(); - newtWinMessage(_("Error"), _("OK"), - _("Cannot find ks.cfg on removable media.")); +int ksGetCommand(int cmd, char **last, int *argc, char ***argv) +{ + int i = 0; + + if (last) { + for (i = 0; i < numCommands; i++) { + if (commands[i].argv == last) + break; + } + + i++; + } + + for (; i < numCommands; i++) { + if (commands[i].code == cmd) { + if (argv) + *argv = commands[i].argv; + if (argc) + *argc = commands[i].argc; + return 0; + } } - return 1; - } - return 0; + return 1; } +int kickstartFromRemovable(char *kssrc) +{ + struct device **devices; + char *p, *kspath; + int i, rc; + + logMessage(INFO, "doing kickstart from removable media"); + devices = getDevices(DEVICE_DISK); + /* usb can take some time to settle, even with the various hacks we + * have in place. some systems use portable USB CD-ROM drives, try to + * make sure there really isn't one before bailing. */ + for (i = 0; !devices && i < 10; ++i) { + logMessage(INFO, "sleeping to wait for a USB disk"); + sleep(2); + devices = getDevices(DEVICE_DISK); + } + if (!devices) { + logMessage(ERROR, "no disks"); + return 1; + } + + for (i = 0; devices[i]; i++) { + if (devices[i]->priv.removable == 1) { + logMessage(INFO, "first removable media is %s", + devices[i]->device); + break; + } + } + + if (!devices[i] || (devices[i]->priv.removable == 0)) { + logMessage(ERROR, "no removable devices"); + return 1; + } + + /* format is floppy:[/path/to/ks.cfg] */ + kspath = ""; + p = strchr(kssrc, ':'); + if (p) + kspath = p + 1; + + if (!p || strlen(kspath) < 1) + kspath = "/ks.cfg"; + + if ((rc = getKickstartFromBlockDevice(devices[i]->device, kspath))) { + if (rc == 3) { + startNewt(); + newtWinMessage(_("Error"), _("OK"), + _ + ("Cannot find ks.cfg on removable media.")); + } + return 1; + } + + return 0; +} /* given a device name (w/o '/dev' on it), try to get ks file */ /* Error codes: @@ -309,241 +321,253 @@ int kickstartFromRemovable(char *kssrc) { 2 - could not mount device as ext2, vfat, or iso9660 3 - kickstart file named path not there */ -int getKickstartFromBlockDevice(char *device, char *path) { - return getFileFromBlockDevice(device, path, "/tmp/ks.cfg"); +int getKickstartFromBlockDevice(char *device, char *path) +{ + return getFileFromBlockDevice(device, path, "/tmp/ks.cfg"); } -static char *newKickstartLocation(const char *origLocation) { - const char *location; - char *retval = NULL; - newtComponent f, okay, cancel, answer, locationEntry; - newtGrid grid, buttons; +static char *newKickstartLocation(const char *origLocation) +{ + const char *location; + char *retval = NULL; + newtComponent f, okay, cancel, answer, locationEntry; + newtGrid grid, buttons; - startNewt(); + startNewt(); - locationEntry = newtEntry(-1, -1, NULL, 60, &location, NEWT_FLAG_SCROLL); - newtEntrySet(locationEntry, origLocation, 1); + locationEntry = + newtEntry(-1, -1, NULL, 60, &location, NEWT_FLAG_SCROLL); + newtEntrySet(locationEntry, origLocation, 1); - /* button bar at the bottom of the window */ - buttons = newtButtonBar(_("OK"), &okay, _("Cancel"), &cancel, NULL); + /* button bar at the bottom of the window */ + buttons = newtButtonBar(_("OK"), &okay, _("Cancel"), &cancel, NULL); - grid = newtCreateGrid(1, 3); + grid = newtCreateGrid(1, 3); - newtGridSetField(grid, 0, 0, NEWT_GRID_COMPONENT, - newtTextboxReflowed(-1, -1, _("Unable to download the kickstart file. Please modify the kickstart parameter below or press Cancel to proceed as an interactive installation."), 60, 0, 0, 0), - 0, 0, 0, 0, NEWT_ANCHOR_LEFT, 0); - newtGridSetField(grid, 0, 1, NEWT_GRID_COMPONENT, locationEntry, - 0, 1, 0, 0, NEWT_ANCHOR_LEFT, 0); - newtGridSetField(grid, 0, 2, NEWT_GRID_SUBGRID, buttons, - 0, 1, 0, 0, 0, NEWT_GRID_FLAG_GROWX); + newtGridSetField(grid, 0, 0, NEWT_GRID_COMPONENT, + newtTextboxReflowed(-1, -1, + _ + ("Unable to download the kickstart file. Please modify the kickstart parameter below or press Cancel to proceed as an interactive installation."), + 60, 0, 0, 0), 0, 0, 0, 0, + NEWT_ANCHOR_LEFT, 0); + newtGridSetField(grid, 0, 1, NEWT_GRID_COMPONENT, locationEntry, 0, 1, + 0, 0, NEWT_ANCHOR_LEFT, 0); + newtGridSetField(grid, 0, 2, NEWT_GRID_SUBGRID, buttons, 0, 1, 0, 0, 0, + NEWT_GRID_FLAG_GROWX); - f = newtForm(NULL, NULL, 0); - newtGridAddComponentsToForm(grid, f, 1); - newtGridWrappedWindow(grid, _("Error downloading kickstart file")); - newtGridFree(grid, 1); + f = newtForm(NULL, NULL, 0); + newtGridAddComponentsToForm(grid, f, 1); + newtGridWrappedWindow(grid, _("Error downloading kickstart file")); + newtGridFree(grid, 1); - /* run the form */ - answer = newtRunForm(f); + /* run the form */ + answer = newtRunForm(f); - if (answer != cancel) - retval = strdup(location); + if (answer != cancel) + retval = strdup(location); - newtFormDestroy(f); - newtPopWindow(); + newtFormDestroy(f); + newtPopWindow(); - return retval; + return retval; } -int isKickstartFileRemote(char *ksFile) { - char *location = NULL; - - if (ksFile == NULL) { - return 0; - } - - if (!strcmp(ksFile, "ks")) { - return 1; - } else if (!strncmp(ksFile, "ks=", 3)) { - location = ksFile + 3; - } - - if (!strncmp(location, "http", 4) || - !strncmp(location, "ftp://", 6) || - !strncmp(location, "nfs:", 4)) { - return 1; - } else { - return 0; - } +int isKickstartFileRemote(char *ksFile) +{ + char *location = NULL; + + if (ksFile == NULL) { + return 0; + } + + if (!strcmp(ksFile, "ks")) { + return 1; + } else if (!strncmp(ksFile, "ks=", 3)) { + location = ksFile + 3; + } + + if (!strncmp(location, "http", 4) || + !strncmp(location, "ftp://", 6) || !strncmp(location, "nfs:", 4)) { + return 1; + } else { + return 0; + } } -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)) { - rc = kickstartFromNfs(NULL, loaderData); - 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"); - } 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"); - } 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; - } - } - - flags |= LOADER_FLAGS_KICKSTART; - return; +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)) { + rc = kickstartFromNfs(NULL, loaderData); + 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"); + } 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"); + } 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; + } + } + + flags |= LOADER_FLAGS_KICKSTART; + return; } -static void setUpdates(struct loaderData_s * loaderData, int argc, - char ** argv) { - if (argc == 1) - flags |= LOADER_FLAGS_UPDATES; - else if (argc == 2) - loaderData->updatessrc = strdup(argv[1]); - else - logMessage(WARNING, "updates command given with incorrect arguments"); +static void setUpdates(struct loaderData_s *loaderData, int argc, char **argv) +{ + if (argc == 1) + flags |= LOADER_FLAGS_UPDATES; + else if (argc == 2) + loaderData->updatessrc = strdup(argv[1]); + else + logMessage(WARNING, + "updates command given with incorrect arguments"); } -static void setTextMode(struct loaderData_s * loaderData, int argc, - char ** argv) { - logMessage(INFO, "kickstart forcing text mode"); - flags |= LOADER_FLAGS_TEXT; - return; +static void setTextMode(struct loaderData_s *loaderData, int argc, char **argv) +{ + logMessage(INFO, "kickstart forcing text mode"); + flags |= LOADER_FLAGS_TEXT; + return; } -static void setGraphicalMode(struct loaderData_s * loaderData, int argc, - char ** argv) { - logMessage(INFO, "kickstart forcing graphical mode"); - flags |= LOADER_FLAGS_GRAPHICAL; - return; +static void setGraphicalMode(struct loaderData_s *loaderData, int argc, + char **argv) +{ + logMessage(INFO, "kickstart forcing graphical mode"); + flags |= LOADER_FLAGS_GRAPHICAL; + return; } -static void setCmdlineMode(struct loaderData_s * loaderData, int argc, - char ** argv) { - logMessage(INFO, "kickstart forcing cmdline mode"); - flags |= LOADER_FLAGS_CMDLINE; - return; +static void setCmdlineMode(struct loaderData_s *loaderData, int argc, + char **argv) +{ + logMessage(INFO, "kickstart forcing cmdline mode"); + flags |= LOADER_FLAGS_CMDLINE; + return; } -static void setSELinux(struct loaderData_s * loaderData, int argc, - char ** argv) { - flags |= LOADER_FLAGS_SELINUX; - return; +static void setSELinux(struct loaderData_s *loaderData, int argc, char **argv) +{ + flags |= LOADER_FLAGS_SELINUX; + return; } -static void setPowerOff(struct loaderData_s * loaderData, int argc, - char ** argv) { - if (!FL_NOKILL(flags)) - flags |= LOADER_FLAGS_POWEROFF; - return; +static void setPowerOff(struct loaderData_s *loaderData, int argc, char **argv) +{ + if (!FL_NOKILL(flags)) + flags |= LOADER_FLAGS_POWEROFF; + return; } -static void setHalt(struct loaderData_s * loaderData, int argc, - char ** argv) { - if (!FL_NOKILL(flags)) - flags |= LOADER_FLAGS_HALT; - return; +static void setHalt(struct loaderData_s *loaderData, int argc, char **argv) +{ + if (!FL_NOKILL(flags)) + flags |= LOADER_FLAGS_HALT; + return; } -static void setShutdown(struct loaderData_s * loaderData, int argc, - char ** argv) { - gint eject = 0, reboot = 0, halt = 0, poweroff = 0; - GOptionContext *optCon = g_option_context_new(NULL); - GError *optErr = NULL; - GOptionEntry ksOptions[] = { - { "eject", 'e', 0, G_OPTION_ARG_INT, &eject, NULL, NULL }, - { "reboot", 'r', 0, G_OPTION_ARG_INT, &reboot, NULL, NULL }, - { "halt", 'h', 0, G_OPTION_ARG_INT, &halt, NULL, NULL }, - { "poweroff", 'p', 0, G_OPTION_ARG_INT, &poweroff, NULL, NULL }, - { NULL }, - }; - - g_option_context_set_help_enabled(optCon, FALSE); - g_option_context_add_main_entries(optCon, ksOptions, NULL); - - if (!g_option_context_parse(optCon, &argc, &argv, &optErr)) { - startNewt(); - newtWinMessage(_("Kickstart Error"), _("OK"), - _("Bad argument to shutdown kickstart method " - "command: %s"), optErr->message); - g_error_free(optErr); - g_option_context_free(optCon); - return; - } - - g_option_context_free(optCon); - - if (FL_NOKILL(flags)) { - flags |= LOADER_FLAGS_HALT; - } else { - if (poweroff) - flags |= LOADER_FLAGS_POWEROFF; - if ((!poweroff && !reboot) || (halt)) - flags |= LOADER_FLAGS_HALT; - } +static void setShutdown(struct loaderData_s *loaderData, int argc, char **argv) +{ + gint eject = 0, reboot = 0, halt = 0, poweroff = 0; + GOptionContext *optCon = g_option_context_new(NULL); + GError *optErr = NULL; + GOptionEntry ksOptions[] = { + {"eject", 'e', 0, G_OPTION_ARG_INT, &eject, NULL, NULL}, + {"reboot", 'r', 0, G_OPTION_ARG_INT, &reboot, NULL, NULL}, + {"halt", 'h', 0, G_OPTION_ARG_INT, &halt, NULL, NULL}, + {"poweroff", 'p', 0, G_OPTION_ARG_INT, &poweroff, NULL, NULL}, + {NULL}, + }; + + g_option_context_set_help_enabled(optCon, FALSE); + g_option_context_add_main_entries(optCon, ksOptions, NULL); + + if (!g_option_context_parse(optCon, &argc, &argv, &optErr)) { + startNewt(); + newtWinMessage(_("Kickstart Error"), _("OK"), + _("Bad argument to shutdown kickstart method " + "command: %s"), optErr->message); + g_error_free(optErr); + g_option_context_free(optCon); + return; + } + + g_option_context_free(optCon); + + if (FL_NOKILL(flags)) { + flags |= LOADER_FLAGS_HALT; + } else { + if (poweroff) + flags |= LOADER_FLAGS_POWEROFF; + if ((!poweroff && !reboot) || (halt)) + flags |= LOADER_FLAGS_HALT; + } } -static void setMediaCheck(struct loaderData_s * loaderData, int argc, - char ** argv) { - flags |= LOADER_FLAGS_MEDIACHECK; - return; +static void setMediaCheck(struct loaderData_s *loaderData, int argc, + char **argv) +{ + flags |= LOADER_FLAGS_MEDIACHECK; + return; } -void runKickstart(struct loaderData_s * loaderData) { - struct ksCommandNames * cmd; - int argc; - char ** argv; - - logMessage(INFO, "setting up kickstart"); - for (cmd = ksTable; cmd->name; cmd++) { - if ((!ksGetCommand(cmd->code, NULL, &argc, &argv)) && cmd->setupData) { - cmd->setupData(loaderData, argc, argv); - } - } +void runKickstart(struct loaderData_s *loaderData) +{ + struct ksCommandNames *cmd; + int argc; + char **argv; + + logMessage(INFO, "setting up kickstart"); + for (cmd = ksTable; cmd->name; cmd++) { + if ((!ksGetCommand(cmd->code, NULL, &argc, &argv)) + && cmd->setupData) { + cmd->setupData(loaderData, argc, argv); + } + } } /* vim:set sw=8 noet */ diff --git a/loader/kickstart.h b/loader/kickstart.h index 8b9a1a9..c7c07ee 100644 --- a/loader/kickstart.h +++ b/loader/kickstart.h @@ -41,13 +41,13 @@ #define KS_CMD_MEDIACHECK 17 #define KS_CMD_UPDATES 18 -int ksReadCommands(char * cmdFile); -int ksGetCommand(int cmd, char ** last, int * argc, char *** argv); +int ksReadCommands(char *cmdFile); +int ksGetCommand(int cmd, char **last, int *argc, char ***argv); int ksHasCommand(int cmd); int isKickstartFileRemote(char *ksFile); -void getKickstartFile(struct loaderData_s * loaderData); -void runKickstart(struct loaderData_s * loaderData); +void getKickstartFile(struct loaderData_s *loaderData); +void runKickstart(struct loaderData_s *loaderData); int getKickstartFromBlockDevice(char *device, char *path); #endif diff --git a/loader/lang.c b/loader/lang.c index 734f826..e956b78 100644 --- a/loader/lang.c +++ b/loader/lang.c @@ -50,351 +50,382 @@ extern uint64_t flags; struct aString { - unsigned int hash; - short length; - char * str; -} ; + unsigned int hash; + short length; + char *str; +}; -struct aString * strings = NULL; +struct aString *strings = NULL; int numStrings = 0, allocedStrings = 0; static int english = 0; -static char * topLineWelcome = N_("Welcome to %s for %s"); -static char * topLineWelcomeRescue = N_("Welcome to %s for %s - Rescue Mode"); -static char * bottomHelpLine = N_(" <Tab>/<Alt-Tab> between elements | <Space> selects | <F12> next screen "); +static char *topLineWelcome = N_("Welcome to %s for %s"); +static char *topLineWelcomeRescue = N_("Welcome to %s for %s - Rescue Mode"); +static char *bottomHelpLine = + N_ + (" <Tab>/<Alt-Tab> between elements | <Space> selects | <F12> next screen "); -static int aStringCmp(const void * a, const void * b) { - const struct aString * first = a; - const struct aString * second = b; +static int aStringCmp(const void *a, const void *b) +{ + const struct aString *first = a; + const struct aString *second = b; - if (first->hash < second->hash) - return -1; - else if (first->hash == second->hash) - return 0; + if (first->hash < second->hash) + return -1; + else if (first->hash == second->hash) + return 0; - return 1; + return 1; } -char * translateString(char * str) { - unsigned int sum = 0, xor = 0; - int len = 0; - char * chptr; - struct aString * match; - struct aString key; - - for (chptr = str; *chptr; chptr++) { - sum += *chptr; - xor ^= *chptr; - len++; - } - - key.hash = (sum << 16) | ((xor & 0xFF) << 8) | (len & 0xFF); - match = bsearch(&key, strings, numStrings, sizeof(*strings), aStringCmp); - if (!match) - return str; - - return match->str; +char *translateString(char *str) +{ + unsigned int sum = 0, xor = 0; + int len = 0; + char *chptr; + struct aString *match; + struct aString key; + + for (chptr = str; *chptr; chptr++) { + sum += *chptr; + xor ^= *chptr; + len++; + } + + key.hash = (sum << 16) | ((xor & 0xFF) << 8) | (len & 0xFF); + match = + bsearch(&key, strings, numStrings, sizeof(*strings), aStringCmp); + if (!match) + return str; + + return match->str; } -static struct langInfo * languages = NULL; +static struct langInfo *languages = NULL; static int numLanguages = 0; -static void loadLanguageList(void) { - char * file = "/etc/lang-table"; - FILE * f; - char line[256]; - char name[256], key[256], font[256], code[256], - keyboard[256], timezone[256]; - int lineNum = 0; - - wcwidth(0); - f = fopen(file, "r"); - if (!f) { - newtWinMessage(_("Error"), _("OK"), "cannot open %s: %m", file); - return; - } - - while (fgets(line, sizeof(line), f)) { - lineNum++; - languages = realloc(languages, sizeof(*languages) * (numLanguages + 1)); - if (sscanf(line, "%[^\t]\t%[^\t]\t%[^\t]\t%[^\t]\t%[^\t]\t%[^\t]\n", - name, key, font, code, keyboard, timezone) != 6) { - printf("bad line %d in lang-table", lineNum); - logMessage(WARNING, "bad line %d in lang-table", lineNum); - } else { - languages[numLanguages].lang = strdup(name); - languages[numLanguages].key = strdup(key); - languages[numLanguages].font = strdup(font); - languages[numLanguages].lc_all = strdup(code); - languages[numLanguages++].keyboard = strdup(keyboard); - } - } - fclose(f); +static void loadLanguageList(void) +{ + char *file = "/etc/lang-table"; + FILE *f; + char line[256]; + char name[256], key[256], font[256], code[256], + keyboard[256], timezone[256]; + int lineNum = 0; + + wcwidth(0); + f = fopen(file, "r"); + if (!f) { + newtWinMessage(_("Error"), _("OK"), "cannot open %s: %m", file); + return; + } + + while (fgets(line, sizeof(line), f)) { + lineNum++; + languages = + realloc(languages, sizeof(*languages) * (numLanguages + 1)); + if (sscanf + (line, "%[^\t]\t%[^\t]\t%[^\t]\t%[^\t]\t%[^\t]\t%[^\t]\n", + name, key, font, code, keyboard, timezone) != 6) { + printf("bad line %d in lang-table", lineNum); + logMessage(WARNING, "bad line %d in lang-table", + lineNum); + } else { + languages[numLanguages].lang = strdup(name); + languages[numLanguages].key = strdup(key); + languages[numLanguages].font = strdup(font); + languages[numLanguages].lc_all = strdup(code); + languages[numLanguages++].keyboard = strdup(keyboard); + } + } + fclose(f); } -int getLangInfo(struct langInfo ** langs) { - if (!languages) - loadLanguageList(); +int getLangInfo(struct langInfo **langs) +{ + if (!languages) + loadLanguageList(); - *langs = languages; - return numLanguages; + *langs = languages; + return numLanguages; } -void loadLanguage (char * file) { - char filename[200]; - gzFile stream; - int fd, hash, rc; - char * key = getenv("LANGKEY"); - - if (strings) { - free(strings), strings = NULL; - numStrings = allocedStrings = 0; - } - - /* english requires no files */ - if (!strcmp(key, "en")) - return; - - if (!file) { - file = filename; - sprintf(filename, "/etc/loader.tr"); - } - - stream = gunzip_open(file); - - if (!stream) { - newtWinMessage("Error", "OK", "Translation for %s is not available. " - "The Installation will proceed in English.", key); - return ; - } - - sprintf(filename, "%s.tr", key); - - rc = installCpioFile(stream, filename, "/tmp/translation", 1); - gunzip_close(stream); - - if (rc || access("/tmp/translation", R_OK)) { - newtWinMessage("Error", "OK", "Cannot get translation file %s.\n", - filename); - return; - } - - fd = open("/tmp/translation", O_RDONLY); - if (fd < 0) { - newtWinMessage("Error", "OK", "Failed to open /tmp/translation: %m\n"); - return; - } - - while (read(fd, &hash, 4) == 4) { - if (allocedStrings == numStrings) { - allocedStrings += 10; - strings = realloc(strings, sizeof(*strings) * allocedStrings); - } - - strings[numStrings].hash = ntohl(hash); - rc = read(fd, &strings[numStrings].length, 2); - strings[numStrings].length = ntohs(strings[numStrings].length); - strings[numStrings].str = malloc(strings[numStrings].length + 1); - rc = read(fd, strings[numStrings].str, strings[numStrings].length); - strings[numStrings].str[strings[numStrings].length] = '\0'; - numStrings++; - } - - close(fd); - unlink("/tmp/translation"); - - qsort(strings, numStrings, sizeof(*strings), aStringCmp); +void loadLanguage(char *file) +{ + char filename[200]; + gzFile stream; + int fd, hash, rc; + char *key = getenv("LANGKEY"); + + if (strings) { + free(strings), strings = NULL; + numStrings = allocedStrings = 0; + } + + /* english requires no files */ + if (!strcmp(key, "en")) + return; + + if (!file) { + file = filename; + sprintf(filename, "/etc/loader.tr"); + } + + stream = gunzip_open(file); + + if (!stream) { + newtWinMessage("Error", "OK", + "Translation for %s is not available. " + "The Installation will proceed in English.", + key); + return; + } + + sprintf(filename, "%s.tr", key); + + rc = installCpioFile(stream, filename, "/tmp/translation", 1); + gunzip_close(stream); + + if (rc || access("/tmp/translation", R_OK)) { + newtWinMessage("Error", "OK", + "Cannot get translation file %s.\n", filename); + return; + } + + fd = open("/tmp/translation", O_RDONLY); + if (fd < 0) { + newtWinMessage("Error", "OK", + "Failed to open /tmp/translation: %m\n"); + return; + } + + while (read(fd, &hash, 4) == 4) { + if (allocedStrings == numStrings) { + allocedStrings += 10; + strings = + realloc(strings, sizeof(*strings) * allocedStrings); + } + + strings[numStrings].hash = ntohl(hash); + rc = read(fd, &strings[numStrings].length, 2); + strings[numStrings].length = ntohs(strings[numStrings].length); + strings[numStrings].str = + malloc(strings[numStrings].length + 1); + rc = read(fd, strings[numStrings].str, + strings[numStrings].length); + strings[numStrings].str[strings[numStrings].length] = '\0'; + numStrings++; + } + + close(fd); + unlink("/tmp/translation"); + + qsort(strings, numStrings, sizeof(*strings), aStringCmp); } - /* give the index of the language to set to -- sets the appropriate * lang variables if we have a font. * * ASSUMPTION: languages exists */ -static void setLangEnv (int i) { - if (i > numLanguages) - return; - - if (strcmp(languages[i].font, "latarcyrheb-sun16")) - return; - logMessage(INFO, "setting language to %s", languages[i].lc_all); - - setenv("LANG", languages[i].lc_all, 1); - setenv("LANGKEY", languages[i].key, 1); - setenv("LINGUAS", languages[i].lang, 1); - loadLanguage (NULL); +static void setLangEnv(int i) +{ + if (i > numLanguages) + return; + + if (strcmp(languages[i].font, "latarcyrheb-sun16")) + return; + logMessage(INFO, "setting language to %s", languages[i].lc_all); + + setenv("LANG", languages[i].lc_all, 1); + setenv("LANGKEY", languages[i].key, 1); + setenv("LINGUAS", languages[i].lang, 1); + loadLanguage(NULL); } /* choice is the index of the chosen language in languages */ -static int setupLanguage(int choice, int forced) { - char * buf; - int i; - - logMessage(DEBUGLVL, "going to set language to %s", languages[choice].lc_all); - /* load the language only if it is displayable. if they're using - * a serial console or iSeries vioconsole, we hope it's smart enough */ - if ((strcmp(languages[choice].font, "latarcyrheb-sun16") && !FL_SERIAL(flags) && - !FL_VIRTPCONSOLE(flags) && !isVioConsole())) { - if (forced == 1) return 0; - - newtWinMessage("Language Unavailable", "OK", - "%s display is unavailable in text mode. The " - "installation will continue in English until the " - "display of %s is possible.", languages[choice].lang, - languages[choice].lang); - setLangEnv(english); - return 0; - } - - setLangEnv (choice); - isysLoadFont(); - - /* clear out top line */ - buf = alloca(80); - for (i=0; i < 80; i++) - buf[i] = ' '; - newtDrawRootText(0, 0, buf); - - char *fmt = FL_RESCUE(flags) ? _(topLineWelcomeRescue) : _(topLineWelcome); - checked_asprintf(&buf, fmt, getProductName(), getProductArch()); +static int setupLanguage(int choice, int forced) +{ + char *buf; + int i; + + logMessage(DEBUGLVL, "going to set language to %s", + languages[choice].lc_all); + /* load the language only if it is displayable. if they're using + * a serial console or iSeries vioconsole, we hope it's smart enough */ + if ((strcmp(languages[choice].font, "latarcyrheb-sun16") + && !FL_SERIAL(flags) && !FL_VIRTPCONSOLE(flags) + && !isVioConsole())) { + if (forced == 1) + return 0; + + newtWinMessage("Language Unavailable", "OK", + "%s display is unavailable in text mode. The " + "installation will continue in English until the " + "display of %s is possible.", + languages[choice].lang, languages[choice].lang); + setLangEnv(english); + return 0; + } + + setLangEnv(choice); + isysLoadFont(); + + /* clear out top line */ + buf = alloca(80); + for (i = 0; i < 80; i++) + buf[i] = ' '; + newtDrawRootText(0, 0, buf); + + char *fmt = + FL_RESCUE(flags) ? _(topLineWelcomeRescue) : _(topLineWelcome); + checked_asprintf(&buf, fmt, getProductName(), getProductArch()); + + newtDrawRootText(0, 0, buf); + free(buf); + newtPopHelpLine(); + newtPushHelpLine(_(bottomHelpLine)); - newtDrawRootText(0, 0, buf); - free(buf); - newtPopHelpLine(); - newtPushHelpLine(_(bottomHelpLine)); - - return 0; + return 0; } /* this is pretty simple. we want to break down the language specifier * into its short form (eg, en_US) */ -static char * getLangShortForm(char * oldLang) { - char * lang; - char * c; - - lang = strdup(oldLang); - - c = strchr(lang, '@'); - if (c) { - *c = '\0'; - } - - c = strchr(lang, '.'); - if (c) { - *c = '\0'; - } - - return lang; +static char *getLangShortForm(char *oldLang) +{ + char *lang; + char *c; + + lang = strdup(oldLang); + + c = strchr(lang, '@'); + if (c) { + *c = '\0'; + } + + c = strchr(lang, '.'); + if (c) { + *c = '\0'; + } + + return lang; } /* return the nick of a language -- eg en_US -> en */ -static char * getLangNick(char * oldLang) { - char * lang; - char * c; - - lang = strdup(oldLang); - - c = strchr(lang, '_'); - if (c) { - *c = '\0'; - } - - return lang; -} +static char *getLangNick(char *oldLang) +{ + char *lang; + char *c; -int setLanguage (char * key, int forced) { - int i; - - if (!languages) loadLanguageList(); - - for (i = 0; i < numLanguages; i++) { - if (!strcmp(languages[i].lc_all, key)) { - return setupLanguage(i, forced | !FL_KICKSTART(flags)); - } - } - - /* we didn't specify anything that's exactly in the lang-table. check - * against short forms and nicks */ - for (i = 0; i < numLanguages; i++) { - if (!strcmp(getLangShortForm(languages[i].lc_all), key)) { - return setupLanguage(i, forced | !FL_KICKSTART(flags)); - } - } - - for (i = 0; i < numLanguages; i++) { - if (!strcmp(getLangNick(languages[i].lc_all), key)) { - return setupLanguage(i, forced | !FL_KICKSTART(flags)); - } - } - - logMessage(ERROR, "unable to set to requested language %s", key); - return -1; + lang = strdup(oldLang); + + c = strchr(lang, '_'); + if (c) { + *c = '\0'; + } + + return lang; } -int chooseLanguage(char ** lang) { - int choice = 0; - char ** langs; - int i; - int current = -1; - char * currentLangName = getenv("LANG"); - int numLangs = 0; - char * langPicked; - - if (!languages) loadLanguageList(); - - langs = alloca(sizeof(*langs) * (numLanguages + 1)); - - for (i = 0; i < numLanguages; i++) { - if (!strncmp(languages[i].key, "en", 2)) - english = numLangs; - if (currentLangName && - !strcmp(languages[i].lang, currentLangName)) - current = numLangs; - - langs[numLangs++] = languages[i].lang; - } - - langs[numLangs] = NULL; - - if (current >= 0) - choice = current; - else - choice = english; - - if (!FL_CMDLINE(flags)) - newtWinMenu(_("Choose a Language"), - _("What language would you like to use during the " - "installation process?"), 40, 5, 5, 8, - langs, &choice, _("OK"), NULL); - - langPicked = langs[choice]; - for (i = 0; i < numLanguages; i++) { - if (!strcmp(langPicked, languages[i].lang)) { - *lang = languages[i].lc_all; - choice = i; - break; - } - } - - /* this can't happen */ - if (i == numLanguages) abort(); - - return setupLanguage(choice, 0); +int setLanguage(char *key, int forced) +{ + int i; + + if (!languages) + loadLanguageList(); + + for (i = 0; i < numLanguages; i++) { + if (!strcmp(languages[i].lc_all, key)) { + return setupLanguage(i, forced | !FL_KICKSTART(flags)); + } + } + + /* we didn't specify anything that's exactly in the lang-table. check + * against short forms and nicks */ + for (i = 0; i < numLanguages; i++) { + if (!strcmp(getLangShortForm(languages[i].lc_all), key)) { + return setupLanguage(i, forced | !FL_KICKSTART(flags)); + } + } + + for (i = 0; i < numLanguages; i++) { + if (!strcmp(getLangNick(languages[i].lc_all), key)) { + return setupLanguage(i, forced | !FL_KICKSTART(flags)); + } + } + + logMessage(ERROR, "unable to set to requested language %s", key); + return -1; } -void setKickstartLanguage(struct loaderData_s * loaderData, int argc, - char ** argv) { - if (argc < 2) { - logMessage(ERROR, "no argument passed to lang kickstart command"); - return; - } +int chooseLanguage(char **lang) +{ + int choice = 0; + char **langs; + int i; + int current = -1; + char *currentLangName = getenv("LANG"); + int numLangs = 0; + char *langPicked; + + if (!languages) + loadLanguageList(); + + langs = alloca(sizeof(*langs) * (numLanguages + 1)); + + for (i = 0; i < numLanguages; i++) { + if (!strncmp(languages[i].key, "en", 2)) + english = numLangs; + if (currentLangName && + !strcmp(languages[i].lang, currentLangName)) + current = numLangs; + + langs[numLangs++] = languages[i].lang; + } + + langs[numLangs] = NULL; + + if (current >= 0) + choice = current; + else + choice = english; + + if (!FL_CMDLINE(flags)) + newtWinMenu(_("Choose a Language"), + _("What language would you like to use during the " + "installation process?"), 40, 5, 5, 8, + langs, &choice, _("OK"), NULL); + + langPicked = langs[choice]; + for (i = 0; i < numLanguages; i++) { + if (!strcmp(langPicked, languages[i].lang)) { + *lang = languages[i].lc_all; + choice = i; + break; + } + } + + /* this can't happen */ + if (i == numLanguages) + abort(); + + return setupLanguage(choice, 0); +} - loaderData->lang = argv[1]; - loaderData->lang_set = 1; +void setKickstartLanguage(struct loaderData_s *loaderData, int argc, + char **argv) +{ + if (argc < 2) { + logMessage(ERROR, + "no argument passed to lang kickstart command"); + return; + } + + loaderData->lang = argv[1]; + loaderData->lang_set = 1; } /* vim:set sw=8 noet */ diff --git a/loader/lang.h b/loader/lang.h index 9044153..a1b75bd 100644 --- a/loader/lang.h +++ b/loader/lang.h @@ -26,17 +26,16 @@ #define N_(foo) (foo) struct langInfo { - char * lang, * key, * font, * lc_all, * keyboard; -} ; + char *lang, *key, *font, *lc_all, *keyboard; +}; - -int chooseLanguage(char ** lang); -char * translateString(char * str); -int setLanguage (char * key, int forced); +int chooseLanguage(char **lang); +char *translateString(char *str); +int setLanguage(char *key, int forced); int getLangInfo(struct langInfo **langs); -void setKickstartLanguage(struct loaderData_s * loaderData, int argc, - char ** argv); +void setKickstartLanguage(struct loaderData_s *loaderData, int argc, + char **argv); #endif /* _LANG_H_ */ diff --git a/loader/loader.c b/loader/loader.c index 97b0512..132e07a 100644 --- a/loader/loader.c +++ b/loader/loader.c @@ -63,7 +63,7 @@ #include "copy.h" #include "getparts.h" #include "loader.h" -#include "loadermisc.h" /* JKFIXME: functions here should be split out */ +#include "loadermisc.h" /* JKFIXME: functions here should be split out */ #include "log.h" #include "lang.h" #include "fwloader.h" @@ -103,7 +103,7 @@ /* maximum number of extra arguments that can be passed to the second stage */ #define MAX_EXTRA_ARGS 128 -static char * extraArgs[MAX_EXTRA_ARGS]; +static char *extraArgs[MAX_EXTRA_ARGS]; static int hasGraphicalOverride(); static int newtRunning = 0; @@ -124,14 +124,15 @@ int num_link_checks = 5; int post_link_sleep = 0; static pid_t init_pid = 1; -static int init_sig = SIGUSR1; /* default to shutdown=halt */ +static int init_sig = SIGUSR1; /* default to shutdown=halt */ static struct installMethod installMethods[] = { - { N_("Local CD/DVD"), 0, DEVICE_CDROM, mountCdromImage }, - { N_("Hard drive"), 0, DEVICE_DISK, mountHardDrive }, - { N_("NFS directory"), 1, DEVICE_NETWORK, mountNfsImage }, - { "URL", 1, DEVICE_NETWORK, mountUrlImage }, + {N_("Local CD/DVD"), 0, DEVICE_CDROM, mountCdromImage}, + {N_("Hard drive"), 0, DEVICE_DISK, mountHardDrive}, + {N_("NFS directory"), 1, DEVICE_NETWORK, mountNfsImage}, + {"URL", 1, DEVICE_NETWORK, mountUrlImage}, }; + static int numMethods = sizeof(installMethods) / sizeof(struct installMethod); static int expected_exit = 0; @@ -139,2152 +140,2297 @@ static int expected_exit = 0; static void doExit(int) __attribute__ ((noreturn)); static void doExit(int result) { - expected_exit = 1; - exit(result); + expected_exit = 1; + exit(result); } -void doSuspend(void) { - newtFinished(); - doExit(1); +void doSuspend(void) +{ + newtFinished(); + doExit(1); } -void doShell(void) { - pid_t child; - int status; - - newtSuspend(); - child = fork(); - - if (child == 0) { - if (execl("/sbin/bash", "/sbin/bash", "-i", NULL) == -1) { - logMessage(ERROR, "%s (%d): %m", __func__, __LINE__); - _exit(1); - } - } else if (child == -1) { - logMessage(ERROR, "%s (%d): %m", __func__, __LINE__); - newtResume(); - } else { - if (waitpid(child, &status, 0) == -1) { - logMessage(ERROR, "%s (%d): %m", __func__, __LINE__); - } - - newtResume(); - } +void doShell(void) +{ + pid_t child; + int status; + + newtSuspend(); + child = fork(); + + if (child == 0) { + if (execl("/sbin/bash", "/sbin/bash", "-i", NULL) == -1) { + logMessage(ERROR, "%s (%d): %m", __func__, __LINE__); + _exit(1); + } + } else if (child == -1) { + logMessage(ERROR, "%s (%d): %m", __func__, __LINE__); + newtResume(); + } else { + if (waitpid(child, &status, 0) == -1) { + logMessage(ERROR, "%s (%d): %m", __func__, __LINE__); + } + + newtResume(); + } } -void doGdbserver(struct loaderData_s *loaderData) { - int child, fd; - char *pid; - iface_t iface; - - /* If gdbserver is found, go ahead and run it on the loader process now - * before anything bad happens. - */ - if (loaderData->gdbServer && !access("/usr/bin/gdbserver", X_OK)) { - pid_t loaderPid = getpid(); - iface_init_iface_t(&iface); - - if (kickstartNetworkUp(loaderData, &iface)) { - logMessage(ERROR, "can't run gdbserver due to no network"); - return; - } - - checked_asprintf(&pid, "%d", loaderPid); - - if (!(child = fork())) { - logMessage(INFO, "starting gdbserver: %s %s %s %s", - "/usr/bin/gdbserver", "--attach", loaderData->gdbServer, - pid); - - fd = open("/dev/null", O_RDONLY); - close(STDIN_FILENO); - dup2(fd, STDIN_FILENO); - close(fd); - fd = open("/dev/null", O_WRONLY); - close(STDOUT_FILENO); - dup2(fd, STDOUT_FILENO); - close(STDERR_FILENO); - dup2(fd, STDERR_FILENO); - close(fd); - - if (execl("/usr/bin/gdbserver", "/usr/bin/gdbserver", "--attach", - loaderData->gdbServer, pid, NULL) == -1) - logMessage(ERROR, "error running gdbserver: %m"); - - _exit(1); - } - } +void doGdbserver(struct loaderData_s *loaderData) +{ + int child, fd; + char *pid; + iface_t iface; + + /* If gdbserver is found, go ahead and run it on the loader process now + * before anything bad happens. + */ + if (loaderData->gdbServer && !access("/usr/bin/gdbserver", X_OK)) { + pid_t loaderPid = getpid(); + iface_init_iface_t(&iface); + + if (kickstartNetworkUp(loaderData, &iface)) { + logMessage(ERROR, + "can't run gdbserver due to no network"); + return; + } + + checked_asprintf(&pid, "%d", loaderPid); + + if (!(child = fork())) { + logMessage(INFO, "starting gdbserver: %s %s %s %s", + "/usr/bin/gdbserver", "--attach", + loaderData->gdbServer, pid); + + fd = open("/dev/null", O_RDONLY); + close(STDIN_FILENO); + dup2(fd, STDIN_FILENO); + close(fd); + fd = open("/dev/null", O_WRONLY); + close(STDOUT_FILENO); + dup2(fd, STDOUT_FILENO); + close(STDERR_FILENO); + dup2(fd, STDERR_FILENO); + close(fd); + + if (execl + ("/usr/bin/gdbserver", "/usr/bin/gdbserver", + "--attach", loaderData->gdbServer, pid, + NULL) == -1) + logMessage(ERROR, + "error running gdbserver: %m"); + + _exit(1); + } + } } -void startNewt(void) { - if (!newtRunning) { - char *buf; - char *arch = getProductArch(); - - checked_asprintf(&buf, _("Welcome to %s for %s"), getProductName(), arch); - - newtInit(); - newtCls(); - newtDrawRootText(0, 0, buf); - free(buf); - - newtPushHelpLine(_(" <Tab>/<Alt-Tab> between elements | <Space> selects | <F12> next screen ")); - - newtRunning = 1; - if (!access("/bin/sh", X_OK)) - newtSetSuspendCallback((void *) doShell, NULL); - } +void startNewt(void) +{ + if (!newtRunning) { + char *buf; + char *arch = getProductArch(); + + checked_asprintf(&buf, _("Welcome to %s for %s"), + getProductName(), arch); + + newtInit(); + newtCls(); + newtDrawRootText(0, 0, buf); + free(buf); + + newtPushHelpLine(_ + (" <Tab>/<Alt-Tab> between elements | <Space> selects | <F12> next screen ")); + + newtRunning = 1; + if (!access("/bin/sh", X_OK)) + newtSetSuspendCallback((void *)doShell, NULL); + } } -void stopNewt(void) { - if (newtRunning) newtFinished(); - newtRunning = 0; +void stopNewt(void) +{ + if (newtRunning) + newtFinished(); + newtRunning = 0; } static gchar *productName = NULL; static gchar *productPath = NULL; static gchar *productArch = NULL; -static void initProductInfo(void) { - gchar *contents = NULL; - gchar **lines = NULL, **stamp = NULL; - GError *fileErr = NULL; - - if (!g_file_get_contents("/.buildstamp", &contents, NULL, &fileErr)) { - logMessage(ERROR, "error reading .buildstamp: %s", fileErr->message); - g_error_free(fileErr); - productName = g_strdup("anaconda"); - productArch = g_strdup("unknown architecture"); - productPath = g_strdup("anaconda"); - return; - } - - /* .buildstamp uses the first 3 lines in this format: - * STAMP.productArch - * productName - * productPath - */ - lines = g_strsplit(contents, "\n", 0); - g_free(contents); - - if ((lines != NULL) && (g_strv_length(lines) >= 3)) { - /* STAMP.productArch */ - stamp = g_strsplit(lines[0], ".", 0); - - if ((stamp != NULL) && (g_strv_length(stamp) == 2)) { - productArch = g_strdup(stamp[1]); - } else { - productArch = g_strdup("unknown architecture"); - } - - if (stamp) { - g_strfreev(stamp); - } - - productName = g_strdup(lines[1]); - productPath = g_strdup(lines[2]); - } else { - productName = g_strdup("anaconda"); - productArch = g_strdup("unknown architecture"); - productPath = g_strdup("anaconda"); - } - - if (lines) { - g_strfreev(lines); - } - - return; +static void initProductInfo(void) +{ + gchar *contents = NULL; + gchar **lines = NULL, **stamp = NULL; + GError *fileErr = NULL; + + if (!g_file_get_contents("/.buildstamp", &contents, NULL, &fileErr)) { + logMessage(ERROR, "error reading .buildstamp: %s", + fileErr->message); + g_error_free(fileErr); + productName = g_strdup("anaconda"); + productArch = g_strdup("unknown architecture"); + productPath = g_strdup("anaconda"); + return; + } + + /* .buildstamp uses the first 3 lines in this format: + * STAMP.productArch + * productName + * productPath + */ + lines = g_strsplit(contents, "\n", 0); + g_free(contents); + + if ((lines != NULL) && (g_strv_length(lines) >= 3)) { + /* STAMP.productArch */ + stamp = g_strsplit(lines[0], ".", 0); + + if ((stamp != NULL) && (g_strv_length(stamp) == 2)) { + productArch = g_strdup(stamp[1]); + } else { + productArch = g_strdup("unknown architecture"); + } + + if (stamp) { + g_strfreev(stamp); + } + + productName = g_strdup(lines[1]); + productPath = g_strdup(lines[2]); + } else { + productName = g_strdup("anaconda"); + productArch = g_strdup("unknown architecture"); + productPath = g_strdup("anaconda"); + } + + if (lines) { + g_strfreev(lines); + } + + return; } -char * getProductName(void) { - if (!productName) { - initProductInfo(); - } - return productName; +char *getProductName(void) +{ + if (!productName) { + initProductInfo(); + } + return productName; } -char * getProductArch(void) { - if (!productArch) { - initProductInfo(); - } - return productArch; +char *getProductArch(void) +{ + if (!productArch) { + initProductInfo(); + } + return productArch; } -char * getProductPath(void) { - if (!productPath) { - initProductInfo(); - } - return productPath; +char *getProductPath(void) +{ + if (!productPath) { + initProductInfo(); + } + return productPath; } -void initializeConsole() { - /* enable UTF-8 console */ - setenv("LANG","en_US.UTF-8",1); - printf("\033%%G"); - fflush(stdout); +void initializeConsole() +{ + /* enable UTF-8 console */ + setenv("LANG", "en_US.UTF-8", 1); + printf("\033%%G"); + fflush(stdout); - isysLoadFont(); - isysSetUnicodeKeymap(); + isysLoadFont(); + isysSetUnicodeKeymap(); } /* fbcon is buggy and resets our color palette if we allocate a terminal * after initializing it, so we initialize 9 of them before we need them. * If it doesn't work, the user gets to suffer through having an ugly palette, * but things are still usable. */ -static void initializeTtys(void) { - int fd, n; - char dev[] = "/dev/ttyX"; - - for (n = 9; n > 0; n--) { - sprintf(dev, "/dev/tty%d", n); - mknod(dev, 0600 | S_IFCHR, makedev(4, n)); - fd = open(dev, O_RDWR|O_NOCTTY); - if (fd >= 0) { - ioctl(fd, VT_ACTIVATE, n); - if (n == 1) - ioctl(fd, VT_WAITACTIVE, n); - close(fd); - } else - logMessage(ERROR, "failed to initialize %s", dev); - } +static void initializeTtys(void) +{ + int fd, n; + char dev[] = "/dev/ttyX"; + + for (n = 9; n > 0; n--) { + sprintf(dev, "/dev/tty%d", n); + mknod(dev, 0600 | S_IFCHR, makedev(4, n)); + fd = open(dev, O_RDWR | O_NOCTTY); + if (fd >= 0) { + ioctl(fd, VT_ACTIVATE, n); + if (n == 1) + ioctl(fd, VT_WAITACTIVE, n); + close(fd); + } else + logMessage(ERROR, "failed to initialize %s", dev); + } } -static void spawnShell(void) { - pid_t pid; - - if (FL_SERIAL(flags) || FL_NOSHELL(flags)) { - logMessage(INFO, "not spawning a shell"); - return; - } else if (access("/bin/sh", X_OK)) { - logMessage(ERROR, "cannot open shell - /bin/sh doesn't exist"); - return; - } - - if (!(pid = fork())) { - int fd; - - fd = open("/dev/tty2", O_RDWR|O_NOCTTY); - if (fd < 0) { - logMessage(ERROR, "cannot open /dev/tty2 -- no shell will be provided"); - return; +static void spawnShell(void) +{ + pid_t pid; + + if (FL_SERIAL(flags) || FL_NOSHELL(flags)) { + logMessage(INFO, "not spawning a shell"); + return; + } else if (access("/bin/sh", X_OK)) { + logMessage(ERROR, "cannot open shell - /bin/sh doesn't exist"); + return; } - dup2(fd, 0); - dup2(fd, 1); - dup2(fd, 2); - - close(fd); - setsid(); + if (!(pid = fork())) { + int fd; + + fd = open("/dev/tty2", O_RDWR | O_NOCTTY); + if (fd < 0) { + logMessage(ERROR, + "cannot open /dev/tty2 -- no shell will be provided"); + return; + } + + dup2(fd, 0); + dup2(fd, 1); + dup2(fd, 2); + + close(fd); + setsid(); + + /* enable UTF-8 console */ + printf("\033%%G"); + fflush(stdout); + isysLoadFont(); + + if (ioctl(0, TIOCSCTTY, NULL)) { + logMessage(ERROR, "could not set new controlling tty"); + } + + signal(SIGINT, SIG_DFL); + signal(SIGTSTP, SIG_DFL); + + if (!access("/tmp/updates/pyrc.py", R_OK | X_OK)) + setenv("PYTHONSTARTUP", "/tmp/updates/pyrc.py", 1); + else if (!access + ("/usr/lib/anaconda-runtime/pyrc.py", R_OK | X_OK)) + setenv("PYTHONSTARTUP", + "/usr/lib/anaconda-runtime/pyrc.py", 1); + setenv("LD_LIBRARY_PATH", LIBPATH, 1); + setenv("LANG", "C", 1); + + if (execl("/bin/sh", "-/bin/sh", NULL) == -1) { + logMessage(CRITICAL, "exec of /bin/sh failed: %m"); + exit(1); + } + } - /* enable UTF-8 console */ - printf("\033%%G"); - fflush(stdout); - isysLoadFont(); - - if (ioctl(0, TIOCSCTTY, NULL)) { - logMessage(ERROR, "could not set new controlling tty"); - } - - signal(SIGINT, SIG_DFL); - signal(SIGTSTP, SIG_DFL); - - if (!access("/tmp/updates/pyrc.py", R_OK|X_OK)) - setenv("PYTHONSTARTUP", "/tmp/updates/pyrc.py", 1); - else if (!access("/usr/lib/anaconda-runtime/pyrc.py", R_OK|X_OK)) - setenv("PYTHONSTARTUP", "/usr/lib/anaconda-runtime/pyrc.py", 1); - setenv("LD_LIBRARY_PATH", LIBPATH, 1); - setenv("LANG", "C", 1); - - if (execl("/bin/sh", "-/bin/sh", NULL) == -1) { - logMessage(CRITICAL, "exec of /bin/sh failed: %m"); - exit(1); - } - } - - return; + return; } - -static void copyWarnFn (char *msg) { - logMessage(WARNING, msg); +static void copyWarnFn(char *msg) +{ + logMessage(WARNING, msg); } -static void copyErrorFn (char *msg) { - newtWinMessage(_("Error"), _("OK"), _(msg)); +static void copyErrorFn(char *msg) +{ + newtWinMessage(_("Error"), _("OK"), _(msg)); } -void loadUpdates(struct loaderData_s *loaderData) { - char *device = NULL, *part = NULL, *buf; - char **devNames = NULL; - enum { UPD_DEVICE, UPD_PART, UPD_PROMPT, UPD_LOAD, UPD_DONE } stage = UPD_DEVICE; - int rc, num = 0; - int dir = 1; - - while (stage != UPD_DONE) { - switch (stage) { - case UPD_DEVICE: { - rc = getRemovableDevices(&devNames); - if (rc == 0) - return; - - /* we don't need to ask which to use if they only have one */ - if (rc == 1) { - device = strdup(devNames[0]); - free(devNames); - devNames = NULL; - if (dir == -1) - return; - - stage = UPD_PART; - break; - } - dir = 1; - - startNewt(); - rc = newtWinMenu(_("Update Disk Source"), - _("You have multiple devices which could serve " - "as sources for an update disk. Which would " - "you like to use?"), 40, 10, 10, - rc < 6 ? rc : 6, devNames, - &num, _("OK"), _("Cancel"), NULL); - - if (rc == 2) { - free(devNames); - devNames = NULL; - return; - } - - device = strdup(devNames[num]); - free(devNames); - devNames = NULL; - stage = UPD_PART; - } - - case UPD_PART: { - char ** part_list = getPartitionsList(device); - int nump = 0, num = 0; - - if (part != NULL) { - free(part); - part = NULL; - } - - if ((nump = lenPartitionsList(part_list)) == 0) { - if (dir == -1) { - stage = UPD_DEVICE; - } else { - checked_asprintf(&part, "/dev/%s", device); - stage = UPD_PROMPT; - } - - break; - } - dir = 1; - - startNewt(); - rc = newtWinMenu(_("Update Disk Source"), - _("There are multiple partitions on this device " - "which could contain the update disk image. " - "Which would you like to use?"), 40, 10, 10, - nump < 6 ? nump : 6, part_list, &num, _("OK"), - _("Back"), NULL); - - if (rc == 2) { - freePartitionsList(part_list); - stage = UPD_DEVICE; - dir = -1; - break; - } - - part = strdup(part_list[num]); - stage = UPD_LOAD; - } - - case UPD_PROMPT: - checked_asprintf(&buf, _("Insert your updates disk into %s and " - "press \"OK\" to continue."), part); - - rc = newtWinChoice(_("Updates Disk"), _("OK"), _("Back"), buf); - free(buf); - buf = NULL; - - if (rc == 2) { - stage = UPD_PART; - dir = -1; - break; - } - - stage = UPD_LOAD; - break; - - case UPD_LOAD: - logMessage(INFO, "UPDATES device is %s", part); - - if (doPwMount(part, "/tmp/update-disk", "auto", "ro", NULL)) { - newtWinMessage(_("Error"), _("OK"), - _("Failed to mount updates disk")); - stage = UPD_PROMPT; - break; - } else { - /* Copy everything to /tmp/updates so we can unmount the disk */ - winStatus(40, 3, _("Updates"), _("Reading anaconda updates")); - if (!copyDirectory("/tmp/update-disk", "/tmp/updates", copyWarnFn, - copyErrorFn)) { - dir = 1; - stage = UPD_DONE; - } - - newtPopWindow(); - umount("/tmp/update-disk"); - } - - case UPD_DONE: - break; - } - } - - return; +void loadUpdates(struct loaderData_s *loaderData) +{ + char *device = NULL, *part = NULL, *buf; + char **devNames = NULL; + enum { UPD_DEVICE, UPD_PART, UPD_PROMPT, UPD_LOAD, UPD_DONE } stage = + UPD_DEVICE; + int rc, num = 0; + int dir = 1; + + while (stage != UPD_DONE) { + switch (stage) { + case UPD_DEVICE:{ + rc = getRemovableDevices(&devNames); + if (rc == 0) + return; + + /* we don't need to ask which to use if they only have one */ + if (rc == 1) { + device = strdup(devNames[0]); + free(devNames); + devNames = NULL; + if (dir == -1) + return; + + stage = UPD_PART; + break; + } + dir = 1; + + startNewt(); + rc = newtWinMenu(_("Update Disk Source"), + _ + ("You have multiple devices which could serve " + "as sources for an update disk. Which would " + "you like to use?"), 40, 10, + 10, rc < 6 ? rc : 6, devNames, + &num, _("OK"), _("Cancel"), + NULL); + + if (rc == 2) { + free(devNames); + devNames = NULL; + return; + } + + device = strdup(devNames[num]); + free(devNames); + devNames = NULL; + stage = UPD_PART; + } + + case UPD_PART:{ + char **part_list = getPartitionsList(device); + int nump = 0, num = 0; + + if (part != NULL) { + free(part); + part = NULL; + } + + if ((nump = lenPartitionsList(part_list)) == 0) { + if (dir == -1) { + stage = UPD_DEVICE; + } else { + checked_asprintf(&part, + "/dev/%s", + device); + stage = UPD_PROMPT; + } + + break; + } + dir = 1; + + startNewt(); + rc = newtWinMenu(_("Update Disk Source"), + _ + ("There are multiple partitions on this device " + "which could contain the update disk image. " + "Which would you like to use?"), + 40, 10, 10, + nump < 6 ? nump : 6, part_list, + &num, _("OK"), _("Back"), + NULL); + + if (rc == 2) { + freePartitionsList(part_list); + stage = UPD_DEVICE; + dir = -1; + break; + } + + part = strdup(part_list[num]); + stage = UPD_LOAD; + } + + case UPD_PROMPT: + checked_asprintf(&buf, + _ + ("Insert your updates disk into %s and " + "press \"OK\" to continue."), part); + + rc = newtWinChoice(_("Updates Disk"), _("OK"), + _("Back"), buf); + free(buf); + buf = NULL; + + if (rc == 2) { + stage = UPD_PART; + dir = -1; + break; + } + + stage = UPD_LOAD; + break; + + case UPD_LOAD: + logMessage(INFO, "UPDATES device is %s", part); + + if (doPwMount + (part, "/tmp/update-disk", "auto", "ro", NULL)) { + newtWinMessage(_("Error"), _("OK"), + _ + ("Failed to mount updates disk")); + stage = UPD_PROMPT; + break; + } else { + /* Copy everything to /tmp/updates so we can unmount the disk */ + winStatus(40, 3, _("Updates"), + _("Reading anaconda updates")); + if (!copyDirectory + ("/tmp/update-disk", "/tmp/updates", + copyWarnFn, copyErrorFn)) { + dir = 1; + stage = UPD_DONE; + } + + newtPopWindow(); + umount("/tmp/update-disk"); + } + + case UPD_DONE: + break; + } + } + + return; } -static char *newUpdatesLocation(const char *origLocation) { - const char *location; - char *retval = NULL; - newtComponent f, okay, cancel, answer, locationEntry; - newtGrid grid, buttons; +static char *newUpdatesLocation(const char *origLocation) +{ + const char *location; + char *retval = NULL; + newtComponent f, okay, cancel, answer, locationEntry; + newtGrid grid, buttons; - startNewt(); + startNewt(); - locationEntry = newtEntry(-1, -1, NULL, 60, &location, NEWT_FLAG_SCROLL); - newtEntrySet(locationEntry, origLocation, 1); + locationEntry = + newtEntry(-1, -1, NULL, 60, &location, NEWT_FLAG_SCROLL); + newtEntrySet(locationEntry, origLocation, 1); - /* button bar at the bottom of the window */ - buttons = newtButtonBar(_("OK"), &okay, _("Cancel"), &cancel, NULL); + /* button bar at the bottom of the window */ + buttons = newtButtonBar(_("OK"), &okay, _("Cancel"), &cancel, NULL); - grid = newtCreateGrid(1, 3); + grid = newtCreateGrid(1, 3); - newtGridSetField(grid, 0, 0, NEWT_GRID_COMPONENT, - newtTextboxReflowed(-1, -1, _("Unable to download the updates image. Please modify the updates location below or press Cancel to proceed without updates.."), 60, 0, 0, 0), - 0, 0, 0, 0, NEWT_ANCHOR_LEFT, 0); - newtGridSetField(grid, 0, 1, NEWT_GRID_COMPONENT, locationEntry, - 0, 1, 0, 0, NEWT_ANCHOR_LEFT, 0); - newtGridSetField(grid, 0, 2, NEWT_GRID_SUBGRID, buttons, - 0, 1, 0, 0, 0, NEWT_GRID_FLAG_GROWX); + newtGridSetField(grid, 0, 0, NEWT_GRID_COMPONENT, + newtTextboxReflowed(-1, -1, + _ + ("Unable to download the updates image. Please modify the updates location below or press Cancel to proceed without updates.."), + 60, 0, 0, 0), 0, 0, 0, 0, + NEWT_ANCHOR_LEFT, 0); + newtGridSetField(grid, 0, 1, NEWT_GRID_COMPONENT, locationEntry, 0, 1, + 0, 0, NEWT_ANCHOR_LEFT, 0); + newtGridSetField(grid, 0, 2, NEWT_GRID_SUBGRID, buttons, 0, 1, 0, 0, 0, + NEWT_GRID_FLAG_GROWX); - f = newtForm(NULL, NULL, 0); - newtGridAddComponentsToForm(grid, f, 1); - newtGridWrappedWindow(grid, _("Error downloading updates image")); - newtGridFree(grid, 1); + f = newtForm(NULL, NULL, 0); + newtGridAddComponentsToForm(grid, f, 1); + newtGridWrappedWindow(grid, _("Error downloading updates image")); + newtGridFree(grid, 1); - /* run the form */ - answer = newtRunForm(f); + /* run the form */ + answer = newtRunForm(f); - if (answer != cancel) - retval = strdup(location); + if (answer != cancel) + retval = strdup(location); - newtFormDestroy(f); - newtPopWindow(); + newtFormDestroy(f); + newtPopWindow(); - return retval; + return retval; } -static int loadUpdatesFromRemote(char * url, struct loaderData_s * loaderData) { - int rc = getFileFromUrl(url, "/tmp/updates.img", loaderData); +static int loadUpdatesFromRemote(char *url, struct loaderData_s *loaderData) +{ + int rc = getFileFromUrl(url, "/tmp/updates.img", loaderData); - if (rc != 0) { - char *newLocation = newUpdatesLocation(url); + if (rc != 0) { + char *newLocation = newUpdatesLocation(url); - if (!newLocation) - return rc; - else - return loadUpdatesFromRemote(newLocation, loaderData); - } + if (!newLocation) + return rc; + else + return loadUpdatesFromRemote(newLocation, loaderData); + } - copyUpdatesImg("/tmp/updates.img"); - unlink("/tmp/updates.img"); - return 0; + copyUpdatesImg("/tmp/updates.img"); + unlink("/tmp/updates.img"); + return 0; } -static void writeVNCPasswordFile(char *pfile, char *password) { - FILE *f; +static void writeVNCPasswordFile(char *pfile, char *password) +{ + FILE *f; - f = fopen(pfile, "w+"); - fprintf(f, "%s\n", password); - fclose(f); + f = fopen(pfile, "w+"); + fprintf(f, "%s\n", password); + fclose(f); } /* XXX: read information from /etc/sysconfig/network-scripts/ifcfg-$INTERFACE * (written by linuxrc), the linuxrc mess should be firing up NM too */ -static void readNetInfo(struct loaderData_s ** ld) { - int i; - struct loaderData_s * loaderData = *ld; - DIR *dp = NULL; - FILE *f = NULL; - struct dirent *ent = NULL; - char *cfgfile = NULL; - int bufsiz = 100; - char buf[bufsiz]; - char *vname = NULL; - char *vparm = NULL; - - /* when this function is called, we can assume only one network device - * config file has been written to /etc/sysconfig/network-scripts, so - * find it and read it - */ - dp = opendir("/etc/sysconfig/network-scripts"); - if (dp == NULL) { - return; - } - - while ((ent = readdir(dp)) != NULL) { - if (!strncmp(ent->d_name, "ifcfg-", 6)) { - checked_asprintf(&cfgfile, "/etc/sysconfig/network-scripts/%s", - ent->d_name); - - break; - } - } - - if (dp != NULL) { - if (closedir(dp) == -1) { - logMessage(DEBUGLVL, "%s (%d): %m", __func__, __LINE__); - abort(); - } - } - - if (cfgfile == NULL) { - logMessage(DEBUGLVL, "no ifcfg files found in /etc/sysconfig/network-scripts"); - return; - } - - - if ((f = fopen(cfgfile, "r")) == NULL) { - logMessage(DEBUGLVL, "%s (%d): %m", __func__, __LINE__); - free(cfgfile); - return; - } - - if ((vname = (char *) malloc(sizeof(char) * 15)) == NULL) { - logMessage(DEBUGLVL, "%s (%d): %m", __func__, __LINE__); - abort(); - } - - if ((vparm = (char *) malloc(sizeof(char) * 85)) == NULL) { - logMessage(DEBUGLVL, "%s (%d): %m", __func__, __LINE__); - abort(); - } - - /* make sure everything is NULL before we begin copying info */ - loaderData->ipv4 = NULL; - loaderData->netmask = NULL; - loaderData->gateway = NULL; - loaderData->dns = NULL; - loaderData->peerid = NULL; - loaderData->subchannels = NULL; - loaderData->portname = NULL; - loaderData->nettype = NULL; - loaderData->ctcprot = NULL; - loaderData->layer2 = NULL; - loaderData->portno = NULL; - loaderData->macaddr = NULL; - - /* - * The /tmp/netinfo file is written out by /sbin/init on s390x (which is - * really the linuxrc.s390 script). It's a shell-sourcable file with - * various system settings needing for the system instance. - * - * The goal of this function is to read in only the network settings - * and populate the loaderData structure. - */ - while(fgets(buf, bufsiz, f)) { - /* trim whitespace from end */ - i = 0; - while (!isspace(buf[i]) && i < (bufsiz-1)) - i++; - buf[i] = '\0'; - - /* break up var name and value */ - if (strstr(buf, "=")) { - vname = strtok(buf, "="); - if (vname == NULL) - continue; - - vparm = strtok(NULL, "="); - if (vparm == NULL) - continue; - - if (!strncmp(vname, "IPADDR", 6)) - loaderData->ipv4 = strdup(vparm); - - if (!strncmp(vname, "NETMASK", 7)) - loaderData->netmask = strdup(vparm); - - if (!strncmp(vname, "GATEWAY", 7)) - loaderData->gateway = strdup(vparm); - - if (!strncmp(vname, "DNS", 3)) - loaderData->dns = strdup(vparm); - - if (!strncmp(vname, "MTU", 3)) { - errno = 0; - loaderData->mtu = strtol(vparm, NULL, 10); - - if ((errno == ERANGE && (loaderData->mtu == LONG_MIN || - loaderData->mtu == LONG_MAX)) || - (errno != 0 && loaderData->mtu == 0)) { - logMessage(ERROR, "%s: %d: %m", __func__, __LINE__); - abort(); - } - } - - if (!strncmp(vname, "PEERID", 6)) - loaderData->peerid = strdup(vparm); - - if (!strncmp(vname, "SUBCHANNELS", 12)) - loaderData->subchannels = strdup(vparm); - - if (!strncmp(vname, "PORTNAME", 8)) - loaderData->portname = strdup(vparm); - - if (!strncmp(vname, "NETTYPE", 7)) - loaderData->nettype = strdup(vparm); - - if (!strncmp(vname, "CTCPROT", 7)) - loaderData->ctcprot = strdup(vparm); - - if (!strncmp(vname, "LAYER2", 6)) - loaderData->layer2 = strdup(vparm); - - if (!strncmp(vname, "PORTNO", 6)) - loaderData->portno = strdup(vparm); - - if (!strncmp(vname, "MACADDR", 7)) - loaderData->macaddr = strdup(vparm); - - if (!strncmp(vname, "HOSTNAME", 8)) - loaderData->hostname = strdup(vparm); - } - } - - if (loaderData->ipv4 && loaderData->netmask) { - flags |= LOADER_FLAGS_HAVE_CMSCONF; - } - - if (fclose(f) == -1) { - logMessage(ERROR, "%s: %d: %m", __func__, __LINE__); - abort(); - } - - if (cfgfile != NULL) { - free(cfgfile); - } - - return; +static void readNetInfo(struct loaderData_s **ld) +{ + int i; + struct loaderData_s *loaderData = *ld; + DIR *dp = NULL; + FILE *f = NULL; + struct dirent *ent = NULL; + char *cfgfile = NULL; + int bufsiz = 100; + char buf[bufsiz]; + char *vname = NULL; + char *vparm = NULL; + + /* when this function is called, we can assume only one network device + * config file has been written to /etc/sysconfig/network-scripts, so + * find it and read it + */ + dp = opendir("/etc/sysconfig/network-scripts"); + if (dp == NULL) { + return; + } + + while ((ent = readdir(dp)) != NULL) { + if (!strncmp(ent->d_name, "ifcfg-", 6)) { + checked_asprintf(&cfgfile, + "/etc/sysconfig/network-scripts/%s", + ent->d_name); + + break; + } + } + + if (dp != NULL) { + if (closedir(dp) == -1) { + logMessage(DEBUGLVL, "%s (%d): %m", __func__, __LINE__); + abort(); + } + } + + if (cfgfile == NULL) { + logMessage(DEBUGLVL, + "no ifcfg files found in /etc/sysconfig/network-scripts"); + return; + } + + if ((f = fopen(cfgfile, "r")) == NULL) { + logMessage(DEBUGLVL, "%s (%d): %m", __func__, __LINE__); + free(cfgfile); + return; + } + + if ((vname = (char *)malloc(sizeof(char) * 15)) == NULL) { + logMessage(DEBUGLVL, "%s (%d): %m", __func__, __LINE__); + abort(); + } + + if ((vparm = (char *)malloc(sizeof(char) * 85)) == NULL) { + logMessage(DEBUGLVL, "%s (%d): %m", __func__, __LINE__); + abort(); + } + + /* make sure everything is NULL before we begin copying info */ + loaderData->ipv4 = NULL; + loaderData->netmask = NULL; + loaderData->gateway = NULL; + loaderData->dns = NULL; + loaderData->peerid = NULL; + loaderData->subchannels = NULL; + loaderData->portname = NULL; + loaderData->nettype = NULL; + loaderData->ctcprot = NULL; + loaderData->layer2 = NULL; + loaderData->portno = NULL; + loaderData->macaddr = NULL; + + /* + * The /tmp/netinfo file is written out by /sbin/init on s390x (which is + * really the linuxrc.s390 script). It's a shell-sourcable file with + * various system settings needing for the system instance. + * + * The goal of this function is to read in only the network settings + * and populate the loaderData structure. + */ + while (fgets(buf, bufsiz, f)) { + /* trim whitespace from end */ + i = 0; + while (!isspace(buf[i]) && i < (bufsiz - 1)) + i++; + buf[i] = '\0'; + + /* break up var name and value */ + if (strstr(buf, "=")) { + vname = strtok(buf, "="); + if (vname == NULL) + continue; + + vparm = strtok(NULL, "="); + if (vparm == NULL) + continue; + + if (!strncmp(vname, "IPADDR", 6)) + loaderData->ipv4 = strdup(vparm); + + if (!strncmp(vname, "NETMASK", 7)) + loaderData->netmask = strdup(vparm); + + if (!strncmp(vname, "GATEWAY", 7)) + loaderData->gateway = strdup(vparm); + + if (!strncmp(vname, "DNS", 3)) + loaderData->dns = strdup(vparm); + + if (!strncmp(vname, "MTU", 3)) { + errno = 0; + loaderData->mtu = strtol(vparm, NULL, 10); + + if ((errno == ERANGE + && (loaderData->mtu == LONG_MIN + || loaderData->mtu == LONG_MAX)) + || (errno != 0 && loaderData->mtu == 0)) { + logMessage(ERROR, "%s: %d: %m", + __func__, __LINE__); + abort(); + } + } + + if (!strncmp(vname, "PEERID", 6)) + loaderData->peerid = strdup(vparm); + + if (!strncmp(vname, "SUBCHANNELS", 12)) + loaderData->subchannels = strdup(vparm); + + if (!strncmp(vname, "PORTNAME", 8)) + loaderData->portname = strdup(vparm); + + if (!strncmp(vname, "NETTYPE", 7)) + loaderData->nettype = strdup(vparm); + + if (!strncmp(vname, "CTCPROT", 7)) + loaderData->ctcprot = strdup(vparm); + + if (!strncmp(vname, "LAYER2", 6)) + loaderData->layer2 = strdup(vparm); + + if (!strncmp(vname, "PORTNO", 6)) + loaderData->portno = strdup(vparm); + + if (!strncmp(vname, "MACADDR", 7)) + loaderData->macaddr = strdup(vparm); + + if (!strncmp(vname, "HOSTNAME", 8)) + loaderData->hostname = strdup(vparm); + } + } + + if (loaderData->ipv4 && loaderData->netmask) { + flags |= LOADER_FLAGS_HAVE_CMSCONF; + } + + if (fclose(f) == -1) { + logMessage(ERROR, "%s: %d: %m", __func__, __LINE__); + abort(); + } + + if (cfgfile != NULL) { + free(cfgfile); + } + + return; } /* parse anaconda or pxelinux-style ip= arguments * pxelinux format: ip=<client-ip>:<boot-server-ip>:<gw-ip>:<netmask> * anaconda format: ip=<client-ip> netmask=<netmask> gateway=<gw-ip> */ -static void parseCmdLineIp(struct loaderData_s * loaderData, char *argv) +static void parseCmdLineIp(struct loaderData_s *loaderData, char *argv) { - /* Detect pxelinux */ - if (strstr(argv, ":") != NULL) { - char *start, *end; - - /* IP */ - start = argv + 3; - end = strstr(start, ":"); - loaderData->ipv4 = strndup(start, end-start); - loaderData->ipinfo_set = 1; - - /* Boot server */ - if (end + 1 == '\0') - return; - start = end + 1; - end = strstr(start, ":"); - if (end == NULL) - return; - - /* Gateway */ - if (end + 1 == '\0') - return; - start = end + 1; - end = strstr(start, ":"); - if (end == NULL) { - loaderData->gateway = strdup (start); - return; - } else { - loaderData->gateway = strndup(start, end-start); - } - - /* Netmask */ - if (end + 1 == '\0') - return; - start = end + 1; - loaderData->netmask = strdup(start); - } else { - loaderData->ipv4 = strdup(argv + 3); - loaderData->ipinfo_set = 1; - } - - if (loaderData->ipinfo_set) - flags |= LOADER_FLAGS_IP_PARAM; + /* Detect pxelinux */ + if (strstr(argv, ":") != NULL) { + char *start, *end; + + /* IP */ + start = argv + 3; + end = strstr(start, ":"); + loaderData->ipv4 = strndup(start, end - start); + loaderData->ipinfo_set = 1; + + /* Boot server */ + if (end + 1 == '\0') + return; + start = end + 1; + end = strstr(start, ":"); + if (end == NULL) + return; + + /* Gateway */ + if (end + 1 == '\0') + return; + start = end + 1; + end = strstr(start, ":"); + if (end == NULL) { + loaderData->gateway = strdup(start); + return; + } else { + loaderData->gateway = strndup(start, end - start); + } + + /* Netmask */ + if (end + 1 == '\0') + return; + start = end + 1; + loaderData->netmask = strdup(start); + } else { + loaderData->ipv4 = strdup(argv + 3); + loaderData->ipinfo_set = 1; + } + + if (loaderData->ipinfo_set) + flags |= LOADER_FLAGS_IP_PARAM; } #ifdef ENABLE_IPV6 /* * parse anaconda ipv6= arguments */ -static void parseCmdLineIpv6(struct loaderData_s * loaderData, char *argv) +static void parseCmdLineIpv6(struct loaderData_s *loaderData, char *argv) { - /* right now we only accept ipv6= arguments equal to: - * dhcp DHCPv6 call - * auto RFC 2461 neighbor discovery - */ - loaderData->ipv6 = NULL; - - if (!strncmp(str2lower(argv), "ipv6=dhcp", 9)) { - loaderData->ipv6 = strdup("dhcp"); - } else if (!strncmp(str2lower(argv), "ipv6=auto", 9)) { - loaderData->ipv6 = strdup("auto"); - } - - if (loaderData->ipv6 != NULL) { - loaderData->ipv6info_set = 1; - flags |= LOADER_FLAGS_IPV6_PARAM; - } - - return; + /* right now we only accept ipv6= arguments equal to: + * dhcp DHCPv6 call + * auto RFC 2461 neighbor discovery + */ + loaderData->ipv6 = NULL; + + if (!strncmp(str2lower(argv), "ipv6=dhcp", 9)) { + loaderData->ipv6 = strdup("dhcp"); + } else if (!strncmp(str2lower(argv), "ipv6=auto", 9)) { + loaderData->ipv6 = strdup("auto"); + } + + if (loaderData->ipv6 != NULL) { + loaderData->ipv6info_set = 1; + flags |= LOADER_FLAGS_IPV6_PARAM; + } + + return; } #endif -static long argToLong(char *arg, int offset) { - long retval; +static long argToLong(char *arg, int offset) +{ + long retval; - errno = 0; + errno = 0; - retval = strtol(arg+offset, NULL, 10); - if ((errno == ERANGE && (retval == LONG_MIN || retval == LONG_MAX)) || - (errno != 0 && retval == 0)) { - logMessage(ERROR, "%s: %d: %m", __func__, __LINE__); - abort(); - } + retval = strtol(arg + offset, NULL, 10); + if ((errno == ERANGE && (retval == LONG_MIN || retval == LONG_MAX)) || + (errno != 0 && retval == 0)) { + logMessage(ERROR, "%s: %d: %m", __func__, __LINE__); + abort(); + } - return retval; + return retval; } /* parses /proc/cmdline for any arguments which are important to us. * NOTE: in test mode, can specify a cmdline with --cmdline */ -static void parseCmdLineFlags(struct loaderData_s * loaderData, - char * cmdLine) { - int fd; - char buf[1024]; - int len; - gint argc = 0; - gchar **argv = NULL; - GError *optErr = NULL; - int numExtraArgs = 0; - int i; - char *front, *stage2param = NULL; - - /* we want to default to graphical and allow override with 'text' */ - flags |= LOADER_FLAGS_GRAPHICAL; - - /* if we have any explicit cmdline (probably test mode), we don't want - * to parse /proc/cmdline */ - if (!cmdLine) { - if ((fd = open("/proc/cmdline", O_RDONLY)) < 0) return; - len = read(fd, buf, sizeof(buf) - 1); - close(fd); - if (len <= 0) { - logMessage(INFO, "kernel command line was empty"); - return; - } - - buf[len] = '\0'; - cmdLine = buf; - } - - logMessage(INFO, "kernel command line: %s", cmdLine); - - if (!g_shell_parse_argv(cmdLine, &argc, &argv, &optErr)) { - g_error_free(optErr); - return; - } - - for (i=0; i < argc; i++) { - if (!strcasecmp(argv[i], "askmethod")) - flags |= LOADER_FLAGS_ASKMETHOD; - else if (!strcasecmp(argv[i], "asknetwork")) - flags |= LOADER_FLAGS_ASKNETWORK; - else if (!strcasecmp(argv[i], "noshell")) - flags |= LOADER_FLAGS_NOSHELL; - else if (!strcasecmp(argv[i], "nokill")) - flags |= LOADER_FLAGS_NOKILL; - else if (!strcasecmp(argv[i], "mediacheck")) - flags |= LOADER_FLAGS_MEDIACHECK; - else if (!strcasecmp(argv[i], "allowwireless")) - flags |= LOADER_FLAGS_ALLOW_WIRELESS; - else if (!strcasecmp(argv[i], "telnet")) - flags |= LOADER_FLAGS_TELNETD; - else if (!strcasecmp(argv[i], "noprobe")) - flags |= LOADER_FLAGS_NOPROBE; - else if (!strcasecmp(argv[i], "text")) { - logMessage(INFO, "text mode forced from cmdline"); - flags |= LOADER_FLAGS_TEXT; - flags &= ~LOADER_FLAGS_GRAPHICAL; - } - else if (!strcasecmp(argv[i], "graphical")) { - logMessage(INFO, "graphical mode forced from cmdline"); - flags |= LOADER_FLAGS_GRAPHICAL; - } else if (!strcasecmp(argv[i], "cmdline")) { - logMessage(INFO, "cmdline mode forced from cmdline"); - flags |= LOADER_FLAGS_CMDLINE; - } else if (!strncasecmp(argv[i], "updates=", 8)) - loaderData->updatessrc = strdup(argv[i] + 8); - else if (!strncasecmp(argv[i], "updates", 7)) - flags |= LOADER_FLAGS_UPDATES; - else if (!strncasecmp(argv[i], "dogtail=", 8)) - loaderData->dogtailurl = strdup(argv[i] + 8); - else if (!strncasecmp(argv[i], "dd=", 3) || - !strncasecmp(argv[i], "driverdisk=", 11)) { - loaderData->ddsrc = strdup(argv[i] + - (argv[i][1] == 'r' ? 11 : 3)); - } - else if (!strcasecmp(argv[i], "dd") || - !strcasecmp(argv[i], "driverdisk")) - flags |= LOADER_FLAGS_MODDISK; - else if (!strcasecmp(argv[i], "rescue")) - flags |= LOADER_FLAGS_RESCUE; - else if (!strcasecmp(argv[i], "nopass")) - flags |= LOADER_FLAGS_NOPASS; - else if (!strcasecmp(argv[i], "serial")) - flags |= LOADER_FLAGS_SERIAL; - else if (!strcasecmp(argv[i], "noipv4")) - flags |= LOADER_FLAGS_NOIPV4; +static void parseCmdLineFlags(struct loaderData_s *loaderData, char *cmdLine) +{ + int fd; + char buf[1024]; + int len; + gint argc = 0; + gchar **argv = NULL; + GError *optErr = NULL; + int numExtraArgs = 0; + int i; + char *front, *stage2param = NULL; + + /* we want to default to graphical and allow override with 'text' */ + flags |= LOADER_FLAGS_GRAPHICAL; + + /* if we have any explicit cmdline (probably test mode), we don't want + * to parse /proc/cmdline */ + if (!cmdLine) { + if ((fd = open("/proc/cmdline", O_RDONLY)) < 0) + return; + len = read(fd, buf, sizeof(buf) - 1); + close(fd); + if (len <= 0) { + logMessage(INFO, "kernel command line was empty"); + return; + } + + buf[len] = '\0'; + cmdLine = buf; + } + + logMessage(INFO, "kernel command line: %s", cmdLine); + + if (!g_shell_parse_argv(cmdLine, &argc, &argv, &optErr)) { + g_error_free(optErr); + return; + } + + for (i = 0; i < argc; i++) { + if (!strcasecmp(argv[i], "askmethod")) + flags |= LOADER_FLAGS_ASKMETHOD; + else if (!strcasecmp(argv[i], "asknetwork")) + flags |= LOADER_FLAGS_ASKNETWORK; + else if (!strcasecmp(argv[i], "noshell")) + flags |= LOADER_FLAGS_NOSHELL; + else if (!strcasecmp(argv[i], "nokill")) + flags |= LOADER_FLAGS_NOKILL; + else if (!strcasecmp(argv[i], "mediacheck")) + flags |= LOADER_FLAGS_MEDIACHECK; + else if (!strcasecmp(argv[i], "allowwireless")) + flags |= LOADER_FLAGS_ALLOW_WIRELESS; + else if (!strcasecmp(argv[i], "telnet")) + flags |= LOADER_FLAGS_TELNETD; + else if (!strcasecmp(argv[i], "noprobe")) + flags |= LOADER_FLAGS_NOPROBE; + else if (!strcasecmp(argv[i], "text")) { + logMessage(INFO, "text mode forced from cmdline"); + flags |= LOADER_FLAGS_TEXT; + flags &= ~LOADER_FLAGS_GRAPHICAL; + } else if (!strcasecmp(argv[i], "graphical")) { + logMessage(INFO, "graphical mode forced from cmdline"); + flags |= LOADER_FLAGS_GRAPHICAL; + } else if (!strcasecmp(argv[i], "cmdline")) { + logMessage(INFO, "cmdline mode forced from cmdline"); + flags |= LOADER_FLAGS_CMDLINE; + } else if (!strncasecmp(argv[i], "updates=", 8)) + loaderData->updatessrc = strdup(argv[i] + 8); + else if (!strncasecmp(argv[i], "updates", 7)) + flags |= LOADER_FLAGS_UPDATES; + else if (!strncasecmp(argv[i], "dogtail=", 8)) + loaderData->dogtailurl = strdup(argv[i] + 8); + else if (!strncasecmp(argv[i], "dd=", 3) || + !strncasecmp(argv[i], "driverdisk=", 11)) { + loaderData->ddsrc = strdup(argv[i] + + (argv[i][1] == + 'r' ? 11 : 3)); + } else if (!strcasecmp(argv[i], "dd") + || !strcasecmp(argv[i], "driverdisk")) + flags |= LOADER_FLAGS_MODDISK; + else if (!strcasecmp(argv[i], "rescue")) + flags |= LOADER_FLAGS_RESCUE; + else if (!strcasecmp(argv[i], "nopass")) + flags |= LOADER_FLAGS_NOPASS; + else if (!strcasecmp(argv[i], "serial")) + flags |= LOADER_FLAGS_SERIAL; + else if (!strcasecmp(argv[i], "noipv4")) + flags |= LOADER_FLAGS_NOIPV4; #ifdef ENABLE_IPV6 - else if (!strcasecmp(argv[i], "noipv6")) - flags |= LOADER_FLAGS_NOIPV6; + else if (!strcasecmp(argv[i], "noipv6")) + flags |= LOADER_FLAGS_NOIPV6; #endif - else if (!strcasecmp(argv[i], "kssendmac")) - flags |= LOADER_FLAGS_KICKSTART_SEND_MAC; - else if (!strcasecmp(argv[i], "kssendsn")) - flags |= LOADER_FLAGS_KICKSTART_SEND_SERIAL; - /* deprecated hardware bits */ - else if (!strcasecmp(argv[i], "nousbstorage")) - mlAddBlacklist("usb-storage"); - else if (!strcasecmp(argv[i], "nousb")) { - mlAddBlacklist("ehci-hcd"); - mlAddBlacklist("ohci-hcd"); - mlAddBlacklist("uhci-hcd"); - } else if (!strcasecmp(argv[i], "nofirewire")) - mlAddBlacklist("firewire-ohci"); - else if (!strncasecmp(argv[i], "loglevel=", 9)) { - if (!strcasecmp(argv[i]+9, "debug")) { - loaderData->logLevel = strdup(argv[i]+9); - setLogLevel(DEBUGLVL); - } - else if (!strcasecmp(argv[i]+9, "info")) { - loaderData->logLevel = strdup(argv[i]+9); - setLogLevel(INFO); - } - else if (!strcasecmp(argv[i]+9, "warning")) { - loaderData->logLevel = strdup(argv[i]+9); - setLogLevel(WARNING); - } - else if (!strcasecmp(argv[i]+9, "error")) { - loaderData->logLevel = strdup(argv[i]+9); - setLogLevel(ERROR); - } - else if (!strcasecmp(argv[i]+9, "critical")) { - loaderData->logLevel = strdup(argv[i]+9); - setLogLevel(CRITICAL); - } - } - else if (!strncasecmp(argv[i], "ksdevice=", 9)) { - loaderData->netDev = strdup(argv[i] + 9); - loaderData->netDev_set = 1; - } - else if (!strncmp(argv[i], "BOOTIF=", 7)) { - /* +10 so that we skip over the leading 01- */ - loaderData->bootIf = strdup(argv[i] + 10); - - /* scan the BOOTIF value and replace '-' with ':' */ - front = loaderData->bootIf; - if (front) { - while (*front != '\0') { - if (*front == '-') - *front = ':'; - front++; - } - } - - loaderData->bootIf_set = 1; - } else if (!strncasecmp(argv[i], "dhcpclass=", 10)) { - loaderData->netCls = strdup(argv[i] + 10); - loaderData->netCls_set = 1; - } - else if (!strcasecmp(argv[i], "ks") || !strncasecmp(argv[i], "ks=", 3)) - loaderData->ksFile = strdup(argv[i]); - else if (!strncasecmp(argv[i], "display=", 8)) - setenv("DISPLAY", argv[i] + 8, 1); - else if ((!strncasecmp(argv[i], "lang=", 5)) && - (strlen(argv[i]) > 5)) { - loaderData->lang = strdup(argv[i] + 5); - loaderData->lang_set = 1; - } - else if (!strncasecmp(argv[i], "keymap=", 7) && - (strlen(argv[i]) > 7)) { - loaderData->kbd = strdup(argv[i] + 7); - loaderData->kbd_set = 1; - } - else if (!strncasecmp(argv[i], "method=", 7)) { - logMessage(WARNING, "method= is deprecated. Please use repo= instead."); - loaderData->instRepo = strdup(argv[i] + 7); - } - else if (!strncasecmp(argv[i], "repo=", 5)) - loaderData->instRepo = strdup(argv[i] + 5); - else if (!strncasecmp(argv[i], "stage2=", 7)) { - stage2param = strdup(argv[i]+7); - setStage2LocFromCmdline(argv[i] + 7, loaderData); - } - else if (!strncasecmp(argv[i], "hostname=", 9)) - loaderData->hostname = strdup(argv[i] + 9); - else if (!strncasecmp(argv[i], "ip=", 3)) - parseCmdLineIp(loaderData, argv[i]); + else if (!strcasecmp(argv[i], "kssendmac")) + flags |= LOADER_FLAGS_KICKSTART_SEND_MAC; + else if (!strcasecmp(argv[i], "kssendsn")) + flags |= LOADER_FLAGS_KICKSTART_SEND_SERIAL; + /* deprecated hardware bits */ + else if (!strcasecmp(argv[i], "nousbstorage")) + mlAddBlacklist("usb-storage"); + else if (!strcasecmp(argv[i], "nousb")) { + mlAddBlacklist("ehci-hcd"); + mlAddBlacklist("ohci-hcd"); + mlAddBlacklist("uhci-hcd"); + } else if (!strcasecmp(argv[i], "nofirewire")) + mlAddBlacklist("firewire-ohci"); + else if (!strncasecmp(argv[i], "loglevel=", 9)) { + if (!strcasecmp(argv[i] + 9, "debug")) { + loaderData->logLevel = strdup(argv[i] + 9); + setLogLevel(DEBUGLVL); + } else if (!strcasecmp(argv[i] + 9, "info")) { + loaderData->logLevel = strdup(argv[i] + 9); + setLogLevel(INFO); + } else if (!strcasecmp(argv[i] + 9, "warning")) { + loaderData->logLevel = strdup(argv[i] + 9); + setLogLevel(WARNING); + } else if (!strcasecmp(argv[i] + 9, "error")) { + loaderData->logLevel = strdup(argv[i] + 9); + setLogLevel(ERROR); + } else if (!strcasecmp(argv[i] + 9, "critical")) { + loaderData->logLevel = strdup(argv[i] + 9); + setLogLevel(CRITICAL); + } + } else if (!strncasecmp(argv[i], "ksdevice=", 9)) { + loaderData->netDev = strdup(argv[i] + 9); + loaderData->netDev_set = 1; + } else if (!strncmp(argv[i], "BOOTIF=", 7)) { + /* +10 so that we skip over the leading 01- */ + loaderData->bootIf = strdup(argv[i] + 10); + + /* scan the BOOTIF value and replace '-' with ':' */ + front = loaderData->bootIf; + if (front) { + while (*front != '\0') { + if (*front == '-') + *front = ':'; + front++; + } + } + + loaderData->bootIf_set = 1; + } else if (!strncasecmp(argv[i], "dhcpclass=", 10)) { + loaderData->netCls = strdup(argv[i] + 10); + loaderData->netCls_set = 1; + } else if (!strcasecmp(argv[i], "ks") + || !strncasecmp(argv[i], "ks=", 3)) + loaderData->ksFile = strdup(argv[i]); + else if (!strncasecmp(argv[i], "display=", 8)) + setenv("DISPLAY", argv[i] + 8, 1); + else if ((!strncasecmp(argv[i], "lang=", 5)) && + (strlen(argv[i]) > 5)) { + loaderData->lang = strdup(argv[i] + 5); + loaderData->lang_set = 1; + } else if (!strncasecmp(argv[i], "keymap=", 7) && + (strlen(argv[i]) > 7)) { + loaderData->kbd = strdup(argv[i] + 7); + loaderData->kbd_set = 1; + } else if (!strncasecmp(argv[i], "method=", 7)) { + logMessage(WARNING, + "method= is deprecated. Please use repo= instead."); + loaderData->instRepo = strdup(argv[i] + 7); + } else if (!strncasecmp(argv[i], "repo=", 5)) + loaderData->instRepo = strdup(argv[i] + 5); + else if (!strncasecmp(argv[i], "stage2=", 7)) { + stage2param = strdup(argv[i] + 7); + setStage2LocFromCmdline(argv[i] + 7, loaderData); + } else if (!strncasecmp(argv[i], "hostname=", 9)) + loaderData->hostname = strdup(argv[i] + 9); + else if (!strncasecmp(argv[i], "ip=", 3)) + parseCmdLineIp(loaderData, argv[i]); #ifdef ENABLE_IPV6 - else if (!strncasecmp(argv[i], "ipv6=", 5)) - parseCmdLineIpv6(loaderData, argv[i]); + else if (!strncasecmp(argv[i], "ipv6=", 5)) + parseCmdLineIpv6(loaderData, argv[i]); #endif - else if (!strncasecmp(argv[i], "netmask=", 8)) - loaderData->netmask = strdup(argv[i] + 8); - else if (!strncasecmp(argv[i], "gateway=", 8)) - loaderData->gateway = strdup(argv[i] + 8); - else if (!strncasecmp(argv[i], "dns=", 4)) - loaderData->dns = strdup(argv[i] + 4); - else if (!strncasecmp(argv[i], "ethtool=", 8)) - loaderData->ethtool = strdup(argv[i] + 8); - else if (!strncasecmp(argv[i], "essid=", 6)) - loaderData->essid = strdup(argv[i] + 6); - else if (!strncasecmp(argv[i], "mtu=", 4)) - loaderData->mtu = argToLong(argv[i], 4); - else if (!strncasecmp(argv[i], "wepkey=", 7)) - loaderData->wepkey = strdup(argv[i] + 7); - else if (!strncasecmp(argv[i], "linksleep=", 10)) - num_link_checks = argToLong(argv[i], 10); - else if (!strncasecmp(argv[i], "nicdelay=", 9)) - post_link_sleep = argToLong(argv[i], 9); - else if (!strncasecmp(argv[i], "dhcptimeout=", 12)) - loaderData->dhcpTimeout = argToLong(argv[i], 12); - else if (!strncasecmp(argv[i], "selinux=0", 9)) - flags &= ~LOADER_FLAGS_SELINUX; - else if (!strncasecmp(argv[i], "selinux", 7)) - flags |= LOADER_FLAGS_SELINUX; - else if (!strncasecmp(argv[i], "gdb=", 4)) - loaderData->gdbServer = strdup(argv[i] + 4); - else if (!strncasecmp(argv[i], "proxy=", 6)) - splitProxyParam(argv[i]+6, &loaderData->proxyUser, - &loaderData->proxyPassword, &loaderData->proxy, - &loaderData->proxyPort); - else if (numExtraArgs < (MAX_EXTRA_ARGS - 1)) { - /* go through and append args we just want to pass on to */ - /* the anaconda script, but don't want to represent as a */ - /* LOADER_FLAGS_XXX since loader doesn't care about these */ - /* particular options. */ - /* do vncpassword case first */ - if (!strncasecmp(argv[i], "vncpassword=", 12)) { - writeVNCPasswordFile("/tmp/vncpassword.dat", argv[i]+12); - } - else if (!strncasecmp(argv[i], "resolution=", 11) || - !strncasecmp(argv[i], "nomount", 7) || - !strncasecmp(argv[i], "vnc", 3) || - !strncasecmp(argv[i], "vncconnect=", 11) || - !strncasecmp(argv[i], "headless", 8) || - !strncasecmp(argv[i], "usefbx", 6) || - !strncasecmp(argv[i], "mpath", 6) || - !strncasecmp(argv[i], "nompath", 8) || - !strncasecmp(argv[i], "dmraid", 6) || - !strncasecmp(argv[i], "nodmraid", 8) || - !strncasecmp(argv[i], "xdriver=", 8) || - !strncasecmp(argv[i], "vesa", 4) || - !strncasecmp(argv[i], "syslog=", 7)) { - - /* vnc implies graphical */ - if (!strncasecmp(argv[i], "vnc", 3)) { - logMessage(INFO, "vnc forced graphical mode from cmdline"); - flags |= LOADER_FLAGS_GRAPHICAL; - } - - /* the following things require networking to be configured - * by loader, so an active connection is ready once we get - * to anaconda - */ - if (!strncasecmp(argv[i], "syslog", 6) || - !strncasecmp(argv[i], "vnc", 3) || - isKickstartFileRemote(loaderData->ksFile)) { - logMessage(INFO, "early networking required for %s", - argv[i]); - flags |= LOADER_FLAGS_EARLY_NETWORKING; - } - - if (!strncasecmp(argv[i], "vesa", 4)) { - checked_asprintf(&extraArgs[numExtraArgs], - "--xdriver=vesa"); - - logMessage(WARNING, "\"vesa\" command line argument is deprecated. use \"xdriver=vesa\"."); - } else { - checked_asprintf(&extraArgs[numExtraArgs],"--%s", - argv[i]); - } - - numExtraArgs += 1; - - if (numExtraArgs > (MAX_EXTRA_ARGS - 2)) { - logMessage(WARNING, "Too many command line arguments (max " - "allowed is %d), rest will be dropped.", - MAX_EXTRA_ARGS); - } - } - } - } - - readNetInfo(&loaderData); - - /* NULL terminates the array of extra args */ - extraArgs[numExtraArgs] = NULL; - - return; + else if (!strncasecmp(argv[i], "netmask=", 8)) + loaderData->netmask = strdup(argv[i] + 8); + else if (!strncasecmp(argv[i], "gateway=", 8)) + loaderData->gateway = strdup(argv[i] + 8); + else if (!strncasecmp(argv[i], "dns=", 4)) + loaderData->dns = strdup(argv[i] + 4); + else if (!strncasecmp(argv[i], "ethtool=", 8)) + loaderData->ethtool = strdup(argv[i] + 8); + else if (!strncasecmp(argv[i], "essid=", 6)) + loaderData->essid = strdup(argv[i] + 6); + else if (!strncasecmp(argv[i], "mtu=", 4)) + loaderData->mtu = argToLong(argv[i], 4); + else if (!strncasecmp(argv[i], "wepkey=", 7)) + loaderData->wepkey = strdup(argv[i] + 7); + else if (!strncasecmp(argv[i], "linksleep=", 10)) + num_link_checks = argToLong(argv[i], 10); + else if (!strncasecmp(argv[i], "nicdelay=", 9)) + post_link_sleep = argToLong(argv[i], 9); + else if (!strncasecmp(argv[i], "dhcptimeout=", 12)) + loaderData->dhcpTimeout = argToLong(argv[i], 12); + else if (!strncasecmp(argv[i], "selinux=0", 9)) + flags &= ~LOADER_FLAGS_SELINUX; + else if (!strncasecmp(argv[i], "selinux", 7)) + flags |= LOADER_FLAGS_SELINUX; + else if (!strncasecmp(argv[i], "gdb=", 4)) + loaderData->gdbServer = strdup(argv[i] + 4); + else if (!strncasecmp(argv[i], "proxy=", 6)) + splitProxyParam(argv[i] + 6, &loaderData->proxyUser, + &loaderData->proxyPassword, + &loaderData->proxy, + &loaderData->proxyPort); + else if (numExtraArgs < (MAX_EXTRA_ARGS - 1)) { + /* go through and append args we just want to pass on to */ + /* the anaconda script, but don't want to represent as a */ + /* LOADER_FLAGS_XXX since loader doesn't care about these */ + /* particular options. */ + /* do vncpassword case first */ + if (!strncasecmp(argv[i], "vncpassword=", 12)) { + writeVNCPasswordFile("/tmp/vncpassword.dat", + argv[i] + 12); + } else if (!strncasecmp(argv[i], "resolution=", 11) + || !strncasecmp(argv[i], "nomount", 7) + || !strncasecmp(argv[i], "vnc", 3) + || !strncasecmp(argv[i], "vncconnect=", 11) + || !strncasecmp(argv[i], "headless", 8) + || !strncasecmp(argv[i], "usefbx", 6) + || !strncasecmp(argv[i], "mpath", 6) + || !strncasecmp(argv[i], "nompath", 8) + || !strncasecmp(argv[i], "dmraid", 6) + || !strncasecmp(argv[i], "nodmraid", 8) + || !strncasecmp(argv[i], "xdriver=", 8) + || !strncasecmp(argv[i], "vesa", 4) + || !strncasecmp(argv[i], "syslog=", 7)) { + + /* vnc implies graphical */ + if (!strncasecmp(argv[i], "vnc", 3)) { + logMessage(INFO, + "vnc forced graphical mode from cmdline"); + flags |= LOADER_FLAGS_GRAPHICAL; + } + + /* the following things require networking to be configured + * by loader, so an active connection is ready once we get + * to anaconda + */ + if (!strncasecmp(argv[i], "syslog", 6) || + !strncasecmp(argv[i], "vnc", 3) || + isKickstartFileRemote(loaderData->ksFile)) { + logMessage(INFO, + "early networking required for %s", + argv[i]); + flags |= LOADER_FLAGS_EARLY_NETWORKING; + } + + if (!strncasecmp(argv[i], "vesa", 4)) { + checked_asprintf(&extraArgs + [numExtraArgs], + "--xdriver=vesa"); + + logMessage(WARNING, + "\"vesa\" command line argument is deprecated. use \"xdriver=vesa\"."); + } else { + checked_asprintf(&extraArgs + [numExtraArgs], "--%s", + argv[i]); + } + + numExtraArgs += 1; + + if (numExtraArgs > (MAX_EXTRA_ARGS - 2)) { + logMessage(WARNING, + "Too many command line arguments (max " + "allowed is %d), rest will be dropped.", + MAX_EXTRA_ARGS); + } + } + } + } + + readNetInfo(&loaderData); + + /* NULL terminates the array of extra args */ + extraArgs[numExtraArgs] = NULL; + + return; } /* make sure they have enough ram */ -static void checkForRam(void) { - if (totalMemory() < MIN_RAM) { - char *buf; - - checked_asprintf(&buf, _("You do not have enough RAM to install %s " - "on this machine."), getProductName()); - - startNewt(); - newtWinMessage(_("Error"), _("OK"), buf); - free(buf); - stopNewt(); - doExit(0); - } +static void checkForRam(void) +{ + if (totalMemory() < MIN_RAM) { + char *buf; + + checked_asprintf(&buf, + _("You do not have enough RAM to install %s " + "on this machine."), getProductName()); + + startNewt(); + newtWinMessage(_("Error"), _("OK"), buf); + free(buf); + stopNewt(); + doExit(0); + } } -static int haveDeviceOfType(int type) { - struct device ** devices; +static int haveDeviceOfType(int type) +{ + struct device **devices; - devices = getDevices(type); - if (devices) { - return 1; - } - return 0; + devices = getDevices(type); + if (devices) { + return 1; + } + return 0; } static char *doLoaderMain(struct loaderData_s *loaderData, - moduleInfoSet modInfo) { - enum { STEP_LANG, STEP_KBD, STEP_METHOD, STEP_DRIVER, - STEP_DRIVERDISK, STEP_NETWORK, STEP_IFACE, - STEP_IP, STEP_STAGE2, STEP_DONE } step; - - char *url = NULL, *ret = NULL, *devName = NULL, *kbdtype = NULL; - static iface_t iface; - int i, rc, dir = 1; - int needsNetwork = 0, class = -1; - int skipMethodDialog = 0, skipLangKbd = 0; - - char *installNames[10]; - int numValidMethods = 0; - int validMethods[10]; - - for (i = 0; i < numMethods; i++, numValidMethods++) { - installNames[numValidMethods] = installMethods[i].name; - validMethods[numValidMethods] = i; - } - installNames[numValidMethods] = NULL; - - /* Before anything else, see if there's a CD/DVD with a stage2 image on - * it. However if stage2= was given, use that value as an override here. - * That will also then bypass any method selection UI in loader. - */ - if (!FL_ASKMETHOD(flags)) { - url = findAnacondaCD("/mnt/stage2"); - if (url) { - setStage2LocFromCmdline(url, loaderData); - skipMethodDialog = 1; - - logMessage(INFO, "Detected stage 2 image on CD (url: %s)", url); - winStatus(50, 3, _("Media Detected"), - _("Found local installation media"), 0); - sleep(3); - newtPopWindow(); - - skipLangKbd = 1; - flags |= LOADER_FLAGS_NOPASS; - } else if (!loaderData->stage2Data && loaderData->instRepo) { - /* If no CD/DVD with a stage2 image was found and we were given a - * repo=/method= parameter, try to piece together a valid setting - * for the stage2= parameter based on that. - */ - char *tmp; - - checked_asprintf(&tmp, "%s/images/install.img", - loaderData->instRepo); - - logMessage(INFO, "no stage2= given, assuming %s", tmp); - setStage2LocFromCmdline(tmp, loaderData); - free(tmp); - - /* If we had to infer a stage2= location, but the repo= parameter - * we based this guess on was wrong, we need to correct the typo - * in both places. Unfortunately we can't really know what the - * user meant, so the best we can do is take the results of - * running stage2= through the UI and chop off any /images/whatever - * path that's at the end of it. - */ - loaderData->inferredStage2 = 1; - skipMethodDialog = 1; - } else if (loaderData->stage2Data) { - skipMethodDialog = 1; - } - } else { - /* Needed because they have already been set when parsing cmdline. - * (Leaks a little.) - */ - loaderData->method = -1; - loaderData->stage2Data = NULL; - } - - i = 0; - step = STEP_LANG; - - while (step != STEP_DONE) { - switch(step) { - case STEP_LANG: { - if (loaderData->lang && (loaderData->lang_set == 1)) - setLanguage(loaderData->lang, 1); - else if (FL_RESCUE(flags) || !skipLangKbd) - chooseLanguage(&loaderData->lang); - - step = STEP_KBD; - dir = 1; - break; - } - - case STEP_KBD: { - if (loaderData->kbd && (loaderData->kbd_set == 1)) { - /* JKFIXME: this is broken -- we should tell of the - * failure; best by pulling code out in kbd.c to use */ - if (isysLoadKeymap(loaderData->kbd)) { - logMessage(WARNING, "requested keymap %s is not valid, asking", - loaderData->kbd); - loaderData->kbd = NULL; - loaderData->kbd_set = 0; - break; - } - rc = LOADER_NOOP; - } else if (FL_RESCUE(flags) || !skipLangKbd) { - /* JKFIXME: should handle kbdtype, too probably... but it - * just matters for sparc */ - if (!FL_CMDLINE(flags)) - rc = chooseKeyboard(loaderData, &kbdtype); - else - rc = LOADER_NOOP; - } else { - step = STEP_METHOD; - dir = 1; - } - - if (rc == LOADER_NOOP) { - if (dir == -1) - step = STEP_LANG; - else - step = STEP_METHOD; - - break; - } - - if (rc == LOADER_BACK) { - step = STEP_LANG; - dir = -1; - } else { - step = STEP_METHOD; - dir = 1; - } - - break; - } - - case STEP_METHOD: { - if (loaderData->method != -1) - skipMethodDialog = 1; - else if (FL_CMDLINE(flags)) { - fprintf(stderr, "No method given for cmdline mode, aborting\n"); - doExit(EXIT_FAILURE); - } - - /* If we already found a stage2 image, skip the prompt. */ - if (skipMethodDialog) { - if (dir == 1) - rc = 1; - else - rc = -1; - } else { - /* we need to set these each time through so that we get - * updated for language changes (#83672) */ - for (i = 0; i < numMethods; i++) { - installNames[i] = _(installMethods[i].name); - } - installNames[i] = NULL; - - rc = newtWinMenu(FL_RESCUE(flags) ? _("Rescue Method") : - _("Installation Method"), - FL_RESCUE(flags) ? - _("What type of media contains the rescue " - "image?") : - _("What type of media contains the installation " - "image?"), - 30, 10, 20, 6, installNames, &loaderData->method, - _("OK"), _("Back"), NULL); - if (rc == 2) { - loaderData->method = -1; - } - } - - if (rc && (rc != 1)) { - step = STEP_KBD; - dir = -1; - } else { - class = installMethods[validMethods[loaderData->method]].type; - step = STEP_DRIVER; - dir = 1; - } - break; - } - - case STEP_DRIVER: { - if ((FL_EARLY_NETWORKING(flags) && haveDeviceOfType(DEVICE_NETWORK)) || - (class == -1 || haveDeviceOfType(class))) { - step = STEP_NETWORK; - dir = 1; - class = -1; - break; - } - - if (skipLangKbd) { - skipLangKbd = 0; - step = STEP_KBD; - break; - } - - rc = newtWinTernary(_("No driver found"), _("Select driver"), - _("Use a driver disk"), _("Back"), - _("Unable to find any devices of the type " - "needed for this installation type. " - "Would you like to manually select your " - "driver or use a driver disk?")); - if (rc == 2) { - step = STEP_DRIVERDISK; - dir = 1; - break; - } else if (rc == 3) { - step = STEP_METHOD; - dir = -1; - break; - } - - chooseManualDriver(installMethods[validMethods[loaderData->method]].type, - loaderData); - /* it doesn't really matter what we return here; we just want - * to reprobe and make sure we have the driver */ - step = STEP_DRIVER; - break; - } - - case STEP_DRIVERDISK: { - if (skipLangKbd) { - skipLangKbd = 0; - step = STEP_KBD; - break; - } - - rc = loadDriverFromMedia(class, loaderData, 0, 0); - if (rc == LOADER_BACK) { - step = STEP_DRIVER; - dir = -1; - break; - } - - /* need to come back to driver so that we can ensure that we found - * the right kind of driver after loading the driver disk */ - step = STEP_DRIVER; - break; - } - - case STEP_NETWORK: { - if (((installMethods[validMethods[loaderData->method]].type != - DEVICE_NETWORK) && (!hasGraphicalOverride()) && - !FL_ASKNETWORK(flags) && - !FL_EARLY_NETWORKING(flags)) || - (is_nm_connected())) { - needsNetwork = 0; - if (dir == 1) - step = STEP_STAGE2; - else if (dir == -1) - step = STEP_METHOD; - break; - } - - needsNetwork = 1; - if (!haveDeviceOfType(DEVICE_NETWORK)) { - class = DEVICE_NETWORK; - step = STEP_DRIVER; - break; - } - logMessage(INFO, "need to set up networking"); - - memset(&iface, 0, sizeof(iface)); - - /* fall through to interface selection */ - } - - case STEP_IFACE: { - logMessage(INFO, "going to pick interface"); - - /* skip configureTCPIP() screen for kickstart (#260621) */ - if (loaderData->ksFile) - flags |= LOADER_FLAGS_IS_KICKSTART; - - if (FL_HAVE_CMSCONF(flags)) { - loaderData->ipinfo_set = 1; + moduleInfoSet modInfo) +{ + enum { STEP_LANG, STEP_KBD, STEP_METHOD, STEP_DRIVER, + STEP_DRIVERDISK, STEP_NETWORK, STEP_IFACE, + STEP_IP, STEP_STAGE2, STEP_DONE + } step; + + char *url = NULL, *ret = NULL, *devName = NULL, *kbdtype = NULL; + static iface_t iface; + int i, rc, dir = 1; + int needsNetwork = 0, class = -1; + int skipMethodDialog = 0, skipLangKbd = 0; + + char *installNames[10]; + int numValidMethods = 0; + int validMethods[10]; + + for (i = 0; i < numMethods; i++, numValidMethods++) { + installNames[numValidMethods] = installMethods[i].name; + validMethods[numValidMethods] = i; + } + installNames[numValidMethods] = NULL; + + /* Before anything else, see if there's a CD/DVD with a stage2 image on + * it. However if stage2= was given, use that value as an override here. + * That will also then bypass any method selection UI in loader. + */ + if (!FL_ASKMETHOD(flags)) { + url = findAnacondaCD("/mnt/stage2"); + if (url) { + setStage2LocFromCmdline(url, loaderData); + skipMethodDialog = 1; + + logMessage(INFO, + "Detected stage 2 image on CD (url: %s)", + url); + winStatus(50, 3, _("Media Detected"), + _("Found local installation media"), 0); + sleep(3); + newtPopWindow(); + + skipLangKbd = 1; + flags |= LOADER_FLAGS_NOPASS; + } else if (!loaderData->stage2Data && loaderData->instRepo) { + /* If no CD/DVD with a stage2 image was found and we were given a + * repo=/method= parameter, try to piece together a valid setting + * for the stage2= parameter based on that. + */ + char *tmp; + + checked_asprintf(&tmp, "%s/images/install.img", + loaderData->instRepo); + + logMessage(INFO, "no stage2= given, assuming %s", tmp); + setStage2LocFromCmdline(tmp, loaderData); + free(tmp); + + /* If we had to infer a stage2= location, but the repo= parameter + * we based this guess on was wrong, we need to correct the typo + * in both places. Unfortunately we can't really know what the + * user meant, so the best we can do is take the results of + * running stage2= through the UI and chop off any /images/whatever + * path that's at the end of it. + */ + loaderData->inferredStage2 = 1; + skipMethodDialog = 1; + } else if (loaderData->stage2Data) { + skipMethodDialog = 1; + } + } else { + /* Needed because they have already been set when parsing cmdline. + * (Leaks a little.) + */ + loaderData->method = -1; + loaderData->stage2Data = NULL; + } + + i = 0; + step = STEP_LANG; + + while (step != STEP_DONE) { + switch (step) { + case STEP_LANG:{ + if (loaderData->lang + && (loaderData->lang_set == 1)) + setLanguage(loaderData->lang, 1); + else if (FL_RESCUE(flags) || !skipLangKbd) + chooseLanguage(&loaderData->lang); + + step = STEP_KBD; + dir = 1; + break; + } + + case STEP_KBD:{ + if (loaderData->kbd + && (loaderData->kbd_set == 1)) { + /* JKFIXME: this is broken -- we should tell of the + * failure; best by pulling code out in kbd.c to use */ + if (isysLoadKeymap(loaderData->kbd)) { + logMessage(WARNING, + "requested keymap %s is not valid, asking", + loaderData->kbd); + loaderData->kbd = NULL; + loaderData->kbd_set = 0; + break; + } + rc = LOADER_NOOP; + } else if (FL_RESCUE(flags) || !skipLangKbd) { + /* JKFIXME: should handle kbdtype, too probably... but it + * just matters for sparc */ + if (!FL_CMDLINE(flags)) + rc = chooseKeyboard(loaderData, + &kbdtype); + else + rc = LOADER_NOOP; + } else { + step = STEP_METHOD; + dir = 1; + } + + if (rc == LOADER_NOOP) { + if (dir == -1) + step = STEP_LANG; + else + step = STEP_METHOD; + + break; + } + + if (rc == LOADER_BACK) { + step = STEP_LANG; + dir = -1; + } else { + step = STEP_METHOD; + dir = 1; + } + + break; + } + + case STEP_METHOD:{ + if (loaderData->method != -1) + skipMethodDialog = 1; + else if (FL_CMDLINE(flags)) { + fprintf(stderr, + "No method given for cmdline mode, aborting\n"); + doExit(EXIT_FAILURE); + } + + /* If we already found a stage2 image, skip the prompt. */ + if (skipMethodDialog) { + if (dir == 1) + rc = 1; + else + rc = -1; + } else { + /* we need to set these each time through so that we get + * updated for language changes (#83672) */ + for (i = 0; i < numMethods; i++) { + installNames[i] = + _(installMethods[i].name); + } + installNames[i] = NULL; + + rc = newtWinMenu(FL_RESCUE(flags) ? + _("Rescue Method") : + _ + ("Installation Method"), + FL_RESCUE(flags) ? + _ + ("What type of media contains the rescue " + "image?") : + _ + ("What type of media contains the installation " + "image?"), 30, 10, 20, + 6, installNames, + &loaderData->method, + _("OK"), _("Back"), + NULL); + if (rc == 2) { + loaderData->method = -1; + } + } + + if (rc && (rc != 1)) { + step = STEP_KBD; + dir = -1; + } else { + class = + installMethods[validMethods + [loaderData->method]]. + type; + step = STEP_DRIVER; + dir = 1; + } + break; + } + + case STEP_DRIVER:{ + if ((FL_EARLY_NETWORKING(flags) + && haveDeviceOfType(DEVICE_NETWORK)) + || (class == -1 || haveDeviceOfType(class))) { + step = STEP_NETWORK; + dir = 1; + class = -1; + break; + } + + if (skipLangKbd) { + skipLangKbd = 0; + step = STEP_KBD; + break; + } + + rc = newtWinTernary(_("No driver found"), + _("Select driver"), + _("Use a driver disk"), + _("Back"), + _ + ("Unable to find any devices of the type " + "needed for this installation type. " + "Would you like to manually select your " + "driver or use a driver disk?")); + if (rc == 2) { + step = STEP_DRIVERDISK; + dir = 1; + break; + } else if (rc == 3) { + step = STEP_METHOD; + dir = -1; + break; + } + + chooseManualDriver(installMethods + [validMethods + [loaderData->method]].type, + loaderData); + /* it doesn't really matter what we return here; we just want + * to reprobe and make sure we have the driver */ + step = STEP_DRIVER; + break; + } + + case STEP_DRIVERDISK:{ + if (skipLangKbd) { + skipLangKbd = 0; + step = STEP_KBD; + break; + } + + rc = loadDriverFromMedia(class, loaderData, 0, + 0); + if (rc == LOADER_BACK) { + step = STEP_DRIVER; + dir = -1; + break; + } + + /* need to come back to driver so that we can ensure that we found + * the right kind of driver after loading the driver disk */ + step = STEP_DRIVER; + break; + } + + case STEP_NETWORK:{ + if (((installMethods + [validMethods[loaderData->method]].type != + DEVICE_NETWORK) + && (!hasGraphicalOverride()) + && !FL_ASKNETWORK(flags) + && !FL_EARLY_NETWORKING(flags)) + || (is_nm_connected())) { + needsNetwork = 0; + if (dir == 1) + step = STEP_STAGE2; + else if (dir == -1) + step = STEP_METHOD; + break; + } + + needsNetwork = 1; + if (!haveDeviceOfType(DEVICE_NETWORK)) { + class = DEVICE_NETWORK; + step = STEP_DRIVER; + break; + } + logMessage(INFO, "need to set up networking"); + + memset(&iface, 0, sizeof(iface)); + + /* fall through to interface selection */ + } + + case STEP_IFACE:{ + logMessage(INFO, "going to pick interface"); + + /* skip configureTCPIP() screen for kickstart (#260621) */ + if (loaderData->ksFile) + flags |= LOADER_FLAGS_IS_KICKSTART; + + if (FL_HAVE_CMSCONF(flags)) { + loaderData->ipinfo_set = 1; #ifdef ENABLE_IPV6 - loaderData->ipv6info_set = 1; + loaderData->ipv6info_set = 1; #endif - } - - rc = chooseNetworkInterface(loaderData); - if ((rc == LOADER_BACK) || (rc == LOADER_ERROR) || - ((dir == -1) && (rc == LOADER_NOOP))) { - /* don't skip method dialog iff we don't have url from ks or boot params */ - if (!loaderData->stage2Data) { - loaderData->method = -1; - } - step = STEP_METHOD; - dir = -1; - break; - } - - devName = loaderData->netDev; - strcpy(iface.device, devName); - - /* continue to ip config */ - step = STEP_IP; - dir = 1; - break; - } - - case STEP_IP: { - if (!needsNetwork || dir == -1) { - step = STEP_METHOD; /* only hit going back */ - break; - } - - if ((ret = malloc(INET6_ADDRSTRLEN+1)) == NULL) { - logMessage(ERROR, "malloc failure for ret in STEP_IP"); - doExit(EXIT_FAILURE); - } - - logMessage(INFO, "going to do getNetConfig"); - - /* s390 provides all config info by way of the CMS conf file */ - if (FL_HAVE_CMSCONF(flags)) { - loaderData->ipinfo_set = 1; + } + + rc = chooseNetworkInterface(loaderData); + if ((rc == LOADER_BACK) || (rc == LOADER_ERROR) + || ((dir == -1) && (rc == LOADER_NOOP))) { + /* don't skip method dialog iff we don't have url from ks or boot params */ + if (!loaderData->stage2Data) { + loaderData->method = -1; + } + step = STEP_METHOD; + dir = -1; + break; + } + + devName = loaderData->netDev; + strcpy(iface.device, devName); + + /* continue to ip config */ + step = STEP_IP; + dir = 1; + break; + } + + case STEP_IP:{ + if (!needsNetwork || dir == -1) { + step = STEP_METHOD; /* only hit going back */ + break; + } + + if ((ret = + malloc(INET6_ADDRSTRLEN + 1)) == NULL) { + logMessage(ERROR, + "malloc failure for ret in STEP_IP"); + doExit(EXIT_FAILURE); + } + + logMessage(INFO, "going to do getNetConfig"); + + /* s390 provides all config info by way of the CMS conf file */ + if (FL_HAVE_CMSCONF(flags)) { + loaderData->ipinfo_set = 1; #ifdef ENABLE_IPV6 - loaderData->ipv6info_set = 1; + loaderData->ipv6info_set = 1; #endif - } - - /* populate netDev based on any kickstart data */ - setupIfaceStruct(&iface, loaderData); - rc = readNetConfig(devName, &iface, loaderData->netCls, loaderData->method); - - /* set the hostname if we have that */ - if (loaderData->hostname) { - if (sethostname(loaderData->hostname, - strlen(loaderData->hostname))) { - logMessage(ERROR, "error setting hostname to %s", - loaderData->hostname); - } - } - - free(ret); - ret = NULL; - - if ((rc == LOADER_BACK) || - ((dir == -1) && (rc == LOADER_NOOP))) { - needsNetwork = 1; - step = STEP_IFACE; - dir = -1; - break; - } - /* retry */ - if (rc == LOADER_ERROR) { - needsNetwork = 1; - break; - } - - writeEnabledNetInfo(&iface); - step = STEP_STAGE2; - dir = 1; - break; - } - - case STEP_STAGE2: { - if (url) { - logMessage(INFO, "stage2 url is %s", url); - return url; - } - - logMessage(INFO, "starting STEP_STAGE2"); - url = installMethods[validMethods[loaderData->method]].mountImage( - installMethods + validMethods[loaderData->method], - "/mnt/stage2", loaderData); - if (!url) { - step = STEP_IP; - loaderData->ipinfo_set = 0; + } + + /* populate netDev based on any kickstart data */ + setupIfaceStruct(&iface, loaderData); + rc = readNetConfig(devName, &iface, + loaderData->netCls, + loaderData->method); + + /* set the hostname if we have that */ + if (loaderData->hostname) { + if (sethostname(loaderData->hostname, + strlen + (loaderData->hostname))) + { + logMessage(ERROR, + "error setting hostname to %s", + loaderData->hostname); + } + } + + free(ret); + ret = NULL; + + if ((rc == LOADER_BACK) || + ((dir == -1) && (rc == LOADER_NOOP))) { + needsNetwork = 1; + step = STEP_IFACE; + dir = -1; + break; + } + /* retry */ + if (rc == LOADER_ERROR) { + needsNetwork = 1; + break; + } + + writeEnabledNetInfo(&iface); + step = STEP_STAGE2; + dir = 1; + break; + } + + case STEP_STAGE2:{ + if (url) { + logMessage(INFO, "stage2 url is %s", + url); + return url; + } + + logMessage(INFO, "starting STEP_STAGE2"); + url = + installMethods[validMethods + [loaderData-> + method]].mountImage + (installMethods + + validMethods[loaderData->method], + "/mnt/stage2", loaderData); + if (!url) { + step = STEP_IP; + loaderData->ipinfo_set = 0; #ifdef ENABLE_IPV6 - loaderData->ipv6info_set = 0; + loaderData->ipv6info_set = 0; #endif - loaderData->method = -1; - skipMethodDialog = 0; - dir = -1; - } else { - logMessage(INFO, "got stage2 at url %s", url); - step = STEP_DONE; - dir = 1; - - if (loaderData->invalidRepoParam) { - char *newInstRepo; - - /* Doesn't contain /images? Let's not even try. */ - if (strstr(url, "/images") == NULL) - break; - - checked_asprintf(&newInstRepo, "%.*s", - (int) (strstr(url, "/images")-url), url); - - free(loaderData->instRepo); - loaderData->instRepo = newInstRepo; - logMessage(INFO, "reset repo= parameter to %s", - loaderData->instRepo); - } - } - - break; - } - - case STEP_DONE: - break; - } - } - - return url; + loaderData->method = -1; + skipMethodDialog = 0; + dir = -1; + } else { + logMessage(INFO, "got stage2 at url %s", + url); + step = STEP_DONE; + dir = 1; + + if (loaderData->invalidRepoParam) { + char *newInstRepo; + + /* Doesn't contain /images? Let's not even try. */ + if (strstr(url, "/images") == + NULL) + break; + + checked_asprintf(&newInstRepo, + "%.*s", + (int)(strstr + (url, + "/images") + - url), + url); + + free(loaderData->instRepo); + loaderData->instRepo = + newInstRepo; + logMessage(INFO, + "reset repo= parameter to %s", + loaderData->instRepo); + } + } + + break; + } + + case STEP_DONE: + break; + } + } + + return url; } -static int manualDeviceCheck(struct loaderData_s *loaderData) { - char ** devices; - int i, j, rc, num = 0; - unsigned int width = 40; - char * buf; - - do { - /* FIXME */ - devices = malloc(1 * sizeof(*devices)); - j = 0; - devices[j] = NULL; - - if (width > 70) - width = 70; - - if (j > 0) { - buf = _("The following devices have been found on your system."); - } else { - buf = _("No device drivers have been loaded for your system. " - "Would you like to load any now?"); - } - - rc = newtWinMenu(_("Devices"), buf, width, 10, 20, - (j > 6) ? 6 : j, devices, &num, _("Done"), - _("Add Device"), NULL); - - /* no leaky */ - for (i = 0; i < j; i++) - free(devices[j]); - free(devices); - - if (rc != 2) - break; - - chooseManualDriver(DEVICE_ANY, loaderData); - } while (1); - return 0; + +static int manualDeviceCheck(struct loaderData_s *loaderData) +{ + char **devices; + int i, j, rc, num = 0; + unsigned int width = 40; + char *buf; + + do { + /* FIXME */ + devices = malloc(1 * sizeof(*devices)); + j = 0; + devices[j] = NULL; + + if (width > 70) + width = 70; + + if (j > 0) { + buf = + _ + ("The following devices have been found on your system."); + } else { + buf = + _ + ("No device drivers have been loaded for your system. " + "Would you like to load any now?"); + } + + rc = newtWinMenu(_("Devices"), buf, width, 10, 20, + (j > 6) ? 6 : j, devices, &num, _("Done"), + _("Add Device"), NULL); + + /* no leaky */ + for (i = 0; i < j; i++) + free(devices[j]); + free(devices); + + if (rc != 2) + break; + + chooseManualDriver(DEVICE_ANY, loaderData); + } while (1); + return 0; } /* JKFIXME: I don't really like this, but at least it isolates the ifdefs */ /* Either move dirname to %s_old or unlink depending on arch (unlink on all * !s390{,x} arches). symlink to /mnt/runtime/dirname. dirname *MUST* start * with a '/' */ -static void migrate_runtime_directory(char * dirname) { - char * runtimedir; - int ret; - - checked_asprintf(&runtimedir, "/mnt/runtime%s", dirname); - - if (!access(runtimedir, X_OK)) { - if (unlink(dirname) == -1) { - char * olddir; - - checked_asprintf(&olddir, "%s_old", dirname); - - ret = rename(dirname, olddir); - free(olddir); - } - ret = symlink(runtimedir, dirname); - } - free(runtimedir); -} +static void migrate_runtime_directory(char *dirname) +{ + char *runtimedir; + int ret; + checked_asprintf(&runtimedir, "/mnt/runtime%s", dirname); -static int hasGraphicalOverride() { - int i; + if (!access(runtimedir, X_OK)) { + if (unlink(dirname) == -1) { + char *olddir; - if (getenv("DISPLAY")) - return 1; + checked_asprintf(&olddir, "%s_old", dirname); - for (i = 0; extraArgs[i] != NULL; i++) { - if (!strncasecmp(extraArgs[i], "--vnc", 5)) - return 1; - } - return 0; + ret = rename(dirname, olddir); + free(olddir); + } + ret = symlink(runtimedir, dirname); + } + free(runtimedir); } -void loaderSegvHandler(int signum) { - void *array[30]; - size_t i; - const char const * const errmsgs[] = { - "loader received SIG", - "! Backtrace:\n", - "Loader exited unexpectedly! Backtrace:\n", - }; - - /* XXX This should really be in a glibc header somewhere... */ - extern const char *const sys_sigabbrev[NSIG]; - - signal(signum, SIG_DFL); /* back to default */ - - newtFinished(); - if (signum == 0) { - i = write(STDERR_FILENO, errmsgs[2], strlen(errmsgs[2])); - } else { - i = write(STDERR_FILENO, errmsgs[0], strlen(errmsgs[0])); - i = write(STDERR_FILENO, sys_sigabbrev[signum], - strlen(sys_sigabbrev[signum])); - i = write(STDERR_FILENO, errmsgs[1], strlen(errmsgs[1])); - } - - i = backtrace (array, 30); - backtrace_symbols_fd(array, i, STDERR_FILENO); - _exit(1); +static int hasGraphicalOverride() +{ + int i; + + if (getenv("DISPLAY")) + return 1; + + for (i = 0; extraArgs[i] != NULL; i++) { + if (!strncasecmp(extraArgs[i], "--vnc", 5)) + return 1; + } + return 0; +} + +void loaderSegvHandler(int signum) +{ + void *array[30]; + size_t i; + const char const *const errmsgs[] = { + "loader received SIG", + "! Backtrace:\n", + "Loader exited unexpectedly! Backtrace:\n", + }; + + /* XXX This should really be in a glibc header somewhere... */ + extern const char *const sys_sigabbrev[NSIG]; + + signal(signum, SIG_DFL); /* back to default */ + + newtFinished(); + if (signum == 0) { + i = write(STDERR_FILENO, errmsgs[2], strlen(errmsgs[2])); + } else { + i = write(STDERR_FILENO, errmsgs[0], strlen(errmsgs[0])); + i = write(STDERR_FILENO, sys_sigabbrev[signum], + strlen(sys_sigabbrev[signum])); + i = write(STDERR_FILENO, errmsgs[1], strlen(errmsgs[1])); + } + + i = backtrace(array, 30); + backtrace_symbols_fd(array, i, STDERR_FILENO); + _exit(1); } void loaderExitHandler(void) { - if (expected_exit) - return; + if (expected_exit) + return; - loaderSegvHandler(0); + loaderSegvHandler(0); } static void setupBacktrace(void) { - void *array; + void *array; - signal(SIGSEGV, loaderSegvHandler); - signal(SIGABRT, loaderSegvHandler); - atexit(loaderExitHandler); + signal(SIGSEGV, loaderSegvHandler); + signal(SIGABRT, loaderSegvHandler); + atexit(loaderExitHandler); - /* Turns out, there's an initializer at the top of backtrace() that - * (on some arches) calls dlopen(). dlopen(), unsurprisingly, calls - * malloc(). So, call backtrace() early in signal handler setup so - * we can later safely call it from the signal handler itself. */ - backtrace(&array, 1); + /* Turns out, there's an initializer at the top of backtrace() that + * (on some arches) calls dlopen(). dlopen(), unsurprisingly, calls + * malloc(). So, call backtrace() early in signal handler setup so + * we can later safely call it from the signal handler itself. */ + backtrace(&array, 1); } -void loaderUsrXHandler(int signum) { - logMessage(INFO, "Remembering signal %d\n", signum); - init_sig = signum; +void loaderUsrXHandler(int signum) +{ + logMessage(INFO, "Remembering signal %d\n", signum); + init_sig = signum; } -static int anaconda_trace_init(void) { +static int anaconda_trace_init(void) +{ #ifdef USE_MTRACE - setenv("MALLOC_TRACE","/malloc",1); - mtrace(); + setenv("MALLOC_TRACE", "/malloc", 1); + mtrace(); #endif - /* We have to do this before we init bogl(), which doLoaderMain will do - * when setting fonts for different languages. It's also best if this - * is well before we might take a SEGV, so they'll go to tty8 */ - initializeTtys(); + /* We have to do this before we init bogl(), which doLoaderMain will do + * when setting fonts for different languages. It's also best if this + * is well before we might take a SEGV, so they'll go to tty8 */ + initializeTtys(); - /* set up signal handler */ - setupBacktrace(); + /* set up signal handler */ + setupBacktrace(); - return 0; + return 0; } static void add_to_path_env(const char *env, const char *val) { - char *oldenv, *newenv; + char *oldenv, *newenv; - oldenv = getenv(env); - if (oldenv) { - checked_asprintf(&newenv, "%s:%s", val, oldenv); + oldenv = getenv(env); + if (oldenv) { + checked_asprintf(&newenv, "%s:%s", val, oldenv); - oldenv = strdupa(newenv); - free(newenv); - newenv = oldenv; - } else { - newenv = strdupa(val); - } + oldenv = strdupa(newenv); + free(newenv); + newenv = oldenv; + } else { + newenv = strdupa(val); + } - setenv(env, newenv, 1); + setenv(env, newenv, 1); } -int main(int argc, char ** argv) { - int rc, ret, pid, status; - - struct stat sb; - struct serial_struct si; - char * arg; - FILE *f; - - char twelve = 12; - - moduleInfoSet modInfo; - - char *url = NULL; - - char ** argptr, ** tmparg; - char * anacondaArgs[50]; - - struct loaderData_s loaderData; - - char *path, *fmt; - - gchar *cmdLine = NULL, *ksFile = NULL, *virtpcon = NULL; - gboolean mediacheck = FALSE; - gchar **remaining = NULL; - GOptionContext *optCon = g_option_context_new(NULL); - GError *optErr = NULL; - GOptionEntry optionTable[] = { - { "cmdline", 0, 0, G_OPTION_ARG_STRING, &cmdLine, NULL, NULL }, - { "ksfile", 0, 0, G_OPTION_ARG_STRING, &ksFile, NULL, NULL }, - { "mediacheck", 0, 0, G_OPTION_ARG_NONE, &mediacheck, NULL, NULL }, - { "virtpconsole", 0, 0, G_OPTION_ARG_STRING, &virtpcon, NULL, NULL }, - { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &remaining, - NULL, NULL }, - { NULL }, - }; - - /* get init PID if we have it */ - if ((f = fopen("/var/run/init.pid", "r")) != NULL) { - char linebuf[256]; - memset(linebuf, '\0', sizeof(linebuf)); - - while (fgets(linebuf, sizeof(linebuf) - 1, f) != NULL) { - errno = 0; - init_pid = strtol((const char *) &linebuf, NULL, 10); - if (errno == EINVAL || errno == ERANGE) { - logMessage(ERROR, "%s (%d): %m", __func__, __LINE__); - init_pid = 1; - } - } - - fclose(f); - } - - signal(SIGUSR1, loaderUsrXHandler); - signal(SIGUSR2, loaderUsrXHandler); - - /* Make sure sort order is right. */ - setenv ("LC_COLLATE", "C", 1); - - /* Very first thing, set up tracebacks and debug features. */ - rc = anaconda_trace_init(); - - /* now we parse command line options */ - g_option_context_set_help_enabled(optCon, FALSE); - g_option_context_add_main_entries(optCon, optionTable, NULL); - - if (!g_option_context_parse(optCon, &argc, &argv, &optErr)) { - fprintf(stderr, "bad option: %s\n", optErr->message); - g_error_free(optErr); - g_option_context_free(optCon); - doExit(1); - } - - g_option_context_free(optCon); - - if (remaining) { - fprintf(stderr, "unexpected argument: %s\n", remaining[0]); - g_strfreev(remaining); - doExit(1); - } - - g_strfreev(remaining); - - if (!access("/var/run/loader.run", R_OK)) { - printf(_("loader has already been run. Starting shell.\n")); - execl("/bin/sh", "-/bin/sh", NULL); - doExit(0); - } - - f = fopen("/var/run/loader.run", "w+"); - fprintf(f, "%d\n", getpid()); - fclose(f); - - /* The fstat checks disallows serial console if we're running through - a pty. This is handy for Japanese. */ - fstat(0, &sb); - if (major(sb.st_rdev) != 3 && major(sb.st_rdev) != 136 && - (virtpcon == NULL)){ - if ((ioctl (0, TIOCLINUX, &twelve) < 0) && - (ioctl(0, TIOCGSERIAL, &si) != -1)) - flags |= LOADER_FLAGS_SERIAL; - } - - if (mediacheck) flags |= LOADER_FLAGS_MEDIACHECK; - if (ksFile) flags |= LOADER_FLAGS_KICKSTART; - if (virtpcon) flags |= LOADER_FLAGS_VIRTPCONSOLE; - - /* uncomment to send mac address in ks=http:/ header by default*/ - flags |= LOADER_FLAGS_KICKSTART_SEND_MAC; - - /* JKFIXME: I do NOT like this... it also looks kind of bogus */ +int main(int argc, char **argv) +{ + int rc, ret, pid, status; + + struct stat sb; + struct serial_struct si; + char *arg; + FILE *f; + + char twelve = 12; + + moduleInfoSet modInfo; + + char *url = NULL; + + char **argptr, **tmparg; + char *anacondaArgs[50]; + + struct loaderData_s loaderData; + + char *path, *fmt; + + gchar *cmdLine = NULL, *ksFile = NULL, *virtpcon = NULL; + gboolean mediacheck = FALSE; + gchar **remaining = NULL; + GOptionContext *optCon = g_option_context_new(NULL); + GError *optErr = NULL; + GOptionEntry optionTable[] = { + {"cmdline", 0, 0, G_OPTION_ARG_STRING, &cmdLine, NULL, NULL}, + {"ksfile", 0, 0, G_OPTION_ARG_STRING, &ksFile, NULL, NULL}, + {"mediacheck", 0, 0, G_OPTION_ARG_NONE, &mediacheck, NULL, + NULL}, + {"virtpconsole", 0, 0, G_OPTION_ARG_STRING, &virtpcon, NULL, + NULL}, + {G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, + &remaining, + NULL, NULL}, + {NULL}, + }; + + /* get init PID if we have it */ + if ((f = fopen("/var/run/init.pid", "r")) != NULL) { + char linebuf[256]; + memset(linebuf, '\0', sizeof(linebuf)); + + while (fgets(linebuf, sizeof(linebuf) - 1, f) != NULL) { + errno = 0; + init_pid = strtol((const char *)&linebuf, NULL, 10); + if (errno == EINVAL || errno == ERANGE) { + logMessage(ERROR, "%s (%d): %m", __func__, + __LINE__); + init_pid = 1; + } + } + + fclose(f); + } + + signal(SIGUSR1, loaderUsrXHandler); + signal(SIGUSR2, loaderUsrXHandler); + + /* Make sure sort order is right. */ + setenv("LC_COLLATE", "C", 1); + + /* Very first thing, set up tracebacks and debug features. */ + rc = anaconda_trace_init(); + + /* now we parse command line options */ + g_option_context_set_help_enabled(optCon, FALSE); + g_option_context_add_main_entries(optCon, optionTable, NULL); + + if (!g_option_context_parse(optCon, &argc, &argv, &optErr)) { + fprintf(stderr, "bad option: %s\n", optErr->message); + g_error_free(optErr); + g_option_context_free(optCon); + doExit(1); + } + + g_option_context_free(optCon); + + if (remaining) { + fprintf(stderr, "unexpected argument: %s\n", remaining[0]); + g_strfreev(remaining); + doExit(1); + } + + g_strfreev(remaining); + + if (!access("/var/run/loader.run", R_OK)) { + printf(_("loader has already been run. Starting shell.\n")); + execl("/bin/sh", "-/bin/sh", NULL); + doExit(0); + } + + f = fopen("/var/run/loader.run", "w+"); + fprintf(f, "%d\n", getpid()); + fclose(f); + + /* The fstat checks disallows serial console if we're running through + a pty. This is handy for Japanese. */ + fstat(0, &sb); + if (major(sb.st_rdev) != 3 && major(sb.st_rdev) != 136 && + (virtpcon == NULL)) { + if ((ioctl(0, TIOCLINUX, &twelve) < 0) && + (ioctl(0, TIOCGSERIAL, &si) != -1)) + flags |= LOADER_FLAGS_SERIAL; + } + + if (mediacheck) + flags |= LOADER_FLAGS_MEDIACHECK; + if (ksFile) + flags |= LOADER_FLAGS_KICKSTART; + if (virtpcon) + flags |= LOADER_FLAGS_VIRTPCONSOLE; + + /* uncomment to send mac address in ks=http:/ header by default */ + flags |= LOADER_FLAGS_KICKSTART_SEND_MAC; + + /* JKFIXME: I do NOT like this... it also looks kind of bogus */ #if defined(__s390__) || defined(__s390x__) - flags |= LOADER_FLAGS_NOSHELL; + flags |= LOADER_FLAGS_NOSHELL; #endif - openLog(); - openlog("loader", 0, LOG_LOCAL0); - - memset(&loaderData, 0, sizeof(loaderData)); - loaderData.method = -1; - loaderData.fw_loader_pid = -1; - loaderData.fw_search_pathz_len = -1; - loaderData.dhcpTimeout = -1; + openLog(); + openlog("loader", 0, LOG_LOCAL0); - extraArgs[0] = NULL; - parseCmdLineFlags(&loaderData, cmdLine); + memset(&loaderData, 0, sizeof(loaderData)); + loaderData.method = -1; + loaderData.fw_loader_pid = -1; + loaderData.fw_search_pathz_len = -1; + loaderData.dhcpTimeout = -1; - logMessage(INFO, "anaconda version %s on %s starting", VERSION, getProductArch()); + extraArgs[0] = NULL; + parseCmdLineFlags(&loaderData, cmdLine); - if ((FL_SERIAL(flags) || FL_VIRTPCONSOLE(flags)) && - !hasGraphicalOverride()) { - logMessage(INFO, "text mode forced due to serial/virtpconsole"); - flags |= LOADER_FLAGS_TEXT; - } - set_fw_search_path(&loaderData, "/firmware:/lib/firmware"); - start_fw_loader(&loaderData); + logMessage(INFO, "anaconda version %s on %s starting", VERSION, + getProductArch()); - arg = "/lib/modules/module-info"; - modInfo = newModuleInfoSet(); - if (readModuleInfo(arg, modInfo, NULL, 0)) { - fprintf(stderr, "failed to read %s\n", arg); - sleep(5); - stop_fw_loader(&loaderData); - doExit(1); - } - initializeConsole(); + if ((FL_SERIAL(flags) || FL_VIRTPCONSOLE(flags)) && + !hasGraphicalOverride()) { + logMessage(INFO, "text mode forced due to serial/virtpconsole"); + flags |= LOADER_FLAGS_TEXT; + } + set_fw_search_path(&loaderData, "/firmware:/lib/firmware"); + start_fw_loader(&loaderData); + + arg = "/lib/modules/module-info"; + modInfo = newModuleInfoSet(); + if (readModuleInfo(arg, modInfo, NULL, 0)) { + fprintf(stderr, "failed to read %s\n", arg); + sleep(5); + stop_fw_loader(&loaderData); + doExit(1); + } + initializeConsole(); - checkForRam(); + checkForRam(); - /* iSeries vio console users will be ssh'ing in to the primary - partition, so use a terminal type that is appripriate */ - if (isVioConsole()) - setenv("TERM", "vt100", 1); + /* iSeries vio console users will be ssh'ing in to the primary + partition, so use a terminal type that is appripriate */ + if (isVioConsole()) + setenv("TERM", "vt100", 1); - mlLoadModuleSet("cramfs:squashfs:iscsi_tcp"); + mlLoadModuleSet("cramfs:squashfs:iscsi_tcp"); #if !defined(__s390__) && !defined(__s390x__) - mlLoadModuleSet("floppy:edd:pcspkr:iscsi_ibft"); + mlLoadModuleSet("floppy:edd:pcspkr:iscsi_ibft"); #endif #ifdef ENABLE_IPV6 - if (!FL_NOIPV6(flags)) - mlLoadModule("ipv6", NULL); + if (!FL_NOIPV6(flags)) + mlLoadModule("ipv6", NULL); #endif - /* now let's do some initial hardware-type setup */ - dasdSetup(); + /* now let's do some initial hardware-type setup */ + dasdSetup(); #if defined(__powerpc__) - mlLoadModule("spufs", NULL); + mlLoadModule("spufs", NULL); #endif - if (loaderData.lang && (loaderData.lang_set == 1)) { - setLanguage(loaderData.lang, 1); - } + if (loaderData.lang && (loaderData.lang_set == 1)) { + setLanguage(loaderData.lang, 1); + } - /* FIXME: this is a bit of a hack */ - loaderData.modInfo = modInfo; + /* FIXME: this is a bit of a hack */ + loaderData.modInfo = modInfo; - if (FL_MODDISK(flags)) { - startNewt(); - loadDriverDisks(DEVICE_ANY, &loaderData); - } + if (FL_MODDISK(flags)) { + startNewt(); + loadDriverDisks(DEVICE_ANY, &loaderData); + } - if (!access("/dd.img", R_OK)) { - logMessage(INFO, "found /dd.img, loading drivers"); - getDDFromSource(&loaderData, "path:/dd.img"); - } + if (!access("/dd.img", R_OK)) { + logMessage(INFO, "found /dd.img, loading drivers"); + getDDFromSource(&loaderData, "path:/dd.img"); + } - /* this allows us to do an early load of modules specified on the - * command line to allow automating the load order of modules so that - * eg, certain scsi controllers are definitely first. - * FIXME: this syntax is likely to change in a future release - * but is done as a quick hack for the present. - */ - if (!mlInitModuleConfig()) { - logMessage(ERROR, "unable to initialize kernel module loading"); - abort(); - } + /* this allows us to do an early load of modules specified on the + * command line to allow automating the load order of modules so that + * eg, certain scsi controllers are definitely first. + * FIXME: this syntax is likely to change in a future release + * but is done as a quick hack for the present. + */ + if (!mlInitModuleConfig()) { + logMessage(ERROR, "unable to initialize kernel module loading"); + abort(); + } - earlyModuleLoad(0); + earlyModuleLoad(0); - busProbe(FL_NOPROBE(flags)); + busProbe(FL_NOPROBE(flags)); - /* Disable all network interfaces in NetworkManager by default */ + /* Disable all network interfaces in NetworkManager by default */ #if !defined(__s390__) && !defined(__s390x__) - int i; + int i; - if ((i = writeDisabledNetInfo()) != 0) { - logMessage(ERROR, "writeDisabledNetInfo failure: %d", i); - } + if ((i = writeDisabledNetInfo()) != 0) { + logMessage(ERROR, "writeDisabledNetInfo failure: %d", i); + } #endif - /* Start NetworkManager now so it's always available to talk to. */ - if (iface_start_NetworkManager()) - logMessage(INFO, "failed to start NetworkManager"); - - if (!FL_CMDLINE(flags)) - startNewt(); - - /* can't run gdbserver until after network modules are loaded */ - doGdbserver(&loaderData); - - /* JKFIXME: we'd really like to do this before the busprobe, but then - * we won't have network devices available (and that's the only thing - * we support with this right now */ - if (loaderData.ddsrc != NULL) { - getDDFromSource(&loaderData, loaderData.ddsrc); - } - - /* JKFIXME: loaderData->ksFile is set to the arg from the command line, - * and then getKickstartFile() changes it and sets FL_KICKSTART. - * kind of weird. */ - if (loaderData.ksFile || ksFile) { - logMessage(INFO, "getting kickstart file"); - - if (!ksFile) - getKickstartFile(&loaderData); - if (FL_KICKSTART(flags) && - (ksReadCommands((ksFile)?ksFile:loaderData.ksFile)!=LOADER_ERROR)) { - runKickstart(&loaderData); - } - } - - if (FL_TELNETD(flags)) - startTelnetd(&loaderData); - - url = doLoaderMain(&loaderData, modInfo); - - /* unlink dirs and link to the ones in /mnt/runtime */ - migrate_runtime_directory("/usr"); - migrate_runtime_directory("/lib"); - migrate_runtime_directory("/lib64"); - ret = symlink("/mnt/runtime/etc/selinux", "/etc/selinux"); - copyDirectory("/mnt/runtime/etc","/etc", NULL, copyErrorFn); - copyDirectory("/mnt/runtime/var","/var", NULL, copyErrorFn); - - /* now load SELinux policy before exec'ing anaconda and the shell - * (if we're using SELinux) */ - if (FL_SELINUX(flags)) { - if (mount("/selinux", "/selinux", "selinuxfs", 0, NULL)) { - logMessage(ERROR, "failed to mount /selinux: %m, disabling SELinux"); - flags &= ~LOADER_FLAGS_SELINUX; - } else { - if (loadpolicy() == 0) { - setexeccon(ANACONDA_CONTEXT); - } else { - logMessage(ERROR, "failed to load policy, disabling SELinux"); - flags &= ~LOADER_FLAGS_SELINUX; - } - } - } - - logMessage(INFO, "getting ready to spawn shell now"); - - spawnShell(); /* we can attach gdb now :-) */ - - if (FL_NOPROBE(flags) && !loaderData.ksFile) { - startNewt(); - manualDeviceCheck(&loaderData); - } - - if (loaderData.updatessrc) - loadUpdatesFromRemote(loaderData.updatessrc, &loaderData); - else if (FL_UPDATES(flags)) - loadUpdates(&loaderData); - - /* make sure /tmp/updates exists so that magic in anaconda to */ - /* symlink rhpl/ will work */ - if (access("/tmp/updates", F_OK)) - mkdirChain("/tmp/updates"); - - add_fw_search_dir(&loaderData, "/tmp/updates/firmware"); - add_fw_search_dir(&loaderData, "/tmp/product/firmware"); - - add_to_path_env("PYTHONPATH", "/tmp/updates"); - add_to_path_env("PYTHONPATH", "/tmp/updates/iw"); - add_to_path_env("PYTHONPATH", "/tmp/updates/textw"); - add_to_path_env("PYTHONPATH", "/tmp/product"); - add_to_path_env("LD_LIBRARY_PATH", "/tmp/updates"); - add_to_path_env("LD_LIBRARY_PATH", "/tmp/product"); - add_to_path_env("PATH", "/tmp/updates"); - add_to_path_env("PATH", "/tmp/product"); - - stop_fw_loader(&loaderData); - start_fw_loader(&loaderData); - - mlLoadModuleSet("raid0:raid1:raid5:raid6:raid456:raid10:linear:dm-mod:dm-zero:dm-mirror:dm-snapshot:dm-multipath:dm-round-robin:dm-crypt:cbc:sha256:lrw:xts"); - - if (!access("/mnt/runtime/usr/lib/libunicode-lite.so.1", R_OK)) - setenv("LD_PRELOAD", "/mnt/runtime/usr/lib/libunicode-lite.so.1", 1); - if (!access("/mnt/runtime/usr/lib64/libunicode-lite.so.1", R_OK)) - setenv("LD_PRELOAD", "/mnt/runtime/usr/lib64/libunicode-lite.so.1", 1); - - argptr = anacondaArgs; - - path = getenv("PATH"); - while (path && path[0]) { - int n = strcspn(path, ":"); - char c, *binpath; - - c = path[n]; - path[n] = '\0'; - checked_asprintf(&binpath, "%s/anaconda", path); - path[n] = c; - - if (!access(binpath, X_OK)) { - *argptr++ = strdupa(binpath); - free(binpath); - break; - } - free(binpath); - path += n + 1; - } - - logMessage(INFO, "Running anaconda script %s", *(argptr-1)); - - *argptr++ = "--stage2"; - if (strncmp(url, "ftp:", 4)) { - *argptr++ = url; - } else { - int fd, ret; - - fd = open("/tmp/ftp-stage2", O_CREAT | O_TRUNC | O_RDWR, 0600); - ret = write(fd, url, strlen(url)); - ret = write(fd, "\r", 1); - close(fd); - *argptr++ = "@/tmp/ftp-stage2"; - } - - /* add extra args - this potentially munges extraArgs */ - tmparg = extraArgs; - while (*tmparg) { - char *idx; - - logMessage(DEBUGLVL, "adding extraArg %s", *tmparg); - idx = strchr(*tmparg, '='); - if (idx && ((idx-*tmparg) < strlen(*tmparg))) { - *idx = '\0'; - *argptr++ = *tmparg; - *argptr++ = idx+1; - } else { - *argptr++ = *tmparg; - } - - tmparg++; - } - - if (FL_NOIPV4(flags)) - *argptr++ = "--noipv4"; + /* Start NetworkManager now so it's always available to talk to. */ + if (iface_start_NetworkManager()) + logMessage(INFO, "failed to start NetworkManager"); + + if (!FL_CMDLINE(flags)) + startNewt(); + + /* can't run gdbserver until after network modules are loaded */ + doGdbserver(&loaderData); + + /* JKFIXME: we'd really like to do this before the busprobe, but then + * we won't have network devices available (and that's the only thing + * we support with this right now */ + if (loaderData.ddsrc != NULL) { + getDDFromSource(&loaderData, loaderData.ddsrc); + } + + /* JKFIXME: loaderData->ksFile is set to the arg from the command line, + * and then getKickstartFile() changes it and sets FL_KICKSTART. + * kind of weird. */ + if (loaderData.ksFile || ksFile) { + logMessage(INFO, "getting kickstart file"); + + if (!ksFile) + getKickstartFile(&loaderData); + if (FL_KICKSTART(flags) && + (ksReadCommands((ksFile) ? ksFile : loaderData.ksFile) != + LOADER_ERROR)) { + runKickstart(&loaderData); + } + } + + if (FL_TELNETD(flags)) + startTelnetd(&loaderData); + + url = doLoaderMain(&loaderData, modInfo); + + /* unlink dirs and link to the ones in /mnt/runtime */ + migrate_runtime_directory("/usr"); + migrate_runtime_directory("/lib"); + migrate_runtime_directory("/lib64"); + ret = symlink("/mnt/runtime/etc/selinux", "/etc/selinux"); + copyDirectory("/mnt/runtime/etc", "/etc", NULL, copyErrorFn); + copyDirectory("/mnt/runtime/var", "/var", NULL, copyErrorFn); + + /* now load SELinux policy before exec'ing anaconda and the shell + * (if we're using SELinux) */ + if (FL_SELINUX(flags)) { + if (mount("/selinux", "/selinux", "selinuxfs", 0, NULL)) { + logMessage(ERROR, + "failed to mount /selinux: %m, disabling SELinux"); + flags &= ~LOADER_FLAGS_SELINUX; + } else { + if (loadpolicy() == 0) { + setexeccon(ANACONDA_CONTEXT); + } else { + logMessage(ERROR, + "failed to load policy, disabling SELinux"); + flags &= ~LOADER_FLAGS_SELINUX; + } + } + } + + logMessage(INFO, "getting ready to spawn shell now"); + + spawnShell(); /* we can attach gdb now :-) */ + + if (FL_NOPROBE(flags) && !loaderData.ksFile) { + startNewt(); + manualDeviceCheck(&loaderData); + } + + if (loaderData.updatessrc) + loadUpdatesFromRemote(loaderData.updatessrc, &loaderData); + else if (FL_UPDATES(flags)) + loadUpdates(&loaderData); + + /* make sure /tmp/updates exists so that magic in anaconda to */ + /* symlink rhpl/ will work */ + if (access("/tmp/updates", F_OK)) + mkdirChain("/tmp/updates"); + + add_fw_search_dir(&loaderData, "/tmp/updates/firmware"); + add_fw_search_dir(&loaderData, "/tmp/product/firmware"); + + add_to_path_env("PYTHONPATH", "/tmp/updates"); + add_to_path_env("PYTHONPATH", "/tmp/updates/iw"); + add_to_path_env("PYTHONPATH", "/tmp/updates/textw"); + add_to_path_env("PYTHONPATH", "/tmp/product"); + add_to_path_env("LD_LIBRARY_PATH", "/tmp/updates"); + add_to_path_env("LD_LIBRARY_PATH", "/tmp/product"); + add_to_path_env("PATH", "/tmp/updates"); + add_to_path_env("PATH", "/tmp/product"); + + stop_fw_loader(&loaderData); + start_fw_loader(&loaderData); + + mlLoadModuleSet + ("raid0:raid1:raid5:raid6:raid456:raid10:linear:dm-mod:dm-zero:dm-mirror:dm-snapshot:dm-multipath:dm-round-robin:dm-crypt:cbc:sha256:lrw:xts"); + + if (!access("/mnt/runtime/usr/lib/libunicode-lite.so.1", R_OK)) + setenv("LD_PRELOAD", + "/mnt/runtime/usr/lib/libunicode-lite.so.1", 1); + if (!access("/mnt/runtime/usr/lib64/libunicode-lite.so.1", R_OK)) + setenv("LD_PRELOAD", + "/mnt/runtime/usr/lib64/libunicode-lite.so.1", 1); + + argptr = anacondaArgs; + + path = getenv("PATH"); + while (path && path[0]) { + int n = strcspn(path, ":"); + char c, *binpath; + + c = path[n]; + path[n] = '\0'; + checked_asprintf(&binpath, "%s/anaconda", path); + path[n] = c; + + if (!access(binpath, X_OK)) { + *argptr++ = strdupa(binpath); + free(binpath); + break; + } + free(binpath); + path += n + 1; + } + + logMessage(INFO, "Running anaconda script %s", *(argptr - 1)); + + *argptr++ = "--stage2"; + if (strncmp(url, "ftp:", 4)) { + *argptr++ = url; + } else { + int fd, ret; + + fd = open("/tmp/ftp-stage2", O_CREAT | O_TRUNC | O_RDWR, 0600); + ret = write(fd, url, strlen(url)); + ret = write(fd, "\r", 1); + close(fd); + *argptr++ = "@/tmp/ftp-stage2"; + } + + /* add extra args - this potentially munges extraArgs */ + tmparg = extraArgs; + while (*tmparg) { + char *idx; + + logMessage(DEBUGLVL, "adding extraArg %s", *tmparg); + idx = strchr(*tmparg, '='); + if (idx && ((idx - *tmparg) < strlen(*tmparg))) { + *idx = '\0'; + *argptr++ = *tmparg; + *argptr++ = idx + 1; + } else { + *argptr++ = *tmparg; + } + + tmparg++; + } + + if (FL_NOIPV4(flags)) + *argptr++ = "--noipv4"; #ifdef ENABLE_IPV6 - if (FL_NOIPV6(flags)) - *argptr++ = "--noipv6"; + if (FL_NOIPV6(flags)) + *argptr++ = "--noipv6"; #endif - if (FL_KICKSTART(flags)) { - *argptr++ = "--kickstart"; - *argptr++ = loaderData.ksFile; - } - - if (FL_SERIAL(flags)) - *argptr++ = "--serial"; - - if (FL_RESCUE(flags)) { - *argptr++ = "--rescue"; - } else { - if (FL_TEXT(flags)) - *argptr++ = "-T"; - else if (FL_GRAPHICAL(flags)) - *argptr++ = "--graphical"; - if (FL_CMDLINE(flags)) - *argptr++ = "-C"; - if (!FL_SELINUX(flags)) - *argptr++ = "--noselinux"; - else if (FL_SELINUX(flags)) - *argptr++ = "--selinux"; - - if (FL_VIRTPCONSOLE(flags)) { - *argptr++ = "--virtpconsole"; - *argptr++ = virtpcon; - } - - if (loaderData.updatessrc && FL_UPDATES(flags)) { - *argptr++ = "--updates"; - *argptr++ = loaderData.updatessrc; - } - - if (loaderData.dogtailurl) { - *argptr++ = "--dogtail"; - *argptr++ = loaderData.dogtailurl; - } - - if ((loaderData.lang) && !FL_NOPASS(flags)) { - *argptr++ = "--lang"; - *argptr++ = loaderData.lang; - } - - if ((loaderData.kbd) && !FL_NOPASS(flags)) { - *argptr++ = "--keymap"; - *argptr++ = loaderData.kbd; - } - - if (loaderData.logLevel) { - *argptr++ = "--loglevel"; - *argptr++ = loaderData.logLevel; - } - - if (loaderData.instRepo) { - *argptr++ = "--repo"; - if (strncmp(loaderData.instRepo, "ftp:", 4)) { - *argptr++ = loaderData.instRepo; - } else { - int fd, ret; - - fd = open("/tmp/ftp-repo", O_CREAT | O_TRUNC | O_RDWR, 0600); - ret = write(fd, loaderData.instRepo, strlen(loaderData.instRepo)); - ret = write(fd, "\r", 1); - close(fd); - *argptr++ = "@/tmp/ftp-repo"; - } - } - - if (loaderData.proxy && strcmp("", loaderData.proxy)) { - char *tmp = NULL; - *argptr++ = "--proxy"; - - tmp = strdup(loaderData.proxy); - if (loaderData.proxyPort) { - tmp = realloc(tmp, strlen(tmp)+strlen(loaderData.proxyPort)+2); - tmp = strcat(tmp, ":"); - tmp = strcat(tmp, loaderData.proxyPort); - } - - *argptr++ = tmp; - - if (loaderData.proxyUser) { - int fd, ret; - - fd = open("/tmp/proxy", O_CREAT|O_TRUNC|O_RDWR, 0600); - ret = write(fd, loaderData.proxyUser, strlen(loaderData.proxyUser)); - ret = write(fd, "\r\n", 2); - - if (loaderData.proxyPassword) { - ret = write(fd, loaderData.proxyPassword, strlen(loaderData.proxyPassword)); - ret = write(fd, "\r\n", 2); - } - - close(fd); - - *argptr++ = "--proxyAuth"; - *argptr++ = "/tmp/proxy"; - } - } - } - - *argptr = NULL; - - stopNewt(); - closeLog(); - - if (FL_RESCUE(flags)) { - fmt = _("Running anaconda %s, the %s rescue mode - please wait.\n"); - } else { - fmt = _("Running anaconda %s, the %s system installer - please wait.\n"); - } - printf(fmt, VERSION, getProductName()); - - if (!(pid = fork())) { - if (execv(anacondaArgs[0], anacondaArgs) == -1) { - fprintf(stderr,"exec of anaconda failed: %m\n"); - doExit(1); - } - } - - waitpid(pid, &status, 0); - - if (!WIFEXITED(status) || (WIFEXITED(status) && WEXITSTATUS(status))) { - rc = 1; - } else { - rc = 0; - } - - if ((rc == 0) && (FL_POWEROFF(flags) || FL_HALT(flags))) { - if (!(pid = fork())) { - char * cmd = (FL_POWEROFF(flags) ? strdup("/sbin/poweroff") : - strdup("/sbin/halt")); - if (execl(cmd, cmd, NULL) == -1) { - fprintf(stderr, "exec of poweroff failed: %m\n"); - doExit(1); - } - } - waitpid(pid, &status, 0); - } - - stop_fw_loader(&loaderData); + if (FL_KICKSTART(flags)) { + *argptr++ = "--kickstart"; + *argptr++ = loaderData.ksFile; + } + + if (FL_SERIAL(flags)) + *argptr++ = "--serial"; + + if (FL_RESCUE(flags)) { + *argptr++ = "--rescue"; + } else { + if (FL_TEXT(flags)) + *argptr++ = "-T"; + else if (FL_GRAPHICAL(flags)) + *argptr++ = "--graphical"; + if (FL_CMDLINE(flags)) + *argptr++ = "-C"; + if (!FL_SELINUX(flags)) + *argptr++ = "--noselinux"; + else if (FL_SELINUX(flags)) + *argptr++ = "--selinux"; + + if (FL_VIRTPCONSOLE(flags)) { + *argptr++ = "--virtpconsole"; + *argptr++ = virtpcon; + } + + if (loaderData.updatessrc && FL_UPDATES(flags)) { + *argptr++ = "--updates"; + *argptr++ = loaderData.updatessrc; + } + + if (loaderData.dogtailurl) { + *argptr++ = "--dogtail"; + *argptr++ = loaderData.dogtailurl; + } + + if ((loaderData.lang) && !FL_NOPASS(flags)) { + *argptr++ = "--lang"; + *argptr++ = loaderData.lang; + } + + if ((loaderData.kbd) && !FL_NOPASS(flags)) { + *argptr++ = "--keymap"; + *argptr++ = loaderData.kbd; + } + + if (loaderData.logLevel) { + *argptr++ = "--loglevel"; + *argptr++ = loaderData.logLevel; + } + + if (loaderData.instRepo) { + *argptr++ = "--repo"; + if (strncmp(loaderData.instRepo, "ftp:", 4)) { + *argptr++ = loaderData.instRepo; + } else { + int fd, ret; + + fd = open("/tmp/ftp-repo", + O_CREAT | O_TRUNC | O_RDWR, 0600); + ret = + write(fd, loaderData.instRepo, + strlen(loaderData.instRepo)); + ret = write(fd, "\r", 1); + close(fd); + *argptr++ = "@/tmp/ftp-repo"; + } + } + + if (loaderData.proxy && strcmp("", loaderData.proxy)) { + char *tmp = NULL; + *argptr++ = "--proxy"; + + tmp = strdup(loaderData.proxy); + if (loaderData.proxyPort) { + tmp = + realloc(tmp, + strlen(tmp) + + strlen(loaderData.proxyPort) + 2); + tmp = strcat(tmp, ":"); + tmp = strcat(tmp, loaderData.proxyPort); + } + + *argptr++ = tmp; + + if (loaderData.proxyUser) { + int fd, ret; + + fd = open("/tmp/proxy", + O_CREAT | O_TRUNC | O_RDWR, 0600); + ret = + write(fd, loaderData.proxyUser, + strlen(loaderData.proxyUser)); + ret = write(fd, "\r\n", 2); + + if (loaderData.proxyPassword) { + ret = + write(fd, loaderData.proxyPassword, + strlen + (loaderData.proxyPassword)); + ret = write(fd, "\r\n", 2); + } + + close(fd); + + *argptr++ = "--proxyAuth"; + *argptr++ = "/tmp/proxy"; + } + } + } + + *argptr = NULL; + + stopNewt(); + closeLog(); + + if (FL_RESCUE(flags)) { + fmt = + _ + ("Running anaconda %s, the %s rescue mode - please wait.\n"); + } else { + fmt = + _ + ("Running anaconda %s, the %s system installer - please wait.\n"); + } + printf(fmt, VERSION, getProductName()); + + if (!(pid = fork())) { + if (execv(anacondaArgs[0], anacondaArgs) == -1) { + fprintf(stderr, "exec of anaconda failed: %m\n"); + doExit(1); + } + } + + waitpid(pid, &status, 0); + + if (!WIFEXITED(status) || (WIFEXITED(status) && WEXITSTATUS(status))) { + rc = 1; + } else { + rc = 0; + } + + if ((rc == 0) && (FL_POWEROFF(flags) || FL_HALT(flags))) { + if (!(pid = fork())) { + char *cmd = + (FL_POWEROFF(flags) ? strdup("/sbin/poweroff") : + strdup("/sbin/halt")); + if (execl(cmd, cmd, NULL) == -1) { + fprintf(stderr, + "exec of poweroff failed: %m\n"); + doExit(1); + } + } + waitpid(pid, &status, 0); + } + + stop_fw_loader(&loaderData); #if defined(__s390__) || defined(__s390x__) - /* at the latest possibility signal init=linuxrc.s390 to reboot/halt */ - logMessage(INFO, "Sending signal %d to process %d\n", - init_sig, init_pid); - kill(init_pid, init_sig); + /* at the latest possibility signal init=linuxrc.s390 to reboot/halt */ + logMessage(INFO, "Sending signal %d to process %d\n", + init_sig, init_pid); + kill(init_pid, init_sig); #endif - doExit(rc); + doExit(rc); - doExit(1); + doExit(1); } /* vim:set sw=8 noet */ diff --git a/loader/loader.h b/loader/loader.h index 6ed2197..88a985b 100644 --- a/loader/loader.h +++ b/loader/loader.h @@ -109,9 +109,9 @@ void startNewt(void); void stopNewt(void); -char * getProductName(void); -char * getProductPath(void); -char * getProductArch(void); +char *getProductName(void); +char *getProductPath(void); +char *getProductArch(void); #include "moduleinfo.h" #include "../isys/devices.h" @@ -119,50 +119,52 @@ char * getProductArch(void); * we can't tell if it was explicitly set by kickstart/cmdline or * if we just got it going through the install. */ struct loaderData_s { - char * lang; - int lang_set; - char * kbd; - int kbd_set; - char * netDev; - int netDev_set; - char * bootIf; - int bootIf_set; - char * netCls; - int netCls_set; - char *ipv4, *netmask, *gateway, *dns, *hostname, *peerid, *ethtool, *subchannels, *portname, *essid, *wepkey, *nettype, *ctcprot, *layer2, *portno, *macaddr; + char *lang; + int lang_set; + char *kbd; + int kbd_set; + char *netDev; + int netDev_set; + char *bootIf; + int bootIf_set; + char *netCls; + int netCls_set; + char *ipv4, *netmask, *gateway, *dns, *hostname, *peerid, *ethtool, + *subchannels, *portname, *essid, *wepkey, *nettype, *ctcprot, + *layer2, *portno, *macaddr; #ifdef ENABLE_IPV6 - char *ipv6; - int ipv6info_set; + char *ipv6; + int ipv6info_set; #endif - int mtu; - int noDns; - int dhcpTimeout; - int ipinfo_set; - char * ksFile; - int method; - char * ddsrc; - void * stage2Data; - char * logLevel; - char * updatessrc; - char * dogtailurl; - char * gdbServer; - char * instRepo; - - pid_t fw_loader_pid; - char *fw_search_pathz; - size_t fw_search_pathz_len; - - moduleInfoSet modInfo; - - int inferredStage2, invalidRepoParam; - - /* Proxy info needs to be in the loaderData so we can get these - * settings off the command line, too. - */ - char *proxy; - char *proxyPort; - char *proxyUser; - char *proxyPassword; + int mtu; + int noDns; + int dhcpTimeout; + int ipinfo_set; + char *ksFile; + int method; + char *ddsrc; + void *stage2Data; + char *logLevel; + char *updatessrc; + char *dogtailurl; + char *gdbServer; + char *instRepo; + + pid_t fw_loader_pid; + char *fw_search_pathz; + size_t fw_search_pathz_len; + + moduleInfoSet modInfo; + + int inferredStage2, invalidRepoParam; + + /* Proxy info needs to be in the loaderData so we can get these + * settings off the command line, too. + */ + char *proxy; + char *proxyPort; + char *proxyUser; + char *proxyPassword; }; /* 64 bit platforms, definitions courtesy of glib */ diff --git a/loader/loadermisc.c b/loader/loadermisc.c index f998b57..b20348e 100644 --- a/loader/loadermisc.c +++ b/loader/loadermisc.c @@ -35,117 +35,124 @@ #include "log.h" #include "windows.h" -int copyFileFd(int infd, char * dest, progressCB pbcb, - struct progressCBdata *data, long long total) { - int outfd; - char buf[4096]; - int i; - int rc = 0; - long long count = 0; - - outfd = open(dest, O_CREAT | O_RDWR, 0666); - - if (outfd < 0) { - logMessage(ERROR, "failed to open %s: %m", dest); - return 1; - } - - while ((i = read(infd, buf, sizeof(buf))) > 0) { - if (write(outfd, buf, i) != i) { - rc = 1; - break; - } - - count += i; - - if (pbcb && data && total) { - pbcb(data, count, total); - } - } - - close(outfd); - - return rc; +int copyFileFd(int infd, char *dest, progressCB pbcb, + struct progressCBdata *data, long long total) +{ + int outfd; + char buf[4096]; + int i; + int rc = 0; + long long count = 0; + + outfd = open(dest, O_CREAT | O_RDWR, 0666); + + if (outfd < 0) { + logMessage(ERROR, "failed to open %s: %m", dest); + return 1; + } + + while ((i = read(infd, buf, sizeof(buf))) > 0) { + if (write(outfd, buf, i) != i) { + rc = 1; + break; + } + + count += i; + + if (pbcb && data && total) { + pbcb(data, count, total); + } + } + + close(outfd); + + return rc; } -int copyFile(char * source, char * dest) { - int infd = -1; - int rc; +int copyFile(char *source, char *dest) +{ + int infd = -1; + int rc; - infd = open(source, O_RDONLY); + infd = open(source, O_RDONLY); - if (infd < 0) { - logMessage(ERROR, "failed to open %s: %m", source); - return 1; - } + if (infd < 0) { + logMessage(ERROR, "failed to open %s: %m", source); + return 1; + } - rc = copyFileFd(infd, dest, NULL, NULL, 0); + rc = copyFileFd(infd, dest, NULL, NULL, 0); - close(infd); + close(infd); - return rc; + return rc; } -int simpleStringCmp(const void * a, const void * b) { - const char * first = *((const char **) a); - const char * second = *((const char **) b); +int simpleStringCmp(const void *a, const void *b) +{ + const char *first = *((const char **)a); + const char *second = *((const char **)b); - return strverscmp(first, second); + return strverscmp(first, second); } /* look for available memory. note: won't ever report more than the * 900 megs or so supported by the -BOOT kernel due to not using e820 */ -int totalMemory(void) { - int fd; - int bytesRead; - char buf[4096]; - char * chptr, * start; - int total = 0; - - fd = open("/proc/meminfo", O_RDONLY); - if (fd < 0) { - logMessage(ERROR, "failed to open /proc/meminfo: %m"); - return 0; - } - - bytesRead = read(fd, buf, sizeof(buf) - 1); - if (bytesRead < 0) { - logMessage(ERROR, "failed to read from /proc/meminfo: %m"); - close(fd); - return 0; - } - - close(fd); - buf[bytesRead] = '\0'; - - chptr = buf; - while (*chptr && !total) { - if (strncmp(chptr, "MemTotal:", 9)) { - chptr++; - continue; - } - - start = ++chptr ; - while (*chptr && *chptr != '\n') chptr++; - - *chptr = '\0'; - - while (!isdigit(*start) && *start) start++; - if (!*start) { - logMessage(WARNING, "no number appears after MemTotal tag"); - return 0; - } - - chptr = start; - while (*chptr && isdigit(*chptr)) { - total = (total * 10) + (*chptr - '0'); - chptr++; - } - } - - logMessage(INFO, "%d kB are available", total); - - return total; +int totalMemory(void) +{ + int fd; + int bytesRead; + char buf[4096]; + char *chptr, *start; + int total = 0; + + fd = open("/proc/meminfo", O_RDONLY); + if (fd < 0) { + logMessage(ERROR, "failed to open /proc/meminfo: %m"); + return 0; + } + + bytesRead = read(fd, buf, sizeof(buf) - 1); + if (bytesRead < 0) { + logMessage(ERROR, "failed to read from /proc/meminfo: %m"); + close(fd); + return 0; + } + + close(fd); + buf[bytesRead] = '\0'; + + chptr = buf; + while (*chptr && !total) { + if (strncmp(chptr, "MemTotal:", 9)) { + chptr++; + continue; + } + + start = ++chptr; + while (*chptr && *chptr != '\n') + chptr++; + + *chptr = '\0'; + + while (!isdigit(*start) && *start) + start++; + if (!*start) { + logMessage(WARNING, + "no number appears after MemTotal tag"); + return 0; + } + + chptr = start; + while (*chptr && isdigit(*chptr)) { + total = (total * 10) + (*chptr - '0'); + chptr++; + } + } + + logMessage(INFO, "%d kB are available", total); + + return total; } /* vim:set sw=8 noet */ diff --git a/loader/loadermisc.h b/loader/loadermisc.h index 8a97360..f60f9a5 100644 --- a/loader/loadermisc.h +++ b/loader/loadermisc.h @@ -24,10 +24,10 @@ #include "windows.h" -int copyFile(char * source, char * dest); -int copyFileFd(int infd, char * dest, progressCB pbcb, - struct progressCBdata *data, long long total); -int simpleStringCmp(const void * a, const void * b); +int copyFile(char *source, char *dest); +int copyFileFd(int infd, char *dest, progressCB pbcb, + struct progressCBdata *data, long long total); +int simpleStringCmp(const void *a, const void *b); int totalMemory(void); #endif diff --git a/loader/log.c b/loader/log.c index ac26ad3..d4ac6c7 100644 --- a/loader/log.c +++ b/loader/log.c @@ -33,122 +33,129 @@ #include "log.h" -static FILE * tty_logfile = NULL; -static FILE * file_logfile = NULL; +static FILE *tty_logfile = NULL; +static FILE *file_logfile = NULL; static int minLevel = INFO; -static void printLogHeader(int level, FILE *outfile) { - struct timeval current_time; - struct tm *t; - int msecs; - - gettimeofday(¤t_time, NULL); - t = gmtime(¤t_time.tv_sec); - msecs = current_time.tv_usec / 1000; - switch (level) { - case DEBUGLVL: - fprintf (outfile, "%02d:%02d:%02d,%03d DEBUG : ", t->tm_hour, - t->tm_min, t->tm_sec, msecs); - break; - - case INFO: - fprintf (outfile, "%02d:%02d:%02d,%03d INFO : ", t->tm_hour, - t->tm_min, t->tm_sec, msecs); - break; - - case WARNING: - fprintf (outfile, "%02d:%02d:%02d,%03d WARNING : ", t->tm_hour, - t->tm_min, t->tm_sec, msecs); - break; - - case ERROR: - fprintf (outfile, "%02d:%02d:%02d,%03d ERROR : ", t->tm_hour, - t->tm_min, t->tm_sec, msecs); - break; - - case CRITICAL: - fprintf (outfile, "%02d:%02d:%02d,%03d CRITICAL: ", t->tm_hour, - t->tm_min, t->tm_sec, msecs); - break; - } +static void printLogHeader(int level, FILE * outfile) +{ + struct timeval current_time; + struct tm *t; + int msecs; + + gettimeofday(¤t_time, NULL); + t = gmtime(¤t_time.tv_sec); + msecs = current_time.tv_usec / 1000; + switch (level) { + case DEBUGLVL: + fprintf(outfile, "%02d:%02d:%02d,%03d DEBUG : ", t->tm_hour, + t->tm_min, t->tm_sec, msecs); + break; + + case INFO: + fprintf(outfile, "%02d:%02d:%02d,%03d INFO : ", t->tm_hour, + t->tm_min, t->tm_sec, msecs); + break; + + case WARNING: + fprintf(outfile, "%02d:%02d:%02d,%03d WARNING : ", t->tm_hour, + t->tm_min, t->tm_sec, msecs); + break; + + case ERROR: + fprintf(outfile, "%02d:%02d:%02d,%03d ERROR : ", t->tm_hour, + t->tm_min, t->tm_sec, msecs); + break; + + case CRITICAL: + fprintf(outfile, "%02d:%02d:%02d,%03d CRITICAL: ", t->tm_hour, + t->tm_min, t->tm_sec, msecs); + break; + } } -void logMessageV(int level, const char * s, va_list ap) { +void logMessageV(int level, const char *s, va_list ap) +{ - /* Only log to the screen things that are above the minimum level. */ - if (tty_logfile && level >= minLevel) { - va_list apc; + /* Only log to the screen things that are above the minimum level. */ + if (tty_logfile && level >= minLevel) { + va_list apc; - va_copy(apc, ap); + va_copy(apc, ap); - printLogHeader(level, tty_logfile); - vfprintf(tty_logfile, s, apc); - fprintf(tty_logfile, "\n"); - fflush(tty_logfile); + printLogHeader(level, tty_logfile); + vfprintf(tty_logfile, s, apc); + fprintf(tty_logfile, "\n"); + fflush(tty_logfile); - va_end(apc); - } + va_end(apc); + } - /* But log everything to the file. */ - if (file_logfile) { - va_list apc; + /* But log everything to the file. */ + if (file_logfile) { + va_list apc; - va_copy(apc, ap); + va_copy(apc, ap); - printLogHeader(level, file_logfile); - vfprintf(file_logfile, s, apc); - fprintf(file_logfile, "\n"); - fflush(file_logfile); + printLogHeader(level, file_logfile); + vfprintf(file_logfile, s, apc); + fprintf(file_logfile, "\n"); + fflush(file_logfile); - va_end(apc); - } + va_end(apc); + } } -void logMessage(int level, const char * s, ...) { - va_list args; +void logMessage(int level, const char *s, ...) +{ + va_list args; - va_start(args, s); - logMessageV(level, s, args); - va_end(args); + va_start(args, s); + logMessageV(level, s, args); + va_end(args); } int tty_logfd = -1; int file_logfd = -1; -void openLog() { - int flags; +void openLog() +{ + int flags; - tty_logfile = fopen("/dev/tty3", "w"); - file_logfile = fopen("/tmp/anaconda.log", "w"); + tty_logfile = fopen("/dev/tty3", "w"); + file_logfile = fopen("/tmp/anaconda.log", "w"); - if (tty_logfile) { - tty_logfd = fileno(tty_logfile); - flags = fcntl(tty_logfd, F_GETFD, 0) | FD_CLOEXEC; - fcntl(tty_logfd, F_SETFD, flags); - } + if (tty_logfile) { + tty_logfd = fileno(tty_logfile); + flags = fcntl(tty_logfd, F_GETFD, 0) | FD_CLOEXEC; + fcntl(tty_logfd, F_SETFD, flags); + } - if (file_logfile) { - file_logfd = fileno(file_logfile); - flags = fcntl(file_logfd, F_GETFD, 0) | FD_CLOEXEC; - fcntl(file_logfd, F_SETFD, flags); - } + if (file_logfile) { + file_logfd = fileno(file_logfile); + flags = fcntl(file_logfd, F_GETFD, 0) | FD_CLOEXEC; + fcntl(file_logfd, F_SETFD, flags); + } } -void closeLog(void) { - if (tty_logfile) - fclose(tty_logfile); +void closeLog(void) +{ + if (tty_logfile) + fclose(tty_logfile); - if (file_logfile) - fclose(file_logfile); + if (file_logfile) + fclose(file_logfile); } /* set the level. higher means you see more verbosity */ -void setLogLevel(int level) { - minLevel = level; +void setLogLevel(int level) +{ + minLevel = level; } -int getLogLevel(void) { - return minLevel; +int getLogLevel(void) +{ + return minLevel; } /* vim:set sw=8 noet */ diff --git a/loader/log.h b/loader/log.h index 3461d2a..106cb85 100644 --- a/loader/log.h +++ b/loader/log.h @@ -29,10 +29,10 @@ #define ERROR 40 #define CRITICAL 50 -void logMessageV(int level, const char * s, va_list ap) - __attribute__ ((format (printf, 2, 0))); -void logMessage(int level, const char * s, ...) - __attribute__ ((format (printf, 2, 3))); +void logMessageV(int level, const char *s, va_list ap) + __attribute__ ((format(printf, 2, 0))); +void logMessage(int level, const char *s, ...) + __attribute__ ((format(printf, 2, 3))); void openLog(); void closeLog(void); void setLogLevel(int minLevel); diff --git a/loader/mediacheck.c b/loader/mediacheck.c index 118e774..81e338b 100644 --- a/loader/mediacheck.c +++ b/loader/mediacheck.c @@ -34,79 +34,81 @@ #include "log.h" #include "windows.h" -int doMediaCheck(char *file, char *descr) { - struct progressCBdata data; - newtComponent t, f, scale, label; - int rc; - int dlen; - int llen; - char tmpstr[1024]; - - if (access(file, R_OK) < 0) { - newtWinMessage(_("Error"), _("OK"), _("Unable to find install image " - "%s"), file); - return -1; - } - - if (descr) - snprintf(tmpstr, sizeof(tmpstr), _("Checking \"%s\"."), descr); - else - snprintf(tmpstr, sizeof(tmpstr), _("Checking media.")); - - dlen = strlen(tmpstr); - if (dlen > 65) - dlen = 65; - - newtCenteredWindow(dlen+8, 6, _("Media Check")); - t = newtTextbox(1, 1, dlen+4, 3, NEWT_TEXTBOX_WRAP); - - newtTextboxSetText(t, tmpstr); - llen = strlen(tmpstr); - - label = newtLabel(llen+1, 1, "-"); - f = newtForm(NULL, NULL, 0); - newtFormAddComponent(f, t); - scale = newtScale(3, 3, dlen, 100); - newtFormAddComponent(f, scale); - - newtDrawForm(f); - newtRefresh(); - - data.scale = scale; - data.label = label; - - rc = mediaCheckFile(file, progressCallback, &data); - - newtFormDestroy(f); - newtPopWindow(); - - if (rc == -1) { - logMessage(WARNING, "mediacheck: %s (%s) has no checksum info", file, descr); - newtWinMessage(_("Error"), _("OK"), - _("Unable to read the disc checksum from the " - "primary volume descriptor. This probably " - "means the disc was created without adding the " - "checksum.")); - } else if (rc == 0) { - logMessage(ERROR, "mediacheck: %s (%s) FAILED", file, descr); - newtWinMessage(_("Error"), _("OK"), - _("The image which was just tested has errors. " - "This could be due to a " - "corrupt download or a bad disc. " - "If applicable, please clean the disc " - "and try again. If this test continues to fail you " - "should not continue the install.")); - } else if (rc > 0) { - logMessage(INFO, "mediacheck: %s (%s) PASSED", file, descr); - newtWinMessage(_("Success"), _("OK"), - _("The image which was just tested was successfully " - "verified. It should be OK to install from this " - "media. Note that not all media/drive errors can " - "be detected by the media check.")); - } - - - return rc; +int doMediaCheck(char *file, char *descr) +{ + struct progressCBdata data; + newtComponent t, f, scale, label; + int rc; + int dlen; + int llen; + char tmpstr[1024]; + + if (access(file, R_OK) < 0) { + newtWinMessage(_("Error"), _("OK"), + _("Unable to find install image " "%s"), file); + return -1; + } + + if (descr) + snprintf(tmpstr, sizeof(tmpstr), _("Checking \"%s\"."), descr); + else + snprintf(tmpstr, sizeof(tmpstr), _("Checking media.")); + + dlen = strlen(tmpstr); + if (dlen > 65) + dlen = 65; + + newtCenteredWindow(dlen + 8, 6, _("Media Check")); + t = newtTextbox(1, 1, dlen + 4, 3, NEWT_TEXTBOX_WRAP); + + newtTextboxSetText(t, tmpstr); + llen = strlen(tmpstr); + + label = newtLabel(llen + 1, 1, "-"); + f = newtForm(NULL, NULL, 0); + newtFormAddComponent(f, t); + scale = newtScale(3, 3, dlen, 100); + newtFormAddComponent(f, scale); + + newtDrawForm(f); + newtRefresh(); + + data.scale = scale; + data.label = label; + + rc = mediaCheckFile(file, progressCallback, &data); + + newtFormDestroy(f); + newtPopWindow(); + + if (rc == -1) { + logMessage(WARNING, "mediacheck: %s (%s) has no checksum info", + file, descr); + newtWinMessage(_("Error"), _("OK"), + _("Unable to read the disc checksum from the " + "primary volume descriptor. This probably " + "means the disc was created without adding the " + "checksum.")); + } else if (rc == 0) { + logMessage(ERROR, "mediacheck: %s (%s) FAILED", file, descr); + newtWinMessage(_("Error"), _("OK"), + _("The image which was just tested has errors. " + "This could be due to a " + "corrupt download or a bad disc. " + "If applicable, please clean the disc " + "and try again. If this test continues to fail you " + "should not continue the install.")); + } else if (rc > 0) { + logMessage(INFO, "mediacheck: %s (%s) PASSED", file, descr); + newtWinMessage(_("Success"), _("OK"), + _ + ("The image which was just tested was successfully " + "verified. It should be OK to install from this " + "media. Note that not all media/drive errors can " + "be detected by the media check.")); + } + + return rc; } /* vim:set sw=8 noet */ diff --git a/loader/method.c b/loader/method.c index e7e10c3..1c6eee1 100644 --- a/loader/method.c +++ b/loader/method.c @@ -58,178 +58,187 @@ /* boot flags */ extern uint64_t flags; -int umountLoopback(char * mntpoint, char * device) { - int loopfd; +int umountLoopback(char *mntpoint, char *device) +{ + int loopfd; - umount(mntpoint); + umount(mntpoint); - logMessage(INFO, "umounting loopback %s %s", mntpoint, device); + logMessage(INFO, "umounting loopback %s %s", mntpoint, device); - loopfd = open(device, O_RDONLY); + loopfd = open(device, O_RDONLY); - if (ioctl(loopfd, LOOP_CLR_FD, 0) == -1) - logMessage(ERROR, "LOOP_CLR_FD failed for %s %s: %m", mntpoint, device); + if (ioctl(loopfd, LOOP_CLR_FD, 0) == -1) + logMessage(ERROR, "LOOP_CLR_FD failed for %s %s: %m", mntpoint, + device); - close(loopfd); + close(loopfd); - return 0; + return 0; } -int mountLoopback(char *fsystem, char *mntpoint, char *device) { - char *opts, *err = NULL; +int mountLoopback(char *fsystem, char *mntpoint, char *device) +{ + char *opts, *err = NULL; - if (device == NULL) { - logMessage(ERROR, "no loopback device given"); - return LOADER_ERROR; - } + if (device == NULL) { + logMessage(ERROR, "no loopback device given"); + return LOADER_ERROR; + } - if (access(fsystem, F_OK) != 0) { - logMessage(ERROR, "file %s is not accessible", fsystem); - return LOADER_ERROR; - } + if (access(fsystem, F_OK) != 0) { + logMessage(ERROR, "file %s is not accessible", fsystem); + return LOADER_ERROR; + } - checked_asprintf(&opts, "ro,loop=%s", device); + checked_asprintf(&opts, "ro,loop=%s", device); - if (doPwMount(fsystem, mntpoint, "auto", opts, &err)) { - logMessage(ERROR, "failed to mount loopback device %s on %s as %s: %s", - device, mntpoint, fsystem, err); - return LOADER_ERROR; - } + if (doPwMount(fsystem, mntpoint, "auto", opts, &err)) { + logMessage(ERROR, + "failed to mount loopback device %s on %s as %s: %s", + device, mntpoint, fsystem, err); + return LOADER_ERROR; + } - logMessage(INFO, "mounted loopback device %s on %s as %s", mntpoint, device, fsystem); + logMessage(INFO, "mounted loopback device %s on %s as %s", mntpoint, + device, fsystem); - return 0; + return 0; } /* returns the *absolute* path (malloced) to the #1 iso image */ /* get timestamp and description of ISO image from stamp file */ /* returns 0 on success, -1 otherwise */ -int readStampFileFromIso(char *file, char **timestamp, char **releasedescr) { - DIR * dir; - FILE *f; - struct dirent * ent; - struct stat sb; - char *stampfile; - char *descr, *tstamp; - char tmpstr[1024]; - int filetype; - int rc; - - lstat(file, &sb); - if (S_ISBLK(sb.st_mode)) { - filetype = 1; - if (doPwMount(file, "/tmp/testmnt", "iso9660", "ro", NULL)) { - logMessage(ERROR, "Failed to mount device %s to get description", - file); - return -1; - } - } else if (S_ISREG(sb.st_mode)) { - filetype = 2; - if (mountLoopback(file, "/tmp/testmnt", "/dev/loop6")) { - logMessage(ERROR, "Failed to mount iso %s to get description", - file); - return -1; +int readStampFileFromIso(char *file, char **timestamp, char **releasedescr) +{ + DIR *dir; + FILE *f; + struct dirent *ent; + struct stat sb; + char *stampfile; + char *descr, *tstamp; + char tmpstr[1024]; + int filetype; + int rc; + + lstat(file, &sb); + if (S_ISBLK(sb.st_mode)) { + filetype = 1; + if (doPwMount(file, "/tmp/testmnt", "iso9660", "ro", NULL)) { + logMessage(ERROR, + "Failed to mount device %s to get description", + file); + return -1; + } + } else if (S_ISREG(sb.st_mode)) { + filetype = 2; + if (mountLoopback(file, "/tmp/testmnt", "/dev/loop6")) { + logMessage(ERROR, + "Failed to mount iso %s to get description", + file); + return -1; + } + } else { + logMessage(ERROR, "Unknown type of file %s to get description", + file); + return -1; } - } else { - logMessage(ERROR, "Unknown type of file %s to get description", - file); - return -1; - } - if (!(dir = opendir("/tmp/testmnt"))) { - umount("/tmp/testmnt"); - if (filetype == 2) - umountLoopback("/tmp/testmnt", "/dev/loop6"); - return -1; - } - - errno = 0; - stampfile = NULL; - while ((ent = readdir(dir))) { - if (!strncmp(ent->d_name, ".discinfo", 9)) { - stampfile = strdup(".discinfo"); - break; + if (!(dir = opendir("/tmp/testmnt"))) { + umount("/tmp/testmnt"); + if (filetype == 2) + umountLoopback("/tmp/testmnt", "/dev/loop6"); + return -1; } - } - - closedir(dir); - descr = NULL; - tstamp = NULL; - if (stampfile) { - snprintf(tmpstr, sizeof(tmpstr), "/tmp/testmnt/%s", stampfile); - f = fopen(tmpstr, "r"); - if (f) { - char *tmpptr; - - /* readtime stamp line */ - tmpptr = fgets(tmpstr, sizeof(tmpstr), f); - - if (tmpptr) - tstamp = strdup(tmpstr); - - /* now read OS description line */ - if (tmpptr) - tmpptr = fgets(tmpstr, sizeof(tmpstr), f); - - if (tmpptr) - descr = strdup(tmpstr); - - /* skip over arch */ - if (tmpptr) - tmpptr = fgets(tmpstr, sizeof(tmpstr), f); - - /* now get the CD number */ - if (tmpptr) { - unsigned int len; - char *p, *newstr; - - tmpptr = fgets(tmpstr, sizeof(tmpstr), f); - - /* nuke newline from end of descr, stick number on end*/ - for (p=descr+strlen(descr); p != descr && !isspace(*p); p--); - - *p = '\0'; - len = strlen(descr) + strlen(tmpstr) + 10; - newstr = malloc(len); - strncpy(newstr, descr, len-1); - strncat(newstr, " ", len-1); - - /* is this a DVD or not? If disc id has commas, like */ - /* "1,2,3", its a DVD */ - if (strchr(tmpstr, ',')) - strncat(newstr, "DVD\n", len-1); - else { - strncat(newstr, "disc ", len-1); - strncat(newstr, tmpstr, len-1); - } - free(descr); - descr = newstr; - } + errno = 0; + stampfile = NULL; + while ((ent = readdir(dir))) { + if (!strncmp(ent->d_name, ".discinfo", 9)) { + stampfile = strdup(".discinfo"); + break; + } + } - fclose(f); + closedir(dir); + descr = NULL; + tstamp = NULL; + if (stampfile) { + snprintf(tmpstr, sizeof(tmpstr), "/tmp/testmnt/%s", stampfile); + f = fopen(tmpstr, "r"); + if (f) { + char *tmpptr; + + /* readtime stamp line */ + tmpptr = fgets(tmpstr, sizeof(tmpstr), f); + + if (tmpptr) + tstamp = strdup(tmpstr); + + /* now read OS description line */ + if (tmpptr) + tmpptr = fgets(tmpstr, sizeof(tmpstr), f); + + if (tmpptr) + descr = strdup(tmpstr); + + /* skip over arch */ + if (tmpptr) + tmpptr = fgets(tmpstr, sizeof(tmpstr), f); + + /* now get the CD number */ + if (tmpptr) { + unsigned int len; + char *p, *newstr; + + tmpptr = fgets(tmpstr, sizeof(tmpstr), f); + + /* nuke newline from end of descr, stick number on end */ + for (p = descr + strlen(descr); + p != descr && !isspace(*p); p--) ; + + *p = '\0'; + len = strlen(descr) + strlen(tmpstr) + 10; + newstr = malloc(len); + strncpy(newstr, descr, len - 1); + strncat(newstr, " ", len - 1); + + /* is this a DVD or not? If disc id has commas, like */ + /* "1,2,3", its a DVD */ + if (strchr(tmpstr, ',')) + strncat(newstr, "DVD\n", len - 1); + else { + strncat(newstr, "disc ", len - 1); + strncat(newstr, tmpstr, len - 1); + } + + free(descr); + descr = newstr; + } + + fclose(f); + } } - } - free(stampfile); + free(stampfile); - umount("/tmp/testmnt"); - if (filetype == 2) - umountLoopback("/tmp/testmnt", "/dev/loop6"); + umount("/tmp/testmnt"); + if (filetype == 2) + umountLoopback("/tmp/testmnt", "/dev/loop6"); - if (descr != NULL && tstamp != NULL) { - descr[strlen(descr)-1] = '\0'; - *releasedescr = descr; + if (descr != NULL && tstamp != NULL) { + descr[strlen(descr) - 1] = '\0'; + *releasedescr = descr; - tstamp[strlen(tstamp)-1] = '\0'; - *timestamp = tstamp; + tstamp[strlen(tstamp) - 1] = '\0'; + *timestamp = tstamp; - rc = 0; - } else { - rc = 1; - } + rc = 0; + } else { + rc = 1; + } - return rc; + return rc; } /* XXX this ignores "location", which should be fixed @@ -237,223 +246,233 @@ int readStampFileFromIso(char *file, char **timestamp, char **releasedescr) { * Given a starting isoFile, will offer choice to mediacheck it and * all other ISO images in the same directory with the same stamp */ -void queryIsoMediaCheck(char *isoFile) { - DIR * dir; - struct dirent * ent; - char *isoDir; - char isoImage[1024]; - char tmpmessage[1024]; - char *master_timestamp; - char *tmpstr; - int rc, first; - - /* dont bother to test in automated installs */ - if (FL_KICKSTART(flags) && !FL_MEDIACHECK(flags)) - return; - - /* if they did not specify to mediacheck explicitely then return */ - if (!FL_MEDIACHECK(flags)) - return; - - /* check that file is actually an iso */ - if (!fileIsIso(isoFile)) - return; - - /* get stamp of isoFile, free descr since we dont care */ - readStampFileFromIso(isoFile, &master_timestamp, &tmpstr); - free(tmpstr); - - /* get base path from isoFile */ - tmpstr = strdup(isoFile); - isoDir = strdup(dirname(tmpstr)); - free(tmpstr); - - logMessage(DEBUGLVL, "isoFile = %s", isoFile); - logMessage(DEBUGLVL, "isoDir = %s", isoDir); - logMessage(DEBUGLVL, "Master Timestemp = %s", master_timestamp); - - if (!(dir = opendir(isoDir))) { - newtWinMessage(_("Error"), _("OK"), - _("Failed to read directory %s: %m"), - isoDir); - free(isoDir); - free(master_timestamp); - return; - } - - /* Walk through the directories looking for a CD images. */ - errno = 0; - first = 0; - while (1) { - char *nextname; - char *tdescr, *tstamp; - - if (first) { - first = 1; - nextname = isoFile; - } else { - ent = readdir(dir); - if (!ent) - break; - - nextname = ent->d_name; +void queryIsoMediaCheck(char *isoFile) +{ + DIR *dir; + struct dirent *ent; + char *isoDir; + char isoImage[1024]; + char tmpmessage[1024]; + char *master_timestamp; + char *tmpstr; + int rc, first; + + /* dont bother to test in automated installs */ + if (FL_KICKSTART(flags) && !FL_MEDIACHECK(flags)) + return; + + /* if they did not specify to mediacheck explicitely then return */ + if (!FL_MEDIACHECK(flags)) + return; + + /* check that file is actually an iso */ + if (!fileIsIso(isoFile)) + return; + + /* get stamp of isoFile, free descr since we dont care */ + readStampFileFromIso(isoFile, &master_timestamp, &tmpstr); + free(tmpstr); + + /* get base path from isoFile */ + tmpstr = strdup(isoFile); + isoDir = strdup(dirname(tmpstr)); + free(tmpstr); + + logMessage(DEBUGLVL, "isoFile = %s", isoFile); + logMessage(DEBUGLVL, "isoDir = %s", isoDir); + logMessage(DEBUGLVL, "Master Timestemp = %s", master_timestamp); + + if (!(dir = opendir(isoDir))) { + newtWinMessage(_("Error"), _("OK"), + _("Failed to read directory %s: %m"), isoDir); + free(isoDir); + free(master_timestamp); + return; } - /* synthesize name of iso from isoDir and file entry */ - snprintf(isoImage, sizeof(isoImage), "%s/%s", isoDir, nextname); + /* Walk through the directories looking for a CD images. */ + errno = 0; + first = 0; + while (1) { + char *nextname; + char *tdescr, *tstamp; + + if (first) { + first = 1; + nextname = isoFile; + } else { + ent = readdir(dir); + if (!ent) + break; + + nextname = ent->d_name; + } - /* see if this is an iso image */ - if (!fileIsIso(isoImage)) { - errno = 0; - continue; - } + /* synthesize name of iso from isoDir and file entry */ + snprintf(isoImage, sizeof(isoImage), "%s/%s", isoDir, nextname); - /* see if its part of the current CD set */ - readStampFileFromIso(isoImage, &tstamp, &tdescr); - if (strcmp(tstamp, master_timestamp)) { - errno = 0; - continue; - } - - /* found a valid candidate, proceed */ - snprintf(tmpmessage, sizeof(tmpmessage), - _("Would you like to perform a checksum " - "test of the ISO image:\n\n %s?"), isoImage); - - rc = newtWinChoice(_("Checksum Test"), _("Test"), _("Skip"), - tmpmessage); - - if (rc == 2) { - logMessage(INFO, "mediacheck: skipped checking of %s", isoImage); - if (tdescr) - free(tdescr); - continue; - } else { - doMediaCheck(isoImage, tdescr); - if (tdescr) - free(tdescr); + /* see if this is an iso image */ + if (!fileIsIso(isoImage)) { + errno = 0; + continue; + } + + /* see if its part of the current CD set */ + readStampFileFromIso(isoImage, &tstamp, &tdescr); + if (strcmp(tstamp, master_timestamp)) { + errno = 0; + continue; + } - continue; + /* found a valid candidate, proceed */ + snprintf(tmpmessage, sizeof(tmpmessage), + _("Would you like to perform a checksum " + "test of the ISO image:\n\n %s?"), isoImage); + + rc = newtWinChoice(_("Checksum Test"), _("Test"), _("Skip"), + tmpmessage); + + if (rc == 2) { + logMessage(INFO, "mediacheck: skipped checking of %s", + isoImage); + if (tdescr) + free(tdescr); + continue; + } else { + doMediaCheck(isoImage, tdescr); + if (tdescr) + free(tdescr); + + continue; + } } - } - free(isoDir); - free(master_timestamp); - closedir(dir); + free(isoDir); + free(master_timestamp); + closedir(dir); } -static void copyWarnFn (char *msg) { - logMessage(WARNING, msg); +static void copyWarnFn(char *msg) +{ + logMessage(WARNING, msg); } -static void copyErrorFn (char *msg) { - newtWinMessage(_("Error"), _("OK"), _(msg)); +static void copyErrorFn(char *msg) +{ + newtWinMessage(_("Error"), _("OK"), _(msg)); } /* * unpack a gzipped cpio ball into a tree rooted at rootDir * returns 0 on success, 1 on failure */ -int unpackCpioBall(char * ballPath, char * rootDir) { - gzFile fd; - char *buf, *cwd; - int rc = 1; - - if (access(ballPath, R_OK)) - return 1; - - if (access(rootDir, R_OK)) - mkdirChain(rootDir); - - buf = (char *)malloc(PATH_MAX); - cwd = getcwd(buf, PATH_MAX); - if ((rc = chdir(rootDir)) == 0) { - fd = gunzip_open(ballPath); - if (fd) { - if (!installCpioFile(fd, NULL, NULL, 0)) { - logMessage(INFO, "copied contents of %s into %s", ballPath, - rootDir); - rc = chdir(cwd); - return 0; - } - gunzip_close(fd); - } - rc = chdir(cwd); - } - - return 1; +int unpackCpioBall(char *ballPath, char *rootDir) +{ + gzFile fd; + char *buf, *cwd; + int rc = 1; + + if (access(ballPath, R_OK)) + return 1; + + if (access(rootDir, R_OK)) + mkdirChain(rootDir); + + buf = (char *)malloc(PATH_MAX); + cwd = getcwd(buf, PATH_MAX); + if ((rc = chdir(rootDir)) == 0) { + fd = gunzip_open(ballPath); + if (fd) { + if (!installCpioFile(fd, NULL, NULL, 0)) { + logMessage(INFO, + "copied contents of %s into %s", + ballPath, rootDir); + rc = chdir(cwd); + return 0; + } + gunzip_close(fd); + } + rc = chdir(cwd); + } + + return 1; } -void copyUpdatesImg(char * path) { - if (!access(path, R_OK)) { - if (!mountLoopback(path, "/tmp/update-disk", "/dev/loop7")) { - copyDirectory("/tmp/update-disk", "/tmp/updates", copyWarnFn, - copyErrorFn); - umountLoopback("/tmp/update-disk", "/dev/loop7"); - unlink("/tmp/update-disk"); - } else { - unpackCpioBall(path, "/tmp/updates"); - } - } +void copyUpdatesImg(char *path) +{ + if (!access(path, R_OK)) { + if (!mountLoopback(path, "/tmp/update-disk", "/dev/loop7")) { + copyDirectory("/tmp/update-disk", "/tmp/updates", + copyWarnFn, copyErrorFn); + umountLoopback("/tmp/update-disk", "/dev/loop7"); + unlink("/tmp/update-disk"); + } else { + unpackCpioBall(path, "/tmp/updates"); + } + } } -void copyProductImg(char * path) { - if (!access(path, R_OK)) { - if (!mountLoopback(path, "/tmp/product-disk", "/dev/loop7")) { - copyDirectory("/tmp/product-disk", "/tmp/product", copyWarnFn, - copyErrorFn); - umountLoopback("/tmp/product-disk", "/dev/loop7"); - unlink("/tmp/product-disk"); - } - } +void copyProductImg(char *path) +{ + if (!access(path, R_OK)) { + if (!mountLoopback(path, "/tmp/product-disk", "/dev/loop7")) { + copyDirectory("/tmp/product-disk", "/tmp/product", + copyWarnFn, copyErrorFn); + umountLoopback("/tmp/product-disk", "/dev/loop7"); + unlink("/tmp/product-disk"); + } + } } /* unmount a second stage, if mounted. Used for CDs and mediacheck mostly, so we can eject CDs. */ -void umountStage2(void) { - umountLoopback("/mnt/runtime", "/dev/loop0"); +void umountStage2(void) +{ + umountLoopback("/mnt/runtime", "/dev/loop0"); } /* mount a second stage, verify the stamp file, copy updates * Returns 0 on success, 1 on failure to mount, -1 on bad stamp */ -int mountStage2(char *stage2path) { - if (access(stage2path, R_OK)) { - return 1; - } +int mountStage2(char *stage2path) +{ + if (access(stage2path, R_OK)) { + return 1; + } - if (mountLoopback(stage2path, "/mnt/runtime", "/dev/loop0")) { - return 1; - } + if (mountLoopback(stage2path, "/mnt/runtime", "/dev/loop0")) { + return 1; + } - return 0; + return 0; } - /* copies a second stage from fd to dest and mounts on mntpoint */ -int copyFileAndLoopbackMount(int fd, char * dest, char * device, char * mntpoint, - progressCB pbcb, struct progressCBdata *data, - long long total) { - int rc; - struct stat sb; - - rc = copyFileFd(fd, dest, pbcb, data, total); - stat(dest, &sb); - logMessage(DEBUGLVL, "copied %" PRId64 " bytes to %s (%s)", sb.st_size, dest, - ((rc) ? " incomplete" : "complete")); - - if (rc) { - /* just to make sure */ - unlink(dest); - return 1; - } +int copyFileAndLoopbackMount(int fd, char *dest, char *device, char *mntpoint, + progressCB pbcb, struct progressCBdata *data, + long long total) +{ + int rc; + struct stat sb; + + rc = copyFileFd(fd, dest, pbcb, data, total); + stat(dest, &sb); + logMessage(DEBUGLVL, "copied %" PRId64 " bytes to %s (%s)", sb.st_size, + dest, ((rc) ? " incomplete" : "complete")); + + if (rc) { + /* just to make sure */ + unlink(dest); + return 1; + } - if (mountLoopback(dest, mntpoint, device)) { - /* JKFIXME: this used to be fatal, but that seems unfriendly */ - logMessage(ERROR, "Error mounting %s on %s: %m", device, mntpoint); - return 1; - } + if (mountLoopback(dest, mntpoint, device)) { + /* JKFIXME: this used to be fatal, but that seems unfriendly */ + logMessage(ERROR, "Error mounting %s on %s: %m", device, + mntpoint); + return 1; + } - return 0; + return 0; } /* given a device name (w/o '/dev' on it), try to get a file */ @@ -462,78 +481,88 @@ int copyFileAndLoopbackMount(int fd, char * dest, char * device, char * mntpoint 2 - could not mount device as ext2, vfat, or iso9660 3 - file named path not there */ -int getFileFromBlockDevice(char *device, char *path, char * dest) { - int rc, i; - char file[4096]; - - logMessage(INFO, "getFileFromBlockDevice(%s, %s)", device, path); - - /* some USB thumb drives and hard drives are slow to initialize */ - /* retry up to 5 times or 31 seconds */ - rc = doPwMount(device, "/tmp/mnt", "auto", "ro", NULL); - for (i = 0; mountMightSucceedLater(rc) && i < 5; ++i) { - logMessage(INFO, "sleeping to wait for USB storage devices"); - sleep(1 << i); - rc = doPwMount(device, "/tmp/mnt", "auto", "ro", NULL); - logMessage(ERROR, "error code: %d", rc); - } - if (rc) { - logMessage(ERROR, "failed to mount /dev/%s: %m", device); - return 2; - } - - snprintf(file, sizeof(file), "/tmp/mnt/%s", path); - logMessage(INFO, "Searching for file on path %s", file); - - if (access(file, R_OK)) { - rc = 3; - } else { - copyFile(file, dest); - rc = 0; - logMessage(INFO, "file copied to %s", dest); - } - - umount("/tmp/mnt"); - unlink("/tmp/mnt"); - return rc; +int getFileFromBlockDevice(char *device, char *path, char *dest) +{ + int rc, i; + char file[4096]; + + logMessage(INFO, "getFileFromBlockDevice(%s, %s)", device, path); + + /* some USB thumb drives and hard drives are slow to initialize */ + /* retry up to 5 times or 31 seconds */ + rc = doPwMount(device, "/tmp/mnt", "auto", "ro", NULL); + for (i = 0; mountMightSucceedLater(rc) && i < 5; ++i) { + logMessage(INFO, "sleeping to wait for USB storage devices"); + sleep(1 << i); + rc = doPwMount(device, "/tmp/mnt", "auto", "ro", NULL); + logMessage(ERROR, "error code: %d", rc); + } + if (rc) { + logMessage(ERROR, "failed to mount /dev/%s: %m", device); + return 2; + } + + snprintf(file, sizeof(file), "/tmp/mnt/%s", path); + logMessage(INFO, "Searching for file on path %s", file); + + if (access(file, R_OK)) { + rc = 3; + } else { + copyFile(file, dest); + rc = 0; + logMessage(INFO, "file copied to %s", dest); + } + + umount("/tmp/mnt"); + unlink("/tmp/mnt"); + return rc; } -void setStage2LocFromCmdline(char * arg, struct loaderData_s * ld) { - char * c, * dup; - - dup = strdup(arg); - c = dup; - /* : will let us delimit real information on the method */ - if ((c = strtok(c, ":"))) { - c = strtok(NULL, ":"); - - if (!strncmp(arg, "nfs:", 4)) { - ld->method = METHOD_NFS; - ld->stage2Data = calloc(sizeof(struct nfsInstallData *), 1); - - parseNfsHostPathOpts(arg + 4, - &(((struct nfsInstallData *)ld->stage2Data)->host), - &(((struct nfsInstallData *)ld->stage2Data)->directory), - &(((struct nfsInstallData *)ld->stage2Data)->mountOpts)); - } else if (!strncmp(arg, "ftp:", 4) || - !strncmp(arg, "http", 4)) { - ld->method = METHOD_URL; - ld->stage2Data = calloc(sizeof(struct urlInstallData *), 1); - ((urlInstallData *)ld->stage2Data)->url = strdup(arg); - } else if (!strncmp(arg, "cdrom:", 6)) { - ld->method = METHOD_CDROM; - } else if (!strncmp(arg, "harddrive:", 10) || - !strncmp(arg, "hd:", 3)) { - ld->method = METHOD_HD; - ld->stage2Data = calloc(sizeof(struct hdInstallData *), 1); - ((struct hdInstallData *)ld->stage2Data)->partition = strdup(c); - if ((c = strtok(NULL, ":"))) - ((struct hdInstallData *)ld->stage2Data)->directory = strdup(c); - else - ((struct hdInstallData *)ld->stage2Data)->directory = NULL; - } - } - free(dup); +void setStage2LocFromCmdline(char *arg, struct loaderData_s *ld) +{ + char *c, *dup; + + dup = strdup(arg); + c = dup; + /* : will let us delimit real information on the method */ + if ((c = strtok(c, ":"))) { + c = strtok(NULL, ":"); + + if (!strncmp(arg, "nfs:", 4)) { + ld->method = METHOD_NFS; + ld->stage2Data = + calloc(sizeof(struct nfsInstallData *), 1); + + parseNfsHostPathOpts(arg + 4, + &(((struct nfsInstallData *) + ld->stage2Data)->host), + &(((struct nfsInstallData *) + ld->stage2Data)->directory), + &(((struct nfsInstallData *) + ld->stage2Data)->mountOpts)); + } else if (!strncmp(arg, "ftp:", 4) || !strncmp(arg, "http", 4)) { + ld->method = METHOD_URL; + ld->stage2Data = + calloc(sizeof(struct urlInstallData *), 1); + ((urlInstallData *) ld->stage2Data)->url = strdup(arg); + } else if (!strncmp(arg, "cdrom:", 6)) { + ld->method = METHOD_CDROM; + } else if (!strncmp(arg, "harddrive:", 10) || + !strncmp(arg, "hd:", 3)) { + ld->method = METHOD_HD; + ld->stage2Data = + calloc(sizeof(struct hdInstallData *), 1); + ((struct hdInstallData *)ld->stage2Data)->partition = + strdup(c); + if ((c = strtok(NULL, ":"))) + ((struct hdInstallData *)ld-> + stage2Data)->directory = strdup(c); + else + ((struct hdInstallData *)ld-> + stage2Data)->directory = NULL; + } + } + free(dup); } /* vim:set sw=8 noet */ diff --git a/loader/method.h b/loader/method.h index 6ddc76b..3576515 100644 --- a/loader/method.h +++ b/loader/method.h @@ -25,37 +25,38 @@ /* method identifiers, needs to match struct installMethod order in loader.c */ enum { - METHOD_CDROM, - METHOD_HD, - METHOD_NFS, - METHOD_URL + METHOD_CDROM, + METHOD_HD, + METHOD_NFS, + METHOD_URL }; struct installMethod { - char * name; - int network; - enum deviceType type; - char * (*mountImage)(struct installMethod * method, - char * location, struct loaderData_s * loaderData); + char *name; + int network; + enum deviceType type; + char *(*mountImage) (struct installMethod * method, + char *location, struct loaderData_s * loaderData); }; -int umountLoopback(char * mntpoint, char * device); -int mountLoopback(char * fsystem, char * mntpoint, char * device); +int umountLoopback(char *mntpoint, char *device); +int mountLoopback(char *fsystem, char *mntpoint, char *device); int readStampFileFromIso(char *file, char **descr, char **timestamp); -void queryIsoMediaCheck(char * isoDir); +void queryIsoMediaCheck(char *isoDir); void umountStage2(void); int mountStage2(char *stage2path); int copyFileAndLoopbackMount(int fd, char *dest, char *device, char *mntpoint, - progressCB pbcb, struct progressCBdata *data, long long total); -int getFileFromBlockDevice(char *device, char *path, char * dest); + progressCB pbcb, struct progressCBdata *data, + long long total); +int getFileFromBlockDevice(char *device, char *path, char *dest); -int unpackCpioBall(char * ballPath, char * rootDir); -void copyUpdatesImg(char * path); -void copyProductImg(char * path); +int unpackCpioBall(char *ballPath, char *rootDir); +void copyUpdatesImg(char *path); +void copyProductImg(char *path); -void setStage2LocFromCmdline(char * arg, struct loaderData_s * ld); +void setStage2LocFromCmdline(char *arg, struct loaderData_s *ld); #endif diff --git a/loader/mkctype.c b/loader/mkctype.c index 9d1558b..c810a14 100644 --- a/loader/mkctype.c +++ b/loader/mkctype.c @@ -26,53 +26,60 @@ # define __ctype_toupper (*__ctype_toupper_loc()) #endif -int main(int argc, char ** argv) { - int i; +int main(int argc, char **argv) +{ + int i; - printf("#include <sys/types.h>\n\n"); + printf("#include <sys/types.h>\n\n"); - printf("static const unsigned short int __ctype_b_internal[] = {"); + printf("static const unsigned short int __ctype_b_internal[] = {"); - for (i = -128; i < 256; i++) { - if (!(i % 8)) { - printf("\n"); + for (i = -128; i < 256; i++) { + if (!(i % 8)) { + printf("\n"); + } + + printf("\t0x%x,", __ctype_b[i]); } - printf("\t0x%x,", __ctype_b[i]); - } + printf("\n};\n\n"); + printf + ("const unsigned short int * __ctype_b = __ctype_b_internal + 128;\n\n"); - printf("\n};\n\n"); - printf("const unsigned short int * __ctype_b = __ctype_b_internal + 128;\n\n"); + printf("const int __ctype_toupper_internal[] = {"); + for (i = -128; i < 256; i++) { + if (!(i % 8)) { + printf("\n"); + } - printf("const int __ctype_toupper_internal[] = {"); - for (i = -128; i < 256; i++) { - if (!(i % 8)) { - printf("\n"); + printf("\t0x%x,", __ctype_toupper[i]); } - printf("\t0x%x,", __ctype_toupper[i]); - } + printf("\n};\n\n"); + printf + ("const int * __ctype_toupper = __ctype_toupper_internal + 128;\n\n"); - printf("\n};\n\n"); - printf("const int * __ctype_toupper = __ctype_toupper_internal + 128;\n\n"); + printf("const int __ctype_tolower_internal[] = {"); + for (i = -128; i < 256; i++) { + if (!(i % 8)) { + printf("\n"); + } - printf("const int __ctype_tolower_internal[] = {"); - for (i = -128; i < 256; i++) { - if (!(i % 8)) { - printf("\n"); + printf("\t0x%x,", __ctype_tolower[i]); } - printf("\t0x%x,", __ctype_tolower[i]); - } - - printf("\n};\n\n"); - printf("const int * __ctype_tolower = __ctype_tolower_internal + 128;\n\n"); + printf("\n};\n\n"); + printf + ("const int * __ctype_tolower = __ctype_tolower_internal + 128;\n\n"); - printf ("const unsigned short int **__ctype_b_loc (void) { return &__ctype_b; }\n"); - printf ("const int **__ctype_toupper_loc (void) { return &__ctype_toupper; }\n"); - printf ("const int **__ctype_tolower_loc (void) { return &__ctype_tolower; }\n\n"); + printf + ("const unsigned short int **__ctype_b_loc (void) { return &__ctype_b; }\n"); + printf + ("const int **__ctype_toupper_loc (void) { return &__ctype_toupper; }\n"); + printf + ("const int **__ctype_tolower_loc (void) { return &__ctype_tolower; }\n\n"); - return 0; + return 0; }; /* vim:set sw=8 noet */ diff --git a/loader/moduleinfo.c b/loader/moduleinfo.c index ef38d73..06ae3d2 100644 --- a/loader/moduleinfo.c +++ b/loader/moduleinfo.c @@ -33,52 +33,53 @@ #include "moduleinfo.h" -struct moduleInfo * getModuleList(moduleInfoSet mis, - enum driverMajor major) { - struct moduleInfo * miList, * next; - int i; - - next = miList = malloc(sizeof(*miList) * mis->numModules + 1); - for (i = 0; i < mis->numModules; i++) { - if (mis->moduleList[i].major == major || major == DRIVER_NONE) { - *next = mis->moduleList[i]; - next++; - } - } - - if (next == miList) { - free(next); - return NULL; - } - - next->moduleName = NULL; - next++; - - miList = realloc(miList, sizeof(*miList) * (next - miList)); - return miList; +struct moduleInfo *getModuleList(moduleInfoSet mis, enum driverMajor major) +{ + struct moduleInfo *miList, *next; + int i; + + next = miList = malloc(sizeof(*miList) * mis->numModules + 1); + for (i = 0; i < mis->numModules; i++) { + if (mis->moduleList[i].major == major || major == DRIVER_NONE) { + *next = mis->moduleList[i]; + next++; + } + } + + if (next == miList) { + free(next); + return NULL; + } + + next->moduleName = NULL; + next++; + + miList = realloc(miList, sizeof(*miList) * (next - miList)); + return miList; } -struct moduleInfo * findModuleInfo(moduleInfoSet mis, - const char * moduleName) { - int i; - struct moduleInfo * found = NULL; - - for (i = 0; i < mis->numModules; i++) { - if (!strcmp(moduleName, mis->moduleList[i].moduleName)) { - if (!found) - found = mis->moduleList + i; - else if (found->locationID && !mis->moduleList[i].locationID) - ; - else - found = mis->moduleList + i; - } - } - - return found; +struct moduleInfo *findModuleInfo(moduleInfoSet mis, const char *moduleName) +{ + int i; + struct moduleInfo *found = NULL; + + for (i = 0; i < mis->numModules; i++) { + if (!strcmp(moduleName, mis->moduleList[i].moduleName)) { + if (!found) + found = mis->moduleList + i; + else if (found->locationID + && !mis->moduleList[i].locationID) ; + else + found = mis->moduleList + i; + } + } + + return found; } -moduleInfoSet newModuleInfoSet(void) { - return calloc(sizeof(struct moduleInfoSet_s), 1); +moduleInfoSet newModuleInfoSet(void) +{ + return calloc(sizeof(struct moduleInfoSet_s), 1); } /* filename: file to read module-info from @@ -88,191 +89,217 @@ moduleInfoSet newModuleInfoSet(void) { * override: 1 if modules from this module ball should override old ones * of the same name. */ -int readModuleInfo(const char * filename, moduleInfoSet mis, - void * location, int override) { - int fd, isIndented; - char * buf, * start, * next = NULL, * chptr; - struct stat sb; - char oldch; - struct moduleInfo * nextModule; - int modulesAlloced; - int i; - int found = 0, skipModule = 0; - - fd = open(filename, O_RDONLY); - if (fd < 0) return -1; - - fstat(fd, &sb); - buf = alloca(sb.st_size + 1); - i = read(fd, buf, sb.st_size); - buf[sb.st_size] = '\0'; - close(fd); - - if (i != sb.st_size) - return -1; - - nextModule = NULL; - modulesAlloced = mis->numModules; - - if (strncmp(buf, "Version 0\n", 10)) return -1; - - start = buf + 10; - while (start && *start) { - chptr = strchr(start, '\n'); - if (chptr) { - /* slice and dice */ - next = chptr + 1; - } else { - chptr += strlen(start) - 1; - } - - chptr--; - while (isspace(*chptr)) chptr--; - chptr++; - *chptr = '\0'; - - isIndented = 0; - if (isspace(*start)) { - while (isspace(*start) && *start != '\n') start++; - isIndented = 1; - } - - if (*start != '\n' && *start && *start != '#') { - if (!isIndented) { - if (nextModule && nextModule->moduleName && - nextModule == (mis->moduleList + mis->numModules)) { - mis->numModules++; - } - - if (mis->numModules == modulesAlloced) { - modulesAlloced += 5; - mis->moduleList = realloc(mis->moduleList, - modulesAlloced * sizeof(*mis->moduleList)); - } - - nextModule = NULL; - found = 0; - skipModule = 0; - for (i = 0; i < mis->numModules; i++) { - if (!strcmp(mis->moduleList[i].moduleName, start)) { - if (override) - nextModule = mis->moduleList + i; - else - skipModule = 1; - found = 1; - break; - } - } - - if (!found && !nextModule) { - nextModule = mis->moduleList + mis->numModules; - - nextModule->moduleName = strdup(start); - } - - if (nextModule) { - nextModule->major = DRIVER_NONE; - nextModule->minor = DRIVER_MINOR_NONE; - nextModule->description = NULL; - nextModule->flags = 0; - nextModule->args = NULL; - nextModule->numArgs = 0; - nextModule->locationID = location; - } - } else if (!nextModule && skipModule) { - /* we're skipping this one (not overriding), do nothing */ - } else if (!nextModule && skipModule) { - /* ACK! syntax error */ - fprintf(stderr, "module-info syntax error in %s\n", filename); - return 1; - } else if (nextModule->major == DRIVER_NONE) { - chptr = start + strlen(start) - 1; - while (!isspace(*chptr) && chptr > start) chptr--; - if (chptr != start) chptr++; - - if (!strcmp(chptr, "eth")) { - nextModule->major = DRIVER_NET; - nextModule->minor = DRIVER_MINOR_ETHERNET; - } else if (!strcmp(chptr, "tr")) { - nextModule->major = DRIVER_NET; - nextModule->minor = DRIVER_MINOR_TR; - } else if (!strcmp(chptr, "scsi_hostadapter") || - !strcmp(chptr, "scsi")) { - nextModule->major = DRIVER_SCSI; - } else if (!strcmp(chptr, "pcmcia")) { - nextModule->major = DRIVER_PCMCIA; - } else if (!strcmp(chptr, "fs")) { - nextModule->major = DRIVER_FS; - } else if (!strcmp(chptr, "cdrom")) { - nextModule->major = DRIVER_CDROM; - } else if (!strcmp(chptr, "ide")) { - nextModule->major = DRIVER_IDE; - } else { - nextModule->major = DRIVER_OTHER; - } - } else if (!nextModule->description) { - chptr = start + strlen(start) - 1; - if (*start == '"' && *chptr == '"') { - start++; - *chptr = '\0'; - nextModule->description = strdup(start); - } - } else { - nextModule->args = realloc(nextModule->args, - sizeof(*nextModule->args) * (nextModule->numArgs + 1)); - chptr = start; - while (!isspace(*chptr) && *chptr) chptr++; - if (*chptr) { - oldch = *chptr; - *chptr = '\0'; - nextModule->args[nextModule->numArgs].arg = strdup(start); - - start = chptr + 1; - while (*start && isspace(*start)) start++; - - if (*start == '"') { - start++; - chptr = strchr(start, '"'); - if (chptr) { - *chptr = '\0'; - nextModule->args[nextModule->numArgs].description = - strdup(start); - nextModule->numArgs++; - } - } - } - } - } - - start = next; - } - - /* do we need to add in this last module? */ - if (nextModule && ((nextModule - mis->moduleList) == mis->numModules)) - mis->numModules++; - - return 0; +int readModuleInfo(const char *filename, moduleInfoSet mis, + void *location, int override) +{ + int fd, isIndented; + char *buf, *start, *next = NULL, *chptr; + struct stat sb; + char oldch; + struct moduleInfo *nextModule; + int modulesAlloced; + int i; + int found = 0, skipModule = 0; + + fd = open(filename, O_RDONLY); + if (fd < 0) + return -1; + + fstat(fd, &sb); + buf = alloca(sb.st_size + 1); + i = read(fd, buf, sb.st_size); + buf[sb.st_size] = '\0'; + close(fd); + + if (i != sb.st_size) + return -1; + + nextModule = NULL; + modulesAlloced = mis->numModules; + + if (strncmp(buf, "Version 0\n", 10)) + return -1; + + start = buf + 10; + while (start && *start) { + chptr = strchr(start, '\n'); + if (chptr) { + /* slice and dice */ + next = chptr + 1; + } else { + chptr += strlen(start) - 1; + } + + chptr--; + while (isspace(*chptr)) + chptr--; + chptr++; + *chptr = '\0'; + + isIndented = 0; + if (isspace(*start)) { + while (isspace(*start) && *start != '\n') + start++; + isIndented = 1; + } + + if (*start != '\n' && *start && *start != '#') { + if (!isIndented) { + if (nextModule && nextModule->moduleName && + nextModule == + (mis->moduleList + mis->numModules)) { + mis->numModules++; + } + + if (mis->numModules == modulesAlloced) { + modulesAlloced += 5; + mis->moduleList = + realloc(mis->moduleList, + modulesAlloced * + sizeof(*mis->moduleList)); + } + + nextModule = NULL; + found = 0; + skipModule = 0; + for (i = 0; i < mis->numModules; i++) { + if (!strcmp + (mis->moduleList[i].moduleName, + start)) { + if (override) + nextModule = + mis->moduleList + i; + else + skipModule = 1; + found = 1; + break; + } + } + + if (!found && !nextModule) { + nextModule = + mis->moduleList + mis->numModules; + + nextModule->moduleName = strdup(start); + } + + if (nextModule) { + nextModule->major = DRIVER_NONE; + nextModule->minor = DRIVER_MINOR_NONE; + nextModule->description = NULL; + nextModule->flags = 0; + nextModule->args = NULL; + nextModule->numArgs = 0; + nextModule->locationID = location; + } + } else if (!nextModule && skipModule) { + /* we're skipping this one (not overriding), do nothing */ + } else if (!nextModule && skipModule) { + /* ACK! syntax error */ + fprintf(stderr, + "module-info syntax error in %s\n", + filename); + return 1; + } else if (nextModule->major == DRIVER_NONE) { + chptr = start + strlen(start) - 1; + while (!isspace(*chptr) && chptr > start) + chptr--; + if (chptr != start) + chptr++; + + if (!strcmp(chptr, "eth")) { + nextModule->major = DRIVER_NET; + nextModule->minor = + DRIVER_MINOR_ETHERNET; + } else if (!strcmp(chptr, "tr")) { + nextModule->major = DRIVER_NET; + nextModule->minor = DRIVER_MINOR_TR; + } else if (!strcmp(chptr, "scsi_hostadapter") || + !strcmp(chptr, "scsi")) { + nextModule->major = DRIVER_SCSI; + } else if (!strcmp(chptr, "pcmcia")) { + nextModule->major = DRIVER_PCMCIA; + } else if (!strcmp(chptr, "fs")) { + nextModule->major = DRIVER_FS; + } else if (!strcmp(chptr, "cdrom")) { + nextModule->major = DRIVER_CDROM; + } else if (!strcmp(chptr, "ide")) { + nextModule->major = DRIVER_IDE; + } else { + nextModule->major = DRIVER_OTHER; + } + } else if (!nextModule->description) { + chptr = start + strlen(start) - 1; + if (*start == '"' && *chptr == '"') { + start++; + *chptr = '\0'; + nextModule->description = strdup(start); + } + } else { + nextModule->args = realloc(nextModule->args, + sizeof + (*nextModule->args) * + (nextModule->numArgs + + 1)); + chptr = start; + while (!isspace(*chptr) && *chptr) + chptr++; + if (*chptr) { + oldch = *chptr; + *chptr = '\0'; + nextModule->args[nextModule-> + numArgs].arg = + strdup(start); + + start = chptr + 1; + while (*start && isspace(*start)) + start++; + + if (*start == '"') { + start++; + chptr = strchr(start, '"'); + if (chptr) { + *chptr = '\0'; + nextModule->args + [nextModule->numArgs].description + = strdup(start); + nextModule->numArgs++; + } + } + } + } + } + + start = next; + } + + /* do we need to add in this last module? */ + if (nextModule && ((nextModule - mis->moduleList) == mis->numModules)) + mis->numModules++; + + return 0; } -void freeModuleInfoSet(moduleInfoSet mis) { - int i, j; +void freeModuleInfoSet(moduleInfoSet mis) +{ + int i, j; - for (i = 0; i < mis->numModules; i++) { - if (mis->moduleList[i].moduleName) - free(mis->moduleList[i].moduleName); + for (i = 0; i < mis->numModules; i++) { + if (mis->moduleList[i].moduleName) + free(mis->moduleList[i].moduleName); - if (mis->moduleList[i].description) - free(mis->moduleList[i].description); + if (mis->moduleList[i].description) + free(mis->moduleList[i].description); - for (j = 0; i < mis->moduleList[i].numArgs; j++) { - if (mis->moduleList[i].args[j].arg) - free(mis->moduleList[i].args[j].arg) ; - if (mis->moduleList[i].args[j].description) - free(mis->moduleList[i].args[j].description) ; - } - } + for (j = 0; i < mis->moduleList[i].numArgs; j++) { + if (mis->moduleList[i].args[j].arg) + free(mis->moduleList[i].args[j].arg); + if (mis->moduleList[i].args[j].description) + free(mis->moduleList[i].args[j].description); + } + } - free(mis); + free(mis); } /* vim:set sw=8 noet */ diff --git a/loader/moduleinfo.h b/loader/moduleinfo.h index d1a4a52..7225646 100644 --- a/loader/moduleinfo.h +++ b/loader/moduleinfo.h @@ -21,39 +21,41 @@ #define MODULEINFO_H enum driverMajor { DRIVER_NONE = 0, DRIVER_SCSI, DRIVER_NET, DRIVER_CDROM, - DRIVER_PCMCIA, DRIVER_FS, DRIVER_IDE, DRIVER_OTHER = 1000, - DRIVER_ANY = 5000 }; + DRIVER_PCMCIA, DRIVER_FS, DRIVER_IDE, DRIVER_OTHER = 1000, + DRIVER_ANY = 5000 +}; enum driverMinor { DRIVER_MINOR_NONE = 0, DRIVER_MINOR_ETHERNET, - DRIVER_MINOR_TR }; + DRIVER_MINOR_TR +}; struct moduleArg { - char * arg; - char * description; + char *arg; + char *description; }; #define MI_FLAG_NOMISCARGS (1 << 0) struct moduleInfo { - char * moduleName; - char * description; - enum driverMajor major; - enum driverMinor minor; - int numArgs; - struct moduleArg * args; - int flags; - void * locationID; + char *moduleName; + char *description; + enum driverMajor major; + enum driverMinor minor; + int numArgs; + struct moduleArg *args; + int flags; + void *locationID; }; struct moduleInfoSet_s { - struct moduleInfo * moduleList; - int numModules; + struct moduleInfo *moduleList; + int numModules; }; struct moduleBallLocation { - char * path; /* path to module ball that this driver is from. if NULL, - * implies /modules/modules.cgz */ - char * title; /* title used for driver disk -- may be NULL */ - int version; /* module ball version, used to determine layout */ + char *path; /* path to module ball that this driver is from. if NULL, + * implies /modules/modules.cgz */ + char *title; /* title used for driver disk -- may be NULL */ + int version; /* module ball version, used to determine layout */ }; #define CURRENT_MODBALLVER 1 @@ -62,18 +64,16 @@ struct moduleBallLocation { * 1: multi-arch, modules are in uname.release/arch */ -typedef struct moduleInfoSet_s * moduleInfoSet; +typedef struct moduleInfoSet_s *moduleInfoSet; moduleInfoSet newModuleInfoSet(void); void freeModuleInfoSet(moduleInfoSet mis); -int readModuleInfo(const char * filename, moduleInfoSet mis, void * path, int override); -struct moduleInfo * findModuleInfo(moduleInfoSet mis, - const char * moduleName); +int readModuleInfo(const char *filename, moduleInfoSet mis, void *path, + int override); +struct moduleInfo *findModuleInfo(moduleInfoSet mis, const char *moduleName); /* NULL moduleName indicates the end of the list; the list must be freed() */ -struct moduleInfo * getModuleList(moduleInfoSet mis, - enum driverMajor major); - +struct moduleInfo *getModuleList(moduleInfoSet mis, enum driverMajor major); #endif diff --git a/loader/modules.c b/loader/modules.c index 4bda633..0553735 100644 --- a/loader/modules.c +++ b/loader/modules.c @@ -51,362 +51,377 @@ extern uint64_t flags; static GSList *modopts = NULL; static GSList *blacklist = NULL; -static gboolean _isValidModule(gchar *module) { - gint fd = -1, i = 0; - gchar *path = NULL, *buf = NULL, *modname = NULL; - gchar *ends[] = { ".ko.gz:", ".ko:", NULL }; - struct utsname utsbuf; - struct stat sbuf; - - if (uname(&utsbuf) == -1) { - logMessage(ERROR, "%s (%d): %m", __func__, __LINE__); - return FALSE; - } - - if (asprintf(&path, "/lib/modules/%s/modules.dep", utsbuf.release) == -1) { - logMessage(ERROR, "%s (%d): %m", __func__, __LINE__); - return FALSE; - } - - if (stat(path, &sbuf) == -1) { - logMessage(ERROR, "%s (%d): %m", __func__, __LINE__); - free(path); - return FALSE; - } - - if ((fd = open(path, O_RDONLY)) == -1) { - logMessage(ERROR, "%s (%d): %m", __func__, __LINE__); - free(path); - return FALSE; - } else { - free(path); - } - - buf = mmap(0, sbuf.st_size, PROT_READ, MAP_SHARED, fd, 0); - if (!buf || buf == MAP_FAILED) { - close(fd); - return FALSE; - } - - close(fd); - - while (ends[i] != NULL) { - if (asprintf(&modname, "/%s%s", module, ends[i]) == -1) { - logMessage(ERROR, "%s (%d): %m", __func__, __LINE__); - return FALSE; - } - - if (g_strstr_len(buf, -1, modname) != NULL) { - munmap(buf, sbuf.st_size); - free(modname); - return TRUE; - } - - free(modname); - modname = NULL; - i++; - } - - munmap(buf, sbuf.st_size); - return FALSE; +static gboolean _isValidModule(gchar * module) +{ + gint fd = -1, i = 0; + gchar *path = NULL, *buf = NULL, *modname = NULL; + gchar *ends[] = { ".ko.gz:", ".ko:", NULL }; + struct utsname utsbuf; + struct stat sbuf; + + if (uname(&utsbuf) == -1) { + logMessage(ERROR, "%s (%d): %m", __func__, __LINE__); + return FALSE; + } + + if (asprintf(&path, "/lib/modules/%s/modules.dep", utsbuf.release) == + -1) { + logMessage(ERROR, "%s (%d): %m", __func__, __LINE__); + return FALSE; + } + + if (stat(path, &sbuf) == -1) { + logMessage(ERROR, "%s (%d): %m", __func__, __LINE__); + free(path); + return FALSE; + } + + if ((fd = open(path, O_RDONLY)) == -1) { + logMessage(ERROR, "%s (%d): %m", __func__, __LINE__); + free(path); + return FALSE; + } else { + free(path); + } + + buf = mmap(0, sbuf.st_size, PROT_READ, MAP_SHARED, fd, 0); + if (!buf || buf == MAP_FAILED) { + close(fd); + return FALSE; + } + + close(fd); + + while (ends[i] != NULL) { + if (asprintf(&modname, "/%s%s", module, ends[i]) == -1) { + logMessage(ERROR, "%s (%d): %m", __func__, __LINE__); + return FALSE; + } + + if (g_strstr_len(buf, -1, modname) != NULL) { + munmap(buf, sbuf.st_size); + free(modname); + return TRUE; + } + + free(modname); + modname = NULL; + i++; + } + + munmap(buf, sbuf.st_size); + return FALSE; } -static void _addOption(const gchar *module, const gchar *option) { - gboolean found = FALSE; - GSList *iterator = modopts; - module_t *modopt = NULL; - gchar *tmpopt = g_strdup(option); - - while (iterator != NULL) { - modopt = (module_t *) iterator->data; - - if (!strncmp(modopt->name, module, strlen(modopt->name))) { - found = TRUE; - break; - } - - iterator = g_slist_next(iterator); - } - - if (found) { - modopt->options = g_slist_append(modopt->options, tmpopt); - } else { - if ((modopt = g_malloc0(sizeof(module_t))) == NULL) { - logMessage(ERROR, "%s (%d): %m", __func__, __LINE__); - abort(); - } - - modopt->name = g_strdup(module); - modopt->options = NULL; - modopt->options = g_slist_append(modopt->options, tmpopt); - modopts = g_slist_append(modopts, modopt); - } - - return; +static void _addOption(const gchar * module, const gchar * option) +{ + gboolean found = FALSE; + GSList *iterator = modopts; + module_t *modopt = NULL; + gchar *tmpopt = g_strdup(option); + + while (iterator != NULL) { + modopt = (module_t *) iterator->data; + + if (!strncmp(modopt->name, module, strlen(modopt->name))) { + found = TRUE; + break; + } + + iterator = g_slist_next(iterator); + } + + if (found) { + modopt->options = g_slist_append(modopt->options, tmpopt); + } else { + if ((modopt = g_malloc0(sizeof(module_t))) == NULL) { + logMessage(ERROR, "%s (%d): %m", __func__, __LINE__); + abort(); + } + + modopt->name = g_strdup(module); + modopt->options = NULL; + modopt->options = g_slist_append(modopt->options, tmpopt); + modopts = g_slist_append(modopts, modopt); + } + + return; } -static gboolean _writeModulesConf(gchar *conf) { - gint fd = -1, rc = 0, len = 0; - GSList *iterator = modopts; - GString *buf = g_string_new("# Module options and blacklists written by anaconda\n"); - - if (conf == NULL) { - /* XXX: should this use mkstemp() ? */ - conf = "/tmp/modprobe.conf"; - } - - if ((fd = open(conf, O_WRONLY | O_CREAT, 0644)) == -1) { - logMessage(ERROR, "error opening to %s: %m", conf); - return FALSE; - } - - while (iterator != NULL) { - module_t *modopt = iterator->data; - GSList *optiterator = modopt->options; - g_string_append_printf(buf, "options %s", modopt->name); - - while (optiterator != NULL) { - gchar *option = (gchar *) optiterator->data; - g_string_append_printf(buf, " %s", option); - optiterator = g_slist_next(optiterator); - } - - g_string_append(buf, "\n"); - iterator = g_slist_next(iterator); - } - - iterator = blacklist; - - while (iterator != NULL) { - gchar *module = (gchar *) iterator->data; - g_string_append_printf(buf, "blacklist %s\n", module); - iterator = g_slist_next(iterator); - } - - len = buf->len; - rc = write(fd, buf->str, len); - close(fd); - g_string_free(buf, TRUE); - - return (rc == len); +static gboolean _writeModulesConf(gchar * conf) +{ + gint fd = -1, rc = 0, len = 0; + GSList *iterator = modopts; + GString *buf = + g_string_new + ("# Module options and blacklists written by anaconda\n"); + + if (conf == NULL) { + /* XXX: should this use mkstemp() ? */ + conf = "/tmp/modprobe.conf"; + } + + if ((fd = open(conf, O_WRONLY | O_CREAT, 0644)) == -1) { + logMessage(ERROR, "error opening to %s: %m", conf); + return FALSE; + } + + while (iterator != NULL) { + module_t *modopt = iterator->data; + GSList *optiterator = modopt->options; + g_string_append_printf(buf, "options %s", modopt->name); + + while (optiterator != NULL) { + gchar *option = (gchar *) optiterator->data; + g_string_append_printf(buf, " %s", option); + optiterator = g_slist_next(optiterator); + } + + g_string_append(buf, "\n"); + iterator = g_slist_next(iterator); + } + + iterator = blacklist; + + while (iterator != NULL) { + gchar *module = (gchar *) iterator->data; + g_string_append_printf(buf, "blacklist %s\n", module); + iterator = g_slist_next(iterator); + } + + len = buf->len; + rc = write(fd, buf->str, len); + close(fd); + g_string_free(buf, TRUE); + + return (rc == len); } -static gboolean _doLoadModule(const gchar *module, gchar **args) { - gint child; - gint status; - - if (!(child = fork())) { - gint i, rc; - gchar **argv = NULL; - gint fd = -1; - - if ((argv = g_malloc0(3 * sizeof(*argv))) == NULL) { - logMessage(ERROR, "%s (%d): %m", __func__, __LINE__); - abort(); - } - - if ((fd = open("/dev/tty3", O_RDWR)) == -1) { - logMessage(ERROR, "%s (%d): %m", __func__, __LINE__); - } else { - dup2(fd, 0); - dup2(fd, 1); - dup2(fd, 2); - close(fd); - } - - argv[0] = "/sbin/modprobe"; - argv[1] = g_strdup(module); - argv[2] = NULL; - - if (args) { - for (i = 0; args[i] ; i++) { - _addOption(module, args[i]); - } - _writeModulesConf(MODULES_CONF); - } - - rc = execv("/sbin/modprobe", argv); - g_strfreev(argv); - _exit(rc); - } - - waitpid(child, &status, 0); - - if (!WIFEXITED(status) || (WIFEXITED(status) && WEXITSTATUS(status))) { - return TRUE; - } else { - return FALSE; - } +static gboolean _doLoadModule(const gchar * module, gchar ** args) +{ + gint child; + gint status; + + if (!(child = fork())) { + gint i, rc; + gchar **argv = NULL; + gint fd = -1; + + if ((argv = g_malloc0(3 * sizeof(*argv))) == NULL) { + logMessage(ERROR, "%s (%d): %m", __func__, __LINE__); + abort(); + } + + if ((fd = open("/dev/tty3", O_RDWR)) == -1) { + logMessage(ERROR, "%s (%d): %m", __func__, __LINE__); + } else { + dup2(fd, 0); + dup2(fd, 1); + dup2(fd, 2); + close(fd); + } + + argv[0] = "/sbin/modprobe"; + argv[1] = g_strdup(module); + argv[2] = NULL; + + if (args) { + for (i = 0; args[i]; i++) { + _addOption(module, args[i]); + } + _writeModulesConf(MODULES_CONF); + } + + rc = execv("/sbin/modprobe", argv); + g_strfreev(argv); + _exit(rc); + } + + waitpid(child, &status, 0); + + if (!WIFEXITED(status) || (WIFEXITED(status) && WEXITSTATUS(status))) { + return TRUE; + } else { + return FALSE; + } } -gboolean mlInitModuleConfig(void) { - gint i = 0; - gchar *cmdline = NULL; - gchar **options = NULL; - GError *readErr = NULL; - - /* read module options out of /proc/cmdline and into a structure */ - if (!g_file_get_contents("/proc/cmdline", &cmdline, NULL, &readErr)) { - logMessage(ERROR, "unable to read /proc/cmdline: %s", readErr->message); - g_error_free(readErr); - return _writeModulesConf(MODULES_CONF); - } - - cmdline = g_strchomp(cmdline); - options = g_strsplit(cmdline, " ", 0); - g_free(cmdline); - - if (options == NULL) { - return _writeModulesConf(MODULES_CONF); - } - - while (options[i] != NULL) { - gchar *tmpmod = NULL; - gchar **fields = NULL; - - if (g_strstr_len(options[i], -1, "=") == NULL) { - i++; - continue; - } - - if (!strncmp(options[i], "blacklist=", 10)) { - if ((fields = g_strsplit(options[i], "=", 0)) != NULL) { - if (g_strv_length(fields) == 2) { - tmpmod = g_strdup(fields[1]); - blacklist = g_slist_append(blacklist, tmpmod); - } - } - } else if ((fields = g_strsplit(options[i], ".", 0)) != NULL) { - if (g_strv_length(fields) == 2) { - if (_isValidModule(fields[0])) { - _addOption(fields[0], fields[1]); - } - } - } - - if (fields != NULL) { - g_strfreev(fields); - } - - i++; - } - - if (options != NULL) { - g_strfreev(options); - } - - return _writeModulesConf(MODULES_CONF); +gboolean mlInitModuleConfig(void) +{ + gint i = 0; + gchar *cmdline = NULL; + gchar **options = NULL; + GError *readErr = NULL; + + /* read module options out of /proc/cmdline and into a structure */ + if (!g_file_get_contents("/proc/cmdline", &cmdline, NULL, &readErr)) { + logMessage(ERROR, "unable to read /proc/cmdline: %s", + readErr->message); + g_error_free(readErr); + return _writeModulesConf(MODULES_CONF); + } + + cmdline = g_strchomp(cmdline); + options = g_strsplit(cmdline, " ", 0); + g_free(cmdline); + + if (options == NULL) { + return _writeModulesConf(MODULES_CONF); + } + + while (options[i] != NULL) { + gchar *tmpmod = NULL; + gchar **fields = NULL; + + if (g_strstr_len(options[i], -1, "=") == NULL) { + i++; + continue; + } + + if (!strncmp(options[i], "blacklist=", 10)) { + if ((fields = g_strsplit(options[i], "=", 0)) != NULL) { + if (g_strv_length(fields) == 2) { + tmpmod = g_strdup(fields[1]); + blacklist = + g_slist_append(blacklist, tmpmod); + } + } + } else if ((fields = g_strsplit(options[i], ".", 0)) != NULL) { + if (g_strv_length(fields) == 2) { + if (_isValidModule(fields[0])) { + _addOption(fields[0], fields[1]); + } + } + } + + if (fields != NULL) { + g_strfreev(fields); + } + + i++; + } + + if (options != NULL) { + g_strfreev(options); + } + + return _writeModulesConf(MODULES_CONF); } /* load a module with a given list of arguments */ -gboolean mlLoadModule(const gchar *module, gchar **args) { - return _doLoadModule(module, args); +gboolean mlLoadModule(const gchar * module, gchar ** args) +{ + return _doLoadModule(module, args); } /* loads a : separated list of modules */ -gboolean mlLoadModuleSet(const gchar *modNames) { - gchar **mods = NULL, **iterator = NULL; - gboolean rc = FALSE; - - if (modNames == NULL) { - return FALSE; - } - - if ((mods = g_strsplit(modNames, ":", 0)) != NULL) { - iterator = mods; - - while (*iterator != NULL) { - rc |= _doLoadModule(*iterator, NULL); - iterator++; - } - } else { - return FALSE; - } - - g_strfreev(mods); - return rc; +gboolean mlLoadModuleSet(const gchar * modNames) +{ + gchar **mods = NULL, **iterator = NULL; + gboolean rc = FALSE; + + if (modNames == NULL) { + return FALSE; + } + + if ((mods = g_strsplit(modNames, ":", 0)) != NULL) { + iterator = mods; + + while (*iterator != NULL) { + rc |= _doLoadModule(*iterator, NULL); + iterator++; + } + } else { + return FALSE; + } + + g_strfreev(mods); + return rc; } -gboolean mlAddBlacklist(gchar *module) { - gchar *tmpmod = NULL; +gboolean mlAddBlacklist(gchar * module) +{ + gchar *tmpmod = NULL; - if (module == NULL) { - return FALSE; - } + if (module == NULL) { + return FALSE; + } - tmpmod = g_strdup(module); - blacklist = g_slist_append(blacklist, tmpmod); - return _writeModulesConf(MODULES_CONF); + tmpmod = g_strdup(module); + blacklist = g_slist_append(blacklist, tmpmod); + return _writeModulesConf(MODULES_CONF); } -gboolean mlRemoveBlacklist(gchar *module) { - GSList *iterator = blacklist; +gboolean mlRemoveBlacklist(gchar * module) +{ + GSList *iterator = blacklist; - if (module == NULL) { - return FALSE; - } + if (module == NULL) { + return FALSE; + } - while (iterator != NULL) { - if (!strcmp((gchar *) iterator->data, module)) { - iterator = g_slist_delete_link(blacklist, iterator); - continue; - } else { - iterator = g_slist_next(iterator); - } - } + while (iterator != NULL) { + if (!strcmp((gchar *) iterator->data, module)) { + iterator = g_slist_delete_link(blacklist, iterator); + continue; + } else { + iterator = g_slist_next(iterator); + } + } - return TRUE; + return TRUE; } -void loadKickstartModule(struct loaderData_s * loaderData, - int argc, char **argv) { - gchar *opts = NULL; - gchar *module = NULL; - gchar **args = NULL, **remaining = NULL; - gboolean rc; - GOptionContext *optCon = g_option_context_new(NULL); - GError *optErr = NULL; - GOptionEntry ksDeviceOptions[] = { - { "opts", 0, 0, G_OPTION_ARG_STRING, &opts, NULL, NULL }, - { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &remaining, - NULL, NULL }, - { NULL }, - }; - - g_option_context_set_help_enabled(optCon, FALSE); - g_option_context_add_main_entries(optCon, ksDeviceOptions, NULL); - - if (!g_option_context_parse(optCon, &argc, &argv, &optErr)) { - startNewt(); - newtWinMessage(_("Kickstart Error"), _("OK"), - _("Bad argument to device kickstart method " - "command: %s"), optErr->message); - g_error_free(optErr); - g_option_context_free(optCon); - return; - } - - g_option_context_free(optCon); - - if ((remaining != NULL) && (g_strv_length(remaining) == 1)) { - module = remaining[0]; - } - - if (!module) { - startNewt(); - newtWinMessage(_("Kickstart Error"), _("OK"), - _("A module name must be specified for " - "the kickstart device command.")); - return; - } - - if (opts) { - args = g_strsplit(opts, " ", 0); - } - - rc = mlLoadModule(module, args); - g_strfreev(args); - return; +void loadKickstartModule(struct loaderData_s *loaderData, int argc, char **argv) +{ + gchar *opts = NULL; + gchar *module = NULL; + gchar **args = NULL, **remaining = NULL; + gboolean rc; + GOptionContext *optCon = g_option_context_new(NULL); + GError *optErr = NULL; + GOptionEntry ksDeviceOptions[] = { + {"opts", 0, 0, G_OPTION_ARG_STRING, &opts, NULL, NULL}, + {G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, + &remaining, + NULL, NULL}, + {NULL}, + }; + + g_option_context_set_help_enabled(optCon, FALSE); + g_option_context_add_main_entries(optCon, ksDeviceOptions, NULL); + + if (!g_option_context_parse(optCon, &argc, &argv, &optErr)) { + startNewt(); + newtWinMessage(_("Kickstart Error"), _("OK"), + _("Bad argument to device kickstart method " + "command: %s"), optErr->message); + g_error_free(optErr); + g_option_context_free(optCon); + return; + } + + g_option_context_free(optCon); + + if ((remaining != NULL) && (g_strv_length(remaining) == 1)) { + module = remaining[0]; + } + + if (!module) { + startNewt(); + newtWinMessage(_("Kickstart Error"), _("OK"), + _("A module name must be specified for " + "the kickstart device command.")); + return; + } + + if (opts) { + args = g_strsplit(opts, " ", 0); + } + + rc = mlLoadModule(module, args); + g_strfreev(args); + return; } /* vim:set sw=8 noet */ diff --git a/loader/modules.h b/loader/modules.h index 6785df9..66c0027 100644 --- a/loader/modules.h +++ b/loader/modules.h @@ -29,8 +29,8 @@ #define MODULES_CONF "/etc/modprobe.d/anaconda.conf" typedef struct _module_t { - gchar *name; - GSList *options; + gchar *name; + GSList *options; } module_t; gboolean mlInitModuleConfig(void); diff --git a/loader/net.c b/loader/net.c index 60f6f59..072d44e 100644 --- a/loader/net.c +++ b/loader/net.c @@ -65,1132 +65,1225 @@ extern uint64_t flags; * @param dptr Pointer to intfconfig_s data structure for this field. * @see intfconfig_s */ -static void cidrCallback(newtComponent co, void * dptr) { - struct intfconfig_s * data = dptr; - int cidr, upper = 0; - struct in_addr addr; - - if (co == data->cidr4Entry) { - if (data->cidr4 == NULL && data->ipv4 == NULL) - return; - - if (inet_pton(AF_INET, data->cidr4, &addr) >= 1) - return; - - errno = 0; - cidr = strtol(data->cidr4, NULL, 10); - if ((errno == ERANGE && (cidr == LONG_MIN || cidr == LONG_MAX)) || - (errno != 0 && cidr == 0)) { - logMessage(ERROR, "%s: %d: %m", __func__, __LINE__); - abort(); - } - - if (strcmp(data->ipv4, "")) - upper = 32; +static void cidrCallback(newtComponent co, void *dptr) +{ + struct intfconfig_s *data = dptr; + int cidr, upper = 0; + struct in_addr addr; + + if (co == data->cidr4Entry) { + if (data->cidr4 == NULL && data->ipv4 == NULL) + return; + + if (inet_pton(AF_INET, data->cidr4, &addr) >= 1) + return; + + errno = 0; + cidr = strtol(data->cidr4, NULL, 10); + if ((errno == ERANGE && (cidr == LONG_MIN || cidr == LONG_MAX)) + || (errno != 0 && cidr == 0)) { + logMessage(ERROR, "%s: %d: %m", __func__, __LINE__); + abort(); + } + + if (strcmp(data->ipv4, "")) + upper = 32; #ifdef ENABLE_IPV6 - } else if (co == data->cidr6Entry) { - if (data->cidr6 == NULL && data->ipv6 == NULL) - return; - - errno = 0; - cidr = strtol(data->cidr6, NULL, 10); - if ((errno == ERANGE && (cidr == LONG_MIN || cidr == LONG_MAX)) || - (errno != 0 && cidr == 0)) { - logMessage(ERROR, "%s: %d: %m", __func__, __LINE__); - abort(); - } - - if (strcmp(data->ipv6, "")) - upper = 128; + } else if (co == data->cidr6Entry) { + if (data->cidr6 == NULL && data->ipv6 == NULL) + return; + + errno = 0; + cidr = strtol(data->cidr6, NULL, 10); + if ((errno == ERANGE && (cidr == LONG_MIN || cidr == LONG_MAX)) + || (errno != 0 && cidr == 0)) { + logMessage(ERROR, "%s: %d: %m", __func__, __LINE__); + abort(); + } + + if (strcmp(data->ipv6, "")) + upper = 128; #endif - } - - if (upper != 0) { - if (cidr < 1 || cidr > upper) { - newtWinMessage(_("Invalid Prefix"), _("Retry"), - _("Prefix must be between 1 and 32 " - "for IPv4 networks or between 1 and 128 " - "for IPv6 networks")); - } - } + } + + if (upper != 0) { + if (cidr < 1 || cidr > upper) { + newtWinMessage(_("Invalid Prefix"), _("Retry"), + _("Prefix must be between 1 and 32 " + "for IPv4 networks or between 1 and 128 " + "for IPv6 networks")); + } + } } -static void ipCallback(newtComponent co, void * dptr) { - int i; - char *buf, *octet; - struct intfconfig_s * data = dptr; - - if (co == data->ipv4Entry) { - /* do we need to guess a netmask for the user? */ - if (data->cidr4 == NULL && data->ipv4 != NULL) { - buf = strdup(data->ipv4); - octet = strtok(buf, "."); - errno = 0; - i = strtol(octet, NULL, 10); - - if ((errno == ERANGE && (i == LONG_MIN || i == LONG_MAX)) || - (errno != 0 && i == 0)) { - logMessage(ERROR, "%s: %d: %m", __func__, __LINE__); - abort(); - } - - free(buf); - free(octet); - - if (i >= 0 && i <= 127) - newtEntrySet(data->cidr4Entry, "8", 1); - else if (i >= 128 && i <= 191) - newtEntrySet(data->cidr4Entry, "16", 1); - else if (i >= 192 && i <= 222) - newtEntrySet(data->cidr4Entry, "24", 1); - } - - return; +static void ipCallback(newtComponent co, void *dptr) +{ + int i; + char *buf, *octet; + struct intfconfig_s *data = dptr; + + if (co == data->ipv4Entry) { + /* do we need to guess a netmask for the user? */ + if (data->cidr4 == NULL && data->ipv4 != NULL) { + buf = strdup(data->ipv4); + octet = strtok(buf, "."); + errno = 0; + i = strtol(octet, NULL, 10); + + if ((errno == ERANGE + && (i == LONG_MIN || i == LONG_MAX)) || (errno != 0 + && i == + 0)) { + logMessage(ERROR, "%s: %d: %m", __func__, + __LINE__); + abort(); + } + + free(buf); + free(octet); + + if (i >= 0 && i <= 127) + newtEntrySet(data->cidr4Entry, "8", 1); + else if (i >= 128 && i <= 191) + newtEntrySet(data->cidr4Entry, "16", 1); + else if (i >= 192 && i <= 222) + newtEntrySet(data->cidr4Entry, "24", 1); + } + + return; #ifdef ENABLE_IPV6 - } else if (co == data->ipv6Entry) { - /* users must provide a mask, we can't guess for ipv6 */ - return; + } else if (co == data->ipv6Entry) { + /* users must provide a mask, we can't guess for ipv6 */ + return; #endif - } + } } -static void setMethodSensitivity(void *dptr, int radio_button_count) { - int i = 0; +static void setMethodSensitivity(void *dptr, int radio_button_count) +{ + int i = 0; - for (i = 0; i < radio_button_count; i++) { - newtCheckboxSetFlags(*((newtComponent *) dptr), NEWT_FLAG_DISABLED, - NEWT_FLAGS_TOGGLE); - dptr += sizeof (newtComponent); - } + for (i = 0; i < radio_button_count; i++) { + newtCheckboxSetFlags(*((newtComponent *) dptr), + NEWT_FLAG_DISABLED, NEWT_FLAGS_TOGGLE); + dptr += sizeof(newtComponent); + } - return; + return; } -static void v4MethodCallback(newtComponent co, void *dptr) { - setMethodSensitivity(dptr, 2); - return; +static void v4MethodCallback(newtComponent co, void *dptr) +{ + setMethodSensitivity(dptr, 2); + return; } #ifdef ENABLE_IPV6 -static void v6MethodCallback(newtComponent co, void *dptr) { - setMethodSensitivity(dptr, 3); - return; +static void v6MethodCallback(newtComponent co, void *dptr) +{ + setMethodSensitivity(dptr, 3); + return; } #endif -static void parseEthtoolSettings(struct loaderData_s * loaderData) { - char * option, * buf; - ethtool_duplex duplex = ETHTOOL_DUPLEX_UNSPEC; - ethtool_speed speed = ETHTOOL_SPEED_UNSPEC; - - buf = strdup(loaderData->ethtool); - option = strtok(buf, " "); - while (option) { - if (option[strlen(option) - 1] == '\"') - option[strlen(option) - 1] = '\0'; - if (option[0] == '\"') - option++; - if (!strncmp(option, "duplex", 6)) { - if (!strncmp(option + 7, "full", 4)) - duplex = ETHTOOL_DUPLEX_FULL; - else if (!strncmp(option + 7, "half", 4)) - duplex = ETHTOOL_DUPLEX_HALF; - else - logMessage(WARNING, "Unknown duplex setting: %s", option + 7); - option = strtok(NULL, " "); - } else if (!strncmp("speed", option, 5)) { - if (!strncmp(option + 6, "1000", 4)) - speed = ETHTOOL_SPEED_1000; - else if (!strncmp(option + 6, "100", 3)) - speed = ETHTOOL_SPEED_100; - else if (!strncmp(option + 6, "10", 2)) - speed = ETHTOOL_SPEED_10; - else - logMessage(WARNING, "Unknown speed setting: %s", option + 6); - option = strtok(NULL, " "); - } else { - logMessage(WARNING, "Unknown ethtool setting: %s", option); - } - option = strtok(NULL, " "); - } - setEthtoolSettings(loaderData->netDev, speed, duplex); - free(buf); +static void parseEthtoolSettings(struct loaderData_s *loaderData) +{ + char *option, *buf; + ethtool_duplex duplex = ETHTOOL_DUPLEX_UNSPEC; + ethtool_speed speed = ETHTOOL_SPEED_UNSPEC; + + buf = strdup(loaderData->ethtool); + option = strtok(buf, " "); + while (option) { + if (option[strlen(option) - 1] == '\"') + option[strlen(option) - 1] = '\0'; + if (option[0] == '\"') + option++; + if (!strncmp(option, "duplex", 6)) { + if (!strncmp(option + 7, "full", 4)) + duplex = ETHTOOL_DUPLEX_FULL; + else if (!strncmp(option + 7, "half", 4)) + duplex = ETHTOOL_DUPLEX_HALF; + else + logMessage(WARNING, + "Unknown duplex setting: %s", + option + 7); + option = strtok(NULL, " "); + } else if (!strncmp("speed", option, 5)) { + if (!strncmp(option + 6, "1000", 4)) + speed = ETHTOOL_SPEED_1000; + else if (!strncmp(option + 6, "100", 3)) + speed = ETHTOOL_SPEED_100; + else if (!strncmp(option + 6, "10", 2)) + speed = ETHTOOL_SPEED_10; + else + logMessage(WARNING, "Unknown speed setting: %s", + option + 6); + option = strtok(NULL, " "); + } else { + logMessage(WARNING, "Unknown ethtool setting: %s", + option); + } + option = strtok(NULL, " "); + } + setEthtoolSettings(loaderData->netDev, speed, duplex); + free(buf); } /* given loader data from kickstart, populate network configuration struct */ -void setupIfaceStruct(iface_t * iface, struct loaderData_s * loaderData) { - struct in_addr addr; - struct in6_addr addr6; - char * c; - - memset(&addr, 0, sizeof(addr)); - memset(&addr6, 0, sizeof(addr6)); - - if (loaderData->ethtool) { - parseEthtoolSettings(loaderData); - } - - if (loaderData->netCls_set) { - iface->vendorclass = loaderData->netCls; - } else { - iface->vendorclass = NULL; - } - - if (loaderData->ipinfo_set && loaderData->ipv4 != NULL) { - /* this is iBFT configured device */ - if (!strncmp(loaderData->ipv4, "ibft", 4)) { - char *devmacaddr = iface_mac2str(loaderData->netDev); - iface->ipv4method = IPV4_IBFT_METHOD; - iface->isiBFT = 1; - - /* Problems with getting the info from iBFT or iBFT uses dhcp*/ - if(!devmacaddr || !ibft_present()){ - iface->ipv4method = IPV4_DHCP_METHOD; - logMessage(INFO, "iBFT is not present"); - } - /* MAC address doesn't match */ - else if(strcasecmp(ibft_iface_mac(), devmacaddr)){ - iface->ipv4method = IPV4_DHCP_METHOD; - logMessage(INFO, "iBFT doesn't know what NIC to use - falling back to DHCP"); - } - else if(ibft_iface_dhcp()){ - iface->ipv4method = IPV4_IBFT_DHCP_METHOD; - logMessage(INFO, "iBFT is configured to use DHCP"); - } - if(devmacaddr) free(devmacaddr); - } - /* this is how we specify dhcp */ - else if (!strncmp(loaderData->ipv4, "dhcp", 4)) { - iface->dhcptimeout = loaderData->dhcpTimeout; - iface->ipv4method = IPV4_DHCP_METHOD; - } else if (inet_pton(AF_INET, loaderData->ipv4, &addr) >= 1) { - iface->ipaddr.s_addr = addr.s_addr; - iface->ipv4method = IPV4_MANUAL_METHOD; - } else { /* invalid ip information, disable the setting of ip info */ - loaderData->ipinfo_set = 0; - iface->ipv4method = 0; - loaderData->ipv4 = NULL; - } - } - - if (loaderData->netmask != NULL) { - if (inet_pton(AF_INET, loaderData->netmask, &iface->netmask) <= 0) { - logMessage(ERROR, "%s (%d): %s", __func__, __LINE__, - strerror(errno)); - } - } - - if (loaderData->gateway != NULL) { - if (inet_pton(AF_INET, loaderData->gateway, &iface->gateway) <= 0) { - logMessage(ERROR, "%s (%d): %s", __func__, __LINE__, - strerror(errno)); - } - } +void setupIfaceStruct(iface_t * iface, struct loaderData_s *loaderData) +{ + struct in_addr addr; + struct in6_addr addr6; + char *c; + memset(&addr, 0, sizeof(addr)); + memset(&addr6, 0, sizeof(addr6)); + + if (loaderData->ethtool) { + parseEthtoolSettings(loaderData); + } + + if (loaderData->netCls_set) { + iface->vendorclass = loaderData->netCls; + } else { + iface->vendorclass = NULL; + } + + if (loaderData->ipinfo_set && loaderData->ipv4 != NULL) { + /* this is iBFT configured device */ + if (!strncmp(loaderData->ipv4, "ibft", 4)) { + char *devmacaddr = iface_mac2str(loaderData->netDev); + iface->ipv4method = IPV4_IBFT_METHOD; + iface->isiBFT = 1; + + /* Problems with getting the info from iBFT or iBFT uses dhcp */ + if (!devmacaddr || !ibft_present()) { + iface->ipv4method = IPV4_DHCP_METHOD; + logMessage(INFO, "iBFT is not present"); + } + /* MAC address doesn't match */ + else if (strcasecmp(ibft_iface_mac(), devmacaddr)) { + iface->ipv4method = IPV4_DHCP_METHOD; + logMessage(INFO, + "iBFT doesn't know what NIC to use - falling back to DHCP"); + } else if (ibft_iface_dhcp()) { + iface->ipv4method = IPV4_IBFT_DHCP_METHOD; + logMessage(INFO, + "iBFT is configured to use DHCP"); + } + if (devmacaddr) + free(devmacaddr); + } + /* this is how we specify dhcp */ + else if (!strncmp(loaderData->ipv4, "dhcp", 4)) { + iface->dhcptimeout = loaderData->dhcpTimeout; + iface->ipv4method = IPV4_DHCP_METHOD; + } else if (inet_pton(AF_INET, loaderData->ipv4, &addr) >= 1) { + iface->ipaddr.s_addr = addr.s_addr; + iface->ipv4method = IPV4_MANUAL_METHOD; + } else { /* invalid ip information, disable the setting of ip info */ + loaderData->ipinfo_set = 0; + iface->ipv4method = 0; + loaderData->ipv4 = NULL; + } + } + + if (loaderData->netmask != NULL) { + if (inet_pton(AF_INET, loaderData->netmask, &iface->netmask) <= + 0) { + logMessage(ERROR, "%s (%d): %s", __func__, __LINE__, + strerror(errno)); + } + } + + if (loaderData->gateway != NULL) { + if (inet_pton(AF_INET, loaderData->gateway, &iface->gateway) <= + 0) { + logMessage(ERROR, "%s (%d): %s", __func__, __LINE__, + strerror(errno)); + } + } #ifdef ENABLE_IPV6 - if (loaderData->ipv6info_set && loaderData->ipv6 != NULL) { - if (!strncmp(loaderData->ipv6, "dhcp", 4)) { - iface->ipv6method = IPV6_DHCP_METHOD; - } else if (!strcmp(loaderData->ipv6, "auto", 4)) { - iface->ipv6method = IPV6_AUTO_METHOD; - } else if (inet_pton(AF_INET6, loaderData->ipv6, &addr6) >= 1) { - memcpy(&iface->ip6addr, &addr6, sizeof(struct in6_addr)); - iface->ipv6method = IPV6_MANUAL_METHOD; - } else { - iface->ipv6method = 0; - loaderData->ipv6info_set = 0; - loaderData->ipv6 = NULL; - } - } - - if (loaderData->gateway6 != NULL) { - if (inet_pton(AF_INET6, loaderData->gateway6, &iface->gateway6) <= 0) { - logMessage(ERROR, "%s (%d): %s", __func__, __LINE__, - strerror(errno)); - } - } + if (loaderData->ipv6info_set && loaderData->ipv6 != NULL) { + if (!strncmp(loaderData->ipv6, "dhcp", 4)) { + iface->ipv6method = IPV6_DHCP_METHOD; + } else if (!strcmp(loaderData->ipv6, "auto", 4)) { + iface->ipv6method = IPV6_AUTO_METHOD; + } else if (inet_pton(AF_INET6, loaderData->ipv6, &addr6) >= 1) { + memcpy(&iface->ip6addr, &addr6, + sizeof(struct in6_addr)); + iface->ipv6method = IPV6_MANUAL_METHOD; + } else { + iface->ipv6method = 0; + loaderData->ipv6info_set = 0; + loaderData->ipv6 = NULL; + } + } + + if (loaderData->gateway6 != NULL) { + if (inet_pton(AF_INET6, loaderData->gateway6, &iface->gateway6) + <= 0) { + logMessage(ERROR, "%s (%d): %s", __func__, __LINE__, + strerror(errno)); + } + } #endif - /* iBFT configured DNS */ - if(iface->ipv4method == IPV4_IBFT_METHOD){ - if(iface->numdns<MAXNS){ - if(ibft_iface_dns1() && inet_pton(AF_INET, ibft_iface_dns1(), &addr)>=1){ - iface->dns[iface->numdns] = strdup(ibft_iface_dns1()); - iface->numdns++; - logMessage(INFO, "adding iBFT dns server %s", ibft_iface_dns1()); - } - } - if(iface->numdns<MAXNS){ - if(ibft_iface_dns2() && inet_pton(AF_INET, ibft_iface_dns2(), &addr)>=1){ - iface->dns[iface->numdns] = strdup(ibft_iface_dns2()); - iface->numdns++; - logMessage(INFO, "adding iBFT dns server %s", ibft_iface_dns2()); - } - } - } - - if (loaderData->dns) { - char * buf; - char ret[INET6_ADDRSTRLEN+1]; - buf = strdup(loaderData->dns); - - /* Scan the dns parameter for multiple comma-separated IP addresses */ - c = strtok(buf, ","); - while ((iface->numdns < MAXNS) && (c != NULL)) { - if (inet_pton(AF_INET, c, &addr) >= 1) { - iface->dns[iface->numdns] = strdup(c); - iface->numdns++; - - if (inet_ntop(AF_INET, &addr, ret, INET_ADDRSTRLEN) == NULL) { - logMessage(ERROR, "%s (%d): %s", __func__, __LINE__, strerror(errno)); - } else { - logMessage(DEBUGLVL, "adding dns4 %s", ret); - c = strtok(NULL, ","); - } - } else if (inet_pton(AF_INET6, c, &addr6) >= 1) { - iface->dns[iface->numdns] = strdup(c); - iface->numdns++; - - if (inet_ntop(AF_INET6, &addr6, ret, INET6_ADDRSTRLEN) == NULL) { - logMessage(ERROR, "%s (%d): %s", __func__, __LINE__, strerror(errno)); - } else { - logMessage(DEBUGLVL, "adding dns6 %s", ret); - c = strtok(NULL, ","); - } - } - } - - - - logMessage(INFO, "dnsservers is %s", loaderData->dns); - } - - if (loaderData->hostname) { - logMessage(INFO, "setting specified hostname of %s", - loaderData->hostname); - iface->hostname = strdup(loaderData->hostname); - } - - if (loaderData->mtu) { - iface->mtu = loaderData->mtu; - } - - if (loaderData->peerid) { - iface->peerid = strdup(loaderData->peerid); - } - - if (loaderData->subchannels) { - iface->subchannels = strdup(loaderData->subchannels); - } - - if (loaderData->ctcprot) { - iface->ctcprot = strdup(loaderData->ctcprot); - } - - if (loaderData->portname) { - iface->portname = strdup(loaderData->portname); - } - - if (loaderData->nettype) { - iface->nettype = strdup(loaderData->nettype); - } - - if (loaderData->ethtool) { - parseEthtoolSettings(loaderData); - } - - if (loaderData->layer2) { - iface->layer2 = strdup(loaderData->layer2); - } - - if (loaderData->portno) { - iface->portno = strdup(loaderData->portno); - } - - if (loaderData->noDns) { - iface->flags |= IFACE_FLAGS_NO_WRITE_RESOLV_CONF; - } - - iface->dhcptimeout = loaderData->dhcpTimeout; - - return; + /* iBFT configured DNS */ + if (iface->ipv4method == IPV4_IBFT_METHOD) { + if (iface->numdns < MAXNS) { + if (ibft_iface_dns1() + && inet_pton(AF_INET, ibft_iface_dns1(), + &addr) >= 1) { + iface->dns[iface->numdns] = + strdup(ibft_iface_dns1()); + iface->numdns++; + logMessage(INFO, "adding iBFT dns server %s", + ibft_iface_dns1()); + } + } + if (iface->numdns < MAXNS) { + if (ibft_iface_dns2() + && inet_pton(AF_INET, ibft_iface_dns2(), + &addr) >= 1) { + iface->dns[iface->numdns] = + strdup(ibft_iface_dns2()); + iface->numdns++; + logMessage(INFO, "adding iBFT dns server %s", + ibft_iface_dns2()); + } + } + } + + if (loaderData->dns) { + char *buf; + char ret[INET6_ADDRSTRLEN + 1]; + buf = strdup(loaderData->dns); + + /* Scan the dns parameter for multiple comma-separated IP addresses */ + c = strtok(buf, ","); + while ((iface->numdns < MAXNS) && (c != NULL)) { + if (inet_pton(AF_INET, c, &addr) >= 1) { + iface->dns[iface->numdns] = strdup(c); + iface->numdns++; + + if (inet_ntop + (AF_INET, &addr, ret, + INET_ADDRSTRLEN) == NULL) { + logMessage(ERROR, "%s (%d): %s", + __func__, __LINE__, + strerror(errno)); + } else { + logMessage(DEBUGLVL, "adding dns4 %s", + ret); + c = strtok(NULL, ","); + } + } else if (inet_pton(AF_INET6, c, &addr6) >= 1) { + iface->dns[iface->numdns] = strdup(c); + iface->numdns++; + + if (inet_ntop + (AF_INET6, &addr6, ret, + INET6_ADDRSTRLEN) == NULL) { + logMessage(ERROR, "%s (%d): %s", + __func__, __LINE__, + strerror(errno)); + } else { + logMessage(DEBUGLVL, "adding dns6 %s", + ret); + c = strtok(NULL, ","); + } + } + } + + logMessage(INFO, "dnsservers is %s", loaderData->dns); + } + + if (loaderData->hostname) { + logMessage(INFO, "setting specified hostname of %s", + loaderData->hostname); + iface->hostname = strdup(loaderData->hostname); + } + + if (loaderData->mtu) { + iface->mtu = loaderData->mtu; + } + + if (loaderData->peerid) { + iface->peerid = strdup(loaderData->peerid); + } + + if (loaderData->subchannels) { + iface->subchannels = strdup(loaderData->subchannels); + } + + if (loaderData->ctcprot) { + iface->ctcprot = strdup(loaderData->ctcprot); + } + + if (loaderData->portname) { + iface->portname = strdup(loaderData->portname); + } + + if (loaderData->nettype) { + iface->nettype = strdup(loaderData->nettype); + } + + if (loaderData->ethtool) { + parseEthtoolSettings(loaderData); + } + + if (loaderData->layer2) { + iface->layer2 = strdup(loaderData->layer2); + } + + if (loaderData->portno) { + iface->portno = strdup(loaderData->portno); + } + + if (loaderData->noDns) { + iface->flags |= IFACE_FLAGS_NO_WRITE_RESOLV_CONF; + } + + iface->dhcptimeout = loaderData->dhcpTimeout; + + return; } -int readNetConfig(char * device, iface_t * iface, - char * dhcpclass, int methodNum) { - int err; - int ret; - int i = 0; - struct netconfopts opts; - struct in_addr addr; - struct intfconfig_s ipcomps; - - /* ipcomps contains the user interface components */ - ipcomps.ipv4 = NULL; - ipcomps.cidr4 = NULL; - ipcomps.gw = NULL; +int readNetConfig(char *device, iface_t * iface, char *dhcpclass, int methodNum) +{ + int err; + int ret; + int i = 0; + struct netconfopts opts; + struct in_addr addr; + struct intfconfig_s ipcomps; + + /* ipcomps contains the user interface components */ + ipcomps.ipv4 = NULL; + ipcomps.cidr4 = NULL; + ipcomps.gw = NULL; #ifdef ENABLE_IPV6 - ipcomps.ipv6 = NULL; - ipcomps.cidr6 = NULL; - ipcomps.gw6 = NULL; + ipcomps.ipv6 = NULL; + ipcomps.cidr6 = NULL; + ipcomps.gw6 = NULL; #endif - ipcomps.ns = NULL; + ipcomps.ns = NULL; - /* init opts */ - opts.ipv4Choice = 0; + /* init opts */ + opts.ipv4Choice = 0; #ifdef ENABLE_IPV6 - opts.ipv6Choice = 0; + opts.ipv6Choice = 0; #endif - /* JKFIXME: we really need a way to override this and be able to change - * our network config */ - if (!FL_ASKNETWORK(flags) && - ((iface->ipv4method > IPV4_UNUSED_METHOD) || - (iface->ipv6method > IPV4_UNUSED_METHOD))) { - logMessage(INFO, "doing kickstart... setting it up"); - - err = writeEnabledNetInfo(iface); - if (err) { - logMessage(ERROR, "failed to write %s data for %s (%d)", - SYSCONFIG_PATH, iface->device, err); - return LOADER_BACK; - } - - i = get_connection(iface); - newtPopWindow(); - - if (i > 0) { - if (FL_CMDLINE(flags)) { - fprintf(stderr, _("There was an error configuring your network " - "interface.")); - fprintf(stderr, _("\nThis cannot be corrected in cmdline mode.\n" - "Halting.\n")); - exit(1); - } - - newtWinMessage(_("Network Error"), _("Retry"), - _("There was an error configuring your network " - "interface.")); - return LOADER_BACK; - } - - return LOADER_NOOP; - } - - /* dhcp/manual network configuration loop */ - i = 1; - while (i == 1) { - ret = configureTCPIP(device, iface, &opts, methodNum); - - if (ret == LOADER_NOOP) { - /* dhcp selected, proceed */ - i = 0; - } else if (ret == LOADER_OK) { - /* do manual configuration */ - ret = manualNetConfig(device, iface, &ipcomps, &opts); - - if (ret == LOADER_BACK) { - continue; - } else if (ret == LOADER_OK) { - i = 0; - } - } else if (ret == LOADER_BACK) { - return LOADER_BACK; - } - } - - /* calculate any missing IPv4 pieces */ - if (opts.ipv4Choice == '*') { - memset(&addr, 0, sizeof(addr)); - addr.s_addr = (iface->ipaddr.s_addr) & (iface->netmask.s_addr); - - if (iface->broadcast.s_addr == 0) { - iface->broadcast.s_addr = addr.s_addr | ~(iface->netmask.s_addr); - } - } - - /* bring up the interface */ - err = writeEnabledNetInfo(iface); - if (err) { - logMessage(ERROR, "failed to write %s data for %s (%d)", - SYSCONFIG_PATH, iface->device, err); - iface->ipv4method = IPV4_UNUSED_METHOD; - iface->ipv6method = IPV6_UNUSED_METHOD; - return LOADER_BACK; - } - - i = get_connection(iface); - newtPopWindow(); - - if (i > 0) { - newtWinMessage(_("Network Error"), _("Retry"), - _("There was an error configuring your network " - "interface.")); - iface->ipv4method = IPV4_UNUSED_METHOD; - iface->ipv6method = IPV6_UNUSED_METHOD; - return LOADER_ERROR; - } - - return LOADER_OK; + /* JKFIXME: we really need a way to override this and be able to change + * our network config */ + if (!FL_ASKNETWORK(flags) && + ((iface->ipv4method > IPV4_UNUSED_METHOD) || + (iface->ipv6method > IPV4_UNUSED_METHOD))) { + logMessage(INFO, "doing kickstart... setting it up"); + + err = writeEnabledNetInfo(iface); + if (err) { + logMessage(ERROR, "failed to write %s data for %s (%d)", + SYSCONFIG_PATH, iface->device, err); + return LOADER_BACK; + } + + i = get_connection(iface); + newtPopWindow(); + + if (i > 0) { + if (FL_CMDLINE(flags)) { + fprintf(stderr, + _ + ("There was an error configuring your network " + "interface.")); + fprintf(stderr, + _ + ("\nThis cannot be corrected in cmdline mode.\n" + "Halting.\n")); + exit(1); + } + + newtWinMessage(_("Network Error"), _("Retry"), + _ + ("There was an error configuring your network " + "interface.")); + return LOADER_BACK; + } + + return LOADER_NOOP; + } + + /* dhcp/manual network configuration loop */ + i = 1; + while (i == 1) { + ret = configureTCPIP(device, iface, &opts, methodNum); + + if (ret == LOADER_NOOP) { + /* dhcp selected, proceed */ + i = 0; + } else if (ret == LOADER_OK) { + /* do manual configuration */ + ret = manualNetConfig(device, iface, &ipcomps, &opts); + + if (ret == LOADER_BACK) { + continue; + } else if (ret == LOADER_OK) { + i = 0; + } + } else if (ret == LOADER_BACK) { + return LOADER_BACK; + } + } + + /* calculate any missing IPv4 pieces */ + if (opts.ipv4Choice == '*') { + memset(&addr, 0, sizeof(addr)); + addr.s_addr = (iface->ipaddr.s_addr) & (iface->netmask.s_addr); + + if (iface->broadcast.s_addr == 0) { + iface->broadcast.s_addr = + addr.s_addr | ~(iface->netmask.s_addr); + } + } + + /* bring up the interface */ + err = writeEnabledNetInfo(iface); + if (err) { + logMessage(ERROR, "failed to write %s data for %s (%d)", + SYSCONFIG_PATH, iface->device, err); + iface->ipv4method = IPV4_UNUSED_METHOD; + iface->ipv6method = IPV6_UNUSED_METHOD; + return LOADER_BACK; + } + + i = get_connection(iface); + newtPopWindow(); + + if (i > 0) { + newtWinMessage(_("Network Error"), _("Retry"), + _("There was an error configuring your network " + "interface.")); + iface->ipv4method = IPV4_UNUSED_METHOD; + iface->ipv6method = IPV6_UNUSED_METHOD; + return LOADER_ERROR; + } + + return LOADER_OK; } -int configureTCPIP(char * device, iface_t * iface, - struct netconfopts * opts, int methodNum) { - int i = 0, z = 0, skipForm = 0, ret; - newtComponent f, okay, back, answer; - newtComponent ipv4Checkbox, v4Method[2]; +int configureTCPIP(char *device, iface_t * iface, + struct netconfopts *opts, int methodNum) +{ + int i = 0, z = 0, skipForm = 0, ret; + newtComponent f, okay, back, answer; + newtComponent ipv4Checkbox, v4Method[2]; #ifdef ENABLE_IPV6 - newtComponent ipv6Checkbox, v6Method[3]; + newtComponent ipv6Checkbox, v6Method[3]; #endif - newtGrid grid, checkgrid, buttons; + newtGrid grid, checkgrid, buttons; - /* UI WINDOW 1: ask for ipv4 choice, ipv6 choice, and conf methods */ + /* UI WINDOW 1: ask for ipv4 choice, ipv6 choice, and conf methods */ - /* IPv4 checkbox */ - if (!opts->ipv4Choice) { - if (FL_NOIPV4(flags) && !FL_IP_PARAM(flags)) - opts->ipv4Choice = ' '; - else - opts->ipv4Choice = '*'; - } + /* IPv4 checkbox */ + if (!opts->ipv4Choice) { + if (FL_NOIPV4(flags) && !FL_IP_PARAM(flags)) + opts->ipv4Choice = ' '; + else + opts->ipv4Choice = '*'; + } - ipv4Checkbox = newtCheckbox(-1, -1, _("Enable IPv4 support"), - opts->ipv4Choice, NULL, &(opts->ipv4Choice)); - v4Method[0] = newtRadiobutton(-1, -1, DHCP_METHOD_STR, 1, NULL); - v4Method[1] = newtRadiobutton(-1, -1, MANUAL_METHOD_STR, 0, v4Method[0]); + ipv4Checkbox = newtCheckbox(-1, -1, _("Enable IPv4 support"), + opts->ipv4Choice, NULL, + &(opts->ipv4Choice)); + v4Method[0] = newtRadiobutton(-1, -1, DHCP_METHOD_STR, 1, NULL); + v4Method[1] = + newtRadiobutton(-1, -1, MANUAL_METHOD_STR, 0, v4Method[0]); #ifdef ENABLE_IPV6 - /* IPv6 checkbox */ - if (!opts->ipv6Choice) { - if (FL_NOIPV6(flags) && !FL_IPV6_PARAM(flags)) - opts->ipv6Choice = ' '; - else - opts->ipv6Choice = '*'; - } - - ipv6Checkbox = newtCheckbox(-1, -1, _("Enable IPv6 support"), - opts->ipv6Choice, NULL, &(opts->ipv6Choice)); - v6Method[0] = newtRadiobutton(-1, -1, AUTO_METHOD_STR, 1, NULL); - v6Method[1] = newtRadiobutton(-1, -1, DHCPV6_METHOD_STR, 0, v6Method[0]); - v6Method[2] = newtRadiobutton(-1, -1, MANUAL_METHOD_STR, 0, v6Method[1]); + /* IPv6 checkbox */ + if (!opts->ipv6Choice) { + if (FL_NOIPV6(flags) && !FL_IPV6_PARAM(flags)) + opts->ipv6Choice = ' '; + else + opts->ipv6Choice = '*'; + } + + ipv6Checkbox = newtCheckbox(-1, -1, _("Enable IPv6 support"), + opts->ipv6Choice, NULL, + &(opts->ipv6Choice)); + v6Method[0] = newtRadiobutton(-1, -1, AUTO_METHOD_STR, 1, NULL); + v6Method[1] = + newtRadiobutton(-1, -1, DHCPV6_METHOD_STR, 0, v6Method[0]); + v6Method[2] = + newtRadiobutton(-1, -1, MANUAL_METHOD_STR, 0, v6Method[1]); #endif - /* button bar at the bottom of the window */ - buttons = newtButtonBar(_("OK"), &okay, _("Back"), &back, NULL); + /* button bar at the bottom of the window */ + buttons = newtButtonBar(_("OK"), &okay, _("Back"), &back, NULL); - /* checkgrid contains the toggle options for net configuration */ + /* checkgrid contains the toggle options for net configuration */ #ifdef ENABLE_IPV6 - checkgrid = newtCreateGrid(1, 8); + checkgrid = newtCreateGrid(1, 8); #else - checkgrid = newtCreateGrid(1, 3); + checkgrid = newtCreateGrid(1, 3); #endif - newtGridSetField(checkgrid, 0, 0, NEWT_GRID_COMPONENT, ipv4Checkbox, - 0, 0, 0, 0, NEWT_ANCHOR_LEFT, 0); - for (i = 1; i < 3; i++) - newtGridSetField(checkgrid, 0, i, NEWT_GRID_COMPONENT, v4Method[i-1], - 7, 0, 0, 0, NEWT_ANCHOR_LEFT, 0); + newtGridSetField(checkgrid, 0, 0, NEWT_GRID_COMPONENT, ipv4Checkbox, + 0, 0, 0, 0, NEWT_ANCHOR_LEFT, 0); + for (i = 1; i < 3; i++) + newtGridSetField(checkgrid, 0, i, NEWT_GRID_COMPONENT, + v4Method[i - 1], 7, 0, 0, 0, NEWT_ANCHOR_LEFT, + 0); #ifdef ENABLE_IPV6 - newtGridSetField(checkgrid, 0, 4, NEWT_GRID_COMPONENT, ipv6Checkbox, - 0, 1, 0, 0, NEWT_ANCHOR_LEFT, 0); - for (i = 5; i < 8; i++) - newtGridSetField(checkgrid, 0, i, NEWT_GRID_COMPONENT, v6Method[i-5], - 7, 0, 0, 0, NEWT_ANCHOR_LEFT, 0); + newtGridSetField(checkgrid, 0, 4, NEWT_GRID_COMPONENT, ipv6Checkbox, + 0, 1, 0, 0, NEWT_ANCHOR_LEFT, 0); + for (i = 5; i < 8; i++) + newtGridSetField(checkgrid, 0, i, NEWT_GRID_COMPONENT, + v6Method[i - 5], 7, 0, 0, 0, NEWT_ANCHOR_LEFT, + 0); #endif - /* main window layout */ - grid = newtCreateGrid(1, 2); - newtGridSetField(grid, 0, 0, NEWT_GRID_SUBGRID, checkgrid, - 0, 0, 0, 1, 0, 0); - newtGridSetField(grid, 0, 1, NEWT_GRID_SUBGRID, buttons, - 0, 0, 0, 0, 0, NEWT_GRID_FLAG_GROWX); + /* main window layout */ + grid = newtCreateGrid(1, 2); + newtGridSetField(grid, 0, 0, NEWT_GRID_SUBGRID, checkgrid, + 0, 0, 0, 1, 0, 0); + newtGridSetField(grid, 0, 1, NEWT_GRID_SUBGRID, buttons, + 0, 0, 0, 0, 0, NEWT_GRID_FLAG_GROWX); - f = newtForm(NULL, NULL, 0); - newtGridAddComponentsToForm(grid, f, 1); - newtGridWrappedWindow(grid, _("Configure TCP/IP")); - newtGridFree(grid, 1); + f = newtForm(NULL, NULL, 0); + newtGridAddComponentsToForm(grid, f, 1); + newtGridWrappedWindow(grid, _("Configure TCP/IP")); + newtGridFree(grid, 1); - /* callbacks */ - newtComponentAddCallback(ipv4Checkbox, v4MethodCallback, &v4Method); + /* callbacks */ + newtComponentAddCallback(ipv4Checkbox, v4MethodCallback, &v4Method); #ifdef ENABLE_IPV6 - newtComponentAddCallback(ipv6Checkbox, v6MethodCallback, &v6Method); + newtComponentAddCallback(ipv6Checkbox, v6MethodCallback, &v6Method); #endif - /* match radio button sensitivity to initial checkbox choices */ - if (opts->ipv4Choice == ' ') - setMethodSensitivity(&v4Method, 2); + /* match radio button sensitivity to initial checkbox choices */ + if (opts->ipv4Choice == ' ') + setMethodSensitivity(&v4Method, 2); #ifdef ENABLE_IPV6 - if (opts->ipv6Choice == ' ') - setMethodSensitivity(&v6Method, 3); + if (opts->ipv6Choice == ' ') + setMethodSensitivity(&v6Method, 3); #endif #ifdef ENABLE_IPV6 - /* If the user provided any of the following boot paramters, skip - * prompting for network configuration information: - * ip=<val> ipv6=<val> - * noipv4 noipv6 - * ip=<val> noipv6 - * ipv6=<val> noipv4 - */ - if ((FL_IP_PARAM(flags) && FL_IPV6_PARAM(flags)) || - (FL_IP_PARAM(flags) && FL_NOIPV6(flags)) || - (FL_IPV6_PARAM(flags) && FL_NOIPV4(flags)) || - (FL_NOIPV4(flags) && FL_NOIPV6(flags))) { - skipForm = 1; - newtPopWindow(); - } + /* If the user provided any of the following boot paramters, skip + * prompting for network configuration information: + * ip=<val> ipv6=<val> + * noipv4 noipv6 + * ip=<val> noipv6 + * ipv6=<val> noipv4 + */ + if ((FL_IP_PARAM(flags) && FL_IPV6_PARAM(flags)) || + (FL_IP_PARAM(flags) && FL_NOIPV6(flags)) || + (FL_IPV6_PARAM(flags) && FL_NOIPV4(flags)) || + (FL_NOIPV4(flags) && FL_NOIPV6(flags))) { + skipForm = 1; + newtPopWindow(); + } #else - if (FL_IP_PARAM(flags) || FL_NOIPV4(flags)) { - skipForm = 1; - newtPopWindow(); - } + if (FL_IP_PARAM(flags) || FL_NOIPV4(flags)) { + skipForm = 1; + newtPopWindow(); + } #endif - /* run the form */ - do { - if (!skipForm) { - answer = newtRunForm(f); + /* run the form */ + do { + if (!skipForm) { + answer = newtRunForm(f); - if (answer == back) { - newtFormDestroy(f); - newtPopWindow(); - return LOADER_BACK; - } + if (answer == back) { + newtFormDestroy(f); + newtPopWindow(); + return LOADER_BACK; + } - /* need at least one stack */ + /* need at least one stack */ #ifdef ENABLE_IPV6 - if (opts->ipv4Choice == ' ' && opts->ipv6Choice == ' ') { + if (opts->ipv4Choice == ' ' && opts->ipv6Choice == ' ') { #else - if (opts->ipv4Choice == ' ') { + if (opts->ipv4Choice == ' ') { #endif - newtWinMessage(_("Missing Protocol"), _("Retry"), - _("You must select at least one protocol (IPv4 " - "or IPv6).")); - continue; - } - - /* NFS only works over IPv4 */ - if (opts->ipv4Choice == ' ' && methodNum == METHOD_NFS) { - newtWinMessage(_("IPv4 Needed for NFS"), _("Retry"), - _("NFS installation method requires IPv4 support.")); - continue; - } - } - - /* what TCP/IP stacks do we use? what conf methods? */ - if (opts->ipv4Choice == '*') { - flags &= ~LOADER_FLAGS_NOIPV4; - for (z = IPV4_FIRST_METHOD; z <= IPV4_LAST_METHOD; z++) - if (newtRadioGetCurrent(v4Method[0]) == v4Method[z-1]) - iface->ipv4method = z; - } else { - flags |= LOADER_FLAGS_NOIPV4; - } + newtWinMessage(_("Missing Protocol"), + _("Retry"), + _ + ("You must select at least one protocol (IPv4 " + "or IPv6).")); + continue; + } + + /* NFS only works over IPv4 */ + if (opts->ipv4Choice == ' ' && methodNum == METHOD_NFS) { + newtWinMessage(_("IPv4 Needed for NFS"), + _("Retry"), + _ + ("NFS installation method requires IPv4 support.")); + continue; + } + } + + /* what TCP/IP stacks do we use? what conf methods? */ + if (opts->ipv4Choice == '*') { + flags &= ~LOADER_FLAGS_NOIPV4; + for (z = IPV4_FIRST_METHOD; z <= IPV4_LAST_METHOD; z++) + if (newtRadioGetCurrent(v4Method[0]) == + v4Method[z - 1]) + iface->ipv4method = z; + } else { + flags |= LOADER_FLAGS_NOIPV4; + } #ifdef ENABLE_IPV6 - if (opts->ipv6Choice == '*') { - flags &= ~LOADER_FLAGS_NOIPV6; - for (z = IPV6_FIRST_METHOD; z <= IPV6_LAST_METHOD; z++) - if (newtRadioGetCurrent(v6Method[0]) == v6Method[z-1]) - iface->ipv6method = z; - } else { - flags |= LOADER_FLAGS_NOIPV6; - } + if (opts->ipv6Choice == '*') { + flags &= ~LOADER_FLAGS_NOIPV6; + for (z = IPV6_FIRST_METHOD; z <= IPV6_LAST_METHOD; z++) + if (newtRadioGetCurrent(v6Method[0]) == + v6Method[z - 1]) + iface->ipv6method = z; + } else { + flags |= LOADER_FLAGS_NOIPV6; + } #endif - /* do interface configuration (call DHCP here, or return for manual) */ + /* do interface configuration (call DHCP here, or return for manual) */ #ifdef ENABLE_IPV6 - if ((!FL_NOIPV4(flags) && iface->ipv4method == IPV4_DHCP_METHOD) || - (!FL_NOIPV6(flags) && (iface->ipv6method == IPV6_AUTO_METHOD || - iface->ipv6method == IPV6_DHCP_METHOD))) { + if ((!FL_NOIPV4(flags) && iface->ipv4method == IPV4_DHCP_METHOD) + || (!FL_NOIPV6(flags) + && (iface->ipv6method == IPV6_AUTO_METHOD + || iface->ipv6method == IPV6_DHCP_METHOD))) { #else - if (!FL_NOIPV4(flags) && iface->ipv4method == IPV4_DHCP_METHOD) { + if (!FL_NOIPV4(flags) && iface->ipv4method == IPV4_DHCP_METHOD) { #endif - /* DHCP selected, exit the loop */ - ret = LOADER_NOOP; - i = 1; + /* DHCP selected, exit the loop */ + ret = LOADER_NOOP; + i = 1; #ifdef ENABLE_IPV6 - } else if ((!FL_NOIPV4(flags) && iface->ipv4method == IPV4_MANUAL_METHOD) || - (!FL_NOIPV6(flags) && iface->ipv6method == IPV6_MANUAL_METHOD)) { + } else if ((!FL_NOIPV4(flags) + && iface->ipv4method == IPV4_MANUAL_METHOD) + || (!FL_NOIPV6(flags) + && iface->ipv6method == IPV6_MANUAL_METHOD)) { #else - } else if (!FL_NOIPV4(flags) && iface->ipv4method == IPV4_MANUAL_METHOD) { + } else if (!FL_NOIPV4(flags) + && iface->ipv4method == IPV4_MANUAL_METHOD) { #endif - /* manual IP configuration selected */ - ret = LOADER_OK; - i = 1; - } - } while (i != 1); + /* manual IP configuration selected */ + ret = LOADER_OK; + i = 1; + } + } while (i != 1); - newtFormDestroy(f); - newtPopWindow(); - return ret; + newtFormDestroy(f); + newtPopWindow(); + return ret; } -int manualNetConfig(char * device, iface_t * iface, - struct intfconfig_s * ipcomps, struct netconfopts * opts) { - int i, rows, pos, cidr, have[2], stack[2]; - char *buf = NULL; - char ret[48]; - struct in_addr addr; +int manualNetConfig(char *device, iface_t * iface, + struct intfconfig_s *ipcomps, struct netconfopts *opts) +{ + int i, rows, pos, cidr, have[2], stack[2]; + char *buf = NULL; + char ret[48]; + struct in_addr addr; #ifdef ENABLE_IPV6 - struct in6_addr addr6; - int prefix; + struct in6_addr addr6; + int prefix; #endif - struct in_addr *tmpaddr = NULL; - newtComponent f, okay, back, answer; - newtGrid egrid = NULL; - newtGrid qgrid = NULL; + struct in_addr *tmpaddr = NULL; + newtComponent f, okay, back, answer; + newtGrid egrid = NULL; + newtGrid qgrid = NULL; #ifdef ENABLE_IPV6 - newtGrid rgrid = NULL; + newtGrid rgrid = NULL; #endif - newtGrid buttons, grid; - newtComponent text = NULL; + newtGrid buttons, grid; + newtComponent text = NULL; - memset(ret, '\0', INET6_ADDRSTRLEN+1); + memset(ret, '\0', INET6_ADDRSTRLEN + 1); - /* so we don't perform this test over and over */ - stack[IPV4] = opts->ipv4Choice == '*' && - iface->ipv4method == IPV4_MANUAL_METHOD; + /* so we don't perform this test over and over */ + stack[IPV4] = opts->ipv4Choice == '*' && + iface->ipv4method == IPV4_MANUAL_METHOD; #ifdef ENABLE_IPV6 - stack[IPV6] = opts->ipv6Choice == '*' && - iface->ipv6method == IPV6_MANUAL_METHOD; + stack[IPV6] = opts->ipv6Choice == '*' && + iface->ipv6method == IPV6_MANUAL_METHOD; #endif - /* UI WINDOW 2 (optional): manual IP config for non-DHCP installs */ - rows = 2; - for (i = 0; i < 2; i++) { - if (stack[i]) { - rows++; - } - } - egrid = newtCreateGrid(4, rows); - - pos = 0; - - /* IPv4 entry items */ - if (stack[IPV4]) { - newtGridSetField(egrid, 0, pos, NEWT_GRID_COMPONENT, - newtLabel(-1, -1, _("IPv4 address:")), - 0, 0, 0, 0, NEWT_ANCHOR_LEFT, 0); - - ipcomps->ipv4Entry = newtEntry(-1, -1, NULL, 16, &ipcomps->ipv4, 0); - ipcomps->cidr4Entry = newtEntry(-1, -1, NULL, 16, &ipcomps->cidr4, 0); - - /* use a nested grid for ipv4 addr & netmask */ - qgrid = newtCreateGrid(3, 1); - - newtGridSetField(qgrid, 0, 0, NEWT_GRID_COMPONENT, - ipcomps->ipv4Entry, 1, 0, 0, 0, NEWT_ANCHOR_LEFT, 0); - newtGridSetField(qgrid, 1, 0, NEWT_GRID_COMPONENT, - newtLabel(-1, -1, _("/")), - 1, 0, 0, 0, NEWT_ANCHOR_LEFT, 0); - newtGridSetField(qgrid, 2, 0, NEWT_GRID_COMPONENT, - ipcomps->cidr4Entry, 1, 0, 0, 0, NEWT_ANCHOR_LEFT, 0); - - newtGridSetField(egrid, 1, pos, NEWT_GRID_SUBGRID, qgrid, - 0, 0, 0, 0, NEWT_ANCHOR_LEFT, 0); - - newtComponentAddCallback(ipcomps->ipv4Entry, ipCallback, ipcomps); - newtComponentAddCallback(ipcomps->cidr4Entry, cidrCallback, ipcomps); - - /* populate fields if we have data already */ - if (iface_have_in_addr(&iface->ipaddr)) { - if (inet_ntop(AF_INET, &iface->ipaddr, ret, - INET_ADDRSTRLEN) == NULL) { - logMessage(ERROR, "%s (%d): %s", __func__, __LINE__, - strerror(errno)); - } - } else if (iface_have_in_addr(&iface->ipaddr)) { - if (inet_ntop(AF_INET, &iface->ipaddr, ret, - INET_ADDRSTRLEN) == NULL) { - logMessage(ERROR, "%s (%d): %s", __func__, __LINE__, - strerror(errno)); - } - } - - if (*ret) { - newtEntrySet(ipcomps->ipv4Entry, ret, 1); - } - - if (iface_have_in_addr(&iface->netmask)) { - if (inet_ntop(AF_INET, &iface->netmask, ret, - INET_ADDRSTRLEN) == NULL) { - logMessage(ERROR, "%s (%d): %s", __func__, __LINE__, - strerror(errno)); - } - } else if (iface_have_in_addr(&iface->netmask)) { - if (inet_ntop(AF_INET, &iface->netmask, ret, - INET_ADDRSTRLEN) == NULL) { - logMessage(ERROR, "%s (%d): %s", __func__, __LINE__, - strerror(errno)); - } - } - - if (*ret) { - newtEntrySet(ipcomps->cidr4Entry, ret, 1); - } - - pos++; - } - + /* UI WINDOW 2 (optional): manual IP config for non-DHCP installs */ + rows = 2; + for (i = 0; i < 2; i++) { + if (stack[i]) { + rows++; + } + } + egrid = newtCreateGrid(4, rows); + + pos = 0; + + /* IPv4 entry items */ + if (stack[IPV4]) { + newtGridSetField(egrid, 0, pos, NEWT_GRID_COMPONENT, + newtLabel(-1, -1, _("IPv4 address:")), + 0, 0, 0, 0, NEWT_ANCHOR_LEFT, 0); + + ipcomps->ipv4Entry = + newtEntry(-1, -1, NULL, 16, &ipcomps->ipv4, 0); + ipcomps->cidr4Entry = + newtEntry(-1, -1, NULL, 16, &ipcomps->cidr4, 0); + + /* use a nested grid for ipv4 addr & netmask */ + qgrid = newtCreateGrid(3, 1); + + newtGridSetField(qgrid, 0, 0, NEWT_GRID_COMPONENT, + ipcomps->ipv4Entry, 1, 0, 0, 0, + NEWT_ANCHOR_LEFT, 0); + newtGridSetField(qgrid, 1, 0, NEWT_GRID_COMPONENT, + newtLabel(-1, -1, _("/")), 1, 0, 0, 0, + NEWT_ANCHOR_LEFT, 0); + newtGridSetField(qgrid, 2, 0, NEWT_GRID_COMPONENT, + ipcomps->cidr4Entry, 1, 0, 0, 0, + NEWT_ANCHOR_LEFT, 0); + + newtGridSetField(egrid, 1, pos, NEWT_GRID_SUBGRID, qgrid, + 0, 0, 0, 0, NEWT_ANCHOR_LEFT, 0); + + newtComponentAddCallback(ipcomps->ipv4Entry, ipCallback, + ipcomps); + newtComponentAddCallback(ipcomps->cidr4Entry, cidrCallback, + ipcomps); + + /* populate fields if we have data already */ + if (iface_have_in_addr(&iface->ipaddr)) { + if (inet_ntop(AF_INET, &iface->ipaddr, ret, + INET_ADDRSTRLEN) == NULL) { + logMessage(ERROR, "%s (%d): %s", __func__, + __LINE__, strerror(errno)); + } + } else if (iface_have_in_addr(&iface->ipaddr)) { + if (inet_ntop(AF_INET, &iface->ipaddr, ret, + INET_ADDRSTRLEN) == NULL) { + logMessage(ERROR, "%s (%d): %s", __func__, + __LINE__, strerror(errno)); + } + } + + if (*ret) { + newtEntrySet(ipcomps->ipv4Entry, ret, 1); + } + + if (iface_have_in_addr(&iface->netmask)) { + if (inet_ntop(AF_INET, &iface->netmask, ret, + INET_ADDRSTRLEN) == NULL) { + logMessage(ERROR, "%s (%d): %s", __func__, + __LINE__, strerror(errno)); + } + } else if (iface_have_in_addr(&iface->netmask)) { + if (inet_ntop(AF_INET, &iface->netmask, ret, + INET_ADDRSTRLEN) == NULL) { + logMessage(ERROR, "%s (%d): %s", __func__, + __LINE__, strerror(errno)); + } + } + + if (*ret) { + newtEntrySet(ipcomps->cidr4Entry, ret, 1); + } + + pos++; + } #ifdef ENABLE_IPV6 - /* IPv6 entry items */ - if (stack[IPV6]) { - newtGridSetField(egrid, 0, pos, NEWT_GRID_COMPONENT, - newtLabel(-1, -1, _("IPv6 address:")), - 0, 0, 0, 0, NEWT_ANCHOR_LEFT, 0); - - ipcomps->ipv6Entry = newtEntry(-1, -1, NULL, 41, &ipcomps->ipv6, 0); - ipcomps->cidr6Entry = newtEntry(-1, -1, NULL, 4, &ipcomps->cidr6, 0); - - /* use a nested grid for ipv6 addr & netmask */ - rgrid = newtCreateGrid(3, 1); - - newtGridSetField(rgrid, 0, 0, NEWT_GRID_COMPONENT, - ipcomps->ipv6Entry, 1, 0, 0, 0, NEWT_ANCHOR_LEFT, 0); - newtGridSetField(rgrid, 1, 0, NEWT_GRID_COMPONENT, - newtLabel(-1, -1, _("/")), - 1, 0, 0, 0, NEWT_ANCHOR_LEFT, 0); - newtGridSetField(rgrid, 2, 0, NEWT_GRID_COMPONENT, - ipcomps->cidr6Entry, 1, 0, 0, 0, NEWT_ANCHOR_LEFT, 0); - - newtGridSetField(egrid, 1, pos, NEWT_GRID_SUBGRID, rgrid, - 0, 0, 0, 0, NEWT_ANCHOR_LEFT, 0); - - newtComponentAddCallback(ipcomps->ipv6Entry, ipCallback, ipcomps); - newtComponentAddCallback(ipcomps->cidr6Entry, cidrCallback, ipcomps); - - /* populate fields if we have data already */ - if (iface_have_in6_addr(&iface->ip6addr)) { - if (inet_ntop(AF_INET6, &iface->ip6addr, ret, - INET6_ADDRSTRLEN) == NULL) { - logMessage(ERROR, "%s (%d): %s", __func__, __LINE__, - strerror(errno)); - } - } else if (iface_have_in6_addr(&iface->ip6addr)) { - if (inet_ntop(AF_INET6, &iface->ip6addr, ret, - INET6_ADDRSTRLEN) == NULL) { - logMessage(ERROR, "%s (%d): %s", __func__, __LINE__, - strerror(errno)); - } - } - - if (*ret) { - newtEntrySet(ipcomps->ipv6Entry, ret, 1); - } - - if (iface->ip6prefix) { - if (asprintf(&buf, "%d", iface->ip6prefix) == -1) { - buf = NULL; - } - } else if (iface->ip6prefix) { - if (asprintf(&buf, "%d", iface->ip6prefix) == -1) { - buf = NULL; - } - } - - if (buf != NULL) { - newtEntrySet(ipcomps->cidr6Entry, buf, 1); - free(buf); - } - - pos++; - } + /* IPv6 entry items */ + if (stack[IPV6]) { + newtGridSetField(egrid, 0, pos, NEWT_GRID_COMPONENT, + newtLabel(-1, -1, _("IPv6 address:")), + 0, 0, 0, 0, NEWT_ANCHOR_LEFT, 0); + + ipcomps->ipv6Entry = + newtEntry(-1, -1, NULL, 41, &ipcomps->ipv6, 0); + ipcomps->cidr6Entry = + newtEntry(-1, -1, NULL, 4, &ipcomps->cidr6, 0); + + /* use a nested grid for ipv6 addr & netmask */ + rgrid = newtCreateGrid(3, 1); + + newtGridSetField(rgrid, 0, 0, NEWT_GRID_COMPONENT, + ipcomps->ipv6Entry, 1, 0, 0, 0, + NEWT_ANCHOR_LEFT, 0); + newtGridSetField(rgrid, 1, 0, NEWT_GRID_COMPONENT, + newtLabel(-1, -1, _("/")), 1, 0, 0, 0, + NEWT_ANCHOR_LEFT, 0); + newtGridSetField(rgrid, 2, 0, NEWT_GRID_COMPONENT, + ipcomps->cidr6Entry, 1, 0, 0, 0, + NEWT_ANCHOR_LEFT, 0); + + newtGridSetField(egrid, 1, pos, NEWT_GRID_SUBGRID, rgrid, + 0, 0, 0, 0, NEWT_ANCHOR_LEFT, 0); + + newtComponentAddCallback(ipcomps->ipv6Entry, ipCallback, + ipcomps); + newtComponentAddCallback(ipcomps->cidr6Entry, cidrCallback, + ipcomps); + + /* populate fields if we have data already */ + if (iface_have_in6_addr(&iface->ip6addr)) { + if (inet_ntop(AF_INET6, &iface->ip6addr, ret, + INET6_ADDRSTRLEN) == NULL) { + logMessage(ERROR, "%s (%d): %s", __func__, + __LINE__, strerror(errno)); + } + } else if (iface_have_in6_addr(&iface->ip6addr)) { + if (inet_ntop(AF_INET6, &iface->ip6addr, ret, + INET6_ADDRSTRLEN) == NULL) { + logMessage(ERROR, "%s (%d): %s", __func__, + __LINE__, strerror(errno)); + } + } + + if (*ret) { + newtEntrySet(ipcomps->ipv6Entry, ret, 1); + } + + if (iface->ip6prefix) { + if (asprintf(&buf, "%d", iface->ip6prefix) == -1) { + buf = NULL; + } + } else if (iface->ip6prefix) { + if (asprintf(&buf, "%d", iface->ip6prefix) == -1) { + buf = NULL; + } + } + + if (buf != NULL) { + newtEntrySet(ipcomps->cidr6Entry, buf, 1); + free(buf); + } + + pos++; + } #endif - /* common entry items */ - ipcomps->gwEntry = newtEntry(-1, -1, NULL, 41, &ipcomps->gw, 0); - ipcomps->nsEntry = newtEntry(-1, -1, NULL, 41, &ipcomps->ns, 0); - - newtGridSetField(egrid, 0, pos, NEWT_GRID_COMPONENT, - newtLabel(-1, -1, _("Gateway:")), - 0, 0, 0, 0, NEWT_ANCHOR_LEFT, 0); - newtGridSetField(egrid, 1, pos, NEWT_GRID_COMPONENT, - ipcomps->gwEntry, 1, 0, 0, 0, NEWT_ANCHOR_LEFT, 0); - - pos++; - - newtGridSetField(egrid, 0, pos, NEWT_GRID_COMPONENT, - newtLabel(-1, -1, _("Name Server:")), - 0, 0, 0, 0, NEWT_ANCHOR_LEFT, 0); - newtGridSetField(egrid, 1, pos, NEWT_GRID_COMPONENT, - ipcomps->nsEntry, 1, 0, 0, 0, NEWT_ANCHOR_LEFT, 0); - - if (iface_have_in_addr(&iface->gateway)) { - if (inet_ntop(AF_INET, &iface->gateway, ret, - INET_ADDRSTRLEN) == NULL) { - logMessage(ERROR, "%s (%d): %s", __func__, __LINE__, - strerror(errno)); - } else { - newtEntrySet(ipcomps->gwEntry, ret, 1); - } - } else if (iface_have_in6_addr(&iface->gateway6)) { - if (inet_ntop(AF_INET6, &iface->gateway6, ret, - INET6_ADDRSTRLEN) == NULL) { - logMessage(ERROR, "%s (%d): %s", __func__, __LINE__, - strerror(errno)); - } else { - newtEntrySet(ipcomps->gwEntry, ret, 1); - } - } - - if (iface->numdns) { - newtEntrySet(ipcomps->nsEntry, iface->dns[0], 1); - } else if (iface->numdns) { - newtEntrySet(ipcomps->nsEntry, iface->dns[0], 1); - } - - newtComponentAddCallback(ipcomps->gwEntry, ipCallback, ipcomps); - newtComponentAddCallback(ipcomps->nsEntry, ipCallback, ipcomps); - - /* button bar at the bottom of the window */ - buttons = newtButtonBar(_("OK"), &okay, _("Back"), &back, NULL); - - /* main window layout */ - grid = newtCreateGrid(1, 3); - - checked_asprintf(&buf, - _("Enter the IPv4 and/or the IPv6 address and prefix " - "(address / prefix). For IPv4, the dotted-quad " - "netmask or the CIDR-style prefix are acceptable. " - "The gateway and name server fields must be valid IPv4 " - "or IPv6 addresses.")); - - text = newtTextboxReflowed(-1, -1, buf, 52, 0, 10, 0); - - newtGridSetField(grid, 0, 0, NEWT_GRID_COMPONENT, text, - 0, 0, 0, 1, NEWT_ANCHOR_LEFT, 0); - newtGridSetField(grid, 0, 1, NEWT_GRID_SUBGRID, egrid, - 0, 0, 0, 1, NEWT_ANCHOR_LEFT, 0); - newtGridSetField(grid, 0, 2, NEWT_GRID_SUBGRID, buttons, - 0, 0, 0, 0, 0, NEWT_GRID_FLAG_GROWX); - - f = newtForm(NULL, NULL, 0); - newtGridAddComponentsToForm(grid, f, 1); - newtGridWrappedWindow(grid, _("Manual TCP/IP Configuration")); - newtGridFree(grid, 1); - - have[IPV4] = 0; - have[IPV6] = 0; - - for (i = IPV4; i <= IPV6; i++) { - if (!stack[i]) { - have[i] = 2; - } - } - - /* run the form */ - while ((have[IPV4] != 2) && (have[IPV6] != 2)) { - answer = newtRunForm(f); - - /* collect IPv4 data */ - if (stack[IPV4]) { - if (ipcomps->ipv4) { - if (inet_pton(AF_INET, ipcomps->ipv4, &iface->ipaddr) <= 0) { - logMessage(ERROR, "%s (%d): %s", __func__, __LINE__, - strerror(errno)); - } else { - have[IPV4]++; - } - } - - if (ipcomps->cidr4) { - if (inet_pton(AF_INET, ipcomps->cidr4, &iface->netmask) >= 1) { - have[IPV4]++; - } else { - errno = 0; - cidr = strtol(ipcomps->cidr4, NULL, 10); - - if ((errno == ERANGE && (cidr == LONG_MIN || - cidr == LONG_MAX)) || - (errno != 0 && cidr == 0)) { - logMessage(ERROR, "%s: %d: %m", __func__, __LINE__); - abort(); - } - - if (cidr >= 1 && cidr <= 32) { - tmpaddr = iface_prefix2netmask(cidr); - if (tmpaddr != NULL) { - memcpy(&iface->netmask, tmpaddr, - sizeof(struct in_addr)); - have[IPV4]++; - } else { - iface->netmask.s_addr = 0; - } - } - } - } - } + /* common entry items */ + ipcomps->gwEntry = newtEntry(-1, -1, NULL, 41, &ipcomps->gw, 0); + ipcomps->nsEntry = newtEntry(-1, -1, NULL, 41, &ipcomps->ns, 0); + + newtGridSetField(egrid, 0, pos, NEWT_GRID_COMPONENT, + newtLabel(-1, -1, _("Gateway:")), + 0, 0, 0, 0, NEWT_ANCHOR_LEFT, 0); + newtGridSetField(egrid, 1, pos, NEWT_GRID_COMPONENT, + ipcomps->gwEntry, 1, 0, 0, 0, NEWT_ANCHOR_LEFT, 0); + + pos++; + + newtGridSetField(egrid, 0, pos, NEWT_GRID_COMPONENT, + newtLabel(-1, -1, _("Name Server:")), + 0, 0, 0, 0, NEWT_ANCHOR_LEFT, 0); + newtGridSetField(egrid, 1, pos, NEWT_GRID_COMPONENT, + ipcomps->nsEntry, 1, 0, 0, 0, NEWT_ANCHOR_LEFT, 0); + + if (iface_have_in_addr(&iface->gateway)) { + if (inet_ntop(AF_INET, &iface->gateway, ret, + INET_ADDRSTRLEN) == NULL) { + logMessage(ERROR, "%s (%d): %s", __func__, __LINE__, + strerror(errno)); + } else { + newtEntrySet(ipcomps->gwEntry, ret, 1); + } + } else if (iface_have_in6_addr(&iface->gateway6)) { + if (inet_ntop(AF_INET6, &iface->gateway6, ret, + INET6_ADDRSTRLEN) == NULL) { + logMessage(ERROR, "%s (%d): %s", __func__, __LINE__, + strerror(errno)); + } else { + newtEntrySet(ipcomps->gwEntry, ret, 1); + } + } + + if (iface->numdns) { + newtEntrySet(ipcomps->nsEntry, iface->dns[0], 1); + } else if (iface->numdns) { + newtEntrySet(ipcomps->nsEntry, iface->dns[0], 1); + } + + newtComponentAddCallback(ipcomps->gwEntry, ipCallback, ipcomps); + newtComponentAddCallback(ipcomps->nsEntry, ipCallback, ipcomps); + + /* button bar at the bottom of the window */ + buttons = newtButtonBar(_("OK"), &okay, _("Back"), &back, NULL); + + /* main window layout */ + grid = newtCreateGrid(1, 3); + + checked_asprintf(&buf, + _("Enter the IPv4 and/or the IPv6 address and prefix " + "(address / prefix). For IPv4, the dotted-quad " + "netmask or the CIDR-style prefix are acceptable. " + "The gateway and name server fields must be valid IPv4 " + "or IPv6 addresses.")); + + text = newtTextboxReflowed(-1, -1, buf, 52, 0, 10, 0); + + newtGridSetField(grid, 0, 0, NEWT_GRID_COMPONENT, text, + 0, 0, 0, 1, NEWT_ANCHOR_LEFT, 0); + newtGridSetField(grid, 0, 1, NEWT_GRID_SUBGRID, egrid, + 0, 0, 0, 1, NEWT_ANCHOR_LEFT, 0); + newtGridSetField(grid, 0, 2, NEWT_GRID_SUBGRID, buttons, + 0, 0, 0, 0, 0, NEWT_GRID_FLAG_GROWX); + + f = newtForm(NULL, NULL, 0); + newtGridAddComponentsToForm(grid, f, 1); + newtGridWrappedWindow(grid, _("Manual TCP/IP Configuration")); + newtGridFree(grid, 1); + + have[IPV4] = 0; + have[IPV6] = 0; + for (i = IPV4; i <= IPV6; i++) { + if (!stack[i]) { + have[i] = 2; + } + } + + /* run the form */ + while ((have[IPV4] != 2) && (have[IPV6] != 2)) { + answer = newtRunForm(f); + + /* collect IPv4 data */ + if (stack[IPV4]) { + if (ipcomps->ipv4) { + if (inet_pton + (AF_INET, ipcomps->ipv4, + &iface->ipaddr) <= 0) { + logMessage(ERROR, "%s (%d): %s", + __func__, __LINE__, + strerror(errno)); + } else { + have[IPV4]++; + } + } + + if (ipcomps->cidr4) { + if (inet_pton + (AF_INET, ipcomps->cidr4, + &iface->netmask) >= 1) { + have[IPV4]++; + } else { + errno = 0; + cidr = strtol(ipcomps->cidr4, NULL, 10); + + if ((errno == ERANGE + && (cidr == LONG_MIN + || cidr == LONG_MAX)) + || (errno != 0 && cidr == 0)) { + logMessage(ERROR, "%s: %d: %m", + __func__, __LINE__); + abort(); + } + + if (cidr >= 1 && cidr <= 32) { + tmpaddr = + iface_prefix2netmask(cidr); + if (tmpaddr != NULL) { + memcpy(&iface->netmask, + tmpaddr, + sizeof(struct + in_addr)); + have[IPV4]++; + } else { + iface->netmask.s_addr = + 0; + } + } + } + } + } #ifdef ENABLE_IPV6 - /* collect IPv6 data */ - if (stack[IPV6]) { - if (ipcomps->ipv6) { - if (inet_pton(AF_INET6, ipcomps->ipv6, &iface->ip6addr) <= 0) { - logMessage(ERROR, "%s (%d): %s", __func__, __LINE__, - strerror(errno)); - } else { - have[IPV6]++; - } - } - - if (ipcomps->cidr6) { - errno = 0; - prefix = strtol(ipcomps->cidr6, NULL, 10); - - if ((errno == ERANGE && (prefix == LONG_MIN || - prefix == LONG_MAX)) || - (errno != 0 && prefix == 0)) { - logMessage(ERROR, "%s: %d: %m", __func__, __LINE__); - abort(); - } - - if (prefix > 0 || prefix <= 128) { - iface->ip6prefix = prefix; - have[IPV6]++; - } - } - } + /* collect IPv6 data */ + if (stack[IPV6]) { + if (ipcomps->ipv6) { + if (inet_pton + (AF_INET6, ipcomps->ipv6, + &iface->ip6addr) <= 0) { + logMessage(ERROR, "%s (%d): %s", + __func__, __LINE__, + strerror(errno)); + } else { + have[IPV6]++; + } + } + + if (ipcomps->cidr6) { + errno = 0; + prefix = strtol(ipcomps->cidr6, NULL, 10); + + if ((errno == ERANGE && (prefix == LONG_MIN || + prefix == LONG_MAX)) || + (errno != 0 && prefix == 0)) { + logMessage(ERROR, "%s: %d: %m", + __func__, __LINE__); + abort(); + } + + if (prefix > 0 || prefix <= 128) { + iface->ip6prefix = prefix; + have[IPV6]++; + } + } + } #endif - /* collect common network settings */ - if (ipcomps->gw) { - if (inet_pton(AF_INET, ipcomps->gw, &iface->gateway) <= 0) { - memset(&iface->gateway, 0, sizeof(iface->gateway)); - - if (inet_pton(AF_INET6, ipcomps->gw, &iface->gateway6) <= 0) { - logMessage(ERROR, "%s (%d): %s", __func__, __LINE__, - strerror(errno)); - memset(&iface->gateway6, 0, sizeof(iface->gateway6)); - } - } - } - - /* gather nameservers */ - if (ipcomps->ns) { + /* collect common network settings */ + if (ipcomps->gw) { + if (inet_pton(AF_INET, ipcomps->gw, &iface->gateway) <= + 0) { + memset(&iface->gateway, 0, + sizeof(iface->gateway)); + + if (inet_pton + (AF_INET6, ipcomps->gw, + &iface->gateway6) <= 0) { + logMessage(ERROR, "%s (%d): %s", + __func__, __LINE__, + strerror(errno)); + memset(&iface->gateway6, 0, + sizeof(iface->gateway6)); + } + } + } + + /* gather nameservers */ + if (ipcomps->ns) { #ifdef ENABLE_IPV6 - if ((inet_pton(AF_INET, ipcomps->ns, &addr) >= 1) || - (inet_pton(AF_INET6, ipcomps->ns, &addr6) >= 1)) { + if ((inet_pton(AF_INET, ipcomps->ns, &addr) >= 1) || + (inet_pton(AF_INET6, ipcomps->ns, &addr6) >= 1)) { #else - if (inet_pton(AF_INET, ipcomps->ns, &addr) >= 1) { + if (inet_pton(AF_INET, ipcomps->ns, &addr) >= 1) { #endif - iface->dns[0] = strdup(ipcomps->ns); - if (iface->numdns < 1) - iface->numdns = 1; - } - } - - /* user selected back, but we've saved what they entered already */ - if (answer == back) { - newtFormDestroy(f); - newtPopWindow(); - free(buf); - return LOADER_BACK; - } - - /* we might be done now */ - if (stack[IPV4] && have[IPV4] != 2) { - newtWinMessage(_("Missing Information"), _("Retry"), - _("You must enter both a valid IPv4 address and a " - "network mask or CIDR prefix.")); - } - + iface->dns[0] = strdup(ipcomps->ns); + if (iface->numdns < 1) + iface->numdns = 1; + } + } + + /* user selected back, but we've saved what they entered already */ + if (answer == back) { + newtFormDestroy(f); + newtPopWindow(); + free(buf); + return LOADER_BACK; + } + + /* we might be done now */ + if (stack[IPV4] && have[IPV4] != 2) { + newtWinMessage(_("Missing Information"), _("Retry"), + _ + ("You must enter both a valid IPv4 address and a " + "network mask or CIDR prefix.")); + } #ifdef ENABLE_IPV6 - if (stack[IPV6] && have[IPV6] != 2) { - newtWinMessage(_("Missing Information"), _("Retry"), - _("You must enter both a valid IPv6 address and a " - "CIDR prefix.")); - } + if (stack[IPV6] && have[IPV6] != 2) { + newtWinMessage(_("Missing Information"), _("Retry"), + _ + ("You must enter both a valid IPv6 address and a " + "CIDR prefix.")); + } #endif - strcpy(iface->device, device); - } + strcpy(iface->device, device); + } - free(buf); - newtFormDestroy(f); - newtPopWindow(); + free(buf); + newtFormDestroy(f); + newtPopWindow(); - return LOADER_OK; + return LOADER_OK; } /* * By default, we disable all network interfaces and then only * bring up the ones the user wants. */ -int writeDisabledNetInfo(void) { - int i = 0; - char *ofile = NULL; - char *nfile = NULL; - FILE *fp = NULL; - struct device **devs = NULL; - - devs = getDevices(DEVICE_NETWORK); - - if (devs == NULL) { - return 1; - } - - for (i = 0; devs[i]; i++) { - /* remove dhclient-DEVICE.conf if we have it */ - if (asprintf(&ofile, "/etc/dhcp/dhclient-%s.conf", devs[i]->device) == -1) { - return 5; - } - - if (!access(ofile, R_OK|W_OK)) { - if (unlink(ofile)) { - logMessage(ERROR, "error removing %s", ofile); - } - } - - if (ofile) { - free(ofile); - ofile = NULL; - } - - /* write disabled ifcfg-DEVICE file */ - - checked_asprintf(&ofile, "%s/.ifcfg-%s", - NETWORK_SCRIPTS_PATH, - devs[i]->device); - checked_asprintf(&nfile, "%s/ifcfg-%s", - NETWORK_SCRIPTS_PATH, - devs[i]->device); - - if ((fp = fopen(ofile, "w")) == NULL) { - free(ofile); - return 2; - } - - fprintf(fp, "DEVICE=%s\n", devs[i]->device); - fprintf(fp, "HWADDR=%s\n", iface_mac2str(devs[i]->device)); - fprintf(fp, "ONBOOT=no\n"); - fprintf(fp, "NM_CONTROLLED=no\n"); - - if (fclose(fp) == EOF) { - return 3; - } - - if (rename(ofile, nfile) == -1) { - free(ofile); - free(nfile); - return 4; - } - - if (ofile) { - free(ofile); - ofile = NULL; - } - - if (nfile) { - free(nfile); - nfile = NULL; - } - } - - return 0; +int writeDisabledNetInfo(void) +{ + int i = 0; + char *ofile = NULL; + char *nfile = NULL; + FILE *fp = NULL; + struct device **devs = NULL; + + devs = getDevices(DEVICE_NETWORK); + + if (devs == NULL) { + return 1; + } + + for (i = 0; devs[i]; i++) { + /* remove dhclient-DEVICE.conf if we have it */ + if (asprintf + (&ofile, "/etc/dhcp/dhclient-%s.conf", + devs[i]->device) == -1) { + return 5; + } + + if (!access(ofile, R_OK | W_OK)) { + if (unlink(ofile)) { + logMessage(ERROR, "error removing %s", ofile); + } + } + + if (ofile) { + free(ofile); + ofile = NULL; + } + + /* write disabled ifcfg-DEVICE file */ + + checked_asprintf(&ofile, "%s/.ifcfg-%s", + NETWORK_SCRIPTS_PATH, devs[i]->device); + checked_asprintf(&nfile, "%s/ifcfg-%s", + NETWORK_SCRIPTS_PATH, devs[i]->device); + + if ((fp = fopen(ofile, "w")) == NULL) { + free(ofile); + return 2; + } + + fprintf(fp, "DEVICE=%s\n", devs[i]->device); + fprintf(fp, "HWADDR=%s\n", iface_mac2str(devs[i]->device)); + fprintf(fp, "ONBOOT=no\n"); + fprintf(fp, "NM_CONTROLLED=no\n"); + + if (fclose(fp) == EOF) { + return 3; + } + + if (rename(ofile, nfile) == -1) { + free(ofile); + free(nfile); + return 4; + } + + if (ofile) { + free(ofile); + ofile = NULL; + } + + if (nfile) { + free(nfile); + nfile = NULL; + } + } + + return 0; } /* @@ -1198,914 +1291,960 @@ int writeDisabledNetInfo(void) { * /etc/sysconfig/network-scripts/ifcfg-DEVICE * /etc/sysconfig/network */ -int writeEnabledNetInfo(iface_t *iface) { - int i = 0, osa_layer2 = 1, osa_portno = 0; - mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; - FILE *fp = NULL; - char buf[INET6_ADDRSTRLEN+1]; - char *ofile = NULL; - char *nfile = NULL; - struct utsname kv; - - memset(&buf, '\0', sizeof(buf)); - - if ((mkdir(NETWORK_SCRIPTS_PATH, mode) == -1) && (errno != EEXIST)) { - return 16; - } - - /* write vendor class */ - if (iface->vendorclass == NULL) { - if (uname(&kv) == -1) { - iface->vendorclass = "anaconda"; - } else { - if (asprintf(&iface->vendorclass, "anaconda-%s %s %s", - kv.sysname, kv.release, kv.machine) == -1 ) { - return 20; - } - } - } - - if (asprintf(&ofile, "/etc/dhcp/dhclient-%s.conf", iface->device) == -1) { - return 17; - } - - if ((fp = fopen(ofile, "w")) == NULL) { - free(ofile); - return 18; - } - - fprintf(fp, "send vendor-class-identifier \"%s\";\n", - iface->vendorclass); - - if (fclose(fp) == EOF) { - free(ofile); - return 19; - } - - if (ofile) { - free(ofile); - ofile = NULL; - } - - /* write out new ifcfg-DEVICE file */ - if (asprintf(&ofile, "%s/.ifcfg-%s", - NETWORK_SCRIPTS_PATH, iface->device) == -1) { - return 1; - } - - if (asprintf(&nfile, "%s/ifcfg-%s", - NETWORK_SCRIPTS_PATH, iface->device) == -1) { - return 13; - } - - if ((fp = fopen(ofile, "w")) == NULL) { - free(ofile); - return 2; - } - - fprintf(fp, "DEVICE=%s\n", iface->device); - fprintf(fp, "HWADDR=%s\n", iface_mac2str(iface->device)); - fprintf(fp, "ONBOOT=yes\n"); - - if (!FL_NOIPV4(flags)) { - if (iface->ipv4method == IPV4_IBFT_METHOD) { - /* When initrd and NM support iBFT, we should just write - * BOOTPROTO=ibft and let NM deal with it. Until than, - * just use static and do it ourselves. */ - fprintf(fp, "BOOTPROTO=static\n"); - if(ibft_iface_ip()) fprintf(fp, "IPADDR=%s\n", ibft_iface_ip()); - if(ibft_iface_mask()) fprintf(fp, "NETMASK=%s\n", ibft_iface_mask()); - if(ibft_iface_gw()) fprintf(fp, "GATEWAY=%s\n", ibft_iface_gw()); - } else if (iface->ipv4method == IPV4_IBFT_DHCP_METHOD) { - fprintf(fp, "BOOTPROTO=dhcp\n"); - } else if (iface->ipv4method == IPV4_DHCP_METHOD) { - fprintf(fp, "BOOTPROTO=dhcp\n"); - } else if (iface->ipv4method == IPV4_MANUAL_METHOD) { - fprintf(fp, "BOOTPROTO=static\n"); - - if (iface_have_in_addr(&iface->ipaddr)) { - if (inet_ntop(AF_INET, &iface->ipaddr, buf, - INET_ADDRSTRLEN) == NULL) { - free(ofile); - fclose(fp); - return 3; - } - - fprintf(fp, "IPADDR=%s\n", buf); - } - - if (iface_have_in_addr(&iface->netmask)) { - if (inet_ntop(AF_INET, &iface->netmask, buf, - INET_ADDRSTRLEN) == NULL) { - free(ofile); - fclose(fp); - return 4; - } - - fprintf(fp, "NETMASK=%s\n", buf); - } - - if (iface_have_in_addr(&iface->broadcast)) { - if (inet_ntop(AF_INET, &iface->broadcast, buf, - INET_ADDRSTRLEN) == NULL) { - free(ofile); - fclose(fp); - return 5; - } - - fprintf(fp, "BROADCAST=%s\n", buf); - } - - if (iface_have_in_addr(&iface->gateway)) { - if (inet_ntop(AF_INET, &iface->gateway, buf, - INET_ADDRSTRLEN) == NULL) { - free(ofile); - fclose(fp); - return 6; - } - - fprintf(fp, "GATEWAY=%s\n", buf); - } - } - } +int writeEnabledNetInfo(iface_t * iface) +{ + int i = 0, osa_layer2 = 1, osa_portno = 0; + mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; + FILE *fp = NULL; + char buf[INET6_ADDRSTRLEN + 1]; + char *ofile = NULL; + char *nfile = NULL; + struct utsname kv; + + memset(&buf, '\0', sizeof(buf)); + + if ((mkdir(NETWORK_SCRIPTS_PATH, mode) == -1) && (errno != EEXIST)) { + return 16; + } + + /* write vendor class */ + if (iface->vendorclass == NULL) { + if (uname(&kv) == -1) { + iface->vendorclass = "anaconda"; + } else { + if (asprintf(&iface->vendorclass, "anaconda-%s %s %s", + kv.sysname, kv.release, + kv.machine) == -1) { + return 20; + } + } + } + + if (asprintf(&ofile, "/etc/dhcp/dhclient-%s.conf", iface->device) == -1) { + return 17; + } + + if ((fp = fopen(ofile, "w")) == NULL) { + free(ofile); + return 18; + } + fprintf(fp, "send vendor-class-identifier \"%s\";\n", + iface->vendorclass); + + if (fclose(fp) == EOF) { + free(ofile); + return 19; + } + + if (ofile) { + free(ofile); + ofile = NULL; + } + + /* write out new ifcfg-DEVICE file */ + if (asprintf(&ofile, "%s/.ifcfg-%s", + NETWORK_SCRIPTS_PATH, iface->device) == -1) { + return 1; + } + + if (asprintf(&nfile, "%s/ifcfg-%s", + NETWORK_SCRIPTS_PATH, iface->device) == -1) { + return 13; + } + + if ((fp = fopen(ofile, "w")) == NULL) { + free(ofile); + return 2; + } + + fprintf(fp, "DEVICE=%s\n", iface->device); + fprintf(fp, "HWADDR=%s\n", iface_mac2str(iface->device)); + fprintf(fp, "ONBOOT=yes\n"); + + if (!FL_NOIPV4(flags)) { + if (iface->ipv4method == IPV4_IBFT_METHOD) { + /* When initrd and NM support iBFT, we should just write + * BOOTPROTO=ibft and let NM deal with it. Until than, + * just use static and do it ourselves. */ + fprintf(fp, "BOOTPROTO=static\n"); + if (ibft_iface_ip()) + fprintf(fp, "IPADDR=%s\n", ibft_iface_ip()); + if (ibft_iface_mask()) + fprintf(fp, "NETMASK=%s\n", ibft_iface_mask()); + if (ibft_iface_gw()) + fprintf(fp, "GATEWAY=%s\n", ibft_iface_gw()); + } else if (iface->ipv4method == IPV4_IBFT_DHCP_METHOD) { + fprintf(fp, "BOOTPROTO=dhcp\n"); + } else if (iface->ipv4method == IPV4_DHCP_METHOD) { + fprintf(fp, "BOOTPROTO=dhcp\n"); + } else if (iface->ipv4method == IPV4_MANUAL_METHOD) { + fprintf(fp, "BOOTPROTO=static\n"); + + if (iface_have_in_addr(&iface->ipaddr)) { + if (inet_ntop(AF_INET, &iface->ipaddr, buf, + INET_ADDRSTRLEN) == NULL) { + free(ofile); + fclose(fp); + return 3; + } + + fprintf(fp, "IPADDR=%s\n", buf); + } + + if (iface_have_in_addr(&iface->netmask)) { + if (inet_ntop(AF_INET, &iface->netmask, buf, + INET_ADDRSTRLEN) == NULL) { + free(ofile); + fclose(fp); + return 4; + } + + fprintf(fp, "NETMASK=%s\n", buf); + } + + if (iface_have_in_addr(&iface->broadcast)) { + if (inet_ntop(AF_INET, &iface->broadcast, buf, + INET_ADDRSTRLEN) == NULL) { + free(ofile); + fclose(fp); + return 5; + } + + fprintf(fp, "BROADCAST=%s\n", buf); + } + + if (iface_have_in_addr(&iface->gateway)) { + if (inet_ntop(AF_INET, &iface->gateway, buf, + INET_ADDRSTRLEN) == NULL) { + free(ofile); + fclose(fp); + return 6; + } + + fprintf(fp, "GATEWAY=%s\n", buf); + } + } + } #ifdef ENABLE_IPV6 - if (!FL_NOIPV6(flags)) { - if (iface->ipv6method == IPV6_AUTO_METHOD || - iface->ipv6method == IPV6_DHCP_METHOD || - iface->ipv6method == IPV6_MANUAL_METHOD) { - fprintf(fp, "IPV6INIT=yes\n"); - - if (iface->ipv6method == IPV6_AUTO_METHOD) { - fprintf(fp, "IPV6_AUTOCONF=yes\n"); - } else if (iface->ipv6method == IPV6_DHCP_METHOD) { - fprintf(fp, "DHCPV6C=yes\n"); - } else if (iface->ipv6method == IPV6_MANUAL_METHOD) { - if (iface_have_in6_addr(&iface->ip6addr)) { - if (inet_ntop(AF_INET6, &iface->ip6addr, buf, - INET6_ADDRSTRLEN) == NULL) { - free(ofile); - fclose(fp); - return 7; - } - - if (iface->ip6prefix) { - fprintf(fp, "IPV6ADDR=%s/%d\n", buf, iface->ip6prefix); - } else { - fprintf(fp, "IPV6ADDR=%s\n", buf); - } - } - } - - if (iface_have_in6_addr(&iface->gateway6)) { - if (inet_ntop(AF_INET6, &iface->gateway6, buf, - INET6_ADDRSTRLEN) == NULL) { - free(ofile); - fclose(fp); - return 8; - } - - fprintf(fp, "IPV6_DEFAULTGW=%s\n", buf); - } - } - } + if (!FL_NOIPV6(flags)) { + if (iface->ipv6method == IPV6_AUTO_METHOD || + iface->ipv6method == IPV6_DHCP_METHOD || + iface->ipv6method == IPV6_MANUAL_METHOD) { + fprintf(fp, "IPV6INIT=yes\n"); + + if (iface->ipv6method == IPV6_AUTO_METHOD) { + fprintf(fp, "IPV6_AUTOCONF=yes\n"); + } else if (iface->ipv6method == IPV6_DHCP_METHOD) { + fprintf(fp, "DHCPV6C=yes\n"); + } else if (iface->ipv6method == IPV6_MANUAL_METHOD) { + if (iface_have_in6_addr(&iface->ip6addr)) { + if (inet_ntop + (AF_INET6, &iface->ip6addr, buf, + INET6_ADDRSTRLEN) == NULL) { + free(ofile); + fclose(fp); + return 7; + } + + if (iface->ip6prefix) { + fprintf(fp, "IPV6ADDR=%s/%d\n", + buf, iface->ip6prefix); + } else { + fprintf(fp, "IPV6ADDR=%s\n", + buf); + } + } + } + + if (iface_have_in6_addr(&iface->gateway6)) { + if (inet_ntop(AF_INET6, &iface->gateway6, buf, + INET6_ADDRSTRLEN) == NULL) { + free(ofile); + fclose(fp); + return 8; + } + + fprintf(fp, "IPV6_DEFAULTGW=%s\n", buf); + } + } + } #endif - if (iface->numdns > 0) { - for (i = 0; i < iface->numdns; i++) { - fprintf(fp, "DNS%d=%s\n", i+1, iface->dns[i]); - } - } - - if (iface->hostname) { - fprintf(fp, "HOSTNAME=%s\n", iface->hostname); - } + if (iface->numdns > 0) { + for (i = 0; i < iface->numdns; i++) { + fprintf(fp, "DNS%d=%s\n", i + 1, iface->dns[i]); + } + } - if (iface->domain) { - fprintf(fp, "DOMAIN=%s\n", iface->domain); - } + if (iface->hostname) { + fprintf(fp, "HOSTNAME=%s\n", iface->hostname); + } - if (iface->mtu) { - fprintf(fp, "MTU=%d\n", iface->mtu); - } + if (iface->domain) { + fprintf(fp, "DOMAIN=%s\n", iface->domain); + } - if (iface->peerid) { - fprintf(fp, "PEERID=%s\n", iface->peerid); - } + if (iface->mtu) { + fprintf(fp, "MTU=%d\n", iface->mtu); + } - if (iface->subchannels) { - fprintf(fp, "SUBCHANNELS=%s\n", iface->subchannels); - } + if (iface->peerid) { + fprintf(fp, "PEERID=%s\n", iface->peerid); + } - if (iface->portname) { - fprintf(fp, "PORTNAME=%s\n", iface->portname); - } + if (iface->subchannels) { + fprintf(fp, "SUBCHANNELS=%s\n", iface->subchannels); + } - if (iface->nettype) { - fprintf(fp, "NETTYPE=%s\n", iface->nettype); - } + if (iface->portname) { + fprintf(fp, "PORTNAME=%s\n", iface->portname); + } - if (iface->ctcprot) { - fprintf(fp, "CTCPROT=%s\n", iface->ctcprot); - } + if (iface->nettype) { + fprintf(fp, "NETTYPE=%s\n", iface->nettype); + } - if (iface->layer2 && !strcmp(iface->layer2, "1")) { - osa_layer2 = 1; - } + if (iface->ctcprot) { + fprintf(fp, "CTCPROT=%s\n", iface->ctcprot); + } - if (iface->portno && !strcmp(iface->portno, "1")) { - osa_portno = 1; - } + if (iface->layer2 && !strcmp(iface->layer2, "1")) { + osa_layer2 = 1; + } - if (osa_layer2 || osa_portno) { - fprintf(fp, "OPTIONS=\""); + if (iface->portno && !strcmp(iface->portno, "1")) { + osa_portno = 1; + } - if (osa_layer2) { - fprintf(fp, "layer2=1"); - } + if (osa_layer2 || osa_portno) { + fprintf(fp, "OPTIONS=\""); - if (osa_layer2 && osa_portno) { - fprintf(fp, " "); - } + if (osa_layer2) { + fprintf(fp, "layer2=1"); + } - if (osa_portno) { - fprintf(fp, "portno=1"); - } + if (osa_layer2 && osa_portno) { + fprintf(fp, " "); + } - fprintf(fp, "\"\n"); - } + if (osa_portno) { + fprintf(fp, "portno=1"); + } - if (iface->macaddr) { - fprintf(fp, "MACADDR=%s\n", iface->macaddr); - } + fprintf(fp, "\"\n"); + } - if (fclose(fp) == EOF) { - free(ofile); - free(nfile); - return 8; - } + if (iface->macaddr) { + fprintf(fp, "MACADDR=%s\n", iface->macaddr); + } - if (rename(ofile, nfile) == -1) { - free(ofile); - free(nfile); - return 14; - } + if (fclose(fp) == EOF) { + free(ofile); + free(nfile); + return 8; + } - if (ofile) { - free(ofile); - } + if (rename(ofile, nfile) == -1) { + free(ofile); + free(nfile); + return 14; + } - if (nfile) { - free(nfile); - } + if (ofile) { + free(ofile); + } - /* Global settings */ - if ((fp = fopen(SYSCONFIG_PATH"/.network", "w")) == NULL) { - return 9; - } + if (nfile) { + free(nfile); + } - if (!FL_NOIPV4(flags)) { - fprintf(fp, "NETWORKING=yes\n"); - } + /* Global settings */ + if ((fp = fopen(SYSCONFIG_PATH "/.network", "w")) == NULL) { + return 9; + } + if (!FL_NOIPV4(flags)) { + fprintf(fp, "NETWORKING=yes\n"); + } #ifdef ENABLE_IPV6 - if (!FL_NOIPV6(flags)) { - fprintf(fp, "NETWORKING_IPV6=yes\n"); - } + if (!FL_NOIPV6(flags)) { + fprintf(fp, "NETWORKING_IPV6=yes\n"); + } #endif - if (iface->hostname != NULL) { - fprintf(fp, "HOSTNAME=%s\n", iface->hostname); - } - - if (iface_have_in_addr(&iface->gateway)) { - if (inet_ntop(AF_INET, &iface->gateway, buf, - INET_ADDRSTRLEN) == NULL) { - fclose(fp); - return 10; - } + if (iface->hostname != NULL) { + fprintf(fp, "HOSTNAME=%s\n", iface->hostname); + } - fprintf(fp, "GATEWAY=%s\n", buf); - } + if (iface_have_in_addr(&iface->gateway)) { + if (inet_ntop(AF_INET, &iface->gateway, buf, + INET_ADDRSTRLEN) == NULL) { + fclose(fp); + return 10; + } + fprintf(fp, "GATEWAY=%s\n", buf); + } #ifdef ENABLE_IPV6 - if (iface_have_in6_addr(&iface->gateway6)) { - if (inet_ntop(AF_INET6, &iface->gateway6, buf, - INET6_ADDRSTRLEN) == NULL) { - fclose(fp); - return 11; - } - - fprintf(fp, "IPV6_DEFAULTGW=%s\n", buf); - } + if (iface_have_in6_addr(&iface->gateway6)) { + if (inet_ntop(AF_INET6, &iface->gateway6, buf, + INET6_ADDRSTRLEN) == NULL) { + fclose(fp); + return 11; + } + + fprintf(fp, "IPV6_DEFAULTGW=%s\n", buf); + } #endif - if (fclose(fp) == EOF) { - return 12; - } + if (fclose(fp) == EOF) { + return 12; + } - if (rename(SYSCONFIG_PATH"/.network", - SYSCONFIG_PATH"/network") == -1) { - return 15; - } + if (rename(SYSCONFIG_PATH "/.network", SYSCONFIG_PATH "/network") == -1) { + return 15; + } - return 0; + return 0; } -void setKickstartNetwork(struct loaderData_s * loaderData, int argc, - char ** argv) { - iface_t iface; - gchar *bootProto = NULL, *device = NULL, *class = NULL, *ethtool = NULL; - gchar *essid = NULL, *wepkey = NULL, *onboot = NULL; - gint mtu = 1500, dhcpTimeout = -1; - gboolean noipv4 = FALSE, noipv6 = FALSE, noDns = FALSE, noksdev = FALSE; - GOptionContext *optCon = g_option_context_new(NULL); - GError *optErr = NULL; - GOptionEntry ksOptions[] = { - { "bootproto", 0, 0, G_OPTION_ARG_STRING, &bootProto, NULL, NULL }, - { "device", 0, 0, G_OPTION_ARG_STRING, &device, NULL, NULL }, - { "dhcpclass", 0, 0, G_OPTION_ARG_STRING, &class, NULL, NULL }, - { "gateway", 'g', 0, G_OPTION_ARG_STRING, &loaderData->gateway, - NULL, NULL }, - { "ip", 'i', 0, G_OPTION_ARG_STRING, &loaderData->ipv4, NULL, NULL }, - { "mtu", 0, 0, G_OPTION_ARG_INT, &mtu, NULL, NULL }, - { "nameserver", 'n', 0, G_OPTION_ARG_STRING, &loaderData->dns, - NULL, NULL }, - { "netmask", 'm', 0, G_OPTION_ARG_STRING, &loaderData->netmask, - NULL, NULL }, - { "noipv4", 0, 0, G_OPTION_ARG_NONE, &noipv4, NULL, NULL }, - { "noipv6", 0, 0, G_OPTION_ARG_NONE, &noipv6, NULL, NULL }, - { "nodns", 0, 0, G_OPTION_ARG_NONE, &noDns, NULL, NULL }, - { "hostname", 'h', 0, G_OPTION_ARG_STRING, &loaderData->hostname, - NULL, NULL }, - { "ethtool", 0, 0, G_OPTION_ARG_STRING, ðtool, NULL, NULL }, - { "essid", 0, 0, G_OPTION_ARG_STRING, &essid, NULL, NULL }, - { "wepkey", 0, 0, G_OPTION_ARG_STRING, &wepkey, NULL, NULL }, - { "onboot", 0, 0, G_OPTION_ARG_STRING, &onboot, NULL, NULL }, - { "notksdevice", 0, 0, G_OPTION_ARG_NONE, &noksdev, NULL, NULL }, - { "dhcptimeout", 0, 0, G_OPTION_ARG_INT, &dhcpTimeout, NULL, NULL }, - { NULL }, - }; - - iface_init_iface_t(&iface); - - g_option_context_set_help_enabled(optCon, FALSE); - g_option_context_add_main_entries(optCon, ksOptions, NULL); - - if (!g_option_context_parse(optCon, &argc, &argv, &optErr)) { - newtWinMessage(_("Kickstart Error"), _("OK"), - _("Bad argument to kickstart network command: %s"), - optErr->message); - g_error_free(optErr); - } - - g_option_context_free(optCon); - - /* if they've specified dhcp/bootp use dhcp for the interface */ - if (bootProto && (!strncmp(bootProto, "dhcp", 4) || - !strncmp(bootProto, "bootp", 4))) { - loaderData->ipv4 = strdup("dhcp"); - loaderData->ipinfo_set = 1; - } else if (loaderData->ipv4) { - /* JKFIXME: this assumes a bit... */ - loaderData->ipinfo_set = 1; - } - - /* now make sure the specified bootproto is valid */ - if (bootProto && strcmp(bootProto, "dhcp") && strcmp(bootProto, "bootp") && - strcmp(bootProto, "static") && strcmp(bootProto, "query")) { - newtWinMessage(_("Kickstart Error"), _("OK"), - _("Bad bootproto %s specified in network command"), - bootProto); - } - - if (!noksdev) { - if (device) { - /* If --device=MAC was given, translate into a device name now. */ - if (index(device, ':') != NULL) - loaderData->netDev = iface_mac2device(device); - else - loaderData->netDev = strdup(device); - - loaderData->netDev_set = 1; - } - - if (class) { - loaderData->netCls = strdup(class); - loaderData->netCls_set = 1; - } - - if (ethtool) { - if (loaderData->ethtool) - free(loaderData->ethtool); - loaderData->ethtool = strdup(ethtool); - free(ethtool); - } - - if (essid) { - if (loaderData->essid) - free(loaderData->essid); - loaderData->essid = strdup(essid); - free(essid); - } - - if (wepkey) { - if (loaderData->wepkey) - free(loaderData->wepkey); - loaderData->wepkey = strdup(wepkey); - free(wepkey); - } - - if (mtu) { - loaderData->mtu = mtu; - } - - if (noipv4) - flags |= LOADER_FLAGS_NOIPV4; +void setKickstartNetwork(struct loaderData_s *loaderData, int argc, char **argv) +{ + iface_t iface; + gchar *bootProto = NULL, *device = NULL, *class = NULL, *ethtool = NULL; + gchar *essid = NULL, *wepkey = NULL, *onboot = NULL; + gint mtu = 1500, dhcpTimeout = -1; + gboolean noipv4 = FALSE, noipv6 = FALSE, noDns = FALSE, noksdev = FALSE; + GOptionContext *optCon = g_option_context_new(NULL); + GError *optErr = NULL; + GOptionEntry ksOptions[] = { + {"bootproto", 0, 0, G_OPTION_ARG_STRING, &bootProto, NULL, + NULL}, + {"device", 0, 0, G_OPTION_ARG_STRING, &device, NULL, NULL}, + {"dhcpclass", 0, 0, G_OPTION_ARG_STRING, &class, NULL, NULL}, + {"gateway", 'g', 0, G_OPTION_ARG_STRING, &loaderData->gateway, + NULL, NULL}, + {"ip", 'i', 0, G_OPTION_ARG_STRING, &loaderData->ipv4, NULL, + NULL}, + {"mtu", 0, 0, G_OPTION_ARG_INT, &mtu, NULL, NULL}, + {"nameserver", 'n', 0, G_OPTION_ARG_STRING, &loaderData->dns, + NULL, NULL}, + {"netmask", 'm', 0, G_OPTION_ARG_STRING, &loaderData->netmask, + NULL, NULL}, + {"noipv4", 0, 0, G_OPTION_ARG_NONE, &noipv4, NULL, NULL}, + {"noipv6", 0, 0, G_OPTION_ARG_NONE, &noipv6, NULL, NULL}, + {"nodns", 0, 0, G_OPTION_ARG_NONE, &noDns, NULL, NULL}, + {"hostname", 'h', 0, G_OPTION_ARG_STRING, &loaderData->hostname, + NULL, NULL}, + {"ethtool", 0, 0, G_OPTION_ARG_STRING, ðtool, NULL, NULL}, + {"essid", 0, 0, G_OPTION_ARG_STRING, &essid, NULL, NULL}, + {"wepkey", 0, 0, G_OPTION_ARG_STRING, &wepkey, NULL, NULL}, + {"onboot", 0, 0, G_OPTION_ARG_STRING, &onboot, NULL, NULL}, + {"notksdevice", 0, 0, G_OPTION_ARG_NONE, &noksdev, NULL, NULL}, + {"dhcptimeout", 0, 0, G_OPTION_ARG_INT, &dhcpTimeout, NULL, + NULL}, + {NULL}, + }; + + iface_init_iface_t(&iface); + + g_option_context_set_help_enabled(optCon, FALSE); + g_option_context_add_main_entries(optCon, ksOptions, NULL); + + if (!g_option_context_parse(optCon, &argc, &argv, &optErr)) { + newtWinMessage(_("Kickstart Error"), _("OK"), + _ + ("Bad argument to kickstart network command: %s"), + optErr->message); + g_error_free(optErr); + } + + g_option_context_free(optCon); + + /* if they've specified dhcp/bootp use dhcp for the interface */ + if (bootProto && (!strncmp(bootProto, "dhcp", 4) || + !strncmp(bootProto, "bootp", 4))) { + loaderData->ipv4 = strdup("dhcp"); + loaderData->ipinfo_set = 1; + } else if (loaderData->ipv4) { + /* JKFIXME: this assumes a bit... */ + loaderData->ipinfo_set = 1; + } + + /* now make sure the specified bootproto is valid */ + if (bootProto && strcmp(bootProto, "dhcp") && strcmp(bootProto, "bootp") + && strcmp(bootProto, "static") && strcmp(bootProto, "query")) { + newtWinMessage(_("Kickstart Error"), _("OK"), + _ + ("Bad bootproto %s specified in network command"), + bootProto); + } + + if (!noksdev) { + if (device) { + /* If --device=MAC was given, translate into a device name now. */ + if (index(device, ':') != NULL) + loaderData->netDev = iface_mac2device(device); + else + loaderData->netDev = strdup(device); + + loaderData->netDev_set = 1; + } + + if (class) { + loaderData->netCls = strdup(class); + loaderData->netCls_set = 1; + } + + if (ethtool) { + if (loaderData->ethtool) + free(loaderData->ethtool); + loaderData->ethtool = strdup(ethtool); + free(ethtool); + } + + if (essid) { + if (loaderData->essid) + free(loaderData->essid); + loaderData->essid = strdup(essid); + free(essid); + } + + if (wepkey) { + if (loaderData->wepkey) + free(loaderData->wepkey); + loaderData->wepkey = strdup(wepkey); + free(wepkey); + } + + if (mtu) { + loaderData->mtu = mtu; + } + + if (noipv4) + flags |= LOADER_FLAGS_NOIPV4; #ifdef ENABLE_IPV6 - if (noipv6) - flags |= LOADER_FLAGS_NOIPV6; + if (noipv6) + flags |= LOADER_FLAGS_NOIPV6; #endif - } - - if (noDns) { - loaderData->noDns = 1; - } - - /* Make sure the network is always up if there's a network line in the - * kickstart file, as %post/%pre scripts might require that. - */ - if (loaderData->method != METHOD_NFS && loaderData->method != METHOD_URL) { - if (kickstartNetworkUp(loaderData, &iface)) - logMessage(ERROR, "unable to bring up network"); - } + } + + if (noDns) { + loaderData->noDns = 1; + } + + /* Make sure the network is always up if there's a network line in the + * kickstart file, as %post/%pre scripts might require that. + */ + if (loaderData->method != METHOD_NFS + && loaderData->method != METHOD_URL) { + if (kickstartNetworkUp(loaderData, &iface)) + logMessage(ERROR, "unable to bring up network"); + } } /* if multiple interfaces get one to use from user. */ /* NOTE - uses kickstart data available in loaderData */ -int chooseNetworkInterface(struct loaderData_s * loaderData) { - int i, rc, ask, idrc, secs, deviceNums = 0, deviceNum, foundDev = 0; - unsigned int max = 40; - char **devices; - char **deviceNames; - char *ksMacAddr = NULL, *seconds = strdup("10"), *idstr = NULL; - struct device **devs; - int lookForLink = 0; - struct newtWinEntry entry[] = {{N_("Seconds:"), (char **) &seconds, 0}, - {NULL, NULL, 0 }}; - - devs = getDevices(DEVICE_NETWORK); - if (!devs) { - logMessage(ERROR, "no network devices in choose network device!"); - return LOADER_ERROR; - } - - for (i = 0; devs[i]; i++); - - devices = alloca((i + 1) * sizeof(*devices)); - deviceNames = alloca((i + 1) * sizeof(*devices)); - if (loaderData->netDev && (loaderData->netDev_set) == 1) { - if ((loaderData->bootIf && (loaderData->bootIf_set) == 1) && - !strcasecmp(loaderData->netDev, "bootif")) { - ksMacAddr = strdup(loaderData->bootIf); - } else { - ksMacAddr = strdup(loaderData->netDev); - } - - ksMacAddr = str2upper(ksMacAddr); - } - - for (i = 0; devs[i]; i++) { - if (!devs[i]->device) - continue; - - if (devs[i]->description) { - deviceNames[deviceNums] = alloca(strlen(devs[i]->device) + - strlen(devs[i]->description) + 4); - sprintf(deviceNames[deviceNums],"%s - %.50s", - devs[i]->device, devs[i]->description); - - if (strlen(deviceNames[deviceNums]) > max) - max = strlen(deviceNames[deviceNums]); - - devices[deviceNums] = devs[i]->device; - } else { - devices[deviceNums] = devs[i]->device; - deviceNames[deviceNums] = devs[i]->device; - } - - deviceNums++; - - /* this device has been set and we don't really need to ask - * about it again... */ - if (loaderData->netDev && (loaderData->netDev_set == 1)) { - if (!strcmp(loaderData->netDev, devs[i]->device)) { - foundDev = 1; - } else if (ksMacAddr != NULL) { - /* maybe it's a mac address */ - char *devmacaddr = iface_mac2str(devs[i]->device); - - if ((devmacaddr != NULL) && !strcmp(ksMacAddr, devmacaddr)) { - foundDev = 1; - free(loaderData->netDev); - loaderData->netDev = devs[i]->device; - if (devmacaddr != NULL) - free(devmacaddr); - break; - } - - if (devmacaddr != NULL) - free(devmacaddr); - } - } - } - - if (ksMacAddr) - free(ksMacAddr); - if (foundDev == 1) - return LOADER_NOOP; - - devices[deviceNums] = NULL; - deviceNames[deviceNums] = NULL; - qsort(devices, deviceNums, sizeof(*devices), simpleStringCmp); - qsort(deviceNames, deviceNums, sizeof(*devices), simpleStringCmp); - - /* ASSERT: we should *ALWAYS* have a network device when we get here */ - if (!deviceNums) { - logMessage(CRITICAL, "no network device in chooseNetworkInterface"); - return LOADER_ERROR; - } - - /* JKFIXME: if we only have one interface and it doesn't have link, - * do we go ahead? */ - if (deviceNums == 1) { - logMessage(INFO, "only have one network device: %s", devices[0]); - loaderData->netDev = devices[0]; - return LOADER_NOOP; - } - - while ((loaderData->netDev && (loaderData->netDev_set == 1)) && - !strcmp(loaderData->netDev, "ibft")) { - char *devmacaddr = NULL; - char *ibftmacaddr = ""; - - /* get MAC from the iBFT table */ - if (!(ibftmacaddr = ibft_iface_mac())) { /* iBFT not present or error */ - lookForLink = 0; - break; - } - - logMessage(INFO, "looking for iBFT configured device %s with link", - ibftmacaddr); - lookForLink = 0; - - for (i = 0; devs[i]; i++) { - if (!devs[i]->device) - continue; - - devmacaddr = iface_mac2str(devs[i]->device); - - if(!strcasecmp(devmacaddr, ibftmacaddr)){ - logMessage(INFO, - "%s has the right MAC (%s), checking for link", - devmacaddr, devices[i]); - free(devmacaddr); - - if (get_link_status(devices[i]) == 1) { - lookForLink = 0; - loaderData->netDev = devices[i]; - logMessage(INFO, "%s has link, using it", devices[i]); - - /* set the IP method to ibft if not requested differently */ - if (loaderData->ipv4 == NULL) { - loaderData->ipv4 = strdup("ibft"); - logMessage(INFO, - "%s will be configured using iBFT values", - devices[i]); - } - - return LOADER_NOOP; - } else { - logMessage(INFO, "%s has no link, skipping it", devices[i]); - } - - break; - } else { - free(devmacaddr); - } - } - - break; - } - - if ((loaderData->netDev && (loaderData->netDev_set == 1)) && - !strcmp(loaderData->netDev, "link")) { - lookForLink = 1; - } - - if (lookForLink) { - logMessage(INFO, "looking for first netDev with link"); - - for (rc = 0; rc < 5; rc++) { - for (i = 0; i < deviceNums; i++) { - if (get_link_status(devices[i]) == 1) { - loaderData->netDev = devices[i]; - logMessage(INFO, "%s has link, using it", devices[i]); - return LOADER_NOOP; - } - } - - sleep(1); - } - - logMessage(WARNING, - "wanted netdev with link, but none present. prompting"); - } - - if (FL_CMDLINE(flags)) { - fprintf(stderr, "No way to determine which NIC to use, and cannot " - "prompt in cmdline\nmode. Halting.\n"); - fprintf(stderr, "Please use the ksdevice= parameter to specify the " - "device name (e.g., eth0)\n or the MAC address of " - "the NIC to use for installation.\n"); - exit(1); - } - - startNewt(); - - if (max > 70) - max = 70; - - /* JKFIXME: should display link status */ - deviceNum = 0; - ask = 1; - while (ask) { - rc = newtWinMenu(_("Networking Device"), - _("You have multiple network devices on this system. " - "Which would you like to install through?"), - max, 10, 10, - deviceNums < 6 ? deviceNums : 6, deviceNames, - &deviceNum, _("OK"), _("Identify"), _("Back"), NULL); - - if (rc == 2) { - if (!devices[deviceNum]) { - logMessage(ERROR, "NIC %d contains no device name", deviceNum); - continue; - } - - checked_asprintf(&idstr, "%s %s %s", - _("You can identify the physical port for"), - devices[deviceNum], - _("by flashing the LED lights for a number of " - "seconds. Enter a number between 1 and 30 to " - "set the duration to flash the LED port " - "lights.")); - - i = 1; - while (i) { - idrc = newtWinEntries(_("Identify NIC"), idstr, 50, 5, 15, 24, - entry, _("OK"), _("Back"), NULL); - - if (idrc == 0 || idrc == 1) { - errno = 0; - secs = strtol((const char *) seconds, NULL, 10); - if (errno == EINVAL || errno == ERANGE) { - logMessage(ERROR, "strtol() failure in %s: %m", - __func__); - continue; - } - - if (secs <=0 || secs > 300) { - newtWinMessage(_("Invalid Duration"), _("OK"), - _("You must enter the number of " - "seconds as an integer between 1 " - "and 30.")); - continue; - } - - idrc = 41 + strlen(devices[deviceNum]); - if (secs > 9) { - idrc += 1; - } - - winStatus(idrc, 3, NULL, - _("Flashing %s port lights for %d seconds."), - devices[deviceNum], secs); - - if (identifyNIC(devices[deviceNum], secs)) { - logMessage(ERROR, - "error during physical NIC identification"); - } - - newtPopWindow(); - i = 0; - } else if (idrc == 2) { - i = 0; - } - } - } else if (rc == 3) { - ask = 0; - return LOADER_BACK; - } else { - ask = 0; - } - } - - loaderData->netDev = devices[deviceNum]; - return LOADER_OK; +int chooseNetworkInterface(struct loaderData_s *loaderData) +{ + int i, rc, ask, idrc, secs, deviceNums = 0, deviceNum, foundDev = 0; + unsigned int max = 40; + char **devices; + char **deviceNames; + char *ksMacAddr = NULL, *seconds = strdup("10"), *idstr = NULL; + struct device **devs; + int lookForLink = 0; + struct newtWinEntry entry[] = { {N_("Seconds:"), (char **)&seconds, 0}, + {NULL, NULL, 0} + }; + + devs = getDevices(DEVICE_NETWORK); + if (!devs) { + logMessage(ERROR, + "no network devices in choose network device!"); + return LOADER_ERROR; + } + + for (i = 0; devs[i]; i++) ; + + devices = alloca((i + 1) * sizeof(*devices)); + deviceNames = alloca((i + 1) * sizeof(*devices)); + if (loaderData->netDev && (loaderData->netDev_set) == 1) { + if ((loaderData->bootIf && (loaderData->bootIf_set) == 1) && + !strcasecmp(loaderData->netDev, "bootif")) { + ksMacAddr = strdup(loaderData->bootIf); + } else { + ksMacAddr = strdup(loaderData->netDev); + } + + ksMacAddr = str2upper(ksMacAddr); + } + + for (i = 0; devs[i]; i++) { + if (!devs[i]->device) + continue; + + if (devs[i]->description) { + deviceNames[deviceNums] = + alloca(strlen(devs[i]->device) + + strlen(devs[i]->description) + 4); + sprintf(deviceNames[deviceNums], "%s - %.50s", + devs[i]->device, devs[i]->description); + + if (strlen(deviceNames[deviceNums]) > max) + max = strlen(deviceNames[deviceNums]); + + devices[deviceNums] = devs[i]->device; + } else { + devices[deviceNums] = devs[i]->device; + deviceNames[deviceNums] = devs[i]->device; + } + + deviceNums++; + + /* this device has been set and we don't really need to ask + * about it again... */ + if (loaderData->netDev && (loaderData->netDev_set == 1)) { + if (!strcmp(loaderData->netDev, devs[i]->device)) { + foundDev = 1; + } else if (ksMacAddr != NULL) { + /* maybe it's a mac address */ + char *devmacaddr = + iface_mac2str(devs[i]->device); + + if ((devmacaddr != NULL) + && !strcmp(ksMacAddr, devmacaddr)) { + foundDev = 1; + free(loaderData->netDev); + loaderData->netDev = devs[i]->device; + if (devmacaddr != NULL) + free(devmacaddr); + break; + } + + if (devmacaddr != NULL) + free(devmacaddr); + } + } + } + + if (ksMacAddr) + free(ksMacAddr); + if (foundDev == 1) + return LOADER_NOOP; + + devices[deviceNums] = NULL; + deviceNames[deviceNums] = NULL; + qsort(devices, deviceNums, sizeof(*devices), simpleStringCmp); + qsort(deviceNames, deviceNums, sizeof(*devices), simpleStringCmp); + + /* ASSERT: we should *ALWAYS* have a network device when we get here */ + if (!deviceNums) { + logMessage(CRITICAL, + "no network device in chooseNetworkInterface"); + return LOADER_ERROR; + } + + /* JKFIXME: if we only have one interface and it doesn't have link, + * do we go ahead? */ + if (deviceNums == 1) { + logMessage(INFO, "only have one network device: %s", + devices[0]); + loaderData->netDev = devices[0]; + return LOADER_NOOP; + } + + while ((loaderData->netDev && (loaderData->netDev_set == 1)) && + !strcmp(loaderData->netDev, "ibft")) { + char *devmacaddr = NULL; + char *ibftmacaddr = ""; + + /* get MAC from the iBFT table */ + if (!(ibftmacaddr = ibft_iface_mac())) { /* iBFT not present or error */ + lookForLink = 0; + break; + } + + logMessage(INFO, + "looking for iBFT configured device %s with link", + ibftmacaddr); + lookForLink = 0; + + for (i = 0; devs[i]; i++) { + if (!devs[i]->device) + continue; + + devmacaddr = iface_mac2str(devs[i]->device); + + if (!strcasecmp(devmacaddr, ibftmacaddr)) { + logMessage(INFO, + "%s has the right MAC (%s), checking for link", + devmacaddr, devices[i]); + free(devmacaddr); + + if (get_link_status(devices[i]) == 1) { + lookForLink = 0; + loaderData->netDev = devices[i]; + logMessage(INFO, + "%s has link, using it", + devices[i]); + + /* set the IP method to ibft if not requested differently */ + if (loaderData->ipv4 == NULL) { + loaderData->ipv4 = + strdup("ibft"); + logMessage(INFO, + "%s will be configured using iBFT values", + devices[i]); + } + + return LOADER_NOOP; + } else { + logMessage(INFO, + "%s has no link, skipping it", + devices[i]); + } + + break; + } else { + free(devmacaddr); + } + } + + break; + } + + if ((loaderData->netDev && (loaderData->netDev_set == 1)) && + !strcmp(loaderData->netDev, "link")) { + lookForLink = 1; + } + + if (lookForLink) { + logMessage(INFO, "looking for first netDev with link"); + + for (rc = 0; rc < 5; rc++) { + for (i = 0; i < deviceNums; i++) { + if (get_link_status(devices[i]) == 1) { + loaderData->netDev = devices[i]; + logMessage(INFO, + "%s has link, using it", + devices[i]); + return LOADER_NOOP; + } + } + + sleep(1); + } + + logMessage(WARNING, + "wanted netdev with link, but none present. prompting"); + } + + if (FL_CMDLINE(flags)) { + fprintf(stderr, + "No way to determine which NIC to use, and cannot " + "prompt in cmdline\nmode. Halting.\n"); + fprintf(stderr, + "Please use the ksdevice= parameter to specify the " + "device name (e.g., eth0)\n or the MAC address of " + "the NIC to use for installation.\n"); + exit(1); + } + + startNewt(); + + if (max > 70) + max = 70; + + /* JKFIXME: should display link status */ + deviceNum = 0; + ask = 1; + while (ask) { + rc = newtWinMenu(_("Networking Device"), + _ + ("You have multiple network devices on this system. " + "Which would you like to install through?"), + max, 10, 10, deviceNums < 6 ? deviceNums : 6, + deviceNames, &deviceNum, _("OK"), + _("Identify"), _("Back"), NULL); + + if (rc == 2) { + if (!devices[deviceNum]) { + logMessage(ERROR, + "NIC %d contains no device name", + deviceNum); + continue; + } + + checked_asprintf(&idstr, "%s %s %s", + _ + ("You can identify the physical port for"), + devices[deviceNum], + _ + ("by flashing the LED lights for a number of " + "seconds. Enter a number between 1 and 30 to " + "set the duration to flash the LED port " + "lights.")); + + i = 1; + while (i) { + idrc = + newtWinEntries(_("Identify NIC"), idstr, 50, + 5, 15, 24, entry, _("OK"), + _("Back"), NULL); + + if (idrc == 0 || idrc == 1) { + errno = 0; + secs = + strtol((const char *)seconds, NULL, + 10); + if (errno == EINVAL || errno == ERANGE) { + logMessage(ERROR, + "strtol() failure in %s: %m", + __func__); + continue; + } + + if (secs <= 0 || secs > 300) { + newtWinMessage(_ + ("Invalid Duration"), + _("OK"), + _ + ("You must enter the number of " + "seconds as an integer between 1 " + "and 30.")); + continue; + } + + idrc = 41 + strlen(devices[deviceNum]); + if (secs > 9) { + idrc += 1; + } + + winStatus(idrc, 3, NULL, + _ + ("Flashing %s port lights for %d seconds."), + devices[deviceNum], secs); + + if (identifyNIC + (devices[deviceNum], secs)) { + logMessage(ERROR, + "error during physical NIC identification"); + } + + newtPopWindow(); + i = 0; + } else if (idrc == 2) { + i = 0; + } + } + } else if (rc == 3) { + ask = 0; + return LOADER_BACK; + } else { + ask = 0; + } + } + + loaderData->netDev = devices[deviceNum]; + return LOADER_OK; } /* JKFIXME: bad name. this function brings up networking early on a * kickstart install so that we can do things like grab the ks.cfg from * the network */ -int kickstartNetworkUp(struct loaderData_s * loaderData, iface_t * iface) { - int rc, err; - - if (is_nm_connected() == TRUE) - return 0; - - memset(iface, 0, sizeof(*iface)); - - do { - do { - /* this is smart and does the right thing based on whether or not - * we have ksdevice= specified */ - rc = chooseNetworkInterface(loaderData); - - if (rc == LOADER_ERROR) { - /* JKFIXME: ask for a driver disk? */ - logMessage(ERROR, "no network drivers for doing kickstart"); - return -1; - } else if (rc == LOADER_BACK) { - return -1; - } - - /* insert device into iface structure */ - strcpy(iface->device, loaderData->netDev); - - break; - } while (1); - - /* we don't want to end up asking about interface more than once - * if we're in a kickstart-ish case (#100724) */ - loaderData->netDev_set = 1; - - /* default to DHCP for IPv4 if nothing is provided */ - if (loaderData->ipv4 == NULL) { - loaderData->ipv4 = strdup("dhcp"); - loaderData->ipinfo_set = 1; - } - - setupIfaceStruct(iface, loaderData); - rc = readNetConfig(loaderData->netDev, iface, loaderData->netCls, - loaderData->method); - - if (rc == LOADER_ERROR) { - logMessage(ERROR, "unable to setup networking"); - return -1; - } else if (rc == LOADER_BACK) { - /* Going back to the interface selection screen, so unset anything - * we set before attempting to bring the incorrect interface up. - */ - if ((rc = writeDisabledNetInfo()) != 0) { - logMessage(ERROR, "writeDisabledNetInfo failure (%s): %d", - __func__, rc); - } - - loaderData->netDev_set = 0; - loaderData->ipinfo_set = 0; - free(loaderData->ipv4); - loaderData->ipv4 = NULL; - break; - } else { - break; - } - - err = writeEnabledNetInfo(iface); - if (err) { - logMessage(ERROR, - "failed to write %s data for %s (%d)", - SYSCONFIG_PATH, iface->device, err); - return -1; - } - - err = get_connection(iface); - newtPopWindow(); - - if (err) { - logMessage(ERROR, "failed to start NetworkManager (%d)", err); - return -1; - } - } while (1); - - return 0; +int kickstartNetworkUp(struct loaderData_s *loaderData, iface_t * iface) +{ + int rc, err; + + if (is_nm_connected() == TRUE) + return 0; + + memset(iface, 0, sizeof(*iface)); + + do { + do { + /* this is smart and does the right thing based on whether or not + * we have ksdevice= specified */ + rc = chooseNetworkInterface(loaderData); + + if (rc == LOADER_ERROR) { + /* JKFIXME: ask for a driver disk? */ + logMessage(ERROR, + "no network drivers for doing kickstart"); + return -1; + } else if (rc == LOADER_BACK) { + return -1; + } + + /* insert device into iface structure */ + strcpy(iface->device, loaderData->netDev); + + break; + } while (1); + + /* we don't want to end up asking about interface more than once + * if we're in a kickstart-ish case (#100724) */ + loaderData->netDev_set = 1; + + /* default to DHCP for IPv4 if nothing is provided */ + if (loaderData->ipv4 == NULL) { + loaderData->ipv4 = strdup("dhcp"); + loaderData->ipinfo_set = 1; + } + + setupIfaceStruct(iface, loaderData); + rc = readNetConfig(loaderData->netDev, iface, + loaderData->netCls, loaderData->method); + + if (rc == LOADER_ERROR) { + logMessage(ERROR, "unable to setup networking"); + return -1; + } else if (rc == LOADER_BACK) { + /* Going back to the interface selection screen, so unset anything + * we set before attempting to bring the incorrect interface up. + */ + if ((rc = writeDisabledNetInfo()) != 0) { + logMessage(ERROR, + "writeDisabledNetInfo failure (%s): %d", + __func__, rc); + } + + loaderData->netDev_set = 0; + loaderData->ipinfo_set = 0; + free(loaderData->ipv4); + loaderData->ipv4 = NULL; + break; + } else { + break; + } + + err = writeEnabledNetInfo(iface); + if (err) { + logMessage(ERROR, + "failed to write %s data for %s (%d)", + SYSCONFIG_PATH, iface->device, err); + return -1; + } + + err = get_connection(iface); + newtPopWindow(); + + if (err) { + logMessage(ERROR, "failed to start NetworkManager (%d)", + err); + return -1; + } + } while (1); + + return 0; } -void splitHostname (char *str, char **host, char **port) +void splitHostname(char *str, char **host, char **port) { - char *rightbrack = strchr(str, ']'); - - *host = NULL; - *port = NULL; - - if (*str == '[' && rightbrack) { - /* An IPv6 address surrounded by brackets, optionally with a colon and - * port number. - */ - char *colon = strrchr(rightbrack, ':'); - - if (colon) { - *host = strndup(str+1, rightbrack-1-str); - *port = strdup(colon+1); - } - else - *host = strndup(str+1, rightbrack-1-str); - } else if (strcount(str, ':') > 1) { - /* An IPv6 address without brackets. Don't make the user surround the - * address with brackets if there's no port number. - */ - *host = strdup(str); - } else { - /* An IPv4 address, optionally with a colon and port number. */ - char *colon = strrchr(str, ':'); - - if (colon) { - *host = strndup(str, colon-str); - *port = strdup(colon+1); - } - else - *host = strdup(str); - } + char *rightbrack = strchr(str, ']'); + + *host = NULL; + *port = NULL; + + if (*str == '[' && rightbrack) { + /* An IPv6 address surrounded by brackets, optionally with a colon and + * port number. + */ + char *colon = strrchr(rightbrack, ':'); + + if (colon) { + *host = strndup(str + 1, rightbrack - 1 - str); + *port = strdup(colon + 1); + } else + *host = strndup(str + 1, rightbrack - 1 - str); + } else if (strcount(str, ':') > 1) { + /* An IPv6 address without brackets. Don't make the user surround the + * address with brackets if there's no port number. + */ + *host = strdup(str); + } else { + /* An IPv4 address, optionally with a colon and port number. */ + char *colon = strrchr(str, ':'); + + if (colon) { + *host = strndup(str, colon - str); + *port = strdup(colon + 1); + } else + *host = strdup(str); + } } /* * Start NetworkManager and wait for a valid link, return non-zero on error. */ -int get_connection(iface_t *iface) { - int count = 0; - NMClient *client = NULL; - NMState state; - GMainLoop *loop; - GMainContext *ctx; - - if (iface == NULL) { - return 1; - } - - logMessage(DEBUGLVL, "configuring device %s", iface->device); - - /* display status */ - if (FL_CMDLINE(flags)) { - printf(_("Waiting for NetworkManager to configure %s.\n"), - iface->device); - } else { - winStatus(55, 3, NULL, - _("Waiting for NetworkManager to configure %s.\n"), - iface->device, 0); - } - - g_type_init(); - - client = nm_client_new(); - if (!client) { - logMessage(ERROR, "%s (%d): could not connect to system bus", - __func__, __LINE__); - return 2; - } - - /* Create a loop for processing dbus signals */ - loop = g_main_loop_new(NULL, FALSE); - ctx = g_main_loop_get_context(loop); - - /* pump the loop until all the messages are clear */ - while (g_main_context_pending (ctx)) { - g_main_context_iteration (ctx, FALSE); - } - - /* send message and block until a reply or error comes back */ - while (count < 45) { - /* pump the loop again to clear the messages */ - while (g_main_context_pending (ctx)) { - g_main_context_iteration (ctx, FALSE); - } - state = nm_client_get_state(client); - - if (state == NM_STATE_CONNECTED) { - logMessage(INFO, "%s (%d): NetworkManager connected", - __func__, __LINE__); - res_init(); - g_object_unref(client); - return 0; - } - - sleep(1); - count++; - } - - g_main_loop_unref(loop); - g_object_unref(client); - return 3; +int get_connection(iface_t * iface) +{ + int count = 0; + NMClient *client = NULL; + NMState state; + GMainLoop *loop; + GMainContext *ctx; + + if (iface == NULL) { + return 1; + } + + logMessage(DEBUGLVL, "configuring device %s", iface->device); + + /* display status */ + if (FL_CMDLINE(flags)) { + printf(_("Waiting for NetworkManager to configure %s.\n"), + iface->device); + } else { + winStatus(55, 3, NULL, + _("Waiting for NetworkManager to configure %s.\n"), + iface->device, 0); + } + + g_type_init(); + + client = nm_client_new(); + if (!client) { + logMessage(ERROR, "%s (%d): could not connect to system bus", + __func__, __LINE__); + return 2; + } + + /* Create a loop for processing dbus signals */ + loop = g_main_loop_new(NULL, FALSE); + ctx = g_main_loop_get_context(loop); + + /* pump the loop until all the messages are clear */ + while (g_main_context_pending(ctx)) { + g_main_context_iteration(ctx, FALSE); + } + + /* send message and block until a reply or error comes back */ + while (count < 45) { + /* pump the loop again to clear the messages */ + while (g_main_context_pending(ctx)) { + g_main_context_iteration(ctx, FALSE); + } + state = nm_client_get_state(client); + + if (state == NM_STATE_CONNECTED) { + logMessage(INFO, "%s (%d): NetworkManager connected", + __func__, __LINE__); + res_init(); + g_object_unref(client); + return 0; + } + + sleep(1); + count++; + } + + g_main_loop_unref(loop); + g_object_unref(client); + return 3; } /* vim:set sw=8 noet */ diff --git a/loader/net.h b/loader/net.h index f6659bf..afec10c 100644 --- a/loader/net.h +++ b/loader/net.h @@ -35,43 +35,42 @@ #define NETWORK_SCRIPTS_PATH "/etc/sysconfig/network-scripts" struct intfconfig_s { - newtComponent ipv4Entry, cidr4Entry; - newtComponent gwEntry, nsEntry; - const char *ipv4, *cidr4; + newtComponent ipv4Entry, cidr4Entry; + newtComponent gwEntry, nsEntry; + const char *ipv4, *cidr4; #ifdef ENABLE_IPV6 - newtComponent ipv6Entry, cidr6Entry; - const char *ipv6, *cidr6; - const char *gw6; + newtComponent ipv6Entry, cidr6Entry; + const char *ipv6, *cidr6; + const char *gw6; #endif - const char *gw, *ns; + const char *gw, *ns; }; struct netconfopts { - char ipv4Choice; + char ipv4Choice; #ifdef ENABLE_IPV6 - char ipv6Choice; + char ipv6Choice; #endif }; typedef int int32; -int readNetConfig(char * device, iface_t * iface, - char * dhcpclass, int methodNum); -int configureTCPIP(char * device, iface_t * iface, struct netconfopts * opts, - int methodNum); -int manualNetConfig(char * device, iface_t * iface, - struct intfconfig_s * ipcomps, struct netconfopts * opts); +int readNetConfig(char *device, iface_t * iface, + char *dhcpclass, int methodNum); +int configureTCPIP(char *device, iface_t * iface, struct netconfopts *opts, + int methodNum); +int manualNetConfig(char *device, iface_t * iface, + struct intfconfig_s *ipcomps, struct netconfopts *opts); void debugNetworkInfo(iface_t * iface); int writeDisabledNetInfo(void); int writeEnabledNetInfo(iface_t * iface); -int chooseNetworkInterface(struct loaderData_s * loaderData); -void setupIfaceStruct(iface_t * iface, struct loaderData_s * loaderData); +int chooseNetworkInterface(struct loaderData_s *loaderData); +void setupIfaceStruct(iface_t * iface, struct loaderData_s *loaderData); int setupWireless(iface_t * iface); -void setKickstartNetwork(struct loaderData_s * loaderData, int argc, - char ** argv); -int kickstartNetworkUp(struct loaderData_s * loaderData, - iface_t * iface); -void splitHostname (char *str, char **host, char **port); +void setKickstartNetwork(struct loaderData_s *loaderData, int argc, + char **argv); +int kickstartNetworkUp(struct loaderData_s *loaderData, iface_t * iface); +void splitHostname(char *str, char **host, char **port); int get_connection(iface_t * iface); #endif diff --git a/loader/nfsinstall.c b/loader/nfsinstall.c index ac25878..453549d 100644 --- a/loader/nfsinstall.c +++ b/loader/nfsinstall.c @@ -57,500 +57,579 @@ /* boot flags */ extern uint64_t flags; -static int nfsGetSetup(char ** hostptr, char ** dirptr, char ** optsptr) { - struct newtWinEntry entries[4]; - char * buf; - char * newServer = *hostptr ? strdup(*hostptr) : NULL; - char * newDir = *dirptr ? strdup(*dirptr) : NULL; - char * newMountOpts = *optsptr ? strdup(*optsptr) : NULL; - int rc; - - entries[0].text = _("NFS server name:"); - entries[0].value = &newServer; - entries[0].flags = NEWT_FLAG_SCROLL; - - checked_asprintf(&entries[1].text, _("%s directory:"), getProductName()); - - entries[1].value = &newDir; - entries[1].flags = NEWT_FLAG_SCROLL; - entries[2].text = _("NFS mount options (optional):"); - entries[2].value = &newMountOpts; - entries[2].flags = NEWT_FLAG_SCROLL; - entries[3].text = NULL; - entries[3].value = NULL; - - if (asprintf(&buf, _("Please enter the server and path to your %s " - "installation image and optionally additional " - "NFS mount options."), getProductName()) == -1) { - logMessage(CRITICAL, "%s: %d: %m", __func__, __LINE__); - abort(); - } - - do { - rc = newtWinEntries(_("NFS Setup"), buf, 60, 5, 15, - 24, entries, _("OK"), _("Back"), NULL); - } while ((!strcmp(newServer, "") || !strcmp(newDir, "")) && rc != 2); - - free(buf); - free(entries[1].text); - - if (rc == 2) { - if (newServer) free(newServer); - if (newDir) free(newDir); - if (newMountOpts) free(newMountOpts); - return LOADER_BACK; - } - - if (*hostptr) free(*hostptr); - if (*dirptr) free(*dirptr); - if (*optsptr) free(*optsptr); - *hostptr = newServer; - *dirptr = newDir; - *optsptr = newMountOpts; - - return 0; +static int nfsGetSetup(char **hostptr, char **dirptr, char **optsptr) +{ + struct newtWinEntry entries[4]; + char *buf; + char *newServer = *hostptr ? strdup(*hostptr) : NULL; + char *newDir = *dirptr ? strdup(*dirptr) : NULL; + char *newMountOpts = *optsptr ? strdup(*optsptr) : NULL; + int rc; + + entries[0].text = _("NFS server name:"); + entries[0].value = &newServer; + entries[0].flags = NEWT_FLAG_SCROLL; + + checked_asprintf(&entries[1].text, _("%s directory:"), + getProductName()); + + entries[1].value = &newDir; + entries[1].flags = NEWT_FLAG_SCROLL; + entries[2].text = _("NFS mount options (optional):"); + entries[2].value = &newMountOpts; + entries[2].flags = NEWT_FLAG_SCROLL; + entries[3].text = NULL; + entries[3].value = NULL; + + if (asprintf(&buf, _("Please enter the server and path to your %s " + "installation image and optionally additional " + "NFS mount options."), getProductName()) == -1) { + logMessage(CRITICAL, "%s: %d: %m", __func__, __LINE__); + abort(); + } + + do { + rc = newtWinEntries(_("NFS Setup"), buf, 60, 5, 15, + 24, entries, _("OK"), _("Back"), NULL); + } while ((!strcmp(newServer, "") || !strcmp(newDir, "")) && rc != 2); + + free(buf); + free(entries[1].text); + + if (rc == 2) { + if (newServer) + free(newServer); + if (newDir) + free(newDir); + if (newMountOpts) + free(newMountOpts); + return LOADER_BACK; + } + + if (*hostptr) + free(*hostptr); + if (*dirptr) + free(*dirptr); + if (*optsptr) + free(*optsptr); + *hostptr = newServer; + *dirptr = newDir; + *optsptr = newMountOpts; + + return 0; } -void parseNfsHostPathOpts(char *url, char **host, char **path, char **opts) { - char *tmp; - char *hostsrc; - - logMessage(DEBUGLVL, "parseNfsHostPathOpts url: |%s|", url); - - hostsrc = strdup(url); - *host = hostsrc; - tmp = strchr(*host, ':'); - - if (tmp) { - *path = strdup(tmp + 1); - *tmp = '\0'; - } - else { - *path = malloc(sizeof(char *)); - **path = '\0'; - } - - tmp = strchr(*path, ':'); - if (tmp && (strlen(tmp) > 1)) { - char * c = tmp; - *opts = *host; - *host = *path; - *path = strdup(c + 1); - *c = '\0'; - } else { - *opts = NULL; - } - - logMessage(DEBUGLVL, "parseNfsHostPathOpts host: |%s|", *host); - logMessage(DEBUGLVL, "parseNfsHostPathOpts path: |%s|", *path); - logMessage(DEBUGLVL, "parseNfsHostPathOpts opts: |%s|", *opts); +void parseNfsHostPathOpts(char *url, char **host, char **path, char **opts) +{ + char *tmp; + char *hostsrc; + + logMessage(DEBUGLVL, "parseNfsHostPathOpts url: |%s|", url); + + hostsrc = strdup(url); + *host = hostsrc; + tmp = strchr(*host, ':'); + + if (tmp) { + *path = strdup(tmp + 1); + *tmp = '\0'; + } else { + *path = malloc(sizeof(char *)); + **path = '\0'; + } + + tmp = strchr(*path, ':'); + if (tmp && (strlen(tmp) > 1)) { + char *c = tmp; + *opts = *host; + *host = *path; + *path = strdup(c + 1); + *c = '\0'; + } else { + *opts = NULL; + } + + logMessage(DEBUGLVL, "parseNfsHostPathOpts host: |%s|", *host); + logMessage(DEBUGLVL, "parseNfsHostPathOpts path: |%s|", *path); + logMessage(DEBUGLVL, "parseNfsHostPathOpts opts: |%s|", *opts); } -static void addDefaultKickstartFile(char **file, char *ip) { - /* if the filename ends with / or is null, use default kickstart - * name of IP_ADDRESS-kickstart appended to *file - */ - if ((*file) && (((*file)[strlen(*file) - 1] == '/') || - ((*file)[strlen(*file) - 1] == '\0'))) { - checked_asprintf(file, "%s%s-kickstart", *file, ip); - logMessage(DEBUGLVL, "addDefaultKickstartFile file: |%s|", *file); - } +static void addDefaultKickstartFile(char **file, char *ip) +{ + /* if the filename ends with / or is null, use default kickstart + * name of IP_ADDRESS-kickstart appended to *file + */ + if ((*file) && (((*file)[strlen(*file) - 1] == '/') || + ((*file)[strlen(*file) - 1] == '\0'))) { + checked_asprintf(file, "%s%s-kickstart", *file, ip); + logMessage(DEBUGLVL, "addDefaultKickstartFile file: |%s|", + *file); + } } -char * mountNfsImage(struct installMethod * method, - char * location, struct loaderData_s * loaderData) { - char * host = NULL; - char * directory = NULL; - char * mountOpts = NULL; - char * fullPath = NULL; - char * url = NULL; - - enum { NFS_STAGE_NFS, NFS_STAGE_MOUNT, NFS_STAGE_DONE, - NFS_STAGE_UPDATES } stage = NFS_STAGE_NFS; - - int rc; - - /* JKFIXME: ASSERT -- we have a network device setup when we get here */ - while (stage != NFS_STAGE_DONE) { - switch (stage) { - case NFS_STAGE_NFS: - if (loaderData->method == METHOD_NFS && loaderData->stage2Data) { - host = ((struct nfsInstallData *)loaderData->stage2Data)->host; - directory = ((struct nfsInstallData *)loaderData->stage2Data)->directory; - - if (((struct nfsInstallData *) - loaderData->stage2Data)->mountOpts == NULL) { - mountOpts = strdup("ro"); - } else { - checked_asprintf(&mountOpts, "ro,%s", - ((struct nfsInstallData *) - loaderData->stage2Data)->mountOpts); - } - - logMessage(INFO, "host is %s, dir is %s, opts are '%s'", host, directory, mountOpts); - - if (!host || !directory) { - logMessage(ERROR, "missing host or directory specification"); - - if (loaderData->inferredStage2) - loaderData->invalidRepoParam = 1; - - loaderData->method = -1; - break; - } else { - host = strdup(host); - directory = strdup(directory); - } - } else { - char *colonopts, *substr, *tmp; - - logMessage(INFO, "going to do nfsGetSetup"); - if (nfsGetSetup(&host, &directory, &mountOpts) == LOADER_BACK) { - loaderData->stage2Data = NULL; - return NULL; - } - - /* If the user-provided URL points at a repo instead of a - * stage2 image, fix that up now. - */ - substr = strstr(directory, ".img"); - if (!substr || (substr && *(substr+4) != '\0')) { - if (mountOpts && strlen(mountOpts)) { - checked_asprintf(&colonopts, ":%s", mountOpts); - } else { - colonopts = strdup(""); - } - - checked_asprintf(&(loaderData->instRepo), "nfs%s:%s:%s", - colonopts, host, directory); - checked_asprintf(&tmp, "nfs%s:%s:%s/images/install.img", - colonopts, host, directory); - - setStage2LocFromCmdline(tmp, loaderData); - free(host); - free(directory); - free(mountOpts); - free(colonopts); - free(tmp); - continue; - } - - loaderData->invalidRepoParam = 1; - } - - stage = NFS_STAGE_MOUNT; - break; - - case NFS_STAGE_MOUNT: { - char *buf; - - checked_asprintf(&fullPath, "%s:%.*s", host, - (int) (strrchr(directory, '/')-directory), - directory); - logMessage(INFO, "mounting nfs path %s", fullPath); - - stage = NFS_STAGE_NFS; - - if (!doPwMount(fullPath, "/mnt/stage2", "nfs", mountOpts, NULL)) { - checked_asprintf(&buf, "/mnt/stage2/%s", - strrchr(directory, '/')); - - if (!access(buf, R_OK)) { - logMessage(INFO, "can access %s", buf); - rc = mountStage2(buf); - - if (rc == 0) { - stage = NFS_STAGE_UPDATES; - checked_asprintf(&url, "nfs:%s:%s", host, - directory); - free(buf); - break; - } else { - logMessage(WARNING, "unable to mount %s", buf); - free(buf); - break; - } - } else { - logMessage(WARNING, "unable to access %s", buf); - free(buf); - umount("/mnt/stage2"); - } - } else { - newtWinMessage(_("Error"), _("OK"), - _("That directory could not be mounted from " - "the server.")); - if (loaderData->method >= 0) - loaderData->method = -1; - - if (loaderData->inferredStage2) - loaderData->invalidRepoParam = 1; - - break; - } - - checked_asprintf(&buf, - _("That directory does not seem to " - "contain a %s installation image."), - getProductName()); - - newtWinMessage(_("Error"), _("OK"), buf); - free(buf); - - if (loaderData->method >= 0) - loaderData->method = -1; - - if (loaderData->inferredStage2) - loaderData->invalidRepoParam = 1; - - break; - } - - case NFS_STAGE_UPDATES: { - char *buf; - - checked_asprintf(&buf, "%.*s/RHupdates", - (int) (strrchr(fullPath, '/')-fullPath), - fullPath); - - logMessage(INFO, "mounting nfs path %s for updates", buf); - - if (!doPwMount(buf, "/tmp/update-disk", "nfs", mountOpts, NULL)) { - logMessage(INFO, "Using RHupdates/ for NFS install"); - copyDirectory("/tmp/update-disk", "/tmp/updates", NULL, NULL); - umount("/tmp/update-disk"); - unlink("/tmp/update-disk"); - } else { - logMessage(INFO, "No RHupdates/ directory found, skipping"); - } - - stage = NFS_STAGE_DONE; - break; - } - - case NFS_STAGE_DONE: - break; - } - } - - free(host); - free(directory); - if (mountOpts) - free(mountOpts); - if (fullPath) - free(fullPath); - - return url; +char *mountNfsImage(struct installMethod *method, + char *location, struct loaderData_s *loaderData) +{ + char *host = NULL; + char *directory = NULL; + char *mountOpts = NULL; + char *fullPath = NULL; + char *url = NULL; + + enum { NFS_STAGE_NFS, NFS_STAGE_MOUNT, NFS_STAGE_DONE, + NFS_STAGE_UPDATES + } stage = NFS_STAGE_NFS; + + int rc; + + /* JKFIXME: ASSERT -- we have a network device setup when we get here */ + while (stage != NFS_STAGE_DONE) { + switch (stage) { + case NFS_STAGE_NFS: + if (loaderData->method == METHOD_NFS + && loaderData->stage2Data) { + host = + ((struct nfsInstallData *) + loaderData->stage2Data)->host; + directory = + ((struct nfsInstallData *) + loaderData->stage2Data)->directory; + + if (((struct nfsInstallData *) + loaderData->stage2Data)->mountOpts == NULL) { + mountOpts = strdup("ro"); + } else { + checked_asprintf(&mountOpts, "ro,%s", + ((struct nfsInstallData + *) + loaderData->stage2Data)->mountOpts); + } + + logMessage(INFO, + "host is %s, dir is %s, opts are '%s'", + host, directory, mountOpts); + + if (!host || !directory) { + logMessage(ERROR, + "missing host or directory specification"); + + if (loaderData->inferredStage2) + loaderData->invalidRepoParam = + 1; + + loaderData->method = -1; + break; + } else { + host = strdup(host); + directory = strdup(directory); + } + } else { + char *colonopts, *substr, *tmp; + + logMessage(INFO, "going to do nfsGetSetup"); + if (nfsGetSetup(&host, &directory, &mountOpts) + == LOADER_BACK) { + loaderData->stage2Data = NULL; + return NULL; + } + + /* If the user-provided URL points at a repo instead of a + * stage2 image, fix that up now. + */ + substr = strstr(directory, ".img"); + if (!substr + || (substr && *(substr + 4) != '\0')) { + if (mountOpts && strlen(mountOpts)) { + checked_asprintf(&colonopts, + ":%s", + mountOpts); + } else { + colonopts = strdup(""); + } + + checked_asprintf(& + (loaderData->instRepo), + "nfs%s:%s:%s", + colonopts, host, + directory); + checked_asprintf(&tmp, + "nfs%s:%s:%s/images/install.img", + colonopts, host, + directory); + + setStage2LocFromCmdline(tmp, + loaderData); + free(host); + free(directory); + free(mountOpts); + free(colonopts); + free(tmp); + continue; + } + + loaderData->invalidRepoParam = 1; + } + + stage = NFS_STAGE_MOUNT; + break; + + case NFS_STAGE_MOUNT:{ + char *buf; + + checked_asprintf(&fullPath, "%s:%.*s", host, + (int)(strrchr(directory, '/') - + directory), directory); + logMessage(INFO, "mounting nfs path %s", + fullPath); + + stage = NFS_STAGE_NFS; + + if (!doPwMount + (fullPath, "/mnt/stage2", "nfs", mountOpts, + NULL)) { + checked_asprintf(&buf, "/mnt/stage2/%s", + strrchr(directory, + '/')); + + if (!access(buf, R_OK)) { + logMessage(INFO, + "can access %s", + buf); + rc = mountStage2(buf); + + if (rc == 0) { + stage = + NFS_STAGE_UPDATES; + checked_asprintf(&url, + "nfs:%s:%s", + host, + directory); + free(buf); + break; + } else { + logMessage(WARNING, + "unable to mount %s", + buf); + free(buf); + break; + } + } else { + logMessage(WARNING, + "unable to access %s", + buf); + free(buf); + umount("/mnt/stage2"); + } + } else { + newtWinMessage(_("Error"), _("OK"), + _ + ("That directory could not be mounted from " + "the server.")); + if (loaderData->method >= 0) + loaderData->method = -1; + + if (loaderData->inferredStage2) + loaderData->invalidRepoParam = + 1; + + break; + } + + checked_asprintf(&buf, + _ + ("That directory does not seem to " + "contain a %s installation image."), + getProductName()); + + newtWinMessage(_("Error"), _("OK"), buf); + free(buf); + + if (loaderData->method >= 0) + loaderData->method = -1; + + if (loaderData->inferredStage2) + loaderData->invalidRepoParam = 1; + + break; + } + + case NFS_STAGE_UPDATES:{ + char *buf; + + checked_asprintf(&buf, "%.*s/RHupdates", + (int)(strrchr(fullPath, '/') - + fullPath), fullPath); + + logMessage(INFO, + "mounting nfs path %s for updates", + buf); + + if (!doPwMount + (buf, "/tmp/update-disk", "nfs", mountOpts, + NULL)) { + logMessage(INFO, + "Using RHupdates/ for NFS install"); + copyDirectory("/tmp/update-disk", + "/tmp/updates", NULL, + NULL); + umount("/tmp/update-disk"); + unlink("/tmp/update-disk"); + } else { + logMessage(INFO, + "No RHupdates/ directory found, skipping"); + } + + stage = NFS_STAGE_DONE; + break; + } + + case NFS_STAGE_DONE: + break; + } + } + + free(host); + free(directory); + if (mountOpts) + free(mountOpts); + if (fullPath) + free(fullPath); + + return url; } - -void setKickstartNfs(struct loaderData_s * loaderData, int argc, - char ** argv) { - char *substr = NULL; - gchar *host = NULL, *dir = NULL, *mountOpts = NULL; - GOptionContext *optCon = g_option_context_new(NULL); - GError *optErr = NULL; - GOptionEntry ksNfsOptions[] = { - { "server", 0, 0, G_OPTION_ARG_STRING, &host, NULL, NULL }, - { "dir", 0, 0, G_OPTION_ARG_STRING, &dir, NULL, NULL }, - { "opts", 0, 0, G_OPTION_ARG_STRING, &mountOpts, NULL, NULL }, - { NULL }, - }; - - logMessage(INFO, "kickstartFromNfs"); - - g_option_context_set_help_enabled(optCon, FALSE); - g_option_context_add_main_entries(optCon, ksNfsOptions, NULL); - - if (!g_option_context_parse(optCon, &argc, &argv, &optErr)) { - startNewt(); - newtWinMessage(_("Kickstart Error"), _("OK"), - _("Bad argument to NFS kickstart method " - "command: %s"), optErr->message); - g_error_free(optErr); - g_option_context_free(optCon); - return; - } - - g_option_context_free(optCon); - - if (!host || !dir) { - logMessage(ERROR, "host and directory for nfs kickstart not specified"); - return; - } - - loaderData->method = METHOD_NFS; - loaderData->stage2Data = NULL; - - substr = strstr(dir, ".img"); - if (!substr || (substr && *(substr+4) != '\0')) { - checked_asprintf(&(loaderData->instRepo), "nfs:%s:%s", host, dir); - - logMessage(INFO, "results of nfs, host is %s, dir is %s, opts are '%s'", - host, dir, mountOpts); - } else { - loaderData->stage2Data = calloc(sizeof(struct nfsInstallData *), 1); - ((struct nfsInstallData *)loaderData->stage2Data)->host = host; - ((struct nfsInstallData *)loaderData->stage2Data)->directory = dir; - ((struct nfsInstallData *)loaderData->stage2Data)->mountOpts = mountOpts; - - logMessage(INFO, "results of nfs, host is %s, dir is %s, opts are '%s'", - ((struct nfsInstallData *) loaderData->stage2Data)->host, - ((struct nfsInstallData *) loaderData->stage2Data)->directory, - ((struct nfsInstallData *) loaderData->stage2Data)->mountOpts); - } +void setKickstartNfs(struct loaderData_s *loaderData, int argc, char **argv) +{ + char *substr = NULL; + gchar *host = NULL, *dir = NULL, *mountOpts = NULL; + GOptionContext *optCon = g_option_context_new(NULL); + GError *optErr = NULL; + GOptionEntry ksNfsOptions[] = { + {"server", 0, 0, G_OPTION_ARG_STRING, &host, NULL, NULL}, + {"dir", 0, 0, G_OPTION_ARG_STRING, &dir, NULL, NULL}, + {"opts", 0, 0, G_OPTION_ARG_STRING, &mountOpts, NULL, NULL}, + {NULL}, + }; + + logMessage(INFO, "kickstartFromNfs"); + + g_option_context_set_help_enabled(optCon, FALSE); + g_option_context_add_main_entries(optCon, ksNfsOptions, NULL); + + if (!g_option_context_parse(optCon, &argc, &argv, &optErr)) { + startNewt(); + newtWinMessage(_("Kickstart Error"), _("OK"), + _("Bad argument to NFS kickstart method " + "command: %s"), optErr->message); + g_error_free(optErr); + g_option_context_free(optCon); + return; + } + + g_option_context_free(optCon); + + if (!host || !dir) { + logMessage(ERROR, + "host and directory for nfs kickstart not specified"); + return; + } + + loaderData->method = METHOD_NFS; + loaderData->stage2Data = NULL; + + substr = strstr(dir, ".img"); + if (!substr || (substr && *(substr + 4) != '\0')) { + checked_asprintf(&(loaderData->instRepo), "nfs:%s:%s", host, + dir); + + logMessage(INFO, + "results of nfs, host is %s, dir is %s, opts are '%s'", + host, dir, mountOpts); + } else { + loaderData->stage2Data = + calloc(sizeof(struct nfsInstallData *), 1); + ((struct nfsInstallData *)loaderData->stage2Data)->host = host; + ((struct nfsInstallData *)loaderData->stage2Data)->directory = + dir; + ((struct nfsInstallData *)loaderData->stage2Data)->mountOpts = + mountOpts; + + logMessage(INFO, + "results of nfs, host is %s, dir is %s, opts are '%s'", + ((struct nfsInstallData *)loaderData-> + stage2Data)->host, + ((struct nfsInstallData *)loaderData-> + stage2Data)->directory, + ((struct nfsInstallData *)loaderData-> + stage2Data)->mountOpts); + } } - -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, i = 0; - iface_t iface; - NMClient *client = NULL; - NMState state; - const GPtrArray *devices; - - 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 - */ - if (!url) { - g_type_init(); - - client = nm_client_new(); - if (!client) { - logMessage(CRITICAL, "%s (%d): failure creating NM proxy", - __func__, __LINE__); - return 1; - } - - state = nm_client_get_state(client); - if (state != NM_STATE_CONNECTED) { - logMessage(ERROR, "%s (%d): no active network devices", - __func__, __LINE__); - g_object_unref(client); - return 1; - } - - devices = nm_client_get_devices(client); - for (i = 0; i < devices->len; i++) { - NMDevice *candidate = g_ptr_array_index(devices, i); - const char *devname = nm_device_get_iface(candidate); - NMDHCP4Config *dhcp = NULL; - const char *server_name = NULL; - const char *filename = NULL; - struct in_addr addr; - char nextserver[INET_ADDRSTRLEN+1]; - - if (nm_device_get_state(candidate) != NM_DEVICE_STATE_ACTIVATED) - continue; - - if (strcmp(iface.device, devname)) - continue; - - dhcp = nm_device_get_dhcp4_config(candidate); - if (!dhcp) { - logMessage(ERROR, "no boot options received by DHCP"); - continue; - } - - server_name = nm_dhcp4_config_get_one_option(dhcp, "server_name"); - if (!server_name) { - logMessage(ERROR, "no bootserver was found"); - g_object_unref(client); - return 1; - } - - /* 'server_name' may be a hostname or an IPv4 address */ - memset(&nextserver, '\0', sizeof(nextserver)); - if (inet_pton(AF_INET, server_name, &addr) >= 1) { - strcpy(nextserver, server_name); - } else { - struct hostent *he = gethostbyname(server_name); - if (he != NULL) { - if (inet_ntop(AF_INET, he->h_addr_list[0], - nextserver, INET_ADDRSTRLEN) == NULL) { - memset(&nextserver, '\0', sizeof(nextserver)); - } - } - } - - filename = nm_dhcp4_config_get_one_option(dhcp, "filename"); - if (filename == NULL) { - checked_asprintf(&url, "%s:/kickstart/", nextserver); - logMessage(ERROR, "bootp: no bootfile received"); - } else { - checked_asprintf(&url, "%s:%s", nextserver, filename); - logMessage(INFO, "bootp: bootfile is %s", filename); - } - - break; - } - - g_object_unref(client); - } - - /* get the IP of the target system */ - if ((ip = iface_ip2str(loaderData->netDev, AF_INET)) == NULL) { - logMessage(ERROR, "iface_ip2str returned NULL"); - return 1; - } - - logMessage(INFO, "url is %s", url); - - parseNfsHostPathOpts(url, &host, &path, &opts); - addDefaultKickstartFile(&path, ip); - - /* 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 == '/') { - checked_asprintf(&host, "%s:%s", host, path); - } else { - checked_asprintf(&host, "%s:/%s", host, path); - } - } - - logMessage(INFO, "file location: nfs:%s/%s", host, file); - - if (!doPwMount(host, "/tmp/mnt", "nfs", opts, NULL)) { - char * buf; - - checked_asprintf(&buf, "/tmp/mnt/%s", file); - - 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; +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, i = 0; + iface_t iface; + NMClient *client = NULL; + NMState state; + const GPtrArray *devices; + + 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 + */ + if (!url) { + g_type_init(); + + client = nm_client_new(); + if (!client) { + logMessage(CRITICAL, + "%s (%d): failure creating NM proxy", + __func__, __LINE__); + return 1; + } + + state = nm_client_get_state(client); + if (state != NM_STATE_CONNECTED) { + logMessage(ERROR, "%s (%d): no active network devices", + __func__, __LINE__); + g_object_unref(client); + return 1; + } + + devices = nm_client_get_devices(client); + for (i = 0; i < devices->len; i++) { + NMDevice *candidate = g_ptr_array_index(devices, i); + const char *devname = nm_device_get_iface(candidate); + NMDHCP4Config *dhcp = NULL; + const char *server_name = NULL; + const char *filename = NULL; + struct in_addr addr; + char nextserver[INET_ADDRSTRLEN + 1]; + + if (nm_device_get_state(candidate) != + NM_DEVICE_STATE_ACTIVATED) + continue; + + if (strcmp(iface.device, devname)) + continue; + + dhcp = nm_device_get_dhcp4_config(candidate); + if (!dhcp) { + logMessage(ERROR, + "no boot options received by DHCP"); + continue; + } + + server_name = + nm_dhcp4_config_get_one_option(dhcp, "server_name"); + if (!server_name) { + logMessage(ERROR, "no bootserver was found"); + g_object_unref(client); + return 1; + } + + /* 'server_name' may be a hostname or an IPv4 address */ + memset(&nextserver, '\0', sizeof(nextserver)); + if (inet_pton(AF_INET, server_name, &addr) >= 1) { + strcpy(nextserver, server_name); + } else { + struct hostent *he = gethostbyname(server_name); + if (he != NULL) { + if (inet_ntop + (AF_INET, he->h_addr_list[0], + nextserver, + INET_ADDRSTRLEN) == NULL) { + memset(&nextserver, '\0', + sizeof(nextserver)); + } + } + } + + filename = + nm_dhcp4_config_get_one_option(dhcp, "filename"); + if (filename == NULL) { + checked_asprintf(&url, "%s:/kickstart/", + nextserver); + logMessage(ERROR, + "bootp: no bootfile received"); + } else { + checked_asprintf(&url, "%s:%s", nextserver, + filename); + logMessage(INFO, "bootp: bootfile is %s", + filename); + } + + break; + } + + g_object_unref(client); + } + + /* get the IP of the target system */ + if ((ip = iface_ip2str(loaderData->netDev, AF_INET)) == NULL) { + logMessage(ERROR, "iface_ip2str returned NULL"); + return 1; + } + + logMessage(INFO, "url is %s", url); + + parseNfsHostPathOpts(url, &host, &path, &opts); + addDefaultKickstartFile(&path, ip); + + /* 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 == '/') { + checked_asprintf(&host, "%s:%s", host, path); + } else { + checked_asprintf(&host, "%s:/%s", host, path); + } + } + + logMessage(INFO, "file location: nfs:%s/%s", host, file); + + if (!doPwMount(host, "/tmp/mnt", "nfs", opts, NULL)) { + char *buf; + + checked_asprintf(&buf, "/tmp/mnt/%s", file); + + 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; } -int kickstartFromNfs(char * url, struct loaderData_s * loaderData) { - return getFileFromNfs(url, "/tmp/ks.cfg", loaderData); +int kickstartFromNfs(char *url, struct loaderData_s *loaderData) +{ + return getFileFromNfs(url, "/tmp/ks.cfg", loaderData); } /* vim:set sw=8 noet */ diff --git a/loader/nfsinstall.h b/loader/nfsinstall.h index 1517cc3..76a755d 100644 --- a/loader/nfsinstall.h +++ b/loader/nfsinstall.h @@ -23,19 +23,17 @@ #include "method.h" struct nfsInstallData { - char * host; - char * directory; - char * mountOpts; + char *host; + char *directory; + char *mountOpts; }; - -void setKickstartNfs(struct loaderData_s * loaderData, int argc, - char ** argv); -int kickstartFromNfs(char * url, struct loaderData_s * loaderData); -char * mountNfsImage(struct installMethod * method, - char * location, struct loaderData_s * loaderData); -int getFileFromNfs(char * url, char * dest, struct loaderData_s * loaderData); -void parseNfsHostPathOpts(char * url, char ** host, char ** path, char ** opts); +void setKickstartNfs(struct loaderData_s *loaderData, int argc, char **argv); +int kickstartFromNfs(char *url, struct loaderData_s *loaderData); +char *mountNfsImage(struct installMethod *method, + char *location, struct loaderData_s *loaderData); +int getFileFromNfs(char *url, char *dest, struct loaderData_s *loaderData); +void parseNfsHostPathOpts(char *url, char **host, char **path, char **opts); #endif diff --git a/loader/selinux.c b/loader/selinux.c index 45fab1d..8f1f532 100644 --- a/loader/selinux.c +++ b/loader/selinux.c @@ -34,25 +34,24 @@ #include "loadermisc.h" #include "log.h" -int loadpolicy() { - int pid, status; +int loadpolicy() +{ + int pid, status; - logMessage(INFO, "Loading SELinux policy"); + logMessage(INFO, "Loading SELinux policy"); - if (!(pid = fork())) { - setenv("LD_LIBRARY_PATH", LIBPATH, 1); - execl("/sbin/load_policy", - "/sbin/load_policy", "-q", NULL); - logMessage(ERROR, "exec of load_policy failed: %m"); - exit(1); - } + if (!(pid = fork())) { + setenv("LD_LIBRARY_PATH", LIBPATH, 1); + execl("/sbin/load_policy", "/sbin/load_policy", "-q", NULL); + logMessage(ERROR, "exec of load_policy failed: %m"); + exit(1); + } - waitpid(pid, &status, 0); - if (WIFEXITED(status) && (WEXITSTATUS(status) != 0)) - return 1; + waitpid(pid, &status, 0); + if (WIFEXITED(status) && (WEXITSTATUS(status) != 0)) + return 1; - return 0; + return 0; } - /* vim:set sw=8 noet */ diff --git a/loader/shutdown.c b/loader/shutdown.c index 3ade4c2..137f8ae 100644 --- a/loader/shutdown.c +++ b/loader/shutdown.c @@ -35,7 +35,8 @@ void disableSwap(void); void unmountFilesystems(void); -static void performTerminations(int doKill) { +static void performTerminations(int doKill) +{ if (!doKill) return; @@ -51,7 +52,8 @@ static void performTerminations(int doKill) { printf("done\n"); } -static void performUnmounts(int doKill) { +static void performUnmounts(int doKill) +{ int ignore; if (!doKill) @@ -60,18 +62,19 @@ static void performUnmounts(int doKill) { printf("disabling swap...\n"); disableSwap(); - printf("unmounting filesystems...\n"); + printf("unmounting filesystems...\n"); unmountFilesystems(); - printf("waiting for mdraid sets to become clean...\n"); + printf("waiting for mdraid sets to become clean...\n"); ignore = system("/sbin/mdadm --wait-clean --scan"); } -static void performReboot(reboot_action rebootAction) { +static void performReboot(reboot_action rebootAction) +{ if (rebootAction == POWEROFF) { - printf("powering off system\n"); + printf("powering off system\n"); sleep(2); - reboot(RB_POWER_OFF); + reboot(RB_POWER_OFF); } else if (rebootAction == REBOOT) { printf("rebooting system\n"); sleep(2); @@ -86,11 +89,13 @@ static void performReboot(reboot_action rebootAction) { int shouldReboot = 0; -static void rebootHandler(int signum) { - shouldReboot = 1; +static void rebootHandler(int signum) +{ + shouldReboot = 1; } -void shutDown(int doKill, reboot_action rebootAction) { +void shutDown(int doKill, reboot_action rebootAction) +{ if (rebootAction == POWEROFF || rebootAction == REBOOT) { performUnmounts(doKill); performTerminations(doKill); @@ -100,8 +105,8 @@ void shutDown(int doKill, reboot_action rebootAction) { if (!shouldReboot && rebootAction != REBOOT) printf("you may safely reboot your system\n"); - - signal(SIGINT, rebootHandler); + + signal(SIGINT, rebootHandler); while (1) { if (shouldReboot) { performUnmounts(1); @@ -111,44 +116,45 @@ void shutDown(int doKill, reboot_action rebootAction) { sleep(1); } - exit(0); + exit(0); - return; + return; } #ifdef AS_SHUTDOWN -int main(int argc, char ** argv) { - int fd; - reboot_action rebootAction = HALT; - int doKill = 1; - int i = 1; - - while (i < argc) { - if (!strncmp("-r", argv[i], 2)) - rebootAction = REBOOT; - else if (!strncmp("--nokill", argv[i], 8)) - doKill = 0; - else if (!strncmp("-P", argv[i], 2)) - rebootAction = POWEROFF; - i++; - } - - /* ignore some signals so we don't kill ourself */ - signal(SIGINT, SIG_IGN); - signal(SIGTSTP, SIG_IGN); - - /* now change to / */ - i = chdir("/"); - - /* redirect output to the real console */ - fd = open("/dev/console", O_RDWR); - dup2(fd, 0); - dup2(fd, 1); - dup2(fd, 2); - close(fd); - - shutDown(doKill, rebootAction); - return 0; +int main(int argc, char **argv) +{ + int fd; + reboot_action rebootAction = HALT; + int doKill = 1; + int i = 1; + + while (i < argc) { + if (!strncmp("-r", argv[i], 2)) + rebootAction = REBOOT; + else if (!strncmp("--nokill", argv[i], 8)) + doKill = 0; + else if (!strncmp("-P", argv[i], 2)) + rebootAction = POWEROFF; + i++; + } + + /* ignore some signals so we don't kill ourself */ + signal(SIGINT, SIG_IGN); + signal(SIGTSTP, SIG_IGN); + + /* now change to / */ + i = chdir("/"); + + /* redirect output to the real console */ + fd = open("/dev/console", O_RDWR); + dup2(fd, 0); + dup2(fd, 1); + dup2(fd, 2); + close(fd); + + shutDown(doKill, rebootAction); + return 0; } #endif diff --git a/loader/telnet.c b/loader/telnet.c index 888ff14..8639e0a 100644 --- a/loader/telnet.c +++ b/loader/telnet.c @@ -56,189 +56,195 @@ * too. */ void -telnet_negotiate(int socket, char ** term_type_ptr, int * heightPtr, - int * widthPtr) { - char ch; - int done = 0; - char * termType = NULL; - int termLength = 0, termAlloced = 0; - enum { ST_NONE, ST_TERMTYPE, ST_WINDOWSIZE } state; - char sizeBuf[4]; - int height = -1, width = -1; - char * sizePtr = sizeBuf; - char request[]= - IAC DONT ECHO - IAC WILL ECHO - IAC WILL NAWS - IAC WILL SUPPRESS_GO_AHEAD - IAC DO SUPPRESS_GO_AHEAD - IAC DONT NEWENVIRON - IAC WONT NEWENVIRON - IAC WONT LINEMODE - IAC DO NAWS - IAC SB TERMINAL_TYPE "\x01" IAC SE - ; - int ret; - - ret = write(socket, request, sizeof(request)-1); - - /* Read from the terminal until we get the terminal type. This will - do bad things if the client doesn't send the terminal type, but - those clients have existed for aeons (right?) */ - - do { - ret = read(socket, &ch, 1); - if (ch != '\xff') { - abort(); - } - - ret = read(socket, &ch, 1); /* command */ - - if (ch != '\xfa') { - ret = read(socket, &ch, 1); /* verb */ - continue; - } +telnet_negotiate(int socket, char **term_type_ptr, int *heightPtr, + int *widthPtr) +{ + char ch; + int done = 0; + char *termType = NULL; + int termLength = 0, termAlloced = 0; + enum { ST_NONE, ST_TERMTYPE, ST_WINDOWSIZE } state; + char sizeBuf[4]; + int height = -1, width = -1; + char *sizePtr = sizeBuf; + char request[] = + IAC DONT ECHO + IAC WILL ECHO + IAC WILL NAWS + IAC WILL SUPPRESS_GO_AHEAD + IAC DO SUPPRESS_GO_AHEAD + IAC DONT NEWENVIRON + IAC WONT NEWENVIRON + IAC WONT LINEMODE IAC DO NAWS IAC SB TERMINAL_TYPE "\x01" IAC SE; + int ret; + + ret = write(socket, request, sizeof(request) - 1); + + /* Read from the terminal until we get the terminal type. This will + do bad things if the client doesn't send the terminal type, but + those clients have existed for aeons (right?) */ + + do { + ret = read(socket, &ch, 1); + if (ch != '\xff') { + abort(); + } - ret = read(socket, &ch, 1); /* suboption */ - if (ch == '\x18') { - state = ST_TERMTYPE; - ret = read(socket, &ch, 1); /* should be 0x0! */ - done = 1; - } else if (ch == '\x1f') { - state = ST_WINDOWSIZE; - } else { - state = ST_NONE;; - } + ret = read(socket, &ch, 1); /* command */ - ret = read(socket, &ch, 1); /* data */ - while (ch != '\xff') { - if (state == ST_TERMTYPE) { - if (termAlloced == termLength) { - termAlloced += 10; - termType = realloc(termType, termAlloced + 1); + if (ch != '\xfa') { + ret = read(socket, &ch, 1); /* verb */ + continue; } - termType[termLength++] = tolower(ch); - } else if (state == ST_WINDOWSIZE) { - if ((sizePtr - sizeBuf) < (int)sizeof(sizeBuf)) - *sizePtr++ = ch; - } + ret = read(socket, &ch, 1); /* suboption */ + if (ch == '\x18') { + state = ST_TERMTYPE; + ret = read(socket, &ch, 1); /* should be 0x0! */ + done = 1; + } else if (ch == '\x1f') { + state = ST_WINDOWSIZE; + } else { + state = ST_NONE;; + } - ret = read(socket, &ch, 1); /* data */ - } + ret = read(socket, &ch, 1); /* data */ + while (ch != '\xff') { + if (state == ST_TERMTYPE) { + if (termAlloced == termLength) { + termAlloced += 10; + termType = + realloc(termType, termAlloced + 1); + } + + termType[termLength++] = tolower(ch); + } else if (state == ST_WINDOWSIZE) { + if ((sizePtr - sizeBuf) < (int)sizeof(sizeBuf)) + *sizePtr++ = ch; + } + + ret = read(socket, &ch, 1); /* data */ + } - ret = read(socket, &ch, 1); /* should be a SE */ + ret = read(socket, &ch, 1); /* should be a SE */ - } while (!done); + } while (!done); - termType[termLength] = '\0'; + termType[termLength] = '\0'; - if (sizePtr - sizeBuf == sizeof(sizeBuf)) { - width = (sizeBuf[0] << 8) + sizeBuf[1]; - height = (sizeBuf[2] << 8) + sizeBuf[3]; - } + if (sizePtr - sizeBuf == sizeof(sizeBuf)) { + width = (sizeBuf[0] << 8) + sizeBuf[1]; + height = (sizeBuf[2] << 8) + sizeBuf[3]; + } - if (heightPtr) *heightPtr = height; - if (widthPtr) *widthPtr = width; + if (heightPtr) + *heightPtr = height; + if (widthPtr) + *widthPtr = width; - if (term_type_ptr) *term_type_ptr = termType; + if (term_type_ptr) + *term_type_ptr = termType; } -int -telnet_process_input(telnet_state * ts, char *data, int len) { - char *s, *d; /* source, destination */ +int telnet_process_input(telnet_state * ts, char *data, int len) +{ + char *s, *d; /* source, destination */ # if DEBUG_TELNET - printf("\nprinting packet:"); - for (s=data; s<data+len; s++) { - if (!((s-data)%10)) - printf("\n %03d: ", s-data); - printf("%02x ", *s & 0x000000FF); - } - printf("\n"); + printf("\nprinting packet:"); + for (s = data; s < data + len; s++) { + if (!((s - data) % 10)) + printf("\n %03d: ", s - data); + printf("%02x ", *s & 0x000000FF); + } + printf("\n"); # endif /* DEBUG_TELNET */ - for (s=data, d=data; s<data+len; s++) { - switch (*ts) { - case TS_DATA: - if (*s == '\xff') { /* IAC */ - *ts = TS_IAC; - continue; - } + for (s = data, d = data; s < data + len; s++) { + switch (*ts) { + case TS_DATA: + if (*s == '\xff') { /* IAC */ + *ts = TS_IAC; + continue; + } #if DEBUG_TELNET - printf("copying data element '%c'\n", *s); -#endif /* DEBUG_TELNET */ - if (s>d) { - *(d++) = *s; - } else { - d++; - } - break; - - case TS_IAC: - if (*s == '\xfa') { /* SB */ - *ts = TS_SB; - continue; - } - /* if not SB, skip IAC verb object */ + printf("copying data element '%c'\n", *s); +#endif /* DEBUG_TELNET */ + if (s > d) { + *(d++) = *s; + } else { + d++; + } + break; + + case TS_IAC: + if (*s == '\xfa') { /* SB */ + *ts = TS_SB; + continue; + } + /* if not SB, skip IAC verb object */ # if DEBUG_TELNET - printf("skipping verb/object (offset %d)...\n", s-data-1); + printf("skipping verb/object (offset %d)...\n", + s - data - 1); # endif /* DEBUG_TELNET */ - s += 1; - *ts = TS_DATA; - break; + s += 1; + *ts = TS_DATA; + break; - case TS_SB: + case TS_SB: # if DEBUG_TELNET - printf("skipping SB (offset %d)...\n", s-data-1); + printf("skipping SB (offset %d)...\n", s - data - 1); # endif /* DEBUG_TELNET */ - while (s < (data+(len-1))) { - if (*s == '\xff') { - break; /* fall through to TS_SB_IAC setting below */ - } else { - s++; - } - } - if (*s == '\xff') { - *ts = TS_SB_IAC; - } - break; - - case TS_SB_IAC: - if (*s == '\xf0') { /* SE */ + while (s < (data + (len - 1))) { + if (*s == '\xff') { + break; /* fall through to TS_SB_IAC setting below */ + } else { + s++; + } + } + if (*s == '\xff') { + *ts = TS_SB_IAC; + } + break; + + case TS_SB_IAC: + if (*s == '\xf0') { /* SE */ # if DEBUG_TELNET - printf("SE ends SB (offset %d)...\n", s-data-1); + printf("SE ends SB (offset %d)...\n", + s - data - 1); # endif /* DEBUG_TELNET */ - *ts = TS_DATA; - } else { + *ts = TS_DATA; + } else { # if DEBUG_TELNET - printf("IAC without SE in SB (offset %d)\n", s-data-1); + printf("IAC without SE in SB (offset %d)\n", + s - data - 1); # endif /* DEBUG_TELNET */ - *ts = TS_SB; - } - break; - - default: - logMessage(WARNING, "unknown telnet state %d for data element %c", - *ts, *s); - *ts = TS_DATA; - break; + *ts = TS_SB; + } + break; + + default: + logMessage(WARNING, + "unknown telnet state %d for data element %c", + *ts, *s); + *ts = TS_DATA; + break; + } } - } - /* calculate new length after copying data around */ - len = d - data; + /* calculate new length after copying data around */ + len = d - data; #if DEBUG_TELNET - printf("returning len: %d of packet:", len); - for (s=data; s<data+len; s++) { - if (!((s-data)%10)) - printf("\n %03d: ", s-data); - printf("%02x ", *s & 0x000000FF); - } - printf("\n"); + printf("returning len: %d of packet:", len); + for (s = data; s < data + len; s++) { + if (!((s - data) % 10)) + printf("\n %03d: ", s - data); + printf("%02x ", *s & 0x000000FF); + } + printf("\n"); #endif /* DEBUG_TELNET */ - return len; + return len; } /* The telnet protocol requires CR/NL instead of just NL @@ -250,26 +256,26 @@ telnet_process_input(telnet_state * ts, char *data, int len) { * Therefore, instead, we create a modified copy of the data and write * the whole modified copy at once. */ -void -telnet_send_output(int sock, char *data, int len) { - char *s, *d; /* source, destination */ - char *buf; - int ret; - - buf = alloca((len*2)+1); /* max necessary size */ - - /* just may need to add CR before NL (but do not double existing CRs) */ - for (s=data, d=buf; d-buf<len; s++, d++) { - if ((*s == '\n') && (s == data || (*(s-1) != '\r'))) { - /* NL without preceding CR */ - *(d++) = '\r'; - len++; +void telnet_send_output(int sock, char *data, int len) +{ + char *s, *d; /* source, destination */ + char *buf; + int ret; + + buf = alloca((len * 2) + 1); /* max necessary size */ + + /* just may need to add CR before NL (but do not double existing CRs) */ + for (s = data, d = buf; d - buf < len; s++, d++) { + if ((*s == '\n') && (s == data || (*(s - 1) != '\r'))) { + /* NL without preceding CR */ + *(d++) = '\r'; + len++; + } + *d = *s; } - *d = *s; - } - /* now send it... */ - ret = write(sock, buf, len); + /* now send it... */ + ret = write(sock, buf, len); } /* vim:set sw=8 noet */ diff --git a/loader/telnet.h b/loader/telnet.h index f9e3c03..a7162ee 100644 --- a/loader/telnet.h +++ b/loader/telnet.h @@ -30,12 +30,10 @@ typedef enum { } telnet_state; void -telnet_negotiate(int socket, char ** term_type_ptr, int * heightPtr, - int * widthPtr); -int -telnet_process_input(telnet_state * ts, char *data, int len); -void -telnet_send_output(int sock, char *data, int len); +telnet_negotiate(int socket, char **term_type_ptr, int *heightPtr, + int *widthPtr); +int telnet_process_input(telnet_state * ts, char *data, int len); +void telnet_send_output(int sock, char *data, int len); #endif /* __TELNET_H__ */ diff --git a/loader/telnetd.c b/loader/telnetd.c index 7497901..504663e 100644 --- a/loader/telnetd.c +++ b/loader/telnetd.c @@ -52,206 +52,217 @@ extern uint64_t flags; /* Forks, keeping the loader as our child (so we know when it dies). */ -int beTelnet(void) { - int sock; - int conn; - socklen_t addrLength; - pid_t child; - int i; - int masterFd, ttyFd; - struct sockaddr_in address; - char buf[4096]; - struct pollfd fds[3]; - telnet_state ts = TS_DATA; - char * termType; - int height, width; - struct winsize ws; - - if ((sock = socket(PF_INET, SOCK_STREAM, 0)) < 0) { - logMessage(ERROR, "socket: %s", strerror(errno)); - return -1; - } - - address.sin_family = AF_INET; - address.sin_port = htons(IPPORT_TELNET); - memset(&address.sin_addr, 0, sizeof(address.sin_addr)); - addrLength = sizeof(address); - - /* Let the kernel reuse the socket address. This lets us run - twice in a row, without waiting for the (ip, port) tuple - to time out. Makes testing much easier*/ - conn = 1; - setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &conn, sizeof(conn)); - - bind(sock, (struct sockaddr *) &address, sizeof(address)); - listen(sock, 5); - - winStatus(45, 3, _("Telnet"), _("Waiting for telnet connection.")); - - if ((conn = accept(sock, (struct sockaddr *) &address, &addrLength)) < 0) { - newtWinMessage(_("Error"), _("OK"), "accept failed: %s", - strerror(errno)); - close(sock); - return -1; - } - - stopNewt(); - close(sock); - telnet_negotiate(conn, &termType, &height, &width); +int beTelnet(void) +{ + int sock; + int conn; + socklen_t addrLength; + pid_t child; + int i; + int masterFd, ttyFd; + struct sockaddr_in address; + char buf[4096]; + struct pollfd fds[3]; + telnet_state ts = TS_DATA; + char *termType; + int height, width; + struct winsize ws; + + if ((sock = socket(PF_INET, SOCK_STREAM, 0)) < 0) { + logMessage(ERROR, "socket: %s", strerror(errno)); + return -1; + } + + address.sin_family = AF_INET; + address.sin_port = htons(IPPORT_TELNET); + memset(&address.sin_addr, 0, sizeof(address.sin_addr)); + addrLength = sizeof(address); + + /* Let the kernel reuse the socket address. This lets us run + twice in a row, without waiting for the (ip, port) tuple + to time out. Makes testing much easier */ + conn = 1; + setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &conn, sizeof(conn)); + + bind(sock, (struct sockaddr *)&address, sizeof(address)); + listen(sock, 5); + + winStatus(45, 3, _("Telnet"), _("Waiting for telnet connection.")); + + if ((conn = accept(sock, (struct sockaddr *)&address, &addrLength)) < 0) { + newtWinMessage(_("Error"), _("OK"), "accept failed: %s", + strerror(errno)); + close(sock); + return -1; + } + + stopNewt(); + close(sock); + telnet_negotiate(conn, &termType, &height, &width); #ifdef DEBUG_TELNET - printf("got term type %s\n", termType); + printf("got term type %s\n", termType); #endif - masterFd = open("/dev/ptmx", O_RDWR); - if (masterFd < 0) { - logMessage(CRITICAL, "cannot open /dev/ptmx"); - close(conn); - return -1; - } + masterFd = open("/dev/ptmx", O_RDWR); + if (masterFd < 0) { + logMessage(CRITICAL, "cannot open /dev/ptmx"); + close(conn); + return -1; + } - if (height != -1 && width != -1) { + if (height != -1 && width != -1) { #ifdef DEBUG_TELNET - printf("setting window size to %d x %d\n", width, height); + printf("setting window size to %d x %d\n", width, height); #endif - ws.ws_row = height; - ws.ws_col = width; - ioctl(masterFd, TIOCSWINSZ, &ws); - } + ws.ws_row = height; + ws.ws_col = width; + ioctl(masterFd, TIOCSWINSZ, &ws); + } + child = fork(); - child = fork(); - - if (child) { + if (child) { #ifndef DEBUG_TELNET - startNewt(); - winStatus(45, 3, _("Telnet"), _("Running anaconda via telnet.")); + startNewt(); + winStatus(45, 3, _("Telnet"), + _("Running anaconda via telnet.")); #endif - fds[0].events = POLLIN; - fds[0].fd = masterFd; + fds[0].events = POLLIN; + fds[0].fd = masterFd; - fds[1].events = POLLIN; - fds[1].fd = conn; + fds[1].events = POLLIN; + fds[1].fd = conn; - while ((i = poll(fds, 2, -1)) > 0) { - if (fds[0].revents) { - i = read(masterFd, buf, sizeof(buf)); + while ((i = poll(fds, 2, -1)) > 0) { + if (fds[0].revents) { + i = read(masterFd, buf, sizeof(buf)); #ifdef DEBUG_TELNET - { - int j; - int row; - - for (row = 0; row < (i / 12) + 1; row++) { - printf("wrote:"); - - for (j = (row * 12); j < i && j < ((row + 1) * 12); j++) - printf(" 0x%2x", (unsigned char) buf[j]); - - printf("\nwrote:"); - - for (j = (row*12); j < i && j < ((row+1)*12); j++) { - if (isprint(buf[j])) - printf(" %c ", buf[j]); - else - printf(" "); - } - - printf("\n"); - } - } + { + int j; + int row; + + for (row = 0; row < (i / 12) + 1; row++) { + printf("wrote:"); + + for (j = (row * 12); + j < i + && j < ((row + 1) * 12); + j++) + printf(" 0x%2x", + (unsigned char) + buf[j]); + + printf("\nwrote:"); + + for (j = (row * 12); + j < i + && j < ((row + 1) * 12); + j++) { + if (isprint(buf[j])) + printf(" %c ", + buf[j]); + else + printf(" "); + } + + printf("\n"); + } + } #endif - /* child died */ - if (i < 0) - break; + /* child died */ + if (i < 0) + break; - telnet_send_output(conn, buf, i); - } + telnet_send_output(conn, buf, i); + } - if (fds[1].revents) { - int ret; - i = read(conn, buf, sizeof(buf)); + if (fds[1].revents) { + int ret; + i = read(conn, buf, sizeof(buf)); - /* connection went away */ - if (!i) - break; + /* connection went away */ + if (!i) + break; - i = telnet_process_input(&ts, buf, i); - ret = write(masterFd, buf, i); + i = telnet_process_input(&ts, buf, i); + ret = write(masterFd, buf, i); #ifdef DEBUG_TELNET - { - int j; - - printf("got:"); - for (j = 0; j < i; j++) - printf(" 0x%x", (unsigned char) buf[j]); - printf("\n"); - } + { + int j; + + printf("got:"); + for (j = 0; j < i; j++) + printf(" 0x%x", + (unsigned char)buf[j]); + printf("\n"); + } #endif - } - } - - if (i < 0) { - logMessage(ERROR, "poll: %s", strerror(errno)); - } + } + } + if (i < 0) { + logMessage(ERROR, "poll: %s", strerror(errno)); + } #ifndef DEBUG_TELNET - stopNewt(); + stopNewt(); #endif - kill(child, SIGTERM); - close(conn); - exit(0); - } + kill(child, SIGTERM); + close(conn); + exit(0); + } - unlockpt(masterFd); - grantpt(masterFd); - ttyFd = open(ptsname(masterFd), O_RDWR); - close(masterFd); - setsid(); - close(0); - close(1); - close(2); + unlockpt(masterFd); + grantpt(masterFd); + ttyFd = open(ptsname(masterFd), O_RDWR); + close(masterFd); + setsid(); + close(0); + close(1); + close(2); - if (ttyFd != 0) { - dup2(ttyFd, 0); - close(ttyFd); - } + if (ttyFd != 0) { + dup2(ttyFd, 0); + close(ttyFd); + } - dup2(0, 1); - dup2(0, 2); + dup2(0, 1); + dup2(0, 2); - /* brand new tty! */ - setenv("TERM", termType, 1); + /* brand new tty! */ + setenv("TERM", termType, 1); - startNewt(); + startNewt(); - return 0; + return 0; } -void startTelnetd(struct loaderData_s * loaderData) { - char *ipaddr = NULL; - iface_t iface; +void startTelnetd(struct loaderData_s *loaderData) +{ + char *ipaddr = NULL; + iface_t iface; - iface_init_iface_t(&iface); + iface_init_iface_t(&iface); - if (kickstartNetworkUp(loaderData, &iface)) { - logMessage(ERROR, "unable to bring up network"); - return; - } + if (kickstartNetworkUp(loaderData, &iface)) { + logMessage(ERROR, "unable to bring up network"); + return; + } - ipaddr = iface_ip2str(iface.device, AF_INET); - if (ipaddr == NULL) { - logMessage(ERROR, "%s (%d): no IP address found for %s", - __func__, __LINE__, iface.device); - return; - } + ipaddr = iface_ip2str(iface.device, AF_INET); + if (ipaddr == NULL) { + logMessage(ERROR, "%s (%d): no IP address found for %s", + __func__, __LINE__, iface.device); + return; + } - logMessage(INFO, "going to beTelnet for %s", ipaddr); - if (!beTelnet()) - flags |= LOADER_FLAGS_TEXT | LOADER_FLAGS_NOSHELL; + logMessage(INFO, "going to beTelnet for %s", ipaddr); + if (!beTelnet()) + flags |= LOADER_FLAGS_TEXT | LOADER_FLAGS_NOSHELL; - return; + return; } /* vim:set sw=8 noet */ diff --git a/loader/telnetd.h b/loader/telnetd.h index 588ce11..7930de1 100644 --- a/loader/telnetd.h +++ b/loader/telnetd.h @@ -20,7 +20,7 @@ #ifndef TELNETD_H #define TELNETD_H -void startTelnetd(struct loaderData_s * loaderData); +void startTelnetd(struct loaderData_s *loaderData); #endif diff --git a/loader/udelay.h b/loader/udelay.h index 372e945..7366935 100644 --- a/loader/udelay.h +++ b/loader/udelay.h @@ -31,71 +31,64 @@ #define NSECS_PER_USEC 1000LL #define NSECS_PER_SEC (NSECS_PER_USEC * USECS_PER_SEC) -static inline void -nsectospec(long long nsecs, struct timespec *ts) +static inline void nsectospec(long long nsecs, struct timespec *ts) { - if (nsecs < 0) { - ts->tv_sec = -1; - ts->tv_nsec = -1; - return; - } - ts->tv_sec = nsecs / NSECS_PER_SEC; - ts->tv_nsec = (nsecs % NSECS_PER_SEC); + if (nsecs < 0) { + ts->tv_sec = -1; + ts->tv_nsec = -1; + return; + } + ts->tv_sec = nsecs / NSECS_PER_SEC; + ts->tv_nsec = (nsecs % NSECS_PER_SEC); } -static inline void -usectospec(long long usecs, struct timespec *ts) +static inline void usectospec(long long usecs, struct timespec *ts) { - if (usecs > 0 && LLONG_MAX / NSECS_PER_USEC > usecs) - usecs *= NSECS_PER_USEC; - - nsectospec(usecs, ts); + if (usecs > 0 && LLONG_MAX / NSECS_PER_USEC > usecs) + usecs *= NSECS_PER_USEC; + + nsectospec(usecs, ts); } -static inline int -speczero(struct timespec *ts) +static inline int speczero(struct timespec *ts) { - return (ts->tv_sec == 0 && ts->tv_nsec == 0); + return (ts->tv_sec == 0 && ts->tv_nsec == 0); } -static inline int -specinf(struct timespec *ts) +static inline int specinf(struct timespec *ts) { - return (ts->tv_sec < 0 || ts->tv_nsec < 0); + return (ts->tv_sec < 0 || ts->tv_nsec < 0); } -static inline long long -spectonsec(struct timespec *ts) +static inline long long spectonsec(struct timespec *ts) { - long long nsecs = 0; - if (specinf(ts)) - return -1; - - nsecs = ts->tv_sec * NSECS_PER_SEC; - nsecs += ts->tv_nsec; - return nsecs; + long long nsecs = 0; + if (specinf(ts)) + return -1; + + nsecs = ts->tv_sec * NSECS_PER_SEC; + nsecs += ts->tv_nsec; + return nsecs; } -static inline long long -spectousec(struct timespec *ts) +static inline long long spectousec(struct timespec *ts) { - long long usecs = spectonsec(ts); + long long usecs = spectonsec(ts); - return usecs < 0 ? usecs : usecs / NSECS_PER_USEC; + return usecs < 0 ? usecs : usecs / NSECS_PER_USEC; } -static inline int -gettimespecofday(struct timespec *ts) +static inline int gettimespecofday(struct timespec *ts) { - struct timeval tv = {0, 0}; - int rc; - - rc = gettimeofday(&tv, NULL); - if (rc >= 0) { - ts->tv_sec = tv.tv_sec; - ts->tv_nsec = tv.tv_usec * NSECS_PER_USEC; - } - return rc; + struct timeval tv = { 0, 0 }; + int rc; + + rc = gettimeofday(&tv, NULL); + if (rc >= 0) { + ts->tv_sec = tv.tv_sec; + ts->tv_nsec = tv.tv_usec * NSECS_PER_USEC; + } + return rc; } /* minuend minus subtrahend equals difference */ @@ -103,41 +96,41 @@ static inline void tssub(struct timespec *minuend, struct timespec *subtrahend, struct timespec *difference) { - long long m, s, d; - - m = spectonsec(minuend); - s = spectonsec(subtrahend); - - if (s < 0) { - d = 0; - } else if (m < 0) { - d = -1; - } else { - m -= s; - d = m < 0 ? 0 : m; - } - - nsectospec(d, difference); - return; + long long m, s, d; + + m = spectonsec(minuend); + s = spectonsec(subtrahend); + + if (s < 0) { + d = 0; + } else if (m < 0) { + d = -1; + } else { + m -= s; + d = m < 0 ? 0 : m; + } + + nsectospec(d, difference); + return; } static inline void tsadd(struct timespec *augend, struct timespec *addend, struct timespec *sum) { - long long aug, add; + long long aug, add; - aug = spectonsec(augend); - add = spectonsec(addend); + aug = spectonsec(augend); + add = spectonsec(addend); // printf("aug: %Ld add: %Ld\n", aug, add); - if (aug < 0 || add < 0) - nsectospec(-1, sum); - else if (LLONG_MAX - MAX(add,aug) < MAX(add,aug)) - nsectospec(LLONG_MAX, sum); - else - nsectospec(aug+add, sum); - return; + if (aug < 0 || add < 0) + nsectospec(-1, sum); + else if (LLONG_MAX - MAX(add, aug) < MAX(add, aug)) + nsectospec(LLONG_MAX, sum); + else + nsectospec(aug + add, sum); + return; } #define tsGT(x,y) (tscmp((x), (y)) < 0) @@ -147,50 +140,46 @@ tsadd(struct timespec *augend, struct timespec *addend, struct timespec *sum) #define tsLE(x,y) (tscmp((x), (y)) >= 0) #define tsLT(x,y) (tscmp((x), (y)) > 0) -static inline int -tscmp(struct timespec *a, struct timespec *b) +static inline int tscmp(struct timespec *a, struct timespec *b) { - long long m, s; - long long rc; - - m = spectonsec(a); - s = spectonsec(b); - - if (s < 0) { - rc = 1; - if (m < 0) - rc = 0; - } else if (m < 0) { - rc = -1; - } else { - rc = MIN(MAX(s-m, -1), 1); - } - - return rc; + long long m, s; + long long rc; + + m = spectonsec(a); + s = spectonsec(b); + + if (s < 0) { + rc = 1; + if (m < 0) + rc = 0; + } else if (m < 0) { + rc = -1; + } else { + rc = MIN(MAX(s - m, -1), 1); + } + + return rc; } -static inline void -udelayspec(struct timespec total) +static inline void udelayspec(struct timespec total) { - struct timespec rem; - if (specinf(&total)) { - do { - usectospec(LLONG_MAX, &rem); - } while (nanosleep(&rem, &rem) == -1 && errno == EINTR); - } else { - rem = total; - while (nanosleep(&rem, &rem) == -1 && errno == EINTR) - ; - } + struct timespec rem; + if (specinf(&total)) { + do { + usectospec(LLONG_MAX, &rem); + } while (nanosleep(&rem, &rem) == -1 && errno == EINTR); + } else { + rem = total; + while (nanosleep(&rem, &rem) == -1 && errno == EINTR) ; + } } -static inline void -udelay(long long usecs) +static inline void udelay(long long usecs) { - struct timespec rem = {0,0}; + struct timespec rem = { 0, 0 }; - usectospec(usecs, &rem); - udelayspec(rem); + usectospec(usecs, &rem); + udelayspec(rem); } #endif /* UDELAY_H */ diff --git a/loader/undomounts.c b/loader/undomounts.c index b42d9b1..e6b07ae 100644 --- a/loader/undomounts.c +++ b/loader/undomounts.c @@ -43,199 +43,219 @@ #define MNT_DETACH 0x00000002 struct unmountInfo { - char * name; - int mounted; - int loopDevice; - enum { FS, LOOP } what; -} ; - -void undoLoop(struct unmountInfo * fs, int numFs, int this); - -static void printstr(char * string) { - int ret; - - ret = write(1, string, strlen(string)); -} + char *name; + int mounted; + int loopDevice; + enum { FS, LOOP } what; +}; -void undoMount(struct unmountInfo * fs, int numFs, int this) { - size_t len = strlen(fs[this].name); - int i; - - if (!fs[this].mounted) return; - fs[this].mounted = 0; - - /* unmount everything underneath this */ - for (i = 0; i < numFs; i++) { - if (fs[i].name && (strlen(fs[i].name) >= len) && - (fs[i].name[len] == '/') && - !strncmp(fs[this].name, fs[i].name, len)) { - if (fs[i].what == LOOP) - undoLoop(fs, numFs, i); - else - undoMount(fs, numFs, i); - } - } - - printf("\t%s", fs[this].name); - /* don't need to unmount /tmp. it is busy anyway. */ - if (umount2(fs[this].name, MNT_DETACH) < 0) { - printf(" umount failed (%d)", errno); - } else { - printf(" done"); - } - printf("\n"); +void undoLoop(struct unmountInfo *fs, int numFs, int this); + +static void printstr(char *string) +{ + int ret; + + ret = write(1, string, strlen(string)); } -void undoLoop(struct unmountInfo * fs, int numFs, int this) { - int i; - int fd; - - if (!fs[this].mounted) return; - fs[this].mounted = 0; - - /* find the device mount */ - for (i = 0; i < numFs; i++) { - if (fs[i].what == FS && (fs[i].loopDevice == fs[this].loopDevice)) - break; - } - - if (i < numFs) { - /* the device is mounted, unmount it (and recursively, anything - * underneath) */ - undoMount(fs, numFs, i); - } - - unlink("/tmp/loop"); - mknod("/tmp/loop", 0600 | S_IFBLK, (7 << 8) | fs[this].loopDevice); - printf("\tdisabling /dev/loop%d", fs[this].loopDevice); - if ((fd = open("/tmp/loop", O_RDONLY, 0)) < 0) { - printf(" failed to open device: %d", errno); - } else { - if (ioctl(fd, LOOP_CLR_FD, 0)) - printf(" LOOP_CLR_FD failed: %d", errno); - close(fd); - } +void undoMount(struct unmountInfo *fs, int numFs, int this) +{ + size_t len = strlen(fs[this].name); + int i; + + if (!fs[this].mounted) + return; + fs[this].mounted = 0; + + /* unmount everything underneath this */ + for (i = 0; i < numFs; i++) { + if (fs[i].name && (strlen(fs[i].name) >= len) && + (fs[i].name[len] == '/') && + !strncmp(fs[this].name, fs[i].name, len)) { + if (fs[i].what == LOOP) + undoLoop(fs, numFs, i); + else + undoMount(fs, numFs, i); + } + } - printf("\n"); + printf("\t%s", fs[this].name); + /* don't need to unmount /tmp. it is busy anyway. */ + if (umount2(fs[this].name, MNT_DETACH) < 0) { + printf(" umount failed (%d)", errno); + } else { + printf(" done"); + } + printf("\n"); } -void unmountFilesystems(void) { - int fd, size; - char buf[65535]; /* this should be big enough */ - char * chptr, * start; - struct unmountInfo filesystems[500]; - int numFilesystems = 0; - int i; - struct loop_info li; - char * device; - struct stat sb; - - fd = open("/proc/mounts", O_RDONLY, 0); - if (fd < 1) { - /* FIXME: was perror */ - printstr("failed to open /proc/mounts"); - sleep(2); - return; - } - - size = read(fd, buf, sizeof(buf) - 1); - buf[size] = '\0'; - - close(fd); - - chptr = buf; - while (*chptr) { - device = chptr; - while (*chptr != ' ') chptr++; - *chptr++ = '\0'; - start = chptr; - while (*chptr != ' ') chptr++; - *chptr++ = '\0'; - - if (strcmp(start, "/") && strcmp(start, "/tmp") && - strcmp(start, "/dev")) { - filesystems[numFilesystems].name = strdup(start); - filesystems[numFilesystems].what = FS; - filesystems[numFilesystems].mounted = 1; - - stat(start, &sb); - if ((sb.st_dev >> 8) == 7) { - filesystems[numFilesystems].loopDevice = sb.st_dev & 0xf; - } else { - filesystems[numFilesystems].loopDevice = -1; - } - - numFilesystems++; +void undoLoop(struct unmountInfo *fs, int numFs, int this) +{ + int i; + int fd; + + if (!fs[this].mounted) + return; + fs[this].mounted = 0; + + /* find the device mount */ + for (i = 0; i < numFs; i++) { + if (fs[i].what == FS + && (fs[i].loopDevice == fs[this].loopDevice)) + break; } - while (*chptr != '\n') chptr++; - chptr++; - } + if (i < numFs) { + /* the device is mounted, unmount it (and recursively, anything + * underneath) */ + undoMount(fs, numFs, i); + } - for (i = 0; i < 7; i++) { unlink("/tmp/loop"); - mknod("/tmp/loop", 0600 | S_IFBLK, (7 << 8) | i); - if ((fd = open("/tmp/loop", O_RDONLY, 0)) >= 0) { - if (!ioctl(fd, LOOP_GET_STATUS, &li) && li.lo_name[0]) { - filesystems[numFilesystems].name = strdup(li.lo_name); - filesystems[numFilesystems].what = LOOP; - filesystems[numFilesystems].mounted = 1; - filesystems[numFilesystems].loopDevice = i; - numFilesystems++; - } - - close(fd); + mknod("/tmp/loop", 0600 | S_IFBLK, (7 << 8) | fs[this].loopDevice); + printf("\tdisabling /dev/loop%d", fs[this].loopDevice); + if ((fd = open("/tmp/loop", O_RDONLY, 0)) < 0) { + printf(" failed to open device: %d", errno); + } else { + if (ioctl(fd, LOOP_CLR_FD, 0)) + printf(" LOOP_CLR_FD failed: %d", errno); + close(fd); + } + + printf("\n"); +} + +void unmountFilesystems(void) +{ + int fd, size; + char buf[65535]; /* this should be big enough */ + char *chptr, *start; + struct unmountInfo filesystems[500]; + int numFilesystems = 0; + int i; + struct loop_info li; + char *device; + struct stat sb; + + fd = open("/proc/mounts", O_RDONLY, 0); + if (fd < 1) { + /* FIXME: was perror */ + printstr("failed to open /proc/mounts"); + sleep(2); + return; + } + + size = read(fd, buf, sizeof(buf) - 1); + buf[size] = '\0'; + + close(fd); + + chptr = buf; + while (*chptr) { + device = chptr; + while (*chptr != ' ') + chptr++; + *chptr++ = '\0'; + start = chptr; + while (*chptr != ' ') + chptr++; + *chptr++ = '\0'; + + if (strcmp(start, "/") && strcmp(start, "/tmp") && + strcmp(start, "/dev")) { + filesystems[numFilesystems].name = strdup(start); + filesystems[numFilesystems].what = FS; + filesystems[numFilesystems].mounted = 1; + + stat(start, &sb); + if ((sb.st_dev >> 8) == 7) { + filesystems[numFilesystems].loopDevice = + sb.st_dev & 0xf; + } else { + filesystems[numFilesystems].loopDevice = -1; + } + + numFilesystems++; + } + + while (*chptr != '\n') + chptr++; + chptr++; + } + + for (i = 0; i < 7; i++) { + unlink("/tmp/loop"); + mknod("/tmp/loop", 0600 | S_IFBLK, (7 << 8) | i); + if ((fd = open("/tmp/loop", O_RDONLY, 0)) >= 0) { + if (!ioctl(fd, LOOP_GET_STATUS, &li) && li.lo_name[0]) { + filesystems[numFilesystems].name = + strdup(li.lo_name); + filesystems[numFilesystems].what = LOOP; + filesystems[numFilesystems].mounted = 1; + filesystems[numFilesystems].loopDevice = i; + numFilesystems++; + } + + close(fd); + } } - } - for (i = 0; i < numFilesystems; i++) { - if (filesystems[i].what == LOOP) { - undoLoop(filesystems, numFilesystems, i); + for (i = 0; i < numFilesystems; i++) { + if (filesystems[i].what == LOOP) { + undoLoop(filesystems, numFilesystems, i); + } } - } - for (i = 0; i < numFilesystems; i++) { - if ((filesystems[i].mounted) && (filesystems[i].name)) { - undoMount(filesystems, numFilesystems, i); + for (i = 0; i < numFilesystems; i++) { + if ((filesystems[i].mounted) && (filesystems[i].name)) { + undoMount(filesystems, numFilesystems, i); + } } - } - for (i = 0; i < numFilesystems; i++) - free(filesystems[i].name); + for (i = 0; i < numFilesystems; i++) + free(filesystems[i].name); } -void disableSwap(void) { - int fd; - char buf[4096]; - int i; - char * start; - char * chptr; - - if ((fd = open("/proc/swaps", O_RDONLY, 0)) < 0) return; - - i = read(fd, buf, sizeof(buf) - 1); - close(fd); - if (i < 0) return; - buf[i] = '\0'; - - start = buf; - while (*start) { - while (*start != '\n' && *start) start++; - if (!*start) return; - - start++; - if (*start != '/') return; - chptr = start; - while (*chptr && *chptr != ' ') chptr++; - if (!(*chptr)) return; - *chptr = '\0'; - printf("\t%s", start); - if (swapoff(start)) - printf(" failed (%d)", errno); - printf("\n"); +void disableSwap(void) +{ + int fd; + char buf[4096]; + int i; + char *start; + char *chptr; - start = chptr + 1; - } + if ((fd = open("/proc/swaps", O_RDONLY, 0)) < 0) + return; + + i = read(fd, buf, sizeof(buf) - 1); + close(fd); + if (i < 0) + return; + buf[i] = '\0'; + + start = buf; + while (*start) { + while (*start != '\n' && *start) + start++; + if (!*start) + return; + + start++; + if (*start != '/') + return; + chptr = start; + while (*chptr && *chptr != ' ') + chptr++; + if (!(*chptr)) + return; + *chptr = '\0'; + printf("\t%s", start); + if (swapoff(start)) + printf(" failed (%d)", errno); + printf("\n"); + + start = chptr + 1; + } } /* vim:set sw=8 noet */ diff --git a/loader/urlinstall.c b/loader/urlinstall.c index 3813c24..478013a 100644 --- a/loader/urlinstall.c +++ b/loader/urlinstall.c @@ -52,364 +52,398 @@ extern uint64_t flags; char **extraHeaders = NULL; -static char **headers() { - int len = 2; - - /* The list of HTTP headers is unlikely to change, unless a new ethernet - * device suddenly shows up since last time we downloaded a file. So, - * cache the result here to save some time. - */ - if (extraHeaders != NULL) - return extraHeaders; - - if ((extraHeaders = realloc(extraHeaders, 2*sizeof(char *))) == NULL) { - logMessage(CRITICAL, "%s: %d: %m", __func__, __LINE__); - abort(); - } - - checked_asprintf(&extraHeaders[0], "X-Anaconda-Architecture: %s", getProductArch()); - checked_asprintf(&extraHeaders[1], "X-Anaconda-System-Release: %s", getProductName()); - - if (FL_KICKSTART_SEND_MAC(flags)) { - /* find all ethernet devices and make a header entry for each one */ - int i; - char *dev, *mac; - struct device **devices; - - devices = getDevices(DEVICE_NETWORK); - for (i = 0; devices && devices[i]; i++) { - dev = devices[i]->device; - mac = iface_mac2str(dev); - - if (mac) { - extraHeaders = realloc(extraHeaders, (len+1)*sizeof(char *)); - checked_asprintf(&extraHeaders[len], "X-RHN-Provisioning-MAC-%d: %s %s", - i, dev, mac); - - len++; - free(mac); - } - } - } - - if (FL_KICKSTART_SEND_SERIAL(flags) && !access("/sbin/dmidecode", X_OK)) { - FILE *f; - char sn[1024]; - size_t sn_len; - - if ((f = popen("/sbin/dmidecode -s system-serial-number", "r")) == NULL) { - logMessage(CRITICAL, "%s: %d: %m", __func__, __LINE__); - abort(); - } - - sn_len = fread(sn, sizeof(char), 1023, f); - if (ferror(f)) { - logMessage(CRITICAL, "%s: %d: %m", __func__, __LINE__); - abort(); - } - - sn[sn_len] = '\0'; - pclose(f); - - extraHeaders = realloc(extraHeaders, (len+1)*sizeof(char *)); - - checked_asprintf(&extraHeaders[len], "X-System-Serial-Number: %s", sn); - - len++; - } - - extraHeaders = realloc(extraHeaders, (len+1)*sizeof(char *)); - extraHeaders[len] = NULL; - return extraHeaders; +static char **headers() +{ + int len = 2; + + /* The list of HTTP headers is unlikely to change, unless a new ethernet + * device suddenly shows up since last time we downloaded a file. So, + * cache the result here to save some time. + */ + if (extraHeaders != NULL) + return extraHeaders; + + if ((extraHeaders = realloc(extraHeaders, 2 * sizeof(char *))) == NULL) { + logMessage(CRITICAL, "%s: %d: %m", __func__, __LINE__); + abort(); + } + + checked_asprintf(&extraHeaders[0], "X-Anaconda-Architecture: %s", + getProductArch()); + checked_asprintf(&extraHeaders[1], "X-Anaconda-System-Release: %s", + getProductName()); + + if (FL_KICKSTART_SEND_MAC(flags)) { + /* find all ethernet devices and make a header entry for each one */ + int i; + char *dev, *mac; + struct device **devices; + + devices = getDevices(DEVICE_NETWORK); + for (i = 0; devices && devices[i]; i++) { + dev = devices[i]->device; + mac = iface_mac2str(dev); + + if (mac) { + extraHeaders = + realloc(extraHeaders, + (len + 1) * sizeof(char *)); + checked_asprintf(&extraHeaders[len], + "X-RHN-Provisioning-MAC-%d: %s %s", + i, dev, mac); + + len++; + free(mac); + } + } + } + + if (FL_KICKSTART_SEND_SERIAL(flags) && !access("/sbin/dmidecode", X_OK)) { + FILE *f; + char sn[1024]; + size_t sn_len; + + if ((f = + popen("/sbin/dmidecode -s system-serial-number", + "r")) == NULL) { + logMessage(CRITICAL, "%s: %d: %m", __func__, __LINE__); + abort(); + } + + sn_len = fread(sn, sizeof(char), 1023, f); + if (ferror(f)) { + logMessage(CRITICAL, "%s: %d: %m", __func__, __LINE__); + abort(); + } + + sn[sn_len] = '\0'; + pclose(f); + + extraHeaders = + realloc(extraHeaders, (len + 1) * sizeof(char *)); + + checked_asprintf(&extraHeaders[len], + "X-System-Serial-Number: %s", sn); + + len++; + } + + extraHeaders = realloc(extraHeaders, (len + 1) * sizeof(char *)); + extraHeaders[len] = NULL; + return extraHeaders; } -static int loadSingleUrlImage(struct loaderData_s *loaderData, struct iurlinfo *ui, - char *dest, char *mntpoint, char *device, int silentErrors) { - char **ehdrs = NULL; - int status; - - if (!strncmp(ui->url, "http", 4)) - ehdrs = headers(); - - status = urlinstTransfer(loaderData, ui, ehdrs, dest); - if (status) { - if (!silentErrors) { - newtWinMessage(_("Error"), _("OK"), - _("Unable to retrieve %s."), ui->url); - } - - return 2; - } - - if (dest != NULL) { - if (mountLoopback(dest, mntpoint, device)) { - logMessage(ERROR, "Error mounting %s on %s: %m", device, mntpoint); - return 1; - } - } - - return 0; +static int loadSingleUrlImage(struct loaderData_s *loaderData, + struct iurlinfo *ui, char *dest, char *mntpoint, + char *device, int silentErrors) +{ + char **ehdrs = NULL; + int status; + + if (!strncmp(ui->url, "http", 4)) + ehdrs = headers(); + + status = urlinstTransfer(loaderData, ui, ehdrs, dest); + if (status) { + if (!silentErrors) { + newtWinMessage(_("Error"), _("OK"), + _("Unable to retrieve %s."), ui->url); + } + + return 2; + } + + if (dest != NULL) { + if (mountLoopback(dest, mntpoint, device)) { + logMessage(ERROR, "Error mounting %s on %s: %m", device, + mntpoint); + return 1; + } + } + + return 0; } -static void copyWarnFn (char *msg) { - logMessage(WARNING, msg); +static void copyWarnFn(char *msg) +{ + logMessage(WARNING, msg); } -static void copyErrorFn (char *msg) { - newtWinMessage(_("Error"), _("OK"), _(msg)); +static void copyErrorFn(char *msg) +{ + newtWinMessage(_("Error"), _("OK"), _(msg)); } -static int loadUrlImages(struct loaderData_s *loaderData, struct iurlinfo *ui) { - char *oldUrl, *path, *dest, *slash; - int rc; - - oldUrl = strdup(ui->url); - free(ui->url); - - /* Figure out the path where updates.img and product.img files are - * kept. Since ui->url points to a stage2 image file, we just need - * to trim off the file name and look in the same directory. - */ - if ((slash = strrchr(oldUrl, '/')) == NULL) - return 0; - - if ((path = strndup(oldUrl, slash-oldUrl)) == NULL) - path = oldUrl; - - /* grab the updates.img before install.img so that we minimize our - * ramdisk usage */ - checked_asprintf(&ui->url, "%s/%s", path, "updates.img"); - - if (!loadSingleUrlImage(loaderData, ui, "/tmp/updates-disk.img", "/tmp/update-disk", - "/dev/loop7", 1)) { - copyDirectory("/tmp/update-disk", "/tmp/updates", copyWarnFn, - copyErrorFn); - umountLoopback("/tmp/update-disk", "/dev/loop7"); - unlink("/tmp/updates-disk.img"); - unlink("/tmp/update-disk"); - } else if (!access("/tmp/updates-disk.img", R_OK)) { - unpackCpioBall("/tmp/updates-disk.img", "/tmp/updates"); - unlink("/tmp/updates-disk.img"); - } - - free(ui->url); - - /* grab the product.img before install.img so that we minimize our - * ramdisk usage */ - checked_asprintf(&ui->url, "%s/%s", path, "product.img"); - - if (!loadSingleUrlImage(loaderData, ui, "/tmp/product-disk.img", "/tmp/product-disk", - "/dev/loop7", 1)) { - copyDirectory("/tmp/product-disk", "/tmp/product", copyWarnFn, - copyErrorFn); - umountLoopback("/tmp/product-disk", "/dev/loop7"); - unlink("/tmp/product-disk.img"); - unlink("/tmp/product-disk"); - } - - free(ui->url); - ui->url = strdup(oldUrl); - - checked_asprintf(&dest, "/tmp/install.img"); - - rc = loadSingleUrlImage(loaderData, ui, dest, "/mnt/runtime", "/dev/loop0", 0); - free(dest); - free(oldUrl); - - if (rc) { - if (rc != 2) - newtWinMessage(_("Error"), _("OK"), - _("Unable to retrieve the install image.")); - return 1; - } - - return 0; +static int loadUrlImages(struct loaderData_s *loaderData, struct iurlinfo *ui) +{ + char *oldUrl, *path, *dest, *slash; + int rc; + + oldUrl = strdup(ui->url); + free(ui->url); + + /* Figure out the path where updates.img and product.img files are + * kept. Since ui->url points to a stage2 image file, we just need + * to trim off the file name and look in the same directory. + */ + if ((slash = strrchr(oldUrl, '/')) == NULL) + return 0; + + if ((path = strndup(oldUrl, slash - oldUrl)) == NULL) + path = oldUrl; + + /* grab the updates.img before install.img so that we minimize our + * ramdisk usage */ + checked_asprintf(&ui->url, "%s/%s", path, "updates.img"); + + if (!loadSingleUrlImage + (loaderData, ui, "/tmp/updates-disk.img", "/tmp/update-disk", + "/dev/loop7", 1)) { + copyDirectory("/tmp/update-disk", "/tmp/updates", copyWarnFn, + copyErrorFn); + umountLoopback("/tmp/update-disk", "/dev/loop7"); + unlink("/tmp/updates-disk.img"); + unlink("/tmp/update-disk"); + } else if (!access("/tmp/updates-disk.img", R_OK)) { + unpackCpioBall("/tmp/updates-disk.img", "/tmp/updates"); + unlink("/tmp/updates-disk.img"); + } + + free(ui->url); + + /* grab the product.img before install.img so that we minimize our + * ramdisk usage */ + checked_asprintf(&ui->url, "%s/%s", path, "product.img"); + + if (!loadSingleUrlImage + (loaderData, ui, "/tmp/product-disk.img", "/tmp/product-disk", + "/dev/loop7", 1)) { + copyDirectory("/tmp/product-disk", "/tmp/product", copyWarnFn, + copyErrorFn); + umountLoopback("/tmp/product-disk", "/dev/loop7"); + unlink("/tmp/product-disk.img"); + unlink("/tmp/product-disk"); + } + + free(ui->url); + ui->url = strdup(oldUrl); + + checked_asprintf(&dest, "/tmp/install.img"); + + rc = loadSingleUrlImage(loaderData, ui, dest, "/mnt/runtime", + "/dev/loop0", 0); + free(dest); + free(oldUrl); + + if (rc) { + if (rc != 2) + newtWinMessage(_("Error"), _("OK"), + _ + ("Unable to retrieve the install image.")); + return 1; + } + + return 0; } char *mountUrlImage(struct installMethod *method, char *location, - struct loaderData_s *loaderData) { - urlInstallData *stage2Data = (urlInstallData *) loaderData->stage2Data; - struct iurlinfo ui; - - enum { URL_STAGE_MAIN, URL_STAGE_FETCH, - URL_STAGE_DONE } stage = URL_STAGE_MAIN; - - memset(&ui, 0, sizeof(ui)); - - while (stage != URL_STAGE_DONE) { - switch(stage) { - case URL_STAGE_MAIN: { - /* If the stage2= parameter was given (or inferred from repo=) - * then use that configuration info to fetch the image. This - * could also have come from kickstart. Else, we need to show - * the UI. - */ - if (loaderData->method == METHOD_URL && stage2Data) { - ui.url = strdup(stage2Data->url); - logMessage(INFO, "URL_STAGE_MAIN: url is %s", ui.url); - - if (!ui.url) { - logMessage(ERROR, "missing URL specification"); - loaderData->method = -1; - free(loaderData->stage2Data); - loaderData->stage2Data = NULL; - - if (loaderData->inferredStage2) - loaderData->invalidRepoParam = 1; - - break; - } - - /* ks info was adequate, lets skip to fetching image */ - stage = URL_STAGE_FETCH; - break; - } else { - char *substr; - - if (urlMainSetupPanel(loaderData, &ui)) { - loaderData->stage2Data = NULL; - return NULL; - } - - /* If the user-provided URL points at a repo instead of - * a stage2 image, fix it up now. - */ - substr = strstr(ui.url, ".img"); - if (!substr || (substr && *(substr+4) != '\0')) { - loaderData->instRepo = strdup(ui.url); - - checked_asprintf(&ui.url, "%s/images/install.img", - ui.url); - } - - loaderData->invalidRepoParam = 1; - } - - stage = URL_STAGE_FETCH; - break; - } - - case URL_STAGE_FETCH: { - if (loadUrlImages(loaderData, &ui)) { - stage = URL_STAGE_MAIN; - - if (loaderData->method >= 0) - loaderData->method = -1; - - if (loaderData->inferredStage2) - loaderData->invalidRepoParam = 1; - } else { - stage = URL_STAGE_DONE; - } - - break; - } - - case URL_STAGE_DONE: - break; - } - } - - return ui.url; + struct loaderData_s *loaderData) +{ + urlInstallData *stage2Data = (urlInstallData *) loaderData->stage2Data; + struct iurlinfo ui; + + enum { URL_STAGE_MAIN, URL_STAGE_FETCH, + URL_STAGE_DONE + } stage = URL_STAGE_MAIN; + + memset(&ui, 0, sizeof(ui)); + + while (stage != URL_STAGE_DONE) { + switch (stage) { + case URL_STAGE_MAIN:{ + /* If the stage2= parameter was given (or inferred from repo=) + * then use that configuration info to fetch the image. This + * could also have come from kickstart. Else, we need to show + * the UI. + */ + if (loaderData->method == METHOD_URL + && stage2Data) { + ui.url = strdup(stage2Data->url); + logMessage(INFO, + "URL_STAGE_MAIN: url is %s", + ui.url); + + if (!ui.url) { + logMessage(ERROR, + "missing URL specification"); + loaderData->method = -1; + free(loaderData->stage2Data); + loaderData->stage2Data = NULL; + + if (loaderData->inferredStage2) + loaderData->invalidRepoParam + = 1; + + break; + } + + /* ks info was adequate, lets skip to fetching image */ + stage = URL_STAGE_FETCH; + break; + } else { + char *substr; + + if (urlMainSetupPanel(loaderData, &ui)) { + loaderData->stage2Data = NULL; + return NULL; + } + + /* If the user-provided URL points at a repo instead of + * a stage2 image, fix it up now. + */ + substr = strstr(ui.url, ".img"); + if (!substr + || (substr + && *(substr + 4) != '\0')) { + loaderData->instRepo = + strdup(ui.url); + + checked_asprintf(&ui.url, + "%s/images/install.img", + ui.url); + } + + loaderData->invalidRepoParam = 1; + } + + stage = URL_STAGE_FETCH; + break; + } + + case URL_STAGE_FETCH:{ + if (loadUrlImages(loaderData, &ui)) { + stage = URL_STAGE_MAIN; + + if (loaderData->method >= 0) + loaderData->method = -1; + + if (loaderData->inferredStage2) + loaderData->invalidRepoParam = + 1; + } else { + stage = URL_STAGE_DONE; + } + + break; + } + + case URL_STAGE_DONE: + break; + } + } + + return ui.url; } -int getFileFromUrl(char * url, char * dest, - struct loaderData_s * loaderData) { - struct iurlinfo ui; - char **ehdrs = NULL; - int rc; - iface_t iface; +int getFileFromUrl(char *url, char *dest, struct loaderData_s *loaderData) +{ + struct iurlinfo ui; + char **ehdrs = NULL; + int rc; + iface_t iface; - iface_init_iface_t(&iface); + iface_init_iface_t(&iface); - if (kickstartNetworkUp(loaderData, &iface)) { - logMessage(ERROR, "unable to bring up network"); - return 1; - } + if (kickstartNetworkUp(loaderData, &iface)) { + logMessage(ERROR, "unable to bring up network"); + return 1; + } - memset(&ui, 0, sizeof(ui)); - ui.url = url; + memset(&ui, 0, sizeof(ui)); + ui.url = url; - logMessage(INFO, "file location: %s", url); + logMessage(INFO, "file location: %s", url); - if (!strncmp(url, "http", 4)) { - ehdrs = headers(); - } + if (!strncmp(url, "http", 4)) { + ehdrs = headers(); + } - rc = urlinstTransfer(loaderData, &ui, ehdrs, dest); - if (rc) { - logMessage(ERROR, "failed to retrieve %s", ui.url); - return 1; - } + rc = urlinstTransfer(loaderData, &ui, ehdrs, dest); + if (rc) { + logMessage(ERROR, "failed to retrieve %s", ui.url); + return 1; + } - return 0; + return 0; } /* pull kickstart configuration file via http */ -int kickstartFromUrl(char * url, struct loaderData_s * loaderData) { - return getFileFromUrl(url, "/tmp/ks.cfg", loaderData); +int kickstartFromUrl(char *url, struct loaderData_s *loaderData) +{ + return getFileFromUrl(url, "/tmp/ks.cfg", loaderData); } -void setKickstartUrl(struct loaderData_s * loaderData, int argc, - char ** argv) { - char *substr = NULL; - gchar *url = NULL, *proxy = NULL; - GOptionContext *optCon = g_option_context_new(NULL); - GError *optErr = NULL; - GOptionEntry ksUrlOptions[] = { - { "url", 0, 0, G_OPTION_ARG_STRING, &url, NULL, NULL }, - { "proxy", 0, 0, G_OPTION_ARG_STRING, &proxy, NULL, NULL }, - { NULL }, - }; - - logMessage(INFO, "kickstartFromUrl"); - - g_option_context_set_help_enabled(optCon, FALSE); - g_option_context_add_main_entries(optCon, ksUrlOptions, NULL); - - if (!g_option_context_parse(optCon, &argc, &argv, &optErr)) { - startNewt(); - newtWinMessage(_("Kickstart Error"), _("OK"), - _("Bad argument to URL kickstart method " - "command: %s"), optErr->message); - g_error_free(optErr); - g_option_context_free(optCon); - return; - } - - g_option_context_free(optCon); - - if (!url) { - newtWinMessage(_("Kickstart Error"), _("OK"), - _("Must supply a --url argument to Url kickstart method.")); - return; - } - - /* determine install type */ - if (strncmp(url, "http", 4) && strncmp(url, "ftp://", 6)) { - newtWinMessage(_("Kickstart Error"), _("OK"), - _("Unknown Url method %s"), url); - return; - } - - substr = strstr(url, ".img"); - if (!substr || (substr && *(substr+4) != '\0')) { - loaderData->instRepo = strdup(url); - } else { - if ((loaderData->stage2Data = calloc(sizeof(urlInstallData *), 1)) == NULL) - return; - - ((urlInstallData *)loaderData->stage2Data)->url = url; - loaderData->method = METHOD_URL; - } - - if (proxy) { - splitProxyParam(proxy, &loaderData->proxyUser, - &loaderData->proxyPassword, - &loaderData->proxy, - &loaderData->proxyPort); - } - logMessage(INFO, "results of url ks, url %s", url); +void setKickstartUrl(struct loaderData_s *loaderData, int argc, char **argv) +{ + char *substr = NULL; + gchar *url = NULL, *proxy = NULL; + GOptionContext *optCon = g_option_context_new(NULL); + GError *optErr = NULL; + GOptionEntry ksUrlOptions[] = { + {"url", 0, 0, G_OPTION_ARG_STRING, &url, NULL, NULL}, + {"proxy", 0, 0, G_OPTION_ARG_STRING, &proxy, NULL, NULL}, + {NULL}, + }; + + logMessage(INFO, "kickstartFromUrl"); + + g_option_context_set_help_enabled(optCon, FALSE); + g_option_context_add_main_entries(optCon, ksUrlOptions, NULL); + + if (!g_option_context_parse(optCon, &argc, &argv, &optErr)) { + startNewt(); + newtWinMessage(_("Kickstart Error"), _("OK"), + _("Bad argument to URL kickstart method " + "command: %s"), optErr->message); + g_error_free(optErr); + g_option_context_free(optCon); + return; + } + + g_option_context_free(optCon); + + if (!url) { + newtWinMessage(_("Kickstart Error"), _("OK"), + _ + ("Must supply a --url argument to Url kickstart method.")); + return; + } + + /* determine install type */ + if (strncmp(url, "http", 4) && strncmp(url, "ftp://", 6)) { + newtWinMessage(_("Kickstart Error"), _("OK"), + _("Unknown Url method %s"), url); + return; + } + + substr = strstr(url, ".img"); + if (!substr || (substr && *(substr + 4) != '\0')) { + loaderData->instRepo = strdup(url); + } else { + if ((loaderData->stage2Data = + calloc(sizeof(urlInstallData *), 1)) == NULL) + return; + + ((urlInstallData *) loaderData->stage2Data)->url = url; + loaderData->method = METHOD_URL; + } + + if (proxy) { + splitProxyParam(proxy, &loaderData->proxyUser, + &loaderData->proxyPassword, + &loaderData->proxy, &loaderData->proxyPort); + } + logMessage(INFO, "results of url ks, url %s", url); } /* vim:set sw=8 noet */ diff --git a/loader/urlinstall.h b/loader/urlinstall.h index 808d64e..9fc3d75 100644 --- a/loader/urlinstall.h +++ b/loader/urlinstall.h @@ -25,13 +25,11 @@ typedef struct iurlinfo urlInstallData; -void setKickstartUrl(struct loaderData_s * loaderData, int argc, - char ** argv); -int kickstartFromUrl(char * url, struct loaderData_s * loaderData); -char * mountUrlImage(struct installMethod * method, - char * location, struct loaderData_s * loaderData); -int getFileFromUrl(char * url, char * dest, struct loaderData_s * loaderData); - +void setKickstartUrl(struct loaderData_s *loaderData, int argc, char **argv); +int kickstartFromUrl(char *url, struct loaderData_s *loaderData); +char *mountUrlImage(struct installMethod *method, + char *location, struct loaderData_s *loaderData); +int getFileFromUrl(char *url, char *dest, struct loaderData_s *loaderData); #endif diff --git a/loader/urls.c b/loader/urls.c index 1ad5493..a72e2ba 100644 --- a/loader/urls.c +++ b/loader/urls.c @@ -55,316 +55,352 @@ extern uint64_t flags; /* This is just a wrapper around the windows.c progress callback that accepts * the arguments libcurl provides. */ -int progress_cb(void *data, double dltotal, double dlnow, double ultotal, double ulnow) { - struct progressCBdata *cb_data = (struct progressCBdata *) data; +int progress_cb(void *data, double dltotal, double dlnow, double ultotal, + double ulnow) +{ + struct progressCBdata *cb_data = (struct progressCBdata *)data; - progressCallback(cb_data, dlnow, dltotal); - return 0; + progressCallback(cb_data, dlnow, dltotal); + return 0; } int splitProxyParam(char *param, char **user, char **password, char **host, - char **port) { - /* proxy=[protocol://][username[:password]@]host[:port] */ - char *pattern = "([[:alpha:]]+://)?(([[:alnum:]]+)(:[^:@]+)?@)?([^:]+)(:[[:digit:]]+)?(/.*)?"; - regex_t re; - regmatch_t pmatch[NMATCH]; - - if (regcomp(&re, pattern, REG_EXTENDED)) { - return 0; - } - - if (regexec(&re, param, NMATCH, pmatch, 0) == REG_NOMATCH) { - regfree(&re); - return 0; - } - - /* Match 0 is always the whole string (assuming regexec matched anything) - * so skip it. Then, these indices are just the number of the starting - * paren in pattern above. Make sure to change these whenever changing - * the pattern. - */ - if (pmatch[3].rm_so != -1) - *user = strndup(param+pmatch[3].rm_so, pmatch[3].rm_eo-pmatch[3].rm_so); - - /* Skip the leading colon. */ - if (pmatch[4].rm_so != -1) - *password = strndup(param+pmatch[4].rm_so+1, pmatch[4].rm_eo-pmatch[4].rm_so-1); - - if (pmatch[5].rm_so != -1) - *host = strndup(param+pmatch[5].rm_so, pmatch[5].rm_eo-pmatch[5].rm_so); - - /* Skip the leading colon. */ - if (pmatch[6].rm_so != -1) - *port = strndup(param+pmatch[6].rm_so+1, pmatch[6].rm_eo-pmatch[6].rm_so-1); - - regfree(&re); - return 1; + char **port) +{ + /* proxy=[protocol://][username[:password]@]host[:port] */ + char *pattern = + "([[:alpha:]]+://)?(([[:alnum:]]+)(:[^:@]+)?@)?([^:]+)(:[[:digit:]]+)?(/.*)?"; + regex_t re; + regmatch_t pmatch[NMATCH]; + + if (regcomp(&re, pattern, REG_EXTENDED)) { + return 0; + } + + if (regexec(&re, param, NMATCH, pmatch, 0) == REG_NOMATCH) { + regfree(&re); + return 0; + } + + /* Match 0 is always the whole string (assuming regexec matched anything) + * so skip it. Then, these indices are just the number of the starting + * paren in pattern above. Make sure to change these whenever changing + * the pattern. + */ + if (pmatch[3].rm_so != -1) + *user = + strndup(param + pmatch[3].rm_so, + pmatch[3].rm_eo - pmatch[3].rm_so); + + /* Skip the leading colon. */ + if (pmatch[4].rm_so != -1) + *password = + strndup(param + pmatch[4].rm_so + 1, + pmatch[4].rm_eo - pmatch[4].rm_so - 1); + + if (pmatch[5].rm_so != -1) + *host = + strndup(param + pmatch[5].rm_so, + pmatch[5].rm_eo - pmatch[5].rm_so); + + /* Skip the leading colon. */ + if (pmatch[6].rm_so != -1) + *port = + strndup(param + pmatch[6].rm_so + 1, + pmatch[6].rm_eo - pmatch[6].rm_so - 1); + + regfree(&re); + return 1; } int urlinstTransfer(struct loaderData_s *loaderData, struct iurlinfo *ui, - char **extraHeaders, char *dest) { - struct progressCBdata *cb_data; - CURL *curl = NULL; - CURLcode status; - struct curl_slist *headers = NULL; - char *version; - FILE *f = NULL; - - logMessage(INFO, "transferring %s", ui->url); - - f = fopen(dest, "w"); - - /* Initialize libcurl */ - curl_global_init(CURL_GLOBAL_SSL); - curl = curl_easy_init(); - - checked_asprintf(&version, "anaconda/%s", VERSION); - - curl_easy_setopt(curl, CURLOPT_USERAGENT, version); - curl_easy_setopt(curl, CURLOPT_URL, ui->url); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, f); - - /* If a proxy was provided, add the options for that now. */ - if (loaderData->proxy && strcmp(loaderData->proxy, "")) { - curl_easy_setopt(curl, CURLOPT_PROXY, loaderData->proxy); - - if (loaderData->proxyPort && strcmp(loaderData->proxyPort, "")) - curl_easy_setopt(curl, CURLOPT_PROXYPORT, - strtol(loaderData->proxyPort, NULL, 10)); - - if (loaderData->proxyUser && strcmp(loaderData->proxyUser, "")) - curl_easy_setopt(curl, CURLOPT_PROXYUSERNAME, - loaderData->proxyUser); - - if (loaderData->proxyPassword && strcmp(loaderData->proxyPassword, "")) - curl_easy_setopt(curl, CURLOPT_PROXYPASSWORD, - loaderData->proxyPassword); - } - - if (extraHeaders) { - int i; - for (i = 0; extraHeaders[i] != NULL; i++) { - headers = curl_slist_append(headers, extraHeaders[i]); - } - - curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); - } - - /* Only set up the progress bar if we've got a UI to display it. */ - if (FL_CMDLINE(flags)) { - printf("%s %s...\n", _("Retrieving"), ui->url); - } else { - char *filename; - - filename = strrchr(ui->url, '/'); - if (!filename) - filename = ui->url; - - cb_data = winProgressBar(70, 5, _("Retrieving"), "%s %s...", _("Retrieving"), filename); - - curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0); - curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, progress_cb); - curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, cb_data); - } - - /* Finally, do the transfer. */ - status = curl_easy_perform(curl); - if (status) - logMessage(ERROR, "Error downloading %s: %s", ui->url, curl_easy_strerror(status)); - - if (!FL_CMDLINE(flags)) - newtPopWindow(); - - if (headers) - curl_slist_free_all(headers); - - fclose(f); - free(version); - - curl_easy_cleanup(curl); - curl_global_cleanup(); - - return status; + char **extraHeaders, char *dest) +{ + struct progressCBdata *cb_data; + CURL *curl = NULL; + CURLcode status; + struct curl_slist *headers = NULL; + char *version; + FILE *f = NULL; + + logMessage(INFO, "transferring %s", ui->url); + + f = fopen(dest, "w"); + + /* Initialize libcurl */ + curl_global_init(CURL_GLOBAL_SSL); + curl = curl_easy_init(); + + checked_asprintf(&version, "anaconda/%s", VERSION); + + curl_easy_setopt(curl, CURLOPT_USERAGENT, version); + curl_easy_setopt(curl, CURLOPT_URL, ui->url); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, f); + + /* If a proxy was provided, add the options for that now. */ + if (loaderData->proxy && strcmp(loaderData->proxy, "")) { + curl_easy_setopt(curl, CURLOPT_PROXY, loaderData->proxy); + + if (loaderData->proxyPort && strcmp(loaderData->proxyPort, "")) + curl_easy_setopt(curl, CURLOPT_PROXYPORT, + strtol(loaderData->proxyPort, NULL, + 10)); + + if (loaderData->proxyUser && strcmp(loaderData->proxyUser, "")) + curl_easy_setopt(curl, CURLOPT_PROXYUSERNAME, + loaderData->proxyUser); + + if (loaderData->proxyPassword + && strcmp(loaderData->proxyPassword, "")) + curl_easy_setopt(curl, CURLOPT_PROXYPASSWORD, + loaderData->proxyPassword); + } + + if (extraHeaders) { + int i; + for (i = 0; extraHeaders[i] != NULL; i++) { + headers = curl_slist_append(headers, extraHeaders[i]); + } + + curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); + } + + /* Only set up the progress bar if we've got a UI to display it. */ + if (FL_CMDLINE(flags)) { + printf("%s %s...\n", _("Retrieving"), ui->url); + } else { + char *filename; + + filename = strrchr(ui->url, '/'); + if (!filename) + filename = ui->url; + + cb_data = + winProgressBar(70, 5, _("Retrieving"), "%s %s...", + _("Retrieving"), filename); + + curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0); + curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, progress_cb); + curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, cb_data); + } + + /* Finally, do the transfer. */ + status = curl_easy_perform(curl); + if (status) + logMessage(ERROR, "Error downloading %s: %s", ui->url, + curl_easy_strerror(status)); + + if (!FL_CMDLINE(flags)) + newtPopWindow(); + + if (headers) + curl_slist_free_all(headers); + + fclose(f); + free(version); + + curl_easy_cleanup(curl); + curl_global_cleanup(); + + return status; } -char * addrToIp(char * hostname) { - struct in_addr ad; - struct in6_addr ad6; - char *ret; - struct hostent *host; - - if ((ret = malloc(INET6_ADDRSTRLEN+1)) == 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 ((host = gethostbyname(hostname)) != NULL) - return host->h_name; - else - return NULL; +char *addrToIp(char *hostname) +{ + struct in_addr ad; + struct in6_addr ad6; + char *ret; + struct hostent *host; + + if ((ret = malloc(INET6_ADDRSTRLEN + 1)) == 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 ((host = gethostbyname(hostname)) != NULL) + return host->h_name; + else + return NULL; } -static void setProxySensitivity(newtComponent co, void *dptr) { - int i; +static void setProxySensitivity(newtComponent co, void *dptr) +{ + int i; - /* It's 4 because there are four entry boxes in the proxy grid. Lame. */ - for (i = 0; i < 4; i++) { - newtEntrySetFlags(*((newtComponent *) dptr), NEWT_FLAG_DISABLED, - NEWT_FLAGS_TOGGLE); - dptr += sizeof(newtComponent); - } + /* It's 4 because there are four entry boxes in the proxy grid. Lame. */ + for (i = 0; i < 4; i++) { + newtEntrySetFlags(*((newtComponent *) dptr), NEWT_FLAG_DISABLED, + NEWT_FLAGS_TOGGLE); + dptr += sizeof(newtComponent); + } - return; + return; } -int urlMainSetupPanel(struct loaderData_s *loaderData, struct iurlinfo * ui) { - newtComponent form, okay, cancel, urlEntry, proxyCheckbox; - newtComponent proxyEntries[4]; - newtComponent answer, text; - char enableProxy; - char *url = "", *proxy = "", *proxyPort = "", *proxyUser = "", *proxyPassword = ""; - char * reflowedText = NULL; - int width, height; - newtGrid buttons, grid, proxyGrid; - char * buf = NULL; - - /* Populate the UI with whatever initial value we've got. */ - if (ui && ui->url) - url = ui->url; - - if (loaderData->proxy) - proxy = loaderData->proxy; - - if (loaderData->proxyPort) - proxyPort = loaderData->proxyPort; - - if (loaderData->proxyUser) - proxyUser = loaderData->proxyUser; - - if (loaderData->proxyPassword) - proxyPassword = loaderData->proxyPassword; - - buttons = newtButtonBar(_("OK"), &okay, _("Back"), &cancel, NULL); - - checked_asprintf(&buf, - _("Please enter the URL containing the %s installation image on your server."), - getProductName()); - - reflowedText = newtReflowText(buf, 47, 5, 5, &width, &height); - free(buf); - - text = newtTextbox(-1, -1, width, height, NEWT_TEXTBOX_WRAP); - newtTextboxSetText(text, reflowedText); - free(reflowedText); - - urlEntry = newtEntry(22, 8, url, 60, (const char **) &url, - NEWT_ENTRY_SCROLL); - - /* If we've been provided with proxy settings already, enable the proxy - * grid. This will make sure all the fields get filled in, too. - */ - enableProxy = loaderData->proxy != NULL && strcmp("", loaderData->proxy) ? '*' : ' '; - - proxyCheckbox = newtCheckbox(-1, -1, _("Enable HTTP proxy"), enableProxy, - NULL, &enableProxy); - newtComponentAddCallback(proxyCheckbox, setProxySensitivity, &proxyEntries); - - proxyEntries[0] = newtEntry(-1, -1, proxy, 35, (const char **) &proxy, NEWT_FLAG_SCROLL); - proxyEntries[1] = newtEntry(-1, -1, proxyPort, 5, (const char **) &proxyPort, 0); - proxyEntries[2] = newtEntry(-1, -1, proxyUser, 15, (const char **) &proxyUser, NEWT_FLAG_SCROLL); - proxyEntries[3] = newtEntry(-1, -1, proxyPassword, 15, (const char **) &proxyPassword, NEWT_FLAG_SCROLL|NEWT_FLAG_PASSWORD); - - /* Set the initial proxy grid sensitivity to match. */ - if (enableProxy == ' ') - setProxySensitivity(proxyCheckbox, proxyEntries); - - proxyGrid = newtCreateGrid(2, 4); - newtGridSetField(proxyGrid, 0, 0, NEWT_GRID_COMPONENT, - newtLabel(-1, -1, _("Proxy URL")), - 0, 0, 0, 0, 0, NEWT_ANCHOR_LEFT); - newtGridSetField(proxyGrid, 1, 0, NEWT_GRID_COMPONENT, proxyEntries[0], - 0, 0, 0, 0, 0, NEWT_ANCHOR_LEFT); - newtGridSetField(proxyGrid, 0, 1, NEWT_GRID_COMPONENT, - newtLabel(-1, -1, _("Port")), - 0, 0, 0, 0, 0, NEWT_ANCHOR_LEFT); - newtGridSetField(proxyGrid, 1, 1, NEWT_GRID_COMPONENT, proxyEntries[1], - 0, 0, 0, 0, 0, NEWT_ANCHOR_LEFT); - newtGridSetField(proxyGrid, 0, 2, NEWT_GRID_COMPONENT, - newtLabel(-1, -1, _("Username")), - 0, 0, 0, 1, 0, NEWT_ANCHOR_LEFT); - newtGridSetField(proxyGrid, 1, 2, NEWT_GRID_COMPONENT, proxyEntries[2], - 0, 0, 0, 1, 0, NEWT_ANCHOR_LEFT); - newtGridSetField(proxyGrid, 0, 3, NEWT_GRID_COMPONENT, - newtLabel(-1, -1, _("Password")), - 0, 0, 0, 1, 0, NEWT_ANCHOR_LEFT); - newtGridSetField(proxyGrid, 1, 3, NEWT_GRID_COMPONENT, proxyEntries[3], - 0, 0, 0, 1, 0, NEWT_ANCHOR_LEFT); - - grid = newtCreateGrid(1, 5); - newtGridSetField(grid, 0, 0, NEWT_GRID_COMPONENT, text, - 0, 0, 0, 1, 0, 0); - newtGridSetField(grid, 0, 1, NEWT_GRID_COMPONENT, urlEntry, - 0, 0, 0, 1, 0, 0); - newtGridSetField(grid, 0, 2, NEWT_GRID_COMPONENT, proxyCheckbox, - 0, 0, 0, 1, 0, NEWT_ANCHOR_LEFT); - newtGridSetField(grid, 0, 3, NEWT_GRID_SUBGRID, proxyGrid, - 0, 0, 0, 0, 0, NEWT_GRID_FLAG_GROWX); - newtGridSetField(grid, 0, 4, NEWT_GRID_SUBGRID, buttons, - 0, 0, 0, 0, 0, NEWT_GRID_FLAG_GROWX); - - form = newtForm(NULL, NULL, 0); - newtGridAddComponentsToForm(grid, form, 1); - newtGridWrappedWindow(grid, _("URL Setup")); - newtGridFree(grid, 1); - - do { - answer = newtRunForm(form); - if (answer != cancel) { - if (!strlen(url)) { - newtWinMessage(_("Error"), _("OK"), - _("You must enter a URL.")); - continue; - } - - if (strncmp(url, "http", 4) && strncmp(url, "ftp://", 6)) { - newtWinMessage(_("Error"), _("OK"), - _("URL must be either an ftp or http URL")); - continue; - } - - ui->url = strdup(url); - - if (enableProxy == '*') { - loaderData->proxy = strdup(proxy); - loaderData->proxyPort = strdup(proxyPort); - loaderData->proxyUser = strdup(proxyUser); - loaderData->proxyPassword = strdup(proxyPassword); - } else { - loaderData->proxy = ""; - loaderData->proxyPort = ""; - loaderData->proxyUser = ""; - loaderData->proxyPassword = ""; - } - - /* FIXME: add back in hostname checking */ - } - - break; - } while (1); - - if (answer == cancel) { - newtFormDestroy(form); - newtPopWindow(); - - return LOADER_BACK; - } - - newtFormDestroy(form); - newtPopWindow(); - - return 0; +int urlMainSetupPanel(struct loaderData_s *loaderData, struct iurlinfo *ui) +{ + newtComponent form, okay, cancel, urlEntry, proxyCheckbox; + newtComponent proxyEntries[4]; + newtComponent answer, text; + char enableProxy; + char *url = "", *proxy = "", *proxyPort = "", *proxyUser = + "", *proxyPassword = ""; + char *reflowedText = NULL; + int width, height; + newtGrid buttons, grid, proxyGrid; + char *buf = NULL; + + /* Populate the UI with whatever initial value we've got. */ + if (ui && ui->url) + url = ui->url; + + if (loaderData->proxy) + proxy = loaderData->proxy; + + if (loaderData->proxyPort) + proxyPort = loaderData->proxyPort; + + if (loaderData->proxyUser) + proxyUser = loaderData->proxyUser; + + if (loaderData->proxyPassword) + proxyPassword = loaderData->proxyPassword; + + buttons = newtButtonBar(_("OK"), &okay, _("Back"), &cancel, NULL); + + checked_asprintf(&buf, + _ + ("Please enter the URL containing the %s installation image on your server."), + getProductName()); + + reflowedText = newtReflowText(buf, 47, 5, 5, &width, &height); + free(buf); + + text = newtTextbox(-1, -1, width, height, NEWT_TEXTBOX_WRAP); + newtTextboxSetText(text, reflowedText); + free(reflowedText); + + urlEntry = newtEntry(22, 8, url, 60, (const char **)&url, + NEWT_ENTRY_SCROLL); + + /* If we've been provided with proxy settings already, enable the proxy + * grid. This will make sure all the fields get filled in, too. + */ + enableProxy = loaderData->proxy != NULL + && strcmp("", loaderData->proxy) ? '*' : ' '; + + proxyCheckbox = + newtCheckbox(-1, -1, _("Enable HTTP proxy"), enableProxy, NULL, + &enableProxy); + newtComponentAddCallback(proxyCheckbox, setProxySensitivity, + &proxyEntries); + + proxyEntries[0] = + newtEntry(-1, -1, proxy, 35, (const char **)&proxy, + NEWT_FLAG_SCROLL); + proxyEntries[1] = + newtEntry(-1, -1, proxyPort, 5, (const char **)&proxyPort, 0); + proxyEntries[2] = + newtEntry(-1, -1, proxyUser, 15, (const char **)&proxyUser, + NEWT_FLAG_SCROLL); + proxyEntries[3] = + newtEntry(-1, -1, proxyPassword, 15, (const char **)&proxyPassword, + NEWT_FLAG_SCROLL | NEWT_FLAG_PASSWORD); + + /* Set the initial proxy grid sensitivity to match. */ + if (enableProxy == ' ') + setProxySensitivity(proxyCheckbox, proxyEntries); + + proxyGrid = newtCreateGrid(2, 4); + newtGridSetField(proxyGrid, 0, 0, NEWT_GRID_COMPONENT, + newtLabel(-1, -1, _("Proxy URL")), + 0, 0, 0, 0, 0, NEWT_ANCHOR_LEFT); + newtGridSetField(proxyGrid, 1, 0, NEWT_GRID_COMPONENT, proxyEntries[0], + 0, 0, 0, 0, 0, NEWT_ANCHOR_LEFT); + newtGridSetField(proxyGrid, 0, 1, NEWT_GRID_COMPONENT, + newtLabel(-1, -1, _("Port")), + 0, 0, 0, 0, 0, NEWT_ANCHOR_LEFT); + newtGridSetField(proxyGrid, 1, 1, NEWT_GRID_COMPONENT, proxyEntries[1], + 0, 0, 0, 0, 0, NEWT_ANCHOR_LEFT); + newtGridSetField(proxyGrid, 0, 2, NEWT_GRID_COMPONENT, + newtLabel(-1, -1, _("Username")), + 0, 0, 0, 1, 0, NEWT_ANCHOR_LEFT); + newtGridSetField(proxyGrid, 1, 2, NEWT_GRID_COMPONENT, proxyEntries[2], + 0, 0, 0, 1, 0, NEWT_ANCHOR_LEFT); + newtGridSetField(proxyGrid, 0, 3, NEWT_GRID_COMPONENT, + newtLabel(-1, -1, _("Password")), + 0, 0, 0, 1, 0, NEWT_ANCHOR_LEFT); + newtGridSetField(proxyGrid, 1, 3, NEWT_GRID_COMPONENT, proxyEntries[3], + 0, 0, 0, 1, 0, NEWT_ANCHOR_LEFT); + + grid = newtCreateGrid(1, 5); + newtGridSetField(grid, 0, 0, NEWT_GRID_COMPONENT, text, + 0, 0, 0, 1, 0, 0); + newtGridSetField(grid, 0, 1, NEWT_GRID_COMPONENT, urlEntry, + 0, 0, 0, 1, 0, 0); + newtGridSetField(grid, 0, 2, NEWT_GRID_COMPONENT, proxyCheckbox, + 0, 0, 0, 1, 0, NEWT_ANCHOR_LEFT); + newtGridSetField(grid, 0, 3, NEWT_GRID_SUBGRID, proxyGrid, + 0, 0, 0, 0, 0, NEWT_GRID_FLAG_GROWX); + newtGridSetField(grid, 0, 4, NEWT_GRID_SUBGRID, buttons, + 0, 0, 0, 0, 0, NEWT_GRID_FLAG_GROWX); + + form = newtForm(NULL, NULL, 0); + newtGridAddComponentsToForm(grid, form, 1); + newtGridWrappedWindow(grid, _("URL Setup")); + newtGridFree(grid, 1); + + do { + answer = newtRunForm(form); + if (answer != cancel) { + if (!strlen(url)) { + newtWinMessage(_("Error"), _("OK"), + _("You must enter a URL.")); + continue; + } + + if (strncmp(url, "http", 4) + && strncmp(url, "ftp://", 6)) { + newtWinMessage(_("Error"), _("OK"), + _ + ("URL must be either an ftp or http URL")); + continue; + } + + ui->url = strdup(url); + + if (enableProxy == '*') { + loaderData->proxy = strdup(proxy); + loaderData->proxyPort = strdup(proxyPort); + loaderData->proxyUser = strdup(proxyUser); + loaderData->proxyPassword = + strdup(proxyPassword); + } else { + loaderData->proxy = ""; + loaderData->proxyPort = ""; + loaderData->proxyUser = ""; + loaderData->proxyPassword = ""; + } + + /* FIXME: add back in hostname checking */ + } + + break; + } while (1); + + if (answer == cancel) { + newtFormDestroy(form); + newtPopWindow(); + + return LOADER_BACK; + } + + newtFormDestroy(form); + newtPopWindow(); + + return 0; } /* vim:set sw=8 noet */ diff --git a/loader/urls.h b/loader/urls.h index 91739d0..df77546 100644 --- a/loader/urls.h +++ b/loader/urls.h @@ -24,14 +24,14 @@ #include "windows.h" struct iurlinfo { - char * url; + char *url; }; int splitProxyParam(char *param, char **user, char **password, char **host, - char **port); -int urlMainSetupPanel(struct loaderData_s *loaderData, struct iurlinfo * ui); + char **port); +int urlMainSetupPanel(struct loaderData_s *loaderData, struct iurlinfo *ui); int urlinstTransfer(struct loaderData_s *loaderData, struct iurlinfo *ui, - char **extraHeaders, char *dest); + char **extraHeaders, char *dest); #endif diff --git a/loader/windows.c b/loader/windows.c index 0dfdd48..9cd803c 100644 --- a/loader/windows.c +++ b/loader/windows.c @@ -34,86 +34,90 @@ #include "log.h" #include "windows.h" -void winStatus(int width, int height, char * title, char * text, ...) { - newtComponent t, f; - char * buf = NULL; - va_list args; +void winStatus(int width, int height, char *title, char *text, ...) +{ + newtComponent t, f; + char *buf = NULL; + va_list args; - va_start(args, text); + va_start(args, text); - if (vasprintf(&buf, text, args) != -1) { - newtCenteredWindow(width, height, title); + if (vasprintf(&buf, text, args) != -1) { + newtCenteredWindow(width, height, title); - t = newtTextbox(1, 1, width - 2, height - 2, NEWT_TEXTBOX_WRAP); - newtTextboxSetText(t, buf); - f = newtForm(NULL, NULL, 0); + t = newtTextbox(1, 1, width - 2, height - 2, NEWT_TEXTBOX_WRAP); + newtTextboxSetText(t, buf); + f = newtForm(NULL, NULL, 0); - free(buf); + free(buf); - newtFormAddComponent(f, t); + newtFormAddComponent(f, t); - newtDrawForm(f); - newtRefresh(); - newtFormDestroy(f); - } + newtDrawForm(f); + newtRefresh(); + newtFormDestroy(f); + } - va_end(args); + va_end(args); } - -void scsiWindow(const char * driver) { - winStatus(40, 3, _("Loading SCSI driver"), - _("Loading %s driver"), driver); +void scsiWindow(const char *driver) +{ + winStatus(40, 3, _("Loading SCSI driver"), + _("Loading %s driver"), driver); } -void progressCallback(void *pbdata, long long pos, long long total) { - struct progressCBdata *data = pbdata; - char tickmark[2] = "-"; - char *ticks = "-\\|/"; - int x = ceil(pos * 100.0 / total); +void progressCallback(void *pbdata, long long pos, long long total) +{ + struct progressCBdata *data = pbdata; + char tickmark[2] = "-"; + char *ticks = "-\\|/"; + int x = ceil(pos * 100.0 / total); - newtScaleSet(data->scale, x); - *tickmark = ticks[x % 4]; + newtScaleSet(data->scale, x); + *tickmark = ticks[x % 4]; - newtLabelSetText(data->label, tickmark); - newtRefresh(); + newtLabelSetText(data->label, tickmark); + newtRefresh(); } -struct progressCBdata *winProgressBar(int width, int height, char *title, char *text, ...) { - struct progressCBdata *data; - char *buf = NULL; - va_list args; - int llen; - newtComponent t, f, scale, label; - - va_start(args, text); - - if (vasprintf(&buf, text, args) != -1) { - va_end(args); - newtCenteredWindow(width, height, title); - t = newtTextbox(1, 1, width - 2, height - 2, NEWT_TEXTBOX_WRAP); - newtTextboxSetText(t, buf); - llen = strlen(buf); - free(buf); - label = newtLabel(llen + 1, 1, "-"); - f = newtForm(NULL, NULL, 0); - newtFormAddComponent(f, t); - scale = newtScale(3, 3, width - 6, 100); - newtFormAddComponent(f, scale); - newtDrawForm(f); - newtRefresh(); - - if ((data = malloc(sizeof(struct progressCBdata))) == NULL) { - logMessage(ERROR, "%s: %d: %m", __func__, __LINE__); - abort(); - } - - data->scale = scale; - data->label = label; - return data; - } - - return NULL; +struct progressCBdata *winProgressBar(int width, int height, char *title, + char *text, ...) +{ + struct progressCBdata *data; + char *buf = NULL; + va_list args; + int llen; + newtComponent t, f, scale, label; + + va_start(args, text); + + if (vasprintf(&buf, text, args) != -1) { + va_end(args); + newtCenteredWindow(width, height, title); + t = newtTextbox(1, 1, width - 2, height - 2, NEWT_TEXTBOX_WRAP); + newtTextboxSetText(t, buf); + llen = strlen(buf); + free(buf); + label = newtLabel(llen + 1, 1, "-"); + f = newtForm(NULL, NULL, 0); + newtFormAddComponent(f, t); + scale = newtScale(3, 3, width - 6, 100); + newtFormAddComponent(f, scale); + newtDrawForm(f); + newtRefresh(); + + if ((data = malloc(sizeof(struct progressCBdata))) == NULL) { + logMessage(ERROR, "%s: %d: %m", __func__, __LINE__); + abort(); + } + + data->scale = scale; + data->label = label; + return data; + } + + return NULL; } /* vim:set sw=8 noet */ diff --git a/loader/windows.h b/loader/windows.h index 7499e41..7ca55cb 100644 --- a/loader/windows.h +++ b/loader/windows.h @@ -24,8 +24,8 @@ #include "lang.h" -void winStatus(int width, int height, char * title, char * text, ...); -void scsiWindow(const char * driver); +void winStatus(int width, int height, char *title, char *text, ...); +void scsiWindow(const char *driver); #define errorWindow(String) \ newtWinMessage(_("Error"), _("OK"), String, strerror (errno)); @@ -33,12 +33,13 @@ void scsiWindow(const char * driver); typedef void (*progressCB) (void *pbdata, long long offset, long long total); struct progressCBdata { - newtComponent scale; - newtComponent label; + newtComponent scale; + newtComponent label; }; void progressCallback(void *pbdata, long long pos, long long total); -struct progressCBdata *winProgressBar(int width, int height, char *title, char *text, ...); +struct progressCBdata *winProgressBar(int width, int height, char *title, + char *text, ...); #endif /* _WINDOWS_H_ */ diff --git a/mini-wm.c b/mini-wm.c index 7e7f048..ee8f459 100644 --- a/mini-wm.c +++ b/mini-wm.c @@ -27,99 +27,92 @@ #include <gtk/gtk.h> #include <X11/extensions/Xcomposite.h> -static gboolean -is_focusable (Window window) +static gboolean is_focusable(Window window) { - Display *xdisplay = GDK_DISPLAY (); - XWindowAttributes xwa; - gboolean result = FALSE; - - gdk_error_trap_push (); - if (XGetWindowAttributes (xdisplay, window, &xwa)) - { - if (!xwa.override_redirect && xwa.map_state == IsViewable) - result = TRUE; - } - gdk_error_trap_pop (); - - return result; + Display *xdisplay = GDK_DISPLAY(); + XWindowAttributes xwa; + gboolean result = FALSE; + + gdk_error_trap_push(); + if (XGetWindowAttributes(xdisplay, window, &xwa)) { + if (!xwa.override_redirect && xwa.map_state == IsViewable) + result = TRUE; + } + gdk_error_trap_pop(); + + return result; } -static void -check_focus () +static void check_focus() { - Window *children; - unsigned int n_children; - Window root; - Window parent; - - XQueryTree (GDK_DISPLAY(), GDK_ROOT_WINDOW(), - &root, &parent, &children, &n_children); - - while (n_children > 0) { - if (is_focusable (children[n_children-1])) { - gdk_error_trap_push (); - XSetInputFocus (GDK_DISPLAY(), children[n_children-1], - RevertToPointerRoot, CurrentTime); - XSync (GDK_DISPLAY(), 0); - if (gdk_error_trap_pop () == 0) - break; - } - n_children--; - } - - XFree (children); + Window *children; + unsigned int n_children; + Window root; + Window parent; + + XQueryTree(GDK_DISPLAY(), GDK_ROOT_WINDOW(), + &root, &parent, &children, &n_children); + + while (n_children > 0) { + if (is_focusable(children[n_children - 1])) { + gdk_error_trap_push(); + XSetInputFocus(GDK_DISPLAY(), children[n_children - 1], + RevertToPointerRoot, CurrentTime); + XSync(GDK_DISPLAY(), 0); + if (gdk_error_trap_pop() == 0) + break; + } + n_children--; + } + + XFree(children); } GdkFilterReturn -mini_wm_root_filter (GdkXEvent *xevent, - GdkEvent *event, - gpointer data) +mini_wm_root_filter(GdkXEvent * xevent, GdkEvent * event, gpointer data) { - XEvent *xev = xevent; - - if (xev->xany.type == MapNotify || - xev->xany.type == UnmapNotify || - xev->xany.type == ConfigureNotify || - xev->xany.type == DestroyNotify) - { - check_focus (); - } - - return GDK_FILTER_CONTINUE; + XEvent *xev = xevent; + + if (xev->xany.type == MapNotify || + xev->xany.type == UnmapNotify || + xev->xany.type == ConfigureNotify || + xev->xany.type == DestroyNotify) { + check_focus(); + } + + return GDK_FILTER_CONTINUE; } -void -mini_wm_start (void) +void mini_wm_start(void) { - XWindowAttributes attrs; + XWindowAttributes attrs; - XCompositeRedirectSubwindows (GDK_DISPLAY(), GDK_ROOT_WINDOW(), - CompositeRedirectAutomatic); + XCompositeRedirectSubwindows(GDK_DISPLAY(), GDK_ROOT_WINDOW(), + CompositeRedirectAutomatic); - XGetWindowAttributes (GDK_DISPLAY(), GDK_ROOT_WINDOW(), &attrs); - XSelectInput (GDK_DISPLAY(), GDK_ROOT_WINDOW(), - attrs.your_event_mask | SubstructureNotifyMask); + XGetWindowAttributes(GDK_DISPLAY(), GDK_ROOT_WINDOW(), &attrs); + XSelectInput(GDK_DISPLAY(), GDK_ROOT_WINDOW(), + attrs.your_event_mask | SubstructureNotifyMask); - gdk_window_add_filter (GDK_ROOT_PARENT (), mini_wm_root_filter, NULL); + gdk_window_add_filter(GDK_ROOT_PARENT(), mini_wm_root_filter, NULL); - check_focus (); + check_focus(); } -int main( int argc, - char *argv[] ) +int main(int argc, char *argv[]) { - gtk_init (&argc, &argv); + gtk_init(&argc, &argv); - mini_wm_start (); + mini_wm_start(); - /* Indicate back to anaconda that we now have established - * connection to the display. */ - if (write(1, "#", 1) == -1) abort(); + /* Indicate back to anaconda that we now have established + * connection to the display. */ + if (write(1, "#", 1) == -1) + abort(); - gtk_main(); + gtk_main(); - return(0); + return (0); } /* vim:set sw=8 noet */ diff --git a/utils/geninitrdsz.c b/utils/geninitrdsz.c index 5d5be44..7aa446f 100644 --- a/utils/geninitrdsz.c +++ b/utils/geninitrdsz.c @@ -32,33 +32,35 @@ #include <errno.h> #include <string.h> -int main(int argc,char **argv) { - unsigned int zero = 0; - int fd; - unsigned int size; - mode_t mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH; +int main(int argc, char **argv) +{ + unsigned int zero = 0; + int fd; + unsigned int size; + mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; - if (argc != 3) { - printf("Usage: %s [integer size] [output file]\n", basename(argv[0])); - printf("Example: %s 12288475 initrd.size\n", basename(argv[0])); - return 0; - } + if (argc != 3) { + printf("Usage: %s [integer size] [output file]\n", + basename(argv[0])); + printf("Example: %s 12288475 initrd.size\n", basename(argv[0])); + return 0; + } - size = htonl(atoi(argv[1])); - fd = open(argv[2], O_CREAT | O_RDWR, mode); + size = htonl(atoi(argv[1])); + fd = open(argv[2], O_CREAT | O_RDWR, mode); - if (write(fd, &zero, sizeof(int)) == -1) { - perror("writing initrd.size (zero)"); - return errno; - } + if (write(fd, &zero, sizeof(int)) == -1) { + perror("writing initrd.size (zero)"); + return errno; + } - if (write(fd, &size, sizeof(int)) == -1) { - perror("writing initrd.size (size)"); - return errno; - } + if (write(fd, &size, sizeof(int)) == -1) { + perror("writing initrd.size (size)"); + return errno; + } - close(fd); - return 0; + close(fd); + return 0; } /* vim:set sw=8 noet */ diff --git a/utils/mapshdr.c b/utils/mapshdr.c index 2408ada..0cddbad 100644 --- a/utils/mapshdr.c +++ b/utils/mapshdr.c @@ -26,36 +26,38 @@ #include "../isys/lang.h" -int main(int argc, char ** argv) { - struct kmapHeader h; - struct kmapInfo info; - int i, x; - struct stat sb; - char * chptr; - - h.magic = KMAP_MAGIC; - h.numEntries = argc - 1; - x = write(1, &h, sizeof(h)); - - for (i = 1; i < argc; i++) { - if (stat(argv[i], &sb)) { - fprintf(stderr, "stat error for %s: %s\n", argv[i], - strerror(errno)); - exit(1); +int main(int argc, char **argv) +{ + struct kmapHeader h; + struct kmapInfo info; + int i, x; + struct stat sb; + char *chptr; + + h.magic = KMAP_MAGIC; + h.numEntries = argc - 1; + x = write(1, &h, sizeof(h)); + + for (i = 1; i < argc; i++) { + if (stat(argv[i], &sb)) { + fprintf(stderr, "stat error for %s: %s\n", argv[i], + strerror(errno)); + exit(1); + } + + memset(info.name, 0, KMAP_NAMELEN); + strncpy(info.name, argv[i], KMAP_NAMELEN - 1); + + chptr = info.name + strlen(info.name) - 1; + while (*chptr != '.') + *chptr-- = '\0'; + *chptr = '\0'; + + info.size = sb.st_size; + x = write(1, &info, sizeof(info)); } - memset(info.name, 0, KMAP_NAMELEN); - strncpy(info.name, argv[i], KMAP_NAMELEN - 1); - - chptr = info.name + strlen(info.name) - 1; - while (*chptr != '.') *chptr-- = '\0'; - *chptr = '\0'; - - info.size = sb.st_size; - x = write(1, &info, sizeof(info)); - } - - return 0; + return 0; } /* vim:set sw=8 noet */ diff --git a/utils/mk-s390-cdboot.c b/utils/mk-s390-cdboot.c index d05aa98..c27f002 100644 --- a/utils/mk-s390-cdboot.c +++ b/utils/mk-s390-cdboot.c @@ -21,266 +21,300 @@ #define INITRD_START 0x0000000000800000LL #define START_PSW_ADDRESS 0x80010000 -static struct option getopt_long_options[]= { - { "image", 1, 0, 'i'}, - { "ramdisk", 1, 0, 'r'}, - { "parmfile", 1, 0, 'p'}, - { "outfile", 1, 0, 'o'}, - { "help", 0, 0, 'h'}, - {0, 0, 0, 0} +static struct option getopt_long_options[] = { + {"image", 1, 0, 'i'}, + {"ramdisk", 1, 0, 'r'}, + {"parmfile", 1, 0, 'p'}, + {"outfile", 1, 0, 'o'}, + {"help", 0, 0, 'h'}, + {0, 0, 0, 0} }; -static void usage(char *cmd) { - printf("%s [-h] [-v] -i <kernel> -r <ramdisk> -p <parmfile> -o <outfile>\n", cmd); +static void usage(char *cmd) +{ + printf + ("%s [-h] [-v] -i <kernel> -r <ramdisk> -p <parmfile> -o <outfile>\n", + cmd); } -int main (int argc, char **argv) { - char *cmd = basename(argv[0]); - FILE *fd1 = NULL; - FILE *fd2 = NULL; - FILE *fd3 = NULL; - FILE *fd4 = NULL; - char buffer[BUFFER_LEN]; - int wc, rc, oc, index; - unsigned long long initrd_start = INITRD_START; - unsigned long long initrd_size; - char *image = NULL; - char *ramdisk = NULL; - char *parmfile = NULL; - char *outfile = NULL; - int image_specified = 0; - int ramdisk_specified = 0; - int parmfile_specified = 0; - int outfile_specified = 0; - int start_psw_address = START_PSW_ADDRESS; - - opterr = 0; - while (1) { - oc = getopt_long(argc, argv, "i:r:p:o:h?", getopt_long_options, &index); - if (oc == -1) { - break; - } - - switch (oc) { - case '?': - case 'h': - usage(cmd); - exit(0); - case 'i': - image = strdup(optarg); - image_specified = 1; - break; - case 'r': - ramdisk = strdup(optarg); - ramdisk_specified = 1; - break; - case 'p': - parmfile = strdup(optarg); - parmfile_specified = 1; - break; - case 'o': - outfile = strdup(optarg); - outfile_specified = 1; - break; - default: - usage(cmd); - exit(0); - } - } - - if (!image_specified || !ramdisk_specified || - !parmfile_specified || !outfile_specified) { - usage(cmd); - exit(0); - } - - printf("Creating bootable CD-ROM image...\n"); - printf("kernel is : %s\n", image); - printf("ramdisk is : %s\n", ramdisk); - printf("parmfile is: %s\n", parmfile); - printf("outfile is : %s\n", outfile); - - if ((fd1 = fopen(outfile, "w")) == NULL) { - fprintf(stderr, "%s (%d): %s\n", __func__, __LINE__, strerror(errno)); - abort(); - } - - if ((fd2 = fopen(image, "r")) == NULL) { - fprintf(stderr, "%s (%d): %s\n", __func__, __LINE__, strerror(errno)); - abort(); - } - - if ((fd3 = fopen(ramdisk, "r")) == NULL) { - fprintf(stderr, "%s (%d): %s\n", __func__, __LINE__, strerror(errno)); - abort(); - } - - if ((fd4 = fopen(parmfile, "r")) == NULL) { - fprintf(stderr, "%s (%d): %s\n", __func__, __LINE__, strerror(errno)); - abort(); - } - - printf("writing kernel...\n"); - while (1) { - rc = fread(buffer, 1, 1, fd2); - - if (rc == 0) { - break; - } - - if (feof(fd2) || ferror(fd2)) { - fprintf(stderr, "%s (%d): %s\n", __func__, __LINE__, strerror(errno)); - abort(); - } - - wc = fwrite(buffer, 1, 1, fd1); - if (feof(fd1) || ferror(fd1)) { - fprintf(stderr, "%s (%d): %s\n", __func__, __LINE__, strerror(errno)); - abort(); - } - - if (wc != rc) { - fprintf(stderr, "could only write %i of %i bytes of kernel\n", - wc, rc); - } - } - - printf("writing initrd...\n"); - fseek(fd1, initrd_start, SEEK_SET); - while (1) { - rc = fread(buffer, 1, 1, fd3); - - if (rc == 0) { - break; - } - - if (feof(fd3) || ferror(fd3)) { - fprintf(stderr, "%s (%d): %s\n", __func__, __LINE__, strerror(errno)); - abort(); - } - - wc = fwrite(buffer, 1, 1, fd1); - if (feof(fd1) || ferror(fd1)) { - fprintf(stderr, "%s (%d): %s\n", __func__, __LINE__, strerror(errno)); - abort(); - } - - if (wc != rc) { - fprintf(stderr, "could only write %i of %i bytes of initrd\n", - wc, rc); - } - } - - if (fseek(fd3, 0, SEEK_END) == -1) { - fprintf(stderr, "%s (%d): %s\n", __func__, __LINE__, strerror(errno)); - abort(); - } - - if ((initrd_size = ftell(fd3)) == -1) { - fprintf(stderr, "%s (%d): %s\n", __func__, __LINE__, strerror(errno)); - abort(); - } - - printf("changing start PSW address to 0x%08x...\n", start_psw_address); - if (fseek(fd1, 0x4, SEEK_SET) == -1) { - fprintf(stderr, "%s (%d): %s\n", __func__, __LINE__, strerror(errno)); - abort(); - } - - wc = fwrite(&start_psw_address, 1, 4, fd1); - if (feof(fd1) || ferror(fd1)) { - fprintf(stderr, "%s (%d): %s\n", __func__, __LINE__, strerror(errno)); - abort(); - } - - if (wc != 4) { - fprintf(stderr, "could only write %i of %i bytes of PSW address\n", - wc, 4); - } - - printf("writing initrd address and size...\n"); - printf("INITRD start: 0x%016llx\n", initrd_start); - printf("INITRD size : 0x%016llx\n", initrd_size); - - if (fseek(fd1, 0x10408, SEEK_SET) == -1) { - fprintf(stderr, "%s (%d): %s\n", __func__, __LINE__, strerror(errno)); - abort(); - } - - wc = fwrite(&initrd_start, 1, 8, fd1); - if (feof(fd1) || ferror(fd1)) { - fprintf(stderr, "%s (%d): %s\n", __func__, __LINE__, strerror(errno)); - abort(); - } - - if (wc != 8) { - fprintf(stderr, "could only write %i of %i bytes of INITRD start\n", - wc, 8); - } - - if (fseek(fd1, 0x10410, SEEK_SET) == -1) { - fprintf(stderr, "%s (%d): %s\n", __func__, __LINE__, strerror(errno)); - abort(); - } - - wc = fwrite(&initrd_size, 1, 8, fd1); - if (feof(fd1) || ferror(fd1)) { - fprintf(stderr, "%s (%d): %s\n", __func__, __LINE__, strerror(errno)); - abort(); - } - - if (wc != 8) { - fprintf(stderr, "could only write %i of %i bytes of INITRD size\n", - wc, 8); - } - - printf("writing parmfile...\n"); - if (fseek(fd1, 0x10480, SEEK_SET) == -1) { - fprintf(stderr, "%s (%d): %s\n", __func__, __LINE__, strerror(errno)); - abort(); - } - - while (1) { - rc = fread(buffer, 1, 1, fd4); - - if (rc == 0) { - break; - } - - if (feof(fd4) || ferror(fd4)) { - fprintf(stderr, "%s (%d): %s\n", __func__, __LINE__, strerror(errno)); - abort(); - } - - wc = fwrite(buffer, 1, 1, fd1); - if (feof(fd1) || ferror(fd1)) { - fprintf(stderr, "%s (%d): %s\n", __func__, __LINE__, strerror(errno)); - abort(); - } - - if (wc != 1) { - fprintf(stderr, "could only write %i of %i bytes of parmfile\n", - wc, 1); - } - } - - if (fclose(fd1) == EOF) { - fprintf(stderr, "%s (%d): %s\n", __func__, __LINE__, strerror(errno)); - } - - if (fclose(fd2) == EOF) { - fprintf(stderr, "%s (%d): %s\n", __func__, __LINE__, strerror(errno)); - } - - if (fclose(fd3) == EOF) { - fprintf(stderr, "%s (%d): %s\n", __func__, __LINE__, strerror(errno)); - } - - if (fclose(fd4) == EOF) { - fprintf(stderr, "%s (%d): %s\n", __func__, __LINE__, strerror(errno)); - } - - return EXIT_SUCCESS; +int main(int argc, char **argv) +{ + char *cmd = basename(argv[0]); + FILE *fd1 = NULL; + FILE *fd2 = NULL; + FILE *fd3 = NULL; + FILE *fd4 = NULL; + char buffer[BUFFER_LEN]; + int wc, rc, oc, index; + unsigned long long initrd_start = INITRD_START; + unsigned long long initrd_size; + char *image = NULL; + char *ramdisk = NULL; + char *parmfile = NULL; + char *outfile = NULL; + int image_specified = 0; + int ramdisk_specified = 0; + int parmfile_specified = 0; + int outfile_specified = 0; + int start_psw_address = START_PSW_ADDRESS; + + opterr = 0; + while (1) { + oc = getopt_long(argc, argv, "i:r:p:o:h?", getopt_long_options, + &index); + if (oc == -1) { + break; + } + + switch (oc) { + case '?': + case 'h': + usage(cmd); + exit(0); + case 'i': + image = strdup(optarg); + image_specified = 1; + break; + case 'r': + ramdisk = strdup(optarg); + ramdisk_specified = 1; + break; + case 'p': + parmfile = strdup(optarg); + parmfile_specified = 1; + break; + case 'o': + outfile = strdup(optarg); + outfile_specified = 1; + break; + default: + usage(cmd); + exit(0); + } + } + + if (!image_specified || !ramdisk_specified || + !parmfile_specified || !outfile_specified) { + usage(cmd); + exit(0); + } + + printf("Creating bootable CD-ROM image...\n"); + printf("kernel is : %s\n", image); + printf("ramdisk is : %s\n", ramdisk); + printf("parmfile is: %s\n", parmfile); + printf("outfile is : %s\n", outfile); + + if ((fd1 = fopen(outfile, "w")) == NULL) { + fprintf(stderr, "%s (%d): %s\n", __func__, __LINE__, + strerror(errno)); + abort(); + } + + if ((fd2 = fopen(image, "r")) == NULL) { + fprintf(stderr, "%s (%d): %s\n", __func__, __LINE__, + strerror(errno)); + abort(); + } + + if ((fd3 = fopen(ramdisk, "r")) == NULL) { + fprintf(stderr, "%s (%d): %s\n", __func__, __LINE__, + strerror(errno)); + abort(); + } + + if ((fd4 = fopen(parmfile, "r")) == NULL) { + fprintf(stderr, "%s (%d): %s\n", __func__, __LINE__, + strerror(errno)); + abort(); + } + + printf("writing kernel...\n"); + while (1) { + rc = fread(buffer, 1, 1, fd2); + + if (rc == 0) { + break; + } + + if (feof(fd2) || ferror(fd2)) { + fprintf(stderr, "%s (%d): %s\n", __func__, __LINE__, + strerror(errno)); + abort(); + } + + wc = fwrite(buffer, 1, 1, fd1); + if (feof(fd1) || ferror(fd1)) { + fprintf(stderr, "%s (%d): %s\n", __func__, __LINE__, + strerror(errno)); + abort(); + } + + if (wc != rc) { + fprintf(stderr, + "could only write %i of %i bytes of kernel\n", + wc, rc); + } + } + + printf("writing initrd...\n"); + fseek(fd1, initrd_start, SEEK_SET); + while (1) { + rc = fread(buffer, 1, 1, fd3); + + if (rc == 0) { + break; + } + + if (feof(fd3) || ferror(fd3)) { + fprintf(stderr, "%s (%d): %s\n", __func__, __LINE__, + strerror(errno)); + abort(); + } + + wc = fwrite(buffer, 1, 1, fd1); + if (feof(fd1) || ferror(fd1)) { + fprintf(stderr, "%s (%d): %s\n", __func__, __LINE__, + strerror(errno)); + abort(); + } + + if (wc != rc) { + fprintf(stderr, + "could only write %i of %i bytes of initrd\n", + wc, rc); + } + } + + if (fseek(fd3, 0, SEEK_END) == -1) { + fprintf(stderr, "%s (%d): %s\n", __func__, __LINE__, + strerror(errno)); + abort(); + } + + if ((initrd_size = ftell(fd3)) == -1) { + fprintf(stderr, "%s (%d): %s\n", __func__, __LINE__, + strerror(errno)); + abort(); + } + + printf("changing start PSW address to 0x%08x...\n", start_psw_address); + if (fseek(fd1, 0x4, SEEK_SET) == -1) { + fprintf(stderr, "%s (%d): %s\n", __func__, __LINE__, + strerror(errno)); + abort(); + } + + wc = fwrite(&start_psw_address, 1, 4, fd1); + if (feof(fd1) || ferror(fd1)) { + fprintf(stderr, "%s (%d): %s\n", __func__, __LINE__, + strerror(errno)); + abort(); + } + + if (wc != 4) { + fprintf(stderr, + "could only write %i of %i bytes of PSW address\n", wc, + 4); + } + + printf("writing initrd address and size...\n"); + printf("INITRD start: 0x%016llx\n", initrd_start); + printf("INITRD size : 0x%016llx\n", initrd_size); + + if (fseek(fd1, 0x10408, SEEK_SET) == -1) { + fprintf(stderr, "%s (%d): %s\n", __func__, __LINE__, + strerror(errno)); + abort(); + } + + wc = fwrite(&initrd_start, 1, 8, fd1); + if (feof(fd1) || ferror(fd1)) { + fprintf(stderr, "%s (%d): %s\n", __func__, __LINE__, + strerror(errno)); + abort(); + } + + if (wc != 8) { + fprintf(stderr, + "could only write %i of %i bytes of INITRD start\n", wc, + 8); + } + + if (fseek(fd1, 0x10410, SEEK_SET) == -1) { + fprintf(stderr, "%s (%d): %s\n", __func__, __LINE__, + strerror(errno)); + abort(); + } + + wc = fwrite(&initrd_size, 1, 8, fd1); + if (feof(fd1) || ferror(fd1)) { + fprintf(stderr, "%s (%d): %s\n", __func__, __LINE__, + strerror(errno)); + abort(); + } + + if (wc != 8) { + fprintf(stderr, + "could only write %i of %i bytes of INITRD size\n", wc, + 8); + } + + printf("writing parmfile...\n"); + if (fseek(fd1, 0x10480, SEEK_SET) == -1) { + fprintf(stderr, "%s (%d): %s\n", __func__, __LINE__, + strerror(errno)); + abort(); + } + + while (1) { + rc = fread(buffer, 1, 1, fd4); + + if (rc == 0) { + break; + } + + if (feof(fd4) || ferror(fd4)) { + fprintf(stderr, "%s (%d): %s\n", __func__, __LINE__, + strerror(errno)); + abort(); + } + + wc = fwrite(buffer, 1, 1, fd1); + if (feof(fd1) || ferror(fd1)) { + fprintf(stderr, "%s (%d): %s\n", __func__, __LINE__, + strerror(errno)); + abort(); + } + + if (wc != 1) { + fprintf(stderr, + "could only write %i of %i bytes of parmfile\n", + wc, 1); + } + } + + if (fclose(fd1) == EOF) { + fprintf(stderr, "%s (%d): %s\n", __func__, __LINE__, + strerror(errno)); + } + + if (fclose(fd2) == EOF) { + fprintf(stderr, "%s (%d): %s\n", __func__, __LINE__, + strerror(errno)); + } + + if (fclose(fd3) == EOF) { + fprintf(stderr, "%s (%d): %s\n", __func__, __LINE__, + strerror(errno)); + } + + if (fclose(fd4) == EOF) { + fprintf(stderr, "%s (%d): %s\n", __func__, __LINE__, + strerror(errno)); + } + + return EXIT_SUCCESS; } /* vim:set sw=8 noet */ diff --git a/utils/modlist.c b/utils/modlist.c index e14499a..2aad07f 100644 --- a/utils/modlist.c +++ b/utils/modlist.c @@ -25,124 +25,146 @@ #include "../isys/isys.h" #include "moduleinfo.h" -int main(int argc, char ** argv) { - GOptionContext *optCon = g_option_context_new(NULL); - GError *optErr = NULL; - gchar *modInfoFile = "/boot/module-info"; - gboolean ignoreMissing = FALSE, showModInfo = FALSE; - gchar **remaining = NULL; - enum driverMajor major; - const char * type; - const char * mod; - struct moduleInfo * list, * m; - int i, arg = 0; - moduleInfoSet mis; - struct moduleInfo * mi; - GOptionEntry optionTable[] = { - { "ignore-missing", 'I', 0, G_OPTION_ARG_NONE, &ignoreMissing, - "Ignore modules not in modinfo file for --modinfo", NULL }, - { "modinfo", 'm', 0, G_OPTION_ARG_NONE, &showModInfo, - "Give output in module-info file for listed args", NULL }, - { "modinfo-file", 'f', 0, G_OPTION_ARG_STRING, &modInfoFile, - "Module info file to use", NULL }, - { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &remaining, - NULL, NULL }, - { NULL }, - }; +int main(int argc, char **argv) +{ + GOptionContext *optCon = g_option_context_new(NULL); + GError *optErr = NULL; + gchar *modInfoFile = "/boot/module-info"; + gboolean ignoreMissing = FALSE, showModInfo = FALSE; + gchar **remaining = NULL; + enum driverMajor major; + const char *type; + const char *mod; + struct moduleInfo *list, *m; + int i, arg = 0; + moduleInfoSet mis; + struct moduleInfo *mi; + GOptionEntry optionTable[] = { + {"ignore-missing", 'I', 0, G_OPTION_ARG_NONE, &ignoreMissing, + "Ignore modules not in modinfo file for --modinfo", NULL}, + {"modinfo", 'm', 0, G_OPTION_ARG_NONE, &showModInfo, + "Give output in module-info file for listed args", NULL}, + {"modinfo-file", 'f', 0, G_OPTION_ARG_STRING, &modInfoFile, + "Module info file to use", NULL}, + {G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, + &remaining, + NULL, NULL}, + {NULL}, + }; - g_option_context_add_main_entries(optCon, optionTable, NULL); + g_option_context_add_main_entries(optCon, optionTable, NULL); - if (!g_option_context_parse(optCon, &argc, &argv, &optErr)) { - fprintf(stderr, "bad option: %s\n", optErr->message); - g_error_free(optErr); - g_option_context_free(optCon); - g_strfreev(remaining); - exit(1); - } + if (!g_option_context_parse(optCon, &argc, &argv, &optErr)) { + fprintf(stderr, "bad option: %s\n", optErr->message); + g_error_free(optErr); + g_option_context_free(optCon); + g_strfreev(remaining); + exit(1); + } - g_option_context_free(optCon); + g_option_context_free(optCon); - if (remaining == NULL) { - exit(1); - } + if (remaining == NULL) { + exit(1); + } - mis = newModuleInfoSet(); - if (readModuleInfo(modInfoFile, mis, NULL, 0)) { - fprintf(stderr, "Failed to read %s\n", modInfoFile); - exit(1); - } + mis = newModuleInfoSet(); + if (readModuleInfo(modInfoFile, mis, NULL, 0)) { + fprintf(stderr, "Failed to read %s\n", modInfoFile); + exit(1); + } - if (showModInfo) { - printf("Version 0\n"); - while ((mod = remaining[arg]) != NULL) { - mi = findModuleInfo(mis, mod); - if (mi) { - printf("%s\n", mi->moduleName); - switch (mi->major) { - case DRIVER_CDROM: printf("\tcdrom\n"); break; - case DRIVER_SCSI: printf("\tscsi\n"); break; - case DRIVER_FS: printf("\tfs\n"); break; - case DRIVER_PCMCIA: printf("\tpcmcia\n"); break; - case DRIVER_IDE: printf("\tide\n"); break; - case DRIVER_OTHER: printf("\tother\n"); break; - case DRIVER_NET: - switch (mi->minor) { - case DRIVER_MINOR_ETHERNET: printf("\teth\n"); break; - case DRIVER_MINOR_TR: printf("\ttr\n"); break; + if (showModInfo) { + printf("Version 0\n"); + while ((mod = remaining[arg]) != NULL) { + mi = findModuleInfo(mis, mod); + if (mi) { + printf("%s\n", mi->moduleName); + switch (mi->major) { + case DRIVER_CDROM: + printf("\tcdrom\n"); + break; + case DRIVER_SCSI: + printf("\tscsi\n"); + break; + case DRIVER_FS: + printf("\tfs\n"); + break; + case DRIVER_PCMCIA: + printf("\tpcmcia\n"); + break; + case DRIVER_IDE: + printf("\tide\n"); + break; + case DRIVER_OTHER: + printf("\tother\n"); + break; + case DRIVER_NET: + switch (mi->minor) { + case DRIVER_MINOR_ETHERNET: + printf("\teth\n"); + break; + case DRIVER_MINOR_TR: + printf("\ttr\n"); + break; - default: - fprintf(stderr, "unknown net minor type for %s\n", - mi->moduleName); - g_strfreev(remaining); - exit(1); - } - break; + default: + fprintf(stderr, + "unknown net minor type for %s\n", + mi->moduleName); + g_strfreev(remaining); + exit(1); + } + break; - default: - fprintf(stderr, "unknown device type for %s (%d)\n", - mi->moduleName, mi->major); - g_strfreev(remaining); - exit(1); + default: + fprintf(stderr, + "unknown device type for %s (%d)\n", + mi->moduleName, mi->major); + g_strfreev(remaining); + exit(1); + } + printf("\t\"%s\"\n", mi->description); + for (i = 0; i < mi->numArgs; i++) { + printf("\t%s \"%s\"\n", mi->args[i].arg, + mi->args[i].description); + } + } else if (!ignoreMissing) { + fprintf(stderr, "I know nothing about %s\n", + mod); + g_strfreev(remaining); + exit(1); + } + arg++; } - printf("\t\"%s\"\n", mi->description); - for (i = 0; i < mi->numArgs; i++) { - printf("\t%s \"%s\"\n", mi->args[i].arg, - mi->args[i].description); - } - } else if (!ignoreMissing) { - fprintf(stderr, "I know nothing about %s\n", mod); - g_strfreev(remaining); - exit(1); - } - arg++; - } - } else { - while ((type = remaining[arg]) != NULL) { - if (!strcasecmp(type, "scsi")) { - major = DRIVER_SCSI; - } else if (!strcasecmp(type, "net")) { - major = DRIVER_NET; - } else if (!strcasecmp(type, "fs")) { - major = DRIVER_FS; - } else if (!strcasecmp(type, "cdrom")) { - major = DRIVER_CDROM; - } else { - fprintf(stderr, "type must be one of scsi, net, fs, cdrom\n"); - g_strfreev(remaining); - exit(1); - } + } else { + while ((type = remaining[arg]) != NULL) { + if (!strcasecmp(type, "scsi")) { + major = DRIVER_SCSI; + } else if (!strcasecmp(type, "net")) { + major = DRIVER_NET; + } else if (!strcasecmp(type, "fs")) { + major = DRIVER_FS; + } else if (!strcasecmp(type, "cdrom")) { + major = DRIVER_CDROM; + } else { + fprintf(stderr, + "type must be one of scsi, net, fs, cdrom\n"); + g_strfreev(remaining); + exit(1); + } - list = getModuleList(mis, major); - for (m = list; m && m->moduleName; m++) - printf("%s\n", m->moduleName); - free(list); - arg++; + list = getModuleList(mis, major); + for (m = list; m && m->moduleName; m++) + printf("%s\n", m->moduleName); + free(list); + arg++; + } } - } - g_strfreev(remaining); - return 0; + g_strfreev(remaining); + return 0; } /* vim:set sw=8 noet */ diff --git a/utils/readmap.c b/utils/readmap.c index f570d49..7e87780 100644 --- a/utils/readmap.c +++ b/utils/readmap.c @@ -34,88 +34,92 @@ #include "../isys/lang.h" -int main(int argc, char ** argv) { - int console; - int kmap, key; - struct kbentry entry; - int keymaps[MAX_NR_KEYMAPS]; - int count = 0; - int out; - short keymap[NR_KEYS]; - int magic = KMAP_MAGIC; - int verbose = 0; - - if (argc != 2) { - printf("bad usage\n"); - exit(1); - } - - if (getenv("DEBUG") != NULL) - verbose = 1; - - memset(keymaps, 0, sizeof(keymaps)); - - console = open("/dev/tty0", O_RDWR); - if (console < 0) { - perror("open VGA+KBD"); - exit(1); - } - - for (kmap = 0; kmap < MAX_NR_KEYMAPS; kmap++) { - for (key = 0; key < NR_KEYS; key++) { - entry.kb_index = key; - entry.kb_table = kmap; - if (ioctl(console, KDGKBENT, &entry)) { - perror("ioctl failed"); +int main(int argc, char **argv) +{ + int console; + int kmap, key; + struct kbentry entry; + int keymaps[MAX_NR_KEYMAPS]; + int count = 0; + int out; + short keymap[NR_KEYS]; + int magic = KMAP_MAGIC; + int verbose = 0; + + if (argc != 2) { + printf("bad usage\n"); exit(1); - } else if (KTYP(entry.kb_value) != KT_SPEC) { - keymaps[kmap] = 1; - count++; - break; - } } - } - - if (verbose) fprintf(stderr, "found %d valid keymaps\n", count); - - if (verbose) fprintf(stderr, "creating keymap file %s\n", argv[1]); - if ((out = open(argv[1], O_WRONLY | O_CREAT | O_TRUNC, 0666)) < 1) { - perror("open keymap"); - exit(1); - } - - if (write(out, &magic, sizeof(magic)) != sizeof(magic)) { - perror("write magic"); - exit(1); - } - - if (write(out, keymaps, sizeof(keymaps)) != sizeof(keymaps)) { - perror("write header"); - exit(1); - } - - for (kmap = 0; kmap < MAX_NR_KEYMAPS; kmap++) { - if (!keymaps[kmap]) continue; - for (key = 0; key < NR_KEYS; key++) { - entry.kb_index = key; - entry.kb_table = kmap; - if (ioctl(console, KDGKBENT, &entry)) { - perror("ioctl failed"); + + if (getenv("DEBUG") != NULL) + verbose = 1; + + memset(keymaps, 0, sizeof(keymaps)); + + console = open("/dev/tty0", O_RDWR); + if (console < 0) { + perror("open VGA+KBD"); + exit(1); + } + + for (kmap = 0; kmap < MAX_NR_KEYMAPS; kmap++) { + for (key = 0; key < NR_KEYS; key++) { + entry.kb_index = key; + entry.kb_table = kmap; + if (ioctl(console, KDGKBENT, &entry)) { + perror("ioctl failed"); + exit(1); + } else if (KTYP(entry.kb_value) != KT_SPEC) { + keymaps[kmap] = 1; + count++; + break; + } + } + } + + if (verbose) + fprintf(stderr, "found %d valid keymaps\n", count); + + if (verbose) + fprintf(stderr, "creating keymap file %s\n", argv[1]); + if ((out = open(argv[1], O_WRONLY | O_CREAT | O_TRUNC, 0666)) < 1) { + perror("open keymap"); + exit(1); + } + + if (write(out, &magic, sizeof(magic)) != sizeof(magic)) { + perror("write magic"); + exit(1); + } + + if (write(out, keymaps, sizeof(keymaps)) != sizeof(keymaps)) { + perror("write header"); exit(1); - } else { - keymap[key] = entry.kb_value; - } } - if (write(out, keymap, sizeof(keymap)) != sizeof(keymap)) { - perror("write keymap"); - exit(1); + for (kmap = 0; kmap < MAX_NR_KEYMAPS; kmap++) { + if (!keymaps[kmap]) + continue; + for (key = 0; key < NR_KEYS; key++) { + entry.kb_index = key; + entry.kb_table = kmap; + if (ioctl(console, KDGKBENT, &entry)) { + perror("ioctl failed"); + exit(1); + } else { + keymap[key] = entry.kb_value; + } + } + + if (write(out, keymap, sizeof(keymap)) != sizeof(keymap)) { + perror("write keymap"); + exit(1); + } } - } - close(out); + close(out); - return 0; + return 0; } /* vim:set sw=8 noet */ diff --git a/utils/snarffont.c b/utils/snarffont.c index bdaff2d..de99de9 100644 --- a/utils/snarffont.c +++ b/utils/snarffont.c @@ -27,73 +27,74 @@ #define MAXFONTSIZE 65536 -int main(void) { - unsigned char buf[MAXFONTSIZE]; - struct console_font_op cfo; - unsigned short map[E_TABSZ]; - struct unipair descs[2048]; - struct unimapdesc d; - int fd; +int main(void) +{ + unsigned char buf[MAXFONTSIZE]; + struct console_font_op cfo; + unsigned short map[E_TABSZ]; + struct unipair descs[2048]; + struct unimapdesc d; + int fd; - if ((fd = open("/dev/tty0", O_RDONLY)) < 0) { - fprintf(stderr, "%s: %m", __func__); - return EXIT_FAILURE; - } + if ((fd = open("/dev/tty0", O_RDONLY)) < 0) { + fprintf(stderr, "%s: %m", __func__); + return EXIT_FAILURE; + } - cfo.op = KD_FONT_OP_GET; - cfo.flags = 0; - cfo.width = 8; - cfo.height = 16; - cfo.charcount = 512; - cfo.data = buf; - if (ioctl(fd, KDFONTOP, &cfo)) { - fprintf(stderr, "%s: %m", __func__); - return EXIT_FAILURE; - } + cfo.op = KD_FONT_OP_GET; + cfo.flags = 0; + cfo.width = 8; + cfo.height = 16; + cfo.charcount = 512; + cfo.data = buf; + if (ioctl(fd, KDFONTOP, &cfo)) { + fprintf(stderr, "%s: %m", __func__); + return EXIT_FAILURE; + } - if (ioctl(fd, GIO_UNISCRNMAP, map)) { - fprintf(stderr, "%s: %m", __func__); - return EXIT_FAILURE; - } + if (ioctl(fd, GIO_UNISCRNMAP, map)) { + fprintf(stderr, "%s: %m", __func__); + return EXIT_FAILURE; + } - d.entry_ct = 2048; - d.entries = descs; - if (ioctl(fd, GIO_UNIMAP, &d)) { - fprintf(stderr, "%s: %m", __func__); - return EXIT_FAILURE; - } + d.entry_ct = 2048; + d.entries = descs; + if (ioctl(fd, GIO_UNIMAP, &d)) { + fprintf(stderr, "%s: %m", __func__); + return EXIT_FAILURE; + } - if (write(1, &cfo, sizeof(cfo)) == -1) { - fprintf(stderr, "%s: %m", __func__); - return EXIT_FAILURE; - } + if (write(1, &cfo, sizeof(cfo)) == -1) { + fprintf(stderr, "%s: %m", __func__); + return EXIT_FAILURE; + } - if (write(1, &cfo, sizeof(cfo)) == -1) { - fprintf(stderr, "%s: %m", __func__); - return EXIT_FAILURE; - } + if (write(1, &cfo, sizeof(cfo)) == -1) { + fprintf(stderr, "%s: %m", __func__); + return EXIT_FAILURE; + } - if (write(1, buf, sizeof(buf)) == -1) { - fprintf(stderr, "%s: %m", __func__); - return EXIT_FAILURE; - } + if (write(1, buf, sizeof(buf)) == -1) { + fprintf(stderr, "%s: %m", __func__); + return EXIT_FAILURE; + } - if (write(1, map, sizeof(map)) == -1) { - fprintf(stderr, "%s: %m", __func__); - return EXIT_FAILURE; - } + if (write(1, map, sizeof(map)) == -1) { + fprintf(stderr, "%s: %m", __func__); + return EXIT_FAILURE; + } - if (write(1, &d.entry_ct, sizeof(d.entry_ct)) == -1) { - fprintf(stderr, "%s: %m", __func__); - return EXIT_FAILURE; - } + if (write(1, &d.entry_ct, sizeof(d.entry_ct)) == -1) { + fprintf(stderr, "%s: %m", __func__); + return EXIT_FAILURE; + } - if (write(1, descs, d.entry_ct * sizeof(descs[0])) == -1) { - fprintf(stderr, "%s: %m", __func__); - return EXIT_FAILURE; - } + if (write(1, descs, d.entry_ct * sizeof(descs[0])) == -1) { + fprintf(stderr, "%s: %m", __func__); + return EXIT_FAILURE; + } - return 0; + return 0; } /* vim:set sw=8 noet */ diff --git a/xutils.c b/xutils.c index a411beb..1c6f204 100644 --- a/xutils.c +++ b/xutils.c @@ -24,247 +24,248 @@ #include <X11/Xatom.h> #include <gdk/gdkx.h> -static PyObject * setRootResource(PyObject * s, PyObject * args); -static PyObject * getXatom(PyObject *s, PyObject *args); - +static PyObject *setRootResource(PyObject * s, PyObject * args); +static PyObject *getXatom(PyObject * s, PyObject * args); static PyMethodDef xutilsMethods[] = { - { "setRootResource", setRootResource, 1, NULL }, - { "getXatom", getXatom, 1, NULL }, - { NULL, NULL, 0, NULL } + {"setRootResource", setRootResource, 1, NULL}, + {"getXatom", getXatom, 1, NULL}, + {NULL, NULL, 0, NULL} }; typedef struct _Resource { - char *key, *val; + char *key, *val; } Resource; -static int -openDisplay(Display **dpy, Window *root) +static int openDisplay(Display ** dpy, Window * root) { - int scrn; + int scrn; - *dpy=XOpenDisplay(""); - if (!*dpy) - return -1; + *dpy = XOpenDisplay(""); + if (!*dpy) + return -1; - scrn=DefaultScreen(*dpy); - *root = RootWindow(*dpy, scrn); - return 0; + scrn = DefaultScreen(*dpy); + *root = RootWindow(*dpy, scrn); + return 0; } -static void -closeDisplay(Display *dpy) +static void closeDisplay(Display * dpy) { - XCloseDisplay(dpy); -} + XCloseDisplay(dpy); +} -static Resource ** -getCurrentResources(Display *dpy) +static Resource **getCurrentResources(Display * dpy) { - char *resource_string, *p; - Resource **rc; - int nrec; - - /* read through current resources, split on newlines */ - resource_string = XResourceManagerString(dpy); - - if (!resource_string) - return NULL; - - rc = (Resource **)malloc(sizeof(Resource *)); - p = resource_string; - nrec = 0; - while (1) { - char *eol; - char *sep; - int nleft; - - /* find next newline, defines end of current record */ - eol = strchr(p, '\n'); - - if (!eol) - break; - - /* find colon separating key and value */ - /* if no colon skip this record */ - sep = strchr(p, ':'); - if (sep) { - int len; - Resource *newrec; - - newrec = (Resource *) malloc(sizeof(Resource)); - - len = sep - p + 1; - newrec->key = (char *) malloc(len*sizeof(char)); - memcpy(newrec->key, p, len); - newrec->key[len-1] = '\0'; - - len = eol - sep; - newrec->val = (char *) malloc(len*sizeof(char)); - memcpy(newrec->val, sep+1, len); - newrec->val[len-1] = '\0'; - - rc = (Resource **) realloc(rc, (nrec+1) * sizeof(Resource *)); - rc[nrec] = newrec; - nrec = nrec + 1; + char *resource_string, *p; + Resource **rc; + int nrec; + + /* read through current resources, split on newlines */ + resource_string = XResourceManagerString(dpy); + + if (!resource_string) + return NULL; + + rc = (Resource **) malloc(sizeof(Resource *)); + p = resource_string; + nrec = 0; + while (1) { + char *eol; + char *sep; + int nleft; + + /* find next newline, defines end of current record */ + eol = strchr(p, '\n'); + + if (!eol) + break; + + /* find colon separating key and value */ + /* if no colon skip this record */ + sep = strchr(p, ':'); + if (sep) { + int len; + Resource *newrec; + + newrec = (Resource *) malloc(sizeof(Resource)); + + len = sep - p + 1; + newrec->key = (char *)malloc(len * sizeof(char)); + memcpy(newrec->key, p, len); + newrec->key[len - 1] = '\0'; + + len = eol - sep; + newrec->val = (char *)malloc(len * sizeof(char)); + memcpy(newrec->val, sep + 1, len); + newrec->val[len - 1] = '\0'; + + rc = (Resource **) realloc(rc, + (nrec + + 1) * sizeof(Resource *)); + rc[nrec] = newrec; + nrec = nrec + 1; + } + + nleft = strlen(resource_string) - (eol - resource_string); + if (nleft <= 0) + break; + + p = eol + 1; } - nleft = strlen(resource_string) - (eol-resource_string); - if (nleft <= 0) - break; - - p = eol + 1; - } - - if (nrec > 0) { - rc = (Resource **) realloc(rc, (nrec+1) * sizeof(Resource *)); - rc[nrec] = NULL; - } else { - rc = NULL; - } + if (nrec > 0) { + rc = (Resource **) realloc(rc, (nrec + 1) * sizeof(Resource *)); + rc[nrec] = NULL; + } else { + rc = NULL; + } - return rc; + return rc; } -static void -freeResources(Resource **rc) +static void freeResources(Resource ** rc) { - int idx; + int idx; - if (!rc) - return; + if (!rc) + return; - idx = 0; - while (rc[idx]) { - free(rc[idx]->key); - free(rc[idx]->val); - free(rc[idx]); + idx = 0; + while (rc[idx]) { + free(rc[idx]->key); + free(rc[idx]->val); + free(rc[idx]); - idx++; - } + idx++; + } - free(rc); + free(rc); } -static PyObject * -setRootResource(PyObject *s, PyObject *args) +static PyObject *setRootResource(PyObject * s, PyObject * args) { - Display *dpy; - Window root; - Resource **resources, **p; - char *key, *val, *rstring; - int fnd, nrec; - - if (!PyArg_ParseTuple(args, "ss", &key, &val)) { - return NULL; - } - - if (openDisplay(&dpy, &root) < 0) { - PyErr_SetString(PyExc_SystemError, "Could not open display."); - return NULL; - } - - resources = getCurrentResources(dpy); - fnd = 0; - nrec = 0; - if (resources) { - p = resources; - while (*p) { - if (!strcmp(key, (*p)->key)) { - free((*p)->val); - (*p)->val = strdup(val); - fnd = 1; - break; - } - - p++; + Display *dpy; + Window root; + Resource **resources, **p; + char *key, *val, *rstring; + int fnd, nrec; + + if (!PyArg_ParseTuple(args, "ss", &key, &val)) { + return NULL; } - p = resources; - while (*p) { - nrec++; - p++; + if (openDisplay(&dpy, &root) < 0) { + PyErr_SetString(PyExc_SystemError, "Could not open display."); + return NULL; } - } - - if (!fnd) { - Resource *newrec; - - newrec = (Resource *) malloc(sizeof(Resource)); - newrec->key = strdup(key); - newrec->val = strdup(val); - - if (nrec > 0) - resources = (Resource **) realloc(resources, (nrec+2) * sizeof(Resource *)); - else - resources = (Resource **) malloc(2*sizeof(Resource *)); - - resources[nrec] = newrec; - resources[nrec+1] = NULL; - } - - rstring = NULL; - p = resources; - while (*p) { - int len; - char *tmpstr; - - len = strlen((*p)->key) + strlen((*p)->val) + 3; - tmpstr = (char *) malloc(len*sizeof(char)); - strcpy(tmpstr, (*p)->key); - strcat(tmpstr, ":"); - strcat(tmpstr, (*p)->val); - strcat(tmpstr, "\n"); - - if (rstring) { - rstring = (char *)realloc(rstring, (strlen(rstring)+len+1)*sizeof(char)); - strcat(rstring, tmpstr); - } else { - rstring = tmpstr; + + resources = getCurrentResources(dpy); + fnd = 0; + nrec = 0; + if (resources) { + p = resources; + while (*p) { + if (!strcmp(key, (*p)->key)) { + free((*p)->val); + (*p)->val = strdup(val); + fnd = 1; + break; + } + + p++; + } + + p = resources; + while (*p) { + nrec++; + p++; + } } - p++; - } + if (!fnd) { + Resource *newrec; - XChangeProperty(dpy, root, XA_RESOURCE_MANAGER, XA_STRING, - 8, PropModeReplace, (unsigned char *)rstring, - strlen(rstring)); + newrec = (Resource *) malloc(sizeof(Resource)); + newrec->key = strdup(key); + newrec->val = strdup(val); - free(rstring); - freeResources(resources); + if (nrec > 0) + resources = + (Resource **) realloc(resources, + (nrec + + 2) * sizeof(Resource *)); + else + resources = + (Resource **) malloc(2 * sizeof(Resource *)); - closeDisplay(dpy); + resources[nrec] = newrec; + resources[nrec + 1] = NULL; + } + + rstring = NULL; + p = resources; + while (*p) { + int len; + char *tmpstr; + + len = strlen((*p)->key) + strlen((*p)->val) + 3; + tmpstr = (char *)malloc(len * sizeof(char)); + strcpy(tmpstr, (*p)->key); + strcat(tmpstr, ":"); + strcat(tmpstr, (*p)->val); + strcat(tmpstr, "\n"); + + if (rstring) { + rstring = + (char *)realloc(rstring, + (strlen(rstring) + len + + 1) * sizeof(char)); + strcat(rstring, tmpstr); + } else { + rstring = tmpstr; + } + + p++; + } + + XChangeProperty(dpy, root, XA_RESOURCE_MANAGER, XA_STRING, + 8, PropModeReplace, (unsigned char *)rstring, + strlen(rstring)); - Py_INCREF(Py_None); - return Py_None; + free(rstring); + freeResources(resources); + + closeDisplay(dpy); + + Py_INCREF(Py_None); + return Py_None; } /* this assumes you've already imported gtk and thus have a display */ -static PyObject * -getXatom(PyObject *s, PyObject *args) +static PyObject *getXatom(PyObject * s, PyObject * args) { - char *atomname; - Atom theatom; - - if (!PyArg_ParseTuple(args, "s", &atomname)) { - return NULL; - } - - theatom = gdk_x11_get_xatom_by_name(atomname); - if (XGetSelectionOwner (GDK_DISPLAY(), theatom) != None) { - Py_INCREF(Py_True); - return Py_True; - } - Py_INCREF(Py_False); - return Py_False; + char *atomname; + Atom theatom; + + if (!PyArg_ParseTuple(args, "s", &atomname)) { + return NULL; + } + + theatom = gdk_x11_get_xatom_by_name(atomname); + if (XGetSelectionOwner(GDK_DISPLAY(), theatom) != None) { + Py_INCREF(Py_True); + return Py_True; + } + Py_INCREF(Py_False); + return Py_False; } -void -initxutils () +void initxutils() { - PyObject * d; + PyObject *d; - d = Py_InitModule ("xutils", xutilsMethods); + d = Py_InitModule("xutils", xutilsMethods); } /* vim:set sw=8 noet */ -- 1.6.5.2 _______________________________________________ Anaconda-devel-list mailing list Anaconda-devel-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/anaconda-devel-list