1N/A * Copyright (c) 1999-2002 Sendmail, Inc. and its suppliers. 1N/A * All rights reserved. 1N/A * By using this file, you agree to the terms and conditions set 1N/A * forth in the LICENSE file which can be found at the top level of 1N/A * the sendmail distribution. 1N/A#
pragma ident "%Z%%M% %I% %E% SMI" 1N/A** Notice: this file is used by libmilter. Please try to avoid 1N/A** using libsm specific functions. 1N/A** XXX the type of the length parameter has been changed 1N/A** from size_t to ssize_t to avoid theoretical problems with negative 1N/A** numbers passed into these functions. 1N/A** The real solution to this problem is to make sure that this doesn't 1N/A** happen, but for now we'll use this workaround. 1N/A** SM_STRLCPY -- size bounded string copy 1N/A** This is a bounds-checking variant of strcpy. 1N/A** If size > 0, copy up to size-1 characters from the nul terminated 1N/A** string src to dst, nul terminating the result. If size == 0, 1N/A** the dst buffer is not modified. 1N/A** Additional note: this function has been "tuned" to run fast and tested 1N/A** as such (versus versions in some OS's libc). 1N/A** The result is strlen(src). You can detect truncation (not all 1N/A** of the characters in the source string were copied) using the 1N/A** char *s, buf[BUFSIZ]; 1N/A** if (sm_strlcpy(buf, s, sizeof(buf)) >= sizeof(buf)) 1N/A** dst -- destination buffer 1N/A** src -- source string 1N/A** size -- size of destination buffer 1N/A** SM_STRLCAT -- size bounded string concatenation 1N/A** This is a bounds-checking variant of strcat. 1N/A** If strlen(dst) < size, then append at most size - strlen(dst) - 1 1N/A** characters from the source string to the destination string, 1N/A** nul terminating the result. Otherwise, dst is not modified. 1N/A** The result is the initial length of dst + the length of src. 1N/A** You can detect overflow (not all of the characters in the 1N/A** source string were copied) using the following idiom: 1N/A** char *s, buf[BUFSIZ]; 1N/A** if (sm_strlcat(buf, s, sizeof(buf)) >= sizeof(buf)) 1N/A** dst -- nul-terminated destination string buffer 1N/A** src -- nul-terminated source string 1N/A** size -- size of destination buffer 1N/A** total length of the string tried to create 1N/A** (= initial length of dst + length of src) 1N/A** SM_STRLCAT2 -- append two strings to dst obeying length and 1N/A** strlcat2 will append at most len - strlen(dst) - 1 chars. 1N/A** terminates with '\0' if len > 0 1N/A** dst = dst "+" src1 "+" src2 1N/A** use this instead of sm_strlcat(dst,src1); sm_strlcat(dst,src2); 1N/A** dst -- "destination" string. 1N/A** src1 -- "from" string 1. 1N/A** src2 -- "from" string 2. 1N/A** len -- max. length of "destination" string. 1N/A** total length of the string tried to create 1N/A** (= initial length of dst + length of src) 1N/A** if this is greater than len then an overflow would have 1N/A /* current size of dst */ 1N/A /* max. size is less than current? */ 1N/A len -= o +
1;
/* space left in dst */ 1N/A /* copy the first string; i: index in src1; j: index in dst */ 1N/A /* src1: end reached? */ 1N/A /* no: terminate dst; there is space since i < len */ 1N/A len -= i;
/* space left in dst */ 1N/A /* copy the second string; i: index in src2; j: index in dst */ 1N/A dst[j] =
'\0';
/* terminate dst; there is space since i < len */ 1N/A** SM_STRLCPYN -- concatenate n strings and assign the result to dst 1N/A** while obeying length and '\0' terminate it 1N/A** dst = src1 "+" src2 "+" ... 1N/A** use this instead of sm_snprintf() for string values 1N/A** and repeated sm_strlc*() calls for better speed. 1N/A** dst -- "destination" string. 1N/A** len -- max. length of "destination" string. 1N/A** n -- number of strings 1N/A** total length of the string tried to create 1N/A** (= initial length of dst + length of src) 1N/A** if this is greater than len then an overflow would have 1N/A#
endif /* __STDC__ */ 1N/A if (
len-- <= 0)
/* This allows space for the terminating '\0' */ 1N/A j = 0;
/* index in dst */ 1N/A /* loop through all source strings */ 1N/A /* copy string; i: index in str; j: index in dst */ 1N/A /* str: end reached? */ 1N/A /* no: terminate dst; there is space since j < len */ 1N/A dst[j] =
'\0';
/* terminate dst; there is space since j < len */ 1N/A** SM_STRLAPP -- append string if it fits into buffer. 1N/A** If size > 0, copy up to size-1 characters from the nul terminated 1N/A** string src to dst, nul terminating the result. If size == 0, 1N/A** the dst buffer is not modified. 1N/A** This routine is useful for appending strings in a loop, e.g, instead of 1N/A** for (ptr, ptr != NULL, ptr = next->ptr) 1N/A** (void) sm_strlcpy(s, ptr->string, sizeof buf - (s - buf)); 1N/A** replace the loop body with: 1N/A** if (!sm_strlapp(*s, ptr->string, sizeof buf - (s - buf))) 1N/A** XXX interface isn't completely clear (yet), hence this code is 1N/A** dst -- (pointer to) destination buffer 1N/A** src -- source string 1N/A** size -- size of destination buffer 1N/A** true if strlen(src) < size 1N/A** modifies dst if append succeeds (enough space).