{
int sect, track, counter;
+ assert(d);
assert(blockno>=0);
- assert(blockno<d->size);
- assert(buffer!=(char*)0);
+ assert(buffer);
+ if (blockno>=d->size)
+ {
+ boo="Attempting to access block beyond end of disk";
+ return -1;
+ }
if (end<0) end=d->blksiz/d->secLength-1;
sect=(blockno*(d->blksiz/d->secLength)+ d->sectrk*d->boottrk)%d->sectrk;
track=(blockno*(d->blksiz/d->secLength)+ d->sectrk*d->boottrk)/d->sectrk;
{
const char *err;
+ assert(d->skewtab[sect]>=0);
+ assert(d->skewtab[sect]<d->sectrk);
if (counter>=start && (err=Device_readSector(&d->dev,track,d->skewtab[sect],buffer+(d->secLength*counter))))
{
boo=err;
{
int first=1;
+ assert(a);
+ assert(pattern);
while (*pattern)
{
switch (*pattern)
int user;
char pat[255];
+ assert(a);
+ assert(pattern);
assert(strlen(pattern)<255);
if (isdigit(*pattern) && *(pattern+1)==':') { user=(*pattern-'0'); pattern+=2; }
else if (isdigit(*pattern) && isdigit(*(pattern+1)) && *(pattern+2)==':') { user=(10*(*pattern-'0')+(*(pattern+1)-'0')); pattern+=3; }
FILE *fp;
int insideDef=0,found=0;
+ d->libdskGeometry[0] = '\0';
d->type=0;
if ((fp=fopen("diskdefs","r"))==(FILE*)0 && (fp=fopen(DISKDEFS,"r"))==(FILE*)0)
{
{
int argc;
char *argv[2];
+ char *s;
+
+ /* Allow inline comments preceded by ; or # */
+ s = strchr(line, '#');
+ if (s) strcpy(s, "\n");
+ s = strchr(line, ';');
+ if (s) strcpy(s, "\n");
for (argc=0; argc<1 && (argv[argc]=strtok(argc ? (char*)0 : line," \t\n")); ++argc);
if ((argv[argc]=strtok((char*)0,"\n"))!=(char*)0) ++argc;
for (pass=0; pass<2; ++pass)
{
- char *s;
-
sectors=0;
for (s=argv[1]; *s; )
{
errno=0;
multiplier=1;
- val = strtoul(argv[1],&endptr,10);
- if ((errno==ERANGE && val==ULONG_MAX)||(errno!=0 && val==0))
+ val = strtol(argv[1],&endptr,10);
+ if ((errno==ERANGE && val==LONG_MAX)||(errno!=0 && val<=0))
{
fprintf(stderr,"%s: invalid offset value \"%s\" - %s\n",cmd,argv[1],strerror(errno));
exit(1);
/* Have a unit specifier */
switch (toupper(*endptr))
{
- case 'K':
- multiplier=1024;
- break;
- case 'M':
- multiplier=1024*1024;
- break;
- case 'T':
- if (d->sectrk<0||d->tracks<0||d->secLength<0)
- {
- fprintf(stderr,"%s: offset must be specified after sectrk, tracks and secLength\n",cmd);
+ case 'K':
+ multiplier=1024;
+ break;
+ case 'M':
+ multiplier=1024*1024;
+ break;
+ case 'T':
+ if (d->sectrk<0||d->tracks<0||d->secLength<0)
+ {
+ fprintf(stderr,"%s: offset must be specified after sectrk, tracks and secLength\n",cmd);
+ exit(1);
+ }
+ multiplier=d->sectrk*d->secLength;
+ break;
+ case 'S':
+ if (d->sectrk<0||d->tracks<0||d->secLength<0)
+ {
+ fprintf(stderr,"%s: offset must be specified after sectrk, tracks and secLength\n",cmd);
+ exit(1);
+ }
+ multiplier=d->secLength;
+ break;
+ default:
+ fprintf(stderr,"%s: unknown unit specifier \"%c\"\n",cmd,*endptr);
exit(1);
- }
- multiplier=d->sectrk*d->secLength;
- break;
- case 'S':
- if (d->sectrk<0||d->tracks<0||d->secLength<0)
- {
- fprintf(stderr,"%s: offset must be specified after sectrk, tracks and secLength\n",cmd);
- exit(1);
- }
- multiplier=d->secLength;
- break;
- default:
- fprintf(stderr,"%s: unknown unit specifier \"%c\"\n",cmd,*endptr);
- exit(1);
}
}
if (val*multiplier>INT_MAX)
exit(1);
}
}
+ else if (strcmp(argv[0], "libdsk:format")==0)
+ {
+ strncpy(d->libdskGeometry, argv[1], sizeof(d->libdskGeometry) - 1);
+ d->libdskGeometry[sizeof(d->libdskGeometry) - 1] = 0;
+ }
}
- else if (argc>0 && argv[0][0]!='#')
+ else if (argc>0 && argv[0][0]!='#' && argv[0][0]!=';')
{
fprintf(stderr,"%s: invalid keyword `%s'\n",cmd,argv[0]);
exit(1);
insideDef=1;
d->skew=1;
d->extents=0;
- d->type|=CPMFS_DR3;
+ d->type=CPMFS_DR22;
d->skewtab=(int*)0;
d->offset=0;
d->boottrk=d->secLength=d->sectrk=d->tracks=-1;
+ d->libdskGeometry[0] = 0;
if (strcmp(argv[1],format)==0) found=1;
}
}
unsigned char boot_sector[512], *boot_spec;
const char *err;
- Device_setGeometry(&d->dev,512,9,40,0);
+ Device_setGeometry(&d->dev,512,9,40,0,"pcw180");
if ((err=Device_readSector(&d->dev, 0, 0, (char *)boot_sector)))
{
fprintf(stderr,"%s: Failed to read Amstrad superblock (%s)\n",cmd,err);
d->offset = 0;
d->size = (d->secLength*d->sectrk*(d->tracks-d->boottrk))/d->blksiz;
d->extents = ((d->size>=256 ? 8 : 16)*d->blksiz)/16384;
+ d->libdskGeometry[0] = 0; /* LibDsk can recognise an Amstrad superblock
+ * and autodect */
return 0;
}
assert(s_ifdir);
while (s_ifreg && !S_ISREG(s_ifreg)) s_ifreg<<=1;
assert(s_ifreg);
- if (strcmp(format, "amstrad")==0) amsReadSuper(d,format);
+ if (strcmp(format,"amstrad")==0) amsReadSuper(d,format);
else diskdefReadSuper(d,format);
- Device_setGeometry(&d->dev,d->secLength,d->sectrk,d->tracks,d->offset);
+ boo = Device_setGeometry(&d->dev,d->secLength,d->sectrk,d->tracks,d->offset,d->libdskGeometry);
+ if (boo) return -1;
+
if (d->skewtab==(int*)0) /* generate skew table */ /*{{{*/
{
int i,j,k;
if (( d->skewtab = malloc(d->sectrk*sizeof(int))) == (int*)0)
{
- fprintf(stderr,"%s: can not allocate memory for skew sector table\n",cmd);
- exit(1);
+ boo=strerror(errno);
+ return -1;
}
memset(d->skewtab,0,d->sectrk*sizeof(int));
for (i=j=0; i<d->sectrk; ++i,j=(j+d->skew)%d->sectrk)
{
while (1)
{
+ assert(i<d->sectrk);
+ assert(j<d->sectrk);
for (k=0; k<i && d->skewtab[k]!=j; ++k);
if (k<i) j=(j+1)%d->sectrk;
else break;
d->alvSize=((d->secLength*d->sectrk*(d->tracks-d->boottrk))/d->blksiz+INTBITS-1)/INTBITS;
if ((d->alv=malloc(d->alvSize*sizeof(int)))==(int*)0)
{
- boo="out of memory";
+ boo=strerror(errno);
return -1;
}
}
/*}}}*/
/* allocate directory buffer */ /*{{{*/
- if ((d->dir=malloc(d->maxdir*32))==(struct PhysDirectoryEntry*)0)
+ assert(sizeof(struct PhysDirectoryEntry)==32);
+ if ((d->dir=malloc(((d->maxdir*32+d->blksiz-1)/d->blksiz)*d->blksiz))==(struct PhysDirectoryEntry*)0)
{
- boo="out of memory";
+ boo=strerror(errno);
return -1;
}
/*}}}*/
/* variables */ /*{{{*/
struct PhysDirectoryEntry *cur=(struct PhysDirectoryEntry*)0;
char buf[2+8+1+3+1]; /* 00foobarxy.zzy\0 */
- int i;
char *bufp;
int hasext;
/*}}}*/
/*}}}*/
while (1)
{
+ int i;
+
if (dir->pos==0) /* first entry is . */ /*{{{*/
{
ent->ino=dir->ino->sb->maxdir;
}
/*}}}*/
}
- else if (dir->pos>=RESERVED_ENTRIES && dir->pos<dir->ino->sb->maxdir+RESERVED_ENTRIES)
+ else if (dir->pos>=RESERVED_ENTRIES && dir->pos<(int)dir->ino->sb->maxdir+RESERVED_ENTRIES)
{
int first=dir->pos-RESERVED_ENTRIES;
extcap=(file->ino->sb->size<256 ? 16 : 8)*blocksize;
if (extcap>16384) extcap=16384*file->ino->sb->extents;
- if (file->ino->ino==file->ino->sb->maxdir+1) /* [passwd] */ /*{{{*/
+ if (file->ino->ino==(ino_t)file->ino->sb->maxdir+1) /* [passwd] */ /*{{{*/
{
if ((file->pos+count)>file->ino->size) count=file->ino->size-file->pos;
if (count) memcpy(buf,file->ino->sb->passwd+file->pos,count);
return count;
}
/*}}}*/
- else if (file->ino->ino==file->ino->sb->maxdir+2) /* [label] */ /*{{{*/
+ else if (file->ino->ino==(ino_t)file->ino->sb->maxdir+2) /* [label] */ /*{{{*/
{
if ((file->pos+count)>file->ino->size) count=file->ino->size-file->pos;
if (count) memcpy(buf,file->ino->sb->label+file->pos,count);
{
start=(file->pos%blocksize)/file->ino->sb->secLength;
end=((file->pos%blocksize+count)>blocksize ? blocksize-1 : (file->pos%blocksize+count-1))/file->ino->sb->secLength;
- readBlock(file->ino->sb,block,buffer,start,end);
+ if (readBlock(file->ino->sb,block,buffer,start,end)==-1)
+ {
+ if (got==0) got=-1;
+ break;
+ }
}
}
nextblockpos=(file->pos/blocksize)*blocksize+blocksize;
{
start=(file->pos%blocksize)/file->ino->sb->secLength;
end=((file->pos%blocksize+count)>blocksize ? blocksize-1 : (file->pos%blocksize+count-1))/file->ino->sb->secLength;
- if (file->pos%file->ino->sb->secLength) readBlock(file->ino->sb,block,buffer,start,start);
- if (end!=start && (file->pos+count-1)<blocksize) readBlock(file->ino->sb,block,buffer+end*file->ino->sb->secLength,end,end);
+ if (file->pos%file->ino->sb->secLength)
+ {
+ if (readBlock(file->ino->sb,block,buffer,start,start)==-1)
+ {
+ if (got==0) got=-1;
+ break;
+ }
+ }
+ if (end!=start && (file->pos+count-1)<blocksize)
+ {
+ if (readBlock(file->ino->sb,block,buffer+end*file->ino->sb->secLength,end,end)==-1)
+ {
+ if (got==0) got=-1;
+ break;
+ }
+ }
}
/*}}}*/
nextblockpos=(file->pos/blocksize)*blocksize+blocksize;