Esempio n. 1
0
int FLDigiDoc::certRSAKeyValue(const QString &certfile, QByteArray &modResult,
                               QByteArray &expResult)
{
  int err = ERR_OK;
  unsigned char buf2[1024 * sizeof(unsigned char)], *buf1 = 0;
  unsigned char buf22[1024 * sizeof(unsigned char)], *buf11 = 0;
  int len2, len1;
  EVP_PKEY *pubKey;

  len1 = 512;
  buf1 = (unsigned char *) malloc(len1);
  memset(buf1, 0, len1);

  buf11 = (unsigned char *) malloc(len1);
  memset(buf11, 0, len1);

  err = ReadPublicKey(&pubKey, certfile.latin1());

  // FIXME
  // modulus
  len1 = BN_bn2bin(pubKey->pkey.rsa->n, buf1);
  // in version 1.1 we output modulus as it is
  // starting from 1.2 we convert it to big-endian
  //  len2 = sizeof(buf2);
  //  memset(buf2, 0, len2);
  //  encode(buf1, len1, buf2, &len2);
  //  printf("Old modulus: %s\n", buf2);
  //  if (!strcmp(pSigDoc->szFormatVer, DIGIDOC_XML_1_1_VER)) {
  //    swapBytes((byte *)buf1, len1);
  //  }
  len2 = sizeof(buf2);
  memset(buf2, 0, len2);
  encode(buf1, len1, buf2, &len2);
  modResult.duplicate((const char *)buf2, len2);

  // exponent
  memset(buf11, 0, len1);
  len1 = BN_bn2bin(pubKey->pkey.rsa->e, buf11);
  len2 = sizeof(buf22);
  memset(buf22, 0, len2);
  encode(buf11, len1, buf22, &len2);
  expResult.duplicate((const char *)buf22, len2);

  EVP_PKEY_free(pubKey);
  free(buf1);
  free(buf11);
  return err;
}
Esempio n. 2
0
void TESession::zmodemRcvBlock(const char *data, int len)
{
    QByteArray ba;
    ba.duplicate(data, len);
    zmodemProc->writeStdin(ba);
//  qWarning("--> %d bytes", len);
}
Esempio n. 3
0
QVariant
KexiBlobTableEdit::value()
{
	return d->value;
#if 0
	//todo
//	ok = true;

	if(m_content && m_content->isModified())
	{
		return QVariant(m_content->text());
	}
	QByteArray value;
	QFile f( m_tempFile->name() );
	f.open(IO_ReadOnly);
	QDataStream stream(&f);
	char* data = (char*) malloc(f.size());
	value.resize(f.size());
	stream.readRawBytes(data, f.size());
	value.duplicate(data, f.size());
	free(data);
	kdDebug() << "KexiBlobTableEdit: Size of BLOB: " << value.size() << endl;
	return QVariant(value);
#endif
}
Esempio n. 4
0
KLF_EXPORT QByteArray klfFmt(const char * fmt, va_list pp)
{
  static const int bufferSize = 8192;
  char buffer[bufferSize];
  int len;
#if defined(_BSD_SOURCE) || _XOPEN_SOURCE >= 500 || defined(_ISOC99_SOURCE)
  // stdio.h provided vsnprintf()
  len = vsnprintf(buffer, bufferSize, fmt, pp);
  if (len >= bufferSize) {
    // output was truncated
    qWarning("%s(): output from format string \"%s\" was truncated from %d to %d bytes.",
	     KLF_FUNC_NAME, fmt, len, (bufferSize-1));
    len = bufferSize-1;
  }
#else
  len = vsprintf(buffer, fmt, pp);
#endif

  if (len < 0) {
    qWarning("%s(): vs(n)printf() failed for format \"%s\"", KLF_FUNC_NAME, fmt);
    return QByteArray();
  }

  // create a QByteArray
  QByteArray data;
#ifdef KLFBACKEND_QT4
  data = QByteArray(buffer, len);
#else
  data.duplicate(buffer, len);
#endif
  return data;
}
Esempio n. 5
0
int FLDigiDoc::certSerialNumber(const QString &certfile, QByteArray &serialResult)
{
  int bLen = 512;
  char buf[bLen * sizeof(char)];
  int err = GetCertSerialNumber(buf, bLen, certfile.latin1());
  serialResult.duplicate((const char *) buf, bLen);
  return err;
}
Esempio n. 6
0
void XMLPreferences::setPrefUInt64(const QString& inName,
				   const QString& inSection,
				   uint64_t inValue,
				   Persistence pers)
{
  QByteArray ba;
  ba.duplicate((const char*)&inValue, sizeof(uint64_t));
  setPref(inName, inSection, ba, pers);
}
Esempio n. 7
0
unsigned KBufferedIO::feedWriteBuffer(unsigned nbytes, const char *buffer)
{
  if (nbytes == 0)
    return 0;

  QByteArray *a = new QByteArray(nbytes);
  a->duplicate(buffer, nbytes);
  outBuf.append(a);
  return nbytes;
}
Esempio n. 8
0
QVariant QMYSQLResult::data( int field )
{
    if ( !isSelect() || field >= (int) d->fieldTypes.count() ) {
	qWarning( "QMYSQLResult::data: column %d out of range", field );
	return QVariant();
    }
    
    QString val( d->row[field] );
    switch ( d->fieldTypes.at( field ) ) {
    case QVariant::LongLong:
	return QVariant( val.toLongLong() );
    case QVariant::ULongLong:
	return QVariant( val.toULongLong() );
    case QVariant::Int: 
	return QVariant( val.toInt() );
    case QVariant::UInt:
	return QVariant( val.toUInt() );
    case QVariant::Double:
	return QVariant( val.toDouble() );
    case QVariant::Date:
	if ( val.isEmpty() ) {
	    return QVariant( QDate() );
	} else {
	    return QVariant( QDate::fromString( val, Qt::ISODate )  );
	}
    case QVariant::Time:
	if ( val.isEmpty() ) {
	    return QVariant( QTime() );
	} else {
	    return QVariant( QTime::fromString( val, Qt::ISODate ) );
	}
    case QVariant::DateTime:
	if ( val.isEmpty() )
	    return QVariant( QDateTime() );
	if ( val.length() == 14u )
	    // TIMESTAMPS have the format yyyyMMddhhmmss
	    val.insert(4, "-").insert(7, "-").insert(10, 'T').insert(13, ':').insert(16, ':');
	return QVariant( QDateTime::fromString( val, Qt::ISODate ) );
    case QVariant::ByteArray: {
	unsigned long* fl = mysql_fetch_lengths( d->result );
	QByteArray ba;
	ba.duplicate( d->row[field], fl[field] );
	return QVariant( ba );
    }
    default:
    case QVariant::String:
    case QVariant::CString:
	return QVariant( val );
    }
#ifdef QT_CHECK_RANGE
    qWarning("QMYSQLResult::data: unknown data type");
#endif
    return QVariant();
}
Esempio n. 9
0
QByteArray sha1(const char *str, int size)
{
    unsigned char digest[20];
    SHA_CTX ctx;
    if (size < 0)
        size = strlen(str);
    SHA1_Init(&ctx);
    SHA1_Update(&ctx, str, size);
    SHA1_Final(digest, &ctx);
    QByteArray ba;
    ba.duplicate((char*)digest, sizeof(digest));
    return ba;
}
Esempio n. 10
0
QByteArray md5(const char *str, int size)
{
    MD5_CTX c;
    unsigned char md[MD5_DIGEST_LENGTH];
    if (size < 0)
        size = strlen(str);
    MD5_Init(&c);
    MD5_Update(&c, str, size);
    MD5_Final(md, &c);
    QByteArray ba;
    ba.duplicate((char*)md, sizeof(md));
    return ba;
}
Esempio n. 11
0
unsigned KBufferedIO::feedReadBuffer(unsigned nbytes, const char *buffer, bool atBeginning)
{
  if (nbytes == 0)
    return 0;

  QByteArray *a = new QByteArray(nbytes);
  a->duplicate(buffer, nbytes);

  if (atBeginning)
    inBuf.prepend(a);
  else
    inBuf.append(a);

  return nbytes;
}
Esempio n. 12
0
int FLDigiDoc::certDigest(const QString &certfile, QByteArray &digestResult)
{
  int err = ERR_OK, len1;
  char buf1[1024 * sizeof(char)];
  X509 *pCert = 0;
  DigiDocMemBuf mbuf;
  mbuf.pMem = 0;
  mbuf.nLen = 0;
  err = ReadCertificate(&pCert, certfile.latin1());
  if (!err && pCert) {
    len1 = sizeof(buf1);
    buf1[0] = 0;
    err = ddocCertGetDigest(pCert, &mbuf);
    encode((const byte *) mbuf.pMem, mbuf.nLen, (byte *) buf1, &len1);
    digestResult.duplicate((const char *) buf1, len1);
    ddocMemBuf_free(&mbuf);
  }
  if (pCert) {
    X509_free(pCert);
    pCert = 0;
  }
  return err;
}
Esempio n. 13
0
void cSpeech::talking(int s, QString speech) // PC speech
{
/*
	Unicode speech format
	byte = char, short = char[2], int = char[4], wchar = char[2] = unicode character

	Message Sent By Client:
	0xAD - Unicode Speech Request
	BYTE cmd(0xAD)
	short msgsize 1, 2
	byte type(0 = say, 2 = emote, 8 = whisper, 9 = yell) 3
	short color 4, 5
	short font 6, 7
	BYTE[4] lang(null terminated, "enu " for US english.) 8, 9, 10, 11
	wchar[?] text(null terminated, ?=(msgsize - 12)/2) 13
  
	Message Sent By Server:
	0xAE - Unicode Speech Message
	BYTE cmd(0xAE) 0
	short msgsize 1, 2
	BYTE[4] ser(ser of speaker, all 0xFF if none) 3, 4, 5, 6
	BYTE[2] model(id of speaker, all 0xFF if none)7, 8
	BYTE type 9
	short color 10, 11
	short font 12, 13
	BYTE[4] language(same as before) 14, 15, 16, 17
	BYTE[30] speaker's name(normal chars, not wchars) 18 - 48
	WCHAR[?] text(null terminated, ?=(msgsize - 48)/2

    Importnat note regarding 0xAD: since 2.0.7 clients send between lang and text 0...10 bytes. (we can ignore them safely)
	Those bytes get cut out in network.cpp correctly, so the buffer THIS functions sees is actualy what is written above.
    The actual data the client sends is differently though.
	Just noted this to prevent from debugging if somebody finds out client data doesn't fit to this description (LB) 

*/
	
	//char nonuni[512];
	unsigned char talk2[19];
	QByteArray unicodetext;
	char lang[4];
	char name[50] = {0,};	// it **IS** important to 0 out the remaining gaps
	
	P_CHAR pc_currchar = currchar[s];	
//	strcpy(nonuni, speech.latin1());

	// len+font+color+type = same postion for non unicode and unicode speech packets
	// but 8 ... x DIFFER a lot for unicode and non unicode packets !!!

	strncpy(name, pc_currchar->name.c_str(), 50);

	char speech_type       = buffer[s][3]; 
	UI16 speech_color	   = ShortFromCharPtr(&buffer[s][4]);
	char speech_fontbyte1  = buffer[s][6];
	char speech_fontbyte2  = buffer[s][7];

	int ucl = ( speech.length() * 2 ) + 2;
	int tl = ucl + 48 ;

	if (pc_currchar->unicode)
	{
		lang[0]=buffer[s][8];
		lang[1]=buffer[s][9];
		lang[2]=buffer[s][10];
		lang[3]=buffer[s][11];
		
		unicodetext.duplicate( (char*)&buffer[s][12], ucl );
	}
	else
	{
		lang[0]='E';
		lang[1]='N';
		lang[2]='U';
		lang[3]=0;
		
		char2wchar(speech.latin1());		// we are sending unicode response no matter if the speech request was non unicode or not
											// so convert to uni-text in case of non unicode
		unicodetext.duplicate( (char*)&temp, ucl );
	}

	/*
	clConsole.send("speech: %s\n",nonuni);
	clConsole.send("unicode speech:\n");
	for ( a=0; a < tl-48; a++) clConsole.send("%02i ",unicodetext[a]);
	clConsole.send("\n");*/




	//// Very important: do not use buffer[s][] anymore in this function !!!!
	//// unicode text that gets send is in unicodetext, nonunicode text for normal string processing in non uni code
//	string punt(nonuni);
	if (InputSpeech(speech, pc_currchar, s))	// handle things like renaming or describing an item
		return;

	if (pc_currchar->squelched)					// not allowed to talk
	{
		sysmessage(s, "You have been squelched.");
		return;
	}
			
	// AntiChrist
	pc_currchar->unhide();
		
	if (speech[0] == (char)SrvParams->commandPrefix() )
	{
		Commands->Command(s, speech.latin1());
		return;
	}

	if ( speech_type == '\x09' && pc_currchar->canBroadcast() )
	{
		broadcast(s);
		return;
	}
	
	talk2[0] = 0xAE;
	ShortToCharPtr(tl, &talk2[1]);
	LongToCharPtr(pc_currchar->serial, &talk2[3]);
	ShortToCharPtr(pc_currchar->id(), &talk2[7]);
	talk2[9] =  speech_type;
	ShortToCharPtr(speech_color, &talk2[10]);
	talk2[12] = speech_fontbyte1;
	talk2[13] = speech_fontbyte2;
	
	talk2[14] = lang[0];
	talk2[15] = lang[1];
	talk2[16] = lang[2];
	talk2[17] = lang[3];
	
	Xsend(s, talk2, 18);
	Xsend(s, name, 30);   
	Xsend(s, unicodetext.data(), unicodetext.size());   
	
	if (speech_type == 0 || speech_type == 2)
	{
		pc_currchar->saycolor = speech_color;
	}
	if (SrvParams->speechLog()) // Logging bugfixed by LB
	{
		char temp2[512];
		sprintf(temp2, "%s.speech_log", pc_currchar->name.c_str());
		sprintf((char*)temp, "%s [%x] [%i] said:\n%s\n", pc_currchar->name.c_str(), pc_currchar->serial, pc_currchar->account, speech.latin1());
		savelog((char*)temp, (char*)temp2);
	}
	
	//char SpeechUpr[512];
	//strcpy(SpeechUpr, nonuni);
	//strupr(SpeechUpr);
	QString SpeechUpr = speech.upper();
	//transform(SpeechUpr.begin(), SpeechUpr.end(), SpeechUpr.begin(), ::toupper);
	//if (!strcmp(SpeechUpr, "I RESIGN FROM MY GUILD"))
	if (SpeechUpr == "I RESIGN FROM MY GUILD")
	{
		GuildResign(s);
	}
	
	if (response(s,pc_currchar, SpeechUpr))
		return;  // Vendor responded already
	
	//if (strstr(SpeechUpr, "GUARDS"))
	if (SpeechUpr.contains("GUARDS"))
		callguards(currchar[s]);
	
	if (Boats->Speech(s, SpeechUpr))
		return;
	
	house_speech(s, SpeechUpr); // houses crackerjack 8/12/99			
	
	int i, j;
	for (i = 0; i < now; i++)
	{
		// AntiChrist - don't check line of sight for talking!!!
		if (inrange1(i, s) && perm[i] && i!=s)//&&line_of_sight(s, pc_currchar->pos.x, pc_currchar->pos.y, pc_currchar->pos.z, chars[currchar[i]].x, chars[currchar[i]].y, chars[currchar[i]].z, WALLS_CHIMNEYS + DOORS + FLOORS_FLAT_ROOFING))
		{
			Xsend(i, talk2, 18);
			Xsend(i, name, 30);
			if (pc_currchar->dead				// a ghost is talking
				&& !currchar[i]->dead		// Ghost can talk normally to other ghosts
				&& !currchar[i]->isGMorCounselor()// GM/Counselors can see ghosts talking always  Seers?
				&& currchar[i]->spiritspeaktimer == 0)
			{
				unsigned char ghostspeech[512];
				memcpy(&ghostspeech, unicodetext.data(), unicodetext.size());
				for (j = 1; j < ucl-2 ; j += 2)	// -2: dont override /0 /0 terminator !
				{
					if (ghostspeech[j] != 32)	// keep the blanks
						ghostspeech[j] = (ghostspeech[j]%2) ? 'O' : 'o';
				}
				Xsend(i, ghostspeech, ucl);		// send 'ghostified' speech "OOoooOo  Ooo"
			}
			else
				Xsend(i, unicodetext.data(), unicodetext.size());   
		}
	}
	
	if (pc_currchar->dead) return; // this makes it so npcs do not respond to dead people
	
	cChar* pc=NULL;
	cChar* pNpc=NULL;
	cRegion::RegionIterator4Chars ri(pc_currchar->pos);
	for (ri.Begin(); !ri.atEnd(); ri++)
	{	
		pc = ri.GetData();
		if (!pc->isSameAs(pc_currchar) 
			&& pc->isNpc()
			&& pc->dist(pc_currchar) <= 2)
		{
			pNpc=pc;
			break;
		}
	}
	if (pNpc && pNpc->speech)
	{
		Script *pScp=i_scripts[speech_script];
		if (!pScp->Open())
			return;
		char sect[512];
		sprintf(sect, "SPEECH %i", pNpc->speech);
		if (!pScp->find(sect)) 
		{
			pScp->Close();
			return;
		}
		int match = 0;
		strcpy(sect, "NO DEFAULT TEXT DEFINED");
		unsigned long loopexit = 0;
		do
		{
			pScp->NextLineSplitted();
			if (script1[0] != '}')
			{
				if (!(strcmp("DEFAULT", (char*)script1)))
				{
					strcpy(sect, (char*)script2);
				}
				if (!(strcmp("ON", (char*)script1)))
				{
					char scpUpr[500];
					strcpy(scpUpr,script2);
					strupr(scpUpr);
					if (SpeechUpr.find(scpUpr)!= string::npos)
						match=1;
				}
				if (!(strcmp("SAY", (char*)script1)))
				{
					if (match == 1)
					{
						npctalk(s, pNpc, (char*)script2, 0);
						match = 2;
					}
				}
				
				if (!(strcmp("TRG", (char*)script1))) // Added by Magius(CHE) §
				{							  
					if (match == 1)
					{
						pNpc->trigger = str2num(script2);
						scpMark m=pScp->Suspend();
						
						Trig->triggernpc(s, pNpc, 1);
						
						pScp->Resume(m);
						strcpy((char*)script1, "DUMMY");
						
						match = 2;
					}
				}
			}
		}
		while (script1[0] != '}'  && (++loopexit < MAXLOOPS));
		if (match == 0)
		{
			npctalk(s, pNpc, sect, 0);
		}
		pScp->Close();
	}
}
Esempio n. 14
0
bool DomConvenience::elementToVariant(const QDomElement& e, 
				      QVariant& v)
{
  bool ok = false;

  if (e.tagName() == "string")
  {
    if (e.hasAttribute("value"))
    {
      v = QVariant(e.attribute("value"));
      ok = true;
    }
    else
      qWarning("%s element without value!", (const char*)e.tagName());
  }
  else if (e.tagName() == "int")
  {
    int base = getBase(e); 

    if (e.hasAttribute("value"))
      v = QVariant(e.attribute("value").toInt(&ok, base));
    else
      qWarning("%s element without value!", (const char*)e.tagName());
  }
  else if (e.tagName() == "uint")
  {
    int base = getBase(e); 

    if (e.hasAttribute("value"))
      v = QVariant(e.attribute("value").toUInt(&ok, base));
    else
      qWarning("%s element without value!", (const char*)e.tagName());
  }
  else if (e.tagName() == "double")
  {
    if (e.hasAttribute("value"))
      v = QVariant(e.attribute("value").toDouble(&ok));
    else
      qWarning("%s element without value!", (const char*)e.tagName());
  }
  else if (e.tagName() == "bool")
  {
    if (e.hasAttribute("value"))
    {
      QString val = e.attribute("value");
      v = QVariant(getBoolFromString(val, ok), 0);
      
      if (!ok)
	qWarning("%s element with bogus value '%s'!",
		 (const char*)e.tagName(), (const char*)val);
    }
    else
      qWarning("%s element without value!", (const char*)e.tagName());
  }
  else if (e.tagName() == "color")
  {
    QColor color = getColor(e);
    
    ok = color.isValid();

    v = color;

    if (!ok)
      qWarning("%s element without valid value!", (const char*)e.tagName());
  }
  else if (e.tagName() == "pen")
  {
    int base = getBase(e);
    uint w = 0; 
    Qt::PenStyle s = Qt::SolidLine;
    Qt::PenCapStyle c = Qt::SquareCap;
    Qt::PenJoinStyle j = Qt::BevelJoin;
    QColor color = getColor(e);

    if (e.hasAttribute("style"))
      s = (Qt::PenStyle)e.attribute("style").toInt(0, base);
    if (e.hasAttribute("cap"))
      c = (Qt::PenCapStyle)e.attribute("cap").toInt(0, base);
    if (e.hasAttribute("join"))
      j = (Qt::PenJoinStyle)e.attribute("join").toInt(0, base);
    
    ok = color.isValid();

    v = QPen(color, w, s, c, j);

    if (!ok)
      qWarning("%s element without valid value!", (const char*)e.tagName());
  }
  else if (e.tagName() == "brush")
  {
    int base = getBase(e);
    QColor color = getColor(e);
    Qt::BrushStyle s = Qt::SolidPattern;
    if (e.hasAttribute("style"))
      s = (Qt::BrushStyle)e.attribute("style").toInt(0, base);
    
    ok = color.isValid();
    
    v = QBrush(color, s);

    if (!ok)
      qWarning("%s element without valid value!", (const char*)e.tagName());
  }
  else if (e.tagName() == "point")
  {
    int base = getBase(e);
    bool coordOk;

    int x = 0, y = 0;
    if (e.hasAttribute("x"))
      x = e.attribute("x").toInt(&coordOk, base);

    if (e.hasAttribute("y"))
      y = e.attribute("y").toInt(&coordOk, base);
    
    v = QVariant(QPoint(x, y));
    ok = true;
  }
  else if (e.tagName() == "rect")
  {
    int base = getBase(e);
    bool coordOk;

    int x = 0, y = 0, width = 0, height = 0;
    if (e.hasAttribute("x"))
      x = e.attribute("x").toInt(&coordOk, base);

    if (e.hasAttribute("y"))
      y = e.attribute("y").toInt(&coordOk, base);

    if (e.hasAttribute("width"))
      width = e.attribute("width").toInt(&coordOk, base);

    if (e.hasAttribute("height"))
      height = e.attribute("height").toInt(&coordOk, base);
    
    v = QVariant(QRect(x, y, width, height));
    ok = true;
  }
  else if (e.tagName() == "size")
  {
    int base = getBase(e);
    bool coordOk;

    int width = 0, height = 0;
    if (e.hasAttribute("width"))
      width = e.attribute("width").toInt(&coordOk, base);

    if (e.hasAttribute("height"))
      height = e.attribute("height").toInt(&coordOk, base);
    
    v = QVariant(QSize(width, height));
    ok = true;
  }
  else if (e.tagName() == "key")
  {
    int key;
    if (e.hasAttribute("sequence"))
    {
      key = QAccel::stringToKey(e.attribute("sequence"));

      // fix the key code (deal with Qt brain death)
      key &= ~Qt::UNICODE_ACCEL;

#if QT_VERSION >= 300
      v = QVariant(QKeySequence(key));
#else
      v = QVariant(key);
#endif
      ok = true;
    }
  }
  else if (e.tagName() == "font")
  {
    QFont f;
    bool boolOk;

    if (e.hasAttribute("family"))
      f.setFamily(e.attribute("family"));
    if (e.hasAttribute("pointsize"))
      f.setPointSize(e.attribute("pointsize").toInt());
    if (e.hasAttribute("bold"))
      f.setBold(getBoolFromString(e.attribute("bold"), boolOk));
    if (e.hasAttribute("italic"))
      f.setItalic(getBoolFromString(e.attribute("italic"), boolOk));
    if (e.hasAttribute("strikeout"))
      f.setStrikeOut(getBoolFromString(e.attribute("strikeout"), boolOk));

    v = QVariant(f);
    ok = true;
  }
  else if (e.tagName() == "sizepolicy")
  {
    QSizePolicy sp;
    
    if (e.hasAttribute("hsizetype"))
      sp.setHorData((QSizePolicy::SizeType)e.attribute("hsizetype").toInt());
    if (e.hasAttribute("vsizetype"))
      sp.setVerData((QSizePolicy::SizeType)e.attribute("vsizetype").toInt());
#if (QT_VERSION >= 300)
    if (e.hasAttribute("horstretch"))
      sp.setHorStretch(e.attribute("horstretch").toInt());
    if (e.hasAttribute("verstretch"))
      sp.setHorStretch(e.attribute("verstretch").toInt());
#endif
    v = QVariant(sp);
    ok = true;
  }
  else if (e.tagName() == "cursor")
  {
    if (e.hasAttribute("shape"))
      v = QVariant(QCursor(e.attribute("shape").toInt(&ok, 10)));
    else
      qWarning("%s element without value!", (const char*)e.tagName());
  }
  else if (e.tagName() == "stringlist")
  {
    QDomNodeList stringNodeList = e.elementsByTagName("string");
    QStringList stringList;
    QDomElement stringElement;
    
    for (uint i = 0; i < stringNodeList.length(); i++)
    {
      stringElement = stringNodeList.item(i).toElement();
      if (!stringElement.hasAttribute("value"))
      {
	qWarning("%s element in %s without value! Ignoring!",
		 (const char*)stringElement.tagName(),
		 (const char*)e.tagName());
	continue;
      }

      stringList.append(e.attribute("value"));
    }

    v = stringList;

    ok = true;
  }
  else if (e.tagName() == "uint64")
  {
    QString value = e.attribute("value");

    // borrowed more or less from Qt 3.2 (since we have to support older)
    uint64_t val = 0;
    const QChar* p = value.unicode();
    int l = value.length();
    const uint64_t max_mult = UINT64_MAX / 16;

    if (!p)
    {
      qWarning("Invalid value for tag: %s", (const char*)e.tagName());
      return false;
    }

    while ( l && p->isSpace() )                 // skip leading space
      l--,p++;
    if ( !l )
      return false;
    if ( *p == '+' )
      l--,p++;
    
    if ( !l || !ok_in_hex(*p) )
        return false;
    while ( l && ok_in_hex(*p) ) 
    {
      l--;
      uint dv;
      if ( p->isDigit() ) 
	dv = p->digitValue();
      else 
      {
	if ( *p >= 'a' && *p <= 'f' )
	  dv = *p - 'a' + 10;
	else
	  dv = *p - 'A' + 10;
      }
      if ( val > max_mult || (val == max_mult && dv > UINT64_MAX % 16) )
	return false;
      val = 16 * val + dv;
      p++;
    }

    QByteArray ba;
    ba.duplicate((const char*)&val, sizeof(uint64_t));

    v = ba;
    ok = true;
  }
  else if (e.tagName() == "list")
  {
    qWarning("Unimplemented tag: %s", (const char*)e.tagName());
  }
  else if (e.tagName() == "map")
  {
    qWarning("Unimplemented tag: %s", (const char*)e.tagName());
  }
  else
  {
    qWarning("Unknown tag: %s", (const char*)e.tagName());
  }

  return ok;
}