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