/* YAYANC */ /* Yet Another "Yet Another New Catalogue" - extensive revisions by David J. Welch. A Public Domain Program. "If you bought it, you paid too much!" The original YANC.C was for H/Z-19 only, this one is completely generic in its terminal handling. Compiled under BDS C compiler. There were numerous errors in the space calculations, and even in this version, Random Files will appear larger than they are, although the Free Space will reflect the true file sizes in all cases now! The revisionist may be contacted via the CP-MIG on CompuServe. [ID: 70270,626] */ #include "bdscio.h" #define LISTCHAR 5 /* bdos function list char to printer */ #define RETURNVER 12 /* bdos function return version no */ #define RESETDISK 13 /* bdos function reset disk system */ #define SELDISK 14 /* bdos function select disk */ #define SRCHFIRST 17 /* bdos function search for first */ #define SRCHNEXT 18 /* bdos function search for next */ #define DELETEFILE 19 /* bdos function delete file */ #define RENAMEFILE 23 /* bdos function rename file */ #define GETDISK 25 /* bdos function get current disk */ #define SETDMA 26 /* bdos function set dma addr */ #define GETDPB 31 /* bdos function get disk parameter */ #define GETFREE 46 /* bdos function get disk free space */ #define FCBSIZE 16 /* cpm directory entry size */ #define NUMDRIVES 16 /* number of cpm drives */ #define DIRSIZ 1024 /* max # of cpm dir entries */ #define DMADDR 0x80 /* bdos default dma addr */ #define MAXLINES 58 /* max lines before sending FF */ #define FF 0x0c /* form feed character */ #define CR 0x0d /* carriage return character */ #define YES TRUE #define NO FALSE #define EOS NO #define BOOLEAN char #define GETS_SIZE 128 BOOLEAN printer; char mdrive,ddrive; char *pfcb[DIRSIZ],volname[13],ibuffer[BUFSIZ],obuffer[BUFSIZ]; int nfcb,cfcb,block,dirmax,linecount,itemcount; unsigned disksz,remsz,intf(); struct dontcat { char fname[13]; struct dontcat *next; } *dcs; struct dontcat *head; main() /* Master catalog system based on Ward Christiansen's programs * * FMAP, CAT, UCAT and QCAT. Rewritten into a single program * * in BDS C. This program is menu driven to be easy to use * */ { char cmd; char matchstr[GETS_SIZE]; if (bdos(RETURNVER,0) == 0) { puts("Can't use this program with CPM 1.4"); exit(); } mdrive = 'A'; ddrive = 'B'; printer = NO; while (1) { cmd = menu(); switch (cmd) { case 1: updatedir(); break; case 2: strcpy(matchstr,"*.*"); listmast(matchstr); break; case 3: getstr(matchstr); listmast(matchstr); break; case 4: getstr(matchstr); listvol(matchstr); break; case 5: dispdir(); break; case 6: initmast(); break; case 7: getdefaults(); break; case 8: makedirfile(); break; case 9: exit(); break; } } } menu() { char x,y; char c; char *conbuf; char i; printf("\nMaster Catalog System defaults:\n"); printf("Master Catalog on drive %c:\n",mdrive); printf(" Disk to Add on drive %c:\n",ddrive); printf("Printer: "); if (printer) printf("on\n\n"); else printf("off\n\n"); printf(" Enter number of desired action:\n\n"); printf("1 - Update the master catalog with above defaults\n"); printf("2 - List the entire master catalog\n"); printf("3 - List specific files with a match key\n"); printf("4 - List a volume from the master catalog\n"); printf("5 - List the disk directory\n"); printf("6 - Initialize MAST.CAT\n"); printf("7 - Update the defaults\n"); printf("8 - Make directory volume label file\n"); printf("9 - Quit this program"); while (1) { printf("\n\n Selection ->"); conbuf = "Nonsense\0"; getline(conbuf, 8); x = atoi (conbuf); if ( x>0 && x<10 ) return x; break; } } updatedir() { char *top; top = alloc(1); printf("\n\rInsert disk to be catalogued in %c:\n\r",ddrive); if (mdrive != ddrive) printf("Be sure the master disk is in %c:\r\n",mdrive); hold(); readdir(); if (strcmp(volname,"n/a")) updatemast(); else { printf("No volume label file on disk\r\n"); hold(); } free(top); } dispdir() { printf("Load disk to list in drive %c: ",ddrive); hold(); puts("\r\nReading directory....\r\n\n"); readdir(); listdir(); } readdir() { char fcb[FCBSIZE]; char dmapos; BOOLEAN firstime; char *alloc; char *ptr,bsh; char i; bdos(RESETDISK,0); bdos(SELDISK,(ddrive-'A')); bdos(SETDMA,DMADDR); bdos(GETFREE,(ddrive-'A')); ptr = (DMADDR+2); if (0xf8 & *ptr) remsz = 65535; else remsz = (intf(*ptr--) << 13) + (intf(*ptr--) << 5) + (intf(*ptr) >> 3); ptr = 3 + bdos(GETDPB,0); block = (1 + *ptr); ptr += 2; disksz = (1 + intf(*ptr++) + (intf(*ptr++) << 8)) * (block/8); dirmax = (*ptr+(*(ptr+1)*256))+1; if (disksz != 65535) disksz -= dirmax >> 5; firstime = YES; for (i=0; i<13; i++) fcb[i] = '?'; for (i=13; i> 3); break; case 2: for (j=nfcb++; j>i; j--) pfcb[j] = pfcb[j-1]; pfcb[i] = alloc(FCBSIZE); return copyfcb(i,fcb); break; } } i = nfcb++; pfcb[i] = alloc(FCBSIZE); return copyfcb(i,fcb); } else if ( ( (*fcb == 0) && (*(fcb+1) == '-')) || (*fcb == 32) ) { if (*fcb == 32) k = 1; else k = 2; i2 = 0; for (i1=k; i1<9; i1++) volname[i2++] = fcb[i1]; if (*fcb == 0) volname[i2++] = ' '; for (i1=9; i1<12; i1++) volname[i2++] = fcb[i1]; volname[i2] = EOS; return 0; } else return 0; } copyfcb(ptr,fcb) char *fcb; int ptr; { char *tfcb,*sfcb; char i; tfcb = sfcb = pfcb[ptr]; for (i=0; i> 3); } comparefcb(fcb1,fcb2) char *fcb1,*fcb2; /* Compare two fcb's -- return: * * -2 name1,user1 < name2,user2 * * -1 name1,user1 = name2,user2 & extent1 < extent2; * * 0 name1,user1,extent1 = name2,user2,extent2; * * +1 name1,user1 = name2,user2 & extent1 > extent2; * * +2 name1,user1 > name2,user2; */ { int val; char s1[14],s2[14]; char i,k; for (i=0,k=1; k<12; i++,k++) { s1[i] = fcb1[k]; s2[i] = fcb2[k]; } s1[i] = fcb1[0] + '0'; s2[i] = fcb2[0] + '0'; i++; s1[i] = EOS; s2[i] = EOS; val = strcmp(s1,s2); if (val < 0) return -2; else if (val > 0) return 2; else if (fcb1[12] < fcb2[12]) return -1; else if (fcb1[12] > fcb2[12]) return 1; else return 0; } listdir() { int size,i; char j,k; char s[50],stemp[5]; char *fcb; sprintf(s," Directory for volume: %s\r\n",volname); printf("%s",s); if (printer) { bdos(LISTCHAR,FF); for (i=0; i> 3); sprintf(stemp,"%d",size); for (j=0; j 0) rsize = extract(rfname,rvolname,rec); while (recsize >= 0 && cfcb < nfcb) { fc = strcmp(fname,rfname); vc = strcmp(volname,rvolname); if (fc < 0) { putentry(obuffer,fname,volname,size); printf("ADD:%s\r\n",fname); ++cfcb; if (cfcb < nfcb) size = bldentry(fname); } else if (fc == 0) { if (vc < 0) { putentry(obuffer,fname,volname,size); printf("ADD:%s\r\n",fname); ++cfcb; if (cfcb < nfcb) size=bldentry(fname); } else if (vc == 0) { putentry(obuffer,fname,volname,size); printf("CHG:%s\r\n",fname); ++cfcb; if (cfcb < nfcb) size=bldentry(fname); recsize = readline(ibuffer,rec); if (recsize > 0) rsize=extract(rfname,rvolname, rec); } else /* (vc > 0) */ { putentry(obuffer,rfname,rvolname,rsize); recsize = readline(ibuffer,rec); if (recsize > 0) rsize=extract(rfname,rvolname, rec); } } else /* (fc > 0) */ { if (vc == 0) { printf("DEL:%s\r\n",rfname); recsize = readline(ibuffer,rec); if (recsize > 0) rsize=extract(rfname,rvolname, rec); } else { putentry(obuffer,rfname,rvolname,rsize); recsize = readline(ibuffer,rec); if (recsize > 0) rsize=extract(rfname,rvolname, rec); } } } if (recsize < 0) while (cfcb < nfcb) { putentry(obuffer,fname,volname,size); printf("ADD:%s\r\n",fname); cfcb++; if (cfcb < nfcb) size = bldentry(fname); } if (cfcb == nfcb) while (recsize >= 0) { vc = strcmp(volname,rvolname); if (vc == 0) printf("DEL:%s\r\n",rfname); else putentry(obuffer,rfname,rvolname,rsize); recsize = readline(ibuffer,rec); if (recsize > 0) rsize=extract(rfname,rvolname,rec); } putc(CPMEOF,obuffer); fflush(obuffer); fclose(ibuffer); fclose(obuffer); hold(); } copydont(fdo,fdi) FILE *fdi,*fdo; { char rec[GETS_SIZE]; head = NULL; if (readline(fdi,rec) < 0) abort("\r\nFile MAST.CAT is null\r\n"); else if (rec[0] != '(') abort("\r\nNo valid exclude files\r\n"); while (rec[strlen(rec)-1] != ')') { writeline(fdo,rec); dontadd(rec); if (readline(fdi,rec) < 0) abort("\r\nPremature End of File\r\n"); } writeline(fdo,rec); rec[strlen(rec)-1] = EOS; dontadd(rec); } dontadd(rec) char *rec; { char i,j; struct dontcat *ptr,*nptr; i=0; if (rec[0] == '(') i = 1; nptr = ptr = head; while (nptr != NULL) { ptr = nptr; nptr = ptr->next; } if (diff(nptr,ptr) == 0) nptr = head = alloc(15); else nptr = ptr->next = alloc(15); nptr->next = NULL; j = 0; while (j<8 && rec[i] != '.' && rec[i] != EOS) nptr->fname[j++] = rec[i++]; while (j<8) nptr->fname[j++] = ' '; if (rec[i] == '.') i++; while (j<11 && rec[i] != EOS) nptr->fname[j++] = rec[i++]; while (j<11) nptr->fname[j++] = ' '; nptr->fname[j] = EOS; } writeline(fd,buff) FILE *fd; char *buff; { char c; char *cp; cp = buff; while ((c = *cp++) != EOS) putc(c,fd); putc('\r',fd); putc('\n',fd); } readline(fd,buff) FILE *fd; char *buff; { char *cp; char c; for (cp = buff; (c=getc(fd)) != '\n' && c != CPMEOF; ) if (c != '\r') *cp++ = c; *cp = '\0'; if (cp != buff) return cp-buff; else if (c != CPMEOF) return 0; else return -1; } bldfree(buff,n) char *buff; int n; { char *cp; buff[5] = 'k'; buff[6] = ' '; buff[7] = ' '; buff[8] = 'F'; buff[9] = 'R'; buff[10] = 'E'; buff[11] = '0'; /* free space is always user 0 */ buff[12] = EOS; cp = &buff[5]; do { *--cp = n%10 + '0'; n = n/10; } while (n != 0); while (cp > buff) *--cp = '+'; return n; } bldentry(fname) char *fname; { char i,j; char *fcb; struct dontcat *ptr; while (cfcb < nfcb) { fcb = pfcb[cfcb]; for (j=0,i=1; i<12; j++,i++) fname[j] = fcb[i]; fname[11] = EOS; ptr = head; while (ptr != NULL && strcmp(ptr,fname)) ptr = ptr->next; if (ptr == NULL) { fname[11] = fcb[0] + '0'; fname[12] = EOS; return (*(fcb+12) << 4) + (((block + *(fcb+15) - 1 ) / block * block) >> 3); } else cfcb++; } return 0; } putentry(fd,name,vol,size) FILE *fd; char *name,*vol; int size; { char c,s[10],*cp; putfcb(fd,name); putc(',',fd); putfcb(fd,vol); sprintf(s,",%d",name[11] - '0'); cp = s; while (c = *cp++) putc(c,fd); sprintf(s,",%dK",size); cp = s; while (c = *cp++) putc(c,fd); putc('\r',fd); putc('\n',fd); } putfcb(fd,name) FILE *fd; char *name; { char i; for (i=0; i<8; i++) { if (name[i] == ' ') break; putc(name[i],fd); } if (name[8] != ' ') putc('.',fd); for (i=8; i<11; i++) { if (name[i] == ' ') break; putc(name[i],fd); } } extract(name,vol,rec) char *name,*vol,*rec; { int n,size; char i,j; i = j = 0; while (j<8 && rec[i] != '.' && rec[i] != ',' && rec[i] != EOS) name[j++] = rec[i++]; while (j<8) name[j++] = ' '; if (rec[i] == '.') i++; while (j<11 && rec[i] != ',' && rec[i] != EOS) name[j++] = rec[i++]; while (j<11) name[j++] = ' '; if (rec[i] == ',') i++; j = 0; while (j<8 && rec[i] != '.' && rec[i] != ',' && rec[i] != EOS) vol[j++] = rec[i++]; while (j<8) vol[j++] = ' '; if (rec[i] == '.') i++; while (j<11 && rec[i] != ',' && rec[i] != EOS) vol[j++] = rec[i++]; while (j<11) vol[j++] = ' '; vol[11] = EOS; if (rec[i] == ',') i++; n = 0; while (isdigit(rec[i])) n = n*10 + (rec[i++] - '0'); while (!isdigit(rec[i]) && rec[i] != EOS) i++; name[11] = n + '0'; name[12] = EOS; size = 0; while (isdigit(rec[i])) size = size*10 + (rec[i++] - '0'); return size; } listmast(str) char *str; { int size; char c; char hstr[GETS_SIZE],rec[GETS_SIZE]; char file[13],vol[13],nstr[13]; char buffer[BUFSIZ]; expandstr(nstr,str); strcpy(hstr,"FILES: "); strcat(hstr,str); bdos(RESETDISK,0); bdos(SELDISK,(mdrive - 'A')); bdos(SETDMA,DMADDR); if (fopen("MAST.CAT",buffer) == ERROR) { puts("Can't open MAST.CAT"); hold(); return 0; } linecount = 99; itemcount = 0; do c=getc(buffer); while (c != ')' && c != CPMEOF); do c=getc(buffer); while (c != '\n' && c != CPMEOF); while (readline(buffer,rec) > 0) { size = extract(file,vol,rec); if (filecompare(file,nstr) == 0) listentry(file,vol,size,hstr); } if (printer) { bdos(LISTCHAR,'\r'); bdos(LISTCHAR,'\n'); } fclose(buffer); hold(); } listvol(str) char *str; { int size; char c; char hstr[GETS_SIZE],rec[GETS_SIZE]; char file[13],vol[13],nstr[13]; char buffer[BUFSIZ]; expandstr(nstr,str); strcpy(hstr,"VOLUME: "); strcat(hstr,str); bdos(RESETDISK,0); bdos(SELDISK,(mdrive - 'A')); bdos(SETDMA,DMADDR); if (fopen("MAST.CAT",ibuffer) == ERROR) { puts("Can't open MAST.CAT"); hold(); return 0; } linecount = 99; itemcount = 0; do c=getc(ibuffer); while (c != ')' && c != CPMEOF); do c=getc(ibuffer); while (c != '\n' && c != CPMEOF); while (readline(ibuffer,rec) > 0) { size = extract(file,vol,rec); if (filecompare(vol,nstr) == 0) listentry(file,vol,size,hstr); } if (printer) { bdos(LISTCHAR,'\r'); bdos(LISTCHAR,'\n'); } fclose(ibuffer); hold(); } expandstr(nstr,str) char *nstr,*str; { int i,j; i = j = 0; while ( (i < 8) && (str[j] != '.' ) && (str[j] != '*' ) && (str[j] != EOS ) ) nstr[i++] = str[j++]; if (str[j] == '*') { /* if we have an asterisk */ j++; while (i < 8) /* and are on the FILENAME */ nstr[i++] = '?';/* make them ????? */ } if(str[j] == '.') { /* if we have a period */ j++; /* pass it by. . . */ while (i < 8) nstr[i++] = ' '; } while ( (i < 11) && (str[j] != '*' ) && (str[j] != EOS ) ) nstr[i++] = str[j++]; if (str[j] == '*') while (i < 11) nstr[i++] = '?'; else while (i < 11) nstr[i++] = ' '; nstr[11] = '?'; nstr[12] = EOS; } filecompare(file,str) char *file,*str; { char i,diff; for (i=0; i MAXLINES) { printf("%s\r\n\n",str); if (printer) { bdos(LISTCHAR,FF); for (i=0; i<5; i++) bdos(LISTCHAR,' '); for (i=0; i 14) { printf("file name too long\n\r"); notdone = YES; } } bldfile(buf2); } bldfile(buf) char *buf; { char str[GETS_SIZE]; if(fcreat(buf,obuffer) == ERROR) { sprintf(str,"unable to build file %s\n\r",buf); abort(str); } fclose(obuffer); /* an empty file has now been built */ puts("Volume label file built"); } getdefaults() { char c; do { printf("\r\nEnter drive where Master Catalog will reside - "); mdrive = toupper(getchar()); } while ( mdrive < 'A' || mdrive > (NUMDRIVES+'@')); do { printf("\r\nEnter drive of Disk to be cataloged - "); ddrive = toupper(getchar()); } while ( ddrive < 'A' || ddrive > (NUMDRIVES+'@')); do { printf("\r\nEcho displays to the CP/M list device? (y/n) - "); c = toupper(getchar()); } while (c != 'Y' && c != 'N'); if (c == 'Y') printer = YES; else printer = NO; } hold() { printf("press return when ready"); while(bdos(6,255) != CR) /* do nothing */ ; printf("\r\n"); } abort(str) char *str; { printf("%s",str); printf("\r\n ----- aborting -----\r\n"); exit(); } diff(p1,p2) char *p1,*p2; { return p1-p2; } unsigned intf(parm) char parm; { unsigned result; char *intfptr; result = 0; intfptr = &result; *intfptr = parm; return result; }