Esempio n. 1
0
static void
z_header_set_destroy_foreach(gpointer key G_GNUC_UNUSED,
                                         gpointer value,
                                         gpointer user_data G_GNUC_UNUSED)
{
  z_enter();
  z_header_set_destroy_chain((GList *)value);
  z_return();
}
Esempio n. 2
0
/**
 * anypy_proxy_new:
 * @params: parameters for the AnyPyProxy class constructor
 *
 * This function is called upon startup to create a new AnyPy proxy.
 **/
ZProxy *
anypy_proxy_new(ZProxyParams *params)
{
  AnyPyProxy *self;
  
  z_enter();
  self = Z_CAST(z_proxy_new(Z_CLASS(AnyPyProxy), params), AnyPyProxy);
  z_return(&self->super);
}
Esempio n. 3
0
/**
 * finger_proxy_new:
 * @params: ZProxyParams structure
 *
 * Finger proxy constructor. Allocates and initializes a proxy instance,
 * starts proxy thread.
 **/
static ZProxy *
finger_proxy_new(ZProxyParams *params)
{
    FingerProxy  *self;

    z_enter();
    self = Z_CAST(z_proxy_new(Z_CLASS(FingerProxy), params), FingerProxy);
    z_return((ZProxy *) self);
}
Esempio n. 4
0
/**
 * Reads some data from the blob into a buffer.
 *
 * @param[in] self this
 * @param[in] pos position to read from
 * @param[in] data buffer to read into
 * @param[in] req_datalen bytes to read
 * @param[in] timeout timeout
 *
 * @returns The amount of data actually read.
 **/
gsize
z_blob_get_copy(ZBlob *self, gint64 pos, gchar* data, gsize req_datalen, gint timeout)
{
  off_t         err;
  gssize        rd = 0;

  z_enter();
  g_assert(self);
  g_assert(data);
  g_assert(pos >= 0);
  if (pos < self->size)
    {
      if (req_datalen > (guint64) (self->size - pos))
        req_datalen = self->size - pos;
      if (z_blob_lock(self, timeout))
        {
          if (self->is_in_file)
            {
              gssize remain;
              err = lseek(self->fd, pos, SEEK_SET);
              if (err < 0)
                {
                  z_log(NULL, CORE_ERROR, 0, "Blob error, lseek() failed; file='%s', error='%s'", self->filename, g_strerror(errno));
                  g_assert(0);
                }
              remain = req_datalen;
              while (remain > 0)
                {
                  rd = read(self->fd, data, remain);
                  if (rd < 0)
                    {
                      if (errno == EINTR)
                        {
                          continue;
                        }
                      else
                        {
                          z_log(NULL, CORE_ERROR, 0, "Blob error, read() failed; file='%s', error='%s'", self->filename, g_strerror(errno));
                          g_assert(0);
                        }
                    }
                  remain -= rd;
                }
            }
          else
            {
              memmove(data, self->data + pos, req_datalen);
              rd = req_datalen;
            }
          self->stat.req_rd++;
          self->stat.total_rd += rd;
          self->stat.last_accessed = time(NULL);
          z_blob_unlock(self);
        }
    }
  z_return(rd);          
}
Esempio n. 5
0
/**
 * Get the (absolute) filename assigned to the blob.
 *
 * @param[in] self this
 * @param[in] user Owner of the created file or NULL
 * @param[in] group Group of the created file or NULL
 * @param[in] mode Mode of the created file of -1
 * @param[in] timeout timeout
 *
 * @returns The filename
 **/
const gchar * 
z_blob_get_file(ZBlob *self, const gchar *user, const gchar *group, gint mode, gint timeout)
{
  const gchar   *res = NULL;

  z_enter();
  g_assert(self);
  if (!self->filename || !self->system)
    z_return(NULL);

  if (z_blob_lock(self, timeout))
    {
      if (!self->is_in_file)
        {
          if (self->storage_locked)
            goto exit;

          g_mutex_lock(self->system->mtx_blobsys); /* swap_out() accesses the blob systems data
                                                      directly, so it needs to be locked */
          z_blob_swap_out(self);
          g_mutex_unlock(self->system->mtx_blobsys);
        }
      if (group || user)
        {
          uid_t user_id = -1;
          gid_t group_id = -1;
          
          if (user && !z_resolve_user(user, &user_id))
            {
              z_log(NULL, CORE_ERROR, 3, "Cannot resolve user; user='******'", user);
              goto exit;
            }
          
          if (group && !z_resolve_group(group, &group_id))
            {
              z_log(NULL, CORE_ERROR, 3, "Cannot resolve group; group='%s'", group);
              goto exit;
            }
          
          if (chown(self->filename, user_id, group_id) == -1)
            goto exit;
        }

      if ((mode != -1) && (chmod(self->filename, mode) == -1))
        goto exit;

      res = self->filename;

exit:
      if (res == NULL)
        z_blob_unlock(self);
    }

  z_return(res); 
}
Esempio n. 6
0
/**
 * Destroy the default blob system.
 **/
void
z_blob_system_default_destroy(void)
{
  z_enter();
  if (z_blob_system_default)
    {
      z_blob_system_unref(z_blob_system_default);
      z_blob_system_default = NULL;
    }
  z_return();
}
Esempio n. 7
0
/**
 * Create a new ZCodeBase64Decode instance.
 *
 * @param[in]      bufsize initial buffer size
 * @param[in]      error_tolerant whether to be tolerant of errors in input
 *
 * @returns new object
 **/
ZCode *
z_code_base64_decode_new(gint bufsize, gboolean error_tolerant)
{
  ZCodeBase64Decode *self;

  z_enter();
  self = g_new0(ZCodeBase64Decode, 1);
  z_code_base64_decode_init(self, bufsize, error_tolerant);
  z_leave();
  return &self->super;
}
Esempio n. 8
0
/**
 * Initialize ZCodeBase64Decode instance.
 *
 * @param[in] self ZCodeBase64Decode instance
 * @param[in] bufsize initial buffer size
 * @param[in] error_tolerant whether to be tolerant of errors in input
 **/
static void
z_code_base64_decode_init(ZCodeBase64Decode *self, gint bufsize, gboolean error_tolerant)
{
  z_enter();
  z_code_init(&self->super, bufsize);
  self->super.transform = z_code_base64_decode_transform;
  self->super.finish = z_code_base64_decode_finish;
  self->phase = 0;
  self->error_tolerant = error_tolerant;
  z_leave();
}
Esempio n. 9
0
/**
 * Create a new ZCodeBase64Encode instance.
 *
 * @param[in]      bufsize initial buffer size
 * @param[in]      linelen line length in output
 * 
 * @returns new object
 **/
ZCode*
z_code_base64_encode_new(gint bufsize, gint linelen)
{
  ZCodeBase64Encode *self;

  z_enter();
  self = g_new0(ZCodeBase64Encode, 1);
  z_code_base64_encode_init(self, bufsize, linelen);
  z_leave();
  return &self->super;
}
Esempio n. 10
0
/**
 * Initialize the default blob system.
 **/
void
z_blob_system_default_init(void)
{
  z_enter();
  z_blob_system_default = z_blob_system_new(z_blob_system_default_tmpdir,
                                            z_blob_system_default_max_disk_usage,
                                            z_blob_system_default_max_mem_usage,
                                            z_blob_system_default_lowat,
                                            z_blob_system_default_hiwat,
                                            z_blob_system_default_noswap_max);
  z_return();
}
Esempio n. 11
0
/**
 * Initialize ZCodeBase64Encode instance.
 *
 * @param[in] self ZCodeBase64Encode instance
 * @param[in] bufsize initial buffer size
 * @param[in] linelen line length in output
 **/
static void
z_code_base64_encode_init(ZCodeBase64Encode *self, gint bufsize, gint linelen)
{
  z_enter();
  z_code_init(&self->super, bufsize);
  self->super.transform = z_code_base64_encode_transform;
  self->super.finish = z_code_base64_encode_finish;
  self->phase = 0;
  self->linepos = 0;
  self->linelen = linelen;
  z_leave();
}
Esempio n. 12
0
GList *
z_header_set_get_all_headers(ZHeaderSet *self)
{
  GList *ret = NULL;

  z_enter();
  g_hash_table_foreach(self->headers,
                       z_header_set_append_foreach,
                       &ret);
  ret = g_list_reverse(ret);
  z_return(ret);
}
Esempio n. 13
0
/**
 * binary -> base64 conversion
 *
 * @param[in] s this
 * @param[in] from_ source buffer
 * @param[in] fromlen source buffer length
 *
 * @returns Whether conversion succeeded
 **/
static gboolean
z_code_base64_encode_transform(ZCode *s, const void *from_, gsize fromlen)
{
  ZCodeBase64Encode *self = (ZCodeBase64Encode *) s;
  gsize pos, buf_used_orig;
  const guchar *from = from_;
  
  z_enter();
  z_code_grow((ZCode*)self, z_code_calculate_growing(self->super.buf_used, fromlen, self->linelen));
  
  /* This may allocate 4 excess bytes - but requires no further realloc()s.
   * Since the calculation uses buf_used, these 4 bytes won't accumulate, but
   * will be used in the future write()s, so the extra 4 is a grand total. */
 
  z_log(NULL, CORE_DUMP, 8, "Encoding base64 data; len='%" G_GSIZE_FORMAT"', phase='%d', used='%" G_GSIZE_FORMAT "', partial='0x%02x'",
        fromlen, self->phase, self->super.buf_used, self->super.buf[self->super.buf_used]);
  z_log_data_dump(NULL, CORE_DEBUG, 8, from, fromlen);

  buf_used_orig = self->super.buf_used;

  for (pos = 0; pos < fromlen; pos++)
    {
      switch (self->phase)
        {
        case 0: /* no previous partial content, (00.. ...., 00.. ....) -> (00xx xxxx, 00xx ....) */
          self->super.buf[self->super.buf_used] = from[pos] >> 2;
          z_code_base64_encode_fix(self, FALSE);
          self->super.buf[self->super.buf_used] = (from[pos] & 0x03) << 4;
          break;

        case 1: /* 2 upper bits already set, (00yy ...., 00.. ....) -> (00yy xxxx, 00xx xx..) */
          self->super.buf[self->super.buf_used] |= from[pos] >> 4;
          z_code_base64_encode_fix(self, FALSE);
          self->super.buf[self->super.buf_used] = (from[pos] & 0x0f) << 2;
          break;

        case 2: /* 4 upper bits already set, (00yy yy.., 00.. ....) -> (00yy yyxx, 00xx xxxx) */
          self->super.buf[self->super.buf_used] |= from[pos] >> 6;
          z_code_base64_encode_fix(self, FALSE);
          self->super.buf[self->super.buf_used] = from[pos] & 0x3f;
          z_code_base64_encode_fix(self, FALSE);
          break;
        }
      self->phase = (self->phase + 1) % 3;
    }
  z_log(NULL, CORE_DUMP, 8, "Encoded base64 data; len='%" G_GSIZE_FORMAT "', phase='%d', used='%" G_GSIZE_FORMAT "', partial='0x%02x'",
        self->super.buf_used - buf_used_orig, self->phase, self->super.buf_used, self->super.buf[self->super.buf_used]);
  z_log_data_dump(NULL, CORE_DEBUG, 8, self->super.buf + buf_used_orig, self->super.buf_used - buf_used_orig);

  z_leave();
  return TRUE;
}
Esempio n. 14
0
/**
 * Release the lock on the blob after z_blob_get_file.
 *
 * @param[in] self this
 *
 * Besides releasing the lock itself, this function also updates the
 * blob size from the file size.
 **/
void
z_blob_release_file(ZBlob *self)
{
  struct stat st;
  
  z_enter();
  g_assert(self);
  if (!fstat(self->fd, &st))
    self->size = self->alloc_size = st.st_size;
  else
    z_log(NULL, CORE_ERROR, 3, "Cannot stat file on release, blob size may be incorrect from now;");
  z_blob_unlock(self);
  z_return();
}
Esempio n. 15
0
gboolean
z_kzorp_get_lookup_result(gint fd, struct z_kzorp_lookup_result *result)
{
  socklen_t size = sizeof(*result);

  z_enter();

  if (getsockopt(fd, SOL_IP, SO_KZORP_RESULT, result, &size) < 0)
    {
      z_log(NULL, CORE_ERROR, 3, "Error querying KZorp lookup result; fd='%d', error='%s'", fd, g_strerror(errno));
      z_return(FALSE);
    }

  z_return(TRUE);
}
Esempio n. 16
0
/**
 * Create a new blob.
 *
 * @param[in] sys Blob system to create the blob into
 * @param[in] initial_size Initial size to allocate.
 *
 * This function creates a new blob. If sys is NULL, z_blob_system_default will be used.
 *
 * @returns The new blob instance
 **/
ZBlob*
z_blob_new(ZBlobSystem *sys, gsize initial_size)
{
  ZBlob   *self;

  z_enter();
  if (!sys)
    sys = z_blob_system_default;

  if (!sys || !sys->active) 
    z_return(NULL);

  self = g_new0(ZBlob, 1);
  self->system = sys;

  self->filename = g_strdup_printf("%s/blob_XXXXXX", self->system->dir);
  self->fd = mkstemp(self->filename);

  if (self->fd < 0)
    {
      z_log(NULL, CORE_ERROR, 2, "Error creating blob file: file='%s', error='%s'", self->filename, strerror(errno));
      g_free(self->filename);
      g_free(self);
      z_return(NULL);
    }
  
  z_refcount_set(&self->ref_cnt, 1);
  self->size = 0;
  self->alloc_size = 0;
  self->data = NULL;
  self->is_in_file = FALSE;
  self->mtx_reply = g_mutex_new();
  self->cond_reply = g_cond_new();
  self->mapped_ptr = NULL;
  self->mapped_length = 0;
  self->storage_locked = FALSE;

  z_blob_statistic_init(&self->stat);
  self->mtx_lock = g_mutex_new();

  g_mutex_lock(self->system->mtx_blobsys);
  self->system->blobs = g_list_append(self->system->blobs, self);
  g_mutex_unlock(self->system->mtx_blobsys);

  if (initial_size > 0)
    z_blob_alloc(self, initial_size);
  z_return(self);
}
Esempio n. 17
0
static void
z_header_set_destroy_chain(GList *list)
{
  ZHeader *header;

  z_enter();
  while (list)
    {
      header = (ZHeader *)list->data;
      g_string_free(header->key, TRUE);
      g_string_free(header->value, TRUE);
      g_free(header);
      list = g_list_delete_link(list, list);
    }
  z_return();
}
Esempio n. 18
0
/**
 * telnet_copy_buf:
 * @to: 
 * @from: 
 * @bytes: 
 *
 * 
 *
 * Returns:
 * 
 */
static gint
telnet_copy_buf(ZIOBufferDyn *to, ZIOBuffer *from, guint bytes)
{
  guint         i;

  z_enter();
  if ((i = to->size - to->end) < bytes)
    {
      /* we must allocate more buffer space */
      to->size += (1 + bytes / TELNET_BUFFER_SIZE) * TELNET_BUFFER_SIZE;
      to->buf = g_realloc(to->buf, to->size);
    }
  for (i = 0; to->end < to->size && from->ofs < from->end && i < bytes; to->end++, from->ofs++, i++)
      to->buf[to->end] = from->buf[from->ofs];
  z_return(i == bytes);
}
Esempio n. 19
0
/**
 * Truncates/expands a blob.
 *
 * @param[in] self this
 * @param[in] pos position to truncate at
 * @param[in] timeout timeout
 *
 * @returns TRUE on success
 **/
gboolean
z_blob_truncate(ZBlob *self, gint64 pos, gint timeout)
{
  gboolean      res = FALSE;

  z_enter();
  g_assert(self);
  g_assert(pos >= 0);
  if (z_blob_lock(self, timeout))
    {
      z_blob_alloc(self, pos);
      z_blob_unlock(self);
      res = TRUE;
    }
  z_return(res);
}
Esempio n. 20
0
void
z_fd_get_peer_tos(gint fd, guint8 *tos)
{
  gint tmp;
  gchar buf[256];
  gboolean tos_found = FALSE;
  socklen_t buflen, len;
    
  z_enter();
  *tos = 0;
  tmp = 1;
  if (setsockopt(fd, SOL_IP, IP_RECVTOS, &tmp, sizeof(tmp)) < 0)
    {
      z_log(NULL, CORE_ERROR, 8, "Error in setsockopt(SOL_IP, IP_RECVTOS); fd='%d', error='%s'", fd, g_strerror(errno));
      z_leave();
      return;
    }

  buflen = sizeof(buf);
  if (getsockopt(fd, SOL_IP, IP_PKTOPTIONS, &buf, &buflen) >= 0)
    {
      struct msghdr msg;
      struct cmsghdr *cmsg;
      
      msg.msg_controllen = buflen;
      msg.msg_control = buf;
      for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg))
        {
          if (cmsg->cmsg_level == SOL_IP && cmsg->cmsg_type == IP_TOS)
            {
              *tos = *(guchar *) CMSG_DATA(cmsg);
              tos_found = TRUE;
              break;
            }
        }
    }
  if (!tos_found)
    {
      len = sizeof(*tos);
      if (getsockopt(fd, SOL_IP, IP_TOS, tos, &len) == -1)
        {
          z_log(NULL, CORE_ERROR, 2, "Error in getsockopt(SOL_IP, IP_PKTOPTIONS) || getsockopt(SOL_IP, IP_TOS); fd='%d', error='%s'", fd, g_strerror(errno));
          *tos = 0;
        }
    }
  z_leave();
}
Esempio n. 21
0
/**
 * Writes a blob out to disk, called only from z_blob_system_threadproc()
 *
 * @param[in] self this
 *
 * @warning Caller must hold a lock BOTH on the blob AND the blob system!
 **/
static void
z_blob_swap_out(ZBlob *self)
{
  off_t err;
  gssize written, remain;

  z_enter();
  g_assert(self);
  if (!self->storage_locked && !self->is_in_file && self->system)
    {
      err = lseek(self->fd, 0, SEEK_SET);
      if (err < 0)
        {
          z_log(NULL, CORE_ERROR, 0, "Blob error, lseek() failed; file='%s', error='%s'", self->filename, g_strerror(errno));
          g_assert(0);
        }
      remain = self->size;
      while (remain > 0)
        {
          written = write(self->fd, self->data, remain);
          if (written < 0)
            {
              if (errno == EINTR)
                {
                  continue;
                }
              else
                {
                  z_log(NULL, CORE_ERROR, 0, "Blob error, write() failed; file='%s', error='%s'", self->filename, g_strerror(errno));
                  g_assert(0);
                }
            }
          remain -= written;
        }
      self->is_in_file = 1;
      g_free(self->data);
      self->data = NULL;
      self->stat.swap_count++;
      self->stat.last_accessed = time(NULL);
      self->system->mem_used -= self->alloc_size;
      self->system->disk_used += self->alloc_size;
    }
  z_return();
}
Esempio n. 22
0
/**
 * Lock a blob.
 *
 * @param[in] self this
 * @param[in] timeout Timeout for locking. A negative value means infinite and thus blocking mode. Zero means nonblocking mode.
 *
 * @returns TRUE if successfully locked.
 **/
gboolean
z_blob_lock(ZBlob *self, gint timeout)
{
  gboolean        res;
  struct timeval  tvnow, tvfinish;

  z_enter();
  g_assert(self);

  if (timeout < 0)        /* infinite timeout -> blocking mode */
    {
      g_mutex_lock(self->mtx_lock);
      res = TRUE;
    }
  else if (timeout == 0)  /* zero timeout -> nonblocking mode */
    {
      res = g_mutex_trylock(self->mtx_lock);
    }
  else                    /* positive timeout */
    {
      gettimeofday(&tvfinish, NULL);
      tvfinish.tv_sec += (timeout / 1000);
      tvfinish.tv_usec += 1000 * (timeout % 1000);
      tvfinish.tv_sec += (tvfinish.tv_usec / 1000000);
      tvfinish.tv_usec %= 1000000;
      /* FIXME: maybe g_cond_wait_timed_wait ? */
      do
        {
          res = FALSE;
          if (g_mutex_trylock(self->mtx_lock))
            {
              res = TRUE;
              break;
            }
          usleep(1000);
          gettimeofday(&tvnow, NULL);
        } 
      while ((tvnow.tv_sec < tvfinish.tv_sec) ||
             ((tvnow.tv_sec == tvfinish.tv_sec) && (tvnow.tv_usec < tvfinish.tv_usec)));
    }
  z_return(res);
}
Esempio n. 23
0
/**
 * Decrease reference count of blob; destroy it if the count reaches zero.
 *
 * @param[in] self this
 **/
void
z_blob_unref(ZBlob *self)
{
  z_enter();
  if (self && z_refcount_dec(&self->ref_cnt))
    {
      g_mutex_lock(self->system->mtx_blobsys);
      self->alloc_req = -self->alloc_size;
      self->system->blobs = g_list_remove(self->system->blobs, self);
      z_blob_check_alloc(self);
      g_mutex_unlock(self->system->mtx_blobsys);

      if (self->data)
        g_free(self->data);

      if (self->fd >= 0)
        close(self->fd);

      if (self->filename)
        {
          if (unlink(self->filename))
            z_log(NULL, CORE_ERROR, 3, "Error removing blob file, unlink() failed; file='%s', error='%s'", self->filename, strerror(errno));
          g_free(self->filename);
          self->filename = NULL;
        }

      g_mutex_free(self->mtx_reply);
      g_cond_free(self->cond_reply);
      if (g_mutex_trylock(self->mtx_lock))
        {
          g_mutex_unlock(self->mtx_lock);
          g_mutex_free(self->mtx_lock);
        }
      else
        {
          z_log(NULL, CORE_ERROR, 3, "Error while destroying blob, someone still has a lock on it;");
          /* someone has locked the blob by z_blob_get_file or _get_ptr, and forgot to release it */
        }
      g_free(self);
    }
  z_return();
}
Esempio n. 24
0
/**
 * Finalize Base64 decoding.
 *
 * @param[in] s ZCodeBase64Decode instance
 *
 * Checks if the input was complete (if so, we returned to phase 0).
 * If it wasn't, the error is logged; and if we're not error_tolerant,
 * the return value also indicates this error condition.
 *
 * @return always TRUE if error_tolerant; otherwise FALSE if the input was incomplete
 **/
static gboolean
z_code_base64_decode_finish(ZCode *s)
{
  ZCodeBase64Decode *self = (ZCodeBase64Decode *) s;
  
  z_enter();
  if (self->phase != 0)
    {
      z_log(NULL, CORE_ERROR, 3, "Unfinished base64 encoding; phase='%d'", self->phase);
      self->phase = 0;
      if (!self->error_tolerant)
        {
          z_leave();
          return FALSE;
        }
    }

  z_leave();
  return TRUE;
}
Esempio n. 25
0
/**
 * Unlocks a blob locked by 'z_blob_get_ptr()'.
 *
 * @param[in] self this
 * @param[in] data Pointer to a range, obtained by 'z_blob_get_ptr()'
 **/
void
z_blob_free_ptr(ZBlob *self, gchar *data)
{
  guint offset_in_page;

  z_enter();
  g_assert(self);
  g_assert(self->mapped_ptr);
  g_assert(self->mapped_ptr == data);
  g_assert(self->mapped_length > 0);
  if (self->is_in_file)
    {
      offset_in_page = GPOINTER_TO_UINT(data) % getpagesize();
      munmap(data - offset_in_page, self->mapped_length + offset_in_page);
    }
  self->mapped_ptr = NULL;
  self->mapped_length = 0;
  z_blob_unlock(self);
  z_return();
}
Esempio n. 26
0
ZHeader *
z_header_set_iterate(ZHeaderSet *self, gchar *key, gpointer *opaque)
{
  ZHeader *res;
  GList *value = opaque ? (GList *) *opaque : NULL;

  z_enter();
  if (value == NULL)
    value = (GList *) g_hash_table_lookup(self->headers, key);
  else
    value = g_list_next(value);

  if (value == NULL)
    z_return(NULL);

  res = value->data;
  if (opaque)
    *opaque = value;
  z_return(res);
}
Esempio n. 27
0
/**
 * Obtains a pointer to a subrange of the blob.
 *
 * @param[in]      self this
 * @param[in]      pos start of the range to get ptr for
 * @param[in, out] req_datalen length of the range: in=requested, out=mapped
 * @param[in]      timeout timeout
 *
 * This function obtains a pointer to a specified subrange of the blob.
 * Until the pointer is freed by 'z_blob_free_ptr()', the blob will be locked for
 * reading, that means read operations are still possible, but writes and
 * swapping is disabled and will block!
 *
 * @returns The pointer on success, NULL on error
 **/
gchar *
z_blob_get_ptr(ZBlob *self, gint64 pos, gsize *req_datalen, gint timeout)
{
  gchar             *data = NULL;
  gint offset_in_page;

  z_enter();
  g_assert(self);
  g_assert(req_datalen);
  g_assert(self->mapped_ptr == NULL);
  g_assert(pos >= 0);

  if ((pos < self->size) && (self->size > 0) && z_blob_lock(self, timeout))
    {
      if (self->size < (pos + (gssize) *req_datalen))
        *req_datalen = self->size - pos;

      if (self->is_in_file)
        {
          offset_in_page = pos % getpagesize();
          data = (gchar*)mmap(NULL, *req_datalen + offset_in_page, PROT_READ | PROT_WRITE, MAP_SHARED, self->fd, pos - offset_in_page);
          if (data == (gchar*)-1)
            data = NULL;
          else
            data += offset_in_page;
        }
      else
        {
          data = self->data + pos;
        }

      self->mapped_ptr = data;
      self->mapped_length = *req_datalen;

      if (!data)
        z_blob_unlock(self);
    }
  z_return(data);
}
Esempio n. 28
0
gboolean
z_header_set_add(ZHeaderSet *self,
                 GString *key,
                 GString *value,
                 gboolean multiple)
{
  ZHeader *header;
  GList *hlist;

  z_enter();
  header = g_new0(ZHeader, 1);
  header->key = key;
  header->value = value;
  hlist = g_hash_table_lookup(self->headers, header->key->str);
  if (!hlist || (header->key->str[0] == 'X') || multiple)
    {
      self->headers_count++;
      hlist = g_list_append(hlist, header);
      g_hash_table_insert(self->headers, header->key->str, hlist);
      z_return(TRUE);
    }
  z_return(FALSE);
}
Esempio n. 29
0
/**
 * z_dispatch_chain_new:
 * @protocol Protocol identifier (ZD_PROTO_*)
 * @bind_addr Address to bind to
 * @params Additional parameters (see ZDispatch*Params)
 *
 * Constructor of ZDispatchChain, allocates and initialises a new instance, optionally
 * starts a processing thread for it.
 *
 * Returns:
 * The new instance
 */
static ZDispatchChain *
z_dispatch_chain_new(const gchar *session_id, ZDispatchBind *key, ZDispatchParams *params)
{
  ZDispatchChain *self = g_new0(ZDispatchChain, 1);
  gchar thread_name[256], buf[256];
  
  z_enter();
  self->session_id = strdup(session_id);
  self->ref_cnt = 1;
  self->registered_key = z_dispatch_bind_ref(key);
  self->threaded = ((ZDispatchCommonParams *) params)->threaded;

  memcpy(&self->params, params, sizeof(*params));
  if (self->threaded)
    {
      self->accept_queue = g_async_queue_new();
      z_dispatch_chain_ref(self);
      g_snprintf(thread_name, sizeof(thread_name), "dispatch(%s)", z_dispatch_bind_format(key, buf, sizeof(buf)));
      if (!z_thread_new(thread_name, z_dispatch_chain_thread, self))
        {
	  /*LOG
	    This message indicates that Zorp was unable to create a
	    dispatcher thread for accepting new connection, and it is
	    reverting back to the original non-threaded mode.  It is likely
	    that Zorp reached its thread or resource limit. Check your logs
	    for further information.
	   */
          z_log(NULL, CORE_ERROR, 2, "Error creating dispatch thread, falling back to non-threaded mode;");
          z_dispatch_chain_unref(self);
          self->threaded = FALSE;
          g_async_queue_unref(self->accept_queue);
          self->accept_queue = NULL;
        }
    }
  z_return(self);
}
Esempio n. 30
0
gboolean 
z_policy_tuple_get_verdict(ZPolicyObj *tuple, guint *verdict)
{
  ZPolicyObj *tmp;
                                                                                
  z_enter();
  if (!z_policy_seq_check(tuple))
    {
      if (z_policy_var_parse(tuple, "i", verdict))
        z_return(TRUE);
      /* not a sequence nor an int */
      z_return(FALSE);
    }
                                                                                
  tmp = z_policy_seq_getitem(tuple, 0);
  if (!tmp || !z_policy_var_parse(tmp, "i", verdict))
    {
      /* policy syntax error */
      z_policy_var_unref(tmp);
      z_return(FALSE);
    }
  z_policy_var_unref(tmp);
  z_return(TRUE);
}