diff options
author | Eric Andersen <andersen@codepoet.org> | 2001-03-16 22:47:14 +0000 |
---|---|---|
committer | Eric Andersen <andersen@codepoet.org> | 2001-03-16 22:47:14 +0000 |
commit | aad1a88c76f208d188fd061e3723bd637437e8d5 (patch) | |
tree | 75ac2b994f7f04af776e93eeedba82b873ff557e /libbb/recursive_action.c | |
parent | dfba13d199bb58d802df99c1ef20fdc0d628e86d (diff) | |
download | busybox-w32-aad1a88c76f208d188fd061e3723bd637437e8d5.tar.gz busybox-w32-aad1a88c76f208d188fd061e3723bd637437e8d5.tar.bz2 busybox-w32-aad1a88c76f208d188fd061e3723bd637437e8d5.zip |
Convert utility.c into libbb.a. It is now a whole pile of .c
files. Clean up the resulting damage and fix up the makefile.
-Erik
Diffstat (limited to 'libbb/recursive_action.c')
-rw-r--r-- | libbb/recursive_action.c | 160 |
1 files changed, 160 insertions, 0 deletions
diff --git a/libbb/recursive_action.c b/libbb/recursive_action.c new file mode 100644 index 000000000..6b93340be --- /dev/null +++ b/libbb/recursive_action.c | |||
@@ -0,0 +1,160 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * Utility routines. | ||
4 | * | ||
5 | * Copyright (C) tons of folks. Tracking down who wrote what | ||
6 | * isn't something I'm going to worry about... If you wrote something | ||
7 | * here, please feel free to acknowledge your work. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
17 | * General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
22 | * | ||
23 | * Based in part on code from sash, Copyright (c) 1999 by David I. Bell | ||
24 | * Permission has been granted to redistribute this code under the GPL. | ||
25 | * | ||
26 | */ | ||
27 | |||
28 | #include <stdio.h> | ||
29 | #include <dirent.h> | ||
30 | #include <sys/stat.h> | ||
31 | #include "libbb.h" | ||
32 | |||
33 | /* same conditions as recursive_action */ | ||
34 | #define bb_need_name_too_long | ||
35 | #define BB_DECLARE_EXTERN | ||
36 | #include "../messages.c" | ||
37 | |||
38 | #undef DEBUG_RECURS_ACTION | ||
39 | |||
40 | |||
41 | /* | ||
42 | * Walk down all the directories under the specified | ||
43 | * location, and do something (something specified | ||
44 | * by the fileAction and dirAction function pointers). | ||
45 | * | ||
46 | * Unfortunately, while nftw(3) could replace this and reduce | ||
47 | * code size a bit, nftw() wasn't supported before GNU libc 2.1, | ||
48 | * and so isn't sufficiently portable to take over since glibc2.1 | ||
49 | * is so stinking huge. | ||
50 | */ | ||
51 | int recursive_action(const char *fileName, | ||
52 | int recurse, int followLinks, int depthFirst, | ||
53 | int (*fileAction) (const char *fileName, | ||
54 | struct stat * statbuf, | ||
55 | void* userData), | ||
56 | int (*dirAction) (const char *fileName, | ||
57 | struct stat * statbuf, | ||
58 | void* userData), | ||
59 | void* userData) | ||
60 | { | ||
61 | int status; | ||
62 | struct stat statbuf; | ||
63 | struct dirent *next; | ||
64 | |||
65 | if (followLinks == TRUE) | ||
66 | status = stat(fileName, &statbuf); | ||
67 | else | ||
68 | status = lstat(fileName, &statbuf); | ||
69 | |||
70 | if (status < 0) { | ||
71 | #ifdef DEBUG_RECURS_ACTION | ||
72 | fprintf(stderr, | ||
73 | "status=%d followLinks=%d TRUE=%d\n", | ||
74 | status, followLinks, TRUE); | ||
75 | #endif | ||
76 | perror_msg("%s", fileName); | ||
77 | return FALSE; | ||
78 | } | ||
79 | |||
80 | if ((followLinks == FALSE) && (S_ISLNK(statbuf.st_mode))) { | ||
81 | if (fileAction == NULL) | ||
82 | return TRUE; | ||
83 | else | ||
84 | return fileAction(fileName, &statbuf, userData); | ||
85 | } | ||
86 | |||
87 | if (recurse == FALSE) { | ||
88 | if (S_ISDIR(statbuf.st_mode)) { | ||
89 | if (dirAction != NULL) | ||
90 | return (dirAction(fileName, &statbuf, userData)); | ||
91 | else | ||
92 | return TRUE; | ||
93 | } | ||
94 | } | ||
95 | |||
96 | if (S_ISDIR(statbuf.st_mode)) { | ||
97 | DIR *dir; | ||
98 | |||
99 | if (dirAction != NULL && depthFirst == FALSE) { | ||
100 | status = dirAction(fileName, &statbuf, userData); | ||
101 | if (status == FALSE) { | ||
102 | perror_msg("%s", fileName); | ||
103 | return FALSE; | ||
104 | } else if (status == SKIP) | ||
105 | return TRUE; | ||
106 | } | ||
107 | dir = opendir(fileName); | ||
108 | if (!dir) { | ||
109 | perror_msg("%s", fileName); | ||
110 | return FALSE; | ||
111 | } | ||
112 | status = TRUE; | ||
113 | while ((next = readdir(dir)) != NULL) { | ||
114 | char nextFile[PATH_MAX]; | ||
115 | |||
116 | if ((strcmp(next->d_name, "..") == 0) | ||
117 | || (strcmp(next->d_name, ".") == 0)) { | ||
118 | continue; | ||
119 | } | ||
120 | if (strlen(fileName) + strlen(next->d_name) + 1 > PATH_MAX) { | ||
121 | error_msg(name_too_long); | ||
122 | return FALSE; | ||
123 | } | ||
124 | memset(nextFile, 0, sizeof(nextFile)); | ||
125 | if (fileName[strlen(fileName)-1] == '/') | ||
126 | sprintf(nextFile, "%s%s", fileName, next->d_name); | ||
127 | else | ||
128 | sprintf(nextFile, "%s/%s", fileName, next->d_name); | ||
129 | if (recursive_action(nextFile, TRUE, followLinks, depthFirst, | ||
130 | fileAction, dirAction, userData) == FALSE) { | ||
131 | status = FALSE; | ||
132 | } | ||
133 | } | ||
134 | closedir(dir); | ||
135 | if (dirAction != NULL && depthFirst == TRUE) { | ||
136 | if (dirAction(fileName, &statbuf, userData) == FALSE) { | ||
137 | perror_msg("%s", fileName); | ||
138 | return FALSE; | ||
139 | } | ||
140 | } | ||
141 | if (status == FALSE) | ||
142 | return FALSE; | ||
143 | } else { | ||
144 | if (fileAction == NULL) | ||
145 | return TRUE; | ||
146 | else | ||
147 | return fileAction(fileName, &statbuf, userData); | ||
148 | } | ||
149 | return TRUE; | ||
150 | } | ||
151 | |||
152 | |||
153 | /* END CODE */ | ||
154 | /* | ||
155 | Local Variables: | ||
156 | c-file-style: "linux" | ||
157 | c-basic-offset: 4 | ||
158 | tab-width: 4 | ||
159 | End: | ||
160 | */ | ||