You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Configuration.cxx 9.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430
  1. /* Copyright (C) 2002-2004 RealVNC Ltd. All Rights Reserved.
  2. * Copyright (C) 2004-2005 Cendio AB. All rights reserved.
  3. *
  4. * This is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation; either version 2 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This software is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this software; if not, write to the Free Software
  16. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
  17. * USA.
  18. */
  19. // -=- Configuration.cxx
  20. #include <stdlib.h>
  21. #include <ctype.h>
  22. #include <string.h>
  23. #include <assert.h>
  24. #ifdef WIN32
  25. #define strcasecmp _stricmp
  26. #define strncasecmp _strnicmp
  27. #endif
  28. #include <rfb/util.h>
  29. #include <rfb/Configuration.h>
  30. #include <rfb/LogWriter.h>
  31. #include <rfb/Exception.h>
  32. #ifdef WIN32
  33. // Under Win32, we use these routines from several threads,
  34. // so we must provide suitable locking.
  35. #include <rfb/Threading.h>
  36. static rfb::Mutex configLock;
  37. #endif
  38. #include <rdr/HexOutStream.h>
  39. #include <rdr/HexInStream.h>
  40. using namespace rfb;
  41. static LogWriter vlog("Config");
  42. // -=- Configuration
  43. VoidParameter* Configuration::head = 0;
  44. bool Configuration::setParam(const char* n, const char* v, bool immutable) {
  45. return setParam(n, strlen(n), v, immutable);
  46. }
  47. bool Configuration::setParam(const char* name, int len,
  48. const char* val, bool immutable)
  49. {
  50. VoidParameter* current = head;
  51. while (current) {
  52. if ((int)strlen(current->getName()) == len &&
  53. strncasecmp(current->getName(), name, len) == 0)
  54. {
  55. bool b = current->setParam(val);
  56. current->setHasBeenSet();
  57. if (b && immutable)
  58. current->setImmutable();
  59. return b;
  60. }
  61. current = current->_next;
  62. }
  63. return false;
  64. }
  65. bool Configuration::setParam(const char* config, bool immutable) {
  66. bool hyphen = false;
  67. if (config[0] == '-') {
  68. hyphen = true;
  69. config++;
  70. if (config[0] == '-') config++; // allow gnu-style --<option>
  71. }
  72. const char* equal = strchr(config, '=');
  73. if (equal) {
  74. return setParam(config, equal-config, equal+1, immutable);
  75. } else if (hyphen) {
  76. VoidParameter* current = head;
  77. while (current) {
  78. if (strcasecmp(current->getName(), config) == 0) {
  79. bool b = current->setParam();
  80. current->setHasBeenSet();
  81. if (b && immutable)
  82. current->setImmutable();
  83. return b;
  84. }
  85. current = current->_next;
  86. }
  87. }
  88. return false;
  89. }
  90. VoidParameter* Configuration::getParam(const char* param)
  91. {
  92. VoidParameter* current = head;
  93. while (current) {
  94. if (strcasecmp(current->getName(), param) == 0)
  95. return current;
  96. current = current->_next;
  97. }
  98. return 0;
  99. }
  100. void Configuration::listParams(int width, int nameWidth) {
  101. VoidParameter* current = head;
  102. while (current) {
  103. char* def_str = current->getDefaultStr();
  104. const char* desc = current->getDescription();
  105. fprintf(stderr," %-*s -", nameWidth, current->getName());
  106. int column = strlen(current->getName());
  107. if (column < nameWidth) column = nameWidth;
  108. column += 4;
  109. while (true) {
  110. const char* s = strchr(desc, ' ');
  111. int wordLen;
  112. if (s) wordLen = s-desc;
  113. else wordLen = strlen(desc);
  114. if (column + wordLen + 1 > width) {
  115. fprintf(stderr,"\n%*s",nameWidth+4,"");
  116. column = nameWidth+4;
  117. }
  118. fprintf(stderr," %.*s",wordLen,desc);
  119. column += wordLen + 1;
  120. desc += wordLen + 1;
  121. if (!s) break;
  122. }
  123. if (def_str) {
  124. if (column + (int)strlen(def_str) + 11 > width)
  125. fprintf(stderr,"\n%*s",nameWidth+4,"");
  126. fprintf(stderr," (default=%s)\n",def_str);
  127. strFree(def_str);
  128. } else {
  129. fprintf(stderr,"\n");
  130. }
  131. current = current->_next;
  132. }
  133. }
  134. // -=- VoidParameter
  135. VoidParameter::VoidParameter(const char* name_, const char* desc_)
  136. : immutable(false), _hasBeenSet(false), name(name_), description(desc_) {
  137. _next = Configuration::head;
  138. Configuration::head = this;
  139. }
  140. VoidParameter::~VoidParameter() {
  141. }
  142. const char*
  143. VoidParameter::getName() const {
  144. return name;
  145. }
  146. const char*
  147. VoidParameter::getDescription() const {
  148. return description;
  149. }
  150. bool VoidParameter::setParam() {
  151. return false;
  152. }
  153. bool VoidParameter::isBool() const {
  154. return false;
  155. }
  156. void
  157. VoidParameter::setImmutable() {
  158. vlog.debug("set immutable %s", getName());
  159. immutable = true;
  160. }
  161. void
  162. VoidParameter::setHasBeenSet() {
  163. _hasBeenSet = true;
  164. }
  165. bool
  166. VoidParameter::hasBeenSet() {
  167. return _hasBeenSet;
  168. }
  169. // -=- AliasParameter
  170. AliasParameter::AliasParameter(const char* name_, const char* desc_,
  171. VoidParameter* param_)
  172. : VoidParameter(name_, desc_), param(param_) {
  173. }
  174. bool
  175. AliasParameter::setParam(const char* v) {
  176. return param->setParam(v);
  177. }
  178. bool AliasParameter::setParam() {
  179. return param->setParam();
  180. }
  181. char*
  182. AliasParameter::getDefaultStr() const {
  183. return 0;
  184. }
  185. char* AliasParameter::getValueStr() const {
  186. return param->getValueStr();
  187. }
  188. bool AliasParameter::isBool() const {
  189. return param->isBool();
  190. }
  191. void
  192. AliasParameter::setImmutable() {
  193. vlog.debug("set immutable %s (Alias)", getName());
  194. param->setImmutable();
  195. }
  196. // -=- BoolParameter
  197. BoolParameter::BoolParameter(const char* name_, const char* desc_, bool v)
  198. : VoidParameter(name_, desc_), value(v), def_value(v) {
  199. }
  200. bool
  201. BoolParameter::setParam(const char* v) {
  202. if (immutable) return true;
  203. if (*v == 0 || strcasecmp(v, "1") == 0 || strcasecmp(v, "on") == 0
  204. || strcasecmp(v, "true") == 0 || strcasecmp(v, "yes") == 0)
  205. value = 1;
  206. else if (strcasecmp(v, "0") == 0 || strcasecmp(v, "off") == 0
  207. || strcasecmp(v, "false") == 0 || strcasecmp(v, "no") == 0)
  208. value = 0;
  209. else {
  210. vlog.error("Bool parameter %s: invalid value '%s'", getName(), v);
  211. return false;
  212. }
  213. vlog.debug("set %s(Bool) to %s(%d)", getName(), v, value);
  214. return true;
  215. }
  216. bool BoolParameter::setParam() {
  217. setParam(true);
  218. return true;
  219. }
  220. void BoolParameter::setParam(bool b) {
  221. if (immutable) return;
  222. value = b;
  223. vlog.debug("set %s(Bool) to %d", getName(), value);
  224. }
  225. char*
  226. BoolParameter::getDefaultStr() const {
  227. char* result = new char[8];
  228. sprintf(result, "%d", (int)def_value);
  229. return result;
  230. }
  231. char* BoolParameter::getValueStr() const {
  232. char* result = new char[8];
  233. sprintf(result, "%d", (int)value);
  234. return result;
  235. }
  236. bool BoolParameter::isBool() const {
  237. return true;
  238. }
  239. BoolParameter::operator bool() const {
  240. return value;
  241. }
  242. // -=- IntParameter
  243. IntParameter::IntParameter(const char* name_, const char* desc_, int v)
  244. : VoidParameter(name_, desc_), value(v), def_value(v) {
  245. }
  246. bool
  247. IntParameter::setParam(const char* v) {
  248. if (immutable) return true;
  249. vlog.debug("set %s(Int) to %s", getName(), v);
  250. value = atoi(v);
  251. return true;
  252. }
  253. bool
  254. IntParameter::setParam(int v) {
  255. if (immutable) return true;
  256. vlog.debug("set %s(Int) to %d", getName(), v);
  257. value = v;
  258. return true;
  259. }
  260. char*
  261. IntParameter::getDefaultStr() const {
  262. char* result = new char[16];
  263. sprintf(result, "%d", def_value);
  264. return result;
  265. }
  266. char* IntParameter::getValueStr() const {
  267. char* result = new char[16];
  268. sprintf(result, "%d", value);
  269. return result;
  270. }
  271. IntParameter::operator int() const {
  272. return value;
  273. }
  274. // -=- StringParameter
  275. StringParameter::StringParameter(const char* name_, const char* desc_,
  276. const char* v)
  277. : VoidParameter(name_, desc_), value(strDup(v)), def_value(v)
  278. {
  279. if (!v) {
  280. fprintf(stderr,"Default value <null> for %s not allowed\n",name_);
  281. throw rfb::Exception("Default value <null> not allowed");
  282. }
  283. }
  284. StringParameter::~StringParameter() {
  285. strFree(value);
  286. }
  287. bool StringParameter::setParam(const char* v) {
  288. #ifdef WIN32
  289. Lock l(configLock);
  290. #endif
  291. if (immutable) return true;
  292. if (!v)
  293. throw rfb::Exception("setParam(<null>) not allowed");
  294. vlog.debug("set %s(String) to %s", getName(), v);
  295. strFree(value);
  296. value = strDup(v);
  297. return value != 0;
  298. }
  299. char* StringParameter::getDefaultStr() const {
  300. return strDup(def_value);
  301. }
  302. char* StringParameter::getValueStr() const {
  303. #ifdef WIN32
  304. Lock l(configLock);
  305. #endif
  306. return strDup(value);
  307. }
  308. // -=- BinaryParameter
  309. BinaryParameter::BinaryParameter(const char* name_, const char* desc_, const void* v, int l)
  310. : VoidParameter(name_, desc_), value(0), length(0), def_value((char*)v), def_length(l) {
  311. if (l) {
  312. value = new char[l];
  313. length = l;
  314. memcpy(value, v, l);
  315. }
  316. }
  317. BinaryParameter::~BinaryParameter() {
  318. if (value)
  319. delete [] value;
  320. }
  321. bool BinaryParameter::setParam(const char* v) {
  322. #ifdef WIN32
  323. Lock l(configLock);
  324. #endif
  325. if (immutable) return true;
  326. vlog.debug("set %s(Binary) to %s", getName(), v);
  327. return rdr::HexInStream::hexStrToBin(v, &value, &length);
  328. }
  329. void BinaryParameter::setParam(const void* v, int len) {
  330. #ifdef WIN32
  331. Lock l(configLock);
  332. #endif
  333. if (immutable) return;
  334. vlog.debug("set %s(Binary)", getName());
  335. delete [] value; value = 0;
  336. if (len) {
  337. value = new char[len];
  338. length = len;
  339. memcpy(value, v, len);
  340. }
  341. }
  342. char* BinaryParameter::getDefaultStr() const {
  343. return rdr::HexOutStream::binToHexStr(def_value, def_length);
  344. }
  345. char* BinaryParameter::getValueStr() const {
  346. #ifdef WIN32
  347. Lock l(configLock);
  348. #endif
  349. return rdr::HexOutStream::binToHexStr(value, length);
  350. }
  351. void BinaryParameter::getData(void** data_, int* length_) const {
  352. #ifdef WIN32
  353. Lock l(configLock);
  354. #endif
  355. if (length_) *length_ = length;
  356. if (data_) {
  357. *data_ = new char[length];
  358. memcpy(*data_, value, length);
  359. }
  360. }