utils.c
上传用户:gzpyjq
上传日期:2013-01-31
资源大小:1852k
文件大小:9k
源码类别:

手机WAP编程

开发平台:

WINDOWS

  1. /*
  2.  * utils.c - generally useful, non-application specific functions for Gateway
  3.  *
  4.  */
  5. #include <ctype.h>
  6. #include <errno.h>
  7. #include <stdarg.h>
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <string.h>
  11. #include <time.h>
  12. #include <unistd.h>
  13. #include <termios.h>
  14. #include "gwlib.h"
  15. /*
  16.  * new datatype functions
  17.  */
  18. MultibyteInt get_variable_value(Octet *source, int *len)
  19. {
  20.     MultibyteInt retval = 0;
  21.     
  22.     for(*len=1;; (*len)++, source++) {
  23. retval = retval * 0x80 + (*source & 0x7F);
  24. if (*source < 0x80)  /* if the continue-bit (high bit) is not set */
  25.     break;
  26.     }
  27.     return retval;
  28. }
  29. int write_variable_value(MultibyteInt value, Octet *dest)
  30. {
  31.     int i, loc = 0;
  32.     Octet revbuffer[20]; /* we write it backwards */
  33.     
  34.     for (;;) {
  35. revbuffer[loc++] = (value & 0x7F) + 0x80;
  36. if (value >= 0x80)
  37.     value = value >> 7;
  38. else
  39.     break;
  40.     }
  41.     for(i=0; i < loc; i++) /* reverse the buffer */
  42. dest[i] = revbuffer[loc-i-1];
  43.     
  44.     dest[loc-1] &= 0x7F; /* remove trailer-bit from last */
  45.     return loc;
  46. }
  47. Octet reverse_octet(Octet source)
  48. {
  49.     Octet dest;
  50.     dest = (source & 1) <<7;
  51.     dest += (source & 2) <<5;
  52.     dest += (source & 4) <<3;
  53.     dest += (source & 8) <<1;
  54.     dest += (source & 16) >>1;
  55.     dest += (source & 32) >>3;
  56.     dest += (source & 64) >>5;
  57.     dest += (source & 128) >>7;
  58.     
  59.     return dest;
  60. }
  61. int get_and_set_debugs(int argc, char **argv,
  62.        int (*find_own) (int index, int argc, char **argv))
  63. {
  64.     int i, ret = -1;
  65.     int debug_lvl = -1;
  66.     int file_lvl = GW_DEBUG;
  67.     char *log_file = NULL;
  68.     char *debug_places = NULL;
  69.     
  70.     for(i=1; i < argc; i++) {
  71. if (strcmp(argv[i],"-v")==0 ||
  72.     strcmp(argv[i],"--verbosity")==0) {
  73.     if (i+1 < argc) {
  74. debug_lvl = atoi(argv[i+1]);
  75. i++;
  76.     } else
  77. fprintf(stderr, "Missing argument for option %sn", argv[i]); 
  78. } else if (strcmp(argv[i],"-F")==0 ||
  79.    strcmp(argv[i],"--logfile")==0) {
  80.     if (i+1 < argc && *(argv[i+1]) != '-') {
  81. log_file = argv[i+1];
  82. i++;
  83.     } else
  84. fprintf(stderr, "Missing argument for option %sn", argv[i]); 
  85. } else if (strcmp(argv[i],"-V")==0 ||
  86.    strcmp(argv[i],"--fileverbosity")==0) {
  87.     if (i+1 < argc) {
  88. file_lvl = atoi(argv[i+1]);
  89. i++;
  90.     } else
  91. fprintf(stderr, "Missing argument for option %sn", argv[i]); 
  92. } else if (strcmp(argv[i],"-D")==0 ||
  93.    strcmp(argv[i],"--debug")==0) {
  94.     if (i+1 < argc) {
  95. debug_places = argv[i+1];
  96. i++;
  97.     } else
  98. fprintf(stderr, "Missing argument for option %sn", argv[i]); 
  99. } else if (strcmp(argv[i],"--")==0) {
  100.     i++;
  101.     break;
  102. } else if(*argv[i] != '-') {
  103.     break;
  104. } else {
  105.     if (find_own != NULL) {
  106. ret = find_own(i, argc, argv);
  107.     }
  108.     if (ret < 0) {
  109. fprintf(stderr, "Unknown option %s, exiting.n", argv[i]);
  110. panic(0, "Option parsing failed");
  111.     }
  112.     else
  113. i += ret; /* advance additional args */
  114. }
  115.     }
  116.     if (debug_lvl > -1)
  117. log_set_output_level(debug_lvl);
  118.     if (debug_places != NULL)
  119.         log_set_debug_places(debug_places);
  120.     if (log_file != NULL)
  121. log_open(log_file, file_lvl);
  122.     info(0, "Debug_lvl = %d, log_file = %s, log_lvl = %d",
  123.   debug_lvl, log_file ? log_file : "<none>", file_lvl);
  124.     if (debug_places != NULL)
  125.     info(0, "Debug places: `%s'", debug_places);
  126.     
  127.     return i;
  128. }
  129. static int pattern_matches_ip(Octstr *pattern, Octstr *ip)
  130. {
  131.     long i, j;
  132.     long pat_len, ip_len;
  133.     int pat_c, ip_c;
  134.     
  135.     pat_len = octstr_len(pattern);
  136.     ip_len = octstr_len(ip);
  137.     i = 0;
  138.     j = 0;
  139.     while (i < pat_len && j < ip_len) {
  140. pat_c = octstr_get_char(pattern, i);
  141. ip_c = octstr_get_char(ip, j);
  142. if (pat_c == ip_c) {
  143.     /* The characters match, go to the next ones. */
  144.     ++i;
  145.     ++j;
  146. } else if (pat_c != '*') {
  147.     /* They differ, and the pattern isn't a wildcard one. */
  148.     return 0;
  149. } else {
  150.     /* We found a wildcard in the pattern. Skip in ip. */
  151.     ++i;
  152.     while (j < ip_len && ip_c != '.') {
  153. ++j;
  154. ip_c = octstr_get_char(ip, j);
  155.     }
  156. }
  157.     }
  158.     
  159.     if (i >= pat_len && j >= ip_len)
  160.      return 1;
  161.     return 0;
  162. }
  163. static int pattern_list_matches_ip(Octstr *pattern_list, Octstr *ip)
  164. {
  165.     List *patterns;
  166.     Octstr *pattern;
  167.     int matches;
  168.     patterns = octstr_split(pattern_list, octstr_imm(";"));
  169.     matches = 0;
  170.     while (!matches && (pattern = list_extract_first(patterns)) != NULL) {
  171. matches = pattern_matches_ip(pattern, ip);
  172. octstr_destroy(pattern);
  173.     }
  174.     
  175.     list_destroy(patterns, octstr_destroy_item);
  176.     return matches;
  177. }
  178. int is_allowed_ip(Octstr *allow_ip, Octstr *deny_ip, Octstr *ip)
  179. {
  180.     if (ip == NULL)
  181. return 0;
  182.     if (octstr_len(deny_ip) == 0)
  183. return 1;
  184.     if (allow_ip != NULL && pattern_list_matches_ip(allow_ip, ip))
  185. return 1;
  186.     if (pattern_list_matches_ip(deny_ip, ip))
  187.      return 0;
  188.     return 1;
  189. }
  190. int connect_denied(Octstr *allow_ip, Octstr *ip)
  191. {
  192.     if (ip == NULL)
  193. return 1;
  194.     /* If IP not set, allow from Localhost */
  195.     if (allow_ip == NULL) { 
  196. if (pattern_list_matches_ip(octstr_imm("127.0.0.1"), ip))
  197.     return 0;
  198.     } else {
  199. if (pattern_list_matches_ip(allow_ip, ip))
  200.     return 0;
  201.     }
  202.     return 1;
  203. }
  204. int does_prefix_match(Octstr *prefix, Octstr *number)
  205. {
  206.     /* XXX modify to use just octstr operations
  207.      */
  208.     char *b, *p, *n;
  209.     gw_assert(prefix != NULL);
  210.     gw_assert(number != NULL);
  211.     p = octstr_get_cstr(prefix);
  212.     n = octstr_get_cstr(number);
  213.     
  214.     while (*p != '') {
  215.         b = n;
  216.         for (b = n; *b != ''; b++, p++) {
  217.             if (*p == ';' || *p == '') {
  218.                 return 1;
  219.             }
  220.             if (*p != *b) break;
  221.         }
  222.         if (*p == ';' || *p == '') {
  223.             return 1;
  224.         }
  225.         while (*p != '' && *p != ';')
  226.             p++;
  227.         while (*p == ';') p++;
  228.     }
  229.     return 0;
  230. }
  231. int normalize_number(char *dial_prefixes, Octstr **number)
  232. {
  233.     char *t, *p, *official, *start;
  234.     int len, official_len;
  235.     
  236.     if (dial_prefixes == NULL || dial_prefixes[0] == '')
  237.         return 0;
  238.     t = official = dial_prefixes;
  239.     official_len = 0;
  240.     gw_assert(number != NULL);
  241.     
  242.     while(1) {
  243.      p = octstr_get_cstr(*number);
  244.         for(start = t, len = 0; ; t++, p++, len++)
  245. {
  246.             if (*t == ',' || *t == ';' || *t == '') {
  247.                 if (start != official) {
  248.                     Octstr *nstr;
  249.     long n;
  250.     
  251.     if ( official[0] == '-' ) official_len=0;
  252.     n = official_len;
  253.     if (strlen(official) < (size_t) n)
  254.      n = strlen(official);
  255.                     nstr = octstr_create_from_data(official, n);
  256.                     octstr_insert_data(nstr, official_len,
  257.                                            octstr_get_cstr(*number) + len,
  258.                                            octstr_len(*number) - len);
  259.                     octstr_destroy(*number);
  260.                     *number = nstr;
  261.                 }
  262.                 return 1;
  263.             }
  264.             if (*p == '' || *t != *p)
  265.                 break;          /* not matching */
  266.         }
  267.         for(; *t != ',' && *t != ';' && *t != ''; t++, len++)
  268.             ;
  269.         if (*t == '') break;
  270.         if (start == official) official_len = len;
  271.         if (*t == ';') official = t+1;
  272.         t++;
  273.     }
  274.     return 0;
  275. }
  276. long decode_network_long(unsigned char *data) {
  277.         return (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];
  278. }
  279. void encode_network_long(unsigned char *data, unsigned long value) {
  280.         data[0] = (value >> 24) & 0xff;
  281.         data[1] = (value >> 16) & 0xff;
  282.         data[2] = (value >> 8) & 0xff;
  283.         data[3] = value & 0xff;
  284. }
  285. /* Something that does the same as GNU cfmakeraw. We don't use cfmakeraw
  286.    so that we always know what it does, and also to reduce configure.in
  287.    complexity. */
  288. void kannel_cfmakeraw (struct termios *tio){
  289.     /* Block until a charactor is available, but it only needs to be one*/
  290.     tio->c_cc[VMIN]    = 1;
  291.     tio->c_cc[VTIME]   = 0;
  292.     /* GNU cfmakeraw sets these flags so we had better too...*/
  293.     /* Control modes */
  294.     /* Mask out character size (CSIZE), then set it to 8 bits (CS8).
  295.      * Enable parity bit generation in both directions (PARENB).
  296.      */
  297.     tio->c_cflag      &= ~(CSIZE|PARENB);
  298.     tio->c_cflag      |= CS8;
  299.     /* Input Flags,*/
  300.     /* Turn off all input flags that interfere with the byte stream:
  301.      * BRKINT - generate SIGINT when receiving BREAK, ICRNL - translate
  302.      * NL to CR, IGNCR - ignore CR, IGNBRK - ignore BREAK,
  303.      * INLCR - translate NL to CR, IXON - use XON/XOFF flow control,
  304.      * ISTRIP - strip off eighth bit.
  305.      */
  306.     tio->c_iflag &= ~(BRKINT|ICRNL|IGNCR|IGNBRK|INLCR|IXON|ISTRIP);
  307.     /* Other flags,*/
  308.     /* Turn off all local flags that interpret the byte stream:
  309.      * ECHO - echo input chars, ECHONL - always echo NL even if ECHO is off,
  310.      * ICANON - enable canonical mode (basically line-oriented mode),
  311.      * IEXTEN - enable implementation-defined input processing,
  312.      * ISIG - generate signals when certain characters are received. */
  313.     tio->c_lflag      &= ~(ECHO|ECHONL|ICANON|IEXTEN|ISIG);
  314.     /* Output flags,*/
  315.     /* Disable implementation defined processing on the output stream*/
  316.     tio->c_oflag      &= ~OPOST;
  317. }
  318. int gw_isdigit(int c)
  319. {
  320.     return isdigit(c);
  321. }
  322. int gw_isxdigit(int c)
  323. {
  324.     return isxdigit(c);
  325. }
  326. /* Rounds up the result of a division */
  327. int roundup_div(int a, int b)
  328. {
  329.     int t;
  330.     t = a / b;
  331.     if (t * b != a)
  332. t += 1;
  333.     return t;
  334. }