static void handleDir(const String &dir, FileNameHandler &nameHandler, TCHAR **argv, bool recurse) { if(argv == NULL) { traverseDir(dir, nameHandler, NULL, recurse); } else { WildCardRegex filter((const TCHAR**)argv); #ifdef _DEBUG filter.dump(); #endif traverseDir(dir, nameHandler, &filter, recurse); } }
int main(int argc, char** argv){ if(argc <3){ cerr<<"Usage: ./main <path/to/target/config/file> <path/to/target/src/dir>"<<endl; cerr<<"or"<<endl; cerr<<"Usage: ./main -f <path/to/predefined/config-name/file> <path/to/target/src/dir>"<<endl; return 0; } std::vector<std::string> vec_options; vec_options.clear(); if( argc == 4 /*&& argv[1] == "-f"*/){ readOptions( vec_options, argv[2]); //从option-name.txt中读入配置名 } else{ //通过augeaus程序分析配置文件得到配置名 std::string conf_file_path = string(argv[1]); if( confilter(conf_file_path) == -1){ cerr<<"filter the option name in Config file failed"<<endl; return -1; } readOptions(vec_options, "./conf_list.dat"); } //先对每个配置项生成字典,计算熵,确定权重,具体每个词单独的字典匹配使用时再生成 std::map< std::string, double > entropy_dict; entropy_dict.clear(); calcEntropy(vec_options, entropy_dict); printf("options size : %d\n", vec_options.size()); // for(int i =0; i< vec_options.size(); i++){ // printf("%s\n", vec_options[i].c_str()); // } // for( std::map<string, double>::iterator ite=entropy_dict.begin(); ite!=entropy_dict.end(); ite++){ // printf("%s %lf\n", ite->first.c_str(), ite->second); // } vector<string> file_v; if(argc == 3) traverseDir(argv[2], file_v); else if( argc == 4) traverseDir(argv[3], file_v); printf("file_v size : %d\n", file_v.size()); string targetfile = findTargetFile(file_v, vec_options); //如果stack太小会出现cannot access to variable ...的错误 if( targetfile == ""){ cerr<<"Don't find any targetfile to analyze!"<<endl; return -1; } analyzeTargetFile(targetfile, vec_options, entropy_dict); }
//遍历要发送的文件夹,利用上面的回掉函数发送 int traverseDir(int fSock, char* fullpath, Mysnd snd) //FILENAME指定了fullpath的容量 { struct stat fst; struct dirent *dirp; char *ptr; DIR *dp; int tmp; if (lstat(fullpath, &fst)<0) { printf("\nDir: get attributes error.\n"); return -1; } if (S_ISREG(fst.st_mode)) return snd(fSock, fullpath, fst.st_size, 1); else if (S_ISDIR(fst.st_mode)) { if (snd(fSock, fullpath, 0, 2)<0) return -1; } else return -1; tmp = strlen(fullpath); ptr = fullpath + tmp; *ptr++ = '/'; //tmp+1 *ptr = '\0'; if ((dp=opendir(fullpath)) == NULL) { printf("\nDir: open error.\n"); return -1; } while ((dirp=readdir(dp)) != NULL) { if (strcmp(dirp->d_name, ".")==0 || strcmp(dirp->d_name, "..")==0) continue; strncpy(ptr, dirp->d_name, FILENAME-tmp-1); if (traverseDir(fSock, fullpath, snd)<0) return -1; } ptr[-1] = '\0'; //还原fullname snd(fSock, ".", 0, 3); if (closedir(dp) < 0) { printf("\nDir: close error.\n"); return -1; } return 0; }
static struct pcdir * findAvailableRootDirEntSlot(int fd, int32_t *clusterWithSlot) { struct pcdir *deletedEntry = NULL; struct pcdir *appendPoint = NULL; char *ignorecp = NULL; int ignore = 0; *clusterWithSlot = 0; /* * First off, try to find an erased entry in the root * directory. The root directory is an area outside of the * file space on FAT12 and FAT16 file systems. On FAT32 file * systems, the root directory is in a file area cluster just * like any other directory. */ if (!IsFAT32) { traverseFromRoot(fd, 0, PCFS_NO_SUBDIRS, PCFS_FIND_STATUS, PCD_ERASED, &deletedEntry, clusterWithSlot, &appendPoint, ignorecp, &ignore); } else { DirCount++; traverseDir(fd, TheBIOSParameterBlock.bpb32.root_dir_clust, 0, PCFS_NO_SUBDIRS, PCFS_FIND_STATUS, PCD_ERASED, &deletedEntry, clusterWithSlot, &appendPoint, ignorecp, &ignore); } /* * If we found a deleted file in the directory we'll overwrite * that entry. */ if (deletedEntry) return (deletedEntry); /* * If there is room at the end of the existing directory, we * should place the new entry there. */ if (appendPoint) return (appendPoint); /* * XXX need to grow the directory */ return (NULL); }
static void traverseDir(const String &path, FileNameHandler &nameHandler, WildCardRegex *filter, bool recurse) { DirList list = scandir(FileNameSplitter::getChildName(path,_T("*.*")),SELECTALLBUTDOT,SORTDIRLASTALPHA); nameHandler.handleStartDir(path.cstr()); for(size_t i = 0; i < list.size(); i++) { DirListEntry &e = list[i]; if(e.attrib & _A_SUBDIR) { if(recurse) { traverseDir(FileNameSplitter::getChildName(path,e.name), nameHandler, filter, recurse); } } else { if(filter && !filter->match(e.name)) { continue; } nameHandler.handleFileName(FileNameSplitter::getChildName(path,e.name).cstr(),e); } } nameHandler.handleEndDir(path.cstr()); }
void createCHKNameList(int fd) { struct pcdir *ignorep1, *ignorep2; int32_t ignore32; char *ignorecp = NULL; char ignore = '\0'; int ignoreint = 0; ignorep1 = ignorep2 = NULL; if (!OkayToRelink || CHKsList != NULL) return; /* * Allocate an array to keep a bit map of the integer * values used in CHK names. */ if ((CHKsList = (uchar_t *)calloc(1, idivceil(MAXCHKVAL, NBBY))) == NULL) { OkayToRelink = 0; return; } /* * Search the root directory for all the files with names of * the form FILEXXXX.CHK. The root directory is an area * outside of the file space on FAT12 and FAT16 file systems. * On FAT32 file systems, the root directory is in a file * area cluster just like any other directory. */ if (!IsFAT32) { traverseFromRoot(fd, 0, PCFS_NO_SUBDIRS, PCFS_FIND_CHKS, ignore, &ignorep1, &ignore32, &ignorep2, ignorecp, &ignoreint); } else { DirCount++; traverseDir(fd, TheBIOSParameterBlock.bpb32.root_dir_clust, 0, PCFS_NO_SUBDIRS, PCFS_FIND_CHKS, ignore, &ignorep1, &ignore32, &ignorep2, ignorecp, &ignoreint); } }
//文件或文件夹发送 void* sendData(void* option) { int fSock = *(int *)option; char buf[RECFRG], fileName[FILENAME]; int i, commandNo, realCount, offset, curErr; unsigned int packetNo, fileNo; filenode *preFile, *curFile; gsNode *preSend, *curSend; FILE* sfile; sigset_t mask, oldmask; free(option); // 为什么上来就free?? sigemptyset(&mask); sigaddset(&mask, SIGPIPE); if (pthread_sigmask(SIG_BLOCK, &mask, &oldmask) != 0) printf("SIG_BLOCK error.\n"); //以tcp的方式接受传输请求 for (i=0;i<4;i++) // 为什么是4次 { if (readDelimiter(fSock, buf, RECFRG, ':')<=0) { printf("Transfer cancelled.\n"); shutdown(fSock, SHUT_RDWR); return NULL; } } if (readDelimiter(fSock, buf, RECFRG, ':')<=0) { printf("Transfer cancelled.\n"); shutdown(fSock, SHUT_RDWR); return NULL; } commandNo = atoi(buf); if (!(commandNo & IPMSG_GETFILEDATA)) { printf("Invalid request.\n"); shutdown(fSock, SHUT_RDWR); return NULL; } if (readDelimiter(fSock, buf, RECFRG, ':')<=0) { printf("Transfer cancelled.\n"); shutdown(fSock, SHUT_RDWR); return NULL; } sscanf(buf, "%x", &packetNo); if (readDelimiter(fSock, buf, RECFRG, ':')<0) { printf("Transfer cancelled.\n"); shutdown(fSock, SHUT_RDWR); return NULL; } sscanf(buf, "%x", &fileNo); pthread_mutex_lock(&sendFMutex); preSend = &sendFHead; curSend = sendFHead.next; while ((curSend != NULL) && (curSend->packetNo!=packetNo || curSend->transferring==1 || curSend->cancelled==1)){ preSend = preSend->next; curSend = curSend->next; } if (curSend != NULL) { curSend->transferring = 1; curSend->tcpSock = fSock; pthread_mutex_unlock(&sendFMutex); curFile = curSend->fileList.next; preFile = &curSend->fileList; while ((curFile!=NULL) && (curFile->fileNo!=fileNo)) { preFile = preFile->next; curFile = curFile->next; } if (curFile != NULL) { getFileName(fileName, curFile->fileName, sizeof(fileName)); printf("\nStart transferring %s.\n", fileName); switch (curFile->fileType) { case 1: //发送文件 if (readDelimiter(fSock, buf, RECFRG, ':')<=0) //offset似乎没用上 { printf("Transfer cancelled.\n"); shutdown(fSock, SHUT_RDWR); return NULL; } sscanf(buf, "%x", &offset); sfile = fopen(curFile->fileName, "r"); while ((realCount = fread(buf, 1, RECFRG, sfile))>0) if (writen(fSock, buf, realCount)<0) { curErr = errno; break; } break; case 2: //发送文件夹 curErr = traverseDir(fSock, curFile->fileName, sendDir); break; default: break; } } } else pthread_mutex_unlock(&sendFMutex); pthread_mutex_lock(&sendFMutex); if ((curSend!=NULL) && (curSend->cancelled==1)) { preSend->next = curSend->next; deGsNode(curSend); free(curSend); pthread_mutex_unlock(&sendFMutex); shutdown(fSock, SHUT_RDWR); printf("Transfer canceled.\n"); return NULL; } if ((curErr<0) || (errno == ECONNRESET) || (errno == EPIPE)) //error or connection reset by peer { if (curFile!=NULL) { curSend->transferring = 0; curSend->tcpSock = -1; } pthread_mutex_unlock(&sendFMutex); shutdown(fSock, SHUT_RDWR); printf("Peer needs retransfer.\n"); return NULL; } if (curFile!=NULL) { printf("\n%s is transferred.\n", fileName); preFile->next = curFile->next; free(curFile); } if (curSend!=NULL && curSend->fileList.next == NULL) { preSend->next = curSend->next; deGsNode(curSend); free(curSend); } else if (curSend!=NULL) { curSend->transferring = 0; curSend->tcpSock = -1; } pthread_mutex_unlock(&sendFMutex); shutdown(fSock, SHUT_RDWR); }
/* * visitNodes() * * This is the main workhouse routine for traversing pcfs metadata. * There isn't a lot to the metadata. Basically there is a root * directory somewhere (either in its own special place outside the * data area or in a data cluster). The root directory (and all other * directories) are filled with a number of fixed size entries. An * entry has the filename and extension, the file's attributes, the * file's size, and the starting data cluster of the storage allocated * to the file. To determine which clusters are assigned to the file, * you start at the starting cluster entry in the FAT, and follow the * chain of entries in the FAT. * * Arguments are: * fd * descriptor for accessing the raw file system data * currentCluster * original caller supplies the initial starting cluster, * subsequent recursive calls are made with updated * cluster numbers for the sub-directories. * dirData * pointer to the directory data bytes * dirDataLen * size of the whole buffer of data bytes (usually it is * the size of a cluster, but the root directory on * FAT12/16 is not necessarily the same size as a cluster). * depth * original caller should set it to zero (assuming they are * starting from the root directory). This number is used to * change the indentation of file names presented as debug info. * descend * boolean indicates if we should descend into subdirectories. * operation * what, if any, matching should be performed. * The PCFS_TRAVERSE_ALL operation is a depth first traversal * of all nodes in the metadata tree, that tracks all the * clusters in use (according to the meta-data, at least) * matchRequired * value to be matched (if any) * found * output parameter * used to return pointer to a directory entry that matches * the search requirement * original caller should pass in a pointer to a NULL pointer. * lastDirCluster * output parameter * if no match found, last cluster num of starting directory * dirEnd * output parameter * if no match found, return parameter stores pointer to where * new directory entry could be appended to existing directory * recordPath * output parameter * as files are discovered, and directories traversed, this * buffer is used to store the current full path name. * pathLen * output parameter * this is in the integer length of the current full path name. */ static void visitNodes(int fd, int32_t currentCluster, ClusterContents *dirData, int32_t dirDataLen, int depth, int descend, int operation, char matchRequired, struct pcdir **found, int32_t *lastDirCluster, struct pcdir **dirEnd, char *recordPath, int *pathLen) { struct pcdir *longdp = NULL; struct pcdir *dp; int32_t longStart; int withinLongName = 0; int saveLen = *pathLen; dp = dirData->dirp; /* * A directory entry where the first character of the name is * PCD_UNUSED indicates the end of the directory. */ while ((uchar_t *)dp < dirData->bytes + dirDataLen && dp->pcd_filename[0] != PCD_UNUSED) { /* * Handle the special case find operations. */ searchChecks(dp, operation, matchRequired, found); if (*found) break; /* * Are we looking at part of a long file name entry? * If so, we may need to note the start of the name. * We don't do any further processing of long file * name entries. * * We also skip deleted entries and the '.' and '..' * entries. */ if ((dp->pcd_attr & PCDL_LFN_BITS) == PCDL_LFN_BITS) { if (!withinLongName) { withinLongName++; longStart = currentCluster; longdp = dp; } dp++; continue; } else if ((dp->pcd_filename[0] == PCD_ERASED) || (dp->pcd_filename[0] == '.')) { /* * XXX - if we were within a long name, then * its existence is bogus, because it is not * attached to any real file. */ withinLongName = 0; dp++; continue; } withinLongName = 0; if (operation == PCFS_TRAVERSE_ALL) catalogEntry(fd, dp, longdp, longStart, depth, recordPath, pathLen); longdp = NULL; longStart = 0; if (dp->pcd_attr & PCA_DIR && descend == PCFS_VISIT_SUBDIRS) { traverseDir(fd, extractStartCluster(dp), depth + 1, descend, operation, matchRequired, found, lastDirCluster, dirEnd, recordPath, pathLen); if (*found) break; } dp++; *pathLen = saveLen; } if (*found) return; if ((uchar_t *)dp < dirData->bytes + dirDataLen) { /* * We reached the end of directory before the end of * our provided data (a cluster). That means this cluster * is the last one in this directory's chain. It also * means we've just looked at the last directory entry. */ *lastDirCluster = currentCluster; *dirEnd = dp; return; } /* * If there is more to the directory we'll go get it otherwise we * are done traversing this directory. */ if ((currentCluster == FAKE_ROOTDIR_CLUST) || (lastInFAT(currentCluster))) { *lastDirCluster = currentCluster; return; } else { traverseDir(fd, nextInChain(currentCluster), depth, descend, operation, matchRequired, found, lastDirCluster, dirEnd, recordPath, pathLen); *pathLen = saveLen; } }
int main(int argc, char** argv) { if(argc != 3){ printf("Illegal number of arguments\n"); exit(1); } else{ char * outputFileName = argv[1]; char * inputDirName = argv[2]; FILE * ifp; //input file sream FILE * ofp; //output file stream //sl is used as a sort of "sorted keyset" for the hashmap since key values are returned //by time added, this makes sure keys are sorted SortedListPtr sl = SLCreate(compareStrings, destroyBasicTypeAlloc); hashPtr indexHash = NULL; char option = '\0'; if((ifp = fopen(inputDirName,"r+")) == NULL) if(errno == EISDIR){ //if a slash is added to the end of directory remove it //only for formatting purposes truncateSlash(inputDirName); traverseDir(inputDirName, NULL, sl, &indexHash); } else{ perror("Error encountered while trying to open file or directory"); exit(2); } else{ readsFile(ifp, inputDirName, sl, &indexHash); } if((ofp = fopen(outputFileName,"r")) == NULL){ //check if file exists if(errno == ENOENT){ //if it doesnt fclose(ofp); //close the file opened for reading ofp = fopen(outputFileName,"w"); //and create it for writing if(SortedWriteToFile(ofp, sl, &indexHash) == -2) printf("No words were found.\n"); } else{ perror("Error trying to open output file"); exit(2); } } else{ printf("File exists, override file (y/n)? "); //if it exists ask user to override scanf("%c", &option); if(option == 'y'){ fclose(ofp); ofp = fopen(outputFileName,"w"); if(SortedWriteToFile(ofp, sl, &indexHash) == -2) printf("No words were found.\n"); } } //clean mess if(ifp!=NULL) fclose(ifp); if(ofp!=NULL) fclose(ofp); clearHash(&indexHash); SLDestroy(sl); } return 0; }