import.c revision f79b2dff1024db4f6326f3422236bed169dd902f
1f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle/* 2f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle * Copyright (C) 2010 The Android Open Source Project 3f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle * 4f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle * Licensed under the Apache License, Version 2.0 (the "License"); 5f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle * you may not use this file except in compliance with the License. 6f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle * You may obtain a copy of the License at 7f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle * 8f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle * http://www.apache.org/licenses/LICENSE-2.0 9f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle * 10f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle * Unless required by applicable law or agreed to in writing, software 11f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle * distributed under the License is distributed on an "AS IS" BASIS, 12f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle * See the License for the specific language governing permissions and 14f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle * limitations under the License. 15f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle */ 16f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 17f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle#include <assert.h> 18f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle#include <ctype.h> 19f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle#include <dirent.h> 20f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle#include <errno.h> 21f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle#include <unistd.h> 22f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle#include <stdio.h> 23f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle#include <string.h> 24f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle#include <sys/stat.h> 25f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 26f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle#include "errors.h" 27f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle#include "extent.h" 28f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle#include "fat.h" 29f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle#include "fdpool.h" 30f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle#include "filedir.h" 31f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle#include "fs.h" 32f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle#include "import.h" 33f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle#include "utils.h" 34f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 35f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttlestatic inline int valid_char(int c) 36f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle{ 37f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle return (isalnum(c) || strchr("!#$%'()-@^_`{}~", c) || ((c >= 128) && (c < 256))); 38f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle} 39f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 40f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttlestatic int convert_name(char *short_name, const char *long_name) 41f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle{ 42f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle int i; 43f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 44f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle const char *s; 45f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle const char *dot; 46f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle int c; 47f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 48f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle dot = NULL; 49f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 50f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle for (s = long_name; *s; s++) { 51f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle if (*s == '.') { 52f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle if (dot) { 53f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle goto short_fail; 54f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle } else { 55f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle dot = s; 56f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle } 57f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle } else if (!valid_char(*s)) { 58f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle goto short_fail; 59f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle } 60f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle } 61f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 62f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle if (dot - long_name > 8) { 63f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle goto short_fail; 64f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle } 65f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 66f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle if (dot && (s - (dot + 1) > 3)) { 67f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle goto short_fail; 68f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle } 69f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 70f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle memset(short_name, ' ', 11); 71f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 72f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle if (!dot) { 73f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle dot = s; 74f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle } 75f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 76f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle for (i = 0; i < dot - long_name; i++) { 77f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle short_name[i] = toupper(long_name[i]); 78f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle } 79f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 80f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle for (i = 0; i < s - dot; i++) { 81f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle short_name[8 + i] = toupper(dot[1 + i]); 82f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle } 83f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 84f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle return 0; 85f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 86f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttleshort_fail: 87f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle return 1; 88f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle} 89f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 90f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttlestruct imported { 91f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle cluster_t first_cluster; 92f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle uint32_t size; 93f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle struct fat_dirent *dot_dot_dirent; 94f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle}; 95f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 96f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttlestatic int import_file(struct fs *fs, char *path, struct imported *out) 97f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle{ 98f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle struct stat st; 99f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle struct file *f = NULL; 100f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle char *path_copy = NULL; 101f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle int ret; 102f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 103f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle ret = stat(path, &st); 104f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle if (ret < 0) { 105f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle WARN("importing %s: stat failed: %s\n", path, strerror(errno)); 106f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle goto fail; 107f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle } 108f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 109f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle f = malloc(sizeof(struct file)); 110f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle if (!f) { 111f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle WARN("importing %s: couldn't allocate file struct: out of memory\n", path); 112f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle ret = MALLOC_FAIL; 113f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle goto fail; 114f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle } 115f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 116f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle path_copy = strdup(path); 117f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle if (!path_copy) { 118f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle WARN("importing %s: couldn't strdup path: out of memory\n", path); 119f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle ret = MALLOC_FAIL; 120f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle goto fail; 121f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle } 122f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 123f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle f->path = path_copy; 124f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle f->size = st.st_size; 125f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle f->dev = st.st_dev; 126f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle f->ino = st.st_ino; 127f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle f->mtime = st.st_mtime; 128f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle fdpool_init(&f->pfd); 129f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 130f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle ret = fs_alloc_extent(fs, &f->extent, 131f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle f->size, EXTENT_TYPE_FILE, &f->first_cluster); 132f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle if (ret) { 133f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle WARN("importing %s: couldn't allocate data extent\n", path); 134f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle goto fail; 135f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle } 136f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 137f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle out->first_cluster = f->first_cluster; 138f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle out->size = f->size; 139f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle out->dot_dot_dirent = NULL; 140f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 141f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle return 0; 142f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 143f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttlefail: 144f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle if (path_copy) 145f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle free(path_copy); 146f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle if (f) 147f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle free(f); 148f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle return ret; 149f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle} 150f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 151f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttlestruct item { 152f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle char name[11]; 153f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle struct imported imp; 154f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle struct item *next; 155f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle int is_dir; 156f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle}; 157f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 158f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttlestatic struct item *free_items_head; 159f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 160f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttlestatic struct item *alloc_item(void) 161f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle{ 162f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle struct item *item; 163f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 164f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle if (free_items_head) { 165f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle item = free_items_head; 166f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle free_items_head = item->next; 167f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle } else { 168f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle item = malloc(sizeof(struct item)); 169f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle /* May return NULL if item couldn't be allocated. */ 170f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle } 171f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 172f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle return item; 173f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle} 174f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 175f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttlestatic void free_item(struct item *item) 176f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle{ 177f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle item->next = free_items_head; 178f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle free_items_head = item; 179f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle} 180f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 181f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttlestatic void free_items(struct item *head) 182f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle{ 183f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle struct item *tail; 184f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 185f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle for (tail = head; tail->next; tail = tail->next); 186f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 187f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle tail->next = free_items_head; 188f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle free_items_head = head; 189f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle} 190f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 191f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle/* TODO: With some work, this can be rewritten so we don't recurse 192f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle * until all memory is allocated. */ 193f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttlestatic int import_dir(struct fs *fs, char *path, int is_root, struct imported *out) 194f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle{ 195f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle struct dir *d; 196f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle cluster_t first_cluster; 197f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 198f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle DIR *dir; 199f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle struct dirent *de; 200f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 201f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle char ch_path[PATH_MAX]; 202f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle struct imported *ch_imp; 203f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle cluster_t ch_first_cluster; 204f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle struct fat_dirent *ch_dirent; 205f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 206f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle int ret; 207f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 208f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle struct item *items; 209f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle struct item *item; 210f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle int count; 211f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 212f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle int i; 213f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 214f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle dir = opendir(path); 215f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle if (!dir) { 216f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle WARN("importing %s: opendir failed: %s\n", path, strerror(errno)); 217f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle return -1; 218f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle } 219f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 220f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle d = malloc(sizeof(struct dir)); 221f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle if (!d) { 222f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle WARN("importing %s: couldn't allocate dir struct: out of memory\n", path); 223f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle closedir(dir); 224f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle return MALLOC_FAIL; 225f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle } 226f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 227f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle d->path = strdup(path); 228f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle if (!d->path) { 229f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle WARN("importing %s: couldn't strdup path: out of memory\n", path); 230f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle closedir(dir); 231f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle free(d); 232f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle return MALLOC_FAIL; 233f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle } 234f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 235f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle items = NULL; 236f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle item = NULL; 237f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle count = 0; 238f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 239f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle while ((de = readdir(dir))) { 240f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle if (de->d_name[0] == '.') { 241f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle goto skip_item; 242f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle } 243f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 244f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle ret = snprintf(ch_path, PATH_MAX, "%s/%s", path, de->d_name); 245f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle if (ret < 0 || ret >= PATH_MAX) { 246f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle goto skip_item; 247f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle } 248f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 249f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle item = alloc_item(); 250f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle if (!item) { 251f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle WARN("importing %s: couldn't allocate item struct: out of memory\n", path); 252f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle ret = MALLOC_FAIL; 253f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle goto free_items; 254f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle } 255f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 256f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle if (convert_name(item->name, de->d_name)) { 257f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle goto skip_item; 258f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle } 259f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 260f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle switch (de->d_type) { 261f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle case DT_REG: 262f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle import_file(fs, ch_path, &item->imp); 263f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle item->is_dir = 0; 264f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle break; 265f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle case DT_DIR: 266f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle import_dir(fs, ch_path, 0, &item->imp); 267f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle item->is_dir = 1; 268f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle break; 269f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle default: 270f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle goto skip_item; 271f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle } 272f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 273f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle item->next = items; 274f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle items = item; 275f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 276f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle count++; 277f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 278f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle item = NULL; 279f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 280f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle continue; 281f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 282f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttleskip_item: 283f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle if (item) 284f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle free_item(item); 285f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle } 286f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 287f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle closedir(dir); 288f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 289f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle d->size = sizeof(struct fat_dirent) * (count + (is_root ? 0 : 2)); 290f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle ret = fs_alloc_extent(fs, &d->extent, d->size, EXTENT_TYPE_DIR, &d->first_cluster); 291f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle if (ret) { 292f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle WARN("importing %s: couldn't allocate directory table extent: out of space\n", path); 293f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle goto free_items; 294f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle } 295f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 296f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle first_cluster = is_root ? 0 : d->first_cluster; 297f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 298f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle d->entries = malloc(sizeof(struct fat_dirent) * (count + (is_root ? 0 : 2))); 299f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle assert(d->entries); 300f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle for (i = count - 1; i >= 0; i--) { 301f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle item = items; 302f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle items = item->next; 303f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 304f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle ch_dirent = &d->entries[i + (is_root ? 0 : 2)]; 305f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 306f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle fat_dirent_set(ch_dirent, 307f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle item->name, item->is_dir ? FAT_ATTR_SUBDIR : 0, 308f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle item->imp.first_cluster, item->imp.size); 309f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 310f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle if (item->imp.dot_dot_dirent) { 311f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle fat_dirent_set_first_cluster(item->imp.dot_dot_dirent, first_cluster); 312f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle } 313f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 314f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle free_item(item); 315f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle } 316f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 317f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle if (!is_root) { 318f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle fat_dirent_set(&d->entries[0], 319f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle ".. ", FAT_ATTR_SUBDIR, 320f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle (cluster_t)-1, 0); 321f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle out->dot_dot_dirent = &d->entries[0]; /* will set first_cluster */ 322f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 323f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle fat_dirent_set(&d->entries[1], 324f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle ". ", FAT_ATTR_SUBDIR, 325f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle first_cluster, 0); 326f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle } else { 327f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle out->dot_dot_dirent = NULL; 328f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle } 329f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 330f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle out->first_cluster = d->first_cluster; 331f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle out->size = 0; 332f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 333f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle return 0; 334f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 335f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttlefree_items: 336f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle free_items(items); 337f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle free(d->path); 338f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle free(d); 339f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 340f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle return ret; 341f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle} 342f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 343f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttleint import_tree(struct fs *fs, char *path) 344f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle{ 345f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle struct imported imp; 346f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle int ret; 347f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 348f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle ret = import_dir(fs, path, 0, &imp); 349f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle if (ret) 350f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle return ret; 351f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 352f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle fs_set_rootdir_start(fs, imp.first_cluster); 353f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle fs_update_free_clusters(fs); 354f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle 355f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle return 0; 356f79b2dff1024db4f6326f3422236bed169dd902fThomas Tuttle} 357