📄 dosfns.c
字号:
/****************************************************************/
/* */
/* dosfns.c */
/* */
/* DOS functions */
/* */
/* 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"
#ifdef VERSION_STRINGS
static BYTE *dosfnsRcsId = "$Header: C:/dos-c/src/fs/dosfns.c_v 1.9 04 Jan 1998 23:14:38 patv $";
#endif
/* $Logfile: C:/dos-c/src/fs/dosfns.c_v $ */
/* $Log: C:/dos-c/src/fs/dosfns.c_v $
*
* Rev 1.9 04 Jan 1998 23:14:38 patv
* Changed Log for strip utility
*
* Rev 1.8 03 Jan 1998 8:36:04 patv
* Converted data area to SDA format
*
* Rev 1.7 22 Jan 1997 12:59:56 patv
* pre-0.92 bug fixes
*
* Rev 1.6 16 Jan 1997 12:46:32 patv
* pre-Release 0.92 feature additions
*
* Rev 1.5 29 May 1996 21:15:20 patv
* bug fixes for v0.91a
*
* Rev 1.4 19 Feb 1996 3:20:08 patv
* Added NLS, int2f and config.sys processing
*
* Rev 1.2 01 Sep 1995 17:48:48 patv
* First GPL release.
*
* Rev 1.1 30 Jul 1995 20:50:24 patv
* Eliminated version strings in ipl
*
* Rev 1.0 02 Jul 1995 8:04:20 patv
* Initial revision.
*/
/* $EndLog$ */
#include "globals.h"
#ifdef PROTO
BOOL check_break(VOID);
sft FAR *get_sft(COUNT);
WORD get_free_hndl(VOID);
sft FAR *get_free_sft(WORD FAR *);
BYTE FAR *get_root(BYTE FAR *);
BOOL cmatch(COUNT, COUNT, COUNT);
BOOL fnmatch(BYTE FAR *, BYTE FAR *, COUNT, COUNT);
#else
BOOL check_break();
sft FAR *get_sft();
WORD get_free_hndl();
sft FAR *get_free_sft();
BYTE FAR *get_root();
BOOL cmatch();
BOOL fnmatch();
#endif
BOOL
check_break (void)
{
if(break_ena && con_break())
{
handle_break();
/* shouldn't return, but in case... */
return TRUE;
}
else
return FALSE;
}
sft FAR *get_sft(hndl)
COUNT hndl;
{
psp FAR *p = MK_FP(cu_psp,0);
WORD sys_idx;
sfttbl FAR *sp;
if (hndl >= p -> ps_maxfiles)
return (sft FAR *)-1;
/* Get the SFT block that contains the SFT */
if (p -> ps_filetab[hndl] == 0xff)
return (sft FAR *)-1;
sys_idx = p -> ps_filetab[hndl];
for(sp = sfthead; sp != (sfttbl FAR *)-1; sp = sp -> sftt_next)
{
if(sys_idx < sp -> sftt_count)
break;
else
sys_idx -= sp -> sftt_count;
}
/* If not found, return an error */
if(sp == (sfttbl FAR *)-1)
return (sft FAR *)-1;
/* finally, point to the right entry */
return (sft FAR *)&(sp -> sftt_table[sys_idx]);
}
UCOUNT
DosRead (COUNT hndl, UCOUNT n, BYTE FAR *bp, COUNT FAR *err)
{
sft FAR *s;
WORD sys_idx;
sfttbl FAR *sp;
UCOUNT ReadCount;
/* Test that the handle is valid */
if(hndl < 0)
{
*err = DE_INVLDHNDL;
return 0;
}
/* Get the SFT block that contains the SFT */
if((s = get_sft(hndl)) == (sft FAR *)-1)
{
*err = DE_INVLDHNDL;
return 0;
}
/* If not open or write permission - exit */
if(s -> sft_count == 0 || (s -> sft_mode & SFT_MWRITE))
{
*err = DE_INVLDACC;
return 0;
}
/* Do a device read if device */
if(s -> sft_flags & SFT_FDEVICE)
{
request rq;
/* First test for eof and exit */
/* immediately if it is */
if(!(s -> sft_flags & SFT_FEOF) || (s -> sft_flags & SFT_FNUL))
{
s -> sft_flags &= ~SFT_FEOF;
*err = SUCCESS;
return 0;
}
/* Now handle raw and cooked modes */
if(s -> sft_flags & SFT_FBINARY)
{
rq.r_length = sizeof(request);
rq.r_command = C_INPUT;
rq.r_count = n;
rq.r_trans = (BYTE FAR *)bp;
rq.r_status = 0;
execrh((request FAR *)&rq, s -> sft_dev);
if(rq.r_status & S_ERROR)
{
REG i;
BYTE buff[FNAME_SIZE+1];
fbcopy(s -> sft_name, (BYTE FAR *)buff, FNAME_SIZE);
buff[FNAME_SIZE+1] = 0;
for(i = FNAME_SIZE; i > 0; i--)
if(buff[i] == ' ')
buff[i] = 0;
else
break;
char_error(&rq, buff);
}
else
{
*err = SUCCESS;
return rq.r_count;
}
}
else if(s -> sft_flags & SFT_FSTDIN)
{
if(!check_break())
{
kb_buf.kb_size = LINESIZE - 1;
kb_buf.kb_count = 0;
sti((keyboard FAR *)&kb_buf);
fbcopy((BYTE FAR *)kb_buf.kb_buf, bp, kb_buf.kb_count);
*err = SUCCESS;
return kb_buf.kb_count;
}
else
{
*err = SUCCESS;
return 0;
}
}
else
{
if(!check_break())
{
*bp = _sti();
*err = SUCCESS;
return 1;
}
else
{
*err = SUCCESS;
return 0;
}
}
}
else /* a block read */
{
if(!check_break())
{
COUNT rc;
ReadCount = rdwrblock(s -> sft_status, bp, n, XFR_READ, &rc);
if(rc != SUCCESS)
{
*err = rc;
return 0;
}
else
{
*err = SUCCESS;
return ReadCount;
}
}
else
{
*err = SUCCESS;
return 0;
}
}
*err = SUCCESS;
return 0;
}
UCOUNT
DosWrite (COUNT hndl, UCOUNT n, BYTE FAR *bp, COUNT FAR *err)
{
sft FAR *s;
WORD sys_idx;
sfttbl FAR *sp;
UCOUNT ReadCount;
/* Test that the handle is valid */
if(hndl < 0)
{
*err = DE_INVLDHNDL;
return 0;
}
/* Get the SFT block that contains the SFT */
if((s = get_sft(hndl)) == (sft FAR *)-1)
{
*err = DE_INVLDHNDL;
return 0;
}
/* If this is not opened and it's not a write */
/* another error */
if(s -> sft_count == 0 ||
(!(s -> sft_mode & SFT_MWRITE) && !(s -> sft_mode & SFT_MRDWR)))
{
*err = DE_ACCESS;
return 0;
}
/* Do a device write if device */
if(s -> sft_flags & SFT_FDEVICE)
{
request rq;
/* set to no EOF */
s -> sft_flags &= ~SFT_FEOF;
/* if null just report full transfer */
if(s -> sft_flags & SFT_FNUL)
{
*err = SUCCESS;
return n;
}
/* Now handle raw and cooked modes */
if(s -> sft_flags & SFT_FBINARY)
{
rq.r_length = sizeof(request);
rq.r_command = C_OUTPUT;
rq.r_count = n;
rq.r_trans = (BYTE FAR *)bp;
rq.r_status = 0;
execrh((request FAR *)&rq, s -> sft_dev);
if(rq.r_status & S_ERROR)
{
REG i;
BYTE buff[FNAME_SIZE+1];
fbcopy(s -> sft_name, (BYTE FAR *)buff, FNAME_SIZE);
buff[FNAME_SIZE+1] = 0;
for(i = FNAME_SIZE; i > 0; i--)
if(buff[i] == ' ')
buff[i] = 0;
else
break;
char_error(&rq, buff);
}
else
{
*err = SUCCESS;
return rq.r_count;
}
}
else
{
REG c, cnt = n, xfer = 0;
while(cnt-- && (*bp != CTL_Z) && !check_break())
{
rq.r_length = sizeof(request);
rq.r_command = C_OUTPUT;
rq.r_count = 1;
rq.r_trans = (BYTE FAR *)bp++;
rq.r_status = 0;
execrh((request FAR *)&rq, s -> sft_dev);
if(rq.r_status & S_ERROR)
{
REG i;
BYTE buff[FNAME_SIZE+1];
fbcopy(s -> sft_name, (BYTE FAR *)buff, FNAME_SIZE);
buff[FNAME_SIZE+1] = 0;
for(i = FNAME_SIZE; i > 0; i--)
if(buff[i] == ' ')
buff[i] = 0;
else
break;
char_error(&rq, buff);
}
++xfer;
}
*err = SUCCESS;
return xfer;
}
}
else /* a block write */
{
if(!check_break())
{
COUNT rc;
ReadCount = rdwrblock(s -> sft_status, bp, n, XFR_WRITE, &rc);
if(rc < SUCCESS)
{
*err = rc;
return 0;
}
else
{
*err = SUCCESS;
return ReadCount;
}
}
else
{
*err = SUCCESS;
return 0;
}
}
*err = SUCCESS;
return 0;
}
COUNT
DosSeek (COUNT hndl, LONG new_pos, COUNT mode, ULONG *set_pos)
{
sft FAR *s;
/* Test for invalid mode */
if(mode < 0 || mode > 2)
return DE_INVLDFUNC;
/* Test that the handle is valid */
if(hndl < 0)
return DE_INVLDHNDL;
/* Get the SFT block that contains the SFT */
if((s = get_sft(hndl)) == (sft FAR *)-1)
return DE_INVLDHNDL;
/* Do special return for character devices */
if(s -> sft_flags & SFT_FDEVICE)
{
*set_pos = 0l;
return SUCCESS;
}
else
{
*set_pos = dos_lseek(s -> sft_status, new_pos, mode);
if((LONG)*set_pos < 0)
return (int)*set_pos;
else
return SUCCESS;
}
}
static WORD
get_free_hndl (void)
{
psp FAR *p = MK_FP(cu_psp,0);
WORD hndl;
for(hndl = 0; hndl < p -> ps_maxfiles; hndl++)
{
if(p -> ps_filetab[hndl] == 0xff)
return hndl;
}
return 0xff;
}
static sft FAR *get_free_sft(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;
}
static BYTE FAR *
get_root (BYTE FAR *fname)
{
BYTE FAR *froot;
REG WORD length;
/* find the end */
for(length = 0, froot = fname; !froot != '\0'; ++froot)
++length;
/* now back up to first path seperator or start */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -