mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-23 08:24:18 +00:00
184 lines
7.5 KiB
C
184 lines
7.5 KiB
C
/****************************************************************************/
|
||
/* */
|
||
/* _ o p e n F u n c t i o n */
|
||
/* --------------------------- */
|
||
/* Copyright 1982 by Digital Research Inc. All rights reserved. */
|
||
/* */
|
||
/* Function "__open" is used to parse the CP/M fcb and open or create */
|
||
/* the requested file. Created files are deleted first, to avoid */
|
||
/* directory problems. */
|
||
/* */
|
||
/* Calling Sequence: */
|
||
/* */
|
||
/* ret = __open(ch,filnam,bdosfunc); */
|
||
/* */
|
||
/* Where: */
|
||
/* ch Is a vacant channel number */
|
||
/* filnam Is a null-terminated CP/M filename */
|
||
/* bdosfunc Is the desired BDOS function to perform */
|
||
/* */
|
||
/* This routine may also be used to delete files as well. */
|
||
/* */
|
||
/* Modified 26-Jun-83 (sw) for wild cards and user # support */
|
||
/* */
|
||
/****************************************************************************/
|
||
#include <portab.h>
|
||
#include <cpm.h>
|
||
#include <ctype.h>
|
||
BYTE *_index(); /* Character locator */
|
||
WORD __open(ch,filnam,bdosfunc) /****************************/
|
||
/* */
|
||
WORD ch; /* Channel number */
|
||
REG BYTE *filnam; /* -> filename */
|
||
WORD bdosfunc; /* BDOS Function */
|
||
{ /****************************/
|
||
REG FD *fp; /* -> ccb area */
|
||
REG struct fcbtab *fcbp; /* -> FCB area in ccb */
|
||
REG BYTE *p; /* Temp character pointer */
|
||
REG WORD i; /* Character index */
|
||
BYTE tokbuf[32]; /* Token temporary buffer */
|
||
REG WORD xuser; /* User number */
|
||
BYTE *get_token(); /****************************/
|
||
fp = _getccb(ch); /* Fetch ccb pointer */
|
||
fcbp = &(fp ->fcb); /* Fetch fcb pointer */
|
||
/****************************/
|
||
xuser = __BDOS(USER,0xFFL); /* Fetch current user number*/
|
||
fp->user = xuser; /* Set it as default */
|
||
/****************************/
|
||
filnam = get_token(filnam,tokbuf,32); /* Get the next token */
|
||
if(*filnam == ':') /* Is the delim a colon? */
|
||
{ /* If yes, then a drive spec*/
|
||
if(stuff_drive(fp,fcbp,tokbuf) == FAILURE) /* Check drive OK */
|
||
return(FAILURE); /* Return error if bad */
|
||
filnam=get_token(++filnam,tokbuf,32); /* Get next token */
|
||
} /****************************/
|
||
/* */
|
||
if(*filnam == '*') /* Delimiter is a "*"?? */
|
||
{ /* */
|
||
fill(&(fcbp->fname[0]),'?',8); /* Yes, fill with ?'s 1st */
|
||
filnam++; /* Bump to next character */
|
||
} /****************************/
|
||
_strcpy(tokbuf,fcbp->fname,8); /* Copy the file name in */
|
||
if(*filnam && (*filnam != '.')) /* Check legality */
|
||
return(FAILURE); /* Not legal file name */
|
||
/****************************/
|
||
if(*filnam++ == '.') /* If extension specified */
|
||
{ /* */
|
||
filnam=get_token(filnam,tokbuf,32); /* get extension token */
|
||
if(*filnam == '*') /* Is wildcarded ext? */
|
||
fill(&(fcbp->fname[8]),'?',3); /* If yes, fill with ?'s */
|
||
_strcpy(tokbuf,&(fcbp->fname[8]),3); /* Copy the string */
|
||
} /* */
|
||
/****************************/
|
||
if(bdosfunc == CREATE) /* Creating file? */
|
||
{ /* */
|
||
if(_index(fcbp->fname,'?')) /* Wild cards @!@#$!!! */
|
||
return(FAILURE); /* Just quit */
|
||
if(xuser != fp->user) /* need to change users? */
|
||
__BDOS(USER,(LONG)fp->user); /* Use user # specified */
|
||
/****************************/
|
||
__BDOS(DELETE,fcbp); /* delete it first */
|
||
} /****************************/
|
||
if(xuser != fp->user) /* Different user #?? */
|
||
__BDOS(USER,(LONG)fp->user); /* Change it first */
|
||
/* */
|
||
i = __BDOS(bdosfunc,fcbp); /* Do requested operation */
|
||
if(xuser != fp->user) /* did we change users? */
|
||
__BDOS(USER,(LONG)xuser); /* Then change back */
|
||
/* */
|
||
if(bdosfunc == SEARCHF || /* For search first */
|
||
bdosfunc == SEARCHN) /* or search next */
|
||
return(i); /* return directory index */
|
||
return((i<=3) ? SUCCESS : FAILURE); /* Binary return code */
|
||
} /****************************/
|
||
MLOCAL _strcpy(s,d,c) /* Special string copy func */
|
||
REG BYTE *s; /* Source string */
|
||
REG BYTE *d; /* Destination area */
|
||
REG WORD c; /* Count */
|
||
{ /****************************/
|
||
while ((*s) && (c)) /* */
|
||
{ /* */
|
||
*d++ = toupper(*s); /* Copy a byte */
|
||
s++; /* Up source */
|
||
c--; /* Down count */
|
||
} /* */
|
||
} /****************************/
|
||
|
||
/****************************************************************************/
|
||
/* */
|
||
/* G e t _ t o k e n R o u t i n e */
|
||
/* --------------------------------- */
|
||
/* */
|
||
/* Routine get_token takes the next token from the input string. */
|
||
/* */
|
||
/* Calling Sequence: */
|
||
/* */
|
||
/* ret = get_token(src,dest,len); */
|
||
/* */
|
||
/* Where: */
|
||
/* */
|
||
/* src is the address of the source string */
|
||
/* dest is the address of the destination area */
|
||
/* len is the number of bytes in "dest". */
|
||
/* */
|
||
/* ret is the returned address of the delimiter */
|
||
/* */
|
||
/****************************************************************************/
|
||
MLOCAL BYTE *_delim="<>.,=:+-&/\\|()[]*"; /* Delimiter set */
|
||
MLOCAL BYTE *get_token(src,dest,len) /* */
|
||
REG BYTE *src; /* -> source */
|
||
REG BYTE *dest; /* -> destination */
|
||
REG WORD len; /* output area size */
|
||
{ /****************************/
|
||
while(*src && (!_index(_delim,*src)) && len)/* Until done */
|
||
{ /* */
|
||
*dest++ = *src++; /* Move 1 byte */
|
||
len--; /* Down count */
|
||
} /****************************/
|
||
*dest = '\0'; /* Drop in null terminator */
|
||
return(src); /* Return delimiter addr. */
|
||
} /****************************/
|
||
|
||
/****************************************************************************/
|
||
/* */
|
||
/* S t u f f _ d r i v e F u n c t i o n */
|
||
/* --------------------------------------- */
|
||
/* */
|
||
/* Routine "stuff_drive" loads the user and drive code fields from */
|
||
/* the filename string. */
|
||
/* */
|
||
/* Calling sequence: */
|
||
/* */
|
||
/* ret = stuff_drive(fp,fcbp,src); */
|
||
/* */
|
||
/* Where: */
|
||
/* */
|
||
/* fp Is the ccb address */
|
||
/* fcbp Is the FCB address within the ccb */
|
||
/* src Is the source filename string */
|
||
/* */
|
||
/****************************************************************************/
|
||
MLOCAL WORD stuff_drive(fp,fcbp,src) /* */
|
||
REG FD *fp; /* -> CCB area */
|
||
REG struct fcbtab *fcbp; /* -> FCB area */
|
||
REG BYTE *src; /* -> Source string */
|
||
{ /****************************/
|
||
REG WORD i; /* Accumulator */
|
||
i = 0; /* Zap to zero */
|
||
while(isdigit(*src)) /* As long as source is dig.*/
|
||
{ /* */
|
||
i = (i*10) + *src++ - '0'; /* Convert to number */
|
||
fp->user = i; /* store user number */
|
||
} /****************************/
|
||
/* */
|
||
if(*src) /* Drive code letter? */
|
||
{ /* Here => yes */
|
||
fcbp->drive = toupper(*src)-'A'+1; /* get drive code byte */
|
||
src++; /* Increment source pointer */
|
||
} /* */
|
||
if(*src || (fp->user > 15)) /* Illegal stuff? */
|
||
return(FAILURE); /* Yes, quit */
|
||
return(SUCCESS); /* OK to continue */
|
||
} /****************************/
|
||
|