Files
Digital-Research-Source-Code/CPM OPERATING SYSTEMS/CPM 86/CONCURRENT/CCPM-86 3.1 SOURCE/D6/SQPRINT.C
Sepp J Morris 31738079c4 Upload
Digital Research
2020-11-06 18:50:37 +01:00

428 lines
12 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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 );
}