diff options
Diffstat (limited to 'src/jobs.c')
-rw-r--r-- | src/jobs.c | 178 |
1 files changed, 178 insertions, 0 deletions
diff --git a/src/jobs.c b/src/jobs.c new file mode 100644 index 0000000..7893632 --- /dev/null +++ b/src/jobs.c @@ -0,0 +1,178 @@ +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <cjson/cJSON.h> + +#include "jobs.h" +#include "util.h" + +static int job_output_insert(struct job *j, char *name, char *store_path); + +int job_read(FILE *stream, struct job **job) +{ + int ret; + cJSON *root, *temp, *input_drvs, *array; + struct job *dep_job; + char *name = NULL; + char *out_name = NULL; + char *drv_path = NULL; + + ret = json_streaming_read(stream, &root); + if (ret < 0) + return ret; + + temp = cJSON_GetObjectItemCaseSensitive(root, "name"); + if (!cJSON_IsString(temp)) { + ret = -EPERM; + goto out_free; + } + name = strdup(temp->valuestring); + if (name == NULL) { + ret = -EPERM; + goto out_free; + } + + temp = cJSON_GetObjectItemCaseSensitive(root, "drvPath"); + if (!cJSON_IsString(temp)) { + ret = -EPERM; + goto out_free; + } + drv_path = strdup(temp->valuestring); + if (drv_path == NULL) { + ret = -EPERM; + goto out_free; + } + + ret = job_new(job, name, drv_path); + if (ret < 0) + goto out_free; + + input_drvs = cJSON_GetObjectItemCaseSensitive(root, "inputDrvs"); + for (temp = input_drvs; temp != NULL; temp = temp->next) { + array = cJSON_GetObjectItemCaseSensitive(temp, temp->string); + if (!cJSON_IsArray(array)) { + ret = -EPERM; + job_free(*job); + goto out_free; + } + + drv_path = strdup(temp->string); + if (drv_path == NULL) { + ret = -EPERM; + job_free(*job); + goto out_free; + } + + ret = job_new(&dep_job, NULL, drv_path); + if (ret < 0) { + ret = -EPERM; + job_free(*job); + goto out_free; + } + + for (; array != NULL; array = array->next) { + out_name = strdup(array->string); + ret = job_output_insert(dep_job, out_name, NULL); + if (ret < 0) { + job_free(*job); + job_free(dep_job); + goto out_free; + } + } + + LIST_INSERT_HEAD(&(*job)->deps, dep_job, dlist); + drv_path = NULL; + } + +out_free: + cJSON_Delete(root); + + if (ret < 0) { + print_err("%s", "Invalid JSON"); + free(name); + free(drv_path); + } + return ret; +} + +void output_free(struct output *output) +{ + if (output == NULL) + return; + + free(output->name); + free(output->store_path); + + free(output); +} + +void job_free(struct job *job) +{ + struct job *j; + struct output *o; + + if (job == NULL) + return; + + free(job->name); + free(job->drv_path); + free(job); + LIST_FOREACH (o, &job->outputs, dlist) + output_free(o); + + LIST_FOREACH (j, &job->deps, dlist) + job_free(j); +} + +static int job_output_insert(struct job *j, char *name, char *store_path) +{ + struct output *o; + + o = malloc(sizeof(*o)); + if (o == NULL) { + print_err("%s", strerror(errno)); + return -errno; + } + + o->name = name; + o->store_path = store_path; + LIST_INSERT_HEAD(&j->outputs, o, dlist); + + return 0; +} + +int job_new(struct job **j, char *name, char *drv_path) +{ + struct job *job; + + job = malloc(sizeof(*job)); + if (*j == NULL) { + print_err("%s", strerror(errno)); + return -errno; + } + + job->name = name; + job->drv_path = drv_path; + LIST_INIT(&job->deps); + LIST_INIT(&job->outputs); + + *j = job; + return 0; +} + +int jobs_init(FILE **stream) +{ + int ret; + + /* TODO: proproperly handle args */ + char *const args[] = { + "--flake", + "github:sinanmohd/evanix#packages.x86_64-linux.evanix", + }; + + /* the package is wrapProgram-ed with nix-eval-jobs */ + ret = vpopen(stream, "nix-eval-jobs", args); + return ret; +} |