Compare commits

..

No commits in common. "546ed596d4cc850f60be336aa7a8c4af817f469e" and "9bce32e72797babc805469a00bee4a7509960fd1" have entirely different histories.

3 changed files with 28 additions and 25 deletions

3
TODO
View file

@ -1,5 +1,4 @@
Implement randomness (xorshift? https://www.jstatsoft.org/article/view/v008i14) Implement randomness (xorshift? https://www.jstatsoft.org/article/view/v008i14)
Maybe extract file "read"/"write" operations with read_fat_chain()
Config parser (config.c) Config parser (config.c)
Do the actual corrupty things Do the actual corrupty things
Use fopen(3) and friends instead of open(2)

View file

@ -8,8 +8,6 @@
#include "dosfs.h" #include "dosfs.h"
#include "debug.h" #include "debug.h"
static unsigned int *read_fat_chain(dosfs_t *, unsigned int, int *);
/* /*
* Opens an image a la open(2). Returns 0 on success, or * Opens an image a la open(2). Returns 0 on success, or
* some error number on failure. * some error number on failure.
@ -153,9 +151,6 @@ dos_listdir(dosfs_t *fsd, unsigned int offset)
(void)memcpy(&cur->ent, &dirs[i], sizeof(struct dos_dirent)); (void)memcpy(&cur->ent, &dirs[i], sizeof(struct dos_dirent));
/* useful for get_byte_offset() */
cur->fat_chain = read_fat_chain(fsd, cur->ent.low_loc,
&cur->fc_len);
res = 0; res = 0;
} }
@ -239,29 +234,39 @@ read_fat_chain(dosfs_t *fsd, unsigned int first, int *length)
} }
/* /*
* Converts the byte offset of a file into the "real" * TODO: reads a file to a given buffer
* offset, i.e. one that can be used with lseek()/pread().
*/ */
int int
get_byte_offset(dosfs_t *fsd, dosfile_t *file, int f_offset) dos_fread(dosfs_t *fsd, dosfile_t *file, void *buf, int max_size)
{ {
int coff, csz; unsigned int *chain = NULL;
int clen = 0, i, left, chunk, cbytes, off, res;
if (f_offset > file->ent.size) { chain = read_fat_chain(fsd, file->ent.low_loc, &clen);
DPRINTF("offset requested is out of bounds!\n"); if (chain == NULL) {
return -EINVAL; return -1; /* XXX */
} }
/* size in bytes of a cluster */ cbytes = fsd->ib.sect_size * fsd->ib.sect_per_cluster;
csz = fsd->ib.sect_per_cluster * fsd->ib.sect_size; left = max_size;
/* get the offset in the fat chain */ for (i = 0; i < clen; i++) {
coff = f_offset / csz; /* only copy as much as we can hold */
chunk = (left < cbytes) ? left : cbytes;
if (coff > file->fc_len) { res = pread(fsd->ifd, buf + (i * cbytes),
DPRINTF("offset is within filesize, but not enough clusters??\n"); chunk, fsd->data_loc + (chain[i] * cbytes));
return -EINVAL; if (res == -1) {
DPRINTF("pread failed\n");
free(chain);
return -1;
}
left -= chunk;
if (left <= 0)
break;
} }
return (file->fat_chain[coff] * csz) + (f_offset % csz); return 0;
} }

View file

@ -69,17 +69,16 @@ typedef struct dosfile_t {
struct dos_dirent ent; struct dos_dirent ent;
char fname[9]; char fname[9];
char fext[4]; char fext[4];
unsigned int *fat_chain;
int fc_len;
struct dosfile_t *next; struct dosfile_t *next;
} dosfile_t; } dosfile_t;
int open_image(const char *, int, dosfs_t *); int open_image(const char *, int, dosfs_t *);
void close_image(dosfs_t *); void close_image(dosfs_t *);
dosfile_t *dos_listdir(dosfs_t *, unsigned int); dosfile_t *dos_listdir(dosfs_t *, unsigned int);
int dos_fread(dosfs_t *, dosfile_t *, void *, int);
void dos_freedir(dosfile_t *); void dos_freedir(dosfile_t *);
int get_byte_offset(dosfs_t *, dosfile_t *, int);
#endif /* !_FAT12_H */ #endif /* !_FAT12_H */