iaction.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <assert.h>
  5. #include <syslog.h>
  6. #include <faux/str.h>
  7. #include <faux/conv.h>
  8. #include <faux/list.h>
  9. #include <faux/error.h>
  10. #include <klish/khelper.h>
  11. #include <klish/kaction.h>
  12. #include <klish/iaction.h>
  13. #define TAG "ACTION"
  14. static const char * const kaction_io_e_str[] = {
  15. NULL,
  16. "false",
  17. "true",
  18. "tty",
  19. };
  20. static const char *kaction_io_e_enum2str(kaction_io_e io)
  21. {
  22. if ((KACTION_IO_NONE == io) || (io >= KACTION_IO_MAX))
  23. return NULL;
  24. return kaction_io_e_str[io];
  25. }
  26. static kaction_io_e kaction_io_e_str2enum(const char *str)
  27. {
  28. kaction_io_e io = KACTION_IO_NONE;
  29. if (!str)
  30. return KACTION_IO_NONE;
  31. for (io = (KACTION_IO_NONE + 1); io < KACTION_IO_MAX; io++) {
  32. if (faux_str_casecmp(str, kaction_io_e_str[io]) == 0)
  33. break;
  34. }
  35. if (io >= KACTION_IO_MAX)
  36. return KACTION_IO_NONE;
  37. return io;
  38. }
  39. bool_t iaction_parse(const iaction_t *info, kaction_t *action, faux_error_t *error)
  40. {
  41. bool_t retcode = BOOL_TRUE;
  42. if (!info)
  43. return BOOL_FALSE;
  44. if (!action)
  45. return BOOL_FALSE;
  46. // Sym
  47. if (!faux_str_is_empty(info->sym)) {
  48. if (!kaction_set_sym_ref(action, info->sym)) {
  49. faux_error_add(error, TAG": Illegal 'sym' attribute");
  50. retcode = BOOL_FALSE;
  51. }
  52. }
  53. // Lock
  54. if (!faux_str_is_empty(info->lock)) {
  55. if (!kaction_set_lock(action, info->lock)) {
  56. faux_error_add(error, TAG": Illegal 'lock' attribute");
  57. retcode = BOOL_FALSE;
  58. }
  59. }
  60. // Interrupt
  61. if (!faux_str_is_empty(info->interrupt)) {
  62. bool_t b = BOOL_FALSE;
  63. if (!faux_conv_str2bool(info->interrupt, &b) ||
  64. !kaction_set_interrupt(action, b)) {
  65. faux_error_add(error, TAG": Illegal 'interrupt' attribute");
  66. retcode = BOOL_FALSE;
  67. }
  68. }
  69. // In
  70. if (!faux_str_is_empty(info->in)) {
  71. kaction_io_e io = KACTION_IO_NONE;
  72. if (((io = kaction_io_e_str2enum(info->in)) == KACTION_IO_NONE) ||
  73. !kaction_set_in(action, io)) {
  74. faux_error_add(error, TAG": Illegal 'in' attribute");
  75. retcode = BOOL_FALSE;
  76. }
  77. }
  78. // Out
  79. if (!faux_str_is_empty(info->out)) {
  80. kaction_io_e io = KACTION_IO_NONE;
  81. if (((io = kaction_io_e_str2enum(info->out)) == KACTION_IO_NONE) ||
  82. !kaction_set_out(action, io)) {
  83. faux_error_add(error, TAG": Illegal 'out' attribute");
  84. retcode = BOOL_FALSE;
  85. }
  86. }
  87. // Exec_on
  88. if (!faux_str_is_empty(info->exec_on)) {
  89. kaction_cond_e c = KACTION_COND_NONE;
  90. if (!faux_str_casecmp(info->exec_on, "fail"))
  91. c = KACTION_COND_FAIL;
  92. else if (!faux_str_casecmp(info->exec_on, "success"))
  93. c = KACTION_COND_SUCCESS;
  94. else if (!faux_str_casecmp(info->exec_on, "always"))
  95. c = KACTION_COND_ALWAYS;
  96. else if (!faux_str_casecmp(info->exec_on, "never"))
  97. c = KACTION_COND_NEVER;
  98. if ((KACTION_COND_NONE == c) || !kaction_set_exec_on(action, c)) {
  99. faux_error_add(error, TAG": Illegal 'exec_on' attribute");
  100. retcode = BOOL_FALSE;
  101. }
  102. }
  103. // Update_retcode
  104. if (!faux_str_is_empty(info->update_retcode)) {
  105. bool_t b = BOOL_FALSE;
  106. if (!faux_conv_str2bool(info->update_retcode, &b) ||
  107. !kaction_set_update_retcode(action, b)) {
  108. faux_error_add(error, TAG": Illegal 'update_retcode' attribute");
  109. retcode = BOOL_FALSE;
  110. }
  111. }
  112. // Permanent
  113. if (!faux_str_is_empty(info->permanent)) {
  114. tri_t b = TRI_UNDEFINED;
  115. if (!faux_conv_str2tri(info->permanent, &b) ||
  116. !kaction_set_permanent(action, b)) {
  117. faux_error_add(error, TAG": Illegal 'permanent' attribute");
  118. retcode = BOOL_FALSE;
  119. }
  120. }
  121. // Sync
  122. if (!faux_str_is_empty(info->sync)) {
  123. tri_t b = TRI_UNDEFINED;
  124. if (!faux_conv_str2tri(info->sync, &b) ||
  125. !kaction_set_sync(action, b)) {
  126. faux_error_add(error, TAG": Illegal 'sync' attribute");
  127. retcode = BOOL_FALSE;
  128. }
  129. }
  130. // Script
  131. if (!faux_str_is_empty(info->script)) {
  132. if (!kaction_set_script(action, info->script)) {
  133. faux_error_add(error, TAG": Illegal 'script' attribute");
  134. retcode = BOOL_FALSE;
  135. }
  136. }
  137. return retcode;
  138. }
  139. kaction_t *iaction_load(const iaction_t *iaction, faux_error_t *error)
  140. {
  141. kaction_t *kaction = NULL;
  142. kaction = kaction_new();
  143. if (!kaction) {
  144. faux_error_add(error, TAG": Can't create object");
  145. return NULL;
  146. }
  147. if (!iaction_parse(iaction, kaction, error)) {
  148. kaction_free(kaction);
  149. return NULL;
  150. }
  151. return kaction;
  152. }
  153. char *iaction_deploy(const kaction_t *kaction, int level)
  154. {
  155. char *str = NULL;
  156. char *tmp = NULL;
  157. char *exec_on = NULL;
  158. if (!kaction)
  159. return NULL;
  160. tmp = faux_str_sprintf("%*cACTION {\n", level, ' ');
  161. faux_str_cat(&str, tmp);
  162. faux_str_free(tmp);
  163. attr2ctext(&str, "sym", kaction_sym_ref(kaction), level + 1);
  164. attr2ctext(&str, "lock", kaction_lock(kaction), level + 1);
  165. attr2ctext(&str, "interrupt", faux_conv_bool2str(kaction_interrupt(kaction)), level + 1);
  166. attr2ctext(&str, "in", kaction_io_e_enum2str(kaction_in(kaction)), level + 1);
  167. attr2ctext(&str, "out", kaction_io_e_enum2str(kaction_out(kaction)), level + 1);
  168. // Exec_on
  169. switch (kaction_exec_on(kaction)) {
  170. case KACTION_COND_FAIL:
  171. exec_on = "fail";
  172. break;
  173. case KACTION_COND_SUCCESS:
  174. exec_on = "success";
  175. break;
  176. case KACTION_COND_ALWAYS:
  177. exec_on = "always";
  178. break;
  179. case KACTION_COND_NEVER:
  180. exec_on = "never";
  181. break;
  182. default:
  183. exec_on = NULL;
  184. }
  185. attr2ctext(&str, "exec_on", exec_on, level + 1);
  186. attr2ctext(&str, "update_retcode", faux_conv_bool2str(kaction_update_retcode(kaction)), level + 1);
  187. attr2ctext(&str, "permanent", faux_conv_tri2str(kaction_permanent(kaction)), level + 1);
  188. attr2ctext(&str, "sync", faux_conv_tri2str(kaction_sync(kaction)), level + 1);
  189. attr2ctext(&str, "script", kaction_script(kaction), level + 1);
  190. tmp = faux_str_sprintf("%*c},\n\n", level, ' ');
  191. faux_str_cat(&str, tmp);
  192. faux_str_free(tmp);
  193. return str;
  194. }