//保存tracker的url地址到链表 int save_tracker_list() { //先查看有没有备用的tracker的URL,有的话直接从announce-list之后开始查找并添加到链表 long long pos = -1;//记录在metafile_buf中的缓冲区的位置 int len = 0; //记录字符串的长度 char tempUrl[512]; memset(tempUrl,0,sizeof(tempUrl)); if(find_buf("d8:announce",&pos) == 1){ if(find_buf("13:announce-list",&pos) == 1){ pos += strlen("13:announce-list"); pos += 2; //跳过2个l while(metafile_buf[pos] != 'e') { len = 0; while(isdigit(metafile_buf[pos])) { len = len*10 + metafile_buf[pos] - '0'; pos++; } pos++; //pass : int i; for(i = 0;i < len;i++){ tempUrl[i] = metafile_buf[pos++]; } tempUrl[i+1] = '\0'; //质保存http的url if(memcmp(tempUrl,"http",4) == 0){ add_tracker_list(tempUrl); } pos++; //pass e if(metafile_buf[pos] == 'l'){ pos++; //pass l } } }else{ //没有备用的tracker的url pos += strlen("d8:announce"); while(isdigit(metafile_buf[pos])) { len = len *10 + metafile_buf[pos] - '0'; pos++; } pos++;//滤过: int i; for(i = 0;i < len;i++){ tempUrl[i] = metafile_buf[pos++]; } tempUrl[i+1] = '\0'; //添加到链表节点 add_tracker_list(tempUrl); } }else{ printf("parse metafile fail %s:%d\n",__FILE__,__LINE__); return -1; } return 0; }
//获取pieces的hash值,保存到缓冲区中 int get_pieces_hash() { //先获取hash值的字符串长度 pieces_hash_length = 0; long long pos; if(find_buf("6:pieces",&pos) == 1) { pos += strlen("6:pieces"); while(metafile_buf[pos] != ':') //数字以:结束 { pieces_hash_length = pieces_hash_length*10 + (metafile_buf[pos++] - '0'); } #ifdef DEBUG printf("pieces hash = %lld\n",pieces_hash_length); #endif pieces_hash = (char *)malloc(pieces_hash_length+1); if(pieces_hash == NULL){ printf("malloc fial %s:%d \n",__FILE__,__LINE__); return -1; } memset(pieces_hash,0,sizeof(pieces_hash)); pos++; //pass : long i; for(i = 0;i < pieces_hash_length ;i++){ pieces_hash[i] = metafile_buf[pos++]; } pieces_hash[i] = '\0'; } return 0; }
//判断是否为多文件 int is_multi_file() { long long i; if(find_buf("5:files",&i) == 1) { ismulti_file = 1; } #ifdef DEBUG //printf("multi file = %d\n",ismulti_file); #endif return ismulti_file; }
//获取每个piece的长度 int get_piece_length() { long long pos; piece_length = 0; if(find_buf("12:piece length",&pos) == 1){ pos += strlen("12:piece length"); pos++; //pass i while(isdigit(metafile_buf[pos])&&(metafile_buf[pos] != 'e')) { piece_length = piece_length *10 + (metafile_buf[pos++] - '0'); } }else{ printf("get piece_length fail %s:%d\n",__FILE__,__LINE__); return -1; } return 0; }
/* * alloc_node() * Allocate a new node * * Somewhat complicated because the file's storage structure is stored * at the front of the file. We read in the first sector, then extend * the buffered block out to the indicated size. */ static struct openfile * alloc_node(daddr_t d) { struct buf *b; struct fs_file *fs; ulong len, fslen; struct openfile *o; /* * Get buf, address first sector as an fs_file */ b = find_buf(d, 1, ABC_FILL); fs = index_buf(b, 0, 1); ASSERT(fs->fs_nblk > 0, "alloc_node: zero"); ASSERT(fs->fs_blks[0].a_start == d, "alloc_node: mismatch"); /* * Extend the buf if necessary */ len = fs->fs_blks[0].a_len; fslen = fs->fs_len; if (len > 1) { if (len > EXTSIZ) { len = EXTSIZ; } if (resize_buf(d, (uint)len, 1)) { return(0); } } /* * Create a new openfile and return it */ o = malloc(sizeof(struct openfile)); if (o == 0) { return(0); } o->o_file = d; o->o_len = len; o->o_hiwrite = fslen; o->o_refs = 1; o->o_flags = 0; return(o); }
/* Select old buffer or create a new one. Defaults to previously * used buffer. */ f_selbuffer() { register char *ans; register struct buffer *b; if((b = last_buf) == cur_buf) /* If default same as current, */ if(!(b = sel_mbuf(b))) /* try to pick a more useful one. */ b = sel_nbuf(cur_buf); ans = ask("Select buffer (%s): ",b->b_name); if (ans == 0) /* he aborted */ return; if (*ans != '\0') /* Null string => use last buff */ { b = find_buf (ans); /* Else find/create one */ if (b == 0) b = make_buf (ans); } sel_buf(b); chkfree(ans); }
int get_next_line(int const fd, char **line) { static t_list *tree; t_buf *buf; t_list *cur; char *tmpline; if (line == NULL) return (-1); cur = find_buf(tree, fd); if (cur == NULL && (cur = bufnew(&tree, fd)) == NULL) return (-1); buf = cur->content; if ((tmpline = read_til_next_line(fd, buf)) == NULL) if (buf->size == 0) return (0); else return (-1); else { *line = tmpline; return (1); } }
// 计算info_hash的值 int cal_info_hash() { //找到4:info后面的字典d的结束标记e long long begin,end,pos; int push_pop = 0; //用于标记,找到d对应的e //查找4:info if(find_buf("4:info",&pos) == 1){ pos += strlen("4:info"); begin = pos; //记录info关键字对应值的开始位置 do{ if(metafile_buf[pos] == 'd'){ //字典开头 push_pop++; pos++; } else if(isdigit(metafile_buf[pos])) { int i = 0; //如果是数字,说明后面跟一个字符串 5:files 跳过:和字符串 while(isdigit(metafile_buf[pos])){ i = i * 10 + (metafile_buf[pos++] - '0'); } pos++; //pass: pos += i; //printf("***%c\n",metafile_buf[pos]); } else if(metafile_buf[pos] == 'l') //列表开头 { push_pop++; pos++; } else if(metafile_buf[pos] == 'i' && isdigit(metafile_buf[pos+1])) //说明是数字 { push_pop++; pos++; //pass:i while(isdigit(metafile_buf[pos])){ //跳过i和e之间的数字 pos++; } // printf("***%c\n",metafile_buf[pos]); // printf("push_pop = %d\n",push_pop); } else if(metafile_buf[pos == 'e']){ //如果是e push_pop-1 push_pop--; pos++; } }while(push_pop > 0); //退出循环pos指向e的下一个字符 end = pos -1; #ifdef DEBUG printf("begin = %c,end = %c,pos = %c\n",metafile_buf[begin],metafile_buf[end],metafile_buf[pos]); #endif //计算info 对应信息的hash值,保存到info_hash中,用于连接tracker和peer memset(info_hash,0,sizeof(info_hash)); SHA1_CTX context; SHA1Init(&context); SHA1Update(&context, (unsigned char *)&metafile_buf[begin], end - begin + 1); SHA1Final(info_hash,&context); #ifdef DEBUG printf("info_hash: "); int j = 0; for(;j<20;j++){ printf("%.2x",info_hash[j]); } printf("\n"); #endif }else{ printf("get info_hash fail %s:%d\n",__FILE__,__LINE__); return -1; } return 0; }
//获取文件名和文件大小,如果是多文件获取的是目录名 int get_filepath_name() { char filename[1024]; long long pos; unsigned long long len = 0;//保存路径名的长度 unsigned long long len2 = 0; filesize = 0; memset(filename,0,sizeof(filename)); //获得目录名 memset(dirname,0,sizeof(dirname)); if(find_buf("4:name",&pos) == 1) { pos += strlen("4:name"); while(isdigit(metafile_buf[pos])) { len = len*10 + (metafile_buf[pos++] - '0'); } pos++; //pass : int i; for(i = 0;i < len;i++) { dirname[i] = metafile_buf[pos++]; } dirname[i] = '\0'; //判断是否为多问文件 if(is_multi_file() == 0){ //不是多文件,获取文件长度 if(find_buf("6:length",&pos) == 1){ pos += strlen("6:length"); pos++; //跳过i while(metafile_buf[pos] != 'e' && isdigit(metafile_buf[pos])) { filesize = filesize * 10 + (metafile_buf[pos++] - '0'); } #ifdef DEBUG printf("single filesize = %lld\n",filesize); #endif } }else{ //多文件模式 filesize 为所有文件大小之和 if(find_buf("5:files",&pos) == 1){ pos += strlen("5:files"); pos++; //pass l pos++; //pass d while(metafile_buf[pos] != 'e') { len = 0; len2 = 0; memset(filename,0,sizeof(filename)); //现获取文件长度 pos += strlen("6:length"); pos++; // pass i while(isdigit(metafile_buf[pos]) && metafile_buf[pos] != 'e') { len = len *10 + (metafile_buf[pos++] - '0'); } pos++; //pass e //获取文件路径path pos += strlen("4:path"); pos++; //pass l while(isdigit(metafile_buf[pos])){ len2 = len2 *10 + (metafile_buf[pos++] - '0'); } pos++; //pass : int i; for(i = 0; i < len2;i++) { filename[i] = metafile_buf[pos++]; } filename[i] = '\0'; pos += 2; if(metafile_buf[pos] == 'd') { pos++; } filesize += len; //添加到Files链表中 add_toFiles(filename,len); } } } } return 0; }