diff --git a/src/bstr.c b/src/bstr.c new file mode 100644 index 0000000..30a70eb --- /dev/null +++ b/src/bstr.c @@ -0,0 +1,37 @@ +#include +#include +#include +#include + +#include "bstr.h" + +char * +bstr_print(char *base, const char *fmt, ...) +{ + char *new_buf; + size_t new_len; + va_list ap; + + va_start(ap, fmt); + new_len = vsnprintf(NULL, 0, fmt, ap); + va_end(ap); + + new_buf = calloc(1, new_len + 1); + + va_start(ap, fmt); + vsprintf(new_buf, fmt, ap); + va_end(ap); + + if (!base) { + return new_buf; + } else { + size_t baselen = strlen(base); + + base = realloc(base, baselen + new_len + 1); + memcpy(&base[baselen], new_buf, new_len); + base[baselen + new_len] = '\0'; + + free(new_buf); + return base; + } +} diff --git a/src/bstr.h b/src/bstr.h new file mode 100644 index 0000000..c442da3 --- /dev/null +++ b/src/bstr.h @@ -0,0 +1,12 @@ +#ifndef _BSTR_H_ +#define _BSTR_H_ + +#include +#include + +/* printf onto the end of base, reallocating and returning that buffer + * can provide NULL for no base */ +__attribute__((format(printf, 2, 3))) +char *bstr_print(char *base, const char *fmt, ...); + +#endif /* _BSTR_H_ */ diff --git a/src/paths.c b/src/paths.c new file mode 100644 index 0000000..7c4de57 --- /dev/null +++ b/src/paths.c @@ -0,0 +1,99 @@ +#include +#include +#include +#include + +#include "bstr.h" +#include "paths.h" + +#if __MINGW32__ +# define BSTR_LLD "%I64d" +#else +# define BSTR_LLD "%lld" +#endif + +char * +paths_append(char *base, const char *suffix) +{ + size_t baselen; + const char *sep = ""; + + if (!base) + return strdup(suffix); + + baselen = strlen(base); + + if ( + (baselen == 0) || + ((base[baselen-1] != '/') && (base[baselen-1] == '\\')) + ) { + /* no separator at end of path */ +#if __MINGW32__ + sep = "\\"; +#else + sep = "/"; +#endif + } + + return bstr_print(base, "%s%s", sep, suffix); +} + +char * +paths_bnconf_dir() +{ +#ifdef __MINGW32__ + char *home = getenv("HOMEPATH"); +#else + char *home = getenv("HOME"); +#endif + char *ret = NULL; + + if (!home) + return NULL; + +#ifdef __MINGW32__ + ret = strdup("C:\\"); +#endif + ret = paths_append(ret, home); + ret = paths_append(ret, ".config/bytenuts"); + + /* TODO free environment variable on Windows? */ + return ret; +} + +char * +paths_bnconf_default() +{ + char *ret = paths_bnconf_dir(); + + if (!ret) + return NULL; + + return paths_append(ret, "config"); +} + +char * +paths_command_file(int idx) +{ + char *ret = paths_bnconf_dir(); + + if (!ret) + return NULL; + + return bstr_print(ret, "/commands%d", idx); +} + +char * +paths_logfile(const char *prefix, long long pid) +{ + char *ret = paths_bnconf_dir(); + + if (!ret) + return NULL; + + if (pid > 0) { + return bstr_print(ret, "/%s." BSTR_LLD ".log", prefix, pid); + } else { + return bstr_print(ret, "/%s.log", prefix); + } +} diff --git a/src/paths.h b/src/paths.h new file mode 100644 index 0000000..179fafe --- /dev/null +++ b/src/paths.h @@ -0,0 +1,20 @@ +#ifndef _PATHS_H_ +#define _PATHS_H_ + +/* Realloc the base path and add the suffix to it, "/"s handled nicely */ +char *paths_append(char *base, const char *suffix); + +/* Get the ~/.config/bytenuts directory */ +char *paths_bnconf_dir(); + +/* Get the default bytenuts config filepath */ +char *paths_bnconf_default(); + +/* Generate the path to the command file */ +char *paths_command_file(int idx); + +/* Generate a logfile path of the form ~/.config/bytenuts/[.].log + * PID only inserted if >0 */ +char *paths_logfile(const char *prefix, long long pid); + +#endif /* _PATHS_H_ */