diff options
author | Erik Troan <ewt@redhat.com> | 1999-06-07 16:20:28 +0000 |
---|---|---|
committer | Erik Troan <ewt@redhat.com> | 1999-06-07 16:20:28 +0000 |
commit | b618b84a39b515482a1f6d91ddbf30fa95c424b4 (patch) | |
tree | 429a21e55a319d1243aef21c50fae3f451f0fe37 /isys | |
parent | 9eb6ae369c87516c13854e4c02f24e7f1f848e77 (diff) | |
download | anaconda-b618b84a39b515482a1f6d91ddbf30fa95c424b4.tar.gz anaconda-b618b84a39b515482a1f6d91ddbf30fa95c424b4.tar.xz anaconda-b618b84a39b515482a1f6d91ddbf30fa95c424b4.zip |
*** empty log message ***
Diffstat (limited to 'isys')
-rw-r--r-- | isys/cpio.c | 34 | ||||
-rw-r--r-- | isys/cpio.h | 59 | ||||
-rw-r--r-- | isys/devnodes.c | 131 | ||||
-rw-r--r-- | isys/moduleinfo.c | 168 | ||||
-rw-r--r-- | isys/otherinsmod.c | 129 |
5 files changed, 521 insertions, 0 deletions
diff --git a/isys/cpio.c b/isys/cpio.c new file mode 100644 index 000000000..06e41502f --- /dev/null +++ b/isys/cpio.c @@ -0,0 +1,34 @@ +#include <fcntl.h> +#include <newt.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <zlib.h> + +#include "cpio.h" + +int installCpioFile(FD_t fd, char * cpioName, char * outName, int inWin) { + struct cpioFileMapping map; + int rc; + char * failedFile; + CFD_t cfdbuf, *cfd = &cfdbuf; + + if (outName) { + map.archivePath = cpioName; + map.fsPath = outName; + map.mapFlags = CPIO_MAP_PATH; + } + + cfd->cpioIoType = cpioIoTypeGzFd; + cfd->cpioGzFd = gzdFdopen(fdDup(fdFileno(fd)), "r"); + + rc = cpioInstallArchive(cfd, outName ? &map : NULL, 1, NULL, NULL, + &failedFile); + gzdClose(cfd->cpioGzFd); + + if (rc || access(outName, R_OK)) { + return -1; + } + + return 0; +} diff --git a/isys/cpio.h b/isys/cpio.h new file mode 100644 index 000000000..44301aee9 --- /dev/null +++ b/isys/cpio.h @@ -0,0 +1,59 @@ +#ifndef H_CPIO +#define H_CPIO + +#include <zlib.h> +#define HAVE_ZLIB_H 1 +#include <rpm/rpmio.h> + +#define CPIO_MAP_PATH (1 << 0) +#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 */ + +struct cpioFileMapping { + 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 */ +}; + +typedef struct CFD { + union { + FD_t _cfdu_fd; +#define cpioFd _cfdu._cfdu_fd + FILE * _cfdu_fp; +#define cpioFp _cfdu._cfdu_fp + FD_t _cfdu_gzfd; +#define cpioGzFd _cfdu._cfdu_gzfd + } _cfdu; + int cpioPos; + enum cpioIoType { + cpioIoTypeDebug, + cpioIoTypeFd, + cpioIoTypeFp, + cpioIoTypeGzFd, + } cpioIoType; +} CFD_t; + +typedef void (*cpioCallback)(struct cpioCallbackInfo * filespec, void * data); + +/* librpm provides these */ +int cpioInstallArchive(CFD_t *cfd, struct cpioFileMapping * mappings, + int numMappings, cpioCallback cb, void * cbData, + char ** failedFile); +const char *cpioStrerror(int rc); + +int installCpioFile(FD_t fd, char * cpioName, char * outName, int inWin); + +#endif diff --git a/isys/devnodes.c b/isys/devnodes.c new file mode 100644 index 000000000..97ab2c3c9 --- /dev/null +++ b/isys/devnodes.c @@ -0,0 +1,131 @@ +#include <errno.h> +#include <fcntl.h> +#include <sys/stat.h> +#include <sys/sysmacros.h> +#include <unistd.h> + +struct devnum { + char * name; + short major, minor; + int isChar; +}; + +static struct devnum devices[] = { + { "aztcd", 29, 0, 0 }, + { "bpcd", 41, 0, 0 }, + { "cdu31a", 15, 0, 0 }, + { "cdu535", 24, 0, 0 }, + { "cm206cd", 32, 0, 0 }, + { "fd0", 2, 0, 0 }, + { "fd1", 2, 1, 0 }, + { "gscd", 16, 0, 0 }, + { "lp0", 6, 0, 1 }, + { "lp1", 6, 1, 1 }, + { "lp2", 6, 2, 1 }, + { "mcd", 23, 0, 0 }, + { "mcdx", 20, 0, 0 }, + { "nst0", 9, 128, 1 }, + { "optcd", 17, 0, 0 }, + { "sbpcd", 25, 0, 0 }, + { "scd0", 11, 0, 0 }, + { "scd1", 11, 1, 0 }, + { "sjcd", 18, 0, 0 }, +}; + +int numDevices = sizeof(devices) / sizeof(struct devnum); + +int devMakeInode(char * devName, char * path) { + int i; + int major, minor; + int type; + char *ptr; + char *dir; + + if (devName[0] == 's' && devName[1] == 'd') { + type = S_IFBLK; + major = 8; + minor = (devName[2] - 'a') << 4; + if (devName[3] && devName[4]) + minor += 10 + (devName[4] - '0'); + else if (devName[3]) + minor += (devName[3] - '0'); + } else if (devName[0] == 'h' && devName[1] == 'd') { + type = S_IFBLK; + if (devName[2] == 'a') + major = 3, minor = 0; + else if (devName[2] == 'b') + major = 3, minor = 64; + else if (devName[2] == 'c') + major = 22, minor = 0; + else if (devName[2] == 'd') + major = 22, minor = 64; + else if (devName[2] == 'e') + major = 33, minor = 0; + else if (devName[2] == 'f') + major = 33, minor = 64; + else if (devName[2] == 'g') + major = 34, minor = 0; + else if (devName[2] == 'h') + major = 34, minor = 64; + else + return -1; + + if (devName[3] && devName[4]) + minor += 10 + (devName[4] - '0'); + else if (devName[3]) + minor += (devName[3] - '0'); + } else if (!strncmp(devName, "ram", 3)) { + type = S_IFBLK; + major = 1; + minor = 1; + if (devName[3]) + minor += devName[3] - '1'; + } else if (!strncmp(devName, "rd/", 3)) { + /* dac 960 "/rd/c0d0{p1}" */ + type = S_IFBLK; + major = 48 + devName[4] - '0'; /* controller */ + minor = (devName[6] - '0') * 8; /* disk */ + if (strlen(devName) > 7) /* partition */ + minor += devName[8] - '0'; + } else if (!strncmp(devName, "ida/", 4)) { + /* Compaq Smart Array "ida/c0d0{p1} */ + type = S_IFBLK; + major = 72; /* controller */ + minor = (devName[7] - '0') * 16; /* disk */ + if (strlen(devName) > 8) /* partition */ + minor += atoi(devName + 9); + } else { + for (i = 0; i < numDevices; i++) { + if (!strcmp(devices[i].name, devName)) break; + } + if (i == numDevices) return -1; + major = devices[i].major; + minor = devices[i].minor; + + if (devices[i].isChar) + type = S_IFCHR; + else + type = S_IFBLK; + } + + ptr = path; + i = 0; + while (*ptr) + if (*ptr++ == '/') + i++; + if (i > 2) { + dir = alloca(strlen(path) + 1); + strcpy(dir, path); + ptr = dir + (strlen(path) - 1); + while (*ptr != '/') + *ptr-- = '\0'; + mkdir(dir, 0644); + } + + unlink(path); + if (mknod(path, type | 0600, makedev(major, minor))) { + return -2; + } + + return 0; +} diff --git a/isys/moduleinfo.c b/isys/moduleinfo.c new file mode 100644 index 000000000..afc646026 --- /dev/null +++ b/isys/moduleinfo.c @@ -0,0 +1,168 @@ +#include <alloca.h> +#include <ctype.h> +#include <fcntl.h> +#include <stdlib.h> +#include <string.h> +#include <sys/stat.h> +#include <unistd.h> + +#include "isys.h" + +struct moduleInfo * moduleList = NULL; +int numModules = 0; + +struct moduleInfo * isysGetModuleList(enum driverMajor major) { + struct moduleInfo * miList, * next; + int i; + + next = miList = malloc(sizeof(*miList) * numModules + 1); + for (i = 0; i < numModules; i++) { + if (moduleList[i].major == major || major == DRIVER_NONE) { + *next = 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 * isysFindModuleInfo(const char * moduleName) { + int i; + + for (i = 0; i < numModules; i++) + if (!strcmp(moduleName, moduleList[i].moduleName)) + return moduleList + i; + + return NULL; +} + +int isysReadModuleInfo(const char * filename) { + int fd, isIndented; + char * buf, * start, * next, * chptr; + struct stat sb; + char oldch; + struct moduleInfo * nextModule; + int modulesAlloced; + + fd = open(filename, O_RDONLY); + if (fd < 0) return -1; + + fstat(fd, &sb); + buf = alloca(sb.st_size + 1); + read(fd, buf, sb.st_size); + buf[sb.st_size] = '\0'; + close(fd); + + nextModule = moduleList; + modulesAlloced = 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) numModules++; + + if (numModules == modulesAlloced) { + modulesAlloced += 5; + moduleList = realloc(moduleList, + modulesAlloced * sizeof(*moduleList)); + } + nextModule = moduleList + numModules; + nextModule->moduleName = strdup(start); + nextModule->major = DRIVER_NONE; + nextModule->minor = DRIVER_MINOR_NONE; + nextModule->description = NULL; + nextModule->args = NULL; + nextModule->numArgs = 0; + } 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, "plip")) { + nextModule->major = DRIVER_NET; + nextModule->minor = DRIVER_MINOR_PLIP; + } else if (!strcmp(chptr, "scsi_hostadapter")) { + nextModule->major = DRIVER_SCSI; + } else if (!strcmp(chptr, "cdrom")) { + nextModule->major = DRIVER_CDROM; + } + } else if (!nextModule->description) { + chptr = start + strlen(start) - 1; + if (*start == '"' && *chptr == '"') { + start++; + chptr--; + *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; + } + + if (nextModule && nextModule->moduleName) numModules++; + numModules = nextModule - moduleList; + + return 0; +} diff --git a/isys/otherinsmod.c b/isys/otherinsmod.c new file mode 100644 index 000000000..5cbbfae3e --- /dev/null +++ b/isys/otherinsmod.c @@ -0,0 +1,129 @@ +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <zlib.h> +#include <fcntl.h> +#include <sys/utsname.h> +#include <sys/wait.h> + +#include "cpio.h" +#include "isys.h" + +/* hack */ +int insmod_main(int argc, char ** argv); +int rmmod_main(int argc, char ** argv); + +int ourInsmodCommand(int argc, char ** argv) { + char * file; + char finalName[100]; + char * chptr; + FD_t fd; + int rc, rmObj = 0; + int sparc64 = 0; +#ifdef __sparc__ + + struct utsname u; + + if (!uname(&u) && !strcmp(u.machine, "sparc64")) + sparc64 = 1; +#endif + + if (argc < 2) { + fprintf(stderr, "usage: insmod <module>.o [params]\n"); + return 1; + } + + file = argv[1]; + if (access(file, R_OK)) { + /* it might be having a ball */ + fd = fdOpen(sparc64 ? + "/modules/modules64.cgz" : "/modules/modules.cgz", + O_RDONLY, 0); + if (fdFileno(fd) < 0) { + return 1; + } + + chptr = strrchr(file, '/'); + if (chptr) file = chptr + 1; + sprintf(finalName, "/tmp/%s", file); + + if (installCpioFile(fd, file, finalName, 0)) + return 1; + + rmObj = 1; + file = finalName; + } + + argv[1] = file; + +#ifdef __sparc__ + if (sparc64) { + int pid, status; + + if (!(pid = fork())) { + execv("/bin/insmod64", argv); + exit(-1); + } + waitpid(pid, &status, 0); + if (WIFEXITED(status)) + rc = WEXITSTATUS(status); + else + rc = -1; + } else +#endif + rc = insmod_main(argc, argv); + + if (rmObj) unlink(file); + + return rc; +} + +int rmmod(char * modName) { + pid_t child; + int status; + char * argv[] = { "/bin/rmmod", modName, NULL }; + int argc = 2; + int rc = 0; + + if ((child = fork()) == 0) { + exit(rmmod_main(argc, argv)); + } + + waitpid(child, &status, 0); + + if (WIFEXITED(status)) + rc = WEXITSTATUS(status); + else + rc = -1; + + return rc; +} + +int insmod(char * modName, char ** args) { + int argc; + char ** argv; + int rc = 0; + pid_t child; + int status; + + argc = 2; + for (argv = args; *argv; argv++, argc++); + + argv = malloc(sizeof(*argv) * (argc + 1)); + argv[0] = "/bin/insmod"; + argv[1] = modName; + memcpy(argv + 2, args, argc - 1); + + if ((child = fork()) == 0) { + exit(ourInsmodCommand(argc, argv)); + } + + waitpid(child, &status, 0); + + if (WIFEXITED(status)) + rc = WEXITSTATUS(status); + else + rc = -1; + + return rc; +} |