📄 fcbfns.c
字号:
/****************************************************************/
/* */
/* fcbfns.c */
/* */
/* Old CP/M Style Function Handlers for Kernel */
/* */
/* Copyright (c) 1995 */
/* Pasquale J. Villani */
/* All Rights Reserved */
/* */
/* This file is part of DOS-C. */
/* */
/* DOS-C is free software; you can redistribute it and/or */
/* modify it under the terms of the GNU General Public License */
/* as published by the Free Software Foundation; either version */
/* 2, or (at your option) any later version. */
/* */
/* DOS-C is distributed in the hope that it will be useful, but */
/* WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */
/* the GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public */
/* License along with DOS-C; see the file COPYING. If not, */
/* write to the Free Software Foundation, 675 Mass Ave, */
/* Cambridge, MA 02139, USA. */
/****************************************************************/
#include "../../hdr/portab.h"
#include "globals.h"
/* $Logfile: C:/dos-c/src/fs/fcbfns.c_v $ */
#ifdef VERSION_STRINGS
static BYTE *RcsId = "$Header: C:/dos-c/src/fs/fcbfns.c_v 1.6 04 Jan 1998 23:14:38 patv $";
#endif
/* $Log: C:/dos-c/src/fs/fcbfns.c_v $
*
* Rev 1.6 04 Jan 1998 23:14:38 patv
* Changed Log for strip utility
*
* Rev 1.5 03 Jan 1998 8:36:02 patv
* Converted data area to SDA format
*
* Rev 1.4 16 Jan 1997 12:46:38 patv
* pre-Release 0.92 feature additions
*
* Rev 1.3 29 May 1996 21:15:14 patv
* bug fixes for v0.91a
*
* Rev 1.2 01 Sep 1995 17:48:44 patv
* First GPL release.
*
* Rev 1.1 30 Jul 1995 20:50:26 patv
* Eliminated version strings in ipl
*
* Rev 1.0 02 Jul 1995 8:06:06 patv
* Initial revision.
*/
/* $EndLog$ */
#define FCB_SUCCESS 0
#define FCB_ERR_NODATA 1
#define FCB_ERR_EOF 3
#define FCB_ERR_WRITE 1
#define D_ALL D_NORMAL | D_RDONLY | D_HIDDEN | D_SYSTEM | D_DIR | D_ARCHIVE
#ifdef PROTO
fcb FAR *ExtFcbToFcb(xfcb FAR *lpExtFcb);
fcb FAR *CommonFcbInit(xfcb FAR *lpExtFcb, BYTE *pszBuffer, COUNT *pCurDrive);
void FcbNameInit(fcb FAR *lpFcb, BYTE *pszBuffer, COUNT *pCurDrive);
sft FAR *FcbGetSft(COUNT SftIndex);
VOID FcbNextRecord(fcb FAR *lpFcb);
sft FAR *FcbGetFreeSft(WORD FAR *sft_idx);
BOOL FcbFnameMatch(BYTE FAR *s, BYTE FAR *d, COUNT n, COUNT mode);
BOOL FcbCharMatch(COUNT s, COUNT d, COUNT mode);
BOOL FcbCalcRec(xfcb FAR *lpXfcb);
VOID MoveDirInfo(dmatch FAR *lpDmatch, struct dirent FAR *lpDir);
#else
fcb FAR *ExtFcbToFcb();
fcb FAR *CommonFcbInit();
void FcbNameInit();
sft FAR *FcbGetSft();
VOID FcbNextRecord();
sft FAR *FcbGetFreeSft();
BOOL FcbFnameMatch();
BOOL FcbCharMatch();
BOOL FcbCalcRec();
VOID MoveDirInfo();
#endif
static dmatch Dmatch;
VOID DosOutputString(BYTE FAR *s)
{
while(*s != '$')
DosCharOutput(*s++);
}
static BYTE *con_name = "CON";
int DosCharInputEcho(VOID)
{
BYTE cb;
CharReqHdr.r_length = sizeof(request);
CharReqHdr.r_command = C_INPUT;
CharReqHdr.r_count = 1;
CharReqHdr.r_trans = (VOID FAR *)&cb;
CharReqHdr.r_status = 0;
execrh((request FAR *)&CharReqHdr, syscon);
if(CharReqHdr.r_status & S_ERROR)
return char_error(&CharReqHdr, con_name);
DosCharOutput(cb);
return cb;
}
int DosCharInput(VOID)
{
BYTE cb;
CharReqHdr.r_length = sizeof(request);
CharReqHdr.r_command = C_INPUT;
CharReqHdr.r_count = 1;
CharReqHdr.r_trans = (VOID FAR *)&cb;
CharReqHdr.r_status = 0;
execrh((request FAR *)&CharReqHdr, syscon);
if(CharReqHdr.r_status & S_ERROR)
return char_error(&CharReqHdr, con_name);
return cb;
}
VOID DosDirectConsoleIO(iregs FAR *r)
{
BYTE buf;
if(r -> DL == 0xff)
{
r -> FLAGS &= ~FLG_ZERO;
CharReqHdr.r_length = sizeof(request);
CharReqHdr.r_command = C_ISTAT;
CharReqHdr.r_status = 0;
execrh((request FAR *)&CharReqHdr, syscon);
if(CharReqHdr.r_status & S_ERROR)
{
char_error(&CharReqHdr, con_name);
return;
}
if(CharReqHdr.r_status & S_BUSY)
{
CharReqHdr.r_length = sizeof(request);
CharReqHdr.r_command = C_INPUT;
CharReqHdr.r_count = 1;
CharReqHdr.r_trans = (VOID FAR *)&buf;
CharReqHdr.r_status = 0;
execrh((request FAR *)&CharReqHdr, syscon);
if(CharReqHdr.r_status & S_ERROR)
{
char_error(&CharReqHdr, con_name);
return;
}
r -> AL = buf;
r -> FLAGS |= FLG_ZERO;
}
}
else
{
CharReqHdr.r_length = sizeof(request);
CharReqHdr.r_command = C_OUTPUT;
CharReqHdr.r_count = 1;
CharReqHdr.r_trans = (VOID FAR *)(&buf);
CharReqHdr.r_status = 0;
execrh((request FAR *)&CharReqHdr, syscon);
if(CharReqHdr.r_status & S_ERROR)
char_error(&CharReqHdr, con_name);
}
}
/* Console output with printer echo */
VOID DosCharOutput(COUNT c)
{
BYTE buf = c;
/* Test for break first */
if(con_break())
return;
/* Now do an output directly to the console */
CharReqHdr.r_length = sizeof(request);
CharReqHdr.r_command = C_OUTPUT;
CharReqHdr.r_count = 1;
CharReqHdr.r_trans = (VOID FAR *)(&buf);
CharReqHdr.r_status = 0;
execrh((request FAR *)&CharReqHdr, syscon);
if(CharReqHdr.r_status & S_ERROR)
char_error(&CharReqHdr, con_name);
++scr_pos;
/* printer echo stuff */
}
VOID DosDisplayOutput(COUNT c)
{
/* Non-portable construct */
if(c < ' ' || c == 0x7f)
{
switch(c)
{
case '\r':
scr_pos = 0;
break;
case 0x7f:
++scr_pos;
break;
case '\b':
if(scr_pos > 0)
--scr_pos;
break;
case '\t':
do
DosCharOutput(' ');
while(scr_pos & 7);
return;
default:
break;
}
DosCharOutput(c);
}
else
{
DosCharOutput(c);
}
}
VOID
FatGetDrvData (COUNT drive, COUNT FAR *spc, COUNT FAR *bps, COUNT FAR *nc, BYTE FAR **mdp)
{
struct dpb *dpbp;
/* first check for valid drive */
if(drive < 0 || drive > NDEVS)
{
*spc = -1;
return;
}
/* next - "log" in the drive */
drive = (drive == 0 ? default_drive : drive - 1);
dpbp = &blk_devices[drive];
++(dpbp -> dpb_count);
dpbp -> dpb_flags = -1;
if((media_check(dpbp) < 0) || (dpbp -> dpb_count <= 0))
{
*spc = -1;
return;
}
/* get the data vailable from dpb */
*nc = dpbp -> dpb_size;
*spc = dpbp -> dpb_clsmask;
*bps = dpbp -> dpb_secsize;
/* Point to the media desctriptor fotr this drive */
*mdp = &(dpbp -> dpb_mdb);
--(dpbp -> dpb_count);
}
#define PARSE_SEP_STOP 0x01
#define PARSE_DFLT_DRIVE 0x02
#define PARSE_BLNK_FNAME 0x04
#define PARSE_BLNK_FEXT 0x08
#define PARSE_RET_NOWILD 0
#define PARSE_RET_WILD 1
#define PARSE_RET_BADDRIVE 0xff
#ifndef IPL
WORD FcbParseFname(wTestMode, lpFileName, lpFcb)
REG WORD wTestMode;
BYTE FAR **lpFileName;
fcb FAR *lpFcb;
{
COUNT nIndex;
WORD wRetCode = PARSE_RET_NOWILD;
/* pjv -- ExtFcbToFcb? */
/* Start out with some simple stuff first. Check if we are */
/* going to use a default drive specificaton. */
if(!(wTestMode & PARSE_DFLT_DRIVE))
lpFcb -> fcb_drive = FDFLT_DRIVE;
if(!(wTestMode & PARSE_BLNK_FNAME))
{
for(nIndex = 0; nIndex < FNAME_SIZE; ++nIndex)
lpFcb -> fcb_fname[nIndex] = ' ';
}
if(!(wTestMode & PARSE_BLNK_FEXT))
{
for(nIndex = 0; nIndex < FEXT_SIZE; ++nIndex)
lpFcb -> fcb_fext[nIndex] = ' ';
}
/* Undocumented behavior, set record number & record size to 0 */
lpFcb -> fcb_cublock = lpFcb -> fcb_recsiz = 0;
if(!(wTestMode & PARSE_SEP_STOP))
{
*lpFileName = ParseSkipWh(*lpFileName);
if(TestCmnSeps(*lpFileName))
++*lpFileName;
}
/* Undocumented "feature," we skip white space anyway */
*lpFileName = ParseSkipWh(*lpFileName);
/* Now check for drive specification */
if(*(*lpFileName + 1) == ':')
{
REG BYTE Drive = upChar(**lpFileName);
/* non-portable construct to be changed */
if(Drive < 'A' || Drive > 'Z')
return PARSE_RET_BADDRIVE;
Drive -= ('A' - 1);
if(Drive > nblkdev)
return PARSE_RET_BADDRIVE;
else
lpFcb -> fcb_drive = Drive;
*lpFileName += 2;
}
/* Now to format the file name into the string */
*lpFileName = GetNameField(*lpFileName, (BYTE FAR *)lpFcb -> fcb_fname, FNAME_SIZE, (BOOL *)&wRetCode);
/* Do we have an extension? If do, format it else return */
if(**lpFileName == '.')
*lpFileName = GetNameField(++*lpFileName, (BYTE FAR *)lpFcb -> fcb_fext, FEXT_SIZE, (BOOL *)&wRetCode);
return wRetCode ? PARSE_RET_WILD : PARSE_RET_NOWILD;
}
BYTE FAR *
ParseSkipWh (BYTE FAR *lpFileName)
{
while(*lpFileName == ' ' || *lpFileName == '\t')
++lpFileName;
return lpFileName;
}
BOOL
TestCmnSeps (BYTE FAR *lpFileName)
{
BYTE *pszTest, *pszCmnSeps = ":<|>+=,";
for(pszTest = pszCmnSeps; *pszTest != '\0'; ++pszTest)
if(*lpFileName == *pszTest)
return TRUE;
return FALSE;
}
BOOL
TestFieldSeps (BYTE FAR *lpFileName)
{
BYTE *pszTest, *pszCmnSeps = "/\"[]<>|.";
/* Another non-portable construct */
if(*lpFileName <= ' ')
return TRUE;
for(pszTest = pszCmnSeps; *pszTest != '\0'; ++pszTest)
if(*lpFileName == *pszTest)
return TRUE;
return FALSE;
}
BYTE FAR *
GetNameField (BYTE FAR *lpFileName, BYTE FAR *lpDestField, COUNT nFieldSize, BOOL *pbWildCard)
{
COUNT nIndex = 0;
BYTE cFill = ' ';
*pbWildCard = FALSE;
while(*lpFileName != '\0' && !TestFieldSeps(lpFileName) && nIndex< nFieldSize)
{
if(*lpFileName == ' ')
break;
if(*lpFileName == '*')
{
*pbWildCard = TRUE;
cFill = '?';
++lpFileName;
break;
}
if(*lpFileName == '?')
*pbWildCard = TRUE;
*lpDestField++ = upChar(*lpFileName++);
++nIndex;
}
/* Blank out remainder of field on exit */
for( ; nIndex < nFieldSize; ++nIndex)
*lpDestField++ = cFill;
return lpFileName;
}
static sft FAR *FcbGetSft(SftIndex)
COUNT SftIndex;
{
/* Get the SFT block that contains the SFT */
for(lpCurSft = sfthead; lpCurSft != (sfttbl FAR *)-1;
lpCurSft = lpCurSft -> sftt_next)
{
if(SftIndex < lpCurSft -> sftt_count)
break;
else
SftIndex -= lpCurSft -> sftt_count;
}
/* If not found, return an error */
if(lpCurSft == (sfttbl FAR *)-1)
return (sft FAR *)-1;
/* finally, point to the right entry */
return (sft FAR *)&(lpCurSft -> sftt_table[SftIndex]);
}
static VOID FcbNextRecord(lpFcb)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -