X-Git-Url: http://mj.ucw.cz/gitweb/?a=blobdiff_plain;f=submit%2Fcommands.c;h=98adf37f3e8a21f63653b3c6200e6c3e9a26346f;hb=c861bd9c09d20e06533e122253bcd3bb94b0bef9;hp=bee9549d24f04b3c3675f0ae2aafbeca66dab851;hpb=8b3af4ea3647832046e7f140c78181986429aea9;p=eval.git diff --git a/submit/commands.c b/submit/commands.c index bee9549..98adf37 100644 --- a/submit/commands.c +++ b/submit/commands.c @@ -4,13 +4,15 @@ * (c) 2007 Martin Mares */ -#include "lib/lib.h" -#include "lib/mempool.h" -#include "lib/simple-lists.h" -#include "lib/stkstring.h" +#include "ucw/lib.h" +#include "ucw/mempool.h" +#include "ucw/simple-lists.h" +#include "ucw/stkstring.h" +#include "ucw/fastbuf.h" #include "sherlock/object.h" #include "sherlock/objread.h" +#include #include #include "submitd.h" @@ -36,7 +38,7 @@ read_request(struct conn *c) struct obj_read_state st; obj_read_start(&st, c->request); st.error_callback = read_error_cb; - byte line[1024]; + char line[1024]; uns size = 0; for (;;) { @@ -68,7 +70,7 @@ write_reply(struct conn *c) obj_set_attr(c->reply, '+', "OK"); if (trace_commands) { - byte *m; + char *m; if (m = obj_find_aval(c->reply, '-')) msg(L_DEBUG, ">> -%s", m); else if (m = obj_find_aval(c->reply, '+')) @@ -82,7 +84,7 @@ write_reply(struct conn *c) } static void -err(struct conn *c, byte *msg) +err(struct conn *c, char *msg) { obj_set_attr(c->reply, '-', msg); } @@ -128,6 +130,43 @@ 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 * @@ -145,7 +184,7 @@ read_attachment(struct conn *c, uns max_size) // This is less efficient than bbcopy(), but we want our own error handling. struct fastbuf *fb = bopen_tmp(4096); - byte buf[4096]; + char buf[4096]; uns remains = size; while (remains) { @@ -165,7 +204,13 @@ read_attachment(struct conn *c, uns max_size) static void cmd_submit(struct conn *c) { - byte *tname = obj_find_aval(c->request, 'T'); + if (contest_over(c)) + { + err(c, "The contest is over, no more submits allowed"); + return; + } + + char *tname = obj_find_aval(c->request, 'T'); if (!tname) { err(c, "No task specified"); @@ -178,7 +223,7 @@ cmd_submit(struct conn *c) return; } - byte *pname = obj_find_aval(c->request, 'P'); + char *pname = obj_find_aval(c->request, 'P'); if (!pname) { simp_node *s = clist_head(&task->parts); @@ -191,7 +236,7 @@ cmd_submit(struct conn *c) return; } - byte *ext = obj_find_aval(c->request, 'X'); + char *ext = obj_find_aval(c->request, 'X'); if (!ext || !ext_exists_p(task, ext)) { err(c, "Missing or invalid extension"); @@ -219,7 +264,7 @@ cmd_submit(struct conn *c) for (struct oattr *a = obj_find_attr(parto, 'V' + OBJ_ATTR_SON); a; a=a->same) { uns ver = obj_find_anum(a->son, 'V', 0); - byte *ext = obj_find_aval(a->son, 'X'); + char *ext = obj_find_aval(a->son, 'X'); ASSERT(ver && ext); last_ver = MAX(last_ver, ver); if (ver == current_ver) @@ -251,7 +296,7 @@ cmd_submit(struct conn *c) static void execute_command(struct conn *c) { - byte *cmd = obj_find_aval(c->request, '!'); + char *cmd = obj_find_aval(c->request, '!'); if (!cmd) { err(c, "Missing command"); @@ -263,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"); } @@ -282,7 +329,7 @@ process_command(struct conn *c) static void execute_init(struct conn *c) { - byte *user = obj_find_aval(c->request, 'U'); + char *user = obj_find_aval(c->request, 'U'); if (!user) { err(c, "Missing user");