| 
									
										
										
										
											2011-05-25 00:24:33 +01:00
										 |  |  | /* See LICENSE file for copyright and license details. */ | 
					
						
							|  |  |  | #include <dirent.h>
 | 
					
						
							| 
									
										
										
										
											2014-01-30 12:37:35 +00:00
										 |  |  | #include <limits.h>
 | 
					
						
							|  |  |  | #include <stdio.h>
 | 
					
						
							| 
									
										
										
										
											2011-05-25 00:24:33 +01:00
										 |  |  | #include <stdlib.h>
 | 
					
						
							|  |  |  | #include <string.h>
 | 
					
						
							| 
									
										
										
										
											2011-06-04 14:30:54 +01:00
										 |  |  | #include <sys/stat.h>
 | 
					
						
							| 
									
										
										
										
											2014-01-30 12:37:35 +00:00
										 |  |  | #include <sys/types.h>
 | 
					
						
							|  |  |  | #include <unistd.h>
 | 
					
						
							| 
									
										
										
										
											2013-03-05 21:46:48 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-25 00:24:33 +01:00
										 |  |  | #include "../util.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-02 21:43:56 +01:00
										 |  |  | int recurse_follow = 'P'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-25 00:24:33 +01:00
										 |  |  | void | 
					
						
							| 
									
										
										
										
											2015-03-02 21:43:56 +01:00
										 |  |  | recurse(const char *path, void (*fn)(const char *, int), int depth) | 
					
						
							| 
									
										
										
										
											2011-05-25 00:24:33 +01:00
										 |  |  | { | 
					
						
							|  |  |  | 	struct dirent *d; | 
					
						
							| 
									
										
										
										
											2015-02-09 19:53:24 +00:00
										 |  |  | 	struct stat lst, st; | 
					
						
							| 
									
										
										
										
											2011-05-25 00:24:33 +01:00
										 |  |  | 	DIR *dp; | 
					
						
							| 
									
										
										
										
											2015-03-03 00:11:41 +01:00
										 |  |  | 	size_t len; | 
					
						
							|  |  |  | 	char *buf; | 
					
						
							| 
									
										
										
										
											2011-05-25 00:24:33 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-02 21:43:56 +01:00
										 |  |  | 	if (lstat(path, &lst) < 0) | 
					
						
							|  |  |  | 		eprintf("lstat %s:", path); | 
					
						
							|  |  |  | 	if (stat(path, &st) < 0) | 
					
						
							|  |  |  | 		eprintf("stat %s:", path); | 
					
						
							|  |  |  | 	if (!S_ISDIR(lst.st_mode) && !(S_ISLNK(lst.st_mode) && S_ISDIR(st.st_mode) && | 
					
						
							|  |  |  | 	    !(recurse_follow == 'P' || (recurse_follow == 'H' && depth > 0)))) | 
					
						
							| 
									
										
										
										
											2011-06-04 14:30:54 +01:00
										 |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2014-06-30 15:58:00 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (!(dp = opendir(path))) | 
					
						
							| 
									
										
										
										
											2011-06-04 14:30:54 +01:00
										 |  |  | 		eprintf("opendir %s:", path); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-03 00:11:41 +01:00
										 |  |  | 	len = strlen(path); | 
					
						
							| 
									
										
										
										
											2014-06-30 15:58:00 +01:00
										 |  |  | 	while ((d = readdir(dp))) { | 
					
						
							| 
									
										
										
										
											2015-03-02 21:43:56 +01:00
										 |  |  | 		if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, "..")) | 
					
						
							| 
									
										
										
										
											2014-01-30 12:37:35 +00:00
										 |  |  | 			continue; | 
					
						
							| 
									
										
										
										
											2015-03-03 00:11:41 +01:00
										 |  |  | 		buf = emalloc(len + (*(path + len) != '/') + strlen(d->d_name) + 1); | 
					
						
							|  |  |  | 		sprintf(buf, "%s%s%s", path, (*(path + len) == '/') ? "" : "/", d->d_name); | 
					
						
							| 
									
										
										
										
											2015-03-02 21:43:56 +01:00
										 |  |  | 		fn(buf, depth + 1); | 
					
						
							| 
									
										
										
										
											2015-03-03 00:11:41 +01:00
										 |  |  | 		free(buf); | 
					
						
							| 
									
										
										
										
											2013-03-05 21:46:48 +01:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2011-05-25 00:24:33 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	closedir(dp); | 
					
						
							|  |  |  | } |