]> jfr.im git - irc/quakenet/lightweight.git/blob - clientcommands/cleanupdb.c
- Removes channels (from the database) that have been suspended for more than 365...
[irc/quakenet/lightweight.git] / clientcommands / cleanupdb.c
1 /*
2 This file is part of lightweight.
3
4 lightweight is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 lightweight is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with lightweight; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18
19 #include <lightweight.h>
20 #include <globalexterns.h>
21 #include <usersdb.h>
22 #include <accountsdb.h>
23 #include <channelsdb.h>
24 #include <channels.h>
25
26 /* cleanupdb.c */
27
28 /*
29 * cleanupdb: removes unused (no authed join for DAYS_BEFORE_EXPIRE days) and
30 * and empty channels (ie: empty chanlev) unless they are suspended.
31 *
32 * Parameters:
33 * -n Don't execute, just show what would be done.
34 *
35 * Operator only.
36 */
37
38 #define CHAN_OK 0
39 #define CHAN_EXPIRED 1
40 #define CHAN_EMPTY 2
41 #define CHAN_OWNER 3
42 #define CHAN_SUSPENDED_EXPIRED 98
43 #define CHAN_SUSPENDED 99
44
45 static int preview, verbose;
46
47 int ExpireChannel(struct reggedchannel *chan, struct user *usr_ptr, int preview)
48 {
49 int i, empty = 1;
50 char buf[512];
51 unsigned char currentflags;
52 time_t now;
53
54 now = time(NULL);
55 i = (now - chan->lastused) / (3600 * 24);
56
57 if (IsSuspended(chan)) {
58 if (now - chan->lastused > (SUSPEND_EXPIRY_TIME * 3600 * 24)) {
59 if (verbose)
60 NoticeToUser(usr_ptr, "%s has been deleted. (suspended for %d days)", chan->channelname, i);
61 if (!preview) {
62 Log("Cleanupdb: channel %s removed (suspended for > %d days)", chan->channelname, i);
63 sprintf(buf, "Channel removed, suspended for > %d days.", i);
64 PartChannel(chan, buf);
65 RemoveChannel(chan);
66 }
67 return (CHAN_SUSPENDED_EXPIRED);
68 }
69 return (CHAN_SUSPENDED);
70 }
71
72 if (chan->lastused && ((now - DAYS_BEFORE_EXPIRE * 3600 * 24) > chan->lastused)) {
73 if (verbose)
74 NoticeToUser(usr_ptr, "%s has expired. (unused for %d days)", chan->channelname, i);
75 if (!preview) {
76 Log("Cleanupdb: channel %s removed (expired: unused for %d days)", chan->channelname, i);
77 sprintf(buf, "Channel expired, unused for %d days.", i);
78 PartChannel(chan, buf);
79 RemoveChannel(chan);
80 }
81 return (CHAN_EXPIRED);
82 }
83
84 /* remove empty channels and non-empty channels w/o any owner/master or op (+n/+m/+o) */
85 for (i = 0; i < USERSPERCHANNEL; i++) {
86 if (NULL != chan->channeluser[i]) {
87 empty = 0;
88 currentflags = chan->channeluser[i]->channelflags[GetUserChannelIndex(chan, chan->channeluser[i])];
89 if (currentflags & CFLAG_OWNER || currentflags & CFLAG_MASTER || currentflags & CFLAG_OP) {
90 return (CHAN_OK);
91 }
92 }
93 }
94
95 if (verbose)
96 NoticeToUser(usr_ptr, "%s %s.", chan->channelname, (empty ? "is empty" : "has no owners, masters or operators"));
97 if (!preview) {
98 Log("Cleanupdb: channel %s removed (%s)", chan->channelname, (empty ? "empty" : "no owners, masters or operators"));
99 sprintf(buf, "Channel %s.", (empty ? "is empty" : "has no owners, masters or operators"));
100 PartChannel(chan, buf);
101 RemoveChannel(chan);
102 }
103
104 return (empty ? CHAN_EMPTY : CHAN_OWNER);
105 }
106
107 void docleanupdb(struct user *usr_ptr, char *tail)
108 {
109 char *option;
110 int i;
111 struct reggedchannel *chan;
112 unsigned int chan_ok, chan_expired, chan_empty, chan_owner, chan_suspended,
113 chan_suspended_expired, chan_unknown, chan_total;
114
115 if (!usr_ptr->oper) {
116 NoticeToUser(usr_ptr, "You are not an operator");
117 return;
118 }
119
120 if (!CheckAuthLevel(usr_ptr, 255))
121 return;
122
123 preview = verbose = 0;
124
125 option = tail;
126 SeperateWord(tail);
127 if (option != NULL) {
128 while (*option) {
129 switch(*option) {
130 case 'v':
131 verbose++;
132 break;
133 case 'n':
134 preview++;
135 break;
136 case '-':
137 break;
138 default:
139 NoticeToUser(usr_ptr, "Usage: cleanupdb [-nv]");
140 return;
141 }
142 *option++;
143 }
144 }
145
146 Log("Cleanupdb: %s (%s) requested cleanupdb%s", usr_ptr->nick, usr_ptr->authedas->authname,
147 (preview ? " -n (preview mode)." : "."));
148
149 chan_ok = chan_expired = chan_empty = chan_owner = chan_suspended = chan_suspended_expired = chan_unknown = 0;
150 for (i = 0; i < HASHMAX; i++) {
151 chan = channelhashtable[i];
152 while (NULL != chan) { /* go through the list */
153 switch (ExpireChannel(chan, usr_ptr, preview)) {
154 case CHAN_OK:
155 chan_ok++;
156 break;
157 case CHAN_EXPIRED:
158 chan_expired++;
159 break;
160 case CHAN_EMPTY:
161 chan_empty++;
162 break;
163 case CHAN_OWNER:
164 chan_owner++;
165 break;
166 case CHAN_SUSPENDED:
167 chan_suspended++;
168 break;
169 case CHAN_SUSPENDED_EXPIRED:
170 chan_suspended_expired++;
171 break;
172 default:
173 chan_unknown++;
174 break;
175 }
176 chan = chan->nextbychannelname; /* next in list */
177 }
178 }
179
180 chan_total = chan_expired + chan_empty + chan_owner + chan_suspended + chan_unknown + chan_ok + chan_suspended_expired;
181 NoticeToUser(usr_ptr, "%d channel/s %s (unused for >= %d days)", chan_expired,
182 (preview) ? "would be removed" : "removed", DAYS_BEFORE_EXPIRE);
183 NoticeToUser(usr_ptr, "%d channel/s %s (empty)", chan_empty, (preview) ? "would be removed" : "removed");
184 NoticeToUser(usr_ptr, "%d channel/s %s (no owners, masters or operators)", chan_owner, (preview) ? "would be removed" : "removed");
185 if (chan_unknown)
186 NoticeToUser(usr_ptr, "%d channel/s (unknown)", chan_unknown);
187 NoticeToUser(usr_ptr, "%d channel/s suspended (untouched)", chan_suspended);
188 NoticeToUser(usr_ptr, "%d channel/s suspended (cleaned)", chan_suspended_expired);
189 NoticeToUser(usr_ptr, "%d channel/s still valid (was %d channel/s)",
190 (chan_total - (chan_expired + chan_empty + chan_owner + chan_suspended_expired)), chan_total);
191
192 if (!preview)
193 Log("Cleanupdb: %s (%s) deleted %d channel/s (%d expired, %d empty, %d no owner/master/op) of %d channel/s", usr_ptr->nick,
194 usr_ptr->authedas->authname, (chan_expired + chan_empty + chan_owner), chan_expired, chan_empty, chan_owner,
195 chan_total);
196
197 NoticeToUser(usr_ptr, "Done.");
198 }