-
Notifications
You must be signed in to change notification settings - Fork 0
/
util.c
156 lines (129 loc) · 2.62 KB
/
util.c
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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include "util.h"
void *util_dup(const void *src, size_t len)
{
void *new = malloc(len);
if(!new)
return NULL;
return (void *)memcpy(new, src, len);
}
char *util_strdup(const char *src)
{
size_t len = strlen(src) + 1;
return (char *)util_dup(src, len);
}
void util_strncpy(char *dst, const char *src, size_t dstsz)
{
if(!dstsz)
return;
while(dstsz--)
if(!(*dst++ = *src++))
return;
dst[-1] = '\0';
}
int util_clamp(int val, int min, int max)
{
if(val < min)
return min;
if(val > max)
return max;
return val;
}
void util_randstr(char *buf, size_t len, const char *alphabet)
{
int alphalen = strlen(alphabet);
while(len--)
*buf++=alphabet[rand()%alphalen];
*buf = '\0';
}
int util_tokenize(char *buf, char **tokarr, size_t toksize)
{
if(buf[0] == ' ') //Cant begin with whitespace
return 0;
int ntok = 0;
while(*buf && ntok < toksize){
tokarr[ntok++] = buf;
if(ntok > 1 && *buf == ':')
break;
while(*buf && *buf != ' ') buf++;
if(!*buf)
break;
*buf++ = '\0';
while(*buf && *buf == ' ') buf++;
}
return ntok;
}
struct irc_message util_irc_message_parse(char *msg)
{
struct irc_message r;
for(int i = 0; i < MAX_TOKENS; i++)
r.tokarr[i] = NULL;
r.ntok = util_tokenize(msg, r.tokarr, COUNT_OF(r.tokarr));
if(r.tokarr[0][0] == ':')
r.prefix = util_irc_prefix_parse(r.tokarr[0]);
else{
r.prefix.nick = NULL;
r.prefix.user = NULL;
r.prefix.host = NULL;
}
r.cmd = (r.prefix.nick) ? 1 : 0;
r.middle = r.cmd + 1;
r.trailing = (r.tokarr[r.ntok - 1][0] == ':') ? r.ntok - 1 : -1;
if(r.trailing)
r.tokarr[r.trailing]++;
return r;
}
struct irc_prefix util_irc_prefix_parse(char *prefix)
{
struct irc_prefix p;
char *t = strchr(prefix, '@');
if(t){
*t = '\0';
p.host = t + 1;
}
else
p.host = NULL;
t = strchr(prefix, '!');
if(t){
*t = '\0';
p.user = t + 1;
}
else
p.user = NULL;
p.nick = prefix;
return p;
}
void util_irc_prefix_construct(char *buf, size_t bufsz, struct irc_prefix p)
{
snprintf(buf, bufsz, "%s!%s@%s", p.nick, p.user, p.host);
}
void util_parse_hostspec(char *host, size_t sz, int *port, bool *ssl, const char *hostspec)
{
if(hostspec[0] == '!')
*ssl = true;
char *sep = strchr(hostspec, ':');
if(sep)
*sep = '\0';
util_strncpy(host, hostspec, sz);
if(sep)
*port = strtol(sep + 1, NULL, 10);
else
*port = 6667;
}
void util_mkdir_r(char *path)
{
char buf[2048];
util_strncpy(buf, path, sizeof buf);
for(char *p = buf + 1; *p != '\0'; p++)
{
if(*p == '/' && *(p+1) != '\0')
{
*p = '\0';
mkdir(buf, 0755);
*p = '/';
}
}
}