Exemplo n.º 1
0
int
file_perms_set(
        FILE *flog,
        const unsigned char *path,
        int group,
        int mode,
        int old_group,
        int old_mode)
{
  if (group > 0) {
    if (chown(path, -1, group) < 0) {
      fprintf(flog, "chown: %s: %s\n", path, os_ErrorMsg());
    }
  } else if (old_group > 0) {
    chown(path, -1, old_group);
  }
  if (mode > 0) {
    if (chmod(path, mode) < 0) {
      fprintf(flog, "chmod: %s: %s\n", path, os_ErrorMsg());
    }
  } else if (old_mode > 0) {
    chmod(path, old_mode);
  }
  return 0;
}
Exemplo n.º 2
0
static int
read_from_pipe(int fd, unsigned char **reply_bytes, size_t *reply_size)
{
  unsigned char *p = 0;
  size_t s = 0, a = 0;
  unsigned char b[4096];
  int r;

  a = 8192; s = 0;
  p = xmalloc(a);
  p[0] = 0;

  while ((r = read(fd, b, sizeof(b))) > 0) {
    if (r + s >= a) {
      a *= 2;
      p = xrealloc(p, a);
    }
    memcpy(p + s, b, r);
    s += r;
    p[s] = 0;
  }
  if (r < 0) {
    err("read_from_pipe failed: %s", os_ErrorMsg());
    goto failed;
  }
  if (reply_bytes) *reply_bytes = (unsigned char*) p;
  else xfree(p);
  if (reply_size) *reply_size = s;
  return 0;

 failed:
  xfree(p);
  return -1;
}
Exemplo n.º 3
0
struct generic_section_config *
nwrun_in_packet_parse(const unsigned char *path, struct nwrun_in_packet **pkt)
{
  FILE *f = 0;
  struct generic_section_config *config = 0, *p;
  struct nwrun_in_packet *packet = 0;

  if (!(f = fopen(path, "rb"))) {
    err("cannot open file %s: %s", path, os_ErrorMsg());
    goto cleanup;
  }
  fclose(f); f = 0;
  if (!(config = parse_param(path, 0, nwrun_in_config, 1, 0, 0, 0))) {
    goto cleanup;
  }

  for (p = config; p; p = p->next) {
    if (!p->name[0] || !strcmp(p->name, "global")) {
      packet = (struct nwrun_in_packet *) p;
    }
  }

  if (!packet) {
    err("no global section in %s", path);
    goto cleanup;
  }
  *pkt = packet;
  return config;

 cleanup:
  param_free(config, nwrun_in_config);
  if (f) fclose(f);
  return 0;
}
Exemplo n.º 4
0
static int
do_read(int fd, void *buf, size_t size)
{
  unsigned char *p = (unsigned char*) buf;
  int r, se;

  while (size) {
    r = read(fd, p, size);
    if (r < 0) {
      se = errno;
      if (se == EINTR) continue;
      err("do_read: read failed: %s", os_ErrorMsg());
      errno = se;
      return -se;
    }
    if (!r) {
      err("do_read: unexpected EOF");
      errno = EPIPE;
      return -EPIPE;
    }
    p += r;
    size -= r;
  }
  return 0;
}
Exemplo n.º 5
0
static int
reset_func(
        struct rldb_plugin_cnts *cdata,
        time_t init_duration,
        time_t init_sched_time,
        time_t init_finish_time)
{
  struct rldb_file_cnts *cs = (struct rldb_file_cnts*) cdata;
  struct runlog_state *rls = cs->rl_state;
  int i;

  rls->run_u = 0;
  if (rls->run_a > 0) {
    memset(rls->runs, 0, sizeof(rls->runs[0]) * rls->run_a);
    for (i = 0; i < rls->run_a; ++i)
      rls->runs[i].status = RUN_EMPTY;
  }

  memset(&rls->head, 0, sizeof(rls->head));
  rls->head.version = 2;
  rls->head.duration = init_duration;
  rls->head.sched_time = init_sched_time;
  rls->head.finish_time = init_finish_time;

  if (ftruncate(cs->run_fd, 0) < 0) {
    err("ftruncate failed: %s", os_ErrorMsg());
    return -1;
  }
  return run_flush_header(cs);
}
Exemplo n.º 6
0
Arquivo: random.c Projeto: NUOG/ejudge
unsigned
random_u32(void)
{
  unsigned val = 0;
  int n, r;
  char *p;

  ASSERT(urandom_fd >= 0);

  while (!val) {
    p = (char*) &val;
    r = sizeof(val);
    while (r > 0) {
      n = read(urandom_fd, p, r);
      if (n < 0) {
        err("read from /dev/urandom failed: %s", os_ErrorMsg());
        return (unsigned) rand();
      }
      if (!n) {
        err("EOF on /dev/urandom???");
        return (unsigned) rand();
      }
      p += n;
      r -= n;
    }
  }

  return val;
}
Exemplo n.º 7
0
Arquivo: random.c Projeto: NUOG/ejudge
void
random_bytes(unsigned char *buf, int count)
{
  int r, n;
  unsigned char *p;

  ASSERT(urandom_fd >= 0);

  // generate the needed number of bytes
  r = count;
  p = buf;
  while (r > 0) {
    n = read(urandom_fd, p, r);
    if (n < 0) {
      err("read from /dev/urandom failed: %s", os_ErrorMsg());
      goto fail;
    }
    if (!n) {
      err("EOF on /dev/urandom???");
      goto fail;
    }
    p += n;
    r -= n;
  }
  return;

 fail:
  for (; r; r--, p++)
    *p = (unsigned char) rand();
}
Exemplo n.º 8
0
static void
create_dir(void)
{
  if (os_MakeDirPath(global->work_dir, 0777) < 0) {
    die("cannot create directory %s: %s", global->work_dir, os_ErrorMsg());
  }
  if (os_MakeDirPath(global->spool_dir, 0777) < 0) {
    die("cannot create directory %s: %s", global->work_dir, os_ErrorMsg());
  }

  if (make_all_dir(global->queue_dir, 0777) < 0) {
    exit(1);
  }
  if (make_all_dir(global->result_dir, 0777) < 0) {
    exit(1);
  }
}
Exemplo n.º 9
0
static int
squeeze_func(struct rldb_plugin_cnts *cdata)
{
  struct rldb_file_cnts *cs = (struct rldb_file_cnts*) cdata;
  struct runlog_state *rls = cs->rl_state;

  int i, j, retval, first_moved = -1, w;
  unsigned char *ptr;
  size_t tot;

  for (i = 0, j = 0; i < rls->run_u; i++) {
    if (rls->runs[i].status == RUN_EMPTY) continue;
    if (i != j) {
      if (first_moved < 0) first_moved = j;
      memcpy(&rls->runs[j], &rls->runs[i], sizeof(rls->runs[j]));
      rls->runs[j].run_id = j;
    }
    j++;
  }
  if  (rls->run_u == j) {
    // no runs were removed
    ASSERT(first_moved == -1);
    return 0;
  }

  retval = rls->run_u - j;
  rls->run_u = j;
  if (rls->run_u < rls->run_a) {
    memset(&rls->runs[rls->run_u], 0,
           (rls->run_a - rls->run_u) * sizeof(rls->runs[0]));
  }

  // update log on disk
  if (do_truncate(cs) < 0) return -1;
  if (first_moved == -1) {
    // no entries were moved because the only entries empty were the last
    return retval;
  }
  ASSERT(first_moved >= 0 && first_moved < rls->run_u);
  if (sf_lseek(cs->run_fd,
               sizeof(rls->head) + first_moved * sizeof(rls->runs[0]),
               SEEK_SET, "run") == (off_t) -1)
    return -1;
  tot = (rls->run_u - first_moved) * sizeof(rls->runs[0]);
  ptr = (unsigned char *) &rls->runs[first_moved];
  while (tot > 0) {
    w = write(cs->run_fd, ptr, tot);
    if (w <= 0) {
      err("run_squeeze_log: write error: %s", os_ErrorMsg());
      return -1;
    }
    tot -= w;
    ptr += w;
  }
  return retval;
}
Exemplo n.º 10
0
Arquivo: random.c Projeto: NUOG/ejudge
int
random_init(void)
{
  if (urandom_fd >= 0) return 0;

  if((urandom_fd = open("/dev/urandom", O_RDONLY)) < 0) {
    err("open of /dev/urandom failed: %s", os_ErrorMsg());
    return -1;
  }
  return 0;
}
Exemplo n.º 11
0
static int
do_truncate(struct rldb_file_cnts *cs)
{
  struct runlog_state *rls = cs->rl_state;
  size_t size = sizeof(rls->head) + sizeof(rls->runs[0]) * rls->run_u;

  if (ftruncate(cs->run_fd, size) < 0) {
    err("%s: ftruncate failed: %s", __FILE__, os_ErrorMsg());
    return -1;
  }
  return 0;
}
Exemplo n.º 12
0
int
super_clnt_send_packet(int sock_fd, size_t size, const void *buf)
{
  const unsigned char *b;
  int w, n;
  rint32_t size32;
  struct iovec vv[2];

  if (sock_fd < 0) return -SSERV_ERR_NOT_CONNECTED;

  /* -1073741824 is 0xc0000000 or 0xffffffffc0000000 */
  if ((size & -1073741824L)) {
    err("send_packet: packet length exceeds 1GiB");
    return -SSERV_ERR_WRITE_TO_SERVER;
  }
  size32 = (ruint32_t) size;

  vv[0].iov_base = &size32;
  vv[0].iov_len = sizeof(size32);
  vv[1].iov_base = (void*) buf;
  vv[1].iov_len = size;

  n = writev(sock_fd, vv, 2);
  if (n == size + 4) return 0;
  if (n <= 0) goto write_error;

  /* if the fast method did not work out, try the slow one */
  if (n < 4) {
    w = 4 - n;
    b = (const unsigned char*) &size32 + n;
    while (w > 0) {
      if ((n = write(sock_fd, b, w)) <= 0) goto write_error;
      w -= n;
      b += n;
    }
    n = 4;
  }

  w = size + 4 - n;
  b = (const unsigned char*) buf + n - 4;
  while (w > 0) {
    if ((n = write(sock_fd, b, w)) <= 0) goto write_error;
    w -= n;
    b += n;
  }

  return 0;

 write_error:
  err("super_clnt_send_packet: write() failed: %s", os_ErrorMsg());
  return -SSERV_ERR_WRITE_TO_SERVER;
}
Exemplo n.º 13
0
static int
concatenate_files(const unsigned char *dst_path, const unsigned char *src_path)
{
  int retcode = -1;
  FILE *fout = 0;
  FILE *fin = 0;
  int c;

  if (!(fout = fopen(dst_path, "ab"))) {
    err("failed to open %s for appending: %s", dst_path, os_ErrorMsg());
    goto failed;
  }
  if (!(fin = fopen(src_path, "rb"))) {
    err("failed to open %s for reading: %s", src_path, os_ErrorMsg());
    goto failed;
  }

  while ((c = getc(fin)) != EOF)
    putc(c, fout);

  if (ferror(fin)) {
    err("read error from %s", src_path);
    goto failed;
  }
  if (ferror(fout)) {
    err("write error to %s", dst_path);
    goto failed;
  }

  fclose(fin); fin = 0;
  fclose(fout); fout = 0;

  retcode = 0;

 failed:
  if (fin) fclose(fin);
  if (fout) fclose(fout);
  return retcode;
}
Exemplo n.º 14
0
int
userlist_clnt_bytes_available(struct userlist_clnt *clnt)
{
#if HAVE_SIOCINQ - 0 == 1
  int sz = 0;

  if (ioctl(clnt->fd, SIOCINQ, &sz) < 0) {
    err("%s: ioctl failed: %s", __FUNCTION__, os_ErrorMsg());
    return -ULS_ERR_READ_ERROR;
  } else {
    return sz;
  }
#else
  err("%s: not implemented", __FUNCTION__);
  return -1;
#endif
}
Exemplo n.º 15
0
int
userlist_clnt_generate_team_passwd(
        struct userlist_clnt *clnt,
        int cmd,
        int contest_id,
        int out_fd)
{
  struct userlist_pk_map_contest *out = 0;
  struct userlist_packet *in = 0;
  int r;
  size_t out_size, in_size = 0;
  int pfd[2], pp[2];
  char b;

  if (cmd != ULS_GENERATE_TEAM_PASSWORDS && cmd != ULS_GENERATE_PASSWORDS) {
    return -ULS_ERR_PROTOCOL;
  }

  if (pipe(pp) < 0) {
    err("pipe() failed: %s", os_ErrorMsg());
    return -ULS_ERR_WRITE_ERROR;
  }
  pfd[0] = out_fd;
  pfd[1] = pp[1];

  out_size = sizeof(*out);
  out = alloca(out_size);
  memset(out, 0, out_size);
  out->request_id = cmd;
  out->contest_id = contest_id;
  if ((r = userlist_clnt_pass_fd(clnt, 2, pfd)) < 0) return r;
  if ((r = userlist_clnt_send_packet(clnt, out_size, out)) < 0) return r;
  if ((r = userlist_clnt_read_and_notify(clnt, &in_size, (void*) &in)) < 0)
    return r;
  r = in->id;
  xfree(in);
  if (r < 0) return r;

  close(pfd[1]);
  r = read(pp[0], &b, 1);
  if (r > 0) return -ULS_ERR_PROTOCOL;
  if (r < 0) return -ULS_ERR_READ_ERROR;
  return 0;
}
Exemplo n.º 16
0
static int
save_runlog_backup(
        const unsigned char *path,
        const unsigned char *suffix)
{
  unsigned char *back;
  size_t len;
  if (!suffix) suffix = ".bak";

  len = strlen(path);
  back = alloca(len + 16);
  sprintf(back, "%s%s", path, suffix);
  if (rename(path, back) < 0) {
    err("save_runlog_backup: rename failed: %s", os_ErrorMsg());
    return -1;
  }
  info("old runlog is saved as %s", back);
  return 0;
}
Exemplo n.º 17
0
static int
do_write(int fd, void const *buf, size_t size)
{
  const unsigned char *p = (const unsigned char *) buf;
  int w, se;

  ASSERT(buf);
  ASSERT(size);

  while (size) {
    w = write(fd, p, size);
    if (w <= 0) {
      se = errno;
      if (se == EINTR) continue;
      err("do_write: write error: %s", os_ErrorMsg());
      errno = se;
      return -se;
    }
    p += w;
    size -= w;
  }
  return 0;
}
Exemplo n.º 18
0
static int
run_all_tests(int argc, char *argv[])
{
  unsigned char tmp_work_dir[PATH_MAX];
  unsigned char abs_prog_name[PATH_MAX];
  unsigned char abs_test_dir[PATH_MAX];
  unsigned char abs_work_dir[PATH_MAX];
  unsigned char test_base[PATH_MAX];
  unsigned char test_path[PATH_MAX];
  unsigned char corr_base[PATH_MAX];
  unsigned char corr_path[PATH_MAX];
  unsigned char info_base[PATH_MAX];
  unsigned char info_path[PATH_MAX];
  unsigned char tgzdir_base[PATH_MAX];
  unsigned char tgzdir_path[PATH_MAX];
  const unsigned char *s;
  int pid = getpid(), serial = 0;
  int retval = 0, status;
  long cpu_time, real_time;

  tmp_work_dir[0] = 0;

  if (!working_dir || !*working_dir) {
    s = getenv("TMPDIR");
    if (!s) s = getenv("TEMPDIR");
#if defined P_tmpdir
    if (!s) s = P_tmpdir;
#endif
    if (!s) s = "/tmp";
    while (1) {
      snprintf(tmp_work_dir, sizeof(tmp_work_dir), "%s/%d.%d", s, pid, ++serial);
      if (mkdir(tmp_work_dir, 0700) >= 0) break;
      if (errno != EEXIST) {
        fatal("cannot create directory %s: %s", tmp_work_dir, os_ErrorMsg());
      }
    }
    working_dir = xstrdup(tmp_work_dir);
  }
  if (!os_IsAbsolutePath(working_dir)) {
    snprintf(abs_work_dir, sizeof(abs_work_dir), "%s/%s", current_dir, working_dir);
    working_dir = xstrdup(abs_work_dir);
  }

  if (!os_IsAbsolutePath(argv[0])) {
    snprintf(abs_prog_name, sizeof(abs_prog_name), "%s/%s", current_dir, argv[0]);
    argv[0] = xstrdup(abs_prog_name);
  }
  if (!os_IsAbsolutePath(test_dir)) {
    snprintf(abs_test_dir, sizeof(abs_test_dir), "%s/%s", current_dir, test_dir);
    test_dir = xstrdup(abs_test_dir);
  }

  serial = 0;
  while (1) {
    snprintf(test_base, sizeof(test_base), test_pattern, ++serial);
    snprintf(test_path, sizeof(test_path), "%s/%s", test_dir, test_base);
    test_file = xstrdup(test_path);
    if (os_CheckAccess(test_path, REUSE_F_OK) < 0) break;
    corr_path[0] = 0;
    info_path[0] = 0;
    corr_file = NULL;
    info_file = NULL;
    if (corr_pattern && corr_pattern[0]) {
      snprintf(corr_base, sizeof(corr_base), corr_pattern, serial);
      snprintf(corr_path, sizeof(corr_path), "%s/%s", test_dir, corr_base);
      corr_file = xstrdup(corr_path);
    }
    if (info_pattern && info_pattern[0]) {
      snprintf(info_base, sizeof(info_base), info_pattern, serial);
      snprintf(info_path, sizeof(info_path), "%s/%s", test_dir, info_base);
      info_file = xstrdup(info_path);
    }
    if (tgzdir_pattern && tgzdir_pattern[0]) {
      snprintf(tgzdir_base, sizeof(tgzdir_base), tgzdir_pattern, serial);
      snprintf(tgzdir_path, sizeof(tgzdir_path), "%s/%s", test_dir, tgzdir_path);
      tgzdir_file = xstrdup(tgzdir_path);
    }
    cpu_time = 0;
    real_time = 0;
    status = run_program(argc, argv, &cpu_time, &real_time);
    if (status == RUN_CHECK_FAILED) retval = RUN_CHECK_FAILED;
    if (status != RUN_OK && retval == RUN_OK) retval = RUN_PARTIAL;
    if (quiet_flag <= 0) {
      printf("%-8d%-8.8s%-8ld%-8ld\n", serial, get_run_status_str(status),
             cpu_time, real_time);
    }
  }

  if (tmp_work_dir[0]) {
    remove_directory_recursively(tmp_work_dir, 0);
  }
  return retval;
}
Exemplo n.º 19
0
static int
read_runlog_version_1(struct rldb_file_cnts *cs)
{
  struct runlog_state *rls = cs->rl_state;
  int rem;
  struct stat stbuf;
  struct run_header_v1 header_v1;
  int run_v1_u, i;
  struct run_entry_v1 *runs_v1 = 0;
  struct run_entry_v1 *po;
  struct run_entry    *pn;

  info("reading runs log version 1 (binary)");

  /* calculate the size of the file */
  if (fstat(cs->run_fd, &stbuf) < 0) {
    err("read_runlog_version_1: fstat() failed: %s", os_ErrorMsg());
    return -1;
  }
  if (sf_lseek(cs->run_fd, 0, SEEK_SET, "run") == (off_t) -1) return -1;
  if (stbuf.st_size < sizeof (header_v1)) {
    err("read_runlog_version_1: file is too small");
    return -1;
  }

  // read header
  if (do_read(cs->run_fd, &header_v1, sizeof(header_v1)) < 0) return -1;
  info("run log version %d", header_v1.version);
  if (header_v1.version != 1) {
    err("unsupported run log version %d", rls->head.version);
    return -1;
  }

  stbuf.st_size -= sizeof(header_v1);
  if ((rem = stbuf.st_size % sizeof(struct run_entry_v1)) != 0) {
    err("bad runs file size: remainder %d", rem);
    return -1;
  }
  run_v1_u = stbuf.st_size / sizeof(struct run_entry_v1);
  if (run_v1_u > 0) {
    XCALLOC(runs_v1, run_v1_u);
    if (do_read(cs->run_fd, runs_v1, sizeof(runs_v1[0]) * run_v1_u) < 0)
      return -1;
  }

  // assign the header
  memset(&rls->head, 0, sizeof(rls->head));
  rls->head.version = 2;
  rls->head.byte_order = 0;
  rls->head.start_time = header_v1.start_time;
  rls->head.sched_time = header_v1.sched_time;
  rls->head.duration = header_v1.duration;
  rls->head.stop_time = header_v1.stop_time;

  // copy version 1 runlog to version 2 runlog
  rls->run_a = 128;
  rls->run_u = run_v1_u;
  while (run_v1_u > rls->run_a) rls->run_a *= 2;
  XCALLOC(rls->runs, rls->run_a);
  for (i = 0; i < rls->run_a; ++i)
    rls->runs[i].status = RUN_EMPTY;

  for (i = 0; i < rls->run_u; i++) {
    po = &runs_v1[i];
    pn = &rls->runs[i];

    pn->run_id = po->submission;
    pn->time = po->timestamp;
    pn->size = po->size;
    pn->a.ip = po->ip;
    memcpy(&pn->sha1, &po->sha1, sizeof(pn->sha1));
    pn->user_id = po->team;
    pn->prob_id = po->problem;
    pn->score = po->score;
    pn->locale_id = po->locale_id;
    pn->lang_id = po->language;
    pn->status = po->status;
    pn->test = po->test;
    pn->is_imported = po->is_imported;
    pn->variant = po->variant;
    pn->is_hidden = po->is_hidden;
    pn->is_readonly = po->is_readonly;
    pn->pages = po->pages;
    pn->score_adj = po->score_adj;
    pn->judge_id = po->judge_id;
    pn->nsec = po->nsec;
  }

  xfree(runs_v1);
  return 0;
}
Exemplo n.º 20
0
int
super_clnt_recv_packet(int sock_fd,
                       struct prot_super_packet *p_res,
                       size_t *p_size, void **p_data)
{
  unsigned char *b, *alloc_mem = 0, *bb;
  int in_size, r, n, code = -SSERV_UNKNOWN_ERROR;
  struct prot_super_packet *pkt;

  if (sock_fd < 0) return -SSERV_ERR_NOT_CONNECTED;

  // read packet length
  b = (unsigned char*) &in_size;
  r = 4;
  while (r > 0) {
    if ((n = read(sock_fd, b, r)) < 0) {
      err("super_cnlt_recv_packet: read() failed: %s", os_ErrorMsg());
      code = -SSERV_ERR_READ_FROM_SERVER;
      goto failed;
    }
    if (!n) {
      err("super_cnlt_recv_packet: unexpected EOF");
      code = -SSERV_ERR_EOF_FROM_SERVER;
      goto failed;
    }
    r -= n; b += n;
  }

  if (p_res) {
    if (in_size != sizeof(*p_res)) {
      err("super_cnlt_recv_packet: unexpected size: %d", in_size);
      code = -SSERV_ERR_PROTOCOL_ERROR;
      goto failed;
    }
    if (p_size || p_data) {
      err("super_cnlt_recv_packet: p_size and p_data must be 0");
      code = -SSERV_ERR_PROTOCOL_ERROR;
      goto failed;
    }
    bb = b = (unsigned char*) p_res;
    r = in_size;
  } else {
    if (!p_size || !p_data) {
      err("super_cnlt_recv_packet: p_size and p_data must be set");
      code = -SSERV_ERR_PROTOCOL_ERROR;
      goto failed;
    }
    if (in_size < sizeof(struct prot_super_packet) || in_size >= 256 * 1024) {
      err("super_cnlt_recv_packet: invalid packet length %d", in_size);
      code = -SSERV_ERR_PROTOCOL_ERROR;
      goto failed;
    }
    bb = b = alloc_mem = (unsigned char*) xcalloc(1, in_size);
    r = in_size;
  }

  while (r > 0) {
    if ((n = read(sock_fd, b, r)) < 0) {
      err("super_cnlt_recv_packet: read() failed: %s", os_ErrorMsg());
      code = -SSERV_ERR_READ_FROM_SERVER;
      goto failed;
    }
    if (!n) {
      err("super_cnlt_recv_packet: unexpected EOF");
      code = -SSERV_ERR_EOF_FROM_SERVER;
      goto failed;
    }
    r -= n; b += n;
  }

  pkt = (struct prot_super_packet*) bb;
  if (pkt->magic != PROT_SUPER_PACKET_MAGIC) {
    err("super_cnlt_recv_packet: bad magic in packet: %04x", pkt->magic);
    code = -SSERV_ERR_PROTOCOL_ERROR;
    goto failed;
  }

  if (p_size) *p_size = in_size;
  if (p_data) *p_data = bb;

  return 0;

 failed:
  xfree(alloc_mem);
  return code;
}
Exemplo n.º 21
0
int
userlist_clnt_send_packet(struct userlist_clnt *clnt,
                          size_t size, void const *buf)
{
  const unsigned char *b;
  int w, n;
  rint32_t size32;
  struct iovec vv[2];

#if !defined PYTHON
  ASSERT(clnt);
  ASSERT(size > 0);
  ASSERT(clnt->fd >= 0);
#endif

  /* -1073741824 is 0xc0000000 or 0xffffffffc0000000 */
  if ((size & -1073741824L)) {
#if defined PYTHON
    PyErr_SetString(PyExc_ValueError, "packet length exceeds 1GiB");
    return -1;
#else
    err("send_packet: packet length exceeds 1GiB");
    return -ULS_ERR_WRITE_ERROR;
#endif
  }
  size32 = (ruint32_t) size;

  vv[0].iov_base = &size32;
  vv[0].iov_len = sizeof(size32); /* 4, actually */
  vv[1].iov_base = (void*) buf;
  vv[1].iov_len = size;

  n = writev(clnt->fd, vv, 2);
  if (n == size + 4) return 0;
  if (n <= 0) goto write_error;

  /* if the fast method did not work out, try the slow one */
  if (n < 4) {
    w = 4 - n;
    b = (const unsigned char*) &size32 + n;
    while (w > 0) {
      if ((n = write(clnt->fd, b, w)) <= 0) goto write_error;
      w -= n;
      b += n;
    }
    n = 4;
  }
  w = size + 4 - n;
  b = (const unsigned char*) buf + n - 4;
  while (w > 0) {
    if ((n = write(clnt->fd, b, w)) <= 0) goto write_error;
    w -= n;
    b += n;
  }

  return 0;

 write_error:
#if defined PYTHON
  PyErr_SetFromErrno(PyExc_IOError);
  close(clnt->fd);
  clnt->fd = -1;
  return -1;
#else
  n = errno;
  err("send_packet: write() failed: %s", os_ErrorMsg());
  close(clnt->fd);
  clnt->fd = -1;
  if (n == EPIPE) return -ULS_ERR_DISCONNECT;
  return -ULS_ERR_WRITE_ERROR;
#endif
}
Exemplo n.º 22
0
int
sock_op_get_creds(
        int sock_fd,
        int conn_id,
        int *p_pid,
        int *p_uid,
        int *p_gid)
{
#if HAVE_SO_PASSCRED
  struct msghdr msg;
  unsigned char msgbuf[512];
  struct cmsghdr *pmsg;
  struct ucred *pcred;
  struct iovec recv_vec[1];
  int val = -1, r;

  memset(&msg, 0, sizeof(msg));
  msg.msg_flags = 0;
  msg.msg_control = msgbuf;
  msg.msg_controllen = sizeof(msgbuf);
  recv_vec[0].iov_base = &val;
  recv_vec[0].iov_len = 4;
  msg.msg_iov = recv_vec;
  msg.msg_iovlen = 1;

  if ((r = recvmsg(sock_fd, &msg, 0)) < 0) {
    err("%d: recvmsg failed: %s", conn_id, os_ErrorMsg());
    return -1;
  }
  if (r != 4) {
    err("%d: read %d bytes instead of 4", conn_id, r);
    return -1;
  }
  if (val != 0) {
    err("%d: expected 4 zero bytes", conn_id);
    return -1;
  }
  if ((msg.msg_flags & MSG_CTRUNC)) {
    err("%d: protocol error: control buffer too small", conn_id);
    return -1;
  }
  pmsg = CMSG_FIRSTHDR(&msg);
  if (!pmsg) {
    err("%d: empty control data", conn_id);
    return -1;
  }
  if (pmsg->cmsg_level != SOL_SOCKET || pmsg->cmsg_type != SCM_CREDENTIALS
      || pmsg->cmsg_len != CMSG_LEN(sizeof(*pcred))) {
    err("%d: protocol error: unexpected control data", conn_id);
    return -1;
  }
  pcred = (struct ucred*) CMSG_DATA(pmsg);
  if (p_pid) *p_pid = pcred->pid;
  if (p_uid) *p_uid = pcred->uid;
  if (p_gid) *p_gid = pcred->gid;
  if (CMSG_NXTHDR(&msg, pmsg)) {
    err("%d: protocol error: unexpected control data", conn_id);
    return -1;
  }
#else
  if (p_pid) *p_pid = getpid();
  if (p_uid) *p_uid = getuid();
  if (p_gid) *p_gid = getgid();
#endif
  return 0;
}
Exemplo n.º 23
0
static void
read_packet(const unsigned char *dir_path)
{
  unsigned char packet_conf_file[EJ_PATH_MAX];
  FILE *f = 0;
  struct generic_section_config *packet_config = 0;
  struct nwrun_in_packet *packet = 0;
  unsigned char result_name[EJ_PATH_MAX];
  unsigned char result_in_dir[EJ_PATH_MAX];
  unsigned char result_dir_dir[EJ_PATH_MAX];
  unsigned char contest_dir[EJ_PATH_MAX];
  struct nwrun_out_packet result;
  unsigned char result_packet_path[EJ_PATH_MAX];
  int clean_result_dir = 0;

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

  snprintf(packet_conf_file,sizeof(packet_conf_file),"%s/packet.cfg",dir_path);
  packet_config = nwrun_in_packet_parse(packet_conf_file, &packet);
  if (!packet_config) goto cleanup;

  nwrun_in_packet_print(stderr, (const struct nwrun_in_packet *) packet_config);
  
  /* setup packet defaults */
  if (packet->contest_id <= 0) {
    err("contest_id is not set");
    goto cleanup;
  }
  if (packet->prob_id <= 0) {
    err("prob_id is not set");
    goto cleanup;
  }
  if (packet->test_num <= 0) {
    err("test_num is not set");
    goto cleanup;
  }
  if (packet->judge_id <= 0) {
    err("judge_id is not set");
    goto cleanup;
  }
  if (!packet->program_name[0]) {
    err("program_name is not set");
    goto cleanup;
  }
  if (!packet->test_file_name[0]) {
    err("test_file_name is not set");
    goto cleanup;
  }
  if (!packet->input_file_name[0]) {
    snprintf(packet->input_file_name, sizeof(packet->input_file_name),
             "%s", DEFAULT_INPUT_FILE_NAME);
  }
  if (!packet->result_file_name[0]) {
    err("result_file_name is not set");
    goto cleanup;
  }
  if (!packet->output_file_name[0]) {
    snprintf(packet->output_file_name, sizeof(packet->output_file_name),
             "%s", DEFAULT_OUTPUT_FILE_NAME);
  }
  if (!packet->error_file_name[0]) {
    snprintf(packet->error_file_name, sizeof(packet->error_file_name),
             "%s", DEFAULT_ERROR_FILE_NAME);
  }

  if (packet->max_output_file_size <= 0) {
    packet->max_output_file_size = DEFAULT_MAX_OUTPUT_FILE_SIZE;
  }
  if (packet->max_error_file_size <= 0) {
    packet->max_error_file_size = DEFAULT_MAX_ERROR_FILE_SIZE;
  }
  if (packet->time_limit_millis <= 0) {
    err("time_limit_millis is invalid (%d)", packet->time_limit_millis);
    goto cleanup;
  }

  /* create the output directory */
  snprintf(result_name, sizeof(result_name), "%c%c%d%c%d%c%d%c%d%c%d",
           get_priority_code(packet->priority - 17),
           get_num_prefix(packet->contest_id), packet->contest_id,
           get_num_prefix(packet->run_id - 1), packet->run_id - 1,
           get_num_prefix(packet->prob_id), packet->prob_id,
           get_num_prefix(packet->test_num), packet->test_num,
           get_num_prefix(packet->judge_id), packet->judge_id);
  if (packet->use_contest_id_in_reply) {
    snprintf(contest_dir, sizeof(contest_dir), "%s/%06d", global->result_dir, packet->contest_id);
    if (make_all_dir(contest_dir, 0777) < 0) {
      goto cleanup;
    }
    snprintf(result_in_dir, sizeof(result_in_dir), "%s/in/%s_%s",
             contest_dir, os_NodeName(), result_name);
    snprintf(result_dir_dir, sizeof(result_dir_dir), "%s/dir/%s",
             contest_dir, result_name);
  } else {
    snprintf(result_in_dir, sizeof(result_in_dir), "%s/in/%s_%s",
             global->result_dir, os_NodeName(), result_name);
    snprintf(result_dir_dir, sizeof(result_dir_dir), "%s/dir/%s",
             global->result_dir, result_name);
  }

  if (make_dir(result_in_dir, 0777) < 0) {
    goto cleanup;
  }
  clean_result_dir = 1;

  // set default values
  snprintf(result.hostname, sizeof(result.hostname), "%s", os_NodeName());
  result.contest_id = packet->contest_id;
  result.run_id = packet->run_id;
  result.prob_id = packet->prob_id;
  result.test_num = packet->test_num;
  result.judge_id = packet->judge_id;
  result.status = RUN_CHECK_FAILED;
  snprintf(result.comment, sizeof(result.comment), "Default status was not changed");

  handle_packet(dir_path, packet, result_in_dir, &result);

  snprintf(result_packet_path, sizeof(result_packet_path), "%s/packet.cfg",
           result_in_dir);
  if (!(f = fopen(result_packet_path, "wb"))) {
    err("cannot open file %s: %s", result_packet_path, os_ErrorMsg());
    goto cleanup;
  }
  nwrun_out_packet_print(f, &result);
  fclose(f); f = 0;

  nwrun_out_packet_print(stderr, &result); 

  if (rename(result_in_dir, result_dir_dir) < 0) {
    err("rename: %s -> %s failed: %s", result_in_dir, result_dir_dir, os_ErrorMsg());
    goto cleanup;
  }
  clean_result_dir = 0;

 cleanup:
  if (clean_result_dir) {
    remove_directory_recursively(result_in_dir, 0);
  }
  nwrun_in_packet_free(packet_config);
  if (f) fclose(f);
}
Exemplo n.º 24
0
int
new_server_clnt_http_request(
        new_server_conn_t conn,
        FILE *log_f,
        int out_fd,
        unsigned char *args[],
        unsigned char *envs[],
        int param_num,
        unsigned char *param_names[],
        size_t param_sizes_in[],
        unsigned char *params[],
        unsigned char **reply_bytes,
        size_t *reply_size)
{
  int arg_num = 0, env_num = 0, i;
  ej_size_t *arg_sizes = 0, *env_sizes = 0, *param_sizes = 0;
  ej_size_t *param_name_sizes = 0;
  ej_size_t t;
  struct new_server_prot_http_request *out = 0;
  size_t out_size;
  unsigned long bptr;// hope,that that's enough for pointer
  int pipe_fd[2] = { -1, -1 }, pass_fd[2];
  int data_fd[2] = { -1, -1 };
  int errcode = -NEW_SRV_ERR_PARAM_OUT_OF_RANGE, r;
  void *void_in = 0;
  size_t in_size = 0;
  struct new_server_prot_packet *in;
  char c;
  const char *emsg = 0;

  if (args) {
    for (; args[arg_num]; arg_num++);
  }
  if (arg_num < 0 || arg_num > MAX_PARAM_NUM) {
    msg(log_f, "invalid number of arguments %d", arg_num);
    goto failed;
  }
  if (envs) {
    for (; envs[env_num]; env_num++);
  }
  if (env_num < 0 || env_num > MAX_PARAM_NUM) {
    msg(log_f, "invalid number of environment vars %d", env_num);
    goto failed;
  }
  if (param_num < 0 || param_num > MAX_PARAM_NUM) {
    msg(log_f, "invalid number of parameters %d", param_num);
    goto failed;
  }

  out_size = sizeof(*out);
  out_size += arg_num * sizeof(ej_size_t);
  out_size += env_num * sizeof(ej_size_t);
  out_size += 2 * param_num * sizeof(ej_size_t);

  if (arg_num > 0) {
    XALLOCAZ(arg_sizes, arg_num);
    for (i = 0; i < arg_num; i++) {
      arg_sizes[i] = t = strlen(args[i]);
      if (/* t < 0 || */ t > MAX_PARAM_SIZE) {
        msg(log_f, "invalid argument length %d", t);
        goto failed;
      }
      out_size += t + 1;
    }
  }

  if (env_num > 0) {
    XALLOCAZ(env_sizes, env_num);
    for (i = 0; i < env_num; i++) {
      env_sizes[i] = t = strlen(envs[i]);
      if (/* t < 0 || */ t > MAX_PARAM_SIZE) {
        msg(log_f, "invalid environment var length %d", t);
        goto failed;
      }
      out_size += t + 1;
    }
  }

  if (param_num > 0) {
    XALLOCAZ(param_name_sizes, param_num);
    XALLOCAZ(param_sizes, param_num);
    for (i = 0; i < param_num; i++) {
      param_name_sizes[i] = t = strlen(param_names[i]);
      if (/* t < 0 || */ t > MAX_PARAM_SIZE) {
        msg(log_f, "invalid parameter name length %d", t);
        goto failed;
      }
      out_size += t + 1;
      param_sizes[i] = t = param_sizes_in[i];
      if (/* t < 0 || */ t > MAX_PARAM_SIZE) {
        msg(log_f, "invalid parameter value length %d", t);
        goto failed;
      }
      out_size += t + 1;
    }
  }

  if (/* out_size < 0 || */ out_size > MAX_PARAM_SIZE) {
    msg(log_f, "invalid total packet size %zu", out_size);
    goto failed;
  }

  out = (struct new_server_prot_http_request*) xcalloc(out_size, 1);
  out->b.magic = NEW_SERVER_PROT_PACKET_MAGIC;
  out->b.id = NEW_SRV_CMD_HTTP_REQUEST;
  out->arg_num = arg_num;
  out->env_num = env_num;
  out->param_num = param_num;

  bptr = (unsigned long) out;
  bptr += sizeof(*out);
  if (arg_num > 0) {
    memcpy((void*) bptr, arg_sizes, arg_num * sizeof(arg_sizes[0]));
    bptr += arg_num * sizeof(arg_sizes[0]);
  }
  if (env_num > 0) {
    memcpy((void*) bptr, env_sizes, env_num * sizeof(env_sizes[0]));
    bptr += env_num * sizeof(env_sizes[0]);
  }
  if (param_num > 0) {
    memcpy((void*) bptr, param_name_sizes, param_num * sizeof(ej_size_t));
    bptr += param_num * sizeof(param_sizes[0]);
    memcpy((void*) bptr, param_sizes, param_num * sizeof(param_sizes[0]));
    bptr += param_num * sizeof(param_sizes[0]);
  }
  for (i = 0; i < arg_num; i++) {
    memcpy((void*) bptr, args[i], arg_sizes[i]);
    bptr += arg_sizes[i] + 1;
  }
  for (i = 0; i < env_num; i++) {
    memcpy((void*) bptr, envs[i], env_sizes[i]);
    bptr += env_sizes[i] + 1;
  }
  for (i = 0; i < param_num; i++) {
    memcpy((void*) bptr, param_names[i], param_name_sizes[i]);
    bptr += param_name_sizes[i] + 1;
    memcpy((void*) bptr, params[i], param_sizes[i]);
    bptr += param_sizes[i] + 1;
  }

  if (pipe(pipe_fd) < 0) {
    emsg = os_ErrorMsg();
    msg(log_f, "waiting pipe() failed: %s", emsg);
    err("new_server_clnt_http_request: pipe() failed: %s", emsg);
    errcode = -NEW_SRV_ERR_SYSTEM_ERROR;
    goto failed;
  }
  if (out_fd < 0) {
    if (pipe(data_fd) < 0) {
      emsg = os_ErrorMsg();
      msg(log_f, "data pipe() failed: %s", emsg);
      err("new_server_clnt_http_request: pipe() failed: %s", emsg);
      errcode = -NEW_SRV_ERR_SYSTEM_ERROR;
      goto failed;
    }
    out_fd = data_fd[1];
  }
  pass_fd[0] = out_fd;
  pass_fd[1] = pipe_fd[1];
  if ((errcode = new_server_clnt_pass_fd(conn, 2, pass_fd)) < 0) {
    msg(log_f, "pass_fd failed: error code: %d", -errcode);
    goto failed;
  }
  close(pipe_fd[1]); pipe_fd[1] = -1;
  if (data_fd[1] >= 0) close(data_fd[1]);
  data_fd[1] = -1;
  if ((errcode = new_server_clnt_send_packet(conn, out_size, out)) < 0) {
    msg(log_f, "send_packet failed: error code: %d", -errcode);
    goto failed;
  }
  if ((errcode = new_server_clnt_recv_packet(conn, &in_size, &void_in)) < 0) {
    msg(log_f, "recv_packet failed: error code: %d", -errcode);
    goto failed;
  }
  errcode = -NEW_SRV_ERR_PROTOCOL_ERROR;
  if (in_size != sizeof(*in)) {
    msg(log_f, "received packet size mismatch");
    err("new_server_clnt_http_request: packet size mismatch");
    goto failed;
  }
  in = (struct new_server_prot_packet*) void_in;
  if (in->magic != NEW_SERVER_PROT_PACKET_MAGIC) {
    msg(log_f, "received packet magic mismatch");
    err("new_server_clnt_http_request: packet magic mismatch");
    goto failed;
  }
  errcode = in->id;
  if (errcode < 0) {
    msg(log_f, "server reply code is %d", -errcode);
    goto failed;
  }

  if (data_fd[0] >= 0) {
    read_from_pipe(data_fd[0], reply_bytes, reply_size);
    close(data_fd[0]); data_fd[0] = -1;
  }

  // wait for the server to complete page generation
  r = read(pipe_fd[0], &c, 1);
  if (r < 0) {
    emsg = os_ErrorMsg();
    msg(log_f, "wait pipe read() failed: %s", emsg);
    err("new_server_clnt_http_request: read() failed: %s", emsg);
    errcode = -NEW_SRV_ERR_READ_ERROR;
    goto failed;
  }
  if (r > 0) {
    msg(log_f, "wait pipe is not empty");
    err("new_server_clnt_http_request: data in wait pipe");
    goto failed;
  }
  errcode = NEW_SRV_RPL_OK;

 failed:
  xfree(out);
  xfree(void_in);
  if (pipe_fd[0] >= 0) close(pipe_fd[0]);
  if (pipe_fd[1] >= 0) close(pipe_fd[1]);
  if (data_fd[0] >= 0) close(data_fd[0]);
  if (data_fd[1] >= 0) close(data_fd[1]);
  return errcode;
}
Exemplo n.º 25
0
int
super_clnt_create_contest(
        int sock_fd,
        int out_fd,
        int cmd,
        int num_mode,
        int templ_mode,
        int contest_id,
        int templ_id,
        const unsigned char *self_url,
        const unsigned char *hidden_vars,
        const unsigned char *extra_args)
{
  struct prot_super_pkt_create_contest *out = 0;
  struct prot_super_packet *in = 0;
  size_t self_url_len, hidden_vars_len, extra_args_len, out_size;
  unsigned char *self_url_ptr, *hidden_vars_ptr, *extra_args_ptr;
  int r, pipe_fd[2], pass_fd[2];
  char c;

  if (sock_fd < 0) return -SSERV_ERR_NOT_CONNECTED;

  if (!self_url) self_url = "";
  if (!hidden_vars) hidden_vars = "";
  if (!extra_args) extra_args = "";
  self_url_len = strlen(self_url);
  hidden_vars_len = strlen(hidden_vars);
  extra_args_len = strlen(extra_args);
  out_size = sizeof(*out) + self_url_len + hidden_vars_len + extra_args_len;

  out = alloca(out_size);
  memset(out, 0, out_size);
  self_url_ptr = out->data;
  hidden_vars_ptr = self_url_ptr + self_url_len + 1;
  extra_args_ptr = hidden_vars_ptr + hidden_vars_len + 1;

  out->b.id = cmd;
  out->b.magic = PROT_SUPER_PACKET_MAGIC;
  out->num_mode = num_mode;
  out->templ_mode = templ_mode;
  out->contest_id = contest_id;
  out->templ_id = templ_id;
  out->self_url_len = self_url_len;
  out->hidden_vars_len = hidden_vars_len;
  out->extra_args_len = extra_args_len;
  memcpy(self_url_ptr, self_url, self_url_len);
  memcpy(hidden_vars_ptr, hidden_vars, hidden_vars_len);
  memcpy(extra_args_ptr, extra_args, extra_args_len);

  if (pipe(pipe_fd) < 0) {
    err("super_clnt_main_page: pipe() failed: %s", os_ErrorMsg());
    return -SSERV_ERR_SYSTEM_ERROR;
  }
  pass_fd[0] = out_fd;
  pass_fd[1] = pipe_fd[1];
  if ((r = super_clnt_pass_fd(sock_fd, 2, pass_fd)) < 0) {
    close(pipe_fd[0]); close(pipe_fd[1]);
    return r;
  }
  close(pipe_fd[1]);

  if ((r = super_clnt_send_packet(sock_fd, out_size, out)) < 0) {
    close(pipe_fd[0]);
    return r;
  }

  in = (struct prot_super_packet*) alloca(sizeof(*in));
  memset(in, 0, sizeof(*in));
  if ((r = super_clnt_recv_packet(sock_fd, in, 0, 0)) < 0) {
    close(pipe_fd[0]);
    return r;
  }

  if (in->id < 0) {
    close(pipe_fd[0]);
    return in->id;
  }
  if (in->id != SSERV_RPL_OK) {
    close(pipe_fd[0]);
    err("super_clnt_main_page: unexpected reply: %d", in->id);
    return -SSERV_ERR_PROTOCOL_ERROR;
  }

  if ((r = read(pipe_fd[0], &c, 1)) < 0) {
    err("super_clnt_main_page: read() failed: %s", os_ErrorMsg());
    close(pipe_fd[0]);
    return -SSERV_ERR_READ_FROM_SERVER;
  }
  if (r > 0) {
    err("super_clnt_main_page: data in wait pipe");
    close(pipe_fd[0]);
    return -SSERV_ERR_PROTOCOL_ERROR;
  }
  close(pipe_fd[0]);
  return SSERV_RPL_OK;
}