imported mkdosfs, added getopt.c for use with dosfsck Added: trunk/rosapps/sysutils/dosfsck/getopt.c Deleted: trunk/rosapps/sysutils/dosfsck/mkdosfs.c Added: trunk/rosapps/sysutils/mkdosfs/ Added: trunk/rosapps/sysutils/mkdosfs/.cvsignore Added: trunk/rosapps/sysutils/mkdosfs/ANNOUNCE Added: trunk/rosapps/sysutils/mkdosfs/COPYING Added: trunk/rosapps/sysutils/mkdosfs/ChangeLog Added: trunk/rosapps/sysutils/mkdosfs/Makefile Added: trunk/rosapps/sysutils/mkdosfs/README Added: trunk/rosapps/sysutils/mkdosfs/getopt.c Added: trunk/rosapps/sysutils/mkdosfs/mkdosfs-ygg-0.3b.lsm Added: trunk/rosapps/sysutils/mkdosfs/mkdosfs.8 Added: trunk/rosapps/sysutils/mkdosfs/mkdosfs.c Added: trunk/rosapps/sysutils/mkdosfs/mkdosfs.dsp Added: trunk/rosapps/sysutils/mkdosfs/mkdosfs.dsw Added: trunk/rosapps/sysutils/mkdosfs/mkdosfs.plg _____
Added: trunk/rosapps/sysutils/dosfsck/getopt.c --- trunk/rosapps/sysutils/dosfsck/getopt.c 2005-07-29 22:22:12 UTC (rev 16883) +++ trunk/rosapps/sysutils/dosfsck/getopt.c 2005-07-29 22:53:33 UTC (rev 16884) @@ -0,0 +1,63 @@
+/* + * $Id$ + * This is an unpublished work copyright (c) 1998 HELIOS Software GmbH + * 30827 Garbsen, Germany + */ + + +#include <stdio.h> +#include <string.h> +#ifdef HAS_UNISTD +# include <unistd.h> +#endif + +char *optarg; +int optind = 1; +int opterr = 1; +int optopt; +static int subopt; +static int suboptind = 1; + +int getopt(int argc, char *const argv[], const char * optstring) +{ + char *curopt; + char *p; + int cursubopt; + + if (suboptind == optind-1 && argv[suboptind][subopt] != '\0') { + curopt = (char *)argv[suboptind]; + } else { + curopt = (char *)argv[optind]; + if (curopt == NULL || curopt[0] != '-' || strcmp(curopt, "-") == 0) + return -1; + suboptind = optind; + subopt = 1; + optind++; + if (strcmp(curopt, "--") == 0) + return -1; + } + cursubopt = subopt++; + if ((p = strchr(optstring, curopt[cursubopt])) == NULL) { + optopt = curopt[cursubopt]; + if (opterr) + fprintf(stderr, "%s: illegal option -- %c\n", argv[0], optopt); + return '?'; + } + if (p[1] == ':') { + if (curopt[cursubopt+1] != '\0') { + optarg = curopt+cursubopt+1; + suboptind++; + return p[0]; + } + if (argv[optind] == NULL) { + optopt = p[0]; + if (opterr) + fprintf(stderr, "%s: option requires an argument -- %c\n", argv[0], optopt); + if (*optstring == ':') + return ':'; + return '?'; + } + optarg = argv[optind++]; + } + return p[0]; +} _____
Deleted: trunk/rosapps/sysutils/dosfsck/mkdosfs.c --- trunk/rosapps/sysutils/dosfsck/mkdosfs.c 2005-07-29 22:22:12 UTC (rev 16883) +++ trunk/rosapps/sysutils/dosfsck/mkdosfs.c 2005-07-29 22:53:33 UTC (rev 16884) @@ -1,2072 +0,0 @@
-/* - Filename: mkdosfs.c - Version: 0.3b (Yggdrasil) - Author: Dave Hudson - Started: 24th August 1994 - Last Updated: 7th May 1998 - Updated by: Roman Hodek Roman.Hodek@informatik.uni-erlangen.de - Target O/S: Linux (2.x) - - Description: Utility to allow an MS-DOS filesystem to be created - under Linux. A lot of the basic structure of this program has been - borrowed from Remy Card's "mke2fs" code. - - As far as possible the aim here is to make the "mkdosfs" command - look almost identical to the other Linux filesystem make utilties, - eg bad blocks are still specified as blocks, not sectors, but when - it comes down to it, DOS is tied to the idea of a sector (512 bytes - as a rule), and not the block. For example the boot block does not - occupy a full cluster. - - Fixes/additions May 1998 by Roman Hodek - Roman.Hodek@informatik.uni-erlangen.de: - - Atari format support - - New options -A, -S, -C - - Support for filesystems > 2GB - - FAT32 support - - Port to work under Windows NT/2K/XP Dec 2002 by - Jens-Uwe Mager jum@anubis.han.de - - Copying: Copyright 1993, 1994 David Hudson (dave@humbug.demon.co.uk) - - Portions copyright 1992, 1993 Remy Card (card@masi.ibp.fr) - and 1991 Linus Torvalds (torvalds@klaava.helsinki.fi) - - 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, 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ - - -/* Include the header files */ - -//#include "../version.h" -#define VERSION "test" -#define VERSION_DATE __DATE__ - -#ifdef _WIN32 -#define _WIN32_WINNT 0x0400 -#include <windows.h> -#include <winioctl.h> -#define __LITTLE_ENDIAN 1234 -#define __BIG_ENDIAN 4321 -#define __BYTE_ORDER __LITTLE_ENDIAN -#define inline -#define __attribute__(x) -#define BLOCK_SIZE 512 -#else -#include <linux/hdreg.h> -#include <linux/fs.h> -#include <linux/fd.h> -#include <endian.h> -#include <mntent.h> -#include <signal.h> -#include <sys/ioctl.h> -#include <unistd.h> -#endif -#include <fcntl.h> -#include <string.h> -#include <stdio.h> -#include <stdlib.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <time.h> - -#if __BYTE_ORDER == __BIG_ENDIAN - -#include <asm/byteorder.h> -#ifdef __le16_to_cpu -/* ++roman: 2.1 kernel headers define these function, they're probably more - * efficient then coding the swaps machine-independently. */ -#define CF_LE_W __le16_to_cpu -#define CF_LE_L __le32_to_cpu -#define CT_LE_W __cpu_to_le16 -#define CT_LE_L __cpu_to_le32 -#else -#define CF_LE_W(v) ((((v) & 0xff) << 8) | (((v) >> 8) & 0xff)) -#define CF_LE_L(v) (((unsigned)(v)>>24) | (((unsigned)(v)>>8)&0xff00) | \ - (((unsigned)(v)<<8)&0xff0000) | ((unsigned)(v)<<24)) -#define CT_LE_W(v) CF_LE_W(v) -#define CT_LE_L(v) CF_LE_L(v) -#endif /* defined(__le16_to_cpu) */ - -#else - -#define CF_LE_W(v) (v) -#define CF_LE_L(v) (v) -#define CT_LE_W(v) (v) -#define CT_LE_L(v) (v) - -#endif /* __BIG_ENDIAN */ - -#ifdef _WIN32 - -typedef unsigned char __u8; -typedef unsigned short __u16; -typedef unsigned int __u32; -typedef unsigned __int64 __u64; -typedef __int64 loff_t; -typedef __int64 ll_t; - -extern char *optarg; -extern int optind; -extern int opterr; -extern int optopt; -int getopt(int argc, char *const argv[], const char * optstring); - -static int is_device = 0; - -#define open WIN32open -#define close WIN32close -#define read WIN32read -#define write WIN32write -#define llseek WIN32llseek - -#define O_SHORT_LIVED _O_SHORT_LIVED -#define O_ACCMODE 3 -#define O_NONE 3 -#define O_BACKUP 0x10000 -#define O_SHARED 0x20000 - -static int WIN32open(const char *path, int oflag, ...) -{ - HANDLE fh; - DWORD desiredAccess; - DWORD shareMode; - DWORD creationDisposition; - DWORD flagsAttributes = FILE_ATTRIBUTE_NORMAL; - SECURITY_ATTRIBUTES securityAttributes; - va_list ap; - int pmode; - int trunc = FALSE; - - securityAttributes.nLength = sizeof(securityAttributes); - securityAttributes.lpSecurityDescriptor = NULL; - securityAttributes.bInheritHandle = oflag & O_NOINHERIT ? FALSE : TRUE; - switch (oflag & O_ACCMODE) { - case O_RDONLY: - desiredAccess = GENERIC_READ; - shareMode = FILE_SHARE_READ; - break; - case O_WRONLY: - desiredAccess = GENERIC_WRITE; - shareMode = 0; - break; - case O_RDWR: - desiredAccess = GENERIC_READ|GENERIC_WRITE; - shareMode = 0; - break; - case O_NONE: - desiredAccess = 0; - shareMode = FILE_SHARE_READ|FILE_SHARE_WRITE; - } - if (oflag & O_APPEND) { - desiredAccess |= FILE_APPEND_DATA|SYNCHRONIZE; - shareMode = FILE_SHARE_READ|FILE_SHARE_WRITE; - } - if (oflag & O_SHARED) - shareMode |= FILE_SHARE_READ|FILE_SHARE_WRITE; - switch (oflag & (O_CREAT|O_EXCL|O_TRUNC)) { - case 0: - case O_EXCL: - creationDisposition = OPEN_EXISTING; - break; - case O_CREAT: - creationDisposition = OPEN_ALWAYS; - break; - case O_CREAT|O_EXCL: - case O_CREAT|O_TRUNC|O_EXCL: - creationDisposition = CREATE_NEW; - break; - case O_TRUNC: - case O_TRUNC|O_EXCL: - creationDisposition = TRUNCATE_EXISTING; - break; - case O_CREAT|O_TRUNC: - creationDisposition = OPEN_ALWAYS; - trunc = TRUE; - break; - } - if (oflag & O_CREAT) { - va_start(ap, oflag); - pmode = va_arg(ap, int); - va_end(ap); - if ((pmode & 0222) == 0) - flagsAttributes |= FILE_ATTRIBUTE_READONLY; - } - if (oflag & O_TEMPORARY) { - flagsAttributes |= FILE_FLAG_DELETE_ON_CLOSE; - desiredAccess |= DELETE; - } - if (oflag & O_SHORT_LIVED) - flagsAttributes |= FILE_ATTRIBUTE_TEMPORARY; - if (oflag & O_SEQUENTIAL) - flagsAttributes |= FILE_FLAG_SEQUENTIAL_SCAN; - else if (oflag & O_RANDOM) - flagsAttributes |= FILE_FLAG_RANDOM_ACCESS; - if (oflag & O_BACKUP) - flagsAttributes |= FILE_FLAG_BACKUP_SEMANTICS; - if ((fh = CreateFile(path, desiredAccess, shareMode, &securityAttributes, - creationDisposition, flagsAttributes, NULL)) == INVALID_HANDLE_VALUE) { - errno = GetLastError(); - return -1; - } - if (trunc) { - if (!SetEndOfFile(fh)) { - errno = GetLastError(); - CloseHandle(fh); - DeleteFile(path); - return -1; - } - } - return (int)fh; -} - -static int WIN32close(int fd) -{ - if (!CloseHandle((HANDLE)fd)) { - errno = GetLastError(); - return -1; - } - return 0; -} - -static int WIN32read(int fd, void *buf, unsigned int len) -{ - DWORD actualLen; - - if (!ReadFile((HANDLE)fd, buf, (DWORD)len, &actualLen, NULL)) { - errno = GetLastError(); - if (errno == ERROR_BROKEN_PIPE) - return 0; - else - return -1; - } - return (int)actualLen; -} - -static int WIN32write(int fd, void *buf, unsigned int len) -{ - DWORD actualLen; - - if (!WriteFile((HANDLE)fd, buf, (DWORD)len, &actualLen, NULL)) { - errno = GetLastError(); - return -1; - } - return (int)actualLen; -} - -static loff_t WIN32llseek(int fd, loff_t offset, int whence) -{ - long lo, hi; - DWORD err; - - lo = offset & 0xffffffff; - hi = offset >> 32; - lo = SetFilePointer((HANDLE)fd, lo, &hi, whence); - if (lo == 0xFFFFFFFF && (err = GetLastError()) != NO_ERROR) { - errno = err; - return -1; - } - return ((loff_t)hi << 32) | (off_t)lo; -} - -int fsctl(int fd, int code) -{ - DWORD ret; - if (!DeviceIoControl((HANDLE)fd, code, NULL, 0, NULL, 0, &ret, NULL)) { - errno = GetLastError(); - return -1; - } - return 0; -} - -#else - -#define O_NOINHERIT 0 -#define O_TEMPORARY 0 -#define O_SHORT_LIVED 0 -#define O_SEQUENTIAL 0 -#define O_RANDOM 0 -#define O_BACKUP 0 -#define O_SHARED 0 -#ifndef O_NONE -# define O_NONE 0 -#endif - -typedef long long ll_t; -/* Use the _llseek system call directly, because there (once?) was a bug in - * the glibc implementation of it. */ -#include <linux/unistd.h> -#if defined(__alpha) || defined(__ia64__) -/* On alpha, the syscall is simply lseek, because it's a 64 bit system. */ -static loff_t llseek( int fd, loff_t offset, int whence ) -{ - return lseek(fd, offset, whence); -} -#else -# ifndef __NR__llseek -# error _llseek system call not present -# endif -static _syscall5( int, _llseek, uint, fd, ulong, hi, ulong, lo, - loff_t *, res, uint, wh ); -static loff_t llseek( int fd, loff_t offset, int whence ) -{ - loff_t actual; - - if (_llseek(fd, offset>>32, offset&0xffffffff, &actual, whence) != 0) - return (loff_t)-1; - return actual; -} -#endif - -#endif - -/* Constant definitions */ - -#define TRUE 1 /* Boolean constants */ -#define FALSE 0 - -#define TEST_BUFFER_BLOCKS 16 -#define HARD_SECTOR_SIZE 512 -#define SECTORS_PER_BLOCK ( BLOCK_SIZE / HARD_SECTOR_SIZE ) - - -/* Macro definitions */ - -/* Report a failure message and return a failure error code */ - -#define die( str ) fatal_error( "%s: " str "\n" ) - - -/* Mark a cluster in the FAT as bad */ - -#define mark_sector_bad( sector ) mark_FAT_sector( sector, FAT_BAD ) - -/* Compute ceil(a/b) */ - -inline int -cdiv (int a, int b) -{ - return (a + b - 1) / b; -} - -/* MS-DOS filesystem structures -- I included them here instead of - including linux/msdos_fs.h since that doesn't include some fields we - need */ - -#define ATTR_RO 1 /* read-only */ -#define ATTR_HIDDEN 2 /* hidden */ -#define ATTR_SYS 4 /* system */ -#define ATTR_VOLUME 8 /* volume label */ -#define ATTR_DIR 16 /* directory */ -#define ATTR_ARCH 32 /* archived */ - -#define ATTR_NONE 0 /* no attribute bits */ -#define ATTR_UNUSED (ATTR_VOLUME | ATTR_ARCH | ATTR_SYS | ATTR_HIDDEN) - /* attribute bits that are copied "as is" */ - -/* FAT values */ -#define FAT_EOF (atari_format ? 0x0fffffff : 0x0ffffff8) -#define FAT_BAD 0x0ffffff7 - -#define MSDOS_EXT_SIGN 0x29 /* extended boot sector signature */ -#define MSDOS_FAT12_SIGN "FAT12 " /* FAT12 filesystem signature */ -#define MSDOS_FAT16_SIGN "FAT16 " /* FAT16 filesystem signature */ -#define MSDOS_FAT32_SIGN "FAT32 " /* FAT32 filesystem signature */ - -#define BOOT_SIGN 0xAA55 /* Boot sector magic number */ - -#define MAX_CLUST_12 ((1 << 12) - 16) -#define MAX_CLUST_16 ((1 << 16) - 16) -/* M$ says the high 4 bits of a FAT32 FAT entry are reserved and don't belong - * to the cluster number. So the max. cluster# is based on 2^28 */ -#define MAX_CLUST_32 ((1 << 28) - 16) - -#define FAT12_THRESHOLD 4078 - -#define OLDGEMDOS_MAX_SECTORS 32765 -#define GEMDOS_MAX_SECTORS 65531 -#define GEMDOS_MAX_SECTOR_SIZE (16*1024) - -#define BOOTCODE_SIZE 448 -#define BOOTCODE_FAT32_SIZE 420 - -/* __attribute__ ((packed)) is used on all structures to make gcc ignore any - * alignments */ - -#ifdef _WIN32 -#pragma pack(push, 1) -#endif -struct msdos_volume_info { - __u8 drive_number; /* BIOS drive number */ - __u8 RESERVED; /* Unused */ - __u8 ext_boot_sign; /* 0x29 if fields below exist (DOS 3.3+) */ - __u8 volume_id[4]; /* Volume ID number */ - __u8 volume_label[11];/* Volume label */ - __u8 fs_type[8]; /* Typically FAT12 or FAT16 */ -} __attribute__ ((packed)); - -struct msdos_boot_sector -{ - __u8 boot_jump[3]; /* Boot strap short or near jump */ - __u8 system_id[8]; /* Name - can be used to special case - partition manager volumes */ - __u8 sector_size[2]; /* bytes per logical sector */ - __u8 cluster_size; /* sectors/cluster */ - __u16 reserved; /* reserved sectors */ - __u8 fats; /* number of FATs */ - __u8 dir_entries[2]; /* root directory entries */ - __u8 sectors[2]; /* number of sectors */ - __u8 media; /* media code (unused) */ - __u16 fat_length; /* sectors/FAT */ - __u16 secs_track; /* sectors per track */ - __u16 heads; /* number of heads */ - __u32 hidden; /* hidden sectors (unused) */ - __u32 total_sect; /* number of sectors (if sectors == 0) */ - union { - struct { - struct msdos_volume_info vi; - __u8 boot_code[BOOTCODE_SIZE]; - } __attribute__ ((packed)) _oldfat; - struct { - __u32 fat32_length; /* sectors/FAT */ - __u16 flags; /* bit 8: fat mirroring, low 4: active fat */ - __u8 version[2]; /* major, minor filesystem version */ - __u32 root_cluster; /* first cluster in root directory */ - __u16 info_sector; /* filesystem info sector */ - __u16 backup_boot; /* backup boot sector */ - __u16 reserved2[6]; /* Unused */ - struct msdos_volume_info vi; - __u8 boot_code[BOOTCODE_FAT32_SIZE]; - } __attribute__ ((packed)) _fat32; - } __attribute__ ((packed)) fstype; - __u16 boot_sign; -} __attribute__ ((packed)); -#define fat32 fstype._fat32 -#define oldfat fstype._oldfat - -struct fat32_fsinfo { - __u32 reserved1; /* Nothing as far as I can tell */ - __u32 signature; /* 0x61417272L */ - __u32 free_clusters; /* Free cluster count. -1 if unknown */ - __u32 next_cluster; /* Most recently allocated cluster. - * Unused under Linux. */ - __u32 reserved2[4]; -}; - -struct msdos_dir_entry - { - char name[8], ext[3]; /* name and extension */ - __u8 attr; /* attribute bits */ - __u8 lcase; /* Case for base and extension */ - __u8 ctime_ms; /* Creation time, milliseconds */ - __u16 ctime; /* Creation time */ - __u16 cdate; /* Creation date */ - __u16 adate; /* Last access date */ - __u16 starthi; /* high 16 bits of first cl. (FAT32) */ - __u16 time, date, start; /* time, date and first cluster */ - __u32 size; /* file size (in bytes) */ - } __attribute__ ((packed)); - -#ifdef _WIN32 -#pragma pack(pop) -#endif - -/* The "boot code" we put into the filesystem... it writes a message and - tells the user to try again */ - -char dummy_boot_jump[3] = { 0xeb, 0x3c, 0x90 }; - -char dummy_boot_jump_m68k[2] = { 0x60, 0x1c }; - -char dummy_boot_code[BOOTCODE_SIZE] = - "\x0e" /* push cs */ - "\x1f" /* pop ds */ - "\xbe\x5b\x7c" /* mov si, offset message_txt */ - /* write_msg: */ - "\xac" /* lodsb */ - "\x22\xc0" /* and al, al */ - "\x74\x0b" /* jz key_press */ - "\x56" /* push si */ - "\xb4\x0e" /* mov ah, 0eh */ - "\xbb\x07\x00" /* mov bx, 0007h */ - "\xcd\x10" /* int 10h */ - "\x5e" /* pop si */ - "\xeb\xf0" /* jmp write_msg */ - /* key_press: */ - "\x32\xe4" /* xor ah, ah */ - "\xcd\x16" /* int 16h */ - "\xcd\x19" /* int 19h */ - "\xeb\xfe" /* foo: jmp foo */ - /* message_txt: */ - - "This is not a bootable disk. Please insert a bootable floppy and\r\n" - "press any key to try again ... \r\n"; - -#define MESSAGE_OFFSET 29 /* Offset of message in above code */ - -/* Global variables - the root of all evil :-) - see these and weep! */ - -static char *program_name = "mkdosfs"; /* Name of the program */ -static char *device_name = NULL; /* Name of the device on which to create the filesystem */ -static int atari_format = 0; /* Use Atari variation of MS-DOS FS format */ -static int check = FALSE; /* Default to no readablity checking */ -static int verbose = 0; /* Default to verbose mode off */ -static long volume_id; /* Volume ID number */ -static time_t create_time; /* Creation time */ -static char volume_name[] = " "; /* Volume name */ -static int blocks; /* Number of blocks in filesystem */ -static int sector_size = 512; /* Size of a logical sector */ -static int sector_size_set = 0; /* User selected sector size */ -static int backup_boot = 0; /* Sector# of backup boot sector */ -static int reserved_sectors = 0;/* Number of reserved sectors */ -static int badblocks = 0; /* Number of bad blocks in the filesystem */ -static int nr_fats = 2; /* Default number of FATs to produce */ -static int size_fat = 0; /* Size in bits of FAT entries */ -static int size_fat_by_user = 0; /* 1 if FAT size user selected */ -static int dev = -1; /* FS block device file handle */ -static int ignore_full_disk = 0; /* Ignore warning about 'full' disk devices */ -static unsigned int currently_testing = 0; /* Block currently being tested (if autodetect bad blocks) */ -static struct msdos_boot_sector bs; /* Boot sector data */ -static int start_data_sector; /* Sector number for the start of the data area */ -static int start_data_block; /* Block number for the start of the data area */ -static unsigned char *fat; /* File allocation table */ -static unsigned char *info_sector; /* FAT32 info sector */ -static struct msdos_dir_entry *root_dir; /* Root directory */ -static int size_root_dir; /* Size of the root directory in bytes */ -static int sectors_per_cluster = 0; /* Number of sectors per disk cluster */ -static int root_dir_entries = 0; /* Number of root directory entries */ -static char *blank_sector; /* Blank sector - all zeros */ - - -/* Function prototype definitions */ - -static void fatal_error (const char *fmt_string) __attribute__((noreturn)); -static void mark_FAT_cluster (int cluster, unsigned int value); -static void mark_FAT_sector (int sector, unsigned int value); -static long do_check (char *buffer, int try, unsigned int current_block); -static void alarm_intr (int alnum); -static void check_blocks (void); -static void get_list_blocks (char *filename); -static int valid_offset (int fd, loff_t offset); -static int count_blocks (char *filename); -static void check_mount (char *device_name); -#ifdef _WIN32 -static void establish_params (void); -#else -static void establish_params (int device_num, int size); -#endif -static void setup_tables (void); -static void write_tables (void); - - -/* The function implementations */ - -/* Handle the reporting of fatal errors. Volatile to let gcc know that this doesn't return */ - -static void -fatal_error (const char *fmt_string) -{ - fprintf (stderr, fmt_string, program_name, device_name); - exit (1); /* The error exit code is 1! */ -} - - -/* Mark the specified cluster as having a particular value */ - -static void -mark_FAT_cluster (int cluster, unsigned int value) -{ - switch( size_fat ) { - case 12: - value &= 0x0fff; - if (((cluster * 3) & 0x1) == 0) - { - fat[3 * cluster / 2] = (unsigned char) (value & 0x00ff); - fat[(3 * cluster / 2) + 1] = (unsigned char) ((fat[(3 * cluster / 2) + 1] & 0x00f0) - | ((value & 0x0f00) >> 8)); - } - else - { - fat[3 * cluster / 2] = (unsigned char) ((fat[3 * cluster / 2] & 0x000f) | ((value & 0x000f) << 4)); - fat[(3 * cluster / 2) + 1] = (unsigned char) ((value & 0x0ff0)
4);
- } - break; - - case 16: - value &= 0xffff; - fat[2 * cluster] = (unsigned char) (value & 0x00ff); - fat[(2 * cluster) + 1] = (unsigned char) (value >> 8); - break; - - case 32: - value &= 0xfffffff; - fat[4 * cluster] = (unsigned char) (value & 0x000000ff); - fat[(4 * cluster) + 1] = (unsigned char) ((value & 0x0000ff00) >> 8); - fat[(4 * cluster) + 2] = (unsigned char) ((value & 0x00ff0000) >> 16); - fat[(4 * cluster) + 3] = (unsigned char) ((value & 0xff000000) >> 24); - break; - - default: - die("Bad FAT size (not 12, 16, or 32)"); - } -} - - -/* Mark a specified sector as having a particular value in it's FAT entry */ - -static void -mark_FAT_sector (int sector, unsigned int value) -{ - int cluster; - - cluster = (sector - start_data_sector) / (int) (bs.cluster_size) / - (sector_size/HARD_SECTOR_SIZE); - if (cluster < 0) - die ("Invalid cluster number in mark_FAT_sector: probably bug!"); - - mark_FAT_cluster (cluster, value); -} - - -/* Perform a test on a block. Return the number of blocks that could be read successfully */ - -static long -do_check (char *buffer, int try, unsigned int current_block) -{ - long got; - - if (llseek (dev, (loff_t)current_block * BLOCK_SIZE, SEEK_SET) /* Seek to the correct location */ - != (loff_t)current_block * BLOCK_SIZE) - die ("seek failed during testing for blocks"); - - got = read (dev, buffer, try * BLOCK_SIZE); /* Try reading! */ - if (got < 0) - got = 0; - - if (got & (BLOCK_SIZE - 1)) - printf ("Unexpected values in do_check: probably bugs\n"); - got /= BLOCK_SIZE; - - return got; -} - -#ifndef _WIN32 -/* Alarm clock handler - display the status of the quest for bad blocks! Then retrigger the alarm for five senconds - later (so we can come here again) */ - -static void -alarm_intr (int alnum) -{ - if (currently_testing >= blocks) - return; - - signal (SIGALRM, alarm_intr); - alarm (5); - if (!currently_testing) - return; - - printf ("%d... ", currently_testing); - fflush (stdout); -} -#endif - -static void -check_blocks (void) -{ - int try, got; - int i; - static char blkbuf[BLOCK_SIZE * TEST_BUFFER_BLOCKS]; - - if (verbose) - { - printf ("Searching for bad blocks "); - fflush (stdout); - } - currently_testing = 0; -#ifndef _WIN32 - if (verbose) - { - signal (SIGALRM, alarm_intr); - alarm (5); - } -#endif - try = TEST_BUFFER_BLOCKS; - while (currently_testing < blocks) - { - if (currently_testing + try > blocks) - try = blocks - currently_testing; - got = do_check (blkbuf, try, currently_testing); - currently_testing += got; - if (got == try) - { - try = TEST_BUFFER_BLOCKS; - continue; - } - else - try = 1; - if (currently_testing < start_data_block) - die ("bad blocks before data-area: cannot make fs"); - - for (i = 0; i < SECTORS_PER_BLOCK; i++) /* Mark all of the sectors in the block as bad */ - mark_sector_bad (currently_testing * SECTORS_PER_BLOCK + i); - badblocks++; - currently_testing++; - } - - if (verbose) - printf ("\n"); - - if (badblocks) - printf ("%d bad block%s\n", badblocks, - (badblocks > 1) ? "s" : ""); -} - - -static void -get_list_blocks (char *filename) -{ - int i; - FILE *listfile; - unsigned long blockno; - - listfile = fopen (filename, "r"); - if (listfile == (FILE *) NULL) - die ("Can't open file of bad blocks"); - - while (!feof (listfile)) - { - fscanf (listfile, "%ld\n", &blockno); - for (i = 0; i < SECTORS_PER_BLOCK; i++) /* Mark all of the sectors in the block as bad */ - mark_sector_bad (blockno * SECTORS_PER_BLOCK + i); - badblocks++; - } - fclose (listfile); - - if (badblocks) - printf ("%d bad block%s\n", badblocks, - (badblocks > 1) ? "s" : ""); -} - - -#ifndef _WIN32 -/* Given a file descriptor and an offset, check whether the offset is a valid offset for the file - return FALSE if it - isn't valid or TRUE if it is */ - -static int -valid_offset (int fd, loff_t offset) -{ - char ch; - - if (llseek (fd, offset, SEEK_SET) < 0) - return FALSE; - if (read (fd, &ch, 1) < 1) - return FALSE; - return TRUE; -} -#endif - - -/* Given a filename, look to see how many blocks of BLOCK_SIZE are present, returning the answer */ - -static int -count_blocks (char *filename) -{ -#ifdef _WIN32 - int fd; - DISK_GEOMETRY geom; - BY_HANDLE_FILE_INFORMATION hinfo; - DWORD ret; - loff_t len = 0; - - if ((fd = open(filename, O_RDONLY)) < 0) { - perror(filename); - exit(1); - } - /* - * This should probably use IOCTL_DISK_GET_LENGTH_INFO here, but - * this ioctl is only available in XP and up. - */ - if (is_device) { - if (!DeviceIoControl((HANDLE)fd, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, &geom, sizeof(geom), &ret, NULL)) { - errno = GetLastError(); - die("unable to get length for '%s'"); - } - len = geom.Cylinders.QuadPart*geom.TracksPerCylinder*geom.SectorsPerTrack*BLOC K_SIZE; - } else { - if (!GetFileInformationByHandle((HANDLE)fd, &hinfo)) { - errno = GetLastError(); - die("unable to get length for '%s'"); - } - len = ((loff_t)hinfo.nFileSizeHigh << 32) | (loff_t)hinfo.nFileSizeLow; - } - close(fd); - return len/BLOCK_SIZE; -#else - loff_t high, low; - int fd; - - if ((fd = open (filename, O_RDONLY)) < 0) - { - perror (filename); - exit (1); - } - low = 0; - - for (high = 1; valid_offset (fd, high); high *= 2) - low = high; - while (low < high - 1) - { - const loff_t mid = (low + high) / 2; - - if (valid_offset (fd, mid)) - low = mid; - else - high = mid; - } - valid_offset (fd, 0); - close (fd); - - return (low + 1) / BLOCK_SIZE; -#endif -} - - -/* Check to see if the specified device is currently mounted - abort if it is */ - -static void -check_mount (char *device_name) -{ -#ifndef _WIN32 - FILE *f; - struct mntent *mnt; - - if ((f = setmntent (MOUNTED, "r")) == NULL) - return; - while ((mnt = getmntent (f)) != NULL) - if (strcmp (device_name, mnt->mnt_fsname) == 0) - die ("%s contains a mounted file system."); - endmntent (f); -#endif -} - - -/* Establish the geometry and media parameters for the device */ -#ifdef _WIN32 -static void -establish_params (void) -{ - DISK_GEOMETRY geometry; - DWORD ret; - - if (!is_device) { - bs.media = (char) 0xf8; /* Set up the media descriptor for a hard drive */ - bs.dir_entries[0] = (char) 0; - bs.dir_entries[1] = (char) 2; - /* For FAT32, use 4k clusters on sufficiently large file systems, - * otherwise 1 sector per cluster. This is also what M$'s format - * command does for FAT32. */ - bs.cluster_size = (char) - (size_fat == 32 ? - ((ll_t)blocks*SECTORS_PER_BLOCK >= 512*1024 ? 8 : 1) : - 4); /* FAT12 and FAT16: start at 4 sectors per cluster */ - return; - } - if (!DeviceIoControl((HANDLE)dev, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, &geometry, sizeof(geometry), &ret, NULL)) { - errno = GetLastError(); - die ("unable to get geometry for '%s'"); - } - bs.secs_track = geometry.SectorsPerTrack; - bs.heads = geometry.TracksPerCylinder; - switch (geometry.MediaType) { - case F3_1Pt44_512: - bs.media = (char) 0xf9; - bs.cluster_size = (char) 2; - bs.dir_entries[0] = (char) 112; - bs.dir_entries[1] = (char) 0; - break; - case F3_2Pt88_512: - bs.media = (char) 0xf0; - bs.cluster_size = (char)(atari_format ? 2 : 1); - bs.dir_entries[0] = (char) 224; - bs.dir_entries[1] = (char) 0; - break; - case F3_720_512: - bs.media = (char) 0xfd; - bs.cluster_size = (char) 2; - bs.dir_entries[0] = (char) 112; - bs.dir_entries[1] = (char) 0; - break; - default: - bs.media = (char) 0xf8; /* Set up the media descriptor for a hard drive */ - bs.dir_entries[0] = (char) 0; - bs.dir_entries[1] = (char) 2; - /* For FAT32, use 4k clusters on sufficiently large file systems, - * otherwise 1 sector per cluster. This is also what M$'s format - * command does for FAT32. */ - bs.cluster_size = (char) - (size_fat == 32 ? - ((ll_t)blocks*SECTORS_PER_BLOCK >= 512*1024 ? 8 : 1) : - 4); /* FAT12 and FAT16: start at 4 sectors per cluster */ - } -} -#else -static void -establish_params (int device_num,int size) -{ [truncated at 1000 lines; 4230 more skipped]