]> jfr.im git - irc/quakenet/newserv.git/blame - nickrate/nickrate.c
Move to package based path
[irc/quakenet/newserv.git] / nickrate / nickrate.c
CommitLineData
c86edd1d
Q
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
17unsigned int nicks;
18unsigned int quits;
19int listenfd;
20
21void nr_nick(int hooknum, void *arg);
22void nr_handlelistensocket(int fd, short events);
23int nr_openlistensocket(int portnum);
24
25void _init() {
26 nicks=0;
27 quits=0;
28 registerhook(HOOK_NICK_NEWNICK, &nr_nick);
29 registerhook(HOOK_NICK_LOSTNICK, &nr_nick);
30
31 listenfd=nr_openlistensocket(6002);
32 if (listenfd>0) {
33 registerhandler(listenfd,POLLIN,&nr_handlelistensocket);
34 }
35
36}
37
38void _fini() {
39 deregisterhook(HOOK_NICK_NEWNICK, &nr_nick);
40 deregisterhook(HOOK_NICK_LOSTNICK, &nr_nick);
41 deregisterhandler(listenfd,1);
42}
43
44void nr_nick(int hooknum, void *arg) {
45 nick *np=(nick *)arg;
46
47 if (serverlist[homeserver(np->numeric)].linkstate == LS_LINKED) {
48 if (hooknum==HOOK_NICK_NEWNICK) {
49 nicks++;
50 } else {
51 quits++;
52 }
53 }
54}
55
56int nr_openlistensocket(int portnum) {
57 struct sockaddr_in sin;
58 int fd;
59 unsigned int opt=1;
60
61 if ((fd=socket(AF_INET,SOCK_STREAM,0))==-1) {
62 Error("proxyscan",ERR_ERROR,"Unable to open listening socket (%d).",errno);
63 return -1;
64 }
65
66 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char *) &opt, sizeof(opt))!=0) {
67 Error("proxyscan",ERR_ERROR,"Unable to set SO_REUSEADDR on listen socket.");
68 return -1;
69 }
70
71 /* Initialiase the addresses */
72 memset(&sin,0,sizeof(sin));
73 sin.sin_family=AF_INET;
74 sin.sin_port=htons(portnum);
75
76 if (bind(fd, (struct sockaddr *) &sin, sizeof(sin))) {
77 Error("proxyscan",ERR_ERROR,"Unable to bind listen socket (%d).",errno);
78 return -1;
79 }
80
81 listen(fd,5);
82
83 if (ioctl(fd, FIONBIO, &opt)!=0) {
84 Error("proxyscan",ERR_ERROR,"Unable to set listen socket non-blocking.");
85 return -1;
86 }
87
88 return fd;
89}
90
91/* Here's what we do when poll throws the listen socket at us:
92 * accept() the connection, spam a short message and immediately
93 * close it again */
94
95void nr_handlelistensocket(int fd, short events) {
96 struct sockaddr_in sin;
97 socklen_t addrsize=sizeof(sin);
98 char buf[20];
99 int newfd;
100 if ((newfd=accept(fd, (struct sockaddr *)&sin, &addrsize))>0) {
101 /* Got new connection */
102 sprintf(buf,"%u\n",nicks);
103 write(newfd,buf,strlen(buf));
104 sprintf(buf,"%u\n",quits);
105 write(newfd,buf,strlen(buf));
106 close(newfd);
107 }
108}