Knowledge Base Nr: 00091 printfile.cpp - http://www.swe-kaiser.de

Downloads:

Linux: Druckt eine Datei und gibt Ergebniss aus. Prüft Druckerstatus vor dem Drucken
und verhindert im Gegensatz zu 'cp' das Blockieren.wenn der Drucker nicht bereit ist.

  
//usage: %s <dateiname|-d> <dev>
//beim aufruf mit -d statt dateiname werden die portwerte zyklisch angezeigt
//bauen: g++ printfile.cpp -o printfile

//ACHTUNG: unbedingt beachten: root-Rechte vergeben!
// - chmod 6777 printfile
// - chown root.root printfile

//ACHTUNG: die portaddressen und die zurückgelesenen werte unterscheiden sich von rechner zu rechner
// und sind zudem noch druckerabhängig!

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/io.h>
#include <sys/types.h>

bool g_bShowStatus = false;

int getPrinterStatusParallel()
{
const int IOBASE = 0x378; //3bc,378,278
const unsigned char DRUCKER_OK = 0xdf; //alles ok

int nErr = ioperm(IOBASE, 10, 1);
if (nErr)
{
printf("\nError: ioperm(0x%04X): %d %s\n", IOBASE, errno, strerror(errno));
return nErr; //ist -1
}

unsigned char uc1,uc2, uc3, uc4;
uc1 = inb(IOBASE+1);

if (g_bShowStatus) //for debugging
{
while (1) //endlos status anzeigen
{
uc1 = inb(IOBASE+0);
uc2 = inb(IOBASE+1);
uc3 = inb(IOBASE+2);
uc4 = inb(IOBASE+3);
printf("\ndruckerstatus parallel(0x%04x): 0x%02x 0x%02x 0x%02x 0x%02x\n"
, IOBASE, uc1, uc2, uc3, uc4);
fflush(stdout);
sleep(1);
}
}

if (uc1 != DRUCKER_OK)
return 0;
else
return 1;
}

int getPrinterStatusSeriell()
{
const int IOBASE = 0x2f8; //3f8,2f8,3e8,2e8
const unsigned char DRUCKER_OK = 0xa0; //alles ok???

//berechtigung freischalten
int nErr = ioperm(IOBASE, 8, 1);
if (nErr)
{
printf("\nError: ioperm(0x%04X): %d %s\n", IOBASE, errno, strerror(errno));
return nErr; //ist -1
}

unsigned char uc1,uc2, uc3, uc4, uc5, uc6, uc7, uc8;
uc1 = inb(IOBASE); //f.e. 0x3f8
uc7 = inb(IOBASE+6); //f.e. 0x3fe

if (g_bShowStatus) //for debugging
{
while (1) //endlos status anzeigen
{
uc1 = inb(IOBASE+0);
uc2 = inb(IOBASE+1);
uc3 = inb(IOBASE+2);
uc4 = inb(IOBASE+3);
uc5 = inb(IOBASE+4);
uc6 = inb(IOBASE+5);
uc7 = inb(IOBASE+6);
uc8 = inb(IOBASE+7);
printf("\ndruckerstatus seriell(0x%04x): 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x"
, IOBASE, uc1, uc2, uc3, uc4, uc5, uc6, uc7, uc8);

fflush(stdout);
sleep(1);
}
}

if (((uc7 & DRUCKER_OK) == DRUCKER_OK) && (uc1 != 0))
return 1;
else
return 0;
}

void my_exit(int nErr, const char* lpszText)
{
char szValue[200];

printf("%d\n%s\n", nErr, lpszText);
exit(nErr);
}

// Kommandozeilenparameter: siehe Erklaerungstext
int main(int argc, char *argv[])
{
char szMsg[200];

if (argc != 3)
{
sprintf(szMsg, "Aufruf falsch - usage: %s <dateiname|-d> <dev>", argv[0]);
my_exit(-1, szMsg);
}

if (strcmp(argv[1], "-d") == 0) //endlos status anzeigen in getPrinterStatusXXX()
{
g_bShowStatus = true;
}
else
{
FILE* fp = fopen(argv[1], "r");
if (!fp)
{
sprintf(szMsg, "Error: Datei <%s> kann nicht geöffnet werden -> %d %s", argv[1], errno, strerror(errno));
my_exit(-2, szMsg);
}
}

FILE* pr = fopen(argv[2], "w");
if (!pr)
{
sprintf(szMsg, "Error: drucker <%s> kann nicht geöffnet werden -> %d %s", argv[2], errno, strerror(errno));
my_exit(-30, szMsg);
}

int nStatus = -1;
char* pPrn = "";
if (strstr(argv[2], "tty")) //rs232 oder centronics
{
pPrn = "seriell";
nStatus = getPrinterStatusSeriell();
}
else
{
pPrn = "parallel";
nStatus = getPrinterStatusParallel();
}

if (nStatus < 0)
{
sprintf(szMsg, "Error: druckerstatus(%s) <%s> kann nicht abgefragt werden -> %d %s", pPrn, argv[2], errno, strerror(errno));
my_exit(-31, szMsg);
}
else if (nStatus == 0)
{
sprintf(szMsg, "Error: drucker(%s) <%s> nicht bereit -> %d %s", pPrn, argv[2], errno, strerror(errno));
my_exit(-32, szMsg);
}

while (!feof(fp))
{
const int MAXBUFFER = 200;
unsigned char cBuffer[MAXBUFFER+1] = {0};

int n = fread(&cBuffer, 1, MAXBUFFER, fp);
if (ferror(fp))
{
sprintf(szMsg, "Error: beim lesen von datei <%s> -> %d %s", argv[1], errno, strerror(errno));
my_exit(-4, szMsg);
}

if (n>0)
{
fwrite(&cBuffer, 1, n, pr);
if (ferror(pr))
{
sprintf(szMsg, "Error: beim schreiben von <%s> -> %d %s", argv[2], errno, strerror(errno));
my_exit(-5, szMsg);
}
}
}

fclose(fp);
fclose(pr);

sprintf(szMsg, "OK! gedruckt: file: <%s> device: <%s>", argv[1], argv[2]);
my_exit(0, szMsg);

return 0; //never reached!
}