скрипт для парсинга файлов каталогов

Discussion in 'Избранное' started by Scipio, 7 Dec 2007.

  1. HornetBlack

    HornetBlack Member

    Joined:
    28 Oct 2007
    Messages:
    27
    Likes Received:
    13
    Reputations:
    15
    Mailbrush, а я так понимаю, что тебе минусы девать некуда или ты можешь сказать что-нибудь полезное по обсуждаемой теме?
    Во-первых, это не археология, т.к. FBSD на хостах до сих пор встречается довольно часто и нужно получить максимум из доступной инфы.
    Во-вторых, я сейчас разрабатываю инструмент для детального исследования SI и обсуждаемая тема это только малая часть моей тулзы.
    Итак?
     
    1 person likes this.
  2. HornetBlack

    HornetBlack Member

    Joined:
    28 Oct 2007
    Messages:
    27
    Likes Received:
    13
    Reputations:
    15
    После недолгих поисков на сайте www.kernel-api.org нашел документацию по форматам записей каталога EXT/EXT2. Итого имеем 3 варианта каталогов:

    1. struct ext_dir_entry:

    unsigned long inode
    unsigned short rec_len
    unsigned short name_len
    char name [EXT_NAME_LEN]

    2. struct ext2_dir_entry:

    __u32 inode Inode number.
    __u16 rec_len Directory entry length.
    __u16 name_len Name length.
    char name [EXT2_NAME_LEN] File name.

    3. struct ext2_dir_entry2:

    __u32 inode Inode number.
    __u16 rec_len Directory entry length.
    __u8 name_len Name length.
    __u8 file_type
    char name [EXT2_NAME_LEN] File name.

    Первый и второй варианты практически идентичны (видимо для совместимости ext и ext2)

    Дополнительно по типам и выравниванию:

    #define EXT2_FT_UNKNOWN 0
    #define EXT2_FT_REG_FILE 1
    #define EXT2_FT_DIR 2
    #define EXT2_FT_CHRDEV 3
    #define EXT2_FT_BLKDEV 4
    #define EXT2_FT_FIFO 5
    #define EXT2_FT_SOCK 6
    #define EXT2_FT_SYMLINK 7
    #define EXT2_FT_MAX 8

    /**

    * EXT2_DIR_PAD defines the directory entries boundaries
    *
    * NOTE: It must be a multiple of 4

    */
    #define EXT2_DIR_PAD 4
    #define EXT2_DIR_ROUND (EXT2_DIR_PAD - 1)
    #define EXT2_DIR_REC_LEN(name_len) (((name_len) + 8 + EXT2_DIR_ROUND) & \
    ~EXT2_DIR_ROUND)


    Жаль, что до таблиц inode не добраться, но надо уметь довольствоваться малым... ))
     
    #22 HornetBlack, 30 Mar 2009
    Last edited: 30 Mar 2009
    1 person likes this.
  3. oRb

    oRb Elder - Старейшина

    Joined:
    9 May 2008
    Messages:
    294
    Likes Received:
    582
    Reputations:
    256
    Только сегодня наткнулся на эту тему, хотя скрипт уже юзал, тк нашел его на blacktoad'е.
    Scipio, отличная вещь.
    Решил немного сам покопаться.
    Там сначала идет нульбайт, далее 04 | 08 | 0a, потом идет длина имени папки/файла/ссылки. Поэтому твой скрипт не показывал файлы, в названиях которых более 16 символов.
    Пытался вдуплить как определить удален файл/папка или нет. 2 часа пялился в hex-редактор, так ничего и не придумал.
    Переписанный скрипт:
    PHP:
     <html> 
    <head> 
    <title>FreeBSD dir parser</title> 
    <style> 
        body { background-color:#444;font: 9pt Lucida,Verdana;color:#fff;margin: 5; } 
        a { text-decoration:none; color:#df5; } 
    </style> 
    </head> 
    <body> 
    <form method="post"> 
    Path: <input type="text" name="pole" value="<?=htmlspecialchars($_POST['pole']);?>"/> <input type="submit"/> 
    </form> 
    <pre> 
    <?php 
    error_reporting
    ); 
    set_time_limit); 
    if ( isset( 
    $_POST['pole'] ) ) 
        
    $str = @file_get_contents$_POST['pole'] ); 
    if ( !empty( 
    $str ) ) { 
        
    $content = array( 'dirs' => array(), 'files' => array(), 'links' => array() ); 
        function 
    getItem$type, &$i ) { 
            
    $item_len ord$GLOBALS['str'][$i+1] ); 
            if( 
    $item_len && ( ord($GLOBALS['str'][$i+2]) != ) ) {
                
    $item substr$GLOBALS['str'], $i+2$item_len );
                if( 
    strpos($item"\0") !== false )
                    return;
                
    $GLOBALS['content'][$type][] = substr$GLOBALS['str'], $i+2$item_len );
            } else
                
    $item_len 0
            
    $i += $item_len
        } 
        
    $len strlen$str ); 
        for( 
    $i 0$i $len$i++ ) { 
            if( 
    ord$str[$i] ) != 
                continue; 
            
    $i++; 
            
    $char ord$str[$i] ); 
            if( 
    $char == 0x04 
                
    getItem('dirs'$i); 
            elseif( 
    $char == 0x08 
                
    getItem('files'$i); 
            elseif( 
    $char == 0x0a 
                
    getItem('links'$i); 
        } 
        
    sort($content['dirs']); 
        foreach( 
    $content['dirs'] as $item 
            echo 
    "<i>dir</i>\t[ ".$item." ]\n"
        
    sort($content['files']); 
        foreach(
    $content['files'] as $item
            echo 
    "<i>file</i>\t".$item."\n"
        
    sort($content['links']); 
        foreach(
    $content['links'] as $item
            echo 
    "<i>link</i>\t".$item."\n"

    ?> 
    </pre> 
    <a href="https://forum.antichat.ru/thread55237.html">Original https://forum.antichat.ru/thread55237.html</a> 
    </body> 
    </html> 
     
    #23 oRb, 23 Aug 2009
    Last edited: 1 Nov 2009
    3 people like this.