+/*
+ * Copyright (C) 2004-2008 Andre Noll <maan@systemlinux.org>
+ *
+ * Licensed under the GPL v2. For licencing details see COPYING.
+ */
#include <string.h>
#include <stdlib.h>
+#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <limits.h>
#include <unistd.h>
-#include "cmdline.h"
#include "gcc-compat.h"
#include "log.h"
#include "error.h"
#include "string.h"
-__noreturn void clean_exit(int status);
-
/**
* Write a message to a dynamically allocated string.
*
if (!(p = realloc(p, size))) {
DSS_EMERG_LOG("realloc failed (size = %zu), aborting\n",
size);
- clean_exit(EXIT_FAILURE);
+ exit(EXIT_FAILURE);
}
return p;
}
if (!p) {
DSS_EMERG_LOG("malloc failed (size = %zu), aborting\n",
size);
- clean_exit(EXIT_FAILURE);
+ exit(EXIT_FAILURE);
}
return p;
}
if ((ret = strdup(s? s: "")))
return ret;
DSS_EMERG_LOG("strdup failed, aborting\n");
- clean_exit(EXIT_FAILURE);
+ exit(EXIT_FAILURE);
}
/**
return msg;
}
-__printf_1_2 void make_err_msg(const char* fmt,...)
-{
- free(dss_error_txt);
- VSPRINTF(fmt, dss_error_txt);
-}
-
/**
* Get the home directory of the current user.
*
errno = 0; /* To distinguish success/failure after call */
tmp = strtoll(str, &endptr, 10);
- if (errno == ERANGE && (tmp == LLONG_MAX || tmp == LLONG_MIN)) {
- make_err_msg("%s", str);
+ if (errno == ERANGE && (tmp == LLONG_MAX || tmp == LLONG_MIN))
return -E_ATOI_OVERFLOW;
- }
- if (errno != 0 && tmp == 0) { /* other error */
- make_err_msg("%s", str);
+ if (errno != 0 && tmp == 0) /* other error */
return -E_STRTOLL;
- }
- if (endptr == str) {
- make_err_msg("%s", str);
+ if (endptr == str)
return -E_ATOI_NO_DIGITS;
- }
- if (*endptr != '\0') { /* Further characters after number */
- make_err_msg("%s", str);
+ if (*endptr != '\0') /* Further characters after number */
return -E_ATOI_JUNK_AT_END;
- }
*value = tmp;
return 1;
}
return dss_strdup(pw? pw->pw_name : "unknown_user");
}
+/**
+ * Split string and return pointers to its parts.
+ *
+ * \param args The string to be split.
+ * \param argv_ptr Pointer to the list of substrings.
+ * \param delim Delimiter.
+ *
+ * This function modifies \a args by replacing each occurance of \a delim by
+ * zero. A \p NULL-terminated array of pointers to char* is allocated dynamically
+ * and these pointers are initialized to point to the broken-up substrings
+ * within \a args. A pointer to this array is returned via \a argv_ptr.
+ *
+ * \return The number of substrings found in \a args.
+ */
+__must_check unsigned split_args(char *args, char *** const argv_ptr, const char *delim)
+{
+ char *p = args;
+ char **argv;
+ size_t n = 0, i, j;
+
+ p = args + strspn(args, delim);
+ for (;;) {
+ i = strcspn(p, delim);
+ if (!i)
+ break;
+ p += i;
+ n++;
+ p += strspn(p, delim);
+ }
+ *argv_ptr = dss_malloc((n + 1) * sizeof(char *));
+ argv = *argv_ptr;
+ i = 0;
+ p = args + strspn(args, delim);
+ while (p) {
+ argv[i] = p;
+ j = strcspn(p, delim);
+ if (!j)
+ break;
+ p += strcspn(p, delim);
+ if (*p) {
+ *p = '\0';
+ p++;
+ p += strspn(p, delim);
+ }
+ i++;
+ }
+ argv[n] = NULL;
+ return n;
+}