195 lines
4.0 KiB
C
195 lines
4.0 KiB
C
/**************************************************************************
|
|
***************************************************************************
|
|
|
|
W E G A - Quelle (C) TU KMSt / ZFT/KEAW Abt. WAE - 1988
|
|
Programm: dosopn.c
|
|
|
|
Bearbeiter : P. Hoge
|
|
Datum : 24.11.89
|
|
Version : 1.3
|
|
|
|
***************************************************************************
|
|
**************************************************************************/
|
|
|
|
#include "dos.h"
|
|
|
|
/* dosopn
|
|
* Durchmustert ein DCP-Verzeichnis,
|
|
* uebergibt die Adresse einer Struktur dostat
|
|
* fuer die durch path beschriebene Datei.
|
|
* Liefert -1 bei Fehler und 0 wenn nicht gefunden
|
|
*/
|
|
dosopn(path,dp,stp)
|
|
register char *path;
|
|
register struct dosdisc *dp;
|
|
register struct dostat *stp;
|
|
{
|
|
char s[LMAX],*p;
|
|
long dadr;
|
|
unsigned next,dosnxt();
|
|
int res,dn;
|
|
char *strchr();
|
|
|
|
dn = dp->dirnum;
|
|
dadr = dp->maindir;
|
|
next = 0;
|
|
strcpy(s,path);
|
|
path = s;
|
|
if (path[0] == '/')
|
|
path++;
|
|
while (path != 0 && path[0] != '\0') {
|
|
if ((p=strchr(path,'/')) != 0)
|
|
path[strlen(path)-strlen(p++)] = '\0';
|
|
while (-1) {
|
|
if ((res=dosrde(dp->fd,path,dn,dadr,stp)) < 0)
|
|
return(res);
|
|
if (res == 1) {
|
|
next = stp->first;
|
|
dadr = DOSADR(next,dp->clustsiz)+dp->data;
|
|
break;
|
|
}
|
|
dn = dp->clustsiz/32;
|
|
if ((next=dosnxt(dp->fd,next,dp->fat1,dp->fatlen))<1)
|
|
return(0);
|
|
dadr = DOSADR(next,dp->clustsiz)+dp->data;
|
|
}
|
|
path = p;
|
|
}
|
|
return(1);
|
|
}
|
|
|
|
|
|
/* dosrde
|
|
* Sucht einen Verzeichniseintrag und
|
|
* belegt eine Struktur dostat mit Werten
|
|
*/
|
|
dosrde(fd,fn,dnum,adr,stp)
|
|
int fd;
|
|
register char *fn; /* Name des zu suchenden DCP-Files */
|
|
int dnum; /* max. moegliche Anzahl von Verzeichniseintraegn */
|
|
register long adr; /* Startadresse des Verzeichnisses */
|
|
register struct dostat *stp;
|
|
{
|
|
int res;
|
|
char *strchr(),*ext, c='\0';
|
|
|
|
lseek(fd,adr,0);
|
|
ext = strchr(fn,'.');
|
|
if (ext)
|
|
ext++;
|
|
else
|
|
ext = &c;
|
|
|
|
while ((res=getde(fd,stp)) > 0 ) {
|
|
if (dnum-- == 0)
|
|
return(0);
|
|
if (ncmp(fn, stp->name, 8) && ncmp(ext, &stp->name[8], 3))
|
|
break;
|
|
}
|
|
return(res);
|
|
}
|
|
|
|
ncmp(a,b,n)
|
|
register char *a,*b;
|
|
register int n;
|
|
{
|
|
while (n--) {
|
|
if (*b == 0x20 && (*a == '\0' || *a == '.'))
|
|
break;
|
|
if (*a++ != *b++)
|
|
return(0);
|
|
}
|
|
return(1);
|
|
}
|
|
|
|
|
|
/* getde
|
|
* liest einen 32-Byte Verzeichniseintrag und belegt
|
|
* dostat mit den Dateiparametern.
|
|
* Beachte: Der Bytezaehler muss vorher auf das erste
|
|
* Byte des Eintrages zeigen !
|
|
* Die Funktion liefert 0, wenn keine gueltigen Eintraege
|
|
* mehr im Verzeichnis stehen und -1 bei Lesefehler.
|
|
*/
|
|
getde(fd,stat_buf)
|
|
register int fd;
|
|
register struct dostat *stat_buf;
|
|
{
|
|
register int i;
|
|
register unsigned date,time;
|
|
unsigned char dirbuf[32];
|
|
|
|
if (read(fd,dirbuf,32)!=32)
|
|
return(-1);
|
|
|
|
for (i=0;i<11;i++)
|
|
stat_buf->name[i]=dirbuf[i];
|
|
stat_buf->name[i]='\0';
|
|
|
|
if (stat_buf->name[0]=='\0')
|
|
return(0);
|
|
|
|
if (dirbuf[11]&0x01)
|
|
stat_buf->flag = RO;
|
|
else
|
|
stat_buf->flag = RW;
|
|
stat_buf->attr = dirbuf[11];
|
|
if (dirbuf[11]&0x02)
|
|
stat_buf->mode = _BLOCKED;
|
|
else if (dirbuf[11]&0x04)
|
|
stat_buf->mode = _SYSDAT;
|
|
else if (dirbuf[11]&0x10)
|
|
stat_buf->mode = _SDIR;
|
|
else
|
|
stat_buf->mode = _FILE;
|
|
|
|
stat_buf->first=dirbuf[27]*256+dirbuf[26];
|
|
stat_buf->dim=dirbuf[31]*16777216+dirbuf[30]*65536+dirbuf[29]*256+dirbuf[28];
|
|
date=dirbuf[25]*256 + dirbuf[24];
|
|
time=dirbuf[23]*256 + dirbuf[22];
|
|
|
|
stat_buf->date.year=date/512 + 1980;
|
|
stat_buf->date.month=(date&0x01ff)/32;
|
|
stat_buf->date.day=date&0x001f;
|
|
|
|
stat_buf->time.hour=time/2048;
|
|
stat_buf->time.min=(time&0x07ff)/32;
|
|
stat_buf->time.sec=(time&0x001f)*2;
|
|
return(1);
|
|
}
|
|
|
|
|
|
/* Bereitstellen der naechsten Clusternummer
|
|
* liefert 0 bei Dateiende
|
|
*/
|
|
unsigned dosnxt(fd,first,fat,fatlen)
|
|
register int fd;
|
|
register unsigned first;
|
|
register unsigned long fat;
|
|
register int fatlen;
|
|
{
|
|
register unsigned nxt;
|
|
unsigned char b[2];
|
|
|
|
if (fatlen == 12) {
|
|
lseek(fd,fat+(long)(1.5*first),0);
|
|
read(fd,b,2);
|
|
|
|
if (first % 2 == 0)
|
|
nxt = (b[1]&0x0f)*256 + b[0];
|
|
else
|
|
nxt = b[1]*16 + b[0]/16;
|
|
|
|
if (nxt >= 0x0ff8 && nxt <= 0x0fff)
|
|
nxt = 0;
|
|
}
|
|
else {
|
|
lseek(fd,fat+(long)(2*first),0);
|
|
read(fd,b,2);
|
|
nxt = b[1]*256+b[0];
|
|
if (nxt >= 0xfff8 && nxt <= 0xffff)
|
|
nxt = 0;
|
|
}
|
|
return(nxt);
|
|
}
|