2 * IRC - Internet Relay Chat, ircd/ircd_string.c
3 * Copyright (C) 1999 Thomas Helvey
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)
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.
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.
21 #include "ircd_string.h"
22 #include "ircd_defs.h"
23 #include "ircd_chattr.h"
27 * include the character attribute tables here
29 #include "chattr.tab.c"
34 * Walk through a string of tokens, using a set of separators.
37 char* ircd_strtok(char **save, char *str, char *fs)
39 char *pos = *save; /* keep last position across calls */
43 pos = str; /* new string scan */
45 while (pos && *pos && strchr(fs, *pos) != NULL)
46 pos++; /* skip leading separators */
49 return (pos = *save = NULL); /* string contains only sep's */
51 tmp = pos; /* now, keep position of the token */
53 while (*pos && strchr(fs, *pos) == NULL)
54 pos++; /* skip content of the token */
57 *pos++ = '\0'; /* remove first sep after the token */
59 pos = NULL; /* end of string */
68 * reduce a string of duplicate list entries to contain only the unique
69 * items. Unavoidably O(n^2).
71 char* canonize(char* buffer)
73 static char cbuf[BUFSIZE];
83 for (s = ircd_strtok(&p, buffer, ","); s; s = ircd_strtok(&p, NULL, ","))
88 for (t = ircd_strtok(&p2, cbuf, ","); t; t = ircd_strtok(&p2, NULL, ","))
89 if (0 == ircd_strcmp(s, t))
113 * ircd_strncpy - optimized strncpy
114 * This may not look like it would be the fastest possible way to do it,
115 * but it generally outperforms everything else on many platforms,
116 * including asm library versions and memcpy, if compiled with the
117 * optimizer on. (-O2 for gcc) --Bleep
119 char* ircd_strncpy(char* s1, const char* s2, size_t n)
127 while (s < endp && (*s++ = *s2++))
134 NTL_HDR_strChattr { NTL_SRC_strChattr }
135 NTL_HDR_strCasediff { NTL_SRC_strCasediff }
136 #endif /* !FORCEINLINE */
138 /*=============================================================================
139 * Other functions visible externally
142 int strnChattr(const char *s, size_t n)
148 x &= IRCD_CharAttrTab[*rs++ - CHAR_MIN];
153 * ircd_strcmp - case insensitive comparison of 2 strings
154 * NOTE: see ircd_chattr.h for notes on case mapping.
156 int ircd_strcmp(const char *a, const char *b)
160 while (ToLower(*ra) == ToLower(*rb)) {
170 * ircd_strncmp - counted case insensitive comparison of 2 strings
171 * NOTE: see ircd_chattr.h for notes on case mapping.
173 int ircd_strncmp(const char *a, const char *b, size_t n)
180 while (ToLower(*ra) == ToLower(*rb)) {
181 if (!*ra++ || !left--)
190 * unique_name_vector - create a unique vector of names from
191 * a token separated list
192 * list - [in] a token delimited null terminated character array
193 * token - [in] the token to replace
194 * vector - [out] vector of strings to be returned
195 * size - [in] maximum number of elements to place in vector
196 * Returns count of elements placed into the vector, if the list
197 * is an empty string { '\0' } 0 is returned.
198 * list, and vector must be non-null and size must be > 0
199 * Empty strings <token><token> are not placed in the vector or counted.
200 * This function ignores all subsequent tokens when count == size
202 * NOTE: this function destroys it's input, do not use list after it
203 * is passed to this function
205 int unique_name_vector(char* list, char token, char** vector, int size)
217 * ignore spurious tokens
219 while (token == *start)
222 for (end = strchr(start, token); end; end = strchr(start, token)) {
225 * ignore spurious tokens
227 while (token == *end)
229 for (i = 0; i < count; ++i) {
230 if (0 == ircd_strcmp(vector[i], start))
234 vector[count++] = start;
241 vector[count++] = start;
247 * token_vector - create a vector of tokens from
248 * a token separated list
249 * list - [in] a token delimited null terminated character array
250 * token - [in] the token to replace
251 * vector - [out] vector of strings to be returned
252 * size - [in] maximum number of elements to place in vector
253 * returns count of elements placed into the vector, if the list
254 * is an empty string { '\0' } 0 is returned.
255 * list, and vector must be non-null and size must be > 1
256 * Empty tokens are counted and placed in the list
258 * NOTE: this function destroys it's input, do not use list after it
259 * is passed to this function
261 int token_vector(char* list, char token, char** vector, int size)
271 vector[count++] = start;
272 for (end = strchr(start, token); end; end = strchr(start, token)) {
276 vector[count++] = start;
286 * host_from_uh - get the host.domain part of a user@host.domain string
287 * ripped from get_sockhost
289 char* host_from_uh(char* host, const char* userhost, size_t n)
294 assert(0 != userhost);
296 if ((s = strchr(userhost, '@')))
300 ircd_strncpy(host, s, n);
306 * this new faster inet_ntoa was ripped from:
307 * From: Thomas Helvey <tomh@inxpress.net>
309 static const char* IpQuadTab[] =
311 "0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
312 "10", "11", "12", "13", "14", "15", "16", "17", "18", "19",
313 "20", "21", "22", "23", "24", "25", "26", "27", "28", "29",
314 "30", "31", "32", "33", "34", "35", "36", "37", "38", "39",
315 "40", "41", "42", "43", "44", "45", "46", "47", "48", "49",
316 "50", "51", "52", "53", "54", "55", "56", "57", "58", "59",
317 "60", "61", "62", "63", "64", "65", "66", "67", "68", "69",
318 "70", "71", "72", "73", "74", "75", "76", "77", "78", "79",
319 "80", "81", "82", "83", "84", "85", "86", "87", "88", "89",
320 "90", "91", "92", "93", "94", "95", "96", "97", "98", "99",
321 "100", "101", "102", "103", "104", "105", "106", "107", "108", "109",
322 "110", "111", "112", "113", "114", "115", "116", "117", "118", "119",
323 "120", "121", "122", "123", "124", "125", "126", "127", "128", "129",
324 "130", "131", "132", "133", "134", "135", "136", "137", "138", "139",
325 "140", "141", "142", "143", "144", "145", "146", "147", "148", "149",
326 "150", "151", "152", "153", "154", "155", "156", "157", "158", "159",
327 "160", "161", "162", "163", "164", "165", "166", "167", "168", "169",
328 "170", "171", "172", "173", "174", "175", "176", "177", "178", "179",
329 "180", "181", "182", "183", "184", "185", "186", "187", "188", "189",
330 "190", "191", "192", "193", "194", "195", "196", "197", "198", "199",
331 "200", "201", "202", "203", "204", "205", "206", "207", "208", "209",
332 "210", "211", "212", "213", "214", "215", "216", "217", "218", "219",
333 "220", "221", "222", "223", "224", "225", "226", "227", "228", "229",
334 "230", "231", "232", "233", "234", "235", "236", "237", "238", "239",
335 "240", "241", "242", "243", "244", "245", "246", "247", "248", "249",
336 "250", "251", "252", "253", "254", "255"
340 * ircd_ntoa - rewrote and renamed yet again :) --Bleep
341 * inetntoa - in_addr to string
342 * changed name to remove collision possibility and
343 * so behaviour is guaranteed to take a pointer arg.
345 * inet_ntoa -- returned the dotted notation of a given
348 * inet_ntoa -- its broken on some Ultrix/Dynix too. -avalon
350 const char* ircd_ntoa(const char* in)
353 return ircd_ntoa_r(buf, in);
357 * reentrant version of above
359 const char* ircd_ntoa_r(char* buf, const char* in)
362 const unsigned char* a = (const unsigned char*)in;