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

传真(Fax)编程

开发平台:

C/C++

  1. /* $Id: FaxMachineInfo.c++,v 1.6 2008/04/26 22:34:28 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 "Sys.h"
  27. #include <sys/file.h>
  28. #include <errno.h>
  29. #include "FaxMachineInfo.h"
  30. #include "StackBuffer.h"
  31. #include "class2.h"
  32. #include "config.h"
  33. const fxStr FaxMachineInfo::infoDir(FAX_INFODIR);
  34. FaxMachineInfo::FaxMachineInfo()
  35. {
  36.     changed = false;
  37.     resetConfig();
  38. }
  39. FaxMachineInfo::FaxMachineInfo(const FaxMachineInfo& other)
  40.     : FaxConfig(other)
  41.     , file(other.file)
  42.     , csi(other.csi)
  43.     , nsf(other.nsf)
  44.     , dis(other.dis)
  45.     , lastSendFailure(other.lastSendFailure)
  46.     , lastDialFailure(other.lastDialFailure)
  47.     , pagerPassword(other.pagerPassword)
  48.     , pagerTTYParity(other.pagerTTYParity)
  49.     , pagingProtocol(other.pagingProtocol)
  50.     , pageSource(other.pageSource)
  51.     , pagerSetupCmds(other.pagerSetupCmds)
  52. {
  53.     locked = other.locked;
  54.     supportsVRes = other.supportsVRes;
  55.     supports2DEncoding = other.supports2DEncoding;
  56.     supportsMMR = other.supportsMMR;
  57.     hasV34Trouble = other.hasV34Trouble;
  58.     hasV17Trouble = other.hasV17Trouble;
  59.     senderHasV17Trouble = other.senderHasV17Trouble;
  60.     senderSkipsV29 = other.senderSkipsV29;
  61.     supportsPostScript = other.supportsPostScript;
  62.     supportsBatching = other.supportsBatching;
  63.     calledBefore = other.calledBefore;
  64.     maxPageWidth = other.maxPageWidth;
  65.     maxPageLength = other.maxPageLength;
  66.     maxSignallingRate = other.maxSignallingRate;
  67.     minScanlineTime = other.minScanlineTime;
  68.     sendFailures = other.sendFailures;
  69.     dialFailures = other.dialFailures;
  70.     pagerMaxMsgLength = other.pagerMaxMsgLength;
  71.     changed = other.changed;
  72. }
  73. FaxMachineInfo::~FaxMachineInfo() { writeConfig(); }
  74. u_short
  75. FaxMachineInfo::getMaxPageWidthInMM() const
  76. {
  77.     return (u_short)(maxPageWidth/(204.0f/25.4f));
  78. }
  79. #include <ctype.h>
  80. bool
  81. FaxMachineInfo::updateConfig(const fxStr& number)
  82. {
  83.     fxStr canon(number);
  84.     u_int i = 0;
  85.     while (i < canon.length()) {
  86. if (!isdigit(canon[i]))
  87.     canon.remove(i);
  88. else
  89.     i++;
  90.     }
  91.     if (file == "")
  92. file = infoDir | "/" | canon;
  93.     return FaxConfig::updateConfig(file);
  94. }
  95. void
  96. FaxMachineInfo::resetConfig()
  97. {
  98.     supportsVRes = VR_FINE; // normal and high res support
  99.     supports2DEncoding = true; // assume 2D-encoding support
  100.     supportsMMR = true; // assume MMR support
  101.     hasV34Trouble = false; // assume no problems
  102.     hasV17Trouble = false; // assume no problems
  103.     senderHasV17Trouble = false; // assume no problems
  104.     senderSkipsV29 = false; // assume V.29 usage
  105.     supportsPostScript = false; // no support for Adobe protocol
  106.     supportsBatching = true; // assume batching (EOM) support
  107.     calledBefore = false; // never called before
  108.     maxPageWidth = 2432; // max required width
  109.     maxPageLength = (u_short) -1; // infinite page length
  110.     maxSignallingRate = BR_14400; // T.17 14.4KB
  111.     minScanlineTime = ST_0MS; // 0ms/0ms
  112.     sendFailures = 0;
  113.     dialFailures = 0;
  114.     pagerMaxMsgLength = (u_int) -1; // unlimited length
  115.     pagerPassword = ""; // no password string
  116.     pagerTTYParity = ""; // unspecified
  117.     pagingProtocol = "ixo"; // ixo/tap or ucp
  118.     pageSource = ""; // source unknown
  119.     pagerSetupCmds = ""; // use values from config file
  120.     locked = 0;
  121. }
  122. extern void vlogError(const char* fmt, va_list ap);
  123. void
  124. FaxMachineInfo::error(const char* fmt0 ...)
  125. {
  126.     va_list ap;
  127.     va_start(ap, fmt0);
  128.     vlogError(file | ": " | fmt0, ap);
  129.     va_end(ap);
  130. }
  131. /*
  132.  * Report an error encountered while parsing the info file.
  133.  */
  134. void
  135. FaxMachineInfo::vconfigError(const char* fmt0, va_list ap)
  136. {
  137.     vlogError(file |
  138. fxStr::format(": line %u: %s", getConfigLineNumber(), fmt0), ap);
  139. }
  140. void
  141. FaxMachineInfo::configError(const char* fmt0 ...)
  142. {
  143.     va_list ap;
  144.     va_start(ap, fmt0);
  145.     vconfigError(fmt0, ap);
  146.     va_end(ap);
  147. }
  148. void FaxMachineInfo::configTrace(const char* ...) {}
  149. #define N(a) (sizeof (a) / sizeof (a[0]))
  150. static const char* brnames[] =
  151.    { "2400", "4800", "7200", "9600", "12000", "14400",
  152.      "16800", "19200", "21600", "24000", "26400", "28800", "31200", "33600" };
  153. #define NBR N(brnames)
  154. static const char* stnames[] =
  155.    { "0ms", "5ms", "10ms/5ms", "10ms",
  156.      "20ms/10ms", "20ms", "40ms/20ms", "40ms" };
  157. #define NST N(stnames)
  158. #define VR 0
  159. #define G32D 1
  160. #define G4 2
  161. #define PS 3
  162. #define WD 4
  163. #define LN 5
  164. #define BR 6
  165. #define ST 7
  166. #define V34 8
  167. #define V17 9
  168. #define BATCH 10
  169. #define PAGING 11
  170. #define SV17 12
  171. #define SSV29 13
  172. #define setLocked(b,ix) locked |= b<<ix
  173. bool
  174. FaxMachineInfo::setConfigItem(const char* tag, const char* value)
  175. {
  176.     int b = (tag[0] == '&' ? 1 : 0); // locked down indicator
  177.     if (b) tag++;
  178.     if (streq(tag, "supportshighres")) { // obsolete tag
  179. supportsVRes = VR_FINE;
  180. setLocked(b, VR);
  181.     } else if (streq(tag, "supportsvres")) {
  182. supportsVRes = getNumber(value);
  183. setLocked(b, VR);
  184.     } else if (streq(tag, "supports2dencoding")) {
  185. supports2DEncoding = getBoolean(value);
  186. setLocked(b, G32D);
  187.     } else if (streq(tag, "supportsmmr")) {
  188. supportsMMR = getBoolean(value);
  189. setLocked(b, G4);
  190.     } else if (streq(tag, "hasv34trouble")) {
  191. hasV34Trouble = getBoolean(value);
  192. setLocked(b, V34);
  193.     } else if (streq(tag, "hasv17trouble")) {
  194. hasV17Trouble = getBoolean(value);
  195. setLocked(b, V17);
  196.     } else if (streq(tag, "senderhasv17trouble")) {
  197. senderHasV17Trouble = getBoolean(value);
  198. setLocked(b, SV17);
  199.     } else if (streq(tag, "senderskipsv29")) {
  200. senderSkipsV29 = getBoolean(value);
  201. setLocked(b, SSV29);
  202.     } else if (streq(tag, "supportspostscript")) {
  203. supportsPostScript = getBoolean(value);
  204. setLocked(b, PS);
  205.     } else if (streq(tag, "supportsbatching")) {
  206. supportsBatching = getBoolean(value);
  207. setLocked(b, BATCH);
  208.     } else if (streq(tag, "calledbefore")) {
  209. calledBefore = getBoolean(value);
  210.     } else if (streq(tag, "maxpagewidth")) {
  211. maxPageWidth = getNumber(value);
  212. setLocked(b, WD);
  213.     } else if (streq(tag, "maxpagelength")) {
  214. maxPageLength = getNumber(value);
  215. setLocked(b, LN);
  216.     } else if (streq(tag, "sendfailures")) {
  217. sendFailures = getNumber(value);
  218.     } else if (streq(tag, "dialfailures")) {
  219. dialFailures = getNumber(value);
  220.     } else if (streq(tag, "remotecsi")) {
  221. csi = value;
  222.     } else if (streq(tag, "remotensf")) {
  223. nsf = value;
  224.     } else if (streq(tag, "remotedis")) {
  225. dis = value;
  226.     } else if (streq(tag, "lastsendfailure")) {
  227. lastSendFailure = value;
  228.     } else if (streq(tag, "lastdialfailure")) {
  229. lastDialFailure = value;
  230.     } else if (streq(tag, "maxsignallingrate")) {
  231. u_int ix;
  232. if (findValue(value, brnames, N(brnames), ix)) {
  233.     maxSignallingRate = ix;
  234.     setLocked(b, BR);
  235. }
  236.     } else if (streq(tag, "minscanlinetime")) {
  237. u_int ix;
  238. if (findValue(value, stnames, N(stnames), ix)) {
  239.     minScanlineTime = ix;
  240.     setLocked(b, ST);
  241. }
  242.     } else if (streq(tag, "pagermaxmsglength")) {
  243. pagerMaxMsgLength = getNumber(value);
  244.     } else if (streq(tag, "pagerpassword")) {
  245. pagerPassword = value;
  246.     } else if (streq(tag, "pagerttyparity")) {
  247. pagerTTYParity = value;
  248.     } else if (streq(tag, "pagingprotocol")) {
  249. pagingProtocol = value;
  250. setLocked(b, PAGING);
  251.     } else if (streq(tag, "pagesource")) {
  252. pageSource = value;
  253.     } else if (streq(tag, "pagersetupcmds")) {
  254. pagerSetupCmds = value;
  255.     } else
  256. return (false);
  257.     return (true);
  258. }
  259. #define isLocked(b) (locked & (1<<b))
  260. #define checkLock(ix, member, value)
  261.     if (!isLocked(ix)) {
  262. member = value;
  263. changed = true;
  264.     }
  265. void FaxMachineInfo::setSupportsVRes(int v)
  266.     { checkLock(VR, supportsVRes, v); }
  267. void FaxMachineInfo::setSupports2DEncoding(bool b)
  268.     { checkLock(G32D, supports2DEncoding, b); }
  269. void FaxMachineInfo::setSupportsMMR(bool b)
  270.     { checkLock(G4, supportsMMR, b); }
  271. void FaxMachineInfo::setHasV34Trouble(bool b)
  272.     { checkLock(V34, hasV34Trouble, b); }
  273. void FaxMachineInfo::setHasV17Trouble(bool b)
  274.     { checkLock(V17, hasV17Trouble, b); }
  275. void FaxMachineInfo::setSenderHasV17Trouble(bool b)
  276.     { checkLock(SV17, senderHasV17Trouble, b); }
  277. void FaxMachineInfo::setSenderSkipsV29(bool b)
  278.     { checkLock(SSV29, senderSkipsV29, b); }
  279. void FaxMachineInfo::setSupportsPostScript(bool b)
  280.     { checkLock(PS, supportsPostScript, b); }
  281. void FaxMachineInfo::setSupportsBatching(bool b)
  282.     { checkLock(BATCH, supportsBatching, b); }
  283. void FaxMachineInfo::setMaxPageWidthInPixels(int v)
  284.     { checkLock(WD, maxPageWidth, v); }
  285. void FaxMachineInfo::setMaxPageLengthInMM(int v)
  286.     { checkLock(LN, maxPageLength, v); }
  287. void FaxMachineInfo::setMaxSignallingRate(int v)
  288.     { checkLock(BR, maxSignallingRate, v); }
  289. void FaxMachineInfo::setMinScanlineTime(int v)
  290.     { checkLock(ST, minScanlineTime, v); }
  291. void
  292. FaxMachineInfo::setCalledBefore(bool b)
  293. {
  294.     calledBefore = b;
  295.     changed = true;
  296. }
  297. #define checkChanged(member, value)
  298.     if (member != value) {
  299. member = value;
  300. changed = true;
  301.     }
  302. void FaxMachineInfo::setCSI(const fxStr& v)
  303.     { checkChanged(csi, v); }
  304. void FaxMachineInfo::setNSF(const fxStr& v)
  305.     { checkChanged(nsf, v); }
  306. void FaxMachineInfo::setDIS(const fxStr& v)
  307.     { checkChanged(dis, v); }
  308. void FaxMachineInfo::setLastSendFailure(const fxStr& v)
  309.     { checkChanged(lastSendFailure, v); }
  310. void FaxMachineInfo::setLastDialFailure(const fxStr& v)
  311.     { checkChanged(lastDialFailure, v); }
  312. void FaxMachineInfo::setSendFailures(int v)
  313.     { checkChanged(sendFailures, v); }
  314. void FaxMachineInfo::setDialFailures(int v)
  315.     { checkChanged(dialFailures, v); }
  316. /*
  317.  * Rewrite the file if the contents have changed.
  318.  */
  319. void
  320. FaxMachineInfo::writeConfig()
  321. {
  322.     if (changed && file != "") {
  323. mode_t omask = umask(022);
  324. int fd = Sys::open(file, O_WRONLY|O_CREAT, 0644);
  325. (void) umask(omask);
  326. if (fd >= 0) {
  327.     fxStackBuffer buf;
  328.     writeConfig(buf);
  329.     u_int cc = buf.getLength();
  330.     if (Sys::write(fd, buf, cc) != (ssize_t)cc) {
  331. error("write error: %s", strerror(errno));
  332. Sys::close(fd);
  333. return;
  334.     }
  335.     int ignore = ftruncate(fd, cc);
  336.     Sys::close(fd);
  337. } else
  338.     error("open: %m");
  339. changed = false;
  340.     }
  341. }
  342. static void
  343. putBoolean(fxStackBuffer& buf, const char* tag, bool locked, bool b)
  344. {
  345.     buf.fput("%s%s:%sn", locked ? "&" : "", tag, b ? "yes" : "no");
  346. }
  347. static void
  348. putDecimal(fxStackBuffer& buf, const char* tag, bool locked, int v)
  349. {
  350.     buf.fput("%s%s:%dn", locked ? "&" : "", tag, v);
  351. }
  352. static void
  353. putString(fxStackBuffer& buf, const char* tag, bool locked, const char* v)
  354. {
  355.     buf.fput("%s%s:"%s"n", locked ? "&" : "", tag, v);
  356. }
  357. static void
  358. putIfString(fxStackBuffer& buf, const char* tag, bool locked, const char* v)
  359. {
  360.     if (*v != '')
  361. buf.fput("%s%s:"%s"n", locked ? "&" : "", tag, v);
  362. }
  363. void
  364. FaxMachineInfo::writeConfig(fxStackBuffer& buf)
  365. {
  366.     putDecimal(buf, "supportsVRes", isLocked(VR), supportsVRes);
  367.     putBoolean(buf, "supports2DEncoding", isLocked(G32D),supports2DEncoding);
  368.     putBoolean(buf, "supportsMMR", isLocked(G4),supportsMMR);
  369.     putBoolean(buf, "hasV34Trouble", isLocked(V34),hasV34Trouble);
  370.     putBoolean(buf, "hasV17Trouble", isLocked(V17),hasV17Trouble);
  371.     putBoolean(buf, "senderHasV17Trouble", isLocked(SV17),senderHasV17Trouble);
  372.     putBoolean(buf, "senderSkipsV29", isLocked(SSV29), senderSkipsV29);
  373.     putBoolean(buf, "supportsPostScript", isLocked(PS), supportsPostScript);
  374.     putBoolean(buf, "supportsBatching", isLocked(BATCH), supportsBatching);
  375.     putBoolean(buf, "calledBefore", false, calledBefore);
  376.     putDecimal(buf, "maxPageWidth", isLocked(WD), maxPageWidth);
  377.     putDecimal(buf, "maxPageLength", isLocked(LN), maxPageLength);
  378.     putString(buf, "maxSignallingRate", isLocked(BR),
  379. brnames[fxmin(maxSignallingRate, BR_33600)]);
  380.     putString(buf, "minScanlineTime", isLocked(ST),
  381. stnames[fxmin(minScanlineTime, ST_40MS)]);
  382.     putString(buf, "remoteCSI", false, csi);
  383.     putString(buf, "remoteNSF", false, nsf);
  384.     putString(buf, "remoteDIS", false, dis);
  385.     putDecimal(buf, "sendFailures", false, sendFailures);
  386.     putIfString(buf, "lastSendFailure", false, lastSendFailure);
  387.     putDecimal(buf, "dialFailures", false, dialFailures);
  388.     putIfString(buf, "lastDialFailure", false, lastDialFailure);
  389.     if (pagerMaxMsgLength != (u_int) -1)
  390. putDecimal(buf, "pagerMaxMsgLength", true, pagerMaxMsgLength);
  391.     putIfString(buf, "pagerPassword", true, pagerPassword);
  392.     putIfString(buf, "pagerTTYParity", true, pagerTTYParity);
  393.     putIfString(buf, "pagingProtocol", isLocked(PAGING), pagingProtocol);
  394.     putIfString(buf, "pageSource", true, pageSource);
  395.     putIfString(buf, "pagerSetupCmds", true, pagerSetupCmds);
  396. }