1 /* $Id$ */
2 /*
3 * Copyright (c) 1995-1996 Sam Leffler
4 * Copyright (c) 1995-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 _HylaFAXServer_
27 #define _HylaFAXServer_
28
29 #include "FaxConfig.h"
30 #include "IOHandler.h"
31 #include "Dictionary.h"
32 #include "StrArray.h"
33 #include "FaxRequest.h"
34 #include "FaxRecvInfo.h"
35 #include "manifest.h"
36 #include "FileCache.h"
37 #include "Trace.h"
38 #include "Trigger.h"
39 #include "StackBuffer.h"
40 #include "SystemLog.h"
41
42 #include "config.h"
43
44 #include <sys/types.h>
45 #include <sys/socket.h>
46 #include <dirent.h>
47
48 #include <setjmp.h>
49 #include <errno.h>
50
51 /*
52 * In-memory copy of a job description file.
53 */
54 struct Job : public FaxRequest {
55 time_t lastmod; // last file modify time, for updates
56 bool queued; // for SNPP
57
58 Job(const fxStr& qf, int fd = -1);
59 ~Job();
60
61 bool checkDocument(const char* pathname);
62 };
63 fxDECLARE_StrKeyDictionary(JobDict, Job*)
64
65 /*
66 * Received facsimile information.
67 */
68 struct RecvInfo : public FaxRecvInfo {
69 bool beingReceived; // currently being received
70 time_t recvTime; // time receive operation started
71
72 RecvInfo();
73 RecvInfo(const char* qfile);
74 ~RecvInfo();
75 };
fxDECLARE_StrKeyDictionary(RecvInfoDict,RecvInfo *)76 fxDECLARE_StrKeyDictionary(RecvInfoDict, RecvInfo*)
77
78 /*
79 * An array of content that can sort on a different key
80 */
81 class KeyString
82 : public fxStr
83 {
84 public:
85 KeyString ();
86 KeyString (const fxStr& key, const fxStr& data);
87
88 int compare (const KeyString* that) const;
89
90 private:
91 fxStr key;
92 };
93 fxDECLARE_ObjArray(KeyStringArray, KeyString);
94
95
96 #ifdef T_USER
97 #undef T_USER // XXX FreeBSD defines this
98 #endif
99
100 /*
101 * Parser tokens; also used to identify protocol commands/operations.
102 */
103 enum Token {
104 /*
105 * Syntactic items.
106 */
107 T_SP, T_CRLF, T_COMMA, T_STRING, T_NUMBER,
108 T_NIL, T_LEXERR,
109 /*
110 * Commands.
111 */
112 T_ABOR, T_ACCT, T_ADDMODEM, T_ADDUSER, T_ADMIN,
113 T_ALLO, T_ANSWER, T_APPE, T_CHMOD, T_CHOWN,
114 T_CONFIG, T_CWD, T_CDUP, T_DELE, T_DELUSER,
115 T_DELMODEM, T_DISABLE, T_ENABLE, T_EPSV, T_EPRT, T_FILEFMT, T_FILESFMT, T_FORM,
116 T_HELP, T_IDLE, T_LOCKWAIT, T_JDELE, T_JGDELE, T_JGINTR,
117 T_JGKILL, T_JGNEW, T_JGPARM, T_JGREST, T_JGRP,
118 T_JGSUB, T_JGSUSP, T_JGWAIT, T_JINTR, T_JKILL,
119 T_JNEW, T_JOB, T_JOBFMT, T_JOBSFMT, T_JPARM, T_JREST,
120 T_JSUB, T_JSUSP, T_JWAIT, T_LIST, T_MDTM,
121 T_MODE, T_MODEMFMT, T_MODEMSFMT, T_NLST, T_NOOP, T_PASS,
122 T_PASV, T_PORT, T_PWD, T_QUIT, T_RCVFMT, T_RCVSFMT,
123 T_REIN, T_REST, T_RETP, T_RETR, T_RNFR,
124 T_RNTO, T_SHUT, T_SITE, T_SIZE, T_STAT,
125 T_STOR, T_STOT, T_STOU, T_STRU, T_SYST,
126 T_TRIGGER, T_TYPE, T_TZONE, T_USER, T_VRFY,
127 /*
128 * Job state parameters.
129 */
130 T_ACCTINFO, T_BEGBR, T_BEGST, T_CHOPTHRESH, T_CLIENT,
131 T_COMMENTS, T_COMMID, T_COVER, T_DATAFORMAT, T_DIALSTRING,
132 T_DOCUMENT, T_DONEOP, T_EXTERNAL, T_FAXNUMBER, T_FROM_COMPANY, T_FROM_LOCATION,
133 T_FROM_USER, T_FROM_VOICE, T_GROUPID, T_HRES, T_JOBID,
134 T_JOBINFO, T_JOBTYPE, T_LASTTIME, T_MAXDIALS, T_MAXPAGES,
135 T_MAXTRIES, T_MINBR, T_MODEM, T_NDIALS, T_NOTIFY,
136 T_NOTIFYADDR,T_NPAGES, T_NTRIES, T_OWNER, T_PAGECHOP,
137 T_PAGELENGTH,T_PAGEWIDTH, T_PAGERANGE, T_PASSWD, T_POLL, T_REGARDING,
138 T_RETRYTIME, T_SCHEDPRI, T_SENDTIME, T_STATE, T_STATUS, T_STATUSCODE, T_ERRORCODE,
139 T_SUBADDR, T_TAGLINE, T_TOTDIALS, T_TOTPAGES, T_TOTTRIES,
140 T_TO_COMPANY,T_TO_LOCATION, T_TO_USER, T_TO_VOICE, T_TSI, T_USE_CONTCOVER,
141 T_USE_ECM, T_USE_TAGLINE, T_USE_XVRES, T_USRKEY, T_VRES,
142 /*
143 * SNPP tokens.
144 */
145 T_2WAY, T_ACKREAD, T_ALERT, T_CALLERID, T_COVERAGE,
146 T_DATA, T_EXPTAG, T_HOLDUNTIL, T_JQUEUE, T_KTAG,
147 T_LEVEL, T_LOGIN, T_MCRESPONSE, T_MESSAGE, T_MSTATUS,
148 T_NOQUEUEING,T_PAGER, T_PING, T_RTYPE, T_SEND,
149 T_SUBJECT
150 };
151
152 struct tab { // protocol command table entry
153 const char* name;
154 Token token;
155 bool checklogin; // if true, must be logged in first
156 bool implemented; // false if command is not implemented
157 const char* help;
158 };
159
160 class SpoolDir;
161 struct ParamProtection;
162
163 struct stat;
164 typedef struct tiff TIFF;
165 class JobExt;
166 class ModemExt;
167 class ModemConfig;
168 class IDCache;
169
170 extern const char* fmtTime(time_t t);
171
172 /*
173 * An instance of a fax server process.
174 */
175 class HylaFAXServer : public SystemLog, public FaxConfig, public IOHandler {
176 public:
177 struct stringtag {
178 const char* name;
179 fxStr HylaFAXServer::* p;
180 const char* def; // NULL is shorthand for ""
181 };
182 struct numbertag {
183 const char* name;
184 u_int HylaFAXServer::*p;
185 u_int def;
186 };
187 struct booltag {
188 const char* name;
189 bool HylaFAXServer::*p;
190 bool def;
191 };
192 static int _debugSleep;
193 protected:
194 u_int state;
195 #define S_LOGGEDIN 0x0001 // client is logged in
196 #define S_PRIVILEGED 0x0002 // client has administrative privileges
197 #define S_LREPLIES 0x0004 // using continuation msgs in replies
198 #define S_WAITFIFO 0x0008 // waiting on response to FIFO msg
199 #define S_USEGMT 0x0010 // process times in GMT or local TZ
200 #define S_WAITPASS 0x0020 // had user command, waiting for passwd
201 #define S_TRANSFER 0x0040 // actively transferring data
202 #define S_WAITDATA 0x0080 // scanner is waiting for data
203 #define S_WAITTRIG 0x0100 // trigger is active
204 #define S_LOGTRIG 0x0200 // write trigger events to data conn
205 #define S_CHECKGID 0x0400 // check if file GID is set correctly
206 #define S_SETGID 0x0800 // must explicitly force GID on files
207 u_int tracingLevel; // server tracing control flags
208 fxStr logFacility; // name of syslog facility for logging
209 fxStr userAccessFile; // user access control file
210 fxStr xferfaxLogFile; // log file for data transfers
211 fxStr faxContact; // email account for inquiries
212 fxStr systemType; // system ID string returned for SYST
213 fxStr faxqFIFOName; // faxq FIFO name
214 fxStr clientFIFOName; // client FIFO name
215 int faxqFd; // faxq FIFO open descriptor
216 int clientFd; // client FIFO open descriptor
217 fxStr fifoResponse; // response received to FIFO msg
218 u_int idleTimeout; // client inactivity timeout
219 u_int maxIdleTimeout; // upper bound on idle timeout
220 u_int lockTimeout; // qfile lock timeout
221 u_int maxLockTimeout; // upper bound on qfile lock timeout
222 int data; // current data connection (socket)
223 int pdata; // passive mode data connect (socket)
224 fxStr hostname; // name of machine server is running on
225 fxStr hostaddr; // primary address for hostname
226 fxStr remotehost; // name of peer's machine
227 fxStr remoteaddr; // address of peer's machine
228 fxStr autospout; // text to send with next reply
229 fxStr shutdownFile; // file with shutdown information
230 fxStr shutdownMsg; // text of shutdown message
231 time_t lastModTime; // last mod. time of shutdown file
232 time_t lastTime; // time of last shutdown notification
233 time_t discTime; // time to disconnect service
234 time_t denyTime; // time to deny service
235 u_int jobProtection; // Protection to use on Jobs
236 bool publicJobQ; // Public/protection on recvq?
237 bool publicRecvQ; // Public/protection on recvq?
238 bool allowSorting; // Allow client to make us sort
239 /*
240 * User authentication and login-related state.
241 */
242 fxStr passwd; // encrypted user password
243 fxStr adminwd; // encrypted passwd for admin privileges
244 u_int uid; // client's ID
245 u_int loginAttempts; // number of failed login attempts
246 u_int maxLoginAttempts; // login failures before server exits
247 u_int adminAttempts; // number of failed admin attempts
248 u_int maxAdminAttempts; // admin failures before server exits
249 fxStr the_user; // name of user
250 fxStr admingroup; // name of local user group that is allowed
251 // to administer the fax server
252 IDCache* idcache; // fax UID -> name mapping table
253 /*
254 * File and file-transfer related state.
255 */
256 off_t restart_point; // file offset for restarting transfers
257 jmp_buf urgcatch; // throw location for transfer interrupt
258 off_t file_size; // size of file being transferred
259 off_t byte_count; // amount of data currently sent
260 int xferfaxlog; // open transfer log file
261 int mode; // data transfer mode
262 int form; // data transfer format
263 int type; // data transfer type
264 int stru; // file structure
265 SpoolDir* cwd; // current working directory
266 fxStrArray tempFiles; // files created with STOT
267 fxStr fileFormat; // format string for directory listings
268 fxStr fileSortFormat; // format string for directory listings
269 TIFF* cachedTIFF; // cached open TIFF file
270 /*
271 * Parser-related state.
272 */
273 Token pushedToken; // lexical token push back
274 fxStr tokenBody; // string body of current lexical token
275 char cbuf[512]; // current input line
276 int cpos; // position in cbuf
277 int ctrlFlags; // file descriptor flags for control
278 int recvCC; // amount of data remaining in recvBuf
279 int recvNext; // next byte for scanner
280 char recvBuf[1024]; // input data buffer
281 u_int consecutiveBadCmds; // # consecutive invalid control cmds
282 u_int maxConsecutiveBadCmds; // max # before forced disconnect
283 /*
284 * Job-related state.
285 */
286 Job defJob; // default job state information
287 JobDict jobs; // non-default jobs
288 Job* curJob; // current job
289 fxStr jobFormat; // job status format string
290 fxStr jobSortFormat; // job status format string
291 JobDict blankJobs; // jobs created during this session but not submitted
292 /*
293 * Receive queue-related state.
294 */
295 RecvInfoDict recvq; // cache of info about received fax
296 fxStr recvFormat; // received fax status format string
297 fxStr recvSortFormat; // received fax status format sort key
298 /*
299 * Trigger-related state.
300 */
301 fxStr trigSpec; // specification for active trigger
302 u_int tid; // current active trigger ID
303 /*
304 * Modem-related state.
305 */
306 fxStr modemFormat; // modem status format string
307 fxStr modemSortFormat; // modem status format string
308
309 static gid_t faxuid; // system gid of fax user = our uid
310 #if HAS_TM_ZONE
311 const char* tzname[2]; // local timezone name
312 #endif
313 time_t gmtoff; // time_t offset btwn GMT and local time
314
315 void userCmd(const char* name); // USER
316 void adminCmd(const char* name); // ADMIN
317 void passCmd(const char* passwd); // PASS
318 void statusCmd(void); // STAT
319
320 void formCmd(const char* name); // FORM
321 void formHelpCmd(void); // FORM
322 void typeCmd(const char* name); // TYPE
323 void modeCmd(const char* name); // MODE
324 void struCmd(const char* name); // STRU
325 void deleCmd(const char* name); // DELE
326 void mdtmCmd(const char* name); // MDTM
327 void cwdCmd(const char *path); // CWD
328 void pwdCmd(void); // PWD
329 void retrieveCmd(const char* name); // RETR
330 void retrievePageCmd(const char* name);// RETP
331 void listCmd(const char* name); // LIST
332 void nlstCmd(const char* name); // NLST
333 void storeCmd(const char*, const char*);// STOR+APPE
334 void storeUniqueCmd(bool isTemp); // STOU+STOT
335 void statFileCmd(const char* name); // STAT
336 void chownCmd(const char*, const char*);// CHOWN
337 void chmodCmd(const char*, u_int); // CHMOD
338
339 virtual void passiveCmd(void) = 0; // PASV: depends on transport
340 virtual void portCmd(Token) = 0; // PORT: depends on transport
341
342 void triggerCmd(const char*, ...); // TRIGGER
343
344 /*
345 * Administrative commands (experimental).
346 */
347 void abortCallCmd(const char*);
348 void addUserCmd(const char* spec, const char* pass, const char* apass);
349 void delUserCmd(const char* spec);
350 void answerCallCmd(const char* modem, const char* how);
351 void disableModemCmd(const char* modem, const char* reason);
352 void enableModemCmd(const char* mode);
353 void shutCmd(const struct tm& when, const char* reason);
354 void addModemCmd(const char* modem);
355 void delModemCmd(const char* modem);
356 void configQueryCmd(const char* where);
357 void configCmd(const char* where, const char* info);
358
359 virtual void initServer(void);
360 bool readShutdownFile(void);
361 bool isShutdown(bool quiet);
362 void fatal(const char *fmt, ...);
363 void reply(int code, const char* fmt, ...);
364 void vreply(int code, const char* fmt, va_list ap);
365 void lreply(int code, const char* fmt, ...);
366 void vlreply(int code, const char* fmt, va_list ap);
367 void perror_reply(int code, const char* string, int errnum);
368 void ack(int code, const char*);
369 void printTransferStatus(FILE* fd);
370 struct tm* cvtTime(const time_t&) const;
371 void setFileOwner(const char* filename);
372
373 void loginRefused(const char* why);
374
375 bool checkUser(const char*);
376 bool checkPasswd(const char*);
377
378 bool checkuserHosts(FILE*, const char *name);
379 bool checkuserPAM(const char *name);
380
381 bool checkpasswdHosts(const char* passwd);
382 bool checkpasswdPAM(const char* passwd);
383
384 bool isAdminGroup(const char* user=NULL);
385
386 void login(int code);
387 void end_login(void);
388 virtual void dologout(int status);
389 const char* fixPathname(const char* file);
390 const char* userName(u_int uid);
391 bool userID(const char*, u_int& id);
392 void fillIDCache(void);
393
394 bool cvtPasswd(const char* type, const char* pass, fxStr& result);
395 bool findUser(FILE* db, const char* user, u_int& newuid);
396 bool addUser(FILE* db, const char* user, u_int uid,
397 const char* upass, const char* apass);
398 bool deleteUser(FILE* db, const char* user);
399
400 /*
401 * Configuration file support.
402 */
403 static stringtag strings[];
404 static numbertag numbers[];
405 static booltag booleans[];
406
407 void resetConfig();
408 void setupConfig();
409 void configError(const char* fmt, ...);
410 void configTrace(const char* fmt, ...);
411 bool setConfigItem(const char* tag, const char* value);
412
413 bool restartSend(FILE* fd, off_t marker);
414
415 static SpoolDir dirs[];
416
417 bool checkFileRights(int op, const struct stat&);
418
419 void dirSetup(void);
420 static SpoolDir* dirLookup(const char* path);
421 static SpoolDir* dirLookup(ino_t ino);
422 SpoolDir* dirAccess(const char* path);
423 SpoolDir* fileAccess(const char* path, int op, struct stat&);
424 bool fileVisible(const SpoolDir&, const char*, const struct stat&);
425
426 bool isVisibleRecvQFile(const char*, const struct stat&);
427 void listRecvQ(FILE* fd, const SpoolDir& sd, DIR* dir);
428 void listRecvQFile(FILE*, const SpoolDir&, const char*, const struct stat&);
429
430 bool isVisibleSendQFile(const char*, const struct stat&);
431 void listSendQ(FILE* fd, const SpoolDir& sd, DIR* dir);
432 void listSendQFile(FILE*, const SpoolDir&, const char*, const struct stat&);
433 void nlstSendQ(FILE* fd, const SpoolDir& sd, DIR* dir);
434 void nlstSendQFile(FILE*, const SpoolDir&, const char*, const struct stat&);
435
436 void listStatus(FILE* fd, const SpoolDir& sd, DIR* dir);
437 void listStatusFile(FILE*, const SpoolDir&, const char*, const struct stat&);
438 void nlstStatus(FILE* fd, const SpoolDir& sd, DIR* dir);
439
440 bool isVisibletrue(const char*, const struct stat&);
441 bool isVisibleDocQFile(const char*, const struct stat&);
442 bool isVisibleRootFile(const char*, const struct stat&);
443
444 void listDirectory(FILE* fd, const SpoolDir& sd, DIR* dir);
445 void listUnixFile(FILE*, const SpoolDir&, const char*, const struct stat&);
446 void makeProt(const struct stat& sb, bool withGrp, char prot[10]);
447 void Fprintf(FILE*, const char* fmt, const char*, const struct stat&);
448 void Fprintf(fxStackBuffer&, const char* fmt, const char*, const struct stat&);
449
450 void nlstDirectory(FILE* fd, const SpoolDir& sd, DIR* dir);
451 void nlstUnixFile(FILE*, const SpoolDir&, const char*, const struct stat&);
452
453 virtual FILE* openDataConn(const char* mode, int& code) = 0;
454 static const char* dataConnMsg(int code);
455 virtual void closeDataConn(FILE*);
456
457 bool sendData(FILE* fdin, FILE* fdout);
458 bool sendIData(int fdin, int fdout);
459 bool sendZData(int fdin, int fdout);
460 bool recvData(FILE* instr, FILE* outstr);
461 bool recvIData(int fdin, int fdout);
462 bool recvZData(int fdin, int fdout);
463
464 TIFF* openTIFF(const char* name);
465 bool sendTIFFData(TIFF* tif, FILE* fdout);
466 bool sendTIFFHeader(TIFF* tif, int fdout);
467 bool sendITIFFData(TIFF* tif, int fdout);
468
469 void logTransfer(const char*, const SpoolDir&, const char*, time_t);
470
471 virtual int parse(void);
472 bool cmd(Token t);
473 bool site_cmd(Token t);
474 bool param_cmd(Token t);
475 bool string_param(fxStr&, const char* what = NULL);
476 bool number_param(long&);
477 bool boolean_param(bool&);
478 bool file_param(fxStr& pathname);
479 bool pwd_param(fxStr& s);
480 bool timespec_param(int ndigits, time_t& t);
481 bool pathname_param(fxStr& pathname);
482 bool job_param(fxStr& jid);
483 bool jgrp_param(fxStr& jgid);
484 bool pathname(fxStr& s);
485 bool CRLF();
486 bool SPACE();
487 bool COMMA();
488 bool TIMESPEC(u_int len, time_t& result);
489 bool BOOLEAN(bool& b);
490 bool STRING(fxStr& s, const char* what = NULL);
491 bool NUMBER(long& n);
492 bool checkNUMBER(const char* s);
493 bool opt_CRLF();
494 bool opt_STRING(fxStr& s);
495 bool multi_STRING(fxStr& s);
496 static u_int twodigits(const char* cp, u_int range);
497 static u_int fourdigits(const char* cp);
498 virtual void syntaxError(const char* msg);
499
500 virtual void netStatus(FILE*) = 0; // depends on transport
501 virtual bool hostPort() = 0; // depends on transport
502
503 int getChar(bool waitForInput);
504 void pushCmdData(const char* data, int n);
505 bool getCmdLine(char* s, int n, bool waitForInput = false);
506 void pushToken(Token t);
507 Token nextToken(void);
508 bool checkToken(Token);
509 bool getToken(Token, const char*);
510 void helpCmd(const tab* ctab, const char* s);
511 void logcmd(Token t, const char* fmt = NULL, ...);
512 void cmdFailure(Token t, const char* why);
513 bool checklogin(Token);
514 bool checkadmin(Token);
515
516 static const char* version;
517
518 virtual const char* cmdToken(Token t);
519 virtual const char* siteToken(Token t);
520 static const char* parmToken(Token t);
521
522 bool initClientFIFO(fxStr& emsg);
523 int FIFOInput(int fd);
524 void FIFOMessage(const char* cp, u_int len);
525 bool sendModem(const char* modem, fxStr& emsg, const char* fmt ...);
526 bool sendQueuerMsg(fxStr& emsg, const fxStr& msg);
527 bool sendQueuer(fxStr& emsg, const char* fmt ...);
528 bool sendQueuerACK(fxStr& emsg, const char* fmt, ...);
529 bool vsendQueuerACK(fxStr& emsg, const char* fmt, va_list ap);
530
531 bool newTrigger(fxStr& emsg, const char* fmt, ...);
532 bool vnewTrigger(fxStr& emsg, const char* fmt, va_list ap);
533 bool loadTrigger(fxStr& emsg);
534 bool cancelTrigger(fxStr& emsg);
535 void triggerEvent(const TriggerMsgHeader& h, const char* data);
536 void logEventMsg(const TriggerMsgHeader&h, fxStr& msg);
537 void logJobEventMsg(const TriggerMsgHeader&, const JobExt&);
538 void logSendEventMsg(const TriggerMsgHeader&, const JobExt&, const char*);
539 void logModemEventMsg(const TriggerMsgHeader&,
540 const ModemExt&, const char*);
541 void logRecvEventMsg(const TriggerMsgHeader&,
542 const FaxRecvInfo&, const char*);
543
544 virtual void initDefaultJob(void);
545 void parmBotch(Token t);
546 bool checkAccess(const Job& job, Token t, u_int op);
547 bool checkParm(Job&, Token t, u_int op);
548 bool checkJobState(Job*);
549 void replyJobParamValue(Job&, int code, Token t);
550 void replyBoolean(int code, bool b);
551 bool setValue(u_short& v, const char* value, const char* what,
552 const char* valNames[], u_int nValNames);
553 void flushPreparedDocuments(Job& job);
554 bool setJobParameter(Job&, Token t, const fxStr& value);
555 bool setJobParameter(Job&, Token t, u_short value);
556 bool setJobParameter(Job&, Token t, time_t value);
557 bool setJobParameter(Job&, Token t, bool b);
558 bool setJobParameter(Job&, Token t, float value);
559 bool docType(const char* docname, FaxSendOp& op);
560 bool checkAddDocument(Job&, Token type, const char* docname, FaxSendOp&);
561 void addCoverDocument(Job&, const char* docname);
562 void addDocument(Job&, const char* docname);
563 void addPollOp(Job&, const char* sep, const char* pwd);
564 void newJobCmd(void);
565 bool newJob(fxStr& emsg);
566 Job* findJob(const char* jobid, fxStr& emsg);
567 Job* findJobInMemmory(const char* jobid);
568 Job* findJobOnDisk(const char* jobid, fxStr& emsg);
569 bool updateJobFromDisk(Job& job);
570 void replyCurrentJob(const char* leader);
571 void setCurrentJob(const char* jobid);
572 Job* preJobCmd(const char* op, const char* jobid, fxStr& emsg);
573 void operateOnJob(const char* jobid, const char* what, const char* op);
574 void deleteJob(const char* jobid);
575 void killJob(const char* jobid);
576 void replyBadJob(const Job& job, Token t);
577 void resetJob(const char* jobid);
578 void interruptJob(const char* jobid);
579 void suspendJob(const char* jobid);
580 void submitJob(const char* jobid);
581 void waitForJob(const char* jobid);
582 bool updateJobOnDisk(Job& req, fxStr& emsg);
583 bool lockJob(Job& job, int how, fxStr& emsg);
584 bool lockJob(Job& job, int how);
585 void unlockJob(Job& job);
586 void purgeJobs(void);
587 void jstatCmd(const Job&);
588 void jstatLine(Token t, const char* fmt ...);
589
590 const char* compactTime(time_t t);
591 void Jprintf(FILE* fd, const char* fmt, const Job& job);
592 void Jprintf(fxStackBuffer& buf, const char* fmt, const Job& job);
593
594 u_int getJobNumber(fxStr&);
595 u_int getDocumentNumber(fxStr&);
596
597 bool getRecvDocStatus(RecvInfo& ri);
598 RecvInfo* getRecvInfo(const fxStr& qfile, const struct stat& sb);
599 const char* compactRecvTime(time_t t);
600 void Rprintf(FILE*, const char*, const RecvInfo&, const struct stat&);
601 void Rprintf(fxStackBuffer&, const char*, const RecvInfo&, const struct stat&);
602
603 void getServerStatus(const char* fileName, fxStr& status);
604 void Mprintf(FILE*, const char*, const ModemConfig&);
605 void Mprintf(fxStackBuffer&, const char*, const ModemConfig&);
606 public:
607 HylaFAXServer();
608 virtual ~HylaFAXServer();
609
610 static void setupPermissions(void);
611 static void closeAllBut(int fd);
612 static void closeAllDispatched();
613
614 static void sanitize(fxStr& s);
615 static void canonModem(fxStr& s);
616 static void canonDevID(fxStr& s);
617
618 virtual void open(void);
619 virtual void close(void);
620
621 virtual int inputReady(int);
622 void timerExpired(long, long);
623 };
pushToken(Token t)624 inline void HylaFAXServer::pushToken(Token t) { pushedToken = t; }
625
626 /*
627 * Directories in the spooling area are treated
628 * specially to hide implementation details and
629 * privileged information that clients have no
630 * business seeing. Also we implement an access
631 * control system that is built on top of the
632 * normal UNIX protection mechanisms.
633 */
634 struct SpoolDir {
635 const char* pathname;
636 bool adminOnly; // accessible by unprivileged clients
637 bool storAble; // unprivileged clients may STOR files
638 bool deleAble; // unprivileged clients may DELE files
639 ino_t ino; // directory inode number
640 bool (HylaFAXServer::*isVisibleFile)(const char*, const struct stat&);
641 void (HylaFAXServer::*listDirectory)(FILE*, const SpoolDir&, DIR*);
642 void (HylaFAXServer::*listFile)(FILE*, const SpoolDir&,
643 const char*, const struct stat&);
644 void (HylaFAXServer::*nlstDirectory)(FILE*, const SpoolDir&, DIR*);
645 void (HylaFAXServer::*nlstFile)(FILE*, const SpoolDir&,
646 const char*, const struct stat&);
647 void (HylaFAXServer::*delFile)(const SpoolDir&, const char*);
648 void (HylaFAXServer::*retrFile)(const SpoolDir&, const char*);
649 void (HylaFAXServer::*storFile)(const SpoolDir&, const char*);
650 };
651
652 #define IS(x) ((state & (S_##x)) != 0)
653
654 #endif /* _HylaFAXServer_ */
655