!C99Shell v. 1.0 pre-release build #13!

Software: Apache/2.0.54 (Unix) mod_perl/1.99_09 Perl/v5.8.0 mod_ssl/2.0.54 OpenSSL/0.9.7l DAV/2 FrontPage/5.0.2.2635 PHP/4.4.0 mod_gzip/2.0.26.1a 

uname -a: Linux snow.he.net 4.4.276-v2-mono-1 #1 SMP Wed Jul 21 11:21:17 PDT 2021 i686 

uid=99(nobody) gid=98(nobody) groups=98(nobody) 

Safe-mode: OFF (not secure)

/usr/src/linux-2.4.18-xfs-1.1/drivers/char/ftape/lowlevel/   drwxr-xr-x
Free 318.33 GB of 458.09 GB (69.49%)
Home    Back    Forward    UPDIR    Refresh    Search    Buffer    Encoder    Tools    Proc.    FTP brute    Sec.    SQL    PHP-code    Update    Feedback    Self remove    Logout    


Viewing file:     ftape-bsm.c (12.53 KB)      -rw-r--r--
Select action/file-type:
(+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
/*
 *      Copyright (C) 1994-1996 Bas Laarhoven,
 *                (C) 1996-1997 Claus Heine.

 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2, or (at your option)
 any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program; see the file COPYING.  If not, write to
 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.

 *
 * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/ftape-bsm.c,v $
 * $Revision: 1.3 $
 * $Date: 1997/10/05 19:15:15 $
 *
 *      This file contains the bad-sector map handling code for
 *      the QIC-117 floppy tape driver for Linux.
 *      QIC-40, QIC-80, QIC-3010 and QIC-3020 maps are implemented.
 */

#include <linux/string.h>

#include <linux/ftape.h>
#include "../lowlevel/ftape-tracing.h"
#include "../lowlevel/ftape-bsm.h"
#include "../lowlevel/ftape-ctl.h"
#include "../lowlevel/ftape-rw.h"

/*      Global vars.
 */

/*      Local vars.
 */
static __u8 *bad_sector_map;
static SectorCount *bsm_hash_ptr; 

typedef enum {
    forward, backward
} mode_type;

#if 0
/*  fix_tape converts a normal QIC-80 tape into a 'wide' tape.
 *  For testing purposes only !
 */
void fix_tape(__u8 * buffer, ft_format_type new_code)
{
    static __u8 list[BAD_SECTOR_MAP_SIZE];
    SectorMap *src_ptr = (SectorMap *) list;
    __u8 *dst_ptr = bad_sector_map;
    SectorMap map;
    unsigned int sector = 1;
    int i;

    if (format_code != fmt_var && format_code != fmt_big) {
        memcpy(list, bad_sector_map, sizeof(list));
        memset(bad_sector_map, 0, sizeof(bad_sector_map));
        while ((__u8 *) src_ptr - list < sizeof(list)) {
            map = *src_ptr++;
            if (map == EMPTY_SEGMENT) {
                *(SectorMap *) dst_ptr = 0x800000 + sector;
                dst_ptr += 3;
                sector += SECTORS_PER_SEGMENT;
            } else {
                for (i = 0; i < SECTORS_PER_SEGMENT; ++i) {
                    if (map & 1) {
                        *(SewctorMap *) dst_ptr = sector;
                        dst_ptr += 3;
                    }
                    map >>= 1;
                    ++sector;
                }
            }
        }
    }
    bad_sector_map_changed = 1;
    *(buffer + 4) = new_code;    /* put new format code */
    if (format_code != fmt_var && new_code == fmt_big) {
        PUT4(buffer, FT_6_HSEG_1,   (__u32)GET2(buffer, 6));
        PUT4(buffer, FT_6_HSEG_2,   (__u32)GET2(buffer, 8));
        PUT4(buffer, FT_6_FRST_SEG, (__u32)GET2(buffer, 10));
        PUT4(buffer, FT_6_LAST_SEG, (__u32)GET2(buffer, 12));
        memset(buffer+6, '\0', 8);
    }
    format_code = new_code;
}

#endif

/*   given buffer that contains a header segment, find the end of
 *   of the bsm list
 */
__u8 * ftape_find_end_of_bsm_list(__u8 * address)
{
    __u8 *ptr   = address + FT_HEADER_END; /* start of bsm list */
    __u8 *limit = address + FT_SEGMENT_SIZE;
    while (ptr + 2 < limit) {
        if (ptr[0] || ptr[1] || ptr[2]) {
            ptr += 3;
        } else {
            return ptr;
        }
    }
    return NULL;
}

static inline void put_sector(SectorCount *ptr, unsigned int sector)
{
    ptr->bytes[0] = sector & 0xff;
    sector >>= 8;
    ptr->bytes[1] = sector & 0xff;
    sector >>= 8;
    ptr->bytes[2] = sector & 0xff;
}

static inline unsigned int get_sector(SectorCount *ptr)
{
#if 1
    unsigned int sector;

    sector  = ptr->bytes[0];
    sector += ptr->bytes[1] <<  8;
    sector += ptr->bytes[2] << 16;

    return sector;
#else
    /*  GET4 gets the next four bytes in Intel little endian order
     *  and converts them to host byte order and handles unaligned
     *  access.
     */
    return (GET4(ptr, 0) & 0x00ffffff); /* back to host byte order */
#endif
}

static void bsm_debug_fake(void)
{
    /* for testing of bad sector handling at end of tape
     */
#if 0
    ftape_put_bad_sector_entry(segments_per_track * tracks_per_tape - 3,
                   0x000003e0;
    ftape_put_bad_sector_entry(segments_per_track * tracks_per_tape - 2,
                   0xff3fffff;
    ftape_put_bad_sector_entry(segments_per_track * tracks_per_tape - 1,
                   0xffffe000;
#endif
    /*  Enable to test bad sector handling
     */
#if 0
    ftape_put_bad_sector_entry(30, 0xfffffffe)
    ftape_put_bad_sector_entry(32, 0x7fffffff);
    ftape_put_bad_sector_entry(34, 0xfffeffff);
    ftape_put_bad_sector_entry(36, 0x55555555);
    ftape_put_bad_sector_entry(38, 0xffffffff);
    ftape_put_bad_sector_entry(50, 0xffff0000);
    ftape_put_bad_sector_entry(51, 0xffffffff);
    ftape_put_bad_sector_entry(52, 0xffffffff);
    ftape_put_bad_sector_entry(53, 0x0000ffff);
#endif
    /*  Enable when testing multiple volume tar dumps.
     */
#if 0
    {
        int i;

        for (i = ft_first_data_segment;
             i <= ft_last_data_segment - 7; ++i) {
            ftape_put_bad_sector_entry(i, EMPTY_SEGMENT);
        }
    }
#endif
    /*  Enable when testing bit positions in *_error_map
     */
#if 0
    {
        int i;
        
        for (i = first_data_segment; i <= last_data_segment; ++i) {
            ftape_put_bad_sector_entry(i,
                       ftape_get_bad_sector_entry(i) 
                       | 0x00ff00ff);
        }
    }
#endif
}

static void print_bad_sector_map(void)
{
    unsigned int good_sectors;
    unsigned int total_bad = 0;
    int i;
    TRACE_FUN(ft_t_flow);

    if (ft_format_code == fmt_big || 
        ft_format_code == fmt_var || 
        ft_format_code == fmt_1100ft) {
        SectorCount *ptr = (SectorCount *)bad_sector_map;
        unsigned int sector;

        while((sector = get_sector(ptr++)) != 0) {
            if ((ft_format_code == fmt_big || 
                 ft_format_code == fmt_var) &&
                sector & 0x800000) {
                total_bad += FT_SECTORS_PER_SEGMENT - 3;
                TRACE(ft_t_noise, "bad segment at sector: %6d",
                      sector & 0x7fffff);
            } else {
                ++total_bad;
                TRACE(ft_t_noise, "bad sector: %6d", sector);
            }
        }
        /*  Display old ftape's end-of-file marks
         */
        while ((sector = get_unaligned(((__u16*)ptr)++)) != 0) {
            TRACE(ft_t_noise, "Old ftape eof mark: %4d/%2d",
                  sector, get_unaligned(((__u16*)ptr)++));
        }
    } else { /* fixed size format */
        for (i = ft_first_data_segment;
             i < (int)(ft_segments_per_track * ft_tracks_per_tape); ++i) {
            SectorMap map = ((SectorMap *) bad_sector_map)[i];

            if (map) {
                TRACE(ft_t_noise,
                      "bsm for segment %4d: 0x%08x", i, (unsigned int)map);
                total_bad += ((map == EMPTY_SEGMENT)
                           ? FT_SECTORS_PER_SEGMENT - 3
                           : count_ones(map));
            }
        }
    }
    good_sectors =
        ((ft_segments_per_track * ft_tracks_per_tape - ft_first_data_segment)
         * (FT_SECTORS_PER_SEGMENT - 3)) - total_bad;
    TRACE(ft_t_info, "%d Kb usable on this tape", good_sectors);
    if (total_bad == 0) {
        TRACE(ft_t_info,
              "WARNING: this tape has no bad blocks registered !");
    } else {
        TRACE(ft_t_info, "%d bad sectors", total_bad);
    }
    TRACE_EXIT;
}


void ftape_extract_bad_sector_map(__u8 * buffer)
{
    TRACE_FUN(ft_t_any);

    /*  Fill the bad sector map with the contents of buffer.
     */
    if (ft_format_code == fmt_var || ft_format_code == fmt_big) {
        /* QIC-3010/3020 and wide QIC-80 tapes no longer have a failed
         * sector log but use this area to extend the bad sector map.
         */
        bad_sector_map = &buffer[FT_HEADER_END];
    } else {
        /* non-wide QIC-80 tapes have a failed sector log area that
         * mustn't be included in the bad sector map.
         */
        bad_sector_map = &buffer[FT_FSL + FT_FSL_SIZE];
    }
    if (ft_format_code == fmt_1100ft || 
        ft_format_code == fmt_var    ||
        ft_format_code == fmt_big) {
        bsm_hash_ptr = (SectorCount *)bad_sector_map;
    } else {
        bsm_hash_ptr = NULL;
    }
    bsm_debug_fake();
    if (TRACE_LEVEL >= ft_t_info) {
        print_bad_sector_map();
    }
    TRACE_EXIT;
}

static inline SectorMap cvt2map(unsigned int sector)
{
    return 1 << (((sector & 0x7fffff) - 1) % FT_SECTORS_PER_SEGMENT);
}

static inline int cvt2segment(unsigned int sector)
{
    return ((sector & 0x7fffff) - 1) / FT_SECTORS_PER_SEGMENT;
}

static int forward_seek_entry(int segment_id, 
                  SectorCount **ptr, 
                  SectorMap *map)
{
    unsigned int sector;
    int segment;

    do {
        sector = get_sector((*ptr)++);
        segment = cvt2segment(sector);
    } while (sector != 0 && segment < segment_id);
    (*ptr) --; /* point to first sector >= segment_id */
    /*  Get all sectors in segment_id
     */
    if (sector == 0 || segment != segment_id) {
        *map = 0;
        return 0;
    } else if ((sector & 0x800000) &&
           (ft_format_code == fmt_var || ft_format_code == fmt_big)) {
        *map = EMPTY_SEGMENT;
        return FT_SECTORS_PER_SEGMENT;
    } else {
        int count = 1;
        SectorCount *tmp_ptr = (*ptr) + 1;
        
        *map = cvt2map(sector);
        while ((sector = get_sector(tmp_ptr++)) != 0 &&
               (segment = cvt2segment(sector)) == segment_id) {
            *map |= cvt2map(sector);
            ++count;
        }
        return count;
    }
}

static int backwards_seek_entry(int segment_id,
                SectorCount **ptr,
                SectorMap *map)
{
    unsigned int sector;
    int segment; /* max unsigned int */

    if (*ptr <= (SectorCount *)bad_sector_map) {
        *map = 0;
        return 0;
    }
    do {
        sector  = get_sector(--(*ptr));
        segment = cvt2segment(sector);
    } while (*ptr > (SectorCount *)bad_sector_map && segment > segment_id);
    if (segment > segment_id) { /*  at start of list, no entry found */
        *map = 0;
        return 0;
    } else if (segment < segment_id) {
        /*  before smaller entry, adjust for overshoot */
        (*ptr) ++;
        *map = 0;
        return 0;
    } else if ((sector & 0x800000) &&
           (ft_format_code == fmt_big || ft_format_code == fmt_var)) {
        *map = EMPTY_SEGMENT;
        return FT_SECTORS_PER_SEGMENT;
    } else { /*  get all sectors in segment_id */
        int count = 1;

        *map = cvt2map(sector);
        while(*ptr > (SectorCount *)bad_sector_map) {
            sector = get_sector(--(*ptr));
            segment = cvt2segment(sector);
            if (segment != segment_id) {
                break;
            }
            *map |= cvt2map(sector);
            ++count;
        }
        if (segment < segment_id) {
            (*ptr) ++;
        }
        return count;
    }
}

void ftape_put_bad_sector_entry(int segment_id, SectorMap new_map)
{
    SectorCount *ptr = (SectorCount *)bad_sector_map;
    int count;
    int new_count;
    SectorMap map;
    TRACE_FUN(ft_t_any);

    if (ft_format_code == fmt_1100ft || 
        ft_format_code == fmt_var || 
        ft_format_code == fmt_big) {
        count = forward_seek_entry(segment_id, &ptr, &map);
        new_count = count_ones(new_map);
        /* If format code == 4 put empty segment instead of 32
         * bad sectors.
         */
        if (ft_format_code == fmt_var || ft_format_code == fmt_big) {
            if (new_count == FT_SECTORS_PER_SEGMENT) {
                new_count = 1;
            }
            if (count == FT_SECTORS_PER_SEGMENT) {
                count = 1;
            }
        }
        if (count != new_count) {
            /* insert (or delete if < 0) new_count - count
             * entries.  Move trailing part of list
             * including terminating 0.
             */
            SectorCount *hi_ptr = ptr;

            do {
            } while (get_sector(hi_ptr++) != 0);
            /*  Note: ptr is of type byte *, and each bad sector
             *  consumes 3 bytes.
             */
            memmove(ptr + new_count, ptr + count,
                (size_t)(hi_ptr - (ptr + count))*sizeof(SectorCount));
        }
        TRACE(ft_t_noise, "putting map 0x%08x at %p, segment %d",
              (unsigned int)new_map, ptr, segment_id);
        if (new_count == 1 && new_map == EMPTY_SEGMENT) {
            put_sector(ptr++, (0x800001 + 
                      segment_id * 
                      FT_SECTORS_PER_SEGMENT));
        } else {
            int i = 0;

            while (new_map) {
                if (new_map & 1) {
                    put_sector(ptr++, 
                           1 + segment_id * 
                           FT_SECTORS_PER_SEGMENT + i);
                }
                ++i;
                new_map >>= 1;
            }
        }
    } else {
        ((SectorMap *) bad_sector_map)[segment_id] = new_map;
    }
    TRACE_EXIT;
}

SectorMap ftape_get_bad_sector_entry(int segment_id)
{
    if (ft_used_header_segment == -1) {
        /*  When reading header segment we'll need a blank map.
         */
        return 0;
    } else if (bsm_hash_ptr != NULL) {
        /*  Invariants:
         *    map - mask value returned on last call.
         *    bsm_hash_ptr - points to first sector greater or equal to
         *          first sector in last_referenced segment.
         *    last_referenced - segment id used in the last call,
         *                      sector and map belong to this id.
         *  This code is designed for sequential access and retries.
         *  For true random access it may have to be redesigned.
         */
        static int last_reference = -1;
        static SectorMap map;

        if (segment_id > last_reference) {
            /*  Skip all sectors before segment_id
             */
            forward_seek_entry(segment_id, &bsm_hash_ptr, &map);
        } else if (segment_id < last_reference) {
            /* Skip backwards until begin of buffer or
             * first sector in segment_id 
             */
            backwards_seek_entry(segment_id, &bsm_hash_ptr, &map);
        }        /* segment_id == last_reference : keep map */
        last_reference = segment_id;
        return map;
    } else {
        return ((SectorMap *) bad_sector_map)[segment_id];
    }
}

/*  This is simply here to prevent us from overwriting other kernel
 *  data. Writes will result in NULL Pointer dereference.
 */
void ftape_init_bsm(void)
{
    bad_sector_map = NULL;
    bsm_hash_ptr   = NULL;
}

:: Command execute ::

Enter:
 
Select:
 

:: Search ::
  - regexp 

:: Upload ::
 
[ Read-Only ]

:: Make Dir ::
 
[ Read-Only ]
:: Make File ::
 
[ Read-Only ]

:: Go Dir ::
 
:: Go File ::
 

--[ c99shell v. 1.0 pre-release build #13 powered by Captain Crunch Security Team | http://ccteam.ru | Generation time: 0.027 ]--