xref: /plan9/sys/src/cmd/fax/file.c (revision 7dd7cddf99dd7472612f1413b4da293630e6b1bc)
1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4 
5 #include "modem.h"
6 
7 static long wd[5] = {
8 	1728, 2048, 2432, 1216, 864
9 };
10 
11 void
setpageid(char * pageid,char * spool,long time,int pid,int pageno)12 setpageid(char *pageid, char *spool, long time, int pid, int pageno)
13 {
14 	sprint(pageid, "%s/%lud.%d.%3.3d", spool, time, pid, pageno);
15 }
16 
17 int
createfaxfile(Modem * m,char * spool)18 createfaxfile(Modem *m, char *spool)
19 {
20 	setpageid(m->pageid, spool, m->time, m->pid, m->pageno);
21 	verbose("openfaxfile: %s", m->pageid);
22 	if((m->pagefd = create(m->pageid, OTRUNC|OWRITE, 0666)) < 0)
23 		return seterror(m, Esys);
24 
25 	fprint(m->pagefd, "TYPE=ccitt-g31\n");
26 	fprint(m->pagefd, "WINDOW=0 0 %ld -1\n", wd[m->fdcs[2]]);
27 	if(m->valid & Vftsi)
28 		fprint(m->pagefd, "FTSI=%s\n", m->ftsi);
29 	fprint(m->pagefd, "FDCS=%lud,%lud,%lud,%lud,%lud,%lud,%lud,%lud\n",
30 		m->fdcs[0], m->fdcs[1], m->fdcs[2], m->fdcs[3],
31 		m->fdcs[4], m->fdcs[5], m->fdcs[6], m->fdcs[7]);
32 	fprint(m->pagefd, "\n");
33 
34 	return Eok;
35 }
36 
37 enum
38 {
39 	Gshdrsize=	0x40,
40 };
41 
42 int
gsopen(Modem * m)43 gsopen(Modem *m)
44 {
45 	int n;
46 	char bytes[Gshdrsize];
47 
48 	/*
49 	 *  Is this gs output
50 	 */
51 	n = Bread(m->bp, bytes, Gshdrsize);
52 	if(n != Gshdrsize)
53 		return seterror(m, Esys);
54 	if(bytes[0]!='\0' || strcmp(bytes+1, "PC Research, Inc")!=0){
55 		Bseek(m->bp, 0, 0);
56 		return seterror(m, Esys);
57 	}
58 
59 	m->valid |= Vtype;
60 	if(bytes[0x1d])
61 		m->vr = 1;
62 	else
63 		m->vr = 0;
64 	m->wd = 0;
65 	m->ln = 2;
66 	m->df = 0;
67 	return Eok;
68 }
69 
70 int
picopen(Modem * m)71 picopen(Modem *m)
72 {
73 	char *p, *q;
74 	int i, x;
75 
76 	/*
77 	 * Look at the header. Every page should have a valid type.
78 	 * The first page should have WINDOW.
79 	 */
80 	while(p = Brdline(m->bp, '\n')){
81 		if(Blinelen(m->bp) == 1)
82 			break;
83 		p[Blinelen(m->bp)-1] = 0;
84 
85 		verbose("openfaxfile: %s", p);
86 		if(strcmp("TYPE=ccitt-g31", p) == 0)
87 			m->valid |= Vtype;
88 		/*
89 		else if(m->pageno == 1 && strncmp("PHONE=", p, 6) == 0){
90 			strcpy(m->number, p+6);
91 			m->valid |= Vphone;
92 		}
93 		 */
94 		else if(m->pageno == 1 && strncmp("WINDOW=", p, 7) == 0){
95 			p += 7;
96 			verbose("openfaxfile: WINDOW: %s", p);
97 			for(i = 0; i < 4; i++){
98 				x = strtol(p, &q, 10);
99 				if(i == 2)
100 					m->wd = x;
101 				if((p = q) == 0){
102 					Bterm(m->bp);
103 					return seterror(m, Eproto);
104 				}
105 			}
106 			for(i = 0; i < 5; i++){
107 				if(m->wd == wd[i]){
108 					m->wd = i;
109 					m->valid |= Vwd;
110 					break;
111 				}
112 			}
113 			if((m->valid & Vwd) == 0){
114 				Bterm(m->bp);
115 				return seterror(m, Eproto);
116 			}
117 		}
118 		else if(m->pageno == 1 && strncmp("FDCS=", p, 5) == 0){
119 			p += 5;
120 			m->df = m->vr = m->wd = 0;
121 			m->ln = 2;
122 			for(i = 0; i < 5; i++){
123 				x = strtol(p, &q, 10);
124 				switch(i){
125 				case 0:
126 					m->vr = x;
127 					break;
128 				case 3:
129 					m->ln = x;
130 					break;
131 				case 4:
132 					m->df = x;
133 					break;
134 				}
135 				if((p = q) == 0){
136 					Bterm(m->bp);
137 					return seterror(m, Eproto);
138 				}
139 				if(*p++ != ',')
140 					break;
141 			}
142 		}
143 	}
144 
145 	verbose("openfaxfile: valid #%4.4ux", m->valid);
146 	if((m->valid & (Vtype|Vwd)) != (Vtype|Vwd)){
147 		Bterm(m->bp);
148 		return seterror(m, Eproto);
149 	}
150 
151 	return Eok;
152 }
153 
154 int
openfaxfile(Modem * m,char * file)155 openfaxfile(Modem *m, char *file)
156 {
157 	if((m->bp = Bopen(file, OREAD)) == 0)
158 		return seterror(m, Esys);
159 	m->valid &= ~(Vtype);
160 
161 	if(gsopen(m) == Eok)
162 		return Eok;
163 	return picopen(m);
164 }
165