OpenDNSSEC-enforcer
1.3.4
|
00001 /* 00002 * $Id: string_util.c 3718 2010-08-10 21:17:18Z jakob $ 00003 * 00004 * Copyright (c) 2008-2009 Nominet UK. All rights reserved. 00005 * 00006 * Redistribution and use in source and binary forms, with or without 00007 * modification, are permitted provided that the following conditions 00008 * are met: 00009 * 1. Redistributions of source code must retain the above copyright 00010 * notice, this list of conditions and the following disclaimer. 00011 * 2. Redistributions in binary form must reproduce the above copyright 00012 * notice, this list of conditions and the following disclaimer in the 00013 * documentation and/or other materials provided with the distribution. 00014 * 00015 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 00016 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00017 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00018 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 00019 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00020 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 00021 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00022 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 00023 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 00024 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 00025 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00026 * 00027 */ 00028 00029 /*++ 00030 * Filename: string_util.c 00031 * 00032 * Description: 00033 * String utility functions used by the whois programs. 00034 -*/ 00035 00036 #include "config.h" 00037 00038 #include <assert.h> 00039 #include <ctype.h> 00040 #include <string.h> 00041 #include <stdio.h> 00042 #include <stdlib.h> 00043 00044 #include "compat.h" 00045 00046 #include "ksm/string_util.h" 00047 #include "ksm/message.h" 00048 #include "ksm/ksmdef.h" 00049 00050 /*+ 00051 * StrUncomment - Uncomment Line 00052 * 00053 * Description: 00054 * Locates the first comment character in the line, and truncates the line 00055 * at that point. The comment character is hard-coded as the hash (#) 00056 * character. 00057 * 00058 * Arguments: 00059 * char* line (modified) 00060 * Line to check. If a comment introducer exists, it is replaced with 00061 * a null character. If the line is NULL, the routine is a no-op. 00062 * 00063 * Returns: 00064 * void 00065 -*/ 00066 00067 void StrUncomment(char* line) 00068 { 00069 char *comment; /* Pointer to first comment character */ 00070 00071 if (line && (comment = strstr(line, COMMENT_CHAR))) { 00072 00073 /* comment points to character, or null if not found */ 00074 00075 *comment = '\0'; 00076 } 00077 } 00078 00079 00080 00081 /*+ 00082 * StrWhitespace - Replace Whitespace 00083 * 00084 * Description: 00085 * Replaces every whitespace characters with a space. This conversion is 00086 * usually done to simplify future processing. 00087 * 00088 * Arguments: 00089 * char* line (modified) 00090 * Line to modify. 00091 * 00092 * Returns: 00093 * void 00094 -*/ 00095 00096 void StrWhitespace(char* line) 00097 { 00098 if (line) { 00099 while (*line) { 00100 if (isspace((int) *line)) { 00101 *line = ' '; 00102 } 00103 ++line; 00104 } 00105 } 00106 } 00107 00108 00109 /*+ 00110 * StrStrdup - Duplicate String 00111 * 00112 * Description: 00113 * Wrapper for "strdup" that always returns, or exits the program (after 00114 * outputting a message to stderr) if the string duplication fails. 00115 * 00116 * Arguments: 00117 * const char* string (input) 00118 * String to be duplicated. 00119 * 00120 * Returns: 00121 * char* 00122 * Pointer to duplicated string (guaranteed to be non-null). The 00123 * string should be freed with StrFree() - a macro wrapper for "free". 00124 -*/ 00125 00126 char* StrStrdup(const char* string) 00127 { 00128 char* duplicate = NULL; /* Pointer to the duplicated string */ 00129 00130 if (string) { 00131 duplicate = strdup(string); 00132 if (duplicate == NULL) { 00133 MsgLog(KSM_STMTALLOC, "StrStrdup: Call to malloc() returned null - out of swap space?"); 00134 fprintf(stderr, "StrStrdup: Call to malloc() returned null - out of swap space?"); 00135 exit(1); 00136 } 00137 } 00138 else { 00139 duplicate = MemCalloc(1, 1); /* Allocate a single zeroed byte */ 00140 } 00141 00142 return duplicate; 00143 } 00144 00145 00146 /*+ 00147 * StrStrncpy - Copy String 00148 * StrStrncat - Concatenate String 00149 * 00150 * Description: 00151 * Wrapper for "strncpy"/"strncat" that guarantees that: 00152 * 00153 * (a) As much of the source string as possible is copied to the 00154 * destination. 00155 * (b) The destination string is terminated by a null byte (something not 00156 * guaranteed by the standard functions). 00157 * 00158 * Also, the function is void, unlike the standard library counterparts 00159 * that return a pointer to the destination string. 00160 * 00161 * Arguments: 00162 * char* dst (output) 00163 * Destination string. The final byte of this string will always be 00164 * set to NULL. If this argument is NULL, the routine is a no-op. 00165 * 00166 * const char* src (input) 00167 * Source string. If NULL, the routine is a no-op (StrStrncat) or 00168 * the destination is set to the empty string (StrStrncpy). 00169 * 00170 * size_t dstlen (input) 00171 * Total amount of space allocated for the destination, including the 00172 * terminating null byte. If this is zero, the routine is a no-op. 00173 * Note that in the case of StrStrncat, this is the total amount of 00174 * space IGNORING the current contents of "dst" - it is just the total 00175 * space available to hold the entire resultant string. 00176 -*/ 00177 00178 void StrStrncpy(char* dst, const char* src, size_t dstlen) 00179 { 00180 if (dst && (dstlen > 0)) { 00181 if (src) { 00182 (void) strlcpy(dst, src, dstlen); 00183 /* dst[dstlen - 1] = '\0'; */ 00184 } 00185 else { 00186 dst[0] = '\0'; 00187 } 00188 } 00189 00190 return; 00191 } 00192 00193 void StrStrncat(char* dst, const char* src, size_t dstlen) 00194 { 00195 size_t length; /* Amount of space used in dst */ 00196 size_t remain; /* Remaining space in dst */ 00197 00198 if (dst) { 00199 length = strlen(dst); 00200 remain = dstlen - length; 00201 if (remain > 1) { 00202 00203 /* More space than just the trailing NULL */ 00204 00205 StrStrncpy(&dst[length], src, remain); 00206 } 00207 } 00208 00209 return; 00210 } 00211 00212 00213 00214 /*+ 00215 * StrTrimR - Trim Right 00216 * 00217 * Description: 00218 * Modifies a string by trimming white-space characters from the right of 00219 * the string. It does this by modifying the string, inserting a null 00220 * character after the last non white-space character. 00221 * 00222 * Arguments: 00223 * char *text (modified) 00224 * Text to modify. If this is NULL, the routine is a no-op. 00225 * 00226 * Returns: 00227 * void 00228 -*/ 00229 00230 void StrTrimR(char *text) 00231 { 00232 if (text) { 00233 00234 /* Work backwards through the string */ 00235 00236 int textlen = strlen(text); 00237 while (-- textlen >= 0) { 00238 if (! isspace((int) text[textlen])) { 00239 text[textlen + 1] = '\0'; 00240 return; 00241 } 00242 } 00243 00244 /* Get here if the entire string is white space */ 00245 00246 text[0] = '\0'; 00247 } 00248 return; 00249 } 00250 00251 00252 00253 /*+ 00254 * StrTrimL - Trim Left 00255 * 00256 * Description: 00257 * Searches a string and returns a pointer to the first non white-space 00258 * character in it. 00259 * 00260 * Arguments: 00261 * char* text (input) 00262 * Text to search. 00263 * 00264 * Returns: 00265 * char* 00266 * Pointer to first non white-space character in the string. If the 00267 * string is NULL, NULL is returned. If the string is all white space, 00268 * a pointer to the trailing null character is returned. 00269 -*/ 00270 00271 char* StrTrimL(char* text) 00272 { 00273 if (text) { 00274 while (*text && isspace((int) *text)) { 00275 ++text; 00276 } 00277 } 00278 00279 return text; 00280 } 00281 00282 00283 /*+ 00284 * StrTrim - Trim String 00285 * 00286 * Description: 00287 * A combination of StrTrimL and StrTrimR, this routine modifies the passed 00288 * string by inserting the null character after the last non-space in the 00289 * string, then returning a pointer into the string to the first non 00290 * white-space character. 00291 * 00292 * Arguments: 00293 * char *text (modified) 00294 * Text to be trimmed. The text may be modified. 00295 * 00296 * Returns: 00297 * char* 00298 * Pointer into text of the first non white-space character. If the 00299 * input string is NULL, NULL is returned. 00300 -*/ 00301 00302 char* StrTrim(char* text) 00303 { 00304 StrTrimR(text); 00305 return StrTrimL(text); 00306 } 00307 00308 00309 /*+ 00310 * StrToLower - Convert to Lower Case 00311 * 00312 * Description: 00313 * Converts the passed string to lowercase characters. As a side-effect it 00314 * also returns the length of the string. 00315 * 00316 * Arguments: 00317 * char *text (modified) 00318 * String to be modified. If NULL, this routine is a no-op. 00319 * 00320 * Returns: 00321 * size_y 00322 * Length of the string. 00323 -*/ 00324 00325 size_t StrToLower(char* string) 00326 { 00327 char* ptr = string; 00328 if (ptr) { 00329 while (*ptr) { 00330 *ptr = tolower((int) *ptr); 00331 ++ptr; 00332 } 00333 } 00334 00335 return (size_t) (ptr - string); 00336 } 00337 00338 00339 /*+ 00340 * StrToUpper - Convert to Upper Case 00341 * 00342 * Description: 00343 * Converts the passed string to uppercase characters. As a side-effect it 00344 * also returns the length of the string. 00345 * 00346 * Arguments: 00347 * char *text (modified) 00348 * String to be modified. If NULL, this routine is a no-op. 00349 * 00350 * Returns: 00351 * size_t 00352 * Length of the string. 00353 -*/ 00354 00355 size_t StrToUpper(char* string) 00356 { 00357 char* ptr = string; 00358 if (ptr) { 00359 while (*ptr) { 00360 *ptr = toupper((int) *ptr); 00361 ++ptr; 00362 } 00363 } 00364 00365 return (size_t) (ptr - string); 00366 } 00367 00368 00369 00370 /*+ 00371 * StrReplaceChar - Replace Character - Null-Terminated String 00372 * StrReplaceCharN - Replace Character - Length Given 00373 * 00374 * Description: 00375 * Replaces all occurrences of a given character in a string by the given 00376 * character. 00377 * 00378 * StrReplaceCharN is generally used where the string may contain embedded 00379 * null characters in order to remove them. 00380 * 00381 * Arguments: 00382 * char* string (modified) 00383 * String in which the replacement is to take place. 00384 * 00385 * size_t len (input, StrReplaceCharN only) 00386 * Lenght of input string. 00387 * 00388 * char search (input) 00389 * Character to search for. 00390 * 00391 * char replace (input) 00392 * Replacement chaaracter. 00393 * 00394 * Returns: 00395 * size_t 00396 * Number of replacements. 00397 -*/ 00398 00399 size_t StrReplaceCharN(char* string, size_t len, char search, char replace) 00400 { 00401 size_t count = 0; /* Replacement count */ 00402 size_t i; /* Loop counter */ 00403 00404 if (string) { 00405 for (i = 0; i < len; ++i) { 00406 if (string[i] == search) { 00407 string[i] = replace; 00408 ++count; 00409 } 00410 } 00411 } 00412 return count; 00413 } 00414 00415 size_t StrReplaceChar(char* string, char search, char replace) 00416 { 00417 size_t count = 0; /* Replacement count */ 00418 00419 if (string) { 00420 count = StrReplaceCharN(string, strlen(string), search, replace); 00421 } 00422 return count; 00423 } 00424 00425 00426 00427 /*+ 00428 * StrTrimmedLength 00429 * 00430 * Description: 00431 * Searches the string and returns the length of the string less leading 00432 * and trailing spaces. Essentially, this will be the result of a call to 00433 * strlen() after the string has been passed through StrTrim(). 00434 * 00435 * Arguments: 00436 * const char* string (input) 00437 * String to search. 00438 * 00439 * Returns: 00440 * size_t 00441 * Size of the string. 00442 -*/ 00443 00444 size_t StrTrimmedLength(const char* string) 00445 { 00446 size_t length = 0; /* Length of trimmed string */ 00447 size_t in_length; /* Length of input string */ 00448 size_t first_char; /* Position of first non-space character */ 00449 size_t last_char; /* Position of last non-space character */ 00450 00451 if (string) { 00452 in_length = strlen(string); 00453 00454 /* 00455 * Get offset of first non-space character. If the string does not 00456 * contain any such characters, first_char will equal "length". 00457 */ 00458 00459 first_char = 0; 00460 while (first_char < in_length) { 00461 if (! isspace((int) string[first_char])) { 00462 break; 00463 } 00464 ++first_char; 00465 } 00466 00467 if (first_char < in_length) { 00468 00469 /* 00470 * Must be a printable character, so find the offset of the last 00471 * such character. 00472 */ 00473 00474 last_char = in_length - 1; 00475 while (isspace((int) string[last_char])) { 00476 --last_char; 00477 } 00478 00479 /* ... and work out the length */ 00480 00481 length = last_char - first_char + 1; 00482 assert(length > 0); 00483 } 00484 00485 /* No "else" - length is set to zero on enty */ 00486 } 00487 00488 return length; 00489 }