~ubuntu-branches/ubuntu/oneiric/eggdrop/oneiric

« back to all changes in this revision

Viewing changes to src/mod/irc.mod/cmdsirc.c

  • Committer: Bazaar Package Importer
  • Author(s): Guilherme de S. Pastore
  • Date: 2004-06-17 09:15:28 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20040617091528-64rrw1sa33lkfhmh
Tags: 1.6.16-2
* Fixed typo on README.Debian
* Fixed hyphens in manual page
* Converted debian/rules to CDBS
* Set path to binary on example config file
* Changed LANGDIR on src/eggdrop.h (Closes: #254824)

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
 * chancmds.c -- part of irc.mod
3
3
 *   handles commands directly relating to channel interaction
4
4
 *
5
 
 * $Id: cmdsirc.c,v 1.30 2002/01/02 03:46:39 guppy Exp $
 
5
 * $Id: cmdsirc.c,v 1.56 2004/01/09 05:56:38 wcc Exp $
6
6
 */
7
7
/*
8
8
 * Copyright (C) 1997 Robey Pointer
9
 
 * Copyright (C) 1999, 2000, 2001, 2002 Eggheads Development Team
 
9
 * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 Eggheads Development Team
10
10
 *
11
11
 * This program is free software; you can redistribute it and/or
12
12
 * modify it under the terms of the GNU General Public License
23
23
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
24
24
 */
25
25
 
26
 
/* Do we have any flags that will allow us ops on a channel?
27
 
 */
28
 
static struct chanset_t *has_op(int idx, char *chname)
 
26
static struct chanset_t *get_channel(int idx, char *chname)
29
27
{
30
28
  struct chanset_t *chan;
31
29
 
32
30
  if (chname && chname[0]) {
33
31
    chan = findchan_by_dname(chname);
34
 
    if (!chan) {
 
32
    if (chan)
 
33
      return chan;
 
34
    else
35
35
      dprintf(idx, "No such channel.\n");
36
 
      return 0;
37
 
    }
38
36
  } else {
39
37
    chname = dcc[idx].u.chat->con_chan;
40
38
    chan = findchan_by_dname(chname);
41
 
    if (!chan) {
 
39
    if (chan)
 
40
      return chan;
 
41
    else
42
42
      dprintf(idx, "Invalid console channel.\n");
43
 
      return 0;
44
 
    }
45
43
  }
46
 
  get_user_flagrec(dcc[idx].user, &user, chname);
 
44
  return 0;
 
45
}
 
46
 
 
47
/* Do we have any flags that will allow us ops on a channel?
 
48
 */
 
49
static int has_op(int idx, struct chanset_t *chan)
 
50
{
 
51
  get_user_flagrec(dcc[idx].user, &user, chan->dname);
47
52
  if (chan_op(user) || (glob_op(user) && !chan_deop(user)))
48
 
    return chan;
 
53
    return 1;
49
54
  dprintf(idx, "You are not a channel op on %s.\n", chan->dname);
50
55
  return 0;
51
56
}
52
57
 
 
58
static int has_oporhalfop(int idx, struct chanset_t *chan)
 
59
{
 
60
  get_user_flagrec(dcc[idx].user, &user, chan->dname);
 
61
  if (chan_op(user) || chan_halfop(user) || (glob_op(user) &&
 
62
      !chan_deop(user)) || (glob_halfop(user) && !chan_dehalfop(user)))
 
63
    return 1;
 
64
  dprintf(idx, "You are not a channel op or halfop on %s.\n", chan->dname);
 
65
  return 0;
 
66
}
 
67
 
53
68
/* Finds a nick of the handle. Returns m->nick if
54
69
 * the nick was found, otherwise NULL (Sup 1Nov2000)
55
70
 */
56
71
static char *getnick(char *handle, struct chanset_t *chan)
57
72
{
58
 
  char                   s[UHOSTLEN];
59
 
  struct userrec        *u;
60
 
  register memberlist   *m;
 
73
  char s[UHOSTLEN];
 
74
  struct userrec *u;
 
75
  register memberlist *m;
61
76
 
62
77
  for (m = chan->channel.member; m && m->nick[0]; m = m->next) {
63
78
    egg_snprintf(s, sizeof s, "%s!%s", m->nick, m->userhost);
81
96
    chname = newsplit(&par);
82
97
  else
83
98
    chname = 0;
84
 
  if (!(chan = has_op(idx, chname)))
 
99
  chan = get_channel(idx, chname);
 
100
  if (!chan || !has_op(idx, chan))
85
101
    return;
86
102
  m = ismember(chan, botname);
87
103
  if (!m) {
88
104
    dprintf(idx, "Cannot say to %s: I'm not on that channel.\n", chan->dname);
89
105
    return;
90
106
  }
91
 
  if ((chan->channel.mode & CHANMODER) && !(m->flags & (CHANOP | CHANVOICE))) {
92
 
    dprintf(idx, "Cannot say to %s, it is moderated.\n", chan->dname);
 
107
  if ((chan->channel.mode & CHANMODER) && !me_op(chan) && !me_halfop(chan) &&
 
108
      !me_voice(chan)) {
 
109
    dprintf(idx, "Cannot say to %s: It is moderated.\n", chan->dname);
93
110
    return;
94
111
  }
95
 
  putlog(LOG_CMDS, "*", "#%s# (%s) act %s", dcc[idx].nick,
96
 
         chan->dname, par);
97
 
  dprintf(DP_HELP, "PRIVMSG %s :\001ACTION %s\001\n",
98
 
          chan->name, par);
 
112
  putlog(LOG_CMDS, "*", "#%s# (%s) act %s", dcc[idx].nick, chan->dname, par);
 
113
  dprintf(DP_HELP, "PRIVMSG %s :\001ACTION %s\001\n", chan->name, par);
99
114
  dprintf(idx, "Action to %s: %s\n", chan->dname, par);
100
115
}
101
116
 
104
119
  char *nick;
105
120
 
106
121
  nick = newsplit(&par);
107
 
  if (!par[0]) {
 
122
  if (!par[0])
108
123
    dprintf(idx, "Usage: msg <nick> <message>\n");
109
 
  } else {
 
124
  else {
110
125
    putlog(LOG_CMDS, "*", "#%s# msg %s %s", dcc[idx].nick, nick, par);
111
126
    dprintf(DP_HELP, "PRIVMSG %s :%s\n", nick, par);
112
127
    dprintf(idx, "Msg to %s: %s\n", nick, par);
127
142
    chname = newsplit(&par);
128
143
  else
129
144
    chname = 0;
130
 
  if (!(chan = has_op(idx, chname)))
 
145
  chan = get_channel(idx, chname);
 
146
  if (!chan || !has_op(idx, chan))
131
147
    return;
132
148
  m = ismember(chan, botname);
133
149
  if (!m) {
134
150
    dprintf(idx, "Cannot say to %s: I'm not on that channel.\n", chan->dname);
135
151
    return;
136
152
  }
137
 
  if ((chan->channel.mode & CHANMODER) && !(m->flags & (CHANOP | CHANVOICE))) {
138
 
    dprintf(idx, "Cannot say to %s, it is moderated.\n", chan->dname);
 
153
  if ((chan->channel.mode & CHANMODER) && !me_op(chan) && !me_halfop(chan) &&
 
154
      !me_voice(chan)) {
 
155
    dprintf(idx, "Cannot say to %s: It is moderated.\n", chan->dname);
139
156
    return;
140
157
  }
141
158
  putlog(LOG_CMDS, "*", "#%s# (%s) say %s", dcc[idx].nick, chan->dname, par);
155
172
    dprintf(idx, "Usage: kickban [channel] [-|@]<nick> [reason]\n");
156
173
    return;
157
174
  }
 
175
 
158
176
  if (strchr(CHANMETA, par[0]) != NULL)
159
177
    chname = newsplit(&par);
160
178
  else
161
179
    chname = 0;
162
 
  if (!(chan = has_op(idx, chname)))
 
180
  chan = get_channel(idx, chname);
 
181
  if (!chan || !has_oporhalfop(idx, chan))
163
182
    return;
164
183
  if (!channel_active(chan)) {
165
184
    dprintf(idx, "I'm not on %s right now!\n", chan->dname);
166
185
    return;
167
186
  }
168
 
  if (!me_op(chan)) {
169
 
    dprintf(idx, "I can't help you now because I'm not a channel op on %s.\n",
170
 
            chan->dname);
 
187
  if (HALFOP_CANTDOMODE('b')) {
 
188
    dprintf(idx, "I can't help you now because I'm not a channel op or halfop "
 
189
            "on %s, or halfops cannot set bans.\n", chan->dname);
171
190
    return;
172
191
  }
173
192
  putlog(LOG_CMDS, "*", "#%s# (%s) kickban %s", dcc[idx].nick,
174
 
         chan->dname, par);
 
193
         chan->dname, par);
175
194
  nick = newsplit(&par);
176
195
  if ((nick[0] == '@') || (nick[0] == '-')) {
177
196
    bantype = nick[0];
180
199
  if (match_my_nick(nick)) {
181
200
    dprintf(idx, "I'm not going to kickban myself.\n");
182
201
    return;
183
 
  } else {
184
 
    m = ismember(chan, nick);
185
 
    if (!m)
186
 
      dprintf(idx, "%s is not on %s\n", nick, chan->dname);
187
 
    else {
188
 
      egg_snprintf(s, sizeof s, "%s!%s", m->nick, m->userhost);
189
 
      u = get_user_by_host(s);
190
 
      get_user_flagrec(u, &victim, chan->dname);
191
 
      if ((chan_op(victim) || (glob_op(victim) && !chan_deop(victim))) &&
192
 
          !(chan_master(user) || glob_master(user))) {
193
 
        dprintf(idx, "%s is a legal op.\n", nick);
194
 
        return;
195
 
      }
196
 
      if ((chan_master(victim) || glob_master(victim)) &&
197
 
          !(glob_owner(user) || chan_owner(user))) {
198
 
        dprintf(idx, "%s is a %s master.\n", nick, chan->dname);
199
 
        return;
200
 
      }
201
 
      if (glob_bot(victim) && !(glob_owner(victim) || chan_owner(victim))) {
202
 
        dprintf(idx, "%s is another channel bot!\n", nick);
203
 
        return;
204
 
      }
205
 
      if (use_exempts &&
206
 
          (u_match_mask(global_exempts,s) || u_match_mask(chan->exempts, s))) {
207
 
        dprintf(idx, "%s is permanent exempted!\n", nick);
208
 
        return;
209
 
      }
210
 
      if (m->flags & CHANOP)
211
 
        add_mode(chan, '-', 'o', m->nick);
212
 
      check_exemptlist(chan, s);
213
 
      switch (bantype) {
214
 
        case '@':
215
 
          s1 = strchr(s, '@');
216
 
          s1 -= 3;
217
 
          s1[0] = '*';
218
 
          s1[1] = '!';
219
 
          s1[2] = '*';
220
 
          break;
221
 
        case '-':
222
 
          s1 = strchr(s, '-');
223
 
          s1[1] = '*';
224
 
          s1--;
225
 
          s1[0] = '*';
226
 
          break;
227
 
        default:
228
 
          s1 = quickban(chan, m->userhost);
229
 
          break;
230
 
      }
231
 
      if (bantype == '@' || bantype == '-')
232
 
        do_mask(chan, chan->channel.ban, s1, 'b');
233
 
      if (!par[0])
234
 
        par = "requested";
235
 
      dprintf(DP_SERVER, "KICK %s %s :%s\n", chan->name, m->nick, par);
236
 
      m->flags |= SENTKICK;
237
 
      u_addban(chan, s1, dcc[idx].nick, par, now + (60 * ban_time), 0);
238
 
      dprintf(idx, "Okay, done.\n");
239
 
    }
240
 
  }
241
 
}
242
 
 
243
 
static void cmd_voice(struct userrec *u, int idx, char *par)
244
 
{
245
 
  struct chanset_t *chan;
246
 
  char *nick;
247
 
  memberlist *m;
248
 
  char s[UHOSTLEN];
249
 
 
250
 
  nick = newsplit(&par);
251
 
  if (!(chan = has_op(idx, par)))
252
 
    return;
253
 
  if (!nick[0] && !(nick = getnick(u->handle, chan))) {
254
 
    dprintf(idx, "Usage: voice <nick> [channel]\n");
255
 
    return;
256
 
  }
257
 
  if (!channel_active(chan)) {
258
 
    dprintf(idx, "I'm not on %s right now!\n", chan->dname);
259
 
    return;
260
 
  }
261
 
  if (!me_op(chan)) {
262
 
    dprintf(idx, "I can't help you now because I'm not a chan op on %s.\n",
263
 
            chan->dname);
264
 
    return;
265
 
  }
266
 
  putlog(LOG_CMDS, "*", "#%s# (%s) voice %s %s", dcc[idx].nick,
267
 
         dcc[idx].u.chat->con_chan, nick, par);
268
 
  m = ismember(chan, nick);
269
 
  if (!m) {
270
 
    dprintf(idx, "%s is not on %s.\n", nick, chan->dname);
271
 
    return;
272
 
  }
273
 
  egg_snprintf(s, sizeof s, "%s!%s", m->nick, m->userhost);
274
 
  add_mode(chan, '+', 'v', nick);
275
 
  dprintf(idx, "Gave voice to %s on %s\n", nick, chan->dname);
276
 
}
277
 
 
278
 
static void cmd_devoice(struct userrec *u, int idx, char *par)
279
 
{
280
 
  struct chanset_t *chan;
281
 
  char *nick;
282
 
  memberlist *m;
283
 
  char s[UHOSTLEN];
284
 
 
285
 
  nick = newsplit(&par);
286
 
  if (!(chan = has_op(idx, par)))
287
 
    return;
288
 
  if (!nick[0] && !(nick = getnick(u->handle, chan))) {
289
 
    dprintf(idx, "Usage: devoice <nick> [channel]\n");
290
 
    return;
291
 
  }
292
 
  if (!channel_active(chan)) {
293
 
    dprintf(idx, "I'm not on %s right now!\n", chan->dname);
294
 
    return;
295
 
  }
296
 
  if (!me_op(chan)) {
297
 
    dprintf(idx, "I can't do that right now I'm not a chan op on %s.\n",
298
 
            chan->dname);
299
 
    return;
300
 
  }
301
 
  putlog(LOG_CMDS, "*", "#%s# (%s) devoice %s %s", dcc[idx].nick,
302
 
         dcc[idx].u.chat->con_chan, nick, par);
303
 
  m = ismember(chan, nick);
304
 
  if (!m) {
305
 
    dprintf(idx, "%s is not on %s.\n", nick, chan->dname);
306
 
    return;
307
 
  }
308
 
  egg_snprintf(s, sizeof s, "%s!%s", m->nick, m->userhost);
309
 
  add_mode(chan, '-', 'v', nick);
310
 
  dprintf(idx, "Devoiced %s on %s\n", nick, chan->dname);
 
202
  }
 
203
  m = ismember(chan, nick);
 
204
  if (!m) {
 
205
    dprintf(idx, "%s is not on %s\n", nick, chan->dname);
 
206
    return;
 
207
  }
 
208
  if (!me_op(chan) && chan_hasop(m)) {
 
209
    dprintf(idx, "I can't help you now because halfops cannot kick ops.\n");
 
210
    return;
 
211
  }
 
212
  egg_snprintf(s, sizeof s, "%s!%s", m->nick, m->userhost);
 
213
  u = get_user_by_host(s);
 
214
  get_user_flagrec(u, &victim, chan->dname);
 
215
  if ((chan_op(victim) || (glob_op(victim) && !chan_deop(victim))) &&
 
216
      !(chan_master(user) || glob_master(user))) {
 
217
    dprintf(idx, "%s is a legal op.\n", nick);
 
218
    return;
 
219
  }
 
220
  if ((chan_master(victim) || glob_master(victim)) &&
 
221
      !(glob_owner(user) || chan_owner(user))) {
 
222
    dprintf(idx, "%s is a %s master.\n", nick, chan->dname);
 
223
    return;
 
224
  }
 
225
  if (glob_bot(victim) && !(glob_owner(user) || chan_owner(user))) {
 
226
    dprintf(idx, "%s is another channel bot!\n", nick);
 
227
    return;
 
228
  }
 
229
  if (use_exempts && (u_match_mask(global_exempts, s) ||
 
230
      u_match_mask(chan->exempts, s))) {
 
231
    dprintf(idx, "%s is permanently exempted!\n", nick);
 
232
    return;
 
233
  }
 
234
  if (m->flags & CHANOP)
 
235
    add_mode(chan, '-', 'o', m->nick);
 
236
  check_exemptlist(chan, s);
 
237
  switch (bantype) {
 
238
  case '@':
 
239
    s1 = strchr(s, '@');
 
240
    s1 -= 3;
 
241
    s1[0] = '*';
 
242
    s1[1] = '!';
 
243
    s1[2] = '*';
 
244
    break;
 
245
  case '-':
 
246
    s1 = strchr(s, '!');
 
247
    s1[1] = '*';
 
248
    s1--;
 
249
    s1[0] = '*';
 
250
    break;
 
251
  default:
 
252
    s1 = quickban(chan, m->userhost);
 
253
    break;
 
254
  }
 
255
  if (bantype == '@' || bantype == '-')
 
256
    do_mask(chan, chan->channel.ban, s1, 'b');
 
257
  if (!par[0])
 
258
    par = "requested";
 
259
  dprintf(DP_SERVER, "KICK %s %s :%s\n", chan->name, m->nick, par);
 
260
  m->flags |= SENTKICK;
 
261
  u_addban(chan, s1, dcc[idx].nick, par, now + (60 * chan->ban_time), 0);
 
262
  dprintf(idx, "Okay, done.\n");
311
263
}
312
264
 
313
265
static void cmd_op(struct userrec *u, int idx, char *par)
318
270
  char s[UHOSTLEN];
319
271
 
320
272
  nick = newsplit(&par);
321
 
  if (!(chan = has_op(idx, par)))
 
273
  chan = get_channel(idx, par);
 
274
  if (!chan || !has_op(idx, chan))
322
275
    return;
 
276
 
323
277
  if (!nick[0] && !(nick = getnick(u->handle, chan))) {
324
278
    dprintf(idx, "Usage: op <nick> [channel]\n");
325
279
    return;
326
280
  }
 
281
 
327
282
  if (!channel_active(chan)) {
328
283
    dprintf(idx, "I'm not on %s right now!\n", chan->dname);
329
284
    return;
330
285
  }
331
 
  if (!me_op(chan)) {
332
 
    dprintf(idx, "I can't help you now because I'm not a chan op on %s.\n",
333
 
            chan->dname);
 
286
 
 
287
  if (HALFOP_CANTDOMODE('o')) {
 
288
    dprintf(idx, "I can't help you now because I'm not a chan op or halfop on "
 
289
            "%s, or halfops cannot set +o modes.\n", chan->dname);
334
290
    return;
335
291
  }
336
 
  putlog(LOG_CMDS, "*", "#%s# (%s) op %s %s", dcc[idx].nick,
337
 
         dcc[idx].u.chat->con_chan, nick, par);
 
292
 
 
293
  putlog(LOG_CMDS, "*", "#%s# (%s) op %s", dcc[idx].nick, chan->dname, nick);
338
294
  m = ismember(chan, nick);
339
295
  if (!m) {
340
296
    dprintf(idx, "%s is not on %s.\n", nick, chan->dname);
347
303
    dprintf(idx, "%s is currently being auto-deopped.\n", m->nick);
348
304
    return;
349
305
  }
350
 
  if (channel_bitch(chan)
351
 
      && !(chan_op(victim) || (glob_op(victim) && !chan_deop(victim)))) {
 
306
  if (channel_bitch(chan) && !(chan_op(victim) || (glob_op(victim) &&
 
307
      !chan_deop(victim)))) {
352
308
    dprintf(idx, "%s is not a registered op.\n", m->nick);
353
309
    return;
354
310
  }
355
311
  add_mode(chan, '+', 'o', nick);
356
 
  dprintf(idx, "Gave op to %s on %s\n", nick, chan->dname);
 
312
  dprintf(idx, "Gave op to %s on %s.\n", nick, chan->dname);
357
313
}
358
314
 
359
315
static void cmd_deop(struct userrec *u, int idx, char *par)
364
320
  char s[UHOSTLEN];
365
321
 
366
322
  nick = newsplit(&par);
367
 
  if (!(chan = has_op(idx, par)))
 
323
  chan = get_channel(idx, par);
 
324
  if (!chan || !has_op(idx, chan))
368
325
    return;
 
326
 
369
327
  if (!nick[0] && !(nick = getnick(u->handle, chan))) {
370
328
    dprintf(idx, "Usage: deop <nick> [channel]\n");
371
329
    return;
372
330
  }
 
331
 
373
332
  if (!channel_active(chan)) {
374
333
    dprintf(idx, "I'm not on %s right now!\n", chan->dname);
375
334
    return;
376
335
  }
377
 
  if (!me_op(chan)) {
378
 
    dprintf(idx, "I can't help you now because I'm not a chan op on %s.\n",
379
 
            chan->dname);
 
336
 
 
337
  if (HALFOP_CANTDOMODE('o')) {
 
338
    dprintf(idx, "I can't help you now because I'm not a chan op or halfop on "
 
339
            "%s, or halfops cannot set -o modes.\n", chan->dname);
380
340
    return;
381
341
  }
382
 
  putlog(LOG_CMDS, "*", "#%s# (%s) deop %s %s", dcc[idx].nick,
383
 
         dcc[idx].u.chat->con_chan, nick, par);
 
342
 
 
343
  putlog(LOG_CMDS, "*", "#%s# (%s) deop %s", dcc[idx].nick, chan->dname, nick);
384
344
  m = ismember(chan, nick);
385
345
  if (!m) {
386
346
    dprintf(idx, "%s is not on %s.\n", nick, chan->dname);
395
355
  get_user_flagrec(u, &victim, chan->dname);
396
356
  if ((chan_master(victim) || glob_master(victim)) &&
397
357
      !(chan_owner(user) || glob_owner(user))) {
398
 
    dprintf(idx, "%s is a master for %s\n", m->nick, chan->dname);
 
358
    dprintf(idx, "%s is a master for %s.\n", m->nick, chan->dname);
399
359
    return;
400
360
  }
401
361
  if ((chan_op(victim) || (glob_op(victim) && !chan_deop(victim))) &&
402
362
      !(chan_master(user) || glob_master(user))) {
403
 
    dprintf(idx, "%s has the op flag for %s\n", m->nick, chan->dname);
 
363
    dprintf(idx, "%s has the op flag for %s.\n", m->nick, chan->dname);
404
364
    return;
405
365
  }
406
366
  add_mode(chan, '-', 'o', nick);
407
 
  dprintf(idx, "Took op from %s on %s\n", nick, chan->dname);
 
367
  dprintf(idx, "Took op from %s on %s.\n", nick, chan->dname);
 
368
}
 
369
 
 
370
static void cmd_halfop(struct userrec *u, int idx, char *par)
 
371
{
 
372
  struct chanset_t *chan;
 
373
  struct userrec *u2;
 
374
  char *nick;
 
375
  memberlist *m;
 
376
  char s[UHOSTLEN];
 
377
 
 
378
  nick = newsplit(&par);
 
379
  chan = get_channel(idx, par);
 
380
  if (!chan)
 
381
    return;
 
382
 
 
383
  if (!nick[0] && !(nick = getnick(u->handle, chan))) {
 
384
    dprintf(idx, "Usage: halfop <nick> [channel]\n");
 
385
    return;
 
386
  }
 
387
 
 
388
  get_user_flagrec(dcc[idx].user, &user, chan->dname);
 
389
  m = ismember(chan, nick);
 
390
  if (m && !chan_op(user) && (!glob_op(user) || chan_deop(user))) {
 
391
    egg_snprintf(s, sizeof s, "%s!%s", m->nick, m->userhost);
 
392
    u2 = m->user ? m->user : get_user_by_host(s);
 
393
 
 
394
    if (!u2 || strcmp(u2->handle, dcc[idx].nick) || (!chan_halfop(user) &&
 
395
        (!glob_halfop(user) || chan_dehalfop(user)))) {
 
396
      dprintf(idx, "You are not a channel op on %s.\n", chan->dname);
 
397
      return;
 
398
    }
 
399
  }
 
400
 
 
401
  if (!channel_active(chan)) {
 
402
    dprintf(idx, "I'm not on %s right now!\n", chan->dname);
 
403
    return;
 
404
  }
 
405
 
 
406
  if (HALFOP_CANTDOMODE('h')) {
 
407
    dprintf(idx, "I can't help you now because I'm not a chan op or halfop on "
 
408
            "%s, or halfops cannot set +h modes.\n", chan->dname);
 
409
    return;
 
410
  }
 
411
 
 
412
  putlog(LOG_CMDS, "*", "#%s# (%s) halfop %s", dcc[idx].nick,
 
413
         chan->dname, nick);
 
414
  m = ismember(chan, nick);
 
415
  if (!m) {
 
416
    dprintf(idx, "%s is not on %s.\n", nick, chan->dname);
 
417
    return;
 
418
  }
 
419
  egg_snprintf(s, sizeof s, "%s!%s", m->nick, m->userhost);
 
420
  u = get_user_by_host(s);
 
421
  get_user_flagrec(u, &victim, chan->dname);
 
422
  if (chan_dehalfop(victim) || (glob_dehalfop(victim) && !glob_halfop(victim))) {
 
423
    dprintf(idx, "%s is currently being auto-dehalfopped.\n", m->nick);
 
424
    return;
 
425
  }
 
426
  if (channel_bitch(chan) && !(chan_op(victim) || chan_op(victim) ||
 
427
      (glob_op(victim) && !chan_deop(victim)) || (glob_halfop(victim) &&
 
428
      !chan_dehalfop(victim)))) {
 
429
    dprintf(idx, "%s is not a registered halfop.\n", m->nick);
 
430
    return;
 
431
  }
 
432
  add_mode(chan, '+', 'h', nick);
 
433
  dprintf(idx, "Gave halfop to %s on %s.\n", nick, chan->dname);
 
434
}
 
435
 
 
436
static void cmd_dehalfop(struct userrec *u, int idx, char *par)
 
437
{
 
438
  struct chanset_t *chan;
 
439
  struct userrec *u2;
 
440
  char *nick;
 
441
  memberlist *m;
 
442
  char s[UHOSTLEN];
 
443
 
 
444
  nick = newsplit(&par);
 
445
  chan = get_channel(idx, par);
 
446
  if (!chan)
 
447
    return;
 
448
 
 
449
  if (!nick[0] && !(nick = getnick(u->handle, chan))) {
 
450
    dprintf(idx, "Usage: dehalfop <nick> [channel]\n");
 
451
    return;
 
452
  }
 
453
 
 
454
  get_user_flagrec(dcc[idx].user, &user, chan->dname);
 
455
  m = ismember(chan, nick);
 
456
  if (m && !chan_op(user) && (!glob_op(user) || chan_deop(user))) {
 
457
    egg_snprintf(s, sizeof s, "%s!%s", m->nick, m->userhost);
 
458
    u2 = m->user ? m->user : get_user_by_host(s);
 
459
 
 
460
    if (!u2 || strcmp(u2->handle, dcc[idx].nick) || (!chan_halfop(user) &&
 
461
        (!glob_halfop(user) || chan_dehalfop(user)))) {
 
462
      dprintf(idx, "You are not a channel op on %s.\n", chan->dname);
 
463
      return;
 
464
    }
 
465
  }
 
466
 
 
467
  if (!channel_active(chan)) {
 
468
    dprintf(idx, "I'm not on %s right now!\n", chan->dname);
 
469
    return;
 
470
  }
 
471
 
 
472
  if (HALFOP_CANTDOMODE('h')) {
 
473
    dprintf(idx, "I can't help you now because I'm not a chan op or halfop on "
 
474
            "%s, or halfops cannot set -h modes.\n", chan->dname);
 
475
    return;
 
476
  }
 
477
 
 
478
  putlog(LOG_CMDS, "*", "#%s# (%s) dehalfop %s", dcc[idx].nick,
 
479
         chan->dname, nick);
 
480
  m = ismember(chan, nick);
 
481
  if (!m) {
 
482
    dprintf(idx, "%s is not on %s.\n", nick, chan->dname);
 
483
    return;
 
484
  }
 
485
  if (match_my_nick(nick)) {
 
486
    dprintf(idx, "I'm not going to dehalfop myself.\n");
 
487
    return;
 
488
  }
 
489
  egg_snprintf(s, sizeof s, "%s!%s", m->nick, m->userhost);
 
490
  u = get_user_by_host(s);
 
491
  get_user_flagrec(u, &victim, chan->dname);
 
492
  if ((chan_master(victim) || glob_master(victim)) &&
 
493
      !(chan_owner(user) || glob_owner(user))) {
 
494
    dprintf(idx, "%s is a master for %s.\n", m->nick, chan->dname);
 
495
    return;
 
496
  }
 
497
  if ((chan_op(victim) || (glob_op(victim) && !chan_deop(victim))) &&
 
498
      !(chan_master(user) || glob_master(user))) {
 
499
    dprintf(idx, "%s has the op flag for %s.\n", m->nick, chan->dname);
 
500
    return;
 
501
  }
 
502
  if ((chan_halfop(victim) || (glob_halfop(victim) &&
 
503
      !chan_dehalfop(victim))) && !(chan_master(user) || glob_master(user))) {
 
504
    dprintf(idx, "%s has the halfop flag for %s.\n", m->nick, chan->dname);
 
505
    return;
 
506
  }
 
507
  add_mode(chan, '-', 'h', nick);
 
508
  dprintf(idx, "Took halfop from %s on %s.\n", nick, chan->dname);
 
509
}
 
510
 
 
511
static void cmd_voice(struct userrec *u, int idx, char *par)
 
512
{
 
513
  struct chanset_t *chan;
 
514
  struct userrec *u2;
 
515
  char *nick;
 
516
  memberlist *m;
 
517
  char s[UHOSTLEN];
 
518
 
 
519
  nick = newsplit(&par);
 
520
  chan = get_channel(idx, par);
 
521
  if (!chan)
 
522
    return;
 
523
 
 
524
  if (!nick[0] && !(nick = getnick(u->handle, chan))) {
 
525
    dprintf(idx, "Usage: voice <nick> [channel]\n");
 
526
    return;
 
527
  }
 
528
 
 
529
  get_user_flagrec(dcc[idx].user, &user, chan->dname);
 
530
  m = ismember(chan, nick);
 
531
 
 
532
  /* By factoring out a !, this code becomes a lot clearer.
 
533
   * If you are... not a (channel op, or a channel half op, or a global op
 
534
   * without channel deop, or a global halfop without channel dehalfop)...
 
535
   * - stdarg */
 
536
  if (m && !(chan_op(user) || chan_halfop(user) || (glob_op(user) && !chan_deop(user)) || (glob_halfop(user) && !chan_dehalfop(user)))) {
 
537
    egg_snprintf(s, sizeof s, "%s!%s", m->nick, m->userhost);
 
538
    u2 = m->user ? m->user : get_user_by_host(s);
 
539
 
 
540
    if (!u2 || strcmp(u2->handle, dcc[idx].nick) || (!chan_voice(user) &&
 
541
        (!glob_voice(user) || chan_quiet(user)))) {
 
542
      dprintf(idx, "You are not a channel op or halfop on %s.\n", chan->dname);
 
543
      return;
 
544
    }
 
545
  }
 
546
 
 
547
  if (!channel_active(chan)) {
 
548
    dprintf(idx, "I'm not on %s right now!\n", chan->dname);
 
549
    return;
 
550
  }
 
551
 
 
552
  if (HALFOP_CANTDOMODE('v')) {
 
553
    dprintf(idx, "I can't help you now because I'm not a chan op or halfop on "
 
554
            "%s, or halfops cannot set +v modes.\n", chan->dname);
 
555
    return;
 
556
  }
 
557
 
 
558
  putlog(LOG_CMDS, "*", "#%s# (%s) voice %s", dcc[idx].nick, chan->dname, nick);
 
559
  m = ismember(chan, nick);
 
560
  if (!m) {
 
561
    dprintf(idx, "%s is not on %s.\n", nick, chan->dname);
 
562
    return;
 
563
  }
 
564
  egg_snprintf(s, sizeof s, "%s!%s", m->nick, m->userhost);
 
565
  add_mode(chan, '+', 'v', nick);
 
566
  dprintf(idx, "Gave voice to %s on %s\n", nick, chan->dname);
 
567
}
 
568
 
 
569
static void cmd_devoice(struct userrec *u, int idx, char *par)
 
570
{
 
571
  struct chanset_t *chan;
 
572
  struct userrec *u2;
 
573
  char *nick;
 
574
  memberlist *m;
 
575
  char s[UHOSTLEN];
 
576
 
 
577
  nick = newsplit(&par);
 
578
  chan = get_channel(idx, par);
 
579
  if (!chan)
 
580
    return;
 
581
 
 
582
  if (!nick[0] && !(nick = getnick(u->handle, chan))) {
 
583
    dprintf(idx, "Usage: devoice <nick> [channel]\n");
 
584
    return;
 
585
  }
 
586
 
 
587
  get_user_flagrec(dcc[idx].user, &user, chan->dname);
 
588
  m = ismember(chan, nick);
 
589
  if (m && !(chan_op(user) || chan_halfop(user) || (glob_op(user) && !chan_deop(user)) || (glob_halfop(user) && !chan_dehalfop(user)))) {
 
590
    egg_snprintf(s, sizeof s, "%s!%s", m->nick, m->userhost);
 
591
    u2 = m->user ? m->user : get_user_by_host(s);
 
592
 
 
593
    if (!u2 || strcmp(u2->handle, dcc[idx].nick) || (!chan_voice(user) &&
 
594
        (!glob_voice(user) || chan_quiet(user)))) {
 
595
      dprintf(idx, "You are not a channel op or halfop on %s.\n", chan->dname);
 
596
      return;
 
597
    }
 
598
  }
 
599
 
 
600
  if (!channel_active(chan)) {
 
601
    dprintf(idx, "I'm not on %s right now!\n", chan->dname);
 
602
    return;
 
603
  }
 
604
 
 
605
  if (HALFOP_CANTDOMODE('v')) {
 
606
    dprintf(idx, "I can't help you now because I'm not a chan op or halfop on "
 
607
            "%s, or halfops cannot set -v modes.\n", chan->dname);
 
608
    return;
 
609
  }
 
610
 
 
611
  putlog(LOG_CMDS, "*", "#%s# (%s) devoice %s", dcc[idx].nick,
 
612
         chan->dname, nick);
 
613
  m = ismember(chan, nick);
 
614
  if (!m) {
 
615
    dprintf(idx, "%s is not on %s.\n", nick, chan->dname);
 
616
    return;
 
617
  }
 
618
  egg_snprintf(s, sizeof s, "%s!%s", m->nick, m->userhost);
 
619
  add_mode(chan, '-', 'v', nick);
 
620
  dprintf(idx, "Devoiced %s on %s\n", nick, chan->dname);
408
621
}
409
622
 
410
623
static void cmd_kick(struct userrec *u, int idx, char *par)
422
635
    chname = newsplit(&par);
423
636
  else
424
637
    chname = 0;
425
 
  if (!(chan = has_op(idx, chname)))
 
638
  chan = get_channel(idx, chname);
 
639
  if (!chan || !has_oporhalfop(idx, chan))
426
640
    return;
427
641
  if (!channel_active(chan)) {
428
642
    dprintf(idx, "I'm not on %s right now!\n", chan->dname);
429
643
    return;
430
644
  }
431
 
  if (!me_op(chan)) {
432
 
    dprintf(idx, "I can't help you now because I'm not a channel op on %s.\n",
433
 
            chan->dname);
 
645
  if (!me_op(chan) && !me_halfop(chan)) {
 
646
    dprintf(idx, "I can't help you now because I'm not a channel op or halfop "
 
647
            "on %s.\n", chan->dname);
434
648
    return;
435
649
  }
436
 
  putlog(LOG_CMDS, "*", "#%s# (%s) kick %s", dcc[idx].nick,
437
 
         chan->dname, par);
 
650
  putlog(LOG_CMDS, "*", "#%s# (%s) kick %s", dcc[idx].nick, chan->dname, par);
438
651
  nick = newsplit(&par);
439
652
  if (!par[0])
440
653
    par = "request";
447
660
    dprintf(idx, "%s is not on %s\n", nick, chan->dname);
448
661
    return;
449
662
  }
 
663
  if (!me_op(chan) && chan_hasop(m)) {
 
664
    dprintf(idx, "I can't help you now because halfops cannot kick ops.\n",
 
665
            chan->dname);
 
666
    return;
 
667
  }
450
668
  egg_snprintf(s, sizeof s, "%s!%s", m->nick, m->userhost);
451
669
  u = get_user_by_host(s);
452
670
  get_user_flagrec(u, &victim, chan->dname);
460
678
    dprintf(idx, "%s is a %s master.\n", nick, chan->dname);
461
679
    return;
462
680
  }
463
 
  if (glob_bot(victim) && !(glob_owner(victim) || chan_owner(victim))) {
 
681
  if (glob_bot(victim) && !(glob_owner(user) || chan_owner(user))) {
464
682
    dprintf(idx, "%s is another channel bot!\n", nick);
465
683
    return;
466
684
  }
478
696
  if (!par[0])
479
697
    par = dcc[idx].nick;
480
698
  nick = newsplit(&par);
481
 
  if (!(chan = has_op(idx, par)))
 
699
  chan = get_channel(idx, par);
 
700
  if (!chan || !has_oporhalfop(idx, chan))
482
701
    return;
 
702
 
483
703
  putlog(LOG_CMDS, "*", "#%s# (%s) invite %s", dcc[idx].nick, chan->dname,
484
 
         nick);
485
 
  if (!me_op(chan)) {
 
704
         nick);
 
705
  if (!me_op(chan) && !me_halfop(chan)) {
486
706
    if (chan->channel.mode & CHANINV) {
487
 
      dprintf(idx, "I can't help you now because I'm not a channel op on %s.\n",
488
 
              chan->dname);
 
707
      dprintf(idx, "I can't help you now because I'm not a channel op or "
 
708
              "halfop on %s.\n", chan->dname);
489
709
      return;
490
710
    }
491
711
    if (!channel_active(chan)) {
504
724
 
505
725
static void cmd_channel(struct userrec *u, int idx, char *par)
506
726
{
507
 
  char handle[HANDLEN + 1], s[UHOSTLEN], s1[UHOSTLEN], atrflag, chanflag,
508
 
       *chname;
 
727
  char handle[HANDLEN + 1], s[UHOSTLEN], s1[UHOSTLEN], atrflag, chanflag;
509
728
  struct chanset_t *chan;
510
729
  memberlist *m;
511
 
  static char spaces[33] = "                              ";
512
 
  static char spaces2[33] = "                              ";
513
 
  int len, len2;
 
730
  int maxnicklen, maxhandlen;
 
731
  char format[81];
514
732
 
515
 
  if (!has_op(idx, par))
516
 
    return;
517
 
  chname = newsplit(&par);
518
 
  putlog(LOG_CMDS, "*", "#%s# (%s) channel %s", dcc[idx].nick,
519
 
         dcc[idx].u.chat->con_chan, chname);
520
 
  if (!chname[0])
521
 
    chan = findchan_by_dname(dcc[idx].u.chat->con_chan);
522
 
  else
523
 
    chan = findchan_by_dname(chname);
524
 
  if (chan == NULL) {
525
 
    dprintf(idx, "%s %s\n", IRC_NOTACTIVECHAN, chname);
526
 
    return;
527
 
  }
 
733
  chan = get_channel(idx, par);
 
734
  if (!chan || !has_oporhalfop(idx, chan))
 
735
    return;
 
736
  putlog(LOG_CMDS, "*", "#%s# (%s) channel", dcc[idx].nick, chan->dname);
528
737
  strncpyz(s, getchanmode(chan), sizeof s);
529
738
  if (channel_pending(chan))
530
739
    egg_snprintf(s1, sizeof s1, "%s %s", IRC_PROCESSINGCHAN, chan->dname);
533
742
  else
534
743
    egg_snprintf(s1, sizeof s1, "%s %s", IRC_DESIRINGCHAN, chan->dname);
535
744
  dprintf(idx, "%s, %d member%s, mode %s:\n", s1, chan->channel.members,
536
 
          chan->channel.members == 1 ? "" : "s", s);
 
745
          chan->channel.members == 1 ? "" : "s", s);
537
746
  if (chan->channel.topic)
538
747
    dprintf(idx, "%s: %s\n", IRC_CHANNELTOPIC, chan->channel.topic);
539
748
  if (channel_active(chan)) {
 
749
    /* find max nicklen and handlen */
 
750
    maxnicklen = maxhandlen = 0;
 
751
    for (m = chan->channel.member; m && m->nick[0]; m = m->next) {
 
752
      if (strlen(m->nick) > maxnicklen)
 
753
        maxnicklen = strlen(m->nick);
 
754
      if ((m->user) && (strlen(m->user->handle) > maxhandlen))
 
755
        maxhandlen = strlen(m->user->handle);
 
756
    }
 
757
    if (maxnicklen < 9)
 
758
      maxnicklen = 9;
 
759
    if (maxhandlen < 9)
 
760
      maxhandlen = 9;
 
761
 
540
762
    dprintf(idx, "(n = owner, m = master, o = op, d = deop, b = bot)\n");
541
 
    spaces[nick_len - 9] = 0;
542
 
    spaces2[HANDLEN - 9] = 0;
543
 
    dprintf(idx, " NICKNAME %s HANDLE   %s JOIN   IDLE  USER@HOST\n",
544
 
            spaces, spaces2);
545
 
    spaces[nick_len - 9] = ' ';
546
 
    spaces2[HANDLEN - 9] = ' ';
 
763
    egg_snprintf(format, sizeof format, " %%-%us %%-%us %%-6s %%-5s %%s\n",
 
764
                 maxnicklen, maxhandlen);
 
765
    dprintf(idx, format, "NICKNAME", "HANDLE", " JOIN", "IDLE", "USER@HOST");
547
766
    for (m = chan->channel.member; m && m->nick[0]; m = m->next) {
548
767
      if (m->joined > 0) {
549
 
        if ((now - (m->joined)) > 86400)
550
 
          egg_strftime(s, 6, "%d%b", localtime(&(m->joined)));
551
 
        else
552
 
          egg_strftime(s, 6, "%H:%M", localtime(&(m->joined)));
 
768
        if ((now - (m->joined)) > 86400)
 
769
          egg_strftime(s, 6, "%d%b", localtime(&(m->joined)));
 
770
        else
 
771
          egg_strftime(s, 6, "%H:%M", localtime(&(m->joined)));
553
772
      } else
554
 
        strncpyz(s, " --- ", sizeof s);
555
 
      if (m->user == NULL) {
556
 
        egg_snprintf(s1, sizeof s1, "%s!%s", m->nick, m->userhost);
557
 
        m->user = get_user_by_host(s1);
558
 
      }
559
 
      if (m->user == NULL) {
560
 
        strncpyz(handle, "*", sizeof handle);
561
 
      } else {
562
 
        strncpyz(handle, m->user->handle, sizeof handle);
563
 
      }
 
773
        strncpyz(s, " --- ", sizeof s);
 
774
      if (m->user == NULL) {
 
775
        egg_snprintf(s1, sizeof s1, "%s!%s", m->nick, m->userhost);
 
776
        m->user = get_user_by_host(s1);
 
777
      }
 
778
      if (m->user == NULL)
 
779
        strncpyz(handle, "*", sizeof handle);
 
780
      else
 
781
        strncpyz(handle, m->user->handle, sizeof handle);
564
782
      get_user_flagrec(m->user, &user, chan->dname);
565
783
      /* Determine status char to use */
566
 
      if (glob_bot(user) && (glob_op(user)||chan_op(user)))
567
 
        atrflag = 'B';
 
784
      if (glob_bot(user) && (glob_op(user) || chan_op(user)))
 
785
        atrflag = 'B';
568
786
      else if (glob_bot(user))
569
 
        atrflag = 'b';
 
787
        atrflag = 'b';
570
788
      else if (glob_owner(user))
571
 
        atrflag = 'N';
 
789
        atrflag = 'N';
572
790
      else if (chan_owner(user))
573
 
        atrflag = 'n';
 
791
        atrflag = 'n';
574
792
      else if (glob_master(user))
575
 
        atrflag = 'M';
 
793
        atrflag = 'M';
576
794
      else if (chan_master(user))
577
 
        atrflag = 'm';
 
795
        atrflag = 'm';
578
796
      else if (glob_deop(user))
579
 
        atrflag = 'D';
 
797
        atrflag = 'D';
580
798
      else if (chan_deop(user))
581
 
        atrflag = 'd';
 
799
        atrflag = 'd';
 
800
      else if (glob_dehalfop(user))
 
801
        atrflag = 'R';
 
802
      else if (chan_dehalfop(user))
 
803
        atrflag = 'r';
582
804
      else if (glob_autoop(user))
583
 
        atrflag = 'A';
 
805
        atrflag = 'A';
 
806
      else if (chan_autohalfop(user))
 
807
        atrflag = 'y';
 
808
      else if (glob_autohalfop(user))
 
809
        atrflag = 'Y';
584
810
      else if (chan_autoop(user))
585
 
        atrflag = 'a';
 
811
        atrflag = 'a';
586
812
      else if (glob_op(user))
587
 
        atrflag = 'O';
 
813
        atrflag = 'O';
588
814
      else if (chan_op(user))
589
 
        atrflag = 'o';
 
815
        atrflag = 'o';
 
816
      else if (glob_halfop(user))
 
817
        atrflag = 'L';
 
818
      else if (chan_halfop(user))
 
819
        atrflag = 'l';
590
820
      else if (glob_quiet(user))
591
 
        atrflag = 'Q';
 
821
        atrflag = 'Q';
592
822
      else if (chan_quiet(user))
593
 
        atrflag = 'q';
 
823
        atrflag = 'q';
594
824
      else if (glob_gvoice(user))
595
 
        atrflag = 'G';
 
825
        atrflag = 'G';
596
826
      else if (chan_gvoice(user))
597
 
        atrflag = 'g';
 
827
        atrflag = 'g';
598
828
      else if (glob_voice(user))
599
 
        atrflag = 'V';
 
829
        atrflag = 'V';
600
830
      else if (chan_voice(user))
601
 
        atrflag = 'v';
 
831
        atrflag = 'v';
602
832
      else if (glob_friend(user))
603
833
        atrflag = 'F';
604
834
      else if (chan_friend(user))
616
846
      else if (chan_exempt(user))
617
847
        atrflag = 'e';
618
848
      else
619
 
        atrflag = ' ';
 
849
        atrflag = ' ';
620
850
      if (chan_hasop(m))
621
 
        chanflag = '@';
 
851
        chanflag = '@';
 
852
      else if (chan_hashalfop(m))
 
853
        chanflag = '%';
622
854
      else if (chan_hasvoice(m))
623
 
        chanflag = '+';
 
855
        chanflag = '+';
624
856
      else
625
 
        chanflag = ' ';
626
 
      spaces[len = (nick_len - strlen(m->nick))] = 0;
627
 
      spaces2[len2 = (HANDLEN - strlen(handle))] = 0;
628
 
      if (chan_issplit(m))
629
 
        dprintf(idx, "%c%s%s %s%s %s %c     <- netsplit, %lus\n", chanflag,
630
 
                m->nick, spaces, handle, spaces2, s, atrflag,
631
 
                now - (m->split));
632
 
      else if (!rfc_casecmp(m->nick, botname))
633
 
        dprintf(idx, "%c%s%s %s%s %s %c     <- it's me!\n", chanflag, m->nick,
634
 
                spaces, handle, spaces2, s, atrflag);
635
 
      else {
636
 
        /* Determine idle time */
637
 
        if (now - (m->last) > 86400)
638
 
          egg_snprintf(s1, sizeof s1, "%2lud", ((now - (m->last)) / 86400));
639
 
        else if (now - (m->last) > 3600)
640
 
          egg_snprintf(s1, sizeof s1, "%2luh", ((now - (m->last)) / 3600));
641
 
        else if (now - (m->last) > 180)
642
 
          egg_snprintf(s1, sizeof s1, "%2lum", ((now - (m->last)) / 60));
643
 
        else
644
 
          strncpyz(s1, "   ", sizeof s1);
645
 
        dprintf(idx, "%c%s%s %s%s %s %c %s  %s\n", chanflag, m->nick,
646
 
                spaces, handle, spaces2, s, atrflag, s1, m->userhost);
 
857
        chanflag = ' ';
 
858
      if (chan_issplit(m)) {
 
859
        egg_snprintf(format, sizeof format,
 
860
                     "%%c%%-%us %%-%us %%s %%c     <- netsplit, %%lus\n",
 
861
                     maxnicklen, maxhandlen);
 
862
        dprintf(idx, format, chanflag, m->nick, handle, s, atrflag,
 
863
                now - (m->split));
 
864
      } else if (!rfc_casecmp(m->nick, botname)) {
 
865
        egg_snprintf(format, sizeof format,
 
866
                     "%%c%%-%us %%-%us %%s %%c     <- it's me!\n",
 
867
                     maxnicklen, maxhandlen);
 
868
        dprintf(idx, format, chanflag, m->nick, handle, s, atrflag);
 
869
      } else {
 
870
        /* Determine idle time */
 
871
        if (now - (m->last) > 86400)
 
872
          egg_snprintf(s1, sizeof s1, "%2lud", ((now - (m->last)) / 86400));
 
873
        else if (now - (m->last) > 3600)
 
874
          egg_snprintf(s1, sizeof s1, "%2luh", ((now - (m->last)) / 3600));
 
875
        else if (now - (m->last) > 180)
 
876
          egg_snprintf(s1, sizeof s1, "%2lum", ((now - (m->last)) / 60));
 
877
        else
 
878
          strncpyz(s1, "   ", sizeof s1);
 
879
        egg_snprintf(format, sizeof format,
 
880
                     "%%c%%-%us %%-%us %%s %%c %%s  %%s\n", maxnicklen,
 
881
                     maxhandlen);
 
882
        dprintf(idx, format, chanflag, m->nick, handle, s, atrflag, s1,
 
883
                m->userhost);
647
884
      }
648
 
      spaces[len] = ' ';
649
 
      spaces2[len2] = ' ';
650
885
      if (chan_fakeop(m))
651
 
        dprintf(idx, "    (%s)\n", IRC_FAKECHANOP);
 
886
        dprintf(idx, "    (%s)\n", IRC_FAKECHANOP);
652
887
      if (chan_sentop(m))
653
 
        dprintf(idx, "    (%s)\n", IRC_PENDINGOP);
 
888
        dprintf(idx, "    (%s)\n", IRC_PENDINGOP);
654
889
      if (chan_sentdeop(m))
655
 
        dprintf(idx, "    (%s)\n", IRC_PENDINGDEOP);
 
890
        dprintf(idx, "    (%s)\n", IRC_PENDINGDEOP);
656
891
      if (chan_sentkick(m))
657
 
        dprintf(idx, "    (%s)\n", IRC_PENDINGKICK);
 
892
        dprintf(idx, "    (%s)\n", IRC_PENDINGKICK);
658
893
    }
659
894
  }
660
895
  dprintf(idx, "%s\n", IRC_ENDCHANINFO);
666
901
 
667
902
  if (par[0] && (strchr(CHANMETA, par[0]) != NULL)) {
668
903
    char *chname = newsplit(&par);
669
 
    chan = has_op(idx, chname);
 
904
 
 
905
    chan = get_channel(idx, chname);
670
906
  } else
671
 
    chan = has_op(idx, "");
672
 
  if (chan) {
673
 
    if (!channel_active(chan)) {
674
 
      dprintf(idx, "I'm not on %s right now!\n", chan->dname);
675
 
      return;
676
 
    }
677
 
    if (!par[0]) {
678
 
      if (chan->channel.topic) {
679
 
        dprintf(idx, "The topic for %s is: %s\n", chan->dname,
680
 
                chan->channel.topic);
681
 
      } else {
682
 
        dprintf(idx, "No topic is set for %s\n", chan->dname);
683
 
      }
684
 
    } else if (channel_optopic(chan) && !me_op(chan)) {
685
 
      dprintf(idx, "I'm not a channel op on %s and the channel is +t.\n",
686
 
              chan->dname);
687
 
    } else {
688
 
      dprintf(DP_SERVER, "TOPIC %s :%s\n", chan->name, par);
689
 
      dprintf(idx, "Changing topic...\n");
690
 
      putlog(LOG_CMDS, "*", "#%s# (%s) topic %s", dcc[idx].nick,
691
 
             chan->dname, par);
692
 
    }
 
907
    chan = get_channel(idx, "");
 
908
 
 
909
  if (!chan || !has_oporhalfop(idx, chan))
 
910
    return;
 
911
 
 
912
  if (!channel_active(chan)) {
 
913
    dprintf(idx, "I'm not on %s right now!\n", chan->dname);
 
914
    return;
 
915
  }
 
916
  if (!par[0]) {
 
917
    if (chan->channel.topic)
 
918
      dprintf(idx, "The topic for %s is: %s\n", chan->dname,
 
919
              chan->channel.topic);
 
920
    else
 
921
      dprintf(idx, "No topic is set for %s\n", chan->dname);
 
922
  } else if (channel_optopic(chan) && !me_op(chan) && !me_halfop(chan))
 
923
    dprintf(idx, "I'm not a channel op or halfop on %s and the channel is "
 
924
            "+t.\n", chan->dname);
 
925
  else {
 
926
    dprintf(DP_SERVER, "TOPIC %s :%s\n", chan->name, par);
 
927
    dprintf(idx, "Changing topic...\n");
 
928
    putlog(LOG_CMDS, "*", "#%s# (%s) topic %s", dcc[idx].nick,
 
929
           chan->dname, par);
693
930
  }
694
931
}
695
932
 
696
933
static void cmd_resetbans(struct userrec *u, int idx, char *par)
697
934
{
698
 
  char *chname;
699
935
  struct chanset_t *chan;
700
 
 
701
 
  chname = newsplit(&par);
702
 
  rmspace(chname);
703
 
 
704
 
  if (chname[0]) {
705
 
    chan = findchan_by_dname(chname);
706
 
    if (!chan) {
707
 
      dprintf(idx, "That channel doesn't exist!\n");
708
 
      return;
709
 
    }
710
 
    get_user_flagrec(u, &user, chname);
711
 
  } else {
712
 
    chan = findchan_by_dname(dcc[idx].u.chat->con_chan);
713
 
    if (!chan) {
714
 
      dprintf(idx, "Invalid console channel.\n");
715
 
      return;
716
 
    }
717
 
    get_user_flagrec(u, &user, dcc[idx].u.chat->con_chan);
718
 
  }
719
 
  if (glob_op(user) || chan_op(user)) {
720
 
    putlog(LOG_CMDS, "*", "#%s# (%s) resetbans", dcc[idx].nick, chan->dname);
721
 
    dprintf(idx, "Resetting bans on %s...\n", chan->dname);
722
 
    resetbans(chan);
723
 
  }
 
936
  char *chname = newsplit(&par);
 
937
 
 
938
  chan = get_channel(idx, chname);
 
939
  if (!chan || !has_oporhalfop(idx, chan))
 
940
    return;
 
941
 
 
942
  putlog(LOG_CMDS, "*", "#%s# (%s) resetbans", dcc[idx].nick, chan->dname);
 
943
  dprintf(idx, "Resetting bans on %s...\n", chan->dname);
 
944
  resetbans(chan);
724
945
}
725
946
 
726
947
static void cmd_resetexempts(struct userrec *u, int idx, char *par)
727
948
{
728
 
  char *chname;
729
949
  struct chanset_t *chan;
730
 
 
731
 
  chname = newsplit(&par);
732
 
  rmspace(chname);
733
 
  if (chname[0]) {
734
 
    chan = findchan_by_dname(chname);
735
 
    if (!chan) {
736
 
      dprintf(idx, "That channel doesn't exist!\n");
737
 
      return;
738
 
    }
739
 
    get_user_flagrec(u, &user, chname);
740
 
  } else {
741
 
    chan = findchan_by_dname(dcc[idx].u.chat->con_chan);
742
 
    if (!chan) {
743
 
    dprintf(idx, "Invalid console channel.\n");
744
 
      return;
745
 
    }
746
 
    get_user_flagrec(u, &user, dcc[idx].u.chat->con_chan);
747
 
  }
748
 
  if (glob_op(user) || chan_op(user)) {
749
 
    putlog(LOG_CMDS, "*", "#%s# (%s) resetexempts", dcc[idx].nick, chan->dname);
750
 
    dprintf(idx, "Resetting exemptions on %s...\n", chan->dname);
751
 
    resetexempts(chan);
752
 
  }
 
950
  char *chname = newsplit(&par);
 
951
 
 
952
  chan = get_channel(idx, chname);
 
953
  if (!chan || !has_oporhalfop(idx, chan))
 
954
    return;
 
955
 
 
956
  putlog(LOG_CMDS, "*", "#%s# (%s) resetexempts", dcc[idx].nick, chan->dname);
 
957
  dprintf(idx, "Resetting exempts on %s...\n", chan->dname);
 
958
  resetexempts(chan);
753
959
}
754
960
 
755
961
static void cmd_resetinvites(struct userrec *u, int idx, char *par)
756
962
{
757
 
  char *chname;
758
963
  struct chanset_t *chan;
759
 
 
760
 
  chname = newsplit(&par);
761
 
  rmspace(chname);
762
 
  if (chname[0]) {
763
 
    chan = findchan_by_dname(chname);
764
 
    if (!chan) {
765
 
      dprintf(idx, "That channel doesn't exist!\n");
766
 
      return;
767
 
    }
768
 
    get_user_flagrec(u, &user, chname);
769
 
  } else {
770
 
    chan = findchan_by_dname(dcc[idx].u.chat->con_chan);
771
 
    if (!chan) {
772
 
    dprintf(idx, "Invalid console channel.\n");
773
 
      return;
774
 
    }
775
 
    get_user_flagrec(u, &user, dcc[idx].u.chat->con_chan);
776
 
  }
777
 
  if (glob_op(user) || chan_op(user)) {
778
 
    putlog(LOG_CMDS, "*", "#%s# (%s) resetinvites", dcc[idx].nick, chan->dname);
779
 
    dprintf(idx, "Resetting invitations on %s...\n", chan->dname);
780
 
    resetinvites(chan);
781
 
  }
 
964
  char *chname = newsplit(&par);
 
965
 
 
966
  chan = get_channel(idx, chname);
 
967
  if (!chan || !has_oporhalfop(idx, chan))
 
968
    return;
 
969
 
 
970
  putlog(LOG_CMDS, "*", "#%s# (%s) resetinvites", dcc[idx].nick, chan->dname);
 
971
  dprintf(idx, "Resetting resetinvites on %s...\n", chan->dname);
 
972
  resetinvites(chan);
782
973
}
783
974
 
784
975
static void cmd_adduser(struct userrec *u, int idx, char *par)
791
982
  int statichost = 0;
792
983
  char *p1 = s1;
793
984
 
794
 
  if ((!par[0]) || ((par[0]=='!') && (!par[1]))) {
 
985
  if ((!par[0]) || ((par[0] == '!') && (!par[1]))) {
795
986
    dprintf(idx, "Usage: adduser <nick> [handle]\n");
796
987
    return;
797
988
  }
811
1002
 
812
1003
    for (p = par; *p; p++)
813
1004
      if ((*p <= 32) || (*p >= 127))
814
 
        ok = 0;
 
1005
        ok = 0;
815
1006
    if (!ok) {
816
1007
      dprintf(idx, "You can't have strange characters in a nick.\n");
817
1008
      return;
840
1031
    return;
841
1032
  }
842
1033
  u = get_user_by_handle(userlist, hand);
843
 
  if (u && (u->flags & (USER_OWNER|USER_MASTER)) &&
 
1034
  if (u && (u->flags & (USER_OWNER | USER_MASTER)) &&
844
1035
      !(atr & USER_OWNER) && egg_strcasecmp(dcc[idx].nick, hand)) {
845
1036
    dprintf(idx, "You can't add hostmasks to the bot owner/master.\n");
846
1037
    return;
852
1043
    p1 = strchr(s1, '!');
853
1044
    if (strchr("~^+=-", p1[1])) {
854
1045
      if (strict_host)
855
 
        p1[1] = '?';
 
1046
        p1[1] = '?';
856
1047
      else {
857
 
        p1[1] = '!';
858
 
        p1++;
 
1048
        p1[1] = '!';
 
1049
        p1++;
859
1050
      }
860
1051
    }
861
1052
    p1--;
871
1062
    check_this_user(hand, 0, NULL);
872
1063
  }
873
1064
  putlog(LOG_CMDS, "*", "#%s# adduser %s %s", dcc[idx].nick, nick,
874
 
         hand == nick ? "" : hand);
 
1065
         hand == nick ? "" : hand);
875
1066
}
876
1067
 
877
1068
static void cmd_deluser(struct userrec *u, int idx, char *par)
879
1070
  char *nick, s[UHOSTLEN];
880
1071
  struct chanset_t *chan;
881
1072
  memberlist *m = NULL;
882
 
  struct flag_record victim = {FR_GLOBAL | FR_CHAN | FR_ANYWH, 0, 0, 0, 0, 0};
 
1073
  struct flag_record victim = { FR_GLOBAL | FR_CHAN | FR_ANYWH, 0, 0, 0, 0, 0 };
883
1074
 
884
1075
  if (!par[0]) {
885
1076
    dprintf(idx, "Usage: deluser <nick>\n");
913
1104
  /* Shouldn't allow people to remove permanent owners (guppy 9Jan1999) */
914
1105
  if ((glob_owner(victim) && egg_strcasecmp(dcc[idx].nick, nick)) ||
915
1106
      isowner(u->handle)) {
916
 
    dprintf(idx, "Can't remove the bot owner!\n");
 
1107
    dprintf(idx, "You can't remove a bot owner!\n");
917
1108
  } else if (glob_botmast(victim) && !glob_owner(user)) {
918
 
    dprintf(idx, "Can't delete a master!\n");
 
1109
    dprintf(idx, "You can't remove a bot master!\n");
919
1110
  } else if (chan_owner(victim) && !glob_owner(user)) {
920
 
    dprintf(idx, "Can't remove a channel owner!\n");
 
1111
    dprintf(idx, "You can't remove a channel owner!\n");
921
1112
  } else if (chan_master(victim) && !(glob_owner(user) || chan_owner(user))) {
922
 
    dprintf(idx, "Can't delete a channel master!\n");
 
1113
    dprintf(idx, "You can't remove a channel master!\n");
923
1114
  } else if (glob_bot(victim) && !glob_owner(user)) {
924
 
    dprintf(idx, "Can't delete a bot!\n");
 
1115
    dprintf(idx, "You can't remove a bot!\n");
925
1116
  } else {
926
1117
    char buf[HANDLEN + 1];
927
1118
 
928
1119
    strncpyz(buf, u->handle, sizeof buf);
929
1120
    buf[HANDLEN] = 0;
930
1121
    if (deluser(u->handle)) {
931
 
      dprintf(idx, "Deleted %s.\n", buf); /* ?!?! :) */
 
1122
      dprintf(idx, "Deleted %s.\n", buf);       /* ?!?! :) */
932
1123
      putlog(LOG_CMDS, "*", "#%s# deluser %s [%s]", dcc[idx].nick, nick, buf);
933
 
    } else {
 
1124
    } else
934
1125
      dprintf(idx, "Failed.\n");
935
 
    }
936
1126
  }
937
1127
}
938
1128
 
946
1136
      dprintf(idx, "%s\n", IRC_NOMONITOR);
947
1137
    else {
948
1138
      get_user_flagrec(u, &user, par);
949
 
      if (!glob_master(user) && !chan_master(user)) {
950
 
        dprintf(idx, "You are not a master on %s.\n", chan->dname);
951
 
      } else if (!channel_active(chan)) {
952
 
        dprintf(idx, "I'm not on %s at the moment!\n", chan->dname);
953
 
      } else {
954
 
        putlog(LOG_CMDS, "*", "#%s# reset %s", dcc[idx].nick, par);
955
 
        dprintf(idx, "Resetting channel info for %s...\n", chan->dname);
956
 
        reset_chan_info(chan);
 
1139
      if (!glob_master(user) && !chan_master(user))
 
1140
        dprintf(idx, "You are not a master on %s.\n", chan->dname);
 
1141
      else if (!channel_active(chan))
 
1142
        dprintf(idx, "I'm not on %s at the moment!\n", chan->dname);
 
1143
      else {
 
1144
        putlog(LOG_CMDS, "*", "#%s# reset %s", dcc[idx].nick, par);
 
1145
        dprintf(idx, "Resetting channel info for %s...\n", chan->dname);
 
1146
        reset_chan_info(chan);
957
1147
      }
958
1148
    }
959
 
  } else if (!(u->flags & USER_MASTER)) {
 
1149
  } else if (!(u->flags & USER_MASTER))
960
1150
    dprintf(idx, "You are not a Bot Master.\n");
961
 
  } else {
 
1151
  else {
962
1152
    putlog(LOG_CMDS, "*", "#%s# reset all", dcc[idx].nick);
963
1153
    dprintf(idx, "Resetting channel info for all channels...\n");
964
1154
    for (chan = chanset; chan; chan = chan->next) {
965
1155
      if (channel_active(chan))
966
 
        reset_chan_info(chan);
 
1156
        reset_chan_info(chan);
967
1157
    }
968
1158
  }
969
1159
}
970
1160
 
971
 
static cmd_t irc_dcc[] =
972
 
{
973
 
  {"adduser",           "m|m",  (Function) cmd_adduser,         NULL},
974
 
  {"deluser",           "m|m",  (Function) cmd_deluser,         NULL},
975
 
  {"reset",             "m|m",  (Function) cmd_reset,           NULL},
976
 
  {"resetbans",         "o|o",  (Function) cmd_resetbans,       NULL},
977
 
  {"resetexempts",      "o|o",  (Function) cmd_resetexempts,    NULL},
978
 
  {"resetinvites",      "o|o",  (Function) cmd_resetinvites,    NULL},
979
 
  {"act",               "o|o",  (Function) cmd_act,             NULL},
980
 
  {"channel",           "o|o",  (Function) cmd_channel,         NULL},
981
 
  {"deop",              "o|o",  (Function) cmd_deop,            NULL},
982
 
  {"invite",            "o|o",  (Function) cmd_invite,          NULL},
983
 
  {"kick",              "o|o",  (Function) cmd_kick,            NULL},
984
 
  {"kickban",           "o|o",  (Function) cmd_kickban,         NULL},
985
 
  {"msg",               "o",    (Function) cmd_msg,             NULL},
986
 
  {"voice",             "o|o",  (Function) cmd_voice,           NULL},
987
 
  {"devoice",           "o|o",  (Function) cmd_devoice,         NULL},
988
 
  {"op",                "o|o",  (Function) cmd_op,              NULL},
989
 
  {"say",               "o|o",  (Function) cmd_say,             NULL},
990
 
  {"topic",             "o|o",  (Function) cmd_topic,           NULL},
991
 
  {NULL,                NULL,   NULL,                           NULL}
 
1161
static cmd_t irc_dcc[] = {
 
1162
  {"adduser",      "m|m",   (Function) cmd_adduser,      NULL},
 
1163
  {"deluser",      "m|m",   (Function) cmd_deluser,      NULL},
 
1164
  {"reset",        "m|m",   (Function) cmd_reset,        NULL},
 
1165
  {"resetbans",    "o|o",   (Function) cmd_resetbans,    NULL},
 
1166
  {"resetexempts", "o|o",   (Function) cmd_resetexempts, NULL},
 
1167
  {"resetinvites", "o|o",   (Function) cmd_resetinvites, NULL},
 
1168
  {"act",          "o|o",   (Function) cmd_act,          NULL},
 
1169
  {"channel",      "o|o",   (Function) cmd_channel,      NULL},
 
1170
  {"op",           "o|o",   (Function) cmd_op,           NULL},
 
1171
  {"deop",         "o|o",   (Function) cmd_deop,         NULL},
 
1172
  {"halfop",       "ol|ol", (Function) cmd_halfop,       NULL},
 
1173
  {"dehalfop",     "ol|ol", (Function) cmd_dehalfop,     NULL},
 
1174
  {"voice",        "ov|ov", (Function) cmd_voice,        NULL},
 
1175
  {"devoice",      "ov|ov", (Function) cmd_devoice,      NULL},
 
1176
  {"invite",       "o|o",   (Function) cmd_invite,       NULL},
 
1177
  {"kick",         "lo|lo", (Function) cmd_kick,         NULL},
 
1178
  {"kickban",      "lo|lo", (Function) cmd_kickban,      NULL},
 
1179
  {"msg",          "o",     (Function) cmd_msg,          NULL},
 
1180
  {"say",          "o|o",   (Function) cmd_say,          NULL},
 
1181
  {"topic",        "lo|lo",   (Function) cmd_topic,        NULL},
 
1182
  {NULL,           NULL,    NULL,                        NULL}
992
1183
};