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

手机短信编程

开发平台:

Unix_Linux

  1. /*==========================================================
  2.  * Program : serv_stuff.c                  Project : smslink
  3.  * Author  : Philippe Andersson.
  4.  * Date    : 24/01/00
  5.  * Version : 0.03b
  6.  * Notice  : (c) Les Ateliers du Heron, 1998 for Scitex Europe, S.A.
  7.  * Comment : Library of functions for the smslink server.
  8.  *
  9.  * Modification History :
  10.  * - 0.01b (19/08/99) : Initial release. Moved the SMS server-
  11.  *   specific functions from stuff.c over here.
  12.  * - 0.02b (21/10/99) : Moved tellsock() over to stuff.c (also
  13.  *   used by sms2mailgw for communication with sendmail).
  14.  * - 0.03b (24/01/00) : The definition for union semun disappeared
  15.  *   from the include files coming with the latest version of
  16.  *   glibc2. Fixed the code for daemons_death() and set_semvalue()
  17.  *   to account for this.
  18.  *========================================================*/
  19. #include <unistd.h>
  20. #include <stdio.h>                         /* for fprintf */
  21. #include <stdlib.h>                  /* for errno & stuff */
  22. #include <errno.h>
  23. #include <string.h>
  24. #include <syslog.h>
  25. #include <sys/time.h>           /* for the struct timeval */
  26. #include <sys/types.h>
  27. #include <sys/ipc.h>
  28. #include <sys/sem.h>                        /* semaphores */
  29. #include <sys/shm.h>                     /* shared memory */
  30. #include <sys/ioctl.h>            /* for the ioctl() call */
  31. #include <dial/modems.h>           /* requires 'libmodem' */
  32. #include "sms_serv.h"
  33. /*========================================================*/
  34. /* For debugging purposes only - comment out for normal compile */
  35. /* #define INCL_DEBUG_CODE */
  36. /*========================================================*/
  37. void daemons_death ()
  38. {
  39. #ifdef _SEM_SEMUN_UNDEFINED /* see <bits/sem.h> */
  40.   union semun {
  41.     int val; /* value for SETVAL */
  42.     struct semid_ds *buf; /* buffer for IPC_STAT & IPC_SET */
  43.     unsigned short int *array; /* array for GETALL & SETALL */
  44.     struct seminfo *__buf; /* buffer for IPC_INFO */
  45.   } sem_union;
  46. #else  
  47.   union semun sem_union;
  48. #endif                     /* #ifdef _SEM_SEMUN_UNDEFINED */
  49.   extern int shmem_sem, global_sem;
  50.   extern int shmem_id;
  51.   extern void *shared_memory;
  52.   extern acl_list gsm_acl;
  53.   extern int errno;
  54.   
  55.   /* free what's need to be freed */
  56.   free_acl_list (&gsm_acl);
  57.   
  58.   /* release shared memory */
  59.   if (shmdt (shared_memory) == -1)
  60.     syserr ("sms_serv: can't detach from shared memory segment");
  61.   if (shmctl (shmem_id, IPC_RMID, 0) == -1)
  62.     syserr ("sms_serv: can't remove shared memory segment");
  63.   
  64.   /* delete semaphores */
  65.   if (semctl (shmem_sem, 0, IPC_RMID, sem_union) == -1)
  66.     syserr ("sms_serv: can't delete shmem semaphore");
  67.   
  68.   if (semctl (global_sem, 0, IPC_RMID, sem_union) == -1)
  69.     syserr ("sms_serv: can't delete global semaphore");
  70.   
  71.   /* remove checkpoint file */
  72.   if (unlink (CHECKPOINTF) == -1) {
  73.     if (errno != ENOENT) {             /* no such file... */
  74.       syserr ("sms_serv: can't remove checkpoint file");
  75.     }
  76.   }
  77.   /* log it... */
  78.   syslog ((FACILITY | LOG_INFO), "server exiting on SIGTERM.");
  79.   /* closes connection to the syslog daemon */
  80.   closelog ();
  81.   
  82.   /* now exits gracefully */
  83.   exit (0);
  84. }                                     /* daemons_death () */
  85. /*========================================================*/
  86. /*========================================================*/
  87. /*################# struct gsms_def handling #############*/
  88. /*========================================================*/
  89. int gsmdevcpy (struct gsms_def *dest, struct gsms_def *src)
  90. {
  91.   if ((src != NULL) && (dest != NULL)) {
  92.     dest->free = src->free;
  93.     dest->owner = src->owner;
  94.     strcpy (dest->device, src->device);
  95.     strcpy (dest->PIN, src->PIN);
  96.     strcpy (dest->PUK, src->PUK);
  97.     strcpy (dest->addr, src->addr);
  98.     strcpy (dest->defsca, src->defsca);
  99.     strcpy (dest->provider, src->provider);
  100.     return (0);
  101.   }
  102.   else {
  103.     return (-1);
  104.   }
  105. }                                         /* gsmdevcpy () */
  106. /*========================================================*/
  107. /*################ Dialogue with GSM module ##############*/
  108. /*========================================================*/
  109. int tell_gsm (int fd, char *command)
  110. {
  111.   int len;
  112.   
  113.   len = strlen (command);
  114.   if (write (fd, command, len) != len) {
  115.     syslog ((FACILITY | LOG_ERR), "error writing to the GSM module.");
  116.     mdmperror ("error writing to the GSM module");
  117.     mdm_unlock (mdmopendevice);
  118.     hangup (fd);
  119.     free (command);
  120.     exit (-1);
  121.   }
  122. }                                          /* tell_gsm () */
  123. /*========================================================*/
  124. int get_gsm_answer (int fd, char *answer, int size, int resptime)
  125. {
  126.   int nread, retval, previous;
  127.   fd_set inputs;
  128.   struct timeval timeout;
  129.   char *buffer;
  130.   
  131.   /*--------------------------------------Initializations */
  132.   nread = previous = 0;
  133.   
  134.   FD_ZERO (&inputs);
  135.   FD_SET (fd, &inputs);
  136.   
  137.   timeout.tv_sec = 10;
  138.   timeout.tv_usec = 0;
  139.   
  140.   /* wait for data to arrive on the line */
  141.   retval = select (FD_SETSIZE, &inputs, NULL, NULL, &timeout);
  142.   switch (retval) {
  143.     case 0:
  144.       syslog ((FACILITY | LOG_WARNING), "timeout while waiting for GSM answer.");
  145.       break;
  146.     
  147.     case -1:
  148.       syserr ("sms_serv: call to select() failed");
  149.       break;
  150.       
  151.     default:
  152.       if (FD_ISSET (fd, &inputs)) {
  153.         /* first wait for all data to be ready */
  154. ioctl (fd, FIONREAD, &nread);
  155. while (nread != previous) {
  156.   sleep (resptime);
  157.   previous = nread;
  158.   ioctl (fd, FIONREAD, &nread);
  159. }                    /* while (nread != previous) */
  160. /* we know what's the data size - alloc space for it */
  161. buffer = (char *) malloc ((nread + 1) * sizeof (char));
  162. if (!buffer)
  163.   syserr ("sms_serv: can't allocate buffer space");
  164. /* now we can finally read this data */
  165. nread = read (fd, buffer, nread);
  166. switch (nread) {
  167.   case 0:
  168.     /* EOF */
  169.     syslog ((FACILITY | LOG_WARNING), "got no data from GSM module.");
  170.     break;
  171.     
  172.   case -1:
  173.     syserr ("sms_serv: error while reading answer from GSM");
  174.     break;
  175.     
  176.   default:
  177.     buffer[nread] = '';
  178. #ifdef INCL_DEBUG_CODE
  179.     fprintf (stderr, "pid<%d> Got : [%s] (%d char)n", getpid (), buffer, nread);
  180. #endif
  181.     /* here we could pre-process it (remove Ctrl-Z) */
  182.     /* copy it over to out string param. */
  183.     if (nread > size) {
  184.       syslog ((FACILITY | LOG_WARNING), "too much data, truncation will occur");
  185.       strncpy (answer, buffer, size);
  186.       answer[size] = '';
  187.     }
  188.     else {
  189.       strcpy (answer, buffer);
  190.     }
  191.     break;
  192. }                               /* switch (nread) */
  193.       }                                /* if (FD_ISSET... */
  194.       free (buffer);
  195.       break;
  196.   }                                    /* switch (retval) */
  197.   return (nread);
  198. }                                    /* get_gsm_answer () */
  199. /*========================================================*/
  200. /*####################### Semaphores #####################*/
  201. /*========================================================*/
  202. int set_semvalue (int sem_id, int value)
  203. /* returns 0 on success, -1 on failure */
  204. {
  205. #ifdef _SEM_SEMUN_UNDEFINED /* see <bits/sem.h> */
  206.   union semun {
  207.     int val; /* value for SETVAL */
  208.     struct semid_ds *buf; /* buffer for IPC_STAT & IPC_SET */
  209.     unsigned short int *array; /* array for GETALL & SETALL */
  210.     struct seminfo *__buf; /* buffer for IPC_INFO */
  211.   } sem_union;
  212. #else  
  213.   union semun sem_union;
  214. #endif                     /* #ifdef _SEM_SEMUN_UNDEFINED */
  215.   
  216.   sem_union.val = value;
  217.   return (semctl (sem_id, 0, SETVAL, sem_union));
  218. }                                      /* set_semvalue () */
  219. /*========================================================*/
  220. int sem_wait (int sem_id)
  221. /* waits for the semaphore to be decreased */
  222. {
  223.   struct sembuf sem_b;
  224.   
  225.   sem_b.sem_num = 0;                   /* sem array index */
  226.   sem_b.sem_op = -1;             /* value to inc. sem. by */
  227.   sem_b.sem_flg = SEM_UNDO;
  228.   
  229.   /* --- can sleep here --- */
  230.   return (semop (sem_id, &sem_b, 1));
  231. }                                      /* int sem_wait () */
  232. /*========================================================*/
  233. int sem_decreq (int sem_id)
  234. /* attempts to decrease the semaphore - return error if fails */
  235. {
  236.   struct sembuf sem_b;
  237.   
  238.   sem_b.sem_num = 0;                   /* sem array index */
  239.   sem_b.sem_op = -1;             /* value to inc. sem. by */
  240.   sem_b.sem_flg = (IPC_NOWAIT | SEM_UNDO);
  241.   
  242.   return (semop (sem_id, &sem_b, 1));
  243. }                                    /* int sem_decreq () */
  244. /*========================================================*/
  245. int sem_signal (int sem_id)
  246. /* increases the semaphore - always succeeds */
  247. {
  248.   struct sembuf sem_b;
  249.   
  250.   sem_b.sem_num = 0;                   /* sem array index */
  251.   sem_b.sem_op = 1;              /* value to inc. sem. by */
  252.   sem_b.sem_flg = SEM_UNDO;
  253.   
  254.   return (semop (sem_id, &sem_b, 1));
  255. }                                    /* int sem_signal () */
  256. /*==========================================================
  257.  * EOF : serv_stuff.c
  258.  *===================*/