aboutsummaryrefslogtreecommitdiff
path: root/src/util.c
blob: 79a3cee0f2d353e5edbf2b4b158a0389e8890e30 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#include "util.h"
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include "lua.h"
#include "net.h"

/*
 simple function to parse key=value; strings which are common in http headers
 values may be null, because these strings can often just be a key such as
 content-type: multipart/form-data; boundary=awa
 will set the table to
 multipart/form-data = (null)
 boundary = awa
*/
int gen_parse(char* inp, int len, parray_t** _table){
  str* current = str_init(""), *last = NULL;
  int state = 0; 

  parray_t* table = *_table;
  for(int i = 0; i < len; i++){

    if(state != 1 && inp[i] == ';'){
      //if(last != NULL){
      if(last == NULL) swap(str*, current, last);
      parray_set(table, last->c, (void*)current);
      str_free(last);
      //}
      last = NULL;
      current = str_init("");
      state = 0;
    } else if(state != 1 && inp[i] == '='){
      last = current;
      current = str_init("");
      if(i + 1 < len && inp[i+1] == '"'){
        state = 1;
        i++;
      }
    } else if(state == 1 && inp[i] == '"'){
      state = 0;
    } else if(current->c[0] != '\0' || inp[i] != ' ') str_pushl(current, inp + i, 1);
  }

  if(current->len > 0){
    if(last == NULL) swap(str*, current, last);
    parray_set(table, last->c, (void*)current);
    str_free(last);
  }
  *_table = table;
  return 1;
}

int tolower(int i){
  if('A' <= i && i <= 'Z') i += 32;
  return i;
}

void str_lowercase(str* str){
  for(size_t i = 0; i != str->len; i++){
    str->c[i] = tolower(str->c[i]);
  }
}

char* strnstr(const char *s1, const char *s2, size_t n) {
  // simplistic algorithm with O(n2) worst case, stolen from stack overflow
  size_t i, len;
  char c = *s2;

  if(c == '\0')
    return (char *)s1;

  for(len = strlen(s2); len <= n; n--, s1++){
    if(*s1 == c){
      for(i = 1;; i++){
        if(i == len) return (char *)s1;
        if(s1[i] != s2[i]) break;
      }
    }
  }
  return NULL;
}

void _p_fatal(const char* m, int line, const char* file, const char* function){
  fprintf(stderr, "%s[fatal] %s \n"
      "\tthread: %zu\n"
      "\tat: %s:%s(%i) %s\n",color_red, m, pthread_self(), file, function, line, color_reset);
  exit(EXIT_FAILURE);
}

void p_error(const char* m){
  fprintf(stderr, "%s[error]%s %s\n",color_red, color_reset, m);
}