Index: vendors/Nintendo/DLDI/config.vendor =================================================================== --- vendors/Nintendo/DLDI/config.vendor (revision 1879) +++ vendors/Nintendo/DLDI/config.vendor (working copy) @@ -186,7 +186,7 @@ # MSDOS # # CONFIG_USER_DOSFSTOOLS_MKDOSFS is not set -# CONFIG_USER_DOSFSTOOLS_DOSFSCK is not set +CONFIG_USER_DOSFSTOOLS_DOSFSCK=y # # Network Applications Index: user/dosfstools/dosfsck/dosfsck.h =================================================================== --- user/dosfstools/dosfsck/dosfsck.h (revision 1879) +++ user/dosfstools/dosfsck/dosfsck.h (working copy) @@ -13,21 +13,35 @@ #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 */ -#include -#ifndef MSDOS_FAT12 -#define MSDOS_FAT12 4084 /* maximum number of clusters in a 12 bit FAT */ +#include +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) +# define __KERNEL__ +# include +# include +# undef __KERNEL__ #endif -/* 2.1 kernels use le16_to_cpu() type functions for CF_LE_W & Co., but don't - * export this macros, only __le16_to_cpu(). */ -#ifndef le16_to_cpu -#define le16_to_cpu __le16_to_cpu -#define le32_to_cpu __le32_to_cpu -#define cpu_to_le16 __cpu_to_le16 -#define cpu_to_le32 __cpu_to_le32 -#endif +#include +#undef CF_LE_W +#undef CF_LE_L +#undef CT_LE_W +#undef CT_LE_L + +#if __BYTE_ORDER == __BIG_ENDIAN +#include +#define CF_LE_W(v) bswap_16(v) +#define CF_LE_L(v) bswap_32(v) +#define CT_LE_W(v) CF_LE_W(v) +#define CT_LE_L(v) CF_LE_L(v) +#else +#define CF_LE_W(v) (v) +#define CF_LE_L(v) (v) +#define CT_LE_W(v) (v) +#define CT_LE_L(v) (v) +#endif /* __BIG_ENDIAN */ + #define VFAT_LN_ATTR (ATTR_RO | ATTR_HIDDEN | ATTR_SYS | ATTR_VOLUME) /* ++roman: Use own definition of boot sector structure -- the kernel headers' @@ -75,7 +89,7 @@ }; typedef struct { - __s8 name[8],ext[3]; /* name and extension */ + __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 */ Index: user/dosfstools/dosfsck/boot.c =================================================================== --- user/dosfstools/dosfsck/boot.c (revision 1879) +++ user/dosfstools/dosfsck/boot.c (working copy) @@ -34,13 +34,13 @@ { 0xff, "5.25\" 320k floppy 2s/40tr/8sec" }, }; -#if defined __alpha || defined __ia64__ || defined __s390x__ || defined __x86_64__ || defined __ppc64__ +#if defined __alpha || defined __ia64__ || defined __s390x__ || defined __x86_64__ || defined __ppc64__ || __arm__ /* Unaligned fields must first be copied byte-wise */ #define GET_UNALIGNED_W(f) \ ({ \ unsigned short __v; \ memcpy( &__v, &f, sizeof(__v) ); \ - CF_LE_W( *(unsigned short *)&f ); \ + CF_LE_W( *(unsigned short *)&__v ); \ }) #else #define GET_UNALIGNED_W(f) CF_LE_W( *(unsigned short *)&f ) @@ -80,22 +80,25 @@ 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",fs->fat_start, - fs->fat_start/lss); + 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); if (!fs->root_cluster) { printf("Root directory starts at byte %llu (sector %llu)\n", - fs->root_start,fs->root_start/lss); + (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); } - printf("Data area starts at byte %llu (sector %llu)\n",fs->data_start, - fs->data_start/lss); + 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), @@ -137,7 +140,7 @@ 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), + fs_write((off_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; @@ -158,8 +161,8 @@ for( p = (__u8 *)b, q = (__u8 *)&b2, i = 0; i < sizeof(b2); ++p, ++q, ++i ) { if (*p != *q) { - sprintf( buf, "%s%d:%02x/%02x", first ? "" : ", ", - p-(__u8 *)b, *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 ); pos += strlen(buf); @@ -212,9 +215,9 @@ 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((off_t)s*lss,sizeof(i),&i); b->info_sector = CT_LE_W(s); - fs_write((loff_t)offsetof(struct boot_sector,info_sector), + fs_write((off_t)offsetof(struct boot_sector,info_sector), sizeof(b->info_sector),&b->info_sector); if (fs->backupboot_start) fs_write(fs->backupboot_start+ @@ -238,16 +241,16 @@ 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 %d: 0x%08x != expected 0x%08x\n", - offsetof(struct info_sector,magic), + 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 %d: 0x%08x != expected 0x%08x\n", - offsetof(struct info_sector,signature), + 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 %d: 0x%04x != expected 0x%04x\n", - offsetof(struct info_sector,boot_sign), + 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" ); @@ -269,7 +272,7 @@ unsigned total_sectors; unsigned short logical_sector_size, sectors; unsigned fat_length; - loff_t data_size; + off_t data_size; fs_read(0,sizeof(b),&b); logical_sector_size = GET_UNALIGNED_W(b.sector_size); @@ -283,17 +286,17 @@ total_sectors = sectors ? sectors : CF_LE_L(b.total_sect); 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((off_t)((total_sectors & ~1)-1)*(off_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)* + fs->fat_start = (off_t)CF_LE_W(b.reserved)*logical_sector_size; + fs->root_start = ((off_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; + data_size = (off_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 */ Index: user/dosfstools/dosfsck/io.c =================================================================== --- user/dosfstools/dosfsck/io.c (revision 1879) +++ user/dosfstools/dosfsck/io.c (working copy) @@ -39,33 +39,21 @@ unsigned device_no; -/* Use the _llseek system call directly, because there (once?) was a bug in - * the glibc implementation of it. */ -#include -#if defined __alpha || defined __ia64__ || defined __s390x__ || defined __x86_64__ || defined __ppc64__ -/* On alpha, the syscall is simply lseek, because it's a 64 bit system. */ -static loff_t llseek( int fd, loff_t offset, int whence ) -{ - return lseek(fd, offset, whence); -} -#else -# ifndef __NR__llseek -# error _llseek system call not present -# endif -static _syscall5( int, _llseek, uint, fd, ulong, hi, ulong, lo, - loff_t *, res, uint, wh ); +#ifdef __DJGPP__ +#include "volume.h" /* DOS lowlevel disk access functions */ +#undef llseek static loff_t llseek( int fd, loff_t offset, int whence ) { - loff_t actual; - - if (_llseek(fd, offset>>32, offset&0xffffffff, &actual, whence) != 0) - return (loff_t)-1; - return actual; + 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) +#define write(a,b,c) WriteVolume(b,c) #endif - void fs_open(char *path,int rw) { struct stat stbuf; @@ -75,9 +63,25 @@ changes = last = NULL; did_change = 0; +#ifndef _DJGPP_ if (fstat(fd,&stbuf) < 0) - pdie("fstat",path); + 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); + 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 */ + } +#endif } @@ -146,13 +150,13 @@ 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", - this->pos,strerror(errno),this->size); + (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, - this->pos,strerror(errno)); + (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,this->pos); + "\n",size,this->size,(long long)this->pos); free(this->data); free(this); } Index: user/dosfstools/dosfsck/io.h =================================================================== --- user/dosfstools/dosfsck/io.h (revision 1879) +++ user/dosfstools/dosfsck/io.h (working copy) @@ -11,6 +11,10 @@ #include /* for loff_t */ +/* In earlier versions, an own llseek() was used, but glibc lseek() is + * sufficient (or even better :) for 64 bit offsets in the meantime */ +#define llseek lseek + void fs_open(char *path,int rw); /* Opens the file system PATH. If RW is zero, the file system is opened Index: user/dosfstools/dosfsck/README =================================================================== --- user/dosfstools/dosfsck/README (revision 1879) +++ user/dosfstools/dosfsck/README (working copy) @@ -55,6 +55,6 @@ some checks on the (cruel) structure of how LFNs are stored and some attempts to fix problems. -- Roman +- Roman BTW, version 2 isn't ALPHA anymore :-) Index: user/dosfstools/dosfsck/check.c =================================================================== --- user/dosfstools/dosfsck/check.c (revision 1879) +++ user/dosfstools/dosfsck/check.c (working copy) @@ -80,7 +80,7 @@ } i += sizeof(DIR_ENT); offset += sizeof(DIR_ENT); - if (i >= fs->cluster_size) { + if ((i % fs->cluster_size) == 0) { prev = clu_num; if ((clu_num = next_cluster(fs,clu_num)) == 0 || clu_num == -1) break; @@ -101,6 +101,7 @@ die("Root directory full and no free cluster"); 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); @@ -120,7 +121,7 @@ break; i += sizeof(DIR_ENT); offset2 += sizeof(DIR_ENT); - if (i >= fs->cluster_size) { + if ((i % fs->cluster_size) == 0) { if ((clu_num = next_cluster(fs,clu_num)) == 0 || clu_num == -1) break; @@ -422,6 +423,12 @@ } 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", @@ -756,7 +763,10 @@ file_modify(cp,de.name); fs_write(offset,1,&de); } - if (IS_FREE(de.name)) return; + if (IS_FREE(de.name)) { + lfn_check_orphaned(); + return; + } if (de.attr == VFAT_LN_ATTR) { lfn_add_slot(&de,offset); return; @@ -805,6 +815,7 @@ 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); @@ -839,6 +850,7 @@ for (i = 0; i < fs->root_entries; i++) 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); Index: user/dosfstools/dosfsck/lfn.c =================================================================== --- user/dosfstools/dosfsck/lfn.c (revision 1879) +++ user/dosfstools/dosfsck/lfn.c (working copy) @@ -315,14 +315,16 @@ } } } - - lfn_slot--; - 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_offsets[lfn_parts++] = dir_offset; + if (lfn_slot != -1) { + lfn_slot--; + 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_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 ); @@ -452,7 +454,24 @@ return( lfn ); } +void lfn_check_orphaned(void) +{ + char *long_name; + if (lfn_slot == -1) + return; + + 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') { + clear_lfn_slots(0, lfn_parts - 1); + } + lfn_reset(); +} + /* Local Variables: */ /* tab-width: 8 */ /* End: */ Index: user/dosfstools/dosfsck/file.c =================================================================== --- user/dosfstools/dosfsck/file.c (revision 1879) +++ user/dosfstools/dosfsck/file.c (working copy) @@ -15,6 +15,14 @@ #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 */ + +#include +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) +# define __KERNEL__ +# include +# undef __KERNEL__ +#endif + #include #include "common.h" Index: user/dosfstools/dosfsck/dosfsck.8 =================================================================== --- user/dosfstools/dosfsck/dosfsck.8 (revision 1879) +++ user/dosfstools/dosfsck/dosfsck.8 (working copy) @@ -4,7 +4,7 @@ .SH SYNOPSIS .ad l .B dosfsck -.RB [ \-aAflrtvVwy ] +.RB [ \-aAflnrtvVwy ] .RB [ \-d\ \fIpath\fB\ \-d\ \fI...\fB ] .RB [ \-u\ \fIpath\fB\ \-u\ \fI...\fB ] .I device @@ -95,10 +95,12 @@ added to the free disk space except in auto mode (\fB-a\fP). .IP \fB\-l\fP List path names of files being processed. +.IP \fB\-n\fP +No-operation mode: non-interactively check for errors, but don't write +anything to the filesystem. .IP \fB\-r\fP Interactively repair the file system. The user is asked for advice whenever -there is more than one approach to fix an inconsistency. This is the default -behaviour. +there is more than one approach to fix an inconsistency. .IP \fB\-t\fP Mark unreadable clusters as bad. .IP \fB-u\fP @@ -138,4 +140,4 @@ .SH AUTHORS Werner Almesberger Extensions (FAT32, VFAT) by and current maintainer: -Roman Hodek +Roman Hodek Index: user/dosfstools/dosfsck/lfn.h =================================================================== --- user/dosfstools/dosfsck/lfn.h (revision 1879) +++ user/dosfstools/dosfsck/lfn.h (working copy) @@ -15,4 +15,6 @@ char *lfn_get( DIR_ENT *de ); /* Retrieve the long name for the proper dir entry. */ +void lfn_check_orphaned(void); + #endif Index: user/dosfstools/dosfsck/dosfsck.c =================================================================== --- user/dosfstools/dosfsck/dosfsck.c (revision 1879) +++ user/dosfstools/dosfsck/dosfsck.c (working copy) @@ -9,6 +9,7 @@ #include "../version.h" #include +#include #include #include #include @@ -38,6 +39,7 @@ 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," -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"); @@ -88,7 +90,7 @@ interactive = 1; check_atari(); - while ((c = getopt(argc,argv,"Aad:flrtu:vVwy")) != EOF) + while ((c = getopt(argc,argv,"Aad:flnrtu:vVwy")) != EOF) switch (c) { case 'A': /* toggle Atari format */ atari_format = !atari_format; @@ -108,6 +110,10 @@ case 'l': list = 1; break; + case 'n': + rw = 0; + interactive = 0; + break; case 'r': rw = 1; interactive = 1; Index: user/dosfstools/dosfsck/Makefile =================================================================== --- user/dosfstools/dosfsck/Makefile (revision 1879) +++ user/dosfstools/dosfsck/Makefile (working copy) @@ -4,7 +4,7 @@ all: dosfsck dosfsck: $(OBJECTS) - $(CC) -o $@ $(LDFLAGS) $^ $(LDLIBS) + $(CC) -o $@ $(LDFLAGS) $^ .c.o: $(CC) -c $(CFLAGS) $*.c @@ -21,13 +21,6 @@ ln -s dosfsck.8 $(MANDIR)/fsck.msdos.8 ln -s dosfsck.8 $(MANDIR)/fsck.vfat.8 -romfs: - $(ROMFSINST) dosfsck /sbin/dosfsck - rm -f $(ROMFSDIR)/sbin/fsck.msdos - rm -f $(ROMFSDIR)/sbin/fsck.vfat - $(ROMFSINST) -s dosfsck /sbin/fsck.msdos - $(ROMFSINST) -s dosfsck /sbin/fsck.vfat - clean: rm -f *.o *.s *.i *~ \#*# tmp_make .#* .new* @@ -49,3 +42,7 @@ file.o: file.c common.h file.h io.o: io.c dosfsck.h common.h io.h lfn.o: lfn.c common.h io.h dosfsck.h lfn.h file.h + +romfs: + $(ROMFSINST) dosfsck /usr/bin/dosfsck + Index: user/dosfstools/dosfsck/common.h =================================================================== --- user/dosfstools/dosfsck/common.h (revision 1879) +++ user/dosfstools/dosfsck/common.h (working copy) @@ -2,6 +2,13 @@ /* Written 1993 by Werner Almesberger */ +#include +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) +# define __KERNEL__ +# include +# undef __KERNEL__ +# define MSDOS_FAT12 4084 /* maximum number of clusters in a 12 bit FAT */ +#endif #ifndef _COMMON_H #define _COMMON_H Index: user/dosfstools/Makefile =================================================================== --- user/dosfstools/Makefile (revision 1879) +++ user/dosfstools/Makefile (working copy) @@ -2,13 +2,14 @@ # Makefile for dosfstools (mkdosfs and dosfsck) # -CC = gcc +#CC = gcc CPP = $(CC) -E +#OPTFLAGS = -O2 -fomit-frame-pointer -D_FILE_OFFSET_BITS=64 OPTFLAGS = -O2 -fomit-frame-pointer WARNFLAGS = -Wall DEBUGFLAGS = -CFLAGS = $(OPTFLAGS) $(WARNFLAGS) $(DEBUGFLAGS) -LDFLAGS = +CFLAGS += $(OPTFLAGS) $(WARNFLAGS) $(DEBUGFLAGS) +#LDFLAGS = PREFIX = SBINDIR = $(PREFIX)/sbin