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

« back to all changes in this revision

Viewing changes to src/misc.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:
7
7
 *   help system
8
8
 *   motd display and %var substitution
9
9
 *
10
 
 * $Id: misc.c,v 1.47 2002/01/02 03:46:35 guppy Exp $
 
10
 * $Id: misc.c,v 1.73 2004/05/27 06:29:46 wcc Exp $
11
11
 */
12
12
/*
13
13
 * Copyright (C) 1997 Robey Pointer
14
 
 * Copyright (C) 1999, 2000, 2001, 2002 Eggheads Development Team
 
14
 * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 Eggheads Development Team
15
15
 *
16
16
 * This program is free software; you can redistribute it and/or
17
17
 * modify it under the terms of the GNU General Public License
32
32
#include <sys/stat.h>
33
33
#include <unistd.h>
34
34
#include <fcntl.h>
 
35
#include <ctype.h>
35
36
#include "chan.h"
36
37
#include "tandem.h"
37
38
#include "modules.h"
 
39
 
38
40
#ifdef HAVE_UNAME
39
41
#  include <sys/utsname.h>
40
42
#endif
 
43
 
41
44
#include "stat.h"
42
45
 
43
 
extern struct dcc_t     *dcc;
44
 
extern struct chanset_t *chanset;
45
 
extern char              helpdir[], version[], origbotname[], botname[],
46
 
                         admin[], network[], motdfile[], ver[], botnetnick[],
47
 
                         bannerfile[], logfile_suffix[], textdir[];
48
 
extern int               backgrd, con_chan, term_z, use_stderr, dcc_total,
49
 
                         keep_all_logs, quick_logs, strict_host;
50
 
extern time_t            now;
51
 
extern Tcl_Interp       *interp;
52
 
 
53
 
 
54
 
int      shtime = 1;            /* Whether or not to display the time
55
 
                                   with console output */
56
 
log_t   *logs = 0;              /* Logfiles */
57
 
int      max_logs = 5;          /* Current maximum log files */
58
 
int      max_logsize = 0;       /* Maximum logfile size, 0 for no limit */
59
 
int      conmask = LOG_MODES | LOG_CMDS | LOG_MISC; /* Console mask */
60
 
int      debug_output = 0;      /* Disply output to server to LOG_SERVEROUT */
 
46
extern struct dcc_t *dcc;
 
47
extern struct chanset_t *chanset;
 
48
 
 
49
extern char helpdir[], version[], origbotname[], botname[], admin[], network[],
 
50
            motdfile[], ver[], botnetnick[], bannerfile[], logfile_suffix[],
 
51
            textdir[];
 
52
extern int  backgrd, con_chan, term_z, use_stderr, dcc_total, keep_all_logs,
 
53
            quick_logs, strict_host;
 
54
 
 
55
extern time_t now;
 
56
extern Tcl_Interp *interp;
 
57
 
 
58
 
 
59
int shtime = 1;                 /* Display the time with console output */
 
60
log_t *logs = 0;                /* Logfiles */
 
61
int max_logs = 5;               /* Current maximum log files */
 
62
int max_logsize = 0;            /* Maximum logfile size, 0 for no limit */
 
63
int raw_log = 0;                /* Disply output to server to LOG_SERVEROUT */
 
64
 
 
65
int conmask = LOG_MODES | LOG_CMDS | LOG_MISC; /* Console mask */
61
66
 
62
67
struct help_list_t {
63
68
  struct help_list_t *next;
130
135
  return 0;
131
136
}
132
137
 
133
 
/*        This implementation wont overrun dst - 'max' is the max bytes that dst
134
 
 *      can be, including the null terminator. So if 'dst' is a 128 byte buffer,
135
 
 *      pass 128 as 'max'. The function will _always_ null-terminate 'dst'.
136
 
 *
137
 
 *      Returns: The number of characters appended to 'dst'.
138
 
 *
139
 
 *  Usage eg.
140
 
 *
141
 
 *              char    buf[128];
142
 
 *              size_t  bufsize = sizeof(buf);
143
 
 *
144
 
 *              buf[0] = 0, bufsize--;
145
 
 *
146
 
 *              while (blah && bufsize) {
147
 
 *                      bufsize -= egg_strcatn(buf, <some-long-string>, sizeof(buf));
148
 
 *              }
149
 
 *
150
 
 *      <Cybah>
 
138
/*  This implementation wont overrun dst - 'max' is the max bytes that dst
 
139
 *  can be, including the null terminator. So if 'dst' is a 128 byte buffer,
 
140
 *  pass 128 as 'max'. The function will _always_ null-terminate 'dst'.
 
141
 *
 
142
 *  Returns: The number of characters appended to 'dst'.
 
143
 *
 
144
 *  Usage example:
 
145
 *
 
146
 *    char buf[128];
 
147
 *    size_t bufsize = sizeof(buf);
 
148
 *
 
149
 *    buf[0] = 0, bufsize--;
 
150
 *
 
151
 *    while (blah && bufsize) {
 
152
 *      bufsize -= egg_strcatn(buf, <some-long-string>, sizeof(buf));
 
153
 *    }
 
154
 *
 
155
 *  <Cybah>
151
156
 */
152
157
int egg_strcatn(char *dst, const char *src, size_t max)
153
158
{
254
259
  return "";
255
260
}
256
261
 
 
262
void remove_crlf(char **line)
 
263
{
 
264
  char *p;
 
265
 
 
266
  p = strchr(*line, '\n');
 
267
  if (p != NULL)
 
268
    *p = 0;
 
269
  p = strchr(*line, '\r');
 
270
  if (p != NULL)
 
271
    *p = 0;
 
272
}
 
273
 
257
274
char *newsplit(char **rest)
258
275
{
259
276
  register char *o, *r;
278
295
 * or "abc!user@3ffe:604:2:b02e:6174:7265:6964:6573" into
279
296
 *    "*!user@3ffe:604:2:b02e:6174:7265:6964:*"
280
297
 */
281
 
void maskhost(const char *s, char *nw)
 
298
void _maskhost(const char *s, char *nw, int host)
282
299
{
283
300
  register const char *p, *q, *e, *f;
284
301
  int i;
299
316
    while (*p != '@') {
300
317
      if (!fl && strchr("~+-^=", *p)) {
301
318
        if (strict_host)
302
 
          nw[i] = '?';
303
 
        else
304
 
          i--;
 
319
          nw[i] = '?';
 
320
        else if (!host)
 
321
          nw[i] = '*';
 
322
        else
 
323
          i--;
305
324
      } else
306
 
        nw[i] = *p;
 
325
        nw[i] = *p;
307
326
      fl++;
308
327
      p++;
309
328
      i++;
323
342
    /* TLD or 2 part host */
324
343
    strcpy(nw, q);
325
344
  else {
326
 
    if (e == NULL) {            /* IPv6 address?                */
 
345
    if (e == NULL) {            /* IPv6 address?                */
327
346
      const char *mask_str;
328
347
 
329
348
      f = strrchr(q, ':');
330
 
      if (strchr(f, '.')) {     /* IPv4 wrapped in an IPv6?     */
331
 
        f = strrchr(f, '.');
332
 
        mask_str = ".*";
333
 
      } else                    /* ... no, true IPv6.           */
334
 
        mask_str = ":*";
 
349
      if (strchr(f, '.')) {     /* IPv4 wrapped in an IPv6?     */
 
350
        f = strrchr(f, '.');
 
351
        mask_str = ".*";
 
352
      } else                      /* ... no, true IPv6.               */
 
353
        mask_str = ":*";
335
354
      strncpy(nw, q, f - q);
336
355
      /* No need to nw[f-q] = 0 here, as the strcpy below will
337
356
       * terminate the string for us.
341
360
    } else {
342
361
      for (f = e; *f; f++);
343
362
      f--;
344
 
      if (*f >= '0' && *f <= '9') {     /* Numeric IP address */
345
 
        while (*f != '.')
346
 
          f--;
347
 
        strncpy(nw, q, f - q);
348
 
        /* No need to nw[f-q] = 0 here, as the strcpy below will
349
 
         * terminate the string for us.
350
 
         */
351
 
        nw += (f - q);
352
 
        strcpy(nw, ".*");
353
 
      } else {                          /* Normal host >= 3 parts */
354
 
        /*    a.b.c  -> *.b.c
355
 
         *    a.b.c.d ->  *.b.c.d if tld is a country (2 chars)
356
 
         *             OR   *.c.d if tld is com/edu/etc (3 chars)
357
 
         *    a.b.c.d.e -> *.c.d.e   etc
358
 
         */
359
 
        const char *x = strchr(e + 1, '.');
 
363
      if (*f >= '0' && *f <= '9') {     /* Numeric IP address */
 
364
        while (*f != '.')
 
365
          f--;
 
366
        strncpy(nw, q, f - q);
 
367
        /* No need to nw[f-q] = 0 here, as the strcpy below will
 
368
         * terminate the string for us.
 
369
         */
 
370
        nw += (f - q);
 
371
        strcpy(nw, ".*");
 
372
      } else {                    /* Normal host >= 3 parts */
 
373
        /*    a.b.c  -> *.b.c
 
374
         *    a.b.c.d ->  *.b.c.d if tld is a country (2 chars)
 
375
         *             OR   *.c.d if tld is com/edu/etc (3 chars)
 
376
         *    a.b.c.d.e -> *.c.d.e   etc
 
377
         */
 
378
        const char *x = strchr(e + 1, '.');
360
379
 
361
 
        if (!x)
362
 
          x = p;
363
 
        else if (strchr(x + 1, '.'))
364
 
          x = e;
365
 
        else if (strlen(x) == 3)
366
 
          x = p;
367
 
        else
368
 
          x = e;
369
 
        sprintf(nw, "*%s", x);
 
380
        if (!x)
 
381
          x = p;
 
382
        else if (strchr(x + 1, '.'))
 
383
          x = e;
 
384
        else if (strlen(x) == 3)
 
385
          x = p;
 
386
        else
 
387
          x = e;
 
388
        sprintf(nw, "*%s", x);
370
389
      }
371
390
    }
372
391
  }
376
395
 */
377
396
void dumplots(int idx, const char *prefix, char *data)
378
397
{
379
 
  char          *p = data, *q, *n, c;
380
 
  const int      max_data_len = 500 - strlen(prefix);
 
398
  char *p = data, *q, *n, c;
 
399
  const int max_data_len = 500 - strlen(prefix);
381
400
 
382
401
  if (!*data) {
383
402
    dprintf(idx, "%s\n", prefix);
396
415
    } else {
397
416
      /* Search backwards for the last space */
398
417
      while (*q != ' ' && q != p)
399
 
        q--;
 
418
        q--;
400
419
      if (q == p)
401
 
        q = p + max_data_len;
 
420
        q = p + max_data_len;
402
421
      c = *q;
403
422
      *q = 0;
404
423
      dprintf(idx, "%s%s\n", prefix, p);
405
424
      *q = c;
406
425
      p = q;
407
426
      if (c == ' ')
408
 
        p++;
 
427
        p++;
409
428
    }
410
429
  }
411
430
  /* Last trailing bit: split by linefeeds if possible */
418
437
    n = strchr(p, '\n');
419
438
  }
420
439
  if (*p)
421
 
    dprintf(idx, "%s%s\n", prefix, p);  /* Last trailing bit */
 
440
    dprintf(idx, "%s%s\n", prefix, p);  /* Last trailing bit */
422
441
}
423
442
 
424
443
/* Convert an interval (in seconds) to one of:
481
500
 */
482
501
void putlog EGG_VARARGS_DEF(int, arg1)
483
502
{
484
 
  int i, type;
485
 
  char *format, *chname, s[LOGLINELEN], s1[256], *out;
486
 
  time_t tt;
487
 
  char ct[81], *s2;
488
 
  struct tm *t = localtime(&now);
 
503
  int i, type, tsl = 0;
 
504
  char *format, *chname, s[LOGLINELEN], s1[256], *out, ct[81], *s2, stamp[34];
489
505
  va_list va;
 
506
  time_t now2 = time(NULL);
 
507
  struct tm *t = localtime(&now2);
490
508
 
491
509
  type = EGG_VARARGS_START(int, arg1, va);
492
510
  chname = va_arg(va, char *);
493
511
  format = va_arg(va, char *);
494
512
 
495
 
  /* Format log entry at offset 8, then i can prepend the timestamp */
496
 
  out = &s[8];
 
513
  /* Create the timestamp */
 
514
  t = localtime(&now2);
 
515
  if (shtime) {
 
516
    egg_strftime(stamp, sizeof(stamp) - 2, LOG_TS, t);
 
517
    strcat(stamp, " ");
 
518
    tsl = strlen(stamp);
 
519
  }
 
520
  else
 
521
    *stamp = '\0';
 
522
 
 
523
  /* Format log entry at offset 'tsl,' then i can prepend the timestamp */
 
524
  out = s + tsl;
497
525
  /* No need to check if out should be null-terminated here,
498
526
   * just do it! <cybah>
499
527
   */
500
 
  egg_vsnprintf(out, LOGLINEMAX - 8, format, va);
501
 
  out[LOGLINEMAX - 8] = 0;
502
 
  tt = now;
 
528
  egg_vsnprintf(out, LOGLINEMAX - tsl, format, va);
 
529
  out[LOGLINEMAX - tsl] = 0;
503
530
  if (keep_all_logs) {
504
531
    if (!logfile_suffix[0])
505
 
      egg_strftime(ct, 12, ".%d%b%Y", localtime(&tt));
 
532
      egg_strftime(ct, 12, ".%d%b%Y", t);
506
533
    else {
507
 
      egg_strftime(ct, 80, logfile_suffix, localtime(&tt));
 
534
      egg_strftime(ct, 80, logfile_suffix, t);
508
535
      ct[80] = 0;
509
536
      s2 = ct;
510
537
      /* replace spaces by underscores */
511
538
      while (s2[0]) {
512
 
        if (s2[0] == ' ')
513
 
          s2[0] = '_';
514
 
        s2++;
 
539
        if (s2[0] == ' ')
 
540
          s2[0] = '_';
 
541
        s2++;
515
542
      }
516
543
    }
517
544
  }
518
 
  if ((out[0]) && (shtime)) {
519
 
    egg_strftime(s1, 9, "[%H:%M] ", localtime(&tt));
520
 
    strncpy(&s[0], s1, 8);
 
545
  /* Place the timestamp in the string to be printed */
 
546
  if (out[0] && shtime) {
 
547
    strncpy(s, stamp, tsl);
521
548
    out = s;
522
549
  }
523
550
  strcat(out, "\n");
524
551
  if (!use_stderr) {
525
552
    for (i = 0; i < max_logs; i++) {
526
553
      if ((logs[i].filename != NULL) && (logs[i].mask & type) &&
527
 
          ((chname[0] == '*') || (logs[i].chname[0] == '*') ||
528
 
           (!rfc_casecmp(chname, logs[i].chname)))) {
529
 
        if (logs[i].f == NULL) {
530
 
          /* Open this logfile */
531
 
          if (keep_all_logs) {
532
 
            egg_snprintf(s1, 256, "%s%s", logs[i].filename, ct);
533
 
            logs[i].f = fopen(s1, "a+");
534
 
          } else
535
 
            logs[i].f = fopen(logs[i].filename, "a+");
536
 
        }
537
 
        if (logs[i].f != NULL) {
538
 
          /* Check if this is the same as the last line added to
539
 
           * the log. <cybah>
540
 
           */
541
 
          if (!egg_strcasecmp(out + 8, logs[i].szlast)) {
542
 
            /* It is a repeat, so increment repeats */
543
 
            logs[i].repeats++;
544
 
          } else {
545
 
            /* Not a repeat, check if there were any repeat
546
 
             * lines previously...
547
 
             */
548
 
            if (logs[i].repeats > 0) {
549
 
              /* Yep.. so display 'last message repeated x times'
550
 
               * then reset repeats. We want the current time here,
551
 
               * so put that in the file first.
552
 
               */
553
 
              if (t) {
554
 
                fprintf(logs[i].f, "[%2.2d:%2.2d] ", t->tm_hour, t->tm_min);
555
 
                fprintf(logs[i].f, MISC_LOGREPEAT, logs[i].repeats);
556
 
              } else {
557
 
                fprintf(logs[i].f, "[??:??] ");
558
 
                fprintf(logs[i].f, MISC_LOGREPEAT, logs[i].repeats);
559
 
              }
560
 
              logs[i].repeats = 0;
561
 
              /* No need to reset logs[i].szlast here
562
 
               * because we update it later on...
563
 
               */
564
 
            }
565
 
            fputs(out, logs[i].f);
566
 
            strncpyz(logs[i].szlast, out + 8, LOGLINEMAX);
567
 
          }
568
 
        }
 
554
          ((chname[0] == '*') || (logs[i].chname[0] == '*') ||
 
555
           (!rfc_casecmp(chname, logs[i].chname)))) {
 
556
        if (logs[i].f == NULL) {
 
557
          /* Open this logfile */
 
558
          if (keep_all_logs) {
 
559
            egg_snprintf(s1, 256, "%s%s", logs[i].filename, ct);
 
560
            logs[i].f = fopen(s1, "a+");
 
561
          } else
 
562
            logs[i].f = fopen(logs[i].filename, "a+");
 
563
        }
 
564
        if (logs[i].f != NULL) {
 
565
          /* Check if this is the same as the last line added to
 
566
           * the log. <cybah>
 
567
           */
 
568
          if (!egg_strcasecmp(out + tsl, logs[i].szlast))
 
569
            /* It is a repeat, so increment repeats */
 
570
            logs[i].repeats++;
 
571
          else {
 
572
            /* Not a repeat, check if there were any repeat
 
573
             * lines previously...
 
574
             */
 
575
            if (logs[i].repeats > 0) {
 
576
              /* Yep.. so display 'last message repeated x times'
 
577
               * then reset repeats. We want the current time here,
 
578
               * so put that in the file first.
 
579
               */
 
580
              fprintf(logs[i].f, stamp);
 
581
              fprintf(logs[i].f, MISC_LOGREPEAT, logs[i].repeats);
 
582
              logs[i].repeats = 0;
 
583
              /* No need to reset logs[i].szlast here
 
584
               * because we update it later on...
 
585
               */
 
586
            }
 
587
            fputs(out, logs[i].f);
 
588
            strncpyz(logs[i].szlast, out + tsl, LOGLINEMAX);
 
589
          }
 
590
        }
569
591
      }
570
592
    }
571
593
  }
572
 
  for (i = 0; i < dcc_total; i++)
 
594
  for (i = 0; i < dcc_total; i++) {
573
595
    if ((dcc[i].type == &DCC_CHAT) && (dcc[i].u.chat->con_flags & type)) {
574
596
      if ((chname[0] == '*') || (dcc[i].u.chat->con_chan[0] == '*') ||
575
 
          (!rfc_casecmp(chname, dcc[i].u.chat->con_chan)))
576
 
        dprintf(i, "%s", out);
 
597
          !rfc_casecmp(chname, dcc[i].u.chat->con_chan)) {
 
598
        dprintf(i, "%s", out);
 
599
      }
577
600
    }
578
 
  if ((!backgrd) && (!con_chan) && (!term_z))
 
601
  }
 
602
  if (!backgrd && !con_chan && !term_z)
579
603
    dprintf(DP_STDOUT, "%s", out);
580
604
  else if ((type & LOG_MISC) && use_stderr) {
581
605
    if (shtime)
582
 
      out += 8;
 
606
      out += tsl;
583
607
    dprintf(DP_STDERR, "%s", s);
584
608
  }
585
609
  va_end(va);
590
614
 */
591
615
void logsuffix_change(char *s)
592
616
{
593
 
  int    i;
594
 
  char  *s2 = logfile_suffix;
 
617
  int i;
 
618
  char *s2 = logfile_suffix;
 
619
 
 
620
  /* If the suffix didn't really change, ignore. It's probably a rehash. */
 
621
  if (s && s2 && !strcmp(s, s2))
 
622
    return;
595
623
 
596
624
  debug0("Logfile suffix changed. Closing all open logs.");
597
625
  strcpy(logfile_suffix, s);
613
641
{
614
642
  struct stat ss;
615
643
  int i;
 
644
 
616
645
/* int x=1; */
617
 
  char buf[1024];               /* Should be plenty */
 
646
  char buf[1024];               /* Should be plenty */
618
647
 
619
648
  if (!keep_all_logs && max_logsize > 0) {
620
649
    for (i = 0; i < max_logs; i++) {
621
650
      if (logs[i].filename) {
622
 
        if (stat(logs[i].filename, &ss) != 0) {
623
 
          break;
624
 
        }
625
 
        if ((ss.st_size >> 10) > max_logsize) {
626
 
          if (logs[i].f) {
627
 
            /* write to the log before closing it huh.. */
628
 
            putlog(LOG_MISC, "*", MISC_CLOGS, logs[i].filename, ss.st_size);
629
 
            fflush(logs[i].f);
630
 
            fclose(logs[i].f);
631
 
            logs[i].f = NULL;
632
 
          }
 
651
        if (stat(logs[i].filename, &ss) != 0) {
 
652
          break;
 
653
        }
 
654
        if ((ss.st_size >> 10) > max_logsize) {
 
655
          if (logs[i].f) {
 
656
            /* write to the log before closing it huh.. */
 
657
            putlog(LOG_MISC, "*", MISC_CLOGS, logs[i].filename, ss.st_size);
 
658
            fflush(logs[i].f);
 
659
            fclose(logs[i].f);
 
660
            logs[i].f = NULL;
 
661
          }
633
662
 
634
 
          egg_snprintf(buf, sizeof buf, "%s.yesterday", logs[i].filename);
635
 
          buf[1023] = 0;
636
 
          unlink(buf);
637
 
          movefile(logs[i].filename, buf);
638
 
        }
 
663
          egg_snprintf(buf, sizeof buf, "%s.yesterday", logs[i].filename);
 
664
          buf[1023] = 0;
 
665
          unlink(buf);
 
666
          movefile(logs[i].filename, buf);
 
667
        }
639
668
      }
640
669
    }
641
670
  }
646
675
void flushlogs()
647
676
{
648
677
  int i;
649
 
  struct tm *t = localtime(&now);
650
678
 
651
679
  /* Logs may not be initialised yet. */
652
680
  if (!logs)
657
685
   */
658
686
  for (i = 0; i < max_logs; i++) {
659
687
    if (logs[i].f != NULL) {
660
 
       if ((logs[i].repeats > 0) && quick_logs) {
661
 
         /* Repeat.. if quicklogs used then display 'last message
662
 
          * repeated x times' and reset repeats.
663
 
          */
664
 
        if (t) {
665
 
          fprintf(logs[i].f, "[%2.2d:%2.2d] ", t->tm_hour, t->tm_min);
666
 
          fprintf(logs[i].f, MISC_LOGREPEAT, logs[i].repeats);
667
 
        } else {
668
 
          fprintf(logs[i].f, "[??:??] ");
669
 
          fprintf(logs[i].f, MISC_LOGREPEAT, logs[i].repeats);
670
 
        }
671
 
        /* Reset repeats */
672
 
        logs[i].repeats = 0;
 
688
      if ((logs[i].repeats > 0) && quick_logs) {
 
689
        /* Repeat.. if quicklogs used then display 'last message
 
690
         * repeated x times' and reset repeats.
 
691
         */
 
692
        char stamp[33];
 
693
 
 
694
        egg_strftime(stamp, sizeof(stamp) - 1, LOG_TS, localtime(&now));
 
695
        fprintf(logs[i].f, "%s ", stamp);
 
696
        fprintf(logs[i].f, MISC_LOGREPEAT, logs[i].repeats);
 
697
        /* Reset repeats */
 
698
        logs[i].repeats = 0;
673
699
      }
674
700
      fflush(logs[i].f);
675
701
    }
681
707
 *     String substitution functions
682
708
 */
683
709
 
684
 
static int       cols = 0;
685
 
static int       colsofar = 0;
686
 
static int       blind = 0;
687
 
static int       subwidth = 70;
688
 
static char     *colstr = NULL;
 
710
static int cols = 0;
 
711
static int colsofar = 0;
 
712
static int blind = 0;
 
713
static int subwidth = 70;
 
714
static char *colstr = NULL;
689
715
 
690
716
 
691
717
/* Add string to colstr
698
724
  if ((newcol[0]) && (newcol[0] != '\377'))
699
725
    colsofar++;
700
726
  colstr = nrealloc(colstr, strlen(colstr) + strlen(newcol) +
701
 
                    (colstr[0] ? 2 : 1));
 
727
                    (colstr[0] ? 2 : 1));
702
728
  if ((newcol[0]) && (newcol[0] != '\377')) {
703
729
    if (colstr[0])
704
730
      strcat(colstr, "\377");
714
740
      *p = 0;
715
741
      strcat(s, q);
716
742
      for (i = strlen(q); i < colwidth; i++)
717
 
        strcat(s, " ");
 
743
        strcat(s, " ");
718
744
      q = p + 1;
719
745
      p = strchr(q, '\377');
720
746
    }
750
776
#define HELP_FLASH 8
751
777
 
752
778
void help_subst(char *s, char *nick, struct flag_record *flags,
753
 
                int isdcc, char *topic)
 
779
                int isdcc, char *topic)
754
780
{
755
781
  char xx[HELP_BUF_LEN + 1], sub[161], *current, *q, chr, *writeidx,
756
 
  *readidx, *towrite;
 
782
       *readidx, *towrite;
757
783
  struct chanset_t *chan;
758
784
  int i, j, center = 0;
759
785
  static int help_flags;
 
786
 
760
787
#ifdef HAVE_UNAME
761
788
  struct utsname uname_info;
762
789
#endif
794
821
    switch (chr) {
795
822
    case 'b':
796
823
      if (glob_hilite(*flags)) {
797
 
        if (help_flags & HELP_IRC) {
798
 
          towrite = "\002";
799
 
        } else if (help_flags & HELP_BOLD) {
800
 
          help_flags &= ~HELP_BOLD;
801
 
          towrite = "\033[0m";
802
 
        } else {
803
 
          help_flags |= HELP_BOLD;
804
 
          towrite = "\033[1m";
805
 
        }
 
824
        if (help_flags & HELP_IRC) {
 
825
          towrite = "\002";
 
826
        } else if (help_flags & HELP_BOLD) {
 
827
          help_flags &= ~HELP_BOLD;
 
828
          towrite = "\033[0m";
 
829
        } else {
 
830
          help_flags |= HELP_BOLD;
 
831
          towrite = "\033[1m";
 
832
        }
806
833
      }
807
834
      break;
808
835
    case 'v':
809
836
      if (glob_hilite(*flags)) {
810
 
        if (help_flags & HELP_IRC) {
811
 
          towrite = "\026";
812
 
        } else if (help_flags & HELP_REV) {
813
 
          help_flags &= ~HELP_REV;
814
 
          towrite = "\033[0m";
815
 
        } else {
816
 
          help_flags |= HELP_REV;
817
 
          towrite = "\033[7m";
818
 
        }
 
837
        if (help_flags & HELP_IRC) {
 
838
          towrite = "\026";
 
839
        } else if (help_flags & HELP_REV) {
 
840
          help_flags &= ~HELP_REV;
 
841
          towrite = "\033[0m";
 
842
        } else {
 
843
          help_flags |= HELP_REV;
 
844
          towrite = "\033[7m";
 
845
        }
819
846
      }
820
847
      break;
821
848
    case '_':
822
849
      if (glob_hilite(*flags)) {
823
 
        if (help_flags & HELP_IRC) {
824
 
          towrite = "\037";
825
 
        } else if (help_flags & HELP_UNDER) {
826
 
          help_flags &= ~HELP_UNDER;
827
 
          towrite = "\033[0m";
828
 
        } else {
829
 
          help_flags |= HELP_UNDER;
830
 
          towrite = "\033[4m";
831
 
        }
 
850
        if (help_flags & HELP_IRC) {
 
851
          towrite = "\037";
 
852
        } else if (help_flags & HELP_UNDER) {
 
853
          help_flags &= ~HELP_UNDER;
 
854
          towrite = "\033[0m";
 
855
        } else {
 
856
          help_flags |= HELP_UNDER;
 
857
          towrite = "\033[4m";
 
858
        }
832
859
      }
833
860
      break;
834
861
    case 'f':
835
862
      if (glob_hilite(*flags)) {
836
 
        if (help_flags & HELP_FLASH) {
837
 
          if (help_flags & HELP_IRC) {
838
 
            towrite = "\002\037";
839
 
          } else {
840
 
            towrite = "\033[0m";
841
 
          }
842
 
          help_flags &= ~HELP_FLASH;
843
 
        } else {
844
 
          help_flags |= HELP_FLASH;
845
 
          if (help_flags & HELP_IRC) {
846
 
            towrite = "\037\002";
847
 
          } else {
848
 
            towrite = "\033[5m";
849
 
          }
850
 
        }
 
863
        if (help_flags & HELP_FLASH) {
 
864
          if (help_flags & HELP_IRC)
 
865
            towrite = "\002\037";
 
866
          else
 
867
            towrite = "\033[0m";
 
868
          help_flags &= ~HELP_FLASH;
 
869
        } else {
 
870
          help_flags |= HELP_FLASH;
 
871
          if (help_flags & HELP_IRC)
 
872
            towrite = "\037\002";
 
873
          else
 
874
            towrite = "\033[5m";
 
875
        }
851
876
      }
852
877
      break;
853
878
    case 'U':
854
879
#ifdef HAVE_UNAME
855
 
      if (!uname(&uname_info)) {
856
 
        egg_snprintf(sub, sizeof sub, "%s %s", uname_info.sysname,
857
 
                       uname_info.release);
858
 
        towrite = sub;
 
880
      if (uname(&uname_info) >= 0) {
 
881
        egg_snprintf(sub, sizeof sub, "%s %s", uname_info.sysname,
 
882
                     uname_info.release);
 
883
        towrite = sub;
859
884
      } else
860
885
#endif
861
 
        towrite = "*UNKNOWN*";
 
886
        towrite = "*UNKNOWN*";
862
887
      break;
863
888
    case 'B':
864
889
      towrite = (isdcc ? botnetnick : botname);
882
907
    case 'N':
883
908
      towrite = strchr(nick, ':');
884
909
      if (towrite)
885
 
        towrite++;
 
910
        towrite++;
886
911
      else
887
 
        towrite = nick;
 
912
        towrite = nick;
888
913
      break;
889
914
    case 'C':
890
915
      if (!blind)
891
 
        for (chan = chanset; chan; chan = chan->next) {
892
 
          if ((strlen(chan->dname) + writeidx + 2) >=
893
 
              (s + HELP_BUF_LEN)) {
894
 
            strncpy(writeidx, chan->dname, (s + HELP_BUF_LEN) - writeidx);
895
 
            s[HELP_BUF_LEN] = 0;
896
 
            return;
897
 
          }
898
 
          writeidx += my_strcpy(writeidx, chan->dname);
899
 
          if (chan->next) {
900
 
            *writeidx++ = ',';
901
 
            *writeidx++ = ' ';
902
 
          }
903
 
        }
 
916
        for (chan = chanset; chan; chan = chan->next) {
 
917
          if ((strlen(chan->dname) + writeidx + 2) >= (s + HELP_BUF_LEN)) {
 
918
            strncpy(writeidx, chan->dname, (s + HELP_BUF_LEN) - writeidx);
 
919
            s[HELP_BUF_LEN] = 0;
 
920
            return;
 
921
          }
 
922
          writeidx += my_strcpy(writeidx, chan->dname);
 
923
          if (chan->next) {
 
924
            *writeidx++ = ',';
 
925
            *writeidx++ = ' ';
 
926
          }
 
927
        }
904
928
      break;
905
929
    case '{':
906
930
      q = current;
907
931
      current++;
908
932
      while ((*current != '}') && (*current))
909
 
        current++;
 
933
        current++;
910
934
      if (*current) {
911
 
        *current = 0;
912
 
        current--;
913
 
        q += 2;
914
 
        /* Now q is the string and p is where the rest of the fcn expects */
915
 
        if (!strncmp(q, "help=", 5)) {
916
 
          if (topic && egg_strcasecmp(q + 5, topic))
917
 
            blind |= 2;
918
 
          else
919
 
            blind &= ~2;
920
 
        } else if (!(blind & 2)) {
921
 
          if (q[0] == '+') {
922
 
            struct flag_record fr =
923
 
            {FR_GLOBAL | FR_CHAN, 0, 0, 0, 0, 0};
924
 
 
925
 
            break_down_flags(q + 1, &fr, NULL);
926
 
            if (!flagrec_ok(&fr, flags))
927
 
              blind |= 1;
928
 
            else
929
 
              blind &= ~1;
930
 
          } else if (q[0] == '-') {
931
 
            blind &= ~1;
932
 
          } else if (!egg_strcasecmp(q, "end")) {
933
 
            blind &= ~1;
934
 
            subwidth = 70;
935
 
            if (cols) {
936
 
              sub[0] = 0;
937
 
              subst_addcol(sub, "\377");
938
 
              nfree(colstr);
939
 
              colstr = NULL;
940
 
              cols = 0;
941
 
              towrite = sub;
942
 
            }
943
 
          } else if (!egg_strcasecmp(q, "center"))
944
 
            center = 1;
945
 
          else if (!strncmp(q, "cols=", 5)) {
946
 
            char *r;
947
 
 
948
 
            cols = atoi(q + 5);
949
 
            colsofar = 0;
950
 
            colstr = (char *) nmalloc(1);
951
 
            colstr[0] = 0;
952
 
            r = strchr(q + 5, '/');
953
 
            if (r != NULL)
954
 
              subwidth = atoi(r + 1);
955
 
          }
956
 
        }
 
935
        *current = 0;
 
936
        current--;
 
937
        q += 2;
 
938
        /* Now q is the string and p is where the rest of the fcn expects */
 
939
        if (!strncmp(q, "help=", 5)) {
 
940
          if (topic && egg_strcasecmp(q + 5, topic))
 
941
            blind |= 2;
 
942
          else
 
943
            blind &= ~2;
 
944
        } else if (!(blind & 2)) {
 
945
          if (q[0] == '+') {
 
946
            struct flag_record fr = { FR_GLOBAL | FR_CHAN, 0, 0, 0, 0, 0 };
 
947
 
 
948
            break_down_flags(q + 1, &fr, NULL);
 
949
            if (!flagrec_ok(&fr, flags))
 
950
              blind |= 1;
 
951
            else
 
952
              blind &= ~1;
 
953
          } else if (q[0] == '-')
 
954
            blind &= ~1;
 
955
          else if (!egg_strcasecmp(q, "end")) {
 
956
            blind &= ~1;
 
957
            subwidth = 70;
 
958
            if (cols) {
 
959
              sub[0] = 0;
 
960
              subst_addcol(sub, "\377");
 
961
              nfree(colstr);
 
962
              colstr = NULL;
 
963
              cols = 0;
 
964
              towrite = sub;
 
965
            }
 
966
          } else if (!egg_strcasecmp(q, "center"))
 
967
            center = 1;
 
968
          else if (!strncmp(q, "cols=", 5)) {
 
969
            char *r;
 
970
 
 
971
            cols = atoi(q + 5);
 
972
            colsofar = 0;
 
973
            colstr = (char *) nmalloc(1);
 
974
            colstr[0] = 0;
 
975
            r = strchr(q + 5, '/');
 
976
            if (r != NULL)
 
977
              subwidth = atoi(r + 1);
 
978
          }
 
979
        }
957
980
      } else
958
 
        current = q;            /* no } so ignore */
 
981
        current = q;            /* no } so ignore */
959
982
      break;
960
983
    default:
961
984
      if (!blind) {
962
 
        *writeidx++ = chr;
963
 
        if (writeidx >= (s + HELP_BUF_LEN)) {
964
 
          *writeidx = 0;
965
 
          return;
966
 
        }
 
985
        *writeidx++ = chr;
 
986
        if (writeidx >= (s + HELP_BUF_LEN)) {
 
987
          *writeidx = 0;
 
988
          return;
 
989
        }
967
990
      }
968
991
    }
969
992
    if (towrite && !blind) {
970
993
      if ((writeidx + strlen(towrite)) >= (s + HELP_BUF_LEN)) {
971
 
        strncpy(writeidx, towrite, (s + HELP_BUF_LEN) - writeidx);
972
 
        s[HELP_BUF_LEN] = 0;
973
 
        return;
 
994
        strncpy(writeidx, towrite, (s + HELP_BUF_LEN) - writeidx);
 
995
        s[HELP_BUF_LEN] = 0;
 
996
        return;
974
997
      }
975
998
      writeidx += my_strcpy(writeidx, towrite);
976
999
    }
998
1021
    if (i > 0) {
999
1022
      s[0] = 0;
1000
1023
      for (j = 0; j < i; j++)
1001
 
        s[j] = ' ';
 
1024
        s[j] = ' ';
1002
1025
      strcpy(s + i, xx);
1003
1026
    }
1004
1027
  }
1019
1042
    while (!feof(f)) {
1020
1043
      fgets(s, HELP_BUF_LEN, f);
1021
1044
      if (!feof(f)) {
1022
 
        p = s;
1023
 
        while ((q = strstr(p, "%{help="))) {
1024
 
          q += 7;
1025
 
          if ((p = strchr(q, '}'))) {
1026
 
            *p = 0;
1027
 
            list = nmalloc(sizeof(struct help_list_t));
 
1045
        p = s;
 
1046
        while ((q = strstr(p, "%{help="))) {
 
1047
          q += 7;
 
1048
          if ((p = strchr(q, '}'))) {
 
1049
            *p = 0;
 
1050
            list = nmalloc(sizeof(struct help_list_t));
1028
1051
 
1029
 
            list->name = nmalloc(p - q + 1);
1030
 
            strcpy(list->name, q);
1031
 
            list->next = current->first;
1032
 
            list->type = type;
1033
 
            current->first = list;
1034
 
            p++;
1035
 
          } else
1036
 
            p = "";
1037
 
        }
 
1052
            list->name = nmalloc(p - q + 1);
 
1053
            strcpy(list->name, q);
 
1054
            list->next = current->first;
 
1055
            list->type = type;
 
1056
            current->first = list;
 
1057
            p++;
 
1058
          } else
 
1059
            p = "";
 
1060
        }
1038
1061
      }
1039
1062
    }
1040
1063
    fclose(f);
1048
1071
 
1049
1072
  for (current = help_list; current; current = current->next)
1050
1073
    if (!strcmp(current->name, file))
1051
 
      return;                   /* Already exists, can't re-add :P */
 
1074
      return;                   /* Already exists, can't re-add :P */
1052
1075
  current = nmalloc(sizeof(struct help_ref));
1053
1076
 
1054
1077
  current->name = nmalloc(strlen(file) + 1);
1072
1095
  for (current = help_list; current; last = current, current = current->next)
1073
1096
    if (!strcmp(current->name, file)) {
1074
1097
      while ((item = current->first)) {
1075
 
        current->first = item->next;
1076
 
        nfree(item->name);
1077
 
        nfree(item);
 
1098
        current->first = item->next;
 
1099
        nfree(item->name);
 
1100
        nfree(item);
1078
1101
      }
1079
1102
      nfree(current->name);
1080
1103
      if (last)
1081
 
        last->next = current->next;
 
1104
        last->next = current->next;
1082
1105
      else
1083
 
        help_list = current->next;
 
1106
        help_list = current->next;
1084
1107
      nfree(current);
1085
1108
      return;
1086
1109
    }
1115
1138
    dprintf(idx, "HELP FILE(S): %s\n", current->name);
1116
1139
    for (item = current->first; item; item = item->next) {
1117
1140
      dprintf(idx, "   %s (%s)\n", item->name, (item->type == 0) ? "msg/" :
1118
 
              (item->type == 1) ? "" : "set/");
 
1141
              (item->type == 1) ? "" : "set/");
1119
1142
    }
1120
1143
  }
1121
1144
}
1129
1152
  struct help_list_t *item;
1130
1153
 
1131
1154
  /* Somewhere here goes the eventual substituation */
1132
 
  if (!(dcc & HELP_TEXT))
1133
 
  {
 
1155
  if (!(dcc & HELP_TEXT)) {
1134
1156
    for (current = help_list; current; current = current->next)
1135
1157
      for (item = current->first; item; item = item->next)
1136
 
        if (!strcmp(item->name, file)) {
1137
 
          if (!item->type && !dcc) {
1138
 
            egg_snprintf(s, sizeof s, "%smsg/%s", helpdir, current->name);
1139
 
            if ((f = fopen(s, "r")))
1140
 
              return f;
1141
 
          } else if (dcc && item->type) {
1142
 
            if (item->type == 1)
1143
 
              egg_snprintf(s, sizeof s, "%s%s", helpdir, current->name);
1144
 
            else
1145
 
              egg_snprintf(s, sizeof s, "%sset/%s", helpdir, current->name);
1146
 
            if ((f = fopen(s, "r")))
1147
 
              return f;
1148
 
          }
1149
 
        }
 
1158
        if (!strcmp(item->name, file)) {
 
1159
          if (!item->type && !dcc) {
 
1160
            egg_snprintf(s, sizeof s, "%smsg/%s", helpdir, current->name);
 
1161
            if ((f = fopen(s, "r")))
 
1162
              return f;
 
1163
          } else if (dcc && item->type) {
 
1164
            if (item->type == 1)
 
1165
              egg_snprintf(s, sizeof s, "%s%s", helpdir, current->name);
 
1166
            else
 
1167
              egg_snprintf(s, sizeof s, "%sset/%s", helpdir, current->name);
 
1168
            if ((f = fopen(s, "r")))
 
1169
              return f;
 
1170
          }
 
1171
        }
1150
1172
    /* No match was found, so we better return NULL */
1151
1173
    return NULL;
1152
1174
  }
1165
1187
  FILE *f = resolve_help(fl, file);
1166
1188
 
1167
1189
  if (f) {
1168
 
    help_subst(NULL, NULL, 0, HELP_IRC, NULL);  /* Clear flags */
 
1190
    help_subst(NULL, NULL, 0, HELP_IRC, NULL);  /* Clear flags */
1169
1191
    while (!feof(f)) {
1170
1192
      fgets(s, HELP_BUF_LEN, f);
1171
1193
      if (!feof(f)) {
1172
 
        if (s[strlen(s) - 1] == '\n')
1173
 
          s[strlen(s) - 1] = 0;
1174
 
        if (!s[0])
1175
 
          strcpy(s, " ");
1176
 
        help_subst(s, who, flags, 0, file);
1177
 
        if ((s[0]) && (strlen(s) > 1)) {
1178
 
          dprintf(DP_HELP, "NOTICE %s :%s\n", who, s);
1179
 
          lines++;
1180
 
        }
 
1194
        if (s[strlen(s) - 1] == '\n')
 
1195
          s[strlen(s) - 1] = 0;
 
1196
        if (!s[0])
 
1197
          strcpy(s, " ");
 
1198
        help_subst(s, who, flags, 0, file);
 
1199
        if ((s[0]) && (strlen(s) > 1)) {
 
1200
          dprintf(DP_HELP, "NOTICE %s :%s\n", who, s);
 
1201
          lines++;
 
1202
        }
1181
1203
      }
1182
1204
    }
1183
1205
    fclose(f);
1187
1209
}
1188
1210
 
1189
1211
static int display_tellhelp(int idx, char *file, FILE *f,
1190
 
                            struct flag_record *flags)
 
1212
                            struct flag_record *flags)
1191
1213
{
1192
1214
  char s[HELP_BUF_LEN + 1];
1193
1215
  int lines = 0;
1194
1216
 
1195
1217
  if (f) {
1196
1218
    help_subst(NULL, NULL, 0,
1197
 
               (dcc[idx].status & STAT_TELNET) ? 0 : HELP_IRC, NULL);
 
1219
               (dcc[idx].status & STAT_TELNET) ? 0 : HELP_IRC, NULL);
1198
1220
    while (!feof(f)) {
1199
1221
      fgets(s, HELP_BUF_LEN, f);
1200
1222
      if (!feof(f)) {
1201
 
        if (s[strlen(s) - 1] == '\n')
1202
 
          s[strlen(s) - 1] = 0;
1203
 
        if (!s[0])
1204
 
          strcpy(s, " ");
1205
 
        help_subst(s, dcc[idx].nick, flags, 1, file);
1206
 
        if (s[0]) {
1207
 
          dprintf(idx, "%s\n", s);
1208
 
          lines++;
1209
 
        }
 
1223
        if (s[strlen(s) - 1] == '\n')
 
1224
          s[strlen(s) - 1] = 0;
 
1225
        if (!s[0])
 
1226
          strcpy(s, " ");
 
1227
        help_subst(s, dcc[idx].nick, flags, 1, file);
 
1228
        if (s[0]) {
 
1229
          dprintf(idx, "%s\n", s);
 
1230
          lines++;
 
1231
        }
1210
1232
      }
1211
1233
    }
1212
1234
    fclose(f);
1238
1260
  for (current = help_list; current; current = current->next)
1239
1261
    for (item = current->first; item; item = item->next)
1240
1262
      if (wild_match(match, item->name) && item->type) {
1241
 
        if (item->type == 1)
1242
 
          egg_snprintf(s, sizeof s, "%s%s", helpdir, current->name);
1243
 
        else
1244
 
          egg_snprintf(s, sizeof s, "%sset/%s", helpdir, current->name);
1245
 
        if ((f = fopen(s, "r")))
1246
 
          display_tellhelp(idx, item->name, f, flags);
 
1263
        if (item->type == 1)
 
1264
          egg_snprintf(s, sizeof s, "%s%s", helpdir, current->name);
 
1265
        else
 
1266
          egg_snprintf(s, sizeof s, "%sset/%s", helpdir, current->name);
 
1267
        if ((f = fopen(s, "r")))
 
1268
          display_tellhelp(idx, item->name, f, flags);
1247
1269
      }
1248
1270
  if (!s[0])
1249
1271
    dprintf(idx, "%s\n", IRC_NOHELP2);
1263
1285
    for (item = current->first; item; item = item->next)
1264
1286
      if (!strcmp(match, item->name) && item->type) {
1265
1287
 
1266
 
        if (item->type == 1)
1267
 
          egg_snprintf(s, sizeof s, "%s%s", helpdir, current->name);
1268
 
        else
1269
 
          egg_snprintf(s, sizeof s, "%sset/%s", helpdir, current->name);
1270
 
        if ((f = fopen(s, "r")))
1271
 
          display_tellhelp(idx, item->name, f, flags);
 
1288
        if (item->type == 1)
 
1289
          egg_snprintf(s, sizeof s, "%s%s", helpdir, current->name);
 
1290
        else
 
1291
          egg_snprintf(s, sizeof s, "%sset/%s", helpdir, current->name);
 
1292
        if ((f = fopen(s, "r")))
 
1293
          display_tellhelp(idx, item->name, f, flags);
1272
1294
      }
1273
1295
  if (!s[0])
1274
1296
    dprintf(idx, "%s\n", IRC_NOHELP2);
1279
1301
void sub_lang(int idx, char *text)
1280
1302
{
1281
1303
  char s[1024];
1282
 
  struct flag_record fr = {FR_GLOBAL | FR_CHAN, 0, 0, 0, 0, 0};
 
1304
  struct flag_record fr = { FR_GLOBAL | FR_CHAN, 0, 0, 0, 0, 0 };
1283
1305
 
1284
1306
  get_user_flagrec(dcc[idx].user, &fr, dcc[idx].u.chat->con_chan);
1285
1307
  help_subst(NULL, NULL, 0,
1286
 
             (dcc[idx].status & STAT_TELNET) ? 0 : HELP_IRC, NULL);
 
1308
             (dcc[idx].status & STAT_TELNET) ? 0 : HELP_IRC, NULL);
1287
1309
  strncpyz(s, text, sizeof s);
1288
1310
  if (s[strlen(s) - 1] == '\n')
1289
1311
    s[strlen(s) - 1] = 0;
1301
1323
char *extracthostname(char *hostmask)
1302
1324
{
1303
1325
  char *p = strrchr(hostmask, '@');
 
1326
 
1304
1327
  return p ? p + 1 : "";
1305
1328
}
1306
1329
 
1310
1333
{
1311
1334
  FILE *vv;
1312
1335
  char s[1024];
1313
 
  struct flag_record fr = {FR_GLOBAL | FR_CHAN, 0, 0, 0, 0, 0};
 
1336
  struct flag_record fr = { FR_GLOBAL | FR_CHAN, 0, 0, 0, 0, 0 };
1314
1337
 
1315
1338
  if (!is_file(motdfile))
1316
1339
    return;
1323
1346
  dprintf(idx, "\n");
1324
1347
  /* reset the help_subst variables to their defaults */
1325
1348
  help_subst(NULL, NULL, 0,
1326
 
             (dcc[idx].status & STAT_TELNET) ? 0 : HELP_IRC, NULL);
 
1349
             (dcc[idx].status & STAT_TELNET) ? 0 : HELP_IRC, NULL);
1327
1350
  while (!feof(vv)) {
1328
1351
    fgets(s, 120, vv);
1329
1352
    if (!feof(vv)) {
1330
1353
      if (s[strlen(s) - 1] == '\n')
1331
 
        s[strlen(s) - 1] = 0;
 
1354
        s[strlen(s) - 1] = 0;
1332
1355
      if (!s[0])
1333
 
        strcpy(s, " ");
 
1356
        strcpy(s, " ");
1334
1357
      help_subst(s, dcc[idx].nick, &fr, 1, botnetnick);
1335
1358
      if (s[0])
1336
 
        dprintf(idx, "%s\n", s);
 
1359
        dprintf(idx, "%s\n", s);
1337
1360
    }
1338
1361
  }
1339
1362
  fclose(vv);
1340
1363
  dprintf(idx, "\n");
1341
1364
}
1342
1365
 
1343
 
/* Show banner to telnet user 
 
1366
/* Show banner to telnet user
1344
1367
 */
1345
 
void show_banner(int idx) {
 
1368
void show_banner(int idx)
 
1369
{
1346
1370
  FILE *vv;
1347
1371
  char s[1024];
1348
 
  struct flag_record fr = {FR_GLOBAL | FR_CHAN, 0, 0, 0, 0, 0};
 
1372
  struct flag_record fr = { FR_GLOBAL | FR_CHAN, 0, 0, 0, 0, 0 };
1349
1373
 
1350
1374
  if (!is_file(bannerfile))
1351
1375
    return;
1354
1378
  if (!vv)
1355
1379
    return;
1356
1380
 
1357
 
  get_user_flagrec(dcc[idx].user, &fr,dcc[idx].u.chat->con_chan);
 
1381
  get_user_flagrec(dcc[idx].user, &fr, dcc[idx].u.chat->con_chan);
1358
1382
  /* reset the help_subst variables to their defaults */
1359
1383
  help_subst(NULL, NULL, 0, 0, NULL);
1360
 
  while(!feof(vv)) {
 
1384
  while (!feof(vv)) {
1361
1385
    fgets(s, 120, vv);
1362
1386
    if (!feof(vv)) {
1363
1387
      if (!s[0])
1364
 
        strcpy(s, " \n");
 
1388
        strcpy(s, " \n");
1365
1389
      help_subst(s, dcc[idx].nick, &fr, 0, botnetnick);
1366
1390
      dprintf(idx, "%s", s);
1367
1391
    }
1376
1400
  int j;
1377
1401
 
1378
1402
  for (j = 0; j < len; j++) {
1379
 
    if (random() % 3 == 0)
1380
 
      s[j] = '0' + (random() % 10);
 
1403
    if (!randint(3))
 
1404
      s[j] = '0' + randint(10);
1381
1405
    else
1382
 
      s[j] = 'a' + (random() % 26);
 
1406
      s[j] = 'a' + randint(26);
1383
1407
  }
1384
1408
  s[len] = 0;
1385
1409
}
1408
1432
 */
1409
1433
char *str_escape(const char *str, const char div, const char mask)
1410
1434
{
1411
 
  const int      len = strlen(str);
1412
 
  int            buflen = (2 * len), blen = 0;
1413
 
  char          *buf = nmalloc(buflen + 1), *b = buf;
1414
 
  const char    *s;
 
1435
  const int len = strlen(str);
 
1436
  int buflen = (2 * len), blen = 0;
 
1437
  char *buf = nmalloc(buflen + 1), *b = buf;
 
1438
  const char *s;
1415
1439
 
1416
1440
  if (!buf)
1417
1441
    return NULL;
1421
1445
      buflen = (buflen * 2);
1422
1446
      buf = nrealloc(buf, buflen + 1);
1423
1447
      if (!buf)
1424
 
        return NULL;
 
1448
        return NULL;
1425
1449
      b = buf + blen;
1426
1450
    }
1427
1451
 
1457
1481
 */
1458
1482
char *strchr_unescape(char *str, const char div, register const char esc_char)
1459
1483
{
1460
 
  char           buf[3];
1461
 
  register char *s, *p;
 
1484
  char buf[3];
 
1485
  register char *s, *p;
1462
1486
 
1463
 
  buf[3] = 0;
 
1487
  buf[2] = 0;
1464
1488
  for (s = p = str; *s; s++, p++) {
1465
 
    if (*s == esc_char) {       /* Found escape character.              */
 
1489
    if (*s == esc_char) {       /* Found escape character.              */
1466
1490
      /* Convert code to character. */
1467
1491
      buf[0] = s[1], buf[1] = s[2];
1468
1492
      *p = (unsigned char) strtol(buf, NULL, 16);
1469
1493
      s += 2;
1470
1494
    } else if (*s == div) {
1471
1495
      *p = *s = 0;
1472
 
      return (s + 1);           /* Found searched for character.        */
 
1496
      return (s + 1);           /* Found searched for character.        */
1473
1497
    } else
1474
1498
      *p = *s;
1475
1499
  }
1477
1501
  return NULL;
1478
1502
}
1479
1503
 
 
1504
/* Is every character in a string a digit? */
 
1505
int str_isdigit(const char *str)
 
1506
{
 
1507
  if (!*str)
 
1508
    return 0;
 
1509
 
 
1510
  for (; *str; ++str) {
 
1511
    if (!egg_isdigit(*str))
 
1512
      return 0;
 
1513
  }
 
1514
  return 1;
 
1515
}
 
1516
 
1480
1517
/* As strchr_unescape(), but converts the complete string, without
1481
1518
 * searching for a specific delimiter character.
1482
1519
 */
1485
1522
  (void) strchr_unescape(str, 0, esc_char);
1486
1523
}
1487
1524
 
1488
 
/* Kills the bot. s1 is the reason shown to other bots, 
 
1525
/* Kills the bot. s1 is the reason shown to other bots,
1489
1526
 * s2 the reason shown on the partyline. (Sup 25Jul2001)
1490
1527
 */
1491
1528
void kill_bot(char *s1, char *s2)