예제 #1
0
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);
}
예제 #2
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);
}