/*
 *			rawprt.exe  (Win32 application to do > PRN:)
 *					by SHIMA (July 1998)
 */

#include <stdio.h>
#include <io.h>
#include <fcntl.h>
#include <windows.h>
#include <winspool.h>

#define	BUF_LEN	0x1000

char printer_name[256];
unsigned char p_buf[BUF_LEN];
int p_len;

static HANDLE printer;

BOOL f_rawerr;
BOOL f_rawwait;

void Win32cPrtinterInit(char *s);
void Win32cPrtinterEnd(void);
void PrFlush(char *pr_buf, int pr_buf_len);

void main(int argc, char **argv)
{
	FILE *fp;
	int i;
	char *p = NULL;
	int ch;

	fp = stdin;
	setmode(fileno(fp), O_BINARY);
	fp->flags |= _F_BIN;

	for(i = 1; i < argc; i++){
		if(argv[i][0] != '-'){
			if((fp = fopen(argv[i], "rb")) == NULL){
				fprintf(stderr, "Cannot open %s.", argv[i]);
				exit(1);
			}
			break;
		}
		switch(argv[i][1]){
		  case 'p': p = argv[i]+2;
		  			break;
		}
	}
	if(isatty(fileno(fp))){
		fprintf(stderr, "Input device is a character device.");
		fprintf(stderr,
		"\n\nrawprt Ver.0.1: output data to printer (copy /b <file> PRN:)\n"
		"written by SHIMA(July 24, 1998)\n\n"
		"rawprt [-p<printer_name>] [<file>]\n"
		"default input : stdin\n"
		"default output: stdprn\n");
		exit(2);
	}
	Win32cPrtinterInit(p);
	while((ch=getc(fp)) != EOF){
		p_buf[p_len] = ch;
		if(++p_len >= BUF_LEN){
			PrFlush(p_buf, p_len);
			p_len = 0;
		}
	}
	PrFlush(p_buf, p_len);
	Win32cPrtinterEnd();
}

void AbortRawPrint(void)
{
	if(printer){
		AbortPrinter(printer);
		printer = NULL;
	}
	f_rawerr = TRUE;
}

void Win32cPrtinterInit(char *s)
{
	DOC_INFO_1 di;
	char *p;

	f_rawerr = FALSE;
	if (s == NULL) {	/* default printer */
		GetProfileString("windows", "device", "", printer_name, 256);
		if ( (p = strchr(printer_name, ',')) != NULL )
		    *p = '\0';
	} else
		strncpy(printer_name, s, 256);

    if (!OpenPrinter(printer_name, &printer, NULL)) {
		printer = NULL;
		fprintf(stderr,
			"OpenPrinter() failed for \042%s\042, error code = %d", 
			printer_name, GetLastError());
			AbortRawPrint();
			exit(3);
	}
	/* from here until ClosePrinter, should AbortPrinter on error */
	di.pDocName = "dviprt";
	di.pOutputFile = NULL;
	di.pDatatype = "RAW";
	if (!StartDocPrinter(printer, 1, (LPBYTE)&di)) {
		AbortRawPrint();
		fprintf(stderr, 
			"StartDocPrinter() failed for \042%s\042, error code = %d", 
			printer_name, GetLastError());
		exit(4);
    }
	return;
}

void Win32cPrtinterEnd(void)
{
	if (!EndDocPrinter(printer)) {
		AbortRawPrint();
		fprintf(stderr,
			"EndDocPrinter() failed for \042%s\042, error code = %d", 
			printer_name, GetLastError());
	}
    else if (!ClosePrinter(printer)) {
		fprintf(stderr,
			"CloseDocPrinter() failed for \042%s\042, error code = %d", 
			printer_name, GetLastError());
		AbortRawPrint();
	}
	printer = NULL;
}


void PrFlush(char *pr_buf, int pr_buf_len)
{
	DWORD written;

	if(!pr_buf_len)
		return;

	if (!WritePrinter(printer, (LPVOID)pr_buf, pr_buf_len, &written)) {
	    AbortPrinter(printer);
		fprintf(stderr,
			"WritePrinter() failed for \042%s\042, error code = %d", 
			printer_name, GetLastError());
		exit(5);
	}
	return;
}
