mirror of
https://github.com/deater/dos33fsprogs.git
synced 2024-12-27 02:31:00 +00:00
prodos: enable setting create/modify time
This commit is contained in:
parent
b99cdc1ee7
commit
c84a801d49
@ -11,13 +11,15 @@ prodos: prodos.o \
|
||||
prodos_catalog.o \
|
||||
prodos_dump.o \
|
||||
prodos_volume_bitmap.o \
|
||||
prodos_voldir.o
|
||||
prodos_voldir.o \
|
||||
prodos_time.o
|
||||
$(CC) -o prodos prodos.o \
|
||||
prodos_read.o \
|
||||
prodos_catalog.o \
|
||||
prodos_dump.o \
|
||||
prodos_volume_bitmap.o \
|
||||
prodos_voldir.o $(LFLAGS)
|
||||
prodos_voldir.o \
|
||||
prodos_time.o $(LFLAGS)
|
||||
|
||||
prodos.o: prodos.c prodos.h
|
||||
$(CC) $(CFLAGS) -g -c prodos.c
|
||||
@ -49,10 +51,10 @@ text_to_prodos.o: text_to_prodos.c
|
||||
###
|
||||
|
||||
mkprodosfs: mkprodosfs.o prodos_read.o prodos_volume_bitmap.o \
|
||||
prodos_voldir.o
|
||||
prodos_voldir.o prodos_time.o
|
||||
$(CC) $(LFLAGS) -o mkprodosfs mkprodosfs.o \
|
||||
prodos_read.o prodos_volume_bitmap.o \
|
||||
prodos_voldir.o
|
||||
prodos_voldir.o prodos_time.o
|
||||
|
||||
mkprodosfs.o: mkprodosfs.c prodos.h
|
||||
$(CC) $(CFLAGS) -c mkprodosfs.c
|
||||
@ -82,6 +84,11 @@ prodos_read.o: prodos_read.c prodos.h
|
||||
prodos_voldir.o: prodos_voldir.c prodos.h
|
||||
$(CC) $(CFLAGS) -c prodos_voldir.c
|
||||
|
||||
###
|
||||
|
||||
prodos_time.o: prodos_time.c prodos.h
|
||||
$(CC) $(CFLAGS) -c prodos_time.c
|
||||
|
||||
|
||||
###
|
||||
|
||||
|
@ -8,6 +8,9 @@ Tools for manipulating Apple II prodos filesystems
|
||||
|
||||
+ mkprodosfs: create an Apple ][ ProDOS filesystems
|
||||
|
||||
+ prodos_cat : allow cat'ing (listing) prodos text files with \r (CR)
|
||||
line endings on a machine like Linux that's expecting \n (LF)
|
||||
|
||||
NOTE: subdirectory support is currently not implemented
|
||||
|
||||
TODO:
|
||||
|
@ -4,12 +4,13 @@
|
||||
#include <unistd.h> /* close() */
|
||||
#include <stdlib.h> /* strtol() */
|
||||
#include <errno.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "version.h"
|
||||
|
||||
#include "prodos.h"
|
||||
|
||||
int debug=1;
|
||||
int debug=0;
|
||||
|
||||
static int ones_lookup[8]={
|
||||
0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE, 0xFF,
|
||||
@ -134,7 +135,7 @@ int main(int argc, char **argv) {
|
||||
|
||||
voldir.bit_map_pointer=6;
|
||||
|
||||
voldir.creation_time=0;
|
||||
voldir.creation_time=prodos_time(time(NULL));
|
||||
|
||||
voldir.file_count=0;
|
||||
|
||||
|
@ -6,14 +6,14 @@
|
||||
#include <unistd.h> /* lseek() */
|
||||
#include <ctype.h> /* toupper() */
|
||||
#include <errno.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "version.h"
|
||||
|
||||
#include "prodos.h"
|
||||
|
||||
static int ignore_errors=0;
|
||||
int debug=1;
|
||||
|
||||
int debug=0;
|
||||
|
||||
/* Given filename, return voldir/offset */
|
||||
static int prodos_lookup_file(struct voldir_t *voldir,
|
||||
@ -207,6 +207,21 @@ static int prodos_writeout_filedesc(struct voldir_t *voldir,
|
||||
#define ERROR_FILE_TOO_BIG 7
|
||||
|
||||
|
||||
|
||||
#define PRODOS_NUM_FILE_TYPES 5
|
||||
|
||||
static struct prodos_file_type {
|
||||
int type;
|
||||
char name[4];
|
||||
} file_types[PRODOS_NUM_FILE_TYPES] = {
|
||||
{PRODOS_TYPE_TXT,"TXT"},
|
||||
{PRODOS_TYPE_BIN,"BIN"},
|
||||
{PRODOS_TYPE_BAS,"BAS"},
|
||||
{PRODOS_TYPE_VAR,"VAR"},
|
||||
{PRODOS_TYPE_SYS,"SYS"},
|
||||
};
|
||||
|
||||
|
||||
/* creates file apple_filename on the image from local file filename */
|
||||
/* returns ?? */
|
||||
static int prodos_add_file(struct voldir_t *voldir,
|
||||
@ -215,7 +230,7 @@ static int prodos_add_file(struct voldir_t *voldir,
|
||||
char *filename, char *apple_filename) {
|
||||
|
||||
|
||||
int free_blocks,file_size,needed_blocks,total_blocks,file_type;
|
||||
int free_blocks,file_size,needed_blocks,total_blocks,storage_type;
|
||||
int block,i,j,needed_limit;
|
||||
struct stat file_info;
|
||||
int input_fd;
|
||||
@ -225,6 +240,8 @@ static int prodos_add_file(struct voldir_t *voldir,
|
||||
unsigned char data_buffer[PRODOS_BYTES_PER_BLOCK];
|
||||
int key_block,index,inode;
|
||||
struct file_entry_t file;
|
||||
int file_type=0;
|
||||
|
||||
|
||||
/* check for valid filename */
|
||||
|
||||
@ -247,6 +264,14 @@ static int prodos_add_file(struct voldir_t *voldir,
|
||||
}
|
||||
}
|
||||
|
||||
/* get file type */
|
||||
for(i=0;i<PRODOS_NUM_FILE_TYPES;i++) {
|
||||
if (!strncmp(type,file_types[i].name,3)) {
|
||||
file_type=file_types[i].type;
|
||||
if (debug) printf("Found type %s=%d\n",type,file_type);
|
||||
}
|
||||
}
|
||||
|
||||
/* Determine size of file to upload */
|
||||
if (stat(filename,&file_info)<0) {
|
||||
fprintf(stderr,"Error! %s not found!\n",filename);
|
||||
@ -269,19 +294,19 @@ static int prodos_add_file(struct voldir_t *voldir,
|
||||
else if (needed_blocks==1) {
|
||||
/* seedling */
|
||||
if (debug) printf("File seedling\n");
|
||||
file_type=PRODOS_FILE_SEEDLING;
|
||||
storage_type=PRODOS_FILE_SEEDLING;
|
||||
total_blocks=needed_blocks;
|
||||
}
|
||||
else if (needed_blocks<=256) {
|
||||
/* sapling */
|
||||
if (debug) printf("File sapling\n");
|
||||
file_type=PRODOS_FILE_SAPLING;
|
||||
storage_type=PRODOS_FILE_SAPLING;
|
||||
total_blocks=needed_blocks+1; /* for index block */
|
||||
}
|
||||
else if (needed_blocks<=65536) {
|
||||
/* tree */
|
||||
if (debug) printf("File tree\n");
|
||||
file_type=PRODOS_FILE_TREE;
|
||||
storage_type=PRODOS_FILE_TREE;
|
||||
total_blocks=needed_blocks+1 /* for key index block */
|
||||
+(1+needed_blocks/256); /* for index blocks */
|
||||
/* FIXME: -1? */
|
||||
@ -309,7 +334,7 @@ static int prodos_add_file(struct voldir_t *voldir,
|
||||
return ERROR_IMAGE_NOT_FOUND;
|
||||
}
|
||||
|
||||
if (file_type==PRODOS_FILE_SEEDLING) {
|
||||
if (storage_type==PRODOS_FILE_SEEDLING) {
|
||||
block=prodos_allocate_block(voldir);
|
||||
key_block=block;
|
||||
|
||||
@ -322,7 +347,7 @@ static int prodos_add_file(struct voldir_t *voldir,
|
||||
prodos_write_block(voldir,data_buffer,block);
|
||||
}
|
||||
|
||||
if (file_type==PRODOS_FILE_SAPLING) {
|
||||
if (storage_type==PRODOS_FILE_SAPLING) {
|
||||
/* allocate index */
|
||||
index=prodos_allocate_block(voldir);
|
||||
key_block=index;
|
||||
@ -348,7 +373,7 @@ static int prodos_add_file(struct voldir_t *voldir,
|
||||
}
|
||||
|
||||
|
||||
if (file_type==PRODOS_FILE_TREE) {
|
||||
if (storage_type==PRODOS_FILE_TREE) {
|
||||
/* allocate key index */
|
||||
key_block=prodos_allocate_block(voldir);
|
||||
memset(key_buffer,0,PRODOS_BYTES_PER_BLOCK);
|
||||
@ -395,19 +420,19 @@ static int prodos_add_file(struct voldir_t *voldir,
|
||||
|
||||
|
||||
/* FIXME */
|
||||
file.storage_type=file_type;
|
||||
file.storage_type=storage_type;
|
||||
file.name_length=strlen(apple_filename);
|
||||
memcpy(file.file_name,apple_filename,file.name_length);
|
||||
file.file_type=0;
|
||||
file.file_type=file_type;
|
||||
file.key_pointer=key_block;
|
||||
file.blocks_used=total_blocks; /* includes index blocks */
|
||||
file.eof=file_size;
|
||||
file.creation_time=0;
|
||||
file.creation_time=prodos_time(time(NULL));
|
||||
file.version=0;
|
||||
file.min_version=0;
|
||||
file.access=0;
|
||||
file.aux_type=0;
|
||||
file.last_mod=0;
|
||||
file.last_mod=prodos_time(time(NULL));
|
||||
file.header_pointer=PRODOS_VOLDIR_KEY_BLOCK;
|
||||
|
||||
|
||||
@ -416,6 +441,8 @@ static int prodos_add_file(struct voldir_t *voldir,
|
||||
return inode;
|
||||
}
|
||||
|
||||
if (debug) printf("Found inode $%x\n",inode);
|
||||
|
||||
/* read in existing voldir entry */
|
||||
result=prodos_read_block(voldir,data_buffer,inode>>8);
|
||||
|
||||
@ -427,6 +454,7 @@ static int prodos_add_file(struct voldir_t *voldir,
|
||||
result=prodos_write_block(voldir,data_buffer,inode>>8);
|
||||
|
||||
/* update file count */
|
||||
if (debug) printf("Updating file count...\n");
|
||||
voldir->file_count++;
|
||||
prodos_sync_voldir(voldir);
|
||||
|
||||
@ -1048,7 +1076,7 @@ int main(int argc, char **argv) {
|
||||
interleave=arg_interleave-1;
|
||||
}
|
||||
|
||||
prodos_read_voldir(prodos_fd,&voldir,interleave,image_offset);
|
||||
prodos_init_voldir(prodos_fd,&voldir,interleave,image_offset);
|
||||
|
||||
/* Move to next argument */
|
||||
optind++;
|
||||
|
@ -91,5 +91,9 @@ int prodos_write_block(struct voldir_t *voldir,unsigned char *block, int blocknu
|
||||
/* prodos_voldir.c */
|
||||
int prodos_sync_voldir(struct voldir_t *voldir);
|
||||
int prodos_change_volume_name(struct voldir_t *voldir, char *volname);
|
||||
int prodos_read_voldir(int fd, struct voldir_t *voldir,
|
||||
int prodos_init_voldir(int fd, struct voldir_t *voldir,
|
||||
int interleave, int image_offset);
|
||||
int prodos_read_voldir(struct voldir_t *voldir);
|
||||
|
||||
/* prodos_time.c */
|
||||
int prodos_time(time_t t);
|
||||
|
@ -2,6 +2,7 @@
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "prodos.h"
|
||||
|
||||
@ -129,7 +130,7 @@ static int prodos_text_timestamp(int t, unsigned char *timestamp) {
|
||||
minute=t&0x3f;
|
||||
|
||||
sprintf((char *)timestamp,"%2d-%s-%02d %2d:%02d",
|
||||
day,prodos_capital_month_names[month],year,hour,minute);
|
||||
day,prodos_capital_month_names[month],year%100,hour,minute);
|
||||
timestamp[16]=0;
|
||||
|
||||
return 0;
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "version.h"
|
||||
|
||||
|
38
utils/prodos-utils/prodos_time.c
Normal file
38
utils/prodos-utils/prodos_time.c
Normal file
@ -0,0 +1,38 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h> /* exit() */
|
||||
#include <string.h> /* strncpy() */
|
||||
#include <sys/stat.h> /* struct stat */
|
||||
#include <fcntl.h> /* O_RDONLY */
|
||||
#include <unistd.h> /* lseek() */
|
||||
#include <ctype.h> /* toupper() */
|
||||
#include <errno.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "version.h"
|
||||
|
||||
#include "prodos.h"
|
||||
|
||||
extern int debug;
|
||||
|
||||
int prodos_time(time_t t) {
|
||||
|
||||
struct tm *broken_time;
|
||||
int pyear,pmonth,pday,phour,pminute;
|
||||
int ptime;
|
||||
|
||||
broken_time=localtime(&t);
|
||||
|
||||
pyear=broken_time->tm_year;
|
||||
pmonth=broken_time->tm_mon;
|
||||
pday=broken_time->tm_mday;
|
||||
phour=broken_time->tm_hour;
|
||||
pminute=broken_time->tm_min;
|
||||
|
||||
ptime=(pyear<<25)|(pmonth<<21)|(pday<<16)|(phour<<8)|pminute;
|
||||
|
||||
if (debug) printf("Y=%d M=%d D=%d h=%d m=%d\n",
|
||||
pyear,pmonth,pday,phour,pminute);
|
||||
|
||||
return ptime;
|
||||
}
|
||||
|
@ -13,18 +13,14 @@
|
||||
|
||||
extern int debug;
|
||||
|
||||
|
||||
/* Read volume directory into a buffer */
|
||||
int prodos_read_voldir(int fd, struct voldir_t *voldir,
|
||||
int interleave, int image_offset) {
|
||||
int prodos_read_voldir(struct voldir_t *voldir) {
|
||||
|
||||
int result;
|
||||
unsigned char voldir_buffer[PRODOS_BYTES_PER_BLOCK];
|
||||
|
||||
voldir->interleave=interleave;
|
||||
voldir->image_offset=image_offset;
|
||||
|
||||
/* read in VOLDIR KEY Block*/
|
||||
voldir->fd=fd;
|
||||
result=prodos_read_block(voldir,voldir_buffer,PRODOS_VOLDIR_KEY_BLOCK);
|
||||
|
||||
if (result<0) {
|
||||
@ -32,8 +28,6 @@ int prodos_read_voldir(int fd, struct voldir_t *voldir,
|
||||
return -1;
|
||||
}
|
||||
|
||||
voldir->fd=fd;
|
||||
|
||||
voldir->storage_type=(voldir_buffer[0x4]>>4)&0xf;
|
||||
voldir->name_length=(voldir_buffer[0x4]&0xf);
|
||||
if (voldir->storage_type!=0xf) {
|
||||
@ -68,12 +62,38 @@ int prodos_read_voldir(int fd, struct voldir_t *voldir,
|
||||
}
|
||||
|
||||
|
||||
/* Read volume directory into a buffer */
|
||||
int prodos_init_voldir(int fd, struct voldir_t *voldir,
|
||||
int interleave, int image_offset) {
|
||||
|
||||
|
||||
voldir->interleave=interleave;
|
||||
voldir->image_offset=image_offset;
|
||||
|
||||
/* read in VOLDIR KEY Block*/
|
||||
voldir->fd=fd;
|
||||
|
||||
prodos_read_voldir(voldir);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* write out the voldir */
|
||||
/* This is tricky as the superblock-type info is entry 0 */
|
||||
/* but the rest are directory entries */
|
||||
/* and we sort of treat these as separate but not */
|
||||
|
||||
int prodos_sync_voldir(struct voldir_t *voldir) {
|
||||
|
||||
unsigned char newvoldir[PRODOS_BYTES_PER_BLOCK];
|
||||
|
||||
memset(newvoldir,0,PRODOS_BYTES_PER_BLOCK);
|
||||
/* read in existing voldir */
|
||||
prodos_read_block(voldir,newvoldir,PRODOS_VOLDIR_KEY_BLOCK);
|
||||
|
||||
// memset(newvoldir,0,PRODOS_BYTES_PER_BLOCK);
|
||||
|
||||
newvoldir[0x4]=(voldir->storage_type<<4)|(voldir->name_length&0xf);
|
||||
memcpy(&newvoldir[0x5],voldir->volume_name,voldir->name_length);
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "prodos.h"
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user