diff options
Diffstat (limited to 'src/lib/core')
-rw-r--r-- | src/lib/core/conda.c | 99 | ||||
-rw-r--r-- | src/lib/core/include/conda.h | 2 | ||||
-rw-r--r-- | src/lib/core/include/utils.h | 37 | ||||
-rw-r--r-- | src/lib/core/template.c | 17 | ||||
-rw-r--r-- | src/lib/core/utils.c | 31 |
5 files changed, 133 insertions, 53 deletions
diff --git a/src/lib/core/conda.c b/src/lib/core/conda.c index 44af34d..268b433 100644 --- a/src/lib/core/conda.c +++ b/src/lib/core/conda.c @@ -4,7 +4,7 @@ #include "conda.h" -int micromamba(struct MicromambaInfo *info, char *command, ...) { +int micromamba(const struct MicromambaInfo *info, char *command, ...) { struct utsname sys; uname(&sys); @@ -24,7 +24,12 @@ int micromamba(struct MicromambaInfo *info, char *command, ...) { sprintf(installer_path, "%s/latest", getenv("TMPDIR") ? getenv("TMPDIR") : "/tmp"); if (access(installer_path, F_OK)) { - download(url, installer_path, NULL); + char *errmsg = NULL; + const long http_code = download(url, installer_path, &errmsg); + if (HTTP_ERROR(http_code)) { + fprintf(stderr, "download failed: %ld: %s\n", http_code, errmsg); + return -1; + } } char mmbin[PATH_MAX]; @@ -62,37 +67,38 @@ int micromamba(struct MicromambaInfo *info, char *command, ...) { } int python_exec(const char *args) { - int result = -1; const char *command_base = "python "; - const size_t required_len = strlen(command_base) + strlen(args) + 1; + const char *command_fmt = "%s%s"; - char *command = calloc(required_len, sizeof(*command)); + const int len = snprintf(NULL, 0, command_fmt, command_base, args); + char *command = calloc(len + 1, sizeof(*command)); if (!command) { - SYSERROR("Unable to allocate %zu bytes for command string", required_len); - return result; + SYSERROR("Unable to allocate %d bytes for command string", len); + return -1; } - snprintf(command, required_len, "%s%s", command_base, args); + + snprintf(command, len + 1, command_fmt, command_base, args); msg(STASIS_MSG_L3, "Executing: %s\n", command); - result = system(command); + const int result = system(command); guard_free(command); return result; } int pip_exec(const char *args) { - int result = -1; const char *command_base = "python -m pip "; - const size_t required_len = strlen(command_base) + strlen(args) + 1; + const char *command_fmt = "%s%s"; - char *command = calloc(required_len, sizeof(*command)); + const int len = snprintf(NULL, 0, command_fmt, command_base, args); + char *command = calloc(len + 1, sizeof(*command)); if (!command) { - SYSERROR("Unable to allocate %zu bytes for command string", required_len); - return result; + SYSERROR("Unable to allocate %d bytes for command string", len); + return -1; } - snprintf(command, required_len, "%s%s", command_base, args); + snprintf(command, len + 1, command_fmt, command_base, args); msg(STASIS_MSG_L3, "Executing: %s\n", command); - result = system(command); + const int result = system(command); guard_free(command); return result; } @@ -199,7 +205,6 @@ int pkg_index_provides(int mode, const char *index, const char *spec) { } int conda_exec(const char *args) { - char command[PATH_MAX]; const char *mamba_commands[] = { "build", "install", @@ -224,15 +229,24 @@ int conda_exec(const char *args) { } } - snprintf(command, sizeof(command) - 1, "%s %s", conda_as, args); + const char *command_fmt = "%s %s"; + const int len = snprintf(NULL, 0, command_fmt, conda_as, args); + char *command = calloc(len + 1, sizeof(*command)); + if (!command) { + return -1; + } + + snprintf(command, len + 1, command_fmt, conda_as, args); msg(STASIS_MSG_L3, "Executing: %s\n", command); - return system(command); + const int result = system(command); + guard_free(command); + return result; } static int conda_prepend_bin(const char *root) { char conda_bin[PATH_MAX] = {0}; - snprintf(conda_bin, sizeof(conda_bin) - 1, "%s/bin", root); + snprintf(conda_bin, sizeof(conda_bin), "%s/bin", root); if (env_manipulate_pathstr("PATH", conda_bin, PM_PREPEND | PM_ONCE)) { return -1; } @@ -242,7 +256,7 @@ static int conda_prepend_bin(const char *root) { static int conda_prepend_condabin(const char *root) { char conda_condabin[PATH_MAX] = {0}; - snprintf(conda_condabin, sizeof(conda_condabin) - 1, "%s/condabin", root); + snprintf(conda_condabin, sizeof(conda_condabin), "%s/condabin", root); if (env_manipulate_pathstr("PATH", conda_condabin, PM_PREPEND | PM_ONCE)) { return -1; } @@ -351,7 +365,7 @@ int conda_activate(const char *root, const char *env_name) { return -1; } - snprintf(command, sizeof(command) - 1, + snprintf(command, sizeof(command), "set -a\n" "source %s\n" "__conda_exe() (\n" @@ -521,10 +535,8 @@ int conda_setup_headless() { } int conda_env_create_from_uri(char *name, char *uri, char *python_version) { - char env_command[PATH_MAX]; char *uri_fs = NULL; - // Convert a bare system path to a file:// path if (!strstr(uri, "://")) { uri_fs = calloc(strlen(uri) + strlen("file://") + 1, sizeof(*uri_fs)); @@ -545,25 +557,50 @@ int conda_env_create_from_uri(char *name, char *uri, char *python_version) { // We'll create a new file with the same random bits, ending with .yml strcat(tempfile, ".yml"); char *errmsg = NULL; - download(uri_fs ? uri_fs : uri, tempfile, &errmsg); + const long http_code = download(uri_fs ? uri_fs : uri, tempfile, &errmsg); + if (HTTP_ERROR(http_code)) { + if (errmsg) { + fprintf(stderr, "download failed: %ld: %s\n", http_code, errmsg); + guard_free(errmsg); + } + guard_free(uri_fs); + return -1; + } guard_free(uri_fs); // Rewrite python version char spec[255] = {0}; - snprintf(spec, sizeof(spec) - 1, "- python=%s\n", python_version); + snprintf(spec, sizeof(spec), "- python=%s\n", python_version); file_replace_text(tempfile, "- python\n", spec, 0); - sprintf(env_command, "env create -n '%s' --file='%s'", name, tempfile); - int status = conda_exec(env_command); + const char *fmt = "env create -n '%s' --file='%s'"; + int len = snprintf(NULL, 0, fmt, name, tempfile); + char *env_command = calloc(len + 1, sizeof(*env_command)); + if (!env_command) { + return -1; + } + + snprintf(env_command, len + 1, fmt, name, tempfile); + const int status = conda_exec(env_command); unlink(tempfile); + guard_free(env_command); return status; } int conda_env_create(char *name, char *python_version, char *packages) { - char env_command[PATH_MAX]; - sprintf(env_command, "create -n %s python=%s %s", name, python_version, packages ? packages : ""); - return conda_exec(env_command); + const char *fmt = "create -n %s python=%s %s"; + const int len = snprintf(NULL, 0, fmt, name, python_version, packages ? packages : ""); + char *env_command = calloc(len + 1, sizeof(*env_command)); + if (!env_command) { + return -1; + } + + snprintf(env_command, len + 1, fmt, name, python_version, packages ? packages : ""); + const int result = conda_exec(env_command); + guard_free(env_command); + + return result; } int conda_env_remove(char *name) { diff --git a/src/lib/core/include/conda.h b/src/lib/core/include/conda.h index ea8613f..f3d481c 100644 --- a/src/lib/core/include/conda.h +++ b/src/lib/core/include/conda.h @@ -38,7 +38,7 @@ struct MicromambaInfo { * @param ... variadic arguments * @return exit code */ -int micromamba(struct MicromambaInfo *info, char *command, ...); +int micromamba(const struct MicromambaInfo *info, char *command, ...); /** * Execute Python diff --git a/src/lib/core/include/utils.h b/src/lib/core/include/utils.h index b405b2a..583a8b8 100644 --- a/src/lib/core/include/utils.h +++ b/src/lib/core/include/utils.h @@ -419,4 +419,41 @@ int gen_file_extension_str(char *filename, const char *extension); char *remove_extras(char *s); void debug_hexdump(char *data, int len); + +/** + * Realloc helper + * + * @code{.c} + * #include <stdio.h> + * #include <stdlib.h> + * #include <string.h> + * #include "utils.h" + * + * int main(int argc, char *argv[]) { + * size_t sz = 10; + * char *data = calloc(sz, sizeof(*data)); + * + * // populate data + * strncat(data, "/path/to/", sz - 1); + * + * // Double the allocation size for data + * if (grow(sz * 2, &sz, &data)) { + * // memory error + * } + * + * // sz is now 20 + * strncat(data, "filename", sz - 1 - strlen(data)); + * + * puts(data); + * // output: "/path/to/filename" + * } + * @endcode + * + * @param size_new increase by `size_new` bytes + * @param size_orig address of variable containing the original allocation size (modified) + * @param data address to write data + * @return 0 on success + * @return -1 on error + */ +int grow(size_t size_new, size_t *size_orig, char **data); #endif //STASIS_UTILS_H diff --git a/src/lib/core/template.c b/src/lib/core/template.c index ba45a5a..68d20c9 100644 --- a/src/lib/core/template.c +++ b/src/lib/core/template.c @@ -137,23 +137,6 @@ struct tplfunc_frame *tpl_getfunc(char *key) { return result; } -static int grow(size_t z, size_t *output_bytes, char **output) { - if (z >= *output_bytes) { - size_t new_size = *output_bytes + z + 1; - SYSDEBUG("template output buffer new size: %zu\n", new_size); - - char *tmp = realloc(*output, new_size); - if (!tmp) { - perror("realloc failed"); - return -1; - } else if (tmp != *output) { - *output = tmp; - } - *output_bytes = new_size; - } - return 0; -} - char *tpl_render(char *str) { if (!str) { return NULL; diff --git a/src/lib/core/utils.c b/src/lib/core/utils.c index a9c9ea5..f02a7ea 100644 --- a/src/lib/core/utils.c +++ b/src/lib/core/utils.c @@ -892,10 +892,11 @@ int gen_file_extension_str(char *filename, const char *extension) { return replace_text(ext_orig, ext_orig, extension, 0); } +#define DEBUG_HEXDUMP_FMT_BYTES 6 #define DEBUG_HEXDUMP_ADDR_MAXLEN 20 #define DEBUG_HEXDUMP_BYTES_MAXLEN (16 * 3 + 2) #define DEBUG_HEXDUMP_ASCII_MAXLEN (16 + 1) -#define DEBUG_HEXDUMP_OUTPUT_MAXLEN (DEBUG_HEXDUMP_ADDR_MAXLEN + DEBUG_HEXDUMP_BYTES_MAXLEN + DEBUG_HEXDUMP_ASCII_MAXLEN + 1) +#define DEBUG_HEXDUMP_OUTPUT_MAXLEN (DEBUG_HEXDUMP_FMT_BYTES + DEBUG_HEXDUMP_ADDR_MAXLEN + DEBUG_HEXDUMP_BYTES_MAXLEN + DEBUG_HEXDUMP_ASCII_MAXLEN + 1) void debug_hexdump(char *data, int len) { int count = 0; @@ -936,10 +937,32 @@ void debug_hexdump(char *data, int len) { // Add group padding strcat(bytes, " "); } - int padding = 16 - count; + const int padding = 16 - count; for (int i = 0; i < padding; i++) { strcat(bytes, " "); } - sprintf(output, "%s | %s | %s", addr, bytes, ascii); + snprintf(output, DEBUG_HEXDUMP_FMT_BYTES + sizeof(addr) + sizeof(bytes) + sizeof(ascii), "%s | %s | %s", addr, bytes, ascii); puts(output); -}
\ No newline at end of file +} + +int grow(const size_t size_new, size_t *size_orig, char **data) { + if (!*data) { + return 0; + } + if (size_new >= *size_orig) { + const size_t new_size = *size_orig + size_new + 1; + SYSDEBUG("template data buffer new size: %zu\n", new_size); + + char *tmp = realloc(*data, new_size); + if (!tmp) { + perror("realloc failed"); + return -1; + } + if (tmp != *data) { + *data = tmp; + } + *size_orig = new_size; + } + return 0; +} + |