void loadLanguage(void) { char *filename; 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; checked_asprintf(&filename, "/tmp/translation/%s.tr", key); rc = unpack_archive_file("/etc/loader.tr", "/tmp/translation"); if (rc != ARCHIVE_OK || access("/tmp/translation", R_OK) == -1) { newtWinMessage("Error", "OK", "Cannot get translation file %s.\n", filename); return; } fd = open(filename, O_RDONLY); if (fd < 0) { newtWinMessage("Error", "OK", "Failed to open /tmp/translation: %m\n"); free(filename); 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); free(filename); int translation_dir_fd = open("/tmp/translation", O_RDONLY); recursiveRemove(translation_dir_fd); close(translation_dir_fd); rmdir("/tmp/translation"); qsort(strings, numStrings, sizeof(*strings), aStringCmp); }
/* @p path must be point to malloc'ed memory * Replaces **path with a pointer to a string containing * dirname + path. * path must be absolute. */ static int prepend_dir_to_name(const char *dirname, char **path) { char *buf; checked_asprintf(&buf, "%s%s", dirname, *path); if (buf == NULL) { return EXIT_OUT_OF_MEMORY; } free(*path); *path = buf; return 0; }
inline int cb_saveversions(gchar** parts, void *data0) { GHashTable *ht = data0; gchar *module = g_strdup(parts[0]); char *versionfilename; char *srcversionfilename; gchar *version; gchar *srcversion; gchar *value, *value2; checked_asprintf(&versionfilename, "/sys/module/%s/version", module); checked_asprintf(&srcversionfilename, "/sys/module/%s/srcversion", module); /* emty string */ value = g_new0(gchar, 1); /* get possible version file */ if (g_file_get_contents(versionfilename, &version, NULL, NULL)) { value2 = g_strconcat(value, version, "/", NULL); g_free(value); g_free(version); value = value2; } /* get possible src version file */ if (g_file_get_contents(srcversionfilename, &srcversion, NULL, NULL)) { value2 = g_strconcat(value, srcversion, NULL); g_free(value); g_free(srcversion); value = value2; } free(versionfilename); free(srcversionfilename); g_hash_table_insert(ht, module, value); return 1; }
/** * Read in @p filename from inside @p dirname, and try to parse it as * a status file. * * If a new entry is read, a pointer to it is returned in @p lp. **/ static int dcc_mon_do_file(char *dirname, char *filename, struct dcc_task_state **lp) { int fd; char *fullpath; int ret; *lp = NULL; /* Is this a file we want to see */ if (!str_startswith(dcc_state_prefix, filename)) { /* rs_trace("skipped"); */ return 0; } checked_asprintf(&fullpath, "%s/%s", dirname, filename); if (fullpath == NULL) { return EXIT_OUT_OF_MEMORY; } rs_trace("process %s", fullpath); /* Remember that the file might disappear at any time, so open it * now so that we can hang on. */ if ((fd = open(fullpath, O_RDONLY|O_BINARY, 0)) == -1) { if (errno == ENOENT) { rs_trace("%s disappeared", fullpath); ret = 0; goto out_free; } else { /* hm */ rs_log_warning("failed to open %s: %s", fullpath, strerror(errno)); ret = EXIT_IO_ERROR; goto out_free; } } if ((ret = dcc_mon_kill_old(fd, fullpath))) { /* closes fd on failure */ goto out_free; } ret = dcc_mon_load_state(fd, fullpath, lp); dcc_close(fd); out_free: free(fullpath); return ret; /* ok */ }
/* 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(81); /* reserve one byte for \0 */ for (i=0; i < 80; i++) buf[i] = ' '; buf[80] = 0; /* and set the \0 */ 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)); return 0; }
/* * explode source RPM into the current directory * use filters to skip packages and files we do not need */ int explodeRPM(const char *source, filterfunc filter, dependencyfunc provides, dependencyfunc deps, void* userptr) { char buffer[BUFFERSIZE+1]; /* make space for trailing \0 */ FD_t fdi; Header h; char * rpmio_flags = NULL; rpmRC rc; FD_t gzdi; struct archive *cpio; struct archive_entry *cpio_entry; struct cpio_mydata cpio_mydata; rpmts ts; rpmVSFlags vsflags; const char *compr; if (strcmp(source, "-") == 0) fdi = fdDup(STDIN_FILENO); else fdi = Fopen(source, "r.ufdio"); if (Ferror(fdi)) { const char *srcname = (strcmp(source, "-") == 0) ? "<stdin>" : source; logMessage(ERROR, "%s: %s\n", srcname, Fstrerror(fdi)); return EXIT_FAILURE; } rpmReadConfigFiles(NULL, NULL); /* Initialize RPM transaction */ ts = rpmtsCreate(); vsflags = 0; /* Do not check digests, signatures or headers */ vsflags |= _RPMVSF_NODIGESTS; vsflags |= _RPMVSF_NOSIGNATURES; vsflags |= RPMVSF_NOHDRCHK; (void) rpmtsSetVSFlags(ts, vsflags); rc = rpmReadPackageFile(ts, fdi, "rpm2dir", &h); ts = rpmtsFree(ts); switch (rc) { case RPMRC_OK: case RPMRC_NOKEY: case RPMRC_NOTTRUSTED: break; case RPMRC_NOTFOUND: logMessage(ERROR, "%s is not an RPM package", source); return EXIT_FAILURE; break; case RPMRC_FAIL: default: logMessage(ERROR, "error reading header from %s package\n", source); return EXIT_FAILURE; break; } /* Retrieve all dependencies and run them through deps function */ while (deps) { struct rpmtd_s td; const char *depname; if (!headerGet(h, RPMTAG_REQUIRENAME, &td, HEADERGET_MINMEM)) break; /* iterator */ while ((depname = rpmtdNextString(&td))) { if (deps(depname, userptr)) { Fclose(fdi); return EXIT_BADDEPS; } } rpmtdFreeData(&td); break; } /* Retrieve all provides and run them through provides function */ while (provides) { struct rpmtd_s td; const char *depname; int found = 0; if (!headerGet(h, RPMTAG_PROVIDES, &td, HEADERGET_MINMEM)) break; /* iterator */ while ((depname = rpmtdNextString(&td))) { if (!provides(depname, userptr)) { found++; } } rpmtdFreeData(&td); if (found<=0) return EXIT_BADDEPS; break; } /* Retrieve type of payload compression. */ compr = headerGetString(h, RPMTAG_PAYLOADCOMPRESSOR); if (compr && strcmp(compr, "gzip")) { checked_asprintf(&rpmio_flags, "r.%sdio", compr); } else { checked_asprintf(&rpmio_flags, "r.gzdio"); } /* Open uncompressed cpio stream */ gzdi = Fdopen(fdi, rpmio_flags); free(rpmio_flags); if (gzdi == NULL) { logMessage(ERROR, "cannot re-open payload: %s\n", Fstrerror(gzdi)); return EXIT_FAILURE; } /* initialize cpio decompressor */ cpio = archive_read_new(); if (cpio==NULL) { Fclose(gzdi); return -1; } cpio_mydata.gzdi = gzdi; cpio_mydata.buffer = buffer; archive_read_support_compression_all(cpio); archive_read_support_format_all(cpio); rc = archive_read_open(cpio, &cpio_mydata, NULL, rpm_myread, rpm_myclose); /* check the status of archive_open */ if (rc != ARCHIVE_OK){ Fclose(gzdi); return -1; } /* read all files in cpio archive */ while ((rc = archive_read_next_header(cpio, &cpio_entry)) == ARCHIVE_OK){ const struct stat *fstat; int64_t fsize; const char* filename; int needskip = 1; /* do we need to read the data to get to the next header? */ int offset = 0; int towrite = 0; filename = archive_entry_pathname(cpio_entry); fstat = archive_entry_stat(cpio_entry); fsize = archive_entry_size(cpio_entry); /* Strip leading slashes */ while (filename[offset] == '/') offset+=1; /* Strip leading ./ */ while (filename[offset] == '.' && filename[offset+1] == '/') offset+=2; /* Other file type - we do not care except special cases */ if (!S_ISREG(fstat->st_mode)) towrite = 1; else towrite = 2; if (filter && filter(filename+offset, fstat, userptr)) { /* filter this file */ towrite = 0; } /* Create directories */ char* dirname = strdup(filename+offset); /* If the dup fails, let's hope the dirs already exist */ if (dirname){ char* dirptr = dirname; while (dirptr && *dirptr) { dirptr = strchr(dirptr, '/'); if (dirptr) { *dirptr = 0; mkdir(dirname, 0700); *dirptr = '/'; dirptr++; } } free(dirname); } /* Regular file */ if (towrite>=2) { FILE *fdout = fopen(filename+offset, "w"); if (fdout==NULL){ rc = 33; break; } rc = archive_read_data_into_fd(cpio, fileno(fdout)); if (rc!=ARCHIVE_OK) { /* XXX We didn't get the file.. well.. */ needskip = 0; } else { needskip = 0; fclose(fdout); } } /* symlink, we assume that the path contained in symlink * is shorter than BUFFERSIZE */ while (towrite && S_ISLNK(fstat->st_mode)) { char symlinkbuffer[BUFFERSIZE-1]; needskip = 0; if ((rc = archive_read_data(cpio, symlinkbuffer, fsize))!=ARCHIVE_OK) { /* XXX We didn't get the file.. well.. */ break; } if (symlink(buffer, filename+offset)) { logMessage(ERROR, "Failed to create symlink %s -> %s", filename+offset, buffer); } break; } if(needskip) archive_read_data_skip(cpio); } archive_read_finish(cpio); return rc != ARCHIVE_OK; }
/* Go through arguments (in @p argv), and relevant environment variables, and * find out where the dependencies output should go. Return that location in a * newly allocated string in @p dotd_fname. @p needs_dotd is set to true if the * compilation command line and environent imply that a .d file must be * produced. @p sets_dotd_target is set to true if there is a -MQ or -MT * option. This is to be used on the client, so that the client knows where to * put the .d file it gets from the server. @p dotd_target is set only if * @needs_dotd is true and @sets_dotd_target is false and the target is given in * the DEPENDENCIES_OUTPUT environment variable. * * Note: -M is not handled here, because this option implies -E. * * TODO(manos): it does not support SUNPRO_DEPENDENCIES. */ int dcc_get_dotd_info(char **argv, char **dotd_fname, int *needs_dotd, int *sets_dotd_target, char **dotd_target) { char *deps_output = 0; char *input_file; char *output_file; char **new_args; /* will throw this away */ int has_dash_o = 0; char *env_var = 0; int ret; int i; char *a; *needs_dotd = 0; *sets_dotd_target = 0; *dotd_target = NULL; env_var = getenv("DEPENDENCIES_OUTPUT"); if (env_var != NULL) { *needs_dotd = 1; } for (i = 0; (a = argv[i]); i++) { if (strcmp(a, "-MT") == 0) { *sets_dotd_target = 1; ++i; continue; } if (strcmp(a, "-MQ") == 0) { *sets_dotd_target = 1; ++i; continue; } /* Catch-all for all -MD, -MMD, etc, options. * -MQ and -MT do not imply a deps file is expected. */ if (strncmp(a, "-M", 2) == 0) { *needs_dotd = 1; } if (strcmp(a, "-MF") == 0) { ++i; deps_output = argv[i]; } else if (strncmp(a, "-MF", 3) == 0) { deps_output = argv[i] + 3; } else if (strcmp(a, "-o") == 0) { has_dash_o = 1; } } /* TODO(csilvers): we also need to parse -Wp,-x,-y,-z, in the same * way we do gcc flags in the for loop above. Note that the -Wp * flags are passed to cpp, with slightly different semantics than * gcc flags (eg -Wp,-MD takes a filename argument, while -MD does * not). */ if (deps_output) { *dotd_fname = strdup(deps_output); if (*dotd_fname == NULL) { return EXIT_OUT_OF_MEMORY; } else { return 0; } } /* ok, so there is no explicit setting of the deps filename. */ deps_output = env_var; if (deps_output) { char *space; *dotd_fname = strdup(deps_output); if (*dotd_fname == NULL) { return EXIT_OUT_OF_MEMORY; } space = strchr(*dotd_fname, ' '); if (space != NULL) { *space = '\0'; *dotd_target = space + 1; } return 0; } /* and it's not set explicitly in the variable */ { /* Call dcc_scan_args to find the input/output files in order to calculate a name for the .d file.*/ char *extension; char *tmp_dotd_fname; ret = dcc_scan_args(argv, &input_file, &output_file, &new_args, NULL); if (ret) return ret; /* if .o is set, just append .d. * otherwise, take the basename of the input, and set the suffix to .d */ if (has_dash_o) tmp_dotd_fname = strdup(output_file); else tmp_dotd_fname = strdup(input_file); if (tmp_dotd_fname == NULL) return EXIT_OUT_OF_MEMORY; extension = dcc_find_extension(tmp_dotd_fname); /* Whether derived from input or output filename, we peel the extension off (if it exists). */ if (extension) { /* dcc_find_extension guarantees that there is space for 'd'. */ extension[1] = 'd'; extension[2] = '\0'; *dotd_fname = tmp_dotd_fname; } else { /* There is no extension (or name ends with a "."). */ if (tmp_dotd_fname[strlen(tmp_dotd_fname) - 1] == '.') checked_asprintf(dotd_fname, "%s%s", tmp_dotd_fname, "d"); else checked_asprintf(dotd_fname, "%s%s", tmp_dotd_fname, ".d"); if (*dotd_fname == NULL) { return EXIT_OUT_OF_MEMORY; } free(tmp_dotd_fname); } return 0; } }
/* 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; logMessage(INFO, "mounting device %s for hard drive install", device); 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); if (path) { logMessage(INFO, "Path to stage2 image is %s", path); rc = copyFile(path, "/tmp/install.img"); rc = mountStage2("/tmp/install.img"); free(path); if (rc) { umountLoopback("/mnt/runtime", "/dev/loop0"); umount("/mnt/isodir"); goto err; } checked_asprintf(&updpath, "%s/updates.img", dirspec); logMessage(INFO, "Looking for updates for HD in %s", updpath); copyUpdatesImg(updpath); free(updpath); checked_asprintf(&updpath, "%s/product.img", dirspec); logMessage(INFO, "Looking for product for HD in %s", updpath); copyProductImg(updpath); free(updpath); free(dirspec); umount("/mnt/isodir"); checked_asprintf(&url, "hd:%s:/%s", device, dirName ? dirName : "."); return url; } else { free(dirspec); free(path); 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; }
/* 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); } else { ksdirectory = strdup("/images/install.img"); } 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; }