#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <utime.h>

#define VER_MAJOR 1
#define VER_MINOR 4

#ifdef __linux__
    #include <unistd.h>
    #include <linux/types.h>
    #include <sys/stat.h>
    #define SLASH "/"
    #define UNIX_ATTR
    #define LFN_AVAIL
    #define CODEPAGE_FAT 852
    #define CODEPAGE_LOCAL 912
#endif
#ifdef __MSDOS__
    #include <dir.h>
    #include <dos.h>
    #include <io.h>
    typedef unsigned char __u8;
    typedef signed char __s8;
    typedef unsigned short __u16;
    typedef signed short __s16;
    typedef unsigned long __u32;
    typedef signed long __s32;
    #define SLASH "\\"
    #define DOS_ATTR
    #define CODEPAGE_FAT 852
    #define CODEPAGE_LOCAL 852
#endif
#ifdef __OS2__
    #include <dir.h>
    #include <dos.h>
    #include <io.h>
    typedef unsigned char __u8;
    typedef signed char __s8;
    typedef unsigned short __u16;
    typedef signed short __s16;
    typedef unsigned long __u32;
    typedef signed long __s32;
    #define SLASH "\\"
    #define DOS_ATTR
    #define LFN_AVAIL
    #define CODEPAGE_FAT 852
    #define CODEPAGE_LOCAL 852
#endif

#pragma pack(1)

typedef char shortstring[16];
typedef char string[256];

#define ERR_OPEN    -1
#define ERR_BADFILE -2

#define FAT12_MAGIC "FAT12"

#define MEDIA_D8 0xFF
#define MEDIA_S8 0xFE
#define MEDIA_D9 0xFD
#define MEDIA_S9 0xFC
#define MEDIA_HP 0xFA
#define MEDIA_QD 0xF9
#define MEDIA_HD 0xF8
#define MEDIA_OTHER 0xF0

#define FMT_RAW 0
#define FMT_DDI 1

struct tbootsec {
    __u8 jmp[3];
    __u8 oem[8];      // OEM ID
    __u16 bytesec;    // Bytes per sector
    __u8 secclu;      // Sectors per cluster
    __u16 ressect;    // Reserved sectors at beginning
    __u8 fatcps;      // FAT Copies
    __u16 rootent;    // Root directory entries
    __u16 totalsc;    // Total sectors on disk
    __u8 bpb;         // Media descriptor byte
    __u16 secfat;     // Sectors per FAT
    __u16 sectrack;   // Sectors per track
    __u16 sides;      // Sides
    __s32 hiddensc;   // Special hidden sectors
    __s32 numsec;     // Big total number of sectors
    __u16 physnum;    // Physical drive number
    __u8 extboots;    // Extended Boot Record Signature
    __u16 volumen[2]; // Volume Serial Number
    __u8 volumel[11]; // Volume Label
    __u8 filsysid[8]; // File System ID
    __u8 code[448];
    __u16 sig;
};

struct tdatetime {
    unsigned sec2 : 5;
    unsigned min  : 6;
    unsigned hour : 5;
    unsigned mday : 5;
    unsigned mon  : 4;
    unsigned year : 7;
};

struct sfn {
    __u8 name[8];
    __u8 ext[3];
    __u8 attr;
    __u8 reserved[10];
    struct tdatetime dt;
    __u16 clust;
    __s32 size;
};

struct lfn {
    unsigned seqnum  : 6;
    unsigned last    : 1;
    unsigned deleted : 1;
    __u16 c0;
    __u16 c1;
    __u16 c2;
    __u16 c3;
    __u16 c4;
    __u8 attr;
    __u8 reserved;
    __u8 cksum;
    __u16 c5;
    __u16 c6;
    __u16 c7;
    __u16 c8;
    __u16 c9;
    __u16 c10;
    __u16 clust;
    __u16 c11;
    __u16 c12;
};

union tdirent {
    struct sfn s;
    struct lfn l;
};

#define ATTR_RO  0x01
#define ATTR_HID 0x02
#define ATTR_SYS 0x04
#define ATTR_VOL 0x08
#define ATTR_DIR 0x10
#define ATTR_ARC 0x20
#define ATTR_LFN 0x0F
