/* Z3func01 - Zcpr3 access functions for C */ #include #include "z3env.h" /* structure of named directory */ struct ndre { int drvusr; /* low byte is drive, high byte is user */ char name[8]; char passwd[8]; }; /* Drive, user, and directory manipulation */ /* Encode drive and user into a single int. The low byte of the int is the drive, the high byte is the user. No range chacking is done. */ int duencode(d,u) int d,u; { return((u<<8) + d); } /* Decode packed du into drive and user. Note that arguments for drive and user are pointers to ints! This function also returns the user to the caller. */ int dudecode(du,drive,user) int du, *drive, *user; { *drive=du & 0xff; return(*user = du>>8); } /* Validate du against environment max du, drive vector. Returns du if ok or -1 if drive or user bad. */ int duvalid(du) int du; { char drive,user; int drvmsk; #ifdef BDSC struct env *zenv(), *envadr; envadr = zenv(); #endif drive=du & 0xff; user = du>>8; if(drive < envadr->maxdisk && user <= envadr->maxuser) { drvmsk = 1 << drive; /* within bounds, check for holes */ if(drvmsk & envadr->okdvct) return(du); /* passed, return to caller */ } return(-1); /* failed */ } /* Get encoded du from FCB */ int getfdu(fcb) struct zfcb *fcb; { int i; i = fcb->drive; if(i) --i; /* zero base the drive */ else i = bdos(25,0); /* get drive from bdos */ return(((fcb->user & 0x7f) << 8) + i); } /* Set du in fcb from encoded value. Returns du. */ int setfdu(fcb,du) struct zfcb *fcb; int du; { fcb->user = du >> 8; fcb->drive = (++du) & 0x7f; return(du); } /* Convert encoded du to dir. Returns string in dir which must be 9 bytes long minimum. If the du is found, the name is simply copied to dir and null terminated. A null string indicates no named directory exists for the specified du. */ char *du2dir(du,dir) int du; char *dir; { unsigned numdir,i; char *p; struct ndre *ndrp; #ifdef BDSC struct env *zenv(), *envadr; envadr = zenv(); ndrp=envadr->ndr; #else ndrp=(struct ndre *)(envadr->ndr); /* address of ndr */ #endif numdir=envadr->ndrsize; /* number of names */ ++du; /* bump drive number by 1 for ndr */ p=dir; for(;numdir--;++ndrp) { if(ndrp->drvusr == du) { for(i=0;i<8;++i) *p++ = ndrp->name[i]; break; } } *p = '\0'; /* terminate name (if any) */ return(dir); } /* Convert dir to encoded du. If no match is located, try to parse as a drive/user specification if duok is true. If this fails, -1 is returned. -1 is also returned if the parsed du is invalid. */ int dir2du(dir) char *dir; { unsigned numdir, i, j; char tstbf[9]; struct ndre *ndrp; #ifdef BDSC struct env *zenv(), *envadr; envadr = zenv(); ndrp=envadr->ndr; #else ndrp=(struct ndre *)(envadr->ndr); /* address of ndr */ #endif numdir=envadr->ndrsize; /* number of names */ /* copy name to local buffer and pad with spaces if needed */ strncpy(tstbf,dir,8); capstr(tstbf); /* insure upper case */ if((i = strlen(tstbf)) < 8) { for(;i < 8; ++i) tstbf[i]=' '; /* pad with spaces */ tstbf[8]='\0'; } /* now scan ndr for a match */ for(;numdir--;++ndrp) { if(strncmp(tstbf, &(ndrp->name), 8) == 0) { i = ndrp->drvusr; return(duvalid(--i)); /* fix drive number and validate */ } } /* No match, could it be a DU:? */ if(getduok()) { j = 0; /* Get drive */ if(tstbf[0] >= 'A' && tstbf[0] <= 'P') { i = tstbf[0] - 'A'; ++j; } else i = bdos(25,0); /* get drive from bdos */ /* Get user */ if(isdigit(tstbf[j])) i += atoi(&tstbf[j]) << 8; else i += bdos(32,0xff) << 8; return(duvalid(i)); } return(-1); } /* Get password for directory. Returns password in pass. If no named directory entry was found for the du, the string is null. If the du was found but there is no password, pass is returned as spaces. */ char *getpass(du,pass) char *pass; { unsigned numdir,i; char *p; struct ndre *ndrp; #ifdef BDSC struct env *zenv(), *envadr; envadr = zenv(); ndrp=envadr->ndr; #else ndrp=(struct ndre *)(envadr->ndr); /* address of ndr */ #endif numdir=envadr->ndrsize; /* number of names */ ++du; /* bump drive number by 1 for ndr */ p=pass; for(;numdir--;++ndrp) { if(ndrp->drvusr == du) { for(i=0;i<8;++i) *p++ = ndrp->passwd[i]; break; } } *p = '\0'; /* terminate name (if any) */ return(pass); }