expect.c
上传用户:mei_mei897
上传日期:2007-01-05
资源大小:82k
文件大小:8k
源码类别:

手机短信编程

开发平台:

Unix_Linux

  1. /* -------------------------------------------------------------------- */
  2. /* SMS Client, send messages to mobile phones and pagers */
  3. /* */
  4. /* expect.c */
  5. /* */
  6. /*  Copyright (C) 1997,1998 Angelo Masci */
  7. /* */
  8. /*  This library is free software; you can redistribute it and/or */
  9. /*  modify it under the terms of the GNU Library General Public */
  10. /*  License as published by the Free Software Foundation; either */
  11. /*  version 2 of the License, or (at your option) any later version. */
  12. /* */
  13. /*  This library is distributed in the hope that it will be useful, */
  14. /*  but WITHOUT ANY WARRANTY; without even the implied warranty of */
  15. /*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU */
  16. /*  Library General Public License for more details. */
  17. /* */
  18. /*  You should have received a copy of the GNU Library General Public */
  19. /*  License along with this library; if not, write to the Free */
  20. /*  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
  21. /* */
  22. /*  You can contact the author at this e-mail address: */
  23. /* */
  24. /*  angelo@styx.demon.co.uk */
  25. /* */
  26. /* -------------------------------------------------------------------- */
  27. /* $Id: expect.c,v 5.1 1998/02/01 07:10:39 root Exp root $
  28.    -------------------------------------------------------------------- */
  29. #include <stdio.h>
  30. #include <errno.h>
  31. #include <signal.h>
  32. #include <string.h>
  33. #include <unistd.h>
  34. #include <errno.h>
  35. #include <stdlib.h>
  36. #include "common.h"
  37. #include "logfile.h"
  38. #include "sms_error.h"
  39. /* -------------------------------------------------------------------- */
  40. #define MAX_LINE  4096
  41. static int caught_alarm = 0;
  42. /* -------------------------------------------------------------------- */
  43. static void signal_alarm(int);
  44. static int expread(int, char *);
  45. static int expwrite(int, char *);
  46. /* -------------------------------------------------------------------- */
  47. /* -------------------------------------------------------------------- */
  48. static void signal_alarm(int signo)
  49. {
  50. caught_alarm = 1;
  51. return;
  52. }
  53. /* -------------------------------------------------------------------- */
  54. /* Read explen characters from fd and copy to str, */
  55. /* appending ''. Compare explen characters of str with expect_string. */
  56. /* */
  57. /* Return Values: */
  58. /* */
  59. /*  0 Expect_string is found before timeout expires */
  60. /* -1 Error or Timeout exceeded */
  61. /* */
  62. /* -------------------------------------------------------------------- */
  63. int expnstr(int fd, char *str, char *expect_string, int explen, int timeout)
  64. {
  65. int  i;
  66. char  *ptr;
  67. /* ---------------------------- */
  68. caught_alarm = 0;
  69. if (signal(SIGALRM, signal_alarm) == SIG_ERR)
  70. { exit(ESIGERR);
  71. }
  72. alarm(timeout);
  73. ptr = str;
  74. for (i=0; i<explen; i++)
  75. {
  76. switch (expread(fd, ptr))
  77. {
  78. case 1:
  79. { ptr++;
  80. break;
  81. }
  82. case 0:
  83. {
  84. *ptr = '';
  85. lprintf(LOG_WARNING, "EOF Detectedn");
  86. alarm(0);
  87. return -1;
  88. }
  89. default:
  90. {
  91. /* Timeout */
  92. *ptr = '';
  93. lprintf(LOG_ERROR, "Timeout: searching for +%s+ failed after %d secondsn", expect_string, timeout);
  94. lprintf(LOG_VERBOSE, "Received: +%s+n", str);
  95. alarm(0);
  96. return -1;
  97. }
  98. }
  99. }
  100. if (strncmp(str, expect_string, explen) == 0)
  101. {
  102. *ptr = '';
  103. lprintf(LOG_VERBOSE, "Received: +%s+n", str);
  104. alarm(0);
  105. return 0;
  106. }
  107. *ptr = '';
  108. lprintf(LOG_VERBOSE, "Received: +%s+n", str);
  109. alarm(0);
  110. return -1;
  111. }
  112. /* -------------------------------------------------------------------- */
  113. /* Read from open file fd and search for expect_string. */
  114. /* All data read is placed in str and terminated with '' */
  115. /* Return Values: */
  116. /* */
  117. /*  0 Expect_string is found before timeout expires */
  118. /* -1 Error errno is set appropriately. */
  119. /* */
  120. /* Errors: */
  121. /* */
  122. /*     ETIMEOUT Timeout exceeded */
  123. /*     EEOF     End of File encountered */
  124. /*     ELEN     Buffer length exceeded */
  125. /* */
  126. /* -------------------------------------------------------------------- */
  127. int expstr(int fd, char *str, char *expect_string, int maxlen, int timeout)
  128. {
  129. int  explen,
  130.   i,
  131. len;
  132. char  *ptr,
  133.   *cmpptr;
  134. /* ---------------------------- */
  135. explen = sms_strlen(expect_string);
  136. caught_alarm = 0;
  137. if (signal(SIGALRM, signal_alarm) == SIG_ERR)
  138. { exit(ESIGERR);
  139. }
  140. alarm(timeout);
  141. len = 0;
  142. ptr = str;
  143. for (i=0; i<explen; i++)
  144. {
  145. if (len >= maxlen)
  146. { alarm(0);
  147. return -1;
  148. }
  149. switch (expread(fd, ptr))
  150. {
  151. case 1:
  152. { ptr++;
  153. len++;
  154. break;
  155. }
  156. case 0:
  157. {
  158. *ptr = '';
  159. alarm(0);
  160. lprintf(LOG_WARNING, "EOF Detectedn");
  161. return -1;
  162. }
  163. default:
  164. {
  165. /* Timeout */
  166. *ptr = '';
  167. alarm(0);
  168. lprintf(LOG_ERROR, "Timeout: searching for +%s+ failed after %d secondsn", expect_string, timeout);
  169. lprintf(LOG_VERBOSE, "Received: +%s+n", str);
  170. return -1;
  171. }
  172. }
  173. }
  174. cmpptr = str;
  175. while (len < (maxlen -1))
  176. {
  177. if (strncmp(cmpptr, expect_string, explen) == 0)
  178. {
  179. *ptr = '';
  180. alarm(0);
  181. lprintf(LOG_VERBOSE, "Received: +%s+n", str);
  182. return 0;
  183. }
  184. cmpptr++;
  185. switch (expread(fd, ptr))
  186. {
  187. case 1:
  188. { ptr++;
  189. len++;
  190. break;
  191. }
  192. case 0:
  193. {
  194. *ptr = '';
  195. alarm(0);
  196. lprintf(LOG_WARNING, "EOF Detectedn");
  197. return -1;
  198. }
  199. default:
  200. {
  201. /* Timeout */
  202. *ptr = '';
  203. alarm(0);
  204. lprintf(LOG_ERROR, "Timeout: searching for +%s+ failed after %d secondsn", expect_string, timeout);
  205. lprintf(LOG_VERBOSE, "Received: +%s+n", str);
  206. return -1;
  207. }
  208. }
  209. }
  210. *ptr = '';
  211. alarm(0);
  212. lprintf(LOG_ERROR, "Buffer Length exceeded: searching for +%s+ failed after reading %d bytesn", expect_string, (maxlen -1));
  213. lprintf(LOG_VERBOSE, "Received: +%s+n", str);
  214. return -1;
  215. }
  216. /* -------------------------------------------------------------------- */
  217. /* -------------------------------------------------------------------- */
  218. static int expread(int fd, char *buf)
  219. {
  220. if (caught_alarm)
  221. { return -1; /* Timeout */
  222. }
  223. reread:
  224. switch (read(fd, buf, 1))
  225. {
  226. case  1:
  227. lprintf(LOG_VERYVERBOSE, "Received: +%c+n", buf[0]);
  228. return 1;  /* Sucessful Read */
  229. case -1:
  230. if (errno == EINTR)
  231. { if (caught_alarm)
  232. { return -1;  /* Timeout */
  233. }
  234. else
  235. { /* Received an interrupt */
  236. /* that wasn't our timer */
  237. /* safely ignore it and */
  238. /* reread data */
  239. goto reread;
  240. }
  241. }
  242. else
  243. { lprintf(LOG_ERROR, "Unknown read error %dn", errno);
  244. return -1;  /* ERROR */
  245. }
  246. }
  247. return 0;  /* EOF */
  248. }
  249. /* -------------------------------------------------------------------- */
  250. /* Write len bytes of buf to fd, return prematurely on timeout */
  251. /* Return Values: */
  252. /* */
  253. /* -1 On timeout */
  254. /*  0 Success */
  255. /* -------------------------------------------------------------------- */
  256. int twrite(int fd, char *buf, int len, int timeout)
  257. {
  258. char  *ptr,
  259. *line;
  260. int  i;
  261. /* ---------------------------- */
  262. caught_alarm = 0;
  263. if (signal(SIGALRM, signal_alarm) == SIG_ERR)
  264. { exit(ESIGERR);
  265. }
  266. alarm(timeout);
  267. ptr = buf;
  268. for (i=0; i<len; i++)
  269. {
  270. if (expwrite(fd, ptr) != 1)
  271. {
  272. /* Timeout */
  273. alarm(0);
  274. lprintf(LOG_ERROR, "Timeout: Written %d characters of +%s+ failed after %d secondsn", i, buf, timeout);
  275. return -1;
  276. }
  277. ptr++;
  278. }
  279. alarm(0);
  280. line = (char *)malloc(sizeof(char) * (len +1));
  281. if (line == NULL)
  282. { lprintf(LOG_ERROR, "malloc() failedn");
  283. exit(-1);
  284. }
  285. strncpy(line, buf, len);
  286. line[len] = '';
  287. lprintf(LOG_VERBOSE, "Written: +%s+n", line);
  288. free(line);
  289. return 0;
  290. }
  291. /* -------------------------------------------------------------------- */
  292. /* -------------------------------------------------------------------- */
  293. static int expwrite(int fd, char *buf)
  294. {
  295. if (caught_alarm)
  296. { return -1; /* Timeout */
  297. }
  298. rewrite:
  299. switch (write(fd, buf, 1))
  300. {
  301. case  1:
  302. lprintf(LOG_VERYVERBOSE, "Written: +%c+n", buf[0]);
  303. return 1;  /* Sucessful Write */
  304. case -1:
  305. if (errno == EINTR)
  306. { if (caught_alarm)
  307. { return -1;  /* Timeout */
  308. }
  309. else
  310. { /* Received an interrupt */
  311. /* that wasn't our timer */
  312. /* safely ignore it and */
  313. /* rewrite data */
  314. goto rewrite;
  315. }
  316. }
  317. else
  318. { lprintf(LOG_ERROR, "unknown write error %dn", errno);
  319. return -1;  /* ERROR */
  320. }
  321. }
  322. return 0;  /* Undefined */
  323. }