home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: OtherApp
/
OtherApp.zip
/
PSFAX2.ZIP
/
psfax2
/
psfax2.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-10-16
|
22KB
|
804 lines
/* psfax2.c */
/*---------------------------------------------------------------------------*/
/* This file is part of PSFax/2. */
/* */
/* Written By: Gary L. Hennigan */
/* */
/* This code can modified as much as you like provided you follow the */
/* guidelines as described in the file install.doc which you should have */
/* received with this file. If you did not please notify the author for a */
/* copy of this file via Internet email. The address is: */
/* ghenniga@NMSU.Edu */
/*---------------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "psfax2.h"
/**Global variable(s). **/
char cGlobResp[MAXRESPLEN];
int main(int argc, char **argv)
{
/**Local functions. **/
void vMemCheck( void * );
void vCleanExit( char *, char *, int, int );
int iPageCount( char * );
ULONG ulOpenPort(char *, HFILE *);
ULONG ulClosePort( HFILE );
int iPortGetSet( HFILE, DCBINFO * );
int iPortInit( HFILE, DCBINFO * );
int iModemInit( HFILE, DCBINFO * );
int iModemDial( HFILE, char *, DCBINFO *, int );
int iFaxInit( HFILE , DCBINFO *, int, int, int, int );
int iFaxSendPage( HFILE, DCBINFO *, FILE *, int );
int iFaxInterrupt( HFILE, DCBINFO * );
/**Local variables. **/
FILE *fp;
int i1, iTemp, iPageCnt, iPageStat;
char *cTemp, *cRecipPhone, *cSendPhone, *cRecipName, *cSendName;
char *cPSFileName[MAXPSFILES], *cTempDir, *cFaxDir, *cFaxCnfFile;
char cBuff[CCHMAXPATH], cBuff2[2*CCHMAXPATH], cCoverName[CCHMAXPATH];
char cPortID[6];
HFILE hTTY;
DCBINFO dcbCom;
/**Initialized local variables. **/
BOOL bRecipPhone=FALSE, bCover=FALSE, bSendPhone=FALSE;
BOOL bRecipName=FALSE, bSendName=FALSE, bCQuote=FALSE;
int iNumPSFiles=0, iWait=60, iRedial=5;
/*-------------------------------End Declarations---------------------------*/
/**If no arguments were given print out help information. **/
if( argc <= 1 )
{
printf("usage: psfax2 -p <rnum> -c -s <sname> -S <snum> -r <rname> ");
printf("[psfile]\n");
printf("where:\n(required)\n");
printf("\trnum - fax phone number of recipient\n");
printf("(optional cover sheet)\n");
printf("\t-c - use the predefined cover sheet\n");
printf("\tsnam - the sender's name\n");
printf("\tsnum - the sender's return fax phone number\n");
printf("\trname - the recipient's name\n");
printf("\t[psfile1] - the name of the postscript file ");
printf("to send\n\n");
printf("example:\n psfax2 -p1-505-555-1234 -c -s \"jay ");
printf("doe\" -S1-202-555-4321 -r \"jan doe\" psout.ps\n");
exit(0);
}
/**Determine the location of the configuration file. **/
cTemp = getenv("FAXPATH");
if(!cTemp)
{
printf("You must set the environment variable FAXPATH to point to");
printf(" the directory\nwhich contains the file psfax2.cnf\n");
exit(-1);
}
cFaxDir = (char *)malloc((strlen(cTemp)+2)*sizeof(char));
vMemCheck(cFaxDir);
strcpy(cFaxDir,cTemp);
if(cFaxDir[strlen(cTemp)] != '\\')
{
cFaxDir[strlen(cTemp)] = '\\';
cFaxDir[strlen(cTemp)+1] = '\000';
}
cFaxCnfFile = (char *)malloc((strlen(cFaxDir)+12)*sizeof(char));
vMemCheck(cFaxCnfFile);
strcpy(cFaxCnfFile,cFaxDir);
strcat(cFaxCnfFile,"psfax2.cnf");
/**If it exists, open the configuration file. **/
fp=fopen(cFaxCnfFile,"r");
if(!fp)
{
printf("The configuration file \"%s\" could not be found!\n",
cFaxCnfFile);
exit(-1);
}
fscanf(fp, "%s", cPortID);
strcpy(cCoverName,cFaxDir);
fscanf(fp, "%s", &cCoverName[strlen(cCoverName)]);
fscanf(fp, "%d", &iWait);
fscanf(fp, "%d", &iRedial);
fclose(fp);
free(cFaxCnfFile);
free(cFaxDir);
/**Parse the command line. **/
for( i1=1; i1 < argc; i1++ )
{
cTemp = strchr(argv[i1],'-');
if( cTemp )
{
switch(cTemp[1])
{
/** Recipient's phone number. **/
case 'p':
if(cTemp[2])
{
cRecipPhone = (char *)malloc((strlen(&cTemp[2])+1)*
sizeof(char));
vMemCheck(cRecipPhone);
strcpy(cRecipPhone,&cTemp[2]);
}
else
{
cRecipPhone = (char *)malloc((strlen(argv[i1+1])+1)*
sizeof(char));
vMemCheck(cRecipPhone);
strcpy(cRecipPhone,argv[i1+1]);
i1++;
}
bRecipPhone=TRUE;
break;
/** Cover page flag. **/
case 'c':
bCover = TRUE;
break;
/** Sender's phone number. **/
case 'S':
if(cTemp[2])
{
cSendPhone = (char *)malloc((strlen(&cTemp[2])+1)*
sizeof(char));
vMemCheck(cSendPhone);
strcpy(cSendPhone,&cTemp[2]);
}
else
{
cSendPhone = (char *)malloc((strlen(argv[i1+1])+1)*
sizeof(char));
vMemCheck(cSendPhone);
strcpy(cSendPhone,argv[i1+1]);
i1++;
}
bSendPhone=TRUE;
break;
/** Recipient's name. **/
case 'r':
if(cTemp[2])
{
/** Multiple word and/or quoted name. **/
if(cTemp[2] == '\"'|| cTemp[2] == '\'')
{
iTemp = strlen(&cTemp[3]);
if(cTemp[iTemp+2] == '\"' || cTemp[iTemp+2] == '\'')
{
cTemp[iTemp+2] = 0x00;
iTemp--;
bCQuote = TRUE;
}
cRecipName = (char *)malloc((iTemp+1)*
sizeof(char));
vMemCheck(cRecipName);
strcpy(cRecipName,&cTemp[3]);
while(bCQuote == FALSE)
{
i1++;
iTemp = strlen(argv[i1]);
if(argv[i1][iTemp-1] == '\"' ||
argv[i1][iTemp-1] == '\'')
{
argv[i1][iTemp-1] = 0x00;
bCQuote = TRUE;
iTemp--;
}
cRecipName = (char *)realloc(cRecipName,
(strlen(cRecipName)+
iTemp+2)*
sizeof(char));
vMemCheck(cRecipName);
strcat(cRecipName," ");
strcat(cRecipName,argv[i1]);
}
}
/** Single word name, no quotes. **/
else
{
cRecipName = (char *)malloc((strlen(&cTemp[2])+1)*
sizeof(char));
vMemCheck(cRecipName);
strcpy(cRecipName,&cTemp[2]);
}
}
/** Space between paramater and argument. **/
else
{
/** Multiple word name. **/
if(argv[i1+1][0] == '\"' || argv[i1+1][0] == '\'')
{
cTemp = &argv[i1+1][1];
iTemp = strlen(cTemp);
if(cTemp[iTemp-1] == '\"' || cTemp[iTemp-1] == '\'')
{
cTemp[iTemp-1] = 0x00;
iTemp--;
bCQuote = TRUE;
}
cRecipName = (char *)malloc((iTemp+1)*
sizeof(char));
vMemCheck(cRecipName);
strcpy(cRecipName,cTemp);
while(bCQuote == FALSE)
{
i1++;
iTemp = strlen(argv[i1+1]);
if(argv[i1+1][iTemp-1] == '\"' ||
argv[i1+1][iTemp-1] == '\'')
{
argv[i1+1][iTemp-1] = 0x00;
bCQuote = TRUE;
iTemp--;
}
cRecipName = (char *)realloc(cRecipName,
(strlen(cRecipName)+
iTemp+2)*
sizeof(char));
vMemCheck(cRecipName);
strcat(cRecipName," ");
strcat(cRecipName,argv[i1+1]);
}
i1++;
}
/** Single word name. **/
else
{
i1++;
cRecipName = (char *)malloc((strlen(argv[i1])+1)*
sizeof(char));
vMemCheck(cRecipName);
strcpy(cRecipName,argv[i1]);
}
}
bCQuote=FALSE;
bRecipName=TRUE;
break; /* Recipient's Name */
/** Sender's name. **/
case 's':
if(cTemp[2])
{
/** Multiple word and/or quoted name. **/
if(cTemp[2] == '\"'|| cTemp[2] == '\'')
{
iTemp = strlen(&cTemp[3]);
if(cTemp[iTemp+2] == '\"' || cTemp[iTemp+2] == '\'')
{
cTemp[iTemp+2] = 0x00;
iTemp--;
bCQuote = TRUE;
}
cSendName = (char *)malloc((iTemp+1)*
sizeof(char));
vMemCheck(cSendName);
strcpy(cSendName,&cTemp[3]);
while(bCQuote == FALSE)
{
i1++;
iTemp = strlen(argv[i1]);
if(argv[i1][iTemp-1] == '\"' ||
argv[i1][iTemp-1] == '\'')
{
argv[i1][iTemp-1] = 0x00;
bCQuote = TRUE;
iTemp--;
}
cSendName = (char *)realloc(cSendName,
(strlen(cSendName)+
iTemp+2)*
sizeof(char));
vMemCheck(cSendName);
strcat(cSendName," ");
strcat(cSendName,argv[i1]);
}
}
/** Single word name, no quotes. **/
else
{
cSendName = (char *)malloc((strlen(&cTemp[2])+1)*
sizeof(char));
vMemCheck(cSendName);
strcpy(cSendName,&cTemp[2]);
}
}
/** Space between paramater and argument. **/
else
{
/** Multiple word name. **/
if(argv[i1+1][0] == '\"' || argv[i1+1][0] == '\'')
{
cTemp = &argv[i1+1][1];
iTemp = strlen(cTemp);
if(cTemp[iTemp-1] == '\"' || cTemp[iTemp-1] == '\'')
{
cTemp[iTemp-1] = 0x00;
iTemp--;
bCQuote = TRUE;
}
cSendName = (char *)malloc((iTemp+1)*
sizeof(char));
vMemCheck(cSendName);
strcpy(cSendName,cTemp);
while(bCQuote == FALSE)
{
i1++;
iTemp = strlen(argv[i1+1]);
if(argv[i1+1][iTemp-1] == '\"' ||
argv[i1+1][iTemp-1] == '\'')
{
argv[i1+1][iTemp-1] = 0x00;
bCQuote = TRUE;
iTemp--;
}
cSendName = (char *)realloc(cSendName,
(strlen(cSendName)+
iTemp+2)*
sizeof(char));
vMemCheck(cSendName);
strcat(cSendName," ");
strcat(cSendName,argv[i1+1]);
}
i1++;
}
/** Single word name. **/
else
{
i1++;
cSendName = (char *)malloc((strlen(argv[i1])+1)*
sizeof(char));
vMemCheck(cSendName);
strcpy(cSendName,argv[i1]);
}
}
bCQuote=FALSE;
bSendName=TRUE;
break; /* Sender Name */
default:
printf("Unknown option %s!\n", argv[i1]);
break;
} /* end switch cTemp[1] */
} /* endif cTemp */
/** Anything without a "-" is considered a postscript file name. **/
else
{
if(iNumPSFiles < MAXPSFILES)
{
cPSFileName[iNumPSFiles] = (char *)malloc((strlen(argv[i1])+1)*
sizeof(char));
strcpy(cPSFileName[iNumPSFiles],argv[i1]);
}
else
{
printf("Too many files! Maximum is %d\n", MAXPSFILES);
exit(0);
}
iNumPSFiles++;
}
} /* end i1 for loop, command line parser */
/**Check that at least one file was specified. **/
if( iNumPSFiles <= 0 )
{
puts("No files specified!");
exit(-1);
}
/**Check if the specified files exist. **/
i1 = 0;
do
{
fp = fopen(cPSFileName[i1++],"r");
if( !fp )
{
printf("The file specified, \"%s\", does not exist!\n",
cPSFileName[i1-1]);
exit(-1);
}
fclose(fp);
} while(i1 < iNumPSFiles);
/**Locate the TMP directory. **/
cTemp = getenv("TMP");
if(cTemp)
{
cTempDir = (char *)malloc((strlen(cTemp)+2)*sizeof(char));
vMemCheck(cTempDir);
strcpy(cTempDir,cTemp);
if(cTempDir[strlen(cTempDir)-1] != '\\')
strcat(cTempDir,"\\");
/** Translate to lower case. For some reason the DosDelete function **/
/** doesn't like uppercase? **/
for(i1=0; i1 < strlen(cTempDir); i1++)
{
if(!islower(cTempDir[i1]))
cTempDir[i1] = tolower(cTempDir[i1]);
}
}
else
{
cTempDir = (char *)malloc(3*sizeof(char));
vMemCheck(cTempDir);
strcpy(cTempDir,"\\");
}
/**Clean out any old fax files. **/
puts("Cleaning out old files...");
strcpy(cBuff,cTempDir);
strcat(cBuff,"g3cfax.1");
DosDelete(cBuff);
strcpy(cBuff,cTempDir);
strcat(cBuff,"g3fax.1");
i1 = 2;
while(DosDelete(cBuff) == 0)
{
sprintf(cBuff,"%sg3fax.%d",cTempDir,i1);
i1++;
}
/**Convert the PostScript documents to G3 fax files. **/
puts("Converting documents...");
strcpy(cBuff,cTempDir);
strcat(cBuff,"g3fax.%%d");
sprintf(cBuff2, "gs.exe -dNOPAUSE -sDEVICE=dfaxhigh -q -sOutputFile=%s ",
cBuff);
for(i1=0; i1 < iNumPSFiles; i1++ )
{
strcat(cBuff2,cPSFileName[i1]);
fp = popen(cBuff2, "w");
fprintf(fp, "quit\n");
pclose(fp);
}
/**Get a page count. **/
iPageCnt = iPageCount(cTempDir);
/**If it was specified, generate a coverpage. **/
if( bCover == TRUE )
{
fp = fopen("mcover.ps","w");
fprintf(fp, "/recipnum (%s) def\n", cRecipPhone);
if(bRecipName == TRUE)
fprintf(fp, "/recipient (%s) def\n", cRecipName);
if(bSendName == TRUE)
fprintf(fp, "/sender (%s) def\n", cSendName);
if(bSendPhone == TRUE)
fprintf(fp, "/returnfaxnum (%s) def\n", cSendPhone);
fprintf(fp, "/pages (%d) def\n", iPageCnt+1);
fprintf(fp,"(");
for(i1=0; i1 < strlen(cCoverName); i1++)
{
if(cCoverName[i1] == '\\')
{
fprintf(fp, "\\");
}
fprintf(fp, "%c", cCoverName[i1]);
}
fprintf(fp, ")");
fprintf(fp, " run\n");
fclose(fp);
/** Create the Group 3 coverpage. **/
strcpy(cBuff,cTempDir);
strcat(cBuff,"g3cfax.%%d");
sprintf(cBuff2,
"gs.exe -dNOPAUSE -sDEVICE=dfaxhigh -q -sOutputFile=%s mcover.ps",
cBuff);
fp = popen(cBuff2,"w");
fprintf(fp, "quit\n");
pclose(fp);
DosDelete("mcover.ps");
}
printf("\n"); /* To make room on the screen. */
/**Open the port. **/
puts("Initializing port and modem...");
while(ulOpenPort(cPortID, &hTTY) != 0)
{
printf("Port %s is invalid or being used by another process\n",
cPortID);
printf("Enter 'e' to exit or 'r' to retry: ");
scanf("%s",cBuff);
if(cBuff[0] == 'e' || cBuff[0] == 'E')
vCleanExit(cTempDir,cBuff,iPageCnt,-1);
}
/**Get the current port characteristics. **/
if(iPortGetSet(hTTY, &dcbCom) != 0)
{
puts("Could not get port settings!");
vCleanExit(cTempDir,cBuff,iPageCnt,-1);
}
/**Initialize the port. **/
if(iPortInit(hTTY, &dcbCom) != 0)
{
puts("Setting port characteristics failed!");
vCleanExit(cTempDir,cBuff,iPageCnt,-1);
}
/**Initialize the modem. **/
if(iModemInit(hTTY, &dcbCom) != 0)
{
puts("Modem initialization timed out!");
vCleanExit(cTempDir,cBuff,iPageCnt,-1);
}
/**Dial the modem. **/
printf("Dialing %s...\n", cRecipPhone);
do
{
iTemp = iModemDial(hTTY, cRecipPhone, &dcbCom, iWait);
switch(iTemp)
{
case DIAL_BUSY:
puts("Phone busy!");
break;
case DIAL_NOANSWER:
printf("No answer from remote! ");
printf("Enter 'r' to retry, 'e' to exit: ");
scanf("%s",cBuff);
if(cBuff[0] == 'e' || cBuff[0] == 'E')
vCleanExit(cTempDir,cBuff,iPageCnt,-1);
break;
case DIAL_NOCARRIER:
printf("Could not detect carrier!");
printf(" Enter 'r' to retry, 'e' to exit: ");
scanf("%s",cBuff);
if(cBuff[0] == 'e' || cBuff[0] == 'E')
vCleanExit(cTempDir,cBuff,iPageCnt,-1);
break;
case DIAL_NODIALTONE:
printf("No dial tone! Enter 'r' to retry, 'e' to exit: ");
scanf("%s",cBuff);
if(cBuff[0] == 'e' || cBuff[0] == 'E')
vCleanExit(cTempDir,cBuff,iPageCnt,-1);
break;
case DIAL_UNKNOWN:
printf("Unexpected or unknown response! ");
printf("Enter 'r' to retry, 'e' to exit: ");
scanf("%s",cBuff);
if(cBuff[0] == 'e' || cBuff[0] == 'E')
vCleanExit(cTempDir,cBuff,iPageCnt,-1);
break;
}
if( iTemp != 0 )
{
printf("Waiting %d seconds to redial...",iRedial);
sleep(iRedial);
printf("\n");
}
}
while(iTemp != 0);
/**Initiate fax connection. */
if(iFaxInit(hTTY, &dcbCom, DF_1DHUFFMAN, VR_FINE, WD_1728,
LN_UNLIMITED) != 0)
{
puts("Could not init fax data transmission for the page!");
vCleanExit(cTempDir, cBuff, iPageCnt, -1);
}
/**Begin sending the document(s). **/
iTemp = PEND_ANOTHER;
if(bCover == TRUE)
{
puts("Sending cover page...");
if(iPageCnt <= 0)
iTemp = PEND_ENDTRAN;
strcpy(cBuff,cTempDir);
strcat(cBuff,"g3cfax.1");
fp = fopen(cBuff,"r");
if(!fp)
{
puts("G3 cover page could not be found...");
vCleanExit(cTempDir, cBuff, iPageCnt, -1);
}
do
{
iPageStat = iFaxSendPage(hTTY, &dcbCom, fp, iTemp);
switch( iPageStat )
{
case PPR_PPR:
printf("There were partial page errors during the cover page");
printf(" transmission! Continuing...\n");
iPageStat = 0;
break;
case PPR_MCF:
iPageStat = 0;
break;
case PPR_RTN:
printf("Remote requested retransmission! Retransmitting...\n");
rewind(fp);
iPageStat = 1;
break;
case PPR_RTP:
printf("Page good but remote wants a retransmission? ");
printf("Retransmitting...\n");
rewind(fp);
iPageStat = 1;
break;
case PPR_PIN:
printf("Page bad and remote requests an interrupt!\n");
iPageStat = -1;
break;
case PPR_PIP:
printf("Page good but remote requests an interrupt!\n");
iFaxInterrupt(hTTY, &dcbCom);
vCleanExit(cTempDir, cBuff, iPageCnt, -1);
break;
default:
puts("Cancelling transmission!");
iFaxInterrupt(hTTY, &dcbCom);
vCleanExit(cTempDir, cBuff, iPageCnt, -1);
break;
}
} while(iPageStat == 1);
fclose(fp);
}
/**Send the pages of the document. **/
for(i1=0; i1 < iPageCnt; i1++)
{
/** Send the page. **/
printf("Sending page %d...\n",i1+1);
if(i1 == iPageCnt-1)
iTemp = PEND_ENDTRAN;
sprintf(cBuff, "%sg3fax.%d", cTempDir, i1+1);
fp = fopen(cBuff,"r");
if(!fp)
{
printf("G3 page %d could not be opened!\n", i1);
vCleanExit(cTempDir, cBuff, iPageCnt, -1);
}
do
{
iPageStat = iFaxSendPage(hTTY, &dcbCom, fp, iTemp);
switch( iPageStat )
{
case PPR_PPR:
printf("There were partial page errors during the page");
printf(" transmission! Continuing...\n");
iPageStat = 0;
break;
case PPR_MCF:
iPageStat = 0;
break;
case PPR_RTN:
printf("Remote requested retransmission! Retransmitting...\n");
rewind(fp);
iPageStat = 1;
break;
case PPR_RTP:
printf("Page good but remote wants a retransmission? ");
printf("Retransmitting...\n");
rewind(fp);
iPageStat = 1;
break;
case PPR_PIN:
printf("Page bad and remote requests an interrupt!\n");
iPageStat = -1;
break;
case PPR_PIP:
printf("Page good but remote requests an interrupt!\n");
iPageStat = -1;
break;
default:
puts("Cancelling transmission!");
iPageStat = -1;
break;
}
} while(iPageStat == 1);
fclose(fp);
/** If an interrupt was requested, Grant It. **/
if(iPageStat == -1)
{
iFaxInterrupt(hTTY, &dcbCom);
vCleanExit(cTempDir, cBuff, iPageCnt, -1);
}
}
/**Close the port, clean up and exit. **/
ulClosePort(hTTY);
vCleanExit(cTempDir, cBuff, iPageCnt, 0);
return 0;
}
/****************************************************************************/
/************************Memory check function*******************************/
/****************************************************************************/
void vMemCheck( void *ptr )
{
if( !ptr )
{
puts("Not enough memory!");
exit(-1);
}
}
/****************************************************************************/
/*************************Count the number of********************************/
/*****************************pages to fax***********************************/
/****************************************************************************/
int iPageCount(CHAR *cTempDir)
{
FILE *fp;
char cBuff[CCHMAXPATH];
int iCnt=0;
/*-----------------------------End Declarations----------------------------*/
sprintf(cBuff, "%sg3fax.1", cTempDir);
fp = fopen(cBuff,"r");
while( fp )
{
iCnt++;
fclose(fp);
sprintf(cBuff,"%sg3fax.%d", cTempDir, iCnt+1);
fp = fopen(cBuff,"r");
}
return iCnt;
}
/****************************************************************************/
/**************************Clean up any files********************************/
/****************************and exit PSFax2*********************************/
/****************************************************************************/
void vCleanExit(char *cTempDir, char *cBuff, int iPageCnt, int iError)
{
int i1;
/*-----------------------------End Declarations----------------------------*/
/**Clean out the fax files. **/
if(iError != 0)
printf("Cleaning up and exiting on error condition %d\n", iError);
else
puts("Cleaning up and exiting...");
strcpy(cBuff,cTempDir);
strcat(cBuff,"g3cfax.1");
DosDelete(cBuff);
strcpy(cBuff,cTempDir);
strcat(cBuff,"g3fax.1");
for(i1=1; i1 <= iPageCnt; i1++)
{
sprintf(cBuff,"%sg3fax.%d",cTempDir,i1);
DosDelete(cBuff);
}
exit(iError);
}