}
/**
- * Get the home directory of the current user.
+ * Return the expansion of $HOME/.paraslash.
*
- * \return A dynamically allocated string that must be freed by the caller. If
- * the home directory could not be found, this function returns "/tmp".
+ * If the environment variable HOME is unset or empty, the function prints an
+ * error message and aborts. Otherwise, on the first call the memory for the
+ * string is allocated and a pointer to this memory location is returned.
+ * Subsequent calls return a pointer to the memory that was allocated during
+ * the first call.
+ *
+ * \return A pointer to a C string, allocated on the heap. Callers should make
+ * sure that free() is only called once.
+ *
+ * \sa getenv(3), getuid(2).
*/
-__must_check __malloc char *para_homedir(void)
+__malloc char *get_confdir(void)
{
- struct passwd *pw = getpwuid(getuid());
- return para_strdup(pw? pw->pw_dir : "/tmp");
+ static char *dot_para;
+ const char *home;
+
+ if (dot_para)
+ return dot_para;
+ home = getenv("HOME");
+ if (!home || !*home) {
+ PARA_EMERG_LOG("fatal: HOME is unset or empty");
+ exit(EXIT_FAILURE);
+ }
+ dot_para = make_message("%s/.paraslash", home);
+ return dot_para;
}
/**
return 1;
}
-static inline int loglevel_equal(const char *arg, const char * const ll)
-{
- return !strncasecmp(arg, ll, strlen(ll));
-}
-
-/**
- * Compute the loglevel number from its name.
- *
- * \param txt The name of the loglevel (debug, info, ...).
- *
- * \return The numeric representation of the loglevel name.
- */
-int get_loglevel_by_name(const char *txt)
-{
- if (loglevel_equal(txt, "debug"))
- return LL_DEBUG;
- if (loglevel_equal(txt, "info"))
- return LL_INFO;
- if (loglevel_equal(txt, "notice"))
- return LL_NOTICE;
- if (loglevel_equal(txt, "warning"))
- return LL_WARNING;
- if (loglevel_equal(txt, "error"))
- return LL_ERROR;
- if (loglevel_equal(txt, "crit"))
- return LL_CRIT;
- if (loglevel_equal(txt, "emerg"))
- return LL_EMERG;
- return -E_BAD_LL;
-}
-
static int get_next_word(const char *buf, const char *delim, char **word)
{
enum line_state_flags {LSF_HAVE_WORD = 1, LSF_BACKSLASH = 2,
static int create_argv_offset(int offset, const char *buf, const char *delim,
char ***result)
{
- char *word, **argv = arr_alloc(offset + 1, sizeof(char *));
+ char *word, **argv = arr_zalloc(offset + 1, sizeof(char *));
const char *p;
int i, ret;
- for (i = 0; i < offset; i++)
- argv[i] = NULL;
- for (p = buf; p && *p; p += ret, i++) {
+ for (p = buf, i = offset; p && *p; p += ret, i++) {
ret = get_next_word(p, delim, &word);
if (ret < 0)
goto err;
return create_argv_offset(1, buf, delim, result);
}
-/**
- * Find out if the given string is contained in the arg vector.
- *
- * \param arg The string to look for.
- * \param argv The array to search.
- *
- * \return The first index whose value equals \a arg, or \p -E_ARG_NOT_FOUND if
- * arg was not found in \a argv.
- */
-int find_arg(const char *arg, char **argv)
-{
- int i;
-
- if (!argv)
- return -E_ARG_NOT_FOUND;
- for (i = 0; argv[i]; i++)
- if (strcmp(arg, argv[i]) == 0)
- return i;
- return -E_ARG_NOT_FOUND;
-}
-
/**
* Compile a regular expression.
*