ServerCert certs/server-cert.pem
ServerKey certs/server-key.pem
+# Keep history of all submitted files in files of a given name prefix
+# (formatted by strftime; default: no history kept)
+History history/%H%M%S-
+
# Rules for accepting connections (first matching rule is used)
Access {
# IP address ranges matched by this rule
# Task plans
Task { Name world; OpenData 10; MaxSize 1M; }
- Task necklace
- Task nei
- Task town
+ Task asteroids
+ Task cards
+ Task lines
Extension c cpp pas
OpenDataExt out
static byte *ca_cert_name = "?";
static byte *server_cert_name = "?";
static byte *server_key_name = "?";
+byte *history_format;
static clist access_rules;
static uns trace_tls;
uns max_request_size;
CF_STRING("CACert", &ca_cert_name),
CF_STRING("ServerCert", &server_cert_name),
CF_STRING("ServerKey", &server_key_name),
+ CF_STRING("History", &history_format),
CF_LIST("Access", &access_rules, &access_conf),
CF_UNS("TraceTLS", &trace_tls),
CF_UNS("TraceCommands", &trace_commands),
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
+#include <time.h>
#include "submitd.h"
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(byte *user, byte *task, byte *part, byte *ext, uns version, byte *submitted_name)
+{
+ if (!history_format)
+ return;
+
+ time_t now = time(NULL);
+ struct tm *tm = localtime(&now);
+ byte prefix[256];
+ if (strftime(prefix, sizeof(prefix), history_format, tm) <= 0)
+ {
+ msg(L_ERROR, "Error formatting history prefix: too long");
+ return;
+ }
+
+ byte *name = stk_printf("%s%s:%s:%s:v%d.%s", prefix, user, task, (strcmp(task, part) ? part : (byte*)""), 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(byte *user, byte *task, byte *part, byte *ext, uns version, struct fastbuf *fb)
{
byte *dir = stk_printf("solutions/%s/%s", user, task);
byte *name = stk_printf("%s/%s.%s", dir, part, ext);
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)