Add support for arc4random
[ngircd-alex.git] / src / tool / tool.c
1 /*
2  * ngIRCd -- The Next Generation IRC Daemon
3  * Copyright (c)2001-2010 Alexander Barton (alex@barton.de)
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 2 of the License, or
8  * (at your option) any later version.
9  * Please read the file COPYING, README and AUTHORS for more information.
10  */
11
12 #include "portab.h"
13
14 /**
15  * @file
16  * Tool functions
17  */
18
19 #include "imp.h"
20 #include <assert.h>
21 #include <ctype.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <sys/time.h>
26
27 #include <netinet/in.h>
28
29 #ifdef SYSLOG
30 #define SYSLOG_NAMES 1
31 #include <syslog.h>
32 #endif
33
34 #include "exp.h"
35 #include "tool.h"
36
37
38 /**
39  * Removes all leading and trailing whitespaces of a string.
40  * @param String The string to remove whitespaces from.
41  */
42 GLOBAL void
43 ngt_TrimStr(char *String)
44 {
45         char *start, *end;
46
47         assert(String != NULL);
48
49         start = String;
50
51         /* Remove whitespaces at the beginning of the string ... */
52         while (*start == ' ' || *start == '\t' ||
53                *start == '\n' || *start == '\r')
54                 start++;
55
56         if (!*start) {
57                 *String = '\0';
58                 return;
59         }
60
61         /* ... and at the end: */
62         end = strchr(start, '\0');
63         end--;
64         while ((*end == ' ' || *end == '\t' || *end == '\n' || *end == '\r')
65                && end >= start)
66                 end--;
67
68         /* New trailing NULL byte */
69         *(++end) = '\0';
70
71         memmove(String, start, (size_t)(end - start)+1);
72 } /* ngt_TrimStr */
73
74
75 /**
76  * Convert a string to uppercase letters.
77  */
78 GLOBAL char *
79 ngt_UpperStr(char *String)
80 {
81         char *ptr;
82
83         assert(String != NULL);
84
85         ptr = String;
86         while(*ptr) {
87                 *ptr = toupper((int)*ptr);
88                 ptr++;
89         }
90         return String;
91 } /* ngt_UpperStr */
92
93
94 /**
95  * Convert a string to lowercase letters.
96  */
97 GLOBAL char *
98 ngt_LowerStr(char *String)
99 {
100         char *ptr;
101
102         assert(String != NULL);
103
104         ptr = String;
105         while(*ptr) {
106                 *ptr = tolower((int)*ptr);
107                 ptr++;
108         }
109         return String;
110 } /* ngt_LowerStr */
111
112
113 GLOBAL void
114 ngt_TrimLastChr( char *String, const char Chr)
115 {
116         /* If last character in the string matches Chr, remove it.
117          * Empty strings are handled correctly. */
118
119         size_t len;
120
121         assert(String != NULL);
122
123         len = strlen(String);
124         if(len == 0)
125                 return;
126
127         len--;
128
129         if(String[len] == Chr)
130                 String[len] = '\0';
131 } /* ngt_TrimLastChr */
132
133
134 /**
135  * Fill a String with random chars
136  */
137 GLOBAL char *
138 ngt_RandomStr(char *String, const size_t len)
139 {
140         static const char chars[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!\"#$&'()*+,-./:;<=>?@[\\]^_`";
141         struct timeval t;
142         size_t i;
143
144         assert(String != NULL);
145
146         gettimeofday(&t, NULL);
147 #ifndef HAVE_ARC4RANDOM
148         srand((unsigned)(t.tv_usec * t.tv_sec));
149
150         for (i = 0; i < len; ++i) {
151                 String[i] = chars[rand() % (sizeof(chars) - 1)];
152         }
153 #else
154         for (i = 0; i < len; ++i)
155                 String[i] = chars[arc4random() % (sizeof(chars) - 1)];
156 #endif
157         String[len] = '\0';
158
159         return String;
160 } /* ngt_RandomStr */
161
162
163 #ifdef SYSLOG
164
165
166 #ifndef INTERNAL_MARK
167
168 #ifndef _code
169 typedef struct _code {
170         char    *c_name;
171         int     c_val;
172 } CODE;
173 #endif
174
175 CODE facilitynames[] = {
176 #ifdef LOG_AUTH
177         { "auth",       LOG_AUTH },
178 #endif
179 #ifdef LOG_AUTHPRIV
180         { "authpriv",   LOG_AUTHPRIV },
181 #endif
182 #ifdef LOG_CRON
183         { "cron",       LOG_CRON },
184 #endif
185 #ifdef LOG_DAEMON
186         { "daemon",     LOG_DAEMON },
187 #endif
188 #ifdef LOG_FTP
189         { "ftp",        LOG_FTP },
190 #endif
191 #ifdef LOG_LPR
192         { "lpr",        LOG_LPR },
193 #endif
194 #ifdef LOG_MAIL
195         { "mail",       LOG_MAIL },
196 #endif
197 #ifdef LOG_NEWS
198         { "news",       LOG_NEWS },
199 #endif
200 #ifdef LOG_UUCP
201         { "uucp",       LOG_UUCP },
202 #endif
203 #ifdef LOG_USER
204         { "user",       LOG_USER },
205 #endif
206 #ifdef LOG_LOCAL7
207         { "local0",     LOG_LOCAL0 },
208         { "local1",     LOG_LOCAL1 },
209         { "local2",     LOG_LOCAL2 },
210         { "local3",     LOG_LOCAL3 },
211         { "local4",     LOG_LOCAL4 },
212         { "local5",     LOG_LOCAL5 },
213         { "local6",     LOG_LOCAL6 },
214         { "local7",     LOG_LOCAL7 },
215 #endif
216         { 0,            -1 }
217 };
218
219 #endif
220
221
222 GLOBAL const char*
223 ngt_SyslogFacilityName(int Facility)
224 {
225         int i = 0;
226         while(facilitynames[i].c_name) {
227                 if (facilitynames[i].c_val == Facility)
228                         return facilitynames[i].c_name;
229                 i++;
230         }
231         return "unknown";
232 }
233
234
235 GLOBAL int
236 ngt_SyslogFacilityID(char *Name, int DefaultFacility)
237 {
238         int i = 0;
239         while(facilitynames[i].c_name) {
240                 if (strcasecmp(facilitynames[i].c_name, Name) == 0)
241                         return facilitynames[i].c_val;
242                 i++;
243         }
244         return DefaultFacility;
245 }
246
247
248 #endif
249
250
251 /* -eof- */