]> mj.ucw.cz Git - moe.git/blobdiff - submit/tasks.c
mo-create-logins: Do not transliterate user names
[moe.git] / submit / tasks.c
index 00df760f0882bbb76d1d6a55fd9d08cbf49b942a..ecb4cbfc34c925598ec0eebd19ff2bad39373052 100644 (file)
@@ -4,18 +4,19 @@
  *  (c) 2007 Martin Mares <mj@ucw.cz>
  */
 
-#include "lib/lib.h"
-#include "lib/conf.h"
-#include "lib/fastbuf.h"
-#include "lib/stkstring.h"
-#include "lib/simple-lists.h"
-#include "lib/mempool.h"
+#include "ucw/lib.h"
+#include "ucw/conf.h"
+#include "ucw/fastbuf.h"
+#include "ucw/stkstring.h"
+#include "ucw/simple-lists.h"
+#include "ucw/mempool.h"
 #include "sherlock/object.h"
 
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <unistd.h>
 #include <errno.h>
+#include <time.h>
 
 #include "submitd.h"
 
@@ -23,7 +24,7 @@ clist task_list;
 static clist extensions;
 static clist open_data_extensions;
 
-static byte *
+static char *
 tasks_conf_commit(void *p UNUSED)
 {
   // We do not do any journaling here as we do not switch config files on the fly
@@ -33,7 +34,7 @@ tasks_conf_commit(void *p UNUSED)
       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);
+           simp_append(cf_pool, &t->parts)->s = mp_printf(cf_pool, "%02d", i);
          t->extensions = &open_data_extensions;
        }
       else
@@ -66,7 +67,7 @@ struct cf_section tasks_conf = {
 };
 
 struct task *
-task_find(byte *name)
+task_find(char *name)
 {
   CLIST_FOR_EACH(struct task *, t, task_list)
     if (!strcasecmp(t->name, name))
@@ -75,7 +76,7 @@ task_find(byte *name)
 }
 
 int
-part_exists_p(struct task *t, byte *name)
+part_exists_p(struct task *t, char *name)
 {
   CLIST_FOR_EACH(simp_node *, p, t->parts)
     if (!strcmp(p->s, name))
@@ -84,7 +85,7 @@ part_exists_p(struct task *t, byte *name)
 }
 
 int
-ext_exists_p(struct task *t, byte *ext)
+ext_exists_p(struct task *t, char *ext)
 {
   CLIST_FOR_EACH(simp_node *, x, *t->extensions)
     if (!strcmp(x->s, ext))
@@ -93,9 +94,9 @@ ext_exists_p(struct task *t, byte *ext)
 }
 
 int
-user_exists_p(byte *user)
+user_exists_p(char *user)
 {
-  byte *fn = stk_printf("solutions/%s", user);
+  char *fn = stk_printf("solutions/%s", user);
   struct stat st;
   return !stat(fn, &st) && S_ISDIR(st.st_mode);
 }
@@ -140,7 +141,7 @@ task_unlock_status(struct conn *c, uns write_back)
       obj_write(fb, c->task_status, BUCKET_TYPE_PLAIN);
       brewind(fb);
       bconfig(fb, BCONFIG_IS_TEMP_FILE, 0);
-      byte *name = stk_printf("solutions/%s/status", c->user);
+      char *name = stk_printf("solutions/%s/status", c->user);
       if (rename(fb->name, name) < 0)
        die("Unable to rename %s to %s: %m", fb->name, name);
       bclose(fb);
@@ -163,7 +164,7 @@ 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');
+      char *name = obj_find_aval(o, 'T');
       ASSERT(name);
       if (!strcmp(name, t->name))
        return o;
@@ -176,12 +177,12 @@ task_status_find_task(struct conn *c, struct task *t, uns create)
 }
 
 struct odes *
-task_status_find_part(struct odes *to, byte *part, uns create)
+task_status_find_part(struct odes *to, char *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');
+      char *name = obj_find_aval(o, 'P');
       ASSERT(name);
       if (!strcmp(name, part))
        return o;
@@ -193,10 +194,34 @@ task_status_find_part(struct odes *to, byte *part, uns create)
   return o;
 }
 
-void task_submit_part(byte *user, byte *task, byte *part, byte *ext, uns version UNUSED, struct fastbuf *fb)
+static void
+task_record_history(char *user, char *task, char *part, char *ext, uns version, char *submitted_name)
 {
-  byte *dir = stk_printf("solutions/%s/%s", user, task);
-  byte *name = stk_printf("%s/%s.%s", dir, part, ext);
+  if (!history_format)
+    return;
+
+  time_t now = time(NULL);
+  struct tm *tm = localtime(&now);
+  char prefix[256];
+  if (strftime(prefix, sizeof(prefix), history_format, tm) <= 0)
+    {
+      msg(L_ERROR, "Error formatting history prefix: too long");
+      return;
+    }
+
+  char *name = stk_printf("%s%s:%s:%s:v%d.%s", prefix, user, task, (strcmp(task, part) ? part : (char*)""), version, ext);
+  struct fastbuf *orig = bopen(submitted_name, O_RDONLY, 4096);
+  struct fastbuf *hist = bopen(name, O_WRONLY | O_CREAT | O_EXCL, 4096);
+  bbcopy_slow(orig, hist, ~0U);
+  bclose(hist);
+  bclose(orig);
+}
+
+void
+task_submit_part(char *user, char *task, char *part, char *ext, uns version, struct fastbuf *fb)
+{
+  char *dir = stk_printf("solutions/%s/%s", user, task);
+  char *name = stk_printf("%s/%s.%s", dir, part, ext);
 
   struct stat st;
   if (stat(dir, &st) < 0 && errno == ENOENT && mkdir(dir, 0777) < 0)
@@ -205,12 +230,15 @@ void task_submit_part(byte *user, byte *task, byte *part, byte *ext, uns version
   bconfig(fb, BCONFIG_IS_TEMP_FILE, 0);
   if (rename(fb->name, name) < 0)
     die("Cannot rename %s to %s: %m", fb->name, name);
+
+  task_record_history(user, task, part, ext, version, name);
 }
 
-void task_delete_part(byte *user, byte *task, byte *part, byte *ext, uns version UNUSED)
+void
+task_delete_part(char *user, char *task, char *part, char *ext, uns version UNUSED)
 {
-  byte *dir = stk_printf("solutions/%s/%s", user, task);
-  byte *name = stk_printf("%s/%s.%s", dir, part, ext);
+  char *dir = stk_printf("solutions/%s/%s", user, task);
+  char *name = stk_printf("%s/%s.%s", dir, part, ext);
   if (unlink(name) < 0)
     msg(L_ERROR, "Cannot delete %s: %m", name);
 }