]> jfr.im git - irc/quakenet/newserv.git/blob - nickrate/nickrate.c
CHANSERV: tell user when they can't attempts to auth any more, and drop max attempts...
[irc/quakenet/newserv.git] / nickrate / nickrate.c
1 #include "../server/server.h"
2 #include "../core/hooks.h"
3 #include "../core/events.h"
4 #include "../nick/nick.h"
5 #include <sys/poll.h>
6 #include <sys/types.h>
7 #include <sys/socket.h>
8 #include <netdb.h>
9 #include "../core/error.h"
10 #include <stdlib.h>
11 #include <stdio.h>
12 #include <errno.h>
13 #include <sys/ioctl.h>
14 #include <unistd.h>
15 #include <netinet/in.h>
16 #include <string.h>
17 #include "../lib/version.h"
18
19 MODULE_VERSION("")
20
21 unsigned int nicks;
22 unsigned int quits;
23 int nickrate_listenfd;
24
25 void nr_nick(int hooknum, void *arg);
26 void nr_handlelistensocket(int fd, short events);
27 int nr_openlistensocket(int portnum);
28
29 void _init() {
30 nicks=0;
31 quits=0;
32 registerhook(HOOK_NICK_NEWNICK, &nr_nick);
33 registerhook(HOOK_NICK_LOSTNICK, &nr_nick);
34
35 nickrate_listenfd=nr_openlistensocket(6002);
36 if (nickrate_listenfd>0) {
37 registerhandler(nickrate_listenfd,POLLIN,&nr_handlelistensocket);
38 }
39
40 }
41
42 void _fini() {
43 deregisterhook(HOOK_NICK_NEWNICK, &nr_nick);
44 deregisterhook(HOOK_NICK_LOSTNICK, &nr_nick);
45 deregisterhandler(nickrate_listenfd,1);
46 }
47
48 void nr_nick(int hooknum, void *arg) {
49 nick *np=(nick *)arg;
50
51 if (serverlist[homeserver(np->numeric)].linkstate == LS_LINKED) {
52 if (hooknum==HOOK_NICK_NEWNICK) {
53 nicks++;
54 } else {
55 quits++;
56 }
57 }
58 }
59
60 int nr_openlistensocket(int portnum) {
61 struct sockaddr_in sin;
62 int fd;
63 unsigned int opt=1;
64
65 if ((fd=socket(AF_INET,SOCK_STREAM,0))==-1) {
66 Error("proxyscan",ERR_ERROR,"Unable to open listening socket (%d).",errno);
67 return -1;
68 }
69
70 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char *) &opt, sizeof(opt))!=0) {
71 Error("proxyscan",ERR_ERROR,"Unable to set SO_REUSEADDR on listen socket.");
72 return -1;
73 }
74
75 /* Initialiase the addresses */
76 memset(&sin,0,sizeof(sin));
77 sin.sin_family=AF_INET;
78 sin.sin_port=htons(portnum);
79
80 if (bind(fd, (struct sockaddr *) &sin, sizeof(sin))) {
81 Error("proxyscan",ERR_ERROR,"Unable to bind listen socket (%d).",errno);
82 return -1;
83 }
84
85 listen(fd,5);
86
87 if (ioctl(fd, FIONBIO, &opt)!=0) {
88 Error("proxyscan",ERR_ERROR,"Unable to set listen socket non-blocking.");
89 return -1;
90 }
91
92 return fd;
93 }
94
95 /* Here's what we do when poll throws the listen socket at us:
96 * accept() the connection, spam a short message and immediately
97 * close it again */
98
99 void nr_handlelistensocket(int fd, short events) {
100 struct sockaddr_in sin;
101 socklen_t addrsize=sizeof(sin);
102 char buf[20];
103 int newfd;
104 if ((newfd=accept(fd, (struct sockaddr *)&sin, &addrsize))>0) {
105 /* Got new connection */
106 sprintf(buf,"%u\n",nicks);
107 write(newfd,buf,strlen(buf));
108 sprintf(buf,"%u\n",quits);
109 write(newfd,buf,strlen(buf));
110 close(newfd);
111 }
112 }