fecdec: Minor cleanups.
[paraslash.git] / string.c
index 51461b20938df75ed79211b9b5bc5e97e46333e0..3c80d27cc6b6ad73a95392c17cdb041837ec6ba5 100644 (file)
--- a/string.c
+++ b/string.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2004-2008 Andre Noll <maan@systemlinux.org>
+ * Copyright (C) 2004-2009 Andre Noll <maan@systemlinux.org>
  *
  * Licensed under the GPL v2. For licencing details see COPYING.
  */
@@ -59,9 +59,10 @@ __must_check __malloc void *para_realloc(void *p, size_t size)
  */
 __must_check __malloc void *para_malloc(size_t size)
 {
-       assert(size);
-       void *p = malloc(size);
+       void *p;
 
+       assert(size);
+       p = malloc(size);
        if (!p) {
                PARA_EMERG_LOG("malloc failed (size = %zu),  aborting\n",
                        size);
@@ -91,7 +92,7 @@ __must_check __malloc void *para_calloc(size_t size)
 }
 
 /**
- * Pparaslash's version of strdup().
+ * Paraslash's version of strdup().
  *
  * \param s The string to be duplicated.
  *
@@ -250,33 +251,6 @@ __must_check __malloc char *para_tmpname(void)
        return make_message("%08i", rand());
 }
 
-/**
- * Create unique temporary file.
- *
- * \param template The template to be passed to mkstemp().
- * \param mode The desired mode of the tempfile.
- *
- * This wrapper for mkstemp additionally uses fchmod() to
- * set the given mode of the tempfile if mkstemp() returned success.
- *
- * \return The file descriptor of the temp file just created on success.
- * On errors, a negative value is returned.
- */
-__must_check int para_mkstemp(char *template, mode_t mode)
-{
-       int tmp, fd = mkstemp(template);
-
-       if (fd < 0)
-               return -ERRNO_TO_PARA_ERROR(errno);
-       tmp = fchmod(fd, mode);
-       if (tmp >= 0)
-               return fd;
-       tmp = errno;
-       close(fd);
-       unlink(template);
-       return -ERRNO_TO_PARA_ERROR(tmp);
-}
-
 /**
  * Get the logname of the current user.
  *
@@ -354,27 +328,6 @@ __must_check unsigned split_args(char *args, char *** const argv_ptr, const char
        return n;
 }
 
-/**
- * Ensure that file descriptors 0, 1, and 2 are valid.
- *
- * Common approach that opens /dev/null until it gets a file descriptor greater
- * than two.
- *
- * \sa okir's Black Hats Manual.
- */
-void valid_fd_012(void)
-{
-       while (1) {
-               int fd = open("/dev/null", O_RDWR);
-               if (fd < 0)
-                       exit(EXIT_FAILURE);
-               if (fd > 2) {
-                       close(fd);
-                       break;
-               }
-       }
-}
-
 /**
  * Get the own hostname.
  *
@@ -511,7 +464,15 @@ int for_each_line_ro(char *buf, size_t size, line_handler_t *line_handler,
  *
  * This function prints into the buffer given by \a b at the offset which is
  * also given by \a b. If there is not enough space to hold the result, the
- * buffer size is doubled until the underlying call to vsnprintf() succeeds.
+ * buffer size is doubled until the underlying call to vsnprintf() succeeds
+ * or the size of the buffer exceeds the maximal size specified in \a pb.
+ *
+ * In the latter case the unmodified \a buf and \a offset values as well as the
+ * private_data pointer of \a b are passed to the \a max_size_handler of \a b.
+ * If this function succeeds, i.e. returns a non-negative value, the offset of
+ * \a b is reset to zero and the given data is written to the beginning of the
+ * buffer.
+ *
  * Upon return, the offset of \a b is adjusted accordingly so that subsequent
  * calls to this function append data to what is already contained in the
  * buffer.
@@ -532,26 +493,35 @@ __printf_2_3 int para_printf(struct para_buffer *b, const char *fmt, ...)
                b->buf = para_malloc(128);
                b->size = 128;
                b->offset = 0;
-       } else if (b->size <= b->offset + 1) {
-               b->size *= 2;
-               b->buf = para_realloc(b->buf, b->size);
        }
        while (1) {
                char *p = b->buf + b->offset;
                size_t size = b->size - b->offset;
                va_list ap;
-               va_start(ap, fmt);
-               ret = vsnprintf(p, size, fmt, ap);
-               va_end(ap);
-               if (ret > -1 && ret < size) { /* success */
-                       b->offset += ret;
-                       break;
+               if (size) {
+                       va_start(ap, fmt);
+                       ret = vsnprintf(p, size, fmt, ap);
+                       va_end(ap);
+                       if (ret > -1 && ret < size) { /* success */
+                               b->offset += ret;
+                               return ret;
+                       }
                }
-               /* try again with more space */
-               b->size *= 2;
-               b->buf = para_realloc(b->buf, b->size);
+               /* check if we may grow the buffer */
+               if (!b->max_size || 2 * b->size < b->max_size) { /* yes */
+                       /* try again with more space */
+                       b->size *= 2;
+                       b->buf = para_realloc(b->buf, b->size);
+                       continue;
+               }
+               /* can't grow buffer */
+               if (!b->offset || !b->max_size_handler) /* message too large */
+                       return -ERRNO_TO_PARA_ERROR(ENOSPC);
+               ret = b->max_size_handler(b->buf, b->offset, b->private_data);
+               if (ret < 0)
+                       return ret;
+               b->offset = 0;
        }
-       return ret;
 }
 
 /** \cond LLONG_MAX and LLONG_LIN might not be defined. */
@@ -616,3 +586,22 @@ int para_atoi32(const char *str, int32_t *value)
        *value = tmp;
        return 1;
 }
+
+int get_loglevel_by_name(const char *txt)
+{
+       if (!strcasecmp(txt, "debug"))
+               return LL_DEBUG;
+       if (!strcasecmp(txt, "info"))
+               return LL_INFO;
+       if (!strcasecmp(txt, "notice"))
+               return LL_NOTICE;
+       if (!strcasecmp(txt, "warning"))
+               return LL_WARNING;
+       if (!strcasecmp(txt, "error"))
+               return LL_ERROR;
+       if (!strcasecmp(txt, "crit"))
+               return LL_CRIT;
+       if (!strcasecmp(txt, "emerg"))
+               return LL_EMERG;
+       return -1;
+}