X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=e2fsck%2Fmessage.c;h=9aaedc5082cf61966defd552c8a16e0f66254c68;hb=2e6436d459307af8d6be6fb0da6ab24860d8e677;hp=90861f95585340b4f9a897c1235a632a7df03d2f;hpb=1ce6453931d74a05d96c009983d342e524ab2912;p=tools%2Fe2fsprogs.git diff --git a/e2fsck/message.c b/e2fsck/message.c index 90861f9..9aaedc5 100644 --- a/e2fsck/message.c +++ b/e2fsck/message.c @@ -14,17 +14,18 @@ * The following % expansions are supported: * * %b block number - * %B integer + * %B interpret blkcount as blkcount * %c block number - * %di ->ino inode number - * %dn ->name string - * %dr ->rec_len - * %dl ->name_len - * %dt ->filetype - * %D inode number + * %Di ->ino inode number + * %Dn ->name string + * %Dr ->rec_len + * %Dl ->name_len + * %Dt ->filetype + * %d inode number * %g integer * %i inode number * %Is -> i_size + * %IS -> i_extra_isize * %Ib -> i_blocks * %Il -> i_links_count * %Im -> i_mode @@ -34,6 +35,7 @@ * %Id -> i_dir_acl * %Iu -> i_uid * %Ig -> i_gid + * %It * %j inode number * %m * %N @@ -44,20 +46,19 @@ * %q ext2fs_get_pathname of directory * %Q ext2fs_get_pathname of directory with as * the containing directory. + * %r interpret blkcount as refcount * %s miscellaneous string * %S backup superblock * %X hexadecimal format * * The following '@' expansions are supported: * + * @a extended attribute * @A error allocating * @b block * @B bitmap * @c compress * @C conflicts with some other fs block - * @i inode - * @I illegal - * @j journal * @D deleted * @d directory * @e entry @@ -65,13 +66,22 @@ * @f filesystem * @F for @i %i (%Q) is * @g group + * @h HTREE directory inode + * @i inode + * @I illegal + * @j journal * @l lost+found * @L is a link + * @m multiply-claimed + * @n invalid * @o orphaned + * @p problem in * @r root inode - * @s should be + * @s should be * @S superblock * @u unattached + * @v device + * @x extent * @z zero-length */ @@ -98,6 +108,7 @@ * letter in the table below. */ static const char *abbrevs[] = { + N_("aextended attribute"), N_("Aerror allocating"), N_("bblock"), N_("Bbitmap"), @@ -113,13 +124,19 @@ static const char *abbrevs[] = { N_("ffilesystem"), N_("Ffor @i %i (%Q) is"), N_("ggroup"), + N_("hHTREE @d @i"), N_("llost+found"), N_("Lis a link"), + N_("mmultiply-claimed"), + N_("ninvalid"), N_("oorphaned"), + N_("pproblem in"), N_("rroot @i"), N_("sshould be"), N_("Ssuper@b"), N_("uunattached"), + N_("vdevice"), + N_("xextent"), N_("zzero-length"), "@@", 0 @@ -128,7 +145,7 @@ static const char *abbrevs[] = { /* * Give more user friendly names to the "special" inodes. */ -#define num_special_inodes 7 +#define num_special_inodes 11 static const char *special_inode_name[] = { N_(""), /* 0 */ @@ -137,7 +154,11 @@ static const char *special_inode_name[] = N_(""), /* 3 */ N_(""), /* 4 */ N_(""), /* 5 */ - N_("") /* 6 */ + N_(""), /* 6 */ + N_(""), /* 7 */ + N_(""), /* 8 */ + N_(""), /* 9 */ + N_(""), /* 10 */ }; /* @@ -170,7 +191,7 @@ static void safe_print(const char *cp, int len) * This function prints a pathname, using the ext2fs_get_pathname * function */ -static void print_pathname(ext2_filsys fs, ino_t dir, ino_t ino) +static void print_pathname(ext2_filsys fs, ext2_ino_t dir, ext2_ino_t ino) { errcode_t retval; char *path; @@ -179,39 +200,57 @@ static void print_pathname(ext2_filsys fs, ino_t dir, ino_t ino) fputs(_(special_inode_name[ino]), stdout); return; } - + retval = ext2fs_get_pathname(fs, dir, ino, &path); if (retval) fputs("???", stdout); else { safe_print(path, -1); - ext2fs_free_mem((void **) &path); + ext2fs_free_mem(&path); } } +static void print_time(time_t t) +{ + const char * time_str; + static int do_gmt = -1; + +#ifdef __dietlibc__ + /* The diet libc doesn't respect the TZ environemnt variable */ + if (do_gmt == -1) { + time_str = getenv("TZ"); + if (!time_str) + time_str = ""; + do_gmt = !strcmp(time_str, "GMT0"); + } +#endif + time_str = asctime((do_gmt > 0) ? gmtime(&t) : localtime(&t)); + printf("%.24s", time_str); +} + /* * This function handles the '@' expansion. We allow recursive * expansion; an @ expression can contain further '@' and '%' - * expressions. + * expressions. */ static _INLINE_ void expand_at_expression(e2fsck_t ctx, char ch, struct problem_context *pctx, - int *first) + int *first, int recurse) { const char **cpp, *str; - + /* Search for the abbreviation */ for (cpp = abbrevs; *cpp; cpp++) { if (ch == *cpp[0]) break; } - if (*cpp) { - str = (*cpp) + 1; + if (*cpp && recurse < 10) { + str = _(*cpp) + 1; if (*first && islower(*str)) { *first = 0; fputc(toupper(*str++), stdout); } - print_e2fsck_message(ctx, _(str), pctx, *first); + print_e2fsck_message(ctx, str, pctx, *first, recurse+1); } else printf("@%c", ch); } @@ -219,18 +258,19 @@ static _INLINE_ void expand_at_expression(e2fsck_t ctx, char ch, /* * This function expands '%IX' expressions */ -static _INLINE_ void expand_inode_expression(char ch, - struct problem_context *ctx) +static _INLINE_ void expand_inode_expression(ext2_filsys fs, char ch, + struct problem_context *ctx) { struct ext2_inode *inode; - char * time_str; + struct ext2_inode_large *large_inode; time_t t; if (!ctx || !ctx->inode) goto no_inode; - + inode = ctx->inode; - + large_inode = (struct ext2_inode_large *) inode; + switch (ch) { case 's': if (LINUX_S_ISDIR(inode->i_mode)) @@ -243,13 +283,22 @@ static _INLINE_ void expand_inode_expression(char ch, else printf("%u", inode->i_size); #else - printf("%llu", (inode->i_size | - ((__u64) inode->i_size_high << 32))); + printf("%llu", inode->i_size | + ((long long)inode->i_size_high << 32)); #endif } break; + case 'S': + printf("%u", large_inode->i_extra_isize); + break; case 'b': - printf("%u", inode->i_blocks); + if (fs->super->s_feature_ro_compat & + EXT4_FEATURE_RO_COMPAT_HUGE_FILE) + printf("%llu", inode->i_blocks + + (((long long) inode->osd2.linux2.l_i_blocks_hi) + << 32)); + else + printf("%u", inode->i_blocks); break; case 'l': printf("%d", inode->i_links_count); @@ -258,9 +307,7 @@ static _INLINE_ void expand_inode_expression(char ch, printf("0%o", inode->i_mode); break; case 'M': - t = inode->i_mtime; - time_str = ctime(&t); - printf("%.24s", time_str); + print_time(inode->i_mtime); break; case 'F': printf("%u", inode->i_faddr); @@ -273,12 +320,29 @@ static _INLINE_ void expand_inode_expression(char ch, inode->i_dir_acl : 0)); break; case 'u': - printf("%d", (inode->i_uid | - (inode->osd2.linux2.l_i_uid_high << 16))); + printf("%d", inode_uid(*inode)); break; case 'g': - printf("%d", (inode->i_gid | - (inode->osd2.linux2.l_i_gid_high << 16))); + printf("%d", inode_gid(*inode)); + break; + case 't': + if (LINUX_S_ISREG(inode->i_mode)) + printf(_("regular file")); + else if (LINUX_S_ISDIR(inode->i_mode)) + printf(_("directory")); + else if (LINUX_S_ISCHR(inode->i_mode)) + printf(_("character device")); + else if (LINUX_S_ISBLK(inode->i_mode)) + printf(_("block device")); + else if (LINUX_S_ISFIFO(inode->i_mode)) + printf(_("named pipe")); + else if (LINUX_S_ISLNK(inode->i_mode)) + printf(_("symbolic link")); + else if (LINUX_S_ISSOCK(inode->i_mode)) + printf(_("socket")); + else + printf(_("unknown file type with mode 0%o"), + inode->i_mode); break; default: no_inode: @@ -290,17 +354,18 @@ static _INLINE_ void expand_inode_expression(char ch, /* * This function expands '%dX' expressions */ -static _INLINE_ void expand_dirent_expression(char ch, +static _INLINE_ void expand_dirent_expression(ext2_filsys fs, char ch, struct problem_context *ctx) { struct ext2_dir_entry *dirent; + unsigned int rec_len; int len; - + if (!ctx || !ctx->dirent) goto no_dirent; - + dirent = ctx->dirent; - + switch (ch) { case 'i': printf("%u", dirent->inode); @@ -309,12 +374,14 @@ static _INLINE_ void expand_dirent_expression(char ch, len = dirent->name_len & 0xFF; if (len > EXT2_NAME_LEN) len = EXT2_NAME_LEN; - if (len > dirent->rec_len) - len = dirent->rec_len; + if ((ext2fs_get_rec_len(fs, dirent, &rec_len) == 0) && + (len > rec_len)) + len = rec_len; safe_print(dirent->name, len); break; case 'r': - printf("%u", dirent->rec_len); + (void) ext2fs_get_rec_len(fs, dirent, &rec_len); + printf("%u", rec_len); break; case 'l': printf("%u", dirent->name_len & 0xFF); @@ -330,39 +397,66 @@ static _INLINE_ void expand_dirent_expression(char ch, } static _INLINE_ void expand_percent_expression(ext2_filsys fs, char ch, + int *first, struct problem_context *ctx) { + e2fsck_t e2fsck_ctx = fs ? (e2fsck_t) fs->priv_data : NULL; + const char *m; + if (!ctx) goto no_context; - + switch (ch) { case '%': fputc('%', stdout); break; case 'b': - printf("%u", ctx->blk); +#ifdef EXT2_NO_64_TYPE + printf("%u", (unsigned long) ctx->blk); +#else + printf("%llu", (unsigned long long) ctx->blk); +#endif break; case 'B': + if (ctx->blkcount == BLOCK_COUNT_IND) + m = _("indirect block"); + else if (ctx->blkcount == BLOCK_COUNT_DIND) + m = _("double indirect block"); + else if (ctx->blkcount == BLOCK_COUNT_TIND) + m = _("triple indirect block"); + else if (ctx->blkcount == BLOCK_COUNT_TRANSLATOR) + m = _("translator block"); + else + m = _("block #"); + if (*first && islower(m[0])) + fputc(toupper(*m++), stdout); + fputs(m, stdout); + if (ctx->blkcount >= 0) { #ifdef EXT2_NO_64_TYPE - printf("%d", ctx->blkcount); + printf("%d", ctx->blkcount); #else - printf("%lld", ctx->blkcount); + printf("%lld", (long long) ctx->blkcount); #endif + } break; case 'c': - printf("%u", ctx->blk2); +#ifdef EXT2_NO_64_TYPE + printf("%u", (unsigned long) ctx->blk2); +#else + printf("%llu", (unsigned long long) ctx->blk2); +#endif break; case 'd': - printf("%lu", ctx->dir); + printf("%u", ctx->dir); break; case 'g': printf("%d", ctx->group); break; case 'i': - printf("%lu", ctx->ino); + printf("%u", ctx->ino); break; case 'j': - printf("%lu", ctx->ino2); + printf("%u", ctx->ino2); break; case 'm': printf("%s", error_message(ctx->errcode)); @@ -371,7 +465,7 @@ static _INLINE_ void expand_percent_expression(ext2_filsys fs, char ch, #ifdef EXT2_NO_64_TYPE printf("%u", ctx->num); #else - printf("%llu", ctx->num); + printf("%llu", (long long)ctx->num); #endif break; case 'p': @@ -387,17 +481,30 @@ static _INLINE_ void expand_percent_expression(ext2_filsys fs, char ch, case 'Q': print_pathname(fs, ctx->dir, ctx->ino); break; + case 'r': +#ifdef EXT2_NO_64_TYPE + printf("%d", ctx->blkcount); +#else + printf("%lld", (long long) ctx->blkcount); +#endif + break; case 'S': - printf("%d", get_backup_sb(fs)); + printf("%u", get_backup_sb(NULL, fs, NULL, NULL)); break; case 's': printf("%s", ctx->str ? ctx->str : "NULL"); break; + case 't': + print_time((time_t) ctx->num); + break; + case 'T': + print_time(e2fsck_ctx ? e2fsck_ctx->now : time(0)); + break; case 'X': #ifdef EXT2_NO_64_TYPE printf("0x%x", ctx->num); #else - printf("0x%llx", ctx->num); + printf("0x%llx", (long long)ctx->num); #endif break; default: @@ -405,10 +512,11 @@ static _INLINE_ void expand_percent_expression(ext2_filsys fs, char ch, printf("%%%c", ch); break; } -} +} void print_e2fsck_message(e2fsck_t ctx, const char *msg, - struct problem_context *pctx, int first) + struct problem_context *pctx, int first, + int recurse) { ext2_filsys fs = ctx->fs; const char * cp; @@ -418,16 +526,16 @@ void print_e2fsck_message(e2fsck_t ctx, const char *msg, for (cp = msg; *cp; cp++) { if (cp[0] == '@') { cp++; - expand_at_expression(ctx, *cp, pctx, &first); + expand_at_expression(ctx, *cp, pctx, &first, recurse); } else if (cp[0] == '%' && cp[1] == 'I') { cp += 2; - expand_inode_expression(*cp, pctx); + expand_inode_expression(fs, *cp, pctx); } else if (cp[0] == '%' && cp[1] == 'D') { cp += 2; - expand_dirent_expression(*cp, pctx); + expand_dirent_expression(fs, *cp, pctx); } else if ((cp[0] == '%')) { cp++; - expand_percent_expression(fs, *cp, pctx); + expand_percent_expression(fs, *cp, &first, pctx); } else { for (i=0; cp[i]; i++) if ((cp[i] == '@') || cp[i] == '%')