/* Fetch CPU statistics from /proc/stat */ static void get_cpu_statistics(stats_cpu_t *sc) { FILE *fp; char buf[1024]; fp = xfopen_for_read("/proc/stat"); memset(sc, 0, sizeof(*sc)); while (fgets(buf, sizeof(buf), fp)) { int i; char *ibuf; /* Does the line start with "cpu "? */ if (!starts_with_cpu(buf) || buf[3] != ' ') { continue; } ibuf = buf + 4; for (i = STATS_CPU_USER; i <= STATS_CPU_GUEST; i++) { ibuf = skip_whitespace(ibuf); sscanf(ibuf, "%"FMT_DATA"u", &sc->vector[i]); if (i != STATS_CPU_GUEST) { sc->vector[GLOBAL_UPTIME] += sc->vector[i]; } ibuf = skip_non_whitespace(ibuf); } break; } if (this_is_smp()) { sc->vector[SMP_UPTIME] = get_smp_uptime(); } fclose(fp); }
int scriptreplay_main(int argc UNUSED_PARAM, char **argv) { const char *script = "typescript"; double delay, factor = 1000000.0; int fd; unsigned long count; FILE *tfp; if (!argv[1]) bb_show_usage(); if (argv[2]) { script = argv[2]; if (argv[3]) factor /= atof(argv[3]); } tfp = xfopen_for_read(argv[1]); fd = xopen(script, O_RDONLY); while (fscanf(tfp, "%lf %lu\n", &delay, &count) == 2) { usleep(delay * factor); bb_copyfd_exact_size(fd, STDOUT_FILENO, count); } if (ENABLE_FEATURE_CLEAN_UP) { close(fd); fclose(tfp); } return EXIT_SUCCESS; }
static cputime_t get_smp_uptime(void) { FILE *fp; unsigned long sec, dec; fp = xfopen_for_read("/proc/uptime"); if (fscanf(fp, "%lu.%lu", &sec, &dec) != 2) bb_error_msg_and_die("can't read '%s'", "/proc/uptime"); fclose(fp); return (cputime_t)sec * G.clk_tck + dec * G.clk_tck / 100; }
void FAST_FUNC encode_base64(char *fname, const char *text, const char *eol) { enum { SRC_BUF_SIZE = 45, /* This *MUST* be a multiple of 3 */ DST_BUF_SIZE = 4 * ((SRC_BUF_SIZE + 2) / 3), }; #define src_buf text char src[SRC_BUF_SIZE]; FILE *fp = fp; ssize_t len = len; char dst_buf[DST_BUF_SIZE + 1]; if (fname) { fp = (NOT_LONE_DASH(fname)) ? xfopen_for_read(fname) : (FILE *)text; src_buf = src; } else if (text) { // though we do not call uuencode(NULL, NULL) explicitly // still we do not want to break things suddenly len = strlen(text); } else return; while (1) { size_t size; if (fname) { size = fread((char *)src_buf, 1, SRC_BUF_SIZE, fp); if ((ssize_t)size < 0) bb_perror_msg_and_die(bb_msg_read_error); } else { size = len; if (len > SRC_BUF_SIZE) size = SRC_BUF_SIZE; } if (!size) break; // encode the buffer we just read in bb_uuencode(dst_buf, src_buf, size, bb_uuenc_tbl_base64); if (fname) { printf("%s\n", eol); } else { src_buf += size; len -= size; } fwrite(dst_buf, 1, 4 * ((size + 2) / 3), stdout); } if (fname && NOT_LONE_DASH(fname)) fclose(fp); #undef src_buf }
static void bb_dump_addfile(dumper_t *dumper, char *name) { char *p; FILE *fp; char *buf; fp = xfopen_for_read(name); while ((buf = xmalloc_fgetline(fp)) != NULL) { p = skip_whitespace(buf); if (*p && (*p != '#')) { bb_dump_add(dumper, p); } free(buf); } fclose(fp); }
/* if fn is NULL then input is stdin and output is stdout */ static void convert(char *fn, int conv_type) { FILE *in, *out; int ch; char *temp_fn = temp_fn; /* for compiler */ char *resolved_fn = resolved_fn; in = stdin; out = stdout; if (fn != NULL) { struct stat st; int fd; resolved_fn = xmalloc_follow_symlinks(fn); if (resolved_fn == NULL) bb_simple_perror_msg_and_die(fn); in = xfopen_for_read(resolved_fn); xfstat(fileno(in), &st, resolved_fn); temp_fn = xasprintf("%sXXXXXX", resolved_fn); fd = xmkstemp(temp_fn); if (fchmod(fd, st.st_mode) == -1) bb_simple_perror_msg_and_die(temp_fn); fchown(fd, st.st_uid, st.st_gid); out = xfdopen_for_write(fd); } while ((ch = fgetc(in)) != EOF) { if (ch == '\r') continue; if (ch == '\n') if (conv_type == CT_UNIX2DOS) fputc('\r', out); fputc(ch, out); } if (fn != NULL) { if (fclose(in) < 0 || fclose(out) < 0) { unlink(temp_fn); bb_perror_nomsg_and_die(); } xrename(temp_fn, resolved_fn); free(temp_fn); free(resolved_fn); } }
static llist_t *append_file_list_to_list(llist_t *list) { FILE *src_stream; char *line; llist_t *newlist = NULL; while (list) { src_stream = xfopen_for_read(llist_pop(&list)); while ((line = xmalloc_fgetline(src_stream)) != NULL) { /* kill trailing '/' unless the string is just "/" */ char *cp = last_char_is(line, '/'); if (cp > line) *cp = '\0'; llist_add_to(&newlist, line); } fclose(src_stream); } return newlist; }
/* Prompt the user for a response, and * if user responds affirmatively, return true; * otherwise, return false. Uses "/dev/tty", not stdin. */ static int xargs_ask_confirmation(void) { FILE *tty_stream; int c, savec; #if !ENABLE_PLATFORM_MINGW32 tty_stream = xfopen_for_read(CURRENT_TTY); #endif fputs(" ?...", stderr); fflush_all(); #if !ENABLE_PLATFORM_MINGW32 c = savec = getc(tty_stream); while (c != EOF && c != '\n') c = getc(tty_stream); fclose(tty_stream); #else c = savec = getche(); while (c != EOF && c != '\r') c = getche(); fputs("\n", stderr); fflush_all(); #endif return (savec == 'y' || savec == 'Y'); }
/* Read /proc/interrupts, save IRQ counts and IRQ description */ static void process_irq_counts(void) { FILE *fp; char buf[128]; /* Reset values */ G.interrupt_0 = 0; G.total_interrupt = 0; fp = xfopen_for_read("/proc/interrupts"); while (fgets(buf, sizeof(buf), fp)) { char irq_desc[sizeof(" <kernel IPI> : ") + sizeof(buf)]; char *p; const char *name; int nr; ullong count; ullong delta; p = strchr(buf, ':'); if (!p) continue; /* 0: 143646045 153901007 IO-APIC-edge timer * ^ */ *p = '\0'; /* Deal with non-maskable interrupts -- make up fake numbers */ nr = index_in_strings("NMI\0RES\0CAL\0TLB\0TRM\0THR\0SPU\0", buf); if (nr >= 0) { nr += 20000; } else { /* bb_strtou doesn't eat leading spaces, using strtoul */ errno = 0; nr = strtoul(buf, NULL, 10); if (errno) continue; } p++; /* 0: 143646045 153901007 IO-APIC-edge timer * ^ */ /* Sum counts for this IRQ */ count = 0; while (1) { char *tmp; p = skip_whitespace(p); if (!isdigit(*p)) break; count += bb_strtoull(p, &tmp, 10); p = tmp; } /* 0: 143646045 153901007 IO-APIC-edge timer * NMI: 1 2 Non-maskable interrupts * ^ */ if (nr < 20000) { /* Skip to the interrupt name, e.g. 'timer' */ p = strchr(p, ' '); if (!p) continue; p = skip_whitespace(p); } name = p; strchrnul(name, '\n')[0] = '\0'; /* Save description of the interrupt */ if (nr >= 20000) sprintf(irq_desc, " <kernel IPI> : %s", name); else sprintf(irq_desc, " <interrupt> : %s", name); delta = save_irq_count(nr, count); /* Skip per CPU timer interrupts */ if (is_hpet_irq(name)) continue; if (nr != 0 && delta != 0) save_line(irq_desc, delta); if (nr == 0) G.interrupt_0 = delta; else G.total_interrupt += delta; } fclose(fp); }
int readprofile_main(int argc UNUSED_PARAM, char **argv) { FILE *map; const char *mapFile, *proFile; unsigned long indx = 1; size_t len; uint64_t add0 = 0; unsigned int step; unsigned int *buf, total, fn_len; unsigned long long fn_add, next_add; /* current and next address */ char fn_name[S_LEN], next_name[S_LEN]; /* current and next name */ char mapline[S_LEN]; char mode[8]; int maplineno = 1; int header_printed; int multiplier = 0; unsigned opt; enum { OPT_M = (1 << 0), OPT_m = (1 << 1), OPT_p = (1 << 2), OPT_n = (1 << 3), OPT_a = (1 << 4), OPT_b = (1 << 5), OPT_s = (1 << 6), OPT_i = (1 << 7), OPT_r = (1 << 8), OPT_v = (1 << 9), }; #define optMult (opt & OPT_M) #define optNative (opt & OPT_n) #define optAll (opt & OPT_a) #define optBins (opt & OPT_b) #define optSub (opt & OPT_s) #define optInfo (opt & OPT_i) #define optReset (opt & OPT_r) #define optVerbose (opt & OPT_v) #define next (current^1) proFile = defaultpro; mapFile = defaultmap; opt_complementary = "M+"; /* -M N */ opt = getopt32(argv, "M:m:p:nabsirv", &multiplier, &mapFile, &proFile); if (opt & (OPT_M|OPT_r)) { /* mult or reset, or both */ int fd, to_write; /* * When writing the multiplier, if the length of the write is * not sizeof(int), the multiplier is not changed */ to_write = sizeof(int); if (!optMult) to_write = 1; /* sth different from sizeof(int) */ fd = xopen(defaultpro, O_WRONLY); xwrite(fd, &multiplier, to_write); close(fd); return EXIT_SUCCESS; } /* * Use an fd for the profiling buffer, to skip stdio overhead */ len = MAXINT(ssize_t); buf = xmalloc_xopen_read_close(proFile, &len); if (!optNative) { int entries = len / sizeof(*buf); int big = 0, small = 0, i; unsigned *p; for (p = buf+1; p < buf+entries; p++) { if (*p & ~0U << (sizeof(*buf)*4)) big++; if (*p & ((1 << (sizeof(*buf)*4))-1)) small++; } if (big > small) { bb_error_msg("assuming revergsed byte order, " "use -n to force native byte order"); for (p = buf; p < buf+entries; p++) for (i = 0; i < sizeof(*buf)/2; i++) { unsigned char *b = (unsigned char *) p; unsigned char tmp; tmp = b[i]; b[i] = b[sizeof(*buf)-i-1]; b[sizeof(*buf)-i-1] = tmp; } } } step = buf[0]; if (optInfo) { printf("Sampling_step: %u\n", step); return EXIT_SUCCESS; } total = 0; map = xfopen_for_read(mapFile); while (fgets(mapline, S_LEN, map)) { if (sscanf(mapline, "%llx %s %s", &fn_add, mode, fn_name) != 3) bb_error_msg_and_die("%s(%i): wrong map line", mapFile, maplineno); if (!strcmp(fn_name, "_stext")) /* only elf works like this */ { add0 = fn_add; break; } maplineno++; } if (!add0) bb_error_msg_and_die("can't find \"_stext\" in %s", mapFile); /* * Main loop. */ while (fgets(mapline, S_LEN, map)) { unsigned int this = 0; if (sscanf(mapline, "%llx %s %s", &next_add, mode, next_name) != 3) bb_error_msg_and_die("%s(%i): wrong map line", mapFile, maplineno); header_printed = 0; /* ignore any LEADING (before a '[tT]' symbol is found) Absolute symbols */ if ((*mode == 'A' || *mode == '?') && total == 0) continue; if (*mode != 'T' && *mode != 't' && *mode != 'W' && *mode != 'w' ) { break; /* only text is profiled */ } if (indx >= len / sizeof(*buf)) bb_error_msg_and_die("profile address out of range. " "Wrong map file?"); while (indx < (next_add-add0)/step) { if (optBins && (buf[indx] || optAll)) { if (!header_printed) { printf("%s:\n", fn_name); header_printed = 1; } printf("\t%"PRIx64"\t%u\n", (indx - 1)*step + add0, buf[indx]); } this += buf[indx++]; } total += this; if (optBins) { if (optVerbose || this > 0) printf(" total\t\t\t\t%u\n", this); } else if ((this || optAll) && (fn_len = next_add-fn_add) != 0 ) { if (optVerbose) printf("%016llx %-40s %6u %8.4f\n", fn_add, fn_name, this, this/(double)fn_len); else printf("%6u %-40s %8.4f\n", this, fn_name, this/(double)fn_len); if (optSub) { unsigned long long scan; for (scan = (fn_add-add0)/step + 1; scan < (next_add-add0)/step; scan++) { unsigned long long addr; addr = (scan - 1)*step + add0; printf("\t%#llx\t%s+%#llx\t%u\n", addr, fn_name, addr - fn_add, buf[scan]); } } } fn_add = next_add; strcpy(fn_name, next_name); maplineno++; } /* clock ticks, out of kernel text - probably modules */ printf("%6u %s\n", buf[len/sizeof(*buf)-1], "*unknown*"); /* trailer */ if (optVerbose) printf("%016x %-40s %6u %8.4f\n", 0, "total", total, total/(double)(fn_add-add0)); else printf("%6u %-40s %8.4f\n", total, "total", total/(double)(fn_add-add0)); fclose(map); free(buf); return EXIT_SUCCESS; }
int sed_main(int argc UNUSED_PARAM, char **argv) { unsigned opt; llist_t *opt_e, *opt_f; char *opt_i; #if ENABLE_LONG_OPTS static const char sed_longopts[] ALIGN1 = /* name has_arg short */ "in-place\0" Optional_argument "i" "regexp-extended\0" No_argument "r" "quiet\0" No_argument "n" "silent\0" No_argument "n" "expression\0" Required_argument "e" "file\0" Required_argument "f"; #endif int status = EXIT_SUCCESS; INIT_G(); /* destroy command strings on exit */ if (ENABLE_FEATURE_CLEAN_UP) atexit(sed_free_and_close_stuff); /* Lie to autoconf when it starts asking stupid questions. */ if (argv[1] && strcmp(argv[1], "--version") == 0) { puts("This is not GNU sed version 4.0"); return 0; } /* do normal option parsing */ opt_e = opt_f = NULL; opt_i = NULL; opt_complementary = "e::f::" /* can occur multiple times */ "nn"; /* count -n */ IF_LONG_OPTS(applet_long_options = sed_longopts); /* -i must be first, to match OPT_in_place definition */ opt = getopt32(argv, "i::rne:f:", &opt_i, &opt_e, &opt_f, &G.be_quiet); /* counter for -n */ //argc -= optind; argv += optind; if (opt & OPT_in_place) { // -i atexit(cleanup_outname); } if (opt & 0x2) G.regex_type |= REG_EXTENDED; // -r //if (opt & 0x4) G.be_quiet++; // -n while (opt_e) { // -e add_cmd_block(llist_pop(&opt_e)); } while (opt_f) { // -f char *line; FILE *cmdfile; cmdfile = xfopen_for_read(llist_pop(&opt_f)); while ((line = xmalloc_fgetline(cmdfile)) != NULL) { add_cmd(line); free(line); } fclose(cmdfile); } /* if we didn't get a pattern from -e or -f, use argv[0] */ if (!(opt & 0x18)) { if (!*argv) bb_show_usage(); add_cmd_block(*argv++); } /* Flush any unfinished commands. */ add_cmd(""); /* By default, we write to stdout */ G.nonstdout = stdout; /* argv[0..(argc-1)] should be names of file to process. If no * files were specified or '-' was specified, take input from stdin. * Otherwise, we process all the files specified. */ if (argv[0] == NULL) { if (opt & OPT_in_place) bb_error_msg_and_die(bb_msg_requires_arg, "-i"); add_input_file(stdin); } else { int i; for (i = 0; argv[i]; i++) { struct stat statbuf; int nonstdoutfd; FILE *file; sed_cmd_t *sed_cmd; if (LONE_DASH(argv[i]) && !(opt & OPT_in_place)) { add_input_file(stdin); process_files(); continue; } file = fopen_or_warn(argv[i], "r"); if (!file) { status = EXIT_FAILURE; continue; } add_input_file(file); if (!(opt & OPT_in_place)) { continue; } /* -i: process each FILE separately: */ G.outname = xasprintf("%sXXXXXX", argv[i]); nonstdoutfd = xmkstemp(G.outname); G.nonstdout = xfdopen_for_write(nonstdoutfd); /* Set permissions/owner of output file */ fstat(fileno(file), &statbuf); /* chmod'ing AFTER chown would preserve suid/sgid bits, * but GNU sed 4.2.1 does not preserve them either */ fchmod(nonstdoutfd, statbuf.st_mode); fchown(nonstdoutfd, statbuf.st_uid, statbuf.st_gid); process_files(); fclose(G.nonstdout); G.nonstdout = stdout; if (opt_i) { char *backupname = xasprintf("%s%s", argv[i], opt_i); xrename(argv[i], backupname); free(backupname); } /* else unlink(argv[i]); - rename below does this */ xrename(G.outname, argv[i]); //TODO: rollback backup on error? free(G.outname); G.outname = NULL; /* Re-enable disabled range matches */ for (sed_cmd = G.sed_cmd_head; sed_cmd; sed_cmd = sed_cmd->next) { sed_cmd->beg_line = sed_cmd->beg_line_orig; } } /* Here, to handle "sed 'cmds' nonexistent_file" case we did: * if (G.current_input_file >= G.input_file_count) * return status; * but it's not needed since process_files() works correctly * in this case too. */ } process_files(); return status; }
int patch_main(int argc UNUSED_PARAM, char **argv) { struct stat saved_stat; char *patch_line; FILE *patch_file; int patch_level; int ret = 0; char plus = '+'; unsigned opt; enum { OPT_R = (1 << 2), OPT_N = (1 << 3), /*OPT_f = (1 << 4), ignored */ /*OPT_E = (1 << 5), ignored, this is the default */ /*OPT_g = (1 << 6), ignored */ OPT_dry_run = (1 << 7) * ENABLE_LONG_OPTS, }; xfunc_error_retval = 2; { const char *p = "-1"; const char *i = "-"; /* compat */ #if ENABLE_LONG_OPTS static const char patch_longopts[] ALIGN1 = "strip\0" Required_argument "p" "input\0" Required_argument "i" "reverse\0" No_argument "R" "forward\0" No_argument "N" /* "Assume user knows what [s]he is doing, do not ask any questions": */ "force\0" No_argument "f" /*ignored*/ # if ENABLE_DESKTOP "remove-empty-files\0" No_argument "E" /*ignored*/ /* "Controls actions when a file is under RCS or SCCS control, * and does not exist or is read-only and matches the default version, * or when a file is under ClearCase control and does not exist..." * IOW: rather obscure option. * But Gentoo's portage does use -g0 */ "get\0" Required_argument "g" /*ignored*/ # endif "dry-run\0" No_argument "\xfd" # if ENABLE_DESKTOP "backup-if-mismatch\0" No_argument "\xfe" /*ignored*/ "no-backup-if-mismatch\0" No_argument "\xff" /*ignored*/ # endif ; applet_long_options = patch_longopts; #endif /* -f,-E,-g are ignored */ opt = getopt32(argv, "p:i:RN""fEg:", &p, &i, NULL); if (opt & OPT_R) plus = '-'; patch_level = xatoi(p); /* can be negative! */ patch_file = xfopen_stdin(i); } patch_line = xmalloc_fgetline(patch_file); while (patch_line) { FILE *src_stream; FILE *dst_stream; //char *old_filename; char *new_filename; char *backup_filename = NULL; unsigned src_cur_line = 1; unsigned dst_cur_line = 0; unsigned dst_beg_line; unsigned bad_hunk_count = 0; unsigned hunk_count = 0; smallint copy_trailing_lines_flag = 0; /* Skip everything upto the "---" marker * No need to parse the lines "Only in <dir>", and "diff <args>" */ do { /* Extract the filename ugsed before the patch was generated */ new_filename = extract_filename(patch_line, patch_level, "--- "); // was old_filename above patch_line = xmalloc_fgetline(patch_file); if (!patch_line) goto quit; } while (!new_filename); free(new_filename); // "source" filename is irrelevant new_filename = extract_filename(patch_line, patch_level, "+++ "); if (!new_filename) { bb_error_msg_and_die("invalid patch"); } /* Get access rights from the file to be patched */ if (stat(new_filename, &saved_stat) != 0) { char *slash = strrchr(new_filename, '/'); if (slash) { /* Create leading directories */ *slash = '\0'; bb_make_directory(new_filename, -1, FILEUTILS_RECUR); *slash = '/'; } src_stream = NULL; saved_stat.st_mode = 0644; } else if (!(opt & OPT_dry_run)) { backup_filename = xasprintf("%s.orig", new_filename); xrename(new_filename, backup_filename); src_stream = xfopen_for_read(backup_filename); } else src_stream = xfopen_for_read(new_filename); if (opt & OPT_dry_run) { dst_stream = xfopen_for_write("/dev/null"); } else { dst_stream = xfopen_for_write(new_filename); fchmod(fileno(dst_stream), saved_stat.st_mode); } printf("patching file %s\n", new_filename); /* Handle all hunks for this file */ patch_line = xmalloc_fgets(patch_file); while (patch_line) { unsigned count; unsigned src_beg_line; unsigned hunk_offset_start; unsigned src_last_line = 1; unsigned dst_last_line = 1; if ((sscanf(patch_line, "@@ -%u,%u +%u,%u", &src_beg_line, &src_last_line, &dst_beg_line, &dst_last_line) < 3) && (sscanf(patch_line, "@@ -%u +%u,%u", &src_beg_line, &dst_beg_line, &dst_last_line) < 2) ) { /* No more hunks for this file */ break; } if (plus != '+') { /* reverse patch */ unsigned tmp = src_last_line; src_last_line = dst_last_line; dst_last_line = tmp; tmp = src_beg_line; src_beg_line = dst_beg_line; dst_beg_line = tmp; } hunk_count++; if (src_beg_line && dst_beg_line) { /* Copy unmodified lines upto start of hunk */ /* src_beg_line will be 0 if it's a new file */ count = src_beg_line - src_cur_line; if (copy_lines(src_stream, dst_stream, count)) { bb_error_msg_and_die("bad src file"); } src_cur_line += count; dst_cur_line += count; copy_trailing_lines_flag = 1; } src_last_line += hunk_offset_start = src_cur_line; dst_last_line += dst_cur_line; while (1) { free(patch_line); patch_line = xmalloc_fgets(patch_file); if (patch_line == NULL) break; /* EOF */ if (!*patch_line) { /* whitespace-damaged patch with "" lines */ free(patch_line); patch_line = xstrdup(" "); } if ((*patch_line != '-') && (*patch_line != '+') && (*patch_line != ' ') ) { break; /* End of hunk */ } if (*patch_line != plus) { /* '-' or ' ' */ char *src_line = NULL; if (src_cur_line == src_last_line) break; if (src_stream) { src_line = xmalloc_fgets(src_stream); if (src_line) { int diff = strcmp(src_line, patch_line + 1); src_cur_line++; free(src_line); if (diff) src_line = NULL; } } /* Do not patch an already patched hunk with -N */ if (src_line == 0 && (opt & OPT_N)) { continue; } if (!src_line) { bb_error_msg("hunk #%u FAILED at %u", hunk_count, hunk_offset_start); bad_hunk_count++; break; } if (*patch_line != ' ') { /* '-' */ continue; } } if (dst_cur_line == dst_last_line) break; fputs(patch_line + 1, dst_stream); dst_cur_line++; } /* end of while loop handling one hunk */ } /* end of while loop handling one file */ /* Cleanup last patched file */ if (copy_trailing_lines_flag) { copy_lines(src_stream, dst_stream, (unsigned)(-1)); } if (src_stream) { fclose(src_stream); } fclose(dst_stream); if (bad_hunk_count) { ret = 1; bb_error_msg("%u out of %u hunk FAILED", bad_hunk_count, hunk_count); } else { /* It worked, we can remove the backup */ if (backup_filename) { unlink(backup_filename); } if (!(opt & OPT_dry_run) && ((dst_cur_line == 0) || (dst_beg_line == 0)) ) { /* The new patched file is empty, remove it */ xunlink(new_filename); // /* old_filename and new_filename may be the same file */ // unlink(old_filename); } } free(backup_filename); //free(old_filename); free(new_filename); } /* end of "while there are patch lines" */ quit: /* 0 = SUCCESS * 1 = Some hunks failed * 2 = More serious problems (exited earlier) */ return ret; }
int hexdump_main(int argc, char **argv) { dumper_t *dumper = alloc_dumper(); const char *p; int ch; #if ENABLE_FEATURE_HEXDUMP_REVERSE FILE *fp; smallint rdump = 0; #endif if (ENABLE_HD && !applet_name[2]) { /* we are "hd" */ ch = 'C'; goto hd_applet; } /* We cannot use getopt32: in hexdump options are cumulative. * E.g. "hexdump -C -C file" should dump each line twice */ while ((ch = getopt(argc, argv, hexdump_opts)) > 0) { p = strchr(hexdump_opts, ch); if (!p) bb_show_usage(); if ((p - hexdump_opts) < 5) { bb_dump_add(dumper, add_first); bb_dump_add(dumper, add_strings[(int)(p - hexdump_opts)]); } /* Save a little bit of space below by omitting the 'else's. */ if (ch == 'C') { hd_applet: bb_dump_add(dumper, "\"%08.8_Ax\n\""); bb_dump_add(dumper, "\"%08.8_ax \" 8/1 \"%02x \" \" \" 8/1 \"%02x \" "); bb_dump_add(dumper, "\" |\" 16/1 \"%_p\" \"|\\n\""); } if (ch == 'e') { bb_dump_add(dumper, optarg); } /* else */ if (ch == 'f') { bb_dump_addfile(dumper, optarg); } /* else */ if (ch == 'n') { dumper->dump_length = xatoi_positive(optarg); } /* else */ if (ch == 's') { /* compat: -s accepts hex numbers too */ dumper->dump_skip = xstrtoull_range_sfx( optarg, /*base:*/ 0, /*lo:*/ 0, /*hi:*/ OFF_T_MAX, bkm_suffixes ); } /* else */ if (ch == 'v') { dumper->dump_vflag = ALL; } #if ENABLE_FEATURE_HEXDUMP_REVERSE if (ch == 'R') { rdump = 1; } #endif } if (!dumper->fshead) { bb_dump_add(dumper, add_first); bb_dump_add(dumper, "\"%07.7_ax \" 8/2 \"%04x \" \"\\n\""); } argv += optind; #if !ENABLE_FEATURE_HEXDUMP_REVERSE return bb_dump_dump(dumper, argv); #else if (!rdump) { return bb_dump_dump(dumper, argv); } /* -R: reverse of 'hexdump -Cv' */ fp = stdin; if (!*argv) { argv--; goto jump_in; } do { char *buf; fp = xfopen_for_read(*argv); jump_in: while ((buf = xmalloc_fgetline(fp)) != NULL) { p = buf; while (1) { /* skip address or previous byte */ while (isxdigit(*p)) p++; while (*p == ' ') p++; /* '|' char will break the line */ if (!isxdigit(*p) || sscanf(p, "%x ", &ch) != 1) break; putchar(ch); } free(buf); } fclose(fp); } while (*++argv); fflush_stdout_and_exit(EXIT_SUCCESS); #endif }
int patch_main(int argc UNUSED_PARAM, char **argv) { struct stat saved_stat; char *patch_line; FILE *patch_file; int patch_level; int ret = 0; char plus = '+'; xfunc_error_retval = 2; { const char *p = "-1"; const char *i = "-"; /* compat */ if (getopt32(argv, "p:i:R", &p, &i) & 4) plus = '-'; patch_level = xatoi(p); /* can be negative! */ patch_file = xfopen_stdin(i); } patch_line = xmalloc_fgetline(patch_file); while (patch_line) { FILE *src_stream; FILE *dst_stream; //char *old_filename; char *new_filename; char *backup_filename; unsigned src_cur_line = 1; unsigned dst_cur_line = 0; unsigned dst_beg_line; unsigned bad_hunk_count = 0; unsigned hunk_count = 0; smallint copy_trailing_lines_flag = 0; /* Skip everything upto the "---" marker * No need to parse the lines "Only in <dir>", and "diff <args>" */ do { /* Extract the filename used before the patch was generated */ new_filename = extract_filename(patch_line, patch_level, "--- "); // was old_filename above patch_line = xmalloc_fgetline(patch_file); if (!patch_line) goto quit; } while (!new_filename); free(new_filename); // "source" filename is irrelevant new_filename = extract_filename(patch_line, patch_level, "+++ "); if (!new_filename) { bb_error_msg_and_die("invalid patch"); } /* Get access rights from the file to be patched */ if (stat(new_filename, &saved_stat) != 0) { char *slash = strrchr(new_filename, '/'); if (slash) { /* Create leading directories */ *slash = '\0'; bb_make_directory(new_filename, -1, FILEUTILS_RECUR); *slash = '/'; } backup_filename = NULL; src_stream = NULL; saved_stat.st_mode = 0644; } else { backup_filename = xasprintf("%s.orig", new_filename); xrename(new_filename, backup_filename); src_stream = xfopen_for_read(backup_filename); } dst_stream = xfopen_for_write(new_filename); fchmod(fileno(dst_stream), saved_stat.st_mode); printf("patching file %s\n", new_filename); /* Handle all hunks for this file */ patch_line = xmalloc_fgets(patch_file); while (patch_line) { unsigned count; unsigned src_beg_line; unsigned hunk_offset_start; unsigned src_last_line = 1; unsigned dst_last_line = 1; if ((sscanf(patch_line, "@@ -%d,%d +%d,%d", &src_beg_line, &src_last_line, &dst_beg_line, &dst_last_line) < 3) && (sscanf(patch_line, "@@ -%d +%d,%d", &src_beg_line, &dst_beg_line, &dst_last_line) < 2) ) { /* No more hunks for this file */ break; } if (plus != '+') { /* reverse patch */ unsigned tmp = src_last_line; src_last_line = dst_last_line; dst_last_line = tmp; tmp = src_beg_line; src_beg_line = dst_beg_line; dst_beg_line = tmp; } hunk_count++; if (src_beg_line && dst_beg_line) { /* Copy unmodified lines upto start of hunk */ /* src_beg_line will be 0 if it's a new file */ count = src_beg_line - src_cur_line; if (copy_lines(src_stream, dst_stream, count)) { bb_error_msg_and_die("bad src file"); } src_cur_line += count; dst_cur_line += count; copy_trailing_lines_flag = 1; } src_last_line += hunk_offset_start = src_cur_line; dst_last_line += dst_cur_line; while (1) { free(patch_line); patch_line = xmalloc_fgets(patch_file); if (patch_line == NULL) break; /* EOF */ if ((*patch_line != '-') && (*patch_line != '+') && (*patch_line != ' ') ) { break; /* End of hunk */ } if (*patch_line != plus) { /* '-' or ' ' */ char *src_line = NULL; if (src_cur_line == src_last_line) break; if (src_stream) { src_line = xmalloc_fgets(src_stream); if (src_line) { int diff = strcmp(src_line, patch_line + 1); src_cur_line++; free(src_line); if (diff) src_line = NULL; } } if (!src_line) { bb_error_msg("hunk #%u FAILED at %u", hunk_count, hunk_offset_start); bad_hunk_count++; break; } if (*patch_line != ' ') { /* '-' */ continue; } } if (dst_cur_line == dst_last_line) break; fputs(patch_line + 1, dst_stream); dst_cur_line++; } /* end of while loop handling one hunk */ } /* end of while loop handling one file */ /* Cleanup last patched file */ if (copy_trailing_lines_flag) { copy_lines(src_stream, dst_stream, (unsigned)(-1)); } if (src_stream) { fclose(src_stream); } fclose(dst_stream); if (bad_hunk_count) { ret = 1; bb_error_msg("%u out of %u hunk FAILED", bad_hunk_count, hunk_count); } else { /* It worked, we can remove the backup */ if (backup_filename) { unlink(backup_filename); } if ((dst_cur_line == 0) || (dst_beg_line == 0)) { /* The new patched file is empty, remove it */ xunlink(new_filename); // /* old_filename and new_filename may be the same file */ // unlink(old_filename); } } free(backup_filename); //free(old_filename); free(new_filename); } /* end of "while there are patch lines" */ quit: /* 0 = SUCCESS * 1 = Some hunks failed * 2 = More serious problems (exited earlier) */ return ret; }
static int readmode(struct fb_var_screeninfo *base, const char *fn, const char *mode) { FILE *f; char buf[256]; char *p = buf; f = xfopen_for_read(fn); while (fgets(buf, sizeof(buf), f)) { p = strstr(buf, "mode "); if (!p && !(p = strstr(buf, "mode\t"))) continue; p = strstr(p + 5, mode); if (!p) continue; p += strlen(mode); if (!isspace(*p) && (*p != 0) && (*p != '"') && (*p != '\r') && (*p != '\n') ) { continue; /* almost, but not quite */ } while (fgets(buf, sizeof(buf), f)) { if ((p = strstr(buf, "geometry "))) { p += 9; /* FIXME: catastrophic on arches with 64bit ints */ sscanf(p, "%d %d %d %d %d", &(base->xres), &(base->yres), &(base->xres_virtual), &(base->yres_virtual), &(base->bits_per_pixel)); } else if ((p = strstr(buf, "timings "))) { p += 8; sscanf(p, "%d %d %d %d %d %d %d", &(base->pixclock), &(base->left_margin), &(base->right_margin), &(base->upper_margin), &(base->lower_margin), &(base->hsync_len), &(base->vsync_len)); } else if ((p = strstr(buf, "laced "))) { //p += 6; ss(&base->vmode, FB_VMODE_INTERLACED, buf, "false"); } else if ((p = strstr(buf, "double "))) { //p += 7; ss(&base->vmode, FB_VMODE_DOUBLE, buf, "false"); } else if ((p = strstr(buf, "vsync "))) { //p += 6; ss(&base->sync, FB_SYNC_VERT_HIGH_ACT, buf, "low"); } else if ((p = strstr(buf, "hsync "))) { //p += 6; ss(&base->sync, FB_SYNC_HOR_HIGH_ACT, buf, "low"); } else if ((p = strstr(buf, "csync "))) { //p += 6; ss(&base->sync, FB_SYNC_COMP_HIGH_ACT, buf, "low"); } else if ((p = strstr(buf, "extsync "))) { //p += 8; ss(&base->sync, FB_SYNC_EXT, buf, "false"); } if (strstr(buf, "endmode")) return 1; } } return 0; }