linux c非递归遍历目录,【Linux C】遍历 指定文件夹(home)的所有文件 (非递归实现)...

为什么要写这个呢...是因为要出一些恶意的代码片段,有一个遍历文件夹的需求。按照要求,所有的恶意行为只能写在一个函数中,且不能有注释。本来不想自己写,可是google到的遍历文件夹的代码全是递归写的。虽然gcc也支持内部函数的编译,但是这样感觉不太优雅,于是稍微修改一下,就有了下面的代码。

实现思路其实很简单,其实就是链表啦,不过上次写链表还是13年吧,真太菜了。

用一个结构体保存 1. 当前文件夹的path的地址2.下一个结构体的地址(初始化为NULL)。

遍历时,创建两个结构体指针,folderfirst和folderlast。用folderfirst遍历指定文件夹(如/home)的时候,如果出现新的文件夹,就用创建新的结构体,用folderlast来增加到链表中。当前文件夹遍历完成,修改folderfirst指向下一个结构体。循环结束的条件就是,folderfirst为NULL。

PS:这么实现貌似算广度优先搜索?貌似搜索文件夹BFS比DFS要快, 和OS有关系。忘了出处了,感兴趣的可以搜索一下。

1806191523 bug:scan根目录的时候,猜测由于部分文件没有读权限,因此程序就停了。此外,有替代工具,命令"du -h"。暂时没时间改了,有空参考一下du的源码实现吧。ftp://ftp.gnu.org/gnu/coreutils/

如果有人有兴趣修改,欢迎留言讨论。

最新以及历史版本放在:https://gist.github.com/thinkycx/a6359201f79ffdf4e97a111c5fe4cf01

代码:

/*

date: 20180619

author: thinkycx

usage: gcc scanfolder.c -o scanfolder

./scanfolder [foldername]

./scscanfolderan /home

Only support to scan folder and regular file.Maybe support symbolic etc in future...

*/

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

void f(char *path){

#define SEARCH_PATH "/home"

struct foldernode{

char *path; // point to foldername or filename path

struct foldernode *next;

};

DIR *dir;

struct stat statbuf;

struct dirent *ptr;

char *filename;

char *filepath;

char *data;

char *foldername ;

char *folderpath ;

struct foldernode folderstart;

folderstart.path = path;

folderstart.next = NULL;

struct foldernode * folderfirst; // use to search

folderfirst = &folderstart;

struct foldernode * folderlast; // use to add foldernode

folderlast = &folderstart;

while(folderfirst != NULL){

dir = opendir(folderfirst->path);

if (dir) {

while ((ptr = readdir(dir)) != NULL) {

if(strcmp(ptr->d_name, ".")==0 || strcmp(ptr->d_name, "..")==0)

continue;

else if(ptr->d_type == 8){ //file

filename = malloc(0x100);

filepath = malloc(0x1000);

memset(filename, 0x100, 0);

memset(filepath, 0x100, 0);

strcpy(filename, ptr->d_name);

sprintf(filepath, "%s/%s", folderfirst->path, filename);

printf("[*]FILE %s\n",filepath);

free(filename);

free(filepath);

}

else if(ptr->d_type == 4){ //folder

foldername = malloc(0x100);

folderpath = malloc(0x1000);

memset(foldername, 0x100, 0);

memset(folderpath, 0x1000, 0);

strcpy(foldername, ptr->d_name);

sprintf(folderpath, "%s/%s", folderfirst->path , foldername);

printf("[*]FOLDER %s\n",folderpath);

struct foldernode *foldernew;

foldernew = malloc(sizeof(struct foldernode));

foldernew->path = malloc(strlen(folderpath)+1);

strcpy(foldernew->path, folderpath);

foldernew->next = NULL;

folderlast->next = foldernew;

folderlast = foldernew;

free(foldername);

free(folderpath);

}

}

}else{

return;

}

folderfirst = folderfirst->next; // change folderfirst point to next foldernode

closedir(dir);

}

}

int main(int argc,char **argv, char **env) {

if(argc == 2){

f(argv[1]);

}else{

printf("Usage: scanfolder [foldername]\n\tscanfolder /home\n");

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值