DLLLOCAL void addProxyAuthorization(const QoreHashNode* headers, QoreHashNode& h, ExceptionSink* xsink) {
      if (proxy_connection.username.empty())
	 return;

      AbstractQoreNode* pauth = 0;
      // check for "Proxy-Authorization" header
      if (headers) {
	 ConstHashIterator hi(headers);
	 while (hi.next()) {
	    if (!strcasecmp(hi.getKey(), "Proxy-Authorization")) {
	       pauth = hi.getReferencedValue();
	       h.setKeyValue("Proxy-Authorization", pauth, xsink);
	       assert(!*xsink);
	       break;
	    }
	 }
      }

      if (!pauth) {
	 QoreString tmp;
	 tmp.sprintf("%s:%s", proxy_connection.username.c_str(), proxy_connection.password.c_str());
	 QoreStringNode* auth_str = new QoreStringNode("Basic ");
	 auth_str->concatBase64(&tmp);
	 h.setKeyValue("Proxy-Authorization", auth_str, xsink);
	 assert(!*xsink);
      }
   }
Beispiel #2
0
QoreHashNode* ConstantList::getInfo() {
   QoreHashNode* h = new QoreHashNode;

   for (cnemap_t::iterator i = cnemap.begin(), e = cnemap.end(); i != e; ++i)
      h->setKeyValue(i->first, i->second->node->refSelf(), 0);

   return h;
}
Beispiel #3
0
QoreHashNode* ParseOptionMaps::getStringToCodeMap() const {
   QoreHashNode* h = new QoreHashNode;

   for (pormap_t::const_iterator i = pormap.begin(), e = pormap.end(); i != e; ++i) {
      h->setKeyValue(i->first, new QoreBigIntNode(i->second), 0);
   }

   return h;
}
void do_event(Queue *cb_queue, int64 id, int event) {
   if (cb_queue) {
      ExceptionSink xsink;
      QoreHashNode* h = new QoreHashNode;
      h->setKeyValue("event", new QoreBigIntNode(event), 0);
      h->setKeyValue("source", new QoreBigIntNode(QORE_SOURCE_HTTPCLIENT), 0);
      h->setKeyValue("id", new QoreBigIntNode(id), 0);
      cb_queue->pushAndTakeRef(h);
   }
}
void do_content_length_event(Queue *cb_queue, int64 id, int len) {
   if (cb_queue) {
      ExceptionSink xsink;
      QoreHashNode* h = new QoreHashNode;
      h->setKeyValue("event", new QoreBigIntNode(QORE_EVENT_HTTP_CONTENT_LENGTH), 0);
      h->setKeyValue("source", new QoreBigIntNode(QORE_SOURCE_HTTPCLIENT), 0);
      h->setKeyValue("id", new QoreBigIntNode(id), 0);
      h->setKeyValue("len", new QoreBigIntNode(len), 0);
      cb_queue->pushAndTakeRef(h);
   }
}
Beispiel #6
0
QoreHashNode* ParseOptionMaps::getCodeToStringMap() const {
   QoreHashNode* h = new QoreHashNode;
   
   QoreString key;
   for (pomap_t::const_iterator i = pomap.begin(), e = pomap.end(); i != e; ++i) {
      key.clear();
      key.sprintf(QLLD, i->first);
      h->setKeyValue(key.c_str(), new QoreStringNode(i->second), 0);
   }
   
   return h;
}
void check_headers(const char* str, int len, bool &multipart, QoreHashNode& ans, const QoreEncoding *enc, ExceptionSink* xsink) {
   // see if the string starts with "multipart/"
   if (!multipart) {
      if (len > 10 && !strncasecmp(str, "multipart/", 10)) {
	 ans.setKeyValue("_qore_multipart", new QoreStringNode(str + 10, len - 10, enc), xsink);
	 multipart = true;
      }
   }
   else {
      if (len > 9 && !strncasecmp(str, "boundary=", 9))
	 ans.setKeyValue("_qore_multipart_boundary", new QoreStringNode(str + 9, len - 9, enc), xsink);
      else if (len > 6 && !strncasecmp(str, "start=", 6))
	 ans.setKeyValue("_qore_multipart_start", new QoreStringNode(str + 6, len - 6, enc), xsink);
   }
}
Beispiel #8
0
   // destructive
   DLLLOCAL QoreHashNode* getHash() {
      QoreHashNode* h = new QoreHashNode;
      if (protocol) {
	 h->setKeyValue("protocol", protocol, 0);
	 protocol = 0;
      }
      if (path) {
	 h->setKeyValue("path", path, 0);
	 path = 0;
      }
      if (username) {
	 h->setKeyValue("username", username, 0);
	 username = 0;
      }
      if (password) {
	 h->setKeyValue("password", password, 0);
	 password = 0;
      }
      if (host) {
	 h->setKeyValue("host", host, 0);
	 host = 0;
      }
      if (port)
	 h->setKeyValue("port", new QoreBigIntNode(port), 0);
   
      return h;
   }
Beispiel #9
0
// 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;
}
Beispiel #10
0
QoreHashNode* Datasource::getConfigHash() const {
   QoreHashNode* h = new QoreHashNode;

   h->setKeyValue("type", new QoreStringNode(priv->dsl->getName()), 0);
   if (!priv->username.empty())
      h->setKeyValue("user", new QoreStringNode(priv->username), 0);
   if (!priv->password.empty())
      h->setKeyValue("pass", new QoreStringNode(priv->password), 0);
   if (!priv->dbname.empty())
      h->setKeyValue("db", new QoreStringNode(priv->dbname), 0);
   if (!priv->db_encoding.empty())
      h->setKeyValue("charset", new QoreStringNode(priv->db_encoding), 0);
   if (!priv->hostname.empty())
      h->setKeyValue("host", new QoreStringNode(priv->hostname), 0);
   if (priv->port)
      h->setKeyValue("port", new QoreBigIntNode(priv->port), 0);

   QoreHashNode* options = priv->getCurrentOptionHash();
   if (options)
      h->setKeyValue("options", options, 0);

   return h;
}
void do_redirect_event(Queue *cb_queue, int64 id, const QoreStringNode* loc, const QoreStringNode* msg) {
   if (cb_queue) {
      ExceptionSink xsink;
      QoreHashNode* h = new QoreHashNode;
      h->setKeyValue("event", new QoreBigIntNode(QORE_EVENT_HTTP_REDIRECT), 0);
      h->setKeyValue("source", new QoreBigIntNode(QORE_SOURCE_HTTPCLIENT), 0);
      h->setKeyValue("id", new QoreBigIntNode(id), 0);
      h->setKeyValue("location", loc->refSelf(), 0);
      if (msg)
	 h->setKeyValue("status_message", msg->refSelf(), 0);
      cb_queue->pushAndTakeRef(h);
   }
}
AbstractQoreNode* QoreXmlReader::getXmlData(ExceptionSink* xsink, const QoreEncoding* data_ccsid, int pflags, int min_depth) {
   xml_stack xstack;

   QORE_TRACE("getXMLData()");
   int rc = 1;

   while (rc == 1) {
      int nt = nodeTypeSkipWhitespace();
      // get node name
      const char* name = constName();
      if (!name)
	 name = "--";

      if (nt == -1) // ERROR
	 break;

      if (nt == XML_READER_TYPE_ELEMENT) {
	 int depth = QoreXmlReader::depth();
	 xstack.checkDepth(depth);

	 AbstractQoreNode* n = xstack.getNode();
	 // if there is no node pointer, then make a hash
	 if (!n) {
	    QoreHashNode* h = new QoreHashNode;
	    xstack.setNode(h);
	    xstack.push(h->getKeyValuePtr(name), depth);
	 }
	 else { // node ptr already exists
	    QoreHashNode* h = n->getType() == NT_HASH ? reinterpret_cast<QoreHashNode*>(n) : 0;
	    if (!h) {
	       h = new QoreHashNode;
	       xstack.setNode(h);
	       h->setKeyValue("^value^", n, 0);
	       xstack.incValueCount();
	       xstack.push(h->getKeyValuePtr(name), depth);
	    }
	    else {
	       // see if key already exists
	       AbstractQoreNode* v;
	       bool exists;
	       v = h->getKeyValueExistence(name, exists);

	       if (!exists)
		  xstack.push(h->getKeyValuePtr(name), depth);
	       else {
		  if (!(pflags & XPF_PRESERVE_ORDER)) {
		     QoreListNode* vl = get_node_type(v) == NT_LIST ? reinterpret_cast<QoreListNode*>(v) : 0;
		     // if it's not a list, then make into a list with current value as first entry
		     if (!vl) {
			AbstractQoreNode** vp = h->getKeyValuePtr(name);
			vl = new QoreListNode;
			vl->push(v);
			(*vp) = vl;
		     }
		     xstack.push(vl->get_entry_ptr(vl->size()), depth);
		  }
		  else {
		     // see if last key was the same, if so make a list if it's not
		     const char* lk = h->getLastKey();
		     bool get_value = false;
		     if (keys_are_equal(name, lk, get_value)) {
			// get actual key value if there was a suffix
			if (get_value)
			   v = h->getKeyValue(lk);

			QoreListNode* vl = get_node_type(v) == NT_LIST ? reinterpret_cast<QoreListNode*>(v) : 0;
			// if it's not a list, then make into a list with current value as first entry
			if (!vl) {
			   AbstractQoreNode** vp = h->getKeyValuePtr(lk);
			   vl = new QoreListNode;
			   vl->push(v);
			   (*vp) = vl;
			}
			xstack.push(vl->get_entry_ptr(vl->size()), depth);
		     }
		     else {
			QoreString ns;
			int c = 1;
			while (true) {
			   ns.sprintf("%s^%d", name, c);
			   if (!h->existsKey(ns.getBuffer()))
			      break;
			   c++;
			   ns.clear();
			}
			xstack.push(h->getKeyValuePtr(ns.getBuffer()), depth);
		     }
		  }
	       }
	    }
	 }
	 // add attributes to structure if possible
	 if (hasAttributes()) {
	    ReferenceHolder<QoreHashNode> h(new QoreHashNode, xsink);
	    while (moveToNextAttribute(xsink) == 1) {
	       const char* aname = constName();
	       QoreStringNode* value = getValue(data_ccsid, xsink);
	       if (!value)
		  return 0;
	       h->setKeyValue(aname, value, xsink);
	    }
	    if (*xsink)
	       return 0;

	    // make new new a hash and assign "^attributes^" key
	    QoreHashNode* nv = new QoreHashNode;
	    nv->setKeyValue("^attributes^", h.release(), xsink);
	    xstack.setNode(nv);
	 }
	 //printd(5, "%s: type: %d, hasValue: %d, empty: %d, depth: %d\n", name, nt, xmlTextReaderHasValue(reader), xmlTextReaderIsEmptyElement(reader), depth);
      }
      else if (nt == XML_READER_TYPE_TEXT) {
	 int depth = QoreXmlReader::depth();
	 xstack.checkDepth(depth);

	 const char* str = constValue();
	 if (str) {
            QoreStringNodeHolder val(getValue(data_ccsid, xsink));
	    if (!val)
	       return 0;

	    AbstractQoreNode* n = xstack.getNode();
	    if (n) {
	       QoreHashNode* h = n->getType() == NT_HASH ? reinterpret_cast<QoreHashNode*>(n) : 0;
	       if (h) {
		  if (!xstack.getValueCount())
		     h->setKeyValue("^value^", val.release(), xsink);
		  else {
		     QoreString kstr;
		     kstr.sprintf("^value%d^", xstack.getValueCount());
		     h->setKeyValue(kstr.getBuffer(), val.release(), xsink);
		  }
	       }
	       else { // convert value to hash and save value node
		  h = new QoreHashNode;
		  xstack.setNode(h);
		  h->setKeyValue("^value^", n, 0);
		  xstack.incValueCount();

		  QoreString kstr;
		  kstr.sprintf("^value%d^", 1);
		  h->setKeyValue(kstr.getBuffer(), val.release(), xsink);
	       }
	       xstack.incValueCount();
	    }
	    else
	       xstack.setNode(val.release());
	 }
      }
      else if (nt == XML_READER_TYPE_CDATA) {
	 int depth = QoreXmlReader::depth();
	 xstack.checkDepth(depth);

	 const char* str = constValue();
	 if (str) {
	    QoreStringNode* val = getValue(data_ccsid, xsink);
	    if (!val)
	       return 0;

	    AbstractQoreNode* n = xstack.getNode();
	    if (n && n->getType() == NT_HASH) {
	       QoreHashNode* h = reinterpret_cast<QoreHashNode*>(n);
	       if (!xstack.getCDataCount())
		  h->setKeyValue("^cdata^", val, xsink);
	       else {
		  QoreString kstr;
		  kstr.sprintf("^cdata%d^", xstack.getCDataCount());
		  h->setKeyValue(kstr.getBuffer(), val, xsink);
	       }
	    }
	    else { // convert value to hash and save value node
	       QoreHashNode* h = new QoreHashNode;
	       xstack.setNode(h);
	       if (n) {
		  h->setKeyValue("^value^", n, 0);
		  xstack.incValueCount();
	       }

	       h->setKeyValue("^cdata^", val, xsink);
	    }
	    xstack.incCDataCount();
	 }
      }
      rc = read();

      if (min_depth > 0 && QoreXmlReader::depth() < min_depth) {
         rc = 0;
         break;
      }
   }
   return rc ? 0 : xstack.getVal();
}
Beispiel #13
0
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;
}
Beispiel #14
0
QoreHashNode *QoreException::makeExceptionObject() {
   QORE_TRACE("makeExceptionObject()");

   QoreHashNode *h = new QoreHashNode;

   h->setKeyValue("type", new QoreStringNode(type == ET_USER ? "User" : "System"), 0);
   h->setKeyValue("file", new QoreStringNode(file), 0);
   h->setKeyValue("line", new QoreBigIntNode(start_line), 0);
   h->setKeyValue("endline", new QoreBigIntNode(end_line), 0);
   h->setKeyValue("source", new QoreStringNode(source), 0);
   h->setKeyValue("offset", new QoreBigIntNode(offset), 0);
   h->setKeyValue("callstack", callStack->refSelf(), 0);

   if (err)
      h->setKeyValue("err", err->refSelf(), 0);
   if (desc)
      h->setKeyValue("desc", desc->refSelf(), 0);
   if (arg)
      h->setKeyValue("arg", arg->refSelf(), 0);

   // add chained exceptions with this "chain reaction" call
   if (next)
      h->setKeyValue("next", next->makeExceptionObject(), 0);

   return h;
}
Beispiel #15
0
// static member function
void ExceptionSink::defaultExceptionHandler(QoreException* e) {
   ExceptionSink xsink;

   QoreString nstr;
   {
      DateTime now;
      now.setNow();
      now.format(nstr, "YYYY-MM-DD HH:mm:SS.xx Dy Z (z)");
   }

   unsigned ecnt = 0;

   while (e) {
      //printd(5, "ExceptionSink::defaultExceptionHandler() cs size=%d\n", cs->size());
      printe("unhandled QORE %s exception thrown in TID %d at %s", e->type == ET_USER ? "User" : "System", gettid(), nstr.getBuffer());

      QoreListNode *cs = e->callStack;
      bool found = false;
      if (cs->size()) {
	 // find first non-rethrow element
	 unsigned i = 0;
	 
	 QoreHashNode *h;
	 while (true) {
	    h = reinterpret_cast<QoreHashNode *>(cs->retrieve_entry(i));
	    assert(h);	    
	    if ((reinterpret_cast<QoreBigIntNode *>(h->getKeyValue("typecode")))->val != CT_RETHROW)
	       break;
	    i++;
	    if (i == cs->size())
	       break;
	 }

	 if (i < cs->size()) {
	    found = true;
	    QoreStringNode *func = reinterpret_cast<QoreStringNode *>(h->getKeyValue("function"));
	    QoreStringNode *type = reinterpret_cast<QoreStringNode *>(h->getKeyValue("type"));

	    printe(" in %s() (%s:%d", func->getBuffer(), e->file.c_str(), e->start_line);

	    if (e->start_line == e->end_line) {
	       if (!e->source.empty())
	          printe(", source %s:%d", e->source.c_str(), e->start_line + e->offset);
	    }
	    else {
               printe("-%d", e->end_line);
	       if (!e->source.empty())
                  printe(", source %s:%d-%d", e->source.c_str(), e->start_line + e->offset, e->end_line + e->offset);
	    }
	    printe(", %s code)\n", type->getBuffer());
	 }
      }

      if (!found) {
	 if (!e->file.empty()) {
	    printe(" at %s:", e->file.c_str());
	    if (e->start_line == e->end_line) {
	       if (!e->start_line) {
		  printe("<init>");
		  if (!e->source.empty())
		     printe(" (source %s)", e->source.c_str());
	       }
	       else {
		  printe("%d", e->start_line);
                  if (!e->source.empty())
                     printe(" (source %s:%d)", e->source.c_str(), e->start_line + e->offset);
	       }
	    }
	    else {
	       printe("%d-%d", e->start_line, e->end_line);
               if (!e->source.empty())
                  printe(" (source %s:%d-%d)", e->source.c_str(), e->start_line + e->offset, e->end_line + e->offset);
	    }
	 }
	 else if (e->start_line) {
	    if (e->start_line == e->end_line) {
	       if (!e->start_line)
		  printe(" at <init>");
	       else
		  printe(" on line %d", e->start_line);
	    }
	    else
	       printe(" on lines %d through %d", e->start_line, e->end_line);
	 }
	 printe("\n");
      }
      
      if (e->type == ET_SYSTEM) {
	 QoreStringNode* err = reinterpret_cast<QoreStringNode *>(e->err);
	 QoreStringNode* desc = reinterpret_cast<QoreStringNode *>(e->desc);
	 printe("%s: %s\n", err->getBuffer(), desc->getBuffer());
      }
      else {
	 bool hdr = false;

	 if (e->err) {
	    if (e->err->getType() == NT_STRING) {
	       QoreStringNode *err = reinterpret_cast<QoreStringNode *>(e->err);
	       printe("%s", err->getBuffer());
	    }
	    else {
	       QoreNodeAsStringHelper str(e->err, FMT_NORMAL, &xsink);
	       printe("EXCEPTION: %s", str->getBuffer());
	       hdr = true;
	    }
	 }
	 else
	    printe("EXCEPTION");
	 
	 if (e->desc) {
	    if (e->desc->getType() == NT_STRING) {
	       QoreStringNode *desc = reinterpret_cast<QoreStringNode *>(e->desc);
	       printe("%s%s", hdr ? ", desc: " : ": ", desc->getBuffer());
	    }
	    else {
	       QoreNodeAsStringHelper str(e->desc, FMT_NORMAL, &xsink);
	       printe(", desc: %s", str->getBuffer());
	       hdr = true;
	    }
	 }
	 
	 if (e->arg) {
	    if (e->arg->getType() == NT_STRING) {
	       QoreStringNode *arg = reinterpret_cast<QoreStringNode *>(e->arg);
	       printe("%s%s", hdr ? ", arg: " : "", arg->getBuffer());
	    }
	    else {
	       QoreNodeAsStringHelper str (e->arg, FMT_NORMAL, &xsink);
	       printe(", arg: %s", str->getBuffer());
	    }
	 }
	 printe("\n");
      }

      if (cs->size()) {
	 printe("call stack:\n");
	 for (unsigned i = 0; i < cs->size(); i++) {
	    int pos = cs->size() - i;
	    QoreHashNode* h = reinterpret_cast<QoreHashNode*>(cs->retrieve_entry(i));
	    QoreStringNode* strtype = reinterpret_cast<QoreStringNode*>(h->getKeyValue("type"));
	    const char* type = strtype->getBuffer();
	    int typecode = (int)reinterpret_cast<QoreBigIntNode*>(h->getKeyValue("typecode"))->val;
	    if (!strcmp(type, "new-thread"))
	       printe(" %2d: *thread start*\n", pos);
	    else {
	       QoreStringNode* fn = reinterpret_cast<QoreStringNode*>(h->getKeyValue("file"));
	       const char* fns = fn && !fn->empty() ? fn->getBuffer() : 0;
	       int start_line = (int)reinterpret_cast<QoreBigIntNode*>(h->getKeyValue("line"))->val;
	       int end_line = (int)reinterpret_cast<QoreBigIntNode*>(h->getKeyValue("endline"))->val;

	       QoreStringNode* src = reinterpret_cast<QoreStringNode*>(h->getKeyValue("source"));
	       const char* srcs = src && !src->empty() ? src->getBuffer() : 0;
	       int offset = (int)reinterpret_cast<QoreBigIntNode*>(h->getKeyValue("offset"))->val;

	       printe(" %2d: ", pos);

	       if (typecode == CT_RETHROW) {
	          printe("RETHROW at ");
	          if (fn) {
	             printe("%s:", fn->getBuffer());
	          }
	          else
	             printe("line");
	          printe("%d", start_line);
                  if (srcs)
                     printe(" (source %s:%d)", srcs, offset + start_line);
	       }
	       else {
	          QoreStringNode* fs = reinterpret_cast<QoreStringNode *>(h->getKeyValue("function"));
		  printe("%s() (", fs->getBuffer());
		  if (fns) {
		     if (start_line == end_line) {
			if (!start_line)
			   printe("%s:<init>", fns);
			else {
                           printe("%s:%d", fns, start_line);
			   if (srcs)
			      printe(" (source %s:%d)", srcs, start_line + offset);
			}
		     }
		     else {
			printe("%s:%d-%d", fns, start_line, end_line);
                        if (srcs)
                           printe(" (source %s:%d-%d)", srcs, start_line + offset, end_line + offset);
		     }
		  }
		  else {
		     if (start_line == end_line) {
			if (!start_line)
			   printe("<init>");
			else
			   printe("line %d", start_line);
		     }
		     else
			printe("line %d - %d", start_line, end_line);
		  }
		  printe(", %s code)", type);
	       }
	       printe("\n");
	    }
	 }
      }
      e = e->next;
      if (e) {
	 ++ecnt;
	 if (ecnt == Q_MAX_EXCEPTIONS) {
	    printe("*** maximum exception count reached (%d); supressing further output\n", ecnt);
	    break;
	 }
	 printe("chained exception:\n");
      }
   }
}