📄 serv_stuff.c
字号:
/*========================================================== * 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] = '\0';#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] = '\0'; } 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 *===================*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -