1
/* silocheck - checks whether a file is located below 1GB, so that
4
Copyright (C) 1996 Jakub Jelinek
6
This program is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2 of the License, or
9
(at your option) any later version.
11
This program is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
GNU General Public License for more details.
16
You should have received a copy of the GNU General Public License
17
along with this program; if not, write to the Free Software
18
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
22
#include "../second/fs/ufs.c"
30
#include <sys/ioctl.h>
32
# include <sys/stat.h>
33
# define _LINUX_STAT_H
34
# define _LINUX_TIME_H
35
# define _LINUX_STRING_H_
38
# include <linux/fs.h>
39
# include <ext2fs/ext2_fs.h>
40
# include <ext2fs/ext2fs.h>
41
# include <scsi/scsi.h>
44
# include <sys/sysmacros.h>
45
# define mmajor(x) major(x)
46
# define mminor(x) minor(x)
47
# define mmakedev(x,y) makedev(x,y)
49
# define mmajor(x) (int)((x) >> 8)
50
# define mminor(x) (int)((x) & 0xff)
51
# define mmakedev(major, minor) (((major) << 8) | (minor))
53
#elif defined (__sun__)
54
# include <sys/types.h>
55
# include <sys/stat.h>
56
# include <non-linux/ext2_fs.h>
57
# include <ext2fs/ext2fs.h>
60
# include <sys/byteorder.h>
62
# define BYTE_ORDER 4321
63
# elif defined (_LITTLE_ENDIAN)
64
# define BYTE_ORDER 1234
66
# error "Unknown byteorder"
68
static int ufs_blocks (char *, ino_t);
70
# error "Unknown system"
80
/* This is just so that we don't have to fight with incompatible ufs_fs.h headers */
81
#define SILO_UFS_MAGIC 0x00011954
82
struct silo_ufs_super_block {
83
unsigned char xxx1[36];
84
unsigned int fs_fsize;
85
unsigned char xxx2[1332];
86
unsigned int fs_magic;
89
struct sun_disklabel {
90
unsigned char info[128]; /* Informative text string */
91
unsigned char spare[292]; /* Boot information etc. */
92
unsigned short rspeed; /* Disk rotational speed */
93
unsigned short pcylcount; /* Physical cylinder count */
94
unsigned short sparecyl; /* extra sects per cylinder */
95
unsigned char spare2[4]; /* More magic... */
96
unsigned short ilfact; /* Interleave factor */
97
unsigned short ncyl; /* Data cylinder count */
98
unsigned short nacyl; /* Alt. cylinder count */
99
unsigned short ntrks; /* Tracks per cylinder */
100
unsigned short nsect; /* Sectors per track */
101
unsigned char spare3[4]; /* Even more magic... */
102
struct sun_partition {
103
unsigned long start_cylinder;
104
unsigned long num_sectors;
106
unsigned short magic; /* Magic number */
107
unsigned short csum; /* Label xor'd checksum */
110
#if BYTE_ORDER == 4321
111
__u32 swab32 (__u32 value)
113
return ((value >> 24) | ((value >> 8) & 0xff00) |
114
((value << 8) & 0xff0000) | (value << 24));
117
__u16 swab16 (__u16 value)
119
return (value >> 8) | (value << 8);
121
#define bswab32(x) (x)
122
#define bswab16(x) (x)
124
#define swab32(x) (x)
125
#define swab16(x) (x)
126
__u32 bswab32 (__u32 value)
128
return ((value >> 24) | ((value >> 8) & 0xff00) |
129
((value << 8) & 0xff0000) | (value << 24));
132
__u16 bswab16 (__u16 value)
134
return (value >> 8) | (value << 8);
144
static void silo_fatal(char *fmt,...)
148
fprintf (stderr, "Fatal error: ");
149
vfprintf (stderr, fmt, ap);
155
int check_fs (int fd)
157
struct silo_ufs_super_block ufs;
158
struct ext2_super_block sb; /* Super Block Info */
160
if (lseek (fd, 1024, 0) != 1024 || read (fd, &sb, sizeof (sb)) != sizeof (sb))
161
silo_fatal("Cannot read Super Block!");
162
if (swab16 (sb.s_magic) == EXT2_SUPER_MAGIC)
163
return 1024 << swab32 (sb.s_log_block_size);
164
if (lseek (fd, 8192, 0) != 8192 || read (fd, &ufs, sizeof (ufs)) != sizeof (ufs))
166
if (bswab32 (ufs.fs_magic) == SILO_UFS_MAGIC)
171
void read_sb (char *device, char *bootdev)
175
struct sun_disklabel *sdl;
178
if ((fd = open (device, O_RDONLY)) == -1)
179
silo_fatal("Cannot open superblock on %s", device);
181
if (bs == (unsigned short)-1)
182
silo_fatal("File systems other than ext2, ext3, ufs and romfs "
183
"not yet supported", device);
188
partno = (int) (*(device + strlen (device) - 1) - '0') - 1;
189
#elif defined(__sun__)
190
partno = (int) (*(device + strlen (device) - 1) - '0');
192
sdl = (struct sun_disklabel *) &buff;
193
if ((fd = open (bootdev, O_RDONLY)) == -1)
194
silo_fatal("Error opening %s", bootdev);
195
if (read (fd, buff, sizeof (buff)) != sizeof (buff))
196
silo_fatal("Error reading %s's label", bootdev);
197
doff = bswab16(sdl->ntrks) * bswab16(sdl->nsect) * bswab32(sdl->partitions[partno].start_cylinder);
198
offset = bswab16(sdl->ntrks) * bswab16(sdl->nsect) * bswab32(sdl->partitions[0].start_cylinder);
202
int get_partition_blocks (char *device, char *filename)
209
if ((fd = open (filename, O_RDONLY)) == -1) {
210
silo_fatal("Cannot find %s", filename);
212
if (fstat (fd, &st) < 0) {
213
silo_fatal("Couldn't stat %s", filename);
217
for (i = 0, j = 0;; i++) {
219
if ((j << 9) >= size || ioctl (fd, FIBMAP, &block) < 0)
222
for (k = 0; k < nsect; k++)
225
for (k = 0; k < nsect; k++)
226
blocks[j++] = block * nsect + doff + k;
231
#elif defined(__sun__)
232
ufs_blocks (device, st.st_ino);
238
char *find_dev(int number)
241
# define DEVNAME "/dev"
243
# define DEVNAME "/dev/dsk"
248
static char name[PATH_MAX+1];
251
if (!number) return NULL;
252
if ((dp = opendir(DEVNAME)) == NULL) return NULL;
253
strcpy(name,DEVNAME "/");
254
p = strchr (name, 0);
255
while ((dir = readdir(dp)) != NULL) {
256
strcpy(p,dir->d_name);
257
if (stat(name,&s) < 0) return NULL;
258
if (S_ISBLK(s.st_mode) && s.st_rdev == number) return name;
267
"Usage: %s [options] filename\n"
269
" -v print disk blocks\n"
270
" -c print disk blocks in a start-len format\n"
275
int main(int argc,char **argv)
278
int i, j, printblocks = 0;
280
char bootdev[1024], bootdev2[1024];
285
while (argc && **argv == '-') {
287
if (argv[0][2]) usage(name);
288
switch ((*argv++)[1]) {
299
if (argc != 1) usage(name);
301
if (stat (filename, &st1) < 0)
302
silo_fatal("Cannot open %s", filename);
304
if (mmajor(st1.st_dev) == 8) {
305
sprintf (bootdev2, "/dev/sd%c%c", (mminor(st1.st_dev) >> 4) + 'a', (mminor(st1.st_dev) & 0xf) + '0');
306
sprintf (bootdev, "/dev/sd%c", (mminor(st1.st_dev) >> 4) + 'a');
310
char *p = find_dev (st1.st_dev);
313
silo_fatal("Couldn't find out what device is %s on", filename);
315
strcpy (bootdev2, p);
317
if (strlen (p) == strlen ("/dev/dsk/c0t0d0s0")) {
318
p = strchr (p, 0) - 2;
319
if (*p == 's' && p[1] >= '0' && p[1] <= '7') {
320
p = strchr (bootdev, 0) - 1;
326
read_sb (bootdev2, bootdev);
327
get_partition_blocks (bootdev2, filename);
329
printf ("%s: ", filename);
330
for (i = 0; i < nblocks; i++) {
331
for (j = 0; !blocks[i] && i < nblocks; i++, j++);
333
if (i) printf (", ");
334
printf ("%dxHOLE", j);
335
if (i >= nblocks) break;
337
if (i) printf (", ");
338
if (printblocks == 2) {
339
for (j = 0; blocks[i + j] && blocks[i + j] == blocks[i] + j && j < nblocks; j++);
341
printf ("%08X(%d)", blocks[i], j);
346
printf ("%08X", blocks[i]);
350
for (i = 0; i < nblocks; i++) {
351
if (blocks[i] >= 0x200000) {
352
fprintf (stderr, "%s extends past the 1GB boundary and thus SILO might not load it correctly\n", filename);
361
static errcode_t std_open (const char *name, int flags, io_channel * channel);
362
static errcode_t std_close (io_channel channel);
363
static errcode_t std_set_blksize (io_channel channel, int blksize);
364
static errcode_t std_read_blk (io_channel channel, unsigned long block, int count, void *data);
365
static errcode_t std_write_blk (io_channel channel, unsigned long block, int count, const void *data);
366
static errcode_t std_flush (io_channel channel);
368
static struct struct_io_manager struct_std_manager =
370
EXT2_ET_MAGIC_IO_MANAGER,
380
static ufs_filsys fs = NULL;
381
static io_manager std_io_manager = &struct_std_manager;
382
static int std_fd = 0;
384
static unsigned int cbs = 1024; /* Block Size */
386
static errcode_t std_open (const char *name, int flags, io_channel * channel)
392
return EXT2_ET_BAD_DEVICE_NAME;
393
io = (io_channel) malloc (sizeof (struct struct_io_channel));
395
return EXT2_ET_BAD_DEVICE_NAME;
396
std_fd = open (name, O_RDONLY);
398
silo_fatal("Cannot open %s", name);
399
memset (io, 0, sizeof (struct struct_io_channel));
400
io->magic = EXT2_ET_MAGIC_IO_CHANNEL;
401
io->manager = std_io_manager;
402
io->name = (char *) malloc (strlen (name) + 1);
403
strcpy (io->name, name);
404
io->block_size = cbs;
412
static errcode_t std_close (io_channel channel)
417
static errcode_t std_set_blksize (io_channel channel, int blksize)
419
channel->block_size = cbs = blksize;
422
static errcode_t std_read_blk (io_channel channel, unsigned long block, int count, void *data)
426
size = (count < 0) ? -count : count * cbs;
427
if (lseek (std_fd, block * cbs, SEEK_SET) != block * cbs)
428
silo_fatal("Cannot seek");
429
if (read (std_fd, data, size) != size)
430
silo_fatal("Read error on block %d", block);
434
static errcode_t std_write_blk (io_channel channel, unsigned long block, int count, const void *data)
438
static errcode_t std_flush (io_channel channel)
442
static int ufs_block_idx = 0;
443
static int ufs_blocks_dump (ufs_filsys fs, blk_t *block, int i, void *private)
446
for (j = 0; j < nsect; j++)
447
blocks [ufs_block_idx++] = *block * nsect + doff + j;
451
static int ufs_blocks (char *device, ino_t inode)
453
if (ufs_open (device, std_io_manager, &fs))
454
silo_fatal("Cannot open ufs filesystem containing second stage");
456
if (ufs_block_iterate (fs, inode, ufs_blocks_dump, 0))
457
silo_fatal("Block iterating error on second stage");
458
blocks [ufs_block_idx] = 0;
459
nblocks = ufs_block_idx;