3 #include "../lib/strlfunc.h"
4 #include "../core/config.h"
5 #include "../core/schedule.h"
6 #include "../localuser/localuser.h"
9 static sstring
*patrol_hostpool
[PATROL_POOLSIZE
], *patrol_tailpool
[PATROL_POOLSIZE
];
10 static unsigned int patrol_hostpoolsize
, patrol_tailpoolsize
;
11 static int patrol_min_hosts
;
12 static char patrol_hostmode
;
14 int patrol_minmaxrand(float min
, float max
) {
15 return (int)((max
- min
+ 1) * rand() / (RAND_MAX
+ min
)) + min
;
18 nick
*patrol_selectuser(void) {
19 int target
= patrol_minmaxrand(0, 500), loops
= 150, j
;
23 for (j
= patrol_minmaxrand(0, NICKHASHSIZE
- 1); j
< NICKHASHSIZE
; j
++)
24 for (np
= nicktable
[j
]; np
; np
= np
->next
)
27 } while (--loops
> 0);
32 host
*patrol_selecthost(void) {
33 int target
= patrol_minmaxrand(0, 500), loops
= 150, j
;
37 for (j
= patrol_minmaxrand(0, HOSTHASHSIZE
- 1); j
< HOSTHASHSIZE
; j
++)
38 for (hp
= hosttable
[j
]; hp
; hp
= hp
->next
)
41 } while (--loops
> 0);
46 int patrol_isip(char *host
) {
47 char *p
= host
, components
= 0, length
= 0;
51 if (((!length
) || (length
= 0)) || (++components
> 3))
54 if ((++length
> 3) || !isdigit(*p
))
59 return components
== 3;
62 static int specialuseronhost(host
*hp
) {
65 for (np
= hp
->nicks
; np
; np
= np
->nextbyhost
)
66 if (IsOper(np
) || IsService(np
) || IsXOper(np
) || NickOnServiceServer(np
))
72 char patrol_genchar(int ty
) {
73 /* hostname and realname characters*/
75 if (!(patrol_minmaxrand(0, 40) % 10)) {
76 return patrol_minmaxrand(48, 57);
78 return patrol_minmaxrand(97, 122);
81 /* ident characters - without numbers*/
83 return patrol_minmaxrand(97, 122);
84 /* ident characters - with numbers*/
86 ty
= patrol_minmaxrand(97, 125);
88 if (ty
> 122) return patrol_minmaxrand(48, 57);
91 /* nick characters - with and without numbers*/
92 } else if (ty
== 3 || ty
== 4) {
93 if (!(patrol_minmaxrand(0, 59) % 16)) {
94 char weirdos
[6] = { '\\', '|', '[', '{', ']', '}' };
95 return weirdos
[patrol_minmaxrand(0, 5)];
99 ty
= patrol_minmaxrand(65, 93);
101 if (ty
> 90) return patrol_minmaxrand(48, 57);
103 ty
= patrol_minmaxrand(65, 90);
106 if (!(patrol_minmaxrand(0, 40) % 8)) return ty
;
115 void patrol_gennick(char *ptc
, char size
) {
118 for (i
= 0; i
< size
; i
++) {
120 ptc
[i
] = patrol_genchar(3);
122 ptc
[i
] = patrol_genchar(4);
129 void patrol_genident(char *ptc
, char size
) {
132 for (i
= 0; i
< size
; i
++) {
134 ptc
[i
] = patrol_genchar(1);
136 ptc
[i
] = patrol_genchar(2);
143 void patrol_genhost(char *ptc
, char size
, struct irc_in_addr
*ipaddress
) {
144 int dots
= patrol_minmaxrand(2, 5), i
, dotexist
= 0, cur
;
147 for (i
= 0; i
< size
; i
++) {
148 ptc
[i
] = patrol_genchar(0);
150 if ((i
> 5) && (i
< (size
- 4))) {
151 if ((ptc
[i
- 1] != '.') && (ptc
[i
- 1] != '-')) {
152 cur
= patrol_minmaxrand(1, size
/ dots
);
169 memset(ipaddress
, 0, sizeof(ipaddress
));
170 ((unsigned short *)(ipaddress
->in6_16
))[5] = 65535;
171 ((unsigned short *)(ipaddress
->in6_16
))[6] = patrol_minmaxrand(0, 65535);
172 ((unsigned short *)(ipaddress
->in6_16
))[7] = patrol_minmaxrand(0, 65535);
175 void patrol_genreal(char *ptc
, char size
) {
176 int spaces
= patrol_minmaxrand(2, 4), i
;
178 for (i
= 0; i
< size
; i
++) {
179 ptc
[i
] = patrol_genchar(0);
181 if ((i
> 5) && (i
< (size
- 4))) {
182 if (ptc
[i
- 1] != ' ') {
183 if (patrol_minmaxrand(1, size
/ spaces
) == 1) ptc
[i
] = ' ';
191 void patrol_generatehost(char *buf
, int maxsize
, struct irc_in_addr
*ipaddress
) {
192 if (PATROL_HOST_MODE
== PATROL_STEAL_HOST
) {
199 hp
= patrol_selecthost();
201 if (hp
&& (hp
->clonecount
<= PATROL_MAX_CLONE_COUNT
) && !patrol_isip(hp
->name
->content
) && !specialuseronhost(hp
)) {
202 strlcpy(buf
, hp
->name
->content
, maxsize
+ 1);
205 memcpy(ipaddress
, &hp
->nicks
->ipaddress
, sizeof(struct irc_in_addr
));
207 memset(ipaddress
, 0, sizeof(struct irc_in_addr
));
208 ((unsigned short *)(ipaddress
->in6_16
))[5] = 65535;
209 ((unsigned short *)(ipaddress
->in6_16
))[6] = patrol_minmaxrand(0, 65535);
210 ((unsigned short *)(ipaddress
->in6_16
))[7] = patrol_minmaxrand(0, 65535);
215 } while (--loops
> 0);
218 int pieces
= patrol_minmaxrand(2, 4), totallen
= 0, a
= 0, i
;
219 int *choices
= malloc(sizeof(int) * (pieces
+ 1));
220 int *lengths
= malloc(sizeof(int) * (pieces
+ 1));
222 choices
[pieces
] = patrol_minmaxrand(0, patrol_tailpoolsize
- 1);
223 lengths
[pieces
] = strlen(patrol_tailpool
[choices
[pieces
]]->content
) + 1;
224 totallen
+= lengths
[pieces
];
226 for (i
= 0; i
< pieces
; i
++) {
227 choices
[i
] = patrol_minmaxrand(0, patrol_hostpoolsize
- 1);
228 lengths
[i
] = strlen(patrol_hostpool
[choices
[i
]]->content
) + 1;
230 if (totallen
+ lengths
[i
] > maxsize
) {
231 choices
[i
] = choices
[pieces
];
232 lengths
[i
] = lengths
[pieces
];
233 pieces
-= (pieces
- i
);
237 totallen
+= lengths
[i
];
240 for (i
= 0; i
< pieces
; i
++) {
241 for (cpos
= patrol_hostpool
[choices
[i
]]->content
; *cpos
;)
247 for (cpos
= patrol_tailpool
[choices
[i
]]->content
; *cpos
;) {
255 memset(ipaddress
, 0, sizeof(struct irc_in_addr
));
256 ((unsigned short *)(ipaddress
->in6_16
))[5] = 65535;
257 ((unsigned short *)(ipaddress
->in6_16
))[6] = patrol_minmaxrand(0, 65535);
258 ((unsigned short *)(ipaddress
->in6_16
))[7] = patrol_minmaxrand(0, 65535);
262 void patrol_generatenick(char *buf
, int maxsize
) {
263 int bits
= patrol_minmaxrand(2, 3), loops
= 0, wanttocopy
, len
= 0, i
, d
= 0, newmaxsize
= maxsize
- patrol_minmaxrand(0, 7);
267 maxsize
= newmaxsize
;
270 np
= patrol_selectuser();
273 wanttocopy
= patrol_minmaxrand(1, (strlen(np
->nick
) / 2) + 3);
275 for (i
= 0; ((i
< wanttocopy
) && (len
< maxsize
)); i
++)
276 buf
[len
++] = np
->nick
[i
];
283 } while (++loops
< 10);
288 void patrol_generateident(char *buf
, int maxsize
) {
289 nick
*np
= patrol_selectuser();
293 strlcpy(buf
, np
->ident
, maxsize
+ 1);
296 void patrol_generaterealname(char *buf
, int maxsize
) {
297 nick
*np
= patrol_selectuser();
301 strlcpy(buf
, np
->realname
->name
->content
, maxsize
+ 1);
304 nick
*patrol_generateclone(int extraumodes
, UserMessageHandler handler
) {
305 int loops
= 0, modes
= UMODE_XOPER
| UMODE_INV
| extraumodes
;
306 char c_nick
[NICKLEN
+ 1], c_ident
[USERLEN
+ 1], c_host
[HOSTLEN
+ 1], c_real
[REALLEN
+ 1];
307 struct irc_in_addr ipaddress
;
309 /* PPA: unlikely to be infinite */
313 if (!loops
&& patrol_hostmode
) /* only have one go at this */
314 patrol_generatenick(c_nick
, NICKLEN
);
317 patrol_gennick(c_nick
, patrol_minmaxrand(7, PATROL_MMIN(13, NICKLEN
)));
320 } while ((getnickbynick(c_nick
) != NULL
));
322 patrol_generateident(c_ident
, USERLEN
);
325 patrol_genident(c_ident
, patrol_minmaxrand(4, PATROL_MMIN(8, USERLEN
)));
327 if (patrol_hostmode
) {
328 patrol_generatehost(c_host
, HOSTLEN
, &ipaddress
);
331 patrol_genhost(c_host
, HOSTLEN
, &ipaddress
);
333 patrol_genhost(c_host
, HOSTLEN
, &ipaddress
);
336 patrol_generaterealname(c_real
, REALLEN
);
339 patrol_genreal(c_real
, patrol_minmaxrand(15, PATROL_MMIN(50, REALLEN
)));
341 return registerlocaluserflagsip(c_nick
, c_ident
, c_host
, c_real
, NULL
, 0, 0, modes
, &ipaddress
, handler
);
344 void patrol_nickchange(nick
*np
) {
345 char c_nick
[NICKLEN
+ 1];
348 /* PPA: unlikely to be infinite */
350 if ((loops
++ < 10) && patrol_hostmode
) {
351 patrol_generatenick(c_nick
, NICKLEN
);
353 patrol_gennick(c_nick
, patrol_minmaxrand(7, PATROL_MMIN(13, NICKLEN
)));
355 } while (c_nick
[0] && (getnickbynick(c_nick
) != NULL
));
357 renamelocaluser(np
, c_nick
);
360 int patrol_is_not_octet(char *begin
, int length
) {
366 for (i
= 0; i
< length
; i
++) {
367 if (!((*begin
>= '0') && (*begin
<= '9')))
376 int patrol_generatepool(void) {
377 int i
, k
= 0, j
= 0, loops
= 0;
381 for (i
= 0; i
< NICKHASHSIZE
; i
++)
382 for (np
= nicktable
[i
]; np
; np
= np
->next
)
385 if (j
< patrol_min_hosts
)
388 if (PATROL_HOST_MODE
== PATROL_STEAL_HOST
)
389 return PATROL_MINPOOLSIZE
;
394 for (j
= patrol_minmaxrand(0, NICKHASHSIZE
- 1); j
< NICKHASHSIZE
; j
++) {
396 for (p
= nicktable
[j
]->host
->name
->content
, pp
= p
; *p
;) {
398 if (!patrol_is_not_octet(pp
, p
- pp
)) {
399 if (i
< PATROL_POOLSIZE
) {
400 if (i
< patrol_hostpoolsize
)
401 freesstring(patrol_hostpool
[i
]);
403 patrol_hostpool
[i
] = getsstring(pp
, p
- pp
);
406 if (k
>= PATROL_POOLSIZE
)
415 if (!patrol_is_not_octet(pp
, p
- pp
)) {
416 if (k
< PATROL_POOLSIZE
) {
417 if (k
< patrol_tailpoolsize
)
418 freesstring(patrol_tailpool
[k
]);
420 patrol_tailpool
[k
] = getsstring(pp
, p
- pp
);
423 if (i
>= PATROL_POOLSIZE
)
431 } while ((loops
< 5) && ((i
< PATROL_POOLSIZE
) || (k
< PATROL_POOLSIZE
)));
433 patrol_hostpoolsize
= i
;
434 patrol_tailpoolsize
= k
;
438 int patrol_repool(void) {
439 if (patrol_generatepool() < PATROL_MINPOOLSIZE
) {
448 void patrol_sched_repool(void *arg
) {
452 delta
= PATROL_POOL_REGENERATION
;
456 scheduleoneshot(time(NULL
) + delta
, &patrol_sched_repool
, NULL
);
463 snprintf(buf
, sizeof(buf
), "%d", PATROL_MINIMUM_HOSTS_BEFORE_POOL
);
464 m
= getcopyconfigitem("patrol", "minpoolhosts", buf
, 32);
465 patrol_min_hosts
= atoi(m
->content
);
468 scheduleoneshot(time(NULL
) + 5, &patrol_sched_repool
, NULL
);
474 deleteallschedules(&patrol_sched_repool
);
476 for (i
= 0; i
< patrol_hostpoolsize
; i
++)
477 freesstring(patrol_hostpool
[i
]);
479 for (i
= 0; i
< patrol_tailpoolsize
; i
++)
480 freesstring(patrol_tailpool
[i
]);