]>
jfr.im git - irc/quakenet/newserv.git/blob - lpart/lpart.c
2 * lpart: simple newserv module to instruct L to leave a channel
3 * after it has had no other users for a certain time.
6 #include "../lib/sstring.h"
7 #include "../channel/channel.h"
8 #include "../core/config.h"
9 #include "../core/hooks.h"
10 #include "../nick/nick.h"
11 #include "../core/schedule.h"
12 #include "../control/control.h"
13 #include "../core/error.h"
15 sstring
*targetnick
; /* Name of the service to talk to */
16 int lpartext
; /* Our chanext index */
17 int timeout
; /* How long to wait for */
18 int shorttimeout
; /* How long to wait if there are no interesting modes */
20 void lp_handlepart(int hooknum
, void *arg
);
21 void lp_dopart(void *arg
);
22 void lp_schedpart(channel
*cp
);
30 lpartext
=registerchanext("lpart");
32 /* Set up the targetnick */
33 targetnick
=getcopyconfigitem("lpart","servicenick","L",NICKLEN
);
35 /* Set up the timeout */
36 tss
=getcopyconfigitem("lpart","timeout","86400",6);
37 timeout
=strtol(tss
->content
,NULL
,10);
40 tss
=getcopyconfigitem("lpart","shorttimeout","300",6);
41 shorttimeout
=strtol(tss
->content
,NULL
,10);
44 if ((np
=getnickbynick(targetnick
->content
))) {
45 for(i
=0;i
<CHANNELHASHSIZE
;i
++) {
46 for (cip
=chantable
[i
];cip
;cip
=cip
->next
) {
47 if (cip
->channel
&& cip
->channel
->users
->totalusers
==1 &&
48 getnumerichandlefromchanhash(cip
->channel
->users
,np
->numeric
)) {
49 lp_schedpart(cip
->channel
);
55 registerhook(HOOK_CHANNEL_LOSTNICK
,&lp_handlepart
);
59 /* We need to clean up any outstanding callbacks we have */
60 deleteallschedules(&lp_dopart
);
61 releasechanext(lpartext
);
62 deregisterhook(HOOK_CHANNEL_LOSTNICK
,&lp_handlepart
);
65 void lp_handlepart(int hooknum
, void *arg
) {
66 void **args
=(void **)arg
;
70 /* For a part, first arg is channel and second is nick */
71 cp
=(channel
*)args
[0];
73 /* We're only interested if there is now one user on the channel.
74 Note that the parting user is STILL ON THE CHANNEL at this point,
75 so we're interested if there are two or fewer users left. */
77 if (cp
->users
->totalusers
!=2)
80 /* Let's see if our user is even on the network */
81 if ((np
=getnickbynick(targetnick
->content
))==NULL
)
84 /* And if it's on the channel in question */
85 if (getnumerichandlefromchanhash(cp
->users
,np
->numeric
)==NULL
)
88 /* OK, now let's see if we already had something scheduled for this channel */
89 if (cp
->index
->exts
[lpartext
]!=NULL
) {
90 /* We delete the old schedule at this point */
91 deleteschedule(cp
->index
->exts
[lpartext
],&lp_dopart
, (void *)cp
->index
);
94 /* Error("lpart",ERR_DEBUG,"Scheduling part of channel %s",cp->index->name->content); */
98 void lp_schedpart(channel
*cp
) {
101 /* If the channel has anything that might be worth preserving, use the full timeout.
102 * Otherwise, use the shorter one
105 if ((cp
->flags
& ~(CHANMODE_NOEXTMSG
| CHANMODE_TOPICLIMIT
| CHANMODE_NOCTCP
| CHANMODE_NONOTICE
)) || cp
->topic
|| cp
->bans
) {
108 thetimeout
=shorttimeout
;
111 cp
->index
->exts
[lpartext
]=scheduleoneshot(time(NULL
)+thetimeout
,&lp_dopart
,(void *)cp
->index
);
114 void lp_dopart(void *arg
) {
118 cip
=(chanindex
*)arg
;
119 cip
->exts
[lpartext
]=NULL
;
121 /* Check the chan still exists */
122 if (cip
->channel
==NULL
) {
123 releasechanindex(cip
);
127 /* Check the usercount is 1 */
128 if (cip
->channel
->users
->totalusers
>1)
131 /* Let's see if our user is even on the network */
132 if ((np
=getnickbynick(targetnick
->content
))==NULL
)
135 /* And if it's on the channel in question */
136 if (getnumerichandlefromchanhash(cip
->channel
->users
,np
->numeric
)==NULL
)
139 /* OK, we've established that the channel is of size 1 and has our nick on it. Send the part command.
140 Use controlreply() for this */
142 /* Error("lpart",ERR_DEBUG,"Telling L to part %s",cip->name->content); */
143 controlmessage(np
,"part %s",cip
->name
->content
);