コード例 #1
0
static const QoreStringNode* get_string_header_node(ExceptionSink* xsink, QoreHashNode& h, const char* header, bool allow_multiple = false) {
   AbstractQoreNode* n = h.getKeyValue(header);
   if (!n)
      return 0;

   qore_type_t t = get_node_type(n);
   if (t == NT_STRING)
      return reinterpret_cast<const QoreStringNode*>(n);
   assert(t == NT_LIST);
   if (!allow_multiple) {
      xsink->raiseException("HTTP-HEADER-ERROR", "multiple \"%s\" headers received in HTTP message", header);
      return 0;
   }
   // convert list to a comma-separated string
   QoreListNode* l = reinterpret_cast<QoreListNode*>(n);
   // get first list entry
   n = l->retrieve_entry(0);
   assert(get_node_type(n) == NT_STRING);
   QoreStringNode* rv = reinterpret_cast<QoreStringNode*>(n)->copy();
   for (size_t i = 1; i < l->size(); ++i) {
      n = l->retrieve_entry(i);
      assert(get_node_type(n) == NT_STRING);
      rv->concat(',');
      rv->concat(reinterpret_cast<QoreStringNode*>(n));
   }
   // dereference old list and save reference to return value in header hash
   h.setKeyValue(header, rv, xsink);
   return rv;
}
コード例 #2
0
const dtext * OCI_API OCI_ElemGetString2(OCI_Library *pOCILib, OCI_Elem *elem)
{
    const dtext *str  = NULL;
    boolean res       = FALSE;

    OCI_CHECK_PTR(pOCILib, OCI_IPC_ELEMENT, elem, NULL);

    if (elem->typinf->cols[0].type != OCI_CDT_TEXT) {
       QoreStringNode* desc = new QoreStringNode("cannot retrieve a text value for element '");
       if (elem->typinf->schema) {
	  desc->concat(elem->typinf->schema);
	  desc->concat('.');
       }
       desc->sprintf("%s' of type '%s'", elem->typinf->name, OCI_GetColumnTypeName(elem->typinf->cols[0].type));
       return FALSE;
    }
    
    if (elem->handle != NULL)
    {
        res = TRUE;

        str = (dtext *) OCI_StringFromStringPtr(pOCILib, (OCIString *) elem->handle,
                                                &elem->buf, &elem->buflen);
    }

    OCI_RESULT(pOCILib, res);

    return str;    
}
コード例 #3
0
void getQoreException(java::lang::Throwable *t, ExceptionSink &xsink) {
   //fprintf(stderr, "Unhandled Java exception %p:\n", t);

   //fprintf(stderr, "%s\n", str.getBuffer());

   QoreStringNode *desc = getJavaExceptionMessage(t);

   // get stack trace
   JArray<java::lang::StackTraceElement *> *stack = t->getStackTrace();
   
   java::lang::StackTraceElement **e = elements(stack);
   for (int i = 0; i < stack->length; ++i) {
      QoreString file, cls, meth;
      getQoreString(e[i]->getFileName(), file);
      getQoreString(e[i]->getClassName(), cls);
      getQoreString(e[i]->getMethodName(), meth);

      int line = e[i]->getLineNumber();

      desc->sprintf("\n  %s:%d: %s::%s() (%s)", file.getBuffer(), line > 0 ? line : 0, cls.getBuffer(), meth.getBuffer(), e[i]->isNativeMethod() ? "native" : "java");
   }

   while ((t = t->getCause())) {
      desc->concat("\ncaused by: ");
      SimpleRefHolder<QoreStringNode> ndesc(getJavaExceptionMessage(t));
      desc->concat(*ndesc, &xsink);
   }

   xsink.raiseException("JAVA-EXCEPTION", desc);
}
コード例 #4
0
ファイル: CallStack.cpp プロジェクト: temnoregg/qore
QoreHashNode* CallNode::getInfo() const {
   QoreHashNode* h = new QoreHashNode;
   // FIXME: add class name
   QoreStringNode *str = new QoreStringNode;
   if (obj) {
      str->concat(obj.getClass()->name.c_str());
      str->concat("::");
   }
   str->concat(func);

   h->setKeyValue("function", str, 0);
   h->setKeyValue("line",     new QoreBigIntNode(loc.start_line), 0);
   h->setKeyValue("endline",  new QoreBigIntNode(loc.end_line), 0);
   h->setKeyValue("file",     new QoreStringNode(loc.file), 0);
   h->setKeyValue("source",   loc.source ? new QoreStringNode(loc.source) : 0, 0);
   h->setKeyValue("offset",   new QoreBigIntNode(loc.offset), 0);
   h->setKeyValue("typecode", new QoreBigIntNode(type), 0);
   // CT_RETHROW is only aded manually
   switch (type) {
      case CT_USER:
	 h->setKeyValue("type",  new QoreStringNode("user"), 0);
	 break;
      case CT_BUILTIN:
	 h->setKeyValue("type",  new QoreStringNode("builtin"), 0);
	 break;
      case CT_NEWTHREAD:
	 h->setKeyValue("type",  new QoreStringNode("new-thread"), 0);
	 break;
   }
   return h;
}
コード例 #5
0
boolean OCI_API OCI_ElemSetString2(OCI_Library *pOCILib, OCI_Elem *elem, const dtext *value, ExceptionSink* xsink)
{
    boolean res  = TRUE;

    OCI_CHECK_PTR(pOCILib, OCI_IPC_ELEMENT, elem, FALSE);
    if (elem->typinf->cols[0].type != OCI_CDT_TEXT) {
       QoreStringNode* desc = new QoreStringNode("cannot bind a string value to element '");
       if (elem->typinf->schema) {
	  desc->concat(elem->typinf->schema);
	  desc->concat('.');
       }
       desc->sprintf("%s' of type '%s'", elem->typinf->name, OCI_GetColumnTypeName(elem->typinf->cols[0].type));
       return FALSE;
    }

    if (value == NULL)
    {
        res = OCI_ElemSetNull2(pOCILib, elem);
    }
    else
    {
        res = OCI_StringToStringPtr(pOCILib, (OCIString **) &elem->handle, 
                                    elem->con->err, (void *) value, 
                                    &elem->buf, &elem->buflen, xsink);

        OCI_ElemSetNullIndicator(elem, OCI_IND_NOTNULL);
    }

    OCI_RESULT(pOCILib, res);

    return res;
}
コード例 #6
0
ファイル: CallReferenceNode.cpp プロジェクト: temnoregg/qore
AbstractQoreNode* ParseObjectMethodReferenceNode::parseInitImpl(LocalVar* oflag, int pflag, int& lvids, const QoreTypeInfo*& typeInfo) {
   typeInfo = callReferenceTypeInfo;
   if (exp) {
      const QoreTypeInfo* argTypeInfo = 0;
      exp = exp->parseInit(oflag, pflag, lvids, argTypeInfo);

      if (argTypeInfo->hasType()) {
	 if (objectTypeInfo && argTypeInfo && !objectTypeInfo->parseAccepts(argTypeInfo)) {
	    // raise parse exception
	    QoreStringNode* desc = new QoreStringNode("invalid call; object expression gives ");
	    argTypeInfo->getThisType(*desc);
	    desc->concat(", but should resolve to an object to make a call with this syntax");
	    qore_program_private::makeParseException(getProgram(), "PARSE-TYPE-ERROR", desc);
	 }
	 else {
	    const QoreClass* n_qc = argTypeInfo->getUniqueReturnClass();
	    if (n_qc) {
	       bool m_priv = false;
	       m = qore_class_private::parseFindMethodTree(*const_cast<QoreClass*>(n_qc), method.c_str(), m_priv);
	       if (m) {
		  qc = n_qc;
		  if (m_priv && !qore_class_private::parseCheckPrivateClassAccess(*qc))
		     parseException("PARSE-ERROR", "method %s::%s() is private in this context, therefore a call reference cannot be taken", qc->getName(), method.c_str());
	       }
	       else
		  parseException("PARSE-ERROR", "method %s::%s() cannot be found", n_qc->getName(), method.c_str());
	    }
	 }
      }
   }
   return this;
}
コード例 #7
0
/* ------------------------------------------------------------------------ *
 * OCI_ElemSetLob
 * ------------------------------------------------------------------------ */
boolean OCI_API OCI_ElemSetLob2(OCI_Library *pOCILib, OCI_Elem *elem, OCI_Lob *value, ExceptionSink* xsink)
{
    boolean res  = TRUE;

    OCI_CHECK_PTR(pOCILib, OCI_IPC_ELEMENT, elem, FALSE);

    if (elem->typinf->cols[0].type != OCI_CDT_LOB) {
       QoreStringNode* desc = new QoreStringNode("cannot bind a lob value to element '");
       if (elem->typinf->schema) {
	  desc->concat(elem->typinf->schema);
	  desc->concat('.');
       }
       desc->sprintf("%s' of type '%s'", elem->typinf->name, OCI_GetColumnTypeName(elem->typinf->cols[0].type));
       return FALSE;
    }
  
    if (value == NULL)
    {
        res = OCI_ElemSetNull2(pOCILib, elem);
    }
    else
    {
        if (elem->obj == NULL)
        {
            OCI_LobInit(pOCILib, elem->con, (OCI_Lob **) &elem->obj,
                        (OCILobLocator *) elem->handle,
                        elem->typinf->cols[0].subtype, xsink);
        }

        if (elem->obj != NULL)
        {
	   res = OCI_LobAssign(pOCILib, (OCI_Lob *) elem->obj, value, xsink);

            if (res == TRUE)
            {
                OCI_ElemSetNullIndicator(elem, OCI_IND_NOTNULL);

                elem->handle = ((OCI_Lob *) elem->obj)->handle;
            }
        }
    }

    OCI_RESULT(pOCILib, res);

    return res;
}
コード例 #8
0
   // always generate a Host header pointing to the host hosting the resource, not the proxy
   // (RFC 2616 is not totally clear on this, but other clients do it this way)
   DLLLOCAL AbstractQoreNode* getHostHeaderValue() {
      if (connection.port == 80)
	 return new QoreStringNode(connection.host.c_str());

      QoreStringNode* str = new QoreStringNode;
      str->concat(connection.host);
      if (connection.port)
	 str->sprintf(":%d", connection.port);
      return str;
   }
コード例 #9
0
ファイル: RegexSubstNode.cpp プロジェクト: qorelanguage/qore
// called directly for run-time evaluation
QoreStringNode *RegexSubstNode::exec(const QoreString *target, const QoreString *nstr, ExceptionSink *xsink) const {
   TempEncodingHelper t(target, QCS_UTF8, xsink);
   if (*xsink)
      return 0;

   QoreStringNode *tstr = new QoreStringNode;
   
   const char *ptr = t->getBuffer();
   //printd(5, "RegexSubstNode::exec(%s) this=%p: global=%s\n", ptr, this, global ? "true" : "false"); 
   while (true) {
      int ovector[SUBST_OVECSIZE];
      int offset = ptr - t->getBuffer();
      if ((unsigned)offset >= t->size())
         break;
      int rc = pcre_exec(p, 0, t->getBuffer(), t->strlen(), offset, 0, ovector, SUBST_OVECSIZE);

      //printd(5, "RegexSubstNode::exec() prec_exec() rc: %d\n", rc);
      // FIXME: rc = 0 means that not enough space was available in ovector!
      if (rc < 1)
	 break;
      
      if (ovector[0] > offset)
	 tstr->concat(ptr, ovector[0] - offset);
      
      concat(tstr, ovector, SUBST_LASTELEM, nstr->getBuffer(), t->getBuffer(), rc);
      
      //printd(5, "RegexSubstNode::exec() '%s' =~ s/?/%s/%s offset=%d, 0=%d, 1=%d ('%s')\n", t->getBuffer(), nstr->getBuffer(), global ? "g" : "", offset, ovector[0], ovector[1], tstr->getBuffer());
      
      ptr = t->getBuffer() + ovector[1];
      
      if (!global)
	 break;
   } 
   
   //printd(5, "RegexSubstNode::exec() *ptr=%d ('%s') tstr='%s'\n", *ptr, ptr, tstr->getBuffer());
   if (*ptr)
      tstr->concat(ptr);
   
   //printd(5, "RegexSubstNode::exec() this=%p: returning '%s'\n", this, tstr->getBuffer());
   return tstr;
}
コード例 #10
0
ファイル: StatementBlock.cpp プロジェクト: temnoregg/qore
void StatementBlock::parseCheckReturn() {
   const QoreTypeInfo* returnTypeInfo = getReturnTypeInfo();
   if (returnTypeInfo->hasType() && !returnTypeInfo->parseAccepts(nothingTypeInfo)) {
      // make sure the last statement is a return statement if the block has a return type
      if (statement_list.empty() || !(*statement_list.last())->hasFinalReturn()) {
	 QoreStringNode* desc = new QoreStringNode("this code block has declared return type ");
	 returnTypeInfo->getThisType(*desc);
	 desc->concat(" but does not have a return statement as the last statement in the block");
	 qore_program_private::makeParseException(getProgram(), loc, "MISSING-RETURN", desc);
      }
   }
}
コード例 #11
0
ファイル: RegexTransNode.cpp プロジェクト: qorelanguage/qore
QoreStringNode *RegexTransNode::exec(const QoreString *str, ExceptionSink *xsink) const {
   //printd(5, "source='%s' target='%s' ('%s')\n", source->getBuffer(), target->getBuffer(), str->getBuffer());
   TempEncodingHelper tstr(str, QCS_DEFAULT, xsink);
   if (*xsink)
      return 0;

   QoreStringNode *ns = new QoreStringNode;
   for (qore_size_t i = 0; i < tstr->strlen(); i++) {
      char c = tstr->getBuffer()[i];
      const char *p = strchr(source->getBuffer(), c);
      if (p) {
	 qore_size_t pos = p - source->getBuffer();
	 if (target->strlen() <= pos)
	    pos = target->strlen() - 1;
	 ns->concat(target->getBuffer()[pos]);
      }
      else
	 ns->concat(c);
   }

   return ns;
}
コード例 #12
0
OCI_Object * OCI_API OCI_ElemGetObject2(OCI_Library * pOCILib, OCI_Elem *elem, ExceptionSink* xsink)
{
    boolean res = TRUE;
    OCI_Object *obj = NULL;

    OCI_CHECK_PTR(pOCILib, OCI_IPC_ELEMENT, elem, NULL);

    if (elem->typinf->cols[0].type != OCI_CDT_OBJECT) {
       QoreStringNode* desc = new QoreStringNode("cannot retrieve an object value from element '");
       if (elem->typinf->schema) {
	  desc->concat(elem->typinf->schema);
	  desc->concat('.');
       }
       desc->sprintf("%s' of type '%s'", elem->typinf->name, OCI_GetColumnTypeName(elem->typinf->cols[0].type));
       return FALSE;
    }

    if (elem->ind != OCI_IND_NULL)
    {
        if (elem->init == FALSE)
        {
            obj = OCI_ObjectInit(pOCILib, elem->con, (OCI_Object **) &elem->obj,
                                 elem->handle, 
                                 elem->typinf->cols[0].typinf,
                                 NULL, -1, TRUE, xsink);

            elem->init = (obj != NULL);
        }
        else
            obj = (OCI_Object *) elem->obj;

        res = elem->init;
    }

    OCI_RESULT(pOCILib, res);

    return obj;
}
コード例 #13
0
boolean OCI_ElemSetNumberFromString(OCI_Library* pOCILib, OCI_Elem* elem, const char* str, int size, ExceptionSink* xsink) {
    boolean res = FALSE;

    OCI_CHECK_PTR(pOCILib, OCI_IPC_ELEMENT, elem, FALSE);
    if (elem->typinf->cols[0].type != OCI_CDT_NUMERIC) {
       QoreStringNode* desc = new QoreStringNode("cannot bind a numeric value to element '");
       if (elem->typinf->schema) {
	  desc->concat(elem->typinf->schema);
	  desc->concat('.');
       }
       desc->sprintf("%s' of type '%s'", elem->typinf->name, OCI_GetColumnTypeName(elem->typinf->cols[0].type));
       return FALSE;
    }

    res = OCI_NumberConvertStr2(pOCILib, elem->con, (OCINumber*)elem->handle, str, size, NUM_FMT, NUM_FMT_LEN, xsink);

    if (res)
       OCI_ElemSetNullIndicator(elem, OCI_IND_NOTNULL);

    OCI_RESULT(pOCILib, res);

    return res;
}
コード例 #14
0
OCI_Coll * OCI_API OCI_ElemGetColl2(OCI_Library *pOCILib, OCI_Elem *elem, ExceptionSink* xsink)
{
    boolean res    = TRUE;
    OCI_Coll *coll = NULL;

    OCI_CHECK_PTR(pOCILib, OCI_IPC_ELEMENT, elem, NULL);

    if (elem->typinf->cols[0].type != OCI_CDT_COLLECTION) {
       QoreStringNode* desc = new QoreStringNode("cannot retrieve a collection from element '");
       if (elem->typinf->schema) {
	  desc->concat(elem->typinf->schema);
	  desc->concat('.');
       }
       desc->sprintf("%s' of type '%s'", elem->typinf->name, OCI_GetColumnTypeName(elem->typinf->cols[0].type));
       return FALSE;
    }

    if (elem->ind != OCI_IND_NULL)
    {
        if (elem->init == FALSE)
        {
            coll = OCI_CollInit(pOCILib, elem->con, (OCI_Coll **) &elem->obj, 
                                (OCIColl *) elem->handle, 
                                elem->typinf->cols[0].typinf, xsink);

            elem->init = (coll != NULL);
        }
        else
            coll = (OCI_Coll *) elem->obj;

        res = elem->init;
    }

    OCI_RESULT(pOCILib, res);

    return coll;
}
コード例 #15
0
OCI_Interval * OCI_API OCI_ElemGetInterval2(OCI_Library *pOCILib, OCI_Elem *elem)
{
    boolean res = TRUE;
    OCI_Interval *itv = NULL;

    OCI_CHECK_PTR(pOCILib, OCI_IPC_ELEMENT, elem, NULL);

    if (elem->typinf->cols[0].type != OCI_CDT_INTERVAL) {
       QoreStringNode* desc = new QoreStringNode("cannot retrieve an interval value for element '");
       if (elem->typinf->schema) {
	  desc->concat(elem->typinf->schema);
	  desc->concat('.');
       }
       desc->sprintf("%s' of type '%s'", elem->typinf->name, OCI_GetColumnTypeName(elem->typinf->cols[0].type));
       return FALSE;
    }

    if (elem->ind != OCI_IND_NULL)
    {
        if (elem->init == FALSE)
        {
            itv = OCI_IntervalInit(pOCILib, elem->con, (OCI_Interval **) &elem->obj, 
                                    (OCIInterval *) elem->handle,
                                    elem->typinf->cols[0].subtype);

            elem->init = (itv != NULL);
        }
        else
            itv = (OCI_Interval *) elem->obj;

        res = elem->init;
    }

    OCI_RESULT(pOCILib, res);

    return itv;
}
コード例 #16
0
OCI_Timestamp * OCI_API  OCI_ElemGetTimestamp2(OCI_Library *pOCILib, OCI_Elem *elem)
{
    boolean res = TRUE;
    OCI_Timestamp *tmsp = NULL;

    OCI_CHECK_PTR(pOCILib, OCI_IPC_ELEMENT, elem, NULL);

    if (elem->typinf->cols[0].type != OCI_CDT_TIMESTAMP) {
       QoreStringNode* desc = new QoreStringNode("cannot retrieve a timestamp value for element '");
       if (elem->typinf->schema) {
	  desc->concat(elem->typinf->schema);
	  desc->concat('.');
       }
       desc->sprintf("%s' of type '%s'", elem->typinf->name, OCI_GetColumnTypeName(elem->typinf->cols[0].type));
       return FALSE;
    }

    if (elem->ind != OCI_IND_NULL)
    {
        if (elem->init == FALSE)
        {
            tmsp = OCI_TimestampInit(pOCILib, elem->con, (OCI_Timestamp **) &elem->obj, 
                                     (OCIDateTime *) elem->handle, 
                                     elem->typinf->cols[0].subtype);

            elem->init = (tmsp != NULL);
        }
        else
            tmsp = (OCI_Timestamp *) elem->obj;

        res = elem->init;
    }

    OCI_RESULT(pOCILib, res);

    return tmsp;
}
コード例 #17
0
OCI_Date * OCI_API  OCI_ElemGetDate2(OCI_Library *pOCILib, OCI_Elem *elem)
{
    boolean res    = TRUE;
    OCI_Date *date = NULL;

    OCI_CHECK_PTR(pOCILib, OCI_IPC_ELEMENT, elem, NULL);

    if (elem->typinf->cols[0].type != OCI_CDT_DATETIME) {
       QoreStringNode* desc = new QoreStringNode("cannot retrieve a datetime value for element '");
       if (elem->typinf->schema) {
	  desc->concat(elem->typinf->schema);
	  desc->concat('.');
       }
       desc->sprintf("%s' of type '%s'", elem->typinf->name, OCI_GetColumnTypeName(elem->typinf->cols[0].type));
       return FALSE;
    }
    
    if (elem->ind != OCI_IND_NULL)
    {
        if (elem->init == FALSE)
        {
            date = OCI_DateInit2(pOCILib, elem->con, (OCI_Date **) &elem->obj, 
                                (OCIDate *) elem->handle, FALSE, FALSE);

            elem->init = (date != NULL);
        }
        else
            date = (OCI_Date *) elem->obj;

        res = elem->init;
    }

    OCI_RESULT(pOCILib, res);

    return date;
}
コード例 #18
0
OCI_Lob * OCI_API OCI_ElemGetLob2(OCI_Library *pOCILib, OCI_Elem *elem, ExceptionSink* xsink)
{
    boolean res  = TRUE;
    OCI_Lob *lob = NULL;

    OCI_CHECK_PTR(pOCILib, OCI_IPC_ELEMENT, elem, NULL);
    if (elem->typinf->cols[0].type != OCI_CDT_LOB) {
       QoreStringNode* desc = new QoreStringNode("cannot retrieve a LOB value from element '");
       if (elem->typinf->schema) {
	  desc->concat(elem->typinf->schema);
	  desc->concat('.');
       }
       desc->sprintf("%s' of type '%s'", elem->typinf->name, OCI_GetColumnTypeName(elem->typinf->cols[0].type));
       return FALSE;
    }

    if (elem->ind != OCI_IND_NULL)
    {      
        if (elem->init == FALSE)
        {
            lob = OCI_LobInit(pOCILib, elem->con, (OCI_Lob **) &elem->obj, 
                              (OCILobLocator *) elem->handle,
                              elem->typinf->cols[0].subtype, xsink);

            elem->init = (lob != NULL);
        }
        else
            lob = (OCI_Lob *) elem->obj;

        res = elem->init;
    }

    OCI_RESULT(pOCILib, res);

    return lob;
}
コード例 #19
0
QoreStringNode *getJavaExceptionMessage(java::lang::Throwable *t) {
   //printd(0, "getJavaExceptionMessage() t=%p\n", t);

   QoreStringNode *desc = new QoreStringNode;

   // get exception class name
   getQoreString(t->getClass()->getName(), *desc);

   java::lang::String *jstr = t->getMessage();
   if (jstr) {
      desc->concat(", message: ");
      appendQoreString(jstr, *desc);
   }

   return desc;
}
コード例 #20
0
ファイル: CallReferenceNode.cpp プロジェクト: temnoregg/qore
AbstractQoreNode* CallReferenceCallNode::parseInitImpl(LocalVar* oflag, int pflag, int& lvids, const QoreTypeInfo*& typeInfo) {
   // call references calls can return any value
   typeInfo = 0;

   pflag &= ~(PF_RETURN_VALUE_IGNORED);

   const QoreTypeInfo* expTypeInfo = 0;
   if (exp) {
      exp = exp->parseInit(oflag, pflag, lvids, expTypeInfo);

      if (expTypeInfo && codeTypeInfo && expTypeInfo->hasType() && !codeTypeInfo->parseAccepts(expTypeInfo)) {
	 // raise parse exception
	 QoreStringNode* desc = new QoreStringNode("invalid call; expression gives ");
	 expTypeInfo->getThisType(*desc);
	 desc->concat(", but a call reference or closure is required to make a call");
	 qore_program_private::makeParseException(getProgram(), "PARSE-TYPE-ERROR", desc);
      }
   }

   if (args) {
      bool needs_eval = args->needs_eval();

      // turn off PF_RETURN_VALUE_IGNORED
      pflag &= ~PF_RETURN_VALUE_IGNORED;
      
      ListIterator li(args);
      while (li.next()) {
	 AbstractQoreNode** n = li.getValuePtr();
	 if (*n) {
	    const QoreTypeInfo* argTypeInfo = 0;
	    (*n) = (*n)->parseInit(oflag, pflag, lvids, argTypeInfo);
	    
	    if (!needs_eval && (*n)->needs_eval()) {
	       args->setNeedsEval();
	       needs_eval = true;
	    }
	 }
      }
   }
   
   return this;
}
コード例 #21
0
ファイル: QoreException.cpp プロジェクト: temnoregg/qore
// static function
QoreHashNode *QoreException::getStackHash(int type, const char *class_name, const char *code, const QoreProgramLocation& loc) {
   QoreHashNode *h = new QoreHashNode;

   QoreStringNode *str = new QoreStringNode;
   if (class_name)
      str->sprintf("%s::", class_name);
   str->concat(code);

   //printd(5, "QoreException::getStackHash() %s at %s:%d-%d src: %s+%d\n", str->getBuffer(), loc.file ? loc.file : "n/a", loc.start_line, loc.end_line, loc.source ? loc.source : "n/a", loc.offset);
   
   h->setKeyValue("function", str, 0);
   h->setKeyValue("line",     new QoreBigIntNode(loc.start_line), 0);
   h->setKeyValue("endline",  new QoreBigIntNode(loc.end_line), 0);
   h->setKeyValue("file",     loc.file ? new QoreStringNode(loc.file) : 0, 0);
   h->setKeyValue("source",   loc.source ? new QoreStringNode(loc.source) : 0, 0);
   h->setKeyValue("offset",   new QoreBigIntNode(loc.offset), 0);
   h->setKeyValue("typecode", new QoreBigIntNode(type), 0);
   const char *tstr = 0;
   switch (type) {
      case CT_USER:
	 tstr = "user";
         break;
      case CT_BUILTIN:
	 tstr = "builtin";
         break;
      case CT_RETHROW:
	 tstr = "rethrow";
         break;
/*
      case CT_NEWTHREAD:
	 tstr = "new-thread";
         break;
*/
      default:
	 assert(false);
   }
   h->setKeyValue("type",  new QoreStringNode(tstr), 0);
   return h;
}
コード例 #22
0
ファイル: Datasource.cpp プロジェクト: temnoregg/qore
QoreStringNode* Datasource::getConfigString() const {
   QoreStringNode* str = new QoreStringNode(priv->dsl->getName());
   str->concat(':');

   if (!priv->username.empty())
      str->concat(priv->username);
   if (!priv->password.empty())
      str->sprintf("/%s", priv->password.c_str());
   if (!priv->dbname.empty())
      str->sprintf("@%s", priv->dbname.c_str());
   if (!priv->db_encoding.empty())
      str->sprintf("(%s)", priv->db_encoding.c_str());
   if (!priv->hostname.empty())
      str->sprintf("%%%s", priv->hostname.c_str());
   if (priv->port)
      str->sprintf(":%d", priv->port);

   bool first = false;
   ReferenceHolder<QoreHashNode> opts(qore_dbi_private::get(*priv->dsl)->getOptionHash(this), 0);
   ConstHashIterator hi(*opts);
   while (hi.next()) {
      const QoreHashNode* ov = reinterpret_cast<const QoreHashNode*>(hi.getValue());
      const AbstractQoreNode* v = ov->getKeyValue("value");
      if (!v || v == &False)
	 continue;

      if (first)
	 str->concat(',');
      else {
	 str->concat('{');
	 first = true;
      }
      str->concat(hi.getKey());
      if (v == &True)
	 continue;

      QoreStringValueHelper sv(v);
      str->sprintf("=%s", sv->getBuffer());
   }
   if (first)
      str->concat('}');

   return str;
}
コード例 #23
0
AbstractQoreNode* QoreAssignmentOperatorNode::parseInitImpl(LocalVar* oflag, int pflag, int& lvids, const QoreTypeInfo*& typeInfo) {
   // turn off "reference ok" and "return value ignored" flags
   pflag &= ~(PF_RETURN_VALUE_IGNORED);

   left = left->parseInit(oflag, pflag | PF_FOR_ASSIGNMENT, lvids, ti);
   //printd(5, "QoreAssignmentOperatorNode::parseInitImpl() this: %p left: %p '%s' nt: %d ti: %p '%s'\n", this, left, get_type_name(left), get_node_type(left), ti, ti->getName());
   checkLValue(left, pflag);

   // return type info is the same as the lvalue's typeinfo
   typeInfo = ti;

   const QoreTypeInfo* r = 0;
   right = right->parseInit(oflag, pflag, lvids, r);

   // check for illegal assignment to $self
   if (oflag)
      check_self_assignment(left, oflag);

   //printd(5, "QoreAssignmentOperatorNode::parseInitImpl() this: %p left: %s ti: %p '%s', right: %s ti: %s\n", this, get_type_name(left), ti, ti->getName(), get_type_name(right), r->getName());

   if (ti->hasType() && r->hasType() && !ti->parseAccepts(r)) {
      if (getProgram()->getParseExceptionSink()) {
	 QoreStringNode *edesc = new QoreStringNode("lvalue for assignment operator (=) expects ");
	 ti->getThisType(*edesc);
	 edesc->concat(", but right-hand side is ");
	 r->getThisType(*edesc);
	 qore_program_private::makeParseException(getProgram(), loc, "PARSE-TYPE-ERROR", edesc);
      }
   }

   // replace this node with optimized operator implementations, if possible
   if (ti == bigIntTypeInfo || ti == softBigIntTypeInfo)
      return makeSpecialization<QoreIntAssignmentOperatorNode>();

   return this;
}
コード例 #24
0
QoreHashNode* qore_httpclient_priv::send_internal(ExceptionSink* xsink, const char* mname, const char* meth, const char* mpath, const QoreHashNode* headers, const void* data, unsigned size, const ResolvedCallReferenceNode* send_callback, bool getbody, QoreHashNode* info, int timeout_ms, const ResolvedCallReferenceNode* recv_callback, QoreObject* obj) {
   assert(!(data && send_callback));

   // check if method is valid
   method_map_t::const_iterator i = method_map.find(meth);
   if (i == method_map.end()) {
       i = additional_methods_map.find(meth);
       if (i == additional_methods_map.end()) {
          xsink->raiseException("HTTP-CLIENT-METHOD-ERROR", "HTTP method (%s) not recognized.", meth);
          return 0;
       }
   }

   // make sure the capitalized version is used
   meth = i->first.c_str();
   bool bodyp = i->second;

   // use the default timeout value if a zero value is given in the call
   if (!timeout_ms)
      timeout_ms = timeout;

   SafeLocker sl(msock->m);
   Queue* cb_queue = msock->socket->getQueue();

   ReferenceHolder<QoreHashNode> nh(new QoreHashNode, xsink);
   bool keep_alive = true;

   bool transfer_encoding = false;

   if (headers) {
      ConstHashIterator hi(headers);
      while (hi.next()) {
	 // if one of the mandatory headers is found, then ignore it
	 strcase_set_t::iterator si = header_ignore.find(hi.getKey());
	 if (si != header_ignore.end())
	    continue;

	 // otherwise set the value in the hash
	 const AbstractQoreNode* n = hi.getValue();
	 if (!is_nothing(n)) {
	    if (!strcasecmp(hi.getKey(), "transfer-encoding"))
	       transfer_encoding = true;

	    nh->setKeyValue(hi.getKey(), n->refSelf(), xsink);

	    if (!strcasecmp(hi.getKey(), "connection") || (proxy_connection.has_url() && !strcasecmp(hi.getKey(), "proxy-connection"))) {
	       const char* conn = get_string_header(xsink, **nh, hi.getKey(), true);
	       if (*xsink) {
		  disconnect_unlocked();
		  return 0;
	       }
	       if (conn && !strcasecmp(conn, "close"))
		  keep_alive = false;
	    }
	 }
      }
   }

   // add default headers if they weren't overridden
   for (header_map_t::const_iterator hdri = default_headers.begin(), e = default_headers.end(); hdri != e; ++hdri) {
      // look in original headers to see if the key was already given
      if (headers) {
	 bool skip = false;
	 ConstHashIterator hi(headers);
	 while (hi.next()) {
	    if (!strcasecmp(hi.getKey(), hdri->first.c_str())) {
	       skip = true;
	       break;
	    }
	 }
	 if (skip)
	    continue;
      }
      // if there is no message body then do not send the "content-type" header
      if (!data && !send_callback && !strcmp(hdri->first.c_str(), "Content-Type"))
	 continue;
      nh->setKeyValue(hdri->first.c_str(), new QoreStringNode(hdri->second.c_str()), xsink);
   }

   // set Transfer-Encoding: chunked if used with a send callback
   if (send_callback && !transfer_encoding)
      nh->setKeyValue("Transfer-Encoding", new QoreStringNode("chunked"), xsink);

   if (!connection.username.empty()) {
      // check for "Authorization" header
      bool auth_found = false;
      if (headers) {
	 ConstHashIterator hi(headers);
	 while (hi.next()) {
	    if (!strcasecmp(hi.getKey(), "Authorization")) {
	       auth_found = true;
	       break;
	    }
	 }
      }

      if (!auth_found) {
	 QoreString tmp;
	 tmp.sprintf("%s:%s", connection.username.c_str(), connection.password.c_str());
	 QoreStringNode* auth_str = new QoreStringNode("Basic ");
	 auth_str->concatBase64(&tmp);
	 nh->setKeyValue("Authorization", auth_str, xsink);
      }
   }

   // save original HTTP method in case we have to issue a CONNECT request to a proxy for an HTTPS connection
   const char* meth_orig = meth;

   bool use_proxy_connect = false;
   const char* proxy_path = 0;
   ReferenceHolder<QoreHashNode> proxy_headers(xsink);
   QoreString hostport;
   if (!proxy_connected && proxy_connection.has_url()) {
      // use CONNECT if we need to make an HTTPS connection from the proxy
      if (!proxy_connection.ssl && connection.ssl) {
	 meth = "CONNECT";
	 use_proxy_connect = true;
	 hostport.concat(connection.host);
	 if (connection.port)
	    hostport.sprintf(":%d", connection.port);
	 proxy_path = hostport.getBuffer();
	 proxy_headers = new QoreHashNode;
	 proxy_headers->setKeyValue("Host", new QoreStringNode(hostport), xsink);

	 addProxyAuthorization(headers, **proxy_headers, xsink);
      }
      else
	 addProxyAuthorization(headers, **nh, xsink);
   }

   bool host_override = headers ? (bool)headers->getKeyValue("Host") : false;

   int code;
   ReferenceHolder<QoreHashNode> ans(xsink);
   int redirect_count = 0;
   const char* location = 0;

   // flag for aborted chunked sends
   bool send_aborted = false;

   while (true) {
      // set host field automatically if not overridden
      if (!host_override)
	 nh->setKeyValue("Host", getHostHeaderValue(), xsink);

      if (info) {
	 info->setKeyValue("headers", nh->copy(), xsink);
	 if (*xsink)
	    return 0;
      }

      //printd(5, "qore_httpclient_priv::send_internal() meth=%s proxy_path=%s mpath=%s upc=%d\n", meth, proxy_path ? proxy_path : "n/a", mpath, use_proxy_connect);
      // send HTTP message and get response header
      if (use_proxy_connect)
	 ans = sendMessageAndGetResponse(meth, proxy_path, *(*proxy_headers), 0, 0, 0, info, true, timeout_ms, code, send_aborted, xsink);
      else
	 ans = sendMessageAndGetResponse(meth, mpath, *(*nh), data, size, send_callback, info, false, timeout_ms, code, send_aborted, xsink);
      if (!ans)
	 return 0;

      if (info) {
	 info->setKeyValue("response-headers", ans->refSelf(), xsink);
	 if (*xsink)
	    return 0;
      }

      if (code >= 300 && code < 400) {
	 disconnect_unlocked();

	 host_override = false;
	 const QoreStringNode* mess = reinterpret_cast<QoreStringNode*>(ans->getKeyValue("status_message"));

	 const QoreStringNode* loc = get_string_header_node(xsink, **ans, "location");
	 if (*xsink)
	    return 0;
	 const char* location = loc && !loc->empty() ? loc->getBuffer() : 0;
	 if (!location) {
	    sl.unlock();
	    const char* msg = mess ? mess->getBuffer() : "<no message>";
	    xsink->raiseException("HTTP-CLIENT-REDIRECT-ERROR", "no redirect location given for status code %d: message: '%s'", code, msg);
	    return 0;
	 }

	 if (cb_queue)
	    do_redirect_event(cb_queue, msock->socket->getObjectIDForEvents(), loc, mess);

	 if (++redirect_count > max_redirects)
	    break;

	 if (set_url_unlocked(location, xsink)) {
	    sl.unlock();
	    const char* msg = mess ? mess->getBuffer() : "<no message>";
	    xsink->raiseException("HTTP-CLIENT-REDIRECT-ERROR", "exception occurred while setting URL for new location '%s' (code %d: message: '%s')", location, code, msg);
	    return 0;
	 }

	 // set redirect info in info hash if present
	 if (info) {
	    QoreString tmp;
	    tmp.sprintf("redirect-%d", redirect_count);
	    info->setKeyValue(tmp.getBuffer(), loc->refSelf(), xsink);
	    if (*xsink)
	       return 0;

	    tmp.clear();
	    tmp.sprintf("redirect-message-%d", redirect_count);
	    info->setKeyValue(tmp.getBuffer(), mess ? mess->refSelf() : 0, xsink);
	 }

	 // FIXME: reset send callback and send_aborted here

	 // set mpath to NULL so that the new path will be taken
	 mpath = 0;
	 continue;
      }
      else if (use_proxy_connect) {
	 meth = meth_orig;
	 use_proxy_connect = false;
	 proxy_path = 0;
	 if (msock->socket->upgradeClientToSSL(0, 0, xsink)) {
	    disconnect_unlocked();
	    return 0;
	 }
	 proxy_connected = true;

	 // remove "Proxy-Authorization" header
	 nh->removeKey("Proxy-Authorization", xsink);
	 if (*xsink)
	    return 0;

	 // try again as if we are talking directly to the client
	 continue;
      }

      break;
   }

   if (code >= 300 && code < 400) {
      sl.unlock();
      const char* mess = get_string_header(xsink, **ans, "status_message");
      if (!mess)
	 mess = "<no message>";
      if (!location)
	 location = "<no location>";
      xsink->raiseException("HTTP-CLIENT-MAXIMUM-REDIRECTS-EXCEEDED", "maximum redirections (%d) exceeded; redirect code %d to '%s' ignored (message: '%s')", max_redirects, code, location, mess);
      return 0;
   }

   // process content-type
   const QoreStringNode* v = get_string_header_node(xsink, **ans, "content-type");
   if (*xsink) {
      disconnect_unlocked();
      return 0;
   }
   //ans->getKeyValue("content-type");   

   // see if there is a character set specification in the content-type header
   if (v) {
      // save original content-type header before processing
      ans->setKeyValue("_qore_orig_content_type", v->refSelf(), xsink);

      const char* str = v->getBuffer();
      const char* p = strstr(str, "charset=");
      if (p && (p == str || *(p - 1) == ';' || *(p - 1) == ' ')) {
	 // move p to start of encoding
	 const char* c = p + 8;
	 char quote = '\0';
	 if (*c == '\'' || *c == '"') {
	    quote = *c;
	    ++c;
	 }
	 QoreString enc;
	 while (*c && *c != ';' && *c != ' ' && *c != quote)
	    enc.concat(*(c++));
	 
	 if (quote && *c == quote)
	    ++c;

	 printd(5, "QoreHttpClientObject::send_intern() setting encoding to '%s' from content-type header: '%s' (cs=%p c=%p %d)\n", enc.getBuffer(), str, p + 8, c);

	 // set new encoding
	 msock->socket->setEncoding(QEM.findCreate(&enc));
	 // strip from content-type
	 QoreStringNode* nc = new QoreStringNode();
	 // skip any spaces before the charset=
	 while (p != str && (*(p - 1) == ' ' || *(p - 1) == ';'))
	    p--;
	 if (p != str)
	    nc->concat(str, p - str);
	 if (*c)
	    nc->concat(c);
	 ans->setKeyValue("content-type", nc, xsink);
	 str = nc->getBuffer();
      }
      // split into a list if ";" characters are present
      p = strchr(str, ';');
      if (p) {
	 bool multipart = false;
	 QoreListNode* l = new QoreListNode();
	 do {
	    // skip whitespace
	    while (*str == ' ') str++;
	    if (str != p) {
	       int len = p - str;
	       check_headers(str, len, multipart, *(*ans), msock->socket->getEncoding(), xsink);
	       l->push(new QoreStringNode(str, len, msock->socket->getEncoding()));
	    }
	    str = p + 1;
	 } while ((p = strchr(str, ';')));
	 // skip whitespace
	 while (*str == ' ') str++;
	 // add last field
	 if (*str) {
	    check_headers(str, strlen(str), multipart, *(*ans), msock->socket->getEncoding(), xsink);
	    l->push(new QoreStringNode(str, msock->socket->getEncoding()));
	 }
	 ans->setKeyValue("content-type", l, xsink);
      }
   }

   // send headers to recv_callback
   if (recv_callback && msock->socket->priv->runHeaderCallback(xsink, mname, *recv_callback, &msock->m, *ans, send_aborted, obj))
      return 0;

   AbstractQoreNode* body = 0;
   const char* content_encoding = 0;

   // do not read any message body for messages that cannot have one
   // rfc 2616 4.4 p1 (http://tools.ietf.org/html/rfc2616#section-4.4)
   /*
     1.Any response message which "MUST NOT" include a message-body (such
     as the 1xx, 204, and 304 responses and any response to a HEAD
     request) is always terminated by the first empty line after the
     header fields, regardless of the entity-header fields present in
     the message.
    */
   //printd(5, "qore_httpclient_priv::send_internal() this: %p bodyp: %d code: %d\n", this, bodyp, code);

   qore_uncompress_to_string_t dec = 0;

   // code >= 300 && < 400 is already handled above
   if (bodyp && (code < 100 || code >= 200) && code != 204) {
      // see if we should do a binary or string read
      content_encoding = get_string_header(xsink, **ans, "content-encoding");
      if (*xsink) {
	 disconnect_unlocked();
	 return 0;
      }

      if (content_encoding) {
	 // check for misuse (? not sure: check RFCs again) of this field by including a character encoding value
	 if (!strncasecmp(content_encoding, "iso", 3) || !strncasecmp(content_encoding, "utf-", 4)) {
	    msock->socket->setEncoding(QEM.findCreate(content_encoding));
	    content_encoding = 0;
	 }
	 else if (!recv_callback) {
	    // only decode message bodies automatically if there is no receive callback
	    if (!strcasecmp(content_encoding, "deflate") || !strcasecmp(content_encoding, "x-deflate"))
	       dec = qore_inflate_to_string;
	    else if (!strcasecmp(content_encoding, "gzip") || !strcasecmp(content_encoding, "x-gzip"))
	       dec = qore_gunzip_to_string;
	    else if (!strcasecmp(content_encoding, "bzip2") || !strcasecmp(content_encoding, "x-bzip2"))
	       dec = qore_bunzip2_to_string;
	 }
      }

      const char* te = get_string_header(xsink, **ans, "transfer-encoding");
      if (*xsink) {
	 disconnect_unlocked();
	 return 0;
      }
   
      // get response body, if any
      const char* cl = get_string_header(xsink, **ans, "content-length");
      if (*xsink) {
	 disconnect_unlocked();
	 return 0;
      }
      int len = cl ? atoi(cl) : 0;
      
      if (cl && cb_queue)
	 do_content_length_event(cb_queue, msock->socket->getObjectIDForEvents(), len);

      if (te && !strcasecmp(te, "chunked")) { // check for chunked response body
	 if (cb_queue)
	    do_event(cb_queue, msock->socket->getObjectIDForEvents(), QORE_EVENT_HTTP_CHUNKED_START);
	 ReferenceHolder<QoreHashNode> nah(xsink);
	 if (recv_callback) {
	    if (content_encoding)
	       msock->socket->priv->readHttpChunkedBodyBinary(timeout_ms, xsink, QORE_SOURCE_HTTPCLIENT, recv_callback, &msock->m, obj);
	    else
	       msock->socket->priv->readHttpChunkedBody(timeout_ms, xsink, QORE_SOURCE_HTTPCLIENT, recv_callback, &msock->m, obj);
	 }
	 else {
	    if (content_encoding)
	       nah = msock->socket->priv->readHttpChunkedBodyBinary(timeout_ms, xsink, QORE_SOURCE_HTTPCLIENT);
	    else
	       nah = msock->socket->priv->readHttpChunkedBody(timeout_ms, xsink, QORE_SOURCE_HTTPCLIENT);
	 }
	 if (cb_queue)
	    do_event(cb_queue, msock->socket->getObjectIDForEvents(), QORE_EVENT_HTTP_CHUNKED_END);
	 
	 if (!nah && !recv_callback) {
	    if (!msock->socket->isOpen())
	       disconnect_unlocked();
	    return 0;
	 }

	 if (info) {
	    info->setKeyValue("chunked", &True, xsink);
	    if (*xsink)
	       return 0;
	 }
	 
	 if (!recv_callback) {
	    body = nah->takeKeyValue("body");
	    ans->merge(*nah, xsink);
	 }
      }
      else if (getbody || len) {
	 if (content_encoding) {
	    SimpleRefHolder<BinaryNode> bobj(msock->socket->recvBinary(len, timeout_ms, xsink));
	    if (!(*xsink) && bobj)
	       body = bobj.release();
	 }
	 else {
	    QoreStringNodeHolder bstr(msock->socket->recv(len, timeout_ms, xsink));
	    if (!(*xsink) && bstr)
	       body = bstr.release();
	 }
	 
	 if (*xsink && !msock->socket->isOpen())
	    disconnect_unlocked();
	 //printf("body=%p\n", body);
      }  
   }

   // check for connection: close header
   if (!keep_alive)
      disconnect_unlocked();
   else {
      const char* conn = get_string_header(xsink, **ans, "connection", true);
      if (*xsink) {
	 disconnect_unlocked();
	 return 0;
      }
      if (conn && !strcasecmp(conn, "close"))
	 disconnect_unlocked();
   }

   sl.unlock();

   // for content-encoding processing we can run unlocked

   // add body to result hash and process content encoding if necessary
   if (body) {
      if (content_encoding) {
	 if (!dec) {
	    if (!recv_callback) {
	       xsink->raiseException("HTTP-CLIENT-RECEIVE-ERROR", "don't know how to handle content-encoding '%s'", content_encoding);
	       ans = 0;
	    }
	 }
	 else {
	    BinaryNode* bobj = reinterpret_cast<BinaryNode*>(body);
	    QoreStringNode* str = dec(bobj, msock->socket->getEncoding(), xsink);
	    bobj->deref();
	    body = str;
	 }
      }

      if (body) {
	 // send data to recv_callback (already unlocked)
	 if (recv_callback) {
	    ReferenceHolder<> bh(body, xsink);
	    if (msock->socket->priv->runDataCallback(xsink, mname, *recv_callback, 0, body, false)
		|| msock->socket->priv->runHeaderCallback(xsink, mname, *recv_callback, 0, 0, send_aborted, obj))
	       return 0;
	 }
	 else
	    ans->setKeyValue("body", body, xsink);
      }
   }

   // do not throw an exception if a receive callback is used
   if (!recv_callback && !*xsink && (code < 100 || code >= 300)) {
      const char* mess = get_string_header(xsink, **ans, "status_message");
      if (!mess)
	 mess = "<no message>";
      assert(!*xsink);

      xsink->raiseExceptionArg("HTTP-CLIENT-RECEIVE-ERROR", ans.release(), "HTTP status code %d received: message: %s", code, mess);
      return 0;
   }

   return *xsink || recv_callback ? 0 : ans.release();
}
コード例 #25
0
static QoreStringNode *ssh2_module_init() {
   qore_libssh2_version = libssh2_version(LIBSSH2_VERSION_NUM);
   if (!qore_libssh2_version) {
      QoreStringNode *err = new QoreStringNode("the runtime version of the library is too old; got '%s', expecting minimum version '");
      err->concat(LIBSSH2_VERSION);
      err->concat('\'');
      return err;
   }

   // setup ssh2 error map
   ssh2_emap.insert(emap_t::value_type(LIBSSH2_ERROR_SOCKET_NONE, "LIBSSH2_ERROR_SOCKET_NONE"));
#ifdef LIBSSH2_ERROR_BANNER_RECV
   ssh2_emap.insert(emap_t::value_type(LIBSSH2_ERROR_BANNER_RECV, "LIBSSH2_ERROR_BANNER_RECV"));
#endif
   ssh2_emap.insert(emap_t::value_type(LIBSSH2_ERROR_BANNER_SEND, "LIBSSH2_ERROR_BANNER_SEND"));
   ssh2_emap.insert(emap_t::value_type(LIBSSH2_ERROR_INVALID_MAC, "LIBSSH2_ERROR_INVALID_MAC"));
   ssh2_emap.insert(emap_t::value_type(LIBSSH2_ERROR_KEX_FAILURE, "LIBSSH2_ERROR_KEX_FAILURE"));
   ssh2_emap.insert(emap_t::value_type(LIBSSH2_ERROR_ALLOC, "LIBSSH2_ERROR_ALLOC"));
   ssh2_emap.insert(emap_t::value_type(LIBSSH2_ERROR_SOCKET_SEND, "LIBSSH2_ERROR_SOCKET_SEND"));
   ssh2_emap.insert(emap_t::value_type(LIBSSH2_ERROR_KEY_EXCHANGE_FAILURE, "LIBSSH2_ERROR_KEY_EXCHANGE_FAILURE"));
   ssh2_emap.insert(emap_t::value_type(LIBSSH2_ERROR_TIMEOUT, "LIBSSH2_ERROR_TIMEOUT"));
   ssh2_emap.insert(emap_t::value_type(LIBSSH2_ERROR_HOSTKEY_INIT, "LIBSSH2_ERROR_HOSTKEY_INIT"));
   ssh2_emap.insert(emap_t::value_type(LIBSSH2_ERROR_HOSTKEY_SIGN, "LIBSSH2_ERROR_HOSTKEY_SIGN"));
   ssh2_emap.insert(emap_t::value_type(LIBSSH2_ERROR_DECRYPT, "LIBSSH2_ERROR_DECRYPT"));
   ssh2_emap.insert(emap_t::value_type(LIBSSH2_ERROR_SOCKET_DISCONNECT, "LIBSSH2_ERROR_SOCKET_DISCONNECT"));
   ssh2_emap.insert(emap_t::value_type(LIBSSH2_ERROR_PROTO, "LIBSSH2_ERROR_PROTO"));
   ssh2_emap.insert(emap_t::value_type(LIBSSH2_ERROR_PASSWORD_EXPIRED, "LIBSSH2_ERROR_PASSWORD_EXPIRED"));
   ssh2_emap.insert(emap_t::value_type(LIBSSH2_ERROR_FILE, "LIBSSH2_ERROR_FILE"));
   ssh2_emap.insert(emap_t::value_type(LIBSSH2_ERROR_METHOD_NONE, "LIBSSH2_ERROR_METHOD_NONE"));
#ifdef LIBSSH2_ERROR_AUTHENTICATION_FAILED
   ssh2_emap.insert(emap_t::value_type(LIBSSH2_ERROR_AUTHENTICATION_FAILED, "LIBSSH2_ERROR_AUTHENTICATION_FAILED"));
#endif
   ssh2_emap.insert(emap_t::value_type(LIBSSH2_ERROR_PUBLICKEY_UNRECOGNIZED, "LIBSSH2_ERROR_PUBLICKEY_UNRECOGNIZED"));
   ssh2_emap.insert(emap_t::value_type(LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED, "LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED"));
   ssh2_emap.insert(emap_t::value_type(LIBSSH2_ERROR_CHANNEL_OUTOFORDER, "LIBSSH2_ERROR_CHANNEL_OUTOFORDER"));
   ssh2_emap.insert(emap_t::value_type(LIBSSH2_ERROR_CHANNEL_FAILURE, "LIBSSH2_ERROR_CHANNEL_FAILURE"));
   ssh2_emap.insert(emap_t::value_type(LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED, "LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED"));
   ssh2_emap.insert(emap_t::value_type(LIBSSH2_ERROR_CHANNEL_UNKNOWN, "LIBSSH2_ERROR_CHANNEL_UNKNOWN"));
   ssh2_emap.insert(emap_t::value_type(LIBSSH2_ERROR_CHANNEL_WINDOW_EXCEEDED, "LIBSSH2_ERROR_CHANNEL_WINDOW_EXCEEDED"));
   ssh2_emap.insert(emap_t::value_type(LIBSSH2_ERROR_CHANNEL_PACKET_EXCEEDED, "LIBSSH2_ERROR_CHANNEL_PACKET_EXCEEDED"));
   ssh2_emap.insert(emap_t::value_type(LIBSSH2_ERROR_CHANNEL_CLOSED, "LIBSSH2_ERROR_CHANNEL_CLOSED"));
   ssh2_emap.insert(emap_t::value_type(LIBSSH2_ERROR_CHANNEL_EOF_SENT, "LIBSSH2_ERROR_CHANNEL_EOF_SENT"));
   ssh2_emap.insert(emap_t::value_type(LIBSSH2_ERROR_SCP_PROTOCOL, "LIBSSH2_ERROR_SCP_PROTOCOL"));
   ssh2_emap.insert(emap_t::value_type(LIBSSH2_ERROR_ZLIB, "LIBSSH2_ERROR_ZLIB"));
   ssh2_emap.insert(emap_t::value_type(LIBSSH2_ERROR_SOCKET_TIMEOUT, "LIBSSH2_ERROR_SOCKET_TIMEOUT"));
   ssh2_emap.insert(emap_t::value_type(LIBSSH2_ERROR_SFTP_PROTOCOL, "LIBSSH2_ERROR_SFTP_PROTOCOL"));
   ssh2_emap.insert(emap_t::value_type(LIBSSH2_ERROR_REQUEST_DENIED, "LIBSSH2_ERROR_REQUEST_DENIED"));
   ssh2_emap.insert(emap_t::value_type(LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, "LIBSSH2_ERROR_METHOD_NOT_SUPPORTED"));
   ssh2_emap.insert(emap_t::value_type(LIBSSH2_ERROR_INVAL, "LIBSSH2_ERROR_INVAL"));
   ssh2_emap.insert(emap_t::value_type(LIBSSH2_ERROR_INVALID_POLL_TYPE, "LIBSSH2_ERROR_INVALID_POLL_TYPE"));
   ssh2_emap.insert(emap_t::value_type(LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, "LIBSSH2_ERROR_PUBLICKEY_PROTOCOL"));
   ssh2_emap.insert(emap_t::value_type(LIBSSH2_ERROR_EAGAIN, "LIBSSH2_ERROR_EAGAIN"));
   ssh2_emap.insert(emap_t::value_type(LIBSSH2_ERROR_BUFFER_TOO_SMALL, "LIBSSH2_ERROR_BUFFER_TOO_SMALL"));
   ssh2_emap.insert(emap_t::value_type(LIBSSH2_ERROR_BAD_USE, "LIBSSH2_ERROR_BAD_USE"));
   ssh2_emap.insert(emap_t::value_type(LIBSSH2_ERROR_COMPRESS, "LIBSSH2_ERROR_COMPRESS"));
   ssh2_emap.insert(emap_t::value_type(LIBSSH2_ERROR_OUT_OF_BOUNDARY, "LIBSSH2_ERROR_OUT_OF_BOUNDARY"));
#ifdef LIBSSH2_ERROR_AGENT_PROTOCOL
   ssh2_emap.insert(emap_t::value_type(LIBSSH2_ERROR_AGENT_PROTOCOL, "LIBSSH2_ERROR_AGENT_PROTOCOL"));
#endif
#ifdef LIBSSH2_ERROR_SOCKET_RECV
   ssh2_emap.insert(emap_t::value_type(LIBSSH2_ERROR_SOCKET_RECV, "LIBSSH2_ERROR_SOCKET_RECV"));
#endif
#ifdef LIBSSH2_ERROR_ENCRYPT
   ssh2_emap.insert(emap_t::value_type(LIBSSH2_ERROR_ENCRYPT, "LIBSSH2_ERROR_ENCRYPT"));
#endif
#ifdef LIBSSH2_ERROR_BAD_SOCKET
   ssh2_emap.insert(emap_t::value_type(LIBSSH2_ERROR_BAD_SOCKET, "LIBSSH2_ERROR_BAD_SOCKET"));
#endif
#ifdef LIBSSH2_ERROR_KNOWN_HOSTS
   ssh2_emap.insert(emap_t::value_type(LIBSSH2_ERROR_KNOWN_HOSTS, "LIBSSH2_ERROR_KNOWN_HOSTS"));
#endif
   ssh2_emap.insert(emap_t::value_type(LIBSSH2_ERROR_BANNER_NONE, "LIBSSH2_ERROR_BANNER_NONE"));

   // setup sftp error map
   sftp_emap.insert(edmap_t::value_type(LIBSSH2_FX_OK, ErrDesc("LIBSSH2_FX_OK", "success")));
   sftp_emap.insert(edmap_t::value_type(LIBSSH2_FX_EOF, ErrDesc("LIBSSH2_FX_EOF", "EOF: end of file")));
   sftp_emap.insert(edmap_t::value_type(LIBSSH2_FX_NO_SUCH_FILE, ErrDesc("LIBSSH2_FX_NO_SUCH_FILE", "file does not exist")));
   sftp_emap.insert(edmap_t::value_type(LIBSSH2_FX_PERMISSION_DENIED, ErrDesc("LIBSSH2_FX_PERMISSION_DENIED", "permission denied")));
   sftp_emap.insert(edmap_t::value_type(LIBSSH2_FX_FAILURE, ErrDesc("LIBSSH2_FX_FAILURE", "command failed")));
   sftp_emap.insert(edmap_t::value_type(LIBSSH2_FX_BAD_MESSAGE, ErrDesc("LIBSSH2_FX_BAD_MESSAGE", "bad message")));
   sftp_emap.insert(edmap_t::value_type(LIBSSH2_FX_NO_CONNECTION, ErrDesc("LIBSSH2_FX_NO_CONNECTION", "no connection")));
   sftp_emap.insert(edmap_t::value_type(LIBSSH2_FX_CONNECTION_LOST, ErrDesc("LIBSSH2_FX_CONNECTION_LOST", "connection lost")));
   sftp_emap.insert(edmap_t::value_type(LIBSSH2_FX_OP_UNSUPPORTED, ErrDesc("LIBSSH2_FX_OP_UNSUPPORTED", "sshd sftp server does not support this operation")));
   sftp_emap.insert(edmap_t::value_type(LIBSSH2_FX_INVALID_HANDLE, ErrDesc("LIBSSH2_FX_INVALID_HANDLE", "invalid handle")));
   sftp_emap.insert(edmap_t::value_type(LIBSSH2_FX_NO_SUCH_PATH, ErrDesc("LIBSSH2_FX_NO_SUCH_PATH", "path does not exist")));
   sftp_emap.insert(edmap_t::value_type(LIBSSH2_FX_FILE_ALREADY_EXISTS, ErrDesc("LIBSSH2_FX_FILE_ALREADY_EXISTS", "file already exists")));
   sftp_emap.insert(edmap_t::value_type(LIBSSH2_FX_WRITE_PROTECT, ErrDesc("LIBSSH2_FX_WRITE_PROTECT", "write protected")));
   sftp_emap.insert(edmap_t::value_type(LIBSSH2_FX_NO_MEDIA, ErrDesc("LIBSSH2_FX_NO_MEDIA", "no media")));
   sftp_emap.insert(edmap_t::value_type(LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM, ErrDesc("LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM", "filesystem full")));
   sftp_emap.insert(edmap_t::value_type(LIBSSH2_FX_QUOTA_EXCEEDED, ErrDesc("LIBSSH2_FX_QUOTA_EXCEEDED", "quota exceeded")));
#ifdef LIBSSH2_FX_UNKNOWN_PRINCIPAL
   sftp_emap.insert(edmap_t::value_type(LIBSSH2_FX_UNKNOWN_PRINCIPAL, ErrDesc("LIBSSH2_FX_UNKNOWN_PRINCIPAL", "unknown principal")));
#else
   sftp_emap.insert(edmap_t::value_type(LIBSSH2_FX_UNKNOWN_PRINCIPLE, ErrDesc("LIBSSH2_FX_UNKNOWN_PRINCIPAL", "unknown principal")));
#endif
#ifdef LIBSSH2_FX_LOCK_CONFLICT
   sftp_emap.insert(edmap_t::value_type(LIBSSH2_FX_LOCK_CONFLICT, ErrDesc("LIBSSH2_FX_LOCK_CONFLICT", "lock conflict")));
#else
   sftp_emap.insert(edmap_t::value_type(LIBSSH2_FX_LOCK_CONFlICT, ErrDesc("LIBSSH2_FX_LOCK_CONFLICT", "lock conflict")));
#endif
   sftp_emap.insert(edmap_t::value_type(LIBSSH2_FX_DIR_NOT_EMPTY, ErrDesc("LIBSSH2_FX_DIR_NOT_EMPTY", "directory not empty")));
   sftp_emap.insert(edmap_t::value_type(LIBSSH2_FX_NOT_A_DIRECTORY, ErrDesc("LIBSSH2_FX_NOT_A_DIRECTORY", "not a directory")));
   sftp_emap.insert(edmap_t::value_type(LIBSSH2_FX_INVALID_FILENAME, ErrDesc("LIBSSH2_FX_INVALID_FILENAME", "invalid filename")));
   sftp_emap.insert(edmap_t::value_type(LIBSSH2_FX_LINK_LOOP, ErrDesc("LIBSSH2_FX_LINK_LOOP", "link loop")));

   // all classes belonging to here
   ssh2ns.addSystemClass(initSSH2BaseClass(ssh2ns));
   ssh2ns.addSystemClass(initSSH2ChannelClass(ssh2ns));
   ssh2ns.addSystemClass(initSSH2ClientClass(ssh2ns));
   ssh2ns.addSystemClass(initSFTPClientClass(ssh2ns));

   // constants
   ssh2ns.addConstant("Version", new QoreStringNode(qore_libssh2_version));

   return 0;
}