X-Git-Url: http://mj.ucw.cz/gitweb/?a=blobdiff_plain;f=submit%2Ftasks.c;h=1ca515a86588e1711be1ab97506417992c5036ae;hb=93993ba75adfb5e4a9a7639e157026cc4fbb07b3;hp=4a6930319799983dae873420da09c8ed5d879174;hpb=92811b1aa5a791bc776b58afb241a7d93e737604;p=eval.git diff --git a/submit/tasks.c b/submit/tasks.c index 4a69303..1ca515a 100644 --- a/submit/tasks.c +++ b/submit/tasks.c @@ -8,20 +8,40 @@ #include "lib/conf.h" #include "lib/fastbuf.h" #include "lib/stkstring.h" +#include "lib/simple-lists.h" +#include "lib/mempool.h" #include "sherlock/object.h" #include #include #include +#include #include "submitd.h" clist task_list; +static clist extensions; +static clist open_data_extensions; static byte * -tasks_conf_init(void) +tasks_conf_commit(void *p UNUSED) { - clist_init(&task_list); + // We do not do any journaling here as we do not switch config files on the fly + CLIST_FOR_EACH(struct task *, t, task_list) + { + clist_init(&t->parts); + if (t->open_data) + { + for (uns i=1; i<=t->open_data; i++) + simp_append(cf_pool, &t->parts)->s = mp_printf(cf_pool, "%d", i); + t->extensions = &open_data_extensions; + } + else + { + simp_append(cf_pool, &t->parts)->s = t->name; + t->extensions = &extensions; + } + } return NULL; } @@ -29,14 +49,17 @@ static struct cf_section task_conf = { CF_TYPE(struct task), CF_ITEMS { CF_STRING("Name", PTR_TO(struct task, name)), + CF_UNS("OpenData", PTR_TO(struct task, open_data)), CF_END } }; struct cf_section tasks_conf = { - CF_INIT(tasks_conf_init), + CF_COMMIT(tasks_conf_commit), CF_ITEMS { CF_LIST("Task", &task_list, &task_conf), + CF_LIST("Extension", &extensions, &cf_string_list_config), + CF_LIST("OpenDataExt", &open_data_extensions, &cf_string_list_config), CF_END } }; @@ -50,12 +73,42 @@ task_find(byte *name) return NULL; } +int +part_exists_p(struct task *t, byte *name) +{ + CLIST_FOR_EACH(simp_node *, p, t->parts) + if (!strcmp(p->s, name)) + return 1; + return 0; +} + +int +ext_exists_p(struct task *t, byte *ext) +{ + CLIST_FOR_EACH(simp_node *, x, *t->extensions) + if (!strcmp(x->s, ext)) + return 1; + return 0; +} + int user_exists_p(byte *user) { - byte *fn = stk_printf("solutions/%s/status", user); + byte *fn = stk_printf("solutions/%s", user); struct stat st; - return !stat(fn, &st) && S_ISREG(st.st_mode); + return !stat(fn, &st) && S_ISDIR(st.st_mode); +} + +void +task_load_status(struct conn *c) +{ + struct fastbuf *fb = bopen_try(stk_printf("solutions/%s/status", c->user), O_RDONLY, 4096); + c->task_status = obj_new(c->pool); + if (fb) + { + obj_read(fb, c->task_status); + bclose(fb); + } } void @@ -72,21 +125,13 @@ task_lock_status(struct conn *c) }; if (fcntl(c->task_lock_fd, F_SETLKW, &fl) < 0) die("Cannot lock status file: %m"); - - struct fastbuf *fb = bopen_try(stk_printf("solutions/%s/status", c->user), O_RDONLY, 4096); - c->task_status = obj_new(c->pool); - if (fb) - { - obj_read(fb, c->task_status); - bclose(fb); - } + task_load_status(c); } void task_unlock_status(struct conn *c, uns write_back) { ASSERT(c->task_lock_fd); - ASSERT(c->task_status); if (write_back) { @@ -109,27 +154,62 @@ task_unlock_status(struct conn *c, uns write_back) if (fcntl(c->task_lock_fd, F_SETLKW, &fl) < 0) die("Cannot unlock status file: %m"); c->task_lock_fd = 0; - c->task_status = NULL; } struct odes * -task_status_find_task(struct conn *c, struct task *t) +task_status_find_task(struct conn *c, struct task *t, uns create) { for (struct oattr *a = obj_find_attr(c->task_status, 'T' + OBJ_ATTR_SON); a; a=a->same) { struct odes *o = a->son; byte *name = obj_find_aval(o, 'T'); + ASSERT(name); if (!strcmp(name, t->name)) return o; } + if (!create) + return NULL; struct odes *o = obj_add_son(c->task_status, 'T' + OBJ_ATTR_SON); obj_set_attr(o, 'T', t->name); return o; } -void -task_submit(struct conn *c, struct task *t, struct fastbuf *fb, byte *filename) +struct odes * +task_status_find_part(struct odes *to, byte *part, uns create) +{ + for (struct oattr *a = obj_find_attr(to, 'P' + OBJ_ATTR_SON); a; a=a->same) + { + struct odes *o = a->son; + byte *name = obj_find_aval(o, 'P'); + ASSERT(name); + if (!strcmp(name, part)) + return o; + } + if (!create) + return NULL; + struct odes *o = obj_add_son(to, 'P' + OBJ_ATTR_SON); + obj_set_attr(o, 'P', part); + return o; +} + +void task_submit_part(byte *user, byte *task, byte *part, byte *ext, uns version UNUSED, struct fastbuf *fb) +{ + byte *dir = stk_printf("solutions/%s/%s", user, task); + byte *name = stk_printf("%s/%s.%s", dir, part, ext); + + struct stat st; + if (stat(dir, &st) < 0 && errno == ENOENT && mkdir(dir, 0777) < 0) + die("Cannot create %s: %m", dir); + + bconfig(fb, BCONFIG_IS_TEMP_FILE, 0); + if (rename(fb->name, name) < 0) + die("Cannot rename %s to %s: %m", fb->name, name); +} + +void task_delete_part(byte *user, byte *task, byte *part, byte *ext, uns version UNUSED) { - byte *dir = stk_printf("solutions/%s/%s", c->user, t->name); - byte *name = stk_printf("%s/%s", dir, filename); + byte *dir = stk_printf("solutions/%s/%s", user, task); + byte *name = stk_printf("%s/%s.%s", dir, part, ext); + if (unlink(name) < 0) + log(L_ERROR, "Cannot delete %s: %m", name); }