Index: common/db/job.php
===================================================================
--- common/db/job.php	(revision 909)
+++ common/db/job.php	(working copy)
@@ -41,12 +41,7 @@
        `job`.`compiler_id`, `job`.`status`, `job`.`submit_time`,
        `job`.`eval_message`, `job`.`score`, `job`.`file_contents`
     FROM `ia_job` AS `job`
-    INNER JOIN `ia_user` AS `user` ON `user`.`id` = `job`.`user_id`
-    LEFT JOIN `ia_round` AS `round` ON `round`.`id` = `job`.`round_id`
     WHERE (`status` != 'done')
-      AND ((`round`.`allow_eval` = TRUE) OR
-           (`round`.`id` IS NULL) OR
-           (`user`.`security_level` = 'admin'))
     ORDER BY `submit_time` ASC LIMIT 1
 SQL;
     return db_fetch($query);
@@ -86,14 +81,15 @@
     $field_list = "`job`.`id`, job.`user_id`, `job`.`compiler_id`, `job`.`status`,
                    `job`.`submit_time`, `job`.`eval_message`, `job`.`score`, `job`.`eval_log`,
                    OCTET_LENGTH(`job`.`file_contents`) AS `job_size`,
-                   `user`.`username` as `user_name`, `user`.`full_name` as `user_fullname`,
+                   `user`.`username` AS `user_name`, `user`.`full_name` AS `user_fullname`,
                    `task`.`id` AS `task_id`,
                    `task`.`page_name` AS `task_page_name`, task.`title` AS `task_title`,
                    `task`.`hidden` AS `task_hidden`, `task`.`user_id` AS `task_owner_id`,
                    `task`.`open_source` AS `task_open_source`,
                    `task`.`open_tests` AS `task_open_tests`,
                    `round`.`id` AS `round_id`,
-                   `round`.`page_name` AS `round_page_name`, `round`.`title` AS `round_title`";
+                   `round`.`page_name` AS `round_page_name`, `round`.`title` AS `round_title`,
+                   `round`.`public_eval` AS `round_public_eval`";
     if ($contents) {
         $field_list .= ", job.file_contents";
     }
@@ -121,6 +117,13 @@
                     ON `job`.`user_id` = `user`.`id`";
     }
 
+    // score_begin and score_end filters shouldn't work on rounds
+    // without public eval, so we join with ia_round
+    if (getattr($filters, 'score_begin') || getattr($filters, 'score_end')) {
+        $sql .= "\nLEFT JOIN `ia_round` AS `round`
+                    ON `job`.`round_id` = `round`.`id`";
+    }
+
     return $sql;
 }
 
@@ -176,10 +179,10 @@
         $wheres[] = sprintf("`job`.`status` = '%s'", db_escape($status));
     }
     if (!is_null($score_begin) && is_whole_number($score_begin)) {
-        $wheres[] = sprintf("`job`.`score` >= '%s'", db_escape($score_begin));
+        $wheres[] = sprintf("(`job`.`score` >= '%s') AND (`round`.`public_eval` = 1)", db_escape($score_begin));
     }
     if (!is_null($score_end) && is_whole_number($score_end)) {
-        $wheres[] = sprintf("`job`.`score` <= '%s'", db_escape($score_end));
+        $wheres[] = sprintf("(`job`.`score` <= '%s') AND (`round`.`public_eval` = 1)", db_escape($score_end));
     }
     if (!is_null($eval_msg)) {
         $wheres[] = sprintf("`job`.`eval_message` LIKE '%s%%'", db_escape($eval_msg));
@@ -199,9 +202,9 @@
     log_assert($range >= 0);
     $query = <<<SQL
 SELECT `job`.`id`,
-       `job`.`user_id` as `user_id`,
-       `job`.`round_id` as `round_id`,
-       `job`.`task_id` as `task_id`, 
+       `job`.`user_id` AS `user_id`,
+       `job`.`round_id` AS `round_id`,
+       `job`.`task_id` AS `task_id`, 
        `job`.`submit_time`, 
        `job`.`compiler_id`, 
        `job`.`status`,
@@ -217,7 +220,8 @@
        `task`.`user_id` AS `task_owner_id`,
        `task`.`open_source` AS `task_open_source`,
        `round`.`page_name` AS `round_page_name`, 
-       `round`.`title` AS `round_title`
+       `round`.`title` AS `round_title`,
+       `round`.`public_eval` AS `round_public_eval`
 #       (CASE WHEN `status` = 'processing' THEN
 #                (SELECT `value` FROM `ia_parameter_value`
 #                 WHERE `ia_parameter_value`.`object_id` = `task_id` AND
@@ -241,10 +245,10 @@
     return db_fetch_all($query);
 }
 
-// Counts jobs based on complex filterss
+// Counts jobs based on complex filters
 function job_get_count($filters) {
     $query = <<<SQL
-SELECT COUNT(*) as `cnt`
+SELECT COUNT(*) AS `cnt`
       FROM `ia_job` AS `job`
 SQL;
 
Index: common/db/score.php
===================================================================
--- common/db/score.php	(revision 909)
+++ common/db/score.php	(working copy)
@@ -60,10 +60,26 @@
         }
     }
     if ($round != null) {
+        if (is_string($round))
+            $round = array($round);
+
         if (is_array($round) && count($round) > 0) {
-            $where[] = "(`round_id` IN (" . db_escape_array($round) . "))";
-        } else if (is_string($round)) {
-            $where[] = sprintf("(`round_id` = '%s')", $round);
+            $rounds_where = "(`id` IN (" . db_escape_array($round) . "))";
+            $query = "SELECT `id`, `state`, `public_eval` FROM `ia_round` WHERE " . $rounds_where;
+            $round_objects = db_fetch_all($query);
+            $allowed_round_ids = array();
+
+            foreach ($round_objects as $round) {
+                if (identity_can('round-view-scores', $round)) {
+                    $allowed_round_ids[] = $round["id"];
+                }
+            }
+
+            if (count($allowed_round_ids) == 0) {
+                $where[] = "(TRUE = FALSE)";
+            } else {
+                $where[] = "(`round_id` IN (" . db_escape_array($allowed_round_ids) . "))";
+            }
         }
     }
 
@@ -89,8 +105,8 @@
     $where = score_build_where_clauses($user, $task, $round);
     $where[] = sprintf("ia_score.`name` = '%s'", db_escape($score_name));
     $query = sprintf("SELECT
-                ia_score.`name` as `score_name`, `user_id`, `task_id`, `round_id`, SUM(`score`) as score, 
-                ia_user.username as user_name, ia_user.full_name as user_full,
+                ia_score.`name` AS `score_name`, `user_id`, `task_id`, `round_id`, SUM(`score`) AS score, 
+                ia_user.username AS user_name, ia_user.full_name AS user_full,
                 ia_user.rating_cache AS user_rating
             FROM ia_score
                 LEFT JOIN ia_user ON ia_user.id = ia_score.user_id
@@ -106,7 +122,7 @@
         // in the requested range.
         $where = score_build_where_clauses($user, $task, $round);
         $where[] = sprintf("ia_score.`name` = '%s'", db_escape($score_name));
-        $query = sprintf("SELECT SUM(`score`) as score 
+        $query = sprintf("SELECT SUM(`score`) AS score 
                           FROM ia_score
                           WHERE %s GROUP BY %s
                           HAVING score > %s",
@@ -143,7 +159,7 @@
     } else {
         $join = "";
     }
-    $query = sprintf("SELECT COUNT(DISTINCT user_id) as `cnt`
+    $query = sprintf("SELECT COUNT(DISTINCT user_id) AS `cnt`
             FROM ia_score $join
             WHERE %s",
             join($where, " AND "), $groupby);
@@ -403,7 +419,7 @@
     $rows = db_fetch_all($query);
 
     if ($with_rankings && count($rows)) {
-        $query = sprintf("SELECT `rating_cache` as rating_cache
+        $query = sprintf("SELECT `rating_cache` AS rating_cache
                           FROM ia_user
                           WHERE rating_cache > 1.5 + 3 * ROUND(%s/3)
                           AND security_level != 'admin'",
@@ -433,7 +449,7 @@
 
 // Count function for get_users_by_rating_range.
 function get_users_by_rating_count() {
-    $query = "SELECT COUNT(*) as `cnt`
+    $query = "SELECT COUNT(*) AS `cnt`
         FROM `ia_user`
         WHERE `rating_cache` > 0
         AND `security_level` != 'admin'";
Index: common/db/user.php
===================================================================
--- common/db/user.php	(revision 909)
+++ common/db/user.php	(working copy)
@@ -227,14 +227,13 @@
         log_error('You can\'t select nothing.');
     }
 
-    $query = "SELECT *
+    $query = sprintf("SELECT *
         FROM ia_score
         LEFT JOIN ia_task ON ia_task.id = ia_score.task_id
         WHERE ia_score.`name` = 'score' AND ia_score.user_id = '%s'
               AND ia_score.round_id = 'arhiva' AND NOT ia_task.id IS NULL %s
         GROUP BY ia_task.id
-        ORDER BY ia_task.`order`";
-    $query = sprintf($query, $user_id, $where);
+        ORDER BY ia_task.`order`", $user_id, $where);
 
     return db_fetch_all($query);
 }
Index: common/round.php
===================================================================
--- common/round.php	(revision 909)
+++ common/round.php	(working copy)
@@ -67,7 +67,8 @@
             'title' => $round_id,
             'page_name' => IA_ROUND_TEXTBLOCK_PREFIX . $round_id,
             'state' => 'waiting',
-            'start_time' => NULL
+            'start_time' => NULL,
+            'public_eval' => (($round_type == 'archive') ? 1 : 0)
     );
 
     log_assert_valid(round_validate($round));
@@ -100,6 +101,10 @@
         $errors['state'] = "Starea rundei este invalida";
     }
 
+    if (!is_whole_number(getattr($round, 'public_eval'))) {
+        $errors['public_eval'] = "public_eval este invalid";
+    }
+
     // NULL is ok here.
     if (!is_db_date(getattr($round, 'start_time', db_date_format()))) {
         $errors['start_time'] = "Timpul trebuie specificat ca YYYY-MM-DD HH:MM:SS";
@@ -113,7 +118,6 @@
     log_assert_valid(round_validate($round));
     log_print("CONTEST LOGIC: Starting round {$round['id']}.");
     $round['state'] = 'running';
-    $round['allow_eval'] = 0;
     round_update($round);
     round_unhide_all_tasks($round['id']);
 }
@@ -123,7 +127,7 @@
     log_assert_valid(round_validate($round));
     log_print("CONTEST LOGIC: Stopping round {$round['id']}.");
     $round['state'] = 'complete';
-    $round['allow_eval'] = 1;
+    $round['public_eval'] = 1;
     round_update($round);
 }
 
@@ -132,7 +136,6 @@
     log_assert_valid(round_validate($round));
     log_print("CONTEST LOGIC: Stand-by for round {$round['id']}.");
     $round['state'] = 'waiting';
-    $round['allow_eval'] = 0;
     round_update($round);
     round_hide_all_tasks($round['id']);
 }
Index: common/security.php
===================================================================
--- common/security.php	(revision 909)
+++ common/security.php	(working copy)
@@ -147,13 +147,15 @@
         case 'task-submit':
         case 'round-submit':
         case 'round-view-tasks':
+        case 'round-view-scores':
         case 'round-register':
         case 'user-editprofile':
         case 'user-change-security':
         case 'user-tag':
         case 'job-view':
         case 'job-eval':
-        case 'job-view-source': 
+        case 'job-view-source':
+        case 'job-view-score':
             return $action;
 
         default:
@@ -431,6 +433,8 @@
 
         case 'round-view-tasks':
             return $round['state'] != 'waiting' || $is_admin;
+        case 'round-view-scores':
+            return $round['public_eval'] == true || $is_admin;
 
         case 'simple-rev-edit':
         case 'simple-edit':
@@ -511,6 +515,7 @@
     $is_task_owner = ($job['task_owner_id'] == $user['id'] && $usersec == 'helper');
     $can_view_job = ($job['task_hidden'] == false) || $is_task_owner || $is_admin;
     $can_view_source = ($job['task_open_source'] == true) || $is_task_owner || $is_owner || $is_admin;
+    $can_view_score = ($job['round_public_eval'] == true) || $is_task_owner || $is_admin;
 
     // Log query response.
     $action = security_simplify_action($action);
@@ -532,6 +537,9 @@
         case 'job-view-source': 
             return $can_view_job && $can_view_source;
 
+        case 'job-view-score':
+            return $can_view_job && $can_view_score;
+
         default:
             log_error('Invalid job action: '.$action);
     }
Index: scripts/live-eval
===================================================================
--- scripts/live-eval	(revision 0)
+++ scripts/live-eval	(revision 0)
@@ -0,0 +1,8 @@
+#! /usr/bin/env php
+<?php
+require_once(dirname($argv[0]) . "/utilities.php");
+
+db_connect();
+$query = "ALTER TABLE `ia_round` CHANGE COLUMN `allow_eval` `public_eval` TINYINT(1) NOT NULL DEFAULT 0;";
+db_query($query);
+?>
Index: www/controllers/job_detail.php
===================================================================
--- www/controllers/job_detail.php	(revision 909)
+++ www/controllers/job_detail.php	(working copy)
@@ -35,28 +35,34 @@
 
     $view['title'] = 'Borderou de evaluare (job #'.$job_id.')';
     $view['job'] = $job;
-    $view['tests'] = job_test_get_all($job_id);
     $view['group_count'] = 0;
-    foreach ($view['tests'] as $test) {
-        $view['group_count'] = max($view['group_count'], $test['test_group']);
-    }
-    for ($group = 1; $group <= $view['group_count']; $group++) {
-        $view['group_score'][$group] = 0;
-        $view['group_size'][$group] = 0;
-        $solved_group = true;
+    $view['tests'] = array();
+
+    if (identity_can('job-view-score', $job)) {
+        $view['tests'] = job_test_get_all($job_id);
         foreach ($view['tests'] as $test) {
-            if ($test['test_group'] != $group) {
-                continue;
+            $view['group_count'] = max($view['group_count'], $test['test_group']);
+        }
+        for ($group = 1; $group <= $view['group_count']; $group++) {
+            $view['group_score'][$group] = 0;
+            $view['group_size'][$group] = 0;
+            $solved_group = true;
+            foreach ($view['tests'] as $test) {
+                if ($test['test_group'] != $group) {
+                    continue;
+                }
+                $view['group_score'][$group] += $test['points'];
+                $view['group_size'][$group]++;
+                if (!$test['points']) {
+                    $solved_group = false;
+                }
             }
-            $view['group_score'][$group] += $test['points'];
-            $view['group_size'][$group]++;
-            if (!$test['points']) {
-                $solved_group = false;
+            if (!$solved_group) {
+                $view['group_score'][$group] = 0;
             }
         }
-        if (!$solved_group) {
-            $view['group_score'][$group] = 0;
-        }
+    } else {
+        $view['job']['score'] = "Ascuns";
     }
 
     if (!$view['job']['eval_message']) {
Index: www/controllers/round.php
===================================================================
--- www/controllers/round.php	(revision 909)
+++ www/controllers/round.php	(working copy)
@@ -59,6 +59,7 @@
     $values['title'] = request('title', $round['title']);
     $values['page_name'] = request('page_name', $round['page_name']);
     $values['start_time'] = request('start_time', $round['start_time']);
+    $values['public_eval'] = request('public_eval', $round['public_eval']);
 
     // Get tasks. SHIT FUCK DAMN;
     // It seems we can't find out if the user submitted anything at all.
@@ -93,6 +94,7 @@
     $new_round['title'] = $values['title'];
     $new_round['page_name'] = $values['page_name'];
     $new_round['start_time'] = $values['start_time'];
+    $new_round['public_eval'] = $values['public_eval'];
 
     $errors = round_validate($new_round);
 
Index: www/macros/macro_tasks.php
===================================================================
--- www/macros/macro_tasks.php	(revision 909)
+++ www/macros/macro_tasks.php	(working copy)
@@ -94,7 +94,7 @@
     }
 
 
-    $scores = !is_null(getattr($args, 'score'));
+    $scores = !is_null(getattr($args, 'score')) && identity_can("round-view-scores", $round);
     if (identity_is_anonymous() || $scores == false) {
         $user_id = null;
     } else {
@@ -102,8 +102,11 @@
     }
 
     $filter = request('filtru', '');
-    if ($user_id) {
+    $tabs = '';
+    if ($user_id && identity_can("round-view-scores", $round)) {
         $tabs = task_list_tabs($filter);
+    } else {
+        $filter = '';
     }
 
     $show_numbers = getattr($args, 'show_numbers', false);
Index: www/views/monitor.php
===================================================================
--- www/views/monitor.php	(revision 909)
+++ www/views/monitor.php	(working copy)
@@ -67,8 +67,12 @@
     function format_state($row) {
         $url = url_job_detail($row['id']);
         if ($row['status'] == 'done') {
-            $msg = htmlentities(sprintf("%s: %s puncte",
+            if (identity_can("job-view-score", $row)) {
+                $msg = htmlentities(sprintf("%s: %s puncte",
                     $row['eval_message'], $row['score']));
+            } else {
+                $msg = htmlentities( $row['eval_message'] );
+            }
             $msg = "<span style=\"job-status-done\">$msg</span>";
             return format_link($url, $msg, false);
         }
Index: www/views/round_edit.php
===================================================================
--- www/views/round_edit.php	(revision 909)
+++ www/views/round_edit.php	(working copy)
@@ -57,6 +57,12 @@
                 'values' => round_get_types(),
                 'default' => 'classic',
         ),
+        'public_eval' => array(
+                'name' => 'Evaluare publica',
+                'description' => "Concurentii pot vedea scorul obtinut la sursele trimise",
+                'default' => '0',
+                'type' => 'bool',
+        ),
 );
 ?>
 
@@ -91,6 +97,7 @@
   <legend>Parametri</legend>
   <ul class="form">
    <?= view_form_field_li($form_fields['type'], 'type') ?>
+   <?= view_form_field_li($form_fields['public_eval'], 'public_eval') ?>
    <li><hr /></li>
    <li id="field_params">
     <?= format_param_editor_list(
