/* vim:set shiftwidth=4 ts=8: */
/*
 * QEMU Block driver for virtual VFAT (shadows a local directory)
 *
 * Copyright (c) 2004,2005 Johannes E. Schindelin
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
#include <sys/stat.h>
#include <dirent.h>
#include "qemu-common.h"
#include "block_int.h"
#include "module.h"

#ifndef S_IWGRP
#define S_IWGRP 0
#endif
#ifndef S_IWOTH
#define S_IWOTH 0
#endif

/* TODO: add ":bootsector=blabla.img:" */
/* LATER TODO: add automatic boot sector generation from
    BOOTEASY.ASM and Ranish Partition Manager
    Note that DOS assumes the system files to be the first files in the
    file system (test if the boot sector still relies on that fact)! */
/* MAYBE TODO: write block-visofs.c */
/* TODO: call try_commit() only after a timeout */

/* #define DEBUG */

#ifdef DEBUG

#define DLOG(a) a

#undef stderr
#define stderr STDERR
FILE* stderr = NULL;

static void checkpoint(void);

#ifdef __MINGW32__
void nonono(const char* file, int line, const char* msg) {
    fprintf(stderr, "Nonono! %s:%d %s\n", file, line, msg);
    exit(-5);
}
#undef assert
#define assert(a) do {if (!(a)) nonono(__FILE__, __LINE__, #a);}while(0)
#endif

#else

#define DLOG(a)

#endif

/* dynamic array functions */
typedef struct array_t {
    char* pointer;
    unsigned int size,next,item_size;
} array_t;

static inline void array_init(array_t* array,unsigned int item_size)
{
    array->pointer = NULL;
    array->size=0;
    array->next=0;
    array->item_size=item_size;
}

static inline void array_free(array_t* array)
{
    if(array->pointer)
        free(array->pointer);
    array->size=array->next=0;
}

/* does not automatically grow */
static inline void* array_get(array_t* array,unsigned int index) {
    assert(index < array->next);
    return array->pointer + index * array->item_size;
}

static inline int array_ensure_allocated(array_t* array, int index)
{
    if((index + 1) * array->item_size > array->size) {
	int new_size = (index + 32) * array->item_size;
	array->pointer = qemu_realloc(array->pointer, new_size);
	if (!array->pointer)
	    return -1;
	array->size = new_size;
	array->next = index + 1;
    }

    return 0;
}

static inline void* array_get_next(array_t* array) {
    unsigned int next = array->next;
    void* result;

    if (array_ensure_allocated(array, next) < 0)
	return NULL;

    array->next = next + 1;
    result = array_get(array, next);

    return result;
}

static inline void* array_insert(array_t* array,unsigned int index,unsigned int count) {
    if((array->next+count)*array->item_size>array->size) {
	int increment=count*array->item_size;
	array->pointer=qemu_realloc(array->pointer,array->size+increment);
	if(!array->pointer)
            return NULL;
	array->size+=increment;
    }
    memmove(array->pointer+(index+count)*array->item_size,
		array->pointer+index*array->item_size,
		(array->next-index)*array->item_size);
    array->next+=count;
    return array->pointer+index*array->item_size;
}

/* this performs a "roll", so that the element which was at index_from becomes
 * index_to, but the order of all other elements is preserved. */
static inline int array_roll(array_t* array,int index_to,int index_from,int count)
{
    char* buf;
    char* from;
    char* to;
    int is;

    if(!array ||
	    index_to<0 || index_to>=array->next ||
	    index_from<0 || index_from>=array->next)
	return -1;

    if(index_to==index_from)
	return 0;

    is=array->item_size;
    from=array->pointer+index_from*is;
    to=array->pointer+index_to*is;
    buf=qemu_malloc(is*count);
    memcpy(buf,from,is*count);

    if(index_to<index_from)
	memmove(to+is*count,to,from-to);
    else
	memmove(from,from+is*count,to-from);

    memcpy(to,buf,is*count);

    free(buf);

    return 0;
}

static inline int array_remove_slice(array_t* array,int index, int count)
{
    assert(index >=0);
    assert(count > 0);
    assert(index + count <= array->next);
    if(array_roll(array,array->next-1,index,count))
	return -1;
    array->next -= count;
    return 0;
}

static int array_remove(array_t* array,int index)
{
    return array_remove_slice(array, index, 1);
}

/* return the index for a given member */
static int array_index(array_t* array, void* pointer)
{
    size_t offset = (char*)pointer - array->pointer;
    assert((offset % array->item_size) == 0);
    assert(offset/array->item_size < array->next);
    return offset/array->item_size;
}

/* These structures are used to fake a disk and the VFAT filesystem.
 * For this reason we need to use __attribute__((packed)). */

typedef struct bootsector_t {
    uint8_t jump[3];
    uint8_t name[8];
    uint16_t sector_size;
    uint8_t sectors_per_cluster;
    uint16_t reserved_sectors;
    uint8_t number_of_fats;
    uint16_t root_entries;
    uint16_t total_sectors16;
    uint8_t media_type;
    uint16_t sectors_per_fat;
    uint16_t sectors_per_track;
    uint16_t number_of_heads;
    uint32_t hidden_sectors;
    uint32_t total_sectors;
    union {
        struct {
	    uint8_t drive_number;
	    uint8_t current_head;
	    uint8_t signature;
	    uint32_t id;
	    uint8_t volume_label[11];
	} __attribute__((packed)) fat16;
	struct {
	    uint32_t sectors_per_fat;
	    uint16_t flags;
	    uint8_t major,minor;
	    uint32_t first_cluster_of_root_directory;
	    uint16_t info_sector;
	    uint16_t backup_boot_sector;
	    uint16_t ignored;
	} __attribute__((packed)) fat32;
    } u;
    uint8_t fat_type[8];
    uint8_t ignored[0x1c0];
    uint8_t magic[2];
} __attribute__((packed)) bootsector_t;

typedef struct {
    uint8_t head;
    uint8_t sector;
    uint8_t cylinder;
} mbr_chs_t;

typedef struct partition_t {
    uint8_t attributes; /* 0x80 = bootable */
    mbr_chs_t start_CHS;
    uint8_t   fs_type; /* 0x1 = FAT12, 0x6 = FAT16, 0xe = FAT16_LBA, 0xb = FAT32, 0xc = FAT32_LBA */
    mbr_chs_t end_CHS;
    uint32_t start_sector_long;
    uint32_t length_sector_long;
} __attribute__((packed)) partition_t;

typedef struct mbr_t {
    uint8_t ignored[0x1b8];
    uint32_t nt_id;
    uint8_t ignored2[2];
    partition_t partition[4];
    uint8_t magic[2];
} __attribute__((packed)) mbr_t;

typedef struct direntry_t {
    uint8_t name[8];
    uint8_t extension[3];
    uint8_t attributes;
    uint8_t reserved[2];
    uint16_t ctime;
    uint16_t cdate;
    uint16_t adate;
    uint16_t begin_hi;
    uint16_t mtime;
    uint16_t mdate;
    uint16_t begin;
    uint32_t size;
} __attribute__((packed)) direntry_t;

/* this structure are used to transparently access the files */

typedef struct mapping_t {
    /* begin is the first cluster, end is the last+1 */
    uint32_t begin,end;
    /* as s->directory is growable, no pointer may be used here */
    unsigned int dir_index;
    /* the clusters of a file may be in any order; this points to the first */
    int first_mapping_index;
    union {
	/* offset is
	 * - the offset in the file (in clusters) for a file, or
	 * - the next cluster of the directory for a directory, and
	 * - the address of the buffer for a faked entry
	 */
	struct {
	    uint32_t offset;
	} file;
	struct {
	    int parent_mapping_index;
	    int first_dir_index;
	} dir;
    } info;
    /* path contains the full path, i.e. it always starts with s->path */
    char* path;

    enum { MODE_UNDEFINED = 0, MODE_NORMAL = 1, MODE_MODIFIED = 2,
	MODE_DIRECTORY = 4, MODE_FAKED = 8,
	MODE_DELETED = 16, MODE_RENAMED = 32 } mode;
    int read_only;
} mapping_t;

#ifdef DEBUG
static void print_direntry(const struct direntry_t*);
static void print_mapping(const struct mapping_t* mapping);
#endif

/* here begins the real VVFAT driver */

typedef struct BDRVVVFATState {
    BlockDriverState* bs; /* pointer to parent */
    unsigned int first_sectors_number; /* 1 for a single partition, 0x40 for a disk with partition table */
    unsigned char first_sectors[0x40*0x200];

    int fat_type; /* 16 or 32 */
    array_t fat,directory,mapping;

    unsigned int cluster_size;
    unsigned int sectors_per_cluster;
    unsigned int sectors_per_fat;
    unsigned int sectors_of_root_directory;
    uint32_t last_cluster_of_root_directory;
    unsigned int faked_sectors; /* how many sectors are faked before file data */
    uint32_t sector_count; /* total number of sectors of the partition */
    uint32_t cluster_count; /* total number of clusters of this partition */
    uint32_t max_fat_value;

    int current_fd;
    mapping_t* current_mapping;
    unsigned char* cluster; /* points to current cluster */
    unsigned char* cluster_buffer; /* points to a buffer to hold temp data */
    unsigned int current_cluster;

    /* write support */
    BlockDriverState* write_target;
    char* qcow_filename;
    BlockDriverState* qcow;
    void* fat2;
    char* used_clusters;
    array_t commits;
    const char* path;
    int downcase_short_names;
} BDRVVVFATState;

/* take the sector position spos and convert it to Cylinder/Head/Sector position
 * if the position is outside the specified geometry, fill maximum value for CHS
 * and return 1 to signal overflow.
 */
static int sector2CHS(BlockDriverState* bs, mbr_chs_t * chs, int spos){
    int head,sector;
    sector   = spos % (bs->secs);  spos/= bs->secs;
    head     = spos % (bs->heads); spos/= bs->heads;
    if(spos >= bs->cyls){
        /* Overflow,
        it happens if 32bit sector positions are used, while CHS is only 24bit.
        Windows/Dos is said to take 1023/255/63 as nonrepresentable CHS */
        chs->head     = 0xFF;
        chs->sector   = 0xFF;
        chs->cylinder = 0xFF;
        return 1;
    }
    chs->head     = (uint8_t)head;
    chs->sector   = (uint8_t)( (sector+1) | ((spos>>8)<<6) );
    chs->cylinder = (uint8_t)spos;
    return 0;
}

static void init_mbr(BDRVVVFATState* s)
{
    /* TODO: if the files mbr.img and bootsect.img exist, use them */
    mbr_t* real_mbr=(mbr_t*)s->first_sectors;
    partition_t* partition = &(real_mbr->partition[0]);
    int lba;

    memset(s->first_sectors,0,512);

    /* Win NT Disk Signature */
    real_mbr->nt_id= cpu_to_le32(0xbe1afdfa);

    partition->attributes=0x80; /* bootable */

    /* LBA is used when partition is outside the CHS geometry */
    lba = sector2CHS(s->bs, &partition->start_CHS, s->first_sectors_number-1);
    lba|= sector2CHS(s->bs, &partition->end_CHS,   s->sector_count);

    /*LBA partitions are identified only by start/length_sector_long not by CHS*/
    partition->start_sector_long =cpu_to_le32(s->first_sectors_number-1);
    partition->length_sector_long=cpu_to_le32(s->sector_count - s->first_sectors_number+1);

    /* FAT12/FAT16/FAT32 */
    /* DOS uses different types when partition is LBA,
       probably to prevent older versions from using CHS on them */
    partition->fs_type= s->fat_type==12 ? 0x1:
                        s->fat_type==16 ? (lba?0xe:0x06):
                         /*fat_tyoe==32*/ (lba?0xc:0x0b);

    real_mbr->magic[0]=0x55; real_mbr->magic[1]=0xaa;
}

/* direntry functions */

/* dest is assumed to hold 258 bytes, and pads with 0xffff up to next multiple of 26 */
static inline int short2long_name(char* dest,const char* src)
{
    int i;
    int len;
    for(i=0;i<129 && src[i];i++) {
        dest[2*i]=src[i];
	dest[2*i+1]=0;
    }
    len=2*i;
    dest[2*i]=dest[2*i+1]=0;
    for(i=2*i+2;(i%26);i++)
	dest[i]=0xff;
    return len;
}

static inline direntry_t* create_long_filename(BDRVVVFATState* s,const char* filename)
{
    char buffer[258];
    int length=short2long_name(buffer,filename),
        number_of_entries=(length+25)/26,i;
    direntry_t* entry;

    for(i=0;i<number_of_entries;i++) {
	entry=array_get_next(&(s->directory));
	entry->attributes=0xf;
	entry->reserved[0]=0;
	entry->begin=0;
	entry->name[0]=(number_of_entries-i)|(i==0?0x40:0);
    }
    for(i=0;i<26*number_of_entries;i++) {
	int offset=(i%26);
	if(offset<10) offset=1+offset;
	else if(offset<22) offset=14+offset-10;
	else offset=28+offset-22;
	entry=array_get(&(s->directory),s->directory.next-1-(i/26));
	entry->name[offset]=buffer[i];
    }
    return array_get(&(s->directory),s->directory.next-number_of_entries);
}

static char is_free(const direntry_t* direntry)
{
    return direntry->name[0]==0xe5 || direntry->name[0]==0x00;
}

static char is_volume_label(const direntry_t* direntry)
{
    return direntry->attributes == 0x28;
}

static char is_long_name(const direntry_t* direntry)
{
    return direntry->attributes == 0xf;
}

static char is_short_name(const direntry_t* direntry)
{
    return !is_volume_label(direntry) && !is_long_name(direntry)
	&& !is_free(direntry);
}

static char is_directory(const direntry_t* direntry)
{
    return direntry->attributes & 0x10 && direntry->name[0] != 0xe5;
}

static inline char is_dot(const direntry_t* direntry)
{
    return is_short_name(direntry) && direntry->name[0] == '.';
}

static char is_file(const direntry_t* direntry)
{
    return is_short_name(direntry) && !is_directory(direntry);
}

static inline uint32_t begin_of_direntry(const direntry_t* direntry)
{
    return le16_to_cpu(direntry->begin)|(le16_to_cpu(direntry->begin_hi)<<16);
}

static inline uint32_t filesize_of_direntry(const direntry_t* direntry)
{
    return le32_to_cpu(direntry->size);
}

static void set_begin_of_direntry(direntry_t* direntry, uint32_t begin)
{
    direntry->begin = cpu_to_le16(begin & 0xffff);
    direntry->begin_hi = cpu_to_le16((begin >> 16) & 0xffff);
}

/* fat functions */

static inline uint8_t fat_chksum(const direntry_t* entry)
{
    uint8_t chksum=0;
    int i;

    for(i=0;i<11;i++) {
        unsigned char c;

        c = (i < 8) ? entry->name[i] : entry->extension[i-8];
        chksum=(((chksum&0xfe)>>1)|((chksum&0x01)?0x80:0)) + c;
    }

    return chksum;
}

/* if return_time==0, this returns the fat_date, else the fat_time */
static uint16_t fat_datetime(time_t time,int return_time) {
    struct tm* t;
#ifdef _WIN32
    t=localtime(&time); /* this is not thread safe */
#else
    struct tm t1;
    t = &t1;
    localtime_r(&time,t);
#endif
    if(return_time)
	return cpu_to_le16((t->tm_sec/2)|(t->tm_min<<5)|(t->tm_hour<<11));
    return cpu_to_le16((t->tm_mday)|((t->tm_mon+1)<<5)|((t->tm_year-80)<<9));
}

static inline void fat_set(BDRVVVFATState* s,unsigned int cluster,uint32_t value)
{
    if(s->fat_type==32) {
	uint32_t* entry=array_get(&(s->fat),cluster);
	*entry=cpu_to_le32(value);
    } else if(s->fat_type==16) {
	uint16_t* entry=array_get(&(s->fat),cluster);
	*entry=cpu_to_le16(value&0xffff);
    } else {
	int offset = (cluster*3/2);
	unsigned char* p = array_get(&(s->fat), offset);
        switch (cluster&1) {
	case 0:
		p[0] = value&0xff;
		p[1] = (p[1]&0xf0) | ((value>>8)&0xf);
		break;
	case 1:
		p[0] = (p[0]&0xf) | ((value&0xf)<<4);
		p[1] = (value>>4);
		break;
	}
    }
}

static inline uint32_t fat_get(BDRVVVFATState* s,unsigned int cluster)
{
    if(s->fat_type==32) {
	uint32_t* entry=array_get(&(s->fat),cluster);
	return le32_to_cpu(*entry);
    } else if(s->fat_type==16) {
	uint16_t* entry=array_get(&(s->fat),cluster);
	return le16_to_cpu(*entry);
    } else {
	const uint8_t* x=(uint8_t*)(s->fat.pointer)+cluster*3/2;
	return ((x[0]|(x[1]<<8))>>(cluster&1?4:0))&0x0fff;
    }
}

static inline int fat_eof(BDRVVVFATState* s,uint32_t fat_entry)
{
    if(fat_entry>s->max_fat_value-8)
	return -1;
    return 0;
}

static inline void init_fat(BDRVVVFATState* s)
{
    if (s->fat_type == 12) {
	array_init(&(s->fat),1);
	array_ensure_allocated(&(s->fat),
		s->sectors_per_fat * 0x200 * 3 / 2 - 1);
    } else {
	array_init(&(s->fat),(s->fat_type==32?4:2));
	array_ensure_allocated(&(s->fat),
		s->sectors_per_fat * 0x200 / s->fat.item_size - 1);
    }
    memset(s->fat.pointer,0,s->fat.size);

    switch(s->fat_type) {
	case 12: s->max_fat_value=0xfff; break;
	case 16: s->max_fat_value=0xffff; break;
	case 32: s->max_fat_value=0x0fffffff; break;
	default: s->max_fat_value=0; /* error... */
    }

}

/* TODO: in create_short_filename, 0xe5->0x05 is not yet handled! */
/* TODO: in parse_short_filename, 0x05->0xe5 is not yet handled! */
static inline direntry_t* create_short_and_long_name(BDRVVVFATState* s,
	unsigned int directory_start, const char* filename, int is_dot)
{
    int i,j,long_index=s->directory.next;
    direntry_t* entry = NULL;
    direntry_t* entry_long = NULL;

    if(is_dot) {
	entry=array_get_next(&(s->directory));
	memset(entry->name,0x20,11);
	memcpy(entry->name,filename,strlen(filename));
	return entry;
    }

    entry_long=create_long_filename(s,filename);

    i = strlen(filename);
    for(j = i - 1; j>0  && filename[j]!='.';j--);
    if (j > 0)
	i = (j > 8 ? 8 : j);
    else if (i > 8)
	i = 8;

    entry=array_get_next(&(s->directory));
    memset(entry->name,0x20,11);
    memcpy(entry->name, filename, i);

    if(j > 0)
	for (i = 0; i < 3 && filename[j+1+i]; i++)
	    entry->extension[i] = filename[j+1+i];

    /* upcase & remove unwanted characters */
    for(i=10;i>=0;i--) {
	if(i==10 || i==7) for(;i>0 && entry->name[i]==' ';i--);
	if(entry->name[i]<=' ' || entry->name[i]>0x7f
		|| strchr(".*?<>|\":/\\[];,+='",entry->name[i]))
	    entry->name[i]='_';
        else if(entry->name[i]>='a' && entry->name[i]<='z')
            entry->name[i]+='A'-'a';
    }

    /* mangle duplicates */
    while(1) {
	direntry_t* entry1=array_get(&(s->directory),directory_start);
	int j;

	for(;entry1<entry;entry1++)
	    if(!is_long_name(entry1) && !memcmp(entry1->name,entry->name,11))
		break; /* found dupe */
	if(entry1==entry) /* no dupe found */
	    break;

	/* use all 8 characters of name */
	if(entry->name[7]==' ') {
	    int j;
	    for(j=6;j>0 && entry->name[j]==' ';j--)
		entry->name[j]='~';
	}

	/* increment number */
	for(j=7;j>0 && entry->name[j]=='9';j--)
	    entry->name[j]='0';
	if(j>0) {
	    if(entry->name[j]<'0' || entry->name[j]>'9')
	        entry->name[j]='0';
	    else
	        entry->name[j]++;
	}
    }

    /* calculate checksum; propagate to long name */
    if(entry_long) {
        uint8_t chksum=fat_chksum(entry);

	/* calculate anew, because realloc could have taken place */
	entry_long=array_get(&(s->directory),long_index);
	while(entry_long<entry && is_long_name(entry_long)) {
	    entry_long->reserved[1]=chksum;
	    entry_long++;
	}
    }

    return entry;
}

/*
 * Read a directory. (the index of the corresponding mapping must be passed).
 */
static int read_directory(BDRVVVFATState* s, int mapping_index)
{
    mapping_t* mapping = array_get(&(s->mapping), mapping_index);
    direntry_t* direntry;
    const char* dirname = mapping->path;
    int first_cluster = mapping->begin;
    int parent_index = mapping->info.dir.parent_mapping_index;
    mapping_t* parent_mapping = (mapping_t*)
        (parent_index >= 0 ? array_get(&(s->mapping), parent_index) : NULL);
    int first_cluster_of_parent = parent_mapping ? parent_mapping->begin : -1;

    DIR* dir=opendir(dirname);
    struct dirent* entry;
    int i;

    assert(mapping->mode & MODE_DIRECTORY);

    if(!dir) {
	mapping->end = mapping->begin;
	return -1;
    }

    i = mapping->info.dir.first_dir_index =
	    first_cluster == 0 ? 0 : s->directory.next;

    /* actually read the directory, and allocate the mappings */
    while((entry=readdir(dir))) {
	unsigned int length=strlen(dirname)+2+strlen(entry->d_name);
        char* buffer;
	direntry_t* direntry;
        struct stat st;
	int is_dot=!strcmp(entry->d_name,".");
	int is_dotdot=!strcmp(entry->d_name,"..");

	if(first_cluster == 0 && (is_dotdot || is_dot))
	    continue;

	buffer=(char*)qemu_malloc(length);
	snprintf(buffer,length,"%s/%s",dirname,entry->d_name);

	if(stat(buffer,&st)<0) {
	    free(buffer);
            continue;
	}

	/* create directory entry for this file */
	direntry=create_short_and_long_name(s, i, entry->d_name,
		is_dot || is_dotdot);
	direntry->attributes=(S_ISDIR(st.st_mode)?0x10:0x20);
	direntry->reserved[0]=direntry->reserved[1]=0;
	direntry->ctime=fat_datetime(st.st_ctime,1);
	direntry->cdate=fat_datetime(st.st_ctime,0);
	direntry->adate=fat_datetime(st.st_atime,0);
	direntry->begin_hi=0;
	direntry->mtime=fat_datetime(st.st_mtime,1);
	direntry->mdate=fat_datetime(st.st_mtime,0);
	if(is_dotdot)
	    set_begin_of_direntry(direntry, first_cluster_of_parent);
	else if(is_dot)
	    set_begin_of_direntry(direntry, first_cluster);
	else
	    direntry->begin=0; /* do that later */
        if (st.st_size > 0x7fffffff) {
	    fprintf(stderr, "File %s is larger than 2GB\n", buffer);
	    free(buffer);
            closedir(dir);
	    return -2;
        }
	direntry->size=cpu_to_le32(S_ISDIR(st.st_mode)?0:st.st_size);

	/* create mapping for this file */
	if(!is_dot && !is_dotdot && (S_ISDIR(st.st_mode) || st.st_size)) {
	    s->current_mapping=(mapping_t*)array_get_next(&(s->mapping));
	    s->current_mapping->begin=0;
	    s->current_mapping->end=st.st_size;
	    /*
	     * we get the direntry of the most recent direntry, which
	     * contains the short name and all the relevant information.
	     */
	    s->current_mapping->dir_index=s->directory.next-1;
	    s->current_mapping->first_mapping_index = -1;
	    if (S_ISDIR(st.st_mode)) {
		s->current_mapping->mode = MODE_DIRECTORY;
		s->current_mapping->info.dir.parent_mapping_index =
		    mapping_index;
	    } else {
		s->current_mapping->mode = MODE_UNDEFINED;
		s->current_mapping->info.file.offset = 0;
	    }
	    s->current_mapping->path=buffer;
	    s->current_mapping->read_only =
		(st.st_mode & (S_IWUSR | S_IWGRP | S_IWOTH)) == 0;
	}
    }
    closedir(dir);

    /* fill with zeroes up to the end of the cluster */
    while(s->directory.next%(0x10*s->sectors_per_cluster)) {
	direntry_t* direntry=array_get_next(&(s->directory));
	memset(direntry,0,sizeof(direntry_t));
    }

/* TODO: if there are more entries, bootsector has to be adjusted! */
#define ROOT_ENTRIES (0x02 * 0x10 * s->sectors_per_cluster)
    if (mapping_index == 0 && s->directory.next < ROOT_ENTRIES) {
	/* root directory */
	int cur = s->directory.next;
	array_ensure_allocated(&(s->directory), ROOT_ENTRIES - 1);
	memset(array_get(&(s->directory), cur), 0,
		(ROOT_ENTRIES - cur) * sizeof(direntry_t));
    }

     /* reget the mapping, since s->mapping was possibly realloc()ed */
    mapping = (mapping_t*)array_get(&(s->mapping), mapping_index);
    first_cluster += (s->directory.next - mapping->info.dir.first_dir_index)
	* 0x20 / s->cluster_size;
    mapping->end = first_cluster;

    direntry = (direntry_t*)array_get(&(s->directory), mapping->dir_index);
    set_begin_of_direntry(direntry, mapping->begin);

    return 0;
}

static inline uint32_t sector2cluster(BDRVVVFATState* s,off_t sector_num)
{
    return (sector_num-s->faked_sectors)/s->sectors_per_cluster;
}

static inline off_t cluster2sector(BDRVVVFATState* s, uint32_t cluster_num)
{
    return s->faked_sectors + s->sectors_per_cluster * cluster_num;
}

static inline uint32_t sector_offset_in_cluster(BDRVVVFATState* s,off_t sector_num)
{
    return (sector_num-s->first_sectors_number-2*s->sectors_per_fat)%s->sectors_per_cluster;
}

#ifdef DBG
static direntry_t* get_direntry_for_mapping(BDRVVVFATState* s,mapping_t* mapping)
{
    if(mapping->mode==MODE_UNDEFINED)
	return 0;
    return (direntry_t*)(s->directory.pointer+sizeof(direntry_t)*mapping->dir_index);
}
#endif

static int init_directories(BDRVVVFATState* s,
	const char* dirname)
{
    bootsector_t* bootsector;
    mapping_t* mapping;
    unsigned int i;
    unsigned int cluster;

    memset(&(s->first_sectors[0]),0,0x40*0x200);

    s->cluster_size=s->sectors_per_cluster*0x200;
    s->cluster_buffer=qemu_malloc(s->cluster_size);

    /*
     * The formula: sc = spf+1+spf*spc*(512*8/fat_type),
     * where sc is sector_count,
     * spf is sectors_per_fat,
     * spc is sectors_per_clusters, and
     * fat_type = 12, 16 or 32.
     */
    i = 1+s->sectors_per_cluster*0x200*8/s->fat_type;
    s->sectors_per_fat=(s->sector_count+i)/i; /* round up */

    array_init(&(s->mapping),sizeof(mapping_t));
    array_init(&(s->directory),sizeof(direntry_t));

    /* add volume label */
    {
	direntry_t* entry=array_get_next(&(s->directory));
	entry->attributes=0x28; /* archive | volume label */
	memcpy(entry->name,"QEMU VVF",8);
	memcpy(entry->extension,"AT ",3);
    }

    /* Now build FAT, and write back information into directory */
    init_fat(s);

    s->faked_sectors=s->first_sectors_number+s->sectors_per_fat*2;
    s->cluster_count=sector2cluster(s, s->sector_count);

    mapping = array_get_next(&(s->mapping));
    mapping->begin = 0;
    mapping->dir_index = 0;
    mapping->info.dir.parent_mapping_index = -1;
    mapping->first_mapping_index = -1;
    mapping->path = qemu_strdup(dirname);
    i = strlen(mapping->path);
    if (i > 0 && mapping->path[i - 1] == '/')
	mapping->path[i - 1] = '\0';
    mapping->mode = MODE_DIRECTORY;
    mapping->read_only = 0;
    s->path = mapping->path;

    for (i = 0, cluster = 0; i < s->mapping.next; i++) {
	/* MS-DOS expects the FAT to be 0 for the root directory
	 * (except for the media byte). */
	/* LATER TODO: still true for FAT32? */
	int fix_fat = (i != 0);
	mapping = array_get(&(s->mapping), i);

        if (mapping->mode & MODE_DIRECTORY) {
	    mapping->begin = cluster;
	    if(read_directory(s, i)) {
		fprintf(stderr, "Could not read directory %s\n",
			mapping->path);
		return -1;
	    }
	    mapping = array_get(&(s->mapping), i);
	} else {
	    assert(mapping->mode == MODE_UNDEFINED);
	    mapping->mode=MODE_NORMAL;
	    mapping->begin = cluster;
	    if (mapping->end > 0) {
		direntry_t* direntry = array_get(&(s->directory),
			mapping->dir_index);

		mapping->end = cluster + 1 + (mapping->end-1)/s->cluster_size;
		set_begin_of_direntry(direntry, mapping->begin);
	    } else {
		mapping->end = cluster + 1;
		fix_fat = 0;
	    }
	}

	assert(mapping->begin < mapping->end);

	/* next free cluster */
	cluster = mapping->end;

	if(cluster > s->cluster_count) {
	    fprintf(stderr,"Directory does not fit in FAT%d (capacity %s)\n",
		    s->fat_type,
		    s->fat_type == 12 ? s->sector_count == 2880 ? "1.44 MB"
								: "2.88 MB"
				      : "504MB");
	    return -EINVAL;
	}

	/* fix fat for entry */
	if (fix_fat) {
	    int j;
	    for(j = mapping->begin; j < mapping->end - 1; j++)
		fat_set(s, j, j+1);
	    fat_set(s, mapping->end - 1, s->max_fat_value);
	}
    }

    mapping = array_get(&(s->mapping), 0);
    s->sectors_of_root_directory = mapping->end * s->sectors_per_cluster;
    s->last_cluster_of_root_directory = mapping->end;

    /* the FAT signature */
    fat_set(s,0,s->max_fat_value);
    fat_set(s,1,s->max_fat_value);

    s->current_mapping = NULL;

    bootsector=(bootsector_t*)(s->first_sectors+(s->first_sectors_number-1)*0x200);
    bootsector->jump[0]=0xeb;
    bootsector->jump[1]=0x3e;
    bootsector->jump[2]=0x90;
    memcpy(bootsector->name,"QEMU    ",8);
    bootsector->sector_size=cpu_to_le16(0x200);
    bootsector->sectors_per_cluster=s->sectors_per_cluster;
    bootsector->reserved_sectors=cpu_to_le16(1);
    bootsector->number_of_fats=0x2; /* number of FATs */
    bootsector->root_entries=cpu_to_le16(s->sectors_of_root_directory*0x10);
    bootsector->total_sectors16=s->sector_count>0xffff?0:cpu_to_le16(s->sector_count);
    bootsector->media_type=(s->fat_type!=12?0xf8:s->sector_count==5760?0xf9:0xf8); /* media descriptor */
    s->fat.pointer[0] = bootsector->media_type;
    bootsector->sectors_per_fat=cpu_to_le16(s->sectors_per_fat);
    bootsector->sectors_per_track=cpu_to_le16(s->bs->secs);
    bootsector->number_of_heads=cpu_to_le16(s->bs->heads);
    bootsector->hidden_sectors=cpu_to_le32(s->first_sectors_number==1?0:0x3f);
    bootsector->total_sectors=cpu_to_le32(s->sector_count>0xffff?s->sector_count:0);

    /* LATER TODO: if FAT32, this is wrong */
    bootsector->u.fat16.drive_number=s->fat_type==12?0:0x80; /* assume this is hda (TODO) */
    bootsector->u.fat16.current_head=0;
    bootsector->u.fat16.signature=0x29;
    bootsector->u.fat16.id=cpu_to_le32(0xfabe1afd);

    memcpy(bootsector->u.fat16.volume_label,"QEMU VVFAT ",11);
    memcpy(bootsector->fat_type,(s->fat_type==12?"FAT12   ":s->fat_type==16?"FAT16   ":"FAT32   "),8);
    bootsector->magic[0]=0x55; bootsector->magic[1]=0xaa;

    return 0;
}

#ifdef DEBUG
static BDRVVVFATState *vvv = NULL;
#endif

static int enable_write_target(BDRVVVFATState *s);
static int is_consistent(BDRVVVFATState *s);

static int vvfat_open(BlockDriverState *bs, const char* dirname, int flags)
{
    BDRVVVFATState *s = bs->opaque;
    int floppy = 0;
    int i;

#ifdef DEBUG
    vvv = s;
#endif

DLOG(if (stderr == NULL) {
    stderr = fopen("vvfat.log", "a");
    setbuf(stderr, NULL);
})

    s->bs = bs;

    s->fat_type=16;
    /* LATER TODO: if FAT32, adjust */
    s->sectors_per_cluster=0x10;
    /* 504MB disk*/
    bs->cyls=1024; bs->heads=16; bs->secs=63;

    s->current_cluster=0xffffffff;

    s->first_sectors_number=0x40;
    /* read only is the default for safety */
    bs->read_only = 1;
    s->qcow = s->write_target = NULL;
    s->qcow_filename = NULL;
    s->fat2 = NULL;
    s->downcase_short_names = 1;

    if (!strstart(dirname, "fat:", NULL))
	return -1;

    if (strstr(dirname, ":floppy:")) {
	floppy = 1;
	s->fat_type = 12;
	s->first_sectors_number = 1;
	s->sectors_per_cluster=2;
	bs->cyls = 80; bs->heads = 2; bs->secs = 36;
    }

    s->sector_count=bs->cyls*bs->heads*bs->secs;

    if (strstr(dirname, ":32:")) {
	fprintf(stderr, "Big fat greek warning: FAT32 has not been tested. You are welcome to do so!\n");
	s->fat_type = 32;
    } else if (strstr(dirname, ":16:")) {
	s->fat_type = 16;
    } else if (strstr(dirname, ":12:")) {
	s->fat_type = 12;
	s->sector_count=2880;
    }

    if (strstr(dirname, ":rw:")) {
	if (enable_write_target(s))
	    return -1;
	bs->read_only = 0;
    }

    i = strrchr(dirname, ':') - dirname;
    assert(i >= 3);
    if (dirname[i-2] == ':' && qemu_isalpha(dirname[i-1]))
	/* workaround for DOS drive names */
	dirname += i-1;
    else
	dirname += i+1;

    bs->total_sectors=bs->cyls*bs->heads*bs->secs;

    if(init_directories(s, dirname))
	return -1;

    s->sector_count = s->faked_sectors + s->sectors_per_cluster*s->cluster_count;

    if(s->first_sectors_number==0x40)
	init_mbr(s);

    /* for some reason or other, MS-DOS does not like to know about CHS... */
    if (floppy)
	bs->heads = bs->cyls = bs->secs = 0;

    //    assert(is_consistent(s));
    return 0;
}

static inline void vvfat_close_current_file(BDRVVVFATState *s)
{
    if(s->current_mapping) {
	s->current_mapping = NULL;
	if (s->current_fd) {
		close(s->current_fd);
		s->current_fd = 0;
	}
    }
    s->current_cluster = -1;
}

/* mappings between index1 and index2-1 are supposed to be ordered
 * return value is the index of the last mapping for which end>cluster_num
 */
static inline int find_mapping_for_cluster_aux(BDRVVVFATState* s,int cluster_num,int index1,int index2)
{
    while(1) {
        int index3;
	mapping_t* mapping;
	index3=(index1+index2)/2;
	mapping=array_get(&(s->mapping),index3);
	assert(mapping->begin < mapping->end);
	if(mapping->begin>=cluster_num) {
	    assert(index2!=index3 || index2==0);
	    if(index2==index3)
		return index1;
	    index2=index3;
	} else {
	    if(index1==index3)
		return mapping->end<=cluster_num ? index2 : index1;
	    index1=index3;
	}
	assert(index1<=index2);
	DLOG(mapping=array_get(&(s->mapping),index1);
	assert(mapping->begin<=cluster_num);
	assert(index2 >= s->mapping.next ||
		((mapping = array_get(&(s->mapping),index2)) &&
		mapping->end>cluster_num)));
    }
}

static inline mapping_t* find_mapping_for_cluster(BDRVVVFATState* s,int cluster_num)
{
    int index=find_mapping_for_cluster_aux(s,cluster_num,0,s->mapping.next);
    mapping_t* mapping;
    if(index>=s->mapping.next)
        return NULL;
    mapping=array_get(&(s->mapping),index);
    if(mapping->begin>cluster_num)
        return NULL;
    assert(mapping->begin<=cluster_num && mapping->end>cluster_num);
    return mapping;
}

/*
 * This function simply compares path == mapping->path. Since the mappings
 * are sorted by cluster, this is expensive: O(n).
 */
static inline mapping_t* find_mapping_for_path(BDRVVVFATState* s,
	const char* path)
{
    int i;

    for (i = 0; i < s->mapping.next; i++) {
	mapping_t* mapping = array_get(&(s->mapping), i);
	if (mapping->first_mapping_index < 0 &&
		!strcmp(path, mapping->path))
	    return mapping;
    }

    return NULL;
}

static int open_file(BDRVVVFATState* s,mapping_t* mapping)
{
    if(!mapping)
	return -1;
    if(!s->current_mapping ||
	    strcmp(s->current_mapping->path,mapping->path)) {
	/* open file */
	int fd = open(mapping->path, O_RDONLY | O_BINARY | O_LARGEFILE);
	if(fd<0)
	    return -1;
	vvfat_close_current_file(s);
	s->current_fd = fd;
	s->current_mapping = mapping;
    }
    return 0;
}

static inline int read_cluster(BDRVVVFATState *s,int cluster_num)
{
    if(s->current_cluster != cluster_num) {
	int result=0;
	off_t offset;
	assert(!s->current_mapping || s->current_fd || (s->current_mapping->mode & MODE_DIRECTORY));
	if(!s->current_mapping
		|| s->current_mapping->begin>cluster_num
		|| s->current_mapping->end<=cluster_num) {
	    /* binary search of mappings for file */
	    mapping_t* mapping=find_mapping_for_cluster(s,cluster_num);

	    assert(!mapping || (cluster_num>=mapping->begin && cluster_num<mapping->end));

	    if (mapping && mapping->mode & MODE_DIRECTORY) {
		vvfat_close_current_file(s);
		s->current_mapping = mapping;
read_cluster_directory:
		offset = s->cluster_size*(cluster_num-s->current_mapping->begin);
		s->cluster = (unsigned char*)s->directory.pointer+offset
			+ 0x20*s->current_mapping->info.dir.first_dir_index;
		assert(((s->cluster-(unsigned char*)s->directory.pointer)%s->cluster_size)==0);
		assert((char*)s->cluster+s->cluster_size <= s->directory.pointer+s->directory.next*s->directory.item_size);
		s->current_cluster = cluster_num;
		return 0;
	    }

	    if(open_file(s,mapping))
		return -2;
	} else if (s->current_mapping->mode & MODE_DIRECTORY)
	    goto read_cluster_directory;

	assert(s->current_fd);

	offset=s->cluster_size*(cluster_num-s->current_mapping->begin)+s->current_mapping->info.file.offset;
	if(lseek(s->current_fd, offset, SEEK_SET)!=offset)
	    return -3;
	s->cluster=s->cluster_buffer;
	result=read(s->current_fd,s->cluster,s->cluster_size);
	if(result<0) {
	    s->current_cluster = -1;
	    return -1;
	}
	s->current_cluster = cluster_num;
    }
    return 0;
}

#ifdef DEBUG
static void hexdump(const void* address, uint32_t len)
{
    const unsigned char* p = address;
    int i, j;

    for (i = 0; i < len; i += 16) {
	for (j = 0; j < 16 && i + j < len; j++)
	    fprintf(stderr, "%02x ", p[i + j]);
	for (; j < 16; j++)
	    fprintf(stderr, "   ");
	fprintf(stderr, " ");
	for (j = 0; j < 16 && i + j < len; j++)
	    fprintf(stderr, "%c", (p[i + j] < ' ' || p[i + j] > 0x7f) ? '.' : p[i + j]);
	fprintf(stderr, "\n");
    }
}

static void print_direntry(const direntry_t* direntry)
{
    int j = 0;
    char buffer[1024];

    fprintf(stderr, "direntry %p: ", direntry);
    if(!direntry)
	return;
    if(is_long_name(direntry)) {
	unsigned char* c=(unsigned char*)direntry;
	int i;
	for(i=1;i<11 && c[i] && c[i]!=0xff;i+=2)
#define ADD_CHAR(c) {buffer[j] = (c); if (buffer[j] < ' ') buffer[j] = 0xb0; j++;}
	    ADD_CHAR(c[i]);
	for(i=14;i<26 && c[i] && c[i]!=0xff;i+=2)
	    ADD_CHAR(c[i]);
	for(i=28;i<32 && c[i] && c[i]!=0xff;i+=2)
	    ADD_CHAR(c[i]);
	buffer[j] = 0;
	fprintf(stderr, "%s\n", buffer);
    } else {
	int i;
	for(i=0;i<11;i++)
	    ADD_CHAR(direntry->name[i]);
	buffer[j] = 0;
	fprintf(stderr,"%s attributes=0x%02x begin=%d size=%d\n",
		buffer,
		direntry->attributes,
		begin_of_direntry(direntry),le32_to_cpu(direntry->size));
    }
}

static void print_mapping(const mapping_t* mapping)
{
    fprintf(stderr, "mapping (%p): begin, end = %d, %d, dir_index = %d, "
        "first_mapping_index = %d, name = %s, mode = 0x%x, " ,
        mapping, mapping->begin, mapping->end, mapping->dir_index,
        mapping->first_mapping_index, mapping->path, mapping->mode);

    if (mapping->mode & MODE_DIRECTORY)
	fprintf(stderr, "parent_mapping_index = %d, first_dir_index = %d\n", mapping->info.dir.parent_mapping_index, mapping->info.dir.first_dir_index);
    else
	fprintf(stderr, "offset = %d\n", mapping->info.file.offset);
}
#endif

static int vvfat_read(BlockDriverState *bs, int64_t sector_num,
                    uint8_t *buf, int nb_sectors)
{
    BDRVVVFATState *s = bs->opaque;
    int i;

    for(i=0;i<nb_sectors;i++,sector_num++) {
	if (sector_num >= s->sector_count)
	   return -1;
	if (s->qcow) {
	    int n;
	    if (s->qcow->drv->bdrv_is_allocated(s->qcow,
			sector_num, nb_sectors-i, &n)) {
DLOG(fprintf(stderr, "sectors %d+%d allocated\n", (int)sector_num, n));
		if (s->qcow->drv->bdrv_read(s->qcow, sector_num, buf+i*0x200, n))
		    return -1;
		i += n - 1;
		sector_num += n - 1;
		continue;
	    }
DLOG(fprintf(stderr, "sector %d not allocated\n", (int)sector_num));
	}
	if(sector_num<s->faked_sectors) {
	    if(sector_num<s->first_sectors_number)
		memcpy(buf+i*0x200,&(s->first_sectors[sector_num*0x200]),0x200);
	    else if(sector_num-s->first_sectors_number<s->sectors_per_fat)
		memcpy(buf+i*0x200,&(s->fat.pointer[(sector_num-s->first_sectors_number)*0x200]),0x200);
	    else if(sector_num-s->first_sectors_number-s->sectors_per_fat<s->sectors_per_fat)
		memcpy(buf+i*0x200,&(s->fat.pointer[(sector_num-s->first_sectors_number-s->sectors_per_fat)*0x200]),0x200);
	} else {
	    uint32_t sector=sector_num-s->faked_sectors,
	    sector_offset_in_cluster=(sector%s->sectors_per_cluster),
	    cluster_num=sector/s->sectors_per_cluster;
	    if(read_cluster(s, cluster_num) != 0) {
		/* LATER TODO: strict: return -1; */
		memset(buf+i*0x200,0,0x200);
		continue;
	    }
	    memcpy(buf+i*0x200,s->cluster+sector_offset_in_cluster*0x200,0x200);
	}
    }
    return 0;
}

/* LATER TODO: statify all functions */

/*
 * Idea of the write support (use snapshot):
 *
 * 1. check if all data is consistent, recording renames, modifications,
 *    new files and directories (in s->commits).
 *
 * 2. if the data is not consistent, stop committing
 *
 * 3. handle renames, and create new files and directories (do not yet
 *    write their contents)
 *
 * 4. walk the directories, fixing the mapping and direntries, and marking
 *    the handled mappings as not deleted
 *
 * 5. commit the contents of the files
 *
 * 6. handle deleted files and directories
 *
 */

typedef struct commit_t {
    char* path;
    union {
	struct { uint32_t cluster; } rename;
	struct { int dir_index; uint32_t modified_offset; } writeout;
	struct { uint32_t first_cluster; } new_file;
	struct { uint32_t cluster; } mkdir;
    } param;
    /* DELETEs and RMDIRs are handled differently: see handle_deletes() */
    enum {
	ACTION_RENAME, ACTION_WRITEOUT, ACTION_NEW_FILE, ACTION_MKDIR
    } action;
} commit_t;

static void clear_commits(BDRVVVFATState* s)
{
    int i;
DLOG(fprintf(stderr, "clear_commits (%d commits)\n", s->commits.next));
    for (i = 0; i < s->commits.next; i++) {
	commit_t* commit = array_get(&(s->commits), i);
	assert(commit->path || commit->action == ACTION_WRITEOUT);
	if (commit->action != ACTION_WRITEOUT) {
	    assert(commit->path);
	    free(commit->path);
	} else
	    assert(commit->path == NULL);
    }
    s->commits.next = 0;
}

static void schedule_rename(BDRVVVFATState* s,
	uint32_t cluster, char* new_path)
{
    commit_t* commit = array_get_next(&(s->commits));
    commit->path = new_path;
    commit->param.rename.cluster = cluster;
    commit->action = ACTION_RENAME;
}

static void schedule_writeout(BDRVVVFATState* s,
	int dir_index, uint32_t modified_offset)
{
    commit_t* commit = array_get_next(&(s->commits));
    commit->path = NULL;
    commit->param.writeout.dir_index = dir_index;
    commit->param.writeout.modified_offset = modified_offset;
    commit->action = ACTION_WRITEOUT;
}

static void schedule_new_file(BDRVVVFATState* s,
	char* path, uint32_t first_cluster)
{
    commit_t* commit = array_get_next(&(s->commits));
    commit->path = path;
    commit->param.new_file.first_cluster = first_cluster;
    commit->action = ACTION_NEW_FILE;
}

static void schedule_mkdir(BDRVVVFATState* s, uint32_t cluster, char* path)
{
    commit_t* commit = array_get_next(&(s->commits));
    commit->path = path;
    commit->param.mkdir.cluster = cluster;
    commit->action = ACTION_MKDIR;
}

typedef struct {
    /*
     * Since the sequence number is at most 0x3f, and the filename
     * length is at most 13 times the sequence number, the maximal
     * filename length is 0x3f * 13 bytes.
     */
    unsigned char name[0x3f * 13 + 1];
    int checksum, len;
    int sequence_number;
} long_file_name;

static void lfn_init(long_file_name* lfn)
{
   lfn->sequence_number = lfn->len = 0;
   lfn->checksum = 0x100;
}

/* return 0 if parsed successfully, > 0 if no long name, < 0 if error */
static int parse_long_name(long_file_name* lfn,
	const direntry_t* direntry)
{
    int i, j, offset;
    const unsigned char* pointer = (const unsigned char*)direntry;

    if (!is_long_name(direntry))
	return 1;

    if (pointer[0] & 0x40) {
	lfn->sequence_number = pointer[0] & 0x3f;
	lfn->checksum = pointer[13];
	lfn->name[0] = 0;
	lfn->name[lfn->sequence_number * 13] = 0;
    } else if ((pointer[0] & 0x3f) != --lfn->sequence_number)
	return -1;
    else if (pointer[13] != lfn->checksum)
	return -2;
    else if (pointer[12] || pointer[26] || pointer[27])
	return -3;

    offset = 13 * (lfn->sequence_number - 1);
    for (i = 0, j = 1; i < 13; i++, j+=2) {
	if (j == 11)
	    j = 14;
	else if (j == 26)
	    j = 28;

	if (pointer[j+1] == 0)
	    lfn->name[offset + i] = pointer[j];
	else if (pointer[j+1] != 0xff || (pointer[0] & 0x40) == 0)
	    return -4;
	else
	    lfn->name[offset + i] = 0;
    }

    if (pointer[0] & 0x40)
	lfn->len = offset + strlen((char*)lfn->name + offset);

    return 0;
}

/* returns 0 if successful, >0 if no short_name, and <0 on error */
static int parse_short_name(BDRVVVFATState* s,
	long_file_name* lfn, direntry_t* direntry)
{
    int i, j;

    if (!is_short_name(direntry))
	return 1;

    for (j = 7; j >= 0 && direntry->name[j] == ' '; j--);
    for (i = 0; i <= j; i++) {
	if (direntry->name[i] <= ' ' || direntry->name[i] > 0x7f)
	    return -1;
	else if (s->downcase_short_names)
	    lfn->name[i] = qemu_tolower(direntry->name[i]);
	else
	    lfn->name[i] = direntry->name[i];
    }

    for (j = 2; j >= 0 && direntry->extension[j] == ' '; j--);
    if (j >= 0) {
	lfn->name[i++] = '.';
	lfn->name[i + j + 1] = '\0';
	for (;j >= 0; j--) {
	    if (direntry->extension[j] <= ' ' || direntry->extension[j] > 0x7f)
		return -2;
	    else if (s->downcase_short_names)
		lfn->name[i + j] = qemu_tolower(direntry->extension[j]);
	    else
		lfn->name[i + j] = direntry->extension[j];
	}
    } else
	lfn->name[i + j + 1] = '\0';

    lfn->len = strlen((char*)lfn->name);

    return 0;
}

static inline uint32_t modified_fat_get(BDRVVVFATState* s,
	unsigned int cluster)
{
    if (cluster < s->last_cluster_of_root_directory) {
	if (cluster + 1 == s->last_cluster_of_root_directory)
	    return s->max_fat_value;
	else
	    return cluster + 1;
    }

    if (s->fat_type==32) {
        uint32_t* entry=((uint32_t*)s->fat2)+cluster;
        return le32_to_cpu(*entry);
    } else if (s->fat_type==16) {
        uint16_t* entry=((uint16_t*)s->fat2)+cluster;
        return le16_to_cpu(*entry);
    } else {
        const uint8_t* x=s->fat2+cluster*3/2;
        return ((x[0]|(x[1]<<8))>>(cluster&1?4:0))&0x0fff;
    }
}

static inline int cluster_was_modified(BDRVVVFATState* s, uint32_t cluster_num)
{
    int was_modified = 0;
    int i, dummy;

    if (s->qcow == NULL)
	return 0;

    for (i = 0; !was_modified && i < s->sectors_per_cluster; i++)
	was_modified = s->qcow->drv->bdrv_is_allocated(s->qcow,
		cluster2sector(s, cluster_num) + i, 1, &dummy);

    return was_modified;
}

static const char* get_basename(const char* path)
{
    char* basename = strrchr(path, '/');
    if (basename == NULL)
	return path;
    else
	return basename + 1; /* strip '/' */
}

/*
 * The array s->used_clusters holds the states of the clusters. If it is
 * part of a file, it has bit 2 set, in case of a directory, bit 1. If it
 * was modified, bit 3 is set.
 * If any cluster is allocated, but not part of a file or directory, this
 * driver refuses to commit.
 */
typedef enum {
     USED_DIRECTORY = 1, USED_FILE = 2, USED_ANY = 3, USED_ALLOCATED = 4
} used_t;

/*
 * get_cluster_count_for_direntry() not only determines how many clusters
 * are occupied by direntry, but also if it was renamed or modified.
 *
 * A file is thought to be renamed *only* if there already was a file with
 * exactly the same first cluster, but a different name.
 *
 * Further, the files/directories handled by this function are
 * assumed to be *not* deleted (and *only* those).
 */
static uint32_t get_cluster_count_for_direntry(BDRVVVFATState* s,
	direntry_t* direntry, const char* path)
{
    /*
     * This is a little bit tricky:
     * IF the guest OS just inserts a cluster into the file chain,
     * and leaves the rest alone, (i.e. the original file had clusters
     * 15 -> 16, but now has 15 -> 32 -> 16), then the following happens:
     *
     * - do_commit will write the cluster into the file at the given
     *   offset, but
     *
     * - the cluster which is overwritten should be moved to a later
     *   position in the file.
     *
     * I am not aware that any OS does something as braindead, but this
     * situation could happen anyway when not committing for a long time.
     * Just to be sure that this does not bite us, detect it, and copy the
     * contents of the clusters to-be-overwritten into the qcow.
     */
    int copy_it = 0;
    int was_modified = 0;
    int32_t ret = 0;

    uint32_t cluster_num = begin_of_direntry(direntry);
    uint32_t offset = 0;
    int first_mapping_index = -1;
    mapping_t* mapping = NULL;
    const char* basename2 = NULL;

    vvfat_close_current_file(s);

    /* the root directory */
    if (cluster_num == 0)
	return 0;

    /* write support */
    if (s->qcow) {
	basename2 = get_basename(path);

	mapping = find_mapping_for_cluster(s, cluster_num);

	if (mapping) {
	    const char* basename;

	    assert(mapping->mode & MODE_DELETED);
	    mapping->mode &= ~MODE_DELETED;

	    basename = get_basename(mapping->path);

	    assert(mapping->mode & MODE_NORMAL);

	    /* rename */
	    if (strcmp(basename, basename2))
		schedule_rename(s, cluster_num, qemu_strdup(path));
	} else if (is_file(direntry))
	    /* new file */
	    schedule_new_file(s, qemu_strdup(path), cluster_num);
	else {
            abort();
	    return 0;
	}
    }

    while(1) {
	if (s->qcow) {
	    if (!copy_it && cluster_was_modified(s, cluster_num)) {
		if (mapping == NULL ||
			mapping->begin > cluster_num ||
			mapping->end <= cluster_num)
		mapping = find_mapping_for_cluster(s, cluster_num);


		if (mapping &&
			(mapping->mode & MODE_DIRECTORY) == 0) {

		    /* was modified in qcow */
		    if (offset != mapping->info.file.offset + s->cluster_size
			    * (cluster_num - mapping->begin)) {
			/* offset of this cluster in file chain has changed */
                        abort();
			copy_it = 1;
		    } else if (offset == 0) {
			const char* basename = get_basename(mapping->path);

			if (strcmp(basename, basename2))
			    copy_it = 1;
			first_mapping_index = array_index(&(s->mapping), mapping);
		    }

		    if (mapping->first_mapping_index != first_mapping_index
			    && mapping->info.file.offset > 0) {
                        abort();
			copy_it = 1;
		    }

		    /* need to write out? */
		    if (!was_modified && is_file(direntry)) {
			was_modified = 1;
			schedule_writeout(s, mapping->dir_index, offset);
		    }
		}
	    }

	    if (copy_it) {
		int i, dummy;
		/*
		 * This is horribly inefficient, but that is okay, since
		 * it is rarely executed, if at all.
		 */
		int64_t offset = cluster2sector(s, cluster_num);

		vvfat_close_current_file(s);
		for (i = 0; i < s->sectors_per_cluster; i++)
		    if (!s->qcow->drv->bdrv_is_allocated(s->qcow,
				offset + i, 1, &dummy)) {
			if (vvfat_read(s->bs,
				    offset, s->cluster_buffer, 1))
			    return -1;
			if (s->qcow->drv->bdrv_write(s->qcow,
				    offset, s->cluster_buffer, 1))
			    return -2;
		    }
	    }
	}

	ret++;
	if (s->used_clusters[cluster_num] & USED_ANY)
	    return 0;
	s->used_clusters[cluster_num] = USED_FILE;

	cluster_num = modified_fat_get(s, cluster_num);

	if (fat_eof(s, cluster_num))
	    return ret;
	else if (cluster_num < 2 || cluster_num > s->max_fat_value - 16)
	    return -1;

	offset += s->cluster_size;
    }
}

/*
 * This function looks at the modified data (qcow).
 * It returns 0 upon inconsistency or error, and the number of clusters
 * used by the directory, its subdirectories and their files.
 */
static int check_directory_consistency(BDRVVVFATState *s,
	int cluster_num, const char* path)
{
    int ret = 0;
    unsigned char* cluster = qemu_malloc(s->cluster_size);
    direntry_t* direntries = (direntry_t*)cluster;
    mapping_t* mapping = find_mapping_for_cluster(s, cluster_num);

    long_file_name lfn;
    int path_len = strlen(path);
    char path2[PATH_MAX];

    assert(path_len < PATH_MAX); /* len was tested before! */
    pstrcpy(path2, sizeof(path2), path);
    path2[path_len] = '/';
    path2[path_len + 1] = '\0';

    if (mapping) {
	const char* basename = get_basename(mapping->path);
	const char* basename2 = get_basename(path);

	assert(mapping->mode & MODE_DIRECTORY);

	assert(mapping->mode & MODE_DELETED);
	mapping->mode &= ~MODE_DELETED;

	if (strcmp(basename, basename2))
	    schedule_rename(s, cluster_num, qemu_strdup(path));
    } else
	/* new directory */
	schedule_mkdir(s, cluster_num, qemu_strdup(path));

    lfn_init(&lfn);
    do {
	int i;
	int subret = 0;

	ret++;

	if (s->used_clusters[cluster_num] & USED_ANY) {
	    fprintf(stderr, "cluster %d used more than once\n", (int)cluster_num);
	    return 0;
	}
	s->used_clusters[cluster_num] = USED_DIRECTORY;

DLOG(fprintf(stderr, "read cluster %d (sector %d)\n", (int)cluster_num, (int)cluster2sector(s, cluster_num)));
	subret = vvfat_read(s->bs, cluster2sector(s, cluster_num), cluster,
		s->sectors_per_cluster);
	if (subret) {
	    fprintf(stderr, "Error fetching direntries\n");
	fail:
	    free(cluster);
	    return 0;
	}

	for (i = 0; i < 0x10 * s->sectors_per_cluster; i++) {
	    int cluster_count = 0;

DLOG(fprintf(stderr, "check direntry %d: \n", i); print_direntry(direntries + i));
	    if (is_volume_label(direntries + i) || is_dot(direntries + i) ||
		    is_free(direntries + i))
		continue;

	    subret = parse_long_name(&lfn, direntries + i);
	    if (subret < 0) {
		fprintf(stderr, "Error in long name\n");
		goto fail;
	    }
	    if (subret == 0 || is_free(direntries + i))
		continue;

	    if (fat_chksum(direntries+i) != lfn.checksum) {
		subret = parse_short_name(s, &lfn, direntries + i);
		if (subret < 0) {
		    fprintf(stderr, "Error in short name (%d)\n", subret);
		    goto fail;
		}
		if (subret > 0 || !strcmp((char*)lfn.name, ".")
			|| !strcmp((char*)lfn.name, ".."))
		    continue;
	    }
	    lfn.checksum = 0x100; /* cannot use long name twice */

	    if (path_len + 1 + lfn.len >= PATH_MAX) {
		fprintf(stderr, "Name too long: %s/%s\n", path, lfn.name);
		goto fail;
	    }
            pstrcpy(path2 + path_len + 1, sizeof(path2) - path_len - 1,
                    (char*)lfn.name);

	    if (is_directory(direntries + i)) {
		if (begin_of_direntry(direntries + i) == 0) {
		    DLOG(fprintf(stderr, "invalid begin for directory: %s\n", path2); print_direntry(direntries + i));
		    goto fail;
		}
		cluster_count = check_directory_consistency(s,
			begin_of_direntry(direntries + i), path2);
		if (cluster_count == 0) {
		    DLOG(fprintf(stderr, "problem in directory %s:\n", path2); print_direntry(direntries + i));
		    goto fail;
		}
	    } else if (is_file(direntries + i)) {
		/* check file size with FAT */
		cluster_count = get_cluster_count_for_direntry(s, direntries + i, path2);
		if (cluster_count !=
			(le32_to_cpu(direntries[i].size) + s->cluster_size
			 - 1) / s->cluster_size) {
		    DLOG(fprintf(stderr, "Cluster count mismatch\n"));
		    goto fail;
		}
	    } else
                abort(); /* cluster_count = 0; */

	    ret += cluster_count;
	}

	cluster_num = modified_fat_get(s, cluster_num);
    } while(!fat_eof(s, cluster_num));

    free(cluster);
    return ret;
}

/* returns 1 on success */
static int is_consistent(BDRVVVFATState* s)
{
    int i, check;
    int used_clusters_count = 0;

DLOG(checkpoint());
    /*
     * - get modified FAT
     * - compare the two FATs (TODO)
     * - get buffer for marking used clusters
     * - recurse direntries from root (using bs->bdrv_read to make
     *    sure to get the new data)
     *   - check that the FAT agrees with the size
     *   - count the number of clusters occupied by this directory and
     *     its files
     * - check that the cumulative used cluster count agrees with the
     *   FAT
     * - if all is fine, return number of used clusters
     */
    if (s->fat2 == NULL) {
	int size = 0x200 * s->sectors_per_fat;
	s->fat2 = qemu_malloc(size);
	memcpy(s->fat2, s->fat.pointer, size);
    }
    check = vvfat_read(s->bs,
	    s->first_sectors_number, s->fat2, s->sectors_per_fat);
    if (check) {
	fprintf(stderr, "Could not copy fat\n");
	return 0;
    }
    assert (s->used_clusters);
    for (i = 0; i < sector2cluster(s, s->sector_count); i++)
	s->used_clusters[i] &= ~USED_ANY;

    clear_commits(s);

    /* mark every mapped file/directory as deleted.
     * (check_directory_consistency() will unmark those still present). */
    if (s->qcow)
	for (i = 0; i < s->mapping.next; i++) {
	    mapping_t* mapping = array_get(&(s->mapping), i);
	    if (mapping->first_mapping_index < 0)
		mapping->mode |= MODE_DELETED;
	}

    used_clusters_count = check_directory_consistency(s, 0, s->path);
    if (used_clusters_count <= 0) {
	DLOG(fprintf(stderr, "problem in directory\n"));
	return 0;
    }

    check = s->last_cluster_of_root_directory;
    for (i = check; i < sector2cluster(s, s->sector_count); i++) {
	if (modified_fat_get(s, i)) {
	    if(!s->used_clusters[i]) {
		DLOG(fprintf(stderr, "FAT was modified (%d), but cluster is not used?\n", i));
		return 0;
	    }
	    check++;
	}

	if (s->used_clusters[i] == USED_ALLOCATED) {
	    /* allocated, but not used... */
	    DLOG(fprintf(stderr, "unused, modified cluster: %d\n", i));
	    return 0;
	}
    }

    if (check != used_clusters_count)
	return 0;

    return used_clusters_count;
}

static inline void adjust_mapping_indices(BDRVVVFATState* s,
	int offset, int adjust)
{
    int i;

    for (i = 0; i < s->mapping.next; i++) {
	mapping_t* mapping = array_get(&(s->mapping), i);

#define ADJUST_MAPPING_INDEX(name) \
	if (mapping->name >= offset) \
	    mapping->name += adjust

	ADJUST_MAPPING_INDEX(first_mapping_index);
	if (mapping->mode & MODE_DIRECTORY)
	    ADJUST_MAPPING_INDEX(info.dir.parent_mapping_index);
    }
}

/* insert or update mapping */
static mapping_t* insert_mapping(BDRVVVFATState* s,
	uint32_t begin, uint32_t end)
{
    /*
     * - find mapping where mapping->begin >= begin,
     * - if mapping->begin > begin: insert
     *   - adjust all references to mappings!
     * - else: adjust
     * - replace name
     */
    int index = find_mapping_for_cluster_aux(s, begin, 0, s->mapping.next);
    mapping_t* mapping = NULL;
    mapping_t* first_mapping = array_get(&(s->mapping), 0);

    if (index < s->mapping.next && (mapping = array_get(&(s->mapping), index))
	    && mapping->begin < begin) {
	mapping->end = begin;
	index++;
	mapping = array_get(&(s->mapping), index);
    }
    if (index >= s->mapping.next || mapping->begin > begin) {
	mapping = array_insert(&(s->mapping), index, 1);
	mapping->path = NULL;
	adjust_mapping_indices(s, index, +1);
    }

    mapping->begin = begin;
    mapping->end = end;

DLOG(mapping_t* next_mapping;
assert(index + 1 >= s->mapping.next ||
((next_mapping = array_get(&(s->mapping), index + 1)) &&
 next_mapping->begin >= end)));

    if (s->current_mapping && first_mapping != (mapping_t*)s->mapping.pointer)
	s->current_mapping = array_get(&(s->mapping),
		s->current_mapping - first_mapping);

    return mapping;
}

static int remove_mapping(BDRVVVFATState* s, int mapping_index)
{
    mapping_t* mapping = array_get(&(s->mapping), mapping_index);
    mapping_t* first_mapping = array_get(&(s->mapping), 0);

    /* free mapping */
    if (mapping->first_mapping_index < 0)
	free(mapping->path);

    /* remove from s->mapping */
    array_remove(&(s->mapping), mapping_index);

    /* adjust all references to mappings */
    adjust_mapping_indices(s, mapping_index, -1);

    if (s->current_mapping && first_mapping != (mapping_t*)s->mapping.pointer)
	s->current_mapping = array_get(&(s->mapping),
		s->current_mapping - first_mapping);

    return 0;
}

static void adjust_dirindices(BDRVVVFATState* s, int offset, int adjust)
{
    int i;
    for (i = 0; i < s->mapping.next; i++) {
	mapping_t* mapping = array_get(&(s->mapping), i);
	if (mapping->dir_index >= offset)
	    mapping->dir_index += adjust;
	if ((mapping->mode & MODE_DIRECTORY) &&
		mapping->info.dir.first_dir_index >= offset)
	    mapping->info.dir.first_dir_index += adjust;
    }
}

static direntry_t* insert_direntries(BDRVVVFATState* s,
	int dir_index, int count)
{
    /*
     * make room in s->directory,
     * adjust_dirindices
     */
    direntry_t* result = array_insert(&(s->directory), dir_index, count);
    if (result == NULL)
	return NULL;
    adjust_dirindices(s, dir_index, count);
    return result;
}

static int remove_direntries(BDRVVVFATState* s, int dir_index, int count)
{
    int ret = array_remove_slice(&(s->directory), dir_index, count);
    if (ret)
	return ret;
    adjust_dirindices(s, dir_index, -count);
    return 0;
}

/*
 * Adapt the mappings of the cluster chain starting at first cluster
 * (i.e. if a file starts at first_cluster, the chain is followed according
 * to the modified fat, and the corresponding entries in s->mapping are
 * adjusted)
 */
static int commit_mappings(BDRVVVFATState* s,
	uint32_t first_cluster, int dir_index)
{
    mapping_t* mapping = find_mapping_for_cluster(s, first_cluster);
    direntry_t* direntry = array_get(&(s->directory), dir_index);
    uint32_t cluster = first_cluster;

    vvfat_close_current_file(s);

    assert(mapping);
    assert(mapping->begin == first_cluster);
    mapping->first_mapping_index = -1;
    mapping->dir_index = dir_index;
    mapping->mode = (dir_index <= 0 || is_directory(direntry)) ?
	MODE_DIRECTORY : MODE_NORMAL;

    while (!fat_eof(s, cluster)) {
	uint32_t c, c1;

	for (c = cluster, c1 = modified_fat_get(s, c); c + 1 == c1;
		c = c1, c1 = modified_fat_get(s, c1));

	c++;
	if (c > mapping->end) {
	    int index = array_index(&(s->mapping), mapping);
	    int i, max_i = s->mapping.next - index;
	    for (i = 1; i < max_i && mapping[i].begin < c; i++);
	    while (--i > 0)
		remove_mapping(s, index + 1);
	}
	assert(mapping == array_get(&(s->mapping), s->mapping.next - 1)
		|| mapping[1].begin >= c);
	mapping->end = c;

	if (!fat_eof(s, c1)) {
	    int i = find_mapping_for_cluster_aux(s, c1, 0, s->mapping.next);
	    mapping_t* next_mapping = i >= s->mapping.next ? NULL :
		array_get(&(s->mapping), i);

	    if (next_mapping == NULL || next_mapping->begin > c1) {
		int i1 = array_index(&(s->mapping), mapping);

		next_mapping = insert_mapping(s, c1, c1+1);

		if (c1 < c)
		    i1++;
		mapping = array_get(&(s->mapping), i1);
	    }

	    next_mapping->dir_index = mapping->dir_index;
	    next_mapping->first_mapping_index =
		mapping->first_mapping_index < 0 ?
		array_index(&(s->mapping), mapping) :
		mapping->first_mapping_index;
	    next_mapping->path = mapping->path;
	    next_mapping->mode = mapping->mode;
	    next_mapping->read_only = mapping->read_only;
	    if (mapping->mode & MODE_DIRECTORY) {
		next_mapping->info.dir.parent_mapping_index =
			mapping->info.dir.parent_mapping_index;
		next_mapping->info.dir.first_dir_index =
			mapping->info.dir.first_dir_index +
			0x10 * s->sectors_per_cluster *
			(mapping->end - mapping->begin);
	    } else
		next_mapping->info.file.offset = mapping->info.file.offset +
			mapping->end - mapping->begin;

	    mapping = next_mapping;
	}

	cluster = c1;
    }

    return 0;
}

static int commit_direntries(BDRVVVFATState* s,
	int dir_index, int parent_mapping_index)
{
    direntry_t* direntry = array_get(&(s->directory), dir_index);
    uint32_t first_cluster = dir_index == 0 ? 0 : begin_of_direntry(direntry);
    mapping_t* mapping = find_mapping_for_cluster(s, first_cluster);

    int factor = 0x10 * s->sectors_per_cluster;
    int old_cluster_count, new_cluster_count;
    int current_dir_index = mapping->info.dir.first_dir_index;
    int first_dir_index = current_dir_index;
    int ret, i;
    uint32_t c;

DLOG(fprintf(stderr, "commit_direntries for %s, parent_mapping_index %d\n", mapping->path, parent_mapping_index));

    assert(direntry);
    assert(mapping);
    assert(mapping->begin == first_cluster);
    assert(mapping->info.dir.first_dir_index < s->directory.next);
    assert(mapping->mode & MODE_DIRECTORY);
    assert(dir_index == 0 || is_directory(direntry));

    mapping->info.dir.parent_mapping_index = parent_mapping_index;

    if (first_cluster == 0) {
	old_cluster_count = new_cluster_count =
	    s->last_cluster_of_root_directory;
    } else {
	for (old_cluster_count = 0, c = first_cluster; !fat_eof(s, c);
		c = fat_get(s, c))
	    old_cluster_count++;

	for (new_cluster_count = 0, c = first_cluster; !fat_eof(s, c);
		c = modified_fat_get(s, c))
	    new_cluster_count++;
    }

    if (new_cluster_count > old_cluster_count) {
	if (insert_direntries(s,
		current_dir_index + factor * old_cluster_count,
		factor * (new_cluster_count - old_cluster_count)) == NULL)
	    return -1;
    } else if (new_cluster_count < old_cluster_count)
	remove_direntries(s,
		current_dir_index + factor * new_cluster_count,
		factor * (old_cluster_count - new_cluster_count));

    for (c = first_cluster; !fat_eof(s, c); c = modified_fat_get(s, c)) {
	void* direntry = array_get(&(s->directory), current_dir_index);
	int ret = vvfat_read(s->bs, cluster2sector(s, c), direntry,
		s->sectors_per_cluster);
	if (ret)
	    return ret;
	assert(!strncmp(s->directory.pointer, "QEMU", 4));
	current_dir_index += factor;
    }

    ret = commit_mappings(s, first_cluster, dir_index);
    if (ret)
	return ret;

    /* recurse */
    for (i = 0; i < factor * new_cluster_count; i++) {
	direntry = array_get(&(s->directory), first_dir_index + i);
	if (is_directory(direntry) && !is_dot(direntry)) {
	    mapping = find_mapping_for_cluster(s, first_cluster);
	    assert(mapping->mode & MODE_DIRECTORY);
	    ret = commit_direntries(s, first_dir_index + i,
		array_index(&(s->mapping), mapping));
	    if (ret)
		return ret;
	}
    }

    return 0;
}

/* commit one file (adjust contents, adjust mapping),
   return first_mapping_index */
static int commit_one_file(BDRVVVFATState* s,
	int dir_index, uint32_t offset)
{
    direntry_t* direntry = array_get(&(s->directory), dir_index);
    uint32_t c = begin_of_direntry(direntry);
    uint32_t first_cluster = c;
    mapping_t* mapping = find_mapping_for_cluster(s, c);
    uint32_t size = filesize_of_direntry(direntry);
    char* cluster = qemu_malloc(s->cluster_size);
    uint32_t i;
    int fd = 0;

    assert(offset < size);
    assert((offset % s->cluster_size) == 0);

    for (i = s->cluster_size; i < offset; i += s->cluster_size)
	c = modified_fat_get(s, c);

    fd = open(mapping->path, O_RDWR | O_CREAT | O_BINARY, 0666);
    if (fd < 0) {
	fprintf(stderr, "Could not open %s... (%s, %d)\n", mapping->path,
		strerror(errno), errno);
	return fd;
    }
    if (offset > 0)
	if (lseek(fd, offset, SEEK_SET) != offset)
	    return -3;

    while (offset < size) {
	uint32_t c1;
	int rest_size = (size - offset > s->cluster_size ?
		s->cluster_size : size - offset);
	int ret;

	c1 = modified_fat_get(s, c);

	assert((size - offset == 0 && fat_eof(s, c)) ||
		(size > offset && c >=2 && !fat_eof(s, c)));

	ret = vvfat_read(s->bs, cluster2sector(s, c),
	    (uint8_t*)cluster, (rest_size + 0x1ff) / 0x200);

	if (ret < 0)
	    return ret;

	if (write(fd, cluster, rest_size) < 0)
	    return -2;

	offset += rest_size;
	c = c1;
    }

    if (ftruncate(fd, size)) {
        perror("ftruncate()");
        close(fd);
        return -4;
    }
    close(fd);

    return commit_mappings(s, first_cluster, dir_index);
}

#ifdef DEBUG
/* test, if all mappings point to valid direntries */
static void check1(BDRVVVFATState* s)
{
    int i;
    for (i = 0; i < s->mapping.next; i++) {
	mapping_t* mapping = array_get(&(s->mapping), i);
	if (mapping->mode & MODE_DELETED) {
	    fprintf(stderr, "deleted\n");
	    continue;
	}
	assert(mapping->dir_index < s->directory.next);
	direntry_t* direntry = array_get(&(s->directory), mapping->dir_index);
	assert(mapping->begin == begin_of_direntry(direntry) || mapping->first_mapping_index >= 0);
	if (mapping->mode & MODE_DIRECTORY) {
	    assert(mapping->info.dir.first_dir_index + 0x10 * s->sectors_per_cluster * (mapping->end - mapping->begin) <= s->directory.next);
	    assert((mapping->info.dir.first_dir_index % (0x10 * s->sectors_per_cluster)) == 0);
	}
    }
}

/* test, if all direntries have mappings */
static void check2(BDRVVVFATState* s)
{
    int i;
    int first_mapping = -1;

    for (i = 0; i < s->directory.next; i++) {
	direntry_t* direntry = array_get(&(s->directory), i);

	if (is_short_name(direntry) && begin_of_direntry(direntry)) {
	    mapping_t* mapping = find_mapping_for_cluster(s, begin_of_direntry(direntry));
	    assert(mapping);
	    assert(mapping->dir_index == i || is_dot(direntry));
	    assert(mapping->begin == begin_of_direntry(direntry) || is_dot(direntry));
	}

	if ((i % (0x10 * s->sectors_per_cluster)) == 0) {
	    /* cluster start */
	    int j, count = 0;

	    for (j = 0; j < s->mapping.next; j++) {
		mapping_t* mapping = array_get(&(s->mapping), j);
		if (mapping->mode & MODE_DELETED)
		    continue;
		if (mapping->mode & MODE_DIRECTORY) {
		    if (mapping->info.dir.first_dir_index <= i && mapping->info.dir.first_dir_index + 0x10 * s->sectors_per_cluster > i) {
			assert(++count == 1);
			if (mapping->first_mapping_index == -1)
			    first_mapping = array_index(&(s->mapping), mapping);
			else
			    assert(first_mapping == mapping->first_mapping_index);
			if (mapping->info.dir.parent_mapping_index < 0)
			    assert(j == 0);
			else {
			    mapping_t* parent = array_get(&(s->mapping), mapping->info.dir.parent_mapping_index);
			    assert(parent->mode & MODE_DIRECTORY);
			    assert(parent->info.dir.first_dir_index < mapping->info.dir.first_dir_index);
			}
		    }
		}
	    }
	    if (count == 0)
		first_mapping = -1;
	}
    }
}
#endif

static int handle_renames_and_mkdirs(BDRVVVFATState* s)
{
    int i;

#ifdef DEBUG
    fprintf(stderr, "handle_renames\n");
    for (i = 0; i < s->commits.next; i++) {
	commit_t* commit = array_get(&(s->commits), i);
	fprintf(stderr, "%d, %s (%d, %d)\n", i, commit->path ? commit->path : "(null)", commit->param.rename.cluster, commit->action);
    }
#endif

    for (i = 0; i < s->commits.next;) {
	commit_t* commit = array_get(&(s->commits), i);
	if (commit->action == ACTION_RENAME) {
	    mapping_t* mapping = find_mapping_for_cluster(s,
		    commit->param.rename.cluster);
	    char* old_path = mapping->path;

	    assert(commit->path);
	    mapping->path = commit->path;
	    if (rename(old_path, mapping->path))
		return -2;

	    if (mapping->mode & MODE_DIRECTORY) {
		int l1 = strlen(mapping->path);
		int l2 = strlen(old_path);
		int diff = l1 - l2;
		direntry_t* direntry = array_get(&(s->directory),
			mapping->info.dir.first_dir_index);
		uint32_t c = mapping->begin;
		int i = 0;

		/* recurse */
		while (!fat_eof(s, c)) {
		    do {
			direntry_t* d = direntry + i;

			if (is_file(d) || (is_directory(d) && !is_dot(d))) {
			    mapping_t* m = find_mapping_for_cluster(s,
				    begin_of_direntry(d));
			    int l = strlen(m->path);
			    char* new_path = qemu_malloc(l + diff + 1);

			    assert(!strncmp(m->path, mapping->path, l2));

                            pstrcpy(new_path, l + diff + 1, mapping->path);
                            pstrcpy(new_path + l1, l + diff + 1 - l1,
                                    m->path + l2);

			    schedule_rename(s, m->begin, new_path);
			}
			i++;
		    } while((i % (0x10 * s->sectors_per_cluster)) != 0);
		    c = fat_get(s, c);
		}
	    }

	    free(old_path);
	    array_remove(&(s->commits), i);
	    continue;
	} else if (commit->action == ACTION_MKDIR) {
	    mapping_t* mapping;
	    int j, parent_path_len;

#ifdef __MINGW32__
            if (mkdir(commit->path))
                return -5;
#else
            if (mkdir(commit->path, 0755))
                return -5;
#endif

	    mapping = insert_mapping(s, commit->param.mkdir.cluster,
		    commit->param.mkdir.cluster + 1);
	    if (mapping == NULL)
		return -6;

	    mapping->mode = MODE_DIRECTORY;
	    mapping->read_only = 0;
	    mapping->path = commit->path;
	    j = s->directory.next;
	    assert(j);
	    insert_direntries(s, s->directory.next,
		    0x10 * s->sectors_per_cluster);
	    mapping->info.dir.first_dir_index = j;

	    parent_path_len = strlen(commit->path)
		- strlen(get_basename(commit->path)) - 1;
	    for (j = 0; j < s->mapping.next; j++) {
		mapping_t* m = array_get(&(s->mapping), j);
		if (m->first_mapping_index < 0 && m != mapping &&
			!strncmp(m->path, mapping->path, parent_path_len) &&
			strlen(m->path) == parent_path_len)
		    break;
	    }
	    assert(j < s->mapping.next);
	    mapping->info.dir.parent_mapping_index = j;

	    array_remove(&(s->commits), i);
	    continue;
	}

	i++;
    }
    return 0;
}

/*
 * TODO: make sure that the short name is not matching *another* file
 */
static int handle_commits(BDRVVVFATState* s)
{
    int i, fail = 0;

    vvfat_close_current_file(s);

    for (i = 0; !fail && i < s->commits.next; i++) {
	commit_t* commit = array_get(&(s->commits), i);
	switch(commit->action) {
	case ACTION_RENAME: case ACTION_MKDIR:
            abort();
	    fail = -2;
	    break;
	case ACTION_WRITEOUT: {
#ifndef NDEBUG
            /* these variables are only used by assert() below */
	    direntry_t* entry = array_get(&(s->directory),
		    commit->param.writeout.dir_index);
	    uint32_t begin = begin_of_direntry(entry);
	    mapping_t* mapping = find_mapping_for_cluster(s, begin);
#endif

	    assert(mapping);
	    assert(mapping->begin == begin);
	    assert(commit->path == NULL);

	    if (commit_one_file(s, commit->param.writeout.dir_index,
			commit->param.writeout.modified_offset))
		fail = -3;

	    break;
	}
	case ACTION_NEW_FILE: {
	    int begin = commit->param.new_file.first_cluster;
	    mapping_t* mapping = find_mapping_for_cluster(s, begin);
	    direntry_t* entry;
	    int i;

	    /* find direntry */
	    for (i = 0; i < s->directory.next; i++) {
		entry = array_get(&(s->directory), i);
		if (is_file(entry) && begin_of_direntry(entry) == begin)
		    break;
	    }

	    if (i >= s->directory.next) {
		fail = -6;
		continue;
	    }

	    /* make sure there exists an initial mapping */
	    if (mapping && mapping->begin != begin) {
		mapping->end = begin;
		mapping = NULL;
	    }
	    if (mapping == NULL) {
		mapping = insert_mapping(s, begin, begin+1);
	    }
	    /* most members will be fixed in commit_mappings() */
	    assert(commit->path);
	    mapping->path = commit->path;
	    mapping->read_only = 0;
	    mapping->mode = MODE_NORMAL;
	    mapping->info.file.offset = 0;

	    if (commit_one_file(s, i, 0))
		fail = -7;

	    break;
	}
	default:
            abort();
	}
    }
    if (i > 0 && array_remove_slice(&(s->commits), 0, i))
	return -1;
    return fail;
}

static int handle_deletes(BDRVVVFATState* s)
{
    int i, deferred = 1, deleted = 1;

    /* delete files corresponding to mappings marked as deleted */
    /* handle DELETEs and unused mappings (modified_fat_get(s, mapping->begin) == 0) */
    while (deferred && deleted) {
	deferred = 0;
	deleted = 0;

	for (i = 1; i < s->mapping.next; i++) {
	    mapping_t* mapping = array_get(&(s->mapping), i);
	    if (mapping->mode & MODE_DELETED) {
		direntry_t* entry = array_get(&(s->directory),
			mapping->dir_index);

		if (is_free(entry)) {
		    /* remove file/directory */
		    if (mapping->mode & MODE_DIRECTORY) {
			int j, next_dir_index = s->directory.next,
			first_dir_index = mapping->info.dir.first_dir_index;

			if (rmdir(mapping->path) < 0) {
			    if (errno == ENOTEMPTY) {
				deferred++;
				continue;
			    } else
				return -5;
			}

			for (j = 1; j < s->mapping.next; j++) {
			    mapping_t* m = array_get(&(s->mapping), j);
			    if (m->mode & MODE_DIRECTORY &&
				    m->info.dir.first_dir_index >
				    first_dir_index &&
				    m->info.dir.first_dir_index <
				    next_dir_index)
				next_dir_index =
				    m->info.dir.first_dir_index;
			}
			remove_direntries(s, first_dir_index,
				next_dir_index - first_dir_index);

			deleted++;
		    }
		} else {
		    if (unlink(mapping->path))
			return -4;
		    deleted++;
		}
		DLOG(fprintf(stderr, "DELETE (%d)\n", i); print_mapping(mapping); print_direntry(entry));
		remove_mapping(s, i);
	    }
	}
    }

    return 0;
}

/*
 * synchronize mapping with new state:
 *
 * - copy FAT (with bdrv_read)
 * - mark all filenames corresponding to mappings as deleted
 * - recurse direntries from root (using bs->bdrv_read)
 * - delete files corresponding to mappings marked as deleted
 */
static int do_commit(BDRVVVFATState* s)
{
    int ret = 0;

    /* the real meat are the commits. Nothing to do? Move along! */
    if (s->commits.next == 0)
	return 0;

    vvfat_close_current_file(s);

    ret = handle_renames_and_mkdirs(s);
    if (ret) {
	fprintf(stderr, "Error handling renames (%d)\n", ret);
        abort();
	return ret;
    }

    /* copy FAT (with bdrv_read) */
    memcpy(s->fat.pointer, s->fat2, 0x200 * s->sectors_per_fat);

    /* recurse direntries from root (using bs->bdrv_read) */
    ret = commit_direntries(s, 0, -1);
    if (ret) {
	fprintf(stderr, "Fatal: error while committing (%d)\n", ret);
        abort();
	return ret;
    }

    ret = handle_commits(s);
    if (ret) {
	fprintf(stderr, "Error handling commits (%d)\n", ret);
        abort();
	return ret;
    }

    ret = handle_deletes(s);
    if (ret) {
	fprintf(stderr, "Error deleting\n");
        abort();
	return ret;
    }

    s->qcow->drv->bdrv_make_empty(s->qcow);

    memset(s->used_clusters, 0, sector2cluster(s, s->sector_count));

DLOG(checkpoint());
    return 0;
}

static int try_commit(BDRVVVFATState* s)
{
    vvfat_close_current_file(s);
DLOG(checkpoint());
    if(!is_consistent(s))
	return -1;
    return do_commit(s);
}

static int vvfat_write(BlockDriverState *bs, int64_t sector_num,
                    const uint8_t *buf, int nb_sectors)
{
    BDRVVVFATState *s = bs->opaque;
    int i, ret;

DLOG(checkpoint());

    /* Check if we're operating in read-only mode */
    if (s->qcow == NULL) {
        return -EACCES;
    }

    vvfat_close_current_file(s);

    /*
     * Some sanity checks:
     * - do not allow writing to the boot sector
     * - do not allow to write non-ASCII filenames
     */

    if (sector_num < s->first_sectors_number)
	return -1;

    for (i = sector2cluster(s, sector_num);
	    i <= sector2cluster(s, sector_num + nb_sectors - 1);) {
	mapping_t* mapping = find_mapping_for_cluster(s, i);
	if (mapping) {
	    if (mapping->read_only) {
		fprintf(stderr, "Tried to write to write-protected file %s\n",
			mapping->path);
		return -1;
	    }

	    if (mapping->mode & MODE_DIRECTORY) {
		int begin = cluster2sector(s, i);
		int end = begin + s->sectors_per_cluster, k;
		int dir_index;
		const direntry_t* direntries;
		long_file_name lfn;

		lfn_init(&lfn);

		if (begin < sector_num)
		    begin = sector_num;
		if (end > sector_num + nb_sectors)
		    end = sector_num + nb_sectors;
		dir_index  = mapping->dir_index +
		    0x10 * (begin - mapping->begin * s->sectors_per_cluster);
		direntries = (direntry_t*)(buf + 0x200 * (begin - sector_num));

		for (k = 0; k < (end - begin) * 0x10; k++) {
		    /* do not allow non-ASCII filenames */
		    if (parse_long_name(&lfn, direntries + k) < 0) {
			fprintf(stderr, "Warning: non-ASCII filename\n");
			return -1;
		    }
		    /* no access to the direntry of a read-only file */
		    else if (is_short_name(direntries+k) &&
			    (direntries[k].attributes & 1)) {
			if (memcmp(direntries + k,
				    array_get(&(s->directory), dir_index + k),
				    sizeof(direntry_t))) {
			    fprintf(stderr, "Warning: tried to write to write-protected file\n");
			    return -1;
			}
		    }
		}
	    }
	    i = mapping->end;
	} else
	    i++;
    }

    /*
     * Use qcow backend. Commit later.
     */
DLOG(fprintf(stderr, "Write to qcow backend: %d + %d\n", (int)sector_num, nb_sectors));
    ret = s->qcow->drv->bdrv_write(s->qcow, sector_num, buf, nb_sectors);
    if (ret < 0) {
	fprintf(stderr, "Error writing to qcow backend\n");
	return ret;
    }

    for (i = sector2cluster(s, sector_num);
	    i <= sector2cluster(s, sector_num + nb_sectors - 1); i++)
	if (i >= 0)
	    s->used_clusters[i] |= USED_ALLOCATED;

DLOG(checkpoint());
    /* TODO: add timeout */
    try_commit(s);

DLOG(checkpoint());
    return 0;
}

static int vvfat_is_allocated(BlockDriverState *bs,
	int64_t sector_num, int nb_sectors, int* n)
{
    BDRVVVFATState* s = bs->opaque;
    *n = s->sector_count - sector_num;
    if (*n > nb_sectors)
	*n = nb_sectors;
    else if (*n < 0)
	return 0;
    return 1;
}

static int write_target_commit(BlockDriverState *bs, int64_t sector_num,
	const uint8_t* buffer, int nb_sectors) {
    BDRVVVFATState* s = *((BDRVVVFATState**) bs->opaque);
    return try_commit(s);
}

static void write_target_close(BlockDriverState *bs) {
    BDRVVVFATState* s = *((BDRVVVFATState**) bs->opaque);
    bdrv_delete(s->qcow);
    free(s->qcow_filename);
}

static BlockDriver vvfat_write_target = {
    .format_name        = "vvfat_write_target",
    .bdrv_write         = write_target_commit,
    .bdrv_close         = write_target_close,
};

static int enable_write_target(BDRVVVFATState *s)
{
    BlockDriver *bdrv_qcow;
    QEMUOptionParameter *options;
    int ret;
    int size = sector2cluster(s, s->sector_count);
    s->used_clusters = calloc(size, 1);

    array_init(&(s->commits), sizeof(commit_t));

    s->qcow_filename = qemu_malloc(1024);
    get_tmp_filename(s->qcow_filename, 1024);

    bdrv_qcow = bdrv_find_format("qcow");
    options = parse_option_parameters("", bdrv_qcow->create_options, NULL);
    set_option_parameter_int(options, BLOCK_OPT_SIZE, s->sector_count * 512);
    set_option_parameter(options, BLOCK_OPT_BACKING_FILE, "fat:");

    if (bdrv_create(bdrv_qcow, s->qcow_filename, options) < 0)
	return -1;

    s->qcow = bdrv_new("");
    if (s->qcow == NULL) {
        return -1;
    }

    ret = bdrv_open(s->qcow, s->qcow_filename,
            BDRV_O_RDWR | BDRV_O_CACHE_WB | BDRV_O_NO_FLUSH, bdrv_qcow);
    if (ret < 0) {
	return ret;
    }

#ifndef _WIN32
    unlink(s->qcow_filename);
#endif

    s->bs->backing_hd = calloc(sizeof(BlockDriverState), 1);
    s->bs->backing_hd->drv = &vvfat_write_target;
    s->bs->backing_hd->opaque = qemu_malloc(sizeof(void*));
    *(void**)s->bs->backing_hd->opaque = s;

    return 0;
}

static void vvfat_close(BlockDriverState *bs)
{
    BDRVVVFATState *s = bs->opaque;

    vvfat_close_current_file(s);
    array_free(&(s->fat));
    array_free(&(s->directory));
    array_free(&(s->mapping));
    if(s->cluster_buffer)
        free(s->cluster_buffer);
}

static BlockDriver bdrv_vvfat = {
    .format_name	= "vvfat",
    .instance_size	= sizeof(BDRVVVFATState),
    .bdrv_file_open	= vvfat_open,
    .bdrv_read		= vvfat_read,
    .bdrv_write		= vvfat_write,
    .bdrv_close		= vvfat_close,
    .bdrv_is_allocated	= vvfat_is_allocated,
    .protocol_name	= "fat",
};

static void bdrv_vvfat_init(void)
{
    bdrv_register(&bdrv_vvfat);
}

block_init(bdrv_vvfat_init);

#ifdef DEBUG
static void checkpoint(void) {
    assert(((mapping_t*)array_get(&(vvv->mapping), 0))->end == 2);
    check1(vvv);
    check2(vvv);
    assert(!vvv->current_mapping || vvv->current_fd || (vvv->current_mapping->mode & MODE_DIRECTORY));
#if 0
    if (((direntry_t*)vvv->directory.pointer)[1].attributes != 0xf)
	fprintf(stderr, "Nonono!\n");
    mapping_t* mapping;
    direntry_t* direntry;
    assert(vvv->mapping.size >= vvv->mapping.item_size * vvv->mapping.next);
    assert(vvv->directory.size >= vvv->directory.item_size * vvv->directory.next);
    if (vvv->mapping.next<47)
	return;
    assert((mapping = array_get(&(vvv->mapping), 47)));
    assert(mapping->dir_index < vvv->directory.next);
    direntry = array_get(&(vvv->directory), mapping->dir_index);
    assert(!memcmp(direntry->name, "USB     H  ", 11) || direntry->name[0]==0);
#endif
    return;
    /* avoid compiler warnings: */
    hexdump(NULL, 100);
    remove_mapping(vvv, 0);
    print_mapping(NULL);
    print_direntry(NULL);
}
#endif
