Main Page | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

utils.c File Reference

#include "gw-config.h"
#include <ctype.h>
#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <termios.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pwd.h>
#include <grp.h>
#include "gwlib.h"

Include dependency graph for utils.c:

Include dependency graph

Go to the source code of this file.

Defines

#define PANIC_SCRIPT_MAX_LEN   4096

Functions

void parachute_sig_handler (int signum)
void parachute_init_signals (int child)
int is_executable (const char *filename)
int become_daemon (void)
 PRINTFLIKE (2, 3)
void parachute_start (const char *myname, const char *panic_script)
void write_pid_file (void)
void remove_pid_file (void)
int change_user (const char *user)
MultibyteInt get_variable_value (Octet *source, int *len)
int write_variable_value (MultibyteInt value, Octet *dest)
Octet reverse_octet (Octet source)
int get_and_set_debugs (int argc, char **argv, int(*find_own)(int index, int argc, char **argv))
int pattern_matches_ip (Octstr *pattern, Octstr *ip)
int pattern_list_matches_ip (Octstr *pattern_list, Octstr *ip)
int is_allowed_ip (Octstr *allow_ip, Octstr *deny_ip, Octstr *ip)
int connect_denied (Octstr *allow_ip, Octstr *ip)
int does_prefix_match (Octstr *prefix, Octstr *number)
int normalize_number (char *dial_prefixes, Octstr **number)
long decode_network_long (unsigned char *data)
void encode_network_long (unsigned char *data, unsigned long value)
void kannel_cfmakeraw (struct termios *tio)
int gw_isdigit (int c)
int gw_isxdigit (int c)
int roundup_div (int a, int b)
unsigned long long gw_generate_id (void)

Variables

pid_t child_pid = -1
sigaction child_actions [32]
int child_actions_init = 0
char * pid_file = NULL
volatile sig_atomic_t parachute_shutdown = 0


Define Documentation

#define PANIC_SCRIPT_MAX_LEN   4096
 

Definition at line 205 of file utils.c.

Referenced by PRINTFLIKE().


Function Documentation

int become_daemon void   )  [static]
 

Definition at line 180 of file utils.c.

References panic.

Referenced by get_and_set_debugs().

00181 {
00182     int fd;
00183     if (getppid() != 1) {
00184        signal(SIGTTOU, SIG_IGN);
00185        signal(SIGTTIN, SIG_IGN);
00186        signal(SIGTSTP, SIG_IGN);
00187        if (fork())
00188           return 0;
00189        setsid();
00190     }
00191 
00192     close(STDIN_FILENO);
00193     close(STDOUT_FILENO);
00194     close(STDERR_FILENO);
00195     fd = open("/dev/null", O_RDWR); /* stdin */
00196     if (fd == -1)
00197         panic(errno, "Could not open `/dev/null'");
00198     dup(fd); /* stdout */
00199     dup(fd); /* stderr */
00200 
00201     chdir("/");
00202     return 1;
00203 }

int change_user const char *  user  )  [static]
 

Definition at line 349 of file utils.c.

References error().

Referenced by get_and_set_debugs().

00350 {
00351     struct passwd *pass;
00352 
00353     if (!user)
00354         return -1;
00355 
00356     pass = getpwnam(user);
00357     if (!pass) {
00358         error(0, "Could not find a user `%s' in system.", user);
00359         return -1;
00360     }
00361 
00362     if (-1 == setgid(pass->pw_gid)) {
00363         error(errno, "Could not change group id from %ld to %ld.", (long) getgid(), (long) pass->pw_gid);
00364         return -1;
00365     }
00366 
00367     if (initgroups(user, -1) == -1) {
00368         error(errno, "Could not set supplementary group ID's.");
00369     }
00370     
00371     if (-1 == setuid(pass->pw_uid)) {
00372         error(errno, "Could not change user id from %ld to %ld.", (long) getuid(), (long) pass->pw_uid);
00373         return -1;
00374     }
00375 
00376     return 0;
00377 }

Here is the call graph for this function:

int connect_denied Octstr allow_ip,
Octstr ip
 

Definition at line 633 of file utils.c.

References octstr_imm(), and pattern_list_matches_ip().

Referenced by httpsmsc_receiver().

00634 {
00635     if (ip == NULL)
00636     return 1;
00637 
00638     /* If IP not set, allow from Localhost */
00639     if (allow_ip == NULL) { 
00640     if (pattern_list_matches_ip(octstr_imm("127.0.0.1"), ip))
00641         return 0;
00642     } else {
00643     if (pattern_list_matches_ip(allow_ip, ip))
00644         return 0;
00645     }
00646     return 1;
00647 }

Here is the call graph for this function:

long decode_network_long unsigned char *  data  ) 
 

Definition at line 735 of file utils.c.

References data.

Referenced by conn_read_withlen(), parse_integer(), read_msg(), and smpp_pdu_read_len().

00735                                               {
00736         return (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];
00737 }

int does_prefix_match Octstr prefix,
Octstr number
 

Definition at line 650 of file utils.c.

References gw_assert, number, and octstr_get_cstr.

Referenced by check_allowed_translation(), and smscconn_usable().

00651 {
00652     /* XXX modify to use just octstr operations
00653      */
00654     char *b, *p, *n;
00655 
00656     gw_assert(prefix != NULL);
00657     gw_assert(number != NULL);
00658 
00659     p = octstr_get_cstr(prefix);
00660     n = octstr_get_cstr(number);
00661     
00662 
00663     while (*p != '\0') {
00664         b = n;
00665         for (b = n; *b != '\0'; b++, p++) {
00666             if (*p == ';' || *p == '\0') {
00667                 return 1;
00668             }
00669             if (*p != *b) break;
00670         }
00671         if (*p == ';' || *p == '\0') {
00672             return 1;
00673         }
00674         while (*p != '\0' && *p != ';')
00675             p++;
00676         while (*p == ';') p++;
00677     }
00678     return 0;
00679 }

void encode_network_long unsigned char *  data,
unsigned long  value
 

Definition at line 740 of file utils.c.

References data.

Referenced by append_integer(), conn_write_withlen(), and write_msg().

00740                                                                    {
00741         data[0] = (value >> 24) & 0xff;
00742         data[1] = (value >> 16) & 0xff;
00743         data[2] = (value >> 8) & 0xff;
00744         data[3] = value & 0xff;
00745 }

int get_and_set_debugs int  argc,
char **  argv,
int(*)(int index, int argc, char **argv)  find_own
 

Definition at line 434 of file utils.c.

References become_daemon(), cfg_dump_all(), change_user(), GW_NON_EXCL, info(), log_close_all(), log_open(), log_set_debug_places(), log_set_output_level(), log_set_syslog(), panic, parachute_start(), pid_file, remove_pid_file(), and write_pid_file().

Referenced by main().

00436 {
00437     int i, ret = -1;
00438     int debug_lvl = -1;
00439     int file_lvl = GW_DEBUG;
00440     char *log_file = NULL;
00441     char *debug_places = NULL;
00442     char *panic_script = NULL, *user = NULL;
00443     int parachute = 0, daemonize = 0;
00444 
00445     for (i=1; i < argc; i++) {
00446         if (strcmp(argv[i],"-v")==0 || strcmp(argv[i],"--verbosity")==0) {
00447             if (i+1 < argc) {
00448                 debug_lvl = atoi(argv[i+1]);
00449                 i++;
00450             } else
00451                 panic(0, "Missing argument for option %s\n", argv[i]); 
00452         } else if (strcmp(argv[i],"-F")==0 || strcmp(argv[i],"--logfile")==0) {
00453             if (i+1 < argc && *(argv[i+1]) != '-') {
00454                 log_file = argv[i+1];
00455                 i++;
00456             } else
00457                 panic(0, "Missing argument for option %s\n", argv[i]); 
00458         } else if (strcmp(argv[i],"-V")==0 || strcmp(argv[i],"--fileverbosity")==0) {
00459             if (i+1 < argc) {
00460                 file_lvl = atoi(argv[i+1]);
00461                 i++;
00462             } else
00463                 panic(0, "Missing argument for option %s\n", argv[i]); 
00464         } else if (strcmp(argv[i],"-D")==0 || strcmp(argv[i],"--debug")==0) {
00465             if (i+1 < argc) {
00466                 debug_places = argv[i+1];
00467                 i++;
00468             } else
00469                 panic(0, "Missing argument for option %s\n", argv[i]); 
00470         } else if (strcmp(argv[i], "-X")==0 || strcmp(argv[i], "--panic-script")==0) {
00471             if (i+1 < argc) {
00472                 panic_script = argv[i+1];
00473                 i++;
00474             } else
00475                 panic(0, "Missing argument for option %s\n", argv[i]);
00476         } else if (strcmp(argv[i], "-P")==0 || strcmp(argv[i], "--parachute")==0) {
00477             parachute = 1;
00478         } else if (strcmp(argv[i], "-d")==0 || strcmp(argv[i], "--daemonize")==0) {
00479             daemonize = 1;
00480         } else if (strcmp(argv[i], "-p")==0 || strcmp(argv[i], "--pid-file")==0) {
00481             if (i+1 < argc) {
00482                 pid_file = argv[i+1];
00483                 i++;
00484             } else
00485                 panic(0, "Missing argument for option %s\n", argv[i]);
00486         } else if (strcmp(argv[i], "-u")==0 || strcmp(argv[i], "--user")==0) {
00487             if (i+1 < argc) {
00488                 user = argv[i+1];
00489                 i++;
00490             } else
00491                 panic(0, "Missing argument for option %s\n", argv[i]);
00492         } else if (strcmp(argv[i], "-g")==0 || strcmp(argv[i], "--generate")==0) {
00493             cfg_dump_all();
00494             exit(0);
00495         } else if (strcmp(argv[i],"--")==0) {
00496             i++;
00497             break;
00498         } else if (*argv[i] != '-') {
00499             break;
00500         } else {
00501             if (find_own != NULL) {
00502             ret = find_own(i, argc, argv);
00503         }
00504         if (ret < 0) {
00505             fprintf(stderr, "Unknown option %s, exiting.\n", argv[i]);
00506             panic(0, "Option parsing failed");
00507         } else
00508             i += ret;   /* advance additional args */
00509         }
00510     }
00511 
00512     if (user && -1 == change_user(user))
00513         panic(0, "Could not change to user `%s'.", user);
00514 
00515     /* deamonize */
00516     if (daemonize && !become_daemon())
00517        exit(0);
00518 
00519     if (pid_file) {
00520         write_pid_file();
00521         atexit(remove_pid_file);
00522     }
00523 
00524     if (parachute) {
00525         /*
00526          * if we are running as daemon so open syslog
00527          * in order not to deal with i.e. log rotate.
00528          */
00529         if (daemonize) {
00530             char *ident = strrchr(argv[0], '/');
00531             if (!ident)
00532                 ident = argv[0];
00533             else
00534                 ident++;
00535             log_set_syslog(ident, (debug_lvl > -1 ? debug_lvl : 0));
00536         }
00537         parachute_start(argv[0], panic_script);
00538         /* now we are in child process so close syslog */
00539         if (daemonize)
00540             log_close_all();
00541     }
00542 
00543     if (debug_lvl > -1)
00544         log_set_output_level(debug_lvl);
00545     if (debug_places != NULL)
00546         log_set_debug_places(debug_places);
00547     if (log_file != NULL)
00548         log_open(log_file, file_lvl, GW_NON_EXCL);
00549 
00550     info(0, "Debug_lvl = %d, log_file = %s, log_lvl = %d",
00551          debug_lvl, log_file ? log_file : "<none>", file_lvl);
00552     if (debug_places != NULL)
00553         info(0, "Debug places: `%s'", debug_places);
00554 
00555     return i;
00556 }

Here is the call graph for this function:

MultibyteInt get_variable_value Octet source,
int *  len
 

Definition at line 385 of file utils.c.

References MultibyteInt.

Referenced by sema_decode_msg().

00386 {
00387     MultibyteInt retval = 0;
00388     
00389     for(*len=1;; (*len)++, source++) {
00390     retval = retval * 0x80 + (*source & 0x7F);
00391     if (*source < 0x80)  /* if the continue-bit (high bit) is not set */
00392         break;
00393     }
00394     return retval;
00395 }

unsigned long long gw_generate_id void   ) 
 

Definition at line 813 of file utils.c.

References gw_rand().

00814 {
00815     /* create a 64 bit unique Id by putting a 32 bit epoch time value
00816      * and a 32 bit random value together */
00817     unsigned long random, timer;
00818      
00819     random = gw_rand();
00820     timer = (unsigned long)time(NULL);
00821     
00822     return ((unsigned long long)timer << 32) + random;
00823 }

Here is the call graph for this function:

int gw_isdigit int  c  ) 
 

Definition at line 788 of file utils.c.

Referenced by convert_addr_from_pdu(), date_parse_iso(), get_originator_type(), handle_dlr(), handle_pdu(), msg_to_cgwop(), msg_to_emimsg(), msg_to_pdu(), pack_parameter(), packet_check_header(), packet_check_parameter(), and run_batch().

00789 {
00790     return isdigit(c);
00791 }

int gw_isxdigit int  c  ) 
 

Definition at line 794 of file utils.c.

Referenced by octstr_hex_to_binary(), octstr_is_all_hex(), octstr_symbolize(), packet_check(), and packet_check_parameter().

00795 {
00796     return isxdigit(c);
00797 }

int is_allowed_ip Octstr allow_ip,
Octstr deny_ip,
Octstr ip
 

Definition at line 615 of file utils.c.

References octstr_len(), and pattern_list_matches_ip().

Referenced by accept_boxc(), authorise_username(), cgw_listener(), emi2_listener(), fake_listener(), get_data(), httpadmin_run(), main(), and udp_receiver().

00616 {
00617     if (ip == NULL)
00618     return 0;
00619 
00620     if (octstr_len(deny_ip) == 0)
00621     return 1;
00622 
00623     if (allow_ip != NULL && pattern_list_matches_ip(allow_ip, ip))
00624     return 1;
00625 
00626     if (pattern_list_matches_ip(deny_ip, ip))
00627         return 0;
00628 
00629     return 1;
00630 }

Here is the call graph for this function:

int is_executable const char *  filename  )  [static]
 

Definition at line 152 of file utils.c.

References error(), and filename.

Referenced by parachute_start().

00153 {
00154     struct stat buf;
00155 
00156     if (stat(filename, &buf)) {
00157         error(errno, "Error while stat of file `%s'", filename);
00158         return 0;
00159     }
00160     if (!S_ISREG(buf.st_mode) && !S_ISLNK(buf.st_mode)) {
00161         error(0, "File `%s' is not a regular file.", filename);
00162         return 0;
00163     }
00164     /* others has exec permission */
00165     if (S_IXOTH & buf.st_mode) return 1;
00166     /* group has exec permission */
00167     if ((S_IXGRP & buf.st_mode) && buf.st_gid == getgid())
00168         return 1;
00169     /* owner has exec permission */
00170     if ((S_IXUSR & buf.st_mode) && buf.st_uid == getuid())
00171         return 1;
00172 
00173     return 0;
00174 }

Here is the call graph for this function:

void kannel_cfmakeraw struct termios *  tio  ) 
 

Definition at line 751 of file utils.c.

Referenced by at2_open_device(), at_dial(), and X28_open_data_link().

00751                                            {
00752     /* Block until a charactor is available, but it only needs to be one*/
00753     tio->c_cc[VMIN]    = 1;
00754     tio->c_cc[VTIME]   = 0;
00755 
00756     /* GNU cfmakeraw sets these flags so we had better too...*/
00757 
00758     /* Control modes */
00759     /* Mask out character size (CSIZE), then set it to 8 bits (CS8).
00760      * Enable parity bit generation in both directions (PARENB).
00761      */
00762     tio->c_cflag      &= ~(CSIZE|PARENB);
00763     tio->c_cflag      |= CS8;
00764 
00765     /* Input Flags,*/
00766     /* Turn off all input flags that interfere with the byte stream:
00767      * BRKINT - generate SIGINT when receiving BREAK, ICRNL - translate
00768      * NL to CR, IGNCR - ignore CR, IGNBRK - ignore BREAK,
00769      * INLCR - translate NL to CR, IXON - use XON/XOFF flow control,
00770      * ISTRIP - strip off eighth bit.
00771      */
00772     tio->c_iflag &= ~(BRKINT|ICRNL|IGNCR|IGNBRK|INLCR|IXON|ISTRIP);
00773 
00774     /* Other flags,*/
00775     /* Turn off all local flags that interpret the byte stream:
00776      * ECHO - echo input chars, ECHONL - always echo NL even if ECHO is off,
00777      * ICANON - enable canonical mode (basically line-oriented mode),
00778      * IEXTEN - enable implementation-defined input processing,
00779      * ISIG - generate signals when certain characters are received. */
00780     tio->c_lflag      &= ~(ECHO|ECHONL|ICANON|IEXTEN|ISIG);
00781 
00782     /* Output flags,*/
00783     /* Disable implementation defined processing on the output stream*/
00784     tio->c_oflag      &= ~OPOST;
00785 }

int normalize_number char *  dial_prefixes,
Octstr **  number
 

Definition at line 682 of file utils.c.

References gw_assert, number, octstr_create_from_data, octstr_destroy(), octstr_get_cstr, octstr_insert_data(), and octstr_len().

Referenced by bb_smscconn_receive(), radius_acct_get_msisdn(), smsc2_rout(), and smscconn_send().

00683 {
00684     char *t, *p, *official, *start;
00685     int len, official_len;
00686     
00687     if (dial_prefixes == NULL || dial_prefixes[0] == '\0')
00688         return 0;
00689 
00690     t = official = dial_prefixes;
00691     official_len = 0;
00692 
00693     gw_assert(number != NULL);
00694     
00695     while(1) {
00696 
00697         p = octstr_get_cstr(*number);
00698         for(start = t, len = 0; ; t++, p++, len++)
00699     {
00700             if (*t == ',' || *t == ';' || *t == '\0') {
00701                 if (start != official) {
00702                     Octstr *nstr;
00703             long n;
00704             
00705             if ( official[0] == '-' ) official_len=0;
00706             n = official_len;
00707             if (strlen(official) < (size_t) n)
00708                 n = strlen(official);
00709                     nstr = octstr_create_from_data(official, n);
00710                     octstr_insert_data(nstr, official_len,
00711                                            octstr_get_cstr(*number) + len,
00712                                            octstr_len(*number) - len);
00713                     octstr_destroy(*number);
00714                     *number = nstr;
00715                 }
00716                 return 1;
00717             }
00718             if (*p == '\0' || *t != *p)
00719                 break;          /* not matching */
00720         }
00721         for(; *t != ',' && *t != ';' && *t != '\0'; t++, len++)
00722             ;
00723         if (*t == '\0') break;
00724         if (start == official) official_len = len;
00725         if (*t == ';') official = t+1;
00726         t++;
00727     }
00728     return 0;
00729 }

Here is the call graph for this function:

void parachute_init_signals int  child  )  [static]
 

Definition at line 114 of file utils.c.

References child_actions, child_actions_init, and panic.

Referenced by parachute_start().

00115 {
00116     struct sigaction sa;
00117 
00118     if (child_actions_init && child) {
00119         sigaction(SIGTERM, &child_actions[SIGTERM], NULL);
00120         sigaction(SIGQUIT, &child_actions[SIGQUIT], NULL);
00121         sigaction(SIGINT,  &child_actions[SIGINT], NULL);
00122         sigaction(SIGABRT, &child_actions[SIGABRT], NULL);
00123         sigaction(SIGHUP,  &child_actions[SIGHUP], NULL);
00124         sigaction(SIGALRM, &child_actions[SIGALRM], NULL);
00125         sigaction(SIGUSR1, &child_actions[SIGUSR1], NULL);
00126         sigaction(SIGUSR2, &child_actions[SIGUSR2], NULL);
00127         sigaction(SIGPIPE, &child_actions[SIGPIPE], NULL);
00128     }
00129     else if (!child && !child_actions_init) {
00130         sa.sa_flags = 0;
00131         sigemptyset(&sa.sa_mask);
00132         sa.sa_handler = parachute_sig_handler;
00133         sigaction(SIGTERM, &sa, &child_actions[SIGTERM]);
00134         sigaction(SIGQUIT, &sa, &child_actions[SIGQUIT]);
00135         sigaction(SIGINT,  &sa, &child_actions[SIGINT]);
00136         sigaction(SIGABRT, &sa, &child_actions[SIGABRT]);
00137         sigaction(SIGHUP,  &sa, &child_actions[SIGHUP]);
00138         sigaction(SIGALRM, &sa, &child_actions[SIGALRM]);
00139         sigaction(SIGUSR1, &sa, &child_actions[SIGUSR1]);
00140         sigaction(SIGUSR2, &sa, &child_actions[SIGUSR2]);
00141         sa.sa_handler = SIG_IGN;
00142         sigaction(SIGPIPE, &sa, &child_actions[SIGPIPE]);
00143         sigaction(SIGTTOU, &sa, NULL);
00144         sigaction(SIGTTIN, &sa, NULL);
00145         sigaction(SIGTSTP, &sa, NULL);
00146         child_actions_init = 1;
00147     }
00148     else
00149         panic(0, "Child process signal handlers not initialized before.");
00150 }

void parachute_sig_handler int  signum  )  [static]
 

Definition at line 94 of file utils.c.

References child_pid, info(), and parachute_shutdown.

00095 {
00096     info(0, "Signal %d received, forward to child pid (%ld)", signum, (long) child_pid);
00097 
00098     /* we do not handle any signal, just forward these to child process */
00099     if (child_pid != -1 && getpid() != child_pid)
00100         kill(child_pid, signum);
00101 
00102     /* if signal received and no child there, terminating */
00103     switch(signum) {
00104         case SIGTERM:
00105         case SIGINT:
00106         case SIGABRT:
00107             if (child_pid == -1)
00108                 exit(0);
00109             else
00110                 parachute_shutdown = 1;
00111     }
00112 }

Here is the call graph for this function:

void parachute_start const char *  myname,
const char *  panic_script
[static]
 

Definition at line 232 of file utils.c.

References child_pid, debug(), error(), gwlib_shutdown(), gwthread_sleep(), info(), is_executable(), panic, and parachute_init_signals().

Referenced by get_and_set_debugs().

00232                                                                           {
00233     time_t last_start = 0, last_panic = 0;
00234     long respawn_count = 0;
00235     int status;
00236 
00237 
00238     if (panic_script && !is_executable(panic_script))
00239         panic(0, "Panic script `%s' is not executable for us.", panic_script);
00240 
00241     /* setup sighandler */
00242     parachute_init_signals(0);
00243 
00244     for (;;) {
00245         if (respawn_count > 0 && difftime(time(NULL), last_start) < 10) {
00246             error(0, "Child process died too fast, disabling for 30 sec.");
00247             gwthread_sleep(30.0);
00248         }
00249         if (!(child_pid = fork())) { /* child process */
00250             parachute_init_signals(1); /* reset sighandlers */
00251         return;
00252         }
00253     else if (child_pid < 0) {
00254         error(errno, "Could not start child process! Will retry in 5 sec.");
00255         gwthread_sleep(5.0);
00256             continue;
00257     }
00258     else { /* father process */
00259         time(&last_start);
00260             info(0, "Child process with PID (%ld) started.", (long) child_pid);
00261             do {
00262                 if (waitpid(child_pid, &status, 0) == child_pid) {
00263                     /* check here why child terminated */
00264                    if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
00265                        info(0, "Child process exited gracefully, exit...");
00266                        gwlib_shutdown();
00267                        exit(0);
00268                    }
00269                    else if (WIFEXITED(status)) {
00270                        error(0, "Caught child PID (%ld) which died with return code %d",
00271                            (long) child_pid, WEXITSTATUS(status));
00272                        child_pid = -1;
00273                    }
00274                    else if (WIFSIGNALED(status)) {
00275                        error(0, "Caught child PID (%ld) which died due to signal %d",
00276                            (long) child_pid, WTERMSIG(status));
00277                        child_pid = -1;
00278                    }
00279                 }
00280                 else if (errno != EINTR) {
00281                     error(errno, "Error while waiting of child process.");
00282                 }
00283             } while(child_pid > 0);
00284 
00285             if (parachute_shutdown) {
00286                 /* may only happens if child process crashed while shutdown */
00287                 info(0, "Child process crashed while shutdown. Exiting due to signal...");
00288                 info(0, "Going into gwlib_shutdown...");
00289                 gwlib_shutdown();
00290                 info(0, "gwlib_shutdown done... Bye bye...");
00291                 exit(WIFEXITED(status) ? WEXITSTATUS(status) : 0);
00292             }
00293 
00294             /* check whether it's panic while start */
00295             if (respawn_count == 0 && difftime(time(NULL), last_start) < 2) {
00296                 info(0, "Child process crashed while starting. Exiting...");
00297                 info(0, "Going into gwlib_shutdown...");
00298                 gwlib_shutdown();
00299                 info(0, "gwlib_shutdown done... Bye bye...");
00300                 exit(WIFEXITED(status) ? WEXITSTATUS(status) : 1);
00301             }
00302 
00303             respawn_count++;
00304             if (panic_script && myname && difftime(time(NULL), last_panic) > 300) {
00305                 time(&last_panic);
00306                 debug("kannel", 0, "Executing panic script: %s %s %ld", panic_script, myname, respawn_count);
00307                 execute_panic_script(panic_script, "%s %ld", myname, respawn_count);
00308             }
00309             /* sleep a while to get e.g. sockets released */
00310             gwthread_sleep(5.0);
00311     }
00312     }
00313 }

Here is the call graph for this function:

int pattern_list_matches_ip Octstr pattern_list,
Octstr ip
[static]
 

Definition at line 596 of file utils.c.

References gwlist_destroy(), gwlist_extract_first(), octstr_destroy(), octstr_destroy_item(), octstr_imm(), octstr_split(), and pattern_matches_ip().

Referenced by connect_denied(), and is_allowed_ip().

00597 {
00598     List *patterns;
00599     Octstr *pattern;
00600     int matches;
00601 
00602     patterns = octstr_split(pattern_list, octstr_imm(";"));
00603     matches = 0;
00604 
00605     while (!matches && (pattern = gwlist_extract_first(patterns)) != NULL) {
00606     matches = pattern_matches_ip(pattern, ip);
00607     octstr_destroy(pattern);
00608     }
00609     
00610     gwlist_destroy(patterns, octstr_destroy_item);
00611     return matches;
00612 }

Here is the call graph for this function:

int pattern_matches_ip Octstr pattern,
Octstr ip
[static]
 

Definition at line 559 of file utils.c.

References octstr_get_char(), and octstr_len().

Referenced by pattern_list_matches_ip().

00560 {
00561     long i, j;
00562     long pat_len, ip_len;
00563     int pat_c, ip_c;
00564     
00565     pat_len = octstr_len(pattern);
00566     ip_len = octstr_len(ip);
00567 
00568     i = 0;
00569     j = 0;
00570     while (i < pat_len && j < ip_len) {
00571     pat_c = octstr_get_char(pattern, i);
00572     ip_c = octstr_get_char(ip, j);
00573     if (pat_c == ip_c) {
00574         /* The characters match, go to the next ones. */
00575         ++i;
00576         ++j;
00577     } else if (pat_c != '*') {
00578         /* They differ, and the pattern isn't a wildcard one. */
00579         return 0;
00580     } else {
00581         /* We found a wildcard in the pattern. Skip in ip. */
00582         ++i;
00583         while (j < ip_len && ip_c != '.') {
00584         ++j;
00585         ip_c = octstr_get_char(ip, j);
00586         }
00587     }
00588     }
00589     
00590     if (i >= pat_len && j >= ip_len)
00591         return 1;
00592     return 0;
00593 }

Here is the call graph for this function:

PRINTFLIKE ,
[static]
 

Definition at line 207 of file utils.c.

References PANIC_SCRIPT_MAX_LEN.

00208 {
00209     char *args[3];
00210     char buf[PANIC_SCRIPT_MAX_LEN + 1];
00211     va_list ap;
00212 
00213     va_start(ap, format);
00214     vsnprintf(buf, PANIC_SCRIPT_MAX_LEN, format, ap);
00215     va_end(ap);
00216 
00217     if (fork())
00218        return;
00219 
00220     close(STDIN_FILENO);
00221     close(STDOUT_FILENO);
00222     close(STDERR_FILENO);
00223 
00224     args[0] = (char*) panic_script;
00225     args[1] = buf;
00226     args[2] = NULL;
00227 
00228     execv(args[0], args);
00229 }

void remove_pid_file void   )  [static]
 

Definition at line 336 of file utils.c.

References child_pid, error(), and pid_file.

Referenced by get_and_set_debugs().

00337 {
00338     if (!pid_file)
00339         return;
00340 
00341     /* ensure we don't called from child process */
00342     if (child_pid == 0)
00343         return;
00344 
00345     if (-1 == unlink(pid_file))
00346         error(errno, "Could not unlink pid-file `%s'", pid_file);
00347 }

Here is the call graph for this function:

Octet reverse_octet Octet  source  ) 
 

Definition at line 418 of file utils.c.

References Octet.

Referenced by OTAbitmap_create(), and wbmp_create().

00419 {
00420     Octet   dest;
00421     dest = (source & 1) <<7;
00422     dest += (source & 2) <<5;
00423     dest += (source & 4) <<3;
00424     dest += (source & 8) <<1;
00425     dest += (source & 16) >>1;
00426     dest += (source & 32) >>3;
00427     dest += (source & 64) >>5;
00428     dest += (source & 128) >>7;
00429     
00430     return dest;
00431 }

int roundup_div int  a,
int  b
 

Definition at line 801 of file utils.c.

00802 {
00803     int t;
00804 
00805     t = a / b;
00806     if (t * b != a)
00807         t += 1;
00808 
00809     return t;
00810 }

void write_pid_file void   )  [static]
 

Definition at line 316 of file utils.c.

References file, panic, and pid_file.

Referenced by get_and_set_debugs(), and main().

00317 {
00318     int fd;
00319     FILE *file;
00320 
00321     if (!pid_file)
00322         return;
00323 
00324     fd = open(pid_file, O_WRONLY|O_NOCTTY|O_TRUNC|O_CREAT|O_EXCL, 0644);
00325     if (fd == -1)
00326         panic(errno, "Could not open pid-file `%s'", pid_file);
00327 
00328     file = fdopen(fd, "w");
00329     if (!file)
00330         panic(errno, "Could not open file-stream `%s'", pid_file);
00331 
00332     fprintf(file, "%ld\n", (long) getpid());
00333     fclose(file);
00334 }

int write_variable_value MultibyteInt  value,
Octet dest
 

Definition at line 398 of file utils.c.

References Octet.

Referenced by sema_encode_msg(), sema_submit_result(), and wbmp_create_stream().

00399 {
00400     int i, loc = 0;
00401     Octet revbuffer[20];    /* we write it backwards */
00402     
00403     for (;;) {
00404     revbuffer[loc++] = (value & 0x7F) + 0x80;   
00405     if (value >= 0x80)
00406         value = value >> 7;
00407     else
00408         break;
00409     }
00410     for(i=0; i < loc; i++)      /* reverse the buffer */
00411     dest[i] = revbuffer[loc-i-1];
00412     
00413     dest[loc-1] &= 0x7F;    /* remove trailer-bit from last */
00414 
00415     return loc;
00416 }


Variable Documentation

struct sigaction child_actions[32] [static]
 

Definition at line 86 of file utils.c.

Referenced by parachute_init_signals().

int child_actions_init = 0 [static]
 

Definition at line 88 of file utils.c.

Referenced by parachute_init_signals().

pid_t child_pid = -1 [static]
 

Definition at line 84 of file utils.c.

Referenced by parachute_sig_handler(), parachute_start(), and remove_pid_file().

volatile sig_atomic_t parachute_shutdown = 0 [static]
 

Definition at line 91 of file utils.c.

Referenced by parachute_sig_handler().

char* pid_file = NULL [static]
 

Definition at line 90 of file utils.c.

Referenced by get_and_set_debugs(), remove_pid_file(), and write_pid_file().

See file LICENSE for details about the license agreement for using, modifying, copying or deriving work from this software.