Exemplo n.º 1
0
static int
read_scores (const char *filename, struct score_entry **scores,
	     ptrdiff_t *count, ptrdiff_t *alloc)
{
  int readval = -1;
  ptrdiff_t scorecount = 0;
  ptrdiff_t cursize = 0;
  struct score_entry *ret = 0;
  struct score_entry entry;
  FILE *f = fopen (filename, "r");
  int retval = -1;
  if (!f)
    return -1;
  while ((readval = read_score (f, &entry)) == 0)
    if (push_score (&ret, &scorecount, &cursize, &entry) < 0)
      return -1;
  if (readval > 0 && fclose (f) == 0)
    {
      *count = scorecount;
      *alloc = cursize;
      *scores = ret;
      retval = 0;
    }
  return retval;
}
Exemplo n.º 2
0
static int
read_scores (const char *filename, struct score_entry **scores,
	     ptrdiff_t *count, ptrdiff_t *alloc)
{
  char *p, *filedata;
  ptrdiff_t filesize, nread;
  struct stat st;
  FILE *f = fopen (filename, "r");
  if (!f)
    return -1;
  if (fstat (fileno (f), &st) != 0)
    return -1;
  if (! (0 <= st.st_size && st.st_size < min (PTRDIFF_MAX, SIZE_MAX)))
    {
      errno = EOVERFLOW;
      return -1;
    }
  filesize = st.st_size;
  filedata = malloc (filesize + 1);
  if (! filedata)
    return -1;
  nread = fread (filedata, 1, filesize + 1, f);
  if (filesize < nread)
    {
      errno = 0;
      return -1;
    }
  if (nread < filesize)
    filesize = nread;
  if (ferror (f) || fclose (f) != 0)
    return -1;
  filedata[filesize] = 0;
  if (strlen (filedata) != filesize)
    {
      errno = 0;
      return -1;
    }

  *scores = 0;
  *count = *alloc = 0;
  for (p = filedata; p < filedata + filesize; )
    {
      struct score_entry entry;
      p = read_score (p, &entry);
      if (!p)
	{
	  errno = 0;
	  return -1;
	}
      if (push_score (scores, count, alloc, &entry) < 0)
	return -1;
    }
  return 0;
}
Exemplo n.º 3
0
int
main (int argc, char **argv)
{
  int c;
  bool running_suid;
  void *lockstate;
  char *scorefile;
  char *nl;
  const char *prefix, *user_prefix = NULL;
  struct stat buf;
  struct score_entry *scores;
  struct score_entry newscore;
  bool reverse = false;
  ptrdiff_t scorecount, scorealloc;
  ptrdiff_t max_scores = MAX_SCORES;

  srand (time (0));

  while ((c = getopt (argc, argv, "hrm:d:")) != -1)
    switch (c)
      {
      case 'h':
	usage (EXIT_SUCCESS);
	break;
      case 'd':
	user_prefix = optarg;
	break;
      case 'r':
	reverse = 1;
	break;
      case 'm':
	{
	  intmax_t m = strtoimax (optarg, 0, 10);
	  if (m < 0)
	    usage (EXIT_FAILURE);
	  max_scores = min (m, MAX_SCORES);
	}
	break;
      default:
	usage (EXIT_FAILURE);
      }

  if (argc - optind != 3)
    usage (EXIT_FAILURE);

  running_suid = (getuid () != geteuid ());

  prefix = get_prefix (running_suid, user_prefix);

  scorefile = malloc (strlen (prefix) + strlen (argv[optind]) + 2);
  if (!scorefile)
    lose_syserr ("Couldn't allocate score file");

  strcpy (scorefile, prefix);
  strcat (scorefile, "/");
  strcat (scorefile, argv[optind]);

  newscore.score = strtoimax (argv[optind + 1], 0, 10);

  newscore.data = argv[optind + 2];
  if (strlen (newscore.data) > MAX_DATA_LEN)
    newscore.data[MAX_DATA_LEN] = '\0';
  nl = strchr (newscore.data, '\n');
  if (nl)
    *nl = '\0';

  newscore.username = get_user_id ();
  if (! newscore.username)
    lose_syserr ("Couldn't determine user id");

  if (stat (scorefile, &buf) < 0)
    lose_syserr ("Failed to access scores file");

  if (lock_file (scorefile, &lockstate) < 0)
    lose_syserr ("Failed to lock scores file");

  if (read_scores (scorefile, &scores, &scorecount, &scorealloc) < 0)
    {
      unlock_file (scorefile, lockstate);
      lose_syserr ("Failed to read scores file");
    }
  if (push_score (&scores, &scorecount, &scorealloc, &newscore) < 0)
    {
      unlock_file (scorefile, lockstate);
      lose_syserr ("Failed to add score");
    }
  sort_scores (scores, scorecount, reverse);
  /* Limit the number of scores.  If we're using reverse sorting, then
     also increment the beginning of the array, to skip over the
     *smallest* scores.  Otherwise, just decrementing the number of
     scores suffices, since the smallest is at the end. */
  if (scorecount > max_scores)
    {
      if (reverse)
	scores += scorecount - max_scores;
      scorecount = max_scores;
    }
  if (write_scores (scorefile, scores, scorecount) < 0)
    {
      unlock_file (scorefile, lockstate);
      lose_syserr ("Failed to write scores file");
    }
  if (unlock_file (scorefile, lockstate) < 0)
    lose_syserr ("Failed to unlock scores file");
  exit (EXIT_SUCCESS);
}
Exemplo n.º 4
0
void test_scored_subexpression() {
  // Create a database with the default options.
  auto db = grnxx::open_db("");

  // Create a table with the default options.
  auto table = db->create_table("Table");

  constexpr size_t NUM_ROWS = 1 << 16;

  // Generate random values.
  grnxx::Array<grnxx::Float> float_values;
  grnxx::Array<grnxx::Int> ref_values;
  float_values.resize(NUM_ROWS);
  ref_values.resize(NUM_ROWS);
  for (size_t i = 0; i < NUM_ROWS; ++i) {
    float_values[i] = grnxx::Float(1.0 * rng() / rng.max());
//    ref_values[i] = mersenne_twister() % NUM_ROWS;
    ref_values[i] = grnxx::Int(0);
  }

  // Create columns for Float and Int values.
  auto float_column = table->create_column("Float", GRNXX_FLOAT);
  grnxx::ColumnOptions options;
  options.reference_table_name = "Table";
  auto ref_column = table->create_column("Ref", GRNXX_INT, options);

  // Store generated values into columns.
  for (size_t i = 0; i < NUM_ROWS; ++i) {
    grnxx::Int row_id = table->insert_row();
    assert(row_id.match(grnxx::Int(i)));
    float_column->set(row_id, float_values[i]);
  }
  for (size_t i = 0; i < NUM_ROWS; ++i) {
    ref_column->set(grnxx::Int(i), ref_values[i]);
  }

  // Generate a list of records.
  grnxx::Array<grnxx::Record> records;
  auto cursor = table->create_cursor();
  assert(cursor->read_all(&records) == table->num_rows());

  // Set scores (Float).
  auto builder = grnxx::ExpressionBuilder::create(table);
  builder->push_column("Float");
  auto expression = builder->release();
  expression->adjust(&records);

  // Test an expression (Ref.(_score > 0.5)).
  builder->push_column("Ref");
  builder->begin_subexpression();
  builder->push_score();
  builder->push_constant(grnxx::Float(0.5));
  builder->push_operator(GRNXX_GREATER);
  builder->end_subexpression();
  expression = builder->release();

  expression->filter(&records);
  size_t count = 0;
  for (size_t i = 0; i < NUM_ROWS; ++i) {
    if (float_values[i].raw() > 0.5) {
      assert(records[count].row_id.match(grnxx::Int(i)));
      ++count;
    }
  }
  assert(records.size() == count);
}
Exemplo n.º 5
0
int
main (int argc, char **argv)
{
  int c;
  bool running_suid, running_sgid;
  void *lockstate;
  char *scorefile;
  char *end, *nl, *user, *data;
  const char *prefix, *user_prefix = NULL;
  struct score_entry *scores;
  struct score_entry newscore;
  bool reverse = false;
  ptrdiff_t scorecount, scorealloc;
  ptrdiff_t max_scores = MAX_SCORES;

  srand (time (0));

  while ((c = getopt (argc, argv, "hrm:d:")) != -1)
    switch (c)
      {
      case 'h':
	usage (EXIT_SUCCESS);
	break;
      case 'd':
	user_prefix = optarg;
	break;
      case 'r':
	reverse = 1;
	break;
      case 'm':
	{
	  intmax_t m = strtoimax (optarg, &end, 10);
	  if (optarg == end || *end || m < 0)
	    usage (EXIT_FAILURE);
	  max_scores = min (m, MAX_SCORES);
	}
	break;
      default:
	usage (EXIT_FAILURE);
      }

  if (argc - optind != 3)
    usage (EXIT_FAILURE);

  running_suid = (getuid () != geteuid ());
  running_sgid = (getgid () != getegid ());
  if (running_suid && running_sgid)
    lose ("This program can run either suid or sgid, but not both.");

  prefix = get_prefix (running_suid || running_sgid, user_prefix);

  scorefile = malloc (strlen (prefix) + strlen (argv[optind]) + 2);
  if (!scorefile)
    lose_syserr ("Couldn't allocate score file");

  char *z = stpcpy (scorefile, prefix);
  *z++ = '/';
  strcpy (z, argv[optind]);

  newscore.score = normalize_integer (argv[optind + 1]);
  if (! newscore.score)
    {
      fprintf (stderr, "%s: Invalid score\n", argv[optind + 1]);
      return EXIT_FAILURE;
    }

  user = get_user_id ();
  if (! user)
    lose_syserr ("Couldn't determine user id");
  data = argv[optind + 2];
  if (strlen (data) > MAX_DATA_LEN)
    data[MAX_DATA_LEN] = '\0';
  nl = strchr (data, '\n');
  if (nl)
    *nl = '\0';
  newscore.user_data = malloc (strlen (user) + 1 + strlen (data) + 1);
  if (! newscore.user_data
      || sprintf (newscore.user_data, "%s %s", user, data) < 0)
    lose_syserr ("Memory exhausted");

  if (lock_file (scorefile, &lockstate) < 0)
    lose_syserr ("Failed to lock scores file");

  if (read_scores (scorefile, &scores, &scorecount, &scorealloc) < 0)
    {
      unlock_file (scorefile, lockstate);
      lose_syserr ("Failed to read scores file");
    }
  if (push_score (&scores, &scorecount, &scorealloc, &newscore) < 0)
    {
      unlock_file (scorefile, lockstate);
      lose_syserr ("Failed to add score");
    }
  sort_scores (scores, scorecount, reverse);
  /* Limit the number of scores.  If we're using reverse sorting, then
     also increment the beginning of the array, to skip over the
     *smallest* scores.  Otherwise, just decrementing the number of
     scores suffices, since the smallest is at the end. */
  if (scorecount > max_scores)
    {
      if (reverse)
	scores += scorecount - max_scores;
      scorecount = max_scores;
    }
  if (write_scores (scorefile, running_sgid ? 0664 : 0644,
		    scores, scorecount) < 0)
    {
      unlock_file (scorefile, lockstate);
      lose_syserr ("Failed to write scores file");
    }
  if (unlock_file (scorefile, lockstate) < 0)
    lose_syserr ("Failed to unlock scores file");
  exit (EXIT_SUCCESS);
}