循环遍历目录
由于工作需要涉及到商城的资金交易安全,在这个网络上又找不到合适的答案所以就自己摸索,去设计一款代码分析软件。废话不多说先贴上一份有bug的目录遍历代码。。。
1 #include <io.h> 2 #include <time.h> 3 #include <stdio.h> 4 #include <stdlib.h> 5 #include <string.h> 6 #include <fcntl.h> 7 #include <sys/stat.h> 8 #include <unistd.h> 9 #include <tchar.h> 10 #include <dirent.h> 11 #include <wchar.h> 12 #include <winsock2.h> 13 #include <Windows.h> 14 15 #if 0 16 //注意windows unix结构体定义是不同的 17 struct dirent 18 { 19 long d_ino; /* Always zero. */ 20 unsigned short d_reclen; /* Always zero. */ 21 unsigned short d_namlen; /* Length of name in d_name. */ 22 char d_name[FILENAME_MAX]; /* File name. */ 23 }; 24 25 struct dirent 26 { 27 long d_ino; /* not used in this implementation */ 28 long d_off; /* not used in this implementation */ 29 unsigned short d_namlen; 30 char d_name[1]; 31 }; 32 33 //Windows gcc include 34 struct stat 35 { 36 dev_t st_dev; /* Equivalent to drive number 0=A 1=B ... */ 37 ino_t st_ino; /* Always zero ? */ 38 mode_t st_mode; /* See above constants */ 39 short st_nlink; /* Number of links. */ 40 short st_uid; /* User: Maybe significant on NT ? */ 41 short st_gid; /* Group: Ditto */ 42 dev_t st_rdev; /* Seems useless (not even filled in) */ 43 off_t st_size; /* File size in bytes */ 44 time_t st_atime; /* Accessed date (always 00:00 hrs local 45 * on FAT) */ 46 time_t st_mtime; /* Modified time */ 47 time_t st_ctime; /* Creation time */ 48 }; 49 50 //openbsd 51 struct stat { 52 dev_t st_dev; /* major/minor device number */ 53 ino_t st_ino; /* i-node number */ 54 mode_t st_mode; /* file mode, protection bits, etc. */ 55 short int st_nlink; /* # links; TEMPORARY HACK: should be nlink_t*/ 56 uid_t st_uid; /* uid of the file's owner */ 57 short int st_gid; /* gid; TEMPORARY HACK: should be gid_t */ 58 dev_t st_rdev; 59 off_t st_size; /* file size */ 60 time_t st_atime; /* time of last access */ 61 time_t st_mtime; /* time of last data modification */ 62 time_t st_ctime; /* time of last file status change */ 63 }; 64 65 //来自网络 66 struct stat { 67 mode_t st_mode; //文件对应的模式,文件,目录等 68 ino_t st_ino; //inode节点号 69 dev_t st_dev; //设备号码 70 dev_t st_rdev; //特殊设备号码 71 nlink_t st_nlink; //文件的连接数 72 uid_t st_uid; //文件所有者 73 gid_t st_gid; //文件所有者对应的组 74 off_t st_size; //普通文件,对应的文件字节数 75 time_t st_atime; //文件最后被访问的时间 76 time_t st_mtime; //文件内容最后被修改的时间 77 time_t st_ctime; //文件状态改变时间 78 blksize_t st_blksize; //文件内容对应的块大小 79 blkcnt_t st_blocks; //伟建内容对应的块数量 80 }; 81 82 //来自网络 83 stat结构体中的st_mode 则定义了下列数种情况: 84 S_IFMT 0170000 文件类型的位遮罩 85 S_IFSOCK 0140000 scoket 86 S_IFLNK 0120000 符号连接 87 S_IFREG 0100000 一般文件 88 S_IFBLK 0060000 区块装置 89 S_IFDIR 0040000 目录 //注意 0x4000 和 0x40000差了非常多 90 S_IFCHR 0020000 字符装置 91 S_IFIFO 0010000 先进先出 92 93 S_ISUID 04000 文件的(set user-id on execution)位 94 S_ISGID 02000 文件的(set group-id on execution)位 95 S_ISVTX 01000 文件的sticky位 96 97 S_IRUSR(S_IREAD) 00400 文件所有者具可读取权限 98 S_IWUSR(S_IWRITE)00200 文件所有者具可写入权限 99 S_IXUSR(S_IEXEC) 00100 文件所有者具可执行权限 100 101 S_IRGRP 00040 用户组具可读取权限 102 S_IWGRP 00020 用户组具可写入权限 103 S_IXGRP 00010 用户组具可执行权限 104 105 S_IROTH 00004 其他用户具可读取权限 106 S_IWOTH 00002 其他用户具可写入权限 107 S_IXOTH 00001 其他用户具可执行权限 108 109 上述的文件类型在POSIX中定义了检查这些类型的宏定义: 110 S_ISLNK (st_mode) 判断是否为符号连接 111 S_ISREG (st_mode) 是否为一般文件 112 S_ISDIR (st_mode) 是否为目录 113 S_ISCHR (st_mode) 是否为字符装置文件 114 S_ISBLK (s3e) 是否为先进先出 115 S_ISSOCK (st_mode) 是否为socket 116 若一目录具有sticky位(S_ISVTX),则表示在此目录下的文件只能被该文件所有者、此目录所有者或root来删除或改名,在linux中,最典型的就是这个/tmp目录啦。 117 118 #if 0 119 //win gcc include 120 /* 121 * Constants for the stat st_mode member. 122 */ 123 #define _S_IFIFO 0x1000 /* FIFO */ 124 #define _S_IFCHR 0x2000 /* Character */ 125 #define _S_IFBLK 0x3000 /* Block: Is this ever set under w32? */ 126 #define _S_IFDIR 0x4000 /* Directory */ 127 #define _S_IFREG 0x8000 /* Regular */ 128 129 #define _S_IFMT 0xF000 /* File type mask */ 130 131 #define _S_IEXEC 0x0040 132 #define _S_IWRITE 0x0080 133 #define _S_IREAD 0x0100 134 135 #define _S_IRWXU (_S_IREAD | _S_IWRITE | _S_IEXEC) 136 #define _S_IXUSR _S_IEXEC 137 #define _S_IWUSR _S_IWRITE 138 #define _S_IRUSR _S_IREAD 139 140 #define _S_ISDIR(m) (((m) & _S_IFMT) == _S_IFDIR) 141 #define _S_ISFIFO(m) (((m) & _S_IFMT) == _S_IFIFO) 142 #define _S_ISCHR(m) (((m) & _S_IFMT) == _S_IFCHR) 143 #define _S_ISBLK(m) (((m) & _S_IFMT) == _S_IFBLK) 144 #define _S_ISREG(m) (((m) & _S_IFMT) == _S_IFREG) 145 146 #ifndef _NO_OLDNAMES 147 148 #define S_IFIFO _S_IFIFO 149 #define S_IFCHR _S_IFCHR 150 #define S_IFBLK _S_IFBLK 151 #define S_IFDIR _S_IFDIR 152 #define S_IFREG _S_IFREG 153 #define S_IFMT _S_IFMT 154 #define S_IEXEC _S_IEXEC 155 #define S_IWRITE _S_IWRITE 156 #define S_IREAD _S_IREAD 157 #define S_IRWXU _S_IRWXU 158 #define S_IXUSR _S_IXUSR 159 #define S_IWUSR _S_IWUSR 160 #define S_IRUSR _S_IRUSR 161 162 #define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) 163 #define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO) 164 #define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR) 165 #define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK) 166 #define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) 167 168 #endif /* Not _NO_OLDNAMES */ 169 170 #endif /*win gcc include*/ 171 172 173 #if 0 174 175 /* Traditional mask definitions for st_mode. */ 176 #define S_IFMT 0170000 /* type of file */ 177 #define S_IFREG 0100000 /* regular */ 178 #define S_IFBLK 0060000 /* block special */ 179 #define S_IFDIR 0040000 /* directory */ 180 #define S_IFCHR 0020000 /* character special */ 181 #define S_IFIFO 0010000 /* this is a FIFO */ 182 #define S_ISUID 0004000 /* set user id on execution */ 183 #define S_ISGID 0002000 /* set group id on execution */ 184 /* next is reserved for future use */ 185 #define S_ISVTX 01000 /* save swapped text even after use */ 186 187 /* POSIX masks for st_mode. */ 188 #define S_IRWXU 00700 /* owner: rwx------ */ 189 #define S_IRUSR 00400 /* owner: r-------- */ 190 #define S_IWUSR 00200 /* owner: -w------- */ 191 #define S_IXUSR 00100 /* owner: --x------ */ 192 193 #define S_IRWXG 00070 /* group: ---rwx--- */ 194 #define S_IRGRP 00040 /* group: ---r----- */ 195 #define S_IWGRP 00020 /* group: ----w---- */ 196 #define S_IXGRP 00010 /* group: -----x--- */ 197 198 #define S_IRWXO 00007 /* others: ------rwx */ 199 #define S_IROTH 00004 /* others: ------r-- */ 200 #define S_IWOTH 00002 /* others: -------w- */ 201 #define S_IXOTH 00001 /* others: --------x */ 202 203 /* The following macros test st_mode (from POSIX Sec. 5.6.1.1. */ 204 #define S_ISREG(m) ((m & S_IFMT) == S_IFREG) /* is a reg file */ 205 #define S_ISDIR(m) ((m & S_IFMT) == S_IFDIR) /* is a directory */ 206 #define S_ISCHR(m) ((m & S_IFMT) == S_IFCHR) /* is a char spec */ 207 #define S_ISBLK(m) ((m & S_IFMT) == S_IFBLK) /* is a block spec */ 208 #define S_ISFIFO(m) ((m & S_IFMT) == S_IFIFO) /* is a pipe/FIFO */ 209 210 #endif /* linux posix */ 211 212 213 #endif 214 215 216 int lstat(const char *str, struct stat *sb) 217 { 218 int fd, rv; 219 220 if ((fd = open(str, 0)) < 0) 221 return (-1); 222 rv = fstat(fd, sb); 223 (void)close(fd); 224 return (rv); 225 } 226 227 //用递归打开一个目录列表会比较简单 228 #if 0 229 DIR *sdir,*pdir,rdir[]="./",subdir[512]; 230 struct dirent *ptr; 231 struct stat *stbuf; 232 unsigned int i,offset; 233 234 pdir = sdir = opendir(rdir); 235 236 while((ptr = readdir(sdir))!=NULL) 237 { 238 printf("d_name: %s\n",ptr->d_name); 239 //判断是目录还是文件或者链接 240 sprintf(subdir,"%s/%s/",rdir,ptr->d_name); 241 lstat(subdir,&stbuf); 242 //遍历子目录 243 if(S_ISDIR(stbuf.st_mode)) 244 { 245 offset = telldir(sdir); 246 sdir = 247 248 } 249 250 } 251 ptr = seekdir(dir,offset); 252 253 closedir(sdir); 254 #endif 255 256 //linux 257 void ListFolderContents(const char *root) 258 { 259 DIR *sdir; 260 DWORD attrib; 261 char subdir[512],dupdir[1024]; 262 struct dirent *ptr; 263 struct stat stbuf; 264 265 sdir = opendir(root); 266 267 while((ptr = readdir(sdir))!=NULL) 268 { 269 if(strcmp(ptr->d_name,".")==0 || strcmp(ptr->d_name,"..")==0)continue; 270 //判断是目录还是文件或者链接 271 sprintf(subdir,"%s%s\\",root,ptr->d_name); 272 lstat(subdir,&stbuf); 273 printf("[root=%s]\nsubdir: %s stbuf.st_mode=%x isdir=%d\n",root,subdir,stbuf.st_mode,S_ISDIR(stbuf.st_mode)); 274 //Sleep(3000);//调试 275 unsigned len = MultiByteToWideChar(0, 0, subdir, strlen(subdir), NULL, 0); 276 if (len == 0) return printf("error ---001----------\n"); 277 else 278 { 279 memset(dupdir,0,1024); 280 len = MultiByteToWideChar(0, 0, subdir, strlen(subdir), dupdir, len); 281 if (len == 0) return printf("error ---002----------\n"); 282 } 283 printf("%s\n",dupdir);//遍历输出全部的文件 284 Sleep(1000); 285 attrib = GetFileAttributesW(dupdir); 286 //printf("[attrib=%d][attrib=%ul]\n",attrib,attrib); 287 //遍历子目录 288 //if(S_ISDIR(stbuf.st_mode)) //linux 289 if(attrib != INVALID_FILE_ATTRIBUTES && (attrib & FILE_ATTRIBUTE_DIRECTORY) != 0) 290 { 291 ListFolderContents(subdir); 292 } 293 } 294 closedir(sdir); 295 } 296 297 #if 0 298 //windows 299 void ListFolderContents(char *root) 300 { 301 DIR *sdir; 302 char subdir[512]; 303 struct dirent *ptr; 304 struct stat stbuf; 305 306 sdir = opendir(root); 307 308 while((ptr = readdir(sdir))!=NULL) 309 { 310 //判断是目录还是文件或者链接 311 //sprintf(subdir,"%s/%s",root,ptr->d_name);//linux 312 sprintf(subdir,"%s%s",root,ptr->d_name); 313 lstat("./apps",&stbuf); //linux 314 printf("subdir: %s stbuf.st_mode=%04x isdir=%d\n",subdir,stbuf.st_mode,S_ISDIR(stbuf.st_mode)); 315 DWORD attrib = GetFileAttributesW(subdir); 316 printf("[attrib=%d][attrib=%ul]\n",attrib,attrib); 317 // GetFileAttributes(subdir) == FILE_ATTRIBUTE_DIRECTORY //windows 318 //遍历子目录 319 //if(S_ISDIR(stbuf.st_mode)) //linux 320 if(attrib != INVALID_FILE_ATTRIBUTES && (attrib & FILE_ATTRIBUTE_DIRECTORY) != 0) 321 { 322 ListFolderContents(subdir); 323 } 324 //Sleep(500);//调试 325 } 326 closedir(sdir); 327 } 328 329 #endif 330 331 //网络搜索windows 遍历方法BUG! 332 /*void ListFolderContents(char *dir) 333 { 334 HANDLE hFind; 335 WIN32_FIND_DATA findData; 336 char dirNew[512]; 337 338 // 向目录加通配符,用于搜索第一个文件 339 strcpy(dirNew, dir); 340 strcat(dirNew, "*.*"); 341 342 hFind = FindFirstFile(dirNew, &findData); 343 do 344 { 345 // 是否是文件夹,并且名称不为"."或".." 346 if(strcmp(findData.cFileName, ".") == 0 || strcmp(findData.cFileName, "..") == 0)continue; 347 if(findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) 348 { 349 // 将dirNew设置为搜索到的目录,并进行下一轮搜索 350 strcpy(dirNew, dir); 351 strcat(dirNew, "\\"); 352 strcat(dirNew, findData.cFileName); 353 printf("dir=%s\n"); 354 ListFolderContents(dirNew); 355 } 356 }while (FindNextFile(hFind, &findData)); 357 358 FindClose(hFind); 359 }*/ 360 361 362 int main(int argc, char *argv[]) 363 { 364 int len; 365 static char ServicePath[512]; 366 367 if( !GetModuleFileName( GetModuleHandle(NULL), ServicePath, 256 ) ) 368 { 369 return printf("Cannot install service (%d)\n", GetLastError()); 370 } 371 for(len=strlen(ServicePath);len>0;len--) 372 if(ServicePath[len]==0x5c){ServicePath[len+1]=0;break;} 373 printf(ServicePath); 374 //ListFolderContents("./"); 375 ListFolderContents(ServicePath);//windows 376 }
Serious. Nonsense