Codebase list gpart / fe36723
New upstream release. Joao Eriberto Mota Filho 9 years ago
30 changed file(s) with 1059 addition(s) and 961 deletion(s). Raw diff Collapse all Expand all
+0
-18
.gitignore less more
0 *.o
1 src/gpart
2 Makefile
3 Makefile.in
4 aclocal.m4
5 autom4te.cache/
6 compile
7 config.h
8 config.h.in
9 config.log
10 config.status
11 configure
12 depcomp
13 install-sh
14 man/gpart.8
15 missing
16 .deps/
17 stamp-h1
0 v0.2.1
1 - Fix distribution issues that prevented builds of dist tarball
2
3 v0.2
4 - Import some FreeBSD patches
5 - Default scan by sector size to handle new 4k alignment method
6 - Properly consider the real size of the disk to not invalidate partitions
7
8 v0.1i
9 - Switch to autoconf/automake for cross-platform support
10 - Integrate patches from distributions to fix build and overflow issues
11
120 v0.1h
131 - New support for the following filesystems: BeOS, QNX 4.x & SGI XFS.
142 - Updated Reiser filesystem support (Francis Devereux <francis@devereux.tc>).
0 #
1 # gpart Makefile
2 #
3 include inst.defs
4 include make.defs
5
6 all: gpart
7
8 gpart:
9 $(MAKE) -C src
10 $(MAKE) -C man
11
12 install:
13 $(MAKE) -C src install
14 $(MAKE) -C man install
15
16 uninstall:
17 $(MAKE) -C src uninstall
18 $(MAKE) -C man uninstall
19
20 clean:
21 $(MAKE) -C src clean
22 $(MAKE) -C man clean
+0
-6
Makefile.am less more
0 AUTOMAKE_OPTIONS = foreign
1 SUBDIRS = src man
2
3 docdir = $(datadir)/doc/@PACKAGE@
4 doc_DATA = Changes README
5 EXTRA_DIST = Changes README
2323
2424 - Currently recognized partitions/filesystems types ---------------------
2525
26 Modname Typ Description
27 fat 0x01 "Primary DOS with 12 bit FAT"
28 0x04 "Primary DOS with 16 bit FAT (<= 32MB)"
29 0x06 "Primary 'big' DOS (> 32MB)"
30 0x0B "DOS or Windows 95 with 32 bit FAT"
31 0x0C "DOS or Windows 95 with 32 bit FAT, LBA"
32 ntfs 0x07 "OS/2 HPFS, NTFS, QNX or Advanced UNIX"
33 hpfs 0x07 "OS/2 HPFS, NTFS, QNX or Advanced UNIX"
34 ext2 0x83 "Linux ext2 filesystem"
35 lswap 0x82 "Linux swap"
36 bsddl 0xA5 "FreeBSD/NetBSD/386BSD"
37 s86dl 0x82 "Solaris/x86 disklabel"
38 minix 0x80 "Minix V1"
39 0x81 "Minix V2"
40 reiserfs 0x83 "ReiserFS filesystem"
41 hmlvm 0xFE "Linux LVM physical volumes"
42 qnx4 0x4F "QNX 4.x"
43 beos 0xEB "BeOS fs"
44 xfs 0x83 "SGI XFS filesystem"
45
46
47
48 - Guessing modules ------------------------------------------------------
49
50 Each guessing module must provide three functions callabble from
26 Modname Typ Description
27 fat 0x01 "Primary DOS with 12 bit FAT"
28 0x04 "Primary DOS with 16 bit FAT (<= 32MB)"
29 0x06 "Primary 'big' DOS (> 32MB)"
30 0x0B "DOS or Windows 95 with 32 bit FAT"
31 0x0C "DOS or Windows 95 with 32 bit FAT, LBA"
32 ntfs 0x07 "OS/2 HPFS, NTFS, QNX or Advanced UNIX"
33 hpfs 0x07 "OS/2 HPFS, NTFS, QNX or Advanced UNIX"
34 ext2 0x83 "Linux ext2 filesystem"
35 lswap 0x82 "Linux swap"
36 bsddl 0xA5 "FreeBSD/NetBSD/386BSD"
37 s86dl 0x82 "Solaris/x86 disklabel"
38 minix 0x80 "Minix V1"
39 0x81 "Minix V2"
40 rfs 0x83 "Reiser filesystem"
41 hmlvm 0xFE "Linux LVM physical volumes"
42 qnx4 0x4F "QNX 4.x"
43 beos 0xEB "BeOS fs"
44 xfs 0x83 "SGI XFS filesystem"
45
46
47
48 - External guessing modules ---------------------------------------------
49
50 gpart allows external partition type guessing modules to be
51 added dynamically. An external module of type "xxx" must be
52 compiled into a shared object file called "gm_xxx.so".
53
54 External modules must provide three functions callable from
5155 gpart:
5256
5357 int xxx_init(disk_desc *d,g_module *m)
8488 hand too much tolerance leads to misguided guesses,
8589 so a golden middle way must be found.
8690
91 To create a shared object file from C source, compile the
92 module via
93
94 gcc -Wall -fPIC -shared gm_xxx.c -o gm_xxx.so
95
96 Then install the shared object in a directory searched by
97 the dynamic linker, or set LD_LIBRARY_PATH accordingly.
98 The new external module can then be included by calling
99 gpart like
100
101 gpart -t xxx <other options>
102
103
87104
88105 - Output explanation ----------------------------------------------------
89106
+0
-7
autogen.sh less more
0 #!/bin/sh
1 set -e
2 aclocal
3 autoconf
4 autoheader
5 automake --add-missing
6 ./configure
+0
-39
configure.ac less more
0 # -*- Autoconf -*-
1 # Process this file with autoconf to produce a configure script.
2
3 AC_PREREQ([2.69])
4 AC_INIT(gpart, 0.2.1, https://github.com/baruch/gpart/issues)
5 AM_INIT_AUTOMAKE([1.14])
6 AC_CONFIG_SRCDIR([src/gpart.c])
7 AC_CONFIG_HEADERS([config.h])
8
9 # Checks for programs.
10 AC_PROG_CC
11 AC_PROG_INSTALL
12
13 # Checks for libraries.
14 # FIXME: Replace `main' with a function in `-ldl':
15 AC_CHECK_LIB([dl], [main])
16
17 # Checks for header files.
18 AC_CHECK_HEADERS([fcntl.h stdint.h stdlib.h string.h sys/ioctl.h sys/mount.h unistd.h])
19
20 # Checks for typedefs, structures, and compiler characteristics.
21 AC_TYPE_INT16_T
22 AC_TYPE_INT8_T
23 AC_TYPE_SIZE_T
24 AC_TYPE_SSIZE_T
25 AC_TYPE_UINT16_T
26 AC_TYPE_UINT32_T
27 AC_TYPE_UINT64_T
28 AC_TYPE_UINT8_T
29
30 # Checks for library functions.
31 AC_FUNC_MALLOC
32 AC_CHECK_FUNCS([getpagesize memset strchr strdup strerror strtoul])
33
34 AC_CONFIG_FILES([Makefile
35 man/Makefile
36 src/Makefile
37 man/gpart.8])
38 AC_OUTPUT
0 #
1 # installation directories for gpart
2 #
3 prefix=/usr/local
4 bindir=$(prefix)/bin
5 libdir=$(prefix)/lib
6 mandir=$(prefix)/man
7 manext=8
8 sharedir=$(prefix)/share
0 #
1 #
2 #
3 CC = gcc
4 CFLAGS = -Wall -O2 -pedantic
5 LDFLAGS =
6 MAKEDEP = gcc -M
7 INSTALL = install
8 RM = rm -f
9 #
10 prg = gpart
11 version = 0.1h
0 #
1 # gpart man Makefile
2 #
3 include ../inst.defs
4 include ../make.defs
5
6
7 all: $(prg).$(manext)
8
9 $(prg).$(manext): $(prg).man
10 @sed -e 's/%MANEXT%/$(manext)/g' \
11 -e 's/%VERSION%/$(version)/g' < $< > $@
12
13 $(prg).$(manext).ps: $(prg).$(manext)
14 @groff -man $< > $@
15
16 clean:
17 @$(RM) $(prg).$(manext) $(prg).$(manext).ps
18
19 install: $(prg).$(manext)
20 $(INSTALL) -d $(mandir)
21 $(INSTALL) -d $(mandir)/man$(manext)
22 $(INSTALL) -m 0444 $(prg).$(manext) $(mandir)/man$(manext)
23
24 uninstall:
25 $(RM) $(mandir)/man$(manext)/$(prg).$(manext)
+0
-1
man/Makefile.am less more
0 man_MANS = gpart.8
+0
-506
man/gpart.8.in less more
0 .\"
1 .\" gpart v@VERSION@ man page (c) Jan 1999 Michail Brzitwa
2 .\"
3 .TH GPART 8 "January 2001" "Administration Tools"
4 .SH NAME
5 gpart \- guess PC-type hard disk partitions
6 .SH SYNOPSIS
7 .B gpart
8 [options]
9 .I device
10
11 Options: [-b <backup MBR>][-C c,h,s][-c][-d][-E][-e][-f]
12 [-g][-h][-i][-K <last-sector>][-k <# of sectors>] [-L]
13 [-l <log file>][-n <increment>] [-q][-s <sector-size>]
14 [-t <module-name>][-V][-v] [-W <device>][-w <module-name,
15 weight>]
16 .SH DESCRIPTION
17 .B gpart
18 tries to guess which partitions are on a hard disk.
19 If the primary partition table has been lost, overwritten
20 or destroyed the partitions still exist on the disk but
21 the operating system cannot access them.
22
23 .B gpart
24 ignores the primary partition table and scans the disk
25 (or disk image, file) sector after sector for several
26 filesystem/partition types. It does so by "asking" filesystem
27 recognition modules if they think a given sequence of
28 sectors resembles the beginning of a filesystem or partition
29 type. Currently the following filesystem types are known to
30 .B gpart
31 (listed by module names) :
32
33 .TP
34 .I beos
35 BeOS filesystem type.
36 .TP
37 .I bsddl
38 FreeBSD/NetBSD/386BSD disklabel sub-partitioning
39 scheme used on Intel platforms.
40 .TP
41 .I ext2
42 Linux second extended filesystem.
43 .TP
44 .I fat
45 MS-DOS FAT12/16/32 "filesystems".
46 .TP
47 .I hpfs
48 IBM OS/2 High Performance filesystem.
49 .TP
50 .I hmlvm
51 Linux LVM physical volumes (LVM by Heinz Mauelshagen).
52 .TP
53 .I lswap
54 Linux swap partitions (versions 0 and 1).
55 .TP
56 .I minix
57 The Minix operating system filesystem type.
58 .TP
59 .I ntfs
60 MS Windows NT/2000 filesystem.
61 .TP
62 .I qnx4
63 QNX 4.x filesystem.
64 .TP
65 .I reiserfs
66 The Reiser filesystem (version 3.5.X, X > 11, 3.6.X).
67 .TP
68 .I s86dl
69 Sun Solaris on Intel platforms uses a sub-partitioning
70 scheme on PC hard disks similar to the BSD disklabels.
71 .TP
72 .I xfs
73 Silicon Graphic's journalling filesystem for Linux.
74 .PP
75 More filesystem guessing modules can be added at
76 runtime (see the
77 .I -t
78 option). Please consult the
79 .B gpart
80 README file for detailed explanations on how to create
81 guessing modules. All modules are accompanied by a guessing
82 weight factor which denotes how "educated" their guesses
83 are compared to other modules. This weight can be
84 changed if a certain module keeps on mis-identifying
85 a partition.
86
87 Naturally only partitions which have been formatted in
88 some way can be recognized. If the type of a partition
89 entry in the primary partition table is changed from
90 x to y while the filesystem is still of type x,
91 .B gpart
92 will also still guess a type x.
93
94 No checks are performed whether a found filesystem
95 is clean or even consistent/mountable, so it is quite
96 possible that
97 .B gpart
98 may identify partitions which existed prior to the current
99 partitioning scheme of the disk. Especially on large
100 disks old file system headers/superblocks may be present
101 a long time until they are finally overwritten with
102 user data.
103
104 It should be stressed that
105 .B gpart
106 does a very heuristic job, never believe its output
107 without any plausability checks. It can be easily right
108 in its guesswork but it can also be terribly wrong. You
109 have been warned.
110
111 After having found a list of possible partition types,
112 the list is checked for consistency. For example, a
113 partition which overlaps with the previous one will be
114 discarded. All remaining partitions are labelled with
115 one of the following attributes: "primary", "logical",
116 "orphaned" or "invalid".
117
118 A partition labelled "orphaned" is a logical partition
119 which seems ok but is missed in the chain of logical
120 partitions. This may occur if a logical partition is
121 deleted from the extended partition table without
122 overwriting the actual disk space.
123
124 An "invalid" partition is one that cannot be accepted
125 because of various reasons. If a consistent primary partition
126 table was created in this process it is printed and
127 can be written to a file or device.
128
129 .SH EXTENDED PARTITIONS
130 If the disk/file to be examined consists of primary
131 partitions only,
132 .B gpart
133 has quite a good chance to identify them. Extended
134 partitions on the other hand can result in a lot of
135 problems.
136
137 Extended partitions are realized as a linked list of
138 extended partition tables, each of which include an
139 entry pointing to a logical partition. The size of an
140 extended partition depends on where the last logical
141 partition ends. This means that extended partitions
142 may include "holes", unallocated disk space which
143 should only be assigned to logical, not primary partitions.
144
145 .B gpart
146 tries to do its best to check a found chain of logical
147 partitions but there are very many possible points of
148 failure. If "good" fdisk programs are used to create
149 extended partitions, the resulting tables consist of
150 a zeroed boot record and the four partition entries
151 of which at least two should be marked unused. Unfortunately
152 e.g. the fdisk program shipped with Windows NT does
153 not seem to zero out the boot record area so
154 .B gpart
155 has to be overly tolerant in recognizing extended partition
156 tables. This tolerance may result in quite stupid
157 guesses.
158
159 .SH DISK TRANSFERS
160 If you want to investigate hard disks from other systems
161 you should note down the geometry (number of cylinders,
162 heads per cylinder and sectors per head) used for that
163 disk, and tell
164 .B gpart
165 about this geometry.
166
167 Investigating disks from machines with a different
168 endianness than the scanning one has not been tested
169 at all, and is currently not recommended.
170
171 .SH LARGE DISKS
172 .B gpart
173 relies on the OS reporting the correct disk geometry.
174 Unfortunately sometimes the OS may report a geometry
175 smaller the the actual one (e.g. disks with more than
176 1024 or 16384 cylinder).
177
178 .B gpart
179 checks if guessed partitions extend beyond the disk
180 size and marks those "invalid", but may be mistaken
181 in case the disk size is calculated from an incorrect
182 geometry. For instance if a disk with the geometry
183 1028/255/63 should be scanned, and the OS reports
184 1024/255/63
185 .B gpart
186 should be called like
187
188 .RS
189 gpart -C 1028,255,63 <other options> <device>
190 .RE
191
192 .SH PRECAUTIONS
193 .B gpart
194 may be of some help when the primary partition table was
195 lost or destroyed but it can under
196 .B no
197 circumstances replace proper disk/partition table backups.
198 To save the master boot record (MBR) including the primary
199 partition table to a file type
200
201 .RS
202 dd if=/dev/hda of=mbr bs=512 count=1
203 .RE
204
205 exchanging /dev/hda with the block device name of the
206 disk in question. This should be done for all disks
207 in the system. To restore the primary partition table
208 without overwriting the MBR type
209
210 .RS
211 dd if=mbr of=/dev/hda bs=1 count=64 skip=446 seek=446
212 .RE
213
214 .B Warning:
215 make sure that all parameters are typed as shown and
216 that the disk device is correct. Failing to do so may
217 result in severe filesystem corruption. The saved file
218 should be stored in a safe place like a floppy disk.
219
220 .SH OPTIONS
221 .IP "-b backupfile"
222 If the guessed primary partition table seems consistent
223 and should be written (see the
224 .I
225 -W
226 option) backup the current MBR into the specified file.
227 .IP "-C c,h,s"
228 Set the disk geometry (cylinders, heads, sectors) for
229 the scan. This is useful if a disk should be scanned
230 which was partitioned using a different geometry, if the
231 .I device
232 is a disk-image or if the disk geometry cannot be retrieved
233 through the PCs BIOS. No spaces are allowed between the
234 numbers, unless all three are enclosed in quotes.
235 .IP -c
236 Check/compare mode (implies the
237 .I -q
238 quiet option). After the scan is done, the resulting
239 primary partition table is compared to the existing
240 one. The return code of
241 .B gpart
242 then contains the number of differences (0 if they
243 are identical except for the boot/active flag which
244 cannot be guessed). This option has no effect if
245 .I -d
246 is given on the command line.
247 .IP -d
248 Do not start the guessing loop. Useful if the partition
249 table should be printed (in combination with the
250 .I -v
251 option) without actually scanning for partitions.
252 .IP -E
253 Do not try to identify extended partition tables. If
254 there are extended partitions on the given device
255 .B gpart
256 will most certainly complain about too many primary
257 partitions because there can be only four primary
258 partitions. Existing logical partitions will be listed
259 as primary ones.
260 .IP -e
261 Do not skip disk read errors. If this option is given,
262 and short disk reads or general disk read errors (EIO)
263 are encountered,
264 .B gpart
265 will exit. If not given, the program tries to continue.
266 .IP -f
267 Full scan. When a possible partition is found,
268 .B gpart
269 normally skips all sectors this entry seems to occupy
270 and continues the scan from the end of the last possible
271 partition. The disk scan can take quite a while if
272 this option is given, be patient.
273 .IP -g
274 Do not try to get the disk geometry from the OS. If the
275 .I device
276 is no block or character device but a plain file this
277 option should be supplied. If the file to be scanned is
278 an image of a disk, the geometry can be given by the
279 .I -C
280 option.
281 .IP -h
282 Show some help.
283 .IP -i
284 Run interactively. Each time a possible partition is
285 identified the user is asked for confirmation.
286 .IP "-K last sector"
287 Scan only up to the given sector or the end of the file
288 or device whichever comes first.
289 .IP "-k sectors"
290 Skip given number of sectors before the scan. Potentially
291 useful if a partition is looked for at the end of a
292 large disk.
293 .IP -L
294 List available filesystem/partition type modules and
295 their weights, then exit.
296 .IP "-l logfile"
297 Log output to the given file (even if
298 .I -q
299 was supplied).
300 .IP "-n increment"
301 Scan increment: number of sectors or "s" for single
302 sector increment, "h" for an increment of sectors
303 per head (depends on geometry) or "c" for cylinder
304 increment.
305
306 The increment also influences the condition where extended
307 partition tables are searched: if the scan increment
308 is "s" (i.e. 1) extended partition tables are required
309 to be on a head boundary, otherwise they must be on a
310 cylinder boundary.
311
312 If the disk geometry could not be retrieved and no
313 geometry was given on the command line, the default
314 increment is one sector.
315 .IP -q
316 Quiet/no output mode. However if a logfile was
317 specified (see
318 .I -l
319 option) all output is written to that file. This
320 option overrides the
321 .I -i
322 interactive mode.
323 .IP "-s sector size"
324 Preset medium sector size.
325 .B gpart
326 tries to find out the sector size but may fail in
327 doing so. Probed sector sizes are 2^i, i=9..14
328 (512 to 16384 bytes). The default medium sector
329 size is 512 bytes.
330 .IP -V
331 Show version number.
332 .IP -v
333 Be verbose. This option can be given more than
334 once resulting in quite a lot of information.
335 .IP "-W device"
336 Write partition table. If a consistent primary
337 partition table has been guessed it can be written
338 to the specified file or device. The supplied device
339 can be the same as the scanned one.
340
341 Additionally the guessed partition entries can
342 be edited. No checks are performed on the entered
343 values, thus the resulting table is allowed to
344 be highly inconsistent. Please beware.
345
346 .B Warning:
347 The guessed partition table should be checked
348 very carefully before writing it back. You can
349 always write the guessed partition table into a
350 plain file and write this into sector 0 using
351 .BR dd (1)
352 (see section PRECAUTIONS above).
353
354 .IP "-w module name,weight"
355 Put the given module at the head of the module chain
356 and assign a new weight to that module. All modules
357 are given an initial weight of 1.0. Again no spaces
358 are allowed.
359
360
361 .PP
362 Default settings are "-n h".
363
364 .SH EXAMPLES
365 \-\ To scan the first IDE hard disk under Linux using default
366 settings type
367
368 .RS
369 gpart /dev/hda
370 .RE
371
372 \-\ To print the primary partition table of the third IDE
373 drive without starting the scan loop in FreeBSD type
374
375 .RS
376 gpart -vvd /dev/wd2
377 .RE
378 .RE
379
380 \-\ If
381 .BR lilo(8)
382 was installed in the master boot record (MBR) of a
383 hard disk it saves the contents of the first sector
384 in a file called /boot/boot.<major/minor>. To list
385 the partitions contained in such a file type e.g.
386
387 .RS
388 gpart -vdg /boot/boot.0300
389 .RE
390
391 If the partition table contains an extended partition,
392 .B gpart
393 will complain about invalid extended partition tables
394 because the extended entry points to sectors not within
395 that file.
396
397 \-\ Usually the first primary partition starts on the
398 second head. If
399 .B gpart
400 cannot identify the first partition properly this may
401 not be the case.
402 .B gpart
403 can be told to start the scan directly from sector one
404 of the disk, using the sector-wise scan mode:
405
406 .RS
407 gpart -k 1 -n s /dev/hdb
408 .RE
409
410 \-\ Suppose
411 .B gpart
412 identifies an NTFS partition as FAT on a certain
413 disk. In this situation the "ntfs" module should be
414 made the first module to be probed and given a
415 weight higher than the usual weight of 1.0:
416
417 .RS
418 gpart -w ntfs,1.5 /dev/hdb
419 .RE
420
421 To list the available modules and their weights use
422 the
423 .I -L
424 option.
425
426 \-\ After having checked the output of
427 .B gpart
428 at least thrice, the primary partition table can
429 be written back to the device this way:
430
431 .RS
432 gpart -W /dev/sdc /dev/sdc
433 .RE
434
435 This of course may be extremely dangerous to your health
436 and social security, so beware.
437
438 \-\ A hard disk with 63 sectors per head is scanned in
439 steps of 63 sectors. To perform the scan on every second
440 head while skipping the first 1008 sectors type
441
442 .RS
443 gpart -k 1008 -n 126 /dev/sda
444 .RE
445
446 \-\ If you want to see how easily
447 .B gpart
448 can be mislead, and how many probable partition starts
449 are on a disk, search the whole disk really sector by
450 sector, writing all output to a logfile:
451
452 .RS
453 gpart -vvfn s -ql /tmp/gpart.log /dev/sd2 &
454 .RE
455
456 Usually
457 .B gpart
458 will not be able to produce an educated guess of the
459 primary partition table in this mode. The logfile
460 however may contain enough hints to manually reconstruct
461 the partition table.
462
463 .SH FILES
464 .I /dev/*
465 .RS
466 Hard disk block devices. The naming scheme of hard disk
467 block devices is OS dependent, consult your system manuals
468 for more information.
469 .RE
470
471 .SH DIAGNOSTICS
472 There are many error message types, all of them should
473 be self-explanatory. Complain if they are not.
474
475 .SH BUGS
476 .B gpart
477 is beta software, so expect buggy behaviour.
478
479 \-\
480 .B gpart
481 only accepts extended partition links with one logical
482 partition. There may be
483 .B fdisk
484 variants out there creating links with up to three
485 logical partition entries but these are not accepted.
486
487 .SH TO DO
488 .br
489 \-\ Support big-endian architectures.
490 .br
491 \-\ Test on 64-bit architectures.
492 .br
493 \-\ Look for boot manager partitions (e.g. OS/2 BM).
494 .br
495 \-\ Think about reconstructing logical partition chains.
496
497 .SH AUTHOR
498 Please send bug reports, suggestions, comments etc. to
499
500 .RS
501 Michail Brzitwa <michail@brzitwa.de>
502 .RE
503
504 .SH "SEE ALSO"
505 .BR fdisk (8).
0 .\"
1 .\" gpart v%VERSION% man page (c) Jan 1999 Michail Brzitwa
2 .\"
3 .TH GPART %MANEXT% "January 2001" "Administration Tools"
4 .SH NAME
5 gpart \- guess PC-type hard disk partitions
6 .SH SYNOPSIS
7 .B gpart
8 [options]
9 .I device
10
11 Options: [-b <backup MBR>][-C c,h,s][-c][-d][-E][-e][-f]
12 [-g][-h][-i][-K <last-sector>][-k <# of sectors>] [-L]
13 [-l <log file>][-n <increment>] [-q][-s <sector-size>]
14 [-t <module-name>][-V][-v] [-W <device>][-w <module-name,
15 weight>]
16 .SH DESCRIPTION
17 .B gpart
18 tries to guess which partitions are on a hard disk.
19 If the primary partition table has been lost, overwritten
20 or destroyed the partitions still exist on the disk but
21 the operating system cannot access them.
22
23 .B gpart
24 ignores the primary partition table and scans the disk
25 (or disk image, file) sector after sector for several
26 filesystem/partition types. It does so by "asking" filesystem
27 recognition modules if they think a given sequence of
28 sectors resembles the beginning of a filesystem or partition
29 type. Currently the following filesystem types are known to
30 .B gpart
31 (listed by module names) :
32
33 .TP
34 .I beos
35 BeOS filesystem type.
36 .TP
37 .I bsddl
38 FreeBSD/NetBSD/386BSD disklabel sub-partitioning
39 scheme used on Intel platforms.
40 .TP
41 .I ext2
42 Linux second extended filesystem.
43 .TP
44 .I fat
45 MS-DOS FAT12/16/32 "filesystems".
46 .TP
47 .I hpfs
48 IBM OS/2 High Performance filesystem.
49 .TP
50 .I hmlvm
51 Linux LVM physical volumes (LVM by Heinz Mauelshagen).
52 .TP
53 .I lswap
54 Linux swap partitions (versions 0 and 1).
55 .TP
56 .I minix
57 The Minix operating system filesystem type.
58 .TP
59 .I ntfs
60 MS Windows NT/2000 filesystem.
61 .TP
62 .I qnx4
63 QNX 4.x filesystem.
64 .TP
65 .I rfs
66 The Reiser filesystem (version 3.5.X, X > 11).
67 .TP
68 .I s86dl
69 Sun Solaris on Intel platforms uses a sub-partitioning
70 scheme on PC hard disks similar to the BSD disklabels.
71 .TP
72 .I xfs
73 Silicon Graphic's journalling filesystem for Linux.
74 .PP
75 More filesystem guessing modules can be added at
76 runtime (see the
77 .I -t
78 option). Please consult the
79 .B gpart
80 README file for detailed explanations on how to create
81 guessing modules. All modules are accompanied by a guessing
82 weight factor which denotes how "educated" their guesses
83 are compared to other modules. This weight can be
84 changed if a certain module keeps on mis-identifying
85 a partition.
86
87 Naturally only partitions which have been formatted in
88 some way can be recognized. If the type of a partition
89 entry in the primary partition table is changed from
90 x to y while the filesystem is still of type x,
91 .B gpart
92 will also still guess a type x.
93
94 No checks are performed whether a found filesystem
95 is clean or even consistent/mountable, so it is quite
96 possible that
97 .B gpart
98 may identify partitions which existed prior to the current
99 partitioning scheme of the disk. Especially on large
100 disks old file system headers/superblocks may be present
101 a long time until they are finally overwritten with
102 user data.
103
104 It should be stressed that
105 .B gpart
106 does a very heuristic job, never believe its output
107 without any plausability checks. It can be easily right
108 in its guesswork but it can also be terribly wrong. You
109 have been warned.
110
111 After having found a list of possible partition types,
112 the list is checked for consistency. For example, a
113 partition which overlaps with the previous one will be
114 discarded. All remaining partitions are labelled with
115 one of the following attributes: "primary", "logical",
116 "orphaned" or "invalid".
117
118 A partition labelled "orphaned" is a logical partition
119 which seems ok but is missed in the chain of logical
120 partitions. This may occur if a logical partition is
121 deleted from the extended partition table without
122 overwriting the actual disk space.
123
124 An "invalid" partition is one that cannot be accepted
125 because of various reasons. If a consistent primary partition
126 table was created in this process it is printed and
127 can be written to a file or device.
128
129 .SH EXTENDED PARTITIONS
130 If the disk/file to be examined consists of primary
131 partitions only,
132 .B gpart
133 has quite a good chance to identify them. Extended
134 partitions on the other hand can result in a lot of
135 problems.
136
137 Extended partitions are realized as a linked list of
138 extended partition tables, each of which include an
139 entry pointing to a logical partition. The size of an
140 extended partition depends on where the last logical
141 partition ends. This means that extended partitions
142 may include "holes", unallocated disk space which
143 should only be assigned to logical, not primary partitions.
144
145 .B gpart
146 tries to do its best to check a found chain of logical
147 partitions but there are very many possible points of
148 failure. If "good" fdisk programs are used to create
149 extended partitions, the resulting tables consist of
150 a zeroed boot record and the four partition entries
151 of which at least two should be marked unused. Unfortunately
152 e.g. the fdisk program shipped with Windows NT does
153 not seem to zero out the boot record area so
154 .B gpart
155 has to be overly tolerant in recognizing extended partition
156 tables. This tolerance may result in quite stupid
157 guesses.
158
159 .SH DISK TRANSFERS
160 If you want to investigate hard disks from other systems
161 you should note down the geometry (number of cylinders,
162 heads per cylinder and sectors per head) used for that
163 disk, and tell
164 .B gpart
165 about this geometry.
166
167 Investigating disks from machines with a different
168 endianness than the scanning one has not been tested
169 at all, and is currently not recommended.
170
171 .SH LARGE DISKS
172 .B gpart
173 relies on the OS reporting the correct disk geometry.
174 Unfortunately sometimes the OS may report a geometry
175 smaller the the actual one (e.g. disks with more than
176 1024 or 16384 cylinder).
177
178 .B gpart
179 checks if guessed partitions extend beyond the disk
180 size and marks those "invalid", but may be mistaken
181 in case the disk size is calculated from an incorrect
182 geometry. For instance if a disk with the geometry
183 1028/255/63 should be scanned, and the OS reports
184 1024/255/63
185 .B gpart
186 should be called like
187
188 .RS
189 gpart -C 1028,255,63 <other options> <device>
190 .RE
191
192 .SH PRECAUTIONS
193 .B gpart
194 may be of some help when the primary partition table was
195 lost or destroyed but it can under
196 .B no
197 circumstances replace proper disk/partition table backups.
198 To save the master boot record (MBR) including the primary
199 partition table to a file type
200
201 .RS
202 dd if=/dev/hda of=mbr bs=512 count=1
203 .RE
204
205 exchanging /dev/hda with the block device name of the
206 disk in question. This should be done for all disks
207 in the system. To restore the primary partition table
208 without overwriting the MBR type
209
210 .RS
211 dd if=mbr of=/dev/hda bs=1 count=64 skip=446 seek=446
212 .RE
213
214 .B Warning:
215 make sure that all parameters are typed as shown and
216 that the disk device is correct. Failing to do so may
217 result in severe filesystem corruption. The saved file
218 should be stored in a safe place like a floppy disk.
219
220 .SH OPTIONS
221 .IP "-b backupfile"
222 If the guessed primary partition table seems consistent
223 and should be written (see the
224 .I
225 -W
226 option) backup the current MBR into the specified file.
227 .IP "-C c,h,s"
228 Set the disk geometry (cylinders, heads, sectors) for
229 the scan. This is useful if a disk should be scanned
230 which was partitioned using a different geometry, if the
231 .I device
232 is a disk-image or if the disk geometry cannot be retrieved
233 through the PCs BIOS. No spaces are allowed between the
234 numbers, unless all three are enclosed in quotes.
235 .IP -c
236 Check/compare mode (implies the
237 .I -q
238 quiet option). After the scan is done, the resulting
239 primary partition table is compared to the existing
240 one. The return code of
241 .B gpart
242 then contains the number of differences (0 if they
243 are identical except for the boot/active flag which
244 cannot be guessed). This option has no effect if
245 .I -d
246 is given on the command line.
247 .IP -d
248 Do not start the guessing loop. Useful if the partition
249 table should be printed (in combination with the
250 .I -v
251 option) without actually scanning for partitions.
252 .IP -E
253 Do not try to identify extended partition tables. If
254 there are extended partitions on the given device
255 .B gpart
256 will most certainly complain about too many primary
257 partitions because there can be only four primary
258 partitions. Existing logical partitions will be listed
259 as primary ones.
260 .IP -e
261 Do not skip disk read errors. If this option is given,
262 and short disk reads or general disk read errors (EIO)
263 are encountered,
264 .B gpart
265 will exit. If not given, the program tries to continue.
266 .IP -f
267 Full scan. When a possible partition is found,
268 .B gpart
269 normally skips all sectors this entry seems to occupy
270 and continues the scan from the end of the last possible
271 partition. The disk scan can take quite a while if
272 this option is given, be patient.
273 .IP -g
274 Do not try to get the disk geometry from the OS. If the
275 .I device
276 is no block or character device but a plain file this
277 option should be supplied. If the file to be scanned is
278 an image of a disk, the geometry can be given by the
279 .I -C
280 option.
281 .IP -h
282 Show some help.
283 .IP -i
284 Run interactively. Each time a possible partition is
285 identified the user is asked for confirmation.
286 .IP "-K last sector"
287 Scan only up to the given sector or the end of the file
288 or device whichever comes first.
289 .IP "-k sectors"
290 Skip given number of sectors before the scan. Potentially
291 useful if a partition is looked for at the end of a
292 large disk.
293 .IP -L
294 List available filesystem/partition type modules and
295 their weights, then exit.
296 .IP "-l logfile"
297 Log output to the given file (even if
298 .I -q
299 was supplied).
300 .IP "-n increment"
301 Scan increment: number of sectors or "s" for single
302 sector increment, "h" for an increment of sectors
303 per head (depends on geometry) or "c" for cylinder
304 increment.
305
306 The increment also influences the condition where extended
307 partition tables are searched: if the scan increment
308 is "s" (i.e. 1) extended partition tables are required
309 to be on a head boundary, otherwise they must be on a
310 cylinder boundary.
311
312 If the disk geometry could not be retrieved and no
313 geometry was given on the command line, the default
314 increment is one sector.
315 .IP -q
316 Quiet/no output mode. However if a logfile was
317 specified (see
318 .I -l
319 option) all output is written to that file. This
320 option overrides the
321 .I -i
322 interactive mode.
323 .IP "-s sector size"
324 Preset medium sector size.
325 .B gpart
326 tries to find out the sector size but may fail in
327 doing so. Probed sector sizes are 2^i, i=9..14
328 (512 to 16384 bytes). The default medium sector
329 size is 512 bytes.
330 .IP "-t module name"
331 Plug in another guessing module. The module to
332 be dynamically linked in must be a shared object
333 file named "gm_<modname>.so".
334 .IP -V
335 Show version number.
336 .IP -v
337 Be verbose. This option can be given more than
338 once resulting in quite a lot of information.
339 .IP "-W device"
340 Write partition table. If a consistent primary
341 partition table has been guessed it can be written
342 to the specified file or device. The supplied device
343 can be the same as the scanned one.
344
345 Additionally the guessed partition entries can
346 be edited. No checks are performed on the entered
347 values, thus the resulting table is allowed to
348 be highly inconsistent. Please beware.
349
350 .B Warning:
351 The guessed partition table should be checked
352 very carefully before writing it back. You can
353 always write the guessed partition table into a
354 plain file and write this into sector 0 using
355 .BR dd (1)
356 (see section PRECAUTIONS above).
357
358 .IP "-w module name,weight"
359 Put the given module at the head of the module chain
360 and assign a new weight to that module. All modules
361 are given an initial weight of 1.0. Again no spaces
362 are allowed.
363
364
365 .PP
366 Default settings are "-n h".
367
368 .SH EXAMPLES
369 \-\ To scan the first IDE hard disk under Linux using default
370 settings type
371
372 .RS
373 gpart /dev/hda
374 .RE
375
376 \-\ To print the primary partition table of the third IDE
377 drive without starting the scan loop in FreeBSD type
378
379 .RS
380 gpart -vvd /dev/wd2
381 .RE
382 .RE
383
384 \-\ If
385 .BR lilo(8)
386 was installed in the master boot record (MBR) of a
387 hard disk it saves the contents of the first sector
388 in a file called /boot/boot.<major/minor>. To list
389 the partitions contained in such a file type e.g.
390
391 .RS
392 gpart -vdg /boot/boot.0300
393 .RE
394
395 If the partition table contains an extended partition,
396 .B gpart
397 will complain about invalid extended partition tables
398 because the extended entry points to sectors not within
399 that file.
400
401 \-\ Usually the first primary partition starts on the
402 second head. If
403 .B gpart
404 cannot identify the first partition properly this may
405 not be the case.
406 .B gpart
407 can be told to start the scan directly from sector one
408 of the disk, using the sector-wise scan mode:
409
410 .RS
411 gpart -k 1 -n s /dev/hdb
412 .RE
413
414 \-\ Suppose
415 .B gpart
416 identifies an NTFS partition as FAT on a certain
417 disk. In this situation the "ntfs" module should be
418 made the first module to be probed and given a
419 weight higher than the usual weight of 1.0:
420
421 .RS
422 gpart -w ntfs,1.5 /dev/hdb
423 .RE
424
425 To list the available modules and their weights use
426 the
427 .I -L
428 option.
429
430 \-\ After having checked the output of
431 .B gpart
432 at least thrice, the primary partition table can
433 be written back to the device this way:
434
435 .RS
436 gpart -W /dev/sdc /dev/sdc
437 .RE
438
439 This of course may be extremely dangerous to your health
440 and social security, so beware.
441
442 \-\ A hard disk with 63 sectors per head is scanned in
443 steps of 63 sectors. To perform the scan on every second
444 head while skipping the first 1008 sectors type
445
446 .RS
447 gpart -k 1008 -n 126 /dev/sda
448 .RE
449
450 \-\ If you want to see how easily
451 .B gpart
452 can be mislead, and how many probable partition starts
453 are on a disk, search the whole disk really sector by
454 sector, writing all output to a logfile:
455
456 .RS
457 gpart -vvfn s -ql /tmp/gpart.log /dev/sd2 &
458 .RE
459
460 Usually
461 .B gpart
462 will not be able to produce an educated guess of the
463 primary partition table in this mode. The logfile
464 however may contain enough hints to manually reconstruct
465 the partition table.
466
467 .SH FILES
468 .I /dev/*
469 .RS
470 Hard disk block devices. The naming scheme of hard disk
471 block devices is OS dependent, consult your system manuals
472 for more information.
473 .RE
474
475 .SH DIAGNOSTICS
476 There are many error message types, all of them should
477 be self-explanatory. Complain if they are not.
478
479 .SH BUGS
480 .B gpart
481 is beta software, so expect buggy behaviour.
482
483 \-\
484 .B gpart
485 only accepts extended partition links with one logical
486 partition. There may be
487 .B fdisk
488 variants out there creating links with up to three
489 logical partition entries but these are not accepted.
490
491 .SH TO DO
492 .br
493 \-\ Support big-endian architectures.
494 .br
495 \-\ Test on 64-bit architectures.
496 .br
497 \-\ Look for boot manager partitions (e.g. OS/2 BM).
498 .br
499 \-\ Think about reconstructing logical partition chains.
500
501 .SH AUTHOR
502 Please send bug reports, suggestions, comments etc. to
503
504 .RS
505 Michail Brzitwa <michail@brzitwa.de>
506 .RE
507
508 .SH "SEE ALSO"
509 .BR fdisk (8).
0 #
1 # gpart src Makefile
2 #
3 include ../inst.defs
4 include ../make.defs
5
6 CFLAGS+=-DVERSION=\"$(version)\"
7 ifeq ($(shell uname),Linux)
8 LIBS=-ldl
9 endif
10
11 ifdef DEBUG
12 CFLAGS+=-g
13 LDFLAGS+=-g
14 endif
15
16 ifdef GPART_LANG
17 CFLAGS+=-DGPART_LANG=\'$(GPART_LANG)\'
18 endif
19
20
21 mod=ext2 lswap fat bsddl ntfs hpfs s86dl minix rfs hmlvm qnx4 beos xfs
22 modobj=$(foreach m,$(mod),gm_$(m).o)
23 obj=gpart.o gmodules.o disku.o l64seek.o $(modobj)
24 src=$(obj:.o=.c)
25 hdr=$(wildcard *.h)
26 allsrc=Makefile $(src) $(hdr)
27
28 all: $(prg)
29
30 $(prg): $(obj)
31 $(CC) -o $@ $(LDFLAGS) $(obj) $(LIBS)
32
33 install: $(prg)
34 $(INSTALL) -d $(bindir)
35 $(INSTALL) -s $(prg) $(bindir)
36
37 uninstall:
38 $(RM) $(bindir)/$(prg)
39
40 clean:
41 @$(RM) $(obj) $(prg) .depend
42
43 static:
44 @$(MAKE) LDFLAGS=-static
45
46 rcscheck:
47 @for f in $(allsrc); do \
48 rcsdiff $$f >/dev/null 2>&1 || echo "Please checkin $$f"; \
49 done
50
51 checkin:
52 @for f in $(allsrc); do \
53 rcsdiff $$f >/dev/null 2>&1 || ci -m"v$(version)" -l $$f; \
54 done
55
56
57 .depend: $(src)
58 @$(MAKEDEP) $(src) > $@
59
60 -include .depend
+0
-6
src/Makefile.am less more
0 AM_CFLAGS = -Wall -O2
1 AM_LDFLAGS =
2
3 bin_PROGRAMS = gpart
4 gpart_SOURCES = disku.c gm_beos.c gm_bsddl.c gm_ext2.c gm_fat.c gm_hmlvm.c gm_hpfs.c gm_lswap.c gm_minix.c gm_ntfs.c gmodules.c gm_qnx4.c gm_reiserfs.c gm_s86dl.c gm_xfs.c gpart.c l64seek.c
5 EXTRA_DIST = errmsgs.h gm_bsddl.h gm_fat.h gm_hpfs.h gm_ntfs.h gm_qnx4.h gm_s86dl.h gpart.h gm_beos.h gm_ext2.h gm_hmlvm.h gm_minix.h gmodules.h gm_reiserfs.h gm_xfs.h l64seek.h
1515 */
1616
1717
18 #include <errno.h>
1918 #include <stdio.h>
2019 #include <string.h>
2120 #include <sys/ioctl.h>
22 #include <errno.h>
2321 #include "gpart.h"
2422
2523 #if defined(__linux__)
2826 #endif
2927
3028 #if defined(__FreeBSD__)
31 #include <sys/param.h>
29 #include <errno.h>
3230 #include <sys/disklabel.h>
33 #include <sys/disk.h>
3431 #endif
3532
36 #include <unistd.h>
3733
3834
3935 /*
4440 struct disk_geom *disk_geometry(disk_desc *d)
4541 {
4642 static struct disk_geom g;
47 uint64_t nsects;
48
49 memset(&g, 0, sizeof(g));
5043
5144 #if defined(__linux__)
5245 struct hd_geometry hg;
53 #endif
54 #if defined(__FreeBSD__)
55 struct disklabel dl;
56 #endif
46 long nsects;
5747
58 struct stat st;
59 int ret;
60 uint64_t lba;
61 ret = stat(d->d_dev, &st);
62 if (ret == 0)
63 {
64 if (S_ISREG(st.st_mode))
65 {
66 nsects = st.st_size / 512;
67 if (nsects == 0)
68 pr(FATAL, EM_FATALERROR, "Not a block device image file");
69 lba = nsects - 1;
70 g.d_h = (lba / 63) % 255;
71 g.d_s = lba % 63 + 1;
72 g.d_c = lba / (255 * 63);
73 g.d_nsecs = nsects;
74 return (&g);
75 }
76 }
77
78 #if defined(__linux__)
7948 if (ioctl(d->d_fd,HDIO_GETGEO,&hg) == -1)
8049 pr(FATAL,EM_IOCTLFAILED,"HDIO_GETGEO",strerror(errno));
8150 #ifdef BLKGETSIZE
8251 if (ioctl(d->d_fd,BLKGETSIZE,&nsects) == -1)
8352 pr(FATAL,EM_IOCTLFAILED,"BLKGETSIZE",strerror(errno));
84 g.d_nsecs = nsects;
8553 g.d_c = nsects / (hg.heads * hg.sectors);
8654 #else
8755 g.d_c = hg.cylinders;
9260 #endif
9361
9462 #if defined(__FreeBSD__)
95 struct disklabel loclab;
96 u_int u;
97 off_t o; /* total disk size */
98
99 if (ioctl(d->d_fd, DIOCGFWSECTORS, &u) == 0)
100 g.d_s = u;
101 else
102 pr(FATAL, EM_IOCTLFAILED, "DIOCGFWSECTORS", strerror(errno));
103 // loclab.d_nsectors = 63;
104 if (ioctl(d->d_fd, DIOCGFWHEADS, &u) == 0)
105 g.d_h = u;
106 else
107 pr(FATAL, EM_IOCTLFAILED, "DIOCGFWHEADS", strerror(errno));
108 if (ioctl(d->d_fd, DIOCGSECTORSIZE, &u) == 0)
109 if (u != 512)
110 pr(FATAL, "sector size not a multiple of 512");
111 if (ioctl(d->d_fd, DIOCGMEDIASIZE, &o))
112 pr(FATAL, EM_IOCTLFAILED, "DIOCGMEDIASIZE", strerror(errno));
113
114 g.d_nsecs = o / u;
115 g.d_c = g.d_nsecs / g.d_h / g.d_s;
63 struct disklabel dl;
64 if (ioctl(d->d_fd,DIOCGDINFO,&dl) == -1)
65 pr(FATAL,EM_IOCTLFAILED,"DIOCGDINFO",strerror(errno));
66 g.d_c = dl.d_ncylinders;
67 g.d_h = dl.d_ntracks;
68 g.d_s = dl.d_nsectors;
11669 #endif
11770
11871 return (&g);
120120
121121 /*
122122 * current mount count shouldn't be greater than max+20
123 * but ext3 usually has s_max_mnt_count==-1
124123 */
125124
126 if ((sb->s_max_mnt_count!=-1)&&(sb->s_mnt_count > sb->s_max_mnt_count + 20))
125 if (sb->s_mnt_count > sb->s_max_mnt_count + 20)
127126 return (1);
128127
129128 /*
5959 __u16 info_sector; /* filesystem info sector */
6060 __u16 backup_boot; /* backup boot sector */
6161 __u16 reserved2[6]; /* Unused */
62 } __attribute__ ((packed));
63 /* "__attribute__ ((packed))"
64 added by davidc@debian.org,
65 as suggested by falk@zxmjz18.extern.uni-tuebingen.de
66 Fri Jul 07 18:04:15 2000
67 in debian bug report #66893 "FAT detection broken on Alpha" */
62 };
63
6864 #endif /* _GM_FAT_H */
4545
4646 int ntfs_gfun(disk_desc *d,g_module *m)
4747 {
48 int blocksize, clusterfactor, clustersize;
4849 int mft_clusters_per_record;
4950 s64_t size, ls;
5051 byte_t *ubuf, *sbuf;
6364 if (NTFS_GETU32(d->d_sbuf + 0x44) > 256UL)
6465 return (1);
6566
67 blocksize = NTFS_GETU16(d->d_sbuf + 0x0B);
68 clusterfactor = NTFS_GETU8(d->d_sbuf + 0x0D);
69 clustersize = blocksize * clusterfactor;
6670 mft_clusters_per_record = NTFS_GETS8(d->d_sbuf + 0x40);
6771 if ((mft_clusters_per_record < 0) && (mft_clusters_per_record != -10))
6872 return (1);
6973 size = NTFS_GETU64(d->d_sbuf + 0x28);
74
75 size /= clusterfactor;
76 size *= clustersize;
77 size /= d->d_ssize;
7078
7179 /*
7280 * look for an additional backup boot sector at the end of
1313 *
1414 */
1515
16 #include <stdint.h>
17 #include <asm/byteorder.h>
18
1916 #ifndef _GM_NTFS_H
2017 #define _GM_NTFS_H
2118
3128 /* 'NTFS' in little endian */
3229 #define NTFS_SUPER_MAGIC 0x5346544E
3330
31 #if defined(i386) || defined(__i386__) || defined(__alpha__)
32
3433 /* unsigned integral types */
3534 #ifndef NTFS_INTEGRAL_TYPES
3635 #define NTFS_INTEGRAL_TYPES
37 typedef uint8_t ntfs_u8;
38 typedef uint16_t ntfs_u16;
39 typedef uint32_t ntfs_u32;
40 typedef uint64_t ntfs_u64;
41 typedef int8_t ntfs_s8;
42 typedef int16_t ntfs_s16;
36 typedef unsigned char ntfs_u8;
37 typedef unsigned short ntfs_u16;
38 typedef unsigned int ntfs_u32;
39 typedef s64_t ntfs_u64;
4340 #endif /* NTFS_INTEGRAL_TYPES */
41 #endif /* defined(i386) || defined(__i386__) || defined(__alpha__) */
4442
4543
4644 /* Macros reading unsigned integers from a byte pointer */
45 /* these should work for all little endian machines */
4746 #define NTFS_GETU8(p) (*(ntfs_u8*)(p))
48 #define NTFS_GETU16(p) ((ntfs_u16)htole16(*(ntfs_u16*)(p)))
49 #define NTFS_GETU24(p) ((ntfs_u32)NTFS_GETU16(p) | \
50 ((ntfs_u32)NTFS_GETU8(((char*)p)+2))<<16)
51 #define NTFS_GETU32(p) ((ntfs_u32)htole32(*(ntfs_u32*)(p)))
52 #define NTFS_GETU64(p) ((ntfs_u64)htole64(*(ntfs_u64*)(p)))
47 #define NTFS_GETU16(p) (*(ntfs_u16*)(p))
48 #define NTFS_GETU24(p) (NTFS_GETU32(p) & 0xFFFFFF)
49 #define NTFS_GETU32(p) (*(ntfs_u32*)(p))
50 #define NTFS_GETU64(p) (*(ntfs_u64*)(p))
5351
5452 /* Macros reading signed integers, returning int */
55 #define NTFS_GETS8(p) (*(ntfs_s8*)(p))
56 #define NTFS_GETS16(p) ((ntfs_s16)htole16(*(ntfs_s16*)(p)))
57 #define NTFS_GETS24(p) (NTFS_GETU24(p) < 0x800000 ? \
58 (int)NTFS_GETU24(p) : \
59 (int)(NTFS_GETU24(p) - 0x1000000))
53 #define NTFS_GETS8(p) ((int)(*(char*)(p)))
54 #define NTFS_GETS16(p) ((int)(*(short*)(p)))
55 #define NTFS_GETS24(p) (NTFS_GETU24(p) < 0x800000 ? (int)NTFS_GETU24(p) :
56
57
6058
6159 #endif /* _GM_NTFS_H */
+0
-91
src/gm_reiserfs.c less more
0 /*
1 * gm_reiserfs.c -- gpart ReiserFS guessing module
2 *
3 * gpart (c) 1999-2001 Michail Brzitwa <mb@ichabod.han.de>
4 * Guess PC-type hard disk partitions.
5 *
6 * gpart is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published
8 * by the Free Software Foundation; either version 2, or (at your
9 * option) any later version.
10 *
11 * Created: 21.01.1999 <mb@ichabod.han.de>
12 * Modified: 26.12.2000 Francis Devereux <francis@devereux.tc>
13 * Added reiserfs 3.5.28 support.
14 * Modified: 10.01.2003 Yury Umanets <umka@namesys.com>
15 * Added reiserfs 3.6.x support.
16 *
17 */
18
19 #include <string.h>
20 #include <errno.h>
21 #include "gpart.h"
22 #include "gm_reiserfs.h"
23
24 static const char rcsid[] = "$Id: gm_reiserfs.c,v 1.5 2003/01/10 16:38:08 mb Exp mb $";
25
26
27 int reiserfs_init(disk_desc *d,g_module *m)
28 {
29 if ((d == 0) || (m == 0))
30 return (0);
31
32 m->m_desc = "ReiserFS filesystem";
33 return (REISERFS_FIRST_BLOCK * 1024 + SB_V35_SIZE);
34 }
35
36
37
38 int reiserfs_term(disk_desc *d)
39 {
40 return (1);
41 }
42
43
44
45 int reiserfs_gfun(disk_desc *d,g_module *m)
46 {
47 struct reiserfs_super_block_v35 *sb;
48 dos_part_entry *pt = &m->m_part;
49 s64_t size;
50
51 m->m_guess = GM_NO;
52 sb = (struct reiserfs_super_block_v35 *)(d->d_sbuf + REISERFS_FIRST_BLOCK * 1024);
53 if (strncmp(sb->s_magic,REISERFS_SUPER_V35_MAGIC,12) == 0 ||
54 strncmp(sb->s_magic,REISERFS_SUPER_V36_MAGIC,12) == 0)
55 {
56 /*
57 * sanity checks.
58 */
59
60 if (sb->s_block_count < sb->s_free_blocks)
61 return (1);
62
63 if (sb->s_block_count < REISERFS_MIN_BLOCK_AMOUNT)
64 return (1);
65
66 if ((sb->s_state != REISERFS_VALID_FS) &&
67 (sb->s_state != REISERFS_ERROR_FS))
68 return (1);
69
70 if (sb->s_oid_maxsize % 2) /* must be even */
71 return (1);
72
73 if (sb->s_oid_maxsize < sb->s_oid_cursize)
74 return (1);
75
76 if ((sb->s_blocksize != 4096) && (sb->s_blocksize != 8192))
77 return (1);
78
79 /*
80 * ok.
81 */
82
83 m->m_guess = GM_YES;
84 pt->p_start = d->d_nsb;
85 size = sb->s_block_count; size *= sb->s_blocksize; size /= d->d_ssize;
86 pt->p_size = (unsigned long)size;
87 pt->p_typ = 0x83;
88 }
89 return (1);
90 }
+0
-82
src/gm_reiserfs.h less more
0 /*
1 * gm_reiserfs.h -- gpart ReiserFS guessing module header
2 *
3 * gpart (c) 1999-2001 Michail Brzitwa <mb@ichabod.han.de>
4 * Guess PC-type hard disk partitions.
5 *
6 * gpart is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published
8 * by the Free Software Foundation; either version 2, or (at your
9 * option) any later version.
10 *
11 * Created: 21.01.1999 <mb@ichabod.han.de>
12 * Modified: 26.12.2000 Francis Devereux <francis@devereux.tc>
13 * Update support reiserfs version 3.5.28
14 * Modified: 10.01.2003 Yury Umanets <umka@namesys.com>
15 * Added reiserfs 3.6.x support.
16 *
17 */
18
19 #ifndef _GM_reiserfs_H
20 #define _GM_reiserfs_H
21
22 /* imported from asm/types.h */
23 typedef __signed__ char __s8;
24 typedef unsigned char __u8;
25
26 typedef __signed__ short __s16;
27 typedef unsigned short __u16;
28
29 typedef __signed__ int __s32;
30 typedef unsigned int __u32;
31
32 /*
33 * taken from ReiserFS v3.5.28, v3.6.x. Reiserfs Copyright 1996-2000 Hans Reiser
34 */
35
36 #define REISERFS_SUPER_V35_MAGIC "ReIsErFs"
37 #define REISERFS_SUPER_V36_MAGIC "ReIsEr2Fs"
38
39 #define REISERFS_FIRST_BLOCK 64
40 #define REISERFS_VALID_FS 1
41 #define REISERFS_ERROR_FS 2
42 #define REISERFS_MIN_BLOCK_AMOUNT 100
43
44 struct reiserfs_super_block_v35
45 {
46 __u32 s_block_count; /* blocks count */
47 __u32 s_free_blocks; /* free blocks count */
48 __u32 s_root_block; /* root block number */
49 __u32 s_journal_block; /* journal block number */
50 __u32 s_journal_dev; /* journal device number */
51 __u32 s_orig_journal_size; /* size of the journal on FS creation. used to make sure they don't overflow it */
52 __u32 s_journal_trans_max; /* max number of blocks in a transaction. */
53 __u32 s_journal_block_count; /* total size of the journal. can change over time */
54 __u32 s_journal_max_batch; /* max number of blocks to batch into a trans */
55 __u32 s_journal_max_commit_age; /* in seconds, how old can an async commit be */
56 __u32 s_journal_max_trans_age; /* in seconds, how old can a transaction be */
57 __u16 s_blocksize; /* block size */
58 __u16 s_oid_maxsize; /* max size of object id array, see get_objectid() commentary */
59 __u16 s_oid_cursize; /* current size of object id array */
60 __u16 s_state; /* valid or error */
61 char s_magic[12]; /* reiserfs magic string indicates that file system is reiserfs */
62 __u32 s_hash_function_code; /* indicate, what hash fuction is being use to sort names in a directory*/
63 __u16 s_tree_height; /* height of disk tree */
64 __u16 s_bmap_nr; /* amount of bitmap blocks needed to address each block of file system */
65 __u16 s_reserved;
66 };
67
68 #define SB_V35_SIZE (sizeof(struct reiserfs_super_block_v35))
69
70 struct reiserfs_super_block_v36 {
71 struct reiserfs_super_block_v35 s_v35;
72 __u32 s_inode_generation;
73 __u32 s_flags;
74 char s_uuid[16];
75 char s_label[16];
76 char s_unused[88];
77 };
78
79 #define SB_V36_SIZE (sizeof(struct reiserfs_super_block_v36))
80
81 #endif /* _GM_REISERFS_H */
0 /*
1 * gm_rfs.c -- gpart ReiserFS guessing module
2 *
3 * gpart (c) 1999-2001 Michail Brzitwa <mb@ichabod.han.de>
4 * Guess PC-type hard disk partitions.
5 *
6 * gpart is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published
8 * by the Free Software Foundation; either version 2, or (at your
9 * option) any later version.
10 *
11 * Created: 21.01.1999 <mb@ichabod.han.de>
12 * Modified: 26.12.2000 Francis Devereux <francis@devereux.tc>
13 * Added reiserfs 3.5.28 support.
14 *
15 */
16
17 #include <string.h>
18 #include <errno.h>
19 #include "gpart.h"
20 #include "gm_rfs.h"
21
22 static const char rcsid[] = "$Id: gm_rfs.c,v 1.5 2001/02/07 18:08:08 mb Exp mb $";
23
24
25 int rfs_init(disk_desc *d,g_module *m)
26 {
27 if ((d == 0) || (m == 0))
28 return (0);
29
30 m->m_desc = "Reiser filesystem";
31 return (REISERFS_FIRST_BLOCK * 1024 + SB_SIZE);
32 }
33
34
35
36 int rfs_term(disk_desc *d)
37 {
38 return (1);
39 }
40
41
42
43 int rfs_gfun(disk_desc *d,g_module *m)
44 {
45 struct reiserfs_super_block *sb;
46 dos_part_entry *pt = &m->m_part;
47 s64_t size;
48
49 m->m_guess = GM_NO;
50 sb = (struct reiserfs_super_block *)(d->d_sbuf + REISERFS_FIRST_BLOCK * 1024);
51 if (strncmp(sb->s_magic,REISERFS_SUPER_MAGIC,12) == 0)
52 {
53 /*
54 * sanity checks.
55 */
56
57 if (sb->s_block_count < sb->s_free_blocks)
58 return (1);
59
60 if (sb->s_block_count < REISERFS_MIN_BLOCK_AMOUNT)
61 return (1);
62
63 if ((sb->s_state != REISERFS_VALID_FS) &&
64 (sb->s_state != REISERFS_ERROR_FS))
65 return (1);
66
67 if (sb->s_oid_maxsize % 2) /* must be even */
68 return (1);
69
70 if (sb->s_oid_maxsize < sb->s_oid_cursize)
71 return (1);
72
73 if ((sb->s_blocksize != 4096) && (sb->s_blocksize != 8192))
74 return (1);
75
76 /*
77 * ok.
78 */
79
80 m->m_guess = GM_YES;
81 pt->p_start = d->d_nsb;
82 size = sb->s_block_count; size *= sb->s_blocksize; size /= d->d_ssize;
83 pt->p_size = (unsigned long)size;
84 pt->p_typ = 0x83;
85 }
86 return (1);
87 }
0 /*
1 * gm_rfs.h -- gpart ReiserFS guessing module header
2 *
3 * gpart (c) 1999-2001 Michail Brzitwa <mb@ichabod.han.de>
4 * Guess PC-type hard disk partitions.
5 *
6 * gpart is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published
8 * by the Free Software Foundation; either version 2, or (at your
9 * option) any later version.
10 *
11 * Created: 21.01.1999 <mb@ichabod.han.de>
12 * Modified: 26.12.2000 Francis Devereux <francis@devereux.tc>
13 * Update support reiserfs version 3.5.28
14 *
15 */
16
17 #ifndef _GM_RFS_H
18 #define _GM_RFS_H
19
20 /* imported from asm/types.h */
21 typedef __signed__ char __s8;
22 typedef unsigned char __u8;
23
24 typedef __signed__ short __s16;
25 typedef unsigned short __u16;
26
27 typedef __signed__ int __s32;
28 typedef unsigned int __u32;
29
30 /*
31 * taken from ReiserFS v3.5.28. Reiserfs Copyright 1996-2000 Hans Reiser
32 */
33
34 #define REISERFS_SUPER_MAGIC "ReIsErFs"
35 #define REISERFS_FIRST_BLOCK 64
36 #define REISERFS_VALID_FS 1
37 #define REISERFS_ERROR_FS 2
38 #define REISERFS_MIN_BLOCK_AMOUNT 100
39
40 struct reiserfs_super_block
41 {
42 __u32 s_block_count; /* blocks count */
43 __u32 s_free_blocks; /* free blocks count */
44 __u32 s_root_block; /* root block number */
45 __u32 s_journal_block; /* journal block number */
46 __u32 s_journal_dev; /* journal device number */
47 __u32 s_orig_journal_size; /* size of the journal on FS creation. used to make sure they don't overflow it */
48 __u32 s_journal_trans_max; /* max number of blocks in a transaction. */
49 __u32 s_journal_block_count; /* total size of the journal. can change over time */
50 __u32 s_journal_max_batch; /* max number of blocks to batch into a trans */
51 __u32 s_journal_max_commit_age; /* in seconds, how old can an async commit be */
52 __u32 s_journal_max_trans_age; /* in seconds, how old can a transaction be */
53 __u16 s_blocksize; /* block size */
54 __u16 s_oid_maxsize; /* max size of object id array, see get_objectid() commentary */
55 __u16 s_oid_cursize; /* current size of object id array */
56 __u16 s_state; /* valid or error */
57 char s_magic[12]; /* reiserfs magic string indicates that file system is reiserfs */
58 __u32 s_hash_function_code; /* indicate, what hash fuction is being use to sort names in a directory*/
59 __u16 s_tree_height; /* height of disk tree */
60 __u16 s_bmap_nr; /* amount of bitmap blocks needed to address each block of file system */
61 __u16 s_reserved;
62 };
63
64 #define SB_SIZE (sizeof(struct reiserfs_super_block))
65
66
67 #endif /* _GM_RFS_H */
1717 #include <stdio.h>
1818 #include <stdlib.h>
1919 #include <string.h>
20 #include <dlfcn.h>
2021 #include "gpart.h"
2122
2223
5556 {
5657 if (m)
5758 {
59 if (m->m_hd) dlclose(m->m_hd);
5860 if (m->m_name) free((void *)m->m_name);
5961 free(m);
6062 g_count--;
129131 return (m);
130132 }
131133
134
135
132136 /*
133137 * preloaded modules
134138 */
137141 {
138142 g_module *m;
139143
140 #define GMODINS(mod) \
141 do { \
142 m = g_mod_lookup(GM_INSERT,#mod); \
143 if (m) { \
144 m->m_init=mod##_init; \
145 m->m_term=mod##_term; \
146 m->m_gfun=mod##_gfun; \
147 } \
148 } while (0);
144 #define GMODINS(mod) if(!(m = g_mod_lookup(GM_INSERT,#mod))->m_hd){ \
145 m->m_init=mod##_init; m->m_term=mod##_term; \
146 m->m_gfun=mod##_gfun; }
149147
150148 /*
151149 * If no weights are given on the command line, the order
152150 * is somehow important.
153151 */
154152
155 #define G_MODULE(mod) GMODINS(mod)
156 G_MODULES
157 #undef G_MODULE
158 }
153 GMODINS(bsddl);
154 GMODINS(lswap);
155 GMODINS(qnx4);
156 GMODINS(rfs);
157 GMODINS(ntfs);
158 GMODINS(hpfs);
159 GMODINS(minix);
160 GMODINS(beos);
161 GMODINS(ext2);
162 GMODINS(fat);
163 GMODINS(s86dl);
164 GMODINS(hmlvm);
165 GMODINS(xfs);
166 }
167
168
169
170 int g_mod_addexternal(char *name)
171 {
172 g_module *m;
173 char buf[FILENAME_MAX];
174
175 /*
176 * external modules are named 'gm_' name '.so', and will
177 * be searched in the standard ld.so library directories
178 * or those explicitly given by LD_LIBRARY_PATH.
179 */
180
181 snprintf(buf,FILENAME_MAX-1,"gm_%s.so",name);
182 buf[FILENAME_MAX-1] = 0;
183
184 m = g_mod_lookup(GM_INSERT,name);
185 if (m->m_hd)
186 dlclose(m->m_hd);
187
188 if ((m->m_hd = dlopen(buf,RTLD_NOW)) == 0)
189 pr(FATAL,(char *)dlerror());
190
191 snprintf(buf,FILENAME_MAX-1,"%s_init",name);
192 m->m_init = (int (*)())dlsym(m->m_hd,buf);
193 snprintf(buf,FILENAME_MAX-1,"%s_term",name);
194 m->m_term = (int (*)())dlsym(m->m_hd,buf);
195 snprintf(buf,FILENAME_MAX-1,"%s_gfun",name);
196 m->m_gfun = (int (*)())dlsym(m->m_hd,buf);
197 if ((m->m_gfun == 0))
198 pr(FATAL,"module %s: missing vital functions",name);
199
200 return (1);
201 }
3232 int (*m_gfun)(disk_desc *,struct g_mod *);
3333 float m_guess;
3434 float m_weight; /* probability weight */
35 void *m_hd; /* dlopen() descriptor */
3536 dos_part_entry m_part; /* a guessed partition entry */
3637 long m_align; /* alignment of partition */
3738 struct g_mod *m_next;
4647 void g_mod_list(), g_mod_delete(g_module *), g_mod_deleteall();
4748 g_module *g_mod_head(), *g_mod_lookup(int,char *);
4849 void g_mod_addinternals();
49 int g_mod_count();
50 int g_mod_count(), g_mod_addexternal(char *);
5051 g_module *g_mod_setweight(char *,float);
5152
5253
5354
5455 /*
55 * preloaded guessing modules, order is important as it is also the order of registering and guessing
56 * preloaded guessing modules
5657 */
5758
58 #define G_MODULES \
59 G_MODULE(bsddl) \
60 G_MODULE(lswap) \
61 G_MODULE(qnx4) \
62 G_MODULE(reiserfs) \
63 G_MODULE(ntfs) \
64 G_MODULE(hpfs) \
65 G_MODULE(minix) \
66 G_MODULE(beos) \
67 G_MODULE(ext2) \
68 G_MODULE(fat) \
69 G_MODULE(s86dl) \
70 G_MODULE(hmlvm) \
71 G_MODULE(xfs)
59 #define GMODDECL(mod) int mod##_init(disk_desc *,g_module *), \
60 mod##_term(disk_desc *), \
61 mod##_gfun(disk_desc *,g_module *)
7262
73 #define G_MODULE(mod) int mod##_init(disk_desc *,g_module *), \
74 mod##_term(disk_desc *), \
75 mod##_gfun(disk_desc *,g_module *);
76 G_MODULES
77 #undef G_MODULE
63 GMODDECL(bsddl); GMODDECL(ext2); GMODDECL(fat);
64 GMODDECL(hpfs); GMODDECL(lswap); GMODDECL(ntfs);
65 GMODDECL(s86dl); GMODDECL(minix); GMODDECL(rfs);
66 GMODDECL(hmlvm); GMODDECL(qnx4); GMODDECL(beos);
67 GMODDECL(xfs);
68
7869
7970 #endif /* _GMODULES_H */
5959
6060
6161 static const char rcsid[] = "$Id: gpart.c,v 1.11 2001/02/07 18:08:08 mb Exp mb $";
62 static const char *gpart_version = PACKAGE_NAME " v" VERSION;
62 static const char *gpart_version = PROGRAM " v" VERSION;
6363
6464
6565 int f_check = 0, f_verbose = 0, f_dontguess = 0, f_fast = 1;
6666 int f_getgeom = 1, f_interactive = 0, f_quiet = 0, f_testext = 1;
6767 int f_skiperrors = 1, berrno = 0;
6868 int (*boundary_fun)(disk_desc *,s64_t);
69 unsigned long increment = 's', gc = 0, gh = 0, gs = 0;
69 unsigned long increment = 'h', gc = 0, gh = 0, gs = 0;
7070 s64_t skipsec = 0, maxsec = 0;
71 FILE *logfile = 0;
71 FILE *log = 0;
7272
7373
7474
7676 {
7777 FILE *fp = stderr;
7878
79 fprintf(fp,"Usage: %s [options] device\n",PACKAGE_NAME);
79 fprintf(fp,"Usage: %s [options] device\n",PROGRAM);
8080 fprintf(fp,"Options: [-b <backup MBR>][-C c,h,s][-c][-d][-E][-e][-f][-g][-h][-i]\n");
8181 fprintf(fp," [-K <last sector>][-k <# of sectors>][-L][-l <log file>]\n");
82 fprintf(fp," [-n <increment>][-q][-s <sector-size>]\n");
82 fprintf(fp," [-n <increment>][-q][-s <sector-size>][-t <module-name>]\n");
8383 fprintf(fp," [-V][-v][-W <device>][-w <module-name,weight>]\n");
8484 fprintf(fp,"%s (c) 1999-2001 Michail Brzitwa <michail@brzitwa.de>.\n",gpart_version);
8585 fprintf(fp,"Guess PC-type hard disk partitions.\n\n");
86 if (! f_verbose)
87 return;
8688 fprintf(fp,"Options:\n");
8789 fprintf(fp," -b Save a backup of the original MBR to specified file.\n");
8890 fprintf(fp," -C Set c/h/s to be used in the scan.\n");
101103 fprintf(fp," -n Scan increment: number or 's' sector, 'h' head, 'c' cylinder.\n");
102104 fprintf(fp," -q Run quiet (however log file is written if specified).\n");
103105 fprintf(fp," -s Sector size to use (disable sector size probing).\n");
106 fprintf(fp," -t Name of a guessing module to be added.\n");
104107 fprintf(fp," -V Show version.\n");
105108 fprintf(fp," -v Verbose mode. Can be given more than once.\n");
106109 fprintf(fp," -W Write guessed primary partition table to given device or file.\n");
121124 case FATAL :
122125 g_mod_deleteall();
123126 if (! f_quiet) fprintf(stderr,EM_FATALERROR,msg);
124 if (logfile)
125 {
126 fprintf(logfile,EM_FATALERROR,msg);
127 fclose(logfile);
127 if (log)
128 {
129 fprintf(log,EM_FATALERROR,msg);
130 fclose(log);
128131 }
129132 exit(1);
130133 case ERROR :
131134 if (! f_quiet) fprintf(stderr,EM_SIMPLEERROR,msg);
132 if (logfile) fprintf(logfile,EM_SIMPLEERROR,msg);
135 if (log) fprintf(log,EM_SIMPLEERROR,msg);
133136 break;
134137 case WARN :
135138 if (! f_quiet) fprintf(stderr,EM_WARNING,msg);
136 if (logfile) fprintf(logfile,EM_WARNING,msg);
139 if (log) fprintf(log,EM_WARNING,msg);
137140 break;
138141 case MSG :
139142 if (! f_quiet) fputs(msg,stdout); fflush(stdout);
140 if (logfile) fputs(msg,logfile);
143 if (log) fputs(msg,log);
141144 break;
142145 }
143 if (logfile) fflush(logfile);
146 if (log) fflush(log);
144147 }
145148
146149
370373 dos_part_entry *t;
371374 int ne = 0;
372375
373 for (t = &p[0]; t <= &p[NDOSPARTS - 1]; t++)
376 for (t = &p[0]; t < &p[NDOSPARTS]; t++)
374377 if (is_ext_parttype(t))
375378 ne++;
376379 return (ne);
383386 dos_part_entry *t;
384387 int nr = 0;
385388
386 for (t = &p[0]; t <= &p[NDOSPARTS - 1]; t++)
389 for (t = &p[0]; t < &p[NDOSPARTS]; t++)
387390 if (is_real_parttype(t))
388391 nr++;
389392 return (nr);
453456 * ptbl sanity checks.
454457 */
455458
456 for (t = p; t <= &p[NDOSPARTS - 1]; t++)
459 for (t = p; t < &p[NDOSPARTS]; t++)
457460 if (! is_sane_partentry(d,t,0))
458461 return (0);
459462
598601 for ( ; pt; pt = pt->t_ext)
599602 {
600603 pr(MSG,PM_EXTPART);
601 for (p = pt->t_parts; p <= &pt->t_parts[NDOSPARTS - 1]; p++)
604 for (p = pt->t_parts; p < &pt->t_parts[NDOSPARTS + 1]; p++)
602605 if (is_real_parttype(p))
603606 print_partition(d,p,1,offset + extst);
604607
605 for (p = pt->t_parts; p <= &pt->t_parts[NDOSPARTS - 1]; p++)
608 for (p = pt->t_parts; p < &pt->t_parts[NDOSPARTS + 1]; p++)
606609 if (is_ext_parttype(p))
607610 extst = p->p_start;
608611 }
702705 while (1)
703706 {
704707 ep = 0;
705 for (p = pt->t_parts; p <= &pt->t_parts[NDOSPARTS - 1]; p++)
708 for (p = pt->t_parts; p < &pt->t_parts[NDOSPARTS + 1]; p++)
706709 if (is_ext_parttype(p))
707710 {
708711 if (ep == 0)
829832 pr(FATAL,EM_CANTGETGEOM);
830833 memcpy(&d->d_dg,dg,sizeof(struct disk_geom));
831834
832 d->d_nsecs = dg->d_nsecs;
833
834835 /*
835836 * command line geometry overrides
836837 */
847848 }
848849 if (d->d_dg.d_c < 1024) d->d_dosc = 1;
849850 if ((d->d_dg.d_h > 16) || (d->d_dg.d_s > 63)) d->d_lba = 1;
850
851 if (gh && gc && gs) {
852 /* Override number of sectors with command line parameters */
853 d->d_nsecs = d->d_dg.d_c;
854 d->d_nsecs *= d->d_dg.d_h;
855 d->d_nsecs *= d->d_dg.d_s;
856 }
857
851 d->d_nsecs = d->d_dg.d_c;
852 d->d_nsecs *= d->d_dg.d_h;
853 d->d_nsecs *= d->d_dg.d_s;
858854 read_ext_part_table(d,&d->d_pt);
859855 close(d->d_fd);
860856 free((void *)ubuf);
12241220 {
12251221 int fd, ret = 0;
12261222
1227 if ((fd = open(bfile, O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) < 0)
1223 if ((fd = open(bfile,O_WRONLY|O_CREAT)) < 0)
12281224 return (ret);
12291225
12301226 if (write(fd,d->d_pt.t_boot,512) == 512)
14331429 if (no_of_ext_partitions(gp->g_p) == 0)
14341430 in_ext = 0;
14351431 rp = 0;
1436 for (p = &gp->g_p[0]; p <= &gp->g_p[NDOSPARTS - 1]; p++)
1432 for (p = &gp->g_p[0]; p < &gp->g_p[NDOSPARTS]; p++)
14371433 {
14381434 if (is_real_parttype(p))
14391435 rp = p;
15341530 in_ext = 1; ofs = gp->g_sec;
15351531 }
15361532 rp = ep = 0;
1537 for (p = &gp->g_p[0]; p <= &gp->g_p[NDOSPARTS - 1]; p++)
1533 for (p = &gp->g_p[0]; p < &gp->g_p[NDOSPARTS]; p++)
15381534 {
15391535 if (is_real_parttype(p))
15401536 rp = p;
17531749 }
17541750 break;
17551751 case 'l' :
1756 if (logfile) fclose(logfile);
1757 if ((logfile = fopen(optarg,"w")) == 0)
1752 if (log) fclose(log);
1753 if ((log = fopen(optarg,"w")) == 0)
17581754 pr(FATAL,EM_OPENLOG,optarg);
17591755 break;
17601756 case 'L' :
17651761 case 's' :
17661762 if ((sectsize = atoi(optarg)) <= 0)
17671763 pr(FATAL,"sector size must be >= 0");
1764 break;
1765 case 't' :
1766 if (! g_mod_addexternal(optarg))
1767 return (EXIT_FAILURE);
17681768 break;
17691769 case 'v' :
17701770 f_verbose++; break;
18301830 }
18311831 }
18321832 free_disk_desc(d);
1833 if (logfile) fclose(logfile);
1833 if (log) fclose(log);
18341834
18351835 return (f_check ? no_of_incons : 0);
18361836 }
1616 #ifndef _GPART_H
1717 #define _GPART_H
1818
19 #include "config.h"
20
2119 #include "errmsgs.h"
2220 #include "l64seek.h"
2321
24 #include <stdint.h>
22 #define PROGRAM "gpart"
2523
26 typedef uint8_t byte_t;
24
25 typedef unsigned char byte_t;
2726
2827
2928
30 #define le16(x) htole16(x)
31 #define be16(x) htobe16(x)
32 #define le32(x) htole32(x)
33 #define be32(x) htobe32(x)
34 #define le64(x) htole64(x)
35 #define be64(x) htobe64(x)
29 /*
30 * endianness (incomplete, later)
31 */
32
33 #if defined(__i386__) || defined(__alpha__)
34 # define le16(x) (x) /* x as little endian */
35 # define be16(x) ((((x)&0xff00)>>8) | \
36 (((x)&0x00ff)<<8))
37 # define le32(x) (x)
38 # define be32(x) ((((x)&0xff000000L)>>24) | \
39 (((x)&0x00ff0000L)>>8) | \
40 (((x)&0x0000ff00L)<<8) | \
41 (((x)&0x000000ffL)<<24))
42 # define le64(x) (x)
43 # define be64(x) ((((x)&0xff00000000000000LL)>>56) | \
44 (((x)&0x00ff000000000000LL)>>40) | \
45 (((x)&0x0000ff0000000000LL)>>24) | \
46 (((x)&0x000000ff00000000LL)>>8) | \
47 (((x)&0x00000000ff000000LL)<<8) | \
48 (((x)&0x0000000000ff0000LL)<<24) | \
49 (((x)&0x000000000000ff00LL)<<40) | \
50 (((x)&0x00000000000000ffLL)<<56))
51 #else /* bigendian */
52 # define le16(x) ((((x)&0xff00)>>8) | \
53 (((x)&0x00ff)<<8))
54 # define be16(x) (x)
55 # define le32(x) ((((x)&0xff000000L)>>24) | \
56 (((x)&0x00ff0000L)>>8) | \
57 (((x)&0x0000ff00L)<<8) | \
58 (((x)&0x000000ffL)<<24))
59 # define be32(x) (x)
60 # define le64(x) ((((x)&0xff00000000000000LL)>>56) | \
61 (((x)&0x00ff000000000000LL)>>40) | \
62 (((x)&0x0000ff0000000000LL)>>24) | \
63 (((x)&0x000000ff00000000LL)>>8) | \
64 (((x)&0x00000000ff000000LL)<<8) | \
65 (((x)&0x0000000000ff0000LL)<<24) | \
66 (((x)&0x000000000000ff00LL)<<40) | \
67 (((x)&0x00000000000000ffLL)<<56))
68 # define be64(x) (x)
69 #endif
3670
3771
3872 #ifndef max
77111 byte_t p_ehd; /* end head */
78112 byte_t p_esect; /* end sector */
79113 byte_t p_ecyl; /* end cylinder */
80 uint32_t p_start; /* start sector (absolute) */
81 uint32_t p_size; /* # of sectors */
114 unsigned long p_start; /* start sector (absolute) */
115 unsigned long p_size; /* # of sectors */
82116 } dos_part_entry;
83117
84118
88122 byte_t _align[2];
89123 byte_t t_boot[DOSPARTOFF];
90124 dos_part_entry t_parts[NDOSPARTS];
91 uint16_t t_magic; /* DOSPTMAGIC */
125 unsigned short t_magic; /* DOSPTMAGIC */
92126 } dos_part_table;
93127
94128
121155 long d_c; /* cylinder count */
122156 long d_h; /* heads/cyl */
123157 long d_s; /* sectors/head */
124 uint64_t d_nsecs; /* Number of sectors total */
158 long d_rc; /* real values if the above are */
159 long d_rh; /* translated */
160 long d_rs;
125161 } d_dg;
126162 unsigned int d_lba : 1;
127163 unsigned int d_dosc : 1; /* dos compatible? (g_c < 1024) */
2424 } ostck[OSTACKLEN];
2525 static int osptr = -1;
2626
27 #if defined(__linux__) && defined(__i386__)
28 _syscall5(int,_llseek,uint,fd,ulong,hi,ulong,lo,loff_t *,res,uint,wh)
29 #endif
30
2731
2832
2933 off64_t l64seek(int fd,off64_t offset,int whence)
3034 {
3135 off64_t ret = (off64_t)-1;
3236
37 #if defined(__linux__) && defined(__i386__)
38 int iret;
39 unsigned long ohi, olo;
40
41 ohi = (unsigned long)((offset >> 32) & 0xFFFFFFFF);
42 olo = (unsigned long)(offset & 0xFFFFFFFF);
43 iret = _llseek(fd,ohi,olo,&ret,whence);
44 if (iret == -1)
45 ret = (off64_t)-1;
46 #endif
47
48 #if defined(__FreeBSD__) || (defined(__linux__) && defined(__alpha__))
3349 ret = lseek(fd,offset,whence);
50 #endif
3451
3552 return (ret);
3653 }
1616 #ifndef _L64SEEK_H
1717 #define _L64SEEK_H
1818
19 #include <sys/stat.h>
20 #include <sys/types.h>
2119 #include <unistd.h>
2220
2321 /*
2624 * offsets.
2725 */
2826
29 typedef loff_t off64_t;
27
28 #if defined(__linux__)
29 # include <linux/unistd.h>
30 # include <sys/types.h>
31 typedef int64_t off64_t;
32 #endif
33
34
35 #if defined(__FreeBSD__)
36 typedef off_t off64_t;
37 #endif
38
39
3040 typedef off64_t s64_t;
3141
3242 off64_t l64seek(int fd, off64_t offset, int whence);
3444 int l64opush(int);
3545 s64_t l64opop(int);
3646
47
3748 #endif