aboutsummaryrefslogtreecommitdiff
path: root/utility.c
diff options
context:
space:
mode:
Diffstat (limited to 'utility.c')
-rw-r--r--utility.c80
1 files changed, 77 insertions, 3 deletions
diff --git a/utility.c b/utility.c
index 0279cca56..c8ce3921a 100644
--- a/utility.c
+++ b/utility.c
@@ -122,7 +122,76 @@ int get_kernel_revision()
122} 122}
123#endif /* BB_INIT || BB_PS */ 123#endif /* BB_INIT || BB_PS */
124 124
125#if defined (BB_CP_MV) || defined (BB_DU)
125 126
127#define HASH_SIZE 311 /* Should be prime */
128#define hash_inode(i) ((i) % HASH_SIZE)
129
130static ino_dev_hashtable_bucket_t *ino_dev_hashtable[HASH_SIZE];
131
132/*
133 * Return 1 if statbuf->st_ino && statbuf->st_dev are recorded in
134 * `ino_dev_hashtable', else return 0
135 *
136 * If NAME is a non-NULL pointer to a character pointer, and there is
137 * a match, then set *NAME to the value of the name slot in that
138 * bucket.
139 */
140int is_in_ino_dev_hashtable(const struct stat *statbuf, char **name)
141{
142 ino_dev_hashtable_bucket_t *bucket;
143
144 bucket = ino_dev_hashtable[hash_inode(statbuf->st_ino)];
145 while (bucket != NULL) {
146 if ((bucket->ino == statbuf->st_ino) &&
147 (bucket->dev == statbuf->st_dev))
148 {
149 if (name) *name = bucket->name;
150 return 1;
151 }
152 bucket = bucket->next;
153 }
154 return 0;
155}
156
157/* Add statbuf to statbuf hash table */
158void add_to_ino_dev_hashtable(const struct stat *statbuf, const char *name)
159{
160 int i;
161 size_t s;
162 ino_dev_hashtable_bucket_t *bucket;
163
164 i = hash_inode(statbuf->st_ino);
165 s = name ? strlen(name) : 0;
166 bucket = malloc(sizeof(ino_dev_hashtable_bucket_t) + s);
167 if (bucket == NULL)
168 fatalError("Not enough memory.");
169 bucket->ino = statbuf->st_ino;
170 bucket->dev = statbuf->st_dev;
171 if (name)
172 strcpy(bucket->name, name);
173 else
174 bucket->name[0] = '\0';
175 bucket->next = ino_dev_hashtable[i];
176 ino_dev_hashtable[i] = bucket;
177}
178
179/* Clear statbuf hash table */
180void reset_ino_dev_hashtable(void)
181{
182 int i;
183 ino_dev_hashtable_bucket_t *bucket;
184
185 for (i = 0; i < HASH_SIZE; i++) {
186 while (ino_dev_hashtable[i] != NULL) {
187 bucket = ino_dev_hashtable[i]->next;
188 free(ino_dev_hashtable[i]);
189 ino_dev_hashtable[i] = bucket;
190 }
191 }
192}
193
194#endif /* BB_CP_MV || BB_DU */
126 195
127#if defined (BB_CP_MV) || defined (BB_DU) || defined (BB_LN) 196#if defined (BB_CP_MV) || defined (BB_DU) || defined (BB_LN)
128/* 197/*
@@ -161,7 +230,7 @@ int isDirectory(const char *fileName, const int followLinks, struct stat *statBu
161/* 230/*
162 * Copy one file to another, while possibly preserving its modes, times, 231 * Copy one file to another, while possibly preserving its modes, times,
163 * and modes. Returns TRUE if successful, or FALSE on a failure with an 232 * and modes. Returns TRUE if successful, or FALSE on a failure with an
164 * error message output. (Failure is not indicted if the attributes cannot 233 * error message output. (Failure is not indicated if the attributes cannot
165 * be set.) 234 * be set.)
166 * -Erik Andersen 235 * -Erik Andersen
167 */ 236 */
@@ -1335,6 +1404,11 @@ extern void whine_if_fstab_is_missing()
1335} 1404}
1336#endif 1405#endif
1337 1406
1338
1339
1340/* END CODE */ 1407/* END CODE */
1408/*
1409Local Variables:
1410c-file-style: "linux"
1411c-basic-offset: 4
1412tab-width: 4
1413End:
1414*/