rc.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370
  1. /*
  2. * rc.c
  3. *
  4. * Copyright 2001-2003, Meiosys (www.meiosys.com). All rights reserved.
  5. *
  6. * See the COPYING file for the terms of usage and distribution.
  7. */
  8. #ifdef HAVE_CONFIG_H
  9. #include "config.h"
  10. #endif
  11. #include <tchar.h>
  12. #include "log4c/rc.h"
  13. #include "log4c/category.h"
  14. #include "log4c/appender.h"
  15. #include "log4c/layout.h"
  16. #include "log4c/appender_type_rollingfile.h"
  17. #include "log4c/rollingpolicy.h"
  18. #include "log4c/rollingpolicy_type_sizewin.h"
  19. #include "sd/error.h"
  20. #include "sd/domnode.h"
  21. #include "sd/malloc.h"
  22. #include "sd/sd_xplatform.h"
  23. #include "sd/factory.h"
  24. #include <stdlib.h>
  25. #include <string.h>
  26. static const TCHAR version[] = _T("1.2.1");
  27. static log4c_rc_t __log4c_rc = { { 0, 0, 0, 0 } };
  28. log4c_rc_t* const log4c_rc = &__log4c_rc;
  29. /******************************************************************************/
  30. static long parse_byte_size (const TCHAR *astring)
  31. {
  32. /* Parse size in bytes depending on the suffix. Valid suffixes are KB, MB and GB */
  33. size_t sz = _tcslen (astring);
  34. long res = _tcstol(astring, (TCHAR **) NULL, 10);
  35. if (res <= 0)
  36. return 0;
  37. if (astring[ sz - 1 ] == _T('B')) {
  38. switch (astring[ sz - 2 ]) {
  39. case _T('K'):
  40. res *= 1024;
  41. break;
  42. case _T('M'):
  43. res *= 1024 * 1024;
  44. break;
  45. case _T('G'):
  46. res *= 1024 * 1024 * 1024;
  47. break;
  48. default:
  49. sd_debug(_T("Wrong suffix parsing size in bytes for string %s, ignoring suffix"),
  50. astring);
  51. }
  52. }
  53. sd_debug(_T("Parsed size parameter %s to value %ld"),astring, res);
  54. return (res);
  55. }
  56. /******************************************************************************/
  57. static int config_load(log4c_rc_t* this, sd_domnode_t* anode)
  58. {
  59. sd_list_iter_t* i = NULL;
  60. for (i = sd_list_begin(anode->children); i != sd_list_end(anode->children);
  61. i = sd_list_iter_next(i))
  62. {
  63. sd_domnode_t* node = i->data;
  64. if (!_tcscmp(node->name, _T("nocleanup"))) {
  65. this->config.nocleanup = _ttoi(node->value);
  66. if (this->config.nocleanup)
  67. sd_debug(_T("deactivating log4c cleanup"));
  68. }
  69. if (!_tcscmp(node->name, _T("bufsize"))) {
  70. this->config.bufsize = parse_byte_size(node->value);
  71. if (this->config.bufsize)
  72. sd_debug(_T("using fixed buffer size of %d bytes"),
  73. this->config.bufsize);
  74. else
  75. sd_debug(_T("using dynamic allocated buffer"));
  76. }
  77. if (!_tcscmp(node->name, _T("debug"))) {
  78. sd_domnode_t* level = sd_domnode_attrs_get(node, _T("level"));
  79. if (level) {
  80. this->config.debug = _ttoi(level->value);
  81. sd_debug(_T("activating log4c debugging. level = %d"), this->config.debug);
  82. }
  83. }
  84. if (!_tcscmp(node->name, _T("reread"))) {
  85. this->config.reread = _ttoi(node->value);
  86. sd_debug(_T("log4crc reread is %d"),this->config.reread);
  87. if (0 == this->config.reread)
  88. sd_debug(_T("deactivating log4crc reread"));
  89. }
  90. }
  91. return 0;
  92. }
  93. /******************************************************************************/
  94. static int category_load(log4c_rc_t* this, sd_domnode_t* anode)
  95. {
  96. sd_domnode_t* name = sd_domnode_attrs_get(anode, _T("name"));
  97. sd_domnode_t* priority = sd_domnode_attrs_get(anode, _T("priority"));
  98. sd_domnode_t* additivity = sd_domnode_attrs_get(anode, _T("additivity"));
  99. sd_domnode_t* appender = sd_domnode_attrs_get(anode, _T("appender"));
  100. log4c_category_t* cat = NULL;
  101. if (!name) {
  102. sd_error(_T("attribute \"name\" is missing"));
  103. return -1;
  104. }
  105. cat = log4c_category_get(name->value);
  106. if (priority)
  107. log4c_category_set_priority(
  108. cat, log4c_priority_to_int(priority->value));
  109. if (additivity) {
  110. if (!strcasecmp(additivity->value, _T("false"), _tcslen(_T("false")))) {
  111. log4c_category_set_additivity(cat, 0);
  112. } else if (!strcasecmp(additivity->value, _T("true"), _tcslen(_T("true")))) {
  113. log4c_category_set_additivity(cat, 1);
  114. } else {
  115. sd_error(_T("additivity value is invalid : %s"), additivity->value);
  116. }
  117. }
  118. if (appender)
  119. log4c_category_set_appender(
  120. cat, log4c_appender_get(appender->value));
  121. return 0;
  122. }
  123. /******************************************************************************/
  124. static int appender_load(log4c_rc_t* this, sd_domnode_t* anode)
  125. {
  126. sd_domnode_t* name = sd_domnode_attrs_get(anode, _T("name"));
  127. sd_domnode_t* type = sd_domnode_attrs_get(anode, _T("type"));
  128. sd_domnode_t* layout = sd_domnode_attrs_get(anode, _T("layout"));
  129. log4c_appender_t* app = NULL;
  130. if (!name) {
  131. sd_error(_T("attribute \"name\" is missing"));
  132. return -1;
  133. }
  134. sd_debug(_T("appender_load[name='%s'"),
  135. (name->value ? name->value : _T("(not set)")));
  136. app = log4c_appender_get(name->value);
  137. if (type){
  138. sd_debug(_T("appender type is '%s'"),
  139. (type->value ? type->value: _T("(not set)")));
  140. log4c_appender_set_type(app, log4c_appender_type_get(type->value));
  141. #ifdef WITH_ROLLINGFILE
  142. if ( !strcasecmp(type->value, _T("rollingfile"), _tcsclen(_T("rollingfile")))) {
  143. rollingfile_udata_t *rfup = NULL;
  144. log4c_rollingpolicy_t *rollingpolicyp = NULL;
  145. sd_domnode_t* logdir = sd_domnode_attrs_get(anode,
  146. _T("logdir"));
  147. sd_domnode_t* logprefix = sd_domnode_attrs_get(anode,
  148. _T("prefix"));
  149. sd_domnode_t* rollingpolicy_name = sd_domnode_attrs_get(anode,
  150. _T("rollingpolicy"));
  151. sd_debug(_T("logdir='%s', prefix='%s', rollingpolicy='%s'"),
  152. (logdir && logdir->value ? name->value : _T("(not set)")),
  153. (logprefix && logprefix->value ? logprefix->value : _T("(not set)")),
  154. (rollingpolicy_name && rollingpolicy_name->value ?
  155. rollingpolicy_name->value : _T("(not set)")));
  156. rfup = rollingfile_make_udata();
  157. rollingfile_udata_set_logdir(rfup, (TCHAR *)logdir->value);
  158. rollingfile_udata_set_files_prefix(rfup, (TCHAR *)logprefix->value);
  159. if (rollingpolicy_name){
  160. /* recover a rollingpolicy instance with this name */
  161. rollingpolicyp = log4c_rollingpolicy_get(rollingpolicy_name->value);
  162. /* connect that policy to this rollingfile appender conf */
  163. rollingfile_udata_set_policy(rfup, rollingpolicyp);
  164. log4c_appender_set_udata(app, rfup);
  165. /* allow the policy to initialize itself */
  166. log4c_rollingpolicy_init(rollingpolicyp, rfup);
  167. } else {
  168. /* no rollingpolicy specified, default to default sizewin */
  169. sd_debug(_T("no rollingpolicy name specified--will default"));
  170. }
  171. }
  172. #endif
  173. }
  174. if (layout)
  175. log4c_appender_set_layout(app, log4c_layout_get(layout->value));
  176. sd_debug(_T("]"));
  177. return 0;
  178. }
  179. /******************************************************************************/
  180. static int layout_load(log4c_rc_t* this, sd_domnode_t* anode)
  181. {
  182. sd_domnode_t* name = sd_domnode_attrs_get(anode, _T("name"));
  183. sd_domnode_t* type = sd_domnode_attrs_get(anode, _T("type"));
  184. log4c_layout_t* layout = NULL;
  185. if (!name) {
  186. sd_error(_T("attribute \"name\" is missing"));
  187. return -1;
  188. }
  189. layout = log4c_layout_get(name->value);
  190. if (type)
  191. log4c_layout_set_type(layout, log4c_layout_type_get(type->value));
  192. return 0;
  193. }
  194. #ifdef WITH_ROLLINGFILE
  195. /******************************************************************************/
  196. static int rollingpolicy_load(log4c_rc_t* this, sd_domnode_t* anode)
  197. {
  198. sd_domnode_t* name = sd_domnode_attrs_get(anode, _T("name"));
  199. sd_domnode_t* type = sd_domnode_attrs_get(anode, _T("type"));
  200. log4c_rollingpolicy_t* rpolicyp = NULL;
  201. long a_maxsize;
  202. sd_debug(_T("rollingpolicy_load["));
  203. if (!name) {
  204. sd_error(_T("attribute \"name\" is missing"));
  205. return -1;
  206. }
  207. rpolicyp = log4c_rollingpolicy_get(name->value);
  208. if (type){
  209. log4c_rollingpolicy_set_type(rpolicyp,
  210. log4c_rollingpolicy_type_get(type->value));
  211. if (!strcasecmp(type->value, _T("sizewin"), _tcsclen(_T("sizewin")))){
  212. sd_domnode_t* maxsize = sd_domnode_attrs_get(anode, _T("maxsize"));
  213. sd_domnode_t* maxnum = sd_domnode_attrs_get(anode, _T("maxnum"));
  214. rollingpolicy_sizewin_udata_t *sizewin_udatap = NULL;
  215. sd_debug(_T("type='sizewin', maxsize='%s', maxnum='%s', rpolicyname='%s'"),
  216. (maxsize && maxsize->value ? maxsize->value : _T("(not set)")),
  217. (maxnum && maxnum->value ? maxnum->value : _T("(not set)")),
  218. (name && name->value ? name->value : _T("(not set)")));
  219. /*
  220. * Get a new sizewin policy type and configure it.
  221. * Then attach it to the policy object.
  222. * Check to see if this policy already has a
  223. sw udata object. If so, leave as is except update
  224. the params
  225. */
  226. if ( !(sizewin_udatap = log4c_rollingpolicy_get_udata(rpolicyp))){
  227. sd_debug(_T("creating new sizewin udata for this policy"));
  228. sizewin_udatap = sizewin_make_udata();
  229. log4c_rollingpolicy_set_udata(rpolicyp,sizewin_udatap);
  230. a_maxsize = parse_byte_size(maxsize->value);
  231. if (a_maxsize)
  232. sizewin_udata_set_file_maxsize(sizewin_udatap, a_maxsize);
  233. else{
  234. sd_debug(_T("When parsing %s a size of 0 was returned. Default size %d will be used"),
  235. maxsize->value, ROLLINGPOLICY_SIZE_DEFAULT_MAX_FILE_SIZE);
  236. sizewin_udata_set_file_maxsize(sizewin_udatap, ROLLINGPOLICY_SIZE_DEFAULT_MAX_FILE_SIZE);
  237. }
  238. sizewin_udata_set_max_num_files(sizewin_udatap, _ttoi(maxnum->value));
  239. }else{
  240. sd_debug(_T("policy already has a sizewin udata--just updating params"));
  241. sizewin_udata_set_file_maxsize(sizewin_udatap, parse_byte_size(maxsize->value));
  242. sizewin_udata_set_max_num_files(sizewin_udatap, _ttoi(maxnum->value));
  243. /* allow the policy to initialize itself */
  244. log4c_rollingpolicy_init(rpolicyp,
  245. log4c_rollingpolicy_get_rfudata(rpolicyp));
  246. }
  247. }
  248. }
  249. sd_debug(_T("]"));
  250. return 0;
  251. }
  252. #endif
  253. /******************************************************************************/
  254. extern int log4c_rc_load(log4c_rc_t* this, const TCHAR* a_filename)
  255. {
  256. sd_list_iter_t* i = NULL;
  257. sd_domnode_t* node = NULL;
  258. sd_domnode_t* root_node = NULL;
  259. sd_debug(_T("parsing file '%s'\n"), a_filename);
  260. if (!this)
  261. return -1;
  262. root_node = sd_domnode_new(NULL, NULL);
  263. if (sd_domnode_load(root_node, a_filename) == -1) {
  264. sd_domnode_delete(root_node);
  265. return -1;
  266. }
  267. /* Check configuration file root node */
  268. if (_tcscmp(root_node->name, _T("log4c"))) {
  269. sd_error(_T("invalid root name %s"), root_node->name);
  270. sd_domnode_delete(root_node);
  271. return -1;
  272. }
  273. /* Check configuration file revision */
  274. if ( (node = sd_domnode_attrs_get(root_node, _T("version"))) != NULL)
  275. if (_tcscmp(version, node->value)) {
  276. sd_error(_T("version mismatch: %s != %s"), version, node->value);
  277. sd_domnode_delete(root_node);
  278. return -1;
  279. }
  280. /* backward compatibility. */
  281. if ( (node = sd_domnode_attrs_get(root_node, _T("cleanup"))) != NULL) {
  282. sd_debug(_T("attribute \"cleanup\" is deprecated"));
  283. this->config.nocleanup = !_ttoi(node->value);
  284. }
  285. /* load configuration elements */
  286. for (i = sd_list_begin(root_node->children);
  287. i != sd_list_end(root_node->children);
  288. i = sd_list_iter_next(i))
  289. {
  290. sd_domnode_t* node = i->data;
  291. if (!_tcscmp(node->name, _T("category"))) category_load(this, node);
  292. if (!_tcscmp(node->name, _T("appender"))) appender_load(this, node);
  293. #ifdef WITH_ROLLINGFILE
  294. if (!_tcscmp(node->name, _T("rollingpolicy")))rollingpolicy_load(this, node);
  295. #endif
  296. if (!_tcscmp(node->name, _T("layout"))) layout_load(this, node);
  297. if (!_tcscmp(node->name, _T("config"))) config_load(this, node);
  298. }
  299. sd_domnode_delete(root_node);
  300. return 0;
  301. }
  302. /******************************************************************************/
  303. extern int log4c_load(const TCHAR* a_filename)
  304. {
  305. return log4c_rc_load(&__log4c_rc, a_filename);
  306. }