/********************************************************************
 * FUNCTION new_event_cb
 * 
 * Malloc and fill in a new event control block
 *
 * INPUTS:
 *   modname == module name
 *   event == eventname
 *   cbfn == callback function to use
 *
 * RETURNS:
 *   filled in struct or NULL if ERR_INTERNAL_MEM
 *********************************************************************/
static event_cb_t *
    new_event_cb (const xmlChar *modname,
                 const xmlChar *event,
                 yangcli_notif_cbfn_t cbfn)
{
    event_cb_t *cb = m__getObj(event_cb_t);
    if (cb == NULL) {
        return NULL;
    }
    memset(cb, 0x0, sizeof(event_cb_t));

    cb->modname = xml_strdup(modname);
    if (cb->modname == NULL) {
        free_event_cb(cb);
        return NULL;
    }

    cb->event = xml_strdup(event);
    if (cb->event == NULL) {
        free_event_cb(cb);
        return NULL;
    }

    cb->cbfn = cbfn;

    return cb;

} /* new_event_cb */
Beispiel #2
0
/********************************************************************
* FUNCTION agt_ses_set_dummy_session_acm
*
* Set the session ID and username of the user that
* will be responsible for the rollback if needed
*
* INPUTS:
*   dummy_session == session control block to change
*   use_sid == Session ID to use for the rollback
*
* RETURNS:
*   status
*********************************************************************/
status_t
    agt_ses_set_dummy_session_acm (ses_cb_t *dummy_session,
                                   ses_id_t  use_sid)
{
    ses_cb_t  *scb;

    assert( dummy_session && "dummy_session is NULL!" );

    if (!agt_ses_init_done) {
        agt_ses_init();
    }

    scb = agtses[use_sid];
    if (scb == NULL) {
        return ERR_NCX_INVALID_VALUE;
    }

    dummy_session->rollback_sid = use_sid;

    /*TODO Quick fix for confirmed-commit/rollback bug. */
    /*     Needs further investigation. */
    dummy_session->sid = use_sid;

    if (scb == dummy_session) {
        return NO_ERR;  /* skip -- nothing to do */
    }

    if (dummy_session->username && scb->username) {
        m__free(dummy_session->username);
        dummy_session->username = NULL;
    }

    if (scb->username) {
        dummy_session->username = xml_strdup(scb->username);
        if (dummy_session->username == NULL) {
            return ERR_INTERNAL_MEM;
        }
    }

    if (dummy_session->peeraddr && scb->peeraddr) {
        m__free(dummy_session->peeraddr);
        dummy_session->peeraddr = NULL;
    }

    if (scb->peeraddr) {
        dummy_session->peeraddr = xml_strdup(scb->peeraddr);
        if (dummy_session->peeraddr == NULL) {
            return ERR_INTERNAL_MEM;
        }
    }
    
    return NO_ERR;

}  /* agt_ses_set_dummy_session_acm */
Beispiel #3
0
/********************************************************************
* FUNCTION ncx_copy_str
* 
* Copy the contents of str1 to str2
* Supports base types:
*     NCX_BT_STRING
*     NCX_BT_INSTANCE_ID
*     NCX_BT_LEAFREF
*
* INPUTS:
*     str1 == first string
*     str2 == second string
*     btyp == expected data type
*
* OUTPUTS:
*    str2 contains copy of str1
*
* RETURNS:
*     status
*********************************************************************/
status_t
    ncx_copy_str (const ncx_str_t *str1,
                  ncx_str_t *str2,
                  ncx_btype_t  btyp)
{
#ifdef DEBUG
    if (!str1 || !str2) {
        return SET_ERROR(ERR_INTERNAL_PTR);
    }
#endif
    if (!(typ_is_string(btyp) || btyp==NCX_BT_BITS)) {
        return ERR_NCX_INVALID_VALUE;
    }   

    if (*str1) {
        *str2 = xml_strdup(*str1);
        if (!*str2) {
            return ERR_INTERNAL_MEM;
        }
    } else {
        *str2 = NULL;
    }
    return NO_ERR;

}  /* ncx_copy_str */
Beispiel #4
0
/********************************************************************
* FUNCTION mgr_rpc_new_request
*
* Malloc and initialize a new mgr_rpc_req_t struct
*
* INPUTS:
*   scb == session control block
*
* RETURNS:
*   pointer to struct or NULL or memory error
*********************************************************************/
mgr_rpc_req_t *
    mgr_rpc_new_request (ses_cb_t *scb)
{
    mgr_scb_t       *mscb;
    mgr_rpc_req_t   *req;
    char             numbuff[NCX_MAX_NUMLEN];

    req = m__getObj(mgr_rpc_req_t);
    if (!req) {
        return NULL;
    }
    memset(req, 0x0, sizeof(mgr_rpc_req_t));

    mscb = mgr_ses_get_mscb(scb);
    sprintf(numbuff, "%u", mscb->next_id);
    if (mscb->next_id >= MGR_MAX_REQUEST_ID) {
        mscb->next_id = 0;
    } else {
        mscb->next_id++;
    }

    req->msg_id = xml_strdup((const xmlChar *)numbuff);
    if (req->msg_id) {
        xml_msg_init_hdr(&req->mhdr);
        xml_init_attrs(&req->attrs);
    } else {
        m__free(req);
        req = NULL;
    }
    return req;

} /* mgr_rpc_new_request */
Beispiel #5
0
/********************************************************************
* FUNCTION agt_cfg_new_auditrec
*
* Malloc and initialize a new agt_cfg_audit_rec_t struct
*
* INPUTS:
*   target == i-i string of edit target
*   editop == edit operation enum
*
* RETURNS:
*   pointer to struct or NULL or memory error
*********************************************************************/
agt_cfg_audit_rec_t *
    agt_cfg_new_auditrec (const xmlChar *target,
                          op_editop_t editop)
{
    agt_cfg_audit_rec_t *auditrec;

#ifdef DEBUG
    if (target == NULL) {
        SET_ERROR(ERR_INTERNAL_PTR);
        return NULL;
    }
#endif

    auditrec = m__getObj(agt_cfg_audit_rec_t);
    if (!auditrec) {
        return NULL;
    }
    memset(auditrec, 0x0, sizeof(agt_cfg_audit_rec_t));
    auditrec->target = xml_strdup(target);
    if (auditrec->target == NULL) {
        m__free(auditrec);
        return NULL;
    }
    auditrec->editop = editop;
    return auditrec;

} /* agt_cfg_new_auditrec */
Beispiel #6
0
void test_output()
{
    xml_body_ptr body = NULL;
    xml_table_ptr table = NULL;
    xml_item_ptr item = NULL;
    xml_item_attr_ptr attr = NULL;
    xml_handel handel = NULL;
    char *buf;
    int len, i, t_cnt = 1;

    printf("\n*** test_output ***\n");

    /* new body with [t_cnt] tables */
    body = xml_body_new(t_cnt);
    for ( i = 0; i < t_cnt; i++ ) {
        /* init every table with 1 item, each item 1 attribute */
        xml_table_init(body->t_list + i, 1, 1);
    }

    /* init xml_body here */    
    body->unit_code = xml_strdup(body, "场所编码");

    table = xml_get_table(body, 0);
    /* init xml_table[0] here */
    table->name = xml_strdup(body, "记录集名称");
    
    item = xml_get_item(table, 0);    
    attr = xml_get_attr(item, 0);
    /* init xml_item[0].attr[0] */
    attr->name = xml_strdup(body, "item1");
    attr->value = xml_strdup(body, "值1");

    /* get xml buffer */
    handel = xml_output(body, &buf, &len);
    
    printf("%s", buf);
    
    /* clean xml buffer */
    xml_output_clean(handel);

    /* clean body */
    xml_body_clean(body);
    
}
Beispiel #7
0
static void s_xml_parse_item(xml_body_ptr body, xml_item_ptr item, xmlNodePtr n_item)
{
    xmlAttrPtr n_attr = NULL;
    int i;
    
    for ( i = 0, n_attr = n_item->properties; NULL != n_attr; i++, n_attr = n_attr->next ) {
        item->attr_list[i].name = xml_strdup(body, (const char *)n_attr->name);
        item->attr_list[i].value = s_xml_get_attr(body, n_item, (const char *)n_attr->name);
    }
}
Beispiel #8
0
/********************************************************************
* FUNCTION ncx_clone_iffeature
* 
* Clone a new ncx_iffeature_t struct
*
* INPUTS:
*    srciff == ifffeature struct to clone
* RETURNS:
*    pointer to a malloced ncx_iffeature_t struct,
*    or NULL if malloc error
*********************************************************************/
ncx_iffeature_t *
    ncx_clone_iffeature (ncx_iffeature_t *srciff)
{
    ncx_iffeature_t *iff;

    iff = m__getObj(ncx_iffeature_t);
    if (!iff) {
        return NULL;
    }
    memset(iff, 0x0, sizeof(ncx_iffeature_t));

    if (srciff->prefix) {
        iff->prefix = xml_strdup(srciff->prefix);
        if (iff->prefix == NULL) {
            ncx_free_iffeature(iff);
            return NULL;
        }
    }

    if (srciff->name) {
        iff->name = xml_strdup(srciff->name);
        if (iff->name == NULL) {
            ncx_free_iffeature(iff);
            return NULL;
        }
    }

    iff->feature = srciff->feature;

    ncx_set_error(&iff->tkerr,
                  srciff->tkerr.mod,
                  srciff->tkerr.linenum,
                  srciff->tkerr.linepos);

    //iff->seen not set

    return iff;

} /* ncx_clone_iffeature */
Beispiel #9
0
/********************************************************************
* FUNCTION new_feature_entry
* 
* Create a feature_entry_t
*
* INPUTS:
*   featstr == feature string parm to use
*********************************************************************/
static feature_entry_t *
    new_feature_entry (const xmlChar *featstr)
{
    uint32 len = 0;
    boolean splitdone = FALSE;
    status_t res = split_feature_string(featstr, &len);
    if (res == NO_ERR) {
        splitdone = TRUE;
    }

    feature_entry_t *feature_entry = m__getObj(feature_entry_t);
    if (feature_entry == NULL) {
        return NULL;
    }
    memset(feature_entry, 0x0, sizeof(feature_entry_t));

    if (splitdone) {
        feature_entry->modname = xml_strndup(featstr, len);
        if (feature_entry->modname == NULL) {
            free_feature_entry(feature_entry);
            return NULL;
        }

        feature_entry->feature = xml_strdup(&featstr[len+1]);
        if (feature_entry->feature == NULL) {
            free_feature_entry(feature_entry);
            return NULL;
        }
    } else {
        feature_entry->feature = xml_strdup(featstr);
        if (feature_entry->feature == NULL) {
            free_feature_entry(feature_entry);
            return NULL;
        }
    }

    return feature_entry;

}  /* new_feature_entry */
Beispiel #10
0
/* 得到xml结点的属性值 */
static char * s_xml_get_attr(xml_body_ptr body, const xmlNodePtr node, const char *name)
{
    xmlChar *value = NULL;
    char *value_o = NULL;

    value = xmlGetProp(node, CONST_CAST name);
    if ( NULL != value ) {
        value_o = xml_strdup(body, iconv_utf8_to_gbk((char *)value));
        xmlFree((void *)value);
    }

    return value_o;
}
Beispiel #11
0
/********************************************************************
* FUNCTION yangapi_new_keyval
*
* Create a new YANGAPI keyval holder
*
* INPUTS:
*   keyval == key valuse string
* RETURNS:
*   pointer to initialized keyval, or NULL if malloc error
*********************************************************************/
yangapi_keyval_t *
    yangapi_new_keyval (const xmlChar *keyval)
{
    yangapi_keyval_t *val = m__getObj(yangapi_keyval_t);
    if (val) {
        memset(val, 0x0, sizeof(yangapi_keyval_t));
        val->value = xml_strdup(keyval);
        if (!val->value) {
            yangapi_free_keyval(val);
            return NULL;
        }
    }
    return val;

}  /* yangapi_new_keyval */
Beispiel #12
0
/********************************************************************
* FUNCTION new_feature_entry2
* 
* Create a feature_entry_t
*
* INPUTS:
*   modname == module name to use
*   name == feature name to use
*********************************************************************/
static feature_entry_t *
    new_feature_entry2 (const xmlChar *modname,
                        const xmlChar *name)
{
    feature_entry_t *feature_entry = m__getObj(feature_entry_t);
    if (feature_entry == NULL) {
        return NULL;
    }
    memset(feature_entry, 0x0, sizeof(feature_entry_t));

    feature_entry->modname = xml_strdup(modname);
    if (feature_entry->modname == NULL) {
        free_feature_entry(feature_entry);
        return NULL;
    }

    feature_entry->feature = xml_strdup(name);
    if (feature_entry->feature == NULL) {
        free_feature_entry(feature_entry);
        return NULL;
    }
    return feature_entry;

}  /* new_feature_entry2 */
/********************************************************************
 * FUNCTION set_alias
 * 
 * Set an alias value field
 *
 * INPUTS:
 *    alias == alias record to use
 *    valstr == value string to use
 *
 * RETURNS:
 *    status
 *********************************************************************/
static status_t
    set_alias (alias_cb_t *alias,
               const xmlChar *valstr)
{
    status_t  res = NO_ERR;

    if (alias->value) {
        m__free(alias->value);
        alias->value = NULL;
    }
    alias->quotes = 0;
    if (valstr) {
        if (*valstr == '"' || *valstr == '\'') {
            /* preseve quotes used */
            alias->quotes = (*valstr == '"') ? 2 : 1;

            /* check trim quoted string */
            uint32 len = xml_strlen(valstr);
            if (len > 2) {
                const xmlChar *endstr = &valstr[len-1];
                if (*endstr == *valstr) {
                    /* remove paired quotes */
                    alias->value = xml_strndup(valstr+1, len-2);
                    if (alias->value == NULL) {
                        res = ERR_INTERNAL_MEM;
                    }
                } else {
                    /* improper string; unmatched quotes */
                    res = ERR_NCX_INVALID_VALUE;
                }
            } else {
                /* else got just a quote char */
                res = ERR_NCX_INVALID_VALUE;
            }
        } else {
            alias->value = xml_strdup(valstr);
            if (alias->value == NULL) {
                res = ERR_INTERNAL_MEM;
            }
        }
    } /* else cleared value if not already */


    return res;

}  /* set_alias */
static agt_cb_queue_notification_set_t* new_callback_set( const xmlChar *modname )
{
    agt_cb_queue_notification_set_t* cbSet = m__getObj( 
            agt_cb_queue_notification_set_t );

    if ( !cbSet )
    {
        return NULL;
    }

    memset( cbSet, 0, sizeof( agt_cb_queue_notification_set_t ) );
    cbSet->modname = xml_strdup( modname );
    if ( !cbSet->modname )
    {
        m__free( cbSet );
        return NULL;
    }

    return cbSet;
}
Beispiel #15
0
/********************************************************************
* FUNCTION consume_node
* 
* Internal consume XML node function
* see agt_xml_consume_node for details.
*
* EXTRA INPUTS:
*   eoferr == TRUE if an End of File error should be generated
*          == FALSE if not
*    nserr == TRUE if bad namespace should be checked
*          == FALSE if not
*    clean == TRUE is a string should be cleaned before returned 
*          == FALSE if a string node should be returned as-is
*
* RETURNS:
*   status of the operation
*   Try to fail on fatal errors only
*********************************************************************/
static status_t 
    consume_node (ses_cb_t *scb,
                  boolean advance,
                  xml_node_t *node,
                  ncx_layer_t layer,
                  xml_msg_hdr_t *msghdr,
                  boolean eoferr,
                  boolean nserr,
                  boolean clean)
{
    int             ret, nodetyp;
    const xmlChar  *badns;
    xmlChar        *valstr, *namestr;
    uint32          len;
    status_t        res, res2;
    boolean         done;

    /* init local vars */
    done = FALSE;
    res = NO_ERR;
    res2 = NO_ERR;
    badns = NULL;

    /* loop past any unused xmlTextReader node types */
    while (!done) {
        /* check if a new node should be read */
        if (advance) {
            /* advance the node pointer */
            ret = xmlTextReaderRead(scb->reader);
            if (ret != 1) {
                /* do not treat this as an internal error */
                res = ERR_XML_READER_EOF;
                if (msghdr && eoferr) {
                    /* generate an operation-failed error */
                    agt_record_error(scb, 
                                     msghdr, 
                                     layer, 
                                     res, 
                                     NULL, 
                                     NCX_NT_NONE,
                                     NULL, 
                                     NCX_NT_NONE,
                                     NULL);
                }
                return res;
            }
        }

        /* get the node depth to match the end node correctly */
        node->depth = xmlTextReaderDepth(scb->reader);
        if (node->depth == -1) {
            /* this never actaully happens */
            SET_ERROR(ERR_XML_READER_INTERNAL);
            node->depth = 0;
        }

        /* get the internal nodetype, check it and convert it */
        nodetyp = xmlTextReaderNodeType(scb->reader);
        switch (nodetyp) {
        case XML_ELEMENT_NODE:
            /* classify element as empty or start */
            if (xmlTextReaderIsEmptyElement(scb->reader)) {
                node->nodetyp = XML_NT_EMPTY;
            } else {
                node->nodetyp = XML_NT_START;
            }
            done = TRUE;
            break;
        case XML_ELEMENT_DECL:
            node->nodetyp = XML_NT_END;
            done = TRUE;
            break;
        case XML_TEXT_NODE:
     /* case XML_DTD_NODE: */
            node->nodetyp = XML_NT_STRING;
            done = TRUE;
            break;
        default:
            /* unused node type -- keep trying */
            if (LOGDEBUG3) {
                log_debug3("\nxml_consume_node: skip unused node (%s)",
                           xml_get_node_name(nodetyp));
            }
            advance = TRUE;
        }
    }

    /* finish the node, depending on its type */
    switch (node->nodetyp) {
    case XML_NT_START:
    case XML_NT_END:
    case XML_NT_EMPTY:
        /* get the element QName */
        namestr = xml_strdup(xmlTextReaderConstName(scb->reader));
        if (!namestr) {
            res = ERR_INTERNAL_MEM;
        } else {
            node->qname = namestr;

            /* check for namespace prefix in the name 
             * only error returned is unknown-namespace 
             */
            len = 0;
            res = xml_check_ns(scb->reader, 
                               namestr, 
                               &node->nsid, 
                               &len, 
                               &badns);
            if (!nserr && res != NO_ERR) {
                node->nsid = xmlns_inv_id();
                len = 0;
                res = NO_ERR;
            }
            
            /* set the element name to the char after the prefix, if any */
            node->elname = (const xmlChar *)(namestr+len);
        
            /* get all the attributes, except for XML_NT_END */
            if (res == NO_ERR && node->nodetyp != XML_NT_END) {
                res2 = get_all_attrs(scb, 
                                     node,
                                     &node->attrs, 
                                     layer, 
                                     msghdr, 
                                     nserr);
            }

            /* Set the node module */
            if (res == NO_ERR) {
                if (node->nsid) {
                    node->module = xmlns_get_module(node->nsid);
                } else {
                    /* no entry, use the default module (ncx) */
                    node->module = NCX_DEF_MODULE;
                }
            }
        }
        break;
    case XML_NT_STRING:
        /* get the text value -- this is a malloced string */
        node->simval = NULL;
        valstr = xmlTextReaderValue(scb->reader);
        if (valstr) {
            if (clean) {
                node->simfree = xml_copy_clean_string(valstr);
            } else {
                node->simfree = xml_strdup(valstr);
            }
            if (node->simfree) {
                node->simlen = xml_strlen(node->simfree);
                node->simval = (const xmlChar *)node->simfree;
            }

            /* see if this is a QName string; if so save the NSID */
            xml_check_qname_content(scb->reader, node);

            xmlFree(valstr);
        }
        if (!node->simval) {
            /* prevent a NULL ptr reference */
            node->simval = EMPTY_STRING;
            node->simlen = 0;
            node->simfree = NULL;
        }
        break;
    default:
        break;
    }

    if ((res != NO_ERR) && msghdr) {
        if (badns) {
            /* generate an operation-failed error */
            agt_record_error(scb,
                             msghdr,
                             layer, 
                             res, 
                             node,
                             NCX_NT_STRING, 
                             badns, 
                             NCX_NT_NONE, 
                             NULL);
        } else {
            agt_record_error(scb,
                             msghdr,
                             layer,
                             res, 
                             node,
                             NCX_NT_NONE,
                             NULL, 
                             NCX_NT_NONE, 
                             NULL);
        }
    }

    if (LOGDEBUG4) {
        log_debug4("\nxml_consume_node: return (%d)", 
                   (res==NO_ERR) ? res2 : res);
        if (scb->state != SES_ST_INIT) {
            xml_dump_node(node);
        }
    }

    /* return general error first, then attribute error 
     * It doesn't really matter since the caller will 
     * assume all error reports have been queued upon return
     */
    return (res==NO_ERR) ? res2 : res;

}  /* consume_node */
Beispiel #16
0
XMLNODE *XMLParseFile(XSLTGLOBALDATA *gctx, char *file)
{
  info("XMLParseFile:: file %s", file);
  return xml_parse_file(gctx, xml_strdup(file), 0);
}
Beispiel #17
0
/********************************************************************
* FUNCTION mgr_rpc_dispatch
*
* Dispatch an incoming <rpc-reply> response
* handle the <rpc-reply> element
* called by mgr_top.c: 
* This function is registered with top_register_node
* for the module 'netconf', top-node 'rpc-reply'
*
* INPUTS:
*   scb == session control block
*   top == top element descriptor
*********************************************************************/
void 
    mgr_rpc_dispatch (ses_cb_t *scb,
                      xml_node_t *top)
{
    obj_template_t          *rpyobj;
    mgr_rpc_rpy_t           *rpy;
    mgr_rpc_req_t           *req;
    xml_attr_t              *attr;
    xmlChar                 *msg_id;
    ncx_module_t            *mod;
    mgr_rpc_cbfn_t           handler;
    ncx_num_t                num;
    status_t                 res;

#ifdef DEBUG
    if (!scb || !top) {
        SET_ERROR(ERR_INTERNAL_PTR);
        return;
    }
#endif

    /* init local vars */
    res = NO_ERR;
    msg_id = NULL;
    req = NULL;

    /* make sure any real session has been properly established */
    if (scb->type != SES_TYP_DUMMY && scb->state != SES_ST_IDLE) {
        log_error("\nError: mgr_rpc: skipping incoming message '%s'",
                  top->qname);
        mgr_xml_skip_subtree(scb->reader, top);
        return;
    }

    /* check if the reply template is already cached */
    rpyobj = NULL;
    mod = ncx_find_module(NC_MODULE, NULL);
    if (mod != NULL) {
        rpyobj = ncx_find_object(mod, NC_RPC_REPLY_TYPE);
    }
    if (rpyobj == NULL) {
        SET_ERROR(ERR_NCX_DEF_NOT_FOUND);
        mgr_xml_skip_subtree(scb->reader, top);
        return;
    }

    /* get the NC RPC message-id attribute; should be present
     * because the send-rpc function put a message-id in <rpc>
     */
    attr = xml_find_attr(top, 0, NCX_EL_MESSAGE_ID);
    if (attr && attr->attr_val) {
        msg_id = xml_strdup(attr->attr_val);
    }
    if (msg_id == NULL) {
        mgr_xml_skip_subtree(scb->reader, top);
        log_info("\nmgr_rpc: incoming message with no message-id");
        return;
    }       

    /* the current node is 'rpc-reply' in the netconf namespace
     * First get a new RPC reply struct
     */
    rpy = new_reply();
    if (rpy == NULL) {
        m__free(msg_id);
        log_error("\nError: mgr_rpc: skipping incoming message");
        mgr_xml_skip_subtree(scb->reader, top);
        return;
    } else {
        rpy->msg_id = msg_id;
    }
    
    /* get the NCX RPC group-id attribute if present */
    attr = xml_find_attr(top, xmlns_ncx_id(), NCX_EL_GROUP_ID);
    if (attr && attr->attr_val) {
        res = ncx_decode_num(attr->attr_val, NCX_BT_UINT32, &num);
        if (res == NO_ERR) {
            rpy->group_id = num.u;
        }
    }

    /* find the request that goes with this reply */
    if (rpy->msg_id != NULL) {
        req = find_request(scb, rpy->msg_id);
        if (req == NULL) {
#ifdef MGR_RPC_DEBUG
            log_debug("\nmgr_rpc: got request found for msg (%s) "
                      "on session %d", 
                      rpy->msg_id, 
                      scb->sid);
#endif
            mgr_xml_skip_subtree(scb->reader, top);
            mgr_rpc_free_reply(rpy);
            return;
        } else {
            dlq_remove(req);
        }
    }

    /* have a request/reply pair, so parse the reply 
     * as a val_value_t tree, stored in rpy->reply
     */
    rpy->res = mgr_val_parse_reply(scb, 
                                   rpyobj, 
                                   (req != NULL) ?
                                   req->rpc : ncx_get_gen_anyxml(),
                                   top, 
                                   rpy->reply);
    if (rpy->res != NO_ERR && LOGINFO) {
        log_info("\nmgr_rpc: got invalid reply on session %d (%s)",
                 scb->sid, get_error_string(rpy->res));
    }

    /* check that there is nothing after the <rpc-reply> element */
    if (rpy->res==NO_ERR && 
        !xml_docdone(scb->reader) && LOGINFO) {
        log_info("\nmgr_rpc: got extra nodes in reply on session %d",
                 scb->sid);
    }

    /* invoke the reply handler */
    if (req != NULL) { 
        handler = (mgr_rpc_cbfn_t)req->replycb;
        (*handler)(scb, req, rpy);
    }

    /* only reset the session state to idle if was not changed
     * to SES_ST_SHUTDOWN_REQ during this RPC call
     */
    if (scb->state == SES_ST_IN_MSG) {
        scb->state = SES_ST_IDLE;
    }

#ifdef MGR_RPC_DEBUG
    print_errors();
    clear_errors();
#endif

} /* mgr_rpc_dispatch */
Beispiel #18
0
/********************************************************************
* FUNCTION tstamp_convert_to_utctime
*
* Check if the specified string is a valid dateTime or 
* date-and-time string is valid and if so, convert it
* to 
*
* INPUTS:
*   buff == pointer to buffer to check
*   isNegative == address of return negative date flag
*   res == address of return status
*
* OUTPUTS:
*   *isNegative == TRUE if a negative dateTime string is given
*                  FALSE if no starting '-' sign found
*   *res == return status
*
* RETURNS:
*   malloced pointer to converted date time string
*   or NULL if some error
*********************************************************************/
xmlChar *
    tstamp_convert_to_utctime (const xmlChar *timestr,
                               boolean *isNegative,
                               status_t *res)
{
    assert(timestr && "timestr is NULL!");
    assert(isNegative && "isNegative is NULL!");
    assert(res && "res is NULL!");

    *res = NO_ERR;

    struct tm convertedtime;
    memset(&convertedtime, 0x0, sizeof(struct tm));

    if (*timestr == '-') {
        *isNegative = TRUE;
        timestr++;
    } else {
        *isNegative = FALSE;
    }

    xmlChar *buffer = NULL;
    const char *retptr = NULL;

    uint32 len = xml_strlen(timestr);
    if (len == 20) {
        /* could be in canonical form */
        retptr = strptime((const char *)timestr, "%FT%TZ", &convertedtime);
        if (retptr && *retptr == '\0') {
            buffer = xml_strdup(timestr);
            if (!buffer) {
                *res = ERR_INTERNAL_MEM;
                return NULL;
            } else {
                return buffer;
            }
        } else {
            *res = ERR_NCX_INVALID_VALUE;
            return NULL;
        }
    } else if (len > 20) {
        retptr = strptime((const char *)timestr, "%FT%T", &convertedtime);
        if (retptr == NULL || *retptr == '\0') {
            *res = ERR_NCX_INVALID_VALUE;
            return NULL;
        }

        /* check is frac-seconds entered, and skip it */
        if (*retptr == '.') {
            retptr++;
            if (!isdigit((int)*retptr)) {
                *res = ERR_NCX_INVALID_VALUE;
                return NULL;
            }

            retptr++;  /* got a start digit */
            while (isdigit((int)*retptr)) {
                retptr++;
            }
        }

        /* check if a timezone offset is present */
        retptr = strptime(retptr, "%z", &convertedtime);
        if (retptr == NULL) {
            *res = ERR_NCX_INVALID_VALUE;
            return NULL;
        }

        /* check where retptr ended up */
        if (*retptr == '\0') {
            /* OK read all the bytes */
            ;
        } else if (*retptr == ':') {
            if (strcmp(retptr, ":00")) {
                /* the linux strptime function does
                 * not process the 'time-minute' field in the
                 * time string; since this is so rare
                 * just treat as a special error
                 */
                *res = ERR_NCX_OPERATION_NOT_SUPPORTED;
                return NULL;
            } /* else time-minute field == '00' and no error */
        } else {
            *res = ERR_NCX_INVALID_VALUE;
            return NULL;
        }

        buffer = m__getMem(TSTAMP_MIN_SIZE);
        if (!buffer) {
            *res = ERR_INTERNAL_MEM;
            return NULL;
        }

        time_t utime = mktime(&convertedtime);
        if (utime == (utime)-1) {
            *res = ERR_NCX_INVALID_VALUE;
            m__free(buffer);
            return NULL;
        }

        struct tm *curtime = gmtime(&utime);
        time_to_string(curtime, buffer);
        return buffer;
    } else {
        /* improper length */
        *res = ERR_NCX_INVALID_VALUE;
        return NULL;
    }
    
} /* tstamp_convert_to_utctime */