📄 mbchecker.c
字号:
/*========================================================== * Program : mbchecker.c Project : smslink * Author : Philippe Andersson. * Date : 25/02/00 * Version : 0.10b * Notice : (c) Les Ateliers du Heron, 1998 for Scitex Europe, S.A. * Comment : Mailbox checking functions for the smslink server. * * Modification History : * - 0.01a (05/12/98) : Initial release. * - 0.02a (16/05/99) : Added include line for errno.h, to solve * compilation problem on RedHat platform. * - 0.03a (06/06/99) : Started building the actual mailbox * check procedure. * - 0.04b (28/06/99) : In mbcheck(), moved the AT+CNMI command * after the PIN check routine. PIN-Activated SIM is required * for AT+CNMI. Solved a bug with default SMSC. * - 0.05a (03/07/99) : Added list managment functions. * - 0.06a (11/07/99) : Added dumptofile() function. * ++++ Switch to Beta ++++ * - 0.07b (20/07/99) : Improved mbcheck() to also remove the * messages from the SIM after having saved them to disk. * - 0.08b (17/08/99) : Included code to create and update the * checkpoint file after each successfull mailbox check (needed * for interaction with the SMS to Mail gateway). * - 0.09b (02/12/99) : Improved handling for default SMSC in * mbcheck(). Now uses the value kept in /etc/gsmdevices. * - 0.10b (25/02/00) : In mbcheck_wrapper(), moved the update * of the checkpoint file outside of the device-checking loop * (first because there's no need to update it more than once, * second because it caused sms2mailgw to fire during the * device checking loop). *========================================================*/#include <stdio.h> /* for fprintf */#include <stdlib.h> /* for errno & stuff */#include <ctype.h> /* for isdigit() */#include <errno.h>#include <string.h>#include <unistd.h>#include <fcntl.h>#include <syslog.h>#include <signal.h>#include <sys/time.h> /* for the struct timeval */#include <sys/types.h>#include <sys/ipc.h>#include <sys/sem.h> /* semaphores */#include <sys/shm.h> /* shared memory */#include <sys/ioctl.h> /* for the ioctl() call */#include <termios.h> /* for baudrates definitions */#include <dial/modems.h> /* requires 'libmodem' */#include "sms_serv.h"/*========================================================*//* For debugging purposes only - comment out for normal compile *//* #define INCL_DEBUG_CODE *//*-------------------------------------External variables *//* program specific *//*---------------------------------------Global variables */int MBC_instance;int MBC_instance_is_set = FALSE;/*========================================================*//********** FUNCTIONS ********//*========================================================*/void mbox_list_init (mbox_list *list){ list->head = NULL; list->tail = NULL;} /* mbox_list_init () *//*========================================================*/int empty_mbox_list (mbox_list list){ return (list.head == NULL);} /* empty_mbox_list () *//*========================================================*/void mbox_list_insert (mbox_list *list, struct mbox_item *element){ /* WARNING : the order of the elements IS relevent - has to * be chronological => insert at tail. */ /* chain the element in the list */ if (empty_mbox_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; }} /* mbox_list_insert () *//*========================================================*/void free_mbox_list (mbox_list *list){ struct mbox_item *cursor; if (!empty_mbox_list (*list)) { /* hop to element before last */ cursor = list->tail->prev; /* now go back and clean behind */ while (cursor != NULL) { free (cursor->next); cursor->next = NULL; list->tail = cursor; cursor = cursor->prev; } /* while (cursor != NULL) */ } /* if (!empty_mbox_list (... */ /* now clean last element and reset header */ free (list->head); list->head = NULL; list->tail = NULL;} /* free_mbox_list () *//*========================================================*/void MBC_unlock_gsm (){ extern int shmem_sem; extern struct gsms_def *gsmdevices; syslog ((FACILITY | LOG_WARNING), "MBC being hit by SIGTERM."); /* set the allocated GSM module back to 'free' status */ if (MBC_instance_is_set) { if (sem_wait (shmem_sem) == -1) syserr ("sms_serv: failed to wait on shared mem. semaphore"); /* ---- Begin Crit. Sect. #5 ---- */ if (!gsmdevices[MBC_instance].free) { gsmdevices[MBC_instance].free = TRUE; gsmdevices[MBC_instance].owner = 0; syslog ((FACILITY | LOG_WARNING), "GSM instance </dev/%s> has been unlocked.", gsmdevices[MBC_instance].device); } /* leave crit. sect. */ if (sem_signal (shmem_sem) == -1) syserr ("sms_serv: can't signal shared mem. semaphore"); /* ---- End Crit. Sect. #5 ---- */ } /* free what's need to be freed and exit */ /*------------------------------------------------------*/ exit (0);} /* MBC_unlock_gsm () *//*========================================================*/int all_done (int *array, int size){ int retval = TRUE; int i; for (i = 0; i < size; i++) { retval = (retval && array[i]); } return (retval);} /* all_done () *//*========================================================*/struct mbox_item *mbparse (char *msg_string){ struct mbox_item *msg; char *s; char *token; char date[9]; char time[10]; char brol[5]; int year, month, day; /*----------------Take a local copy of the input string */ if ((s = (char *) malloc ((strlen (msg_string) + 1) * sizeof (char))) == NULL) return (NULL); strcpy (s, msg_string); /*-----------------------Allocate memory for the struct */ if ((msg = (struct mbox_item *) malloc (sizeof (struct mbox_item))) == NULL) return (NULL); /*----------------------------------------Initialize it */ msg->msgid = 0; msg->fromgsm[0] = '\0'; msg->date[0] = '\0'; msg->time[0] = '\0'; msg->text[0] = '\0'; msg->next = NULL; msg->prev = NULL; /*----------------------------Parse message string copy */ /*...........................................Message ID */ if ((token = strtok (s, ",")) != NULL) { /* Message ID - extract the ID token alone and atoi it */ while (!isdigit (token[0]) && token[0]) token++; msg->msgid = atoi (token);#ifdef INCL_DEBUG_CODE fprintf (stderr, "token #1, msg ID = [%d]\n", msg->msgid);#endif } else { /* Internal structure error */ return (NULL); } /*.......................................Message Status */ if ((token = strtok (NULL, ",")) != NULL) { /* Message status - drop it */#ifdef INCL_DEBUG_CODE fprintf (stderr, "token #2, msg status = [%s] (ignored)\n", token);#endif } else { /* Internal structure error */ return (NULL); } /*....................................Sender GSM number */ if ((token = strtok (NULL, ",")) != NULL) { /* Sender GSM number - dequote it */ dequote (token); strcpy (msg->fromgsm, token);#ifdef INCL_DEBUG_CODE fprintf (stderr, "token #3, sender GSM = [%s]\n", msg->fromgsm);#endif } else { /* Internal structure error */ return (NULL); } /*........................................Date and Time */ if ((token = strtok (NULL, "\r")) != NULL) { /* Date and Time - dequote and split */ dequote (token); strncpy (date, token, 8); date[8] = '\0'; token += 9; strncpy (time, token, 9); time[9] = '\0'; /* Convert date format from DD/MM/YY to YYYYMMDD */ strncpy (brol, date, 2); /* day */ day = atoi (brol); shiftleft (date, 3); strncpy (brol, date, 2); /* month */ month = atoi (brol); shiftleft (date, 3); strncpy (brol, date, 2); /* year */ year = atoi (brol); /* take care of the missing century */ if (year < 95) year += 2000; else year += 1900; sprintf (msg->date, "%d%02d%02d", year, month, day); /* Copy the time over */ strcpy (msg->time, time);#ifdef INCL_DEBUG_CODE fprintf (stderr, "token #4, message date = [%s]\n", msg->date); fprintf (stderr, "token #5, message time = [%s]\n", msg->time);#endif } else { /* Internal structure error */ return (NULL); } /*.........................................Message text */ if ((token = strtok (NULL, "\r")) != NULL) { /* Message text - trim unwanted characters */ trim (token); strcpy (msg->text, token);#ifdef INCL_DEBUG_CODE fprintf (stderr, "token #6, message text = [%s]\n", msg->text);#endif } else { /* Internal structure error */ return (NULL); } /*-------------------------------------------------Exit */ free (s); return (msg);} /* mbparse () *//*========================================================*/int dumptofile (mbox_list *list, char *device){ int nline = 0; FILE *mbox_file; int lockf_desc; struct mbox_item *cursor; int save_errno; lockf_desc = open (MBOX_LOCKF, (O_RDWR | O_CREAT | O_EXCL), 0444); if (lockf_desc == -1) { syslog ((FACILITY | LOG_ERR), "can't lock the inbox file."); mdmperror ("sms_serv: can't lock the inbox file"); } else { /* file is now locked */ if ((mbox_file = fopen (MBOX_FILE, "a")) != NULL) { cursor = list->head; while (cursor != NULL) { fprintf (mbox_file, "/dev/%s,%d,%s,%s,%s,\"%s\"\n", device, cursor->msgid, cursor->fromgsm, cursor->date, cursor->time, cursor->text); nline++; cursor = cursor->next; } /* while (cursor != NULL) */ fclose (mbox_file); } else { syslog ((FACILITY | LOG_ERR), "can't open the inbox file."); mdmperror ("sms_serv: can't open the inbox file"); } /* Now remove lock file */ close (lockf_desc); if (unlink (MBOX_LOCKF) == -1) { syslog ((FACILITY | LOG_ERR), "can't remove the lock file."); mdmperror ("sms_serv: can't remove the lock file"); } } /* if (lockf_desc == -1) */ return (nline);} /* dumptofile () *//*========================================================*/int mbcheck (struct gsms_def *gsm){ int fd, retval = 0; int nmsgin = 0; char *scratch; char *p1; char *p2; char *cmsgid; int nread; int newpin; int retries; int msgid; struct mbox_item *message; mbox_list mailbox; /*--------------------------------------Initializations */ scratch = (char *) malloc ((BIGBUFF + 1) * sizeof (char)); if (!scratch) syserr ("sms_serv: can't allocate scratch space"); memset (scratch, 0, (BIGBUFF + 1)); mbox_list_init (&mailbox); /* open modem line */ fd = blopen_mdm_line (gsm->device, B9600); if (fd < 0) { syslog ((FACILITY | LOG_ERR), "call to blopen_mdm_line() failed."); mdmperror ("sms_serv: blopen_mdm_line() failed"); free (scratch); return (-1); } /*------------set GSM to "verbose" error reporting mode */ sprintf (scratch, "at+cmee=1\r"); tell_gsm (fd, scratch); memset (scratch, 0, (BIGBUFF + 1)); if (get_gsm_answer (fd, scratch, BIGBUFF, 1)) {#ifdef INCL_DEBUG_CODE fprintf (stderr, "%s\n", scratch);#endif /* check for "OK" */ if (strstr (scratch, "OK") == NULL) { mdm_unlock (mdmopendevice); hangup (fd); free (scratch); syslog ((FACILITY | LOG_ERR), "error after sending AT+CMEE command."); mdmperror ("sms_serv: error after sending AT+CMEE command"); return (-1); } } else { mdm_unlock (mdmopendevice); hangup (fd); free (scratch); syslog ((FACILITY | LOG_ERR), "GSM module not responding."); mdmperror ("sms_serv: GSM not responding"); return (-1); } /*---------------------------then, check for SIM status */ sprintf (scratch, "at+cpin?\r"); tell_gsm (fd, scratch); memset (scratch, 0, (BIGBUFF + 1)); if (get_gsm_answer (fd, scratch, BIGBUFF, 1)) {#ifdef INCL_DEBUG_CODE fprintf (stderr, "%s\n", scratch);#endif /* check for "READY" -- if not, make it so */ retries = MAXATTEMPTS; while ((strstr (scratch, "READY") == NULL) && retries--) { /* not ready yet -> asking for PIN or PUK ? */ if (strstr (scratch, "SIM PIN")) { /* send PIN */ sprintf (scratch, "at+cpin=%s\r", gsm->PIN); tell_gsm (fd, scratch); memset (scratch, 0, (BIGBUFF + 1)); if (get_gsm_answer (fd, scratch, BIGBUFF, 15)) {#ifdef INCL_DEBUG_CODE fprintf (stderr, "%s\n", scratch);#endif /* check for "OK" */ if (strstr (scratch, "OK") == NULL) { mdm_unlock (mdmopendevice); hangup (fd); free (scratch); syslog ((FACILITY | LOG_ERR), "can't send PIN to GSM or wrong PIN."); mdmperror ("sms_serv: can't send PIN to GSM or wrong PIN"); return (-1); } } else { mdm_unlock (mdmopendevice); hangup (fd); free (scratch); syslog ((FACILITY | LOG_ERR), "GSM module not responding."); mdmperror ("sms_serv: GSM not responding"); return (-1); } } else if (strstr (scratch, "SIM PUK")) { /* send PUK - set new random PIN */ srand (getpid ()); newpin = rand (); syslog ((FACILITY | LOG_WARNING), "I'll try to set new PIN for </dev/%s>.", gsm->device); sprintf (scratch, "at+cpin=\"%s\",\"%04d\"\r", gsm->PUK, newpin); tell_gsm (fd, scratch); memset (scratch, 0, (BIGBUFF + 1));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -