]> mj.ucw.cz Git - eval.git/blobdiff - submit/tasks.c
Some more GTK experiments.
[eval.git] / submit / tasks.c
index 4a6930319799983dae873420da09c8ed5d879174..1ca515a86588e1711be1ab97506417992c5036ae 100644 (file)
@@ -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 <sys/stat.h>
 #include <fcntl.h>
 #include <unistd.h>
+#include <errno.h>
 
 #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);
 }