SendFaxJob.c++
上传用户:weiyuanprp
上传日期:2020-05-20
资源大小:1169k
文件大小:19k
源码类别:

传真(Fax)编程

开发平台:

C/C++

  1. /* $Id: SendFaxJob.c++,v 1.9 2008/09/14 10:33:17 faxguy Exp $ */
  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. #include "config.h"
  27. #include "Sys.h"
  28. #include <ctype.h>
  29. #include <string.h>
  30. #include <errno.h>
  31. #if CONFIG_INETTRANSPORT
  32. extern "C" {
  33. #include <sys/socket.h>
  34. #include <netinet/in.h>
  35. #include <netdb.h>            // XXX
  36. }
  37. #endif
  38. #include "SendFaxClient.h"
  39. #include "PageSize.h"
  40. #include "FaxConfig.h"
  41. SendFaxJob::SendFaxJob()
  42. {
  43. }
  44. SendFaxJob::SendFaxJob(const SendFaxJob& other)
  45.     : jobtag(other.jobtag)
  46.     , mailbox(other.mailbox)
  47.     , number(other.number)
  48.     , subaddr(other.subaddr)
  49.     , passwd(other.passwd)
  50.     , external(other.external)
  51.     , coverFile(other.coverFile)
  52.     , coverTemplate(other.coverTemplate)
  53.     , name(other.name)
  54.     , voicenumber(other.voicenumber)
  55.     , location(other.location)
  56.     , company(other.company)
  57.     , comments(other.comments)
  58.     , regarding(other.regarding)
  59.     , fromlocation(other.fromlocation)
  60.     , fromfax(other.fromfax)
  61.     , fromvoice(other.fromvoice)
  62.     , fromcompany(other.fromcompany)
  63.     , killTime(other.killTime)
  64.     , sendTime(other.sendTime)
  65.     , tagline(other.tagline)
  66.     , pageSize(other.pageSize)
  67. {
  68.     notify = other.notify;
  69.     autoCover = other.autoCover;
  70.     coverIsTemp = other.coverIsTemp;
  71.     sendTagLine = other.sendTagLine;
  72.     useXVRes = other.useXVRes;
  73.     retryTime = other.retryTime;
  74.     hres = other.hres;
  75.     vres = other.vres;
  76.     pageWidth = other.pageWidth;
  77.     pageLength = other.pageLength;
  78.     maxRetries = other.maxRetries;
  79.     maxDials = other.maxDials;
  80.     priority = other.priority;
  81.     minsp = other.minsp;
  82.     desiredbr = other.desiredbr;
  83.     desiredst = other.desiredst;
  84.     desiredec = other.desiredec;
  85.     desireddf = other.desireddf;
  86.     pagechop = other.pagechop;
  87.     chopthreshold = other.chopthreshold;
  88.     skippages = other.skippages;
  89.     skippedpages = other.skippedpages;
  90.     nocountcover = other.nocountcover;
  91.     serverdocover = other.serverdocover;
  92.     ignoremodembusy = other.ignoremodembusy;
  93. }
  94. SendFaxJob::~SendFaxJob()
  95. {
  96.     if (coverFile != "" && coverIsTemp)
  97. Sys::unlink(coverFile);
  98. }
  99. /*
  100.  * Configuration file support.
  101.  */
  102. #define N(a) (sizeof (a) / sizeof (a[0]))
  103. SendFaxJob::SFJ_stringtag SendFaxJob::strings[] = {
  104. { "tagline", &SendFaxJob::tagline, NULL },
  105. { "sendtime", &SendFaxJob::sendTime, NULL },
  106. { "killtime", &SendFaxJob::killTime, FAX_TIMEOUT },
  107. { "pagesize", &SendFaxJob::pageSize, "default" },
  108. { "jobtag", &SendFaxJob::jobtag, NULL },
  109. { "subaddress", &SendFaxJob::subaddr, NULL },
  110. { "password", &SendFaxJob::passwd, NULL },
  111. { "cover-template", &SendFaxJob::coverTemplate, NULL },
  112. { "cover-comments", &SendFaxJob::comments, NULL },
  113. { "cover-regarding", &SendFaxJob::regarding, NULL },
  114. { "cover-company", &SendFaxJob::company, NULL },
  115. { "cover-location", &SendFaxJob::location, NULL },
  116. { "cover-voice", &SendFaxJob::voicenumber, NULL },
  117. { "cover-from-location", &SendFaxJob::fromlocation, NULL },
  118. { "cover-from-fax", &SendFaxJob::fromfax, NULL },
  119. { "cover-from-voice", &SendFaxJob::fromvoice, NULL },
  120. { "cover-from-company", &SendFaxJob::fromcompany, NULL },
  121. };
  122. SendFaxJob::SFJ_numbertag SendFaxJob::numbers[] = {
  123. { "maxtries", &SendFaxJob::maxRetries, FAX_RETRIES },
  124. { "maxdials", &SendFaxJob::maxDials, FAX_REDIALS },
  125. { "skippages", &SendFaxJob::skippages, 0 },
  126. { "skippedpages", &SendFaxJob::skippedpages, 0 },
  127. { "nocountcover", &SendFaxJob::nocountcover, 0 },
  128. };
  129. SendFaxJob::SFJ_floattag SendFaxJob::floats[] = {
  130. { "hres", &SendFaxJob::hres, 204. },
  131. { "vres", &SendFaxJob::vres, FAX_DEFVRES },
  132. { "pagewidth", &SendFaxJob::pageWidth, 0. },
  133. { "pagelength", &SendFaxJob::pageLength, 0. },
  134. { "chopthreshold", &SendFaxJob::chopthreshold, 3.0 },
  135. };
  136. void
  137. SendFaxJob::setupConfig()
  138. {
  139.     int i;
  140.     for (i = N(strings)-1; i >= 0; i--)
  141. (*this).*strings[i].p = (strings[i].def ? strings[i].def : "");
  142.     for (i = N(numbers)-1; i >= 0; i--)
  143. (*this).*numbers[i].p = numbers[i].def;
  144.     for (i = N(floats)-1; i >= 0; i--)
  145. (*this).*floats[i].p = floats[i].def;
  146.     autoCover = true;
  147.     sendTagLine = false; // default is to use server config
  148.     useXVRes = false; // default is to use normal or fine
  149.     serverdocover = false; // default to do it client-side
  150.     ignoremodembusy = false; // default to acknowledge busy status
  151.     notify = FAX_DEFNOTIFY; // default notification
  152.     mailbox = "";
  153.     priority = FAX_DEFPRIORITY; // default transmit priority
  154.     minsp = (u_int) -1;
  155.     desiredbr = (u_int) -1;
  156.     desiredst = (u_int) -1;
  157.     desiredec = (u_int) -1;
  158.     desireddf = (u_int) -1;
  159.     retryTime = (u_int) -1;
  160.     pagechop = chop_default;
  161. }
  162. bool
  163. SendFaxJob::setConfigItem(const char* tag, const char* value)
  164. {
  165.     u_int ix;
  166.     if (FaxConfig::findTag(tag, (const FaxConfig::tags*) strings, N(strings), ix)) {
  167. (*this).*strings[ix].p = value;
  168. switch (ix) {
  169. case 0: sendTagLine = true; break;
  170. }
  171.     } else if (FaxConfig::findTag(tag, (const FaxConfig::tags*) numbers, N(numbers), ix)) {
  172. (*this).*numbers[ix].p = atoi(value);
  173.     } else if (FaxConfig::findTag(tag, (const FaxConfig::tags*) floats, N(floats), ix)) {
  174. (*this).*floats[ix].p = atof(value);
  175.     } else if (streq(tag, "autocoverpage"))
  176. setAutoCoverPage(FaxConfig::getBoolean(value));
  177.     else if (streq(tag, "notify") || streq(tag, "notification"))
  178. setNotification(value);
  179.     else if (streq(tag, "mailaddr"))
  180. setMailbox(value);
  181.     else if (streq(tag, "priority"))
  182. setPriority(value);
  183.     else if (streq(tag, "minspeed"))
  184. setMinSpeed(value);
  185.     else if (streq(tag, "desiredspeed"))
  186. setDesiredSpeed(value);
  187.     else if (streq(tag, "desiredmst"))
  188. setDesiredMST(value);
  189.     else if (streq(tag, "desiredec"))
  190. setDesiredEC(value);
  191.     else if (streq(tag, "usexvres"))
  192. setUseXVRes(FaxConfig::getBoolean(value));
  193.     else if (streq(tag, "serverdocover"))
  194. setServerDoCover(FaxConfig::getBoolean(value));
  195.     else if (streq(tag, "ignoremodembusy"))
  196. setIgnoreModemBusy(FaxConfig::getBoolean(value));
  197.     else if (streq(tag, "desireddf"))
  198. setDesiredDF(value);
  199.     else if (streq(tag, "retrytime"))
  200. setRetryTime(value);
  201.     else if (streq(tag, "pagechop"))
  202. setChopHandling(value);
  203.     else
  204. return (false);
  205.     return (true);
  206. }
  207. #undef N
  208. #define valeq(a,b) (strcasecmp(a,b)==0)
  209. #define valneq(a,b,n) (strncasecmp(a,b,n)==0)
  210. void SendFaxJob::setDoneOp(const char* v) { doneop = v; }
  211. bool
  212. SendFaxJob::setNotification(const char* v0)
  213. {
  214.     const char* v = v0;
  215.     if (valneq(v, "when", 4)) {
  216. for (v += 4; isspace(*v); v++)
  217.     ;
  218.     }
  219.     if (valeq(v, "done"))
  220. notify = when_done;
  221.     else if (valneq(v, "req", 3))
  222. notify = when_requeued;
  223.     else if (valeq(v, "none") || valeq(v, "off"))
  224. notify = no_notice;
  225.     else if (valeq(v, "default"))
  226. notify = FAX_DEFNOTIFY;
  227.     else
  228. return (false);
  229.     return (true);
  230. }
  231. void SendFaxJob::setNotification(FaxNotify n) { notify = n; }
  232. /*
  233.  * Create the mail address for a local user.
  234.  */
  235. void
  236. SendFaxJob::setMailbox(const char* user)
  237. {
  238.     fxStr acct(user);
  239.     if (acct != "" && acct.next(0, "@!") == acct.length()) {
  240. static fxStr domainName;
  241. if (domainName == "") {
  242.     char hostname[64];
  243.     (void) gethostname(hostname, sizeof (hostname));
  244. #if CONFIG_INETTRANSPORT
  245.     struct hostent* hp = gethostbyname(hostname);
  246.     domainName = (hp ? hp->h_name : hostname);
  247. #else
  248.     domainName = hostname;
  249. #endif
  250. }
  251. mailbox = acct | "@" | domainName;
  252.     } else
  253. mailbox = acct;
  254.     // strip leading & trailing white space
  255.     mailbox.remove(0, mailbox.skip(0, " t"));
  256.     mailbox.resize(mailbox.skipR(mailbox.length(), " t"));
  257. }
  258. void SendFaxJob::setJobTag(const char* s) { jobtag = s; }
  259. void
  260. SendFaxJob::setRetryTime(const char* v)
  261. {
  262.     char* cp;
  263.     u_int t = (u_int) strtoul(v, &cp, 10);
  264.     if (cp) {
  265. while (isspace(*cp))
  266.     ;
  267. if (strncasecmp(cp, "min", 3) == 0)
  268.     t *= 60;
  269. else if (strncasecmp(cp, "hour", 4) == 0)
  270.     t *= 60*60;
  271. else if (strncasecmp(cp, "day", 3) == 0)
  272.     t *= 24*60*60;
  273.     }
  274.     retryTime = t;
  275. }
  276. void SendFaxJob::setRetryTime(u_int v) { retryTime = v; }
  277. void SendFaxJob::setKillTime(const char* s) { killTime = s; }
  278. void SendFaxJob::setSendTime(const char* s) { sendTime = s; }
  279. void SendFaxJob::setMaxRetries(u_int n) { maxRetries = n; }
  280. void SendFaxJob::setMaxDials(u_int n) { maxDials = n; }
  281. void
  282. SendFaxJob::setPriority(const char* pri)
  283. {
  284.     if (valeq(pri, "default") || valeq(pri, "normal"))
  285. priority = FAX_DEFPRIORITY;
  286.     else if (valeq(pri, "bulk") || valeq(pri, "junk"))
  287. priority = FAX_DEFPRIORITY + 4*16;
  288.     else if (valeq(pri, "low"))
  289. priority = FAX_DEFPRIORITY + 4*16-1;
  290.     else if (valeq(pri, "high"))
  291. priority = FAX_DEFPRIORITY - 4*16;
  292.     else
  293. priority = atoi(pri);
  294. }
  295. void SendFaxJob::setPriority(int p) { priority = p; }
  296. void SendFaxJob::setTSI(const char* s) { tsi = s; }
  297. void SendFaxJob::setFaxNumber(const char* s) { faxnumber = s; }
  298. void SendFaxJob::setFaxName(const char* s) { faxname = s; }
  299. void SendFaxJob::setDialString(const char* s) { number = s; }
  300. void SendFaxJob::setSubAddress(const char* s) { subaddr = s; }
  301. void SendFaxJob::setPassword(const char* s) { passwd = s; }
  302. void SendFaxJob::setExternalNumber(const char* s) { external = s; }
  303. void SendFaxJob::setAutoCoverPage(bool b) { autoCover = b; }
  304. void
  305. SendFaxJob::setCoverPageFile(const char* s, bool removeOnExit)
  306. {
  307.     if (coverFile != "" && removeOnExit)
  308. Sys::unlink(coverFile);
  309.     coverFile = s;
  310.     coverIsTemp = removeOnExit;
  311. }
  312. void SendFaxJob::setCoverTemplate(const char* s) { coverTemplate = s; }
  313. void SendFaxJob::setCoverName(const char* s) { name = s; }
  314. void SendFaxJob::setCoverLocation(const char* s) { location = s; }
  315. void SendFaxJob::setCoverCompany(const char* s) { company = s; }
  316. void SendFaxJob::setCoverComments(const char* s) { comments = s; }
  317. void SendFaxJob::setCoverRegarding(const char* s) { regarding = s; }
  318. void SendFaxJob::setCoverVoiceNumber(const char* s) { voicenumber = s; }
  319. void SendFaxJob::setCoverFromLocation(const char* s) { fromlocation = s; }
  320. void SendFaxJob::setCoverFromFax(const char* s) { fromfax = s; }
  321. void SendFaxJob::setCoverFromVoice(const char* s) { fromvoice = s; }
  322. void SendFaxJob::setCoverFromCompany(const char* s) { fromcompany = s; }
  323. bool
  324. SendFaxJob::setPageSize(const char* name)
  325. {
  326.     PageSizeInfo* info = PageSizeInfo::getPageSizeByName(name);
  327.     if (info) {
  328. pageWidth = info->width();
  329. pageLength = info->height();
  330. pageSize = name;
  331. delete info;
  332. return (true);
  333.     } else
  334. return (false);
  335. }
  336. void SendFaxJob::setVResolution(float r) { vres = r; }
  337. void SendFaxJob::setHResolution(float r) { hres = r; }
  338. int
  339. SendFaxJob::getSpeed(const char* value) const
  340. {
  341.     switch (atoi(value)) {
  342.     case 2400: return (0);
  343.     case 4800: return (1);
  344.     case 7200: return (2);
  345.     case 9600: return (3);
  346.     case 12000: return (4);
  347.     case 14400: return (5);
  348.     case 16800: return (6);
  349.     case 19200: return (7);
  350.     case 21600: return (8);
  351.     case 24000: return (9);
  352.     case 26400: return (10);
  353.     case 28800: return (11);
  354.     case 31200: return (12);
  355.     case 33600: return (13);
  356.     }
  357.     return (-1);
  358. }
  359. void SendFaxJob::setMinSpeed(int v) { minsp = v; }
  360. void SendFaxJob::setMinSpeed(const char* v) { minsp = getSpeed(v); }
  361. void SendFaxJob::setDesiredSpeed(int v) { desiredbr = v; }
  362. void SendFaxJob::setDesiredSpeed(const char* v) { desiredbr = getSpeed(v); }
  363. void
  364. SendFaxJob::setDesiredMST(const char* v)
  365. {
  366.     if (valeq(v, "0ms"))
  367. desiredst = 0;
  368.     else if (valeq(v, "5ms"))
  369. desiredst = 1;
  370.     else if (valeq(v, "10ms2"))
  371. desiredst = 2;
  372.     else if (valeq(v, "10ms"))
  373. desiredst = 3;
  374.     else if (valeq(v, "20ms2"))
  375. desiredst = 4;
  376.     else if (valeq(v, "20ms"))
  377. desiredst = 5;
  378.     else if (valeq(v, "40ms2"))
  379. desiredst = 6;
  380.     else if (valeq(v, "40ms"))
  381. desiredst = 7;
  382.     else
  383. desiredst = atoi(v);
  384. }
  385. void SendFaxJob::setDesiredMST(int v) { desiredst = v; }
  386. void
  387. SendFaxJob::setDesiredEC(const char* e)
  388. {
  389.     desiredec = atoi(e); 
  390. }
  391. void SendFaxJob::setDesiredEC(int e) { desiredec = e; }
  392. void SendFaxJob::setUseXVRes(bool b) { useXVRes = b; }
  393. void SendFaxJob::setServerDoCover(bool b) { serverdocover = b; }
  394. void SendFaxJob::setIgnoreModemBusy(bool b) { ignoremodembusy = b; }
  395. void
  396. SendFaxJob::setDesiredDF(const char* v)
  397. {
  398.     if (strcasecmp(v, "1d") == 0 || strcasecmp(v, "1dmh") == 0 || strcasecmp(v, "1dmr") == 0)
  399. desireddf = 0;
  400.     else if (strcasecmp(v, "2d") == 0 || strcasecmp(v, "2dmr") == 0)
  401. desireddf = 1;
  402.     else if (strcasecmp(v, "2dmruncomp") == 0)
  403. desireddf = 1; // NB: force 2D w/o uncompressed
  404.     else if (strcasecmp(v, "2dmmr") == 0)
  405. desireddf = 3;
  406.     else
  407. desireddf = atoi(v);
  408. }
  409. void SendFaxJob::setDesiredDF(int df) { desireddf = df; }
  410. void
  411. SendFaxJob::setTagLineFormat(const char* v)
  412. {
  413.     tagline = v;
  414.     sendTagLine = true;
  415. }
  416. void
  417. SendFaxJob::setChopHandling(const char* v)
  418. {
  419.     if (strcasecmp(v, "none") == 0)
  420. pagechop = chop_none;
  421.     else if (strcasecmp(v, "all") == 0)
  422. pagechop = chop_all;
  423.     else if (strcasecmp(v, "last") == 0)
  424. pagechop = chop_last;
  425.     else
  426. pagechop = atoi(v);
  427. }
  428. void SendFaxJob::setChopHandling(u_int v) { pagechop = v; }
  429. void SendFaxJob::setChopThreshold(float v) { chopthreshold = v; }
  430. void SendFaxJob::setSkipPages(u_int v) { skippages = v; }
  431. void SendFaxJob::setSkippedPages(u_int v) { skippedpages = v; }
  432. void SendFaxJob::setNoCountCover(u_int v) { nocountcover = v; }
  433. extern int
  434. parseAtSyntax(const char* s, const struct tm& ref, struct tm& at0, fxStr& emsg);
  435. #define CHECK(x) { if (!(x)) goto failure; }
  436. #define CHECKCMD(x) CHECK(client.command(x) == COMPLETE)
  437. #define CHECKPARM(a,b) CHECK(client.jobParm(a,b))
  438. #define IFPARM(a,b,v) { if ((b) != (v)) CHECKPARM(a,b) }
  439. bool
  440. SendFaxJob::initJobs(SendFaxClient& client, fxStr& emsg)
  441. {
  442.     if (!client.setCurrentJob("DEFAULT")) { // inherit from default
  443. emsg = client.getLastResponse();
  444. return (false);
  445.     }
  446.     return (true);
  447. }
  448. bool
  449. SendFaxJob::createJob(SendFaxClient& client, fxStr& emsg)
  450. {
  451.     if (!client.newJob(jobid, groupid, emsg)) // create new job on server
  452. return (false);
  453.     time_t now = Sys::now();
  454.     fxStr tod = "";
  455.     u_int delim = 0;
  456.     CHECKPARM("FROMUSER", client.getSenderName())
  457.     delim = sendTime.next(0, '@');
  458.     if (delim < sendTime.length()) {
  459. tod = sendTime.tail(sendTime.length() - delim - 1);
  460. sendTime = sendTime.head(delim);
  461.     }
  462.     struct tm tts;
  463.     if (sendTime != "") {
  464. if (!parseAtSyntax(sendTime, *localtime(&now), tts, emsg)) {
  465.     emsg.insert(sendTime | ": ");
  466.     return (false);
  467. }
  468. now = mktime(&tts);
  469. // NB: must send time relative to GMT
  470. CHECK(client.jobSendTime(*gmtime(&now)))
  471.     } else
  472. tts = *localtime(&now);
  473.     if (killTime != "") {
  474. struct tm when;
  475. if (!parseAtSyntax(killTime, tts, when, emsg)) {
  476.     emsg.insert(killTime | ": ");
  477.     return (false);
  478. }
  479. CHECK(client.jobLastTime(mktime(&when) - now))
  480.     }
  481.     if (retryTime != (u_int) -1)
  482. CHECK(client.jobRetryTime(retryTime))
  483.     IFPARM("MODEM", client.getModem(), ""); // XXX should be per-job state
  484.     IFPARM("MAXDIALS", maxDials, (u_int) -1)
  485.     IFPARM("MAXTRIES", maxRetries, (u_int) -1)
  486.     IFPARM("TIMEOFDAY", tod, "")
  487.     CHECKPARM("SCHEDPRI", priority)
  488.     /*
  489.      * If the dialstring is different from the
  490.      * displayable number then pass both.
  491.      */
  492.     IFPARM("TSI", tsi, "")
  493.     IFPARM("FAXNUMBER", faxnumber, "")
  494.     IFPARM("FAXNAME", faxname, "")
  495.     IFPARM("EXTERNAL", external, number)
  496.     CHECKPARM("DIALSTRING", number)
  497.     IFPARM("SUBADDR", subaddr, "")
  498.     IFPARM("PASSWD", passwd, "")
  499.     CHECKPARM("NOTIFYADDR", mailbox)
  500.     IFPARM("TOUSER", name, "")
  501.     IFPARM("TOCOMPANY", company, "")
  502.     IFPARM("TOLOCATION", location, "")
  503.     IFPARM("TOVOICE", voicenumber, "")
  504.     IFPARM("FROMCOMPANY", fromcompany, "")
  505.     IFPARM("FROMLOCATION", fromlocation, "")
  506.     IFPARM("FROMVOICE", fromvoice, "")
  507.     IFPARM("REGARDING", regarding, "")
  508.     IFPARM("JOBINFO", jobtag, "")
  509.     CHECKPARM("VRES", (u_int) vres)
  510.     CHECKPARM("PAGEWIDTH", (u_int) pageWidth)
  511.     CHECKPARM("PAGELENGTH", (u_int) pageLength)
  512.     IFPARM("MINBR", minsp, (u_int) -1)
  513.     IFPARM("BEGBR", desiredbr, (u_int) -1)
  514.     IFPARM("BEGST", desiredst, (u_int) -1)
  515.     if (desiredec != (u_int) -1) {
  516. CHECKPARM("USEECM", (bool) (desiredec != 0 ? true : false))
  517. if (desiredec) {
  518.     CHECKPARM("ECMTYPE", 
  519. desiredec == 1 ? "64bit" :
  520. desiredec == 2 ? "256bit" :
  521. desiredec == 3 ? "halfduplex" :
  522. desiredec == 4 ? "fullduplex" :
  523.   "256bit");
  524. }
  525.     }
  526.     if (desireddf != (u_int) -1) {
  527. CHECKPARM("DATAFORMAT",
  528.     desireddf == 0 ? "g31d" :
  529.     desireddf == 1 ? "g32d" :
  530.     desireddf == 2 ? "g32dunc" :
  531.     desireddf == 3 ? "g4"   :
  532.   "g31d")
  533.     }
  534.     if (sendTagLine) {
  535. CHECKPARM("USETAGLINE", true)
  536. CHECKPARM("TAGLINE", tagline)
  537.     }
  538.     if (useXVRes) {
  539. CHECKPARM("USEXVRES", true)
  540.     }
  541.     if (serverdocover) {
  542. CHECKPARM("SERVERDOCOVER", true)
  543.     }
  544.     if (ignoremodembusy) {
  545. CHECKPARM("IGNOREMODEMBUSY", true)
  546.     }
  547.     if (doneop == "archive") {
  548. CHECKPARM("DONEOP", "archive")
  549.     }
  550.     CHECKPARM("NOTIFY",
  551. notify == when_done ? "done" :
  552. notify == when_requeued ? "done+requeue" :
  553.   "none")
  554.     CHECKPARM("PAGECHOP", 
  555. pagechop == chop_default? "default" :
  556. pagechop == chop_none ? "none" :
  557. pagechop == chop_all ? "all" :
  558.   "last")
  559.     IFPARM("CHOPTHRESHOLD", chopthreshold, -1)
  560.     IFPARM("SKIPPAGES", skippages, 0)
  561.     IFPARM("SKIPPEDPAGES", skippedpages, 0)
  562.     IFPARM("NOCOUNTCOVER", nocountcover, 0)
  563.     if (coverFile != "") {
  564. int fd = Sys::open(coverFile, O_RDONLY);
  565. if (fd < 0) {
  566.     emsg = fxStr::format("%s: Can not open: %s",
  567. (const char*) coverFile, strerror(errno));
  568.     return (false); // XXX
  569. }
  570. fxStr coverDoc;
  571. bool fileSent = 
  572.        client.setFormat(FaxClient::FORM_PS)
  573.     && client.setType(FaxClient::TYPE_I) // XXX??? TYPE_A
  574.     && client.sendZData(fd, &FaxClient::storeTemp, coverDoc, emsg);
  575. Sys::close(fd);
  576. if (!fileSent) {
  577.     if (emsg == "")
  578. emsg = "Document transfer failed: " | client.getLastResponse();
  579.     return (false);
  580. }
  581. CHECK(client.jobCover(coverDoc))
  582.     }
  583.     /*
  584.      * Append documents and polling requests.
  585.      */
  586.     u_int i, n;
  587.     for (i = 0, n = client.getNumberOfFiles(); i < n; i++)
  588. CHECK(client.jobDocument(client.getFileDocument(i)))
  589.     for (i = 0, n = client.getNumberOfPollRequests(); i < n; i++) {
  590. fxStr sep, pwd;
  591. client.getPollRequest(i, sep, pwd);
  592. CHECK(client.jobPollRequest(sep, pwd))
  593.     }
  594.     return (true);
  595. failure:
  596.     emsg = client.getLastResponse();
  597.     return (false);
  598. }
  599. #undef CHECKPARM
  600. #undef IFPARM
  601. #undef CHECKCMD
  602. #undef CHECK
  603. fxIMPLEMENT_ObjArray(SendFaxJobArray, SendFaxJob)