Package: mtools
Version: 3.9.10.ds1-3
Severity: wishlist

        Please consider the script (attached) for inclusion into Mtools.

        The script runs `dd', `mpartition' and `mformat' in sequence to
        construct a DOS hard disk image (i. e., with MBR) consisting of
        the specified number of DOS partitions of a given size.  E. g.:

$ grep -F x: -- ~/.mtoolsrc 
drive x: file="/.../dos-exchange.image" partition=1
$ mkdosdisk /.../dos-exchange.image 640M 
0+0 records in
0+0 records out
0 bytes (0 B) copied, 1.9639e-05 seconds, 0.0 kB/s
Warning: no active (bootable) partition present
$ 

        The above creates a DOS hard disk image consisting of a single
        640 MiB-long DOS partition with a filesystem, which is already
        configured as drive X: for Mtools.  Now, test it:

$ mcopy -s \
      
ftp.glcf.umiacs.umd.edu/glcf/Landsat/WRS2/p148/r023/L71148023_02319990801.ETM-USGS
 \
      x: 
$ mdir x:
 Volume in drive X has no label
 Volume Serial Number is 1959-D83D
Directory for X:/

L71148~1 ETM <DIR>     2009-06-20   0:46  L71148023_02319990801.ETM-USGS
        1 file                    0 bytes
                         87 932 928 bytes free

$ mdir x:/L71148~1.ETM/ 
 Volume in drive X has no label
 Volume Serial Number is 1959-D83D
Directory for X:/L71148~1.ETM

.            <DIR>     2009-06-20   0:46 
..           <DIR>     2009-06-20   0:46 
L71148~1 JPG     13523 2009-06-20   0:46  L71148023_02319990801.preview.jpg
L71148~2 JPG    431712 2009-06-20   0:46  L71148023_02319990801.browse.jpg
L71148~3 JPG     15857 2009-06-20   0:46  L71148023_02319990801.742.preview.jpg
L71148~1 TIF  59389708 2009-06-20   0:46  l71148023_02319990801_b50.tif
L71148~2 TIF  59389708 2009-06-20   0:46  l71148023_02319990801_b40.tif
L71148~3 TIF  59389708 2009-06-20   0:46  l71148023_02319990801_b30.tif
L71148~4 TIF  14852018 2009-06-20   0:46  l71148023_02319990801_b61.tif
L72148~1 TIF  14852018 2009-06-20   0:46  l72148023_02319990801_b62.tif
L72148~2 TIF  59389708 2009-06-20   0:46  l72148023_02319990801_b70.tif
L72148~3 TIF  237407428 2009-06-20   0:46  l72148023_02319990801_b80.tif
L71148~5 TIF  59389708 2009-06-20   0:46  l71148023_02319990801_b20.tif
L71148~1 GZ   21186574 2009-06-20   0:46  l71148023_02319990801_b10.tif.gz
L71148~4 JPG    512946 2009-06-20   0:46  L71148023_02319990801.742.browse.jpg
       15 files         586 220 616 bytes
                         87 932 928 bytes free

$ 

        And, once the image is no longer needed:

$ rm /.../dos-exchange.image 
$ 

        I'm currently trying to use such a temporary partition to allow
        for large file sets to be transferred between a host GNU/Linux
        system and FreeDOS guests (running under, e. g., Qemu or KVM.)

-- 
FSF associate member #7257
#!/bin/bash
### mkdosdisk.sh --- Make a DOS hard disk image (MBR + FAT FS)  -*- Sh -*-

progname="$(basename "$0")"

## FIXME: hardcoded values
sectors=63
heads=255
first_drive_letter=C

MTOOLSRC=
export MTOOLSRC

err () {
    local x="$1" f="$2" r
    shift 2
    printf "%s: ${f}\n" "${progname}" "$@" >&2
    r="$?"
    if [ "$x" != 0 ]; then
        ## .
        exit "$x"
    fi
    ## .
    return "$r"
}

clean_up () {
    ## be cautious here
    case "$MTOOLSRC" in
        (*/mkdosdisk.??????) rm -- "$MTOOLSRC" ;;
    esac
    trap '' EXIT
}

trap clean_up EXIT

drive_letter_next () {
    ## .
    printf %c\\n "$1" | tr a-z A-Z | tr A-Z B-Z\!
}

size_to_sectors () {
    local s u m
    echo "$1" \
        | sed -e 's/^[[:blank:]]*\([[:digit:]]\+\)[[:blank:]]*\(.*\)$/\1 \2/' \
        | {
        read s u
        case "$u" in
            ([Ss]) m=1 ;;
            ([kK]) m=2 ;;
            ([mM]) m=$[2 * 1024] ;;
            ([gG]) m=$[2 * 1024 * 1024] ;;
            ([tT]) m=$[2 * 1024 * 1024 * 1024] ;;
            (*)
                ## .
                err 1 "%s: Unknown unit, use one of s, k, M, G or T" \
                    "$1"
                ;;
        esac
        ## .
        echo $[$m * $s]
    }
}

process_sizes () {
    local s1 s cyl
    local d i
    local spc=$[$sectors * $heads]
    ## NB: alters estimated_image_size and partition_sizes
    ## NB: uses image_file
    i=1
    d="$first_drive_letter"
    for s1; do
        s="$(size_to_sectors "$s1")"
        cyl=$[($s + $spc - 1) / $spc]
        estimated_image_size=$[$estimated_image_size + $cyl]
        partition_sizes="${partition_sizes} ${cyl}"
        printf "drive %c: file=\"%s\" partition=%d\\n" \
            "$d" "$image_file" "$i"
        i=$[1 + $i]
        d="$(drive_letter_next "$d")"
    done
}

initialize_image () {
    local file="$1" cyl="$2"
    local spc=$[$sectors * $heads]

    ## .
    dd if=/dev/null bs="${spc}b" seek="$cyl" count=0 \
        of="$file" \
        && mpartition -I -s "$sectors" -h "$heads" -t "$cyl" \
               "$first_drive_letter":
}

create_partitions () {
    local cyl d
    d="$first_drive_letter"
    for cyl; do
        if ! mpartition -c -s "$sectors" -h "$heads" -t "$cyl" \
            "$d":; then
            err 1 "%c: Failed to create partition (%d cylinders)" \
                "$d" "$cyl"
        fi
        d="$(drive_letter_next "$d")"
    done
}

mkfs_partitions () {
    local cyl d
    d="$first_drive_letter"
    for cyl; do
        if ! mformat "$d":; then
            err 1 "%c: Failed to create filesystem (%d cylinders)" \
                "$d" "$cyl"
        fi
        d="$(drive_letter_next "$d")"
    done
}

if [ "$#" -le 1 ]; then
    ## .
    err 1 "Both image file and partition size has to be specified"
fi

image_file="$1"
initialized_p=
shift

if [ -e "$image_file" ]; then
    err 0 "%s: Warning: file exists, not initializing" \
        "$image_file"
    initialized_p=yes
fi

MTOOLSRC="$(mktemp -t mkdosdisk.XXXXXX)"

estimated_image_size=1
partition_sizes=''
process_sizes "$@" > "$MTOOLSRC"

if [ -z "$initialized_p" ]; then
    if ! initialize_image "$image_file" "$estimated_image_size"; then
        err 1 "%s: Cannot initialize image" \
            "$image_file"
    fi
fi

create_partitions $partition_sizes
mkfs_partitions   $partition_sizes

### mkdosdisk.sh ends here

Reply via email to