Magellan Linux

Diff of /trunk/mkinitrd-magellan/busybox/libbb/recursive_action.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 815 by niro, Sat Sep 1 22:45:15 2007 UTC revision 816 by niro, Fri Apr 24 18:33:46 2009 UTC
# Line 22  Line 22 
22   * is so stinking huge.   * is so stinking huge.
23   */   */
24    
25  static int true_action(const char *fileName, struct stat *statbuf, void* userData, int depth)  static int FAST_FUNC true_action(const char *fileName UNUSED_PARAM,
26     struct stat *statbuf UNUSED_PARAM,
27     void* userData UNUSED_PARAM,
28     int depth UNUSED_PARAM)
29  {  {
30   return TRUE;   return TRUE;
31  }  }
# Line 31  static int true_action(const char *fileN Line 34  static int true_action(const char *fileN
34   * recursive_action() return 0, but it doesn't stop directory traversal   * recursive_action() return 0, but it doesn't stop directory traversal
35   * (fileAction/dirAction will be called on each file).   * (fileAction/dirAction will be called on each file).
36   *   *
37   * if !depthFirst, dirAction return value of 0 (FALSE) or 2 (SKIP)   * If !ACTION_RECURSE, dirAction is called on the directory and its
38   * prevents recursion into that directory, instead   * return value is returned from recursive_action(). No recursion.
39   * recursive_action() returns 0 (if FALSE) or 1 (if SKIP).   *
40     * If ACTION_RECURSE, recursive_action() is called on each directory.
41     * If any one of these calls returns 0, current recursive_action() returns 0.
42     *
43     * If ACTION_DEPTHFIRST, dirAction is called after recurse.
44     * If it returns 0, the warning is printed and recursive_action() returns 0.
45     *
46     * If !ACTION_DEPTHFIRST, dirAction is called before we recurse.
47     * Return value of 0 (FALSE) or 2 (SKIP) prevents recursion
48     * into that directory, instead recursive_action() returns 0 (if FALSE)
49     * or 1 (if SKIP)
50   *   *
51   * followLinks=0/1 differs mainly in handling of links to dirs.   * followLinks=0/1 differs mainly in handling of links to dirs.
52   * 0: lstat(statbuf). Calls fileAction on link name even if points to dir.   * 0: lstat(statbuf). Calls fileAction on link name even if points to dir.
53   * 1: stat(statbuf). Calls dirAction and optionally recurse on link to dir.   * 1: stat(statbuf). Calls dirAction and optionally recurse on link to dir.
54   */   */
55    
56  int recursive_action(const char *fileName,  int FAST_FUNC recursive_action(const char *fileName,
57   int recurse, int followLinks, int depthFirst,   unsigned flags,
58   int (*fileAction)(const char *fileName, struct stat *statbuf, void* userData, int depth),   int FAST_FUNC (*fileAction)(const char *fileName, struct stat *statbuf, void* userData, int depth),
59   int (*dirAction)(const char *fileName, struct stat *statbuf, void* userData, int depth),   int FAST_FUNC (*dirAction)(const char *fileName, struct stat *statbuf, void* userData, int depth),
60   void* userData,   void* userData,
61   int depth)   unsigned depth)
62  {  {
63   struct stat statbuf;   struct stat statbuf;
64   int status;   int status;
# Line 55  int recursive_action(const char *fileNam Line 68  int recursive_action(const char *fileNam
68   if (!fileAction) fileAction = true_action;   if (!fileAction) fileAction = true_action;
69   if (!dirAction) dirAction = true_action;   if (!dirAction) dirAction = true_action;
70    
71   status = (followLinks ? stat : lstat)(fileName, &statbuf);   status = ACTION_FOLLOWLINKS; /* hijack a variable for bitmask... */
72     if (!depth)
73     status = ACTION_FOLLOWLINKS | ACTION_FOLLOWLINKS_L0;
74     status = ((flags & status) ? stat : lstat)(fileName, &statbuf);
75   if (status < 0) {   if (status < 0) {
76  #ifdef DEBUG_RECURS_ACTION  #ifdef DEBUG_RECURS_ACTION
77   bb_error_msg("status=%d followLinks=%d TRUE=%d",   bb_error_msg("status=%d flags=%x", status, flags);
  status, followLinks, TRUE);  
78  #endif  #endif
79   bb_perror_msg("%s", fileName);   goto done_nak_warn;
  return FALSE;  
80   }   }
81    
82   /* If S_ISLNK(m), then we know that !S_ISDIR(m).   /* If S_ISLNK(m), then we know that !S_ISDIR(m).
83   * Then we can skip checking first part: if it is true, then   * Then we can skip checking first part: if it is true, then
84   * (!dir) is also true! */   * (!dir) is also true! */
85   if ( /* (!followLinks && S_ISLNK(statbuf.st_mode)) || */   if ( /* (!(flags & ACTION_FOLLOWLINKS) && S_ISLNK(statbuf.st_mode)) || */
86   !S_ISDIR(statbuf.st_mode)   !S_ISDIR(statbuf.st_mode)
87   ) {   ) {
88   return fileAction(fileName, &statbuf, userData, depth);   return fileAction(fileName, &statbuf, userData, depth);
# Line 77  int recursive_action(const char *fileNam Line 90  int recursive_action(const char *fileNam
90    
91   /* It's a directory (or a link to one, and followLinks is set) */   /* It's a directory (or a link to one, and followLinks is set) */
92    
93   if (!recurse) {   if (!(flags & ACTION_RECURSE)) {
94   return dirAction(fileName, &statbuf, userData, depth);   return dirAction(fileName, &statbuf, userData, depth);
95   }   }
96    
97   if (!depthFirst) {   if (!(flags & ACTION_DEPTHFIRST)) {
98   status = dirAction(fileName, &statbuf, userData, depth);   status = dirAction(fileName, &statbuf, userData, depth);
99   if (!status) {   if (!status)
100   bb_perror_msg("%s", fileName);   goto done_nak_warn;
  return FALSE;  
  }  
101   if (status == SKIP)   if (status == SKIP)
102   return TRUE;   return TRUE;
103   }   }
# Line 96  int recursive_action(const char *fileNam Line 107  int recursive_action(const char *fileNam
107   /* findutils-4.1.20 reports this */   /* findutils-4.1.20 reports this */
108   /* (i.e. it doesn't silently return with exit code 1) */   /* (i.e. it doesn't silently return with exit code 1) */
109   /* To trigger: "find -exec rm -rf {} \;" */   /* To trigger: "find -exec rm -rf {} \;" */
110   bb_perror_msg("%s", fileName);   goto done_nak_warn;
  return FALSE;  
111   }   }
112   status = TRUE;   status = TRUE;
113   while ((next = readdir(dir)) != NULL) {   while ((next = readdir(dir)) != NULL) {
# Line 106  int recursive_action(const char *fileNam Line 116  int recursive_action(const char *fileNam
116   nextFile = concat_subpath_file(fileName, next->d_name);   nextFile = concat_subpath_file(fileName, next->d_name);
117   if (nextFile == NULL)   if (nextFile == NULL)
118   continue;   continue;
119   if (!recursive_action(nextFile, TRUE, followLinks, depthFirst,   /* process every file (NB: ACTION_RECURSE is set in flags) */
120   fileAction, dirAction, userData, depth+1)) {   if (!recursive_action(nextFile, flags, fileAction, dirAction,
121     userData, depth + 1))
122   status = FALSE;   status = FALSE;
123   }  // s = recursive_action(nextFile, flags, fileAction, dirAction,
124    // userData, depth + 1);
125   free(nextFile);   free(nextFile);
126    //#define RECURSE_RESULT_ABORT 3
127    // if (s == RECURSE_RESULT_ABORT) {
128    // closedir(dir);
129    // return s;
130    // }
131    // if (s == FALSE)
132    // status = FALSE;
133   }   }
134   closedir(dir);   closedir(dir);
135   if (depthFirst) {  
136   if (!dirAction(fileName, &statbuf, userData, depth)) {   if (flags & ACTION_DEPTHFIRST) {
137   bb_perror_msg("%s", fileName);   if (!dirAction(fileName, &statbuf, userData, depth))
138   return FALSE;   goto done_nak_warn;
  }  
139   }   }
140    
141   if (!status)   return status;
142   return FALSE;  
143   return TRUE;   done_nak_warn:
144     if (!(flags & ACTION_QUIET))
145     bb_simple_perror_msg(fileName);
146     return FALSE;
147  }  }

Legend:
Removed from v.815  
changed lines
  Added in v.816