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

« back to all changes in this revision

Viewing changes to src/dccutil.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:
6
6
 *   memory management for dcc structures
7
7
 *   timeout checking for dcc connections
8
8
 *
9
 
 * $Id: dccutil.c,v 1.34 2002/01/02 03:46:35 guppy Exp $
 
9
 * $Id: dccutil.c,v 1.50 2004/05/26 00:20:19 wcc Exp $
10
10
 */
11
11
/*
12
12
 * Copyright (C) 1997 Robey Pointer
13
 
 * Copyright (C) 1999, 2000, 2001, 2002 Eggheads Development Team
 
13
 * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 Eggheads Development Team
14
14
 *
15
15
 * This program is free software; you can redistribute it and/or
16
16
 * modify it under the terms of the GNU General Public License
34
34
#include "modules.h"
35
35
#include "tandem.h"
36
36
 
37
 
extern struct dcc_t     *dcc;
38
 
extern int               dcc_total, max_dcc, dcc_flood_thr, backgrd, MAXSOCKS;
39
 
extern char              botnetnick[], spaces[], version[];
40
 
extern time_t            now;
41
 
extern sock_list        *socklist;
42
 
extern Tcl_Interp       *interp;
 
37
extern struct dcc_t *dcc;
 
38
extern int dcc_total, max_dcc, dcc_flood_thr, backgrd, copy_to_tmp, MAXSOCKS;
 
39
extern char botnetnick[], version[];
 
40
extern time_t now;
 
41
extern sock_list *socklist;
 
42
extern Tcl_Interp *interp;
43
43
 
44
 
char    motdfile[121] = "text/motd";    /* File where the motd is stored */
45
 
int     connect_timeout = 15;           /* How long to wait before a telnet
46
 
                                           connection times out */
 
44
char motdfile[121] = "text/motd";       /* File where the motd is stored */
 
45
int connect_timeout = 15;       /* How long to wait before a telnet
 
46
                                 * connection times out */
47
47
 
48
48
int reserved_port_min = 0;
49
49
int reserved_port_max = 0;
62
62
  MAXSOCKS = max_dcc + 10;
63
63
  if (socklist)
64
64
    socklist = (sock_list *) nrealloc((void *) socklist,
65
 
                                      sizeof(sock_list) * MAXSOCKS);
 
65
               sizeof(sock_list) * MAXSOCKS);
66
66
  else
67
67
    socklist = (sock_list *) nmalloc(sizeof(sock_list) * MAXSOCKS);
68
68
  for (; osock < MAXSOCKS; osock++)
109
109
 
110
110
  idx = EGG_VARARGS_START(int, arg1, va);
111
111
  format = va_arg(va, char *);
 
112
 
112
113
  egg_vsnprintf(buf, 1023, format, va);
113
114
  va_end(va);
114
115
  /* We can not use the return value vsnprintf() to determine where
118
119
   */
119
120
  /* We actually can, since if it's < 0 or >= sizeof(buf), we know it wrote
120
121
   * sizeof(buf) bytes. But we're not doing that anyway.
121
 
  */
122
 
  buf[sizeof(buf)-1] = 0;
 
122
   */
 
123
  buf[sizeof(buf) - 1] = 0;
123
124
  len = strlen(buf);
124
125
 
125
126
  if (idx < 0) {
146
147
    }
147
148
    return;
148
149
  } else {
149
 
    if (len > 500) {            /* Truncate to fit */
 
150
    if (len > 500) {            /* Truncate to fit */
150
151
      buf[500] = 0;
151
152
      strcat(buf, "\n");
152
153
      len = 501;
155
156
      char *p = add_cr(buf);
156
157
 
157
158
      tputs(dcc[idx].sock, p, strlen(p));
158
 
    } else if (dcc[idx].type && dcc[idx].type->output) {
 
159
    } else if (dcc[idx].type && dcc[idx].type->output)
159
160
      dcc[idx].type->output(idx, buf, dcc[idx].u.other);
160
 
    } else
 
161
    else
161
162
      tputs(dcc[idx].sock, buf, len);
162
163
  }
163
164
}
170
171
  va_list va;
171
172
 
172
173
  format = EGG_VARARGS_START(char *, arg1, va);
 
174
 
173
175
  egg_vsnprintf(s, 511, format, va);
174
176
  va_end(va);
175
177
  len = strlen(s);
196
198
  x = EGG_VARARGS_START(int, arg1, va);
197
199
  chan = va_arg(va, int);
198
200
  format = va_arg(va, char *);
 
201
 
199
202
  egg_vsnprintf(s, 511, format, va);
200
203
  va_end(va);
201
204
  len = strlen(s);
213
216
void dcc_chatter(int idx)
214
217
{
215
218
  int i, j;
216
 
  struct flag_record fr = {FR_GLOBAL | FR_CHAN | FR_ANYWH, 0, 0, 0, 0, 0};
 
219
  struct flag_record fr = { FR_GLOBAL | FR_CHAN | FR_ANYWH, 0, 0, 0, 0, 0 };
217
220
 
218
221
  get_user_flagrec(dcc[idx].user, &fr, NULL);
219
222
  show_motd(idx);
224
227
  check_tcl_chon(dcc[idx].nick, dcc[idx].sock);
225
228
  /* Still there? */
226
229
  if ((idx >= dcc_total) || (dcc[idx].sock != j))
227
 
    return;                     /* Nope */
 
230
    return;                     /* Nope */
228
231
  /* Tcl script may have taken control */
229
232
  if (dcc[idx].type == &DCC_CHAT) {
230
233
    if (!strcmp(dcc[idx].u.chat->con_chan, "***"))
235
238
       * so dont bother sending them
236
239
       */
237
240
      if (i == -2)
238
 
        i = 0;
 
241
        i = 0;
239
242
      dcc[idx].u.chat->channel = i;
240
 
      if (dcc[idx].u.chat->channel >= 0) {
241
 
        if (dcc[idx].u.chat->channel < 100000) {
242
 
          botnet_send_join_idx(idx, -1);
243
 
        }
244
 
      }
 
243
      if ((dcc[idx].u.chat->channel >= 0) &&
 
244
          (dcc[idx].u.chat->channel < GLOBAL_CHANS))
 
245
        botnet_send_join_idx(idx, -1);
245
246
      check_tcl_chjn(botnetnick, dcc[idx].nick, dcc[idx].u.chat->channel,
246
 
                     geticon(idx), dcc[idx].sock, dcc[idx].host);
 
247
                     geticon(idx), dcc[idx].sock, dcc[idx].host);
247
248
    }
248
249
    /* But *do* bother with sending it locally */
249
250
    if (!dcc[idx].u.chat->channel) {
250
251
      chanout_but(-1, 0, "*** %s joined the party line.\n", dcc[idx].nick);
251
252
    } else if (dcc[idx].u.chat->channel > 0) {
252
253
      chanout_but(-1, dcc[idx].u.chat->channel,
253
 
                  "*** %s joined the channel.\n", dcc[idx].nick);
 
254
                  "*** %s joined the channel.\n", dcc[idx].nick);
 
255
    }
 
256
  }
 
257
}
 
258
 
 
259
/* Closes an open FD for transfer sockets. */
 
260
void killtransfer(int n)
 
261
{
 
262
  int i, ok = 1;
 
263
 
 
264
  if (dcc[n].type->flags & DCT_FILETRAN) {
 
265
    if (dcc[n].u.xfer->f) {
 
266
      fclose(dcc[n].u.xfer->f);
 
267
      dcc[n].u.xfer->f = NULL;
 
268
    }
 
269
    if (dcc[n].u.xfer->filename && copy_to_tmp) {
 
270
      for (i = 0; i < dcc_total; i++) {
 
271
        if ((i != n) && (dcc[i].type->flags & DCT_FILETRAN) &&
 
272
            (dcc[i].u.xfer->filename) &&
 
273
            (!strcmp(dcc[i].u.xfer->filename, dcc[n].u.xfer->filename))) {
 
274
          ok = 0;
 
275
          break;
 
276
        }
 
277
      }
 
278
      if (ok)
 
279
        unlink(dcc[n].u.xfer->filename);
254
280
    }
255
281
  }
256
282
}
260
286
 */
261
287
void lostdcc(int n)
262
288
{
 
289
  /* Make sure it's a valid dcc index. */
 
290
  if (n < 0 || n >= max_dcc)
 
291
    return;
 
292
 
263
293
  if (dcc[n].type && dcc[n].type->kill)
264
294
    dcc[n].type->kill(n, dcc[n].u.other);
265
295
  else if (dcc[n].u.other)
266
296
    nfree(dcc[n].u.other);
267
297
  egg_bzero(&dcc[n], sizeof(struct dcc_t));
268
298
 
269
 
  dcc[n].sock = (-1);
 
299
  dcc[n].sock = -1;
270
300
  dcc[n].type = &DCC_LOST;
271
301
}
272
302
 
287
317
  if (n < dcc_total)
288
318
    egg_memcpy(&dcc[n], &dcc[dcc_total], sizeof(struct dcc_t));
289
319
  else
290
 
    egg_bzero(&dcc[n], sizeof(struct dcc_t)); /* drummer */
 
320
    egg_bzero(&dcc[n], sizeof(struct dcc_t));   /* drummer */
291
321
}
292
322
 
293
323
/* Clean up sockets that were just left for dead.
299
329
  for (i = 0; i < dcc_total; i++) {
300
330
    if (dcc[i].type == &DCC_LOST) {
301
331
      dcc[i].type = NULL;
302
 
      dcc[i].sock = (-1);
 
332
      dcc[i].sock = -1;
303
333
      removedcc(i);
304
334
      i--;
305
335
    }
311
341
 */
312
342
void tell_dcc(int zidx)
313
343
{
314
 
  int i, j, k;
 
344
  int i, j;
315
345
  char other[160];
316
 
 
317
 
  spaces[HANDLEN - 9] = 0;
318
 
  dprintf(zidx, "SOCK ADDR     PORT  NICK     %s HOST              TYPE\n"
319
 
          ,spaces);
320
 
  dprintf(zidx, "---- -------- ----- ---------%s ----------------- ----\n"
321
 
          ,spaces);
322
 
  spaces[HANDLEN - 9] = ' ';
 
346
  char format[81];
 
347
  int nicklen;
 
348
 
 
349
  /* calculate max nicklen */
 
350
  nicklen = 0;
 
351
  for (i = 0; i < dcc_total; i++) {
 
352
    if (strlen(dcc[i].nick) > nicklen)
 
353
      nicklen = strlen(dcc[i].nick);
 
354
  }
 
355
  if (nicklen < 9)
 
356
    nicklen = 9;
 
357
 
 
358
  egg_snprintf(format, sizeof format, "%%-4s %%-8s %%-5s %%-%us %%-17s %%s\n",
 
359
               nicklen);
 
360
  dprintf(zidx, format, "SOCK", "ADDR", "PORT", "NICK", "HOST", "TYPE");
 
361
  dprintf(zidx, format, "----", "--------", "-----", "---------",
 
362
          "-----------------", "----");
 
363
 
 
364
  egg_snprintf(format, sizeof format, "%%-4d %%08X %%5d %%-%us %%-17s %%s\n",
 
365
               nicklen);
323
366
  /* Show server */
324
367
  for (i = 0; i < dcc_total; i++) {
325
368
    j = strlen(dcc[i].host);
333
376
      sprintf(other, "?:%lX  !! ERROR !!", (long) dcc[i].type);
334
377
      break;
335
378
    }
336
 
    k = HANDLEN - strlen(dcc[i].nick);
337
 
    spaces[k] = 0;
338
 
    dprintf(zidx, "%-4d %08X %5d %s%s %-17s %s\n", dcc[i].sock, dcc[i].addr,
339
 
            dcc[i].port, dcc[i].nick, spaces, dcc[i].host + j, other);
340
 
    spaces[k] = ' ';
 
379
    dprintf(zidx, format, dcc[i].sock, dcc[i].addr, dcc[i].port, dcc[i].nick,
 
380
            dcc[i].host + j, other);
341
381
  }
342
382
}
343
383
 
351
391
  }
352
392
  if (dcc[idx].u.chat->channel >= 0) {
353
393
    chanout_but(-1, dcc[idx].u.chat->channel,
354
 
                "*** %s is no longer away.\n", dcc[idx].nick);
355
 
    if (dcc[idx].u.chat->channel < 100000) {
 
394
                "*** %s is no longer away.\n", dcc[idx].nick);
 
395
    if (dcc[idx].u.chat->channel < GLOBAL_CHANS) {
356
396
      botnet_send_away(-1, botnetnick, dcc[idx].sock, NULL, idx);
357
397
    }
358
398
  }
378
418
  strcpy(dcc[idx].u.chat->away, s);
379
419
  if (dcc[idx].u.chat->channel >= 0) {
380
420
    chanout_but(-1, dcc[idx].u.chat->channel,
381
 
                "*** %s is now away: %s\n", dcc[idx].nick, s);
382
 
    if (dcc[idx].u.chat->channel < 100000) {
 
421
                "*** %s is now away: %s\n", dcc[idx].nick, s);
 
422
    if (dcc[idx].u.chat->channel < GLOBAL_CHANS) {
383
423
      botnet_send_away(-1, botnetnick, dcc[idx].sock, s, idx);
384
424
    }
385
425
  }
392
432
void *_get_data_ptr(int size, char *file, int line)
393
433
{
394
434
  char *p;
 
435
 
395
436
#ifdef DEBUG_MEM
396
437
  char x[1024];
397
438
 
411
452
{
412
453
  int i;
413
454
 
414
 
  i = 10 + (random() % 6);
 
455
  i = 10 + randint(6);
415
456
  make_rand_str(s, i);
416
457
}
417
458
 
475
516
  }
476
517
}
477
518
 
478
 
int detect_dcc_flood(time_t * timer, struct chat_info *chat, int idx)
 
519
int detect_dcc_flood(time_t *timer, struct chat_info *chat, int idx)
479
520
{
480
521
  time_t t;
481
522
 
491
532
      /* FLOOD */
492
533
      dprintf(idx, "*** FLOOD: %s.\n", IRC_GOODBYE);
493
534
      /* Evil assumption here that flags&DCT_CHAT implies chat type */
494
 
      if ((dcc[idx].type->flags & DCT_CHAT) && chat &&
495
 
          (chat->channel >= 0)) {
496
 
        char x[1024];
 
535
      if ((dcc[idx].type->flags & DCT_CHAT) && chat && (chat->channel >= 0)) {
 
536
        char x[1024];
497
537
 
498
 
        egg_snprintf(x, sizeof x, DCC_FLOODBOOT, dcc[idx].nick);
499
 
        chanout_but(idx, chat->channel, "*** %s", x);
500
 
        if (chat->channel < 100000)
501
 
          botnet_send_part_idx(idx, x);
 
538
        egg_snprintf(x, sizeof x, DCC_FLOODBOOT, dcc[idx].nick);
 
539
        chanout_but(idx, chat->channel, "*** %s", x);
 
540
        if (chat->channel < GLOBAL_CHANS)
 
541
          botnet_send_part_idx(idx, x);
502
542
      }
503
543
      check_tcl_chof(dcc[idx].nick, dcc[idx].sock);
504
544
      if ((dcc[idx].sock != STDOUT) || backgrd) {
505
 
        killsock(dcc[idx].sock);
506
 
        lostdcc(idx);
 
545
        killsock(dcc[idx].sock);
 
546
        lostdcc(idx);
507
547
      } else {
508
 
        dprintf(DP_STDOUT, "\n### SIMULATION RESET ###\n\n");
509
 
        dcc_chatter(idx);
 
548
        dprintf(DP_STDOUT, "\n### SIMULATION RESET ###\n\n");
 
549
        dcc_chatter(idx);
510
550
      }
511
 
      return 1;                 /* <- flood */
 
551
      return 1;                 /* <- flood */
512
552
    }
513
553
  }
514
554
  return 0;
526
566
  /* If it's a partyliner (chatterer :) */
527
567
  /* Horrible assumption that DCT_CHAT using structure uses same format
528
568
   * as DCC_CHAT */
529
 
  if ((dcc[idx].type->flags & DCT_CHAT) &&
530
 
      (dcc[idx].u.chat->channel >= 0)) {
 
569
  if ((dcc[idx].type->flags & DCT_CHAT) && (dcc[idx].u.chat->channel >= 0)) {
531
570
    char x[1024];
532
571
 
533
572
    egg_snprintf(x, sizeof x, DCC_BOOTED3, by, dcc[idx].nick,
534
 
                 reason[0] ? ": " : "", reason);
 
573
                 reason[0] ? ": " : "", reason);
535
574
    chanout_but(idx, dcc[idx].u.chat->channel, "*** %s.\n", x);
536
 
    if (dcc[idx].u.chat->channel < 100000)
 
575
    if (dcc[idx].u.chat->channel < GLOBAL_CHANS)
537
576
      botnet_send_part_idx(idx, x);
538
577
  }
539
578
  check_tcl_chof(dcc[idx].nick, dcc[idx].sock);