I finally figured out the NTFS labels after reading a rant on how UTF-8 rocks 
and how MS switched 
to UTF16 or UCS1 or whatever. The reason I couldn't grep for the label (mine 
was "myntfs") was
that it is stored as "m\0y\0n\0t\0f\0s\0\0" - found another good use for 
hexdump :)

Notes:
I only have x86 to test on, so there are a couple of places that may need 
bswap_{16,32} for endianness.
I used a 65k buf instead of toybuf (4k) for simplicity, but tried to organize 
it for toybuf if wanted.
I have info on more fs types, to patch with after review.
blkid does output for all devices if 0 args -> read /proc/partitions?


/* blkid.c - Prints type, label and UUID of filesystem(s).
 *
 * Copyright 2013 Brad Conroy <[email protected]>
 *
 * See 
ftp://ftp.kernel.org/pub/linux/utils/util-linux/v2.24/libblkid-docs/api-index-full.html

USE_BLKID(NEWTOY(blkid, NULL, TOYFLAG_BIN))

config BLKID
  bool "blkid"
  default n
  help
    usage: blkid [block device...]
    Prints type, label and UUID of filesystem.

*/
#define FOR_blkid
#include "toys.h"

#define BIT(x) (1<<(x))
#define _MATCH(buf,type,offset,match) (((unsigned type 
*)&buf[offset])[0]==(match))
#define MATCH2(b,a) (_MATCH(b,a##_TYPE,a##_OFFSET,a##_MAGIC2)||MATCH(b,a))
#define MATCH3(b,a) (_MATCH(b,a##_TYPE,a##_OFFSET,a##_MAGIC3)||MATCH2(b,a))
#define MATCH(b,a) _MATCH(b,a##_TYPE,a##_OFFSET,a##_MAGIC)
/* may need to check endianess for C2I */
#define C2I(a,b,c,d) (a|(b<<8)|(c<<16)|(d<<24))

typedef struct fs_info{
        unsigned uuid_off;
        unsigned lab_off;
        short uuid_t;
        short lab_len;
}fs_info_t;

//#define SET_FS(t) (fs_info_t){t##_UUID,t##_LABEL,t##_UUID_T,t##_LABEL_SZ}
#define SET_FS(t) (fs_info_t)t##_INFO

#define ADFS_MAGIC                      0xadf5
#define ADFS_TYPE                       short
#define ADFS_OFFSET                     0xc00
#define ADFS_INFO                       {0,0,0,0}       /*todo*/

#define BFS_MAGIC                       0x1badface
#define BFS_TYPE                        long
#define BFS_OFFSET                      0
#define BFS_INFO                        {0,0,0,0}

/*won't fit in 1 toybuf*/
#define BTRFS_MAGIC                     C2I('_','B','H','R')    //'RHB_'
//#define BTRFS_MAGIC2          'M_Sf'  /*not currently used*/
//#define BTRFS_OFFSET2         65604   /*not currently used*/
#define BTRFS_TYPE                      long    /*change to long long if full 
magic used?*/
#define BTRFS_OFFSET            65600
#define BTRFS_INFO                      {65803,65819,16,256}

#define CRAMFS_MAGIC            0x28cd3d45
#define CRAMFS_MAGIC2           0x453dcd28
#define CRAMFS_TYPE                     long
#define CRAMFS_OFFSET           0
#define CRAMFS_INFO                     {0,48,0,16}

#define EXT_MAGIC                       0xEF53
#define EXT_MAGIC2                      0xEF51
#define EXT_MAGIC3                      0x53EF
#define EXT_TYPE                        short
#define EXT_OFFSET                      1080
#define EXT3_BYTE                       1116
#define EXT4_BYTE                       1120
#define EXT_INFO                        {1128,1144,16,16}

#define F2FS_MAGIC                      0xF2F52010
#define F2FS_TYPE                       long
#define F2FS_OFFSET                     1024
#define F2FS_INFO                       {1132,1110,16,16}

/*won't fit in 1 toybuf*/
#define JFS_MAGIC                       C2I('J','S','F','1')    //'1SFJ'
#define JFS_TYPE                        long
#define JFS_OFFSET                      32768
#define JFS_INFO                        {32920,32904,16,16}

#define NILFS_MAGIC                     0x3434
#define NILFS_TYPE                      short
#define NILFS_OFFSET            1030
#define NILFS_INFO                      {1176,1192,16,80}

#define NTFS_MAGIC                      C2I('N','T','F','S')    //'SFTN'
#define NTFS_TYPE                       long
#define NTFS_OFFSET                     3
#define NTFS_INFO                       {0x48,0X4D80,8,-8}

/*won't fit in 1 toybuf*/
#define REISER_MAGIC            C2I('R','e','I','s')    //'sIeR'
#define REISER_TYPE                     long
#define REISER_OFFSET           8244
#define REISER_INFO                     {8276,8292,16,16}

#define REISERB_MAGIC           REISER_MAGIC    //'sIeR'
#define REISERB_TYPE            REISER_TYPE
#define REISERB_OFFSET          65588
#define REISERB_INFO            {65620,65636,16,16}

#define ROMFS_MAGIC                     C2I('r','o','m','-') //'-mor'
#define ROMFS_OFFSET            0
#define ROMFS_TYPE                      long
#define ROMFS_INFO                      {0,0,0,0}

#define SQUASHFS_OFFSET         0
#define SQUASHFS_TYPE           long
#define SQUASHFS_MAGIC          0x73717368
#define SQUASHFS_INFO           {0,0,0,0}

#define XIAFS_OFFSET            572
#define XIAFS_TYPE                      long
#define XIAFS_MAGIC                     0x012FD16D
#define XIAFS_INFO                      {0,0,0,0}

#define XFS_OFFSET                      0
#define XFS_TYPE                        long
#define XFS_MAGIC                       C2I('X','F','S','B')
#define XFS_INFO                        {32,108,16,12}

#if (CFG_BLKID)
char *toutf8(unsigned short * ws){      /* hack for NTFS utf16 */
        static char buf[16];
        int i=0;
        while((buf[i++]=*ws++));
        return buf;
}
#endif

/* TODO if no args use proc/partitions */
void do_blkid(int fd, char *name){      
        fs_info_t fs;
        char *fstype;
        unsigned char buf[66560];  /*toybuf is only 4096, could rework logic*/
        int sb_read;

        sb_read = read(fd, &buf, sizeof(buf));
        if (sb_read < 1) return;

        if MATCH(buf,ADFS){
                fstype="adfs";
                if (CFG_BLKID) fs=SET_FS(ADFS);
        }else if MATCH(buf,BFS){
                fstype="bfs";
                if (CFG_BLKID) fs=SET_FS(BFS);
        }else if MATCH(buf,CRAMFS){
                fstype="cramfs";
                if (CFG_BLKID) fs=SET_FS(CRAMFS);
        }else if MATCH3(buf,EXT){
                
fstype=(buf[EXT3_BYTE]&BIT(2))?((buf[EXT4_BYTE]&BIT(6))?"ext4":"ext3"):"ext2";
                if (CFG_BLKID) fs=SET_FS(EXT);
        }else if MATCH(buf,F2FS){
                fstype="f2fs";
                if (CFG_BLKID) fs=SET_FS(F2FS);
        }else if MATCH(buf,NILFS){
                fstype="nilfs";
                if (CFG_BLKID) fs=SET_FS(NILFS);
        }else if MATCH(buf,NTFS){
                fstype="ntfs";
                if (CFG_BLKID) fs=SET_FS(NTFS);
        }else if MATCH(buf,XIAFS){
                fstype="xiafs";
                if (CFG_BLKID) fs=SET_FS(XIAFS);
/*below here would require more than 1 toybuf*/
        }else if MATCH(buf,REISER){
                fstype="reiserfs";
                if (CFG_BLKID) fs=SET_FS(REISER);
        }else if MATCH(buf,JFS){
                fstype="jfs";
                if (CFG_BLKID) fs=SET_FS(JFS);
        }else if MATCH(buf,BTRFS){
                fstype="btrfs";
                if (CFG_BLKID) fs=SET_FS(BTRFS);
        }else if MATCH(buf,REISERB){
                fstype="reiserfs";
                if (CFG_BLKID) fs=SET_FS(REISERB);
        }else return;

if (CFG_BLKID  && !strncmp("blkid",toys.which->name,5) ){
        printf("%s:",name);
        if ( fs.lab_len > 0 )
                printf(" LABEL=\"%.*s\"", fs.lab_len, (char *)&buf[fs.lab_off]);
        else if ( fs.lab_len < 0 )
                printf(" LABEL=\"%.*s\"", -fs.lab_len,
                        toutf8((unsigned short *)&buf[fs.lab_off]));
        if ( fs.uuid_off > 0 ){
                if ( fs.uuid_t == 16 )
                        printf(" 
UUID=\"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-"
                        "%02x%02x%02x%02x%02x%02x\"",
                        buf[fs.uuid_off], buf[fs.uuid_off+1],
                        buf[fs.uuid_off+2], buf[fs.uuid_off+3],
                        buf[fs.uuid_off+4], buf[fs.uuid_off+5],
                        buf[fs.uuid_off+6], buf[fs.uuid_off+7],
                        buf[fs.uuid_off+8], buf[fs.uuid_off+9],
                        buf[fs.uuid_off+10], buf[fs.uuid_off+11],
                        buf[fs.uuid_off+12], buf[fs.uuid_off+13],
                        buf[fs.uuid_off+14], buf[fs.uuid_off+15]);
                if ( fs.uuid_t == 8 )
                        printf(" UUID=\"%02X%02X%02X%02X%02X%02X%02X%02X\"",
                        buf[fs.uuid_off+7], buf[fs.uuid_off+6],
                        buf[fs.uuid_off+5], buf[fs.uuid_off+4],
                        buf[fs.uuid_off+3], buf[fs.uuid_off+2],
                        buf[fs.uuid_off+1], buf[fs.uuid_off]);
        }
        printf(" TYPE=\"%s\"",fstype);
}else /* fstype */
        write(1,fstype,strlen(fstype)); /* avoid printf overhead in fstype */
        putchar('\n');
}

#if (CFG_BLKID)
void blkid_main(void)
{
  loopfiles(toys.optargs, do_blkid);
}
#endif


/* fstype.c - Prints type of filesystem(s).
 *
 * Copyright 2013 Brad Conroy <[email protected]>

USE_FSTYPE(NEWTOY(fstype, NULL, TOYFLAG_BIN))

config FSTYPE
  bool "fstype"
  default n
  help
    usage: fstype [block device...]
    Prints type of filesystem.
*/
#define FOR_fstype
#include "toys.h"
void do_blkid(int fd, char *name);
void fstype_main(void)
{
  loopfiles(toys.optargs, do_blkid);
}
_______________________________________________
Toybox mailing list
[email protected]
http://lists.landley.net/listinfo.cgi/toybox-landley.net

Reply via email to