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

传真(Fax)编程

开发平台:

C/C++

  1. /* $Id: FaxConfig.c++,v 1.6 2007/11/14 17:45:04 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. /*
  27.  * HylaFAX Server Configuration Base Class.
  28.  */
  29. #include "FaxConfig.h"
  30. #include "Str.h"
  31. #include <ctype.h>
  32. #include <pwd.h>
  33. #include "Sys.h"
  34. FaxConfig::FaxConfig()
  35. {
  36.     lineno = 0;
  37.     lastModTime = 0;
  38. }
  39. FaxConfig::FaxConfig(const FaxConfig& other)
  40. {
  41.     lineno = other.lineno;
  42.     lastModTime = other.lastModTime;
  43. }
  44. FaxConfig::~FaxConfig() {}
  45. void
  46. FaxConfig::readConfig(const fxStr& filename)
  47. {
  48.     FILE* fd = Sys::fopen(tildeExpand(filename), "r");
  49.     if (fd) {
  50. configTrace("Read config file %s", (const char*) filename);
  51. char line[1024];
  52. while (fgets(line, sizeof (line)-1, fd)) {
  53.     line[strlen(line)-1]=''; // Nuke r at end of line
  54.     (void) readConfigItem(line);
  55. }
  56. fclose(fd);
  57.     }
  58. }
  59. void FaxConfig::resetConfig() { lineno = 0; }
  60. bool
  61. FaxConfig::updateConfig(const fxStr& filename)
  62. {
  63.     struct stat sb;
  64.     fxStr path(tildeExpand(filename));
  65.     if (Sys::stat(path, sb) == 0 && sb.st_mtime > lastModTime) {
  66. resetConfig();
  67. readConfig(path);
  68. lastModTime = sb.st_mtime;
  69. return (true);
  70.     } else
  71. return (false);
  72. }
  73. /*
  74.  * Expand a filename that might have `~' in it.
  75.  */
  76. fxStr
  77. FaxConfig::tildeExpand(const fxStr& filename)
  78. {
  79.     fxStr path(filename);
  80.     if (filename.length() > 1 && filename[0] == '~') {
  81. path.remove(0);
  82. const char* cp = getenv("HOME");
  83. if (!cp || *cp == '') {
  84.     struct passwd* pwd = getpwuid(getuid());
  85.     if (!pwd) {
  86. configError("No passwd file entry for uid %u,"
  87.     " cannot expand ~ in "%s"",
  88.     getuid(), (const char*) filename);
  89. cp = ""; // NB: XXX maybe this should be fatal?
  90.     } else
  91. cp = pwd->pw_dir;
  92. }
  93. path.insert(cp);
  94.     }
  95.     return (path);
  96. }
  97. bool
  98. FaxConfig::findTag(const char* tag, const void* names0, u_int n, u_int& ix)
  99. {
  100.     const tags* names = (const tags*) names0;
  101.     for (int i = n-1; i >= 0; i--) {
  102. const char* cp = names[i].name;
  103. if (cp[0] == tag[0] && streq(cp, tag)) {
  104.     ix = i;
  105.     return (true);
  106. }
  107.     }
  108.     return (false);
  109. }
  110. bool
  111. FaxConfig::findValue(const char* value, const char* values[], u_int n, u_int& ix)
  112. {
  113.     for (u_int i = 0; i < n; i++) {
  114. const char* cp = values[i];
  115. if (cp[0] == value[0] && streq(cp, value)) {
  116.     ix = i;
  117.     return (true);
  118. }
  119.     }
  120.     return (false);
  121. }
  122. int
  123. FaxConfig::getNumber(const char* s)
  124. {
  125.     return ((int) strtol(s, NULL, 0));
  126. }
  127. #define valeq(a,b) (strcasecmp(a,b)==0)
  128. bool
  129. FaxConfig::getBoolean(const char* cp)
  130. {
  131.     return (valeq(cp, "on") || valeq(cp, "yes") || valeq(cp, "true"));
  132. }
  133. bool
  134. FaxConfig::readConfigItem(const char* b)
  135. {
  136.     char buf[2048];
  137.     char* cp;
  138.     lineno++;
  139.     strncpy(buf, b, sizeof (buf));
  140.     for (cp = buf; isspace(*cp); cp++) // skip leading white space
  141. ;
  142.     if (*cp == '#' || *cp == '')
  143. return (true);
  144.     const char* tag = cp; // start of tag
  145.     while (*cp && *cp != ':') { // skip to demarcating ':'
  146. if (isupper(*cp))
  147.     *cp = tolower(*cp);
  148. cp++;
  149.     }
  150.     if (*cp != ':') {
  151. configError("Syntax error at line %u, missing ':' in "%s"",
  152.     lineno, b);
  153. return (false);
  154.     }
  155.     for (*cp++ = ''; isspace(*cp); cp++) // skip white space again
  156. ;
  157.     const char* value;
  158.     if (*cp == '"') { // "..." value
  159. int c;
  160. /*
  161.  * Parse quoted string and deal with  escapes.
  162.  */
  163. char* dp = ++cp;
  164. for (value = dp; (c = *cp) != '"'; cp++) {
  165.     if (c == '') { // unmatched quote mark
  166. configError("Syntax error at line %u, missing quote mark in "%s"",
  167.     lineno, b);
  168. return (false);
  169.     }
  170.     if (c == '\') {
  171. c = *++cp;
  172. if (isdigit(c)) { // nnn octal escape
  173.     int v = c - '0';
  174.     if (isdigit(c = cp[1])) {
  175. cp++, v = (v << 3) + (c - '0');
  176. if (isdigit(c = cp[1]))
  177.     cp++, v = (v << 3) + (c - '0');
  178.     }
  179.     c = v;
  180. } else { // <char> escapes
  181.     for (const char* tp = "nnttrrbbffv13"; *tp; tp += 2)
  182. if (c == tp[0]) {
  183.     c = tp[1];
  184.     break;
  185. }
  186. }
  187.     }
  188.     *dp++ = c;
  189. }
  190. *dp = '';
  191.     } else { // value up to 1st non-ws
  192. for (value = cp; *cp && !isspace(*cp); cp++)
  193.     ;
  194. *cp = '';
  195.     }
  196.     if (streq(tag, "include")) {
  197. u_int old_lineno = lineno;
  198. configTrace("%s = %s (line %u)", tag, value, lineno);
  199. lineno = 0;
  200. readConfig(value);
  201. lineno = old_lineno;
  202. return (true);
  203.     }
  204.     if (!setConfigItem(tag, value)) {
  205. configTrace("Unknown configuration parameter "%s" ignored at line %u",
  206.      tag, lineno);
  207. return (false);
  208.     } else {
  209. configTrace("%s = %s (line %u)", tag, value, lineno);
  210. return (true);
  211.     }
  212. }