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

« back to all changes in this revision

Viewing changes to src/tcldcc.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
 * tcldcc.c -- handles:
3
3
 *   Tcl stubs for the dcc commands
4
4
 *
5
 
 * $Id: tcldcc.c,v 1.33 2002/01/02 03:46:36 guppy Exp $
 
5
 * $Id: tcldcc.c,v 1.51 2004/04/06 06: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
27
27
#include "tandem.h"
28
28
#include "modules.h"
29
29
 
30
 
extern Tcl_Interp       *interp;
31
 
extern tcl_timer_t      *timer,
32
 
                        *utimer;
33
 
extern struct dcc_t     *dcc;
34
 
extern int               dcc_total, backgrd, parties, make_userfile,
35
 
                         do_restart, remote_boots, max_dcc;
36
 
extern char              botnetnick[];
37
 
extern party_t          *party;
38
 
extern tand_t           *tandbot;
39
 
extern time_t            now;
40
 
 
41
 
/* Traffic stuff. */
42
 
extern unsigned long otraffic_irc, otraffic_irc_today, itraffic_irc, itraffic_irc_today, otraffic_bn, otraffic_bn_today, itraffic_bn, itraffic_bn_today, otraffic_dcc, otraffic_dcc_today, itraffic_dcc, itraffic_dcc_today, otraffic_trans, otraffic_trans_today, itraffic_trans, itraffic_trans_today, otraffic_unknown, otraffic_unknown_today, itraffic_unknown, itraffic_unknown_today;
43
 
 
44
 
int                      enable_simul = 0;
45
 
static struct portmap   *root = NULL;
 
30
extern Tcl_Interp *interp;
 
31
extern tcl_timer_t *timer, *utimer;
 
32
extern struct dcc_t *dcc;
 
33
extern char botnetnick[];
 
34
extern int dcc_total, backgrd, parties, make_userfile, do_restart, max_dcc,
 
35
           remote_boots;
 
36
extern party_t *party;
 
37
extern tand_t *tandbot;
 
38
extern time_t now;
 
39
extern unsigned long otraffic_irc, otraffic_irc_today, itraffic_irc,
 
40
                     itraffic_irc_today, otraffic_bn, otraffic_bn_today,
 
41
                     itraffic_bn, itraffic_bn_today, otraffic_dcc,
 
42
                     otraffic_dcc_today, itraffic_dcc, itraffic_dcc_today,
 
43
                     otraffic_trans, otraffic_trans_today, itraffic_trans,
 
44
                     itraffic_trans_today, otraffic_unknown, itraffic_unknown,
 
45
                     otraffic_unknown_today, itraffic_unknown_today;
 
46
static struct portmap *root = NULL;
46
47
 
47
48
 
48
49
int expmem_tcldcc(void)
56
57
  return tot;
57
58
}
58
59
 
59
 
/***********************************************************************/
60
 
 
61
60
static int tcl_putdcc STDVAR
62
61
{
63
62
  int i, j;
64
63
 
65
64
  BADARGS(3, 3, " idx text");
 
65
 
66
66
  i = atoi(argv[1]);
67
67
  j = findidx(i);
68
68
  if (j < 0) {
70
70
    return TCL_ERROR;
71
71
  }
72
72
  dumplots(-i, "", argv[2]);
 
73
 
73
74
  return TCL_OK;
74
75
}
75
76
 
76
 
/* Allows tcl scripts to send out raw data. Can be used for fast server
77
 
 * write (idx=0)
78
 
 *
79
 
 * usage:
80
 
 *      putdccraw <idx> <size> <rawdata>
81
 
 * example:
82
 
 *      putdccraw 6 13 "eggdrop rulz\n"
83
 
 *
84
 
 * (added by drummer@sophia.jpte.hu)
 
77
/* Allows tcl scripts to send out raw data. Can be used for fast server write.
 
78
 * The server idx is 0.
 
79
 *
 
80
 * Usage: putdccraw <idx> <size> <rawdata>
 
81
 *
 
82
 * Example: putdccraw 6 13 "eggdrop rulz\n"
 
83
 *
 
84
 * Added by <drummer@sophia.jpte.hu>.
85
85
 */
86
 
 
87
86
static int tcl_putdccraw STDVAR
88
87
{
89
88
  int i, j = 0, z;
90
89
 
91
90
  BADARGS(4, 4, " idx size text");
 
91
 
92
92
  z = atoi(argv[1]);
93
93
  for (i = 0; i < dcc_total; i++) {
94
94
    if (!z && !strcmp(dcc[i].nick, "(server)")) {
109
109
 
110
110
static int tcl_dccsimul STDVAR
111
111
{
 
112
  int idx;
 
113
 
112
114
  BADARGS(3, 3, " idx command");
113
 
  if (enable_simul) {
114
 
    int idx = findidx(atoi(argv[1]));
115
 
 
116
 
    if (idx >= 0 && (dcc[idx].type->flags & DCT_SIMUL)) {
117
 
      int l = strlen(argv[2]);
118
 
 
119
 
      if (l > 510) {
120
 
        l = 510;
121
 
        argv[2][510] = 0;       /* Restrict length of cmd */
122
 
      }
123
 
      if (dcc[idx].type && dcc[idx].type->activity) {
124
 
        dcc[idx].type->activity(idx, argv[2], l);
125
 
        return TCL_OK;
126
 
      }
127
 
    } else
 
115
 
 
116
  idx = findidx(atoi(argv[1]));
 
117
  if (idx >= 0 && (dcc[idx].type->flags & DCT_SIMUL)) {
 
118
    int l = strlen(argv[2]);
 
119
 
 
120
    if (l > 510) {
 
121
      l = 510;
 
122
      argv[2][510] = 0;        /* Restrict length of cmd */
 
123
    }
 
124
    if (dcc[idx].type && dcc[idx].type->activity) {
 
125
      dcc[idx].type->activity(idx, argv[2], l);
 
126
      return TCL_OK;
 
127
    }
 
128
  } else
128
129
      Tcl_AppendResult(irp, "invalid idx", NULL);
129
 
  } else
130
 
    Tcl_AppendResult(irp, "simul disabled", NULL);
131
130
  return TCL_ERROR;
132
131
}
133
132
 
 
133
 
134
134
static int tcl_dccbroadcast STDVAR
135
135
{
136
136
  char msg[401];
137
137
 
138
138
  BADARGS(2, 2, " message");
 
139
 
139
140
  strncpyz(msg, argv[1], sizeof msg);
140
141
  chatout("*** %s\n", msg);
141
142
  botnet_send_chat(-1, botnetnick, msg);
148
149
  char s[11];
149
150
 
150
151
  BADARGS(2, 2, " nickname");
 
152
 
151
153
  for (i = 0; i < dcc_total; i++)
152
 
    if ((dcc[i].type->flags & DCT_SIMUL) &&
 
154
    if ((dcc[i].type->flags & (DCT_SIMUL | DCT_BOT)) &&
153
155
        !egg_strcasecmp(argv[1], dcc[i].nick)) {
154
156
      egg_snprintf(s, sizeof s, "%ld", dcc[i].sock);
155
157
      Tcl_AppendResult(irp, s, NULL);
165
167
  int idx;
166
168
 
167
169
  BADARGS(2, 2, " idx");
 
170
 
168
171
  idx = findidx(atoi(argv[1]));
169
 
  if (idx < 0 ||
170
 
      (dcc[idx].type != &DCC_CHAT && dcc[idx].type != &DCC_SCRIPT)) {
 
172
  if (idx < 0 || (dcc[idx].type != &DCC_CHAT &&
 
173
      dcc[idx].type != &DCC_SCRIPT)) {
171
174
    Tcl_AppendResult(irp, "invalid idx", NULL);
172
175
    return TCL_ERROR;
173
176
  }
 
177
 
174
178
  if (dcc[idx].type == &DCC_SCRIPT)
175
179
    egg_snprintf(s, sizeof s, "%d", dcc[idx].u.script->u.chat->channel);
176
180
  else
177
181
    egg_snprintf(s, sizeof s, "%d", dcc[idx].u.chat->channel);
 
182
 
178
183
  Tcl_AppendResult(irp, s, NULL);
179
184
  return TCL_OK;
180
185
}
185
190
  module_entry *me;
186
191
 
187
192
  BADARGS(3, 3, " idx channel");
 
193
 
188
194
  idx = findidx(atoi(argv[1]));
189
 
  if (idx < 0 ||
190
 
      (dcc[idx].type != &DCC_CHAT && dcc[idx].type != &DCC_SCRIPT)) {
 
195
  if (idx < 0 || (dcc[idx].type != &DCC_CHAT &&
 
196
      dcc[idx].type != &DCC_SCRIPT)) {
191
197
    Tcl_AppendResult(irp, "invalid idx", NULL);
192
198
    return TCL_ERROR;
193
199
  }
194
200
  if (argv[2][0] < '0' || argv[2][0] > '9') {
195
201
    if (!strcmp(argv[2], "-1") || !egg_strcasecmp(argv[2], "off"))
196
 
      chan = (-1);
 
202
      chan = -1;
197
203
    else {
198
204
      Tcl_SetVar(irp, "chan", argv[2], 0);
199
205
      if (Tcl_VarEval(irp, "assoc ", "$chan", NULL) != TCL_OK ||
200
 
          !interp->result[0]) {
201
 
        Tcl_AppendResult(irp, "channel name is invalid", NULL);
202
 
        return TCL_ERROR;
 
206
          !interp->result[0]) {
 
207
        Tcl_AppendResult(irp, "channel name is invalid", NULL);
 
208
        return TCL_ERROR;
203
209
      }
204
210
      chan = atoi(interp->result);
205
211
    }
206
212
  } else
207
213
    chan = atoi(argv[2]);
208
214
  if ((chan < -1) || (chan > 199999)) {
209
 
    Tcl_AppendResult(irp, "channel out of range; must be -1 thru 199999",
210
 
                     NULL);
 
215
    Tcl_AppendResult(irp, "channel out of range; must be -1 through 199999",
 
216
                     NULL);
211
217
    return TCL_ERROR;
212
218
  }
213
219
  if (dcc[idx].type == &DCC_SCRIPT)
217
223
 
218
224
    if (dcc[idx].u.chat->channel >= 0) {
219
225
      if ((chan >= GLOBAL_CHANS) && (oldchan < GLOBAL_CHANS))
220
 
        botnet_send_part_idx(idx, "*script*");
 
226
        botnet_send_part_idx(idx, "*script*");
221
227
      check_tcl_chpt(botnetnick, dcc[idx].nick, dcc[idx].sock,
222
 
                     dcc[idx].u.chat->channel);
 
228
                     dcc[idx].u.chat->channel);
223
229
    }
224
230
    dcc[idx].u.chat->channel = chan;
225
231
    if (chan < GLOBAL_CHANS)
226
232
      botnet_send_join_idx(idx, oldchan);
227
233
    check_tcl_chjn(botnetnick, dcc[idx].nick, chan, geticon(idx),
228
 
                   dcc[idx].sock, dcc[idx].host);
 
234
                   dcc[idx].sock, dcc[idx].host);
229
235
  }
230
236
  /* Console autosave. */
231
237
  if ((me = module_find("console", 1, 1))) {
242
248
  char msg[401];
243
249
 
244
250
  BADARGS(3, 3, " channel message");
 
251
 
245
252
  chan = atoi(argv[1]);
246
253
  if ((chan < 0) || (chan > 199999)) {
247
 
    Tcl_AppendResult(irp, "channel out of range; must be 0 thru 199999",
248
 
                     NULL);
 
254
    Tcl_AppendResult(irp, "channel out of range; must be 0 through 199999", NULL);
249
255
    return TCL_ERROR;
250
256
  }
251
257
  strncpyz(msg, argv[2], sizeof msg);
 
258
 
252
259
  chanout_but(-1, chan, "*** %s\n", argv[2]);
253
260
  botnet_send_chan(-1, botnetnick, NULL, chan, argv[2]);
254
261
  check_tcl_bcst(botnetnick, chan, argv[2]);
261
268
  module_entry *me;
262
269
 
263
270
  BADARGS(2, 4, " idx ?channel? ?console-modes?");
 
271
 
264
272
  i = findidx(atoi(argv[1]));
265
273
  if (i < 0 || dcc[i].type != &DCC_CHAT) {
266
274
    Tcl_AppendResult(irp, "invalid idx", NULL);
267
275
    return TCL_ERROR;
268
276
  }
269
277
  pls = 1;
 
278
 
270
279
  for (arg = 2; arg < argc; arg++) {
271
280
    if (argv[arg][0] && ((strchr(CHANMETA, argv[arg][0]) != NULL) ||
272
 
        (argv[arg][0] == '*'))) {
 
281
        (argv[arg][0] == '*'))) {
273
282
      if ((argv[arg][0] != '*') && (!findchan_by_dname(argv[arg]))) {
274
 
        /* If we dont find the channel, and it starts with a +... assume it
275
 
         * should be the console flags to set.
276
 
         */
277
 
        if (argv[arg][0]=='+')
 
283
        /* If we dont find the channel, and it starts with a +, assume it
 
284
         * should be the console flags to set. */
 
285
        if (argv[arg][0] == '+')
278
286
          goto do_console_flags;
279
 
        Tcl_AppendResult(irp, "invalid channel", NULL);
280
 
        return TCL_ERROR;
 
287
        Tcl_AppendResult(irp, "invalid channel", NULL);
 
288
        return TCL_ERROR;
281
289
      }
282
290
      strncpyz(dcc[i].u.chat->con_chan, argv[arg], 81);
283
291
    } else {
284
292
      if ((argv[arg][0] != '+') && (argv[arg][0] != '-'))
285
 
        dcc[i].u.chat->con_flags = 0;
286
 
      do_console_flags:
 
293
        dcc[i].u.chat->con_flags = 0;
 
294
    do_console_flags:
287
295
      for (j = 0; j < strlen(argv[arg]); j++) {
288
 
        if (argv[arg][j] == '+')
289
 
          pls = 1;
290
 
        else if (argv[arg][j] == '-')
291
 
          pls = (-1);
292
 
        else {
293
 
          char s[2];
 
296
        if (argv[arg][j] == '+')
 
297
          pls = 1;
 
298
        else if (argv[arg][j] == '-')
 
299
          pls = -1;
 
300
        else {
 
301
          char s[2];
294
302
 
295
 
          s[0] = argv[arg][j];
296
 
          s[1] = 0;
297
 
          if (pls == 1)
298
 
            dcc[i].u.chat->con_flags |= logmodes(s);
299
 
          else
300
 
            dcc[i].u.chat->con_flags &= ~logmodes(s);
301
 
        }
 
303
          s[0] = argv[arg][j];
 
304
          s[1] = 0;
 
305
          if (pls == 1)
 
306
            dcc[i].u.chat->con_flags |= logmodes(s);
 
307
          else
 
308
            dcc[i].u.chat->con_flags &= ~logmodes(s);
 
309
        }
302
310
      }
303
311
    }
304
312
  }
319
327
  module_entry *me;
320
328
 
321
329
  BADARGS(2, 4, " idx ?strip-flags?");
 
330
 
322
331
  i = findidx(atoi(argv[1]));
323
332
  if (i < 0 || dcc[i].type != &DCC_CHAT) {
324
333
    Tcl_AppendResult(irp, "invalid idx", NULL);
325
334
    return TCL_ERROR;
326
335
  }
327
336
  pls = 1;
 
337
 
328
338
  for (arg = 2; arg < argc; arg++) {
329
339
    if ((argv[arg][0] != '+') && (argv[arg][0] != '-'))
330
340
      dcc[i].u.chat->strip_flags = 0;
331
341
    for (j = 0; j < strlen(argv[arg]); j++) {
332
342
      if (argv[arg][j] == '+')
333
 
        pls = 1;
 
343
        pls = 1;
334
344
      else if (argv[arg][j] == '-')
335
 
        pls = (-1);
 
345
        pls = -1;
336
346
      else {
337
 
        char s[2];
 
347
        char s[2];
338
348
 
339
 
        s[0] = argv[arg][j];
340
 
        s[1] = 0;
341
 
        if (pls == 1)
342
 
          dcc[i].u.chat->strip_flags |= stripmodes(s);
343
 
        else
344
 
          dcc[i].u.chat->strip_flags &= ~stripmodes(s);
 
349
        s[0] = argv[arg][j];
 
350
        s[1] = 0;
 
351
        if (pls == 1)
 
352
          dcc[i].u.chat->strip_flags |= stripmodes(s);
 
353
        else
 
354
          dcc[i].u.chat->strip_flags &= ~stripmodes(s);
345
355
      }
346
356
    }
347
357
  }
361
371
  module_entry *me;
362
372
 
363
373
  BADARGS(2, 3, " idx ?status?");
 
374
 
364
375
  i = findidx(atoi(argv[1]));
365
376
  if (i < 0 || dcc[i].type != &DCC_CHAT) {
366
377
    Tcl_AppendResult(irp, "invalid idx", NULL);
392
403
  module_entry *me;
393
404
 
394
405
  BADARGS(2, 3, " idx ?status?");
 
406
 
395
407
  i = findidx(atoi(argv[1]));
396
408
  if (i < 0 || dcc[i].type != &DCC_CHAT) {
397
409
    Tcl_AppendResult(irp, "invalid idx", NULL);
427
439
  void *hold;
428
440
 
429
441
  BADARGS(3, 3, " idx command");
 
442
 
430
443
  idx = findidx(atoi(argv[1]));
431
444
  if (idx < 0) {
432
445
    Tcl_AppendResult(irp, "invalid idx", NULL);
435
448
  if (dcc[idx].type->flags & DCT_CHAT) {
436
449
    if (dcc[idx].u.chat->channel >= 0) {
437
450
      chanout_but(idx, dcc[idx].u.chat->channel, "*** %s has gone.\n",
438
 
                  dcc[idx].nick);
 
451
                  dcc[idx].nick);
439
452
      check_tcl_chpt(botnetnick, dcc[idx].nick, dcc[idx].sock,
440
 
                     dcc[idx].u.chat->channel);
 
453
                     dcc[idx].u.chat->channel);
441
454
      botnet_send_part_idx(idx, "gone");
442
455
    }
443
456
    check_tcl_chof(dcc[idx].nick, dcc[idx].sock);
448
461
  dcc[idx].u.script->type = dcc[idx].type;
449
462
  dcc[idx].type = &DCC_SCRIPT;
450
463
  /* Do not buffer data anymore. All received and stored data is passed
451
 
     over to the dcc functions from now on.  */
 
464
   * over to the dcc functions from now on.  */
452
465
  sockoptions(dcc[idx].sock, EGG_OPTION_UNSET, SOCK_BUFFER);
453
466
  strncpyz(dcc[idx].u.script->command, argv[2], 120);
454
467
  return TCL_OK;
459
472
  int idx;
460
473
 
461
474
  BADARGS(2, 2, " idx");
 
475
 
462
476
  idx = findidx(atoi(argv[1]));
463
477
  if (idx < 0 || !(dcc[idx].type->flags & DCT_VALIDIDX))
464
 
     Tcl_AppendResult(irp, "0", NULL);
 
478
    Tcl_AppendResult(irp, "0", NULL);
465
479
  else
466
 
     Tcl_AppendResult(irp, "1", NULL);
 
480
    Tcl_AppendResult(irp, "1", NULL);
467
481
   return TCL_OK;
468
482
}
469
483
 
472
486
  int idx;
473
487
 
474
488
  BADARGS(2, 3, " idx ?reason?");
 
489
 
475
490
  idx = findidx(atoi(argv[1]));
476
491
  if (idx < 0) {
477
492
    Tcl_AppendResult(irp, "invalid idx", NULL);
478
493
    return TCL_ERROR;
479
494
  }
480
 
  /* Don't kill terminal socket */
481
 
  if ((dcc[idx].sock == STDOUT) && !backgrd)
 
495
 
 
496
  if ((dcc[idx].sock == STDOUT) && !backgrd) /* Don't kill terminal socket */
482
497
    return TCL_OK;
483
 
  /* Make sure 'whom' info is updated for other bots */
484
 
  if (dcc[idx].type->flags & DCT_CHAT) {
 
498
 
 
499
 
 
500
  if (dcc[idx].type->flags & DCT_CHAT) { /* Make sure 'whom' info is updated */
485
501
    chanout_but(idx, dcc[idx].u.chat->channel, "*** %s has left the %s%s%s\n",
486
 
                dcc[idx].nick, dcc[idx].u.chat ? "channel" : "partyline",
487
 
                argc == 3 ? ": " : "", argc == 3 ? argv[2] : "");
 
502
                dcc[idx].nick, dcc[idx].u.chat ? "channel" : "partyline",
 
503
                argc == 3 ? ": " : "", argc == 3 ? argv[2] : "");
488
504
    botnet_send_part_idx(idx, argc == 3 ? argv[2] : "");
489
505
    if ((dcc[idx].u.chat->channel >= 0) &&
490
 
        (dcc[idx].u.chat->channel < GLOBAL_CHANS))
 
506
        (dcc[idx].u.chat->channel < GLOBAL_CHANS))
491
507
      check_tcl_chpt(botnetnick, dcc[idx].nick, dcc[idx].sock,
492
 
                     dcc[idx].u.chat->channel);
 
508
                     dcc[idx].u.chat->channel);
493
509
    check_tcl_chof(dcc[idx].nick, dcc[idx].sock);
494
 
    /* Notice is sent to the party line, the script can add a reason. */
495
510
  }
496
511
  killsock(dcc[idx].sock);
 
512
  killtransfer(idx);
497
513
  lostdcc(idx);
498
514
  return TCL_OK;
499
515
}
504
520
  char msg[401];
505
521
 
506
522
  BADARGS(3, 3, " botnick message");
 
523
 
507
524
  i = nextbot(argv[1]);
508
525
  if (i < 0) {
509
 
    Tcl_AppendResult(irp, "bot is not in the botnet", NULL);
 
526
    Tcl_AppendResult(irp, "bot is not on the botnet", NULL);
510
527
    return TCL_ERROR;
511
528
  }
512
529
  strncpyz(msg, argv[2], sizeof msg);
 
530
 
513
531
  botnet_send_zapf(i, botnetnick, argv[1], msg);
514
532
  return TCL_OK;
515
533
}
519
537
  char msg[401];
520
538
 
521
539
  BADARGS(2, 2, " message");
 
540
 
522
541
  strncpyz(msg, argv[1], sizeof msg);
523
542
  botnet_send_zapf_broad(-1, botnetnick, NULL, msg);
524
543
  return TCL_OK;
529
548
  int idx;
530
549
 
531
550
  BADARGS(2, 2, " idx");
 
551
 
532
552
  idx = findidx(atoi(argv[1]));
533
553
  if (idx < 0) {
534
554
    Tcl_AppendResult(irp, "invalid idx", NULL);
535
555
    return TCL_ERROR;
536
556
  }
 
557
 
537
558
  Tcl_AppendResult(irp, dcc[idx].nick, NULL);
538
559
  return TCL_OK;
539
560
}
543
564
  int i;
544
565
 
545
566
  BADARGS(2, 2, " bot");
 
567
 
546
568
  i = nextbot(argv[1]);
547
569
  if (i < 0)
548
 
     Tcl_AppendResult(irp, "0", NULL);
 
570
    Tcl_AppendResult(irp, "0", NULL);
549
571
  else
550
 
     Tcl_AppendResult(irp, "1", NULL);
551
 
   return TCL_OK;
 
572
    Tcl_AppendResult(irp, "1", NULL);
 
573
  return TCL_OK;
552
574
}
553
575
 
554
576
static int tcl_bots STDVAR
556
578
  tand_t *bot;
557
579
 
558
580
  BADARGS(1, 1, "");
 
581
 
559
582
  for (bot = tandbot; bot; bot = bot->next)
560
 
     Tcl_AppendElement(irp, bot->bot);
561
 
   return TCL_OK;
 
583
    Tcl_AppendElement(irp, bot->bot);
 
584
  return TCL_OK;
562
585
}
563
586
 
564
587
static int tcl_botlist STDVAR
565
588
{
 
589
  char *p, sh[2], string[20];
 
590
  EGG_CONST char *list[4];
566
591
  tand_t *bot;
567
 
  char *list[4], *p;
568
 
  char sh[2], string[20];
569
592
 
570
593
  BADARGS(1, 1, "");
 
594
 
571
595
  sh[1] = 0;
572
596
  list[3] = sh;
573
597
  list[2] = string;
583
607
  return TCL_OK;
584
608
}
585
609
 
586
 
/* list of { idx nick host type {other}  timestamp}
587
 
 */
588
610
static int tcl_dcclist STDVAR
589
611
{
590
612
  int i;
591
 
  char idxstr[10];
592
 
  char timestamp[11];
593
 
  char *list[6], *p;
594
 
  char other[160];
 
613
  char *p, idxstr[10], timestamp[11], other[160];
 
614
  EGG_CONST char *list[6];
595
615
 
596
616
  BADARGS(1, 2, " ?type?");
 
617
 
597
618
  for (i = 0; i < dcc_total; i++) {
598
 
    if (argc == 1 ||
599
 
        ((argc == 2) && (dcc[i].type && !egg_strcasecmp(dcc[i].type->name, argv[1])))) {
 
619
    if (argc == 1 || ((argc == 2) && (dcc[i].type &&
 
620
        !egg_strcasecmp(dcc[i].type->name, argv[1])))) {
600
621
      egg_snprintf(idxstr, sizeof idxstr, "%ld", dcc[i].sock);
601
622
      egg_snprintf(timestamp, sizeof timestamp, "%ld", dcc[i].timeval);
602
623
      if (dcc[i].type && dcc[i].type->display)
603
 
        dcc[i].type->display(i, other);
 
624
        dcc[i].type->display(i, other);
604
625
      else {
605
 
        egg_snprintf(other, sizeof other, "?:%lX  !! ERROR !!",
606
 
                     (long) dcc[i].type);
607
 
        break;
 
626
        egg_snprintf(other, sizeof other, "?:%lX  !! ERROR !!",
 
627
                     (long) dcc[i].type);
 
628
        break;
608
629
      }
609
630
      list[0] = idxstr;
610
631
      list[1] = dcc[i].nick;
620
641
  return TCL_OK;
621
642
}
622
643
 
623
 
/* list of { nick bot host flag idletime awaymsg [channel]}
624
 
 */
625
644
static int tcl_whom STDVAR
626
645
{
627
 
  char c[2], idle[11], work[20], *list[7], *p;
628
646
  int chan, i;
 
647
  char c[2], idle[11], work[20], *p;
 
648
  EGG_CONST char *list[7];
629
649
 
630
650
  BADARGS(2, 2, " chan");
 
651
 
631
652
  if (argv[1][0] == '*')
632
 
     chan = -1;
 
653
    chan = -1;
633
654
  else {
634
655
    if ((argv[1][0] < '0') || (argv[1][0] > '9')) {
635
656
      Tcl_SetVar(interp, "chan", argv[1], 0);
636
657
      if ((Tcl_VarEval(interp, "assoc ", "$chan", NULL) != TCL_OK) ||
637
 
          !interp->result[0]) {
638
 
        Tcl_AppendResult(irp, "channel name is invalid", NULL);
639
 
        return TCL_ERROR;
 
658
          !interp->result[0]) {
 
659
        Tcl_AppendResult(irp, "channel name is invalid", NULL);
 
660
        return TCL_ERROR;
640
661
      }
641
662
      chan = atoi(interp->result);
642
663
    } else
643
664
      chan = atoi(argv[1]);
644
665
    if ((chan < 0) || (chan > 199999)) {
645
 
      Tcl_AppendResult(irp, "channel out of range; must be 0 thru 199999",
646
 
                       NULL);
 
666
      Tcl_AppendResult(irp, "channel out of range; must be 0 through 199999",
 
667
                       NULL);
647
668
      return TCL_ERROR;
648
669
    }
649
670
  }
650
671
  for (i = 0; i < dcc_total; i++)
651
672
    if (dcc[i].type == &DCC_CHAT) {
652
673
      if (dcc[i].u.chat->channel == chan || chan == -1) {
653
 
        c[0] = geticon(i);
654
 
        c[1] = 0;
655
 
        egg_snprintf(idle, sizeof idle, "%lu", (now - dcc[i].timeval) / 60);
656
 
        list[0] = dcc[i].nick;
657
 
        list[1] = botnetnick;
658
 
        list[2] = dcc[i].host;
659
 
        list[3] = c;
660
 
        list[4] = idle;
661
 
        list[5] = dcc[i].u.chat->away ? dcc[i].u.chat->away : "";
662
 
        if (chan == -1) {
663
 
          egg_snprintf(work, sizeof work, "%d", dcc[i].u.chat->channel);
664
 
          list[6] = work;
665
 
        }
666
 
        p = Tcl_Merge((chan == -1) ? 7 : 6, list);
667
 
        Tcl_AppendElement(irp, p);
668
 
        Tcl_Free((char *) p);
 
674
        c[0] = geticon(i);
 
675
        c[1] = 0;
 
676
        egg_snprintf(idle, sizeof idle, "%lu", (now - dcc[i].timeval) / 60);
 
677
        list[0] = dcc[i].nick;
 
678
        list[1] = botnetnick;
 
679
        list[2] = dcc[i].host;
 
680
        list[3] = c;
 
681
        list[4] = idle;
 
682
        list[5] = dcc[i].u.chat->away ? dcc[i].u.chat->away : "";
 
683
        if (chan == -1) {
 
684
          egg_snprintf(work, sizeof work, "%d", dcc[i].u.chat->channel);
 
685
          list[6] = work;
 
686
        }
 
687
        p = Tcl_Merge((chan == -1) ? 7 : 6, list);
 
688
        Tcl_AppendElement(irp, p);
 
689
        Tcl_Free((char *) p);
669
690
      }
670
691
    }
671
692
  for (i = 0; i < parties; i++) {
673
694
      c[0] = party[i].flag;
674
695
      c[1] = 0;
675
696
      if (party[i].timer == 0L)
676
 
        strcpy(idle, "0");
 
697
        strcpy(idle, "0");
677
698
      else
678
 
        egg_snprintf(idle, sizeof idle, "%lu", (now - party[i].timer) / 60);
 
699
        egg_snprintf(idle, sizeof idle, "%lu", (now - party[i].timer) / 60);
679
700
      list[0] = party[i].nick;
680
701
      list[1] = party[i].bot;
681
702
      list[2] = party[i].from ? party[i].from : "";
683
704
      list[4] = idle;
684
705
      list[5] = party[i].status & PLSTAT_AWAY ? party[i].away : "";
685
706
      if (chan == -1) {
686
 
        egg_snprintf(work, sizeof work, "%d", party[i].chan);
687
 
        list[6] = work;
 
707
        egg_snprintf(work, sizeof work, "%d", party[i].chan);
 
708
        list[6] = work;
688
709
      }
689
710
      p = Tcl_Merge((chan == -1) ? 7 : 6, list);
690
711
      Tcl_AppendElement(irp, p);
699
720
  char s[20];
700
721
 
701
722
  BADARGS(1, 1, "");
 
723
 
702
724
  egg_snprintf(s, sizeof s, "%d", dcc_total);
703
725
  Tcl_AppendResult(irp, s, NULL);
704
726
  return TCL_OK;
706
728
 
707
729
static int tcl_getdccidle STDVAR
708
730
{
709
 
  int  x, idx;
 
731
  int x, idx;
710
732
  char s[21];
711
733
 
712
734
  BADARGS(2, 2, " idx");
 
735
 
713
736
  idx = findidx(atoi(argv[1]));
714
737
  if (idx < 0) {
715
738
    Tcl_AppendResult(irp, "invalid idx", NULL);
716
739
    return TCL_ERROR;
717
740
  }
718
741
  x = (now - dcc[idx].timeval);
 
742
 
719
743
  egg_snprintf(s, sizeof s, "%d", x);
720
744
  Tcl_AppendElement(irp, s);
721
745
  return TCL_OK;
726
750
  int idx;
727
751
 
728
752
  BADARGS(2, 2, " idx");
 
753
 
729
754
  idx = findidx(atol(argv[1]));
730
755
  if (idx < 0 || dcc[idx].type != &DCC_CHAT) {
731
756
    Tcl_AppendResult(irp, "invalid idx", NULL);
733
758
  }
734
759
  if (dcc[idx].u.chat->away == NULL)
735
760
    return TCL_OK;
 
761
 
736
762
  Tcl_AppendResult(irp, dcc[idx].u.chat->away, NULL);
737
763
  return TCL_OK;
738
764
}
742
768
  int idx;
743
769
 
744
770
  BADARGS(3, 3, " idx message");
 
771
 
745
772
  idx = findidx(atol(argv[1]));
746
773
  if (idx < 0 || dcc[idx].type != &DCC_CHAT) {
747
774
    Tcl_AppendResult(irp, "invalid idx", NULL);
748
775
    return TCL_ERROR;
749
776
  }
750
777
  if (!argv[2][0]) {
751
 
    /* un-away */
752
778
    if (dcc[idx].u.chat->away != NULL)
753
779
      not_away(idx);
754
780
    return TCL_OK;
755
781
  }
756
 
  /* away */
757
782
  set_away(idx, argv[2]);
758
783
  return TCL_OK;
759
784
}
764
789
  char bot[HANDLEN + 1], bot2[HANDLEN + 1];
765
790
 
766
791
  BADARGS(2, 3, " ?via-bot? bot");
 
792
 
767
793
  strncpyz(bot, argv[1], sizeof bot);
768
794
  if (argc == 3) {
769
795
    x = 1;
774
800
    else
775
801
      botnet_send_link(i, botnetnick, bot, bot2);
776
802
  } else
777
 
     x = botlink("", -2, bot);
 
803
    x = botlink("", -2, bot);
 
804
 
778
805
  egg_snprintf(bot, sizeof bot, "%d", x);
779
806
  Tcl_AppendResult(irp, bot, NULL);
780
807
  return TCL_OK;
786
813
  char bot[HANDLEN + 1];
787
814
 
788
815
  BADARGS(2, 3, " bot ?comment?");
 
816
 
789
817
  strncpyz(bot, argv[1], sizeof bot);
790
818
  i = nextbot(bot);
791
819
  if (i < 0)
792
 
     x = 0;
 
820
    x = 0;
793
821
  else {
794
822
    x = 1;
795
823
    if (!egg_strcasecmp(bot, dcc[i].nick))
796
 
      x = botunlink(-2, bot, argv[2]);
 
824
      x = botunlink(-2, bot, argv[2], botnetnick);
797
825
    else
798
826
      botnet_send_unlink(i, botnetnick, lastbot(bot), bot, argv[2]);
799
827
  }
800
828
  egg_snprintf(bot, sizeof bot, "%d", x);
 
829
 
801
830
  Tcl_AppendResult(irp, bot, NULL);
802
831
  return TCL_OK;
803
832
}
808
837
  char s[81];
809
838
 
810
839
  BADARGS(3, 3, " hostname port");
 
840
 
811
841
  if (dcc_total == max_dcc) {
812
842
    Tcl_AppendResult(irp, "out of dcc table space", NULL);
813
843
    return TCL_ERROR;
814
844
  }
815
845
  sock = getsock(0);
 
846
 
816
847
  if (sock < 0) {
817
848
    Tcl_AppendResult(irp, MISC_NOFREESOCK, NULL);
818
849
    return TCL_ERROR;
820
851
  z = open_telnet_raw(sock, argv[1], atoi(argv[2]));
821
852
  if (z < 0) {
822
853
    killsock(sock);
823
 
    if (z == (-2))
 
854
    if (z == -2)
824
855
      strncpyz(s, "DNS lookup failed", sizeof s);
825
856
    else
826
857
      neterror(s);
827
858
    Tcl_AppendResult(irp, s, NULL);
828
859
    return TCL_ERROR;
829
860
  }
830
 
  /* Well well well... it worked! */
831
861
  i = new_dcc(&DCC_SOCKET, 0);
832
862
  dcc[i].sock = sock;
833
863
  dcc[i].port = atoi(argv[2]);
846
876
 */
847
877
static int tcl_listen STDVAR
848
878
{
849
 
  int i, j, idx = (-1), port, realport;
 
879
  int i, j, idx = -1, port, realport;
850
880
  char s[11];
851
881
  struct portmap *pmap = NULL, *pold = NULL;
852
882
 
853
883
  BADARGS(3, 5, " port type ?mask?/?proc ?flag??");
 
884
 
854
885
  port = realport = atoi(argv[1]);
855
886
  for (pmap = root; pmap; pold = pmap, pmap = pmap->next)
856
887
    if (pmap->realport == port) {
857
888
      port = pmap->mappedto;
858
889
      break;
859
 
    }
 
890
  }
860
891
  for (i = 0; i < dcc_total; i++)
861
892
    if ((dcc[i].type == &DCC_TELNET) && (dcc[i].port == port))
862
893
      idx = i;
863
894
  if (!egg_strcasecmp(argv[2], "off")) {
864
895
    if (pmap) {
865
896
      if (pold)
866
 
        pold->next = pmap->next;
 
897
        pold->next = pmap->next;
867
898
      else
868
 
        root = pmap->next;
 
899
        root = pmap->next;
869
900
      nfree(pmap);
870
901
    }
871
902
    /* Remove */
885
916
    }
886
917
    /* Try to grab port */
887
918
    j = port + 20;
888
 
    i = (-1);
 
919
    i = -1;
889
920
    while (port < j && i < 0) {
890
921
      i = open_listen(&port);
891
922
      if (i == -1)
892
 
        port++;
 
923
        port++;
893
924
      else if (i == -2)
894
925
        break;
895
926
    }
897
928
      Tcl_AppendResult(irp, "Couldn't grab nearby port", NULL);
898
929
      return TCL_ERROR;
899
930
    } else if (i == -2) {
900
 
      Tcl_AppendResult(irp, "Couldn't assign the requested IP. Please make sure 'my-ip' is set properly.", NULL);
 
931
      Tcl_AppendResult(irp, "Couldn't assign the requested IP. Please make "
 
932
                       "sure 'my-ip' is set properly.", NULL);
901
933
      return TCL_ERROR;
902
934
    }
903
935
    idx = new_dcc(&DCC_TELNET, 0);
917
949
    }
918
950
    if (argc == 5) {
919
951
      if (strcmp(argv[4], "pub")) {
920
 
        Tcl_AppendResult(irp, "unknown flag: ", argv[4], ". allowed flags: pub",
921
 
                         NULL);
922
 
        killsock(dcc[idx].sock);
923
 
        lostdcc(idx);
924
 
        return TCL_ERROR;
 
952
        Tcl_AppendResult(irp, "unknown flag: ", argv[4], ". allowed flags: pub",
 
953
                         NULL);
 
954
        killsock(dcc[idx].sock);
 
955
        lostdcc(idx);
 
956
        return TCL_ERROR;
925
957
      }
926
958
      dcc[idx].status = LSTN_PUBLIC;
927
959
    }
939
971
    strcpy(dcc[idx].nick, "(telnet)");
940
972
  if (!dcc[idx].nick[0]) {
941
973
    Tcl_AppendResult(irp, "illegal listen type: must be one of ",
942
 
                     "bots, users, all, off, script", NULL);
 
974
                     "bots, users, all, off, script", NULL);
943
975
    killsock(dcc[idx].sock);
944
976
    dcc_total--;
945
977
    return TCL_ERROR;
946
978
  }
947
 
  if (argc == 4) {
 
979
  if (argc == 4)
948
980
    strncpyz(dcc[idx].host, argv[3], UHOSTMAX);
949
 
  } else
 
981
  else
950
982
    strcpy(dcc[idx].host, "*");
951
983
  egg_snprintf(s, sizeof s, "%d", port);
952
984
  Tcl_AppendResult(irp, s, NULL);
967
999
  int i, ok = 0;
968
1000
 
969
1001
  BADARGS(2, 3, " user@bot ?reason?");
 
1002
 
970
1003
  strncpyz(who, argv[1], sizeof who);
971
1004
 
972
1005
  if (strchr(who, '@') != NULL) {
975
1008
    splitc(whonick, who, '@');
976
1009
    whonick[HANDLEN] = 0;
977
1010
    if (!egg_strcasecmp(who, botnetnick))
978
 
       strncpyz(who, whonick, sizeof who);
 
1011
      strncpyz(who, whonick, sizeof who);
979
1012
    else if (remote_boots > 0) {
980
1013
      i = nextbot(who);
981
1014
      if (i < 0)
982
 
        return TCL_OK;
983
 
      botnet_send_reject(i, botnetnick, NULL, whonick, who, argv[2] ? argv[2] : "");
984
 
    } else {
 
1015
        return TCL_OK;
 
1016
      botnet_send_reject(i, botnetnick, NULL, whonick, who,
 
1017
                         argv[2] ? argv[2] : "");
 
1018
    } else
985
1019
      return TCL_OK;
986
 
    }
987
1020
  }
988
1021
  for (i = 0; i < dcc_total; i++)
989
1022
    if (!ok && (dcc[i].type->flags & DCT_CANBOOT) &&
997
1030
static int tcl_rehash STDVAR
998
1031
{
999
1032
  BADARGS(1, 1, " ");
 
1033
 
1000
1034
  if (make_userfile) {
1001
1035
    putlog(LOG_MISC, "*", USERF_NONEEDNEW);
1002
1036
    make_userfile = 0;
1003
1037
  }
1004
1038
  write_userfile(-1);
 
1039
 
1005
1040
  putlog(LOG_MISC, "*", USERF_REHASHING);
1006
1041
  do_restart = -2;
1007
1042
  return TCL_OK;
1010
1045
static int tcl_restart STDVAR
1011
1046
{
1012
1047
  BADARGS(1, 1, " ");
 
1048
 
1013
1049
  if (!backgrd) {
1014
1050
    Tcl_AppendResult(interp, "You can't restart a -n bot", NULL);
1015
1051
    return TCL_ERROR;
1034
1070
 
1035
1071
  /* IRC traffic */
1036
1072
  sprintf(buf, "irc %ld %ld %ld %ld", itraffic_irc_today, itraffic_irc +
1037
 
          itraffic_irc_today, otraffic_irc_today, otraffic_irc + otraffic_irc_today);
1038
 
  Tcl_AppendElement(irp, buf);  
 
1073
          itraffic_irc_today, otraffic_irc_today,
 
1074
          otraffic_irc + otraffic_irc_today);
 
1075
  Tcl_AppendElement(irp, buf);
1039
1076
 
1040
1077
  /* Botnet traffic */
1041
1078
  sprintf(buf, "botnet %ld %ld %ld %ld", itraffic_bn_today, itraffic_bn +
1042
 
          itraffic_bn_today, otraffic_bn_today, otraffic_bn + otraffic_bn_today);
 
1079
          itraffic_bn_today, otraffic_bn_today,
 
1080
          otraffic_bn + otraffic_bn_today);
1043
1081
  Tcl_AppendElement(irp, buf);
1044
1082
 
1045
1083
  /* Partyline */
1046
 
  sprintf(buf, "partyline %ld %ld %ld %ld", itraffic_dcc_today, itraffic_dcc +  
1047
 
          itraffic_dcc_today, otraffic_dcc_today, otraffic_dcc + otraffic_dcc_today);    
 
1084
  sprintf(buf, "partyline %ld %ld %ld %ld", itraffic_dcc_today, itraffic_dcc +
 
1085
          itraffic_dcc_today, otraffic_dcc_today,
 
1086
          otraffic_dcc + otraffic_dcc_today);
1048
1087
  Tcl_AppendElement(irp, buf);
1049
1088
 
1050
1089
  /* Transfer */
1051
 
  sprintf(buf, "transfer %ld %ld %ld %ld", itraffic_trans_today, itraffic_trans +  
1052
 
          itraffic_trans_today, otraffic_trans_today, otraffic_trans + otraffic_trans_today);    
 
1090
  sprintf(buf, "transfer %ld %ld %ld %ld", itraffic_trans_today,
 
1091
          itraffic_trans + itraffic_trans_today, otraffic_trans_today,
 
1092
          otraffic_trans + otraffic_trans_today);
1053
1093
  Tcl_AppendElement(irp, buf);
1054
1094
 
1055
1095
  /* Misc traffic */
1056
 
  sprintf(buf, "misc %ld %ld %ld %ld", itraffic_unknown_today, itraffic_unknown +  
1057
 
          itraffic_unknown_today, otraffic_unknown_today, otraffic_unknown + 
1058
 
          otraffic_unknown_today);    
 
1096
  sprintf(buf, "misc %ld %ld %ld %ld", itraffic_unknown_today,
 
1097
          itraffic_unknown + itraffic_unknown_today, otraffic_unknown_today,
 
1098
          otraffic_unknown + otraffic_unknown_today);
1059
1099
  Tcl_AppendElement(irp, buf);
1060
1100
 
1061
1101
  /* Totals */
1062
 
  in_total_today = itraffic_irc_today + itraffic_bn_today + itraffic_dcc_today + 
1063
 
                itraffic_trans_today + itraffic_unknown_today,
1064
 
  in_total = in_total_today + itraffic_irc + itraffic_bn + itraffic_dcc + 
1065
 
              itraffic_trans + itraffic_unknown;
1066
 
  out_total_today = otraffic_irc_today + otraffic_bn_today + otraffic_dcc_today +
1067
 
                itraffic_trans_today + otraffic_unknown_today,
 
1102
  in_total_today = itraffic_irc_today + itraffic_bn_today +
 
1103
                   itraffic_dcc_today + itraffic_trans_today +
 
1104
                   itraffic_unknown_today;
 
1105
  in_total = in_total_today + itraffic_irc + itraffic_bn + itraffic_dcc +
 
1106
             itraffic_trans + itraffic_unknown;
 
1107
  out_total_today = otraffic_irc_today + otraffic_bn_today +
 
1108
                    otraffic_dcc_today + itraffic_trans_today +
 
1109
                    otraffic_unknown_today;
1068
1110
  out_total = out_total_today + otraffic_irc + otraffic_bn + otraffic_dcc +
1069
 
              otraffic_trans + otraffic_unknown;          
1070
 
  sprintf(buf, "total %ld %ld %ld %ld", in_total_today, in_total, out_total_today, out_total);
 
1111
              otraffic_trans + otraffic_unknown;
 
1112
  sprintf(buf, "total %ld %ld %ld %ld", in_total_today, in_total,
 
1113
          out_total_today, out_total);
1071
1114
  Tcl_AppendElement(irp, buf);
1072
 
  return(TCL_OK);
 
1115
  return TCL_OK;
1073
1116
}
1074
1117
 
1075
 
tcl_cmds tcldcc_cmds[] =
1076
 
{
1077
 
  {"putdcc",            tcl_putdcc},
1078
 
  {"putdccraw",         tcl_putdccraw},
1079
 
  {"putidx",            tcl_putdcc},
1080
 
  {"dccsimul",          tcl_dccsimul},
1081
 
  {"dccbroadcast",      tcl_dccbroadcast},
1082
 
  {"hand2idx",          tcl_hand2idx},
1083
 
  {"getchan",           tcl_getchan},
1084
 
  {"setchan",           tcl_setchan},
1085
 
  {"dccputchan",        tcl_dccputchan},
1086
 
  {"console",           tcl_console},
1087
 
  {"strip",             tcl_strip},
1088
 
  {"echo",              tcl_echo},
1089
 
  {"page",              tcl_page},
1090
 
  {"control",           tcl_control},
1091
 
  {"valididx",          tcl_valididx},
1092
 
  {"killdcc",           tcl_killdcc},
1093
 
  {"putbot",            tcl_putbot},
1094
 
  {"putallbots",        tcl_putallbots},
1095
 
  {"idx2hand",          tcl_idx2hand},
1096
 
  {"bots",              tcl_bots},
1097
 
  {"botlist",           tcl_botlist},
1098
 
  {"dcclist",           tcl_dcclist},
1099
 
  {"whom",              tcl_whom},
1100
 
  {"dccused",           tcl_dccused},
1101
 
  {"getdccidle",        tcl_getdccidle},
1102
 
  {"getdccaway",        tcl_getdccaway},
1103
 
  {"setdccaway",        tcl_setdccaway},
1104
 
  {"islinked",          tcl_islinked},
1105
 
  {"link",              tcl_link},
1106
 
  {"unlink",            tcl_unlink},
1107
 
  {"connect",           tcl_connect},
1108
 
  {"listen",            tcl_listen},
1109
 
  {"boot",              tcl_boot},
1110
 
  {"rehash",            tcl_rehash},
1111
 
  {"restart",           tcl_restart},
1112
 
  {"traffic",           tcl_traffic},
1113
 
  {NULL,                NULL}
 
1118
tcl_cmds tcldcc_cmds[] = {
 
1119
  {"putdcc",             tcl_putdcc},
 
1120
  {"putdccraw",       tcl_putdccraw},
 
1121
  {"putidx",             tcl_putdcc},
 
1122
  {"dccsimul",         tcl_dccsimul},
 
1123
  {"dccbroadcast", tcl_dccbroadcast},
 
1124
  {"hand2idx",         tcl_hand2idx},
 
1125
  {"getchan",           tcl_getchan},
 
1126
  {"setchan",           tcl_setchan},
 
1127
  {"dccputchan",     tcl_dccputchan},
 
1128
  {"console",           tcl_console},
 
1129
  {"strip",               tcl_strip},
 
1130
  {"echo",                 tcl_echo},
 
1131
  {"page",                 tcl_page},
 
1132
  {"control",           tcl_control},
 
1133
  {"valididx",         tcl_valididx},
 
1134
  {"killdcc",           tcl_killdcc},
 
1135
  {"putbot",             tcl_putbot},
 
1136
  {"putallbots",     tcl_putallbots},
 
1137
  {"idx2hand",         tcl_idx2hand},
 
1138
  {"bots",                 tcl_bots},
 
1139
  {"botlist",           tcl_botlist},
 
1140
  {"dcclist",           tcl_dcclist},
 
1141
  {"whom",                 tcl_whom},
 
1142
  {"dccused",           tcl_dccused},
 
1143
  {"getdccidle",     tcl_getdccidle},
 
1144
  {"getdccaway",     tcl_getdccaway},
 
1145
  {"setdccaway",     tcl_setdccaway},
 
1146
  {"islinked",         tcl_islinked},
 
1147
  {"link",                 tcl_link},
 
1148
  {"unlink",             tcl_unlink},
 
1149
  {"connect",           tcl_connect},
 
1150
  {"listen",             tcl_listen},
 
1151
  {"boot",                 tcl_boot},
 
1152
  {"rehash",             tcl_rehash},
 
1153
  {"restart",           tcl_restart},
 
1154
  {"traffic",           tcl_traffic},
 
1155
  {NULL,                       NULL}
1114
1156
};