Esempio n. 1
0
NEOERR *wdb_create (WDB **wdb, const char *path, const char *name, 
                    const char *key, ULIST *col_def, int flags)
{
  WDB *my_wdb;
  char d_path[_POSIX_PATH_MAX];
  NEOERR *err = STATUS_OK;
  int x, len, r;
  char *s;

  *wdb = NULL;

  err = wdb_alloc (&my_wdb, flags);
  if (err) return nerr_pass(err);

  my_wdb->name = strdup (name);
  my_wdb->key = strdup (key);
  my_wdb->path = strdup(path);
  if (my_wdb->name == NULL || my_wdb->key == NULL || my_wdb->path == NULL)
  {
    wdb_destroy (&my_wdb);
    return nerr_raise (NERR_NOMEM, 
	"Unable to allocate memory for creation of %s", name);
  }

  /* ondisk must start at one because of skipList */
  my_wdb->last_ondisk = 1;   
  len = uListLength(col_def);
  for (x = 0; x < len; x++)
  {
    err = uListGet (col_def, x, (void *)&s);
    if (err) 
    {
      wdb_destroy (&my_wdb);
      return nerr_pass(err);
    }
    err = wdb_column_insert (my_wdb, -1, s, WDB_TYPE_STR);
    my_wdb->defn_dirty = 0; /* So we don't save on error destroy */
    if (err) 
    {
      wdb_destroy (&my_wdb);
      return nerr_pass(err);
    }
  }

  err = wdb_save_defn (my_wdb, path);
  if (err)
  {
    wdb_destroy (&my_wdb);
    return nerr_pass(err);
  }

  snprintf (d_path, sizeof(d_path), "%s.wdb", path);
  r = db_open(d_path, DB_BTREE, DB_CREATE | DB_TRUNCATE, 0, NULL, NULL, &(my_wdb->db));
  if (r)
  {
    wdb_destroy (&my_wdb);
    return nerr_raise (NERR_DB, "Unable to create db file %s: %d", d_path, r);
  }

  *wdb = my_wdb;

  return STATUS_OK;
}
Esempio n. 2
0
NEOERR *wdbr_next (WDB *wdb, WDBCursor *cursor, WDBRow **row, int flags)
{
  DBT dkey, data;
  WDBRow *my_row;
  NEOERR *err = STATUS_OK;
  int r;

  *row = NULL;

  if (wdb->table_version != cursor->table_version)
  {
    return nerr_raise (NERR_ASSERT, "Cursor doesn't match database");
  }

  memset(&dkey, 0, sizeof(dkey));
  memset(&data, 0, sizeof(data));
  dkey.flags = DB_DBT_MALLOC;
  data.flags = DB_DBT_MALLOC;

  /* First call */
  if (flags & WDBC_FIRST)
  {
    r = cursor->db_cursor->c_get (cursor->db_cursor, &dkey, &data, DB_FIRST);
    if (r == DB_NOTFOUND)
      return nerr_raise (NERR_NOT_FOUND, "Cursor empty");
    else if (r)
      return nerr_raise (NERR_DB, "Unable to get first item from cursor: %d", 
	  r);
  }
  else
  {
    r = cursor->db_cursor->c_get (cursor->db_cursor, &dkey, &data, DB_NEXT);
    if (r == DB_NOTFOUND)
      return STATUS_OK;
    else if (r)
      return nerr_raise (NERR_DB, "Unable to get next item from cursor: %d", r);
  }

  /* allocate row */
  err = alloc_row (wdb, &my_row);
  if (err)
  {
    free (data.data);
    return nerr_pass(err);
  }

  my_row->key_value = (char *) malloc (dkey.size + 1);
  if (my_row->key_value == NULL)
  {
    free (data.data);
    free (my_row);
    return nerr_raise (NERR_NOMEM, "No memory for new row");
  }

  memcpy (my_row->key_value, dkey.data, dkey.size);
  my_row->key_value[dkey.size] = '\0';

  /* unpack row */
  err = unpack_row (wdb, data.data, data.size, my_row);
  free (data.data);
  free (dkey.data);
  if (err)
  {
    free (my_row);
    return nerr_pass(err);
  }

  *row = my_row;

  return STATUS_OK;
}
Esempio n. 3
0
File: mscli.c Progetto: bigclean/moc
/*
 * application logic message, called by msparse_buf()
 */
static NEOERR* msparse_msg(moc_srv *srv, unsigned char *buf, size_t len, moc_arg *arg)
{
    uint32_t id, reply;
    unsigned char *payload;
    size_t psize, rv;

    MOC_NOT_NULLB(arg, arg->evth);
    
    if (!srv || !buf || len < 8) return nerr_raise(NERR_ASSERT, "illegal packet");

    //MSG_DUMP("recv: ", buf, len);

    /* The header is:
     * 4 bytes    ID
     * 4 bytes    Reply Code
     * Variable   Payload
     */
    id = ntohl(* ((uint32_t *) buf));
    reply = ntohl(* ((uint32_t *) buf + 1));

    payload = buf + 8;
    psize = len - 8;

    if (id == 0 && reply == 10000) {
        /*
         * server push
         */
        if (psize < 4) return nerr_raise(NERR_ASSERT, "server pushed empty message");

        struct msqueue_entry *e = msqueue_entry_create();
        if (!e) return nerr_raise(NERR_NOMEM, "alloc msqueue entry");
        
        rv = unpack_hdf(payload + 4, psize - 4, &(e->hdfrcv));
        if (rv <= 0) return nerr_raise(NERR_ASSERT, "server pushed illegal message");

        //TRACE_HDF(e->hdfrcv);

        char *cmd = NULL;
        HDF_ATTR *attr = hdf_get_attr(e->hdfrcv, "_Reserve");
        while (attr != NULL) {
            if (!strcmp(attr->key, "cmd")) cmd = attr->value;
            attr = attr->next;
        }
        if (!cmd) return nerr_raise(NERR_ASSERT, "cmd not supplied");

        e->ename = strdup(srv->evt->ename);
        e->cmd = strdup(cmd);

        mtc_dbg("receive cmd %s", cmd);
        
        hdf_remove_tree(e->hdfrcv, "_Reserve");

        mssync_lock(&arg->callbacksync);
        msqueue_put(arg->callbackqueue, e);
        mssync_unlock(&arg->callbacksync);

        /*
         * notify callback thread
         */
        mssync_signal(&arg->callbacksync);
    } else {
        /*
         * server response
         */
        if (id < g_reqid)
            return nerr_raise(NERR_ASSERT, "id not match %d %d", g_reqid, id);

        if (psize >= 4) {
            mssync_lock(&(arg->mainsync));
            rv = unpack_hdf(payload + 4, psize - 4, &(srv->evt->hdfrcv));
            mssync_unlock(&(arg->mainsync));
            if (rv <= 0)
                return nerr_raise(NERR_ASSERT, "server responsed illegal message");

            //TRACE_HDF(srv->evt->hdfrcv);
        }

        /*
         * notify main thread
         */
        mssync_signal(&(arg->mainsync));
    }
    
    return STATUS_OK;
}
Esempio n. 4
0
File: ooms.c Progetto: kingiol/cmoon
NEOERR* oms_users_data_add(CGI *cgi, HASH *dbh, HASH *evth, session_t *ses)
{
    mevent_t *evt = (mevent_t*)hash_lookup(evth, "aic");
    char *aname, *pname, *email;
    int cost;
    NEOERR *err;

    APP_CHECK_ADMIN();

    HDF_GET_STR_IDENT(cgi->hdf, PRE_COOKIE".aname", pname);
    HDF_GET_STR(cgi->hdf, PRE_QUERY".aname", aname);
    HDF_GET_STR(cgi->hdf, PRE_QUERY".email", email);
    LEGAL_CK_ANAME(pname);
    LEGAL_CK_ANAME(aname);
    LEGAL_CK_EMAIL(email);

    /*
     * check
     */
    int state = hdf_get_int_value(evt->hdfrcv, "state", LCS_ST_FREE);
    if (state <= LCS_ST_FREE)
        return nerr_raise(LERR_NEEDUP, "%s want to add users %s", pname, aname);
    else if (state >= LCS_ST_VIP) goto add;

    /*
     * chargeback
     */
    cost = hdf_get_int_value(g_cfg, "Cost.account", 0);
    evt = (mevent_t*)hash_lookup(evth, "bank");
    hdf_set_value(evt->hdfsnd, "aname", pname);
    hdf_set_int_value(evt->hdfsnd, "btype", BANK_OP_ADDACCOUNT);
    hdf_set_int_value(evt->hdfsnd, "fee", cost);
    hdf_set_value(evt->hdfsnd, "account", aname);

    MEVENT_TRIGGER(evt, pname, REQ_CMD_BANK_ADDBILL, FLAGS_SYNC);

add:
    /*
     * add
     */
    evt = (mevent_t*)hash_lookup(evth, "aic");
    hdf_copy(evt->hdfsnd, NULL, hdf_get_obj(cgi->hdf, PRE_QUERY));
    hdf_set_value(evt->hdfsnd, "pname", pname);
    hdf_set_value(evt->hdfsnd, "aname", aname);
    hdf_set_int_value(evt->hdfsnd, "state",
                      hdf_get_int_value(evt->hdfrcv, "state", LCS_ST_FREE));
    hdf_set_value(evt->hdfsnd, "masn", aname);

    if (PROCESS_NOK(mevent_trigger(evt, aname, REQ_CMD_APPNEW, FLAGS_SYNC))) {
        char *zpa = NULL;
        hdf_write_string(evt->hdfrcv, &zpa);
        mtc_foo("add %s failure %d %s", aname, evt->errcode, zpa);
        SAFE_FREE(zpa);

        if (state < LCS_ST_VIP) {
            /*
             * roll back
             */
            evt = (mevent_t*)hash_lookup(evth, "bank");
            hdf_set_value(evt->hdfsnd, "aname", pname);
            hdf_set_int_value(evt->hdfsnd, "btype", BANK_OP_ROLLBACK);
            hdf_set_int_value(evt->hdfsnd, "fee", -cost);
            hdf_set_valuef(evt->hdfsnd, "remark = 客服帐号 %s 创建失败", aname);

            if (PROCESS_NOK(mevent_trigger(evt, pname, REQ_CMD_BANK_ADDBILL,
                                           FLAGS_SYNC))) {
                /*
                 * ATTENTION we need pay back to customer manually
                 */
                hdf_write_string(evt->hdfrcv, &zpa);
                mtc_foo("rollback %s failure %d %s", aname, evt->errcode, zpa);
                SAFE_FREE(zpa);
            }
        }

        return nerr_raise(evt->errcode, "add %s failure %d", aname, evt->errcode);
    }

    return STATUS_OK;
}
Esempio n. 5
0
NEOERR* mast_dds_load(char *dir, char *name, RendAsset **a)
{
    char fname[PATH_MAX], *buf, *pos;
    NEOERR *err;

    DdsLoadInfo loadInfoDXT1 = {
        1, 0, 0, 4, 8, GL_COMPRESSED_RGBA_S3TC_DXT1
    };
    DdsLoadInfo loadInfoDXT3 = {
        1, 0, 0, 4, 16, GL_COMPRESSED_RGBA_S3TC_DXT3
    };
    DdsLoadInfo loadInfoDXT5 = {
        1, 0, 0, 4, 16, GL_COMPRESSED_RGBA_S3TC_DXT5
    };
    DdsLoadInfo loadInfoBGRA8 = {
        0, 0, 0, 1, 4, GL_RGBA8, GL_BGRA, GL_UNSIGNED_BYTE
    };
    DdsLoadInfo loadInfoBGR8 = {
        0, 0, 0, 1, 3, GL_RGB8, GL_BGR, GL_UNSIGNED_BYTE
    };
    DdsLoadInfo loadInfoBGR5A1 = {
        0, 1, 0, 1, 2, GL_RGB5_A1, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV
    };
    DdsLoadInfo loadInfoBGR565 = {
        0, 1, 0, 1, 2, GL_RGB5, GL_RGB, GL_UNSIGNED_SHORT_5_6_5
    };
    DdsLoadInfo loadInfoIndex8 = {
        0, 0, 1, 1, 1, GL_RGB8, GL_BGRA, GL_UNSIGNED_BYTE
    };

    if (dir) snprintf(fname, sizeof(fname), "%s%s", dir, name);
    else strncpy(fname, name, sizeof(fname));

    TexAsset *tnode = mtex_node_new();
    if (!tnode) return nerr_raise(NERR_NOMEM, "alloc texture");

    DDS_header hdr;
    int x = 0;
    int y = 0;
    int mipMapCount = 0;
    int totallen = 0;

    err = ne_load_file_len(fname, &buf, &totallen);
    if (err != STATUS_OK) return nerr_pass(err);

    glEnable(GL_TEXTURE_2D);
    glGenTextures(1, &tnode->tex);
    glBindTexture(GL_TEXTURE_2D, tnode->tex);

    pos = buf;
    memcpy(&hdr, buf, sizeof(hdr));
    pos += sizeof(hdr);
    if (pos - buf > totallen) return nerr_raise(NERR_ASSERT, "file too short");

    if (hdr.dwMagic != DDS_MAGIC || hdr.dwSize != 124 ||
        !(hdr.dwFlags & DDSD_PIXELFORMAT) || !(hdr.dwFlags & DDSD_CAPS) )
        return nerr_raise(NERR_ASSERT, "%s Does not appear to be a .dds file", fname);

    x = hdr.dwWidth;
    y = hdr.dwHeight;

    if (!is_power_of_two(x)) {
        mtc_warn("Texture %s with is %i pixels which is not a power of two!", fname, x);
    }

    if (!is_power_of_two(y)) {
        mtc_warn("Texture %s height is %i pixels which is not a power of two!", fname, y);
    }

    DdsLoadInfo* li = &loadInfoDXT1;

    if (PF_IS_DXT1(hdr.sPixelFormat)) {
        li = &loadInfoDXT1;
    } else if (PF_IS_DXT3(hdr.sPixelFormat)) {
        li = &loadInfoDXT3;
    } else if (PF_IS_DXT5(hdr.sPixelFormat)) {
        li = &loadInfoDXT5;
    } else if (PF_IS_BGRA8(hdr.sPixelFormat)) {
        li = &loadInfoBGRA8;
    } else if (PF_IS_BGR8(hdr.sPixelFormat)) {
        li = &loadInfoBGR8;
    } else if (PF_IS_BGR5A1(hdr.sPixelFormat)) {
        li = &loadInfoBGR5A1;
    } else if (PF_IS_BGR565(hdr.sPixelFormat)) {
        li = &loadInfoBGR565;
    } else if (PF_IS_INDEX8(hdr.sPixelFormat)) {
        li = &loadInfoIndex8;
    } else {
        return nerr_raise(NERR_ASSERT, "%s: Unknown DDS File format type.", fname);
    }

    glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_FALSE);
    mipMapCount = (hdr.dwFlags & DDSD_MIPMAPCOUNT) ? hdr.dwMipMapCount : 1;

    int ix, zz;
    GLenum cFormat, format;

    if (li->compressed) {
        size_t size = max(li->divSize, x) / li->divSize *
                      max(li->divSize, y) / li->divSize * li->blockBytes;
        char *data = malloc(size);
        if (!data ) {
            return nerr_raise(NERR_ASSERT, "%s: not contain any data.", fname);
        }

        cFormat = li->internalFormat;
        format = li->internalFormat;

        for( ix = 0; ix < mipMapCount; ++ix ) {
            memcpy(data, pos, size);
            pos += size;
            if (pos - buf > totallen) return nerr_raise(NERR_ASSERT, "file too short");

            glCompressedTexImage2D(GL_TEXTURE_2D, ix, li->internalFormat,
                                   x, y, 0, size, data);
            x = (x+1)>>1;
            y = (y+1)>>1;
            size = max(li->divSize, x) / li->divSize *
                   max(li->divSize, y) / li->divSize * li->blockBytes;
        }
        free(data);
    } else if (li->palette) {
Esempio n. 6
0
/* Client side */
NEOERR *ne_net_connect(NSOCK **sock, const char *host, int port, 
                       int conn_timeout, int data_timeout)
{
  struct sockaddr_in serv_addr;
  struct hostent hp;
  struct hostent *php;
  int fd;
  int r = 0, x;
  int flags;
  struct timeval tv;
  fd_set fds;
  int optval;
  socklen_t optlen;
  NSOCK *my_sock;

  /* FIXME: This isn't thread safe... but there's no man entry for the _r
   * version? */

  php = gethostbyname(host);
  if (php == NULL)
  {
    return nerr_raise(NERR_IO, "Host not found: %s", hstrerror(h_errno));
  }
  hp = *php;

  memset(&serv_addr, 0, sizeof(serv_addr));
  serv_addr.sin_family = AF_INET;
  serv_addr.sin_port = htons(port);
  fd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
  if (fd == -1)
    return nerr_raise_errno(NERR_IO, "Unable to create socket");

  flags = fcntl(fd, F_GETFL, 0 );
  if (flags == -1)
  {
    close(fd);
    return nerr_raise_errno(NERR_IO, "Unable to get socket flags");
  }

  if (fcntl(fd, F_SETFL, flags | O_NDELAY) == -1)
  {
    close(fd);
    return nerr_raise_errno(NERR_IO, "Unable to set O_NDELAY");
  }

  x = 0;
  while (hp.h_addr_list[x] != NULL)
  {
    memcpy(&(serv_addr.sin_addr), hp.h_addr_list[x], sizeof(struct in_addr));
    errno = 0;
    r = connect(fd, (struct sockaddr *) &(serv_addr), sizeof(struct sockaddr_in));
    if (r == 0 || errno == EINPROGRESS) break;
    x++;
  }
  if (r != 0)
  {
    if (errno != EINPROGRESS)
    {
      close(fd);
      return nerr_raise_errno(NERR_IO, "Unable to connect to %s:%d", 
	  host, port);
    }
    tv.tv_sec = conn_timeout;
    tv.tv_usec = 0;

    FD_ZERO(&fds);
    FD_SET(fd, &fds);

    r = select(fd+1, NULL, &fds, NULL, &tv);
    if (r == 0)
    {
      close(fd);
      return nerr_raise(NERR_IO, "Connection to %s:%d failed: Timeout", host,
	  port);
    }
    if (r < 0)
    {
      close(fd);
      return nerr_raise_errno(NERR_IO, "Connection to %s:%d failed", host,
	  port);
    }

    optlen = sizeof(optval);

    if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &optval, &optlen) == -1) 
    {
      close(fd);
      return nerr_raise_errno(NERR_IO, 
	  "Unable to getsockopt to determine connection error");
    }

    if (optval)
    {
      close(fd);
      errno = optval;
      return nerr_raise_errno(NERR_IO, "Connection to %s:%d failed", host, 
	  port);
    }
  }
  /* Re-enable blocking... we'll use select on read/write for timeouts
   * anyways, and if we want non-blocking version in the future we'll
   * add a flag or something.
   */
  flags = fcntl(fd, F_GETFL, 0 );
  if (flags == -1)
  {
    close(fd);
    return nerr_raise_errno(NERR_IO, "Unable to get socket flags");
  }

  if (fcntl(fd, F_SETFL, flags & ~O_NDELAY) == -1)
  {
    close(fd);
    return nerr_raise_errno(NERR_IO, "Unable to set O_NDELAY");
  }

  my_sock = (NSOCK *) calloc(1, sizeof(NSOCK));
  if (my_sock == NULL)
  {
    close(fd);
    return nerr_raise(NERR_NOMEM, "Unable to allocate memory for NSOCK");
  }
  my_sock->fd = fd;
  my_sock->remote_ip = ntohl(serv_addr.sin_addr.s_addr);
  my_sock->remote_port = port;
  my_sock->data_timeout = data_timeout;
  my_sock->conn_timeout = conn_timeout;

  *sock = my_sock;

  return STATUS_OK;
}
Esempio n. 7
0
NEOERR* session_init(CGI *cgi, HASH *dbh, session_t **ses)
{
    session_t *lses;
    HDF *node, *onode;
    char tok[LEN_HDF_KEY], *s;

    /*
     * follow cgi_parse(), to process _type_object
     */
    s = hdf_get_value(cgi->hdf, PRE_QUERY"._type_object", NULL);
    if (s) {
        ULIST *list;
        string_array_split(&list, s, ",", 50);
        ITERATE_MLIST(list) {
            snprintf(tok, sizeof(tok), "%s.%s",
                     PRE_QUERY, neos_strip((char*)list->items[t_rsv_i]));
            onode = hdf_get_obj(cgi->hdf, tok);
            if (onode) {
                mjson_export_to_hdf(onode, NULL, MJSON_EXPORT_NONE, false);
            }
        }
        uListDestroy(&list, ULIST_FREE);
    }
    
    *ses = NULL;

    lses = calloc(1, sizeof(session_t));
    if (!lses) return nerr_raise(NERR_NOMEM, "calloc memory for session_t failure");

    /*
     * mname
     */
    HDF_FETCH_STR(cgi->hdf, PRE_COOKIE".mname", s);
    if (!s) HDF_FETCH_STR(cgi->hdf, PRE_COOKIE".username", s);
    if (s) lses->mname = strdup(s);

    /*
     * province
     */
    HDF_FETCH_STR(cgi->hdf, PRE_COOKIE".province", s);
    hdf_init(&lses->province);
    if (s) {
        neos_unescape((UINT8*)s, strlen(s), '%');
        hdf_set_value(lses->province, NULL, s);
        mjson_export_to_hdf(lses->province, MJSON_EXPORT_NONE, NULL, false);
    }

    /*
     * city
     */
    HDF_FETCH_STR(cgi->hdf, PRE_COOKIE".city", s);
    hdf_init(&lses->city);
    if (s) {
        neos_unescape((UINT8*)s, strlen(s), '%');
        hdf_set_value(lses->city, NULL, s);
        mjson_export_to_hdf(lses->city, MJSON_EXPORT_NONE, NULL, false);
    }

    /*
     * browser
     */
    HDF_FETCH_STR(cgi->hdf, PRE_HTTP".UserAgent", s);
    if (s) {
        mstr_repchr(s, ' ', '\0');
        for (int i = 0; i < m_browsers_size; i++) {
            if (!strncasecmp(s, m_browsers[i], strlen(m_browsers[i]))) {
                lses->browser = i;
                break;
            }
        }
        s = strchr(s, '/');
        if (s) lses->bversion = strtof(s+1, NULL);
    }

    /*
     * reqtype
     */
    lses->reqtype = CGI_REQ_HTML;
    char *uri = hdf_get_value(cgi->hdf, PRE_REQ_URI_RW, NULL);
    if (!uri) {
        uri = "terminal";
        lses->reqtype = CGI_REQ_TERMINAL;
    }
    mstr_repchr(uri, '/', '_');
    uri = mstr_strip(uri, '_');
    if (!strncmp(uri, "json_", 5)) {
        uri = uri+5;
        lses->reqtype = CGI_REQ_AJAX;
    } else if (!strncmp(uri, "image_", 6)) {
        uri = uri+6;
        lses->reqtype = CGI_REQ_IMAGE;
    }

    /*
     * dataer, render
     */
    switch (http_req_method(cgi)) {
        case CGI_REQ_POST:
            snprintf(tok, sizeof(tok), "%s_data_mod", uri);
            break;
        case CGI_REQ_PUT:
            snprintf(tok, sizeof(tok), "%s_data_add", uri);
            break;
        case CGI_REQ_DEL:
            snprintf(tok, sizeof(tok), "%s_data_del", uri);
            break;
        default:
        case CGI_REQ_GET:
            snprintf(tok, sizeof(tok), "%s_data_get", uri);
            break;
    }
    lses->dataer = strdup(tok);
    lses->render = strdup(uri);

    /*
     * tm_cache_browser
     */
    node = hdf_get_obj(g_cfg, PRE_CFG_FILECACHE".0");
    while (node != NULL) {
        if (reg_search(hdf_get_value(node, "uri", "NULL"), uri)) {
            lses->tm_cache_browser = hdf_get_int_value(node, "tm_cache", 0);
            break;
        }
        node = hdf_obj_next(node);
    }

    /*
     * DONE
     */
    *ses = lses;
    
    return STATUS_OK;
}
Esempio n. 8
0
static NEOERR* _set_value (HDF *hdf, const char *name, const char *value,
                           int dupl, int wf, int lnk, HDF_ATTR *attr,
                           HDF **set_node)
{
  NEOERR *err;
  HDF *hn, *hp, *hs;
  HDF hash_key;
  int x = 0;
  const char *s = name;
  const char *n = name;
  int count = 0;

  if (set_node != NULL) *set_node = NULL;
  if (hdf == NULL)
  {
    return nerr_raise(NERR_ASSERT, "Unable to set %s on NULL hdf", name);
  }

  /* HACK: allow setting of this node by passing an empty name */
  if (name == NULL || name[0] == '\0')
  {
    /* handle setting attr first */
    if (hdf->attr == NULL)
    {
      hdf->attr = attr;
    }
    else
    {
      _merge_attr(hdf->attr, attr);
    }
    /* set link flag */
    if (lnk) hdf->link = 1;
    else hdf->link = 0;
    /* if we're setting ourselves to ourselves... */
    if (hdf->value == value)
    {
      if (set_node != NULL) *set_node = hdf;
      return STATUS_OK;
    }
    if (hdf->alloc_value)
    {
      free(hdf->value);
      hdf->value = NULL;
    }
    if (value == NULL)
    {
      hdf->alloc_value = 0;
      hdf->value = NULL;
    }
    else if (dupl)
    {
      hdf->alloc_value = 1;
      hdf->value = strdup(value);
      if (hdf->value == NULL)
	return nerr_raise (NERR_NOMEM, "Unable to duplicate value %s for %s",
	    value, name);
    }
    else
    {
      hdf->alloc_value = wf;
      hdf->value = (char *)value;
    }
    if (set_node != NULL) *set_node = hdf;
    return STATUS_OK;
  }

  n = name;
  s = strchr (n, '.');
  x = (s != NULL) ? s - n : strlen(n);
  if (x == 0)
  {
    return nerr_raise(NERR_ASSERT, "Unable to set Empty component %s", name);
  }

  if (hdf->link)
  {
    char *new_name = (char *) malloc(strlen(hdf->value) + 1 + strlen(name) + 1);
    if (new_name == NULL)
    {
      return nerr_raise(NERR_NOMEM, "Unable to allocate memory");
    }
    strcpy(new_name, hdf->value);
    strcat(new_name, ".");
    strcat(new_name, name);
    err = _set_value (hdf->top, new_name, value, dupl, wf, lnk, attr, set_node);
    free(new_name);
    return nerr_pass(err);
  }
  else
  {
    hn = hdf;
  }

  while (1)
  {
    /* examine cache to see if we have a match */
    count = 0;
    hp = hn->last_hp;
    hs = hn->last_hs;

    if ((hs == NULL && hp == hn->child) || (hs && hs->next == hp))
    {
      if (hp && hp->name && (x == hp->name_len) && !strncmp (hp->name, n, x))
      {
	goto skip_search;
      }
    }

    hp = hn->child;
    hs = NULL;

    /* Look for a matching node at this level */
    if (hn->hash != NULL)
    {
      hash_key.name = (char *)n;
      hash_key.name_len = x;
      hp = ne_hash_lookup(hn->hash, &hash_key);
      hs = hn->last_child;
    }
    else
    {
      while (hp != NULL)
      {
	if (hp->name && (x == hp->name_len) && !strncmp(hp->name, n, x))
	{
	  break;
	}
	hs = hp;
	hp = hp->next;
	count++;
      }
    }

    /* save in cache any value we found */
    if (hp) {
      hn->last_hp = hp;
      hn->last_hs = hs;
    }

skip_search:

    if (hp == NULL)
    {
      /* If there was no matching node at this level, we need to
       * allocate an intersitial node (or the actual node if we're
       * at the last part of the HDF name) */
      if (s != NULL)
      {
	/* intersitial */
	err = _alloc_hdf (&hp, n, x, NULL, 0, 0, hdf->top);
      }
      else
      {
	err = _alloc_hdf (&hp, n, x, value, dupl, wf, hdf->top);
	if (lnk) hp->link = 1;
	else hp->link = 0;
	hp->attr = attr;
      }
      if (err != STATUS_OK)
	return nerr_pass (err);
      if (hn->child == NULL)
	hn->child = hp;
      else
	hs->next = hp;
      hn->last_child = hp;

      /* This is the point at which we convert to a hash table
       * at this level, if we're over the count */
      if (count > FORCE_HASH_AT && hn->hash == NULL)
      {
	err = _hdf_hash_level(hn);
	if (err) return nerr_pass(err);
      }
      else if (hn->hash != NULL)
      {
	err = ne_hash_insert(hn->hash, hp, hp);
	if (err) return nerr_pass(err);
      }
    }
    else if (s == NULL)
    {
      /* If there is a matching node and we're at the end of the HDF
       * name, then we update the value of the node */
      /* handle setting attr first */
      if (hp->attr == NULL)
      {
	hp->attr = attr;
      }
      else
      {
	_merge_attr(hp->attr, attr);
      }
      if (hp->value != value)
      {
	if (hp->alloc_value)
	{
	  free(hp->value);
	  hp->value = NULL;
	}
	if (value == NULL)
	{
	  hp->alloc_value = 0;
	  hp->value = NULL;
	}
	else if (dupl)
	{
	  hp->alloc_value = 1;
	  hp->value = strdup(value);
	  if (hp->value == NULL)
	    return nerr_raise (NERR_NOMEM, "Unable to duplicate value %s for %s",
		value, name);
	}
	else
	{
	  hp->alloc_value = wf;
	  hp->value = (char *)value;
	}
      }
      if (lnk) hp->link = 1;
      else hp->link = 0;
    }
    else if (hp->link)
    {
      char *new_name = (char *) malloc(strlen(hp->value) + strlen(s) + 1);
      if (new_name == NULL)
      {
        return nerr_raise(NERR_NOMEM, "Unable to allocate memory");
      }
      strcpy(new_name, hp->value);
      strcat(new_name, s);
      err = _set_value (hdf->top, new_name, value, dupl, wf, lnk, attr, set_node);
      free(new_name);
      return nerr_pass(err);
    }
    /* At this point, we're done if there is not more HDF name space to
     * traverse */
    if (s == NULL)
      break;
    /* Otherwise, we need to find the next part of the namespace */
    n = s + 1;
    s = strchr (n, '.');
    x = (s != NULL) ? s - n : strlen(n);
    if (x == 0)
    {
      return nerr_raise(NERR_ASSERT, "Unable to set Empty component %s", name);
    }
    hn = hp;
  }
  if (set_node != NULL) *set_node = hp;
  return STATUS_OK;
}
Esempio n. 9
0
static NEOERR* _hdf_read_string (HDF *hdf, const char **str, STRING *line,
                                 const char *path, int *lineno,
                                 int include_handle, int expect_end_brace) {
  NEOERR *err;
  HDF *lower;
  char *s;
  char *name, *value;
  HDF_ATTR *attr = NULL;

  while (**str != '\0')
  {
    /* Reset string length, but don't free the reserved buffer */
    line->len = 0;
    err = _copy_line_advance(str, line);
    if (err) return nerr_pass(err);
    attr = NULL;
    (*lineno)++;
    s = line->buf;
    SKIPWS(s);
    if ((!strncmp(s, "#include ", 9) || !strncmp(s, "-include ", 9)) && include_handle != INCLUDE_IGNORE)
    {
      int required = !strncmp(s, "#include ", 9);
      if (include_handle == INCLUDE_ERROR)
      {
	return nerr_raise (NERR_PARSE,
                           "[%d]: #include not supported in string parse",
                           *lineno);
      }
      else if (include_handle < INCLUDE_MAX_DEPTH)
      {
        int l;
        s += 9;
        name = neos_strip(s);
        l = strlen(name);
        if (name[0] == '"' && name[l-1] == '"')
        {
          name[l-1] = '\0';
          name++;
        }
        char fullpath[PATH_MAX];
        if (name[0] != '/') {
          memset(fullpath, 0, PATH_MAX);

          char *p = strrchr(path, '/');
          if (p == NULL) {
            char pwd[PATH_MAX];
            memset(pwd, 0, PATH_MAX);
            getcwd(pwd, PATH_MAX);
            snprintf(fullpath, PATH_MAX, "%s/%s", pwd, name);
          } else {
            int dir_len = p - path + 1;
            snprintf(fullpath, PATH_MAX, "%s", path);
            snprintf(fullpath + dir_len, PATH_MAX - dir_len, "%s", name);
          }
          name = fullpath;
        }
        err = hdf_read_file_internal(hdf, name, include_handle + 1);
        if (err != STATUS_OK && required)
        {
          return nerr_pass_ctx(err, "In file %s:%d", path, *lineno);
        }
      }
      else {
        return nerr_raise (NERR_MAX_RECURSION,
                           "[%d]: Too many recursion levels.",
                           *lineno
                           );
      }
    }
    else if (s[0] == '#')
    {
      /* comment: pass */
    }
    else if (s[0] == '}') /* up */
    {
      s = neos_strip(s);
      if (strcmp(s, "}"))
      {
        err = nerr_raise(NERR_PARSE,
	    "[%s:%d] Trailing garbage on line following }: %s", path, *lineno,
	    line->buf);
        return err;
      }
      return STATUS_OK;
    }
    else if (s[0])
    {
      /* Valid hdf name is [0-9a-zA-Z_.]+ */
      int splice = *s == '@';
      if (splice) s++;
      name = s;
      while (*s && (isalnum(*s) || *s == '_' || *s == '.' || *s == '*')) s++;
      SKIPWS(s);

      char num[16];
      static int counter = 0;
      if (*name == '*') {
        snprintf(num, sizeof(num), "%d", counter++);
        name = num;
      }

      if (s[0] == '[') /* attributes */
      {
	*s = '\0';
	name = neos_strip(name);
	s++;
	err = parse_attr(&s, &attr);
	if (err)
        {
          return nerr_pass_ctx(err, "In file %s:%d", path, *lineno);
        }
	SKIPWS(s);
      }
      if (splice) {
        name = neos_strip(name);
        HDF *h = hdf_get_obj(hdf->top, name);
        if (h) {
          HDF *c = hdf_obj_child(h);
          while (c) {
            err = hdf_copy (hdf, hdf_obj_name(c), c);
            if (err != STATUS_OK) break;
            c = hdf_obj_next(c);
          }
        }
	if (err != STATUS_OK)
        {
          return nerr_pass_ctx(err, "In file %s:%d", path, *lineno);
        }
      } else if (s[0] == '=') /* assignment */
      {
	*s = '\0';
	name = neos_strip(name);
	s++;
	value = neos_strip(s);
	err = _set_value (hdf, name, value, 1, 1, 0, attr, NULL);
	if (err != STATUS_OK)
        {
          return nerr_pass_ctx(err, "In file %s:%d", path, *lineno);
        }
      }
      else if (s[0] == ':' && s[1] == '=') /* copy */
      {
	*s = '\0';
	name = neos_strip(name);
	s+=2;
	value = neos_strip(s);
        HDF *h = hdf_get_obj(hdf->top, value);
        if (!h)
        {
	  err = nerr_raise(NERR_PARSE,
                           "[%s:%d] Failed to copy a node that is not loaded "
                           "yet: %s", path, *lineno, value);
          return err;
        }
        err = hdf_copy(hdf, name, h);
	if (err != STATUS_OK)
        {
          return nerr_pass_ctx(err, "In file %s:%d", path, *lineno);
        }
      }
      else if (s[0] == '!' && s[1] == '=') /* exec */
      {
	*s = '\0';
	name = neos_strip(name);
	s+=2;
	value = neos_strip(s);

        FILE *f = popen(value, "r");
	if (f == NULL)
        {
	  err = nerr_raise(NERR_PARSE,
                           "[%s:%d] Failed to exec specified command: %s",
                           path, *lineno, line->buf);
          return err;
        }
        char *content = _read_file(f);
        fclose(f);
        int len = strlen(content);
        if (len > 0 && content[len - 1] == '\n') {
          content[len - 1] = '\0'; // remove \n artifact
        }
	err = _set_value (hdf, name, content, 1, 1, 0, attr, NULL);
        free(content);

	if (err != STATUS_OK)
        {
          return nerr_pass_ctx(err, "In file %s:%d", path, *lineno);
        }
      }
      else if (s[0] == ':') /* link */
      {
	*s = '\0';
	name = neos_strip(name);
	s++;
	value = neos_strip(s);
	err = _set_value (hdf, name, value, 1, 1, 1, attr, NULL);
	if (err != STATUS_OK)
        {
          return nerr_pass_ctx(err, "In file %s:%d", path, *lineno);
        }
      }
      else if (s[0] == '{') /* deeper */
      {
	*s = '\0';
	name = neos_strip(name);
	lower = hdf_get_obj (hdf, name);
	if (lower == NULL)
	{
	  err = _set_value (hdf, name, NULL, 1, 1, 0, attr, &lower);
	}
	else
	{
	  err = _set_value (lower, NULL, lower->value, 1, 1, 0, attr, NULL);
	}
	if (err != STATUS_OK)
        {
          return nerr_pass_ctx(err, "In file %s:%d", path, *lineno);
        }
	err = _hdf_read_string (lower, str, line, path, lineno, include_handle,
                                1);
	if (err != STATUS_OK)
        {
          return nerr_pass_ctx(err, "In file %s:%d", path, *lineno);
        }
      }
      else if (s[0] == '<' && s[1] == '<') /* multi-line assignment */
      {
	char *m;
	int msize = 0;
	int mmax = 128;
	int l;

	*s = '\0';
	name = neos_strip(name);
	s+=2;
	value = neos_strip(s);
	l = strlen(value);
	if (l == 0)
        {
	  err = nerr_raise(NERR_PARSE,
	      "[%s:%d] No multi-assignment terminator given: %s", path, *lineno,
	      line->buf);
          return err;
        }
	m = (char *) malloc (mmax * sizeof(char));
	if (m == NULL)
        {
	  return nerr_raise(NERR_NOMEM,
	    "[%s:%d] Unable to allocate memory for multi-line assignment to %s",
	    path, *lineno, name);
        }
	while (_copy_line (str, m+msize, mmax-msize) != 0)
	{
          (*lineno)++;
	  if (!strncmp(value, m+msize, l) && isspace(m[msize+l]))
	  {
	    m[msize] = '\0';
	    break;
	  }
	  msize += strlen(m+msize);
	  if (msize + l + 10 > mmax)
	  {
	    void *new_ptr;
	    mmax += 128;
	    new_ptr = realloc (m, mmax * sizeof(char));
	    if (new_ptr == NULL)
	    {
        free(m);
	      return nerr_raise(NERR_NOMEM,
		  "[%s:%d] Unable to allocate memory for multi-line assignment to %s: size=%d",
		  path, *lineno, name, mmax);
      }
      m = (char *) new_ptr;
	  }
	}
	err = _set_value (hdf, name, m, 0, 1, 0, attr, NULL);
	if (err != STATUS_OK)
	{
	  free (m);
          return nerr_pass_ctx(err, "In file %s:%d", path, *lineno);
	}

      }
      else
      {
	err = nerr_raise(NERR_PARSE, "[%s:%d] Unable to parse line %s", path,
	    *lineno, line->buf);
        return err;
      }
    }
  }
  if (expect_end_brace) {
    err = nerr_raise(NERR_PARSE, "[%s:%d] Missing matching }", path, *lineno);
    return err;
  }
  return STATUS_OK;
}
Esempio n. 10
0
/* attributes are of the form [key1, key2, key3=value, key4="repr"] */
static NEOERR* parse_attr(char **str, HDF_ATTR **attr)
{
  NEOERR *err = STATUS_OK;
  char *s = *str;
  char *k, *v;
  int k_l, v_l;
  STRING buf;
  char c;
  HDF_ATTR *ha, *hal = NULL;

  *attr = NULL;

  string_init(&buf);
  while (*s && *s != ']')
  {
    k = s;
    k_l = 0;
    v = NULL;
    v_l = 0;
    while (*s && isalnum(*s)) s++;
    k_l = s-k;
    if (*s == '\0' || k_l == 0)
    {
      _dealloc_hdf_attr(attr);
      return nerr_raise(NERR_PARSE, "Misformed attribute specification: %s", *str);
    }
    SKIPWS(s);
    if (*s == '=')
    {
      s++;
      SKIPWS(s);
      if (*s == '"')
      {
	s++;
	while (*s && *s != '"')
	{
	  if (*s == '\\')
	  {
	    if (isdigit(*(s+1)))
	    {
	      s++;
	      c = *s - '0';
	      if (isdigit(*(s+1)))
	      {
		s++;
		c = (c * 8) + (*s - '0');
		if (isdigit(*(s+1)))
		{
		  s++;
		  c = (c * 8) + (*s - '0');
		}
	      }
	    }
	    else
	    {
	      s++;
	      if (*s == 'n') c = '\n';
	      else if (*s == 't') c = '\t';
	      else if (*s == 'r') c = '\r';
	      else c = *s;
	    }
	    err = string_append_char(&buf, c);
	  }
	  else
	  {
	    err = string_append_char(&buf, *s);
	  }
	  if (err)
	  {
	    string_clear(&buf);
	    _dealloc_hdf_attr(attr);
	    return nerr_pass(err);
	  }
	  s++;
	}
	if (*s == '\0')
	{
	  _dealloc_hdf_attr(attr);
	  string_clear(&buf);
	  return nerr_raise(NERR_PARSE, "Misformed attribute specification: %s", *str);
	}
	s++;
	v = buf.buf;
        v_l = buf.len;
      }
      else
      {
	v = s;
	while (*s && *s != ' ' && *s != ',' && *s != ']') s++;
	if (*s == '\0')
	{
	  _dealloc_hdf_attr(attr);
	  return nerr_raise(NERR_PARSE, "Misformed attribute specification: %s", *str);
	}
        v_l = s-v;
      }
    }
    else
    {
      v = "1";
    }
    ha = (HDF_ATTR*) calloc (1, sizeof(HDF_ATTR));
    if (ha == NULL)
    {
      _dealloc_hdf_attr(attr);
      string_clear(&buf);
      return nerr_raise(NERR_NOMEM, "Unable to load attributes: %s", s);
    }
    if (*attr == NULL) *attr = ha;
    ha->key = _strndup(k, k_l);
    if (v)
      ha->value = _strndup(v, v_l);
    else
      ha->value = strdup("");
    if (ha->key == NULL || ha->value == NULL)
    {
      _dealloc_hdf_attr(attr);
      string_clear(&buf);
      return nerr_raise(NERR_NOMEM, "Unable to load attributes: %s", s);
    }
    if (hal != NULL) hal->next = ha;
    hal = ha;
    string_clear(&buf);
    SKIPWS(s);
    if (*s == ',')
    {
      s++;
      SKIPWS(s);
    }
  }
  if (*s == '\0')
  {
    _dealloc_hdf_attr(attr);
    return nerr_raise(NERR_PARSE, "Misformed attribute specification: %s", *str);
  }
  *str = s+1;
  return STATUS_OK;
}
Esempio n. 11
0
static NEOERR* hdf_dump_cb(HDF *hdf, const char *prefix, int dtype, int lvl,
                           void *rock, DUMPF_CB dump_cbf)
{
  NEOERR *err;
  char *p, op;
  char ml[10] = "\nEOM\n";
  int ml_len = strlen(ml);
  char whsp[256] = "";

  if (dtype == DUMP_TYPE_PRETTY)
  {
    memset(whsp, ' ', 256);
    if (lvl > 127)
      lvl = 127;
    whsp[lvl*2] = '\0';
  }

  if (hdf != NULL) hdf = hdf->child;

  while (hdf != NULL)
  {
    op = '=';
    if (hdf->value)
    {
      if (hdf->link) op = ':';
      if (prefix && (dtype == DUMP_TYPE_DOTTED))
      {
	err = dump_cbf(rock, "%s.%s", prefix, hdf->name);
      }
      else
      {
	err = dump_cbf(rock, "%s%s", whsp, hdf->name);
      }
      if (err) return nerr_pass (err);
      if (hdf->attr)
      {
	HDF_ATTR *attr = hdf->attr;
	char *v = NULL;

	err = dump_cbf(rock, " [");
	if (err) return nerr_pass(err);
	while (attr != NULL)
	{
	  if (attr->value == NULL || !strcmp(attr->value, "1"))
	    err = dump_cbf(rock, "%s", attr->key);
	  else
	  {
	    v = repr_string_alloc(attr->value);

	    if (v == NULL)
	      return nerr_raise(NERR_NOMEM, "Unable to repr attr %s value %s", attr->key, attr->value);
	    err = dump_cbf(rock, "%s=%s", attr->key, v);
	    free(v);
	  }
	  if (err) return nerr_pass(err);
	  if (attr->next)
	  {
	    err = dump_cbf(rock, ", ");
	    if (err) return nerr_pass(err);
	  }
	  attr = attr->next;
	}
	err = dump_cbf(rock, "] ");
	if (err) return nerr_pass(err);
      }
      if (strchr (hdf->value, '\n'))
      {
	int vlen = strlen(hdf->value);

	while (strstr(hdf->value, ml) || ((vlen > ml_len) && !strncmp(hdf->value + vlen - ml_len + 1, ml, strlen(ml) - 1)))
	{
	  gen_ml_break(ml, sizeof(ml));
	  ml_len = strlen(ml);
	}
	if (hdf->value[strlen(hdf->value)-1] != '\n')
	  err = dump_cbf(rock, " << %s%s%s", ml+1, hdf->value, ml);
	else
	  err = dump_cbf(rock, " << %s%s%s", ml+1, hdf->value, ml+1);
      }
      else
      {
	err = dump_cbf(rock, " %c %s\n", op, hdf->value);
      }
      if (err) return nerr_pass (err);
    }
    if (hdf->child)
    {
      if (prefix && (dtype == DUMP_TYPE_DOTTED))
      {
	p = (char *) malloc (strlen(hdf->name) + strlen(prefix) + 2);
	sprintf (p, "%s.%s", prefix, hdf->name);
	err = hdf_dump_cb (hdf, p, dtype, lvl+1, rock, dump_cbf);
	free(p);
      }
      else
      {
	if (hdf->name && (dtype != DUMP_TYPE_DOTTED))
	{
	  err = dump_cbf(rock, "%s%s {\n", whsp, hdf->name);
	  if (err) return nerr_pass (err);
	  err = hdf_dump_cb (hdf, hdf->name, dtype, lvl+1, rock, dump_cbf);
	  if (err) return nerr_pass (err);
	  err = dump_cbf(rock, "%s}\n", whsp);
	}
	else
	{
	  err = hdf_dump_cb (hdf, hdf->name, dtype, lvl+1, rock, dump_cbf);
	}
      }
      if (err) return nerr_pass (err);
    }
    hdf = hdf->next;
  }
  return STATUS_OK;
}