[r2332]: / trunk / hfaxd / HylaFAXServer.h  Maximize  Restore  History

Download this file

662 lines (596 with data), 25.6 kB

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