Logo Search packages:      
Sourcecode: fatsort version File versions  Download package

fatsort.c

/*
      FATSort, utility for sorting FAT directory structures
      Copyright (C) 2004 Boris Leidner <fatsort(at)formenos.de>

      This program is free software; you can redistribute it and/or
      modify it under the terms of the GNU General Public License
      as published by the Free Software Foundation; either version 2
      of the License, or (at your option) any later version.

      This program is distributed in the hope that it will be useful,
      but WITHOUT ANY WARRANTY; without even the implied warranty of
      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      GNU General Public License for more details.

      You should have received a copy of the GNU General Public License
      along with this program; if not, write to the Free Software
      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/

/*
      This file contains the main function of fatsort.
*/

#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <string.h>
#include <unistd.h>
#include <stdarg.h>
#include <assert.h>
#include <errno.h>
#include <locale.h>
#include <time.h>

// project includes
#include "endianness.h"
#include "signal.h"
#include "FAT_fs.h"
#include "options.h"
#include "errors.h"
#include "sort.h"
#include "misc.h"
#include "platform.h"

#ifdef __WIN32__
#include <ctype.h>
#endif

// program information
#define INFO_PROGRAM "FATSort Utility"
#define INFO_VERSION "0.9.14"
#define INFO_AUTHOR "Boris Leidner <fatsort(at)formenos.de>"
#define INFO_HEADER INFO_PROGRAM " " INFO_VERSION " by " INFO_AUTHOR
#define INFO_LICENSE    "License GPLv2: GNU GPL version 2 (see LICENSE.txt)\n" \
                  "This is free software: you are free to change and redistribute it.\n" \
                  "There is NO WARRANTY, to the extent permitted by law.\n"

#define INFO_USAGE "\n" "Usage: fatsort [options] device\n" \
                  "\n" \
                  "Options:\n" \
                  "\t-c\t Ignore case of file names\n" \
                  "\t-f\t Force sorting even if filesystem is mounted\n" \
                  "\t-h\t Print some help\n" \
                  "\t-i\t Print file system information only\n" \
                  "\t-l\t Print current order of files only\n" \
                  "\t-o flag\t Sort order of files where flag is one of\n" \
                  "\t\t\td : directories first (default)\n" \
                  "\t\t\tf : files first\n" \
                  "\t\t\ta : files and directories are not differentiated\n" \
                  "\t-n\t Natural order sorting\n" \
                  "\t-d dir\t Sort directory dir only\n" \
                  "\t-D dir\t Sort directory dir and all subdirectories\n" \
                  "\t-q\t Be quiet\n" \
                  "\t-r\t Sort in reverse order\n" \
                  "\t-R\t Sort in random order\n" \
                  "\t-v\t Print version information\n" \
                  "\n" \
                  "Device must be a FAT16 or FAT32 file system. FAT12 is not supported yet.\n" \
                  "\n" \
                  "Example: fatsort /dev/sda\n" \
                  "\n" \
                  "NOTE: THE FILESYSTEM MUST BE CONSISTENT, OTHERWISE YOU MAY DAMAGE IT!\n" \
                  "IF SOMEONE ELSE HAS ACCESS TO THE DEVICE HE MIGHT EXPLOIT FATSORT WITH\n" \
                  "A FORGED CORRUPT FILESYSTEM! USE THIS PROGRAM AT YOUR OWN RISK!\n"

int32_t printFSInfo(char *filename) {
/*
      print file system information
*/

      assert(filename != NULL);

      u_int32_t FATSz, value;
      int32_t FATType, cluster;
      FILE *fd;
      struct sBootSector bs;

      printf("\t- File system information -\n");

      if ((fd=fopen(filename, "rb")) == NULL) {
            stderror();
            return -1;
      }

      // read boot sector
      if (read_bootsector(fd, &bs)) {
            myerror("Failed to read boot sector!");
            return -1;
      }

      if (bs.BS_FATSz16 != 0) {
            FATSz = SwapInt16(bs.BS_FATSz16);
      } else {
            FATSz = SwapInt32(bs.FATxx.FAT32.BS_FATSz32);
      }

      FATType = getFATType(&bs);
      if (FATType == -1) {
            myerror("Failed to get FAT type!");
            return -1;
      }

      cluster=getCountOfClusters(&bs);
      if (cluster == -1) {
            myerror("Failed to get count of cluster!");
            return -1;
      }

      printf("Device:\t\t\t\t%s\n", filename);
      fflush(stdout);
      printf("Type:\t\t\t\tFAT%u\n", getFATType(&bs));
      fflush(stdout);
      printf("Sector size:\t\t\t%u bytes\n", SwapInt16(bs.BS_BytesPerSec));
      fflush(stdout);
      printf("FAT size:\t\t\t%u sectors (%u bytes)\n", FATSz, FATSz * SwapInt16(bs.BS_BytesPerSec));
      printf("Cluster size:\t\t\t%u bytes\n", bs.BS_SecPerClus * SwapInt16(bs.BS_BytesPerSec));
      printf("Cluster count:\t\t\t%u\n", cluster);
      printf("FS size:\t\t\t%.2f MiBytes\n", (float)cluster * bs.BS_SecPerClus * SwapInt16(bs.BS_BytesPerSec) / (1024.0*1024));
      if (FATType == FATTYPE_FAT32) {
            if (getFATEntry(fd, &bs, SwapInt32(bs.FATxx.FAT32.BS_RootClus), &value) == -1) {
                  myerror("Failed to get FAT enry!");
                  return -1;
            }
            printf("FAT32 root directory first cluster: 0x%x, Data offset: 0x%llx, FAT entry: 0x%x\n",
                  SwapInt32(bs.FATxx.FAT32.BS_RootClus),
                  (unsigned long long)getClusterOffset(&bs, SwapInt32(bs.FATxx.FAT32.BS_RootClus)), value);
      }

      fclose(fd);

      return 0;

}

#ifdef __WIN32__
int32_t win32_fix_filename(char *real_filename, char *filename) {
      char drive_letter = toupper(filename[0]);
      if (drive_letter >= 'A' && drive_letter <= 'Z')
      {
            strcpy(real_filename, "\\\\.\\?:");
            real_filename[4] = drive_letter;
            return 0;
      } else {
            myerror("Invalid drive letter");
            return -1;
      }
}
#endif

int main(int argc, char *argv[]) {
/*
      parse arguments and options and start sorting
*/

      // initialize rng
      srand(time(0));

      // use locale from environment
      if (setlocale(LC_ALL, "") == NULL) {
            myerror("Could not set locale!");
            return -1;
      }

      // initialize blocked signals
      init_signal_handling();
      char *filename;

      if (parse_options(argc, argv) == -1) {
            myerror("Faild to parse options!");
            return -1;
      }

      if (OPT_HELP) {
            printf(INFO_HEADER "\n\n" INFO_LICENSE INFO_USAGE);
            return 0;
      } else if (OPT_VERSION) {
            printf(INFO_HEADER "\n\n" INFO_LICENSE);
            return 0;
      } else if (optind < argc -1) {
            myerror("Too many arguments!");
            myerror("Use -h for more help.");
            return -1;
      } else if (optind == argc) {
            myerror("Device must be given!");
            myerror("Use -h for more help.");
            return -1;
      }

#ifdef __WIN32__
      char win_filename[16];
      win32_fix_filename(win_filename,argv[optind]);
      filename=win_filename;
#else
      filename=argv[optind];
#endif


      if (OPT_INFO) {
            infomsg(INFO_HEADER "\n\n");
            if (printFSInfo(filename) == -1) {
                  myerror("Failed to print file system information");
                  return -1;
            }
      } else {
            infomsg(INFO_HEADER "\n\n");
            if (sort_fs(filename) == -1) {
                  myerror("Failed to sort file system!");
                  return -1;
            }
      }

      return 0;
}

Generated by  Doxygen 1.6.0   Back to index