⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 btfiles.cpp

📁 linux系统下bt的客户端实现。 采用的是c++
💻 CPP
字号:
#include "Btfiles.h"#include <unistd.h>#include <limits.h>#include <fcntl.h>#include <iostream.h>using namespace std;#ifndef PATH_MAX#define PATH_MAX 255#endif#ifndef DEBUG#define DEBUG(fmt, ...) fprintf(stderr, fmt, __VA_ARGS__)#endifbtFiles::btFiles(){	m_head = NULL;	m_totallength = 0;	m_dirctory = NULL;}btFiles::~btFiles(){	btfile *p = m_head, *q;	for (; p;) {		delete p->path;		q = p->next;		delete p;		p = q;	}	m_head = NULL;	m_totallength = 0;	delete m_dirctory;}btfile *btFiles::new_node(){	return new btfile;}int btFiles::open_file(btfile * bf){	char fullpath[PATH_MAX];	snprintf(fullpath, PATH_MAX, "%s%c%s", m_dirctory, '/', bf->path);	if (NULL != bf->fp)		return 0;	if (NULL == fullpath || NULL == (bf->fp = fopen(fullpath, "r+")))		return -1;    DEBUG("open file %s successfully\n", fullpath);	return 0;}ssize_t btFiles::IO(char *buf, uint64_t off, size_t len, bool in){	btfile *p = m_head;	off_t l = 0, pos;	if (!buf || ((off + len) >= m_totallength))		return -1;	if (!len)		return 0;	for (; p && ((l += p->length) <= off); p = p->next);	if (!p)		return -1;	pos = p->length - (l - off);	for (; p && len;) {		if (NULL == p->fp) {			if (open_file(p) < 0)				return -1;		}		if (fseek(p->fp, pos, SEEK_SET) < 0)			return -1;		l = len > (p->length - pos) ? p->length - pos : len;				if (in) {			if (1 != fwrite(buf, l, 1, p->fp))				return -1;			fflush(p->fp);		} else {			if (1 != fread(buf, l, 1, p->fp))				return -1;		}		len -= l;		buf += l;		p = p->next;		pos = 0;	}	if (NULL == p)		return -1;	return 0;}int btFiles::allocate_disk(int fd, uint64_t len){	if (0 == len)		return 0;	if (ftruncate(fd, len) < 0) {		char c = '\0';		if (lseek(fd, len - 1, SEEK_SET) < 0)			return -1;		if (write(fd, &c, 1) < 0)			return -1;	}	return 0;}int btFiles::BuildFromMI(Bencode * pdict){	btfile **pbf = &m_head;	if (NULL == pdict || bencode_dict != pdict->m_enumType)		return -1;	std::string str = "info|name";	Bencode *pcode = query_dict(pdict, str);	if (NULL == pcode || bencode_str != pcode->m_enumType)		return -1;	m_dirctory =		new char[((BencodeString *) pcode)->m_strValue.length() + 1];	strcpy(m_dirctory, ((BencodeString *) pcode)->m_strValue.c_str());	str = "info|files";	pcode = query_dict(pdict, str);	if (pcode) {		if (pcode->m_enumType != bencode_list)			return -1;		std::vector < Bencode * >::iterator iter =			((BencodeList *) pcode)->m_list.begin();		std::vector < Bencode * >::iterator iter_end =			((BencodeList *) pcode)->m_list.end();		while (iter != iter_end) {			Bencode *p;			std::string keylist("path");			char pathname[PATH_MAX];			uint64_t len = 0;			if ((*iter)->m_enumType != bencode_dict)				return -1;			if (NULL == (p = query_dict(*iter, keylist)))				return -1;			if (0 > list2path(p, pathname))				return -1;			keylist = "length";			if (NULL == (p = query_dict(*iter, keylist)))				return -1;			if (p->m_enumType != bencode_int)				return -1;			len = ((BencodeInt *) p)->m_nValue;			m_totallength += len;			btfile *pnode = new btfile;			pnode->path = new char[strlen(pathname) + 1];			strcpy(pnode->path, pathname);			pnode->length = len;			iter++;			pnode->next = *pbf;			*pbf = pnode;			pbf = &pnode->next;		}	} else {	}	return 0;}int btFiles::list2path(Bencode * plist, char *path){	char *p = path;	if (!plist || bencode_list != plist->m_enumType)		return -1;	if (NULL == path)		return 0;	std::vector < Bencode * >::iterator iter =		((BencodeList *) plist)->m_list.begin();	std::vector < Bencode * >::iterator iter_end =		((BencodeList *) plist)->m_list.end();	while (iter != iter_end) {		if (bencode_str != (*iter)->m_enumType)			return -1;		BencodeString *pstr = (BencodeString *) (*iter);		int len = pstr->m_strValue.length();		memcpy(p, pstr->m_strValue.c_str(), len);		p += len;		*p++ = '/';		iter++;	}	p--;	*p = '\0';	return 0;}int btFiles::CreateFiles(){	btfile *p = m_head;	while (p) {		if (0 > build_file(p->path, p->length))			cout << "can't create the file:" << p->path << endl;		p = p->next;	}	return 0;}int btFiles::build_file(const char *pathname, uint64_t length){	char path[PATH_MAX], *p;	struct stat sb;	int fd;	if (snprintf(path, PATH_MAX, "%s%c%s", m_dirctory, '/', pathname) < 0)		return -1;	p = path;	for (; *p;) {		for (; p && *p && *p != '/'; p++);		if ('/' == *p) {			*p = '\0';			if (stat(path, &sb) < 0)				if (mkdir(path, 0755) < 0)					return -1;			*p++ = '/';		} else {			if (stat(path, &sb) < 0)				if (0 > (fd = creat(path, 0644))					|| allocate_disk(fd, length) < 0)					return -1;			close(fd);		}	}	return 0;}void btFiles::printout(){	btfile *pbf = m_head;	cout << "total size is:" << m_totallength << endl;	for (; pbf; pbf = pbf->next)		cout << pbf->path << endl << pbf->length << endl;}/*int main(){    Bencode *pdict = create_dictionary("ab.TORRENT");    if (NULL == pdict) {	cout << "can't create the dictionary" << endl;	exit(0);    }    btFiles bf;    bf.BuildFromMI(pdict);    if (0 > bf.CreateFiles())	cout << "create file failed" << endl;    delete_dictionary(pdict);    return 0;}*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -