This file is indexed.

/usr/bin/atari-hd-image is in hatari 1.8.0+dfsg-1.

This file is owned by root:root, with mode 0o755.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
#!/bin/sh
# script for creating a compatible DOS HD image for Hatari with
# a single FAT16 partition of given size, with given contents

# defaults for disk attributes
diskfile=hd.img   # HD image filename
partname=DOS      # partition name

# no args or first arg has non-digit characters?
if [ $# -lt 1 ] || [ \! -z "$(echo $1|tr -d 0-9)" ]; then
	name=${0##*/}
	echo
	echo "usage: $name <size> [filename] [partition name] [directory]"
	echo
	echo "Create an ACSI/IDE harddisk image for Hatari with a single Atari"
	echo "compatible DOS partition.  Arguments are (defaults in parenthesis):"
	echo "- size: harddisk image size in megabytes, 8-512"
	echo "- filename: name for the harddisk image ($diskfile)"
	echo "- partition name: name for that single partition ($partname)"
	echo "- directory: directory for initial content copied to the image"
	echo
	echo "For example:"
	echo "- 16MB '$diskfile' HD image:"
	echo "  $name 16"
	echo "-  8MB image with 'TEST' partition having files from content/:"
	echo "  $name 8 8mb-disk.img TEST content/"
	echo
	exit 1
fi

# sfdisk/mkdosfs reside in /sbin
PATH=/sbin:$PATH
export PATH

# check tools
if [ -z $(which mkdosfs) ] || [ -z $(which python) ]; then
	echo "ERROR: either mkdosfs or python tool missing!"
	exit 1
fi

# check disk size
if [ $1 -lt 5 ]; then
	echo "ERROR: disk size needs to be at least 5 (MB) to work properly."
	exit 1
fi
if [ $1 -gt 512 ]; then
	echo "ERROR: mkdosfs supports Atari compatible partitions only up to 512 MB."
	exit 1
fi

# disk geometry
skip=0            # alignment / "padding" sectors between MBR before partition
diskheads=16
tracksectors=32	  # same as used by mkdosfs
sectorsize=512

# partition size in sectors:
# 16*32*512 is 1/4MB -> multiply by 4 to get number of required sectors
partsectors=$((4*$1*$diskheads*$tracksectors))

# check optional arguments
if [ \! -z $2 ]; then
	diskfile=$2
fi
if [ \! -z $3 ]; then
	partname=$3
fi
if [ \! -z $4 ]; then
	if [ -z $(which mcopy) ]; then
		echo "ERROR: mcopy (from Mtools) missing!"
		exit 1
	fi
	contentdir=$4
fi

# don't overwrite files by accident
if [ -f $diskfile ]; then
	echo "ERROR: given harddisk image already exits. Give another name or remove it:"
	echo "  rm $diskfile"
	exit 1
fi

# temporary files
tmppart=$diskfile.part

error="premature script exit"
# script exit/error handling
exit_cleanup ()
{
	echo
	if [ -z "$error" ]; then
		echo "$step) Cleaning up..."
	else
		echo "ERROR: $error"
		echo
		echo "cleaning up..."
		echo "rm -f $diskfile"
		rm -f $diskfile
	fi
	echo "rm -f $tmppart"
	rm -f $tmppart
	echo "Done."
}
trap exit_cleanup EXIT

echo
step=1
echo "$step) Creating DOS Master Boot Record / partition table..."
# See:
# - http://en.wikipedia.org/wiki/Master_boot_record
# - http://en.wikipedia.org/wiki/Cylinder-head-sector
# - http://en.wikipedia.org/wiki/File_Allocation_Table#Boot_Sector
# For DOS MBR, the values are little endian.
# -----------
python << EOF
#!/usr/bin/env python
mbr = bytearray(512)

def set_long(idx, value):
    mbr[idx+0] = value & 0xff
    mbr[idx+1] = value >> 8 & 0xff
    mbr[idx+2] = value >> 16 & 0xff
    mbr[idx+3] = value >> 24

def set_word(idx, value):
    mbr[idx] = value & 0xff
    mbr[idx+1] = value >> 8 & 0xff

def set_CHS(idx, values):
    c, h, s = values
    print "CHS: %3d,%3d,%3d @ $%x" % (c,h,s,idx)
    mbr[idx] = h
    mbr[idx+1] = (s & 0x3F) | ((c >> 2) & 0xC0)
    mbr[idx+2] = c & 0xFF

def LBA2CHS(lba):
    c = lba / ($tracksectors * $diskheads)
    h = (lba / $tracksectors) % $diskheads
    s = (lba % $tracksectors) + 1
    return (c,h,s)

# disk size
sectors = 1 + $skip + $partsectors
if sectors < 65536:
    set_word(0x13, sectors)
    set_long(0x20, sectors)
    parttype=0x4
else:
    set_long(0x20, sectors)
    parttype=0x6

# reserved sectors = MBR
mbr[0x0E] = 1

# CHS information
set_word(0x0B, $sectorsize)
mbr[0x0D] = 2 # sectors / cluster
set_word(0x18, $tracksectors)
set_word(0x1A, $diskheads)
  
# non-removable disk
mbr[0x15] = 0xF8
mbr[0x24] = 0x80

# partition size in sectors
partsectors = $partsectors - 1
# first partition takes all
offset = 0x1BE
mbr[offset] = 0x80 # bootable
mbr[offset+4] = parttype
# partition start & sector count in LBA
set_long(offset + 0x08, 1)
set_long(offset + 0x0C, partsectors)
# partition start & end in CHS
set_CHS(offset + 1, LBA2CHS(1))
set_CHS(offset + 5, LBA2CHS(partsectors))
# 3 last partitions are empty
for i in (1,2,3):
    offset += 0x10
    set_long(offset + 0x08, partsectors+1)
    set_long(offset + 0x0C, 0)
    set_CHS(offset + 1, LBA2CHS(partsectors+1))
    set_CHS(offset + 5, LBA2CHS(partsectors))

# MBR signature
mbr[0x1FE] = 0x55
mbr[0x1FF] = 0xAA

open("$diskfile", "wb").write(bytes(mbr))
EOF
# -----------
od -t x1 $diskfile

echo
step=$(($step+1))
echo "$step) Creating an Atari TOS compatible DOS partition..."
# mkdosfs keeps the sector count below 32765 when -A is used by increasing
# the logical sector size (this is for TOS compatibility, -A guarantees
# also 2 sectors / cluster and Atari serial number etc).  Mtools barfs
# if partition size doesn't divide evenly with its track size.  Determine
# suitable cluster count & corresponding track size and align (decrease)
# the file system sector count accordingly.
tracksize=32
clustertmp=$((partsectors/2))
echo "Sectors: $partsectors, sectors/track: $tracksize, clusters: $clustertmp"
while [ $clustertmp -gt 32765 ]; do
	clustertmp=$((clustertmp/2))
	tracksize=$(($tracksize*2))
	echo "Doubling sector size as >32765 clusters -> $clustertmp clusters"
done
sectors=$(($partsectors/$tracksize))
sectors=$(($sectors*$tracksize))
kilobytes=$(($sectors/2))
if [ $sectors -ne $partsectors ]; then
	echo "Align sector count with clusters/sectors/track: $partsectors -> $sectors ($kilobytes kB)"
fi
echo "mkdosfs -A -F 16 -n $partname -C $tmppart $kilobytes"
mkdosfs -A -F 16 -n $partname -C $tmppart $kilobytes

if [ \! -z $contentdir ]; then
	echo
	step=$(($step+1))
	# copy contents of given directory to the new partition
	echo "$step) Copying the initial content to the partition..."
	echo "MTOOLS_NO_VFAT=1 mcopy -i $tmppart -spmv $contentdir/* ::"
	MTOOLS_NO_VFAT=1 mcopy -i $tmppart -spmv $contentdir/* ::
	if [ $? -ne 0 ]; then
		error="mcopy failed."
		exit 2
	fi
fi

echo
step=$(($step+1))
# copy the partition into disk
echo "$step) Copying the partition to disk image..."
echo "dd if=$tmppart of=$diskfile bs=512 seek=$((1+$skip)) count=$sectors"
dd if=$tmppart of=$diskfile bs=512 seek=$((1+$skip)) count=$sectors

step=$(($step+1))
# cleanup is done by exit_cleanup() trap
error=""