home *** CD-ROM | disk | FTP | other *** search
- /****************************************************************************/
- /* MSDOS print spooler interface spool.c */
- /* */
- /* Mike Cole Digital Equipment Co. Ltd. 3 Jan 85 */
- /* based on PC/MSDOS Tips from Tom Jennings (indirectly). */
- /* */
- /* spool(filename) adds a 'filename' to print queue. */
- /* return 1 if couldn't queue */
- /* 0 if done */
- /* -1 if error */
- /* unspool(filename) deletes 'filename' from print queue. */
- /* return 0 if done */
- /* -1 if error */
- /* qspool(namelist) updates 'namelist' with names in the queue */
- /* (starting with the currently printing file. */
- /* This will NOT be in queue order. */
- /* return 0..10 as number of 'filenames' in queue. */
- /* */
- /* 'filename' char filename[13] as 'filename.sfx',0 */
- /* 'namelist' char namelist[10][13] each as 'filename.sfx',0 */
- /****************************************************************************/
- /* To access DOS' PRINT capabilities: */
- /* MOV AH,func */
- /* INT 2Fh */
- #define ADD 0x0000 /* AH = 0 adds the file specified by DS:DX to */
- /* the print queue. */
- /* DS:DX must point to valid opened FCB. */
- #define CAN 0x0100 /* AH = 1 cancels the file indicated by DS:DX. */
- /* DS:DX must point to an FCB, opened or unopened.*/
- /* The drive byte must not be 0. */
- /* Wildcards are restricted: ? is okay, * isn't. */
- #define QRY 0x0200 /* AH > 1 do nothing. */
- /****************************************************************************/
- /* Return with registers set as follows: */
- /* */
- /* DS,SI,DI,CX preserved, all others destroyed. */
- /* AH = number of files currently in queue. */
- /* AL = for AH=0, return 1 if queue was */
- /* full. For all other cases, return 0. */
- /* ES:BX = pointer to list of 10 entries in queue. */
- /* each entry is 40 bytes:- */
- /* 2 byte queue ordering pointer (ignored by us). */
- /* if 1st byte is oxFF, do next?? */
- /* else is offset of next entry. */
- /* 38 byte FCB. If the first byte of an FCB */
- /* FCB is 0xFF, that entry is unused. */
- /* ES:DX = pointer to currently printing */
- /* FCB. If the queue is empty, DX = -1. */
- /****************************************************************************/
- #define TRUE 1
- #define FALSE 0
- #define NULL 0
- #define OPENF 0x0F /*MSDOS Open file */
- #define CLOSEF 0x10 /*MSDOS Close file */
- #define GETDISK 0x19 /*MSDOS Current logged in drive */
- #define QENTRY 40 /*print queue entry size (fcb+2)*/
- #define QLASTENTRY 10*QENTRY /*print queue #entries in bytes*/
-
- struct regval{ unsigned int ax,bx,cx,dx,si,di,ds,es;};
-
- typedef struct fcb_t { /* NON-EXTENDED FCB */
- unsigned char f_dr; /* drive code */
- unsigned char f_name[8], /* name */
- f_ext[3]; /* extension */
- int f_block; /* current block (=128 records) */
- int f_recsz; /* record size in bytes (=1) */
- long f_size; /* file size in bytes (system) */
- unsigned int f_date; /* modification date (system) */
- unsigned int f_time; /* modification time (system) */
- char f_sys[8]; /* for system use */
- unsigned char f_rec; /* current record in block */
- unsigned long f_seek; /* random record position */
- } FCB_T, *FCB_PTR;
-
- static FCB_T mfcb_; /* local file control block */
- /****************************************************************************/
- spool(fn) /*trigger off spool print of output file 'fn'*/
- char *fn; /*return 1 if couldn't queue, 0 if done, -1 if error*/
- { struct regval srs,srd;
- FCB_PTR buildfcb();
-
- segread(&srs.si); /* get ds value */
- srs.ax=ADD;
- if((srs.dx=buildfcb(fn))==NULL)return -1;
- sysint(0x2F,&srs,&srd);
- bdos(CLOSEF,&srs.dx); /*ensure file closed*/
- if(srs.dx!=srd.dx)return srd.ax & 0xff; /*ok if queue ptr returned*/
- return -1; /*error, PRINT not installed*/
- }
- /****************************************************************************/
- unspool(fn) /*cancel spool print of output file 'fn'*/
- char *fn;
- { struct regval srs,srd;
- FCB_PTR buildfcb();
-
- segread(&srs.si); /* get ds value */
- srs.ax=CAN;
- if((srs.dx=buildfcb(fn))==NULL)return -1;
- sysint(0x2F,&srs,&srd);
- bdos(CLOSEF,&srs.dx); /*ensure file closed*/
- if(srs.dx!=srd.dx)return 0; /*ok if queue ptr returned*/
- return -1; /*error, PRINT not installed*/
- }
- /****************************************************************************/
-
- qspool(filelist) /*return number of printing files*/
- char filelist[10][13]; /*return queuelist (printing file first)*/
-
- { struct regval srs,srd;
- FCB_PTR buildfcb();
- FCB_T retfcb;
- int i;
- char *fp; setmem(filelist,130,0);
- segread(&srs.si); /* get ds value */
- srs.ax=QRY;
- srs.dx=0;
- sysint(0x2F,&srs,&srd);
- if(srs.dx==srd.dx)return -1; /*error, PRINT not installed*/
- if((int)srs.dx==-1)return 0; /*queue empty*/
- fp=srd.dx; /*start with current*/
- if(srd.ax>>8)for(i=0;i<10;i++){
- movblock(fp+2,srd.es,&retfcb,srs.ds,sizeof(retfcb));
- if(retfcb.f_dr!=0xff)asciiz(&filelist[i][0],retfcb.f_name);
- fp+=QENTRY;
- if(fp>=srd.bx+QLASTENTRY)fp=srd.bx;
- }
- return srd.ax>>8;
- }
-
-
- /****************************************************************************/
- FCB_PTR buildfcb(rs) /*Build an open FCB*/
- char rs[];
- {
- int i,j;
- char disk; /* disk specified in run string */
- setmem(&mfcb_,sizeof(mfcb_),0);
- mfcb_.f_dr=bdos(GETDISK,0)+1; /* default drive code */
- while (strlen(rs) != 0 && rs[0] == ' ') ++rs;
- if (strlen(rs) == 0)return NULL;
- if (rs[1] == ':' && strlen(rs) == 2)return NULL;
- if (rs[1] == ':') {
- disk = toupper(rs[0]) - '@';
- rs += 2;
- }
- else disk = 0;
- makefn(rs,mfcb_.f_name);
- if(disk)mfcb_.f_dr=disk+1; /* drive code */
- if(bdos(OPENF,&mfcb_))return &mfcb_; /* try open */
- return NULL; /*failed*/
- }
- /****************************************************************************/
- makefn(infn,opfn) /* ASCIZ -> expanded file name */
- char *infn;
- char *opfn;
- {
- int i, j, swe, swf;
- char temp[13];
- unsigned char c;
-
- strcpy(temp, " ");
- j = 0;
- swf = swe = TRUE;
- while (swf == TRUE) {
- c = *infn++;
- switch ( c ) {
- case '.' : swf = FALSE; break;
- case '*' : for (; j < 8; temp[j++] = '?'); break;
-
- case '\0': swf = swe = FALSE; break;
- default : if (j < 8) temp[j++] = toupper(c); break;
- }
- } /* while swf */
- j = 8;
- while (swe == TRUE) {
- switch ( c ) {
- case '.' : break;
- case '*' : for (; j < 11; temp[j++] = '?'); break;
- case '\0': swe = FALSE; break;
- default : if (j < 11) temp[j++] = toupper(c); break;
- }
- c = *infn++;
- } /* while swe */
- for(i = 0; i < 11;*opfn++ = temp[i++]);
- *opfn = '\0';
- } /* makefn() */
- /****************************************************************************/
- asciiz(fo,fi) /* convert to ASCIZ filename */
- char *fo,fi[];
- { int i, j;
- i = 0;
- while (fi[i] != ' ' && i < 8)
- *fo++ = fi[i++];
- *fo++ = '.';
- j = 8;
- while (fi[j] != ' ' && j < 11)
- *fo++ = fi[j++];
- *fo = '\0';
- }
- tracereg(tag,regs)
- char *tag;
- struct regval *regs;
- {
- printf("%s regdump ",tag);
- printf("ax=%04x bx=%04x cx=%04x dx=%04x si=%04x di=%04x ds=%04x es=%04x\n",
- regs->ax,regs->bx,regs->cx,regs->dx,regs->si,regs->di,regs->ds,regs->es);
- }
- tracedump(tag,area,cnt)
- unsigned char *tag;
- unsigned char area[];
- int cnt;
- {int i;
- printf("%s dump ",tag);
- for(i=0;i<cnt;printf("%02x",area[i++]));
- printf("\n");
- }
-