We have an unused FAT implementation in fs/fdos, remove. Signed-off-by: Tom Rini <trini@ti.com>master
parent
4c89a369c7
commit
1530f6f51a
@ -1,13 +0,0 @@ |
||||
#
|
||||
# (C) Copyright 2006
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
#
|
||||
# (C) Copyright 2002
|
||||
# Stäubli Faverges - <www.staubli.com>
|
||||
# Pierre AUBERT p.aubert@staubli.com
|
||||
#
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
|
||||
obj-y := fat.o vfat.o dev.o fdos.o fs.o subdir.o
|
@ -1,174 +0,0 @@ |
||||
/*
|
||||
* (C) Copyright 2002 |
||||
* Stäubli Faverges - <www.staubli.com> |
||||
* Pierre AUBERT p.aubert@staubli.com |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <config.h> |
||||
|
||||
#include "dos.h" |
||||
#include "fdos.h" |
||||
|
||||
#define NB_HEADS 2 |
||||
#define NB_TRACKS 80 |
||||
#define NB_SECTORS 18 |
||||
|
||||
|
||||
static int lastwhere; |
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
* dev_open -- |
||||
*----------------------------------------------------------------------------- |
||||
*/ |
||||
int dev_open (void) |
||||
{ |
||||
lastwhere = 0; |
||||
return (0); |
||||
} |
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
* dev_read -- len and where are sectors number |
||||
*----------------------------------------------------------------------------- |
||||
*/ |
||||
int dev_read (void *buffer, int where, int len) |
||||
{ |
||||
PRINTF ("dev_read (len = %d, where = %d)\n", len, where); |
||||
|
||||
/* Si on ne desire pas lire a la position courante, il faut un seek */ |
||||
if (where != lastwhere) { |
||||
if (!fdc_fdos_seek (where)) { |
||||
PRINTF ("seek error in dev_read"); |
||||
lastwhere = -1; |
||||
return (-1); |
||||
} |
||||
} |
||||
|
||||
if (!fdc_fdos_read (buffer, len)) { |
||||
PRINTF ("read error\n"); |
||||
lastwhere = -1; |
||||
return (-1); |
||||
} |
||||
lastwhere = where + len; |
||||
return (0); |
||||
} |
||||
/*-----------------------------------------------------------------------------
|
||||
* check_dev -- verify the diskette format |
||||
*----------------------------------------------------------------------------- |
||||
*/ |
||||
int check_dev (BootSector_t *boot, Fs_t *fs) |
||||
{ |
||||
unsigned int heads, sectors, tracks; |
||||
int BootP, Infp0, InfpX, InfTm; |
||||
int sect_per_track; |
||||
|
||||
/* Display Boot header */ |
||||
PRINTF ("Jump to boot code 0x%02x 0x%02x 0x%02x\n", |
||||
boot -> jump [0], boot -> jump [1], boot -> jump[2]); |
||||
PRINTF ("OEM name & version '%*.*s'\n", |
||||
BANNER_LG, BANNER_LG, boot -> banner ); |
||||
PRINTF ("Bytes per sector hopefully 512 %d\n", |
||||
__le16_to_cpu (boot -> secsiz)); |
||||
PRINTF ("Cluster size in sectors %d\n", |
||||
boot -> clsiz); |
||||
PRINTF ("Number of reserved (boot) sectors %d\n", |
||||
__le16_to_cpu (boot -> nrsvsect)); |
||||
PRINTF ("Number of FAT tables hopefully 2 %d\n", |
||||
boot -> nfat); |
||||
PRINTF ("Number of directory slots %d\n", |
||||
__le16_to_cpu (boot -> dirents)); |
||||
PRINTF ("Total sectors on disk %d\n", |
||||
__le16_to_cpu (boot -> psect)); |
||||
PRINTF ("Media descriptor=first byte of FAT %d\n", |
||||
boot -> descr); |
||||
PRINTF ("Sectors in FAT %d\n", |
||||
__le16_to_cpu (boot -> fatlen)); |
||||
PRINTF ("Sectors/track %d\n", |
||||
__le16_to_cpu (boot -> nsect)); |
||||
PRINTF ("Heads %d\n", |
||||
__le16_to_cpu (boot -> nheads)); |
||||
PRINTF ("number of hidden sectors %d\n", |
||||
__le32_to_cpu (boot -> nhs)); |
||||
PRINTF ("big total sectors %d\n", |
||||
__le32_to_cpu (boot -> bigsect)); |
||||
PRINTF ("physical drive ? %d\n", |
||||
boot -> physdrive); |
||||
PRINTF ("reserved %d\n", |
||||
boot -> reserved); |
||||
PRINTF ("dos > 4.0 diskette %d\n", |
||||
boot -> dos4); |
||||
PRINTF ("serial number %d\n", |
||||
__le32_to_cpu (boot -> serial)); |
||||
PRINTF ("disk label %*.*s\n", |
||||
LABEL_LG, LABEL_LG, boot -> label); |
||||
PRINTF ("FAT type %8.8s\n", |
||||
boot -> fat_type); |
||||
PRINTF ("reserved by 2M %d\n", |
||||
boot -> res_2m); |
||||
PRINTF ("2M checksum (not used) %d\n", |
||||
boot -> CheckSum); |
||||
PRINTF ("2MF format version %d\n", |
||||
boot -> fmt_2mf); |
||||
PRINTF ("1 if write track after format %d\n", |
||||
boot -> wt); |
||||
PRINTF ("data transfer rate on track 0 %d\n", |
||||
boot -> rate_0); |
||||
PRINTF ("data transfer rate on track<>0 %d\n", |
||||
boot -> rate_any); |
||||
PRINTF ("offset to boot program %d\n", |
||||
__le16_to_cpu (boot -> BootP)); |
||||
PRINTF ("T1: information for track 0 %d\n", |
||||
__le16_to_cpu (boot -> Infp0)); |
||||
PRINTF ("T2: information for track<>0 %d\n", |
||||
__le16_to_cpu (boot -> InfpX)); |
||||
PRINTF ("T3: track sectors size table %d\n", |
||||
__le16_to_cpu (boot -> InfTm)); |
||||
PRINTF ("Format date 0x%04x\n", |
||||
__le16_to_cpu (boot -> DateF)); |
||||
PRINTF ("Format time 0x%04x\n", |
||||
__le16_to_cpu (boot -> TimeF)); |
||||
|
||||
|
||||
/* information is extracted from boot sector */ |
||||
heads = __le16_to_cpu (boot -> nheads); |
||||
sectors = __le16_to_cpu (boot -> nsect); |
||||
fs -> tot_sectors = __le32_to_cpu (boot -> bigsect); |
||||
if (__le16_to_cpu (boot -> psect) != 0) { |
||||
fs -> tot_sectors = __le16_to_cpu (boot -> psect); |
||||
} |
||||
|
||||
sect_per_track = heads * sectors; |
||||
tracks = (fs -> tot_sectors + sect_per_track - 1) / sect_per_track; |
||||
|
||||
BootP = __le16_to_cpu (boot -> BootP); |
||||
Infp0 = __le16_to_cpu (boot -> Infp0); |
||||
InfpX = __le16_to_cpu (boot -> InfpX); |
||||
InfTm = __le16_to_cpu (boot -> InfTm); |
||||
|
||||
if (boot -> dos4 == EXTENDED_BOOT && |
||||
strncmp( boot->banner,"2M", 2 ) == 0 && |
||||
BootP < SZ_STD_SECTOR && |
||||
Infp0 < SZ_STD_SECTOR && |
||||
InfpX < SZ_STD_SECTOR && |
||||
InfTm < SZ_STD_SECTOR && |
||||
BootP >= InfTm + 2 && |
||||
InfTm >= InfpX && |
||||
InfpX >= Infp0 && |
||||
Infp0 >= 76 ) { |
||||
|
||||
return (-1); |
||||
} |
||||
|
||||
if (heads != NB_HEADS || |
||||
tracks != NB_TRACKS || |
||||
sectors != NB_SECTORS || |
||||
__le16_to_cpu (boot -> secsiz) != SZ_STD_SECTOR || |
||||
fs -> tot_sectors == 0 || |
||||
(fs -> tot_sectors % sectors) != 0) { |
||||
return (-1); |
||||
} |
||||
|
||||
return (0); |
||||
} |
@ -1,159 +0,0 @@ |
||||
/*
|
||||
* (C) Copyright 2002 |
||||
* Stäubli Faverges - <www.staubli.com> |
||||
* Pierre AUBERT p.aubert@staubli.com |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
#ifndef _DOS_H_ |
||||
#define _DOS_H_ |
||||
|
||||
/* Definitions for Dos diskettes */ |
||||
|
||||
/* General definitions */ |
||||
#define SZ_STD_SECTOR 512 /* Standard sector size */ |
||||
#define MDIR_SIZE 32 /* Direntry size */ |
||||
#define FAT_BITS 12 /* Diskette use 12 bits fat */ |
||||
|
||||
#define MAX_PATH 128 /* Max size of the MSDOS PATH */ |
||||
#define MAX_DIR_SECS 64 /* Taille max d'un repertoire (en */ |
||||
/* secteurs) */ |
||||
/* Misc. definitions */ |
||||
#define DELMARK '\xe5' |
||||
#define EXTENDED_BOOT (0x29) |
||||
#define MEDIA_STD (0xf0) |
||||
#define JUMP_0_1 (0xe9) |
||||
#define JUMP_0_2 (0xeb) |
||||
|
||||
/* Boot size is 256 bytes, but we need to read almost a sector, then
|
||||
assume bootsize is 512 */ |
||||
#define BOOTSIZE 512 |
||||
|
||||
/* Fat definitions for 12 bits fat */ |
||||
#define FAT12_MAX_NB 4086 |
||||
#define FAT12_LAST 0x0ff6 |
||||
#define FAT12_END 0x0fff |
||||
|
||||
/* file attributes */ |
||||
#define ATTR_READONLY 0x01 |
||||
#define ATTR_HIDDEN 0x02 |
||||
#define ATTR_SYSTEM 0x04 |
||||
#define ATTR_VOLUME 0x08 |
||||
#define ATTR_DIRECTORY 0x10 |
||||
#define ATTR_ARCHIVE 0x20 |
||||
#define ATTR_VSE 0x0f |
||||
|
||||
/* Name format */ |
||||
#define EXTCASE 0x10 |
||||
#define BASECASE 0x8 |
||||
|
||||
/* Definition of the boot sector */ |
||||
#define BANNER_LG 8 |
||||
#define LABEL_LG 11 |
||||
|
||||
typedef struct bootsector |
||||
{ |
||||
unsigned char jump [3]; /* 0 Jump to boot code */ |
||||
char banner [BANNER_LG]; /* 3 OEM name & version */ |
||||
unsigned short secsiz; /* 11 Bytes per sector hopefully 512 */ |
||||
unsigned char clsiz; /* 13 Cluster size in sectors */ |
||||
unsigned short nrsvsect; /* 14 Number of reserved (boot) sectors */ |
||||
unsigned char nfat; /* 16 Number of FAT tables hopefully 2 */ |
||||
unsigned short dirents; /* 17 Number of directory slots */ |
||||
unsigned short psect; /* 19 Total sectors on disk */ |
||||
unsigned char descr; /* 21 Media descriptor=first byte of FAT */ |
||||
unsigned short fatlen; /* 22 Sectors in FAT */ |
||||
unsigned short nsect; /* 24 Sectors/track */ |
||||
unsigned short nheads; /* 26 Heads */ |
||||
unsigned int nhs; /* 28 number of hidden sectors */ |
||||
unsigned int bigsect; /* 32 big total sectors */ |
||||
unsigned char physdrive; /* 36 physical drive ? */ |
||||
unsigned char reserved; /* 37 reserved */ |
||||
unsigned char dos4; /* 38 dos > 4.0 diskette */ |
||||
unsigned int serial; /* 39 serial number */ |
||||
char label [LABEL_LG]; /* 43 disk label */ |
||||
char fat_type [8]; /* 54 FAT type */ |
||||
unsigned char res_2m; /* 62 reserved by 2M */ |
||||
unsigned char CheckSum; /* 63 2M checksum (not used) */ |
||||
unsigned char fmt_2mf; /* 64 2MF format version */ |
||||
unsigned char wt; /* 65 1 if write track after format */ |
||||
unsigned char rate_0; /* 66 data transfer rate on track 0 */ |
||||
unsigned char rate_any; /* 67 data transfer rate on track<>0 */ |
||||
unsigned short BootP; /* 68 offset to boot program */ |
||||
unsigned short Infp0; /* 70 T1: information for track 0 */ |
||||
unsigned short InfpX; /* 72 T2: information for track<>0 */ |
||||
unsigned short InfTm; /* 74 T3: track sectors size table */ |
||||
unsigned short DateF; /* 76 Format date */ |
||||
unsigned short TimeF; /* 78 Format time */ |
||||
unsigned char junk [BOOTSIZE - 80]; /* 80 remaining data */ |
||||
} __attribute__ ((packed)) BootSector_t; |
||||
|
||||
/* Structure d'une entree de repertoire */ |
||||
typedef struct directory { |
||||
char name [8]; /* file name */ |
||||
char ext [3]; /* file extension */ |
||||
unsigned char attr; /* attribute byte */ |
||||
unsigned char Case; /* case of short filename */ |
||||
unsigned char reserved [9]; /* ?? */ |
||||
unsigned char time [2]; /* time stamp */ |
||||
unsigned char date [2]; /* date stamp */ |
||||
unsigned short start; /* starting cluster number */ |
||||
unsigned int size; /* size of the file */ |
||||
} __attribute__ ((packed)) Directory_t; |
||||
|
||||
|
||||
#define MAX_VFAT_SUBENTRIES 20 |
||||
#define VSE_NAMELEN 13 |
||||
|
||||
#define VSE1SIZE 5 |
||||
#define VSE2SIZE 6 |
||||
#define VSE3SIZE 2 |
||||
|
||||
#define VBUFSIZE ((MAX_VFAT_SUBENTRIES * VSE_NAMELEN) + 1) |
||||
|
||||
#define MAX_VNAMELEN (255) |
||||
|
||||
#define VSE_PRESENT 0x01 |
||||
#define VSE_LAST 0x40 |
||||
#define VSE_MASK 0x1f |
||||
|
||||
/* Flag used by vfat_lookup */ |
||||
#define DO_OPEN 1 |
||||
#define ACCEPT_PLAIN 0x20 |
||||
#define ACCEPT_DIR 0x10 |
||||
#define ACCEPT_LABEL 0x08 |
||||
#define SINGLE 2 |
||||
#define MATCH_ANY 0x40 |
||||
|
||||
struct vfat_subentry { |
||||
unsigned char id; /* VSE_LAST pour la fin, VSE_MASK */ |
||||
/* pour un VSE */ |
||||
char text1 [VSE1SIZE * 2]; /* Caracteres encodes sur 16 bits */ |
||||
unsigned char attribute; /* 0x0f pour les VFAT */ |
||||
unsigned char hash1; /* toujours 0 */ |
||||
unsigned char sum; /* Checksum du nom court */ |
||||
char text2 [VSE2SIZE * 2]; /* Caracteres encodes sur 16 bits */ |
||||
unsigned char sector_l; /* 0 pour les VFAT */ |
||||
unsigned char sector_u; /* 0 pour les VFAT */ |
||||
char text3 [VSE3SIZE * 2]; /* Caracteres encodes sur 16 bits */ |
||||
} __attribute__ ((packed)) ; |
||||
|
||||
struct vfat_state { |
||||
char name [VBUFSIZE]; |
||||
int status; /* is now a bit map of 32 bits */ |
||||
int subentries; |
||||
unsigned char sum; /* no need to remember the sum for each */ |
||||
/* entry, it is the same anyways */ |
||||
} __attribute__ ((packed)) ; |
||||
|
||||
/* Conversion macros */ |
||||
#define DOS_YEAR(dir) (((dir)->date[1] >> 1) + 1980) |
||||
#define DOS_MONTH(dir) (((((dir)->date[1]&0x1) << 3) + ((dir)->date[0] >> 5))) |
||||
#define DOS_DAY(dir) ((dir)->date[0] & 0x1f) |
||||
#define DOS_HOUR(dir) ((dir)->time[1] >> 3) |
||||
#define DOS_MINUTE(dir) (((((dir)->time[1]&0x7) << 3) + ((dir)->time[0] >> 5))) |
||||
#define DOS_SEC(dir) (((dir)->time[0] & 0x1f) * 2) |
||||
|
||||
|
||||
#endif |
@ -1,122 +0,0 @@ |
||||
/*
|
||||
* (C) Copyright 2002 |
||||
* Stäubli Faverges - <www.staubli.com> |
||||
* Pierre AUBERT p.aubert@staubli.com |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <config.h> |
||||
#include <malloc.h> |
||||
|
||||
#include "dos.h" |
||||
#include "fdos.h" |
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
* fat_decode -- |
||||
*----------------------------------------------------------------------------- |
||||
*/ |
||||
unsigned int fat_decode (Fs_t *fs, unsigned int num) |
||||
{ |
||||
unsigned int start = num * 3 / 2; |
||||
unsigned char *address = fs -> fat_buf + start; |
||||
|
||||
if (num < 2 || start + 1 > (fs -> fat_len * SZ_STD_SECTOR)) |
||||
return 1; |
||||
|
||||
if (num & 1) |
||||
return ((address [1] & 0xff) << 4) | ((address [0] & 0xf0 ) >> 4); |
||||
else |
||||
return ((address [1] & 0xf) << 8) | (address [0] & 0xff ); |
||||
} |
||||
/*-----------------------------------------------------------------------------
|
||||
* check_fat -- |
||||
*----------------------------------------------------------------------------- |
||||
*/ |
||||
static int check_fat (Fs_t *fs) |
||||
{ |
||||
int i, f; |
||||
|
||||
/* Cluster verification */ |
||||
for (i = 3 ; i < fs -> num_clus; i++){ |
||||
f = fat_decode (fs, i); |
||||
if (f < FAT12_LAST && f > fs -> num_clus){ |
||||
/* Wrong cluster number detected */ |
||||
return (-1); |
||||
} |
||||
} |
||||
return (0); |
||||
} |
||||
/*-----------------------------------------------------------------------------
|
||||
* read_one_fat -- |
||||
*----------------------------------------------------------------------------- |
||||
*/ |
||||
static int read_one_fat (BootSector_t *boot, Fs_t *fs, int nfat) |
||||
{ |
||||
if (dev_read (fs -> fat_buf, |
||||
(fs -> fat_start + nfat * fs -> fat_len), |
||||
fs -> fat_len) < 0) { |
||||
return (-1); |
||||
} |
||||
|
||||
if (fs -> fat_buf [0] || fs -> fat_buf [1] || fs -> fat_buf [2]) { |
||||
if ((fs -> fat_buf [0] != boot -> descr && |
||||
(fs -> fat_buf [0] != 0xf9 || boot -> descr != MEDIA_STD)) || |
||||
fs -> fat_buf [0] < MEDIA_STD){ |
||||
/* Unknown Media */ |
||||
return (-1); |
||||
} |
||||
if (fs -> fat_buf [1] != 0xff || fs -> fat_buf [2] != 0xff){ |
||||
/* FAT doesn't start with good values */ |
||||
return (-1); |
||||
} |
||||
} |
||||
|
||||
if (fs -> num_clus >= FAT12_MAX_NB) { |
||||
/* Too much clusters */ |
||||
return (-1); |
||||
} |
||||
|
||||
return check_fat (fs); |
||||
} |
||||
/*-----------------------------------------------------------------------------
|
||||
* read_fat -- |
||||
*----------------------------------------------------------------------------- |
||||
*/ |
||||
int read_fat (BootSector_t *boot, Fs_t *fs) |
||||
{ |
||||
unsigned int buflen; |
||||
int i; |
||||
|
||||
/* Allocate Fat Buffer */ |
||||
buflen = fs -> fat_len * SZ_STD_SECTOR; |
||||
if (fs -> fat_buf) { |
||||
free (fs -> fat_buf); |
||||
} |
||||
|
||||
if ((fs -> fat_buf = malloc (buflen)) == NULL) { |
||||
return (-1); |
||||
} |
||||
|
||||
/* Try to read each Fat */ |
||||
for (i = 0; i< fs -> nb_fat; i++){ |
||||
if (read_one_fat (boot, fs, i) == 0) { |
||||
/* Fat is OK */ |
||||
fs -> num_fat = i; |
||||
break; |
||||
} |
||||
} |
||||
|
||||
if (i == fs -> nb_fat){ |
||||
return (-1); |
||||
} |
||||
|
||||
if (fs -> fat_len > (((fs -> num_clus + 2) * |
||||
(FAT_BITS / 4) -1 ) / 2 / |
||||
SZ_STD_SECTOR + 1)) { |
||||
return (-1); |
||||
} |
||||
return (0); |
||||
} |
@ -1,156 +0,0 @@ |
||||
/*
|
||||
* (C) Copyright 2002 |
||||
* Stäubli Faverges - <www.staubli.com> |
||||
* Pierre AUBERT p.aubert@staubli.com |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <config.h> |
||||
#include <malloc.h> |
||||
|
||||
#include "dos.h" |
||||
#include "fdos.h" |
||||
|
||||
|
||||
const char *month [] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; |
||||
|
||||
Fs_t fs; |
||||
File_t file; |
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
* dos_open -- |
||||
*----------------------------------------------------------------------------- |
||||
*/ |
||||
int dos_open(char *name) |
||||
{ |
||||
int lg; |
||||
int entry; |
||||
char *fname; |
||||
|
||||
/* We need to suppress the " char around the name */ |
||||
if (name [0] == '"') { |
||||
name ++; |
||||
} |
||||
lg = strlen (name); |
||||
if (name [lg - 1] == '"') { |
||||
name [lg - 1] = '\0'; |
||||
} |
||||
|
||||
/* Open file system */ |
||||
if (fs_init (&fs) < 0) { |
||||
return -1; |
||||
} |
||||
|
||||
/* Init the file descriptor */ |
||||
file.name = name; |
||||
file.fs = &fs; |
||||
|
||||
/* find the subdirectory containing the file */ |
||||
if (open_subdir (&file) < 0) { |
||||
return (-1); |
||||
} |
||||
|
||||
fname = basename (name); |
||||
|
||||
/* if we try to open root directory */ |
||||
if (*fname == '\0') { |
||||
file.file = file.subdir; |
||||
return (0); |
||||
} |
||||
|
||||
/* find the file in the subdir */ |
||||
entry = 0; |
||||
if (vfat_lookup (&file.subdir, |
||||
file.fs, |
||||
&file.file.dir, |
||||
&entry, |
||||
0, |
||||
fname, |
||||
ACCEPT_DIR | ACCEPT_PLAIN | SINGLE | DO_OPEN, |
||||
0, |
||||
&file.file) != 0) { |
||||
/* File not found */ |
||||
printf ("File not found\n"); |
||||
return (-1); |
||||
} |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
* dos_read -- |
||||
*----------------------------------------------------------------------------- |
||||
*/ |
||||
int dos_read (ulong addr) |
||||
{ |
||||
int read = 0, nb; |
||||
|
||||
/* Try to boot a directory ? */ |
||||
if (file.file.dir.attr & (ATTR_DIRECTORY | ATTR_VOLUME)) { |
||||
printf ("Unable to boot %s !!\n", file.name); |
||||
return (-1); |
||||
} |
||||
while (read < file.file.FileSize) { |
||||
PRINTF ("read_file (%ld)\n", (file.file.FileSize - read)); |
||||
nb = read_file (&fs, |
||||
&file.file, |
||||
(char *)addr + read, |
||||
read, |
||||
(file.file.FileSize - read)); |
||||
PRINTF ("read_file -> %d\n", nb); |
||||
if (nb < 0) { |
||||
printf ("read error\n"); |
||||
return (-1); |
||||
} |
||||
read += nb; |
||||
} |
||||
return (read); |
||||
} |
||||
/*-----------------------------------------------------------------------------
|
||||
* dos_dir -- |
||||
*----------------------------------------------------------------------------- |
||||
*/ |
||||
int dos_dir (void) |
||||
{ |
||||
int entry; |
||||
Directory_t dir; |
||||
char *name; |
||||
|
||||
|
||||
if ((file.file.dir.attr & ATTR_DIRECTORY) == 0) { |
||||
printf ("%s: not a directory !!\n", file.name); |
||||
return (1); |
||||
} |
||||
entry = 0; |
||||
if ((name = malloc (MAX_VNAMELEN + 1)) == NULL) { |
||||
PRINTF ("Allcation error\n"); |
||||
return (1); |
||||
} |
||||
|
||||
while (vfat_lookup (&file.file, |
||||
file.fs, |
||||
&dir, |
||||
&entry, |
||||
0, |
||||
NULL, |
||||
ACCEPT_DIR | ACCEPT_PLAIN | MATCH_ANY, |
||||
name, |
||||
NULL) == 0) { |
||||
/* Display file info */ |
||||
printf ("%3.3s %9d %s %02d %04d %02d:%02d:%02d %s\n", |
||||
(dir.attr & ATTR_DIRECTORY) ? "dir" : " ", |
||||
__le32_to_cpu (dir.size), |
||||
month [DOS_MONTH (&dir) - 1], |
||||
DOS_DAY (&dir), |
||||
DOS_YEAR (&dir), |
||||
DOS_HOUR (&dir), |
||||
DOS_MINUTE (&dir), |
||||
DOS_SEC (&dir), |
||||
name); |
||||
|
||||
} |
||||
free (name); |
||||
return (0); |
||||
} |
@ -1,100 +0,0 @@ |
||||
/*
|
||||
* (C) Copyright 2002 |
||||
* Stäubli Faverges - <www.staubli.com> |
||||
* Pierre AUBERT p.aubert@staubli.com |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
#ifndef _FDOS_H_ |
||||
#define _FDOS_H_ |
||||
|
||||
|
||||
#undef FDOS_DEBUG |
||||
|
||||
#ifdef FDOS_DEBUG |
||||
#define PRINTF(fmt,args...) printf (fmt ,##args) |
||||
#else |
||||
#define PRINTF(fmt,args...) |
||||
#endif |
||||
|
||||
/* Data structure describing media */ |
||||
typedef struct fs |
||||
{ |
||||
unsigned long tot_sectors; |
||||
|
||||
int cluster_size; |
||||
int num_clus; |
||||
|
||||
int fat_start; |
||||
int fat_len; |
||||
int nb_fat; |
||||
int num_fat; |
||||
|
||||
int dir_start; |
||||
int dir_len; |
||||
|
||||
unsigned char *fat_buf; |
||||
|
||||
} Fs_t; |
||||
|
||||
/* Data structure describing one file system slot */ |
||||
typedef struct slot { |
||||
int (*map) (struct fs *fs, |
||||
struct slot *file, |
||||
int where, |
||||
int *len); |
||||
unsigned long FileSize; |
||||
|
||||
unsigned short int FirstAbsCluNr; |
||||
unsigned short int PreviousAbsCluNr; |
||||
unsigned short int PreviousRelCluNr; |
||||
|
||||
Directory_t dir; |
||||
} Slot_t; |
||||
|
||||
typedef struct file { |
||||
char *name; |
||||
int Case; |
||||
Fs_t *fs; |
||||
Slot_t subdir; |
||||
Slot_t file; |
||||
} File_t; |
||||
|
||||
|
||||
/* dev.c */ |
||||
int dev_read (void *buffer, int where, int len); |
||||
int dev_open (void); |
||||
int check_dev (BootSector_t *boot, Fs_t *fs); |
||||
|
||||
/* fat.c */ |
||||
unsigned int fat_decode (Fs_t *fs, unsigned int num); |
||||
int read_fat (BootSector_t *boot, Fs_t *fs); |
||||
|
||||
/* vfat.c */ |
||||
int vfat_lookup (Slot_t *dir, |
||||
Fs_t *fs, |
||||
Directory_t *dirent, |
||||
int *entry, |
||||
int *vfat_start, |
||||
char *filename, |
||||
int flags, |
||||
char *outname, |
||||
Slot_t *file); |
||||
|
||||
/* subdir.c */ |
||||
char *basename (char *name); |
||||
int open_subdir (File_t *desc); |
||||
int open_file (Slot_t *file, Directory_t *dir); |
||||
int read_file (Fs_t *fs, |
||||
Slot_t *file, |
||||
char *buf, |
||||
int where, |
||||
int len); |
||||
void init_subdir (void); |
||||
|
||||
/* fs.c */ |
||||
int fs_init (Fs_t *fs); |
||||
|
||||
|
||||
#endif |
@ -1,98 +0,0 @@ |
||||
/*
|
||||
* (C) Copyright 2002 |
||||
* Stäubli Faverges - <www.staubli.com> |
||||
* Pierre AUBERT p.aubert@staubli.com |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <config.h> |
||||
#include <malloc.h> |
||||
|
||||
#include "dos.h" |
||||
#include "fdos.h" |
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
* fill_fs -- Read info on file system |
||||
*----------------------------------------------------------------------------- |
||||
*/ |
||||
static int fill_fs (BootSector_t *boot, Fs_t *fs) |
||||
{ |
||||
|
||||
fs -> fat_start = __le16_to_cpu (boot -> nrsvsect); |
||||
fs -> fat_len = __le16_to_cpu (boot -> fatlen); |
||||
fs -> nb_fat = boot -> nfat; |
||||
|
||||
fs -> dir_start = fs -> fat_start + fs -> nb_fat * fs -> fat_len; |
||||
fs -> dir_len = __le16_to_cpu (boot -> dirents) * MDIR_SIZE / SZ_STD_SECTOR; |
||||
fs -> cluster_size = boot -> clsiz; |
||||
fs -> num_clus = (fs -> tot_sectors - fs -> dir_start - fs -> dir_len) / fs -> cluster_size; |
||||
|
||||
return (0); |
||||
} |
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
* fs_init -- |
||||
*----------------------------------------------------------------------------- |
||||
*/ |
||||
int fs_init (Fs_t *fs) |
||||
{ |
||||
BootSector_t *boot; |
||||
|
||||
/* Initialize physical device */ |
||||
if (dev_open () < 0) { |
||||
PRINTF ("Unable to initialize the fdc\n"); |
||||
return (-1); |
||||
} |
||||
init_subdir (); |
||||
|
||||
/* Allocate space for read the boot sector */ |
||||
if ((boot = (BootSector_t *)malloc (sizeof (BootSector_t))) == NULL) { |
||||
PRINTF ("Unable to allocate space for boot sector\n"); |
||||
return (-1); |
||||
} |
||||
|
||||
/* read boot sector */ |
||||
if (dev_read (boot, 0, 1)){ |
||||
PRINTF ("Error during boot sector read\n"); |
||||
free (boot); |
||||
return (-1); |
||||
} |
||||
|
||||
/* we verify it'a a DOS diskette */ |
||||
if (boot -> jump [0] != JUMP_0_1 && boot -> jump [0] != JUMP_0_2) { |
||||
PRINTF ("Not a DOS diskette\n"); |
||||
free (boot); |
||||
return (-1); |
||||
} |
||||
|
||||
if (boot -> descr < MEDIA_STD) { |
||||
/* We handle only recent medias (type F0) */ |
||||
PRINTF ("unrecognized diskette type\n"); |
||||
free (boot); |
||||
return (-1); |
||||
} |
||||
|
||||
if (check_dev (boot, fs) < 0) { |
||||
PRINTF ("Bad diskette\n"); |
||||
free (boot); |
||||
return (-1); |
||||
} |
||||
|
||||
if (fill_fs (boot, fs) < 0) { |
||||
free (boot); |
||||
|
||||
return (-1); |
||||
} |
||||
|
||||
/* Read FAT */ |
||||
if (read_fat (boot, fs) < 0) { |
||||
free (boot); |
||||
return (-1); |
||||
} |
||||
|
||||
free (boot); |
||||
return (0); |
||||
} |
@ -1,329 +0,0 @@ |
||||
/*
|
||||
* (C) Copyright 2002 |
||||
* Stäubli Faverges - <www.staubli.com> |
||||
* Pierre AUBERT p.aubert@staubli.com |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <config.h> |
||||
#include <malloc.h> |
||||
|
||||
#include "dos.h" |
||||
#include "fdos.h" |
||||
|
||||
static int cache_sect; |
||||
static unsigned char cache [SZ_STD_SECTOR]; |
||||
|
||||
|
||||
#define min(x,y) ((x)<(y)?(x):(y)) |
||||
|
||||
static int descend (Slot_t *parent, |
||||
Fs_t *fs, |
||||
char *path); |
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
* init_subdir -- |
||||
*----------------------------------------------------------------------------- |
||||
*/ |
||||
void init_subdir (void) |
||||
{ |
||||
cache_sect = -1; |
||||
} |
||||
/*-----------------------------------------------------------------------------
|
||||
* basename -- |
||||
*----------------------------------------------------------------------------- |
||||
*/ |
||||
char *basename (char *name) |
||||
{ |
||||
register char *cptr; |
||||
|
||||
if (!name || !*name) { |
||||
return (""); |
||||
} |
||||
|
||||
for (cptr= name; *cptr++; ); |
||||
while (--cptr >= name) { |
||||
if (*cptr == '/') { |
||||
return (cptr + 1); |
||||
} |
||||
} |
||||
return(name); |
||||
} |
||||
/*-----------------------------------------------------------------------------
|
||||
* root_map -- |
||||
*----------------------------------------------------------------------------- |
||||
*/ |
||||
static int root_map (Fs_t *fs, Slot_t *file, int where, int *len) |
||||
{ |
||||
*len = min (*len, fs -> dir_len * SZ_STD_SECTOR - where); |
||||
if (*len < 0 ) { |
||||
*len = 0; |
||||
return (-1); |
||||
} |
||||
return fs -> dir_start * SZ_STD_SECTOR + where; |
||||
} |
||||
/*-----------------------------------------------------------------------------
|
||||
* normal_map -- |
||||
*----------------------------------------------------------------------------- |
||||
*/ |
||||
static int normal_map (Fs_t *fs, Slot_t *file, int where, int *len) |
||||
{ |
||||
int offset; |
||||
int NrClu; |
||||
unsigned short RelCluNr; |
||||
unsigned short CurCluNr; |
||||
unsigned short NewCluNr; |
||||
unsigned short AbsCluNr; |
||||
int clus_size; |
||||
|
||||
clus_size = fs -> cluster_size * SZ_STD_SECTOR; |
||||
offset = where % clus_size; |
||||
|
||||
*len = min (*len, file -> FileSize - where); |
||||
|
||||
if (*len < 0 ) { |
||||
*len = 0; |
||||
return (0); |
||||
} |
||||
|
||||
if (file -> FirstAbsCluNr < 2){ |
||||
*len = 0; |
||||
return (0); |
||||
} |
||||
|
||||
RelCluNr = where / clus_size; |
||||
|
||||
if (RelCluNr >= file -> PreviousRelCluNr){ |
||||
CurCluNr = file -> PreviousRelCluNr; |
||||
AbsCluNr = file -> PreviousAbsCluNr; |
||||
} else { |
||||
CurCluNr = 0; |
||||
AbsCluNr = file -> FirstAbsCluNr; |
||||
} |
||||
|
||||
|
||||
NrClu = (offset + *len - 1) / clus_size; |
||||
while (CurCluNr <= RelCluNr + NrClu) { |
||||
if (CurCluNr == RelCluNr){ |
||||
/* we have reached the beginning of our zone. Save
|
||||
* coordinates */ |
||||
file -> PreviousRelCluNr = RelCluNr; |
||||
file -> PreviousAbsCluNr = AbsCluNr; |
||||
} |
||||
NewCluNr = fat_decode (fs, AbsCluNr); |
||||
if (NewCluNr == 1 || NewCluNr == 0) { |
||||
PRINTF("Fat problem while decoding %d %x\n", |
||||
AbsCluNr, NewCluNr); |
||||
return (-1); |
||||
} |
||||
if (CurCluNr == RelCluNr + NrClu) { |
||||
break; |
||||
} |
||||
|
||||
if (CurCluNr < RelCluNr && NewCluNr == FAT12_END) { |
||||
*len = 0; |
||||
return 0; |
||||
} |
||||
|
||||
if (CurCluNr >= RelCluNr && NewCluNr != AbsCluNr + 1) |
||||
break; |
||||
CurCluNr++; |
||||
AbsCluNr = NewCluNr; |
||||
} |
||||
|
||||
*len = min (*len, (1 + CurCluNr - RelCluNr) * clus_size - offset); |
||||
|
||||
return (((file -> PreviousAbsCluNr - 2) * fs -> cluster_size + |
||||
fs -> dir_start + fs -> dir_len) * |
||||
SZ_STD_SECTOR + offset); |
||||
} |
||||
/*-----------------------------------------------------------------------------
|
||||
* open_subdir -- open the subdir containing the file |
||||
*----------------------------------------------------------------------------- |
||||
*/ |
||||
int open_subdir (File_t *desc) |
||||
{ |
||||
char *pathname; |
||||
char *tmp, *s, *path; |
||||
char terminator; |
||||
|
||||
if ((pathname = (char *)malloc (MAX_PATH)) == NULL) { |
||||
return (-1); |
||||
} |
||||
|
||||
strcpy (pathname, desc -> name); |
||||
|
||||
/* Suppress file name */ |
||||
tmp = basename (pathname); |
||||
*tmp = '\0'; |
||||
|
||||
/* root directory init */ |
||||
desc -> subdir.FirstAbsCluNr = 0; |
||||
desc -> subdir.FileSize = -1; |
||||
desc -> subdir.map = root_map; |
||||
desc -> subdir.dir.attr = ATTR_DIRECTORY; |
||||
|
||||
tmp = pathname; |
||||
for (s = tmp; ; ++s) { |
||||
if (*s == '/' || *s == '\0') { |
||||
path = tmp; |
||||
terminator = *s; |
||||
*s = '\0'; |
||||
if (s != tmp && strcmp (path,".")) { |
||||
if (descend (&desc -> subdir, desc -> fs, path) < 0) { |
||||
free (pathname); |
||||
return (-1); |
||||
} |
||||
} |
||||
if (terminator == 0) { |
||||
break; |
||||
} |
||||
tmp = s + 1; |
||||
} |
||||
} |
||||
free (pathname); |
||||
return (0); |
||||
} |
||||
/*-----------------------------------------------------------------------------
|
||||
* descend -- |
||||
*----------------------------------------------------------------------------- |
||||
*/ |
||||
static int descend (Slot_t *parent, |
||||
Fs_t *fs, |
||||
char *path) |
||||
{ |
||||
int entry; |
||||
Slot_t SubDir; |
||||
|
||||
if(path[0] == '\0' || strcmp (path, ".") == 0) { |
||||
return (0); |
||||
} |
||||
|
||||
|
||||
entry = 0; |
||||
if (vfat_lookup (parent, |
||||
fs, |
||||
&(SubDir.dir), |
||||
&entry, |
||||
0, |
||||
path, |
||||
ACCEPT_DIR | SINGLE | DO_OPEN, |
||||
0, |
||||
&SubDir) == 0) { |
||||
*parent = SubDir; |
||||
return (0); |
||||
} |
||||
|
||||
if (strcmp(path, "..") == 0) { |
||||
parent -> FileSize = -1; |
||||
parent -> FirstAbsCluNr = 0; |
||||
parent -> map = root_map; |
||||
return (0); |
||||
} |
||||
return (-1); |
||||
} |
||||
/*-----------------------------------------------------------------------------
|
||||
* open_file -- |
||||
*----------------------------------------------------------------------------- |
||||
*/ |
||||
int open_file (Slot_t *file, Directory_t *dir) |
||||
{ |
||||
int first; |
||||
unsigned long size; |
||||
|
||||
first = __le16_to_cpu (dir -> start); |
||||
|
||||
if(first == 0 && |
||||
(dir -> attr & ATTR_DIRECTORY) != 0) { |
||||
file -> FirstAbsCluNr = 0; |
||||
file -> FileSize = -1; |
||||
file -> map = root_map; |
||||
return (0); |
||||
} |
||||
|
||||
if ((dir -> attr & ATTR_DIRECTORY) != 0) { |
||||
size = (1UL << 31) - 1; |
||||
} |
||||
else { |
||||
size = __le32_to_cpu (dir -> size); |
||||
} |
||||
|
||||
file -> map = normal_map; |
||||
file -> FirstAbsCluNr = first; |
||||
file -> PreviousRelCluNr = 0xffff; |
||||
file -> FileSize = size; |
||||
return (0); |
||||
} |
||||
/*-----------------------------------------------------------------------------
|
||||
* read_file -- |
||||
*----------------------------------------------------------------------------- |
||||
*/ |
||||
int read_file (Fs_t *fs, |
||||
Slot_t *file, |
||||
char *buf, |
||||
int where, |
||||
int len) |
||||
{ |
||||
int pos; |
||||
int read, nb, sect, offset; |
||||
|
||||
pos = file -> map (fs, file, where, &len); |
||||
if (pos < 0) { |
||||
return -1; |
||||
} |
||||
if (len == 0) { |
||||
return (0); |
||||
} |
||||
|
||||
/* Compute sector number */ |
||||
sect = pos / SZ_STD_SECTOR; |
||||
offset = pos % SZ_STD_SECTOR; |
||||
read = 0; |
||||
|
||||
if (offset) { |
||||
/* Read doesn't start at the sector beginning. We need to use our */ |
||||
/* cache */ |
||||
if (sect != cache_sect) { |
||||
if (dev_read (cache, sect, 1) < 0) { |
||||
return (-1); |
||||
} |
||||
cache_sect = sect; |
||||
} |
||||
nb = min (len, SZ_STD_SECTOR - offset); |
||||
|
||||
memcpy (buf, cache + offset, nb); |
||||
read += nb; |
||||
len -= nb; |
||||
sect += 1; |
||||
} |
||||
|
||||
if (len > SZ_STD_SECTOR) { |
||||
nb = (len - 1) / SZ_STD_SECTOR; |
||||
if (dev_read (buf + read, sect, nb) < 0) { |
||||
return ((read) ? read : -1); |
||||
} |
||||
/* update sector position */ |
||||
sect += nb; |
||||
|
||||
/* Update byte position */ |
||||
nb *= SZ_STD_SECTOR; |
||||
read += nb; |
||||
len -= nb; |
||||
} |
||||
|
||||
if (len) { |
||||
if (sect != cache_sect) { |
||||
if (dev_read (cache, sect, 1) < 0) { |
||||
return ((read) ? read : -1); |
||||
cache_sect = -1; |
||||
} |
||||
cache_sect = sect; |
||||
} |
||||
|
||||
memcpy (buf + read, cache, len); |
||||
read += len; |
||||
} |
||||
return (read); |
||||
} |
@ -1,336 +0,0 @@ |
||||
/*
|
||||
* (C) Copyright 2002 |
||||
* Stäubli Faverges - <www.staubli.com> |
||||
* Pierre AUBERT p.aubert@staubli.com |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <config.h> |
||||
#include <linux/ctype.h> |
||||
|
||||
#include "dos.h" |
||||
#include "fdos.h" |
||||
|
||||
static int dir_read (Fs_t *fs, |
||||
Slot_t *dir, |
||||
Directory_t *dirent, |
||||
int num, |
||||
struct vfat_state *v); |
||||
|
||||
static int unicode_read (char *in, char *out, int num); |
||||
static int match (const char *s, const char *p); |
||||
static unsigned char sum_shortname (char *name); |
||||
static int check_vfat (struct vfat_state *v, Directory_t *dir); |
||||
static char *conv_name (char *name, char *ext, char Case, char *ans); |
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
* clear_vfat -- |
||||
*----------------------------------------------------------------------------- |
||||
*/ |
||||
static void clear_vfat (struct vfat_state *v) |
||||
{ |
||||
v -> subentries = 0; |
||||
v -> status = 0; |
||||
} |
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
* vfat_lookup -- |
||||
*----------------------------------------------------------------------------- |
||||
*/ |
||||
int vfat_lookup (Slot_t *dir, |
||||
Fs_t *fs, |
||||
Directory_t *dirent, |
||||
int *entry, |
||||
int *vfat_start, |
||||
char *filename, |
||||
int flags, |
||||
char *outname, |
||||
Slot_t *file) |
||||
{ |
||||
int found; |
||||
struct vfat_state vfat; |
||||
char newfile [VSE_NAMELEN]; |
||||
int vfat_present = 0; |
||||
|
||||
if (*entry == -1) { |
||||
return -1; |
||||
} |
||||
|
||||
found = 0; |
||||
clear_vfat (&vfat); |
||||
while (1) { |
||||
if (dir_read (fs, dir, dirent, *entry, &vfat) < 0) { |
||||
if (vfat_start) { |
||||
*vfat_start = *entry; |
||||
} |
||||
break; |
||||
} |
||||
(*entry)++; |
||||
|
||||
/* Empty slot */ |
||||
if (dirent -> name[0] == '\0'){ |
||||
if (vfat_start == 0) { |
||||
break; |
||||
} |
||||
continue; |
||||
} |
||||
|
||||
if (dirent -> attr == ATTR_VSE) { |
||||
/* VSE entry, continue */ |
||||
continue; |
||||
} |
||||
if ( (dirent -> name [0] == DELMARK) || |
||||
((dirent -> attr & ATTR_DIRECTORY) != 0 && |
||||
(flags & ACCEPT_DIR) == 0) || |
||||
((dirent -> attr & ATTR_VOLUME) != 0 && |
||||
(flags & ACCEPT_LABEL) == 0) || |
||||
(((dirent -> attr & (ATTR_DIRECTORY | ATTR_VOLUME)) == 0) && |
||||
(flags & ACCEPT_PLAIN) == 0)) { |
||||
clear_vfat (&vfat); |
||||
continue; |
||||
} |
||||
|
||||
vfat_present = check_vfat (&vfat, dirent); |
||||
if (vfat_start) { |
||||
*vfat_start = *entry - 1; |
||||
if (vfat_present) { |
||||
*vfat_start -= vfat.subentries; |
||||
} |
||||
} |
||||
|
||||
if (dirent -> attr & ATTR_VOLUME) { |
||||
strncpy (newfile, dirent -> name, 8); |
||||
newfile [8] = '\0'; |
||||
strncat (newfile, dirent -> ext, 3); |
||||
newfile [11] = '\0'; |
||||
} |
||||
else { |
||||
conv_name (dirent -> name, dirent -> ext, dirent -> Case, newfile); |
||||
} |
||||
|
||||
if (flags & MATCH_ANY) { |
||||
found = 1; |
||||
break; |
||||
} |
||||
|
||||
if ((vfat_present && match (vfat.name, filename)) || |
||||
(match (newfile, filename))) { |
||||
found = 1; |
||||
break; |
||||
} |
||||
clear_vfat (&vfat); |
||||
} |
||||
|
||||
if (found) { |
||||
if ((flags & DO_OPEN) && file) { |
||||
if (open_file (file, dirent) < 0) { |
||||
return (-1); |
||||
} |
||||
} |
||||
if (outname) { |
||||
if (vfat_present) { |
||||
strcpy (outname, vfat.name); |
||||
} |
||||
else { |
||||
strcpy (outname, newfile); |
||||
} |
||||
} |
||||
return (0); /* File found */ |
||||
} else { |
||||
*entry = -1; |
||||
return -1; /* File not found */ |
||||
} |
||||
} |
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
* dir_read -- Read one directory entry |
||||
*----------------------------------------------------------------------------- |
||||
*/ |
||||
static int dir_read (Fs_t *fs, |
||||
Slot_t *dir, |
||||
Directory_t *dirent, |
||||
int num, |
||||
struct vfat_state *v) |
||||
{ |
||||
|
||||
/* read the directory entry */ |
||||
if (read_file (fs, |
||||
dir, |
||||
(char *)dirent, |
||||
num * MDIR_SIZE, |
||||
MDIR_SIZE) != MDIR_SIZE) { |
||||
return (-1); |
||||
} |
||||
|
||||
if (v && (dirent -> attr == ATTR_VSE)) { |
||||
struct vfat_subentry *vse; |
||||
unsigned char id, last_flag; |
||||
char *c; |
||||
|
||||
vse = (struct vfat_subentry *) dirent; |
||||
id = vse -> id & VSE_MASK; |
||||
last_flag = (vse -> id & VSE_LAST); |
||||
if (id > MAX_VFAT_SUBENTRIES) { |
||||
/* Invalid VSE entry */ |
||||
return (-1); |
||||
} |
||||
|
||||
|
||||
/* Decode VSE */ |
||||
if(v -> sum != vse -> sum) { |
||||
clear_vfat (v); |
||||
v -> sum = vse -> sum; |
||||
} |
||||
|
||||
|
||||
v -> status |= 1 << (id - 1); |
||||
if (last_flag) { |
||||
v -> subentries = id; |
||||
} |
||||
|
||||
c = &(v -> name [VSE_NAMELEN * (id - 1)]); |
||||
c += unicode_read (vse->text1, c, VSE1SIZE); |
||||
c += unicode_read (vse->text2, c, VSE2SIZE); |
||||
c += unicode_read (vse->text3, c, VSE3SIZE); |
||||
|
||||
if (last_flag) { |
||||
*c = '\0'; /* Null terminate long name */ |
||||
} |
||||
|
||||
} |
||||
return (0); |
||||
} |
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
* unicode_read -- |
||||
*----------------------------------------------------------------------------- |
||||
*/ |
||||
static int unicode_read (char *in, char *out, int num) |
||||
{ |
||||
int j; |
||||
|
||||
for (j = 0; j < num; ++j) { |
||||
if (in [1]) |
||||
*out = '_'; |
||||
else |
||||
*out = in [0]; |
||||
out ++; |
||||
in += 2; |
||||
} |
||||
return num; |
||||
} |
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
* match -- |
||||
*----------------------------------------------------------------------------- |
||||
*/ |
||||
static int match (const char *s, const char *p) |
||||
{ |
||||
|
||||
for (; *p != '\0'; ) { |
||||
if (toupper (*s) != toupper (*p)) { |
||||
return (0); |
||||
} |
||||
p++; |
||||
s++; |
||||
} |
||||
|
||||
if (*s != '\0') { |
||||
return (0); |
||||
} |
||||
else { |
||||
return (1); |
||||
} |
||||
} |
||||
/*-----------------------------------------------------------------------------
|
||||
* sum_shortname -- |
||||
*----------------------------------------------------------------------------- |
||||
*/ |
||||
static unsigned char sum_shortname (char *name) |
||||
{ |
||||
unsigned char sum; |
||||
int j; |
||||
|
||||
for (j = sum = 0; j < 11; ++j) { |
||||
sum = ((sum & 1) ? 0x80 : 0) + (sum >> 1) + |
||||
(name [j] ? name [j] : ' '); |
||||
} |
||||
return (sum); |
||||
} |
||||
/*-----------------------------------------------------------------------------
|
||||
* check_vfat -- |
||||
* Return 1 if long name is valid, 0 else |
||||
*----------------------------------------------------------------------------- |
||||
*/ |
||||
static int check_vfat (struct vfat_state *v, Directory_t *dir) |
||||
{ |
||||
char name[12]; |
||||
|
||||
if (v -> subentries == 0) { |
||||
return 0; |
||||
} |
||||
|
||||
strncpy (name, dir -> name, 8); |
||||
strncpy (name + 8, dir -> ext, 3); |
||||
name [11] = '\0'; |
||||
|
||||
if (v -> sum != sum_shortname (name)) { |
||||
return 0; |
||||
} |
||||
|
||||
if( (v -> status & ((1 << v -> subentries) - 1)) != |
||||
(1 << v -> subentries) - 1) { |
||||
return 0; |
||||
} |
||||
v->name [VSE_NAMELEN * v -> subentries] = 0; |
||||
|
||||
return 1; |
||||
} |
||||
/*-----------------------------------------------------------------------------
|
||||
* conv_name -- |
||||
*----------------------------------------------------------------------------- |
||||
*/ |
||||
static char *conv_name (char *name, char *ext, char Case, char *ans) |
||||
{ |
||||
char tname [9], text [4]; |
||||
int i; |
||||
|
||||
i = 0; |
||||
while (i < 8 && name [i] != ' ' && name [i] != '\0') { |
||||
tname [i] = name [i]; |
||||
i++; |
||||
} |
||||
tname [i] = '\0'; |
||||
|
||||
if (Case & BASECASE) { |
||||
for (i = 0; i < 8 && tname [i]; i++) { |
||||
tname [i] = tolower (tname [i]); |
||||
} |
||||
} |
||||
|
||||
i = 0; |
||||
while (i < 3 && ext [i] != ' ' && ext [i] != '\0') { |
||||
text [i] = ext [i]; |
||||
i++; |
||||
} |
||||
text [i] = '\0'; |
||||
|
||||
if (Case & EXTCASE){ |
||||
for (i = 0; i < 3 && text [i]; i++) { |
||||
text [i] = tolower (text [i]); |
||||
} |
||||
} |
||||
|
||||
if (*text) { |
||||
strcpy (ans, tname); |
||||
strcat (ans, "."); |
||||
strcat (ans, text); |
||||
} |
||||
else { |
||||
strcpy(ans, tname); |
||||
} |
||||
return (ans); |
||||
} |
Loading…
Reference in new issue