/* File OSDATE.C BDS-C Ver 1.1 04May85 */ #include #include "make.h" #define SEARCH_FIRST 17 /* * osdate - return the DATSTAMP create or modify date for file. * returns 0 for okay, -1 if no date. * */ int osdate(fs, date) char *fs; /* Input filespec. */ char date[5]; /* The returned date. */ { int fsun; /* User number on filespec. */ char fsdisk; /* Disk on filespec. (ascii) */ char fe[20]; /* Filename.ext of filespec (+ some safe space). */ char fcb[36]; int curun; /* Current user number. */ char curdisk; /* Current disk. */ char e_o; /* Value returned by search call. */ int e_r_n; /* Entry record number returned from DATSTAMP. */ int error; /* Return value from getfdate(). */ curun=bdos(32, 0xFF); /* Get current user number. */ curdisk=bdos(25)+'A'; /* Get current disk. */ crackudf(fs, &fsun, &fsdisk, fe); if (fsun == -1) fsun=curun; if (fsdisk == '\0') fsdisk=curdisk; bdos(26, BASE+0x80); /* Go set DMA addr to BASE + 0x80. */ setfcb(fcb, fe); bdos(14, fsdisk-'A'); /* Go select desired disk. */ bdos(32, fsun); /* Select the desire user number. */ e_o=bdosde(SEARCH_FIRST, fcb, &e_r_n); if(e_o != 255) error=getfdate(e_r_n, e_o, date, fsdisk-'A'); else error=-1; bdos(14, curdisk-'A'); /* Restore current disk. */ bdos(32, curun); /* Restore current user number. */ return error; /* Return the correct value. */ } /* crackudf - crack a filespec into user#, disk, filename.ext. * I accept two formats [u/][d:]file.ext or * [d[u]:]file.ext. Actually I do this a little dirty so * that u/du:file.ext will work and the "u/" part is essentially ignored. */ crackudf(fs,un,disk,fe) char *fs; /* File spec string. */ int *un; /* Returned user #, -1 for none or out of range. */ char *disk; /* Disk letter, \0 for none. */ char *fe; /* Returned file.ext string. */ { *un=-1; /* Default none. */ *disk='\0'; /* Default none. */ /* Check for "n/" or "nn/". */ if (isdigit(*fs)) { /* Started with a number. */ if (isdigit(*(fs+1))) { /* A 2nd number. */ if (*(fs+2) == '/') { /* "nn/" form. */ *un=(*fs++ - '0')*10; *un += (*fs++ - '0'); fs++; /* Move past '/'. */ } } else if (*(fs+1) == '/') { /* "n/" form. */ *un=*fs++ - '0'; fs++; /* Move past '/'. */ } } /* Check for "d[nn]:" form. */ if (isalpha(*fs)) { if (*(fs+1) == ':') { /* "d:" form. */ *disk=toupper(*fs++); fs++; /* Move past ':'. */ } else if (isdigit(*(fs+1))) { if (*(fs+2) == ':') { /* "dn:" form. */ *disk=toupper(*fs++); *un=*fs++ - '0'; fs++; /* Move past ':'. */ } else if (isdigit(*(fs+2)) && *(fs+3) == ':') { /* "dnn:" form. */ *disk=toupper(*fs++); *un=(*fs++ - '0')*10; *un += (*fs++ -'0'); fs++; /* Move past ':'. */ } } } if(*un > 31) *un=-1; /* Now just copy the rest of the string. */ while (*fs) *fe++=*fs++; *fe='\0'; /* Terminate fe[]. */ } getfdate(e_r_n, e_o, fdate, disk) int e_r_n; char e_o; char fdate[5]; int disk; { /* v 1.1 read first disk's entire time&date file to buffer */ int i, fd, un, offset; unsigned sects; char bad, *ptr, *tmp; char localbuff[128]; bad = FALSE; if(e_o < 0 || e_o > 3) return -1; /* Set fdate to 0 in case of error. */ for (i=0; i<5; i++) fdate[i] = 0; /* on first call, read entire time&date file to buffer */ if (!havedates || datesdisk != disk) { un=bdos(32, 0xff); bdos(32, 0); /* Point to user 0 */ if ((fd=open("!!!TIME&.DAT", 0)) == -1) { bdos(32, un); return -1;} if (datesdisk == -1) { sects = cfsize(fd); if ( (datebuff = alloc(128*sects) ) == 0){ bdos(32, un); allerr(); } bad = (read(fd, datebuff, sects) != sects); havedates = TRUE; datesdisk = disk; /* save disk of this file*/ /* allocate, then free a large chunk so individual calls won't cause a sbrk() */ if ( tmp = alloc(128*8) ) free(tmp); } else { if (seek(fd, e_r_n/2, 0) == -1 || read(fd, localbuff, 1) != 1) bad = TRUE; } close(fd); bdos(32, un); if (bad) return -1; } /* if initial disk, point at file's date slot t&d file buffer */ /* otherwise, into just-read sector */ offset = 16*(4*(e_r_n & 1) + e_o); ptr = (datesdisk == disk) ? datebuff + 128*(e_r_n/2) + offset : localbuff + offset; /* If a modify date use that as the file date. */ if (ptr[10]) ptr += 10; for (i=0; i<5; i++) fdate[i] = *ptr++; return 0; }