FCBFNS.C
资源名称:840.rar [点击查看]
上传用户:dcs7469208
上传日期:2010-01-02
资源大小:443k
文件大小:33k
源码类别:
操作系统开发
开发平台:
DOS
- /****************************************************************/
- /* */
- /* 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 != ' '; ++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 != ' '; ++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 != ' ' && !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)
- fcb FAR *lpFcb;
- {
- if(++lpFcb -> fcb_curec > 128)
- {
- lpFcb -> fcb_curec = 0;
- ++lpFcb -> fcb_cublock;
- }
- }
- BOOL FcbRead(lpXfcb, nErrorCode)
- xfcb FAR *lpXfcb;
- COUNT *nErrorCode;
- {
- sft FAR *s;
- LONG lPosit;
- COUNT nRead;
- psp FAR *p = MK_FP(cu_psp,0);
- /* Convert to fcb if necessary */
- lpFcb = ExtFcbToFcb(lpXfcb);
- /* Get the SFT block that contains the SFT */
- if((s = FcbGetSft(lpFcb -> fcb_sftno)) == (sft FAR *)-1)
- return FALSE;
- /* If this is not opened another error */
- if(s -> sft_count == 0)
- return FALSE;
- /* Now update the fcb and compute where we need to position */
- /* to. */
- lPosit = ((lpFcb -> fcb_cublock * 128) + lpFcb -> fcb_curec)
- * lpFcb -> fcb_recsiz;
- if(dos_lseek(s -> sft_status, lPosit, 0) < 0)
- {
- *nErrorCode = FCB_ERR_EOF;
- return FALSE;
- }
- /* Do the read */
- nRead = dos_read(s -> sft_status,
- p -> ps_dta, lpFcb -> fcb_recsiz);
- /* Now find out how we will return and do it. */
- if(nRead == lpFcb -> fcb_recsiz)
- {
- *nErrorCode = FCB_SUCCESS;
- FcbNextRecord(lpFcb);
- return TRUE;
- }
- else if(nRead < 0)
- {
- *nErrorCode = FCB_ERR_EOF;
- return TRUE;
- }
- else if(nRead == 0)
- {
- *nErrorCode = FCB_ERR_NODATA;
- return FALSE;
- }
- else
- {
- COUNT nIdx, nCount;
- BYTE FAR *lpDta;
- nCount = lpFcb -> fcb_recsiz - nRead;
- lpDta = (BYTE FAR *)&(p -> ps_dta[nRead]);
- for(nIdx = 0; nIdx < nCount; nIdx++)
- *lpDta++ = 0;
- *nErrorCode = FCB_ERR_EOF;
- FcbNextRecord(lpFcb);
- return FALSE;
- }
- }
- BOOL FcbWrite(lpXfcb, nErrorCode)
- xfcb FAR *lpXfcb;
- COUNT *nErrorCode;
- {
- sft FAR *s;
- LONG lPosit;
- COUNT nWritten;
- psp FAR *p = MK_FP(cu_psp,0);
- /* Convert to fcb if necessary */
- lpFcb = ExtFcbToFcb(lpXfcb);
- /* Get the SFT block that contains the SFT */
- if((s = FcbGetSft(lpFcb -> fcb_sftno)) == (sft FAR *)-1)
- return FALSE;
- /* If this is not opened another error */
- if(s -> sft_count == 0)
- return FALSE;
- /* Now update the fcb and compute where we need to position */
- /* to. */
- lPosit = ((lpFcb -> fcb_cublock * 128) + lpFcb -> fcb_curec)
- * lpFcb -> fcb_recsiz;
- if(dos_lseek(s -> sft_status, lPosit, 0) < 0)
- {
- *nErrorCode = FCB_ERR_EOF;
- return FALSE;
- }
- /* Do the read */
- nWritten = dos_write(s -> sft_status,
- p -> ps_dta, lpFcb -> fcb_recsiz);
- /* Now find out how we will return and do it. */
- if(nWritten == lpFcb -> fcb_recsiz)
- {
- lpFcb -> fcb_fsize = dos_getcufsize(s -> sft_status);
- FcbNextRecord(lpFcb);
- *nErrorCode = FCB_SUCCESS;
- return TRUE;
- }
- else if(nWritten <= 0)
- {
- *nErrorCode = FCB_ERR_WRITE;
- return TRUE;
- }
- *nErrorCode = FCB_ERR_WRITE;
- return FALSE;
- }
- BOOL FcbGetFileSize(lpXfcb)
- xfcb FAR *lpXfcb;
- {
- COUNT FcbDrive, FileNum;
- /* Build a traditional DOS file name */
- lpFcb = CommonFcbInit(lpXfcb, PriPathName, &FcbDrive);
- /* check for a device */
- /* if we have an extension, can't be a device */
- if(IsDevice(PriPathName) || (lpFcb -> fcb_recsiz == 0))
- {
- return FALSE;
- }
- FileNum = dos_open(PriPathName, O_RDONLY);
- if(FileNum >= 0)
- {
- LONG fsize;
- /* Get the size */
- fsize = dos_getfsize(FileNum);
- /* compute the size and update the fcb */
- lpFcb -> fcb_rndm = fsize / lpFcb -> fcb_recsiz;
- if((fsize % lpFcb -> fcb_recsiz) != 0)
- ++lpFcb -> fcb_rndm;
- /* close the file and leave */
- return dos_close(FileNum) == SUCCESS;
- }
- else
- return FALSE;
- }
- BOOL FcbSetRandom(lpXfcb)
- xfcb FAR *lpXfcb;
- {
- LONG lPosit;
- /* Convert to fcb if necessary */
- lpFcb = ExtFcbToFcb(lpXfcb);
- /* Now update the fcb and compute where we need to position */
- /* to. */
- lpFcb -> fcb_rndm = (lpFcb -> fcb_cublock * 128)
- + lpFcb -> fcb_curec;
- return TRUE;
- }
- BOOL FcbCalcRec(lpXfcb)
- xfcb FAR *lpXfcb;
- {
- LONG lPosit;
- /* Convert to fcb if necessary */
- lpFcb = ExtFcbToFcb(lpXfcb);
- /* Now update the fcb and compute where we need to position */
- /* to. */
- lpFcb -> fcb_cublock = lpFcb -> fcb_rndm / 128;
- lpFcb -> fcb_curec = lpFcb -> fcb_rndm % 128;
- return TRUE;
- }
- BOOL FcbRandomBlockRead(lpXfcb, nRecords, nErrorCode)
- xfcb FAR *lpXfcb;
- COUNT nRecords;
- COUNT *nErrorCode;
- {
- FcbCalcRec(lpXfcb);
- /* Convert to fcb if necessary */
- lpFcb = ExtFcbToFcb(lpXfcb);
- do
- FcbRead(lpXfcb, nErrorCode);
- while ((--nRecords > 0) && (*nErrorCode == 0));
- /* Now update the fcb */
- lpFcb -> fcb_rndm = lpFcb -> fcb_cublock * 128 + lpFcb -> fcb_curec;
- return TRUE;
- }
- BOOL FcbRandomBlockWrite(lpXfcb, nRecords, nErrorCode)
- xfcb FAR *lpXfcb;
- COUNT nRecords;
- COUNT *nErrorCode;
- {
- FcbCalcRec(lpXfcb);
- /* Convert to fcb if necessary */
- lpFcb = ExtFcbToFcb(lpXfcb);
- do
- FcbWrite(lpXfcb, nErrorCode);
- while ((--nRecords > 0) && (*nErrorCode == 0));
- /* Now update the fcb */
- lpFcb -> fcb_rndm = lpFcb -> fcb_cublock * 128 + lpFcb -> fcb_curec;
- return TRUE;
- }
- BOOL FcbRandomRead(lpXfcb, nErrorCode)
- xfcb FAR *lpXfcb;
- COUNT *nErrorCode;
- {
- UWORD uwCurrentBlock;
- UBYTE ucCurrentRecord;
- FcbCalcRec(lpXfcb);
- /* Convert to fcb if necessary */
- lpFcb = ExtFcbToFcb(lpXfcb);
- uwCurrentBlock = lpFcb -> fcb_cublock;
- ucCurrentRecord = lpFcb -> fcb_curec;
- FcbRead(lpXfcb, nErrorCode);
- lpFcb -> fcb_cublock = uwCurrentBlock;
- lpFcb -> fcb_curec = ucCurrentRecord;
- return TRUE;
- }
- BOOL FcbRandomWrite(lpXfcb, nErrorCode)
- xfcb FAR *lpXfcb;
- COUNT *nErrorCode;
- {
- UWORD uwCurrentBlock;
- UBYTE ucCurrentRecord;
- FcbCalcRec(lpXfcb);
- /* Convert to fcb if necessary */
- lpFcb = ExtFcbToFcb(lpXfcb);
- uwCurrentBlock = lpFcb -> fcb_cublock;
- ucCurrentRecord = lpFcb -> fcb_curec;
- FcbWrite(lpXfcb, nErrorCode);
- lpFcb -> fcb_cublock = uwCurrentBlock;
- lpFcb -> fcb_curec = ucCurrentRecord;
- return TRUE;
- }
- static sft FAR *FcbGetFreeSft(sft_idx)
- WORD FAR *sft_idx;
- {
- WORD sys_idx = 0;
- sfttbl FAR *sp;
- /* Get the SFT block that contains the SFT */
- for(sp = sfthead; sp != (sfttbl FAR *)-1; sp = sp -> sftt_next)
- {
- REG WORD i;
- for(i = 0; i < sp -> sftt_count; i++)
- {
- if(sp -> sftt_table[i].sft_count == 0)
- {
- *sft_idx = sys_idx + i;
- return (sft FAR *)&sp -> sftt_table[sys_idx + i];
- }
- }
- sys_idx += i;
- }
- /* If not found, return an error */
- return (sft FAR *)-1;
- }
- BOOL FcbCreate(lpXfcb)
- xfcb FAR *lpXfcb;
- {
- WORD sft_idx;
- sft FAR *sftp;
- struct dhdr FAR *dhp;
- COUNT FcbDrive;
- /* get a free system file table entry */
- if((sftp = FcbGetFreeSft((WORD FAR *)&sft_idx)) == (sft FAR *)-1)
- return DE_TOOMANY;
- /* Build a traditional DOS file name */
- lpFcb = CommonFcbInit(lpXfcb, PriPathName, &FcbDrive);
- /* check for a device */
- /* if we have an extension, can't be a device */
- if(IsDevice(PriPathName))
- {
- for(dhp = (struct dhdr FAR *)&nul_dev; dhp != (struct dhdr FAR *)-1; dhp = dhp -> dh_next)
- {
- if(FcbFnameMatch((BYTE FAR *)PriPathName, (BYTE FAR *)dhp -> dh_name, FNAME_SIZE, FALSE))
- {
- sftp -> sft_count += 1;
- sftp -> sft_mode = O_RDWR;
- sftp -> sft_attrib = 0;
- sftp -> sft_flags =
- (dhp -> dh_attr & ~SFT_MASK) | SFT_FDEVICE | SFT_FEOF;
- sftp -> sft_psp = cu_psp;
- fbcopy(lpFcb -> fcb_fname, sftp -> sft_name, FNAME_SIZE+FEXT_SIZE);
- sftp -> sft_dev = dhp;
- lpFcb -> fcb_sftno = sft_idx;
- lpFcb -> fcb_curec = 0;
- lpFcb -> fcb_recsiz = 0;
- lpFcb -> fcb_fsize = 0;
- lpFcb -> fcb_date = dos_getdate();
- lpFcb -> fcb_time = dos_gettime();
- lpFcb -> fcb_rndm = 0;
- return TRUE;
- }
- }
- }
- sftp -> sft_status = dos_creat(PriPathName, 0);
- if(sftp -> sft_status >= 0)
- {
- lpFcb -> fcb_drive = FcbDrive;
- lpFcb -> fcb_sftno = sft_idx;
- lpFcb -> fcb_curec = 0;
- lpFcb -> fcb_recsiz = 128;
- lpFcb -> fcb_fsize = 0;
- lpFcb -> fcb_date = dos_getdate();
- lpFcb -> fcb_time = dos_gettime();
- lpFcb -> fcb_rndm = 0;
- sftp -> sft_count += 1;
- sftp -> sft_mode = O_RDWR;
- sftp -> sft_attrib = 0;
- sftp -> sft_flags = 0;
- sftp -> sft_psp = cu_psp;
- fbcopy((BYTE FAR *)&lpFcb -> fcb_fname, (BYTE FAR *)&sftp -> sft_name, FNAME_SIZE+FEXT_SIZE);
- return TRUE;
- }
- else
- return FALSE;
- }
- static fcb FAR *ExtFcbToFcb(xfcb FAR *lpExtFcb)
- {
- if(*((UBYTE FAR *)lpExtFcb) == 0xff)
- return &lpExtFcb -> xfcb_fcb;
- else
- return (fcb FAR *)lpExtFcb;
- }
- static fcb FAR *CommonFcbInit(lpExtFcb, pszBuffer, pCurDrive)
- xfcb FAR *lpExtFcb;
- BYTE *pszBuffer;
- COUNT *pCurDrive;
- {
- BYTE FAR *lpszFcbFname, *lpszFcbFext;
- COUNT nDrvIdx, nFnameIdx, nFextIdx;
- fcb FAR *lpFcb;
- /* convert to fcb if needed first */
- lpFcb = ExtFcbToFcb(lpExtFcb);
- /* Build a traditional DOS file name */
- FcbNameInit(lpFcb, pszBuffer, pCurDrive);
- /* and return the fcb pointer */
- return lpFcb;
- }
- void FcbNameInit(lpFcb, pszBuffer, pCurDrive)
- fcb FAR *lpFcb;
- BYTE *pszBuffer;
- COUNT *pCurDrive;
- {
- BYTE FAR *lpszFcbFname, FAR *lpszFcbFext;
- COUNT nDrvIdx, nFnameIdx, nFextIdx;
- /* Build a traditional DOS file name */
- lpszFcbFname = (BYTE FAR *)lpFcb -> fcb_fname;
- if(lpFcb -> fcb_drive != 0)
- {
- *pCurDrive = lpFcb -> fcb_drive;
- pszBuffer[0] = 'A' + lpFcb -> fcb_drive - 1;
- pszBuffer[1] = ':';
- nDrvIdx = 2;
- }
- else
- {
- *pCurDrive = default_drive + 1;
- nDrvIdx = 0;
- }
- for(nFnameIdx = 0; nFnameIdx < FNAME_SIZE; nFnameIdx++)
- {
- if(*lpszFcbFname != ' ')
- pszBuffer[nDrvIdx + nFnameIdx] = *lpszFcbFname++;
- else
- break;
- }
- lpszFcbFext = (BYTE FAR *)lpFcb -> fcb_fext;
- if(*lpszFcbFext != ' ')
- {
- pszBuffer[nDrvIdx + nFnameIdx++] = '.';
- for(nFextIdx = 0; nFextIdx < FEXT_SIZE; nFextIdx++)
- {
- if(*lpszFcbFext != ' ')
- pszBuffer[nDrvIdx + nFnameIdx + nFextIdx] =
- *lpszFcbFext++;
- else
- break;
- }
- }
- else
- nFextIdx = 0;
- pszBuffer[nDrvIdx + nFnameIdx + nFextIdx] = ' ';
- }
- /* Ascii only file name match routines */
- static BOOL
- FcbCharMatch (COUNT s, COUNT d, COUNT mode)
- {
- if(s >= 'a' && s <= 'z')
- s -= 'a' - 'A';
- if(d >= 'a' && d <= 'z')
- d -= 'a' - 'A';
- if(mode && s == '?' && (d >= 'A' && s <= 'Z'))
- return TRUE;
- return s == d;
- }
- static BOOL
- FcbFnameMatch (BYTE FAR *s, BYTE FAR *d, COUNT n, COUNT mode)
- {
- while(n--)
- {
- if(!FcbCharMatch(*s++, *d++, mode))
- return FALSE;
- }
- return TRUE;
- }
- BOOL FcbOpen(lpXfcb)
- xfcb FAR *lpXfcb;
- {
- WORD sft_idx;
- sft FAR *sftp;
- struct dhdr FAR *dhp;
- COUNT FcbDrive;
- /* get a free system file table entry */
- if((sftp = FcbGetFreeSft((WORD FAR *)&sft_idx)) == (sft FAR *)-1)
- return DE_TOOMANY;
- /* Build a traditional DOS file name */
- lpFcb = CommonFcbInit(lpXfcb, PriPathName, &FcbDrive);
- /* check for a device */
- /* if we have an extension, can't be a device */
- if(IsDevice(PriPathName))
- {
- for(dhp = (struct dhdr FAR *)&nul_dev; dhp != (struct dhdr FAR *)-1; dhp = dhp -> dh_next)
- {
- if(FcbFnameMatch((BYTE FAR *)PriPathName, (BYTE FAR *)dhp -> dh_name, FNAME_SIZE, FALSE))
- {
- sftp -> sft_count += 1;
- sftp -> sft_mode = O_RDWR;
- sftp -> sft_attrib = 0;
- sftp -> sft_flags =
- (dhp -> dh_attr & ~SFT_MASK) | SFT_FDEVICE | SFT_FEOF;
- sftp -> sft_psp = cu_psp;
- fbcopy(lpFcb -> fcb_fname, sftp -> sft_name, FNAME_SIZE+FEXT_SIZE);
- sftp -> sft_dev = dhp;
- lpFcb -> fcb_sftno = sft_idx;
- lpFcb -> fcb_curec = 0;
- lpFcb -> fcb_recsiz = 0;
- lpFcb -> fcb_fsize = 0;
- lpFcb -> fcb_date = dos_getdate();
- lpFcb -> fcb_time = dos_gettime();
- lpFcb -> fcb_rndm = 0;
- return TRUE;
- }
- }
- }
- sftp -> sft_status = dos_open(PriPathName, O_RDWR);
- if(sftp -> sft_status >= 0)
- {
- lpFcb -> fcb_drive = FcbDrive;
- lpFcb -> fcb_sftno = sft_idx;
- lpFcb -> fcb_curec = 0;
- lpFcb -> fcb_recsiz = 128;
- lpFcb -> fcb_fsize = dos_getfsize(sftp -> sft_status);
- dos_getftime(sftp -> sft_status,
- (date FAR *)&lpFcb -> fcb_date,
- (time FAR *)&lpFcb -> fcb_time);
- lpFcb -> fcb_rndm = 0;
- sftp -> sft_count += 1;
- sftp -> sft_mode = O_RDWR;
- sftp -> sft_attrib = 0;
- sftp -> sft_flags = 0;
- sftp -> sft_psp = cu_psp;
- fbcopy((BYTE FAR *)&lpFcb -> fcb_fname, (BYTE FAR *)&sftp -> sft_name, FNAME_SIZE+FEXT_SIZE);
- return TRUE;
- }
- else
- return FALSE;
- }
- BOOL FcbDelete(lpXfcb)
- xfcb FAR *lpXfcb;
- {
- COUNT FcbDrive;
- /* Build a traditional DOS file name */
- CommonFcbInit(lpXfcb, PriPathName, &FcbDrive);
- /* check for a device */
- /* if we have an extension, can't be a device */
- if(IsDevice(PriPathName))
- {
- return FALSE;
- }
- else
- {
- BYTE FAR *lpOldDta = dta;
- dmatch Dmatch;
- dta = (BYTE FAR *)&Dmatch;
- if(dos_findfirst(D_ALL, PriPathName[1] == ':' ? &PriPathName[2] : PriPathName) != SUCCESS)
- {
- dta = lpOldDta;
- return FALSE;
- }
- do
- {
- if(dos_delete(Dmatch.dm_name) != SUCCESS)
- {
- dta = lpOldDta;
- return FALSE;
- }
- }
- while(dos_findnext() == SUCCESS);
- dta = lpOldDta;
- return TRUE;
- }
- }
- BOOL FcbRename(lpXfcb)
- xfcb FAR *lpXfcb;
- {
- rfcb FAR *lpRenameFcb;
- COUNT FcbDrive;
- /* Build a traditional DOS file name */
- lpRenameFcb = (rfcb FAR *)CommonFcbInit(lpXfcb, PriPathName, &FcbDrive);
- /* check for a device */
- /* if we have an extension, can't be a device */
- if(IsDevice(PriPathName))
- {
- return FALSE;
- }
- else
- {
- BYTE FAR *lpOldDta = dta;
- dmatch Dmatch;
- dta = (BYTE FAR *)&Dmatch;
- if(dos_findfirst(D_ALL, PriPathName[1] == ':' ? &PriPathName[2] : PriPathName) != SUCCESS)
- {
- dta = lpOldDta;
- return FALSE;
- }
- do
- {
- fcb LocalFcb;
- BYTE *pToName, *pszFrom;
- BYTE FAR *pFromPattern;
- COUNT nIndex;
- /* First, expand the find match into fcb style */
- /* file name entry */
- /* Fill with blanks first */
- for(pToName = LocalFcb.fcb_fname, nIndex = 0;
- nIndex < FNAME_SIZE; nIndex++)
- {
- *pToName++ = ' ';
- }
- for(pToName = LocalFcb.fcb_fext, nIndex = 0;
- nIndex < FEXT_SIZE; nIndex++)
- {
- *pToName++ = ' ';
- }
- /* next move in the file name while overwriting */
- /* the filler blanks */
- pszFrom = Dmatch.dm_name;
- pToName = LocalFcb.fcb_fname;
- for(nIndex = 0; nIndex < FNAME_SIZE; nIndex++)
- {
- if(*pszFrom != 0 && *pszFrom != '.')
- *pToName++ = *pszFrom++;
- else if(*pszFrom == '.')
- {
- ++pszFrom;
- break;
- }
- else
- break;
- }
- if(*pszFrom != ' ')
- {
- pToName = LocalFcb.fcb_fext;
- for(nIndex = 0; nIndex < FEXT_SIZE; nIndex++)
- {
- if(*pszFrom != ' ')
- *pToName++ = *pszFrom++;
- else
- break;
- }
- }
- /* Overlay the pattern, skipping '?' */
- /* I'm cheating because this assumes that the */
- /* struct alignments are on byte boundaries */
- pToName = LocalFcb.fcb_fname;
- for(pFromPattern = lpRenameFcb -> renNewName,
- nIndex = 0; nIndex < FNAME_SIZE + FEXT_SIZE; nIndex++)
- {
- if(*pFromPattern != '?')
- *pToName++ = *pFromPattern++;
- else
- ++pFromPattern;
- }
- /* now to build a dos name again */
- LocalFcb.fcb_drive = 0;
- FcbNameInit((fcb FAR *)&LocalFcb, PriPathName, &FcbDrive);
- if(dos_rename(Dmatch.dm_name,
- PriPathName[1] == ':' ? &PriPathName[2] : PriPathName) != SUCCESS)
- {
- dta = lpOldDta;
- return FALSE;
- }
- }
- while(dos_findnext() == SUCCESS);
- dta = lpOldDta;
- return TRUE;
- }
- }
- void MoveDirInfo(lpDmatch, lpDir)
- dmatch FAR *lpDmatch;
- struct dirent FAR *lpDir;
- {
- BYTE FAR *lpToName, FAR *lpszFrom;
- COUNT nIndex;
- /* First, expand the find match into dir style */
- /* file name entry */
- /* Fill with blanks first */
- for(lpToName = lpDir -> dir_name, nIndex = 0;
- nIndex < FNAME_SIZE; nIndex++)
- {
- *lpToName++ = ' ';
- }
- for(lpToName = lpDir -> dir_ext, nIndex = 0;
- nIndex < FEXT_SIZE; nIndex++)
- {
- *lpToName++ = ' ';
- }
- /* next move in the file name while overwriting */
- /* the filler blanks */
- lpszFrom = lpDmatch -> dm_name;
- lpToName = lpDir -> dir_name;
- for(nIndex = 0; nIndex < FNAME_SIZE; nIndex++)
- {
- if(*lpszFrom != 0 && *lpszFrom != '.')
- *lpToName++ = *lpszFrom++;
- else
- break;
- }
- if(*lpszFrom != ' ')
- {
- if(*lpszFrom == '.')
- ++lpszFrom;
- lpToName = lpDir -> dir_ext;
- for(nIndex = 0; nIndex < FEXT_SIZE; nIndex++)
- {
- if(*lpszFrom != ' ')
- *lpToName++ = *lpszFrom++;
- else
- break;
- }
- }
- for(nIndex = 0; nIndex < 10; nIndex++)
- lpDir -> dir_reserved[nIndex] = 0;
- lpDir -> dir_attrib = lpDmatch ->dm_attr_fnd;
- lpDir -> dir_time = lpDmatch ->dm_time;
- lpDir -> dir_date = lpDmatch ->dm_date;
- lpDir -> dir_start = lpDmatch ->dm_cluster;
- lpDir -> dir_size = lpDmatch ->dm_size;
- }
- BOOL FcbClose(lpXfcb)
- xfcb FAR *lpXfcb;
- {
- sft FAR *s;
- /* Convert to fcb if necessary */
- lpFcb = ExtFcbToFcb(lpXfcb);
- /* Get the SFT block that contains the SFT */
- if((s = FcbGetSft(lpFcb -> fcb_sftno)) == (sft FAR *)-1)
- return FALSE;
- /* If this is not opened another error */
- if(s -> sft_count == 0)
- return FALSE;
- /* now just drop the count if a device, else */
- /* call file system handler */
- if(s -> sft_flags & SFT_FDEVICE)
- {
- s -> sft_count -= 1;
- return TRUE;
- }
- else
- {
- s -> sft_count -= 1;
- if(s -> sft_count > 0)
- return SUCCESS;
- else
- {
- /* change time and set file size */
- dos_setftime(s -> sft_status,
- (date FAR *)&lpFcb -> fcb_date,
- (time FAR *)&lpFcb -> fcb_time);
- dos_setfsize(s -> sft_status,
- lpFcb -> fcb_fsize);
- return dos_close(s -> sft_status) == SUCCESS;
- }
- }
- }
- BOOL FcbFindFirst(lpXfcb)
- xfcb FAR *lpXfcb;
- {
- BYTE FAR *lpOldDta;
- BYTE FAR *lpDir;
- COUNT nIdx, FcbDrive;
- psp FAR *lpPsp = MK_FP(cu_psp,0);
- /* First, move the dta to a local and change it around to match */
- /* our functions. */
- lpDir = (BYTE FAR *)dta;
- dta = (BYTE FAR *)&Dmatch;
- /* Next initialze local variables by moving them from the fcb */
- lpFcb = CommonFcbInit(lpXfcb, PriPathName, &FcbDrive);
- if(lpXfcb -> xfcb_flag == 0xff)
- {
- wAttr = lpXfcb -> xfcb_attrib;
- fbcopy(lpXfcb, lpDir, 7);
- lpDir += 7;
- }
- else
- wAttr = D_ALL;
- *lpDir++ = PriPathName[0] - 'A';
- if(dos_findfirst(wAttr, PriPathName) != SUCCESS)
- {
- dta = lpPsp -> ps_dta;
- return FALSE;
- }
- MoveDirInfo((dmatch FAR *)&Dmatch, (struct dirent FAR *)lpDir);
- lpFcb -> fcb_dirclst = Dmatch.dm_cluster;
- lpFcb -> fcb_diroff = Dmatch.dm_entry;
- dta = lpPsp -> ps_dta;
- return TRUE;
- }
- BOOL FcbFindNext(lpXfcb)
- xfcb FAR *lpXfcb;
- {
- BYTE FAR *lpOldDta;
- BYTE FAR *lpDir;
- COUNT nIdx, FcbDrive;
- psp FAR *lpPsp = MK_FP(cu_psp,0);
- /* First, move the dta to a local and change it around to match */
- /* our functions. */
- lpDir = (BYTE FAR *)dta;
- dta = (BYTE FAR *)&Dmatch;
- /* Next initialze local variables by moving them from the fcb */
- lpFcb = CommonFcbInit(lpXfcb, PriPathName, &FcbDrive);
- if((xfcb FAR *)lpFcb != lpXfcb)
- {
- wAttr = lpXfcb -> xfcb_attrib;
- fbcopy(lpXfcb, lpDir, 7);
- lpDir += 7;
- }
- else
- wAttr = D_ALL;
- /* Reconstrct the dirmatch structure from the fcb */
- *lpDir++ = FcbDrive;
- Dmatch.dm_drive = FcbDrive? FcbDrive - 1 : default_drive;
- fbcopy(lpFcb -> fcb_fname, (BYTE FAR *)Dmatch.dm_name_pat, FNAME_SIZE+FEXT_SIZE);
- upMem((BYTE FAR *)Dmatch.dm_name_pat, FNAME_SIZE+FEXT_SIZE);
- Dmatch.dm_attr_srch = wAttr;
- Dmatch.dm_entry = lpFcb -> fcb_diroff;
- Dmatch.dm_cluster = lpFcb -> fcb_dirclst;
- if(dos_findnext() != SUCCESS)
- {
- dta = lpPsp -> ps_dta;
- return FALSE;
- }
- MoveDirInfo((dmatch FAR *)&Dmatch, (struct dirent FAR *)lpDir);
- lpFcb -> fcb_dirclst = Dmatch.dm_cluster;
- lpFcb -> fcb_diroff = Dmatch.dm_entry;
- dta = lpPsp -> ps_dta;
- return TRUE;
- }
- #endif