Exemple #1
0
static list_part_t *ask_structure_ncurses(disk_t *disk_car,list_part_t *list_part, const int verbose, char **current_cmd)
{
  int offset=0;
  int pos_num=0;
  list_part_t *pos=list_part;
  int rewrite=1;
  int old_LINES=LINES;
  while(1)
  {
    int i;
    int command;
    list_part_t *parts;
    int structure_status;
    if(old_LINES!=LINES)
    {
      rewrite=1;
      old_LINES=LINES;
    }
    if(rewrite)
    {
      aff_copy(stdscr);
      wmove(stdscr,4,0);
      wprintw(stdscr,"%s",disk_car->description(disk_car));
      mvwaddstr(stdscr,5,0,msg_PART_HEADER);
      rewrite=0;
    }
    structure_status=disk_car->arch->test_structure(list_part);
    for(i=0,parts=list_part;
	parts!=NULL && i<offset+INTER_STRUCTURE;
	i++, parts=parts->next)
    {
      if(i<offset)
	continue;
      wmove(stdscr,6+i-offset,0);
      wclrtoeol(stdscr);	/* before addstr for BSD compatibility */
      if(parts==pos)
	wattrset(stdscr, A_REVERSE);
      if(structure_status==0 && parts->part->status!=STATUS_DELETED && has_colors())
	wbkgdset(stdscr,' ' | COLOR_PAIR(2));
      if(parts==pos)
	waddstr(stdscr, ">");
      else
	waddstr(stdscr, " ");
      aff_part(stdscr, AFF_PART_STATUS, disk_car, parts->part);
      if(structure_status==0 && parts->part->status!=STATUS_DELETED && has_colors())
	wbkgdset(stdscr,' ' | COLOR_PAIR(0));
      if(parts==pos)
      {
	char buffer_part_size[100];
	wattroff(stdscr, A_REVERSE);
	wmove(stdscr,LINES-1,0);
	wclrtoeol(stdscr);	/* before addstr for BSD compatibility */
	if(parts->part->info[0]!='\0')
	{
	  wprintw(stdscr,"%s, ",parts->part->info);
	}
	size_to_unit(parts->part->part_size, buffer_part_size);
	wprintw(stdscr,"%s", buffer_part_size);
      }
    }
    if(structure_status==0)
    {
      if(list_part!=NULL)
	mvwaddstr(stdscr,LINES-6,0,msg_STRUCT_OK);
    }
    else
    {
      if(has_colors())
	wbkgdset(stdscr,' ' | A_BOLD | COLOR_PAIR(1));
      mvwaddstr(stdscr,LINES-6,0,msg_STRUCT_BAD);
      if(has_colors())
	wbkgdset(stdscr,' ' | COLOR_PAIR(0));
    }
    if(list_part!=NULL && disk_car->arch->msg_part_type!=NULL)
    {
      mvwaddstr(stdscr,LINES-6,16,"Use ");
      if(has_colors())
	wbkgdset(stdscr,' ' | A_BOLD | COLOR_PAIR(0));
      waddstr(stdscr,"Up");
      if(has_colors())
	wbkgdset(stdscr,' ' | COLOR_PAIR(0));
      waddstr(stdscr,"/");
      if(has_colors())
	wbkgdset(stdscr,' ' | A_BOLD | COLOR_PAIR(0));
      waddstr(stdscr,"Down");
      if(has_colors())
	wbkgdset(stdscr,' ' | COLOR_PAIR(0));
      waddstr(stdscr," Arrow keys to select partition.");
      mvwaddstr(stdscr,LINES-5,0,"Use ");
      if(has_colors())
	wbkgdset(stdscr,' ' | A_BOLD | COLOR_PAIR(0));
      waddstr(stdscr,"Left");
      if(has_colors())
	wbkgdset(stdscr,' ' | COLOR_PAIR(0));
      waddstr(stdscr,"/");
      if(has_colors())
	wbkgdset(stdscr,' ' | A_BOLD | COLOR_PAIR(0));
      waddstr(stdscr,"Right");
      if(has_colors())
	wbkgdset(stdscr,' ' | COLOR_PAIR(0));
      waddstr(stdscr," Arrow keys to CHANGE partition characteristics:");
      mvwaddstr(stdscr,LINES-4,0,disk_car->arch->msg_part_type);
    }
    wmove(stdscr,LINES-3,0);
    wclrtoeol(stdscr);	/* before addstr for BSD compatibility */
    waddstr(stdscr,"Keys ");
    /* If the disk can't be partionned, there is no partition to add and no partition to save */
    if(disk_car->arch != &arch_none)
    {
      if(has_colors())
	wbkgdset(stdscr,' ' | A_BOLD | COLOR_PAIR(0));
      waddstr(stdscr,"A");
      if(has_colors())
	wbkgdset(stdscr,' ' | COLOR_PAIR(0));
      waddstr(stdscr,": add partition, ");
      if(has_colors())
	wbkgdset(stdscr,' ' | A_BOLD | COLOR_PAIR(0));
      waddstr(stdscr,"L");
      if(has_colors())
	wbkgdset(stdscr,' ' | COLOR_PAIR(0));
      waddstr(stdscr,": load backup, ");
    }
    if(list_part==NULL)
    {
      waddstr(stdscr,"Enter: to continue");
    }
    else
    {
      if(pos->part->arch==NULL || pos->part->arch==disk_car->arch)
      {
	if(has_colors())
	  wbkgdset(stdscr,' ' | A_BOLD | COLOR_PAIR(0));
	waddstr(stdscr,"T");
	if(has_colors())
	  wbkgdset(stdscr,' ' | COLOR_PAIR(0));
	waddstr(stdscr,": change type, ");
      }
      switch(pos->part->upart_type)
      {
	case UP_EXFAT:
	case UP_EXT2:
	case UP_EXT3:
	case UP_EXT4:
	case UP_RFS:
	case UP_RFS2:
	case UP_RFS3:
	case UP_FAT12:
	case UP_FAT16:
	case UP_FAT32:
	case UP_NTFS:
	  if(has_colors())
	    wbkgdset(stdscr,' ' | A_BOLD | COLOR_PAIR(0));
	  waddstr(stdscr,"P");
	  if(has_colors())
	    wbkgdset(stdscr,' ' | COLOR_PAIR(0));
	  waddstr(stdscr,": list files, ");
	  break;
	default:
	  break;
      }
      if(has_colors())
	wbkgdset(stdscr,' ' | A_BOLD | COLOR_PAIR(0));
      mvwaddstr(stdscr,LINES-2,5, "Enter");
      if(has_colors())
	wbkgdset(stdscr,' ' | COLOR_PAIR(0));
      waddstr(stdscr,": to continue");
    }
    wrefresh(stdscr);
    command=wgetch(stdscr);
    switch(command)
    {
      case KEY_UP:
	if(list_part!=NULL)
	{
	  only_one_bootable(list_part,pos);
	  if(pos->prev!=NULL)
	  {
	    pos=pos->prev;
	    pos_num--;
	  }
	}
	break;
      case KEY_DOWN:
	if(list_part!=NULL)
	{
	  only_one_bootable(list_part,pos);
	  if(pos->next!=NULL)
	  {
	    pos=pos->next;
	    pos_num++;
	  }
	}
	break;
      case KEY_PPAGE:
	if(list_part!=NULL)
	{
	  only_one_bootable(list_part,pos);
	  for(i=0; i<INTER_STRUCTURE && pos->prev!=NULL; i++)
	  {
	    pos=pos->prev;
	    pos_num--;
	  }
	}
	break;
      case KEY_NPAGE:
	if(list_part!=NULL)
	{
	  only_one_bootable(list_part,pos);
	  for(i=0; i<INTER_STRUCTURE && pos->next!=NULL; i++)
	  {
	    pos=pos->next;
	    pos_num++;
	  }
	}
	break;
      case KEY_RIGHT:
      case '+':
      case ' ':
	if(list_part!=NULL)
	{
	  if(pos->part->arch==NULL || pos->part->arch==disk_car->arch)
	    disk_car->arch->set_next_status(disk_car,pos->part);
	}
	break;
      case KEY_LEFT:
      case '-':
	if(list_part!=NULL)
	{
	  if(pos->part->arch==NULL || pos->part->arch==disk_car->arch)
	    disk_car->arch->set_prev_status(disk_car,pos->part);
	}
	break;
      case 'a':
      case 'A':
	if(disk_car->arch != &arch_none)
	{
	  list_part=add_partition_ncurses(disk_car, list_part);
	  rewrite=1;
	  offset=0;
	  pos_num=0;
	  pos=list_part;
	}
	break;
      case 't':
      case 'T':
	if(list_part!=NULL)
	{
	  rewrite=1;
	  change_part_type_ncurses(disk_car, pos->part);
	}
	break;
      case 'p':
      case 'P':
	if(list_part!=NULL)
        {
          const partition_t *partition=pos->part;
          if(partition->sb_offset==0 || partition->sb_size==0)
            dir_partition(disk_car,partition,verbose, current_cmd);
          else
          {
            io_redir_add_redir(disk_car,
                partition->part_offset+partition->sborg_offset,
                partition->sb_size,
                partition->part_offset+partition->sb_offset,
                NULL);
            dir_partition(disk_car,partition,verbose, current_cmd);
            io_redir_del_redir(disk_car, partition->part_offset+partition->sborg_offset);
          }
	  rewrite=1;
        }
	break;
      case 'b':
      case 'B':
	if(partition_save(disk_car,list_part,verbose)<0)
	  display_message("Can't create backup.log.\n");
	else
	  display_message("Results saved in backup.log.\n");
	rewrite=1;
        break;
      case 'l':
      case 'L':
	if(disk_car->arch != &arch_none)
	{
	  list_part=interface_load(disk_car,list_part,verbose);
	  rewrite=1;
	  offset=0;
	  pos_num=0;
	  pos=list_part;
	}
        break;
      case 'q':
      case '\r':
      case '\n':
      case KEY_ENTER:
#ifdef PADENTER
      case PADENTER:
#endif
      case 'M':
	return list_part;
      default:
/*	log_trace("ask_structure command=%x\n",command); */
	break;
    }
    if(pos_num<offset)
      offset=pos_num;
    if(pos_num>=offset+INTER_STRUCTURE)
      offset=pos_num-INTER_STRUCTURE+1;
  }
}
Exemple #2
0
void menu_photorec(struct ph_param *params, struct ph_options *options, alloc_data_t*list_search_space)
{
  list_part_t *list_part;
  list_part_t *current_element;
  unsigned int current_element_num;
  unsigned int user_blocksize=0;
  int done=0;
  init_mode_t mode_init_space=(td_list_empty(&list_search_space->list)?INIT_SPACE_WHOLE:INIT_SPACE_PREINIT);
#ifdef HAVE_NCURSES
  int command;
  unsigned int offset=0;
  unsigned int menu=0;
  static const struct MenuItem menuMain[]=
  {
	{'S',"Search","Start file recovery"},
	{'O',"Options","Modify options"},
	{'F',"File Opt","Modify file options"},
	{'G',"Geometry", "Change disk geometry" },
	{'Q',"Quit","Return to disk selection"},
	{0,NULL,NULL}
  };
#endif
  params->blocksize=0;
  list_part=init_list_part(params->disk, options);
  if(list_part==NULL)
    return;
  log_all_partitions(params->disk, list_part);
  if(list_part->next!=NULL)
  {
    current_element_num=1;
    current_element=list_part->next;
  }
  else
  {
    current_element_num=0;
    current_element=list_part;
  }
  while(done==0)
  {
    if(params->cmd_run!=NULL)
    {
      while(params->cmd_run[0]==',')
	params->cmd_run++;
      if(params->cmd_run[0]=='\0')
      {
	part_free_list(list_part);
	return;
      }
      if(strncmp(params->cmd_run,"search",6)==0)
      {
	params->cmd_run+=6;
	if(params->recup_dir==NULL)
	{
	  char *res;
#ifdef HAVE_NCURSES
	  res=ask_location("Please select a destination to save the recovered files.\nDo not choose to write the files to the same partition they were stored on.", "", NULL);
#else
	  res=get_default_location();
#endif
	  if(res!=NULL)
	  {
	    params->recup_dir=(char *)MALLOC(strlen(res)+1+strlen(DEFAULT_RECUP_DIR)+1);
	    strcpy(params->recup_dir,res);
	    strcat(params->recup_dir,"/");
	    strcat(params->recup_dir,DEFAULT_RECUP_DIR);
	    free(res);
	  }
	}
	if(params->recup_dir!=NULL)
	{
	  params->partition=current_element->part;
	  if(mode_init_space==INIT_SPACE_EXT2_GROUP)
	  {
	    params->blocksize=ext2_fix_group(list_search_space, params->disk, params->partition);
	    if(params->blocksize==0)
	      display_message("Not a valid ext2/ext3/ext4 filesystem");
	  }
	  else if(mode_init_space==INIT_SPACE_EXT2_INODE)
	  {
	    params->blocksize=ext2_fix_inode(list_search_space, params->disk, params->partition);
	    if(params->blocksize==0)
	      display_message("Not a valid ext2/ext3/ext4 filesystem");
	  }
	  if(td_list_empty(&list_search_space->list))
	  {
	    init_search_space(list_search_space, params->disk, params->partition);
	  }
	  if(params->carve_free_space_only>0)
	  {
	    params->blocksize=remove_used_space(params->disk, params->partition, list_search_space);
	  }
	  if(user_blocksize > 0)
	    params->blocksize=user_blocksize;
	  photorec(params, options, list_search_space);
	}
      }
      else if(strncmp(params->cmd_run,"options",7)==0)
      {
	params->cmd_run+=7;
	interface_options_photorec_cli(options, &params->cmd_run);
      }
      else if(strncmp(params->cmd_run,"fileopt",7)==0)
      {
	params->cmd_run+=7;
	interface_file_select(options->list_file_format, &params->cmd_run);
      }
      else if(strncmp(params->cmd_run,"blocksize,",10)==0)
      {
	params->cmd_run+=10;
	user_blocksize=atoi(params->cmd_run);
	while(params->cmd_run[0]!=',' && params->cmd_run[0]!='\0')
	  params->cmd_run++;
      }
      else if(strncmp(params->cmd_run,"geometry,",9)==0)
      {
	params->cmd_run+=9;
	change_geometry_cli(params->disk, &params->cmd_run);
      }
      else if(strncmp(params->cmd_run,"inter",5)==0)
      {	/* Start interactive mode */
	params->cmd_run=NULL;
      }
      else if(strncmp(params->cmd_run,"wholespace",10)==0)
      {
	params->cmd_run+=10;
	params->carve_free_space_only=0;
      }
      else if(strncmp(params->cmd_run,"freespace",9)==0)
      {
	params->cmd_run+=9;
	params->carve_free_space_only=1;
      }
      else if(strncmp(params->cmd_run,"ext2_group,",11)==0)
      {
	unsigned int groupnr;
	params->cmd_run+=11;
	options->mode_ext2=1;
	groupnr=atoi(params->cmd_run);
	while(params->cmd_run[0]!=',' && params->cmd_run[0]!='\0')
	  params->cmd_run++;
	if(mode_init_space==INIT_SPACE_WHOLE)
	  mode_init_space=INIT_SPACE_EXT2_GROUP;
	if(mode_init_space==INIT_SPACE_EXT2_GROUP)
	{
          alloc_data_t *new_free_space;
          new_free_space=(alloc_data_t*)MALLOC(sizeof(*new_free_space));
          /* Temporary storage, values need to be multiplied by group size and aligned */
          new_free_space->start=groupnr;
          new_free_space->end=groupnr;
          new_free_space->file_stat=NULL;
	  new_free_space->data=1;
          if(td_list_add_sorted_uniq(&new_free_space->list, &list_search_space->list, spacerange_cmp))
	    free(new_free_space);
        }
      }
      else if(strncmp(params->cmd_run,"ext2_inode,",11)==0)
      {
	unsigned int inodenr;
	params->cmd_run+=11;
	options->mode_ext2=1;
	inodenr=atoi(params->cmd_run);
	while(params->cmd_run[0]!=',' && params->cmd_run[0]!='\0')
	  params->cmd_run++;
	if(mode_init_space==INIT_SPACE_WHOLE)
	  mode_init_space=INIT_SPACE_EXT2_INODE;
	if(mode_init_space==INIT_SPACE_EXT2_INODE)
	{
          alloc_data_t *new_free_space;
          new_free_space=(alloc_data_t*)MALLOC(sizeof(*new_free_space));
          /* Temporary storage, values need to be multiplied by group size and aligned */
          new_free_space->start=inodenr;
          new_free_space->end=inodenr;
          new_free_space->file_stat=NULL;
	  new_free_space->data=1;
          if(td_list_add_sorted_uniq(&new_free_space->list, &list_search_space->list, spacerange_cmp))
	    free(new_free_space);
        }
      }
      else if(isdigit(params->cmd_run[0]))
      {
	list_part_t *element;
	unsigned int order;
	order= atoi(params->cmd_run);
	while(params->cmd_run[0]!=',' && params->cmd_run[0]!='\0')
	  params->cmd_run++;
	for(element=list_part;element!=NULL && element->part->order!=order;element=element->next);
	if(element!=NULL)
	  current_element=element;
      }
      else
      {
	log_critical("Syntax error in command line: %s\n", params->cmd_run);
	part_free_list(list_part);
	return;
      }
    }
#ifdef HAVE_NCURSES
    else
    { /* ncurses interface */
      list_part_t *element;
      unsigned int i;
      aff_copy(stdscr);
      wmove(stdscr,4,0);
      wprintw(stdscr,"%s",params->disk->description_short(params->disk));
      mvwaddstr(stdscr,6,0,msg_PART_HEADER_LONG);
#if defined(KEY_MOUSE) && defined(ENABLE_MOUSE)
      mousemask(ALL_MOUSE_EVENTS, NULL);
#endif
      for(i=0,element=list_part; element!=NULL && i<offset+INTER_SELECT;element=element->next,i++)
      {
	if(i<offset)
	  continue;
	wmove(stdscr,7+i-offset,0);
	wclrtoeol(stdscr);	/* before addstr for BSD compatibility */
	if(element==current_element)
	{
	  wattrset(stdscr, A_REVERSE);
	  waddstr(stdscr, ">");
	  aff_part(stdscr,AFF_PART_ORDER|AFF_PART_STATUS,params->disk,element->part);
	  wattroff(stdscr, A_REVERSE);
	} else
	{
	  waddstr(stdscr, " ");
	  aff_part(stdscr,AFF_PART_ORDER|AFF_PART_STATUS,params->disk,element->part);
	}
      }
      wmove(stdscr,7+INTER_SELECT,5);
      wclrtoeol(stdscr);
      if(element!=NULL)
	wprintw(stdscr, "Next");
      command = wmenuSelect(stdscr, INTER_SELECT_Y+1, INTER_SELECT_Y, INTER_SELECT_X, menuMain, 8,
	  (options->expert==0?"SOFQ":"SOFGQ"), MENU_HORIZ | MENU_BUTTON | MENU_ACCEPT_OTHERS, menu);
#if defined(KEY_MOUSE) && defined(ENABLE_MOUSE)
      if(command == KEY_MOUSE)
      {
	MEVENT event;
	if(getmouse(&event) == OK)
	{	/* When the user clicks left mouse button */
	  if((event.bstate & BUTTON1_CLICKED) || (event.bstate & BUTTON1_DOUBLE_CLICKED))
	  {
	    if(event.y >=7 && event.y<7+INTER_SELECT)
	    {
	      /* Disk selection */
	      while(current_element_num > event.y-(7-offset) && current_element->prev!=NULL)
	      {
		current_element=current_element->prev;
		current_element_num--;
	      }
	      while(current_element_num < event.y-(7-offset) && current_element->next!=NULL)
	      {
		current_element=current_element->next;
		current_element_num++;
	      }
	      if(event.bstate & BUTTON1_DOUBLE_CLICKED)
		command='S';
	    }
	    else
	      command = menu_to_command(INTER_SELECT_Y+1, INTER_SELECT_Y, INTER_SELECT_X, menuMain, 8,
		  (options->expert==0?"SOFQ":"SOFGQ"), MENU_HORIZ | MENU_BUTTON | MENU_ACCEPT_OTHERS, event.y, event.x);
	  }
	}
      }
#endif
      switch(command)
      {
	case KEY_UP:
	  if(current_element!=NULL && current_element->prev!=NULL)
	  {
	    current_element=current_element->prev;
	    current_element_num--;
	  }
	  break;
	case KEY_PPAGE:
	  for(i=0; (signed)i<INTER_SELECT && current_element->prev!=NULL; i++)
	  {
	    current_element=current_element->prev;
	    current_element_num--;
	  }
	  break;
	case KEY_DOWN:
	  if(current_element->next!=NULL)
	  {
	    current_element=current_element->next;
	    current_element_num++;
	  }
	  break;
	case KEY_NPAGE:
	  for(i=0; (signed)i<INTER_SELECT && current_element->next!=NULL; i++)
	  {
	    current_element=current_element->next;
	    current_element_num++;
	  }
	  break;
	case 's':
	case 'S':
	  if(current_element!=NULL)
	  {
	    params->partition=current_element->part;
	    ask_mode_ext2(params->disk, params->partition, &options->mode_ext2, &params->carve_free_space_only);
	    menu=0;
	    if(params->recup_dir==NULL)
	    {
	      char *res;
	      res=ask_location("Please select a destination to save the recovered files.\nDo not choose to write the files to the same partition they were stored on.", "", NULL);
	      if(res!=NULL)
	      {
		params->recup_dir=(char *)MALLOC(strlen(res)+1+strlen(DEFAULT_RECUP_DIR)+1);
		strcpy(params->recup_dir,res);
		strcat(params->recup_dir,"/");
		strcat(params->recup_dir,DEFAULT_RECUP_DIR);
		free(res);
	      }
	    }
	    if(params->recup_dir!=NULL)
	    {
	      if(td_list_empty(&list_search_space->list))
	      {
		init_search_space(list_search_space, params->disk, params->partition);
	      }
	      if(params->carve_free_space_only>0)
	      {
		aff_copy(stdscr);
		wmove(stdscr,5,0);
		wprintw(stdscr, "Filesystem analysis, please wait...\n");
		wrefresh(stdscr);
		params->blocksize=remove_used_space(params->disk, params->partition, list_search_space);
		/* Only free space is carved, list_search_space is modified.
		 * To carve the whole space, need to quit and reselect the params->partition */
		done = 1;
	      }
	      photorec(params, options, list_search_space);
	    }
	  }
	  break;
	case 'o':
	case 'O':
	  {
	    interface_options_photorec_ncurses(options);
	    menu=1;
	  }
	  break;
	case 'f':
	case 'F':
	  interface_file_select(options->list_file_format, &params->cmd_run);
	  menu=2;
	  break;
	case 'g':
	case 'G':
	  if(options->expert!=0)
	    if(change_geometry_ncurses(params->disk))
	      done=1;
	  break;
      case 'a':
      case 'A':
	if(params->disk->arch != &arch_none)
	{
	  list_part=add_partition_ncurses(params->disk, list_part);
	  current_element=list_part;
	  current_element_num=0;
	}
	break;
	case 'q':
	case 'Q':
	  done = 1;
	  break;
      }
      if(current_element_num<offset)
	offset=current_element_num;
      if(current_element_num>=offset+INTER_SELECT)
	offset=current_element_num-INTER_SELECT+1;
    }
#endif
  }
  log_info("\n");
  part_free_list(list_part);
}
Exemple #3
0
void menu_photorec(struct ph_param *params, struct ph_options *options, alloc_data_t*list_search_space)
{
  list_part_t *list_part;
#ifdef HAVE_NCURSES
  list_part_t *current_element;
  unsigned int current_element_num;
  int done=0;
  int command;
  unsigned int offset=0;
  unsigned int menu=0;
  static const struct MenuItem menuMain[]=
  {
	{'S',"Search","Start file recovery"},
	{'O',"Options","Modify options"},
	{'F',"File Opt","Modify file options"},
	{'G',"Geometry", "Change disk geometry" },
	{'Q',"Quit","Return to disk selection"},
	{0,NULL,NULL}
  };
#endif
  params->blocksize=0;
  list_part=init_list_part(params->disk, options);
  if(list_part==NULL)
    return;
  log_all_partitions(params->disk, list_part);
  if(params->cmd_run!=NULL)
  {
    if(menu_photorec_cli(list_part, params, options, list_search_space) > 0)
    {
      if(params->recup_dir==NULL)
      {
	char *res;
#ifdef HAVE_NCURSES
	res=ask_location("Please select a destination to save the recovered files.\nDo not choose to write the files to the same partition they were stored on.", "", NULL);
#else
	res=get_default_location();
#endif
	if(res!=NULL)
	{
	  params->recup_dir=(char *)MALLOC(strlen(res)+1+strlen(DEFAULT_RECUP_DIR)+1);
	  strcpy(params->recup_dir,res);
	  strcat(params->recup_dir,"/");
	  strcat(params->recup_dir,DEFAULT_RECUP_DIR);
	  free(res);
	}
      }
      if(params->recup_dir!=NULL)
	photorec(params, options, list_search_space);
    }
  }
  if(params->cmd_run!=NULL)
  {
    part_free_list(list_part);
    return;
  }
#ifdef HAVE_NCURSES
  if(list_part->next!=NULL)
  {
    current_element_num=1;
    current_element=list_part->next;
  }
  else
  {
    current_element_num=0;
    current_element=list_part;
  }
  while(done==0)
  { /* ncurses interface */
    list_part_t *element;
    unsigned int i;
    aff_copy(stdscr);
    wmove(stdscr,4,0);
    wprintw(stdscr,"%s",params->disk->description_short(params->disk));
    mvwaddstr(stdscr,6,0,msg_PART_HEADER_LONG);
#if defined(KEY_MOUSE) && defined(ENABLE_MOUSE)
    mousemask(ALL_MOUSE_EVENTS, NULL);
#endif
    for(i=0,element=list_part; element!=NULL && i<offset+INTER_SELECT;element=element->next,i++)
    {
      if(i<offset)
	continue;
      wmove(stdscr,7+i-offset,0);
      wclrtoeol(stdscr);	/* before addstr for BSD compatibility */
      if(element==current_element)
      {
	wattrset(stdscr, A_REVERSE);
	waddstr(stdscr, ">");
	aff_part(stdscr,AFF_PART_ORDER|AFF_PART_STATUS,params->disk,element->part);
	wattroff(stdscr, A_REVERSE);
      } else
      {
	waddstr(stdscr, " ");
	aff_part(stdscr,AFF_PART_ORDER|AFF_PART_STATUS,params->disk,element->part);
      }
    }
    wmove(stdscr,7+INTER_SELECT,5);
    wclrtoeol(stdscr);
    if(element!=NULL)
      wprintw(stdscr, "Next");
    command = wmenuSelect(stdscr, INTER_SELECT_Y+1, INTER_SELECT_Y, INTER_SELECT_X, menuMain, 8,
	(options->expert==0?"SOFQ":"SOFGQ"), MENU_HORIZ | MENU_BUTTON | MENU_ACCEPT_OTHERS, menu);
#if defined(KEY_MOUSE) && defined(ENABLE_MOUSE)
    if(command == KEY_MOUSE)
    {
      MEVENT event;
      if(getmouse(&event) == OK)
      {	/* When the user clicks left mouse button */
	if((event.bstate & BUTTON1_CLICKED) || (event.bstate & BUTTON1_DOUBLE_CLICKED))
	{
	  if(event.y >=7 && event.y<7+INTER_SELECT)
	  {
	    /* Disk selection */
	    while(current_element_num > event.y-(7-offset) && current_element->prev!=NULL)
	    {
	      current_element=current_element->prev;
	      current_element_num--;
	    }
	    while(current_element_num < event.y-(7-offset) && current_element->next!=NULL)
	    {
	      current_element=current_element->next;
	      current_element_num++;
	    }
	    if(event.bstate & BUTTON1_DOUBLE_CLICKED)
	      command='S';
	  }
	  else
	    command = menu_to_command(INTER_SELECT_Y+1, INTER_SELECT_Y, INTER_SELECT_X, menuMain, 8,
		(options->expert==0?"SOFQ":"SOFGQ"), MENU_HORIZ | MENU_BUTTON | MENU_ACCEPT_OTHERS, event.y, event.x);
	}
      }
    }
#endif
    switch(command)
    {
      case KEY_UP:
	if(current_element!=NULL && current_element->prev!=NULL)
	{
	  current_element=current_element->prev;
	  current_element_num--;
	}
	break;
      case KEY_PPAGE:
	for(i=0; (signed)i<INTER_SELECT && current_element->prev!=NULL; i++)
	{
	  current_element=current_element->prev;
	  current_element_num--;
	}
	break;
      case KEY_DOWN:
	if(current_element->next!=NULL)
	{
	  current_element=current_element->next;
	  current_element_num++;
	}
	break;
      case KEY_NPAGE:
	for(i=0; (signed)i<INTER_SELECT && current_element->next!=NULL; i++)
	{
	  current_element=current_element->next;
	  current_element_num++;
	}
	break;
      case 's':
      case 'S':
	if(current_element!=NULL)
	{
	  params->partition=current_element->part;
	  ask_mode_ext2(params->disk, params->partition, &options->mode_ext2, &params->carve_free_space_only);
	  menu=0;
	  if(params->recup_dir==NULL)
	  {
	    char *res;
	    res=ask_location("Please select a destination to save the recovered files.\nDo not choose to write the files to the same partition they were stored on.", "", NULL);
	    if(res!=NULL)
	    {
	      params->recup_dir=(char *)MALLOC(strlen(res)+1+strlen(DEFAULT_RECUP_DIR)+1);
	      strcpy(params->recup_dir,res);
	      strcat(params->recup_dir,"/");
	      strcat(params->recup_dir,DEFAULT_RECUP_DIR);
	      free(res);
	    }
	  }
	  if(params->recup_dir!=NULL)
	  {
	    if(td_list_empty(&list_search_space->list))
	    {
	      init_search_space(list_search_space, params->disk, params->partition);
	    }
	    if(params->carve_free_space_only>0)
	    {
	      aff_copy(stdscr);
	      wmove(stdscr,5,0);
	      wprintw(stdscr, "Filesystem analysis, please wait...\n");
	      wrefresh(stdscr);
	      params->blocksize=remove_used_space(params->disk, params->partition, list_search_space);
	      /* Only free space is carved, list_search_space is modified.
	       * To carve the whole space, need to quit and reselect the params->partition */
	      done = 1;
	    }
	    photorec(params, options, list_search_space);
	  }
	}
	break;
      case 'o':
      case 'O':
	{
	  interface_options_photorec_ncurses(options);
	  menu=1;
	}
	break;
      case 'f':
      case 'F':
	interface_file_select_ncurses(options->list_file_format);
	menu=2;
	break;
      case 'g':
      case 'G':
	if(options->expert!=0)
	  if(change_geometry_ncurses(params->disk))
	    done=1;
	break;
      case 'a':
      case 'A':
	if(params->disk->arch != &arch_none)
	{
	  list_part=add_partition_ncurses(params->disk, list_part);
	  current_element=list_part;
	  current_element_num=0;
	}
	break;
      case 'q':
      case 'Q':
	done = 1;
	break;
    }
    if(current_element_num<offset)
      offset=current_element_num;
    if(current_element_num>=offset+INTER_SELECT)
      offset=current_element_num-INTER_SELECT+1;
  }
#endif
  log_info("\n");
  part_free_list(list_part);
}
Exemple #4
0
void interface_adv(disk_t *disk_car, const int verbose,const int dump_ind, const unsigned int expert, char**current_cmd)
{
#ifdef HAVE_NCURSES
    int offset=0;
    int current_element_num=0;
    int old_LINES=LINES;
#endif
    int rewrite=1;
    unsigned int menu=0;
    list_part_t *element;
    list_part_t *list_part;
    list_part_t *current_element;
    log_info("\nInterface Advanced\n");
    list_part=disk_car->arch->read_part(disk_car,verbose,0);
    current_element=list_part;
    log_all_partitions(disk_car, list_part);
    while(1)
    {
        const char *options;
        static struct MenuItem menuAdv[]=
        {
            {'t',"Type","Change type, this setting will not be saved on disk"},
            {'b',"Boot","Boot sector recovery"},
            {'s',"Superblock",NULL},
            {'l',"List", "List and copy files"},
            {'u',"Undelete", "File undelete"},
            {'c',"Image Creation", "Create an image"},
//      {'a',"Add", "Add temporary partition (Expert only)"},
            {'q',"Quit","Return to main menu"},
            {0,NULL,NULL}
        };
        int command;
#ifdef HAVE_NCURSES
        int i;
        if(old_LINES!=LINES)
        {
            old_LINES=LINES;
            rewrite=1;
        }
        if(rewrite!=0)
        {
            aff_copy(stdscr);
            wmove(stdscr,4,0);
            wprintw(stdscr,"%s",disk_car->description(disk_car));
            if(list_part!=NULL)
                mvwaddstr(stdscr,6,0,msg_PART_HEADER_LONG);
            rewrite=0;
        }
        for(i=0,element=list_part; element!=NULL && i<offset+INTER_ADV; element=element->next,i++)
        {
            if(i<offset)
                continue;
            wmove(stdscr,7+i-offset,0);
            wclrtoeol(stdscr);	/* before addstr for BSD compatibility */
            if(element==current_element)
            {
                wattrset(stdscr, A_REVERSE);
                waddstr(stdscr, ">");
                aff_part(stdscr,AFF_PART_ORDER|AFF_PART_STATUS,disk_car,element->part);
                wattroff(stdscr, A_REVERSE);
            } else
            {
                waddstr(stdscr, " ");
                aff_part(stdscr,AFF_PART_ORDER|AFF_PART_STATUS,disk_car,element->part);
            }
        }
        wmove(stdscr,7+INTER_ADV,5);
        wclrtoeol(stdscr);
        if(element!=NULL)
            wprintw(stdscr, "Next");
#endif
        if(current_element==NULL)
        {
            options="q";
#ifdef HAVE_NCURSES
            wmove(stdscr,7,0);
            wattrset(stdscr, A_REVERSE);
            wprintw(stdscr,"No partition available.");
            wattroff(stdscr, A_REVERSE);
#endif
        }
        else
        {
            const partition_t *partition=current_element->part;
            if(menu==0 && (disk_car->arch!=&arch_none || partition->upart_type!=UP_UNK))
                menu=1;
            if(is_part_fat(partition))
            {
                options="tubcq";
                menu=(partition->upart_type==UP_UNK?1:4);
            }
            else if(is_part_ntfs(partition))
                options="tlubcq";
            else if(is_part_linux(partition))
            {
                if(partition->upart_type==UP_EXT2)
                    options="tuscq";
                else
                    options="tlscq";
                menuAdv[2].desc="Locate ext2/ext3/ext4 backup superblock";
            }
            else if(is_part_hfs(partition) || is_part_hfsp(partition))
            {
                options="tscq";
                menuAdv[2].desc="Locate HFS/HFS+ backup volume header";
            }
            else if(is_fat(partition))
                options="tubcq";
            else if(is_ntfs(partition))
                options="tlubcq";
            else if(is_exfat(partition))
                options="tlubcq";
            else if(is_linux(partition))
            {
                if(partition->upart_type==UP_EXT2)
                    options="tluscq";
                else
                    options="tlscq";
                menuAdv[2].desc="Locate ext2/ext3/ext4 backup superblock";
            }
            else if(is_hfs(partition) || is_hfsp(partition))
            {
                options="tscq";
                menuAdv[2].desc="Locate HFS/HFS+ backup volume header";
            }
            else
                options="tcq";
        }
        if(*current_cmd!=NULL)
        {
            int keep_asking;
            command='q';
            do
            {
                keep_asking=0;
                while(*current_cmd[0]==',')
                    (*current_cmd)++;
                if(strncmp(*current_cmd,"type",4)==0)
                {
                    (*current_cmd)+=4;
                    command='t';
                }
                else if(strncmp(*current_cmd,"addpart",7)==0)
                {
                    (*current_cmd)+=7;
                    command='a';
                }
                else if(strncmp(*current_cmd,"boot",4)==0)
                {
                    (*current_cmd)+=4;
                    command='b';
                }
                else if(strncmp(*current_cmd,"copy",4)==0)
                {
                    (*current_cmd)+=4;
                    command='c';
                }
                else if(strncmp(*current_cmd,"list",4)==0)
                {
                    (*current_cmd)+=4;
                    command='l';
                }
                else if(strncmp(*current_cmd,"undelete",8)==0)
                {
                    (*current_cmd)+=8;
                    command='u';
                }
                else if(strncmp(*current_cmd,"superblock",10)==0)
                {
                    (*current_cmd)+=10;
                    command='s';
                }
                else if(isdigit(*current_cmd[0]))
                {
                    const unsigned int order= atoi(*current_cmd);
                    while(*current_cmd[0]!=',' && *current_cmd[0]!='\0')
                        (*current_cmd)++;
                    for(element=list_part; element!=NULL && element->part->order!=order; element=element->next);
                    if(element!=NULL)
                    {
                        current_element=element;
                        keep_asking=1;
                    }
                }
            } while(keep_asking>0);
        }
        else
        {
#ifdef HAVE_NCURSES
            command = wmenuSelect_ext(stdscr, INTER_ADV_Y+1, INTER_ADV_Y, INTER_ADV_X, menuAdv, 8, options,
                                      MENU_HORIZ | MENU_BUTTON | MENU_ACCEPT_OTHERS, &menu, NULL);
#else
            command = 'q';
#endif
        }
        switch(command)
        {
        case 'q':
        case 'Q':
            part_free_list(list_part);
            return;
#ifdef HAVE_NCURSES
        case 'a':
        case 'A':
            if(disk_car->arch!=&arch_none)
            {
                if(*current_cmd!=NULL)
                    list_part=add_partition_cli(disk_car, list_part, current_cmd);
                else
                    list_part=add_partition_ncurses(disk_car, list_part);
                current_element=list_part;
                rewrite=1;
            }
            break;
#endif
        }
#ifdef HAVE_NCURSES
        if(current_element!=NULL)
        {
            switch(command)
            {
            case 'p':
            case 'P':
            case KEY_UP:
                if(current_element->prev!=NULL)
                {
                    current_element=current_element->prev;
                    current_element_num--;
                }
                break;
            case 'n':
            case 'N':
            case KEY_DOWN:
                if(current_element->next!=NULL)
                {
                    current_element=current_element->next;
                    current_element_num++;
                }
                break;
            case KEY_PPAGE:
                for(i=0; i<INTER_ADV-1 && current_element->prev!=NULL; i++)
                {
                    current_element=current_element->prev;
                    current_element_num--;
                }
                break;
            case KEY_NPAGE:
                for(i=0; i<INTER_ADV-1 && current_element->next!=NULL; i++)
                {
                    current_element=current_element->next;
                    current_element_num++;
                }
                break;
            case 'b':
            case 'B':
            {
                partition_t *partition=current_element->part;
                if(is_part_fat32(partition))
                {
                    fat32_boot_sector(disk_car, partition, verbose, dump_ind, expert,current_cmd);
                    rewrite=1;
                }
                else if(is_part_fat12(partition) || is_part_fat16(partition))
                {
                    fat1x_boot_sector(disk_car, partition, verbose, dump_ind,expert,current_cmd);
                    rewrite=1;
                }
                else if(is_part_ntfs(partition))
                {
                    if(partition->upart_type==UP_EXFAT)
                        exFAT_boot_sector(disk_car, partition, verbose, current_cmd);
                    else
                        ntfs_boot_sector(disk_car, partition, verbose, expert, current_cmd);
                    rewrite=1;
                }
                else if(partition->upart_type==UP_FAT32)
                {
                    fat32_boot_sector(disk_car, partition, verbose, dump_ind, expert,current_cmd);
                    rewrite=1;
                }
                else if(partition->upart_type==UP_FAT12 || partition->upart_type==UP_FAT16)
                {
                    fat1x_boot_sector(disk_car, partition, verbose, dump_ind,expert,current_cmd);
                    rewrite=1;
                }
                else if(partition->upart_type==UP_NTFS)
                {
                    ntfs_boot_sector(disk_car, partition, verbose, expert, current_cmd);
                    rewrite=1;
                }
                else if(partition->upart_type==UP_EXFAT)
                {
                    exFAT_boot_sector(disk_car, partition, verbose, current_cmd);
                    rewrite=1;
                }
            }
            break;
            case 'c':
            case 'C':
            {
                char *dst_path;
#ifdef HAVE_NCURSES
                if(*current_cmd!=NULL)
                    dst_path=get_default_location();
                else
                {
                    char msg[256];
                    snprintf(msg, sizeof(msg),
                             "Please select where to store the file image.dd (%u MB), an image of the partition",
                             (unsigned int)(current_element->part->part_size/1000/1000));
                    dst_path=ask_location(msg, "", NULL);
                }
#else
                dst_path=get_default_location();
#endif
                if(dst_path!=NULL)
                {
                    char *filename=(char *)MALLOC(strlen(dst_path) + 1 + strlen(DEFAULT_IMAGE_NAME) + 1);
                    strcpy(filename, dst_path);
                    strcat(filename, "/");
                    strcat(filename, DEFAULT_IMAGE_NAME);
                    disk_image(disk_car, current_element->part, filename);
                    free(filename);
                    free(dst_path);
                }
            }
            rewrite=1;
            break;
            case 'u':
            case 'U':
            {
                partition_t *partition=current_element->part;
                if(partition->sb_offset!=0 && partition->sb_size>0)
                {
                    io_redir_add_redir(disk_car,
                                       partition->part_offset+partition->sborg_offset,
                                       partition->sb_size,
                                       partition->part_offset+partition->sb_offset,
                                       NULL);
                    if(partition->upart_type==UP_NTFS ||
                            (is_part_ntfs(partition) && partition->upart_type!=UP_EXFAT))
                        ntfs_undelete_part(disk_car, partition, verbose, current_cmd);
                    else
                        dir_partition(disk_car, partition, 0, current_cmd);
                    io_redir_del_redir(disk_car, partition->part_offset+partition->sborg_offset);
                }
                else
                {
                    if(partition->upart_type==UP_NTFS ||
                            (is_part_ntfs(partition) && partition->upart_type!=UP_EXFAT))
                        ntfs_undelete_part(disk_car, partition, verbose, current_cmd);
                    else
                        dir_partition(disk_car, partition, 0, current_cmd);
                }
            }
            rewrite=1;
            break;
            case 'l':
            case 'L':
            {
                partition_t *partition=current_element->part;
                if(partition->sb_offset!=0 && partition->sb_size>0)
                {
                    io_redir_add_redir(disk_car,
                                       partition->part_offset+partition->sborg_offset,
                                       partition->sb_size,
                                       partition->part_offset+partition->sb_offset,
                                       NULL);
                    dir_partition(disk_car,partition,verbose, current_cmd);
                    io_redir_del_redir(disk_car, partition->part_offset+partition->sborg_offset);
                }
                else
                    dir_partition(disk_car,partition,verbose, current_cmd);
            }
            rewrite=1;
            break;
            case 's':
            case 'S':
            {
                if(is_linux(current_element->part))
                {
                    list_part_t *list_sb=search_superblock(disk_car,current_element->part,verbose,dump_ind,1);
                    interface_superblock(disk_car,list_sb,current_cmd);
                    part_free_list(list_sb);
                }
                if(is_hfs(current_element->part) || is_hfsp(current_element->part))
                {
                    HFS_HFSP_boot_sector(disk_car, current_element->part, verbose, current_cmd);
                }
                rewrite=1;
            }
            break;
            case 't':
            case 'T':
                if(*current_cmd!=NULL)
                    change_part_type_cli(disk_car, current_element->part, current_cmd);
                else
                    change_part_type_ncurses(disk_car, current_element->part);
                rewrite=1;
                break;
            }
            if(current_element_num<offset)
                offset=current_element_num;
            if(current_element_num>=offset+INTER_ADV)
                offset=current_element_num-INTER_ADV+1;
        }
#endif
    }
}