diff options
Diffstat (limited to 'utility.c')
-rw-r--r-- | utility.c | 80 |
1 files changed, 77 insertions, 3 deletions
@@ -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 | |||
130 | static 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 | */ | ||
140 | int 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 */ | ||
158 | void 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 */ | ||
180 | void 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 | /* | ||
1409 | Local Variables: | ||
1410 | c-file-style: "linux" | ||
1411 | c-basic-offset: 4 | ||
1412 | tab-width: 4 | ||
1413 | End: | ||
1414 | */ | ||