/*************************************************************************** * * _ p a r s e f n F u n c t i o n * --------------------------------- * Copyright 1983 by Digital Research Inc. All rights reserved. * * Function "_parsefn()" is used to parse a filename into the CP/M fcb. * NOTE: For PCDOS, an OS call is written in assembler ("_pc_parse()"). * * Calling Sequence: * ret = _parsefn(filnam,fcbp); * * Where: * filnam Is a null-terminated CP/M filename * ret Is NULLPTR if entire string parsed, * -1 if there was an error, or * a pointer to the next item to parse * fcbp Is the address of a CP/M File Control Block (fcb). * Note: password will get stuffed into bytes 16-23 * user # (plus 1) in byte 24, if supplied in filnam. * File Spec: * #d:filename.typ;passwd * * Modified: * 1/84 whf handle 68K parsing error. ****************************************************************************/ #include "portab.h" #include "osif.h" #include "ctype.h" #define FAILPTR ((BYTE *)(-1)) /* FAILURE */ BYTE * /****************************/ _parsefn(filnam,fcbp) /* */ REG BYTE *filnam; /* -> filename */ struct fcbtab *fcbp; /* -> FCB address */ { /****************************/ #if PCDOS /*================================================================*/ REG BYTE *retp; /* To convert to ret val */ BYTE *_pc_parse(); /* Use PC-DOS parse call */ /* */ retp = _pc_parse(filnam,fcbp); /* return 1st char after fnam*/ if( fcbp->fname[0] == ' ' ) /* PC-DOS convention for bad*/ return FAILPTR; /* ...filename */ while( isspace(*retp) ) /* skip trailing white stuff*/ ++retp; /* */ if( *retp == NULL ) /* parsed to EOS? */ return NULLPTR; /* yes, say so */ else return retp; /* no, return ptr */ } #endif /*==================================================================*/ #if CPM /*==================================================================*/ BYTE tokbuf[32]; /* Token temporary buffer */ BYTE *get_token(); /* Tokenize the file name */ /****************************/ blkfill(fcbp,NULL,32); /* Init fcb area to NULLs */ blkfill(&(fcbp->fname[0]),' ',11); /* with name area to spaces */ /* */ filnam = get_token(filnam,tokbuf,32); /* Get the first token */ if(*filnam == ':') /* Is the delim a colon? */ { /* If yes, then a drive spec*/ if(stuff_drive(fcbp,tokbuf) == FAILURE) /* Check drive OK */ return FAILPTR; /* Return error if bad */ filnam=get_token(++filnam,tokbuf,32); /* Get next token */ } /****************************/ /* */ if(*filnam == '*') /* Delimiter is a "*"?? */ { /* */ blkfill(&(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 == '.') /* If extension specified */ { /* */ filnam=get_token(++filnam,tokbuf,32); /* get extension token */ if(*filnam == '*') /* Is wildcarded ext? */ { /* */ blkfill(&(fcbp->fname[8]),'?',3); /* If yes, fill with ?'s */ filnam++; /* Bump to next character */ } /* */ _strcpy(tokbuf,&(fcbp->fname[8]),3); /* Copy the string */ } /* */ if(*filnam == ';') /* If password specified */ { /* */ filnam=get_token(++filnam,tokbuf,32); /* get extension token */ _strcpy(tokbuf,&(fcbp->fpasswd[0]),8);/* Copy the string */ } /* */ switch(*filnam) /* Check for EOS */ { /* */ case NULL: /* Null terminated */ case '\n': /* CCPM compatible */ case '\r': /* " " */ return NULLPTR; /* everything a-ok */ } /**** */ return FAILPTR; /* Not legal file name */ } /****************************/ 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="<>.,=:|[]*\n\r"; /* 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 && (!strchr(_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(fcbp,src); */ /* */ /* Where: */ /* fcbp Is the FCB address within the ccb */ /* src Is the source filename string */ /* ret Is SUCCESS if ok, FAILURE o.w. */ /* */ /****************************************************************************/ MLOCAL WORD stuff_drive(fcbp,src) /* */ 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 */ fcbp->fuser = i+1; /* 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 || /* Illegal stuff? */ (fcbp->fuser > 15) || /* Bad user #? */ (fcbp->drive > 15) ) /* Bad drive? */ return(FAILURE); /* Yes, quit */ return(SUCCESS); /* OK to continue */ } /****************************/ #endif /*==================================================================*/