/* check.c - Check and repair a PC/MS-DOS file system

   Copyright (C) 1993 Werner Almesberger <werner.almesberger@lrc.di.epfl.ch>
   Copyright (C) 1998 Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de>

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

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

   You should have received a copy of the GNU General Public License
   along with this program. If not, see <http://www.gnu.org/licenses/>.

   On Debian systems, the complete text of the GNU General Public License
   can be found in /usr/share/common-licenses/GPL-3 file.
*/

/* FAT32, VFAT, Atari format support, and various fixes additions May 1998
 * by Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de> */


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <time.h>

#include "common.h"
#include "dosfsck.h"
#include "io.h"
#include "fat.h"
#include "file.h"
#include "lfn.h"
#include "check.h"


static DOS_FILE *root;

/* get start field of a dir entry */
#define FSTART(p,fs) \
  ((unsigned long)CF_LE_W(p->dir_ent.start) | \
   (fs->fat_bits == 32 ? CF_LE_W(p->dir_ent.starthi) << 16 : 0))

#define MODIFY(p,i,v)					\
  do {							\
    if (p->offset) {					\
	p->dir_ent.i = v;				\
	fs_write(p->offset+offsetof(DIR_ENT,i),		\
		 sizeof(p->dir_ent.i),&p->dir_ent.i);	\
    }							\
  } while(0)

#define MODIFY_START(p,v,fs)						\
  do {									\
    unsigned long __v = (v);						\
    if (!p->offset) {							\
	/* writing to fake entry for FAT32 root dir */			\
	if (!__v) die("Oops, deleting FAT32 root dir!");		\
	fs->root_cluster = __v;						\
	p->dir_ent.start = CT_LE_W(__v&0xffff);				\
	p->dir_ent.starthi = CT_LE_W(__v>>16);				\
	__v = CT_LE_L(__v);						\
	fs_write((loff_t)offsetof(struct boot_sector,root_cluster),	\
	         sizeof(((struct boot_sector *)0)->root_cluster),	\
		 &__v);							\
    }									\
    else {								\
	MODIFY(p,start,CT_LE_W((__v)&0xffff));				\
	if (fs->fat_bits == 32)						\
	    MODIFY(p,starthi,CT_LE_W((__v)>>16));			\
    }									\
  } while(0)


loff_t alloc_rootdir_entry(DOS_FS *fs, DIR_ENT *de, const char *pattern)
{
    static int curr_num = 0;
    loff_t offset;

    if (fs->root_cluster) {
	DIR_ENT d2;
	int i = 0, got = 0;
	unsigned long clu_num, prev = 0;
	loff_t offset2;

	clu_num = fs->root_cluster;
	offset = cluster_start(fs,clu_num);
	while (clu_num > 0 && clu_num != -1) {
	    fs_read(offset,sizeof(DIR_ENT),&d2);
	    if (IS_FREE(d2.name) && d2.attr != VFAT_LN_ATTR) {
		got = 1;
		break;
	    }
	    i += sizeof(DIR_ENT);
	    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)
		    break;
		offset = cluster_start(fs,clu_num);
	    }
	}
	if (!got) {
	    /* no free slot, need to extend root dir: alloc next free cluster
	     * after previous one */
	    if (!prev)
		die("Root directory has no cluster allocated!");
	    for (clu_num = prev+1; clu_num != prev; clu_num++) {
		if (clu_num >= fs->clusters+2) clu_num = 2;
		if (!fs->fat[clu_num].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_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(de,0,sizeof(DIR_ENT));
	while (1) {
	    sprintf(de->name,pattern,curr_num);
	    clu_num = fs->root_cluster;
	    i = 0;
	    offset2 = cluster_start(fs,clu_num);
	    while (clu_num > 0 && clu_num != -1) {
		fs_read(offset2,sizeof(DIR_ENT),&d2);
		if (offset2 != offset &&
		    !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 ||
			clu_num == -1)
			break;
		    offset2 = cluster_start(fs,clu_num);
		}
	    }
	    if (clu_num == 0 || clu_num == -1)
		break;
	    if (++curr_num >= 10000) die("Unable to create unique name");
	}
    }
    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);

	while (next_free < fs->root_entries)
	    if (IS_FREE(root[next_free].name) &&
		root[next_free].attr != VFAT_LN_ATTR)
		break;
	    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));
	while (1) {
	    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))
		    break;
	    if (scan == fs->root_entries) break;
	    if (++curr_num >= 10000) die("Unable to create unique name");
	}
	free(root);
    }
    ++n_files;
    return offset;
}


static char *path_name(DOS_FILE *file)
{
    static char path[PATH_MAX*2];

    if (!file) *path = 0;
    else {
	if (strlen(path_name(file->parent)) > PATH_MAX)
	    die("Path name too long.");
	if (strcmp(path,"/") != 0) strcat(path,"/");
	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 };
		  /* 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)
{
    int month,year;
    time_t secs;

    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 */
    return secs;
}


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));
    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);
    return temp;
}


static int bad_name(unsigned char *name)
{
    int i, spc, suspicious = 0;
    char *bad_chars = atari_format ? "*?\\/:" : "*?<>|\"\\/:";

    /* 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;

    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;
    }

    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;
    }

    spc = 0;
    for (i = 0; i < 8; i++) {
	if (name[i] == ' ')
	    spc = 1;
	else if (spc)
	    /* non-space after a space not allowed, space terminates the name
	     * part */
	    return 1;
    }

    spc = 0;
    for (i = 8; i < 11; i++) {
	if (name[i] == ' ')
	    spc = 1;
	else if (spc)
	    /* non-space after a space not allowed, space terminates the name
	     * part */
	    return 1;
    }

    /* Under GEMDOS, chars >= 128 are never allowed. */
    if (atari_format && suspicious)
	return 1;

    /* Only complain about too much suspicious chars in interactive mode,
     * never correct them automatically. The chars are all basically ok, so we
     * shouldn't auto-correct such names. */
    if (interactive && suspicious > 6)
	return 1;
    return 0;
}


static void drop_file(DOS_FS *fs,DOS_FILE *file)
{
    unsigned long cluster;

    MODIFY(file,name[0],DELETED_FLAG);
    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)
{
    int deleting;
    unsigned long walk,next,prev;

    walk = FSTART(file,fs);
    prev = 0;
    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);
	prev = walk;
	walk = next;
    }
}


static void auto_rename(DOS_FILE *file)
{
    DOS_FILE *first,*walk;
    unsigned long int number;

    if (!file->offset) return;	/* cannot rename FAT32 root dir */
    first = file->parent ? file->parent->first : root;
    number = 0;
    while (1) {
	sprintf(file->dir_ent.name, "FSCK%04d", number / 1000);
	sprintf(file->dir_ent.name, "%03d", number % 1000);
	for (walk = first; walk; walk = walk->next)
	    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);
	    return;
	}
	number++;
	if (number > 9999999) {
		die("Too many files need repair.");
	}
    }
    die("Can't generate a unique name.");
}


static void rename_file(DOS_FILE *file)
{
    unsigned char name[46];
    unsigned char *walk,*here;

    if (!file->offset) {
	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--);
	    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);
		return;
	    }
	}
    }
}


static int handle_dot(DOS_FS *fs,DOS_FILE *file,int dots)
{
    char *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));
	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;
	}
    }
    if (!dots) {
	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)
{
    DOS_FILE *owner;
    int restart;
    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));
	}
	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);
	    }
	    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 (fs->root_cluster && expect == fs->root_cluster)
		expect = 0;
	    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);
	    }
	    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 (!file->offset)
	    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)) {
	if (!fs->fat[curr].value || bad_cluster(fs,curr)) {
	    printf("%s\n  Contains a %s cluster (%lu). Assuming EOF.\n",
	      path_name(file),fs->fat[curr].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);
	    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);
	    break;
	}
	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));
	    clusters2 = 0;
	    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 );
		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 );
		do_trunc = 1;
	    }
	    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'))) {
		prev = 0;
		clusters = 0;
		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;
			while (this > 0 && this != -1) {
			    set_owner(fs,this,NULL);
			    this = next_cluster(fs,this);
			}
			this = curr;
			break;
		    }
		    clusters++;
		    prev = this;
		}
		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);
		break;
	    }
	}
	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));
    }
    return 0;
}


static int check_files(DOS_FS *fs,DOS_FILE *start)
{
    while (start) {
	if (check_file(fs,start)) return 1;
	start = start->next;
    }
    return 0;
}


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;

    if (!*root) return 0;
    parent = (*root)->parent;
    good = bad = 0;
    for (walk = root; *walk; walk = &(*walk)->next)
	if (bad_name((*walk)->dir_ent.name)) 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);
	    /* buglet: deleted directory stays in the list. */
	    return 1;
	}
    }
    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)) {
		*walk = (*walk)->next;
		continue;
	    }
	    if (!strncmp((*walk)->dir_ent.name,MSDOS_DOT,MSDOS_NAME)) dot++;
	    else dotdot++;
	}
	if (!((*walk)->dir_ent.attr & ATTR_VOLUME) &&
	    bad_name((*walk)->dir_ent.name)) {
	    printf("%s\n  Bad file name.\n",path_name(*walk));
	    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;
	    }
	}
	/* don't check for duplicates of the volume label */
	if (!((*walk)->dir_ent.attr & ATTR_VOLUME)) {
	    scan = &(*walk)->next;
	    skip = 0;
	    while (*scan && !skip) {
		if (!((*scan)->dir_ent.attr & ATTR_VOLUME) &&
		    !strncmp((*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));
		    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);
			*walk = (*walk)->next;
			skip = 1;
			break;
		      case '2':
			drop_file(fs,*scan);
			*scan = (*scan)->next;
			continue;
		      case '3':
			rename_file(*walk);
			printf("  Renamed to %s\n",path_name(*walk));
			redo = 1;
			break;
		      case '4':
			rename_file(*scan);
			printf("  Renamed to %s\n",path_name(*walk));
			redo = 1;
			break;
		      case '5':
			auto_rename(*walk);
			printf("  Renamed to %s\n",file_name((*walk)->dir_ent.
			  name));
			break;
		      case '6':
			auto_rename(*scan);
			printf("  Renamed to %s\n",file_name((*scan)->dir_ent.
			  name));
			break;
		    }
		}
		scan = &(*scan)->next;
	    }
	    if (skip) continue;
	}
	if (!redo) walk = &(*walk)->next;
	else {
	    walk = root;
	    dot = dotdot = redo = 0;
	}
    }
    if (dots && !dot)
	printf("%s\n  \".\" is missing. Can't fix this yet.\n",
	  path_name(parent));
    if (dots && !dotdot)
	printf("%s\n  \"..\" is missing. Can't fix this yet.\n",
	  path_name(parent));
    return 0;
}


static void test_file(DOS_FS *fs,DOS_FILE *file,int read_test)
{
    DOS_FILE *owner;
    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);
	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);
		else if (!file->offset)
		    die( "Bad FAT32 root directory! (bad start cluster)\n" );
		else MODIFY_START(file,0,fs);
	    }
	    break;
	}
	if (bad_cluster(fs,walk)) break;
	if (read_test) {
	    if (fs_test(cluster_start(fs,walk),fs->cluster_size)) {
		prev = walk;
		clusters++;
	    }
	    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);
	    }
	}
	set_owner(fs,walk,file);
    }
    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)
{
    unsigned long clusters,left,prev,walk;

    clusters = left = (CF_LE_L(file->dir_ent.size)+fs->cluster_size-1)/
      fs->cluster_size;
    prev = 0;
    for (walk = FSTART(file,fs); left && walk >= 2 && walk <
       fs->clusters+2 && !fs->fat[walk].value; walk++) {
	left--;
	if (prev) set_fat(fs,prev,walk);
	prev = walk;
    }
    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");

}


static void new_dir( void )
{
    lfn_reset();
}


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);
    else {
	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 == fdt_undelete && (de.attr & ATTR_DIR))
	    die("Can't undelete directories.");
	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);
	return;
    }
    new = qalloc(&mem_queue,sizeof(DOS_FILE));
    new->lfn = lfn_get(&de);
    new->offset = offset;
    memcpy(&new->dir_ent,&de,sizeof(de));
    new->next = new->first = NULL;
    new->parent = parent;
    if (type == fdt_undelete) undelete(fs,new);
    **chain = new;
    *chain = &new->next;
    if (list) {
	printf("Checking file %s",path_name(new));
	if (new->lfn)
	    printf(" (%s)", file_name(new->dir_ent.name) );
	printf("\n");
    }
    if (offset &&
	strncmp(de.name,MSDOS_DOT,MSDOS_NAME) != 0 &&
	strncmp(de.name,MSDOS_DOTDOT,MSDOS_NAME) != 0)
	++n_files;
    test_file(fs,new,test);
}


static int subdirs(DOS_FS *fs,DOS_FILE *parent,FDSC **cp);


static int scan_dir(DOS_FS *fs,DOS_FILE *this,FDSC **cp)
{
    DOS_FILE **chain;
    int i;
    unsigned long clu_num;

    chain = &this->first;
    i = 0;
    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);
	i += sizeof(DIR_ENT);
	if (!(i % fs->cluster_size))
	    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);
}


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;
    return 0;
}


int scan_root(DOS_FS *fs)
{
    DOS_FILE **chain;
    int i;

    root = NULL;
    chain = &root;
    new_dir();
    if (fs->root_cluster) {
	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);
    }
    lfn_check_orphaned();
    (void) check_dir(fs,&root,0);
    if (check_files(fs,root)) return 1;
    return subdirs(fs,NULL,&fp_root);
}

/* Local Variables: */
/* tab-width: 8     */
/* End:             */
