ebc17950ecf43c790432b756f49201ac662564d5
[ircu2.10.12-pk.git] / ircd / support.c
1 /*
2  * IRC - Internet Relay Chat, common/support.c
3  * Copyright (C) 1990, 1991 Armin Gruner
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 1, or (at your option)
8  * any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  */
19
20 #include "sys.h"
21 #ifdef _SEQUENT_
22 #include <sys/timers.h>
23 #include <stddef.h>
24 #endif
25 #if HAVE_UNISTD_H
26 #include <unistd.h>
27 #endif
28 #include <stdarg.h>
29 #include <signal.h>
30 #include "h.h"
31 #include "send.h"
32 #include "ircd.h"
33 #include "s_bsd.h"
34 #include "support.h"
35 #include "sprintf_irc.h"
36 #include "common.h"
37 #include "fileio.h"
38
39 RCSTAG_CC("$Id$");
40
41 #ifndef HAVE_STRTOKEN
42 /*
43  * strtoken.c
44  *
45  * Walk through a string of tokens, using a set of separators.
46  * -argv 9/90
47  */
48 char *strtoken(char **save, char *str, char *fs)
49 {
50   char *pos = *save;            /* keep last position across calls */
51   Reg1 char *tmp;
52
53   if (str)
54     pos = str;                  /* new string scan */
55
56   while (pos && *pos && strchr(fs, *pos) != NULL)
57     pos++;                      /* skip leading separators */
58
59   if (!pos || !*pos)
60     return (pos = *save = NULL);        /* string contains only sep's */
61
62   tmp = pos;                    /* now, keep position of the token */
63
64   while (*pos && strchr(fs, *pos) == NULL)
65     pos++;                      /* skip content of the token */
66
67   if (*pos)
68     *pos++ = '\0';              /* remove first sep after the token */
69   else
70     pos = NULL;                 /* end of string */
71
72   *save = pos;
73   return (tmp);
74 }
75 #endif /* !HAVE_STRTOKEN */
76
77 #ifndef HAVE_STRERROR
78 /*
79  * strerror
80  *
81  * Returns an appropriate system error string to a given errno.
82  * -argv 11/90
83  */
84
85 char *strerror(int err_no)
86 {
87   static char buff[40];
88   char *errp;
89
90   errp = (err_no > sys_nerr ? (char *)NULL : sys_errlist[err_no]);
91
92   if (errp == (char *)NULL)
93   {
94     errp = buff;
95     sprintf_irc(errp, "Unknown Error %d", err_no);
96   }
97   return errp;
98 }
99
100 #endif /* !HAVE_STRERROR */
101
102 /*
103  * inetntoa --    Changed the parameter to NOT take a pointer.
104  *                -Run 4/8/97
105  * inetntoa --    Changed name to remove collision possibility and
106  *                so behaviour is garanteed to take a pointer arg.
107  *                -avalon 23/11/92
108  * inet_ntoa --   Returned the dotted notation of a given
109  *                internet number (some ULTRIX don't have this)
110  *                -argv 11/90.
111  * inet_ntoa --   Its broken on some Ultrix/Dynix too. -avalon
112  */
113 char *inetntoa(struct in_addr in)
114 {
115   static char buf[16];
116   Reg1 unsigned char *s = (unsigned char *)&in.s_addr;
117   Reg2 unsigned char a, b, c, d;
118
119   a = *s++;
120   b = *s++;
121   c = *s++;
122   d = *s++;
123   sprintf_irc(buf, "%u.%u.%u.%u", a, b, c, d);
124
125   return buf;
126 }
127
128 #ifndef HAVE_INET_NETOF
129 /*
130  *    inet_netof --   return the net portion of an internet number
131  *                    argv 11/90
132  */
133 int inet_netof(struct in_addr in)
134 {
135   int addr = in.s_net;
136
137   if (addr & 0x80 == 0)
138     return ((int)in.s_net);
139
140   if (addr & 0x40 == 0)
141     return ((int)in.s_net * 256 + in.s_host);
142
143   return ((int)in.s_net * 256 + in.s_host * 256 + in.s_lh);
144 }
145
146 #endif /* !HAVE_INET_NETOF */
147
148 #ifndef HAVE_GETTIMEOFDAY
149 /* This is copied from ircu3.0.0 (with permission), not vica versa. */
150 int gettimeofday(struct timeval *tv, void * /*UNUSED*/)
151 {
152   register int ret;
153   static struct timespec tp;
154
155   if ((ret = getclock(TIMEOFDAY, &tp)))
156     return ret;
157   tv->tv_sec = (long)tp.tv_sec;
158   tv->tv_usec = (tp.tv_nsec + 500) / 1000;
159   return 0;
160 }
161 #endif /* !HAVE_GETTIMEOFDAY */
162
163 #ifdef DEBUGMODE
164
165 void dumpcore(const char *pattern, ...)
166 {
167   va_list vl;
168   static time_t lastd = 0;
169   static int dumps = 0;
170   char corename[12];
171   time_t now;
172   int p;
173
174   va_start(vl, pattern);
175
176   now = time(NULL);
177
178   if (!lastd)
179     lastd = now;
180   else if (now - lastd < 60 && dumps > 2)
181 #ifdef __cplusplus
182     s_die(0);
183 #else
184     s_die();
185 #endif
186   if (now - lastd > 60)
187   {
188     lastd = now;
189     dumps = 1;
190   }
191   else
192     dumps++;
193   p = getpid();
194   if (fork() > 0)
195   {
196     kill(p, 3);
197     kill(p, 9);
198   }
199   write_pidfile();
200   sprintf_irc(corename, "core.%d", p);
201   rename("core", corename);
202   Debug((DEBUG_FATAL, "Dumped core : core.%d", p));
203   sendto_ops("Dumped core : core.%d", p);
204   vdebug(DEBUG_FATAL, pattern, vl);
205   vsendto_ops(pattern, vl);
206 #ifdef __cplusplus
207   s_die(0);
208 #else
209   s_die();
210 #endif
211
212   va_end(vl);
213 }
214 #endif
215
216 int check_if_ipmask(const char *mask)
217 {
218   int has_digit = 0;
219   register const char *p;
220
221   for (p = mask; *p; ++p)
222     if (*p != '*' && *p != '?' && *p != '.')
223     {
224       if (!isDigit(*p))
225         return 0;
226       has_digit = -1;
227     }
228
229   return has_digit;
230 }
231
232 /* Moved from logf() in whocmds.c to here. Modified a 
233  * bit and used for most logging now.
234  *  -Ghostwolf 12-Jul-99
235  */
236
237 extern void write_log(const char *filename, const char *pattern, ...)
238 {
239   FBFILE *logfile;
240   va_list vl;
241   static char logbuf[1024];
242
243   logfile = fbopen(filename, "a");
244
245   if (logfile)
246   {
247     va_start(vl, pattern);
248     vsprintf_irc(logbuf, pattern, vl);
249     va_end(vl);
250
251     fbputs(logbuf, logfile);
252     fbclose(logfile);
253   }
254 }