added ChanUser.c and basic cache system
[NeonServV5.git] / ChanNode.c
1 #include "ChanNode.h"
2
3 static struct ChanNode **chanList;
4
5 void init_ChanNode() {
6     /*
7      len pos chars 
8      26  0   a-z
9      10  26  0-9
10      10  36  {|}~[\]^_`
11      1   46  *everything else*
12      ---------------------------
13      = 47
14     */
15     chanList = calloc(47, sizeof(*chanList));
16 }
17
18 int is_valid_chan(const char *name) {
19     unsigned int ii;
20     if (*name !='#')
21         return 0;
22     for (ii=1; name[ii]; ++ii) {
23         if ((name[ii] > 0) && (name[ii] <= 32))
24             return 0;
25         if (name[ii] == ',')
26             return 0;
27         if (name[ii] == '\xa0')
28             return 0;
29     }
30     return 1;
31 }
32
33 static int get_chanlist_entry(int name) {
34     if((name > 0 && name <= 32) || name == ',' || name == '\xa0') return -1; //invalid name
35     if(tolower(name) >= 97 && tolower(name) <= 122) {
36         return (tolower(name) - 97);
37     }
38     if(tolower(name) >= 48 && tolower(name) <= 57) {
39         return (tolower(name) - 48 + 26);
40     }
41     /* {|}~[\]^_` */
42     if(name == '{') return 36;
43     if(name == '|') return 37;
44     if(name == '}') return 38;
45     if(name == '~') return 39;
46     if(name == '[') return 40;
47     if(name == '\\') return 41;
48     if(name == ']') return 42;
49     if(name == '^') return 43;
50     if(name == '_') return 44;
51     if(name == '`') return 45;
52     return 46;
53 }
54
55 struct ChanNode* getChanByName(const char *name) { //case insensitive
56     int chanListIndex = get_chanlist_entry(name[1]);
57     if(chanListIndex == -1 || chanList[chanListIndex] == NULL)
58         return NULL;
59     struct ChanNode *chan;
60     for(chan = chanList[chanListIndex]; chan; chan = chan->next) {
61         if(!stricmp(name, chan->name))
62             return chan;
63     }
64     return NULL;
65 }
66
67 struct ChanNode* addChannel(const char *name) {
68     int chanListIndex = get_chanlist_entry(name[1]);
69     if(chanListIndex == -1 || !is_valid_chan(name))
70         return NULL;
71     struct ChanNode *chan = malloc(sizeof(*chan));
72     if (!chan)
73     {
74         perror("malloc() failed");
75         return NULL;
76     }
77     strcpy(chan->name, name);
78     chan->user = NULL;
79     chan->topic[0] = 0;
80     chan->flags = 0;
81     chan->next = chanList[chanListIndex];
82     chanList[chanListIndex] = chan;
83     return chan;
84 }
85
86 void delChannel(struct ChanNode* chan, int freeChan) {
87     int chanListIndex = get_chanlist_entry(chan->name[1]);
88     if(chanListIndex == -1) return;
89     struct ChanNode *cchan, *last_chan = NULL;
90     for(cchan = chanList[chanListIndex]; cchan; cchan = cchan->next) {
91         if(cchan == chan) {
92             if(last_chan)
93                 last_chan->next = chan->next;
94             else
95                 chanList[chanListIndex] = chan->next;
96             break;
97         } else
98             last_chan = cchan;
99     }
100     if(freeChan)
101         free(chan);
102     else
103         chan->next = NULL;
104 }