X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=fs%2Fcramfs%2Fcramfs.c;h=228f599d44bbca3e7c067ab5ae86ce9981e10a5e;hb=362b991cbe203cd4795e4231aeb7b3388776da0f;hp=369d1f16740a2abbb040842f994c694f966f8234;hpb=d61ea14885631e58a25feaa81ee82eb464c62d6a;p=oweals%2Fu-boot.git diff --git a/fs/cramfs/cramfs.c b/fs/cramfs/cramfs.c index 369d1f1674..228f599d44 100644 --- a/fs/cramfs/cramfs.c +++ b/fs/cramfs/cramfs.c @@ -26,9 +26,6 @@ #include #include - -#if defined(CONFIG_CMD_JFFS2) - #include #include #include @@ -44,8 +41,16 @@ struct cramfs_super super; /* CPU address space offset calculation macro, struct part_info offset is * device address space offset, so we need to shift it by a device start address. */ +#if defined(CONFIG_MTD_NOR_FLASH) extern flash_info_t flash_info[]; -#define PART_OFFSET(x) (x->offset + flash_info[x->dev->id->num].start[0]) +#define PART_OFFSET(x) ((ulong)x->offset + \ + flash_info[x->dev->id->num].start[0]) +#else +#define PART_OFFSET(x) ((ulong)x->offset) +#endif + +static int cramfs_uncompress (unsigned long begin, unsigned long offset, + unsigned long loadoffset); static int cramfs_read_super (struct part_info *info) { @@ -92,6 +97,22 @@ static int cramfs_read_super (struct part_info *info) return 0; } +/* Unpack to an allocated buffer, trusting in the inode's size field. */ +static char *cramfs_uncompress_link (unsigned long begin, unsigned long offset) +{ + struct cramfs_inode *inode = (struct cramfs_inode *)(begin + offset); + unsigned long size = CRAMFS_24 (inode->size); + char *link = malloc (size + 1); + + if (!link || cramfs_uncompress (begin, offset, (unsigned long)link) != size) { + free (link); + link = NULL; + } else { + link[size] = '\0'; + } + return link; +} + static unsigned long cramfs_resolve (unsigned long begin, unsigned long offset, unsigned long size, int raw, char *filename) @@ -125,7 +146,8 @@ static unsigned long cramfs_resolve (unsigned long begin, unsigned long offset, namelen--; } - if (!strncmp (filename, name, namelen)) { + if (!strncmp(filename, name, namelen) && + (namelen == strlen(filename))) { char *p = strtok (NULL, "/"); if (raw && (p == NULL || *p == '\0')) @@ -140,6 +162,33 @@ static unsigned long cramfs_resolve (unsigned long begin, unsigned long offset, p); } else if (S_ISREG (CRAMFS_16 (inode->mode))) { return offset + inodeoffset; + } else if (S_ISLNK (CRAMFS_16 (inode->mode))) { + unsigned long ret; + char *link; + if (p && strlen(p)) { + printf ("unsupported symlink to \ + non-terminal path\n"); + return 0; + } + link = cramfs_uncompress_link (begin, + offset + inodeoffset); + if (!link) { + printf ("%*.*s: Error reading link\n", + namelen, namelen, name); + return 0; + } else if (link[0] == '/') { + printf ("unsupported symlink to \ + absolute path\n"); + free (link); + return 0; + } + ret = cramfs_resolve (begin, + offset, + size, + raw, + strtok(link, "/")); + free (link); + return ret; } else { printf ("%*.*s: unsupported file type (%x)\n", namelen, namelen, name, @@ -159,7 +208,7 @@ static int cramfs_uncompress (unsigned long begin, unsigned long offset, unsigned long loadoffset) { struct cramfs_inode *inode = (struct cramfs_inode *) (begin + offset); - unsigned long *block_ptrs = (unsigned long *) + u32 *block_ptrs = (u32 *) (begin + (CRAMFS_GET_OFFSET (inode) << 2)); unsigned long curr_block = (CRAMFS_GET_OFFSET (inode) + (((CRAMFS_24 (inode->size)) + @@ -232,20 +281,12 @@ static int cramfs_list_inode (struct part_info *info, unsigned long offset) CRAMFS_24 (inode->size), namelen, namelen, name); if ((CRAMFS_16 (inode->mode) & S_IFMT) == S_IFLNK) { - /* symbolic link. - * Unpack the link target, trusting in the inode's size field. - */ - unsigned long size = CRAMFS_24 (inode->size); - char *link = malloc (size); - - if (link != NULL && cramfs_uncompress (PART_OFFSET(info), offset, - (unsigned long) link) - == size) - printf (" -> %*.*s\n", (int) size, (int) size, link); + char *link = cramfs_uncompress_link (PART_OFFSET(info), offset); + if (link) + printf (" -> %s\n", link); else printf (" [Error reading link]\n"); - if (link) - free (link); + free (link); } else printf ("\n"); @@ -343,5 +384,3 @@ int cramfs_check (struct part_info *info) } return 1; } - -#endif /* CFG_FS_CRAMFS */