exec.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. /*
  2. *
  3. * $Id$
  4. *
  5. *
  6. * Copyright (C) 2001-2003 FhG Fokus
  7. *
  8. * This file is part of ser, a free SIP server.
  9. *
  10. * ser is free software; you can redistribute it and/or modify
  11. * it under the terms of the GNU General Public License as published by
  12. * the Free Software Foundation; either version 2 of the License, or
  13. * (at your option) any later version
  14. *
  15. * For a license to use the ser software under conditions
  16. * other than those described here, or to purchase support for this
  17. * software, please contact iptel.org by e-mail at the following addresses:
  18. * [email protected]
  19. *
  20. * ser is distributed in the hope that it will be useful,
  21. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  22. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  23. * GNU General Public License for more details.
  24. *
  25. * You should have received a copy of the GNU General Public License
  26. * along with this program; if not, write to the Free Software
  27. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  28. *
  29. * History
  30. * --------
  31. * 2003-02-28 scratchpad compatibility abandoned (jiri)
  32. * 2003-01-28 scratchpad removed
  33. * 2004-07-21 rewrite uri done via action() (bogdan)
  34. */
  35. #include "../../comp_defs.h"
  36. #include <stdio.h>
  37. #include <strings.h>
  38. #include <errno.h>
  39. #include <stdlib.h>
  40. #include <sys/types.h>
  41. /*
  42. #include <sys/resource.h>
  43. */
  44. #include <sys/wait.h>
  45. #include "../../mem/mem.h"
  46. #include "../../error.h"
  47. #include "../../config.h"
  48. #include "../../parser/msg_parser.h"
  49. #include "../../dprint.h"
  50. #include "../../dset.h"
  51. #include "../../action.h"
  52. #include "../../ut.h"
  53. #include "config.h"
  54. int exec_msg(struct sip_msg *msg, str* cmd )
  55. {
  56. FILE *pipe;
  57. int exit_status;
  58. int ret;
  59. char* c;
  60. ret=-1; /* pessimist: assume error */
  61. c = as_asciiz(cmd);
  62. if (!c) {
  63. ERR("No memory left\n");
  64. return -1;
  65. }
  66. pipe=popen( c, "w" );
  67. pkg_free(c);
  68. if (pipe==NULL) {
  69. LOG(L_ERR, "ERROR: exec_msg: cannot open pipe: %.*s\n",
  70. cmd->len, ZSW(cmd->s));
  71. ser_error=E_EXEC;
  72. return -1;
  73. }
  74. if (fwrite(msg->buf, 1, msg->len, pipe)!=msg->len) {
  75. LOG(L_ERR, "ERROR: exec_msg: error writing to pipe\n");
  76. ser_error=E_EXEC;
  77. goto error01;
  78. }
  79. /* success */
  80. ret=1;
  81. error01:
  82. if (ferror(pipe)) {
  83. LOG(L_ERR, "ERROR: exec_str: error in pipe: %s\n",
  84. strerror(errno));
  85. ser_error=E_EXEC;
  86. ret=-1;
  87. }
  88. exit_status=pclose(pipe);
  89. if (WIFEXITED(exit_status)) { /* exited properly .... */
  90. /* return false if script exited with non-zero status */
  91. if (WEXITSTATUS(exit_status)!=0) ret=-1;
  92. } else { /* exited erroneously */
  93. LOG(L_ERR, "ERROR: exec_msg: cmd %.*s failed. "
  94. "exit_status=%d, errno=%d: %s\n",
  95. cmd->len, ZSW(cmd->s), exit_status, errno, strerror(errno) );
  96. ret=-1;
  97. }
  98. return ret;
  99. }
  100. int exec_str(struct sip_msg *msg, str* cmd, char *param, int param_len) {
  101. struct action act;
  102. int cmd_len;
  103. FILE *pipe;
  104. char *cmd_line;
  105. int ret;
  106. char uri_line[MAX_URI_SIZE+1];
  107. int uri_cnt;
  108. int uri_len;
  109. int exit_status;
  110. struct run_act_ctx ra_ctx;
  111. /* pessimist: assume error by default */
  112. ret=-1;
  113. cmd_len=cmd->len+param_len+2;
  114. cmd_line=pkg_malloc(cmd_len);
  115. if (cmd_line==0) {
  116. ret=ser_error=E_OUT_OF_MEM;
  117. LOG(L_ERR, "ERROR: exec_str: no mem for command\n");
  118. goto error00;
  119. }
  120. /* 'command parameter \0' */
  121. memcpy(cmd_line, cmd->s, cmd->len); cmd_line[cmd->len]=' ';
  122. memcpy(cmd_line+cmd->len+1, param, param_len);cmd_line[cmd->len+param_len+1]=0;
  123. pipe=popen( cmd_line, "r" );
  124. if (pipe==NULL) {
  125. LOG(L_ERR, "ERROR: exec_str: cannot open pipe: %s\n",
  126. cmd_line);
  127. ser_error=E_EXEC;
  128. goto error01;
  129. }
  130. /* read now line by line */
  131. uri_cnt=0;
  132. while( fgets(uri_line, MAX_URI_SIZE, pipe)!=NULL){
  133. uri_len=strlen(uri_line);
  134. /* trim from right */
  135. while(uri_len && (uri_line[uri_len-1]=='\r'
  136. || uri_line[uri_len-1]=='\n'
  137. || uri_line[uri_len-1]=='\t'
  138. || uri_line[uri_len-1]==' ' )) {
  139. DBG("exec_str: rtrim\n");
  140. uri_len--;
  141. }
  142. /* skip empty line */
  143. if (uri_len==0) continue;
  144. /* ZT */
  145. uri_line[uri_len]=0;
  146. if (uri_cnt==0) {
  147. memset(&act, 0, sizeof(act));
  148. act.type = SET_URI_T;
  149. act.val[0].type = STRING_ST;
  150. act.val[0].u.string = uri_line;
  151. init_run_actions_ctx(&ra_ctx);
  152. if (do_action(&ra_ctx, &act, msg)<0) {
  153. LOG(L_ERR,"ERROR:exec_str : SET_URI_T action failed\n");
  154. ser_error=E_OUT_OF_MEM;
  155. goto error02;
  156. }
  157. } else {
  158. if (ser_append_branch(msg, uri_line, uri_len, 0, 0,
  159. Q_UNSPECIFIED, 0)==-1) {
  160. LOG(L_ERR, "ERROR: exec_str: append_branch failed;"
  161. " too many or too long URIs?\n");
  162. goto error02;
  163. }
  164. }
  165. uri_cnt++;
  166. }
  167. if (uri_cnt==0) {
  168. LOG(L_ERR, "ERROR:exec_str: no uri from %s\n", cmd_line );
  169. goto error02;
  170. }
  171. /* success */
  172. ret=1;
  173. error02:
  174. if (ferror(pipe)) {
  175. LOG(L_ERR, "ERROR: exec_str: error in pipe: %s\n",
  176. strerror(errno));
  177. ser_error=E_EXEC;
  178. ret=-1;
  179. }
  180. exit_status=pclose(pipe);
  181. if (WIFEXITED(exit_status)) { /* exited properly .... */
  182. /* return false if script exited with non-zero status */
  183. if (WEXITSTATUS(exit_status)!=0) ret=-1;
  184. } else { /* exited erroneously */
  185. LOG(L_ERR, "ERROR: exec_str: cmd %.*s failed. "
  186. "exit_status=%d, errno=%d: %s\n",
  187. cmd->len, ZSW(cmd->s), exit_status, errno, strerror(errno) );
  188. ret=-1;
  189. }
  190. error01:
  191. pkg_free(cmd_line);
  192. error00:
  193. return ret;
  194. }