Example #1
0
/**
 * Copy test to testing directory
 *
 * @param __num - number of test to copy
 * @param __total - total count of tests
 * @param __data_dir - data directory
 * @param __dst - destination directory
 * @param __name - name of file to store to
 * @return TRUE on success, FALSE otherwise
 */
static BOOL
copy_test (int __num, int __total, const char *__data_dir,
           const char *__dst, const char *__name)
{
  char src[4096], dst[4096], tst[16];

  /* Get full source filename */
  testnum (__num, __total, tst);
  snprintf (src, BUF_SIZE (src), "%s/%s%s", __data_dir, tst, tst_ext);

  /* Check for existment of test file */
  if (!fexists (src))
    {
      return FALSE;
    }

  /* Get full destination filename */
  snprintf (dst, BUF_SIZE (dst), "%s/%s", __dst, __name);

  if (copyfile (src, dst))
    {
      INF_DEBUG_LOG ("Error copuing test file from %s to %s\n", src, dst);
      return FALSE;
    }

  return TRUE;
}
Example #2
0
/**
 * Copy all files needed for correct working after chrooting
 *
 * @param __dst_dir - where files should be copied
 */
static void
copy_chroot_data (const char *__dst_dir)
{
  char src_dir[4096];
  static char init = FALSE;

  INF_DEBUG_LOG ("Copying chroot data to %s\n", __dst_dir);

  snprintf (src_dir, BUF_SIZE (src_dir), "%s/chroot", data_dir);
  fcopydir (src_dir, __dst_dir);

  snprintf (src_dir, BUF_SIZE (src_dir), "%s/chroot", data_dir);

  if (!init)
    {
      /* Cache list of items, needed by chrooting */
      dynastruc_t *ls;
      int count = 0;
      char *cur_dir;
      ls = dir_listing (src_dir);

      DYNA_FOREACH (ls, cur_dir);
        strcpy (chroot_items[count++], cur_dir);
      DYNA_DONE;

      dyna_destroy (ls, dyna_deleter_free_ref_data);
      init = TRUE;
    }
}
Example #3
0
/**
 * Get command to compile solution
 *
 * @param __self - task to be compoled
 * @param __cur_testing_dir - current testing directory
 * @param __cur_data_dir - directory with current data
 * @para, __cmd - output buffer
 */
static void
build_compiler_command (wt_task_t *__self, const char *__cur_testing_dir,
                        const char *__cur_data_dir, char *__cmd)
{
  char dummy[4096], flags[4096] = "", flags_path[1024];

  /* Get command from config file */
  strcpy (__cmd, COMPILER_PCHAR_KEY (TASK_COMPILER_ID (*__self), "Command"));

  snprintf (flags_path, BUF_SIZE (flags_path),
            "CompilerFlags/%s", TASK_COMPILER_ID (*__self));
  INF_PCHAR_KEY (flags, flags_path);

  /* Parse command */
  replace_defaults (__cmd, __cur_testing_dir, __cur_data_dir);
  REPLACE_VAR (__cmd, "flags", flags);

  /* Source filename */
  snprintf (dummy, BUF_SIZE (dummy), "%s%s", source_file, TASK_SRCEXT (__self));
  REPLACE_VAR (__cmd, "source", dummy);

  /* Output filename */
  snprintf (dummy, BUF_SIZE (dummy), "%s%s", file_to_exec,
            COMPILER_SAFE_PCHAR_KEY (TASK_COMPILER_ID (*__self),
                                     "OutputExtension", INFORMATICS_EXECEXT));
  REPLACE_VAR (__cmd, "output", dummy);
}
Example #4
0
void
test_crypto (const struct crypto_options *co, struct frame* frame)
{
  int i, j;
  struct gc_arena gc = gc_new ();
  struct buffer src = alloc_buf_gc (TUN_MTU_SIZE (frame), &gc);
  struct buffer work = alloc_buf_gc (BUF_SIZE (frame), &gc);
  struct buffer encrypt_workspace = alloc_buf_gc (BUF_SIZE (frame), &gc);
  struct buffer decrypt_workspace = alloc_buf_gc (BUF_SIZE (frame), &gc);
  struct buffer buf = clear_buf();

  /* init work */
  ASSERT (buf_init (&work, FRAME_HEADROOM (frame)));

  msg (M_INFO, "Entering " PACKAGE_NAME " crypto self-test mode.");
  for (i = 1; i <= TUN_MTU_SIZE (frame); ++i)
    {
      update_time ();

      msg (M_INFO, "TESTING ENCRYPT/DECRYPT of packet length=%d", i);

      /*
       * Load src with random data.
       */
      ASSERT (buf_init (&src, 0));
      ASSERT (i <= src.capacity);
      src.len = i;
      ASSERT (rand_bytes (BPTR (&src), BLEN (&src)));

      /* copy source to input buf */
      buf = work;
      memcpy (buf_write_alloc (&buf, BLEN (&src)), BPTR (&src), BLEN (&src));

      /* encrypt */
      openvpn_encrypt (&buf, encrypt_workspace, co, frame);

      /* decrypt */
      openvpn_decrypt (&buf, decrypt_workspace, co, frame);

      /* compare */
      if (buf.len != src.len)
	msg (M_FATAL, "SELF TEST FAILED, src.len=%d buf.len=%d", src.len, buf.len);
      for (j = 0; j < i; ++j)
	{
	  const uint8_t in = *(BPTR (&src) + j);
	  const uint8_t out = *(BPTR (&buf) + j);
	  if (in != out)
	    msg (M_FATAL, "SELF TEST FAILED, pos=%d in=%d out=%d", j, in, out);
	}
    }
  msg (M_INFO, PACKAGE_NAME " crypto self-test mode SUCCEEDED.");
  gc_free (&gc);
}
Example #5
0
/**
 * Validate sequrity hashes
 *
 * @param __s - hash to validate to
 * @param __unique - unique
 */
static void
validate_security (char *__s, long __unique)
{
  char tmp[128], dummy[128], key[128];
  snprintf (tmp, BUF_SIZE (tmp), "##%s@%ld##", __s, __unique);
  md5_crypt (tmp, SECURITY_MAGICK, dummy);
  strcpy (key, dummy + 8);
  strcpy (__s, key);
}
Example #6
0
/* allocate a buffer for socket or tun layer */
void
alloc_buf_sock_tun (struct buffer *buf,
		    const struct frame *frame,
		    const bool tuntap_buffer,
		    const unsigned int align_mask)
{
  /* allocate buffer for overlapped I/O */
  *buf = alloc_buf (BUF_SIZE (frame));
  ASSERT (buf_init (buf, FRAME_HEADROOM_ADJ (frame, align_mask)));
  buf->len = tuntap_buffer ? MAX_RW_SIZE_TUN (frame) : MAX_RW_SIZE_LINK (frame);
  ASSERT (buf_safe (buf, 0));
}
Example #7
0
int main(int argc, char const **argv) {

    int sockfd; // Дескриптор сокета
    const int val = 1; // Для установки параметров сокета
    char buffer[BUF_SIZE()]; // Буффер сообщения
    struct sockaddr_in servaddr, clientaddr; // Параметры сервера и клиента

    sockfd = Socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); // Сокет инициализируется как простой UDP-сокет

    memset(&servaddr, 0, sizeof(servaddr));

/* Заполнение буффера сообщения */
    strcpy(buffer, "HEY ITS MY BROADCAST");

/* Установка параметров сервера и клиента */
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = INADDR_ANY;
    servaddr.sin_port = htons(SERVER_PORT());

    clientaddr.sin_family = AF_INET;
    clientaddr.sin_addr.s_addr = inet_addr("192.168.1.255");
    clientaddr.sin_port = htons(CLIENT_PORT());

/* Установка параметров сокета */
    Setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &val, sizeof(int));

/* Привязка параметров сервера к сокету */
    Bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));

/* Отправка broadcast - сообщения */
    Sendto(sockfd, buffer, BUF_SIZE(), 0, (struct sockaddr *)&clientaddr, sizeof(clientaddr));
    
/* Закрываем сокет и освобождаем память */
    shutdown(sockfd, SHUT_RDWR);
    close(sockfd);

    return 0;

}
Example #8
0
/**
 * Remove all files needed for correct working after chrooting
 * from solution directory
 *
 * @param __dir - where files should be deleted
 */
static void
remove_chroot_data (const char *__dir)
{
  int i = 0;
  char full[4096];

  INF_DEBUG_LOG ("Removing chroot data from %s\n", __dir);

  while (chroot_items[i][0])
    {
      snprintf (full, BUF_SIZE (full), "%s/%s", __dir, chroot_items[i]);
      unlinkdir (full);
      i++;
    }
}
Example #9
0
void
on_ctrlButton_clicked              (GtkButton *__button, gpointer __user_data)
{
  int i;
  char name[64];
  for (i=0; i<7; i++)
    {
      snprintf (name, BUF_SIZE (name), "ctrlButton_%d", i);
      if (__button==(GtkButton*)lookup_widget (main_window, name))
        {
          exec_button_command (i);
          break;
        }
    }
}
Example #10
0
/**
 * Find hive item in configuration tree
 *
 * @param - name of item (absolute path)
 * @return hive item descriptor
 */
hive_item_t*
config_find_item (char *__name)
{
  dyna_item_t *item;
  char buf[65536];
  snprintf (buf, BUF_SIZE (buf), "root/%s", __name);

  LOCK;
    item = hive_find_item (config, buf);
  UNLOCK;

  if (!item)
    {
      return 0;
    }

  return item->data;
}
Example #11
0
/**
 * Launch command
 *
 * @params __args - arguments
 * @return zero on success, non-zero otherwise
 */
int
sys_launch (const char *__args, ...)
{
  char buf[65536], dummy[65536];
  int ret;

  PACK_ARGS (__args, dummy, 65535);
  snprintf (buf, BUF_SIZE (buf), "%s > /dev/null 2>&1", dummy);

  ret = system (buf);
  if (WIFSIGNALED (ret) && (WTERMSIG (ret) == SIGINT ||
      WTERMSIG (ret) == SIGQUIT))
    {
      core_kill_process (0, WTERMSIG (ret));
    }

  return 0;
}
Example #12
0
/**
 * Send new status to client
 *
 * @param __self - client to send changes to
 * @param __vars - changed variables
 */
static void
send_stat_changes (stat_client_t *__self, assarr_t *__vars)
{
  char stat[65536], vars[65536];

  if (__self->ipc_client->access < 7) /* But why?? */
    {
      return;
    }

  dump_arr_to_buf (__vars, vars);
  snprintf (stat, BUF_SIZE (stat), "vars;%ld;%s;", (long) strlen (vars), vars);

  if (strcmp (vars, ""))
    {
      sock_answer (__self->ipc_client->sock, "+OK %s\n", stat);
    }
}
Example #13
0
/**
 * Dump assaciative array to string buffer
 *
 * @param __self - array to be dumped
 * @param __buf - buffer to dump to
 */
static void
dump_arr_to_buf (const assarr_t *__self, char *__buf)
{
  flex_value_t *val;
  char *key;
  char dumped[65536], dummy[1024];

  strcpy (__buf, "");

  ASSARR_FOREACH_DO (__self, key, val);
    flexval_serialize (val, dumped);
    strcat (__buf, key);
    strcat (__buf, ";");
    snprintf (dummy, BUF_SIZE (dummy), "%ld", (long) strlen (dumped));
    strcat (__buf, dummy);
    strcat (__buf, ";");
    strcat (__buf, dumped);
    strcat (__buf, ";");
  ASSARR_FOREACH_DONE;
}
Example #14
0
/**
 * Checking, casted after running compiler
 *
 * @param __self - task to be compiled
 * @param __cur_testing_dir - current testing directory
 * @param __cur_data_dir - directory with current data
 * @oaram __params - collecting params to return to WebIFACE
 * @return TRUE on success, FALSE otherwise
 */
static BOOL
post_compiling_check (wt_task_t *__self, const char *__cur_testing_dir,
                      const char *__cur_data_dir, assarr_t *__params)
{
  char pchar[4096];

  /* Check for existment of solution executable file */
  /* Get full filename of executable file */
  snprintf (pchar, BUF_SIZE (pchar), "%s/%s%s", __cur_testing_dir, file_to_exec,
            COMPILER_SAFE_PCHAR_KEY (TASK_COMPILER_ID (*__self),
                                     "OutputExtension", ""));

  if (!fexists (pchar))
    {
      return FALSE;
    }

  chmod (pchar, 00775);

  return TRUE;
}
Example #15
0
/**
 * Save solution to file
 *
 * @param __self - testing task
 * @param __cur_testing_dir - current testing directory
 * @return TRUE if solution saved, FALSE otherwise
 */
static BOOL
save_solution (wt_task_t *__self, char *__cur_testing_dir)
{
  char fn[4096];
  char *src = TASK_INPUT_PARAM (*__self, "SOURCE");

  snprintf (fn, BUF_SIZE (fn), "%s/%s%s", __cur_testing_dir,
            source_file, TASK_SRCEXT (__self));

  /* Write data to stream */
  if (fwritebuf (fn, src))
    {
      INF_DEBUG_LOG ("Task %ld. Error writting buffer to solution file\n",
                     __self->sid);
      return FALSE;
    }

  chmod (fn, 00660);

  return TRUE;
}
Example #16
0
int
main (int __argc, char **__argv)
{
  pid_t pid, w;
  int i, status, config_allowed = 0;
  long port = -1;

  char cmd[4096] = "",
       workdir[4096] = "./",
       security[128],
       host[128],
       unique[16];

  char pchar_pid[8];
  char pchar_pid2[8];

  long uid = -1, gid = -1;
  long ruid = geteuid (), rgid = getegid ();
  int use_chroot = 0;

  /* Send PID of this stuff  */
  printf ("%u@", getpid ());
  fflush (0);

  signal (SIGINT, signal_term);
  signal (SIGHUP, signal_term);
  /*  signal (SIGSTOP, signal_term); */
  signal (SIGTERM, signal_term);

  strcpy (config_file, CONFIG_FILE);

  /* Getting command line parameters */
  for (i = 0; i < __argc; i++)
    {
      if (C_ARG_EQ ("-cmd") && i < __argc - 1)
        {
          strcpy (cmd, __argv[++i]);
        }
      if (C_ARG_EQ ("-workdir") && i < __argc - 1)
        {
          strcpy (workdir, __argv[++i]);
        }
      if (C_ARG_EQ ("-security") && i < __argc - 1)
        {
          strcpy (security, __argv[++i]);
        }
      if (C_ARG_EQ ("-port") && i < __argc - 1)
        {
          port = atoi (__argv[++i]);
        }
      if (C_ARG_EQ ("-host") && i < __argc - 1)
        {
          strcpy (host, __argv[++i]);
        }
      if (C_ARG_EQ ("-unique") && i < __argc - 1)
        {
          strcpy (unique, __argv[++i]);
        }
      if (C_ARG_EQ ("-sock-read-timeout") && i < __argc - 1)
        {
          read_timeout = atof (__argv[++i]) * NSEC_COUNT;
        }
      if (C_ARG_EQ ("-sock-read-delay") && i < __argc - 1)
        {
          read_delay = atof (__argv[++i]) * NSEC_COUNT;
        }

      if (C_ARG_EQ ("-uid") && i < __argc - 1)
        {
          uid = atol (__argv[++i]);
        }
      if (C_ARG_EQ ("-gid") && i < __argc - 1)
        {
          gid = atol (__argv[++i]);
        }

      if (C_ARG_EQ ("-config-file") && i < __argc - 1)
        {
          strcpy (config_file, __argv[++i]);
        }

      if (C_ARG_EQ ("-chroot"))
        {
          use_chroot = 1, i++;
        }
    }

  validate_security (security, atol (unique));

  /* Initialize IPC socket */
  lrvm_ipc_init (host, port);

  /****
   * Send basic info to LibRUN
   */

  snprintf (pchar_pid, BUF_SIZE (pchar_pid), "%u", getpid ());

  lrvm_ipc_send_command ("unique", unique);
  lrvm_ipc_send_command ("security", security);
  lrvm_ipc_send_command ("validate", "");

  /* Check for valid prefix of config file */
  i = 0;
  while (config_allowed_prefixes[i])
    {
      if (!strncmp (config_file, config_allowed_prefixes[i],
                    strlen (config_allowed_prefixes[i])))
        {
          config_allowed = 1;
          break;
        }
      i++;
    }
  if (!config_allowed)
    {
      /* lrvm_ipc_send_command ("exec_error", config_file); */
      lrvm_ipc_send_command ("exec_error", "\"Strange config file. "
                             "LRVM not started because of security reasons.\"");
      lrvm_ipc_done ();
      term ();
    }

  switch (pid = fork ()) /* Deattach from parent */
    {
    case -1 :
      term ();
      return -1;

    case 0:
      chugid_prepare (ruid, rgid, uid, gid);

      chdir (workdir);
      if (use_chroot)
        {
          chroot (workdir);
        }

      chugid (ruid, rgid, uid, gid);

      snprintf (pchar_pid2, BUF_SIZE (pchar_pid2), "%u", getpid ());
      lrvm_ipc_send_command ("taskpid", pchar_pid2);

      execute (cmd);
      exit (errno);
    }

  do
    {
      w = waitpid (-1, &status, WUNTRACED | WCONTINUED);
      if (w == -1)
        {
          return -1;
        }
      if (WIFEXITED (status))
        {
          int exit_code = WEXITSTATUS (status);
          char buf[8];
          snprintf (buf, BUF_SIZE (buf), "%d", exit_code);
          lrvm_ipc_send_command ("exit_code", buf);
        }
      else
        if (WIFSIGNALED (status))
        {
          int termsig = WTERMSIG (status);
          char buf[8];
          snprintf (buf, BUF_SIZE (buf), "%d", termsig);
          lrvm_ipc_send_command ("termsig", buf);
        }
      else
        if (WIFSTOPPED (status))
        {
          int stopsig = WSTOPSIG (status);
          char buf[8];
          snprintf (buf, BUF_SIZE (buf), "%d", stopsig);
          lrvm_ipc_send_command ("stopsig", buf);
        }
      else
        if (WIFCONTINUED (status))
        {
          lrvm_ipc_send_command ("continue", "");
        }
    }
  while (!WIFEXITED (status) && !WIFSIGNALED (status));

  fflush (0);
  lrvm_ipc_send_command ("finalize", "");
  lrvm_ipc_done ();
  exit (0);
}
Example #17
0
/**
 * Unlink all unwanted testing dirs
 */
static void
unlink_unwanted_testing_dirs (void)
{
  static BOOL initialized = FALSE;
  static timeval_t last_unlink;
  timeval_t cur = now ();

  mutex_lock (unlink_mutex);
  INF_DEBUG_LOG ("Start unlinking unwanted dirs\n");

  if (!initialized)
    {
      last_unlink = now ();
      initialized = TRUE;
    }

  if (CHECK_TIME_DELTA (last_unlink, cur, unlink_interval))
    {
      char *cur_dir;
      char lock_file[4096], full[4096];
      int to_delete = 0;
      dynastruc_t *ls;

      mutex_lock (lck_mutex);
      ls = dir_listing (testing_dir);
      mutex_unlock (lck_mutex);

      to_delete = dyna_length (ls) - keep_alive_testdirs;
      if (to_delete < 0)
        {
          to_delete = 0;
        }

      DYNA_FOREACH (ls, cur_dir);
        if (!to_delete)
          {
            DYNA_BREAK;
          }

        snprintf (full, BUF_SIZE (full), "%s/%s", testing_dir, cur_dir);
        snprintf (lock_file, BUF_SIZE (lock_file), "%s/lock", full);

        if (!flock_test (lock_file))
          {
            INF_INFO ("Unlink testing dir %s\n", cur_dir);
            unlinkdir (full);
          }
        else
          {
            INF_DEBUG_LOG ("Skipping unlinking testing dir %s\n", cur_dir);
          }

        to_delete--;
      DYNA_DONE;

      dyna_destroy (ls, dyna_deleter_free_ref_data);
      last_unlink = cur;
    }

  mutex_unlock (unlink_mutex);
  INF_DEBUG_LOG ("Unwanted dirs have been just deleted\n");
}
Example #18
0
/*
 * Main stuff of testing
 *
 * @param __self - task to be compiled
 * @param __cur_testing_dir - current testing directory
 * @param __points - collected points
 * @param __errors - solution's errors on tests
 * @oaram __params - collecting params to return to WebIFACE
 */
static void
testing_main_loop (wt_task_t *__self, const char *__cur_data_dir,
                   const char *__cur_testing_dir, int *__points,
                   char *__errors, assarr_t *__params)
{
  int i;

  INF_DEBUG_LOG ("Task %ld. Enter testing mainloop stuff\n", __self->sid);

  /* Bonus points (if all tests passed) */
  int bonus = atoi (TASK_INPUT_PARAM (*__self, "BONUS"));

  /* I/O filenames  */
  /* Name of input file */
  char *input_file = TASK_INPUT_PARAM (*__self, "INPUTFILE");
  /* Name of output file  */
  char *output_file = TASK_INPUT_PARAM (*__self, "OUTPUTFILE");

  /* Resource limits */
  /* But why simple atof doesn't work? */
  DWORD memory_limit = flexval_atolf (TASK_INPUT_PARAM (*__self,
                                               "MEMORYLIMIT")) * 1024; /* Kb */
  DWORD time_limit = flexval_atolf (TASK_INPUT_PARAM (*__self,
                                        "TIMELIMIT")) * USEC_COUNT; /* usecs */

  char full_input[4096],  /* Full input filename */
       full_output[4096], /* Full output filename */
       checker_cmd[4096]; /* Command to execute */

  /* String with all tests' results */
  char tests_res_pchar[(MAX_ERRCODE + 1) * MAX_TESTS];

  /* Process's descriptor */
  run_process_info_t *proc = NULL;

  /* Filename to execute */
  char execfn[4096] = {0};

  /* Errors */
  BOOL RE = FALSE, ML = FALSE, TL = FALSE, WA = FALSE, PE = FALSE, CR = FALSE;
  /* PChar-ed error for current test */
  char cur_err_str[MAX_ERRCODE + 1];
  BOOL acm = !strcmp (TASK_INPUT_PARAM (*__self, "ACM"), "TRUE");

  /* Unpack tests' data */
  char *tests_pchar = TASK_INPUT_PARAM (*__self, "TESTS"),
          effective_tests[4096];

  char **tests_pchar_arr = 0;

  /* Points for tests */
  int tests[MAX_TESTS];

  /* Dummy pchar value */
  char dummy[1024];

  int compiler_chroot = COMPILER_SAFE_INT_KEY (TASK_COMPILER_ID (*__self),
                                              "ChRoot", -1);

  /* Get command for solution executing */
  char *run_solution_cmd = COMPILER_SAFE_PCHAR_KEY (TASK_COMPILER_ID (*__self),
                                                    "RunSolutionCmd", NULL);

  if (run_solution_cmd && strcmp (run_solution_cmd, ""))
    {
      /* We'll make some changes in this string, so we should */
      /* close this string to make original stored in hive tree */
      /* for correct freeing */
      run_solution_cmd = strdup (run_solution_cmd);

      /* String may be enlarged when parameters will be substitued  */
      run_solution_cmd = realloc (run_solution_cmd, 65535);

      replace_defaults (run_solution_cmd, __cur_testing_dir, __cur_data_dir);
    }

  /*
   * TODO: Need to strip dupicated spaces in source string with tests
   */

  trim (tests_pchar, effective_tests);
  int tests_count = explode (effective_tests, " ", &tests_pchar_arr);

  /* Per-compiler resource usage correction */
  double time_corr, rss_corr;

  assarr_t *outputs = NULL, *checker_outputs = NULL;
  char *output = NULL;

  for (i = 0; i < tests_count; i++)
    {
      tests[i] = atoi (tests_pchar_arr[i]);
    }

  /* Free unwanted data */
  free_explode_data (tests_pchar_arr);

  /* Some more initializations */
  snprintf (full_input, BUF_SIZE (full_input), "%s/%s",
            __cur_testing_dir, input_file);
  snprintf (full_output, BUF_SIZE (full_output), "%s/%s",
            __cur_testing_dir, output_file);

  strcpy (tests_res_pchar, "");

  TASK_LOG (*__self, "----\n");

  /* Get executable file name */
  INF_PCHAR_KEY (execfn, "FileToExec");
  strcat (execfn, COMPILER_SAFE_PCHAR_KEY (TASK_COMPILER_ID (*__self),
                                           "OutputExtension", ""));
  if (run_solution_cmd)
    {
      REPLACE_VAR (run_solution_cmd, "executable", execfn);
    }
  else
    {
      run_solution_cmd = strdup (execfn);
    }

  if (compiler_chroot >= 0)
    {
      use_chroot = compiler_chroot;
    }

  /* Copying all libs/binaries needed for correct running of solution */
  if (use_chroot)
    {
      copy_chroot_data (__cur_testing_dir);
    }

  /* Get corrections to apply when executing solution */
  snprintf (dummy, BUF_SIZE (dummy), "ResourceCorrections/Compilers/%s/Time",
            TASK_COMPILER_ID (*__self));
  INF_SAFE_FLOAT_KEY (time_corr, dummy, 0);

  snprintf (dummy, BUF_SIZE (dummy), "ResourceCorrections/Compilers/%s/RSS",
            TASK_COMPILER_ID (*__self));
  INF_SAFE_FLOAT_KEY (rss_corr, dummy, 0);

  /* Apply corrections */
  time_limit += time_corr * USEC_COUNT;
  memory_limit += rss_corr;

  if (fabs (time_corr) > 1e-8 || fabs (rss_corr) > 1e-8)
    {
      INF_DEBUG_LOG ("Using per-compiler corrections: RSS: %lf, time: %lf\n",
                     rss_corr, time_corr);
    }

  if (need_store_output () && max_output_store_size > 0)
    {
      outputs = assarr_create ();
      output = malloc (max_output_store_size + 1);
    }

  if (need_store_checker_output ())
    {
      checker_outputs = assarr_create ();
    }

  /* Cycle by tests */
  INF_DEBUG_LOG ("Task %ld. Begin cycle by tests\n", __self->sid);
  for (i = 0; i < tests_count; i++)
    {
      LOOP_CHECK_ACTIVE;

      /* Some pre-initialization */
      strcpy (cur_err_str, "OK");

      /* Command to execute checker */
      build_checker_cmd (__self, __cur_testing_dir, __cur_data_dir,
                         i + 1, tests_count, checker_cmd);

      /* Copy test file (input file) */
      INF_DEBUG_LOG ("Task %ld. Copy test\n", __self->sid);
      if (!copy_test (i + 1, tests_count, __cur_data_dir,
                      __cur_testing_dir, input_file))
        {
          TASK_LOG (*__self, "\n--------\n"
                             "Fatal error: error copying test file #%d.\n"
                             "Testing aborted.\n", i + 1);
          REPORT (__params, "Error copying test #%d.", i + 1);
          LOOPCRASH;
        }

      /* Execute solution */
      SAFE_FREE_PROC (proc);
      INF_DEBUG_LOG ("Task %ld. Executing solution (cmd: %s)\n",
                     __self->sid, run_solution_cmd);
      proc = run_create_process (run_solution_cmd, __cur_testing_dir,
                                 memory_limit, time_limit);

      /* Set security info */
      run_set_usergroup (proc, solution_exec_uid, solution_exec_gid);
      run_set_chroot (proc, use_chroot);

      run_execute_process (proc);
      run_pwait (proc);
      INF_DEBUG_LOG ("Task %ld. Finish executing solution\n", __self->sid);

      LOOP_CHECK_ACTIVE;

      if (RUN_PROC_EXEC_ERROR (*proc))
        {
          INF_DEBUG_LOG ("Task %ld. "
                         "Fatal error duting executing solution: %s\n",
                         __self->sid, RUN_PROC_ERROR_DESC (*proc));

          TASK_LOG (*__self, "\n--------\n"
                             "Fatal error: error executing solution "
                             "at test #%d: %s.\nTesting aborted.\n",
                    i + 1, RUN_PROC_ERROR_DESC (*proc));

          REPORT (__params, "Error executing solution at test #%d: %s.",
                  i + 1, RUN_PROC_ERROR_DESC (*proc));

          LOOPCRASH;
        }

      INF_DEBUG_LOG ("Task %ld test #%d: solution exit with exit_code %d, "
                     "rss_usage %lld and time_usage %lld\n", __self->sid, i,
                     RUN_PROC_EXITCODE (*proc), RUN_PROC_RSSUSAGE (*proc),
                     RUN_PROC_TIMEUSAGE (*proc));

      if (RUN_PROC_PIPEBUF (*proc))
        {
          INF_DEBUG_LOG ("Pipe from task %ld test #%d: %s\n", __self->sid, i,
                         RUN_PROC_PIPEBUF (*proc));
        }

      /* Overview solution's status */
      if (RUN_PROC_MEMORYLIMIT (*proc))
        {
          ERR (ML, "ML")
        }
      else if (RUN_PROC_TIMELIMIT (*proc))
        {
          ERR (TL, "TL")
        }
      else if (PROCESS_RUNTIME_ERROR (*proc))
        {
          ERR (RE, "RE")
        }
      else
        {
          if (!fexists (full_output))
            {
              /* No output file. Presentation error. */
              INF_DEBUG_LOG ("Task %ld. Output file not found after "
                             "running solution.", __self->sid);

              ERR (PE, "PE");
            }
          else
            {
              /* Need this here because in case of ACM rules */
              /* macro ERR() may abort testing cycle */
              if (outputs)
                {
                  FILE *stream = fopen (full_output, "r");

                  snprintf (dummy, BUF_SIZE (dummy), "%d", i);

                  if (stream)
                    {
                      size_t len = fread (output, 1,
                                          max_output_store_size, stream);
                      output[len] = 0;

                      assarr_set_value (outputs, dummy, strdup (output));

                      fclose (stream);
                    }
                }

              /* Exec checker */
              SAFE_FREE_PROC (proc);
              INF_DEBUG_LOG ("Task %ld. Executing checker (cmd: %s)\n",
                             __self->sid, checker_cmd);
              proc = run_create_process (checker_cmd, __cur_data_dir,
                                         checker_memory_limit,
                                         checker_time_limit);

              run_execute_process (proc);
              run_pwait (proc);
              INF_DEBUG_LOG ("Task %ld. Finish executing checker\n",
                             __self->sid);

              LOOP_CHECK_ACTIVE;

              /* Error while trying to execute checker */
              if (RUN_PROC_EXEC_ERROR (*proc))
                {
                  INF_DEBUG_LOG ("Task %ld. "
                                 "Fatal error duting executing checker: %s\n",
                                 __self->sid, RUN_PROC_ERROR_DESC (*proc));

                  TASK_LOG (*__self, "\n--------\n"
                                     "Fatal error: error executing checker "
                                     "at test #%d: %s.\nTesting aborted.\n",
                            i + 1, RUN_PROC_ERROR_DESC (*proc));

                  REPORT (__params, "Error executing checker at test #%d: %s.",
                          i + 1, RUN_PROC_ERROR_DESC (*proc));

                  LOOPCRASH;
                }


              /* Checker finished by signal. */
              if (RUN_PROC_TERMINATED (*proc))
                {
                  TASK_LOG (*__self, "\n--------\n"
                                     "Fatal error: Abnormal checker "
                                     "termionation at test #%d. "
                                     "TERM signal: %d.\nTesting aborted.\n",
                            i + 1, RUN_PROC_TERMSIG (*proc));

                  REPORT (__params, "Abnormal checker termination at test #%d. "
                                    "TERM signal: %d.", i + 1,
                          RUN_PROC_TERMSIG (*proc));

                  LOOPCRASH;
                }

              INF_DEBUG_LOG ("Task %ld. "
                             "Checker finished working with exit code %d\n",
                             __self->sid, RUN_PROC_EXITCODE (*proc));

              /* Resource usage error while executing checker */
              if (RUN_PROC_MEMORYLIMIT (*proc) || RUN_PROC_TIMELIMIT (*proc))
                {
                  INF_DEBUG_LOG ("Task %ld. "
                                 "Checker's resource usage error (%s)\n",
                                 __self->sid, ((RUN_PROC_MEMORYLIMIT (*proc)) ?
                                                   ("Memory limit") :
                                                   ("Time limit")));

#ifdef __DEBUG
                  if (RUN_PROC_MEMORYLIMIT (*proc))
                    {
                      INF_DEBUG_LOG ("Task %ld. Checker's memory limit was"
                                     " %lld but %lld was used\n",
                                     __self->sid, checker_memory_limit,
                                     RUN_PROC_RSSUSAGE (*proc));
                    }
                  else
                    {
                      INF_DEBUG_LOG ("Task %ld. Checker's time limit was %lld "
                                     "but %lld was used\n", __self->sid,
                                     checker_time_limit,
                                     RUN_PROC_TIMEUSAGE (*proc));
                    }
#endif

                  TASK_LOG (*__self, "\n--------\n"
                                     "Fatal error: resource limit error while "
                                     "executing checker.\nTesting aborted.\n");
                  REPORT (__params, "Resource limit exceeded while executing "
                                    "checker at test #%d. ",
                          i + 1);

                  LOOPCRASH;
                }

              /* Store checker's output message */
              if (checker_outputs && RUN_PROC_PIPEBUF (*proc))
                {
                  snprintf (dummy, BUF_SIZE (dummy), "%d", i);

                  assarr_set_value (checker_outputs, dummy,
                                    strdup (RUN_PROC_PIPEBUF (*proc)));
                }

              /* Overview checker's exit code */
              switch (RUN_PROC_EXITCODE (*proc))
                {
                case _OK:
                  /* Update points for task */
                  (*__points) += tests[i];
                  push_string ("OK", " ", tests_res_pchar);
                  break;
                case _WA:
                  ERR (WA, "WA");
                  break;
                case _PE:
                  ERR (PE, "PE");
                  break;
                default:
                  /* Unknown checker's exit code */
                  TASK_LOG (*__self, "\n--------\nFatal error: checker exited "
                                     "with unknown code: %d.\nBuffer from "
                                     "checker: %s\nTesting aborted.\n",
                            RUN_PROC_EXITCODE (*proc),
                            RUN_PROC_PIPEBUF (*proc));

                  REPORT (__params, "Checker exited with unknown code: %d\n"
                                    "Buffer from checker: %s",
                          i + 1, RUN_PROC_PIPEBUF (*proc));

                  LOOPCRASH;
                  break;
                }

              SAFE_FREE_PROC (proc);
            }
        }

      /* Delete input file (to reduce storaging of garbage) and */
      /* correct handling of PE */
      unlink (full_input);
      unlink (full_output);

      SAFE_FREE_PROC (proc);

      /* Log information about passed test */
      LOG_TEST;
    }

  INF_DEBUG_LOG ("Task %ld. Testing mainloop finished\n", __self->sid);

__done_:
  SAFE_FREE_PROC (proc);

  SAFE_FREE (run_solution_cmd);

  assarr_set_value (__params, "TESTS", strdup (tests_res_pchar));

  if (use_chroot)
    {
      remove_chroot_data (__cur_testing_dir);
    }

  LOOP_DONE_CHECK_ACTIVE;

  if (!CR)
    {
      if (RE) push_string ("RE", " ", __errors);
      if (ML) push_string ("ML", " ", __errors);
      if (TL) push_string ("TL", " ", __errors);
      if (WA) push_string ("WA", " ", __errors);
      if (PE) push_string ("PE", " ", __errors);

      /* If errors' string is empty, no errors were occured */
      /* in task's testing. So we can set bonus to points. */
      if (!strcmp (__errors, ""))
        {
          (*__points) += bonus;
          strcpy (__errors, "OK");
        }
    }

  STORE_OUTPUTS (outputs,         "SOLUTION_OUTPUT");
  STORE_OUTPUTS (checker_outputs, "CHECKER_OUTPUT");

  SAFE_FREE (output);
}
Example #19
0
/**
 * Main testing thread
 */
static void
testing_thread (gpointer __data, gpointer __user_data)
{
  wt_task_t *task = __data;

  char pchar[65536];

  /* Directories for current testing stuff */
  char cur_testing_dir[4096];
  char cur_data_dir[4096];
  char lock_file[4096];

  int points = 0, rc;
  char errors[MAX_TESTS * (MAX_ERRCODE + 1)];
  FILE *stream;

  assarr_t *all_params;

  /* Update status of the task */
  TASK_SET_STATUS (*task, TS_RUNNING);

  INF_DEBUG_LOG ("Started new thread for testing task %ld\n", task->sid);

  all_params = assarr_create ();

  /* Calculating current testing and data directories */
  snprintf (cur_testing_dir, BUF_SIZE (cur_testing_dir),
            "%s/%ld", testing_dir, task->sid);
  snprintf (cur_data_dir, BUF_SIZE (cur_data_dir), "%s/%s/%s", data_dir,
            problems_dir, (char*) TASK_INPUT_PARAM (*task, "PROBLEMID"));

  /* Delete all unwanted data */
  unlinkdir (cur_testing_dir);

  /* Create global testing root. */
  /* Deny reading of this root to deny getting listing of this catalogue */
  /* to executable solutions. */
  fmkdir (testing_dir, 00773);

  /* Create current testing directory */
  mutex_lock (lck_mutex);
  snprintf (lock_file, BUF_SIZE (lock_file), "%s/lock", cur_testing_dir);
  fmkdir (cur_testing_dir, 00777);
  flock_set (lock_file);
  mutex_unlock (lck_mutex);

  /* Some initialization */
  points = 0;
  strcpy (errors, "");

  /* Start logging */
  print_common_info (task);

  /*
   * TODO: Add TASK_SET_RESULT_MESSAGE() in case of testing crash
   */

  INF_DEBUG_LOG ("Task %ld. Check for required parameters\n", task->sid);

  /* Check for required data */
  if (!check_required_params (task, pchar))
    {
      strcpy (errors, "CR");
      TASK_LOG (*task, "\n========\n"
                       "Fatal error: Required params aren't defined: %s! "
                       "Testing aborted.\n", pchar);
      REPORT (all_params, "Required params aren't defined: %s.", pchar);
      goto __done_;
    }

  /****
   * TESTING STUFF
   */

  /*
   * Step 0: Saving solution source to file
   */

  INF_DEBUG_LOG ("Task %ld. Step 0: Save solution\n", task->sid);

  if (!save_solution (task, cur_testing_dir))
    {
      strcpy (errors, "CR");
      TASK_LOG (*task, "\n========\nFatal error: unable to save solution! "
                        "Testing aborted.\n");
      REPORT (all_params, "Error saving solution.");
      goto __done_;
    }

  /*
   * Step 1: Compiling colution
   */
  INF_DEBUG_LOG ("Task %ld. Step 1: Compile solution\n", task->sid);

  rc = compile_solution (task, cur_testing_dir, cur_data_dir, all_params);

  TESTING_CHECK_ACTIVE;

  if (rc < 0)
    {
      /* Fatal errors while compile */
      INF_DEBUG_LOG ("[EE] Task %ld. Ctirical error during solution "
                     "compilation process\n");
      points = 0;
      strcpy (errors, "CR");
      TASK_LOG (*task, "\n========\nFatal error while compiling solution. "
                       "Testing aborted.\n");
      goto __done_;
    }

  if (!rc)
    {
      /* Simple compilation error */
      points = 0;
      strcpy (errors, "CE");
      goto __done_;
    }

  /*
   * Step 2: Exec solution at all tests
   */
  testing_main_loop (task, cur_data_dir, cur_testing_dir,
                     &points, errors, all_params);

  TESTING_CHECK_ACTIVE;

__done_:

  /* Updating avaliable parameters */
  snprintf (pchar, BUF_SIZE (pchar), "%d", points);
  assarr_set_value (all_params, "POINTS", strdup (pchar));
  assarr_set_value (all_params, "ERRORS", strdup (errors));

  /* Set output parameters for WebInterface */
  set_output_params (task, all_params);

  /* Some uinitialization */
  assarr_destroy (all_params, assarr_deleter_free_ref_data);

  if (strcmp (errors, "OK"))
    {
      snprintf (pchar, BUF_SIZE (pchar), "Points: %d. Errors: %s",
                points, errors);
    }
  else
    {
      int bonus = atoi (TASK_INPUT_PARAM (*task, "BONUS"));
      snprintf (pchar, BUF_SIZE (pchar), "Points: %d. Bonus: %d",
                points - bonus, bonus);
    }
  TASK_SET_RESULT_MESSAGE (*task, pchar);

  if (strcmp (errors, "CE") && strcmp (errors, "CR"))
    {
      TASK_LOG (*task, "\n========\nTesting completed: %s\n", pchar);
    }

  /* Save log */
  snprintf (pchar, BUF_SIZE (pchar), "%s/%s",
            cur_testing_dir, SOLUTION_ERRORS_LOG);
  stream = fopen (pchar, "w");
  if (stream)
    {
      fprintf (stream, "%s", log_banner);
      TASK_LOG_FLUSH (*task, stream);
      fclose (stream);
    }
  chmod (pchar, 00660);

  INF_DEBUG_LOG ("Task %ld tested\n", task->sid);

  /* Now task is completely tested */
  TASK_SET_STATUS (*task, TS_FINISHED);

  goto __all_done_;

__free_:
  assarr_destroy (all_params, assarr_deleter_free_ref_data);
  TASK_SET_STATUS (*task, TS_INTERRUPTED);

__all_done_:
  flock_clear (lock_file);

  unlink_unwanted_testing_dirs ();

  INF_DEBUG_LOG ("Leave testing thread\n");
}
Example #20
0
void MD_MFTrack::parseEvent(MD_MIDIFile *mf)
// process the event from the physical file
{
	uint8_t	 eType;
	uint32_t eLen, mLen;
	sysex_event	sev;		// used for sysex callback function

	// now we have to process this event
	eType = mf->_fd.read();

	switch (eType)
	{
// ---------------------------- MIDI

	  // midi_event = any MIDI channel message, including running status
	  // Midi events (status bytes 0x8n - 0xEn) The standard Channel MIDI messages, where 'n' is the MIDI channel (0 - 15).
	  // This status byte will be followed by 1 or 2 data bytes, as is usual for the particular MIDI message. 
	  // Any valid Channel MIDI message can be included in a MIDI file.
	case 0x80 ... 0xBf:	// MIDI message with 2 parameters
	case 0xe0 ... 0xef:
		_mev.size = 3;
		_mev.data[0] = eType;
		_mev.channel = _mev.data[0] & 0xf;	// mask off the channel
		_mev.data[0] = _mev.data[0] & 0xf0;	// just the command byte
		_mev.data[1] = mf->_fd.read();
		_mev.data[2] = mf->_fd.read();
		DUMP("[MID2] Ch: ", _mev.channel);
		DUMPX(" Data: ", _mev.data[0]);
		DUMPX(" ", _mev.data[1]);
		DUMPX(" ", _mev.data[2]);
#if !DUMP_DATA
		if (mf->_midiHandler != NULL)
			(mf->_midiHandler)(&_mev);
#endif // !DUMP_DATA
	break;

	case 0xc0 ... 0xdf:	// MIDI message with 1 parameter
		_mev.size = 2;
		_mev.data[0] = eType;
		_mev.channel = _mev.data[0] & 0xf;	// mask off the channel
		_mev.data[0] = _mev.data[0] & 0xf0;	// just the command byte
		_mev.data[1] = mf->_fd.read();
		DUMP("[MID1] Ch: ", _mev.channel);
		DUMPX(" Data: ", _mev.data[0]);
		DUMPX(" ", _mev.data[1]);

#if !DUMP_DATA
		if (mf->_midiHandler != NULL)
			(mf->_midiHandler)(&_mev);
#endif
	break;

	case 0x00 ... 0x7f:	// MIDI run on message
	{
	  // If the first (status) byte is less than 128 (0x80), this implies that MIDI 
	  // running status is in effect, and that this byte is actually the first data byte 
	  // (the status carrying over from the previous MIDI event). 
	  // This can only be the case if the immediately previous event was also a MIDI event, 
	  // ie SysEx and Meta events clear running status. This means that the _mev structure 
	  // should contain the info from the previous message in the structure's channel member 
	  // and data[0] (for the MIDI command). 
	  // Hence start saving the data at byte data[1] with the byte we have just read (eType) 
	  // and use the size member to determine how large the message is (ie, same as before).
	  _mev.data[1] = eType;
	  for (uint8_t i = 2; i < _mev.size; i++)
	  {
		  _mev.data[i] = mf->_fd.read();	// next byte
	  }	

	  DUMP("[MID+] Ch: ", _mev.channel);
	  DUMPS(" Data:");
	  for (uint8_t i = 0; i<_mev.size; i++)
	  {
  		DUMPX(" ", _mev.data[i]);
	  }

#if !DUMP_DATA
	  if (mf->_midiHandler != NULL)
		  (mf->_midiHandler)(&_mev);
#endif
	}
	break;
	  
// ---------------------------- SYSEX

	case 0xf0:		// sysex_event = 0xF0 + <len:1> + <data_bytes> + 0xF7 
	case 0xf7:		// sysex_event = 0xF7 + <len:1> + <data_bytes> + 0xF7 
	{
 		uint8_t	c, i;
		sysex_event sev;

		// collect all the bytes until the 0xf7 - boundaries are included in the message
		sev.track = _trackId;
		sev.data[0] = eType;
		sev.size = mf->_fd.read();
		// The length parameter includes the 0xF7 but not the start boundary. 
		// However, it may be bigger than our buffer will allow us to store.
		sev.size = (sev.size > BUF_SIZE(sev.data) - 2 ? BUF_SIZE(sev.data) - 2 : sev.size + 1);
		for (i = 1; (i < sev.size) && (c != 0xf7); i++)
		{
			c = mf->_fd.read();	// next char
			sev.data[i] = c;
		}	

		// check if we had an overflow
		if (c != 0xf7)
		{
			while ((c = mf->_fd.read()) != 0xf7)
				; // skip read all data
			sev.data[sev.size] = 0xf7;		// terminate properly - data is probably nuked anyway
		}

		DUMPS("[SYSX] Data:");
		for (uint8_t i = 0; i<sev.size; i++)
		{
  			DUMPX(" ", sev.data[i]);
		}

#if !DUMP_DATA
		if (mf->_sysexHandler != NULL)
			(mf->_sysexHandler)(&sev);
#endif
	}
	break;

// ---------------------------- META

	case 0xff:		// meta_event = 0xFF + <meta_type:1> + <length:v> + <event_data_bytes>
	  eType = mf->_fd.read();
	  mLen =  readVarLen(&mf->_fd);
	  DUMPX("[META] Type: 0x", eType);
	  DUMP("\tLen: ", mLen);
	  DUMPS("\t");

	  switch (eType)
	  {
	  case 0x2f:	// End of track
		_endOfTrack = true;
	  DUMPS("END OF TRACK");
	  break;

	  case 0x51:	// set Tempo - really the microseconds per tick
		mf->setMicrosecondPerQuarterNote(readMultiByte(&mf->_fd, MB_TRYTE));
		DUMP("SET TEMPO to ", mf->getTickTime());
		DUMP(" us/tick or ", mf->getTempo());
		DUMPS(" beats/min");
	  break;

	  case 0x58:	// time signature
		mf->setTimeSignature(mf->_fd.read(), (1 << mf->_fd.read()));	// denominator is 2^n
		mf->_fd.seekCur(mLen-2);
		DUMP("SET TIME SIGNATURE to ", mf->getTimeSignature()>>8);
		DUMP("/", mf->getTimeSignature()&0xf);
	  break;

#if SHOW_UNUSED_META
	  case 0x0:	// Sequence Number
		DUMP("SEQUENCE NUMBER ", readMultiByte(&mf->_fd, MB_WORD));
	  break;

	  case 0x1:	// Text
		DUMPS("TEXT ");
		for (int i=0; i<mLen; i++)
			DUMP("", (char)mf->_fd.read());
	  break;

	  case 0x2:	// Copyright Notice
		DUMPS("COPYRIGHT ");
		for (uint8_t i=0; i<mLen; i++)
			DUMP("", (char)mf->_fd.read());
	  break;

	  case 0x3:	// Sequence or Track Name
		DUMPS("SEQ/TRK NAME ");
		for (uint8_t i=0; i<mLen; i++)
			DUMP("", (char)mf->_fd.read());
	  break;

	  case 0x4:	// Instrument Name
		DUMPS("INSTRUMENT ");
		for (uint8_t i=0; i<mLen; i++)
			DUMP("", (char)mf->_fd.read());
	  break;

	  case 0x5:	// Lyric
		DUMPS("LYRIC ");
		for (uint8_t i=0; i<mLen; i++)
			DUMP("", (char)mf->_fd.read());
	  break;

	  case 0x6:	// Marker
		DUMPS("MARKER ");
		for (uint8_t i=0; i<mLen; i++)
			DUMP("", (char)mf->_fd.read());
	  break;

	  case 0x7:	// Cue Point
		DUMPS("CUE POINT ");
		for (uint8_t i=0; i<mLen; i++)
			DUMP("", (char)mf->_fd.read());
	  break;

	  case 0x20:// Channel Prefix
		DUMP("CHANNEL PREFIX ", readMultiByte(&mf->_fd, MB_BYTE));
	  break;

	  case 0x21:// Port Prefix
		DUMP("PORT PREFIX ", readMultiByte(&mf->_fd, MB_BYTE));
	  break;

	  case 0x54:// SMPTE Offset
		DUMPS("SMPTE OFFSET");
		for (uint8_t i=0; i<mLen; i++)
		{
			DUMP(" ", mf->_fd.read());
		}
	  break;

	  case 0x59:// Key Signature
		DUMPS("KEY SIGNATURE");
		for (uint8_t i=0; i<mLen; i++)
		{
			DUMP(" ", mf->_fd.read());
		}
	  break;

	  case 0x7F:	// Sequencer Specific Metadata
		DUMPS("SEQ SPECIFIC");
		for (uint8_t i=0; i<mLen; i++)
		{
			DUMPX(" ", mf->_fd.read());
		}
	  break;
#endif // SHOW_UNUSED_META

	  default:
		  mf->_fd.seekCur(mLen);
		  DUMPS("IGNORED");
	  }
	  break;

// ---------------------------- UNKNOWN

	default:
		// stop playing this track as we cannot identify the eType
		_endOfTrack = true;	
		DUMPX("[UKNOWN 0x", eType);
		DUMPS("] Track aborted");
	}
}