Beispiel #1
0
/********************************************************************
  Insert an item into the queue.
*********************************************************************/
void pq_insert(struct pqueue *q, pq_data_t datum, int datum_priority)
{
  int i;

  fc_assert_ret(NULL != q);

  /* allocate more memory if necessary */
  if (q->size >= q->avail) {
    int newsize = q->size + q->step;

    q->cells = fc_realloc(q->cells, sizeof(pq_data_t) * newsize);
    q->priorities = fc_realloc(q->priorities, sizeof(int) * newsize);
    q->avail = newsize;
  }

  /* insert item */
  i = q->size++;
  while (i > 1 && q->priorities[i / 2] < datum_priority) {
    q->cells[i] = q->cells[i / 2];
    q->priorities[i] = q->priorities[i / 2];
    i /= 2;
  }
  q->cells[i] = datum;
  q->priorities[i] = datum_priority;
}
Beispiel #2
0
/**************************************************************************
  Set one auth option.
**************************************************************************/
static bool set_auth_option(struct auth_option *target, const char *value,
                            enum auth_option_source source)
{
  if (value != NULL
      && !strcmp(target->name, "port")) {
    /* Port value must be all numeric. */
    int i;

    for (i = 0; value[i] != '\0'; i++) {
      if (value[i] < '0' || value[i] > '9') {
        freelog(LOG_ERROR, _("Illegal value for auth port: \"%s\""), value);
        return FALSE;
      }
    }
  }

  if (value == NULL) {
    if (target->value != NULL) {
      free(target->value);
    }
    target->value = NULL;
  } else {
    target->value = fc_realloc(target->value, strlen(value) + 1);
    memcpy(target->value, value, strlen(value) + 1);
  }
  target->source = source;

  return TRUE;
}
Beispiel #3
0
/**************************************************************************
  Initialize ai traits for player
**************************************************************************/
void ai_traits_init(struct player *pplayer)
{
  enum trait tr;

  pplayer->ai_common.traits = fc_realloc(pplayer->ai_common.traits,
                                         sizeof(struct ai_trait) * TRAIT_COUNT);

  for (tr = trait_begin(); tr != trait_end(); tr = trait_next(tr)) {
    pplayer->ai_common.traits[tr].mod = 0;
  }
}
/**************************************************************************
...
**************************************************************************/
static bool buffer_ensure_free_extra_space(struct socket_packet_buffer *buf,
					   int extra_space)
{
  /* room for more? */
  if (buf->nsize - buf->ndata < extra_space) {
    buf->nsize = buf->ndata + extra_space;

    /* added this check so we don't gobble up too much mem */
    if (buf->nsize > MAX_LEN_BUFFER) {
      return FALSE;
    }
    buf->data = (unsigned char *) fc_realloc(buf->data, buf->nsize);
  }
  return TRUE;
}
Beispiel #5
0
/**********************************************************************
  Check that astr has enough size to hold n, and realloc to a bigger
  size if necessary.  Here n must be big enough to include the trailing
  ascii-null if required.  The requested n is stored in astr->n.
  The actual amount allocated may be larger than n, and is stored
  in astr->n_alloc.
***********************************************************************/
void astr_minsize(struct astring *astr, size_t n)
{
  int n1;
  bool was_null = (astr->n == 0);
  
  assert(astr != NULL);
  
  astr->n = n;
  if (n <= astr->n_alloc) {
    return;
  }
  
  /* allocated more if this is only a small increase on before: */
  n1 = (3*(astr->n_alloc+10)) / 2;
  astr->n_alloc = (n > n1) ? n : n1;
  astr->str = (char *)fc_realloc(astr->str, astr->n_alloc);
  if (was_null) {
    astr_clear(astr);
  }
}
Beispiel #6
0
/***************************************************************************
  Resize a dynamic bitvector. Create it if needed.
***************************************************************************/
void dbv_resize(struct dbv *pdbv, int bits)
{
  fc_assert_ret(bits > 0 && bits < MAX_DBV_LENGTH);

  if (pdbv->vec == NULL) {
    /* Initialise a new dbv. */
    dbv_init(pdbv, bits);
  } else {
    /* Resize an existing dbv. */
    fc_assert_ret(pdbv->bits != 0);

    if (bits != pdbv->bits) {
      pdbv->bits = bits;
      pdbv->vec = fc_realloc(pdbv->vec,
                             _BV_BYTES(pdbv->bits) * sizeof(*pdbv->vec));
    }

    dbv_clr_all(pdbv);
  }
}
Beispiel #7
0
/**************************************************************************
  ...
**************************************************************************/
SDL_String16 * copy_chars_to_string16(SDL_String16 *pString,
						const char *pCharString)
{
  size_t n;

  fc_assert_ret_val(pString != NULL, NULL);
  fc_assert_ret_val(pCharString != NULL, NULL);
  
  n = (strlen(pCharString) + 1) * 2;
  
  if (n > pString->n_alloc) {
    /* allocated more if this is only a small increase on before: */
    size_t n1 = (3 * pString->n_alloc) / 2;
    pString->n_alloc = (n > n1) ? n : n1;
    pString->text = fc_realloc(pString->text, pString->n_alloc);
  }
  
  convertcopy_to_utf16(pString->text, pString->n_alloc, pCharString);
  
  return pString;
}
Beispiel #8
0
/**************************************************************************
presult indicates if there is more packets in the cache. We return result
instead of just testing if the returning package is NULL as we sometimes
return a NULL packet even if everything is OK (receive_packet_goto_route).
**************************************************************************/
void *get_packet_from_connection(struct connection *pc,
				 enum packet_type *ptype, bool * presult)
{
  int len_read;
  int whole_packet_len;
  struct {
    enum packet_type type;
    int itype;
  } utype;
  struct data_in din;
#ifdef USE_COMPRESSION
  bool compressed_packet = FALSE;
  int header_size = 0;
#endif

  *presult = FALSE;

  if (!pc->used) {
    return NULL;		/* connection was closed, stop reading */
  }
  
  if (pc->buffer->ndata < 3) {
    return NULL;           /* length and type not read */
  }

  dio_input_init(&din, pc->buffer->data, pc->buffer->ndata);
  dio_get_uint16(&din, &len_read);

  /* The non-compressed case */
  whole_packet_len = len_read;

#ifdef USE_COMPRESSION
  if (len_read == JUMBO_SIZE) {
    compressed_packet = TRUE;
    header_size = 6;
    if (dio_input_remaining(&din) >= 4) {
      dio_get_uint32(&din, &whole_packet_len);
      log_compress("COMPRESS: got a jumbo packet of size %d",
                   whole_packet_len);
    } else {
      /* to return NULL below */
      whole_packet_len = 6;
    }
  } else if (len_read >= COMPRESSION_BORDER) {
    compressed_packet = TRUE;
    header_size = 2;
    whole_packet_len = len_read - COMPRESSION_BORDER;
    log_compress("COMPRESS: got a normal packet of size %d",
                 whole_packet_len);
  }
#endif

  if ((unsigned)whole_packet_len > pc->buffer->ndata) {
    return NULL;		/* not all data has been read */
  }

#ifdef USE_COMPRESSION
  if (compressed_packet) {
    uLong compressed_size = whole_packet_len - header_size;
    /* 
     * We don't know the decompressed size. We assume a bad case
     * here: an expansion by an factor of 100. 
     */
    unsigned long int decompressed_size = 100 * compressed_size;
    void *decompressed = fc_malloc(decompressed_size);
    int error;
    struct socket_packet_buffer *buffer = pc->buffer;
    
    error =
	uncompress(decompressed, &decompressed_size,
		   ADD_TO_POINTER(buffer->data, header_size), 
		   compressed_size);
    if (error != Z_OK) {
      log_verbose("Uncompressing of the packet stream failed. "
                  "The connection will be closed now.");
      connection_close(pc, _("decoding error"));
      return NULL;
    }

    buffer->ndata -= whole_packet_len;
    /* 
     * Remove the packet with the compressed data and shift all the
     * remaining data to the front. 
     */
    memmove(buffer->data, buffer->data + whole_packet_len, buffer->ndata);

    if (buffer->ndata + decompressed_size > buffer->nsize) {
      buffer->nsize += decompressed_size;
      buffer->data = fc_realloc(buffer->data, buffer->nsize);
    }

    /*
     * Make place for the uncompressed data by moving the remaining
     * data.
     */
    memmove(buffer->data + decompressed_size, buffer->data, buffer->ndata);

    /* 
     * Copy the uncompressed data.
     */
    memcpy(buffer->data, decompressed, decompressed_size);

    free(decompressed);

    buffer->ndata += decompressed_size;
    
    log_compress("COMPRESS: decompressed %ld into %ld",
                 compressed_size, decompressed_size);

    return get_packet_from_connection(pc, ptype, presult);
  }
#endif

  /*
   * At this point the packet is a plain uncompressed one. These have
   * to have to be at least 3 bytes in size.
   */
  if (whole_packet_len < 3) {
    log_verbose("The packet stream is corrupt. The connection "
                "will be closed now.");
    connection_close(pc, _("decoding error"));
    return NULL;
  }

  dio_get_uint8(&din, &utype.itype);

  utype.type = utype.itype;

  log_packet("got packet type=(%s)%d len=%d from %s",
             packet_name(utype.type), utype.itype, whole_packet_len,
             is_server() ? pc->username : "******");

  *ptype = utype.type;
  *presult = TRUE;

  if (pc->incoming_packet_notify) {
    pc->incoming_packet_notify(pc, utype.type, whole_packet_len);
  }

#if PACKET_SIZE_STATISTICS 
  {
    static struct {
      int counter;
      int size;
    } packets_stats[PACKET_LAST];
    static int packet_counter = 0;

    int packet_type = utype.itype;
    int size = whole_packet_len;

    if (!packet_counter) {
      int i;

      for (i = 0; i < PACKET_LAST; i++) {
	packets_stats[i].counter = 0;
	packets_stats[i].size = 0;
      }
    }

    packets_stats[packet_type].counter++;
    packets_stats[packet_type].size += size;

    packet_counter++;
    if (packet_counter % 100 == 0) {
      int i, sum = 0;

      log_test("Received packets:");
      for (i = 0; i < PACKET_LAST; i++) {
	if (packets_stats[i].counter == 0)
	  continue;
	sum += packets_stats[i].size;
        log_test("  [%-25.25s %3d]: %6d packets; %8d bytes total; "
                 "%5d bytes/packet average",
                 packet_name(i), i, packets_stats[i].counter,
                 packets_stats[i].size,
                 packets_stats[i].size / packets_stats[i].counter);
      }
      log_test("received %d bytes in %d packets;average size "
               "per packet %d bytes",
               sum, packet_counter, sum / packet_counter);
    }
  }
#endif
  return get_packet_from_connection_helper(pc, utype.type);
}