int main(int argc, const char * const argv[]) { int fd, fdout; size_t read_size, block_size; unsigned int i, begin_index; unsigned char *start, *end, *addr; size_t size; int page_size; off_t offset; const char *file_format; const char *dir_format; int c; read_size = 128 * 1024 * 1024; block_size = 512; begin_index = 0; file_format = "image%05d.jpg"; dir_format = NULL; while ((c = getopt(argc, (char * const *) argv, "b:d:f:hi:m:qr:s:vV")) != -1) { switch (c) { case 'b': block_size = atol_suffix(optarg); break; case 'd': dir_format = optarg; break; case 'f': file_format = optarg; break; case 'i': begin_index = atoi(optarg); break; case 'm': max_size = atol_suffix(optarg); break; case 'q': quiet = 1; break; case 'r': read_size = atol_suffix(optarg); break; case 's': ignore_size = atol_suffix(optarg) - 1; break; case 'v': verbose = 1; break; case 'V': display_version_and_exit("recoverjpeg"); default: usage(c == 'h'); } } argc -= optind; argv += optind; if (argc != 1) { usage(0); } fd = open(argv[0], O_RDONLY); if (fd < 0) { fprintf(stderr, "recoverjpeg: unable to open %s for reading (%s)\n", argv[argc - 1], strerror(errno)); exit(1); } page_size = getpagesize(); if (read_size % page_size || read_size < max_size) { if (read_size < max_size) { read_size = max_size; } read_size = (read_size + page_size - 1) / page_size * page_size; if (!quiet) { fprintf(stderr, "Adjusted read size to %ld bytes\n", (long) read_size); } } start = end = (unsigned char *) malloc(read_size); if (start == 0) { fprintf(stderr, "recoverjpeg: cannot allocate necessary memory (%s)\n", strerror(errno)); exit(1); } for (i = 0, offset = 0, addr = NULL; addr < end;) { if (progressbar()) { display_progressbar(offset, i); } if (addr == NULL || (size_t) (start + read_size - addr) < max_size) { off_t base_offset; long n; base_offset = offset / page_size * page_size; lseek(fd, base_offset, SEEK_SET); n = read(fd, start, read_size); if (n < 0) { fprintf(stderr, "recoverjpeg: unable to read data (%s)\n", strerror(errno)); exit(1); } end = start + n; addr = start + (offset - base_offset); } size = jpeg_size(addr); if (size > ignore_size) { size_t n; const char *buffer = file_name(dir_format, file_format, begin_index + i); i++; if (verbose) { printf("%s %ld bytes\n", buffer, (long) size); } fdout = open(buffer, O_WRONLY | O_CREAT, 0666); if (fdout < 0) { fprintf(stderr, "Unable to open %s for writing\n", buffer); exit(1); } if ((size_t) write(fdout, addr, size) != size) { fprintf(stderr, "Unable to write %ld bytes to %s\n", (long) size, buffer); exit(1); } close(fdout); n = ((size + block_size - 1) / block_size) * block_size; addr += n; offset += n; } else { addr += block_size; offset += block_size; } } if (progressbar()) { cleanup_progressbar(); } if (!quiet) { printf("Restored %d picture%s\n", i, i > 1 ? "s" : ""); } /* Free allocated memory to keep valgrind happy */ free(start); exit(0); }
int main(int argc, char **argv) { prog_name = argv[0]; int show_the_system_info = 0; int show_the_numastat_info = 0; static struct option long_options[] = { {"help", 0, 0, '?'}, {0, 0, 0, 0} }; int long_option_index = 0; int opt; while ((opt = getopt_long(argc, argv, "cmnp:s::vVz?", long_options, &long_option_index)) != -1) { switch (opt) { case 0: printf("Unexpected long option %s", long_options[long_option_index].name); if (optarg) { printf(" with arg %s", optarg); } printf("\n"); display_usage_and_exit(); break; case 'c': compress_display = 1; break; case 'm': show_the_system_info = 1; break; case 'n': show_the_numastat_info = 1; break; case 'p': if ((optarg) && (all_digits(optarg))) { add_pid_to_list(atoi(optarg)); } else { add_pids_from_pattern_search(optarg); } break; case 's': sort_table = 1; if ((optarg) && (all_digits(optarg))) { sort_table_node = atoi(optarg); } break; case 'v': verbose = 1; break; case 'V': display_version_and_exit(); break; case 'z': show_zero_data = 0; break; default: case '?': display_usage_and_exit(); break; } } // Figure out the display width, which is used to format the tables // and limit the output columns per row screen_width = get_screen_width(); // Any remaining arguments are assumed to be additional process specifiers while (optind < argc) { if (all_digits(argv[optind])) { add_pid_to_list(atoi(argv[optind])); } else { add_pids_from_pattern_search(argv[optind]); } optind += 1; } // If there are no program options or arguments, be extremely compatible // with the old numastat perl script (which is included at the end of this // file for reference) compatibility_mode = (argc == 1); init_node_ix_map_and_header(compatibility_mode); // enumarate the NUMA nodes if (compatibility_mode) { show_numastat_info(); free_node_ix_map_and_header(); exit(EXIT_SUCCESS); } // Figure out page sizes page_size_in_bytes = (double)sysconf(_SC_PAGESIZE); huge_page_size_in_bytes = get_huge_page_size_in_bytes(); // Display the info for the process specifiers if (num_pids > 0) { sort_pids_and_remove_duplicates(); show_process_info(); } if (pid_array != NULL) { free(pid_array); } // Display the system-wide memory usage info if (show_the_system_info) { show_system_info(); } // Display the numastat statistics info if ((show_the_numastat_info) || ((num_pids == 0) && (!show_the_system_info))) { show_numastat_info(); } free_node_ix_map_and_header(); exit(EXIT_SUCCESS); }