]> mj.ucw.cz Git - moe.git/blobdiff - submit/commands.c
The reporting script now understands grouping.
[moe.git] / submit / commands.c
index 9542a19983012ef103347242e3f1aec3ba2dc01e..1e576055f72bf31a1a36d5e11ef9bc19164f9b69 100644 (file)
@@ -8,9 +8,11 @@
 #include "lib/mempool.h"
 #include "lib/simple-lists.h"
 #include "lib/stkstring.h"
+#include "lib/fastbuf.h"
 #include "sherlock/object.h"
 #include "sherlock/objread.h"
 
+#include <fcntl.h>
 #include <time.h>
 
 #include "submitd.h"
@@ -128,13 +130,50 @@ cmd_status(struct conn *c)
     }
 }
 
+/*** Contest timeout checks ***/
+
+static int
+load_time_limit(char *name)
+{
+  struct fastbuf *f = bopen_try(name, O_RDONLY, 1024);
+  if (!f)
+    return -1;
+  char buf[256];
+  int h, m;
+  if (bgets_nodie(f, buf, sizeof(buf)) < 0 ||
+      sscanf(buf, "%d:%d", &h, &m) != 2 ||
+      h < 0 || h > 23 || m < 0 || m > 59)
+    {
+      msg(L_ERROR, "Invalid timeout in %s", name);
+      bclose(f);
+      return -1;
+    }
+  bclose(f);
+  return 100*h + m;
+}
+
+static int
+contest_over(struct conn *c)
+{
+  time_t now = time(NULL);
+  struct tm *tm = localtime(&now);
+  int tstamp = tm->tm_hour*100 + tm->tm_min;
+  int local_limit = load_time_limit(stk_printf("solutions/%s/TIMEOUT", c->user));
+  int global_limit = load_time_limit("solutions/TIMEOUT");
+  if (trace_commands > 1)
+    msg(L_DEBUG, "Time check: current %d, global limit %d, user limit %d", tstamp, global_limit, local_limit);
+  if (local_limit >= 0)
+    return (tstamp >= local_limit);
+  return (global_limit >= 0 && tstamp >= global_limit);
+}
+
 /*** SUBMIT ***/
 
 static struct fastbuf *
-read_attachment(struct conn *c)
+read_attachment(struct conn *c, uns max_size)
 {
   uns size = obj_find_anum(c->request, 'S', 0);
-  if (size > max_attachment_size)
+  if (size > max_size)
     {
       err(c, "Submission too large");
       return NULL;
@@ -165,6 +204,12 @@ read_attachment(struct conn *c)
 static void
 cmd_submit(struct conn *c)
 {
+  if (contest_over(c))
+    {
+      err(c, "The contest is over, no more submits allowed");
+      return;
+    }
+
   byte *tname = obj_find_aval(c->request, 'T');
   if (!tname)
     {
@@ -198,7 +243,8 @@ cmd_submit(struct conn *c)
       return;
     }
 
-  struct fastbuf *fb = read_attachment(c);
+  uns max_size = task->max_size ? : max_attachment_size;
+  struct fastbuf *fb = read_attachment(c, max_size);
   if (!fb)
     return;
 
@@ -206,6 +252,13 @@ cmd_submit(struct conn *c)
   struct odes *tasko = task_status_find_task(c, task, 1);
   struct odes *parto = task_status_find_part(tasko, pname, 1);
   uns current_ver = obj_find_anum(parto, 'V', 0);
+  if (current_ver >= max_versions)
+    {
+      err(c, "Maximum number of submits of this task exceeded");
+      bclose(fb);
+      task_unlock_status(c, 0);
+      return;
+    }
   uns last_ver = 0;
   uns replaced_ver = 0;
   for (struct oattr *a = obj_find_attr(parto, 'V' + OBJ_ATTR_SON); a; a=a->same)
@@ -255,6 +308,8 @@ execute_command(struct conn *c)
     cmd_submit(c);
   else if (!strcasecmp(cmd, "STATUS"))
     cmd_status(c);
+  else if (!strcasecmp(cmd, "NOP"))
+    ;
   else
     err(c, "Unknown command");
 }