Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
BitchX
GitHub Repository: BitchX/BitchX1.3
Path: blob/master/source/ircaux.c
1069 views
1
/*
2
* ircaux.c: some extra routines... not specific to irc... that I needed
3
*
4
* Written By Michael Sandrof
5
*
6
* Copyright(c) 1990, 1991
7
*
8
* See the COPYRIGHT file, or do a HELP IRCII COPYRIGHT
9
*/
10
#include "irc.h"
11
static char cvsrevision[] = "$Id: ircaux.c 206 2012-06-13 12:34:32Z keaston $";
12
CVS_REVISION(ircaux_c)
13
#include "struct.h"
14
15
#include "alias.h"
16
#include "log.h"
17
#include "misc.h"
18
#include "vars.h"
19
#include "screen.h"
20
21
#include <pwd.h>
22
23
#include <sys/stat.h>
24
25
#include "ircaux.h"
26
#include "output.h"
27
#include "ircterm.h"
28
#define MAIN_SOURCE
29
#include "modval.h"
30
31
#ifndef MAXPATHLEN
32
#define MAXPATHLEN PATHLEN
33
#endif
34
35
/*
36
* These are used by the malloc routines. We actually ask for an int-size
37
* more of memory, and in that extra int we store the malloc size. Very
38
* handy for debugging and other hackeries.
39
*/
40
41
/*#define MEM_DEBUG 1*/
42
43
#ifdef MEM_DEBUG
44
#include <dmalloc.h>
45
#endif
46
47
/* This union is used to ensure that the resulting address
48
* will be aligned correctly for all types we use. */
49
union alloc_info {
50
size_t size;
51
52
void *dummy1;
53
long dummy2;
54
double dummy3;
55
};
56
57
#define alloc_start(ptr) ((void *)((char *)(ptr) - sizeof(union alloc_info)))
58
#define alloc_size(ptr) (((union alloc_info *)alloc_start(ptr))->size)
59
60
#define FREE_DEBUG 1
61
#define FREED_VAL (size_t)-3
62
#define ALLOC_MAGIC 0xafbdce70
63
64
char compress_buffer[10000];
65
66
void start_memdebug(void)
67
{
68
#ifdef MEM_DEBUG
69
dmalloc_debug(/*0x2202*/0x14f41d83);
70
#endif
71
}
72
73
/*
74
* really_new_malloc is the general interface to the malloc(3) call.
75
* It is only called by way of the ``new_malloc'' #define.
76
* It wont ever return NULL.
77
*/
78
79
/*
80
* Malloc allocator with size caching.
81
*/
82
void * n_malloc (size_t size, const char *module, const char *file, const int line)
83
{
84
char *ptr;
85
86
if (size < FREED_VAL - sizeof(union alloc_info))
87
{
88
#ifdef MEM_DEBUG
89
ptr = _calloc_leap(file, line, 1, size + sizeof(union alloc_info));
90
#else
91
ptr = calloc(1, size + sizeof(union alloc_info));
92
#endif
93
}
94
else
95
{
96
ptr = NULL;
97
}
98
99
if (!ptr)
100
{
101
yell("Malloc() failed, giving up!");
102
putlog(LOG_ALL, "*", "*** failed calloc %s %s (%d)", module?module:empty_string, file, line);
103
term_reset();
104
exit(1);
105
}
106
/* Store the size of the allocation in the buffer. */
107
ptr += sizeof(union alloc_info);
108
alloc_size(ptr) = size;
109
return ptr;
110
}
111
112
/*
113
* new_free: Why do this? Why not? Saves me a bit of trouble here and there
114
*/
115
void * n_free(void *ptr, const char *module, const char *file, const int line)
116
{
117
if (ptr)
118
{
119
#ifdef FREE_DEBUG
120
/* Check to make sure its not been freed before */
121
if (alloc_size(ptr) == FREED_VAL)
122
{
123
yell("free()ing a already free'd pointer, giving up!");
124
putlog(LOG_ALL, "*", "*** failed free %s %s (%d)", module?module:empty_string, file, line);
125
term_reset();
126
exit(1);
127
}
128
#endif
129
alloc_size(ptr) = FREED_VAL;
130
131
#ifdef MEM_DEBUG
132
_free_leap(file, line, alloc_start(ptr));
133
#else
134
free(alloc_start(ptr));
135
#endif
136
ptr = NULL;
137
}
138
return ptr;
139
}
140
141
void * n_realloc (void *ptr, size_t size, const char *module, const char *file, const int line)
142
{
143
char *ptr2 = NULL;
144
145
if (ptr)
146
{
147
if (size)
148
{
149
size_t msize = alloc_size(ptr);
150
151
if (msize >= size)
152
return ptr;
153
154
ptr2 = n_malloc(size, module, file, line);
155
memmove(ptr2, ptr, msize);
156
n_free(ptr, module, file, line);
157
return ptr2;
158
}
159
return n_free(ptr, module, file, line);
160
}
161
else if (size)
162
ptr2 = n_malloc(size, module, file, line);
163
return ptr2;
164
}
165
166
/*
167
* malloc_strcpy: Mallocs enough space for src to be copied in to where
168
* ptr points to.
169
*
170
* Never call this with ptr pointinng to an uninitialised string, as the
171
* call to new_free() might crash the client... - phone, jan, 1993.
172
*/
173
char * n_malloc_strcpy (char **ptr, const char *src, const char *module, const char *file, const int line)
174
{
175
if (!src)
176
return *ptr = n_free(*ptr, module, file, line);
177
if (ptr && *ptr)
178
{
179
if (*ptr == src)
180
return *ptr;
181
if (alloc_size(*ptr) > strlen(src))
182
return strcpy(*ptr, src);
183
*ptr = n_free(*ptr, module, file, line);
184
}
185
*ptr = n_malloc(strlen(src) + 1, module, file, line);
186
return strcpy(*ptr, src);
187
return *ptr;
188
}
189
190
/* malloc_strcat: Yeah, right */
191
char * n_malloc_strcat (char **ptr, const char *src, const char *module, const char *file, const int line)
192
{
193
size_t msize;
194
195
if (*ptr)
196
{
197
if (!src)
198
return *ptr;
199
msize = strlen(*ptr) + strlen(src) + 1;
200
*ptr = n_realloc(*ptr, sizeof(char)*msize, module, file, line);
201
return strcat(*ptr, src);
202
}
203
return (*ptr = n_m_strdup(src, module, file, line));
204
}
205
206
char *BX_malloc_str2cpy(char **ptr, const char *src1, const char *src2)
207
{
208
if (!src1 && !src2)
209
return new_free(ptr);
210
211
if (*ptr)
212
{
213
if (alloc_size(*ptr) > strlen(src1) + strlen(src2))
214
return strcat(strcpy(*ptr, src1), src2);
215
new_free(ptr);
216
}
217
218
*ptr = new_malloc(strlen(src1) + strlen(src2) + 1);
219
return strcat(strcpy(*ptr, src1), src2);
220
}
221
222
char *BX_m_3dup (const char *str1, const char *str2, const char *str3)
223
{
224
size_t msize = strlen(str1) + strlen(str2) + strlen(str3) + 1;
225
return strcat(strcat(strcpy((char *)new_malloc(msize), str1), str2), str3);
226
}
227
228
char *BX_m_opendup (const char *str1, ...)
229
{
230
va_list args;
231
int size;
232
char *this_arg = NULL;
233
char *retval = NULL;
234
235
size = strlen(str1);
236
va_start(args, str1);
237
while ((this_arg = va_arg(args, char *)))
238
size += strlen(this_arg);
239
240
retval = (char *)new_malloc(size + 1);
241
242
strcpy(retval, str1);
243
va_start(args, str1);
244
while ((this_arg = va_arg(args, char *)))
245
strcat(retval, this_arg);
246
247
va_end(args);
248
return retval;
249
}
250
251
char *n_m_strdup (const char *str, const char *module, const char *file, const int line)
252
{
253
char *ptr;
254
255
if (!str)
256
str = empty_string;
257
ptr = (char *)n_malloc(strlen(str) + 1, module, file, line);
258
return strcpy(ptr, str);
259
}
260
261
char *BX_m_s3cat (char **one, const char *maybe, const char *definitely)
262
{
263
if (*one && **one)
264
return m_3cat(one, maybe, definitely);
265
return malloc_strcpy(one, definitely);
266
}
267
268
char *BX_m_s3cat_s (char **one, const char *maybe, const char *ifthere)
269
{
270
if (ifthere && *ifthere)
271
return m_3cat(one, maybe, ifthere);
272
return *one;
273
}
274
275
char *BX_m_3cat(char **one, const char *two, const char *three)
276
{
277
int len = 0;
278
char *str;
279
280
if (*one)
281
len = strlen(*one);
282
if (two)
283
len += strlen(two);
284
if (three)
285
len += strlen(three);
286
len += 1;
287
288
str = (char *)new_malloc(len);
289
if (*one)
290
strcpy(str, *one);
291
if (two)
292
strcat(str, two);
293
if (three)
294
strcat(str, three);
295
296
new_free(one);
297
return ((*one = str));
298
}
299
300
char *BX_upper (char *str)
301
{
302
register char *ptr = NULL;
303
304
if (str)
305
{
306
ptr = str;
307
for (; *str; str++)
308
{
309
if (islower((unsigned char)*str))
310
*str = toupper(*str);
311
}
312
}
313
return (ptr);
314
}
315
316
char *BX_lower (char *str)
317
{
318
register char *ptr = NULL;
319
320
if (str)
321
{
322
ptr = str;
323
for (; *str; str++)
324
{
325
if (isupper((unsigned char)*str))
326
*str = tolower(*str);
327
}
328
}
329
return (ptr);
330
}
331
332
char *BX_malloc_sprintf (char **to, const char *pattern, ...)
333
{
334
char booya[BIG_BUFFER_SIZE*3+1];
335
*booya = 0;
336
337
if (pattern)
338
{
339
va_list args;
340
va_start (args, pattern);
341
vsnprintf(booya, BIG_BUFFER_SIZE * 3, pattern, args);
342
va_end(args);
343
}
344
malloc_strcpy(to, booya);
345
return *to;
346
}
347
348
/* same thing, different variation */
349
char *BX_m_sprintf (const char *pattern, ...)
350
{
351
char booya[BIG_BUFFER_SIZE * 3 + 1];
352
*booya = 0;
353
354
if (pattern)
355
{
356
va_list args;
357
va_start (args, pattern);
358
vsnprintf(booya, BIG_BUFFER_SIZE * 3, pattern, args);
359
va_end(args);
360
}
361
return m_strdup(booya);
362
}
363
364
/* case insensitive string searching */
365
char *BX_stristr (const char *source, const char *search)
366
{
367
int x = 0;
368
369
if (!source || !*source || !search || !*search || strlen(source) < strlen(search))
370
return NULL;
371
372
while (*source)
373
{
374
if (source[x] && toupper(source[x]) == toupper(search[x]))
375
x++;
376
else if (search[x])
377
source++, x = 0;
378
else
379
return (char *)source;
380
}
381
return NULL;
382
}
383
384
/* case insensitive string searching from the end */
385
char *BX_rstristr (char *source, char *search)
386
{
387
char *ptr;
388
int x = 0;
389
390
if (!source || !*source || !search || !*search || strlen(source) < strlen(search))
391
return NULL;
392
393
ptr = source + strlen(source) - strlen(search);
394
395
while (ptr >= source)
396
{
397
if (!search[x])
398
return ptr;
399
400
if (toupper(ptr[x]) == toupper(search[x]))
401
x++;
402
else
403
ptr--, x = 0;
404
}
405
return NULL;
406
}
407
408
/*
409
* word_count: Efficient way to find out how many words are in
410
* a given string. Relies on isspace() not being broken.
411
*/
412
int BX_word_count (char *str)
413
{
414
int cocs = 0;
415
int isv = 1;
416
register char *foo = str;
417
418
if (!foo)
419
return 0;
420
421
while (*foo)
422
{
423
if (*foo == '"' && isv)
424
{
425
while (*(foo+1) && *++foo != '"')
426
;
427
isv = 0;
428
cocs++;
429
}
430
if (!my_isspace(*foo) != !isv)
431
{
432
isv = my_isspace(*foo);
433
cocs++;
434
}
435
foo++;
436
}
437
return (cocs + 1) / 2;
438
}
439
440
#if 0
441
extern int word_scount (char *str)
442
{
443
int cocs = 0;
444
char *foo = str;
445
int isv = 1;
446
447
if (!foo)
448
return 0;
449
450
while (*foo)
451
{
452
if (my_isspace(*foo) != !isv)
453
{
454
isv = my_isspace(*foo);
455
cocs++;
456
}
457
foo++;
458
}
459
return (cocs + 1) / 2;
460
}
461
#endif
462
463
char *BX_next_arg (char *str, char **new_ptr)
464
{
465
char *ptr;
466
467
/* added by Sheik ([email protected]) -- sanity */
468
if (!str || !*str)
469
return NULL;
470
471
if ((ptr = sindex(str, "^ ")) != NULL)
472
{
473
if ((str = sindex(ptr, space)) != NULL)
474
*str++ = (char) 0;
475
else
476
str = empty_string;
477
}
478
else
479
str = empty_string;
480
if (new_ptr)
481
*new_ptr = str;
482
return ptr;
483
}
484
485
extern char *BX_remove_trailing_spaces (char *foo)
486
{
487
char *end;
488
if (!*foo)
489
return foo;
490
491
end = foo + strlen(foo) - 1;
492
while (end > foo && my_isspace(*end))
493
end--;
494
end[1] = 0;
495
return foo;
496
}
497
498
/*
499
* yanks off the last word from 'src'
500
* kinda the opposite of next_arg
501
*/
502
char *BX_last_arg (char **src)
503
{
504
char *ptr;
505
506
if (!src || !*src)
507
return NULL;
508
509
remove_trailing_spaces(*src);
510
ptr = *src + strlen(*src) - 1;
511
512
if (*ptr == '"')
513
{
514
for (ptr--;;ptr--)
515
{
516
if (*ptr == '"')
517
{
518
if (ptr == *src)
519
break;
520
if (ptr[-1] == ' ')
521
{
522
ptr--;
523
break;
524
}
525
}
526
if (ptr == *src)
527
break;
528
}
529
}
530
else
531
{
532
for (;;ptr--)
533
{
534
if (*ptr == ' ')
535
break;
536
if (ptr == *src)
537
break;
538
}
539
}
540
541
if (ptr == *src)
542
{
543
ptr = *src;
544
*src = empty_string;
545
}
546
else
547
{
548
*ptr++ = 0;
549
remove_trailing_spaces(*src);
550
}
551
return ptr;
552
553
}
554
555
#define risspace(c) (c == ' ')
556
char *BX_new_next_arg (char *str, char **new_ptr)
557
{
558
char *ptr,
559
*start;
560
561
if (!str || !*str)
562
return NULL;
563
564
ptr = str;
565
while (*ptr && risspace(*ptr))
566
ptr++;
567
568
if (*ptr == '"')
569
{
570
start = ++ptr;
571
for (str = start; *str; str++)
572
{
573
if (*str == '\\' && str[1])
574
str++;
575
else if (*str == '"')
576
{
577
*(str++) = 0;
578
if (risspace(*str))
579
str++;
580
break;
581
}
582
}
583
}
584
else if (*ptr)
585
{
586
str = ptr;
587
while (*str && !risspace(*str))
588
str++;
589
if (*str)
590
*str++ = 0;
591
}
592
593
if (!*str || !*ptr)
594
str = empty_string;
595
596
if (new_ptr)
597
*new_ptr = str;
598
599
return ptr;
600
}
601
602
/*
603
* This function is "safe" because it doesnt ever return NULL.
604
* XXXX - this is an ugly kludge that needs to go away
605
*/
606
char *safe_new_next_arg (char *str, char **new_ptr)
607
{
608
char *ptr,
609
*start;
610
611
if (!str || !*str)
612
return empty_string;
613
614
if ((ptr = sindex(str, "^ \t")) != NULL)
615
{
616
if (*ptr == '"')
617
{
618
start = ++ptr;
619
while ((str = sindex(ptr, "\"\\")) != NULL)
620
{
621
switch (*str)
622
{
623
case '"':
624
*str++ = '\0';
625
if (*str == ' ')
626
str++;
627
if (new_ptr)
628
*new_ptr = str;
629
return (start);
630
case '\\':
631
if (*(str + 1) == '"')
632
ov_strcpy(str, str + 1);
633
ptr = str + 1;
634
}
635
}
636
str = empty_string;
637
}
638
else
639
{
640
if ((str = sindex(ptr, " \t")) != NULL)
641
*str++ = '\0';
642
else
643
str = empty_string;
644
}
645
}
646
else
647
str = empty_string;
648
649
if (new_ptr)
650
*new_ptr = str;
651
652
if (!ptr)
653
return empty_string;
654
655
return ptr;
656
}
657
658
char *BX_new_new_next_arg (char *str, char **new_ptr, char *type)
659
{
660
char *ptr,
661
*start;
662
663
if (!str || !*str)
664
return NULL;
665
666
if ((ptr = sindex(str, "^ \t")) != NULL)
667
{
668
if ((*ptr == '"') || (*ptr == '\''))
669
{
670
char blah[3];
671
blah[0] = *ptr;
672
blah[1] = '\\';
673
blah[2] = '\0';
674
675
*type = *ptr;
676
start = ++ptr;
677
while ((str = sindex(ptr, blah)) != NULL)
678
{
679
switch (*str)
680
{
681
case '\'':
682
case '"':
683
*str++ = '\0';
684
if (*str == ' ')
685
str++;
686
if (new_ptr)
687
*new_ptr = str;
688
return (start);
689
case '\\':
690
if (str[1] == *type)
691
ov_strcpy(str, str + 1);
692
ptr = str + 1;
693
}
694
}
695
str = empty_string;
696
}
697
else
698
{
699
*type = '\"';
700
if ((str = sindex(ptr, " \t")) != NULL)
701
*str++ = 0;
702
else
703
str = empty_string;
704
}
705
}
706
else
707
str = empty_string;
708
if (new_ptr)
709
*new_ptr = str;
710
return ptr;
711
}
712
713
unsigned char stricmp_table [] =
714
{
715
0, 1, 2, 3, 4, 5, 6, 7,
716
8, 9, 10, 11, 12, 13, 14, 15,
717
16, 17, 18, 19, 20, 21, 22, 23,
718
24, 25, 26, 27, 28, 29, 30, 31,
719
32, 33, 34, 35, 36, 37, 38, 39,
720
40, 41, 42, 43, 44, 45, 46, 47,
721
48, 49, 50, 51, 52, 53, 54, 55,
722
56, 57, 58, 59, 60, 61, 62, 63,
723
64, 65, 66, 67, 68, 69, 70, 71,
724
72, 73, 74, 75, 76, 77, 78, 79,
725
80, 81, 82, 83, 84, 85, 86, 87,
726
88, 89, 90, 91, 92, 93, 94, 95,
727
96, 65, 66, 67, 68, 69, 70, 71,
728
72, 73, 74, 75, 76, 77, 78, 79,
729
80, 81, 82, 83, 84, 85, 86, 87,
730
88, 89, 90, 91, 92, 93, 126, 127,
731
732
128, 129, 130, 131, 132, 133, 134, 135,
733
136, 137, 138, 139, 140, 141, 142, 143,
734
144, 145, 146, 147, 148, 149, 150, 151,
735
152, 153, 154, 155, 156, 157, 158, 159,
736
160, 161, 162, 163, 164, 165, 166, 167,
737
168, 169, 170, 171, 172, 173, 174, 175,
738
176, 177, 178, 179, 180, 181, 182, 183,
739
184, 185, 186, 187, 188, 189, 190, 191,
740
192, 193, 194, 195, 196, 197, 198, 199,
741
200, 201, 202, 203, 204, 205, 206, 207,
742
208, 209, 210, 211, 212, 213, 214, 215,
743
216, 217, 218, 219, 220, 221, 222, 223,
744
224, 225, 226, 227, 228, 229, 230, 231,
745
232, 233, 234, 235, 236, 237, 238, 239,
746
240, 241, 242, 243, 244, 245, 246, 247,
747
248, 249, 250, 251, 252, 253, 254, 255
748
};
749
750
/* my_stricmp: case insensitive version of strcmp */
751
int BX_my_stricmp (const char *str1, const char *str2)
752
{
753
while (*str1 && *str2 && (stricmp_table[(unsigned char)*str1] == stricmp_table[(unsigned char)*str2]))
754
str1++, str2++;
755
return (stricmp_table[(unsigned char)*str1] -
756
stricmp_table[(unsigned char)*str2]);
757
758
}
759
760
/* my_strnicmp: case insensitive version of strncmp */
761
int BX_my_strnicmp (const char *str1, const char *str2, size_t n)
762
{
763
while (n && *str1 && *str2 && (stricmp_table[(unsigned char)*str1] == stricmp_table[(unsigned char)*str2]))
764
str1++, str2++, n--;
765
return (n ?
766
(stricmp_table[(unsigned char)*str1] -
767
stricmp_table[(unsigned char)*str2]) : 0);
768
}
769
770
/* my_strnstr: case insensitive version of strstr */
771
int BX_my_strnstr (register const unsigned char *str1, register const unsigned char *str2, register size_t n)
772
{
773
char *p = (char *)str1;
774
if (!p) return 0;
775
for (; *p; p++)
776
if (!strncasecmp(p, str2, strlen(str2)))
777
return 1;
778
return 0;
779
}
780
781
/* chop -- chops off the last character. capiche? */
782
char *BX_chop (char *stuff, int nchar)
783
{
784
size_t sl = strlen(stuff);
785
if (nchar > 0 && sl > 0 && nchar <= sl)
786
stuff[sl - nchar] = 0;
787
else if (nchar > sl)
788
stuff[0] = 0;
789
return stuff;
790
}
791
792
/*
793
* strext: Makes a copy of the string delmited by two char pointers and
794
* returns it in malloced memory. Useful when you dont want to munge up
795
* the original string with a null. end must be one place beyond where
796
* you want to copy, ie, its the first character you dont want to copy.
797
*/
798
char *strext(char *start, char *end)
799
{
800
char *ptr, *retval;
801
802
ptr = retval = (char *)new_malloc(end-start+1);
803
while (start < end)
804
*ptr++ = *start++;
805
*ptr = 0;
806
return retval;
807
}
808
809
810
/*
811
* strmcpy: Well, it's like this, strncpy doesn't append a trailing null if
812
* strlen(str) == maxlen. strmcpy always makes sure there is a trailing null
813
*/
814
char * BX_strmcpy (char *dest, const char *src, int maxlen)
815
{
816
strlcpy(dest, src, maxlen + 1);
817
return dest;
818
}
819
820
/*
821
* strmcat: like strcat, but truncs the dest string to maxlen (thus the dest
822
* should be able to handle maxlen+1 (for the null))
823
*/
824
char * BX_strmcat(char *dest, const char *src, int maxlen)
825
{
826
strlcat(dest, src, maxlen + 1);
827
return dest;
828
}
829
830
#ifdef INCLUDE_DEADCODE
831
/*
832
* strmcat_ue: like strcat, but truncs the dest string to maxlen (thus the dest
833
* should be able to handle maxlen + 1 (for the null)). Also unescapes
834
* backslashes.
835
*/
836
char * strmcat_ue(char *dest, const char *src, int maxlen)
837
{
838
int dstlen;
839
840
dstlen = strlen(dest);
841
dest += dstlen;
842
maxlen -= dstlen;
843
while (*src && maxlen > 0)
844
{
845
if (*src == '\\')
846
{
847
if (strchr("npr0", src[1]))
848
*dest++ = '\020';
849
else if (*(src + 1))
850
*dest++ = *++src;
851
else
852
*dest++ = '\\';
853
}
854
else
855
*dest++ = *src;
856
src++;
857
}
858
*dest = '\0';
859
return dest;
860
}
861
#endif
862
863
/*
864
* m_strcat_ues: Given two strings, concatenate the 2nd string to
865
* the end of the first one, but if the "unescape" argument is 1, do
866
* unescaping (like in strmcat_ue).
867
* (Malloc_STRCAT_UnEscape Special, in case you were wondering. ;-))
868
*
869
* This uses a cheating, "not-as-efficient-as-possible" algorithm,
870
* but it works with negligible cpu lossage.
871
*/
872
char * n_m_strcat_ues(char **dest, char *src, int unescape, const char *module, const char *file, const int line)
873
{
874
int total_length;
875
char *ptr, *ptr2;
876
int z;
877
878
if (!unescape)
879
{
880
n_malloc_strcat(dest, src, module, file, line);
881
return *dest;
882
}
883
884
z = total_length = (*dest) ? strlen(*dest) : 0;
885
total_length += strlen(src);
886
887
/* RESIZE(*dest, char, total_length + 2);*/
888
*dest = n_realloc(*dest, sizeof(char) * (total_length + 2), module, file, line);
889
if (z == 0)
890
**dest = 0;
891
892
ptr2 = *dest + z;
893
for (ptr = src; *ptr; ptr++)
894
{
895
if (*ptr == '\\')
896
{
897
switch (*++ptr)
898
{
899
case 'n': case 'p': case 'r': case '0':
900
*ptr2++ = '\020';
901
break;
902
case (char) 0:
903
*ptr2++ = '\\';
904
goto end_strcat_ues;
905
break;
906
default:
907
*ptr2++ = *ptr;
908
}
909
}
910
else
911
*ptr2++ = *ptr;
912
}
913
end_strcat_ues:
914
*ptr2 = '\0';
915
916
return *dest;
917
}
918
919
/*
920
* scanstr: looks for an occurrence of str in source. If not found, returns
921
* 0. If it is found, returns the position in source (1 being the first
922
* position). Not the best way to handle this, but what the hell
923
*/
924
extern int BX_scanstr (char *str, char *source)
925
{
926
int i,
927
max,
928
len;
929
930
len = strlen(str);
931
max = strlen(source) - len;
932
for (i = 0; i <= max; i++, source++)
933
{
934
if (!my_strnicmp(source, str, len))
935
return (i + 1);
936
}
937
return (0);
938
}
939
940
#if defined(WINNT) || defined(__EMX__)
941
char *convert_dos(char *str)
942
{
943
register char *p;
944
for (p = str; *p; p++)
945
if (*p == '/')
946
*p = '\\';
947
return str;
948
}
949
950
char *convert_unix(char *arg)
951
{
952
register char *x = arg;
953
while (*x)
954
{
955
if (*x == '\\')
956
*x = '/';
957
x++;
958
}
959
return arg;
960
}
961
962
int is_dos(char *filename)
963
{
964
if (strlen(filename) > 3 && ( (*(filename+1) == ':') && (*(filename+2) == '/' || *(filename+2) == '\\')) )
965
return 1;
966
else
967
return 0;
968
}
969
970
#endif
971
972
973
/* expand_twiddle: expands ~ in pathnames. */
974
char *BX_expand_twiddle (char *str)
975
{
976
char buffer[BIG_BUFFER_SIZE/4 + 1];
977
char *str2;
978
979
#ifdef WINNT
980
convert_unix(str);
981
#endif
982
if (*str == '~')
983
{
984
str++;
985
986
#if defined(WINNT) || defined(__EMX__)
987
if (*str == '\\' || *str == '/')
988
#else
989
if (*str == '/')
990
#endif
991
{
992
strmcpy(buffer, my_path, BIG_BUFFER_SIZE/4);
993
strmcat(buffer, str, BIG_BUFFER_SIZE/4);
994
}
995
else
996
{
997
char *rest;
998
struct passwd *entry;
999
char *p = NULL;
1000
1001
if ((rest = strchr(str, '/')) != NULL)
1002
*rest++ = '\0';
1003
#if defined(WINNT) || defined(__EMX__)
1004
if (((entry = getpwnam(str)) != NULL) || (p = getenv("HOME")))
1005
{
1006
if (p)
1007
strmcpy(buffer, p, BIG_BUFFER_SIZE/4);
1008
else
1009
strmcpy(buffer, entry->pw_dir, BIG_BUFFER_SIZE/4);
1010
#else
1011
if ((entry = getpwnam(str)) != NULL || (p = getenv("HOME")))
1012
{
1013
if (p)
1014
strmcpy(buffer, p, BIG_BUFFER_SIZE/4);
1015
else
1016
strmcpy(buffer, entry->pw_dir, BIG_BUFFER_SIZE/4);
1017
#endif
1018
if (rest)
1019
{
1020
strmcat(buffer, "/", BIG_BUFFER_SIZE/4);
1021
strmcat(buffer, rest, BIG_BUFFER_SIZE/4);
1022
}
1023
}
1024
else
1025
return (char *) NULL;
1026
}
1027
}
1028
else
1029
strmcpy(buffer, str, BIG_BUFFER_SIZE/4);
1030
1031
/* This isnt legal! */
1032
str2 = NULL;
1033
malloc_strcpy(&str2, buffer);
1034
#ifdef __EMX__
1035
convert_unix(str2);
1036
#endif
1037
return str2;
1038
}
1039
1040
/* islegal: true if c is a legal nickname char anywhere but first char */
1041
#define islegal(c) ((((c) >= 'A') && ((c) <= '}')) || \
1042
(((c) >= '0') && ((c) <= '9')) || \
1043
((c) == '-') || ((c) == '_'))
1044
1045
/*
1046
* check_nickname: checks is a nickname is legal. If the first character is
1047
* bad new, null is returned. If the first character is bad, the string is
1048
* truncd down to only legal characters and returned
1049
*
1050
* rewritten, with help from do_nick_name() from the server code (2.8.5),
1051
* phone, april 1993.
1052
*/
1053
char *BX_check_nickname (char *nick)
1054
{
1055
char *s;
1056
int len = 0;
1057
if (!nick || *nick == '-' || isdigit((unsigned char)*nick) ||
1058
!islegal(*nick))
1059
return NULL;
1060
1061
for (s = nick; *s && (s - nick) < NICKNAME_LEN ; s++, len++)
1062
if (!islegal(*s) || my_isspace(*s))
1063
break;
1064
*s = '\0';
1065
1066
return *nick ? nick : NULL;
1067
}
1068
1069
/*
1070
* sindex: much like index(), but it looks for a match of any character in
1071
* the group, and returns that position. If the first character is a ^, then
1072
* this will match the first occurence not in that group.
1073
*/
1074
char *BX_sindex (register char *string, char *group)
1075
{
1076
char *ptr;
1077
1078
if (!string || !group)
1079
return (char *) NULL;
1080
if (*group == '^')
1081
{
1082
group++;
1083
for (; *string; string++)
1084
{
1085
for (ptr = group; *ptr; ptr++)
1086
{
1087
if (*ptr == *string)
1088
break;
1089
}
1090
if (*ptr == '\0')
1091
return string;
1092
}
1093
}
1094
else
1095
{
1096
for (; *string; string++)
1097
{
1098
for (ptr = group; *ptr; ptr++)
1099
{
1100
if (*ptr == *string)
1101
return string;
1102
}
1103
}
1104
}
1105
return (char *) NULL;
1106
}
1107
1108
/*
1109
* rsindex: much like rindex(), but it looks for a match of any character in
1110
* the group, and returns that position. If the first character is a ^, then
1111
* this will match the first occurence not in that group.
1112
*/
1113
char *BX_rsindex (register char *string, char *start, char *group, int howmany)
1114
{
1115
register char *ptr;
1116
1117
if (howmany && string && start && group && start <= string)
1118
{
1119
if (*group == '^')
1120
{
1121
group++;
1122
for (ptr = string; (ptr >= start) && howmany; ptr--)
1123
{
1124
if (!strchr(group, *ptr))
1125
{
1126
if (--howmany == 0)
1127
return ptr;
1128
}
1129
}
1130
}
1131
else
1132
{
1133
for (ptr = string; (ptr >= start) && howmany; ptr--)
1134
{
1135
if (strchr(group, *ptr))
1136
{
1137
if (--howmany == 0)
1138
return ptr;
1139
}
1140
}
1141
}
1142
}
1143
return NULL;
1144
}
1145
1146
/* is_number: returns true if the given string is a number, false otherwise */
1147
int BX_is_number (const char *str)
1148
{
1149
if (!str || !*str)
1150
return 0;
1151
while (*str == ' ')
1152
str++;
1153
if (*str == '-' || *str == '+')
1154
str++;
1155
if (*str)
1156
{
1157
for (; *str; str++)
1158
{
1159
if (!isdigit((unsigned char)(*str)))
1160
return (0);
1161
}
1162
return 1;
1163
}
1164
else
1165
return 0;
1166
}
1167
1168
/* rfgets: exactly like fgets, cept it works backwards through a file! */
1169
char *BX_rfgets (char *buffer, int size, FILE *file)
1170
{
1171
char *ptr;
1172
off_t pos;
1173
1174
if (fseek(file, -2L, SEEK_CUR))
1175
return NULL;
1176
do
1177
{
1178
switch (fgetc(file))
1179
{
1180
case EOF:
1181
return NULL;
1182
case '\n':
1183
pos = ftell(file);
1184
ptr = fgets(buffer, size, file);
1185
fseek(file, pos, 0);
1186
return ptr;
1187
}
1188
}
1189
while (fseek(file, -2L, SEEK_CUR) == 0);
1190
rewind(file);
1191
pos = 0L;
1192
ptr = fgets(buffer, size, file);
1193
fseek(file, pos, 0);
1194
return ptr;
1195
}
1196
1197
/*
1198
* path_search: given a file called name, this will search each element of
1199
* the given path to locate the file. If found in an element of path, the
1200
* full path name of the file is returned in a static string. If not, null
1201
* is returned. Path is a colon separated list of directories
1202
*/
1203
char *BX_path_search (char *name, char *path)
1204
{
1205
static char buffer[BIG_BUFFER_SIZE/2 + 1];
1206
char *ptr,
1207
*free_path = NULL;
1208
1209
/* A "relative" path is valid if the file exists */
1210
/* A "relative" path is searched in the path if the
1211
filename doesnt really exist from where we are */
1212
if (strchr(name, '/'))
1213
if (!access(name, F_OK))
1214
return name;
1215
1216
/* an absolute path is always checked, never searched */
1217
#if defined(WINNT) || defined(__EMX__)
1218
if (name[0] == '/' || name[0] == '\\')
1219
#else
1220
if (name[0] == '/')
1221
#endif
1222
return (access(name, F_OK) ? NULL : name);
1223
1224
if (!path)
1225
return NULL;
1226
1227
/* This is cheating. >;-) */
1228
free_path = LOCAL_COPY(path);
1229
path = free_path;
1230
1231
#ifdef __EMX__
1232
convert_unix(path);
1233
#endif
1234
while (path)
1235
{
1236
#if defined(WINNT) || defined(__EMX__)
1237
if (((ptr = strchr(path, ';')) != NULL) || ((ptr = strchr(path, ':')) != NULL))
1238
#else
1239
if ((ptr = strchr(path, ':')) != NULL)
1240
#endif
1241
*ptr++ = '\0';
1242
*buffer = 0;
1243
if (path[0] == '~')
1244
{
1245
strmcat(buffer, my_path, BIG_BUFFER_SIZE/4);
1246
path++;
1247
}
1248
strmcat(buffer, path, BIG_BUFFER_SIZE/4);
1249
strmcat(buffer, "/", BIG_BUFFER_SIZE/4);
1250
strmcat(buffer, name, BIG_BUFFER_SIZE/4);
1251
1252
if (access(buffer, F_OK) == 0)
1253
break;
1254
path = ptr;
1255
}
1256
1257
return (path != NULL) ? buffer : NULL;
1258
}
1259
1260
/*
1261
* double_quote: Given a str of text, this will quote any character in the
1262
* set stuff with the QUOTE_CHAR. It returns a malloced quoted, null
1263
* terminated string
1264
*/
1265
char *BX_double_quote (const char *str, const char *stuff, char *buffer)
1266
{
1267
register char c;
1268
register int pos;
1269
1270
*buffer = 0;
1271
if (!stuff)
1272
return buffer;
1273
for (pos = 0; (c = *str); str++)
1274
{
1275
if (strchr(stuff, c))
1276
{
1277
if (c == '$')
1278
buffer[pos++] = '$';
1279
else
1280
buffer[pos++] = '\\';
1281
}
1282
buffer[pos++] = c;
1283
}
1284
buffer[pos] = '\0';
1285
return buffer;
1286
}
1287
1288
char *quote_it (const char *str, const char *stuff, char *buffer)
1289
{
1290
register char c;
1291
register int pos;
1292
1293
*buffer = 0;
1294
for (pos = 0; (c = *str); str++)
1295
{
1296
if (stuff && strchr(stuff, c))
1297
{
1298
if (c == '%')
1299
buffer[pos++] = '%';
1300
else
1301
buffer[pos++] = '\\';
1302
}
1303
else if (c == '%')
1304
buffer[pos++] = '%';
1305
buffer[pos++] = c;
1306
}
1307
buffer[pos] = '\0';
1308
return buffer;
1309
}
1310
1311
void BX_ircpanic (char *format, ...)
1312
{
1313
char buffer[3 * BIG_BUFFER_SIZE + 1];
1314
extern char cx_function[];
1315
static int recursion = 0;
1316
if (recursion || x_debug & DEBUG_CRASH)
1317
abort();
1318
1319
recursion++;
1320
if (format)
1321
{
1322
va_list arglist;
1323
va_start(arglist, format);
1324
vsnprintf(buffer, BIG_BUFFER_SIZE, format, arglist);
1325
va_end(arglist);
1326
}
1327
1328
yell("An unrecoverable logic error has occured.");
1329
yell("Please email " BUG_EMAIL " and include the following message:");
1330
1331
yell("Panic: [%s:%s %s]", irc_version, buffer, cx_function?cx_function:empty_string);
1332
dump_call_stack();
1333
irc_exit(1, "BitchX panic... Could it possibly be a bug? Nahhhh...", NULL);
1334
}
1335
1336
/* Not very complicated, but very handy function to have */
1337
int BX_end_strcmp (const char *one, const char *two, int bytes)
1338
{
1339
if (bytes < strlen(one))
1340
return (strcmp(one + strlen (one) - (size_t) bytes, two));
1341
else
1342
return -1;
1343
}
1344
1345
/* beep_em: Not hard to figure this one out */
1346
void BX_beep_em (int beeps)
1347
{
1348
int cnt,
1349
i;
1350
1351
for (cnt = beeps, i = 0; i < cnt; i++)
1352
term_beep();
1353
}
1354
1355
1356
1357
FILE *open_compression (char *executable, char *filename, int hook)
1358
{
1359
FILE *file_pointer = NULL;
1360
int pipes[2];
1361
1362
1363
pipes[0] = -1;
1364
pipes[1] = -1;
1365
1366
if (pipe (pipes) == -1)
1367
{
1368
if (hook)
1369
yell("Cannot start decompression: %s\n", strerror(errno));
1370
if (pipes[0] != -1)
1371
{
1372
close (pipes[0]);
1373
close (pipes[1]);
1374
}
1375
return NULL;
1376
}
1377
1378
switch (fork ())
1379
{
1380
case -1:
1381
{
1382
if (hook)
1383
yell("Cannot start decompression: %s\n", strerror(errno));
1384
return NULL;
1385
}
1386
case 0:
1387
{
1388
int i;
1389
#if !defined(WINNT) && !defined(__EMX__)
1390
setsid();
1391
#endif
1392
setuid (getuid ());
1393
setgid (getgid ());
1394
dup2 (pipes[1], 1);
1395
close (pipes[0]);
1396
for (i = 2; i < 256; i++)
1397
close(i);
1398
#ifdef ZARGS
1399
execl (executable, executable, "-c", ZARGS, filename, NULL);
1400
#else
1401
execl (executable, executable, "-c", filename, NULL);
1402
#endif
1403
_exit (0);
1404
}
1405
default :
1406
{
1407
close (pipes[1]);
1408
if ((file_pointer = fdopen(pipes[0], "r")) == NULL)
1409
{
1410
if (hook)
1411
yell("Cannot start decompression: %s\n", strerror(errno));
1412
return NULL;
1413
}
1414
#if 0
1415
setlinebuf(file_pointer);
1416
setvbuf(file_pointer, NULL, _IONBF, 0);
1417
#endif
1418
break;
1419
}
1420
}
1421
return file_pointer;
1422
}
1423
1424
/* Front end to fopen() that will open ANY file, compressed or not, and
1425
* is relatively smart about looking for the possibilities, and even
1426
* searches a path for you! ;-)
1427
*/
1428
FILE *BX_uzfopen (char **filename, char *path, int hook)
1429
{
1430
static int setup = 0;
1431
int ok_to_decompress = 0;
1432
char * filename_path;
1433
char *filename_trying;
1434
char *filename_blah;
1435
static char *path_to_gunzip = NULL;
1436
static char *path_to_uncompress = NULL;
1437
static char *path_to_bunzip2 = NULL;
1438
FILE * doh = NULL;
1439
1440
filename_trying = alloca(MAXPATHLEN+1);
1441
1442
if (!setup)
1443
{
1444
char *gzip = path_search("gunzip", getenv("PATH"));
1445
char *compress = NULL;
1446
char *bzip = NULL;
1447
if (!gzip)
1448
gzip = empty_string;
1449
path_to_gunzip = m_strdup(gzip);
1450
1451
if (!(compress = path_search("uncompress", getenv("PATH"))))
1452
compress = empty_string;
1453
path_to_uncompress = m_strdup(compress);
1454
1455
if (!(bzip = path_search("bunzip2", getenv("PATH"))))
1456
bzip = empty_string;
1457
path_to_bunzip2 = m_strdup(bzip);
1458
setup = 1;
1459
}
1460
1461
/* It is allowed to pass to this function either a true filename
1462
with the compression extention, or to pass it the base name of
1463
the filename, and this will look to see if there is a compressed
1464
file that matches the base name */
1465
1466
/* Start with what we were given as an initial guess */
1467
if (**filename == '~')
1468
{
1469
filename_blah = expand_twiddle(*filename);
1470
strlcpy(filename_trying, filename_blah, MAXPATHLEN);
1471
new_free(&filename_blah);
1472
}
1473
else
1474
strlcpy(filename_trying, *filename, MAXPATHLEN);
1475
1476
/* Look to see if the passed filename is a full compressed filename */
1477
if ((! end_strcmp (filename_trying, ".gz", 3)) ||
1478
(! end_strcmp (filename_trying, ".z", 2)))
1479
{
1480
if (path_to_gunzip)
1481
{
1482
ok_to_decompress = 1;
1483
filename_path = path_search (filename_trying, path);
1484
}
1485
else
1486
{
1487
if (hook)
1488
yell("Cannot open file %s because gunzip was not found", filename_trying);
1489
new_free(filename);
1490
return NULL;
1491
}
1492
}
1493
else if (! end_strcmp (filename_trying, ".Z", 2))
1494
{
1495
if (path_to_gunzip || path_to_uncompress)
1496
{
1497
ok_to_decompress = 1;
1498
filename_path = path_search (filename_trying, path);
1499
}
1500
else
1501
{
1502
if (hook)
1503
yell("Cannot open file %s because uncompress was not found", filename_trying);
1504
new_free(filename);
1505
return NULL;
1506
}
1507
}
1508
else if (!end_strcmp(filename_trying, ".bz2", 4))
1509
{
1510
if (*path_to_bunzip2)
1511
{
1512
ok_to_decompress = 3;
1513
filename_path = path_search(filename_trying, path);
1514
}
1515
else
1516
{
1517
if (hook)
1518
yell("Cannot open file %s because bunzip2 was not found", filename_trying);
1519
new_free(filename);
1520
return NULL;
1521
}
1522
}
1523
/* Right now it doesnt look like the file is a full compressed fn */
1524
else
1525
{
1526
struct stat file_info;
1527
1528
/* Trivially, see if the file we were passed exists */
1529
filename_path = path_search (filename_trying, path);
1530
1531
/* Nope. it doesnt exist. */
1532
if (!filename_path)
1533
{
1534
/* Is there a "filename.gz"? */
1535
strlcpy (filename_trying, *filename, MAXPATHLEN);
1536
strlcat (filename_trying, ".gz", MAXPATHLEN);
1537
filename_path = path_search (filename_trying, path);
1538
1539
/* Nope. no "filename.gz" */
1540
if (!filename_path)
1541
{
1542
/* Is there a "filename.Z"? */
1543
strlcpy (filename_trying, *filename, MAXPATHLEN);
1544
strlcat (filename_trying, ".Z", MAXPATHLEN);
1545
filename_path = path_search (filename_trying, path);
1546
1547
/* Nope. no "filename.Z" */
1548
if (!filename_path)
1549
{
1550
/* Is there a "filename.z"? */
1551
strlcpy (filename_trying, *filename, MAXPATHLEN);
1552
strlcat (filename_trying, ".z", MAXPATHLEN);
1553
filename_path = path_search (filename_trying, path);
1554
1555
if (!filename_path)
1556
{
1557
strlcpy(filename_trying, *filename, MAXPATHLEN);
1558
strlcat(filename_trying, ".bz2", MAXPATHLEN);
1559
filename_path = path_search(filename_trying, path);
1560
if (!filename_path)
1561
{
1562
if (hook)
1563
yell("File not found: %s", *filename);
1564
new_free(filename);
1565
return NULL;
1566
}
1567
else
1568
/* found a bz2 */
1569
ok_to_decompress = 3;
1570
}
1571
/* Yep. there's a "filename.z" */
1572
else
1573
ok_to_decompress = 2;
1574
}
1575
/* Yep. there's a "filename.Z" */
1576
else
1577
ok_to_decompress = 1;
1578
}
1579
/* Yep. There's a "filename.gz" */
1580
else
1581
ok_to_decompress = 2;
1582
}
1583
/* Imagine that! the file exists as-is (no decompression) */
1584
else
1585
ok_to_decompress = 0;
1586
1587
stat (filename_path, &file_info);
1588
if (file_info.st_mode & S_IFDIR)
1589
{
1590
if (hook)
1591
yell("%s is a directory", filename_trying);
1592
new_free(filename);
1593
return NULL;
1594
}
1595
#ifndef WINNT
1596
if (file_info.st_mode & 0111)
1597
{
1598
char *p;
1599
if ((p = strrchr(filename_path, '.')))
1600
{
1601
p++;
1602
if (!strcmp(p, "so"))
1603
{
1604
malloc_strcpy(filename, filename_path);
1605
return NULL;
1606
}
1607
}
1608
if (hook)
1609
yell("Cannot open %s -- executable file", filename_trying);
1610
new_free(filename);
1611
return NULL;
1612
}
1613
#endif
1614
}
1615
1616
malloc_strcpy (filename, filename_path);
1617
1618
/* at this point, we should have a filename in the variable
1619
filename_trying, and it should exist. If ok_to_decompress
1620
is one, then we can gunzip the file if guzip is available,
1621
else we uncompress the file */
1622
if (ok_to_decompress)
1623
{
1624
if (ok_to_decompress <= 2 && *path_to_gunzip)
1625
return open_compression (path_to_gunzip, filename_path, hook);
1626
else if ((ok_to_decompress == 1) && *path_to_uncompress)
1627
return open_compression (path_to_uncompress, filename_path, hook);
1628
else if ((ok_to_decompress == 3) && *path_to_bunzip2)
1629
return open_compression(path_to_bunzip2, filename_path, hook);
1630
1631
if (hook)
1632
yell("Cannot open compressed file %s because no uncompressor was found", filename_trying);
1633
new_free(filename);
1634
return NULL;
1635
}
1636
1637
/* Its not a compressed file... Try to open it regular-like. */
1638
if ((doh = fopen(filename_path, "r")) != NULL)
1639
return doh;
1640
1641
/* nope.. we just cant seem to open this file... */
1642
if (hook)
1643
yell("Cannot open file %s: %s", filename_path, strerror(errno));
1644
new_free(filename);
1645
return NULL;
1646
}
1647
1648
1649
#ifdef INCLUDE_DEADCODE
1650
/* some more string manips by hop (june, 1995) */
1651
extern int fw_strcmp(comp_len_func *compar, char *one, char *two)
1652
{
1653
int len = 0;
1654
char *pos = one;
1655
1656
while (!my_isspace(*pos))
1657
pos++, len++;
1658
1659
return compar(one, two, len);
1660
}
1661
1662
1663
/*
1664
* Compares the last word in 'one' to the string 'two'. You must provide
1665
* the compar function. my_stricmp is a good default.
1666
*/
1667
extern int lw_strcmp(comp_func *compar, char *one, char *two)
1668
{
1669
char *pos = one + strlen(one) - 1;
1670
1671
if (pos > one) /* cant do pos[-1] if pos == one */
1672
while (!my_isspace(pos[-1]) && (pos > one))
1673
pos--;
1674
else
1675
pos = one;
1676
1677
if (compar)
1678
return compar(pos, two);
1679
else
1680
return my_stricmp(pos, two);
1681
}
1682
1683
/*
1684
* you give it a filename, some flags, and a position, and it gives you an
1685
* fd with the file pointed at the 'position'th byte.
1686
*/
1687
extern int opento(char *filename, int flags, off_t position)
1688
{
1689
int file;
1690
1691
file = open(filename, flags, 777);
1692
lseek(file, position, SEEK_SET);
1693
return file;
1694
}
1695
#endif
1696
1697
/* swift and easy -- returns the size of the file */
1698
off_t file_size (char *filename)
1699
{
1700
struct stat statbuf;
1701
1702
if (!stat(filename, &statbuf))
1703
return (off_t)(statbuf.st_size);
1704
else
1705
return -1;
1706
}
1707
1708
/* Gets the time in second/usecond if you can, second/0 if you cant. */
1709
struct timeval BX_get_time(struct timeval *timer)
1710
{
1711
static struct timeval timer2;
1712
#ifdef HAVE_GETTIMEOFDAY
1713
if (timer)
1714
{
1715
gettimeofday(timer, NULL);
1716
return *timer;
1717
}
1718
gettimeofday(&timer2, NULL);
1719
return timer2;
1720
#else
1721
time_t time2 = time(NULL);
1722
1723
if (timer)
1724
{
1725
timer->tv_sec = time2;
1726
timer->tv_usec = 0;
1727
return *timer;
1728
}
1729
timer2.tv_sec = time2;
1730
timer2.tv_usec = 0;
1731
return timer2;
1732
#endif
1733
}
1734
1735
/*
1736
* calculates the time elapsed between 'one' and 'two' where they were
1737
* gotten probably with a call to get_time. 'one' should be the older
1738
* timer and 'two' should be the most recent timer.
1739
*/
1740
double BX_time_diff (struct timeval one, struct timeval two)
1741
{
1742
struct timeval td;
1743
1744
td.tv_sec = two.tv_sec - one.tv_sec;
1745
td.tv_usec = two.tv_usec - one.tv_usec;
1746
1747
return (double)td.tv_sec + ((double)td.tv_usec / 1000000.0);
1748
}
1749
1750
int BX_time_to_next_minute (void)
1751
{
1752
time_t now = time(NULL);
1753
static int which = 0;
1754
1755
if (which == 1)
1756
return 60 - now % 60;
1757
else
1758
{
1759
struct tm *now_tm = gmtime(&now);
1760
1761
if (!which)
1762
{
1763
if (now_tm->tm_sec == now % 60)
1764
which = 1;
1765
else
1766
which = 2;
1767
}
1768
return 60-now_tm->tm_sec;
1769
}
1770
}
1771
1772
char *BX_plural (int number)
1773
{
1774
return (number != 1) ? "s" : empty_string;
1775
}
1776
1777
char *BX_my_ctime (time_t when)
1778
{
1779
return chop(ctime(&when), 1);
1780
}
1781
1782
char *BX_my_ltoa (long foo)
1783
{
1784
static char buffer[BIG_BUFFER_SIZE/8+1];
1785
char *pos = buffer + BIG_BUFFER_SIZE/8-1;
1786
unsigned long my_absv;
1787
int negative;
1788
1789
my_absv = (foo < 0) ? (unsigned long)-foo : (unsigned long)foo;
1790
negative = (foo < 0) ? 1 : 0;
1791
1792
buffer[BIG_BUFFER_SIZE/8] = 0;
1793
for (; my_absv > 9; my_absv /= 10)
1794
*pos-- = (my_absv % 10) + '0';
1795
*pos = (my_absv) + '0';
1796
1797
if (negative)
1798
*--pos = '-';
1799
1800
return pos;
1801
}
1802
1803
/*
1804
* Formats "src" into "dest" using the given length. If "length" is
1805
* negative, then the string is right-justified. If "length" is
1806
* zero, nothing happens. Sure, i cheat, but its cheaper then doing
1807
* two sprintf's.
1808
*/
1809
char *BX_strformat (char *dest, const char *src, int length, char pad_char)
1810
{
1811
char *ptr1 = dest,
1812
*ptr2 = (char *)src;
1813
int tmplen = length;
1814
int abslen;
1815
char padc;
1816
1817
abslen = (length >= 0 ? length : -length);
1818
if (!(padc = pad_char))
1819
padc = ' ';
1820
1821
/* Cheat by spacing out 'dest' */
1822
for (tmplen = abslen - 1; tmplen >= 0; tmplen--)
1823
dest[tmplen] = padc;
1824
dest[abslen] = 0;
1825
1826
/* Then cheat further by deciding where the string should go. */
1827
if (length > 0) /* left justified */
1828
{
1829
while ((length-- > 0) && *ptr2)
1830
*ptr1++ = *ptr2++;
1831
}
1832
else if (length < 0) /* right justified */
1833
{
1834
length = -length;
1835
ptr1 = dest;
1836
ptr2 = (char *)src;
1837
if (strlen(src) < length)
1838
ptr1 += length - strlen(src);
1839
while ((length-- > 0) && *ptr2)
1840
*ptr1++ = *ptr2++;
1841
}
1842
return dest;
1843
}
1844
1845
1846
/* MatchingBracket returns the next unescaped bracket of the given type */
1847
char *BX_MatchingBracket(register char *string, register char left, register char right)
1848
{
1849
int bracket_count = 1;
1850
1851
if (left == '(')
1852
{
1853
for (; *string; string++)
1854
{
1855
switch (*string)
1856
{
1857
case '(':
1858
bracket_count++;
1859
break;
1860
case ')':
1861
bracket_count--;
1862
if (bracket_count == 0)
1863
return string;
1864
break;
1865
case '\\':
1866
if (string[1])
1867
string++;
1868
break;
1869
}
1870
}
1871
}
1872
else if (left == '[')
1873
{
1874
for (; *string; string++)
1875
{
1876
switch (*string)
1877
{
1878
case '[':
1879
bracket_count++;
1880
break;
1881
case ']':
1882
bracket_count--;
1883
if (bracket_count == 0)
1884
return string;
1885
break;
1886
case '\\':
1887
if (string[1])
1888
string++;
1889
break;
1890
}
1891
}
1892
}
1893
else /* Fallback for everyone else */
1894
{
1895
while (*string && bracket_count)
1896
{
1897
if (*string == '\\' && string[1])
1898
string++;
1899
else if (*string == left)
1900
bracket_count++;
1901
else if (*string == right)
1902
{
1903
if (--bracket_count == 0)
1904
return string;
1905
}
1906
string++;
1907
}
1908
}
1909
1910
return NULL;
1911
}
1912
1913
/*
1914
* parse_number: returns the next number found in a string and moves the
1915
* string pointer beyond that point in the string. Here's some examples:
1916
*
1917
* "123harhar" returns 123 and str as "harhar"
1918
*
1919
* while:
1920
*
1921
* "hoohar" returns -1 and str as "hoohar"
1922
*/
1923
extern int BX_parse_number(char **str)
1924
{
1925
long ret;
1926
char *ptr = *str; /* sigh */
1927
1928
ret = strtol(ptr, str, 10);
1929
if (*str == ptr)
1930
ret = -1;
1931
1932
return (int)ret;
1933
}
1934
1935
#if 0
1936
extern char *chop_word(char *str)
1937
{
1938
char *end = str + strlen(str) - 1;
1939
1940
while (my_isspace(*end) && (end > str))
1941
end--;
1942
while (!my_isspace(*end) && (end > str))
1943
end--;
1944
1945
if (end >= str)
1946
*end = 0;
1947
1948
return str;
1949
}
1950
#endif
1951
1952
extern int BX_splitw (char *str, char ***to)
1953
{
1954
int numwords = word_count(str);
1955
int counter;
1956
if (numwords)
1957
{
1958
*to = (char **)new_malloc(sizeof(char *) * numwords);
1959
for (counter = 0; counter < numwords; counter++)
1960
(*to)[counter] = new_next_arg(str, &str);
1961
}
1962
else
1963
*to = NULL;
1964
return numwords;
1965
}
1966
1967
char * BX_unsplitw (char ***container, int howmany)
1968
{
1969
char *retval = NULL;
1970
char **str = *container;
1971
1972
while (howmany)
1973
{
1974
m_s3cat(&retval, space, *str);
1975
str++, howmany--;
1976
}
1977
1978
new_free((char **)container);
1979
return retval;
1980
}
1981
1982
char *BX_m_2dup (const char *str1, const char *str2)
1983
{
1984
size_t msize = strlen(str1) + strlen(str2) + 1;
1985
return strcat(strcpy((char *)new_malloc(msize), str1), str2);
1986
}
1987
1988
char *BX_m_e3cat (char **one, const char *yes1, const char *yes2)
1989
{
1990
if (*one && **one)
1991
return m_3cat(one, yes1, yes2);
1992
else
1993
*one = m_2dup(yes1, yes2);
1994
return *one;
1995
}
1996
1997
1998
double strtod();
1999
extern int BX_check_val (char *sub)
2000
{
2001
long sval;
2002
char *endptr;
2003
2004
if (!sub || !*sub)
2005
return 0;
2006
2007
#ifdef __EMX__
2008
if(strlen(sub) > 4 && strnicmp(sub, "infin", 5) == 0)
2009
return 0;
2010
#endif
2011
2012
/* get the numeric value (if any). */
2013
sval = strtod(sub, &endptr);
2014
2015
/* Its OK if:
2016
* 1) the f-val is not zero.
2017
* 2) the first illegal character was not a null.
2018
* 3) there were no valid f-chars.
2019
*/
2020
if (sval || *endptr || (sub == endptr))
2021
return 1;
2022
2023
return 0;
2024
}
2025
2026
char *BX_on_off(int var)
2027
{
2028
if (var)
2029
return ("On");
2030
return ("Off");
2031
}
2032
2033
2034
/*
2035
* Appends 'num' copies of 'app' to the end of 'str'.
2036
*/
2037
extern char *BX_strextend(char *str, char app, int num)
2038
{
2039
char *ptr = str + strlen(str);
2040
2041
for (;num;num--)
2042
*ptr++ = app;
2043
2044
*ptr = (char) 0;
2045
return str;
2046
}
2047
2048
const char *BX_strfill(char c, int num)
2049
{
2050
static char buffer[BIG_BUFFER_SIZE/4+1];
2051
int i = 0;
2052
if (num > BIG_BUFFER_SIZE/4)
2053
num = BIG_BUFFER_SIZE/4;
2054
for (i = 0; i < num; i++)
2055
buffer[i] = c;
2056
buffer[num] = 0;
2057
return buffer;
2058
}
2059
2060
#ifdef INCLUDE_DEADCODE
2061
/*
2062
* Appends the given character to the string
2063
*/
2064
char *strmccat(char *str, char c, int howmany)
2065
{
2066
int x = strlen(str);
2067
2068
if (x < howmany)
2069
str[x] = c;
2070
str[x+1] = 0;
2071
2072
return str;
2073
}
2074
2075
/*
2076
* Pull a substring out of a larger string
2077
* If the ending delimiter doesnt occur, then we dont pass
2078
* anything (by definition). This is because we dont want
2079
* to introduce a back door into CTCP handlers.
2080
*/
2081
extern char *BX_pullstr (char *source_string, char *dest_string)
2082
{
2083
char delim = *source_string;
2084
char *end;
2085
2086
end = strchr(source_string + 1, delim);
2087
2088
/* If there is no closing delim, then we punt. */
2089
if (!end)
2090
return NULL;
2091
2092
*end = 0;
2093
end++;
2094
2095
strcpy(dest_string, source_string + 1);
2096
strcpy(source_string, end);
2097
return dest_string;
2098
}
2099
#endif
2100
2101
extern int BX_empty (const char *str)
2102
{
2103
while (str && *str && *str == ' ')
2104
str++;
2105
2106
if (str && *str)
2107
return 0;
2108
2109
return 1;
2110
}
2111
2112
/* makes foo[one][two] look like tmp.one.two -- got it? */
2113
char *BX_remove_brackets (const char *name, const char *args, int *arg_flag)
2114
{
2115
char *ptr, *right, *result1, *rptr, *retval = NULL;
2116
2117
/* XXXX - ugh. */
2118
rptr = m_strdup(name);
2119
2120
while ((ptr = strchr(rptr, '[')))
2121
{
2122
*ptr++ = 0;
2123
right = ptr;
2124
if ((ptr = MatchingBracket(right, '[', ']')))
2125
*ptr++ = 0;
2126
2127
if (args)
2128
result1 = expand_alias(right, args, arg_flag, NULL);
2129
else
2130
result1 = right;
2131
2132
retval = m_3dup(rptr, ".", result1);
2133
if (ptr)
2134
malloc_strcat(&retval, ptr);
2135
2136
if (args)
2137
new_free(&result1);
2138
if (rptr)
2139
new_free(&rptr);
2140
rptr = retval;
2141
}
2142
return upper(rptr);
2143
}
2144
2145
long BX_my_atol (const char *str)
2146
{
2147
if (str)
2148
return (long) strtol(str, NULL, 0);
2149
else
2150
return 0L;
2151
}
2152
2153
#if 0
2154
u_long hashpjw (char *text, u_long prime)
2155
{
2156
char *p;
2157
u_long h = 0, g;
2158
2159
for (p = text; *p; p++)
2160
{
2161
h <<= 4;
2162
h += *p;
2163
if ((g = h & 0xf0000000))
2164
{
2165
h ^= (g >> 24);
2166
h ^= g;
2167
}
2168
}
2169
return h % prime;
2170
}
2171
#endif
2172
2173
char *BX_m_dupchar(int i)
2174
{
2175
char c = (char) i; /* blah */
2176
char *ret = (char *)new_malloc(2);
2177
2178
ret[0] = c;
2179
ret[1] = 0;
2180
return ret;
2181
}
2182
2183
#ifdef INCLUDE_DEADCODE
2184
/*
2185
* This checks to see if ``root'' is a proper subname for ``var''.
2186
*/
2187
int is_root (char *root, char *var, int descend)
2188
{
2189
int rootl, varl;
2190
2191
/* ``root'' must end in a dot */
2192
rootl = strlen(root);
2193
if (root[rootl] != '.')
2194
return 0;
2195
2196
/* ``root'' must be shorter than ``var'' */
2197
varl = strlen(var);
2198
if (varl <= rootl)
2199
return 0;
2200
2201
/* ``var'' must contain ``root'' as a leading subset */
2202
if (my_strnicmp(root, var, rootl))
2203
return 0;
2204
2205
/*
2206
* ``var'' must not contain any additional dots
2207
* if we are checking for the current level only
2208
*/
2209
if (!descend && strchr(var + rootl, '.'))
2210
return 0;
2211
2212
/* Looks like its ok */
2213
return 1;
2214
}
2215
#endif
2216
2217
/* Returns the number of characters they are equal at. */
2218
size_t BX_streq (const char *one, const char *two)
2219
{
2220
size_t cnt = 0;
2221
2222
while (*one && *two && (*one == *two))
2223
cnt++, one++, two++;
2224
2225
return cnt;
2226
}
2227
2228
/* Returns the number of characters they are equal at. */
2229
size_t BX_strieq (const char *one, const char *two)
2230
{
2231
size_t cnt = 0;
2232
2233
while (*one && *two && (toupper(*one) == toupper(*two)))
2234
cnt++, one++, two++;
2235
2236
return cnt;
2237
}
2238
2239
char *n_m_strndup (const char *str, size_t len, const char *module, const char *file, const int line)
2240
{
2241
char *retval = (char *)n_malloc(len + 1, module, file, line);
2242
return strmcpy(retval, (char *)str, len);
2243
}
2244
2245
#if 0
2246
char *remove_nl (char *str)
2247
{
2248
char *ptr;
2249
2250
if ((ptr = strrchr(str, '\n')))
2251
*ptr = 0;
2252
2253
return str;
2254
}
2255
2256
char *spanstr (const char *str, const char *tar)
2257
{
2258
int cnt = 1;
2259
const char *p;
2260
2261
for ( ; *str; str++, cnt++)
2262
{
2263
for (p = tar; *p; p++)
2264
{
2265
if (*p == *str)
2266
return (char *)p;
2267
}
2268
}
2269
2270
return 0;
2271
}
2272
2273
char *s_next_arg (char **from)
2274
{
2275
char *next = strchr(*from, ' ');
2276
char *keep = *from;
2277
*from = next;
2278
return keep;
2279
}
2280
#endif
2281
2282
char *BX_strmopencat (char *dest, int maxlen, ...)
2283
{
2284
va_list args;
2285
int size;
2286
char *this_arg = NULL;
2287
int this_len;
2288
2289
size = strlen(dest);
2290
va_start(args, maxlen);
2291
2292
while (size < maxlen)
2293
{
2294
if (!(this_arg = va_arg(args, char *)))
2295
break;
2296
2297
if (size + ((this_len = strlen(this_arg))) > maxlen)
2298
strncat(dest, this_arg, maxlen - size);
2299
else
2300
strcat(dest, this_arg);
2301
2302
size += this_len;
2303
}
2304
2305
va_end(args);
2306
return dest;
2307
}
2308
2309
/*
2310
* An strcpy that is guaranteed to be safe for overlaps.
2311
*/
2312
char *BX_ov_strcpy (char *one, const char *two)
2313
{
2314
if (two > one)
2315
{
2316
while (two && *two)
2317
*one++ = *two++;
2318
*one = 0;
2319
}
2320
return one;
2321
}
2322
2323
char *BX_next_in_comma_list (char *str, char **after)
2324
{
2325
*after = str;
2326
2327
while (*after && **after && **after != ',')
2328
(*after)++;
2329
2330
if (*after && **after == ',')
2331
{
2332
**after = 0;
2333
(*after)++;
2334
}
2335
2336
return str;
2337
}
2338
2339
#ifdef INCLUDE_DEADCODE
2340
/*
2341
* Checks if ansi string only sets colors/attributes
2342
* ^[[m won't work anymore !!!!
2343
*/
2344
void FixColorAnsi(unsigned char *str)
2345
{
2346
#if !defined(WINNT) && !defined(__EMX__)
2347
register unsigned char *tmpstr;
2348
register unsigned char *tmpstr1=NULL;
2349
int what=0;
2350
int numbers=0;
2351
int val = 0;
2352
2353
tmpstr=str;
2354
while (*tmpstr)
2355
{
2356
if ((*tmpstr>='0' && *tmpstr<='9'))
2357
{
2358
numbers = 1;
2359
val = val * 10 + (*tmpstr - '0');
2360
}
2361
else if (*tmpstr==';')
2362
numbers = 1, val = 0;
2363
else if (!(*tmpstr=='m' || *tmpstr=='C'))
2364
numbers = val = 0;
2365
if (*tmpstr==0x1B)
2366
{
2367
if (what && tmpstr1)
2368
*tmpstr1+=64;
2369
what=1;
2370
tmpstr1=tmpstr;
2371
}
2372
else if (*tmpstr==0x18 || *tmpstr==0x0E)
2373
*tmpstr+=64;
2374
if (what && numbers && (val > 130))
2375
{
2376
what = numbers = val = 0;
2377
*tmpstr1+=64;
2378
}
2379
if (what && *tmpstr=='m')
2380
{
2381
if (!numbers || (val == 12))
2382
{
2383
*tmpstr1+=64;
2384
tmpstr1=tmpstr;
2385
}
2386
what=0;
2387
numbers = val = 0;
2388
}
2389
else if (what && *tmpstr=='C')
2390
{
2391
if (!numbers)
2392
{
2393
*tmpstr1+=64;
2394
tmpstr1=tmpstr;
2395
}
2396
what=0;
2397
numbers = val = 0;
2398
}
2399
else if (what && *tmpstr=='J')
2400
{
2401
val = numbers = 0;
2402
*tmpstr1 +=64;
2403
tmpstr1=tmpstr;
2404
what = 0;
2405
}
2406
else if (what && *tmpstr=='(')
2407
what=2;
2408
else if (what == 2 && (*tmpstr == '0'))
2409
*tmpstr1 += 64;
2410
else if (what == 2 && (*tmpstr=='U' || *tmpstr=='B'))
2411
what=0;
2412
tmpstr++;
2413
}
2414
if (what && tmpstr1 && *tmpstr1)
2415
*tmpstr1+=64;
2416
#endif
2417
}
2418
2419
#endif
2420
/* Dest should be big enough to hold "src" */
2421
void BX_strip_control (const char *src, char *dest)
2422
{
2423
for (; *src; src++)
2424
{
2425
if (isgraph((unsigned char)*src) || isspace((unsigned char)*src))
2426
*dest++ = *src;
2427
}
2428
2429
*dest++ = 0;
2430
}
2431
2432
/*
2433
* figure_out_address
2434
*/
2435
int BX_figure_out_address (char *nuh, char **nick, char **user, char **host, char **domain, int *ip)
2436
{
2437
static char *mystuff = NULL;
2438
char *firstback, *secondback, *thirdback, *fourthback;
2439
char *bang, *at, *myhost = star, *endstring;
2440
int number;
2441
2442
/* Dont bother with channels, theyre ok. */
2443
if (*nuh == '#' || *nuh == '&')
2444
return -1;
2445
2446
malloc_strcpy(&mystuff, nuh);
2447
2448
*nick = *user = *host = *domain = star;
2449
*ip = 0;
2450
2451
bang = strchr(mystuff, '!');
2452
at = strchr(mystuff, '@');
2453
2454
if (!bang && !at)
2455
{
2456
if (strchr(mystuff, '.') || strchr(mystuff, ':'))
2457
myhost = mystuff;
2458
else
2459
{
2460
*nick = mystuff;
2461
return 0;
2462
}
2463
}
2464
2465
if (bang == mystuff)
2466
*user = bang + 1;
2467
else if (bang)
2468
{
2469
*nick = mystuff;
2470
*bang = 0;
2471
*user = bang + 1;
2472
}
2473
else
2474
*user = mystuff;
2475
2476
if (at)
2477
{
2478
if (*user == star)
2479
*user = mystuff;
2480
*at = 0;
2481
myhost = at + 1;
2482
}
2483
2484
/*
2485
* At this point, 'myhost' points what what we think the hostname
2486
* is. We chop it up into discrete parts and see what we end up with.
2487
*/
2488
endstring = myhost + strlen(myhost);
2489
firstback = strnrchr(myhost, '.', 1);
2490
secondback = strnrchr(myhost, '.', 2);
2491
thirdback = strnrchr(myhost, '.', 3);
2492
fourthback = strnrchr(myhost, '.', 4);
2493
2494
/* Track foo@bar or some such thing. */
2495
if (!firstback)
2496
{
2497
*host = myhost;
2498
return 0;
2499
}
2500
2501
/*
2502
* IP address (A.B.C.D)
2503
*/
2504
if (my_atol(firstback + 1))
2505
{
2506
*ip = 1;
2507
*domain = myhost;
2508
2509
number = my_atol(myhost);
2510
if (number < 128)
2511
*host = thirdback;
2512
else if (number < 192)
2513
*host = secondback;
2514
else
2515
*host = firstback;
2516
2517
**host = 0;
2518
(*host)++;
2519
}
2520
/*
2521
* (*).(*.???)
2522
* Handles *.com, *.net, *.edu, etc
2523
*/
2524
else if (secondback && (endstring - firstback == 4))
2525
{
2526
*host = myhost;
2527
*domain = secondback;
2528
**domain = 0;
2529
(*domain)++;
2530
}
2531
/*
2532
* (*).(*.k12.??.us)
2533
* Handles host.school.k12.state.us
2534
*/
2535
else if (fourthback &&
2536
(firstback - secondback == 3) &&
2537
!strncmp(thirdback, ".k12.", 5) &&
2538
!strncmp(firstback, ".us", 3))
2539
{
2540
*host = myhost;
2541
*domain = fourthback;
2542
**domain = 0;
2543
(*domain)++;
2544
}
2545
/*
2546
* ()(*.k12.??.us)
2547
* Handles school.k12.state.us
2548
*/
2549
else if (thirdback && !fourthback &&
2550
(firstback - secondback == 3) &&
2551
!strncmp(thirdback, ".k12.", 5) &&
2552
!strncmp(firstback, ".us", 3))
2553
{
2554
*host = empty_string;
2555
*domain = myhost;
2556
}
2557
/*
2558
* (*).(*.???.??)
2559
* Handles host.domain.com.au
2560
*/
2561
else if (thirdback &&
2562
(endstring - firstback == 3) &&
2563
(firstback - secondback == 4))
2564
{
2565
*host = myhost;
2566
*domain = thirdback;
2567
**domain = 0;
2568
(*domain)++;
2569
}
2570
/*
2571
* ()(*.???.??)
2572
* Handles domain.com.au
2573
*/
2574
else if (secondback && !thirdback &&
2575
(endstring - firstback == 3) &&
2576
(firstback - secondback == 4))
2577
{
2578
*host = empty_string;
2579
*domain = myhost;
2580
}
2581
/*
2582
* (*).(*.??.??)
2583
* Handles host.domain.co.uk
2584
*/
2585
else if (thirdback &&
2586
(endstring - firstback == 3) &&
2587
(firstback - secondback == 3))
2588
{
2589
*host = myhost;
2590
*domain = thirdback;
2591
**domain = 0;
2592
(*domain)++;
2593
}
2594
/*
2595
* ()(*.??.??)
2596
* Handles domain.co.uk
2597
*/
2598
else if (secondback && !thirdback &&
2599
(endstring - firstback == 3) &&
2600
(firstback - secondback == 3))
2601
{
2602
*host = empty_string;
2603
*domain = myhost;
2604
}
2605
/*
2606
* (*).(*.??)
2607
* Handles domain.de
2608
*/
2609
else if (secondback && (endstring - firstback == 3))
2610
{
2611
*host = myhost;
2612
*domain = secondback;
2613
**domain = 0;
2614
(*domain)++;
2615
}
2616
/*
2617
* Everything else...
2618
*/
2619
else
2620
{
2621
*host = empty_string;
2622
*domain = myhost;
2623
}
2624
2625
return 0;
2626
}
2627
2628
#ifdef INCLUDE_DEADCODE
2629
int count_char (const unsigned char *src, const unsigned char look)
2630
{
2631
const unsigned char *t;
2632
int cnt = 0;
2633
2634
while ((t = strchr(src, look)))
2635
cnt++, src = t + 1;
2636
2637
return cnt;
2638
}
2639
#endif
2640
2641
char *BX_strnrchr(char *start, char which, int howmany)
2642
{
2643
char *ends = start + strlen(start);
2644
2645
while (ends > start && howmany)
2646
{
2647
if (*--ends == which)
2648
howmany--;
2649
}
2650
if (ends == start)
2651
return NULL;
2652
else
2653
return ends;
2654
}
2655
2656
/*
2657
* This replaces some number of numbers (1 or more) with a single asterisk.
2658
* We know that the final strcpy() is safe, since we never make a string that
2659
* is longer than the source string, always less than or equal in size.
2660
*/
2661
void BX_mask_digits (char **hostname)
2662
{
2663
char *src_ptr;
2664
char *retval, *retval_ptr;
2665
2666
retval = retval_ptr = alloca(strlen(*hostname) + 1);
2667
src_ptr = *hostname;
2668
2669
while (*src_ptr)
2670
{
2671
if (isdigit((unsigned char)*src_ptr))
2672
{
2673
while (*src_ptr && isdigit((unsigned char)*src_ptr))
2674
src_ptr++;
2675
2676
*retval_ptr++ = '*';
2677
}
2678
else
2679
*retval_ptr++ = *src_ptr++;
2680
}
2681
2682
*retval_ptr = 0;
2683
strcpy(*hostname, retval);
2684
return;
2685
}
2686
2687
/*
2688
* Its like strcspn, except the seconD arg is NOT a string.
2689
*/
2690
size_t BX_ccspan (const char *string, int s)
2691
{
2692
size_t count = 0;
2693
char c = (char) s;
2694
2695
while (string && *string && *string != c)
2696
string++, count++;
2697
2698
return count;
2699
}
2700
2701
#ifdef INCLUDE_DEADCODE
2702
int last_char (const char *string)
2703
{
2704
while (string && string[0] && string[1])
2705
string++;
2706
2707
return (int)*string;
2708
}
2709
#endif
2710
2711
int BX_charcount (const char *string, char what)
2712
{
2713
int x = 0;
2714
const char *place = string;
2715
2716
while (*place)
2717
if (*place++ == what)
2718
x++;
2719
2720
return x;
2721
}
2722
2723
char * encode(const char *str, int len)
2724
{
2725
char *retval;
2726
char *ptr;
2727
2728
if (len == -1)
2729
len = strlen(str);
2730
2731
ptr = retval = new_malloc(len * 2 + 1);
2732
2733
while (len)
2734
{
2735
*ptr++ = (*str >> 4) + 0x41;
2736
*ptr++ = (*str & 0x0f) + 0x41;
2737
str++;
2738
len--;
2739
}
2740
*ptr = 0;
2741
return retval;
2742
}
2743
2744
char * decode(const char *str)
2745
{
2746
char *retval;
2747
char *ptr;
2748
int len = strlen(str);
2749
2750
ptr = retval = new_malloc(len / 2 + 1);
2751
while (len >= 2)
2752
{
2753
*ptr++ = ((str[0] - 0x41) << 4) | (str[1] - 0x41);
2754
str += 2;
2755
len -= 2;
2756
}
2757
*ptr = 0;
2758
return retval;
2759
}
2760
2761
char * chomp (char *s)
2762
{
2763
char *e = s + strlen(s);
2764
2765
if (e == s)
2766
return s;
2767
2768
while (*--e == '\n')
2769
{
2770
*e = 0;
2771
if (e == s)
2772
break;
2773
}
2774
2775
return s;
2776
}
2777
2778
char *BX_strpcat (char *source, const char *format, ...)
2779
{
2780
va_list args;
2781
char buffer[BIG_BUFFER_SIZE + 1];
2782
2783
va_start(args, format);
2784
vsnprintf(buffer, BIG_BUFFER_SIZE, format, args);
2785
va_end(args);
2786
2787
strcat(source, buffer);
2788
return source;
2789
}
2790
2791
char * BX_strmpcat (char *source, size_t siz, const char *format, ...)
2792
{
2793
va_list args;
2794
char buffer[BIG_BUFFER_SIZE + 1];
2795
2796
va_start(args, format);
2797
vsnprintf(buffer, BIG_BUFFER_SIZE, format, args);
2798
va_end(args);
2799
2800
strmcat(source, buffer, siz);
2801
return source;
2802
}
2803
2804
2805
2806
u_char *BX_strcpy_nocolorcodes (u_char *dest, const u_char *source)
2807
{
2808
u_char *save = dest;
2809
2810
do
2811
{
2812
while (*source == 3)
2813
source = skip_ctl_c_seq(source, NULL, NULL, 0);
2814
*dest++ = *source;
2815
}
2816
while (*source++);
2817
2818
return save;
2819
}
2820
2821
char *crypt();
2822
2823
char *BX_cryptit(const char *string)
2824
{
2825
static char saltChars[] =
2826
"abcdefghijklmnopqrstuvwxyzABCDEFGHJIKLMNOPQRSTUVWXYZ./";
2827
char *cpass = (char *)string;
2828
char salt[3];
2829
salt[0] = saltChars[random_number(0) % 64];
2830
salt[1] = saltChars[random_number(0) % 64];
2831
salt[2] = 0;
2832
#if !defined(WINNT)
2833
cpass = crypt(string, salt);
2834
#endif
2835
return cpass;
2836
}
2837
2838
int checkpass(const char *password, const char *old)
2839
{
2840
char seed[3], *p;
2841
seed[0] = old[0];
2842
seed[1] = old[1];
2843
seed[2] = 0;
2844
#if !defined(WINNT)
2845
p = crypt(password, seed);
2846
#else
2847
p = password;
2848
#endif
2849
return strcmp(p, old);
2850
}
2851
2852
2853
char *BX_stripdev(char *ttynam)
2854
{
2855
if (ttynam == NULL)
2856
return NULL;
2857
#ifdef SVR4
2858
/* unixware has /dev/pts012 as synonym for /dev/pts/12 */
2859
if (!strncmp(ttynam, "/dev/pts", 8) && ttynam[8] >= '0' && ttynam[8] <= '9')
2860
{
2861
static char b[13];
2862
sprintf(b, "pts/%d", atoi(ttynam + 8));
2863
return b;
2864
}
2865
#endif /* SVR4 */
2866
if (!strncmp(ttynam, "/dev/", 5))
2867
return ttynam + 5;
2868
return ttynam;
2869
}
2870
2871
2872
void init_socketpath(void)
2873
{
2874
#if !defined(__EMX__) && !defined(WINNT)
2875
struct stat st;
2876
extern char socket_path[], attach_ttyname[];
2877
2878
sprintf(socket_path, "%s/.BitchX/screens", my_path);
2879
if (access(socket_path, F_OK))
2880
{
2881
if (mkdir(socket_path, 0700) != -1)
2882
(void) chown(socket_path, getuid(), getgid());
2883
else
2884
return;
2885
}
2886
if (stat(socket_path, &st) != -1)
2887
{
2888
char host[BIG_BUFFER_SIZE+1];
2889
char *ap;
2890
if (!S_ISDIR(st.st_mode))
2891
return;
2892
gethostname(host, BIG_BUFFER_SIZE);
2893
if ((ap = strchr(host, '.')))
2894
*ap = 0;
2895
ap = &socket_path[strlen(socket_path)];
2896
sprintf(ap, "/%%d.%s.%s", stripdev(attach_ttyname), host);
2897
ap++;
2898
for ( ; *ap; ap++)
2899
if (*ap == '/')
2900
*ap = '-';
2901
}
2902
#endif
2903
}
2904
2905
/*
2906
* This mangles up 'incoming' corresponding to the current values of
2907
* /set mangle_inbound or /set mangle_outbound.
2908
* 'incoming' needs to be at _least_ thrice as big as neccesary
2909
* (ie, sizeof(incoming) >= strlen(incoming) * 3 + 1)
2910
*/
2911
size_t BX_mangle_line (char *incoming, int how, size_t how_much)
2912
{
2913
int stuff;
2914
char *buffer;
2915
int i;
2916
char *s;
2917
2918
stuff = how;
2919
buffer = alloca(how_much + 1); /* Absurdly large */
2920
2921
#if notyet
2922
if (stuff & STRIP_CTCP2)
2923
{
2924
char *output;
2925
2926
output = strip_ctcp2(incoming);
2927
strlcpy(incoming, output, how_much);
2928
new_free(&output);
2929
}
2930
else if (stuff & MANGLE_INBOUND_CTCP2)
2931
{
2932
char *output;
2933
2934
output = ctcp2_to_ircII(incoming);
2935
strlcpy(incoming, output, how_much);
2936
new_free(&output);
2937
}
2938
else if (stuff & MANGLE_OUTBOUND_CTCP2)
2939
{
2940
char *output;
2941
2942
output = ircII_to_ctcp2(incoming);
2943
strlcpy(incoming, output, how_much);
2944
new_free(&output);
2945
}
2946
#endif
2947
2948
if (stuff & MANGLE_ESCAPES)
2949
{
2950
for (i = 0; incoming[i]; i++)
2951
{
2952
if (incoming[i] == 0x1b)
2953
incoming[i] = 0x5b;
2954
}
2955
}
2956
2957
if (stuff & MANGLE_ANSI_CODES)
2958
{
2959
/* strip_ansi can expand up to three times */
2960
char *output;
2961
2962
strip_ansi_never_xlate = 1; /* XXXXX */
2963
output = strip_ansi(incoming);
2964
strip_ansi_never_xlate = 0; /* XXXXX */
2965
if (strlcpy(incoming, output, how_much) > how_much)
2966
say("Mangle_line truncating results (%d > %d) - "
2967
"please email " BUG_EMAIL,
2968
strlen(output), how_much);
2969
new_free(&output);
2970
}
2971
2972
/*
2973
* Now we mangle the individual codes
2974
*/
2975
for (i = 0, s = incoming; *s; s++)
2976
{
2977
switch (*s)
2978
{
2979
case 003: /* color codes */
2980
{
2981
int lhs = 0,
2982
rhs = 0;
2983
char *end;
2984
2985
end = (char *)skip_ctl_c_seq(s, &lhs, &rhs, 0);
2986
if (!(stuff & STRIP_COLOR))
2987
{
2988
while (s < end)
2989
buffer[i++] = *s++;
2990
}
2991
s = end - 1;
2992
break;
2993
}
2994
case REV_TOG: /* Reverse */
2995
{
2996
if (!(stuff & STRIP_REVERSE))
2997
buffer[i++] = REV_TOG;
2998
break;
2999
}
3000
case UND_TOG: /* Underline */
3001
{
3002
if (!(stuff & STRIP_UNDERLINE))
3003
buffer[i++] = UND_TOG;
3004
break;
3005
}
3006
case BOLD_TOG: /* Bold */
3007
{
3008
if (!(stuff & STRIP_BOLD))
3009
buffer[i++] = BOLD_TOG;
3010
break;
3011
}
3012
case BLINK_TOG: /* Flashing */
3013
{
3014
if (!(stuff & STRIP_BLINK))
3015
buffer[i++] = BLINK_TOG;
3016
break;
3017
}
3018
case ROM_CHAR: /* Special rom-chars */
3019
{
3020
if (!(stuff & STRIP_ROM_CHAR))
3021
buffer[i++] = ROM_CHAR;
3022
break;
3023
}
3024
case ND_SPACE: /* Nondestructive spaces */
3025
{
3026
if (!(stuff & STRIP_ND_SPACE))
3027
buffer[i++] = ND_SPACE;
3028
break;
3029
}
3030
case ALT_TOG: /* Alternate character set */
3031
{
3032
if (!(stuff & STRIP_ALT_CHAR))
3033
buffer[i++] = ALT_TOG;
3034
break;
3035
}
3036
case ALL_OFF: /* ALL OFF attribute */
3037
{
3038
if (!(stuff & STRIP_ALL_OFF))
3039
buffer[i++] = ALL_OFF;
3040
break;
3041
}
3042
default:
3043
buffer[i++] = *s;
3044
}
3045
}
3046
3047
buffer[i] = 0;
3048
return strlcpy(incoming, buffer, how_much);
3049
}
3050
3051
void strip_chars(char *buffer, char *strip, char replace)
3052
{
3053
char *p;
3054
if (!buffer || !*buffer || !strip || !*strip || !replace)
3055
return;
3056
while (*strip)
3057
{
3058
while ((p = strchr(buffer, *strip)))
3059
*p = replace;
3060
strip++;
3061
}
3062
}
3063
3064
char *longcomma(long val)
3065
{
3066
char buffer[40];
3067
static char buff[40];
3068
char *s = buff;
3069
int i = 0, j = 0, len;
3070
sprintf(buffer, "%ld", val);
3071
len = strlen(buffer);
3072
for (i = len % 3; i > 0; i--)
3073
*s++ = buffer[j++];
3074
if (len > 3 && len % 3)
3075
*s++ = ',';
3076
len -= (len % 3);
3077
while (len --)
3078
{
3079
*s++ = buffer[j++];
3080
if (!(len % 3) && len)
3081
*s++ = ',';
3082
}
3083
*s = 0;
3084
return buff;
3085
}
3086
3087
char *ulongcomma(unsigned long val)
3088
{
3089
char buffer[40];
3090
static char buff[40];
3091
char *s = buff;
3092
int i = 0, j = 0, len;
3093
sprintf(buffer, "%lu", val);
3094
len = strlen(buffer);
3095
for (i = len % 3; i > 0; i--)
3096
*s++ = buffer[j++];
3097
if (len > 3 && len % 3)
3098
*s++ = ',';
3099
len -= (len % 3);
3100
while (len --)
3101
{
3102
*s++ = buffer[j++];
3103
if (!(len % 3) && len)
3104
*s++ = ',';
3105
}
3106
*s = 0;
3107
return buff;
3108
}
3109
3110
/* XXXX this doesnt belong here. im not sure where it goes, though. */
3111
char * get_userhost (void)
3112
{
3113
strmcpy(userhost, username, NAME_LEN);
3114
strmcat(userhost, "@", NAME_LEN);
3115
strmcat(userhost, hostname, NAME_LEN);
3116
return userhost;
3117
}
3118
3119
3120
3121
/* RANDOM NUMBERS */
3122
/*
3123
* Random number generator #1 -- psuedo-random sequence
3124
* If you do not have /dev/random and do not want to use gettimeofday(), then
3125
* you can use the psuedo-random number generator. Its performance varies
3126
* from weak to moderate. It is a predictable mathematical sequence that
3127
* varies depending on the seed, and it provides very little repetition,
3128
* but with 4 or 5 samples, it should be trivial for an outside person to
3129
* find the next numbers in your sequence.
3130
*
3131
* If 'l' is not zero, then it is considered a "seed" value. You want
3132
* to call it once to set the seed. Subsequent calls should use 'l'
3133
* as 0, and it will return a value.
3134
*/
3135
static unsigned long randm (unsigned long l)
3136
{
3137
/* patch from Sarayan to make $rand() better */
3138
static const long RAND_A = 16807L;
3139
static const long RAND_M = 2147483647L;
3140
static const long RAND_Q = 127773L;
3141
static const int RAND_R = 2836L;
3142
static u_long z = 0;
3143
long t;
3144
3145
if (z == 0)
3146
z = (u_long) getuid();
3147
3148
if (l == 0)
3149
{
3150
t = RAND_A * (z % RAND_Q) - RAND_R * (z / RAND_Q);
3151
if (t > 0)
3152
z = t;
3153
else
3154
z = t + RAND_M;
3155
return (z >> 8) | ((z & 255) << 23);
3156
}
3157
else
3158
{
3159
if (l < 0)
3160
z = (u_long) getuid();
3161
else
3162
z = l;
3163
return 0;
3164
}
3165
}
3166
3167
/*
3168
* Random number generator #2 -- gettimeofday().
3169
* If you have gettimeofday(), then we could use it. Its performance varies
3170
* from weak to moderate. At best, it is a source of modest entropy, with
3171
* distinct linear qualities. At worst, it is a linear sequence. If you do
3172
* not have gettimeofday(), then it uses randm() instead.
3173
*/
3174
static unsigned long randt_2 (void)
3175
{
3176
struct timeval tp1;
3177
get_time(&tp1);
3178
return (unsigned long) tp1.tv_usec;
3179
}
3180
3181
static unsigned long randt (unsigned long l)
3182
{
3183
#ifdef HAVE_GETTIMEOFDAY
3184
unsigned long t1, t2, t;
3185
3186
if (l != 0)
3187
return 0;
3188
3189
t1 = randt_2();
3190
t2 = randt_2();
3191
t = (t1 & 65535) * 65536 + (t2 & 65535);
3192
return t;
3193
#else
3194
return randm(0);
3195
#endif
3196
}
3197
3198
3199
/*
3200
* Random number generator #3 -- /dev/urandom.
3201
* If you have the /dev/urandom device, then we will use it. Its performance
3202
* varies from moderate to very strong. At best, it is a source of pretty
3203
* substantial unpredictable numbers. At worst, it is mathematical psuedo-
3204
* random sequence (which randm() is).
3205
*/
3206
static unsigned long randd (unsigned long l)
3207
{
3208
unsigned long value;
3209
static int random_fd = -1;
3210
3211
if (l != 0)
3212
return 0; /* No seeding appropriate */
3213
3214
if (random_fd == -2)
3215
return randm(0);
3216
3217
else if (random_fd == -1)
3218
{
3219
if ((random_fd = open("/dev/urandom", O_RDONLY)) == -1)
3220
{
3221
random_fd = -2;
3222
return randm(0); /* Fall back to randm */
3223
}
3224
}
3225
3226
read(random_fd, (void *)&value, sizeof(value));
3227
return value;
3228
}
3229
3230
3231
unsigned long BX_random_number (unsigned long l)
3232
{
3233
switch (get_int_var(RANDOM_SOURCE_VAR))
3234
{
3235
case 0:
3236
default:
3237
return randd(l);
3238
case 1:
3239
return randm(l);
3240
case 2:
3241
return randt(l);
3242
}
3243
}
3244
3245
3246