* (c) 2010 Martin Mares <mj@ucw.cz>
*/
-/*
- * TODO:
- * - we probably have to disable NOP
- */
-
/*
* Things that are not implemented:
*
*/
#define _GNU_SOURCE
+#define UNUSED __attribute__((unused))
+
+#undef ENABLE_DAEMON_MODE
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#include <assert.h>
#include <math.h>
+#include <getopt.h>
static int trace;
static int cpu_quota = -1;
if (!eol)
parse_error("Строка слишком долгая");
*eol = 0;
+ if (eol > line && eol[-1] == '\r')
+ *--eol = 0;
char *c = line;
if (!c[0] || c[0] == ';')
- {
- if (!strncmp(c, ";daji_zor_i_litva=", 18))
- {
- trace = atoi(c+18);
- if (error_hook)
- error_hook("Secret tracing switch flipped");
- }
- continue;
- }
+ continue;
+
+ if (c[0] == '.')
+ return;
if (c[0] == '@')
{
eat = 1;
break;
case 4: // One Russian symbol
- bit = 6;
- fmt = "r";
+ fmt = "xr";
break;
case 5: // Russian text
fmt = "xrrrrrr";
break;
case 6: // One Latin symbol
- bit = 6;
- fmt = "l";
+ fmt = "xl";
break;
default: // Latin text
fmt = "xllllll";
linebuf[pos] = ch;
pos = (pos+1) & 0177;
}
- assert(!bit);
+ assert(bit >= 0);
}
static void run(void)
}
}
+static void die(char *msg)
+{
+ fprintf(stderr, "minsk: ");
+ fprintf(stderr, msg);
+ fputc('\n', stderr);
+ exit(1);
+}
+
/*** Daemon interface ***/
+#ifdef ENABLE_DAEMON_MODE
+
+/*
+ * The daemon mode was a quick hack for the Po drate contest.
+ * Most parameters are hard-wired.
+ */
+
#include <unistd.h>
#include <errno.h>
#include <time.h>
#define TBF_MAX 5 // Max number of tokens in the bucket
#define TBF_REFILL_PER_SEC 0.2 // Bucket refill rate (buckets/sec)
-#define PID_FILE "/var/run/minsk.pid"
-#define UID 65534
-#define GID 65534
-
-static void die(char *msg)
-{
- fprintf(stderr, "minsk: ");
- fprintf(stderr, msg);
- fputc('\n', stderr);
- exit(1);
-}
+#define PID_FILE "/var/run/pd-minsk.pid"
+#define UID 124
+#define GID 125
static char **spt_argv;
static char *spt_start, *spt_end;
va_end(args);
}
-static void sigchld_handler(int sig __attribute__((unused)))
+static void sigchld_handler(int sig UNUSED)
{
}
-static void sigalrm_handler(int sig __attribute__((unused)))
+static void sigalrm_handler(int sig UNUSED)
{
const char err[] = "--- Timed out. Time machine disconnected. ---\n";
write(1, err, sizeof(err));
}
}
+#else
+
+static void run_as_daemon(int do_fork UNUSED)
+{
+ die("Daemon mode not supported in this version, need to recompile.");
+}
+
+static void setproctitle_init(int argc UNUSED, char **argv UNUSED)
+{
+}
+
+#endif
+
+static void init_memory(void)
+{
+ // For the contest, we fill the whole memory with -00 00 0000 0000 (HALT),
+ // not +00 00 0000 0000 (NOP). Otherwise, an empty program would reveal
+ // the location of the password :)
+ for (int i=0; i<4096; i++)
+ mem[i] = 01000000000000ULL;
+
+ // Store the password
+ int pos = 02655;
+ mem[pos++] = 0574060565373;
+ mem[pos++] = 0371741405340;
+ mem[pos++] = 0534051524017;
+}
+
+static const struct option longopts[] = {
+ { "cpu-quota", 1, NULL, 'q' },
+ { "daemon", 0, NULL, 'd' },
+ { "nofork", 0, NULL, 'n' },
+ { "print-quota", 1, NULL, 'p' },
+ { "trace", 1, NULL, 't' },
+ { NULL, 0, NULL, 0 },
+};
+
+static void usage(void)
+{
+ fprintf(stderr, "\
+Options:\n\n\
+--daemon Run as daemon and listen for network connections\n\
+--nofork When run with --daemon, avoid forking\n\
+--trace=<level> Enable tracing of program execution\n\
+--cpu-quota=<n> Set CPU quota to <n> instructions\n\
+--print-quota=<n> Set printer quota to <n> lines\n\
+");
+ exit(1);
+}
+
int main(int argc, char **argv)
{
- if (argc > 1)
- {
- setproctitle_init(argc, argv);
- if (!strcmp(argv[1], "--daemon"))
- run_as_daemon(1);
- else if (!strcmp(argv[1], "--net"))
- run_as_daemon(0);
- else
- die("Usage: minsk [--daemon | --net]");
- }
+ int opt;
+ int daemon_mode = 0;
+ int do_fork = 1;
+
+ while ((opt = getopt_long(argc, argv, "", longopts, NULL)) >= 0)
+ switch (opt)
+ {
+ case 'd':
+ daemon_mode = 1;
+ break;
+ case 'n':
+ do_fork = 0;
+ break;
+ case 'p':
+ print_quota = atoi(optarg);
+ break;
+ case 'q':
+ cpu_quota = atoi(optarg);
+ break;
+ case 't':
+ trace = atoi(optarg);
+ break;
+ default:
+ usage();
+ }
+ if (optind < argc)
+ usage();
+
+ setproctitle_init(argc, argv);
+ init_memory();
+
+ if (daemon_mode)
+ run_as_daemon(do_fork);
- trace = 3;
parse_in();
run();
return 0;