Exemple #1
0
static int del_entry(direntry_t *entry, MainParam_t *mp)
{
	Arg_t *arg=(Arg_t *) mp->arg;

	if(got_signal)
		return ERROR_ONE;

	if(entry->entry == -3) {
		fprintf(stderr, "Cannot remove root directory\n");
		return ERROR_ONE;
	}

	if (arg->verbose) {
		fprintf(stderr,"Removing ");
		fprintPwd(stderr, entry,0);
		fputc('\n', stderr);
	}

	if (entry->dir.attr & (ATTR_READONLY | ATTR_SYSTEM)) {
		char tmp[4*MAX_VNAMELEN+1];
		wchar_to_native(entry->name,tmp,MAX_VNAMELEN);
		if (ask_confirmation("%s: \"%s\" is read only, erase anyway (y/n) ? ",
				     progname, tmp))
			return ERROR_ONE;
	}
	if (fatFreeWithDirentry(entry)) 
		return ERROR_ONE;

	wipeEntry(entry);
	return GOT_ONE;
}
Exemple #2
0
void *operatore(){
	while(1){
		//generatore di numeri random usato da wait_client() e ask_confirmation()
		srand(time(NULL));
		//attende un cliente
		wait_client();
		//proteggo l'accesso dell'operatore al db 
		pthread_mutex_lock(&op_lock);
		active_op++;
		if (active_op==1){
			pthread_mutex_lock(&db_lock);
		}
		pthread_mutex_unlock(&op_lock);
		//controllo disponibilita'
		if (check_availability()){
			pthread_mutex_lock(&op_lock);
			active_op--;
			if (active_op==0){
				pthread_mutex_unlock(&db_lock);
			}
			pthread_mutex_unlock(&op_lock);
			//se il posto e' disponibile chiedo conferma della prenotazione
			if (ask_confirmation()){
				pthread_mutex_lock(&db_lock);
				//avuta la conferma dal cliente, ricontrollo se il posto sia ancora libero
				if (check_availability()){	
					//ricevuta la conferma, prenoto il posto e rilascio il lock sul db
					book_seat();
					pthread_mutex_unlock(&db_lock);
					//confermo al cliente l'avvenuta prenotazione
					confirm_booking();
				}
				else {
				pthread_mutex_unlock(&db_lock);
				printf("Ci dispiace, qualcuno ha prenotato il posto prima di lei\n");
				}
			}
			else {
				//prenotazione non confermata, rilascio il lock sul db
				pthread_mutex_lock(&op_lock);
				active_op--;
				if (active_op==0){
					pthread_mutex_unlock(&db_lock);
				}
				pthread_mutex_unlock(&op_lock);
				printf("Ci dispiace che abbia cambiato idea, speriamo di rivederla al piu' presto!\n");
			}
		}
		else {	
			pthread_mutex_lock(&op_lock);
			active_op--;
			if (active_op==0){
				pthread_mutex_unlock(&db_lock);
			}
			pthread_mutex_unlock(&op_lock);
			printf("Ci dispiace, il viaggio che le interessa e' gia' al completo! Speriamo di rivederla presto.\n");
			break;
		}
	}
}
Exemple #3
0
int do_curses_photorec(struct ph_param *params, struct ph_options *options, const list_disk_t *list_disk)
{
  static alloc_data_t list_search_space={
    .list = TD_LIST_HEAD_INIT(list_search_space.list)
  };
  if(params->cmd_device==NULL)
  {
    char *saved_device=NULL;
    char *saved_cmd=NULL;
    session_load(&saved_device, &saved_cmd,&list_search_space);
    if(saved_device!=NULL && saved_cmd!=NULL && !td_list_empty(&list_search_space.list)
#ifdef HAVE_NCURSES
	&& ask_confirmation("Continue previous session ? (Y/N)")!=0
#endif
      )
    {
      /* yes */
      params->cmd_run=saved_cmd;
      params->cmd_device=saved_device;
    }
    else
    {
      free(saved_device);
      free(saved_cmd);
      free_list_search_space(&list_search_space);
    }
  }
  if(params->cmd_device!=NULL && params->cmd_run!=NULL)
  {
    params->disk=photorec_disk_selection_cli(params->cmd_device, list_disk, &list_search_space);
#ifdef HAVE_NCURSES
    if(params->disk==NULL)
    {
      log_critical("No disk found\n");
      return intrf_no_disk_ncurses("PhotoRec");
    }
    if(change_arch_type_cli(params->disk, options->verbose, &params->cmd_run)==0 ||
	change_arch_type_ncurses(params->disk, options->verbose)==0)
    {
      menu_photorec(params, options, &list_search_space);
    }
    return 0;
#else
    if(params->disk==NULL)
    {
      log_critical("No disk found\n");
      return 0;
    }
    change_arch_type_cli(params->disk, options->verbose, &params->cmd_run);
    menu_photorec(params, options, &list_search_space);
    return 0;
#endif
  }
#ifdef HAVE_NCURSES
  return photorec_disk_selection_ncurses(params, options, list_disk, &list_search_space);
#else
  return 0;
#endif
}
Exemple #4
0
int exFAT_boot_sector(disk_t *disk, partition_t *partition, char **current_cmd)
{
  unsigned char *buffer_bs;
  unsigned char *buffer_backup_bs;
  int rescan=1;
  const int size_bs=12 * disk->sector_size;
  const char *options;
#ifdef HAVE_NCURSES
  const struct MenuItem menu_exFAT[]=
  {
    { 'P', "Previous",""},
    { 'N', "Next","" },
    { 'Q', "Quit","Return to Advanced menu"},
    { 'O', "Org. BS","Copy superblock over backup sector"},
    { 'B', "Backup BS","Copy backup superblock over superblock"},
    { 'D', "Dump","Dump superblock and backup superblock"},
    { 0, NULL, NULL }
  };
#endif
  buffer_bs=(unsigned char*)MALLOC(size_bs);
  buffer_backup_bs=(unsigned char*)MALLOC(size_bs);
  while(1)
  {
    int command;
    screen_buffer_reset();
    if(rescan==1)
    {
      options=exFAT_boot_sector_rescan(disk, partition, buffer_bs, buffer_backup_bs);
      rescan=0;
    }
    screen_buffer_to_log();
    if(*current_cmd!=NULL)
    {
      command=exFAT_boot_sector_command(current_cmd, options);
    }
    else
    {
#ifdef HAVE_NCURSES
      unsigned int menu=0;
#endif
      log_flush();
#ifdef HAVE_NCURSES
      command=screen_buffer_display_ext(stdscr, options, menu_exFAT, &menu);
#else
      command=0;
#endif
    }
    switch(command)
    {
      case 0:
        free(buffer_bs);
        free(buffer_backup_bs);
	return 0;
      case 'O': /* O : copy original superblock over backup boot */
#ifdef HAVE_NCURSES
	if(ask_confirmation("Copy original exFAT boot record over backup, confirm ? (Y/N)")!=0)
#endif
	{
	  log_info("copy original superblock over backup boot\n");
	  if(disk->pwrite(disk, buffer_bs, size_bs, partition->part_offset + size_bs) != size_bs)
	  {
	    display_message("Write error: Can't overwrite exFAT backup boot record\n");
	  }
          disk->sync(disk);
	  rescan=1;
	}
	break;
      case 'B': /* B : copy backup superblock over main superblock */
#ifdef HAVE_NCURSES
	if(ask_confirmation("Copy backup exFAT boot record over main boot record, confirm ? (Y/N)")!=0)
#endif
	{
	  log_info("copy backup superblock over main superblock\n");
	  /* Reset information about backup boot record */
	  partition->sb_offset=0;
	  if(disk->pwrite(disk, buffer_backup_bs, size_bs, partition->part_offset) != size_bs)
	  {
	    display_message("Write error: Can't overwrite exFAT main boot record\n");
	  }
          disk->sync(disk);
	  rescan=1;
	}
	break;
      case 'D':
	exFAT_dump(disk, partition, buffer_bs, buffer_backup_bs, current_cmd);
	break;
    }
  }
}
Exemple #5
0
int repair_MFT(disk_t *disk_car, partition_t *partition, const int verbose, const unsigned int expert, char **current_cmd)
{
  struct ntfs_boot_sector *ntfs_header;
  unsigned char *buffer_mft;
  unsigned char *buffer_mftmirr;
  unsigned int cluster_size;
  unsigned int mft_record_size;
  unsigned int mftmirr_size_bytes;
  unsigned int use_MFT=0;
  /* 0: do nothing
   * 1: fix MFT mirror using MFT
   * 2: fix MFT using MFT mirror */
  uint64_t mft_pos;
  uint64_t mftmirr_pos;
  log_trace("repair_MFT\n");
  if(check_NTFS(disk_car, partition, verbose, 0)!=0)
  {
    display_message("Boot sector not valid, can't repair MFT.\n");
    return -1;
  }
  ntfs_header=(struct ntfs_boot_sector *)MALLOC(DEFAULT_SECTOR_SIZE);
  if(disk_car->pread(disk_car, ntfs_header, DEFAULT_SECTOR_SIZE, partition->part_offset) != DEFAULT_SECTOR_SIZE)
  {
    free(ntfs_header);
    display_message("Can't read NTFS boot sector.\n");
    return -1;
  }
  mft_pos=partition->part_offset+(uint64_t)(le16(ntfs_header->reserved)+le64(ntfs_header->mft_lcn)*ntfs_header->sectors_per_cluster)*ntfs_sector_size(ntfs_header);
  mftmirr_pos=partition->part_offset+(uint64_t)(le16(ntfs_header->reserved)+le64(ntfs_header->mftmirr_lcn)*ntfs_header->sectors_per_cluster)*ntfs_sector_size(ntfs_header);
  if(ntfs_header->clusters_per_mft_record>0)
    mft_record_size=ntfs_header->sectors_per_cluster*ntfs_header->clusters_per_mft_record;
  else
    mft_record_size=1<<(-ntfs_header->clusters_per_mft_record);

  cluster_size=ntfs_header->sectors_per_cluster;

  mftmirr_size_bytes = (cluster_size <= 4 * mft_record_size ? 4 * mft_record_size : cluster_size) * ntfs_sector_size(ntfs_header);
#ifdef DEBUG_REPAIR_MFT
  log_debug("mft_pos %lu\n",(unsigned long)(mft_pos/disk_car->sector_size));
  log_debug("mftmirr_pos %lu\n",(unsigned long)(mftmirr_pos/disk_car->sector_size));
  log_debug("cluster_size %u\n", cluster_size);
  log_debug("mft_record_size    %u\n", mft_record_size);
  log_debug("ntfs_sector_size   %u\n", ntfs_sector_size(ntfs_header));
  log_debug("mftmirr_size_bytes %u\n", mftmirr_size_bytes);
#endif
  if(mftmirr_size_bytes==0)
  {
    display_message("Invalid NTFS MFT size.\n");
    log_error("Invalid NTFS MFT size.\n");
    free(ntfs_header);
    return -1;
  }
  /* Check if MFT mirror is identical to the beginning of MFT */
  buffer_mft=(unsigned char *)MALLOC(mftmirr_size_bytes);
  if((unsigned)disk_car->pread(disk_car, buffer_mft, mftmirr_size_bytes, mft_pos) != mftmirr_size_bytes)
  {
    display_message("Can't read NTFS MFT.\n");
    log_error("Can't read NTFS MFT.\n");
    free(buffer_mft);
    free(ntfs_header);
    return -1;
  }
  buffer_mftmirr=(unsigned char *)MALLOC(mftmirr_size_bytes);
  if((unsigned)disk_car->pread(disk_car, buffer_mftmirr, mftmirr_size_bytes, mftmirr_pos) != mftmirr_size_bytes)
  {
    display_message("Can't read NTFS MFT mirror.\n");
    log_error("Can't read NTFS MFT mirror.\n");
    free(buffer_mftmirr);
    free(buffer_mft);
    free(ntfs_header);
    return -1;
  }
  if(memcmp(buffer_mft, buffer_mftmirr, mftmirr_size_bytes)==0)
  {
    log_info("MFT and MFT mirror match perfectly.\n");
    if(*current_cmd==NULL)
      display_message("MFT and MFT mirror match perfectly.\n");
    free(buffer_mftmirr);
    free(buffer_mft);
    free(ntfs_header);
    return 0;
  }
  if(partition->sb_offset!=0)
  {
    log_info("Please quit TestDisk and reboot your computer before trying to fix the MFT.\n");
    display_message("Please quit TestDisk and reboot your computer before trying to fix the MFT.\n");
    free(buffer_mftmirr);
    free(buffer_mft);
    free(ntfs_header);
    return -1;
  }
/*
  log_debug("MFT\n");
  dump_log(buffer_mft, mftmirr_size_bytes);
  log_debug("MFT mirror\n");
  dump_log(buffer_mftmirr, mftmirr_size_bytes);
  */
  /*
  The idea is to use the internal IO redirector built-in TestDisk
  to redirect read access to the MFT to the MFT backup instead (or
  vice-versa) when listing the NTFS files. If TestDisk can get
  a file listing, it also knows which MFT to use.
  */
  {
    int res1,res2;
    dir_data_t dir_data;
    /* Use MFT */
    io_redir_add_redir(disk_car, mftmirr_pos, mftmirr_size_bytes, 0, buffer_mft);
    res1=dir_partition_ntfs_init(disk_car,partition,&dir_data,verbose);
    if(res1==DIR_PART_ENOSYS)
    {
	display_message("Can't determine which MFT is correct, ntfslib is missing.\n");
	log_error("Can't determine which MFT is correct, ntfslib is missing.\n");
	free(buffer_mftmirr);
	free(buffer_mft);
	free(ntfs_header);
	io_redir_del_redir(disk_car,mftmirr_pos);
	return 0;
    }
    if(res1==DIR_PART_OK)
    {
      file_info_t dir_list;
      TD_INIT_LIST_HEAD(&dir_list.list);
      dir_data.get_dir(disk_car,partition,&dir_data,dir_data.current_inode, &dir_list);
      if(!td_list_empty(&dir_list.list))
      {
	log_info("NTFS listing using MFT:\n");
	dir_aff_log(&dir_data, &dir_list);
	if(delete_list_file(&dir_list)>2)
	  res1++;
      }
      dir_data.close(&dir_data);
    }
    io_redir_del_redir(disk_car,mftmirr_pos);
    /* Use MFT mirror */
    io_redir_add_redir(disk_car, mft_pos, mftmirr_size_bytes, 0, buffer_mftmirr);
    res2=dir_partition_ntfs_init(disk_car,partition,&dir_data,verbose);
    if(res2==DIR_PART_OK)
    {
      file_info_t dir_list;
      TD_INIT_LIST_HEAD(&dir_list.list);
      dir_data.get_dir(disk_car,partition,&dir_data,dir_data.current_inode, &dir_list);
      if(!td_list_empty(&dir_list.list))
      {
	log_info("NTFS listing using MFT mirror:\n");
	dir_aff_log(&dir_data, &dir_list);
	if(delete_list_file(&dir_list)>2)
	  res2++;
      }
      dir_data.close(&dir_data);
    }
    io_redir_del_redir(disk_car,mft_pos);
    /* */
    if(res1>res2 && res1>DIR_PART_OK)
    {
      /* Use MFT */
#ifdef HAVE_NCURSES
      if(ask_confirmation("Fix MFT mirror using MFT ? (Y/N)")!=0)
	use_MFT=1;
      else
#endif
	log_info("Don't fix MFT mirror.\n");
    }
    else if(res1<res2 && res2>DIR_PART_OK)
    {
      /* Use MFT mirror */
#ifdef HAVE_NCURSES
      if(ask_confirmation("Fix MFT using its mirror ? (Y/N) - DANGEROUS NON REVERSIBLE OPERATION\nUse it ONLY IF Windows failed to access this filesystem.")!=0)
	use_MFT=2;
      else
#endif
	log_info("Don't fix MFT.\n");
    }
    else
    { /* res1==res2 */
      if(res1>DIR_PART_OK && res2>DIR_PART_OK)
	log_error("Both MFT seems ok but they don't match, use chkdsk.\n");
      else
	log_error("MFT and MFT mirror are bad. Failed to repair them.\n");
      if(expert==0)
      {
	if(res1>DIR_PART_OK && res2>DIR_PART_OK)
	  display_message("Both MFT seems ok but they don't match, use chkdsk.\n");
	else
	  display_message("MFT and MFT mirror are bad. Failed to repair them.\n");
      }
      else
      {
#ifdef HAVE_NCURSES
	unsigned int menu=2;
	int real_key;
	int command;
	static const struct MenuItem menuMFT[]=
	{
	  {'B',"MFT",		"Fix MFT using MFT mirror"},
	  {'M',"MFT Mirror",	"Fix MFT mirror using MFT"},
	  {'Q',"Quit","Return to NTFS functions"},
	  {0,NULL,NULL}
	};
	aff_copy(stdscr);
	wmove(stdscr,4,0);
	wprintw(stdscr,"%s",disk_car->description(disk_car));
	mvwaddstr(stdscr,5,0,msg_PART_HEADER_LONG);
	wmove(stdscr,6,0);
	aff_part(stdscr,AFF_PART_ORDER|AFF_PART_STATUS,disk_car,partition);
	wmove(stdscr,8,0);
	if(res1>0 && res2>0)
	  wprintw(stdscr, "Both MFT seem ok but they don't match.\n");
	else
	  wprintw(stdscr, "MFT and MFT mirror are bad.\n");
	command=wmenuSelect_ext(stdscr, 23, INTER_MFT_Y, INTER_MFT_X, menuMFT, 10, "MBQ",
	    MENU_VERT | MENU_VERT_WARN | MENU_BUTTON, &menu, &real_key);
	switch(command)
	{
	  case 'b':
	  case 'B':
	    use_MFT=2;
	    break;
	  case 'm':
	  case 'M':
	    use_MFT=1;
	    break;
	  default:
	    use_MFT=0;
	    break;
	}
#endif
      }
    }
  }
  if(use_MFT==2)
  {
    if((unsigned)disk_car->pwrite(disk_car, buffer_mftmirr, mftmirr_size_bytes, mft_pos) != mftmirr_size_bytes)
    {
      display_message("Failed to fix MFT: write error.\n");
    }
    else
    {
      disk_car->sync(disk_car);
      display_message("MFT fixed.\n");
    }
  }
  else if(use_MFT==1)
  {
    if((unsigned)disk_car->pwrite(disk_car, buffer_mft, mftmirr_size_bytes, mftmirr_pos) != mftmirr_size_bytes)
    {
      display_message("Failed to fix MFT mirror: write error.\n");
    }
    else
    {
      disk_car->sync(disk_car);
      display_message("MFT mirror fixed.\n");
    }
  }
  free(buffer_mftmirr);
  free(buffer_mft);
  free(ntfs_header);
  return 0;
}
Exemple #6
0
static __inline__ clash_action get_slots(Stream_t *Dir,
					 dos_name_t *dosname,
					 char *longname,
					 struct scan_state *ssp,
					 ClashHandling_t *ch)
{
	int error;
	clash_action ret;
	int match_pos=0;
	direntry_t entry;
	int isprimary;
	int no_overwrite;
	int reason;
	int pessimisticShortRename;
	doscp_t *cp = GET_DOSCONVERT(Dir);

	pessimisticShortRename = (ch->action[0] == NAMEMATCH_AUTORENAME);

	entry.Dir = Dir;
	no_overwrite = 1;
	if((is_reserved(longname,1)) ||
	   longname[strspn(longname,". ")] == '\0'){
		reason = RESERVED;
		isprimary = 1;
	} else if(contains_illegals(longname,long_illegals,1024)) {
		reason = ILLEGALS;
		isprimary = 1;
	} else if(is_reserved(dosname->base,0)) {
		reason = RESERVED;
		ch->use_longname = 1;
		isprimary = 0;
	} else if(contains_illegals(dosname->base,short_illegals,11)) {
		reason = ILLEGALS;
		ch->use_longname = 1;
		isprimary = 0;
	} else {
		reason = EXISTS;
		switch (lookupForInsert(Dir,
					&entry,
					dosname, longname, ssp,
					ch->ignore_entry,
					ch->source_entry,
					pessimisticShortRename &&
					ch->use_longname,
					ch->use_longname)) {
			case -1:
				return NAMEMATCH_ERROR;
				
			case 0:
				return NAMEMATCH_SKIP;
				/* Single-file error error or skip request */
				
			case 5:
				return NAMEMATCH_GREW;
				/* Grew directory, try again */
				
			case 6:
				return NAMEMATCH_SUCCESS; /* Success */
		}	
		match_pos = -2;
		if (ssp->longmatch > -1) {
			/* Primary Long Name Match */
#ifdef debug
			fprintf(stderr,
				"Got longmatch=%d for name %s.\n",
				longmatch, longname);
#endif			
			match_pos = ssp->longmatch;
			isprimary = 1;
		} else if ((ch->use_longname & 1) && (ssp->shortmatch != -1)) {
			/* Secondary Short Name Match */
#ifdef debug
			fprintf(stderr,
				"Got secondary short name match for name %s.\n",
				longname);
#endif

			match_pos = ssp->shortmatch;
			isprimary = 0;
		} else if (ssp->shortmatch >= 0) {
			/* Primary Short Name Match */
#ifdef debug
			fprintf(stderr,
				"Got primary short name match for name %s.\n",
				longname);
#endif
			match_pos = ssp->shortmatch;
			isprimary = 1;
		} else
			return NAMEMATCH_RENAME;

		if(match_pos > -1) {
			entry.entry = match_pos;
			dir_read(&entry, &error);
			if (error)
			    return NAMEMATCH_ERROR;
			/* if we can't overwrite, don't propose it */
			no_overwrite = (match_pos == ch->source || IS_DIR(&entry));
		}
	}
	ret = process_namematch(cp, dosname, longname,
				isprimary, ch, no_overwrite, reason);
	
	if (ret == NAMEMATCH_OVERWRITE && match_pos > -1){
		if((entry.dir.attr & 0x5) &&
		   (ask_confirmation("file is read only, overwrite anyway (y/n) ? ")))
			return NAMEMATCH_RENAME;
		/* Free up the file to be overwritten */
		if(fatFreeWithDirentry(&entry))
			return NAMEMATCH_ERROR;
		
#if 0
		if(isprimary &&
		   match_pos - ssp->match_free + 1 >= ssp->size_needed){
			/* reuse old entry and old short name for overwrite */
			ssp->free_start = match_pos - ssp->size_needed + 1;
			ssp->free_size = ssp->size_needed;
			ssp->slot = match_pos;
			ssp->got_slots = 1;
			strncpy(dosname, dir.name, 3);
			strncpy(dosname + 8, dir.ext, 3);
			return ret;
		} else
#endif
			{
			wipeEntry(&entry);
			return NAMEMATCH_RENAME;
		}
	}

	return ret;
}
Exemple #7
0
void mlabel(int argc, char **argv, int type)
{

	char *newLabel;
	int verbose, clear, interactive, show;
	direntry_t entry;
	int result=0;
	char longname[VBUFSIZE];
	char shortname[45];
	ClashHandling_t ch;
	struct MainParam_t mp;
	Stream_t *RootDir;
	int c;
	int mangled;
	enum { SER_NONE, SER_RANDOM, SER_SET }  set_serial = SER_NONE;
	long serial = 0;
	int need_write_boot = 0;
	int have_boot = 0;
	char *eptr;
	union bootsector boot;
	Stream_t *Fs=0;
	int r;
	struct label_blk_t *labelBlock;
	int isRo=0;
	int *isRop=NULL;

	init_clash_handling(&ch);
	ch.name_converter = label_name;
	ch.ignore_entry = -2;

	verbose = 0;
	clear = 0;
	show = 0;

	if(helpFlag(argc, argv))
		usage(0);
	while ((c = getopt(argc, argv, "i:vcsnN:h")) != EOF) {
		switch (c) {
			case 'i':
				set_cmd_line_image(optarg, 0);
				break;
			case 'v':
				verbose = 1;
				break;
			case 'c':
				clear = 1;
				break;
			case 's':
				show = 1;
				break;
			case 'n':
				set_serial = SER_RANDOM;
				srandom((long)time (0));
				serial=random();
				break;
			case 'N':
				set_serial = SER_SET;
				serial = strtol(optarg, &eptr, 16);
				if(*eptr) {
					fprintf(stderr,
						"%s not a valid serial number\n",
						optarg);
					exit(1);
				}
				break;
			case 'h':
				usage(0);
			default:
				usage(1);
			}
	}

	if (argc - optind != 1 || !argv[optind][0] || argv[optind][1] != ':')
		usage(1);

	init_mp(&mp);
	newLabel = argv[optind]+2;
	if(strlen(newLabel) > VBUFSIZE) {
		fprintf(stderr, "Label too long\n");
		FREE(&RootDir);
		exit(1);
	}

	interactive = !show && !clear &&!newLabel[0] &&
		(set_serial == SER_NONE);
	if(!clear && !newLabel[0]) {
		isRop = &isRo;
	}
	RootDir = open_root_dir(argv[optind][0], isRop ? 0 : O_RDWR, isRop);
	if(isRo) {
		show = 1;
		interactive = 0;
	}	
	if(!RootDir) {
		fprintf(stderr, "%s: Cannot initialize drive\n", argv[0]);
		exit(1);
	}

	initializeDirentry(&entry, RootDir);
	r=vfat_lookup(&entry, 0, 0, ACCEPT_LABEL | MATCH_ANY,
		      shortname, longname);
	if (r == -2) {
		FREE(&RootDir);
		exit(1);
	}

	if(show || interactive){
		if(isNotFound(&entry))
			printf(" Volume has no label\n");
		else if (*longname)
			printf(" Volume label is %s (abbr=%s)\n",
			       longname, shortname);
		else
			printf(" Volume label is %s\n",  shortname);

	}

	/* ask for new label */
	if(interactive){
		newLabel = longname;
		fprintf(stderr,"Enter the new volume label : ");
		if(fgets(newLabel, VBUFSIZE, stdin) == NULL) {
			newLabel[0] = '\0';
			fprintf(stderr, "\n");
		}
		if(newLabel[0])
			newLabel[strlen(newLabel)-1] = '\0';
	}

	if((!show || newLabel[0]) && !isNotFound(&entry)){
		/* if we have a label, wipe it out before putting new one */
		if(interactive && newLabel[0] == '\0')
			if(ask_confirmation("Delete volume label (y/n): ")){
				FREE(&RootDir);
				exit(0);
			}
		entry.dir.attr = 0; /* for old mlabel */
		wipeEntry(&entry);
	}

	if (newLabel[0] != '\0') {
		ch.ignore_entry = 1;
		result = mwrite_one(RootDir,newLabel,0,labelit,NULL,&ch) ?
		  0 : 1;
	}

	have_boot = 0;
	if( (!show || newLabel[0]) || set_serial != SER_NONE) {
		Fs = GetFs(RootDir);
		have_boot = (force_read(Fs,boot.characters,0,sizeof(boot)) ==
			     sizeof(boot));
	}

	if(WORD_S(fatlen)) {
	    labelBlock = &boot.boot.ext.old.labelBlock;
	} else {
	    labelBlock = &boot.boot.ext.fat32.labelBlock;
	}

	if(!show || newLabel[0]){
		dos_name_t dosname;
		const char *shrtLabel;
		doscp_t *cp;
		if(!newLabel[0])
			shrtLabel = "NO NAME    ";
		else
			shrtLabel = newLabel;
		cp = GET_DOSCONVERT(Fs);
		label_name(cp, shrtLabel, verbose, &mangled, &dosname);

		if(have_boot && boot.boot.descr >= 0xf0 &&
		   labelBlock->dos4 == 0x29) {
			strncpy(labelBlock->label, dosname.base, 11);
			need_write_boot = 1;

		}
	}

	if((set_serial != SER_NONE) & have_boot) {
		if(have_boot && boot.boot.descr >= 0xf0 &&
		   labelBlock->dos4 == 0x29) {
			set_dword(labelBlock->serial, serial);	
			need_write_boot = 1;
		}
	}

	if(need_write_boot) {
		force_write(Fs, (char *)&boot, 0, sizeof(boot));
	}

	FREE(&RootDir);
	exit(result);
}
int copy_file(const char *source, const char *dest, int flags)
{
	struct stat source_stat;
	struct stat dest_stat;
	int dest_exists = 0;
	int status = 0;

	if ((!(flags & FILEUTILS_PRESERVE_SYMLINKS) &&
			lstat(source, &source_stat) < 0) ||
			((flags & FILEUTILS_PRESERVE_SYMLINKS) &&
			 stat(source, &source_stat) < 0)) {
		perror_msg("%s", source);
		return -1;
	}

	if (lstat(dest, &dest_stat) < 0) {
		if (errno != ENOENT) {
			perror_msg("unable to stat `%s'", dest);
			return -1;
		}
	} else {
		if (source_stat.st_dev == dest_stat.st_dev &&
			source_stat.st_ino == dest_stat.st_ino) {
		error_msg("`%s' and `%s' are the same file", source, dest);
		return -1;
	}
		dest_exists = 1;
	}

	if (S_ISDIR(source_stat.st_mode)) {
		DIR *dp;
		struct dirent *d;
		mode_t saved_umask = 0;

		if (!(flags & FILEUTILS_RECUR)) {
			error_msg("%s: omitting directory", source);
			return -1;
		}

		/* Create DEST.  */
		if (dest_exists) {
			if (!S_ISDIR(dest_stat.st_mode)) {
				error_msg("`%s' is not a directory", dest);
				return -1;
			}
		} else {
			mode_t mode;
			saved_umask = umask(0);

			mode = source_stat.st_mode;
			if (!(flags & FILEUTILS_PRESERVE_STATUS))
				mode = source_stat.st_mode & ~saved_umask;
			mode |= S_IRWXU;

			if (mkdir(dest, mode) < 0) {
				umask(saved_umask);
				perror_msg("cannot create directory `%s'", dest);
				return -1;
			}

			umask(saved_umask);
		}

		/* Recursively copy files in SOURCE.  */
		if ((dp = opendir(source)) == NULL) {
			perror_msg("unable to open directory `%s'", source);
			status = -1;
			goto end;
		}

		while ((d = readdir(dp)) != NULL) {
			char *new_source, *new_dest;

			if (strcmp(d->d_name, ".") == 0 ||
					strcmp(d->d_name, "..") == 0)
				continue;

			new_source = concat_path_file(source, d->d_name);
			new_dest = concat_path_file(dest, d->d_name);
			if (copy_file(new_source, new_dest, flags) < 0)
				status = -1;
			free(new_source);
			free(new_dest);
		}
		/* closedir have only EBADF error, but "dp" not changes */
		closedir(dp);

		if (!dest_exists &&
				chmod(dest, source_stat.st_mode & ~saved_umask) < 0) {
			perror_msg("unable to change permissions of `%s'", dest);
			status = -1;
		}
	} else if (S_ISREG(source_stat.st_mode)) {
		FILE *sfp, *dfp=NULL;
#ifdef CONFIG_FEATURE_PRESERVE_HARDLINKS
		char *link_name;

		if (!(flags & FILEUTILS_PRESERVE_SYMLINKS) &&
				is_in_ino_dev_hashtable(&source_stat, &link_name)) {
			if (link(link_name, dest) < 0) {
				perror_msg("unable to link `%s'", dest);
				return -1;
			}

			return 0;
		}
#endif

		if ((sfp = wfopen(source, "r")) == NULL) {
			return -1;
		}

		if (dest_exists) {
			if (flags & FILEUTILS_INTERACTIVE) {
				fprintf(stderr, "%s: overwrite `%s'? ", applet_name, dest);
				if (!ask_confirmation()) {
					fclose (sfp);
					return 0;
				}
			}

			if ((dfp = fopen(dest, "w")) == NULL) {
				if (!(flags & FILEUTILS_FORCE)) {
					perror_msg("unable to open `%s'", dest);
					fclose (sfp);
					return -1;
				}

				if (unlink(dest) < 0) {
					perror_msg("unable to remove `%s'", dest);
					fclose (sfp);
					return -1;
				}

				dest_exists = 0;
			}
		}

		if (!dest_exists) {
			int fd;

			if ((fd = open(dest, O_WRONLY|O_CREAT, source_stat.st_mode)) < 0 ||
					(dfp = fdopen(fd, "w")) == NULL) {
				if (fd >= 0)
					close(fd);
				perror_msg("unable to open `%s'", dest);
				fclose (sfp);
				return -1;
			}
		}

		if (copy_file_chunk(sfp, dfp, -1) < 0)
			status = -1;

		if (fclose(dfp) < 0) {
			perror_msg("unable to close `%s'", dest);
			status = -1;
		}

		if (fclose(sfp) < 0) {
			perror_msg("unable to close `%s'", source);
			status = -1;
		}
			}
	else if (S_ISBLK(source_stat.st_mode) || S_ISCHR(source_stat.st_mode) ||
	    S_ISSOCK(source_stat.st_mode) || S_ISFIFO(source_stat.st_mode) ||
	    S_ISLNK(source_stat.st_mode)) {

		if (dest_exists &&
		       ((flags & FILEUTILS_FORCE) == 0 || unlink(dest) < 0)) {
				perror_msg("unable to remove `%s'", dest);
				return -1;

			}
	} else {
		error_msg("internal error: unrecognized file type");
		return -1;
		}
	if (S_ISBLK(source_stat.st_mode) || S_ISCHR(source_stat.st_mode) ||
	    S_ISSOCK(source_stat.st_mode)) {
		if (mknod(dest, source_stat.st_mode, source_stat.st_rdev) < 0) {
			perror_msg("unable to create `%s'", dest);
			return -1;
		}
	} else if (S_ISFIFO(source_stat.st_mode)) {
		if (mkfifo(dest, source_stat.st_mode) < 0) {
			perror_msg("cannot create fifo `%s'", dest);
			return -1;
		}
	} else if (S_ISLNK(source_stat.st_mode)) {
		char *lpath;

		lpath = xreadlink(source);
		if (symlink(lpath, dest) < 0) {
			perror_msg("cannot create symlink `%s'", dest);
			return -1;
		}
		free(lpath);

#if (__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 1)
		if (flags & FILEUTILS_PRESERVE_STATUS)
			if (lchown(dest, source_stat.st_uid, source_stat.st_gid) < 0)
				perror_msg("unable to preserve ownership of `%s'", dest);
#endif

#ifdef CONFIG_FEATURE_PRESERVE_HARDLINKS
		add_to_ino_dev_hashtable(&source_stat, dest);
#endif

		return 0;
	}

#ifdef CONFIG_FEATURE_PRESERVE_HARDLINKS
	add_to_ino_dev_hashtable(&source_stat, dest);
#endif

end:

	if (flags & FILEUTILS_PRESERVE_STATUS) {
		struct utimbuf times;

		times.actime = source_stat.st_atime;
		times.modtime = source_stat.st_mtime;
		if (utime(dest, &times) < 0)
			perror_msg("unable to preserve times of `%s'", dest);
		if (chown(dest, source_stat.st_uid, source_stat.st_gid) < 0) {
			source_stat.st_mode &= ~(S_ISUID | S_ISGID);
			perror_msg("unable to preserve ownership of `%s'", dest);
		}
		if (chmod(dest, source_stat.st_mode) < 0)
			perror_msg("unable to preserve permissions of `%s'", dest);
	}

	return status;
}
Exemple #9
0
int disk_image(disk_t *disk, const partition_t *partition, const char *image_dd)
{
  int ind_stop=0;
  uint64_t nbr_read_error=0;
  uint64_t src_offset=partition->part_offset;
  uint64_t src_offset_old;
  uint64_t dst_offset=0;
  const uint64_t src_offset_end=partition->part_offset+partition->part_size;
  const uint64_t offset_inc=(src_offset_end-src_offset)/10000;
  uint64_t src_offset_next=src_offset;
  struct stat stat_buf;
  unsigned char *buffer=(unsigned char *)MALLOC(READ_SIZE);
  unsigned int readsize=READ_SIZE;
  int disk_dst;
#ifdef HAVE_NCURSES
  WINDOW *window;
#endif
  if((disk_dst=open(image_dd, O_CREAT|O_LARGEFILE|O_RDWR|O_BINARY, 0644)) < 0)
  {
    log_error("Can't create file %s.\n",image_dd);
    display_message("Can't create file!\n");
    free(buffer);
    return -1;
  }
  if(fstat(disk_dst, &stat_buf)==0)
  {
    int res=1;
#ifdef HAVE_NCURSES
    if(stat_buf.st_size > 0)
      res=ask_confirmation("Append to existing file ? (Y/N)");
#endif
    if(res>0)
    {
      dst_offset=stat_buf.st_size;
      src_offset+=dst_offset;
    }
  }
  src_offset_old=src_offset;
#ifdef HAVE_NCURSES
  window=newwin(LINES, COLS, 0, 0);	/* full screen */
  aff_copy(window);
  wmove(window,5,0);
  wprintw(window,"%s\n",disk->description_short(disk));
  wmove(window,6,0);
  aff_part(window,AFF_PART_ORDER|AFF_PART_STATUS,disk,partition);
  wmove(window,10,0);
  waddstr(window, "Disk images are mainly used ");
  wmove(window,11,0);
  waddstr(window, "- for forensics purpose");
  wmove(window,12,0);
  waddstr(window, "- or to deal with media with bad sectors");
#ifdef WIN32
  wmove(window,14,0);
  waddstr(window, "To use TestDisk or PhotoRec with this disk image, go in command line and run");
  wmove(window,15,0);
  waddstr(window, "   testdisk_win.exe image.dd");
  wmove(window,16,0);
  waddstr(window, "or photorec_win.exe image.dd");
#else
  wmove(window,14,0);
  waddstr(window, "To use TestDisk or PhotoRec with this disk image, start a Terminal and run");
  wmove(window,15,0);
  waddstr(window, "   testdisk image.dd");
  wmove(window,16,0);
  waddstr(window, "or photorec image.dd");
#endif
  wmove(window,22,0);
  wattrset(window, A_REVERSE);
  waddstr(window,"  Stop  ");
  wattroff(window, A_REVERSE);
#endif
  while(ind_stop==0 && src_offset < src_offset_end)
  {
    ssize_t pread_res;
    int update=0;
    if(src_offset_end-src_offset < readsize)
      readsize=src_offset_end-src_offset;
    pread_res=disk->pread(disk, buffer, readsize, src_offset);
    if(pread_res > 0)
    {
#if defined(HAVE_PWRITE)
      if(pwrite(disk_dst, buffer, pread_res, dst_offset)<0)
      {
	ind_stop=2;
      }
#else
      if(lseek(disk_dst, dst_offset, SEEK_SET)<0)
      {
	ind_stop=2;
      }
      if(write(disk_dst, buffer, pread_res) != pread_res)
      {
	ind_stop=2;
      }
#endif
      if(src_offset_old + SKIP_SIZE==src_offset)
      {
	disk_image_backward(disk_dst, disk, src_offset_old, src_offset, dst_offset);
      }
    }
    src_offset_old=src_offset;
    if((unsigned)pread_res == readsize)
    {
      src_offset+=readsize;
      dst_offset+=readsize;
      readsize=READ_SIZE;
    }
    else
    {
      update=1;
      nbr_read_error++;
      readsize=disk->sector_size;
      src_offset+=SKIP_SIZE;
      dst_offset+=SKIP_SIZE;
    }
    if(src_offset>src_offset_next)
    {
      update=1;
      src_offset_next=src_offset+offset_inc;
    }
    if(update)
    {
#ifdef HAVE_NCURSES
      unsigned int i;
      const float percent=(src_offset-partition->part_offset)*100.00/partition->part_size;
      wmove(window,7,0);
      wprintw(window,"%3.2f %% ", percent);
      for(i=0;i<percent*3/5;i++)
	wprintw(window,"=");
      wprintw(window,">");
      wrefresh(window);
      ind_stop=check_enter_key_or_s(window);
#endif
    }
  }
  close(disk_dst);
#ifdef HAVE_NCURSES
  delwin(window);
  (void) clearok(stdscr, TRUE);
#ifdef HAVE_TOUCHWIN
  touchwin(stdscr);
#endif
#endif
  if(ind_stop==2)
  {
    display_message("No space left for the file image.\n");
    free(buffer);
    return -2;
  }
  if(ind_stop)
  {
    if(nbr_read_error==0)
      display_message("Incomplete image created.\n");
    else
      display_message("Incomplete image created: read errors have occured.\n");
    free(buffer);
    return 0;
  }
  if(nbr_read_error==0)
    display_message("Image created successfully.\n");
  else
    display_message("Image created successfully but read errors have occured.\n");
  free(buffer);
  return 0;
}
Exemple #10
0
/* Write the Unix file */
static int unix_write(direntry_t *entry, MainParam_t *mp, int needfilter)
{
	Arg_t *arg=(Arg_t *) mp->arg;
	time_t mtime;
	Stream_t *File=mp->File;
	Stream_t *Target, *Source;
	struct stat stbuf;
	int ret;
	char errmsg[80];
	char *unixFile;

	File->Class->get_data(File, &mtime, 0, 0, 0);

	if (!arg->preserveTime)
		mtime = 0L;

	if(arg->type)
		unixFile = "-";
	else
		unixFile = mpBuildUnixFilename(mp);
	if(!unixFile) {
		printOom();
		return ERROR_ONE;
	}

	/* if we are creating a file, check whether it already exists */
	if(!arg->type) {
		if (!arg->nowarn && &arg->type && !access(unixFile, 0)){
			if( ask_confirmation("File \"%s\" exists, overwrite (y/n) ? ",
					     unixFile,0)) {
				free(unixFile);
				return ERROR_ONE;
			}
			
			/* sanity checking */
			if (!stat(unixFile, &stbuf) && !S_ISREG(stbuf.st_mode)) {
				fprintf(stderr,"\"%s\" is not a regular file\n",
					unixFile);
				
				free(unixFile);
				return ERROR_ONE;
			}
		}
	}

	if(!arg->type && arg->verbose) {
		fprintf(stderr,"Copying ");
		mpPrintFilename(stderr,mp);
		fprintf(stderr,"\n");
	}
	
	if(got_signal) {
		free(unixFile);
		return ERROR_ONE;
	}

	if ((Target = SimpleFileOpen(0, 0, unixFile,
				     O_WRONLY | O_CREAT | O_TRUNC,
				     errmsg, 0, 0, 0))) {
		ret = 0;
		if(needfilter && arg->textmode){
			Source = open_filter(COPY(File));
			if (!Source)
				ret = -1;
		} else
			Source = COPY(File);

		if (ret == 0 )
			ret = copyfile(Source, Target);
		FREE(&Source);
		FREE(&Target);
		if(ret <= -1){
			if(!arg->type) {
				unlink(unixFile);
				free(unixFile);
			}
			return ERROR_ONE;
		}
		if(!arg->type) {
			set_mtime(unixFile, mtime);
			free(unixFile);
		}
		return GOT_ONE;
	} else {
		fprintf(stderr,"%s\n", errmsg);
		if(!arg->type)
			free(unixFile);
		return ERROR_ONE;
	}
}
Exemple #11
0
int interface_recovery(disk_t *disk_car, const list_part_t * list_part_org, const int verbose, const int dump_ind, const int align, const int ask_part_order, const unsigned int expert, char **current_cmd)
{
  int res_interface_write;
  int fast_mode=0;
  do
  {
    list_part_t *list_part;
    const list_part_t *element;
    unsigned int menu=0;
    if(fast_mode==0)
      menu=3;	/* Search! */
#ifdef HAVE_NCURSES
    aff_copy(stdscr);
    wmove(stdscr,4,0);
    wprintw(stdscr,"%s",disk_car->description(disk_car));
    wmove(stdscr,5,0);
#endif
    res_interface_write=0;
    list_part=search_part(disk_car, list_part_org, verbose, dump_ind, fast_mode, current_cmd);
    if(list_part!=NULL && (disk_car->arch==&arch_i386 || disk_car->arch==&arch_sun))
    { /* Correct disk geometry is necessary for successfull Intel and Sun partition recovery */
      const unsigned int heads_per_cylinder=get_geometry_from_list_part(disk_car, list_part, verbose);
      if(disk_car->geom.heads_per_cylinder!=heads_per_cylinder)
      {
	log_warning("Warning: the current number of heads per cylinder is %u but the correct value may be %u.\n",
	    disk_car->geom.heads_per_cylinder, heads_per_cylinder);
#ifdef HAVE_NCURSES
	if(*current_cmd==NULL)
	{
	  warning_geometry_ncurses(disk_car, heads_per_cylinder);
	}
#endif
      }
    }
    align_structure(list_part, disk_car, align);

    disk_car->arch->init_structure(disk_car,list_part,verbose);
    if(verbose>0)
    {
#ifdef TARGET_LINUX
      unsigned int i=0;
#endif
      /* Write found partitions in the log file */
      log_info("\nResults\n");
      for(element=list_part;element!=NULL;element=element->next)
	log_partition(disk_car,element->part);
#ifdef TARGET_LINUX
      if(list_part!=NULL)
	log_info("\nHint for advanced users: dmsetup may be used if you prefer to avoid rewriting the partition table for the moment:\n");
      for(element=list_part;element!=NULL;element=element->next)
      {
	const partition_t *partition=element->part;
	log_info("echo \"0 %llu linear %s %llu\" | dmsetup create test%u\n",
	    (long long unsigned)(partition->part_size/512),
	    disk_car->device,
	    (long long unsigned)(partition->part_offset/512),
	    i++);
      }
#endif
    }
    do
    {
      list_part=ask_structure(disk_car,list_part,verbose,current_cmd);
    } while(fast_mode!=0 && list_part!=NULL && is_structure_empty(list_part)
#ifdef HAVE_NCURSES
	&& ask_confirmation("Discard the results, confirm ? (Y/N)")==0
#endif
    );
    if(disk_car->arch->test_structure(list_part)==0)
    {
      int do_again=0;
      int max_ext=0;
      int can_ask_minmax_ext=0;
      int no_confirm=0;
      list_part=reduce_structure(list_part);
      /* sort list_part */
      list_part=sort_partition_list(list_part);
      /* Create PC/Intel Extended partition */
      /* if(disk_car->arch==&arch_i386) */
      {
	list_part_t *parts;
	uint64_t partext_offset=0;
	uint64_t partext_size=0;
	list_part=add_ext_part_i386(disk_car, list_part, !max_ext, verbose);
	for(parts=list_part;parts!=NULL;parts=parts->next)
	  if(parts->part->status==STATUS_EXT)
	  {
	    partext_offset=parts->part->part_offset;
	    partext_size=parts->part->part_size;
	  }
	if(partext_offset>0)
	{
	  list_part=add_ext_part_i386(disk_car, list_part, max_ext, verbose);
	  for(parts=list_part;parts!=NULL;parts=parts->next)
	    if(parts->part->status==STATUS_EXT)
	    {
	      if(partext_offset!=parts->part->part_offset || partext_size!=parts->part->part_size)
		can_ask_minmax_ext=1;
	    }
	}
      }
      list_part=disk_car->arch->init_part_order(disk_car,list_part);
      if(ask_part_order!=0)
      {
	/* Demande l'ordre des entrees dans le MBR */
#ifdef HAVE_NCURSES
	ask_mbr_order_i386(disk_car,list_part);
#endif
	/* Demande l'ordre des partitions etendues */
      }
      do
      {
	do_again=0;
	res_interface_write=interface_write(disk_car,list_part,(fast_mode<1),can_ask_minmax_ext, &no_confirm, current_cmd,&menu);
	switch(res_interface_write)
	{
	  case 'W':
	    if(disk_car->arch == &arch_mac)
	    {
#ifdef HAVE_NCURSES
	      write_part_mac_warning_ncurses();
#endif
	    }
	    else if(disk_car->arch == &arch_sun)
	    {
#ifdef HAVE_NCURSES
	      not_implemented("write_part_sun");
#endif
	    }
	    else if(disk_car->arch == &arch_xbox)
	    {
#ifdef HAVE_NCURSES
	      not_implemented("write_part_xbox");
#endif
	    }
	    else if(disk_car->arch->write_part!=NULL)
	    {
	      if(no_confirm!=0
#ifdef HAVE_NCURSES
		  || ask_confirmation("Write partition table, confirm ? (Y/N)")!=0
#endif
		)
	      {
		log_info("write!\n");
		if(disk_car->arch->write_part(disk_car, list_part, RW, verbose))
		{
		  display_message(msg_PART_WR_ERR);
		}
		else
		{
		  use_backup(disk_car,list_part,verbose,dump_ind,expert,current_cmd);
		  if(no_confirm==0)
		    display_message("You will have to reboot for the change to take effect.\n");
		}
	      }
	      else
		log_info("Don't write, no confirmation\n");
	    }
	    break;
	  case 0:
	    if(disk_car->arch->write_part!=NULL)
	    {
	      log_info("simulate write!\n");
	      disk_car->arch->write_part(disk_car, list_part, RO, verbose);
	    }
	    break;
	  case 'S':
	    if(fast_mode<2)
	      fast_mode++;
	    break;
	  case 'E':
	    max_ext=!max_ext;
	    list_part=add_ext_part_i386(disk_car, list_part, max_ext, verbose);
	    do_again=1;
	    break;
	}
      }
      while(do_again==1);
    }
    else
    {
      display_message("Invalid partition structure.\n");
    }
    part_free_list(list_part);
  } while(res_interface_write=='S');
  return 0;
}
extern int remove_file(const char *path, int flags)
{
	struct stat path_stat;
	int path_exists = 1;

	if (lstat(path, &path_stat) < 0) {
		if (errno != ENOENT) {
			perror_msg("unable to stat `%s'", path);
			return -1;
		}

		path_exists = 0;
	}

	if (!path_exists) {
		if (!(flags & FILEUTILS_FORCE)) {
			perror_msg("cannot remove `%s'", path);
			return -1;
		}
		return 0;
	}

	if (S_ISDIR(path_stat.st_mode)) {
		DIR *dp;
		struct dirent *d;
		int status = 0;

		if (!(flags & FILEUTILS_RECUR)) {
			error_msg("%s: is a directory", path);
			return -1;
		}

		if ((!(flags & FILEUTILS_FORCE) && access(path, W_OK) < 0 &&
					isatty(0)) ||
				(flags & FILEUTILS_INTERACTIVE)) {
			fprintf(stderr, "%s: descend into directory `%s'? ", applet_name,
					path);
			if (!ask_confirmation())
				return 0;
		}

		if ((dp = opendir(path)) == NULL) {
			perror_msg("unable to open `%s'", path);
			return -1;
		}

		while ((d = readdir(dp)) != NULL) {
			char *new_path;

			if (strcmp(d->d_name, ".") == 0 ||
					strcmp(d->d_name, "..") == 0)
				continue;

			new_path = concat_path_file(path, d->d_name);
			if (remove_file(new_path, flags) < 0)
				status = -1;
			free(new_path);
		}

		if (closedir(dp) < 0) {
			perror_msg("unable to close `%s'", path);
			return -1;
		}

		if (flags & FILEUTILS_INTERACTIVE) {
			fprintf(stderr, "%s: remove directory `%s'? ", applet_name, path);
			if (!ask_confirmation())
				return status;
		}

		if (rmdir(path) < 0) {
			perror_msg("unable to remove `%s'", path);
			return -1;
		}

		return status;
	} else {
		if ((!(flags & FILEUTILS_FORCE) && access(path, W_OK) < 0 &&
					!S_ISLNK(path_stat.st_mode) &&
					isatty(0)) ||
				(flags & FILEUTILS_INTERACTIVE)) {
			fprintf(stderr, "%s: remove `%s'? ", applet_name, path);
			if (!ask_confirmation())
				return 0;
		}

		if (unlink(path) < 0) {
			perror_msg("unable to remove `%s'", path);
			return -1;
		}

		return 0;
	}
}
Exemple #13
0
int exFAT_boot_sector(disk_t *disk, partition_t *partition, const int verbose, char **current_cmd)
{
  unsigned char *buffer_bs;
  unsigned char *buffer_backup_bs;
  const char *options="";
  int rescan=1;
#ifdef HAVE_NCURSES
  struct MenuItem menu_exFAT[]=
  {
    { 'P', "Previous",""},
    { 'N', "Next","" },
    { 'Q', "Quit","Return to Advanced menu"},
    { 'O', "Org. BS","Copy superblock over backup sector"},
    { 'B', "Backup BS","Copy backup superblock over superblock"},
    { 'D', "Dump","Dump superblock and backup superblock"},
    { 0, NULL, NULL }
  };
#endif
  buffer_bs=(unsigned char*)MALLOC(12 * disk->sector_size);
  buffer_backup_bs=(unsigned char*)MALLOC(12 * disk->sector_size);

  while(1)
  {
#ifdef HAVE_NCURSES
    unsigned int menu=0;
#endif
    int command;
    screen_buffer_reset();
    if(rescan==1)
    {
      int opt_over=0;
      int opt_B=0;
      int opt_O=0;
      options="D";
#ifdef HAVE_NCURSES
      aff_copy(stdscr);
      wmove(stdscr,4,0);
      wprintw(stdscr,"%s",disk->description(disk));
      mvwaddstr(stdscr,5,0,msg_PART_HEADER_LONG);
      wmove(stdscr,6,0);
      aff_part(stdscr,AFF_PART_ORDER|AFF_PART_STATUS,disk,partition);
#endif
      log_info("\nexFAT_boot_sector\n");
      log_partition(disk,partition);
      screen_buffer_add("Boot sector\n");
      if(disk->pread(disk, buffer_bs, 12 * disk->sector_size, partition->part_offset) != 12 * disk->sector_size)
      {
	screen_buffer_add("Bad: can't read exFAT boot record.\n");
	memset(buffer_bs,0,12 * disk->sector_size);
      }
      else if(test_EXFAT((const struct exfat_super_block*)buffer_bs, partition)==0)
      {
	screen_buffer_add("exFAT OK\n");
	opt_O=1;
	opt_over=1;
      }
      else
	screen_buffer_add("Bad\n");
      screen_buffer_add("\nBackup boot record\n");
      if(disk->pread(disk, buffer_backup_bs, 12 * disk->sector_size, partition->part_offset + 12 * disk->sector_size) != 12 * disk->sector_size)
      {
	screen_buffer_add("Bad: can't read exFAT backup boot record.\n");
	memset(buffer_backup_bs,0,12 * disk->sector_size);
      }
      else if(test_EXFAT((const struct exfat_super_block*)buffer_backup_bs, partition)==0)
      {
	screen_buffer_add("exFAT OK\n");
	opt_B=1;
	opt_over=1;
      }
      else
	screen_buffer_add("Bad\n");
      screen_buffer_add("\n");
      if(memcmp(buffer_bs,buffer_backup_bs,12 * disk->sector_size)==0)
      {
	screen_buffer_add("Sectors are identical.\n");
	opt_over=0;
      }
      else
      {
	screen_buffer_add("Sectors are not identical.\n");
      }
      if(opt_over!=0)
      {
	if(opt_B!=0 && opt_O!=0)
	  options="DOB";
	else if(opt_B!=0)
	  options="DB";
	else if(opt_O!=0)
	  options="DO";
      }
      rescan=0;
    }
    screen_buffer_to_log();
    if(*current_cmd!=NULL)
    {
      command=0;
      while(*current_cmd[0]==',')
	(*current_cmd)++;
      if(strncmp(*current_cmd,"dump",4)==0)
      {
	(*current_cmd)+=4;
	command='D';
      }
      else if(strncmp(*current_cmd,"originalexFAT",11)==0)
      {
	(*current_cmd)+=11;
	if(strchr(options,'O')!=NULL)
	    command='O';
      }
      else if(strncmp(*current_cmd,"backupexFAT",9)==0)
      {
	(*current_cmd)+=9;
	if(strchr(options,'B')!=NULL)
	    command='B';
      }
    }
    else
    {
      log_flush();
#ifdef HAVE_NCURSES
      command=screen_buffer_display_ext(stdscr, options, menu_exFAT, &menu);
#else
      command=0;
#endif
    }
    switch(command)
    {
      case 0:
        free(buffer_bs);
        free(buffer_backup_bs);
	return 0;
      case 'O': /* O : copy original superblock over backup boot */
#ifdef HAVE_NCURSES
	if(ask_confirmation("Copy original exFAT boot record over backup, confirm ? (Y/N)")!=0)
	{
	  log_info("copy original superblock over backup boot\n");
	  if(disk->pwrite(disk, buffer_bs, 12 * disk->sector_size, partition->part_offset + 12 * disk->sector_size) != 12 * disk->sector_size)
	  {
	    display_message("Write error: Can't overwrite exFAT backup boot record\n");
	  }
          disk->sync(disk);
	  rescan=1;
	}
#endif
	break;
      case 'B': /* B : copy backup superblock over main superblock */
#ifdef HAVE_NCURSES
	if(ask_confirmation("Copy backup exFAT boot record over main boot record, confirm ? (Y/N)")!=0)
	{
	  log_info("copy backup superblock over main superblock\n");
	  /* Reset information about backup boot record */
	  partition->sb_offset=0;
	  if(disk->pwrite(disk, buffer_backup_bs, 12 * disk->sector_size, partition->part_offset) != 12 * disk->sector_size)
	  {
	    display_message("Write error: Can't overwrite exFAT main boot record\n");
	  }
          disk->sync(disk);
	  rescan=1;
	}
#endif
	break;
      case 'D':
	exFAT_dump(disk, partition, buffer_bs, buffer_backup_bs, current_cmd);
	break;
    }
  }
}
Exemple #14
0
int ntfs_boot_sector(disk_t *disk_car, partition_t *partition, const int verbose, const unsigned int expert, char **current_cmd)
{
  unsigned char *buffer_bs;
  unsigned char *buffer_backup_bs;
  const char *options="";
#ifdef HAVE_NCURSES
  struct MenuItem menu_ntfs[]=
  {
    { 'P', "Previous",""},
    { 'N', "Next","" },
    { 'Q', "Quit","Return to Advanced menu"},
    { 'L', "List", "List directories and files, copy data from NTFS" },
    { 'O', "Org. BS","Copy boot sector over backup sector"},
    { 'B', "Backup BS","Copy backup boot sector over boot sector"},
    { 'R', "Rebuild BS","Rebuild boot sector"},
    { 'M', "Repair MFT","Check MFT"},
    { 'D', "Dump","Dump boot sector and backup boot sector"},
    { 0, NULL, NULL }
  };
#endif
  buffer_bs=(unsigned char*)MALLOC(NTFS_BOOT_SECTOR_SIZE);
  buffer_backup_bs=(unsigned char*)MALLOC(NTFS_BOOT_SECTOR_SIZE);

  while(1)
  {
    unsigned int menu=0;
    int command;
    screen_buffer_reset();
    {
      int identical_sectors=0;
      int opt_B=0;
      int opt_O=0;
#ifdef HAVE_NCURSES
      aff_copy(stdscr);
      wmove(stdscr,4,0);
      wprintw(stdscr,"%s",disk_car->description(disk_car));
      mvwaddstr(stdscr,5,0,msg_PART_HEADER_LONG);
      wmove(stdscr,6,0);
      aff_part(stdscr,AFF_PART_ORDER|AFF_PART_STATUS,disk_car,partition);
#endif
      log_info("\nntfs_boot_sector\n");
      log_partition(disk_car,partition);
      screen_buffer_add("Boot sector\n");
      if(disk_car->pread(disk_car, buffer_bs, NTFS_BOOT_SECTOR_SIZE, partition->part_offset) != NTFS_BOOT_SECTOR_SIZE)
      {
	screen_buffer_add("ntfs_boot_sector: Can't read boot sector.\n");
	memset(buffer_bs,0,NTFS_BOOT_SECTOR_SIZE);
      }
      if(test_NTFS(disk_car,(struct ntfs_boot_sector*)buffer_bs,partition,verbose,0)==0)
      {
	screen_buffer_add("Status: OK\n");
	opt_O=1;
      }
      else
      {
	screen_buffer_add("Status: Bad\n");
      }
      screen_buffer_add("\nBackup boot sector\n");
      if(disk_car->pread(disk_car, buffer_backup_bs, NTFS_BOOT_SECTOR_SIZE, partition->part_offset + partition->part_size - disk_car->sector_size) != NTFS_BOOT_SECTOR_SIZE)
      {
	screen_buffer_add("ntfs_boot_sector: Can't read backup boot sector.\n");
	memset(buffer_backup_bs,0,NTFS_BOOT_SECTOR_SIZE);
      }
      if(test_NTFS(disk_car,(struct ntfs_boot_sector*)buffer_backup_bs,partition,verbose,0)==0)
      {
	screen_buffer_add("Status: OK\n");
	opt_B=1;
      }
      else
      {
	screen_buffer_add("Status: Bad\n");
      }
      screen_buffer_add("\n");
      if(memcmp(buffer_bs,buffer_backup_bs,NTFS_BOOT_SECTOR_SIZE)==0)
      {
	log_ntfs_info((const struct ntfs_boot_sector *)buffer_bs);
	screen_buffer_add("Sectors are identical.\n");
	identical_sectors=1;
      }
      else
      {
	log_ntfs2_info((const struct ntfs_boot_sector *)buffer_bs, (const struct ntfs_boot_sector *)buffer_backup_bs);
	screen_buffer_add("Sectors are not identical.\n");
	identical_sectors=0;
      }
      screen_buffer_add("\n");
      screen_buffer_add("A valid NTFS Boot sector must be present in order to access\n");
      screen_buffer_add("any data; even if the partition is not bootable.\n");
      if(opt_B!=0 && opt_O!=0)
      {
	if(identical_sectors==0)
	  options="DOBRL";
	else
	  options="DRML";
      }
      else if(opt_B!=0)
      {
	menu=5;
	if(expert>0)
	  options="DBRML";
	else
	  options="DBRL";
      }
      else if(opt_O!=0)
      {
	menu=4;
	options="DORL";
      }
      else
	options="DR";
    }
    screen_buffer_to_log();
    if(*current_cmd!=NULL)
    {
      command=0;
      while(*current_cmd[0]==',')
	(*current_cmd)++;
      if(strncmp(*current_cmd,"rebuildbs",9)==0)
      {
	(*current_cmd)+=9;
	command='R';
      }
      else if(strncmp(*current_cmd,"dump",4)==0)
      {
	(*current_cmd)+=4;
	command='D';
      }
      else if(strncmp(*current_cmd,"list",4)==0)
      {
	(*current_cmd)+=4;
	command='L';
      }
      else if(strncmp(*current_cmd,"originalntfs",11)==0)
      {
	(*current_cmd)+=11;
	if(strchr(options,'O')!=NULL)
	    command='O';
      }
      else if(strncmp(*current_cmd,"backupntfs",9)==0)
      {
	(*current_cmd)+=9;
	if(strchr(options,'B')!=NULL)
	    command='B';
      }
      else if(strncmp(*current_cmd,"repairmft",9)==0)
      {
	(*current_cmd)+=9;
	if(strchr(options,'M')!=NULL)
	    command='M';
      }
    }
    else
    {
      log_flush();
#ifdef HAVE_NCURSES
      command=screen_buffer_display_ext(stdscr, options, menu_ntfs, &menu);
#else
      command=0;
#endif
    }
    switch(command)
    {
      case 0:
        free(buffer_bs);
        free(buffer_backup_bs);
	return 0;
      case 'O': /* O : copy original boot sector over backup boot */
#ifdef HAVE_NCURSES
	if(ask_confirmation("Copy original NTFS boot sector over backup boot, confirm ? (Y/N)")!=0)
	{
	  log_info("copy original boot sector over backup boot\n");
	  if(disk_car->pwrite(disk_car, buffer_bs, NTFS_BOOT_SECTOR_SIZE, partition->part_offset + partition->part_size - disk_car->sector_size) != NTFS_BOOT_SECTOR_SIZE)
	  {
	    display_message("Write error: Can't overwrite NTFS backup boot sector\n");
	  }
          disk_car->sync(disk_car);
	}
#endif
	break;
      case 'B': /* B : copy backup boot sector over boot sector */
#ifdef HAVE_NCURSES
	if(ask_confirmation("Copy backup NTFS boot sector over boot sector, confirm ? (Y/N)")!=0)
	{
	  log_info("copy backup boot sector over boot sector\n");
	  /* Reset information about backup boot sector */
	  partition->sb_offset=0;
	  if(disk_car->pwrite(disk_car, buffer_backup_bs, NTFS_BOOT_SECTOR_SIZE, partition->part_offset) != NTFS_BOOT_SECTOR_SIZE)
	  {
	    display_message("Write error: Can't overwrite NTFS boot sector\n");
	  }
          disk_car->sync(disk_car);
	}
#endif
	break;
      case 'L':
	if(strchr(options,'O')==NULL && strchr(options,'B')!=NULL)
	{
	  io_redir_add_redir(disk_car,partition->part_offset,NTFS_BOOT_SECTOR_SIZE,0,buffer_backup_bs);
	  dir_partition(disk_car, partition, 0,current_cmd);
	  io_redir_del_redir(disk_car,partition->part_offset);
	}
	else
	  dir_partition(disk_car, partition, 0,current_cmd);
	break;
      case 'M':
        repair_MFT(disk_car, partition, verbose, expert, current_cmd);
	break;
      case 'R': /* R : rebuild boot sector */
	rebuild_NTFS_BS(disk_car, partition, verbose, 1, expert, current_cmd);
	break;
      case 'D':
	dump_NTFS(disk_car, partition, buffer_bs, buffer_backup_bs);
	break;
    }
  }
}