Changeset 2725 in MondoRescue for branches/2.2.9/mindi-busybox/util-linux
- Timestamp:
- Feb 25, 2011, 9:26:54 PM (13 years ago)
- Location:
- branches/2.2.9/mindi-busybox/util-linux
- Files:
-
- 56 added
- 31 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/2.2.9/mindi-busybox/util-linux/Config.in
r1765 r2725 1 # DO NOT EDIT. This file is generated from Config.src 1 2 # 2 3 # For a description of the syntax of this configuration file, … … 6 7 menu "Linux System Utilities" 7 8 9 config BLOCKDEV 10 bool "blockdev" 11 default y 12 help 13 Performs some ioctls with block devices. 14 config REV 15 bool "rev" 16 default y 17 help 18 Reverse lines of a file or files. 19 20 config ACPID 21 bool "acpid" 22 default y 23 depends on PLATFORM_LINUX 24 help 25 acpid listens to ACPI events coming either in textual form from 26 /proc/acpi/event (though it is marked deprecated it is still widely 27 used and _is_ a standard) or in binary form from specified evdevs 28 (just use /dev/input/event*). 29 30 It parses the event to retrieve ACTION and a possible PARAMETER. 31 It then spawns /etc/acpi/<ACTION>[/<PARAMETER>] either via run-parts 32 (if the resulting path is a directory) or directly as an executable. 33 34 N.B. acpid relies on run-parts so have the latter installed. 35 36 config FEATURE_ACPID_COMPAT 37 bool "Accept and ignore redundant options" 38 default y 39 depends on ACPID 40 help 41 Accept and ignore compatibility options -g -m -s -S -v. 42 43 config BLKID 44 bool "blkid" 45 default y 46 depends on PLATFORM_LINUX 47 select VOLUMEID 48 help 49 Lists labels and UUIDs of all filesystems. 50 WARNING: 51 With all submodules selected, it will add ~8k to busybox. 52 8 53 config DMESG 9 54 bool "dmesg" 10 default n 11 help 12 dmesg is used to examine or control the kernel ring buffer. When the 55 default y 56 depends on PLATFORM_LINUX 57 help 58 dmesg is used to examine or control the kernel ring buffer. When the 13 59 Linux kernel prints messages to the system log, they are stored in 14 the kernel ring buffer. 60 the kernel ring buffer. You can use dmesg to print the kernel's ring 15 61 buffer, clear the kernel ring buffer, change the size of the kernel 16 62 ring buffer, and change the priority level at which kernel messages 17 are also logged to the system console. 63 are also logged to the system console. Enable this option if you 18 64 wish to enable the 'dmesg' utility. 19 65 20 66 config FEATURE_DMESG_PRETTY 21 bool " pretty dmesg output"67 bool "Pretty dmesg output" 22 68 default y 23 69 depends on DMESG 24 70 help 25 71 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 "<#>". 72 The syslog level is a string prefixed to every line with the form 73 "<#>". 27 74 28 75 With this option you will see: … … 40 87 config FBSET 41 88 bool "fbset" 42 default n 89 default y 90 depends on PLATFORM_LINUX 43 91 help 44 92 fbset is used to show or change the settings of a Linux frame buffer 45 device. 46 interface to access a graphics display. 93 device. The frame buffer device provides a simple and unique 94 interface to access a graphics display. Enable this option 47 95 if you wish to enable the 'fbset' utility. 48 96 49 97 config FEATURE_FBSET_FANCY 50 98 bool "Turn on extra fbset options" 51 default n99 default y 52 100 depends on FBSET 53 101 help 54 102 This option enables extended fbset options, allowing one to set the 55 framebuffer size, color depth, etc. 56 display. 103 framebuffer size, color depth, etc. interface to access a graphics 104 display. Enable this option if you wish to enable extended fbset 57 105 options. 58 106 59 107 config FEATURE_FBSET_READMODE 60 108 bool "Turn on fbset readmode support" 61 default n109 default y 62 110 depends on FBSET 63 111 help … … 68 116 config FDFLUSH 69 117 bool "fdflush" 70 default n 118 default y 119 depends on PLATFORM_LINUX 71 120 help 72 121 fdflush is only needed when changing media on slightly-broken 73 removable media drives. 122 removable media drives. It is used to make Linux believe that a 74 123 hardware disk-change switch has been actuated, which causes Linux to 75 forget anything it has cached from the previous media. 124 forget anything it has cached from the previous media. If you have 76 125 such a slightly-broken drive, you will need to run fdflush every time 77 you change a disk. 126 you change a disk. Most people have working hardware and can safely 78 127 leave this disabled. 79 128 80 129 config FDFORMAT 81 130 bool "fdformat" 82 default n 131 default y 132 depends on PLATFORM_LINUX 83 133 help 84 134 fdformat is used to low-level format a floppy disk. … … 86 136 config FDISK 87 137 bool "fdisk" 88 default n 138 default y 139 depends on PLATFORM_LINUX 89 140 help 90 141 The fdisk utility is used to divide hard disks into one or more 91 logical disks, which are generally called partitions. 142 logical disks, which are generally called partitions. This utility 92 143 can be used to list and edit the set of partitions or BSD style 93 144 'disk slices' that are defined on a hard drive. 94 145 95 146 config FDISK_SUPPORT_LARGE_DISKS 96 bool " support over 4GB disks"147 bool "Support over 4GB disks" 97 148 default y 98 149 depends on FDISK … … 106 157 help 107 158 Enabling this option allows you to create or change a partition table 108 and write those changes out to disk. 159 and write those changes out to disk. If you leave this option 109 160 disabled, you will only be able to view the partition table. 110 161 … … 141 192 and define and edit BSD disk slices. 142 193 194 config FEATURE_GPT_LABEL 195 bool "Support GPT disklabels" 196 default n 197 depends on FDISK && FEATURE_FDISK_WRITABLE 198 help 199 Enabling this option allows you to view GUID Partition Table 200 disklabels. 201 143 202 config FEATURE_FDISK_ADVANCED 144 203 bool "Support expert mode" 145 default n204 default y 146 205 depends on FDISK && FEATURE_FDISK_WRITABLE 147 206 help 148 207 Enabling this option allows you to do terribly unsafe things like 149 208 define arbitrary drive geometry, move the beginning of data in a 150 partition, and similarly evil things. 209 partition, and similarly evil things. Unless you have a very good 151 210 reason you would be wise to leave this disabled. 211 212 config FINDFS 213 bool "findfs" 214 default y 215 depends on PLATFORM_LINUX 216 select VOLUMEID 217 help 218 Prints the name of a filesystem with given label or UUID. 219 WARNING: 220 With all submodules selected, it will add ~8k to busybox. 221 222 config FLOCK 223 bool "flock" 224 default y 225 help 226 Manage locks from shell scripts 152 227 153 228 config FREERAMDISK 154 229 bool "freeramdisk" 155 default n 156 help 157 Linux allows you to create ramdisks. This utility allows you to 230 default y 231 depends on PLATFORM_LINUX 232 help 233 Linux allows you to create ramdisks. This utility allows you to 158 234 delete them and completely free all memory that was used for the 159 ramdisk. 235 ramdisk. For example, if you boot Linux into a ramdisk and later 160 236 pivot_root, you may want to free the memory that is allocated to the 161 ramdisk. 237 ramdisk. If you have no use for freeing memory from a ramdisk, leave 162 238 this disabled. 163 239 164 240 config FSCK_MINIX 165 241 bool "fsck_minix" 166 default n242 default y 167 243 help 168 244 The minix filesystem is a nice, small, compact, read-write filesystem 169 with little overhead. 245 with little overhead. It is not a journaling filesystem however and 170 246 can experience corruption if it is not properly unmounted or if the 171 power goes off in the middle of a write. 247 power goes off in the middle of a write. This utility allows you to 172 248 check for and attempt to repair any corruption that occurs to a minix 173 249 filesystem. 174 250 251 config MKFS_EXT2 252 bool "mkfs_ext2" 253 default y 254 depends on PLATFORM_LINUX 255 help 256 Utility to create EXT2 filesystems. 257 175 258 config MKFS_MINIX 176 259 bool "mkfs_minix" 177 default n 260 default y 261 depends on PLATFORM_LINUX 178 262 help 179 263 The minix filesystem is a nice, small, compact, read-write filesystem 180 with little overhead. If you wish to be able to create minix filesystems 181 this utility will do the job for you. 182 183 comment "Minix filesystem support" 184 depends on FSCK_MINIX || MKFS_MINIX 264 with little overhead. If you wish to be able to create minix 265 filesystems this utility will do the job for you. 185 266 186 267 config FEATURE_MINIX2 … … 189 270 depends on FSCK_MINIX || MKFS_MINIX 190 271 help 191 If you wish to be able to create version 2 minix filesystems, enable this. 192 If you enabled 'mkfs_minix' then you almost certainly want to be using the 193 version 2 filesystem support. 272 If you wish to be able to create version 2 minix filesystems, enable 273 this. If you enabled 'mkfs_minix' then you almost certainly want to 274 be using the version 2 filesystem support. 275 276 config MKFS_REISER 277 bool "mkfs_reiser" 278 default n 279 depends on PLATFORM_LINUX 280 help 281 Utility to create ReiserFS filesystems. 282 Note: this applet needs a lot of testing and polishing. 283 284 config MKFS_VFAT 285 bool "mkfs_vfat" 286 default y 287 depends on PLATFORM_LINUX 288 help 289 Utility to create FAT32 filesystems. 194 290 195 291 config GETOPT 196 292 bool "getopt" 197 default n293 default y 198 294 help 199 295 The getopt utility is used to break up (parse) options in command 200 296 lines to make it easy to write complex shell scripts that also check 201 for legal (and illegal) options. 297 for legal (and illegal) options. If you want to write horribly 202 298 complex shell scripts, or use some horribly complex shell script 203 written by others, this utility may be for you. 299 written by others, this utility may be for you. Most people will 204 300 wisely leave this disabled. 301 302 config FEATURE_GETOPT_LONG 303 bool "Support option -l" 304 default y if LONG_OPTS 305 depends on GETOPT 306 help 307 Enable support for long options (option -l). 205 308 206 309 config HEXDUMP 207 310 bool "hexdump" 208 default n311 default y 209 312 help 210 313 The hexdump utility is used to display binary data in a readable 211 314 way that is comparable to the output from most hex editors. 212 315 316 config FEATURE_HEXDUMP_REVERSE 317 bool "Support -R, reverse of 'hexdump -Cv'" 318 default y 319 depends on HEXDUMP 320 help 321 The hexdump utility is used to display binary data in an ascii 322 readable way. This option creates binary data from an ascii input. 323 NB: this option is non-standard. It's unwise to use it in scripts 324 aimed to be portable. 325 326 config HD 327 bool "hd" 328 default y 329 depends on HEXDUMP 330 help 331 hd is an alias to hexdump -C. 332 213 333 config HWCLOCK 214 334 bool "hwclock" 215 default n 335 default y 336 depends on PLATFORM_LINUX 216 337 help 217 338 The hwclock utility is used to read and set the hardware clock 218 on a system. 339 on a system. This is primarily used to set the current time on 219 340 shutdown in the hardware clock, so the hardware will keep the 220 341 correct time when Linux is _not_ running. … … 222 343 config FEATURE_HWCLOCK_LONG_OPTIONS 223 344 bool "Support long options (--hctosys,...)" 224 default n225 depends on HWCLOCK && GETOPT_LONG226 help 227 By default, the hwclock utility only uses short options. 345 default y 346 depends on HWCLOCK && LONG_OPTS 347 help 348 By default, the hwclock utility only uses short options. If you 228 349 are overly fond of its long options, such as --hctosys, --utc, etc) 229 350 then enable this option. … … 231 352 config FEATURE_HWCLOCK_ADJTIME_FHS 232 353 bool "Use FHS /var/lib/hwclock/adjtime" 233 default y354 default n # util-linux-ng in Fedora 13 still uses /etc/adjtime 234 355 depends on HWCLOCK 235 356 help 236 357 Starting with FHS 2.3, the adjtime state file is supposed to exist 237 at /var/lib/hwclock/adjtime instead of /etc/adjtime. 358 at /var/lib/hwclock/adjtime instead of /etc/adjtime. If you wish 238 359 to use the FHS behavior, answer Y here, otherwise answer N for the 239 360 classic /etc/adjtime path. 240 361 241 http://www.pathname.com/fhs/pub/fhs-2.3.html#VARLIBHWCLOCKSTATEDIRECTORYFORHWCLO362 pathname.com/fhs/pub/fhs-2.3.html#VARLIBHWCLOCKSTATEDIRECTORYFORHWCLO 242 363 243 364 config IPCRM 244 365 bool "ipcrm" 245 default n 246 select FEATURE_SUID 366 default y 247 367 help 248 368 The ipcrm utility allows the removal of System V interprocess … … 252 372 config IPCS 253 373 bool "ipcs" 254 default n255 select FEATURE_SUID374 default y 375 depends on PLATFORM_LINUX 256 376 help 257 377 The ipcs utility is used to provide information on the currently … … 260 380 config LOSETUP 261 381 bool "losetup" 262 default n 382 default y 383 depends on PLATFORM_LINUX 263 384 help 264 385 losetup is used to associate or detach a loop device with a regular 265 file or block device, and to query the status of a loop device. 386 file or block device, and to query the status of a loop device. This 266 387 version does not currently support enabling data encryption. 388 389 config LSPCI 390 bool "lspci" 391 default y 392 #depends on PLATFORM_LINUX 393 help 394 lspci is a utility for displaying information about PCI buses in the 395 system and devices connected to them. 396 397 This version uses sysfs (/sys/bus/pci/devices) only. 398 399 config LSUSB 400 bool "lsusb" 401 default y 402 #depends on PLATFORM_LINUX 403 help 404 lsusb is a utility for displaying information about USB buses in the 405 system and devices connected to them. 406 407 This version uses sysfs (/sys/bus/usb/devices) only. 267 408 268 409 config MDEV 269 410 bool "mdev" 270 default n 411 default y 412 depends on PLATFORM_LINUX 271 413 help 272 414 mdev is a mini-udev implementation for dynamically creating device … … 277 419 config FEATURE_MDEV_CONF 278 420 bool "Support /etc/mdev.conf" 279 default n421 default y 280 422 depends on MDEV 281 423 help … … 285 427 For more information, please see docs/mdev.txt 286 428 429 config FEATURE_MDEV_RENAME 430 bool "Support subdirs/symlinks" 431 default y 432 depends on FEATURE_MDEV_CONF 433 help 434 Add support for renaming devices and creating symlinks. 435 436 For more information, please see docs/mdev.txt 437 438 config FEATURE_MDEV_RENAME_REGEXP 439 bool "Support regular expressions substitutions when renaming device" 440 default y 441 depends on FEATURE_MDEV_RENAME 442 help 443 Add support for regular expressions substitutions when renaming 444 device. 445 287 446 config FEATURE_MDEV_EXEC 288 447 bool "Support command execution at device addition/removal" 289 default n448 default y 290 449 depends on FEATURE_MDEV_CONF 291 450 help … … 297 456 config FEATURE_MDEV_LOAD_FIRMWARE 298 457 bool "Support loading of firmwares" 299 default n458 default y 300 459 depends on MDEV 301 460 help … … 308 467 config MKSWAP 309 468 bool "mkswap" 310 default n469 default y 311 470 help 312 471 The mkswap utility is used to configure a file or disk partition as 313 Linux swap space. 472 Linux swap space. This allows Linux to use the entire file or 314 473 partition as if it were additional RAM, which can greatly increase 315 the capability of low-memory machines. 474 the capability of low-memory machines. This additional memory is 316 475 much slower than real RAM, but can be very helpful at preventing your 317 476 applications being killed by the Linux out of memory (OOM) killer. … … 319 478 the swap space using the 'swapon' utility. 320 479 321 config FEATURE_MKSWAP_ V0322 bool " version 0support"323 default n480 config FEATURE_MKSWAP_UUID 481 bool "UUID support" 482 default y 324 483 depends on MKSWAP 325 # depends on MKSWAP && DEPRECATED 326 help 327 Enable support for the old v0 style. 328 If your kernel is older than 2.1.117, then v0 support is the 329 only option. 484 help 485 Generate swap spaces with universally unique identifiers. 330 486 331 487 config MORE 332 488 bool "more" 333 default n489 default y 334 490 help 335 491 more is a simple utility which allows you to read text one screen 336 sized page at a time. 492 sized page at a time. If you want to read text that is larger than 337 493 the screen, and you are using anything faster than a 300 baud modem, 338 you will probably find this utility very helpful. 494 you will probably find this utility very helpful. If you don't have 339 495 any need to reading text files, you can leave this disabled. 340 341 config FEATURE_USE_TERMIOS342 bool "Use termios to manipulate the screen"343 default y344 depends on MORE345 help346 This option allows utilities such as 'more' and 'top' to determine347 the size of the screen. If you leave this disabled, your utilities348 that display things on the screen will be especially primitive and349 will be unable to determine the current screen size, and will be350 unable to move the cursor.351 496 352 497 config MOUNT 353 498 bool "mount" 499 default y 500 depends on PLATFORM_LINUX 501 help 502 All files and filesystems in Unix are arranged into one big directory 503 tree. The 'mount' utility is used to graft a filesystem onto a 504 particular part of the tree. A filesystem can either live on a block 505 device, or it can be accessible over the network, as is the case with 506 NFS filesystems. Most people using BusyBox will also want to enable 507 the 'mount' utility. 508 509 config FEATURE_MOUNT_FAKE 510 bool "Support option -f" 511 default y 512 depends on MOUNT 513 help 514 Enable support for faking a file system mount. 515 516 config FEATURE_MOUNT_VERBOSE 517 bool "Support option -v" 518 default y 519 depends on MOUNT 520 help 521 Enable multi-level -v[vv...] verbose messages. Useful if you 522 debug mount problems and want to see what is exactly passed 523 to the kernel. 524 525 config FEATURE_MOUNT_HELPERS 526 bool "Support mount helpers" 354 527 default n 355 help 356 All files and filesystems in Unix are arranged into one big directory 357 tree. The 'mount' utility is used to graft a filesystem onto a 358 particular part of the tree. A filesystem can either live on a block 359 device, or it can be accessible over the network, as is the case with 360 NFS filesystems. Most people using BusyBox will also want to enable 361 the 'mount' utility. 528 depends on MOUNT 529 help 530 Enable mounting of virtual file systems via external helpers. 531 E.g. "mount obexfs#-b00.11.22.33.44.55 /mnt" will in effect call 532 "obexfs -b00.11.22.33.44.55 /mnt" 533 Also "mount -t sometype [-o opts] fs /mnt" will try 534 "sometype [-o opts] fs /mnt" if simple mount syscall fails. 535 The idea is to use such virtual filesystems in /etc/fstab. 536 537 config FEATURE_MOUNT_LABEL 538 bool "Support specifying devices by label or UUID" 539 default y 540 depends on MOUNT 541 select VOLUMEID 542 help 543 This allows for specifying a device by label or uuid, rather than by 544 name. This feature utilizes the same functionality as blkid/findfs. 545 This also enables label or uuid support for swapon. 362 546 363 547 config FEATURE_MOUNT_NFS 364 548 bool "Support mounting NFS file systems" 365 default n549 default y 366 550 depends on MOUNT 367 551 select FEATURE_HAVE_RPC … … 372 556 config FEATURE_MOUNT_CIFS 373 557 bool "Support mounting CIFS/SMB file systems" 374 default n558 default y 375 559 depends on MOUNT 376 560 help … … 382 566 default y 383 567 help 384 Without this, mount only supports ro/rw/remount. 568 Without this, mount only supports ro/rw/remount. With this, it 385 569 supports nosuid, suid, dev, nodev, exec, noexec, sync, async, atime, 386 570 noatime, diratime, nodiratime, loud, bind, move, shared, slave, … … 396 580 config PIVOT_ROOT 397 581 bool "pivot_root" 398 default n 582 default y 583 depends on PLATFORM_LINUX 399 584 help 400 585 The pivot_root utility swaps the mount points for the root filesystem 401 with some other mounted filesystem. 586 with some other mounted filesystem. This allows you to do all sorts 402 587 of wild and crazy things with your Linux system and is far more 403 588 powerful than 'chroot'. 404 589 405 Note: This is for initrd in linux 2.4. 590 Note: This is for initrd in linux 2.4. Under initramfs (introduced 406 591 in linux 2.6) use switch_root instead. 407 592 408 593 config RDATE 409 594 bool "rdate" 410 default n595 default y 411 596 help 412 597 The rdate utility allows you to synchronize the date and time of your … … 415 600 systems. 416 601 602 config RDEV 603 bool "rdev" 604 default y 605 help 606 Print the device node associated with the filesystem mounted at '/'. 607 417 608 config READPROFILE 418 609 bool "readprofile" 419 default n 610 default y 611 #depends on PLATFORM_LINUX 420 612 help 421 613 This allows you to parse /proc/profile for basic profiling. 614 615 config RTCWAKE 616 bool "rtcwake" 617 default y 618 depends on PLATFORM_LINUX 619 help 620 Enter a system sleep state until specified wakeup time. 621 622 config SCRIPT 623 bool "script" 624 default y 625 help 626 The script makes typescript of terminal session. 627 628 config SCRIPTREPLAY 629 bool "scriptreplay" 630 default y 631 help 632 This program replays a typescript, using timing information 633 given by script -t. 422 634 423 635 config SETARCH 424 636 bool "setarch" 425 default n 637 default y 638 depends on PLATFORM_LINUX 426 639 help 427 640 The linux32 utility is used to create a 32bit environment for the 428 specified program (usually a shell). 641 specified program (usually a shell). It only makes sense to have 429 642 this util on a system that supports both 64bit and 32bit userland 430 643 (like amd64/x86, ppc64/ppc, sparc64/sparc, etc...). … … 432 645 config SWAPONOFF 433 646 bool "swaponoff" 434 default n 647 default y 648 depends on PLATFORM_LINUX 435 649 help 436 650 This option enables both the 'swapon' and the 'swapoff' utilities. 437 651 Once you have created some swap space using 'mkswap', you also need 438 to enable your swap space with the 'swapon' utility. 652 to enable your swap space with the 'swapon' utility. The 'swapoff' 439 653 utility is used, typically at system shutdown, to disable any swap 440 space. 654 space. If you are not using any swap space, you can leave this 441 655 option disabled. 656 657 config FEATURE_SWAPON_PRI 658 bool "Support priority option -p" 659 default y 660 depends on SWAPONOFF 661 help 662 Enable support for setting swap device priority in swapon. 442 663 443 664 config SWITCH_ROOT 444 665 bool "switch_root" 445 default n 666 default y 667 depends on PLATFORM_LINUX 446 668 help 447 669 The switch_root utility is used from initramfs to select a new 448 root device. 449 pivot_root. 670 root device. Under initramfs, you have to use this instead of 671 pivot_root. (Stop reading here if you don't care why.) 450 672 451 673 Booting with initramfs extracts a gzipped cpio archive into rootfs 452 (which is a variant of ramfs/tmpfs). 453 or unmounted*, pivot_root will not work from initramfs. 674 (which is a variant of ramfs/tmpfs). Because rootfs can't be moved 675 or unmounted*, pivot_root will not work from initramfs. Instead, 454 676 switch_root deletes everything out of rootfs (including itself), 455 677 does a mount --move that overmounts rootfs with the new root, and … … 458 680 * Because the Linux kernel uses rootfs internally as the starting 459 681 and ending point for searching through the kernel's doubly linked 460 list of active mount points. 682 list of active mount points. That's why. 461 683 462 684 config UMOUNT 463 685 bool "umount" 464 default n 465 help 466 When you want to remove a mounted filesystem from its current mount point, 467 for example when you are shutting down the system, the 'umount' utility is 468 the tool to use. If you enabled the 'mount' utility, you almost certainly 469 also want to enable 'umount'. 686 default y 687 depends on PLATFORM_LINUX 688 help 689 When you want to remove a mounted filesystem from its current mount 690 point, for example when you are shutting down the system, the 691 'umount' utility is the tool to use. If you enabled the 'mount' 692 utility, you almost certainly also want to enable 'umount'. 470 693 471 694 config FEATURE_UMOUNT_ALL 472 bool " umount -a option"473 default n695 bool "Support option -a" 696 default y 474 697 depends on UMOUNT 475 698 help … … 481 704 config FEATURE_MOUNT_LOOP 482 705 bool "Support loopback mounts" 483 default n706 default y 484 707 depends on MOUNT || UMOUNT 485 708 help 486 709 Enabling this feature allows automatic mounting of files (containing 487 filesystem images) via the linux kernel's loopback devices. The mount 488 command will detect you are trying to mount a file instead of a block 489 device, and transparently associate the file with a loopback device. 490 The umount command will also free that loopback device. 710 filesystem images) via the linux kernel's loopback devices. 711 The mount command will detect you are trying to mount a file instead 712 of a block device, and transparently associate the file with a 713 loopback device. The umount command will also free that loopback 714 device. 491 715 492 716 You can still use the 'losetup' utility (to manually associate files … … 495 719 (If you don't want umount to free the loop device, use "umount -D".) 496 720 721 config FEATURE_MOUNT_LOOP_CREATE 722 bool "Create new loopback devices if needed" 723 default y 724 depends on FEATURE_MOUNT_LOOP 725 help 726 Linux kernels >= 2.6.24 support unlimited loopback devices. They are 727 allocated for use when trying to use a loop device. The loop device 728 must however exist. 729 730 This feature lets mount to try to create next /dev/loopN device 731 if it does not find a free one. 732 497 733 config FEATURE_MTAB_SUPPORT 498 734 bool "Support for the old /etc/mtab file" 499 735 default n 500 736 depends on MOUNT || UMOUNT 737 select FEATURE_MOUNT_FAKE 501 738 help 502 739 Historically, Unix systems kept track of the currently mounted 503 partitions in the file "/etc/mtab". 740 partitions in the file "/etc/mtab". These days, the kernel exports 504 741 the list of currently mounted partitions in "/proc/mounts", rendering 505 the old mtab file obsolete. 742 the old mtab file obsolete. (In modern systems, /etc/mtab should be 506 743 a symlink to /proc/mounts.) 507 744 … … 511 748 example a mount under chroot won't update it), can't handle modern 512 749 features like separate per-process filesystem namespaces, requires 513 that your /etc directory be writ eable, tends to get easily confused750 that your /etc directory be writable, tends to get easily confused 514 751 by --bind or --move mounts, won't update if you rename a directory 515 that contains a mount point, and so on. 752 that contains a mount point, and so on. (In brief: avoid.) 516 753 517 754 About the only reason to use this is if you've removed /proc from 518 755 your kernel. 519 756 757 config VOLUMEID 758 bool #No description makes it a hidden option 759 default n 760 761 menu "Filesystem/Volume identification" 762 depends on VOLUMEID 763 764 config FEATURE_VOLUMEID_EXT 765 bool "Ext filesystem" 766 default y 767 depends on VOLUMEID 768 help 769 TODO 770 771 config FEATURE_VOLUMEID_BTRFS 772 bool "btrfs filesystem" 773 default y 774 depends on VOLUMEID 775 help 776 TODO 777 778 config FEATURE_VOLUMEID_REISERFS 779 bool "Reiser filesystem" 780 default y 781 depends on VOLUMEID 782 help 783 TODO 784 785 config FEATURE_VOLUMEID_FAT 786 bool "fat filesystem" 787 default y 788 depends on VOLUMEID 789 help 790 TODO 791 792 config FEATURE_VOLUMEID_HFS 793 bool "hfs filesystem" 794 default y 795 depends on VOLUMEID 796 help 797 TODO 798 799 config FEATURE_VOLUMEID_JFS 800 bool "jfs filesystem" 801 default y 802 depends on VOLUMEID 803 help 804 TODO 805 806 ### config FEATURE_VOLUMEID_UFS 807 ### bool "ufs filesystem" 808 ### default y 809 ### depends on VOLUMEID 810 ### help 811 ### TODO 812 813 config FEATURE_VOLUMEID_XFS 814 bool "xfs filesystem" 815 default y 816 depends on VOLUMEID 817 help 818 TODO 819 820 config FEATURE_VOLUMEID_NTFS 821 bool "ntfs filesystem" 822 default y 823 depends on VOLUMEID 824 help 825 TODO 826 827 config FEATURE_VOLUMEID_ISO9660 828 bool "iso9660 filesystem" 829 default y 830 depends on VOLUMEID 831 help 832 TODO 833 834 config FEATURE_VOLUMEID_UDF 835 bool "udf filesystem" 836 default y 837 depends on VOLUMEID 838 help 839 TODO 840 841 config FEATURE_VOLUMEID_LUKS 842 bool "luks filesystem" 843 default y 844 depends on VOLUMEID 845 help 846 TODO 847 848 config FEATURE_VOLUMEID_LINUXSWAP 849 bool "linux swap filesystem" 850 default y 851 depends on VOLUMEID 852 help 853 TODO 854 855 ### config FEATURE_VOLUMEID_LVM 856 ### bool "lvm" 857 ### default y 858 ### depends on VOLUMEID 859 ### help 860 ### TODO 861 862 config FEATURE_VOLUMEID_CRAMFS 863 bool "cramfs filesystem" 864 default y 865 depends on VOLUMEID 866 help 867 TODO 868 869 ### config FEATURE_VOLUMEID_HPFS 870 ### bool "hpfs filesystem" 871 ### default y 872 ### depends on VOLUMEID 873 ### help 874 ### TODO 875 876 config FEATURE_VOLUMEID_ROMFS 877 bool "romfs filesystem" 878 default y 879 depends on VOLUMEID 880 help 881 TODO 882 883 config FEATURE_VOLUMEID_SYSV 884 bool "sysv filesystem" 885 default y 886 depends on VOLUMEID 887 help 888 TODO 889 890 ### config FEATURE_VOLUMEID_MINIX 891 ### bool "minix filesystem" 892 ### default y 893 ### depends on VOLUMEID 894 ### help 895 ### TODO 896 897 ### These only detect partition tables - not used (yet?) 898 ### config FEATURE_VOLUMEID_MAC 899 ### bool "mac filesystem" 900 ### default y 901 ### depends on VOLUMEID 902 ### help 903 ### TODO 904 ### 905 ### config FEATURE_VOLUMEID_MSDOS 906 ### bool "msdos filesystem" 907 ### default y 908 ### depends on VOLUMEID 909 ### help 910 ### TODO 911 912 config FEATURE_VOLUMEID_OCFS2 913 bool "ocfs2 filesystem" 914 default y 915 depends on VOLUMEID 916 help 917 TODO 918 919 ### config FEATURE_VOLUMEID_HIGHPOINTRAID 920 ### bool "highpoint raid" 921 ### default y 922 ### depends on VOLUMEID 923 ### help 924 ### TODO 925 926 ### config FEATURE_VOLUMEID_ISWRAID 927 ### bool "intel raid" 928 ### default y 929 ### depends on VOLUMEID 930 ### help 931 ### TODO 932 933 ### config FEATURE_VOLUMEID_LSIRAID 934 ### bool "lsi raid" 935 ### default y 936 ### depends on VOLUMEID 937 ### help 938 ### TODO 939 940 ### config FEATURE_VOLUMEID_VIARAID 941 ### bool "via raid" 942 ### default y 943 ### depends on VOLUMEID 944 ### help 945 ### TODO 946 947 ### config FEATURE_VOLUMEID_SILICONRAID 948 ### bool "silicon raid" 949 ### default y 950 ### depends on VOLUMEID 951 ### help 952 ### TODO 953 954 ### config FEATURE_VOLUMEID_NVIDIARAID 955 ### bool "nvidia raid" 956 ### default y 957 ### depends on VOLUMEID 958 ### help 959 ### TODO 960 961 ### config FEATURE_VOLUMEID_PROMISERAID 962 ### bool "promise raid" 963 ### default y 964 ### depends on VOLUMEID 965 ### help 966 ### TODO 967 968 config FEATURE_VOLUMEID_LINUXRAID 969 bool "linuxraid" 970 default y 971 depends on VOLUMEID 972 help 973 TODO 974 520 975 endmenu 521 976 977 endmenu -
branches/2.2.9/mindi-busybox/util-linux/Kbuild
r1765 r2725 1 # DO NOT EDIT. This file is generated from Kbuild.src 1 2 # Makefile for busybox 2 3 # 3 4 # Copyright (C) 1999-2005 by Erik Andersen <andersen@codepoet.org> 4 5 # 5 # Licensed under the GPL v2, see the file LICENSE in this tarball.6 # Licensed under GPLv2, see file LICENSE in this source tree. 6 7 7 8 lib-y:= 8 lib-$(CONFIG_DMESG) +=dmesg.o 9 lib-$(CONFIG_FBSET) +=fbset.o 10 lib-$(CONFIG_FDFLUSH) +=freeramdisk.o 11 lib-$(CONFIG_FDFORMAT) +=fdformat.o 12 lib-$(CONFIG_FDISK) +=fdisk.o 13 lib-$(CONFIG_FREERAMDISK) +=freeramdisk.o 14 lib-$(CONFIG_FSCK_MINIX) +=fsck_minix.o 15 lib-$(CONFIG_GETOPT) +=getopt.o 16 lib-$(CONFIG_HEXDUMP) +=hexdump.o 17 lib-$(CONFIG_HWCLOCK) +=hwclock.o 18 lib-$(CONFIG_IPCRM) +=ipcrm.o 19 lib-$(CONFIG_IPCS) +=ipcs.o 20 lib-$(CONFIG_LOSETUP) +=losetup.o 21 lib-$(CONFIG_MDEV) +=mdev.o 22 lib-$(CONFIG_MKFS_MINIX) +=mkfs_minix.o 23 lib-$(CONFIG_MKSWAP) +=mkswap.o 24 lib-$(CONFIG_MORE) +=more.o 25 lib-$(CONFIG_MOUNT) +=mount.o 26 lib-$(CONFIG_PIVOT_ROOT) +=pivot_root.o 27 lib-$(CONFIG_RDATE) +=rdate.o 28 lib-$(CONFIG_READPROFILE) +=readprofile.o 29 lib-$(CONFIG_SETARCH) +=setarch.o 30 lib-$(CONFIG_SWAPONOFF) +=swaponoff.o 31 lib-$(CONFIG_SWITCH_ROOT) +=switch_root.o 32 lib-$(CONFIG_UMOUNT) +=umount.o 9 10 lib-$(CONFIG_BLOCKDEV) += blockdev.o 11 lib-$(CONFIG_REV) += rev.o 12 lib-$(CONFIG_ACPID) += acpid.o 13 lib-$(CONFIG_BLKID) += blkid.o 14 lib-$(CONFIG_DMESG) += dmesg.o 15 lib-$(CONFIG_FBSET) += fbset.o 16 lib-$(CONFIG_FDFLUSH) += freeramdisk.o 17 lib-$(CONFIG_FDFORMAT) += fdformat.o 18 lib-$(CONFIG_FDISK) += fdisk.o 19 lib-$(CONFIG_FINDFS) += findfs.o 20 lib-$(CONFIG_FLOCK) += flock.o 21 lib-$(CONFIG_FREERAMDISK) += freeramdisk.o 22 lib-$(CONFIG_FSCK_MINIX) += fsck_minix.o 23 lib-$(CONFIG_GETOPT) += getopt.o 24 lib-$(CONFIG_HEXDUMP) += hexdump.o 25 lib-$(CONFIG_HWCLOCK) += hwclock.o 26 lib-$(CONFIG_IPCRM) += ipcrm.o 27 lib-$(CONFIG_IPCS) += ipcs.o 28 lib-$(CONFIG_LOSETUP) += losetup.o 29 lib-$(CONFIG_LSPCI) += lspci.o 30 lib-$(CONFIG_LSUSB) += lsusb.o 31 lib-$(CONFIG_MDEV) += mdev.o 32 lib-$(CONFIG_MKFS_EXT2) += mkfs_ext2.o 33 lib-$(CONFIG_MKFS_MINIX) += mkfs_minix.o 34 lib-$(CONFIG_MKFS_REISER) += mkfs_reiser.o 35 lib-$(CONFIG_MKFS_VFAT) += mkfs_vfat.o 36 lib-$(CONFIG_MKSWAP) += mkswap.o 37 lib-$(CONFIG_MORE) += more.o 38 lib-$(CONFIG_MOUNT) += mount.o 39 lib-$(CONFIG_PIVOT_ROOT) += pivot_root.o 40 lib-$(CONFIG_RDATE) += rdate.o 41 lib-$(CONFIG_RDEV) += rdev.o 42 lib-$(CONFIG_READPROFILE) += readprofile.o 43 lib-$(CONFIG_RTCWAKE) += rtcwake.o 44 lib-$(CONFIG_SCRIPT) += script.o 45 lib-$(CONFIG_SCRIPTREPLAY) += scriptreplay.o 46 lib-$(CONFIG_SETARCH) += setarch.o 47 lib-$(CONFIG_SWAPONOFF) += swaponoff.o 48 lib-$(CONFIG_SWITCH_ROOT) += switch_root.o 49 lib-$(CONFIG_UMOUNT) += umount.o -
branches/2.2.9/mindi-busybox/util-linux/dmesg.c
r1765 r2725 5 5 * 6 6 * Copyright 2006 Rob Landley <rob@landley.net> 7 * Copyright 2006 Bernhard Fischer <rep.nop@aon.at>7 * Copyright 2006 Bernhard Reutner-Fischer <rep.nop@aon.at> 8 8 * 9 * Licensed under GPLv2, see file LICENSE in this tarball for details.9 * Licensed under GPLv2, see file LICENSE in this source tree. 10 10 */ 11 12 11 #include <sys/klog.h> 13 12 #include "libbb.h" 14 13 15 int dmesg_main(int argc, char **argv) ;16 int dmesg_main(int argc , char **argv)14 int dmesg_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 15 int dmesg_main(int argc UNUSED_PARAM, char **argv) 17 16 { 18 char *size, *level; 19 int flags = getopt32(argv, "cs:n:", &size, &level); 17 int len, level; 18 char *buf; 19 unsigned opts; 20 enum { 21 OPT_c = 1 << 0, 22 OPT_s = 1 << 1, 23 OPT_n = 1 << 2 24 }; 20 25 21 if (flags & 4) { 22 if (klogctl(8, NULL, xatoul_range(level, 0, 10))) 26 opt_complementary = "s+:n+"; /* numeric */ 27 opts = getopt32(argv, "cs:n:", &len, &level); 28 if (opts & OPT_n) { 29 if (klogctl(8, NULL, (long) level)) 23 30 bb_perror_msg_and_die("klogctl"); 24 } else { 25 int len; 26 char *buf; 27 28 len = (flags & 2) ? xatoul_range(size, 2, INT_MAX) : 16384; 29 buf = xmalloc(len); 30 if (0 > (len = klogctl(3 + (flags & 1), buf, len))) 31 bb_perror_msg_and_die("klogctl"); 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); 31 return EXIT_SUCCESS; 50 32 } 51 33 52 return 0; 34 if (!(opts & OPT_s)) 35 len = klogctl(10, NULL, 0); /* read ring buffer size */ 36 if (len < 16*1024) 37 len = 16*1024; 38 if (len > 16*1024*1024) 39 len = 16*1024*1024; 40 41 buf = xmalloc(len); 42 len = klogctl(3 + (opts & OPT_c), buf, len); /* read ring buffer */ 43 if (len < 0) 44 bb_perror_msg_and_die("klogctl"); 45 if (len == 0) 46 return EXIT_SUCCESS; 47 48 49 if (ENABLE_FEATURE_DMESG_PRETTY) { 50 int last = '\n'; 51 int in = 0; 52 53 /* Skip <#> at the start of lines */ 54 while (1) { 55 if (last == '\n' && buf[in] == '<') { 56 in += 3; 57 if (in >= len) 58 break; 59 } 60 last = buf[in]; 61 putchar(last); 62 in++; 63 if (in >= len) 64 break; 65 } 66 /* Make sure we end with a newline */ 67 if (last != '\n') 68 bb_putchar('\n'); 69 } else { 70 full_write(STDOUT_FILENO, buf, len); 71 if (buf[len-1] != '\n') 72 bb_putchar('\n'); 73 } 74 75 if (ENABLE_FEATURE_CLEAN_UP) free(buf); 76 77 return EXIT_SUCCESS; 53 78 } -
branches/2.2.9/mindi-busybox/util-linux/fbset.c
r1765 r2725 5 5 * Copyright (C) 1999 by Randolph Chung <tausq@debian.org> 6 6 * 7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.7 * Licensed under GPLv2 or later, see file LICENSE in this source tree. 8 8 * 9 9 * This is a from-scratch implementation of fbset; but the de facto fbset … … 18 18 #define DEFAULTFBMODE "/etc/fb.modes" 19 19 20 /* Stuff stolen from the kernel's fb.h */ 21 #define FB_ACTIVATE_ALL 64 20 22 enum { 21 OPT_CHANGE = (1 << 0), 22 OPT_INFO = (1 << 1), 23 OPT_READMODE = (1 << 2), 24 OPT_ALL = (1 << 9), 25 23 FBIOGET_VSCREENINFO = 0x4600, 24 FBIOPUT_VSCREENINFO = 0x4601 25 }; 26 27 struct fb_bitfield { 28 uint32_t offset; /* beginning of bitfield */ 29 uint32_t length; /* length of bitfield */ 30 uint32_t msb_right; /* !=0: Most significant bit is right */ 31 }; 32 struct fb_var_screeninfo { 33 uint32_t xres; /* visible resolution */ 34 uint32_t yres; 35 uint32_t xres_virtual; /* virtual resolution */ 36 uint32_t yres_virtual; 37 uint32_t xoffset; /* offset from virtual to visible */ 38 uint32_t yoffset; /* resolution */ 39 40 uint32_t bits_per_pixel; 41 uint32_t grayscale; /* !=0 Graylevels instead of colors */ 42 43 struct fb_bitfield red; /* bitfield in fb mem if true color, */ 44 struct fb_bitfield green; /* else only length is significant */ 45 struct fb_bitfield blue; 46 struct fb_bitfield transp; /* transparency */ 47 48 uint32_t nonstd; /* !=0 Non standard pixel format */ 49 50 uint32_t activate; /* see FB_ACTIVATE_x */ 51 52 uint32_t height; /* height of picture in mm */ 53 uint32_t width; /* width of picture in mm */ 54 55 uint32_t accel_flags; /* acceleration flags (hints) */ 56 57 /* Timing: All values in pixclocks, except pixclock (of course) */ 58 uint32_t pixclock; /* pixel clock in ps (pico seconds) */ 59 uint32_t left_margin; /* time from sync to picture */ 60 uint32_t right_margin; /* time from picture to sync */ 61 uint32_t upper_margin; /* time from sync to picture */ 62 uint32_t lower_margin; 63 uint32_t hsync_len; /* length of horizontal sync */ 64 uint32_t vsync_len; /* length of vertical sync */ 65 uint32_t sync; /* see FB_SYNC_x */ 66 uint32_t vmode; /* see FB_VMODE_x */ 67 uint32_t reserved[6]; /* Reserved for future compatibility */ 68 }; 69 70 static void copy_if_gt0(uint32_t *src, uint32_t *dst, unsigned cnt) 71 { 72 do { 73 if ((int32_t) *src > 0) 74 *dst = *src; 75 src++; 76 dst++; 77 } while (--cnt); 78 } 79 80 static NOINLINE void copy_changed_values( 81 struct fb_var_screeninfo *base, 82 struct fb_var_screeninfo *set) 83 { 84 //if ((int32_t) set->xres > 0) base->xres = set->xres; 85 //if ((int32_t) set->yres > 0) base->yres = set->yres; 86 //if ((int32_t) set->xres_virtual > 0) base->xres_virtual = set->xres_virtual; 87 //if ((int32_t) set->yres_virtual > 0) base->yres_virtual = set->yres_virtual; 88 copy_if_gt0(&set->xres, &base->xres, 4); 89 90 if ((int32_t) set->bits_per_pixel > 0) base->bits_per_pixel = set->bits_per_pixel; 91 //copy_if_gt0(&set->bits_per_pixel, &base->bits_per_pixel, 1); 92 93 //if ((int32_t) set->pixclock > 0) base->pixclock = set->pixclock; 94 //if ((int32_t) set->left_margin > 0) base->left_margin = set->left_margin; 95 //if ((int32_t) set->right_margin > 0) base->right_margin = set->right_margin; 96 //if ((int32_t) set->upper_margin > 0) base->upper_margin = set->upper_margin; 97 //if ((int32_t) set->lower_margin > 0) base->lower_margin = set->lower_margin; 98 //if ((int32_t) set->hsync_len > 0) base->hsync_len = set->hsync_len; 99 //if ((int32_t) set->vsync_len > 0) base->vsync_len = set->vsync_len; 100 //if ((int32_t) set->sync > 0) base->sync = set->sync; 101 //if ((int32_t) set->vmode > 0) base->vmode = set->vmode; 102 copy_if_gt0(&set->pixclock, &base->pixclock, 9); 103 } 104 105 106 enum { 26 107 CMD_FB = 1, 27 108 CMD_DB = 2, … … 36 117 CMD_ALL = 11, 37 118 CMD_INFO = 12, 38 CMD_CHANGE = 13, 119 CMD_SHOW = 13, 120 CMD_CHANGE = 14, 39 121 40 122 #if ENABLE_FEATURE_FBSET_FANCY … … 62 144 }; 63 145 64 static unsigned g_options;65 66 /* Stuff stolen from the kernel's fb.h */67 #define FB_ACTIVATE_ALL 6468 enum {69 FBIOGET_VSCREENINFO = 0x4600,70 FBIOPUT_VSCREENINFO = 0x460171 };72 struct fb_bitfield {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 */76 };77 struct fb_var_screeninfo {78 uint32_t xres; /* visible resolution */79 uint32_t yres;80 uint32_t xres_virtual; /* virtual resolution */81 uint32_t yres_virtual;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 */90 struct fb_bitfield blue;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 */99 100 uint32_t accel_flags; /* acceleration flags (hints) */101 102 /* Timing: All values in pixclocks, except pixclock (of course) */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 */107 uint32_t lower_margin;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 */113 };114 115 116 146 static const struct cmdoptions_t { 117 const char name[ 10];147 const char name[9]; 118 148 const unsigned char param_count; 119 149 const unsigned char code; 120 150 } g_cmdoptions[] = { 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 }, 151 /*"12345678" + NUL */ 152 { "fb" , 1, CMD_FB }, 153 { "db" , 1, CMD_DB }, 154 { "a" , 0, CMD_ALL }, 155 { "i" , 0, CMD_INFO }, 156 { "g" , 5, CMD_GEOMETRY }, 157 { "t" , 7, CMD_TIMING }, 158 { "accel" , 1, CMD_ACCEL }, 159 { "hsync" , 1, CMD_HSYNC }, 160 { "vsync" , 1, CMD_VSYNC }, 161 { "laced" , 1, CMD_LACED }, 162 { "double" , 1, CMD_DOUBLE }, 163 { "show" , 0, CMD_SHOW }, 164 { "s" , 0, CMD_SHOW }, 133 165 #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 166 { "all" , 0, CMD_ALL }, 167 { "xres" , 1, CMD_XRES }, 168 { "yres" , 1, CMD_YRES }, 169 { "vxres" , 1, CMD_VXRES }, 170 { "vyres" , 1, CMD_VYRES }, 171 { "depth" , 1, CMD_DEPTH }, 172 { "match" , 0, CMD_MATCH }, 173 { "geometry", 5, CMD_GEOMETRY }, 174 { "pixclock", 1, CMD_PIXCLOCK }, 175 { "left" , 1, CMD_LEFT }, 176 { "right" , 1, CMD_RIGHT }, 177 { "upper" , 1, CMD_UPPER }, 178 { "lower" , 1, CMD_LOWER }, 179 { "hslen" , 1, CMD_HSLEN }, 180 { "vslen" , 1, CMD_VSLEN }, 181 { "timings" , 7, CMD_TIMING }, 182 { "csync" , 1, CMD_CSYNC }, 183 { "gsync" , 1, CMD_GSYNC }, 184 { "extsync" , 1, CMD_EXTSYNC }, 185 { "bcast" , 1, CMD_BCAST }, 186 { "rgba" , 1, CMD_RGBA }, 187 { "step" , 1, CMD_STEP }, 188 { "move" , 1, CMD_MOVE }, 189 #endif 190 }; 191 162 192 /* taken from linux/fb.h */ 163 193 enum { 164 FB_VMODE_INTERLACED = 1, /* interlaced */ 165 FB_VMODE_DOUBLE = 2, /* double scan */ 166 FB_SYNC_HOR_HIGH_ACT = 1, /* horizontal sync high active */ 167 FB_SYNC_VERT_HIGH_ACT = 2, /* vertical sync high active */ 168 FB_SYNC_EXT = 4, /* external sync */ 169 FB_SYNC_COMP_HIGH_ACT = 8 /* composite sync high active */ 170 }; 171 #endif 172 173 static int readmode(struct fb_var_screeninfo *base, const char *fn, 194 FB_SYNC_HOR_HIGH_ACT = 1, /* horizontal sync high active */ 195 FB_SYNC_VERT_HIGH_ACT = 2, /* vertical sync high active */ 196 #if ENABLE_FEATURE_FBSET_READMODE 197 FB_VMODE_INTERLACED = 1, /* interlaced */ 198 FB_VMODE_DOUBLE = 2, /* double scan */ 199 FB_SYNC_EXT = 4, /* external sync */ 200 FB_SYNC_COMP_HIGH_ACT = 8, /* composite sync high active */ 201 #endif 202 }; 203 204 #if ENABLE_FEATURE_FBSET_READMODE 205 static void ss(uint32_t *x, uint32_t flag, char *buf, const char *what) 206 { 207 if (strcmp(buf, what) == 0) 208 *x &= ~flag; 209 else 210 *x |= flag; 211 } 212 213 /* Mode db file contains mode definitions like this: 214 * mode "800x600-48-lace" 215 * # D: 36.00 MHz, H: 33.835 kHz, V: 96.39 Hz 216 * geometry 800 600 800 600 8 217 * timings 27778 56 80 79 11 128 12 218 * laced true 219 * hsync high 220 * vsync high 221 * endmode 222 */ 223 static int read_mode_db(struct fb_var_screeninfo *base, const char *fn, 174 224 const char *mode) 175 225 { 176 #if ENABLE_FEATURE_FBSET_READMODE 177 FILE *f; 178 char buf[256]; 179 char *p = buf; 180 181 f = xfopen(fn, "r"); 182 while (!feof(f)) { 183 fgets(buf, sizeof(buf), f); 184 if (!(p = strstr(buf, "mode ")) && !(p = strstr(buf, "mode\t"))) 226 char *token[2], *p, *s; 227 parser_t *parser = config_open(fn); 228 229 while (config_read(parser, token, 2, 1, "# \t\r", PARSE_NORMAL)) { 230 if (strcmp(token[0], "mode") != 0 || !token[1]) 185 231 continue; 186 p += 5;187 if (! (p = strstr(buf, mode)))232 p = strstr(token[1], mode); 233 if (!p) 188 234 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 */ 235 s = p + strlen(mode); 236 //bb_info_msg("CHECK[%s][%s][%d]", mode, p-1, *s); 237 /* exact match? */ 238 if (((!*s || isspace(*s)) && '"' != s[-1]) /* end-of-token */ 239 || ('"' == *s && '"' == p[-1]) /* ends with " but starts with " too! */ 240 ) { 241 //bb_info_msg("FOUND[%s][%s][%s][%d]", token[1], p, mode, isspace(*s)); 242 break; 243 } 244 } 245 246 if (!token[0]) 247 return 0; 248 249 while (config_read(parser, token, 2, 1, "# \t", PARSE_NORMAL)) { 250 int i; 251 252 //bb_info_msg("???[%s][%s]", token[0], token[1]); 253 if (strcmp(token[0], "endmode") == 0) { 254 //bb_info_msg("OK[%s]", mode); 255 return 1; 256 } 257 p = token[1]; 258 i = index_in_strings( 259 "geometry\0timings\0interlaced\0double\0vsync\0hsync\0csync\0extsync\0", 260 token[0]); 261 switch (i) { 262 case 0: 263 if (sizeof(int) == sizeof(base->xres)) { 199 264 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; 265 &base->xres, &base->yres, 266 &base->xres_virtual, &base->yres_virtual, 267 &base->bits_per_pixel); 268 } else { 269 int base_xres, base_yres; 270 int base_xres_virtual, base_yres_virtual; 271 int base_bits_per_pixel; 272 sscanf(p, "%d %d %d %d %d", 273 &base_xres, &base_yres, 274 &base_xres_virtual, &base_yres_virtual, 275 &base_bits_per_pixel); 276 base->xres = base_xres; 277 base->yres = base_yres; 278 base->xres_virtual = base_xres_virtual; 279 base->yres_virtual = base_yres_virtual; 280 base->bits_per_pixel = base_bits_per_pixel; 281 } 282 //bb_info_msg("GEO[%s]", p); 283 break; 284 case 1: 285 if (sizeof(int) == sizeof(base->xres)) { 205 286 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 } 287 &base->pixclock, 288 &base->left_margin, &base->right_margin, 289 &base->upper_margin, &base->lower_margin, 290 &base->hsync_len, &base->vsync_len); 291 } else { 292 int base_pixclock; 293 int base_left_margin, base_right_margin; 294 int base_upper_margin, base_lower_margin; 295 int base_hsync_len, base_vsync_len; 296 sscanf(p, "%d %d %d %d %d %d %d", 297 &base_pixclock, 298 &base_left_margin, &base_right_margin, 299 &base_upper_margin, &base_lower_margin, 300 &base_hsync_len, &base_vsync_len); 301 base->pixclock = base_pixclock; 302 base->left_margin = base_left_margin; 303 base->right_margin = base_right_margin; 304 base->upper_margin = base_upper_margin; 305 base->lower_margin = base_lower_margin; 306 base->hsync_len = base_hsync_len; 307 base->vsync_len = base_vsync_len; 252 308 } 253 254 if (strstr(buf, "endmode")) 255 return 1; 256 } 257 } 258 #else 259 bb_error_msg("mode reading not compiled in"); 260 #endif 309 //bb_info_msg("TIM[%s]", p); 310 break; 311 case 2: 312 case 3: { 313 static const uint32_t syncs[] = {FB_VMODE_INTERLACED, FB_VMODE_DOUBLE}; 314 ss(&base->vmode, syncs[i-2], p, "false"); 315 //bb_info_msg("VMODE[%s]", p); 316 break; 317 } 318 case 4: 319 case 5: 320 case 6: { 321 static const uint32_t syncs[] = {FB_SYNC_VERT_HIGH_ACT, FB_SYNC_HOR_HIGH_ACT, FB_SYNC_COMP_HIGH_ACT}; 322 ss(&base->sync, syncs[i-4], p, "low"); 323 //bb_info_msg("SYNC[%s]", p); 324 break; 325 } 326 case 7: 327 ss(&base->sync, FB_SYNC_EXT, p, "false"); 328 //bb_info_msg("EXTSYNC[%s]", p); 329 break; 330 } 331 } 261 332 return 0; 262 333 } 263 264 static inline void setmode(struct fb_var_screeninfo *base, 265 struct fb_var_screeninfo *set) 266 { 267 if ((int) set->xres > 0) 268 base->xres = set->xres; 269 if ((int) set->yres > 0) 270 base->yres = set->yres; 271 if ((int) set->xres_virtual > 0) 272 base->xres_virtual = set->xres_virtual; 273 if ((int) set->yres_virtual > 0) 274 base->yres_virtual = set->yres_virtual; 275 if ((int) set->bits_per_pixel > 0) 276 base->bits_per_pixel = set->bits_per_pixel; 277 } 278 279 static inline void showmode(struct fb_var_screeninfo *v) 334 #endif 335 336 static NOINLINE void showmode(struct fb_var_screeninfo *v) 280 337 { 281 338 double drate = 0, hrate = 0, vrate = 0; … … 307 364 } 308 365 309 #ifdef STANDALONE 310 int main(int argc, char **argv) 311 #else 312 int fbset_main(int argc, char **argv); 366 int fbset_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 313 367 int fbset_main(int argc, char **argv) 314 #endif 315 { 316 struct fb_var_screeninfo var, varset; 368 { 369 enum { 370 OPT_CHANGE = (1 << 0), 371 OPT_SHOW = (1 << 1), 372 OPT_READMODE = (1 << 2), 373 OPT_ALL = (1 << 9), 374 }; 375 struct fb_var_screeninfo var_old, var_set; 317 376 int fh, i; 377 unsigned options = 0; 378 318 379 const char *fbdev = DEFAULTFBDEV; 319 380 const char *modefile = DEFAULTFBMODE; 320 char *thisarg, *mode = NULL; 321 322 memset(&varset, 0xFF, sizeof(varset)); 381 char *thisarg; 382 char *mode = mode; /* for compiler */ 383 384 memset(&var_set, 0xff, sizeof(var_set)); /* set all to -1 */ 323 385 324 386 /* parse cmd args.... why do they have to make things so difficult? */ 325 387 argv++; 326 388 argc--; 327 for (; argc > 0 && (thisarg = *argv) ; argc--, argv++) {328 for (i = 0; g_cmdoptions[i].name[0]; i++) {329 if (strcmp(thisarg , g_cmdoptions[i].name))389 for (; argc > 0 && (thisarg = *argv) != NULL; argc--, argv++) { 390 if (thisarg[0] == '-') for (i = 0; i < ARRAY_SIZE(g_cmdoptions); i++) { 391 if (strcmp(thisarg + 1, g_cmdoptions[i].name) != 0) 330 392 continue; 331 if (argc -1 <g_cmdoptions[i].param_count)393 if (argc <= g_cmdoptions[i].param_count) 332 394 bb_show_usage(); 333 395 … … 339 401 modefile = argv[1]; 340 402 break; 403 case CMD_ALL: 404 options |= OPT_ALL; 405 break; 406 case CMD_SHOW: 407 options |= OPT_SHOW; 408 break; 341 409 case CMD_GEOMETRY: 342 var set.xres = xatou32(argv[1]);343 var set.yres = xatou32(argv[2]);344 var set.xres_virtual = xatou32(argv[3]);345 var set.yres_virtual = xatou32(argv[4]);346 var set.bits_per_pixel = xatou32(argv[5]);410 var_set.xres = xatou32(argv[1]); 411 var_set.yres = xatou32(argv[2]); 412 var_set.xres_virtual = xatou32(argv[3]); 413 var_set.yres_virtual = xatou32(argv[4]); 414 var_set.bits_per_pixel = xatou32(argv[5]); 347 415 break; 348 416 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; 417 var_set.pixclock = xatou32(argv[1]); 418 var_set.left_margin = xatou32(argv[2]); 419 var_set.right_margin = xatou32(argv[3]); 420 var_set.upper_margin = xatou32(argv[4]); 421 var_set.lower_margin = xatou32(argv[5]); 422 var_set.hsync_len = xatou32(argv[6]); 423 var_set.vsync_len = xatou32(argv[7]); 424 break; 425 case CMD_ACCEL: 426 break; 427 case CMD_HSYNC: 428 var_set.sync |= FB_SYNC_HOR_HIGH_ACT; 429 break; 430 case CMD_VSYNC: 431 var_set.sync |= FB_SYNC_VERT_HIGH_ACT; 362 432 break; 363 433 #if ENABLE_FEATURE_FBSET_FANCY 364 434 case CMD_XRES: 365 var set.xres = xatou32(argv[1]);435 var_set.xres = xatou32(argv[1]); 366 436 break; 367 437 case CMD_YRES: 368 var set.yres = xatou32(argv[1]);438 var_set.yres = xatou32(argv[1]); 369 439 break; 370 440 case CMD_DEPTH: 371 varset.bits_per_pixel = xatou32(argv[1]); 372 break; 373 #endif 441 var_set.bits_per_pixel = xatou32(argv[1]); 442 break; 443 #endif 444 } 445 switch (g_cmdoptions[i].code) { 446 case CMD_FB: 447 case CMD_DB: 448 case CMD_ALL: 449 case CMD_SHOW: 450 break; 451 default: 452 /* other commands imply changes */ 453 options |= OPT_CHANGE; 374 454 } 375 455 argc -= g_cmdoptions[i].param_count; 376 456 argv += g_cmdoptions[i].param_count; 377 break; 378 } 379 if (!g_cmdoptions[i].name[0]) { 380 if (argc != 1) 381 bb_show_usage(); 382 mode = *argv; 383 g_options |= OPT_READMODE; 384 } 457 goto contin; 458 } 459 if (!ENABLE_FEATURE_FBSET_READMODE || argc != 1) 460 bb_show_usage(); 461 mode = *argv; 462 options |= OPT_READMODE; 463 contin: ; 385 464 } 386 465 387 466 fh = xopen(fbdev, O_RDONLY); 388 xioctl(fh, FBIOGET_VSCREENINFO, &var); 389 if (g_options & OPT_READMODE) { 390 if (!readmode(&var, modefile, mode)) { 467 xioctl(fh, FBIOGET_VSCREENINFO, &var_old); 468 469 if (options & OPT_READMODE) { 470 #if ENABLE_FEATURE_FBSET_READMODE 471 if (!read_mode_db(&var_old, modefile, mode)) { 391 472 bb_error_msg_and_die("unknown video mode '%s'", mode); 392 473 } 393 } 394 395 setmode(&var, &varset); 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 } 401 showmode(&var); 402 /* Don't close the file, as exiting will take care of that */ 403 /* close(fh); */ 474 #endif 475 } 476 477 if (options & OPT_CHANGE) { 478 copy_changed_values(&var_old, &var_set); 479 if (options & OPT_ALL) 480 var_old.activate = FB_ACTIVATE_ALL; 481 xioctl(fh, FBIOPUT_VSCREENINFO, &var_old); 482 } 483 484 if (options == 0 || (options & OPT_SHOW)) 485 showmode(&var_old); 486 487 if (ENABLE_FEATURE_CLEAN_UP) 488 close(fh); 404 489 405 490 return EXIT_SUCCESS; -
branches/2.2.9/mindi-busybox/util-linux/fdformat.c
r1765 r2725 1 1 /* vi: set sw=4 ts=4: */ 2 /* fdformat.c - Low-level formats a floppy disk - Werner Almesberger */ 3 4 /* 1999-02-22 Arkadiusz Mi¶kiewicz <misiek@pld.ORG.PL> 5 * - added Native Language Support 6 * 1999-03-20 Arnaldo Carvalho de Melo <acme@conectiva.com.br> 7 * - more i18n/nls translatable strings marked 2 /* fdformat.c - Low-level formats a floppy disk - Werner Almesberger 3 * 5 July 2003 -- modified for Busybox by Erik Andersen 8 4 * 9 * 5 July 2003 -- modified for Busybox by Erik Andersen5 * Licensed under GPLv2, see file LICENSE in this source tree. 10 6 */ 11 7 … … 41 37 }; 42 38 #define FDFMTBEG _IO(2,0x47) 43 #define 39 #define FDFMTTRK _IOW(2,0x48, struct format_descr) 44 40 #define FDFMTEND _IO(2,0x49) 45 41 #define FDGETPRM _IOR(2, 0x04, struct floppy_struct) 46 42 #define FD_FILL_BYTE 0xF6 /* format fill byte. */ 47 43 48 int fdformat_main(int argc, char **argv);49 int fdformat_main(int argc ,char **argv)44 int fdformat_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 45 int fdformat_main(int argc UNUSED_PARAM, char **argv) 50 46 { 51 47 int fd, n, cyl, read_bytes, verify; … … 55 51 struct format_descr descr; 56 52 57 if (argc < 2) { 58 bb_show_usage(); 59 } 53 opt_complementary = "=1"; /* must have 1 param */ 60 54 verify = !getopt32(argv, "n"); 61 55 argv += optind; … … 117 111 while (--read_bytes >= 0) { 118 112 if (data[read_bytes] != FD_FILL_BYTE) { 119 printf("bad data in cyl %d\nContinuing... ", cyl);113 printf("bad data in cyl %d\nContinuing... ", cyl); 120 114 } 121 115 } -
branches/2.2.9/mindi-busybox/util-linux/fdisk.c
r1765 r2725 5 5 * Copyright (C) 2001,2002 Vladimir Oleynik <dzo@simtreas.ru> (initial bb port) 6 6 * 7 * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.7 * Licensed under GPLv2 or later, see file LICENSE in this source tree. 8 8 */ 9 9 10 10 #ifndef _LARGEFILE64_SOURCE 11 11 /* For lseek64 */ 12 # define _LARGEFILE64_SOURCE12 # define _LARGEFILE64_SOURCE 13 13 #endif 14 14 #include <assert.h> /* assert */ 15 #include <sys/mount.h> 16 #if !defined(BLKSSZGET) 17 # define BLKSSZGET _IO(0x12, 104) 18 #endif 19 #if !defined(BLKGETSIZE64) 20 # define BLKGETSIZE64 _IOR(0x12,114,size_t) 21 #endif 15 22 #include "libbb.h" 23 24 #if BB_LITTLE_ENDIAN 25 # define inline_if_little_endian ALWAYS_INLINE 26 #else 27 # define inline_if_little_endian /* nothing */ 28 #endif 29 16 30 17 31 /* Looks like someone forgot to add this to config system */ 18 32 #ifndef ENABLE_FEATURE_FDISK_BLKSIZE 19 33 # define ENABLE_FEATURE_FDISK_BLKSIZE 0 20 # define USE_FEATURE_FDISK_BLKSIZE(a) 21 #endif 22 23 #define DEFAULT_SECTOR_SIZE 512 24 #define MAX_SECTOR_SIZE 2048 25 #define SECTOR_SIZE 512 /* still used in osf/sgi/sun code */ 26 #define MAXIMUM_PARTS 60 27 28 #define ACTIVE_FLAG 0x80 29 30 #define EXTENDED 0x05 31 #define WIN98_EXTENDED 0x0f 32 #define LINUX_PARTITION 0x81 33 #define LINUX_SWAP 0x82 34 #define LINUX_NATIVE 0x83 35 #define LINUX_EXTENDED 0x85 36 #define LINUX_LVM 0x8e 37 #define LINUX_RAID 0xfd 38 39 /* Used for sector numbers. Today's disk sizes make it necessary */ 34 # define IF_FEATURE_FDISK_BLKSIZE(a) 35 #endif 36 37 #define DEFAULT_SECTOR_SIZE 512 38 #define DEFAULT_SECTOR_SIZE_STR "512" 39 #define MAX_SECTOR_SIZE 2048 40 #define SECTOR_SIZE 512 /* still used in osf/sgi/sun code */ 41 #define MAXIMUM_PARTS 60 42 43 #define ACTIVE_FLAG 0x80 44 45 #define EXTENDED 0x05 46 #define WIN98_EXTENDED 0x0f 47 #define LINUX_PARTITION 0x81 48 #define LINUX_SWAP 0x82 49 #define LINUX_NATIVE 0x83 50 #define LINUX_EXTENDED 0x85 51 #define LINUX_LVM 0x8e 52 #define LINUX_RAID 0xfd 53 54 55 enum { 56 OPT_b = 1 << 0, 57 OPT_C = 1 << 1, 58 OPT_H = 1 << 2, 59 OPT_l = 1 << 3, 60 OPT_S = 1 << 4, 61 OPT_u = 1 << 5, 62 OPT_s = (1 << 6) * ENABLE_FEATURE_FDISK_BLKSIZE, 63 }; 64 65 40 66 typedef unsigned long long ullong; 67 /* Used for sector numbers. Partition formats we know 68 * do not support more than 2^32 sectors 69 */ 70 typedef uint32_t sector_t; 71 #if UINT_MAX == 4294967295 72 # define SECT_FMT "" 73 #elif ULONG_MAX == 4294967295 74 # define SECT_FMT "l" 75 #else 76 # error Cant detect sizeof(uint32_t) 77 #endif 41 78 42 79 struct hd_geometry { … … 55 92 56 93 static const char msg_part_already_defined[] ALIGN1 = 57 "Partition %d is already defined, delete it before re-adding\n"; 58 59 60 static unsigned sector_size = DEFAULT_SECTOR_SIZE; 61 static unsigned user_set_sector_size; 62 static unsigned sector_offset = 1; 63 64 #if ENABLE_FEATURE_OSF_LABEL 65 static int possibly_osf_label; 66 #endif 67 68 static unsigned heads, sectors, cylinders; 69 static void update_units(void); 94 "Partition %u is already defined, delete it before re-adding\n"; 70 95 71 96 … … 75 100 unsigned char sector; /* starting sector */ 76 101 unsigned char cyl; /* starting cylinder */ 77 unsigned char sys_ind; /* What partition type */102 unsigned char sys_ind; /* what partition type */ 78 103 unsigned char end_head; /* end head */ 79 104 unsigned char end_sector; /* end sector */ … … 81 106 unsigned char start4[4]; /* starting sector counting from 0 */ 82 107 unsigned char size4[4]; /* nr of sectors in partition */ 83 } ATTRIBUTE_PACKED; 84 85 static const char unable_to_open[] ALIGN1 = "cannot open %s"; 86 static const char unable_to_read[] ALIGN1 = "cannot read from %s"; 87 static const char unable_to_seek[] ALIGN1 = "cannot seek on %s"; 88 static const char unable_to_write[] ALIGN1 = "cannot write to %s"; 89 static const char ioctl_error[] ALIGN1 = "BLKGETSIZE ioctl failed on %s"; 90 static void fdisk_fatal(const char *why) ATTRIBUTE_NORETURN; 91 92 enum label_type { 93 label_dos, label_sun, label_sgi, label_aix, label_osf 94 }; 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 129 130 enum action { fdisk, require, try_only, create_empty_dos, create_empty_sun }; 131 132 static enum label_type current_label_type; 133 134 static const char *disk_device; 135 static int fd; /* the disk */ 136 static int partitions = 4; /* maximum partition + 1 */ 137 static int display_in_cyl_units = 1; 138 static unsigned units_per_sector = 1; 139 #if ENABLE_FEATURE_FDISK_WRITABLE 140 static void change_units(void); 141 static void reread_partition_table(int leave); 142 static void delete_partition(int i); 143 static int get_partition(int warn, int max); 144 static void list_types(const char *const *sys); 145 static unsigned read_int(unsigned low, unsigned dflt, unsigned high, unsigned base, const char *mesg); 146 #endif 147 static const char *partition_type(unsigned char type); 148 static void get_geometry(void); 149 static int get_boot(enum action what); 150 151 #define PLURAL 0 152 #define SINGULAR 1 153 154 static unsigned get_start_sect(const struct partition *p); 155 static unsigned get_nr_sects(const struct partition *p); 108 } PACKED; 156 109 157 110 /* … … 166 119 struct partition *part_table; /* points into sectorbuffer */ 167 120 struct partition *ext_pointer; /* points into sectorbuffer */ 168 ullong offset;/* disk sector number */169 char *sectorbuffer; /* disk sector contents */121 sector_t offset_from_dev_start; /* disk sector number */ 122 char *sectorbuffer; /* disk sector contents */ 170 123 #if ENABLE_FEATURE_FDISK_WRITABLE 171 char changed; /* boolean */124 char changed; /* boolean */ 172 125 #endif 173 126 }; 127 128 #define unable_to_open "can't open '%s'" 129 #define unable_to_read "can't read from %s" 130 #define unable_to_seek "can't seek on %s" 131 132 enum label_type { 133 LABEL_DOS, LABEL_SUN, LABEL_SGI, LABEL_AIX, LABEL_OSF, LABEL_GPT 134 }; 135 136 #define LABEL_IS_DOS (LABEL_DOS == current_label_type) 137 138 #if ENABLE_FEATURE_SUN_LABEL 139 #define LABEL_IS_SUN (LABEL_SUN == current_label_type) 140 #define STATIC_SUN static 141 #else 142 #define LABEL_IS_SUN 0 143 #define STATIC_SUN extern 144 #endif 145 146 #if ENABLE_FEATURE_SGI_LABEL 147 #define LABEL_IS_SGI (LABEL_SGI == current_label_type) 148 #define STATIC_SGI static 149 #else 150 #define LABEL_IS_SGI 0 151 #define STATIC_SGI extern 152 #endif 153 154 #if ENABLE_FEATURE_AIX_LABEL 155 #define LABEL_IS_AIX (LABEL_AIX == current_label_type) 156 #define STATIC_AIX static 157 #else 158 #define LABEL_IS_AIX 0 159 #define STATIC_AIX extern 160 #endif 161 162 #if ENABLE_FEATURE_OSF_LABEL 163 #define LABEL_IS_OSF (LABEL_OSF == current_label_type) 164 #define STATIC_OSF static 165 #else 166 #define LABEL_IS_OSF 0 167 #define STATIC_OSF extern 168 #endif 169 170 #if ENABLE_FEATURE_GPT_LABEL 171 #define LABEL_IS_GPT (LABEL_GPT == current_label_type) 172 #define STATIC_GPT static 173 #else 174 #define LABEL_IS_GPT 0 175 #define STATIC_GPT extern 176 #endif 177 178 enum action { OPEN_MAIN, TRY_ONLY, CREATE_EMPTY_DOS, CREATE_EMPTY_SUN }; 179 180 static void update_units(void); 181 #if ENABLE_FEATURE_FDISK_WRITABLE 182 static void change_units(void); 183 static void reread_partition_table(int leave); 184 static void delete_partition(int i); 185 static unsigned get_partition(int warn, unsigned max); 186 static void list_types(const char *const *sys); 187 static sector_t read_int(sector_t low, sector_t dflt, sector_t high, sector_t base, const char *mesg); 188 #endif 189 static const char *partition_type(unsigned char type); 190 static void get_geometry(void); 191 static void read_pte(struct pte *pe, sector_t offset); 192 #if ENABLE_FEATURE_SUN_LABEL || ENABLE_FEATURE_FDISK_WRITABLE 193 static int get_boot(enum action what); 194 #else 195 static int get_boot(void); 196 #endif 197 198 #define PLURAL 0 199 #define SINGULAR 1 200 201 static sector_t get_start_sect(const struct partition *p); 202 static sector_t get_nr_sects(const struct partition *p); 174 203 175 204 /* DOS partition types */ … … 278 307 }; 279 308 309 enum { 310 dev_fd = 3 /* the disk */ 311 }; 280 312 281 313 /* Globals */ 282 283 314 struct globals { 284 315 char *line_ptr; 316 317 const char *disk_device; 318 int g_partitions; // = 4; /* maximum partition + 1 */ 319 unsigned units_per_sector; // = 1; 320 unsigned sector_size; // = DEFAULT_SECTOR_SIZE; 321 unsigned user_set_sector_size; 322 unsigned sector_offset; // = 1; 323 unsigned g_heads, g_sectors, g_cylinders; 324 smallint /* enum label_type */ current_label_type; 325 smallint display_in_cyl_units; // = 1; 326 #if ENABLE_FEATURE_OSF_LABEL 327 smallint possibly_osf_label; 328 #endif 329 330 smallint listing; /* no aborts for fdisk -l */ 331 smallint dos_compatible_flag; // = 1; 332 #if ENABLE_FEATURE_FDISK_WRITABLE 333 //int dos_changed; 334 smallint nowarn; /* no warnings for fdisk -l/-s */ 335 #endif 336 int ext_index; /* the prime extended partition */ 337 unsigned user_cylinders, user_heads, user_sectors; 338 unsigned pt_heads, pt_sectors; 339 unsigned kern_heads, kern_sectors; 340 sector_t extended_offset; /* offset of link pointers */ 341 sector_t total_number_of_sectors; 342 343 jmp_buf listingbuf; 285 344 char line_buffer[80]; 286 345 char partname_buffer[80]; 287 jmp_buf listingbuf;288 346 /* Raw disk label. For DOS-type partition tables the MBR, 289 347 * with descriptions of the primary partitions. */ … … 292 350 struct pte ptes[MAXIMUM_PARTS]; 293 351 }; 294 /* bb_common_bufsiz1 is too small for this on 64 bit CPUs */295 352 #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) 353 #define line_ptr (G.line_ptr ) 354 #define disk_device (G.disk_device ) 355 #define g_partitions (G.g_partitions ) 356 #define units_per_sector (G.units_per_sector ) 357 #define sector_size (G.sector_size ) 358 #define user_set_sector_size (G.user_set_sector_size) 359 #define sector_offset (G.sector_offset ) 360 #define g_heads (G.g_heads ) 361 #define g_sectors (G.g_sectors ) 362 #define g_cylinders (G.g_cylinders ) 363 #define current_label_type (G.current_label_type ) 364 #define display_in_cyl_units (G.display_in_cyl_units) 365 #define possibly_osf_label (G.possibly_osf_label ) 366 #define listing (G.listing ) 367 #define dos_compatible_flag (G.dos_compatible_flag ) 368 #define nowarn (G.nowarn ) 369 #define ext_index (G.ext_index ) 370 #define user_cylinders (G.user_cylinders ) 371 #define user_heads (G.user_heads ) 372 #define user_sectors (G.user_sectors ) 373 #define pt_heads (G.pt_heads ) 374 #define pt_sectors (G.pt_sectors ) 375 #define kern_heads (G.kern_heads ) 376 #define kern_sectors (G.kern_sectors ) 377 #define extended_offset (G.extended_offset ) 378 #define total_number_of_sectors (G.total_number_of_sectors) 379 #define listingbuf (G.listingbuf ) 380 #define line_buffer (G.line_buffer ) 300 381 #define partname_buffer (G.partname_buffer) 301 #define MBRbuffer (G.MBRbuffer) 302 #define ptes (G.ptes) 303 304 305 /* Code */ 382 #define MBRbuffer (G.MBRbuffer ) 383 #define ptes (G.ptes ) 384 #define INIT_G() do { \ 385 SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \ 386 sector_size = DEFAULT_SECTOR_SIZE; \ 387 sector_offset = 1; \ 388 g_partitions = 4; \ 389 display_in_cyl_units = 1; \ 390 units_per_sector = 1; \ 391 dos_compatible_flag = 1; \ 392 } while (0) 393 394 395 /* TODO: move to libbb? */ 396 /* TODO: return unsigned long long, FEATURE_FDISK_BLKSIZE _can_ handle 397 * disks > 2^32 sectors 398 */ 399 static sector_t bb_BLKGETSIZE_sectors(int fd) 400 { 401 uint64_t v64; 402 unsigned long longsectors; 403 404 if (ioctl(fd, BLKGETSIZE64, &v64) == 0) { 405 /* Got bytes, convert to 512 byte sectors */ 406 v64 >>= 9; 407 if (v64 != (sector_t)v64) { 408 ret_trunc: 409 /* Not only DOS, but all other partition tables 410 * we support can't record more than 32 bit 411 * sector counts or offsets 412 */ 413 bb_error_msg("device has more than 2^32 sectors, can't use all of them"); 414 v64 = (uint32_t)-1L; 415 } 416 return v64; 417 } 418 /* Needs temp of type long */ 419 if (ioctl(fd, BLKGETSIZE, &longsectors)) { 420 /* Perhaps this is a disk image */ 421 off_t sz = lseek(fd, 0, SEEK_END); 422 longsectors = 0; 423 if (sz > 0) 424 longsectors = (uoff_t)sz / sector_size; 425 lseek(fd, 0, SEEK_SET); 426 } 427 if (sizeof(long) > sizeof(sector_t) 428 && longsectors != (sector_t)longsectors 429 ) { 430 goto ret_trunc; 431 } 432 return longsectors; 433 } 434 306 435 307 436 #define IS_EXTENDED(i) \ … … 322 451 (sector(s) - 1 + sectors * ((h) + heads * cylinder(s,c))) 323 452 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 */ 336 static int 337 read_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 453 static void 454 close_dev_fd(void) 455 { 456 /* Not really closing, but making sure it is open, and to harmless place */ 457 xmove_fd(xopen(bb_dev_null, O_RDONLY), dev_fd); 458 } 354 459 355 460 /* 356 * return partition name - uses static storage461 * Return partition name - uses static storage 357 462 */ 358 463 static const char * … … 384 489 if (lth) { 385 490 snprintf(bufp, bufsiz, "%*.*s%s%-2u", 386 491 lth-wp-2, w, dev, p, pno); 387 492 } else { 388 493 snprintf(bufp, bufsiz, "%.*s%s%-2u", w, dev, p, pno); … … 390 495 return bufp; 391 496 } 392 393 #if ENABLE_FEATURE_FDISK_WRITABLE394 static void395 set_all_unchanged(void)396 {397 int i;398 399 for (i = 0; i < MAXIMUM_PARTS; i++)400 ptes[i].changed = 0;401 }402 403 static ALWAYS_INLINE void404 set_changed(int i)405 {406 ptes[i].changed = 1;407 }408 #endif /* FEATURE_FDISK_WRITABLE */409 497 410 498 static ALWAYS_INLINE struct partition * … … 428 516 } 429 517 518 static void fdisk_fatal(const char *why) 519 { 520 if (listing) { 521 close_dev_fd(); 522 longjmp(listingbuf, 1); 523 } 524 bb_error_msg_and_die(why, disk_device); 525 } 526 527 static void 528 seek_sector(sector_t secno) 529 { 530 #if ENABLE_FDISK_SUPPORT_LARGE_DISKS 531 off64_t off = (off64_t)secno * sector_size; 532 if (lseek64(dev_fd, off, SEEK_SET) == (off64_t) -1) 533 fdisk_fatal(unable_to_seek); 534 #else 535 uint64_t off = (uint64_t)secno * sector_size; 536 if (off > MAXINT(off_t) 537 || lseek(dev_fd, (off_t)off, SEEK_SET) == (off_t) -1 538 ) { 539 fdisk_fatal(unable_to_seek); 540 } 541 #endif 542 } 543 430 544 #if ENABLE_FEATURE_FDISK_WRITABLE 545 /* Read line; return 0 or first printable char */ 546 static int 547 read_line(const char *prompt) 548 { 549 int sz; 550 551 sz = read_line_input(prompt, line_buffer, sizeof(line_buffer), NULL); 552 if (sz <= 0) 553 exit(EXIT_SUCCESS); /* Ctrl-D or Ctrl-C */ 554 555 if (line_buffer[sz-1] == '\n') 556 line_buffer[--sz] = '\0'; 557 558 line_ptr = line_buffer; 559 while (*line_ptr != '\0' && (unsigned char)*line_ptr <= ' ') 560 line_ptr++; 561 return *line_ptr; 562 } 563 564 static void 565 set_all_unchanged(void) 566 { 567 int i; 568 569 for (i = 0; i < MAXIMUM_PARTS; i++) 570 ptes[i].changed = 0; 571 } 572 573 static ALWAYS_INLINE void 574 set_changed(int i) 575 { 576 ptes[i].changed = 1; 577 } 578 431 579 static ALWAYS_INLINE void 432 580 write_part_table_flag(char *b) … … 439 587 read_nonempty(const char *mesg) 440 588 { 441 while (!read_line(mesg)) /* repeat */; 589 while (!read_line(mesg)) 590 continue; 442 591 return *line_ptr; 443 592 } … … 460 609 while (1) { 461 610 read_nonempty("Hex code (type L to list codes): "); 462 if ( *line_ptr == 'l' || *line_ptr == 'L') {611 if ((line_ptr[0] | 0x20) == 'l') { 463 612 list_types(sys); 464 613 continue; 465 614 } 466 615 v = bb_strtoul(line_ptr, NULL, 16); 467 if (v > 0xff) 468 /* Bad input also triggers this */ 469 continue; 470 return v; 471 } 616 if (v <= 0xff) 617 return v; 618 } 619 } 620 621 static void 622 write_sector(sector_t secno, const void *buf) 623 { 624 seek_sector(secno); 625 xwrite(dev_fd, buf, sector_size); 472 626 } 473 627 #endif /* FEATURE_FDISK_WRITABLE */ 474 628 629 475 630 #include "fdisk_aix.c" 476 631 477 typedef struct{632 struct sun_partition { 478 633 unsigned char info[128]; /* Informative text string */ 479 634 unsigned char spare0[14]; … … 501 656 unsigned short magic; /* Magic number */ 502 657 unsigned short csum; /* Label xor'd checksum */ 503 } sun_partition; 658 } FIX_ALIASING; 659 typedef struct sun_partition sun_partition; 504 660 #define sunlabel ((sun_partition *)MBRbuffer) 505 661 STATIC_OSF void bsd_select(void); 506 662 STATIC_OSF void xbsd_print_disklabel(int); 507 663 #include "fdisk_osf.c" 664 665 STATIC_GPT void gpt_list_table(int xtra); 666 #include "fdisk_gpt.c" 508 667 509 668 #if ENABLE_FEATURE_SGI_LABEL || ENABLE_FEATURE_SUN_LABEL … … 561 720 #include "fdisk_sun.c" 562 721 722 723 static inline_if_little_endian unsigned 724 read4_little_endian(const unsigned char *cp) 725 { 726 uint32_t v; 727 move_from_unaligned32(v, cp); 728 return SWAP_LE32(v); 729 } 730 731 static sector_t 732 get_start_sect(const struct partition *p) 733 { 734 return read4_little_endian(p->start4); 735 } 736 737 static sector_t 738 get_nr_sects(const struct partition *p) 739 { 740 return read4_little_endian(p->size4); 741 } 742 563 743 #if ENABLE_FEATURE_FDISK_WRITABLE 564 744 /* start_sect and nr_sects are stored little endian on all machines */ 565 745 /* moreover, they are not aligned correctly */ 566 static void746 static inline_if_little_endian void 567 747 store4_little_endian(unsigned char *cp, unsigned val) 568 748 { 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 576 static unsigned 577 read4_little_endian(const unsigned char *cp) 578 { 579 return cp[0] + (cp[1] << 8) + (cp[2] << 16) + (cp[3] << 24); 580 } 581 582 #if ENABLE_FEATURE_FDISK_WRITABLE 749 uint32_t v = SWAP_LE32(val); 750 move_to_unaligned32(cp, v); 751 } 752 583 753 static void 584 754 set_start_sect(struct partition *p, unsigned start_sect) … … 586 756 store4_little_endian(p->start4, start_sect); 587 757 } 588 #endif 589 590 static unsigned 591 get_start_sect(const struct partition *p) 592 { 593 return read4_little_endian(p->start4); 594 } 595 596 #if ENABLE_FEATURE_FDISK_WRITABLE 758 597 759 static void 598 760 set_nr_sects(struct partition *p, unsigned nr_sects) … … 602 764 #endif 603 765 604 static unsigned605 get_nr_sects(const struct partition *p)606 {607 return read4_little_endian(p->size4);608 }609 610 /* normally O_RDWR, -l option gives O_RDONLY */611 static int type_open = O_RDWR;612 613 static int ext_index; /* the prime extended partition */614 static int listing; /* no aborts for fdisk -l */615 static int dos_compatible_flag = ~0;616 #if ENABLE_FEATURE_FDISK_WRITABLE617 static int dos_changed;618 static int nowarn; /* no warnings for fdisk -l/-s */619 #endif620 621 static unsigned user_cylinders, user_heads, user_sectors;622 static unsigned pt_heads, pt_sectors;623 static unsigned kern_heads, kern_sectors;624 625 static ullong extended_offset; /* offset of link pointers */626 static ullong total_number_of_sectors;627 628 static void fdisk_fatal(const char *why)629 {630 if (listing) {631 close(fd);632 longjmp(listingbuf, 1);633 }634 bb_error_msg_and_die(why, disk_device);635 }636 637 static void638 seek_sector(ullong secno)639 {640 secno *= sector_size;641 #if ENABLE_FDISK_SUPPORT_LARGE_DISKS642 if (lseek64(fd, (off64_t)secno, SEEK_SET) == (off64_t) -1)643 fdisk_fatal(unable_to_seek);644 #else645 if (secno > MAXINT(off_t)646 || lseek(fd, (off_t)secno, SEEK_SET) == (off_t) -1647 ) {648 fdisk_fatal(unable_to_seek);649 }650 #endif651 }652 653 #if ENABLE_FEATURE_FDISK_WRITABLE654 static void655 write_sector(ullong secno, char *buf)656 {657 seek_sector(secno);658 if (write(fd, buf, sector_size) != sector_size)659 fdisk_fatal(unable_to_write);660 }661 #endif662 663 766 /* Allocate a buffer and read a partition table sector */ 664 767 static void 665 read_pte(struct pte *pe, ullongoffset)666 { 667 pe->offset = offset;668 pe->sectorbuffer = x malloc(sector_size);768 read_pte(struct pte *pe, sector_t offset) 769 { 770 pe->offset_from_dev_start = offset; 771 pe->sectorbuffer = xzalloc(sector_size); 669 772 seek_sector(offset); 670 if (read(fd, pe->sectorbuffer, sector_size) != sector_size) 773 /* xread would make us abort - bad for fdisk -l */ 774 if (full_read(dev_fd, pe->sectorbuffer, sector_size) != sector_size) 671 775 fdisk_fatal(unable_to_read); 672 776 #if ENABLE_FEATURE_FDISK_WRITABLE … … 676 780 } 677 781 678 static unsigned679 get_partition_start (const struct pte *pe)680 { 681 return pe->offset + get_start_sect(pe->part_table);782 static sector_t 783 get_partition_start_from_dev_start(const struct pte *pe) 784 { 785 return pe->offset_from_dev_start + get_start_sect(pe->part_table); 682 786 } 683 787 … … 689 793 * for "is probably nondos partition". 690 794 */ 795 #ifdef UNUSED 691 796 static int 692 797 is_dos_partition(int t) … … 698 803 t == 0xc1 || t == 0xc4 || t == 0xc6); 699 804 } 805 #endif 700 806 701 807 static void … … 738 844 } else if (LABEL_IS_AIX) { 739 845 puts("o\tcreate a new empty DOS partition table"); 846 puts("q\tquit without saving changes"); 847 puts("s\tcreate a new empty Sun disklabel"); /* sun */ 848 } else if (LABEL_IS_GPT) { 849 puts("o\tcreate a new empty DOS partition table"); 850 puts("p\tprint the partition table"); 740 851 puts("q\tquit without saving changes"); 741 852 puts("s\tcreate a new empty Sun disklabel"); /* sun */ … … 840 951 #else 841 952 #define get_sys_types() i386_sys_types 842 #endif /* FEATURE_FDISK_WRITABLE */953 #endif 843 954 844 955 static const char * … … 855 966 } 856 967 968 static int 969 is_cleared_partition(const struct partition *p) 970 { 971 /* We consider partition "cleared" only if it has only zeros */ 972 const char *cp = (const char *)p; 973 int cnt = sizeof(*p); 974 char bits = 0; 975 while (--cnt >= 0) 976 bits |= *cp++; 977 return (bits == 0); 978 } 979 980 static void 981 clear_partition(struct partition *p) 982 { 983 if (p) 984 memset(p, 0, sizeof(*p)); 985 } 857 986 858 987 #if ENABLE_FEATURE_FDISK_WRITABLE … … 874 1003 int i; 875 1004 876 for (size = 0; sys[size]; size++) /* */; 1005 for (size = 0; sys[size]; size++) 1006 continue; 877 1007 878 1008 done = 0; … … 893 1023 } 894 1024 } while (done < last[0]); 895 putchar('\n'); 896 } 897 #endif /* FEATURE_FDISK_WRITABLE */ 898 899 static int 900 is_cleared_partition(const struct partition *p) 901 { 902 return !(!p || p->boot_ind || p->head || p->sector || p->cyl || 903 p->sys_ind || p->end_head || p->end_sector || p->end_cyl || 904 get_start_sect(p) || get_nr_sects(p)); 905 } 906 907 static void 908 clear_partition(struct partition *p) 909 { 910 if (!p) 911 return; 912 memset(p, 0, sizeof(struct partition)); 913 } 914 915 #if ENABLE_FEATURE_FDISK_WRITABLE 916 static void 917 set_partition(int i, int doext, ullong start, ullong stop, int sysid) 1025 bb_putchar('\n'); 1026 } 1027 1028 #define set_hsc(h, s, c, sector) do \ 1029 { \ 1030 s = sector % g_sectors + 1; \ 1031 sector /= g_sectors; \ 1032 h = sector % g_heads; \ 1033 sector /= g_heads; \ 1034 c = sector & 0xff; \ 1035 s |= (sector >> 2) & 0xc0; \ 1036 } while (0) 1037 1038 static void set_hsc_start_end(struct partition *p, sector_t start, sector_t stop) 1039 { 1040 if (dos_compatible_flag && (start / (g_sectors * g_heads) > 1023)) 1041 start = g_heads * g_sectors * 1024 - 1; 1042 set_hsc(p->head, p->sector, p->cyl, start); 1043 1044 if (dos_compatible_flag && (stop / (g_sectors * g_heads) > 1023)) 1045 stop = g_heads * g_sectors * 1024 - 1; 1046 set_hsc(p->end_head, p->end_sector, p->end_cyl, stop); 1047 } 1048 1049 static void 1050 set_partition(int i, int doext, sector_t start, sector_t stop, int sysid) 918 1051 { 919 1052 struct partition *p; 920 ullongoffset;1053 sector_t offset; 921 1054 922 1055 if (doext) { … … 925 1058 } else { 926 1059 p = ptes[i].part_table; 927 offset = ptes[i].offset ;1060 offset = ptes[i].offset_from_dev_start; 928 1061 } 929 1062 p->boot_ind = 0; … … 931 1064 set_start_sect(p, start - offset); 932 1065 set_nr_sects(p, stop - start + 1); 933 if (dos_compatible_flag && (start/(sectors*heads) > 1023)) 934 start = heads*sectors*1024 - 1; 935 set_hsc(p->head, p->sector, p->cyl, start); 936 if (dos_compatible_flag && (stop/(sectors*heads) > 1023)) 937 stop = heads*sectors*1024 - 1; 938 set_hsc(p->end_head, p->end_sector, p->end_cyl, stop); 1066 set_hsc_start_end(p, start, stop); 939 1067 ptes[i].changed = 1; 940 1068 } … … 944 1072 warn_geometry(void) 945 1073 { 946 if ( heads && sectors &&cylinders)1074 if (g_heads && g_sectors && g_cylinders) 947 1075 return 0; 948 1076 949 1077 printf("Unknown value(s) for:"); 950 if (! heads)1078 if (!g_heads) 951 1079 printf(" heads"); 952 if (! sectors)1080 if (!g_sectors) 953 1081 printf(" sectors"); 954 if (! cylinders)1082 if (!g_cylinders) 955 1083 printf(" cylinders"); 956 1084 printf( … … 965 1093 update_units(void) 966 1094 { 967 int cyl_units = heads *sectors;1095 int cyl_units = g_heads * g_sectors; 968 1096 969 1097 if (display_in_cyl_units && cyl_units) … … 977 1105 warn_cylinders(void) 978 1106 { 979 if (LABEL_IS_DOS && cylinders > 1024 && !nowarn)1107 if (LABEL_IS_DOS && g_cylinders > 1024 && !nowarn) 980 1108 printf("\n" 981 "The number of cylinders for this disk is set to % d.\n"1109 "The number of cylinders for this disk is set to %u.\n" 982 1110 "There is nothing wrong with that, but this is larger than 1024,\n" 983 1111 "and could in certain setups cause problems with:\n" … … 985 1113 "2) booting and partitioning software from other OSs\n" 986 1114 " (e.g., DOS FDISK, OS/2 FDISK)\n", 987 cylinders);1115 g_cylinders); 988 1116 } 989 1117 #endif … … 1007 1135 1008 1136 while (IS_EXTENDED(p->sys_ind)) { 1009 struct pte *pe = &ptes[ partitions];1010 1011 if ( partitions >= MAXIMUM_PARTS) {1137 struct pte *pe = &ptes[g_partitions]; 1138 1139 if (g_partitions >= MAXIMUM_PARTS) { 1012 1140 /* This is not a Linux restriction, but 1013 1141 this program uses arrays of size MAXIMUM_PARTS. 1014 1142 Do not try to 'improve' this test. */ 1015 struct pte *pre = &ptes[ partitions-1];1143 struct pte *pre = &ptes[g_partitions - 1]; 1016 1144 #if ENABLE_FEATURE_FDISK_WRITABLE 1017 printf("Warning: deleting partitions after % d\n",1018 partitions);1145 printf("Warning: deleting partitions after %u\n", 1146 g_partitions); 1019 1147 pre->changed = 1; 1020 1148 #endif … … 1034 1162 printf("Warning: extra link " 1035 1163 "pointer in partition table" 1036 " % d\n",partitions + 1);1164 " %u\n", g_partitions + 1); 1037 1165 else 1038 1166 pe->ext_pointer = p; … … 1041 1169 printf("Warning: ignoring extra " 1042 1170 "data in partition table" 1043 " % d\n",partitions + 1);1171 " %u\n", g_partitions + 1); 1044 1172 else 1045 1173 pe->part_table = p; … … 1062 1190 1063 1191 p = pe->ext_pointer; 1064 partitions++;1192 g_partitions++; 1065 1193 } 1066 1194 … … 1068 1196 /* remove empty links */ 1069 1197 remove: 1070 for (i = 4; i < partitions; i++) {1198 for (i = 4; i < g_partitions; i++) { 1071 1199 struct pte *pe = &ptes[i]; 1072 1200 1073 1201 if (!get_nr_sects(pe->part_table) 1074 && ( partitions > 5 || ptes[4].part_table->sys_ind)1202 && (g_partitions > 5 || ptes[4].part_table->sys_ind) 1075 1203 ) { 1076 printf("Omitting empty partition (% d)\n", i+1);1204 printf("Omitting empty partition (%u)\n", i+1); 1077 1205 delete_partition(i); 1078 1206 goto remove; /* numbering changed */ … … 1086 1214 create_doslabel(void) 1087 1215 { 1088 int i;1089 1090 1216 printf(msg_building_new_label, "DOS disklabel"); 1091 1217 1092 current_label_type = label_dos; 1093 1218 current_label_type = LABEL_DOS; 1094 1219 #if ENABLE_FEATURE_OSF_LABEL 1095 1220 possibly_osf_label = 0; 1096 1221 #endif 1097 partitions = 4; 1098 1099 for (i = 510-64; i < 510; i++) 1100 MBRbuffer[i] = 0; 1222 g_partitions = 4; 1223 1224 memset(&MBRbuffer[510 - 4*16], 0, 4*16); 1101 1225 write_part_table_flag(MBRbuffer); 1102 1226 extended_offset = 0; 1103 1227 set_all_unchanged(); 1104 1228 set_changed(0); 1105 get_boot( create_empty_dos);1106 } 1107 #endif /* FEATURE_FDISK_WRITABLE */1229 get_boot(CREATE_EMPTY_DOS); 1230 } 1231 #endif 1108 1232 1109 1233 static void … … 1112 1236 if (!user_set_sector_size) { 1113 1237 int arg; 1114 if (ioctl( fd, BLKSSZGET, &arg) == 0)1238 if (ioctl(dev_fd, BLKSSZGET, &arg) == 0) 1115 1239 sector_size = arg; 1116 1240 if (sector_size != DEFAULT_SECTOR_SIZE) 1117 printf("Note: sector size is %d (not %d)\n", 1118 sector_size, DEFAULT_SECTOR_SIZE); 1241 printf("Note: sector size is %u " 1242 "(not " DEFAULT_SECTOR_SIZE_STR ")\n", 1243 sector_size); 1119 1244 } 1120 1245 } … … 1125 1250 struct hd_geometry geometry; 1126 1251 1127 if (!ioctl( fd, HDIO_GETGEO, &geometry)) {1252 if (!ioctl(dev_fd, HDIO_GETGEO, &geometry)) { 1128 1253 kern_heads = geometry.heads; 1129 1254 kern_sectors = geometry.sectors; … … 1169 1294 { 1170 1295 int sec_fac; 1171 uint64_t v64;1172 1296 1173 1297 get_sectorsize(); … … 1176 1300 guess_device_type(); 1177 1301 #endif 1178 heads = cylinders =sectors = 0;1302 g_heads = g_cylinders = g_sectors = 0; 1179 1303 kern_heads = kern_sectors = 0; 1180 1304 pt_heads = pt_sectors = 0; … … 1183 1307 get_partition_table_geometry(); 1184 1308 1185 heads = user_heads ? user_heads :1309 g_heads = user_heads ? user_heads : 1186 1310 pt_heads ? pt_heads : 1187 1311 kern_heads ? kern_heads : 255; 1188 sectors = user_sectors ? user_sectors :1312 g_sectors = user_sectors ? user_sectors : 1189 1313 pt_sectors ? pt_sectors : 1190 1314 kern_sectors ? kern_sectors : 63; 1191 if (ioctl(fd, BLKGETSIZE64, &v64) == 0) { 1192 /* got bytes, convert to 512 byte sectors */ 1193 total_number_of_sectors = (v64 >> 9); 1194 } else { 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 } 1315 total_number_of_sectors = bb_BLKGETSIZE_sectors(dev_fd); 1200 1316 1201 1317 sector_offset = 1; 1202 1318 if (dos_compatible_flag) 1203 sector_offset = sectors;1204 1205 cylinders = total_number_of_sectors / (heads *sectors * sec_fac);1206 if (! cylinders)1207 cylinders = user_cylinders;1319 sector_offset = g_sectors; 1320 1321 g_cylinders = total_number_of_sectors / (g_heads * g_sectors * sec_fac); 1322 if (!g_cylinders) 1323 g_cylinders = user_cylinders; 1208 1324 } 1209 1325 1210 1326 /* 1211 * Read MBR. Returns: 1327 * Opens disk_device and optionally reads MBR. 1328 * If what == OPEN_MAIN: 1329 * Open device, read MBR. Abort program on short read. Create empty 1330 * disklabel if the on-disk structure is invalid (WRITABLE mode). 1331 * If what == TRY_ONLY: 1332 * Open device, read MBR. Return an error if anything is out of place. 1333 * Do not create an empty disklabel. This is used for the "list" 1334 * operations: "fdisk -l /dev/sda" and "fdisk -l" (all devices). 1335 * If what == CREATE_EMPTY_*: 1336 * This means that get_boot() was called recursively from create_*label(). 1337 * Do not re-open the device; just set up the ptes array and print 1338 * geometry warnings. 1339 * 1340 * Returns: 1212 1341 * -1: no 0xaa55 flag present (possibly entire disk BSD) 1213 1342 * 0: found or created label 1214 1343 * 1: I/O error 1215 1344 */ 1216 static int 1217 get_boot(enum action what) 1218 { 1219 int i; 1220 1221 partitions = 4; 1222 1345 #if ENABLE_FEATURE_SUN_LABEL || ENABLE_FEATURE_FDISK_WRITABLE 1346 static int get_boot(enum action what) 1347 #else 1348 static int get_boot(void) 1349 #define get_boot(what) get_boot() 1350 #endif 1351 { 1352 int i, fd; 1353 1354 g_partitions = 4; 1223 1355 for (i = 0; i < 4; i++) { 1224 1356 struct pte *pe = &ptes[i]; 1225 1226 1357 pe->part_table = pt_offset(MBRbuffer, i); 1227 1358 pe->ext_pointer = NULL; 1228 pe->offset = 0;1359 pe->offset_from_dev_start = 0; 1229 1360 pe->sectorbuffer = MBRbuffer; 1230 1361 #if ENABLE_FEATURE_FDISK_WRITABLE 1231 pe->changed = (what == create_empty_dos); 1232 #endif 1233 } 1234 1235 #if ENABLE_FEATURE_SUN_LABEL 1236 if (what == create_empty_sun && check_sun_label()) 1237 return 0; 1238 #endif 1239 1240 memset(MBRbuffer, 0, 512); 1362 pe->changed = (what == CREATE_EMPTY_DOS); 1363 #endif 1364 } 1241 1365 1242 1366 #if ENABLE_FEATURE_FDISK_WRITABLE 1243 if (what == create_empty_dos) 1244 goto got_dos_table; /* skip reading disk */ 1245 1246 fd = open(disk_device, type_open); 1367 // ALERT! highly idiotic design! 1368 // We end up here when we call get_boot() recursively 1369 // via get_boot() [table is bad] -> create_doslabel() -> get_boot(CREATE_EMPTY_DOS). 1370 // or get_boot() [table is bad] -> create_sunlabel() -> get_boot(CREATE_EMPTY_SUN). 1371 // (just factor out re-init of ptes[0,1,2,3] in a separate fn instead?) 1372 // So skip opening device _again_... 1373 if (what == CREATE_EMPTY_DOS IF_FEATURE_SUN_LABEL(|| what == CREATE_EMPTY_SUN)) 1374 goto created_table; 1375 1376 fd = open(disk_device, (option_mask32 & OPT_l) ? O_RDONLY : O_RDWR); 1377 1247 1378 if (fd < 0) { 1248 1379 fd = open(disk_device, O_RDONLY); 1249 1380 if (fd < 0) { 1250 if (what == try_only)1381 if (what == TRY_ONLY) 1251 1382 return 1; 1252 1383 fdisk_fatal(unable_to_open); 1253 } else1254 printf("You will not be able to write "1255 "the partition table\n");1256 }1257 1258 if (512 != read(fd, MBRbuffer, 512)) {1259 if (what == try_only)1384 } 1385 printf("'%s' is opened for read only\n", disk_device); 1386 } 1387 xmove_fd(fd, dev_fd); 1388 if (512 != full_read(dev_fd, MBRbuffer, 512)) { 1389 if (what == TRY_ONLY) { 1390 close_dev_fd(); 1260 1391 return 1; 1392 } 1261 1393 fdisk_fatal(unable_to_read); 1262 1394 } … … 1265 1397 if (fd < 0) 1266 1398 return 1; 1267 if (512 != read(fd, MBRbuffer, 512)) 1399 if (512 != full_read(fd, MBRbuffer, 512)) { 1400 close(fd); 1268 1401 return 1; 1402 } 1403 xmove_fd(fd, dev_fd); 1269 1404 #endif 1270 1405 1271 1406 get_geometry(); 1272 1273 1407 update_units(); 1274 1408 … … 1277 1411 return 0; 1278 1412 #endif 1279 1280 1413 #if ENABLE_FEATURE_SGI_LABEL 1281 1414 if (check_sgi_label()) 1282 1415 return 0; 1283 1416 #endif 1284 1285 1417 #if ENABLE_FEATURE_AIX_LABEL 1286 1418 if (check_aix_label()) 1287 1419 return 0; 1288 1420 #endif 1289 1421 #if ENABLE_FEATURE_GPT_LABEL 1422 if (check_gpt_label()) 1423 return 0; 1424 #endif 1290 1425 #if ENABLE_FEATURE_OSF_LABEL 1291 1426 if (check_osf_label()) { 1292 1427 possibly_osf_label = 1; 1293 1428 if (!valid_part_table_flag(MBRbuffer)) { 1294 current_label_type = label_osf;1429 current_label_type = LABEL_OSF; 1295 1430 return 0; 1296 1431 } … … 1300 1435 #endif 1301 1436 1302 #if ENABLE_FEATURE_FDISK_WRITABLE1303 got_dos_table:1304 #endif1305 1306 if (!valid_part_table_flag(MBRbuffer)) {1307 1437 #if !ENABLE_FEATURE_FDISK_WRITABLE 1438 if (!valid_part_table_flag(MBRbuffer)) 1308 1439 return -1; 1309 1440 #else 1310 switch (what) {1311 case fdisk:1441 if (!valid_part_table_flag(MBRbuffer)) { 1442 if (what == OPEN_MAIN) { 1312 1443 printf("Device contains neither a valid DOS " 1313 "partition table, nor Sun, SGI or OSF"1444 "partition table, nor Sun, SGI, OSF or GPT " 1314 1445 "disklabel\n"); 1315 1446 #ifdef __sparc__ 1316 #if ENABLE_FEATURE_SUN_LABEL 1317 create_sunlabel(); 1318 #endif 1447 IF_FEATURE_SUN_LABEL(create_sunlabel();) 1319 1448 #else 1320 1449 create_doslabel(); 1321 1450 #endif 1322 1451 return 0; 1323 case try_only: 1324 return -1; 1325 case create_empty_dos: 1326 #if ENABLE_FEATURE_SUN_LABEL 1327 case create_empty_sun: 1328 #endif 1329 break; 1330 default: 1331 bb_error_msg_and_die("internal error"); 1332 } 1452 } 1453 /* TRY_ONLY: */ 1454 return -1; 1455 } 1456 created_table: 1333 1457 #endif /* FEATURE_FDISK_WRITABLE */ 1334 } 1335 1336 #if ENABLE_FEATURE_FDISK_WRITABLE 1337 warn_cylinders(); 1338 #endif 1458 1459 1460 IF_FEATURE_FDISK_WRITABLE(warn_cylinders();) 1339 1461 warn_geometry(); 1340 1462 1341 1463 for (i = 0; i < 4; i++) { 1342 struct pte *pe = &ptes[i]; 1343 1344 if (IS_EXTENDED(pe->part_table->sys_ind)) { 1345 if (partitions != 4) 1464 if (IS_EXTENDED(ptes[i].part_table->sys_ind)) { 1465 if (g_partitions != 4) 1346 1466 printf("Ignoring extra extended " 1347 "partition % d\n", i + 1);1467 "partition %u\n", i + 1); 1348 1468 else 1349 1469 read_extended(i); … … 1351 1471 } 1352 1472 1353 for (i = 3; i < partitions; i++) {1473 for (i = 3; i < g_partitions; i++) { 1354 1474 struct pte *pe = &ptes[i]; 1355 1356 1475 if (!valid_part_table_flag(pe->sectorbuffer)) { 1357 1476 printf("Warning: invalid flag 0x%02x,0x%02x of partition " 1358 "table % dwill be corrected by w(rite)\n",1477 "table %u will be corrected by w(rite)\n", 1359 1478 pe->sectorbuffer[510], 1360 1479 pe->sectorbuffer[511], 1361 1480 i + 1); 1362 #if ENABLE_FEATURE_FDISK_WRITABLE 1363 pe->changed = 1; 1364 #endif 1481 IF_FEATURE_FDISK_WRITABLE(pe->changed = 1;) 1365 1482 } 1366 1483 } … … 1377 1494 * There is no default if DFLT is not between LOW and HIGH. 1378 1495 */ 1379 static unsigned1380 read_int( unsigned low, unsigned dflt, unsigned high, unsignedbase, const char *mesg)1381 { 1382 unsigned i;1496 static sector_t 1497 read_int(sector_t low, sector_t dflt, sector_t high, sector_t base, const char *mesg) 1498 { 1499 sector_t value; 1383 1500 int default_ok = 1; 1384 1501 const char *fmt = "%s (%u-%u, default %u): "; … … 1403 1520 int absolute = 0; 1404 1521 1405 i = atoi(line_ptr + 1); 1406 1522 value = atoi(line_ptr + 1); 1523 1524 /* (1) if 2nd char is digit, use_default = 0. 1525 * (2) move line_ptr to first non-digit. */ 1407 1526 while (isdigit(*++line_ptr)) 1408 1527 use_default = 0; … … 1412 1531 case 'C': 1413 1532 if (!display_in_cyl_units) 1414 i *= heads *sectors;1533 value *= g_heads * g_sectors; 1415 1534 break; 1416 1535 case 'K': … … 1435 1554 unsigned long unit; 1436 1555 1437 bytes = (ullong) i* absolute;1556 bytes = (ullong) value * absolute; 1438 1557 unit = sector_size * units_per_sector; 1439 1558 bytes += unit/2; /* round */ 1440 1559 bytes /= unit; 1441 i= bytes;1560 value = bytes; 1442 1561 } 1443 1562 if (minus) 1444 i = -i;1445 i+= base;1563 value = -value; 1564 value += base; 1446 1565 } else { 1447 i= atoi(line_ptr);1566 value = atoi(line_ptr); 1448 1567 while (isdigit(*line_ptr)) { 1449 1568 line_ptr++; … … 1452 1571 } 1453 1572 if (use_default) { 1454 i= dflt;1455 printf("Using default value %u\n", i);1456 } 1457 if ( i >= low && i<= high)1573 value = dflt; 1574 printf("Using default value %u\n", value); 1575 } 1576 if (value >= low && value <= high) 1458 1577 break; 1459 1578 printf("Value is out of range\n"); 1460 1579 } 1461 return i;1462 } 1463 1464 static int1465 get_partition(int warn, intmax)1580 return value; 1581 } 1582 1583 static unsigned 1584 get_partition(int warn, unsigned max) 1466 1585 { 1467 1586 struct pte *pe; 1468 inti;1587 unsigned i; 1469 1588 1470 1589 i = read_int(1, 0, max, 0, "Partition number") - 1; … … 1476 1595 || (LABEL_IS_SGI && !sgi_get_num_sectors(i)) 1477 1596 ) { 1478 printf("Warning: partition % dhas empty type\n", i+1);1597 printf("Warning: partition %u has empty type\n", i+1); 1479 1598 } 1480 1599 } … … 1483 1602 1484 1603 static int 1485 get_existing_partition(int warn, intmax)1604 get_existing_partition(int warn, unsigned max) 1486 1605 { 1487 1606 int pno = -1; 1488 inti;1607 unsigned i; 1489 1608 1490 1609 for (i = 0; i < max; i++) { … … 1499 1618 } 1500 1619 if (pno >= 0) { 1501 printf("Selected partition % d\n", pno+1);1620 printf("Selected partition %u\n", pno+1); 1502 1621 return pno; 1503 1622 } … … 1510 1629 1511 1630 static int 1512 get_nonexisting_partition(int warn, intmax)1631 get_nonexisting_partition(int warn, unsigned max) 1513 1632 { 1514 1633 int pno = -1; 1515 inti;1634 unsigned i; 1516 1635 1517 1636 for (i = 0; i < max; i++) { … … 1526 1645 } 1527 1646 if (pno >= 0) { 1528 printf("Selected partition % d\n", pno+1);1647 printf("Selected partition %u\n", pno+1); 1529 1648 return pno; 1530 1649 } … … 1553 1672 1554 1673 if (IS_EXTENDED(p->sys_ind) && !p->boot_ind) 1555 printf("WARNING: Partition % dis an extended partition\n", i + 1);1674 printf("WARNING: Partition %u is an extended partition\n", i + 1); 1556 1675 p->boot_ind = (p->boot_ind ? 0 : ACTIVE_FLAG); 1557 1676 pe->changed = 1; … … 1561 1680 toggle_dos_compatibility_flag(void) 1562 1681 { 1563 dos_compatible_flag = ~dos_compatible_flag;1682 dos_compatible_flag = 1 - dos_compatible_flag; 1564 1683 if (dos_compatible_flag) { 1565 sector_offset = sectors;1684 sector_offset = g_sectors; 1566 1685 printf("DOS Compatibility flag is set\n"); 1567 1686 } else { … … 1597 1716 if (i < 4) { 1598 1717 if (IS_EXTENDED(p->sys_ind) && i == ext_index) { 1599 partitions = 4;1718 g_partitions = 4; 1600 1719 ptes[ext_index].ext_pointer = NULL; 1601 1720 extended_offset = 0; … … 1607 1726 if (!q->sys_ind && i > 4) { 1608 1727 /* the last one in the chain - just delete */ 1609 -- partitions;1728 --g_partitions; 1610 1729 --i; 1611 1730 clear_partition(ptes[i].ext_pointer); … … 1620 1739 set_nr_sects(p, get_nr_sects(q)); 1621 1740 ptes[i-1].changed = 1; 1622 } else if ( partitions > 5) { /* 5 will be moved to 4 */1741 } else if (g_partitions > 5) { /* 5 will be moved to 4 */ 1623 1742 /* the first logical in a longer chain */ 1624 1743 pe = &ptes[5]; … … 1626 1745 if (pe->part_table) /* prevent SEGFAULT */ 1627 1746 set_start_sect(pe->part_table, 1628 get_partition_start(pe) -1629 1630 pe->offset = extended_offset;1747 get_partition_start_from_dev_start(pe) - 1748 extended_offset); 1749 pe->offset_from_dev_start = extended_offset; 1631 1750 pe->changed = 1; 1632 1751 } 1633 1752 1634 if ( partitions > 5) {1635 partitions--;1636 while (i < partitions) {1753 if (g_partitions > 5) { 1754 g_partitions--; 1755 while (i < g_partitions) { 1637 1756 ptes[i] = ptes[i+1]; 1638 1757 i++; 1639 1758 } 1640 } else 1759 } else { 1641 1760 /* the only logical: clear only */ 1642 1761 clear_partition(ptes[i].part_table); 1762 } 1643 1763 } 1644 1764 } … … 1654 1774 only works for Linux like partition tables. */ 1655 1775 if (!LABEL_IS_SGI) { 1656 i = get_existing_partition(0, partitions);1776 i = get_existing_partition(0, g_partitions); 1657 1777 } else { 1658 i = get_partition(0, partitions);1778 i = get_partition(0, g_partitions); 1659 1779 } 1660 1780 if (i == -1) … … 1666 1786 the reverse change must be allowed, too */ 1667 1787 if (!sys && !LABEL_IS_SGI && !LABEL_IS_SUN && !get_nr_sects(p)) { 1668 printf("Partition % ddoes not exist yet!\n", i + 1);1788 printf("Partition %u does not exist yet!\n", i + 1); 1669 1789 return; 1670 1790 } … … 1717 1837 p->sys_ind = sys; 1718 1838 1719 printf("Changed system type of partition % d"1839 printf("Changed system type of partition %u " 1720 1840 "to %x (%s)\n", i + 1, sys, 1721 1841 partition_type(sys)); 1722 1842 ptes[i].changed = 1; 1723 if (is_dos_partition(origsys) || 1724 is_dos_partition(sys)) 1725 dos_changed = 1; 1843 //if (is_dos_partition(origsys) || is_dos_partition(sys)) 1844 // dos_changed = 1; 1726 1845 break; 1727 1846 } … … 1739 1858 linear2chs(unsigned ls, unsigned *c, unsigned *h, unsigned *s) 1740 1859 { 1741 int spc = heads *sectors;1860 int spc = g_heads * g_sectors; 1742 1861 1743 1862 *c = ls / spc; 1744 1863 ls = ls % spc; 1745 *h = ls / sectors;1746 *s = ls % sectors + 1; /* sectors count from 1 */1864 *h = ls / g_sectors; 1865 *s = ls % g_sectors + 1; /* sectors count from 1 */ 1747 1866 } 1748 1867 … … 1755 1874 unsigned lec, leh, les; /* logical ending c, h, s */ 1756 1875 1757 if (! heads || !sectors || (partition >= 4))1876 if (!g_heads || !g_sectors || (partition >= 4)) 1758 1877 return; /* do not check extended partitions */ 1759 1878 … … 1775 1894 1776 1895 /* Same physical / logical beginning? */ 1777 if ( cylinders <= 1024 && (pbc != lbc || pbh != lbh || pbs != lbs)) {1778 printf("Partition % dhas different physical/logical "1896 if (g_cylinders <= 1024 && (pbc != lbc || pbh != lbh || pbs != lbs)) { 1897 printf("Partition %u has different physical/logical " 1779 1898 "beginnings (non-Linux?):\n", partition + 1); 1780 printf(" phys=(% d, %d, %d) ", pbc, pbh, pbs);1781 printf("logical=(% d, %d, %d)\n",lbc, lbh, lbs);1899 printf(" phys=(%u, %u, %u) ", pbc, pbh, pbs); 1900 printf("logical=(%u, %u, %u)\n", lbc, lbh, lbs); 1782 1901 } 1783 1902 1784 1903 /* Same physical / logical ending? */ 1785 if ( cylinders <= 1024 && (pec != lec || peh != leh || pes != les)) {1786 printf("Partition % dhas different physical/logical "1904 if (g_cylinders <= 1024 && (pec != lec || peh != leh || pes != les)) { 1905 printf("Partition %u has different physical/logical " 1787 1906 "endings:\n", partition + 1); 1788 printf(" phys=(% d, %d, %d) ", pec, peh, pes);1789 printf("logical=(% d, %d, %d)\n", lec, leh, les);1907 printf(" phys=(%u, %u, %u) ", pec, peh, pes); 1908 printf("logical=(%u, %u, %u)\n", lec, leh, les); 1790 1909 } 1791 1910 1792 1911 /* Ending on cylinder boundary? */ 1793 if (peh != ( heads - 1) || pes !=sectors) {1794 printf("Partition % idoes not end on cylinder boundary\n",1912 if (peh != (g_heads - 1) || pes != g_sectors) { 1913 printf("Partition %u does not end on cylinder boundary\n", 1795 1914 partition + 1); 1796 1915 } … … 1800 1919 list_disk_geometry(void) 1801 1920 { 1802 long long bytes = (total_number_of_sectors << 9);1803 long megabytes = bytes /1000000;1921 ullong bytes = ((ullong)total_number_of_sectors << 9); 1922 long megabytes = bytes / 1000000; 1804 1923 1805 1924 if (megabytes < 10000) 1806 printf("\nDisk %s: %l d MB, %lldbytes\n",1807 1925 printf("\nDisk %s: %lu MB, %llu bytes\n", 1926 disk_device, megabytes, bytes); 1808 1927 else 1809 printf("\nDisk %s: %l d.%ld GB, %lldbytes\n",1810 1811 printf("% d heads, %d sectors/track, %dcylinders",1812 heads, sectors,cylinders);1928 printf("\nDisk %s: %lu.%lu GB, %llu bytes\n", 1929 disk_device, megabytes/1000, (megabytes/100)%10, bytes); 1930 printf("%u heads, %u sectors/track, %u cylinders", 1931 g_heads, g_sectors, g_cylinders); 1813 1932 if (units_per_sector == 1) 1814 printf(", total % llu sectors",1815 1816 printf("\nUnits = %s of % d * %d = %dbytes\n\n",1817 1818 1933 printf(", total %"SECT_FMT"u sectors", 1934 total_number_of_sectors / (sector_size/512)); 1935 printf("\nUnits = %s of %u * %u = %u bytes\n\n", 1936 str_units(PLURAL), 1937 units_per_sector, sector_size, units_per_sector * sector_size); 1819 1938 } 1820 1939 … … 1829 1948 const struct pte *pe; 1830 1949 const struct partition *p; 1831 ullonglast_p_start_pos = 0, p_start_pos;1832 inti, last_i = 0;1833 1834 for (i = 0; i < partitions; i++) {1950 sector_t last_p_start_pos = 0, p_start_pos; 1951 unsigned i, last_i = 0; 1952 1953 for (i = 0; i < g_partitions; i++) { 1835 1954 if (i == 4) { 1836 1955 last_i = 4; … … 1838 1957 } 1839 1958 pe = &ptes[i]; 1840 if ((p = pe->part_table)->sys_ind) { 1841 p_start_pos = get_partition_start(pe); 1959 p = pe->part_table; 1960 if (p->sys_ind) { 1961 p_start_pos = get_partition_start_from_dev_start(pe); 1842 1962 1843 1963 if (last_p_start_pos > p_start_pos) { … … 1877 1997 /* (Its sector is the global extended_offset.) */ 1878 1998 stage1: 1879 for (j = 5; j < partitions-1; j++) {1880 oj = ptes[j].offset ;1881 ojj = ptes[j+1].offset ;1999 for (j = 5; j < g_partitions - 1; j++) { 2000 oj = ptes[j].offset_from_dev_start; 2001 ojj = ptes[j+1].offset_from_dev_start; 1882 2002 if (oj > ojj) { 1883 ptes[j].offset = ojj;1884 ptes[j+1].offset = oj;2003 ptes[j].offset_from_dev_start = ojj; 2004 ptes[j+1].offset_from_dev_start = oj; 1885 2005 pj = ptes[j].part_table; 1886 2006 set_start_sect(pj, get_start_sect(pj)+oj-ojj); … … 1897 2017 /* Stage 2: sort starting sectors */ 1898 2018 stage2: 1899 for (j = 4; j < partitions-1; j++) {2019 for (j = 4; j < g_partitions - 1; j++) { 1900 2020 pj = ptes[j].part_table; 1901 2021 pjj = ptes[j+1].part_table; 1902 2022 sj = get_start_sect(pj); 1903 2023 sjj = get_start_sect(pjj); 1904 oj = ptes[j].offset ;1905 ojj = ptes[j+1].offset ;2024 oj = ptes[j].offset_from_dev_start; 2025 ojj = ptes[j+1].offset_from_dev_start; 1906 2026 if (oj+sj > ojj+sjj) { 1907 2027 tmp = *pj; … … 1915 2035 1916 2036 /* Probably something was changed */ 1917 for (j = 4; j < partitions; j++)2037 for (j = 4; j < g_partitions; j++) 1918 2038 ptes[j].changed = 1; 1919 2039 } … … 1956 2076 1957 2077 printf("Done.\n"); 1958 1959 2078 } 1960 2079 #endif … … 1970 2089 return; 1971 2090 } 1972 if (LABEL_IS_S UN) {2091 if (LABEL_IS_SGI) { 1973 2092 sgi_list_table(xtra); 2093 return; 2094 } 2095 if (LABEL_IS_GPT) { 2096 gpt_list_table(xtra); 1974 2097 return; 1975 2098 } … … 1995 2118 w+1, "Device"); 1996 2119 1997 for (i = 0; i < partitions; i++) {2120 for (i = 0; i < g_partitions; i++) { 1998 2121 const struct pte *pe = &ptes[i]; 1999 ullongpsects;2000 ullongpblocks;2122 sector_t psects; 2123 sector_t pblocks; 2001 2124 unsigned podd; 2002 2125 … … 2016 2139 pblocks *= (sector_size / 1024); 2017 2140 2018 printf("%s %c %11 llu %11llu %11llu%c %2x %s\n",2141 printf("%s %c %11"SECT_FMT"u %11"SECT_FMT"u %11"SECT_FMT"u%c %2x %s\n", 2019 2142 partname(disk_device, i+1, w+2), 2020 2143 !p->boot_ind ? ' ' : p->boot_ind == ACTIVE_FLAG /* boot flag */ 2021 2144 ? '*' : '?', 2022 (ullong) cround(get_partition_start(pe)), /* start */2023 (ullong) cround(get_partition_start(pe) + psects /* end */2145 cround(get_partition_start_from_dev_start(pe)), /* start */ 2146 cround(get_partition_start_from_dev_start(pe) + psects /* end */ 2024 2147 - (psects ? 1 : 0)), 2025 (ullong)pblocks, podd ? '+' : ' ', /* odd flag on end */2148 pblocks, podd ? '+' : ' ', /* odd flag on end */ 2026 2149 p->sys_ind, /* type id */ 2027 2150 partition_type(p->sys_ind)); /* type name */ … … 2031 2154 2032 2155 /* Is partition table in disk order? It need not be, but... */ 2033 /* partition table entries are not checked for correct order if this2034 2156 /* partition table entries are not checked for correct order 2157 * if this is a sgi, sun or aix labeled disk... */ 2035 2158 if (LABEL_IS_DOS && wrong_p_order(NULL)) { 2036 2159 /* FIXME */ … … 2047 2170 int i; 2048 2171 2049 printf("\nDisk %s: % d heads, %d sectors, %dcylinders\n\n",2050 disk_device, heads, sectors,cylinders);2172 printf("\nDisk %s: %u heads, %u sectors, %u cylinders\n\n", 2173 disk_device, g_heads, g_sectors, g_cylinders); 2051 2174 printf("Nr AF Hd Sec Cyl Hd Sec Cyl Start Size ID\n"); 2052 for (i = 0; i < partitions; i++) {2175 for (i = 0; i < g_partitions; i++) { 2053 2176 pe = &ptes[i]; 2054 2177 p = (extend ? pe->ext_pointer : pe->part_table); 2055 2178 if (p != NULL) { 2056 printf("%2 d %02x%4d%4d%5d%4d%4d%5d%11u%11u %02x\n",2179 printf("%2u %02x%4u%4u%5u%4u%4u%5u%11"SECT_FMT"u%11"SECT_FMT"u %02x\n", 2057 2180 i + 1, p->boot_ind, p->head, 2058 2181 sector(p->sector), … … 2060 2183 sector(p->end_sector), 2061 2184 cylinder(p->end_sector, p->end_cyl), 2062 get_start_sect(p), get_nr_sects(p), p->sys_ind); 2185 get_start_sect(p), get_nr_sects(p), 2186 p->sys_ind); 2063 2187 if (p->sys_ind) 2064 2188 check_consistency(p, i); … … 2070 2194 #if ENABLE_FEATURE_FDISK_WRITABLE 2071 2195 static void 2072 fill_bounds( ullong *first, ullong*last)2073 { 2074 inti;2196 fill_bounds(sector_t *first, sector_t *last) 2197 { 2198 unsigned i; 2075 2199 const struct pte *pe = &ptes[0]; 2076 2200 const struct partition *p; 2077 2201 2078 for (i = 0; i < partitions; pe++,i++) {2202 for (i = 0; i < g_partitions; pe++,i++) { 2079 2203 p = pe->part_table; 2080 2204 if (!p->sys_ind || IS_EXTENDED(p->sys_ind)) { … … 2082 2206 last[i] = 0; 2083 2207 } else { 2084 first[i] = get_partition_start (pe);2208 first[i] = get_partition_start_from_dev_start(pe); 2085 2209 last[i] = first[i] + get_nr_sects(p) - 1; 2086 2210 } … … 2089 2213 2090 2214 static void 2091 check(int n, unsigned h, unsigned s, unsigned c, ullongstart)2092 { 2093 ullongtotal, real_s, real_c;2215 check(int n, unsigned h, unsigned s, unsigned c, sector_t start) 2216 { 2217 sector_t total, real_s, real_c; 2094 2218 2095 2219 real_s = sector(s) - 1; 2096 2220 real_c = cylinder(s, c); 2097 total = (real_c * sectors + real_s) *heads + h;2221 total = (real_c * g_sectors + real_s) * g_heads + h; 2098 2222 if (!total) 2099 printf("Partition % dcontains sector 0\n", n);2100 if (h >= heads)2101 printf("Partition % d: head %d greater than maximum %d\n",2102 n, h + 1, heads);2103 if (real_s >= sectors)2104 printf("Partition % d: sector %dgreater than "2105 "maximum % d\n", n, s,sectors);2106 if (real_c >= cylinders)2107 printf("Partition % d: cylinder %llu greater than "2108 "maximum % d\n", n, real_c + 1,cylinders);2109 if ( cylinders <= 1024 && start != total)2110 printf("Partition % d: previous sectors %llu disagrees with "2111 "total % llu\n", n, start, total);2223 printf("Partition %u contains sector 0\n", n); 2224 if (h >= g_heads) 2225 printf("Partition %u: head %u greater than maximum %u\n", 2226 n, h + 1, g_heads); 2227 if (real_s >= g_sectors) 2228 printf("Partition %u: sector %u greater than " 2229 "maximum %u\n", n, s, g_sectors); 2230 if (real_c >= g_cylinders) 2231 printf("Partition %u: cylinder %"SECT_FMT"u greater than " 2232 "maximum %u\n", n, real_c + 1, g_cylinders); 2233 if (g_cylinders <= 1024 && start != total) 2234 printf("Partition %u: previous sectors %"SECT_FMT"u disagrees with " 2235 "total %"SECT_FMT"u\n", n, start, total); 2112 2236 } 2113 2237 … … 2116 2240 { 2117 2241 int i, j; 2118 unsignedtotal = 1;2119 ullong first[partitions], last[partitions];2242 sector_t total = 1; 2243 sector_t first[g_partitions], last[g_partitions]; 2120 2244 struct partition *p; 2121 2245 … … 2133 2257 2134 2258 fill_bounds(first, last); 2135 for (i = 0; i < partitions; i++) {2259 for (i = 0; i < g_partitions; i++) { 2136 2260 struct pte *pe = &ptes[i]; 2137 2261 … … 2139 2263 if (p->sys_ind && !IS_EXTENDED(p->sys_ind)) { 2140 2264 check_consistency(p, i); 2141 if (get_partition_start (pe) < first[i])2265 if (get_partition_start_from_dev_start(pe) < first[i]) 2142 2266 printf("Warning: bad start-of-data in " 2143 "partition % d\n", i + 1);2267 "partition %u\n", i + 1); 2144 2268 check(i + 1, p->end_head, p->end_sector, p->end_cyl, 2145 2269 last[i]); … … 2148 2272 if ((first[i] >= first[j] && first[i] <= last[j]) 2149 2273 || ((last[i] <= last[j] && last[i] >= first[j]))) { 2150 printf("Warning: partition % doverlaps "2151 "partition % d\n", j + 1, i + 1);2274 printf("Warning: partition %u overlaps " 2275 "partition %u\n", j + 1, i + 1); 2152 2276 total += first[i] >= first[j] ? 2153 2277 first[i] : first[j]; … … 2161 2285 if (extended_offset) { 2162 2286 struct pte *pex = &ptes[ext_index]; 2163 ullonge_last = get_start_sect(pex->part_table) +2287 sector_t e_last = get_start_sect(pex->part_table) + 2164 2288 get_nr_sects(pex->part_table) - 1; 2165 2289 2166 for (i = 4; i < partitions; i++) {2290 for (i = 4; i < g_partitions; i++) { 2167 2291 total++; 2168 2292 p = ptes[i].part_table; 2169 2293 if (!p->sys_ind) { 2170 if (i != 4 || i + 1 < partitions)2171 printf("Warning: partition % d"2294 if (i != 4 || i + 1 < g_partitions) 2295 printf("Warning: partition %u " 2172 2296 "is empty\n", i + 1); 2173 2297 } else if (first[i] < extended_offset || last[i] > e_last) { 2174 printf("Logical partition % dnot entirely in "2175 "partition % d\n", i + 1, ext_index + 1);2298 printf("Logical partition %u not entirely in " 2299 "partition %u\n", i + 1, ext_index + 1); 2176 2300 } 2177 2301 } 2178 2302 } 2179 2303 2180 if (total > heads * sectors *cylinders)2181 printf("Total allocated sectors % dgreater than the maximum "2182 "% d\n", total, heads * sectors *cylinders);2304 if (total > g_heads * g_sectors * g_cylinders) 2305 printf("Total allocated sectors %u greater than the maximum " 2306 "%u\n", total, g_heads * g_sectors * g_cylinders); 2183 2307 else { 2184 total = heads * sectors *cylinders - total;2308 total = g_heads * g_sectors * g_cylinders - total; 2185 2309 if (total != 0) 2186 printf("% dunallocated sectors\n", total);2310 printf("%"SECT_FMT"u unallocated sectors\n", total); 2187 2311 } 2188 2312 } … … 2195 2319 struct partition *p = ptes[n].part_table; 2196 2320 struct partition *q = ptes[ext_index].part_table; 2197 ullonglimit, temp;2198 ullongstart, stop = 0;2199 ullong first[partitions], last[partitions];2321 sector_t limit, temp; 2322 sector_t start, stop = 0; 2323 sector_t first[g_partitions], last[g_partitions]; 2200 2324 2201 2325 if (p && p->sys_ind) { … … 2207 2331 start = sector_offset; 2208 2332 if (display_in_cyl_units || !total_number_of_sectors) 2209 limit = ( ullong) heads * sectors *cylinders - 1;2333 limit = (sector_t) g_heads * g_sectors * g_cylinders - 1; 2210 2334 else 2211 2335 limit = total_number_of_sectors - 1; … … 2220 2344 } 2221 2345 if (display_in_cyl_units) 2222 for (i = 0; i < partitions; i++)2346 for (i = 0; i < g_partitions; i++) 2223 2347 first[i] = (cround(first[i]) - 1) * units_per_sector; 2224 2348 … … 2226 2350 do { 2227 2351 temp = start; 2228 for (i = 0; i < partitions; i++) {2352 for (i = 0; i < g_partitions; i++) { 2229 2353 int lastplusoff; 2230 2354 2231 if (start == ptes[i].offset )2355 if (start == ptes[i].offset_from_dev_start) 2232 2356 start += sector_offset; 2233 2357 lastplusoff = last[i] + ((n < 4) ? 0 : sector_offset); … … 2238 2362 break; 2239 2363 if (start >= temp+units_per_sector && num_read) { 2240 printf("Sector % lldis already allocated\n", temp);2364 printf("Sector %"SECT_FMT"u is already allocated\n", temp); 2241 2365 temp = start; 2242 2366 num_read = 0; 2243 2367 } 2244 2368 if (!num_read && start == temp) { 2245 ullongsaved_start;2369 sector_t saved_start; 2246 2370 2247 2371 saved_start = start; 2248 start = read_int(cround(saved_start), cround(saved_start), cround(limit), 2249 0, mesg); 2372 start = read_int(cround(saved_start), cround(saved_start), cround(limit), 0, mesg); 2250 2373 if (display_in_cyl_units) { 2251 2374 start = (start - 1) * units_per_sector; 2252 if (start < saved_start) start = saved_start; 2375 if (start < saved_start) 2376 start = saved_start; 2253 2377 } 2254 2378 num_read = 1; … … 2258 2382 struct pte *pe = &ptes[n]; 2259 2383 2260 pe->offset = start - sector_offset;2261 if (pe->offset == extended_offset) { /* must be corrected */2262 pe->offset ++;2384 pe->offset_from_dev_start = start - sector_offset; 2385 if (pe->offset_from_dev_start == extended_offset) { /* must be corrected */ 2386 pe->offset_from_dev_start++; 2263 2387 if (sector_offset == 1) 2264 2388 start++; … … 2266 2390 } 2267 2391 2268 for (i = 0; i < partitions; i++) {2392 for (i = 0; i < g_partitions; i++) { 2269 2393 struct pte *pe = &ptes[i]; 2270 2394 2271 if (start < pe->offset && limit >= pe->offset)2272 limit = pe->offset - 1;2395 if (start < pe->offset_from_dev_start && limit >= pe->offset_from_dev_start) 2396 limit = pe->offset_from_dev_start - 1; 2273 2397 if (start < first[i] && limit >= first[i]) 2274 2398 limit = first[i] - 1; … … 2277 2401 printf("No free sectors available\n"); 2278 2402 if (n > 4) 2279 partitions--;2403 g_partitions--; 2280 2404 return; 2281 2405 } … … 2286 2410 "Last %s or +size or +sizeM or +sizeK", 2287 2411 str_units(SINGULAR)); 2288 stop = read_int(cround(start), cround(limit), cround(limit), 2289 cround(start), mesg); 2412 stop = read_int(cround(start), cround(limit), cround(limit), cround(start), mesg); 2290 2413 if (display_in_cyl_units) { 2291 2414 stop = stop * units_per_sector - 1; … … 2297 2420 set_partition(n, 0, start, stop, sys); 2298 2421 if (n > 4) 2299 set_partition(n - 1, 1, ptes[n].offset , stop, EXTENDED);2422 set_partition(n - 1, 1, ptes[n].offset_from_dev_start, stop, EXTENDED); 2300 2423 2301 2424 if (IS_EXTENDED(sys)) { … … 2305 2428 ext_index = n; 2306 2429 pen->ext_pointer = p; 2307 pe4->offset = extended_offset = start;2430 pe4->offset_from_dev_start = extended_offset = start; 2308 2431 pe4->sectorbuffer = xzalloc(sector_size); 2309 2432 pe4->part_table = pt_offset(pe4->sectorbuffer, 0); 2310 2433 pe4->ext_pointer = pe4->part_table + 1; 2311 2434 pe4->changed = 1; 2312 partitions = 5;2435 g_partitions = 5; 2313 2436 } 2314 2437 } … … 2317 2440 add_logical(void) 2318 2441 { 2319 if ( partitions > 5 || ptes[4].part_table->sys_ind) {2320 struct pte *pe = &ptes[ partitions];2442 if (g_partitions > 5 || ptes[4].part_table->sys_ind) { 2443 struct pte *pe = &ptes[g_partitions]; 2321 2444 2322 2445 pe->sectorbuffer = xzalloc(sector_size); 2323 2446 pe->part_table = pt_offset(pe->sectorbuffer, 0); 2324 2447 pe->ext_pointer = pe->part_table + 1; 2325 pe->offset = 0;2448 pe->offset_from_dev_start = 0; 2326 2449 pe->changed = 1; 2327 partitions++;2328 } 2329 add_partition( partitions - 1, LINUX_NATIVE);2450 g_partitions++; 2451 } 2452 add_partition(g_partitions - 1, LINUX_NATIVE); 2330 2453 } 2331 2454 … … 2339 2462 2340 2463 if (LABEL_IS_SUN) { 2341 add_sun_partition(get_partition(0, partitions), LINUX_NATIVE);2464 add_sun_partition(get_partition(0, g_partitions), LINUX_NATIVE); 2342 2465 return; 2343 2466 } 2344 2467 if (LABEL_IS_SGI) { 2345 sgi_add_partition(get_partition(0, partitions), LINUX_NATIVE);2468 sgi_add_partition(get_partition(0, g_partitions), LINUX_NATIVE); 2346 2469 return; 2347 2470 } … … 2356 2479 free_primary += !ptes[i].part_table->sys_ind; 2357 2480 2358 if (!free_primary && partitions >= MAXIMUM_PARTS) {2481 if (!free_primary && g_partitions >= MAXIMUM_PARTS) { 2359 2482 printf("The maximum number of partitions has been created\n"); 2360 2483 return; … … 2377 2500 while (1) { 2378 2501 c = read_nonempty(line); 2379 if ( c == 'p' || c == 'P') {2502 if ((c | 0x20) == 'p') { 2380 2503 i = get_nonexisting_partition(0, 4); 2381 2504 if (i >= 0) … … 2408 2531 if (ptes[i].changed) 2409 2532 ptes[3].changed = 1; 2410 for (i = 3; i < partitions; i++) {2533 for (i = 3; i < g_partitions; i++) { 2411 2534 struct pte *pe = &ptes[i]; 2412 2535 2413 2536 if (pe->changed) { 2414 2537 write_part_table_flag(pe->sectorbuffer); 2415 write_sector(pe->offset , pe->sectorbuffer);2538 write_sector(pe->offset_from_dev_start, pe->sectorbuffer); 2416 2539 } 2417 2540 } … … 2443 2566 sync(); 2444 2567 /* sleep(2); Huh? */ 2445 i = ioctl_or_perror( fd, BLKRRPART, NULL,2568 i = ioctl_or_perror(dev_fd, BLKRRPART, NULL, 2446 2569 "WARNING: rereading partition table " 2447 2570 "failed, kernel still uses old table"); … … 2456 2579 if (leave) { 2457 2580 if (ENABLE_FEATURE_CLEAN_UP) 2458 close (fd);2581 close_dev_fd(); 2459 2582 exit(i != 0); 2460 2583 } … … 2474 2597 printf(" %02X", (unsigned char) pbuffer[i]); 2475 2598 if (l == MAX_PER_LINE - 1) { 2476 puts("");2599 bb_putchar('\n'); 2477 2600 l = -1; 2478 2601 } 2479 2602 } 2480 2603 if (l > 0) 2481 puts("");2482 puts("");2604 bb_putchar('\n'); 2605 bb_putchar('\n'); 2483 2606 } 2484 2607 … … 2492 2615 print_buffer(MBRbuffer); 2493 2616 else { 2494 for (i = 3; i < partitions; i++)2617 for (i = 3; i < g_partitions; i++) 2495 2618 print_buffer(ptes[i].sectorbuffer); 2496 2619 } … … 2498 2621 2499 2622 static void 2500 move_begin( inti)2623 move_begin(unsigned i) 2501 2624 { 2502 2625 struct pte *pe = &ptes[i]; 2503 2626 struct partition *p = pe->part_table; 2504 ullong new, first;2627 sector_t new, first, nr_sects; 2505 2628 2506 2629 if (warn_geometry()) 2507 2630 return; 2508 if (!p->sys_ind || !get_nr_sects(p) || IS_EXTENDED(p->sys_ind)) { 2509 printf("Partition %d has no data area\n", i + 1); 2631 nr_sects = get_nr_sects(p); 2632 if (!p->sys_ind || !nr_sects || IS_EXTENDED(p->sys_ind)) { 2633 printf("Partition %u has no data area\n", i + 1); 2510 2634 return; 2511 2635 } 2512 first = get_partition_start(pe); 2513 new = read_int(first, first, first + get_nr_sects(p) - 1, first, 2514 "New beginning of data") - pe->offset; 2515 2516 if (new != get_nr_sects(p)) { 2517 first = get_nr_sects(p) + get_start_sect(p) - new; 2518 set_nr_sects(p, first); 2519 set_start_sect(p, new); 2636 first = get_partition_start_from_dev_start(pe); /* == pe->offset_from_dev_start + get_start_sect(p) */ 2637 new = read_int(0 /*was:first*/, first, first + nr_sects - 1, first, "New beginning of data"); 2638 if (new != first) { 2639 sector_t new_relative = new - pe->offset_from_dev_start; 2640 nr_sects += (get_start_sect(p) - new_relative); 2641 set_start_sect(p, new_relative); 2642 set_nr_sects(p, nr_sects); 2643 read_nonempty("Recalculate C/H/S values? (Y/N): "); 2644 if ((line_ptr[0] | 0x20) == 'y') 2645 set_hsc_start_end(p, new, new + nr_sects - 1); 2520 2646 pe->changed = 1; 2521 2647 } … … 2528 2654 2529 2655 while (1) { 2530 putchar('\n');2531 c = tolower(read_nonempty("Expert command (m for help): "));2656 bb_putchar('\n'); 2657 c = 0x20 | read_nonempty("Expert command (m for help): "); 2532 2658 switch (c) { 2533 2659 case 'a': … … 2537 2663 case 'b': 2538 2664 if (LABEL_IS_DOS) 2539 move_begin(get_partition(0, partitions));2665 move_begin(get_partition(0, g_partitions)); 2540 2666 break; 2541 2667 case 'c': 2542 user_cylinders = cylinders =2543 read_int(1, cylinders, 1048576, 0,2668 user_cylinders = g_cylinders = 2669 read_int(1, g_cylinders, 1048576, 0, 2544 2670 "Number of cylinders"); 2545 2671 if (LABEL_IS_SUN) 2546 sun_set_ncyl( cylinders);2672 sun_set_ncyl(g_cylinders); 2547 2673 if (LABEL_IS_DOS) 2548 2674 warn_cylinders(); … … 2569 2695 break; 2570 2696 case 'h': 2571 user_heads = heads = read_int(1, heads, 256, 0, 2572 "Number of heads"); 2697 user_heads = g_heads = read_int(1, g_heads, 256, 0, "Number of heads"); 2573 2698 update_units(); 2574 2699 break; … … 2588 2713 break; 2589 2714 case 'q': 2590 close(fd); 2591 puts(""); 2592 exit(0); 2715 if (ENABLE_FEATURE_CLEAN_UP) 2716 close_dev_fd(); 2717 bb_putchar('\n'); 2718 exit(EXIT_SUCCESS); 2593 2719 case 'r': 2594 2720 return; 2595 2721 case 's': 2596 user_sectors = sectors = read_int(1, sectors, 63, 0, 2597 "Number of sectors"); 2722 user_sectors = g_sectors = read_int(1, g_sectors, 63, 0, "Number of sectors"); 2598 2723 if (dos_compatible_flag) { 2599 sector_offset = sectors;2724 sector_offset = g_sectors; 2600 2725 printf("Warning: setting sector offset for DOS " 2601 2726 "compatiblity\n"); … … 2639 2764 2640 2765 snprintf(buf, sizeof(buf), "/proc/ide/%s/media", device+5); 2641 procf = fopen (buf, "r");2766 procf = fopen_for_read(buf); 2642 2767 if (procf != NULL && fgets(buf, sizeof(buf), procf)) 2643 2768 is_ide = (!strncmp(buf, "cdrom", 5) || … … 2656 2781 2657 2782 static void 2658 trydev(const char *device, int user_specified)2783 open_list_and_close(const char *device, int user_specified) 2659 2784 { 2660 2785 int gb; … … 2666 2791 if (is_ide_cdrom_or_tape(device)) 2667 2792 return; 2668 fd = open(disk_device, type_open); 2669 if (fd >= 0) { 2670 gb = get_boot(try_only); 2671 if (gb > 0) { /* I/O error */ 2672 close(fd); 2673 } else if (gb < 0) { /* no DOS signature */ 2674 list_disk_geometry(); 2675 if (LABEL_IS_AIX) { 2676 return; 2677 } 2678 #if ENABLE_FEATURE_OSF_LABEL 2679 if (bsd_trydev(device) < 0) 2680 #endif 2681 printf("Disk %s doesn't contain a valid " 2682 "partition table\n", device); 2683 close(fd); 2684 } else { 2685 close(fd); 2686 list_table(0); 2687 #if ENABLE_FEATURE_FDISK_WRITABLE 2688 if (!LABEL_IS_SUN && partitions > 4){ 2689 delete_partition(ext_index); 2690 } 2691 #endif 2692 } 2693 } else { 2793 2794 /* Open disk_device, save file descriptor to dev_fd */ 2795 errno = 0; 2796 gb = get_boot(TRY_ONLY); 2797 if (gb > 0) { /* I/O error */ 2694 2798 /* Ignore other errors, since we try IDE 2695 2799 and SCSI hard disks which may not be 2696 2800 installed on the system. */ 2697 if (errno == EACCES) { 2698 printf("Cannot open %s\n", device); 2699 return; 2700 } 2701 } 2801 if (user_specified || errno == EACCES) 2802 bb_perror_msg("can't open '%s'", device); 2803 return; 2804 } 2805 2806 if (gb < 0) { /* no DOS signature */ 2807 list_disk_geometry(); 2808 if (LABEL_IS_AIX) 2809 goto ret; 2810 #if ENABLE_FEATURE_OSF_LABEL 2811 if (bsd_trydev(device) < 0) 2812 #endif 2813 printf("Disk %s doesn't contain a valid " 2814 "partition table\n", device); 2815 } else { 2816 list_table(0); 2817 #if ENABLE_FEATURE_FDISK_WRITABLE 2818 if (!LABEL_IS_SUN && g_partitions > 4) { 2819 delete_partition(ext_index); 2820 } 2821 #endif 2822 } 2823 ret: 2824 close_dev_fd(); 2702 2825 } 2703 2826 … … 2705 2828 that look like a partition name (do not end in a digit) */ 2706 2829 static void 2707 tryprocpt(void)2830 list_devs_in_proc_partititons(void) 2708 2831 { 2709 2832 FILE *procpt; … … 2714 2837 2715 2838 while (fgets(line, sizeof(line), procpt)) { 2716 if (sscanf(line, " % d %d %d%[^\n ]",2839 if (sscanf(line, " %u %u %u %[^\n ]", 2717 2840 &ma, &mi, &sz, ptname) != 4) 2718 2841 continue; 2719 for (s = ptname; *s; s++); 2720 if (isdigit(s[-1])) 2842 for (s = ptname; *s; s++) 2843 continue; 2844 /* note: excluding '0': e.g. mmcblk0 is not a partition name! */ 2845 if (s[-1] >= '1' && s[-1] <= '9') 2721 2846 continue; 2722 2847 sprintf(devname, "/dev/%s", ptname); 2723 trydev(devname, 0);2848 open_list_and_close(devname, 0); 2724 2849 } 2725 2850 #if ENABLE_FEATURE_CLEAN_UP … … 2736 2861 #endif 2737 2862 2738 int fdisk_main(int argc, char **argv); 2739 int fdisk_main(int argc, char **argv) 2740 { 2741 char *str_b, *str_C, *str_H, *str_S; 2863 int fdisk_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 2864 int fdisk_main(int argc UNUSED_PARAM, char **argv) 2865 { 2742 2866 unsigned opt; 2743 2867 /* … … 2749 2873 * Options -C, -H, -S set the geometry. 2750 2874 */ 2751 enum { 2752 OPT_b = 1 << 0, 2753 OPT_C = 1 << 1, 2754 OPT_H = 1 << 2, 2755 OPT_l = 1 << 3, 2756 OPT_S = 1 << 4, 2757 OPT_u = 1 << 5, 2758 OPT_s = (1 << 6) * ENABLE_FEATURE_FDISK_BLKSIZE, 2759 }; 2760 2761 PTR_TO_GLOBALS = xzalloc(sizeof(G)); 2762 2763 opt = getopt32(argv, "b:C:H:lS:u" USE_FEATURE_FDISK_BLKSIZE("s"), 2764 &str_b, &str_C, &str_H, &str_S); 2765 argc -= optind; 2875 INIT_G(); 2876 2877 close_dev_fd(); /* needed: fd 3 must not stay closed */ 2878 2879 opt_complementary = "b+:C+:H+:S+"; /* numeric params */ 2880 opt = getopt32(argv, "b:C:H:lS:u" IF_FEATURE_FDISK_BLKSIZE("s"), 2881 §or_size, &user_cylinders, &user_heads, &user_sectors); 2766 2882 argv += optind; 2767 if (opt & OPT_b) { // -b2883 if (opt & OPT_b) { 2768 2884 /* Ugly: this sector size is really per device, 2769 so cannot be combined with multiple disks, 2770 and the same goes for the C/H/S options. 2771 */ 2772 sector_size = xatoi_u(str_b); 2773 if (sector_size != 512 && sector_size != 1024 && 2774 sector_size != 2048) 2885 * so cannot be combined with multiple disks, 2886 * and the same goes for the C/H/S options. 2887 */ 2888 if (sector_size < 512 2889 || sector_size > 0x10000 2890 || (sector_size & (sector_size-1)) /* not power of 2 */ 2891 ) { 2775 2892 bb_show_usage(); 2893 } 2776 2894 sector_offset = 2; 2777 2895 user_set_sector_size = 1; 2778 2896 } 2779 if (opt & OPT_C) user_cylinders = xatoi_u(str_C); // -C 2780 if (opt & OPT_H) { // -H 2781 user_heads = xatoi_u(str_H); 2782 if (user_heads <= 0 || user_heads >= 256) 2783 user_heads = 0; 2784 } 2785 //if (opt & OPT_l) // -l 2786 if (opt & OPT_S) { // -S 2787 user_sectors = xatoi_u(str_S); 2788 if (user_sectors <= 0 || user_sectors >= 64) 2789 user_sectors = 0; 2790 } 2791 if (opt & OPT_u) display_in_cyl_units = 0; // -u 2792 //if (opt & OPT_s) // -s 2793 2794 if (user_set_sector_size && argc != 1) 2795 printf("Warning: the -b (set sector size) option should" 2796 " be used with one specified device\n"); 2897 if (user_heads <= 0 || user_heads >= 256) 2898 user_heads = 0; 2899 if (user_sectors <= 0 || user_sectors >= 64) 2900 user_sectors = 0; 2901 if (opt & OPT_u) 2902 display_in_cyl_units = 0; // -u 2797 2903 2798 2904 #if ENABLE_FEATURE_FDISK_WRITABLE … … 2800 2906 nowarn = 1; 2801 2907 #endif 2802 type_open = O_RDONLY; 2803 if (argc > 0) { 2804 int k; 2805 #if defined(__GNUC__) 2806 /* avoid gcc warning: 2807 variable `k' might be clobbered by `longjmp' */ 2808 (void)&k; 2809 #endif 2908 if (*argv) { 2810 2909 listing = 1; 2811 for (k = 0; k < argc; k++) 2812 trydev(argv[k], 1); 2910 do { 2911 open_list_and_close(*argv, 1); 2912 } while (*++argv); 2813 2913 } else { 2814 /* we no longer have default device names*/2815 /* but, we canuse /proc/partitions instead */2816 tryprocpt();2914 /* we don't have device names, */ 2915 /* use /proc/partitions instead */ 2916 list_devs_in_proc_partititons(); 2817 2917 } 2818 2918 return 0; … … 2823 2923 #if ENABLE_FEATURE_FDISK_BLKSIZE 2824 2924 if (opt & OPT_s) { 2825 long size;2826 2925 int j; 2827 2926 2828 2927 nowarn = 1; 2829 type_open = O_RDONLY; 2830 2831 if (argc <= 0) 2928 if (!argv[0]) 2832 2929 bb_show_usage(); 2833 2834 for (j = 0; j < argc; j++) { 2835 disk_device = argv[j]; 2836 fd = open(disk_device, type_open); 2837 if (fd < 0) 2838 fdisk_fatal(unable_to_open); 2839 if (ioctl(fd, BLKGETSIZE, &size)) 2840 fdisk_fatal(ioctl_error); 2930 for (j = 0; argv[j]; j++) { 2931 unsigned long long size; 2932 fd = xopen(argv[j], O_RDONLY); 2933 size = bb_BLKGETSIZE_sectors(fd) / 2; 2841 2934 close(fd); 2842 if (arg c == 1)2843 printf("%l d\n", size/2);2935 if (argv[1]) 2936 printf("%llu\n", size); 2844 2937 else 2845 printf("%s: %l d\n", argv[j], size/2);2938 printf("%s: %llu\n", argv[j], size); 2846 2939 } 2847 2940 return 0; … … 2850 2943 2851 2944 #if ENABLE_FEATURE_FDISK_WRITABLE 2852 if ( argc != 1)2945 if (!argv[0] || argv[1]) 2853 2946 bb_show_usage(); 2854 2947 2855 2948 disk_device = argv[0]; 2856 get_boot( fdisk);2949 get_boot(OPEN_MAIN); 2857 2950 2858 2951 if (LABEL_IS_OSF) { … … 2862 2955 bsd_select(); 2863 2956 /*Why do we do this? It seems to be counter-intuitive*/ 2864 current_label_type = label_dos;2957 current_label_type = LABEL_DOS; 2865 2958 /* If we return we may want to make an empty DOS label? */ 2866 2959 } … … 2868 2961 while (1) { 2869 2962 int c; 2870 putchar('\n');2871 c = tolower(read_nonempty("Command (m for help): "));2963 bb_putchar('\n'); 2964 c = 0x20 | read_nonempty("Command (m for help): "); 2872 2965 switch (c) { 2873 2966 case 'a': 2874 2967 if (LABEL_IS_DOS) 2875 toggle_active(get_partition(1, partitions));2968 toggle_active(get_partition(1, g_partitions)); 2876 2969 else if (LABEL_IS_SUN) 2877 toggle_sunflags(get_partition(1, partitions),2970 toggle_sunflags(get_partition(1, g_partitions), 2878 2971 0x01); 2879 2972 else if (LABEL_IS_SGI) 2880 2973 sgi_set_bootpartition( 2881 get_partition(1, partitions));2974 get_partition(1, g_partitions)); 2882 2975 else 2883 2976 unknown_command(c); … … 2902 2995 toggle_dos_compatibility_flag(); 2903 2996 else if (LABEL_IS_SUN) 2904 toggle_sunflags(get_partition(1, partitions),2997 toggle_sunflags(get_partition(1, g_partitions), 2905 2998 0x10); 2906 2999 else if (LABEL_IS_SGI) 2907 3000 sgi_set_swappartition( 2908 get_partition(1, partitions));3001 get_partition(1, g_partitions)); 2909 3002 else 2910 3003 unknown_command(c); … … 2918 3011 partition tables */ 2919 3012 if (!LABEL_IS_SGI) { 2920 j = get_existing_partition(1, partitions);3013 j = get_existing_partition(1, g_partitions); 2921 3014 } else { 2922 j = get_partition(1, partitions);3015 j = get_partition(1, g_partitions); 2923 3016 } 2924 3017 if (j >= 0) … … 2947 3040 break; 2948 3041 case 'q': 2949 close(fd); 2950 puts(""); 3042 if (ENABLE_FEATURE_CLEAN_UP) 3043 close_dev_fd(); 3044 bb_putchar('\n'); 2951 3045 return 0; 2952 3046 case 's': -
branches/2.2.9/mindi-busybox/util-linux/fdisk_aix.c
r1765 r2725 2 2 /* 3 3 * Copyright (C) Andreas Neuper, Sep 1998. 4 * This file may be redistributed under5 * the terms of the GNU Public License.4 * 5 * Licensed under GPLv2, see file LICENSE in this source tree. 6 6 */ 7 7 … … 30 30 */ 31 31 32 static int aix_other_endian;33 static s hort aix_volumes = 1;32 static smallint aix_other_endian; /* bool */ 33 static smallint aix_volumes = 1; /* max 15 */ 34 34 35 35 /* … … 55 55 check_aix_label(void) 56 56 { 57 if (aixlabel->magic != AIX_LABEL_MAGIC && 58 aixlabel->magic != AIX_LABEL_MAGIC_SWAPPED) { 57 if (aixlabel->magic != AIX_LABEL_MAGIC 58 && aixlabel->magic != AIX_LABEL_MAGIC_SWAPPED 59 ) { 59 60 current_label_type = 0; 60 61 aix_other_endian = 0; … … 63 64 aix_other_endian = (aixlabel->magic == AIX_LABEL_MAGIC_SWAPPED); 64 65 update_units(); 65 current_label_type = label_aix;66 partitions = 1016;66 current_label_type = LABEL_AIX; 67 g_partitions = 1016; 67 68 aix_volumes = 15; 68 69 aix_info(); -
branches/2.2.9/mindi-busybox/util-linux/fdisk_osf.c
r1765 r2725 1 #if ENABLE_FEATURE_OSF_LABEL2 1 /* 3 2 * Copyright (c) 1987, 1988 Regents of the University of California. … … 33 32 */ 34 33 34 #if ENABLE_FEATURE_OSF_LABEL 35 35 36 36 #ifndef BSD_DISKMAGIC … … 46 46 #if defined(i386) || defined(__sparc__) || defined(__arm__) \ 47 47 || defined(__m68k__) || defined(__mips__) || defined(__s390__) \ 48 || defined(__sh__) || defined(__x86_64__) 49 #define BSD_LABELSECTOR 1 50 #define BSD_LABELOFFSET 0 48 || defined(__s390__) || defined(__s390x__) \ 49 || defined(__sh__) || defined(__x86_64__) || defined(__avr32__) \ 50 || defined(__nds32__) 51 # define BSD_LABELSECTOR 1 52 # define BSD_LABELOFFSET 0 51 53 #elif defined(__alpha__) || defined(__powerpc__) || defined(__ia64__) \ 52 54 || defined(__hppa__) 53 #define BSD_LABELSECTOR 0 54 #define BSD_LABELOFFSET 64 55 #elif defined(__s390__) || defined(__s390x__) 56 #define BSD_LABELSECTOR 1 57 #define BSD_LABELOFFSET 0 58 #else 59 #error unknown architecture 55 # define BSD_LABELSECTOR 0 56 # define BSD_LABELOFFSET 64 57 #else 58 # error unknown architecture 60 59 #endif 61 60 … … 68 67 int16_t d_subtype; /* controller/d_type specific */ 69 68 char d_typename[16]; /* type name, e.g. "eagle" */ 70 char d_packname[16]; 71 69 char d_packname[16]; /* pack identifier */ 70 /* disk geometry: */ 72 71 uint32_t d_secsize; /* # of bytes per sector */ 73 72 uint32_t d_nsectors; /* # of data sectors per track */ … … 90 89 uint32_t d_acylinders; /* # of alt. cylinders per unit */ 91 90 92 91 /* hardware characteristics: */ 93 92 /* 94 93 * d_interleave, d_trackskew and d_cylskew describe perturbations … … 120 119 uint32_t d_magic2; /* the magic number (again) */ 121 120 uint16_t d_checksum; /* xor of data incl. partitions */ 122 121 /* filesystem and partition information: */ 123 122 uint16_t d_npartitions; /* number of partitions in following */ 124 123 uint32_t d_bbsize; /* size of boot area at sn0, bytes */ 125 124 uint32_t d_sbsize; /* max size of fs superblock, bytes */ 126 struct xbsd_partition {/* the partition table */125 struct xbsd_partition { /* the partition table */ 127 126 uint32_t p_size; /* number of sectors in partition */ 128 127 uint32_t p_offset; /* starting sector */ … … 241 240 */ 242 241 243 static int possibly_osf_label;244 245 242 #define FREEBSD_PARTITION 0xa5 246 243 #define NETBSD_PARTITION 0xa9 … … 372 369 return; 373 370 } 374 printf("Reading disklabel of %s at sector % d\n",371 printf("Reading disklabel of %s at sector %u\n", 375 372 partname(disk_device, t+1, 0), ss + BSD_LABELSECTOR); 376 373 if (xbsd_readlabel(xbsd_part) == 0) … … 395 392 396 393 while (1) { 397 putchar('\n');394 bb_putchar('\n'); 398 395 switch (tolower(read_nonempty("BSD disklabel command (m for help): "))) { 399 396 case 'd': … … 416 413 break; 417 414 case 'q': 418 close(fd); 415 if (ENABLE_FEATURE_CLEAN_UP) 416 close_dev_fd(); 419 417 exit(EXIT_SUCCESS); 420 418 case 'r': … … 504 502 505 503 if (show_all) { 504 static const int d_masks[] = { BSD_D_REMOVABLE, BSD_D_ECC, BSD_D_BADSECT }; 505 506 506 #if defined(__alpha__) 507 507 printf("# %s:\n", disk_device); … … 512 512 printf("type: %s\n", xbsd_dktypenames[lp->d_type]); 513 513 else 514 printf("type: % d\n", lp->d_type);514 printf("type: %u\n", lp->d_type); 515 515 printf("disk: %.*s\n", (int) sizeof(lp->d_typename), lp->d_typename); 516 516 printf("label: %.*s\n", (int) sizeof(lp->d_packname), lp->d_packname); 517 printf("flags:"); 518 if (lp->d_flags & BSD_D_REMOVABLE) 519 printf(" removable"); 520 if (lp->d_flags & BSD_D_ECC) 521 printf(" ecc"); 522 if (lp->d_flags & BSD_D_BADSECT) 523 printf(" badsect"); 524 puts(""); 517 printf("flags: "); 518 print_flags_separated(d_masks, "removable\0""ecc\0""badsect\0", lp->d_flags, " "); 519 bb_putchar('\n'); 525 520 /* On various machines the fields of *lp are short/int/long */ 526 521 /* In order to avoid problems, we cast them all to long. */ 527 printf("bytes/sector: %l d\n", (long) lp->d_secsize);528 printf("sectors/track: %l d\n", (long) lp->d_nsectors);529 printf("tracks/cylinder: %l d\n", (long) lp->d_ntracks);530 printf("sectors/cylinder: %l d\n", (long) lp->d_secpercyl);531 printf("cylinders: %l d\n", (long) lp->d_ncylinders);532 printf("rpm: % d\n", lp->d_rpm);533 printf("interleave: % d\n", lp->d_interleave);534 printf("trackskew: % d\n", lp->d_trackskew);535 printf("cylinderskew: % d\n", lp->d_cylskew);536 printf("headswitch: %l d\t\t# milliseconds\n",522 printf("bytes/sector: %lu\n", (long) lp->d_secsize); 523 printf("sectors/track: %lu\n", (long) lp->d_nsectors); 524 printf("tracks/cylinder: %lu\n", (long) lp->d_ntracks); 525 printf("sectors/cylinder: %lu\n", (long) lp->d_secpercyl); 526 printf("cylinders: %lu\n", (long) lp->d_ncylinders); 527 printf("rpm: %u\n", lp->d_rpm); 528 printf("interleave: %u\n", lp->d_interleave); 529 printf("trackskew: %u\n", lp->d_trackskew); 530 printf("cylinderskew: %u\n", lp->d_cylskew); 531 printf("headswitch: %lu\t\t# milliseconds\n", 537 532 (long) lp->d_headswitch); 538 printf("track-to-track seek: %l d\t# milliseconds\n",533 printf("track-to-track seek: %lu\t# milliseconds\n", 539 534 (long) lp->d_trkseek); 540 535 printf("drivedata: "); … … 545 540 i = 0; 546 541 for (j = 0; j <= i; j++) 547 printf("%l d", (long) lp->d_drivedata[j]);548 } 549 printf("\n% dpartitions:\n", lp->d_npartitions);542 printf("%lu ", (long) lp->d_drivedata[j]); 543 } 544 printf("\n%u partitions:\n", lp->d_npartitions); 550 545 printf("# start end size fstype [fsize bsize cpg]\n"); 551 546 pp = lp->d_partitions; … … 553 548 if (pp->p_size) { 554 549 if (display_in_cyl_units && lp->d_secpercyl) { 555 printf(" %c: %8l d%c %8ld%c %8ld%c ",550 printf(" %c: %8lu%c %8lu%c %8lu%c ", 556 551 'a' + i, 557 ( long) pp->p_offset / lp->d_secpercyl + 1,552 (unsigned long) pp->p_offset / lp->d_secpercyl + 1, 558 553 (pp->p_offset % lp->d_secpercyl) ? '*' : ' ', 559 ( long) (pp->p_offset + pp->p_size + lp->d_secpercyl - 1) / lp->d_secpercyl,554 (unsigned long) (pp->p_offset + pp->p_size + lp->d_secpercyl - 1) / lp->d_secpercyl, 560 555 ((pp->p_offset + pp->p_size) % lp->d_secpercyl) ? '*' : ' ', 561 556 (long) pp->p_size / lp->d_secpercyl, … … 563 558 ); 564 559 } else { 565 printf(" %c: %8l d %8ld %8ld",560 printf(" %c: %8lu %8lu %8lu ", 566 561 'a' + i, 567 562 (long) pp->p_offset, … … 578 573 switch (pp->p_fstype) { 579 574 case BSD_FS_UNUSED: 580 printf(" %5l d %5ld%5.5s ",575 printf(" %5lu %5lu %5.5s ", 581 576 (long) pp->p_fsize, (long) pp->p_fsize * pp->p_frag, ""); 582 577 break; 583 578 case BSD_FS_BSDFFS: 584 printf(" %5l d %5ld %5d",579 printf(" %5lu %5lu %5u ", 585 580 (long) pp->p_fsize, (long) pp->p_fsize * pp->p_frag, pp->p_cpg); 586 581 break; … … 589 584 break; 590 585 } 591 puts("");586 bb_putchar('\n'); 592 587 } 593 588 } … … 622 617 while (1) { 623 618 c = read_nonempty("Do you want to create a disklabel? (y/n) "); 624 if ( c == 'y' || c == 'Y') {619 if ((c|0x20) == 'y') { 625 620 if (xbsd_initlabel( 626 621 #if defined(__alpha__) || defined(__powerpc__) || defined(__hppa__) || \ … … 630 625 xbsd_part 631 626 #endif 632 627 ) == 1) { 633 628 xbsd_print_disklabel(1); 634 629 return 1; 635 } else 636 return 0; 637 } else if (c == 'n') 630 } 638 631 return 0; 632 } 633 if ((c|0x20) == 'n') 634 return 0; 639 635 } 640 636 } … … 643 639 edit_int(int def, const char *mesg) 644 640 { 645 mesg = xasprintf("%s (% d): ", mesg, def);641 mesg = xasprintf("%s (%u): ", mesg, def); 646 642 do { 647 643 if (!read_line(mesg)) … … 692 688 int fdb; 693 689 694 fdb = open (path, O_RDONLY);690 fdb = open_or_warn(path, O_RDONLY); 695 691 if (fdb < 0) { 696 perror(path);697 692 return 0; 698 693 } 699 if ( read(fdb, ptr, size) < 0) {700 perror(path);694 if (full_read(fdb, ptr, size) < 0) { 695 bb_simple_perror_msg(path); 701 696 close(fdb); 702 697 return 0; … … 769 764 #endif 770 765 771 if (lseek(fd, sector * SECTOR_SIZE, SEEK_SET) == -1) 772 fdisk_fatal(unable_to_seek); 773 if (BSD_BBSIZE != write(fd, disklabelbuffer, BSD_BBSIZE)) 774 fdisk_fatal(unable_to_write); 766 seek_sector(sector); 767 xwrite(dev_fd, disklabelbuffer, BSD_BBSIZE); 775 768 776 769 #if defined(__alpha__) … … 877 870 #endif 878 871 d->d_secsize = SECTOR_SIZE; /* bytes/sector */ 879 d->d_nsectors = sectors;/* sectors/track */880 d->d_ntracks = heads;/* tracks/cylinder (heads) */881 d->d_ncylinders = cylinders;882 d->d_secpercyl = sectors * heads;/* sectors/cylinder */872 d->d_nsectors = g_sectors; /* sectors/track */ 873 d->d_ntracks = g_heads; /* tracks/cylinder (heads) */ 874 d->d_ncylinders = g_cylinders; 875 d->d_secpercyl = g_sectors * g_heads;/* sectors/cylinder */ 883 876 if (d->d_secpercyl == 0) 884 877 d->d_secpercyl = 1; /* avoid segfaults */ … … 942 935 #endif 943 936 944 if (lseek(fd, sector * SECTOR_SIZE, SEEK_SET) == -1) 945 fdisk_fatal(unable_to_seek); 946 if (BSD_BBSIZE != read(fd, disklabelbuffer, BSD_BBSIZE)) 937 seek_sector(sector); 938 if (BSD_BBSIZE != full_read(dev_fd, disklabelbuffer, BSD_BBSIZE)) 947 939 fdisk_fatal(unable_to_read); 948 940 … … 960 952 961 953 if (d->d_npartitions > BSD_MAXPARTITIONS) 962 printf("Warning: too many partitions (% d, maximum is %d)\n",954 printf("Warning: too many partitions (%u, maximum is %u)\n", 963 955 d->d_npartitions, BSD_MAXPARTITIONS); 964 956 return 1; … … 974 966 sector = get_start_sect(p) + BSD_LABELSECTOR; 975 967 #else 968 (void)p; /* silence warning */ 976 969 sector = BSD_LABELSECTOR; 977 970 #endif … … 988 981 #if defined(__alpha__) && BSD_LABELSECTOR == 0 989 982 alpha_bootblock_checksum(disklabelbuffer); 990 if (lseek(fd, 0, SEEK_SET) == -1) 991 fdisk_fatal(unable_to_seek); 992 if (BSD_BBSIZE != write(fd, disklabelbuffer, BSD_BBSIZE)) 993 fdisk_fatal(unable_to_write); 994 #else 995 if (lseek(fd, sector * SECTOR_SIZE + BSD_LABELOFFSET, SEEK_SET) == -1) 996 fdisk_fatal(unable_to_seek); 997 if (sizeof(struct xbsd_disklabel) != write(fd, d, sizeof(struct xbsd_disklabel))) 998 fdisk_fatal(unable_to_write); 983 seek_sector(0); 984 xwrite(dev_fd, disklabelbuffer, BSD_BBSIZE); 985 #else 986 seek_sector(sector); 987 lseek(dev_fd, BSD_LABELOFFSET, SEEK_CUR); 988 xwrite(dev_fd, d, sizeof(*d)); 999 989 #endif 1000 990 sync_disks(); … … 1028 1018 struct partition *p; 1029 1019 1030 k = get_partition(1, partitions);1020 k = get_partition(1, g_partitions); 1031 1021 1032 1022 if (!xbsd_check_new_partition(&i)) -
branches/2.2.9/mindi-busybox/util-linux/fdisk_sgi.c
r1765 r2725 1 #if ENABLE_FEATURE_SGI_LABEL2 3 1 /* 4 2 * Copyright (C) Andreas Neuper, Sep 1998. 5 * This file may be modified and redistributed under6 * the terms of the GNU Public License.3 * 4 * Licensed under GPLv2, see file LICENSE in this source tree. 7 5 */ 6 7 #if ENABLE_FEATURE_SGI_LABEL 8 9 #define SGI_DEBUG 0 8 10 9 11 #define SGI_VOLHDR 0x00 … … 35 37 unsigned short bytes; 36 38 unsigned short ilfact; 37 unsigned int flags; 39 unsigned int flags; /* controller flags */ 38 40 unsigned int datarate; 39 41 unsigned int retries_on_error; … … 69 71 unsigned int vol_file_size; /* number of bytes */ 70 72 } directory[15]; 71 struct sgi_partinfo { /* 16 * 12 bytes */73 struct sgi_partinfo { /* 16 * 12 bytes */ 72 74 unsigned int num_sectors; /* number of blocks */ 73 75 unsigned int start_sector; /* must be cylinder aligned */ … … 118 120 119 121 120 static int sgi_other_endian; 121 static int debug; 122 static short sgi_volumes = 1; 122 static smallint sgi_other_endian; /* bool */ 123 static smallint sgi_volumes = 1; /* max 15 */ 123 124 124 125 /* … … 235 236 && sgilabel->magic != SGI_LABEL_MAGIC_SWAPPED 236 237 ) { 237 current_label_type = label_dos;238 current_label_type = LABEL_DOS; 238 239 return 0; 239 240 } … … 248 249 } 249 250 update_units(); 250 current_label_type = label_sgi;251 partitions = 16;251 current_label_type = LABEL_SGI; 252 g_partitions = 16; 252 253 sgi_volumes = 15; 253 254 return 1; … … 291 292 292 293 if (xtra) { 293 printf("\nDisk %s (SGI disk label): % d heads, %dsectors\n"294 "% d cylinders, %dphysical cylinders\n"295 "% d extra sects/cyl, interleave %d:1\n"294 printf("\nDisk %s (SGI disk label): %u heads, %u sectors\n" 295 "%u cylinders, %u physical cylinders\n" 296 "%u extra sects/cyl, interleave %u:1\n" 296 297 "%s\n" 297 "Units = %s of % d* 512 bytes\n\n",298 disk_device, heads, sectors,cylinders,298 "Units = %s of %u * 512 bytes\n\n", 299 disk_device, g_heads, g_sectors, g_cylinders, 299 300 SGI_SSWAP16(sgiparam.pcylcount), 300 301 SGI_SSWAP16(sgiparam.sparecyl), … … 304 305 } else { 305 306 printf("\nDisk %s (SGI disk label): " 306 "% d heads, %d sectors, %dcylinders\n"307 "Units = %s of % d* 512 bytes\n\n",308 disk_device, heads, sectors,cylinders,307 "%u heads, %u sectors, %u cylinders\n" 308 "Units = %s of %u * 512 bytes\n\n", 309 disk_device, g_heads, g_sectors, g_cylinders, 309 310 str_units(PLURAL), units_per_sector ); 310 311 } … … 318 319 "Pt# %*s Info Start End Sectors Id System\n", 319 320 w + 2, "Device"); 320 for (i = 0; i < partitions; i++) {321 if (sgi_get_num_sectors(i) || debug) {321 for (i = 0; i < g_partitions; i++) { 322 if (sgi_get_num_sectors(i) || SGI_DEBUG) { 322 323 uint32_t start = sgi_get_start_sector(i); 323 324 uint32_t len = sgi_get_num_sectors(i); 324 325 kpi++; /* only count nonempty partitions */ 325 326 printf( 326 "%2 d: %s %4s %9ld %9ld %9ld%2x %s\n",327 "%2u: %s %4s %9lu %9lu %9lu %2x %s\n", 327 328 /* fdisk part number */ i+1, 328 329 /* device */ partname(disk_device, kpi, w+3), … … 345 346 unsigned char *name = sgilabel->directory[i].vol_file_name; 346 347 347 printf("%2 d: %-10s sector%5u size%8u\n",348 printf("%2u: %-10s sector%5u size%8u\n", 348 349 i, (char*)name, (unsigned int) start, (unsigned int) len); 349 350 } … … 360 361 sgi_get_lastblock(void) 361 362 { 362 return heads * sectors *cylinders;363 return g_heads * g_sectors * g_cylinders; 363 364 } 364 365 … … 439 440 (unsigned int*)sgilabel, sizeof(*sgilabel)) == 0); 440 441 441 if (lseek(fd, 0, SEEK_SET) < 0) 442 fdisk_fatal(unable_to_seek); 443 if (write(fd, sgilabel, SECTOR_SIZE) != SECTOR_SIZE) 444 fdisk_fatal(unable_to_write); 442 write_sector(0, sgilabel); 445 443 if (!strncmp((char*)sgilabel->directory[0].vol_file_name, "sgilabel", 8)) { 446 444 /* … … 450 448 sgiinfo *info = fill_sgiinfo(); 451 449 int infostartblock = SGI_SSWAP32(sgilabel->directory[0].vol_file_start); 452 if (lseek(fd, infostartblock*SECTOR_SIZE, SEEK_SET) < 0) 453 fdisk_fatal(unable_to_seek); 454 if (write(fd, info, SECTOR_SIZE) != SECTOR_SIZE) 455 fdisk_fatal(unable_to_write); 450 write_sector(infostartblock, info); 456 451 free(info); 457 452 } … … 513 508 printf("The entire disk partition should start " 514 509 "at block 0,\n" 515 "not at diskblock % d\n",510 "not at diskblock %u\n", 516 511 sgi_get_start_sector(Index[0])); 517 if ( debug) /* I do not understand how some disks fulfil it */512 if (SGI_DEBUG) /* I do not understand how some disks fulfil it */ 518 513 if ((sgi_get_num_sectors(Index[0]) != lastblock) && verbose) 519 printf("The entire disk partition is only % ddiskblock large,\n"520 "but the disk is % ddiskblocks long\n",514 printf("The entire disk partition is only %u diskblock large,\n" 515 "but the disk is %u diskblocks long\n", 521 516 sgi_get_num_sectors(Index[0]), lastblock); 522 517 lastblock = sgi_get_num_sectors(Index[0]); … … 524 519 if (verbose) 525 520 printf("One Partition (#11) should cover the entire disk\n"); 526 if ( debug> 2)527 printf("sysid=% d\tpartition=%d\n",521 if (SGI_DEBUG > 2) 522 printf("sysid=%u\tpartition=%u\n", 528 523 sgi_get_sysid(Index[0]), Index[0]+1); 529 524 } … … 532 527 533 528 if ((sgi_get_start_sector(Index[i]) % cylsize) != 0) { 534 if ( debug) /* I do not understand how some disks fulfil it */529 if (SGI_DEBUG) /* I do not understand how some disks fulfil it */ 535 530 if (verbose) 536 printf("Partition % ddoes not start on cylinder boundary\n",531 printf("Partition %u does not start on cylinder boundary\n", 537 532 Index[i]+1); 538 533 } 539 534 if (sgi_get_num_sectors(Index[i]) % cylsize != 0) { 540 if ( debug) /* I do not understand how some disks fulfil it */535 if (SGI_DEBUG) /* I do not understand how some disks fulfil it */ 541 536 if (verbose) 542 printf("Partition % ddoes not end on cylinder boundary\n",537 printf("Partition %u does not end on cylinder boundary\n", 543 538 Index[i]+1); 544 539 } … … 547 542 if (start > sgi_get_start_sector(Index[i])) { 548 543 if (verbose) 549 printf("Partitions % d and %d overlap by %dsectors\n",544 printf("Partitions %u and %u overlap by %u sectors\n", 550 545 Index[i-1]+1, Index[i]+1, 551 546 start - sgi_get_start_sector(Index[i])); … … 555 550 if (start < sgi_get_start_sector(Index[i])) { 556 551 if (verbose) 557 printf("Unused gap of % 8u sectors - sectors %8u-%8u\n",552 printf("Unused gap of %u sectors - sectors %u-%u\n", 558 553 sgi_get_start_sector(Index[i]) - start, 559 554 start, sgi_get_start_sector(Index[i])-1); … … 563 558 start = sgi_get_start_sector(Index[i]) 564 559 + sgi_get_num_sectors(Index[i]); 565 if ( debug> 1) {560 if (SGI_DEBUG > 1) { 566 561 if (verbose) 567 printf("%2 d:%12d\t%12d\t%12d\n", Index[i],562 printf("%2u:%12u\t%12u\t%12u\n", Index[i], 568 563 sgi_get_start_sector(Index[i]), 569 564 sgi_get_num_sectors(Index[i]), … … 573 568 if (start < lastblock) { 574 569 if (verbose) 575 printf("Unused gap of % 8u sectors - sectors %8u-%8u\n",570 printf("Unused gap of %u sectors - sectors %u-%u\n", 576 571 lastblock - start, start, lastblock-1); 577 572 gap += lastblock - start; … … 661 656 int n; 662 657 663 for (n = 10; n < partitions; n++) {658 for (n = 10; n < g_partitions; n++) { 664 659 if (!sgi_get_num_sectors(n) ) { 665 660 sgi_set_partition(n, 0, sgi_get_lastblock(), SGI_VOLUME); … … 674 669 int n; 675 670 676 for (n = 8; n < partitions; n++) {671 for (n = 8; n < g_partitions; n++) { 677 672 if (!sgi_get_num_sectors(n)) { 678 673 /* … … 682 677 * sectors. 683 678 */ 684 if ( heads *sectors * 5 < sgi_get_lastblock())685 sgi_set_partition(n, 0, heads *sectors * 5, SGI_VOLHDR);679 if (g_heads * g_sectors * 5 < sgi_get_lastblock()) 680 sgi_set_partition(n, 0, g_heads * g_sectors * 5, SGI_VOLHDR); 686 681 break; 687 682 } … … 781 776 printf(msg_building_new_label, "SGI disklabel"); 782 777 783 sgi_other_endian = (BYTE_ORDER == LITTLE_ENDIAN);784 res = ioctl( fd, BLKGETSIZE, &longsectors);785 if (!ioctl( fd, HDIO_GETGEO, &geometry)) {786 heads = geometry.heads;787 sectors = geometry.sectors;778 sgi_other_endian = BB_LITTLE_ENDIAN; 779 res = ioctl(dev_fd, BLKGETSIZE, &longsectors); 780 if (!ioctl(dev_fd, HDIO_GETGEO, &geometry)) { 781 g_heads = geometry.heads; 782 g_sectors = geometry.sectors; 788 783 if (res == 0) { 789 784 /* the get device size ioctl was successful */ 790 cylinders = longsectors / (heads *sectors);791 cylinders /= sec_fac;785 g_cylinders = longsectors / (g_heads * g_sectors); 786 g_cylinders /= sec_fac; 792 787 } else { 793 788 /* otherwise print error and use truncated version */ 794 cylinders = geometry.cylinders;789 g_cylinders = geometry.cylinders; 795 790 printf( 796 "Warning: BLKGETSIZE ioctl failed on %s. Using geometry cylinder value of % d.\n"797 "This value may be truncated for devices > 33.8 GB.\n", disk_device, cylinders);791 "Warning: BLKGETSIZE ioctl failed on %s. Using geometry cylinder value of %u.\n" 792 "This value may be truncated for devices > 33.8 GB.\n", disk_device, g_cylinders); 798 793 } 799 794 } … … 805 800 old[i].start = get_start_sect(get_part_table(i)); 806 801 old[i].nsect = get_nr_sects(get_part_table(i)); 807 printf("Trying to keep parameters of partition % d\n", i);808 if ( debug)809 printf("ID=%02x\tSTART=% d\tLENGTH=%d\n",802 printf("Trying to keep parameters of partition %u\n", i); 803 if (SGI_DEBUG) 804 printf("ID=%02x\tSTART=%u\tLENGTH=%u\n", 810 805 old[i].sysid, old[i].start, old[i].nsect); 811 806 } … … 851 846 //memset( &(sgilabel->directory), 0, sizeof(struct volume_directory)*15 ); 852 847 //memset( &(sgilabel->partitions), 0, sizeof(struct sgi_partinfo)*16 ); 853 current_label_type = label_sgi;854 partitions = 16;848 current_label_type = LABEL_SGI; 849 g_partitions = 16; 855 850 sgi_volumes = 15; 856 851 sgi_set_entire(); -
branches/2.2.9/mindi-busybox/util-linux/fdisk_sun.c
r1765 r2725 1 #if ENABLE_FEATURE_SUN_LABEL2 3 #define SUNOS_SWAP 34 #define SUN_WHOLE_DISK 55 6 #define SUN_LABEL_MAGIC 0xDABE7 #define SUN_LABEL_MAGIC_SWAPPED 0xBEDA8 #define SUN_SSWAP16(x) (sun_other_endian ? fdisk_swap16(x) : (uint16_t)(x))9 #define SUN_SSWAP32(x) (sun_other_endian ? fdisk_swap32(x) : (uint32_t)(x))10 11 /* Copied from linux/major.h */12 #define FLOPPY_MAJOR 213 14 #define SCSI_IOCTL_GET_IDLUN 0x538215 16 1 /* 17 * fdisk sunlabel.c2 * fdisk_sun.c 18 3 * 19 4 * I think this is mostly, or entirely, due to … … 24 9 * Sat Mar 20 EST 1999 Arnaldo Carvalho de Melo <acme@conectiva.com.br> 25 10 * Internationalization 11 * 12 * Licensed under GPLv2, see file LICENSE in this source tree. 26 13 */ 27 14 28 29 static int sun_other_endian; 30 static int scsi_disk; 31 static int floppy; 15 #if ENABLE_FEATURE_SUN_LABEL 16 17 #define SUNOS_SWAP 3 18 #define SUN_WHOLE_DISK 5 19 20 #define SUN_LABEL_MAGIC 0xDABE 21 #define SUN_LABEL_MAGIC_SWAPPED 0xBEDA 22 #define SUN_SSWAP16(x) (sun_other_endian ? fdisk_swap16(x) : (uint16_t)(x)) 23 #define SUN_SSWAP32(x) (sun_other_endian ? fdisk_swap32(x) : (uint32_t)(x)) 24 25 /* Copied from linux/major.h */ 26 #define FLOPPY_MAJOR 2 27 28 #define SCSI_IOCTL_GET_IDLUN 0x5382 29 30 static smallint sun_other_endian; 31 static smallint scsi_disk; 32 static smallint floppy; 32 33 33 34 #ifndef IDE0_MAJOR … … 43 44 struct stat bootstat; 44 45 45 if (fstat( fd, &bootstat) < 0) {46 if (fstat(dev_fd, &bootstat) < 0) { 46 47 scsi_disk = 0; 47 48 floppy = 0; … … 81 82 82 83 static void 83 set_sun_partition(int i, u int start, uintstop, int sysid)84 set_sun_partition(int i, unsigned start, unsigned stop, int sysid) 84 85 { 85 86 sunlabel->infos[i].id = sysid; 86 87 sunlabel->partitions[i].start_cylinder = 87 SUN_SSWAP32(start / ( heads *sectors));88 SUN_SSWAP32(start / (g_heads * g_sectors)); 88 89 sunlabel->partitions[i].num_sectors = 89 90 SUN_SSWAP32(stop - start); … … 98 99 99 100 if (sunlabel->magic != SUN_LABEL_MAGIC 100 && sunlabel->magic != SUN_LABEL_MAGIC_SWAPPED) { 101 current_label_type = label_dos; 101 && sunlabel->magic != SUN_LABEL_MAGIC_SWAPPED 102 ) { 103 current_label_type = LABEL_DOS; 102 104 sun_other_endian = 0; 103 105 return 0; … … 112 114 "or force a fresh label (s command in main menu)\n"); 113 115 } else { 114 heads = SUN_SSWAP16(sunlabel->ntrks);115 cylinders = SUN_SSWAP16(sunlabel->ncyl);116 sectors = SUN_SSWAP16(sunlabel->nsect);116 g_heads = SUN_SSWAP16(sunlabel->ntrks); 117 g_cylinders = SUN_SSWAP16(sunlabel->ncyl); 118 g_sectors = SUN_SSWAP16(sunlabel->nsect); 117 119 } 118 120 update_units(); 119 current_label_type = label_sun;120 partitions = 8;121 current_label_type = LABEL_SUN; 122 g_partitions = 8; 121 123 return 1; 122 124 } … … 169 171 int i; 170 172 171 if (ioctl( fd, SCSI_IOCTL_GET_IDLUN, &id))173 if (ioctl(dev_fd, SCSI_IOCTL_GET_IDLUN, &id)) 172 174 return NULL; 173 175 174 176 sprintf(buffer, 175 "Host: scsi% d Channel: %02d Id: %02d Lun: %02d\n",177 "Host: scsi%u Channel: %02u Id: %02u Lun: %02u\n", 176 178 /* This is very wrong (works only if you have one HBA), 177 179 but I haven't found a way how to get hostno … … 182 184 (id[0]>>8) & 0xff 183 185 ); 184 pfd = fopen ("/proc/scsi/scsi", "r");186 pfd = fopen_for_read("/proc/scsi/scsi"); 185 187 if (!pfd) { 186 188 return NULL; … … 231 233 { 232 234 struct hd_geometry geometry; 233 unsigned int ndiv; 234 int i; 235 unsigned ndiv; 235 236 unsigned char c; 236 237 const struct sun_predefined_drives *p = NULL; … … 242 243 sunlabel->magic = SUN_SSWAP16(SUN_LABEL_MAGIC); 243 244 if (!floppy) { 245 unsigned i; 244 246 puts("Drive type\n" 245 247 " ? auto configure\n" … … 273 275 } 274 276 if (!p || floppy) { 275 if (!ioctl( fd, HDIO_GETGEO, &geometry)) {276 heads = geometry.heads;277 sectors = geometry.sectors;278 cylinders = geometry.cylinders;277 if (!ioctl(dev_fd, HDIO_GETGEO, &geometry)) { 278 g_heads = geometry.heads; 279 g_sectors = geometry.sectors; 280 g_cylinders = geometry.cylinders; 279 281 } else { 280 heads = 0;281 sectors = 0;282 cylinders = 0;282 g_heads = 0; 283 g_sectors = 0; 284 g_cylinders = 0; 283 285 } 284 286 if (floppy) { 285 287 sunlabel->nacyl = 0; 286 sunlabel->pcylcount = SUN_SSWAP16( cylinders);288 sunlabel->pcylcount = SUN_SSWAP16(g_cylinders); 287 289 sunlabel->rspeed = SUN_SSWAP16(300); 288 290 sunlabel->ilfact = SUN_SSWAP16(1); 289 291 sunlabel->sparecyl = 0; 290 292 } else { 291 heads = read_int(1,heads, 1024, 0, "Heads");292 sectors = read_int(1,sectors, 1024, 0, "Sectors/track");293 if ( cylinders)294 cylinders = read_int(1, cylinders-2, 65535, 0, "Cylinders");293 g_heads = read_int(1, g_heads, 1024, 0, "Heads"); 294 g_sectors = read_int(1, g_sectors, 1024, 0, "Sectors/track"); 295 if (g_cylinders) 296 g_cylinders = read_int(1, g_cylinders - 2, 65535, 0, "Cylinders"); 295 297 else 296 cylinders = read_int(1, 0, 65535, 0, "Cylinders");298 g_cylinders = read_int(1, 0, 65535, 0, "Cylinders"); 297 299 sunlabel->nacyl = SUN_SSWAP16(read_int(0, 2, 65535, 0, "Alternate cylinders")); 298 sunlabel->pcylcount = SUN_SSWAP16(read_int(0, cylinders+SUN_SSWAP16(sunlabel->nacyl), 65535, 0, "Physical cylinders"));300 sunlabel->pcylcount = SUN_SSWAP16(read_int(0, g_cylinders + SUN_SSWAP16(sunlabel->nacyl), 65535, 0, "Physical cylinders")); 299 301 sunlabel->rspeed = SUN_SSWAP16(read_int(1, 5400, 100000, 0, "Rotation speed (rpm)")); 300 302 sunlabel->ilfact = SUN_SSWAP16(read_int(1, 1, 32, 0, "Interleave factor")); 301 sunlabel->sparecyl = SUN_SSWAP16(read_int(0, 0, sectors, 0, "Extra sectors per cylinder"));303 sunlabel->sparecyl = SUN_SSWAP16(read_int(0, 0, g_sectors, 0, "Extra sectors per cylinder")); 302 304 } 303 305 } else { … … 310 312 sunlabel->rspeed = SUN_SSWAP16(p->rspeed); 311 313 sunlabel->ilfact = SUN_SSWAP16(1); 312 cylinders = p->ncyl;313 heads = p->ntrks;314 sectors = p->nsect;314 g_cylinders = p->ncyl; 315 g_heads = p->ntrks; 316 g_sectors = p->nsect; 315 317 puts("You may change all the disk params from the x menu"); 316 318 } 317 319 318 320 snprintf((char *)(sunlabel->info), sizeof(sunlabel->info), 319 "%s%s%s cyl % d alt %d hd %d sec %d",321 "%s%s%s cyl %u alt %u hd %u sec %u", 320 322 p ? p->vendor : "", (p && *p->vendor) ? " " : "", 321 323 p ? p->model : (floppy ? "3,5\" floppy" : "Linux custom"), 322 cylinders, SUN_SSWAP16(sunlabel->nacyl), heads,sectors);323 324 sunlabel->ntrks = SUN_SSWAP16( heads);325 sunlabel->nsect = SUN_SSWAP16( sectors);326 sunlabel->ncyl = SUN_SSWAP16( cylinders);324 g_cylinders, SUN_SSWAP16(sunlabel->nacyl), g_heads, g_sectors); 325 326 sunlabel->ntrks = SUN_SSWAP16(g_heads); 327 sunlabel->nsect = SUN_SSWAP16(g_sectors); 328 sunlabel->ncyl = SUN_SSWAP16(g_cylinders); 327 329 if (floppy) 328 set_sun_partition(0, 0, cylinders * heads *sectors, LINUX_NATIVE);330 set_sun_partition(0, 0, g_cylinders * g_heads * g_sectors, LINUX_NATIVE); 329 331 else { 330 if ( cylinders * heads *sectors >= 150 * 2048) {331 ndiv = cylinders - (50 * 2048 / (heads *sectors)); /* 50M swap */332 if (g_cylinders * g_heads * g_sectors >= 150 * 2048) { 333 ndiv = g_cylinders - (50 * 2048 / (g_heads * g_sectors)); /* 50M swap */ 332 334 } else 333 ndiv = cylinders * 2 / 3;334 set_sun_partition(0, 0, ndiv * heads *sectors, LINUX_NATIVE);335 set_sun_partition(1, ndiv * heads * sectors, cylinders * heads *sectors, LINUX_SWAP);335 ndiv = g_cylinders * 2 / 3; 336 set_sun_partition(0, 0, ndiv * g_heads * g_sectors, LINUX_NATIVE); 337 set_sun_partition(1, ndiv * g_heads * g_sectors, g_cylinders * g_heads * g_sectors, LINUX_SWAP); 336 338 sunlabel->infos[1].flags |= 0x01; /* Not mountable */ 337 339 } 338 set_sun_partition(2, 0, cylinders * heads *sectors, SUN_WHOLE_DISK);340 set_sun_partition(2, 0, g_cylinders * g_heads * g_sectors, SUN_WHOLE_DISK); 339 341 { 340 342 unsigned short *ush = (unsigned short *)sunlabel; … … 347 349 set_all_unchanged(); 348 350 set_changed(0); 349 get_boot( create_empty_sun);351 get_boot(CREATE_EMPTY_SUN); 350 352 } 351 353 … … 361 363 362 364 static void 363 fetch_sun(u int *starts, uint *lens, uint *start, uint*stop)365 fetch_sun(unsigned *starts, unsigned *lens, unsigned *start, unsigned *stop) 364 366 { 365 367 int i, continuous = 1; 366 368 367 369 *start = 0; 368 *stop = cylinders * heads *sectors;369 for (i = 0; i < partitions; i++) {370 *stop = g_cylinders * g_heads * g_sectors; 371 for (i = 0; i < g_partitions; i++) { 370 372 if (sunlabel->partitions[i].num_sectors 371 373 && sunlabel->infos[i].id 372 374 && sunlabel->infos[i].id != SUN_WHOLE_DISK) { 373 starts[i] = SUN_SSWAP32(sunlabel->partitions[i].start_cylinder) * heads *sectors;375 starts[i] = SUN_SSWAP32(sunlabel->partitions[i].start_cylinder) * g_heads * g_sectors; 374 376 lens[i] = SUN_SSWAP32(sunlabel->partitions[i].num_sectors); 375 377 if (continuous) { … … 390 392 } 391 393 392 static u int*verify_sun_starts;394 static unsigned *verify_sun_starts; 393 395 394 396 static int … … 404 406 verify_sun(void) 405 407 { 406 u intstarts[8], lens[8], start, stop;408 unsigned starts[8], lens[8], start, stop; 407 409 int i,j,k,starto,endo; 408 410 int array[8]; 409 411 410 412 verify_sun_starts = starts; 411 fetch_sun(starts, lens,&start,&stop);413 fetch_sun(starts, lens, &start, &stop); 412 414 for (k = 0; k < 7; k++) { 413 415 for (i = 0; i < 8; i++) { 414 if (k && (lens[i] % ( heads *sectors))) {415 printf("Partition % ddoesn't end on cylinder boundary\n", i+1);416 if (k && (lens[i] % (g_heads * g_sectors))) { 417 printf("Partition %u doesn't end on cylinder boundary\n", i+1); 416 418 } 417 419 if (lens[i]) { … … 433 435 if (starts[j]+lens[j] < endo) 434 436 endo = starts[j]+lens[j]; 435 printf("Partition % doverlaps with others in "436 "sectors % d-%d\n", i+1, starto, endo);437 printf("Partition %u overlaps with others in " 438 "sectors %u-%u\n", i+1, starto, endo); 437 439 } 438 440 } … … 453 455 return; 454 456 } 455 stop = cylinders * heads *sectors;457 stop = g_cylinders * g_heads * g_sectors; 456 458 if (starts[array[0]]) 457 printf("Unused gap - sectors 0-%d\n", starts[array[0]]);459 printf("Unused gap - sectors %u-%u\n", 0, starts[array[0]]); 458 460 for (i = 0; i < 7 && array[i+1] != -1; i++) { 459 printf("Unused gap - sectors % d-%d\n", starts[array[i]]+lens[array[i]], starts[array[i+1]]);461 printf("Unused gap - sectors %u-%u\n", starts[array[i]]+lens[array[i]], starts[array[i+1]]); 460 462 } 461 463 start = starts[array[i]] + lens[array[i]]; 462 464 if (start < stop) 463 printf("Unused gap - sectors % d-%d\n", start, stop);465 printf("Unused gap - sectors %u-%u\n", start, stop); 464 466 } 465 467 … … 467 469 add_sun_partition(int n, int sys) 468 470 { 469 u intstart, stop, stop2;470 u intstarts[8], lens[8];471 unsigned start, stop, stop2; 472 unsigned starts[8], lens[8]; 471 473 int whole_disk = 0; 472 474 … … 479 481 } 480 482 481 fetch_sun(starts, lens,&start,&stop);483 fetch_sun(starts, lens, &start, &stop); 482 484 if (stop <= start) { 483 485 if (n == 2) … … 500 502 else 501 503 /* Starting sector has to be properly aligned */ 502 first = (first + heads * sectors - 1) / (heads *sectors);504 first = (first + g_heads * g_sectors - 1) / (g_heads * g_sectors); 503 505 if (n == 2 && first != 0) 504 506 printf("\ … … 521 523 starting at block 0 in an md, or the label will 522 524 be trashed. */ 523 for (i = 0; i < partitions; i++)525 for (i = 0; i < g_partitions; i++) 524 526 if (lens[i] && starts[i] <= first && starts[i] + lens[i] > first) 525 527 break; 526 if (i < partitions && !whole_disk) {528 if (i < g_partitions && !whole_disk) { 527 529 if (n == 2 && !first) { 528 530 whole_disk = 1; 529 531 break; 530 532 } 531 printf("Sector % dis already allocated\n", first);533 printf("Sector %u is already allocated\n", first); 532 534 } else 533 535 break; 534 536 } 535 stop = cylinders * heads *sectors;537 stop = g_cylinders * g_heads * g_sectors; 536 538 stop2 = stop; 537 for (i = 0; i < partitions; i++) {539 for (i = 0; i < g_partitions; i++) { 538 540 if (starts[i] > first && starts[i] < stop) 539 541 stop = starts[i]; … … 560 562 printf( 561 563 "You haven't covered the whole disk with the 3rd partition,\n" 562 "but your value % d%s covers some other partition.\n"563 "Your entry has been changed to % d%s\n",564 "but your value %u %s covers some other partition.\n" 565 "Your entry has been changed to %u %s\n", 564 566 scround(last), str_units(SINGULAR), 565 567 scround(stop), str_units(SINGULAR)); … … 582 584 && sunlabel->infos[i].id == SUN_WHOLE_DISK 583 585 && !sunlabel->partitions[i].start_cylinder 584 && (nsec = SUN_SSWAP32(sunlabel->partitions[i].num_sectors)) == heads * sectors *cylinders)586 && (nsec = SUN_SSWAP32(sunlabel->partitions[i].num_sectors)) == g_heads * g_sectors * g_cylinders) 585 587 printf("If you want to maintain SunOS/Solaris compatibility, " 586 588 "consider leaving this\n" … … 627 629 if (xtra) 628 630 printf( 629 "\nDisk %s (Sun disk label): % d heads, %d sectors, %drpm\n"630 "% d cylinders, %d alternate cylinders, %dphysical cylinders\n"631 "% d extra sects/cyl, interleave %d:1\n"631 "\nDisk %s (Sun disk label): %u heads, %u sectors, %u rpm\n" 632 "%u cylinders, %u alternate cylinders, %u physical cylinders\n" 633 "%u extra sects/cyl, interleave %u:1\n" 632 634 "%s\n" 633 "Units = %s of % d* 512 bytes\n\n",634 disk_device, heads,sectors, SUN_SSWAP16(sunlabel->rspeed),635 cylinders, SUN_SSWAP16(sunlabel->nacyl),635 "Units = %s of %u * 512 bytes\n\n", 636 disk_device, g_heads, g_sectors, SUN_SSWAP16(sunlabel->rspeed), 637 g_cylinders, SUN_SSWAP16(sunlabel->nacyl), 636 638 SUN_SSWAP16(sunlabel->pcylcount), 637 639 SUN_SSWAP16(sunlabel->sparecyl), … … 641 643 else 642 644 printf( 643 "\nDisk %s (Sun disk label): % d heads, %d sectors, %dcylinders\n"644 "Units = %s of % d* 512 bytes\n\n",645 disk_device, heads, sectors,cylinders,645 "\nDisk %s (Sun disk label): %u heads, %u sectors, %u cylinders\n" 646 "Units = %s of %u * 512 bytes\n\n", 647 disk_device, g_heads, g_sectors, g_cylinders, 646 648 str_units(PLURAL), units_per_sector); 647 649 648 650 printf("%*s Flag Start End Blocks Id System\n", 649 651 w + 1, "Device"); 650 for (i = 0; i < partitions; i++) {652 for (i = 0; i < g_partitions; i++) { 651 653 if (sunlabel->partitions[i].num_sectors) { 652 uint32_t start = SUN_SSWAP32(sunlabel->partitions[i].start_cylinder) * heads *sectors;654 uint32_t start = SUN_SSWAP32(sunlabel->partitions[i].start_cylinder) * g_heads * g_sectors; 653 655 uint32_t len = SUN_SSWAP32(sunlabel->partitions[i].num_sectors); 654 printf("%s %c%c %9l d %9ld %9ld%c %2x %s\n",655 partname(disk_device, i+1, w), 656 printf("%s %c%c %9lu %9lu %9lu%c %2x %s\n", 657 partname(disk_device, i+1, w), /* device */ 656 658 (sunlabel->infos[i].flags & 0x01) ? 'u' : ' ', /* flags */ 657 659 (sunlabel->infos[i].flags & 0x10) ? 'r' : ' ', … … 685 687 { 686 688 sunlabel->sparecyl = 687 SUN_SSWAP16(read_int(0, SUN_SSWAP16(sunlabel->sparecyl), sectors, 0,689 SUN_SSWAP16(read_int(0, SUN_SSWAP16(sunlabel->sparecyl), g_sectors, 0, 688 690 "Extra sectors per cylinder")); 689 691 } … … 723 725 csum ^= *ush++; 724 726 sunlabel->csum = csum; 725 if (lseek(fd, 0, SEEK_SET) < 0) 726 fdisk_fatal(unable_to_seek); 727 if (write(fd, sunlabel, SECTOR_SIZE) != SECTOR_SIZE) 728 fdisk_fatal(unable_to_write); 727 write_sector(0, sunlabel); 729 728 } 730 729 #endif /* SUN_LABEL */ -
branches/2.2.9/mindi-busybox/util-linux/freeramdisk.c
r1765 r2725 7 7 * Unified with fdflush by Tito Ragusa <farmatito@tiscali.it> 8 8 * 9 * Licensed under GPLv2, see file LICENSE in this tarball for details.9 * Licensed under GPLv2, see file LICENSE in this source tree. 10 10 */ 11 11 #include <sys/mount.h> 12 12 #include "libbb.h" 13 13 … … 15 15 #define FDFLUSH _IO(2,0x4b) 16 16 17 int freeramdisk_main(int argc, char **argv) ;18 int freeramdisk_main(int argc , char **argv)17 int freeramdisk_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 18 int freeramdisk_main(int argc UNUSED_PARAM, char **argv) 19 19 { 20 20 int fd; 21 21 22 if (argc != 2) bb_show_usage(); 23 24 fd = xopen(argv[1], O_RDWR); 22 fd = xopen(single_argv(argv), O_RDWR); 25 23 26 24 // Act like freeramdisk, fdflush, or both depending on configuration. 27 ioctl_or_perror_and_die(fd, (ENABLE_FREERAMDISK && applet_name[1] =='r')25 ioctl_or_perror_and_die(fd, (ENABLE_FREERAMDISK && applet_name[1] == 'r') 28 26 || !ENABLE_FDFLUSH ? BLKFLSBUF : FDFLUSH, NULL, "%s", argv[1]); 29 27 -
branches/2.2.9/mindi-busybox/util-linux/fsck_minix.c
r1765 r2725 5 5 * (C) 1991, 1992 Linus Torvalds. 6 6 * 7 * Licensed under GPLv2, see file LICENSE in this tarball for details.7 * Licensed under GPLv2, see file LICENSE in this source tree. 8 8 */ 9 9 … … 30 30 * 31 31 * Sat Mar 6 18:59:42 1993, faith@cs.unc.edu: Output namelen with 32 * super -block information32 * superblock information 33 33 * 34 34 * Sat Oct 9 11:17:11 1993, faith@cs.unc.edu: make exit status conform … … 65 65 * Andreas Schwab. 66 66 * 67 * 1999-02-22 Arkadiusz Mi ¶kiewicz <misiek@misiek.eu.org>67 * 1999-02-22 Arkadiusz Mickiewicz <misiek@misiek.eu.org> 68 68 * - added Native Language Support 69 69 * … … 80 80 * -r for repairs (interactive) (not implemented) 81 81 * -v for verbose (tells how many files) 82 * -s for super -block info82 * -s for superblock info 83 83 * -m for minix-like "mode not cleared" warnings 84 84 * -f force filesystem check even if filesystem marked as valid … … 95 95 #define BLKGETSIZE _IO(0x12,96) /* return device size */ 96 96 #endif 97 98 struct BUG_bad_inode_size { 99 char BUG_bad_inode1_size[(INODE_SIZE1 * MINIX1_INODES_PER_BLOCK != BLOCK_SIZE) ? -1 : 1]; 100 #if ENABLE_FEATURE_MINIX2 101 char BUG_bad_inode2_size[(INODE_SIZE2 * MINIX2_INODES_PER_BLOCK != BLOCK_SIZE) ? -1 : 1]; 102 #endif 103 }; 97 104 98 105 enum { … … 108 115 }; 109 116 117 110 118 #if !ENABLE_FEATURE_MINIX2 111 119 enum { version2 = 0 }; … … 114 122 enum { MAX_DEPTH = 32 }; 115 123 124 enum { dev_fd = 3 }; 125 116 126 struct globals { 117 int dev_fd;118 127 #if ENABLE_FEATURE_MINIX2 119 128 smallint version2; 120 129 #endif 121 smallint repair, automatic, verbose, list, show, warn_mode, force;122 130 smallint changed; /* is filesystem modified? */ 123 131 smallint errors_uncorrected; /* flag if some error was not corrected */ … … 125 133 smallint dirsize; 126 134 smallint namelen; 127 c har *device_name;135 const char *device_name; 128 136 int directory, regular, blockdev, chardev, links, symlinks, total; 129 137 char *inode_buffer; … … 141 149 /* Bigger stuff */ 142 150 struct termios sv_termios; 143 char super _block_buffer[BLOCK_SIZE];151 char superblock_buffer[BLOCK_SIZE]; 144 152 char add_zone_ind_blk[BLOCK_SIZE]; 145 153 char add_zone_dind_blk[BLOCK_SIZE]; 146 USE_FEATURE_MINIX2(char add_zone_tind_blk[BLOCK_SIZE];)154 IF_FEATURE_MINIX2(char add_zone_tind_blk[BLOCK_SIZE];) 147 155 char check_file_blk[BLOCK_SIZE]; 148 156 … … 150 158 char current_name[MAX_DEPTH * MINIX_NAME_MAX]; 151 159 }; 152 153 160 #define G (*ptr_to_globals) 154 #define dev_fd (G.dev_fd )155 161 #if ENABLE_FEATURE_MINIX2 156 162 #define version2 (G.version2 ) 157 163 #endif 158 #define repair (G.repair )159 #define automatic (G.automatic )160 #define verbose (G.verbose )161 #define list (G.list )162 #define show (G.show )163 #define warn_mode (G.warn_mode )164 #define force (G.force )165 164 #define changed (G.changed ) 166 165 #define errors_uncorrected (G.errors_uncorrected ) … … 184 183 #define name_component (G.name_component ) 185 184 #define sv_termios (G.sv_termios ) 186 #define super _block_buffer (G.super_block_buffer )185 #define superblock_buffer (G.superblock_buffer ) 187 186 #define add_zone_ind_blk (G.add_zone_ind_blk ) 188 187 #define add_zone_dind_blk (G.add_zone_dind_blk ) … … 191 190 #define current_name (G.current_name ) 192 191 #define INIT_G() do { \ 193 PTR_TO_GLOBALS = xzalloc(sizeof(G)); \192 SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \ 194 193 dirsize = 16; \ 195 194 namelen = 14; \ … … 199 198 } while (0) 200 199 200 201 #define OPTION_STR "larvsmf" 202 enum { 203 OPT_l = (1 << 0), 204 OPT_a = (1 << 1), 205 OPT_r = (1 << 2), 206 OPT_v = (1 << 3), 207 OPT_s = (1 << 4), 208 OPT_w = (1 << 5), 209 OPT_f = (1 << 6), 210 }; 211 #define OPT_list (option_mask32 & OPT_l) 212 #define OPT_automatic (option_mask32 & OPT_a) 213 #define OPT_repair (option_mask32 & OPT_r) 214 #define OPT_verbose (option_mask32 & OPT_v) 215 #define OPT_show (option_mask32 & OPT_s) 216 #define OPT_warn_mode (option_mask32 & OPT_w) 217 #define OPT_force (option_mask32 & OPT_f) 218 /* non-automatic repairs requested? */ 219 #define OPT_manual ((option_mask32 & (OPT_a|OPT_r)) == OPT_r) 220 221 201 222 #define Inode1 (((struct minix1_inode *) inode_buffer)-1) 202 223 #define Inode2 (((struct minix2_inode *) inode_buffer)-1) 203 224 204 #define Super (*(struct minix_super _block *)(super_block_buffer))225 #define Super (*(struct minix_superblock *)(superblock_buffer)) 205 226 206 227 #if ENABLE_FEATURE_MINIX2 … … 223 244 } 224 245 225 #if ENABLE_FEATURE_MINIX2 226 #define INODE_BLOCKS div_roundup(INODES, (version2 ? MINIX2_INODES_PER_BLOCK \ 227 : MINIX1_INODES_PER_BLOCK)) 246 #if !ENABLE_FEATURE_MINIX2 247 #define INODE_BLOCKS div_roundup(INODES, MINIX1_INODES_PER_BLOCK) 228 248 #else 229 #define INODE_BLOCKS div_roundup(INODES, MINIX1_INODES_PER_BLOCK) 230 #endif 231 232 #define INODE_BUFFER_SIZE (INODE_BLOCKS * BLOCK_SIZE) 233 #define NORM_FIRSTZONE (2 + IMAPS + ZMAPS + INODE_BLOCKS) 249 #define INODE_BLOCKS div_roundup(INODES, \ 250 (version2 ? MINIX2_INODES_PER_BLOCK : MINIX1_INODES_PER_BLOCK)) 251 #endif 252 253 #define INODE_BUFFER_SIZE (INODE_BLOCKS * BLOCK_SIZE) 254 #define NORM_FIRSTZONE (2 + IMAPS + ZMAPS + INODE_BLOCKS) 234 255 235 256 /* Before you ask "where they come from?": */ … … 268 289 #endif 269 290 270 static void die(const char *str) ATTRIBUTE_NORETURN;291 static void die(const char *str) NORETURN; 271 292 static void die(const char *str) 272 293 { 273 294 if (termios_set) 274 tcsetattr (0, TCSANOW,&sv_termios);295 tcsetattr_stdin_TCSANOW(&sv_termios); 275 296 bb_error_msg_and_die("%s", str); 276 297 } … … 307 328 int c; 308 329 309 if (! repair) {310 puts("");330 if (!OPT_repair) { 331 bb_putchar('\n'); 311 332 errors_uncorrected = 1; 312 333 return 0; 313 334 } 314 if ( automatic) {315 puts("");335 if (OPT_automatic) { 336 bb_putchar('\n'); 316 337 if (!def) 317 338 errors_uncorrected = 1; … … 320 341 printf(def ? "%s (y/n)? " : "%s (n/y)? ", string); 321 342 for (;;) { 322 fflush (stdout);343 fflush_all(); 323 344 c = getchar(); 324 345 if (c == EOF) { … … 327 348 return def; 328 349 } 329 c = toupper(c); 330 if (c == 'Y') { 350 if (c == '\n') 351 break; 352 c |= 0x20; /* tolower */ 353 if (c == 'y') { 331 354 def = 1; 332 355 break; 333 } else if (c == 'N') { 356 } 357 if (c == 'n') { 334 358 def = 0; 335 359 break; 336 } else if (c == ' ' || c == '\n') 337 break; 360 } 338 361 } 339 362 if (def) … … 353 376 static void check_mount(void) 354 377 { 355 FILE *f; 356 struct mntent *mnt; 357 int cont; 358 int fd; 359 360 f = setmntent(MOUNTED, "r"); 361 if (f == NULL) 362 return; 363 while ((mnt = getmntent(f)) != NULL) 364 if (strcmp(device_name, mnt->mnt_fsname) == 0) 365 break; 366 endmntent(f); 367 if (!mnt) 368 return; 369 370 /* 371 * If the root is mounted read-only, then /etc/mtab is 372 * probably not correct; so we won't issue a warning based on 373 * it. 374 */ 375 fd = open(MOUNTED, O_RDWR); 376 if (fd < 0 && errno == EROFS) 377 return; 378 close(fd); 379 380 printf("%s is mounted. ", device_name); 381 cont = 0; 382 if (isatty(0) && isatty(1)) 383 cont = ask("Do you really want to continue", 0); 384 if (!cont) { 385 printf("Check aborted\n"); 386 exit(0); 378 if (find_mount_point(device_name, 0)) { 379 int cont; 380 #if ENABLE_FEATURE_MTAB_SUPPORT 381 /* 382 * If the root is mounted read-only, then /etc/mtab is 383 * probably not correct; so we won't issue a warning based on 384 * it. 385 */ 386 int fd = open(bb_path_mtab_file, O_RDWR); 387 388 if (fd < 0 && errno == EROFS) 389 return; 390 close(fd); 391 #endif 392 printf("%s is mounted. ", device_name); 393 cont = 0; 394 if (isatty(0) && isatty(1)) 395 cont = ask("Do you really want to continue", 0); 396 if (!cont) { 397 printf("Check aborted\n"); 398 exit(EXIT_SUCCESS); 399 } 387 400 } 388 401 } … … 424 437 * read-block reads block nr into the buffer at addr. 425 438 */ 426 static void read_block(unsigned nr, char*addr)439 static void read_block(unsigned nr, void *addr) 427 440 { 428 441 if (!nr) { … … 430 443 return; 431 444 } 432 if (BLOCK_SIZE * nr != lseek(dev_fd, BLOCK_SIZE * nr, SEEK_SET)) { 433 printf("%s: cannot seek to block in file '%s'\n", 434 bb_msg_read_error, current_name); 435 errors_uncorrected = 1; 436 memset(addr, 0, BLOCK_SIZE); 437 } else if (BLOCK_SIZE != read(dev_fd, addr, BLOCK_SIZE)) { 438 printf("%s: bad block in file '%s'\n", 439 bb_msg_read_error, current_name); 445 xlseek(dev_fd, BLOCK_SIZE * nr, SEEK_SET); 446 if (BLOCK_SIZE != full_read(dev_fd, addr, BLOCK_SIZE)) { 447 printf("%s: bad block %u in file '%s'\n", 448 bb_msg_read_error, nr, current_name); 440 449 errors_uncorrected = 1; 441 450 memset(addr, 0, BLOCK_SIZE); … … 446 455 * write_block writes block nr to disk. 447 456 */ 448 static void write_block(unsigned nr, char*addr)457 static void write_block(unsigned nr, void *addr) 449 458 { 450 459 if (!nr) … … 456 465 return; 457 466 } 458 if (BLOCK_SIZE * nr != lseek(dev_fd, BLOCK_SIZE * nr, SEEK_SET)) 459 die("seek failed in write_block"); 460 if (BLOCK_SIZE != write(dev_fd, addr, BLOCK_SIZE)) { 461 printf("%s: bad block in file '%s'\n", 462 bb_msg_write_error, current_name); 467 xlseek(dev_fd, BLOCK_SIZE * nr, SEEK_SET); 468 if (BLOCK_SIZE != full_write(dev_fd, addr, BLOCK_SIZE)) { 469 printf("%s: bad block %u in file '%s'\n", 470 bb_msg_write_error, nr, current_name); 463 471 errors_uncorrected = 1; 464 472 } … … 473 481 { 474 482 uint16_t ind[BLOCK_SIZE >> 1]; 475 uint16_t dind[BLOCK_SIZE >> 1];476 483 int block, result; 477 484 smallint blk_chg; … … 482 489 if (blknr < 512) { 483 490 block = check_zone_nr(inode->i_zone + 7, &changed); 484 read_block(block, (char *) ind); 485 blk_chg = 0; 486 result = check_zone_nr(blknr + ind, &blk_chg); 487 if (blk_chg) 488 write_block(block, (char *) ind); 489 return result; 491 goto common; 490 492 } 491 493 blknr -= 512; 492 494 block = check_zone_nr(inode->i_zone + 8, &changed); 493 read_block(block, (char *) dind);495 read_block(block, ind); /* double indirect */ 494 496 blk_chg = 0; 495 result = check_zone_nr( dind + (blknr / 512), &blk_chg);497 result = check_zone_nr(&ind[blknr / 512], &blk_chg); 496 498 if (blk_chg) 497 write_block(block, (char *) dind);499 write_block(block, ind); 498 500 block = result; 499 read_block(block, (char *) ind); 501 common: 502 read_block(block, ind); 500 503 blk_chg = 0; 501 result = check_zone_nr( ind + (blknr % 512), &blk_chg);504 result = check_zone_nr(&ind[blknr % 512], &blk_chg); 502 505 if (blk_chg) 503 write_block(block, (char *)ind);506 write_block(block, ind); 504 507 return result; 505 508 } … … 509 512 { 510 513 uint32_t ind[BLOCK_SIZE >> 2]; 511 uint32_t dind[BLOCK_SIZE >> 2];512 uint32_t tind[BLOCK_SIZE >> 2];513 514 int block, result; 514 515 smallint blk_chg; … … 519 520 if (blknr < 256) { 520 521 block = check_zone_nr2(inode->i_zone + 7, &changed); 521 read_block(block, (char *) ind); 522 blk_chg = 0; 523 result = check_zone_nr2(blknr + ind, &blk_chg); 524 if (blk_chg) 525 write_block(block, (char *) ind); 526 return result; 522 goto common2; 527 523 } 528 524 blknr -= 256; 529 if (blknr >=256 * 256) {525 if (blknr < 256 * 256) { 530 526 block = check_zone_nr2(inode->i_zone + 8, &changed); 531 read_block(block, (char *) dind); 532 blk_chg = 0; 533 result = check_zone_nr2(dind + blknr / 256, &blk_chg); 534 if (blk_chg) 535 write_block(block, (char *) dind); 536 block = result; 537 read_block(block, (char *) ind); 538 blk_chg = 0; 539 result = check_zone_nr2(ind + blknr % 256, &blk_chg); 540 if (blk_chg) 541 write_block(block, (char *) ind); 542 return result; 527 goto common1; 543 528 } 544 529 blknr -= 256 * 256; 545 530 block = check_zone_nr2(inode->i_zone + 9, &changed); 546 read_block(block, (char *) tind);531 read_block(block, ind); /* triple indirect */ 547 532 blk_chg = 0; 548 result = check_zone_nr2( tind + blknr / (256 * 256), &blk_chg);533 result = check_zone_nr2(&ind[blknr / (256 * 256)], &blk_chg); 549 534 if (blk_chg) 550 write_block(block, (char *) tind);535 write_block(block, ind); 551 536 block = result; 552 read_block(block, (char *) dind); 537 common1: 538 read_block(block, ind); /* double indirect */ 553 539 blk_chg = 0; 554 result = check_zone_nr2( dind + (blknr / 256) % 256, &blk_chg);540 result = check_zone_nr2(&ind[(blknr / 256) % 256], &blk_chg); 555 541 if (blk_chg) 556 write_block(block, (char *) dind);542 write_block(block, ind); 557 543 block = result; 558 read_block(block, (char *) ind); 544 common2: 545 read_block(block, ind); 559 546 blk_chg = 0; 560 result = check_zone_nr2( ind + blknr % 256, &blk_chg);547 result = check_zone_nr2(&ind[blknr % 256], &blk_chg); 561 548 if (blk_chg) 562 write_block(block, (char *)ind);549 write_block(block, ind); 563 550 return result; 564 551 } 565 552 #endif 566 553 567 static void write_super _block(void)554 static void write_superblock(void) 568 555 { 569 556 /* … … 576 563 Super.s_state &= ~MINIX_ERROR_FS; 577 564 578 if (BLOCK_SIZE != lseek(dev_fd, BLOCK_SIZE, SEEK_SET)) 579 die("seek failed in write_super_block"); 580 if (BLOCK_SIZE != write(dev_fd, super_block_buffer, BLOCK_SIZE)) 581 die("cannot write super-block"); 565 xlseek(dev_fd, BLOCK_SIZE, SEEK_SET); 566 if (BLOCK_SIZE != full_write(dev_fd, superblock_buffer, BLOCK_SIZE)) 567 die("can't write superblock"); 582 568 } 583 569 584 570 static void write_tables(void) 585 571 { 586 write_super _block();572 write_superblock(); 587 573 588 574 if (IMAPS * BLOCK_SIZE != write(dev_fd, inode_map, IMAPS * BLOCK_SIZE)) 589 die("can not write inode map");575 die("can't write inode map"); 590 576 if (ZMAPS * BLOCK_SIZE != write(dev_fd, zone_map, ZMAPS * BLOCK_SIZE)) 591 die("can not write zone map");577 die("can't write zone map"); 592 578 if (INODE_BUFFER_SIZE != write(dev_fd, inode_buffer, INODE_BUFFER_SIZE)) 593 die("can not write inodes");579 die("can't write inodes"); 594 580 } 595 581 … … 619 605 static void read_superblock(void) 620 606 { 621 if (BLOCK_SIZE != lseek(dev_fd, BLOCK_SIZE, SEEK_SET)) 622 die("seek failed"); 623 if (BLOCK_SIZE != read(dev_fd, super_block_buffer, BLOCK_SIZE)) 624 die("cannot read super block"); 607 xlseek(dev_fd, BLOCK_SIZE, SEEK_SET); 608 if (BLOCK_SIZE != full_read(dev_fd, superblock_buffer, BLOCK_SIZE)) 609 die("can't read superblock"); 625 610 /* already initialized to: 626 611 namelen = 14; … … 641 626 #endif 642 627 } else 643 die("bad magic number in super -block");628 die("bad magic number in superblock"); 644 629 if (ZONESIZE != 0 || BLOCK_SIZE != 1024) 645 630 die("only 1k blocks/zones supported"); 646 631 if (IMAPS * BLOCK_SIZE * 8 < INODES + 1) 647 die("bad s_imap_blocks field in super -block");632 die("bad s_imap_blocks field in superblock"); 648 633 if (ZMAPS * BLOCK_SIZE * 8 < ZONES - FIRSTZONE + 1) 649 die("bad s_zmap_blocks field in super -block");634 die("bad s_zmap_blocks field in superblock"); 650 635 } 651 636 … … 658 643 zone_count = xmalloc(ZONES); 659 644 if (IMAPS * BLOCK_SIZE != read(dev_fd, inode_map, IMAPS * BLOCK_SIZE)) 660 die("can not read inode map");645 die("can't read inode map"); 661 646 if (ZMAPS * BLOCK_SIZE != read(dev_fd, zone_map, ZMAPS * BLOCK_SIZE)) 662 die("can not read zone map");647 die("can't read zone map"); 663 648 if (INODE_BUFFER_SIZE != read(dev_fd, inode_buffer, INODE_BUFFER_SIZE)) 664 die("can not read inodes");649 die("can't read inodes"); 665 650 if (NORM_FIRSTZONE != FIRSTZONE) { 666 651 printf("warning: firstzone!=norm_firstzone\n"); … … 668 653 } 669 654 get_dirsize(); 670 if ( show) {655 if (OPT_show) { 671 656 printf("%u inodes\n" 672 657 "%u blocks\n" … … 686 671 } 687 672 688 static struct minix1_inode *get_inode(unsigned nr) 689 { 690 struct minix1_inode *inode; 691 692 if (!nr || nr > INODES) 693 return NULL; 673 static void get_inode_common(unsigned nr, uint16_t i_mode) 674 { 694 675 total++; 695 inode = Inode1 + nr;696 676 if (!inode_count[nr]) { 697 677 if (!inode_in_use(nr)) { 698 678 printf("Inode %d is marked as 'unused', but it is used " 699 679 "for file '%s'\n", nr, current_name); 700 if ( repair) {680 if (OPT_repair) { 701 681 if (ask("Mark as 'in use'", 1)) 702 682 mark_inode(nr); … … 705 685 } 706 686 } 707 if (S_ISDIR(i node->i_mode))687 if (S_ISDIR(i_mode)) 708 688 directory++; 709 else if (S_ISREG(i node->i_mode))689 else if (S_ISREG(i_mode)) 710 690 regular++; 711 else if (S_ISCHR(i node->i_mode))691 else if (S_ISCHR(i_mode)) 712 692 chardev++; 713 else if (S_ISBLK(i node->i_mode))693 else if (S_ISBLK(i_mode)) 714 694 blockdev++; 715 else if (S_ISLNK(i node->i_mode))695 else if (S_ISLNK(i_mode)) 716 696 symlinks++; 717 else if (S_ISSOCK(i node->i_mode));718 else if (S_ISFIFO(i node->i_mode));697 else if (S_ISSOCK(i_mode)); 698 else if (S_ISFIFO(i_mode)); 719 699 else { 720 printf("%s has mode %05o\n", current_name, inode->i_mode); 721 } 722 700 printf("%s has mode %05o\n", current_name, i_mode); 701 } 723 702 } else 724 703 links++; … … 728 707 errors_uncorrected = 1; 729 708 } 730 return inode; 731 } 732 733 #if ENABLE_FEATURE_MINIX2 734 static struct minix2_inode *get_inode2(unsigned nr) 735 { 736 struct minix2_inode *inode; 709 } 710 711 static struct minix1_inode *get_inode(unsigned nr) 712 { 713 struct minix1_inode *inode; 737 714 738 715 if (!nr || nr > INODES) 739 716 return NULL; 740 total++; 717 inode = Inode1 + nr; 718 get_inode_common(nr, inode->i_mode); 719 return inode; 720 } 721 722 #if ENABLE_FEATURE_MINIX2 723 static struct minix2_inode *get_inode2(unsigned nr) 724 { 725 struct minix2_inode *inode; 726 727 if (!nr || nr > INODES) 728 return NULL; 741 729 inode = Inode2 + nr; 742 if (!inode_count[nr]) { 743 if (!inode_in_use(nr)) { 744 printf("Inode %d is marked as 'unused', but it is used " 745 "for file '%s'\n", nr, current_name); 746 if (repair) { 747 if (ask("Mark as 'in use'", 1)) 748 mark_inode(nr); 749 else 750 errors_uncorrected = 1; 751 } 752 } 753 if (S_ISDIR(inode->i_mode)) 754 directory++; 755 else if (S_ISREG(inode->i_mode)) 756 regular++; 757 else if (S_ISCHR(inode->i_mode)) 758 chardev++; 759 else if (S_ISBLK(inode->i_mode)) 760 blockdev++; 761 else if (S_ISLNK(inode->i_mode)) 762 symlinks++; 763 else if (S_ISSOCK(inode->i_mode)); 764 else if (S_ISFIFO(inode->i_mode)); 765 else { 766 printf("%s has mode %05o\n", current_name, inode->i_mode); 767 } 768 } else 769 links++; 770 if (!++inode_count[nr]) { 771 printf("Warning: inode count too big\n"); 772 inode_count[nr]--; 773 errors_uncorrected = 1; 774 } 730 get_inode_common(nr, inode->i_mode); 775 731 return inode; 776 732 } … … 797 753 #endif 798 754 799 static int add_zone(uint16_t *znr, smallint *corrected) 800 { 801 int result; 802 int block; 803 804 result = 0; 805 block = check_zone_nr(znr, corrected); 755 static int add_zone_common(int block, smallint *corrected) 756 { 806 757 if (!block) 807 758 return 0; … … 810 761 current_name); 811 762 if (ask("Clear", 1)) { 812 *znr = 0;813 763 block = 0; 814 764 *corrected = 1; 815 return 0;765 return -1; /* "please zero out *znr" */ 816 766 } 817 767 } … … 827 777 } 828 778 779 static int add_zone(uint16_t *znr, smallint *corrected) 780 { 781 int block; 782 783 block = check_zone_nr(znr, corrected); 784 block = add_zone_common(block, corrected); 785 if (block == -1) { 786 *znr = 0; 787 block = 0; 788 } 789 return block; 790 } 791 829 792 #if ENABLE_FEATURE_MINIX2 830 793 static int add_zone2(uint32_t *znr, smallint *corrected) 831 794 { 832 int result;833 795 int block; 834 796 835 result = 0;836 797 block = check_zone_nr2(znr, corrected); 837 if (!block) 838 return 0; 839 if (zone_count[block]) { 840 printf("Already used block is reused in file '%s'. ", 841 current_name); 842 if (ask("Clear", 1)) { 843 *znr = 0; 844 block = 0; 845 *corrected = 1; 846 return 0; 847 } 848 } 849 if (!zone_in_use(block)) { 850 printf("Block %d in file '%s' is marked as 'unused'. ", 851 block, current_name); 852 if (ask("Correct", 1)) 853 mark_zone(block); 854 } 855 if (!++zone_count[block]) 856 zone_count[block]--; 798 block = add_zone_common(block, corrected); 799 if (block == -1) { 800 *znr = 0; 801 block = 0; 802 } 857 803 return block; 858 804 } … … 952 898 return; 953 899 inode = Inode1 + i; 954 if (!S_ISDIR(inode->i_mode) && !S_ISREG(inode->i_mode) && 955 !S_ISLNK(inode->i_mode)) return; 900 if (!S_ISDIR(inode->i_mode) 901 && !S_ISREG(inode->i_mode) 902 && !S_ISLNK(inode->i_mode) 903 ) { 904 return; 905 } 956 906 for (i = 0; i < 7; i++) 957 907 add_zone(i + inode->i_zone, &changed); … … 1019 969 return; 1020 970 push_filename(name); 1021 if ( list) {1022 if ( verbose)971 if (OPT_list) { 972 if (OPT_verbose) 1023 973 printf("%6d %07o %3d ", ino, inode->i_mode, inode->i_nlinks); 1024 974 printf("%s%s\n", current_name, S_ISDIR(inode->i_mode) ? ":" : ""); … … 1069 1019 return; 1070 1020 push_filename(name); 1071 if ( list) {1072 if ( verbose)1021 if (OPT_list) { 1022 if (OPT_verbose) 1073 1023 printf("%6d %07o %3d ", ino, inode->i_mode, inode->i_nlinks); 1074 1024 printf("%s%s\n", current_name, S_ISDIR(inode->i_mode) ? ":" : ""); … … 1119 1069 char buffer[BLOCK_SIZE]; 1120 1070 1121 if (BLOCK_SIZE * i != lseek(dev_fd, BLOCK_SIZE * i, SEEK_SET)) 1122 die("seek failed in bad_zone"); 1123 return (BLOCK_SIZE != read(dev_fd, buffer, BLOCK_SIZE)); 1071 xlseek(dev_fd, BLOCK_SIZE * i, SEEK_SET); 1072 return (BLOCK_SIZE != full_read(dev_fd, buffer, BLOCK_SIZE)); 1124 1073 } 1125 1074 … … 1129 1078 1130 1079 for (i = 1; i <= INODES; i++) { 1131 if ( warn_mode && Inode1[i].i_mode && !inode_in_use(i)) {1080 if (OPT_warn_mode && Inode1[i].i_mode && !inode_in_use(i)) { 1132 1081 printf("Inode %d has non-zero mode. ", i); 1133 1082 if (ask("Clear", 1)) { … … 1181 1130 1182 1131 for (i = 1; i <= INODES; i++) { 1183 if ( warn_mode && Inode2[i].i_mode && !inode_in_use(i)) {1132 if (OPT_warn_mode && Inode2[i].i_mode && !inode_in_use(i)) { 1184 1133 printf("Inode %d has non-zero mode. ", i); 1185 1134 if (ask("Clear", 1)) { … … 1250 1199 #endif 1251 1200 1252 int fsck_minix_main(int argc, char **argv) ;1253 int fsck_minix_main(int argc , char **argv)1201 int fsck_minix_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 1202 int fsck_minix_main(int argc UNUSED_PARAM, char **argv) 1254 1203 { 1255 1204 struct termios tmp; … … 1260 1209 INIT_G(); 1261 1210 1262 if (INODE_SIZE1 * MINIX1_INODES_PER_BLOCK != BLOCK_SIZE) 1263 die("bad inode size"); 1264 #if ENABLE_FEATURE_MINIX2 1265 if (INODE_SIZE2 * MINIX2_INODES_PER_BLOCK != BLOCK_SIZE) 1266 die("bad v2 inode size"); 1267 #endif 1268 while (--argc != 0) { 1269 argv++; 1270 if (argv[0][0] != '-') { 1271 if (device_name) 1272 bb_show_usage(); 1273 device_name = argv[0]; 1274 } else { 1275 while (*++argv[0]) { 1276 switch (argv[0][0]) { 1277 case 'l': 1278 list = 1; 1279 break; 1280 case 'a': 1281 automatic = 1; 1282 repair = 1; 1283 break; 1284 case 'r': 1285 automatic = 0; 1286 repair = 1; 1287 break; 1288 case 'v': 1289 verbose = 1; 1290 break; 1291 case 's': 1292 show = 1; 1293 break; 1294 case 'm': 1295 warn_mode = 1; 1296 break; 1297 case 'f': 1298 force = 1; 1299 break; 1300 default: 1301 bb_show_usage(); 1302 } 1303 } 1304 } 1305 } 1306 if (!device_name) 1307 bb_show_usage(); 1308 1309 check_mount(); /* trying to check a mounted filesystem? */ 1310 if (repair && !automatic) { 1211 opt_complementary = "=1:ar"; /* one argument; -a assumes -r */ 1212 getopt32(argv, OPTION_STR); 1213 argv += optind; 1214 device_name = argv[0]; 1215 1216 check_mount(); /* trying to check a mounted filesystem? */ 1217 if (OPT_manual) { 1311 1218 if (!isatty(0) || !isatty(1)) 1312 1219 die("need terminal for interactive repairs"); 1313 1220 } 1314 dev_fd = xopen(device_name, repair ? O_RDWR : O_RDONLY);1221 xmove_fd(xopen(device_name, OPT_repair ? O_RDWR : O_RDONLY), dev_fd); 1315 1222 1316 1223 /*sync(); paranoia? */ … … 1326 1233 1327 1234 if (!(Super.s_state & MINIX_ERROR_FS) 1328 && (Super.s_state & MINIX_VALID_FS) && ! force1235 && (Super.s_state & MINIX_VALID_FS) && !OPT_force 1329 1236 ) { 1330 if ( repair)1237 if (OPT_repair) 1331 1238 printf("%s is clean, check is skipped\n", device_name); 1332 1239 return 0; 1333 } else if ( force)1240 } else if (OPT_force) 1334 1241 printf("Forcing filesystem check on %s\n", device_name); 1335 else if ( repair)1242 else if (OPT_repair) 1336 1243 printf("Filesystem on %s is dirty, needs checking\n", 1337 1244 device_name); … … 1339 1246 read_tables(); 1340 1247 1341 if ( repair && !automatic) {1248 if (OPT_manual) { 1342 1249 tcgetattr(0, &sv_termios); 1343 1250 tmp = sv_termios; 1344 1251 tmp.c_lflag &= ~(ICANON | ECHO); 1345 tcsetattr (0, TCSANOW,&tmp);1252 tcsetattr_stdin_TCSANOW(&tmp); 1346 1253 termios_set = 1; 1347 1254 } … … 1355 1262 } 1356 1263 1357 if ( verbose) {1264 if (OPT_verbose) { 1358 1265 int i, free_cnt; 1359 1266 … … 1384 1291 printf("FILE SYSTEM HAS BEEN CHANGED\n"); 1385 1292 sync(); 1386 } else if ( repair)1387 write_super _block();1388 1389 if ( repair && !automatic)1390 tcsetattr (0, TCSANOW,&sv_termios);1293 } else if (OPT_repair) 1294 write_superblock(); 1295 1296 if (OPT_manual) 1297 tcsetattr_stdin_TCSANOW(&sv_termios); 1391 1298 1392 1299 if (changed) -
branches/2.2.9/mindi-busybox/util-linux/getopt.c
r1765 r2725 4 4 * Copyright (c) 1997, 1998, 1999, 2000 Frodo Looijaard <frodol@dds.nl> 5 5 * 6 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.6 * Licensed under GPLv2 or later, see file LICENSE in this source tree. 7 7 */ 8 8 … … 23 23 * No important changes 24 24 * Version 1.1.0: Tue Jun 30 2000 25 * Added NLS support (partly written by Arkadiusz Mi <B6>kiewicz25 * Added NLS support (partly written by Arkadiusz Mickiewicz 26 26 * <misiek@misiek.eu.org>) 27 27 * Ported to Busybox - Alfred M. Szmidt <ams@trillian.itslinux.org> … … 39 39 enum { 40 40 NON_OPT = 1, 41 #if ENABLE_ GETOPT_LONG41 #if ENABLE_FEATURE_GETOPT_LONG 42 42 /* LONG_OPT is the code that is returned when a long option is found. */ 43 43 LONG_OPT = 2 … … 54 54 OPT_T = 0x20, // -T 55 55 OPT_u = 0x40, // -u 56 #if ENABLE_ GETOPT_LONG56 #if ENABLE_FEATURE_GETOPT_LONG 57 57 OPT_a = 0x80, // -a 58 58 OPT_l = 0x100, // -l … … 142 142 * Other settings are found in global variables. 143 143 */ 144 #if !ENABLE_GETOPT_LONG 145 #define generate_output(argv,argc,optstr,longopts) generate_output(argv,argc,optstr) 144 #if !ENABLE_FEATURE_GETOPT_LONG 145 #define generate_output(argv,argc,optstr,longopts) \ 146 generate_output(argv,argc,optstr) 146 147 #endif 147 148 static int generate_output(char **argv, int argc, const char *optstr, const struct option *longopts) 148 149 { 149 150 int exit_code = 0; /* We assume everything will be OK */ 150 unsignedopt;151 #if ENABLE_ GETOPT_LONG151 int opt; 152 #if ENABLE_FEATURE_GETOPT_LONG 152 153 int longindex; 153 154 #endif … … 156 157 if (quiet_errors) /* No error reporting from getopt(3) */ 157 158 opterr = 0; 158 optind = 0; /* Reset getopt(3) */ 159 160 /* We used it already in main() in getopt32(), 161 * we *must* reset getopt(3): */ 162 #ifdef __GLIBC__ 163 optind = 0; 164 #else /* BSD style */ 165 optind = 1; 166 /* optreset = 1; */ 167 #endif 159 168 160 169 while (1) { 161 170 opt = 162 #if ENABLE_ GETOPT_LONG171 #if ENABLE_FEATURE_GETOPT_LONG 163 172 alternative ? 164 173 getopt_long_only(argc, argv, optstr, longopts, &longindex) : … … 167 176 getopt(argc, argv, optstr); 168 177 #endif 169 if (opt == EOF)178 if (opt == -1) 170 179 break; 171 180 if (opt == '?' || opt == ':' ) 172 181 exit_code = 1; 173 182 else if (!quiet_output) { 174 #if ENABLE_ GETOPT_LONG183 #if ENABLE_FEATURE_GETOPT_LONG 175 184 if (opt == LONG_OPT) { 176 185 printf(" --%s", longopts[longindex].name); … … 184 193 else { 185 194 printf(" -%c", opt); 186 charptr = strchr(optstr, opt);195 charptr = strchr(optstr, opt); 187 196 if (charptr != NULL && *++charptr == ':') 188 197 printf(" %s", … … 196 205 while (optind < argc) 197 206 printf(" %s", normalize(argv[optind++])); 198 puts("");207 bb_putchar('\n'); 199 208 } 200 209 return exit_code; 201 210 } 202 211 203 #if ENABLE_ GETOPT_LONG212 #if ENABLE_FEATURE_GETOPT_LONG 204 213 /* 205 214 * Register several long options. options is a string of long options, … … 232 241 bb_error_msg_and_die("empty long option specified"); 233 242 } 234 long_options = xrealloc(long_options, 235 sizeof(long_options[0]) * (long_nr+2)); 243 long_options = xrealloc_vector(long_options, 4, long_nr); 236 244 long_options[long_nr].has_arg = arg_opt; 237 long_options[long_nr].flag = NULL;245 /*long_options[long_nr].flag = NULL; - xrealloc_vector did it */ 238 246 long_options[long_nr].val = LONG_OPT; 239 247 long_options[long_nr].name = xstrdup(tokptr); 240 248 long_nr++; 241 memset(&long_options[long_nr], 0, sizeof(long_options[0]));249 /*memset(&long_options[long_nr], 0, sizeof(long_options[0])); - xrealloc_vector did it */ 242 250 } 243 251 tokptr = strtok(NULL, ", \t\n"); … … 249 257 static void set_shell(const char *new_shell) 250 258 { 251 if (!strcmp(new_shell, "bash") || !strcmp(new_shell,"sh"))259 if (!strcmp(new_shell, "bash") || !strcmp(new_shell, "sh")) 252 260 return; 253 if (!strcmp(new_shell, "tcsh") || !strcmp(new_shell,"csh"))261 if (!strcmp(new_shell, "tcsh") || !strcmp(new_shell, "csh")) 254 262 option_mask32 |= SHELL_IS_TCSH; 255 263 else … … 266 274 */ 267 275 268 #if ENABLE_ GETOPT_LONG276 #if ENABLE_FEATURE_GETOPT_LONG 269 277 static const char getopt_longopts[] ALIGN1 = 270 278 "options\0" Required_argument "o" … … 280 288 #endif 281 289 282 int getopt_main(int argc, char * argv[]);283 int getopt_main(int argc, char * argv[])290 int getopt_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 291 int getopt_main(int argc, char **argv) 284 292 { 285 293 char *optstr = NULL; … … 288 296 const char *compatible; 289 297 char *s_arg; 290 #if ENABLE_ GETOPT_LONG298 #if ENABLE_FEATURE_GETOPT_LONG 291 299 struct option *long_options = NULL; 292 300 llist_t *l_arg = NULL; … … 314 322 } 315 323 316 #if !ENABLE_ GETOPT_LONG324 #if !ENABLE_FEATURE_GETOPT_LONG 317 325 opt = getopt32(argv, "+o:n:qQs:Tu", &optstr, &name, &s_arg); 318 326 #else … … 323 331 /* Effectuate the read options for the applet itself */ 324 332 while (l_arg) { 325 long_options = add_long_options(long_options, l_arg->data); 326 l_arg = l_arg->link; 333 long_options = add_long_options(long_options, llist_pop(&l_arg)); 327 334 } 328 335 #endif -
branches/2.2.9/mindi-busybox/util-linux/hexdump.c
r1765 r2725 5 5 * 6 6 * Copyright (c) 1989 7 * 7 * The Regents of the University of California. All rights reserved. 8 8 * 9 * Licensed under GPLv2 or later, see file L icense in this tarball for details.9 * Licensed under GPLv2 or later, see file LICENSE in this source tree. 10 10 */ 11 11 12 #include <getopt.h>13 12 #include "libbb.h" 14 13 #include "dump.h" … … 16 15 /* This is a NOEXEC applet. Be very careful! */ 17 16 18 19 static void bb_dump_addfile(char *name) 17 static void bb_dump_addfile(dumper_t *dumper, char *name) 20 18 { 21 19 char *p; … … 23 21 char *buf; 24 22 25 fp = xfopen(name, "r"); 26 27 while ((buf = xmalloc_getline(fp)) != NULL) { 23 fp = xfopen_for_read(name); 24 while ((buf = xmalloc_fgetline(fp)) != NULL) { 28 25 p = skip_whitespace(buf); 29 30 26 if (*p && (*p != '#')) { 31 bb_dump_add( p);27 bb_dump_add(dumper, p); 32 28 } 33 29 free(buf); … … 37 33 38 34 static const char *const add_strings[] = { 39 "\"%07.7_ax \" 16/1 \"%03o \" \"\\n\"", 40 "\"%07.7_ax \" 16/1 \"%3_c \" \"\\n\"", 41 "\"%07.7_ax \" 8/2 \" %05u \" \"\\n\"", 42 "\"%07.7_ax \" 8/2 \" %06o \" \"\\n\"", 43 "\"%07.7_ax \" 8/2 \" %04x \" \"\\n\"", 35 "\"%07.7_ax \" 16/1 \"%03o \" \"\\n\"", /* b */ 36 "\"%07.7_ax \" 16/1 \"%3_c \" \"\\n\"", /* c */ 37 "\"%07.7_ax \" 8/2 \" %05u \" \"\\n\"", /* d */ 38 "\"%07.7_ax \" 8/2 \" %06o \" \"\\n\"", /* o */ 39 "\"%07.7_ax \" 8/2 \" %04x \" \"\\n\"", /* x */ 44 40 }; 45 41 46 42 static const char add_first[] ALIGN1 = "\"%07.7_Ax\n\""; 47 43 48 static const char hexdump_opts[] ALIGN1 = "bcdoxCe:f:n:s:v" ;44 static const char hexdump_opts[] ALIGN1 = "bcdoxCe:f:n:s:v" IF_FEATURE_HEXDUMP_REVERSE("R"); 49 45 50 46 static const struct suffix_mult suffixes[] = { … … 52 48 { "k", 1024 }, 53 49 { "m", 1024*1024 }, 54 { }50 { "", 0 } 55 51 }; 56 52 57 int hexdump_main(int argc, char **argv) ;53 int hexdump_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 58 54 int hexdump_main(int argc, char **argv) 59 55 { 56 dumper_t *dumper = alloc_dumper(); 60 57 const char *p; 61 58 int ch; 59 #if ENABLE_FEATURE_HEXDUMP_REVERSE 60 FILE *fp; 61 smallint rdump = 0; 62 #endif 62 63 63 bb_dump_vflag = FIRST; 64 bb_dump_length = -1; 64 if (ENABLE_HD && !applet_name[2]) { /* we are "hd" */ 65 ch = 'C'; 66 goto hd_applet; 67 } 65 68 69 /* We cannot use getopt32: in hexdump options are cumulative. 70 * E.g. "hexdump -C -C file" should dump each line twice */ 66 71 while ((ch = getopt(argc, argv, hexdump_opts)) > 0) { 67 72 p = strchr(hexdump_opts, ch); … … 69 74 bb_show_usage(); 70 75 if ((p - hexdump_opts) < 5) { 71 bb_dump_add(add_first); 72 bb_dump_add(add_strings[(int)(p - hexdump_opts)]); 73 } else if (ch == 'C') { 74 bb_dump_add("\"%08.8_Ax\n\""); 75 bb_dump_add("\"%08.8_ax \" 8/1 \"%02x \" \" \" 8/1 \"%02x \" "); 76 bb_dump_add("\" |\" 16/1 \"%_p\" \"|\\n\""); 77 } else { 78 /* Save a little bit of space below by omitting the 'else's. */ 79 if (ch == 'e') { 80 bb_dump_add(optarg); 81 } /* else */ 82 if (ch == 'f') { 83 bb_dump_addfile(optarg); 84 } /* else */ 85 if (ch == 'n') { 86 bb_dump_length = xatoi_u(optarg); 87 } /* else */ 88 if (ch == 's') { 89 bb_dump_skip = xatoul_range_sfx(optarg, 0, LONG_MAX, suffixes); 90 } /* else */ 91 if (ch == 'v') { 92 bb_dump_vflag = ALL; 93 } 76 bb_dump_add(dumper, add_first); 77 bb_dump_add(dumper, add_strings[(int)(p - hexdump_opts)]); 94 78 } 79 /* Save a little bit of space below by omitting the 'else's. */ 80 if (ch == 'C') { 81 hd_applet: 82 bb_dump_add(dumper, "\"%08.8_Ax\n\""); 83 bb_dump_add(dumper, "\"%08.8_ax \" 8/1 \"%02x \" \" \" 8/1 \"%02x \" "); 84 bb_dump_add(dumper, "\" |\" 16/1 \"%_p\" \"|\\n\""); 85 } 86 if (ch == 'e') { 87 bb_dump_add(dumper, optarg); 88 } /* else */ 89 if (ch == 'f') { 90 bb_dump_addfile(dumper, optarg); 91 } /* else */ 92 if (ch == 'n') { 93 dumper->dump_length = xatoi_positive(optarg); 94 } /* else */ 95 if (ch == 's') { /* compat: -s accepts hex numbers too */ 96 dumper->dump_skip = xstrtoul_range_sfx(optarg, /*base:*/ 0, /*lo:*/ 0, /*hi:*/ LONG_MAX, suffixes); 97 } /* else */ 98 if (ch == 'v') { 99 dumper->dump_vflag = ALL; 100 } 101 #if ENABLE_FEATURE_HEXDUMP_REVERSE 102 if (ch == 'R') { 103 rdump = 1; 104 } 105 #endif 95 106 } 96 107 97 if (! bb_dump_fshead) {98 bb_dump_add( add_first);99 bb_dump_add( "\"%07.7_ax \" 8/2 \"%04x \" \"\\n\"");108 if (!dumper->fshead) { 109 bb_dump_add(dumper, add_first); 110 bb_dump_add(dumper, "\"%07.7_ax \" 8/2 \"%04x \" \"\\n\""); 100 111 } 101 112 102 113 argv += optind; 103 114 104 return bb_dump_dump(argv); 115 #if !ENABLE_FEATURE_HEXDUMP_REVERSE 116 return bb_dump_dump(dumper, argv); 117 #else 118 if (!rdump) { 119 return bb_dump_dump(dumper, argv); 120 } 121 122 /* -R: reverse of 'hexdump -Cv' */ 123 fp = stdin; 124 if (!*argv) { 125 argv--; 126 goto jump_in; 127 } 128 129 do { 130 char *buf; 131 fp = xfopen_for_read(*argv); 132 jump_in: 133 while ((buf = xmalloc_fgetline(fp)) != NULL) { 134 p = buf; 135 while (1) { 136 /* skip address or previous byte */ 137 while (isxdigit(*p)) p++; 138 while (*p == ' ') p++; 139 /* '|' char will break the line */ 140 if (!isxdigit(*p) || sscanf(p, "%x ", &ch) != 1) 141 break; 142 putchar(ch); 143 } 144 free(buf); 145 } 146 fclose(fp); 147 } while (*++argv); 148 149 fflush_stdout_and_exit(EXIT_SUCCESS); 150 #endif 105 151 } -
branches/2.2.9/mindi-busybox/util-linux/hwclock.c
r1765 r2725 5 5 * Copyright (C) 2002 Robert Griebl <griebl@gmx.de> 6 6 * 7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.7 * Licensed under GPLv2 or later, see file LICENSE in this source tree. 8 8 */ 9 9 10 #include "libbb.h" 11 /* After libbb.h, since it needs sys/types.h on some systems */ 10 12 #include <sys/utsname.h> 11 #include <getopt.h> 12 #include "libbb.h" 13 14 /* Copied from linux/rtc.h to eliminate the kernel dependency */ 15 struct linux_rtc_time { 16 int tm_sec; 17 int tm_min; 18 int tm_hour; 19 int tm_mday; 20 int tm_mon; 21 int tm_year; 22 int tm_wday; 23 int tm_yday; 24 int tm_isdst; 25 }; 26 27 #define RTC_SET_TIME _IOW('p', 0x0a, struct linux_rtc_time) /* Set RTC time */ 28 #define RTC_RD_TIME _IOR('p', 0x09, struct linux_rtc_time) /* Read RTC time */ 29 30 #if ENABLE_FEATURE_HWCLOCK_LONG_OPTIONS 31 # ifndef _GNU_SOURCE 32 # define _GNU_SOURCE 33 # endif 34 #endif 35 36 static const char *rtcname; 37 38 static int xopen_rtc(int flags) 39 { 40 int rtc; 41 42 if (!rtcname) { 43 rtc = open("/dev/rtc", flags); 44 if (rtc >= 0) 45 return rtc; 46 rtc = open("/dev/rtc0", flags); 47 if (rtc >= 0) 48 return rtc; 49 rtcname = "/dev/misc/rtc"; 50 } 51 return xopen(rtcname, flags); 52 } 53 54 static time_t read_rtc(int utc) 55 { 56 struct tm tm; 57 char *oldtz = 0; 58 time_t t = 0; 59 int rtc = xopen_rtc(O_RDONLY); 60 61 memset(&tm, 0, sizeof(struct tm)); 62 xioctl(rtc, RTC_RD_TIME, &tm); 63 tm.tm_isdst = -1; /* not known */ 64 65 close(rtc); 66 67 if (utc) { 68 oldtz = getenv("TZ"); 69 putenv((char*)"TZ=UTC0"); 70 tzset(); 71 } 72 73 t = mktime(&tm); 74 75 if (utc) { 76 unsetenv("TZ"); 77 if (oldtz) 78 putenv(oldtz - 3); 79 tzset(); 80 } 81 return t; 82 } 83 84 static void write_rtc(time_t t, int utc) 85 { 86 struct tm tm; 87 int rtc = xopen_rtc(O_WRONLY); 88 89 tm = *(utc ? gmtime(&t) : localtime(&t)); 90 tm.tm_isdst = 0; 91 92 xioctl(rtc, RTC_SET_TIME, &tm); 93 94 close(rtc); 95 } 96 97 static void show_clock(int utc) 98 { 99 //struct tm *ptm; 13 #include "rtc_.h" 14 15 /* diff code is disabled: it's not sys/hw clock diff, it's some useless 16 * "time between hwclock was started and we saw CMOS tick" quantity. 17 * It's useless since hwclock is started at a random moment, 18 * thus the quantity is also random, useless. Showing 0.000000 does not 19 * deprive us from any useful info. 20 * 21 * SHOW_HWCLOCK_DIFF code in this file shows the difference between system 22 * and hw clock. It is useful, but not compatible with standard hwclock. 23 * Thus disabled. 24 */ 25 #define SHOW_HWCLOCK_DIFF 0 26 27 28 #if !SHOW_HWCLOCK_DIFF 29 # define read_rtc(pp_rtcname, sys_tv, utc) read_rtc(pp_rtcname, utc) 30 #endif 31 static time_t read_rtc(const char **pp_rtcname, struct timeval *sys_tv, int utc) 32 { 33 struct tm tm_time; 34 int fd; 35 36 fd = rtc_xopen(pp_rtcname, O_RDONLY); 37 38 rtc_read_tm(&tm_time, fd); 39 40 #if SHOW_HWCLOCK_DIFF 41 { 42 int before = tm_time.tm_sec; 43 while (1) { 44 rtc_read_tm(&tm_time, fd); 45 gettimeofday(sys_tv, NULL); 46 if (before != tm_time.tm_sec) 47 break; 48 } 49 } 50 #endif 51 52 if (ENABLE_FEATURE_CLEAN_UP) 53 close(fd); 54 55 return rtc_tm2time(&tm_time, utc); 56 } 57 58 static void show_clock(const char **pp_rtcname, int utc) 59 { 60 #if SHOW_HWCLOCK_DIFF 61 struct timeval sys_tv; 62 #endif 100 63 time_t t; 101 64 char *cp; 102 65 103 t = read_rtc(utc); 104 //ptm = localtime(&t); /* Sets 'tzname[]' */ 105 66 t = read_rtc(pp_rtcname, &sys_tv, utc); 106 67 cp = ctime(&t); 107 if (cp[0]) 108 cp[strlen(cp) - 1] = '\0'; 109 110 //printf("%s %.6f seconds %s\n", cp, 0.0, utc ? "" : (ptm->tm_isdst ? tzname[1] : tzname[0])); 68 strchrnul(cp, '\n')[0] = '\0'; 69 #if !SHOW_HWCLOCK_DIFF 111 70 printf("%s 0.000000 seconds\n", cp); 112 } 113 114 static void to_sys_clock(int utc) 71 #else 72 { 73 long diff = sys_tv.tv_sec - t; 74 if (diff < 0 /*&& tv.tv_usec != 0*/) { 75 /* Why? */ 76 /* diff >= 0 is ok: diff < 0, can't just use tv.tv_usec: */ 77 /* 45.520820 43.520820 */ 78 /* - 44.000000 - 45.000000 */ 79 /* = 1.520820 = -1.479180, not -2.520820! */ 80 diff++; 81 /* should be 1000000 - tv.tv_usec, but then we must check tv.tv_usec != 0 */ 82 sys_tv.tv_usec = 999999 - sys_tv.tv_usec; 83 } 84 printf("%s %ld.%06lu seconds\n", cp, diff, (unsigned long)sys_tv.tv_usec); 85 } 86 #endif 87 } 88 89 static void to_sys_clock(const char **pp_rtcname, int utc) 115 90 { 116 91 struct timeval tv; 117 const struct timezone tz = { timezone/60 - 60*daylight, 0 }; 118 119 tv.tv_sec = read_rtc(utc); 92 struct timezone tz; 93 94 tz.tz_minuteswest = timezone/60 - 60*daylight; 95 tz.tz_dsttime = 0; 96 97 tv.tv_sec = read_rtc(pp_rtcname, NULL, utc); 120 98 tv.tv_usec = 0; 121 99 if (settimeofday(&tv, &tz)) 122 bb_perror_msg_and_die("settimeofday() failed"); 123 } 124 125 static void from_sys_clock(int utc) 126 { 100 bb_perror_msg_and_die("settimeofday"); 101 } 102 103 static void from_sys_clock(const char **pp_rtcname, int utc) 104 { 105 #if 1 127 106 struct timeval tv; 128 107 struct tm tm_time; 108 int rtc; 109 110 rtc = rtc_xopen(pp_rtcname, O_WRONLY); 129 111 gettimeofday(&tv, NULL); 130 //if (gettimeofday(&tv, NULL)) 131 // bb_perror_msg_and_die("gettimeofday() failed"); 132 write_rtc(tv.tv_sec, utc); 133 } 134 135 #if ENABLE_FEATURE_HWCLOCK_ADJTIME_FHS 136 # define ADJTIME_PATH "/var/lib/hwclock/adjtime" 112 /* Prepare tm_time */ 113 if (sizeof(time_t) == sizeof(tv.tv_sec)) { 114 if (utc) 115 gmtime_r((time_t*)&tv.tv_sec, &tm_time); 116 else 117 localtime_r((time_t*)&tv.tv_sec, &tm_time); 118 } else { 119 time_t t = tv.tv_sec; 120 if (utc) 121 gmtime_r(&t, &tm_time); 122 else 123 localtime_r(&t, &tm_time); 124 } 137 125 #else 138 # define ADJTIME_PATH "/etc/adjtime" 139 #endif 140 static int check_utc(void) 141 { 142 int utc = 0; 143 FILE *f = fopen(ADJTIME_PATH, "r"); 144 145 if (f) { 146 RESERVE_CONFIG_BUFFER(buffer, 128); 147 148 while (fgets(buffer, sizeof(buffer), f)) { 149 int len = strlen(buffer); 150 151 while (len && isspace(buffer[len - 1])) 152 len--; 153 154 buffer[len] = 0; 155 156 if (strncmp(buffer, "UTC", 3) == 0) { 157 utc = 1; 158 break; 159 } 160 } 161 fclose(f); 162 RELEASE_CONFIG_BUFFER(buffer); 163 } 164 return utc; 126 /* Bloated code which tries to set hw clock with better precision. 127 * On x86, even though code does set hw clock within <1ms of exact 128 * whole seconds, apparently hw clock (at least on some machines) 129 * doesn't reset internal fractional seconds to 0, 130 * making all this a pointless excercise. 131 */ 132 /* If we see that we are N usec away from whole second, 133 * we'll sleep for N-ADJ usecs. ADJ corrects for the fact 134 * that CPU is not infinitely fast. 135 * On infinitely fast CPU, next wakeup would be 136 * on (exactly_next_whole_second - ADJ). On real CPUs, 137 * this difference between current time and whole second 138 * is less than ADJ (assuming system isn't heavily loaded). 139 */ 140 /* Small value of 256us gives very precise sync for 2+ GHz CPUs. 141 * Slower CPUs will fail to sync and will go to bigger 142 * ADJ values. qemu-emulated armv4tl with ~100 MHz 143 * performance ends up using ADJ ~= 4*1024 and it takes 144 * 2+ secs (2 tries with successively larger ADJ) 145 * to sync. Even straced one on the same qemu (very slow) 146 * takes only 4 tries. 147 */ 148 #define TWEAK_USEC 256 149 unsigned adj = TWEAK_USEC; 150 struct tm tm_time; 151 struct timeval tv; 152 int rtc = rtc_xopen(pp_rtcname, O_WRONLY); 153 154 /* Try to catch the moment when whole second is close */ 155 while (1) { 156 unsigned rem_usec; 157 time_t t; 158 159 gettimeofday(&tv, NULL); 160 161 t = tv.tv_sec; 162 rem_usec = 1000000 - tv.tv_usec; 163 if (rem_usec < adj) { 164 /* Close enough */ 165 small_rem: 166 t++; 167 } 168 169 /* Prepare tm_time from t */ 170 if (utc) 171 gmtime_r(&t, &tm_time); /* may read /etc/xxx (it takes time) */ 172 else 173 localtime_r(&t, &tm_time); /* same */ 174 175 if (adj >= 32*1024) { 176 break; /* 32 ms diff and still no luck?? give up trying to sync */ 177 } 178 179 /* gmtime/localtime took some time, re-get cur time */ 180 gettimeofday(&tv, NULL); 181 182 if (tv.tv_sec < t /* we are still in old second */ 183 || (tv.tv_sec == t && tv.tv_usec < adj) /* not too far into next second */ 184 ) { 185 break; /* good, we are in sync! */ 186 } 187 188 rem_usec = 1000000 - tv.tv_usec; 189 if (rem_usec < adj) { 190 t = tv.tv_sec; 191 goto small_rem; /* already close to next sec, don't sleep */ 192 } 193 194 /* Try to sync up by sleeping */ 195 usleep(rem_usec - adj); 196 197 /* Jump to 1ms diff, then increase fast (x2): EVERY loop 198 * takes ~1 sec, people won't like slowly converging code here! 199 */ 200 //bb_error_msg("adj:%d tv.tv_usec:%d", adj, (int)tv.tv_usec); 201 if (adj < 512) 202 adj = 512; 203 /* ... and if last "overshoot" does not look insanely big, 204 * just use it as adj increment. This makes convergence faster. 205 */ 206 if (tv.tv_usec < adj * 8) { 207 adj += tv.tv_usec; 208 continue; 209 } 210 adj *= 2; 211 } 212 /* Debug aid to find "optimal" TWEAK_USEC with nearly exact sync. 213 * Look for a value which makes tv_usec close to 999999 or 0. 214 * For 2.20GHz Intel Core 2: optimal TWEAK_USEC ~= 200 215 */ 216 //bb_error_msg("tv.tv_usec:%d", (int)tv.tv_usec); 217 #endif 218 219 tm_time.tm_isdst = 0; 220 xioctl(rtc, RTC_SET_TIME, &tm_time); 221 222 if (ENABLE_FEATURE_CLEAN_UP) 223 close(rtc); 165 224 } 166 225 … … 172 231 #define HWCLOCK_OPT_RTCFILE 0x20 173 232 174 int hwclock_main(int argc, char **argv); 175 int hwclock_main(int argc, char **argv) 176 { 233 int hwclock_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 234 int hwclock_main(int argc UNUSED_PARAM, char **argv) 235 { 236 const char *rtcname = NULL; 177 237 unsigned opt; 178 238 int utc; … … 194 254 /* If -u or -l wasn't given check if we are using utc */ 195 255 if (opt & (HWCLOCK_OPT_UTC | HWCLOCK_OPT_LOCALTIME)) 196 utc = opt & HWCLOCK_OPT_UTC;256 utc = (opt & HWCLOCK_OPT_UTC); 197 257 else 198 utc = check_utc(); 199 200 if (opt & HWCLOCK_OPT_HCTOSYS) { 201 to_sys_clock(utc); 202 return 0; 203 } 204 if (opt & HWCLOCK_OPT_SYSTOHC) { 205 from_sys_clock(utc); 206 return 0; 207 } 208 /* default HWCLOCK_OPT_SHOW */ 209 show_clock(utc); 258 utc = rtc_adjtime_is_utc(); 259 260 if (opt & HWCLOCK_OPT_HCTOSYS) 261 to_sys_clock(&rtcname, utc); 262 else if (opt & HWCLOCK_OPT_SYSTOHC) 263 from_sys_clock(&rtcname, utc); 264 else 265 /* default HWCLOCK_OPT_SHOW */ 266 show_clock(&rtcname, utc); 267 210 268 return 0; 211 269 } -
branches/2.2.9/mindi-busybox/util-linux/ipcrm.c
r1765 r2725 6 6 * Adapted for busybox from util-linux-2.12a. 7 7 * 8 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.8 * Licensed under GPLv2 or later, see file LICENSE in this source tree. 9 9 */ 10 10 … … 25 25 int val; 26 26 struct semid_ds *buf; 27 unsigned short int*array;27 unsigned short *array; 28 28 struct seminfo *__buf; 29 29 }; … … 41 41 } type_id; 42 42 43 static int remove_ids(type_id type, int argc,char **argv)43 static int remove_ids(type_id type, char **argv) 44 44 { 45 45 unsigned long id; 46 int ret = 0; /* silence gcc */47 46 int nb_errors = 0; 48 47 union semun arg; … … 50 49 arg.val = 0; 51 50 52 while (arg c) {51 while (argv[0]) { 53 52 id = bb_strtoul(argv[0], NULL, 10); 54 53 if (errno || id > INT_MAX) { … … 56 55 nb_errors++; 57 56 } else { 57 int ret = 0; 58 58 if (type == SEM) 59 59 ret = semctl(id, 0, IPC_RMID, arg); … … 64 64 65 65 if (ret) { 66 bb_perror_msg("can not remove id %s", argv[0]);66 bb_perror_msg("can't remove id %s", argv[0]); 67 67 nb_errors++; 68 68 } 69 69 } 70 argc--;71 70 argv++; 72 71 } … … 77 76 78 77 79 int ipcrm_main(int argc, char **argv) ;78 int ipcrm_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 80 79 int ipcrm_main(int argc, char **argv) 81 80 { … … 93 92 char w; 94 93 95 w =argv[1][0];94 w = argv[1][0]; 96 95 if ( ((w == 'm' && argv[1][1] == 's' && argv[1][2] == 'g') 97 96 || (argv[1][0] == 's' 98 && ((w =argv[1][1]) == 'h' || w == 'e')97 && ((w = argv[1][1]) == 'h' || w == 'e') 99 98 && argv[1][2] == 'm') 100 99 ) && argv[1][3] == '\0' 101 100 ) { 102 103 101 if (argc < 3) 104 102 bb_show_usage(); … … 111 109 what = SEM; 112 110 113 if (remove_ids(what, argc-2,&argv[2]))114 fflush_stdout_and_exit( 1);111 if (remove_ids(what, &argv[2])) 112 fflush_stdout_and_exit(EXIT_FAILURE); 115 113 printf("resource(s) deleted\n"); 116 114 return 0; … … 123 121 int result; 124 122 int id = 0; 125 int iskey = (isupper)(c);123 int iskey = isupper(c); 126 124 127 125 /* needed to delete semaphores */ -
branches/2.2.9/mindi-busybox/util-linux/ipcs.c
r1765 r2725 6 6 * Adapted for busybox from util-linux-2.12a. 7 7 * 8 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.8 * Licensed under GPLv2 or later, see file LICENSE in this source tree. 9 9 */ 10 10 … … 69 69 int val; 70 70 struct semid_ds *buf; 71 unsigned short int*array;71 unsigned short *array; 72 72 struct seminfo *__buf; 73 73 }; … … 100 100 printf("%-10d %-10o", id, ipcp->mode & 0777); 101 101 102 if ((pw = getpwuid(ipcp->cuid))) 103 printf(" %-10s", pw->pw_name); 104 else 105 printf(" %-10d", ipcp->cuid); 106 if ((gr = getgrgid(ipcp->cgid))) 107 printf(" %-10s", gr->gr_name); 108 else 109 printf(" %-10d", ipcp->cgid); 110 111 if ((pw = getpwuid(ipcp->uid))) 112 printf(" %-10s", pw->pw_name); 113 else 114 printf(" %-10d", ipcp->uid); 115 if ((gr = getgrgid(ipcp->gid))) 116 printf(" %-10s\n", gr->gr_name); 117 else 118 printf(" %-10d\n", ipcp->gid); 119 } 120 121 122 static void do_shm(void) 102 pw = getpwuid(ipcp->cuid); 103 if (pw) printf(" %-10s", pw->pw_name); 104 else printf(" %-10d", ipcp->cuid); 105 gr = getgrgid(ipcp->cgid); 106 if (gr) printf(" %-10s", gr->gr_name); 107 else printf(" %-10d", ipcp->cgid); 108 109 pw = getpwuid(ipcp->uid); 110 if (pw) printf(" %-10s", pw->pw_name); 111 else printf(" %-10d", ipcp->uid); 112 gr = getgrgid(ipcp->gid); 113 if (gr) printf(" %-10s\n", gr->gr_name); 114 else printf(" %-10d\n", ipcp->gid); 115 } 116 117 118 static NOINLINE void do_shm(void) 123 119 { 124 120 int maxid, shmid, id; … … 247 243 248 244 249 static void do_sem(void)245 static NOINLINE void do_sem(void) 250 246 { 251 247 int maxid, semid, id; … … 353 349 354 350 355 static void do_msg(void)351 static NOINLINE void do_msg(void) 356 352 { 357 353 int maxid, msqid, id; … … 560 556 printf("%-10d %-10d %-10d %-10d %-10d\n", i, val, ncnt, zcnt, pid); 561 557 } 562 puts("");563 } 564 565 int ipcs_main(int argc, char **argv) ;566 int ipcs_main(int argc , char **argv)558 bb_putchar('\n'); 559 } 560 561 int ipcs_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 562 int ipcs_main(int argc UNUSED_PARAM, char **argv) 567 563 { 568 564 int id = 0; … … 593 589 if (flags & flag_shm) { 594 590 print_shm(id); 595 fflush_stdout_and_exit( 0);591 fflush_stdout_and_exit(EXIT_SUCCESS); 596 592 } 597 593 if (flags & flag_sem) { 598 594 print_sem(id); 599 fflush_stdout_and_exit( 0);595 fflush_stdout_and_exit(EXIT_SUCCESS); 600 596 } 601 597 if (flags & flag_msg) { 602 598 print_msg(id); 603 fflush_stdout_and_exit( 0);599 fflush_stdout_and_exit(EXIT_SUCCESS); 604 600 } 605 601 bb_show_usage(); … … 608 604 if (!(flags & (flag_shm | flag_msg | flag_sem))) 609 605 flags |= flag_msg | flag_shm | flag_sem; 610 puts("");606 bb_putchar('\n'); 611 607 612 608 if (flags & flag_shm) { 613 609 do_shm(); 614 puts("");610 bb_putchar('\n'); 615 611 } 616 612 if (flags & flag_sem) { 617 613 do_sem(); 618 puts("");614 bb_putchar('\n'); 619 615 } 620 616 if (flags & flag_msg) { 621 617 do_msg(); 622 puts("");623 } 624 fflush_stdout_and_exit( 0);625 } 618 bb_putchar('\n'); 619 } 620 fflush_stdout_and_exit(EXIT_SUCCESS); 621 } -
branches/2.2.9/mindi-busybox/util-linux/losetup.c
r1765 r2725 5 5 * Copyright (C) 2002 Matt Kraai. 6 6 * 7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.7 * Licensed under GPLv2 or later, see file LICENSE in this source tree. 8 8 */ 9 10 #include <getopt.h>11 9 12 10 #include "libbb.h" 13 11 14 int losetup_main(int argc, char **argv) ;15 int losetup_main(int argc , char **argv)12 int losetup_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 13 int losetup_main(int argc UNUSED_PARAM, char **argv) 16 14 { 17 15 unsigned opt; 16 int n; 18 17 char *opt_o; 19 18 unsigned long long offset = 0; 19 enum { 20 OPT_d = (1 << 0), 21 OPT_o = (1 << 1), 22 OPT_f = (1 << 2), 23 }; 20 24 21 opt = getopt32(argv, "do:", &opt_o); 22 argc -= optind; 25 /* max 2 args, all opts are mutually exclusive */ 26 opt_complementary = "?2:d--of:o--df:f--do"; 27 opt = getopt32(argv, "do:f", &opt_o); 23 28 argv += optind; 24 29 25 if (opt == 0x3) // -d + -o (illegal)26 bb_show_usage();30 if (opt == OPT_o) 31 offset = xatoull(opt_o); 27 32 28 if (opt == 0x1) { // -d29 /* detach takes exactly one argument*/30 if ( argc != 1)33 if (opt == OPT_d) { 34 /* -d BLOCKDEV */ 35 if (!argv[0] || argv[1]) 31 36 bb_show_usage(); 32 if ( !del_loop(argv[0]))33 return EXIT_SUCCESS;34 bb_perror_nomsg_and_die();37 if (del_loop(argv[0])) 38 bb_simple_perror_msg_and_die(argv[0]); 39 return EXIT_SUCCESS; 35 40 } 36 41 37 if ( opt == 0x2) // -o38 offset = xatoull(opt_o);42 if (argv[0]) { 43 char *s; 39 44 40 /* -o or no option */ 45 if (opt == OPT_f) /* -f should not have arguments */ 46 bb_show_usage(); 41 47 42 if (argc == 2) { 43 if (set_loop(&argv[0], argv[1], offset) < 0) 44 bb_perror_nomsg_and_die(); 45 } else if (argc == 1) { 46 char *s = query_loop(argv[0]); 48 if (argv[1]) { 49 /* [-o OFS] BLOCKDEV FILE */ 50 if (set_loop(&argv[0], argv[1], offset) < 0) 51 bb_simple_perror_msg_and_die(argv[0]); 52 return EXIT_SUCCESS; 53 } 54 /* [-o OFS] BLOCKDEV */ 55 s = query_loop(argv[0]); 47 56 if (!s) 48 bb_ perror_nomsg_and_die();57 bb_simple_perror_msg_and_die(argv[0]); 49 58 printf("%s: %s\n", argv[0], s); 50 59 if (ENABLE_FEATURE_CLEAN_UP) 51 60 free(s); 52 } else { 53 char dev[sizeof(LOOP_NAME"0")] = LOOP_NAME"0"; 54 char c; 55 for (c = '0'; c <= '9'; ++c) { 56 char *s; 57 dev[sizeof(LOOP_NAME"0")-2] = c; 58 s = query_loop(dev); 59 if (s) { 61 return EXIT_SUCCESS; 62 } 63 64 /* [-o OFS|-f] with no params */ 65 n = 0; 66 while (1) { 67 char *s; 68 char dev[LOOP_NAMESIZE]; 69 70 sprintf(dev, LOOP_FORMAT, n); 71 s = query_loop(dev); 72 n++; 73 if (!s) { 74 if (n > 9 && errno && errno != ENXIO) 75 return EXIT_SUCCESS; 76 if (opt == OPT_f) { 77 puts(dev); 78 return EXIT_SUCCESS; 79 } 80 } else { 81 if (opt != OPT_f) 60 82 printf("%s: %s\n", dev, s); 61 if (ENABLE_FEATURE_CLEAN_UP) 62 free(s); 63 } 83 if (ENABLE_FEATURE_CLEAN_UP) 84 free(s); 64 85 } 65 86 } -
branches/2.2.9/mindi-busybox/util-linux/mdev.c
r1765 r2725 1 1 /* vi: set sw=4 ts=4: */ 2 2 /* 3 *4 3 * mdev - Mini udev for busybox 5 4 * … … 7 6 * Copyright 2005 Frank Sorenson <frank@tuxrocks.com> 8 7 * 9 * Licensed under GPL version 2, see file LICENSE in this tarball for details.8 * Licensed under GPLv2, see file LICENSE in this source tree. 10 9 */ 11 12 10 #include "libbb.h" 13 11 #include "xregex.h" 14 12 13 /* "mdev -s" scans /sys/class/xxx, looking for directories which have dev 14 * file (it is of the form "M:m\n"). Example: /sys/class/tty/tty0/dev 15 * contains "4:0\n". Directory name is taken as device name, path component 16 * directly after /sys/class/ as subsystem. In this example, "tty0" and "tty". 17 * Then mdev creates the /dev/device_name node. 18 * If /sys/class/.../dev file does not exist, mdev still may act 19 * on this device: see "@|$|*command args..." parameter in config file. 20 * 21 * mdev w/o parameters is called as hotplug helper. It takes device 22 * and subsystem names from $DEVPATH and $SUBSYSTEM, extracts 23 * maj,min from "/sys/$DEVPATH/dev" and also examines 24 * $ACTION ("add"/"delete") and $FIRMWARE. 25 * 26 * If action is "add", mdev creates /dev/device_name similarly to mdev -s. 27 * (todo: explain "delete" and $FIRMWARE) 28 * 29 * If /etc/mdev.conf exists, it may modify /dev/device_name's properties. 30 * /etc/mdev.conf file format: 31 * 32 * [-][subsystem/]device user:grp mode [>|=path] [@|$|*command args...] 33 * [-]@maj,min[-min2] user:grp mode [>|=path] [@|$|*command args...] 34 * [-]$envvar=val user:grp mode [>|=path] [@|$|*command args...] 35 * 36 * Leading minus in 1st field means "don't stop on this line", otherwise 37 * search is stopped after the matching line is encountered. 38 * 39 * The device name or "subsystem/device" combo is matched against 1st field 40 * (which is a regex), or maj,min is matched against 1st field, 41 * or specified environment variable (as regex) is matched against 1st field. 42 * 43 * $envvar=val format is useful for loading modules for hot-plugged devices 44 * which do not have driver loaded yet. In this case /sys/class/.../dev 45 * does not exist, but $MODALIAS is set to needed module's name 46 * (actually, an alias to it) by kernel. This rule instructs mdev 47 * to load the module and exit: 48 * $MODALIAS=.* 0:0 660 @modprobe "$MODALIAS" 49 * The kernel will generate another hotplug event when /sys/class/.../dev 50 * file appears. 51 * 52 * When line matches, the device node is created, chmod'ed and chown'ed, 53 * moved to path, and if >path, a symlink to moved node is created, 54 * all this if /sys/class/.../dev exists. 55 * Examples: 56 * =loop/ - moves to /dev/loop 57 * >disk/sda%1 - moves to /dev/disk/sdaN, makes /dev/sdaN a symlink 58 * 59 * Then "command args..." is executed (via sh -c 'command args...'). 60 * @:execute on creation, $:on deletion, *:on both. 61 * This happens regardless of /sys/class/.../dev existence. 62 */ 63 15 64 struct globals { 16 65 int root_major, root_minor; 17 }; 66 char *subsystem; 67 } FIX_ALIASING; 18 68 #define G (*(struct globals*)&bb_common_bufsiz1) 19 #define root_major (G.root_major) 20 #define root_minor (G.root_minor) 21 22 #define MAX_SYSFS_DEPTH 3 /* prevent infinite loops in /sys symlinks */ 23 24 /* mknod in /dev based on a path like "/sys/block/hda/hda1" */ 69 70 /* Prevent infinite loops in /sys symlinks */ 71 #define MAX_SYSFS_DEPTH 3 72 73 /* We use additional 64+ bytes in make_device() */ 74 #define SCRATCH_SIZE 80 75 76 /* Builds an alias path. 77 * This function potentionally reallocates the alias parameter. 78 * Only used for ENABLE_FEATURE_MDEV_RENAME 79 */ 80 static char *build_alias(char *alias, const char *device_name) 81 { 82 char *dest; 83 84 /* ">bar/": rename to bar/device_name */ 85 /* ">bar[/]baz": rename to bar[/]baz */ 86 dest = strrchr(alias, '/'); 87 if (dest) { /* ">bar/[baz]" ? */ 88 *dest = '\0'; /* mkdir bar */ 89 bb_make_directory(alias, 0755, FILEUTILS_RECUR); 90 *dest = '/'; 91 if (dest[1] == '\0') { /* ">bar/" => ">bar/device_name" */ 92 dest = alias; 93 alias = concat_path_file(alias, device_name); 94 free(dest); 95 } 96 } 97 98 return alias; 99 } 100 101 /* mknod in /dev based on a path like "/sys/block/hda/hda1" 102 * NB1: path parameter needs to have SCRATCH_SIZE scratch bytes 103 * after NUL, but we promise to not mangle (IOW: to restore if needed) 104 * path string. 105 * NB2: "mdev -s" may call us many times, do not leak memory/fds! 106 */ 25 107 static void make_device(char *path, int delete) 26 108 { 27 c onst char *device_name;109 char *device_name, *subsystem_slash_devname; 28 110 int major, minor, type, len; 29 int mode = 0660; 30 uid_t uid = 0; 31 gid_t gid = 0; 32 char *temp = path + strlen(path); 33 char *command = NULL; 111 mode_t mode; 112 parser_t *parser; 34 113 35 114 /* Try to read major/minor string. Note that the kernel puts \n after 36 115 * the data, so we don't need to worry about null terminating the string 37 * because sscanf() will stop at the first nondigit, which \n is. We 38 * also depend on path having writeable space after it. */ 39 116 * because sscanf() will stop at the first nondigit, which \n is. 117 * We also depend on path having writeable space after it. 118 */ 119 major = -1; 40 120 if (!delete) { 41 strcat(path, "/dev"); 42 len = open_read_close(path, temp + 1, 64); 43 *temp++ = 0; 44 if (len < 1) return; 121 char *dev_maj_min = path + strlen(path); 122 123 strcpy(dev_maj_min, "/dev"); 124 len = open_read_close(path, dev_maj_min + 1, 64); 125 *dev_maj_min = '\0'; 126 if (len < 1) { 127 if (!ENABLE_FEATURE_MDEV_EXEC) 128 return; 129 /* no "dev" file, but we can still run scripts 130 * based on device name */ 131 } else if (sscanf(++dev_maj_min, "%u:%u", &major, &minor) != 2) { 132 major = -1; 133 } 45 134 } 135 /* else: for delete, -1 still deletes the node, but < -1 suppresses that */ 46 136 47 137 /* Determine device name, type, major and minor */ 48 49 device_name = bb_basename(path); 50 type = path[5]=='c' ? S_IFCHR : S_IFBLK; 51 52 /* If we have a config file, look up permissions for this device */ 53 54 if (ENABLE_FEATURE_MDEV_CONF) { 55 char *conf, *pos, *end; 56 int line, fd; 57 58 /* mmap the config file */ 59 fd = open("/etc/mdev.conf", O_RDONLY); 60 if (fd < 0) 61 goto end_parse; 62 len = xlseek(fd, 0, SEEK_END); 63 conf = mmap(NULL, len, PROT_READ, MAP_PRIVATE, fd, 0); 64 close(fd); 65 if (!conf) 66 goto end_parse; 67 68 line = 0; 69 /* Loop through lines in mmaped file*/ 70 for (pos=conf; pos-conf<len;) { 71 int field; 72 char *end2; 73 74 line++; 75 /* find end of this line */ 76 for (end=pos; end-conf<len && *end!='\n'; end++) 77 ; 78 79 /* Three fields: regex, uid:gid, mode */ 80 for (field=0; field < (3 + ENABLE_FEATURE_MDEV_EXEC); 81 field++) 138 device_name = (char*) bb_basename(path); 139 /* http://kernel.org/doc/pending/hotplug.txt says that only 140 * "/sys/block/..." is for block devices. "/sys/bus" etc is not. 141 * But since 2.6.25 block devices are also in /sys/class/block. 142 * We use strstr("/block/") to forestall future surprises. */ 143 type = S_IFCHR; 144 if (strstr(path, "/block/") || (G.subsystem && strncmp(G.subsystem, "block", 5) == 0)) 145 type = S_IFBLK; 146 147 /* Make path point to "subsystem/device_name" */ 148 subsystem_slash_devname = NULL; 149 /* Check for coldplug invocations first */ 150 if (strncmp(path, "/sys/block/", 11) == 0) /* legacy case */ 151 path += sizeof("/sys/") - 1; 152 else if (strncmp(path, "/sys/class/", 11) == 0) 153 path += sizeof("/sys/class/") - 1; 154 else { 155 /* Example of a hotplug invocation: 156 * SUBSYSTEM="block" 157 * DEVPATH="/sys" + "/devices/virtual/mtd/mtd3/mtdblock3" 158 * ("/sys" is added by mdev_main) 159 * - path does not contain subsystem 160 */ 161 subsystem_slash_devname = concat_path_file(G.subsystem, device_name); 162 path = subsystem_slash_devname; 163 } 164 165 /* If we have config file, look up user settings */ 166 if (ENABLE_FEATURE_MDEV_CONF) 167 parser = config_open2("/etc/mdev.conf", fopen_for_read); 168 169 do { 170 int keep_matching; 171 struct bb_uidgid_t ugid; 172 char *tokens[4]; 173 char *command = NULL; 174 char *alias = NULL; 175 char aliaslink = aliaslink; /* for compiler */ 176 177 /* Defaults in case we won't match any line */ 178 ugid.uid = ugid.gid = 0; 179 keep_matching = 0; 180 mode = 0660; 181 182 if (ENABLE_FEATURE_MDEV_CONF 183 && config_read(parser, tokens, 4, 3, "# \t", PARSE_NORMAL) 184 ) { 185 char *val; 186 char *str_to_match; 187 regmatch_t off[1 + 9 * ENABLE_FEATURE_MDEV_RENAME_REGEXP]; 188 189 val = tokens[0]; 190 keep_matching = ('-' == val[0]); 191 val += keep_matching; /* swallow leading dash */ 192 193 /* Match against either "subsystem/device_name" 194 * or "device_name" alone */ 195 str_to_match = strchr(val, '/') ? path : device_name; 196 197 /* Fields: regex uid:gid mode [alias] [cmd] */ 198 199 if (val[0] == '@') { 200 /* @major,minor[-minor2] */ 201 /* (useful when name is ambiguous: 202 * "/sys/class/usb/lp0" and 203 * "/sys/class/printer/lp0") */ 204 int cmaj, cmin0, cmin1, sc; 205 if (major < 0) 206 continue; /* no dev, no match */ 207 sc = sscanf(val, "@%u,%u-%u", &cmaj, &cmin0, &cmin1); 208 if (sc < 1 209 || major != cmaj 210 || (sc == 2 && minor != cmin0) 211 || (sc == 3 && (minor < cmin0 || minor > cmin1)) 212 ) { 213 continue; /* this line doesn't match */ 214 } 215 goto line_matches; 216 } 217 if (val[0] == '$') { 218 /* regex to match an environment variable */ 219 char *eq = strchr(++val, '='); 220 if (!eq) 221 continue; 222 *eq = '\0'; 223 str_to_match = getenv(val); 224 if (!str_to_match) 225 continue; 226 str_to_match -= strlen(val) + 1; 227 *eq = '='; 228 } 229 /* else: regex to match [subsystem/]device_name */ 230 82 231 { 83 /* Skip whitespace */ 84 while (pos<end && isspace(*pos)) pos++; 85 if (pos==end || *pos=='#') break; 86 for (end2=pos; 87 end2<end && !isspace(*end2) && *end2!='#'; end2++) 88 ; 89 90 if (field == 0) { 91 /* Regex to match this device */ 92 93 char *regex = xstrndup(pos, end2-pos); 94 regex_t match; 95 regmatch_t off; 96 int result; 97 98 /* Is this it? */ 99 xregcomp(&match,regex, REG_EXTENDED); 100 result = regexec(&match, device_name, 1, &off, 0); 101 regfree(&match); 102 free(regex); 103 104 /* If not this device, skip rest of line */ 105 if (result || off.rm_so 106 || off.rm_eo != strlen(device_name)) 107 break; 108 } 109 if (field == 1) { 110 /* uid:gid */ 111 112 char *s, *s2; 113 114 /* Find : */ 115 for (s=pos; s<end2 && *s!=':'; s++) 116 ; 117 if (s == end2) break; 118 119 /* Parse UID */ 120 uid = strtoul(pos, &s2, 10); 121 if (s != s2) { 122 struct passwd *pass; 123 char *_unam = xstrndup(pos, s-pos); 124 pass = getpwnam(_unam); 125 free(_unam); 126 if (!pass) break; 127 uid = pass->pw_uid; 232 regex_t match; 233 int result; 234 235 xregcomp(&match, val, REG_EXTENDED); 236 result = regexec(&match, str_to_match, ARRAY_SIZE(off), off, 0); 237 regfree(&match); 238 //bb_error_msg("matches:"); 239 //for (int i = 0; i < ARRAY_SIZE(off); i++) { 240 // if (off[i].rm_so < 0) continue; 241 // bb_error_msg("match %d: '%.*s'\n", i, 242 // (int)(off[i].rm_eo - off[i].rm_so), 243 // device_name + off[i].rm_so); 244 //} 245 246 /* If no match, skip rest of line */ 247 /* (regexec returns whole pattern as "range" 0) */ 248 if (result 249 || off[0].rm_so 250 || ((int)off[0].rm_eo != (int)strlen(str_to_match)) 251 ) { 252 continue; /* this line doesn't match */ 253 } 254 } 255 line_matches: 256 /* This line matches. Stop parsing after parsing 257 * the rest the line unless keep_matching == 1 */ 258 259 /* 2nd field: uid:gid - device ownership */ 260 if (get_uidgid(&ugid, tokens[1], 1) == 0) 261 bb_error_msg("unknown user/group %s on line %d", tokens[1], parser->lineno); 262 263 /* 3rd field: mode - device permissions */ 264 bb_parse_mode(tokens[2], &mode); 265 266 val = tokens[3]; 267 /* 4th field (opt): ">|=alias" or "!" to not create the node */ 268 269 if (ENABLE_FEATURE_MDEV_RENAME && val) { 270 char *a, *s, *st; 271 272 a = val; 273 s = strchrnul(val, ' '); 274 st = strchrnul(val, '\t'); 275 if (st < s) 276 s = st; 277 st = (s[0] && s[1]) ? s+1 : NULL; 278 279 aliaslink = a[0]; 280 if (aliaslink == '!' && s == a+1) { 281 val = st; 282 /* "!": suppress node creation/deletion */ 283 major = -2; 284 } 285 else if (aliaslink == '>' || aliaslink == '=') { 286 val = st; 287 s[0] = '\0'; 288 if (ENABLE_FEATURE_MDEV_RENAME_REGEXP) { 289 char *p; 290 unsigned i, n; 291 292 /* substitute %1..9 with off[1..9], if any */ 293 n = 0; 294 s = a; 295 while (*s) 296 if (*s++ == '%') 297 n++; 298 299 p = alias = xzalloc(strlen(a) + n * strlen(str_to_match)); 300 s = a + 1; 301 while (*s) { 302 *p = *s; 303 if ('%' == *s) { 304 i = (s[1] - '0'); 305 if (i <= 9 && off[i].rm_so >= 0) { 306 n = off[i].rm_eo - off[i].rm_so; 307 strncpy(p, str_to_match + off[i].rm_so, n); 308 p += n - 1; 309 s++; 310 } 311 } 312 p++; 313 s++; 314 } 315 } else { 316 alias = xstrdup(a + 1); 128 317 } 129 s++; 130 /* parse GID */ 131 gid = strtoul(s, &s2, 10); 132 if (end2 != s2) { 133 struct group *grp; 134 char *_grnam = xstrndup(s, end2-s); 135 grp = getgrnam(_grnam); 136 free(_grnam); 137 if (!grp) break; 138 gid = grp->gr_gid; 139 } 140 } 141 if (field == 2) { 142 /* mode */ 143 144 mode = strtoul(pos, &pos, 8); 145 if (pos != end2) break; 146 } 147 if (ENABLE_FEATURE_MDEV_EXEC && field == 3) { 148 // Command to run 149 const char *s = "@$*"; 150 const char *s2; 151 s2 = strchr(s, *pos++); 152 if (!s2) { 153 // Force error 154 field = 1; 155 break; 156 } 157 if ((s2-s+1) & (1<<delete)) 158 command = xstrndup(pos, end-pos); 159 } 160 161 pos = end2; 162 } 163 164 /* Did everything parse happily? */ 165 166 if (field > 2) break; 167 if (field) bb_error_msg_and_die("bad line %d",line); 168 169 /* Next line */ 170 pos = ++end; 171 } 172 munmap(conf, len); 173 end_parse: /* nothing */ ; 174 } 175 176 umask(0); 177 if (!delete) { 178 if (sscanf(temp, "%d:%d", &major, &minor) != 2) return; 179 if (mknod(device_name, mode | type, makedev(major, minor)) && errno != EEXIST) 180 bb_perror_msg_and_die("mknod %s", device_name); 181 182 if (major == root_major && minor == root_minor) 183 symlink(device_name, "root"); 184 185 if (ENABLE_FEATURE_MDEV_CONF) chown(device_name, uid, gid); 186 } 187 if (command) { 188 /* setenv will leak memory, so use putenv */ 189 char *s = xasprintf("MDEV=%s", device_name); 190 putenv(s); 191 if (system(command) == -1) 192 bb_perror_msg_and_die("cannot run %s", command); 193 s[4] = '\0'; 194 unsetenv(s); 195 free(s); 196 free(command); 197 } 198 if (delete) unlink(device_name); 318 } 319 } 320 321 if (ENABLE_FEATURE_MDEV_EXEC && val) { 322 const char *s = "$@*"; 323 const char *s2 = strchr(s, val[0]); 324 325 if (!s2) { 326 bb_error_msg("bad line %u", parser->lineno); 327 if (ENABLE_FEATURE_MDEV_RENAME) 328 free(alias); 329 continue; 330 } 331 332 /* Are we running this command now? 333 * Run $cmd on delete, @cmd on create, *cmd on both 334 */ 335 if (s2 - s != delete) { 336 /* We are here if: '*', 337 * or: '@' and delete = 0, 338 * or: '$' and delete = 1 339 */ 340 command = xstrdup(val + 1); 341 } 342 } 343 } 344 345 /* End of field parsing */ 346 347 /* "Execute" the line we found */ 348 { 349 const char *node_name; 350 351 node_name = device_name; 352 if (ENABLE_FEATURE_MDEV_RENAME && alias) 353 node_name = alias = build_alias(alias, device_name); 354 355 if (!delete && major >= 0) { 356 if (mknod(node_name, mode | type, makedev(major, minor)) && errno != EEXIST) 357 bb_perror_msg("can't create '%s'", node_name); 358 if (major == G.root_major && minor == G.root_minor) 359 symlink(node_name, "root"); 360 if (ENABLE_FEATURE_MDEV_CONF) { 361 chmod(node_name, mode); 362 chown(node_name, ugid.uid, ugid.gid); 363 } 364 if (ENABLE_FEATURE_MDEV_RENAME && alias) { 365 if (aliaslink == '>') 366 symlink(node_name, device_name); 367 } 368 } 369 370 if (ENABLE_FEATURE_MDEV_EXEC && command) { 371 /* setenv will leak memory, use putenv/unsetenv/free */ 372 char *s = xasprintf("%s=%s", "MDEV", node_name); 373 char *s1 = xasprintf("%s=%s", "SUBSYSTEM", G.subsystem); 374 putenv(s); 375 putenv(s1); 376 if (system(command) == -1) 377 bb_perror_msg("can't run '%s'", command); 378 bb_unsetenv_and_free(s1); 379 bb_unsetenv_and_free(s); 380 free(command); 381 } 382 383 if (delete && major >= -1) { 384 if (ENABLE_FEATURE_MDEV_RENAME && alias) { 385 if (aliaslink == '>') 386 unlink(device_name); 387 } 388 unlink(node_name); 389 } 390 391 if (ENABLE_FEATURE_MDEV_RENAME) 392 free(alias); 393 } 394 395 /* We found matching line. 396 * Stop unless it was prefixed with '-' */ 397 if (ENABLE_FEATURE_MDEV_CONF && !keep_matching) 398 break; 399 400 /* end of "while line is read from /etc/mdev.conf" */ 401 } while (ENABLE_FEATURE_MDEV_CONF); 402 403 if (ENABLE_FEATURE_MDEV_CONF) 404 config_close(parser); 405 free(subsystem_slash_devname); 199 406 } 200 407 201 408 /* File callback for /sys/ traversal */ 202 static int fileAction(const char *fileName, struct stat *statbuf, 203 void *userData, int depth) 409 static int FAST_FUNC fileAction(const char *fileName, 410 struct stat *statbuf UNUSED_PARAM, 411 void *userData, 412 int depth UNUSED_PARAM) 204 413 { 205 size_t len = strlen(fileName) - 4; 414 size_t len = strlen(fileName) - 4; /* can't underflow */ 206 415 char *scratch = userData; 207 416 208 if (strcmp(fileName + len, "/dev")) 417 /* len check is for paranoid reasons */ 418 if (strcmp(fileName + len, "/dev") != 0 || len >= PATH_MAX) 209 419 return FALSE; 210 420 211 421 strcpy(scratch, fileName); 212 scratch[len] = 0;213 make_device(scratch, 0);422 scratch[len] = '\0'; 423 make_device(scratch, /*delete:*/ 0); 214 424 215 425 return TRUE; … … 217 427 218 428 /* Directory callback for /sys/ traversal */ 219 static int dirAction(const char *fileName, struct stat *statbuf, 220 void *userData, int depth) 429 static int FAST_FUNC dirAction(const char *fileName UNUSED_PARAM, 430 struct stat *statbuf UNUSED_PARAM, 431 void *userData UNUSED_PARAM, 432 int depth) 221 433 { 434 /* Extract device subsystem -- the name of the directory 435 * under /sys/class/ */ 436 if (1 == depth) { 437 free(G.subsystem); 438 G.subsystem = strrchr(fileName, '/'); 439 if (G.subsystem) 440 G.subsystem = xstrdup(G.subsystem + 1); 441 } 442 222 443 return (depth >= MAX_SYSFS_DEPTH ? SKIP : TRUE); 223 444 } … … 234 455 * - kernel loads firmware into device 235 456 */ 236 static void load_firmware(const char * const firmware, const char *constsysfs_path)457 static void load_firmware(const char *firmware, const char *sysfs_path) 237 458 { 238 459 int cnt; 239 460 int firmware_fd, loading_fd, data_fd; 240 241 /* check for $FIRMWARE from kernel */242 /* XXX: dont bother: open(NULL) works same as open("no-such-file")243 * if (!firmware)244 * return;245 */246 461 247 462 /* check for /lib/firmware/$FIRMWARE */ … … 256 471 for (cnt = 0; cnt < 30; ++cnt) { 257 472 loading_fd = open("loading", O_WRONLY); 258 if (loading_fd == -1) 259 sleep(1); 260 else 261 break; 473 if (loading_fd != -1) 474 goto loading; 475 sleep(1); 262 476 } 263 if (loading_fd == -1) 477 goto out; 478 479 loading: 480 /* tell kernel we're loading by "echo 1 > /sys/$DEVPATH/loading" */ 481 if (full_write(loading_fd, "1", 1) != 1) 264 482 goto out; 265 483 266 /* tell kernel we're loading by `echo 1 > /sys/$DEVPATH/loading` */ 267 if (write(loading_fd, "1", 1) != 1) 268 goto out; 269 270 /* load firmware by `cat /lib/firmware/$FIRMWARE > /sys/$DEVPATH/data */ 484 /* load firmware into /sys/$DEVPATH/data */ 271 485 data_fd = open("data", O_WRONLY); 272 486 if (data_fd == -1) … … 274 488 cnt = bb_copyfd_eof(firmware_fd, data_fd); 275 489 276 /* tell kernel result by `echo [0|-1] > /sys/$DEVPATH/loading`*/490 /* tell kernel result by "echo [0|-1] > /sys/$DEVPATH/loading" */ 277 491 if (cnt > 0) 278 write(loading_fd, "0", 1);492 full_write(loading_fd, "0", 1); 279 493 else 280 write(loading_fd, "-1", 2);494 full_write(loading_fd, "-1", 2); 281 495 282 496 out: … … 288 502 } 289 503 290 int mdev_main(int argc, char **argv) ;291 int mdev_main(int argc , char **argv)504 int mdev_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 505 int mdev_main(int argc UNUSED_PARAM, char **argv) 292 506 { 293 char *action; 294 char *env_path; 295 RESERVE_CONFIG_BUFFER(temp,PATH_MAX); 507 RESERVE_CONFIG_BUFFER(temp, PATH_MAX + SCRATCH_SIZE); 508 509 /* We can be called as hotplug helper */ 510 /* Kernel cannot provide suitable stdio fds for us, do it ourself */ 511 bb_sanitize_stdio(); 512 513 /* Force the configuration file settings exactly */ 514 umask(0); 296 515 297 516 xchdir("/dev"); 298 517 299 /* Scan */ 300 301 if (argc == 2 && !strcmp(argv[1],"-s")) { 518 if (argv[1] && strcmp(argv[1], "-s") == 0) { 519 /* Scan: 520 * mdev -s 521 */ 302 522 struct stat st; 303 523 304 524 xstat("/", &st); 305 root_major = major(st.st_dev); 306 root_minor = minor(st.st_dev); 307 308 recursive_action("/sys/block", 309 ACTION_RECURSE | ACTION_FOLLOWLINKS, 310 fileAction, dirAction, temp, 0); 311 525 G.root_major = major(st.st_dev); 526 G.root_minor = minor(st.st_dev); 527 528 /* ACTION_FOLLOWLINKS is needed since in newer kernels 529 * /sys/block/loop* (for example) are symlinks to dirs, 530 * not real directories. 531 * (kernel's CONFIG_SYSFS_DEPRECATED makes them real dirs, 532 * but we can't enforce that on users) 533 */ 534 if (access("/sys/class/block", F_OK) != 0) { 535 /* Scan obsolete /sys/block only if /sys/class/block 536 * doesn't exist. Otherwise we'll have dupes. 537 * Also, do not complain if it doesn't exist. 538 * Some people configure kernel to have no blockdevs. 539 */ 540 recursive_action("/sys/block", 541 ACTION_RECURSE | ACTION_FOLLOWLINKS | ACTION_QUIET, 542 fileAction, dirAction, temp, 0); 543 } 312 544 recursive_action("/sys/class", 313 545 ACTION_RECURSE | ACTION_FOLLOWLINKS, 314 546 fileAction, dirAction, temp, 0); 315 316 /* Hotplug */317 318 547 } else { 548 char *fw; 549 char *seq; 550 char *action; 551 char *env_path; 552 static const char keywords[] ALIGN1 = "remove\0add\0"; 553 enum { OP_remove = 0, OP_add }; 554 smalluint op; 555 556 /* Hotplug: 557 * env ACTION=... DEVPATH=... SUBSYSTEM=... [SEQNUM=...] mdev 558 * ACTION can be "add" or "remove" 559 * DEVPATH is like "/block/sda" or "/class/input/mice" 560 */ 319 561 action = getenv("ACTION"); 320 562 env_path = getenv("DEVPATH"); 321 if (!action || !env_path) 563 G.subsystem = getenv("SUBSYSTEM"); 564 if (!action || !env_path /*|| !G.subsystem*/) 322 565 bb_show_usage(); 323 324 sprintf(temp, "/sys%s", env_path); 325 if (!strcmp(action, "remove")) 326 make_device(temp, 1); 327 else if (!strcmp(action, "add")) { 328 make_device(temp, 0); 329 330 if (ENABLE_FEATURE_MDEV_LOAD_FIRMWARE) 331 load_firmware(getenv("FIRMWARE"), temp); 566 fw = getenv("FIRMWARE"); 567 op = index_in_strings(keywords, action); 568 /* If it exists, does /dev/mdev.seq match $SEQNUM? 569 * If it does not match, earlier mdev is running 570 * in parallel, and we need to wait */ 571 seq = getenv("SEQNUM"); 572 if (seq) { 573 int timeout = 2000 / 32; /* 2000 msec */ 574 do { 575 int seqlen; 576 char seqbuf[sizeof(int)*3 + 2]; 577 578 seqlen = open_read_close("mdev.seq", seqbuf, sizeof(seqbuf-1)); 579 if (seqlen < 0) { 580 seq = NULL; 581 break; 582 } 583 seqbuf[seqlen] = '\0'; 584 if (seqbuf[0] == '\n' /* seed file? */ 585 || strcmp(seq, seqbuf) == 0 /* correct idx? */ 586 ) { 587 break; 588 } 589 usleep(32*1000); 590 } while (--timeout); 591 } 592 593 snprintf(temp, PATH_MAX, "/sys%s", env_path); 594 if (op == OP_remove) { 595 /* Ignoring "remove firmware". It was reported 596 * to happen and to cause erroneous deletion 597 * of device nodes. */ 598 if (!fw) 599 make_device(temp, /*delete:*/ 1); 600 } 601 else if (op == OP_add) { 602 make_device(temp, /*delete:*/ 0); 603 if (ENABLE_FEATURE_MDEV_LOAD_FIRMWARE) { 604 if (fw) 605 load_firmware(fw, temp); 606 } 607 } 608 609 if (seq) { 610 xopen_xwrite_close("mdev.seq", utoa(xatou(seq) + 1)); 332 611 } 333 612 } 334 613 335 if (ENABLE_FEATURE_CLEAN_UP) RELEASE_CONFIG_BUFFER(temp); 336 return 0; 614 if (ENABLE_FEATURE_CLEAN_UP) 615 RELEASE_CONFIG_BUFFER(temp); 616 617 return EXIT_SUCCESS; 337 618 } -
branches/2.2.9/mindi-busybox/util-linux/minix.h
r1765 r2725 32 32 33 33 /* 34 * minix super -block data on disk34 * minix superblock data on disk 35 35 */ 36 struct minix_super _block {36 struct minix_superblock { 37 37 uint16_t s_ninodes; 38 38 uint16_t s_nzones; … … 49 49 struct minix_dir_entry { 50 50 uint16_t inode; 51 char name[ 0];51 char name[]; 52 52 }; 53 53 -
branches/2.2.9/mindi-busybox/util-linux/mkfs_minix.c
r1765 r2725 3 3 * mkfs.c - make a linux (minix) file-system. 4 4 * 5 * (C) 1991 Linus Torvalds. This file may be redistributed as per 6 * the Linux copyright. 5 * (C) 1991 Linus Torvalds. 6 * 7 * Licensed under GPLv2, see file LICENSE in this source tree. 7 8 */ 8 9 … … 68 69 #include "minix.h" 69 70 70 #define DEBUG 0 71 72 /* If debugging, store the very same times/uids/gids for image consistency */ 73 #if DEBUG 71 /* Store the very same times/uids/gids for image consistency */ 72 #if 1 74 73 # define CUR_TIME 0 75 74 # define GETUID 0 76 75 # define GETGID 0 77 76 #else 77 /* Was using this. Is it useful? NB: this will break testsuite */ 78 78 # define CUR_TIME time(NULL) 79 79 # define GETUID getuid() … … 90 90 #endif 91 91 92 enum { dev_fd = 3 }; 93 92 94 struct globals { 93 int dev_fd;94 95 95 #if ENABLE_FEATURE_MINIX2 96 96 smallint version2; … … 110 110 unsigned currently_testing; 111 111 112 113 112 char root_block[BLOCK_SIZE]; 114 char super _block_buffer[BLOCK_SIZE];113 char superblock_buffer[BLOCK_SIZE]; 115 114 char boot_block_buffer[512]; 116 115 unsigned short good_blocks_table[MAX_GOOD_BLOCKS]; 117 116 /* check_blocks(): buffer[] was the biggest static in entire bbox */ 118 117 char check_blocks_buffer[BLOCK_SIZE * TEST_BUFFER_BLOCKS]; 118 119 unsigned short ind_block1[BLOCK_SIZE >> 1]; 120 unsigned short dind_block1[BLOCK_SIZE >> 1]; 121 unsigned long ind_block2[BLOCK_SIZE >> 2]; 122 unsigned long dind_block2[BLOCK_SIZE >> 2]; 119 123 }; 120 121 124 #define G (*ptr_to_globals) 125 #define INIT_G() do { \ 126 SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \ 127 } while (0) 122 128 123 129 static ALWAYS_INLINE unsigned div_roundup(unsigned size, unsigned n) … … 129 135 #define INODE_BUF2 (((struct minix2_inode*)G.inode_buffer) - 1) 130 136 131 #define SB (*(struct minix_super _block*)G.super_block_buffer)137 #define SB (*(struct minix_superblock*)G.superblock_buffer) 132 138 133 139 #define SB_INODES (SB.s_ninodes) … … 145 151 # define SB_ZONES (version2 ? SB.s_zones : SB.s_nzones) 146 152 # define INODE_BLOCKS div_roundup(SB_INODES, \ 147 version2 ? MINIX2_INODES_PER_BLOCK : MINIX1_INODES_PER_BLOCK)153 (version2 ? MINIX2_INODES_PER_BLOCK : MINIX1_INODES_PER_BLOCK)) 148 154 #endif 149 155 … … 156 162 static int minix_bit(const char* a, unsigned i) 157 163 { 158 164 return a[i >> 3] & (1<<(i & 7)); 159 165 } 160 166 … … 231 237 static void write_tables(void) 232 238 { 233 /* Mark the super 239 /* Mark the superblock valid. */ 234 240 SB.s_state |= MINIX_VALID_FS; 235 241 SB.s_state &= ~MINIX_ERROR_FS; 236 242 237 243 msg_eol = "seek to 0 failed"; 238 xlseek( G.dev_fd, 0, SEEK_SET);239 240 msg_eol = "can not clear boot sector";241 xwrite( G.dev_fd, G.boot_block_buffer, 512);244 xlseek(dev_fd, 0, SEEK_SET); 245 246 msg_eol = "can't clear boot sector"; 247 xwrite(dev_fd, G.boot_block_buffer, 512); 242 248 243 249 msg_eol = "seek to BLOCK_SIZE failed"; 244 xlseek( G.dev_fd, BLOCK_SIZE, SEEK_SET);245 246 msg_eol = "can not write superblock";247 xwrite( G.dev_fd, G.super_block_buffer, BLOCK_SIZE);248 249 msg_eol = "can not write inode map";250 xwrite( G.dev_fd, G.inode_map, SB_IMAPS * BLOCK_SIZE);251 252 msg_eol = "can not write zone map";253 xwrite( G.dev_fd, G.zone_map, SB_ZMAPS * BLOCK_SIZE);254 255 msg_eol = "can not write inodes";256 xwrite( G.dev_fd, G.inode_buffer, INODE_BUFFER_SIZE);250 xlseek(dev_fd, BLOCK_SIZE, SEEK_SET); 251 252 msg_eol = "can't write superblock"; 253 xwrite(dev_fd, G.superblock_buffer, BLOCK_SIZE); 254 255 msg_eol = "can't write inode map"; 256 xwrite(dev_fd, G.inode_map, SB_IMAPS * BLOCK_SIZE); 257 258 msg_eol = "can't write zone map"; 259 xwrite(dev_fd, G.zone_map, SB_ZMAPS * BLOCK_SIZE); 260 261 msg_eol = "can't write inodes"; 262 xwrite(dev_fd, G.inode_buffer, INODE_BUFFER_SIZE); 257 263 258 264 msg_eol = "\n"; … … 261 267 static void write_block(int blk, char *buffer) 262 268 { 263 xlseek( G.dev_fd, blk * BLOCK_SIZE, SEEK_SET);264 xwrite( G.dev_fd, buffer, BLOCK_SIZE);269 xlseek(dev_fd, blk * BLOCK_SIZE, SEEK_SET); 270 xwrite(dev_fd, buffer, BLOCK_SIZE); 265 271 } 266 272 … … 307 313 int i, j, zone; 308 314 int ind = 0, dind = 0; 315 /* moved to globals to reduce stack usage 309 316 unsigned short ind_block[BLOCK_SIZE >> 1]; 310 317 unsigned short dind_block[BLOCK_SIZE >> 1]; 318 */ 319 #define ind_block (G.ind_block1) 320 #define dind_block (G.dind_block1) 311 321 312 322 #define NEXT_BAD (zone = next(zone)) … … 352 362 if (dind) 353 363 write_block(dind, (char *) dind_block); 364 #undef ind_block 365 #undef dind_block 354 366 } 355 367 … … 360 372 int i, j, zone; 361 373 int ind = 0, dind = 0; 374 /* moved to globals to reduce stack usage 362 375 unsigned long ind_block[BLOCK_SIZE >> 2]; 363 376 unsigned long dind_block[BLOCK_SIZE >> 2]; 377 */ 378 #define ind_block (G.ind_block2) 379 #define dind_block (G.dind_block2) 364 380 365 381 if (!G.badblocks) … … 402 418 if (dind) 403 419 write_block(dind, (char *) dind_block); 420 #undef ind_block 421 #undef dind_block 404 422 } 405 423 #else … … 465 483 /* Seek to the correct loc. */ 466 484 msg_eol = "seek failed during testing of blocks"; 467 xlseek( G.dev_fd, current_block * BLOCK_SIZE, SEEK_SET);485 xlseek(dev_fd, current_block * BLOCK_SIZE, SEEK_SET); 468 486 msg_eol = "\n"; 469 487 470 488 /* Try the read */ 471 got = read( G.dev_fd, buffer, try * BLOCK_SIZE);489 got = read(dev_fd, buffer, try * BLOCK_SIZE); 472 490 if (got < 0) 473 491 got = 0; … … 479 497 } 480 498 481 static void alarm_intr(int alnum )499 static void alarm_intr(int alnum UNUSED_PARAM) 482 500 { 483 501 if (G.currently_testing >= SB_ZONES) … … 488 506 return; 489 507 printf("%d ...", G.currently_testing); 490 fflush (stdout);508 fflush_all(); 491 509 } 492 510 … … 500 518 while (G.currently_testing < SB_ZONES) { 501 519 msg_eol = "seek failed in check_blocks"; 502 xlseek( G.dev_fd, G.currently_testing * BLOCK_SIZE, SEEK_SET);520 xlseek(dev_fd, G.currently_testing * BLOCK_SIZE, SEEK_SET); 503 521 msg_eol = "\n"; 504 522 try = TEST_BUFFER_BLOCKS; … … 524 542 unsigned long blockno; 525 543 526 listfile = xfopen (filename, "r");544 listfile = xfopen_for_read(filename); 527 545 while (!feof(listfile)) { 528 546 fscanf(listfile, "%ld\n", &blockno); … … 540 558 unsigned i; 541 559 542 /* memset(G.super _block_buffer, 0, BLOCK_SIZE); */560 /* memset(G.superblock_buffer, 0, BLOCK_SIZE); */ 543 561 /* memset(G.boot_block_buffer, 0, 512); */ 544 562 SB_MAGIC = G.magic; … … 604 622 } 605 623 606 int mkfs_minix_main(int argc, char **argv); 607 int mkfs_minix_main(int argc, char **argv) 608 { 609 struct mntent *mp; 624 int mkfs_minix_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 625 int mkfs_minix_main(int argc UNUSED_PARAM, char **argv) 626 { 610 627 unsigned opt; 611 628 char *tmp; 612 629 struct stat statbuf; 613 char *str_i , *str_n;630 char *str_i; 614 631 char *listfile = NULL; 615 632 616 PTR_TO_GLOBALS = xzalloc(sizeof(G));633 INIT_G(); 617 634 /* default (changed to 30, per Linus's suggestion, Sun Nov 21 08:05:07 1993) */ 618 635 G.namelen = 30; … … 627 644 #endif 628 645 629 opt = getopt32(argv, "ci:l:n:v", &str_i, &listfile, &str_n); 646 opt_complementary = "n+"; /* -n N */ 647 opt = getopt32(argv, "ci:l:n:v", &str_i, &listfile, &G.namelen); 630 648 argv += optind; 631 649 //if (opt & 1) -c … … 633 651 //if (opt & 4) -l 634 652 if (opt & 8) { // -n 635 G.namelen = xatoi_u(str_n);636 653 if (G.namelen == 14) G.magic = MINIX1_SUPER_MAGIC; 637 654 else if (G.namelen == 30) G.magic = MINIX1_SUPER_MAGIC2; … … 666 683 667 684 /* Check if it is mounted */ 668 mp = find_mount_point(G.device_name, NULL); 669 if (mp && strcmp(G.device_name, mp->mnt_fsname) == 0) 670 bb_error_msg_and_die("%s is mounted on %s; " 671 "refusing to make a filesystem", 672 G.device_name, mp->mnt_dir); 673 674 G.dev_fd = xopen(G.device_name, O_RDWR); 675 if (fstat(G.dev_fd, &statbuf) < 0) 676 bb_error_msg_and_die("cannot stat %s", G.device_name); 685 if (find_mount_point(G.device_name, 0)) 686 bb_error_msg_and_die("can't format mounted filesystem"); 687 688 xmove_fd(xopen(G.device_name, O_RDWR), dev_fd); 689 xfstat(dev_fd, &statbuf, G.device_name); 677 690 if (!S_ISBLK(statbuf.st_mode)) 678 691 opt &= ~1; // clear -c (check) -
branches/2.2.9/mindi-busybox/util-linux/mkswap.c
r1765 r2725 4 4 * Copyright 2006 Rob Landley <rob@landley.net> 5 5 * 6 * Licensed under GPL version 2, see file LICENSE in this tarball for details.6 * Licensed under GPLv2, see file LICENSE in this source tree. 7 7 */ 8 9 8 #include "libbb.h" 10 9 11 int mkswap_main(int argc, char **argv); 12 int mkswap_main(int argc, char **argv)10 #if ENABLE_SELINUX 11 static void mkswap_selinux_setcontext(int fd, const char *path) 13 12 { 14 int fd, pagesize; 13 struct stat stbuf; 14 15 if (!is_selinux_enabled()) 16 return; 17 18 xfstat(fd, &stbuf, path); 19 if (S_ISREG(stbuf.st_mode)) { 20 security_context_t newcon; 21 security_context_t oldcon = NULL; 22 context_t context; 23 24 if (fgetfilecon(fd, &oldcon) < 0) { 25 if (errno != ENODATA) 26 goto error; 27 if (matchpathcon(path, stbuf.st_mode, &oldcon) < 0) 28 goto error; 29 } 30 context = context_new(oldcon); 31 if (!context || context_type_set(context, "swapfile_t")) 32 goto error; 33 newcon = context_str(context); 34 if (!newcon) 35 goto error; 36 /* fsetfilecon_raw is hidden */ 37 if (strcmp(oldcon, newcon) != 0 && fsetfilecon(fd, newcon) < 0) 38 goto error; 39 if (ENABLE_FEATURE_CLEAN_UP) { 40 context_free(context); 41 freecon(oldcon); 42 } 43 } 44 return; 45 error: 46 bb_perror_msg_and_die("SELinux relabeling failed"); 47 } 48 #else 49 # define mkswap_selinux_setcontext(fd, path) ((void)0) 50 #endif 51 52 /* from Linux 2.6.23 */ 53 /* 54 * Magic header for a swap area. ... Note that the first 55 * kilobyte is reserved for boot loader or disk label stuff. 56 */ 57 struct swap_header_v1 { 58 /* char bootbits[1024]; Space for disklabel etc. */ 59 uint32_t version; /* second kbyte, word 0 */ 60 uint32_t last_page; /* 1 */ 61 uint32_t nr_badpages; /* 2 */ 62 char sws_uuid[16]; /* 3,4,5,6 */ 63 char sws_volume[16]; /* 7,8,9,10 */ 64 uint32_t padding[117]; /* 11..127 */ 65 uint32_t badpages[1]; /* 128 */ 66 /* total 129 32-bit words in 2nd kilobyte */ 67 } FIX_ALIASING; 68 69 #define NWORDS 129 70 #define hdr ((struct swap_header_v1*)bb_common_bufsiz1) 71 72 struct BUG_sizes { 73 char swap_header_v1_wrong[sizeof(*hdr) != (NWORDS * 4) ? -1 : 1]; 74 char bufsiz1_is_too_small[COMMON_BUFSIZE < (NWORDS * 4) ? -1 : 1]; 75 }; 76 77 /* Stored without terminating NUL */ 78 static const char SWAPSPACE2[sizeof("SWAPSPACE2")-1] ALIGN1 = "SWAPSPACE2"; 79 80 int mkswap_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 81 int mkswap_main(int argc UNUSED_PARAM, char **argv) 82 { 83 int fd; 84 unsigned pagesize; 15 85 off_t len; 16 unsigned int hdr[129];86 const char *label = ""; 17 87 18 // No options supported. 88 opt_complementary = "-1"; /* at least one param */ 89 /* TODO: -p PAGESZ, -U UUID */ 90 getopt32(argv, "L:", &label); 91 argv += optind; 19 92 20 if (argc != 2) bb_show_usage();93 fd = xopen(argv[0], O_WRONLY); 21 94 22 // Figure out how big the device is and announce our intentions. 95 /* Figure out how big the device is */ 96 len = get_volume_size_in_bytes(fd, argv[1], 1024, /*extend:*/ 1); 97 pagesize = getpagesize(); 98 len -= pagesize; 23 99 24 fd = xopen(argv[1], O_RDWR); 25 len = fdlength(fd); 26 pagesize = getpagesize(); 27 printf("Setting up swapspace version 1, size = %"OFF_FMT"d bytes\n", 28 len - pagesize); 100 /* Announce our intentions */ 101 printf("Setting up swapspace version 1, size = %"OFF_FMT"u bytes\n", len); 102 mkswap_selinux_setcontext(fd, argv[0]); 29 103 30 // Make a header. 104 /* hdr is zero-filled so far. Clear the first kbyte, or else 105 * mkswap-ing former FAT partition does NOT erase its signature. 106 * 107 * util-linux-ng 2.17.2 claims to erase it only if it does not see 108 * a partition table and is not run on whole disk. -f forces it. 109 */ 110 xwrite(fd, hdr, 1024); 31 111 32 memset(hdr, 0, sizeof(hdr));33 hdr [0]= 1;34 hdr [1] = (len / pagesize) - 1;112 /* Fill the header. */ 113 hdr->version = 1; 114 hdr->last_page = (uoff_t)len / pagesize; 35 115 36 // Write the header. Sync to disk because some kernel versions check 37 // signature on disk (not in cache) during swapon. 116 if (ENABLE_FEATURE_MKSWAP_UUID) { 117 char uuid_string[32]; 118 generate_uuid((void*)hdr->sws_uuid); 119 bin2hex(uuid_string, hdr->sws_uuid, 16); 120 /* f.e. UUID=dfd9c173-be52-4d27-99a5-c34c6c2ff55f */ 121 printf("UUID=%.8s" "-%.4s-%.4s-%.4s-%.12s\n", 122 uuid_string, 123 uuid_string+8, 124 uuid_string+8+4, 125 uuid_string+8+4+4, 126 uuid_string+8+4+4+4 127 ); 128 } 129 safe_strncpy(hdr->sws_volume, label, 16); 38 130 39 xlseek(fd, 1024, SEEK_SET); 40 xwrite(fd, hdr, sizeof(hdr)); 41 xlseek(fd, pagesize-10, SEEK_SET); 42 xwrite(fd, "SWAPSPACE2", 10); 131 /* Write the header. Sync to disk because some kernel versions check 132 * signature on disk (not in cache) during swapon. */ 133 xwrite(fd, hdr, NWORDS * 4); 134 xlseek(fd, pagesize - 10, SEEK_SET); 135 xwrite(fd, SWAPSPACE2, 10); 43 136 fsync(fd); 44 137 45 if (ENABLE_FEATURE_CLEAN_UP) close(fd); 138 if (ENABLE_FEATURE_CLEAN_UP) 139 close(fd); 46 140 47 141 return 0; -
branches/2.2.9/mindi-busybox/util-linux/more.c
r1765 r2725 12 12 * Termios corrects by Vladimir Oleynik <dzo@simtreas.ru> 13 13 * 14 * Licensed under GPLv2 or later, see file L icense in this tarball for details.14 * Licensed under GPLv2 or later, see file LICENSE in this source tree. 15 15 */ 16 16 17 17 #include "libbb.h" 18 #if ENABLE_FEATURE_USE_TERMIOS 19 #include <termios.h> 20 #endif /* FEATURE_USE_TERMIOS */ 21 22 23 #if ENABLE_FEATURE_USE_TERMIOS 18 19 /* Support for FEATURE_USE_TERMIOS */ 24 20 25 21 struct globals { … … 27 23 struct termios initial_settings; 28 24 struct termios new_settings; 29 } ;25 } FIX_ALIASING; 30 26 #define G (*(struct globals*)bb_common_bufsiz1) 31 //#define G (*ptr_to_globals)32 27 #define INIT_G() ((void)0) 33 //#define INIT_G() PTR_TO_GLOBALS = xzalloc(sizeof(G))34 28 #define initial_settings (G.initial_settings) 35 29 #define new_settings (G.new_settings ) 36 30 #define cin_fileno (G.cin_fileno ) 37 31 38 #define setTermSettings(fd, argp) tcsetattr(fd, TCSANOW, argp) 32 #define setTermSettings(fd, argp) \ 33 do { \ 34 if (ENABLE_FEATURE_USE_TERMIOS) \ 35 tcsetattr(fd, TCSANOW, argp); \ 36 } while (0) 39 37 #define getTermSettings(fd, argp) tcgetattr(fd, argp) 40 38 41 static void gotsig(int sig )39 static void gotsig(int sig UNUSED_PARAM) 42 40 { 43 putchar('\n'); 41 /* bb_putchar_stderr doesn't use stdio buffering, 42 * therefore it is safe in signal handler */ 43 bb_putchar_stderr('\n'); 44 44 setTermSettings(cin_fileno, &initial_settings); 45 exit(EXIT_FAILURE);45 _exit(EXIT_FAILURE); 46 46 } 47 47 48 #else /* !FEATURE_USE_TERMIOS */49 #define INIT_G() ((void)0)50 #define setTermSettings(fd, argp) ((void)0)51 #endif /* FEATURE_USE_TERMIOS */52 53 48 #define CONVERTED_TAB_SIZE 8 54 49 55 int more_main(int argc, char **argv) ;56 int more_main(int argc , char **argv)50 int more_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 51 int more_main(int argc UNUSED_PARAM, char **argv) 57 52 { 58 int c = c; /* for gcc*/53 int c = c; /* for compiler */ 59 54 int lines; 60 55 int input = 0; … … 65 60 FILE *cin; 66 61 int len; 67 intterminal_width;68 intterminal_height;62 unsigned terminal_width; 63 unsigned terminal_height; 69 64 70 65 INIT_G(); … … 75 70 if (!isatty(STDOUT_FILENO)) 76 71 return bb_cat(argv); 77 cin = fopen (CURRENT_TTY, "r");72 cin = fopen_for_read(CURRENT_TTY); 78 73 if (!cin) 79 74 return bb_cat(argv); 80 75 81 #if ENABLE_FEATURE_USE_TERMIOS 82 cin_fileno = fileno(cin); 83 getTermSettings(cin_fileno, &initial_settings); 84 new_settings = initial_settings; 85 new_settings.c_lflag &= ~ICANON; 86 new_settings.c_lflag &= ~ECHO; 87 new_settings.c_cc[VMIN] = 1; 88 new_settings.c_cc[VTIME] = 0; 89 setTermSettings(cin_fileno, &new_settings); 90 signal(SIGINT, gotsig); 91 signal(SIGQUIT, gotsig); 92 signal(SIGTERM, gotsig); 93 #endif 76 if (ENABLE_FEATURE_USE_TERMIOS) { 77 cin_fileno = fileno(cin); 78 getTermSettings(cin_fileno, &initial_settings); 79 new_settings = initial_settings; 80 new_settings.c_lflag &= ~ICANON; 81 new_settings.c_lflag &= ~ECHO; 82 new_settings.c_cc[VMIN] = 1; 83 new_settings.c_cc[VTIME] = 0; 84 setTermSettings(cin_fileno, &new_settings); 85 bb_signals(0 86 + (1 << SIGINT) 87 + (1 << SIGQUIT) 88 + (1 << SIGTERM) 89 , gotsig); 90 } 94 91 95 92 do { … … 118 115 len = printf("--More-- "); 119 116 if (st.st_size > 0) { 120 len += printf("(% d%% of %"OFF_FMT"dbytes)",117 len += printf("(%u%% of %"OFF_FMT"u bytes)", 121 118 (int) (ftello(file)*100 / st.st_size), 122 119 st.st_size); 123 120 } 124 fflush (stdout);121 fflush_all(); 125 122 126 123 /* … … 131 128 input = getc(cin); 132 129 input = tolower(input); 133 #if !ENABLE_FEATURE_USE_TERMIOS 134 printf("\033[A"); /* up cursor */ 135 #endif 130 if (!ENABLE_FEATURE_USE_TERMIOS) 131 printf("\033[A"); /* cursor up */ 136 132 /* Erase the last message */ 137 133 printf("\r%*s\r", len, ""); … … 155 151 /* The user may have resized the terminal. 156 152 * Re-read the dimensions. */ 157 #if ENABLE_FEATURE_USE_TERMIOS 158 get_terminal_width_height(cin_fileno, &terminal_width, &terminal_height);159 terminal_height -= 1;160 #endif 153 if (ENABLE_FEATURE_USE_TERMIOS) { 154 get_terminal_width_height(cin_fileno, &terminal_width, &terminal_height); 155 terminal_height -= 1; 156 } 161 157 } 162 158 … … 166 162 spaces = CONVERTED_TAB_SIZE - 1; 167 163 c = ' '; 168 164 } 169 165 170 166 /* … … 198 194 } 199 195 fclose(file); 200 fflush (stdout);196 fflush_all(); 201 197 } while (*argv && *++argv); 202 198 end: -
branches/2.2.9/mindi-busybox/util-linux/mount.c
r1765 r2725 7 7 * Copyright (C) 2005-2006 by Rob Landley <rob@landley.net> 8 8 * 9 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.9 * Licensed under GPLv2 or later, see file LICENSE in this source tree. 10 10 */ 11 12 /* Design notes: There is no spec for mount. Remind me to write one. 13 14 mount_main() calls singlemount() which calls mount_it_now(). 15 16 mount_main() can loop through /etc/fstab for mount -a 17 singlemount() can loop through /etc/filesystems for fstype detection. 18 mount_it_now() does the actual mount. 19 */ 11 // Design notes: There is no spec for mount. Remind me to write one. 12 // 13 // mount_main() calls singlemount() which calls mount_it_now(). 14 // 15 // mount_main() can loop through /etc/fstab for mount -a 16 // singlemount() can loop through /etc/filesystems for fstype detection. 17 // mount_it_now() does the actual mount. 18 // 19 #include <mntent.h> 20 #include <syslog.h> 21 #include <sys/mount.h> 22 // Grab more as needed from util-linux's mount/mount_constants.h 23 #ifndef MS_DIRSYNC 24 # define MS_DIRSYNC (1 << 7) // Directory modifications are synchronous 25 #endif 26 #ifndef MS_UNION 27 # define MS_UNION (1 << 8) 28 #endif 29 #ifndef MS_BIND 30 # define MS_BIND (1 << 12) 31 #endif 32 #ifndef MS_MOVE 33 # define MS_MOVE (1 << 13) 34 #endif 35 #ifndef MS_RECURSIVE 36 # define MS_RECURSIVE (1 << 14) 37 #endif 38 #ifndef MS_SILENT 39 # define MS_SILENT (1 << 15) 40 #endif 41 // The shared subtree stuff, which went in around 2.6.15 42 #ifndef MS_UNBINDABLE 43 # define MS_UNBINDABLE (1 << 17) 44 #endif 45 #ifndef MS_PRIVATE 46 # define MS_PRIVATE (1 << 18) 47 #endif 48 #ifndef MS_SLAVE 49 # define MS_SLAVE (1 << 19) 50 #endif 51 #ifndef MS_SHARED 52 # define MS_SHARED (1 << 20) 53 #endif 54 #ifndef MS_RELATIME 55 # define MS_RELATIME (1 << 21) 56 #endif 20 57 21 58 #include "libbb.h" 22 #include <mntent.h> 23 24 /* Needed for nfs support only... */ 25 #include <syslog.h> 59 #if ENABLE_FEATURE_MOUNT_LABEL 60 # include "volume_id.h" 61 #else 62 # define resolve_mount_spec(fsname) ((void)0) 63 #endif 64 65 // Needed for nfs support only 26 66 #include <sys/utsname.h> 27 67 #undef TRUE 28 68 #undef FALSE 29 #include <rpc/rpc.h> 30 #include <rpc/pmap_prot.h> 31 #include <rpc/pmap_clnt.h> 69 #if ENABLE_FEATURE_MOUNT_NFS 70 /* This is just a warning of a common mistake. Possibly this should be a 71 * uclibc faq entry rather than in busybox... */ 72 # if defined(__UCLIBC__) && ! defined(__UCLIBC_HAS_RPC__) 73 # error "You need to build uClibc with UCLIBC_HAS_RPC for NFS support" 74 # endif 75 # include <rpc/rpc.h> 76 # include <rpc/pmap_prot.h> 77 # include <rpc/pmap_clnt.h> 78 #endif 32 79 33 80 34 81 #if defined(__dietlibc__) 35 /* 16.12.2006, Sampo Kellomaki (sampo@iki.fi) 36 * dietlibc-0.30 does not have implementation of getmntent_r() */ 37 /* OTOH: why we use getmntent_r instead of getmntent? TODO... */ 38 struct mntent *getmntent_r(FILE* stream, struct mntent* result, char* buffer, int bufsize) 39 { 40 /* *** XXX FIXME WARNING: This hack is NOT thread safe. --Sampo */ 82 // 16.12.2006, Sampo Kellomaki (sampo@iki.fi) 83 // dietlibc-0.30 does not have implementation of getmntent_r() 84 static struct mntent *getmntent_r(FILE* stream, struct mntent* result, 85 char* buffer UNUSED_PARAM, int bufsize UNUSED_PARAM) 86 { 41 87 struct mntent* ment = getmntent(stream); 42 memcpy(result, ment, sizeof(struct mntent)); 43 return result; 88 return memcpy(result, ment, sizeof(*ment)); 44 89 } 45 90 #endif … … 48 93 // Not real flags, but we want to be able to check for this. 49 94 enum { 50 MOUNT_USERS = (1 <<28)*ENABLE_DESKTOP,51 MOUNT_NOAUTO = (1 <<29),52 MOUNT_SWAP = (1 <<30),95 MOUNT_USERS = (1 << 28) * ENABLE_DESKTOP, 96 MOUNT_NOAUTO = (1 << 29), 97 MOUNT_SWAP = (1 << 30), 53 98 }; 99 100 101 #define OPTION_STR "o:t:rwanfvsiO:" 102 enum { 103 OPT_o = (1 << 0), 104 OPT_t = (1 << 1), 105 OPT_r = (1 << 2), 106 OPT_w = (1 << 3), 107 OPT_a = (1 << 4), 108 OPT_n = (1 << 5), 109 OPT_f = (1 << 6), 110 OPT_v = (1 << 7), 111 OPT_s = (1 << 8), 112 OPT_i = (1 << 9), 113 OPT_O = (1 << 10), 114 }; 115 116 #if ENABLE_FEATURE_MTAB_SUPPORT 117 #define USE_MTAB (!(option_mask32 & OPT_n)) 118 #else 119 #define USE_MTAB 0 120 #endif 121 122 #if ENABLE_FEATURE_MOUNT_FAKE 123 #define FAKE_IT (option_mask32 & OPT_f) 124 #else 125 #define FAKE_IT 0 126 #endif 127 128 #if ENABLE_FEATURE_MOUNT_HELPERS 129 #define HELPERS_ALLOWED (!(option_mask32 & OPT_i)) 130 #else 131 #define HELPERS_ALLOWED 0 132 #endif 133 134 54 135 // TODO: more "user" flag compatibility. 55 136 // "user" option (from mount manpage): … … 61 142 // the console user owner of this device. 62 143 63 /* Standard mount options (from -o options or --options), with corresponding 64 * flags */ 65 66 struct { 67 const char *name; 68 long flags; 69 } static mount_options[] = { 144 // Standard mount options (from -o options or --options), 145 // with corresponding flags 146 static const int32_t mount_options[] = { 70 147 // MS_FLAGS set a bit. ~MS_FLAGS disable that bit. 0 flags are NOPs. 71 148 72 USE_FEATURE_MOUNT_LOOP(73 {"loop", 0},149 IF_FEATURE_MOUNT_LOOP( 150 /* "loop" */ 0, 74 151 ) 75 152 76 USE_FEATURE_MOUNT_FSTAB( 77 {"defaults", 0}, 78 /* {"quiet", 0}, - do not filter out, vfat wants to see it */ 79 {"noauto", MOUNT_NOAUTO}, 80 {"sw", MOUNT_SWAP}, 81 {"swap", MOUNT_SWAP}, 82 USE_DESKTOP({"user", MOUNT_USERS},) 83 USE_DESKTOP({"users", MOUNT_USERS},) 153 IF_FEATURE_MOUNT_FSTAB( 154 /* "defaults" */ 0, 155 /* "quiet" 0 - do not filter out, vfat wants to see it */ 156 /* "noauto" */ MOUNT_NOAUTO, 157 /* "sw" */ MOUNT_SWAP, 158 /* "swap" */ MOUNT_SWAP, 159 IF_DESKTOP(/* "user" */ MOUNT_USERS,) 160 IF_DESKTOP(/* "users" */ MOUNT_USERS,) 161 /* "_netdev" */ 0, 84 162 ) 85 163 86 USE_FEATURE_MOUNT_FLAGS(164 IF_FEATURE_MOUNT_FLAGS( 87 165 // vfs flags 88 {"nosuid", MS_NOSUID}, 89 {"suid", ~MS_NOSUID}, 90 {"dev", ~MS_NODEV}, 91 {"nodev", MS_NODEV}, 92 {"exec", ~MS_NOEXEC}, 93 {"noexec", MS_NOEXEC}, 94 {"sync", MS_SYNCHRONOUS}, 95 {"async", ~MS_SYNCHRONOUS}, 96 {"atime", ~MS_NOATIME}, 97 {"noatime", MS_NOATIME}, 98 {"diratime", ~MS_NODIRATIME}, 99 {"nodiratime", MS_NODIRATIME}, 100 {"loud", ~MS_SILENT}, 166 /* "nosuid" */ MS_NOSUID, 167 /* "suid" */ ~MS_NOSUID, 168 /* "dev" */ ~MS_NODEV, 169 /* "nodev" */ MS_NODEV, 170 /* "exec" */ ~MS_NOEXEC, 171 /* "noexec" */ MS_NOEXEC, 172 /* "sync" */ MS_SYNCHRONOUS, 173 /* "dirsync" */ MS_DIRSYNC, 174 /* "async" */ ~MS_SYNCHRONOUS, 175 /* "atime" */ ~MS_NOATIME, 176 /* "noatime" */ MS_NOATIME, 177 /* "diratime" */ ~MS_NODIRATIME, 178 /* "nodiratime" */ MS_NODIRATIME, 179 /* "mand" */ MS_MANDLOCK, 180 /* "nomand" */ ~MS_MANDLOCK, 181 /* "relatime" */ MS_RELATIME, 182 /* "norelatime" */ ~MS_RELATIME, 183 /* "loud" */ ~MS_SILENT, 101 184 102 185 // action flags 103 104 {"bind", MS_BIND},105 {"move", MS_MOVE},106 {"shared", MS_SHARED},107 {"slave", MS_SLAVE},108 {"private", MS_PRIVATE},109 {"unbindable", MS_UNBINDABLE},110 {"rshared", MS_SHARED|MS_RECURSIVE},111 {"rslave", MS_SLAVE|MS_RECURSIVE},112 {"rprivate", MS_SLAVE|MS_RECURSIVE},113 {"runbindable", MS_UNBINDABLE|MS_RECURSIVE},186 /* "union" */ MS_UNION, 187 /* "bind" */ MS_BIND, 188 /* "move" */ MS_MOVE, 189 /* "shared" */ MS_SHARED, 190 /* "slave" */ MS_SLAVE, 191 /* "private" */ MS_PRIVATE, 192 /* "unbindable" */ MS_UNBINDABLE, 193 /* "rshared" */ MS_SHARED|MS_RECURSIVE, 194 /* "rslave" */ MS_SLAVE|MS_RECURSIVE, 195 /* "rprivate" */ MS_SLAVE|MS_RECURSIVE, 196 /* "runbindable" */ MS_UNBINDABLE|MS_RECURSIVE, 114 197 ) 115 198 116 199 // Always understood. 117 118 {"ro", MS_RDONLY}, // vfs flag 119 {"rw", ~MS_RDONLY}, // vfs flag 120 {"remount", MS_REMOUNT}, // action flag 200 /* "ro" */ MS_RDONLY, // vfs flag 201 /* "rw" */ ~MS_RDONLY, // vfs flag 202 /* "remount" */ MS_REMOUNT // action flag 121 203 }; 122 204 123 124 /* Append mount options to string */ 205 static const char mount_option_str[] = 206 IF_FEATURE_MOUNT_LOOP( 207 "loop\0" 208 ) 209 IF_FEATURE_MOUNT_FSTAB( 210 "defaults\0" 211 // "quiet\0" - do not filter out, vfat wants to see it 212 "noauto\0" 213 "sw\0" 214 "swap\0" 215 IF_DESKTOP("user\0") 216 IF_DESKTOP("users\0") 217 "_netdev\0" 218 ) 219 IF_FEATURE_MOUNT_FLAGS( 220 // vfs flags 221 "nosuid\0" 222 "suid\0" 223 "dev\0" 224 "nodev\0" 225 "exec\0" 226 "noexec\0" 227 "sync\0" 228 "dirsync\0" 229 "async\0" 230 "atime\0" 231 "noatime\0" 232 "diratime\0" 233 "nodiratime\0" 234 "mand\0" 235 "nomand\0" 236 "relatime\0" 237 "norelatime\0" 238 "loud\0" 239 240 // action flags 241 "union\0" 242 "bind\0" 243 "move\0" 244 "shared\0" 245 "slave\0" 246 "private\0" 247 "unbindable\0" 248 "rshared\0" 249 "rslave\0" 250 "rprivate\0" 251 "runbindable\0" 252 ) 253 254 // Always understood. 255 "ro\0" // vfs flag 256 "rw\0" // vfs flag 257 "remount\0" // action flag 258 ; 259 260 261 struct globals { 262 #if ENABLE_FEATURE_MOUNT_NFS 263 smalluint nfs_mount_version; 264 #endif 265 #if ENABLE_FEATURE_MOUNT_VERBOSE 266 unsigned verbose; 267 #endif 268 llist_t *fslist; 269 char getmntent_buf[1]; 270 } FIX_ALIASING; 271 enum { GETMNTENT_BUFSIZE = COMMON_BUFSIZE - offsetof(struct globals, getmntent_buf) }; 272 #define G (*(struct globals*)&bb_common_bufsiz1) 273 #define nfs_mount_version (G.nfs_mount_version) 274 #if ENABLE_FEATURE_MOUNT_VERBOSE 275 #define verbose (G.verbose ) 276 #else 277 #define verbose 0 278 #endif 279 #define fslist (G.fslist ) 280 #define getmntent_buf (G.getmntent_buf ) 281 282 283 #if ENABLE_FEATURE_MOUNT_VERBOSE 284 static int verbose_mount(const char *source, const char *target, 285 const char *filesystemtype, 286 unsigned long mountflags, const void *data) 287 { 288 int rc; 289 290 errno = 0; 291 rc = mount(source, target, filesystemtype, mountflags, data); 292 if (verbose >= 2) 293 bb_perror_msg("mount('%s','%s','%s',0x%08lx,'%s'):%d", 294 source, target, filesystemtype, 295 mountflags, (char*)data, rc); 296 return rc; 297 } 298 #else 299 #define verbose_mount(...) mount(__VA_ARGS__) 300 #endif 301 302 // Append mount options to string 125 303 static void append_mount_options(char **oldopts, const char *newopts) 126 304 { 127 305 if (*oldopts && **oldopts) { 128 / * do not insert options which are already there */306 // Do not insert options which are already there 129 307 while (newopts[0]) { 130 308 char *p; … … 135 313 while (1) { 136 314 if (!strncmp(p, newopts, len) 137 && (p[len] ==',' || p[len]==0))315 && (p[len] == ',' || p[len] == '\0')) 138 316 goto skip; 139 317 p = strchr(p,','); … … 144 322 free(*oldopts); 145 323 *oldopts = p; 146 skip:324 skip: 147 325 newopts += len; 148 326 while (newopts[0] == ',') newopts++; … … 154 332 } 155 333 156 / *Use the mount_options list to parse options into flags.157 * Also return list of unrecognized options if unrecognized!=NULL */ 158 static intparse_mount_options(char *options, char **unrecognized)159 { 160 intflags = MS_SILENT;334 // Use the mount_options list to parse options into flags. 335 // Also update list of unrecognized options if unrecognized != NULL 336 static long parse_mount_options(char *options, char **unrecognized) 337 { 338 long flags = MS_SILENT; 161 339 162 340 // Loop through options 163 341 for (;;) { 164 inti;342 unsigned i; 165 343 char *comma = strchr(options, ','); 166 167 if (comma) *comma = 0; 168 344 const char *option_str = mount_option_str; 345 346 if (comma) *comma = '\0'; 347 348 // FIXME: use hasmntopt() 169 349 // Find this option in mount_options 170 350 for (i = 0; i < ARRAY_SIZE(mount_options); i++) { 171 if (!strcasecmp(mount_options[i].name, options)) { 172 long fl = mount_options[i].flags; 173 if (fl < 0) flags &= fl; 174 else flags |= fl; 175 break; 351 if (strcasecmp(option_str, options) == 0) { 352 long fl = mount_options[i]; 353 if (fl < 0) 354 flags &= fl; 355 else 356 flags |= fl; 357 goto found; 176 358 } 177 } 178 // If unrecognized not NULL, append unrecognized mount options */ 179 if (unrecognized && i == ARRAY_SIZE(mount_options)) { 359 option_str += strlen(option_str) + 1; 360 } 361 // We did not recognize this option. 362 // If "unrecognized" is not NULL, append option there. 363 // Note that we should not append *empty* option - 364 // in this case we want to pass NULL, not "", to "data" 365 // parameter of mount(2) syscall. 366 // This is crucial for filesystems that don't accept 367 // any arbitrary mount options, like cgroup fs: 368 // "mount -t cgroup none /mnt" 369 if (options[0] && unrecognized) { 180 370 // Add it to strflags, to pass on to kernel 181 i = *unrecognized ? strlen(*unrecognized) : 0; 182 *unrecognized = xrealloc(*unrecognized, i+strlen(options)+2); 371 char *p = *unrecognized; 372 unsigned len = p ? strlen(p) : 0; 373 *unrecognized = p = xrealloc(p, len + strlen(options) + 2); 183 374 184 375 // Comma separated if it's not the first one 185 if ( i) (*unrecognized)[i++] = ',';186 strcpy( (*unrecognized)+i, options);187 } 188 189 // Advance to next option, or finish190 if (comma) {191 *comma = ',';192 options = ++comma;193 } else break;376 if (len) p[len++] = ','; 377 strcpy(p + len, options); 378 } 379 found: 380 if (!comma) 381 break; 382 // Advance to next option 383 *comma = ','; 384 options = ++comma; 194 385 } 195 386 … … 198 389 199 390 // Return a list of all block device backed filesystems 200 201 391 static llist_t *get_block_backed_filesystems(void) 202 392 { … … 206 396 }; 207 397 char *fs, *buf; 208 llist_t *list = 0;398 llist_t *list = NULL; 209 399 int i; 210 400 FILE *f; 211 401 212 402 for (i = 0; i < 2; i++) { 213 f = fopen (filesystems[i], "r");403 f = fopen_for_read(filesystems[i]); 214 404 if (!f) continue; 215 405 216 while ((buf = xmalloc_ getline(f)) != 0) {217 if ( !strncmp(buf, "nodev", 5)&& isspace(buf[5]))406 while ((buf = xmalloc_fgetline(f)) != NULL) { 407 if (strncmp(buf, "nodev", 5) == 0 && isspace(buf[5])) 218 408 continue; 219 409 fs = skip_whitespace(buf); 220 if (*fs=='#' || *fs=='*' || !*fs) continue; 410 if (*fs == '#' || *fs == '*' || !*fs) 411 continue; 221 412 222 413 llist_add_to_end(&list, xstrdup(fs)); … … 229 420 } 230 421 231 llist_t *fslist = 0;232 233 422 #if ENABLE_FEATURE_CLEAN_UP 234 423 static void delete_block_backed_filesystems(void) … … 240 429 #endif 241 430 242 #if ENABLE_FEATURE_MTAB_SUPPORT243 static int useMtab = 1;244 static int fakeIt;245 #else246 #define useMtab 0247 #define fakeIt 0248 #endif249 250 431 // Perform actual mount of specific filesystem at specific location. 251 432 // NB: mp->xxx fields may be trashed on exit 252 static int mount_it_now(struct mntent *mp, intvfsflags, char *filteropts)433 static int mount_it_now(struct mntent *mp, long vfsflags, char *filteropts) 253 434 { 254 435 int rc = 0; 255 436 256 if (fakeIt) goto mtab; 437 if (FAKE_IT) { 438 if (verbose >= 2) 439 bb_error_msg("would do mount('%s','%s','%s',0x%08lx,'%s')", 440 mp->mnt_fsname, mp->mnt_dir, mp->mnt_type, 441 vfsflags, filteropts); 442 goto mtab; 443 } 257 444 258 445 // Mount, with fallback to read-only if necessary. 259 260 446 for (;;) { 261 rc = mount(mp->mnt_fsname, mp->mnt_dir, mp->mnt_type, 447 errno = 0; 448 rc = verbose_mount(mp->mnt_fsname, mp->mnt_dir, mp->mnt_type, 262 449 vfsflags, filteropts); 263 if (!rc || (vfsflags&MS_RDONLY) || (errno!=EACCES && errno!=EROFS)) 450 451 // If mount failed, try 452 // helper program mount.<mnt_type> 453 if (HELPERS_ALLOWED && rc && mp->mnt_type) { 454 char *args[8]; 455 int errno_save = errno; 456 args[0] = xasprintf("mount.%s", mp->mnt_type); 457 rc = 1; 458 if (FAKE_IT) 459 args[rc++] = (char *)"-f"; 460 if (ENABLE_FEATURE_MTAB_SUPPORT && !USE_MTAB) 461 args[rc++] = (char *)"-n"; 462 args[rc++] = mp->mnt_fsname; 463 args[rc++] = mp->mnt_dir; 464 if (filteropts) { 465 args[rc++] = (char *)"-o"; 466 args[rc++] = filteropts; 467 } 468 args[rc] = NULL; 469 rc = spawn_and_wait(args); 470 free(args[0]); 471 if (!rc) 472 break; 473 errno = errno_save; 474 } 475 476 if (!rc || (vfsflags & MS_RDONLY) || (errno != EACCES && errno != EROFS)) 264 477 break; 265 bb_error_msg("%s is write-protected, mounting read-only", 266 mp->mnt_fsname); 478 if (!(vfsflags & MS_SILENT)) 479 bb_error_msg("%s is write-protected, mounting read-only", 480 mp->mnt_fsname); 267 481 vfsflags |= MS_RDONLY; 268 482 } … … 273 487 bb_error_msg_and_die(bb_msg_perm_denied_are_you_root); 274 488 275 / *If the mount was successful, and we're maintaining an old-style276 * mtab file by hand, add the new entry to it now. */489 // If the mount was successful, and we're maintaining an old-style 490 // mtab file by hand, add the new entry to it now. 277 491 mtab: 278 if ( ENABLE_FEATURE_MTAB_SUPPORT && useMtab&& !rc && !(vfsflags & MS_REMOUNT)) {492 if (USE_MTAB && !rc && !(vfsflags & MS_REMOUNT)) { 279 493 char *fsname; 280 494 FILE *mountTable = setmntent(bb_path_mtab_file, "a+"); 495 const char *option_str = mount_option_str; 281 496 int i; 282 497 283 498 if (!mountTable) { 284 bb_error_msg("no %s", bb_path_mtab_file);499 bb_error_msg("no %s", bb_path_mtab_file); 285 500 goto ret; 286 501 } … … 288 503 // Add vfs string flags 289 504 290 for (i=0; mount_options[i].flags != MS_REMOUNT; i++) 291 if (mount_options[i].flags > 0 && (mount_options[i].flags & vfsflags)) 292 append_mount_options(&(mp->mnt_opts), mount_options[i].name); 505 for (i = 0; mount_options[i] != MS_REMOUNT; i++) { 506 if (mount_options[i] > 0 && (mount_options[i] & vfsflags)) 507 append_mount_options(&(mp->mnt_opts), option_str); 508 option_str += strlen(option_str) + 1; 509 } 293 510 294 511 // Remove trailing / (if any) from directory we mounted on 295 512 296 513 i = strlen(mp->mnt_dir) - 1; 297 if (i > 0 && mp->mnt_dir[i] == '/') mp->mnt_dir[i] = 0;514 if (i > 0 && mp->mnt_dir[i] == '/') mp->mnt_dir[i] = '\0'; 298 515 299 516 // Convert to canonical pathnames as needed … … 301 518 mp->mnt_dir = bb_simplify_path(mp->mnt_dir); 302 519 fsname = 0; 303 if (!mp->mnt_type || !*mp->mnt_type) { / * bind mount */520 if (!mp->mnt_type || !*mp->mnt_type) { // bind mount 304 521 mp->mnt_fsname = fsname = bb_simplify_path(mp->mnt_fsname); 305 522 mp->mnt_type = (char*)"bind"; … … 326 543 * Copyright (C) 1993 Rick Sladkey <jrs@world.std.com> 327 544 * 328 * Licensed under GPLv2, see file LICENSE in this tarball for details.545 * Licensed under GPLv2, see file LICENSE in this source tree. 329 546 * 330 547 * Wed Feb 8 12:51:48 1995, biro@yggdrasil.com (Ross Biro): allow all port … … 337 554 * Implemented the "bg", "fg" and "retry" mount options for NFS. 338 555 * 339 * 1999-02-22 Arkadiusz Mi ¶kiewicz <misiek@misiek.eu.org>556 * 1999-02-22 Arkadiusz Mickiewicz <misiek@misiek.eu.org> 340 557 * - added Native Language Support 341 558 * … … 343 560 * plus NFSv3 stuff. 344 561 */ 345 346 /* This is just a warning of a common mistake. Possibly this should be a347 * uclibc faq entry rather than in busybox... */348 #if defined(__UCLIBC__) && ! defined(__UCLIBC_HAS_RPC__)349 #error "You need to build uClibc with UCLIBC_HAS_RPC for NFS support."350 #endif351 562 352 563 #define MOUNTPORT 635 … … 527 738 NFS_MOUNT_VER3 = 0x0080, /* 3 */ 528 739 NFS_MOUNT_KERBEROS = 0x0100, /* 3 */ 529 NFS_MOUNT_NONLM = 0x0200 /* 3 */ 740 NFS_MOUNT_NONLM = 0x0200, /* 3 */ 741 NFS_MOUNT_NORDIRPLUS = 0x4000 530 742 }; 531 743 … … 539 751 * it cannot even be used as a struct tag or field name". 540 752 */ 541 542 753 #ifndef EDQUOT 543 #define EDQUOT ENOSPC 544 #endif 545 546 // Convert each NFSERR_BLAH into EBLAH 547 548 static const struct { 549 int stat; 550 int errnum; 551 } nfs_errtbl[] = { 552 {0,0}, {1,EPERM}, {2,ENOENT}, {5,EIO}, {6,ENXIO}, {13,EACCES}, {17,EEXIST}, 553 {19,ENODEV}, {20,ENOTDIR}, {21,EISDIR}, {22,EINVAL}, {27,EFBIG}, 554 {28,ENOSPC}, {30,EROFS}, {63,ENAMETOOLONG}, {66,ENOTEMPTY}, {69,EDQUOT}, 555 {70,ESTALE}, {71,EREMOTE}, {-1,EIO} 754 # define EDQUOT ENOSPC 755 #endif 756 /* Convert each NFSERR_BLAH into EBLAH */ 757 static const uint8_t nfs_err_stat[] = { 758 1, 2, 5, 6, 13, 17, 759 19, 20, 21, 22, 27, 28, 760 30, 63, 66, 69, 70, 71 556 761 }; 557 762 #if ( \ 763 EPERM | ENOENT | EIO | ENXIO | EACCES| EEXIST | \ 764 ENODEV| ENOTDIR | EISDIR | EINVAL| EFBIG | ENOSPC | \ 765 EROFS | ENAMETOOLONG| ENOTEMPTY| EDQUOT| ESTALE| EREMOTE) < 256 766 typedef uint8_t nfs_err_type; 767 #else 768 typedef uint16_t nfs_err_type; 769 #endif 770 static const nfs_err_type nfs_err_errnum[] = { 771 EPERM , ENOENT , EIO , ENXIO , EACCES, EEXIST, 772 ENODEV, ENOTDIR , EISDIR , EINVAL, EFBIG , ENOSPC, 773 EROFS , ENAMETOOLONG, ENOTEMPTY, EDQUOT, ESTALE, EREMOTE 774 }; 558 775 static char *nfs_strerror(int status) 559 776 { 560 777 int i; 561 static char buf[sizeof("unknown nfs status return value: ") + sizeof(int)*3]; 562 563 for (i = 0; nfs_errtbl[i].stat != -1; i++) { 564 if (nfs_errtbl[i].stat == status) 565 return strerror(nfs_errtbl[i].errnum); 566 } 567 sprintf(buf, "unknown nfs status return value: %d", status); 568 return buf; 778 779 for (i = 0; i < ARRAY_SIZE(nfs_err_stat); i++) { 780 if (nfs_err_stat[i] == status) 781 return strerror(nfs_err_errnum[i]); 782 } 783 return xasprintf("unknown nfs status return value: %d", status); 569 784 } 570 785 571 786 static bool_t xdr_fhandle(XDR *xdrs, fhandle objp) 572 787 { 573 if (!xdr_opaque(xdrs, objp, FHSIZE)) 574 return FALSE; 575 return TRUE; 788 return xdr_opaque(xdrs, objp, FHSIZE); 576 789 } 577 790 … … 580 793 if (!xdr_u_int(xdrs, &objp->fhs_status)) 581 794 return FALSE; 582 switch (objp->fhs_status) { 583 case 0: 584 if (!xdr_fhandle(xdrs, objp->fhstatus_u.fhs_fhandle)) 585 return FALSE; 586 break; 587 default: 588 break; 589 } 795 if (objp->fhs_status == 0) 796 return xdr_fhandle(xdrs, objp->fhstatus_u.fhs_fhandle); 590 797 return TRUE; 591 798 } … … 593 800 static bool_t xdr_dirpath(XDR *xdrs, dirpath *objp) 594 801 { 595 if (!xdr_string(xdrs, objp, MNTPATHLEN)) 596 return FALSE; 597 return TRUE; 802 return xdr_string(xdrs, objp, MNTPATHLEN); 598 803 } 599 804 600 805 static bool_t xdr_fhandle3(XDR *xdrs, fhandle3 *objp) 601 806 { 602 if (!xdr_bytes(xdrs, (char **)&objp->fhandle3_val, (unsigned int *) &objp->fhandle3_len, FHSIZE3))603 return FALSE;604 return TRUE;807 return xdr_bytes(xdrs, (char **)&objp->fhandle3_val, 808 (unsigned int *) &objp->fhandle3_len, 809 FHSIZE3); 605 810 } 606 811 … … 609 814 if (!xdr_fhandle3(xdrs, &objp->fhandle)) 610 815 return FALSE; 611 if (!xdr_array(xdrs, &(objp->auth_flavours.auth_flavours_val), &(objp->auth_flavours.auth_flavours_len), ~0, 612 sizeof (int), (xdrproc_t) xdr_int)) 613 return FALSE; 614 return TRUE; 816 return xdr_array(xdrs, &(objp->auth_flavours.auth_flavours_val), 817 &(objp->auth_flavours.auth_flavours_len), 818 ~0, 819 sizeof(int), 820 (xdrproc_t) xdr_int); 615 821 } 616 822 617 823 static bool_t xdr_mountstat3(XDR *xdrs, mountstat3 *objp) 618 824 { 619 if (!xdr_enum(xdrs, (enum_t *) objp)) 620 return FALSE; 621 return TRUE; 825 return xdr_enum(xdrs, (enum_t *) objp); 622 826 } 623 827 … … 626 830 if (!xdr_mountstat3(xdrs, &objp->fhs_status)) 627 831 return FALSE; 628 switch (objp->fhs_status) { 629 case MNT_OK: 630 if (!xdr_mountres3_ok(xdrs, &objp->mountres3_u.mountinfo)) 631 return FALSE; 632 break; 633 default: 634 break; 635 } 832 if (objp->fhs_status == MNT_OK) 833 return xdr_mountres3_ok(xdrs, &objp->mountres3_u.mountinfo); 636 834 return TRUE; 637 835 } 638 836 639 837 #define MAX_NFSPROT ((nfs_mount_version >= 4) ? 3 : 2) 640 641 /*642 * nfs_mount_version according to the sources seen at compile time.643 */644 static int nfs_mount_version;645 static int kernel_version;646 838 647 839 /* … … 659 851 find_kernel_nfs_mount_version(void) 660 852 { 661 if (kernel_version) 853 int kernel_version; 854 855 if (nfs_mount_version) 662 856 return; 663 857 … … 666 860 kernel_version = get_linux_version_code(); 667 861 if (kernel_version) { 668 if (kernel_version < KERNEL_VERSION(2,1,32)) 669 nfs_mount_version = 1; 670 else if (kernel_version < KERNEL_VERSION(2,2,18) || 671 (kernel_version >= KERNEL_VERSION(2,3,0) && 672 kernel_version < KERNEL_VERSION(2,3,99))) 862 if (kernel_version < KERNEL_VERSION(2,2,18)) 673 863 nfs_mount_version = 3; 674 864 /* else v4 since 2.3.99pre4 */ … … 676 866 } 677 867 678 static struct pmap * 679 get_mountport(struct sockaddr_in *server_addr, 868 static void 869 get_mountport(struct pmap *pm_mnt, 870 struct sockaddr_in *server_addr, 680 871 long unsigned prog, 681 872 long unsigned version, … … 684 875 { 685 876 struct pmaplist *pmap; 686 static struct pmap p = {0, 0, 0, 0};687 877 688 878 server_addr->sin_port = PMAPPORT; … … 695 885 if (!prog) 696 886 prog = MOUNTPROG; 697 p .pm_prog = prog;698 p .pm_vers = version;699 p .pm_prot = proto;700 p .pm_port = port;887 pm_mnt->pm_prog = prog; 888 pm_mnt->pm_vers = version; 889 pm_mnt->pm_prot = proto; 890 pm_mnt->pm_port = port; 701 891 702 892 while (pmap) { 703 893 if (pmap->pml_map.pm_prog != prog) 704 894 goto next; 705 if (!version && p .pm_vers > pmap->pml_map.pm_vers)895 if (!version && pm_mnt->pm_vers > pmap->pml_map.pm_vers) 706 896 goto next; 707 897 if (version > 2 && pmap->pml_map.pm_vers != version) … … 709 899 if (version && version <= 2 && pmap->pml_map.pm_vers > 2) 710 900 goto next; 711 if (pmap->pml_map.pm_vers > MAX_NFSPROT || 712 (proto && p.pm_prot && pmap->pml_map.pm_prot != proto) || 713 (port && pmap->pml_map.pm_port != port)) 901 if (pmap->pml_map.pm_vers > MAX_NFSPROT 902 || (proto && pm_mnt->pm_prot && pmap->pml_map.pm_prot != proto) 903 || (port && pmap->pml_map.pm_port != port) 904 ) { 714 905 goto next; 715 memcpy(&p, &pmap->pml_map, sizeof(p)); 716 next: 906 } 907 memcpy(pm_mnt, &pmap->pml_map, sizeof(*pm_mnt)); 908 next: 717 909 pmap = pmap->pml_next; 718 910 } 719 if (!p .pm_vers)720 p .pm_vers = MOUNTVERS;721 if (!p .pm_port)722 p .pm_port = MOUNTPORT;723 if (!p .pm_prot)724 p .pm_prot = IPPROTO_TCP;725 return &p; 726 } 727 911 if (!pm_mnt->pm_vers) 912 pm_mnt->pm_vers = MOUNTVERS; 913 if (!pm_mnt->pm_port) 914 pm_mnt->pm_port = MOUNTPORT; 915 if (!pm_mnt->pm_prot) 916 pm_mnt->pm_prot = IPPROTO_TCP; 917 } 918 919 #if BB_MMU 728 920 static int daemonize(void) 729 921 { 730 int fd;731 922 int pid = fork(); 732 923 if (pid < 0) /* error */ … … 735 926 return 0; 736 927 /* child */ 737 fd = xopen(bb_dev_null, O_RDWR); 738 dup2(fd, 0); 739 dup2(fd, 1); 740 dup2(fd, 2); 741 while (fd > 2) close(fd--); 928 close(0); 929 xopen(bb_dev_null, O_RDWR); 930 xdup2(0, 1); 931 xdup2(0, 2); 742 932 setsid(); 743 933 openlog(applet_name, LOG_PID, LOG_DAEMON); … … 745 935 return 1; 746 936 } 747 748 // TODO 749 static inline int we_saw_this_host_before(const char *hostname) 937 #else 938 static inline int daemonize(void) { return -ENOSYS; } 939 #endif 940 941 /* TODO */ 942 static inline int we_saw_this_host_before(const char *hostname UNUSED_PARAM) 750 943 { 751 944 return 0; … … 765 958 } 766 959 767 / / NB: mp->xxx fields may be trashed on exit768 static int nfsmount(struct mntent *mp, intvfsflags, char *filteropts)960 /* NB: mp->xxx fields may be trashed on exit */ 961 static NOINLINE int nfsmount(struct mntent *mp, long vfsflags, char *filteropts) 769 962 { 770 963 CLIENT *mclient; … … 772 965 char *pathname; 773 966 char *mounthost; 967 /* prior to 2.6.23, kernel took NFS options in a form of this struct 968 * only. 2.6.23+ looks at data->version, and if it's not 1..6, 969 * then data pointer is interpreted as a string. */ 774 970 struct nfs_mount_data data; 775 971 char *opt; … … 787 983 int mountport; 788 984 int proto; 789 int bg; 790 int soft; 791 int intr; 792 int posix; 793 int nocto; 794 int noac; 795 int nolock; 985 #if BB_MMU 986 smallint bg = 0; 987 #else 988 enum { bg = 0 }; 989 #endif 796 990 int retry; 797 int tcp;798 991 int mountprog; 799 992 int mountvers; … … 801 994 int nfsvers; 802 995 int retval; 996 /* these all are one-bit really. gcc 4.3.1 likes this combination: */ 997 smallint tcp; 998 smallint soft; 999 int intr; 1000 int posix; 1001 int nocto; 1002 int noac; 1003 int nordirplus; 1004 int nolock; 803 1005 804 1006 find_kernel_nfs_mount_version(); … … 834 1036 goto fail; 835 1037 } 836 if (hp->h_length > sizeof(struct in_addr)) { 837 bb_error_msg("got bad hp->h_length"); 838 hp->h_length = sizeof(struct in_addr); 839 } 840 memcpy(&server_addr.sin_addr, 841 hp->h_addr, hp->h_length); 1038 if (hp->h_length != (int)sizeof(struct in_addr)) { 1039 bb_error_msg_and_die("only IPv4 is supported"); 1040 } 1041 memcpy(&server_addr.sin_addr, hp->h_addr_list[0], sizeof(struct in_addr)); 842 1042 } 843 1043 … … 861 1061 * timeo is filled in after we know whether it'll be TCP or UDP. */ 862 1062 memset(&data, 0, sizeof(data)); 863 data.retrans = 3; 864 data.acregmin = 3; 865 data.acregmax = 60; 866 data.acdirmin = 30; 867 data.acdirmax = 60; 868 data.namlen = NAME_MAX; 869 870 bg = 0; 1063 data.retrans = 3; 1064 data.acregmin = 3; 1065 data.acregmax = 60; 1066 data.acdirmin = 30; 1067 data.acdirmax = 60; 1068 data.namlen = NAME_MAX; 1069 871 1070 soft = 0; 872 1071 intr = 0; … … 875 1074 nolock = 0; 876 1075 noac = 0; 1076 nordirplus = 0; 877 1077 retry = 10000; /* 10000 minutes ~ 1 week */ 878 1078 tcp = 0; … … 889 1089 char *opteq = strchr(opt, '='); 890 1090 if (opteq) { 1091 int val, idx; 891 1092 static const char options[] ALIGN1 = 892 1093 /* 0 */ "rsize\0" … … 911 1112 /* 19 */ "namlen\0" 912 1113 /* 20 */ "addr\0"; 913 int val = xatoi_u(opteq + 1); 914 *opteq = '\0'; 915 switch (index_in_strings(options, opt)) { 1114 1115 *opteq++ = '\0'; 1116 idx = index_in_strings(options, opt); 1117 switch (idx) { 1118 case 12: // "mounthost" 1119 mounthost = xstrndup(opteq, 1120 strcspn(opteq, " \t\n\r,")); 1121 continue; 1122 case 18: // "proto" 1123 if (!strncmp(opteq, "tcp", 3)) 1124 tcp = 1; 1125 else if (!strncmp(opteq, "udp", 3)) 1126 tcp = 0; 1127 else 1128 bb_error_msg("warning: unrecognized proto= option"); 1129 continue; 1130 case 20: // "addr" - ignore 1131 continue; 1132 } 1133 1134 val = xatoi_positive(opteq); 1135 switch (idx) { 916 1136 case 0: // "rsize" 917 1137 data.rsize = val; 918 break;1138 continue; 919 1139 case 1: // "wsize" 920 1140 data.wsize = val; 921 break;1141 continue; 922 1142 case 2: // "timeo" 923 1143 data.timeo = val; 924 break;1144 continue; 925 1145 case 3: // "retrans" 926 1146 data.retrans = val; 927 break;1147 continue; 928 1148 case 4: // "acregmin" 929 1149 data.acregmin = val; 930 break;1150 continue; 931 1151 case 5: // "acregmax" 932 1152 data.acregmax = val; 933 break;1153 continue; 934 1154 case 6: // "acdirmin" 935 1155 data.acdirmin = val; 936 break;1156 continue; 937 1157 case 7: // "acdirmax" 938 1158 data.acdirmax = val; 939 break;1159 continue; 940 1160 case 8: // "actimeo" 941 1161 data.acregmin = val; … … 943 1163 data.acdirmin = val; 944 1164 data.acdirmax = val; 945 break;1165 continue; 946 1166 case 9: // "retry" 947 1167 retry = val; 948 break;1168 continue; 949 1169 case 10: // "port" 950 1170 port = val; 951 break;1171 continue; 952 1172 case 11: // "mountport" 953 1173 mountport = val; 954 break; 955 case 12: // "mounthost" 956 mounthost = xstrndup(opteq+1, 957 strcspn(opteq+1," \t\n\r,")); 958 break; 1174 continue; 959 1175 case 13: // "mountprog" 960 1176 mountprog = val; 961 break;1177 continue; 962 1178 case 14: // "mountvers" 963 1179 mountvers = val; 964 break;1180 continue; 965 1181 case 15: // "nfsprog" 966 1182 nfsprog = val; 967 break;1183 continue; 968 1184 case 16: // "nfsvers" 969 1185 case 17: // "vers" 970 1186 nfsvers = val; 971 break; 972 case 18: // "proto" 973 if (!strncmp(opteq+1, "tcp", 3)) 974 tcp = 1; 975 else if (!strncmp(opteq+1, "udp", 3)) 976 tcp = 0; 977 else 978 bb_error_msg("warning: unrecognized proto= option"); 979 break; 1187 continue; 980 1188 case 19: // "namlen" 981 if (nfs_mount_version >= 2)1189 //if (nfs_mount_version >= 2) 982 1190 data.namlen = val; 983 else 984 bb_error_msg("warning: option namlen is not supported\n"); 985 break; 986 case 20: // "addr" - ignore 987 break; 1191 //else 1192 // bb_error_msg("warning: option namlen is not supported\n"); 1193 continue; 988 1194 default: 989 1195 bb_error_msg("unknown nfs mount parameter: %s=%d", opt, val); … … 991 1197 } 992 1198 } 993 else { 1199 else { /* not of the form opt=val */ 994 1200 static const char options[] ALIGN1 = 995 1201 "bg\0" … … 1003 1209 "tcp\0" 1004 1210 "udp\0" 1005 "lock\0"; 1211 "lock\0" 1212 "rdirplus\0"; 1006 1213 int val = 1; 1007 1214 if (!strncmp(opt, "no", 2)) { … … 1011 1218 switch (index_in_strings(options, opt)) { 1012 1219 case 0: // "bg" 1220 #if BB_MMU 1013 1221 bg = val; 1222 #endif 1014 1223 break; 1015 1224 case 1: // "fg" 1225 #if BB_MMU 1016 1226 bg = !val; 1227 #endif 1017 1228 break; 1018 1229 case 2: // "soft" … … 1046 1257 bb_error_msg("warning: option nolock is not supported"); 1047 1258 break; 1259 case 11: //rdirplus 1260 nordirplus = !val; 1261 break; 1048 1262 default: 1049 1263 bb_error_msg("unknown nfs mount option: %s%s", val ? "" : "no", opt); … … 1058 1272 | (posix ? NFS_MOUNT_POSIX : 0) 1059 1273 | (nocto ? NFS_MOUNT_NOCTO : 0) 1060 | (noac ? NFS_MOUNT_NOAC : 0); 1274 | (noac ? NFS_MOUNT_NOAC : 0) 1275 | (nordirplus ? NFS_MOUNT_NORDIRPLUS : 0); 1061 1276 if (nfs_mount_version >= 2) 1062 1277 data.flags |= (tcp ? NFS_MOUNT_TCP : 0); … … 1088 1303 */ 1089 1304 if (bg && we_saw_this_host_before(hostname)) { 1090 daemonized = daemonize(); /* parent or error */1305 daemonized = daemonize(); 1091 1306 if (daemonized <= 0) { /* parent or error */ 1092 1307 retval = -daemonized; … … 1095 1310 } 1096 1311 1097 /* create mount daemon client */1312 /* Create mount daemon client */ 1098 1313 /* See if the nfs host = mount host. */ 1099 1314 if (mounthost) { … … 1106 1321 bb_herror_msg("%s", mounthost); 1107 1322 goto fail; 1108 } else {1109 if (hp->h_length > sizeof(struct in_addr)) {1110 bb_error_msg("got bad hp->h_length?");1111 hp->h_length = sizeof(struct in_addr);1112 }1113 mount_server_addr.sin_family = AF_INET;1114 memcpy(&mount_server_addr.sin_addr,1115 hp->h_addr, hp->h_length);1116 1323 } 1324 if (hp->h_length != (int)sizeof(struct in_addr)) { 1325 bb_error_msg_and_die("only IPv4 is supported"); 1326 } 1327 mount_server_addr.sin_family = AF_INET; 1328 memcpy(&mount_server_addr.sin_addr, hp->h_addr_list[0], sizeof(struct in_addr)); 1117 1329 } 1118 1330 } … … 1133 1345 struct timeval total_timeout; 1134 1346 struct timeval retry_timeout; 1135 struct pmap *pm_mnt;1347 struct pmap pm_mnt; 1136 1348 time_t t; 1137 1349 time_t prevt; … … 1142 1354 total_timeout.tv_sec = 20; 1143 1355 total_timeout.tv_usec = 0; 1356 /* FIXME: use monotonic()? */ 1144 1357 timeout = time(NULL) + 60 * retry; 1145 1358 prevt = 0; 1146 1359 t = 30; 1147 retry:1148 /* be careful not to use too many CPU cycles */1360 retry: 1361 /* Be careful not to use too many CPU cycles */ 1149 1362 if (t - prevt < 30) 1150 1363 sleep(30); 1151 1364 1152 pm_mnt = get_mountport(&mount_server_addr,1365 get_mountport(&pm_mnt, &mount_server_addr, 1153 1366 mountprog, 1154 1367 mountvers, 1155 1368 proto, 1156 1369 mountport); 1157 nfsvers = (pm_mnt ->pm_vers < 2) ? 2 : pm_mnt->pm_vers;1370 nfsvers = (pm_mnt.pm_vers < 2) ? 2 : pm_mnt.pm_vers; 1158 1371 1159 1372 /* contact the mount daemon via TCP */ 1160 mount_server_addr.sin_port = htons(pm_mnt ->pm_port);1373 mount_server_addr.sin_port = htons(pm_mnt.pm_port); 1161 1374 msock = RPC_ANYSOCK; 1162 1375 1163 switch (pm_mnt ->pm_prot) {1376 switch (pm_mnt.pm_prot) { 1164 1377 case IPPROTO_UDP: 1165 1378 mclient = clntudp_create(&mount_server_addr, 1166 pm_mnt ->pm_prog,1167 pm_mnt ->pm_vers,1379 pm_mnt.pm_prog, 1380 pm_mnt.pm_vers, 1168 1381 retry_timeout, 1169 1382 &msock); 1170 1383 if (mclient) 1171 1384 break; 1172 mount_server_addr.sin_port = htons(pm_mnt ->pm_port);1385 mount_server_addr.sin_port = htons(pm_mnt.pm_port); 1173 1386 msock = RPC_ANYSOCK; 1174 1387 case IPPROTO_TCP: 1175 1388 mclient = clnttcp_create(&mount_server_addr, 1176 pm_mnt ->pm_prog,1177 pm_mnt ->pm_vers,1389 pm_mnt.pm_prog, 1390 pm_mnt.pm_vers, 1178 1391 &msock, 0, 0); 1179 1392 break; 1180 1393 default: 1181 mclient = 0;1394 mclient = NULL; 1182 1395 } 1183 1396 if (!mclient) { … … 1186 1399 } else { 1187 1400 enum clnt_stat clnt_stat; 1188 /* try to mount hostname:pathname */ 1401 1402 /* Try to mount hostname:pathname */ 1189 1403 mclient->cl_auth = authunix_create_default(); 1190 1404 1191 /* make pointers in xdr_mountres3 NULL so1405 /* Make pointers in xdr_mountres3 NULL so 1192 1406 * that xdr_array allocates memory for us 1193 1407 */ 1194 1408 memset(&status, 0, sizeof(status)); 1195 1409 1196 if (pm_mnt ->pm_vers == 3)1410 if (pm_mnt.pm_vers == 3) 1197 1411 clnt_stat = clnt_call(mclient, MOUNTPROC3_MNT, 1198 1412 (xdrproc_t) xdr_dirpath, … … 1220 1434 auth_destroy(mclient->cl_auth); 1221 1435 clnt_destroy(mclient); 1222 mclient = 0;1436 mclient = NULL; 1223 1437 close(msock); 1438 msock = -1; 1224 1439 } 1225 1440 1226 1441 /* Timeout. We are going to retry... maybe */ 1227 1228 1442 if (!bg) 1229 1443 goto fail; … … 1244 1458 } 1245 1459 1246 prepare_kernel_data:1460 prepare_kernel_data: 1247 1461 1248 1462 if (nfsvers == 2) { … … 1279 1493 } 1280 1494 1281 /* create nfs socket for kernel */ 1282 1495 /* Create nfs socket for kernel */ 1283 1496 if (tcp) { 1284 1497 if (nfs_mount_version < 3) { … … 1306 1519 server_addr.sin_port = htons(port); 1307 1520 1308 /* prepare data structure for kernel */ 1309 1521 /* Prepare data structure for kernel */ 1310 1522 data.fd = fsock; 1311 1523 memcpy((char *) &data.addr, (char *) &server_addr, sizeof(data.addr)); 1312 1524 strncpy(data.hostname, hostname, sizeof(data.hostname)); 1313 1525 1314 /* clean up */ 1315 1526 /* Clean up */ 1316 1527 auth_destroy(mclient->cl_auth); 1317 1528 clnt_destroy(mclient); 1318 1529 close(msock); 1530 msock = -1; 1319 1531 1320 1532 if (bg) { … … 1326 1538 daemonized = daemonize(); 1327 1539 if (daemonized <= 0) { /* parent or error */ 1540 /* FIXME: parent doesn't close fsock - ??! */ 1328 1541 retval = -daemonized; 1329 1542 goto ret; … … 1337 1550 } 1338 1551 1339 do_mount: /* perform actual mount */1340 1552 /* Perform actual mount */ 1553 do_mount: 1341 1554 mp->mnt_type = (char*)"nfs"; 1342 1555 retval = mount_it_now(mp, vfsflags, (char*)&data); 1343 1556 goto ret; 1344 1557 1345 fail: /* abort */1346 1347 if (msock != -1) {1558 /* Abort */ 1559 fail: 1560 if (msock >= 0) { 1348 1561 if (mclient) { 1349 1562 auth_destroy(mclient->cl_auth); … … 1352 1565 close(msock); 1353 1566 } 1354 if (fsock != -1)1567 if (fsock >= 0) 1355 1568 close(fsock); 1356 1569 1357 ret:1570 ret: 1358 1571 free(hostname); 1359 1572 free(mounthost); … … 1362 1575 } 1363 1576 1364 #else / * !ENABLE_FEATURE_MOUNT_NFS */1365 1366 / * Never called. Call should be optimized out. */1367 int nfsmount(struct mntent *mp, intvfsflags, char *filteropts);1368 1369 #endif / * !ENABLE_FEATURE_MOUNT_NFS */1577 #else // !ENABLE_FEATURE_MOUNT_NFS 1578 1579 // Never called. Call should be optimized out. 1580 int nfsmount(struct mntent *mp, long vfsflags, char *filteropts); 1581 1582 #endif // !ENABLE_FEATURE_MOUNT_NFS 1370 1583 1371 1584 // Mount one directory. Handles CIFS, NFS, loopback, autobind, and filesystem … … 1374 1587 static int singlemount(struct mntent *mp, int ignore_busy) 1375 1588 { 1376 int rc = -1, vfsflags; 1377 char *loopFile = 0, *filteropts = 0; 1378 llist_t *fl = 0; 1589 int rc = -1; 1590 long vfsflags; 1591 char *loopFile = NULL, *filteropts = NULL; 1592 llist_t *fl = NULL; 1379 1593 struct stat st; 1380 1594 1595 errno = 0; 1596 1381 1597 vfsflags = parse_mount_options(mp->mnt_opts, &filteropts); 1382 1598 1383 // Treat fstype "auto" as unspecified. 1384 1385 if (mp->mnt_type && strcmp(mp->mnt_type,"auto") == 0) 1386 mp->mnt_type = 0; 1599 // Treat fstype "auto" as unspecified 1600 if (mp->mnt_type && strcmp(mp->mnt_type, "auto") == 0) 1601 mp->mnt_type = NULL; 1602 1603 // Might this be a virtual filesystem? 1604 if (ENABLE_FEATURE_MOUNT_HELPERS && strchr(mp->mnt_fsname, '#')) { 1605 char *args[35]; 1606 char *s; 1607 int n; 1608 // fsname: "cmd#arg1#arg2..." 1609 // WARNING: allows execution of arbitrary commands! 1610 // Try "mount 'sh#-c#sh' bogus_dir". 1611 // It is safe ONLY because non-root 1612 // cannot use two-argument mount command 1613 // and using one-argument "mount 'sh#-c#sh'" doesn't work: 1614 // "mount: can't find sh#-c#sh in /etc/fstab" 1615 // (if /etc/fstab has it, it's ok: root sets up /etc/fstab). 1616 1617 s = mp->mnt_fsname; 1618 n = 0; 1619 args[n++] = s; 1620 while (*s && n < 35 - 2) { 1621 if (*s++ == '#' && *s != '#') { 1622 s[-1] = '\0'; 1623 args[n++] = s; 1624 } 1625 } 1626 args[n++] = mp->mnt_dir; 1627 args[n] = NULL; 1628 rc = spawn_and_wait(args); 1629 goto report_error; 1630 } 1387 1631 1388 1632 // Might this be an CIFS filesystem? 1389 1390 1633 if (ENABLE_FEATURE_MOUNT_CIFS 1391 && (!mp->mnt_type || strcmp(mp->mnt_type, "cifs") == 0)1392 && (mp->mnt_fsname[0] =='/' || mp->mnt_fsname[0]=='\\')1393 && mp->mnt_fsname[0] ==mp->mnt_fsname[1]1634 && (!mp->mnt_type || strcmp(mp->mnt_type, "cifs") == 0) 1635 && (mp->mnt_fsname[0] == '/' || mp->mnt_fsname[0] == '\\') 1636 && mp->mnt_fsname[0] == mp->mnt_fsname[1] 1394 1637 ) { 1638 int len; 1639 char c; 1395 1640 len_and_sockaddr *lsa; 1396 char *ip, *dotted; 1397 char *s; 1398 1399 rc = 1; 1400 // Replace '/' with '\' and verify that unc points to "//server/share". 1401 1402 for (s = mp->mnt_fsname; *s; ++s) 1403 if (*s == '/') *s = '\\'; 1404 1405 // get server IP 1406 1407 s = strrchr(mp->mnt_fsname, '\\'); 1408 if (s <= mp->mnt_fsname+1) goto report_error; 1409 *s = '\0'; 1410 lsa = host2sockaddr(mp->mnt_fsname+2, 0); 1411 *s = '\\'; 1412 if (!lsa) goto report_error; 1413 1414 // insert ip=... option into string flags. 1415 1416 dotted = xmalloc_sockaddr2dotted_noport(&lsa->sa); 1641 char *hostname, *dotted, *ip; 1642 1643 hostname = mp->mnt_fsname + 2; 1644 len = strcspn(hostname, "/\\"); 1645 if (len == 0 || hostname[len] == '\0') 1646 goto report_error; 1647 c = hostname[len]; 1648 hostname[len] = '\0'; 1649 lsa = host2sockaddr(hostname, 0); 1650 hostname[len] = c; 1651 if (!lsa) 1652 goto report_error; 1653 1654 // Insert "ip=..." option into options 1655 dotted = xmalloc_sockaddr2dotted_noport(&lsa->u.sa); 1656 if (ENABLE_FEATURE_CLEAN_UP) free(lsa); 1417 1657 ip = xasprintf("ip=%s", dotted); 1658 if (ENABLE_FEATURE_CLEAN_UP) free(dotted); 1418 1659 parse_mount_options(ip, &filteropts); 1419 1420 // compose new unc '\\server-ip\share' 1421 // (s => slash after hostname) 1422 1423 mp->mnt_fsname = xasprintf("\\\\%s%s", dotted, s); 1424 1425 // lock is required 1660 if (ENABLE_FEATURE_CLEAN_UP) free(ip); 1661 1662 // "-o mand" is required [why?] 1426 1663 vfsflags |= MS_MANDLOCK; 1427 1428 1664 mp->mnt_type = (char*)"cifs"; 1429 1665 rc = mount_it_now(mp, vfsflags, filteropts); 1430 if (ENABLE_FEATURE_CLEAN_UP) { 1431 free(mp->mnt_fsname); 1432 free(ip); 1433 free(dotted); 1434 free(lsa); 1435 } 1666 1436 1667 goto report_error; 1437 1668 } 1438 1669 1439 1670 // Might this be an NFS filesystem? 1440 1441 1671 if (ENABLE_FEATURE_MOUNT_NFS 1442 && (!mp->mnt_type || !strcmp(mp->mnt_type, "nfs"))1672 && (!mp->mnt_type || strcmp(mp->mnt_type, "nfs") == 0) 1443 1673 && strchr(mp->mnt_fsname, ':') != NULL 1444 1674 ) { … … 1451 1681 // (We use stat, not lstat, in order to allow 1452 1682 // mount symlink_to_file_or_blkdev dir) 1453 1454 1683 if (!stat(mp->mnt_fsname, &st) 1455 1684 && !(vfsflags & (MS_REMOUNT | MS_BIND | MS_MOVE)) 1456 1685 ) { 1457 1686 // Do we need to allocate a loopback device for it? 1458 1459 1687 if (ENABLE_FEATURE_MOUNT_LOOP && S_ISREG(st.st_mode)) { 1460 1688 loopFile = bb_simplify_path(mp->mnt_fsname); 1461 mp->mnt_fsname = NULL; / * will receive malloced loop dev name */1462 if (set_loop(& (mp->mnt_fsname), loopFile, 0) < 0) {1689 mp->mnt_fsname = NULL; // will receive malloced loop dev name 1690 if (set_loop(&mp->mnt_fsname, loopFile, 0) < 0) { 1463 1691 if (errno == EPERM || errno == EACCES) 1464 1692 bb_error_msg(bb_msg_perm_denied_are_you_root); 1465 1693 else 1466 bb_perror_msg("can not setup loop device");1694 bb_perror_msg("can't setup loop device"); 1467 1695 return errno; 1468 1696 } 1469 1697 1470 1698 // Autodetect bind mounts 1471 1472 1699 } else if (S_ISDIR(st.st_mode) && !mp->mnt_type) 1473 1700 vfsflags |= MS_BIND; 1474 1701 } 1475 1702 1476 /* If we know the fstype (or don't need to), jump straight 1477 * to the actual mount. */ 1478 1479 if (mp->mnt_type || (vfsflags & (MS_REMOUNT | MS_BIND | MS_MOVE))) 1703 // If we know the fstype (or don't need to), jump straight 1704 // to the actual mount. 1705 if (mp->mnt_type || (vfsflags & (MS_REMOUNT | MS_BIND | MS_MOVE))) { 1480 1706 rc = mount_it_now(mp, vfsflags, filteropts); 1481 else {1707 } else { 1482 1708 // Loop through filesystem types until mount succeeds 1483 1709 // or we run out 1484 1710 1485 /* Initialize list of block backed filesystems. This has to be 1486 * done here so that during "mount -a", mounts after /proc shows up 1487 * can autodetect. */ 1488 1711 // Initialize list of block backed filesystems. 1712 // This has to be done here so that during "mount -a", 1713 // mounts after /proc shows up can autodetect. 1489 1714 if (!fslist) { 1490 1715 fslist = get_block_backed_filesystems(); … … 1496 1721 mp->mnt_type = fl->data; 1497 1722 rc = mount_it_now(mp, vfsflags, filteropts); 1498 if (!rc) break; 1723 if (!rc) 1724 break; 1499 1725 } 1500 1726 } 1501 1727 1502 1728 // If mount failed, clean up loop file (if any). 1503 1504 1729 if (ENABLE_FEATURE_MOUNT_LOOP && rc && loopFile) { 1505 1730 del_loop(mp->mnt_fsname); … … 1514 1739 free(filteropts); 1515 1740 1516 if ( rc &&errno == EBUSY && ignore_busy)1517 r c =0;1518 if (rc <0)1741 if (errno == EBUSY && ignore_busy) 1742 return 0; 1743 if (rc != 0) 1519 1744 bb_perror_msg("mounting %s on %s failed", mp->mnt_fsname, mp->mnt_dir); 1520 1521 1745 return rc; 1746 } 1747 1748 // -O support 1749 // -O interprets a list of filter options which select whether a mount 1750 // point will be mounted: only mounts with options matching *all* filtering 1751 // options will be selected. 1752 // By default each -O filter option must be present in the list of mount 1753 // options, but if it is prefixed by "no" then it must be absent. 1754 // For example, 1755 // -O a,nob,c matches -o a,c but fails to match -o a,b,c 1756 // (and also fails to match -o a because -o c is absent). 1757 // 1758 // It is different from -t in that each option is matched exactly; a leading 1759 // "no" at the beginning of one option does not negate the rest. 1760 static int match_opt(const char *fs_opt_in, const char *O_opt) 1761 { 1762 if (!O_opt) 1763 return 1; 1764 1765 while (*O_opt) { 1766 const char *fs_opt = fs_opt_in; 1767 int O_len; 1768 int match; 1769 1770 // If option begins with "no" then treat as an inverted match: 1771 // matching is a failure 1772 match = 0; 1773 if (O_opt[0] == 'n' && O_opt[1] == 'o') { 1774 match = 1; 1775 O_opt += 2; 1776 } 1777 // Isolate the current O option 1778 O_len = strchrnul(O_opt, ',') - O_opt; 1779 // Check for a match against existing options 1780 while (1) { 1781 if (strncmp(fs_opt, O_opt, O_len) == 0 1782 && (fs_opt[O_len] == '\0' || fs_opt[O_len] == ',') 1783 ) { 1784 if (match) 1785 return 0; // "no" prefix, but option found 1786 match = 1; // current O option found, go check next one 1787 break; 1788 } 1789 fs_opt = strchr(fs_opt, ','); 1790 if (!fs_opt) 1791 break; 1792 fs_opt++; 1793 } 1794 if (match == 0) 1795 return 0; // match wanted but not found 1796 if (O_opt[O_len] == '\0') // end? 1797 break; 1798 // Step to the next O option 1799 O_opt += O_len + 1; 1800 } 1801 // If we get here then everything matched 1802 return 1; 1522 1803 } 1523 1804 1524 1805 // Parse options, if necessary parse fstab/mtab, and call singlemount for 1525 1806 // each directory to be mounted. 1526 1527 static const char must_be_root[] ALIGN1 = "you must be root"; 1528 1529 int mount_main(int argc, char **argv); 1530 int mount_main(int argc, char **argv) 1531 { 1532 enum { OPT_ALL = 0x10 }; 1533 1534 char *cmdopts = xstrdup(""), *fstype=0, *storage_path=0; 1535 char *opt_o; 1807 int mount_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 1808 int mount_main(int argc UNUSED_PARAM, char **argv) 1809 { 1810 char *cmdopts = xzalloc(1); 1811 char *fstype = NULL; 1812 char *O_optmatch = NULL; 1813 char *storage_path; 1814 llist_t *lst_o = NULL; 1536 1815 const char *fstabname; 1537 1816 FILE *fstab; 1538 int i, j, rc = 0; 1817 int i, j; 1818 int rc = EXIT_SUCCESS; 1539 1819 unsigned opt; 1540 1820 struct mntent mtpair[2], *mtcur = mtpair; 1541 SKIP_DESKTOP(const int nonroot = 0;)1542 USE_DESKTOP( int nonroot = (getuid() != 0);) 1543 1544 /* parse long options, like --bind and --move. Note that -o option 1545 * and --option are synonymous. Yes, this means --remount,rw works. */1546 1547 for (i = j = 0; i < argc; i++) {1548 if (argv[i][0] == '-' && argv[i][1] == '-') {1549 append_mount_options(&cmdopts, argv[i] +2);1550 } else argv[j++] = argv[i];1551 }1552 argv[j] = 0;1553 arg c = j;1821 IF_NOT_DESKTOP(const int nonroot = 0;) 1822 1823 IF_DESKTOP(int nonroot = ) sanitize_env_if_suid(); 1824 1825 // Parse long options, like --bind and --move. Note that -o option 1826 // and --option are synonymous. Yes, this means --remount,rw works. 1827 for (i = j = 1; argv[i]; i++) { 1828 if (argv[i][0] == '-' && argv[i][1] == '-') 1829 append_mount_options(&cmdopts, argv[i] + 2); 1830 else 1831 argv[j++] = argv[i]; 1832 } 1833 argv[j] = NULL; 1554 1834 1555 1835 // Parse remaining options 1556 1557 opt = getopt32(argv, "o:t:rwanfvs", &opt_o, &fstype); 1558 if (opt & 0x1) append_mount_options(&cmdopts, opt_o); // -o 1559 //if (opt & 0x2) // -t 1560 if (opt & 0x4) append_mount_options(&cmdopts, "ro"); // -r 1561 if (opt & 0x8) append_mount_options(&cmdopts, "rw"); // -w 1562 //if (opt & 0x10) // -a 1563 if (opt & 0x20) USE_FEATURE_MTAB_SUPPORT(useMtab = 0); // -n 1564 if (opt & 0x40) USE_FEATURE_MTAB_SUPPORT(fakeIt = 1); // -f 1565 //if (opt & 0x80) // -v: verbose (ignore) 1566 //if (opt & 0x100) // -s: sloppy (ignore) 1836 // Max 2 params; -o is a list, -v is a counter 1837 opt_complementary = "?2o::" IF_FEATURE_MOUNT_VERBOSE("vv"); 1838 opt = getopt32(argv, OPTION_STR, &lst_o, &fstype, &O_optmatch 1839 IF_FEATURE_MOUNT_VERBOSE(, &verbose)); 1840 while (lst_o) append_mount_options(&cmdopts, llist_pop(&lst_o)); // -o 1841 if (opt & OPT_r) append_mount_options(&cmdopts, "ro"); // -r 1842 if (opt & OPT_w) append_mount_options(&cmdopts, "rw"); // -w 1567 1843 argv += optind; 1568 argc -= optind;1569 1570 // Three or more non-option arguments? Die with a usage message.1571 1572 if (argc > 2) bb_show_usage();1573 1844 1574 1845 // If we have no arguments, show currently mounted filesystems 1575 1576 if (!argc) { 1577 if (!(opt & OPT_ALL)) { 1846 if (!argv[0]) { 1847 if (!(opt & OPT_a)) { 1578 1848 FILE *mountTable = setmntent(bb_path_mtab_file, "r"); 1579 1849 1580 if (!mountTable) bb_error_msg_and_die("no %s", bb_path_mtab_file); 1581 1582 while (getmntent_r(mountTable, mtpair, bb_common_bufsiz1, 1583 sizeof(bb_common_bufsiz1))) 1850 if (!mountTable) 1851 bb_error_msg_and_die("no %s", bb_path_mtab_file); 1852 1853 while (getmntent_r(mountTable, &mtpair[0], getmntent_buf, 1854 GETMNTENT_BUFSIZE)) 1584 1855 { 1585 1856 // Don't show rootfs. FIXME: why?? 1586 1857 // util-linux 2.12a happily shows rootfs... 1587 //if ( !strcmp(mtpair->mnt_fsname, "rootfs")) continue;1588 1589 if (!fstype || !strcmp(mtpair->mnt_type, fstype))1858 //if (strcmp(mtpair->mnt_fsname, "rootfs") == 0) continue; 1859 1860 if (!fstype || strcmp(mtpair->mnt_type, fstype) == 0) 1590 1861 printf("%s on %s type %s (%s)\n", mtpair->mnt_fsname, 1591 1862 mtpair->mnt_dir, mtpair->mnt_type, 1592 1863 mtpair->mnt_opts); 1593 1864 } 1594 if (ENABLE_FEATURE_CLEAN_UP) endmntent(mountTable); 1865 if (ENABLE_FEATURE_CLEAN_UP) 1866 endmntent(mountTable); 1595 1867 return EXIT_SUCCESS; 1596 1868 } 1597 } else storage_path = bb_simplify_path(argv[0]); 1598 1599 // When we have two arguments, the second is the directory and we can 1600 // skip looking at fstab entirely. We can always abspath() the directory 1601 // argument when we get it. 1602 1603 if (argc == 2) { 1604 if (nonroot) 1605 bb_error_msg_and_die(must_be_root); 1606 mtpair->mnt_fsname = argv[0]; 1607 mtpair->mnt_dir = argv[1]; 1608 mtpair->mnt_type = fstype; 1609 mtpair->mnt_opts = cmdopts; 1610 rc = singlemount(mtpair, 0); 1611 goto clean_up; 1612 } 1613 1614 i = parse_mount_options(cmdopts, 0); 1869 storage_path = NULL; 1870 } else { 1871 // When we have two arguments, the second is the directory and we can 1872 // skip looking at fstab entirely. We can always abspath() the directory 1873 // argument when we get it. 1874 if (argv[1]) { 1875 if (nonroot) 1876 bb_error_msg_and_die(bb_msg_you_must_be_root); 1877 mtpair->mnt_fsname = argv[0]; 1878 mtpair->mnt_dir = argv[1]; 1879 mtpair->mnt_type = fstype; 1880 mtpair->mnt_opts = cmdopts; 1881 resolve_mount_spec(&mtpair->mnt_fsname); 1882 rc = singlemount(mtpair, /*ignore_busy:*/ 0); 1883 return rc; 1884 } 1885 storage_path = bb_simplify_path(argv[0]); // malloced 1886 } 1887 1888 // Past this point, we are handling either "mount -a [opts]" 1889 // or "mount [opts] single_param" 1890 1891 i = parse_mount_options(cmdopts, NULL); // FIXME: should be "long", not "int" 1615 1892 if (nonroot && (i & ~MS_SILENT)) // Non-root users cannot specify flags 1616 bb_error_msg_and_die( must_be_root);1893 bb_error_msg_and_die(bb_msg_you_must_be_root); 1617 1894 1618 1895 // If we have a shared subtree flag, don't worry about fstab or mtab. 1619 1620 1896 if (ENABLE_FEATURE_MOUNT_FLAGS 1621 1897 && (i & (MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE)) 1622 1898 ) { 1623 rc = mount("", argv[0], "", i, ""); 1624 if (rc) bb_perror_msg_and_die("%s", argv[0]); 1625 goto clean_up; 1899 // verbose_mount(source, target, type, flags, data) 1900 rc = verbose_mount("", argv[0], "", i, ""); 1901 if (rc) 1902 bb_simple_perror_msg_and_die(argv[0]); 1903 return rc; 1626 1904 } 1627 1905 1628 1906 // Open either fstab or mtab 1629 1630 1907 fstabname = "/etc/fstab"; 1631 1908 if (i & MS_REMOUNT) { 1909 // WARNING. I am not sure this matches util-linux's 1910 // behavior. It's possible util-linux does not 1911 // take -o opts from mtab (takes only mount source). 1632 1912 fstabname = bb_path_mtab_file; 1633 1913 } 1634 1914 fstab = setmntent(fstabname, "r"); 1635 1915 if (!fstab) 1636 bb_perror_msg_and_die("cannot read %s", fstabname); 1637 1638 // Loop through entries until we find what we're looking for. 1639 1916 bb_perror_msg_and_die("can't read '%s'", fstabname); 1917 1918 // Loop through entries until we find what we're looking for 1640 1919 memset(mtpair, 0, sizeof(mtpair)); 1641 1920 for (;;) { 1642 struct mntent *mt next= (mtcur==mtpair ? mtpair+1 : mtpair);1921 struct mntent *mtother = (mtcur==mtpair ? mtpair+1 : mtpair); 1643 1922 1644 1923 // Get next fstab entry 1645 1646 if (!getmntent_r(fstab, mtcur, bb_common_bufsiz1 1647 + (mtcur==mtpair ? sizeof(bb_common_bufsiz1)/2 : 0), 1648 sizeof(bb_common_bufsiz1)/2)) 1649 { 1650 // Were we looking for something specific? 1651 1652 if (argc) { 1653 1654 // If we didn't find anything, complain. 1655 1656 if (!mtnext->mnt_fsname) 1657 bb_error_msg_and_die("can't find %s in %s", 1658 argv[0], fstabname); 1659 1660 mtcur = mtnext; 1661 if (nonroot) { 1662 // fstab must have "users" or "user" 1663 if (!(parse_mount_options(mtcur->mnt_opts, 0) & MOUNT_USERS)) 1664 bb_error_msg_and_die(must_be_root); 1665 } 1666 1667 // Mount the last thing we found. 1668 1669 mtcur->mnt_opts = xstrdup(mtcur->mnt_opts); 1670 append_mount_options(&(mtcur->mnt_opts), cmdopts); 1671 rc = singlemount(mtcur, 0); 1672 free(mtcur->mnt_opts); 1924 if (!getmntent_r(fstab, mtcur, getmntent_buf 1925 + (mtcur==mtpair ? GETMNTENT_BUFSIZE/2 : 0), 1926 GETMNTENT_BUFSIZE/2) 1927 ) { // End of fstab/mtab is reached 1928 mtcur = mtother; // the thing we found last time 1929 break; 1930 } 1931 1932 // If we're trying to mount something specific and this isn't it, 1933 // skip it. Note we must match the exact text in fstab (ala 1934 // "proc") or a full path from root 1935 if (argv[0]) { 1936 1937 // Is this what we're looking for? 1938 if (strcmp(argv[0], mtcur->mnt_fsname) != 0 1939 && strcmp(storage_path, mtcur->mnt_fsname) != 0 1940 && strcmp(argv[0], mtcur->mnt_dir) != 0 1941 && strcmp(storage_path, mtcur->mnt_dir) != 0 1942 ) { 1943 continue; // no 1673 1944 } 1674 goto clean_up; 1675 } 1676 1677 /* If we're trying to mount something specific and this isn't it, 1678 * skip it. Note we must match both the exact text in fstab (ala 1679 * "proc") or a full path from root */ 1680 1681 if (argc) { 1682 1683 // Is this what we're looking for? 1684 1685 if (strcmp(argv[0], mtcur->mnt_fsname) && 1686 strcmp(storage_path, mtcur->mnt_fsname) && 1687 strcmp(argv[0], mtcur->mnt_dir) && 1688 strcmp(storage_path, mtcur->mnt_dir)) continue; 1689 1690 // Remember this entry. Something later may have overmounted 1691 // it, and we want the _last_ match. 1692 1693 mtcur = mtnext; 1694 1695 // If we're mounting all. 1696 1945 1946 // Remember this entry. Something later may have 1947 // overmounted it, and we want the _last_ match. 1948 mtcur = mtother; 1949 1950 // If we're mounting all 1697 1951 } else { 1698 // Do we need to match a filesystem type? 1699 if (fstype && match_fstype(mtcur, fstype)) continue; 1700 1701 // Skip noauto and swap anyway. 1702 1703 if (parse_mount_options(mtcur->mnt_opts, 0) 1704 & (MOUNT_NOAUTO | MOUNT_SWAP)) continue; 1705 1952 struct mntent *mp; 1706 1953 // No, mount -a won't mount anything, 1707 // even user mounts, for mere humans. 1708 1954 // even user mounts, for mere humans 1709 1955 if (nonroot) 1710 bb_error_msg_and_die(must_be_root); 1711 1712 // Mount this thing. 1956 bb_error_msg_and_die(bb_msg_you_must_be_root); 1957 1958 // Does type match? (NULL matches always) 1959 if (!match_fstype(mtcur, fstype)) 1960 continue; 1961 1962 // Skip noauto and swap anyway 1963 if ((parse_mount_options(mtcur->mnt_opts, NULL) & (MOUNT_NOAUTO | MOUNT_SWAP)) 1964 // swap is bogus "fstype", parse_mount_options can't check fstypes 1965 || strcasecmp(mtcur->mnt_type, "swap") == 0 1966 ) { 1967 continue; 1968 } 1969 1970 // Does (at least one) option match? 1971 // (NULL matches always) 1972 if (!match_opt(mtcur->mnt_opts, O_optmatch)) 1973 continue; 1974 1975 resolve_mount_spec(&mtcur->mnt_fsname); 1713 1976 1714 1977 // NFS mounts want this to be xrealloc-able 1715 1978 mtcur->mnt_opts = xstrdup(mtcur->mnt_opts); 1716 if (singlemount(mtcur, 1)) { 1717 /* Count number of failed mounts */ 1718 rc++; 1979 1980 // If nothing is mounted on this directory... 1981 // (otherwise repeated "mount -a" mounts everything again) 1982 mp = find_mount_point(mtcur->mnt_dir, /*subdir_too:*/ 0); 1983 // We do not check fsname match of found mount point - 1984 // "/" may have fsname of "/dev/root" while fstab 1985 // says "/dev/something_else". 1986 if (mp) { 1987 if (verbose) { 1988 bb_error_msg("according to %s, " 1989 "%s is already mounted on %s", 1990 bb_path_mtab_file, 1991 mp->mnt_fsname, mp->mnt_dir); 1992 } 1993 } else { 1994 // ...mount this thing 1995 if (singlemount(mtcur, /*ignore_busy:*/ 1)) { 1996 // Count number of failed mounts 1997 rc++; 1998 } 1719 1999 } 1720 2000 free(mtcur->mnt_opts); 1721 2001 } 1722 2002 } 1723 if (ENABLE_FEATURE_CLEAN_UP) endmntent(fstab); 1724 1725 clean_up: 1726 2003 2004 // End of fstab/mtab is reached. 2005 // Were we looking for something specific? 2006 if (argv[0]) { // yes 2007 long l; 2008 2009 // If we didn't find anything, complain 2010 if (!mtcur->mnt_fsname) 2011 bb_error_msg_and_die("can't find %s in %s", 2012 argv[0], fstabname); 2013 2014 // What happens when we try to "mount swap_partition"? 2015 // (fstab containts "swap_partition swap swap defaults 0 0") 2016 // util-linux-ng 2.13.1 does this: 2017 // stat("/sbin/mount.swap", 0x7fff62a3a350) = -1 ENOENT (No such file or directory) 2018 // mount("swap_partition", "swap", "swap", MS_MGC_VAL, NULL) = -1 ENOENT (No such file or directory) 2019 // lstat("swap", 0x7fff62a3a640) = -1 ENOENT (No such file or directory) 2020 // write(2, "mount: mount point swap does not exist\n", 39) = 39 2021 // exit_group(32) = ? 2022 #if 0 2023 // In case we want to simply skip swap partitions: 2024 l = parse_mount_options(mtcur->mnt_opts, NULL); 2025 if ((l & MOUNT_SWAP) 2026 // swap is bogus "fstype", parse_mount_options can't check fstypes 2027 || strcasecmp(mtcur->mnt_type, "swap") == 0 2028 ) { 2029 goto ret; 2030 } 2031 #endif 2032 if (nonroot) { 2033 // fstab must have "users" or "user" 2034 l = parse_mount_options(mtcur->mnt_opts, NULL); 2035 if (!(l & MOUNT_USERS)) 2036 bb_error_msg_and_die(bb_msg_you_must_be_root); 2037 } 2038 2039 //util-linux-2.12 does not do this check. 2040 //// If nothing is mounted on this directory... 2041 //// (otherwise repeated "mount FOO" mounts FOO again) 2042 //mp = find_mount_point(mtcur->mnt_dir, /*subdir_too:*/ 0); 2043 //if (mp) { 2044 // bb_error_msg("according to %s, " 2045 // "%s is already mounted on %s", 2046 // bb_path_mtab_file, 2047 // mp->mnt_fsname, mp->mnt_dir); 2048 //} else { 2049 // ...mount the last thing we found 2050 mtcur->mnt_opts = xstrdup(mtcur->mnt_opts); 2051 append_mount_options(&(mtcur->mnt_opts), cmdopts); 2052 resolve_mount_spec(&mtpair->mnt_fsname); 2053 rc = singlemount(mtcur, /*ignore_busy:*/ 0); 2054 if (ENABLE_FEATURE_CLEAN_UP) 2055 free(mtcur->mnt_opts); 2056 //} 2057 } 2058 2059 //ret: 2060 if (ENABLE_FEATURE_CLEAN_UP) 2061 endmntent(fstab); 1727 2062 if (ENABLE_FEATURE_CLEAN_UP) { 1728 2063 free(storage_path); … … 1730 2065 } 1731 2066 2067 //TODO: exitcode should be ORed mask of (from "man mount"): 2068 // 0 success 2069 // 1 incorrect invocation or permissions 2070 // 2 system error (out of memory, cannot fork, no more loop devices) 2071 // 4 internal mount bug or missing nfs support in mount 2072 // 8 user interrupt 2073 //16 problems writing or locking /etc/mtab 2074 //32 mount failure 2075 //64 some mount succeeded 1732 2076 return rc; 1733 2077 } -
branches/2.2.9/mindi-busybox/util-linux/pivot_root.c
r1765 r2725 7 7 * regardless of the kernel being used. 8 8 * 9 * Licensed under GPL version 2, see file LICENSE in this tarball for details.9 * Licensed under GPLv2, see file LICENSE in this source tree. 10 10 */ 11 11 #include "libbb.h" … … 13 13 extern int pivot_root(const char * new_root,const char * put_old); 14 14 15 int pivot_root_main(int argc, char **argv) ;15 int pivot_root_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 16 16 int pivot_root_main(int argc, char **argv) 17 17 { -
branches/2.2.9/mindi-busybox/util-linux/rdate.c
r1765 r2725 6 6 * by Sterling Huxley <sterling@europa.com> 7 7 * 8 * Licensed under GPL v2 or later, see file License for details.8 * Licensed under GPLv2 or later, see file LICENSE in this source tree. 9 9 */ 10 10 … … 13 13 enum { RFC_868_BIAS = 2208988800UL }; 14 14 15 static void socket_timeout(int sig )15 static void socket_timeout(int sig UNUSED_PARAM) 16 16 { 17 17 bb_error_msg_and_die("timeout connecting to time server"); … … 43 43 } 44 44 45 int rdate_main(int argc, char **argv) ;46 int rdate_main(int argc , char **argv)45 int rdate_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 46 int rdate_main(int argc UNUSED_PARAM, char **argv) 47 47 { 48 48 time_t remote_time; … … 62 62 else 63 63 if (stime(&remote_time) < 0) 64 bb_perror_msg_and_die("can not set time of day");64 bb_perror_msg_and_die("can't set time of day"); 65 65 } 66 66 -
branches/2.2.9/mindi-busybox/util-linux/readprofile.c
r1765 r2725 5 5 * Copyright (C) 1994,1996 Alessandro Rubini (rubini@ipvvis.unipv.it) 6 6 * 7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.7 * Licensed under GPLv2 or later, see file LICENSE in this source tree. 8 8 */ 9 9 10 10 /* 11 * 1999-02-22 Arkadiusz Mi ¶kiewicz <misiek@pld.ORG.PL>11 * 1999-02-22 Arkadiusz Mickiewicz <misiek@pld.ORG.PL> 12 12 * - added Native Language Support 13 13 * 1999-09-01 Stephane Eranian <eranian@cello.hpl.hp.com> … … 42 42 static const char defaultpro[] ALIGN1 = "/proc/profile"; 43 43 44 int readprofile_main(int argc, char **argv) ;45 int readprofile_main(int argc , char **argv)44 int readprofile_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 45 int readprofile_main(int argc UNUSED_PARAM, char **argv) 46 46 { 47 47 FILE *map; 48 const char *mapFile, *proFile , *mult = 0;48 const char *mapFile, *proFile; 49 49 unsigned long indx = 1; 50 50 size_t len; … … 56 56 char mapline[S_LEN]; 57 57 char mode[8]; 58 int optAll = 0, optInfo = 0, optReset = 0;59 int optVerbose = 0, optNative = 0;60 int optBins = 0, optSub = 0;61 58 int maplineno = 1; 62 59 int header_printed; 60 int multiplier = 0; 61 unsigned opt; 62 enum { 63 OPT_M = (1 << 0), 64 OPT_m = (1 << 1), 65 OPT_p = (1 << 2), 66 OPT_n = (1 << 3), 67 OPT_a = (1 << 4), 68 OPT_b = (1 << 5), 69 OPT_s = (1 << 6), 70 OPT_i = (1 << 7), 71 OPT_r = (1 << 8), 72 OPT_v = (1 << 9), 73 }; 74 #define optMult (opt & OPT_M) 75 #define optNative (opt & OPT_n) 76 #define optAll (opt & OPT_a) 77 #define optBins (opt & OPT_b) 78 #define optSub (opt & OPT_s) 79 #define optInfo (opt & OPT_i) 80 #define optReset (opt & OPT_r) 81 #define optVerbose (opt & OPT_v) 63 82 64 83 #define next (current^1) … … 67 86 mapFile = defaultmap; 68 87 69 opt_complementary = "nn:aa:bb:ss:ii:rr:vv"; 70 getopt32(argv, "M:m:p:nabsirv", 71 &mult, &mapFile, &proFile, 72 &optNative, &optAll, &optBins, &optSub, 73 &optInfo, &optReset, &optVerbose); 74 75 if (optReset || mult) { 76 int multiplier, fd, to_write; 88 opt_complementary = "M+"; /* -M N */ 89 opt = getopt32(argv, "M:m:p:nabsirv", &multiplier, &mapFile, &proFile); 90 91 if (opt & (OPT_M|OPT_r)) { /* mult or reset, or both */ 92 int fd, to_write; 77 93 78 94 /* … … 80 96 * not sizeof(int), the multiplier is not changed 81 97 */ 82 if (mult) { 83 multiplier = xatoi_u(mult); 84 to_write = sizeof(int); 85 } else { 86 multiplier = 0; 87 to_write = 1; /* sth different from sizeof(int) */ 88 } 98 to_write = sizeof(int); 99 if (!optMult) 100 to_write = 1; /* sth different from sizeof(int) */ 89 101 90 102 fd = xopen(defaultpro, O_WRONLY); 91 92 if (full_write(fd, &multiplier, to_write) != to_write) 93 bb_perror_msg_and_die("error writing %s", defaultpro); 94 103 xwrite(fd, &multiplier, to_write); 95 104 close(fd); 96 105 return EXIT_SUCCESS; … … 101 110 */ 102 111 len = MAXINT(ssize_t); 103 buf = xmalloc_ open_read_close(proFile, &len);112 buf = xmalloc_xopen_read_close(proFile, &len); 104 113 if (!optNative) { 105 int entries = len /sizeof(*buf);114 int entries = len / sizeof(*buf); 106 115 int big = 0, small = 0, i; 107 116 unsigned *p; … … 136 145 total = 0; 137 146 138 map = xfopen (mapFile, "r");147 map = xfopen_for_read(mapFile); 139 148 140 149 while (fgets(mapline, S_LEN, map)) { … … 168 177 Absolute symbols */ 169 178 if ((*mode == 'A' || *mode == '?') && total == 0) continue; 170 if (*mode != 'T' && *mode != 't' && 171 *mode != 'W' && *mode != 'w') 172 break; /* only text is profiled */ 179 if (*mode != 'T' && *mode != 't' 180 && *mode != 'W' && *mode != 'w' 181 ) { 182 break; /* only text is profiled */ 183 } 173 184 174 185 if (indx >= len / sizeof(*buf)) … … 191 202 if (optVerbose || this > 0) 192 203 printf(" total\t\t\t\t%u\n", this); 193 } else if ((this || optAll) && 194 (fn_len = next_add-fn_add) != 0) { 204 } else if ((this || optAll) 205 && (fn_len = next_add-fn_add) != 0 206 ) { 195 207 if (optVerbose) 196 208 printf("%016llx %-40s %6i %8.4f\n", fn_add, -
branches/2.2.9/mindi-busybox/util-linux/setarch.c
r1765 r2725 1 1 /* vi: set sw=4 ts=4: */ 2 2 /* 3 * Linux32/linux64 allows for changing uname emulation.3 * linux32/linux64 allows for changing uname emulation. 4 4 * 5 5 * Copyright 2002 Andi Kleen, SuSE Labs. 6 6 * 7 * Licensed under GPL v2 or later, see file License for details.7 * Licensed under GPLv2 or later, see file LICENSE in this source tree. 8 8 */ 9 9 … … 12 12 #include "libbb.h" 13 13 14 int setarch_main(int ATTRIBUTE_UNUSED argc, char **argv);15 int setarch_main(int ATTRIBUTE_UNUSED argc, char **argv)14 int setarch_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 15 int setarch_main(int argc UNUSED_PARAM, char **argv) 16 16 { 17 int pers = -1;17 int pers; 18 18 19 19 /* Figure out what personality we are supposed to switch to ... 20 20 * we can be invoked as either: 21 * argv[0],argv[1] ->"setarch","personality"22 * argv[0] ->"personality"21 * argv[0],argv[1] == "setarch","personality" 22 * argv[0] == "personality" 23 23 */ 24 retry: 25 if (argv[0][5] == '6') /* linux64 */ 24 if (ENABLE_SETARCH && applet_name[0] == 's' 25 && argv[1] && strncpy(argv[1], "linux", 5) 26 ) { 27 applet_name = argv[1]; 28 argv++; 29 } 30 if (applet_name[5] == '6') /* linux64 */ 26 31 pers = PER_LINUX; 27 else if (a rgv[0][5] == '3') /* linux32 */32 else if (applet_name[5] == '3') /* linux32 */ 28 33 pers = PER_LINUX32; 29 else if (pers == -1 && argv[1] != NULL) { 30 pers = PER_LINUX32; 31 ++argv; 32 goto retry; 33 } 34 else 35 bb_show_usage(); 34 36 35 /* make user actually gave us something to do */ 36 ++argv; 37 argv++; 37 38 if (argv[0] == NULL) 38 39 bb_show_usage(); … … 40 41 /* Try to set personality */ 41 42 if (personality(pers) >= 0) { 42 43 43 /* Try to execute the program */ 44 44 BB_EXECVP(argv[0], argv); 45 45 } 46 46 47 bb_ perror_msg_and_die("%s",argv[0]);47 bb_simple_perror_msg_and_die(argv[0]); 48 48 } -
branches/2.2.9/mindi-busybox/util-linux/swaponoff.c
r1765 r2725 5 5 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org> 6 6 * 7 * Licensed under the GPL version 2, see the file LICENSE in this tarball.7 * Licensed under GPLv2, see file LICENSE in this source tree. 8 8 */ 9 9 … … 12 12 #include <sys/swap.h> 13 13 14 #if ENABLE_FEATURE_MOUNT_LABEL 15 # include "volume_id.h" 16 #else 17 # define resolve_mount_spec(fsname) ((void)0) 18 #endif 19 20 #if ENABLE_FEATURE_SWAPON_PRI 21 struct globals { 22 int flags; 23 } FIX_ALIASING; 24 #define G (*(struct globals*)&bb_common_bufsiz1) 25 #define g_flags (G.flags) 26 #else 27 #define g_flags 0 28 #endif 29 14 30 static int swap_enable_disable(char *device) 15 31 { … … 17 33 struct stat st; 18 34 35 resolve_mount_spec(&device); 19 36 xstat(device, &st); 20 37 … … 22 39 /* test for holes */ 23 40 if (S_ISREG(st.st_mode)) 24 if (st.st_blocks * 512 < st.st_size)41 if (st.st_blocks * (off_t)512 < st.st_size) 25 42 bb_error_msg("warning: swap file has holes"); 26 43 #endif 27 44 28 45 if (applet_name[5] == 'n') 29 status = swapon(device, 0);46 status = swapon(device, g_flags); 30 47 else 31 48 status = swapoff(device); 32 49 33 50 if (status != 0) { 34 bb_ perror_msg("%s",device);51 bb_simple_perror_msg(device); 35 52 return 1; 36 53 } … … 50 67 51 68 err = 0; 52 while ((m = getmntent(f)) != NULL) 53 if (strcmp(m->mnt_type, MNTTYPE_SWAP) == 0) 54 err += swap_enable_disable(m->mnt_fsname); 69 while ((m = getmntent(f)) != NULL) { 70 if (strcmp(m->mnt_type, MNTTYPE_SWAP) == 0) { 71 /* swapon -a should ignore entries with noauto, 72 * but swapoff -a should process them */ 73 if (applet_name[5] != 'n' 74 || hasmntopt(m, MNTOPT_NOAUTO) == NULL 75 ) { 76 err += swap_enable_disable(m->mnt_fsname); 77 } 78 } 79 } 55 80 56 endmntent(f); 81 if (ENABLE_FEATURE_CLEAN_UP) 82 endmntent(f); 57 83 58 84 return err; 59 85 } 60 86 61 int swap_on_off_main(int argc, char **argv) ;62 int swap_on_off_main(int argc , char **argv)87 int swap_on_off_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 88 int swap_on_off_main(int argc UNUSED_PARAM, char **argv) 63 89 { 64 90 int ret; 65 91 66 if (argc == 1) 92 #if !ENABLE_FEATURE_SWAPON_PRI 93 ret = getopt32(argv, "a"); 94 #else 95 opt_complementary = "p+"; 96 ret = getopt32(argv, (applet_name[5] == 'n') ? "ap:" : "a", &g_flags); 97 98 if (ret & 2) { // -p 99 g_flags = SWAP_FLAG_PREFER | 100 ((g_flags & SWAP_FLAG_PRIO_MASK) << SWAP_FLAG_PRIO_SHIFT); 101 ret &= 1; 102 } 103 #endif 104 105 if (ret /* & 1: not needed */) // -a 106 return do_em_all(); 107 108 argv += optind; 109 if (!*argv) 67 110 bb_show_usage(); 68 111 69 ret = getopt32(argv, "a"); 70 if (ret) 71 return do_em_all(); 112 /* ret = 0; redundant */ 113 do { 114 ret += swap_enable_disable(*argv); 115 } while (*++argv); 72 116 73 /* ret = 0; redundant */74 while (*++argv)75 ret += swap_enable_disable(*argv);76 117 return ret; 77 118 } -
branches/2.2.9/mindi-busybox/util-linux/switch_root.c
r1765 r2725 4 4 * Switch from rootfs to another filesystem as the root of the mount tree. 5 5 * 6 * Licensed under GPL version 2, see file LICENSE in this tarball for details.6 * Licensed under GPLv2, see file LICENSE in this source tree. 7 7 */ 8 8 #include <sys/vfs.h> 9 #include <sys/mount.h> 9 10 #include "libbb.h" 10 #include <sys/vfs.h> 11 12 13 // Make up for header deficiencies. 14 11 // Make up for header deficiencies 15 12 #ifndef RAMFS_MAGIC 16 # define RAMFS_MAGIC 0x858458f613 # define RAMFS_MAGIC ((unsigned)0x858458f6) 17 14 #endif 18 19 15 #ifndef TMPFS_MAGIC 20 # define TMPFS_MAGIC 0x0102199416 # define TMPFS_MAGIC ((unsigned)0x01021994) 21 17 #endif 22 23 18 #ifndef MS_MOVE 24 # define MS_MOVE819219 # define MS_MOVE 8192 25 20 #endif 26 21 27 static dev_t rootdev; 28 29 // Recursively delete contents of rootfs. 30 31 static void delete_contents(const char *directory) 22 // Recursively delete contents of rootfs 23 static void delete_contents(const char *directory, dev_t rootdev) 32 24 { 33 25 DIR *dir; … … 36 28 37 29 // Don't descend into other filesystems 38 if (lstat(directory, &st) || st.st_dev != rootdev) return; 39 40 // Recursively delete the contents of directories. 30 if (lstat(directory, &st) || st.st_dev != rootdev) 31 return; 32 33 // Recursively delete the contents of directories 41 34 if (S_ISDIR(st.st_mode)) { 42 35 dir = opendir(directory); … … 46 39 47 40 // Skip . and .. 48 if ( *newdir=='.' && (!newdir[1] || (newdir[1]=='.' && !newdir[2])))41 if (DOT_OR_DOTDOT(newdir)) 49 42 continue; 50 43 51 44 // Recurse to delete contents 52 newdir = alloca(strlen(directory) + strlen(d->d_name) + 2);53 sprintf(newdir, "%s/%s", directory, d->d_name);54 delete_contents(newdir);45 newdir = concat_path_file(directory, newdir); 46 delete_contents(newdir, rootdev); 47 free(newdir); 55 48 } 56 49 closedir(dir); 57 50 58 // Directory should now be empty . Zap it.51 // Directory should now be empty, zap it 59 52 rmdir(directory); 60 53 } 61 62 // It wasn't a directory. Zap it.63 64 } else unlink(directory);54 } else { 55 // It wasn't a directory, zap it 56 unlink(directory); 57 } 65 58 } 66 59 67 int switch_root_main(int argc, char **argv) ;68 int switch_root_main(int argc , char **argv)60 int switch_root_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 61 int switch_root_main(int argc UNUSED_PARAM, char **argv) 69 62 { 70 63 char *newroot, *console = NULL; 71 struct stat st 1, st2;64 struct stat st; 72 65 struct statfs stfs; 66 dev_t rootdev; 73 67 74 68 // Parse args (-c console) 75 76 opt_complementary = "-2"; 77 getopt32(argv, "c:", &console); 69 opt_complementary = "-2"; // minimum 2 params 70 getopt32(argv, "+c:", &console); // '+': stop at first non-option 78 71 argv += optind; 79 80 // Change to new root directory and verify it's a different fs.81 82 72 newroot = *argv++; 83 73 74 // Change to new root directory and verify it's a different fs 84 75 xchdir(newroot); 85 if (lstat(".", &st1) || lstat("/", &st2) || st1.st_dev == st2.st_dev) { 86 bb_error_msg_and_die("bad newroot %s", newroot); 87 } 88 rootdev = st2.st_dev; 89 90 // Additional sanity checks: we're about to rm -rf /, so be REALLY SURE 91 // we mean it. (I could make this a CONFIG option, but I would get email 92 // from all the people who WILL eat their filesystems.) 93 94 if (lstat("/init", &st1) || !S_ISREG(st1.st_mode) || statfs("/", &stfs) || 95 (stfs.f_type != RAMFS_MAGIC && stfs.f_type != TMPFS_MAGIC) || 96 getpid() != 1) 97 { 98 bb_error_msg_and_die("not rootfs"); 76 xstat("/", &st); 77 rootdev = st.st_dev; 78 xstat(".", &st); 79 if (st.st_dev == rootdev || getpid() != 1) { 80 // Show usage, it says new root must be a mountpoint 81 // and we must be PID 1 82 bb_show_usage(); 83 } 84 85 // Additional sanity checks: we're about to rm -rf /, so be REALLY SURE 86 // we mean it. I could make this a CONFIG option, but I would get email 87 // from all the people who WILL destroy their filesystems. 88 if (stat("/init", &st) != 0 || !S_ISREG(st.st_mode)) { 89 bb_error_msg_and_die("/init is not a regular file"); 90 } 91 statfs("/", &stfs); // this never fails 92 if ((unsigned)stfs.f_type != RAMFS_MAGIC 93 && (unsigned)stfs.f_type != TMPFS_MAGIC 94 ) { 95 bb_error_msg_and_die("root filesystem is not ramfs/tmpfs"); 99 96 } 100 97 101 98 // Zap everything out of rootdev 102 103 delete_contents("/"); 104 105 // Overmount / with newdir and chroot into it. The chdir is needed to 106 // recalculate "." and ".." links. 107 108 if (mount(".", "/", NULL, MS_MOVE, NULL) || chroot(".")) 109 bb_error_msg_and_die("error moving root"); 99 delete_contents("/", rootdev); 100 101 // Overmount / with newdir and chroot into it 102 if (mount(".", "/", NULL, MS_MOVE, NULL)) { 103 // For example, fails when newroot is not a mountpoint 104 bb_perror_msg_and_die("error moving root"); 105 } 106 xchroot("."); 107 // The chdir is needed to recalculate "." and ".." links 110 108 xchdir("/"); 111 109 112 // If a new console specified, redirect stdin/stdout/stderr to that. 113 110 // If a new console specified, redirect stdin/stdout/stderr to it 114 111 if (console) { 115 112 close(0); 116 113 xopen(console, O_RDWR); 117 dup2(0, 1);118 dup2(0, 2);119 } 120 121 // Exec real init . (This is why we must be pid 1.)114 xdup2(0, 1); 115 xdup2(0, 2); 116 } 117 118 // Exec real init 122 119 execv(argv[0], argv); 123 bb_perror_msg_and_die(" bad init %s", argv[0]);120 bb_perror_msg_and_die("can't execute '%s'", argv[0]); 124 121 } 122 123 /* 124 From: Rob Landley <rob@landley.net> 125 Date: Tue, Jun 16, 2009 at 7:47 PM 126 Subject: Re: switch_root... 127 128 ... 129 ... 130 ... 131 132 If you're _not_ running out of init_ramfs (if for example you're using initrd 133 instead), you probably shouldn't use switch_root because it's the wrong tool. 134 135 Basically what the sucker does is something like the following shell script: 136 137 find / -xdev | xargs rm -rf 138 cd "$1" 139 shift 140 mount --move . / 141 exec chroot . "$@" 142 143 There are a couple reasons that won't work as a shell script: 144 145 1) If you delete the commands out of your $PATH, your shell scripts can't run 146 more commands, but you can't start using dynamically linked _new_ commands 147 until after you do the chroot because the path to the dynamic linker is wrong. 148 So there's a step that needs to be sort of atomic but can't be as a shell 149 script. (You can work around this with static linking or very carefully laid 150 out paths and sequencing, but it's brittle, ugly, and non-obvious.) 151 152 2) The "find | rm" bit will acually delete everything because the mount points 153 still show up (even if their contents don't), and rm -rf will then happily zap 154 that. So the first line is an oversimplification of what you need to do _not_ 155 to descend into other filesystems and delete their contents. 156 157 The reason we do this is to free up memory, by the way. Since initramfs is a 158 ramfs, deleting its contents frees up the memory it uses. (We leave it with 159 one remaining dentry for the new mount point, but that's ok.) 160 161 Note that you cannot ever umount rootfs, for approximately the same reason you 162 can't kill PID 1. The kernel tracks mount points as a doubly linked list, and 163 the pointer to the start/end of that list always points to an entry that's 164 known to be there (rootfs), so it never has to worry about moving that pointer 165 and it never has to worry about the list being empty. (Back around 2.6.13 166 there _was_ a bug that let you umount rootfs, and the system locked hard the 167 instant you did so endlessly looping to find the end of the mount list and 168 never stopping. They fixed it.) 169 170 Oh, and the reason we mount --move _and_ do the chroot is due to the way "/" 171 works. Each process has two special symlinks, ".", and "/". Each of them 172 points to the dentry of a directory, and give you a location paths can start 173 from. (Historically ".." was also special, because you could enter a 174 directory via a symlink so backing out to the directory you came from doesn't 175 necessarily mean the one physically above where "." points to. These days I 176 think it's just handed off to the filesystem.) 177 178 Anyway, path resolution starts with "." or "/" (although the "./" at the start 179 of the path may be implicit), meaning it's relative to one of those two 180 directories. Your current directory, and your current root directory. The 181 chdir() syscall changes where "." points to, and the chroot() syscall changes 182 where "/" points to. (Again, both are per-process which is why chroot only 183 affects your current process and its child processes.) 184 185 Note that chroot() does _not_ change where "." points to, and back before they 186 put crazy security checks into the kernel your current directory could be 187 somewhere you could no longer access after the chroot. (The command line 188 chroot does a cd as well, the chroot _syscall_ is what I'm talking about.) 189 190 The reason mounting something new over / has no obvious effect is the same 191 reason mounting something over your current directory has no obvious effect: 192 the . and / links aren't recalculated after a mount, so they still point to 193 the same dentry they did before, even if that dentry is no longer accessible 194 by other means. Note that "cd ." is a NOP, and "chroot /" is a nop; both look 195 up the cached dentry and set it right back. They don't re-parse any paths, 196 because they're what all paths your process uses would be relative to. 197 198 That's why the careful sequencing above: we cd into the new mount point before 199 we do the mount --move. Moving the mount point would otherwise make it 200 totally inaccessible to is because cd-ing to the old path wouldn't give it to 201 us anymore, and cd "/" just gives us the cached dentry from when the process 202 was created (in this case the old initramfs one). But the "." symlink gives 203 us the dentry of the filesystem we just moved, so we can then "chroot ." to 204 copy that dentry to "/" and get the new filesystem. If we _didn't_ save that 205 dentry in "." we couldn't get it back after the mount --move. 206 207 (Yes, this is all screwy and I had to email questions to Linus Torvalds to get 208 it straight myself. I keep meaning to write up a "how mount actually works" 209 document someday...) 210 */ -
branches/2.2.9/mindi-busybox/util-linux/umount.c
r1765 r2725 6 6 * Copyright (C) 2005 by Rob Landley <rob@landley.net> 7 7 * 8 * Licensed under GPL version 2, see file LICENSE in this tarball for details.8 * Licensed under GPLv2, see file LICENSE in this source tree. 9 9 */ 10 11 10 #include <mntent.h> 12 #include < getopt.h>11 #include <sys/mount.h> 13 12 #include "libbb.h" 14 13 15 #define OPTION_STRING "flDnravdt:" 16 #define OPT_FORCE 1 17 #define OPT_LAZY 2 18 #define OPT_DONTFREELOOP 4 19 #define OPT_NO_MTAB 8 20 #define OPT_REMOUNT 16 21 #define OPT_ALL (ENABLE_FEATURE_UMOUNT_ALL ? 32 : 0) 14 #if defined(__dietlibc__) 15 // TODO: This does not belong here. 16 /* 16.12.2006, Sampo Kellomaki (sampo@iki.fi) 17 * dietlibc-0.30 does not have implementation of getmntent_r() */ 18 static struct mntent *getmntent_r(FILE* stream, struct mntent* result, 19 char* buffer UNUSED_PARAM, int bufsize UNUSED_PARAM) 20 { 21 struct mntent* ment = getmntent(stream); 22 return memcpy(result, ment, sizeof(*ment)); 23 } 24 #endif 22 25 23 int umount_main(int argc, char **argv); 24 int umount_main(int argc, char **argv) 26 /* ignored: -v -d -t -i */ 27 #define OPTION_STRING "fldnra" "vdt:i" 28 #define OPT_FORCE (1 << 0) // Same as MNT_FORCE 29 #define OPT_LAZY (1 << 1) // Same as MNT_DETACH 30 #define OPT_FREELOOP (1 << 2) 31 #define OPT_NO_MTAB (1 << 3) 32 #define OPT_REMOUNT (1 << 4) 33 #define OPT_ALL (ENABLE_FEATURE_UMOUNT_ALL ? (1 << 5) : 0) 34 35 int umount_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 36 int umount_main(int argc UNUSED_PARAM, char **argv) 25 37 { 26 38 int doForce; 27 char path[2*PATH_MAX];28 39 struct mntent me; 29 40 FILE *fp; 30 char *fstype = 0;41 char *fstype = NULL; 31 42 int status = EXIT_SUCCESS; 32 43 unsigned opt; … … 37 48 } *mtl, *m; 38 49 39 /* Parse any options */40 41 50 opt = getopt32(argv, OPTION_STRING, &fstype); 42 43 argc -= optind; 51 //argc -= optind; 44 52 argv += optind; 45 53 54 // MNT_FORCE and MNT_DETACH (from linux/fs.h) must match 55 // OPT_FORCE and OPT_LAZY, otherwise this trick won't work: 46 56 doForce = MAX((opt & OPT_FORCE), (opt & OPT_LAZY)); 47 57 … … 51 61 * entry. Notice that this also naturally reverses the list so that -a 52 62 * umounts the most recent entries first. */ 63 m = mtl = NULL; 53 64 54 m = mtl = 0; 55 56 /* If we're umounting all, then m points to the start of the list and 57 * the argument list should be empty (which will match all). */ 58 65 // If we're umounting all, then m points to the start of the list and 66 // the argument list should be empty (which will match all). 59 67 fp = setmntent(bb_path_mtab_file, "r"); 60 68 if (!fp) { 61 69 if (opt & OPT_ALL) 62 bb_error_msg_and_die("can not open %s", bb_path_mtab_file);70 bb_error_msg_and_die("can't open '%s'", bb_path_mtab_file); 63 71 } else { 64 while (getmntent_r(fp, &me, path, sizeof(path))) {72 while (getmntent_r(fp, &me, bb_common_bufsiz1, sizeof(bb_common_bufsiz1))) { 65 73 /* Match fstype if passed */ 66 if ( fstype &&match_fstype(&me, fstype))74 if (!match_fstype(&me, fstype)) 67 75 continue; 68 m = x malloc(sizeof(struct mtab_list));76 m = xzalloc(sizeof(*m)); 69 77 m->next = mtl; 70 78 m->device = xstrdup(me.mnt_fsname); … … 75 83 } 76 84 77 / * If we're not umounting all, we need at least one argument. */85 // If we're not umounting all, we need at least one argument. 78 86 if (!(opt & OPT_ALL) && !fstype) { 79 m = 0; 80 if (!argc) bb_show_usage(); 87 if (!argv[0]) 88 bb_show_usage(); 89 m = NULL; 81 90 } 82 91 … … 85 94 int curstat; 86 95 char *zapit = *argv; 96 char *path; 87 97 88 98 // Do we already know what to umount this time through the loop? 89 if (m) safe_strncpy(path, m->dir, PATH_MAX); 99 if (m) 100 path = xstrdup(m->dir); 90 101 // For umount -a, end of mtab means time to exit. 91 else if (opt & OPT_ALL) break;92 // Get next command line argument (and look it up in mtab list)93 else if (!argc--) break;102 else if (opt & OPT_ALL) 103 break; 104 // Use command line argument (and look it up in mtab list) 94 105 else { 106 if (!zapit) 107 break; 95 108 argv++; 96 realpath(zapit, path); 97 for (m = mtl; m; m = m->next) 98 if (!strcmp(path, m->dir) || !strcmp(path, m->device)) 99 break; 109 path = xmalloc_realpath(zapit); 110 if (path) { 111 for (m = mtl; m; m = m->next) 112 if (strcmp(path, m->dir) == 0 || strcmp(path, m->device) == 0) 113 break; 114 } 100 115 } 101 116 // If we couldn't find this sucker in /etc/mtab, punt by passing our … … 108 123 109 124 // Force the unmount, if necessary. 110 if (curstat && doForce) {125 if (curstat && doForce) 111 126 curstat = umount2(zapit, doForce); 112 if (curstat)113 bb_error_msg("forced umount of %s failed!", zapit);114 }115 127 116 128 // If still can't umount, maybe remount read-only? 117 if (curstat && (opt & OPT_REMOUNT) && errno == EBUSY && m) {118 curstat = mount(m->device, zapit, NULL, MS_REMOUNT|MS_RDONLY, NULL);119 bb_error_msg(curstat ? "cannot remount %s read-only" :120 "%s busy - remounted read-only", m->device);121 }122 123 129 if (curstat) { 124 status = EXIT_FAILURE; 125 bb_perror_msg("cannot umount %s", zapit); 130 if ((opt & OPT_REMOUNT) && errno == EBUSY && m) { 131 // Note! Even if we succeed here, later we should not 132 // free loop device or erase mtab entry! 133 const char *msg = "%s busy - remounted read-only"; 134 curstat = mount(m->device, zapit, NULL, MS_REMOUNT|MS_RDONLY, NULL); 135 if (curstat) { 136 msg = "can't remount %s read-only"; 137 status = EXIT_FAILURE; 138 } 139 bb_error_msg(msg, m->device); 140 } else { 141 status = EXIT_FAILURE; 142 bb_perror_msg("can't %sumount %s", (doForce ? "forcibly " : ""), zapit); 143 } 126 144 } else { 127 / *De-allocate the loop device. This ioctl should be ignored on128 * any non-loop block devices. */129 if (ENABLE_FEATURE_MOUNT_LOOP && !(opt & OPT_DONTFREELOOP) && m)145 // De-allocate the loop device. This ioctl should be ignored on 146 // any non-loop block devices. 147 if (ENABLE_FEATURE_MOUNT_LOOP && (opt & OPT_FREELOOP) && m) 130 148 del_loop(m->device); 131 149 if (ENABLE_FEATURE_MTAB_SUPPORT && !(opt & OPT_NO_MTAB) && m) … … 136 154 // Note this means that "umount /dev/blah" will unmount all instances 137 155 // of /dev/blah, not just the most recent. 138 while (m && (m = m->next)) 139 if ((opt & OPT_ALL) || !strcmp(path, m->device)) 140 break; 156 if (m) { 157 while ((m = m->next) != NULL) 158 // NB: if m is non-NULL, path is non-NULL as well 159 if ((opt & OPT_ALL) || strcmp(path, m->device) == 0) 160 break; 161 } 162 free(path); 141 163 } 142 164 143 165 // Free mtab list if necessary 144 145 166 if (ENABLE_FEATURE_CLEAN_UP) { 146 167 while (mtl) {
Note:
See TracChangeset
for help on using the changeset viewer.