mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-25 09:24:19 +00:00
428 lines
12 KiB
C
428 lines
12 KiB
C
#include <portab.h>
|
||
#include "utildef.h"
|
||
#include "cpmfunc.h"
|
||
|
||
#define TAB_DEFAULT 8 /* default tab position */
|
||
|
||
struct _cmdtail /* command tail */
|
||
{
|
||
WORD gbl_sys; /* global system option */
|
||
WORD gbl_grp; /* global group option */
|
||
WORD gbl_tab; /* global tab option */
|
||
WORD lcl_sys[MAX_FILESPEC]; /* local system option */
|
||
WORD lcl_grp[MAX_FILESPEC]; /* local group option */
|
||
WORD lcl_tab[MAX_FILESPEC]; /* local tab option */
|
||
BYTE filespec[MAX_FILESPEC][FILESPEC_LEN];/* filespec list */
|
||
};
|
||
|
||
EXTERN VOID cpmerr();
|
||
EXTERN WORD ok_ver();
|
||
EXTERN VOID get_tail();
|
||
EXTERN VOID copy_ucase();
|
||
EXTERN WORD nextfcb();
|
||
EXTERN WORD fileopen();
|
||
EXTERN WORD readsect();
|
||
EXTERN VOID crlf();
|
||
EXTERN BYTE firstch(); /* return first non-white char */
|
||
EXTERN BYTE *tlex(); /* tlex returns a pointer */
|
||
EXTERN VOID putfname();
|
||
EXTERN VOID itoa();
|
||
|
||
BYTE *pmt00 = "Enter Filename: ";
|
||
BYTE *pmt01 = "Do you want to W(ait) or C(ancel) ? ";
|
||
BYTE *pmt02 = "Do you want to S(top printing), skip to the";
|
||
BYTE *pmt03 = "N(ext file), or R(esume printing this file) ? ";
|
||
|
||
BYTE *msg00 = "Printing file: ";
|
||
BYTE *msg01 = "Press SPACE BAR to stop ";
|
||
BYTE *msg02 = "Printer is being used by another console.";
|
||
BYTE *msg03 = "Printing is completed.";
|
||
BYTE *msg04 = " files printed.";
|
||
BYTE *msg05 = "Print cancelled.";
|
||
BYTE *err00 = "No files were specified on the command line.";
|
||
BYTE *err01 = "File Not Found.";
|
||
BYTE *err03 = "Invalid Command Option.";
|
||
BYTE *err04 = "Requires Concurrent CP/M-86 3.1$";
|
||
BYTE *err05 = "Could not find file: ";
|
||
BYTE *err06 = "Invalid file name: ";
|
||
BYTE *err07 = "Error while opening file: ";
|
||
BYTE *err08 = "Error while reading file: ";
|
||
BYTE *err09 = "Error while closing file: ";
|
||
BYTE *err10 = "A file password is required for file: ";
|
||
|
||
BYTE *index(); /* index returns pointer */
|
||
WORD ptail();
|
||
WORD set_opt();
|
||
|
||
VOID main()
|
||
{
|
||
BYTE buff[DMA_LEN]; /* file input buffer */
|
||
BYTE tail[DMA_LEN]; /* command tail buffer */
|
||
BYTE num_buff[6]; /* character buffer for numbers */
|
||
BYTE response[24]; /* user response buffer */
|
||
BYTE *dma; /* ptr to DMA buffer area */
|
||
BYTE ch; /* single char. response */
|
||
struct _cmdtail cmdtail; /* command tail structure */
|
||
REG WORD eod; /* end of data flag */
|
||
REG WORD i; /* loop control */
|
||
WORD op_code; /* option validation code */
|
||
WORD fsindex; /* filespec list index */
|
||
WORD findex; /* FCB array index */
|
||
WORD curr_user; /* current user number */
|
||
WORD nofile; /* no files flag */
|
||
WORD valid_file; /* filespec validation flag */
|
||
WORD completed; /* # files completed processing */
|
||
WORD attempted; /* # files attempted processing */
|
||
WORD col; /* output column counter */
|
||
WORD msg_len; /* prompt message length */
|
||
WORD open_err; /* open file error return code */
|
||
WORD bad_resp; /* bad user response flag */
|
||
UBYTE tail_len; /* length of command tail */
|
||
BYTE cur_fcb[FCB_LEN]; /* current FCB buffer */
|
||
BYTE wild_fcb[FCB_LEN]; /* filespec FCB buffer */
|
||
|
||
if( !ok_ver(BDOS_VER,OS_TYPE) ) /* version number check */
|
||
cpmerr( err04,-1 );
|
||
|
||
f_errmode( 0xff ); /* return BDOS errors */
|
||
|
||
c_delimit( NULL ); /* set console output */
|
||
/* string delimiter */
|
||
|
||
dma = f_dmaget(); /* get DMA ptr, byte 0 */
|
||
/* is length, get it */
|
||
tail_len = *dma++; /* then skip over it */
|
||
|
||
if( tail_len < 1 ) /* tail present ? */
|
||
cpmerr( err00,-1 );
|
||
else
|
||
copy_ucase( tail,dma,tail_len );
|
||
|
||
if( (op_code = ptail( tail,&cmdtail )) != 0 ) /* parse tail */
|
||
cpmerr( err03,-1 );
|
||
|
||
if( l_cattach() == 0x00ff ) /* if list device is */
|
||
{ /* in use, prompt user. */
|
||
c_writestr( msg02 ); /* the user may W(ait) */
|
||
crlf(); /* or C(ancel) */
|
||
get_tail( pmt01,response );
|
||
if( firstch(response) == 'W' )
|
||
l_attach();
|
||
else
|
||
cpmerr( msg05,-1 ); /* display cancel msg */
|
||
} /* and exit */
|
||
|
||
completed = attempted = 0; /* no files so far */
|
||
curr_user = f_usernum( 0xff ); /* get current user # */
|
||
fsindex = 0;
|
||
while( cmdtail.filespec[fsindex][0] != NULL )
|
||
{
|
||
f_usernum( cmdtail.lcl_grp[fsindex] );
|
||
nofile = 1;
|
||
|
||
cur_fcb[0] = 0xff; /* init to 0xff on first pass through */
|
||
|
||
while( (valid_file = nextfcb(cmdtail.filespec[fsindex],wild_fcb,
|
||
cur_fcb)) > -1 )
|
||
{
|
||
if( is_sysfile( cur_fcb ) == YES
|
||
&& cmdtail.lcl_sys[fsindex] == NO )
|
||
continue; /* skip to next file */
|
||
|
||
attempted++; /* attempt to process */
|
||
nofile = 0; /* another file */
|
||
cur_fcb[EX_FIELD] = 0x00; /* extent set for open */
|
||
cur_fcb[F6_FIELD] |= 0x80; /* open file read only */
|
||
/* mode */
|
||
if( (open_err = fileopen( cur_fcb )) != 0 )
|
||
{ /* error on open,print */
|
||
if( open_err != 7 ) /* message if not */
|
||
{ /* password error, */
|
||
crlf(); /* then skip to the */
|
||
cpmerr( err07,0 ); /* next file */
|
||
putfname( cur_fcb,0 );
|
||
}
|
||
continue;
|
||
}
|
||
|
||
put_header( cur_fcb,&cmdtail ); /* print file header */
|
||
/* on the console */
|
||
eod = 0;
|
||
cur_fcb[CR_FIELD] = 0x00; /* set CR field = 0 */
|
||
col = 0; /* set output col count */
|
||
|
||
while( !eod && (readsect( cur_fcb,buff ) == 0) )
|
||
{
|
||
|
||
for( i=0; i < SEC_LEN && !eod; i++ ) /* write sector */
|
||
{
|
||
if( buff[i] == 0x1a ) /* end of file */
|
||
{
|
||
eod = 1;
|
||
break;
|
||
}
|
||
if( cmdtail.lcl_tab[fsindex] != 0 ) /* expand tabs */
|
||
{
|
||
switch( buff[i] )
|
||
{
|
||
case 0x09 : do
|
||
{
|
||
l_write( ' ' );
|
||
col++;
|
||
}
|
||
while( col % cmdtail.lcl_tab[fsindex] );
|
||
break;
|
||
case 0x0a : l_write( buff[i] );
|
||
col = 0;
|
||
break;
|
||
default : l_write( buff[i] );
|
||
col++;
|
||
break;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
l_write( buff[i] );
|
||
col++;
|
||
}
|
||
|
||
if( c_stat() ) /* check to see if the */
|
||
{ /* user wants to */
|
||
ch = c_rawio( 0x00fd ); /* intervene */
|
||
|
||
if( ch == '\003' ) /* cntrol-c, absolute */
|
||
p_termcpm(); /* halt of print */
|
||
|
||
if( ch == SP ) /* user intervenes if */
|
||
{ /* he hits SPACE BAR */
|
||
|
||
c_write( CR ); /* clear prompt area */
|
||
msg_len = strlen( msg01 );
|
||
while( msg_len-- ) /* and display new */
|
||
c_write( SP ); /* prompt */
|
||
c_write( CR );
|
||
do
|
||
{
|
||
bad_resp = FALSE;
|
||
c_writestr( pmt02 );
|
||
crlf();
|
||
get_tail( pmt03,response );
|
||
switch( firstch( response ) )
|
||
{
|
||
case 'S' : l_write( FF );
|
||
p_termcpm();
|
||
break;
|
||
case 'N' : eod = 1;
|
||
--completed;
|
||
break;
|
||
case NULL :
|
||
case 'R' : c_writestr( msg01 );
|
||
break;
|
||
default : bad_resp = TRUE;
|
||
break;
|
||
}
|
||
}
|
||
while( bad_resp == TRUE );
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
completed++;
|
||
|
||
c_write( CR ); /* erase prompt */
|
||
msg_len = strlen( msg01 );
|
||
while( msg_len-- )
|
||
c_write( SP );
|
||
c_write( CR );
|
||
|
||
l_write( FF ); /* eject a page, next file */
|
||
/* begins on a new page */
|
||
|
||
if( (f_close(cur_fcb) & 0x00ff) == 0x00ff )
|
||
{
|
||
crlf();
|
||
cpmerr( err09,0 );
|
||
putfname( cur_fcb,0 );
|
||
}
|
||
|
||
}
|
||
|
||
if( nofile && ( valid_file != INVALID_FILE ) )
|
||
{
|
||
crlf();
|
||
cpmerr( err05,0 );
|
||
putfname( wild_fcb,0 );
|
||
}
|
||
|
||
fsindex++;
|
||
}
|
||
|
||
crlf(); /* display print completion */
|
||
c_writestr( msg03 ); /* message */
|
||
crlf();
|
||
itoa( completed,num_buff );
|
||
c_writestr( num_buff );
|
||
c_write( '/' );
|
||
itoa( attempted,num_buff );
|
||
c_writestr( num_buff );
|
||
c_writestr( msg04 );
|
||
|
||
f_usernum( curr_user ); /* reset current user */
|
||
|
||
f_errmode( 0 ); /* reset BDOS error mode */
|
||
|
||
l_detach(); /* detach list device */
|
||
}
|
||
|
||
WORD ptail( tail,t_struct )
|
||
BYTE *tail; /* command tail to parse */
|
||
struct _cmdtail *t_struct; /* struct. to hold parsed tail */
|
||
{
|
||
BYTE token[128]; /* cmd. line identifier */
|
||
BYTE *delim; /* string of delimiters */
|
||
BYTE *tptr; /* tail pointer */
|
||
WORD ret_code; /* return code */
|
||
WORD op_cnt; /* option count */
|
||
WORD fsindex; /* filespec list index */
|
||
struct _oplist oplist[5]; /* valid options list */
|
||
|
||
strcpy( oplist[0].opname,OP_TAB ); /* initialize options list */
|
||
oplist[0].max_num = 32767;
|
||
strcpy( oplist[1].opname,OP_SYSTEM );
|
||
oplist[1].max_num = 0;
|
||
strcpy( oplist[2].opname,OP_DIRECTORY );
|
||
oplist[2].max_num = 0;
|
||
strcpy( oplist[3].opname,OP_GROUP );
|
||
oplist[3].max_num = 15;
|
||
oplist[4].opname = NULL; /* sentinal */
|
||
oplist[4].max_num = 0;
|
||
|
||
t_struct->gbl_sys = NO; /* assume no system option */
|
||
t_struct->gbl_grp = f_usernum( 0x00ff );/* assume no system opt */
|
||
t_struct->gbl_tab = TAB_DEFAULT; /* default tab position */
|
||
tptr = tail;
|
||
fsindex = 0;
|
||
ret_code = 0;
|
||
op_cnt = 0;
|
||
delim = ",]";
|
||
while( firstch( tptr ) == '[' && ret_code == 0 )
|
||
{
|
||
tptr++; /* skip start symbol */
|
||
op_cnt++;
|
||
tptr = tlex( tptr,delim,token );
|
||
ret_code = set_opt( token,t_struct,fsindex,oplist,0 );
|
||
while( firstch( tptr ) == ',' && ret_code == 0 )
|
||
{
|
||
tptr++;
|
||
op_cnt++;
|
||
tptr = tlex( tptr,delim,token );
|
||
ret_code = set_opt( token,t_struct,fsindex,oplist,0 );
|
||
}
|
||
if( *(tptr+1) == '[' ) /* skip '][' condition */
|
||
tptr++;
|
||
}
|
||
if( op_cnt > 2 ) /* to many options given */
|
||
ret_code = -1;
|
||
|
||
if( firstch( tptr ) == ']' )
|
||
tptr++;
|
||
|
||
if( firstch( tptr ) == NULL ) /* no files specified on command */
|
||
cpmerr( err00,-1 ); /* line is an error */
|
||
|
||
while ( firstch( tptr ) != NULL && ret_code == 0 )
|
||
{
|
||
delim = "[, ";
|
||
tptr = tlex( tptr,delim,token );
|
||
t_struct->lcl_sys[fsindex] = t_struct->gbl_sys;
|
||
t_struct->lcl_grp[fsindex] = t_struct->gbl_grp;
|
||
t_struct->lcl_tab[fsindex] = t_struct->gbl_tab;
|
||
strcpy( t_struct->filespec[fsindex],token );
|
||
op_cnt = 0;
|
||
while( firstch( tptr ) == '[' && ret_code == 0 )
|
||
{
|
||
tptr++;
|
||
op_cnt++;
|
||
delim = ",]";
|
||
tptr = tlex( tptr,delim,token );
|
||
ret_code = set_opt( token,t_struct,fsindex,oplist,1 );
|
||
while( firstch( tptr ) == ',' && ret_code == 0 )
|
||
{
|
||
tptr++;
|
||
op_cnt++;
|
||
tptr = tlex( tptr,delim,token );
|
||
ret_code = set_opt( token,t_struct,fsindex,oplist,1 );
|
||
}
|
||
if( *(tptr+1) == '[' )
|
||
tptr++;
|
||
}
|
||
if( op_cnt > 2 ) /* too many options */
|
||
ret_code = -1;
|
||
|
||
if( firstch( tptr ) == ']' )
|
||
tptr++; /* skip delimiter */
|
||
if( firstch( tptr ) == ',' )
|
||
tptr++;
|
||
|
||
fsindex++;
|
||
}
|
||
t_struct->filespec[fsindex][0] = NULL; /* end filespec list */
|
||
return( ret_code );
|
||
}
|
||
|
||
WORD set_opt( token,t_ptr,fsindex,oplist,type )
|
||
BYTE *token;
|
||
struct _cmdtail *t_ptr;
|
||
WORD fsindex;
|
||
struct _oplist *oplist;
|
||
WORD type;
|
||
{
|
||
WORD ret_code;
|
||
|
||
if( (ret_code = valid( token,oplist )) == 0 )
|
||
{
|
||
switch( (WORD)token[0] )
|
||
{
|
||
case 'S' : if( type == 0 )
|
||
t_ptr->gbl_sys = YES;
|
||
else
|
||
t_ptr->lcl_sys[fsindex] = YES;
|
||
break;
|
||
case 'D' : if( type == 0 )
|
||
t_ptr->gbl_sys = NO;
|
||
else
|
||
t_ptr->lcl_sys[fsindex] = NO;
|
||
break;
|
||
case 'G' : if( type == 0 )
|
||
t_ptr->gbl_grp = get_num(token,t_ptr->gbl_grp);
|
||
else
|
||
t_ptr->lcl_grp[fsindex] = get_num( token,
|
||
t_ptr->lcl_grp[fsindex] );
|
||
break;
|
||
case 'T' : if( type == 0 )
|
||
t_ptr->gbl_tab = get_num(token,TAB_DEFAULT);
|
||
else
|
||
t_ptr->lcl_tab[fsindex] = get_num(token,
|
||
t_ptr->lcl_tab[fsindex] );
|
||
break;
|
||
default : break;
|
||
}
|
||
}
|
||
return( ret_code );
|
||
}
|
||
|
||
VOID put_header( cur_fcb,cmdtail )
|
||
BYTE cur_fcb[];
|
||
struct _cmdtail *cmdtail;
|
||
{
|
||
WORD findex;
|
||
|
||
crlf(); /* display user header */
|
||
c_writestr( msg00 ); /* on console */
|
||
putfname( cur_fcb,0 );
|
||
crlf();
|
||
c_writestr( msg01 );
|
||
|
||
}
|
||
|