Ejemplo n.º 1
0
/* remove VLAN header from packet and update csum accordingly. */
static int __pop_vlan_tci(struct sk_buff *skb, __be16 *current_tci)
{
	struct vlan_hdr *vhdr;
	int err;

	err = make_writable(skb, VLAN_ETH_HLEN);
	if (unlikely(err))
		return err;

	if (get_ip_summed(skb) == OVS_CSUM_COMPLETE)
		skb->csum = csum_sub(skb->csum, csum_partial(skb->data
					+ ETH_HLEN, VLAN_HLEN, 0));

	vhdr = (struct vlan_hdr *)(skb->data + ETH_HLEN);
	*current_tci = vhdr->h_vlan_TCI;

	memmove(skb->data + VLAN_HLEN, skb->data, 2 * ETH_ALEN);
	__skb_pull(skb, VLAN_HLEN);

	vlan_set_encap_proto(skb, vhdr);
	skb->mac_header += VLAN_HLEN;
	skb_reset_mac_len(skb);

	return 0;
}
Ejemplo n.º 2
0
void
set_drmarker_hotp_policy_status_table(void *new_table)
{
    dr_marker_t *dr_marker = get_drmarker();

    ASSERT_OWN_WRITE_LOCK(true, hotp_get_lock());

    /* We don't want to write to the dr_marker_t before it is initialized;  we
     * could get an exception.
     */
    if (dr_marker == NULL)      /* Part of fix for case 5367. */
        return;
    /* Ok, dr_marker_t has been initialized. */

    /* It is ok to do this memory protection change here even though this can
     * be any arbitrary time due to the nature of nudge.  This is because
     * once initialized, the dr_marker_t isn't touched by any one except the hot
     * patch nudge.
     *
     * TODO: In future other parts of the core may need to change the dr_marker_t.
     *       It might be a good idea to introduce a lock for the dr_marker_t and
     *       generic accessor functions.
     */
    make_writable((byte*)dr_marker, INTERCEPTION_CODE_SIZE);
    dr_marker->dr_hotp_policy_status_table = new_table;
    make_unwritable((byte*)dr_marker, INTERCEPTION_CODE_SIZE);
}
Ejemplo n.º 3
0
static int set_ipv4(struct sk_buff *skb, const struct ovs_key_ipv4 *ipv4_key)
{
	struct iphdr *nh;
	int err;

	err = make_writable(skb, skb_network_offset(skb) +
				 sizeof(struct iphdr));
	if (unlikely(err))
		return err;

	nh = ip_hdr(skb);

	if (ipv4_key->ipv4_src != nh->saddr)
		set_ip_addr(skb, nh, &nh->saddr, ipv4_key->ipv4_src);

	if (ipv4_key->ipv4_dst != nh->daddr)
		set_ip_addr(skb, nh, &nh->daddr, ipv4_key->ipv4_dst);

	if (ipv4_key->ipv4_tos != nh->tos)
		ipv4_change_dsfield(nh, 0, ipv4_key->ipv4_tos);

	if (ipv4_key->ipv4_ttl != nh->ttl)
		set_ip_ttl(skb, nh, ipv4_key->ipv4_ttl);

	return 0;
}
Ejemplo n.º 4
0
/* remove VLAN header from packet and update csum accordingly. */
static int __pop_vlan_tci(struct sk_buff *skb, __be16 *current_tci)
{
	struct vlan_hdr *vhdr;
	int err;

	err = make_writable(skb, VLAN_ETH_HLEN);
	if (unlikely(err))
		return err;

	if (skb->ip_summed == CHECKSUM_COMPLETE)
		skb->csum = csum_sub(skb->csum, csum_partial(skb->data
					+ (2 * ETH_ALEN), VLAN_HLEN, 0));

	vhdr = (struct vlan_hdr *)(skb->data + ETH_HLEN);
	*current_tci = vhdr->h_vlan_TCI;

	memmove(skb->data + VLAN_HLEN, skb->data, 2 * ETH_ALEN);
	__skb_pull(skb, VLAN_HLEN);

	vlan_set_encap_proto(skb, vhdr);
	skb->mac_header += VLAN_HLEN;
	/* Update mac_len for subsequent MPLS actions */
	skb->mac_len -= VLAN_HLEN;

	return 0;
}
Ejemplo n.º 5
0
static int pop_mpls(struct sk_buff *skb, const __be16 ethertype)
{
	struct ethhdr *hdr;
	int err;

	err = make_writable(skb, skb->mac_len + MPLS_HLEN);
	if (unlikely(err))
		return err;

	if (skb->ip_summed == CHECKSUM_COMPLETE)
		skb->csum = csum_sub(skb->csum,
				     csum_partial(mac_header_end(skb),
						  MPLS_HLEN, 0));

	memmove(skb_mac_header(skb) + MPLS_HLEN, skb_mac_header(skb),
		skb->mac_len);

	__skb_pull(skb, MPLS_HLEN);
	skb_reset_mac_header(skb);

	/* mac_header_end() is used to locate the ethertype
	 * field correctly in the presence of VLAN tags.
	 */
	hdr = (struct ethhdr *)(mac_header_end(skb) - ETH_HLEN);
	hdr->h_proto = ethertype;
	if (eth_p_mpls(skb->protocol))
		skb->protocol = ethertype;
	return 0;
}
Ejemplo n.º 6
0
void addr_cache_init(os_exception_frame_t *frame)
{
    (void) frame;

    // Only run this if not already initialized
    if(addr_cache)
        return;

    addr_cache = mmap((void*)0, AC_NUM_ENTRIES * sizeof(ac_entry), PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0);
    if(addr_cache == MAP_FAILED)
    {
        addr_cache = NULL;
        fprintf(stderr, "Failed to mmap addr_cache.\n");
        exit(1);
    }

    setbuf(stdout, NULL);

    unsigned int i;
    for(i = 0; i < AC_NUM_ENTRIES; ++i)
    {
        AC_SET_ENTRY_INVALID(addr_cache[i], (i >> 1) << 10)
    }

#if defined(__i386__) && !defined(NO_TRANSLATION)
    // Relocate the assembly code that wants addr_cache at a fixed address
    extern uint32_t *ac_reloc_start[] __asm__("ac_reloc_start"), *ac_reloc_end[] __asm__("ac_reloc_end");
    uint32_t **reloc;
    for(reloc = ac_reloc_start; reloc != ac_reloc_end; reloc++)
    {
        make_writable(*reloc);
        **reloc += (uintptr_t)addr_cache;
    }
#endif
}
Ejemplo n.º 7
0
static int set_eth_addr(struct sk_buff *skb,
			const struct ovs_key_ethernet *eth_key)
{
	int err;
	err = make_writable(skb, ETH_HLEN);
	if (unlikely(err))
		return err;

	memcpy(eth_hdr(skb)->h_source, eth_key->eth_src, ETH_ALEN);
	memcpy(eth_hdr(skb)->h_dest, eth_key->eth_dst, ETH_ALEN);

	return 0;
}
Ejemplo n.º 8
0
static int set_eth_addr(struct sk_buff *skb,
			const struct ovs_key_ethernet *eth_key)
{
	int err;
	err = make_writable(skb, ETH_HLEN);
	if (unlikely(err))
		return err;

	skb_postpull_rcsum(skb, eth_hdr(skb), ETH_ALEN * 2);

	ether_addr_copy(eth_hdr(skb)->h_source, eth_key->eth_src);
	ether_addr_copy(eth_hdr(skb)->h_dest, eth_key->eth_dst);

	ovs_skb_postpush_rcsum(skb, eth_hdr(skb), ETH_ALEN * 2);

	return 0;
}
Ejemplo n.º 9
0
static int set_tcp(struct sk_buff *skb, const struct ovs_key_tcp *tcp_port_key)
{
	struct tcphdr *th;
	int err;

	err = make_writable(skb, skb_transport_offset(skb) +
				 sizeof(struct tcphdr));
	if (unlikely(err))
		return err;

	th = tcp_hdr(skb);
	if (tcp_port_key->tcp_src != th->source)
		set_tp_port(skb, &th->source, tcp_port_key->tcp_src, &th->check);

	if (tcp_port_key->tcp_dst != th->dest)
		set_tp_port(skb, &th->dest, tcp_port_key->tcp_dst, &th->check);

	return 0;
}
Ejemplo n.º 10
0
static int set_udp(struct sk_buff *skb, const struct ovs_key_udp *udp_port_key)
{
	struct udphdr *uh;
	int err;

	err = make_writable(skb, skb_transport_offset(skb) +
				 sizeof(struct udphdr));
	if (unlikely(err))
		return err;

	uh = udp_hdr(skb);
	if (udp_port_key->udp_src != uh->source)
		set_udp_port(skb, &uh->source, udp_port_key->udp_src);

	if (udp_port_key->udp_dst != uh->dest)
		set_udp_port(skb, &uh->dest, udp_port_key->udp_dst);

	return 0;
}
Ejemplo n.º 11
0
static int set_mpls(struct sk_buff *skb, const __be32 *mpls_lse)
{
	__be32 *stack = (__be32 *)mac_header_end(skb);
	int err;

	err = make_writable(skb, skb->mac_len + MPLS_HLEN);
	if (unlikely(err))
		return err;

	if (skb->ip_summed == CHECKSUM_COMPLETE) {
		__be32 diff[] = { ~(*stack), *mpls_lse };
		skb->csum = ~csum_partial((char *)diff, sizeof(diff),
					  ~skb->csum);
	}

	*stack = *mpls_lse;

	return 0;
}
Ejemplo n.º 12
0
static int set_eth_addr(struct sk_buff *skb,
			const struct ovs_key_ethernet *eth_key)
{
	int err;
	err = make_writable(skb, ETH_HLEN);
	if (unlikely(err))
		return err;

	if (get_ip_summed(skb) == OVS_CSUM_COMPLETE)
		skb->csum = csum_sub(skb->csum, csum_partial(eth_hdr(skb),
							     ETH_ALEN * 2, 0));

	memcpy(eth_hdr(skb)->h_source, eth_key->eth_src, ETH_ALEN);
	memcpy(eth_hdr(skb)->h_dest, eth_key->eth_dst, ETH_ALEN);

	if (get_ip_summed(skb) == OVS_CSUM_COMPLETE)
		skb->csum = csum_add(skb->csum, csum_partial(eth_hdr(skb),
							     ETH_ALEN * 2, 0));

	return 0;
}
Ejemplo n.º 13
0
Archivo: run.c Proyecto: NUOG/ejudge
static int
check_config(void)
{
  int     i, n1 = 0, n2, j, k;
  int     total = 0;

  struct section_problem_data *prb = 0;
  struct section_tester_data *tst = 0;
  unsigned char *var_test_dir;
  unsigned char *var_corr_dir;
  unsigned char *var_info_dir;
  unsigned char *var_tgz_dir;
  problem_xml_t px;
  const struct section_global_data *global = serve_state.global;

  if (skip_arch_count > 0) {
    for (i = 0; i < serve_state.max_abstr_tester; ++i) {
      tst = serve_state.abstr_testers[i];
      if (!tst) continue;
      tst->skip_testing = -1;
      for (j = 0; j < skip_arch_count; ++j) {
        if (!strcmp(skip_archs[j], tst->arch)) {
          break;
        }
      }
      if (j < skip_arch_count) {
        tst->skip_testing = 1;
      }
    }
  }

  /* check spooler dirs */
  if (check_writable_spool(global->run_queue_dir, SPOOL_OUT) < 0) return -1;
  if (check_writable_dir(global->run_exe_dir) < 0) return -1;

  /* check working dirs */
  if (make_writable(global->run_work_dir) < 0) return -1;
  if (check_writable_dir(global->run_work_dir) < 0) return -1;

  for (i = 1; i <= serve_state.max_prob; i++) {
    prb = serve_state.probs[i];
    if (!prb) continue;
    if (prb->disable_testing) continue;
    if (prb->manual_checking) continue;

    /* ignore output-only problems with XML and answer variants */
    px = 0;
    if (prb->variant_num > 0 && prb->xml.a) {
      px = prb->xml.a[0];
    } else {
      px = prb->xml.p;
    }
    if (px && px->answers) {
      prb->disable_testing = 1;
      continue;
    }

    // check if there exists a tester for this problem
    for (j = 1; j <= serve_state.max_tester; j++) {
      if (!serve_state.testers[j]) continue;
      if (serve_state.testers[j]->any) break;
      if (serve_state.testers[j]->problem == i) break;
    }
    if (j > serve_state.max_tester) {
      // no checker for the problem :-(
      info("no checker found for problem %d", i);
      continue;
    }

    if (prb->type > 0 && prb->type != PROB_TYPE_TESTS) {
      // output-only problems have no input file
      if (prb->variant_num <= 0) {
        if (prb->use_corr) {
          if (!prb->corr_dir[0]) {
            err("directory with answers is not defined");
            return -1;
          }
          if (global->advanced_layout > 0) {
            var_corr_dir = (unsigned char*) alloca(sizeof(path_t));
            get_advanced_layout_path(var_corr_dir, sizeof(path_t), global,
                                     prb, DFLT_P_CORR_DIR, -1);
          } else {
            var_corr_dir = prb->corr_dir;
          }
          if (check_readable_dir(var_corr_dir) < 0) return -1;
          if ((n2 = count_files(var_corr_dir,prb->corr_sfx,prb->corr_pat)) < 0)
            return -1;
          n1 = n2;
          info("found %d answers for problem %s", n2, prb->short_name);
          if (n2 != 1) {
            err("output-only problem must define only one answer file");
            return -1;
          }
        }
        if (prb->use_info) {
          if (!prb->info_dir[0]) {
            err("directory with test information is not defined");
            return -1;
          }
          if (global->advanced_layout > 0) {
            var_info_dir = (unsigned char*) alloca(sizeof(path_t));
            get_advanced_layout_path(var_info_dir, sizeof(path_t), global,
                                     prb, DFLT_P_INFO_DIR, -1);
          } else {
            var_info_dir = prb->info_dir;
          }
          if (check_readable_dir(var_info_dir) < 0) return -1;
          if ((n2 = count_files(var_info_dir,prb->info_sfx,prb->info_pat)) < 0)
            return -1;
          info("found %d info files for problem %s", n2, prb->short_name);
          if (n2 != 1) {
            err("output-only problem must define only one info file");
            return -1;
          }
        }
        if (prb->use_tgz) {
          if (!prb->tgz_dir[0]) {
            err("directory with tgz information is not defined");
            return -1;
          }
          if (global->advanced_layout > 0) {
            var_tgz_dir = (unsigned char*) alloca(sizeof(path_t));
            get_advanced_layout_path(var_tgz_dir, sizeof(path_t), global,
                                     prb, DFLT_P_TGZ_DIR, -1);
          } else {
            var_tgz_dir = prb->tgz_dir;
          }
          if (check_readable_dir(var_tgz_dir) < 0) return -1;
          if ((n2 = count_files(var_tgz_dir, prb->tgz_sfx, 0)) < 0) return -1;
          info("found %d tgz files for problem %s", n2, prb->short_name);
          if (n2 != 1) {
            err("output-only problem must define only one tgz file");
            return -1;
          }
        }
      } else {
        var_test_dir = (unsigned char *) alloca(sizeof(path_t));
        var_corr_dir = (unsigned char *) alloca(sizeof(path_t));
        var_info_dir = (unsigned char *) alloca(sizeof(path_t));
        var_tgz_dir = (unsigned char *) alloca(sizeof(path_t));

        for (k = 1; k <= prb->variant_num; k++) {
          if (global->advanced_layout > 0) {
            get_advanced_layout_path(var_test_dir, sizeof(path_t), global,
                                     prb, DFLT_P_TEST_DIR, k);
            get_advanced_layout_path(var_corr_dir, sizeof(path_t), global,
                                     prb, DFLT_P_CORR_DIR, k);
            get_advanced_layout_path(var_info_dir, sizeof(path_t), global,
                                     prb, DFLT_P_INFO_DIR, k);
            get_advanced_layout_path(var_tgz_dir, sizeof(path_t), global,
                                     prb, DFLT_P_TGZ_DIR, k);
          } else {
            snprintf(var_test_dir, sizeof(path_t), "%s-%d", prb->test_dir, k);
            snprintf(var_corr_dir, sizeof(path_t), "%s-%d", prb->corr_dir, k);
            snprintf(var_info_dir, sizeof(path_t), "%s-%d", prb->info_dir, k);
            snprintf(var_tgz_dir, sizeof(path_t), "%s-%d", prb->tgz_dir, k);
          }
          if (prb->use_corr) {
            if (!prb->corr_dir[0]) {
              err("directory with answers is not defined");
              return -1;
            }
            if (check_readable_dir(var_corr_dir) < 0) return -1;
            if ((j = count_files(var_corr_dir,prb->corr_sfx,prb->corr_pat)) < 0)
              return -1;
            if (j != 1) {
              err("output-only problem must define only one answer file");
              return -1;
            }
          }
          if (prb->use_info) {
            if (!prb->info_dir[0]) {
              err("directory with test infos is not defined");
              return -1;
            }
            if (check_readable_dir(var_info_dir) < 0) return -1;
            if ((j = count_files(var_info_dir,prb->info_sfx,prb->info_pat)) < 0)
              return -1;
            if (j != 1) {
              err("output-only problem must define only one info file");
              return -1;
            }
          }
          if (prb->use_tgz) {
            if (!prb->tgz_dir[0]) {
              err("directory with tgz is not defined");
              return -1;
            }
            if (check_readable_dir(var_tgz_dir) < 0) return -1;
            if ((j = count_files(var_tgz_dir, prb->tgz_sfx, 0)) < 0) return -1;
            if (j != 1) {
              err("output-only problem must define only one info file");
              return -1;
            }
          }
        }
        n1 = n2 = 1;
      }
    } else if (!prb->type) {
      /* check existence of tests */
      if (prb->variant_num <= 0) {
        if (global->advanced_layout > 0) {
          var_test_dir = (unsigned char *) alloca(sizeof(path_t));
          get_advanced_layout_path(var_test_dir, sizeof(path_t), global,
                                   prb, DFLT_P_TEST_DIR, -1);
        } else {
          var_test_dir = prb->test_dir;
        }
        if (check_readable_dir(var_test_dir) < 0) return -1;
        if ((n1 = count_files(var_test_dir, prb->test_sfx, prb->test_pat)) < 0)
          return -1;
        if (!n1) {
          err("'%s' does not contain any tests", var_test_dir);
          return -1;
        }
        /*
        if (prb->type_val > 0 && n1 != 1) {
          err("`%s' must have only one test (as output-only problem)",
              prb->short_name);
          return -1;
        }
        */
        info("found %d tests for problem %s", n1, prb->short_name);
        if (n1 < prb->tests_to_accept) {
          err("%d tests required for problem acceptance!",prb->tests_to_accept);
          return -1;
        }
        if (prb->use_corr) {
          if (!prb->corr_dir[0]) {
            err("directory with answers is not defined");
            return -1;
          }
          if (global->advanced_layout > 0) {
            var_corr_dir = (unsigned char *) alloca(sizeof(path_t));
            get_advanced_layout_path(var_corr_dir, sizeof(path_t), global,
                                     prb, DFLT_P_CORR_DIR, -1);
          } else {
            var_corr_dir = prb->corr_dir;
          }
          if (check_readable_dir(var_corr_dir) < 0) return -1;
          if ((n2 = count_files(var_corr_dir,prb->corr_sfx,prb->corr_pat)) < 0)
            return -1;
          info("found %d answers for problem %s", n2, prb->short_name);
          if (n1 != n2) {
            err("number of test does not match number of answers");
            return -1;
          }
        }
        if (prb->use_info) {
          if (!prb->info_dir[0]) {
            err("directory with test information is not defined");
            return -1;
          }
          if (global->advanced_layout > 0) {
            var_info_dir = (unsigned char *) alloca(sizeof(path_t));
            get_advanced_layout_path(var_info_dir, sizeof(path_t), global,
                                     prb, DFLT_P_INFO_DIR, -1);
          } else {
            var_info_dir = prb->info_dir;
          }
          if (check_readable_dir(var_info_dir) < 0) return -1;
          if ((n2 = count_files(var_info_dir,prb->info_sfx,prb->info_pat)) < 0)
            return -1;
          info("found %d info files for problem %s", n2, prb->short_name);
          if (n1 != n2) {
            err("number of test does not match number of info files");
            return -1;
          }
        }
        if (prb->use_tgz) {
          if (!prb->tgz_dir[0]) {
            err("directory with tgz information is not defined");
            return -1;
          }
          if (global->advanced_layout > 0) {
            var_tgz_dir = (unsigned char *) alloca(sizeof(path_t));
            get_advanced_layout_path(var_tgz_dir, sizeof(path_t), global,
                                     prb, DFLT_P_TGZ_DIR, -1);
          } else {
            var_tgz_dir = prb->tgz_dir;
          }
          if (check_readable_dir(var_tgz_dir) < 0) return -1;
          if ((n2 = count_files(var_tgz_dir, prb->tgz_sfx, 0)) < 0) return -1;
          info("found %d tgz files for problem %s", n2, prb->short_name);
          if (n1 != n2) {
            err("number of test does not match number of tgz files");
            return -1;
          }
        }
      } else {
        n1 = n2 = -1;
        var_test_dir = (unsigned char *) alloca(sizeof(path_t));
        var_corr_dir = (unsigned char *) alloca(sizeof(path_t));
        var_info_dir = (unsigned char *) alloca(sizeof(path_t));
        var_tgz_dir = (unsigned char *) alloca(sizeof(path_t));

        for (k = 1; k <= prb->variant_num; k++) {
          if (global->advanced_layout > 0) {
            get_advanced_layout_path(var_test_dir, sizeof(path_t), global,
                                     prb, DFLT_P_TEST_DIR, k);
            get_advanced_layout_path(var_corr_dir, sizeof(path_t), global,
                                     prb, DFLT_P_CORR_DIR, k);
            get_advanced_layout_path(var_info_dir, sizeof(path_t), global,
                                     prb, DFLT_P_INFO_DIR, k);
            get_advanced_layout_path(var_tgz_dir, sizeof(path_t), global,
                                     prb, DFLT_P_TGZ_DIR, k);
          } else {
            snprintf(var_test_dir, sizeof(path_t), "%s-%d", prb->test_dir, k);
            snprintf(var_corr_dir, sizeof(path_t), "%s-%d", prb->corr_dir, k);
            snprintf(var_info_dir, sizeof(path_t), "%s-%d", prb->info_dir, k);
            snprintf(var_tgz_dir, sizeof(path_t), "%s-%d", prb->tgz_dir, k);
          }
          if (check_readable_dir(var_test_dir) < 0) return -1;
          if ((j = count_files(var_test_dir, prb->test_sfx, prb->test_pat)) < 0)
            return -1;
          if (!j) {
            err("'%s' does not contain any tests", var_test_dir);
            return -1;
          }
          /*
          if (prb->type_val > 0 && n1 != 1) {
            err("`%s', variant %d must have only one test (as output-only problem)",
                prb->short_name, j);
            return -1;
          }
          */
          if (n1 < 0) n1 = j;
          if (n1 != j) {
            err("number of tests %d for variant %d does not equal %d",
                j, k, n1);
            return -1;
          }
          info("found %d tests for problem %s, variant %d",
               n1, prb->short_name, k);
          if (n1 < prb->tests_to_accept) {
            err("%d tests required for problem acceptance!",
                prb->tests_to_accept);
            return -1;
          }
          if (prb->use_corr) {
            if (!prb->corr_dir[0]) {
              err("directory with answers is not defined");
              return -1;
            }
            if (check_readable_dir(var_corr_dir) < 0) return -1;
            if ((j = count_files(var_corr_dir,prb->corr_sfx,prb->corr_pat)) < 0)
              return -1;
            info("found %d answers for problem %s, variant %d",
                 j, prb->short_name, k);
            if (n1 != j) {
              err("number of tests %d does not match number of answers %d",
                  n1, j);
              return -1;
            }
          }
          if (prb->use_info) {
            if (!prb->info_dir[0]) {
              err("directory with test infos is not defined");
              return -1;
            }
            if (check_readable_dir(var_info_dir) < 0) return -1;
            if ((j = count_files(var_info_dir,prb->info_sfx,prb->info_pat)) < 0)
              return -1;
            info("found %d test infos for problem %s, variant %d",
                 j, prb->short_name, k);
            if (n1 != j) {
              err("number of tests %d does not match number of test infos %d",
                  n1, j);
              return -1;
            }
          }
          if (prb->use_tgz) {
            if (!prb->tgz_dir[0]) {
              err("directory with tgz is not defined");
              return -1;
            }
            if (check_readable_dir(var_tgz_dir) < 0) return -1;
            if ((j = count_files(var_tgz_dir, prb->tgz_sfx, 0)) < 0) return -1;
            info("found %d tgzs for problem %s, variant %d",
                 j, prb->short_name, k);
            if (n1 != j) {
              err("number of tests %d does not match number of tgz %d",
                  n1, j);
              return -1;
            }
          }
          n2 = n1;
        }
      }
    }

    if (n1 >= tests_a - 1) {
      if (!tests_a) tests_a = 128;
      while (n1 >= tests_a - 1)
        tests_a *= 2;
      xfree(tests);
      XCALLOC(tests, tests_a);
    }

    ASSERT(prb->test_score >= 0);
    if (global->score_system == SCORE_MOSCOW) {
      if (prb->full_score <= 0) {
        err("problem %s: problem full_score is not set", prb->short_name);
        return -1;
      }
      prb->ntests = n1;
      if (!prb->scoring_checker) {
        if (!(prb->x_score_tests = prepare_parse_score_tests(prb->score_tests,
                                                             prb->full_score))){
          err("problem %s: parsing of score_tests failed", prb->short_name);
          return -1;
        }
        prb->x_score_tests[prb->full_score - 1] = n1 + 1;
        if (prb->full_score > 1
            && prb->x_score_tests[prb->full_score - 2] > n1 + 1) {
          err("problem %s: score_tests[%d] > score_tests[%d]",
              prb->short_name,
              prb->full_score - 2, prb->full_score - 1);
          return -1;
        }
      }
    } else if (prb->test_score >= 0 && global->score_system != SCORE_ACM) {
      int score_summ = 0;

      prb->ntests = n1;
      XCALLOC(prb->tscores, prb->ntests + 1);

      for (j = 1; j <= prb->ntests; j++)
        prb->tscores[j] = prb->test_score;

      // test_score_list overrides test_score
      if (prb->test_score_list && prb->test_score_list[0]) {
        char const *s = prb->test_score_list;
        int tn = 1;
        int was_indices = 0;
        int n;
        int index, score;

        while (1) {
          while (*s > 0 && *s <= ' ') s++;
          if (!*s) break;

          if (*s == '[') {
            if (sscanf(s, "[ %d ] %d%n", &index, &score, &n) != 2) {
              err("cannot parse test_score_list for problem %s",
                  prb->short_name);
              return -1;
            }
            if (index < 1 || index > prb->ntests) {
              err("problem %s: test_score_list: index out of range",
                  prb->short_name);
              return -1;
            }
            if (score < 0) {
              err("problem %s: test_score_list: invalid score",
                  prb->short_name);
              return -1;
            }
            tn = index;
            was_indices = 1;
            prb->tscores[tn++] = score;
            s += n;
          } else {
            if (sscanf(s, "%d%n", &score, &n) != 1) {
              err("cannot parse test_score_list for problem %s",
                  prb->short_name);
              return -1;
            }
            if (score < 0) {
              err("problem %s: test_score_list: invalid score",
                  prb->short_name);
              return -1;
            }
            if (tn > prb->ntests) {
              err("problem %s: too many scores specified", prb->short_name);
              return -1;
            }
            prb->tscores[tn++] = score;
            s += n;
          }
        }

        if (!was_indices && tn <= prb->ntests) {
          info("test_score_list for problem %s defines only %d tests",
               prb->short_name, tn - 1);
        }
      }

      for (j = 1; j <= prb->ntests; j++) score_summ += prb->tscores[j];
      if (score_summ > prb->full_score && !prb->valuer_cmd[0]) {
        err("total score (%d) > full score (%d) for problem %s",
            score_summ, prb->full_score, prb->short_name);
        return -1;
      }
    }
  }

  for (i = 1; i <= serve_state.max_tester; i++) {
    if (!serve_state.testers[i]) continue;
    if (serve_state.testers[i]->any) continue;
    prb = serve_state.probs[serve_state.testers[i]->problem];
    total++;

    /* check working dirs */
    if (make_writable(serve_state.testers[i]->check_dir) < 0) return -1;
    if (check_writable_dir(serve_state.testers[i]->check_dir) < 0) return -1;
    if (serve_state.testers[i]->prepare_cmd[0]
        && check_executable(serve_state.testers[i]->prepare_cmd) < 0) return -1;
    if (serve_state.testers[i]->start_cmd[0]
        && check_executable(serve_state.testers[i]->start_cmd) < 0) return -1;
  }

  info("checking default testers...");
  if ((i = process_default_testers()) < 0) return -1;
  info("checking default testers done");
  total += i;

  if (!total) info("no testers");

#if CONF_HAS_LIBINTL - 0 == 1
  // bind message catalogs, if specified
  if (global->enable_l10n && global->l10n_dir[0]) {
    bindtextdomain("ejudge", global->l10n_dir);
    textdomain("ejudge");
  }
#endif

  return 0;
}
Ejemplo n.º 14
0
Archivo: run.c Proyecto: NUOG/ejudge
static int
process_default_testers(void)
{
  int total = 0;
  int i, j, k;
  unsigned char *prob_flags = 0;
  struct section_tester_data *tp, *tq;
  struct section_problem_data *ts;

  struct section_tester_data tn; //temporary entry

  prob_flags = (unsigned char *) alloca(serve_state.max_prob + 1);

  /* scan all the 'any' testers */
  for (i = 1; i <= serve_state.max_tester; i++) {
    tp = serve_state.testers[i];
    if (!tp || !tp->any) continue;

    // check architecture uniqueness
    for (j = 1; j <= serve_state.max_tester; j++) {
      tq = serve_state.testers[j];
      if (i == j || !tq || !tq->any) continue;
      if (strcmp(serve_state.testers[j]->arch, tp->arch) != 0) continue;
      err("default testers %d and %d has the same architecture '%s'",
          i, j, tp->arch);
      return -1;
    }

    // mark the problems with explicit testers for this architecture
    memset(prob_flags, 0, serve_state.max_prob + 1);
    for (j = 1; j <= serve_state.max_tester; j++) {
      tq = serve_state.testers[j];
      if (!tq || tq->any) continue;
      if (strcmp(tp->arch, tq->arch) != 0) continue;

      // tq is specific tester with the same architecture
      ASSERT(tq->problem > 0 && tq->problem <= serve_state.max_prob);
      ASSERT(serve_state.probs[tq->problem]);
      prob_flags[tq->problem] = 1;
    }

    // scan all problems, which have no default tester
    for (k = 1; k <= serve_state.max_prob; k++) {
      ts = serve_state.probs[k];
      if (!ts || prob_flags[k]) continue;
      if (ts->disable_testing) continue;
      if (ts->manual_checking) continue;

      // so at this point: tp - pointer to the default tester,
      // k is the problem number
      // ts - pointer to the problem which should be handled by the
      // default tester
      if (prepare_tester_refinement(&serve_state, &tn, i, k) < 0) return -1;
      if (create_tester_dirs(&tn) < 0) return -1;

      /* check working dirs */
      if (make_writable(tn.check_dir) < 0) return -1;
      if (check_writable_dir(tn.check_dir) < 0) return -1;
      if (tn.prepare_cmd[0] && check_executable(tn.prepare_cmd) < 0) return -1;
      if (tn.start_cmd[0] && check_executable(tn.start_cmd) < 0) return -1;
      total++;

      sarray_free(tn.start_env);
      sarray_free(tn.super);
    }
  }

  return total;
}