Exemple #1
0
int wmenuSimple(WINDOW *window,const struct MenuItem *menuItems, const unsigned int menuDefault)
{
    unsigned int i, itemLength = 0;
    char available[MENU_MAX_ITEMS];

    for(i = 0; menuItems[i].key; i++)
    {
      const unsigned int j = strlen(menuItems[i].name);
      if( j > itemLength ) itemLength = j;
      available[i] = menuItems[i].key;
    }
    available[i] = 0;
    return wmenuSelect(window, 23, 18, 0, menuItems, itemLength, available, MENU_HORIZ | MENU_BUTTON, menuDefault);
}
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;
#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 #3
0
static void interface_editor_ncurses(disk_t *disk)
{
  int done = 0;
  uint64_t hd_offset=0;
  unsigned char *buffer=(unsigned char *)MALLOC(disk->sector_size);
  log_info("%s\n",disk->description(disk));
  aff_copy(stdscr);
  wmove(stdscr,4,0);
  wprintw(stdscr,"%s", disk->description_short(disk));
  while (done==0)
  {
    static const struct MenuItem menuEditor[]=
    {
      { 'C', "Change location", "" },
      { 'D', "Dump", "Dump sector" },
      { 'Q', "Quit",""},
      { 0, NULL, NULL }
    };
    switch ( wmenuSelect(stdscr, INTER_EDIT_Y+1, INTER_EDIT_Y, INTER_EDIT_X, menuEditor, 8, "CDQ", MENU_HORIZ | MENU_BUTTON, 0))
    {
      case 'c':
      case 'C':
	interface_editor_location(disk,&hd_offset);
	break;
      case 'd':
      case 'D':
	{
	  int menu_pos=KEY_DOWN;
	  while(done==0)
	  {
	    wmove(stdscr,5,0);
	    wclrtoeol(stdscr);
	    wprintw(stdscr,"%lu ", (unsigned long)(hd_offset/disk->sector_size));
	    aff_LBA2CHS(disk, hd_offset/disk->sector_size);
	    if((unsigned)disk->pread(disk, buffer, disk->sector_size, hd_offset) != disk->sector_size)
	    {
	      wprintw(stdscr,msg_PART_RD_ERR);
	    }
	    {
	      menu_pos=dump_editor(buffer, disk->sector_size, menu_pos);
	      switch(menu_pos)
	      {
		case KEY_UP:
		  if(hd_offset>0)
		    hd_offset-=disk->sector_size;
		  else
		    menu_pos=KEY_DOWN;
		  break;
		case KEY_DOWN:
		  if(hd_offset<disk->disk_size)
		    hd_offset+=disk->sector_size;
		  else
		    menu_pos=KEY_UP;
		  break;
		default:
		  done = 1;
		  break;
	      }
	    }
	  }
	  done = 0;
	}
	break;
      case key_ESC:
      case 'q':
      case 'Q':
	done = 1;
	break;
    }
  }
  free(buffer);
}
Exemple #4
0
static int dump_editor(const unsigned char *nom_dump,const unsigned int lng, const int menu_pos)
{
  unsigned int pos;
  int done=0;
  unsigned int menu;
  const struct MenuItem menuDump[]=
  {
	{ 'P', "Previous",""},
	{ 'N', "Next","" },
	{ 'Q',"Quit","Quit dump section"},
	{ 0, NULL, NULL }
  };
  /* write dump to log file*/
  dump_log(nom_dump, lng);
  /* ncurses interface */
  pos=(menu_pos==KEY_DOWN?0:lng/0x10-EDIT_MAX_LINES);
  menu=(menu_pos==KEY_DOWN?1:0);
  mvwaddstr(stdscr, EDIT_Y, EDIT_X, msg_DUMP_HEXA);
  do
  {
    	unsigned int i,j;
  	unsigned char car;
	for (i=pos; (i<lng/0x10)&&((i-pos)<EDIT_MAX_LINES); i++)
	{
	  wmove(stdscr,EDIT_Y+i-pos,EDIT_X);
	  wclrtoeol(stdscr);
	  wprintw(stdscr,"%04X ",i*0x10);
	  for(j=0; j< 0x10;j++)
	  {
		car=*(nom_dump+i*0x10+j);
		wprintw(stdscr,"%02x", car);
		if(j%4==(4-1))
		  wprintw(stdscr," ");
	  }
	  wprintw(stdscr,"  ");
	  for(j=0; j< 0x10;j++)
	  {
		car=*(nom_dump+i*0x10+j);
		if ((car<32)||(car >= 127))
		  wprintw(stdscr,".");
		else
		  wprintw(stdscr,"%c",  car);
	  }
	}
	switch (wmenuSelect(stdscr, INTER_EDIT_Y+1, INTER_EDIT_Y, INTER_EDIT_X, menuDump, 8, "PNQ", MENU_HORIZ | MENU_BUTTON | MENU_ACCEPT_OTHERS, menu))
	{
	  case 'p':
	  case 'P':
	  case KEY_UP:
		menu=0;
		if(pos>0)
		  pos--;
		else
		  done=KEY_UP;
		break;
	  case 'n':
	  case 'N':
	  case KEY_DOWN:
		menu=1;
		if(pos<lng/0x10-EDIT_MAX_LINES)
		  pos++;
		else
		  done = KEY_DOWN;
		break;
	  case KEY_PPAGE:
		menu=0;
		if(pos==0)
		  done=KEY_UP;
		if(pos>EDIT_MAX_LINES-1)
		  pos-=EDIT_MAX_LINES-1;
		else
		  pos=0;
		break;
	  case KEY_NPAGE:
		menu=1;
		if(pos==lng/0x10-EDIT_MAX_LINES)
		  done=KEY_DOWN;
		if(pos<lng/0x10-EDIT_MAX_LINES-(EDIT_MAX_LINES-1))
		  pos+=EDIT_MAX_LINES-1;
		else
		  pos=lng/0x10-EDIT_MAX_LINES;
		break;
	  case key_ESC:
	  case 'q':
	  case 'Q':
		done = 'Q';
		break;
	}
  } while(done==0);
  return done;
}
Exemple #5
0
void dump2(WINDOW *window, const void *dump_1, const void *dump_2, const unsigned int lng)
{
  unsigned int nbr_line;
  unsigned int pos=0;
  int done=0;
  unsigned int menu=2;   /* default : quit */
  const char *options="PNQ";
  const struct MenuItem menuDump[]=
  {
    { 'P', "Previous",""},
    { 'N', "Next","" },
    { 'Q',"Quit","Quit dump section"},
    { 0, NULL, NULL }
  };
  /* ncurses interface */
  nbr_line=(lng+0x08-1)/0x08;
  if(nbr_line <= (unsigned)DUMP_MAX_LINES)
  {
    options="Q";
  }
  do
  {
    unsigned int i,j;
    for (i=pos; i<nbr_line && (i-pos) < (unsigned)DUMP_MAX_LINES; i++)
    {
      wmove(window,DUMP_Y+i-pos,DUMP_X);
      wclrtoeol(window);
      wprintw(window,"%04X ",i*0x08);
      for(j=0; j<0x08;j++)
      {
        if(i*0x08+j<lng)
        {
          unsigned char car1=*((const unsigned char*)dump_1+i*0x08+j);
          unsigned char car2=*((const unsigned char*)dump_2+i*0x08+j);
          if(car1!=car2)
            wattrset(window, A_REVERSE);
          wprintw(window,"%02x", car1);
          if(car1!=car2)
            wattroff(window, A_REVERSE);
        }
        else
          wprintw(window," ");
        if(j%4==(4-1))
          wprintw(window," ");
      }
      wprintw(window,"  ");
      for(j=0; j<0x08;j++)
      {
        if(i*0x08+j<lng)
        {
          unsigned char car1=*((const unsigned char*)dump_1+i*0x08+j);
          unsigned char car2=*((const unsigned char*)dump_2+i*0x08+j);
          if(car1!=car2)
            wattrset(window, A_REVERSE);
          if ((car1<32)||(car1 >= 127))
            wprintw(window,".");
          else
            wprintw(window,"%c",  car1);
          if(car1!=car2)
            wattroff(window, A_REVERSE);
        }
        else
          wprintw(window," ");
      }
      wprintw(window,"  ");
      for(j=0; j<0x08;j++)
      {
        if(i*0x08+j<lng)
        {
          unsigned char car1=*((const unsigned char*)dump_1+i*0x08+j);
          unsigned char car2=*((const unsigned char*)dump_2+i*0x08+j);
          if(car1!=car2)
            wattrset(window, A_REVERSE);
          wprintw(window,"%02x", car2);
          if(car1!=car2)
            wattroff(window, A_REVERSE);
          if(j%4==(4-1))
            wprintw(window," ");
        }
        else
          wprintw(window," ");
      }
      wprintw(window,"  ");
      for(j=0; j<0x08;j++)
      {
        if(i*0x08+j<lng)
        {
          unsigned char car1=*((const unsigned char*)dump_1+i*0x08+j);
          unsigned char car2=*((const unsigned char*)dump_2+i*0x08+j);
          if(car1!=car2)
            wattrset(window, A_REVERSE);
          if ((car2<32)||(car2 >= 127))
            wprintw(window,".");
          else
            wprintw(window,"%c",  car2);
          if(car1!=car2)
            wattroff(window, A_REVERSE);
        }
        else
          wprintw(window," ");
      }
    }
    switch (wmenuSelect(window, INTER_DUMP_Y+1, INTER_DUMP_Y, INTER_DUMP_X, menuDump, 8, options, MENU_HORIZ | MENU_BUTTON | MENU_ACCEPT_OTHERS, menu))
    {
      case 'p':
      case 'P':
      case KEY_UP:
        if(strchr(options,'N')!=NULL)
        {
          menu=0;
          if(pos>0)
            pos--;
        }
        break;
      case 'n':
      case 'N':
      case KEY_DOWN:
        if(strchr(options,'N')!=NULL)
        {
          menu=1;
          if(pos<nbr_line-DUMP_MAX_LINES)
            pos++;
        }
        break;
      case KEY_PPAGE:
        if(strchr(options,'N')!=NULL)
        {
          menu=0;
          if(pos > (unsigned)(DUMP_MAX_LINES-1))
            pos-=DUMP_MAX_LINES-1;
          else
            pos=0;
        }
        break;
      case KEY_NPAGE:
        if(strchr(options,'N')!=NULL)
        {
          menu=1;
          if(pos<nbr_line-DUMP_MAX_LINES-(DUMP_MAX_LINES-1))
            pos+=DUMP_MAX_LINES-1;
          else
            pos=nbr_line-DUMP_MAX_LINES;
        }
        break;
      case key_ESC:
      case 'q':
      case 'Q':
        done = TRUE;
        break;
    }
  } while(done==FALSE);
}
Exemple #6
0
void dump(WINDOW *window, const void *nom_dump,unsigned int lng)
{
  unsigned int nbr_line;
  unsigned int pos=0;
  int done=0;
  unsigned int menu=2;   /* default : quit */
  const char *options="PNQ";
  const struct MenuItem menuDump[]=
  {
    { 'P', "Previous",""},
    { 'N', "Next","" },
    { 'Q',"Quit","Quit dump section"},
    { 0, NULL, NULL }
  };
  nbr_line=(lng+0x10-1)/0x10;
  if(nbr_line <= (unsigned)DUMP_MAX_LINES)
  {
    options="Q";
  }
  /* ncurses interface */
  mvwaddstr(window,DUMP_Y,DUMP_X,msg_DUMP_HEXA);
  /* On pourrait utiliser wscrl */
  do
  {
    unsigned char car;
    unsigned int i,j;
    for (i=pos; i<nbr_line && (i-pos) < (unsigned)DUMP_MAX_LINES; i++)
    {
      wmove(window,DUMP_Y+i-pos,DUMP_X);
      wclrtoeol(window);
      wprintw(window,"%04X ",i*0x10);
      for(j=0; j< 0x10;j++)
      {
        if(i*0x10+j<lng)
        {
          car=*((const unsigned char*)nom_dump+i*0x10+j);
          wprintw(window,"%02x", car);
        }
        else
          wprintw(window,"  ");
        if(j%4==(4-1))
          wprintw(window," ");
      }
      wprintw(window,"  ");
      for(j=0; j< 0x10;j++)
      {
        if(i*0x10+j<lng)
        {
          car=*((const unsigned char*)nom_dump+i*0x10+j);
          if ((car<32)||(car >= 127))
            wprintw(window,".");
          else
            wprintw(window,"%c",  car);
        }
        else
          wprintw(window," ");
      }
    }
    switch (wmenuSelect(window, INTER_DUMP_Y+1, INTER_DUMP_Y, INTER_DUMP_X, menuDump, 8, options, MENU_HORIZ | MENU_BUTTON | MENU_ACCEPT_OTHERS, menu))
    {
      case 'p':
      case 'P':
      case KEY_UP:
        if(strchr(options,'N')!=NULL)
        {
          menu=0;
          if(pos>0)
            pos--;
        }
        break;
      case 'n':
      case 'N':
      case KEY_DOWN:
        if(strchr(options,'N')!=NULL)
        {
          menu=1;
          if(pos<nbr_line-DUMP_MAX_LINES)
            pos++;
        }
        break;
      case KEY_PPAGE:
        if(strchr(options,'N')!=NULL)
        {
          menu=0;
          if(pos > (unsigned)(DUMP_MAX_LINES-1))
            pos-=DUMP_MAX_LINES-1;
          else
            pos=0;
        }
        break;
      case KEY_NPAGE:
        if(strchr(options,'N')!=NULL)
        {
          menu=1;
          if(pos<nbr_line-DUMP_MAX_LINES-(DUMP_MAX_LINES-1))
            pos+=DUMP_MAX_LINES-1;
          else
            pos=nbr_line-DUMP_MAX_LINES;
        }
        break;
      case key_ESC:
      case 'q':
      case 'Q':
        done = TRUE;
        break;
    }
  } while(done==FALSE);
}
Exemple #7
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);
}