From 2d8be9c62869c220be6426ef9f37662b4e671454 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 2 Jan 2011 15:41:44 +0100 Subject: [PATCH] Indenting source files. Signed-off-by: Daniel Baumann --- src/boot.c | 407 ++++---- src/boot.h | 5 +- src/check.c | 820 ++++++++------- src/check.h | 5 +- src/common.c | 59 +- src/common.h | 12 +- src/dosfsck.c | 206 ++-- src/dosfsck.h | 165 ++- src/dosfslabel.c | 49 +- src/fat.c | 319 +++--- src/fat.h | 25 +- src/file.c | 171 +-- src/file.h | 19 +- src/io.c | 138 +-- src/io.h | 11 +- src/lfn.c | 341 +++--- src/lfn.h | 6 +- src/mkdosfs.c | 2612 ++++++++++++++++++++++------------------------ 18 files changed, 2669 insertions(+), 2701 deletions(-) diff --git a/src/boot.c b/src/boot.c index 8848efe..35a3f8e 100644 --- a/src/boot.c +++ b/src/boot.c @@ -35,7 +35,6 @@ #include "io.h" #include "boot.h" - #define ROUND_TO_MULTIPLE(n,m) ((n) && (m) ? (n)+(m)-1-((n)-1)%(m) : 0) /* don't divide by zero */ @@ -47,17 +46,17 @@ static struct { __u8 media; char *descr; } mediabytes[] = { - { 0xf0, "5.25\" or 3.5\" HD floppy" }, - { 0xf8, "hard disk" }, - { 0xf9, "3,5\" 720k floppy 2s/80tr/9sec or " - "5.25\" 1.2M floppy 2s/80tr/15sec" }, - { 0xfa, "5.25\" 320k floppy 1s/80tr/8sec" }, - { 0xfb, "3.5\" 640k floppy 2s/80tr/8sec" }, - { 0xfc, "5.25\" 180k floppy 1s/40tr/9sec" }, - { 0xfd, "5.25\" 360k floppy 2s/40tr/9sec" }, - { 0xfe, "5.25\" 160k floppy 1s/40tr/8sec" }, - { 0xff, "5.25\" 320k floppy 2s/40tr/8sec" }, -}; + { + 0xf0, "5.25\" or 3.5\" HD floppy"}, { + 0xf8, "hard disk"}, { + 0xf9, "3,5\" 720k floppy 2s/80tr/9sec or " + "5.25\" 1.2M floppy 2s/80tr/15sec"}, { + 0xfa, "5.25\" 320k floppy 1s/80tr/8sec"}, { + 0xfb, "3.5\" 640k floppy 2s/80tr/8sec"}, { + 0xfc, "5.25\" 180k floppy 1s/40tr/9sec"}, { + 0xfd, "5.25\" 360k floppy 2s/40tr/9sec"}, { + 0xfe, "5.25\" 160k floppy 1s/40tr/8sec"}, { +0xff, "5.25\" 320k floppy 2s/40tr/8sec"},}; #if defined __alpha || defined __arm || defined __arm__ || defined __ia64__ || defined __x86_64__ \ || defined __ppc64__ || defined __bfin__ || defined __MICROBLAZE__ @@ -72,87 +71,84 @@ static struct { #define GET_UNALIGNED_W(f) CF_LE_W( *(unsigned short *)&f ) #endif - -static char *get_media_descr( unsigned char media ) +static char *get_media_descr(unsigned char media) { int i; - for( i = 0; i < sizeof(mediabytes)/sizeof(*mediabytes); ++i ) { + for (i = 0; i < sizeof(mediabytes) / sizeof(*mediabytes); ++i) { if (mediabytes[i].media == media) - return( mediabytes[i].descr ); + return (mediabytes[i].descr); } - return( "undefined" ); + return ("undefined"); } -static void dump_boot(DOS_FS *fs,struct boot_sector *b,unsigned lss) +static void dump_boot(DOS_FS * fs, struct boot_sector *b, unsigned lss) { unsigned short sectors; printf("Boot sector contents:\n"); if (!atari_format) { char id[9]; - strncpy(id,b->system_id,8); + strncpy(id, b->system_id, 8); id[8] = 0; - printf("System ID \"%s\"\n",id); - } - else { + printf("System ID \"%s\"\n", id); + } else { /* On Atari, a 24 bit serial number is stored at offset 8 of the boot * sector */ printf("Serial number 0x%x\n", - b->system_id[5] | (b->system_id[6]<<8) | (b->system_id[7]<<16)); + b->system_id[5] | (b->system_id[6] << 8) | (b-> + system_id[7] << 16)); } - printf("Media byte 0x%02x (%s)\n",b->media,get_media_descr(b->media)); - printf("%10d bytes per logical sector\n",GET_UNALIGNED_W(b->sector_size)); - printf("%10d bytes per cluster\n",fs->cluster_size); - printf("%10d reserved sector%s\n",CF_LE_W(b->reserved), + printf("Media byte 0x%02x (%s)\n", b->media, get_media_descr(b->media)); + printf("%10d bytes per logical sector\n", GET_UNALIGNED_W(b->sector_size)); + printf("%10d bytes per cluster\n", fs->cluster_size); + printf("%10d reserved sector%s\n", CF_LE_W(b->reserved), CF_LE_W(b->reserved) == 1 ? "" : "s"); printf("First FAT starts at byte %llu (sector %llu)\n", (unsigned long long)fs->fat_start, - (unsigned long long)fs->fat_start/lss); - printf("%10d FATs, %d bit entries\n",b->fats,fs->fat_bits); - printf("%10d bytes per FAT (= %u sectors)\n",fs->fat_size, - fs->fat_size/lss); + (unsigned long long)fs->fat_start / lss); + printf("%10d FATs, %d bit entries\n", b->fats, fs->fat_bits); + printf("%10d bytes per FAT (= %u sectors)\n", fs->fat_size, + fs->fat_size / lss); if (!fs->root_cluster) { printf("Root directory starts at byte %llu (sector %llu)\n", (unsigned long long)fs->root_start, - (unsigned long long)fs->root_start/lss); - printf("%10d root directory entries\n",fs->root_entries); - } - else { - printf( "Root directory start at cluster %lu (arbitrary size)\n", - fs->root_cluster); + (unsigned long long)fs->root_start / lss); + printf("%10d root directory entries\n", fs->root_entries); + } else { + printf("Root directory start at cluster %lu (arbitrary size)\n", + fs->root_cluster); } printf("Data area starts at byte %llu (sector %llu)\n", (unsigned long long)fs->data_start, - (unsigned long long)fs->data_start/lss); - printf("%10lu data clusters (%llu bytes)\n",fs->clusters, - (unsigned long long)fs->clusters*fs->cluster_size); - printf("%u sectors/track, %u heads\n",CF_LE_W(b->secs_track), + (unsigned long long)fs->data_start / lss); + printf("%10lu data clusters (%llu bytes)\n", fs->clusters, + (unsigned long long)fs->clusters * fs->cluster_size); + printf("%u sectors/track, %u heads\n", CF_LE_W(b->secs_track), CF_LE_W(b->heads)); - printf("%10u hidden sectors\n", - atari_format ? + printf("%10u hidden sectors\n", atari_format ? /* On Atari, the hidden field is only 16 bit wide and unused */ (((unsigned char *)&b->hidden)[0] | - ((unsigned char *)&b->hidden)[1] << 8) : - CF_LE_L(b->hidden)); - sectors = GET_UNALIGNED_W( b->sectors ); + ((unsigned char *)&b->hidden)[1] << 8) : CF_LE_L(b->hidden)); + sectors = GET_UNALIGNED_W(b->sectors); printf("%10u sectors total\n", sectors ? sectors : CF_LE_L(b->total_sect)); } -static void check_backup_boot(DOS_FS *fs, struct boot_sector *b, int lss) +static void check_backup_boot(DOS_FS * fs, struct boot_sector *b, int lss) { struct boot_sector b2; if (!fs->backupboot_start) { - printf( "There is no backup boot sector.\n" ); + printf("There is no backup boot sector.\n"); if (CF_LE_W(b->reserved) < 3) { - printf( "And there is no space for creating one!\n" ); + printf("And there is no space for creating one!\n"); return; } if (interactive) - printf( "1) Create one\n2) Do without a backup\n" ); - else printf( " Auto-creating backup boot block.\n" ); - if (!interactive || get_key("12","?") == '1') { + printf("1) Create one\n2) Do without a backup\n"); + else + printf(" Auto-creating backup boot block.\n"); + if (!interactive || get_key("12", "?") == '1') { int bbs; /* The usual place for the backup boot sector is sector 6. Choose * that or the last reserved sector. */ @@ -161,55 +157,56 @@ static void check_backup_boot(DOS_FS *fs, struct boot_sector *b, int lss) else { bbs = CF_LE_W(b->reserved) - 1; if (bbs == CF_LE_W(b->info_sector)) - --bbs; /* this is never 0, as we checked reserved >= 3! */ + --bbs; /* this is never 0, as we checked reserved >= 3! */ } - fs->backupboot_start = bbs*lss; + fs->backupboot_start = bbs * lss; b->backup_boot = CT_LE_W(bbs); - fs_write(fs->backupboot_start,sizeof(*b),b); - fs_write((loff_t)offsetof(struct boot_sector,backup_boot), - sizeof(b->backup_boot),&b->backup_boot); - printf( "Created backup of boot sector in sector %d\n", bbs ); + fs_write(fs->backupboot_start, sizeof(*b), b); + fs_write((loff_t) offsetof(struct boot_sector, backup_boot), + sizeof(b->backup_boot), &b->backup_boot); + printf("Created backup of boot sector in sector %d\n", bbs); + return; + } else return; - } - else return; } - fs_read(fs->backupboot_start,sizeof(b2),&b2); - if (memcmp(b,&b2,sizeof(b2)) != 0) { + fs_read(fs->backupboot_start, sizeof(b2), &b2); + if (memcmp(b, &b2, sizeof(b2)) != 0) { /* there are any differences */ __u8 *p, *q; int i, pos, first = 1; char buf[20]; - printf( "There are differences between boot sector and its backup.\n" ); - printf( "Differences: (offset:original/backup)\n " ); + printf("There are differences between boot sector and its backup.\n"); + printf("Differences: (offset:original/backup)\n "); pos = 2; - for( p = (__u8 *)b, q = (__u8 *)&b2, i = 0; i < sizeof(b2); - ++p, ++q, ++i ) { + for (p = (__u8 *) b, q = (__u8 *) & b2, i = 0; i < sizeof(b2); + ++p, ++q, ++i) { if (*p != *q) { - sprintf( buf, "%s%u:%02x/%02x", first ? "" : ", ", - (unsigned)(p-(__u8 *)b), *p, *q ); - if (pos + strlen(buf) > 78) printf( "\n " ), pos = 2; - printf( "%s", buf ); + sprintf(buf, "%s%u:%02x/%02x", first ? "" : ", ", + (unsigned)(p - (__u8 *) b), *p, *q); + if (pos + strlen(buf) > 78) + printf("\n "), pos = 2; + printf("%s", buf); pos += strlen(buf); first = 0; } } - printf( "\n" ); + printf("\n"); if (interactive) - printf( "1) Copy original to backup\n" - "2) Copy backup to original\n" - "3) No action\n" ); - else printf( " Not automatically fixing this.\n" ); - switch (interactive ? get_key("123","?") : '3') { - case '1': - fs_write(fs->backupboot_start,sizeof(*b),b); + printf("1) Copy original to backup\n" + "2) Copy backup to original\n" "3) No action\n"); + else + printf(" Not automatically fixing this.\n"); + switch (interactive ? get_key("123", "?") : '3') { + case '1': + fs_write(fs->backupboot_start, sizeof(*b), b); break; - case '2': - fs_write(0,sizeof(b2),&b2); + case '2': + fs_write(0, sizeof(b2), &b2); break; - default: + default: break; } } @@ -224,75 +221,76 @@ static void init_fsinfo(struct info_sector *i) i->boot_sign = CT_LE_W(0xaa55); } -static void read_fsinfo(DOS_FS *fs, struct boot_sector *b,int lss) +static void read_fsinfo(DOS_FS * fs, struct boot_sector *b, int lss) { struct info_sector i; if (!b->info_sector) { - printf( "No FSINFO sector\n" ); + printf("No FSINFO sector\n"); if (interactive) - printf( "1) Create one\n2) Do without FSINFO\n" ); - else printf( " Not automatically creating it.\n" ); - if (interactive && get_key("12","?") == '1') { + printf("1) Create one\n2) Do without FSINFO\n"); + else + printf(" Not automatically creating it.\n"); + if (interactive && get_key("12", "?") == '1') { /* search for a free reserved sector (not boot sector and not * backup boot sector) */ __u32 s; - for( s = 1; s < CF_LE_W(b->reserved); ++s ) - if (s != CF_LE_W(b->backup_boot)) break; + for (s = 1; s < CF_LE_W(b->reserved); ++s) + if (s != CF_LE_W(b->backup_boot)) + break; if (s > 0 && s < CF_LE_W(b->reserved)) { init_fsinfo(&i); - fs_write((loff_t)s*lss,sizeof(i),&i); + fs_write((loff_t) s * lss, sizeof(i), &i); b->info_sector = CT_LE_W(s); - fs_write((loff_t)offsetof(struct boot_sector,info_sector), - sizeof(b->info_sector),&b->info_sector); + fs_write((loff_t) offsetof(struct boot_sector, info_sector), + sizeof(b->info_sector), &b->info_sector); if (fs->backupboot_start) - fs_write(fs->backupboot_start+ - offsetof(struct boot_sector,info_sector), - sizeof(b->info_sector),&b->info_sector); - } - else { - printf( "No free reserved sector found -- " - "no space for FSINFO sector!\n" ); + fs_write(fs->backupboot_start + + offsetof(struct boot_sector, info_sector), + sizeof(b->info_sector), &b->info_sector); + } else { + printf("No free reserved sector found -- " + "no space for FSINFO sector!\n"); return; } - } - else return; + } else + return; } - fs->fsinfo_start = CF_LE_W(b->info_sector)*lss; - fs_read(fs->fsinfo_start,sizeof(i),&i); + fs->fsinfo_start = CF_LE_W(b->info_sector) * lss; + fs_read(fs->fsinfo_start, sizeof(i), &i); if (i.magic != CT_LE_L(0x41615252) || - i.signature != CT_LE_L(0x61417272) || - i.boot_sign != CT_LE_W(0xaa55)) { - printf( "FSINFO sector has bad magic number(s):\n" ); + i.signature != CT_LE_L(0x61417272) || i.boot_sign != CT_LE_W(0xaa55)) { + printf("FSINFO sector has bad magic number(s):\n"); if (i.magic != CT_LE_L(0x41615252)) - printf( " Offset %llu: 0x%08x != expected 0x%08x\n", - (unsigned long long)offsetof(struct info_sector,magic), - CF_LE_L(i.magic),0x41615252); + printf(" Offset %llu: 0x%08x != expected 0x%08x\n", + (unsigned long long)offsetof(struct info_sector, magic), + CF_LE_L(i.magic), 0x41615252); if (i.signature != CT_LE_L(0x61417272)) - printf( " Offset %llu: 0x%08x != expected 0x%08x\n", - (unsigned long long)offsetof(struct info_sector,signature), - CF_LE_L(i.signature),0x61417272); + printf(" Offset %llu: 0x%08x != expected 0x%08x\n", + (unsigned long long)offsetof(struct info_sector, signature), + CF_LE_L(i.signature), 0x61417272); if (i.boot_sign != CT_LE_W(0xaa55)) - printf( " Offset %llu: 0x%04x != expected 0x%04x\n", - (unsigned long long)offsetof(struct info_sector,boot_sign), - CF_LE_W(i.boot_sign),0xaa55); + printf(" Offset %llu: 0x%04x != expected 0x%04x\n", + (unsigned long long)offsetof(struct info_sector, boot_sign), + CF_LE_W(i.boot_sign), 0xaa55); if (interactive) - printf( "1) Correct\n2) Don't correct (FSINFO invalid then)\n" ); - else printf( " Auto-correcting it.\n" ); - if (!interactive || get_key("12","?") == '1') { + printf("1) Correct\n2) Don't correct (FSINFO invalid then)\n"); + else + printf(" Auto-correcting it.\n"); + if (!interactive || get_key("12", "?") == '1') { init_fsinfo(&i); - fs_write(fs->fsinfo_start,sizeof(i),&i); - } - else fs->fsinfo_start = 0; + fs_write(fs->fsinfo_start, sizeof(i), &i); + } else + fs->fsinfo_start = 0; } if (fs->fsinfo_start) fs->free_clusters = CF_LE_L(i.free_clusters); } -void read_boot(DOS_FS *fs) +void read_boot(DOS_FS * fs) { struct boot_sector b; unsigned total_sectors; @@ -300,41 +298,45 @@ void read_boot(DOS_FS *fs) unsigned fat_length; loff_t data_size; - fs_read(0,sizeof(b),&b); + fs_read(0, sizeof(b), &b); logical_sector_size = GET_UNALIGNED_W(b.sector_size); - if (!logical_sector_size) die("Logical sector size is zero."); + if (!logical_sector_size) + die("Logical sector size is zero."); /* This was moved up because it's the first thing that will fail */ /* if the platform needs special handling of unaligned multibyte accesses */ /* but such handling isn't being provided. See GET_UNALIGNED_W() above. */ - if (logical_sector_size & (SECTOR_SIZE-1)) + if (logical_sector_size & (SECTOR_SIZE - 1)) die("Logical sector size (%d bytes) is not a multiple of the physical " - "sector size.",logical_sector_size); + "sector size.", logical_sector_size); - fs->cluster_size = b.cluster_size*logical_sector_size; - if (!fs->cluster_size) die("Cluster size is zero."); + fs->cluster_size = b.cluster_size * logical_sector_size; + if (!fs->cluster_size) + die("Cluster size is zero."); if (b.fats != 2 && b.fats != 1) - die("Currently, only 1 or 2 FATs are supported, not %d.\n",b.fats); + die("Currently, only 1 or 2 FATs are supported, not %d.\n", b.fats); fs->nfats = b.fats; sectors = GET_UNALIGNED_W(b.sectors); total_sectors = sectors ? sectors : CF_LE_L(b.total_sect); - if (verbose) printf("Checking we can access the last sector of the filesystem\n"); + if (verbose) + printf("Checking we can access the last sector of the filesystem\n"); /* Can't access last odd sector anyway, so round down */ - fs_test((loff_t)((total_sectors & ~1)-1)*(loff_t)logical_sector_size, + fs_test((loff_t) ((total_sectors & ~1) - 1) * (loff_t) logical_sector_size, logical_sector_size); fat_length = CF_LE_W(b.fat_length) ? - CF_LE_W(b.fat_length) : CF_LE_L(b.fat32_length); - fs->fat_start = (loff_t)CF_LE_W(b.reserved)*logical_sector_size; - fs->root_start = ((loff_t)CF_LE_W(b.reserved)+b.fats*fat_length)* - logical_sector_size; + CF_LE_W(b.fat_length) : CF_LE_L(b.fat32_length); + fs->fat_start = (loff_t) CF_LE_W(b.reserved) * logical_sector_size; + fs->root_start = ((loff_t) CF_LE_W(b.reserved) + b.fats * fat_length) * + logical_sector_size; fs->root_entries = GET_UNALIGNED_W(b.dir_entries); - fs->data_start = fs->root_start+ROUND_TO_MULTIPLE(fs->root_entries << - MSDOS_DIR_BITS,logical_sector_size); - data_size = (loff_t)total_sectors*logical_sector_size-fs->data_start; - fs->clusters = data_size/fs->cluster_size; - fs->root_cluster = 0; /* indicates standard, pre-FAT32 root dir */ - fs->fsinfo_start = 0; /* no FSINFO structure */ - fs->free_clusters = -1; /* unknown */ + fs->data_start = fs->root_start + ROUND_TO_MULTIPLE(fs->root_entries << + MSDOS_DIR_BITS, + logical_sector_size); + data_size = (loff_t) total_sectors *logical_sector_size - fs->data_start; + fs->clusters = data_size / fs->cluster_size; + fs->root_cluster = 0; /* indicates standard, pre-FAT32 root dir */ + fs->fsinfo_start = 0; /* no FSINFO structure */ + fs->free_clusters = -1; /* unknown */ if (!b.fat_length && b.fat32_length) { fs->fat_bits = 32; fs->root_cluster = CF_LE_L(b.root_cluster); @@ -344,42 +346,39 @@ void read_boot(DOS_FS *fs) * (root_entries != 0), we handle the root dir the old way. Give a * warning, but convertig to a root dir in a cluster chain seems * to complex for now... */ - printf( "Warning: FAT32 root dir not in cluster chain! " - "Compatibility mode...\n" ); + printf("Warning: FAT32 root dir not in cluster chain! " + "Compatibility mode...\n"); else if (!fs->root_cluster && !fs->root_entries) die("No root directory!"); else if (fs->root_cluster && fs->root_entries) - printf( "Warning: FAT32 root dir is in a cluster chain, but " - "a separate root dir\n" - " area is defined. Cannot fix this easily.\n" ); + printf("Warning: FAT32 root dir is in a cluster chain, but " + "a separate root dir\n" + " area is defined. Cannot fix this easily.\n"); if (fs->clusters < FAT16_THRESHOLD) - printf("Warning: Filesystem is FAT32 according to fat_length " - "and fat32_length fields,\n" - " but has only %lu clusters, less than the required " - "minimum of %d.\n" - " This may lead to problems on some systems.\n", - fs->clusters, FAT16_THRESHOLD); + printf("Warning: Filesystem is FAT32 according to fat_length " + "and fat32_length fields,\n" + " but has only %lu clusters, less than the required " + "minimum of %d.\n" + " This may lead to problems on some systems.\n", + fs->clusters, FAT16_THRESHOLD); - fs->backupboot_start = CF_LE_W(b.backup_boot)*logical_sector_size; - check_backup_boot(fs,&b,logical_sector_size); + fs->backupboot_start = CF_LE_W(b.backup_boot) * logical_sector_size; + check_backup_boot(fs, &b, logical_sector_size); - read_fsinfo(fs,&b,logical_sector_size); - } - else if (!atari_format) { + read_fsinfo(fs, &b, logical_sector_size); + } else if (!atari_format) { /* On real MS-DOS, a 16 bit FAT is used whenever there would be too * much clusers otherwise. */ fs->fat_bits = (fs->clusters >= FAT12_THRESHOLD) ? 16 : 12; if (fs->clusters >= FAT16_THRESHOLD) - die("Too many clusters (%lu) for FAT16 filesystem.", - fs->clusters); - } - else { + die("Too many clusters (%lu) for FAT16 filesystem.", fs->clusters); + } else { /* On Atari, things are more difficult: GEMDOS always uses 12bit FATs * on floppies, and always 16 bit on harddisks. */ - fs->fat_bits = 16; /* assume 16 bit FAT for now */ + fs->fat_bits = 16; /* assume 16 bit FAT for now */ /* If more clusters than fat entries in 16-bit fat, we assume * it's a real MSDOS FS with 12-bit fat. */ - if (fs->clusters+2 > fat_length*logical_sector_size*8/16 || + if (fs->clusters + 2 > fat_length * logical_sector_size * 8 / 16 || /* if it's a floppy disk --> 12bit fat */ device_no == 2 || /* if it's a ramdisk or loopback device and has one of the usual @@ -391,68 +390,72 @@ void read_boot(DOS_FS *fs) } /* On FAT32, the high 4 bits of a FAT entry are reserved */ fs->eff_fat_bits = (fs->fat_bits == 32) ? 28 : fs->fat_bits; - fs->fat_size = fat_length*logical_sector_size; + fs->fat_size = fat_length * logical_sector_size; - fs->label = calloc(12, sizeof (__u8)); + fs->label = calloc(12, sizeof(__u8)); if (fs->fat_bits == 12 || fs->fat_bits == 16) { - struct boot_sector_16 *b16 = (struct boot_sector_16 *)&b; - if (b16->extended_sig == 0x29) - memmove(fs->label, b16->label, 11); - else - fs->label = NULL; + struct boot_sector_16 *b16 = (struct boot_sector_16 *)&b; + if (b16->extended_sig == 0x29) + memmove(fs->label, b16->label, 11); + else + fs->label = NULL; } else if (fs->fat_bits == 32) { - if (b.extended_sig == 0x29) - memmove(fs->label, &b.label, 11); - else - fs->label = NULL; + if (b.extended_sig == 0x29) + memmove(fs->label, &b.label, 11); + else + fs->label = NULL; } - if (fs->clusters > ((unsigned long long)fs->fat_size*8/fs->fat_bits)-2) + if (fs->clusters > + ((unsigned long long)fs->fat_size * 8 / fs->fat_bits) - 2) die("File system has %d clusters but only space for %d FAT entries.", - fs->clusters,((unsigned long long)fs->fat_size*8/fs->fat_bits)-2); + fs->clusters, + ((unsigned long long)fs->fat_size * 8 / fs->fat_bits) - 2); if (!fs->root_entries && !fs->root_cluster) die("Root directory has zero size."); - if (fs->root_entries & (MSDOS_DPS-1)) + if (fs->root_entries & (MSDOS_DPS - 1)) die("Root directory (%d entries) doesn't span an integral number of " - "sectors.",fs->root_entries); - if (logical_sector_size & (SECTOR_SIZE-1)) + "sectors.", fs->root_entries); + if (logical_sector_size & (SECTOR_SIZE - 1)) die("Logical sector size (%d bytes) is not a multiple of the physical " - "sector size.",logical_sector_size); -#if 0 /* linux kernel doesn't check that either */ + "sector size.", logical_sector_size); +#if 0 /* linux kernel doesn't check that either */ /* ++roman: On Atari, these two fields are often left uninitialized */ if (!atari_format && (!b.secs_track || !b.heads)) die("Invalid disk format in boot sector."); #endif - if (verbose) dump_boot(fs,&b,logical_sector_size); + if (verbose) + dump_boot(fs, &b, logical_sector_size); } -static void write_boot_label(DOS_FS *fs, char *label) +static void write_boot_label(DOS_FS * fs, char *label) { struct boot_sector b; struct boot_sector_16 *b16 = (struct boot_sector_16 *)&b; fs_read(0, sizeof(b), &b); if (fs->fat_bits == 12 || fs->fat_bits == 16) { - if (b16->extended_sig != 0x29) { - b16->extended_sig = 0x29; - b16->serial = 0; - memmove(b16->fs_type, fs->fat_bits == 12 ?"FAT12 ":"FAT16 ", 8); - } - memmove(b16->label, label, 11); + if (b16->extended_sig != 0x29) { + b16->extended_sig = 0x29; + b16->serial = 0; + memmove(b16->fs_type, fs->fat_bits == 12 ? "FAT12 " : "FAT16 ", + 8); + } + memmove(b16->label, label, 11); } else if (fs->fat_bits == 32) { - if (b.extended_sig != 0x29) { - b.extended_sig = 0x29; - b.serial = 0; - memmove(b.fs_type, "FAT32 ", 8); - } - memmove(b.label, label, 11); + if (b.extended_sig != 0x29) { + b.extended_sig = 0x29; + b.serial = 0; + memmove(b.fs_type, "FAT32 ", 8); + } + memmove(b.label, label, 11); } fs_write(0, sizeof(b), &b); if (fs->fat_bits == 32 && fs->backupboot_start) - fs_write(fs->backupboot_start, sizeof(b), &b); + fs_write(fs->backupboot_start, sizeof(b), &b); } -static loff_t find_volume_de(DOS_FS *fs, DIR_ENT *de) +static loff_t find_volume_de(DOS_FS * fs, DIR_ENT * de) { unsigned long cluster; loff_t offset; @@ -482,7 +485,7 @@ static loff_t find_volume_de(DOS_FS *fs, DIR_ENT *de) return 0; } -static void write_volume_label(DOS_FS *fs, char *label) +static void write_volume_label(DOS_FS * fs, char *label) { time_t now = time(NULL); struct tm *mtime = localtime(&now); @@ -498,17 +501,17 @@ static void write_volume_label(DOS_FS *fs, char *label) (mtime->tm_min << 5) + (mtime->tm_hour << 11))); de.date = CT_LE_W((unsigned short)(mtime->tm_mday + - ((mtime->tm_mon+1) << 5) + - ((mtime->tm_year-80) << 9))); + ((mtime->tm_mon + 1) << 5) + + ((mtime->tm_year - 80) << 9))); fs_write(offset, sizeof(DIR_ENT), &de); } -void write_label(DOS_FS *fs, char *label) +void write_label(DOS_FS * fs, char *label) { int l = strlen(label); while (l < 11) - label[l++] = ' '; + label[l++] = ' '; write_boot_label(fs, label); write_volume_label(fs, label); diff --git a/src/boot.h b/src/boot.h index eedf2b0..c9edfa3 100644 --- a/src/boot.h +++ b/src/boot.h @@ -19,12 +19,11 @@ can be found in /usr/share/common-licenses/GPL-3 file. */ - #ifndef _BOOT_H #define _BOOT_H -void read_boot(DOS_FS *fs); -void write_label(DOS_FS *fs, char *label); +void read_boot(DOS_FS * fs); +void write_label(DOS_FS * fs, char *label); /* Reads the boot sector from the currently open device and initializes *FS */ diff --git a/src/check.c b/src/check.c index d6c54c1..780d78a 100644 --- a/src/check.c +++ b/src/check.c @@ -23,7 +23,6 @@ /* FAT32, VFAT, Atari format support, and various fixes additions May 1998 * by Roman Hodek */ - #include #include #include @@ -38,7 +37,6 @@ #include "lfn.h" #include "check.h" - static DOS_FILE *root; /* get start field of a dir entry */ @@ -76,8 +74,7 @@ static DOS_FILE *root; } \ } while(0) - -loff_t alloc_rootdir_entry(DOS_FS *fs, DIR_ENT *de, const char *pattern) +loff_t alloc_rootdir_entry(DOS_FS * fs, DIR_ENT * de, const char *pattern) { static int curr_num = 0; loff_t offset; @@ -89,9 +86,9 @@ loff_t alloc_rootdir_entry(DOS_FS *fs, DIR_ENT *de, const char *pattern) loff_t offset2; clu_num = fs->root_cluster; - offset = cluster_start(fs,clu_num); + offset = cluster_start(fs, clu_num); while (clu_num > 0 && clu_num != -1) { - fs_read(offset,sizeof(DIR_ENT),&d2); + fs_read(offset, sizeof(DIR_ENT), &d2); if (IS_FREE(d2.name) && d2.attr != VFAT_LN_ATTR) { got = 1; break; @@ -100,9 +97,9 @@ loff_t alloc_rootdir_entry(DOS_FS *fs, DIR_ENT *de, const char *pattern) offset += sizeof(DIR_ENT); if ((i % fs->cluster_size) == 0) { prev = clu_num; - if ((clu_num = next_cluster(fs,clu_num)) == 0 || clu_num == -1) + if ((clu_num = next_cluster(fs, clu_num)) == 0 || clu_num == -1) break; - offset = cluster_start(fs,clu_num); + offset = cluster_start(fs, clu_num); } } if (!got) { @@ -110,77 +107,81 @@ loff_t alloc_rootdir_entry(DOS_FS *fs, DIR_ENT *de, const char *pattern) * after previous one */ if (!prev) die("Root directory has no cluster allocated!"); - for (clu_num = prev+1; clu_num != prev; clu_num++) { - FAT_ENTRY entry; + for (clu_num = prev + 1; clu_num != prev; clu_num++) { + FAT_ENTRY entry; - if (clu_num >= fs->clusters+2) clu_num = 2; - get_fat(&entry, fs->fat, clu_num, fs); + if (clu_num >= fs->clusters + 2) + clu_num = 2; + get_fat(&entry, fs->fat, clu_num, fs); if (!entry.value) break; } if (clu_num == prev) die("Root directory full and no free cluster"); - set_fat(fs,prev,clu_num); - set_fat(fs,clu_num,-1); + set_fat(fs, prev, clu_num); + set_fat(fs, clu_num, -1); set_owner(fs, clu_num, get_owner(fs, fs->root_cluster)); /* clear new cluster */ - memset( &d2, 0, sizeof(d2) ); - offset = cluster_start(fs,clu_num); - for( i = 0; i < fs->cluster_size; i += sizeof(DIR_ENT) ) - fs_write( offset+i, sizeof(d2), &d2 ); + memset(&d2, 0, sizeof(d2)); + offset = cluster_start(fs, clu_num); + for (i = 0; i < fs->cluster_size; i += sizeof(DIR_ENT)) + fs_write(offset + i, sizeof(d2), &d2); } - memset(de,0,sizeof(DIR_ENT)); + memset(de, 0, sizeof(DIR_ENT)); while (1) { char expanded[12]; sprintf(expanded, pattern, curr_num); - memcpy(de->name+4, expanded, 4); - memcpy(de->ext, expanded+4, 3); + memcpy(de->name + 4, expanded, 4); + memcpy(de->ext, expanded + 4, 3); clu_num = fs->root_cluster; i = 0; - offset2 = cluster_start(fs,clu_num); + offset2 = cluster_start(fs, clu_num); while (clu_num > 0 && clu_num != -1) { - fs_read(offset2,sizeof(DIR_ENT),&d2); + fs_read(offset2, sizeof(DIR_ENT), &d2); if (offset2 != offset && - !strncmp(d2.name,de->name,MSDOS_NAME)) + !strncmp(d2.name, de->name, MSDOS_NAME)) break; i += sizeof(DIR_ENT); offset2 += sizeof(DIR_ENT); if ((i % fs->cluster_size) == 0) { - if ((clu_num = next_cluster(fs,clu_num)) == 0 || + if ((clu_num = next_cluster(fs, clu_num)) == 0 || clu_num == -1) break; - offset2 = cluster_start(fs,clu_num); + offset2 = cluster_start(fs, clu_num); } } if (clu_num == 0 || clu_num == -1) break; - if (++curr_num >= 10000) die("Unable to create unique name"); + if (++curr_num >= 10000) + die("Unable to create unique name"); } - } - else { + } else { DIR_ENT *root; int next_free = 0, scan; - root = alloc(fs->root_entries*sizeof(DIR_ENT)); - fs_read(fs->root_start,fs->root_entries*sizeof(DIR_ENT),root); + root = alloc(fs->root_entries * sizeof(DIR_ENT)); + fs_read(fs->root_start, fs->root_entries * sizeof(DIR_ENT), root); while (next_free < fs->root_entries) if (IS_FREE(root[next_free].name) && root[next_free].attr != VFAT_LN_ATTR) break; - else next_free++; + else + next_free++; if (next_free == fs->root_entries) die("Root directory is full."); - offset = fs->root_start+next_free*sizeof(DIR_ENT); - memset(de,0,sizeof(DIR_ENT)); + offset = fs->root_start + next_free * sizeof(DIR_ENT); + memset(de, 0, sizeof(DIR_ENT)); while (1) { - sprintf(de->name,pattern,curr_num); + sprintf(de->name, pattern, curr_num); for (scan = 0; scan < fs->root_entries; scan++) if (scan != next_free && - !strncmp(root[scan].name,de->name,MSDOS_NAME)) + !strncmp(root[scan].name, de->name, MSDOS_NAME)) break; - if (scan == fs->root_entries) break; - if (++curr_num >= 10000) die("Unable to create unique name"); + if (scan == fs->root_entries) + break; + if (++curr_num >= 10000) + die("Unable to create unique name"); } free(root); } @@ -188,7 +189,6 @@ loff_t alloc_rootdir_entry(DOS_FS *fs, DIR_ENT *de, const char *pattern) return offset; } - /** * Construct a full path (starting with '/') for the specified dentry, * relative to the partition. All components are "long" names where possible. @@ -197,63 +197,64 @@ loff_t alloc_rootdir_entry(DOS_FS *fs, DIR_ENT *de, const char *pattern) * * return Pointer to static string containing file's full path */ -static char *path_name(DOS_FILE *file) +static char *path_name(DOS_FILE * file) { - static char path[PATH_MAX*2]; + static char path[PATH_MAX * 2]; - if (!file) *path = 0; /* Reached the root directory */ + if (!file) + *path = 0; /* Reached the root directory */ else { if (strlen(path_name(file->parent)) > PATH_MAX) die("Path name too long."); - if (strcmp(path,"/") != 0) strcat(path,"/"); + if (strcmp(path, "/") != 0) + strcat(path, "/"); - /* Append the long name to the path, - * or the short name if there isn't a long one - */ - strcpy(strrchr(path,0),file->lfn?file->lfn:file_name(file->dir_ent.name)); + /* Append the long name to the path, + * or the short name if there isn't a long one + */ + strcpy(strrchr(path, 0), + file->lfn ? file->lfn : file_name(file->dir_ent.name)); } return path; } - -static int day_n[] = { 0,31,59,90,120,151,181,212,243,273,304,334,0,0,0,0 }; +static int day_n[] = + { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 0, 0, 0, 0 }; /* JanFebMarApr May Jun Jul Aug Sep Oct Nov Dec */ - /* Convert a MS-DOS time/date pair to a UNIX date (seconds since 1 1 70). */ -time_t date_dos2unix(unsigned short time,unsigned short date) +time_t date_dos2unix(unsigned short time, unsigned short date) { - int month,year; + int month, year; time_t secs; - month = ((date >> 5) & 15)-1; + month = ((date >> 5) & 15) - 1; year = date >> 9; - secs = (time & 31)*2+60*((time >> 5) & 63)+(time >> 11)*3600+86400* - ((date & 31)-1+day_n[month]+(year/4)+year*365-((year & 3) == 0 && - month < 2 ? 1 : 0)+3653); - /* days since 1.1.70 plus 80's leap day */ + secs = + (time & 31) * 2 + 60 * ((time >> 5) & 63) + (time >> 11) * 3600 + + 86400 * ((date & 31) - 1 + day_n[month] + (year / 4) + year * 365 - + ((year & 3) == 0 && month < 2 ? 1 : 0) + 3653); + /* days since 1.1.70 plus 80's leap day */ return secs; } - -static char *file_stat(DOS_FILE *file) +static char *file_stat(DOS_FILE * file) { static char temp[100]; struct tm *tm; char tmp[100]; time_t date; - date = date_dos2unix(CF_LE_W(file->dir_ent.time),CF_LE_W(file-> - dir_ent.date)); + date = + date_dos2unix(CF_LE_W(file->dir_ent.time), CF_LE_W(file->dir_ent.date)); tm = localtime(&date); - strftime(tmp,99,"%H:%M:%S %b %d %Y",tm); - sprintf(temp," Size %u bytes, date %s",CF_LE_L(file->dir_ent.size),tmp); + strftime(tmp, 99, "%H:%M:%S %b %d %Y", tm); + sprintf(temp, " Size %u bytes, date %s", CF_LE_L(file->dir_ent.size), tmp); return temp; } - -static int bad_name(DOS_FILE *file) +static int bad_name(DOS_FILE * file) { int i, spc, suspicious = 0; char *bad_chars = atari_format ? "*?\\/:" : "*?<>|\"\\/:"; @@ -261,23 +262,31 @@ static int bad_name(DOS_FILE *file) /* Do not complain about (and auto-correct) the extended attribute files * of OS/2. */ - if (strncmp(name,"EA DATA SF",11) == 0 || - strncmp(name,"WP ROOT SF",11) == 0) return 0; + if (strncmp(name, "EA DATA SF", 11) == 0 || + strncmp(name, "WP ROOT SF", 11) == 0) + return 0; /* don't complain about the dummy 11 bytes used by patched Linux kernels */ - if (file->dir_ent.lcase & FAT_NO_83NAME) return 0; + if (file->dir_ent.lcase & FAT_NO_83NAME) + return 0; for (i = 0; i < 8; i++) { - if (name[i] < ' ' || name[i] == 0x7f) return 1; - if (name[i] > 0x7f) ++suspicious; - if (strchr(bad_chars,name[i])) return 1; + if (name[i] < ' ' || name[i] == 0x7f) + return 1; + if (name[i] > 0x7f) + ++suspicious; + if (strchr(bad_chars, name[i])) + return 1; } for (i = 8; i < 11; i++) { - if (name[i] < ' ' || name[i] == 0x7f) return 1; - if (name[i] > 0x7f) ++suspicious; - if (strchr(bad_chars,name[i])) return 1; + if (name[i] < ' ' || name[i] == 0x7f) + return 1; + if (name[i] > 0x7f) + ++suspicious; + if (strchr(bad_chars, name[i])) + return 1; } spc = 0; @@ -320,253 +329,277 @@ static void lfn_remove(loff_t from, loff_t to) * This is to avoid that some FAT-reading OSes (not Linux! ;) stop reading * a directory at the first zero entry... */ - memset( &empty, 0, sizeof(empty) ); + memset(&empty, 0, sizeof(empty)); empty.name[0] = DELETED_FLAG; - for( ; from < to; from += sizeof(empty) ) { - fs_write( from, sizeof(DIR_ENT), &empty ); + for (; from < to; from += sizeof(empty)) { + fs_write(from, sizeof(DIR_ENT), &empty); } } -static void drop_file(DOS_FS *fs,DOS_FILE *file) +static void drop_file(DOS_FS * fs, DOS_FILE * file) { unsigned long cluster; - MODIFY(file,name[0],DELETED_FLAG); - if (file->lfn) lfn_remove(file->lfn_offset, file->offset); - for (cluster = FSTART(file,fs); cluster > 0 && cluster < - fs->clusters+2; cluster = next_cluster(fs,cluster)) - set_owner(fs,cluster,NULL); + MODIFY(file, name[0], DELETED_FLAG); + if (file->lfn) + lfn_remove(file->lfn_offset, file->offset); + for (cluster = FSTART(file, fs); cluster > 0 && cluster < + fs->clusters + 2; cluster = next_cluster(fs, cluster)) + set_owner(fs, cluster, NULL); --n_files; } - -static void truncate_file(DOS_FS *fs,DOS_FILE *file,unsigned long clusters) +static void truncate_file(DOS_FS * fs, DOS_FILE * file, unsigned long clusters) { int deleting; - unsigned long walk,next,prev; + unsigned long walk, next, prev; - walk = FSTART(file,fs); + walk = FSTART(file, fs); prev = 0; - if ((deleting = !clusters)) MODIFY_START(file,0,fs); + if ((deleting = !clusters)) + MODIFY_START(file, 0, fs); while (walk > 0 && walk != -1) { - next = next_cluster(fs,walk); - if (deleting) set_fat(fs,walk,0); - else if ((deleting = !--clusters)) set_fat(fs,walk,-1); + next = next_cluster(fs, walk); + if (deleting) + set_fat(fs, walk, 0); + else if ((deleting = !--clusters)) + set_fat(fs, walk, -1); prev = walk; walk = next; } } - -static void auto_rename(DOS_FILE *file) +static void auto_rename(DOS_FILE * file) { - DOS_FILE *first,*walk; + DOS_FILE *first, *walk; unsigned long int number; - if (!file->offset) return; /* cannot rename FAT32 root dir */ + if (!file->offset) + return; /* cannot rename FAT32 root dir */ first = file->parent ? file->parent->first : root; number = 0; while (1) { char num[8]; sprintf(num, "%07d", number); memcpy(file->dir_ent.name, "FSCK", 4); - memcpy(file->dir_ent.name+4, num, 4); - memcpy(file->dir_ent.ext, num+4, 3); + memcpy(file->dir_ent.name + 4, num, 4); + memcpy(file->dir_ent.ext, num + 4, 3); for (walk = first; walk; walk = walk->next) - if (walk != file && !strncmp(walk->dir_ent.name,file->dir_ent. - name,MSDOS_NAME)) break; + if (walk != file + && !strncmp(walk->dir_ent.name, file->dir_ent.name, MSDOS_NAME)) + break; if (!walk) { - fs_write(file->offset,MSDOS_NAME,file->dir_ent.name); - if (file->lfn) lfn_fix_checksum(file->lfn_offset, file->offset, file->dir_ent.name); + fs_write(file->offset, MSDOS_NAME, file->dir_ent.name); + if (file->lfn) + lfn_fix_checksum(file->lfn_offset, file->offset, + file->dir_ent.name); return; } number++; if (number > 9999999) { - die("Too many files need repair."); + die("Too many files need repair."); } } die("Can't generate a unique name."); } - -static void rename_file(DOS_FILE *file) +static void rename_file(DOS_FILE * file) { unsigned char name[46]; - unsigned char *walk,*here; + unsigned char *walk, *here; if (!file->offset) { - printf( "Cannot rename FAT32 root dir\n" ); - return; /* cannot rename FAT32 root dir */ + printf("Cannot rename FAT32 root dir\n"); + return; /* cannot rename FAT32 root dir */ } while (1) { printf("New name: "); fflush(stdout); - if (fgets(name,45,stdin)) { - if ((here = strchr(name,'\n'))) *here = 0; - for (walk = strrchr(name,0); walk >= name && (*walk == ' ' || - *walk == '\t'); walk--); + if (fgets(name, 45, stdin)) { + if ((here = strchr(name, '\n'))) + *here = 0; + for (walk = strrchr(name, 0); walk >= name && (*walk == ' ' || + *walk == '\t'); + walk--) ; walk[1] = 0; - for (walk = name; *walk == ' ' || *walk == '\t'; walk++); - if (file_cvt(walk,file->dir_ent.name)) { - fs_write(file->offset,MSDOS_NAME,file->dir_ent.name); - if (file->lfn) lfn_fix_checksum(file->lfn_offset, file->offset, file->dir_ent.name); + for (walk = name; *walk == ' ' || *walk == '\t'; walk++) ; + if (file_cvt(walk, file->dir_ent.name)) { + fs_write(file->offset, MSDOS_NAME, file->dir_ent.name); + if (file->lfn) + lfn_fix_checksum(file->lfn_offset, file->offset, + file->dir_ent.name); return; } } } } - -static int handle_dot(DOS_FS *fs,DOS_FILE *file,int dots) +static int handle_dot(DOS_FS * fs, DOS_FILE * file, int dots) { char *name; - name = strncmp(file->dir_ent.name,MSDOS_DOT,MSDOS_NAME) ? ".." : "."; + name = strncmp(file->dir_ent.name, MSDOS_DOT, MSDOS_NAME) ? ".." : "."; if (!(file->dir_ent.attr & ATTR_DIR)) { - printf("%s\n Is a non-directory.\n",path_name(file)); + printf("%s\n Is a non-directory.\n", path_name(file)); if (interactive) printf("1) Drop it\n2) Auto-rename\n3) Rename\n" - "4) Convert to directory\n"); - else printf(" Auto-renaming it.\n"); - switch (interactive ? get_key("1234","?") : '2') { - case '1': - drop_file(fs,file); - return 1; - case '2': - auto_rename(file); - printf(" Renamed to %s\n",file_name(file->dir_ent.name)); - return 0; - case '3': - rename_file(file); - return 0; - case '4': - MODIFY(file,size,CT_LE_L(0)); - MODIFY(file,attr,file->dir_ent.attr | ATTR_DIR); - break; + "4) Convert to directory\n"); + else + printf(" Auto-renaming it.\n"); + switch (interactive ? get_key("1234", "?") : '2') { + case '1': + drop_file(fs, file); + return 1; + case '2': + auto_rename(file); + printf(" Renamed to %s\n", file_name(file->dir_ent.name)); + return 0; + case '3': + rename_file(file); + return 0; + case '4': + MODIFY(file, size, CT_LE_L(0)); + MODIFY(file, attr, file->dir_ent.attr | ATTR_DIR); + break; } } if (!dots) { - printf("Root contains directory \"%s\". Dropping it.\n",name); - drop_file(fs,file); + printf("Root contains directory \"%s\". Dropping it.\n", name); + drop_file(fs, file); return 1; } return 0; } - -static int check_file(DOS_FS *fs,DOS_FILE *file) +static int check_file(DOS_FS * fs, DOS_FILE * file) { DOS_FILE *owner; int restart; - unsigned long expect,curr,this,clusters,prev,walk,clusters2; + unsigned long expect, curr, this, clusters, prev, walk, clusters2; if (file->dir_ent.attr & ATTR_DIR) { if (CF_LE_L(file->dir_ent.size)) { printf("%s\n Directory has non-zero size. Fixing it.\n", - path_name(file)); - MODIFY(file,size,CT_LE_L(0)); + path_name(file)); + MODIFY(file, size, CT_LE_L(0)); } - if (file->parent && !strncmp(file->dir_ent.name,MSDOS_DOT,MSDOS_NAME)) { - expect = FSTART(file->parent,fs); - if (FSTART(file,fs) != expect) { + if (file->parent && !strncmp(file->dir_ent.name, MSDOS_DOT, MSDOS_NAME)) { + expect = FSTART(file->parent, fs); + if (FSTART(file, fs) != expect) { printf("%s\n Start (%ld) does not point to parent (%ld)\n", - path_name(file),FSTART(file,fs),expect); - MODIFY_START(file,expect,fs); + path_name(file), FSTART(file, fs), expect); + MODIFY_START(file, expect, fs); } return 0; } - if (file->parent && !strncmp(file->dir_ent.name,MSDOS_DOTDOT, - MSDOS_NAME)) { - expect = file->parent->parent ? FSTART(file->parent->parent,fs):0; + if (file->parent && !strncmp(file->dir_ent.name, MSDOS_DOTDOT, + MSDOS_NAME)) { + expect = + file->parent->parent ? FSTART(file->parent->parent, fs) : 0; if (fs->root_cluster && expect == fs->root_cluster) expect = 0; - if (FSTART(file,fs) != expect) { + if (FSTART(file, fs) != expect) { printf("%s\n Start (%lu) does not point to .. (%lu)\n", - path_name(file),FSTART(file,fs),expect); - MODIFY_START(file,expect,fs); + path_name(file), FSTART(file, fs), expect); + MODIFY_START(file, expect, fs); } return 0; } - if (FSTART(file,fs)==0){ - printf ("%s\n Start does point to root directory. Deleting dir. \n", - path_name(file)); - MODIFY(file,name[0],DELETED_FLAG); - return 0; + if (FSTART(file, fs) == 0) { + printf("%s\n Start does point to root directory. Deleting dir. \n", + path_name(file)); + MODIFY(file, name[0], DELETED_FLAG); + return 0; } } - if (FSTART(file,fs) >= fs->clusters+2) { - printf("%s\n Start cluster beyond limit (%lu > %lu). Truncating file.\n", - path_name(file),FSTART(file,fs),fs->clusters+1); + if (FSTART(file, fs) >= fs->clusters + 2) { + printf + ("%s\n Start cluster beyond limit (%lu > %lu). Truncating file.\n", + path_name(file), FSTART(file, fs), fs->clusters + 1); if (!file->offset) - die( "Bad FAT32 root directory! (bad start cluster)\n" ); - MODIFY_START(file,0,fs); + die("Bad FAT32 root directory! (bad start cluster)\n"); + MODIFY_START(file, 0, fs); } clusters = prev = 0; - for (curr = FSTART(file,fs) ? FSTART(file,fs) : - -1; curr != -1; curr = next_cluster(fs,curr)) { - FAT_ENTRY curEntry; - get_fat(&curEntry, fs->fat, curr, fs); + for (curr = FSTART(file, fs) ? FSTART(file, fs) : + -1; curr != -1; curr = next_cluster(fs, curr)) { + FAT_ENTRY curEntry; + get_fat(&curEntry, fs->fat, curr, fs); - if (!curEntry.value || bad_cluster(fs,curr)) { + if (!curEntry.value || bad_cluster(fs, curr)) { printf("%s\n Contains a %s cluster (%lu). Assuming EOF.\n", - path_name(file), curEntry.value ? "bad" : "free",curr); - if (prev) set_fat(fs,prev,-1); + path_name(file), curEntry.value ? "bad" : "free", curr); + if (prev) + set_fat(fs, prev, -1); else if (!file->offset) - die( "FAT32 root dir starts with a bad cluster!" ); - else MODIFY_START(file,0,fs); + die("FAT32 root dir starts with a bad cluster!"); + else + MODIFY_START(file, 0, fs); break; } if (!(file->dir_ent.attr & ATTR_DIR) && CF_LE_L(file->dir_ent.size) <= - (unsigned long long)clusters*fs->cluster_size) { - printf("%s\n File size is %u bytes, cluster chain length is > %llu " - "bytes.\n Truncating file to %u bytes.\n",path_name(file), - CF_LE_L(file->dir_ent.size),(unsigned long long)clusters*fs->cluster_size, - CF_LE_L(file->dir_ent.size)); - truncate_file(fs,file,clusters); + (unsigned long long)clusters * fs->cluster_size) { + printf + ("%s\n File size is %u bytes, cluster chain length is > %llu " + "bytes.\n Truncating file to %u bytes.\n", path_name(file), + CF_LE_L(file->dir_ent.size), + (unsigned long long)clusters * fs->cluster_size, + CF_LE_L(file->dir_ent.size)); + truncate_file(fs, file, clusters); break; } - if ((owner = get_owner(fs,curr))) { + if ((owner = get_owner(fs, curr))) { int do_trunc = 0; - printf("%s and\n",path_name(owner)); - printf("%s\n share clusters.\n",path_name(file)); + printf("%s and\n", path_name(owner)); + printf("%s\n share clusters.\n", path_name(file)); clusters2 = 0; - for (walk = FSTART(owner,fs); walk > 0 && walk != -1; walk = - next_cluster(fs,walk)) - if (walk == curr) break; - else clusters2++; + for (walk = FSTART(owner, fs); walk > 0 && walk != -1; walk = + next_cluster(fs, walk)) + if (walk == curr) + break; + else + clusters2++; restart = file->dir_ent.attr & ATTR_DIR; if (!owner->offset) { - printf( " Truncating second to %llu bytes because first " - "is FAT32 root dir.\n", (unsigned long long)clusters2*fs->cluster_size ); + printf(" Truncating second to %llu bytes because first " + "is FAT32 root dir.\n", + (unsigned long long)clusters2 * fs->cluster_size); do_trunc = 2; - } - else if (!file->offset) { - printf( " Truncating first to %llu bytes because second " - "is FAT32 root dir.\n", (unsigned long long)clusters*fs->cluster_size ); + } else if (!file->offset) { + printf(" Truncating first to %llu bytes because second " + "is FAT32 root dir.\n", + (unsigned long long)clusters * fs->cluster_size); do_trunc = 1; - } - else if (interactive) + } else if (interactive) printf("1) Truncate first to %llu bytes%s\n" - "2) Truncate second to %llu bytes\n",(unsigned long long)clusters*fs->cluster_size, - restart ? " and restart" : "",(unsigned long long)clusters2*fs->cluster_size); - else printf(" Truncating second to %llu bytes.\n",(unsigned long long)clusters2* - fs->cluster_size); - if (do_trunc != 2 && - (do_trunc == 1 || - (interactive && get_key("12","?") == '1'))) { + "2) Truncate second to %llu bytes\n", + (unsigned long long)clusters * fs->cluster_size, + restart ? " and restart" : "", + (unsigned long long)clusters2 * fs->cluster_size); + else + printf(" Truncating second to %llu bytes.\n", + (unsigned long long)clusters2 * fs->cluster_size); + if (do_trunc != 2 + && (do_trunc == 1 + || (interactive && get_key("12", "?") == '1'))) { prev = 0; clusters = 0; - for (this = FSTART(owner,fs); this > 0 && this != -1; this = - next_cluster(fs,this)) { + for (this = FSTART(owner, fs); this > 0 && this != -1; this = + next_cluster(fs, this)) { if (this == curr) { - if (prev) set_fat(fs,prev,-1); - else MODIFY_START(owner,0,fs); - MODIFY(owner,size,CT_LE_L((unsigned long long)clusters*fs->cluster_size)); - if (restart) return 1; + if (prev) + set_fat(fs, prev, -1); + else + MODIFY_START(owner, 0, fs); + MODIFY(owner, size, + CT_LE_L((unsigned long long)clusters * + fs->cluster_size)); + if (restart) + return 1; while (this > 0 && this != -1) { - set_owner(fs,this,NULL); - this = next_cluster(fs,this); + set_owner(fs, this, NULL); + this = next_cluster(fs, this); } this = curr; break; @@ -576,59 +609,68 @@ static int check_file(DOS_FS *fs,DOS_FILE *file) } if (this != curr) die("Internal error: didn't find cluster %d in chain" - " starting at %d",curr,FSTART(owner,fs)); - } - else { - if (prev) set_fat(fs,prev,-1); - else MODIFY_START(file,0,fs); + " starting at %d", curr, FSTART(owner, fs)); + } else { + if (prev) + set_fat(fs, prev, -1); + else + MODIFY_START(file, 0, fs); break; } } - set_owner(fs,curr,file); + set_owner(fs, curr, file); clusters++; prev = curr; } if (!(file->dir_ent.attr & ATTR_DIR) && CF_LE_L(file->dir_ent.size) > - (unsigned long long)clusters*fs->cluster_size) { - printf("%s\n File size is %u bytes, cluster chain length is %llu bytes." - "\n Truncating file to %lu bytes.\n",path_name(file),CF_LE_L(file-> - dir_ent.size),(unsigned long long)clusters*fs->cluster_size,(unsigned long long)clusters*fs->cluster_size); - MODIFY(file,size,CT_LE_L((unsigned long long)clusters*fs->cluster_size)); + (unsigned long long)clusters * fs->cluster_size) { + printf + ("%s\n File size is %u bytes, cluster chain length is %llu bytes." + "\n Truncating file to %lu bytes.\n", path_name(file), + CF_LE_L(file->dir_ent.size), + (unsigned long long)clusters * fs->cluster_size, + (unsigned long long)clusters * fs->cluster_size); + MODIFY(file, size, + CT_LE_L((unsigned long long)clusters * fs->cluster_size)); } return 0; } - -static int check_files(DOS_FS *fs,DOS_FILE *start) +static int check_files(DOS_FS * fs, DOS_FILE * start) { while (start) { - if (check_file(fs,start)) return 1; + if (check_file(fs, start)) + return 1; start = start->next; } return 0; } - -static int check_dir(DOS_FS *fs,DOS_FILE **root,int dots) +static int check_dir(DOS_FS * fs, DOS_FILE ** root, int dots) { - DOS_FILE *parent,**walk,**scan; - int dot,dotdot,skip,redo; - int good,bad; + DOS_FILE *parent, **walk, **scan; + int dot, dotdot, skip, redo; + int good, bad; - if (!*root) return 0; + if (!*root) + return 0; parent = (*root)->parent; good = bad = 0; for (walk = root; *walk; walk = &(*walk)->next) - if (bad_name(*walk)) bad++; - else good++; - if (*root && parent && good+bad > 4 && bad > good/2) { + if (bad_name(*walk)) + bad++; + else + good++; + if (*root && parent && good + bad > 4 && bad > good / 2) { printf("%s\n Has a large number of bad entries. (%d/%d)\n", - path_name(parent),bad,good+bad); - if (!dots) printf( " Not dropping root directory.\n" ); - else if (!interactive) printf(" Not dropping it in auto-mode.\n"); - else if (get_key("yn","Drop directory ? (y/n)") == 'y') { - truncate_file(fs,parent,0); - MODIFY(parent,name[0],DELETED_FLAG); + path_name(parent), bad, good + bad); + if (!dots) + printf(" Not dropping root directory.\n"); + else if (!interactive) + printf(" Not dropping it in auto-mode.\n"); + else if (get_key("yn", "Drop directory ? (y/n)") == 'y') { + truncate_file(fs, parent, 0); + MODIFY(parent, name[0], DELETED_FLAG); /* buglet: deleted directory stays in the list. */ return 1; } @@ -636,39 +678,41 @@ static int check_dir(DOS_FS *fs,DOS_FILE **root,int dots) dot = dotdot = redo = 0; walk = root; while (*walk) { - if (!strncmp((*walk)->dir_ent.name,MSDOS_DOT,MSDOS_NAME) || - !strncmp((*walk)->dir_ent.name,MSDOS_DOTDOT,MSDOS_NAME)) { - if (handle_dot(fs,*walk,dots)) { + if (!strncmp((*walk)->dir_ent.name, MSDOS_DOT, MSDOS_NAME) || + !strncmp((*walk)->dir_ent.name, MSDOS_DOTDOT, MSDOS_NAME)) { + if (handle_dot(fs, *walk, dots)) { *walk = (*walk)->next; continue; } - if (!strncmp((*walk)->dir_ent.name,MSDOS_DOT,MSDOS_NAME)) dot++; - else dotdot++; + if (!strncmp((*walk)->dir_ent.name, MSDOS_DOT, MSDOS_NAME)) + dot++; + else + dotdot++; } - if (!((*walk)->dir_ent.attr & ATTR_VOLUME) && - bad_name(*walk)) { + if (!((*walk)->dir_ent.attr & ATTR_VOLUME) && bad_name(*walk)) { puts(path_name(*walk)); - printf(" Bad short file name (%s).\n", file_name((*walk)->dir_ent.name)); + printf(" Bad short file name (%s).\n", + file_name((*walk)->dir_ent.name)); if (interactive) printf("1) Drop file\n2) Rename file\n3) Auto-rename\n" - "4) Keep it\n"); - else printf(" Auto-renaming it.\n"); - switch (interactive ? get_key("1234","?") : '3') { - case '1': - drop_file(fs,*walk); - walk = &(*walk)->next; - continue; - case '2': - rename_file(*walk); - redo = 1; - break; - case '3': - auto_rename(*walk); - printf(" Renamed to %s\n",file_name((*walk)->dir_ent. - name)); - break; - case '4': - break; + "4) Keep it\n"); + else + printf(" Auto-renaming it.\n"); + switch (interactive ? get_key("1234", "?") : '3') { + case '1': + drop_file(fs, *walk); + walk = &(*walk)->next; + continue; + case '2': + rename_file(*walk); + redo = 1; + break; + case '3': + auto_rename(*walk); + printf(" Renamed to %s\n", file_name((*walk)->dir_ent.name)); + break; + case '4': + break; } } /* don't check for duplicates of the volume label */ @@ -677,52 +721,57 @@ static int check_dir(DOS_FS *fs,DOS_FILE **root,int dots) skip = 0; while (*scan && !skip) { if (!((*scan)->dir_ent.attr & ATTR_VOLUME) && - !memcmp((*walk)->dir_ent.name,(*scan)->dir_ent.name,MSDOS_NAME)) { + !memcmp((*walk)->dir_ent.name, (*scan)->dir_ent.name, + MSDOS_NAME)) { printf("%s\n Duplicate directory entry.\n First %s\n", - path_name(*walk),file_stat(*walk)); - printf(" Second %s\n",file_stat(*scan)); + path_name(*walk), file_stat(*walk)); + printf(" Second %s\n", file_stat(*scan)); if (interactive) - printf("1) Drop first\n2) Drop second\n3) Rename first\n" - "4) Rename second\n5) Auto-rename first\n" - "6) Auto-rename second\n"); - else printf(" Auto-renaming second.\n"); - switch (interactive ? get_key("123456","?") : '6') { - case '1': - drop_file(fs,*walk); + printf + ("1) Drop first\n2) Drop second\n3) Rename first\n" + "4) Rename second\n5) Auto-rename first\n" + "6) Auto-rename second\n"); + else + printf(" Auto-renaming second.\n"); + switch (interactive ? get_key("123456", "?") : '6') { + case '1': + drop_file(fs, *walk); *walk = (*walk)->next; skip = 1; break; - case '2': - drop_file(fs,*scan); + case '2': + drop_file(fs, *scan); *scan = (*scan)->next; continue; - case '3': + case '3': rename_file(*walk); - printf(" Renamed to %s\n",path_name(*walk)); + printf(" Renamed to %s\n", path_name(*walk)); redo = 1; break; - case '4': + case '4': rename_file(*scan); - printf(" Renamed to %s\n",path_name(*walk)); + printf(" Renamed to %s\n", path_name(*walk)); redo = 1; break; - case '5': + case '5': auto_rename(*walk); - printf(" Renamed to %s\n",file_name((*walk)->dir_ent. - name)); + printf(" Renamed to %s\n", + file_name((*walk)->dir_ent.name)); break; - case '6': + case '6': auto_rename(*scan); - printf(" Renamed to %s\n",file_name((*scan)->dir_ent. - name)); + printf(" Renamed to %s\n", + file_name((*scan)->dir_ent.name)); break; } } scan = &(*scan)->next; } - if (skip) continue; + if (skip) + continue; } - if (!redo) walk = &(*walk)->next; + if (!redo) + walk = &(*walk)->next; else { walk = root; dot = dotdot = redo = 0; @@ -730,14 +779,13 @@ static int check_dir(DOS_FS *fs,DOS_FILE **root,int dots) } if (dots && !dot) printf("%s\n \".\" is missing. Can't fix this yet.\n", - path_name(parent)); + path_name(parent)); if (dots && !dotdot) printf("%s\n \"..\" is missing. Can't fix this yet.\n", - path_name(parent)); + path_name(parent)); return 0; } - /** * Check a dentry's cluster chain for bad clusters. * If requested, we verify readability and mark unreadable clusters as bad. @@ -747,95 +795,102 @@ static int check_dir(DOS_FS *fs,DOS_FILE **root,int dots) * @param[in] read_test Nonzero == verify that dentry's clusters can * be read */ -static void test_file(DOS_FS *fs,DOS_FILE *file,int read_test) +static void test_file(DOS_FS * fs, DOS_FILE * file, int read_test) { DOS_FILE *owner; - unsigned long walk,prev,clusters,next_clu; + unsigned long walk, prev, clusters, next_clu; prev = clusters = 0; - for (walk = FSTART(file,fs); walk > 0 && walk < fs->clusters+2; - walk = next_clu) { - next_clu = next_cluster(fs,walk); + for (walk = FSTART(file, fs); walk > 0 && walk < fs->clusters + 2; + walk = next_clu) { + next_clu = next_cluster(fs, walk); - /* In this stage we are checking only for a loop within our own - * cluster chain. - * Cross-linking of clusters is handled in check_file() - */ - if ((owner = get_owner(fs,walk))) { + /* In this stage we are checking only for a loop within our own + * cluster chain. + * Cross-linking of clusters is handled in check_file() + */ + if ((owner = get_owner(fs, walk))) { if (owner == file) { printf("%s\n Circular cluster chain. Truncating to %lu " - "cluster%s.\n",path_name(file),clusters,clusters == 1 ? "" : - "s"); - if (prev) set_fat(fs,prev,-1); + "cluster%s.\n", path_name(file), clusters, + clusters == 1 ? "" : "s"); + if (prev) + set_fat(fs, prev, -1); else if (!file->offset) - die( "Bad FAT32 root directory! (bad start cluster)\n" ); - else MODIFY_START(file,0,fs); + die("Bad FAT32 root directory! (bad start cluster)\n"); + else + MODIFY_START(file, 0, fs); } break; } - if (bad_cluster(fs,walk)) break; + if (bad_cluster(fs, walk)) + break; if (read_test) { - if (fs_test(cluster_start(fs,walk),fs->cluster_size)) { + if (fs_test(cluster_start(fs, walk), fs->cluster_size)) { prev = walk; clusters++; - } - else { + } else { printf("%s\n Cluster %lu (%lu) is unreadable. Skipping it.\n", - path_name(file),clusters,walk); - if (prev) set_fat(fs,prev,next_cluster(fs,walk)); - else MODIFY_START(file,next_cluster(fs,walk),fs); - set_fat(fs,walk,-2); + path_name(file), clusters, walk); + if (prev) + set_fat(fs, prev, next_cluster(fs, walk)); + else + MODIFY_START(file, next_cluster(fs, walk), fs); + set_fat(fs, walk, -2); } } - set_owner(fs,walk,file); + set_owner(fs, walk, file); } /* Revert ownership (for now) */ - for (walk = FSTART(file,fs); walk > 0 && walk < fs->clusters+2; - walk = next_cluster(fs,walk)) - if (bad_cluster(fs,walk)) break; - else if (get_owner(fs,walk) == file) set_owner(fs,walk,NULL); - else break; + for (walk = FSTART(file, fs); walk > 0 && walk < fs->clusters + 2; + walk = next_cluster(fs, walk)) + if (bad_cluster(fs, walk)) + break; + else if (get_owner(fs, walk) == file) + set_owner(fs, walk, NULL); + else + break; } - -static void undelete(DOS_FS *fs,DOS_FILE *file) +static void undelete(DOS_FS * fs, DOS_FILE * file) { - unsigned long clusters,left,prev,walk; + unsigned long clusters, left, prev, walk; - clusters = left = (CF_LE_L(file->dir_ent.size)+fs->cluster_size-1)/ - fs->cluster_size; + clusters = left = (CF_LE_L(file->dir_ent.size) + fs->cluster_size - 1) / + fs->cluster_size; prev = 0; - walk = FSTART(file,fs); + walk = FSTART(file, fs); - while (left && (walk >= 2) && (walk < fs->clusters+2)) { + while (left && (walk >= 2) && (walk < fs->clusters + 2)) { - FAT_ENTRY curEntry; - get_fat(&curEntry, fs->fat, walk, fs); + FAT_ENTRY curEntry; + get_fat(&curEntry, fs->fat, walk, fs); - if (!curEntry.value) - break; + if (!curEntry.value) + break; left--; - if (prev) set_fat(fs,prev,walk); + if (prev) + set_fat(fs, prev, walk); prev = walk; - walk++; + walk++; } - if (prev) set_fat(fs,prev,-1); - else MODIFY_START(file,0,fs); + if (prev) + set_fat(fs, prev, -1); + else + MODIFY_START(file, 0, fs); if (left) - printf("Warning: Did only undelete %lu of %lu cluster%s.\n",clusters-left, - clusters,clusters == 1 ? "" : "s"); + printf("Warning: Did only undelete %lu of %lu cluster%s.\n", + clusters - left, clusters, clusters == 1 ? "" : "s"); } - -static void new_dir( void ) +static void new_dir(void) { lfn_reset(); } - /** * Create a description for a referenced dentry and insert it in our dentry * tree. Then, go check the dentry's cluster chain for bad clusters and @@ -849,65 +904,64 @@ static void new_dir( void ) * 0 == Root directory * @param cp */ -static void add_file(DOS_FS *fs,DOS_FILE ***chain,DOS_FILE *parent, - loff_t offset,FDSC **cp) +static void add_file(DOS_FS * fs, DOS_FILE *** chain, DOS_FILE * parent, + loff_t offset, FDSC ** cp) { DOS_FILE *new; DIR_ENT de; FD_TYPE type; if (offset) - fs_read(offset,sizeof(DIR_ENT),&de); + fs_read(offset, sizeof(DIR_ENT), &de); else { - /* Construct a DIR_ENT for the root directory */ - memcpy(de.name," ",MSDOS_NAME); + /* Construct a DIR_ENT for the root directory */ + memcpy(de.name, " ", MSDOS_NAME); de.attr = ATTR_DIR; de.size = de.time = de.date = 0; de.start = CT_LE_W(fs->root_cluster & 0xffff); de.starthi = CT_LE_W((fs->root_cluster >> 16) & 0xffff); } - if ((type = file_type(cp,de.name)) != fdt_none) { + if ((type = file_type(cp, de.name)) != fdt_none) { if (type == fdt_undelete && (de.attr & ATTR_DIR)) die("Can't undelete directories."); - file_modify(cp,de.name); - fs_write(offset,1,&de); + file_modify(cp, de.name); + fs_write(offset, 1, &de); } if (IS_FREE(de.name)) { lfn_check_orphaned(); return; } if (de.attr == VFAT_LN_ATTR) { - lfn_add_slot(&de,offset); + lfn_add_slot(&de, offset); return; } - new = qalloc(&mem_queue,sizeof(DOS_FILE)); + new = qalloc(&mem_queue, sizeof(DOS_FILE)); new->lfn = lfn_get(&de, &new->lfn_offset); new->offset = offset; - memcpy(&new->dir_ent,&de,sizeof(de)); + memcpy(&new->dir_ent, &de, sizeof(de)); new->next = new->first = NULL; new->parent = parent; - if (type == fdt_undelete) undelete(fs,new); + if (type == fdt_undelete) + undelete(fs, new); **chain = new; *chain = &new->next; if (list) { - printf("Checking file %s",path_name(new)); + printf("Checking file %s", path_name(new)); if (new->lfn) - printf(" (%s)", file_name(new->dir_ent.name) ); /* (8.3) */ + printf(" (%s)", file_name(new->dir_ent.name)); /* (8.3) */ printf("\n"); } /* Don't include root directory, '.', or '..' in the total file count */ if (offset && - strncmp(de.name,MSDOS_DOT,MSDOS_NAME) != 0 && - strncmp(de.name,MSDOS_DOTDOT,MSDOS_NAME) != 0) + strncmp(de.name, MSDOS_DOT, MSDOS_NAME) != 0 && + strncmp(de.name, MSDOS_DOTDOT, MSDOS_NAME) != 0) ++n_files; - test_file(fs,new,test); /* Bad cluster check */ + test_file(fs, new, test); /* Bad cluster check */ } +static int subdirs(DOS_FS * fs, DOS_FILE * parent, FDSC ** cp); -static int subdirs(DOS_FS *fs,DOS_FILE *parent,FDSC **cp); - - -static int scan_dir(DOS_FS *fs,DOS_FILE *this,FDSC **cp) +static int scan_dir(DOS_FS * fs, DOS_FILE * this, FDSC ** cp) { DOS_FILE **chain; int i; @@ -915,23 +969,24 @@ static int scan_dir(DOS_FS *fs,DOS_FILE *this,FDSC **cp) chain = &this->first; i = 0; - clu_num = FSTART(this,fs); + clu_num = FSTART(this, fs); new_dir(); while (clu_num > 0 && clu_num != -1) { - add_file(fs,&chain,this,cluster_start(fs,clu_num)+(i % fs-> - cluster_size),cp); + add_file(fs, &chain, this, + cluster_start(fs, clu_num) + (i % fs->cluster_size), cp); i += sizeof(DIR_ENT); if (!(i % fs->cluster_size)) - if ((clu_num = next_cluster(fs,clu_num)) == 0 || clu_num == -1) + if ((clu_num = next_cluster(fs, clu_num)) == 0 || clu_num == -1) break; } lfn_check_orphaned(); - if (check_dir(fs,&this->first,this->offset)) return 0; - if (check_files(fs,this->first)) return 1; - return subdirs(fs,this,cp); + if (check_dir(fs, &this->first, this->offset)) + return 0; + if (check_files(fs, this->first)) + return 1; + return subdirs(fs, this, cp); } - /** * Recursively scan subdirectories of the specified parent directory. * @@ -942,19 +997,19 @@ static int scan_dir(DOS_FS *fs,DOS_FILE *this,FDSC **cp) * @return 0 Success * @return 1 Error */ -static int subdirs(DOS_FS *fs,DOS_FILE *parent,FDSC **cp) +static int subdirs(DOS_FS * fs, DOS_FILE * parent, FDSC ** cp) { DOS_FILE *walk; for (walk = parent ? parent->first : root; walk; walk = walk->next) if (walk->dir_ent.attr & ATTR_DIR) - if (strncmp(walk->dir_ent.name,MSDOS_DOT,MSDOS_NAME) && - strncmp(walk->dir_ent.name,MSDOS_DOTDOT,MSDOS_NAME)) - if (scan_dir(fs,walk,file_cd(cp,walk->dir_ent.name))) return 1; + if (strncmp(walk->dir_ent.name, MSDOS_DOT, MSDOS_NAME) && + strncmp(walk->dir_ent.name, MSDOS_DOTDOT, MSDOS_NAME)) + if (scan_dir(fs, walk, file_cd(cp, walk->dir_ent.name))) + return 1; return 0; } - /** * Scan all directory and file information for errors. * @@ -963,7 +1018,7 @@ static int subdirs(DOS_FS *fs,DOS_FILE *parent,FDSC **cp) * @return 0 Success * @return 1 Error */ -int scan_root(DOS_FS *fs) +int scan_root(DOS_FS * fs) { DOS_FILE **chain; int i; @@ -972,14 +1027,15 @@ int scan_root(DOS_FS *fs) chain = &root; new_dir(); if (fs->root_cluster) { - add_file(fs,&chain,NULL,0,&fp_root); - } - else { + add_file(fs, &chain, NULL, 0, &fp_root); + } else { for (i = 0; i < fs->root_entries; i++) - add_file(fs,&chain,NULL,fs->root_start+i*sizeof(DIR_ENT),&fp_root); + add_file(fs, &chain, NULL, fs->root_start + i * sizeof(DIR_ENT), + &fp_root); } lfn_check_orphaned(); - (void) check_dir(fs,&root,0); - if (check_files(fs,root)) return 1; - return subdirs(fs,NULL,&fp_root); + (void)check_dir(fs, &root, 0); + if (check_files(fs, root)) + return 1; + return subdirs(fs, NULL, &fp_root); } diff --git a/src/check.h b/src/check.h index a41bb86..277c44b 100644 --- a/src/check.h +++ b/src/check.h @@ -19,11 +19,10 @@ can be found in /usr/share/common-licenses/GPL-3 file. */ - #ifndef _CHECK_H #define _CHECK_H -loff_t alloc_rootdir_entry(DOS_FS *fs, DIR_ENT *de, const char *pattern); +loff_t alloc_rootdir_entry(DOS_FS * fs, DIR_ENT * de, const char *pattern); /* Allocate a free slot in the root directory for a new file. The file name is constructed after 'pattern', which must include a %d type format for printf @@ -31,7 +30,7 @@ loff_t alloc_rootdir_entry(DOS_FS *fs, DIR_ENT *de, const char *pattern); the 'de' structure, the rest of *de is cleared. The offset returned is to where in the filesystem the entry belongs. */ -int scan_root(DOS_FS *fs); +int scan_root(DOS_FS * fs); /* Scans the root directory and recurses into all subdirectories. See check.c for all the details. Returns a non-zero integer if the file system has to diff --git a/src/common.c b/src/common.c index 296b7a7..51605a2 100644 --- a/src/common.c +++ b/src/common.c @@ -23,7 +23,6 @@ /* FAT32, VFAT, Atari format support, and various fixes additions May 1998 * by Roman Hodek */ - #include #include #include @@ -32,48 +31,44 @@ #include "common.h" - typedef struct _link { void *data; struct _link *next; } LINK; - -void die(char *msg,...) +void die(char *msg, ...) { va_list args; - va_start(args,msg); - vfprintf(stderr,msg,args); + va_start(args, msg); + vfprintf(stderr, msg, args); va_end(args); - fprintf(stderr,"\n"); + fprintf(stderr, "\n"); exit(1); } - -void pdie(char *msg,...) +void pdie(char *msg, ...) { va_list args; - va_start(args,msg); - vfprintf(stderr,msg,args); + va_start(args, msg); + vfprintf(stderr, msg, args); va_end(args); - fprintf(stderr,":%s\n",strerror(errno)); + fprintf(stderr, ":%s\n", strerror(errno)); exit(1); } - void *alloc(int size) { void *this; - if ((this = malloc(size))) return this; + if ((this = malloc(size))) + return this; pdie("malloc"); - return NULL; /* for GCC */ + return NULL; /* for GCC */ } - -void *qalloc(void **root,int size) +void *qalloc(void **root, int size) { LINK *link; @@ -83,39 +78,41 @@ void *qalloc(void **root,int size) return link->data = alloc(size); } - void qfree(void **root) { LINK *this; while (*root) { - this = (LINK *) *root; + this = (LINK *) * root; *root = this->next; free(this->data); free(this); } } - -int min(int a,int b) +int min(int a, int b) { return a < b ? a : b; } - -char get_key(char *valid,char *prompt) +char get_key(char *valid, char *prompt) { - int ch,okay; + int ch, okay; while (1) { - if (prompt) printf("%s ",prompt); + if (prompt) + printf("%s ", prompt); fflush(stdout); - while (ch = getchar(), ch == ' ' || ch == '\t'); - if (ch == EOF) exit(1); - if (!strchr(valid,okay = ch)) okay = 0; - while (ch = getchar(), ch != '\n' && ch != EOF); - if (ch == EOF) exit(1); - if (okay) return okay; + while (ch = getchar(), ch == ' ' || ch == '\t') ; + if (ch == EOF) + exit(1); + if (!strchr(valid, okay = ch)) + okay = 0; + while (ch = getchar(), ch != '\n' && ch != EOF) ; + if (ch == EOF) + exit(1); + if (okay) + return okay; printf("Invalid input.\n"); } } diff --git a/src/common.h b/src/common.h index 99e0be1..395eabb 100644 --- a/src/common.h +++ b/src/common.h @@ -19,16 +19,16 @@ can be found in /usr/share/common-licenses/GPL-3 file. */ -# include +#include #ifndef _COMMON_H #define _COMMON_H -void die(char *msg,...) __attribute((noreturn)); +void die(char *msg, ...) __attribute((noreturn)); /* Displays a prinf-style message and terminates the program. */ -void pdie(char *msg,...) __attribute((noreturn)); +void pdie(char *msg, ...) __attribute((noreturn)); /* Like die, but appends an error message according to the state of errno. */ @@ -37,7 +37,7 @@ void *alloc(int size); /* mallocs SIZE bytes and returns a pointer to the data. Terminates the program if malloc fails. */ -void *qalloc(void **root,int size); +void *qalloc(void **root, int size); /* Like alloc, but registers the data area in a list described by ROOT. */ @@ -45,11 +45,11 @@ void qfree(void **root); /* Deallocates all qalloc'ed data areas described by ROOT. */ -int min(int a,int b); +int min(int a, int b); /* Returns the smaller integer value of a and b. */ -char get_key(char *valid,char *prompt); +char get_key(char *valid, char *prompt); /* Displays PROMPT and waits for user input. Only characters in VALID are accepted. Terminates the program on EOF. Returns the character. */ diff --git a/src/dosfsck.c b/src/dosfsck.c index 7657018..c426887 100644 --- a/src/dosfsck.c +++ b/src/dosfsck.c @@ -23,7 +23,6 @@ /* FAT32, VFAT, Atari format support, and various fixes additions May 1998 * by Roman Hodek */ - #include "version.h" #include @@ -41,69 +40,66 @@ #include "file.h" #include "check.h" - -int interactive = 0,rw = 0,list = 0,test = 0,verbose = 0,write_immed = 0; +int interactive = 0, rw = 0, list = 0, test = 0, verbose = 0, write_immed = 0; int atari_format = 0; unsigned n_files = 0; void *mem_queue = NULL; - static void usage(char *name) { - fprintf(stderr,"usage: %s [-aAflrtvVwy] [-d path -d ...] " - "[-u path -u ...]\n%15sdevice\n",name,""); - fprintf(stderr," -a automatically repair the file system\n"); - fprintf(stderr," -A toggle Atari file system format\n"); - fprintf(stderr," -d path drop that file\n"); - fprintf(stderr," -f salvage unused chains to files\n"); - fprintf(stderr," -l list path names\n"); - fprintf(stderr," -n no-op, check non-interactively without changing\n"); - fprintf(stderr," -p same as -a, for compat with other *fsck\n"); - fprintf(stderr," -r interactively repair the file system\n"); - fprintf(stderr," -t test for bad clusters\n"); - fprintf(stderr," -u path try to undelete that (non-directory) file\n"); - fprintf(stderr," -v verbose mode\n"); - fprintf(stderr," -V perform a verification pass\n"); - fprintf(stderr," -w write changes to disk immediately\n"); - fprintf(stderr," -y same as -a, for compat with other *fsck\n"); + fprintf(stderr, "usage: %s [-aAflrtvVwy] [-d path -d ...] " + "[-u path -u ...]\n%15sdevice\n", name, ""); + fprintf(stderr, " -a automatically repair the file system\n"); + fprintf(stderr, " -A toggle Atari file system format\n"); + fprintf(stderr, " -d path drop that file\n"); + fprintf(stderr, " -f salvage unused chains to files\n"); + fprintf(stderr, " -l list path names\n"); + fprintf(stderr, + " -n no-op, check non-interactively without changing\n"); + fprintf(stderr, " -p same as -a, for compat with other *fsck\n"); + fprintf(stderr, " -r interactively repair the file system\n"); + fprintf(stderr, " -t test for bad clusters\n"); + fprintf(stderr, " -u path try to undelete that (non-directory) file\n"); + fprintf(stderr, " -v verbose mode\n"); + fprintf(stderr, " -V perform a verification pass\n"); + fprintf(stderr, " -w write changes to disk immediately\n"); + fprintf(stderr, " -y same as -a, for compat with other *fsck\n"); exit(2); } - /* * ++roman: On m68k, check if this is an Atari; if yes, turn on Atari variant * of MS-DOS filesystem by default. */ -static void check_atari( void ) +static void check_atari(void) { #ifdef __mc68000__ FILE *f; char line[128], *p; - if (!(f = fopen( "/proc/hardware", "r" ))) { - perror( "/proc/hardware" ); + if (!(f = fopen("/proc/hardware", "r"))) { + perror("/proc/hardware"); return; } - while( fgets( line, sizeof(line), f ) ) { - if (strncmp( line, "Model:", 6 ) == 0) { + while (fgets(line, sizeof(line), f)) { + if (strncmp(line, "Model:", 6) == 0) { p = line + 6; - p += strspn( p, " \t" ); - if (strncmp( p, "Atari ", 6 ) == 0) + p += strspn(p, " \t"); + if (strncmp(p, "Atari ", 6) == 0) atari_format = 1; break; } } - fclose( f ); + fclose(f); #endif } - -int main(int argc,char **argv) +int main(int argc, char **argv) { DOS_FS fs; - int salvage_files,verify,c; - unsigned n_files_check=0, n_files_verify=0; + int salvage_files, verify, c; + unsigned n_files_check = 0, n_files_verify = 0; unsigned long free_clusters; memset(&fs, 0, sizeof(fs)); @@ -111,94 +107,100 @@ int main(int argc,char **argv) interactive = 1; check_atari(); - while ((c = getopt(argc,argv,"Aad:flnprtu:vVwy")) != EOF) + while ((c = getopt(argc, argv, "Aad:flnprtu:vVwy")) != EOF) switch (c) { - case 'A': /* toggle Atari format */ - atari_format = !atari_format; - break; - case 'a': - case 'p': - case 'y': - rw = 1; - interactive = 0; - salvage_files = 1; - break; - case 'd': - file_add(optarg,fdt_drop); - break; - case 'f': - salvage_files = 1; - break; - case 'l': - list = 1; - break; - case 'n': - rw = 0; - interactive = 0; - break; - case 'r': - rw = 1; - interactive = 1; - break; - case 't': - test = 1; - break; - case 'u': - file_add(optarg,fdt_undelete); - break; - case 'v': - verbose = 1; - printf("dosfsck " VERSION " (" VERSION_DATE ")\n"); - break; - case 'V': - verify = 1; - break; - case 'w': - write_immed = 1; - break; - default: - usage(argv[0]); + case 'A': /* toggle Atari format */ + atari_format = !atari_format; + break; + case 'a': + case 'p': + case 'y': + rw = 1; + interactive = 0; + salvage_files = 1; + break; + case 'd': + file_add(optarg, fdt_drop); + break; + case 'f': + salvage_files = 1; + break; + case 'l': + list = 1; + break; + case 'n': + rw = 0; + interactive = 0; + break; + case 'r': + rw = 1; + interactive = 1; + break; + case 't': + test = 1; + break; + case 'u': + file_add(optarg, fdt_undelete); + break; + case 'v': + verbose = 1; + printf("dosfsck " VERSION " (" VERSION_DATE ")\n"); + break; + case 'V': + verify = 1; + break; + case 'w': + write_immed = 1; + break; + default: + usage(argv[0]); } if ((test || write_immed) && !rw) { - fprintf(stderr,"-t and -w require -a or -r\n"); + fprintf(stderr, "-t and -w require -a or -r\n"); exit(2); } - if (optind != argc-1) usage(argv[0]); + if (optind != argc - 1) + usage(argv[0]); - printf( "dosfsck " VERSION ", " VERSION_DATE ", FAT32, LFN\n" ); - fs_open(argv[optind],rw); + printf("dosfsck " VERSION ", " VERSION_DATE ", FAT32, LFN\n"); + fs_open(argv[optind], rw); read_boot(&fs); - if (verify) printf("Starting check/repair pass.\n"); - while (read_fat(&fs), scan_root(&fs)) qfree(&mem_queue); - if (test) fix_bad(&fs); - if (salvage_files) reclaim_file(&fs); - else reclaim_free(&fs); + if (verify) + printf("Starting check/repair pass.\n"); + while (read_fat(&fs), scan_root(&fs)) + qfree(&mem_queue); + if (test) + fix_bad(&fs); + if (salvage_files) + reclaim_file(&fs); + else + reclaim_free(&fs); free_clusters = update_free(&fs); file_unused(); qfree(&mem_queue); - n_files_check = n_files; + n_files_check = n_files; if (verify) { - n_files = 0; - printf("Starting verification pass.\n"); - read_fat(&fs); - scan_root(&fs); - reclaim_free(&fs); - qfree(&mem_queue); - n_files_verify = n_files; + n_files = 0; + printf("Starting verification pass.\n"); + read_fat(&fs); + scan_root(&fs); + reclaim_free(&fs); + qfree(&mem_queue); + n_files_verify = n_files; } if (fs_changed()) { if (rw) { if (interactive) - rw = get_key("yn","Perform changes ? (y/n)") == 'y'; - else printf("Performing changes.\n"); - } - else + rw = get_key("yn", "Perform changes ? (y/n)") == 'y'; + else + printf("Performing changes.\n"); + } else printf("Leaving file system unchanged.\n"); } - printf( "%s: %u files, %lu/%lu clusters\n", argv[optind], - n_files, fs.clusters - free_clusters, fs.clusters ); + printf("%s: %u files, %lu/%lu clusters\n", argv[optind], + n_files, fs.clusters - free_clusters, fs.clusters); return fs_close(rw) ? 1 : 0; } diff --git a/src/dosfsck.h b/src/dosfsck.h index 25a15ed..31ead36 100644 --- a/src/dosfsck.h +++ b/src/dosfsck.h @@ -23,17 +23,16 @@ /* FAT32, VFAT, Atari format support, and various fixes additions May 1998 * by Roman Hodek */ - #ifndef _DOSFSCK_H #define _DOSFSCK_H #include #define _LINUX_STAT_H /* hack to avoid inclusion of */ -#define _LINUX_STRING_H_ /* hack to avoid inclusion of */ -#define _LINUX_FS_H /* hack to avoid inclusion of */ +#define _LINUX_STRING_H_ /* hack to avoid inclusion of */ +#define _LINUX_FS_H /* hack to avoid inclusion of */ -# include -# include +#include +#include #include @@ -60,95 +59,95 @@ /* ++roman: Use own definition of boot sector structure -- the kernel headers' * name for it is msdos_boot_sector in 2.0 and fat_boot_sector in 2.1 ... */ struct boot_sector { - __u8 ignored[3]; /* Boot strap short or near jump */ - __u8 system_id[8]; /* Name - can be used to special case + __u8 ignored[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) */ + __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) */ /* The following fields are only used by FAT32 */ - __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 */ - __u8 reserved2[12]; /* Unused */ + __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 */ + __u8 reserved2[12]; /* Unused */ - __u8 drive_number; /* Logical Drive Number */ - __u8 reserved3; /* Unused */ + __u8 drive_number; /* Logical Drive Number */ + __u8 reserved3; /* Unused */ - __u8 extended_sig; /* Extended Signature (0x29) */ - __u32 serial; /* Serial number */ - __u8 label[11]; /* FS label */ - __u8 fs_type[8]; /* FS Type */ + __u8 extended_sig; /* Extended Signature (0x29) */ + __u32 serial; /* Serial number */ + __u8 label[11]; /* FS label */ + __u8 fs_type[8]; /* FS Type */ /* fill up to 512 bytes */ - __u8 junk[422]; + __u8 junk[422]; } __attribute__ ((packed)); struct boot_sector_16 { - __u8 ignored[3]; /* Boot strap short or near jump */ - __u8 system_id[8]; /* Name - can be used to special case + __u8 ignored[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) */ + __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) */ - __u8 drive_number; /* Logical Drive Number */ - __u8 reserved2; /* Unused */ + __u8 drive_number; /* Logical Drive Number */ + __u8 reserved2; /* Unused */ - __u8 extended_sig; /* Extended Signature (0x29) */ - __u32 serial; /* Serial number */ - __u8 label[11]; /* FS label */ - __u8 fs_type[8]; /* FS Type */ + __u8 extended_sig; /* Extended Signature (0x29) */ + __u32 serial; /* Serial number */ + __u8 label[11]; /* FS label */ + __u8 fs_type[8]; /* FS Type */ /* fill up to 512 bytes */ - __u8 junk[450]; + __u8 junk[450]; } __attribute__ ((packed)); struct info_sector { - __u32 magic; /* Magic for info sector ('RRaA') */ - __u8 junk[0x1dc]; - __u32 reserved1; /* Nothing as far as I can tell */ - __u32 signature; /* 0x61417272 ('rrAa') */ - __u32 free_clusters; /* Free cluster count. -1 if unknown */ - __u32 next_cluster; /* Most recently allocated cluster. */ - __u32 reserved2[3]; - __u16 reserved3; - __u16 boot_sign; + __u32 magic; /* Magic for info sector ('RRaA') */ + __u8 junk[0x1dc]; + __u32 reserved1; /* Nothing as far as I can tell */ + __u32 signature; /* 0x61417272 ('rrAa') */ + __u32 free_clusters; /* Free cluster count. -1 if unknown */ + __u32 next_cluster; /* Most recently allocated cluster. */ + __u32 reserved2[3]; + __u16 reserved3; + __u16 boot_sign; }; typedef struct { - __u8 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 cluster in FAT32 */ - __u16 time,date,start;/* time, date and first cluster */ - __u32 size; /* file size (in bytes) */ + __u8 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 cluster in FAT32 */ + __u16 time, date, start; /* time, date and first cluster */ + __u32 size; /* file size (in bytes) */ } __attribute__ ((packed)) DIR_ENT; typedef struct _dos_file { @@ -156,9 +155,9 @@ typedef struct _dos_file { char *lfn; loff_t offset; loff_t lfn_offset; - struct _dos_file *parent; /* parent directory */ - struct _dos_file *next; /* next entry */ - struct _dos_file *first; /* first entry (directory only) */ + struct _dos_file *parent; /* parent directory */ + struct _dos_file *next; /* next entry */ + struct _dos_file *first; /* first entry (directory only) */ } DOS_FILE; typedef struct { @@ -169,18 +168,18 @@ typedef struct { typedef struct { int nfats; loff_t fat_start; - unsigned int fat_size; /* unit is bytes */ - unsigned int fat_bits; /* size of a FAT entry */ - unsigned int eff_fat_bits; /* # of used bits in a FAT entry */ - unsigned long root_cluster; /* 0 for old-style root dir */ + unsigned int fat_size; /* unit is bytes */ + unsigned int fat_bits; /* size of a FAT entry */ + unsigned int eff_fat_bits; /* # of used bits in a FAT entry */ + unsigned long root_cluster; /* 0 for old-style root dir */ loff_t root_start; unsigned int root_entries; loff_t data_start; unsigned int cluster_size; unsigned long clusters; - loff_t fsinfo_start; /* 0 if not present */ + loff_t fsinfo_start; /* 0 if not present */ long free_clusters; - loff_t backupboot_start; /* 0 if not present */ + loff_t backupboot_start; /* 0 if not present */ unsigned char *fat; DOS_FILE **cluster_owner; char *label; @@ -190,7 +189,7 @@ typedef struct { #define offsetof(t,e) ((int)&(((t *)0)->e)) #endif -extern int interactive,rw,list,verbose,test,write_immed; +extern int interactive, rw, list, verbose, test, write_immed; extern int atari_format; extern unsigned n_files; extern void *mem_queue; diff --git a/src/dosfslabel.c b/src/dosfslabel.c index aabde3f..05ba7e8 100644 --- a/src/dosfslabel.c +++ b/src/dosfslabel.c @@ -38,19 +38,17 @@ #include "file.h" #include "check.h" - -int interactive = 0,rw = 0,list = 0,test = 0,verbose = 0,write_immed = 0; +int interactive = 0, rw = 0, list = 0, test = 0, verbose = 0, write_immed = 0; int atari_format = 0; unsigned n_files = 0; void *mem_queue = NULL; - static void usage(int error) { FILE *f = error ? stderr : stdout; int status = error ? 1 : 0; - fprintf(f,"usage: dosfslabel device [label]\n"); + fprintf(f, "usage: dosfslabel device [label]\n"); exit(status); } @@ -58,31 +56,30 @@ static void usage(int error) * ++roman: On m68k, check if this is an Atari; if yes, turn on Atari variant * of MS-DOS filesystem by default. */ -static void check_atari( void ) +static void check_atari(void) { #ifdef __mc68000__ FILE *f; char line[128], *p; - if (!(f = fopen( "/proc/hardware", "r" ))) { - perror( "/proc/hardware" ); + if (!(f = fopen("/proc/hardware", "r"))) { + perror("/proc/hardware"); return; } - while( fgets( line, sizeof(line), f ) ) { - if (strncmp( line, "Model:", 6 ) == 0) { + while (fgets(line, sizeof(line), f)) { + if (strncmp(line, "Model:", 6) == 0) { p = line + 6; - p += strspn( p, " \t" ); - if (strncmp( p, "Atari ", 6 ) == 0) + p += strspn(p, " \t"); + if (strncmp(p, "Atari ", 6) == 0) atari_format = 1; break; } } - fclose( f ); + fclose(f); #endif } - int main(int argc, char *argv[]) { DOS_FS fs; @@ -94,31 +91,31 @@ int main(int argc, char *argv[]) check_atari(); if (argc < 2 || argc > 3) - usage(1); + usage(1); if (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")) - usage(0); + usage(0); else if (!strcmp(argv[1], "-V") || !strcmp(argv[1], "--version")) { - printf( "dosfslabel " VERSION ", " VERSION_DATE ", FAT32, LFN\n" ); - exit(0); + printf("dosfslabel " VERSION ", " VERSION_DATE ", FAT32, LFN\n"); + exit(0); } device = argv[1]; if (argc == 3) { - label = argv[2]; - if (strlen(label) > 11) { - fprintf(stderr, - "dosfslabel: labels can be no longer than 11 characters\n"); - exit(1); - } - rw = 1; + label = argv[2]; + if (strlen(label) > 11) { + fprintf(stderr, + "dosfslabel: labels can be no longer than 11 characters\n"); + exit(1); + } + rw = 1; } fs_open(device, rw); read_boot(&fs); if (!rw) { - fprintf(stdout, "%s\n", fs.label); - exit(0); + fprintf(stdout, "%s\n", fs.label); + exit(0); } write_label(&fs, label); diff --git a/src/fat.c b/src/fat.c index 329e3cd..0dd3cbd 100644 --- a/src/fat.c +++ b/src/fat.c @@ -23,7 +23,6 @@ /* FAT32, VFAT, Atari format support, and various fixes additions May 1998 * by Roman Hodek */ - #include #include #include @@ -35,7 +34,6 @@ #include "check.h" #include "fat.h" - /** * Fetch the FAT entry for a specified cluster. * @@ -44,34 +42,33 @@ * @param[in] cluster Cluster of interest * @param[in] fs Information from the FAT boot sectors (bits per FAT entry) */ -void get_fat(FAT_ENTRY *entry,void *fat,unsigned long cluster,DOS_FS *fs) +void get_fat(FAT_ENTRY * entry, void *fat, unsigned long cluster, DOS_FS * fs) { unsigned char *ptr; - switch(fs->fat_bits) { - case 12: - ptr = &((unsigned char *) fat)[cluster*3/2]; + switch (fs->fat_bits) { + case 12: + ptr = &((unsigned char *)fat)[cluster * 3 / 2]; entry->value = 0xfff & (cluster & 1 ? (ptr[0] >> 4) | (ptr[1] << 4) : - (ptr[0] | ptr[1] << 8)); + (ptr[0] | ptr[1] << 8)); break; - case 16: - entry->value = CF_LE_W(((unsigned short *) fat)[cluster]); + case 16: + entry->value = CF_LE_W(((unsigned short *)fat)[cluster]); break; - case 32: + case 32: /* According to M$, the high 4 bits of a FAT32 entry are reserved and * are not part of the cluster number. So we cut them off. */ { - unsigned long e = CF_LE_L(((unsigned int *) fat)[cluster]); + unsigned long e = CF_LE_L(((unsigned int *)fat)[cluster]); entry->value = e & 0xfffffff; entry->reserved = e >> 28; } break; - default: - die("Bad FAT entry size: %d bits.",fs->fat_bits); + default: + die("Bad FAT entry size: %d bits.", fs->fat_bits); } } - /** * Build a bookkeeping structure from the partition's FAT table. * If the partition has multiple FATs and they don't agree, try to pick a winner, @@ -80,12 +77,12 @@ void get_fat(FAT_ENTRY *entry,void *fat,unsigned long cluster,DOS_FS *fs) * * @param[inout] fs Information about the filesystem */ -void read_fat(DOS_FS *fs) +void read_fat(DOS_FS * fs) { int eff_size; unsigned long i; - void *first,*second = NULL; - int first_ok,second_ok; + void *first, *second = NULL; + int first_ok, second_ok; unsigned long total_num_clusters; /* Clean up from previous pass */ @@ -95,43 +92,42 @@ void read_fat(DOS_FS *fs) fs->cluster_owner = NULL; total_num_clusters = fs->clusters + 2UL; - eff_size = (total_num_clusters*fs->fat_bits+7)/8ULL; + eff_size = (total_num_clusters * fs->fat_bits + 7) / 8ULL; first = alloc(eff_size); - fs_read(fs->fat_start,eff_size,first); + fs_read(fs->fat_start, eff_size, first); if (fs->nfats > 1) { second = alloc(eff_size); - fs_read(fs->fat_start+fs->fat_size,eff_size,second); + fs_read(fs->fat_start + fs->fat_size, eff_size, second); } - if (second && memcmp(first,second,eff_size) != 0) { + if (second && memcmp(first, second, eff_size) != 0) { FAT_ENTRY first_media, second_media; - get_fat(&first_media,first,0,fs); - get_fat(&second_media,second,0,fs); + get_fat(&first_media, first, 0, fs); + get_fat(&second_media, second, 0, fs); first_ok = (first_media.value & FAT_EXTD(fs)) == FAT_EXTD(fs); second_ok = (second_media.value & FAT_EXTD(fs)) == FAT_EXTD(fs); if (first_ok && !second_ok) { printf("FATs differ - using first FAT.\n"); - fs_write(fs->fat_start+fs->fat_size,eff_size,first); + fs_write(fs->fat_start + fs->fat_size, eff_size, first); } if (!first_ok && second_ok) { printf("FATs differ - using second FAT.\n"); - fs_write(fs->fat_start,eff_size,second); - memcpy(first,second,eff_size); + fs_write(fs->fat_start, eff_size, second); + memcpy(first, second, eff_size); } if (first_ok && second_ok) { if (interactive) { printf("FATs differ but appear to be intact. Use which FAT ?\n" - "1) Use first FAT\n2) Use second FAT\n"); - if (get_key("12","?") == '1') { - fs_write(fs->fat_start+fs->fat_size,eff_size,first); + "1) Use first FAT\n2) Use second FAT\n"); + if (get_key("12", "?") == '1') { + fs_write(fs->fat_start + fs->fat_size, eff_size, first); } else { - fs_write(fs->fat_start,eff_size,second); - memcpy(first,second,eff_size); + fs_write(fs->fat_start, eff_size, second); + memcpy(first, second, eff_size); } - } - else { + } else { printf("FATs differ but appear to be intact. Using first " - "FAT.\n"); - fs_write(fs->fat_start+fs->fat_size,eff_size,first); + "FAT.\n"); + fs_write(fs->fat_start + fs->fat_size, eff_size, first); } } if (!first_ok && !second_ok) { @@ -140,32 +136,30 @@ void read_fat(DOS_FS *fs) } } if (second) { - free(second); + free(second); } - fs->fat = (unsigned char*) first; + fs->fat = (unsigned char *)first; fs->cluster_owner = alloc(total_num_clusters * sizeof(DOS_FILE *)); memset(fs->cluster_owner, 0, (total_num_clusters * sizeof(DOS_FILE *))); /* Truncate any cluster chains that link to something out of range */ - for (i = 2; i < fs->clusters+2; i++) { - FAT_ENTRY curEntry; - get_fat(&curEntry, fs->fat, i, fs); + for (i = 2; i < fs->clusters + 2; i++) { + FAT_ENTRY curEntry; + get_fat(&curEntry, fs->fat, i, fs); if (curEntry.value == 1) { - printf("Cluster %ld out of range (1). Setting to EOF.\n", - i-2); + printf("Cluster %ld out of range (1). Setting to EOF.\n", i - 2); set_fat(fs, i, -1); } - if (curEntry.value >= fs->clusters+2 && + if (curEntry.value >= fs->clusters + 2 && (curEntry.value < FAT_MIN_BAD(fs))) { printf("Cluster %ld out of range (%ld > %ld). Setting to EOF.\n", - i-2, curEntry.value, fs->clusters+2-1); - set_fat(fs,i,-1); + i - 2, curEntry.value, fs->clusters + 2 - 1); + set_fat(fs, i, -1); } } } - /** * Update the FAT entry for a specified cluster * (i.e., change the cluster it links to). @@ -179,7 +173,7 @@ void read_fat(DOS_FS *fs) * -1 == end-of-chain * -2 == bad cluster */ -void set_fat(DOS_FS *fs,unsigned long cluster,unsigned long new) +void set_fat(DOS_FS * fs, unsigned long cluster, unsigned long new) { unsigned char *data = NULL; int size; @@ -189,56 +183,54 @@ void set_fat(DOS_FS *fs,unsigned long cluster,unsigned long new) new = FAT_EOF(fs); else if ((long)new == -2) new = FAT_BAD(fs); - switch( fs->fat_bits ) { - case 12: - data = fs->fat + cluster*3/2; - offs = fs->fat_start+cluster*3/2; + switch (fs->fat_bits) { + case 12: + data = fs->fat + cluster * 3 / 2; + offs = fs->fat_start + cluster * 3 / 2; if (cluster & 1) { - FAT_ENTRY prevEntry; - get_fat(&prevEntry, fs->fat, cluster-1, fs); + FAT_ENTRY prevEntry; + get_fat(&prevEntry, fs->fat, cluster - 1, fs); data[0] = ((new & 0xf) << 4) | (prevEntry.value >> 8); data[1] = new >> 4; - } - else { - FAT_ENTRY subseqEntry; - get_fat(&subseqEntry, fs->fat, cluster+1, fs); + } else { + FAT_ENTRY subseqEntry; + get_fat(&subseqEntry, fs->fat, cluster + 1, fs); data[0] = new & 0xff; - data[1] = (new >> 8) | (cluster == fs->clusters-1 ? 0 : - (0xff & subseqEntry.value) << 4); + data[1] = (new >> 8) | (cluster == fs->clusters - 1 ? 0 : + (0xff & subseqEntry.value) << 4); } size = 2; break; - case 16: - data = fs->fat + cluster*2; - offs = fs->fat_start+cluster*2; - *(unsigned short *) data = CT_LE_W(new); + case 16: + data = fs->fat + cluster * 2; + offs = fs->fat_start + cluster * 2; + *(unsigned short *)data = CT_LE_W(new); size = 2; break; - case 32: - { - FAT_ENTRY curEntry; - get_fat(&curEntry, fs->fat, cluster, fs); + case 32: + { + FAT_ENTRY curEntry; + get_fat(&curEntry, fs->fat, cluster, fs); - data = fs->fat + cluster*4; - offs = fs->fat_start+cluster*4; + data = fs->fat + cluster * 4; + offs = fs->fat_start + cluster * 4; /* According to M$, the high 4 bits of a FAT32 entry are reserved and * are not part of the cluster number. So we never touch them. */ - *(unsigned long *) data = CT_LE_L( (new & 0xfffffff) | - (curEntry.reserved << 28) ); + *(unsigned long *)data = CT_LE_L((new & 0xfffffff) | + (curEntry.reserved << 28)); size = 4; - } + } break; - default: - die("Bad FAT entry size: %d bits.",fs->fat_bits); + default: + die("Bad FAT entry size: %d bits.", fs->fat_bits); } - fs_write(offs,size,data); + fs_write(offs, size, data); if (fs->nfats > 1) { - fs_write(offs+fs->fat_size,size,data); + fs_write(offs + fs->fat_size, size, data); } } - -int bad_cluster(DOS_FS *fs,unsigned long cluster) +int bad_cluster(DOS_FS * fs, unsigned long cluster) { FAT_ENTRY curEntry; get_fat(&curEntry, fs->fat, cluster, fs); @@ -246,7 +238,6 @@ int bad_cluster(DOS_FS *fs,unsigned long cluster) return FAT_IS_BAD(fs, curEntry.value); } - /** * Get the cluster to which the specified cluster is linked. * If the linked cluster is marked bad, abort. @@ -257,7 +248,7 @@ int bad_cluster(DOS_FS *fs,unsigned long cluster) * @return -1 'cluster' is at the end of the chain * @return Other values Next cluster in this chain */ -unsigned long next_cluster(DOS_FS *fs,unsigned long cluster) +unsigned long next_cluster(DOS_FS * fs, unsigned long cluster) { unsigned long value; FAT_ENTRY curEntry; @@ -265,18 +256,17 @@ unsigned long next_cluster(DOS_FS *fs,unsigned long cluster) get_fat(&curEntry, fs->fat, cluster, fs); value = curEntry.value; - if (FAT_IS_BAD(fs,value)) + if (FAT_IS_BAD(fs, value)) die("Internal error: next_cluster on bad cluster"); - return FAT_IS_EOF(fs,value) ? -1 : value; + return FAT_IS_EOF(fs, value) ? -1 : value; } - -loff_t cluster_start(DOS_FS *fs,unsigned long cluster) +loff_t cluster_start(DOS_FS * fs, unsigned long cluster) { - return fs->data_start+((loff_t)cluster-2)*(unsigned long long)fs->cluster_size; + return fs->data_start + ((loff_t) cluster - + 2) * (unsigned long long)fs->cluster_size; } - /** * Update internal bookkeeping to show that the specified cluster belongs * to the specified dentry. @@ -286,46 +276,44 @@ loff_t cluster_start(DOS_FS *fs,unsigned long cluster) * @param[in] owner Information on dentry that owns this cluster * (may be NULL) */ -void set_owner(DOS_FS *fs,unsigned long cluster,DOS_FILE *owner) +void set_owner(DOS_FS * fs, unsigned long cluster, DOS_FILE * owner) { if (fs->cluster_owner == NULL) die("Internal error: attempt to set owner in non-existent table"); - if (owner && fs->cluster_owner[cluster] && (fs->cluster_owner[cluster] != owner)) + if (owner && fs->cluster_owner[cluster] + && (fs->cluster_owner[cluster] != owner)) die("Internal error: attempt to change file owner"); fs->cluster_owner[cluster] = owner; } - -DOS_FILE *get_owner(DOS_FS *fs,unsigned long cluster) +DOS_FILE *get_owner(DOS_FS * fs, unsigned long cluster) { if (fs->cluster_owner == NULL) - return NULL; + return NULL; else - return fs->cluster_owner[cluster]; + return fs->cluster_owner[cluster]; } - -void fix_bad(DOS_FS *fs) +void fix_bad(DOS_FS * fs) { unsigned long i; if (verbose) printf("Checking for bad clusters.\n"); - for (i = 2; i < fs->clusters+2; i++) { - FAT_ENTRY curEntry; - get_fat(&curEntry, fs->fat, i, fs); + for (i = 2; i < fs->clusters + 2; i++) { + FAT_ENTRY curEntry; + get_fat(&curEntry, fs->fat, i, fs); - if (!get_owner(fs,i) && !FAT_IS_BAD(fs, curEntry.value)) - if (!fs_test(cluster_start(fs,i),fs->cluster_size)) { - printf("Cluster %lu is unreadable.\n",i); - set_fat(fs,i,-2); + if (!get_owner(fs, i) && !FAT_IS_BAD(fs, curEntry.value)) + if (!fs_test(cluster_start(fs, i), fs->cluster_size)) { + printf("Cluster %lu is unreadable.\n", i); + set_fat(fs, i, -2); } } } - -void reclaim_free(DOS_FS *fs) +void reclaim_free(DOS_FS * fs) { int reclaimed; unsigned long i; @@ -333,22 +321,22 @@ void reclaim_free(DOS_FS *fs) if (verbose) printf("Checking for unused clusters.\n"); reclaimed = 0; - for (i = 2; i < fs->clusters+2; i++) { - FAT_ENTRY curEntry; - get_fat(&curEntry, fs->fat, i, fs); + for (i = 2; i < fs->clusters + 2; i++) { + FAT_ENTRY curEntry; + get_fat(&curEntry, fs->fat, i, fs); - if (!get_owner(fs,i) && curEntry.value && + if (!get_owner(fs, i) && curEntry.value && !FAT_IS_BAD(fs, curEntry.value)) { - set_fat(fs,i,0); + set_fat(fs, i, 0); reclaimed++; } } if (reclaimed) - printf("Reclaimed %d unused cluster%s (%llu bytes).\n",reclaimed, - reclaimed == 1 ? "" : "s",(unsigned long long)reclaimed*fs->cluster_size); + printf("Reclaimed %d unused cluster%s (%llu bytes).\n", reclaimed, + reclaimed == 1 ? "" : "s", + (unsigned long long)reclaimed * fs->cluster_size); } - /** * Assign the specified owner to all orphan chains (except cycles). * Break cross-links between orphan chains. @@ -359,26 +347,25 @@ void reclaim_free(DOS_FS *fs) * clusters link to it. * @param[in] start_cluster Where to start scanning for orphans */ -static void tag_free(DOS_FS *fs, DOS_FILE *owner, unsigned long *num_refs, +static void tag_free(DOS_FS * fs, DOS_FILE * owner, unsigned long *num_refs, unsigned long start_cluster) { int prev; - unsigned long i,walk; + unsigned long i, walk; if (start_cluster == 0) start_cluster = 2; - for (i = start_cluster; i < fs->clusters+2; i++) { - FAT_ENTRY curEntry; - get_fat(&curEntry, fs->fat, i, fs); + for (i = start_cluster; i < fs->clusters + 2; i++) { + FAT_ENTRY curEntry; + get_fat(&curEntry, fs->fat, i, fs); /* If the current entry is the head of an un-owned chain... */ if (curEntry.value && !FAT_IS_BAD(fs, curEntry.value) && !get_owner(fs, i) && !num_refs[i]) { prev = 0; /* Walk the chain, claiming ownership as we go */ - for (walk = i; walk != -1; - walk = next_cluster(fs,walk)) { + for (walk = i; walk != -1; walk = next_cluster(fs, walk)) { if (!get_owner(fs, walk)) { set_owner(fs, walk, owner); } else { @@ -386,7 +373,7 @@ static void tag_free(DOS_FS *fs, DOS_FILE *owner, unsigned long *num_refs, * or a cycle with a tail. * Terminate this orphan chain (break the link) */ - set_fat(fs,prev,-1); + set_fat(fs, prev, -1); /* This is not necessary because 'walk' is owned and thus * will never become the head of a chain (the only case @@ -395,8 +382,8 @@ static void tag_free(DOS_FS *fs, DOS_FILE *owner, unsigned long *num_refs, * unnecessary. */ num_refs[walk]--; - break; - } + break; + } prev = walk; } } @@ -408,12 +395,12 @@ static void tag_free(DOS_FS *fs, DOS_FILE *owner, unsigned long *num_refs, * * @param[in,out] fs Information about the filesystem */ -void reclaim_file(DOS_FS *fs) +void reclaim_file(DOS_FS * fs) { DOS_FILE orphan; - int reclaimed,files; + int reclaimed, files; int changed = 0; - unsigned long i,next,walk; + unsigned long i, next, walk; unsigned long *num_refs = NULL; /* Only for orphaned clusters */ unsigned long total_num_clusters; @@ -429,22 +416,23 @@ void reclaim_file(DOS_FS *fs) */ for (i = 2; i < total_num_clusters; i++) { - FAT_ENTRY curEntry; - get_fat(&curEntry, fs->fat, i, fs); + FAT_ENTRY curEntry; + get_fat(&curEntry, fs->fat, i, fs); next = curEntry.value; - if (!get_owner(fs,i) && next && next < fs->clusters+2) { + if (!get_owner(fs, i) && next && next < fs->clusters + 2) { /* Cluster is linked, but not owned (orphan) */ - FAT_ENTRY nextEntry; - get_fat(&nextEntry, fs->fat, next, fs); + FAT_ENTRY nextEntry; + get_fat(&nextEntry, fs->fat, next, fs); /* Mark it end-of-chain if it links into an owned cluster, * a free cluster, or a bad cluster. */ - if (get_owner(fs,next) || !nextEntry.value || - FAT_IS_BAD(fs, nextEntry.value)) set_fat(fs,i,-1); + if (get_owner(fs, next) || !nextEntry.value || + FAT_IS_BAD(fs, nextEntry.value)) + set_fat(fs, i, -1); else - num_refs[next]++; + num_refs[next]++; } } @@ -457,24 +445,24 @@ void reclaim_file(DOS_FS *fs) /* Any unaccounted-for orphans must be part of a cycle */ for (i = 2; i < total_num_clusters; i++) { - FAT_ENTRY curEntry; - get_fat(&curEntry, fs->fat, i, fs); + FAT_ENTRY curEntry; + get_fat(&curEntry, fs->fat, i, fs); if (curEntry.value && !FAT_IS_BAD(fs, curEntry.value) && !get_owner(fs, i)) { if (!num_refs[curEntry.value]--) die("Internal error: num_refs going below zero"); - set_fat(fs,i,-1); + set_fat(fs, i, -1); changed = curEntry.value; - printf("Broke cycle at cluster %lu in free chain.\n",i); + printf("Broke cycle at cluster %lu in free chain.\n", i); /* If we've created a new chain head, * tag_free() can claim it */ if (num_refs[curEntry.value] == 0) - break; + break; } - } + } } while (changed); @@ -486,37 +474,37 @@ void reclaim_file(DOS_FS *fs) DIR_ENT de; loff_t offset; files++; - offset = alloc_rootdir_entry(fs,&de,"FSCK%04dREC"); - de.start = CT_LE_W(i&0xffff); + offset = alloc_rootdir_entry(fs, &de, "FSCK%04dREC"); + de.start = CT_LE_W(i & 0xffff); if (fs->fat_bits == 32) - de.starthi = CT_LE_W(i>>16); + de.starthi = CT_LE_W(i >> 16); for (walk = i; walk > 0 && walk != -1; - walk = next_cluster(fs,walk)) { - de.size = CT_LE_L(CF_LE_L(de.size)+fs->cluster_size); + walk = next_cluster(fs, walk)) { + de.size = CT_LE_L(CF_LE_L(de.size) + fs->cluster_size); reclaimed++; } - fs_write(offset,sizeof(DIR_ENT),&de); + fs_write(offset, sizeof(DIR_ENT), &de); } if (reclaimed) printf("Reclaimed %d unused cluster%s (%llu bytes) in %d chain%s.\n", - reclaimed,reclaimed == 1 ? "" : "s",(unsigned long long)reclaimed*fs->cluster_size,files, - files == 1 ? "" : "s"); + reclaimed, reclaimed == 1 ? "" : "s", + (unsigned long long)reclaimed * fs->cluster_size, files, + files == 1 ? "" : "s"); free(num_refs); } - -unsigned long update_free(DOS_FS *fs) +unsigned long update_free(DOS_FS * fs) { unsigned long i; unsigned long free = 0; int do_set = 0; - for (i = 2; i < fs->clusters+2; i++) { - FAT_ENTRY curEntry; - get_fat(&curEntry, fs->fat, i, fs); + for (i = 2; i < fs->clusters + 2; i++) { + FAT_ENTRY curEntry; + get_fat(&curEntry, fs->fat, i, fs); - if (!get_owner(fs,i) && !FAT_IS_BAD(fs, curEntry.value)) + if (!get_owner(fs, i) && !FAT_IS_BAD(fs, curEntry.value)) ++free; } @@ -527,30 +515,31 @@ unsigned long update_free(DOS_FS *fs) printf("Checking free cluster summary.\n"); if (fs->free_clusters != 0xFFFFFFFF) { if (free != fs->free_clusters) { - printf( "Free cluster summary wrong (%ld vs. really %ld)\n", - fs->free_clusters,free); + printf("Free cluster summary wrong (%ld vs. really %ld)\n", + fs->free_clusters, free); if (interactive) - printf( "1) Correct\n2) Don't correct\n" ); - else printf( " Auto-correcting.\n" ); - if (!interactive || get_key("12","?") == '1') + printf("1) Correct\n2) Don't correct\n"); + else + printf(" Auto-correcting.\n"); + if (!interactive || get_key("12", "?") == '1') do_set = 1; } - } - else { - printf( "Free cluster summary uninitialized (should be %ld)\n", free ); + } else { + printf("Free cluster summary uninitialized (should be %ld)\n", free); if (rw) { if (interactive) - printf( "1) Set it\n2) Leave it uninitialized\n" ); - else printf( " Auto-setting.\n" ); - if (!interactive || get_key("12","?") == '1') - do_set = 1; + printf("1) Set it\n2) Leave it uninitialized\n"); + else + printf(" Auto-setting.\n"); + if (!interactive || get_key("12", "?") == '1') + do_set = 1; } } if (do_set) { unsigned long le_free = CT_LE_L(free); fs->free_clusters = free; - fs_write(fs->fsinfo_start+offsetof(struct info_sector,free_clusters), + fs_write(fs->fsinfo_start + offsetof(struct info_sector, free_clusters), sizeof(le_free), &le_free); } diff --git a/src/fat.h b/src/fat.h index 40bb6d0..13ac1b3 100644 --- a/src/fat.h +++ b/src/fat.h @@ -19,66 +19,65 @@ can be found in /usr/share/common-licenses/GPL-3 file. */ - #ifndef _FAT_H #define _FAT_H -void read_fat(DOS_FS *fs); +void read_fat(DOS_FS * fs); /* Loads the FAT of the file system described by FS. Initializes the FAT, replaces broken FATs and rejects invalid cluster entries. */ -void get_fat(FAT_ENTRY *entry, void *fat, unsigned long cluster, DOS_FS *fs); +void get_fat(FAT_ENTRY * entry, void *fat, unsigned long cluster, DOS_FS * fs); /* Retrieve the FAT entry (next chained cluster) for CLUSTER. */ -void set_fat(DOS_FS *fs,unsigned long cluster,unsigned long new); +void set_fat(DOS_FS * fs, unsigned long cluster, unsigned long new); /* Changes the value of the CLUSTERth cluster of the FAT of FS to NEW. Special values of NEW are -1 (EOF, 0xff8 or 0xfff8) and -2 (bad sector, 0xff7 or 0xfff7) */ -int bad_cluster(DOS_FS *fs,unsigned long cluster); +int bad_cluster(DOS_FS * fs, unsigned long cluster); /* Returns a non-zero integer if the CLUSTERth cluster is marked as bad or zero otherwise. */ -unsigned long next_cluster(DOS_FS *fs,unsigned long cluster); +unsigned long next_cluster(DOS_FS * fs, unsigned long cluster); /* Returns the number of the cluster following CLUSTER, or -1 if this is the last cluster of the respective cluster chain. CLUSTER must not be a bad cluster. */ -loff_t cluster_start(DOS_FS *fs,unsigned long cluster); +loff_t cluster_start(DOS_FS * fs, unsigned long cluster); /* Returns the byte offset of CLUSTER, relative to the respective device. */ -void set_owner(DOS_FS *fs,unsigned long cluster,DOS_FILE *owner); +void set_owner(DOS_FS * fs, unsigned long cluster, DOS_FILE * owner); /* Sets the owner pointer of the respective cluster to OWNER. If OWNER was NULL before, it can be set to NULL or any non-NULL value. Otherwise, only NULL is accepted as the new value. */ -DOS_FILE *get_owner(DOS_FS *fs,unsigned long cluster); +DOS_FILE *get_owner(DOS_FS * fs, unsigned long cluster); /* Returns the owner of the repective cluster or NULL if the cluster has no owner. */ -void fix_bad(DOS_FS *fs); +void fix_bad(DOS_FS * fs); /* Scans the disk for currently unused bad clusters and marks them as bad. */ -void reclaim_free(DOS_FS *fs); +void reclaim_free(DOS_FS * fs); /* Marks all allocated, but unused clusters as free. */ -void reclaim_file(DOS_FS *fs); +void reclaim_file(DOS_FS * fs); /* Scans the FAT for chains of allocated, but unused clusters and creates files for them in the root directory. Also tries to fix all inconsistencies (e.g. loops, shared clusters, etc.) in the process. */ -unsigned long update_free(DOS_FS *fs); +unsigned long update_free(DOS_FS * fs); /* Updates free cluster count in FSINFO sector. */ diff --git a/src/file.c b/src/file.c index cb8a94e..4352520 100644 --- a/src/file.c +++ b/src/file.c @@ -23,7 +23,6 @@ /* FAT32, VFAT, Atari format support, and various fixes additions May 1998 * by Roman Hodek */ - #include #include #include @@ -31,32 +30,30 @@ #include #define _LINUX_STAT_H /* hack to avoid inclusion of */ -#define _LINUX_STRING_H_ /* hack to avoid inclusion of */ -#define _LINUX_FS_H /* hack to avoid inclusion of */ +#define _LINUX_STRING_H_ /* hack to avoid inclusion of */ +#define _LINUX_FS_H /* hack to avoid inclusion of */ -# include +#include #include #include "common.h" #include "file.h" - FDSC *fp_root = NULL; - -static void put_char(char **p,unsigned char c) +static void put_char(char **p, unsigned char c) { - if ((c >= ' ' && c < 0x7f) || c >= 0xa0) *(*p)++ = c; + if ((c >= ' ' && c < 0x7f) || c >= 0xa0) + *(*p)++ = c; else { *(*p)++ = '\\'; - *(*p)++ = '0'+(c >> 6); - *(*p)++ = '0'+((c >> 3) & 7); - *(*p)++ = '0'+(c & 7); + *(*p)++ = '0' + (c >> 6); + *(*p)++ = '0' + ((c >> 3) & 7); + *(*p)++ = '0' + (c & 7); } } - /** * Construct the "pretty-printed" representation of the name in a short directory entry. * @@ -67,41 +64,42 @@ static void put_char(char **p,unsigned char c) */ char *file_name(unsigned char *fixed) { - static char path[MSDOS_NAME*4+2]; + static char path[MSDOS_NAME * 4 + 2]; char *p; - int i,j; + int i, j; p = path; - for (i = j = 0; i < 8; i++) + for (i = j = 0; i < 8; i++) if (fixed[i] != ' ') { - while (j++ < i) *p++ = ' '; - put_char(&p,fixed[i]); + while (j++ < i) + *p++ = ' '; + put_char(&p, fixed[i]); } - if (strncmp(fixed+8," ",3)) { + if (strncmp(fixed + 8, " ", 3)) { *p++ = '.'; - for (i = j = 0; i < 3; i++) - if (fixed[i+8] != ' ') { - while (j++ < i) *p++ = ' '; - put_char(&p,fixed[i+8]); + for (i = j = 0; i < 3; i++) + if (fixed[i + 8] != ' ') { + while (j++ < i) + *p++ = ' '; + put_char(&p, fixed[i + 8]); } } *p = 0; return path; } - -int file_cvt(unsigned char *name,unsigned char *fixed) +int file_cvt(unsigned char *name, unsigned char *fixed) { unsigned char c; - int size,ext,cnt; + int size, ext, cnt; size = 8; ext = 0; while (*name) { c = *name; - if (c < ' ' || c > 0x7e || strchr("*?<>|\"/",c)) { + if (c < ' ' || c > 0x7e || strchr("*?<>|\"/", c)) { printf("Invalid character in name. Use \\ooo for special " - "characters.\n"); + "characters.\n"); return 0; } if (c == '.') { @@ -109,7 +107,8 @@ int file_cvt(unsigned char *name,unsigned char *fixed) printf("Duplicate dots in name.\n"); return 0; } - while (size--) *fixed++ = ' '; + while (size--) + *fixed++ = ' '; size = 3; ext = 1; name++; @@ -122,7 +121,7 @@ int file_cvt(unsigned char *name,unsigned char *fixed) printf("Invalid octal character.\n"); return 0; } - c = c*8+*name++-'0'; + c = c * 8 + *name++ - '0'; } if (cnt < 4) { printf("Expected three octal digits.\n"); @@ -130,139 +129,153 @@ int file_cvt(unsigned char *name,unsigned char *fixed) } name += 3; } - if (islower(c)) c = toupper(c); + if (islower(c)) + c = toupper(c); if (size) { *fixed++ = c; size--; } name++; } - if (*name || size == 8) return 0; + if (*name || size == 8) + return 0; if (!ext) { - while (size--) *fixed++ = ' '; + while (size--) + *fixed++ = ' '; size = 3; } - while (size--) *fixed++ = ' '; + while (size--) + *fixed++ = ' '; return 1; } - -void file_add(char *path,FD_TYPE type) +void file_add(char *path, FD_TYPE type) { - FDSC **current,*walk; + FDSC **current, *walk; char name[MSDOS_NAME]; char *here; current = &fp_root; - if (*path != '/') die("%s: Absolute path required.",path); + if (*path != '/') + die("%s: Absolute path required.", path); path++; while (1) { - if ((here = strchr(path,'/'))) *here = 0; - if (!file_cvt(path,name)) exit(2); + if ((here = strchr(path, '/'))) + *here = 0; + if (!file_cvt(path, name)) + exit(2); for (walk = *current; walk; walk = walk->next) - if (!here && (!strncmp(name,walk->name,MSDOS_NAME) || (type == - fdt_undelete && !strncmp(name+1,walk->name+1,MSDOS_NAME-1)))) - die("Ambiguous name: \"%s\"",path); - else if (here && !strncmp(name,walk->name,MSDOS_NAME)) break; + if (!here && (!strncmp(name, walk->name, MSDOS_NAME) || (type == + fdt_undelete + && + !strncmp + (name + 1, + walk-> + name + 1, + MSDOS_NAME + - 1)))) + die("Ambiguous name: \"%s\"", path); + else if (here && !strncmp(name, walk->name, MSDOS_NAME)) + break; if (!walk) { walk = alloc(sizeof(FDSC)); - strncpy(walk->name,name,MSDOS_NAME); + strncpy(walk->name, name, MSDOS_NAME); walk->type = here ? fdt_none : type; walk->first = NULL; walk->next = *current; *current = walk; } current = &walk->first; - if (!here) break; + if (!here) + break; *here = '/'; - path = here+1; + path = here + 1; } } - -FDSC **file_cd(FDSC **curr,char *fixed) +FDSC **file_cd(FDSC ** curr, char *fixed) { FDSC **walk; - if (!curr || !*curr) return NULL; + if (!curr || !*curr) + return NULL; for (walk = curr; *walk; walk = &(*walk)->next) - if (!strncmp((*walk)->name,fixed,MSDOS_NAME) && (*walk)->first) + if (!strncmp((*walk)->name, fixed, MSDOS_NAME) && (*walk)->first) return &(*walk)->first; return NULL; } - -static FDSC **file_find(FDSC **dir,char *fixed) +static FDSC **file_find(FDSC ** dir, char *fixed) { - if (!dir || !*dir) return NULL; - if (*(unsigned char *) fixed == DELETED_FLAG) { + if (!dir || !*dir) + return NULL; + if (*(unsigned char *)fixed == DELETED_FLAG) { while (*dir) { - if (!strncmp((*dir)->name+1,fixed+1,MSDOS_NAME-1) && !(*dir)->first) + if (!strncmp((*dir)->name + 1, fixed + 1, MSDOS_NAME - 1) + && !(*dir)->first) return dir; dir = &(*dir)->next; } return NULL; } while (*dir) { - if (!strncmp((*dir)->name,fixed,MSDOS_NAME) && !(*dir)->first) + if (!strncmp((*dir)->name, fixed, MSDOS_NAME) && !(*dir)->first) return dir; dir = &(*dir)->next; } return NULL; } - /* Returns the attribute of the file FIXED in directory CURR or FDT_NONE if no such file exists or if CURR is NULL. */ -FD_TYPE file_type(FDSC **curr,char *fixed) +FD_TYPE file_type(FDSC ** curr, char *fixed) { FDSC **this; - if ((this = file_find(curr,fixed))) return (*this)->type; + if ((this = file_find(curr, fixed))) + return (*this)->type; return fdt_none; } - -void file_modify(FDSC **curr,char *fixed) +void file_modify(FDSC ** curr, char *fixed) { - FDSC **this,*next; + FDSC **this, *next; - if (!(this = file_find(curr,fixed))) + if (!(this = file_find(curr, fixed))) die("Internal error: file_find failed"); switch ((*this)->type) { - case fdt_drop: - printf("Dropping %s\n",file_name(fixed)); - *(unsigned char *) fixed = DELETED_FLAG; - break; - case fdt_undelete: - *fixed = *(*this)->name; - printf("Undeleting %s\n",file_name(fixed)); - break; - default: - die("Internal error: file_modify"); + case fdt_drop: + printf("Dropping %s\n", file_name(fixed)); + *(unsigned char *)fixed = DELETED_FLAG; + break; + case fdt_undelete: + *fixed = *(*this)->name; + printf("Undeleting %s\n", file_name(fixed)); + break; + default: + die("Internal error: file_modify"); } next = (*this)->next; free(*this); *this = next; } - -static void report_unused(FDSC *this) +static void report_unused(FDSC * this) { FDSC *next; while (this) { next = this->next; - if (this->first) report_unused(this->first); + if (this->first) + report_unused(this->first); else if (this->type != fdt_none) - printf("Warning: did not %s file %s\n",this->type == fdt_drop ? - "drop" : "undelete",file_name(this->name)); + printf("Warning: did not %s file %s\n", this->type == fdt_drop ? + "drop" : "undelete", file_name(this->name)); free(this); this = next; } } - void file_unused(void) { report_unused(fp_root); diff --git a/src/file.h b/src/file.h index b38523b..40bd58a 100644 --- a/src/file.h +++ b/src/file.h @@ -19,49 +19,46 @@ can be found in /usr/share/common-licenses/GPL-3 file. */ - #ifndef _FILE_H #define _FILE_H -typedef enum { fdt_none,fdt_drop,fdt_undelete } FD_TYPE; +typedef enum { fdt_none, fdt_drop, fdt_undelete } FD_TYPE; typedef struct _fptr { char name[MSDOS_NAME]; FD_TYPE type; - struct _fptr *first; /* first entry */ - struct _fptr *next; /* next file in directory */ + struct _fptr *first; /* first entry */ + struct _fptr *next; /* next file in directory */ } FDSC; - extern FDSC *fp_root; - char *file_name(unsigned char *fixed); /* Returns a pointer to a pretty-printed representation of a fixed MS-DOS file name. */ -int file_cvt(unsigned char *name,unsigned char *fixed); +int file_cvt(unsigned char *name, unsigned char *fixed); /* Converts a pretty-printed file name to the fixed MS-DOS format. Returns a non-zero integer on success, zero on failure. */ -void file_add(char *path,FD_TYPE type); +void file_add(char *path, FD_TYPE type); /* Define special attributes for a path. TYPE can be either FDT_DROP or FDT_UNDELETE. */ -FDSC **file_cd(FDSC **curr,char *fixed); +FDSC **file_cd(FDSC ** curr, char *fixed); /* Returns a pointer to the directory descriptor of the subdirectory FIXED of CURR, or NULL if no such subdirectory exists. */ -FD_TYPE file_type(FDSC **curr,char *fixed); +FD_TYPE file_type(FDSC ** curr, char *fixed); /* Returns the attribute of the file FIXED in directory CURR or FDT_NONE if no such file exists or if CURR is NULL. */ -void file_modify(FDSC **curr,char *fixed); +void file_modify(FDSC ** curr, char *fixed); /* Performs the necessary operation on the entry of CURR that is named FIXED. */ diff --git a/src/io.c b/src/io.c index fb0369e..ae043b4 100644 --- a/src/io.c +++ b/src/io.c @@ -45,7 +45,6 @@ #include "common.h" #include "io.h" - typedef struct _change { void *data; loff_t pos; @@ -53,20 +52,20 @@ typedef struct _change { struct _change *next; } CHANGE; - -static CHANGE *changes,*last; -static int fd,did_change = 0; +static CHANGE *changes, *last; +static int fd, did_change = 0; unsigned device_no; - #ifdef __DJGPP__ -#include "volume.h" /* DOS lowlevel disk access functions */ +#include "volume.h" /* DOS lowlevel disk access functions */ loff_t llseek(int fd, loff_t offset, int whence) { - if ((whence != SEEK_SET) || (fd == 4711)) return -1; /* only those supported */ + if ((whence != SEEK_SET) || (fd == 4711)) + return -1; /* only those supported */ return VolumeSeek(offset); } + #define open OpenVolume #define close CloseVolume #define read(a,b,c) ReadVolume(b,c) @@ -74,43 +73,41 @@ loff_t llseek(int fd, loff_t offset, int whence) #else loff_t llseek(int fd, loff_t offset, int whence) { - return (loff_t) lseek64(fd, (off64_t)offset, whence); + return (loff_t) lseek64(fd, (off64_t) offset, whence); } #endif -void fs_open(char *path,int rw) +void fs_open(char *path, int rw) { struct stat stbuf; - if ((fd = open(path,rw ? O_RDWR : O_RDONLY)) < 0) { - perror("open"); - exit(6); + if ((fd = open(path, rw ? O_RDWR : O_RDONLY)) < 0) { + perror("open"); + exit(6); } changes = last = NULL; did_change = 0; #ifndef _DJGPP_ - if (fstat(fd,&stbuf) < 0) - pdie("fstat %s",path); + if (fstat(fd, &stbuf) < 0) + pdie("fstat %s", path); device_no = S_ISBLK(stbuf.st_mode) ? (stbuf.st_rdev >> 8) & 0xff : 0; #else if (IsWorkingOnImageFile()) { - if (fstat(GetVolumeHandle(),&stbuf) < 0) - pdie("fstat image %s",path); + if (fstat(GetVolumeHandle(), &stbuf) < 0) + pdie("fstat image %s", path); device_no = 0; - } - else { - /* return 2 for floppy, 1 for ramdisk, 7 for loopback */ - /* used by boot.c in Atari mode: floppy always FAT12, */ - /* loopback / ramdisk only FAT12 if usual floppy size, */ - /* harddisk always FAT16 on Atari... */ - device_no = (GetVolumeHandle() < 2) ? 2 : 1; - /* telling "floppy" for A:/B:, "ramdisk" for the rest */ + } else { + /* return 2 for floppy, 1 for ramdisk, 7 for loopback */ + /* used by boot.c in Atari mode: floppy always FAT12, */ + /* loopback / ramdisk only FAT12 if usual floppy size, */ + /* harddisk always FAT16 on Atari... */ + device_no = (GetVolumeHandle() < 2) ? 2 : 1; + /* telling "floppy" for A:/B:, "ramdisk" for the rest */ } #endif } - /** * Read data from the partition, accounting for any pending updates that are * queued for writing. @@ -120,61 +117,72 @@ void fs_open(char *path,int rw) * @param[in] size Number of bytes to read * @param[out] data Where to put the data read */ -void fs_read(loff_t pos,int size,void *data) +void fs_read(loff_t pos, int size, void *data) { CHANGE *walk; int got; - if (llseek(fd,pos,0) != pos) pdie("Seek to %lld",pos); - if ((got = read(fd,data,size)) < 0) pdie("Read %d bytes at %lld",size,pos); - if (got != size) die("Got %d bytes instead of %d at %lld",got,size,pos); + if (llseek(fd, pos, 0) != pos) + pdie("Seek to %lld", pos); + if ((got = read(fd, data, size)) < 0) + pdie("Read %d bytes at %lld", size, pos); + if (got != size) + die("Got %d bytes instead of %d at %lld", got, size, pos); for (walk = changes; walk; walk = walk->next) { - if (walk->pos < pos+size && walk->pos+walk->size > pos) { + if (walk->pos < pos + size && walk->pos + walk->size > pos) { if (walk->pos < pos) - memcpy(data,(char *) walk->data+pos-walk->pos,min(size, - walk->size-pos+walk->pos)); - else memcpy((char *) data+walk->pos-pos,walk->data,min(walk->size, - size+pos-walk->pos)); + memcpy(data, (char *)walk->data + pos - walk->pos, min(size, + walk-> + size - + pos + + walk-> + pos)); + else + memcpy((char *)data + walk->pos - pos, walk->data, + min(walk->size, size + pos - walk->pos)); } } } - -int fs_test(loff_t pos,int size) +int fs_test(loff_t pos, int size) { void *scratch; int okay; - if (llseek(fd,pos,0) != pos) pdie("Seek to %lld",pos); + if (llseek(fd, pos, 0) != pos) + pdie("Seek to %lld", pos); scratch = alloc(size); - okay = read(fd,scratch,size) == size; + okay = read(fd, scratch, size) == size; free(scratch); return okay; } - -void fs_write(loff_t pos,int size,void *data) +void fs_write(loff_t pos, int size, void *data) { CHANGE *new; int did; if (write_immed) { did_change = 1; - if (llseek(fd,pos,0) != pos) pdie("Seek to %lld",pos); - if ((did = write(fd,data,size)) == size) return; - if (did < 0) pdie("Write %d bytes at %lld",size,pos); - die("Wrote %d bytes instead of %d at %lld",did,size,pos); + if (llseek(fd, pos, 0) != pos) + pdie("Seek to %lld", pos); + if ((did = write(fd, data, size)) == size) + return; + if (did < 0) + pdie("Write %d bytes at %lld", size, pos); + die("Wrote %d bytes instead of %d at %lld", did, size, pos); } new = alloc(sizeof(CHANGE)); new->pos = pos; - memcpy(new->data = alloc(new->size = size),data,size); + memcpy(new->data = alloc(new->size = size), data, size); new->next = NULL; - if (last) last->next = new; - else changes = new; + if (last) + last->next = new; + else + changes = new; last = new; } - static void fs_flush(void) { CHANGE *this; @@ -183,40 +191,42 @@ static void fs_flush(void) while (changes) { this = changes; changes = changes->next; - if (llseek(fd,this->pos,0) != this->pos) - fprintf(stderr,"Seek to %lld failed: %s\n Did not write %d bytes.\n", - (long long)this->pos,strerror(errno),this->size); - else if ((size = write(fd,this->data,this->size)) < 0) - fprintf(stderr,"Writing %d bytes at %lld failed: %s\n",this->size, - (long long)this->pos,strerror(errno)); - else if (size != this->size) - fprintf(stderr,"Wrote %d bytes instead of %d bytes at %lld." - "\n",size,this->size,(long long)this->pos); + if (llseek(fd, this->pos, 0) != this->pos) + fprintf(stderr, + "Seek to %lld failed: %s\n Did not write %d bytes.\n", + (long long)this->pos, strerror(errno), this->size); + else if ((size = write(fd, this->data, this->size)) < 0) + fprintf(stderr, "Writing %d bytes at %lld failed: %s\n", this->size, + (long long)this->pos, strerror(errno)); + else if (size != this->size) + fprintf(stderr, "Wrote %d bytes instead of %d bytes at %lld." + "\n", size, this->size, (long long)this->pos); free(this->data); free(this); } } - int fs_close(int write) { CHANGE *next; int changed; - changed = !!changes; - if (write) fs_flush(); - else while (changes) { + changed = ! !changes; + if (write) + fs_flush(); + else + while (changes) { next = changes->next; free(changes->data); free(changes); changes = next; } - if (close(fd) < 0) pdie("closing file system"); + if (close(fd) < 0) + pdie("closing file system"); return changed || did_change; } - int fs_changed(void) { - return !!changes || did_change; + return ! !changes || did_change; } diff --git a/src/io.h b/src/io.h index 9da453e..2db4ea7 100644 --- a/src/io.h +++ b/src/io.h @@ -23,32 +23,31 @@ /* FAT32, VFAT, Atari format support, and various fixes additions May 1998 * by Roman Hodek */ - #ifndef _IO_H #define _IO_H -#include /* for loff_t */ +#include /* for loff_t */ loff_t llseek(int fd, loff_t offset, int whence); /* lseek() analogue for large offsets. */ -void fs_open(char *path,int rw); +void fs_open(char *path, int rw); /* Opens the file system PATH. If RW is zero, the file system is opened read-only, otherwise, it is opened read-write. */ -void fs_read(loff_t pos,int size,void *data); +void fs_read(loff_t pos, int size, void *data); /* Reads SIZE bytes starting at POS into DATA. Performs all applicable changes. */ -int fs_test(loff_t pos,int size); +int fs_test(loff_t pos, int size); /* Returns a non-zero integer if SIZE bytes starting at POS can be read without errors. Otherwise, it returns zero. */ -void fs_write(loff_t pos,int size,void *data); +void fs_write(loff_t pos, int size, void *data); /* If write_immed is non-zero, SIZE bytes are written from DATA to the disk, starting at POS. If write_immed is zero, the change is added to a list in diff --git a/src/lfn.c b/src/lfn.c index dc17f20..543dc44 100644 --- a/src/lfn.c +++ b/src/lfn.c @@ -32,14 +32,14 @@ #include "file.h" typedef struct { - __u8 id; /* sequence number for slot */ - __u8 name0_4[10]; /* first 5 characters in name */ - __u8 attr; /* attribute byte */ - __u8 reserved; /* always 0 */ - __u8 alias_checksum; /* checksum for 8.3 alias */ - __u8 name5_10[12]; /* 6 more characters in name */ - __u16 start; /* starting cluster number, 0 in long slots */ - __u8 name11_12[4]; /* last 2 characters in name */ + __u8 id; /* sequence number for slot */ + __u8 name0_4[10]; /* first 5 characters in name */ + __u8 attr; /* attribute byte */ + __u8 reserved; /* always 0 */ + __u8 alias_checksum; /* checksum for 8.3 alias */ + __u8 name5_10[12]; /* 6 more characters in name */ + __u16 start; /* starting cluster number, 0 in long slots */ + __u8 name11_12[4]; /* last 2 characters in name */ } LFN_ENT; #define LFN_ID_START 0x40 @@ -88,22 +88,23 @@ static unsigned char fat_uni2esc[64] = { /* This function converts an unicode string to a normal ASCII string, assuming * ISO-8859-1 charset. Characters not in 8859-1 are converted to the same * escape notation as used by the kernel, i.e. the uuencode-like ":xxx" */ -static char *cnv_unicode( const unsigned char *uni, int maxlen, int use_q ) +static char *cnv_unicode(const unsigned char *uni, int maxlen, int use_q) { const unsigned char *up; unsigned char *out, *cp; int len, val; - for( len = 0, up = uni; (up-uni)/2 < maxlen && (up[0] || up[1]); up += 2 ){ - if (UNICODE_CONVERTABLE(up[0],up[1])) + for (len = 0, up = uni; (up - uni) / 2 < maxlen && (up[0] || up[1]); + up += 2) { + if (UNICODE_CONVERTABLE(up[0], up[1])) ++len; else len += 4; } - cp = out = use_q ? qalloc( &mem_queue, len+1 ) : alloc( len+1 ); + cp = out = use_q ? qalloc(&mem_queue, len + 1) : alloc(len + 1); - for( up = uni; (up-uni)/2 < maxlen && (up[0] || up[1]); up += 2 ) { - if (UNICODE_CONVERTABLE(up[0],up[1])) + for (up = uni; (up - uni) / 2 < maxlen && (up[0] || up[1]); up += 2) { + if (UNICODE_CONVERTABLE(up[0], up[1])) *cp++ = up[0]; else { /* here the same escape notation is used as in the Linux kernel */ @@ -119,19 +120,17 @@ static char *cnv_unicode( const unsigned char *uni, int maxlen, int use_q ) } *cp = 0; - return( out ); + return (out); } - -static void copy_lfn_part( char *dst, LFN_ENT *lfn ) +static void copy_lfn_part(char *dst, LFN_ENT * lfn) { - memcpy( dst, lfn->name0_4, 10 ); - memcpy( dst+10, lfn->name5_10, 12 ); - memcpy( dst+22, lfn->name11_12, 4 ); + memcpy(dst, lfn->name0_4, 10); + memcpy(dst + 10, lfn->name5_10, 12); + memcpy(dst + 22, lfn->name11_12, 4); } - -static void clear_lfn_slots( int start, int end ) +static void clear_lfn_slots(int start, int end) { int i; LFN_ENT empty; @@ -140,11 +139,11 @@ static void clear_lfn_slots( int start, int end ) * This is to avoid that some FAT-reading OSes (not Linux! ;) stop reading * a directory at the first zero entry... */ - memset( &empty, 0, sizeof(empty) ); + memset(&empty, 0, sizeof(empty)); empty.id = DELETED_FLAG; - for( i = start; i <= end; ++i ) { - fs_write( lfn_offsets[i], sizeof(LFN_ENT), &empty ); + for (i = start; i <= end; ++i) { + fs_write(lfn_offsets[i], sizeof(LFN_ENT), &empty); } } @@ -153,34 +152,34 @@ void lfn_fix_checksum(loff_t from, loff_t to, const char *short_name) int i; __u8 sum; for (sum = 0, i = 0; i < 11; i++) - sum = (((sum&1) << 7) | ((sum&0xfe) >> 1)) + short_name[i]; + sum = (((sum & 1) << 7) | ((sum & 0xfe) >> 1)) + short_name[i]; - for( ; from < to; from += sizeof(LFN_ENT) ) { - fs_write( from + offsetof(LFN_ENT,alias_checksum), sizeof(sum), &sum ); + for (; from < to; from += sizeof(LFN_ENT)) { + fs_write(from + offsetof(LFN_ENT, alias_checksum), sizeof(sum), &sum); } } -void lfn_reset( void ) +void lfn_reset(void) { if (lfn_unicode) - free( lfn_unicode ); + free(lfn_unicode); lfn_unicode = NULL; if (lfn_offsets) - free( lfn_offsets ); + free(lfn_offsets); lfn_offsets = NULL; lfn_slot = -1; } - /* This function is only called with de->attr == VFAT_LN_ATTR. It stores part * of the long name. */ -void lfn_add_slot( DIR_ENT *de, loff_t dir_offset ) +void lfn_add_slot(DIR_ENT * de, loff_t dir_offset) { - LFN_ENT *lfn = (LFN_ENT *)de; + LFN_ENT *lfn = (LFN_ENT *) de; int slot = lfn->id & LFN_ID_SLOTMASK; unsigned offset; - if (lfn_slot == 0) lfn_check_orphaned(); + if (lfn_slot == 0) + lfn_check_orphaned(); if (de->attr != VFAT_LN_ATTR) die("lfn_add_slot called with non-LFN directory entry"); @@ -196,124 +195,121 @@ void lfn_add_slot( DIR_ENT *de, loff_t dir_offset ) * checksum ok: clear start bit */ /* XXX: Should delay that until next LFN known (then can better * display the name) */ - printf( "A new long file name starts within an old one.\n" ); - if (slot == lfn_slot && - lfn->alias_checksum == lfn_checksum) { + printf("A new long file name starts within an old one.\n"); + if (slot == lfn_slot && lfn->alias_checksum == lfn_checksum) { char *part1 = CNV_THIS_PART(lfn); char *part2 = CNV_PARTS_SO_FAR(); - printf( " It could be that the LFN start bit is wrong here\n" - " if \"%s\" seems to match \"%s\".\n", part1, part2 ); - free( part1 ); - free( part2 ); + printf(" It could be that the LFN start bit is wrong here\n" + " if \"%s\" seems to match \"%s\".\n", part1, part2); + free(part1); + free(part2); can_clear = 1; } if (interactive) { - printf( "1: Delete previous LFN\n2: Leave it as it is.\n" ); + printf("1: Delete previous LFN\n2: Leave it as it is.\n"); if (can_clear) - printf( "3: Clear start bit and concatenate LFNs\n" ); - } - else printf( " Not auto-correcting this.\n" ); + printf("3: Clear start bit and concatenate LFNs\n"); + } else + printf(" Not auto-correcting this.\n"); if (interactive) { - switch( get_key( can_clear ? "123" : "12", "?" )) { - case '1': - clear_lfn_slots( 0, lfn_parts-1 ); + switch (get_key(can_clear ? "123" : "12", "?")) { + case '1': + clear_lfn_slots(0, lfn_parts - 1); lfn_reset(); break; - case '2': + case '2': break; - case '3': + case '3': lfn->id &= ~LFN_ID_START; - fs_write( dir_offset+offsetof(LFN_ENT,id), - sizeof(lfn->id), &lfn->id ); + fs_write(dir_offset + offsetof(LFN_ENT, id), + sizeof(lfn->id), &lfn->id); break; } } } lfn_slot = slot; lfn_checksum = lfn->alias_checksum; - lfn_unicode = alloc( (lfn_slot*CHARS_PER_LFN+1)*2 ); - lfn_offsets = alloc( lfn_slot*sizeof(loff_t) ); + lfn_unicode = alloc((lfn_slot * CHARS_PER_LFN + 1) * 2); + lfn_offsets = alloc(lfn_slot * sizeof(loff_t)); lfn_parts = 0; - } - else if (lfn_slot == -1 && slot != 0) { + } else if (lfn_slot == -1 && slot != 0) { /* No LFN in progress, but slot found; start bit missing */ /* Causes: 1) start bit got lost, 2) Previous slot with start bit got * lost */ /* Fixes: 1) delete LFN, 2) set start bit */ char *part = CNV_THIS_PART(lfn); - printf( "Long filename fragment \"%s\" found outside a LFN " - "sequence.\n (Maybe the start bit is missing on the " - "last fragment)\n", part ); + printf("Long filename fragment \"%s\" found outside a LFN " + "sequence.\n (Maybe the start bit is missing on the " + "last fragment)\n", part); if (interactive) { - printf( "1: Delete fragment\n2: Leave it as it is.\n" - "3: Set start bit\n" ); - } - else printf( " Not auto-correcting this.\n" ); - switch( interactive ? get_key( "123", "?" ) : '2') { - case '1': + printf("1: Delete fragment\n2: Leave it as it is.\n" + "3: Set start bit\n"); + } else + printf(" Not auto-correcting this.\n"); + switch (interactive ? get_key("123", "?") : '2') { + case '1': if (!lfn_offsets) - lfn_offsets = alloc( sizeof(loff_t) ); + lfn_offsets = alloc(sizeof(loff_t)); lfn_offsets[0] = dir_offset; - clear_lfn_slots( 0, 0 ); + clear_lfn_slots(0, 0); lfn_reset(); return; - case '2': + case '2': lfn_reset(); return; - case '3': + case '3': lfn->id |= LFN_ID_START; - fs_write( dir_offset+offsetof(LFN_ENT,id), - sizeof(lfn->id), &lfn->id ); + fs_write(dir_offset + offsetof(LFN_ENT, id), + sizeof(lfn->id), &lfn->id); lfn_slot = slot; lfn_checksum = lfn->alias_checksum; - lfn_unicode = alloc( (lfn_slot*CHARS_PER_LFN+1)*2 ); - lfn_offsets = alloc( lfn_slot*sizeof(loff_t) ); + lfn_unicode = alloc((lfn_slot * CHARS_PER_LFN + 1) * 2); + lfn_offsets = alloc(lfn_slot * sizeof(loff_t)); lfn_parts = 0; break; } - } - else if (slot != lfn_slot) { + } else if (slot != lfn_slot) { /* wrong sequence number */ /* Causes: 1) seq-no destroyed */ /* Fixes: 1) delete LFN, 2) fix number (maybe only if following parts * are ok?, maybe only if checksum is ok?) (Attention: space * for name was allocated before!) */ int can_fix = 0; - printf( "Unexpected long filename sequence number " - "(%d vs. expected %d).\n", - slot, lfn_slot ); + printf("Unexpected long filename sequence number " + "(%d vs. expected %d).\n", slot, lfn_slot); if (lfn->alias_checksum == lfn_checksum && lfn_slot > 0) { char *part1 = CNV_THIS_PART(lfn); char *part2 = CNV_PARTS_SO_FAR(); - printf( " It could be that just the number is wrong\n" - " if \"%s\" seems to match \"%s\".\n", part1, part2 ); - free( part1 ); - free( part2 ); + printf(" It could be that just the number is wrong\n" + " if \"%s\" seems to match \"%s\".\n", part1, part2); + free(part1); + free(part2); can_fix = 1; } if (interactive) { - printf( "1: Delete LFN\n2: Leave it as it is (and ignore LFN so far)\n" ); + printf + ("1: Delete LFN\n2: Leave it as it is (and ignore LFN so far)\n"); if (can_fix) - printf( "3: Correct sequence number\n" ); - } - else printf( " Not auto-correcting this.\n" ); - switch( interactive ? get_key( can_fix ? "123" : "12", "?" ) : '2') { - case '1': + printf("3: Correct sequence number\n"); + } else + printf(" Not auto-correcting this.\n"); + switch (interactive ? get_key(can_fix ? "123" : "12", "?") : '2') { + case '1': if (!lfn_offsets) { - lfn_offsets = alloc( sizeof(loff_t) ); + lfn_offsets = alloc(sizeof(loff_t)); lfn_parts = 0; } lfn_offsets[lfn_parts++] = dir_offset; - clear_lfn_slots( 0, lfn_parts-1 ); + clear_lfn_slots(0, lfn_parts - 1); lfn_reset(); return; - case '2': + case '2': lfn_reset(); return; - case '3': + case '3': lfn->id = (lfn->id & ~LFN_ID_SLOTMASK) | lfn_slot; - fs_write( dir_offset+offsetof(LFN_ENT,id), - sizeof(lfn->id), &lfn->id ); + fs_write(dir_offset + offsetof(LFN_ENT, id), + sizeof(lfn->id), &lfn->id); break; } } @@ -322,27 +318,27 @@ void lfn_add_slot( DIR_ENT *de, loff_t dir_offset ) /* checksum mismatch */ /* Causes: 1) checksum field here destroyed */ /* Fixes: 1) delete LFN, 2) fix checksum */ - printf( "Checksum in long filename part wrong " - "(%02x vs. expected %02x).\n", - lfn->alias_checksum, lfn_checksum ); + printf("Checksum in long filename part wrong " + "(%02x vs. expected %02x).\n", + lfn->alias_checksum, lfn_checksum); if (interactive) { - printf( "1: Delete LFN\n2: Leave it as it is.\n" - "3: Correct checksum\n" ); - } - else printf( " Not auto-correcting this.\n" ); + printf("1: Delete LFN\n2: Leave it as it is.\n" + "3: Correct checksum\n"); + } else + printf(" Not auto-correcting this.\n"); if (interactive) { - switch( get_key( "123", "?" )) { - case '1': + switch (get_key("123", "?")) { + case '1': lfn_offsets[lfn_parts++] = dir_offset; - clear_lfn_slots( 0, lfn_parts-1 ); + clear_lfn_slots(0, lfn_parts - 1); lfn_reset(); return; - case '2': + case '2': break; - case '3': + case '3': lfn->alias_checksum = lfn_checksum; - fs_write( dir_offset+offsetof(LFN_ENT,alias_checksum), - sizeof(lfn->alias_checksum), &lfn->alias_checksum ); + fs_write(dir_offset + offsetof(LFN_ENT, alias_checksum), + sizeof(lfn->alias_checksum), &lfn->alias_checksum); break; } } @@ -350,43 +346,44 @@ void lfn_add_slot( DIR_ENT *de, loff_t dir_offset ) if (lfn_slot != -1) { lfn_slot--; - offset = lfn_slot * CHARS_PER_LFN*2; - copy_lfn_part( lfn_unicode+offset, lfn ); + offset = lfn_slot * CHARS_PER_LFN * 2; + copy_lfn_part(lfn_unicode + offset, lfn); if (lfn->id & LFN_ID_START) - lfn_unicode[offset+26] = lfn_unicode[offset+27] = 0; + lfn_unicode[offset + 26] = lfn_unicode[offset + 27] = 0; lfn_offsets[lfn_parts++] = dir_offset; } if (lfn->reserved != 0) { - printf( "Reserved field in VFAT long filename slot is not 0 " - "(but 0x%02x).\n", lfn->reserved ); + printf("Reserved field in VFAT long filename slot is not 0 " + "(but 0x%02x).\n", lfn->reserved); if (interactive) - printf( "1: Fix.\n2: Leave it.\n" ); - else printf( "Auto-setting to 0.\n" ); - if (!interactive || get_key("12","?") == '1') { + printf("1: Fix.\n2: Leave it.\n"); + else + printf("Auto-setting to 0.\n"); + if (!interactive || get_key("12", "?") == '1') { lfn->reserved = 0; - fs_write( dir_offset+offsetof(LFN_ENT,reserved), - sizeof(lfn->reserved), &lfn->reserved ); + fs_write(dir_offset + offsetof(LFN_ENT, reserved), + sizeof(lfn->reserved), &lfn->reserved); } } if (lfn->start != CT_LE_W(0)) { - printf( "Start cluster field in VFAT long filename slot is not 0 " - "(but 0x%04x).\n", lfn->start ); + printf("Start cluster field in VFAT long filename slot is not 0 " + "(but 0x%04x).\n", lfn->start); if (interactive) - printf( "1: Fix.\n2: Leave it.\n" ); - else printf( "Auto-setting to 0.\n" ); - if (!interactive || get_key("12","?") == '1') { + printf("1: Fix.\n2: Leave it.\n"); + else + printf("Auto-setting to 0.\n"); + if (!interactive || get_key("12", "?") == '1') { lfn->start = CT_LE_W(0); - fs_write( dir_offset+offsetof(LFN_ENT,start), - sizeof(lfn->start),&lfn->start ); + fs_write(dir_offset + offsetof(LFN_ENT, start), + sizeof(lfn->start), &lfn->start); } } } - /* This function is always called when de->attr != VFAT_LN_ATTR is found, to * retrieve the previously constructed LFN. */ -char *lfn_get( DIR_ENT *de, loff_t *lfn_offset ) +char *lfn_get(DIR_ENT * de, loff_t * lfn_offset) { char *lfn; __u8 sum; @@ -398,7 +395,7 @@ char *lfn_get( DIR_ENT *de, loff_t *lfn_offset ) #if 0 if (de->lcase) - printf( "lcase=%02x\n",de->lcase ); + printf("lcase=%02x\n", de->lcase); #endif if (lfn_slot == -1) @@ -413,67 +410,66 @@ char *lfn_get( DIR_ENT *de, loff_t *lfn_offset ) * 3) renumber entries and truncate name */ char *long_name = CNV_PARTS_SO_FAR(); char *short_name = file_name(de->name); - printf( "Unfinished long file name \"%s\".\n" - " (Start may have been overwritten by %s)\n", - long_name, short_name ); - free( long_name ); + printf("Unfinished long file name \"%s\".\n" + " (Start may have been overwritten by %s)\n", + long_name, short_name); + free(long_name); if (interactive) { - printf( "1: Delete LFN\n2: Leave it as it is.\n" - "3: Fix numbering (truncates long name and attaches " - "it to short name %s)\n", short_name ); - } - else printf( " Not auto-correcting this.\n" ); - switch( interactive ? get_key( "123", "?" ) : '2') { - case '1': - clear_lfn_slots( 0, lfn_parts-1 ); + printf("1: Delete LFN\n2: Leave it as it is.\n" + "3: Fix numbering (truncates long name and attaches " + "it to short name %s)\n", short_name); + } else + printf(" Not auto-correcting this.\n"); + switch (interactive ? get_key("123", "?") : '2') { + case '1': + clear_lfn_slots(0, lfn_parts - 1); lfn_reset(); return NULL; - case '2': + case '2': lfn_reset(); return NULL; - case '3': - for( i = 0; i < lfn_parts; ++i ) { - __u8 id = (lfn_parts-i) | (i==0 ? LFN_ID_START : 0); - fs_write( lfn_offsets[i]+offsetof(LFN_ENT,id), - sizeof(id), &id ); + case '3': + for (i = 0; i < lfn_parts; ++i) { + __u8 id = (lfn_parts - i) | (i == 0 ? LFN_ID_START : 0); + fs_write(lfn_offsets[i] + offsetof(LFN_ENT, id), + sizeof(id), &id); } - memmove( lfn_unicode, lfn_unicode+lfn_slot*CHARS_PER_LFN*2, - lfn_parts*CHARS_PER_LFN*2 ); + memmove(lfn_unicode, lfn_unicode + lfn_slot * CHARS_PER_LFN * 2, + lfn_parts * CHARS_PER_LFN * 2); break; } } for (sum = 0, i = 0; i < 11; i++) - sum = (((sum&1) << 7) | ((sum&0xfe) >> 1)) + de->name[i]; + sum = (((sum & 1) << 7) | ((sum & 0xfe) >> 1)) + de->name[i]; if (sum != lfn_checksum) { /* checksum doesn't match, long name doesn't apply to this alias */ /* Causes: 1) alias renamed */ /* Fixes: 1) Fix checksum in LFN entries */ char *long_name = CNV_PARTS_SO_FAR(); char *short_name = file_name(de->name); - printf( "Wrong checksum for long file name \"%s\".\n" - " (Short name %s may have changed without updating the long name)\n", - long_name, short_name ); - free( long_name ); + printf("Wrong checksum for long file name \"%s\".\n" + " (Short name %s may have changed without updating the long name)\n", + long_name, short_name); + free(long_name); if (interactive) { - printf( "1: Delete LFN\n2: Leave it as it is.\n" - "3: Fix checksum (attaches to short name %s)\n", - short_name ); - } - else printf( " Not auto-correcting this.\n" ); + printf("1: Delete LFN\n2: Leave it as it is.\n" + "3: Fix checksum (attaches to short name %s)\n", short_name); + } else + printf(" Not auto-correcting this.\n"); if (interactive) { - switch( get_key( "123", "?" )) { - case '1': - clear_lfn_slots( 0, lfn_parts-1 ); + switch (get_key("123", "?")) { + case '1': + clear_lfn_slots(0, lfn_parts - 1); lfn_reset(); return NULL; - case '2': + case '2': lfn_reset(); return NULL; - case '3': - for( i = 0; i < lfn_parts; ++i ) { - fs_write( lfn_offsets[i]+offsetof(LFN_ENT,alias_checksum), - sizeof(sum), &sum ); + case '3': + for (i = 0; i < lfn_parts; ++i) { + fs_write(lfn_offsets[i] + offsetof(LFN_ENT, alias_checksum), + sizeof(sum), &sum); } break; } @@ -481,9 +477,9 @@ char *lfn_get( DIR_ENT *de, loff_t *lfn_offset ) } *lfn_offset = lfn_offsets[0]; - lfn = cnv_unicode( lfn_unicode, UNTIL_0, 1 ); + lfn = cnv_unicode(lfn_unicode, UNTIL_0, 1); lfn_reset(); - return( lfn ); + return (lfn); } void lfn_check_orphaned(void) @@ -496,9 +492,10 @@ void lfn_check_orphaned(void) long_name = CNV_PARTS_SO_FAR(); printf("Orphaned long file name part \"%s\"\n", long_name); if (interactive) - printf( "1: Delete.\n2: Leave it.\n" ); - else printf( " Auto-deleting.\n" ); - if (!interactive || get_key("12","?") == '1') { + printf("1: Delete.\n2: Leave it.\n"); + else + printf(" Auto-deleting.\n"); + if (!interactive || get_key("12", "?") == '1') { clear_lfn_slots(0, lfn_parts - 1); } lfn_reset(); diff --git a/src/lfn.h b/src/lfn.h index 2da426d..2ea44a7 100644 --- a/src/lfn.h +++ b/src/lfn.h @@ -22,13 +22,13 @@ #ifndef _LFN_H #define _LFN_H -void lfn_reset( void ); +void lfn_reset(void); /* Reset the state of the LFN parser. */ -void lfn_add_slot( DIR_ENT *de, loff_t dir_offset ); +void lfn_add_slot(DIR_ENT * de, loff_t dir_offset); /* Process a dir slot that is a VFAT LFN entry. */ -char *lfn_get( DIR_ENT *de, loff_t *lfn_offset ); +char *lfn_get(DIR_ENT * de, loff_t * lfn_offset); /* Retrieve the long name for the proper dir entry. */ void lfn_check_orphaned(void); diff --git a/src/mkdosfs.c b/src/mkdosfs.c index a1378ee..1f44eaf 100644 --- a/src/mkdosfs.c +++ b/src/mkdosfs.c @@ -63,7 +63,7 @@ #include #include -# include +#include #if __BYTE_ORDER == __BIG_ENDIAN @@ -105,24 +105,21 @@ #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) +inline int cdiv(int a, int b) { - return (a + b - 1) / b; + return (a + b - 1) / b; } /* MS-DOS filesystem structures -- I included them here instead of @@ -171,75 +168,73 @@ cdiv (int a, int b) * alignments */ 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 */ + __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 +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; + __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. + __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]; + __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)); +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)); /* The "boot code" we put into the filesystem... it writes a message and tells the user to try again */ @@ -249,29 +244,27 @@ char dummy_boot_jump[3] = { 0xeb, 0x3c, 0x90 }; char dummy_boot_jump_m68k[2] = { 0x60, 0x1c }; #define MSG_OFFSET_OFFSET 3 -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"; +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 */ @@ -285,18 +278,18 @@ static int verbose = 0; /* Default to verbose mode off */ static long volume_id; /* Volume ID number */ static time_t create_time; /* Creation time */ static struct timeval create_timeval; /* Creation time */ -static char volume_name[] = " "; /* Volume name */ +static char volume_name[] = " "; /* Volume name */ static unsigned long long 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 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 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 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 int ignore_full_disk = 0; /* Ignore warning about 'full' disk devices */ static off_t 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 */ @@ -308,1038 +301,991 @@ 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 */ -static int hidden_sectors = 0; /* Number of hidden sectors */ +static char *blank_sector; /* Blank sector - all zeros */ +static int hidden_sectors = 0; /* Number of hidden sectors */ static int malloc_entire_fat = FALSE; /* Whether we should malloc() the entire FAT or not */ static int align_structures = TRUE; /* Whether to enforce alignment */ /* 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, off_t 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 unsigned long long count_blocks (char *filename); -static void check_mount (char *device_name); -static void establish_params (int device_num, int size); -static void setup_tables (void); -static void write_tables (void); - +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, off_t 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 unsigned long long count_blocks(char *filename); +static void check_mount(char *device_name); +static void establish_params(int device_num, int size); +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) +static void fatal_error(const char *fmt_string) { - fprintf (stderr, fmt_string, program_name, device_name); - exit (1); /* The error exit code is 1! */ + 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) +static void mark_FAT_cluster(int cluster, unsigned int value) { - switch( size_fat ) { + 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)); + 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); } - 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; + break; case 16: - value &= 0xffff; - fat[2 * cluster] = (unsigned char) (value & 0x00ff); - fat[(2 * cluster) + 1] = (unsigned char) (value >> 8); - break; + 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; + 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)"); - } + 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) +static void mark_FAT_sector(int sector, unsigned int value) { - int cluster; + 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!"); + 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); + 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, off_t current_block) +static long do_check(char *buffer, int try, off_t current_block) { - long got; + long got; - if (llseek (dev, current_block * BLOCK_SIZE, SEEK_SET) /* Seek to the correct location */ - != current_block * BLOCK_SIZE) - die ("seek failed during testing for blocks"); + if (llseek(dev, current_block * BLOCK_SIZE, SEEK_SET) /* Seek to the correct location */ + !=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; + 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; + if (got & (BLOCK_SIZE - 1)) + printf("Unexpected values in do_check: probably bugs\n"); + got /= BLOCK_SIZE; - return got; + return got; } - /* 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) +static void alarm_intr(int alnum) { - if (currently_testing >= blocks) - return; + if (currently_testing >= blocks) + return; - signal (SIGALRM, alarm_intr); - alarm (5); - if (!currently_testing) - return; + signal(SIGALRM, alarm_intr); + alarm(5); + if (!currently_testing) + return; - printf ("%lld... ", (unsigned long long)currently_testing); - fflush (stdout); + printf("%lld... ", (unsigned long long)currently_testing); + fflush(stdout); } - -static void -check_blocks (void) +static void check_blocks(void) { - int try, got; - int i; - static char blkbuf[BLOCK_SIZE * TEST_BUFFER_BLOCKS]; + int try, got; + int i; + static char blkbuf[BLOCK_SIZE * TEST_BUFFER_BLOCKS]; - if (verbose) - { - printf ("Searching for bad blocks "); - fflush (stdout); + if (verbose) { + printf("Searching for bad blocks "); + fflush(stdout); } - currently_testing = 0; - if (verbose) - { - signal (SIGALRM, alarm_intr); - alarm (5); + currently_testing = 0; + if (verbose) { + signal(SIGALRM, alarm_intr); + alarm(5); } - 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"); + 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++; + 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 (verbose) + printf("\n"); - if (badblocks) - printf ("%d bad block%s\n", badblocks, - (badblocks > 1) ? "s" : ""); + if (badblocks) + printf("%d bad block%s\n", badblocks, (badblocks > 1) ? "s" : ""); } - -static void -get_list_blocks (char *filename) +static void get_list_blocks(char *filename) { - int i; - FILE *listfile; - unsigned long blockno; + int i; + FILE *listfile; + unsigned long blockno; - listfile = fopen (filename, "r"); - if (listfile == (FILE *) NULL) - die ("Can't open file of bad blocks"); + 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++; + 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); + fclose(listfile); - if (badblocks) - printf ("%d bad block%s\n", badblocks, - (badblocks > 1) ? "s" : ""); + if (badblocks) + printf("%d bad block%s\n", badblocks, (badblocks > 1) ? "s" : ""); } - /* 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) +static int valid_offset(int fd, loff_t offset) { - char ch; + char ch; - if (llseek (fd, offset, SEEK_SET) < 0) - return FALSE; - if (read (fd, &ch, 1) < 1) - return FALSE; - return TRUE; + if (llseek(fd, offset, SEEK_SET) < 0) + return FALSE; + if (read(fd, &ch, 1) < 1) + return FALSE; + return TRUE; } - /* Given a filename, look to see how many blocks of BLOCK_SIZE are present, returning the answer */ -static unsigned long long -count_blocks (char *filename) +static unsigned long long count_blocks(char *filename) { - loff_t high, low; - int fd; + loff_t high, low; + int fd; - if ((fd = open (filename, O_RDONLY)) < 0) - { - perror (filename); - exit (1); + if ((fd = open(filename, O_RDONLY)) < 0) { + perror(filename); + exit(1); } - /* first try SEEK_END, which should work on most devices nowadays */ - if ((low = llseek(fd, 0, SEEK_END)) <= 0) { - 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; - } - ++low; - } + /* first try SEEK_END, which should work on most devices nowadays */ + if ((low = llseek(fd, 0, SEEK_END)) <= 0) { + 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; + } + ++low; + } - close (fd); - return low / BLOCK_SIZE; + close(fd); + return low / BLOCK_SIZE; } - /* Check to see if the specified device is currently mounted - abort if it is */ -static void -check_mount (char *device_name) +static void check_mount(char *device_name) { - FILE *f; - struct mntent *mnt; + 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); + 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); } - /* Establish the geometry and media parameters for the device */ -static void -establish_params (int device_num,int size) +static void establish_params(int device_num, int size) { - long loop_size; - struct hd_geometry geometry; - struct floppy_struct param; - int def_root_dir_entries = 512; + long loop_size; + struct hd_geometry geometry; + struct floppy_struct param; + int def_root_dir_entries = 512; - if ((0 == device_num) || ((device_num & 0xff00) == 0x0200)) - /* file image or floppy disk */ + if ((0 == device_num) || ((device_num & 0xff00) == 0x0200)) + /* file image or floppy disk */ { - if (0 == device_num) - { - param.size = size/512; - switch(param.size) - { + if (0 == device_num) { + param.size = size / 512; + switch (param.size) { case 720: - param.sect = 9 ; - param.head = 2; - break; + param.sect = 9; + param.head = 2; + break; case 1440: - param.sect = 9; - param.head = 2; - break; + param.sect = 9; + param.head = 2; + break; case 2400: - param.sect = 15; - param.head = 2; - break; + param.sect = 15; + param.head = 2; + break; case 2880: - param.sect = 18; - param.head = 2; - break; + param.sect = 18; + param.head = 2; + break; case 5760: - param.sect = 36; - param.head = 2; - break; + param.sect = 36; + param.head = 2; + break; default: - /* fake values */ - param.sect = 32; - param.head = 64; - break; + /* fake values */ + param.sect = 32; + param.head = 64; + break; } + } else { /* is a floppy diskette */ + + if (ioctl(dev, FDGETPRM, ¶m)) /* Can we get the diskette geometry? */ + die("unable to get diskette geometry for '%s'"); } - else /* is a floppy diskette */ - { - if (ioctl (dev, FDGETPRM, ¶m)) /* Can we get the diskette geometry? */ - die ("unable to get diskette geometry for '%s'"); - } - bs.secs_track = CT_LE_W(param.sect); /* Set up the geometry information */ - bs.heads = CT_LE_W(param.head); - switch (param.size) /* Set up the media descriptor byte */ - { + bs.secs_track = CT_LE_W(param.sect); /* Set up the geometry information */ + bs.heads = CT_LE_W(param.head); + switch (param.size) { /* Set up the media descriptor byte */ case 720: /* 5.25", 2, 9, 40 - 360K */ - bs.media = (char) 0xfd; - bs.cluster_size = (char) 2; - def_root_dir_entries = 112; - break; + bs.media = (char)0xfd; + bs.cluster_size = (char)2; + def_root_dir_entries = 112; + break; case 1440: /* 3.5", 2, 9, 80 - 720K */ - bs.media = (char) 0xf9; - bs.cluster_size = (char) 2; - def_root_dir_entries = 112; - break; + bs.media = (char)0xf9; + bs.cluster_size = (char)2; + def_root_dir_entries = 112; + break; case 2400: /* 5.25", 2, 15, 80 - 1200K */ - bs.media = (char) 0xf9; - bs.cluster_size = (char)(atari_format ? 2 : 1); - def_root_dir_entries = 224; - break; + bs.media = (char)0xf9; + bs.cluster_size = (char)(atari_format ? 2 : 1); + def_root_dir_entries = 224; + break; case 5760: /* 3.5", 2, 36, 80 - 2880K */ - bs.media = (char) 0xf0; - bs.cluster_size = (char) 2; - def_root_dir_entries = 224; - break; + bs.media = (char)0xf0; + bs.cluster_size = (char)2; + def_root_dir_entries = 224; + break; case 2880: /* 3.5", 2, 18, 80 - 1440K */ - floppy_default: - bs.media = (char) 0xf0; - bs.cluster_size = (char)(atari_format ? 2 : 1); - def_root_dir_entries = 224; - break; +floppy_default: + bs.media = (char)0xf0; + bs.cluster_size = (char)(atari_format ? 2 : 1); + def_root_dir_entries = 224; + break; default: /* Anything else */ - if (0 == device_num) - goto def_hd_params; - else - goto floppy_default; + if (0 == device_num) + goto def_hd_params; + else + goto floppy_default; } - } - else if ((device_num & 0xff00) == 0x0700) /* This is a loop device */ - { - if (ioctl (dev, BLKGETSIZE, &loop_size)) - die ("unable to get loop device size"); + } else if ((device_num & 0xff00) == 0x0700) { /* This is a loop device */ + if (ioctl(dev, BLKGETSIZE, &loop_size)) + die("unable to get loop device size"); - switch (loop_size) /* Assuming the loop device -> floppy later */ - { + switch (loop_size) { /* Assuming the loop device -> floppy later */ case 720: /* 5.25", 2, 9, 40 - 360K */ - bs.secs_track = CF_LE_W(9); - bs.heads = CF_LE_W(2); - bs.media = (char) 0xfd; - bs.cluster_size = (char) 2; - def_root_dir_entries = 112; - break; + bs.secs_track = CF_LE_W(9); + bs.heads = CF_LE_W(2); + bs.media = (char)0xfd; + bs.cluster_size = (char)2; + def_root_dir_entries = 112; + break; case 1440: /* 3.5", 2, 9, 80 - 720K */ - bs.secs_track = CF_LE_W(9); - bs.heads = CF_LE_W(2); - bs.media = (char) 0xf9; - bs.cluster_size = (char) 2; - def_root_dir_entries = 112; - break; + bs.secs_track = CF_LE_W(9); + bs.heads = CF_LE_W(2); + bs.media = (char)0xf9; + bs.cluster_size = (char)2; + def_root_dir_entries = 112; + break; case 2400: /* 5.25", 2, 15, 80 - 1200K */ - bs.secs_track = CF_LE_W(15); - bs.heads = CF_LE_W(2); - bs.media = (char) 0xf9; - bs.cluster_size = (char)(atari_format ? 2 : 1); - def_root_dir_entries = 224; - break; + bs.secs_track = CF_LE_W(15); + bs.heads = CF_LE_W(2); + bs.media = (char)0xf9; + bs.cluster_size = (char)(atari_format ? 2 : 1); + def_root_dir_entries = 224; + break; case 5760: /* 3.5", 2, 36, 80 - 2880K */ - bs.secs_track = CF_LE_W(36); - bs.heads = CF_LE_W(2); - bs.media = (char) 0xf0; - bs.cluster_size = (char) 2; - bs.dir_entries[0] = (char) 224; - bs.dir_entries[1] = (char) 0; - break; + bs.secs_track = CF_LE_W(36); + bs.heads = CF_LE_W(2); + bs.media = (char)0xf0; + bs.cluster_size = (char)2; + bs.dir_entries[0] = (char)224; + bs.dir_entries[1] = (char)0; + break; case 2880: /* 3.5", 2, 18, 80 - 1440K */ - bs.secs_track = CF_LE_W(18); - bs.heads = CF_LE_W(2); - bs.media = (char) 0xf0; - bs.cluster_size = (char)(atari_format ? 2 : 1); - def_root_dir_entries = 224; - break; + bs.secs_track = CF_LE_W(18); + bs.heads = CF_LE_W(2); + bs.media = (char)0xf0; + bs.cluster_size = (char)(atari_format ? 2 : 1); + def_root_dir_entries = 224; + break; default: /* Anything else: default hd setup */ - printf("Loop device does not match a floppy size, using " - "default hd params\n"); - bs.secs_track = CT_LE_W(32); /* these are fake values... */ - bs.heads = CT_LE_W(64); - goto def_hd_params; + printf("Loop device does not match a floppy size, using " + "default hd params\n"); + bs.secs_track = CT_LE_W(32); /* these are fake values... */ + bs.heads = CT_LE_W(64); + goto def_hd_params; + } + } else + /* Must be a hard disk then! */ + { + /* Can we get the drive geometry? (Note I'm not too sure about */ + /* whether to use HDIO_GETGEO or HDIO_REQ) */ + if (ioctl(dev, HDIO_GETGEO, &geometry) || geometry.sectors == 0 + || geometry.heads == 0) { + printf("unable to get drive geometry, using default 255/63\n"); + bs.secs_track = CT_LE_W(63); + bs.heads = CT_LE_W(255); + } else { + bs.secs_track = CT_LE_W(geometry.sectors); /* Set up the geometry information */ + bs.heads = CT_LE_W(geometry.heads); + } +def_hd_params: + bs.media = (char)0xf8; /* Set up the media descriptor for a hard drive */ + if (!size_fat && blocks * SECTORS_PER_BLOCK > 1064960) { + if (verbose) + printf("Auto-selecting FAT32 for large filesystem\n"); + size_fat = 32; + } + if (size_fat == 32) { + /* For FAT32, try to do the same as M$'s format command + * (see http://www.win.tue.nl/~aeb/linux/fs/fat/fatgen103.pdf p. 20): + * fs size <= 260M: 0.5k clusters + * fs size <= 8G: 4k clusters + * fs size <= 16G: 8k clusters + * fs size > 16G: 16k clusters + */ + unsigned long sz_mb = + (blocks + (1 << (20 - BLOCK_SIZE_BITS)) - 1) >> (20 - + BLOCK_SIZE_BITS); + bs.cluster_size = + sz_mb > 16 * 1024 ? 32 : sz_mb > 8 * 1024 ? 16 : sz_mb > + 260 ? 8 : 1; + } else { + /* FAT12 and FAT16: start at 4 sectors per cluster */ + bs.cluster_size = (char)4; } } - else - /* Must be a hard disk then! */ - { - /* Can we get the drive geometry? (Note I'm not too sure about */ - /* whether to use HDIO_GETGEO or HDIO_REQ) */ - if (ioctl (dev, HDIO_GETGEO, &geometry) || geometry.sectors == 0 || geometry.heads == 0) { - printf ("unable to get drive geometry, using default 255/63\n"); - bs.secs_track = CT_LE_W(63); - bs.heads = CT_LE_W(255); - } - else { - bs.secs_track = CT_LE_W(geometry.sectors); /* Set up the geometry information */ - bs.heads = CT_LE_W(geometry.heads); - } - def_hd_params: - bs.media = (char) 0xf8; /* Set up the media descriptor for a hard drive */ - if (!size_fat && blocks*SECTORS_PER_BLOCK > 1064960) { - if (verbose) printf("Auto-selecting FAT32 for large filesystem\n"); - size_fat = 32; - } - if (size_fat == 32) { - /* For FAT32, try to do the same as M$'s format command - * (see http://www.win.tue.nl/~aeb/linux/fs/fat/fatgen103.pdf p. 20): - * fs size <= 260M: 0.5k clusters - * fs size <= 8G: 4k clusters - * fs size <= 16G: 8k clusters - * fs size > 16G: 16k clusters - */ - unsigned long sz_mb = - (blocks+(1<<(20-BLOCK_SIZE_BITS))-1) >> (20-BLOCK_SIZE_BITS); - bs.cluster_size = sz_mb > 16*1024 ? 32 : - sz_mb > 8*1024 ? 16 : - sz_mb > 260 ? 8 : - 1; - } - else { - /* FAT12 and FAT16: start at 4 sectors per cluster */ - bs.cluster_size = (char) 4; - } - } - if (!root_dir_entries) - root_dir_entries = def_root_dir_entries; + if (!root_dir_entries) + root_dir_entries = def_root_dir_entries; } /* * If alignment is enabled, round the first argument up to the second; the * latter must be a power of two. */ -static unsigned int -align_object (unsigned int sectors, unsigned int clustsize) +static unsigned int align_object(unsigned int sectors, unsigned int clustsize) { - if (align_structures) - return (sectors + clustsize - 1) & ~(clustsize - 1); - else - return sectors; + if (align_structures) + return (sectors + clustsize - 1) & ~(clustsize - 1); + else + return sectors; } /* Create the filesystem data tables */ -static void -setup_tables (void) +static void setup_tables(void) { - unsigned num_sectors; - unsigned cluster_count = 0, fat_length; - struct tm *ctime; - struct msdos_volume_info *vi = (size_fat == 32 ? &bs.fat32.vi : &bs.oldfat.vi); + unsigned num_sectors; + unsigned cluster_count = 0, fat_length; + struct tm *ctime; + struct msdos_volume_info *vi = + (size_fat == 32 ? &bs.fat32.vi : &bs.oldfat.vi); - if (atari_format) - /* On Atari, the first few bytes of the boot sector are assigned - * differently: The jump code is only 2 bytes (and m68k machine code - * :-), then 6 bytes filler (ignored), then 3 byte serial number. */ - memcpy( bs.system_id-1, "mkdosf", 6 ); - else - strcpy (bs.system_id, "mkdosfs"); - if (sectors_per_cluster) - bs.cluster_size = (char) sectors_per_cluster; - if (size_fat == 32) - { - /* Under FAT32, the root dir is in a cluster chain, and this is - * signalled by bs.dir_entries being 0. */ - root_dir_entries = 0; + if (atari_format) + /* On Atari, the first few bytes of the boot sector are assigned + * differently: The jump code is only 2 bytes (and m68k machine code + * :-), then 6 bytes filler (ignored), then 3 byte serial number. */ + memcpy(bs.system_id - 1, "mkdosf", 6); + else + strcpy(bs.system_id, "mkdosfs"); + if (sectors_per_cluster) + bs.cluster_size = (char)sectors_per_cluster; + if (size_fat == 32) { + /* Under FAT32, the root dir is in a cluster chain, and this is + * signalled by bs.dir_entries being 0. */ + root_dir_entries = 0; } - if (atari_format) { - bs.system_id[5] = (unsigned char) (volume_id & 0x000000ff); - bs.system_id[6] = (unsigned char) ((volume_id & 0x0000ff00) >> 8); - bs.system_id[7] = (unsigned char) ((volume_id & 0x00ff0000) >> 16); - } - else { - vi->volume_id[0] = (unsigned char) (volume_id & 0x000000ff); - vi->volume_id[1] = (unsigned char) ((volume_id & 0x0000ff00) >> 8); - vi->volume_id[2] = (unsigned char) ((volume_id & 0x00ff0000) >> 16); - vi->volume_id[3] = (unsigned char) (volume_id >> 24); - } + if (atari_format) { + bs.system_id[5] = (unsigned char)(volume_id & 0x000000ff); + bs.system_id[6] = (unsigned char)((volume_id & 0x0000ff00) >> 8); + bs.system_id[7] = (unsigned char)((volume_id & 0x00ff0000) >> 16); + } else { + vi->volume_id[0] = (unsigned char)(volume_id & 0x000000ff); + vi->volume_id[1] = (unsigned char)((volume_id & 0x0000ff00) >> 8); + vi->volume_id[2] = (unsigned char)((volume_id & 0x00ff0000) >> 16); + vi->volume_id[3] = (unsigned char)(volume_id >> 24); + } - if (!atari_format) { - memcpy(vi->volume_label, volume_name, 11); + if (!atari_format) { + memcpy(vi->volume_label, volume_name, 11); - memcpy(bs.boot_jump, dummy_boot_jump, 3); - /* Patch in the correct offset to the boot code */ - bs.boot_jump[1] = ((size_fat == 32 ? - (char *)&bs.fat32.boot_code : - (char *)&bs.oldfat.boot_code) - - (char *)&bs) - 2; + memcpy(bs.boot_jump, dummy_boot_jump, 3); + /* Patch in the correct offset to the boot code */ + bs.boot_jump[1] = ((size_fat == 32 ? + (char *)&bs.fat32.boot_code : + (char *)&bs.oldfat.boot_code) - (char *)&bs) - 2; + + if (size_fat == 32) { + int offset = (char *)&bs.fat32.boot_code - + (char *)&bs + MESSAGE_OFFSET + 0x7c00; + if (dummy_boot_code[BOOTCODE_FAT32_SIZE - 1]) + printf("Warning: message too long; truncated\n"); + dummy_boot_code[BOOTCODE_FAT32_SIZE - 1] = 0; + memcpy(bs.fat32.boot_code, dummy_boot_code, BOOTCODE_FAT32_SIZE); + bs.fat32.boot_code[MSG_OFFSET_OFFSET] = offset & 0xff; + bs.fat32.boot_code[MSG_OFFSET_OFFSET + 1] = offset >> 8; + } else { + memcpy(bs.oldfat.boot_code, dummy_boot_code, BOOTCODE_SIZE); + } + bs.boot_sign = CT_LE_W(BOOT_SIGN); + } else { + memcpy(bs.boot_jump, dummy_boot_jump_m68k, 2); + } + if (verbose >= 2) + printf("Boot jump code is %02x %02x\n", + bs.boot_jump[0], bs.boot_jump[1]); + + if (!reserved_sectors) + reserved_sectors = (size_fat == 32) ? 32 : 1; + else { + if (size_fat == 32 && reserved_sectors < 2) + die("On FAT32 at least 2 reserved sectors are needed."); + } + bs.reserved = CT_LE_W(reserved_sectors); + if (verbose >= 2) + printf("Using %d reserved sectors\n", reserved_sectors); + bs.fats = (char)nr_fats; + if (!atari_format || size_fat == 32) + bs.hidden = CT_LE_L(hidden_sectors); + else { + /* In Atari format, hidden is a 16 bit field */ + __u16 hidden = CT_LE_W(hidden_sectors); + if (hidden_sectors & ~0xffff) + die("#hidden doesn't fit in 16bit field of Atari format\n"); + memcpy(&bs.hidden, &hidden, 2); + } + + num_sectors = (long long)blocks *BLOCK_SIZE / sector_size; + if (!atari_format) { + unsigned fatdata1216; /* Sectors for FATs + data area (FAT12/16) */ + unsigned fatdata32; /* Sectors for FATs + data area (FAT32) */ + unsigned fatlength12, fatlength16, fatlength32; + unsigned maxclust12, maxclust16, maxclust32; + unsigned clust12, clust16, clust32; + int maxclustsize; + unsigned root_dir_sectors = cdiv(root_dir_entries * 32, sector_size); + + /* + * If the filesystem is 8192 sectors or less (4 MB with 512-byte + * sectors, i.e. floppy size), don't align the data structures. + */ + if (num_sectors <= 8192) { + if (align_structures && verbose >= 2) + printf("Disabling alignment due to tiny filesystem\n"); + + align_structures = FALSE; + } + + if (sectors_per_cluster) + bs.cluster_size = maxclustsize = sectors_per_cluster; + else + /* An initial guess for bs.cluster_size should already be set */ + maxclustsize = 128; + + do { + fatdata32 = num_sectors + - align_object(reserved_sectors, bs.cluster_size); + fatdata1216 = fatdata32 + - align_object(root_dir_sectors, bs.cluster_size); + + if (verbose >= 2) + printf("Trying with %d sectors/cluster:\n", bs.cluster_size); + + /* The factor 2 below avoids cut-off errors for nr_fats == 1. + * The "nr_fats*3" is for the reserved first two FAT entries */ + clust12 = 2 * ((long long)fatdata1216 * sector_size + nr_fats * 3) / + (2 * (int)bs.cluster_size * sector_size + nr_fats * 3); + fatlength12 = cdiv(((clust12 + 2) * 3 + 1) >> 1, sector_size); + fatlength12 = align_object(fatlength12, bs.cluster_size); + /* Need to recalculate number of clusters, since the unused parts of the + * FATS and data area together could make up space for an additional, + * not really present cluster. */ + clust12 = (fatdata1216 - nr_fats * fatlength12) / bs.cluster_size; + maxclust12 = (fatlength12 * 2 * sector_size) / 3; + if (maxclust12 > MAX_CLUST_12) + maxclust12 = MAX_CLUST_12; + if (verbose >= 2) + printf("FAT12: #clu=%u, fatlen=%u, maxclu=%u, limit=%u\n", + clust12, fatlength12, maxclust12, MAX_CLUST_12); + if (clust12 > maxclust12 - 2) { + clust12 = 0; + if (verbose >= 2) + printf("FAT12: too much clusters\n"); + } + + clust16 = ((long long)fatdata1216 * sector_size + nr_fats * 4) / + ((int)bs.cluster_size * sector_size + nr_fats * 2); + fatlength16 = cdiv((clust16 + 2) * 2, sector_size); + fatlength16 = align_object(fatlength16, bs.cluster_size); + /* Need to recalculate number of clusters, since the unused parts of the + * FATS and data area together could make up space for an additional, + * not really present cluster. */ + clust16 = (fatdata1216 - nr_fats * fatlength16) / bs.cluster_size; + maxclust16 = (fatlength16 * sector_size) / 2; + if (maxclust16 > MAX_CLUST_16) + maxclust16 = MAX_CLUST_16; + if (verbose >= 2) + printf("FAT16: #clu=%u, fatlen=%u, maxclu=%u, limit=%u\n", + clust16, fatlength16, maxclust16, MAX_CLUST_16); + if (clust16 > maxclust16 - 2) { + if (verbose >= 2) + printf("FAT16: too much clusters\n"); + clust16 = 0; + } + /* The < 4078 avoids that the filesystem will be misdetected as having a + * 12 bit FAT. */ + if (clust16 < FAT12_THRESHOLD + && !(size_fat_by_user && size_fat == 16)) { + if (verbose >= 2) + printf(clust16 < FAT12_THRESHOLD ? + "FAT16: would be misdetected as FAT12\n" : + "FAT16: too much clusters\n"); + clust16 = 0; + } + + clust32 = ((long long)fatdata32 * sector_size + nr_fats * 8) / + ((int)bs.cluster_size * sector_size + nr_fats * 4); + fatlength32 = cdiv((clust32 + 2) * 4, sector_size); + fatlength32 = align_object(fatlength32, bs.cluster_size); + /* Need to recalculate number of clusters, since the unused parts of the + * FATS and data area together could make up space for an additional, + * not really present cluster. */ + clust32 = (fatdata32 - nr_fats * fatlength32) / bs.cluster_size; + maxclust32 = (fatlength32 * sector_size) / 4; + if (maxclust32 > MAX_CLUST_32) + maxclust32 = MAX_CLUST_32; + if (clust32 && clust32 < MIN_CLUST_32 + && !(size_fat_by_user && size_fat == 32)) { + clust32 = 0; + if (verbose >= 2) + printf("FAT32: not enough clusters (%d)\n", MIN_CLUST_32); + } + if (verbose >= 2) + printf("FAT32: #clu=%u, fatlen=%u, maxclu=%u, limit=%u\n", + clust32, fatlength32, maxclust32, MAX_CLUST_32); + if (clust32 > maxclust32) { + clust32 = 0; + if (verbose >= 2) + printf("FAT32: too much clusters\n"); + } + + if ((clust12 && (size_fat == 0 || size_fat == 12)) || + (clust16 && (size_fat == 0 || size_fat == 16)) || + (clust32 && size_fat == 32)) + break; + + bs.cluster_size <<= 1; + } while (bs.cluster_size && bs.cluster_size <= maxclustsize); + + /* Use the optimal FAT size if not specified; + * FAT32 is (not yet) choosen automatically */ + if (!size_fat) { + size_fat = (clust16 > clust12) ? 16 : 12; + if (verbose >= 2) + printf("Choosing %d bits for FAT\n", size_fat); + } + + switch (size_fat) { + case 12: + cluster_count = clust12; + fat_length = fatlength12; + bs.fat_length = CT_LE_W(fatlength12); + memcpy(vi->fs_type, MSDOS_FAT12_SIGN, 8); + break; + + case 16: + if (clust16 < FAT12_THRESHOLD) { + if (size_fat_by_user) { + fprintf(stderr, "WARNING: Not enough clusters for a " + "16 bit FAT! The filesystem will be\n" + "misinterpreted as having a 12 bit FAT without " + "mount option \"fat=16\".\n"); + } else { + fprintf(stderr, "This filesystem has an unfortunate size. " + "A 12 bit FAT cannot provide\n" + "enough clusters, but a 16 bit FAT takes up a little " + "bit more space so that\n" + "the total number of clusters becomes less than the " + "threshold value for\n" + "distinction between 12 and 16 bit FATs.\n"); + die("Make the file system a bit smaller manually."); + } + } + cluster_count = clust16; + fat_length = fatlength16; + bs.fat_length = CT_LE_W(fatlength16); + memcpy(vi->fs_type, MSDOS_FAT16_SIGN, 8); + break; + + case 32: + if (clust32 < MIN_CLUST_32) + fprintf(stderr, + "WARNING: Not enough clusters for a 32 bit FAT!\n"); + cluster_count = clust32; + fat_length = fatlength32; + bs.fat_length = CT_LE_W(0); + bs.fat32.fat32_length = CT_LE_L(fatlength32); + memcpy(vi->fs_type, MSDOS_FAT32_SIGN, 8); + root_dir_entries = 0; + break; + + default: + die("FAT not 12, 16 or 32 bits"); + } + + /* Adjust the reserved number of sectors for alignment */ + reserved_sectors = align_object(reserved_sectors, bs.cluster_size); + bs.reserved = CT_LE_W(reserved_sectors); + + /* Adjust the number of root directory entries to help enforce alignment */ + if (align_structures) { + root_dir_entries = align_object(root_dir_sectors, bs.cluster_size) + * (sector_size >> 5); + } + } else { + unsigned clusters, maxclust, fatdata; + + /* GEMDOS always uses a 12 bit FAT on floppies, and always a 16 bit FAT on + * hard disks. So use 12 bit if the size of the file system suggests that + * this fs is for a floppy disk, if the user hasn't explicitly requested a + * size. + */ + if (!size_fat) + size_fat = (num_sectors == 1440 || num_sectors == 2400 || + num_sectors == 2880 || num_sectors == 5760) ? 12 : 16; + if (verbose >= 2) + printf("Choosing %d bits for FAT\n", size_fat); + + /* Atari format: cluster size should be 2, except explicitly requested by + * the user, since GEMDOS doesn't like other cluster sizes very much. + * Instead, tune the sector size for the FS to fit. + */ + bs.cluster_size = sectors_per_cluster ? sectors_per_cluster : 2; + if (!sector_size_set) { + while (num_sectors > GEMDOS_MAX_SECTORS) { + num_sectors >>= 1; + sector_size <<= 1; + } + } + if (verbose >= 2) + printf("Sector size must be %d to have less than %d log. sectors\n", + sector_size, GEMDOS_MAX_SECTORS); + + /* Check if there are enough FAT indices for how much clusters we have */ + do { + fatdata = num_sectors - cdiv(root_dir_entries * 32, sector_size) - + reserved_sectors; + /* The factor 2 below avoids cut-off errors for nr_fats == 1 and + * size_fat == 12 + * The "2*nr_fats*size_fat/8" is for the reserved first two FAT entries + */ + clusters = + (2 * + ((long long)fatdata * sector_size - + 2 * nr_fats * size_fat / 8)) / (2 * ((int)bs.cluster_size * + sector_size + + nr_fats * size_fat / 8)); + fat_length = cdiv((clusters + 2) * size_fat / 8, sector_size); + /* Need to recalculate number of clusters, since the unused parts of the + * FATS and data area together could make up space for an additional, + * not really present cluster. */ + clusters = (fatdata - nr_fats * fat_length) / bs.cluster_size; + maxclust = (fat_length * sector_size * 8) / size_fat; + if (verbose >= 2) + printf("ss=%d: #clu=%d, fat_len=%d, maxclu=%d\n", + sector_size, clusters, fat_length, maxclust); + + /* last 10 cluster numbers are special (except FAT32: 4 high bits rsvd); + * first two numbers are reserved */ + if (maxclust <= + (size_fat == 32 ? MAX_CLUST_32 : (1 << size_fat) - 0x10) + && clusters <= maxclust - 2) + break; + if (verbose >= 2) + printf(clusters > maxclust - 2 ? + "Too many clusters\n" : "FAT too big\n"); + + /* need to increment sector_size once more to */ + if (sector_size_set) + die("With this sector size, the maximum number of FAT entries " + "would be exceeded."); + num_sectors >>= 1; + sector_size <<= 1; + } while (sector_size <= GEMDOS_MAX_SECTOR_SIZE); + + if (sector_size > GEMDOS_MAX_SECTOR_SIZE) + die("Would need a sector size > 16k, which GEMDOS can't work with"); + + cluster_count = clusters; + if (size_fat != 32) + bs.fat_length = CT_LE_W(fat_length); + else { + bs.fat_length = 0; + bs.fat32.fat32_length = CT_LE_L(fat_length); + } + } + + bs.sector_size[0] = (char)(sector_size & 0x00ff); + bs.sector_size[1] = (char)((sector_size & 0xff00) >> 8); + + bs.dir_entries[0] = (char)(root_dir_entries & 0x00ff); + bs.dir_entries[1] = (char)((root_dir_entries & 0xff00) >> 8); if (size_fat == 32) { - int offset = (char *)&bs.fat32.boot_code - - (char *)&bs + MESSAGE_OFFSET + 0x7c00; - if (dummy_boot_code[BOOTCODE_FAT32_SIZE-1]) - printf ("Warning: message too long; truncated\n"); - dummy_boot_code[BOOTCODE_FAT32_SIZE-1] = 0; - memcpy(bs.fat32.boot_code, dummy_boot_code, BOOTCODE_FAT32_SIZE); - bs.fat32.boot_code[MSG_OFFSET_OFFSET] = offset & 0xff; - bs.fat32.boot_code[MSG_OFFSET_OFFSET+1] = offset >> 8; - } - else { - memcpy(bs.oldfat.boot_code, dummy_boot_code, BOOTCODE_SIZE); - } - bs.boot_sign = CT_LE_W(BOOT_SIGN); - } - else { - memcpy(bs.boot_jump, dummy_boot_jump_m68k, 2); - } - if (verbose >= 2) - printf( "Boot jump code is %02x %02x\n", - bs.boot_jump[0], bs.boot_jump[1] ); - - if (!reserved_sectors) - reserved_sectors = (size_fat == 32) ? 32 : 1; - else { - if (size_fat == 32 && reserved_sectors < 2) - die("On FAT32 at least 2 reserved sectors are needed."); - } - bs.reserved = CT_LE_W(reserved_sectors); - if (verbose >= 2) - printf( "Using %d reserved sectors\n", reserved_sectors ); - bs.fats = (char) nr_fats; - if (!atari_format || size_fat == 32) - bs.hidden = CT_LE_L(hidden_sectors); - else { - /* In Atari format, hidden is a 16 bit field */ - __u16 hidden = CT_LE_W(hidden_sectors); - if (hidden_sectors & ~0xffff) - die("#hidden doesn't fit in 16bit field of Atari format\n"); - memcpy( &bs.hidden, &hidden, 2 ); - } - - num_sectors = (long long)blocks*BLOCK_SIZE/sector_size; - if (!atari_format) { - unsigned fatdata1216; /* Sectors for FATs + data area (FAT12/16) */ - unsigned fatdata32; /* Sectors for FATs + data area (FAT32) */ - unsigned fatlength12, fatlength16, fatlength32; - unsigned maxclust12, maxclust16, maxclust32; - unsigned clust12, clust16, clust32; - int maxclustsize; - unsigned root_dir_sectors = cdiv(root_dir_entries*32, sector_size); - - /* - * If the filesystem is 8192 sectors or less (4 MB with 512-byte - * sectors, i.e. floppy size), don't align the data structures. - */ - if (num_sectors <= 8192) { - if (align_structures && verbose >= 2) - printf ("Disabling alignment due to tiny filesystem\n"); - - align_structures = FALSE; + /* set up additional FAT32 fields */ + bs.fat32.flags = CT_LE_W(0); + bs.fat32.version[0] = 0; + bs.fat32.version[1] = 0; + bs.fat32.root_cluster = CT_LE_L(2); + bs.fat32.info_sector = CT_LE_W(1); + if (!backup_boot) + backup_boot = (reserved_sectors >= 7) ? 6 : + (reserved_sectors >= 2) ? reserved_sectors - 1 : 0; + else { + if (backup_boot == 1) + die("Backup boot sector must be after sector 1"); + else if (backup_boot >= reserved_sectors) + die("Backup boot sector must be a reserved sector"); + } + if (verbose >= 2) + printf("Using sector %d as backup boot sector (0 = none)\n", + backup_boot); + bs.fat32.backup_boot = CT_LE_W(backup_boot); + memset(&bs.fat32.reserved2, 0, sizeof(bs.fat32.reserved2)); } - if (sectors_per_cluster) - bs.cluster_size = maxclustsize = sectors_per_cluster; + if (atari_format) { + /* Just some consistency checks */ + if (num_sectors >= GEMDOS_MAX_SECTORS) + die("GEMDOS can't handle more than 65531 sectors"); + else if (num_sectors >= OLDGEMDOS_MAX_SECTORS) + printf("Warning: More than 32765 sector need TOS 1.04 " + "or higher.\n"); + } + if (num_sectors >= 65536) { + bs.sectors[0] = (char)0; + bs.sectors[1] = (char)0; + bs.total_sect = CT_LE_L(num_sectors); + } else { + bs.sectors[0] = (char)(num_sectors & 0x00ff); + bs.sectors[1] = (char)((num_sectors & 0xff00) >> 8); + if (!atari_format) + bs.total_sect = CT_LE_L(0); + } + + if (!atari_format) + vi->ext_boot_sign = MSDOS_EXT_SIGN; + + if (!cluster_count) { + if (sectors_per_cluster) /* If yes, die if we'd spec'd sectors per cluster */ + die("Too many clusters for file system - try more sectors per cluster"); + else + die("Attempting to create a too large file system"); + } + + /* The two following vars are in hard sectors, i.e. 512 byte sectors! */ + start_data_sector = (reserved_sectors + nr_fats * fat_length) * + (sector_size / HARD_SECTOR_SIZE); + start_data_block = (start_data_sector + SECTORS_PER_BLOCK - 1) / + SECTORS_PER_BLOCK; + + if (blocks < start_data_block + 32) /* Arbitrary undersize file system! */ + die("Too few blocks for viable file system"); + + if (verbose) { + printf("%s has %d head%s and %d sector%s per track,\n", + device_name, CF_LE_W(bs.heads), + (CF_LE_W(bs.heads) != 1) ? "s" : "", CF_LE_W(bs.secs_track), + (CF_LE_W(bs.secs_track) != 1) ? "s" : ""); + printf("logical sector size is %d,\n", sector_size); + printf("using 0x%02x media descriptor, with %d sectors;\n", + (int)(bs.media), num_sectors); + printf("file system has %d %d-bit FAT%s and %d sector%s per cluster.\n", + (int)(bs.fats), size_fat, (bs.fats != 1) ? "s" : "", + (int)(bs.cluster_size), (bs.cluster_size != 1) ? "s" : ""); + printf("FAT size is %d sector%s, and provides %d cluster%s.\n", + fat_length, (fat_length != 1) ? "s" : "", + cluster_count, (cluster_count != 1) ? "s" : ""); + printf("There %s %u reserved sector%s.\n", + (reserved_sectors != 1) ? "are" : "is", + reserved_sectors, (reserved_sectors != 1) ? "s" : ""); + + if (size_fat != 32) { + unsigned root_dir_entries = + bs.dir_entries[0] + ((bs.dir_entries[1]) * 256); + unsigned root_dir_sectors = + cdiv(root_dir_entries * 32, sector_size); + printf("Root directory contains %u slots and uses %u sectors.\n", + root_dir_entries, root_dir_sectors); + } + printf("Volume ID is %08lx, ", volume_id & + (atari_format ? 0x00ffffff : 0xffffffff)); + if (strcmp(volume_name, " ")) + printf("volume label %s.\n", volume_name); + else + printf("no volume label.\n"); + } + + /* Make the file allocation tables! */ + + if (malloc_entire_fat) + alloced_fat_length = fat_length; else - /* An initial guess for bs.cluster_size should already be set */ - maxclustsize = 128; + alloced_fat_length = 1; - do { - fatdata32 = num_sectors - - align_object(reserved_sectors, bs.cluster_size); - fatdata1216 = fatdata32 - - align_object(root_dir_sectors, bs.cluster_size); + if ((fat = + (unsigned char *)malloc(alloced_fat_length * sector_size)) == NULL) + die("unable to allocate space for FAT image in memory"); - if (verbose >= 2) - printf( "Trying with %d sectors/cluster:\n", bs.cluster_size ); + memset(fat, 0, alloced_fat_length * sector_size); - /* The factor 2 below avoids cut-off errors for nr_fats == 1. - * The "nr_fats*3" is for the reserved first two FAT entries */ - clust12 = 2*((long long) fatdata1216*sector_size + nr_fats*3) / - (2*(int) bs.cluster_size * sector_size + nr_fats*3); - fatlength12 = cdiv(((clust12+2) * 3 + 1) >> 1, sector_size); - fatlength12 = align_object(fatlength12, bs.cluster_size); - /* Need to recalculate number of clusters, since the unused parts of the - * FATS and data area together could make up space for an additional, - * not really present cluster. */ - clust12 = (fatdata1216 - nr_fats*fatlength12)/bs.cluster_size; - maxclust12 = (fatlength12 * 2 * sector_size) / 3; - if (maxclust12 > MAX_CLUST_12) - maxclust12 = MAX_CLUST_12; - if (verbose >= 2) - printf( "FAT12: #clu=%u, fatlen=%u, maxclu=%u, limit=%u\n", - clust12, fatlength12, maxclust12, MAX_CLUST_12 ); - if (clust12 > maxclust12-2) { - clust12 = 0; - if (verbose >= 2) - printf( "FAT12: too much clusters\n" ); - } - - clust16 = ((long long) fatdata1216 *sector_size + nr_fats*4) / - ((int) bs.cluster_size * sector_size + nr_fats*2); - fatlength16 = cdiv ((clust16+2) * 2, sector_size); - fatlength16 = align_object(fatlength16, bs.cluster_size); - /* Need to recalculate number of clusters, since the unused parts of the - * FATS and data area together could make up space for an additional, - * not really present cluster. */ - clust16 = (fatdata1216 - nr_fats*fatlength16)/bs.cluster_size; - maxclust16 = (fatlength16 * sector_size) / 2; - if (maxclust16 > MAX_CLUST_16) - maxclust16 = MAX_CLUST_16; - if (verbose >= 2) - printf( "FAT16: #clu=%u, fatlen=%u, maxclu=%u, limit=%u\n", - clust16, fatlength16, maxclust16, MAX_CLUST_16 ); - if (clust16 > maxclust16-2) { - if (verbose >= 2) - printf( "FAT16: too much clusters\n" ); - clust16 = 0; - } - /* The < 4078 avoids that the filesystem will be misdetected as having a - * 12 bit FAT. */ - if (clust16 < FAT12_THRESHOLD && !(size_fat_by_user && size_fat == 16)) { - if (verbose >= 2) - printf( clust16 < FAT12_THRESHOLD ? - "FAT16: would be misdetected as FAT12\n" : - "FAT16: too much clusters\n" ); - clust16 = 0; - } - - clust32 = ((long long) fatdata32 *sector_size + nr_fats*8) / - ((int) bs.cluster_size * sector_size + nr_fats*4); - fatlength32 = cdiv((clust32+2) * 4, sector_size); - fatlength32 = align_object(fatlength32, bs.cluster_size); - /* Need to recalculate number of clusters, since the unused parts of the - * FATS and data area together could make up space for an additional, - * not really present cluster. */ - clust32 = (fatdata32 - nr_fats*fatlength32)/bs.cluster_size; - maxclust32 = (fatlength32 * sector_size) / 4; - if (maxclust32 > MAX_CLUST_32) - maxclust32 = MAX_CLUST_32; - if (clust32 && clust32 < MIN_CLUST_32 && !(size_fat_by_user && size_fat == 32)) { - clust32 = 0; - if (verbose >= 2) - printf( "FAT32: not enough clusters (%d)\n", MIN_CLUST_32); - } - if (verbose >= 2) - printf( "FAT32: #clu=%u, fatlen=%u, maxclu=%u, limit=%u\n", - clust32, fatlength32, maxclust32, MAX_CLUST_32 ); - if (clust32 > maxclust32) { - clust32 = 0; - if (verbose >= 2) - printf( "FAT32: too much clusters\n" ); - } - - if ((clust12 && (size_fat == 0 || size_fat == 12)) || - (clust16 && (size_fat == 0 || size_fat == 16)) || - (clust32 && size_fat == 32)) - break; - - bs.cluster_size <<= 1; - } while (bs.cluster_size && bs.cluster_size <= maxclustsize); - - /* Use the optimal FAT size if not specified; - * FAT32 is (not yet) choosen automatically */ - if (!size_fat) { - size_fat = (clust16 > clust12) ? 16 : 12; - if (verbose >= 2) - printf( "Choosing %d bits for FAT\n", size_fat ); + mark_FAT_cluster(0, 0xffffffff); /* Initial fat entries */ + mark_FAT_cluster(1, 0xffffffff); + fat[0] = (unsigned char)bs.media; /* Put media type in first byte! */ + if (size_fat == 32) { + /* Mark cluster 2 as EOF (used for root dir) */ + mark_FAT_cluster(2, FAT_EOF); } - switch (size_fat) { - case 12: - cluster_count = clust12; - fat_length = fatlength12; - bs.fat_length = CT_LE_W(fatlength12); - memcpy(vi->fs_type, MSDOS_FAT12_SIGN, 8); - break; + /* Make the root directory entries */ - case 16: - if (clust16 < FAT12_THRESHOLD) { - if (size_fat_by_user) { - fprintf( stderr, "WARNING: Not enough clusters for a " - "16 bit FAT! The filesystem will be\n" - "misinterpreted as having a 12 bit FAT without " - "mount option \"fat=16\".\n" ); - } - else { - fprintf( stderr, "This filesystem has an unfortunate size. " - "A 12 bit FAT cannot provide\n" - "enough clusters, but a 16 bit FAT takes up a little " - "bit more space so that\n" - "the total number of clusters becomes less than the " - "threshold value for\n" - "distinction between 12 and 16 bit FATs.\n" ); - die( "Make the file system a bit smaller manually." ); - } - } - cluster_count = clust16; - fat_length = fatlength16; - bs.fat_length = CT_LE_W(fatlength16); - memcpy(vi->fs_type, MSDOS_FAT16_SIGN, 8); - break; - - case 32: - if (clust32 < MIN_CLUST_32) - fprintf(stderr, "WARNING: Not enough clusters for a 32 bit FAT!\n"); - cluster_count = clust32; - fat_length = fatlength32; - bs.fat_length = CT_LE_W(0); - bs.fat32.fat32_length = CT_LE_L(fatlength32); - memcpy(vi->fs_type, MSDOS_FAT32_SIGN, 8); - root_dir_entries = 0; - break; - - default: - die("FAT not 12, 16 or 32 bits"); + size_root_dir = (size_fat == 32) ? + bs.cluster_size * sector_size : + (((int)bs.dir_entries[1] * 256 + (int)bs.dir_entries[0]) * + sizeof(struct msdos_dir_entry)); + if ((root_dir = (struct msdos_dir_entry *)malloc(size_root_dir)) == NULL) { + free(fat); /* Tidy up before we die! */ + die("unable to allocate space for root directory in memory"); } - /* Adjust the reserved number of sectors for alignment */ - reserved_sectors = align_object(reserved_sectors, bs.cluster_size); - bs.reserved = CT_LE_W(reserved_sectors); - - /* Adjust the number of root directory entries to help enforce alignment */ - if (align_structures) { - root_dir_entries = align_object(root_dir_sectors, bs.cluster_size) - * (sector_size >> 5); - } - } - else { - unsigned clusters, maxclust, fatdata; - - /* GEMDOS always uses a 12 bit FAT on floppies, and always a 16 bit FAT on - * hard disks. So use 12 bit if the size of the file system suggests that - * this fs is for a floppy disk, if the user hasn't explicitly requested a - * size. - */ - if (!size_fat) - size_fat = (num_sectors == 1440 || num_sectors == 2400 || - num_sectors == 2880 || num_sectors == 5760) ? 12 : 16; - if (verbose >= 2) - printf( "Choosing %d bits for FAT\n", size_fat ); - - /* Atari format: cluster size should be 2, except explicitly requested by - * the user, since GEMDOS doesn't like other cluster sizes very much. - * Instead, tune the sector size for the FS to fit. - */ - bs.cluster_size = sectors_per_cluster ? sectors_per_cluster : 2; - if (!sector_size_set) { - while( num_sectors > GEMDOS_MAX_SECTORS ) { - num_sectors >>= 1; - sector_size <<= 1; - } - } - if (verbose >= 2) - printf( "Sector size must be %d to have less than %d log. sectors\n", - sector_size, GEMDOS_MAX_SECTORS ); - - /* Check if there are enough FAT indices for how much clusters we have */ - do { - fatdata = num_sectors - cdiv (root_dir_entries * 32, sector_size) - - reserved_sectors; - /* The factor 2 below avoids cut-off errors for nr_fats == 1 and - * size_fat == 12 - * The "2*nr_fats*size_fat/8" is for the reserved first two FAT entries - */ - clusters = (2*((long long)fatdata*sector_size - 2*nr_fats*size_fat/8)) / - (2*((int)bs.cluster_size*sector_size + nr_fats*size_fat/8)); - fat_length = cdiv( (clusters+2)*size_fat/8, sector_size ); - /* Need to recalculate number of clusters, since the unused parts of the - * FATS and data area together could make up space for an additional, - * not really present cluster. */ - clusters = (fatdata - nr_fats*fat_length)/bs.cluster_size; - maxclust = (fat_length*sector_size*8)/size_fat; - if (verbose >= 2) - printf( "ss=%d: #clu=%d, fat_len=%d, maxclu=%d\n", - sector_size, clusters, fat_length, maxclust ); - - /* last 10 cluster numbers are special (except FAT32: 4 high bits rsvd); - * first two numbers are reserved */ - if (maxclust <= (size_fat == 32 ? MAX_CLUST_32 : (1<= 2) - printf( clusters > maxclust-2 ? - "Too many clusters\n" : "FAT too big\n" ); - - /* need to increment sector_size once more to */ - if (sector_size_set) - die( "With this sector size, the maximum number of FAT entries " - "would be exceeded." ); - num_sectors >>= 1; - sector_size <<= 1; - } while( sector_size <= GEMDOS_MAX_SECTOR_SIZE ); - - if (sector_size > GEMDOS_MAX_SECTOR_SIZE) - die( "Would need a sector size > 16k, which GEMDOS can't work with"); - - cluster_count = clusters; - if (size_fat != 32) - bs.fat_length = CT_LE_W(fat_length); - else { - bs.fat_length = 0; - bs.fat32.fat32_length = CT_LE_L(fat_length); - } - } - - bs.sector_size[0] = (char) (sector_size & 0x00ff); - bs.sector_size[1] = (char) ((sector_size & 0xff00) >> 8); - - bs.dir_entries[0] = (char) (root_dir_entries & 0x00ff); - bs.dir_entries[1] = (char) ((root_dir_entries & 0xff00) >> 8); - - if (size_fat == 32) - { - /* set up additional FAT32 fields */ - bs.fat32.flags = CT_LE_W(0); - bs.fat32.version[0] = 0; - bs.fat32.version[1] = 0; - bs.fat32.root_cluster = CT_LE_L(2); - bs.fat32.info_sector = CT_LE_W(1); - if (!backup_boot) - backup_boot = (reserved_sectors >= 7) ? 6 : - (reserved_sectors >= 2) ? reserved_sectors-1 : 0; - else - { - if (backup_boot == 1) - die("Backup boot sector must be after sector 1"); - else if (backup_boot >= reserved_sectors) - die("Backup boot sector must be a reserved sector"); - } - if (verbose >= 2) - printf( "Using sector %d as backup boot sector (0 = none)\n", - backup_boot ); - bs.fat32.backup_boot = CT_LE_W(backup_boot); - memset( &bs.fat32.reserved2, 0, sizeof(bs.fat32.reserved2) ); + memset(root_dir, 0, size_root_dir); + if (memcmp(volume_name, " ", 11)) { + struct msdos_dir_entry *de = &root_dir[0]; + memcpy(de->name, volume_name, 8); + memcpy(de->ext, volume_name + 8, 3); + de->attr = ATTR_VOLUME; + ctime = localtime(&create_time); + de->time = CT_LE_W((unsigned short)((ctime->tm_sec >> 1) + + (ctime->tm_min << 5) + + (ctime->tm_hour << 11))); + de->date = + CT_LE_W((unsigned short)(ctime->tm_mday + + ((ctime->tm_mon + 1) << 5) + + ((ctime->tm_year - 80) << 9))); + de->ctime_ms = 0; + de->ctime = de->time; + de->cdate = de->date; + de->adate = de->date; + de->starthi = CT_LE_W(0); + de->start = CT_LE_W(0); + de->size = CT_LE_L(0); } - if (atari_format) { - /* Just some consistency checks */ - if (num_sectors >= GEMDOS_MAX_SECTORS) - die( "GEMDOS can't handle more than 65531 sectors" ); - else if (num_sectors >= OLDGEMDOS_MAX_SECTORS) - printf( "Warning: More than 32765 sector need TOS 1.04 " - "or higher.\n" ); - } - if (num_sectors >= 65536) - { - bs.sectors[0] = (char) 0; - bs.sectors[1] = (char) 0; - bs.total_sect = CT_LE_L(num_sectors); - } - else - { - bs.sectors[0] = (char) (num_sectors & 0x00ff); - bs.sectors[1] = (char) ((num_sectors & 0xff00) >> 8); - if (!atari_format) - bs.total_sect = CT_LE_L(0); + if (size_fat == 32) { + /* For FAT32, create an info sector */ + struct fat32_fsinfo *info; + + if (!(info_sector = malloc(sector_size))) + die("Out of memory"); + memset(info_sector, 0, sector_size); + /* fsinfo structure is at offset 0x1e0 in info sector by observation */ + info = (struct fat32_fsinfo *)(info_sector + 0x1e0); + + /* Info sector magic */ + info_sector[0] = 'R'; + info_sector[1] = 'R'; + info_sector[2] = 'a'; + info_sector[3] = 'A'; + + /* Magic for fsinfo structure */ + info->signature = CT_LE_L(0x61417272); + /* We've allocated cluster 2 for the root dir. */ + info->free_clusters = CT_LE_L(cluster_count - 1); + info->next_cluster = CT_LE_L(2); + + /* Info sector also must have boot sign */ + *(__u16 *) (info_sector + 0x1fe) = CT_LE_W(BOOT_SIGN); } - if (!atari_format) - vi->ext_boot_sign = MSDOS_EXT_SIGN; - - if (!cluster_count) - { - if (sectors_per_cluster) /* If yes, die if we'd spec'd sectors per cluster */ - die ("Too many clusters for file system - try more sectors per cluster"); - else - die ("Attempting to create a too large file system"); - } - - - /* The two following vars are in hard sectors, i.e. 512 byte sectors! */ - start_data_sector = (reserved_sectors + nr_fats * fat_length) * - (sector_size/HARD_SECTOR_SIZE); - start_data_block = (start_data_sector + SECTORS_PER_BLOCK - 1) / - SECTORS_PER_BLOCK; - - if (blocks < start_data_block + 32) /* Arbitrary undersize file system! */ - die ("Too few blocks for viable file system"); - - if (verbose) - { - printf("%s has %d head%s and %d sector%s per track,\n", - device_name, CF_LE_W(bs.heads), (CF_LE_W(bs.heads) != 1) ? "s" : "", - CF_LE_W(bs.secs_track), (CF_LE_W(bs.secs_track) != 1) ? "s" : ""); - printf("logical sector size is %d,\n",sector_size); - printf("using 0x%02x media descriptor, with %d sectors;\n", - (int) (bs.media), num_sectors); - printf("file system has %d %d-bit FAT%s and %d sector%s per cluster.\n", - (int) (bs.fats), size_fat, (bs.fats != 1) ? "s" : "", - (int) (bs.cluster_size), (bs.cluster_size != 1) ? "s" : ""); - printf ("FAT size is %d sector%s, and provides %d cluster%s.\n", - fat_length, (fat_length != 1) ? "s" : "", - cluster_count, (cluster_count != 1) ? "s" : ""); - printf ("There %s %u reserved sector%s.\n", - (reserved_sectors != 1) ? "are" : "is", - reserved_sectors, - (reserved_sectors != 1) ? "s" : ""); - - if (size_fat != 32) { - unsigned root_dir_entries = - bs.dir_entries[0] + ((bs.dir_entries[1]) * 256); - unsigned root_dir_sectors = - cdiv (root_dir_entries*32, sector_size); - printf ("Root directory contains %u slots and uses %u sectors.\n", - root_dir_entries, root_dir_sectors); - } - printf ("Volume ID is %08lx, ", volume_id & - (atari_format ? 0x00ffffff : 0xffffffff)); - if ( strcmp(volume_name, " ") ) - printf("volume label %s.\n", volume_name); - else - printf("no volume label.\n"); - } - - /* Make the file allocation tables! */ - - if (malloc_entire_fat) - alloced_fat_length = fat_length; - else - alloced_fat_length = 1; - - if ((fat = (unsigned char *) malloc (alloced_fat_length * sector_size)) == NULL) - die ("unable to allocate space for FAT image in memory"); - - memset( fat, 0, alloced_fat_length * sector_size ); - - mark_FAT_cluster (0, 0xffffffff); /* Initial fat entries */ - mark_FAT_cluster (1, 0xffffffff); - fat[0] = (unsigned char) bs.media; /* Put media type in first byte! */ - if (size_fat == 32) { - /* Mark cluster 2 as EOF (used for root dir) */ - mark_FAT_cluster (2, FAT_EOF); - } - - /* Make the root directory entries */ - - size_root_dir = (size_fat == 32) ? - bs.cluster_size*sector_size : - (((int)bs.dir_entries[1]*256+(int)bs.dir_entries[0]) * - sizeof (struct msdos_dir_entry)); - if ((root_dir = (struct msdos_dir_entry *) malloc (size_root_dir)) == NULL) - { - free (fat); /* Tidy up before we die! */ - die ("unable to allocate space for root directory in memory"); - } - - memset(root_dir, 0, size_root_dir); - if ( memcmp(volume_name, " ", 11) ) - { - struct msdos_dir_entry *de = &root_dir[0]; - memcpy(de->name, volume_name, 8); - memcpy(de->ext, volume_name+8, 3); - de->attr = ATTR_VOLUME; - ctime = localtime(&create_time); - de->time = CT_LE_W((unsigned short)((ctime->tm_sec >> 1) + - (ctime->tm_min << 5) + (ctime->tm_hour << 11))); - de->date = CT_LE_W((unsigned short)(ctime->tm_mday + - ((ctime->tm_mon+1) << 5) + - ((ctime->tm_year-80) << 9))); - de->ctime_ms = 0; - de->ctime = de->time; - de->cdate = de->date; - de->adate = de->date; - de->starthi = CT_LE_W(0); - de->start = CT_LE_W(0); - de->size = CT_LE_L(0); - } - - if (size_fat == 32) { - /* For FAT32, create an info sector */ - struct fat32_fsinfo *info; - - if (!(info_sector = malloc( sector_size ))) - die("Out of memory"); - memset(info_sector, 0, sector_size); - /* fsinfo structure is at offset 0x1e0 in info sector by observation */ - info = (struct fat32_fsinfo *)(info_sector + 0x1e0); - - /* Info sector magic */ - info_sector[0] = 'R'; - info_sector[1] = 'R'; - info_sector[2] = 'a'; - info_sector[3] = 'A'; - - /* Magic for fsinfo structure */ - info->signature = CT_LE_L(0x61417272); - /* We've allocated cluster 2 for the root dir. */ - info->free_clusters = CT_LE_L(cluster_count - 1); - info->next_cluster = CT_LE_L(2); - - /* Info sector also must have boot sign */ - *(__u16 *)(info_sector + 0x1fe) = CT_LE_W(BOOT_SIGN); - } - - if (!(blank_sector = malloc( sector_size ))) - die( "Out of memory" ); - memset(blank_sector, 0, sector_size); + if (!(blank_sector = malloc(sector_size))) + die("Out of memory"); + memset(blank_sector, 0, sector_size); } - /* Write the new filesystem's data tables to wherever they're going to end up! */ #define error(str) \ @@ -1364,61 +1310,57 @@ setup_tables (void) error ("failed whilst writing " errstr); \ } while(0) - -static void -write_tables (void) +static void write_tables(void) { - int x; - int fat_length; + int x; + int fat_length; - fat_length = (size_fat == 32) ? - CF_LE_L(bs.fat32.fat32_length) : CF_LE_W(bs.fat_length); + fat_length = (size_fat == 32) ? + CF_LE_L(bs.fat32.fat32_length) : CF_LE_W(bs.fat_length); - seekto( 0, "start of device" ); - /* clear all reserved sectors */ - for( x = 0; x < reserved_sectors; ++x ) - writebuf( blank_sector, sector_size, "reserved sector" ); - /* seek back to sector 0 and write the boot sector */ - seekto( 0, "boot sector" ); - writebuf( (char *) &bs, sizeof (struct msdos_boot_sector), "boot sector" ); - /* on FAT32, write the info sector and backup boot sector */ - if (size_fat == 32) - { - seekto( CF_LE_W(bs.fat32.info_sector)*sector_size, "info sector" ); - writebuf( info_sector, 512, "info sector" ); - if (backup_boot != 0) - { - seekto( backup_boot*sector_size, "backup boot sector" ); - writebuf( (char *) &bs, sizeof (struct msdos_boot_sector), - "backup boot sector" ); + seekto(0, "start of device"); + /* clear all reserved sectors */ + for (x = 0; x < reserved_sectors; ++x) + writebuf(blank_sector, sector_size, "reserved sector"); + /* seek back to sector 0 and write the boot sector */ + seekto(0, "boot sector"); + writebuf((char *)&bs, sizeof(struct msdos_boot_sector), "boot sector"); + /* on FAT32, write the info sector and backup boot sector */ + if (size_fat == 32) { + seekto(CF_LE_W(bs.fat32.info_sector) * sector_size, "info sector"); + writebuf(info_sector, 512, "info sector"); + if (backup_boot != 0) { + seekto(backup_boot * sector_size, "backup boot sector"); + writebuf((char *)&bs, sizeof(struct msdos_boot_sector), + "backup boot sector"); } } - /* seek to start of FATS and write them all */ - seekto( reserved_sectors*sector_size, "first FAT" ); - for (x = 1; x <= nr_fats; x++) { - int y; - int blank_fat_length = fat_length - alloced_fat_length; - writebuf( fat, alloced_fat_length * sector_size, "FAT" ); - for (y=0; y 0xffff) - { - printf ("Bad location for backup boot sector : %s\n", optarg); - usage (); - } - break; - - case 'c': /* c : Check FS as we build it */ - check = TRUE; - malloc_entire_fat = TRUE; /* Need to be able to mark clusters bad */ - break; - - case 'C': /* C : Create a new file */ - create = TRUE; - break; - - case 'f': /* f : Choose number of FATs */ - nr_fats = (int) strtol (optarg, &tmp, 0); - if (*tmp || nr_fats < 1 || nr_fats > 4) - { - printf ("Bad number of FATs : %s\n", optarg); - usage (); - } - break; - - case 'F': /* F : Choose FAT size */ - size_fat = (int) strtol (optarg, &tmp, 0); - if (*tmp || (size_fat != 12 && size_fat != 16 && size_fat != 32)) - { - printf ("Bad FAT type : %s\n", optarg); - usage (); - } - size_fat_by_user = 1; - break; - - case 'h': /* h : number of hidden sectors */ - hidden_sectors = (int) strtol (optarg, &tmp, 0); - if ( *tmp || hidden_sectors < 0 ) - { - printf("Bad number of hidden sectors : %s\n", optarg); - usage (); - } - break; - - case 'I': - ignore_full_disk = 1; - break; - - case 'i': /* i : specify volume ID */ - volume_id = strtoul(optarg, &tmp, 16); - if ( *tmp ) - { - printf("Volume ID must be a hexadecimal number\n"); - usage(); - } - break; - - case 'l': /* l : Bad block filename */ - listfile = optarg; - malloc_entire_fat = TRUE; /* Need to be able to mark clusters bad */ - break; - - case 'm': /* m : Set boot message */ - if ( strcmp(optarg, "-") ) - { - msgfile = fopen(optarg, "r"); - if ( !msgfile ) - perror(optarg); - } - else - msgfile = stdin; - - if ( msgfile ) - { - /* The boot code ends at offset 448 and needs a null terminator */ - i = MESSAGE_OFFSET; - pos = 0; /* We are at beginning of line */ - do - { - ch = getc(msgfile); - switch (ch) - { - case '\r': /* Ignore CRs */ - case '\0': /* and nulls */ - break; - - case '\n': /* LF -> CR+LF if necessary */ - if ( pos ) /* If not at beginning of line */ - { - dummy_boot_code[i++] = '\r'; - pos = 0; - } - dummy_boot_code[i++] = '\n'; - break; - - case '\t': /* Expand tabs */ - do - { - dummy_boot_code[i++] = ' '; - pos++; - } - while ( pos % 8 && i < BOOTCODE_SIZE-1 ); - break; - - case EOF: - dummy_boot_code[i++] = '\0'; /* Null terminator */ - break; - - default: - dummy_boot_code[i++] = ch; /* Store character */ - pos++; /* Advance position */ - break; - } - } - while ( ch != EOF && i < BOOTCODE_SIZE-1 ); - - /* Fill up with zeros */ - while( i < BOOTCODE_SIZE-1 ) - dummy_boot_code[i++] = '\0'; - dummy_boot_code[BOOTCODE_SIZE-1] = '\0'; /* Just in case */ - - if ( ch != EOF ) - printf ("Warning: message too long; truncated\n"); - - if ( msgfile != stdin ) - fclose(msgfile); - } - break; - - case 'n': /* n : Volume name */ - sprintf(volume_name, "%-11.11s", optarg); - break; - - case 'r': /* r : Root directory entries */ - root_dir_entries = (int) strtol (optarg, &tmp, 0); - if (*tmp || root_dir_entries < 16 || root_dir_entries > 32768) - { - printf ("Bad number of root directory entries : %s\n", optarg); - usage (); - } - break; - - case 'R': /* R : number of reserved sectors */ - reserved_sectors = (int) strtol (optarg, &tmp, 0); - if (*tmp || reserved_sectors < 1 || reserved_sectors > 0xffff) - { - printf ("Bad number of reserved sectors : %s\n", optarg); - usage (); - } - break; - - case 's': /* s : Sectors per cluster */ - sectors_per_cluster = (int) strtol (optarg, &tmp, 0); - if (*tmp || (sectors_per_cluster != 1 && sectors_per_cluster != 2 - && sectors_per_cluster != 4 && sectors_per_cluster != 8 - && sectors_per_cluster != 16 && sectors_per_cluster != 32 - && sectors_per_cluster != 64 && sectors_per_cluster != 128)) - { - printf ("Bad number of sectors per cluster : %s\n", optarg); - usage (); - } - break; - - case 'S': /* S : Sector size */ - sector_size = (int) strtol (optarg, &tmp, 0); - if (*tmp || (sector_size != 512 && sector_size != 1024 && - sector_size != 2048 && sector_size != 4096 && - sector_size != 8192 && sector_size != 16384 && - sector_size != 32768)) - { - printf ("Bad logical sector size : %s\n", optarg); - usage (); - } - sector_size_set = 1; - break; - - case 'v': /* v : Verbose execution */ - ++verbose; - break; - - default: - printf( "Unknown option: %c\n", c ); - usage (); - } - if (optind < argc) - { - device_name = argv[optind]; /* Determine the number of blocks in the FS */ - - if (!device_name) { - printf("No device specified.\n"); - usage(); - } - - if (!create) - cblocks = count_blocks (device_name); /* Have a look and see! */ + if (argc && *argv) { /* What's the program name? */ + char *p; + program_name = *argv; + if ((p = strrchr(program_name, '/'))) + program_name = p + 1; } - if (optind == argc - 2) /* Either check the user specified number */ - { - blocks = strtoull (argv[optind + 1], &tmp, 0); - if (!create && blocks != cblocks) - { - fprintf (stderr, "Warning: block count mismatch: "); - fprintf (stderr, "found %llu but assuming %llu.\n",cblocks,blocks); + + gettimeofday(&create_timeval, NULL); + create_time = create_timeval.tv_sec; + volume_id = (u_int32_t) ((create_timeval.tv_sec << 20) | create_timeval.tv_usec); /* Default volume ID = creation time, fudged for more uniqueness */ + check_atari(); + + printf("%s " VERSION " (" VERSION_DATE ")\n", program_name); + + while ((c = getopt(argc, argv, "aAb:cCf:F:Ii:l:m:n:r:R:s:S:h:v")) != EOF) + /* Scan the command line for options */ + switch (c) { + case 'A': /* toggle Atari format */ + atari_format = !atari_format; + break; + + case 'a': /* a : skip alignment */ + align_structures = FALSE; + break; + + case 'b': /* b : location of backup boot sector */ + backup_boot = (int)strtol(optarg, &tmp, 0); + if (*tmp || backup_boot < 2 || backup_boot > 0xffff) { + printf("Bad location for backup boot sector : %s\n", optarg); + usage(); + } + break; + + case 'c': /* c : Check FS as we build it */ + check = TRUE; + malloc_entire_fat = TRUE; /* Need to be able to mark clusters bad */ + break; + + case 'C': /* C : Create a new file */ + create = TRUE; + break; + + case 'f': /* f : Choose number of FATs */ + nr_fats = (int)strtol(optarg, &tmp, 0); + if (*tmp || nr_fats < 1 || nr_fats > 4) { + printf("Bad number of FATs : %s\n", optarg); + usage(); + } + break; + + case 'F': /* F : Choose FAT size */ + size_fat = (int)strtol(optarg, &tmp, 0); + if (*tmp || (size_fat != 12 && size_fat != 16 && size_fat != 32)) { + printf("Bad FAT type : %s\n", optarg); + usage(); + } + size_fat_by_user = 1; + break; + + case 'h': /* h : number of hidden sectors */ + hidden_sectors = (int)strtol(optarg, &tmp, 0); + if (*tmp || hidden_sectors < 0) { + printf("Bad number of hidden sectors : %s\n", optarg); + usage(); + } + break; + + case 'I': + ignore_full_disk = 1; + break; + + case 'i': /* i : specify volume ID */ + volume_id = strtoul(optarg, &tmp, 16); + if (*tmp) { + printf("Volume ID must be a hexadecimal number\n"); + usage(); + } + break; + + case 'l': /* l : Bad block filename */ + listfile = optarg; + malloc_entire_fat = TRUE; /* Need to be able to mark clusters bad */ + break; + + case 'm': /* m : Set boot message */ + if (strcmp(optarg, "-")) { + msgfile = fopen(optarg, "r"); + if (!msgfile) + perror(optarg); + } else + msgfile = stdin; + + if (msgfile) { + /* The boot code ends at offset 448 and needs a null terminator */ + i = MESSAGE_OFFSET; + pos = 0; /* We are at beginning of line */ + do { + ch = getc(msgfile); + switch (ch) { + case '\r': /* Ignore CRs */ + case '\0': /* and nulls */ + break; + + case '\n': /* LF -> CR+LF if necessary */ + if (pos) { /* If not at beginning of line */ + dummy_boot_code[i++] = '\r'; + pos = 0; + } + dummy_boot_code[i++] = '\n'; + break; + + case '\t': /* Expand tabs */ + do { + dummy_boot_code[i++] = ' '; + pos++; + } + while (pos % 8 && i < BOOTCODE_SIZE - 1); + break; + + case EOF: + dummy_boot_code[i++] = '\0'; /* Null terminator */ + break; + + default: + dummy_boot_code[i++] = ch; /* Store character */ + pos++; /* Advance position */ + break; + } + } + while (ch != EOF && i < BOOTCODE_SIZE - 1); + + /* Fill up with zeros */ + while (i < BOOTCODE_SIZE - 1) + dummy_boot_code[i++] = '\0'; + dummy_boot_code[BOOTCODE_SIZE - 1] = '\0'; /* Just in case */ + + if (ch != EOF) + printf("Warning: message too long; truncated\n"); + + if (msgfile != stdin) + fclose(msgfile); + } + break; + + case 'n': /* n : Volume name */ + sprintf(volume_name, "%-11.11s", optarg); + break; + + case 'r': /* r : Root directory entries */ + root_dir_entries = (int)strtol(optarg, &tmp, 0); + if (*tmp || root_dir_entries < 16 || root_dir_entries > 32768) { + printf("Bad number of root directory entries : %s\n", optarg); + usage(); + } + break; + + case 'R': /* R : number of reserved sectors */ + reserved_sectors = (int)strtol(optarg, &tmp, 0); + if (*tmp || reserved_sectors < 1 || reserved_sectors > 0xffff) { + printf("Bad number of reserved sectors : %s\n", optarg); + usage(); + } + break; + + case 's': /* s : Sectors per cluster */ + sectors_per_cluster = (int)strtol(optarg, &tmp, 0); + if (*tmp || (sectors_per_cluster != 1 && sectors_per_cluster != 2 + && sectors_per_cluster != 4 && sectors_per_cluster != 8 + && sectors_per_cluster != 16 + && sectors_per_cluster != 32 + && sectors_per_cluster != 64 + && sectors_per_cluster != 128)) { + printf("Bad number of sectors per cluster : %s\n", optarg); + usage(); + } + break; + + case 'S': /* S : Sector size */ + sector_size = (int)strtol(optarg, &tmp, 0); + if (*tmp || (sector_size != 512 && sector_size != 1024 && + sector_size != 2048 && sector_size != 4096 && + sector_size != 8192 && sector_size != 16384 && + sector_size != 32768)) { + printf("Bad logical sector size : %s\n", optarg); + usage(); + } + sector_size_set = 1; + break; + + case 'v': /* v : Verbose execution */ + ++verbose; + break; + + default: + printf("Unknown option: %c\n", c); + usage(); + } + if (optind < argc) { + device_name = argv[optind]; /* Determine the number of blocks in the FS */ + + if (!device_name) { + printf("No device specified.\n"); + usage(); + } + + if (!create) + cblocks = count_blocks(device_name); /* Have a look and see! */ + } + if (optind == argc - 2) { /* Either check the user specified number */ + blocks = strtoull(argv[optind + 1], &tmp, 0); + if (!create && blocks != cblocks) { + fprintf(stderr, "Warning: block count mismatch: "); + fprintf(stderr, "found %llu but assuming %llu.\n", cblocks, blocks); + } + } else if (optind == argc - 1) { /* Or use value found */ + if (create) + die("Need intended size with -C."); + blocks = cblocks; + tmp = ""; + } else { + fprintf(stderr, "No device specified!\n"); + usage(); + } + if (*tmp) { + printf("Bad block count : %s\n", argv[optind + 1]); + usage(); + } + + if (check && listfile) /* Auto and specified bad block handling are mutually */ + die("-c and -l are incompatible"); /* exclusive of each other! */ + + if (!create) { + check_mount(device_name); /* Is the device already mounted? */ + dev = open(device_name, O_EXCL | O_RDWR); /* Is it a suitable device to build the FS on? */ + if (dev < 0) { + fprintf(stderr, "%s: unable to open %s: %s\n", program_name, + device_name, strerror(errno)); + exit(1); /* The error exit code is 1! */ + } + } else { + loff_t offset = blocks * BLOCK_SIZE - 1; + char null = 0; + /* create the file */ + dev = open(device_name, O_EXCL | O_RDWR | O_CREAT | O_TRUNC, 0666); + if (dev < 0) + die("unable to create %s"); + /* seek to the intended end-1, and write one byte. this creates a + * sparse-as-possible file of appropriate size. */ + if (llseek(dev, offset, SEEK_SET) != offset) + die("seek failed"); + if (write(dev, &null, 1) < 0) + die("write failed"); + if (llseek(dev, 0, SEEK_SET) != 0) + die("seek failed"); + } + + if (fstat(dev, &statbuf) < 0) + die("unable to stat %s"); + if (!S_ISBLK(statbuf.st_mode)) { + statbuf.st_rdev = 0; + check = 0; + } else + /* + * Ignore any 'full' fixed disk devices, if -I is not given. + * On a MO-disk one doesn't need partitions. The filesytem can go + * directly to the whole disk. Under other OSes this is known as + * the 'superfloppy' format. As I don't know how to find out if + * this is a MO disk I introduce a -I (ignore) switch. -Joey + */ + if (!ignore_full_disk && ((statbuf.st_rdev & 0xff3f) == 0x0300 || /* hda, hdb */ + (statbuf.st_rdev & 0xff0f) == 0x0800 || /* sd */ + (statbuf.st_rdev & 0xff3f) == 0x0d00 || /* xd */ + (statbuf.st_rdev & 0xff3f) == 0x1600) /* hdc, hdd */ + ) + die("Device partition expected, not making filesystem on entire device '%s' (use -I to override)"); + + if (sector_size_set) { + if (ioctl(dev, BLKSSZGET, &min_sector_size) >= 0) + if (sector_size < min_sector_size) { + sector_size = min_sector_size; + fprintf(stderr, + "Warning: sector size was set to %d (minimal for this device)\n", + sector_size); + } + } else { + if (ioctl(dev, BLKSSZGET, &min_sector_size) >= 0) { + sector_size = min_sector_size; + sector_size_set = 1; } } - else if (optind == argc - 1) /* Or use value found */ - { - if (create) - die( "Need intended size with -C." ); - blocks = cblocks; - tmp = ""; - } - else - { - fprintf (stderr, "No device specified!\n"); - usage (); - } - if (*tmp) - { - printf ("Bad block count : %s\n", argv[optind + 1]); - usage (); - } - if (check && listfile) /* Auto and specified bad block handling are mutually */ - die ("-c and -l are incompatible"); /* exclusive of each other! */ + if (sector_size > 4096) + fprintf(stderr, + "Warning: sector size is set to %d > 4096, such filesystem will not propably mount\n", + sector_size); - if (!create) { - check_mount (device_name); /* Is the device already mounted? */ - dev = open (device_name, O_EXCL|O_RDWR); /* Is it a suitable device to build the FS on? */ - if (dev < 0) { - fprintf (stderr, "%s: unable to open %s: %s\n", program_name, device_name, strerror(errno)); - exit (1); /* The error exit code is 1! */ - } - } - else { - loff_t offset = blocks*BLOCK_SIZE - 1; - char null = 0; - /* create the file */ - dev = open( device_name, O_EXCL|O_RDWR|O_CREAT|O_TRUNC, 0666 ); - if (dev < 0) - die("unable to create %s"); - /* seek to the intended end-1, and write one byte. this creates a - * sparse-as-possible file of appropriate size. */ - if (llseek( dev, offset, SEEK_SET ) != offset) - die( "seek failed" ); - if (write( dev, &null, 1 ) < 0) - die( "write failed" ); - if (llseek( dev, 0, SEEK_SET ) != 0) - die( "seek failed" ); - } + establish_params(statbuf.st_rdev, statbuf.st_size); + /* Establish the media parameters */ - if (fstat (dev, &statbuf) < 0) - die ("unable to stat %s"); - if (!S_ISBLK (statbuf.st_mode)) { - statbuf.st_rdev = 0; - check = 0; - } - else - /* - * Ignore any 'full' fixed disk devices, if -I is not given. - * On a MO-disk one doesn't need partitions. The filesytem can go - * directly to the whole disk. Under other OSes this is known as - * the 'superfloppy' format. As I don't know how to find out if - * this is a MO disk I introduce a -I (ignore) switch. -Joey - */ - if (!ignore_full_disk && ( - (statbuf.st_rdev & 0xff3f) == 0x0300 || /* hda, hdb */ - (statbuf.st_rdev & 0xff0f) == 0x0800 || /* sd */ - (statbuf.st_rdev & 0xff3f) == 0x0d00 || /* xd */ - (statbuf.st_rdev & 0xff3f) == 0x1600 ) /* hdc, hdd */ - ) - die ("Device partition expected, not making filesystem on entire device '%s' (use -I to override)"); + setup_tables(); /* Establish the file system tables */ - if (sector_size_set) - { - if (ioctl(dev, BLKSSZGET, &min_sector_size) >= 0) - if (sector_size < min_sector_size) - { - sector_size = min_sector_size; - fprintf(stderr, "Warning: sector size was set to %d (minimal for this device)\n", sector_size); - } - } - else - { - if (ioctl(dev, BLKSSZGET, &min_sector_size) >= 0) - { - sector_size = min_sector_size; - sector_size_set = 1; - } - } + if (check) /* Determine any bad block locations and mark them */ + check_blocks(); + else if (listfile) + get_list_blocks(listfile); - if (sector_size > 4096) - fprintf(stderr, - "Warning: sector size is set to %d > 4096, such filesystem will not propably mount\n", - sector_size); + write_tables(); /* Write the file system tables away! */ - establish_params (statbuf.st_rdev,statbuf.st_size); - /* Establish the media parameters */ - - setup_tables (); /* Establish the file system tables */ - - if (check) /* Determine any bad block locations and mark them */ - check_blocks (); - else if (listfile) - get_list_blocks (listfile); - - write_tables (); /* Write the file system tables away! */ - - exit (0); /* Terminate with no errors! */ + exit(0); /* Terminate with no errors! */ }