/** * 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; }
/** * 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; } }
/** * 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); }
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); }
/** * 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); }
/* 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)); }
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; }
/** * 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++; } }
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; } } }
/** * 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; }
/** * 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; }
/** * 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); } }
/** * 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; }
/** * 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; }
/** * 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; }
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); }
/** * 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"); }
/* * 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); }
/** * 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"); }
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"); } }