Changeset 1765 in MondoRescue for branches/2.2.5/mindi-busybox/util-linux


Ignore:
Timestamp:
Nov 4, 2007, 3:16:40 AM (13 years ago)
Author:
Bruno Cornec
Message:

Update to busybox 1.7.2

Location:
branches/2.2.5/mindi-busybox/util-linux
Files:
6 added
4 deleted
25 edited

Legend:

Unmodified
Added
Removed
  • branches/2.2.5/mindi-busybox/util-linux/Config.in

    r821 r1765  
    66menu "Linux System Utilities"
    77
    8 config CONFIG_DMESG
     8config DMESG
    99    bool "dmesg"
    1010    default n
     
    1818      wish to enable the 'dmesg' utility.
    1919
    20 config CONFIG_FBSET
     20config FEATURE_DMESG_PRETTY
     21    bool "pretty dmesg output"
     22    default y
     23    depends on DMESG
     24    help
     25      If you wish to scrub the syslog level from the output, say 'Y' here.
     26      The syslog level is a string prefixed to every line with the form "<#>".
     27
     28      With this option you will see:
     29        # dmesg
     30        Linux version 2.6.17.4 .....
     31        BIOS-provided physical RAM map:
     32         BIOS-e820: 0000000000000000 - 000000000009f000 (usable)
     33
     34      Without this option you will see:
     35        # dmesg
     36        <5>Linux version 2.6.17.4 .....
     37        <6>BIOS-provided physical RAM map:
     38        <6> BIOS-e820: 0000000000000000 - 000000000009f000 (usable)
     39
     40config FBSET
    2141    bool "fbset"
    2242    default n
     
    2747      if you wish to enable the 'fbset' utility.
    2848
    29 config CONFIG_FEATURE_FBSET_FANCY
     49config FEATURE_FBSET_FANCY
    3050    bool "Turn on extra fbset options"
    3151    default n
    32     depends on CONFIG_FBSET
     52    depends on FBSET
    3353    help
    3454      This option enables extended fbset options, allowing one to set the
     
    3757      options.
    3858
    39 config CONFIG_FEATURE_FBSET_READMODE
     59config FEATURE_FBSET_READMODE
    4060    bool "Turn on fbset readmode support"
    4161    default n
    42     depends on CONFIG_FBSET
     62    depends on FBSET
    4363    help
    4464      This option allows fbset to read the video mode database stored by
     
    4666      device to pre-defined video modes.
    4767
    48 config CONFIG_FDFLUSH
     68config FDFLUSH
    4969    bool "fdflush"
    5070    default n
     
    5878      leave this disabled.
    5979
    60 config CONFIG_FDFORMAT
     80config FDFORMAT
    6181    bool "fdformat"
    6282    default n
     
    6484      fdformat is used to low-level format a floppy disk.
    6585
    66 config CONFIG_FDISK
     86config FDISK
    6787    bool "fdisk"
    6888    default n
     
    7696    bool "support over 4GB disks"
    7797    default y
    78     depends on CONFIG_FDISK
     98    depends on FDISK
    7999    help
    80100      Enable this option to support large disks > 4GB.
    81101
    82 config CONFIG_FEATURE_FDISK_WRITABLE
     102config FEATURE_FDISK_WRITABLE
    83103    bool "Write support"
    84104    default y
    85     depends on CONFIG_FDISK
     105    depends on FDISK
    86106    help
    87107      Enabling this option allows you to create or change a partition table
     
    89109      disabled, you will only be able to view the partition table.
    90110
    91 config CONFIG_FEATURE_AIX_LABEL
     111config FEATURE_AIX_LABEL
    92112    bool "Support AIX disklabels"
    93113    default n
    94     depends on CONFIG_FDISK && CONFIG_FEATURE_FDISK_WRITABLE
     114    depends on FDISK && FEATURE_FDISK_WRITABLE
    95115    help
    96116      Enabling this option allows you to create or change AIX disklabels.
    97117      Most people can safely leave this option disabled.
    98118
    99 config CONFIG_FEATURE_SGI_LABEL
     119config FEATURE_SGI_LABEL
    100120    bool "Support SGI disklabels"
    101121    default n
    102     depends on CONFIG_FDISK && CONFIG_FEATURE_FDISK_WRITABLE
     122    depends on FDISK && FEATURE_FDISK_WRITABLE
    103123    help
    104124      Enabling this option allows you to create or change SGI disklabels.
    105125      Most people can safely leave this option disabled.
    106126
    107 config CONFIG_FEATURE_SUN_LABEL
     127config FEATURE_SUN_LABEL
    108128    bool "Support SUN disklabels"
    109129    default n
    110     depends on CONFIG_FDISK && CONFIG_FEATURE_FDISK_WRITABLE
     130    depends on FDISK && FEATURE_FDISK_WRITABLE
    111131    help
    112132      Enabling this option allows you to create or change SUN disklabels.
    113133      Most people can safely leave this option disabled.
    114134
    115 config CONFIG_FEATURE_OSF_LABEL
     135config FEATURE_OSF_LABEL
    116136    bool "Support BSD disklabels"
    117137    default n
    118     depends on CONFIG_FDISK && CONFIG_FEATURE_FDISK_WRITABLE
     138    depends on FDISK && FEATURE_FDISK_WRITABLE
    119139    help
    120140      Enabling this option allows you to create or change BSD disklabels
    121141      and define and edit BSD disk slices.
    122142
    123 config CONFIG_FEATURE_FDISK_ADVANCED
     143config FEATURE_FDISK_ADVANCED
    124144    bool "Support expert mode"
    125145    default n
    126     depends on CONFIG_FDISK && CONFIG_FEATURE_FDISK_WRITABLE
     146    depends on FDISK && FEATURE_FDISK_WRITABLE
    127147    help
    128148      Enabling this option allows you to do terribly unsafe things like
     
    131151      reason you would be wise to leave this disabled.
    132152
    133 config CONFIG_FREERAMDISK
     153config FREERAMDISK
    134154    bool "freeramdisk"
    135155    default n
     
    142162      this disabled.
    143163
    144 config CONFIG_FSCK_MINIX
     164config FSCK_MINIX
    145165    bool "fsck_minix"
    146166    default n
     
    153173      filesystem.
    154174
    155 config CONFIG_MKFS_MINIX
     175config MKFS_MINIX
    156176    bool "mkfs_minix"
    157177    default n
     
    162182
    163183comment "Minix filesystem support"
    164     depends on CONFIG_FSCK_MINIX || CONFIG_MKFS_MINIX
    165 
    166 config CONFIG_FEATURE_MINIX2
     184    depends on FSCK_MINIX || MKFS_MINIX
     185
     186config FEATURE_MINIX2
    167187    bool "Support Minix fs v2 (fsck_minix/mkfs_minix)"
    168188    default y
    169     depends on CONFIG_FSCK_MINIX || CONFIG_MKFS_MINIX
     189    depends on FSCK_MINIX || MKFS_MINIX
    170190    help
    171191      If you wish to be able to create version 2 minix filesystems, enable this.
     
    173193      version 2 filesystem support.
    174194
    175 config CONFIG_GETOPT
     195config GETOPT
    176196    bool "getopt"
    177197    default n
     
    184204      wisely leave this disabled.
    185205
    186 config CONFIG_HEXDUMP
     206config HEXDUMP
    187207    bool "hexdump"
    188208    default n
     
    191211      way that is comparable to the output from most hex editors.
    192212
    193 config CONFIG_HWCLOCK
     213config HWCLOCK
    194214    bool "hwclock"
    195215    default n
     
    200220      correct time when Linux is _not_ running.
    201221
    202 config CONFIG_FEATURE_HWCLOCK_LONG_OPTIONS
     222config FEATURE_HWCLOCK_LONG_OPTIONS
    203223    bool "Support long options (--hctosys,...)"
    204224    default n
    205     depends on CONFIG_HWCLOCK && CONFIG_GETOPT_LONG
     225    depends on HWCLOCK && GETOPT_LONG
    206226    help
    207227      By default, the hwclock utility only uses short options.  If you
     
    209229      then enable this option.
    210230
    211 config CONFIG_FEATURE_HWCLOCK_ADJTIME_FHS
     231config FEATURE_HWCLOCK_ADJTIME_FHS
    212232    bool "Use FHS /var/lib/hwclock/adjtime"
    213233    default y
    214     depends on CONFIG_HWCLOCK
     234    depends on HWCLOCK
    215235    help
    216236      Starting with FHS 2.3, the adjtime state file is supposed to exist
     
    221241      http://www.pathname.com/fhs/pub/fhs-2.3.html#VARLIBHWCLOCKSTATEDIRECTORYFORHWCLO
    222242
    223 config CONFIG_IPCRM
     243config IPCRM
    224244    bool "ipcrm"
    225245    default n
    226     select CONFIG_FEATURE_SUID
     246    select FEATURE_SUID
    227247    help
    228248      The ipcrm utility allows the removal of System V interprocess
     
    230250      from the system.
    231251
    232 config CONFIG_IPCS
     252config IPCS
    233253    bool "ipcs"
    234254    default n
    235     select CONFIG_FEATURE_SUID
     255    select FEATURE_SUID
    236256    help
    237257      The ipcs utility is used to provide information on the currently
    238258      allocated System V interprocess (IPC) objects in the system.
    239259
    240 config CONFIG_LOSETUP
     260config LOSETUP
    241261    bool "losetup"
    242262    default n
     
    246266      version does not currently support enabling data encryption.
    247267
    248 config CONFIG_MDEV
     268config MDEV
    249269    bool "mdev"
    250270    default n
    251271    help
    252       mdev is a mini-udev implementation: call it with -s to populate
    253       /dev from /sys, then "echo /sbin/mdev > /proc/sys/kernel/hotplug" to
    254       have it handle hotplug events afterwards.  Device names are taken
    255       from sysfs.
    256 
    257 config CONFIG_FEATURE_MDEV_CONF
     272      mdev is a mini-udev implementation for dynamically creating device
     273      nodes in the /dev directory.
     274
     275      For more information, please see docs/mdev.txt
     276
     277config FEATURE_MDEV_CONF
    258278    bool "Support /etc/mdev.conf"
    259279    default n
    260     depends on CONFIG_MDEV
    261     help
    262       The mdev config file contains lines that look like:
    263 
    264         hd[a-z][0-9]* 0:3 660
    265 
    266       That's device name (with regex match), uid:gid, and permissions.
    267 
    268       Config file parsing stops on the first matching line.  If no config
    269       entry is matched, devices are created with default 0:0 660.  (Make
    270       the last line match .* to override this.)
    271 
    272 config CONFIG_FEATURE_MDEV_EXEC
     280    depends on MDEV
     281    help
     282      Add support for the mdev config file to control ownership and
     283      permissions of the device nodes.
     284
     285      For more information, please see docs/mdev.txt
     286
     287config FEATURE_MDEV_EXEC
    273288    bool "Support command execution at device addition/removal"
    274289    default n
    275     depends on CONFIG_FEATURE_MDEV_CONF
    276     help
    277       This adds support for an optional field to /etc/mdev.conf, consisting
    278       of a special character and a command line to run after creating the
    279       corresponding device(s) and before removing, ala:
    280 
    281         hdc root:cdrom 660  *ln -s $MDEV cdrom
    282 
    283       The $MDEV environment variable is set to the name of the device.
    284 
    285       The special characters and their meanings are:
    286         @ Run after creating the device.
    287         $ Run before removing the device.
    288         * Run both after creating and before removing the device.
    289 
    290       Commands are executed via system() so you need /bin/sh, meaning you
    291       probably want to select a default shell in the Shells menu.
    292 
    293 config CONFIG_MKSWAP
     290    depends on FEATURE_MDEV_CONF
     291    help
     292      This adds support for an optional field to /etc/mdev.conf for
     293      executing commands when devices are created/removed.
     294
     295      For more information, please see docs/mdev.txt
     296
     297config FEATURE_MDEV_LOAD_FIRMWARE
     298    bool "Support loading of firmwares"
     299    default n
     300    depends on MDEV
     301    help
     302      Some devices need to load firmware before they can be usable.
     303
     304      These devices will request userspace look up the files in
     305      /lib/firmware/ and if it exists, send it to the kernel for
     306      loading into the hardware.
     307
     308config MKSWAP
    294309    bool "mkswap"
    295310    default n
     
    304319      the swap space using the 'swapon' utility.
    305320
    306 config CONFIG_FEATURE_MKSWAP_V0
     321config FEATURE_MKSWAP_V0
    307322    bool "version 0 support"
    308323    default n
    309     depends on CONFIG_MKSWAP
    310 #   depends on CONFIG_MKSWAP && CONFIG_DEPRECATED
     324    depends on MKSWAP
     325#   depends on MKSWAP && DEPRECATED
    311326    help
    312327      Enable support for the old v0 style.
     
    314329      only option.
    315330
    316 config CONFIG_MORE
     331config MORE
    317332    bool "more"
    318333    default n
     
    324339      any need to reading text files, you can leave this disabled.
    325340
    326 config CONFIG_FEATURE_USE_TERMIOS
     341config FEATURE_USE_TERMIOS
    327342    bool "Use termios to manipulate the screen"
    328343    default y
    329     depends on CONFIG_MORE
     344    depends on MORE
    330345    help
    331346      This option allows utilities such as 'more' and 'top' to determine
     
    335350      unable to move the cursor.
    336351
    337 config CONFIG_MOUNT
     352config MOUNT
    338353    bool "mount"
    339354    default n
     
    346361      the 'mount' utility.
    347362
    348 config CONFIG_FEATURE_MOUNT_NFS
     363config FEATURE_MOUNT_NFS
    349364    bool "Support mounting NFS file systems"
    350365    default n
    351     depends on CONFIG_MOUNT
    352     help
    353      Enable mounting of NFS file systems.
    354 
    355 config CONFIG_PIVOT_ROOT
     366    depends on MOUNT
     367    select FEATURE_HAVE_RPC
     368    select FEATURE_SYSLOG
     369    help
     370      Enable mounting of NFS file systems.
     371
     372config FEATURE_MOUNT_CIFS
     373    bool "Support mounting CIFS/SMB file systems"
     374    default n
     375    depends on MOUNT
     376    help
     377      Enable support for samba mounts.
     378
     379config FEATURE_MOUNT_FLAGS
     380    depends on MOUNT
     381    bool "Support lots of -o flags in mount"
     382    default y
     383    help
     384      Without this, mount only supports ro/rw/remount.  With this, it
     385      supports nosuid, suid, dev, nodev, exec, noexec, sync, async, atime,
     386      noatime, diratime, nodiratime, loud, bind, move, shared, slave,
     387      private, unbindable, rshared, rslave, rprivate, and runbindable.
     388
     389config FEATURE_MOUNT_FSTAB
     390    depends on MOUNT
     391    bool "Support /etc/fstab and -a"
     392    default y
     393    help
     394      Support mount all and looking for files in /etc/fstab.
     395
     396config PIVOT_ROOT
    356397    bool "pivot_root"
    357398    default n
     
    365406      in linux 2.6) use switch_root instead.
    366407
    367 config CONFIG_RDATE
     408config RDATE
    368409    bool "rdate"
    369410    default n
     
    374415      systems.
    375416
    376 config CONFIG_READPROFILE
     417config READPROFILE
    377418    bool "readprofile"
    378419    default n
     
    380421      This allows you to parse /proc/profile for basic profiling.
    381422
    382 config CONFIG_SETARCH
     423config SETARCH
    383424    bool "setarch"
    384425    default n
     
    389430      (like amd64/x86, ppc64/ppc, sparc64/sparc, etc...).
    390431
    391 config CONFIG_SWAPONOFF
     432config SWAPONOFF
    392433    bool "swaponoff"
    393434    default n
     
    400441      option disabled.
    401442
    402 config CONFIG_SWITCH_ROOT
     443config SWITCH_ROOT
    403444    bool "switch_root"
    404445    default n
     
    419460      list of active mount points.  That's why.
    420461
    421 config CONFIG_UMOUNT
     462config UMOUNT
    422463    bool "umount"
    423464    default n
     
    428469      also want to enable 'umount'.
    429470
    430 config CONFIG_FEATURE_UMOUNT_ALL
     471config FEATURE_UMOUNT_ALL
    431472    bool "umount -a option"
    432473    default n
    433     depends on CONFIG_UMOUNT
     474    depends on UMOUNT
    434475    help
    435476      Support -a option to unmount all currently mounted filesystems.
    436477
    437478comment "Common options for mount/umount"
    438     depends on CONFIG_MOUNT || CONFIG_UMOUNT
    439 
    440 config CONFIG_FEATURE_MOUNT_LOOP
     479    depends on MOUNT || UMOUNT
     480
     481config FEATURE_MOUNT_LOOP
    441482    bool "Support loopback mounts"
    442483    default n
    443     depends on CONFIG_MOUNT || CONFIG_UMOUNT
     484    depends on MOUNT || UMOUNT
    444485    help
    445486      Enabling this feature allows automatic mounting of files (containing
     
    450491
    451492      You can still use the 'losetup' utility (to manually associate files
    452           with loop devices) if you need to do something advanced, such as
     493      with loop devices) if you need to do something advanced, such as
    453494      specify an offset or cryptographic options to the loopback device.
    454495      (If you don't want umount to free the loop device, use "umount -D".)
    455496
    456 config CONFIG_FEATURE_MTAB_SUPPORT
     497config FEATURE_MTAB_SUPPORT
    457498    bool "Support for the old /etc/mtab file"
    458499    default n
    459     depends on CONFIG_MOUNT || CONFIG_UMOUNT
     500    depends on MOUNT || UMOUNT
    460501    help
    461502      Historically, Unix systems kept track of the currently mounted
  • branches/2.2.5/mindi-busybox/util-linux/dmesg.c

    r821 r1765  
    1 /* vi: set ts=4:
    2  *
     1/* vi: set sw=4 ts=4: */
     2/*
     3 *
    34 * dmesg - display/control kernel ring buffer.
    45 *
    5  * Copyring 2006 Rob Landley <rob@landley.net>
     6 * Copyright 2006 Rob Landley <rob@landley.net>
     7 * Copyright 2006 Bernhard Fischer <rep.nop@aon.at>
    68 *
    7  * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
     9 * Licensed under GPLv2, see file LICENSE in this tarball for details.
    810 */
    911
    10 #include "busybox.h"
    11 #include <unistd.h>
    1212#include <sys/klog.h>
     13#include "libbb.h"
    1314
    14 int dmesg_main(int argc, char *argv[])
     15int dmesg_main(int argc, char **argv);
     16int dmesg_main(int argc, char **argv)
    1517{
    1618    char *size, *level;
    17     int flags = bb_getopt_ulflags(argc, argv, "cs:n:", &size, &level);
     19    int flags = getopt32(argv, "cs:n:", &size, &level);
    1820
    1921    if (flags & 4) {
    20         if(klogctl(8, NULL, bb_xgetlarg(level, 10, 0, 10)))
     22        if (klogctl(8, NULL, xatoul_range(level, 0, 10)))
    2123            bb_perror_msg_and_die("klogctl");
    2224    } else {
     
    2426        char *buf;
    2527
    26         len = (flags & 2) ? bb_xgetlarg(size, 10, 2, INT_MAX) : 16384;
     28        len = (flags & 2) ? xatoul_range(size, 2, INT_MAX) : 16384;
    2729        buf = xmalloc(len);
    2830        if (0 > (len = klogctl(3 + (flags & 1), buf, len)))
    2931            bb_perror_msg_and_die("klogctl");
    30         write(1,buf,len);
    31         if (len && buf[len-1]!='\n') putchar('\n');
     32
     33        // Skip <#> at the start of lines, and make sure we end with a newline.
     34
     35        if (ENABLE_FEATURE_DMESG_PRETTY) {
     36            int last = '\n';
     37            int in;
     38
     39            for (in = 0; in<len;) {
     40                if (last == '\n' && buf[in] == '<') in += 3;
     41                else putchar(last = buf[in++]);
     42            }
     43            if (last != '\n') putchar('\n');
     44        } else {
     45            write(1,buf,len);
     46            if (len && buf[len-1]!='\n') putchar('\n');
     47        }
     48
     49        if (ENABLE_FEATURE_CLEAN_UP) free(buf);
    3250    }
    3351
  • branches/2.2.5/mindi-busybox/util-linux/fbset.c

    r821 r1765  
    1313 */
    1414
    15 #include <stdio.h>
    16 #include <stdlib.h>
    17 #include <unistd.h>
    18 #include <fcntl.h>
    19 #include <errno.h>
    20 #include <ctype.h>
    21 #include <string.h>
    22 #include <stdint.h>
    23 #include <sys/ioctl.h>
    24 #include "busybox.h"
     15#include "libbb.h"
    2516
    2617#define DEFAULTFBDEV  FB_0
     
    3122    OPT_INFO     = (1 << 1),
    3223    OPT_READMODE = (1 << 2),
     24    OPT_ALL      = (1 << 9),
    3325
    3426    CMD_FB = 1,
     
    4638    CMD_CHANGE = 13,
    4739
    48 #ifdef CONFIG_FEATURE_FBSET_FANCY
     40#if ENABLE_FEATURE_FBSET_FANCY
    4941    CMD_XRES = 100,
    5042    CMD_YRES = 101,
     
    7062};
    7163
    72 static unsigned int g_options = 0;
     64static unsigned g_options;
    7365
    7466/* Stuff stolen from the kernel's fb.h */
     67#define FB_ACTIVATE_ALL 64
    7568enum {
    7669    FBIOGET_VSCREENINFO = 0x4600,
     
    7871};
    7972struct fb_bitfield {
    80     uint32_t offset;            /* beginning of bitfield    */
    81     uint32_t length;            /* length of bitfield       */
    82     uint32_t msb_right;     /* != 0 : Most significant bit is */
    83                     /* right */
     73    uint32_t offset;                /* beginning of bitfield */
     74    uint32_t length;        /* length of bitfield */
     75    uint32_t msb_right;             /* !=0: Most significant bit is right */
    8476};
    8577struct fb_var_screeninfo {
    86     uint32_t xres;          /* visible resolution       */
     78    uint32_t xres;                  /* visible resolution */
    8779    uint32_t yres;
    88     uint32_t xres_virtual;      /* virtual resolution       */
     80    uint32_t xres_virtual;          /* virtual resolution */
    8981    uint32_t yres_virtual;
    90     uint32_t xoffset;           /* offset from virtual to visible */
    91     uint32_t yoffset;           /* resolution           */
    92 
    93     uint32_t bits_per_pixel;        /* guess what           */
    94     uint32_t grayscale;     /* != 0 Graylevels instead of colors */
    95 
    96     struct fb_bitfield red;     /* bitfield in fb mem if true color, */
    97     struct fb_bitfield green;   /* else only length is significant */
     82    uint32_t xoffset;               /* offset from virtual to visible */
     83    uint32_t yoffset;               /* resolution */
     84
     85    uint32_t bits_per_pixel;
     86    uint32_t grayscale;             /* !=0 Graylevels instead of colors */
     87
     88    struct fb_bitfield red;         /* bitfield in fb mem if true color, */
     89    struct fb_bitfield green;       /* else only length is significant */
    9890    struct fb_bitfield blue;
    99     struct fb_bitfield transp;  /* transparency         */
    100 
    101     uint32_t nonstd;            /* != 0 Non standard pixel format */
    102 
    103     uint32_t activate;          /* see FB_ACTIVATE_*        */
    104 
    105     uint32_t height;            /* height of picture in mm    */
    106     uint32_t width;         /* width of picture in mm    */
     91    struct fb_bitfield transp;      /* transparency */
     92
     93    uint32_t nonstd;                /* !=0 Non standard pixel format */
     94
     95    uint32_t activate;              /* see FB_ACTIVATE_x */
     96
     97    uint32_t height;                /* height of picture in mm */
     98    uint32_t width;                 /* width of picture in mm */
    10799
    108100    uint32_t accel_flags;       /* acceleration flags (hints)   */
    109101
    110102    /* Timing: All values in pixclocks, except pixclock (of course) */
    111     uint32_t pixclock;          /* pixel clock in ps (pico seconds) */
    112     uint32_t left_margin;       /* time from sync to picture    */
    113     uint32_t right_margin;      /* time from picture to sync    */
    114     uint32_t upper_margin;      /* time from sync to picture    */
     103    uint32_t pixclock;              /* pixel clock in ps (pico seconds) */
     104    uint32_t left_margin;           /* time from sync to picture */
     105    uint32_t right_margin;          /* time from picture to sync */
     106    uint32_t upper_margin;          /* time from sync to picture */
    115107    uint32_t lower_margin;
    116     uint32_t hsync_len;     /* length of horizontal sync    */
    117     uint32_t vsync_len;     /* length of vertical sync  */
    118     uint32_t sync;          /* see FB_SYNC_*        */
    119     uint32_t vmode;         /* see FB_VMODE_*       */
    120     uint32_t reserved[6];       /* Reserved for future compatibility */
     108    uint32_t hsync_len;             /* length of horizontal sync */
     109    uint32_t vsync_len;             /* length of vertical sync */
     110    uint32_t sync;                  /* see FB_SYNC_x */
     111    uint32_t vmode;                 /* see FB_VMODE_x */
     112    uint32_t reserved[6];           /* Reserved for future compatibility */
    121113};
    122114
    123115
    124116static const struct cmdoptions_t {
    125     const char *name;
     117    const char name[10];
    126118    const unsigned char param_count;
    127119    const unsigned char code;
    128120} g_cmdoptions[] = {
    129     {
    130     "-fb", 1, CMD_FB}, {
    131     "-db", 1, CMD_DB}, {
    132     "-a", 0, CMD_ALL}, {
    133     "-i", 0, CMD_INFO}, {
    134     "-g", 5, CMD_GEOMETRY}, {
    135     "-t", 7, CMD_TIMING}, {
    136     "-accel", 1, CMD_ACCEL}, {
    137     "-hsync", 1, CMD_HSYNC}, {
    138     "-vsync", 1, CMD_VSYNC}, {
    139     "-laced", 1, CMD_LACED}, {
    140     "-double", 1, CMD_DOUBLE}, {
    141     "-n", 0, CMD_CHANGE}, {
    142 #ifdef CONFIG_FEATURE_FBSET_FANCY
    143     "-all", 0, CMD_ALL}, {
    144     "-xres", 1, CMD_XRES}, {
    145     "-yres", 1, CMD_YRES}, {
    146     "-vxres", 1, CMD_VXRES}, {
    147     "-vyres", 1, CMD_VYRES}, {
    148     "-depth", 1, CMD_DEPTH}, {
    149     "-match", 0, CMD_MATCH}, {
    150     "-geometry", 5, CMD_GEOMETRY}, {
    151     "-pixclock", 1, CMD_PIXCLOCK}, {
    152     "-left", 1, CMD_LEFT}, {
    153     "-right", 1, CMD_RIGHT}, {
    154     "-upper", 1, CMD_UPPER}, {
    155     "-lower", 1, CMD_LOWER}, {
    156     "-hslen", 1, CMD_HSLEN}, {
    157     "-vslen", 1, CMD_VSLEN}, {
    158     "-timings", 7, CMD_TIMING}, {
    159     "-csync", 1, CMD_CSYNC}, {
    160     "-gsync", 1, CMD_GSYNC}, {
    161     "-extsync", 1, CMD_EXTSYNC}, {
    162     "-bcast", 1, CMD_BCAST}, {
    163     "-rgba", 1, CMD_RGBA}, {
    164     "-step", 1, CMD_STEP}, {
    165     "-move", 1, CMD_MOVE}, {
    166 #endif
    167     0, 0, 0}
    168 };
    169 
    170 #ifdef CONFIG_FEATURE_FBSET_READMODE
     121    { "-fb", 1, CMD_FB },
     122    { "-db", 1, CMD_DB },
     123    { "-a", 0, CMD_ALL },
     124    { "-i", 0, CMD_INFO },
     125    { "-g", 5, CMD_GEOMETRY },
     126    { "-t", 7, CMD_TIMING },
     127    { "-accel", 1, CMD_ACCEL },
     128    { "-hsync", 1, CMD_HSYNC },
     129    { "-vsync", 1, CMD_VSYNC },
     130    { "-laced", 1, CMD_LACED },
     131    { "-double", 1, CMD_DOUBLE },
     132    { "-n", 0, CMD_CHANGE },
     133#if ENABLE_FEATURE_FBSET_FANCY
     134    { "-all", 0, CMD_ALL },
     135    { "-xres", 1, CMD_XRES },
     136    { "-yres", 1, CMD_YRES },
     137    { "-vxres", 1, CMD_VXRES },
     138    { "-vyres", 1, CMD_VYRES },
     139    { "-depth", 1, CMD_DEPTH },
     140    { "-match", 0, CMD_MATCH },
     141    { "-geometry", 5, CMD_GEOMETRY },
     142    { "-pixclock", 1, CMD_PIXCLOCK },
     143    { "-left", 1, CMD_LEFT },
     144    { "-right", 1, CMD_RIGHT },
     145    { "-upper", 1, CMD_UPPER },
     146    { "-lower", 1, CMD_LOWER },
     147    { "-hslen", 1, CMD_HSLEN },
     148    { "-vslen", 1, CMD_VSLEN },
     149    { "-timings", 7, CMD_TIMING },
     150    { "-csync", 1, CMD_CSYNC },
     151    { "-gsync", 1, CMD_GSYNC },
     152    { "-extsync", 1, CMD_EXTSYNC },
     153    { "-bcast", 1, CMD_BCAST },
     154    { "-rgba", 1, CMD_RGBA },
     155    { "-step", 1, CMD_STEP },
     156    { "-move", 1, CMD_MOVE },
     157#endif
     158    { "", 0, 0 }
     159};
     160
     161#if ENABLE_FEATURE_FBSET_READMODE
    171162/* taken from linux/fb.h */
    172163enum {
     
    179170};
    180171#endif
     172
    181173static int readmode(struct fb_var_screeninfo *base, const char *fn,
    182174                    const char *mode)
    183175{
    184 #ifdef CONFIG_FEATURE_FBSET_READMODE
     176#if ENABLE_FEATURE_FBSET_READMODE
    185177    FILE *f;
    186178    char buf[256];
    187179    char *p = buf;
    188180
    189     f = bb_xfopen(fn, "r");
     181    f = xfopen(fn, "r");
    190182    while (!feof(f)) {
    191183        fgets(buf, sizeof(buf), f);
    192         if ((p = strstr(buf, "mode ")) || (p = strstr(buf, "mode\t"))) {
    193             p += 5;
    194             if ((p = strstr(buf, mode))) {
    195                 p += strlen(mode);
    196                 if (!isspace(*p) && (*p != 0) && (*p != '"')
    197                     && (*p != '\r') && (*p != '\n'))
    198                     continue;   /* almost, but not quite */
    199                 while (!feof(f)) {
    200                     fgets(buf, sizeof(buf), f);
    201 
    202             if ((p = strstr(buf, "geometry "))) {
    203             p += 9;
    204 
    205             sscanf(p, "%d %d %d %d %d",
    206                 &(base->xres), &(base->yres),
    207                 &(base->xres_virtual), &(base->yres_virtual),
    208                 &(base->bits_per_pixel));
    209             } else if ((p = strstr(buf, "timings "))) {
    210             p += 8;
    211 
    212             sscanf(p, "%d %d %d %d %d %d %d",
    213                 &(base->pixclock),
    214                 &(base->left_margin), &(base->right_margin),
    215                 &(base->upper_margin), &(base->lower_margin),
    216                 &(base->hsync_len), &(base->vsync_len));
    217             } else if ((p = strstr(buf, "laced "))) {
    218             p += 6;
    219 
    220             if (strstr(buf, "false")) {
    221                 base->vmode &= ~FB_VMODE_INTERLACED;
    222             } else {
    223                 base->vmode |= FB_VMODE_INTERLACED;
     184        if (!(p = strstr(buf, "mode ")) && !(p = strstr(buf, "mode\t")))
     185            continue;
     186        p += 5;
     187        if (!(p = strstr(buf, mode)))
     188            continue;
     189        p += strlen(mode);
     190        if (!isspace(*p) && (*p != 0) && (*p != '"')
     191                && (*p != '\r') && (*p != '\n'))
     192            continue;   /* almost, but not quite */
     193
     194        while (!feof(f)) {
     195            fgets(buf, sizeof(buf), f);
     196            if ((p = strstr(buf, "geometry "))) {
     197                p += 9;
     198                /* FIXME: catastrophic on arches with 64bit ints */
     199                sscanf(p, "%d %d %d %d %d",
     200                    &(base->xres), &(base->yres),
     201                    &(base->xres_virtual), &(base->yres_virtual),
     202                    &(base->bits_per_pixel));
     203            } else if ((p = strstr(buf, "timings "))) {
     204                p += 8;
     205                sscanf(p, "%d %d %d %d %d %d %d",
     206                    &(base->pixclock),
     207                    &(base->left_margin), &(base->right_margin),
     208                    &(base->upper_margin), &(base->lower_margin),
     209                    &(base->hsync_len), &(base->vsync_len));
     210            } else if ((p = strstr(buf, "laced "))) {
     211                //p += 6;
     212                if (strstr(buf, "false")) {
     213                    base->vmode &= ~FB_VMODE_INTERLACED;
     214                } else {
     215                    base->vmode |= FB_VMODE_INTERLACED;
     216                }
     217            } else if ((p = strstr(buf, "double "))) {
     218                //p += 7;
     219                if (strstr(buf, "false")) {
     220                    base->vmode &= ~FB_VMODE_DOUBLE;
     221                } else {
     222                    base->vmode |= FB_VMODE_DOUBLE;
     223                }
     224            } else if ((p = strstr(buf, "vsync "))) {
     225                //p += 6;
     226                if (strstr(buf, "low")) {
     227                    base->sync &= ~FB_SYNC_VERT_HIGH_ACT;
     228                } else {
     229                    base->sync |= FB_SYNC_VERT_HIGH_ACT;
     230                }
     231            } else if ((p = strstr(buf, "hsync "))) {
     232                //p += 6;
     233                if (strstr(buf, "low")) {
     234                    base->sync &= ~FB_SYNC_HOR_HIGH_ACT;
     235                } else {
     236                    base->sync |= FB_SYNC_HOR_HIGH_ACT;
     237                }
     238            } else if ((p = strstr(buf, "csync "))) {
     239                //p += 6;
     240                if (strstr(buf, "low")) {
     241                    base->sync &= ~FB_SYNC_COMP_HIGH_ACT;
     242                } else {
     243                    base->sync |= FB_SYNC_COMP_HIGH_ACT;
     244                }
     245            } else if ((p = strstr(buf, "extsync "))) {
     246                //p += 8;
     247                if (strstr(buf, "false")) {
     248                    base->sync &= ~FB_SYNC_EXT;
     249                } else {
     250                    base->sync |= FB_SYNC_EXT;
     251                }
    224252            }
    225             } else if ((p = strstr(buf, "double "))) {
    226             p += 7;
    227 
    228             if (strstr(buf, "false")) {
    229                 base->vmode &= ~FB_VMODE_DOUBLE;
    230             } else {
    231                 base->vmode |= FB_VMODE_DOUBLE;
    232             }
    233             } else if ((p = strstr(buf, "vsync "))) {
    234             p += 6;
    235 
    236             if (strstr(buf, "low")) {
    237                 base->sync &= ~FB_SYNC_VERT_HIGH_ACT;
    238             } else {
    239                 base->sync |= FB_SYNC_VERT_HIGH_ACT;
    240             }
    241             } else if ((p = strstr(buf, "hsync "))) {
    242             p += 6;
    243 
    244             if (strstr(buf, "low")) {
    245                 base->sync &= ~FB_SYNC_HOR_HIGH_ACT;
    246             } else {
    247                 base->sync |= FB_SYNC_HOR_HIGH_ACT;
    248             }
    249             } else if ((p = strstr(buf, "csync "))) {
    250             p += 6;
    251 
    252             if (strstr(buf, "low")) {
    253                 base->sync &= ~FB_SYNC_COMP_HIGH_ACT;
    254             } else {
    255                 base->sync |= FB_SYNC_COMP_HIGH_ACT;
    256             }
    257             } else if ((p = strstr(buf, "extsync "))) {
    258             p += 8;
    259 
    260             if (strstr(buf, "false")) {
    261                 base->sync &= ~FB_SYNC_EXT;
    262             } else {
    263                 base->sync |= FB_SYNC_EXT;
    264             }
    265             }
    266 
    267                     if (strstr(buf, "endmode"))
    268                         return 1;
    269                 }
    270             }
     253
     254            if (strstr(buf, "endmode"))
     255                return 1;
    271256        }
    272257    }
    273258#else
    274     bb_error_msg( "mode reading not compiled in");
     259    bb_error_msg("mode reading not compiled in");
    275260#endif
    276261    return 0;
     
    298283    if (v->pixclock) {
    299284        drate = 1e12 / v->pixclock;
    300         hrate =
    301             drate / (v->left_margin + v->xres + v->right_margin +
    302                      v->hsync_len);
    303         vrate =
    304             hrate / (v->upper_margin + v->yres + v->lower_margin +
    305                      v->vsync_len);
     285        hrate = drate / (v->left_margin + v->xres + v->right_margin + v->hsync_len);
     286        vrate = hrate / (v->upper_margin + v->yres + v->lower_margin + v->vsync_len);
    306287    }
    307288    printf("\nmode \"%ux%u-%u\"\n"
    308 #ifdef CONFIG_FEATURE_FBSET_FANCY
     289#if ENABLE_FEATURE_FBSET_FANCY
    309290    "\t# D: %.3f MHz, H: %.3f kHz, V: %.3f Hz\n"
    310291#endif
    311     "\tgeometry %u %u %u %u %u\n\ttimings %u %u %u %u %u %u %u\n\taccel %s\n\trgba %u/%u,%u/%u,%u/%u,%u/%u\nendmode\n\n",
    312            v->xres, v->yres, (int) (vrate + 0.5),
    313 #ifdef CONFIG_FEATURE_FBSET_FANCY
    314            drate / 1e6, hrate / 1e3, vrate,
    315 #endif
    316            v->xres, v->yres, v->xres_virtual, v->yres_virtual,
    317            v->bits_per_pixel, v->pixclock, v->left_margin,
    318            v->right_margin, v->upper_margin, v->lower_margin, v->hsync_len,
    319            v->vsync_len, (v->accel_flags > 0 ? "true" : "false"), v->red.length,
    320            v->red.offset, v->green.length, v->green.offset, v->blue.length,
    321            v->blue.offset, v->transp.length, v->transp.offset);
     292    "\tgeometry %u %u %u %u %u\n"
     293    "\ttimings %u %u %u %u %u %u %u\n"
     294    "\taccel %s\n"
     295    "\trgba %u/%u,%u/%u,%u/%u,%u/%u\n"
     296    "endmode\n\n",
     297        v->xres, v->yres, (int) (vrate + 0.5),
     298#if ENABLE_FEATURE_FBSET_FANCY
     299        drate / 1e6, hrate / 1e3, vrate,
     300#endif
     301        v->xres, v->yres, v->xres_virtual, v->yres_virtual, v->bits_per_pixel,
     302        v->pixclock, v->left_margin, v->right_margin, v->upper_margin, v->lower_margin,
     303            v->hsync_len, v->vsync_len,
     304        (v->accel_flags > 0 ? "true" : "false"),
     305        v->red.length, v->red.offset, v->green.length, v->green.offset,
     306            v->blue.length, v->blue.offset, v->transp.length, v->transp.offset);
    322307}
    323308
     
    325310int main(int argc, char **argv)
    326311#else
     312int fbset_main(int argc, char **argv);
    327313int fbset_main(int argc, char **argv)
    328314#endif
     
    330316    struct fb_var_screeninfo var, varset;
    331317    int fh, i;
    332     char *fbdev = DEFAULTFBDEV;
    333     char *modefile = DEFAULTFBMODE;
     318    const char *fbdev = DEFAULTFBDEV;
     319    const char *modefile = DEFAULTFBMODE;
    334320    char *thisarg, *mode = NULL;
    335321
     
    340326    argc--;
    341327    for (; argc > 0 && (thisarg = *argv); argc--, argv++) {
    342         for (i = 0; g_cmdoptions[i].name; i++) {
    343             if (!strcmp(thisarg, g_cmdoptions[i].name)) {
    344                 if (argc - 1 < g_cmdoptions[i].param_count)
    345                     bb_show_usage();
    346                 switch (g_cmdoptions[i].code) {
    347                 case CMD_FB:
    348                     fbdev = argv[1];
    349                     break;
    350                 case CMD_DB:
    351                     modefile = argv[1];
    352                     break;
    353                 case CMD_GEOMETRY:
    354                     varset.xres = strtoul(argv[1], 0, 0);
    355                     varset.yres = strtoul(argv[2], 0, 0);
    356                     varset.xres_virtual = strtoul(argv[3], 0, 0);
    357                     varset.yres_virtual = strtoul(argv[4], 0, 0);
    358                     varset.bits_per_pixel = strtoul(argv[5], 0, 0);
    359                     break;
    360                 case CMD_TIMING:
    361                     varset.pixclock = strtoul(argv[1], 0, 0);
    362                     varset.left_margin = strtoul(argv[2], 0, 0);
    363                     varset.right_margin = strtoul(argv[3], 0, 0);
    364                     varset.upper_margin = strtoul(argv[4], 0, 0);
    365                     varset.lower_margin = strtoul(argv[5], 0, 0);
    366                     varset.hsync_len = strtoul(argv[6], 0, 0);
    367                     varset.vsync_len = strtoul(argv[7], 0, 0);
    368                     break;
    369         case CMD_CHANGE:
    370             g_options |= OPT_CHANGE;
    371             break;
    372 #ifdef CONFIG_FEATURE_FBSET_FANCY
    373                 case CMD_XRES:
    374                     varset.xres = strtoul(argv[1], 0, 0);
    375                     break;
    376                 case CMD_YRES:
    377                     varset.yres = strtoul(argv[1], 0, 0);
    378                     break;
    379                case CMD_DEPTH:
    380                     varset.bits_per_pixel = strtoul(argv[1], 0, 0);
    381                     break;
    382 #endif
    383                 }
    384                 argc -= g_cmdoptions[i].param_count;
    385                 argv += g_cmdoptions[i].param_count;
    386                 break;
     328        for (i = 0; g_cmdoptions[i].name[0]; i++) {
     329            if (strcmp(thisarg, g_cmdoptions[i].name))
     330                continue;
     331            if (argc-1 < g_cmdoptions[i].param_count)
     332                bb_show_usage();
     333
     334            switch (g_cmdoptions[i].code) {
     335            case CMD_FB:
     336                fbdev = argv[1];
     337                break;
     338            case CMD_DB:
     339                modefile = argv[1];
     340                break;
     341            case CMD_GEOMETRY:
     342                varset.xres = xatou32(argv[1]);
     343                varset.yres = xatou32(argv[2]);
     344                varset.xres_virtual = xatou32(argv[3]);
     345                varset.yres_virtual = xatou32(argv[4]);
     346                varset.bits_per_pixel = xatou32(argv[5]);
     347                break;
     348            case CMD_TIMING:
     349                varset.pixclock = xatou32(argv[1]);
     350                varset.left_margin = xatou32(argv[2]);
     351                varset.right_margin = xatou32(argv[3]);
     352                varset.upper_margin = xatou32(argv[4]);
     353                varset.lower_margin = xatou32(argv[5]);
     354                varset.hsync_len = xatou32(argv[6]);
     355                varset.vsync_len = xatou32(argv[7]);
     356                break;
     357            case CMD_ALL:
     358                g_options |= OPT_ALL;
     359                break;
     360            case CMD_CHANGE:
     361                g_options |= OPT_CHANGE;
     362                break;
     363#if ENABLE_FEATURE_FBSET_FANCY
     364            case CMD_XRES:
     365                varset.xres = xatou32(argv[1]);
     366                break;
     367            case CMD_YRES:
     368                varset.yres = xatou32(argv[1]);
     369                break;
     370            case CMD_DEPTH:
     371                varset.bits_per_pixel = xatou32(argv[1]);
     372                break;
     373#endif
    387374            }
     375            argc -= g_cmdoptions[i].param_count;
     376            argv += g_cmdoptions[i].param_count;
     377            break;
    388378        }
    389         if (!g_cmdoptions[i].name) {
    390             if (argc == 1) {
    391                 mode = *argv;
    392                 g_options |= OPT_READMODE;
    393             } else {
     379        if (!g_cmdoptions[i].name[0]) {
     380            if (argc != 1)
    394381                bb_show_usage();
    395             }
     382            mode = *argv;
     383            g_options |= OPT_READMODE;
    396384        }
    397385    }
    398386
    399     fh = bb_xopen(fbdev, O_RDONLY);
    400     if (ioctl(fh, FBIOGET_VSCREENINFO, &var))
    401         bb_perror_msg_and_die("fbset(ioctl)");
     387    fh = xopen(fbdev, O_RDONLY);
     388    xioctl(fh, FBIOGET_VSCREENINFO, &var);
    402389    if (g_options & OPT_READMODE) {
    403390        if (!readmode(&var, modefile, mode)) {
    404             bb_error_msg("Unknown video mode `%s'", mode);
    405             return EXIT_FAILURE;
     391            bb_error_msg_and_die("unknown video mode '%s'", mode);
    406392        }
    407393    }
    408394
    409395    setmode(&var, &varset);
    410     if (g_options & OPT_CHANGE)
    411         if (ioctl(fh, FBIOPUT_VSCREENINFO, &var))
    412             bb_perror_msg_and_die("fbset(ioctl)");
     396    if (g_options & OPT_CHANGE) {
     397        if (g_options & OPT_ALL)
     398            var.activate = FB_ACTIVATE_ALL;
     399        xioctl(fh, FBIOPUT_VSCREENINFO, &var);
     400    }
    413401    showmode(&var);
    414402    /* Don't close the file, as exiting will take care of that */
  • branches/2.2.5/mindi-busybox/util-linux/fdformat.c

    r821 r1765  
     1/* vi: set sw=4 ts=4: */
    12/* fdformat.c  -  Low-level formats a floppy disk - Werner Almesberger */
    23
     
    910 */
    1011
    11 #include <stdio.h>
    12 #include <string.h>
    13 #include <fcntl.h>
    14 #include <errno.h>
    15 #include <unistd.h>
    16 #include <stdlib.h>
    17 #include <sys/stat.h>
    18 #include <sys/ioctl.h>
    19 #include "busybox.h"
     12#include "libbb.h"
    2013
    2114
     
    5346#define FD_FILL_BYTE 0xF6 /* format fill byte. */
    5447
    55 static void print_and_flush(const char * __restrict format, ...)
    56 {
    57     va_list arg;
    58 
    59     va_start(arg, format);
    60     bb_vfprintf(stdout, format, arg);
    61     va_end(arg);
    62     bb_xfflush_stdout();
    63 }
    64 
    65 static void bb_xioctl(int fd, int request, void *argp, const char *string)
    66 {
    67     if (ioctl (fd, request, argp) < 0) {
    68         bb_perror_msg_and_die(string);
    69     }
    70 }
    71 
     48int fdformat_main(int argc,char **argv);
    7249int fdformat_main(int argc,char **argv)
    7350{
     
    8158        bb_show_usage();
    8259    }
    83     verify = !bb_getopt_ulflags(argc, argv, "n");
     60    verify = !getopt32(argv, "n");
    8461    argv += optind;
    8562
    86     /* R_OK is needed for verifying */
    87     if (stat(*argv,&st) < 0 || access(*argv,W_OK | R_OK ) < 0) {
    88         bb_perror_msg_and_die("%s",*argv);
    89     }
     63    xstat(*argv, &st);
    9064    if (!S_ISBLK(st.st_mode)) {
    91         bb_error_msg_and_die("%s: not a block device",*argv);
     65        bb_error_msg_and_die("%s: not a block device", *argv);
    9266        /* do not test major - perhaps this was an USB floppy */
    9367    }
    9468
     69    /* O_RDWR for formatting and verifying */
     70    fd = xopen(*argv, O_RDWR);
    9571
    96     /* O_RDWR for formatting and verifying */
    97     fd = bb_xopen(*argv,O_RDWR );
     72    /* original message was: "Could not determine current format type" */
     73    xioctl(fd, FDGETPRM, &param);
    9874
    99     bb_xioctl(fd, FDGETPRM, &param, "FDGETPRM");/*original message was: "Could not determine current format type" */
    100 
    101     print_and_flush("%s-sided, %d tracks, %d sec/track. Total capacity %d kB.\n",
     75    printf("%s-sided, %d tracks, %d sec/track. Total capacity %d kB\n",
    10276        (param.head == 2) ? "Double" : "Single",
    10377        param.track, param.sect, param.size >> 1);
    10478
    10579    /* FORMAT */
    106     print_and_flush("Formatting ... ", NULL);
    107     bb_xioctl(fd, FDFMTBEG,NULL,"FDFMTBEG");
     80    printf("Formatting... ");
     81    xioctl(fd, FDFMTBEG, NULL);
    10882
    10983    /* n == track */
    110     for (n = 0; n < param.track; n++)
    111     {
    112         descr.head = 0;
    113         descr.track = n;
    114         bb_xioctl(fd, FDFMTTRK,&descr,"FDFMTTRK");
    115         print_and_flush("%3d\b\b\b", n);
    116         if (param.head == 2) {
    117         descr.head = 1;
    118         bb_xioctl(fd, FDFMTTRK,&descr,"FDFMTTRK");
    119         }
     84    for (n = 0; n < param.track; n++) {
     85        descr.head = 0;
     86        descr.track = n;
     87        xioctl(fd, FDFMTTRK, &descr);
     88        printf("%3d\b\b\b", n);
     89        if (param.head == 2) {
     90            descr.head = 1;
     91            xioctl(fd, FDFMTTRK, &descr);
     92        }
    12093    }
    12194
    122     bb_xioctl(fd,FDFMTEND,NULL,"FDFMTEND");
    123     print_and_flush("done\n", NULL);
     95    xioctl(fd, FDFMTEND, NULL);
     96    printf("done\n");
    12497
    12598    /* VERIFY */
    126     if(verify) {
     99    if (verify) {
    127100        /* n == cyl_size */
    128101        n = param.sect*param.head*512;
    129102
    130103        data = xmalloc(n);
    131         print_and_flush("Verifying ... ", NULL);
     104        printf("Verifying... ");
    132105        for (cyl = 0; cyl < param.track; cyl++) {
    133             print_and_flush("%3d\b\b\b", cyl);
    134             if((read_bytes = safe_read(fd,data,n))!= n ) {
    135                 if(read_bytes < 0) {
     106            printf("%3d\b\b\b", cyl);
     107            read_bytes = safe_read(fd, data, n);
     108            if (read_bytes != n) {
     109                if (read_bytes < 0) {
    136110                    bb_perror_msg(bb_msg_read_error);
    137111                }
    138                 bb_error_msg_and_die("Problem reading cylinder %d, expected %d, read %d", cyl, n, read_bytes);
     112                bb_error_msg_and_die("problem reading cylinder %d, "
     113                    "expected %d, read %d", cyl, n, read_bytes);
     114                // FIXME: maybe better seek & continue??
    139115            }
    140116            /* Check backwards so we don't need a counter */
    141             while(--read_bytes>=0) {
    142                 if( data[read_bytes] != FD_FILL_BYTE) {
    143                      print_and_flush("bad data in cyl %d\nContinuing ... ",cyl);
     117            while (--read_bytes >= 0) {
     118                if (data[read_bytes] != FD_FILL_BYTE) {
     119                     printf("bad data in cyl %d\nContinuing... ",cyl);
    144120                }
    145121            }
     
    151127        if (ENABLE_FEATURE_CLEAN_UP) free(data);
    152128
    153         print_and_flush("done\n", NULL);
     129        printf("done\n");
    154130    }
    155131
  • branches/2.2.5/mindi-busybox/util-linux/fdisk.c

    r821 r1765  
     1/* vi: set sw=4 ts=4: */
    12/* fdisk.c -- Partition table manipulator for Linux.
    23 *
     
    78 */
    89
    9 /* Current changes have not compatibility with this version */
    10 #define UTIL_LINUX_VERSION "2.12"
    11 
    12 
    13 #define _(x) x
    14 
    15 #define PROC_PARTITIONS "/proc/partitions"
    16 
    17 #include <features.h>
    18 #include <sys/types.h>
    19 #include <sys/stat.h>           /* stat */
    20 #include <ctype.h>
    21 #include <stdlib.h>
    22 #include <stdio.h>
    23 #include <string.h>
    24 #include <errno.h>
    25 #include <unistd.h>
    26 #include <fcntl.h>
    27 #include <setjmp.h>
     10#ifndef _LARGEFILE64_SOURCE
     11/* For lseek64 */
     12#define _LARGEFILE64_SOURCE
     13#endif
    2814#include <assert.h>             /* assert */
    29 #include <getopt.h>
    30 #include <endian.h>
    31 #include <sys/ioctl.h>
    32 #include <sys/param.h>
    33 #include <sys/sysmacros.h>     /* major */
    34 
    35 #include <stdint.h>        /* for uint32_t, uint16_t, uint8_t, int16_t, etc */
    36 
    37 /* Copied from linux/major.h */
    38 #define FLOPPY_MAJOR    2
    39 
    40 #include <sys/utsname.h>
    41 
    42 #include "busybox.h"
    43 
    44 #define DKTYPENAMES
    45 
    46 /*
    47    fdisk.h
    48 */
     15#include "libbb.h"
     16
     17/* Looks like someone forgot to add this to config system */
     18#ifndef ENABLE_FEATURE_FDISK_BLKSIZE
     19# define ENABLE_FEATURE_FDISK_BLKSIZE 0
     20# define USE_FEATURE_FDISK_BLKSIZE(a)
     21#endif
    4922
    5023#define DEFAULT_SECTOR_SIZE     512
    5124#define MAX_SECTOR_SIZE 2048
    52 #define SECTOR_SIZE     512     /* still used in BSD code */
     25#define SECTOR_SIZE     512     /* still used in osf/sgi/sun code */
    5326#define MAXIMUM_PARTS   60
    5427
     
    6437#define LINUX_RAID      0xfd
    6538
    66 #define SUNOS_SWAP 3
    67 #define WHOLE_DISK 5
    68 
    69 #define IS_EXTENDED(i) \
    70     ((i) == EXTENDED || (i) == WIN98_EXTENDED || (i) == LINUX_EXTENDED)
    71 
    72 #define SIZE(a) (sizeof(a)/sizeof((a)[0]))
    73 
    74 #define cround(n)       (display_in_cyl_units ? ((n)/units_per_sector)+1 : (n))
    75 #define scround(x)      (((x)+units_per_sector-1)/units_per_sector)
    76 
    77 #ifdef CONFIG_FEATURE_SUN_LABEL
    78 #define SCSI_IOCTL_GET_IDLUN 0x5382
    79 #endif
    80 
    81 
    82 /* including <linux/hdreg.h> also fails */
     39/* Used for sector numbers. Today's disk sizes make it necessary */
     40typedef unsigned long long ullong;
     41
    8342struct hd_geometry {
    8443    unsigned char heads;
     
    8847};
    8948
    90 #define HDIO_GETGEO             0x0301  /* get device geometry */
    91 
    92 
    93 struct systypes {
    94     const char *name;
    95 };
    96 
    97 static uint sector_size = DEFAULT_SECTOR_SIZE;
    98 static uint user_set_sector_size;
    99 static uint sector_offset = 1;
    100 
    101 /*
    102  * Raw disk label. For DOS-type partition tables the MBR,
    103  * with descriptions of the primary partitions.
    104  */
    105 #if (MAX_SECTOR_SIZE) > (BUFSIZ+1)
    106 static char MBRbuffer[MAX_SECTOR_SIZE];
    107 #else
    108 # define MBRbuffer bb_common_bufsiz1
    109 #endif
    110 
    111 #ifdef CONFIG_FEATURE_OSF_LABEL
     49#define HDIO_GETGEO     0x0301  /* get device geometry */
     50
     51static const char msg_building_new_label[] ALIGN1 =
     52"Building a new %s. Changes will remain in memory only,\n"
     53"until you decide to write them. After that the previous content\n"
     54"won't be recoverable.\n\n";
     55
     56static const char msg_part_already_defined[] ALIGN1 =
     57"Partition %d is already defined, delete it before re-adding\n";
     58
     59
     60static unsigned sector_size = DEFAULT_SECTOR_SIZE;
     61static unsigned user_set_sector_size;
     62static unsigned sector_offset = 1;
     63
     64#if ENABLE_FEATURE_OSF_LABEL
    11265static int possibly_osf_label;
    11366#endif
    11467
    115 static uint heads, sectors, cylinders;
     68static unsigned heads, sectors, cylinders;
    11669static void update_units(void);
    11770
    118 
    119 /*
    120  * return partition name - uses static storage unless buf is supplied
    121  */
    122 static const char *
    123 partname(const char *dev, int pno, int lth)
    124 {
    125     static char buffer[80];
    126     const char *p;
    127     int w, wp;
    128     int bufsiz;
    129     char *bufp;
    130 
    131     bufp = buffer;
    132     bufsiz = sizeof(buffer);
    133 
    134     w = strlen(dev);
    135     p = "";
    136 
    137     if (isdigit(dev[w-1]))
    138         p = "p";
    139 
    140     /* devfs kludge - note: fdisk partition names are not supposed
    141        to equal kernel names, so there is no reason to do this */
    142     if (strcmp(dev + w - 4, "disc") == 0) {
    143         w -= 4;
    144         p = "part";
    145     }
    146 
    147     wp = strlen(p);
    148 
    149     if (lth) {
    150         snprintf(bufp, bufsiz, "%*.*s%s%-2u",
    151              lth-wp-2, w, dev, p, pno);
    152     } else {
    153         snprintf(bufp, bufsiz, "%.*s%s%-2u", w, dev, p, pno);
    154     }
    155     return bufp;
    156 }
    15771
    15872struct partition {
     
    16983} ATTRIBUTE_PACKED;
    17084
    171 enum failure {
    172     ioctl_error, unable_to_open, unable_to_read, unable_to_seek,
    173     unable_to_write
    174 };
    175 
    176 enum label_type{
     85static const char unable_to_open[] ALIGN1 = "cannot open %s";
     86static const char unable_to_read[] ALIGN1 = "cannot read from %s";
     87static const char unable_to_seek[] ALIGN1 = "cannot seek on %s";
     88static const char unable_to_write[] ALIGN1 = "cannot write to %s";
     89static const char ioctl_error[] ALIGN1 = "BLKGETSIZE ioctl failed on %s";
     90static void fdisk_fatal(const char *why) ATTRIBUTE_NORETURN;
     91
     92enum label_type {
    17793    label_dos, label_sun, label_sgi, label_aix, label_osf
    17894};
     95
     96#define LABEL_IS_DOS    (label_dos == current_label_type)
     97
     98#if ENABLE_FEATURE_SUN_LABEL
     99#define LABEL_IS_SUN    (label_sun == current_label_type)
     100#define STATIC_SUN static
     101#else
     102#define LABEL_IS_SUN    0
     103#define STATIC_SUN extern
     104#endif
     105
     106#if ENABLE_FEATURE_SGI_LABEL
     107#define LABEL_IS_SGI    (label_sgi == current_label_type)
     108#define STATIC_SGI static
     109#else
     110#define LABEL_IS_SGI    0
     111#define STATIC_SGI extern
     112#endif
     113
     114#if ENABLE_FEATURE_AIX_LABEL
     115#define LABEL_IS_AIX    (label_aix == current_label_type)
     116#define STATIC_AIX static
     117#else
     118#define LABEL_IS_AIX    0
     119#define STATIC_AIX extern
     120#endif
     121
     122#if ENABLE_FEATURE_OSF_LABEL
     123#define LABEL_IS_OSF    (label_osf == current_label_type)
     124#define STATIC_OSF static
     125#else
     126#define LABEL_IS_OSF    0
     127#define STATIC_OSF extern
     128#endif
    179129
    180130enum action { fdisk, require, try_only, create_empty_dos, create_empty_sun };
     
    185135static int fd;                  /* the disk */
    186136static int partitions = 4;      /* maximum partition + 1 */
    187 static uint display_in_cyl_units = 1;
    188 static uint units_per_sector = 1;
    189 #ifdef CONFIG_FEATURE_FDISK_WRITABLE
    190 static char *line_ptr;
     137static int display_in_cyl_units = 1;
     138static unsigned units_per_sector = 1;
     139#if ENABLE_FEATURE_FDISK_WRITABLE
    191140static void change_units(void);
    192141static void reread_partition_table(int leave);
    193142static void delete_partition(int i);
    194143static int get_partition(int warn, int max);
    195 static void list_types(const struct systypes *sys);
    196 static uint read_int(uint low, uint dflt, uint high, uint base, char *mesg);
     144static void list_types(const char *const *sys);
     145static unsigned read_int(unsigned low, unsigned dflt, unsigned high, unsigned base, const char *mesg);
    197146#endif
    198147static const char *partition_type(unsigned char type);
    199 static void fdisk_fatal(enum failure why) ATTRIBUTE_NORETURN;
    200148static void get_geometry(void);
    201149static int get_boot(enum action what);
     
    204152#define SINGULAR 1
    205153
    206 #define hex_val(c)      ({ \
    207                 char _c = (c); \
    208                 isdigit(_c) ? _c - '0' : \
    209                 tolower(_c) + 10 - 'a'; \
    210             })
    211 
    212 
    213 #define LINE_LENGTH     800
    214 #define pt_offset(b, n) ((struct partition *)((b) + 0x1be + \
    215                 (n) * sizeof(struct partition)))
    216 #define sector(s)       ((s) & 0x3f)
    217 #define cylinder(s, c)  ((c) | (((s) & 0xc0) << 2))
    218 
    219 #define hsc2sector(h,s,c) (sector(s) - 1 + sectors * \
    220                 ((h) + heads * cylinder(s,c)))
    221 #define set_hsc(h,s,c,sector) { \
    222                 s = sector % sectors + 1;       \
    223                 sector /= sectors;      \
    224                 h = sector % heads;     \
    225                 sector /= heads;        \
    226                 c = sector & 0xff;      \
    227                 s |= (sector >> 2) & 0xc0;      \
    228             }
    229 
    230 
    231 static int32_t get_start_sect(const struct partition *p);
    232 static int32_t get_nr_sects(const struct partition *p);
     154static unsigned get_start_sect(const struct partition *p);
     155static unsigned get_nr_sects(const struct partition *p);
    233156
    234157/*
     
    240163 * partition and one link to the next one.
    241164 */
    242 static struct pte {
     165struct pte {
    243166    struct partition *part_table;   /* points into sectorbuffer */
    244167    struct partition *ext_pointer;  /* points into sectorbuffer */
    245 #ifdef CONFIG_FEATURE_FDISK_WRITABLE
     168    ullong offset;          /* disk sector number */
     169    char *sectorbuffer;     /* disk sector contents */
     170#if ENABLE_FEATURE_FDISK_WRITABLE
    246171    char changed;           /* boolean */
    247172#endif
    248     off_t offset;            /* disk sector number */
    249     char *sectorbuffer;     /* disk sector contents */
    250 } ptes[MAXIMUM_PARTS];
    251 
    252 
    253 #ifdef CONFIG_FEATURE_FDISK_WRITABLE
     173};
     174
     175/* DOS partition types */
     176
     177static const char *const i386_sys_types[] = {
     178    "\x00" "Empty",
     179    "\x01" "FAT12",
     180    "\x04" "FAT16 <32M",
     181    "\x05" "Extended",         /* DOS 3.3+ extended partition */
     182    "\x06" "FAT16",            /* DOS 16-bit >=32M */
     183    "\x07" "HPFS/NTFS",        /* OS/2 IFS, eg, HPFS or NTFS or QNX */
     184    "\x0a" "OS/2 Boot Manager",/* OS/2 Boot Manager */
     185    "\x0b" "Win95 FAT32",
     186    "\x0c" "Win95 FAT32 (LBA)",/* LBA really is 'Extended Int 13h' */
     187    "\x0e" "Win95 FAT16 (LBA)",
     188    "\x0f" "Win95 Ext'd (LBA)",
     189    "\x11" "Hidden FAT12",
     190    "\x12" "Compaq diagnostics",
     191    "\x14" "Hidden FAT16 <32M",
     192    "\x16" "Hidden FAT16",
     193    "\x17" "Hidden HPFS/NTFS",
     194    "\x1b" "Hidden Win95 FAT32",
     195    "\x1c" "Hidden W95 FAT32 (LBA)",
     196    "\x1e" "Hidden W95 FAT16 (LBA)",
     197    "\x3c" "Part.Magic recovery",
     198    "\x41" "PPC PReP Boot",
     199    "\x42" "SFS",
     200    "\x63" "GNU HURD or SysV", /* GNU HURD or Mach or Sys V/386 (such as ISC UNIX) */
     201    "\x80" "Old Minix",        /* Minix 1.4a and earlier */
     202    "\x81" "Minix / old Linux",/* Minix 1.4b and later */
     203    "\x82" "Linux swap",       /* also Solaris */
     204    "\x83" "Linux",
     205    "\x84" "OS/2 hidden C: drive",
     206    "\x85" "Linux extended",
     207    "\x86" "NTFS volume set",
     208    "\x87" "NTFS volume set",
     209    "\x8e" "Linux LVM",
     210    "\x9f" "BSD/OS",           /* BSDI */
     211    "\xa0" "Thinkpad hibernation",
     212    "\xa5" "FreeBSD",          /* various BSD flavours */
     213    "\xa6" "OpenBSD",
     214    "\xa8" "Darwin UFS",
     215    "\xa9" "NetBSD",
     216    "\xab" "Darwin boot",
     217    "\xb7" "BSDI fs",
     218    "\xb8" "BSDI swap",
     219    "\xbe" "Solaris boot",
     220    "\xeb" "BeOS fs",
     221    "\xee" "EFI GPT",                    /* Intel EFI GUID Partition Table */
     222    "\xef" "EFI (FAT-12/16/32)",         /* Intel EFI System Partition */
     223    "\xf0" "Linux/PA-RISC boot",         /* Linux/PA-RISC boot loader */
     224    "\xf2" "DOS secondary",              /* DOS 3.3+ secondary */
     225    "\xfd" "Linux raid autodetect",      /* New (2.2.x) raid partition with
     226                        autodetect using persistent
     227                        superblock */
     228#if 0 /* ENABLE_WEIRD_PARTITION_TYPES */
     229    "\x02" "XENIX root",
     230    "\x03" "XENIX usr",
     231    "\x08" "AIX",              /* AIX boot (AIX -- PS/2 port) or SplitDrive */
     232    "\x09" "AIX bootable",     /* AIX data or Coherent */
     233    "\x10" "OPUS",
     234    "\x18" "AST SmartSleep",
     235    "\x24" "NEC DOS",
     236    "\x39" "Plan 9",
     237    "\x40" "Venix 80286",
     238    "\x4d" "QNX4.x",
     239    "\x4e" "QNX4.x 2nd part",
     240    "\x4f" "QNX4.x 3rd part",
     241    "\x50" "OnTrack DM",
     242    "\x51" "OnTrack DM6 Aux1", /* (or Novell) */
     243    "\x52" "CP/M",             /* CP/M or Microport SysV/AT */
     244    "\x53" "OnTrack DM6 Aux3",
     245    "\x54" "OnTrackDM6",
     246    "\x55" "EZ-Drive",
     247    "\x56" "Golden Bow",
     248    "\x5c" "Priam Edisk",
     249    "\x61" "SpeedStor",
     250    "\x64" "Novell Netware 286",
     251    "\x65" "Novell Netware 386",
     252    "\x70" "DiskSecure Multi-Boot",
     253    "\x75" "PC/IX",
     254    "\x93" "Amoeba",
     255    "\x94" "Amoeba BBT",       /* (bad block table) */
     256    "\xa7" "NeXTSTEP",
     257    "\xbb" "Boot Wizard hidden",
     258    "\xc1" "DRDOS/sec (FAT-12)",
     259    "\xc4" "DRDOS/sec (FAT-16 < 32M)",
     260    "\xc6" "DRDOS/sec (FAT-16)",
     261    "\xc7" "Syrinx",
     262    "\xda" "Non-FS data",
     263    "\xdb" "CP/M / CTOS / ...",/* CP/M or Concurrent CP/M or
     264                                  Concurrent DOS or CTOS */
     265    "\xde" "Dell Utility",     /* Dell PowerEdge Server utilities */
     266    "\xdf" "BootIt",           /* BootIt EMBRM */
     267    "\xe1" "DOS access",       /* DOS access or SpeedStor 12-bit FAT
     268                                  extended partition */
     269    "\xe3" "DOS R/O",          /* DOS R/O or SpeedStor */
     270    "\xe4" "SpeedStor",        /* SpeedStor 16-bit FAT extended
     271                                  partition < 1024 cyl. */
     272    "\xf1" "SpeedStor",
     273    "\xf4" "SpeedStor",        /* SpeedStor large partition */
     274    "\xfe" "LANstep",          /* SpeedStor >1024 cyl. or LANstep */
     275    "\xff" "BBT",              /* Xenix Bad Block Table */
     276#endif
     277    NULL
     278};
     279
     280
     281/* Globals */
     282
     283struct globals {
     284    char *line_ptr;
     285    char line_buffer[80];
     286    char partname_buffer[80];
     287    jmp_buf listingbuf;
     288    /* Raw disk label. For DOS-type partition tables the MBR,
     289     * with descriptions of the primary partitions. */
     290    char MBRbuffer[MAX_SECTOR_SIZE];
     291    /* Partition tables */
     292    struct pte ptes[MAXIMUM_PARTS];
     293};
     294/* bb_common_bufsiz1 is too small for this on 64 bit CPUs */
     295#define G (*ptr_to_globals)
     296
     297#define line_ptr        (G.line_ptr)
     298#define listingbuf      (G.listingbuf)
     299#define line_buffer     (G.line_buffer)
     300#define partname_buffer (G.partname_buffer)
     301#define MBRbuffer       (G.MBRbuffer)
     302#define ptes            (G.ptes)
     303
     304
     305/* Code */
     306
     307#define IS_EXTENDED(i) \
     308    ((i) == EXTENDED || (i) == WIN98_EXTENDED || (i) == LINUX_EXTENDED)
     309
     310#define cround(n)       (display_in_cyl_units ? ((n)/units_per_sector)+1 : (n))
     311
     312#define scround(x)      (((x)+units_per_sector-1)/units_per_sector)
     313
     314#define pt_offset(b, n) \
     315    ((struct partition *)((b) + 0x1be + (n) * sizeof(struct partition)))
     316
     317#define sector(s)       ((s) & 0x3f)
     318
     319#define cylinder(s, c)  ((c) | (((s) & 0xc0) << 2))
     320
     321#define hsc2sector(h,s,c) \
     322    (sector(s) - 1 + sectors * ((h) + heads * cylinder(s,c)))
     323
     324#define set_hsc(h,s,c,sector) \
     325    do { \
     326        s = sector % sectors + 1;  \
     327        sector /= sectors;         \
     328        h = sector % heads;        \
     329        sector /= heads;           \
     330        c = sector & 0xff;         \
     331        s |= (sector >> 2) & 0xc0; \
     332    } while (0)
     333
     334#if ENABLE_FEATURE_FDISK_WRITABLE
     335/* read line; return 0 or first printable char */
     336static int
     337read_line(const char *prompt)
     338{
     339    int sz;
     340
     341    sz = read_line_input(prompt, line_buffer, sizeof(line_buffer), NULL);
     342    if (sz <= 0)
     343        exit(0); /* Ctrl-D or Ctrl-C */
     344
     345    if (line_buffer[sz-1] == '\n')
     346        line_buffer[--sz] = '\0';
     347
     348    line_ptr = line_buffer;
     349    while (*line_ptr && !isgraph(*line_ptr))
     350        line_ptr++;
     351    return *line_ptr;
     352}
     353#endif
     354
     355/*
     356 * return partition name - uses static storage
     357 */
     358static const char *
     359partname(const char *dev, int pno, int lth)
     360{
     361    const char *p;
     362    int w, wp;
     363    int bufsiz;
     364    char *bufp;
     365
     366    bufp = partname_buffer;
     367    bufsiz = sizeof(partname_buffer);
     368
     369    w = strlen(dev);
     370    p = "";
     371
     372    if (isdigit(dev[w-1]))
     373        p = "p";
     374
     375    /* devfs kludge - note: fdisk partition names are not supposed
     376       to equal kernel names, so there is no reason to do this */
     377    if (strcmp(dev + w - 4, "disc") == 0) {
     378        w -= 4;
     379        p = "part";
     380    }
     381
     382    wp = strlen(p);
     383
     384    if (lth) {
     385        snprintf(bufp, bufsiz, "%*.*s%s%-2u",
     386             lth-wp-2, w, dev, p, pno);
     387    } else {
     388        snprintf(bufp, bufsiz, "%.*s%s%-2u", w, dev, p, pno);
     389    }
     390    return bufp;
     391}
     392
     393#if ENABLE_FEATURE_FDISK_WRITABLE
    254394static void
    255395set_all_unchanged(void)
     
    261401}
    262402
    263 static void
     403static ALWAYS_INLINE void
    264404set_changed(int i)
    265405{
    266406    ptes[i].changed = 1;
    267407}
    268 #endif /* CONFIG_FEATURE_FDISK_WRITABLE */
    269 
    270 #if defined(CONFIG_FEATURE_SGI_LABEL) || defined(CONFIG_FEATURE_OSF_LABEL)
    271 static struct partition *
     408#endif /* FEATURE_FDISK_WRITABLE */
     409
     410static ALWAYS_INLINE struct partition *
    272411get_part_table(int i)
    273412{
    274413    return ptes[i].part_table;
    275414}
    276 #endif
    277415
    278416static const char *
     
    280418{      /* n==1: use singular */
    281419    if (n == 1)
    282         return display_in_cyl_units ? _("cylinder") : _("sector");
    283     else
    284         return display_in_cyl_units ? _("cylinders") : _("sectors");
     420        return display_in_cyl_units ? "cylinder" : "sector";
     421    return display_in_cyl_units ? "cylinders" : "sectors";
    285422}
    286423
    287424static int
    288 valid_part_table_flag(const char *mbuffer) {
    289     const unsigned char *b = (const unsigned char *)mbuffer;
    290     return (b[510] == 0x55 && b[511] == 0xaa);
    291 }
    292 
    293 #ifdef CONFIG_FEATURE_FDISK_WRITABLE
    294 static char  line_buffer[LINE_LENGTH];
    295 
    296 /* read line; return 0 or first char */
     425valid_part_table_flag(const char *mbuffer)
     426{
     427    return (mbuffer[510] == 0x55 && (uint8_t)mbuffer[511] == 0xaa);
     428}
     429
     430#if ENABLE_FEATURE_FDISK_WRITABLE
     431static ALWAYS_INLINE void
     432write_part_table_flag(char *b)
     433{
     434    b[510] = 0x55;
     435    b[511] = 0xaa;
     436}
     437
     438static char
     439read_nonempty(const char *mesg)
     440{
     441    while (!read_line(mesg)) /* repeat */;
     442    return *line_ptr;
     443}
     444
     445static char
     446read_maybe_empty(const char *mesg)
     447{
     448    if (!read_line(mesg)) {
     449        line_ptr = line_buffer;
     450        line_ptr[0] = '\n';
     451        line_ptr[1] = '\0';
     452    }
     453    return line_ptr[0];
     454}
     455
    297456static int
    298 read_line(void)
    299 {
    300     static int got_eof = 0;
    301 
    302     fflush (stdout);         /* requested by niles@scyld.com */
    303     line_ptr = line_buffer;
    304     if (!fgets(line_buffer, LINE_LENGTH, stdin)) {
    305         if (feof(stdin))
    306             got_eof++;      /* user typed ^D ? */
    307         if (got_eof >= 3) {
    308             fprintf(stderr, _("\ngot EOF thrice - exiting..\n"));
    309             exit(1);
    310         }
    311         return 0;
    312     }
    313     while (*line_ptr && !isgraph(*line_ptr))
    314         line_ptr++;
    315     return *line_ptr;
    316 }
    317 
    318 static char
    319 read_char(const char *mesg)
    320 {
    321     do {
    322         fputs(mesg, stdout);
    323     } while (!read_line());
    324     return *line_ptr;
    325 }
    326 
    327 static char
    328 read_chars(const char *mesg)
    329 {
    330     fputs(mesg, stdout);
    331     if (!read_line()) {
    332         *line_ptr = '\n';
    333         line_ptr[1] = 0;
    334     }
    335     return *line_ptr;
    336 }
    337 
    338 static int
    339 read_hex(const struct systypes *sys)
    340 {
    341     int hex;
    342 
     457read_hex(const char *const *sys)
     458{
     459    unsigned long v;
    343460    while (1) {
    344         read_char(_("Hex code (type L to list codes): "));
    345         if (*line_ptr == 'l' || *line_ptr == 'L')
     461        read_nonempty("Hex code (type L to list codes): ");
     462        if (*line_ptr == 'l' || *line_ptr == 'L') {
    346463            list_types(sys);
    347         else if (isxdigit (*line_ptr)) {
    348             hex = 0;
    349             do
    350                 hex = hex << 4 | hex_val(*line_ptr++);
    351             while (isxdigit(*line_ptr));
    352             return hex;
    353         }
    354     }
    355 }
    356 #endif /* CONFIG_FEATURE_FDISK_WRITABLE */
    357 
    358 #ifdef CONFIG_FEATURE_AIX_LABEL
    359 /*
    360  * Copyright (C) Andreas Neuper, Sep 1998.
    361  *      This file may be redistributed under
    362  *      the terms of the GNU Public License.
    363  */
    364 
    365 typedef struct {
    366     unsigned int   magic;        /* expect AIX_LABEL_MAGIC */
    367     unsigned int   fillbytes1[124];
    368     unsigned int   physical_volume_id;
    369     unsigned int   fillbytes2[124];
    370 } aix_partition;
    371 
    372 #define AIX_LABEL_MAGIC         0xc9c2d4c1
    373 #define AIX_LABEL_MAGIC_SWAPPED 0xc1d4c2c9
    374 #define AIX_INFO_MAGIC          0x00072959
    375 #define AIX_INFO_MAGIC_SWAPPED  0x59290700
    376 
    377 #define aixlabel ((aix_partition *)MBRbuffer)
    378 
    379 
    380 /*
    381   Changes:
    382   * 1999-03-20 Arnaldo Carvalho de Melo <acme@conectiva.com.br>
    383   *     Internationalization
    384   *
    385   * 2003-03-20 Phillip Kesling <pkesling@sgi.com>
    386   *      Some fixes
    387 */
    388 
    389 static int aix_other_endian;
    390 static short aix_volumes = 1;
    391 
    392 /*
    393  * only dealing with free blocks here
    394  */
    395 
    396 static void
    397 aix_info(void)
    398 {
    399     puts(
    400         _("\n\tThere is a valid AIX label on this disk.\n"
    401         "\tUnfortunately Linux cannot handle these\n"
    402         "\tdisks at the moment.  Nevertheless some\n"
    403         "\tadvice:\n"
    404         "\t1. fdisk will destroy its contents on write.\n"
    405         "\t2. Be sure that this disk is NOT a still vital\n"
    406         "\t   part of a volume group. (Otherwise you may\n"
    407         "\t   erase the other disks as well, if unmirrored.)\n"
    408         "\t3. Before deleting this physical volume be sure\n"
    409         "\t   to remove the disk logically from your AIX\n"
    410         "\t   machine.  (Otherwise you become an AIXpert).")
    411     );
    412 }
    413 
    414 static int
    415 check_aix_label(void)
    416 {
    417     if (aixlabel->magic != AIX_LABEL_MAGIC &&
    418         aixlabel->magic != AIX_LABEL_MAGIC_SWAPPED) {
    419         current_label_type = 0;
    420         aix_other_endian = 0;
    421         return 0;
    422     }
    423     aix_other_endian = (aixlabel->magic == AIX_LABEL_MAGIC_SWAPPED);
    424     update_units();
    425     current_label_type = label_aix;
    426     partitions = 1016;
    427     aix_volumes = 15;
    428     aix_info();
    429     /*aix_nolabel();*/              /* %% */
    430     /*aix_label = 1;*/              /* %% */
    431     return 1;
    432 }
    433 #endif  /* AIX_LABEL */
    434 
    435 #ifdef CONFIG_FEATURE_OSF_LABEL
    436 /*
    437  * Copyright (c) 1987, 1988 Regents of the University of California.
    438  * All rights reserved.
    439  *
    440  * Redistribution and use in source and binary forms, with or without
    441  * modification, are permitted provided that the following conditions
    442  * are met:
    443  * 1. Redistributions of source code must retain the above copyright
    444  *    notice, this list of conditions and the following disclaimer.
    445  * 2. Redistributions in binary form must reproduce the above copyright
    446  *    notice, this list of conditions and the following disclaimer in the
    447  *    documentation and/or other materials provided with the distribution.
    448  * 3. All advertising materials mentioning features or use of this software
    449  *    must display the following acknowledgment:
    450  *      This product includes software developed by the University of
    451  *      California, Berkeley and its contributors.
    452  * 4. Neither the name of the University nor the names of its contributors
    453  *    may be used to endorse or promote products derived from this software
    454  *    without specific prior written permission.
    455  *
    456  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
    457  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    458  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    459  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
    460  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    461  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
    462  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
    463  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
    464  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
    465  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
    466  * SUCH DAMAGE.
    467  */
    468 
    469 
    470 #ifndef BSD_DISKMAGIC
    471 #define BSD_DISKMAGIC     ((uint32_t) 0x82564557)
    472 #endif
    473 
    474 #ifndef BSD_MAXPARTITIONS
    475 #define BSD_MAXPARTITIONS 16
    476 #endif
    477 
    478 #define BSD_LINUX_BOOTDIR "/usr/ucb/mdec"
    479 
    480 #if defined (i386) || defined (__sparc__) || defined (__arm__) || defined (__m68k__) || defined (__mips__) || defined (__s390__) || defined (__sh__) || defined(__x86_64__)
    481 #define BSD_LABELSECTOR   1
    482 #define BSD_LABELOFFSET   0
    483 #elif defined (__alpha__) || defined (__powerpc__) || defined (__ia64__) || defined (__hppa__)
    484 #define BSD_LABELSECTOR   0
    485 #define BSD_LABELOFFSET   64
    486 #elif defined (__s390__) || defined (__s390x__)
    487 #define BSD_LABELSECTOR   1
    488 #define BSD_LABELOFFSET   0
    489 #else
    490 #error unknown architecture
    491 #endif
    492 
    493 #define BSD_BBSIZE        8192          /* size of boot area, with label */
    494 #define BSD_SBSIZE        8192          /* max size of fs superblock */
    495 
    496 struct xbsd_disklabel {
    497     uint32_t   d_magic;                /* the magic number */
    498     int16_t    d_type;                 /* drive type */
    499     int16_t    d_subtype;              /* controller/d_type specific */
    500     char       d_typename[16];         /* type name, e.g. "eagle" */
    501     char       d_packname[16];                 /* pack identifier */
    502             /* disk geometry: */
    503     uint32_t   d_secsize;              /* # of bytes per sector */
    504     uint32_t   d_nsectors;             /* # of data sectors per track */
    505     uint32_t   d_ntracks;              /* # of tracks per cylinder */
    506     uint32_t   d_ncylinders;           /* # of data cylinders per unit */
    507     uint32_t   d_secpercyl;            /* # of data sectors per cylinder */
    508     uint32_t   d_secperunit;           /* # of data sectors per unit */
    509     /*
    510      * Spares (bad sector replacements) below
    511      * are not counted in d_nsectors or d_secpercyl.
    512      * Spare sectors are assumed to be physical sectors
    513      * which occupy space at the end of each track and/or cylinder.
    514      */
    515     uint16_t   d_sparespertrack;       /* # of spare sectors per track */
    516     uint16_t   d_sparespercyl;         /* # of spare sectors per cylinder */
    517     /*
    518      * Alternate cylinders include maintenance, replacement,
    519      * configuration description areas, etc.
    520      */
    521     uint32_t   d_acylinders;           /* # of alt. cylinders per unit */
    522 
    523             /* hardware characteristics: */
    524     /*
    525      * d_interleave, d_trackskew and d_cylskew describe perturbations
    526      * in the media format used to compensate for a slow controller.
    527      * Interleave is physical sector interleave, set up by the formatter
    528      * or controller when formatting.  When interleaving is in use,
    529      * logically adjacent sectors are not physically contiguous,
    530      * but instead are separated by some number of sectors.
    531      * It is specified as the ratio of physical sectors traversed
    532      * per logical sector.  Thus an interleave of 1:1 implies contiguous
    533      * layout, while 2:1 implies that logical sector 0 is separated
    534      * by one sector from logical sector 1.
    535      * d_trackskew is the offset of sector 0 on track N
    536      * relative to sector 0 on track N-1 on the same cylinder.
    537      * Finally, d_cylskew is the offset of sector 0 on cylinder N
    538      * relative to sector 0 on cylinder N-1.
    539      */
    540     uint16_t   d_rpm;                  /* rotational speed */
    541     uint16_t   d_interleave;           /* hardware sector interleave */
    542     uint16_t   d_trackskew;            /* sector 0 skew, per track */
    543     uint16_t   d_cylskew;              /* sector 0 skew, per cylinder */
    544     uint32_t   d_headswitch;           /* head switch time, usec */
    545     uint32_t   d_trkseek;              /* track-to-track seek, usec */
    546     uint32_t   d_flags;                /* generic flags */
    547 #define NDDATA 5
    548     uint32_t   d_drivedata[NDDATA];    /* drive-type specific information */
    549 #define NSPARE 5
    550     uint32_t   d_spare[NSPARE];        /* reserved for future use */
    551     uint32_t   d_magic2;               /* the magic number (again) */
    552     uint16_t   d_checksum;             /* xor of data incl. partitions */
    553             /* filesystem and partition information: */
    554     uint16_t   d_npartitions;          /* number of partitions in following */
    555     uint32_t   d_bbsize;               /* size of boot area at sn0, bytes */
    556     uint32_t   d_sbsize;               /* max size of fs superblock, bytes */
    557     struct xbsd_partition    {      /* the partition table */
    558         uint32_t   p_size;         /* number of sectors in partition */
    559         uint32_t   p_offset;       /* starting sector */
    560         uint32_t   p_fsize;        /* filesystem basic fragment size */
    561         uint8_t    p_fstype;       /* filesystem type, see below */
    562         uint8_t    p_frag;         /* filesystem fragments per block */
    563         uint16_t   p_cpg;          /* filesystem cylinders per group */
    564     } d_partitions[BSD_MAXPARTITIONS]; /* actually may be more */
    565 };
    566 
    567 /* d_type values: */
    568 #define BSD_DTYPE_SMD           1               /* SMD, XSMD; VAX hp/up */
    569 #define BSD_DTYPE_MSCP          2               /* MSCP */
    570 #define BSD_DTYPE_DEC           3               /* other DEC (rk, rl) */
    571 #define BSD_DTYPE_SCSI          4               /* SCSI */
    572 #define BSD_DTYPE_ESDI          5               /* ESDI interface */
    573 #define BSD_DTYPE_ST506         6               /* ST506 etc. */
    574 #define BSD_DTYPE_HPIB          7               /* CS/80 on HP-IB */
    575 #define BSD_DTYPE_HPFL          8               /* HP Fiber-link */
    576 #define BSD_DTYPE_FLOPPY        10              /* floppy */
    577 
    578 /* d_subtype values: */
    579 #define BSD_DSTYPE_INDOSPART    0x8             /* is inside dos partition */
    580 #define BSD_DSTYPE_DOSPART(s)   ((s) & 3)       /* dos partition number */
    581 #define BSD_DSTYPE_GEOMETRY     0x10            /* drive params in label */
    582 
    583 #ifdef DKTYPENAMES
    584 static const char * const xbsd_dktypenames[] = {
    585     "unknown",
    586     "SMD",
    587     "MSCP",
    588     "old DEC",
    589     "SCSI",
    590     "ESDI",
    591     "ST506",
    592     "HP-IB",
    593     "HP-FL",
    594     "type 9",
    595     "floppy",
    596     0
    597 };
    598 #define BSD_DKMAXTYPES  (sizeof(xbsd_dktypenames) / sizeof(xbsd_dktypenames[0]) - 1)
    599 #endif
    600 
    601 /*
    602  * Filesystem type and version.
    603  * Used to interpret other filesystem-specific
    604  * per-partition information.
    605  */
    606 #define BSD_FS_UNUSED   0               /* unused */
    607 #define BSD_FS_SWAP     1               /* swap */
    608 #define BSD_FS_V6       2               /* Sixth Edition */
    609 #define BSD_FS_V7       3               /* Seventh Edition */
    610 #define BSD_FS_SYSV     4               /* System V */
    611 #define BSD_FS_V71K     5               /* V7 with 1K blocks (4.1, 2.9) */
    612 #define BSD_FS_V8       6               /* Eighth Edition, 4K blocks */
    613 #define BSD_FS_BSDFFS   7               /* 4.2BSD fast file system */
    614 #define BSD_FS_BSDLFS   9               /* 4.4BSD log-structured file system */
    615 #define BSD_FS_OTHER    10              /* in use, but unknown/unsupported */
    616 #define BSD_FS_HPFS     11              /* OS/2 high-performance file system */
    617 #define BSD_FS_ISO9660  12              /* ISO-9660 filesystem (cdrom) */
    618 #define BSD_FS_ISOFS    BSD_FS_ISO9660
    619 #define BSD_FS_BOOT     13              /* partition contains bootstrap */
    620 #define BSD_FS_ADOS     14              /* AmigaDOS fast file system */
    621 #define BSD_FS_HFS      15              /* Macintosh HFS */
    622 #define BSD_FS_ADVFS    16              /* Digital Unix AdvFS */
    623 
    624 /* this is annoying, but it's also the way it is :-( */
    625 #ifdef __alpha__
    626 #define BSD_FS_EXT2     8               /* ext2 file system */
    627 #else
    628 #define BSD_FS_MSDOS    8               /* MS-DOS file system */
    629 #endif
    630 
    631 #ifdef  DKTYPENAMES
    632 static const struct systypes xbsd_fstypes[] = {
    633     { "\x00" "unused" },            /* BSD_FS_UNUSED  */
    634     { "\x01" "swap" },              /* BSD_FS_SWAP    */
    635     { "\x02" "Version 6" },         /* BSD_FS_V6      */
    636     { "\x03" "Version 7" },         /* BSD_FS_V7      */
    637     { "\x04" "System V" },          /* BSD_FS_SYSV    */
    638     { "\x05" "4.1BSD" },            /* BSD_FS_V71K    */
    639     { "\x06" "Eighth Edition" },    /* BSD_FS_V8      */
    640     { "\x07" "4.2BSD" },            /* BSD_FS_BSDFFS  */
    641 #ifdef __alpha__
    642     { "\x08" "ext2" },              /* BSD_FS_EXT2    */
    643 #else
    644     { "\x08" "MS-DOS" },            /* BSD_FS_MSDOS   */
    645 #endif
    646     { "\x09" "4.4LFS" },            /* BSD_FS_BSDLFS  */
    647     { "\x0a" "unknown" },           /* BSD_FS_OTHER   */
    648     { "\x0b" "HPFS" },              /* BSD_FS_HPFS    */
    649     { "\x0c" "ISO-9660" },          /* BSD_FS_ISO9660 */
    650     { "\x0d" "boot" },              /* BSD_FS_BOOT    */
    651     { "\x0e" "ADOS" },              /* BSD_FS_ADOS    */
    652     { "\x0f" "HFS" },               /* BSD_FS_HFS     */
    653     { "\x10" "AdvFS" },             /* BSD_FS_ADVFS   */
    654     { NULL }
    655 };
    656 #define BSD_FSMAXTYPES (SIZE(xbsd_fstypes)-1)
    657 
    658 #endif
    659 
    660 /*
    661  * flags shared by various drives:
    662  */
    663 #define BSD_D_REMOVABLE 0x01            /* removable media */
    664 #define BSD_D_ECC       0x02            /* supports ECC */
    665 #define BSD_D_BADSECT   0x04            /* supports bad sector forw. */
    666 #define BSD_D_RAMDISK   0x08            /* disk emulator */
    667 #define BSD_D_CHAIN     0x10            /* can do back-back transfers */
    668 #define BSD_D_DOSPART   0x20            /* within MSDOS partition */
    669 
    670 #endif /* OSF_LABEL */
    671 
    672 /*
    673  * Copyright (C) Andreas Neuper, Sep 1998.
    674  *      This file may be modified and redistributed under
    675  *      the terms of the GNU Public License.
    676  */
    677 
    678 struct device_parameter { /* 48 bytes */
    679     unsigned char  skew;
    680     unsigned char  gap1;
    681     unsigned char  gap2;
    682     unsigned char  sparecyl;
    683     unsigned short pcylcount;
    684     unsigned short head_vol0;
    685     unsigned short ntrks;   /* tracks in cyl 0 or vol 0 */
    686     unsigned char  cmd_tag_queue_depth;
    687     unsigned char  unused0;
    688     unsigned short unused1;
    689     unsigned short nsect;   /* sectors/tracks in cyl 0 or vol 0 */
    690     unsigned short bytes;
    691     unsigned short ilfact;
    692     unsigned int   flags;           /* controller flags */
    693     unsigned int   datarate;
    694     unsigned int   retries_on_error;
    695     unsigned int   ms_per_word;
    696     unsigned short xylogics_gap1;
    697     unsigned short xylogics_syncdelay;
    698     unsigned short xylogics_readdelay;
    699     unsigned short xylogics_gap2;
    700     unsigned short xylogics_readgate;
    701     unsigned short xylogics_writecont;
    702 };
    703 
    704 #define SGI_VOLHDR      0x00
    705 /* 1 and 2 were used for drive types no longer supported by SGI */
    706 #define SGI_SWAP        0x03
    707 /* 4 and 5 were for filesystem types SGI haven't ever supported on MIPS CPUs */
    708 #define SGI_VOLUME      0x06
    709 #define SGI_EFS         0x07
    710 #define SGI_LVOL        0x08
    711 #define SGI_RLVOL       0x09
    712 #define SGI_XFS         0x0a
    713 #define SGI_XFSLOG      0x0b
    714 #define SGI_XLV         0x0c
    715 #define SGI_XVM         0x0d
    716 #define ENTIRE_DISK     SGI_VOLUME
    717 /*
    718  * controller flags
    719  */
    720 #define SECTOR_SLIP     0x01
    721 #define SECTOR_FWD      0x02
    722 #define TRACK_FWD       0x04
    723 #define TRACK_MULTIVOL  0x08
    724 #define IGNORE_ERRORS   0x10
    725 #define RESEEK          0x20
    726 #define ENABLE_CMDTAGQ  0x40
    727 
    728 typedef struct {
    729     unsigned int   magic;            /* expect SGI_LABEL_MAGIC */
    730     unsigned short boot_part;        /* active boot partition */
    731     unsigned short swap_part;        /* active swap partition */
    732     unsigned char  boot_file[16];    /* name of the bootfile */
    733     struct device_parameter devparam;       /*  1 * 48 bytes */
    734     struct volume_directory {               /* 15 * 16 bytes */
    735         unsigned char vol_file_name[8]; /* a character array */
    736         unsigned int  vol_file_start;   /* number of logical block */
    737         unsigned int  vol_file_size;    /* number of bytes */
    738     } directory[15];
    739     struct sgi_partition {                  /* 16 * 12 bytes */
    740         unsigned int num_sectors;       /* number of blocks */
    741         unsigned int start_sector;      /* must be cylinder aligned */
    742         unsigned int id;
    743     } partitions[16];
    744     unsigned int   csum;
    745     unsigned int   fillbytes;
    746 } sgi_partition;
    747 
    748 typedef struct {
    749     unsigned int   magic;           /* looks like a magic number */
    750     unsigned int   a2;
    751     unsigned int   a3;
    752     unsigned int   a4;
    753     unsigned int   b1;
    754     unsigned short b2;
    755     unsigned short b3;
    756     unsigned int   c[16];
    757     unsigned short d[3];
    758     unsigned char  scsi_string[50];
    759     unsigned char  serial[137];
    760     unsigned short check1816;
    761     unsigned char  installer[225];
    762 } sgiinfo;
    763 
    764 #define SGI_LABEL_MAGIC         0x0be5a941
    765 #define SGI_LABEL_MAGIC_SWAPPED 0x41a9e50b
    766 #define SGI_INFO_MAGIC          0x00072959
    767 #define SGI_INFO_MAGIC_SWAPPED  0x59290700
    768 #define SGI_SSWAP16(x) (sgi_other_endian ? __swap16(x) \
    769                  : (uint16_t)(x))
    770 #define SGI_SSWAP32(x) (sgi_other_endian ? __swap32(x) \
    771                  : (uint32_t)(x))
    772 
    773 #define sgilabel ((sgi_partition *)MBRbuffer)
    774 #define sgiparam (sgilabel->devparam)
     464            continue;
     465        }
     466        v = bb_strtoul(line_ptr, NULL, 16);
     467        if (v > 0xff)
     468            /* Bad input also triggers this */
     469            continue;
     470        return v;
     471    }
     472}
     473#endif /* FEATURE_FDISK_WRITABLE */
     474
     475#include "fdisk_aix.c"
    775476
    776477typedef struct {
     
    794495    unsigned short nsect;      /* Sectors per track */
    795496    unsigned char spare3[4];   /* Even more magic... */
    796     struct sun_partition {
     497    struct sun_partinfo {
    797498        uint32_t start_cylinder;
    798499        uint32_t num_sectors;
     
    801502    unsigned short csum;       /* Label xor'd checksum */
    802503} sun_partition;
    803 
    804 
    805 #define SUN_LABEL_MAGIC          0xDABE
    806 #define SUN_LABEL_MAGIC_SWAPPED  0xBEDA
    807504#define sunlabel ((sun_partition *)MBRbuffer)
    808 #define SUN_SSWAP16(x) (sun_other_endian ? __swap16(x) \
    809                  : (uint16_t)(x))
    810 #define SUN_SSWAP32(x) (sun_other_endian ? __swap32(x) \
    811                  : (uint32_t)(x))
    812 
    813 
    814 #ifdef CONFIG_FEATURE_OSF_LABEL
    815 /*
    816    Changes:
    817    19990319 - Arnaldo Carvalho de Melo <acme@conectiva.com.br> - i18n/nls
    818 
    819    20000101 - David Huggins-Daines <dhuggins@linuxcare.com> - Better
    820    support for OSF/1 disklabels on Alpha.
    821    Also fixed unaligned accesses in alpha_bootblock_checksum()
    822 */
    823 
    824 #define FREEBSD_PARTITION       0xa5
    825 #define NETBSD_PARTITION        0xa9
    826 
    827 static void xbsd_delete_part(void);
    828 static void xbsd_new_part(void);
    829 static void xbsd_write_disklabel(void);
    830 static int xbsd_create_disklabel(void);
    831 static void xbsd_edit_disklabel(void);
    832 static void xbsd_write_bootstrap(void);
    833 static void xbsd_change_fstype(void);
    834 static int xbsd_get_part_index(int max);
    835 static int xbsd_check_new_partition(int *i);
    836 static void xbsd_list_types(void);
    837 static u_short xbsd_dkcksum(struct xbsd_disklabel *lp);
    838 static int xbsd_initlabel(struct partition *p, struct xbsd_disklabel *d);
    839 static int xbsd_readlabel(struct partition *p, struct xbsd_disklabel *d);
    840 static int xbsd_writelabel(struct partition *p, struct xbsd_disklabel *d);
    841 
    842 #if defined (__alpha__)
    843 static void alpha_bootblock_checksum(char *boot);
    844 #endif
    845 
    846 #if !defined (__alpha__)
    847 static int xbsd_translate_fstype(int linux_type);
    848 static void xbsd_link_part(void);
    849 static struct partition *xbsd_part;
    850 static int xbsd_part_index;
    851 #endif
    852 
    853 #if defined (__alpha__)
    854 /* We access this through a uint64_t * when checksumming */
    855 static char disklabelbuffer[BSD_BBSIZE] ATTRIBUTE_ALIGNED(8);
    856 #else
    857 static char disklabelbuffer[BSD_BBSIZE];
    858 #endif
    859 
    860 static struct xbsd_disklabel xbsd_dlabel;
    861 
    862 #define bsd_cround(n) \
    863     (display_in_cyl_units ? ((n)/xbsd_dlabel.d_secpercyl) + 1 : (n))
    864 
    865 /*
    866  * Test whether the whole disk has BSD disk label magic.
    867  *
    868  * Note: often reformatting with DOS-type label leaves the BSD magic,
    869  * so this does not mean that there is a BSD disk label.
    870  */
    871 static int
    872 check_osf_label(void)
    873 {
    874     if (xbsd_readlabel(NULL, &xbsd_dlabel) == 0)
    875         return 0;
    876     return 1;
    877 }
    878 
    879 static void xbsd_print_disklabel(int);
    880 
    881 static int
    882 btrydev(const char * dev)
    883 {
    884     if (xbsd_readlabel (NULL, &xbsd_dlabel) == 0)
    885         return -1;
    886     printf(_("\nBSD label for device: %s\n"), dev);
    887     xbsd_print_disklabel (0);
    888     return 0;
    889 }
    890 
    891 static void
    892 bmenu(void)
    893 {
    894     puts (_("Command action"));
    895     puts (_("\td\tdelete a BSD partition"));
    896     puts (_("\te\tedit drive data"));
    897     puts (_("\ti\tinstall bootstrap"));
    898     puts (_("\tl\tlist known filesystem types"));
    899     puts (_("\tm\tprint this menu"));
    900     puts (_("\tn\tadd a new BSD partition"));
    901     puts (_("\tp\tprint BSD partition table"));
    902     puts (_("\tq\tquit without saving changes"));
    903     puts (_("\tr\treturn to main menu"));
    904     puts (_("\ts\tshow complete disklabel"));
    905     puts (_("\tt\tchange a partition's filesystem id"));
    906     puts (_("\tu\tchange units (cylinders/sectors)"));
    907     puts (_("\tw\twrite disklabel to disk"));
    908 #if !defined (__alpha__)
    909     puts (_("\tx\tlink BSD partition to non-BSD partition"));
    910 #endif
    911 }
    912 
    913 #if !defined (__alpha__)
    914 static int
    915 hidden(int type)
    916 {
    917     return type ^ 0x10;
    918 }
    919 
    920 static int
    921 is_bsd_partition_type(int type)
    922 {
    923     return (type == FREEBSD_PARTITION ||
    924         type == hidden(FREEBSD_PARTITION) ||
    925         type == NETBSD_PARTITION ||
    926         type == hidden(NETBSD_PARTITION));
    927 }
    928 #endif
    929 
    930 static void
    931 bselect(void)
    932 {
    933 #if !defined (__alpha__)
    934     int t, ss;
    935     struct partition *p;
    936 
    937     for (t = 0; t < 4; t++) {
    938         p = get_part_table(t);
    939         if (p && is_bsd_partition_type(p->sys_ind)) {
    940             xbsd_part = p;
    941             xbsd_part_index = t;
    942             ss = get_start_sect(xbsd_part);
    943             if (ss == 0) {
    944                 fprintf(stderr, _("Partition %s has invalid starting sector 0.\n"),
    945                     partname(disk_device, t+1, 0));
    946                 return;
    947             }
    948                 printf(_("Reading disklabel of %s at sector %d.\n"),
    949                     partname(disk_device, t+1, 0), ss + BSD_LABELSECTOR);
    950             if (xbsd_readlabel(xbsd_part, &xbsd_dlabel) == 0)
    951                 if (xbsd_create_disklabel() == 0)
    952                     return;
    953                 break;
    954         }
    955     }
    956 
    957     if (t == 4) {
    958         printf(_("There is no *BSD partition on %s.\n"), disk_device);
    959         return;
    960     }
    961 
    962 #elif defined (__alpha__)
    963 
    964     if (xbsd_readlabel(NULL, &xbsd_dlabel) == 0)
    965         if (xbsd_create_disklabel() == 0)
    966             exit (EXIT_SUCCESS);
    967 
    968 #endif
    969 
    970     while (1) {
    971         putchar('\n');
    972         switch (tolower(read_char(_("BSD disklabel command (m for help): ")))) {
    973         case 'd':
    974             xbsd_delete_part();
    975             break;
    976         case 'e':
    977             xbsd_edit_disklabel();
    978             break;
    979         case 'i':
    980             xbsd_write_bootstrap();
    981             break;
    982         case 'l':
    983             xbsd_list_types();
    984             break;
    985         case 'n':
    986             xbsd_new_part();
    987             break;
    988         case 'p':
    989             xbsd_print_disklabel(0);
    990             break;
    991         case 'q':
    992             close(fd);
    993             exit(EXIT_SUCCESS);
    994         case 'r':
    995             return;
    996         case 's':
    997             xbsd_print_disklabel(1);
    998             break;
    999         case 't':
    1000             xbsd_change_fstype();
    1001             break;
    1002         case 'u':
    1003             change_units();
    1004             break;
    1005         case 'w':
    1006             xbsd_write_disklabel();
    1007             break;
    1008 #if !defined (__alpha__)
    1009         case 'x':
    1010             xbsd_link_part();
    1011             break;
    1012 #endif
    1013         default:
    1014             bmenu();
    1015             break;
    1016         }
    1017     }
    1018 }
    1019 
    1020 static void
    1021 xbsd_delete_part(void)
    1022 {
    1023     int i;
    1024 
    1025     i = xbsd_get_part_index(xbsd_dlabel.d_npartitions);
    1026     xbsd_dlabel.d_partitions[i].p_size   = 0;
    1027     xbsd_dlabel.d_partitions[i].p_offset = 0;
    1028     xbsd_dlabel.d_partitions[i].p_fstype = BSD_FS_UNUSED;
    1029     if (xbsd_dlabel.d_npartitions == i + 1)
    1030         while (xbsd_dlabel.d_partitions[xbsd_dlabel.d_npartitions-1].p_size == 0)
    1031             xbsd_dlabel.d_npartitions--;
    1032 }
    1033 
    1034 static void
    1035 xbsd_new_part(void)
    1036 {
    1037     off_t begin, end;
    1038     char mesg[256];
    1039     int i;
    1040 
    1041     if (!xbsd_check_new_partition(&i))
    1042         return;
    1043 
    1044 #if !defined (__alpha__) && !defined (__powerpc__) && !defined (__hppa__)
    1045     begin = get_start_sect(xbsd_part);
    1046     end = begin + get_nr_sects(xbsd_part) - 1;
    1047 #else
    1048     begin = 0;
    1049     end = xbsd_dlabel.d_secperunit - 1;
    1050 #endif
    1051 
    1052     snprintf(mesg, sizeof(mesg), _("First %s"), str_units(SINGULAR));
    1053     begin = read_int(bsd_cround(begin), bsd_cround(begin), bsd_cround(end),
    1054         0, mesg);
    1055 
    1056     if (display_in_cyl_units)
    1057         begin = (begin - 1) * xbsd_dlabel.d_secpercyl;
    1058 
    1059     snprintf(mesg, sizeof(mesg), _("Last %s or +size or +sizeM or +sizeK"),
    1060         str_units(SINGULAR));
    1061     end = read_int(bsd_cround (begin), bsd_cround (end), bsd_cround (end),
    1062         bsd_cround (begin), mesg);
    1063 
    1064     if (display_in_cyl_units)
    1065         end = end * xbsd_dlabel.d_secpercyl - 1;
    1066 
    1067     xbsd_dlabel.d_partitions[i].p_size   = end - begin + 1;
    1068     xbsd_dlabel.d_partitions[i].p_offset = begin;
    1069     xbsd_dlabel.d_partitions[i].p_fstype = BSD_FS_UNUSED;
    1070 }
    1071 
    1072 static void
    1073 xbsd_print_disklabel(int show_all)
    1074 {
    1075     struct xbsd_disklabel *lp = &xbsd_dlabel;
    1076     struct xbsd_partition *pp;
    1077     int i, j;
    1078 
    1079     if (show_all) {
    1080 #if defined (__alpha__)
    1081         printf("# %s:\n", disk_device);
    1082 #else
    1083         printf("# %s:\n", partname(disk_device, xbsd_part_index+1, 0));
    1084 #endif
    1085         if ((unsigned) lp->d_type < BSD_DKMAXTYPES)
    1086             printf(_("type: %s\n"), xbsd_dktypenames[lp->d_type]);
    1087         else
    1088             printf(_("type: %d\n"), lp->d_type);
    1089         printf(_("disk: %.*s\n"), (int) sizeof(lp->d_typename), lp->d_typename);
    1090         printf(_("label: %.*s\n"), (int) sizeof(lp->d_packname), lp->d_packname);
    1091         printf(_("flags:"));
    1092         if (lp->d_flags & BSD_D_REMOVABLE)
    1093             printf(_(" removable"));
    1094         if (lp->d_flags & BSD_D_ECC)
    1095             printf(_(" ecc"));
    1096         if (lp->d_flags & BSD_D_BADSECT)
    1097             printf(_(" badsect"));
    1098         printf("\n");
    1099         /* On various machines the fields of *lp are short/int/long */
    1100         /* In order to avoid problems, we cast them all to long. */
    1101         printf(_("bytes/sector: %ld\n"), (long) lp->d_secsize);
    1102         printf(_("sectors/track: %ld\n"), (long) lp->d_nsectors);
    1103         printf(_("tracks/cylinder: %ld\n"), (long) lp->d_ntracks);
    1104         printf(_("sectors/cylinder: %ld\n"), (long) lp->d_secpercyl);
    1105         printf(_("cylinders: %ld\n"), (long) lp->d_ncylinders);
    1106         printf(_("rpm: %d\n"), lp->d_rpm);
    1107         printf(_("interleave: %d\n"), lp->d_interleave);
    1108         printf(_("trackskew: %d\n"), lp->d_trackskew);
    1109         printf(_("cylinderskew: %d\n"), lp->d_cylskew);
    1110         printf(_("headswitch: %ld\t\t# milliseconds\n"),
    1111             (long) lp->d_headswitch);
    1112         printf(_("track-to-track seek: %ld\t# milliseconds\n"),
    1113             (long) lp->d_trkseek);
    1114         printf(_("drivedata: "));
    1115         for (i = NDDATA - 1; i >= 0; i--)
    1116             if (lp->d_drivedata[i])
    1117                 break;
    1118         if (i < 0)
    1119             i = 0;
    1120         for (j = 0; j <= i; j++)
    1121             printf("%ld ", (long) lp->d_drivedata[j]);
    1122     }
    1123     printf(_("\n%d partitions:\n"), lp->d_npartitions);
    1124     printf(_("#       start       end      size     fstype   [fsize bsize   cpg]\n"));
    1125     pp = lp->d_partitions;
    1126     for (i = 0; i < lp->d_npartitions; i++, pp++) {
    1127         if (pp->p_size) {
    1128             if (display_in_cyl_units && lp->d_secpercyl) {
    1129                 printf("  %c: %8ld%c %8ld%c %8ld%c  ",
    1130                     'a' + i,
    1131                     (long) pp->p_offset / lp->d_secpercyl + 1,
    1132                     (pp->p_offset % lp->d_secpercyl) ? '*' : ' ',
    1133                     (long) (pp->p_offset + pp->p_size + lp->d_secpercyl - 1) / lp->d_secpercyl,
    1134                     ((pp->p_offset + pp->p_size) % lp->d_secpercyl) ? '*' : ' ',
    1135                     (long) pp->p_size / lp->d_secpercyl,
    1136                     (pp->p_size % lp->d_secpercyl) ? '*' : ' '
    1137                 );
    1138             } else {
    1139                 printf("  %c: %8ld  %8ld  %8ld   ",
    1140                     'a' + i,
    1141                     (long) pp->p_offset,
    1142                     (long) pp->p_offset + pp->p_size - 1,
    1143                     (long) pp->p_size
    1144                 );
    1145             }
    1146 
    1147             if ((unsigned) pp->p_fstype < BSD_FSMAXTYPES)
    1148                 printf("%8.8s", xbsd_fstypes[pp->p_fstype].name);
    1149             else
    1150                 printf("%8x", pp->p_fstype);
    1151 
    1152             switch (pp->p_fstype) {
    1153             case BSD_FS_UNUSED:
    1154                 printf("    %5ld %5ld %5.5s ",
    1155                     (long) pp->p_fsize, (long) pp->p_fsize * pp->p_frag, "");
    1156                 break;
    1157             case BSD_FS_BSDFFS:
    1158                 printf("    %5ld %5ld %5d ",
    1159                     (long) pp->p_fsize, (long) pp->p_fsize * pp->p_frag, pp->p_cpg);
    1160                 break;
    1161             default:
    1162                 printf("%22.22s", "");
    1163                 break;
    1164             }
    1165             printf("\n");
    1166         }
    1167     }
    1168 }
    1169 
    1170 static void
    1171 xbsd_write_disklabel(void)
    1172 {
    1173 #if defined (__alpha__)
    1174     printf(_("Writing disklabel to %s.\n"), disk_device);
    1175     xbsd_writelabel(NULL, &xbsd_dlabel);
    1176 #else
    1177     printf(_("Writing disklabel to %s.\n"),
    1178         partname(disk_device, xbsd_part_index + 1, 0));
    1179     xbsd_writelabel(xbsd_part, &xbsd_dlabel);
    1180 #endif
    1181     reread_partition_table(0);      /* no exit yet */
    1182 }
    1183 
    1184 static int
    1185 xbsd_create_disklabel(void)
    1186 {
    1187     char c;
    1188 
    1189 #if defined (__alpha__)
    1190     fprintf(stderr, _("%s contains no disklabel.\n"), disk_device);
    1191 #else
    1192     fprintf(stderr, _("%s contains no disklabel.\n"),
    1193         partname(disk_device, xbsd_part_index + 1, 0));
    1194 #endif
    1195 
    1196     while (1) {
    1197         c = read_char(_("Do you want to create a disklabel? (y/n) "));
    1198         if (c == 'y' || c == 'Y') {
    1199             if (xbsd_initlabel(
    1200 #if defined (__alpha__) || defined (__powerpc__) || defined (__hppa__) || \
    1201     defined (__s390__) || defined (__s390x__)
    1202                 NULL, &xbsd_dlabel
    1203 #else
    1204                 xbsd_part, &xbsd_dlabel/* not used, xbsd_part_index*/
    1205 #endif
    1206                 ) == 1) {
    1207                 xbsd_print_disklabel (1);
    1208                 return 1;
    1209             } else
    1210                 return 0;
    1211         } else if (c == 'n')
    1212             return 0;
    1213     }
    1214 }
    1215 
    1216 static int
    1217 edit_int(int def, char *mesg)
    1218 {
    1219     do {
    1220         fputs(mesg, stdout);
    1221         printf(" (%d): ", def);
    1222         if (!read_line())
    1223             return def;
    1224     }
    1225     while (!isdigit(*line_ptr));    /* FIXME: ?!! */
    1226     return atoi(line_ptr);
    1227 }
    1228 
    1229 static void
    1230 xbsd_edit_disklabel(void)
    1231 {
    1232     struct xbsd_disklabel *d;
    1233 
    1234     d = &xbsd_dlabel;
    1235 
    1236 #if defined (__alpha__) || defined (__ia64__)
    1237     d->d_secsize    = (u_long) edit_int((u_long) d->d_secsize     ,_("bytes/sector"));
    1238     d->d_nsectors   = (u_long) edit_int((u_long) d->d_nsectors    ,_("sectors/track"));
    1239     d->d_ntracks    = (u_long) edit_int((u_long) d->d_ntracks     ,_("tracks/cylinder"));
    1240     d->d_ncylinders = (u_long) edit_int((u_long) d->d_ncylinders  ,_("cylinders"));
    1241 #endif
    1242 
    1243   /* d->d_secpercyl can be != d->d_nsectors * d->d_ntracks */
    1244     while (1) {
    1245         d->d_secpercyl = (u_long) edit_int((u_long) d->d_nsectors * d->d_ntracks,
    1246                 _("sectors/cylinder"));
    1247         if (d->d_secpercyl <= d->d_nsectors * d->d_ntracks)
    1248             break;
    1249 
    1250         printf(_("Must be <= sectors/track * tracks/cylinder (default).\n"));
    1251     }
    1252     d->d_rpm        = (u_short) edit_int((u_short) d->d_rpm       ,_("rpm"));
    1253     d->d_interleave = (u_short) edit_int((u_short) d->d_interleave,_("interleave"));
    1254     d->d_trackskew  = (u_short) edit_int((u_short) d->d_trackskew ,_("trackskew"));
    1255     d->d_cylskew    = (u_short) edit_int((u_short) d->d_cylskew   ,_("cylinderskew"));
    1256     d->d_headswitch = (u_long) edit_int((u_long) d->d_headswitch  ,_("headswitch"));
    1257     d->d_trkseek    = (u_long) edit_int((u_long) d->d_trkseek     ,_("track-to-track seek"));
    1258 
    1259     d->d_secperunit = d->d_secpercyl * d->d_ncylinders;
    1260 }
    1261 
    1262 static int
    1263 xbsd_get_bootstrap (char *path, void *ptr, int size)
    1264 {
    1265     int fdb;
    1266 
    1267     if ((fdb = open (path, O_RDONLY)) < 0) {
    1268         perror(path);
    1269         return 0;
    1270     }
    1271     if (read(fdb, ptr, size) < 0) {
    1272         perror(path);
    1273         close(fdb);
    1274         return 0;
    1275     }
    1276     printf(" ... %s\n", path);
    1277     close(fdb);
    1278     return 1;
    1279 }
    1280 
    1281 static void
    1282 sync_disks(void)
    1283 {
    1284     printf(_("\nSyncing disks.\n"));
    1285     sync();
    1286     sleep(4); /* What? */
    1287 }
    1288 
    1289 static void
    1290 xbsd_write_bootstrap(void)
    1291 {
    1292     char *bootdir = BSD_LINUX_BOOTDIR;
    1293     char path[MAXPATHLEN];
    1294     char *dkbasename;
    1295     struct xbsd_disklabel dl;
    1296     char *d, *p, *e;
    1297     int sector;
    1298 
    1299     if (xbsd_dlabel.d_type == BSD_DTYPE_SCSI)
    1300         dkbasename = "sd";
    1301     else
    1302         dkbasename = "wd";
    1303 
    1304     printf(_("Bootstrap: %sboot -> boot%s (%s): "),
    1305         dkbasename, dkbasename, dkbasename);
    1306     if (read_line()) {
    1307         line_ptr[strlen(line_ptr)-1] = '\0';
    1308         dkbasename = line_ptr;
    1309     }
    1310     snprintf(path, sizeof(path), "%s/%sboot", bootdir, dkbasename);
    1311     if (!xbsd_get_bootstrap(path, disklabelbuffer, (int) xbsd_dlabel.d_secsize))
    1312         return;
    1313 
    1314 /* We need a backup of the disklabel (xbsd_dlabel might have changed). */
    1315     d = &disklabelbuffer[BSD_LABELSECTOR * SECTOR_SIZE];
    1316     memmove(&dl, d, sizeof(struct xbsd_disklabel));
    1317 
    1318 /* The disklabel will be overwritten by 0's from bootxx anyway */
    1319     memset(d, 0, sizeof(struct xbsd_disklabel));
    1320 
    1321     snprintf(path, sizeof(path), "%s/boot%s", bootdir, dkbasename);
    1322     if (!xbsd_get_bootstrap (path, &disklabelbuffer[xbsd_dlabel.d_secsize],
    1323               (int) xbsd_dlabel.d_bbsize - xbsd_dlabel.d_secsize))
    1324         return;
    1325 
    1326     e = d + sizeof(struct xbsd_disklabel);
    1327     for (p = d; p < e; p++)
    1328         if (*p) {
    1329             fprintf(stderr, _("Bootstrap overlaps with disk label!\n"));
    1330             exit(EXIT_FAILURE);
    1331         }
    1332 
    1333     memmove(d, &dl, sizeof(struct xbsd_disklabel));
    1334 
    1335 #if defined (__powerpc__) || defined (__hppa__)
    1336     sector = 0;
    1337 #elif defined (__alpha__)
    1338     sector = 0;
    1339     alpha_bootblock_checksum(disklabelbuffer);
    1340 #else
    1341     sector = get_start_sect(xbsd_part);
    1342 #endif
    1343 
    1344     if (lseek(fd, sector * SECTOR_SIZE, SEEK_SET) == -1)
    1345         fdisk_fatal(unable_to_seek);
    1346     if (BSD_BBSIZE != write(fd, disklabelbuffer, BSD_BBSIZE))
    1347         fdisk_fatal(unable_to_write);
    1348 
    1349 #if defined (__alpha__)
    1350     printf(_("Bootstrap installed on %s.\n"), disk_device);
    1351 #else
    1352     printf(_("Bootstrap installed on %s.\n"),
    1353         partname (disk_device, xbsd_part_index+1, 0));
    1354 #endif
    1355 
    1356     sync_disks();
    1357 }
    1358 
    1359 static void
    1360 xbsd_change_fstype(void)
    1361 {
    1362     int i;
    1363 
    1364     i = xbsd_get_part_index(xbsd_dlabel.d_npartitions);
    1365     xbsd_dlabel.d_partitions[i].p_fstype = read_hex(xbsd_fstypes);
    1366 }
    1367 
    1368 static int
    1369 xbsd_get_part_index(int max)
    1370 {
    1371     char prompt[256];
    1372     char l;
    1373 
    1374     snprintf(prompt, sizeof(prompt), _("Partition (a-%c): "), 'a' + max - 1);
    1375     do
    1376             l = tolower(read_char(prompt));
    1377     while (l < 'a' || l > 'a' + max - 1);
    1378     return l - 'a';
    1379 }
    1380 
    1381 static int
    1382 xbsd_check_new_partition(int *i)
    1383 {
    1384     /* room for more? various BSD flavours have different maxima */
    1385     if (xbsd_dlabel.d_npartitions == BSD_MAXPARTITIONS) {
    1386         int t;
    1387 
    1388         for (t = 0; t < BSD_MAXPARTITIONS; t++)
    1389             if (xbsd_dlabel.d_partitions[t].p_size == 0)
    1390                 break;
    1391 
    1392         if (t == BSD_MAXPARTITIONS) {
    1393             fprintf(stderr, _("The maximum number of partitions "
    1394                        "has been created\n"));
    1395             return 0;
    1396         }
    1397     }
    1398 
    1399     *i = xbsd_get_part_index (BSD_MAXPARTITIONS);
    1400 
    1401     if (*i >= xbsd_dlabel.d_npartitions)
    1402         xbsd_dlabel.d_npartitions = (*i) + 1;
    1403 
    1404     if (xbsd_dlabel.d_partitions[*i].p_size != 0) {
    1405         fprintf(stderr, _("This partition already exists.\n"));
    1406         return 0;
    1407     }
    1408 
    1409     return 1;
    1410 }
    1411 
    1412 static void
    1413 xbsd_list_types(void)
    1414 {
    1415     list_types(xbsd_fstypes);
    1416 }
    1417 
    1418 static u_short
    1419 xbsd_dkcksum(struct xbsd_disklabel *lp)
    1420 {
    1421     u_short *start, *end;
    1422     u_short sum = 0;
    1423 
    1424     start = (u_short *) lp;
    1425     end = (u_short *) &lp->d_partitions[lp->d_npartitions];
    1426     while (start < end)
    1427         sum ^= *start++;
    1428     return sum;
    1429 }
    1430 
    1431 static int
    1432 xbsd_initlabel(struct partition *p, struct xbsd_disklabel *d)
    1433 {
    1434     struct xbsd_partition *pp;
    1435 
    1436     get_geometry();
    1437     memset(d, 0, sizeof(struct xbsd_disklabel));
    1438 
    1439     d->d_magic = BSD_DISKMAGIC;
    1440 
    1441     if (strncmp(disk_device, "/dev/sd", 7) == 0)
    1442         d->d_type = BSD_DTYPE_SCSI;
    1443     else
    1444         d->d_type = BSD_DTYPE_ST506;
    1445 
    1446 #if 0 /* not used (at least not written to disk) by NetBSD/i386 1.0 */
    1447     d->d_subtype = BSD_DSTYPE_INDOSPART & pindex;
    1448 #endif
    1449 
    1450 #if !defined (__alpha__)
    1451     d->d_flags = BSD_D_DOSPART;
    1452 #else
    1453     d->d_flags = 0;
    1454 #endif
    1455     d->d_secsize = SECTOR_SIZE;           /* bytes/sector  */
    1456     d->d_nsectors = sectors;            /* sectors/track */
    1457     d->d_ntracks = heads;               /* tracks/cylinder (heads) */
    1458     d->d_ncylinders = cylinders;
    1459     d->d_secpercyl  = sectors * heads;/* sectors/cylinder */
    1460     if (d->d_secpercyl == 0)
    1461         d->d_secpercyl = 1;           /* avoid segfaults */
    1462     d->d_secperunit = d->d_secpercyl * d->d_ncylinders;
    1463 
    1464     d->d_rpm = 3600;
    1465     d->d_interleave = 1;
    1466     d->d_trackskew = 0;
    1467     d->d_cylskew = 0;
    1468     d->d_headswitch = 0;
    1469     d->d_trkseek = 0;
    1470 
    1471     d->d_magic2 = BSD_DISKMAGIC;
    1472     d->d_bbsize = BSD_BBSIZE;
    1473     d->d_sbsize = BSD_SBSIZE;
    1474 
    1475 #if !defined (__alpha__)
    1476     d->d_npartitions = 4;
    1477     pp = &d->d_partitions[2];             /* Partition C should be
    1478                            the NetBSD partition */
    1479     pp->p_offset = get_start_sect(p);
    1480     pp->p_size   = get_nr_sects(p);
    1481     pp->p_fstype = BSD_FS_UNUSED;
    1482     pp = &d->d_partitions[3];             /* Partition D should be
    1483                            the whole disk */
    1484     pp->p_offset = 0;
    1485     pp->p_size   = d->d_secperunit;
    1486     pp->p_fstype = BSD_FS_UNUSED;
    1487 #elif defined (__alpha__)
    1488     d->d_npartitions = 3;
    1489     pp = &d->d_partitions[2];             /* Partition C should be
    1490                            the whole disk */
    1491     pp->p_offset = 0;
    1492     pp->p_size   = d->d_secperunit;
    1493     pp->p_fstype = BSD_FS_UNUSED;
    1494 #endif
    1495 
    1496     return 1;
    1497 }
    1498 
    1499 /*
    1500  * Read a xbsd_disklabel from sector 0 or from the starting sector of p.
    1501  * If it has the right magic, return 1.
    1502  */
    1503 static int
    1504 xbsd_readlabel (struct partition *p, struct xbsd_disklabel *d)
    1505 {
    1506     int t, sector;
    1507 
    1508     /* p is used only to get the starting sector */
    1509 #if !defined (__alpha__)
    1510     sector = (p ? get_start_sect(p) : 0);
    1511 #elif defined (__alpha__)
    1512     sector = 0;
    1513 #endif
    1514 
    1515     if (lseek(fd, sector * SECTOR_SIZE, SEEK_SET) == -1)
    1516         fdisk_fatal(unable_to_seek);
    1517     if (BSD_BBSIZE != read(fd, disklabelbuffer, BSD_BBSIZE))
    1518         fdisk_fatal(unable_to_read);
    1519 
    1520     memmove(d, &disklabelbuffer[BSD_LABELSECTOR * SECTOR_SIZE + BSD_LABELOFFSET],
    1521            sizeof(struct xbsd_disklabel));
    1522 
    1523     if (d->d_magic != BSD_DISKMAGIC || d->d_magic2 != BSD_DISKMAGIC)
    1524         return 0;
    1525 
    1526     for (t = d->d_npartitions; t < BSD_MAXPARTITIONS; t++) {
    1527         d->d_partitions[t].p_size   = 0;
    1528         d->d_partitions[t].p_offset = 0;
    1529         d->d_partitions[t].p_fstype = BSD_FS_UNUSED;
    1530     }
    1531 
    1532     if (d->d_npartitions > BSD_MAXPARTITIONS)
    1533         fprintf(stderr, _("Warning: too many partitions "
    1534                 "(%d, maximum is %d).\n"),
    1535             d->d_npartitions, BSD_MAXPARTITIONS);
    1536     return 1;
    1537 }
    1538 
    1539 static int
    1540 xbsd_writelabel (struct partition *p, struct xbsd_disklabel *d)
    1541 {
    1542     unsigned int sector;
    1543 
    1544 #if !defined (__alpha__) && !defined (__powerpc__) && !defined (__hppa__)
    1545     sector = get_start_sect(p) + BSD_LABELSECTOR;
    1546 #else
    1547     sector = BSD_LABELSECTOR;
    1548 #endif
    1549 
    1550     d->d_checksum = 0;
    1551     d->d_checksum = xbsd_dkcksum (d);
    1552 
    1553     /* This is necessary if we want to write the bootstrap later,
    1554        otherwise we'd write the old disklabel with the bootstrap.
    1555     */
    1556     memmove(&disklabelbuffer[BSD_LABELSECTOR * SECTOR_SIZE + BSD_LABELOFFSET],
    1557         d, sizeof(struct xbsd_disklabel));
    1558 
    1559 #if defined (__alpha__) && BSD_LABELSECTOR == 0
    1560     alpha_bootblock_checksum (disklabelbuffer);
    1561     if (lseek(fd, 0, SEEK_SET) == -1)
    1562         fdisk_fatal(unable_to_seek);
    1563     if (BSD_BBSIZE != write(fd, disklabelbuffer, BSD_BBSIZE))
    1564         fdisk_fatal(unable_to_write);
    1565 #else
    1566     if (lseek(fd, sector * SECTOR_SIZE + BSD_LABELOFFSET, SEEK_SET) == -1)
    1567         fdisk_fatal(unable_to_seek);
    1568     if (sizeof(struct xbsd_disklabel) != write(fd, d, sizeof(struct xbsd_disklabel)))
    1569         fdisk_fatal(unable_to_write);
    1570 #endif
    1571     sync_disks();
    1572     return 1;
    1573 }
    1574 
    1575 
    1576 #if !defined (__alpha__)
    1577 static int
    1578 xbsd_translate_fstype(int linux_type)
    1579 {
    1580     switch (linux_type) {
    1581     case 0x01: /* DOS 12-bit FAT   */
    1582     case 0x04: /* DOS 16-bit <32M  */
    1583     case 0x06: /* DOS 16-bit >=32M */
    1584     case 0xe1: /* DOS access       */
    1585     case 0xe3: /* DOS R/O          */
    1586     case 0xf2: /* DOS secondary    */
    1587         return BSD_FS_MSDOS;
    1588     case 0x07: /* OS/2 HPFS        */
    1589         return BSD_FS_HPFS;
    1590     default:
    1591         return BSD_FS_OTHER;
    1592     }
    1593 }
    1594 
    1595 static void
    1596 xbsd_link_part(void)
    1597 {
    1598     int k, i;
    1599     struct partition *p;
    1600 
    1601     k = get_partition(1, partitions);
    1602 
    1603     if (!xbsd_check_new_partition(&i))
    1604         return;
    1605 
    1606     p = get_part_table(k);
    1607 
    1608     xbsd_dlabel.d_partitions[i].p_size   = get_nr_sects(p);
    1609     xbsd_dlabel.d_partitions[i].p_offset = get_start_sect(p);
    1610     xbsd_dlabel.d_partitions[i].p_fstype = xbsd_translate_fstype(p->sys_ind);
    1611 }
    1612 #endif
    1613 
    1614 #if defined (__alpha__)
    1615 
    1616 #if !defined(__GLIBC__)
    1617 typedef unsigned long long uint64_t;
    1618 #endif
    1619 
    1620 static void
    1621 alpha_bootblock_checksum(char *boot)
    1622 {
    1623     uint64_t *dp, sum;
    1624     int i;
    1625 
    1626     dp = (uint64_t *)boot;
    1627     sum = 0;
    1628     for (i = 0; i < 63; i++)
    1629         sum += dp[i];
    1630     dp[63] = sum;
    1631 }
    1632 #endif /* __alpha__ */
    1633 
    1634 #endif /* OSF_LABEL */
    1635 
    1636 #if defined(CONFIG_FEATURE_SGI_LABEL) || defined(CONFIG_FEATURE_SUN_LABEL)
    1637 static inline unsigned short
    1638 __swap16(unsigned short x)
    1639 {
    1640     return (((uint16_t)(x) & 0xFF) << 8) | (((uint16_t)(x) & 0xFF00) >> 8);
    1641 }
    1642 
    1643 static inline uint32_t
    1644 __swap32(uint32_t x)
    1645 {
    1646     return (((x & 0xFF) << 24) |
    1647         ((x & 0xFF00) << 8) |
    1648         ((x & 0xFF0000) >> 8) |
    1649         ((x & 0xFF000000) >> 24));
    1650 }
    1651 #endif
    1652 
    1653 #ifdef CONFIG_FEATURE_SGI_LABEL
    1654 /*
    1655  *
    1656  * fdisksgilabel.c
    1657  *
    1658  * Copyright (C) Andreas Neuper, Sep 1998.
    1659  *      This file may be modified and redistributed under
    1660  *      the terms of the GNU Public License.
    1661  *
    1662  * Sat Mar 20 EST 1999 Arnaldo Carvalho de Melo <acme@conectiva.com.br>
    1663  *      Internationalization
    1664  */
    1665 
    1666 
    1667 static int sgi_other_endian;
    1668 static int debug;
    1669 static short sgi_volumes = 1;
    1670 
    1671 /*
    1672  * only dealing with free blocks here
    1673  */
    1674 
    1675 typedef struct {
    1676     unsigned int first;
    1677     unsigned int last;
    1678 } freeblocks;
    1679 static freeblocks freelist[17]; /* 16 partitions can produce 17 vacant slots */
    1680 
    1681 static void
    1682 setfreelist(int i, unsigned int f, unsigned int l)
    1683 {
    1684     freelist[i].first = f;
    1685     freelist[i].last = l;
    1686 }
    1687 
    1688 static void
    1689 add2freelist(unsigned int f, unsigned int l)
    1690 {
    1691     int i;
    1692     for (i = 0; i < 17 ; i++)
    1693         if (freelist[i].last == 0)
    1694             break;
    1695     setfreelist(i, f, l);
    1696 }
    1697 
    1698 static void
    1699 clearfreelist(void)
    1700 {
    1701     int i;
    1702 
    1703     for (i = 0; i < 17 ; i++)
    1704         setfreelist(i, 0, 0);
    1705 }
    1706 
    1707 static unsigned int
    1708 isinfreelist(unsigned int b)
    1709 {
    1710     int i;
    1711 
    1712     for (i = 0; i < 17 ; i++)
    1713         if (freelist[i].first <= b && freelist[i].last >= b)
    1714             return freelist[i].last;
    1715     return 0;
    1716 }
    1717     /* return last vacant block of this stride (never 0). */
    1718     /* the '>=' is not quite correct, but simplifies the code */
    1719 /*
    1720  * end of free blocks section
    1721  */
    1722 
    1723 static const struct systypes sgi_sys_types[] = {
    1724 /* SGI_VOLHDR   */  { "\x00" "SGI volhdr"   },
    1725 /* 0x01         */  { "\x01" "SGI trkrepl"  },
    1726 /* 0x02         */  { "\x02" "SGI secrepl"  },
    1727 /* SGI_SWAP     */  { "\x03" "SGI raw"      },
    1728 /* 0x04         */  { "\x04" "SGI bsd"      },
    1729 /* 0x05         */  { "\x05" "SGI sysv"     },
    1730 /* ENTIRE_DISK  */  { "\x06" "SGI volume"   },
    1731 /* SGI_EFS      */  { "\x07" "SGI efs"      },
    1732 /* 0x08         */  { "\x08" "SGI lvol"     },
    1733 /* 0x09         */  { "\x09" "SGI rlvol"    },
    1734 /* SGI_XFS      */  { "\x0a" "SGI xfs"      },
    1735 /* SGI_XFSLOG   */  { "\x0b" "SGI xfslog"   },
    1736 /* SGI_XLV      */  { "\x0c" "SGI xlv"      },
    1737 /* SGI_XVM      */  { "\x0d" "SGI xvm"      },
    1738 /* LINUX_SWAP   */  { "\x82" "Linux swap"   },
    1739 /* LINUX_NATIVE */  { "\x83" "Linux native" },
    1740 /* LINUX_LVM    */  { "\x8d" "Linux LVM"    },
    1741 /* LINUX_RAID   */  { "\xfd" "Linux RAID"   },
    1742             { NULL             }
    1743 };
    1744 
    1745 
    1746 static int
    1747 sgi_get_nsect(void)
    1748 {
    1749     return SGI_SSWAP16(sgilabel->devparam.nsect);
    1750 }
    1751 
    1752 static int
    1753 sgi_get_ntrks(void)
    1754 {
    1755     return SGI_SSWAP16(sgilabel->devparam.ntrks);
    1756 }
    1757 
    1758 static unsigned int
    1759 two_s_complement_32bit_sum(unsigned int* base, int size /* in bytes */)
    1760 {
    1761     int i = 0;
    1762     unsigned int sum = 0;
    1763 
    1764     size /= sizeof(unsigned int);
    1765     for (i = 0; i < size; i++)
    1766         sum -= SGI_SSWAP32(base[i]);
    1767     return sum;
    1768 }
    1769 
    1770 static int
    1771 check_sgi_label(void)
    1772 {
    1773     if (sizeof(sgilabel) > 512) {
    1774         fprintf(stderr,
    1775             _("According to MIPS Computer Systems, Inc the "
    1776             "Label must not contain more than 512 bytes\n"));
    1777         exit(1);
    1778     }
    1779 
    1780     if (sgilabel->magic != SGI_LABEL_MAGIC
    1781      && sgilabel->magic != SGI_LABEL_MAGIC_SWAPPED) {
    1782         current_label_type = label_dos;
    1783         return 0;
    1784     }
    1785 
    1786     sgi_other_endian = (sgilabel->magic == SGI_LABEL_MAGIC_SWAPPED);
    1787     /*
    1788      * test for correct checksum
    1789      */
    1790     if (two_s_complement_32bit_sum((unsigned int*)sgilabel,
    1791                 sizeof(*sgilabel))) {
    1792         fprintf(stderr,
    1793             _("Detected sgi disklabel with wrong checksum.\n"));
    1794     }
    1795     update_units();
    1796     current_label_type = label_sgi;
    1797     partitions = 16;
    1798     sgi_volumes = 15;
    1799     return 1;
    1800 }
    1801 
    1802 static unsigned int
    1803 sgi_get_start_sector(int i)
    1804 {
    1805     return SGI_SSWAP32(sgilabel->partitions[i].start_sector);
    1806 }
    1807 
    1808 static unsigned int
    1809 sgi_get_num_sectors(int i)
    1810 {
    1811     return SGI_SSWAP32(sgilabel->partitions[i].num_sectors);
    1812 }
    1813 
    1814 static int
    1815 sgi_get_sysid(int i)
    1816 {
    1817     return SGI_SSWAP32(sgilabel->partitions[i].id);
    1818 }
    1819 
    1820 static int
    1821 sgi_get_bootpartition(void)
    1822 {
    1823     return SGI_SSWAP16(sgilabel->boot_part);
    1824 }
    1825 
    1826 static int
    1827 sgi_get_swappartition(void)
    1828 {
    1829     return SGI_SSWAP16(sgilabel->swap_part);
    1830 }
    1831 
    1832 static void
    1833 sgi_list_table(int xtra)
    1834 {
    1835     int i, w, wd;
    1836     int kpi = 0;                /* kernel partition ID */
    1837 
    1838     if(xtra) {
    1839         printf(_("\nDisk %s (SGI disk label): %d heads, %d sectors\n"
    1840             "%d cylinders, %d physical cylinders\n"
    1841             "%d extra sects/cyl, interleave %d:1\n"
    1842             "%s\n"
    1843             "Units = %s of %d * 512 bytes\n\n"),
    1844             disk_device, heads, sectors, cylinders,
    1845             SGI_SSWAP16(sgiparam.pcylcount),
    1846             SGI_SSWAP16(sgiparam.sparecyl),
    1847             SGI_SSWAP16(sgiparam.ilfact),
    1848             (char *)sgilabel,
    1849             str_units(PLURAL), units_per_sector);
    1850     } else {
    1851         printf( _("\nDisk %s (SGI disk label): "
    1852             "%d heads, %d sectors, %d cylinders\n"
    1853             "Units = %s of %d * 512 bytes\n\n"),
    1854             disk_device, heads, sectors, cylinders,
    1855             str_units(PLURAL), units_per_sector );
    1856     }
    1857 
    1858     w = strlen(disk_device);
    1859     wd = strlen(_("Device"));
    1860     if (w < wd)
    1861     w = wd;
    1862 
    1863     printf(_("----- partitions -----\n"
    1864         "Pt# %*s  Info     Start       End   Sectors  Id  System\n"),
    1865         w + 2, _("Device"));
    1866     for (i = 0 ; i < partitions; i++) {
    1867         if( sgi_get_num_sectors(i) || debug ) {
    1868             uint32_t start = sgi_get_start_sector(i);
    1869             uint32_t len = sgi_get_num_sectors(i);
    1870             kpi++;              /* only count nonempty partitions */
    1871             printf(
    1872             "%2d: %s %4s %9ld %9ld %9ld  %2x  %s\n",
    1873 /* fdisk part number */ i+1,
    1874 /* device */            partname(disk_device, kpi, w+3),
    1875 /* flags */             (sgi_get_swappartition() == i) ? "swap" :
    1876 /* flags */             (sgi_get_bootpartition() == i) ? "boot" : "    ",
    1877 /* start */             (long) scround(start),
    1878 /* end */               (long) scround(start+len)-1,
    1879 /* no odd flag on end */(long) len,
    1880 /* type id */           sgi_get_sysid(i),
    1881 /* type name */         partition_type(sgi_get_sysid(i)));
    1882         }
    1883     }
    1884     printf(_("----- Bootinfo -----\nBootfile: %s\n"
    1885         "----- Directory Entries -----\n"),
    1886         sgilabel->boot_file);
    1887     for (i = 0 ; i < sgi_volumes; i++) {
    1888         if (sgilabel->directory[i].vol_file_size) {
    1889             uint32_t start = SGI_SSWAP32(sgilabel->directory[i].vol_file_start);
    1890             uint32_t len = SGI_SSWAP32(sgilabel->directory[i].vol_file_size);
    1891             unsigned char *name = sgilabel->directory[i].vol_file_name;
    1892 
    1893             printf(_("%2d: %-10s sector%5u size%8u\n"),
    1894                 i, (char*)name, (unsigned int) start, (unsigned int) len);
    1895         }
    1896     }
    1897 }
    1898 
    1899 static void
    1900 sgi_set_bootpartition(int i)
    1901 {
    1902     sgilabel->boot_part = SGI_SSWAP16(((short)i));
    1903 }
    1904 
    1905 static unsigned int
    1906 sgi_get_lastblock(void)
    1907 {
    1908     return heads * sectors * cylinders;
    1909 }
    1910 
    1911 static void
    1912 sgi_set_swappartition(int i)
    1913 {
    1914     sgilabel->swap_part = SGI_SSWAP16(((short)i));
    1915 }
    1916 
    1917 static int
    1918 sgi_check_bootfile(const char* aFile)
    1919 {
    1920     if (strlen(aFile) < 3) /* "/a\n" is minimum */ {
    1921         printf(_("\nInvalid Bootfile!\n"
    1922             "\tThe bootfile must be an absolute non-zero pathname,\n"
    1923             "\te.g. \"/unix\" or \"/unix.save\".\n"));
    1924         return 0;
    1925     } else {
    1926         if (strlen(aFile) > 16) {
    1927             printf(_("\n\tName of Bootfile too long:  "
    1928                 "16 bytes maximum.\n"));
    1929             return 0;
    1930         } else {
    1931             if (aFile[0] != '/') {
    1932                 printf(_("\n\tBootfile must have a "
    1933                     "fully qualified pathname.\n"));
    1934                 return 0;
    1935             }
    1936         }
    1937     }
    1938     if (strncmp(aFile, (char*)sgilabel->boot_file, 16)) {
    1939         printf(_("\n\tBe aware, that the bootfile is not checked for existence.\n\t"
    1940              "SGI's default is \"/unix\" and for backup \"/unix.save\".\n"));
    1941         /* filename is correct and did change */
    1942         return 1;
    1943     }
    1944     return 0;   /* filename did not change */
    1945 }
    1946 
    1947 static const char *
    1948 sgi_get_bootfile(void)
    1949 {
    1950     return (char*)sgilabel->boot_file;
    1951 }
    1952 
    1953 static void
    1954 sgi_set_bootfile(const char* aFile)
    1955 {
    1956     int i = 0;
    1957 
    1958     if (sgi_check_bootfile(aFile)) {
    1959         while (i < 16) {
    1960             if ((aFile[i] != '\n')  /* in principle caught again by next line */
    1961              && (strlen(aFile) > i))
    1962                 sgilabel->boot_file[i] = aFile[i];
    1963             else
    1964                 sgilabel->boot_file[i] = 0;
    1965             i++;
    1966         }
    1967         printf(_("\n\tBootfile is changed to \"%s\".\n"), sgilabel->boot_file);
    1968     }
    1969 }
    1970 
    1971 static void
    1972 create_sgiinfo(void)
    1973 {
    1974     /* I keep SGI's habit to write the sgilabel to the second block */
    1975     sgilabel->directory[0].vol_file_start = SGI_SSWAP32(2);
    1976     sgilabel->directory[0].vol_file_size = SGI_SSWAP32(sizeof(sgiinfo));
    1977     strcpy((char*)sgilabel->directory[0].vol_file_name, "sgilabel");
    1978 }
    1979 
    1980 static sgiinfo *fill_sgiinfo(void);
    1981 
    1982 static void
    1983 sgi_write_table(void)
    1984 {
    1985     sgilabel->csum = 0;
    1986     sgilabel->csum = SGI_SSWAP32(two_s_complement_32bit_sum(
    1987             (unsigned int*)sgilabel, sizeof(*sgilabel)));
    1988     assert(two_s_complement_32bit_sum(
    1989         (unsigned int*)sgilabel, sizeof(*sgilabel)) == 0);
    1990 
    1991     if (lseek(fd, 0, SEEK_SET) < 0)
    1992         fdisk_fatal(unable_to_seek);
    1993     if (write(fd, sgilabel, SECTOR_SIZE) != SECTOR_SIZE)
    1994         fdisk_fatal(unable_to_write);
    1995     if (!strncmp((char*)sgilabel->directory[0].vol_file_name, "sgilabel", 8)) {
    1996         /*
    1997          * keep this habit of first writing the "sgilabel".
    1998          * I never tested whether it works without (AN 981002).
    1999          */
    2000         sgiinfo *info = fill_sgiinfo();
    2001         int infostartblock = SGI_SSWAP32(sgilabel->directory[0].vol_file_start);
    2002         if (lseek(fd, infostartblock*SECTOR_SIZE, SEEK_SET) < 0)
    2003             fdisk_fatal(unable_to_seek);
    2004         if (write(fd, info, SECTOR_SIZE) != SECTOR_SIZE)
    2005             fdisk_fatal(unable_to_write);
    2006         free(info);
    2007     }
    2008 }
    2009 
    2010 static int
    2011 compare_start(int *x, int *y)
    2012 {
    2013     /*
    2014      * sort according to start sectors
    2015      * and prefers largest partition:
    2016      * entry zero is entire disk entry
    2017      */
    2018     unsigned int i = *x;
    2019     unsigned int j = *y;
    2020     unsigned int a = sgi_get_start_sector(i);
    2021     unsigned int b = sgi_get_start_sector(j);
    2022     unsigned int c = sgi_get_num_sectors(i);
    2023     unsigned int d = sgi_get_num_sectors(j);
    2024 
    2025     if (a == b)
    2026         return (d > c) ? 1 : (d == c) ? 0 : -1;
    2027     return (a > b) ? 1 : -1;
    2028 }
    2029 
    2030 
    2031 static int
    2032 verify_sgi(int verbose)
    2033 {
    2034     int Index[16];      /* list of valid partitions */
    2035     int sortcount = 0;  /* number of used partitions, i.e. non-zero lengths */
    2036     int entire = 0, i = 0;
    2037     unsigned int start = 0;
    2038     long long gap = 0;      /* count unused blocks */
    2039     unsigned int lastblock = sgi_get_lastblock();
    2040 
    2041     clearfreelist();
    2042     for (i = 0; i < 16; i++) {
    2043         if (sgi_get_num_sectors(i) != 0) {
    2044             Index[sortcount++] = i;
    2045             if (sgi_get_sysid(i) == ENTIRE_DISK) {
    2046                 if (entire++ == 1) {
    2047                     if (verbose)
    2048                         printf(_("More than one entire disk entry present.\n"));
    2049                 }
    2050             }
    2051         }
    2052     }
    2053     if (sortcount == 0) {
    2054         if (verbose)
    2055             printf(_("No partitions defined\n"));
    2056         return (lastblock > 0) ? 1 : (lastblock == 0) ? 0 : -1;
    2057     }
    2058     qsort(Index, sortcount, sizeof(Index[0]), (void*)compare_start);
    2059     if (sgi_get_sysid(Index[0]) == ENTIRE_DISK) {
    2060         if ((Index[0] != 10) && verbose)
    2061             printf(_("IRIX likes when Partition 11 covers the entire disk.\n"));
    2062         if ((sgi_get_start_sector(Index[0]) != 0) && verbose)
    2063             printf(_("The entire disk partition should start "
    2064                 "at block 0,\n"
    2065                 "not at diskblock %d.\n"),
    2066         sgi_get_start_sector(Index[0]));
    2067         if (debug)      /* I do not understand how some disks fulfil it */
    2068             if ((sgi_get_num_sectors(Index[0]) != lastblock) && verbose)
    2069                 printf(_("The entire disk partition is only %d diskblock large,\n"
    2070                     "but the disk is %d diskblocks long.\n"),
    2071         sgi_get_num_sectors(Index[0]), lastblock);
    2072         lastblock = sgi_get_num_sectors(Index[0]);
    2073     } else {
    2074         if (verbose)
    2075             printf(_("One Partition (#11) should cover the entire disk.\n"));
    2076         if (debug > 2)
    2077             printf("sysid=%d\tpartition=%d\n",
    2078                 sgi_get_sysid(Index[0]), Index[0]+1);
    2079     }
    2080     for (i = 1, start = 0; i < sortcount; i++) {
    2081         int cylsize = sgi_get_nsect() * sgi_get_ntrks();
    2082 
    2083         if ((sgi_get_start_sector(Index[i]) % cylsize) != 0) {
    2084             if (debug)      /* I do not understand how some disks fulfil it */
    2085                 if (verbose)
    2086                     printf(_("Partition %d does not start on cylinder boundary.\n"),
    2087                         Index[i]+1);
    2088         }
    2089         if (sgi_get_num_sectors(Index[i]) % cylsize != 0) {
    2090             if (debug)      /* I do not understand how some disks fulfil it */
    2091                 if (verbose)
    2092                     printf(_("Partition %d does not end on cylinder boundary.\n"),
    2093                         Index[i]+1);
    2094         }
    2095         /* We cannot handle several "entire disk" entries. */
    2096         if (sgi_get_sysid(Index[i]) == ENTIRE_DISK) continue;
    2097         if (start > sgi_get_start_sector(Index[i])) {
    2098             if (verbose)
    2099                 printf(_("The Partition %d and %d overlap by %d sectors.\n"),
    2100                     Index[i-1]+1, Index[i]+1,
    2101                     start - sgi_get_start_sector(Index[i]));
    2102             if (gap >  0) gap = -gap;
    2103             if (gap == 0) gap = -1;
    2104         }
    2105         if (start < sgi_get_start_sector(Index[i])) {
    2106             if (verbose)
    2107                 printf(_("Unused gap of %8u sectors - sectors %8u-%u\n"),
    2108                     sgi_get_start_sector(Index[i]) - start,
    2109                     start, sgi_get_start_sector(Index[i])-1);
    2110             gap += sgi_get_start_sector(Index[i]) - start;
    2111             add2freelist(start, sgi_get_start_sector(Index[i]));
    2112         }
    2113         start = sgi_get_start_sector(Index[i])
    2114                + sgi_get_num_sectors(Index[i]);
    2115         if (debug > 1) {
    2116             if (verbose)
    2117                 printf("%2d:%12d\t%12d\t%12d\n", Index[i],
    2118                     sgi_get_start_sector(Index[i]),
    2119                     sgi_get_num_sectors(Index[i]),
    2120                     sgi_get_sysid(Index[i]));
    2121         }
    2122     }
    2123     if (start < lastblock) {
    2124         if (verbose)
    2125             printf(_("Unused gap of %8u sectors - sectors %8u-%u\n"),
    2126                 lastblock - start, start, lastblock-1);
    2127         gap += lastblock - start;
    2128         add2freelist(start, lastblock);
    2129     }
    2130     /*
    2131      * Done with arithmetics
    2132      * Go for details now
    2133      */
    2134     if (verbose) {
    2135         if (!sgi_get_num_sectors(sgi_get_bootpartition())) {
    2136             printf(_("\nThe boot partition does not exist.\n"));
    2137         }
    2138         if (!sgi_get_num_sectors(sgi_get_swappartition())) {
    2139             printf(_("\nThe swap partition does not exist.\n"));
    2140         } else {
    2141             if ((sgi_get_sysid(sgi_get_swappartition()) != SGI_SWAP)
    2142              && (sgi_get_sysid(sgi_get_swappartition()) != LINUX_SWAP))
    2143                 printf(_("\nThe swap partition has no swap type.\n"));
    2144         }
    2145         if (sgi_check_bootfile("/unix"))
    2146             printf(_("\tYou have chosen an unusual boot file name.\n"));
    2147     }
    2148     return (gap > 0) ? 1 : (gap == 0) ? 0 : -1;
    2149 }
    2150 
    2151 static int
    2152 sgi_gaps(void)
    2153 {
    2154     /*
    2155      * returned value is:
    2156      *  = 0 : disk is properly filled to the rim
    2157      *  < 0 : there is an overlap
    2158      *  > 0 : there is still some vacant space
    2159      */
    2160     return verify_sgi(0);
    2161 }
    2162 
    2163 static void
    2164 sgi_change_sysid(int i, int sys)
    2165 {
    2166     if( sgi_get_num_sectors(i) == 0 ) { /* caught already before, ... */
    2167         printf(_("Sorry You may change the Tag of non-empty partitions.\n"));
    2168         return;
    2169     }
    2170     if (((sys != ENTIRE_DISK ) && (sys != SGI_VOLHDR))
    2171      && (sgi_get_start_sector(i) < 1) ) {
    2172         read_chars(
    2173             _("It is highly recommended that the partition at offset 0\n"
    2174             "is of type \"SGI volhdr\", the IRIX system will rely on it to\n"
    2175             "retrieve from its directory standalone tools like sash and fx.\n"
    2176             "Only the \"SGI volume\" entire disk section may violate this.\n"
    2177             "Type YES if you are sure about tagging this partition differently.\n"));
    2178         if (strcmp(line_ptr, _("YES\n")))
    2179             return;
    2180     }
    2181     sgilabel->partitions[i].id = SGI_SSWAP32(sys);
    2182 }
    2183 
    2184 /* returns partition index of first entry marked as entire disk */
    2185 static int
    2186 sgi_entire(void)
    2187 {
    2188     int i;
    2189 
    2190     for (i = 0; i < 16; i++)
    2191         if (sgi_get_sysid(i) == SGI_VOLUME)
    2192             return i;
    2193     return -1;
    2194 }
    2195 
    2196 static void
    2197 sgi_set_partition(int i, unsigned int start, unsigned int length, int sys)
    2198 {
    2199     sgilabel->partitions[i].id = SGI_SSWAP32(sys);
    2200     sgilabel->partitions[i].num_sectors = SGI_SSWAP32(length);
    2201     sgilabel->partitions[i].start_sector = SGI_SSWAP32(start);
    2202     set_changed(i);
    2203     if (sgi_gaps() < 0)     /* rebuild freelist */
    2204         printf(_("Do You know, You got a partition overlap on the disk?\n"));
    2205 }
    2206 
    2207 static void
    2208 sgi_set_entire(void)
    2209 {
    2210     int n;
    2211 
    2212     for (n = 10; n < partitions; n++) {
    2213         if(!sgi_get_num_sectors(n) ) {
    2214             sgi_set_partition(n, 0, sgi_get_lastblock(), SGI_VOLUME);
    2215             break;
    2216         }
    2217     }
    2218 }
    2219 
    2220 static void
    2221 sgi_set_volhdr(void)
    2222 {
    2223     int n;
    2224 
    2225     for (n = 8; n < partitions; n++) {
    2226     if (!sgi_get_num_sectors(n)) {
    2227         /*
    2228          * 5 cylinders is an arbitrary value I like
    2229          * IRIX 5.3 stored files in the volume header
    2230          * (like sash, symmon, fx, ide) with ca. 3200
    2231          * sectors.
    2232          */
    2233         if (heads * sectors * 5 < sgi_get_lastblock())
    2234             sgi_set_partition(n, 0, heads * sectors * 5, SGI_VOLHDR);
    2235             break;
    2236         }
    2237     }
    2238 }
    2239 
    2240 static void
    2241 sgi_delete_partition(int i)
    2242 {
    2243     sgi_set_partition(i, 0, 0, 0);
    2244 }
    2245 
    2246 static void
    2247 sgi_add_partition(int n, int sys)
    2248 {
    2249     char mesg[256];
    2250     unsigned int first = 0, last = 0;
    2251 
    2252     if (n == 10) {
    2253         sys = SGI_VOLUME;
    2254     } else if (n == 8) {
    2255         sys = 0;
    2256     }
    2257     if(sgi_get_num_sectors(n)) {
    2258         printf(_("Partition %d is already defined.  Delete "
    2259             "it before re-adding it.\n"), n + 1);
    2260         return;
    2261     }
    2262     if ((sgi_entire() == -1) && (sys != SGI_VOLUME)) {
    2263         printf(_("Attempting to generate entire disk entry automatically.\n"));
    2264         sgi_set_entire();
    2265         sgi_set_volhdr();
    2266     }
    2267     if ((sgi_gaps() == 0) && (sys != SGI_VOLUME)) {
    2268         printf(_("The entire disk is already covered with partitions.\n"));
    2269         return;
    2270     }
    2271     if (sgi_gaps() < 0) {
    2272         printf(_("You got a partition overlap on the disk. Fix it first!\n"));
    2273         return;
    2274     }
    2275     snprintf(mesg, sizeof(mesg), _("First %s"), str_units(SINGULAR));
    2276     while (1) {
    2277         if(sys == SGI_VOLUME) {
    2278             last = sgi_get_lastblock();
    2279             first = read_int(0, 0, last-1, 0, mesg);
    2280             if (first != 0) {
    2281                 printf(_("It is highly recommended that eleventh partition\n"
    2282                         "covers the entire disk and is of type `SGI volume'\n"));
    2283             }
    2284         } else {
    2285             first = freelist[0].first;
    2286             last  = freelist[0].last;
    2287             first = read_int(scround(first), scround(first), scround(last)-1,
    2288                 0, mesg);
    2289         }
    2290         if (display_in_cyl_units)
    2291             first *= units_per_sector;
    2292         else
    2293             first = first; /* align to cylinder if you know how ... */
    2294         if(!last )
    2295             last = isinfreelist(first);
    2296         if(last == 0) {
    2297             printf(_("You will get a partition overlap on the disk. "
    2298                 "Fix it first!\n"));
    2299         } else
    2300             break;
    2301     }
    2302     snprintf(mesg, sizeof(mesg), _(" Last %s"), str_units(SINGULAR));
    2303     last = read_int(scround(first), scround(last)-1, scround(last)-1,
    2304             scround(first), mesg)+1;
    2305     if (display_in_cyl_units)
    2306         last *= units_per_sector;
    2307     else
    2308         last = last; /* align to cylinder if You know how ... */
    2309     if ( (sys == SGI_VOLUME) && (first != 0 || last != sgi_get_lastblock() ) )
    2310         printf(_("It is highly recommended that eleventh partition\n"
    2311             "covers the entire disk and is of type `SGI volume'\n"));
    2312     sgi_set_partition(n, first, last-first, sys);
    2313 }
    2314 
    2315 #ifdef CONFIG_FEATURE_FDISK_ADVANCED
    2316 static void
    2317 create_sgilabel(void)
    2318 {
    2319     struct hd_geometry geometry;
    2320     struct {
    2321         unsigned int start;
    2322         unsigned int nsect;
    2323         int sysid;
    2324     } old[4];
    2325     int i = 0;
    2326     long longsectors;               /* the number of sectors on the device */
    2327     int res;                        /* the result from the ioctl */
    2328     int sec_fac;                    /* the sector factor */
    2329 
    2330     sec_fac = sector_size / 512;    /* determine the sector factor */
    2331 
    2332     fprintf( stderr,
    2333         _("Building a new SGI disklabel. Changes will remain in memory only,\n"
    2334         "until you decide to write them. After that, of course, the previous\n"
    2335         "content will be unrecoverably lost.\n\n"));
    2336 
    2337     sgi_other_endian = (BB_LITTLE_ENDIAN);
    2338     res = ioctl(fd, BLKGETSIZE, &longsectors);
    2339     if (!ioctl(fd, HDIO_GETGEO, &geometry)) {
    2340         heads = geometry.heads;
    2341         sectors = geometry.sectors;
    2342         if (res == 0) {
    2343             /* the get device size ioctl was successful */
    2344             cylinders = longsectors / (heads * sectors);
    2345             cylinders /= sec_fac;
    2346         } else {
    2347             /* otherwise print error and use truncated version */
    2348             cylinders = geometry.cylinders;
    2349             fprintf(stderr,
    2350                 _("Warning:  BLKGETSIZE ioctl failed on %s.  "
    2351                 "Using geometry cylinder value of %d.\n"
    2352                 "This value may be truncated for devices"
    2353                 " > 33.8 GB.\n"), disk_device, cylinders);
    2354         }
    2355     }
    2356     for (i = 0; i < 4; i++) {
    2357         old[i].sysid = 0;
    2358         if (valid_part_table_flag(MBRbuffer)) {
    2359             if(get_part_table(i)->sys_ind) {
    2360                 old[i].sysid = get_part_table(i)->sys_ind;
    2361                 old[i].start = get_start_sect(get_part_table(i));
    2362                 old[i].nsect = get_nr_sects(get_part_table(i));
    2363                 printf(_("Trying to keep parameters of partition %d.\n"), i);
    2364                 if (debug)
    2365                     printf(_("ID=%02x\tSTART=%d\tLENGTH=%d\n"),
    2366                 old[i].sysid, old[i].start, old[i].nsect);
    2367             }
    2368         }
    2369     }
    2370 
    2371     memset(MBRbuffer, 0, sizeof(MBRbuffer));
    2372     sgilabel->magic = SGI_SSWAP32(SGI_LABEL_MAGIC);
    2373     sgilabel->boot_part = SGI_SSWAP16(0);
    2374     sgilabel->swap_part = SGI_SSWAP16(1);
    2375 
    2376     /* sizeof(sgilabel->boot_file) = 16 > 6 */
    2377     memset(sgilabel->boot_file, 0, 16);
    2378     strcpy((char*)sgilabel->boot_file, "/unix");
    2379 
    2380     sgilabel->devparam.skew                     = (0);
    2381     sgilabel->devparam.gap1                     = (0);
    2382     sgilabel->devparam.gap2                     = (0);
    2383     sgilabel->devparam.sparecyl                 = (0);
    2384     sgilabel->devparam.pcylcount                = SGI_SSWAP16(geometry.cylinders);
    2385     sgilabel->devparam.head_vol0                = SGI_SSWAP16(0);
    2386     sgilabel->devparam.ntrks                    = SGI_SSWAP16(geometry.heads);
    2387                         /* tracks/cylinder (heads) */
    2388     sgilabel->devparam.cmd_tag_queue_depth      = (0);
    2389     sgilabel->devparam.unused0                  = (0);
    2390     sgilabel->devparam.unused1                  = SGI_SSWAP16(0);
    2391     sgilabel->devparam.nsect                    = SGI_SSWAP16(geometry.sectors);
    2392                         /* sectors/track */
    2393     sgilabel->devparam.bytes                    = SGI_SSWAP16(512);
    2394     sgilabel->devparam.ilfact                   = SGI_SSWAP16(1);
    2395     sgilabel->devparam.flags                    = SGI_SSWAP32(TRACK_FWD|
    2396                             IGNORE_ERRORS|RESEEK);
    2397     sgilabel->devparam.datarate                 = SGI_SSWAP32(0);
    2398     sgilabel->devparam.retries_on_error         = SGI_SSWAP32(1);
    2399     sgilabel->devparam.ms_per_word              = SGI_SSWAP32(0);
    2400     sgilabel->devparam.xylogics_gap1            = SGI_SSWAP16(0);
    2401     sgilabel->devparam.xylogics_syncdelay       = SGI_SSWAP16(0);
    2402     sgilabel->devparam.xylogics_readdelay       = SGI_SSWAP16(0);
    2403     sgilabel->devparam.xylogics_gap2            = SGI_SSWAP16(0);
    2404     sgilabel->devparam.xylogics_readgate        = SGI_SSWAP16(0);
    2405     sgilabel->devparam.xylogics_writecont       = SGI_SSWAP16(0);
    2406     memset( &(sgilabel->directory), 0, sizeof(struct volume_directory)*15 );
    2407     memset( &(sgilabel->partitions), 0, sizeof(struct sgi_partition)*16 );
    2408     current_label_type = label_sgi;
    2409     partitions = 16;
    2410     sgi_volumes = 15;
    2411     sgi_set_entire();
    2412     sgi_set_volhdr();
    2413     for (i = 0; i < 4; i++) {
    2414         if(old[i].sysid) {
    2415             sgi_set_partition(i, old[i].start, old[i].nsect, old[i].sysid);
    2416         }
    2417     }
    2418 }
    2419 
    2420 static void
    2421 sgi_set_xcyl(void)
    2422 {
    2423     /* do nothing in the beginning */
    2424 }
    2425 #endif /* CONFIG_FEATURE_FDISK_ADVANCED */
    2426 
    2427 /* _____________________________________________________________
    2428  */
    2429 
    2430 static sgiinfo *
    2431 fill_sgiinfo(void)
    2432 {
    2433     sgiinfo *info = calloc(1, sizeof(sgiinfo));
    2434 
    2435     info->magic = SGI_SSWAP32(SGI_INFO_MAGIC);
    2436     info->b1 = SGI_SSWAP32(-1);
    2437     info->b2 = SGI_SSWAP16(-1);
    2438     info->b3 = SGI_SSWAP16(1);
    2439     /* You may want to replace this string !!!!!!! */
    2440     strcpy( (char*)info->scsi_string, "IBM OEM 0662S12         3 30" );
    2441     strcpy( (char*)info->serial, "0000" );
    2442     info->check1816 = SGI_SSWAP16(18*256 +16 );
    2443     strcpy( (char*)info->installer, "Sfx version 5.3, Oct 18, 1994" );
    2444     return info;
    2445 }
    2446 #endif /* SGI_LABEL */
    2447 
    2448 
    2449 #ifdef CONFIG_FEATURE_SUN_LABEL
    2450 /*
    2451  * fdisksunlabel.c
    2452  *
    2453  * I think this is mostly, or entirely, due to
    2454  *      Jakub Jelinek (jj@sunsite.mff.cuni.cz), July 1996
    2455  *
    2456  * Merged with fdisk for other architectures, aeb, June 1998.
    2457  *
    2458  * Sat Mar 20 EST 1999 Arnaldo Carvalho de Melo <acme@conectiva.com.br>
    2459  *      Internationalization
    2460  */
    2461 
    2462 
    2463 static int sun_other_endian;
    2464 static int scsi_disk;
    2465 static int floppy;
    2466 
    2467 #ifndef IDE0_MAJOR
    2468 #define IDE0_MAJOR 3
    2469 #endif
    2470 #ifndef IDE1_MAJOR
    2471 #define IDE1_MAJOR 22
    2472 #endif
    2473 
    2474 static void
    2475 guess_device_type(void)
    2476 {
    2477     struct stat bootstat;
    2478 
    2479     if (fstat(fd, &bootstat) < 0) {
    2480         scsi_disk = 0;
    2481         floppy = 0;
    2482     } else if (S_ISBLK(bootstat.st_mode)
    2483         && (major(bootstat.st_rdev) == IDE0_MAJOR ||
    2484             major(bootstat.st_rdev) == IDE1_MAJOR)) {
    2485         scsi_disk = 0;
    2486         floppy = 0;
    2487     } else if (S_ISBLK(bootstat.st_mode)
    2488         && major(bootstat.st_rdev) == FLOPPY_MAJOR) {
    2489         scsi_disk = 0;
    2490         floppy = 1;
    2491     } else {
    2492         scsi_disk = 1;
    2493         floppy = 0;
    2494     }
    2495 }
    2496 
    2497 static const struct systypes sun_sys_types[] = {
    2498     { "\x00" "Empty"        }, /* 0            */
    2499     { "\x01" "Boot"         }, /* 1            */
    2500     { "\x02" "SunOS root"   }, /* 2            */
    2501     { "\x03" "SunOS swap"   }, /* SUNOS_SWAP   */
    2502     { "\x04" "SunOS usr"    }, /* 4            */
    2503     { "\x05" "Whole disk"   }, /* WHOLE_DISK   */
    2504     { "\x06" "SunOS stand"  }, /* 6            */
    2505     { "\x07" "SunOS var"    }, /* 7            */
    2506     { "\x08" "SunOS home"   }, /* 8            */
    2507     { "\x82" "Linux swap"   }, /* LINUX_SWAP   */
    2508     { "\x83" "Linux native" }, /* LINUX_NATIVE */
    2509     { "\x8e" "Linux LVM"    }, /* 0x8e         */
    2510 /* New (2.2.x) raid partition with autodetect using persistent superblock */
    2511     { "\xfd" "Linux raid autodetect" }, /* 0xfd         */ 
    2512     { NULL }
    2513 };
    2514 
    2515 
    2516 static void
    2517 set_sun_partition(int i, uint start, uint stop, int sysid)
    2518 {
    2519     sunlabel->infos[i].id = sysid;
    2520     sunlabel->partitions[i].start_cylinder =
    2521         SUN_SSWAP32(start / (heads * sectors));
    2522     sunlabel->partitions[i].num_sectors =
    2523         SUN_SSWAP32(stop - start);
    2524     set_changed(i);
    2525 }
    2526 
    2527 static int
    2528 check_sun_label(void)
    2529 {
    2530     unsigned short *ush;
    2531     int csum;
    2532 
    2533     if (sunlabel->magic != SUN_LABEL_MAGIC
    2534      && sunlabel->magic != SUN_LABEL_MAGIC_SWAPPED) {
    2535         current_label_type = label_dos;
    2536         sun_other_endian = 0;
    2537         return 0;
    2538     }
    2539     sun_other_endian = (sunlabel->magic == SUN_LABEL_MAGIC_SWAPPED);
    2540     ush = ((unsigned short *) (sunlabel + 1)) - 1;
    2541     for (csum = 0; ush >= (unsigned short *)sunlabel;) csum ^= *ush--;
    2542     if (csum) {
    2543         fprintf(stderr,_("Detected sun disklabel with wrong checksum.\n"
    2544                 "Probably you'll have to set all the values,\n"
    2545                 "e.g. heads, sectors, cylinders and partitions\n"
    2546                 "or force a fresh label (s command in main menu)\n"));
    2547     } else {
    2548         heads = SUN_SSWAP16(sunlabel->ntrks);
    2549         cylinders = SUN_SSWAP16(sunlabel->ncyl);
    2550         sectors = SUN_SSWAP16(sunlabel->nsect);
    2551     }
    2552     update_units();
    2553     current_label_type = label_sun;
    2554     partitions = 8;
    2555     return 1;
    2556 }
    2557 
    2558 static const struct sun_predefined_drives {
    2559     const char *vendor;
    2560     const char *model;
    2561     unsigned short sparecyl;
    2562     unsigned short ncyl;
    2563     unsigned short nacyl;
    2564     unsigned short pcylcount;
    2565     unsigned short ntrks;
    2566     unsigned short nsect;
    2567     unsigned short rspeed;
    2568 } sun_drives[] = {
    2569     { "Quantum","ProDrive 80S",1,832,2,834,6,34,3662},
    2570     { "Quantum","ProDrive 105S",1,974,2,1019,6,35,3662},
    2571     { "CDC","Wren IV 94171-344",3,1545,2,1549,9,46,3600},
    2572     { "IBM","DPES-31080",0,4901,2,4903,4,108,5400},
    2573     { "IBM","DORS-32160",0,1015,2,1017,67,62,5400},
    2574     { "IBM","DNES-318350",0,11199,2,11474,10,320,7200},
    2575     { "SEAGATE","ST34371",0,3880,2,3882,16,135,7228},
    2576     { "","SUN0104",1,974,2,1019,6,35,3662},
    2577     { "","SUN0207",4,1254,2,1272,9,36,3600},
    2578     { "","SUN0327",3,1545,2,1549,9,46,3600},
    2579     { "","SUN0340",0,1538,2,1544,6,72,4200},
    2580     { "","SUN0424",2,1151,2,2500,9,80,4400},
    2581     { "","SUN0535",0,1866,2,2500,7,80,5400},
    2582     { "","SUN0669",5,1614,2,1632,15,54,3600},
    2583     { "","SUN1.0G",5,1703,2,1931,15,80,3597},
    2584     { "","SUN1.05",0,2036,2,2038,14,72,5400},
    2585     { "","SUN1.3G",6,1965,2,3500,17,80,5400},
    2586     { "","SUN2.1G",0,2733,2,3500,19,80,5400},
    2587     { "IOMEGA","Jaz",0,1019,2,1021,64,32,5394},
    2588 };
    2589 
    2590 static const struct sun_predefined_drives *
    2591 sun_autoconfigure_scsi(void)
    2592 {
    2593     const struct sun_predefined_drives *p = NULL;
    2594 
    2595 #ifdef SCSI_IOCTL_GET_IDLUN
    2596     unsigned int id[2];
    2597     char buffer[2048];
    2598     char buffer2[2048];
    2599     FILE *pfd;
    2600     char *vendor;
    2601     char *model;
    2602     char *q;
    2603     int i;
    2604 
    2605     if (!ioctl(fd, SCSI_IOCTL_GET_IDLUN, &id)) {
    2606         sprintf(buffer,
    2607             "Host: scsi%d Channel: %02d Id: %02d Lun: %02d\n",
    2608 #if 0
    2609             ((id[0]>>24)&0xff)-/*PROC_SCSI_SCSI+PROC_SCSI_FILE*/33,
    2610 #else
    2611             /* This is very wrong (works only if you have one HBA),
    2612                but I haven't found a way how to get hostno
    2613                from the current kernel */
    2614             0,
    2615 #endif
    2616             (id[0]>>16) & 0xff,
    2617             id[0] & 0xff,
    2618             (id[0]>>8) & 0xff
    2619         );
    2620         pfd = fopen("/proc/scsi/scsi","r");
    2621         if (pfd) {
    2622             while (fgets(buffer2, 2048, pfd)) {
    2623                 if (!strcmp(buffer, buffer2)) {
    2624                     if (fgets(buffer2,2048,pfd)) {
    2625                         q = strstr(buffer2,"Vendor: ");
    2626                         if (q) {
    2627                             q += 8;
    2628                             vendor = q;
    2629                             q = strstr(q," ");
    2630                             *q++ = 0;   /* truncate vendor name */
    2631                             q = strstr(q,"Model: ");
    2632                             if (q) {
    2633                                 *q = 0;
    2634                                 q += 7;
    2635                                 model = q;
    2636                                 q = strstr(q," Rev: ");
    2637                                 if (q) {
    2638                                     *q = 0;
    2639                                     for (i = 0; i < SIZE(sun_drives); i++) {
    2640                                         if (*sun_drives[i].vendor && strcasecmp(sun_drives[i].vendor, vendor))
    2641                                             continue;
    2642                                         if (!strstr(model, sun_drives[i].model))
    2643                                             continue;
    2644                                         printf(_("Autoconfigure found a %s%s%s\n"),sun_drives[i].vendor,(*sun_drives[i].vendor) ? " " : "",sun_drives[i].model);
    2645                                         p = sun_drives + i;
    2646                                         break;
    2647                                     }
    2648                                 }
    2649                             }
    2650                         }
    2651                     }
    2652                     break;
    2653                 }
    2654             }
    2655             fclose(pfd);
    2656         }
    2657     }
    2658 #endif
    2659     return p;
    2660 }
    2661 
    2662 static void
    2663 create_sunlabel(void)
    2664 {
    2665     struct hd_geometry geometry;
    2666     unsigned int ndiv;
    2667     int i;
    2668     unsigned char c;
    2669     const struct sun_predefined_drives *p = NULL;
    2670 
    2671     fprintf(stderr,
    2672         _("Building a new sun disklabel. Changes will remain in memory only,\n"
    2673         "until you decide to write them. After that, of course, the previous\n"
    2674         "content won't be recoverable.\n\n"));
    2675     sun_other_endian = BB_LITTLE_ENDIAN;
    2676     memset(MBRbuffer, 0, sizeof(MBRbuffer));
    2677     sunlabel->magic = SUN_SSWAP16(SUN_LABEL_MAGIC);
    2678     if (!floppy) {
    2679         puts(_("Drive type\n"
    2680          "   ?   auto configure\n"
    2681          "   0   custom (with hardware detected defaults)"));
    2682         for (i = 0; i < SIZE(sun_drives); i++) {
    2683             printf("   %c   %s%s%s\n",
    2684                 i + 'a', sun_drives[i].vendor,
    2685                 (*sun_drives[i].vendor) ? " " : "",
    2686                 sun_drives[i].model);
    2687         }
    2688         while (1) {
    2689             c = read_char(_("Select type (? for auto, 0 for custom): "));
    2690             if (c >= 'a' && c < 'a' + SIZE(sun_drives)) {
    2691                 p = sun_drives + c - 'a';
    2692                 break;
    2693             } else if (c >= 'A' && c < 'A' + SIZE(sun_drives)) {
    2694                 p = sun_drives + c - 'A';
    2695                 break;
    2696             } else if (c == '0') {
    2697                 break;
    2698             } else if (c == '?' && scsi_disk) {
    2699                 p = sun_autoconfigure_scsi();
    2700                 if (!p)
    2701                 printf(_("Autoconfigure failed.\n"));
    2702                 else
    2703                 break;
    2704             }
    2705         }
    2706     }
    2707     if (!p || floppy) {
    2708         if (!ioctl(fd, HDIO_GETGEO, &geometry)) {
    2709             heads = geometry.heads;
    2710             sectors = geometry.sectors;
    2711             cylinders = geometry.cylinders;
    2712         } else {
    2713             heads = 0;
    2714             sectors = 0;
    2715             cylinders = 0;
    2716         }
    2717         if (floppy) {
    2718             sunlabel->nacyl = 0;
    2719             sunlabel->pcylcount = SUN_SSWAP16(cylinders);
    2720             sunlabel->rspeed = SUN_SSWAP16(300);
    2721             sunlabel->ilfact = SUN_SSWAP16(1);
    2722             sunlabel->sparecyl = 0;
    2723         } else {
    2724             heads = read_int(1,heads,1024,0,_("Heads"));
    2725             sectors = read_int(1,sectors,1024,0,_("Sectors/track"));
    2726         if (cylinders)
    2727             cylinders = read_int(1,cylinders-2,65535,0,_("Cylinders"));
    2728         else
    2729             cylinders = read_int(1,0,65535,0,_("Cylinders"));
    2730             sunlabel->nacyl = SUN_SSWAP16(read_int(0,2,65535,0, _("Alternate cylinders")));
    2731             sunlabel->pcylcount = SUN_SSWAP16(read_int(0,cylinders+SUN_SSWAP16(sunlabel->nacyl), 65535,0, _("Physical cylinders")));
    2732             sunlabel->rspeed = SUN_SSWAP16(read_int(1,5400,100000,0, _("Rotation speed (rpm)")));
    2733             sunlabel->ilfact = SUN_SSWAP16(read_int(1,1,32,0, _("Interleave factor")));
    2734             sunlabel->sparecyl = SUN_SSWAP16(read_int(0,0,sectors,0, _("Extra sectors per cylinder")));
    2735         }
    2736     } else {
    2737         sunlabel->sparecyl = SUN_SSWAP16(p->sparecyl);
    2738         sunlabel->ncyl = SUN_SSWAP16(p->ncyl);
    2739         sunlabel->nacyl = SUN_SSWAP16(p->nacyl);
    2740         sunlabel->pcylcount = SUN_SSWAP16(p->pcylcount);
    2741         sunlabel->ntrks = SUN_SSWAP16(p->ntrks);
    2742         sunlabel->nsect = SUN_SSWAP16(p->nsect);
    2743         sunlabel->rspeed = SUN_SSWAP16(p->rspeed);
    2744         sunlabel->ilfact = SUN_SSWAP16(1);
    2745         cylinders = p->ncyl;
    2746         heads = p->ntrks;
    2747         sectors = p->nsect;
    2748         puts(_("You may change all the disk params from the x menu"));
    2749     }
    2750 
    2751     snprintf((char *)(sunlabel->info), sizeof(sunlabel->info),
    2752         "%s%s%s cyl %d alt %d hd %d sec %d",
    2753         p ? p->vendor : "", (p && *p->vendor) ? " " : "",
    2754         p ? p->model : (floppy ? _("3,5\" floppy") : _("Linux custom")),
    2755         cylinders, SUN_SSWAP16(sunlabel->nacyl), heads, sectors);
    2756 
    2757     sunlabel->ntrks = SUN_SSWAP16(heads);
    2758     sunlabel->nsect = SUN_SSWAP16(sectors);
    2759     sunlabel->ncyl = SUN_SSWAP16(cylinders);
    2760     if (floppy)
    2761         set_sun_partition(0, 0, cylinders * heads * sectors, LINUX_NATIVE);
    2762     else {
    2763         if (cylinders * heads * sectors >= 150 * 2048) {
    2764             ndiv = cylinders - (50 * 2048 / (heads * sectors)); /* 50M swap */
    2765         } else
    2766             ndiv = cylinders * 2 / 3;
    2767         set_sun_partition(0, 0, ndiv * heads * sectors, LINUX_NATIVE);
    2768         set_sun_partition(1, ndiv * heads * sectors, cylinders * heads * sectors, LINUX_SWAP);
    2769         sunlabel->infos[1].flags |= 0x01; /* Not mountable */
    2770     }
    2771     set_sun_partition(2, 0, cylinders * heads * sectors, WHOLE_DISK);
    2772     {
    2773         unsigned short *ush = (unsigned short *)sunlabel;
    2774         unsigned short csum = 0;
    2775         while (ush < (unsigned short *)(&sunlabel->csum))
    2776             csum ^= *ush++;
    2777         sunlabel->csum = csum;
    2778     }
    2779 
    2780     set_all_unchanged();
    2781     set_changed(0);
    2782     get_boot(create_empty_sun);
    2783 }
    2784 
    2785 static void
    2786 toggle_sunflags(int i, unsigned char mask)
    2787 {
    2788     if (sunlabel->infos[i].flags & mask)
    2789         sunlabel->infos[i].flags &= ~mask;
    2790     else
    2791         sunlabel->infos[i].flags |= mask;
    2792     set_changed(i);
    2793 }
    2794 
    2795 static void
    2796 fetch_sun(uint *starts, uint *lens, uint *start, uint *stop)
    2797 {
    2798     int i, continuous = 1;
    2799 
    2800     *start = 0;
    2801     *stop = cylinders * heads * sectors;
    2802     for (i = 0; i < partitions; i++) {
    2803         if (sunlabel->partitions[i].num_sectors
    2804          && sunlabel->infos[i].id
    2805          && sunlabel->infos[i].id != WHOLE_DISK) {
    2806             starts[i] = SUN_SSWAP32(sunlabel->partitions[i].start_cylinder) * heads * sectors;
    2807             lens[i] = SUN_SSWAP32(sunlabel->partitions[i].num_sectors);
    2808             if (continuous) {
    2809                 if (starts[i] == *start)
    2810                     *start += lens[i];
    2811                 else if (starts[i] + lens[i] >= *stop)
    2812                     *stop = starts[i];
    2813                 else
    2814                     continuous = 0;
    2815                     /* There will be probably more gaps
    2816                       than one, so lets check afterwards */
    2817             }
    2818         } else {
    2819             starts[i] = 0;
    2820             lens[i] = 0;
    2821         }
    2822     }
    2823 }
    2824 
    2825 static uint *verify_sun_starts;
    2826 
    2827 static int
    2828 verify_sun_cmp(int *a, int *b)
    2829 {
    2830     if (*a == -1) return 1;
    2831     if (*b == -1) return -1;
    2832     if (verify_sun_starts[*a] > verify_sun_starts[*b]) return 1;
    2833     return -1;
    2834 }
    2835 
    2836 static void
    2837 verify_sun(void)
    2838 {
    2839     uint starts[8], lens[8], start, stop;
    2840     int i,j,k,starto,endo;
    2841     int array[8];
    2842 
    2843     verify_sun_starts = starts;
    2844     fetch_sun(starts,lens,&start,&stop);
    2845     for (k = 0; k < 7; k++) {
    2846         for (i = 0; i < 8; i++) {
    2847             if (k && (lens[i] % (heads * sectors))) {
    2848                 printf(_("Partition %d doesn't end on cylinder boundary\n"), i+1);
    2849             }
    2850             if (lens[i]) {
    2851                 for (j = 0; j < i; j++)
    2852                     if (lens[j]) {
    2853                         if (starts[j] == starts[i]+lens[i]) {
    2854                             starts[j] = starts[i]; lens[j] += lens[i];
    2855                             lens[i] = 0;
    2856                         } else if (starts[i] == starts[j]+lens[j]){
    2857                             lens[j] += lens[i];
    2858                             lens[i] = 0;
    2859                         } else if (!k) {
    2860                             if (starts[i] < starts[j]+lens[j]
    2861                              && starts[j] < starts[i]+lens[i]) {
    2862                                 starto = starts[i];
    2863                                 if (starts[j] > starto)
    2864                                     starto = starts[j];
    2865                                 endo = starts[i]+lens[i];
    2866                                 if (starts[j]+lens[j] < endo)
    2867                                     endo = starts[j]+lens[j];
    2868                                 printf(_("Partition %d overlaps with others in "
    2869                                     "sectors %d-%d\n"), i+1, starto, endo);
    2870                             }
    2871                         }
    2872                     }
    2873             }
    2874         }
    2875     }
    2876     for (i = 0; i < 8; i++) {
    2877         if (lens[i])
    2878             array[i] = i;
    2879         else
    2880             array[i] = -1;
    2881     }
    2882     qsort(array,SIZE(array),sizeof(array[0]),
    2883         (int (*)(const void *,const void *)) verify_sun_cmp);
    2884     if (array[0] == -1) {
    2885         printf(_("No partitions defined\n"));
    2886         return;
    2887     }
    2888     stop = cylinders * heads * sectors;
    2889     if (starts[array[0]])
    2890         printf(_("Unused gap - sectors 0-%d\n"),starts[array[0]]);
    2891     for (i = 0; i < 7 && array[i+1] != -1; i++) {
    2892         printf(_("Unused gap - sectors %d-%d\n"),starts[array[i]]+lens[array[i]],starts[array[i+1]]);
    2893     }
    2894     start = starts[array[i]] + lens[array[i]];
    2895     if (start < stop)
    2896         printf(_("Unused gap - sectors %d-%d\n"),start,stop);
    2897 }
    2898 
    2899 static void
    2900 add_sun_partition(int n, int sys)
    2901 {
    2902     uint start, stop, stop2;
    2903     uint starts[8], lens[8];
    2904     int whole_disk = 0;
    2905 
    2906     char mesg[256];
    2907     int i, first, last;
    2908 
    2909     if (sunlabel->partitions[n].num_sectors && sunlabel->infos[n].id) {
    2910         printf(_("Partition %d is already defined.  Delete "
    2911             "it before re-adding it.\n"), n + 1);
    2912         return;
    2913     }
    2914 
    2915     fetch_sun(starts,lens,&start,&stop);
    2916     if (stop <= start) {
    2917         if (n == 2)
    2918             whole_disk = 1;
    2919         else {
    2920             printf(_("Other partitions already cover the whole disk.\nDelete "
    2921                    "some/shrink them before retry.\n"));
    2922             return;
    2923         }
    2924     }
    2925     snprintf(mesg, sizeof(mesg), _("First %s"), str_units(SINGULAR));
    2926     while (1) {
    2927         if (whole_disk)
    2928             first = read_int(0, 0, 0, 0, mesg);
    2929         else
    2930             first = read_int(scround(start), scround(stop)+1,
    2931                      scround(stop), 0, mesg);
    2932         if (display_in_cyl_units)
    2933             first *= units_per_sector;
    2934         else
    2935             /* Starting sector has to be properly aligned */
    2936             first = (first + heads * sectors - 1) / (heads * sectors);
    2937         if (n == 2 && first != 0)
    2938             printf("\
    2939 It is highly recommended that the third partition covers the whole disk\n\
    2940 and is of type `Whole disk'\n");
    2941         /* ewt asks to add: "don't start a partition at cyl 0"
    2942            However, edmundo@rano.demon.co.uk writes:
    2943            "In addition to having a Sun partition table, to be able to
    2944            boot from the disc, the first partition, /dev/sdX1, must
    2945            start at cylinder 0. This means that /dev/sdX1 contains
    2946            the partition table and the boot block, as these are the
    2947            first two sectors of the disc. Therefore you must be
    2948            careful what you use /dev/sdX1 for. In particular, you must
    2949            not use a partition starting at cylinder 0 for Linux swap,
    2950            as that would overwrite the partition table and the boot
    2951            block. You may, however, use such a partition for a UFS
    2952            or EXT2 file system, as these file systems leave the first
    2953            1024 bytes undisturbed. */
    2954         /* On the other hand, one should not use partitions
    2955            starting at block 0 in an md, or the label will
    2956            be trashed. */
    2957         for (i = 0; i < partitions; i++)
    2958             if (lens[i] && starts[i] <= first && starts[i] + lens[i] > first)
    2959                 break;
    2960         if (i < partitions && !whole_disk) {
    2961             if (n == 2 && !first) {
    2962                 whole_disk = 1;
    2963                 break;
    2964             }
    2965             printf(_("Sector %d is already allocated\n"), first);
    2966         } else
    2967             break;
    2968     }
    2969     stop = cylinders * heads * sectors;
    2970     stop2 = stop;
    2971     for (i = 0; i < partitions; i++) {
    2972         if (starts[i] > first && starts[i] < stop)
    2973             stop = starts[i];
    2974     }
    2975     snprintf(mesg, sizeof(mesg),
    2976         _("Last %s or +size or +sizeM or +sizeK"),
    2977         str_units(SINGULAR));
    2978     if (whole_disk)
    2979         last = read_int(scround(stop2), scround(stop2), scround(stop2),
    2980                 0, mesg);
    2981     else if (n == 2 && !first)
    2982         last = read_int(scround(first), scround(stop2), scround(stop2),
    2983                 scround(first), mesg);
    2984     else
    2985         last = read_int(scround(first), scround(stop), scround(stop),
    2986                 scround(first), mesg);
    2987     if (display_in_cyl_units)
    2988         last *= units_per_sector;
    2989     if (n == 2 && !first) {
    2990         if (last >= stop2) {
    2991             whole_disk = 1;
    2992             last = stop2;
    2993         } else if (last > stop) {
    2994             printf(_("You haven't covered the whole disk with "
    2995                 "the 3rd partition, but your value\n"
    2996                 "%d %s covers some other partition. "
    2997                 "Your entry has been changed\n"
    2998                 "to %d %s\n"),
    2999                 scround(last), str_units(SINGULAR),
    3000                 scround(stop), str_units(SINGULAR));
    3001             last = stop;
    3002         }
    3003     } else if (!whole_disk && last > stop)
    3004         last = stop;
    3005 
    3006     if (whole_disk)
    3007         sys = WHOLE_DISK;
    3008     set_sun_partition(n, first, last, sys);
    3009 }
    3010 
    3011 static void
    3012 sun_delete_partition(int i)
    3013 {
    3014     unsigned int nsec;
    3015 
    3016     if (i == 2
    3017      && sunlabel->infos[i].id == WHOLE_DISK
    3018      && !sunlabel->partitions[i].start_cylinder
    3019      && (nsec = SUN_SSWAP32(sunlabel->partitions[i].num_sectors)) == heads * sectors * cylinders)
    3020         printf(_("If you want to maintain SunOS/Solaris compatibility, "
    3021             "consider leaving this\n"
    3022             "partition as Whole disk (5), starting at 0, with %u "
    3023             "sectors\n"), nsec);
    3024     sunlabel->infos[i].id = 0;
    3025     sunlabel->partitions[i].num_sectors = 0;
    3026 }
    3027 
    3028 static void
    3029 sun_change_sysid(int i, int sys)
    3030 {
    3031     if (sys == LINUX_SWAP && !sunlabel->partitions[i].start_cylinder) {
    3032         read_chars(
    3033             _("It is highly recommended that the partition at offset 0\n"
    3034             "is UFS, EXT2FS filesystem or SunOS swap. Putting Linux swap\n"
    3035             "there may destroy your partition table and bootblock.\n"
    3036             "Type YES if you're very sure you would like that partition\n"
    3037             "tagged with 82 (Linux swap): "));
    3038         if (strcmp (line_ptr, _("YES\n")))
    3039             return;
    3040     }
    3041     switch (sys) {
    3042     case SUNOS_SWAP:
    3043     case LINUX_SWAP:
    3044         /* swaps are not mountable by default */
    3045         sunlabel->infos[i].flags |= 0x01;
    3046         break;
    3047     default:
    3048         /* assume other types are mountable;
    3049            user can change it anyway */
    3050         sunlabel->infos[i].flags &= ~0x01;
    3051         break;
    3052     }
    3053     sunlabel->infos[i].id = sys;
    3054 }
    3055 
    3056 static void
    3057 sun_list_table(int xtra)
    3058 {
    3059     int i, w;
    3060 
    3061     w = strlen(disk_device);
    3062     if (xtra)
    3063         printf(
    3064         _("\nDisk %s (Sun disk label): %d heads, %d sectors, %d rpm\n"
    3065         "%d cylinders, %d alternate cylinders, %d physical cylinders\n"
    3066         "%d extra sects/cyl, interleave %d:1\n"
    3067         "%s\n"
    3068         "Units = %s of %d * 512 bytes\n\n"),
    3069             disk_device, heads, sectors, SUN_SSWAP16(sunlabel->rspeed),
    3070             cylinders, SUN_SSWAP16(sunlabel->nacyl),
    3071             SUN_SSWAP16(sunlabel->pcylcount),
    3072             SUN_SSWAP16(sunlabel->sparecyl),
    3073             SUN_SSWAP16(sunlabel->ilfact),
    3074             (char *)sunlabel,
    3075             str_units(PLURAL), units_per_sector);
    3076     else
    3077         printf(
    3078     _("\nDisk %s (Sun disk label): %d heads, %d sectors, %d cylinders\n"
    3079     "Units = %s of %d * 512 bytes\n\n"),
    3080             disk_device, heads, sectors, cylinders,
    3081             str_units(PLURAL), units_per_sector);
    3082 
    3083     printf(_("%*s Flag    Start       End    Blocks   Id  System\n"),
    3084         w + 1, _("Device"));
    3085     for (i = 0 ; i < partitions; i++) {
    3086         if (sunlabel->partitions[i].num_sectors) {
    3087             uint32_t start = SUN_SSWAP32(sunlabel->partitions[i].start_cylinder) * heads * sectors;
    3088             uint32_t len = SUN_SSWAP32(sunlabel->partitions[i].num_sectors);
    3089             printf("%s %c%c %9ld %9ld %9ld%c  %2x  %s\n",
    3090                 partname(disk_device, i+1, w),          /* device */           
    3091                 (sunlabel->infos[i].flags & 0x01) ? 'u' : ' ',  /* flags */             
    3092                 (sunlabel->infos[i].flags & 0x10) ? 'r' : ' ',             
    3093                 (long) scround(start),                          /* start */             
    3094                 (long) scround(start+len),                      /* end */               
    3095                 (long) len / 2, len & 1 ? '+' : ' ',            /* odd flag on end */   
    3096                 sunlabel->infos[i].id,                          /* type id */           
    3097                 partition_type(sunlabel->infos[i].id));         /* type name */         
    3098         }
    3099     }
    3100 }
    3101 
    3102 #ifdef CONFIG_FEATURE_FDISK_ADVANCED
    3103 
    3104 static void
    3105 sun_set_alt_cyl(void)
    3106 {
    3107     sunlabel->nacyl =
    3108         SUN_SSWAP16(read_int(0,SUN_SSWAP16(sunlabel->nacyl), 65535, 0,
    3109                 _("Number of alternate cylinders")));
    3110 }
    3111 
    3112 static void
    3113 sun_set_ncyl(int cyl)
    3114 {
    3115     sunlabel->ncyl = SUN_SSWAP16(cyl);
    3116 }
    3117 
    3118 static void
    3119 sun_set_xcyl(void)
    3120 {
    3121     sunlabel->sparecyl =
    3122         SUN_SSWAP16(read_int(0, SUN_SSWAP16(sunlabel->sparecyl), sectors, 0,
    3123                 _("Extra sectors per cylinder")));
    3124 }
    3125 
    3126 static void
    3127 sun_set_ilfact(void)
    3128 {
    3129     sunlabel->ilfact =
    3130         SUN_SSWAP16(read_int(1, SUN_SSWAP16(sunlabel->ilfact), 32, 0,
    3131                 _("Interleave factor")));
    3132 }
    3133 
    3134 static void
    3135 sun_set_rspeed(void)
    3136 {
    3137     sunlabel->rspeed =
    3138         SUN_SSWAP16(read_int(1, SUN_SSWAP16(sunlabel->rspeed), 100000, 0,
    3139                 _("Rotation speed (rpm)")));
    3140 }
    3141 
    3142 static void
    3143 sun_set_pcylcount(void)
    3144 {
    3145     sunlabel->pcylcount =
    3146         SUN_SSWAP16(read_int(0, SUN_SSWAP16(sunlabel->pcylcount), 65535, 0,
    3147                 _("Number of physical cylinders")));
    3148 }
    3149 #endif /* CONFIG_FEATURE_FDISK_ADVANCED */
    3150 
    3151 static void
    3152 sun_write_table(void)
    3153 {
    3154     unsigned short *ush = (unsigned short *)sunlabel;
    3155     unsigned short csum = 0;
    3156 
    3157     while (ush < (unsigned short *)(&sunlabel->csum))
    3158         csum ^= *ush++;
    3159     sunlabel->csum = csum;
    3160     if (lseek(fd, 0, SEEK_SET) < 0)
    3161         fdisk_fatal(unable_to_seek);
    3162     if (write(fd, sunlabel, SECTOR_SIZE) != SECTOR_SIZE)
    3163         fdisk_fatal(unable_to_write);
    3164 }
    3165 #endif /* SUN_LABEL */
    3166 
    3167 /* DOS partition types */
    3168 
    3169 static const struct systypes i386_sys_types[] = {
    3170     { "\x00" "Empty" },
    3171     { "\x01" "FAT12" },
    3172     { "\x04" "FAT16 <32M" },
    3173     { "\x05" "Extended" },         /* DOS 3.3+ extended partition */
    3174     { "\x06" "FAT16" },            /* DOS 16-bit >=32M */
    3175     { "\x07" "HPFS/NTFS" },        /* OS/2 IFS, eg, HPFS or NTFS or QNX */
    3176     { "\x0a" "OS/2 Boot Manager" },/* OS/2 Boot Manager */
    3177     { "\x0b" "Win95 FAT32" },
    3178     { "\x0c" "Win95 FAT32 (LBA)" },/* LBA really is `Extended Int 13h' */
    3179     { "\x0e" "Win95 FAT16 (LBA)" },
    3180     { "\x0f" "Win95 Ext'd (LBA)" },
    3181     { "\x11" "Hidden FAT12" },
    3182     { "\x12" "Compaq diagnostics" },
    3183     { "\x14" "Hidden FAT16 <32M" },
    3184     { "\x16" "Hidden FAT16" },
    3185     { "\x17" "Hidden HPFS/NTFS" },
    3186     { "\x1b" "Hidden Win95 FAT32" },
    3187     { "\x1c" "Hidden Win95 FAT32 (LBA)" },
    3188     { "\x1e" "Hidden Win95 FAT16 (LBA)" },
    3189     { "\x3c" "PartitionMagic recovery" },
    3190     { "\x41" "PPC PReP Boot" },
    3191     { "\x42" "SFS" },
    3192     { "\x63" "GNU HURD or SysV" }, /* GNU HURD or Mach or Sys V/386 (such as ISC UNIX) */
    3193     { "\x80" "Old Minix" },        /* Minix 1.4a and earlier */
    3194     { "\x81" "Minix / old Linux" },/* Minix 1.4b and later */
    3195     { "\x82" "Linux swap" },       /* also Solaris */
    3196     { "\x83" "Linux" },
    3197     { "\x84" "OS/2 hidden C: drive" },
    3198     { "\x85" "Linux extended" },
    3199     { "\x86" "NTFS volume set" },
    3200     { "\x87" "NTFS volume set" },
    3201     { "\x8e" "Linux LVM" },
    3202     { "\x9f" "BSD/OS" },           /* BSDI */
    3203     { "\xa0" "IBM Thinkpad hibernation" },
    3204     { "\xa5" "FreeBSD" },          /* various BSD flavours */
    3205     { "\xa6" "OpenBSD" },
    3206     { "\xa8" "Darwin UFS" },
    3207     { "\xa9" "NetBSD" },
    3208     { "\xab" "Darwin boot" },
    3209     { "\xb7" "BSDI fs" },
    3210     { "\xb8" "BSDI swap" },
    3211     { "\xbe" "Solaris boot" },
    3212     { "\xeb" "BeOS fs" },
    3213     { "\xee" "EFI GPT" },          /* Intel EFI GUID Partition Table */
    3214     { "\xef" "EFI (FAT-12/16/32)" },/* Intel EFI System Partition */
    3215     { "\xf0" "Linux/PA-RISC boot" },/* Linux/PA-RISC boot loader */
    3216     { "\xf2" "DOS secondary" },    /* DOS 3.3+ secondary */
    3217     { "\xfd" "Linux raid autodetect" },/* New (2.2.x) raid partition with
    3218                         autodetect using persistent
    3219                         superblock */
    3220 #ifdef CONFIG_WEIRD_PARTITION_TYPES
    3221     { "\x02" "XENIX root" },
    3222     { "\x03" "XENIX usr" },
    3223     { "\x08" "AIX" },              /* AIX boot (AIX -- PS/2 port) or SplitDrive */
    3224     { "\x09" "AIX bootable" },     /* AIX data or Coherent */
    3225     { "\x10" "OPUS" },
    3226     { "\x18" "AST SmartSleep" },
    3227     { "\x24" "NEC DOS" },
    3228     { "\x39" "Plan 9" },
    3229     { "\x40" "Venix 80286" },
    3230     { "\x4d" "QNX4.x" },
    3231     { "\x4e" "QNX4.x 2nd part" },
    3232     { "\x4f" "QNX4.x 3rd part" },
    3233     { "\x50" "OnTrack DM" },
    3234     { "\x51" "OnTrack DM6 Aux1" }, /* (or Novell) */
    3235     { "\x52" "CP/M" },             /* CP/M or Microport SysV/AT */
    3236     { "\x53" "OnTrack DM6 Aux3" },
    3237     { "\x54" "OnTrackDM6" },
    3238     { "\x55" "EZ-Drive" },
    3239     { "\x56" "Golden Bow" },
    3240     { "\x5c" "Priam Edisk" },
    3241     { "\x61" "SpeedStor" },
    3242     { "\x64" "Novell Netware 286" },
    3243     { "\x65" "Novell Netware 386" },
    3244     { "\x70" "DiskSecure Multi-Boot" },
    3245     { "\x75" "PC/IX" },
    3246     { "\x93" "Amoeba" },
    3247     { "\x94" "Amoeba BBT" },       /* (bad block table) */
    3248     { "\xa7" "NeXTSTEP" },
    3249     { "\xbb" "Boot Wizard hidden" },
    3250     { "\xc1" "DRDOS/sec (FAT-12)" },
    3251     { "\xc4" "DRDOS/sec (FAT-16 < 32M)" },
    3252     { "\xc6" "DRDOS/sec (FAT-16)" },
    3253     { "\xc7" "Syrinx" },
    3254     { "\xda" "Non-FS data" },
    3255     { "\xdb" "CP/M / CTOS / ..." },/* CP/M or Concurrent CP/M or
    3256                     Concurrent DOS or CTOS */
    3257     { "\xde" "Dell Utility" },     /* Dell PowerEdge Server utilities */
    3258     { "\xdf" "BootIt" },           /* BootIt EMBRM */
    3259     { "\xe1" "DOS access" },       /* DOS access or SpeedStor 12-bit FAT
    3260                     extended partition */
    3261     { "\xe3" "DOS R/O" },          /* DOS R/O or SpeedStor */
    3262     { "\xe4" "SpeedStor" },        /* SpeedStor 16-bit FAT extended
    3263                     partition < 1024 cyl. */
    3264     { "\xf1" "SpeedStor" },
    3265     { "\xf4" "SpeedStor" },        /* SpeedStor large partition */
    3266     { "\xfe" "LANstep" },          /* SpeedStor >1024 cyl. or LANstep */
    3267     { "\xff" "BBT" },              /* Xenix Bad Block Table */
    3268 #endif
    3269     { 0 }
    3270 };
    3271 
    3272 
    3273 
    3274 /* A valid partition table sector ends in 0x55 0xaa */
    3275 static unsigned int
    3276 part_table_flag(const char *b)
    3277 {
    3278     return ((uint) b[510]) + (((uint) b[511]) << 8);
    3279 }
    3280 
    3281 
    3282 #ifdef CONFIG_FEATURE_FDISK_WRITABLE
    3283 static void
    3284 write_part_table_flag(char *b)
    3285 {
    3286     b[510] = 0x55;
    3287     b[511] = 0xaa;
    3288 }
    3289 
     505STATIC_OSF void bsd_select(void);
     506STATIC_OSF void xbsd_print_disklabel(int);
     507#include "fdisk_osf.c"
     508
     509#if ENABLE_FEATURE_SGI_LABEL || ENABLE_FEATURE_SUN_LABEL
     510static uint16_t
     511fdisk_swap16(uint16_t x)
     512{
     513    return (x << 8) | (x >> 8);
     514}
     515
     516static uint32_t
     517fdisk_swap32(uint32_t x)
     518{
     519    return (x << 24) |
     520           ((x & 0xFF00) << 8) |
     521           ((x & 0xFF0000) >> 8) |
     522           (x >> 24);
     523}
     524#endif
     525
     526STATIC_SGI const char *const sgi_sys_types[];
     527STATIC_SGI unsigned sgi_get_num_sectors(int i);
     528STATIC_SGI int sgi_get_sysid(int i);
     529STATIC_SGI void sgi_delete_partition(int i);
     530STATIC_SGI void sgi_change_sysid(int i, int sys);
     531STATIC_SGI void sgi_list_table(int xtra);
     532#if ENABLE_FEATURE_FDISK_ADVANCED
     533STATIC_SGI void sgi_set_xcyl(void);
     534#endif
     535STATIC_SGI int verify_sgi(int verbose);
     536STATIC_SGI void sgi_add_partition(int n, int sys);
     537STATIC_SGI void sgi_set_swappartition(int i);
     538STATIC_SGI const char *sgi_get_bootfile(void);
     539STATIC_SGI void sgi_set_bootfile(const char* aFile);
     540STATIC_SGI void create_sgiinfo(void);
     541STATIC_SGI void sgi_write_table(void);
     542STATIC_SGI void sgi_set_bootpartition(int i);
     543#include "fdisk_sgi.c"
     544
     545STATIC_SUN const char *const sun_sys_types[];
     546STATIC_SUN void sun_delete_partition(int i);
     547STATIC_SUN void sun_change_sysid(int i, int sys);
     548STATIC_SUN void sun_list_table(int xtra);
     549STATIC_SUN void add_sun_partition(int n, int sys);
     550#if ENABLE_FEATURE_FDISK_ADVANCED
     551STATIC_SUN void sun_set_alt_cyl(void);
     552STATIC_SUN void sun_set_ncyl(int cyl);
     553STATIC_SUN void sun_set_xcyl(void);
     554STATIC_SUN void sun_set_ilfact(void);
     555STATIC_SUN void sun_set_rspeed(void);
     556STATIC_SUN void sun_set_pcylcount(void);
     557#endif
     558STATIC_SUN void toggle_sunflags(int i, unsigned char mask);
     559STATIC_SUN void verify_sun(void);
     560STATIC_SUN void sun_write_table(void);
     561#include "fdisk_sun.c"
     562
     563#if ENABLE_FEATURE_FDISK_WRITABLE
    3290564/* start_sect and nr_sects are stored little endian on all machines */
    3291565/* moreover, they are not aligned correctly */
    3292566static void
    3293 store4_little_endian(unsigned char *cp, unsigned int val)
    3294 {
    3295     cp[0] = (val & 0xff);
    3296     cp[1] = ((val >> 8) & 0xff);
    3297     cp[2] = ((val >> 16) & 0xff);
    3298     cp[3] = ((val >> 24) & 0xff);
    3299 }
    3300 #endif /* CONFIG_FEATURE_FDISK_WRITABLE */
    3301 
    3302 static unsigned int
     567store4_little_endian(unsigned char *cp, unsigned val)
     568{
     569    cp[0] = val;
     570    cp[1] = val >> 8;
     571    cp[2] = val >> 16;
     572    cp[3] = val >> 24;
     573}
     574#endif /* FEATURE_FDISK_WRITABLE */
     575
     576static unsigned
    3303577read4_little_endian(const unsigned char *cp)
    3304578{
    3305     return (uint)(cp[0]) + ((uint)(cp[1]) << 8)
    3306         + ((uint)(cp[2]) << 16) + ((uint)(cp[3]) << 24);
    3307 }
    3308 
    3309 #ifdef CONFIG_FEATURE_FDISK_WRITABLE
    3310 static void
    3311 set_start_sect(struct partition *p, unsigned int start_sect)
     579    return cp[0] + (cp[1] << 8) + (cp[2] << 16) + (cp[3] << 24);
     580}
     581
     582#if ENABLE_FEATURE_FDISK_WRITABLE
     583static void
     584set_start_sect(struct partition *p, unsigned start_sect)
    3312585{
    3313586    store4_little_endian(p->start4, start_sect);
     
    3315588#endif
    3316589
    3317 static int32_t
     590static unsigned
    3318591get_start_sect(const struct partition *p)
    3319592{
     
    3321594}
    3322595
    3323 #ifdef CONFIG_FEATURE_FDISK_WRITABLE
    3324 static void
    3325 set_nr_sects(struct partition *p, int32_t nr_sects)
     596#if ENABLE_FEATURE_FDISK_WRITABLE
     597static void
     598set_nr_sects(struct partition *p, unsigned nr_sects)
    3326599{
    3327600    store4_little_endian(p->size4, nr_sects);
     
    3329602#endif
    3330603
    3331 static int32_t
     604static unsigned
    3332605get_nr_sects(const struct partition *p)
    3333606{
     
    3338611static int type_open = O_RDWR;
    3339612
    3340 
    3341613static int ext_index;               /* the prime extended partition */
    3342 static int listing;                    /* no aborts for fdisk -l */
     614static int listing;                 /* no aborts for fdisk -l */
    3343615static int dos_compatible_flag = ~0;
    3344 #ifdef CONFIG_FEATURE_FDISK_WRITABLE
     616#if ENABLE_FEATURE_FDISK_WRITABLE
    3345617static int dos_changed;
    3346618static int nowarn;            /* no warnings for fdisk -l/-s */
    3347619#endif
    3348620
    3349 
    3350 
    3351 static uint user_cylinders, user_heads, user_sectors;
    3352 static uint pt_heads, pt_sectors;
    3353 static uint kern_heads, kern_sectors;
    3354 
    3355 static off_t extended_offset;            /* offset of link pointers */
    3356 
    3357 static unsigned long long total_number_of_sectors;
    3358 
    3359 
    3360 static jmp_buf listingbuf;
    3361 
    3362 static void fdisk_fatal(enum failure why)
    3363 {
    3364     const char *message;
    3365 
     621static unsigned user_cylinders, user_heads, user_sectors;
     622static unsigned pt_heads, pt_sectors;
     623static unsigned kern_heads, kern_sectors;
     624
     625static ullong extended_offset;            /* offset of link pointers */
     626static ullong total_number_of_sectors;
     627
     628static void fdisk_fatal(const char *why)
     629{
    3366630    if (listing) {
    3367631        close(fd);
    3368632        longjmp(listingbuf, 1);
    3369633    }
    3370 
    3371     switch (why) {
    3372     case unable_to_open:
    3373         message = "Unable to open %s\n";
    3374         break;
    3375     case unable_to_read:
    3376         message = "Unable to read %s\n";
    3377         break;
    3378     case unable_to_seek:
    3379         message = "Unable to seek on %s\n";
    3380         break;
    3381     case unable_to_write:
    3382         message = "Unable to write %s\n";
    3383         break;
    3384     case ioctl_error:
    3385         message = "BLKGETSIZE ioctl failed on %s\n";
    3386         break;
    3387     default:
    3388         message = "Fatal error\n";
    3389     }
    3390 
    3391     fputc('\n', stderr);
    3392     fprintf(stderr, message, disk_device);
    3393     exit(1);
    3394 }
    3395 
    3396 static void
    3397 seek_sector(off_t secno)
    3398 {
    3399     off_t offset = secno * sector_size;
    3400     if (lseek(fd, offset, SEEK_SET) == (off_t) -1)
     634    bb_error_msg_and_die(why, disk_device);
     635}
     636
     637static void
     638seek_sector(ullong secno)
     639{
     640    secno *= sector_size;
     641#if ENABLE_FDISK_SUPPORT_LARGE_DISKS
     642    if (lseek64(fd, (off64_t)secno, SEEK_SET) == (off64_t) -1)
    3401643        fdisk_fatal(unable_to_seek);
    3402 }
    3403 
    3404 #ifdef CONFIG_FEATURE_FDISK_WRITABLE
    3405 static void
    3406 write_sector(off_t secno, char *buf)
     644#else
     645    if (secno > MAXINT(off_t)
     646     || lseek(fd, (off_t)secno, SEEK_SET) == (off_t) -1
     647    ) {
     648        fdisk_fatal(unable_to_seek);
     649    }
     650#endif
     651}
     652
     653#if ENABLE_FEATURE_FDISK_WRITABLE
     654static void
     655write_sector(ullong secno, char *buf)
    3407656{
    3408657    seek_sector(secno);
     
    3414663/* Allocate a buffer and read a partition table sector */
    3415664static void
    3416 read_pte(struct pte *pe, off_t offset)
     665read_pte(struct pte *pe, ullong offset)
    3417666{
    3418667    pe->offset = offset;
    3419     pe->sectorbuffer = (char *) xmalloc(sector_size);
     668    pe->sectorbuffer = xmalloc(sector_size);
    3420669    seek_sector(offset);
    3421670    if (read(fd, pe->sectorbuffer, sector_size) != sector_size)
    3422671        fdisk_fatal(unable_to_read);
    3423 #ifdef CONFIG_FEATURE_FDISK_WRITABLE
     672#if ENABLE_FEATURE_FDISK_WRITABLE
    3424673    pe->changed = 0;
    3425674#endif
     
    3427676}
    3428677
    3429 static unsigned int
     678static unsigned
    3430679get_partition_start(const struct pte *pe)
    3431680{
     
    3433682}
    3434683
    3435 #ifdef CONFIG_FEATURE_FDISK_WRITABLE
     684#if ENABLE_FEATURE_FDISK_WRITABLE
    3436685/*
    3437686 * Avoid warning about DOS partitions when no DOS partition was changed.
     
    3453702menu(void)
    3454703{
    3455 #ifdef CONFIG_FEATURE_SUN_LABEL
    3456     if (label_sun == current_label_type) {
    3457         puts(_("Command action"));
    3458         puts(_("\ta\ttoggle a read only flag"));           /* sun */
    3459         puts(_("\tb\tedit bsd disklabel"));
    3460         puts(_("\tc\ttoggle the mountable flag"));         /* sun */
    3461         puts(_("\td\tdelete a partition"));
    3462         puts(_("\tl\tlist known partition types"));
    3463         puts(_("\tm\tprint this menu"));
    3464         puts(_("\tn\tadd a new partition"));
    3465         puts(_("\to\tcreate a new empty DOS partition table"));
    3466         puts(_("\tp\tprint the partition table"));
    3467         puts(_("\tq\tquit without saving changes"));
    3468         puts(_("\ts\tcreate a new empty Sun disklabel"));  /* sun */
    3469         puts(_("\tt\tchange a partition's system id"));
    3470         puts(_("\tu\tchange display/entry units"));
    3471         puts(_("\tv\tverify the partition table"));
    3472         puts(_("\tw\twrite table to disk and exit"));
    3473 #ifdef CONFIG_FEATURE_FDISK_ADVANCED
    3474         puts(_("\tx\textra functionality (experts only)"));
    3475 #endif
    3476     } else
    3477 #endif
    3478 #ifdef CONFIG_FEATURE_SGI_LABEL
    3479     if (label_sgi == current_label_type) {
    3480         puts(_("Command action"));
    3481         puts(_("\ta\tselect bootable partition"));    /* sgi flavour */
    3482         puts(_("\tb\tedit bootfile entry"));          /* sgi */
    3483         puts(_("\tc\tselect sgi swap partition"));    /* sgi flavour */
    3484         puts(_("\td\tdelete a partition"));
    3485         puts(_("\tl\tlist known partition types"));
    3486         puts(_("\tm\tprint this menu"));
    3487         puts(_("\tn\tadd a new partition"));
    3488         puts(_("\to\tcreate a new empty DOS partition table"));
    3489         puts(_("\tp\tprint the partition table"));
    3490         puts(_("\tq\tquit without saving changes"));
    3491         puts(_("\ts\tcreate a new empty Sun disklabel"));  /* sun */
    3492         puts(_("\tt\tchange a partition's system id"));
    3493         puts(_("\tu\tchange display/entry units"));
    3494         puts(_("\tv\tverify the partition table"));
    3495         puts(_("\tw\twrite table to disk and exit"));
    3496     } else
    3497 #endif
    3498 #ifdef CONFIG_FEATURE_AIX_LABEL
    3499     if (label_aix == current_label_type) {
    3500         puts(_("Command action"));
    3501         puts(_("\tm\tprint this menu"));
    3502         puts(_("\to\tcreate a new empty DOS partition table"));
    3503         puts(_("\tq\tquit without saving changes"));
    3504         puts(_("\ts\tcreate a new empty Sun disklabel"));  /* sun */
    3505     } else
    3506 #endif
    3507     {
    3508         puts(_("Command action"));
    3509         puts(_("\ta\ttoggle a bootable flag"));
    3510         puts(_("\tb\tedit bsd disklabel"));
    3511         puts(_("\tc\ttoggle the dos compatibility flag"));
    3512         puts(_("\td\tdelete a partition"));
    3513         puts(_("\tl\tlist known partition types"));
    3514         puts(_("\tm\tprint this menu"));
    3515         puts(_("\tn\tadd a new partition"));
    3516         puts(_("\to\tcreate a new empty DOS partition table"));
    3517         puts(_("\tp\tprint the partition table"));
    3518         puts(_("\tq\tquit without saving changes"));
    3519         puts(_("\ts\tcreate a new empty Sun disklabel"));  /* sun */
    3520         puts(_("\tt\tchange a partition's system id"));
    3521         puts(_("\tu\tchange display/entry units"));
    3522         puts(_("\tv\tverify the partition table"));
    3523         puts(_("\tw\twrite table to disk and exit"));
    3524 #ifdef CONFIG_FEATURE_FDISK_ADVANCED
    3525         puts(_("\tx\textra functionality (experts only)"));
    3526 #endif
    3527     }
    3528 }
    3529 #endif /* CONFIG_FEATURE_FDISK_WRITABLE */
    3530 
    3531 
    3532 #ifdef CONFIG_FEATURE_FDISK_ADVANCED
     704    puts("Command Action");
     705    if (LABEL_IS_SUN) {
     706        puts("a\ttoggle a read only flag");           /* sun */
     707        puts("b\tedit bsd disklabel");
     708        puts("c\ttoggle the mountable flag");         /* sun */
     709        puts("d\tdelete a partition");
     710        puts("l\tlist known partition types");
     711        puts("n\tadd a new partition");
     712        puts("o\tcreate a new empty DOS partition table");
     713        puts("p\tprint the partition table");
     714        puts("q\tquit without saving changes");
     715        puts("s\tcreate a new empty Sun disklabel");  /* sun */
     716        puts("t\tchange a partition's system id");
     717        puts("u\tchange display/entry units");
     718        puts("v\tverify the partition table");
     719        puts("w\twrite table to disk and exit");
     720#if ENABLE_FEATURE_FDISK_ADVANCED
     721        puts("x\textra functionality (experts only)");
     722#endif
     723    } else if (LABEL_IS_SGI) {
     724        puts("a\tselect bootable partition");    /* sgi flavour */
     725        puts("b\tedit bootfile entry");          /* sgi */
     726        puts("c\tselect sgi swap partition");    /* sgi flavour */
     727        puts("d\tdelete a partition");
     728        puts("l\tlist known partition types");
     729        puts("n\tadd a new partition");
     730        puts("o\tcreate a new empty DOS partition table");
     731        puts("p\tprint the partition table");
     732        puts("q\tquit without saving changes");
     733        puts("s\tcreate a new empty Sun disklabel");  /* sun */
     734        puts("t\tchange a partition's system id");
     735        puts("u\tchange display/entry units");
     736        puts("v\tverify the partition table");
     737        puts("w\twrite table to disk and exit");
     738    } else if (LABEL_IS_AIX) {
     739        puts("o\tcreate a new empty DOS partition table");
     740        puts("q\tquit without saving changes");
     741        puts("s\tcreate a new empty Sun disklabel");  /* sun */
     742    } else {
     743        puts("a\ttoggle a bootable flag");
     744        puts("b\tedit bsd disklabel");
     745        puts("c\ttoggle the dos compatibility flag");
     746        puts("d\tdelete a partition");
     747        puts("l\tlist known partition types");
     748        puts("n\tadd a new partition");
     749        puts("o\tcreate a new empty DOS partition table");
     750        puts("p\tprint the partition table");
     751        puts("q\tquit without saving changes");
     752        puts("s\tcreate a new empty Sun disklabel");  /* sun */
     753        puts("t\tchange a partition's system id");
     754        puts("u\tchange display/entry units");
     755        puts("v\tverify the partition table");
     756        puts("w\twrite table to disk and exit");
     757#if ENABLE_FEATURE_FDISK_ADVANCED
     758        puts("x\textra functionality (experts only)");
     759#endif
     760    }
     761}
     762#endif /* FEATURE_FDISK_WRITABLE */
     763
     764
     765#if ENABLE_FEATURE_FDISK_ADVANCED
    3533766static void
    3534767xmenu(void)
    3535768{
    3536 #ifdef CONFIG_FEATURE_SUN_LABEL
    3537     if (label_sun == current_label_type) {
    3538     puts(_("Command action"));
    3539     puts(_("\ta\tchange number of alternate cylinders"));      /*sun*/
    3540     puts(_("\tc\tchange number of cylinders"));
    3541     puts(_("\td\tprint the raw data in the partition table"));
    3542     puts(_("\te\tchange number of extra sectors per cylinder"));/*sun*/
    3543     puts(_("\th\tchange number of heads"));
    3544     puts(_("\ti\tchange interleave factor"));                  /*sun*/
    3545     puts(_("\to\tchange rotation speed (rpm)"));               /*sun*/
    3546     puts(_("\tm\tprint this menu"));
    3547     puts(_("\tp\tprint the partition table"));
    3548     puts(_("\tq\tquit without saving changes"));
    3549     puts(_("\tr\treturn to main menu"));
    3550     puts(_("\ts\tchange number of sectors/track"));
    3551     puts(_("\tv\tverify the partition table"));
    3552     puts(_("\tw\twrite table to disk and exit"));
    3553     puts(_("\ty\tchange number of physical cylinders"));       /*sun*/
    3554     }  else
    3555 #endif
    3556 #ifdef CONFIG_FEATURE_SGI_LABEL
    3557     if (label_sgi == current_label_type) {
    3558         puts(_("Command action"));
    3559         puts(_("\tb\tmove beginning of data in a partition")); /* !sun */
    3560         puts(_("\tc\tchange number of cylinders"));
    3561         puts(_("\td\tprint the raw data in the partition table"));
    3562         puts(_("\te\tlist extended partitions"));          /* !sun */
    3563         puts(_("\tg\tcreate an IRIX (SGI) partition table"));/* sgi */
    3564         puts(_("\th\tchange number of heads"));
    3565         puts(_("\tm\tprint this menu"));
    3566         puts(_("\tp\tprint the partition table"));
    3567         puts(_("\tq\tquit without saving changes"));
    3568         puts(_("\tr\treturn to main menu"));
    3569         puts(_("\ts\tchange number of sectors/track"));
    3570         puts(_("\tv\tverify the partition table"));
    3571         puts(_("\tw\twrite table to disk and exit"));
    3572     } else
    3573 #endif
    3574 #ifdef CONFIG_FEATURE_AIX_LABEL
    3575     if (label_aix == current_label_type) {
    3576         puts(_("Command action"));
    3577         puts(_("\tb\tmove beginning of data in a partition")); /* !sun */
    3578         puts(_("\tc\tchange number of cylinders"));
    3579         puts(_("\td\tprint the raw data in the partition table"));
    3580         puts(_("\te\tlist extended partitions"));          /* !sun */
    3581         puts(_("\tg\tcreate an IRIX (SGI) partition table"));/* sgi */
    3582         puts(_("\th\tchange number of heads"));
    3583         puts(_("\tm\tprint this menu"));
    3584         puts(_("\tp\tprint the partition table"));
    3585         puts(_("\tq\tquit without saving changes"));
    3586         puts(_("\tr\treturn to main menu"));
    3587         puts(_("\ts\tchange number of sectors/track"));
    3588         puts(_("\tv\tverify the partition table"));
    3589         puts(_("\tw\twrite table to disk and exit"));
    3590     }  else
    3591 #endif
    3592     {
    3593         puts(_("Command action"));
    3594         puts(_("\tb\tmove beginning of data in a partition")); /* !sun */
    3595         puts(_("\tc\tchange number of cylinders"));
    3596         puts(_("\td\tprint the raw data in the partition table"));
    3597         puts(_("\te\tlist extended partitions"));          /* !sun */
    3598         puts(_("\tf\tfix partition order"));               /* !sun, !aix, !sgi */
    3599 #ifdef CONFIG_FEATURE_SGI_LABEL
    3600         puts(_("\tg\tcreate an IRIX (SGI) partition table"));/* sgi */
    3601 #endif
    3602         puts(_("\th\tchange number of heads"));
    3603         puts(_("\tm\tprint this menu"));
    3604         puts(_("\tp\tprint the partition table"));
    3605         puts(_("\tq\tquit without saving changes"));
    3606         puts(_("\tr\treturn to main menu"));
    3607         puts(_("\ts\tchange number of sectors/track"));
    3608         puts(_("\tv\tverify the partition table"));
    3609         puts(_("\tw\twrite table to disk and exit"));
     769    puts("Command Action");
     770    if (LABEL_IS_SUN) {
     771        puts("a\tchange number of alternate cylinders");      /*sun*/
     772        puts("c\tchange number of cylinders");
     773        puts("d\tprint the raw data in the partition table");
     774        puts("e\tchange number of extra sectors per cylinder");/*sun*/
     775        puts("h\tchange number of heads");
     776        puts("i\tchange interleave factor");                  /*sun*/
     777        puts("o\tchange rotation speed (rpm)");               /*sun*/
     778        puts("p\tprint the partition table");
     779        puts("q\tquit without saving changes");
     780        puts("r\treturn to main menu");
     781        puts("s\tchange number of sectors/track");
     782        puts("v\tverify the partition table");
     783        puts("w\twrite table to disk and exit");
     784        puts("y\tchange number of physical cylinders");       /*sun*/
     785    } else if (LABEL_IS_SGI) {
     786        puts("b\tmove beginning of data in a partition"); /* !sun */
     787        puts("c\tchange number of cylinders");
     788        puts("d\tprint the raw data in the partition table");
     789        puts("e\tlist extended partitions");          /* !sun */
     790        puts("g\tcreate an IRIX (SGI) partition table");/* sgi */
     791        puts("h\tchange number of heads");
     792        puts("p\tprint the partition table");
     793        puts("q\tquit without saving changes");
     794        puts("r\treturn to main menu");
     795        puts("s\tchange number of sectors/track");
     796        puts("v\tverify the partition table");
     797        puts("w\twrite table to disk and exit");
     798    } else if (LABEL_IS_AIX) {
     799        puts("b\tmove beginning of data in a partition"); /* !sun */
     800        puts("c\tchange number of cylinders");
     801        puts("d\tprint the raw data in the partition table");
     802        puts("e\tlist extended partitions");          /* !sun */
     803        puts("g\tcreate an IRIX (SGI) partition table");/* sgi */
     804        puts("h\tchange number of heads");
     805        puts("p\tprint the partition table");
     806        puts("q\tquit without saving changes");
     807        puts("r\treturn to main menu");
     808        puts("s\tchange number of sectors/track");
     809        puts("v\tverify the partition table");
     810        puts("w\twrite table to disk and exit");
     811    } else {
     812        puts("b\tmove beginning of data in a partition"); /* !sun */
     813        puts("c\tchange number of cylinders");
     814        puts("d\tprint the raw data in the partition table");
     815        puts("e\tlist extended partitions");          /* !sun */
     816        puts("f\tfix partition order");               /* !sun, !aix, !sgi */
     817#if ENABLE_FEATURE_SGI_LABEL
     818        puts("g\tcreate an IRIX (SGI) partition table");/* sgi */
     819#endif
     820        puts("h\tchange number of heads");
     821        puts("p\tprint the partition table");
     822        puts("q\tquit without saving changes");
     823        puts("r\treturn to main menu");
     824        puts("s\tchange number of sectors/track");
     825        puts("v\tverify the partition table");
     826        puts("w\twrite table to disk and exit");
    3610827    }
    3611828}
    3612829#endif /* ADVANCED mode */
    3613830
    3614 #ifdef CONFIG_FEATURE_FDISK_WRITABLE
    3615 static const struct systypes *
     831#if ENABLE_FEATURE_FDISK_WRITABLE
     832static const char *const *
    3616833get_sys_types(void)
    3617834{
    3618835    return (
    3619 #ifdef CONFIG_FEATURE_SUN_LABEL
    3620         label_sun == current_label_type ? sun_sys_types :
    3621 #endif
    3622 #ifdef CONFIG_FEATURE_SGI_LABEL
    3623         label_sgi == current_label_type ? sgi_sys_types :
    3624 #endif
     836        LABEL_IS_SUN ? sun_sys_types :
     837        LABEL_IS_SGI ? sgi_sys_types :
    3625838        i386_sys_types);
    3626839}
    3627840#else
    3628841#define get_sys_types() i386_sys_types
    3629 #endif /* CONFIG_FEATURE_FDISK_WRITABLE */
    3630 
    3631 static const char *partition_type(unsigned char type)
     842#endif /* FEATURE_FDISK_WRITABLE */
     843
     844static const char *
     845partition_type(unsigned char type)
    3632846{
    3633847    int i;
    3634     const struct systypes *types = get_sys_types();
    3635 
    3636     for (i = 0; types[i].name; i++)
    3637         if ((unsigned char )types[i].name[0] == type)
    3638             return types[i].name + 1;
    3639 
    3640     return _("Unknown");
    3641 }
    3642 
    3643 
    3644 #ifdef CONFIG_FEATURE_FDISK_WRITABLE
     848    const char *const *types = get_sys_types();
     849
     850    for (i = 0; types[i]; i++)
     851        if ((unsigned char)types[i][0] == type)
     852            return types[i] + 1;
     853
     854    return "Unknown";
     855}
     856
     857
     858#if ENABLE_FEATURE_FDISK_WRITABLE
    3645859static int
    3646860get_sysid(int i)
    3647861{
    3648     return (
    3649 #ifdef CONFIG_FEATURE_SUN_LABEL
    3650         label_sun == current_label_type ? sunlabel->infos[i].id :
    3651 #endif
    3652 #ifdef CONFIG_FEATURE_SGI_LABEL
    3653         label_sgi == current_label_type ? sgi_get_sysid(i) :
    3654 #endif
    3655         ptes[i].part_table->sys_ind);
    3656 }
    3657 
    3658 void list_types(const struct systypes *sys)
    3659 {
    3660     uint last[4], done = 0, next = 0, size;
     862    return LABEL_IS_SUN ? sunlabel->infos[i].id :
     863            (LABEL_IS_SGI ? sgi_get_sysid(i) :
     864                ptes[i].part_table->sys_ind);
     865}
     866
     867static void
     868list_types(const char *const *sys)
     869{
     870    enum { COLS = 3 };
     871
     872    unsigned last[COLS];
     873    unsigned done, next, size;
    3661874    int i;
    3662875
    3663     for (i = 0; sys[i].name; i++);
    3664     size = i;
    3665 
    3666     for (i = 3; i >= 0; i--)
    3667         last[3 - i] = done += (size + i - done) / (i + 1);
    3668     i = done = 0;
    3669 
     876    for (size = 0; sys[size]; size++) /* */;
     877
     878    done = 0;
     879    for (i = COLS-1; i >= 0; i--) {
     880        done += (size + i - done) / (i + 1);
     881        last[COLS-1 - i] = done;
     882    }
     883
     884    i = done = next = 0;
    3670885    do {
    3671         printf("%c%2x  %-15.15s", i ? ' ' : '\n',
    3672             (unsigned char)sys[next].name[0],
    3673             partition_type((unsigned char)sys[next].name[0]));
     886        printf("%c%2x %-22.22s", i ? ' ' : '\n',
     887            (unsigned char)sys[next][0],
     888            sys[next] + 1);
    3674889        next = last[i++] + done;
    3675         if (i > 3 || next >= last[i]) {
     890        if (i >= COLS || next >= last[i]) {
    3676891            i = 0;
    3677892            next = ++done;
     
    3680895    putchar('\n');
    3681896}
    3682 #endif /* CONFIG_FEATURE_FDISK_WRITABLE */
     897#endif /* FEATURE_FDISK_WRITABLE */
    3683898
    3684899static int
     
    3698913}
    3699914
    3700 #ifdef CONFIG_FEATURE_FDISK_WRITABLE
    3701 static void
    3702 set_partition(int i, int doext, off_t start, off_t stop, int sysid)
     915#if ENABLE_FEATURE_FDISK_WRITABLE
     916static void
     917set_partition(int i, int doext, ullong start, ullong stop, int sysid)
    3703918{
    3704919    struct partition *p;
    3705     off_t offset;
     920    ullong offset;
    3706921
    3707922    if (doext) {
     
    3727942
    3728943static int
    3729 test_c(const char **m, const char *mesg)
    3730 {
    3731     int val = 0;
    3732     if (!*m)
    3733         fprintf(stderr, _("You must set"));
    3734     else {
    3735         fprintf(stderr, " %s", *m);
    3736         val = 1;
    3737     }
    3738     *m = mesg;
    3739     return val;
    3740 }
    3741 
    3742 static int
    3743944warn_geometry(void)
    3744945{
    3745     const char *m = NULL;
    3746     int prev = 0;
    3747 
     946    if (heads && sectors && cylinders)
     947        return 0;
     948
     949    printf("Unknown value(s) for:");
    3748950    if (!heads)
    3749         prev = test_c(&m, _("heads"));
     951        printf(" heads");
    3750952    if (!sectors)
    3751         prev = test_c(&m, _("sectors"));
     953        printf(" sectors");
    3752954    if (!cylinders)
    3753         prev = test_c(&m, _("cylinders"));
    3754     if (!m)
    3755         return 0;
    3756 
    3757     fprintf(stderr, "%s%s.\n"
    3758 #ifdef CONFIG_FEATURE_FDISK_WRITABLE
    3759             "You can do this from the extra functions menu.\n"
    3760 #endif
    3761         , prev ? _(" and ") : " ", m);
    3762 
     955        printf(" cylinders");
     956    printf(
     957#if ENABLE_FEATURE_FDISK_WRITABLE
     958        " (settable in the extra functions menu)"
     959#endif
     960        "\n");
    3763961    return 1;
    3764962}
    3765963
    3766 static void update_units(void)
     964static void
     965update_units(void)
    3767966{
    3768967    int cyl_units = heads * sectors;
     
    3774973}
    3775974
    3776 #ifdef CONFIG_FEATURE_FDISK_WRITABLE
     975#if ENABLE_FEATURE_FDISK_WRITABLE
    3777976static void
    3778977warn_cylinders(void)
    3779978{
    3780     if (label_dos == current_label_type && cylinders > 1024 && !nowarn)
    3781         fprintf(stderr, _("\n"
     979    if (LABEL_IS_DOS && cylinders > 1024 && !nowarn)
     980        printf("\n"
    3782981"The number of cylinders for this disk is set to %d.\n"
    3783982"There is nothing wrong with that, but this is larger than 1024,\n"
     
    3785984"1) software that runs at boot time (e.g., old versions of LILO)\n"
    3786985"2) booting and partitioning software from other OSs\n"
    3787 "   (e.g., DOS FDISK, OS/2 FDISK)\n"),
     986"   (e.g., DOS FDISK, OS/2 FDISK)\n",
    3788987            cylinders);
    3789988}
     
    38031002    p = pex->part_table;
    38041003    if (!get_start_sect(p)) {
    3805         fprintf(stderr,
    3806             _("Bad offset in primary extended partition\n"));
     1004        printf("Bad offset in primary extended partition\n");
    38071005        return;
    38081006    }
     
    38141012            /* This is not a Linux restriction, but
    38151013               this program uses arrays of size MAXIMUM_PARTS.
    3816                Do not try to `improve' this test. */
     1014               Do not try to 'improve' this test. */
    38171015            struct pte *pre = &ptes[partitions-1];
    3818 #ifdef CONFIG_FEATURE_FDISK_WRITABLE
    3819             fprintf(stderr,
    3820                 _("Warning: deleting partitions after %d\n"),
     1016#if ENABLE_FEATURE_FDISK_WRITABLE
     1017            printf("Warning: deleting partitions after %d\n",
    38211018                partitions);
    38221019            pre->changed = 1;
     
    38351032            if (IS_EXTENDED(p->sys_ind)) {
    38361033                if (pe->ext_pointer)
    3837                     fprintf(stderr,
    3838                         _("Warning: extra link "
    3839                           "pointer in partition table"
    3840                           " %d\n"), partitions + 1);
     1034                    printf("Warning: extra link "
     1035                        "pointer in partition table"
     1036                        " %d\n", partitions + 1);
    38411037                else
    38421038                    pe->ext_pointer = p;
    38431039            } else if (p->sys_ind) {
    38441040                if (pe->part_table)
    3845                     fprintf(stderr,
    3846                         _("Warning: ignoring extra "
     1041                    printf("Warning: ignoring extra "
    38471042                          "data in partition table"
    3848                           " %d\n"), partitions + 1);
     1043                          " %d\n", partitions + 1);
    38491044                else
    38501045                    pe->part_table = p;
     
    38701065    }
    38711066
    3872 #ifdef CONFIG_FEATURE_FDISK_WRITABLE
     1067#if ENABLE_FEATURE_FDISK_WRITABLE
    38731068    /* remove empty links */
    38741069 remove:
     
    38761071        struct pte *pe = &ptes[i];
    38771072
    3878         if (!get_nr_sects(pe->part_table) &&
    3879             (partitions > 5 || ptes[4].part_table->sys_ind)) {
    3880             printf("omitting empty partition (%d)\n", i+1);
     1073        if (!get_nr_sects(pe->part_table)
     1074         && (partitions > 5 || ptes[4].part_table->sys_ind)
     1075        ) {
     1076            printf("Omitting empty partition (%d)\n", i+1);
    38811077            delete_partition(i);
    38821078            goto remove;    /* numbering changed */
     
    38861082}
    38871083
    3888 #ifdef CONFIG_FEATURE_FDISK_WRITABLE
     1084#if ENABLE_FEATURE_FDISK_WRITABLE
    38891085static void
    38901086create_doslabel(void)
     
    38921088    int i;
    38931089
    3894     fprintf(stderr,
    3895     _("Building a new DOS disklabel. Changes will remain in memory only,\n"
    3896       "until you decide to write them. After that, of course, the previous\n"
    3897       "content won't be recoverable.\n\n"));
     1090    printf(msg_building_new_label, "DOS disklabel");
    38981091
    38991092    current_label_type = label_dos;
    39001093
    3901 #ifdef CONFIG_FEATURE_OSF_LABEL
     1094#if ENABLE_FEATURE_OSF_LABEL
    39021095    possibly_osf_label = 0;
    39031096#endif
     
    39121105    get_boot(create_empty_dos);
    39131106}
    3914 #endif /* CONFIG_FEATURE_FDISK_WRITABLE */
     1107#endif /* FEATURE_FDISK_WRITABLE */
    39151108
    39161109static void
     
    39221115            sector_size = arg;
    39231116        if (sector_size != DEFAULT_SECTOR_SIZE)
    3924             printf(_("Note: sector size is %d (not %d)\n"),
     1117            printf("Note: sector size is %d (not %d)\n",
    39251118                   sector_size, DEFAULT_SECTOR_SIZE);
    39261119    }
    39271120}
    39281121
    3929 static inline void
     1122static void
    39301123get_kernel_geometry(void)
    39311124{
     
    39761169{
    39771170    int sec_fac;
    3978     unsigned long long bytes;       /* really u64 */
     1171    uint64_t v64;
    39791172
    39801173    get_sectorsize();
    39811174    sec_fac = sector_size / 512;
    3982 #ifdef CONFIG_FEATURE_SUN_LABEL
     1175#if ENABLE_FEATURE_SUN_LABEL
    39831176    guess_device_type();
    39841177#endif
     
    39961189        pt_sectors ? pt_sectors :
    39971190        kern_sectors ? kern_sectors : 63;
    3998     if (ioctl(fd, BLKGETSIZE64, &bytes) == 0) {
    3999         /* got bytes */
     1191    if (ioctl(fd, BLKGETSIZE64, &v64) == 0) {
     1192        /* got bytes, convert to 512 byte sectors */
     1193        total_number_of_sectors = (v64 >> 9);
    40001194    } else {
    4001         unsigned long longsectors;
    4002 
    4003     if (ioctl(fd, BLKGETSIZE, &longsectors))
    4004         longsectors = 0;
    4005             bytes = ((unsigned long long) longsectors) << 9;
    4006     }
    4007 
    4008     total_number_of_sectors = (bytes >> 9);
     1195        unsigned long longsectors; /* need temp of type long */
     1196        if (ioctl(fd, BLKGETSIZE, &longsectors))
     1197            longsectors = 0;
     1198        total_number_of_sectors = longsectors;
     1199    }
    40091200
    40101201    sector_offset = 1;
     
    40371228        pe->offset = 0;
    40381229        pe->sectorbuffer = MBRbuffer;
    4039 #ifdef CONFIG_FEATURE_FDISK_WRITABLE
     1230#if ENABLE_FEATURE_FDISK_WRITABLE
    40401231        pe->changed = (what == create_empty_dos);
    40411232#endif
    40421233    }
    40431234
    4044 #ifdef CONFIG_FEATURE_SUN_LABEL
     1235#if ENABLE_FEATURE_SUN_LABEL
    40451236    if (what == create_empty_sun && check_sun_label())
    40461237        return 0;
     
    40491240    memset(MBRbuffer, 0, 512);
    40501241
    4051 #ifdef CONFIG_FEATURE_FDISK_WRITABLE
     1242#if ENABLE_FEATURE_FDISK_WRITABLE
    40521243    if (what == create_empty_dos)
    40531244        goto got_dos_table;             /* skip reading disk */
    40541245
    4055     if ((fd = open(disk_device, type_open)) < 0) {
    4056         if ((fd = open(disk_device, O_RDONLY)) < 0) {
     1246    fd = open(disk_device, type_open);
     1247    if (fd < 0) {
     1248        fd = open(disk_device, O_RDONLY);
     1249        if (fd < 0) {
    40571250            if (what == try_only)
    40581251                return 1;
    40591252            fdisk_fatal(unable_to_open);
    40601253        } else
    4061             printf(_("You will not be able to write "
    4062                 "the partition table.\n"));
     1254            printf("You will not be able to write "
     1255                "the partition table\n");
    40631256    }
    40641257
     
    40691262    }
    40701263#else
    4071     if ((fd = open(disk_device, O_RDONLY)) < 0)
     1264    fd = open(disk_device, O_RDONLY);
     1265    if (fd < 0)
    40721266        return 1;
    40731267    if (512 != read(fd, MBRbuffer, 512))
     
    40791273    update_units();
    40801274
    4081 #ifdef CONFIG_FEATURE_SUN_LABEL
     1275#if ENABLE_FEATURE_SUN_LABEL
    40821276    if (check_sun_label())
    40831277        return 0;
    40841278#endif
    40851279
    4086 #ifdef CONFIG_FEATURE_SGI_LABEL
     1280#if ENABLE_FEATURE_SGI_LABEL
    40871281    if (check_sgi_label())
    40881282        return 0;
    40891283#endif
    40901284
    4091 #ifdef CONFIG_FEATURE_AIX_LABEL
     1285#if ENABLE_FEATURE_AIX_LABEL
    40921286    if (check_aix_label())
    40931287        return 0;
    40941288#endif
    40951289
    4096 #ifdef CONFIG_FEATURE_OSF_LABEL
     1290#if ENABLE_FEATURE_OSF_LABEL
    40971291    if (check_osf_label()) {
    40981292        possibly_osf_label = 1;
     
    41011295            return 0;
    41021296        }
    4103         printf(_("This disk has both DOS and BSD magic.\n"
    4104              "Give the 'b' command to go to BSD mode.\n"));
    4105     }
    4106 #endif
    4107 
    4108 #ifdef CONFIG_FEATURE_FDISK_WRITABLE
     1297        printf("This disk has both DOS and BSD magic.\n"
     1298             "Give the 'b' command to go to BSD mode.\n");
     1299    }
     1300#endif
     1301
     1302#if ENABLE_FEATURE_FDISK_WRITABLE
    41091303 got_dos_table:
    41101304#endif
    41111305
    41121306    if (!valid_part_table_flag(MBRbuffer)) {
    4113 #ifndef CONFIG_FEATURE_FDISK_WRITABLE
     1307#if !ENABLE_FEATURE_FDISK_WRITABLE
    41141308        return -1;
    41151309#else
    41161310        switch (what) {
    41171311        case fdisk:
    4118             fprintf(stderr,
    4119                 _("Device contains neither a valid DOS "
     1312            printf("Device contains neither a valid DOS "
    41201313                  "partition table, nor Sun, SGI or OSF "
    4121                   "disklabel\n"));
     1314                  "disklabel\n");
    41221315#ifdef __sparc__
    4123 #ifdef CONFIG_FEATURE_SUN_LABEL
     1316#if ENABLE_FEATURE_SUN_LABEL
    41241317            create_sunlabel();
    41251318#endif
     
    41311324            return -1;
    41321325        case create_empty_dos:
    4133 #ifdef CONFIG_FEATURE_SUN_LABEL
     1326#if ENABLE_FEATURE_SUN_LABEL
    41341327        case create_empty_sun:
    41351328#endif
    41361329            break;
    41371330        default:
    4138             fprintf(stderr, _("Internal error\n"));
    4139             exit(1);
    4140         }
    4141 #endif /* CONFIG_FEATURE_FDISK_WRITABLE */
    4142     }
    4143 
    4144 #ifdef CONFIG_FEATURE_FDISK_WRITABLE
     1331            bb_error_msg_and_die("internal error");
     1332        }
     1333#endif /* FEATURE_FDISK_WRITABLE */
     1334    }
     1335
     1336#if ENABLE_FEATURE_FDISK_WRITABLE
    41451337    warn_cylinders();
    41461338#endif
     
    41521344        if (IS_EXTENDED(pe->part_table->sys_ind)) {
    41531345            if (partitions != 4)
    4154                 fprintf(stderr, _("Ignoring extra extended "
    4155                     "partition %d\n"), i + 1);
     1346                printf("Ignoring extra extended "
     1347                    "partition %d\n", i + 1);
    41561348            else
    41571349                read_extended(i);
     
    41631355
    41641356        if (!valid_part_table_flag(pe->sectorbuffer)) {
    4165             fprintf(stderr,
    4166                 _("Warning: invalid flag 0x%04x of partition "
    4167                 "table %d will be corrected by w(rite)\n"),
    4168                 part_table_flag(pe->sectorbuffer), i + 1);
    4169 #ifdef CONFIG_FEATURE_FDISK_WRITABLE
     1357            printf("Warning: invalid flag 0x%02x,0x%02x of partition "
     1358                "table %d will be corrected by w(rite)\n",
     1359                pe->sectorbuffer[510],
     1360                pe->sectorbuffer[511],
     1361                i + 1);
     1362#if ENABLE_FEATURE_FDISK_WRITABLE
    41701363            pe->changed = 1;
    41711364#endif
     
    41761369}
    41771370
    4178 #ifdef CONFIG_FEATURE_FDISK_WRITABLE
     1371#if ENABLE_FEATURE_FDISK_WRITABLE
    41791372/*
    41801373 * Print the message MESG, then read an integer between LOW and HIGH (inclusive).
     
    41841377 * There is no default if DFLT is not between LOW and HIGH.
    41851378 */
    4186 static uint
    4187 read_int(uint low, uint dflt, uint high, uint base, char *mesg)
    4188 {
    4189     uint i;
     1379static unsigned
     1380read_int(unsigned low, unsigned dflt, unsigned high, unsigned base, const char *mesg)
     1381{
     1382    unsigned i;
    41901383    int default_ok = 1;
    4191     static char *ms = NULL;
    4192     static int mslen = 0;
    4193 
    4194     if (!ms || strlen(mesg)+100 > mslen) {
    4195         mslen = strlen(mesg)+200;
    4196         ms = xrealloc(ms,mslen);
    4197     }
    4198 
    4199     if (dflt < low || dflt > high)
     1384    const char *fmt = "%s (%u-%u, default %u): ";
     1385
     1386    if (dflt < low || dflt > high) {
     1387        fmt = "%s (%u-%u): ";
    42001388        default_ok = 0;
    4201 
    4202     if (default_ok)
    4203         snprintf(ms, mslen, _("%s (%u-%u, default %u): "),
    4204              mesg, low, high, dflt);
    4205     else
    4206         snprintf(ms, mslen, "%s (%u-%u): ", mesg, low, high);
     1389    }
    42071390
    42081391    while (1) {
     
    42101393
    42111394        /* ask question and read answer */
    4212         while (read_chars(ms) != '\n' && !isdigit(*line_ptr)
    4213          && *line_ptr != '-' && *line_ptr != '+')
    4214             continue;
     1395        do {
     1396            printf(fmt, mesg, low, high, dflt);
     1397    &