📄 gw_stuff.c
字号:
/*========================================================== * Program : gw_stuff.c Project : smslink * Author : Philippe Andersson. * Date : 01/03/00 * Version : 0.16b * Notice : (c) Les Ateliers du Heron, 1998 for Scitex Europe, S.A. * Comment : Library of functions for the smslink sms2mail gateway. * * Modification History : * - 0.01b (19/08/99) : Initial release. Moved the mail gateway- * specific functions from stuff.c over here. * - 0.02b (28/09/99) : Created mailbox_run(). * - 0.03b (29/09/99) : Extensive rework. Added tkize_ibox_line(), * reset_mail_struct() and parse_smail(). * - 0.04b (04/10/99) : Added expand_addr(). * - 0.05b (17/10/99) : Expanded parse_smail() extensively. * - 0.06b (19/10/99) : Debugged tkize_ibox_line(). Increased * debugging output. Created shell for send_mail(). * - 0.07b (20/10/99) : Added mkfromfield(). * - 0.08b (21/10/99) : Added is_dotted_quad () and resolve(). * - 0.09b (08/11/99) : Built dialog in send_mail(). Added * slurp_n_catch(). * - 0.10b (09/11/99) : Modified parse_smail() to provide a * default subject field if the SMS doesn't contain one. Involved * alter the parameters passed to the function. Cosmetics. * - 0.11b (12/11/99) : Improved send_mail() to free() the * allocated space for the nicified date. * - 0.12b (30/11/99) : Added temp file creation to mailbox_run(). * - 0.13b (24/02/00) : Completed the transfer routine to the * new mailbox file in mailbox_run(). * - 0.14b (26/02/00) : Made sure the lockfile (MBOX_LOCKF) was * deleted on each fatal error, as well as on SIGTERM being * caught (in mailgws_death()). Improved error reporting in * various functions. Cosmetics. * - 0.15b (29/02/00) : Added functions to handle recepients * lists (as part of struct email_msg). Heavily modified most * functions (send_mail(), parse_smail(), expand_addr()) and * created sub_tkize_field() to account for changes in the * email_msg struct. * - 0.16b (01/03/00) : Replaced the "old" slurp_n_catch() by * a new version inspired by get_gsm_answer() (cf. serv_stuff.c). * This should be more robust and less sensitive to the amount * of data sent back by the server (here: sendmail). Created * the clean_field() function (forgotten when split expand_addr() * from sub_tkize_field()). *========================================================*/#include <unistd.h>#include <stdio.h> /* for fprintf */#include <stdlib.h> /* for errno & stuff */#include <errno.h>#include <string.h>#include <syslog.h>#include <netdb.h> /* for gethostbyname() */#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <sys/time.h> /* for the struct timeval */#include <sys/types.h>#include <sys/ipc.h>#include <sys/ioctl.h> /* for the ioctl() call */#ifdef LINUX_LC6# include <limits.h> /* for PATH_MAX */# include <linux/limits.h>#else# include <limits.h>#endif#include "sms_serv.h"/*========================================================*//* For debugging purposes only - comment out for normal compile *//* #define INCL_DEBUG_CODE *//*========================================================*/void mailgws_death (){ extern int inbox_is_locked; /* log it... */ syslog ((FACILITY | LOG_INFO), "gateway exiting on SIGTERM."); /* remove inbox lock file if necessary */ if (inbox_is_locked) { unlink (MBOX_LOCKF); } /* closes connection to the syslog daemon */ closelog (); /* now exits gracefully */ exit (0);} /* mailgws_death () *//*========================================================*/void rcpt_list_init (rcpt_list *list){ list->head = NULL; list->tail = NULL;} /* rcpt_list_init () *//*========================================================*/int empty_rcpt_list (rcpt_list list){ return (list.head == NULL);} /* empty_rcpt_list () *//*========================================================*/void rcpt_list_insert (rcpt_list *list, char *recepient){ /* WARNING : the order of the elements might be relevent - let's * store them as they were in the header => avoid inserting at * list head. Do it at the tail. */ int l; struct rcpt_item *element; /* alloc memory for new element */ element = (struct rcpt_item *) malloc (sizeof (struct rcpt_item)); if (!element) { syslog ((FACILITY | LOG_ERR), "can't malloc() for new RCPT entry."); unlink (MBOX_LOCKF); syserr ("sms2mailgw: can't malloc() for new RCPT entry"); } /* initialize fields for new element */ l = strlen (recepient); element->rcpt = (char *) malloc ((l + 1) * sizeof (char)); if (!element->rcpt) { syslog ((FACILITY | LOG_ERR), "can't malloc() for new recepient string."); unlink (MBOX_LOCKF); syserr ("sms2mailgw: can't malloc() for new recepient string"); } strcpy (element->rcpt, recepient); /* chain it in the list */ if (empty_rcpt_list (*list)) { list->head = element; list->tail = element; element->next = NULL; element->prev = NULL; } else { element->next = NULL; element->prev = list->tail; list->tail->next = element; list->tail = element; }} /* rcpt_list_insert () *//*========================================================*/void free_rcpt_list (rcpt_list *list){ struct rcpt_item *cursor; if (!empty_rcpt_list (*list)) { /* hop to element before last */ cursor = list->tail->prev; /* now go back and clean behind */ while (cursor != NULL) { free (cursor->next->rcpt); free (cursor->next); cursor->next = NULL; list->tail = cursor; cursor = cursor->prev; } /* while (cursor != NULL) */ } /* if (!empty_rcpt_list (... */ /* now clean last element and reset header */ free (list->head->rcpt); free (list->head); list->head = NULL; list->tail = NULL;} /* free_rcpt_list () *//*========================================================*/#ifdef INCL_DEBUG_CODEvoid print_rcpt_list (rcpt_list list){ struct rcpt_item *cursor; if (!empty_rcpt_list (list)) { cursor = list.head; fprintf (stderr, "<%s>\n", cursor->rcpt); while (cursor->next != NULL) { cursor = cursor->next; fprintf (stderr, "<%s>\n", cursor->rcpt); } } else { fprintf (stderr, "sms2mailgw: empty recepient list.\n"); }} /* print_acl_list () */#endif/*========================================================*/int is_dotted_quad (char *string){ int is_dq; char *s; int ntok = 0; char *ptok = NULL; long int ip_byte; char **endptr; char *dummyp; /*--------------------------------------Initializations */ s = (char *) malloc ((strlen (string) + 1) * sizeof (char)); if (! s) { syslog ((FACILITY | LOG_ERR), "can't malloc()."); unlink (MBOX_LOCKF); syserr ("sms2mailgw: can't malloc()"); } strcpy (s, string); /*--------------------------------------------Main Loop */ /* no point going any further if the 1st char. is not a digit */ is_dq = isdigit (string[0]); if (is_dq) { ptok = strtok (s, "."); while (ptok != NULL) { ntok++;#ifdef INCL_DEBUG_CODE fprintf (stderr, "got token #%d : <%s>\n", ntok, ptok);#endif dummyp = ptok + strlen (ptok); endptr = &dummyp; ip_byte = strtol (ptok, endptr, 10); if (strlen (*endptr) != 0) {#ifdef INCL_DEBUG_CODE fprintf (stderr, "error on token #%d : can't convert <%s>\n", ntok, *endptr);#endif is_dq = FALSE; } ptok = strtok (NULL, "."); } if (ntok != 4) { is_dq = FALSE; } } /* if (is_dq) */ /*------------------------------------------Conclusions */ free (s); /*-------------------------------------------------Exit */ return (is_dq);} /* is_dotted_quad () *//*========================================================*/unsigned long int resolve (char *host)/* return the host ip address in network format */{ struct hostent *h_ent; struct in_addr target_ip; char **addrs; char *scratch; if (is_dotted_quad (host)) {#ifdef INCL_DEBUG_CODE fprintf (stderr, "I think I got an IP address\n");#endif if (inet_aton (host, &target_ip) == 0) syslog ((FACILITY | LOG_ERR), "invalid server IP address (%s).", host); scratch = (char *) malloc ((MINIBUFF + 1) * sizeof (char)); sprintf (scratch, "sms2mailgw: invalid server IP address (%s)", host); herror (scratch); free (scratch); unlink (MBOX_LOCKF); exit (1); } else {#ifdef INCL_DEBUG_CODE fprintf (stderr, "I think I got a host name\n");#endif if ((h_ent = gethostbyname (host)) == NULL) { syslog ((FACILITY | LOG_ERR), "can't resolve hostname (%s).", host); scratch = (char *) malloc ((MINIBUFF + 1) * sizeof (char)); sprintf (scratch, "sms2mailgw: can't resolve hostname (%s)", host); herror (scratch); free (scratch); unlink (MBOX_LOCKF); exit (1); } /* lines below cf. "Beginning Linux Progr.", pp. 468-473 */ addrs = h_ent->h_addr_list; target_ip = *(struct in_addr *)*addrs;#ifdef INCL_DEBUG_CODE fprintf (stderr, "server IP address is: [%s]\n", inet_ntoa (target_ip));#endif } /* if (isdigit (host[0])) */ return (target_ip.s_addr);} /* resolve () *//*========================================================*/int tkize_ibox_line (char *l, struct inbox_line *tkl){ char *token; char *scratch; /*--------------------------------------Initializations */ /* copy input string to scratch space - we can't modify it */ scratch = (char *) malloc ((strlen (l) + 1) * sizeof (char)); if (! scratch) { syslog ((FACILITY | LOG_ERR), "can't malloc()."); unlink (MBOX_LOCKF); syserr ("sms2mailgw: can't malloc()"); } scratch[0] = '\0'; strcpy (scratch, l); /*--------------------------------------Parsing routine */ /*...............................................Device */ if ((token = strtok (scratch, ",")) == NULL) { return (-1); } strcpy (tkl->device, token); /*................................................MsgID */ if ((token = strtok (NULL, ",")) == NULL) { return (-1); } tkl->msgid = atoi (token); /*..............................................FromGSM */ if ((token = strtok (NULL, ",")) == NULL) { return (-1); } strcpy (tkl->fromgsm, token); /*.................................................Date */ if ((token = strtok (NULL, ",")) == NULL) { return (-1); } strcpy (tkl->date, token); /*.................................................Time */ if ((token = strtok (NULL, ",")) == NULL) { return (-1); } strcpy (tkl->time, token); /*.................................................Text */ /* just grab the rest of the line */ if ((token = strtok (NULL, "\0")) == NULL) { return (-1); } /* remove trailing LF */ token[strlen (token) - 1] = '\0'; dequote (token); strcpy (tkl->text, token); /*-------------------------------------------------Exit */ free (scratch); return 0; /* success */} /* tkize_ibox_line () *//*========================================================*/char *expand_addr (char *field, char *defdom){ char *newstring; /*---------------------------------------Initialization */ newstring = (char *) malloc ((BIGBUFF + 1) * sizeof (char)); if (! newstring) { syslog ((FACILITY | LOG_ERR), "can't malloc()."); unlink (MBOX_LOCKF); syserr ("sms2mailgw: can't malloc()"); } newstring[0] = '\0'; /*---------------------------------Main processing loop */ if (strchr (field, '@') == NULL) { sprintf (newstring, "%s@%s", field, defdom); } else { strcpy (newstring, field); } /*------------------------------------------Conclusions */#ifdef INCL_DEBUG_CODE fprintf (stderr, "expanded field: [%s]\n", newstring);#endif return (newstring);} /* expand_addr () *//*========================================================*/char *clean_field (char *field)/* For fields that cannot be multi-part (Reply-to:), remove * the field header and any additional address. */{ char *ptr; /* The field for sure has a field header - skip it */ shiftleft (field, 2); /* If the first char now is a space, skip that as well */ if (field[0] == ' ') { shiftleft (field, 1); } /* If the field contains a comma, kill it and all that follows */ if ((ptr = strchr (field, ',')) != NULL) { ptr[0] = '\0'; } return (field);} /* clean_field () *//*========================================================*/int sub_tkize_field (rcpt_list *list, char *field, char *defdom){ int nfields = 0; char *s; char *ptr; char *newstring; char *item; /*---------------------------------------Initialization */ /* take a local copy of "field" to avoid it being modified */ s = (char *) malloc ((strlen (field) + 1) * sizeof (char)); if (! s) { syslog ((FACILITY | LOG_ERR), "can't malloc()."); unlink (MBOX_LOCKF); syserr ("sms2mailgw: can't malloc()"); } s[0] = '\0'; strcpy (s, field); ptr = s; /* s for sure has a field header ("T:" for inst.) - skip it */ ptr += 2; /* if there was a blank between the header and the field, skip it too */ if (ptr[0] == ' ') { ptr++; } /*---------------------------------Main processing loop */ if ((item = strtok (ptr, ",")) == NULL) { /* field header w/o contents */ free (s); return (nfields); } /* process first item */ newstring = expand_addr (item, defdom); rcpt_list_insert (list, newstring); nfields++; free (newstring); /* now tokenize and process the rest */ while ((item = strtok (NULL, ",")) != NULL) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -