]> jfr.im git - irc/quakenet/newserv.git/blame - glines/glines_formats.c
BUILD: add require-all build mode
[irc/quakenet/newserv.git] / glines / glines_formats.c
CommitLineData
c60d02ed
GB
1#include <stdio.h>
2#include <string.h>
3#include <assert.h>
4#include "../lib/irc_string.h"
5#include "../lib/version.h"
6#include "../core/schedule.h"
7#include "../irc/irc.h"
8#include "../trusts/trusts.h"
9#include "../control/control.h"
10#include "glines.h"
11
923bc30c
GB
12/** Find canonical user and host for a string.
13 * If \a userhost starts with '$', assign \a userhost to *user_p and NULL to *host_p.
14 * Otherwise, if \a userhost contains '@', assign the earlier part of it to *user_p and the rest to *host_p.
15 * Otherwise, assign \a def_user to *user_p and \a userhost to *host_p.
16 *
17 * @param[in] userhost Input string from user.
18 * @param[out] nick_p Gets pointer to nick part of hostmask.
19 * @param[out] user_p Gets pointer to user (or channel/realname) part of hostmask.
20 * @param[out] host_p Gets point to host part of hostmask (may be assigned NULL).
21 * @param[in] def_user Default value for user part.
22 */
23static void
24canon_userhost(char *userhost, char **nick_p, char **user_p, char **host_p, char *def_user) {
25 char *tmp, *s;
26
27 if (*userhost == '$') {
28 *user_p = userhost;
29 *host_p = NULL;
30 *nick_p = NULL;
31 return;
32 }
33
34 if ((tmp = strchr(userhost, '!'))) {
35 *nick_p = userhost;
36 *(tmp++) = '\0';
37 } else {
38 *nick_p = def_user;
39 tmp = userhost;
40 }
41
42 if (!(s = strchr(tmp, '@'))) {
43 *user_p = def_user;
44 *host_p = tmp;
45 } else {
46 *user_p = tmp;
47 *(s++) = '\0';
48 *host_p = s;
49 }
50}
51
c60d02ed
GB
52gline *makegline(const char *mask) {
53 /* populate gl-> user,host,node,nick and set appropriate flags */
54 gline *gl;
923bc30c
GB
55 char dupmask[512];
56 char *nick, *user, *host;
27a53417
GB
57 const char *pos;
58 int count;
c60d02ed 59
923bc30c 60 /* Make sure there are no spaces in the mask */
c60d02ed
GB
61 if (strchr(mask, ' ') != NULL)
62 return NULL;
63
64 gl = newgline();
65
66 if (!gl) {
67 Error("gline", ERR_ERROR, "Failed to allocate new gline");
68 return NULL;
69 }
923bc30c 70
a86fc0c4 71 if (mask[0] == '#' || mask[0] == '&') {
c60d02ed
GB
72 gl->flags |= GLINE_BADCHAN;
73 gl->user = getsstring(mask, CHANNELLEN);
74 return gl;
75 }
76
a86fc0c4 77 if (mask[0] == '$') {
c60d02ed
GB
78 if (mask[1] != 'R') {
79 freegline(gl);
80 return NULL;
81 }
82
83 gl->flags |= GLINE_REALNAME;
f1165f9d
GB
84
85 if (strcmp(mask + 2, "*") != 0)
86 gl->user = getsstring(mask + 2, REALLEN);
87
c60d02ed
GB
88 return gl;
89 }
90
923bc30c
GB
91 strncpy(dupmask, mask, sizeof(dupmask));
92 canon_userhost(dupmask, &nick, &user, &host, "*");
c60d02ed 93
923bc30c 94 if (ipmask_parse(host, &gl->ip, &gl->bits))
c60d02ed
GB
95 gl->flags |= GLINE_IPMASK;
96 else
97 gl->flags |= GLINE_HOSTMASK;
98
923bc30c
GB
99 /* Don't allow invalid IPv6 bans as those might match * on snircd 1.3.4 */
100 count = 0;
27a53417 101
923bc30c
GB
102 for (pos = host; *pos; pos++)
103 if (*pos == ':')
104 count++;
27a53417 105
923bc30c 106 if (count >= 8) {
4e52c61d 107 controlwall(NO_OPER, NL_GLINES_AUTO, "Warning: Parsed invalid IPv6 G-Line: %s", mask);
923bc30c
GB
108 freegline(gl);
109 return NULL;
27a53417
GB
110 }
111
923bc30c
GB
112 if (strcmp(nick, "*") != 0)
113 gl->nick = getsstring(nick, 512);
c60d02ed 114
923bc30c
GB
115 if (strcmp(user, "*") != 0)
116 gl->user = getsstring(user, 512);
c60d02ed 117
923bc30c
GB
118 if (strcmp(host, "*") != 0)
119 gl->host = getsstring(host, 512);
c60d02ed
GB
120
121 return gl;
122}
123
124char *glinetostring(gline *gl) {
125 static char mask[512]; /* check */
126
127 if (gl->flags & GLINE_REALNAME) {
f1165f9d 128 snprintf(mask, sizeof(mask), "$R%s", (gl->user) ? gl->user->content : "*");
c60d02ed
GB
129 return mask;
130 }
131
132 if (gl->flags & GLINE_BADCHAN) {
133 assert(gl->user);
134
135 strncpy(mask, gl->user->content, sizeof(mask));
136 return mask;
137 }
138
139 snprintf(mask, sizeof(mask), "%s!%s@%s",
140 gl->nick ? gl->nick->content : "*",
141 gl->user ? gl->user->content : "*",
142 gl->host ? gl->host->content : "*");
143
144 return mask;
145}
146