1 /* $Id$ */
2 /*
3 * Copyright (c) 1990-1996 Sam Leffler
4 * Copyright (c) 1991-1996 Silicon Graphics, Inc.
5 * HylaFAX is a trademark of Silicon Graphics
6 *
7 * Permission to use, copy, modify, distribute, and sell this software and
8 * its documentation for any purpose is hereby granted without fee, provided
9 * that (i) the above copyright notices and this permission notice appear in
10 * all copies of the software and related documentation, and (ii) the names of
11 * Sam Leffler and Silicon Graphics may not be used in any advertising or
12 * publicity relating to the software without the specific, prior written
13 * permission of Sam Leffler and Silicon Graphics.
14 *
15 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
17 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
18 *
19 * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
20 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
21 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
22 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
23 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
24 * OF THIS SOFTWARE.
25 */
26 #ifndef _FaxClient_
27 #define _FaxClient_
28
29 #include "Types.h"
30 #include "Str.h"
31 #include "FaxConfig.h"
32
33 class Transport;
34
35 class FaxClient : public FaxConfig {
36 public:
37 enum { // command reply codes
38 PRELIM = 1, // positive preliminary
39 COMPLETE = 2, // positive completion
40 CONTINUE = 3, // positive intermediate
41 TRANSIENT = 4, // transient negative completion
42 ERROR = 5 // permanent negative completion
43 };
44 enum { // data transfer TYPEs
45 TYPE_A = 1, // ASCII
46 TYPE_E = 2, // EBCDIC
47 TYPE_I = 3, // image
48 TYPE_L = 4 // local byte size
49 };
50 enum { // data transfer file STRUctures
51 STRU_F = 1, // file (no record structure)
52 STRU_R = 2, // record structure
53 STRU_P = 3, // page structure
54 STRU_T = 4 // multi-IFD TIFF
55 };
56 enum { // data transfer MODEs
57 MODE_S = 1, // stream
58 MODE_B = 2, // block
59 MODE_C = 3, // run-length compressed
60 MODE_Z = 4 // zlib compressed
61 };
62 enum { // data file FORMats
63 FORM_UNKNOWN = 0, // unknown, initial setting
64 FORM_PS = 1, // PostScript Level I
65 FORM_PS2 = 2, // PostScript Level II
66 FORM_TIFF = 3, // TIFF
67 FORM_PCL = 4, // HP PCL5
68 FORM_PDF = 5 // Portable Document Format
69 };
70 enum {
71 TZ_GMT = 1, // use GMT timezone for time values
72 TZ_LOCAL = 2 // use local timezone for time values
73 };
74
75 // NB: the F_ prefixes workaround a bug in the AIX xlC compiler
76 struct F_stringtag {
77 const char* name;
78 fxStr FaxClient::* p;
79 const char* def; // NULL is shorthand for ""
80 };
81 struct F_numbertag {
82 const char* name;
83 u_int FaxClient::*p;
84 u_int def;
85 };
86 struct FaxParam {
87 const char* cmd;
88 const char** parmNames;
89 u_int NparmNames;
90 u_int FaxClient::*pv;
91 };
92 struct FaxFmtHeader {
93 char fmt; // format character used by server
94 const char* title; // column title to use
95 };
96 private:
97 Transport* transport; // underlying transport protocol support
98 fxStr host; // server's host
99 fxStr modem; // server's modem
100 u_int state; // state flags
101 #define FS_VERBOSE 0x0001 // print data as sent or received
102 #define FS_LOGGEDIN 0x0002 // logged in on server
103 #define FS_TZPEND 0x0004 // tzone setting pending
104 #define FS_JFMTPEND 0x0008 // job status format string pending
105 #define FS_RFMTPEND 0x0010 // job status format string pending
106 #define FS_MFMTPEND 0x0020 // modem status format string pending
107 #define FS_FFMTPEND 0x0040 // file status format string pending
108 fxStr userName; // sender's account name
109 fxStr senderName; // sender's full name (if available)
110 FILE* fdIn; // control stream input handle
111 FILE* fdOut; // control stream output handle
112 int fdData; // data transfer connection
113 char buf[1024]; // input buffer
114 int code; // code from last server repsonse
115 bool pasv; // use of passive mode
116 fxStr proto; // protocol to use for service query
117 fxStr lastResponse; // text message from last server response
118 fxStr lastContinuation; // continuation message from last server response
119 u_int port; // server port to connect to
120 u_int type; // data transfer type
121 u_int stru; // file structure
122 u_int mode; // data transfer mode
123 u_int format; // document format
124 u_int tzone; // use GMT or local timezone for time values
125 fxStr curjob; // current job's ID
126 fxStr jobFmt; // job status format string
127 fxStr recvFmt; // recv queue status format string
128 fxStr modemFmt; // modem status format string
129 fxStr fileFmt; // file status format string
130 fxStr jobSFmt; // job status sort format string
131 fxStr recvSFmt; // recv queue status sort format string
132 fxStr modemSFmt; // modem status sort format string
133 fxStr fileSFmt; // file status sort format string
134
135 static F_stringtag strings[];
136 static F_numbertag numbers[];
137 static FaxParam typeParam;
138 static FaxParam modeParam;
139 static FaxParam struParam;
140 static FaxParam formParam;
141 static FaxParam tzoneParam;
142
143 void init(void);
144
145 bool sendRawData(void* buf, int cc, fxStr& emsg);
146 bool setCommon(FaxParam&, u_int);
147 protected:
148 FaxClient();
149 FaxClient(const fxStr& hostarg);
150 FaxClient(const char* hostarg);
151 ~FaxClient();
152
153 virtual void vprintError(const char* fmt, va_list ap);
154 virtual void vprintWarning(const char* fmt, va_list ap);
155 virtual void vtraceServer(const char* fmt, va_list ap);
156
157 void initServerState(void);
158 bool jobOp(const char* op, const char* jobid);
159 bool extract(u_int& pos, const char* pattern, fxStr& result,
160 const char* cmd, fxStr& emsg);
161 bool storeUnique(const char* cmd, fxStr& docname, fxStr& emsg);
162
163 const fxStr& getStatusFormat(u_int flag, const char* cmd, fxStr& fmt);
164 bool setStatusFormat(const char* cmd, u_int flag, fxStr&, const char*);
165 void makeHeader(const char* fmt, const FaxFmtHeader fmts[], fxStr& header);
166
167 virtual bool setupUserIdentity(fxStr& emsg);
168 void setupHostModem(const char*);
169 void setupHostModem(const fxStr&);
170
171 virtual void resetConfig(void);
172 virtual void setupConfig(void);
173 virtual bool setConfigItem(const char* tag, const char* value);
174 virtual void configError(const char* fmt ...);
175 virtual void configTrace(const char* fmt ...);
176
177 void unexpectedResponse(fxStr& emsg);
178 void protocolBotch(fxStr& emsg, const char* fmt ...);
179 virtual void lostServer(void);
180 public:
181 void printError(const char* fmt ...);
182 void printWarning(const char* fmt ...);
183 void traceServer(const char* fmt ...);
184
185 // bookkeeping
186 void setHost(const fxStr&);
187 void setHost(const char*);
188 void setPort(int);
189 void setProtoName(const char*);
190 const fxStr& getHost() const;
191 void setModem(const fxStr&);
192 void setModem(const char*);
193 const fxStr& getModem(void) const;
194
195 virtual bool callServer(fxStr& emsg);
196 virtual bool hangupServer(void);
197 bool isConnected(void) const;
198 bool isPassive(void) const;
199 bool login(const char* user, fxStr& emsg);
200 bool admin(const char* pass, fxStr& emsg);
201 virtual const char* getPasswd(const char* prompt);
202 bool isLoggedIn(void) const;
203 void setCtrlFds(int in, int out);
204 FILE* getCtrlFd(void) const;
205
206 virtual bool initDataConn(fxStr& emsg);
207 virtual bool openDataConn(fxStr& emsg);
208 virtual void closeDataConn(void);
209 virtual bool abortDataConn(fxStr& emsg);
210 void setDataFd(int fd);
211 int getDataFd(void) const;
212
213 void setVerbose(bool);
214 bool getVerbose(void) const;
215
216 int getPort(void) const;
217 const fxStr& getProtoName(void) const;
218
219 const fxStr& getSenderName(void) const;
220 const fxStr& getUserName(void) const;
221
222 // output
223 int command(const char* fmt ...);
224 int vcommand(const char* fmt, va_list ap);
225 int getReply(bool expectEOF);
226 const fxStr& getLastResponse(void) const;
227 const fxStr& getLastContinuation(void) const;
228 int getLastCode(void) const;
229 /*
230 * Job control support.
231 */
232 const fxStr& getCurrentJob(void) const;
233 bool setCurrentJob(const char* jobid);
234 bool newJob(fxStr& jobid, fxStr& groupid, fxStr& emsg);
235 bool jobSubmit(const char* jobid);
236 bool jobSuspend(const char* jobid);
237 bool jobKill(const char* jobid);
238 bool jobDelete(const char* jobid);
239 bool jobWait(const char* jobid);
240 /*
241 * Set various job parameters.
242 */
243 bool jobParm(const char* name, const fxStr& value);
244 bool jobParm(const char* name, const char* value);
245 bool jobParm(const char* name, bool b);
246 bool jobParm(const char* name, u_int v);
247 bool jobParm(const char* name, float v);
248 bool jobSendTime(const struct tm tm);
249 bool jobLastTime(u_long);
250 bool jobRetryTime(u_long);
251 bool jobCover(const char* docname);
252 bool jobDocument(const char* docname);
253 bool jobPollRequest(const char* sep, const char* pwd);
254 /*
255 * Job group control support.
256 */
257 bool jgrpSubmit(const char* jgrpid);
258 bool jgrpSuspend(const char* jgrpid);
259 bool jgrpKill(const char* jgrpid);
260 bool jgrpWait(const char* jgrpid);
261 /*
262 * Query/set transfer state parameters.
263 */
264 u_int getType(void) const;
265 bool setType(u_int);
266 u_int getMode(void) const;
267 bool setMode(u_int);
268 u_int getStruct(void) const;
269 bool setStruct(u_int);
270 u_int getFormat(void) const;
271 bool setFormat(u_int);
272 u_int getTimeZone(void) const;
273 bool setTimeZone(u_int);
274 /*
275 * Send documents to the server.
276 */
277 bool storeUnique(fxStr& docname, fxStr& emsg); // STOU
278 bool storeTemp(fxStr& docname, fxStr& emsg); // STOT
279 bool storeFile(fxStr&, fxStr& emsg); // STOR
280 bool sendData(int fd, bool (FaxClient::*store)(fxStr&, fxStr&),
281 fxStr& docname, fxStr& emsg);
282 bool sendZData(int fd, bool (FaxClient::*store)(fxStr&, fxStr&),
283 fxStr& docname, fxStr& emsg);
284 /*
285 * Retrieve information from the server.
286 */
287 bool recvData(bool (*f)(int, const char*, int, fxStr&),
288 int arg, fxStr& emsg, u_long restart, const char* fmt, ...);
289 bool recvZData(bool (*f)(void*, const char*, int, fxStr&),
290 void* arg, fxStr& emsg, u_long restart, const char* fmt, ...);
291 /*
292 * Job scripting support.
293 */
294 bool runScript(const char* filename, fxStr& emsg);
295 bool runScript(FILE*, const char* filename, fxStr& emsg);
296 bool runScript(const char* script, u_long scriptLen,
297 const char* filename, fxStr& emsg);
298 /*
299 * Status query support.
300 */
301 static const FaxFmtHeader jobFormats[];
302 static const FaxFmtHeader recvFormats[];
303 static const FaxFmtHeader modemFormats[];
304 static const FaxFmtHeader fileFormats[];
305
306 bool setJobStatusFormat(const char*);
307 const fxStr& getJobStatusFormat(void);
308 bool setRecvStatusFormat(const char*);
309 const fxStr& getRecvStatusFormat(void);
310 bool setModemStatusFormat(const char*);
311 const fxStr& getModemStatusFormat(void);
312 bool setFileStatusFormat(const char*);
313 const fxStr& getFileStatusFormat(void);
314 void getJobStatusHeader(fxStr& header);
315 void getRecvStatusHeader(fxStr& header);
316 void getModemStatusHeader(fxStr& header);
317 void getFileStatusHeader(fxStr& header);
318 };
319
getSenderName(void)320 inline const fxStr& FaxClient::getSenderName(void) const{ return senderName; }
getUserName(void)321 inline const fxStr& FaxClient::getUserName(void) const { return userName; }
getHost(void)322 inline const fxStr& FaxClient::getHost(void) const { return host; }
getModem(void)323 inline const fxStr& FaxClient::getModem(void) const { return modem; }
getProtoName()324 inline const fxStr& FaxClient::getProtoName() const { return proto; }
getVerbose(void)325 inline bool FaxClient::getVerbose(void) const
326 { return (state&FS_VERBOSE) != 0; }
getPort(void)327 inline int FaxClient::getPort(void) const { return port; }
getCtrlFd(void)328 inline FILE* FaxClient::getCtrlFd(void) const { return fdOut; }
getDataFd(void)329 inline int FaxClient::getDataFd(void) const { return fdData; }
getLastResponse(void)330 inline const fxStr& FaxClient::getLastResponse(void) const
331 { return lastResponse; }
getLastContinuation(void)332 inline const fxStr& FaxClient::getLastContinuation(void) const
333 { return lastContinuation; }
getLastCode(void)334 inline int FaxClient::getLastCode(void) const { return code; }
isLoggedIn(void)335 inline bool FaxClient::isLoggedIn(void) const
336 { return (state&FS_LOGGEDIN) != 0; }
isConnected(void)337 inline bool FaxClient::isConnected(void) const { return fdIn != NULL; }
isPassive(void)338 inline bool FaxClient::isPassive(void) const { return pasv; }
getType(void)339 inline u_int FaxClient::getType(void) const { return type; }
getStruct(void)340 inline u_int FaxClient::getStruct(void) const { return stru; }
getMode(void)341 inline u_int FaxClient::getMode(void) const { return mode; }
getFormat(void)342 inline u_int FaxClient::getFormat(void) const { return format; }
getTimeZone(void)343 inline u_int FaxClient::getTimeZone(void) const { return tzone; }
getCurrentJob(void)344 inline const fxStr& FaxClient::getCurrentJob(void) const{ return curjob; }
345
346 extern void fxFatal(const char* fmt, ...);
347 #endif /* _FaxClient_ */
348