Ejemplo n.º 1
0
int main(int argc, char *argv[])
{
	setlocale (LC_ALL, "");
	bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
	bindtextdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR);
	textdomain (GETTEXT_PACKAGE);

	gboolean explicit_username = FALSE;
	gboolean explicit_message = FALSE;
	int error = 0;
	int m = 0, i = 1;
	guint counter = 0;
	gchar *command = NULL;
	gchar *command_run = NULL;
	gchar *username = NULL;
	gchar *password = NULL;

	uid_t whoami;
	struct passwd *pw;

	char err_msg[256];

	gchar *message = NULL;

	char **cmd_argv = NULL;
	GError *cmd_error = NULL;

	GtkWidget *dialog;
	GtkSizeGroup *sizegroup;
	GtkWidget *hbox;
	GtkWidget *image;
	GtkWidget *align;
	GtkWidget *label;
	GtkWidget *user;
	GtkWidget *pass;

	gtk_init(&argc, &argv);

	/* Parse arguments */
	while (i < argc) {
		if (argv[i][0] != '-')
			break;
		if (!strcmp(argv[i], "--help") || !strcmp(argv[i], "-h"))
			say_help(argv[0]);
		if (!strcmp(argv[i], "--version") || !strcmp(argv[i], "-v"))
			say_about();
		if (!strcmp(argv[i], "--user") || !strcmp(argv[i], "-u")) {
			if ((username = argv[i + 1]) == NULL)
				Werror(ERR_MISSING_USER_AND_COMMAND, NULL, 1, 1);
			explicit_username = TRUE;
			i += 1;
		}
		if (!strcmp(argv[i], "--message") || !strcmp(argv[i], "-m")) {
			if ((message = argv[i + 1]) == NULL)
				Werror(ERR_MISSING_MESSAGE_AND_COMMAND, NULL, 1, 1);
			explicit_message = TRUE;
			i += 1;
		}
		i += 1;
	}

	if (argv[i] == NULL)
		Werror(ERR_MISSING_COMMAND, NULL, 1, 1);

	/* handle arguments and spaces in the subcommand correctly */
	if (! g_shell_parse_argv(argv[i], NULL, &cmd_argv, &cmd_error))
		/* Something bad has happened */
		Werror(ERR_INVALID_COMMAND, cmd_error->message, 1, 1);

	/* Get the full path command */
	command = get_real_name(cmd_argv[0]);
	if (command == NULL)
		Werror(ERR_INVALID_COMMAND, cmd_argv[0], 1, 1);

	/* Sanity check */
	whoami = getuid();
	if ((pw = getpwuid(whoami)) == NULL)
		exit(2 + 0 * fprintf(stderr, "Who you think you are? Houdini?\n"));

	if (!explicit_username)
		username = g_strdup("root");

	if (username && !strcmp(pw->pw_name, username)) {
		/* username was me so let's just run it and get the hell out */
		if (execvp(command, &(cmd_argv[0])) == -1) {
			Werror(ERR_PERMISSION_DENIED, NULL, 1, 1);
			exit(1);
		}
		/* We should never get here, but just in case */
		exit(0);
	}

	if (explicit_username && !explicit_message)
		message = g_strdup_printf(gettext("Please enter the\npassword for %s:"), username);
	else if (!explicit_message)
		message = g_strdup(gettext("Please enter the desired\nusername and password:"******"ktsuss");
	gtk_container_set_border_width(GTK_CONTAINER(dialog), 5);
	gtk_container_set_border_width(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), 5);
	gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(dialog)->vbox), 5);
	hbox = gtk_hbox_new(FALSE, 6);
#if GTK_CHECK_VERSION(2, 10, 0)
	image = gtk_image_new_from_stock(GTK_STOCK_DIALOG_AUTHENTICATION, GTK_ICON_SIZE_DIALOG);
#else
	image = gtk_image_new_from_icon_name("ktsuss", GTK_ICON_SIZE_DIALOG);
#endif
	gtk_box_pack_start(GTK_BOX(hbox), image, FALSE, FALSE, 0);
	label = gtk_label_new(message);
	gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
	gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), hbox);
	sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
	if (!explicit_username) {
		hbox = gtk_hbox_new(FALSE, 6);
		label = gtk_label_new(gettext("Username"));
		align = gtk_alignment_new(0, 0.5, 0, 0);
		gtk_container_add(GTK_CONTAINER(align), label);
		gtk_size_group_add_widget(sizegroup, align);
		gtk_box_pack_start(GTK_BOX(hbox), align, FALSE, FALSE, 0);
		user = gtk_entry_new();
		gtk_entry_set_text(GTK_ENTRY(user), username ? username : "******");
		gtk_box_pack_start(GTK_BOX(hbox), user, FALSE, FALSE, 0);
		gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), hbox);
	}
	hbox = gtk_hbox_new(FALSE, 6);
	label = gtk_label_new(gettext("Password"));
	align = gtk_alignment_new(0, 0.5, 0, 0);
	gtk_container_add(GTK_CONTAINER(align), label);
	gtk_size_group_add_widget(sizegroup, align);
	gtk_box_pack_start(GTK_BOX(hbox), align, FALSE, FALSE, 0);
	pass = gtk_entry_new_with_max_length(32);
	gtk_entry_set_visibility(GTK_ENTRY(pass), FALSE);
	gtk_box_pack_start(GTK_BOX(hbox), pass, FALSE, FALSE, 0);
	gtk_entry_set_activates_default(GTK_ENTRY(pass), TRUE);
	gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), hbox);
	gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK);
	gtk_widget_grab_focus(pass);
	gtk_widget_show_all(GTK_DIALOG(dialog)->vbox);

	/* Show the dialog up to 3 times */
	while (counter < 3) {
		if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK) {
			if (!explicit_username)
				username = strdup(gtk_entry_get_text(GTK_ENTRY(user)));
			password = strdup(gtk_entry_get_text(GTK_ENTRY(pass)));

#ifdef SUDOPATH
			if ((error = check_password_sudo(username, password)) == ERR_SUCCESS) {
#else
			if ((error = check_password_su(username, password)) == ERR_SUCCESS) {
#endif
				gtk_widget_destroy(dialog);
				while (gtk_events_pending())
					gtk_main_iteration();
				dialog = NULL;
				/* using argv instead of cmd_argv is fine, because 'su' is going
				 * to implement its only parsing nevertheless */
				command_run = g_strjoinv(" ", &argv[i]);
#ifdef SUDOPATH
				run_sudo(username, password, command_run);
#else
				run_su(username, password, command_run);
#endif
				g_free(command_run);

				counter = 3;
			}
			if (!explicit_username) {
				free(username);
				username = NULL;
			}
			memset(password, '\0', strlen(password));
			free(password);
			if (error != ERR_SUCCESS) {
				snprintf(err_msg, sizeof(err_msg), gettext("Could not run '%s'"), command);
				Werror(error, err_msg, 0, 0);
				counter++;
			}
		}
		else
			break;
		if (counter < 3)
			gtk_widget_grab_focus(pass);
	}

	/* Clean up process */
	if (dialog)
		gtk_widget_destroy(dialog);
	if ((explicit_username && !explicit_message) || !explicit_message)
        free(message);
	if (!explicit_username && username)
		g_free(username);
	
	g_strfreev(cmd_argv);
	if (cmd_error)
		g_error_free(cmd_error);

	return 0;
}
Ejemplo n.º 2
0
int main( int argc, char **argv )
{
  int i;
  int use_sudo=0;
  int create_log=TD_LOG_NONE;
  int run_setlocale=1;
  int testdisk_mode=TESTDISK_O_RDONLY|TESTDISK_O_READAHEAD_32K;
  list_disk_t *list_disk=NULL;
  list_disk_t *element_disk;
  const char *logfile="photorec.log";
  FILE *log_handle=NULL;
  int log_errno=0;
  struct ph_options options={
    .paranoid=1,
    .keep_corrupted_file=0,
    .mode_ext2=0,
    .expert=0,
    .lowmem=0,
    .verbose=0,
    .list_file_format=list_file_enable
  };
  struct ph_param params;
  params.recup_dir=NULL;
  params.cmd_device=NULL;
  params.cmd_run=NULL;
  params.carve_free_space_only=0;
  /* random (weak is ok) is need fot GPT */
  srand(time(NULL));
#ifdef HAVE_SIGACTION
  /* set up the signal handler for SIGINT & SIGHUP */
  sigemptyset(&action.sa_mask);
  sigaddset(&action.sa_mask, SIGINT);
  sigaddset(&action.sa_mask, SIGHUP);
  action.sa_handler  = sighup_hdlr;
  action.sa_flags = 0;
  if(sigaction(SIGINT, &action, NULL)==-1)
  {
    printf("Error on SIGACTION call\n");
    return -1;
  }
  if(sigaction(SIGHUP, &action, NULL)==-1)
  {
    printf("Error on SIGACTION call\n");
    return -1;
  }
#endif
  printf("PhotoRec %s, Data Recovery Utility, %s\nChristophe GRENIER <*****@*****.**>\nhttp://www.cgsecurity.org\n",VERSION,TESTDISKDATE);
  for(i=1;i<argc;i++)
  {
    if((strcmp(argv[i],"/logname")==0) ||(strcmp(argv[i],"-logname")==0))
    {
      if(i+2>=argc)
      {
	display_help();
	free(params.recup_dir);
	return 1;
      }
      logfile=argv[++i];
    }
    else if((strcmp(argv[i],"/log")==0) ||(strcmp(argv[i],"-log")==0))
    {
      if(create_log==TD_LOG_NONE)
        create_log=TD_LOG_APPEND;
    }
    else if((strcmp(argv[i],"/debug")==0) || (strcmp(argv[i],"-debug")==0))
    {
      options.verbose++;
      if(create_log==TD_LOG_NONE)
        create_log=TD_LOG_APPEND;
    }
    else if(((strcmp(argv[i],"/d")==0)||(strcmp(argv[i],"-d")==0)) &&(i+1<argc))
    {
      int len=strlen(argv[i+1]);
      if(argv[i+1][len-1]=='\\' || argv[i+1][len-1]=='/')
      {
        params.recup_dir=(char *)MALLOC(len + strlen(DEFAULT_RECUP_DIR) + 1);
        strcpy(params.recup_dir,argv[i+1]);
        strcat(params.recup_dir,DEFAULT_RECUP_DIR);
      }
      else
        params.recup_dir=strdup(argv[i+1]);
      i++;
    }
    else if((strcmp(argv[i],"/all")==0) || (strcmp(argv[i],"-all")==0))
      testdisk_mode|=TESTDISK_O_ALL;
    else if((strcmp(argv[i],"/direct")==0) || (strcmp(argv[i],"-direct")==0))
      testdisk_mode|=TESTDISK_O_DIRECT;
    else if((strcmp(argv[i],"/help")==0) || (strcmp(argv[i],"-help")==0) || (strcmp(argv[i],"--help")==0) ||
      (strcmp(argv[i],"/h")==0) || (strcmp(argv[i],"-h")==0) ||
      (strcmp(argv[i],"/?")==0) || (strcmp(argv[i],"-?")==0))
    {
      display_help();
      free(params.recup_dir);
      return 0;
    }
    else if((strcmp(argv[i],"/version")==0) || (strcmp(argv[i],"-version")==0) || (strcmp(argv[i],"--version")==0) ||
      (strcmp(argv[i],"/v")==0) || (strcmp(argv[i],"-v")==0))
    {
      display_version();
      free(params.recup_dir);
      return 0;
    }
    else if((strcmp(argv[i],"/nosetlocale")==0) || (strcmp(argv[i],"-nosetlocale")==0))
      run_setlocale=0;
    else if(strcmp(argv[i],"/cmd")==0)
    {
      if(i+2>=argc)
      {
	display_help();
	free(params.recup_dir);
	return 1;
      }
      {
        disk_t *disk_car;
        params.cmd_device=argv[++i];
        params.cmd_run=argv[++i];
        /* There is no log currently */
        disk_car=file_test_availability(params.cmd_device, options.verbose, testdisk_mode);
        if(disk_car==NULL)
        {
          printf("\nUnable to open file or device %s: %s\n", params.cmd_device, strerror(errno));
	  free(params.recup_dir);
	  return 1;
        }
	list_disk=insert_new_disk(list_disk,disk_car);
      }
    }
    else
    {
      disk_t *disk_car=file_test_availability(argv[i], options.verbose, testdisk_mode);
      if(disk_car==NULL)
      {
        printf("\nUnable to open file or device %s: %s\n", argv[i], strerror(errno));
	free(params.recup_dir);
	return 1;
      }
      list_disk=insert_new_disk(list_disk,disk_car);
    }
  }
#ifdef ENABLE_DFXML
  xml_set_command_line(argc, argv);
#endif
  if(create_log!=TD_LOG_NONE)
    log_handle=log_open(logfile, create_log, &log_errno);
#ifdef HAVE_SETLOCALE
  if(run_setlocale>0)
  {
    const char *locale;
    locale = setlocale (LC_ALL, "");
    if (locale==NULL) {
      locale = setlocale (LC_ALL, NULL);
      log_error("Failed to set locale, using default '%s'.\n", locale);
    } else {
      log_info("Using locale '%s'.\n", locale);
    }
  }
#endif
  if(create_log!=TD_LOG_NONE && log_handle==NULL)
    log_handle=log_open_default(logfile, create_log, &log_errno);
#ifdef HAVE_NCURSES
  /* ncurses need locale for correct unicode support */
  if(start_ncurses("PhotoRec", argv[0]))
  {
    free(params.recup_dir);
    return 1;
  }
  {
    const char*filename=logfile;
    while(create_log!=TD_LOG_NONE && log_handle==NULL)
    {
      filename=ask_log_location(filename, log_errno);
      if(filename!=NULL)
	log_handle=log_open(filename, create_log, &log_errno);
      else
	create_log=TD_LOG_NONE;
    }
  }
  aff_copy(stdscr);
  wmove(stdscr,5,0);
  wprintw(stdscr, "Disk identification, please wait...\n");
  wrefresh(stdscr);
#endif
  if(log_handle!=NULL)
  {
    time_t my_time;
#ifdef HAVE_DUP2
    dup2(fileno(log_handle),2);
#endif
    my_time=time(NULL);
    log_info("\n\n%s",ctime(&my_time));
    log_info("Command line: PhotoRec");
    for(i=1;i<argc;i++)
      log_info(" %s", argv[i]);
    log_info("\n\n");
  }
  log_info("PhotoRec %s, Data Recovery Utility, %s\nChristophe GRENIER <*****@*****.**>\nhttp://www.cgsecurity.org\n", VERSION, TESTDISKDATE);
  log_info("OS: %s\n" , get_os());
  log_info("Compiler: %s\n", get_compiler());
  log_info("Compilation date: %s\n", get_compilation_date());
  log_info("ext2fs lib: %s, ntfs lib: %s, ewf lib: %s, libjpeg: %s\n",
      td_ext2fs_version(), td_ntfs_version(), td_ewf_version(), td_jpeg_version());
#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(DJGPP)
#else
#ifdef HAVE_GETEUID
  if(geteuid()!=0)
  {
    log_warning("User is not root!\n");
  }
#endif
#endif
  log_flush();
  screen_buffer_reset();
  /* Scan for available device only if no device or image has been supplied in parameter */
  if(list_disk==NULL)
    list_disk=hd_parse(list_disk, options.verbose, testdisk_mode);
  hd_update_all_geometry(list_disk, options.verbose);
  /* Activate the cache, even if photorec has its own */
  for(element_disk=list_disk;element_disk!=NULL;element_disk=element_disk->next)
  {
    element_disk->disk=new_diskcache(element_disk->disk, testdisk_mode);
  }
  log_disk_list(list_disk);
  reset_list_file_enable(options.list_file_format);
  file_options_load(options.list_file_format);
#ifdef SUDO_BIN
  if(list_disk==NULL)
  {
#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(DJGPP)
#else
#ifdef HAVE_GETEUID
    if(geteuid()!=0)
      use_sudo=2;
#endif
#endif
  }
#endif
  if(use_sudo==0)
    use_sudo=do_curses_photorec(&params, &options, list_disk);
#ifdef HAVE_NCURSES
  end_ncurses();
#endif
  log_info("PhotoRec exited normally.\n");
  if(log_close()!=0)
  {
    printf("PhotoRec: Log file corrupted!\n");
  }
  else if(params.cmd_run!=NULL && params.cmd_run[0]!='\0')
  {
    printf("PhotoRec syntax error: %s\n", params.cmd_run);
  }
#ifdef SUDO_BIN
  if(use_sudo>0)
  {
    printf("\n");
    if(use_sudo>1)
      printf("No disk found.\n");
    printf("PhotoRec will try to restart itself using the sudo command to get\n");
    printf("root (superuser) privileges.\n");
    printf("\n");
    run_sudo(argc, argv);
  }
#endif
  delete_list_disk(list_disk);
  free(params.recup_dir);
#ifdef ENABLE_DFXML
  xml_clear_command_line();
#endif
  return 0;
}
Ejemplo n.º 3
0
int main( int argc, char **argv )
{
  int i;
  int use_sudo=0;
  int help=0, version=0, verbose=0, dump_ind=0;
  int create_log=TD_LOG_NONE;
  int do_list=0;
  int unit=UNIT_DEFAULT;
  int write_used;
  int saveheader=0;
  int create_backup=0;
  int run_setlocale=1;
  int done=0;
  int safe=0;
  int testdisk_mode=TESTDISK_O_RDWR|TESTDISK_O_READAHEAD_8K;
  list_disk_t *list_disk=NULL;
  list_disk_t *element_disk;
  const char *cmd_device=NULL;
  char *cmd_run=NULL;
  const char *logfile="testdisk.log";
  FILE *log_handle=NULL;
  int log_errno=0;
  /* srand needed for GPT creation (weak is ok) */
  srand(time(NULL));
#ifdef HAVE_SIGACTION
  /* set up the signal handler for SIGINT & SIGHUP */
  sigemptyset(&action.sa_mask);
  sigaddset(&action.sa_mask, SIGINT);
  sigaddset(&action.sa_mask, SIGHUP);
  action.sa_handler  = sighup_hdlr;
  action.sa_flags = 0;
  if(sigaction(SIGINT, &action, NULL)==-1)
  {
    printf("Error on SIGACTION call\n");
    return -1;
  }
  if(sigaction(SIGHUP, &action, NULL)==-1)
  {
    printf("Error on SIGACTION call\n");
    return -1;
  }
#endif
  printf("TestDisk %s, Data Recovery Utility, %s\nChristophe GRENIER <*****@*****.**>\nhttp://www.cgsecurity.org\n",VERSION,TESTDISKDATE);
  for(i=1;i<argc;i++)
  {
    if((strcmp(argv[i],"/dump")==0) || (strcmp(argv[i],"-dump")==0))
      dump_ind=1;
    else if((strcmp(argv[i],"/logname")==0) ||(strcmp(argv[i],"-logname")==0))
    {
      if(i+2>=argc)
	help=1;
      else
	logfile=argv[++i];
    }
    else if((strcmp(argv[i],"/log")==0) ||(strcmp(argv[i],"-log")==0))
    {
      if(create_log==TD_LOG_NONE)
        create_log=TD_LOG_APPEND;
      if(log_handle==NULL)
	log_handle=log_open(logfile, create_log, &log_errno);
    }
    else if((strcmp(argv[i],"/debug")==0) || (strcmp(argv[i],"-debug")==0))
    {
      verbose++;
      if(create_log==TD_LOG_NONE)
        create_log=TD_LOG_APPEND;
      if(log_handle==NULL)
	log_handle=log_open(logfile, create_log, &log_errno);
    }
    else if((strcmp(argv[i],"/all")==0) || (strcmp(argv[i],"-all")==0))
      testdisk_mode|=TESTDISK_O_ALL;
    else if((strcmp(argv[i],"/backup")==0) || (strcmp(argv[i],"-backup")==0))
      create_backup=1;
    else if((strcmp(argv[i],"/direct")==0) || (strcmp(argv[i],"-direct")==0))
      testdisk_mode|=TESTDISK_O_DIRECT;
    else if((strcmp(argv[i],"/help")==0) || (strcmp(argv[i],"-help")==0) || (strcmp(argv[i],"--help")==0) ||
      (strcmp(argv[i],"/h")==0) || (strcmp(argv[i],"-h")==0) ||
      (strcmp(argv[i],"/?")==0) || (strcmp(argv[i],"-?")==0))
      help=1;
    else if((strcmp(argv[i],"/version")==0) || (strcmp(argv[i],"-version")==0) || (strcmp(argv[i],"--version")==0) ||
      (strcmp(argv[i],"/v")==0) || (strcmp(argv[i],"-v")==0))
      version=1;
    else if(strcmp(argv[i],"/list")==0 || strcmp(argv[i],"-list")==0 || strcmp(argv[i],"-l")==0)
    {
      do_list=1;
    }
    else if(strcmp(argv[i],"-lu")==0)
    {
      do_list=1;
      unit=UNIT_SECTOR;
    }
    else if((strcmp(argv[i],"/nosetlocale")==0) || (strcmp(argv[i],"-nosetlocale")==0))
      run_setlocale=0;
    else if((strcmp(argv[i],"/safe")==0) || (strcmp(argv[i],"-safe")==0))
      safe=1;
    else if((strcmp(argv[i],"/saveheader")==0) || (strcmp(argv[i],"-saveheader")==0))
      saveheader=1;
    else if(strcmp(argv[i],"/cmd")==0)
    {
      if(i+2>=argc)
	help=1;
      else
      {
	disk_t *disk_car;
	cmd_device=argv[++i];
	cmd_run=argv[++i];
	disk_car=file_test_availability(cmd_device, verbose, testdisk_mode);
	if(disk_car==NULL)
	{
	  printf("\nUnable to open file or device %s\n",cmd_device);
	  help=1;
	}
	else
	  list_disk=insert_new_disk(list_disk,disk_car);
      }
    }
    else
    {
      disk_t *disk_car=file_test_availability(argv[i], verbose, testdisk_mode);
      if(disk_car==NULL)
      {
	printf("\nUnable to open file or device %s\n",argv[i]);
	help=1;
      }
      else
	list_disk=insert_new_disk(list_disk,disk_car);
    }
  }
  if(version!=0)
  {
    printf("\n");
    printf("Version: %s\n", VERSION);
    printf("Compiler: %s\n", get_compiler());
    printf("Compilation date: %s\n", get_compilation_date());
    printf("ext2fs lib: %s, ntfs lib: %s, reiserfs lib: %s, ewf lib: %s\n",
	td_ext2fs_version(), td_ntfs_version(), td_reiserfs_version(), td_ewf_version());
    printf("OS: %s\n" , get_os());
    return 0;
  }
  if(help!=0)
  {
    printf("\n" \
	"Usage: testdisk [/log] [/debug] [file.dd|file.e01|device]\n"\
	"       testdisk /list  [/log]   [file.dd|file.e01|device]\n" \
	"       testdisk /version\n" \
	"\n" \
	"/log          : create a testdisk.log file\n" \
	"/debug        : add debug information\n" \
	"/list         : display current partitions\n" \
	"\n" \
	"TestDisk checks and recovers lost partitions\n" \
	"It works with :\n" \
	"- BeFS (BeOS)                           - BSD disklabel (Free/Open/Net BSD)\n" \
	"- CramFS, Compressed File System        - DOS/Windows FAT12, FAT16 and FAT32\n" \
	"- XBox FATX                             - Windows exFAT\n" \
	"- HFS, HFS+, Hierarchical File System   - JFS, IBM's Journaled File System\n" \
	"- Linux btrfs                           - Linux ext2, ext3 and ext4\n" \
	"- Linux GFS2                            - Linux LUKS\n" \
	"- Linux Raid                            - Linux Swap\n" \
	"- LVM, LVM2, Logical Volume Manager     - Netware NSS\n" \
	"- Windows NTFS                          - ReiserFS 3.5, 3.6 and 4\n" \
	"- Sun Solaris i386 disklabel            - UFS and UFS2 (Sun/BSD/...)\n" \
	"- XFS, SGI's Journaled File System      - Wii WBFS\n" \
	"- Sun ZFS\n" \
	"\n" \
	"If you have problems with TestDisk or bug reports, please contact me.\n");
    return 0;
  }
  screen_buffer_reset();
  if(do_list!=0)
  {
    printf("Please wait...\n");
    /* Scan for available device only if no device or image has been supplied in parameter */
    if(list_disk==NULL)
      list_disk=hd_parse(list_disk, verbose, testdisk_mode);
    /* Activate the cache */
    for(element_disk=list_disk;element_disk!=NULL;element_disk=element_disk->next)
      element_disk->disk=new_diskcache(element_disk->disk,testdisk_mode);
    if(safe==0)
      hd_update_all_geometry(list_disk, verbose);
    for(element_disk=list_disk;element_disk!=NULL;element_disk=element_disk->next)
    {
      disk_t *disk=element_disk->disk;
      const int hpa_dco=is_hpa_or_dco(disk);
      printf("%s\n", disk->description(disk));
      printf("Sector size:%u\n", disk->sector_size);
      if(disk->model!=NULL)
	printf("Model: %s", disk->model);
      if(disk->serial_no!=NULL)
	printf(", S/N:%s", disk->serial_no);
      if(disk->fw_rev!=NULL)
	printf(", FW:%s", disk->fw_rev);
      printf("\n");
      if(hpa_dco!=0)
      {
	if(disk->sector_size!=0)
	  printf("size       %llu sectors\n", (long long unsigned)(disk->disk_real_size/disk->sector_size));
	if(disk->user_max!=0)
	  printf("user_max   %llu sectors\n", (long long unsigned)disk->user_max);
	if(disk->native_max!=0)
	  printf("native_max %llu sectors\n", (long long unsigned)(disk->native_max+1));
	if(disk->dco!=0)
	  printf("dco        %llu sectors\n", (long long unsigned)(disk->dco+1));
	if(hpa_dco&1)
	  printf("Host Protected Area (HPA) present.\n");
	if(hpa_dco&2)
	  printf("Device Configuration Overlay (DCO) present.\n");
      }
      printf("\n");
    }

    for(element_disk=list_disk;element_disk!=NULL;element_disk=element_disk->next)
    {
      disk_t *disk=element_disk->disk;
      autodetect_arch(disk, NULL);
      if(unit==UNIT_DEFAULT)
	autoset_unit(disk);
      else
	disk->unit=unit;
      interface_list(disk, verbose, saveheader, create_backup);
      printf("\n");
    }
    delete_list_disk(list_disk);
    return 0;
  }
#ifdef HAVE_SETLOCALE
  if(run_setlocale>0)
  {
    const char *locale;
    locale = setlocale (LC_ALL, "");
    if (locale==NULL) {
      locale = setlocale (LC_ALL, NULL);
      log_error("Failed to set locale, using default '%s'.\n", locale);
    } else {
      log_info("Using locale '%s'.\n", locale);
    }
  }
#endif
  if(create_log!=TD_LOG_NONE && log_handle==NULL)
    log_handle=log_open_default(logfile, create_log, &log_errno);
#ifdef HAVE_NCURSES
  /* ncurses need locale for correct unicode support */
  if(start_ncurses("TestDisk",argv[0]))
    return 1;
  if(argc==1 && create_log==TD_LOG_NONE)
  {
    verbose=1;
    create_log=ask_testdisk_log_creation();
    if(create_log==TD_LOG_CREATE || create_log==TD_LOG_APPEND)
      log_handle=log_open(logfile, create_log, &log_errno);
  }
  {
    const char*filename=logfile;
    while(create_log!=TD_LOG_NONE && log_handle==NULL)
    {
      filename=ask_log_location(filename, log_errno);
      if(filename!=NULL)
	log_handle=log_open(filename, create_log, &log_errno);
      else
	create_log=TD_LOG_NONE;
    }
  }
#endif
  if(log_handle!=NULL)
  {
    time_t my_time;
#ifdef HAVE_DUP2
    dup2(fileno(log_handle),2);
#endif
    my_time=time(NULL);
    log_info("\n\n%s",ctime(&my_time));
    log_info("Command line: TestDisk");
    for(i=1;i<argc;i++)
      log_info(" %s", argv[i]);
    log_info("\n\n");
    log_flush();
  }
  log_info("TestDisk %s, Data Recovery Utility, %s\nChristophe GRENIER <*****@*****.**>\nhttp://www.cgsecurity.org\n", VERSION, TESTDISKDATE);
  log_info("OS: %s\n" , get_os());
  log_info("Compiler: %s\n", get_compiler());
  log_info("Compilation date: %s\n", get_compilation_date());
  log_info("ext2fs lib: %s, ntfs lib: %s, reiserfs lib: %s, ewf lib: %s\n",
      td_ext2fs_version(), td_ntfs_version(), td_reiserfs_version(), td_ewf_version());
#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(DJGPP)
#else
#ifdef HAVE_GETEUID
  if(geteuid()!=0)
  {
    log_warning("User is not root!\n");
  }
#endif
#endif
#ifdef HAVE_NCURSES
  aff_copy(stdscr);
  wmove(stdscr,5,0);
  wprintw(stdscr, "Please wait...\n");
  wrefresh(stdscr);
#endif
  /* Scan for available device only if no device or image has been supplied in parameter */
  if(list_disk==NULL)
    list_disk=hd_parse(list_disk, verbose, testdisk_mode);
  /* Activate the cache */
  for(element_disk=list_disk;element_disk!=NULL;element_disk=element_disk->next)
    element_disk->disk=new_diskcache(element_disk->disk,testdisk_mode);
#ifdef HAVE_NCURSES
  wmove(stdscr,6,0);
  for(element_disk=list_disk;element_disk!=NULL;element_disk=element_disk->next)
  {
    wprintw(stdscr,"%s\n",element_disk->disk->description(element_disk->disk));
  }
  wrefresh(stdscr);
#endif
  if(safe==0)
    hd_update_all_geometry(list_disk, verbose);
  /* save disk parameters to rapport */
  log_info("Hard disk list\n");
  for(element_disk=list_disk;element_disk!=NULL;element_disk=element_disk->next)
  {
    disk_t *disk=element_disk->disk;
    log_info("%s, sector size=%u", disk->description(disk), disk->sector_size);
    if(disk->model!=NULL)
      log_info(" - %s", disk->model);
    if(disk->serial_no!=NULL)
      log_info(", S/N:%s", disk->serial_no);
    if(disk->fw_rev!=NULL)
      log_info(", FW:%s", disk->fw_rev);
    log_info("\n");
  }
  log_info("\n");
#ifdef SUDO_BIN
  if(list_disk==NULL)
  {
#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(DJGPP)
#else
#ifdef HAVE_GETEUID
    if(geteuid()!=0)
      use_sudo=2;
#endif
#endif
  }
#endif
  if(use_sudo==0)
    use_sudo=do_curses_testdisk(verbose,dump_ind,list_disk,saveheader,cmd_device,&cmd_run);
#ifdef HAVE_NCURSES
  end_ncurses();
#endif
  log_info("\n");
  while(done==0)
  {
    int command='Q';
    if(cmd_run!=NULL)
    {
      while(cmd_run[0]==',')
	(cmd_run)++;
      if(strncmp(cmd_run,"list",4)==0)
      {
	(cmd_run)+=4;
	command='L';
      }
      else if(cmd_run[0]!='\0')
      {
	log_critical("Syntax error in command line: %s\n",cmd_run);
	printf("Syntax error in command line: %s\n",cmd_run);
      }
    }
    switch(command)
    {
      case 'L':
	for(element_disk=list_disk;element_disk!=NULL;element_disk=element_disk->next)
	  interface_list(element_disk->disk, verbose, saveheader, create_backup);
	break;
      case 'q':
      case 'Q':
	done = 1;
	break;
    }
  }
  cmd_device=NULL;
  cmd_run=NULL;
  write_used=delete_list_disk(list_disk);
  log_info("TestDisk exited normally.\n");
  if(log_close()!=0)
  {
    printf("TestDisk: Log file corrupted!\n");
  }
  if(write_used!=0)
  {
    printf("You have to reboot for the change to take effect.\n");
  }
#ifdef SUDO_BIN
  if(use_sudo>0)
  {
    printf("\n");
    if(use_sudo>1)
      printf("No disk found.\n");
    printf("TestDisk will try to restart itself using the sudo command to get\n");
    printf("root (superuser) privileges.\n");
    printf("\n");
    run_sudo(argc, argv);
  }
#endif
  return 0;
}