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