gw_stuff.c
上传用户:eo_sii
上传日期:2007-01-05
资源大小:91k
文件大小:40k
源码类别:

手机短信编程

开发平台:

Unix_Linux

  1. /*==========================================================
  2.  * Program : gw_stuff.c                    Project : smslink
  3.  * Author  : Philippe Andersson.
  4.  * Date    : 01/03/00
  5.  * Version : 0.16b
  6.  * Notice  : (c) Les Ateliers du Heron, 1998 for Scitex Europe, S.A.
  7.  * Comment : Library of functions for the smslink sms2mail gateway.
  8.  *
  9.  * Modification History :
  10.  * - 0.01b (19/08/99) : Initial release. Moved the mail gateway-
  11.  *   specific functions from stuff.c over here.
  12.  * - 0.02b (28/09/99) : Created mailbox_run().
  13.  * - 0.03b (29/09/99) : Extensive rework. Added tkize_ibox_line(),
  14.  *   reset_mail_struct() and parse_smail().
  15.  * - 0.04b (04/10/99) : Added expand_addr().
  16.  * - 0.05b (17/10/99) : Expanded parse_smail() extensively.
  17.  * - 0.06b (19/10/99) : Debugged tkize_ibox_line(). Increased
  18.  *   debugging output. Created shell for send_mail().
  19.  * - 0.07b (20/10/99) : Added mkfromfield().
  20.  * - 0.08b (21/10/99) : Added is_dotted_quad () and resolve().
  21.  * - 0.09b (08/11/99) : Built dialog in send_mail(). Added
  22.  *   slurp_n_catch().
  23.  * - 0.10b (09/11/99) : Modified parse_smail() to provide a
  24.  *   default subject field if the SMS doesn't contain one. Involved
  25.  *   alter the parameters passed to the function. Cosmetics.
  26.  * - 0.11b (12/11/99) : Improved send_mail() to free() the
  27.  *   allocated space for the nicified date.
  28.  * - 0.12b (30/11/99) : Added temp file creation to mailbox_run().
  29.  * - 0.13b (24/02/00) : Completed the transfer routine to the
  30.  *   new mailbox file in mailbox_run().
  31.  * - 0.14b (26/02/00) : Made sure the lockfile (MBOX_LOCKF) was
  32.  *   deleted on each fatal error, as well as on SIGTERM being
  33.  *   caught (in mailgws_death()). Improved error reporting in
  34.  *   various functions. Cosmetics.
  35.  * - 0.15b (29/02/00) : Added functions to handle recepients
  36.  *   lists (as part of struct email_msg). Heavily modified most
  37.  *   functions (send_mail(), parse_smail(), expand_addr()) and
  38.  *   created sub_tkize_field() to account for changes in the
  39.  *   email_msg struct.
  40.  * - 0.16b (01/03/00) : Replaced the "old" slurp_n_catch() by
  41.  *   a new version inspired by get_gsm_answer() (cf. serv_stuff.c).
  42.  *   This should be more robust and less sensitive to the amount
  43.  *   of data sent back by the server (here: sendmail). Created
  44.  *   the clean_field() function (forgotten when split expand_addr()
  45.  *   from sub_tkize_field()).
  46.  *========================================================*/
  47. #include <unistd.h>
  48. #include <stdio.h>                         /* for fprintf */
  49. #include <stdlib.h>                  /* for errno & stuff */
  50. #include <errno.h>
  51. #include <string.h>
  52. #include <syslog.h>
  53. #include <netdb.h>                 /* for gethostbyname() */
  54. #include <sys/socket.h>
  55. #include <netinet/in.h>
  56. #include <arpa/inet.h>
  57. #include <sys/time.h>           /* for the struct timeval */
  58. #include <sys/types.h>
  59. #include <sys/ipc.h>
  60. #include <sys/ioctl.h>            /* for the ioctl() call */
  61. #ifdef LINUX_LC6
  62. #  include <limits.h>                     /* for PATH_MAX */
  63. #  include <linux/limits.h>
  64. #else
  65. #  include <limits.h>
  66. #endif
  67. #include "sms_serv.h"
  68. /*========================================================*/
  69. /* For debugging purposes only - comment out for normal compile */
  70. /* #define INCL_DEBUG_CODE */
  71. /*========================================================*/
  72. void mailgws_death ()
  73. {
  74.   extern int inbox_is_locked;
  75.   
  76.   /* log it... */
  77.   syslog ((FACILITY | LOG_INFO), "gateway exiting on SIGTERM.");
  78.   
  79.   /* remove inbox lock file if necessary */
  80.   if (inbox_is_locked) {
  81.     unlink (MBOX_LOCKF);
  82.   }
  83.   /* closes connection to the syslog daemon */
  84.   closelog ();
  85.   
  86.   /* now exits gracefully */
  87.   exit (0);
  88. }                                     /* mailgws_death () */
  89. /*========================================================*/
  90. void rcpt_list_init (rcpt_list *list)
  91. {
  92.   list->head = NULL;
  93.   list->tail = NULL;
  94. }                                    /* rcpt_list_init () */
  95. /*========================================================*/
  96. int empty_rcpt_list (rcpt_list list)
  97. {
  98.   return (list.head == NULL);
  99. }                                   /* empty_rcpt_list () */
  100. /*========================================================*/
  101. void rcpt_list_insert (rcpt_list *list, char *recepient)
  102. {
  103.   /* WARNING : the order of the elements might be relevent - let's
  104.    * store them as they were in the header => avoid inserting at
  105.    * list head. Do it at the tail. */
  106.   
  107.   int l;
  108.   struct rcpt_item *element;
  109.   /* alloc memory for new element */
  110.   element = (struct rcpt_item *) malloc (sizeof (struct rcpt_item));
  111.   if (!element) {
  112.     syslog ((FACILITY | LOG_ERR), "can't malloc() for new RCPT entry.");
  113.     unlink (MBOX_LOCKF);
  114.     syserr ("sms2mailgw: can't malloc() for new RCPT entry");
  115.   }
  116.   
  117.   /* initialize fields for new element */
  118.   l = strlen (recepient);
  119.   element->rcpt = (char *) malloc ((l + 1) * sizeof (char));
  120.   if (!element->rcpt) {
  121.     syslog ((FACILITY | LOG_ERR), "can't malloc() for new recepient string.");
  122.     unlink (MBOX_LOCKF);
  123.     syserr ("sms2mailgw: can't malloc() for new recepient string");
  124.   }
  125.   strcpy (element->rcpt, recepient);
  126.   
  127.   /* chain it in the list */
  128.   if (empty_rcpt_list (*list)) {
  129.     list->head = element;
  130.     list->tail = element;
  131.     element->next = NULL;
  132.     element->prev = NULL;
  133.   }
  134.   else {
  135.     element->next = NULL;
  136.     element->prev = list->tail;
  137.     list->tail->next = element;
  138.     list->tail = element;
  139.   }
  140. }                                  /* rcpt_list_insert () */
  141. /*========================================================*/
  142. void free_rcpt_list (rcpt_list *list)
  143. {
  144.   struct rcpt_item *cursor;
  145.   if (!empty_rcpt_list (*list)) {
  146.     /* hop to element before last */
  147.     cursor = list->tail->prev;
  148.     /* now go back and clean behind */
  149.     while (cursor != NULL) {
  150.       free (cursor->next->rcpt);
  151.       free (cursor->next);
  152.       cursor->next = NULL;
  153.       list->tail = cursor;
  154.       cursor = cursor->prev;
  155.     }                           /* while (cursor != NULL) */
  156.   }                          /* if (!empty_rcpt_list (... */
  157.   /* now clean last element and reset header */
  158.   free (list->head->rcpt);
  159.   free (list->head);
  160.   list->head = NULL;
  161.   list->tail = NULL;
  162. }                                    /* free_rcpt_list () */
  163. /*========================================================*/
  164. #ifdef INCL_DEBUG_CODE
  165. void print_rcpt_list (rcpt_list list)
  166. {
  167.   struct rcpt_item *cursor;
  168.   if (!empty_rcpt_list (list)) {
  169.     cursor = list.head;
  170.     fprintf (stderr, "<%s>n", cursor->rcpt);
  171.     while (cursor->next != NULL) {
  172.       cursor = cursor->next;
  173.       fprintf (stderr, "<%s>n", cursor->rcpt);
  174.     }
  175.   }
  176.   else {
  177.     fprintf (stderr, "sms2mailgw: empty recepient list.n");
  178.   }
  179. }                                    /* print_acl_list () */
  180. #endif
  181. /*========================================================*/
  182. int is_dotted_quad (char *string)
  183. {
  184.   int is_dq;
  185.   char *s;
  186.   int ntok = 0;
  187.   char *ptok = NULL;
  188.   long int ip_byte;
  189.   char **endptr;
  190.   char *dummyp;
  191.   
  192.   /*--------------------------------------Initializations */
  193.   s = (char *) malloc ((strlen (string) + 1) * sizeof (char));
  194.   if (! s) {
  195.     syslog ((FACILITY | LOG_ERR), "can't malloc().");
  196.     unlink (MBOX_LOCKF);
  197.     syserr ("sms2mailgw: can't malloc()");
  198.   }
  199.   strcpy (s, string);
  200.   /*--------------------------------------------Main Loop */
  201.   /* no point going any further if the 1st char. is not a digit */
  202.   is_dq = isdigit (string[0]);
  203.   if (is_dq) {
  204.     ptok = strtok (s, ".");
  205.     while (ptok != NULL) {
  206.       ntok++;
  207. #ifdef INCL_DEBUG_CODE
  208.       fprintf (stderr, "got token #%d : <%s>n", ntok, ptok);
  209. #endif
  210.       dummyp = ptok + strlen (ptok);
  211.       endptr = &dummyp;
  212.       ip_byte = strtol (ptok, endptr, 10);
  213.       if (strlen (*endptr) != 0) {
  214. #ifdef INCL_DEBUG_CODE
  215. fprintf (stderr, "error on token #%d : can't convert <%s>n", ntok, *endptr);
  216. #endif
  217. is_dq = FALSE;
  218.       }
  219.       ptok = strtok (NULL, ".");
  220.     }
  221.     if (ntok != 4) {
  222.       is_dq = FALSE;
  223.     }
  224.   }                                         /* if (is_dq) */
  225.   /*------------------------------------------Conclusions */
  226.   free (s);
  227.   /*-------------------------------------------------Exit */
  228.   return (is_dq);
  229. }                                    /* is_dotted_quad () */
  230. /*========================================================*/
  231. unsigned long int resolve (char *host)
  232. /* return the host ip address in network format */
  233. {
  234.   struct hostent *h_ent;
  235.   struct in_addr target_ip;
  236.   char **addrs;
  237.   char *scratch;
  238.   
  239.   if (is_dotted_quad (host)) {
  240. #ifdef INCL_DEBUG_CODE
  241.     fprintf (stderr, "I think I got an IP addressn");
  242. #endif
  243.     if (inet_aton (host, &target_ip) == 0)
  244.       syslog ((FACILITY | LOG_ERR), "invalid server IP address (%s).", host);
  245.       scratch = (char *) malloc ((MINIBUFF + 1) * sizeof (char));
  246.       sprintf (scratch, "sms2mailgw: invalid server IP address (%s)", host);
  247.       herror (scratch);
  248.       free (scratch);
  249.       unlink (MBOX_LOCKF);
  250.       exit (1);
  251.   }
  252.   else {
  253. #ifdef INCL_DEBUG_CODE
  254.     fprintf (stderr, "I think I got a host namen");
  255. #endif
  256.     if ((h_ent = gethostbyname (host)) == NULL) {
  257.       syslog ((FACILITY | LOG_ERR), "can't resolve hostname (%s).", host);
  258.       scratch = (char *) malloc ((MINIBUFF + 1) * sizeof (char));
  259.       sprintf (scratch, "sms2mailgw: can't resolve hostname (%s)", host);
  260.       herror (scratch);
  261.       free (scratch);
  262.       unlink (MBOX_LOCKF);
  263.       exit (1);
  264.     }
  265.     /* lines below cf. "Beginning Linux Progr.", pp. 468-473 */
  266.     addrs = h_ent->h_addr_list;
  267.     target_ip = *(struct in_addr *)*addrs;
  268. #ifdef INCL_DEBUG_CODE
  269.     fprintf (stderr, "server IP address is: [%s]n", inet_ntoa (target_ip));
  270. #endif
  271.   }                             /* if (isdigit (host[0])) */
  272.   return (target_ip.s_addr);
  273. }                                           /* resolve () */
  274. /*========================================================*/
  275. int tkize_ibox_line (char *l, struct inbox_line *tkl)
  276. {
  277.   char *token;
  278.   char *scratch;
  279.   
  280.   /*--------------------------------------Initializations */
  281.   /* copy input string to scratch space - we can't modify it */
  282.   scratch = (char *) malloc ((strlen (l) + 1) * sizeof (char));
  283.   if (! scratch) {
  284.     syslog ((FACILITY | LOG_ERR), "can't malloc().");
  285.     unlink (MBOX_LOCKF);
  286.     syserr ("sms2mailgw: can't malloc()");
  287.   }
  288.   scratch[0] = '';
  289.   strcpy (scratch, l);
  290.   
  291.   /*--------------------------------------Parsing routine */
  292.   /*...............................................Device */
  293.   if ((token = strtok (scratch, ",")) == NULL) {
  294.     return (-1);
  295.   }
  296.   strcpy (tkl->device, token);
  297.   
  298.   /*................................................MsgID */
  299.   if ((token = strtok (NULL, ",")) == NULL) {
  300.     return (-1);
  301.   }
  302.   tkl->msgid = atoi (token);
  303.   
  304.   /*..............................................FromGSM */
  305.   if ((token = strtok (NULL, ",")) == NULL) {
  306.     return (-1);
  307.   }
  308.   strcpy (tkl->fromgsm, token);
  309.   
  310.   /*.................................................Date */
  311.   if ((token = strtok (NULL, ",")) == NULL) {
  312.     return (-1);
  313.   }
  314.   strcpy (tkl->date, token);
  315.   
  316.   /*.................................................Time */
  317.   if ((token = strtok (NULL, ",")) == NULL) {
  318.     return (-1);
  319.   }
  320.   strcpy (tkl->time, token);
  321.   
  322.   /*.................................................Text */
  323.   /* just grab the rest of the line */
  324.   if ((token = strtok (NULL, "")) == NULL) {
  325.     return (-1);
  326.   }
  327.   /* remove trailing LF */
  328.   token[strlen (token) - 1] = '';
  329.   dequote (token);
  330.   strcpy (tkl->text, token);
  331.   
  332.   /*-------------------------------------------------Exit */
  333.   free (scratch);
  334.   return 0;                                    /* success */
  335. }                                   /* tkize_ibox_line () */
  336. /*========================================================*/
  337. char *expand_addr (char *field, char *defdom)
  338. {
  339.   char *newstring;
  340.   /*---------------------------------------Initialization */
  341.   newstring = (char *) malloc ((BIGBUFF + 1) * sizeof (char));
  342.   if (! newstring) {
  343.     syslog ((FACILITY | LOG_ERR), "can't malloc().");
  344.     unlink (MBOX_LOCKF);
  345.     syserr ("sms2mailgw: can't malloc()");
  346.   }
  347.   newstring[0] = '';
  348.   
  349.   /*---------------------------------Main processing loop */
  350.   if (strchr (field, '@') == NULL) {
  351.     sprintf (newstring, "%s@%s", field, defdom);
  352.   }
  353.   else {
  354.     strcpy (newstring, field);
  355.   }
  356.   /*------------------------------------------Conclusions */
  357. #ifdef INCL_DEBUG_CODE
  358.   fprintf (stderr, "expanded field: [%s]n", newstring);
  359. #endif
  360.   return (newstring);
  361. }                                       /* expand_addr () */
  362. /*========================================================*/
  363. char *clean_field (char *field)
  364. /* For fields that cannot be multi-part (Reply-to:), remove
  365.  * the field header and any additional address. */
  366. {
  367.   char *ptr;
  368.   
  369.   /* The field for sure has a field header - skip it */
  370.   shiftleft (field, 2);
  371.   /* If the first char now is a space, skip that as well */
  372.   if (field[0] == ' ') {
  373.     shiftleft (field, 1);
  374.   }
  375.   /* If the field contains a comma, kill it and all that follows */
  376.   if ((ptr = strchr (field, ',')) != NULL) {
  377.     ptr[0] = '';
  378.   }
  379.   
  380.   return (field);
  381. }                                       /* clean_field () */
  382. /*========================================================*/
  383. int sub_tkize_field (rcpt_list *list, char *field, char *defdom)
  384. {
  385.   int nfields = 0;
  386.   char *s;
  387.   char *ptr;
  388.   char *newstring;
  389.   char *item;
  390.   
  391.   /*---------------------------------------Initialization */
  392.   /* take a local copy of "field" to avoid it being modified */
  393.   s = (char *) malloc ((strlen (field) + 1) * sizeof (char));
  394.   if (! s) {
  395.     syslog ((FACILITY | LOG_ERR), "can't malloc().");
  396.     unlink (MBOX_LOCKF);
  397.     syserr ("sms2mailgw: can't malloc()");
  398.   }
  399.   s[0] = '';
  400.   strcpy (s, field);
  401.   ptr = s;
  402.   
  403.   /* s for sure has a field header ("T:" for inst.) - skip it */
  404.   ptr += 2;
  405.   /* if there was a blank between the header and the field, skip it too */
  406.   if (ptr[0] == ' ') {
  407.     ptr++;
  408.   }
  409.   
  410.   /*---------------------------------Main processing loop */
  411.   if ((item = strtok (ptr, ",")) == NULL) {
  412.     /* field header w/o contents */
  413.     free (s);
  414.     return (nfields);
  415.   }
  416.   /* process first item */
  417.   newstring = expand_addr (item, defdom);
  418.   rcpt_list_insert (list, newstring);
  419.   nfields++;
  420.   free (newstring);
  421.   
  422.   /* now tokenize and process the rest */
  423.   while ((item = strtok (NULL, ",")) != NULL) {
  424.     /* process additional item(s) */
  425.     newstring = expand_addr (item, defdom);
  426.     rcpt_list_insert (list, newstring);
  427.     nfields++;
  428.     free (newstring);
  429.   }                                        /* while (...) */
  430.   /*------------------------------------------Conclusions */
  431.   free (s);
  432.   return (nfields);
  433. }                                   /* sub_tkize_field () */
  434. /*========================================================*/
  435. char *mkfromfield (char *srcgsm, char *host, char *defdom)
  436. {
  437.   char *fromfield;
  438.   
  439.   /*--------------------------------------Initializations */
  440.   fromfield = (char *) malloc ((BUFFSIZE + 1) * sizeof (char));
  441.   if (! fromfield) {
  442.     syslog ((FACILITY | LOG_ERR), "can't malloc().");
  443.     unlink (MBOX_LOCKF);
  444.     syserr ("sms2mailgw: can't malloc()");
  445.   }
  446.   fromfield[0] = '';
  447.   
  448.   /*-------------------------------------------Processing */
  449.   sprintf (fromfield, "%s%s@%s.%s", GWUSER, srcgsm, host, defdom);
  450.   
  451.   /*------------------------------------------Conclusions */
  452.   return (fromfield);
  453. }                                       /* mkfromfield () */
  454. /*========================================================*/
  455. void reset_mail_struct (struct email_msg *m)
  456. {
  457.   if (m->from) {
  458.     free (m->from);
  459.     m->from = NULL;
  460.   }
  461.   
  462.   if (!empty_rcpt_list (m->to))
  463.     free_rcpt_list (&(m->to));
  464.   if (!empty_rcpt_list (m->cc))
  465.     free_rcpt_list (&(m->cc));
  466.   if (!empty_rcpt_list (m->bcc))
  467.     free_rcpt_list (&(m->bcc));
  468.   
  469.   if (m->reply_to) {
  470.     free (m->reply_to);
  471.     m->reply_to = NULL;
  472.   }
  473.   if (m->subject) {
  474.     free (m->subject);
  475.     m->subject = NULL;
  476.   }
  477.   if (m->body) {
  478.     free (m->body);
  479.     m->body = NULL;
  480.   }
  481. }                                 /* reset_mail_struct () */
  482. /*========================================================*/
  483. int parse_smail (struct inbox_line *ibl, struct email_msg *m, char *host,
  484.                  char *domain)
  485. {
  486.   char *s;
  487.   char *s_saved;
  488.   char *ptr;
  489.   char *s_end;
  490.   int end_found;
  491.   char field_header;
  492.   char end_marker;
  493.   
  494.   /*--------------------------------------Initializations */
  495.   /* struct email fields */
  496.   m->from = NULL;
  497.   rcpt_list_init (&(m->to));
  498.   rcpt_list_init (&(m->cc));
  499.   rcpt_list_init (&(m->bcc));
  500.   m->reply_to = NULL;
  501.   m->subject = NULL;
  502.   m->body = NULL;
  503.   
  504.   /* copy sms string to scratch space - we can't modify it */
  505.   s = (char *) malloc ((MAXMSGLEN + 1) * sizeof (char));
  506.   if (! s) {
  507.     syslog ((FACILITY | LOG_ERR), "can't malloc().");
  508.     unlink (MBOX_LOCKF);
  509.     syserr ("sms2mailgw: can't malloc()");
  510.   }
  511.   s[0] = '';
  512.   strcpy (s, ibl->text);
  513.   s_saved = s;
  514. #ifdef INCL_DEBUG_CODE
  515.   fprintf (stderr, "ns as received:n[%s]n", s);
  516. #endif
  517.   
  518.   /*--------------------------------------Main Processing */
  519.   /* First field have to be To: */
  520.   if ((toupper (s[0]) == 'T') && (s[1] == ':')) {
  521.     /* if space between : and address, remove it */
  522.     if (s[2] == ' ') {
  523.       ptr = (s + 2);
  524.       shiftleft (ptr, 1);
  525.     }
  526.     end_found = FALSE;
  527.     ptr = s;
  528.     while (!end_found) {
  529.       if ((ptr = strchr (ptr, ' ')) == NULL) {
  530.         /* To: was the only field */
  531.         syslog ((FACILITY | LOG_ERR), "can't parse, nothing more than To: field.");
  532. free (s_saved);
  533. return (-1);
  534.       }
  535.       if ((ptr[-1] == ',') && (ptr[0] != '')) {
  536.         /* we have a multipart to: field */
  537. ptr++;
  538.       }
  539.       else {
  540.         end_found = TRUE;
  541. s_end = ptr;
  542.       }
  543.     }                               /* while (!end_found) */
  544.     if (ptr[0] != '') {
  545.       ptr++;
  546.     }
  547.     s_end[0] = '';
  548.     /* sub-tokenize it and save it */
  549. #ifdef INCL_DEBUG_CODE
  550.     fprintf (stderr, "to field: [%s]n", s);
  551. #endif
  552.     sub_tkize_field (&(m->to), s, domain);
  553.     
  554.     /* reset s to begin of next field */
  555.     s = ptr;
  556.     
  557.     /* now loop to process the rest */
  558.     while (s[0]) {
  559.       field_header = toupper (s[0]);
  560.       if ((strchr (FIELD_HEADERS, field_header) != NULL) && (s[1] == ':')) {
  561.         /* we have a valid header */
  562. switch (field_header) {
  563.   case 'T' : {
  564.     end_marker = ' ';
  565.     break;
  566.   }
  567.   
  568.   case 'C' : {
  569.     end_marker = ' ';
  570.     break;
  571.   }
  572.   
  573.   case 'R' : {
  574.     if (m->reply_to) {
  575.       free (m->reply_to);
  576.     }
  577.     end_marker = ' ';
  578.     break;
  579.   }
  580.   
  581.   case 'B' : {
  582.     end_marker = ' ';
  583.     break;
  584.   }
  585.   
  586.   case 'F' : {
  587.     if (m->from) {
  588.       free (m->from);
  589.     }
  590.     end_marker = ' ';
  591.     break;
  592.   }
  593.   
  594.   case 'S' : {
  595.     if (m->subject) {
  596.       free (m->subject);
  597.     }
  598.     end_marker = '#';
  599.     break;
  600.   }
  601. }                        /* switch (field_header) */
  602. /* if space between : and address, remove it */
  603. if (s[2] == ' ') {
  604.   ptr = (s + 2);
  605.   shiftleft (ptr, 1);
  606. }
  607. end_found = FALSE;
  608. ptr = s;
  609. while (!end_found) {
  610.   if ((ptr = strchr (ptr, end_marker)) == NULL) {
  611.     /* we reached end-of-string */
  612.     end_found = TRUE;
  613.     ptr = s + strlen (s);
  614.     s_end = ptr;
  615.   }
  616.   else {
  617.     if ((ptr[-1] == ',') && (ptr[0] != '')) {
  618.       /* multipart field */
  619.       ptr++;
  620.     }
  621.     else {
  622.       end_found = TRUE;
  623.       s_end = ptr;
  624.     }
  625.   }                  /* if (end_marker not found) */
  626. }                           /* while (!end_found) */
  627. if (ptr[0] != '') {
  628.   ptr++;
  629. }
  630. s_end[0] = '';
  631. /* assigns the right field */
  632. switch (field_header) {
  633.   case 'T' : {
  634. #ifdef INCL_DEBUG_CODE
  635.             fprintf (stderr, "field: [%s]n", s);
  636. #endif
  637.             sub_tkize_field (&(m->to), s, domain);
  638.     break;
  639.   }
  640.   
  641.   case 'C' : {
  642. #ifdef INCL_DEBUG_CODE
  643.             fprintf (stderr, "field: [%s]n", s);
  644. #endif
  645.             sub_tkize_field (&(m->cc), s, domain);
  646.     break;
  647.   }
  648.   
  649.   case 'R' : {
  650. #ifdef INCL_DEBUG_CODE
  651.             fprintf (stderr, "field: [%s]n", s);
  652. #endif
  653.             clean_field (s);
  654.     m->reply_to = expand_addr (s, domain);
  655.     break;
  656.   }
  657.   
  658.   case 'B' : {
  659. #ifdef INCL_DEBUG_CODE
  660.             fprintf (stderr, "field: [%s]n", s);
  661. #endif
  662.             sub_tkize_field (&(m->bcc), s, domain);
  663.     break;
  664.   }
  665.   
  666.   case 'F' : {
  667. #ifdef INCL_DEBUG_CODE
  668.             fprintf (stderr, "field: [%s]n", s);
  669. #endif
  670.             clean_field (s);
  671.             m->from = expand_addr (s, domain);
  672.     break;
  673.   }
  674.   
  675.   case 'S' : {
  676. #ifdef INCL_DEBUG_CODE
  677.             fprintf (stderr, "field: [%s]n", s);
  678. #endif
  679.     /* remove field header */
  680.     s += 2;
  681.     /* if ':' is followed by ' ', remove it as well */
  682.     if ((s[0]) && (s[0] == ' ')) {
  683.       s++;
  684.     }
  685.     m->subject = (char *) malloc ((strlen (s) + 1) * sizeof (char));
  686.     if (! m->subject) {
  687.       syslog ((FACILITY | LOG_ERR), "can't malloc().");
  688.               unlink (MBOX_LOCKF);
  689.       syserr ("sms2mailgw: can't malloc()");
  690.     }
  691.     m->subject[0] = '';
  692.     strcpy (m->subject, s);
  693.     break;
  694.   }
  695. }                        /* switch (field_header) */
  696. s = ptr;
  697.       }
  698.       else {
  699.         /* the rest is considered BODY */
  700. if (s[0]) {
  701. #ifdef INCL_DEBUG_CODE
  702.           fprintf (stderr, "body: [%s]n", s);
  703. #endif
  704.   m->body = (char *) malloc ((strlen (s) + 1) * sizeof (char));
  705.   if (! m->body) {
  706.     syslog ((FACILITY | LOG_ERR), "can't malloc().");
  707.             unlink (MBOX_LOCKF);
  708.     syserr ("sms2mailgw: can't malloc()");
  709.   }
  710.   m->body[0] = '';
  711.   strcpy (m->body, s);
  712.   ptr = s + strlen (s);
  713.   s = ptr;
  714. }                                    /* if (s[0]) */
  715.       }                        /* if (valid header found) */
  716.     }                                     /* while (s[0]) */
  717.   }
  718.   else {
  719.     /* can't even find To: field */
  720.     syslog ((FACILITY | LOG_ERR), "can't parse, can't find To: field.");
  721.     free (s_saved);
  722.     return (-1);
  723.   }                           /* if ('T' followed by ':') */
  724.   
  725.   /*--------------------------Make sure we have a subject */
  726.   if (! m->subject) {
  727.     m->subject = (char *) malloc ((MINIBUFF + 1) * sizeof (char));
  728.     if (! m->subject) {
  729.       syslog ((FACILITY | LOG_ERR), "can't malloc().");
  730.       unlink (MBOX_LOCKF);
  731.       syserr ("sms2mailgw: can't malloc()");
  732.     }
  733.     m->subject[0] = '';
  734.     sprintf (m->subject, "An SMS for you from GSM number %s.", ibl->fromgsm);
  735.   }
  736.   /*-------------------------------------------------Exit */
  737.   free (s_saved);
  738.   return 0;                                    /* success */
  739. }                                       /* parse_smail () */
  740. /*========================================================*/
  741. int slurp_n_catch (int fd, int resptime, char *catch)
  742. /* slurps n_lines lines from the input stream, and return a bool
  743. value telling whether catch was found in any of those lines. */
  744. {
  745.   int nread, retval, previous, found;
  746.   fd_set inputs;
  747.   struct timeval timeout;
  748.   char *buffer;
  749.   
  750.   /*--------------------------------------Initializations */
  751.   nread = previous = 0;
  752.   found = FALSE;
  753.   
  754.   FD_ZERO (&inputs);
  755.   FD_SET (fd, &inputs);
  756.   
  757.   timeout.tv_sec = 10;
  758.   timeout.tv_usec = 0;
  759.   
  760.   /* wait for data to arrive on the line */
  761.   retval = select (FD_SETSIZE, &inputs, NULL, NULL, &timeout);
  762.   switch (retval) {
  763.     case 0:
  764.       syslog ((FACILITY | LOG_WARNING), "timeout while waiting for server reply.");
  765.       break;
  766.     
  767.     case -1:
  768.       syslog ((FACILITY | LOG_ERR), "call to select() failed.");
  769.       unlink (MBOX_LOCKF);
  770.       syserr ("sms2mailgw: call to select() failed");
  771.       break;
  772.       
  773.     default:
  774.       if (FD_ISSET (fd, &inputs)) {
  775.         /* first wait for all data to be ready */
  776. ioctl (fd, FIONREAD, &nread);
  777. while (nread != previous) {
  778.   sleep (resptime);
  779.   previous = nread;
  780.   ioctl (fd, FIONREAD, &nread);
  781. }                    /* while (nread != previous) */
  782. /* we know what's the data size - alloc space for it */
  783. buffer = (char *) malloc ((nread + 1) * sizeof (char));
  784. if (!buffer) {
  785.           syslog ((FACILITY | LOG_ERR), "can't allocate buffer space.");
  786.           unlink (MBOX_LOCKF);
  787.   syserr ("sms2mailgw: can't allocate buffer space");
  788. }
  789. /* now we can finally read this data */
  790. nread = read (fd, buffer, nread);
  791. switch (nread) {
  792.   case 0:
  793.     /* EOF */
  794.     buffer[nread] = '';
  795.     syslog ((FACILITY | LOG_WARNING), "no data from server waiting for [%s].",
  796.             catch);
  797.     break;
  798.     
  799.   case -1:
  800.             syslog ((FACILITY | LOG_ERR), "error while reading answer from server.");
  801.             unlink (MBOX_LOCKF);
  802.     syserr ("sms2mailgw: error while reading answer from server");
  803.     break;
  804.     
  805.   default:
  806.     buffer[nread] = '';
  807. #ifdef INCL_DEBUG_CODE
  808.     fprintf (stderr, "pid<%d> Got : [%s] (%d char)n", getpid (), buffer, nread);
  809. #endif
  810.     /* here we could pre-process it (remove Ctrl-Z) */
  811.     /* look for catch */
  812.             found = (strstr (buffer, catch) != NULL);
  813.     break;
  814. }                               /* switch (nread) */
  815.       }                                /* if (FD_ISSET... */
  816.       free (buffer);
  817.       break;
  818.   }                                    /* switch (retval) */
  819.   /*------------------------------------------------------*/
  820. #ifdef INCL_DEBUG_CODE
  821.   fprintf (stderr, "catch found: [%s]n", found ? "yes" : "no");
  822. #endif
  823.   /*----------------------------------Conclusion and exit */
  824.   return (found);
  825. }                                     /* slurp_n_catch () */
  826. /*========================================================*/
  827. int send_mail (struct email_msg *m, struct inbox_line *ibl, char *mailhost,
  828.                char *localhost, char *defdom)
  829. {
  830.   struct servent *sent;
  831.   struct in_addr server_ip;
  832.   struct sockaddr_in sockaddr;
  833.   struct rcpt_item *cursor;
  834.   int sockfd;
  835.   int addrlen;
  836.   char *cmdline;
  837.   char *nd;
  838. #ifdef INCL_DEBUG_CODE
  839.   fprintf (stderr, "===========================================n");
  840.   if (m->from)
  841.     fprintf (stderr, "From: %sn", m->from);
  842.   if (!empty_rcpt_list (m->to)) {
  843.     fprintf (stderr, "To: recepientsn");
  844.     print_rcpt_list (m->to);
  845.   }
  846.   if (!empty_rcpt_list (m->cc)) {
  847.     fprintf (stderr, "CC: recepientsn");
  848.     print_rcpt_list (m->cc);
  849.   }
  850.   if (!empty_rcpt_list (m->bcc)) {
  851.     fprintf (stderr, "BCC: recepientsn");
  852.     print_rcpt_list (m->bcc);
  853.   }
  854.   if (m->reply_to)
  855.     fprintf (stderr, "Reply-To: %sn", m->reply_to);
  856.   if (m->subject)
  857.     fprintf (stderr, "Subject: %sn", m->subject);
  858.   if (m->body)
  859.     fprintf (stderr, "%sn", m->body);
  860.   fprintf (stderr, "===========================================n");
  861. #endif
  862.     
  863.   /*--------------------------------------Initializations */
  864.   cmdline = (char *) malloc ((BUFFSIZE + 1) * sizeof (char));
  865.   if (!cmdline) {    
  866.     syslog ((FACILITY | LOG_ERR), "can't malloc().");
  867.     unlink (MBOX_LOCKF);
  868.     syserr ("sms2mailgw: can't malloc()");
  869.   }
  870.   cmdline[0] = '';
  871.   /* first resolve server name */
  872.   server_ip.s_addr = resolve (mailhost);
  873.   
  874.   /* get the port number we should connect to */
  875.   if ((sent = getservbyname ("smtp", "tcp")) == NULL) {
  876.     syslog ((FACILITY | LOG_ERR), "can't get service port info.");
  877.     unlink (MBOX_LOCKF);
  878.     syserr ("sms2mailgw: can't get service port info");
  879.   }
  880. #ifdef INCL_DEBUG_CODE
  881.   fprintf (stderr, "found port <%d> for service smtpn", ntohs (sent->s_port));
  882. #endif
  883.     
  884.   /* create the socket */
  885.   if ((sockfd = socket (AF_INET, SOCK_STREAM, 0)) == -1) {
  886.     syslog ((FACILITY | LOG_ERR), "can't create socket.");
  887.     unlink (MBOX_LOCKF);
  888.     syserr ("sms2mailgw: can't create socket");
  889.   }
  890.   
  891.   /* build the server socket address parameters */
  892.   sockaddr.sin_family = AF_INET;
  893.   sockaddr.sin_port = sent->s_port;
  894.   sockaddr.sin_addr.s_addr = server_ip.s_addr;
  895.   addrlen = sizeof (sockaddr);
  896.   
  897.   /* now connect to the server */
  898.   if (connect (sockfd, (struct sockaddr *)&sockaddr, addrlen) == -1) {
  899.     syslog ((FACILITY | LOG_ERR), "can't connect to server.");
  900.     unlink (MBOX_LOCKF);
  901.     syserr ("sms2mailgw: can't connect to server");
  902.   }
  903.     
  904.   /*......................................Start of dialog */
  905.   /* slurp server announce and catch prompt */
  906.   if (!slurp_n_catch (sockfd, 1, "220")) {
  907.     syslog ((FACILITY | LOG_ERR), "can't get server announce.");
  908.     unlink (MBOX_LOCKF);
  909.     syserr ("sms2mailgw: can't get server announce");
  910.   }
  911.     
  912.   /* set sender ID - get ok */
  913.   sprintf (cmdline, "HELO %s.%sn", localhost, defdom);
  914.   tellsock (sockfd, cmdline);
  915.   if (!slurp_n_catch (sockfd, 1, "250")) {
  916.     syslog ((FACILITY | LOG_ERR), "failed on HELO command.");
  917.     unlink (MBOX_LOCKF);
  918.     syserr ("sms2mailgw: failed on HELO command");
  919.   }
  920.     
  921.   /* send from: field */
  922.   sprintf (cmdline, "MAIL FROM: %sn", m->from);
  923.   tellsock (sockfd, cmdline);
  924.   if (!slurp_n_catch (sockfd, 1, "250")) {
  925.     syslog ((FACILITY | LOG_ERR), "failed on MAIL command.");
  926.     unlink (MBOX_LOCKF);
  927.     syserr ("sms2mailgw: failed on MAIL command");
  928.   }
  929.   
  930.   /*. . . . . . . . . . . . . Loop through all recepients */
  931.   /* To: field */
  932.   if (!empty_rcpt_list (m->to)) {
  933.     cursor = m->to.head;
  934.     sprintf (cmdline, "RCPT TO: %sn", cursor->rcpt);
  935.     tellsock (sockfd, cmdline);
  936.     if (!slurp_n_catch (sockfd, 1, "250")) {
  937.       syslog ((FACILITY | LOG_ERR), "failed on RCPT command.");
  938.       unlink (MBOX_LOCKF);
  939.       syserr ("sms2mailgw: failed on RCPT command");
  940.     }
  941.     while ((cursor = cursor->next) != NULL) {
  942.       sprintf (cmdline, "RCPT TO: %sn", cursor->rcpt);
  943.       tellsock (sockfd, cmdline);
  944.       if (!slurp_n_catch (sockfd, 1, "250")) {
  945. syslog ((FACILITY | LOG_ERR), "failed on RCPT command.");
  946. unlink (MBOX_LOCKF);
  947. syserr ("sms2mailgw: failed on RCPT command");
  948.       }
  949.     }                                      /* while (...) */
  950.   }                             /* if (not empty to-list) */
  951.   
  952.   /* CC: field */
  953.   if (!empty_rcpt_list (m->cc)) {
  954.     cursor = m->cc.head;
  955.     sprintf (cmdline, "RCPT TO: %sn", cursor->rcpt);
  956.     tellsock (sockfd, cmdline);
  957.     if (!slurp_n_catch (sockfd, 1, "250")) {
  958.       syslog ((FACILITY | LOG_ERR), "failed on RCPT command.");
  959.       unlink (MBOX_LOCKF);
  960.       syserr ("sms2mailgw: failed on RCPT command");
  961.     }
  962.     while ((cursor = cursor->next) != NULL) {
  963.       sprintf (cmdline, "RCPT TO: %sn", cursor->rcpt);
  964.       tellsock (sockfd, cmdline);
  965.       if (!slurp_n_catch (sockfd, 1, "250")) {
  966. syslog ((FACILITY | LOG_ERR), "failed on RCPT command.");
  967. unlink (MBOX_LOCKF);
  968. syserr ("sms2mailgw: failed on RCPT command");
  969.       }
  970.     }                                      /* while (...) */
  971.   }                             /* if (not empty cc-list) */
  972.   /* BCC: field */
  973.   if (!empty_rcpt_list (m->bcc)) {
  974.     cursor = m->bcc.head;
  975.     sprintf (cmdline, "RCPT TO: %sn", cursor->rcpt);
  976.     tellsock (sockfd, cmdline);
  977.     if (!slurp_n_catch (sockfd, 1, "250")) {
  978.       syslog ((FACILITY | LOG_ERR), "failed on RCPT command.");
  979.       unlink (MBOX_LOCKF);
  980.       syserr ("sms2mailgw: failed on RCPT command");
  981.     }
  982.     while ((cursor = cursor->next) != NULL) {
  983.       sprintf (cmdline, "RCPT TO: %sn", cursor->rcpt);
  984.       tellsock (sockfd, cmdline);
  985.       if (!slurp_n_catch (sockfd, 1, "250")) {
  986. syslog ((FACILITY | LOG_ERR), "failed on RCPT command.");
  987. unlink (MBOX_LOCKF);
  988. syserr ("sms2mailgw: failed on RCPT command");
  989.       }
  990.     }                                      /* while (...) */
  991.   }                            /* if (not empty bcc-list) */
  992.   /*. . . . . . . . . . . . . . . . . . . . . . . . . . . */
  993.   /* now send mail data */
  994.   sprintf (cmdline, "DATAn");
  995.   tellsock (sockfd, cmdline);
  996.   if (!slurp_n_catch (sockfd, 1, "354")) {
  997.     syslog ((FACILITY | LOG_ERR), "failed on DATA command.");
  998.     unlink (MBOX_LOCKF);
  999.     syserr ("sms2mailgw: failed on DATA command");
  1000.   }
  1001.   
  1002.   /* From: field as "comment" */
  1003.   if (m->from) {
  1004.     sprintf (cmdline, "From: %sn", m->from);
  1005.     tellsock (sockfd, cmdline);
  1006.   }
  1007.   /* To: field as "comment" */
  1008.   if (!empty_rcpt_list (m->to)) {
  1009.     cursor = m->to.head;
  1010.     sprintf (cmdline, "To: %s", cursor->rcpt);
  1011.     while ((cursor = cursor->next) != NULL) {
  1012.       strcat (cmdline, ", ");
  1013.       strcat (cmdline, cursor->rcpt);
  1014.     }                                      /* while (...) */
  1015.     strcat (cmdline, "n");
  1016.     tellsock (sockfd, cmdline);
  1017.   }                             /* if (not empty to-list) */
  1018.   /* CC: field as "comment" */
  1019.   if (!empty_rcpt_list (m->cc)) {
  1020.     cursor = m->cc.head;
  1021.     sprintf (cmdline, "Cc: %s", cursor->rcpt);
  1022.     while ((cursor = cursor->next) != NULL) {
  1023.       strcat (cmdline, ", ");
  1024.       strcat (cmdline, cursor->rcpt);
  1025.     }                                      /* while (...) */
  1026.     strcat (cmdline, "n");
  1027.     tellsock (sockfd, cmdline);
  1028.   }                             /* if (not empty to-list) */
  1029.   /* BCC: field as "comment" */
  1030.   if (!empty_rcpt_list (m->bcc)) {
  1031.     cursor = m->bcc.head;
  1032.     sprintf (cmdline, "Bcc: %s", cursor->rcpt);
  1033.     while ((cursor = cursor->next) != NULL) {
  1034.       strcat (cmdline, ", ");
  1035.       strcat (cmdline, cursor->rcpt);
  1036.     }                                      /* while (...) */
  1037.     strcat (cmdline, "n");
  1038.     tellsock (sockfd, cmdline);
  1039.   }                             /* if (not empty to-list) */
  1040.   /* Reply-to: field */
  1041.   if (m->reply_to) {
  1042.     sprintf (cmdline, "Reply-to: %sn", m->reply_to);
  1043.     tellsock (sockfd, cmdline);
  1044.   }
  1045.   /* Subject: field */
  1046.   if (m->subject) {
  1047.     sprintf (cmdline, "Subject: %sn", m->subject);
  1048.     tellsock (sockfd, cmdline);
  1049.   }
  1050.   /* Message Body */
  1051.   if (m->body) {
  1052.     sprintf (cmdline, "%sn", m->body);
  1053.     tellsock (sockfd, cmdline);
  1054.   }
  1055.   
  1056.   /* add some system info */
  1057.   sprintf (cmdline, "n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-n");
  1058.   tellsock (sockfd, cmdline);
  1059.   sprintf (cmdline, "This mail has been relayed to you by SMSLink's sms2mailgwn");
  1060.   tellsock (sockfd, cmdline);
  1061.   sprintf (cmdline, "ver. %s (%s) running on %s.%s.n", SMS_GW_VERSION,
  1062.            SMS_GW_DATE, localhost, defdom);
  1063.   tellsock (sockfd, cmdline);
  1064.   nd = nicedate (ibl->date);
  1065.   sprintf (cmdline, "The original message was received on %s at %sn",
  1066.            nd, ibl->time);
  1067.   tellsock (sockfd, cmdline);
  1068.   sprintf (cmdline, "from the GSM number [%s] through device [%s].n", ibl->fromgsm,
  1069.            ibl->device);
  1070.   tellsock (sockfd, cmdline);
  1071.   sprintf (cmdline, "The message ID was [%d].n", ibl->msgid);
  1072.   tellsock (sockfd, cmdline);
  1073.   
  1074.   /* now close the DATA section: one dot only */
  1075.   sprintf (cmdline, ".n");
  1076.   tellsock (sockfd, cmdline);
  1077.   if (!slurp_n_catch (sockfd, 1, "250")) {
  1078.     syslog ((FACILITY | LOG_ERR), "failed on DATA transfer.");
  1079.     unlink (MBOX_LOCKF);
  1080.     syserr ("sms2mailgw: failed on DATA transfer");
  1081.   }
  1082.   
  1083.   /* send the QUIT command */
  1084.   sprintf (cmdline, "QUITn");
  1085.   tellsock (sockfd, cmdline);
  1086.   if (!slurp_n_catch (sockfd, 1, "221")) {
  1087.     syslog ((FACILITY | LOG_ERR), "failed on QUIT command.");
  1088.     unlink (MBOX_LOCKF);
  1089.     syserr ("sms2mailgw: failed on QUIT command");
  1090.   }
  1091.   
  1092.   /*------------------------------------------Conclusions */
  1093.   /* close socket */
  1094.   if (close (sockfd) == -1) {
  1095.     syslog ((FACILITY | LOG_ERR), "can't close socket.");
  1096.     unlink (MBOX_LOCKF);
  1097.     syserr ("sms2mailgw: can't close socket");
  1098.   }
  1099.   
  1100.   /* free what's need to be */
  1101.   free (nd);
  1102.   
  1103.   /* leave */
  1104.   return (0);
  1105. }                                         /* send_mail () */
  1106. /*========================================================*/
  1107. int mailbox_run (char *localhost, char *defaultdomain)
  1108. {
  1109.   struct email_msg email;
  1110.   struct inbox_line tkline;            /* tokenized line */
  1111.   char *line;                                /* raw line */
  1112.   char *buffline;                       /* transfer line */
  1113.   FILE *inbox;
  1114.   FILE *newbox;
  1115.   int anymailfound = FALSE;
  1116.   int filecreatedyet = FALSE;
  1117.   int msg_count = 0;
  1118.   int lineismail;
  1119.   int lcursor;
  1120.   int nline = 0;
  1121.   char *cmd;
  1122.   char *newboxname;
  1123.   
  1124.   /*---------------------------------Initialize variables */
  1125.   line = (char *) malloc ((BIGBUFF + 1) * sizeof (char));
  1126.   if (! line) {
  1127.     syslog ((FACILITY | LOG_ERR), "can't malloc().");
  1128.     unlink (MBOX_LOCKF);
  1129.     syserr ("sms2mailgw: can't malloc()");
  1130.   }
  1131.   line[0] = '';
  1132.   buffline = (char *) malloc ((BIGBUFF + 1) * sizeof (char));
  1133.   if (! buffline) {
  1134.     syslog ((FACILITY | LOG_ERR), "can't malloc().");
  1135.     unlink (MBOX_LOCKF);
  1136.     syserr ("sms2mailgw: can't malloc()");
  1137.   }
  1138.   buffline[0] = '';
  1139.   cmd = (char *) malloc ((BUFFSIZE + 1) * sizeof (char));
  1140.   if (! cmd) {
  1141.     syslog ((FACILITY | LOG_ERR), "can't malloc().");
  1142.     unlink (MBOX_LOCKF);
  1143.     syserr ("sms2mailgw: can't malloc()");
  1144.   }
  1145.   cmd[0] = '';
  1146.   newboxname = (char *) malloc ((PATH_MAX + 1) * sizeof (char));
  1147.   if (! newboxname) {
  1148.     syslog ((FACILITY | LOG_ERR), "can't malloc().");
  1149.     unlink (MBOX_LOCKF);
  1150.     syserr ("sms2mailgw: can't malloc()");
  1151.   }
  1152.   newboxname[0] = '';
  1153.   sprintf (newboxname, "%s.tmp.%d", MBOX_FILE, getpid());
  1154.   /*--------------------------------------------Open file */
  1155.   if ((inbox = fopen (MBOX_FILE, "r")) == NULL) {
  1156.     syslog ((FACILITY | LOG_ERR), "can't fopen() inbox file.");
  1157.     unlink (MBOX_LOCKF);
  1158.     syserr ("sms2mailgw: can't fopen() inbox file");
  1159.   }
  1160.   /*----------------------Read file and process each line */
  1161.   while (fgets (line, BIGBUFF, inbox) != NULL) {
  1162.     nline++;
  1163.     /* tokenize line to fill a struct inbox_line */
  1164.     if (tkize_ibox_line (line, &tkline) == -1) {
  1165.       syslog ((FACILITY | LOG_ERR), "inbox corruption - can't parse line %d.", nline);
  1166.       unlink (MBOX_LOCKF);
  1167.       syserr ("sms2mailgw: inbox corruption - can't parse line");
  1168.     }
  1169.     
  1170.     /* is it a mail message ? */
  1171.     if ((toupper (tkline.text[0]) == 'T') && (tkline.text[1] == ':')) {
  1172.       if (parse_smail (&tkline, &email, localhost, defaultdomain) == -1) {
  1173.         /* reject line after all */
  1174. lineismail = FALSE;
  1175. /* log it */
  1176.         syslog ((FACILITY | LOG_NOTICE), "inbox line #%d don't comply with protocol.",
  1177.        nline);
  1178.       }
  1179.       else {
  1180.         lineismail = TRUE;
  1181.         anymailfound = TRUE;
  1182. if (!email.from) {
  1183.   email.from = mkfromfield (tkline.fromgsm, localhost, defaultdomain);
  1184. }
  1185.         send_mail (&email, &tkline, MAILHOST, localhost, defaultdomain);
  1186. reset_mail_struct (&email);
  1187.         msg_count++;
  1188.       }
  1189.     }
  1190.     else {
  1191.       lineismail = FALSE;
  1192.     }                              /* if (it is an email) */
  1193.     if (anymailfound) {
  1194.       if (!filecreatedyet) {
  1195.         /* open new inbox file */
  1196. if ((newbox = fopen (newboxname, "w")) == NULL) {
  1197.   syslog ((FACILITY | LOG_ERR), "can't fopen() temp inbox file.");
  1198.           unlink (MBOX_LOCKF);
  1199.   syserr ("sms2mailgw: can't fopen() temp inbox file");
  1200. }
  1201.         filecreatedyet = TRUE;
  1202. /* transfer up to current line - current not included */
  1203.         lcursor = 1;
  1204.         /* "rewind" input file */
  1205.         if (fseek (inbox, (long) 0, SEEK_SET) == -1) {
  1206.   syslog ((FACILITY | LOG_ERR), "can't fseek() on inbox file.");
  1207.           unlink (MBOX_LOCKF);
  1208.   syserr ("sms2mailgw: can't fseek() on inbox file");
  1209.         }
  1210.         while (lcursor < nline) {
  1211.           if (fgets (buffline, BIGBUFF, inbox) == NULL) {
  1212.     syslog ((FACILITY | LOG_ERR), "can't read from inbox file.");
  1213.             unlink (MBOX_LOCKF);
  1214.     syserr ("sms2mailgw: can't read from inbox file");
  1215.           }
  1216.           if (fputs (buffline, newbox) == EOF) {
  1217.     syslog ((FACILITY | LOG_ERR), "can't write to new inbox file.");
  1218.             unlink (MBOX_LOCKF);
  1219.     syserr ("sms2mailgw: can't write to new inbox file");
  1220.           }
  1221.           lcursor++;
  1222.         }                      /* while (lcursor < nline) */
  1223.         /* re-read line #nline to skip it */
  1224.         if (fgets (buffline, BIGBUFF, inbox) == NULL) {
  1225.   syslog ((FACILITY | LOG_ERR), "can't read from inbox file.");
  1226.           unlink (MBOX_LOCKF);
  1227.   syserr ("sms2mailgw: can't read from inbox file");
  1228.         }
  1229.       }                            /* if (msg_count == 1) */
  1230.       if (! lineismail) {
  1231.         /* transfer current line to new file */
  1232.         if (fputs (line, newbox) == EOF) {
  1233.   syslog ((FACILITY | LOG_ERR), "can't write to new inbox file.");
  1234.           unlink (MBOX_LOCKF);
  1235.   syserr ("sms2mailgw: can't write to new inbox file");
  1236.         }
  1237.       }                              /* if (! lineismail) */
  1238.     }                                /* if (anymailfound) */
  1239.   }                                    /* while (fgets... */
  1240.   /*------------------------------Close file and conclude */
  1241.   fclose (inbox);
  1242.   if (anymailfound) {
  1243.     fclose (newbox);
  1244.     /* now mv newbox inbox */
  1245.     sprintf (cmd, "mv %s %s", newboxname, MBOX_FILE);
  1246.     if (system (cmd) != 0) {
  1247.       syslog ((FACILITY | LOG_ERR), "can't move new inbox file - system() failed.");
  1248.       unlink (MBOX_LOCKF);
  1249.       syserr ("sms2mailgw: can't move new inbox file - system() failed");
  1250.     }
  1251.   }
  1252.   
  1253.   /* free what's needs to be */
  1254.   free (line);
  1255.   free (buffline);
  1256.   free (cmd);
  1257.   free (newboxname);
  1258.   
  1259.   return (msg_count);
  1260. }                                       /* mailbox_run () */
  1261. /*==========================================================
  1262.  * EOF : gw_stuff.c
  1263.  *===================*/