bool MetaInfo::parse(const QByteArray &data)
 {
     clear();
     content = data;

     BencodeParser parser;
     if (!parser.parse(content)) {
         errString = parser.errorString();
         return false;
     }

     infoData = parser.infoSection();

     QMap<QByteArray, QVariant> dict = parser.dictionary();
     if (!dict.contains("info"))
         return false;

     QMap<QByteArray, QVariant> info = qVariantValue<Dictionary>(dict.value("info"));

     if (info.contains("files")) {
         metaInfoFileForm = MultiFileForm;

         QList<QVariant> files = info.value("files").toList();

         for (int i = 0; i < files.size(); ++i) {
             QMap<QByteArray, QVariant> file = qVariantValue<Dictionary>(files.at(i));
             QList<QVariant> pathElements = file.value("path").toList();
             QList<QString> Directories;
             QByteArray path;
             QString filename;
             int iSize = pathElements.size();
             if (iSize > 0)
             {
                 filename = QString::fromUtf8(pathElements.at(iSize - 1).toByteArray());
                 pathElements.erase(pathElements.end() - 1);
             }
             foreach (QVariant p, pathElements) {
                 if (!path.isEmpty())
                 {
                     path += "/";
                 }
                 path += p.toByteArray();
                 Directories << QString::fromUtf8(p.toByteArray());
             }

             MetaInfoMultiFile multiFile;
             multiFile.length = file.value("length").toLongLong();
             multiFile.path = QString::fromUtf8(path);
             multiFile.filename = filename;
             multiFile.md5sum = file.value("md5sum").toByteArray();
             multiFile.Directories = Directories;
             metaInfoMultiFiles << multiFile;
         }

         metaInfoName = QString::fromUtf8(info.value("name").toByteArray());
         metaInfoPieceLength = info.value("piece length").toInt();
         QByteArray pieces = info.value("pieces").toByteArray();
         for (int i = 0; i < pieces.size(); i += 20)
             metaInfoSha1Sums << pieces.mid(i, 20);
     } else if (info.contains("length")) {
Esempio n. 2
0
 bool MetaInfo::parse(const QByteArray &data)
 {
     clear();
     content = data;

     BencodeParser parser;
     if (!parser.parse(content)) {
         errString = parser.errorString();
         return false;
     }

     infoData = parser.infoSection();

     QMap<QByteArray, QVariant> dict = parser.dictionary();
     if (!dict.contains("info"))
         return false;

	 QMap<QByteArray, QVariant> info = dict.value("info").value<Dictionary>();

     if (info.contains("files")) {
         metaInfoFileForm = MultiFileForm;

         QList<QVariant> files = info.value("files").toList();

         for (int i = 0; i < files.size(); ++i) {
			 QMap<QByteArray, QVariant> file = files.at(i).value<Dictionary>();
             QList<QVariant> pathElements = file.value("path").toList();
             QByteArray path;
             foreach (QVariant p, pathElements) {
                 if (!path.isEmpty())
                     path += "/";
                 path += p.toByteArray();
             }

             MetaInfoMultiFile multiFile;
             multiFile.length = file.value("length").toLongLong();
             metaInfoMultiFiles << multiFile;
         }

     } else if (info.contains("length")) {
Esempio n. 3
0
void TrackerClient::httpRequestDone(bool error)
{
    if (lastTrackerRequest) {
        emit stopped();
        return;
    }

    if (error) {
        emit connectionError(http.error());
        return;
    }

    QByteArray response = http.readAll();
    http.abort();

    BencodeParser parser;
    if (!parser.parse(response)) {
        qWarning("Error parsing bencode response from tracker: %s",
                 qPrintable(parser.errorString()));
        http.abort();
        return;
    }

    QMap<QByteArray, QVariant> dict = parser.dictionary();

    if (dict.contains("failure reason")) {
        // no other items are present
        emit failure(QString::fromUtf8(dict.value("failure reason").toByteArray()));
        return;
    }

    if (dict.contains("warning message")) {
        // continue processing
        emit warning(QString::fromUtf8(dict.value("warning message").toByteArray()));
    }

    if (dict.contains("tracker id")) {
        // store it
        trackerId = dict.value("tracker id").toByteArray();
    }

    if (dict.contains("interval")) {
        // Mandatory item
        if (requestIntervalTimer != -1)
            killTimer(requestIntervalTimer);
        requestIntervalTimer = startTimer(dict.value("interval").toInt() * 1000);
    }

    if (dict.contains("peers")) {
        // store it
        peers.clear();
        QVariant peerEntry = dict.value("peers");
        if (peerEntry.type() == QVariant::List) {
            QList<QVariant> peerTmp = peerEntry.toList();
            for (int i = 0; i < peerTmp.size(); ++i) {
                TorrentPeer tmp;
                QMap<QByteArray, QVariant> peer = qVariantValue<QMap<QByteArray, QVariant> >(peerTmp.at(i));
                tmp.id = QString::fromUtf8(peer.value("peer id").toByteArray());
                tmp.address.setAddress(QString::fromUtf8(peer.value("ip").toByteArray()));
                tmp.port = peer.value("port").toInt();
                peers << tmp;
            }
        } else {
            QByteArray peerTmp = peerEntry.toByteArray();
            for (int i = 0; i < peerTmp.size(); i += 6) {
                TorrentPeer tmp;
                uchar *data = (uchar *)peerTmp.constData() + i;
                tmp.port = (int(data[4]) << 8) + data[5];
                uint ipAddress = 0;
                ipAddress += uint(data[0]) << 24;
                ipAddress += uint(data[1]) << 16;
                ipAddress += uint(data[2]) << 8;
                ipAddress += uint(data[3]);
                tmp.address.setAddress(ipAddress);
                peers << tmp;
            }
        }
        emit peerListUpdated(peers);
    }
}
Esempio n. 4
0
bool MetaInfo::parse(string& content) {
	clear();

	bencode_t ben, ben2;
	BencodeParser parser;
	parser.bencode_init(&ben, content.c_str(), (int)content.length());
	const char* buf;
	long int number;
	int len;

	totalSizeSingleFile = content.length();

	if(!parser.bencode_is_dict(&ben)){
		std::cout<<"not a dictionary";
		return false;
	}

	while(parser.bencode_dict_has_next(&ben))
	{
		if(parser.bencode_dict_get_next(&ben, &ben2, &buf, &len) == 0)
		{
			std::cout<<"breaking the loop\n";
			break;
		}
		std::string key(buf, len);

		if(key == "announce"){
			parser.bencode_string_value(&ben2, &buf, &len);
			metaInfoAnnounce= string(buf, len);
			std::cout<<key<<"="<<metaInfoAnnounce<<std::endl;
		} else if(key == "comment"){
			parser.bencode_string_value(&ben2, &buf, &len);
			metaInfoComment = string(buf, len);
			std::cout<<key<<"="<<metaInfoComment<<std::endl;
		} else if(key == "creation date"){
			parser.bencode_int_value(&ben2, &number);
			std::cout<<key<<"="<<number<<std::endl;
			//			metaInfoCreationDate
		} else if(key == "httpseeds"){
			cout<<key<<std::endl;
			if(parser.bencode_is_list(&ben2)){
				bencode_t ben3;
				while(parser.bencode_list_has_next(&ben2)){
					if(!parser.bencode_list_get_next(&ben2, &ben3))
					{
						std::cout<<"error getting list element\n";
						return false;
					}
					std::string val;
					parser.bencode_string_value(&ben3, &buf, &len);
					val = string(buf, len);
					std::cout<<val<<std::endl;
					metaInfoHTTPseeds.push_back(val);
				}
			}
		} else if(key == "info") { //get info section
			std::cout<<key<<std::endl;
			int infoSectionLength=strlen("d");
			infoData = string(ben2.str, ben2.len);
			if(parser.bencode_is_dict(&ben2)){
				metaInfoFileForm = SingleFileForm;
				bencode_t ben3;
				while(parser.bencode_dict_has_next(&ben2)){
					if(!parser.bencode_dict_get_next(&ben2, &ben3, &buf, &len)){
						std::cout<<"error getting dictionary element\n";
						return false;
					}

					std::string key(buf, len);
					infoSectionLength = infoSectionLength+numberOfDigits(len)+len+1;
					if(key == "files"){
						metaInfoFileForm = MultiFileForm;
					} else if(key=="length"){
						parser.bencode_int_value(&ben3, &number);
						infoSectionLength = infoSectionLength + numberOfDigits(number) + 2;
						metaInfoSingleFile.length = number;
						std::cout<<key<<"="<<number<<std::endl;
					} else if(key=="name"){
						parser.bencode_string_value(&ben3, &buf, &len);
						infoSectionLength = infoSectionLength+len+numberOfDigits(len)+1;
						metaInfoSingleFile.name=string(buf, len);
						std::cout<<key<<"="<<metaInfoSingleFile.name<<std::endl;
					} else if(key=="piece length"){
						parser.bencode_int_value(&ben3, &number);
						infoSectionLength = infoSectionLength + numberOfDigits(number)+2;
						metaInfoSingleFile.pieceLength=number;
						std::cout<<key<<"="<<metaInfoSingleFile.pieceLength<<std::endl;
					} else if(key=="md5sum"){
						parser.bencode_string_value(&ben3, &buf, &len);
						infoSectionLength = infoSectionLength+len+numberOfDigits(len)+1;
						metaInfoSingleFile.md5sum = string(buf, len).c_str();
						std::cout<<key<<"="<<metaInfoSingleFile.md5sum<<std::endl;
					} else if(key=="pieces"){
						std::cout<<key<<std::endl;
						parser.bencode_string_value(&ben3, &buf, &len);
						infoSectionLength = infoSectionLength+len+numberOfDigits(len)+1;
						const char* sha1Data=string(buf, len).c_str();
						for(int i=0; i<len; i+=20){
							char* sha1Sum= (char*)malloc(20);
							memcpy(sha1Sum, sha1Data, 20);
							std::cout<<sha1Sum<<std::endl;
							metaInfoSingleFile.sha1Sums.push_back(sha1Sum);
							sha1Data=sha1Data+20;
						}
					}
				}
			}
			infoSectionLength = infoSectionLength+1;
			infoData = string(infoData.c_str(), infoSectionLength);
			std::cout<<"infoSectionLength = "<<infoSectionLength<<std::endl;
		}
	}
	return true;
}
/**
 * Move to next item
 * @param sp The bencode string we are processing
 * @return Pointer to string on success, otherwise NULL */
static const char *__iterate_to_next_string_pos(
		bencode_t * be,
		const char *sp
)
{
	BencodeParser bp;
	bencode_t iter;

	bp.bencode_init(&iter, sp, __carry_length(be, sp));

	if (bp.bencode_is_dict(&iter))
	{
		/* navigate to the end of the dictionary */
		while (bp.bencode_dict_has_next(&iter))
		{
			/* ERROR: input string is invalid */
			if (0 == bp.bencode_dict_get_next(&iter, NULL, NULL, NULL))
				return NULL;
		}

		return iter.str + 1;
	}
	else if (bp.bencode_is_list(&iter))
	{
		/* navigate to the end of the list */
		while (bp.bencode_list_has_next(&iter))
		{
			/* ERROR: input string is invalid */
			if (-1 == bp.bencode_list_get_next(&iter, NULL))
				return NULL;
		}

		return iter.str + 1;
	}
	else if (bp.bencode_is_string(&iter))
	{
		int len;
		const char *str;

		/* ERROR: input string is invalid */
		if (0 == bp.bencode_string_value(&iter, &str, &len))
			return NULL;

		return str + len;
	}
	else if (bp.bencode_is_int(&iter))
	{
		const char *end;
		long int val;

		if (0 == __read_string_int(&iter.str[1], &end, &val))
			return NULL;

		assert(end[0] == 'e');

		return end + 1;
	}

	/* input string is invalid */
	return NULL;
}