⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cramfs_cb.~c

📁 在win(2000/2003)下面制作CRAMFS映像文件 专门用于嵌入式Linux开发 由于网络上没有类似的软件 索性自己写了一个 经过测试OK 全部源代码
💻 ~C
📖 第 1 页 / 共 3 页
字号:
        TSearchRec search_rec;

        if(0 == FindFirst(file_name,faAnyFile,search_rec))
        {
                buf->st_size = search_rec.Size;

                if((search_rec.Attr & faDirectory)== faDirectory)
                        buf->st_mode = S_IFDIR;
                else
                        buf->st_mode = S_IFREG;

                FindClose(search_rec);

                return(0);
        }

        return(-1);
}
//---------------------------------------------------------
static unsigned int parse_directory(struct entry *root_entry,
        const char *name, struct entry **prev, unsigned int *fslen_ub)
{
        struct dirent **dirlist;
        int totalsize = 0, dircount, dirindex;
        char *path, *endpath;
        size_t len = strlen(name);

        /* Set up the path. */
        /* TODO: Reuse the parent's buffer to save memcpy'ing and duplication. */
        path = (char *)malloc(len + 1 + MAX_INPUT_NAMELEN + 1);
        if (!path) {
                die(MKFS_ERROR, 1, "malloc failed");
        }
        memcpy(path, name, len);
        endpath = path + len;
        *endpath = '/';
        endpath++;

        /* read in the directory and sort */
        dircount = scandir(name, &dirlist, 0, cramsort);

        if (dircount < 0) {
                die(MKFS_ERROR, 1, "scandir failed: %s", name);
        }

        /* process directory */
        for (dirindex = 0; dirindex < dircount; dirindex++) {
                struct dirent *dirent;
                struct entry *entry;
                struct stat st;
                int size;
                size_t namelen;

                dirent = dirlist[dirindex];

                /* Ignore "." and ".." - we won't be adding them to the archive */
                if (dirent->d_name[0] == '.') {
                        if (dirent->d_name[1] == '\0')
                                continue;
                        if (dirent->d_name[1] == '.') {
                                if (dirent->d_name[2] == '\0')
                                        continue;
                        }
                }
                namelen = strlen(dirent->d_name);
                if (namelen > MAX_INPUT_NAMELEN) {
                        die(MKFS_ERROR, 0,
                                "very long (%u bytes) filename found: %s\n"
                                "please increase MAX_INPUT_NAMELEN in mkcramfs.c and recompile",
                                namelen, dirent->d_name);
                }
                memcpy(endpath, dirent->d_name, namelen + 1);

                if (lstat(path, &st) < 0) {
                        warn_skip = 1;
                        continue;
                }
                entry = (struct entry *)calloc(1, sizeof(struct entry));
                if (!entry) {
                        die(MKFS_ERROR, 1, "calloc failed");
                }
                entry->name = strdup(dirent->d_name);
                if (!entry->name) {
                        die(MKFS_ERROR, 1, "strdup failed");
                }
                /* truncate multi-byte UTF-8 filenames on character boundary */
                if (namelen > CRAMFS_MAXPATHLEN) {
                        namelen = CRAMFS_MAXPATHLEN;
                        warn_namelen = 1;
                        /* the first lost byte must not be a trail byte */
                        while ((entry->name[namelen] & 0xc0) == 0x80) {
                                namelen--;
                                /* are we reasonably certain it was UTF-8 ? */
                                if (entry->name[namelen] < 0x80 || !namelen) {
                                        die(MKFS_ERROR, 0, "cannot truncate filenames not encoded in UTF-8");
                                }
                        }
                        entry->name[namelen] = '\0';
                }
                entry->mode = st.st_mode;
                entry->size = st.st_size;
                entry->uid = st.st_uid;
                if (entry->uid >= 1 << CRAMFS_UID_WIDTH)
                        warn_uid = 1;
                entry->gid = st.st_gid;
                if (entry->gid >= 1 << CRAMFS_GID_WIDTH)
                        /* TODO: We ought to replace with a default
                           gid instead of truncating; otherwise there
                           are security problems.  Maybe mode should
                           be &= ~070.  Same goes for uid once Linux
                           supports >16-bit uids. */
                        warn_gid = 1;
                size = sizeof(struct cramfs_inode) + ((namelen + 3) & ~3);
                *fslen_ub += size;
                if (S_ISDIR(st.st_mode))
                {
                        entry->size = parse_directory(root_entry, path,
                                &entry->child, fslen_ub);
                }
                else
                if (S_ISREG(st.st_mode))
                {
                        if (entry->size)
                        {
                                /*
                                if (access(path, R_OK) < 0) {
                                        warn_skip = 1;
                                        continue;
                                }
                                */
                                entry->path = strdup(path);
                                if (!entry->path) {
                                        die(MKFS_ERROR, 1, "strdup failed");
                                }
                                if ((entry->size >= 1 << CRAMFS_SIZE_WIDTH)) {
                                        warn_size = 1;
                                        entry->size = (1 << CRAMFS_SIZE_WIDTH) - 1;
                                }
                        }
                }
                else
                {
                        die(MKFS_ERROR, 0, "bogus file type: %s", entry->name);
                }

                if (S_ISREG(st.st_mode))
                {
                        int blocks = ((entry->size - 1) / blksize + 1);

                        /* block pointers & data expansion allowance + data */
                        if (entry->size)
                                *fslen_ub += (4+26)*blocks + entry->size + 3;
                }

                /* Link it into the list */
                *prev = entry;
                prev = &entry->next;
                totalsize += size;
        }
        free(path);
        free(dirlist);          /* allocated by scandir() with malloc() */
        return totalsize;
}
//---------------------------------------------------------
/* Returns sizeof(struct cramfs_super), which includes the root inode. */
static unsigned int write_superblock(struct entry *root, char *base, int size)
{
        struct cramfs_super *super = (struct cramfs_super *) base;
        unsigned int offset = sizeof(struct cramfs_super) + image_length;

        offset += opt_pad;      /* 0 if no padding */

        super->magic = CRAMFS_MAGIC;
        super->flags = CRAMFS_FLAG_FSID_VERSION_2 | CRAMFS_FLAG_SORTED_DIRS;
        if (opt_holes)
                super->flags |= CRAMFS_FLAG_HOLES;
        if (image_length > 0)
                super->flags |= CRAMFS_FLAG_SHIFTED_ROOT_OFFSET;
        super->size = size;
        memcpy(super->signature, CRAMFS_SIGNATURE, sizeof(super->signature));

        super->fsid.crc = crc32(0L, Z_NULL, 0);
        super->fsid.edition = opt_edition;
        super->fsid.blocks = total_blocks;
        super->fsid.files = total_nodes;

        memset(super->name, 0x00, sizeof(super->name));
        if (opt_name)
                strncpy(super->name, opt_name, sizeof(super->name));
        else
                strncpy(super->name, "Compressed", sizeof(super->name));

        super->root.mode = root->mode;
        super->root.uid = root->uid;
        super->root.gid = root->gid;
        super->root.size = root->size;
        super->root.offset = offset >> 2;

        return offset;
}
//---------------------------------------------------------
static void set_data_offset(struct entry *entry, char *base, unsigned long offset)
{
        struct cramfs_inode *inode = (struct cramfs_inode *) (base + entry->dir_offset);

        if ((offset & 3) != 0) {
                die(MKFS_ERROR, 0, "illegal offset of %lu bytes", offset);
        }
        if (offset >= (1 << (2 + CRAMFS_OFFSET_WIDTH))) {
                die(MKFS_ERROR, 0, "filesystem too big");
        }
        inode->offset = (offset >> 2);
}
//---------------------------------------------------------
/*
 * TODO: Does this work for chars >= 0x80?  Most filesystems use UTF-8
 * encoding for filenames, whereas the console is a single-byte
 * character set like iso-latin-1.
 */

static void print_node(struct entry *e)
{
    //Application->ProcessMessages();

    //Form1->ListBox1->Items->Add((char *)(e->name));
}
//---------------------------------------------------------
/*
 * We do a width-first printout of the directory
 * entries, using a stack to remember the directories
 * we've seen.
 */
static unsigned int write_directory_structure(struct entry *entry,
        char *base, unsigned int offset)
{
        int stack_entries = 0;
        int stack_size = 64;
        struct entry **entry_stack;

        entry_stack = (struct entry **)malloc(stack_size * sizeof(struct entry *));
        if (!entry_stack) {
                die(MKFS_ERROR, 1, "malloc failed");
        }

        if (opt_verbose) {
                printf("root:\n");
        }

        for (;;) {
                int dir_start = stack_entries;
                while (entry) {
                        struct cramfs_inode *inode = (struct cramfs_inode *) (base + offset);
                        size_t len = strlen(entry->name);

                        entry->dir_offset = offset;

                        inode->mode = entry->mode;
                        inode->uid = entry->uid;
                        inode->gid = entry->gid;
                        inode->size = entry->size;
                        inode->offset = 0;
                        /* Non-empty directories, regfiles and symlinks will
                           write over inode->offset later. */

                        offset += sizeof(struct cramfs_inode);
                        total_nodes++;  /* another node */
                        memcpy(base + offset, entry->name, len);
                        /* Pad up the name to a 4-byte boundary */
                        while (len & 3) {
                                *(base + offset + len) = '\0';
                                len++;
                        }
                        inode->namelen = len >> 2;
                        offset += len;

                        if (opt_verbose)
                                print_node(entry);

                        if (entry->child) {
                                if (stack_entries >= stack_size) {
                                        stack_size *= 2;
                                        entry_stack = (struct entry **)realloc(entry_stack,
                                                stack_size * sizeof(struct entry *));
                                        if (!entry_stack) {
                                                die(MKFS_ERROR, 1, "realloc failed");
                                        }
                                }
                                entry_stack[stack_entries] = entry;
                                stack_entries++;
                        }
                        entry = entry->next;
                }

                /*
                 * Reverse the order the stack entries pushed during
                 * this directory, for a small optimization of disk
                 * access in the created fs.  This change makes things
                 * `ls -UR' order.
                 */
                {
                        struct entry **lo = entry_stack + dir_start;
                        struct entry **hi = entry_stack + stack_entries;
                        struct entry *tmp;

                        while (lo < --hi) {
                                tmp = *lo;
                                *lo++ = *hi;
                                *hi = tmp;
                        }
                }

                /* Pop a subdirectory entry from the stack, and recurse. */
                if (!stack_entries)
                        break;
                stack_entries--;
                entry = entry_stack[stack_entries];

                set_data_offset(entry, base, offset);
                if (opt_verbose) {
                        printf("%s:\n", entry->name);
                }
                entry = entry->child;
        }
        free(entry_stack);
        return offset;
}
//---------------------------------------------------------
static int is_zero(char const *begin, unsigned len)
{
        /* Returns non-zero iff the first LEN bytes from BEGIN are all NULs. */
        return (len-- == 0 ||
                (begin[0] == '\0' &&
                 (len-- == 0 ||
                  (begin[1] == '\0' &&
                   (len-- == 0 ||

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -