/* source: utils.c */
/* Copyright Gerhard Rieger and contributors (see file CHANGES) */
/* Published under the GNU General Public License V.2, see file COPYING */

/* useful additions to C library */

#include "config.h"

#include "sysincludes.h"

#include "compat.h"	/* socklen_t */
#include "mytypes.h"
#include "sycls.h"
#include "utils.h"


#if !HAVE_PROTOTYPE_LIB_memrchr
/* GNU extension, available since glibc 2.1.91 */
void *memrchr(const void *s, int c, size_t n) {
   const unsigned char *t = ((unsigned char *)s)+n;
   while (--t >= (unsigned char *)s) {
      if (*t == c)  break;
   }
   if (t < (unsigned char *)s)
      return NULL;
   return (void *)t;
}
#endif /* !HAVE_PROTOTYPE_LIB_memrchr */

void *memdup(const void *src, size_t n) {
   void *dest;

   if ((dest = Malloc(n)) == NULL) {
      return NULL;
   }

   memcpy(dest, src, n);
   return dest;
}

/* search the keyword-table for a match of the leading part of name. */
/* returns the pointer to the matching field of the keyword or NULL if no
   keyword was found. */
const struct wordent *keyw(const struct wordent *keywds, const char *name, unsigned int nkeys) {
   unsigned int lower, upper, mid;
   int r;

   lower = 0;
   upper = nkeys;

   while (upper - lower > 1)
   {
      mid = (upper + lower) >> 1;
      if (!(r = strcasecmp(keywds[mid].name, name)))
      {
	 return &keywds[mid];
      }
      if (r < 0)
	 lower = mid;
      else
	 upper = mid;
   }
   if (nkeys > 0 && !(strcasecmp(keywds[lower].name, name)))
   {
      return &keywds[lower];
   }
   return NULL;
}

/* Linux: setenv(), AIX (4.3?): putenv() */
#if !HAVE_SETENV
int setenv(const char *name, const char *value, int overwrite) {
   int result;
   char *env;
   if (!overwrite) {
      if (getenv(name))  return 0;	/* already exists */
   }
   if ((env = Malloc(strlen(name)+strlen(value)+2)) == NULL) {
      return -1;
   }
   sprintf(env, "%s=%s", name, value);
   if ((result = putenv(env)) != 0) {	/* AIX docu says "... nonzero ..." */
      free(env);
      result = -1;
   }
   /* linux "man putenv" says: ...this string becomes part of the environment*/
   return result;
}
#endif /* !HAVE_SETENV */



/* sanitizes an "untrusted" character. output buffer must provide at least 4
   characters space.
   Does not append \0. returns length of output (currently: max 4) */
static size_t sanitize_char(char c, char *o, int style) {
   int hn;	/* high nibble */
   int ln;	/* low nibble */
   int n;	/* written chars */
   if (isprint((unsigned char)c)) {
      *o = c;
      return 1;
   }
   *o++ = '\\';
   n = 2;
   switch (c) {
   case '\0': *o++ = '0';  break;
   case '\a': *o++ = 'a';  break;
   case '\b': *o++ = 'b';  break;
   case '\t': *o++ = 't';  break;
   case '\n': *o++ = 'n';  break;
   case '\v': *o++ = 'v';  break;
   case '\f': *o++ = 'f';  break;
   case '\r': *o++ = 'r';  break;
   case '\'': *o++ = '\''; break;
   case '\"': *o++ = '"';  break;
   case '\\': *o++ = '\\'; break;
   default:
      *o++ = 'x';
      hn = (c>>4)&0x0f;
      ln = c&0x0f;
      *o++ = (hn>=10 ? (('A'-1)+(hn-10)) : ('0'+hn));
      *o++ = (ln>=10 ? (('A'-1)+(ln-10)) : ('0'+ln));
      n = 4;
   }
   return n;
}

/* sanitizes "untrusted" text, replacing special control characters with the C
   string version (eg."\n"), and replacing unprintable chars with hex
   representation ("\xAB").
   text can grow to four times of input, so keep output buffer long enough!
   returns a pointer to the first untouched byte of the output buffer.
   Output is not \0 terminated.
*/
char *sanitize_string(const char *data,	/* input data */
		   size_t bytes,	/* length of input data, >=0 */
		   char *coded,	/* output buffer, must be long enough */
		   int style
		   ) {
   int c;

   while (bytes > 0) {
      c = *(unsigned char *)data++;
      coded += sanitize_char(c, coded, style);
      --bytes;
   }
   return coded;
}

/* copies a substring out of a given buff
   returns scratch, \0 terminated; scratch must provide len+1 bytes
*/
char *xiosubstr(char *scratch, const char *str, size_t from, size_t len) {
   char *scratch0 = scratch;
   str += from;
   while (len--) {
      *scratch++ = *str++;
   }
   *scratch = '\0';
   return scratch0;
}


/* since version 1.7.2.4 socat supports C-99 behaviour of snprintf but still
   can handle the old glibc case with -1 return on truncation.
   Do not rely on exact return value in case of truncation
 */
int xio_snprintf(char *str, size_t size, const char *format, ...) {
   va_list ap;
   int result;

   va_start(ap, format);
   result = vsnprintf(str, size, format, ap);
#if ! HAVE_C99_SNPRINTF
   if (result < 0) {
      result = size+63;	/* indicate truncation with just some guess */
   }
#endif /* !HAVE_C99_SNPRINTF */
   va_end(ap);
   return result;
}
