//search a directory for files inside and return the number of files found and their path(nfiles,lfiles) int search_dir(char* path){ //directory information struct dirent *dp=malloc(sizeof(struct dirent)); //opens the path and check the files inside DIR *dirp = opendir(path); if(dirp){ //while opendir is not null while ((dp = readdir(dirp)) != NULL){ //exclude . and .. if(strcmp(dp->d_name,".")!=0 && strcmp(dp->d_name,"..")!=0){ //build the full path char newpath[MAXSIZEP]; strcpy(newpath,path); strcat(newpath,dp->d_name); if(dp->d_type==DT_DIR){ strcat(newpath,"/"); // recursively process the files inside the diretory search_dir(newpath); } else{ if(dp->d_type==DT_REG){ //If it is a regular file then start segmenting files and indexing blocks extract_blocks(newpath); nfiles++; } } } } } closedir(dirp); free(dp); //printf("return search dir\n"); return 0; }
void Roms::add_extsd_roms() { std::string mount_point = get_extsd_partition(); if (mount_point.empty()) { return; } std::string search_dir(mount_point); search_dir += "/multiboot"; DIR *dp = opendir(search_dir.c_str()); if (!dp) { return; } auto close_dp = util::finally([&]{ closedir(dp); }); struct stat sb; std::vector<std::shared_ptr<Rom>> temp_roms; struct dirent *ent; while ((ent = readdir(dp))) { if (strcmp(ent->d_name, "extsd-slot-") == 0 || !util::starts_with(ent->d_name, "extsd-slot-")) { continue; } std::string image(search_dir); image += "/"; image += ent->d_name; image += "/system.img"; if (stat(image.c_str(), &sb) == 0 && S_ISREG(sb.st_mode)) { temp_roms.push_back(create_rom_extsd_slot(ent->d_name + 11)); } } std::sort(temp_roms.begin(), temp_roms.end(), &cmp_rom_id); std::move(temp_roms.begin(), temp_roms.end(), std::back_inserter(roms)); }
// recursively search the help dir. // mon 2/26/98 int search_dir(string *dirs, string arg, object me, int wildcard, int wizp) { int i = sizeof(dirs), j; mixed *filenames, *sub_dir; while(i--) { filenames=get_dir(dirs[i] + arg, -1); if(pointerp(filenames) && sizeof(filenames)) { if(!wildcard && filenames[0][1]>0) { //without wildcard, filenames[0] must be the only match. //which should be the same as "dirs[i] + arg" me->start_more( read_file(dirs[i] + arg) ); return 1; } if(wildcard) { j=sizeof(filenames); while(j--) { if(filenames[j][1]>0) { write("help "+filenames[j][0]+ (wizp?" ("+dirs[i]+")":"")+ "\n"); found++; } } } } //check sub_directories if(pointerp(filenames=get_dir(dirs[i], -1))) { if(pointerp(sub_dir=filter_array(filenames, "find_sub"))) { string *dirs1=({}); j=sizeof(sub_dir); while(j--) { dirs1+=({dirs[i]+sub_dir[j][0]+"/"}); } if(search_dir(dirs1, arg, me, wildcard, wizp)==1 && !wildcard) return 1; } }
struct m_inode* search_dir(char* path,struct m_inode* inode,int cd)//查找指定目录下的路径对应目录的I节点 { char *ps=NULL; char tmp[128]= {0}; struct m_inode * tmpnode=NULL; ps=strchr(path,'/'); if(ps==NULL)//路径尾 strcpy(tmp,path); else sscanf(path,"%[^/]",tmp); if(inode->finode.mode==1) //当前为目录 { dir * dir=(struct dir*)calloc(1,sizeof(struct dir)); for(int addr=0; addr<inode->finode.addrnum; addr++)//遍历所以目录数据块 { bread(dir,inode->finode.addr[addr],0,sizeof(struct dir),1); for(int i=0; i<dir->dirNum; i++) { if(strcmp(dir->direct[i].directName,tmp)==0) { if(cd==1) curdirect=dir->direct[i]; tmpnode=iget(dir->direct[i].inodeID); tmpnode->parent=inode; break; } } if(tmpnode) break; } } if(ps!=NULL)//非路径尾 { if (tmpnode!=NULL)//查找到相应节点 return search_dir(ps+1,tmpnode,cd);//递归查找 else return NULL;//未查找到则结束// } else//路径尾 return tmpnode; }
bool search_dir(const char* texture, const char* dir, char* file) { char buf[260]; int rc; long handle; struct _finddata_t fd; //warning("Looking for '%s' in '%s'", texture, dir); sprintf(buf, "%s\\%s.*", dir, texture); for (rc = handle = _findfirst(buf, &fd); rc != -1; rc = _findnext(handle, &fd)) if (!(fd.attrib & _A_SUBDIR)) { const char* ext = fd.name + strlen(fd.name) - 4; if (!stricmp(ext, ".TGA") || !stricmp(ext, ".BMP")) { _findclose(handle); sprintf(file, "%s\\%s", dir, fd.name); return true; } } _findclose(handle); sprintf(buf, "%s\\*.*", dir); for (rc = handle = _findfirst(buf, &fd); rc != -1; rc = _findnext(handle, &fd)) if ((fd.attrib & _A_SUBDIR) && fd.name[0] != '.') { sprintf(buf, "%s\\%s", dir, fd.name); if (search_dir(texture, buf, file)) { _findclose(handle); return true; } } _findclose(handle); return false; }
/* return data block to read directory from it */ static int* traverse_dir_r(char* path){ char* path_pt; int datano = 0; //root dir at data blck zero int ino = -1; int* tuple = (int*)malloc(sizeof(int) * 2); PRINTPTR(tuple); Inode *ibuf = (Inode *)malloc(sizeof(Inode) * INODE_AMT); Inode *init_ibuf = ibuf; if(strlen(path) < 2){ tuple[0] = 2; tuple[1] = 0; return tuple; }else{ for(path_pt=strtok(path, "/"); path_pt!=NULL; path_pt=strtok(NULL, "/") ){ //find inum in the dir ino = search_dir(path_pt, datano); if(ino < 0){ printf("Unabe to find the path specify \n"); return -1; } //retreive data blck in inum if(dread(global_fd, INODE_OFFSET + (ino/INODE_AMT), init_ibuf) < 0){ RFAIL; } ibuf+=ino%INODE_AMT; if(ibuf->f_type){ datano = ibuf->block_pt[0]; } } //when finish traversing return the correct datanum free(init_ibuf); tuple[0] = ino; tuple[1] = tuple; return tuple; } }
void Roms::add_extsd_roms() { for (const std::string &mount_point : extsd_mount_points) { std::string search_dir(mount_point); search_dir += "/multiboot"; DIR *dp = opendir(search_dir.c_str()); if (!dp ) { continue; } auto close_dp = util::finally([&]{ closedir(dp); }); struct stat sb; struct dirent *ent; while ((ent = readdir(dp))) { if (strcmp(ent->d_name, "extsd-slot-") == 0 || !util::starts_with(ent->d_name, "extsd-slot-")) { continue; } std::string image(search_dir); image += "/"; image += ent->d_name; image += "/system.img"; if (stat(image.c_str(), &sb) == 0 && S_ISREG(sb.st_mode)) { roms.push_back(create_rom_extsd_slot(ent->d_name + 11)); } } break; } }
/* Routine to go up tree */ static char *recurser(char *path_buf, int path_size, dev_t root_dev, ino_t root_ino) { struct stat st; dev_t this_dev; ino_t this_ino; if (stat(path_buf, &st) < 0) return 0; this_dev = st.st_dev; this_ino = st.st_ino; if (this_dev == root_dev && this_ino == root_ino) { strcpy(path_buf, "/"); return path_buf; } if (strlen(path_buf) + 4 > path_size) { __set_errno(ERANGE); return 0; } strcat(path_buf, "/.."); if (recurser(path_buf, path_size, root_dev, root_ino) == 0) return 0; return search_dir(this_dev, this_ino, path_buf, path_size); }
int main(int argc, char **argv) { set_log_level(LOG_LEVEL_WARN); #ifdef AG_DEBUG set_log_level(LOG_LEVEL_DEBUG); int i = 0; for (i = 0; i < argc; i++) { fprintf(stderr, "%s ", argv[i]); } fprintf(stderr, "\n"); #endif char *query = NULL; char *path = NULL; int pcre_opts = 0; int study_opts = 0; const char *pcre_err = NULL; int pcre_err_offset = 0; pcre *re = NULL; pcre_extra *re_extra = NULL; struct timeval time_start, time_end; double time_diff = 0.0; gettimeofday(&time_start, NULL); parse_options(argc, argv, &query, &path); if (opts.casing == CASE_INSENSITIVE) { pcre_opts = pcre_opts | PCRE_CASELESS; } log_debug("PCRE Version: %s", pcre_version()); if (!opts.literal) { re = pcre_compile(query, pcre_opts, &pcre_err, &pcre_err_offset, NULL); if (re == NULL) { log_err("pcre_compile failed at position %i. Error: %s", pcre_err_offset, pcre_err); exit(1); } #ifdef USE_PRCE_JIT int has_jit = 0; pcre_config(PCRE_CONFIG_JIT, &has_jit); if (has_jit) { study_opts = study_opts | PCRE_STUDY_JIT_COMPILE; } #endif re_extra = pcre_study(re, study_opts, &pcre_err); if (re_extra == NULL) { log_err("pcre_study failed. Error: %s", pcre_err); exit(1); } } search_dir(re, re_extra, path, 0); if (opts.stats) { gettimeofday(&time_end, NULL); time_diff = ((long)time_end.tv_sec * 1000000 + time_end.tv_usec) - ((long)time_start.tv_sec * 1000000 + time_start.tv_usec); time_diff = time_diff / 1000000; printf("%ld files\n%ld bytes\n%f seconds\n", total_file_count, total_byte_count, time_diff); } pcre_free(re); pcre_free(re_extra); /* TODO I'm pretty sure I should call pcre_free_study() here */ free(query); free(path); cleanup_ignore_patterns(); return(0); }
/* recurse through starting directory * print out matching resources/types */ void search_dir(char *parentdir, char * dirname, struct opt_info * opts) { DIR *dir_ptr; /* an actual directory */ char currpath[PATH_MAX + 1]; int num_glob_call = 0; /* keep glob from running too many times */ if (parentdir != NULL && parentdir[0] != '\0') { /* keep current full path */ sprintf(currpath, "%s/%s", parentdir, dirname); } else { strcpy(currpath, dirname); } /* open the directory with name dirname, if not report and return * not necessarily a failure */ dir_ptr = opendir(dirname); if (!dir_ptr) { report_func_err(dirname); return; } int cherr = chdir(dirname); if (cherr != 0) { report_err("chdir", dirname); closedir(dir_ptr); // don't care about errors return; } for (;;) { struct dirent entry; struct dirent *next_dir; char *name; int err = readdir_r(dir_ptr, &entry, &next_dir); if (err != 0) { continue; } if (next_dir == NULL) { break; } name = next_dir->d_name; if ((strcmp(name, ".") == 0) || (strcmp(name, "..") == 0)) { continue; /* skip self and parents */ } else { filter_results(opts, currpath, &num_glob_call); } if (next_dir->d_type == DT_DIR) { /* only recurse thru directories */ search_dir(currpath, name, opts); /* RECURSION!!! */ } } closedir(dir_ptr); cherr = chdir(".."); if (cherr != 0) { report_err("chdir", ".."); return; } }
/** * * Given an absolute path to a file/directory * (i.e., /foo/bar ---all paths will start with the root directory, "/"), * you need to return the file attributes that is similar stat system call. * * However you don't need to fill all the attributes except file size, * file size in blocks and block size of file system. * * You can ignore the 'st_dev', 'st_blksize' and 'st_ino' fields * (FUSE ignore these values and for more information look into fuse.h file). * * For st_mode you have to send the S_IFDIR if the entry is directory * or S_IFREG if it is a simple file * * Since we are not implementing permissions, * we pass fixed values to st_uid (5), st_gid(500) entries. * * We are also not implementing hard links, * so set the st_nlinks to 3 (just as safe side). * * Its up to you to implemet the time fields (st_atime, st_mtime, st_ctime), * if didn't impement them just return current time. * * The only thing you would be returning correctly is the file size and * size in blocks (st_size, st_blocks) and file system block size (st_blksize) * * The following are common steps to implement this function: * 1. Resolve the directory path -- this * will probably involve reading each directory in the path to get * the location of the file entry (or location of data block with * the file's inode) of the specified file. * * 2. Fill the file size, file size in blocks, block size information * * You should return 0 on success or -1 on error (e.g., the path doesn't * exist). */ static int xmp_getattr(const char *path, struct stat *stbuf) { /* * I am setting some pluasible values but you can change the following to * other values. */ stbuf->st_nlink = 3; stbuf->st_uid = 5; stbuf->st_gid = 500; stbuf->st_rdev = 0; stbuf->st_atime = time(NULL); stbuf->st_mtime = time(NULL); stbuf->st_ctime = time(NULL); stbuf-> st_blksize = BLOCKSIZE; /* you have to implement the following fields correctly if (The path represents the directory) stbuf->st_mode = 0777 | S_IFDIR; else stbuf->st_mode = 0777 | S_IFREG; stbuf->st_size = // file size stbuf->st_blocks = // file size in blocks stbuf->st_blksize = // block size of you file system */ char *tok_pt; int inum = -1; int datanum = 0; //root at data blck zero //if root dir if(strlen(path) < 2 ){ Inode *root_data = (Inode*) malloc(sizeof(Inode) * INODE_AMT); Inode *initptr = root_data; if(dread(global_fd, INODE_OFFSET, root_data) < 0){ printf("Read fail at Line %d \n",__LINE__); } root_data+=2; stbuf->st_size = root_data->f_size; stbuf->st_blocks = root_data->total_blck; stbuf->st_blksize = 512; if(root_data->f_type){ stbuf->st_mode = 0777 | S_IFDIR; } datanum = root_data->block_pt[0]; //free(initptr); printf("finish fetching from root dir \n"); return 0; }else { //if dir is not root or some other dir for(tok_pt = strtok(path, "/"); tok_pt!=NULL; tok_pt=(NULL, "/")){ printf("Finding file %s of the path: %s \n", tok_pt, path); if(strlen(tok_pt) < 2){ break; } Directory *my_dir = (Directory*)malloc(sizeof(Directory) * DIR_AMT); Directory *init_dir = my_dir; if(dread(global_fd, DATA_OFFSET + datanum, my_dir) < 0){ printf("Read fail at datablck %d \n", datanum); return -1; } //search the directory if((inum = search_dir(tok_pt, datanum)) < 0){ printf("Unable to find the file in dir\n"); return -2; } Inode *ibuf = (Inode*)malloc(sizeof(Inode) * INODE_AMT); Inode *init_ibuf = ibuf; if(dread(global_fd, INODE_OFFSET + inum/INODE_AMT , init_ibuf) < 0){ printf("Read inode fail at inum blck: %d, @Line: %d \n", INODE_OFFSET+ inum/INODE_AMT , __LINE__ ); return -1; } ibuf+= inum % INODE_AMT; printf("Pull from inum number %d, pointing to: %d and inode amt: %d \n" ,inum, inum%INODE_AMT, INODE_AMT); stbuf->st_size = ibuf->f_size; stbuf->st_blocks = ibuf->total_blck; stbuf->st_blksize = 512; printf("Assigning file type: %d from inum %d \n", ibuf->f_type, ibuf->inode_num); if(ibuf->f_type){ printf("This dir is a directory \n"); stbuf->st_mode = 0777 | S_IFDIR; datanum = ibuf->block_pt[0]; }else { printf("This dir is just a regular file\n"); stbuf->st_mode = 0777 | S_IFREG; } DEBUG_ME; } } printf("finish fetching from %s \n", path); return 0; }
/*===========================================================================* * do_rename * *===========================================================================*/ PUBLIC int do_rename() { /* Perform the rename(name1, name2) system call. */ struct inode *old_dirp, *old_ip; /* ptrs to old dir, file inodes */ struct inode *new_dirp, *new_ip; /* ptrs to new dir, file inodes */ struct inode *new_superdirp, *next_new_superdirp; int r = OK; /* error flag; initially no error */ int odir, ndir; /* TRUE iff {old|new} file is dir */ int same_pdir; /* TRUE iff parent dirs are the same */ char old_name[NAME_MAX], new_name[NAME_MAX]; ino_t numb; int r1; /* See if 'name1' (existing file) exists. Get dir and file inodes. */ if (fetch_name(m_in.name1, m_in.name1_length, M1) != OK) return(err_code); if ( (old_dirp = last_dir(user_path, old_name))==NIL_INODE) return(err_code); if ( (old_ip = advance(old_dirp, old_name)) == NIL_INODE) r = err_code; /* See if 'name2' (new name) exists. Get dir and file inodes. */ if (fetch_name(m_in.name2, m_in.name2_length, M1) != OK) r = err_code; if ( (new_dirp = last_dir(user_path, new_name)) == NIL_INODE) r = err_code; new_ip = advance(new_dirp, new_name); /* not required to exist */ if (old_ip != NIL_INODE) odir = ((old_ip->i_mode & I_TYPE) == I_DIRECTORY); /* TRUE iff dir */ /* If it is ok, check for a variety of possible errors. */ if (r == OK) { same_pdir = (old_dirp == new_dirp); /* The old inode must not be a superdirectory of the new last dir. */ if (odir && !same_pdir) { dup_inode(new_superdirp = new_dirp); while (TRUE) { /* may hang in a file system loop */ if (new_superdirp == old_ip) { r = EINVAL; break; } next_new_superdirp = advance(new_superdirp, dot2); put_inode(new_superdirp); if (next_new_superdirp == new_superdirp) break; /* back at system root directory */ new_superdirp = next_new_superdirp; if (new_superdirp == NIL_INODE) { /* Missing ".." entry. Assume the worst. */ r = EINVAL; break; } } put_inode(new_superdirp); } /* The old or new name must not be . or .. */ if (strcmp(old_name, ".")==0 || strcmp(old_name, "..")==0 || strcmp(new_name, ".")==0 || strcmp(new_name, "..")==0) r = EINVAL; /* Both parent directories must be on the same device. */ if (old_dirp->i_dev != new_dirp->i_dev) r = EXDEV; /* Parent dirs must be writable, searchable and on a writable device */ if ((r1 = forbidden(old_dirp, W_BIT | X_BIT)) != OK || (r1 = forbidden(new_dirp, W_BIT | X_BIT)) != OK) r = r1; /* Some tests apply only if the new path exists. */ if (new_ip == NIL_INODE) { /* don't rename a file with a file system mounted on it. */ if (old_ip->i_dev != old_dirp->i_dev) r = EXDEV; if (odir && new_dirp->i_nlinks >= (new_dirp->i_sp->s_version == V1 ? CHAR_MAX : SHRT_MAX) && !same_pdir && r == OK) r = EMLINK; } else { if (old_ip == new_ip) r = SAME; /* old=new */ /* has the old file or new file a file system mounted on it? */ if (old_ip->i_dev != new_ip->i_dev) r = EXDEV; ndir = ((new_ip->i_mode & I_TYPE) == I_DIRECTORY); /* dir ? */ if (odir == TRUE && ndir == FALSE) r = ENOTDIR; if (odir == FALSE && ndir == TRUE) r = EISDIR; } } /* If a process has another root directory than the system root, we might * "accidently" be moving it's working directory to a place where it's * root directory isn't a super directory of it anymore. This can make * the function chroot useless. If chroot will be used often we should * probably check for it here. */ /* The rename will probably work. Only two things can go wrong now: * 1. being unable to remove the new file. (when new file already exists) * 2. being unable to make the new directory entry. (new file doesn't exists) * [directory has to grow by one block and cannot because the disk * is completely full]. */ if (r == OK) { if (new_ip != NIL_INODE) { /* There is already an entry for 'new'. Try to remove it. */ if (odir) r = remove_dir(new_dirp, new_ip, new_name); else r = unlink_file(new_dirp, new_ip, new_name); } /* if r is OK, the rename will succeed, while there is now an * unused entry in the new parent directory. */ } if (r == OK) { /* If the new name will be in the same parent directory as the old one, * first remove the old name to free an entry for the new name, * otherwise first try to create the new name entry to make sure * the rename will succeed. */ numb = old_ip->i_num; /* inode number of old file */ if (same_pdir) { r = search_dir(old_dirp, old_name, (ino_t *) 0, DELETE); /* shouldn't go wrong. */ if (r==OK) (void) search_dir(old_dirp, new_name, &numb, ENTER); } else { r = search_dir(new_dirp, new_name, &numb, ENTER); if (r == OK) (void) search_dir(old_dirp, old_name, (ino_t *) 0, DELETE); } } /* If r is OK, the ctime and mtime of old_dirp and new_dirp have been marked * for update in search_dir. */ if (r == OK && odir && !same_pdir) { /* Update the .. entry in the directory (still points to old_dirp). */ numb = new_dirp->i_num; (void) unlink_file(old_ip, NIL_INODE, dot2); if (search_dir(old_ip, dot2, &numb, ENTER) == OK) { /* New link created. */ new_dirp->i_nlinks++; new_dirp->i_dirt = DIRTY; } } /* Release the inodes. */ put_inode(old_dirp); put_inode(old_ip); put_inode(new_dirp); put_inode(new_ip); return(r == SAME ? OK : r); }
/*===========================================================================* * do_link * *===========================================================================*/ PUBLIC int do_link() { /* Perform the link(name1, name2) system call. */ register struct inode *ip, *rip; register int r; char string[NAME_MAX]; struct inode *new_ip; /* See if 'name' (file to be linked) exists. */ if (fetch_name(m_in.name1, m_in.name1_length, M1) != OK) return(err_code); if ( (rip = eat_path(user_path)) == NIL_INODE) return(err_code); /* Check to see if the file has maximum number of links already. */ r = OK; if (rip->i_nlinks >= (rip->i_sp->s_version == V1 ? CHAR_MAX : SHRT_MAX)) r = EMLINK; /* Only super_user may link to directories. */ if (r == OK) if ( (rip->i_mode & I_TYPE) == I_DIRECTORY && !super_user) r = EPERM; /* If error with 'name', return the inode. */ if (r != OK) { put_inode(rip); return(r); } /* Does the final directory of 'name2' exist? */ if (fetch_name(m_in.name2, m_in.name2_length, M1) != OK) { put_inode(rip); return(err_code); } if ( (ip = last_dir(user_path, string)) == NIL_INODE) r = err_code; /* If 'name2' exists in full (even if no space) set 'r' to error. */ if (r == OK) { if ( (new_ip = advance(ip, string)) == NIL_INODE) { r = err_code; if (r == ENOENT) r = OK; } else { put_inode(new_ip); r = EEXIST; } } /* Check for links across devices. */ if (r == OK) if (rip->i_dev != ip->i_dev) r = EXDEV; /* Try to link. */ if (r == OK) r = search_dir(ip, string, &rip->i_num, ENTER); /* If success, register the linking. */ if (r == OK) { rip->i_nlinks++; rip->i_update |= CTIME; rip->i_dirt = DIRTY; } /* Done. Release both inodes. */ put_inode(rip); put_inode(ip); return(r); }
// TODOs: // 1. Open directory file // 2. Search for a file with given name // Return -1 if not found. // 3. Get descriptor number of the found file // 4. Looking for unoccupied entry in open file table. // Return -2 if all entry are occupied. // 5. Initialize the entry (descriptor number, current position, etc.) // 6. Return entry number int FileSystem53::open(string symbolic_file_name) { //print_oft(); if ( symbolic_file_name.size() > 10 ) { //cout << "[email protected](): filename size of boundary" << endl; return -1; } // search the direcotry to find the filename and its corresponding index int desc_index = search_dir(0, symbolic_file_name); if ( desc_index < 0 || desc_index > MAX_FILE_NO ) { //cout << "[email protected](): descriptor index " << desc_index << " out of boundary" << endl; return -1; } int oft_index = open_desc(desc_index); oft[oft_index][0] = desc_index; oft[oft_index][OFT_CURRENT_POSITION_INDEX] = 6; //cout << "desc_index = " << desc_index << endl; //print_oft(); // problem here for updating length and cursors; int cursor = oft[oft_index][OFT_CURRENT_POSITION_INDEX]; char block_buffer[B]; int block_count = 0; int next_pos = 0; while ( oft[oft_index][1] > 0 ) { if ( next_pos > oft[oft_index][1] ) break; //oft[oft_index][1] = 0; for (int i = 1; i < DESCR_SIZE; i++) { int block_index = oft[oft_index][i+1]; //cout << "block_index = " << block_index << endl; if ( block_index != 0 ) { iosystem->read_block(block_index, block_buffer); //print_oft(); // write to oft buffer for (int j = 0; j < B; j++) { next_pos = OFT_CURRENT_POSITION_INDEX + j + 1 + block_count * 64; oft[oft_index][next_pos] = (int)block_buffer[j]; if ( (int)block_buffer[j] == -1 ) break; /* //cout << "block_buffer[" << i << "] = " << (int)block_buffer[i] << endl; int tmp = fputc((int)block_buffer[i], oft_index); if ( tmp == -2 ) break; */ } block_count++; //print_oft(); } } } //print_oft(); return oft_index; }
int main(int argc, char **argv) { char **base_paths = NULL; char **paths = NULL; int i; int pcre_opts = PCRE_MULTILINE; int study_opts = 0; double time_diff; worker_t *workers = NULL; int workers_len; int num_cores; #ifdef KJK_BUILD extern void setup_crash_handler(); /* in kjk_crash_handler.cpp */ setup_crash_handler(); #endif set_log_level(LOG_LEVEL_WARN); work_queue = NULL; work_queue_tail = NULL; memset(&stats, 0, sizeof(stats)); root_ignores = init_ignore(NULL, "", 0); out_fd = stdout; #ifdef USE_PCRE_JIT int has_jit = 0; pcre_config(PCRE_CONFIG_JIT, &has_jit); if (has_jit) { study_opts |= PCRE_STUDY_JIT_COMPILE; } #endif gettimeofday(&(stats.time_start), NULL); parse_options(argc, argv, &base_paths, &paths); log_debug("PCRE Version: %s", pcre_version()); #ifdef _WIN32 { SYSTEM_INFO si; GetSystemInfo(&si); num_cores = si.dwNumberOfProcessors; } #else num_cores = (int)sysconf(_SC_NPROCESSORS_ONLN); #endif workers_len = num_cores; if (opts.literal) { workers_len--; } if (opts.workers) { workers_len = opts.workers; } if (workers_len < 1) { workers_len = 1; } log_debug("Using %i workers", workers_len); done_adding_files = FALSE; workers = (worker_t *) ag_calloc(workers_len, sizeof(worker_t)); if (pthread_cond_init(&files_ready, NULL)) { die("pthread_cond_init failed!"); } if (pthread_mutex_init(&print_mtx, NULL)) { die("pthread_mutex_init failed!"); } if (pthread_mutex_init(&stats_mtx, NULL)) { die("pthread_mutex_init failed!"); } if (pthread_mutex_init(&work_queue_mtx, NULL)) { die("pthread_mutex_init failed!"); } if (opts.casing == CASE_SMART) { opts.casing = is_lowercase(opts.query) ? CASE_INSENSITIVE : CASE_SENSITIVE; } if (opts.literal) { if (opts.casing == CASE_INSENSITIVE) { /* Search routine needs the query to be lowercase */ char *c = opts.query; for (; *c != '\0'; ++c) { *c = (char)tolower(*c); } } generate_alpha_skip(opts.query, opts.query_len, alpha_skip_lookup, opts.casing == CASE_SENSITIVE); find_skip_lookup = NULL; generate_find_skip(opts.query, opts.query_len, &find_skip_lookup, opts.casing == CASE_SENSITIVE); if (opts.word_regexp) { init_wordchar_table(); opts.literal_starts_wordchar = is_wordchar(opts.query[0]); opts.literal_ends_wordchar = is_wordchar(opts.query[opts.query_len - 1]); } } else { if (opts.casing == CASE_INSENSITIVE) { pcre_opts |= PCRE_CASELESS; } if (opts.word_regexp) { char *word_regexp_query; ag_asprintf(&word_regexp_query, "\\b%s\\b", opts.query); free(opts.query); opts.query = word_regexp_query; opts.query_len = strlen(opts.query); } compile_study(&opts.re, &opts.re_extra, opts.query, pcre_opts, study_opts); } if (opts.search_stream) { // search_stream(stdin, ""); } else { for (i = 0; i < workers_len; i++) { workers[i].id = i; int rv = pthread_create(&(workers[i].thread), NULL, &search_file_worker, &(workers[i].id)); if (rv != 0) { die("error in pthread_create(): %s", strerror(rv)); } #if defined(HAVE_PTHREAD_SETAFFINITY_NP) && defined(USE_CPU_SET) if (opts.use_thread_affinity) { cpu_set_t cpu_set; CPU_ZERO(&cpu_set); CPU_SET(i % num_cores, &cpu_set); rv = pthread_setaffinity_np(workers[i].thread, sizeof(cpu_set), &cpu_set); if (rv != 0) { die("error in pthread_setaffinity_np(): %s", strerror(rv)); } log_debug("Thread %i set to CPU %i", i, i); } else { log_debug("Thread affinity disabled."); } #else log_debug("No CPU affinity support."); #endif } for (i = 0; paths[i] != NULL; i++) { log_debug("searching path %s for %s", paths[i], opts.query); symhash = NULL; ignores *ig = init_ignore(root_ignores, "", 0); struct stat s; s.st_dev = 0; #ifndef _WIN32 /* The device is ignored if opts.one_dev is false, so it's fine * to leave it at the default 0 */ if (opts.one_dev && lstat(paths[i], &s) == -1) { log_err("Failed to get device information for path %s. Skipping...", paths[i]); } #endif search_dir(ig, base_paths[i], paths[i], 0, s.st_dev); cleanup_ignore(ig); } pthread_mutex_lock(&work_queue_mtx); done_adding_files = TRUE; pthread_cond_broadcast(&files_ready); pthread_mutex_unlock(&work_queue_mtx); for (i = 0; i < workers_len; i++) { if (pthread_join(workers[i].thread, NULL)) { die("pthread_join failed!"); } } } if (opts.stats) { gettimeofday(&(stats.time_end), NULL); time_diff = ((long)stats.time_end.tv_sec * 1000000 + stats.time_end.tv_usec) - ((long)stats.time_start.tv_sec * 1000000 + stats.time_start.tv_usec); time_diff /= 1000000; printf("%ld matches\n%ld files searched\n%ld bytes searched\n%f seconds\n", stats.total_matches, stats.total_files, stats.total_bytes, time_diff); } if (opts.pager) { pclose(out_fd); } cleanup_options(); pthread_cond_destroy(&files_ready); pthread_mutex_destroy(&work_queue_mtx); pthread_mutex_destroy(&stats_mtx); pthread_mutex_destroy(&print_mtx); cleanup_ignore(root_ignores); free(workers); for (i = 0; paths[i] != NULL; i++) { free(paths[i]); free(base_paths[i]); } free(base_paths); free(paths); if (find_skip_lookup) { free(find_skip_lookup); } return !opts.match_found; }
int main(int argc, char **argv) { char **paths = NULL; int i; int pcre_opts = PCRE_MULTILINE; int study_opts = 0; double time_diff; pthread_t *workers = NULL; int workers_len; set_log_level(LOG_LEVEL_WARN); work_queue = NULL; work_queue_tail = NULL; memset(&stats, 0, sizeof(stats)); root_ignores = init_ignore(NULL); out_fd = stdout; #ifdef USE_PCRE_JIT int has_jit = 0; pcre_config(PCRE_CONFIG_JIT, &has_jit); if (has_jit) { study_opts |= PCRE_STUDY_JIT_COMPILE; } #endif gettimeofday(&(stats.time_start), NULL); parse_options(argc, argv, &paths); log_debug("PCRE Version: %s", pcre_version()); if (opts.workers) { workers_len = opts.workers; } else { /* Experiments show that two worker threads appear to be optimal, both * on dual-core and quad-core systems. See * http://geoff.greer.fm/2012/09/07/the-silver-searcher-adding-pthreads/. * On single-core CPUs, more than one worker thread makes no sense. */ int ncpus = (int)sysconf(_SC_NPROCESSORS_ONLN); workers_len = (ncpus >= 2) ? 2 : 1; } log_debug("Using %i workers", workers_len); done_adding_files = FALSE; workers = ag_calloc(workers_len, sizeof(pthread_t)); if (pthread_cond_init(&files_ready, NULL)) { log_err("pthread_cond_init failed!"); exit(2); } if (pthread_mutex_init(&print_mtx, NULL)) { log_err("pthread_mutex_init failed!"); exit(2); } if (pthread_mutex_init(&stats_mtx, NULL)) { log_err("pthread_mutex_init failed!"); exit(2); } if (pthread_mutex_init(&work_queue_mtx, NULL)) { log_err("pthread_mutex_init failed!"); exit(2); } if (opts.casing == CASE_SMART) { opts.casing = contains_uppercase(opts.query) ? CASE_SENSITIVE : CASE_INSENSITIVE; } if (opts.literal) { if (opts.casing == CASE_INSENSITIVE) { /* Search routine needs the query to be lowercase */ char *c = opts.query; for (; *c != '\0'; ++c) { *c = (char) tolower(*c); } } generate_skip_lookup(opts.query, opts.query_len, skip_lookup, opts.casing == CASE_SENSITIVE); if (opts.word_regexp) { init_wordchar_table(); opts.literal_starts_wordchar = is_wordchar(opts.query[0]); opts.literal_ends_wordchar = is_wordchar(opts.query[opts.query_len - 1]); } } else { if (opts.casing == CASE_INSENSITIVE) { pcre_opts = pcre_opts | PCRE_CASELESS; } if (opts.word_regexp) { char *word_regexp_query; asprintf(&word_regexp_query, "\\b%s\\b", opts.query); free(opts.query); opts.query = word_regexp_query; opts.query_len = strlen(opts.query); } compile_study(&opts.re, &opts.re_extra, opts.query, pcre_opts, study_opts); } if (opts.search_stream) { search_stream(stdin, ""); } else { for (i = 0; i < workers_len; i++) { int ptc_rc = pthread_create(&(workers[i]), NULL, &search_file_worker, NULL); check_err(ptc_rc, "create worker thread"); } for (i = 0; paths[i] != NULL; i++) { log_debug("searching path %s for %s", paths[i], opts.query); search_dir(root_ignores, paths[i], 0); } done_adding_files = TRUE; pthread_cond_broadcast(&files_ready); for (i = 0; i < workers_len; i++) { if (pthread_join(workers[i], NULL)) { log_err("pthread_join failed!"); exit(2); } } } if (opts.stats) { gettimeofday(&(stats.time_end), NULL); time_diff = ((long)stats.time_end.tv_sec * 1000000 + stats.time_end.tv_usec) - ((long)stats.time_start.tv_sec * 1000000 + stats.time_start.tv_usec); time_diff /= 1000000; printf("%ld matches\n%ld files searched\n%ld bytes searched\n%f seconds\n", stats.total_matches, stats.total_files, stats.total_bytes, time_diff); } if (opts.pager) { pclose(out_fd); } pthread_cond_destroy(&files_ready); pthread_mutex_destroy(&work_queue_mtx); pthread_mutex_destroy(&stats_mtx); pthread_mutex_destroy(&print_mtx); cleanup_ignore(root_ignores); free(workers); free(paths); return 0; }
/* Return the absolute name of executable file PROG, including any file extensions. If an absolute name for PROG cannot be found, return NULL. */ char * make_absolute (char *prog) { char absname[MAX_PATH]; char dir[MAX_PATH]; char curdir[MAX_PATH]; char *p, *fname; char *path; int i; /* At least partial absolute path specified; search there. */ if ((isalpha (prog[0]) && prog[1] == ':') || (prog[0] == '\\')) { /* Split the directory from the filename. */ fname = strrchr (prog, '\\'); if (!fname) /* Only a drive specifier is given. */ fname = prog + 2; strncpy (dir, prog, fname - prog); dir[fname - prog] = '\0'; /* Search the directory for the program. */ if (search_dir (dir, prog, MAX_PATH, absname) > 0) return strdup (absname); else return NULL; } if (GetCurrentDirectory (MAX_PATH, curdir) <= 0) return NULL; /* Relative path; search in current dir. */ if (strpbrk (prog, "\\")) { if (search_dir (curdir, prog, MAX_PATH, absname) > 0) return strdup (absname); else return NULL; } /* Just filename; search current directory then PATH. */ path = alloca (strlen (getenv ("PATH")) + strlen (curdir) + 2); strcpy (path, curdir); strcat (path, ";"); strcat (path, getenv ("PATH")); while (*path) { /* Get next directory from path. */ p = path; while (*p && *p != ';') p++; strncpy (dir, path, p - path); dir[p - path] = '\0'; /* Search the directory for the program. */ if (search_dir (dir, prog, MAX_PATH, absname) > 0) return strdup (absname); /* Move to the next directory. */ path = p + 1; } return NULL; }
/* TODO: append matches to some data structure instead of just printing them out * then there can be sweet summaries of matches/files scanned/time/etc */ void search_dir(const pcre *re, const pcre_extra *re_extra, const char* path, const int depth) { struct dirent **dir_list = NULL; struct dirent *dir = NULL; int results = 0; int fd = -1; off_t f_len = 0; char *buf = NULL; char *dir_full_path = NULL; size_t path_length = 0; int i; /* find agignore/gitignore/hgignore/etc files to load ignore patterns from */ #ifdef AG_OS_BSD results = scandir(path, &dir_list, &ignorefile_filter, &alphasort); #else results = scandir(path, &dir_list, (int (*)(const struct dirent *))&ignorefile_filter, &alphasort); #endif if (results > 0) { for (i = 0; i < results; i++) { dir = dir_list[i]; path_length = (size_t)(strlen(path) + strlen(dir->d_name) + 2); /* 2 for slash and null char */ dir_full_path = malloc(path_length); strlcpy(dir_full_path, path, path_length); strlcat(dir_full_path, "/", path_length); strlcat(dir_full_path, dir->d_name, path_length); load_ignore_patterns(dir_full_path); free(dir); dir = NULL; free(dir_full_path); dir_full_path = NULL; } } free(dir_list); dir_list = NULL; #ifdef AG_OS_BSD results = scandir(path, &dir_list, &filename_filter, &alphasort); #else results = scandir(path, &dir_list, (int (*)(const struct dirent *))&filename_filter, &alphasort); #endif if (results == 0) { log_debug("No results found in directory %s", path); free(dir_list); dir_list = NULL; return; } else if (results == -1) { if (errno == ENOTDIR) { /* Not a directory. Probably a file. */ /* If we're only searching one file, don't print the filename header at the top. */ opts.print_heading = depth == 0 ? -1 : opts.print_heading; search_file(re, re_extra, path); return; } else { log_err("Error opening directory %s: %s", path, strerror(errno)); return; } } int offset_vector[3]; int rc = 0; for (i=0; i<results; i++) { dir = dir_list[i]; /* TODO: this is copy-pasted from about 30 lines above */ path_length = (size_t)(strlen(path) + strlen(dir->d_name) + 2); /* 2 for slash and null char */ dir_full_path = malloc(path_length); strlcpy(dir_full_path, path, path_length); strlcat(dir_full_path, "/", path_length); strlcat(dir_full_path, dir->d_name, path_length); log_debug("dir %s type %i", dir_full_path, dir->d_type); if (opts.file_search_regex) { rc = pcre_exec(opts.file_search_regex, NULL, dir_full_path, strlen(dir_full_path), 0, 0, offset_vector, 3); if (rc < 0) { /* no match */ log_debug("Skipping %s due to file_search_regex.", dir_full_path); goto cleanup; } } /* TODO: scan files in current dir before going deeper */ if (dir->d_type == DT_DIR) { if (opts.recurse_dirs) { if (depth < opts.max_search_depth) { log_debug("Searching dir %s", dir_full_path); search_dir(re, re_extra, dir_full_path, depth + 1); } else { log_err("Skipping %s. Use the --depth option to search deeper.", dir_full_path); } } goto cleanup; } search_file(re, re_extra, dir_full_path); cleanup: if (fd != -1) { munmap(buf, f_len); close(fd); fd = -1; } free(dir); dir = NULL; free(dir_full_path); dir_full_path = NULL; } free(dir_list); dir_list = NULL; return; }
static void search_dir(struct snapraid_state* state, struct snapraid_disk* disk, const char* dir, const char* sub) { DIR* d; d = opendir(dir); if (!d) { /* LCOV_EXCL_START */ msg_error("Error opening directory '%s'. %s.\n", dir, strerror(errno)); exit(EXIT_FAILURE); /* LCOV_EXCL_STOP */ } while (1) { char path_next[PATH_MAX]; char sub_next[PATH_MAX]; char out[PATH_MAX]; struct snapraid_filter* reason = 0; struct stat st; const char* name; struct dirent* dd; /* clear errno to detect erroneous conditions */ errno = 0; dd = readdir(d); if (dd == 0 && errno != 0) { /* LCOV_EXCL_START */ msg_error("Error reading directory '%s'. %s.\n", dir, strerror(errno)); exit(EXIT_FAILURE); /* LCOV_EXCL_STOP */ } if (dd == 0) { break; /* finished */ } /* skip "." and ".." files */ name = dd->d_name; if (name[0] == '.' && (name[1] == 0 || (name[1] == '.' && name[2] == 0))) continue; pathprint(path_next, sizeof(path_next), "%s%s", dir, name); pathprint(sub_next, sizeof(sub_next), "%s%s", sub, name); /* exclude hidden files even before calling lstat() */ if (disk != 0 && filter_hidden(state->filter_hidden, dd) != 0) { msg_verbose("Excluding hidden '%s'\n", path_next); continue; } /* exclude content files even before calling lstat() */ if (disk != 0 && filter_content(&state->contentlist, path_next) != 0) { msg_verbose("Excluding content '%s'\n", path_next); continue; } #if HAVE_STRUCT_DIRENT_D_STAT /* convert dirent to lstat result */ dirent_lstat(dd, &st); /* if the st_mode field is missing, takes care to fill it using normal lstat() */ /* at now this can happen only in Windows (with HAVE_STRUCT_DIRENT_D_STAT defined), */ /* because we use a directory reading method that doesn't read info about ReparsePoint. */ /* Note that here we cannot call here lstat_sync(), because we don't know what kind */ /* of file is it, and lstat_sync() doesn't always work */ if (st.st_mode == 0) { if (lstat(path_next, &st) != 0) { /* LCOV_EXCL_START */ msg_error("Error in stat file/directory '%s'. %s.\n", path_next, strerror(errno)); exit(EXIT_FAILURE); /* LCOV_EXCL_STOP */ } } #else /* get lstat info about the file */ if (lstat(path_next, &st) != 0) { /* LCOV_EXCL_START */ msg_error("Error in stat file/directory '%s'. %s.\n", path_next, strerror(errno)); exit(EXIT_FAILURE); /* LCOV_EXCL_STOP */ } #endif if (S_ISREG(st.st_mode)) { if (disk == 0 || filter_path(&state->filterlist, &reason, disk->name, sub_next) == 0) { search_file(state, path_next, st.st_size, st.st_mtime, STAT_NSEC(&st)); } else { msg_verbose("Excluding link '%s' for rule '%s'\n", path_next, filter_type(reason, out, sizeof(out))); } } else if (S_ISDIR(st.st_mode)) { if (disk == 0 || filter_dir(&state->filterlist, &reason, disk->name, sub_next) == 0) { pathslash(path_next, sizeof(path_next)); pathslash(sub_next, sizeof(sub_next)); search_dir(state, disk, path_next, sub_next); } else { msg_verbose("Excluding directory '%s' for rule '%s'\n", path_next, filter_type(reason, out, sizeof(out))); } } } if (closedir(d) != 0) { /* LCOV_EXCL_START */ msg_error("Error closing directory '%s'. %s.\n", dir, strerror(errno)); exit(EXIT_FAILURE); /* LCOV_EXCL_STOP */ } }
int main(int argc, char **argv) { char **base_paths = NULL; char **paths = NULL; int i; int pcre_opts = PCRE_MULTILINE; int study_opts = 0; double time_diff; pthread_t *workers = NULL; int workers_len; set_log_level(LOG_LEVEL_WARN); work_queue = NULL; work_queue_tail = NULL; memset(&stats, 0, sizeof(stats)); root_ignores = init_ignore(NULL, "", 0); out_fd = stdout; #ifdef USE_PCRE_JIT int has_jit = 0; pcre_config(PCRE_CONFIG_JIT, &has_jit); if (has_jit) { study_opts |= PCRE_STUDY_JIT_COMPILE; } #endif gettimeofday(&(stats.time_start), NULL); parse_options(argc, argv, &base_paths, &paths); log_debug("PCRE Version: %s", pcre_version()); #ifdef _WIN32 { SYSTEM_INFO si; GetSystemInfo(&si); workers_len = si.dwNumberOfProcessors; } #else workers_len = (int)sysconf(_SC_NPROCESSORS_ONLN); #endif if (opts.literal) { workers_len--; } if (opts.workers) { workers_len = opts.workers; } if (workers_len < 1) { workers_len = 1; } log_debug("Using %i workers", workers_len); done_adding_files = FALSE; workers = ag_calloc(workers_len, sizeof(pthread_t)); if (pthread_cond_init(&files_ready, NULL)) { die("pthread_cond_init failed!"); } if (pthread_mutex_init(&print_mtx, NULL)) { die("pthread_mutex_init failed!"); } if (pthread_mutex_init(&stats_mtx, NULL)) { die("pthread_mutex_init failed!"); } if (pthread_mutex_init(&work_queue_mtx, NULL)) { die("pthread_mutex_init failed!"); } if (opts.casing == CASE_SMART) { opts.casing = is_lowercase(opts.query) ? CASE_INSENSITIVE : CASE_SENSITIVE; } if (opts.literal) { if (opts.casing == CASE_INSENSITIVE) { /* Search routine needs the query to be lowercase */ char *c = opts.query; for (; *c != '\0'; ++c) { *c = (char)tolower(*c); } } generate_alpha_skip(opts.query, opts.query_len, alpha_skip_lookup, opts.casing == CASE_SENSITIVE); find_skip_lookup = NULL; generate_find_skip(opts.query, opts.query_len, &find_skip_lookup, opts.casing == CASE_SENSITIVE); if (opts.word_regexp) { init_wordchar_table(); opts.literal_starts_wordchar = is_wordchar(opts.query[0]); opts.literal_ends_wordchar = is_wordchar(opts.query[opts.query_len - 1]); } } else { if (opts.casing == CASE_INSENSITIVE) { pcre_opts |= PCRE_CASELESS; } if (opts.word_regexp) { char *word_regexp_query; ag_asprintf(&word_regexp_query, "\\b%s\\b", opts.query); free(opts.query); opts.query = word_regexp_query; opts.query_len = strlen(opts.query); } compile_study(&opts.re, &opts.re_extra, opts.query, pcre_opts, study_opts); } if (opts.search_stream) { search_stream(stdin, ""); } else { for (i = 0; i < workers_len; i++) { int rv = pthread_create(&(workers[i]), NULL, &search_file_worker, &i); if (rv != 0) { die("error in pthread_create(): %s", strerror(rv)); } } for (i = 0; paths[i] != NULL; i++) { log_debug("searching path %s for %s", paths[i], opts.query); symhash = NULL; ignores *ig = init_ignore(root_ignores, "", 0); search_dir(ig, base_paths[i], paths[i], 0); cleanup_ignore(ig); } pthread_mutex_lock(&work_queue_mtx); done_adding_files = TRUE; pthread_cond_broadcast(&files_ready); pthread_mutex_unlock(&work_queue_mtx); for (i = 0; i < workers_len; i++) { if (pthread_join(workers[i], NULL)) { die("pthread_join failed!"); } } } if (opts.stats) { gettimeofday(&(stats.time_end), NULL); time_diff = ((long)stats.time_end.tv_sec * 1000000 + stats.time_end.tv_usec) - ((long)stats.time_start.tv_sec * 1000000 + stats.time_start.tv_usec); time_diff /= 1000000; printf("%ld matches\n%ld files searched\n%ld bytes searched\n%f seconds\n", stats.total_matches, stats.total_files, stats.total_bytes, time_diff); } if (opts.pager) { pclose(out_fd); } cleanup_options(); pthread_cond_destroy(&files_ready); pthread_mutex_destroy(&work_queue_mtx); pthread_mutex_destroy(&stats_mtx); pthread_mutex_destroy(&print_mtx); cleanup_ignore(root_ignores); free(workers); for (i = 0; paths[i] != NULL; i++) { free(paths[i]); free(base_paths[i]); } free(base_paths); free(paths); if (find_skip_lookup) { free(find_skip_lookup); } return !opts.match_found; }
static int search_dir(char *abs_dir_name, void (*update_func)(char *filename, char *dirname), struct z_story_list *story_list, bool recursive, struct babel_info *babel) { z_dir *current_dir; struct z_dir_ent z_dir_entry; char *dirname = NULL; int dirname_size = 0; int len; char *cwd = fsi->get_cwd(); TRACE_LOG("Trying to readdir \"%s\".\n", abs_dir_name); if ((fsi->ch_dir(abs_dir_name)) == -1) { return -1; } if ((current_dir = fsi->open_dir(".")) == NULL) { printf("\"%s\":\n", abs_dir_name); perror("could not opendir"); return -1; } if ( (show_progress == true) && (update_func != NULL) ) update_func(NULL, abs_dir_name); while (fsi->read_dir(&z_dir_entry, current_dir) == 0) { if ( (strcmp(z_dir_entry.d_name, ".") == 0) || (strcmp(z_dir_entry.d_name, "..") == 0) ) continue; len = strlen(abs_dir_name) + strlen(z_dir_entry.d_name) + 2; if (len > dirname_size) { dirname = (char*)fizmo_realloc(dirname, len); dirname_size = len; } strcpy(dirname, abs_dir_name); if (dirname[strlen(dirname) - 1] != '/') strcat(dirname, "/"); strcat(dirname, z_dir_entry.d_name); if (fsi->is_filename_directory(z_dir_entry.d_name) == true) { if (recursive == true) search_dir(dirname, update_func, story_list, true, babel); } else { if ( (show_progress == true) && (update_func != NULL) ) update_func(z_dir_entry.d_name, NULL); detect_and_add_z_file(dirname, NULL, babel, story_list); } } if (dirname != NULL) free(dirname); fsi->close_dir(current_dir); fsi->ch_dir(cwd); free(cwd); return 0; }
//TODO: append matches to some data structure instead of just printing them out // then there can be sweet summaries of matches/files scanned/time/etc int search_dir(pcre *re, const char* path, const int depth) { //TODO: don't just die. also make max depth configurable if(depth > MAX_SEARCH_DEPTH) { log_err("Search depth greater than %i, giving up.", depth); exit(1); } struct dirent **dir_list = NULL; struct dirent *dir = NULL; int results = 0; FILE *fp = NULL; int f_len; size_t r_len; char *buf = NULL; int rv = 0; char *dir_full_path = NULL; size_t path_length = 0; results = scandir(path, &dir_list, &ignorefile_filter, &alphasort); if (results > 0) { for (int i = 0; i < results; i++) { dir = dir_list[i]; path_length = (size_t)(strlen(path) + strlen(dir->d_name) + 2); // 2 for slash and null char dir_full_path = malloc(path_length); dir_full_path = strncpy(dir_full_path, path, path_length); dir_full_path = strncat(dir_full_path, "/", path_length); dir_full_path = strncat(dir_full_path, dir->d_name, path_length); load_ignore_patterns(dir_full_path); free(dir); free(dir_full_path); } } free(dir_list); results = scandir(path, &dir_list, &filename_filter, &alphasort); if (results == 0) { log_debug("No results found"); free(dir_list); return(0); } else if (results == -1) { log_err("Error opening directory %s", path); return(0); } for (int i=0; i<results; i++) { dir = dir_list[i]; // XXX: this is copy-pasted from about 30 lines above path_length = (size_t)(strlen(path) + strlen(dir->d_name) + 2); // 2 for slash and null char dir_full_path = malloc(path_length); dir_full_path = strncpy(dir_full_path, path, path_length); dir_full_path = strncat(dir_full_path, "/", path_length); dir_full_path = strncat(dir_full_path, dir->d_name, path_length); log_debug("dir %s type %i", dir_full_path, dir->d_type); //TODO: scan files in current dir before going deeper if (dir->d_type == DT_DIR && opts.recurse_dirs) { log_debug("searching dir %s", dir_full_path); rv = search_dir(re, dir_full_path, depth + 1); goto cleanup; continue; } fp = fopen(dir_full_path, "r"); if (fp == NULL) { log_err("Error opening file %s. Skipping...", dir_full_path); goto cleanup; continue; } rv = fseek(fp, 0, SEEK_END); if (rv != 0) { log_err("Error fseek()ing file %s. Skipping...", dir_full_path); goto cleanup; } f_len = ftell(fp); //TODO: behave differently if file is HUGE. on 32 bit, anything > 2GB will screw up this program if (f_len == 0) { log_debug("file is empty. skipping"); goto cleanup; } rewind(fp); buf = (char*) malloc(sizeof(char) * f_len + 1); r_len = fread(buf, 1, f_len, fp); buf[r_len] = '\0'; int buf_len = (int)r_len; int buf_offset = 0; int offset_vector[MAX_MATCHES_PER_FILE * 2]; //XXXX int rc = 0; char *match_start = NULL; char *match_end = NULL; int first_match = 1; // In my profiling, most of the execution time is spent in this pcre_exec while(buf_offset < buf_len && (rc = pcre_exec(re, NULL, buf, r_len, buf_offset, 0, offset_vector, sizeof(offset_vector))) >= 0 ) { log_debug("Match found. File %s, offset %i bytes.", dir_full_path, offset_vector[0]); match_start = buf + offset_vector[0]; match_end = buf + offset_vector[1]; buf_offset = offset_vector[1]; print_match(dir_full_path, buf, match_start, match_end, first_match); first_match = 0; } free(buf); cleanup: if (fp != NULL) { fclose(fp); } free(dir); free(dir_full_path); } free(dir_list); return(0); }
/* TODO: append matches to some data structure instead of just printing them out * then there can be sweet summaries of matches/files scanned/time/etc */ int search_dir(const pcre *re, const pcre_extra *re_extra, const char* path, const int depth) { /* TODO: don't just die. also make max depth configurable */ if (depth > MAX_SEARCH_DEPTH) { log_err("Search depth greater than %i, giving up.", depth); exit(1); } struct dirent **dir_list = NULL; struct dirent *dir = NULL; int results = 0; int fd = -1; off_t f_len = 0; char *buf = NULL; int rv = 0; char *dir_full_path = NULL; size_t path_length = 0; int i; results = scandir(path, &dir_list, &ignorefile_filter, &alphasort); if (results > 0) { for (i = 0; i < results; i++) { dir = dir_list[i]; path_length = (size_t)(strlen(path) + strlen(dir->d_name) + 2); /* 2 for slash and null char */ dir_full_path = malloc(path_length); dir_full_path = strncpy(dir_full_path, path, path_length); dir_full_path = strncat(dir_full_path, "/", path_length); dir_full_path = strncat(dir_full_path, dir->d_name, path_length); load_ignore_patterns(dir_full_path); free(dir); dir = NULL; free(dir_full_path); dir_full_path = NULL; } } free(dir_list); dir_list = NULL; results = scandir(path, &dir_list, &filename_filter, &alphasort); if (results == 0) { log_debug("No results found in directory %s", path); free(dir_list); dir_list = NULL; return(0); } else if (results == -1) { log_err("Error opening directory %s", path); return(0); } match matches[MAX_MATCHES_PER_FILE]; int matches_len = 0; int buf_len = 0; int buf_offset = 0; int offset_vector[MAX_MATCHES_PER_FILE * 3]; /* TODO */ int rc = 0; struct stat statbuf; int binary = 0; for (i=0; i<results; i++) { matches_len = 0; buf_offset = 0; binary = 0; dir = dir_list[i]; /* TODO: this is copy-pasted from about 30 lines above */ path_length = (size_t)(strlen(path) + strlen(dir->d_name) + 2); /* 2 for slash and null char */ dir_full_path = malloc(path_length); dir_full_path = strncpy(dir_full_path, path, path_length); dir_full_path = strncat(dir_full_path, "/", path_length); dir_full_path = strncat(dir_full_path, dir->d_name, path_length); log_debug("dir %s type %i", dir_full_path, dir->d_type); /* TODO: scan files in current dir before going deeper */ if (dir->d_type == DT_DIR) { if (opts.recurse_dirs) { log_debug("Searching dir %s", dir_full_path); rv = search_dir(re, re_extra, dir_full_path, depth + 1); } goto cleanup; } if (opts.file_search_regex) { rc = pcre_exec(opts.file_search_regex, NULL, dir_full_path, strlen(dir_full_path), buf_offset, 0, offset_vector, 3); if (rc < 0) { /* no match */ log_debug("Skipping %s due to file_search_regex.", dir_full_path); goto cleanup; } } fd = open(dir_full_path, O_RDONLY); if (fd < 0) { log_err("Error opening file %s. Skipping...", dir_full_path); goto cleanup; } rv = fstat(fd, &statbuf); if (rv != 0) { log_err("Error fstat()ing file %s. Skipping...", dir_full_path); goto cleanup; } f_len = statbuf.st_size; if (f_len == 0) { log_debug("File %s is empty, skipping.", dir_full_path); goto cleanup; } else if (f_len > 1024 * 1024 * 1024) { /* 1 GB */ log_err("File %s is too big. Skipping...", dir_full_path); goto cleanup; } buf = mmap(0, f_len, PROT_READ, MAP_SHARED, fd, 0); if (buf == MAP_FAILED) { log_err("File %s failed to load: %s.", dir_full_path, strerror(errno)); goto cleanup; } buf_len = f_len; if (is_binary((void*)buf, buf_len)) { /* Who needs duck typing when you have void cast? :) */ if (opts.search_binary_files) { binary = 1; } else { log_debug("File %s is binary. Skipping...", dir_full_path); goto cleanup; } } if (opts.literal) { char *match_ptr = buf; char *(*ag_strncmp_fp)(const char*, const char*, size_t) = &ag_strnstr; if (opts.casing == CASE_INSENSITIVE) { ag_strncmp_fp = &ag_strncasestr; } while (buf_offset < buf_len) { match_ptr = ag_strncmp_fp(match_ptr, opts.query, buf_len - buf_offset); if (match_ptr == NULL) { break; } matches[matches_len].start = match_ptr - buf; matches[matches_len].end = matches[matches_len].start + opts.query_len; buf_offset = matches[matches_len].end; matches_len++; match_ptr++; /* Don't segfault. TODO: realloc this array */ if (matches_len >= MAX_MATCHES_PER_FILE) { log_err("Too many matches in %s. Skipping the rest of this file.", dir_full_path); break; } } } else { /* In my profiling, most of the execution time is spent in this pcre_exec */ while (buf_offset < buf_len && (rc = pcre_exec(re, re_extra, buf, buf_len, buf_offset, 0, offset_vector, 3)) >= 0) { log_debug("Match found. File %s, offset %i bytes.", dir_full_path, offset_vector[0]); buf_offset = offset_vector[1]; matches[matches_len].start = offset_vector[0]; matches[matches_len].end = offset_vector[1]; matches_len++; /* Don't segfault. TODO: realloc this array */ if (matches_len >= MAX_MATCHES_PER_FILE) { log_err("Too many matches in %s. Skipping the rest of this file.", dir_full_path); break; } } } if (opts.stats) { total_file_count++; total_byte_count += buf_len; } if (rc == -1) { log_debug("No match in %s", dir_full_path); } if (matches_len > 0) { if (opts.print_filename_only) { print_path(dir_full_path); } else { if (binary) { printf("Binary file %s matches.\n", dir_full_path); } else { print_file_matches(dir_full_path, buf, buf_len, matches, matches_len); } } } cleanup: if (fd != -1) { munmap(buf, f_len); close(fd); fd = -1; } free(dir); dir = NULL; free(dir_full_path); dir_full_path = NULL; } free(dir_list); dir_list = NULL; return(0); }
int main (int argc, char *argv[]){ //directory or disk device int devicetype=-1; //path to the device char devicepath[100]; //path of databases folder int dbfolder=0; char dbfolderpath[100]; while ((argc > 1) && (argv[1][0] == '-')) { switch (argv[1][1]) { case 'f': //Test if -d is not being used also if(devicetype!=DEVICE) devicetype=FOLDER; else{ printf("Cannot use both -f and -d\n"); usage(); } break; case 'd': //test if -f is not being used also if(devicetype!=FOLDER) devicetype=DEVICE; else{ printf("Cannot use both -f and -d\n\n"); usage(); } break; case 'p': strcpy(devicepath,&argv[1][2]); break; case 'b': str_split(&argv[1][2],FIXEDBLOCKS); break; case 'r': str_split(&argv[1][2],RABIN); break; case 'z': dbfolder=1; strcpy(dbfolderpath,&argv[1][2]); break; case 'h': help(); break; default: printf("Wrong Argument: %s\n", argv[1]); usage(); exit(0); break; } ++argv; --argc; } //test if iotype is defined if(devicetype!=FOLDER && devicetype!=DEVICE){ printf("missing -f or -d\n\n"); usage(); exit(0); } //test if testype is defined if(strlen(devicepath)==0){ printf("missing -p<value>\n\n"); usage(); exit(0); } if(nr_sizes_proc_rabin==0 && nr_sizes_proc==0){ printf("missing -b<value> or -r<value>\n\n"); usage(); exit(0); } //Initialize variables total_blocks=malloc(sizeof(uint64_t)*(nr_sizes_proc+nr_sizes_proc_rabin)); eq=malloc(sizeof(uint64_t)*(nr_sizes_proc+nr_sizes_proc_rabin)); incomplete_blocks=malloc(sizeof(uint64_t)*(nr_sizes_proc+nr_sizes_proc_rabin)); incomplete_space=malloc(sizeof(uint64_t)*(nr_sizes_proc+nr_sizes_proc_rabin)); dif=malloc(sizeof(uint64_t)*(nr_sizes_proc+nr_sizes_proc_rabin)); distinctdup=malloc(sizeof(uint64_t)*(nr_sizes_proc+nr_sizes_proc_rabin)); //zeroed_blocks=malloc(sizeof(uint64_t)*nr_sizes_proc); space=malloc(sizeof(uint64_t)*(nr_sizes_proc+nr_sizes_proc_rabin)); dbporiginal=malloc(sizeof(DB**)*(nr_sizes_proc+nr_sizes_proc_rabin)); envporiginal=malloc(sizeof(DB_ENV**)*(nr_sizes_proc+nr_sizes_proc_rabin)); dbprinter=malloc(sizeof(DB**)*(nr_sizes_proc+nr_sizes_proc_rabin)); envprinter=malloc(sizeof(DB_ENV**)*(nr_sizes_proc+nr_sizes_proc_rabin)); int aux=0; for(aux=0;aux<(nr_sizes_proc+nr_sizes_proc_rabin);aux++){ dbporiginal[aux]=malloc(sizeof(DB *)); envporiginal[aux]=malloc(sizeof(DB_ENV *)); dbprinter[aux]=malloc(sizeof(DB *)); envprinter[aux]=malloc(sizeof(DB_ENV *)); char printdbpath[100]; char duplicatedbpath[100]; char sizeid[20]; if(aux<nr_sizes_proc){ sprintf(sizeid,"fixed_%d",sizes_proc[aux]); }else{ sprintf(sizeid,"rabin_%d",sizes_proc_rabin[aux-nr_sizes_proc]); } //if a folder were specified for databases if(dbfolder==1){ strcpy(printdbpath,PRINTDB); strcat(printdbpath,sizeid); strcpy(duplicatedbpath,dbfolderpath); strcat(duplicatedbpath,sizeid); } else{ strcpy(printdbpath,PRINTDB); strcat(printdbpath,sizeid); strcpy(duplicatedbpath,DUPLICATEDB); strcat(duplicatedbpath,sizeid); } char mkcmd[200]; sprintf(mkcmd, "mkdir -p %s", printdbpath); int ress = system(mkcmd); sprintf(mkcmd, "mkdir -p %s", duplicatedbpath); ress=system(mkcmd); if(ress<0) perror("Error creating folders for databases\n"); printf("Removing old databases\n"); //remove databases if exist remove_db(duplicatedbpath,dbporiginal[aux],envporiginal[aux]); remove_db(printdbpath,dbprinter[aux],envprinter[aux]); printf("Initing new database\n"); init_db(duplicatedbpath,dbporiginal[aux],envporiginal[aux]); } //initialize analyzis variables bzero(incomplete_blocks,(nr_sizes_proc+nr_sizes_proc_rabin)*(sizeof(uint64_t))); bzero(incomplete_space,(nr_sizes_proc+nr_sizes_proc_rabin)*(sizeof(uint64_t))); //initialize analyzis variables bzero(total_blocks,(nr_sizes_proc+nr_sizes_proc_rabin)*(sizeof(uint64_t))); //identical chunks (that could be eliminated) bzero(eq,(nr_sizes_proc+nr_sizes_proc_rabin)*(sizeof(uint64_t))); //distinct chunks bzero(dif,(nr_sizes_proc+nr_sizes_proc_rabin)*(sizeof(uint64_t))); //distinct chunks with duplicates bzero(distinctdup,(nr_sizes_proc+nr_sizes_proc_rabin)*(sizeof(uint64_t))); //chunks that were appended with zeros due to their size //bzero(zeroed_blocks,nr_sizes_proc*(sizeof(uint64_t))); //duplicated disk space bzero(space,(nr_sizes_proc+nr_sizes_proc_rabin)*(sizeof(uint64_t))); //initialize rabin block initialize_rabin_polynomial_defaults(); cur_block=malloc(sizeof(struct rab_block_info *)*nr_sizes_proc_rabin); int auxc=0; for(auxc=0;auxc<nr_sizes_proc_rabin;auxc++){ cur_block[auxc]=NULL; } //check if it is a folder or device and start processing if(devicetype==FOLDER){ printf("start processing folder %s\n",devicepath); search_dir(devicepath); } else{ printf("start processing device %s\n",devicepath); extract_blocks(devicepath); } for(aux=0;aux<(nr_sizes_proc+nr_sizes_proc_rabin);aux++){ if(aux>=nr_sizes_proc) fprintf(stderr,"\n\n\nRabin Results for %d\n",sizes_proc_rabin[aux-nr_sizes_proc]); else fprintf(stderr,"\n\n\nFixed Size Results for %d\n",sizes_proc[aux]); fprintf(stderr,"files scanned %llu\n",(unsigned long long int)nfiles); fprintf(stderr,"space scanned %llu Bytes (including incomplete blocks)\n",(unsigned long long int)total_space); fprintf(stderr,"Complete and Incomplete Block statistics:\ntotal blocks scanned %llu\n",(unsigned long long int)total_blocks[aux]); //fprintf(stderr,"total blocks with zeros appended %llu\n",(unsigned long long int)zeroed_blocks[aux]); //blocks without any duplicate are the distinct block minus the distinct blocks with duplicates uint64_t zerodups=dif[aux]-distinctdup[aux]; fprintf(stderr,"blocks without duplicates %llu\n",(unsigned long long int)zerodups); fprintf(stderr,"distinct blocks with duplicates %llu\n",(unsigned long long int)distinctdup[aux]); fprintf(stderr,"duplicate blocks %llu\n",(unsigned long long int)eq[aux]); fprintf(stderr,"space saved %llu Bytes\n",(unsigned long long int)space[aux]); fprintf(stderr,"Incomplete Block statistics:\nincomplete blocks %llu\n",(unsigned long long int)incomplete_blocks[aux]); fprintf(stderr,"incomplete blocks space %llu Bytes\n",(unsigned long long int)incomplete_space[aux]); close_db(dbporiginal[aux],envporiginal[aux]); //TODO this is not removed to keep the database for dedisgen-utils //remove_db(duplicatedbpath,dbporiginal,envporiginal); } //free memory free(incomplete_space); free(incomplete_blocks); free(total_blocks); free(eq); free(dif); free(distinctdup); //free(zeroed_blocks); free(space); free(dbporiginal); free(envporiginal); free(dbprinter); free(envprinter); return 0; }
int main(int argc , char *argv[]) { search_dir(); return 0; }
/* File creation function: * 1. creates empty file with file size zero. * 2. makes/allocates descriptor. * 3. updates directory file. * Parameter(s): * symbolic_file_name: The name of file to create. * Return: * Return 0 for successful creation. * Return -1 for error (no space in disk) * Return -2 for error (for duplication) */ int FileSystem53::create(string symbolic_file_name) { int desc_index = find_empty_descriptor(); if ( desc_index == -1 ) { //cout << "[email protected](): no empty descriptors left" << endl; return -1; } if ( search_dir(0, symbolic_file_name) != -1 ) { //cout << "[email protected](): filename exists" << endl; return -2; } // clean up the exist descriptior in desc_table for (int i = 0; i < 4; i++) { desc_table[desc_index][i] = 0; } // if directory file uses 3 blocked and no more space for the filename // return -1 int filename_length = symbolic_file_name.size(); if ( oft[0][1] + filename_length > 192 || filename_length > 10 ) { //cout << "[email protected](): filename oversize" << endl; return -1; } // get new empty block for directory to store the content if needed.. int dir_block_index = find_empty_block(); if ( dir_block_index == -1 ) { //cout << "[email protected](): no more empty block" << endl; return -1; } // update bytemap desc_table[0][dir_block_index] = 1; // set the first block with the found index; int current_block = (filename_length + oft[0][1]) / 64; oft[0][2+current_block] = dir_block_index; // write filename to directory file in oft // handling multiply filenames // create new file name entry int start_pos = 0; int filename_buffer_length = 2+filename_length; char filename_buffer[filename_buffer_length]; filename_buffer[0] = desc_index; filename_buffer[1] = filename_length; for (int i = 0; i < filename_length; i++) { filename_buffer[i+2] = symbolic_file_name[i]; } // find empty space in directory file to write the entry for (int i = OFT_CURRENT_POSITION_INDEX; i < OFT_ENTRY_SIZE; i++) { while ( oft[0][i] == 0 && start_pos < filename_buffer_length ) { oft[0][i] = filename_buffer[start_pos]; i++; start_pos++; } } //oft[0][OFT_CURRENT_POSITION_INDEX] = start_pos; // update descriptor in oft oft[0][1] += filename_length+2; // write descriptior to desc_table char desc_buffer[DESCR_SIZE]; for (int i = 0; i < DESCR_SIZE; i++) { desc_buffer[i] = oft[0][i+1]; } write_descriptor(1, desc_buffer); return 0; }
/* TODO: Append matches to some data structure instead of just printing them out. * Then ag can have sweet summaries of matches/files scanned/time/etc. */ void search_dir(ignores *ig, const char *base_path, const char *path, const int depth) { struct dirent **dir_list = NULL; struct dirent *dir = NULL; scandir_baton_t scandir_baton; int results = 0; char *dir_full_path = NULL; const char *ignore_file = NULL; int i; /* find agignore/gitignore/hgignore/etc files to load ignore patterns from */ for (i = 0; opts.skip_vcs_ignores ? (i == 0) : (ignore_pattern_files[i] != NULL); i++) { ignore_file = ignore_pattern_files[i]; ag_asprintf(&dir_full_path, "%s/%s", path, ignore_file); if (strcmp(SVN_DIR, ignore_file) == 0) { load_svn_ignore_patterns(ig, dir_full_path); } else { load_ignore_patterns(ig, dir_full_path); } free(dir_full_path); dir_full_path = NULL; } if (opts.path_to_agignore) { load_ignore_patterns(ig, opts.path_to_agignore); } scandir_baton.ig = ig; scandir_baton.base_path = base_path; results = ag_scandir(path, &dir_list, &filename_filter, &scandir_baton); if (results == 0) { log_debug("No results found in directory %s", path); goto search_dir_cleanup; } else if (results == -1) { if (errno == ENOTDIR) { /* Not a directory. Probably a file. */ /* If we're only searching one file, don't print the filename header at the top. */ if (depth == 0 && opts.paths_len == 1) { opts.print_heading = -1; } search_file(path); } else { log_err("Error opening directory %s: %s", path, strerror(errno)); } goto search_dir_cleanup; } int offset_vector[3]; int rc = 0; work_queue_t *queue_item; for (i = 0; i < results; i++) { queue_item = NULL; dir = dir_list[i]; ag_asprintf(&dir_full_path, "%s/%s", path, dir->d_name); /* If a link points to a directory then we need to treat it as a directory. */ if (!opts.follow_symlinks && is_symlink(path, dir)) { log_debug("File %s ignored becaused it's a symlink", dir->d_name); goto cleanup; } if (!is_directory(path, dir)) { if (opts.file_search_regex) { rc = pcre_exec(opts.file_search_regex, NULL, dir_full_path, strlen(dir_full_path), 0, 0, offset_vector, 3); if (rc < 0) { /* no match */ log_debug("Skipping %s due to file_search_regex.", dir_full_path); goto cleanup; } else if (opts.match_files) { log_debug("match_files: file_search_regex matched for %s.", dir_full_path); pthread_mutex_lock(&print_mtx); print_path(dir_full_path, '\n'); pthread_mutex_unlock(&print_mtx); goto cleanup; } } queue_item = ag_malloc(sizeof(work_queue_t)); queue_item->path = dir_full_path; queue_item->next = NULL; pthread_mutex_lock(&work_queue_mtx); if (work_queue_tail == NULL) { work_queue = queue_item; } else { work_queue_tail->next = queue_item; } work_queue_tail = queue_item; pthread_mutex_unlock(&work_queue_mtx); pthread_cond_signal(&files_ready); log_debug("%s added to work queue", dir_full_path); } else if (opts.recurse_dirs) { if (depth < opts.max_search_depth) { log_debug("Searching dir %s", dir_full_path); ignores *child_ig = init_ignore(ig); search_dir(child_ig, base_path, dir_full_path, depth + 1); cleanup_ignore(child_ig); } else { log_err("Skipping %s. Use the --depth option to search deeper.", dir_full_path); } } cleanup: ; free(dir); dir = NULL; if (queue_item == NULL) { free(dir_full_path); dir_full_path = NULL; } } search_dir_cleanup: ; free(dir_list); dir_list = NULL; }
/* TODO: append matches to some data structure instead of just printing them out * then there can be sweet summaries of matches/files scanned/time/etc */ void search_dir(const pcre *re, const pcre_extra *re_extra, const char* path, const int depth) { struct dirent **dir_list = NULL; struct dirent *dir = NULL; int results = 0; int fd = -1; off_t f_len = 0; char *buf = NULL; char *dir_full_path = NULL; size_t path_length = 0; int i; /* find agignore/gitignore/hgignore/etc files to load ignore patterns from */ #ifdef AG_OS_BSD results = scandir(path, &dir_list, &ignorefile_filter, &alphasort); #else results = scandir(path, &dir_list, (int (*)(const struct dirent *))&ignorefile_filter, &alphasort); #endif if (results > 0) { for (i = 0; i < results; i++) { dir = dir_list[i]; path_length = (size_t)(strlen(path) + strlen(dir->d_name) + 2); /* 2 for slash and null char */ dir_full_path = malloc(path_length); strlcpy(dir_full_path, path, path_length); strlcat(dir_full_path, "/", path_length); strlcat(dir_full_path, dir->d_name, path_length); load_ignore_patterns(dir_full_path); free(dir); dir = NULL; free(dir_full_path); dir_full_path = NULL; } } free(dir_list); dir_list = NULL; #ifdef AG_OS_BSD results = scandir(path, &dir_list, &filename_filter, &alphasort); #else results = scandir(path, &dir_list, (int (*)(const struct dirent *))&filename_filter, &alphasort); #endif if (results == 0) { log_debug("No results found in directory %s", path); free(dir_list); dir_list = NULL; return; } else if (results == -1) { if (errno == ENOTDIR) { /* Not a directory. Probably a file. */ /* If we're only searching one file, don't print the filename header at the top. */ opts.print_heading = depth == 0 ? -1 : opts.print_heading; search_file(re, re_extra, path); return; } else { log_err("Error opening directory %s: %s", path, strerror(errno)); return; } } int offset_vector[3]; int rc = 0; struct stat stDirInfo; for (i = 0; i < results; i++) { dir = dir_list[i]; /* TODO: this is copy-pasted from about 30 lines above */ path_length = (size_t)(strlen(path) + strlen(dir->d_name) + 2); /* 2 for slash and null char */ dir_full_path = malloc(path_length); strlcpy(dir_full_path, path, path_length); strlcat(dir_full_path, "/", path_length); strlcat(dir_full_path, dir->d_name, path_length); /* Some filesystems, e.g. ReiserFS, always return a type DT_UNKNOWN from readdir or scandir. */ /* Call lstat if we find DT_UNKNOWN to get the information we need. */ if (dir->d_type == DT_UNKNOWN) { if (lstat(dir_full_path, &stDirInfo) != -1) { if (S_ISDIR(stDirInfo.st_mode)) { dir->d_type = DT_DIR; } else if (S_ISLNK(stDirInfo.st_mode)) { dir->d_type = DT_LNK; } } else { log_err("lstat() failed on %s", dir_full_path); /* If lstat fails we may as well carry on and hope for the best. */ } if (!opts.follow_symlinks && dir->d_type == DT_LNK) { log_debug("File %s ignored becaused it's a symlink", dir->d_name); goto cleanup; } } /* If a link points to a directory then we need to treat it as a directory. */ if (dir->d_type == DT_LNK) { if (stat(dir_full_path, &stDirInfo) != -1) { if (S_ISDIR(stDirInfo.st_mode)) { dir->d_type = DT_DIR; } } else { log_err("stat() failed on %s", dir_full_path); /* If stat fails we may as well carry on and hope for the best. */ } } log_debug("dir %s type %i", dir_full_path, dir->d_type); if (opts.file_search_regex) { rc = pcre_exec(opts.file_search_regex, NULL, dir_full_path, strlen(dir_full_path), 0, 0, offset_vector, 3); if (rc < 0) { /* no match */ log_debug("Skipping %s due to file_search_regex.", dir_full_path); goto cleanup; } } /* TODO: scan files in current dir before going deeper */ if (dir->d_type == DT_DIR) { if (opts.recurse_dirs) { if (depth < opts.max_search_depth) { log_debug("Searching dir %s", dir_full_path); search_dir(re, re_extra, dir_full_path, depth + 1); } else { log_err("Skipping %s. Use the --depth option to search deeper.", dir_full_path); } } goto cleanup; } search_file(re, re_extra, dir_full_path); cleanup: if (fd != -1) { munmap(buf, f_len); close(fd); fd = -1; } free(dir); dir = NULL; free(dir_full_path); dir_full_path = NULL; } free(dir_list); dir_list = NULL; return; }
/*===========================================================================* * fs_link * *===========================================================================*/ int fs_link() { /* Perform the link(name1, name2) system call. */ struct inode *ip, *rip; register int r; char string[MFS_NAME_MAX]; struct inode *new_ip; phys_bytes len; len = min( (unsigned) fs_m_in.REQ_PATH_LEN, sizeof(string)); /* Copy the link name's last component */ r = sys_safecopyfrom(VFS_PROC_NR, (cp_grant_id_t) fs_m_in.REQ_GRANT, (vir_bytes) 0, (vir_bytes) string, (size_t) len); if (r != OK) return r; NUL(string, len, sizeof(string)); /* Temporarily open the file. */ if( (rip = get_inode(fs_dev, (ino_t) fs_m_in.REQ_INODE_NR)) == NULL) return(EINVAL); /* Check to see if the file has maximum number of links already. */ r = OK; if(rip->i_nlinks >= LINK_MAX) r = EMLINK; /* Only super_user may link to directories. */ if(r == OK) if( (rip->i_mode & I_TYPE) == I_DIRECTORY && caller_uid != SU_UID) r = EPERM; /* If error with 'name', return the inode. */ if (r != OK) { put_inode(rip); return(r); } /* Temporarily open the last dir */ if( (ip = get_inode(fs_dev, (ino_t) fs_m_in.REQ_DIR_INO)) == NULL) { put_inode(rip); return(EINVAL); } if (ip->i_nlinks == NO_LINK) { /* Dir does not actually exist */ put_inode(rip); put_inode(ip); return(ENOENT); } /* If 'name2' exists in full (even if no space) set 'r' to error. */ if((new_ip = advance(ip, string, IGN_PERM)) == NULL) { r = err_code; if(r == ENOENT) r = OK; } else { put_inode(new_ip); r = EEXIST; } /* Try to link. */ if(r == OK) r = search_dir(ip, string, &rip->i_num, ENTER, IGN_PERM); /* If success, register the linking. */ if(r == OK) { rip->i_nlinks++; rip->i_update |= CTIME; IN_MARKDIRTY(rip); } /* Done. Release both inodes. */ put_inode(rip); put_inode(ip); return(r); }
/*===========================================================================* * new_node * *===========================================================================*/ PRIVATE struct inode *new_node(struct inode *ldirp, char *string, mode_t bits, zone_t z0) { /* New_node() is called by fs_open(), fs_mknod(), and fs_mkdir(). * In all cases it allocates a new inode, makes a directory entry for it in * the ldirp directory with string name, and initializes it. * It returns a pointer to the inode if it can do this; * otherwise it returns NULL. It always sets 'err_code' * to an appropriate value (OK or an error code). * * The parsed path rest is returned in 'parsed' if parsed is nonzero. It * has to hold at least NAME_MAX bytes. */ register struct inode *rip; register int r; if (ldirp->i_nlinks == NO_LINK) { /* Dir does not actually exist */ err_code = ENOENT; return(NULL); } /* Get final component of the path. */ rip = advance(ldirp, string, IGN_PERM); if (S_ISDIR(bits) && (ldirp->i_nlinks >= LINK_MAX)) { /* New entry is a directory, alas we can't give it a ".." */ put_inode(rip); err_code = EMLINK; return(NULL); } /* if creating a regular file, set it to be an immediate */ else if((bits & I_TYPE) == I_REGULAR) bits |= I_IMMEDIATE; /* printf("new_node() - mode bits: 0%6o\n", bits); */ if ( rip == NULL && err_code == ENOENT) { /* Last path component does not exist. Make new directory entry. */ if ( (rip = alloc_inode((ldirp)->i_dev, bits)) == NULL) { /* Can't creat new inode: out of inodes. */ return(NULL); } /* Force inode to the disk before making directory entry to make * the system more robust in the face of a crash: an inode with * no directory entry is much better than the opposite. */ rip->i_nlinks++; rip->i_zone[0] = z0; /* major/minor device numbers */ rw_inode(rip, WRITING); /* force inode to disk now */ /* New inode acquired. Try to make directory entry. */ if((r=search_dir(ldirp, string, &rip->i_num, ENTER, IGN_PERM)) != OK) { rip->i_nlinks--; /* pity, have to free disk inode */ rip->i_dirt = DIRTY; /* dirty inodes are written out */ put_inode(rip); /* this call frees the inode */ err_code = r; return(NULL); } } else if (err_code == EENTERMOUNT || err_code == ELEAVEMOUNT) { r = EEXIST; } else { /* Either last component exists, or there is some problem. */ if (rip != NULL) r = EEXIST; else r = err_code; } /* The caller has to return the directory inode (*ldirp). */ err_code = r; return(rip); }