Logo Search packages:      
Sourcecode: smstools version File versions

smsd.c

/*
SMS Server Tools
Copyright (C) Stefan Frings

This program is free software unless you got it under another license directly
from the author. You can redistribute it and/or modify it under the terms of
the GNU General Public License as published by the Free Software Foundation.
Either version 2 of the License, or (at your option) any later version.

http://www.meinemullemaus.de/
mailto: smstools@meinemullemaus.de
*/

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <signal.h>
#include <time.h>
#ifndef NOSTATS
#include <mm.h>
#endif
#include <fcntl.h>
#include "extras.h"
#include "locking.h"
#include "smsd_cfg.h"
#include "stats.h"
#include "version.h"
#include "blacklist.h"
#include "whitelist.h"
#include "logging.h"
#include "alarm.h"
#include "charset.h"

int logfilehandle;  // handle of log file.
int thread_id; // -1 for main task, all other have numbers starting with 0.


/* =======================================================================
   Runs checkhandler and returns return code
   ======================================================================= */
   
int run_checkhandler(char* filename)
{
  char cmdline[PATH_MAX+PATH_MAX+32];
  if (checkhandler[0])
  {
    sprintf(cmdline,"%s %s",checkhandler,filename);
    return my_system(cmdline);
  }
  else
  {
    return 0;
  }
}

/* =======================================================================
   Stops the program if the given file exists
   ======================================================================= */

/* filename1 is checked. The others arguments are used to compose an error message. */

void stop_if_file_exists(char* infotext1, char* filename1, char* infotext2, char* filename2)
{
  int datei;
  datei=open(filename1,O_RDONLY);
  if (datei>=0)
  {
    close(datei);
    writelogfile(LOG_CRIT,"Fatal error: %s %s %s %s. %s. Check file and dir permissions.",infotext1,filename1,infotext2,filename2,strerror(errno));
    alarm_handler(LOG_CRIT,"SMSD","Fatal error: %s %s %s %s. %s. Check file and dir permissions.",infotext1,filename1,infotext2,filename2,strerror(errno));
    kill(0,SIGTERM);
  }
}



/* =======================================================================
   Reads an SMS file and splits it into many shorter parts
   ======================================================================= */

// Calculates the number of character in GSM alphabet (some ISO characters need 2 bytes space in GSM)
int calculate_characters(char* text)
{
  int counter=0;
  int character;
  for (character=0; text[character]!=0; character++)
  {
    if (ext_convert(text[character],CS_ISO,CS_SMS)!=' ') // If the character is an extended character ...
      counter+=2;
    else
      counter++;
  }
  return counter;
}


int getSMSdata(char* filename, /* Filename */
               char* To, /* destination number */
             char* From, /* sender name or number */
             char* Text, /* the selected part of the text */
             int* Binary, /* 1 is the content is marked as binary */
             int part, /* this selects the part (beginning with 1) */
             int size, /* Size of the part. Alls parts must be the same size */
             int* udh, /* UDH flag */
             char* Queue, /* Name of Queue */
             int *Flash, /* 1 if send as Flash SMS */
             char* smsc) /* SMSC Number */
{
#define maxlen 2048
  FILE* File;
  char line[300];
  char* sms;
  char tmp[30];
  int character=0;
  int startpos=0;
  int emptyline=0;
  int source_position,dest_position,step,gsm_space;
  int empty;
  To[0]=0;
  From[0]=0;
  Text[0]=0;
  smsc[0]=0;
  Queue[0]=0;
  *Binary=0;
  *udh=1;
  *Flash=0;
  File=fopen(filename,"r");
  if (File)
  {
    sms=calloc(1,maxlen);
    if (!sms)
    {
      writelogfile(LOG_ERR,"could not allocate %d bytes of memory", maxlen);
      fclose(File);
      return 0;
    }
    sms[0]=0;
    while (fgets(line,sizeof(line),File))
    {
      if (emptyline)
      {
        if ((character+strlen(line))<maxlen)
        {
        int i;
        for (i=0; i<strlen(line); i++)
          if (line[i]=='\'')
            line[i]='`';
          strcat(sms,line);
          character+=strlen(line);
        }
      }
      else
      {
        if ((line[0]==0) || (line[0]=='\n') || (line[0]=='\r'))
        emptyline=1;
        if (strstr(line,"To:")==line)
        {
        memmove(line,line+3,strlen(line)-2);
        cutspaces(line);
          if (strstr(line,"00")==line)
            strcpy(To,line+2);
        else if (strchr(line,'+')==line)
          strcpy(To,line+1);
        else
            strcpy(To,line);
        }
        else if (strstr(line,"From:")==line)
        {
          strcpy(From,line+5);
        cutspaces(From);
        }
      else if (strstr(line,"SMSC:")==line)
      {
        memmove(line,line+5,strlen(line)-4);
        cutspaces(line);
          if (strstr(line,"00")==line)
            strcpy(smsc,line+2);
        else if (strchr(line,'+')==line)
          strcpy(smsc,line+1);
        else
            strcpy(smsc,line);
      }
        else if (strstr(line,"Flash:")==line)
        {
          strncpy(tmp,line+6,30);
        cutspaces(tmp);
        if ((strcasecmp(tmp,"yes")==0) || (strcasecmp(tmp,"true")==0) || (strcasecmp(tmp,"1")==0))
          *Flash=1;
        }
        else if (strstr(line,"Provider:")==line)
        {
          strcpy(Queue,line+9);
        cutspaces(Queue);
        }
        else if (strstr(line,"Queue:")==line)
        {
          strcpy(Queue,line+6);
          cutspaces(Queue);
        }
        else if (strstr(line,"Binary:")==line)
        {
          strncpy(tmp,line+8,30);
        cutspaces(tmp);
        if ((strcasecmp(tmp,"yes")==0) || (strcasecmp(tmp,"true")==0) || (strcasecmp(tmp,"1")==0))
          *Binary=1;
      }
      else if (strstr(line,"UDH:")==line)
      {
          strncpy(tmp,line+5,30);
        cutspaces(tmp);
        if ((strcasecmp(tmp,"yes")==0) || (strcasecmp(tmp,"true")==0) || (strcasecmp(tmp,"1")==0))
          *udh=1;
        else
          *udh=0;
      }
      }
    }
    fclose(File);
    
    // Remove trailing line-breaks
    while ((character>1) && ((sms[character-1]=='\n') || (sms[character-1]=='\r')))
    {
      character--;
      sms[character]=0;
    }

    if (part==0) // Do not get Text if part=0
    {
      free(sms);
      return 1;
    }


    if (*Binary==1)   // Binary mode
    {
      Text[0]=0;
      free(sms);
      if (part>1)
        return 0;
      else
        return 1;
    }
    else  // Text mode
    {
      *udh=0;

      if ((calculate_characters(sms)>size) && (autosplit))  // Text needs to be splitted
      {

        source_position=0;
        for (step=1; step<=part; step++)  // Collect all parts until we have the desired one
        {
          Text[0]=0;

          if (number_parts)
            sprintf(Text,"%i ",step);   // Write part nr into the text

          gsm_space=dest_position=strlen(Text);
          empty=1;
          while ((gsm_space<size) && (sms[source_position])) // Collect as many characters as fit into size
          {
            empty=0;
            Text[dest_position++]=sms[source_position];
            if (ext_convert(sms[source_position++],CS_ISO,CS_SMS)!=' ')  // Is that an extended character?
              gsm_space+=2;
            else
              gsm_space++;
          }
          Text[dest_position]=0;
        }
        free(sms);
        if (empty)
          return 0;
        else
          return 1;
      }


      else  // Take the first size characters of the text and ignre the rest
      {
        Text[0]=0;
        if (part>1)  // If second part or more requested, return error
        {
          free(sms);
          return 0;
        }
        else
        {
          strncat(Text,sms,size);
          strcat(Text,"\x00");
          free(sms);
          return 1;
        }
      }

      if ((character>size) && autosplit)
        startpos=(size-3)*(part-1);
      else
        startpos=size*(part-1);
      if ((startpos>=character) && (character>0))
      {
        free(sms);
        return 0;
      }
      else if ((character>size) && autosplit)
      {
        sprintf(Text,"%i ",part);
        strncat(Text,sms+startpos,size-3);
        strcat(Text,"\x00");
      }
      else
      {
        Text[0]=0;
        strncat(Text,sms,size);
      }
      free(sms);
      return 1;
    }
  }
  else return 0;
}

/* =======================================================================
   Mainspooler (sorts SMS into queues, only used if there are provider queues)
   ======================================================================= */

void mainspooler()
{
  char filename[PATH_MAX];
  char to[100];
  char from[100];
  char smsc[100];
  char provider[100];
  char text[300];
  char directory[PATH_MAX];
  char cmdline[PATH_MAX+PATH_MAX+32];
  int queue;
  int binary;
  int udh;
  int i;
  int black;
  int white;
  int checked;
  int flash;
  writelogfile(LOG_INFO,"Smsd main program has started.");
  while (1)
  {
    if (getfile(d_spool,filename))
    {
      if (getSMSdata(filename,to,from,text,&binary,0,160,&udh,provider,&flash,smsc))
      {
        // is To: in the blacklist or whitelist?
        black=inblacklist(to);
      white=inwhitelist(to);
      checked=run_checkhandler(filename);
      // is there a provider name, then set the queue by this name
      if (provider[0])
        queue=getqueue(provider,directory);
      // else set the queue name by phone number
      else
        queue=getqueue(to,directory);
      // is everything ok, then move the file into the queue
        if ((queue!=-1) && (black==0) && (whitelist[0]==0 || white) && (checked==0))
      {
        movefilewithdestlock(filename,directory);
        stop_if_file_exists("Cannot move",filename,"to",directory);
          if (queue>=0)
            writelogfile(LOG_INFO,"Moved SMS from %s to %s to queue %s",from,to,queues[queue].name);
          else
            writelogfile(LOG_INFO,"Moved SMS from %s to %s to checked queue",from,to);
      }
      // else handle errors
      else
      {
        if (black)
        {
          writelogfile(LOG_NOTICE,"Invalid To: field in message file %s (blacklisted).",filename);
          alarm_handler(LOG_NOTICE,"SMSD","Invalid To: field in message file %s (blacklisted).",filename);
        }
        else if (whitelist[0] && white==0)
        {
          writelogfile(LOG_NOTICE,"Invalid To: field in message file %s (not in whitelist).",filename);
          alarm_handler(LOG_NOTICE,"SMSD","Invalid To: field in message file %s (not in whitelist).",filename); 
        }
        else if (checked!=0)
        {
            writelogfile(LOG_NOTICE,"Message rejected by checkhandler. File %s.",filename);
          alarm_handler(LOG_NOTICE,"SMSD","Message rejected by checkhandler. File %s.",filename);         
        }
        else
        {
          writelogfile(LOG_NOTICE,"Invalid destination in message file %s (unknown provider).",filename);
          alarm_handler(LOG_NOTICE,"SMSD","Invalid destination in message file %s (unknown provider).",filename);
        }
        rejected_counter++;
        if (eventhandler[0])
        {
            sprintf(cmdline,"%s %s %s",eventhandler,"FAILED",filename);
            my_system(cmdline);
        }
        movefilewithdestlock(filename,d_failed);
        stop_if_file_exists("Cannot move",filename,"to",d_failed);
      }
      }
      else
        ; /* File ist nicht lesbar, einfach etwas warten und erneut versuchen */
    }
    else
    {
      for (i=0; i<delaytime; i++)
      {
      print_status();
      checkwritestats();
        sleep(1);
      }
    }
  }
}

/* =======================================================================
   Send and receive SM using the getsms and putsms
   ======================================================================= */

int sendsms(int device, char* from, char* to, char* text, int binary, char* filename, int udh, int quick, int flash, char* messageid,char* smsc)
// binary can be 0=ascii  or 1=binary
// udh can be 0=off or 1=on
// filename is only used in binary mode
// smsc is optional. Can be used to override config file setting.
{
  int result;
  char cmdline[PATH_MAX+PATH_MAX+PATH_MAX+1024];
  char tmpfilename[100];
  FILE* fd;
  time_t start_time=time(0);
  statistics[device]->status='s';
  writelogfile(LOG_INFO,"Sending SMS from %s to %s on device %s",from,to,devices[device].name);

    if (debug)
    {
      printf("----------\n%s\n----------\n",text);
      result=0;
    }
    else
    {
      sprintf(cmdline,"%s/putsms -A%i -l%i -L%i -n%s -b%i -e%i -d%s",mypath,alarmlevel,logfilehandle,loglevel,devices[device].name,devices[device].baudrate,errorsleeptime,devices[device].device);
#ifdef WINDOWS
      sprintf(cmdline,"%s/putsms.exe -A%i -l%i -L%i -n%s -b%i -e%i -d%s",mypath,alarmlevel,logfilehandle,loglevel,devices[device].name,devices[device].baudrate,errorsleeptime,devices[device].device);
#endif
      if (alarmhandler[0])
      {
        strcat(cmdline," -a'");
      strcat(cmdline,alarmhandler);
      strcat(cmdline,"'");
      }
      if (smsc[0])
      {
        strcat(cmdline," -s");
      strcat(cmdline,smsc);
      }
      else if (devices[device].smsc[0])
      {
        strcat(cmdline," -s");
      strcat(cmdline,devices[device].smsc);
      }
      if (devices[device].mode[0])
      {
        strcat(cmdline," -m");
      strcat(cmdline,devices[device].mode);
      }
      if (devices[device].pin[0])
      {
        strcat(cmdline," -p");
      strcat(cmdline,devices[device].pin);
      }
      if (devices[device].cs_convert)
        strcat(cmdline," -c");
      if (devices[device].report)
      {
        // Create a temp file for message ID
      strcpy(tmpfilename,tempnam("/tmp",devices[device].name));
        strcat(cmdline," -r -R'");
      strcat(cmdline,tmpfilename);
      strcat(cmdline,"'");
      }
      if (! devices[device].rtscts)
        strcat(cmdline," -H");
      if (quick)
        strcat(cmdline," -q");
      if (devices[device].initstring[0])
      {
        strcat(cmdline," -i'");
      strcat(cmdline,devices[device].initstring);
      strcat(cmdline,"'");
      }
      if (binary==0)
      {
        if (flash)
        strcat(cmdline," -I");
        strcat(cmdline," -- ");
        strcat(cmdline,to);
        strcat(cmdline," '");
      strcat(cmdline,text);
      strcat(cmdline,"'");
      }
      else
      {
        if (udh==0)
        strcat(cmdline," -u");
        strcat(cmdline," -F");
      strcat(cmdline,filename);
      }
      writelogfile(LOG_DEBUG,"Calling: %s",cmdline);

      result=my_system(cmdline);
    }

  statistics[device]->usage_s+=time(0)-start_time;
  if (result==0)
  {
    writelogfile(LOG_INFO,"Sending SMS to %s on %s was successful.",to,devices[device].name);
    statistics[device]->succeeded_counter++;
    messageid[0]=0;
    if (devices[device].report)
    {
      fd=fopen(tmpfilename,"r");
      if (fd)
      {
        fread(messageid,3,1,fd);
      messageid[3]=0;
      fclose(fd);
      unlink(tmpfilename);
      }     
    }
    return 1;
  }
  else
  {
    writelogfile(LOG_WARNING,"Sending SMS to %s on %s failed",to,devices[device].name);
    alarm_handler(LOG_WARNING,devices[device].name,"Sending SMS to %s failed",to);
    statistics[device]->failed_counter++;
    return 0;
  }
}

int receivesms(int device,int* quick)   // receive one SM. quick may beo 0, 1 or 2 for very quick
                              // Returns 1 if successful
                              // Return 0 if no SM available
                              // Returns -1 on error
{
  char cmdline[PATH_MAX+PATH_MAX+1024];
  char* filename;
  int result;
  char newname[PATH_MAX];
  char tmp[32];
  char* cp;
  int start_time=time(0);

  statistics[device]->status='r';
  writelogfile(LOG_INFO,"Checking device %s for incoming SMS",devices[device].name);
  //Create a temp file for received message
  filename = tempnam("/tmp",devices[device].name);
  sprintf(cmdline,"%s/getsms -l%i -L%i -n%s -b%i -e%i -d%s -s%s -o%s",mypath,logfilehandle,loglevel,devices[device].name,devices[device].baudrate,errorsleeptime,devices[device].device,devices[device].name, filename);
#ifdef WINDOWS
  sprintf(cmdline,"%s/getsms.exe -l%i -L%i -n%s -b%i -e%i -d%s -s%s -o%s",mypath,logfilehandle,loglevel,devices[device].name,devices[device].baudrate,errorsleeptime,devices[device].device,devices[device].name, filename);
#endif
  if (alarmhandler[0])
  {
    strcat(cmdline," -a");
    strcat(cmdline,alarmhandler);
    strcat(cmdline," -A");
    sprintf(tmp,"%i",alarmlevel);
    strcat(cmdline,tmp);
  }
  if (devices[device].mode[0])
  {
    strcat(cmdline," -m");
    strcat(cmdline,devices[device].mode);
  }
  if (devices[device].pin[0])
  {
    strcat(cmdline," -p");
    strcat(cmdline,devices[device].pin);
  }
  if (devices[device].cs_convert)
    strcat(cmdline," -c");
  if (! devices[device].rtscts)
    strcat(cmdline," -H");
  if (*quick)
    strcat(cmdline," -q");
  if (*quick==2)
    strcat(cmdline," -Q");
  if (devices[device].initstring[0])
  {
    strcat(cmdline," -i'");
    strcat(cmdline,devices[device].initstring);
    strcat(cmdline,"'");
  }
  if (debug)
    strcat(cmdline," -k");
  writelogfile(LOG_DEBUG,"Calling: %s",cmdline);

  result=my_system(cmdline);
  statistics[device]->usage_r+=time(0)-start_time;
  if ((result!=0) && (result!=5))
  {
    unlink(filename);
    free(filename);
    if (result==1 || result==2 || result==3)
    {
      *quick=0;
      return -1;
    }
    else
    {
      *quick=1;
      return 0;
    }
  }
  else
  {
    movefilewithdestlock(filename,d_incoming);
    stop_if_file_exists("Cannot move file",filename,"to",d_incoming);
    statistics[device]->received_counter++;
    if (eventhandler[0] || devices[device].eventhandler[0])
    {
      cp=strrchr(filename,'/');
      if (cp)
      sprintf(newname,"%s%s",d_incoming,cp);
      else
        sprintf(newname,"%s/%s",d_incoming,filename);
      if (result==5) //Status Report
      {
        if (devices[device].eventhandler[0])
          sprintf(cmdline,"%s %s %s",devices[device].eventhandler,"REPORT",newname);
        else
          sprintf(cmdline,"%s %s %s",eventhandler,"REPORT",newname);
      }
      else // SMS Received
      {
        if (devices[device].eventhandler[0])
          sprintf(cmdline,"%s %s %s",devices[device].eventhandler,"RECEIVED",newname);
        else
          sprintf(cmdline,"%s %s %s",eventhandler,"RECEIVED",newname);
      }
      my_system(cmdline);
    }
    *quick=1;
    free(filename);
    return 1;
  }
  free(filename);
}


int send(int device,int* quick,int* errorcounter)    // Search the queues for SMS to send and send one of them.
                  // Returns 0 if queues are empty
                  // Returns -1 if sending failed
                  // Returns 1 if successful
{
  char filename[PATH_MAX];
  char to[100];
  char from[100];
  char smsc[100];
  char provider[100];
  char text[400];
  char directory[PATH_MAX];
  char lockfilename[PATH_MAX];
  char cmdline[PATH_MAX+PATH_MAX+32];
  int q,queue;
  int part;
  int error;
  int max_len;
  int binary;
  int udh;
  int success=0;
  int flash;
  char messageid[10]={0};

      for (q=0; q<PROVIDER; q++)
      {
        if (devices[device].queues[q][0])
        {
          queue=getqueue(devices[device].queues[q],directory);
        // If the queue does not exist and there is no provider queue defined, then
        // use the queue name as directory name. This should happen only with d_spool.
        if (queue!=-1)
          {
          if (getfile(directory,filename))
          {
              if (lockfile(filename))
              {
              part=1;
              if (strcmp(devices[device].mode,"ascii")==0)
                max_len=140;
              else
                max_len=160;
            error=0;
              while (getSMSdata(filename,to,from,text,&binary,part,max_len,&udh,provider,&flash,smsc))
              {
                
                  // Try a quick receive to ensure that at least 1 memeory space is free
                  if ((receive_before_send) && (devices[device].incoming))
              {
                int oldquick=*quick;  // Backup original quick value
                *quick=2;
                    receivesms(device,quick);
                if (*quick>0)   // Restore original quick value if not changed to 0
                  *quick=oldquick;
              }
              // Try to send the sms
              if (!sendsms(device,from,to,text,binary,filename,udh,*quick,flash,messageid,smsc))
              {
                *quick=0;
                success=-1;
                *errorcounter++;
                error=1;
                if (*errorcounter>=3)
                {
                  writelogfile(LOG_CRIT,"Fatal error: sending on %s failed 3 times. Blocking %i sec.",devices[device].name,blocktime);
                  alarm_handler(LOG_CRIT,devices[device].name,"Fatal error: sending failed 3 times. Blocking %i sec.",blocktime);
                  statistics[device]->multiple_failed_counter++;
                  statistics[device]->status='b';
                  sleep(blocktime);
                  *errorcounter=0;
                  break;
                }
              }
              else
              {
                *quick=1;
                success=1;
                part++;
                if (autosplit==0)
                  break;
              }
              if (error)
                break;
              }
            statistics[device]->status='i';
              if (eventhandler[0] || devices[device].eventhandler[0])
                {
                if (error==1)
                  strcpy(text,"FAILED");
              else
                strcpy(text,"SENT");
              if (devices[device].eventhandler[0])
                  sprintf(cmdline,"%s %s %s %s",devices[device].eventhandler,text,filename,messageid);
              else
                  sprintf(cmdline,"%s %s %s %s",eventhandler,text,filename,messageid);
                  my_system(cmdline);
                }
              if (error==1)
            {
              if (d_failed[0])
              {
                  movefilewithdestlock(filename,d_failed);
                stop_if_file_exists("Cannot move",filename,"to",d_failed);
              }
              else
              {
                  unlink(filename);
                stop_if_file_exists("Cannot delete",filename,"","");
              }
            }
              else
            {
              if (d_sent[0])
              {
                movefilewithdestlock(filename,d_sent);
                stop_if_file_exists("Cannot move",filename,"to",d_sent);
              }
              else
              {
                  unlink(filename);
                stop_if_file_exists("Cannot delete",filename,"","");
              }
            }
              unlock(filename);
            }
          }
        }
        }
        else
          break;
      }
   return (success);
}


/* =======================================================================
   Device-Spooler (one for each modem)
   ======================================================================= */


void devicespooler(int device)
{
  int workless;
  int quick=0;
  int errorcounter;

  writelogfile(LOG_INFO,"Modem handler %i for %s has started.",device,devices[device].name);
  errorcounter=0;

  while (1) /* endless loop */
  {
    workless=1;

    // Send SM
    while (send(device,&quick,&errorcounter)==1)
    {
      workless=0;
      if (devices[device].incoming==2) // repeat only if receiving has low priority
        break;
    }

    // Receive SM
    if (devices[device].incoming)
      while (receivesms(device,&quick)==1)
      {
        workless=0;
        if (devices[device].incoming==1) // repeat only if receiving has high priority
          break;
      }

    if (workless==1) // wait a little bit if there was no SM to send or receive to save CPU usage
    {
      statistics[device]->status='i';
      sleep(delaytime);
    }
  }
}


/* =======================================================================
   Task-Maker (creates threads for the modems and the main queue)
   ======================================================================= */

void taskmaker()
{
  int i;
  // start device spoolers
  for (i=0; i<DEVICES; i++)
  {
    if (devices[i].name[0])
      if (fork()==0)
      {
      thread_id=i;
      write_pid("/var/run/smsd.pid");
      devicespooler(i);
      remove_pid("/var/run/smsd.pid");
      }
  }
  // Start main program
  thread_id=-1;
  write_pid("/var/run/smsd.pid");
  mainspooler();
  remove_pid("/var/run/smsd.pid");
}

void termination_handler (int signum)
{
  if (thread_id==-1)
  {
    savestats();
#ifndef NOSTATS
    MM_destroy();
#endif
    writelogfile(LOG_CRIT,"Smsd main program has stopped.");
    thread_id=-2;
    kill(0,SIGTERM);
  }
  else if (thread_id>=0)
    writelogfile(LOG_CRIT,"Modem handler %i for %s has stopped.",thread_id,devices[thread_id].name);
  remove_pid("/var/run/smsd.pid");
  exit(0);
}

/* =======================================================================
   Main
   ======================================================================= */

int main(int argc,char** argv)
{
  if (signal(SIGINT,termination_handler)==SIG_IGN)
    signal(SIGINT,SIG_IGN);
  if (signal(SIGTERM,termination_handler)==SIG_IGN)
    signal(SIGTERM,SIG_IGN);
    
  parsearguments(argc,argv);
  initcfg();
  readcfg();
  logfilehandle=openlogfile("smsd",logfile,LOG_DAEMON,loglevel);  
  initstats();
  loadstats();
  writelogfile(LOG_CRIT,"Smsd v%s started. Made for getsms v%s and putsms v%s.",smsd_version,getsms_version,putsms_version);  
  taskmaker();

}

Generated by  Doxygen 1.6.0   Back to index