serv_stuff.c
上传用户:eo_sii
上传日期:2007-01-05
资源大小:91k
文件大小:9k
- /*==========================================================
- * Program : serv_stuff.c Project : smslink
- * Author : Philippe Andersson.
- * Date : 24/01/00
- * Version : 0.03b
- * Notice : (c) Les Ateliers du Heron, 1998 for Scitex Europe, S.A.
- * Comment : Library of functions for the smslink server.
- *
- * Modification History :
- * - 0.01b (19/08/99) : Initial release. Moved the SMS server-
- * specific functions from stuff.c over here.
- * - 0.02b (21/10/99) : Moved tellsock() over to stuff.c (also
- * used by sms2mailgw for communication with sendmail).
- * - 0.03b (24/01/00) : The definition for union semun disappeared
- * from the include files coming with the latest version of
- * glibc2. Fixed the code for daemons_death() and set_semvalue()
- * to account for this.
- *========================================================*/
- #include <unistd.h>
- #include <stdio.h> /* for fprintf */
- #include <stdlib.h> /* for errno & stuff */
- #include <errno.h>
- #include <string.h>
- #include <syslog.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 <dial/modems.h> /* requires 'libmodem' */
- #include "sms_serv.h"
- /*========================================================*/
- /* For debugging purposes only - comment out for normal compile */
- /* #define INCL_DEBUG_CODE */
- /*========================================================*/
- void daemons_death ()
- {
- #ifdef _SEM_SEMUN_UNDEFINED /* see <bits/sem.h> */
- union semun {
- int val; /* value for SETVAL */
- struct semid_ds *buf; /* buffer for IPC_STAT & IPC_SET */
- unsigned short int *array; /* array for GETALL & SETALL */
- struct seminfo *__buf; /* buffer for IPC_INFO */
- } sem_union;
- #else
- union semun sem_union;
- #endif /* #ifdef _SEM_SEMUN_UNDEFINED */
- extern int shmem_sem, global_sem;
- extern int shmem_id;
- extern void *shared_memory;
- extern acl_list gsm_acl;
- extern int errno;
-
- /* free what's need to be freed */
- free_acl_list (&gsm_acl);
-
- /* release shared memory */
- if (shmdt (shared_memory) == -1)
- syserr ("sms_serv: can't detach from shared memory segment");
- if (shmctl (shmem_id, IPC_RMID, 0) == -1)
- syserr ("sms_serv: can't remove shared memory segment");
-
- /* delete semaphores */
- if (semctl (shmem_sem, 0, IPC_RMID, sem_union) == -1)
- syserr ("sms_serv: can't delete shmem semaphore");
-
- if (semctl (global_sem, 0, IPC_RMID, sem_union) == -1)
- syserr ("sms_serv: can't delete global semaphore");
-
- /* remove checkpoint file */
- if (unlink (CHECKPOINTF) == -1) {
- if (errno != ENOENT) { /* no such file... */
- syserr ("sms_serv: can't remove checkpoint file");
- }
- }
- /* log it... */
- syslog ((FACILITY | LOG_INFO), "server exiting on SIGTERM.");
- /* closes connection to the syslog daemon */
- closelog ();
-
- /* now exits gracefully */
- exit (0);
- } /* daemons_death () */
- /*========================================================*/
- /*========================================================*/
- /*################# struct gsms_def handling #############*/
- /*========================================================*/
- int gsmdevcpy (struct gsms_def *dest, struct gsms_def *src)
- {
- if ((src != NULL) && (dest != NULL)) {
- dest->free = src->free;
- dest->owner = src->owner;
- strcpy (dest->device, src->device);
- strcpy (dest->PIN, src->PIN);
- strcpy (dest->PUK, src->PUK);
- strcpy (dest->addr, src->addr);
- strcpy (dest->defsca, src->defsca);
- strcpy (dest->provider, src->provider);
- return (0);
- }
- else {
- return (-1);
- }
- } /* gsmdevcpy () */
- /*========================================================*/
- /*################ Dialogue with GSM module ##############*/
- /*========================================================*/
- int tell_gsm (int fd, char *command)
- {
- int len;
-
- len = strlen (command);
- if (write (fd, command, len) != len) {
- syslog ((FACILITY | LOG_ERR), "error writing to the GSM module.");
- mdmperror ("error writing to the GSM module");
- mdm_unlock (mdmopendevice);
- hangup (fd);
- free (command);
- exit (-1);
- }
- } /* tell_gsm () */
- /*========================================================*/
- int get_gsm_answer (int fd, char *answer, int size, int resptime)
- {
- int nread, retval, previous;
- fd_set inputs;
- struct timeval timeout;
- char *buffer;
-
- /*--------------------------------------Initializations */
- nread = previous = 0;
-
- FD_ZERO (&inputs);
- FD_SET (fd, &inputs);
-
- timeout.tv_sec = 10;
- timeout.tv_usec = 0;
-
- /* wait for data to arrive on the line */
- retval = select (FD_SETSIZE, &inputs, NULL, NULL, &timeout);
- switch (retval) {
- case 0:
- syslog ((FACILITY | LOG_WARNING), "timeout while waiting for GSM answer.");
- break;
-
- case -1:
- syserr ("sms_serv: call to select() failed");
- break;
-
- default:
- if (FD_ISSET (fd, &inputs)) {
- /* first wait for all data to be ready */
- ioctl (fd, FIONREAD, &nread);
- while (nread != previous) {
- sleep (resptime);
- previous = nread;
- ioctl (fd, FIONREAD, &nread);
- } /* while (nread != previous) */
- /* we know what's the data size - alloc space for it */
- buffer = (char *) malloc ((nread + 1) * sizeof (char));
- if (!buffer)
- syserr ("sms_serv: can't allocate buffer space");
- /* now we can finally read this data */
- nread = read (fd, buffer, nread);
- switch (nread) {
- case 0:
- /* EOF */
- syslog ((FACILITY | LOG_WARNING), "got no data from GSM module.");
- break;
-
- case -1:
- syserr ("sms_serv: error while reading answer from GSM");
- break;
-
- default:
- buffer[nread] = ' ';
- #ifdef INCL_DEBUG_CODE
- fprintf (stderr, "pid<%d> Got : [%s] (%d char)n", getpid (), buffer, nread);
- #endif
- /* here we could pre-process it (remove Ctrl-Z) */
- /* copy it over to out string param. */
- if (nread > size) {
- syslog ((FACILITY | LOG_WARNING), "too much data, truncation will occur");
- strncpy (answer, buffer, size);
- answer[size] = ' ';
- }
- else {
- strcpy (answer, buffer);
- }
- break;
- } /* switch (nread) */
- } /* if (FD_ISSET... */
- free (buffer);
- break;
- } /* switch (retval) */
- return (nread);
- } /* get_gsm_answer () */
- /*========================================================*/
- /*####################### Semaphores #####################*/
- /*========================================================*/
- int set_semvalue (int sem_id, int value)
- /* returns 0 on success, -1 on failure */
- {
- #ifdef _SEM_SEMUN_UNDEFINED /* see <bits/sem.h> */
- union semun {
- int val; /* value for SETVAL */
- struct semid_ds *buf; /* buffer for IPC_STAT & IPC_SET */
- unsigned short int *array; /* array for GETALL & SETALL */
- struct seminfo *__buf; /* buffer for IPC_INFO */
- } sem_union;
- #else
- union semun sem_union;
- #endif /* #ifdef _SEM_SEMUN_UNDEFINED */
-
- sem_union.val = value;
- return (semctl (sem_id, 0, SETVAL, sem_union));
- } /* set_semvalue () */
- /*========================================================*/
- int sem_wait (int sem_id)
- /* waits for the semaphore to be decreased */
- {
- struct sembuf sem_b;
-
- sem_b.sem_num = 0; /* sem array index */
- sem_b.sem_op = -1; /* value to inc. sem. by */
- sem_b.sem_flg = SEM_UNDO;
-
- /* --- can sleep here --- */
- return (semop (sem_id, &sem_b, 1));
- } /* int sem_wait () */
- /*========================================================*/
- int sem_decreq (int sem_id)
- /* attempts to decrease the semaphore - return error if fails */
- {
- struct sembuf sem_b;
-
- sem_b.sem_num = 0; /* sem array index */
- sem_b.sem_op = -1; /* value to inc. sem. by */
- sem_b.sem_flg = (IPC_NOWAIT | SEM_UNDO);
-
- return (semop (sem_id, &sem_b, 1));
- } /* int sem_decreq () */
- /*========================================================*/
- int sem_signal (int sem_id)
- /* increases the semaphore - always succeeds */
- {
- struct sembuf sem_b;
-
- sem_b.sem_num = 0; /* sem array index */
- sem_b.sem_op = 1; /* value to inc. sem. by */
- sem_b.sem_flg = SEM_UNDO;
-
- return (semop (sem_id, &sem_b, 1));
- } /* int sem_signal () */
- /*==========================================================
- * EOF : serv_stuff.c
- *===================*/