亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? parse_metafile.c

?? 在Linux環境下用c編寫的BT文件源碼
?? C
字號:
#include <stdio.h>
#include <ctype.h>
#include <malloc.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "parse_metafile.h"
#include "sha1.h"

char  *metafile_content = NULL; // 保存種子文件的內容
long  filesize;                 // 種子文件的長度

int       piece_length  = 0;    // 每個piece的長度,通常為256KB即262144字節
char      *pieces       = NULL; // 保存每個pieces的哈希值,每個哈希值為20字節
int       pieces_length = 0;    // pieces緩沖區的長度

int       multi_file    = 0;    // 指明是單文件還是多文件
char      *file_name    = NULL; // 對于單文件,存放文件名;對于多文件,存放目錄名
long long file_length   = 0;    // 存放待下載文件的總長度
Files     *files_head   = NULL; // 只對多文件種子有效,存放各個文件的路徑和長度

unsigned char info_hash[20];    // 保存info_hash的值,連接tracker和peer時使用
unsigned char peer_id[20];      // 保存peer_id的值,連接peer時使用

Announce_list *announce_list_head = NULL; // 用于保存所有tracker服務器的URL


int read_metafile(char *metafile_name)
{
	long  i;
	
	// 以二進制、只讀的方式打開文件
	FILE *fp = fopen(metafile_name,"rb");
	if(fp == NULL) {
		printf("%s:%d can not open file\n",__FILE__,__LINE__);
		return -1;
	}
	
	// 獲取種子文件的長度
	fseek(fp,0,SEEK_END);
	filesize = ftell(fp);
	if(filesize == -1) {
		printf("%s:%d fseek failed\n",__FILE__,__LINE__);
		return -1;
	}
	
	metafile_content = (char *)malloc(filesize+1);
	if(metafile_content == NULL) {
		printf("%s:%d malloc failed\n",__FILE__,__LINE__);
		return -1;
	}
	
	// 讀取種子文件的內容到metafile_content緩沖區中
	fseek(fp,0,SEEK_SET);
	for(i = 0; i < filesize; i++)
		metafile_content[i] = fgetc(fp);
	metafile_content[i] = '\0';

	fclose(fp); 

#ifdef DEBUG
	printf("metafile size is: %ld\n",filesize);
#endif	
	
	return 0;
}

int find_keyword(char *keyword,long *position)
{
	long i;

	*position = -1;
	if(keyword == NULL)  return 0;

	for(i = 0; i < filesize-strlen(keyword); i++) {
		if( memcmp(&metafile_content[i], keyword, strlen(keyword)) == 0 ) {
			*position = i;
			return 1;
		}
	}
	
	return 0;
}

int read_announce_list()
{
	Announce_list  *node = NULL;
	Announce_list  *p    = NULL;
	int            len   = 0;
	long           i;

	if( find_keyword("13:announce-list",&i) == 0 ) {
		if( find_keyword("8:announce",&i) == 1 ) {
			i = i + strlen("8:announce");
			while( isdigit(metafile_content[i]) ) {
				len = len * 10 + (metafile_content[i] - '0');
				i++;
			}
			i++;  // 跳過 ':'

			node = (Announce_list *)malloc(sizeof(Announce_list));
			strncpy(node->announce,&metafile_content[i],len);
			node->announce[len] = '\0';
			node->next = NULL;
			announce_list_head = node;
		}
	} 
	else {  // 如果有13:announce-list關鍵詞就不用處理8:announce關鍵詞
		i = i + strlen("13:announce-list");
		i++;         // skip 'l'
		while(metafile_content[i] != 'e') {
			i++;     // skip 'l'
			while( isdigit(metafile_content[i]) ) {
				len = len * 10 + (metafile_content[i] - '0');
				i++;
			}
			if( metafile_content[i] == ':' )  i++;
			else  return -1;

			// 只處理以http開頭的tracker地址,不處理以udp開頭的地址
			if( memcmp(&metafile_content[i],"http",4) == 0 ) {
				node = (Announce_list *)malloc(sizeof(Announce_list));
				strncpy(node->announce,&metafile_content[i],len);
				node->announce[len] = '\0';
				node->next = NULL;

				if(announce_list_head == NULL)
					announce_list_head = node;
				else {
					p = announce_list_head;
					while( p->next != NULL) p = p->next; // 使p指向最后個結點
					p->next = node; // node成為tracker列表的最后一個結點
				}
			}

			i = i + len;
			len = 0;
			i++;    // skip 'e'
			if(i >= filesize)  return -1;
		}	
	}

#ifdef DEBUG
	p = announce_list_head;
	while(p != NULL) {
		printf("%s\n",p->announce);
		p = p->next;
	}
#endif	
	
	return 0;
}

// 連接某些tracker時會返回一個重定向URL,需要連接該URL才能獲取peer
int add_an_announce(char *url)
{
	Announce_list *p = announce_list_head, *q;

	// 若參數指定的URL在tracker列表中已存在,則無需添加
	while(p != NULL) {
		if(strcmp(p->announce,url) == 0)  break;
		p = p->next;
	}
	if(p != NULL)  return 0;

	q = (Announce_list *)malloc(sizeof(Announce_list));
	strcpy(q->announce,url);
	q->next = NULL;
	
	p = announce_list_head;
	if(p == NULL)  { announce_list_head = q; return 1; }
	while(p->next != NULL)  p = p->next;
	p->next = q;
	return 1;
}

int is_multi_files()
{
	long i;

	if( find_keyword("5:files",&i) == 1 ) {
		multi_file = 1;
		return 1;
	}

#ifdef DEBUG
	// printf("is_multi_files:%d\n",multi_file);
#endif

	return 0;
}

int get_piece_length()
{
	long i;

	if( find_keyword("12:piece length",&i) == 1 ) {
		i = i + strlen("12:piece length");  // skip "12:piece length"
		i++;  // skip 'i'
		while(metafile_content[i] != 'e') {
			piece_length = piece_length * 10 + (metafile_content[i] - '0');
			i++;
		}
	} else {
		return -1;
	}

#ifdef DEBUG
	printf("piece length:%d\n",piece_length);
#endif

	return 0;
}

int get_pieces()
{
	long i;

	if( find_keyword("6:pieces", &i) == 1 ) {
		i = i + 8;     // skip "6:pieces"
		while(metafile_content[i] != ':') {
			pieces_length = pieces_length * 10 + (metafile_content[i] - '0');
			i++;
		}
		i++;           // skip ':'
		pieces = (char *)malloc(pieces_length+1);
		memcpy(pieces,&metafile_content[i],pieces_length);
		pieces[pieces_length] = '\0';
	} else {
		return -1;
	}

#ifdef DEBUG
	printf("get_pieces ok\n");
#endif

	return 0;
}

int get_file_name()
{
	long  i;
	int   count = 0;

	if( find_keyword("4:name", &i) == 1 ) {
		i = i + 6;  // skip "4:name"
		while(metafile_content[i] != ':') {
			count = count * 10 + (metafile_content[i] - '0');
			i++;
		}
		i++;        // skip ':' 
		file_name = (char *)malloc(count+1);
		memcpy(file_name,&metafile_content[i],count);
		file_name[count] = '\0';
	} else {
		return -1;
	}

#ifdef DEBUG
	// 由于可能含有中文字符,因此可能打印出亂碼
	// printf("file_name:%s\n",file_name);
#endif

	return 0;
}

int get_file_length()
{
	long i;

	if(is_multi_files() == 1)  {
		if(files_head == NULL)  get_files_length_path();
		Files *p = files_head;
		while(p != NULL) { file_length += p->length; p = p->next; }
	} else {
		if( find_keyword("6:length",&i) == 1 ) {
			i = i + 8;  // skip "6:length"
			i++;        // skip 'i' 
			while(metafile_content[i] != 'e') {
				file_length = file_length * 10 + (metafile_content[i] - '0');
				i++;
			}	
		}
	}
	
#ifdef DEBUG
	printf("file_length:%lld\n",file_length);
#endif

	return 0;
}

int get_files_length_path()
{
	long   i;
	int    length;
	int    count;
	Files  *node  = NULL;
	Files  *p     = NULL;

	if(is_multi_files() != 1) {
		return 0;
	}
	
	for(i = 0; i < filesize-8; i++) {
		if( memcmp(&metafile_content[i],"6:length",8) == 0 )
		{
			i = i + 8;  // skip "6:length"
			i++;        // skip 'i' 
			length = 0;
			while(metafile_content[i] != 'e') {
				length = length * 10 + (metafile_content[i] - '0');
				i++;
			}
			node = (Files *)malloc(sizeof(Files));
			node->length = length;
			node->next = NULL;
			if(files_head == NULL)
				files_head = node;
			else {
				p = files_head;
				while(p->next != NULL) p = p->next;
				p->next = node;
			}
		}
		if( memcmp(&metafile_content[i],"4:path",6) == 0 )
		{
			i = i + 6;  // skip "4:path"
			i++;        // skip 'l'
			count = 0;
			while(metafile_content[i] != ':') {
				count = count * 10 + (metafile_content[i] - '0');
				i++;
			}
			i++;        // skip ':'
			p = files_head;
			while(p->next != NULL) p = p->next;
			memcpy(p->path,&metafile_content[i],count);
			*(p->path + count) = '\0';
		}
	}

#ifdef DEBUG
	// 由于可能含有中文字符,因此可能打印出亂碼
	// p = files_head;
	// while(p != NULL) {
	//	 printf("%ld:%s\n",p->length,p->path);
	//	 p = p->next;
	// }
#endif

	return 0;
}

int get_info_hash()
{
	int   push_pop = 0;
	long  i, begin, end;

	if(metafile_content == NULL)  return -1;

	if( find_keyword("4:info",&i) == 1 ) {
		begin = i+6;  // begin是關鍵字"4:info"對應值的起始下標
	} else {
		return -1;
	}

	i = i + 6;        // skip "4:info"
	for(; i < filesize; )
		if(metafile_content[i] == 'd') { 
			push_pop++;
			i++;
		} else if(metafile_content[i] == 'l') {
			push_pop++;
			i++;
		} else if(metafile_content[i] == 'i') {
			i++;  // skip i
			if(i == filesize)  return -1;
			while(metafile_content[i] != 'e') {
				if((i+1) == filesize)  return -1;
				else i++;
			}
			i++;  // skip e
		} else if((metafile_content[i] >= '0') && (metafile_content[i] <= '9')) {
			int number = 0;
			while((metafile_content[i] >= '0') && (metafile_content[i] <= '9')) {
				number = number * 10 + metafile_content[i] - '0';
				i++;
			}
			i++;  // skip :
			i = i + number;
		} else if(metafile_content[i] == 'e') {
			push_pop--;
			if(push_pop == 0) { end = i; break; }
			else  i++; 
		} else {
			return -1;
		}
	if(i == filesize)  return -1;

	SHA1_CTX context;
	SHA1Init(&context);
	SHA1Update(&context, &metafile_content[begin], end-begin+1);
	SHA1Final(info_hash, &context);

#ifdef DEBUG
	printf("info_hash:");
	for(i = 0; i < 20; i++)  
		printf("%.2x ",info_hash[i]);
	printf("\n");
#endif

	return 0;
}

int get_peer_id()
{
	// 設置產生隨機數的種子
	srand(time(NULL));
	// 生成隨機數,并把其中12位賦給peer_id,peer_id前8位固定為-TT1000-
	sprintf(peer_id,"-TT1000-%12d",rand());

#ifdef DEBUG
	int i;
	printf("peer_id:");
	for(i = 0; i < 20; i++)  printf("%c",peer_id[i]);
	printf("\n");
#endif

	return 0;
}

void release_memory_in_parse_metafile()
{
	Announce_list *p;
	Files         *q;
	
	if(metafile_content != NULL)  free(metafile_content);
	if(file_name != NULL)         free(file_name);
	if(pieces != NULL)            free(pieces);
	
	while(announce_list_head != NULL) {
		p = announce_list_head;
		announce_list_head = announce_list_head->next;
		free(p);
	}

	while(files_head != NULL) {
		q = files_head;
		files_head = files_head->next;
		free(q);
	}
}

int parse_metafile(char *metafile)
{
	int ret;

	// 讀取種子文件
	ret = read_metafile(metafile);
	if(ret < 0) { printf("%s:%d wrong",__FILE__,__LINE__); return -1; }
	
	// 從種子文件中獲取tracker服務器的地址
	ret = read_announce_list();
	if(ret < 0) { printf("%s:%d wrong",__FILE__,__LINE__); return -1; }

	// 判斷是否為多文件
	ret = is_multi_files();
	if(ret < 0) { printf("%s:%d wrong",__FILE__,__LINE__); return -1; }
	
	// 獲取每個piece的長度,一般為256KB
	ret = get_piece_length();
	if(ret < 0) { printf("%s:%d wrong",__FILE__,__LINE__); return -1; }
	
	// 讀取各個piece的哈希值
	ret = get_pieces();
	if(ret < 0) { printf("%s:%d wrong",__FILE__,__LINE__); return -1; }
	
	// 獲取要下載的文件名,對于多文件的種子,獲取的是目錄名
	ret = get_file_name();
	if(ret < 0) { printf("%s:%d wrong",__FILE__,__LINE__); return -1; }

	// 對于多文件的種子,獲取各個待下載的文件路徑和文件長度
	ret = get_files_length_path();
	if(ret < 0) { printf("%s:%d wrong",__FILE__,__LINE__); return -1; }
	
	// 獲取待下載的文件的總長度
	ret = get_file_length();
	if(ret < 0) { printf("%s:%d wrong",__FILE__,__LINE__); return -1; }

	// 獲得info_hash,生成peer_id
	ret = get_info_hash();
	if(ret < 0) { printf("%s:%d wrong",__FILE__,__LINE__); return -1; }
	ret = get_peer_id();
	if(ret < 0) { printf("%s:%d wrong",__FILE__,__LINE__); return -1; }

	return 0;
}

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
亚洲午夜日本在线观看| 久久精品人人爽人人爽| 一区二区三区四区蜜桃| 色又黄又爽网站www久久| 亚洲精品乱码久久久久久黑人| 99久久久免费精品国产一区二区| 国产精品久久久久永久免费观看| 91免费版pro下载短视频| 亚洲综合在线观看视频| 日韩三级中文字幕| 国产精品亚洲а∨天堂免在线| 国产人妖乱国产精品人妖| 91啦中文在线观看| 丝袜亚洲精品中文字幕一区| 日韩视频中午一区| 东方aⅴ免费观看久久av| 亚洲视频电影在线| 5月丁香婷婷综合| 国产精品系列在线观看| 一区二区三区日韩精品视频| 欧美一区二区黄| youjizz久久| 日韩高清不卡一区二区| 久久久久国产精品麻豆ai换脸 | 欧美精品一级二级三级| 麻豆一区二区三| 国产精品久久午夜| 欧美日韩一级大片网址| 国产精品1区二区.| 亚洲自拍偷拍欧美| 欧美精品一区二区蜜臀亚洲| 色综合亚洲欧洲| 国内外精品视频| 亚洲国产综合色| 国产亚洲一区字幕| 91.com在线观看| 99久久er热在这里只有精品66| 青青草国产成人99久久| 亚洲视频综合在线| 久久久久国产精品免费免费搜索| 在线亚洲一区二区| 成人永久免费视频| 另类小说图片综合网| 亚洲激情成人在线| 国产欧美一区二区精品仙草咪| 欧美妇女性影城| 91在线观看污| 国产福利精品一区| 蜜桃视频第一区免费观看| 樱花影视一区二区| 国产精品国产成人国产三级| 精品国产免费视频| 欧美一区二区三区性视频| 色吧成人激情小说| av在线不卡电影| 国产精品一区不卡| 精品一区二区三区不卡| 日韩精品乱码av一区二区| 一区二区欧美视频| 亚洲人被黑人高潮完整版| 亚洲国产电影在线观看| 欧美精品一区二区三区四区| 91精品国产91久久久久久一区二区 | 波波电影院一区二区三区| 精品写真视频在线观看| 日本va欧美va欧美va精品| 亚洲午夜精品网| 亚洲综合在线电影| 一区二区三区欧美亚洲| 亚洲老妇xxxxxx| 日韩一区欧美一区| 日韩一区日韩二区| 综合久久国产九一剧情麻豆| 国产精品久久久久久久久久免费看 | 一区二区三区中文免费| 亚洲欧美偷拍卡通变态| 中文字幕一区二区5566日韩| 国产精品理论片| 最新热久久免费视频| 国产精品美女久久久久aⅴ| 国产精品全国免费观看高清| 国产欧美视频一区二区三区| 日本一区二区三区在线观看| 国产亚洲美州欧州综合国| 久久久久国产一区二区三区四区| 久久综合精品国产一区二区三区| 精品99久久久久久| 国产蜜臀97一区二区三区 | 欧美激情综合在线| 自拍偷拍国产精品| 亚洲综合激情网| 天天综合网 天天综合色| 奇米精品一区二区三区在线观看| 看片的网站亚洲| 国产精品一区二区三区99| 国产aⅴ精品一区二区三区色成熟| 国产69精品久久777的优势| 97aⅴ精品视频一二三区| 91福利国产成人精品照片| 在线不卡中文字幕| 久久久久97国产精华液好用吗| 中文字幕欧美激情一区| 夜夜夜精品看看| 久久精品国产99国产精品| 成人国产精品免费网站| 欧美午夜精品一区二区三区| 日韩一本二本av| 中文字幕在线一区| 婷婷开心激情综合| 国产成人综合亚洲网站| 在线视频你懂得一区二区三区| 欧美精品v日韩精品v韩国精品v| 精品人在线二区三区| 国产精品久久看| 日本亚洲三级在线| 成人一级片网址| 欧美久久久久中文字幕| 久久久久久久久久美女| 一区二区久久久| 黄网站免费久久| 欧美在线免费视屏| 国产亚洲一区二区三区四区 | 国产一区二区三区免费| 一本久久综合亚洲鲁鲁五月天| 91精品国产一区二区人妖| 一区在线中文字幕| 久久国产精品免费| 欧美中文字幕一区二区三区亚洲| 欧美va亚洲va| 亚洲小说春色综合另类电影| 国产精品一区专区| 精品视频一区二区三区免费| 国产精品灌醉下药二区| 免费观看一级特黄欧美大片| 一本一本久久a久久精品综合麻豆| 精品国产伦一区二区三区免费| 亚洲精品久久嫩草网站秘色| 国产精品亚洲专一区二区三区| 欧美精品tushy高清| 亚洲精品日日夜夜| 成人激情视频网站| 亚洲精品在线免费播放| 日韩精品91亚洲二区在线观看 | 91麻豆swag| 欧美韩国日本综合| 国产在线一区二区| 6080国产精品一区二区| 亚洲综合色在线| 色悠久久久久综合欧美99| 日本一区二区三区免费乱视频| 免费看欧美美女黄的网站| 欧美日韩亚洲综合一区| 玉米视频成人免费看| 91丨porny丨最新| 国产精品热久久久久夜色精品三区 | 日韩精品中文字幕一区| 午夜精品国产更新| 欧美日韩亚州综合| 亚洲综合一区二区三区| 97久久久精品综合88久久| 一色桃子久久精品亚洲| voyeur盗摄精品| 综合久久国产九一剧情麻豆| 99久久精品免费看| 亚洲视频 欧洲视频| 色综合久久天天综合网| 亚洲女人****多毛耸耸8| 91美女在线视频| 一区二区在线观看免费| 欧美午夜精品一区| 亚洲成人午夜电影| 欧美精品粉嫩高潮一区二区| 日韩在线a电影| 精品久久久久一区| 国产一区二区三区黄视频| 国产欧美一区二区三区鸳鸯浴| 国产二区国产一区在线观看| 中文字幕国产精品一区二区| 国产91精品免费| 综合欧美亚洲日本| 欧美日韩你懂得| 久久精品国产999大香线蕉| 精品噜噜噜噜久久久久久久久试看| 激情都市一区二区| 国产精品久久久久久久久搜平片 | 精品影视av免费| 久久久久久免费网| 成人美女在线视频| 亚洲精品福利视频网站| 在线播放国产精品二区一二区四区| 爽爽淫人综合网网站| 精品成人免费观看| 成年人午夜久久久| 亚洲成人免费电影| 亚洲精品一区在线观看| 99精品视频一区二区三区| 亚洲国产精品自拍| 久久综合九色综合97婷婷| 91年精品国产| 激情五月播播久久久精品|