home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (C) 1992,1993 Peter Edward Cann */
-
- #include<stdio.h>
- #include<stdlib.h>
- #include<fcntl.h>
- #include<dos.h>
- #include<time.h>
- #include<signal.h>
- #include"port.h"
-
- /* A real programmer would probably put these in a .h file,
- * but a) they're not very big; b) if they change we're in
- * deep stuff anyway, and c) I'm much too lazy. */
- struct
- {
- unsigned bits;
- unsigned mask;
- }
- whites[]=
- {
- {0x00ac, 0x00ff},
- {0x0038, 0x003f},
- {0x000e, 0x000f},
- {0x0001, 0x000f},
- {0x000d, 0x000f},
- {0x0003, 0x000f},
- {0x0007, 0x000f},
- {0x000f, 0x000f},
- {0x0019, 0x001f},
- {0x0005, 0x001f},
- {0x001c, 0x001f},
- {0x0002, 0x001f},
- {0x0004, 0x003f},
- {0x0030, 0x003f},
- {0x000b, 0x003f},
- {0x002b, 0x003f},
- {0x0015, 0x003f},
- {0x0035, 0x003f},
- {0x0072, 0x007f},
- {0x0018, 0x007f},
- {0x0008, 0x007f},
- {0x0074, 0x007f},
- {0x0060, 0x007f},
- {0x0010, 0x007f},
- {0x000a, 0x007f},
- {0x006a, 0x007f},
- {0x0064, 0x007f},
- {0x0012, 0x007f},
- {0x000c, 0x007f},
- {0x0040, 0x00ff},
- {0x00c0, 0x00ff},
- {0x0058, 0x00ff},
- {0x00d8, 0x00ff},
- {0x0048, 0x00ff},
- {0x00c8, 0x00ff},
- {0x0028, 0x00ff},
- {0x00a8, 0x00ff},
- {0x0068, 0x00ff},
- {0x00e8, 0x00ff},
- {0x0014, 0x00ff},
- {0x0094, 0x00ff},
- {0x0054, 0x00ff},
- {0x00d4, 0x00ff},
- {0x0034, 0x00ff},
- {0x00b4, 0x00ff},
- {0x0020, 0x00ff},
- {0x00a0, 0x00ff},
- {0x0050, 0x00ff},
- {0x00d0, 0x00ff},
- {0x004a, 0x00ff},
- {0x00ca, 0x00ff},
- {0x002a, 0x00ff},
- {0x00aa, 0x00ff},
- {0x0024, 0x00ff},
- {0x00a4, 0x00ff},
- {0x001a, 0x00ff},
- {0x009a, 0x00ff},
- {0x005a, 0x00ff},
- {0x00da, 0x00ff},
- {0x0052, 0x00ff},
- {0x00d2, 0x00ff},
- {0x004c, 0x00ff},
- {0x00cc, 0x00ff},
- {0x002c, 0x00ff},
- {0x001b, 0x001f},
- {0x0009, 0x001f},
- {0x003a, 0x003f},
- {0x0076, 0x007f},
- {0x006c, 0x00ff},
- {0x00ec, 0x00ff},
- {0x0026, 0x00ff},
- {0x00a6, 0x00ff},
- {0x0016, 0x00ff},
- {0x00e6, 0x00ff},
- {0x0066, 0x01ff},
- {0x0166, 0x01ff},
- {0x0096, 0x01ff},
- {0x0196, 0x01ff},
- {0x0056, 0x01ff},
- {0x0156, 0x01ff},
- {0x00d6, 0x01ff},
- {0x01d6, 0x01ff},
- {0x0036, 0x01ff},
- {0x0136, 0x01ff},
- {0x00b6, 0x01ff},
- {0x01b6, 0x01ff},
- {0x0032, 0x01ff},
- {0x0132, 0x01ff},
- {0x00b2, 0x01ff},
- {0x0006, 0x003f},
- {0x01b2, 0x01ff}
- },
- blacks[]=
- {
- {0x03b0, 0x03ff},
- {0x0002, 0x0007},
- {0x0003, 0x0003},
- {0x0001, 0x0003},
- {0x0006, 0x0007},
- {0x000c, 0x000f},
- {0x0004, 0x000f},
- {0x0018, 0x001f},
- {0x0028, 0x003f},
- {0x0008, 0x003f},
- {0x0010, 0x007f},
- {0x0050, 0x007f},
- {0x0070, 0x007f},
- {0x0020, 0x00ff},
- {0x00e0, 0x00ff},
- {0x0030, 0x01ff},
- {0x03a0, 0x03ff},
- {0x0060, 0x03ff},
- {0x0040, 0x03ff},
- {0x0730, 0x07ff},
- {0x00b0, 0x07ff},
- {0x01b0, 0x07ff},
- {0x0760, 0x07ff},
- {0x00a0, 0x07ff},
- {0x0740, 0x07ff},
- {0x00c0, 0x07ff},
- {0x0530, 0x0fff},
- {0x0d30, 0x0fff},
- {0x0330, 0x0fff},
- {0x0b30, 0x0fff},
- {0x0160, 0x0fff},
- {0x0960, 0x0fff},
- {0x0560, 0x0fff},
- {0x0d60, 0x0fff},
- {0x04b0, 0x0fff},
- {0x0cb0, 0x0fff},
- {0x02b0, 0x0fff},
- {0x0ab0, 0x0fff},
- {0x06b0, 0x0fff},
- {0x0eb0, 0x0fff},
- {0x0360, 0x0fff},
- {0x0b60, 0x0fff},
- {0x05b0, 0x0fff},
- {0x0db0, 0x0fff},
- {0x02a0, 0x0fff},
- {0x0aa0, 0x0fff},
- {0x06a0, 0x0fff},
- {0x0ea0, 0x0fff},
- {0x0260, 0x0fff},
- {0x0a60, 0x0fff},
- {0x04a0, 0x0fff},
- {0x0ca0, 0x0fff},
- {0x0240, 0x0fff},
- {0x0ec0, 0x0fff},
- {0x01c0, 0x0fff},
- {0x0e40, 0x0fff},
- {0x0140, 0x0fff},
- {0x01a0, 0x0fff},
- {0x09a0, 0x0fff},
- {0x0d40, 0x0fff},
- {0x0340, 0x0fff},
- {0x05a0, 0x0fff},
- {0x0660, 0x0fff},
- {0x0e60, 0x0fff},
- {0x03c0, 0x03ff},
- {0x0130, 0x0fff},
- {0x0930, 0x0fff},
- {0x0da0, 0x0fff},
- {0x0cc0, 0x0fff},
- {0x02c0, 0x0fff},
- {0x0ac0, 0x0fff},
- {0x06c0, 0x1fff},
- {0x16c0, 0x1fff},
- {0x0a40, 0x1fff},
- {0x1a40, 0x1fff},
- {0x0640, 0x1fff},
- {0x1640, 0x1fff},
- {0x09c0, 0x1fff},
- {0x19c0, 0x1fff},
- {0x05c0, 0x1fff},
- {0x15c0, 0x1fff},
- {0x0dc0, 0x1fff},
- {0x1dc0, 0x1fff},
- {0x0940, 0x1fff},
- {0x1940, 0x1fff},
- {0x0540, 0x1fff},
- {0x1540, 0x1fff},
- {0x0b40, 0x1fff},
- {0x1b40, 0x1fff},
- {0x04c0, 0x1fff},
- {0x14c0, 0x1fff}
- };
-
- /* This is max n bytes+ of Phase C for Federal stripe. Know thy math!!! */
- /* To save 5 k, we do DLE shielding at Tx time. */
-
- #define SFXBUFSIZ 5200
-
- unsigned char sfxbuf[SFXBUFSIZ];
-
- int sfxbufi;
-
- unsigned char wkngbyte, wbmask;
-
- putsym(bitsw, maskw)
- unsigned bitsw, maskw;
- {
- unsigned srcmask;
- for(srcmask=1;srcmask&maskw;srcmask<<=1)
- {
- if(bitsw&srcmask)
- wkngbyte|=wbmask;
- if(!(wbmask<<=1))
- {
- sfxbuf[sfxbufi++]=wkngbyte;
- wkngbyte=0;
- wbmask=0x01;
- }
- }
- }
-
- initsym()
- {
- wkngbyte=0;
- wbmask=0x01;
- }
-
- puteol()
- {
- if(wbmask!=0x01) /* Might as well save a byte */
- sfxbuf[sfxbufi++]=wkngbyte;
- initsym();
- sfxbuf[sfxbufi++]=0x00;
- sfxbuf[sfxbufi++]=0x80;
- }
-
- putwhite(n)
- int n;
- {
- int m;
- if((n<0)||(n>1728))
- {
- printf("\nProbable code error; bad white run length %d.\n", n);
- exit(71);
- }
- if(m=(n&~63))
- {
- m>>=6;
- m+=63;
- putsym(whites[m].bits, whites[m].mask);
- }
- m=n&63;
- putsym(whites[m].bits, whites[m].mask);
- }
-
- putblack(n)
- int n;
- {
- int m;
- if((n<0)||(n>1728))
- {
- printf("\nProbable code error, bad black run length %d.\n", n);
- exit(72);
- }
- if(m=(n&~63))
- {
- m>>=6;
- m+=63;
- putsym(blacks[m].bits, blacks[m].mask);
- }
- m=n&63;
- putsym(blacks[m].bits, blacks[m].mask);
- }
-
- /* 7-segment bit significance:
- *
- * --0--
- * 1 2
- * --3--
- * 4 5
- * --6--
- *
- * Code ten decimal is the hyphen.
- */
-
- unsigned char segmaps[]=
- {0x77,0x24,0x5d,0x6d,0x2e,0x6b,0x7b,0x25,0x7f,0x6f,0x08,0x00};
-
- unsigned char fedstr[80];
-
- makeheader(page)
- int page;
- {
- int white, row, i, pixcnt;
- char pagestr[8], *ssptr, *tsptr;
- sfxbufi=0;
- sprintf(pagestr, "%d", page);
- for(ssptr=pagestr,tsptr=&fedstr[72];*ssptr;ssptr++,tsptr++)
- (*tsptr)=(*ssptr)-'0';
- puteol();
- putwhite(1728);
- puteol();
- putwhite(1728);
- puteol();
- putwhite(1728);
- puteol();
- for(row=0;row<3;row++)
- {
- pixcnt=0;
- white=64;
- for(i=0,ssptr=fedstr;i<80;++i,++ssptr)
- {
- if(segmaps[*ssptr]&1)
- {
- putwhite(white);
- pixcnt+=white;
- white=0;
- putblack(16);
- pixcnt+=16;
- }
- else
- {
- if(segmaps[*ssptr]&2)
- {
- putwhite(white);
- pixcnt+=white;
- white=0;
- putblack(3);
- pixcnt+=3;
- }
- else
- white+=3;
- white+=10;
- if(segmaps[*ssptr]&4)
- {
- putwhite(white);
- pixcnt+=white;
- white=0;
- putblack(3);
- pixcnt+=3;
- }
- else
- white+=3;
- }
- white+=4;
- }
- putwhite(1728-pixcnt);
- puteol();
- }
- for(row=0;row<10;row++)
- {
- pixcnt=0;
- white=64;
- for(i=0,ssptr=fedstr;i<80;++i,++ssptr)
- {
- if(segmaps[*ssptr]&2)
- {
- putwhite(white);
- pixcnt+=white;
- white=0;
- putblack(3);
- pixcnt+=3;
- }
- else
- white+=3;
- white+=10;
- if(segmaps[*ssptr]&4)
- {
- putwhite(white);
- pixcnt+=white;
- white=0;
- putblack(3);
- pixcnt+=3;
- }
- else
- white+=3;
- white+=4;
- }
- putwhite(1728-pixcnt);
- puteol();
- }
- for(row=0;row<3;row++)
- {
- pixcnt=0;
- white=64;
- for(i=0,ssptr=fedstr;i<80;++i,++ssptr)
- {
- if(segmaps[*ssptr]&8)
- {
- putwhite(white);
- pixcnt+=white;
- white=0;
- putblack(16);
- pixcnt+=16;
- }
- else
- {
- if(segmaps[*ssptr]&18) /* 16 | 2; cute, eh? */
- {
- putwhite(white);
- pixcnt+=white;
- white=0;
- putblack(3);
- pixcnt+=3;
- }
- else
- white+=3;
- white+=10;
- if(segmaps[*ssptr]&36) /* 32 | 4 */
- {
- putwhite(white);
- pixcnt+=white;
- white=0;
- putblack(3);
- pixcnt+=3;
- }
- else
- white+=3;
- }
- white+=4;
- }
- putwhite(1728-pixcnt);
- puteol();
- }
- for(row=0;row<10;row++)
- {
- pixcnt=0;
- white=64;
- for(i=0,ssptr=fedstr;i<80;++i,++ssptr)
- {
- if(segmaps[*ssptr]&16)
- {
- putwhite(white);
- pixcnt+=white;
- white=0;
- putblack(3);
- pixcnt+=3;
- }
- else
- white+=3;
- white+=10;
- if(segmaps[*ssptr]&32)
- {
- putwhite(white);
- pixcnt+=white;
- white=0;
- putblack(3);
- pixcnt+=3;
- }
- else
- white+=3;
- white+=4;
- }
- putwhite(1728-pixcnt);
- puteol();
- }
- for(row=0;row<3;row++)
- {
- pixcnt=0;
- white=64;
- for(i=0,ssptr=fedstr;i<80;++i,++ssptr)
- {
- if(segmaps[*ssptr]&64)
- {
- putwhite(white);
- pixcnt+=white;
- white=0;
- putblack(16);
- pixcnt+=16;
- }
- else
- {
- if(segmaps[*ssptr]&16)
- {
- putwhite(white);
- pixcnt+=white;
- white=0;
- putblack(3);
- pixcnt+=3;
- }
- else
- white+=3;
- white+=10;
- if(segmaps[*ssptr]&32)
- {
- putwhite(white);
- pixcnt+=white;
- white=0;
- putblack(3);
- pixcnt+=3;
- }
- else
- white+=3;
- }
- white+=4;
- }
- putwhite(1728-pixcnt);
- puteol();
- }
- putwhite(1728);
- puteol();
- putwhite(1728);
- puteol();
- putwhite(1728);
- puteol();
- putwhite(0);
- putblack(1728);
- putwhite(0);
- /* We only get the black with this or extra EOL; goD knows why! */
- }
-
- sendchar(c)
- unsigned char c;
- {
- while(!(inp(basereg+STATREG)&TXMTMASK))
- if(kbhit())
- getch();
- outp(basereg, c);
- }
-
- int follow;
-
- quit()
- {
- cleanup(0);
- exit(99);
- }
-
- sendstr(str)
- char *str;
- {
- int i;
- for(i=0;str[i]!='\0';++i)
- sendchar(str[i]);
- }
-
- #define FBUFSIZ 4096
-
- unsigned char fbuf[FBUFSIZ];
- int fd, fbufi, fbufn;
-
- unsigned char getbyte()
- {
- if(fbufi>=fbufn)
- if((fbufn=read(fd, fbuf, FBUFSIZ))<=0)
- {
- printf("Premature end of file.\n");
- cleanup(0);
- exit(101);
- }
- else
- fbufi=0;
- return(fbuf[fbufi++]);
- }
-
- int scanok(seconds)
- int seconds;
- {
- static char *okstr="\nOK\r\n";
- static char *fhngstr="\n+FHNG";
- long timestamp;
- int i, j;
- timestamp=time(NULL);
- i=j=0;
- while(1)
- {
- while(follow==index)
- {
- if(kbhit())
- getch();
- if((time(NULL)-timestamp)>seconds)
- return(0);
- }
- putch(buf[follow]);
- if(okstr[i]==buf[follow])
- {
- i++;
- if(okstr[i]=='\0')
- {
- follow++;
- follow%=TBUFSIZ;
- return(1);
- }
- }
- else
- i=0;
- if(fhngstr[j]==buf[follow])
- {
- j++;
- if(fhngstr[i]=='\0')
- {
- follow++;
- follow%=TBUFSIZ;
- do
- {
- follow%=TBUFSIZ;
- while(follow==index)
- {
- if(kbhit())
- getch();
- if((time(NULL)-timestamp)>seconds)
- return(0);
- }
- putch(buf[follow]);
- }
- while(buf[follow++]!='\n');
- follow%=TBUFSIZ;
- return(0);
- }
- }
- else
- j=0;
- follow++;
- follow%=TBUFSIZ;
- }
- }
-
- int scanconnect(seconds)
- int seconds;
- {
- static char *connectstr="\nCONNECT\r\n";
- static char *fhngstr="\n+FHNG";
- long timestamp;
- int i, j;
- timestamp=time(NULL);
- i=j=0;
- while(1)
- {
- while(follow==index)
- {
- if(kbhit())
- getch();
- if((time(NULL)-timestamp)>seconds)
- return(0);
- }
- putch(buf[follow]);
- if(connectstr[i]==buf[follow])
- {
- i++;
- if(connectstr[i]=='\0')
- {
- follow++;
- follow%=TBUFSIZ;
- return(1);
- }
- }
- else
- i=0;
- if(fhngstr[j]==buf[follow])
- {
- j++;
- if(fhngstr[i]=='\0')
- {
- follow++;
- follow%=TBUFSIZ;
- do
- {
- follow%=TBUFSIZ;
- while(follow==index)
- {
- if(kbhit())
- getch();
- if((time(NULL)-timestamp)>seconds)
- return(0);
- }
- putch(buf[follow]);
- }
- while(buf[follow++]!='\n');
- follow%=TBUFSIZ;
- return(0);
- }
- }
- else
- j=0;
- follow++;
- follow%=TBUFSIZ;
- }
- }
-
- int scanfhng0(seconds)
- int seconds;
- {
- static char *fhng0str="\n+FHNG: 0\r\n";
- static char *fhngstr="\n+FHNG: #!";
- long timestamp;
- int i, j;
- timestamp=time(NULL);
- i=j=0;
- while(1)
- {
- while(follow==index)
- {
- if(kbhit())
- getch();
- if((time(NULL)-timestamp)>seconds)
- return(0);
- }
- putch(buf[follow]);
- if(fhng0str[i]==buf[follow])
- {
- i++;
- if(fhng0str[i]=='\0')
- {
- follow++;
- follow%=TBUFSIZ;
- return(1);
- }
- }
- else
- i=0;
- if((fhngstr[j]==buf[follow])||((fhngstr[i]=='#')&&(buf[follow]!='0'))||((fhngstr[i]=='!')&&(buf[follow]!='\r')))
- {
- j++;
- if(fhngstr[i]=='\0')
- {
- follow++;
- follow%=TBUFSIZ;
- do
- {
- follow%=TBUFSIZ;
- while(follow==index)
- {
- if(kbhit())
- getch();
- if((time(NULL)-timestamp)>seconds)
- return(0);
- }
- putch(buf[follow]);
- }
- while(buf[follow++]!='\n');
- follow%=TBUFSIZ;
- return(0);
- }
- }
- else
- j=0;
- follow++;
- follow%=TBUFSIZ;
- }
- }
-
- main(argc, argv)
- int argc;
- char **argv;
- {
- int xflag, dleflag, i, page;
- FILE *cfgfd;
- unsigned char c, *fromstr, timestr[32], *ssptr, *tsptr;
- time_t utime;
- struct tm *goodies;
- if(argc!=4)
- {
- printf("USAGE: sndfax <comnum> <speed> <file>\n");
- exit(98);
- }
- for(i=0;i<80;i++)
- fedstr[i]=11;
- if((fromstr=getenv("PCCPFROM"))==NULL)
- {
- printf("WARNING: USA Federal regulations require fax sender identification.\n");
- printf("Unable to find environment variable PCCPFROM; see manual. Sending anyway.\n");
- }
- for(ssptr=fromstr,tsptr=fedstr,i=0;(*ssptr)&&((*ssptr)!='\n')&&(i<40);ssptr++,tsptr++)
- if(((*ssptr)>='0')&&((*ssptr)<='9'))
- (*tsptr)=(*ssptr)-'0';
- else if((*ssptr)=='-')
- (*tsptr)=10;
- time(&utime);
- goodies=localtime(&utime);
- sprintf(timestr, "%d-%02d-%02d %02d%02d",
- (goodies->tm_year>70)?(goodies->tm_year+1900):(goodies->tm_year+2000),
- (goodies->tm_mon)+1, goodies->tm_mday,
- goodies->tm_hour, goodies->tm_min);
- for(ssptr=timestr,tsptr=&fedstr[45];*ssptr;ssptr++,tsptr++)
- if(((*ssptr)>='0')&&((*ssptr)<='9'))
- (*tsptr)=(*ssptr)-'0';
- else if((*ssptr)=='-')
- (*tsptr)=10;
- if((fd=open(argv[3], O_RDONLY|O_BINARY))==-1)
- {
- printf("Error opening presumed SFX file %s for read.\n", argv[3]);
- exit(97);
- }
- comnum=atoi(argv[1])-1;
- speed=atoi(argv[2]);
- databits='8';
- parity='n';
- stopbits='1';
- setport();
- readset();
- follow=index=0;
- setup();
- signal(SIGINT, quit);
- page=0;
- fbufi=fbufn=0;
- while(1)
- {
- makeheader(++page);
- sendstr("AT+FDT\r");
- if(!scanconnect(60))
- {
- cleanup(0);
- printf("Failed to get CONNECT message.\n");
- close(fd);
- exit(1);
- break;
- }
- while(1)
- {
- while(follow==index)
- if(kbhit())
- getch();
- if(buf[follow++]==0x11)
- {
- follow%=TBUFSIZ;
- break;
- }
- follow%=TBUFSIZ;
- }
- for(i=0;i<sfxbufi;i++)
- {
- for(xflag=0;xflag|(follow!=index);)
- if(follow!=index)
- {
- c=buf[follow++];
- if(follow>=TBUFSIZ)
- follow=0;
- if(c==0x13)
- xflag=1;
- else if(c==0x11)
- xflag=0;
- }
- sendchar(sfxbuf[i]);
- if(sfxbuf[i]==0x10)
- sendchar(0x10); /* Count on buffer slack */
- }
- dleflag=0;
- while(1)
- {
- for(xflag=0;xflag|(follow!=index);)
- if(follow!=index)
- {
- c=buf[follow++];
- if(follow>=TBUFSIZ)
- follow=0;
- if(c==0x13)
- xflag=1;
- else if(c==0x11)
- xflag=0;
- }
- c=getbyte();
- if(dleflag)
- {
- dleflag=0;
- if(c==0x03)
- {
- sendchar(c);
- break;
- }
- else if(c==0x04)
- {
- sendchar(0x03);
- if(!scanok(60))
- {
- printf("Failed to get OK after last page image data.\n");
- cleanup(0);
- exit(2);
- }
- sendstr("AT+FET=2\r");
- if(!scanfhng0(60))
- {
- printf("Failed to get good hangup code.\n");
- cleanup(0);
- exit(3);
- }
- cleanup(0);
- exit(0);
- }
- else
- sendchar(c);
- }
- else
- {
- if(c==0x10)
- dleflag=1;
- sendchar(c);
- }
- }
- if(!scanok(60))
- {
- printf("Failed to get OK after page image data.\n");
- cleanup(0);
- exit(7);
- }
- sendstr("AT+FET=0\r");
- if(!scanok(60))
- {
- printf("Failed to get proper interpage handshake.\n");
- cleanup(0);
- exit(8);
- }
- }
- printf("Something's wrong with the code; we should never have gotten here!\n");
- cleanup(0);
- exit(111);
- }