/*
partprobe - informs the OS kernel of partition layout
Copyright (C) 2001-2002, 2007-2014, 2019-2023 Free Software Foundation,
Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
/* it's best to compile this with:
*
* CFLAGS=-Os ./configure --disable-nls --disable-shared --disable-debug
* --enable-discover-only
*
* And strip(1) afterwards!
*/
#include
#include
#include
#include
#include
#include "closeout.h"
#include "configmake.h"
#include "progname.h"
#include "version-etc.h"
#include
#include "gettext.h"
#if ! ENABLE_NLS
# undef textdomain
# define textdomain(Domainname) /* empty */
# undef bindtextdomain
# define bindtextdomain(Domainname, Dirname) /* empty */
#endif
#undef _
#define _(msgid) gettext (msgid)
#define AUTHORS \
""
/* The official name of this program (e.g., no `g' prefix). */
#define PROGRAM_NAME "partprobe"
static struct option const long_options[] =
{
{"dry-run", no_argument, NULL, 'd'},
{"summary", no_argument, NULL, 's'},
{"help", no_argument, NULL, 'h'},
{"version", no_argument, NULL, 'v'},
{NULL, 0, NULL, 0}
};
/* initialized to 0 according to the language lawyers */
static int opt_no_inform;
static int opt_summary;
static void
summary (PedDisk* disk)
{
PedPartition* walk;
printf ("%s: %s partitions", disk->dev->path, disk->type->name);
for (walk = disk->part_list; walk; walk = walk->next) {
if (!ped_partition_is_active (walk))
continue;
printf (" %d", walk->num);
if (walk->type & PED_PARTITION_EXTENDED) {
PedPartition* log_walk;
int is_first = 1;
printf (" <");
for (log_walk = walk->part_list; log_walk;
log_walk = log_walk->next) {
if (!ped_partition_is_active (log_walk))
continue;
if (!is_first)
printf (" ");
printf ("%d", log_walk->num);
is_first = 0;
}
printf (">");
}
}
printf ("\n");
}
static int
process_dev (PedDevice* dev)
{
PedDiskType* disk_type;
PedDisk* disk;
if (!ped_device_open (dev))
return 0;
disk_type = ped_disk_probe (dev);
if (!disk_type) {
/* Partition table not found, so create dummy,
empty one */
disk_type = ped_disk_type_get("msdos");
if (!disk_type)
goto error;
disk = ped_disk_new_fresh (dev, disk_type);
if (!disk)
goto error_destroy_disk;
} else {
disk = ped_disk_new (dev);
if (!disk)
goto error;
}
if (!opt_no_inform) {
if (!ped_disk_commit_to_os (disk))
goto error_destroy_disk;
}
if (opt_summary)
summary (disk);
ped_disk_destroy (disk);
ped_device_close (dev);
return 1;
error_destroy_disk:
ped_disk_destroy (disk);
error:
ped_device_close (dev);
return 0;
}
static void
usage (int status)
{
if (status != EXIT_SUCCESS)
fprintf (stderr, _("Try `%s --help' for more information.\n"),
program_name);
else
{
printf (_("Usage: %s [OPTION] [DEVICE]...\n"), PROGRAM_NAME);
fputs (_("\
Inform the operating system about partition table changes.\n\
\n\
-d, --dry-run do not actually inform the operating system\n\
-s, --summary print a summary of contents\n\
-h, --help display this help and exit\n\
-v, --version output version information and exit\n\
"), stdout);
fputs (_("\
\n\
When no DEVICE is given, probe all partitions.\n\
"), stdout);
printf (_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
}
exit (status);
}
int
main (int argc, char* argv[])
{
int status = 0;
set_program_name (argv[0]);
setlocale (LC_ALL, "");
bindtextdomain (PACKAGE, LOCALEDIR);
textdomain (PACKAGE);
atexit (close_stdout);
int c;
while ((c = getopt_long (argc, argv, "dhsv", long_options, NULL)) != -1)
switch (c) {
case 'd':
opt_no_inform = 1;
break;
case 's':
opt_summary = 1;
break;
case 'h':
usage (EXIT_SUCCESS);
break;
case 'v':
version_etc (stdout, PROGRAM_NAME, PACKAGE_NAME,
VERSION, AUTHORS, (char *) NULL);
exit (EXIT_SUCCESS);
break;
default:
usage (EXIT_FAILURE);
}
int n_dev = argc - optind;
if (n_dev != 0) {
int i;
for (i = optind; i < argc; i++) {
PedDevice *dev = ped_device_get (argv[i]);
if (dev == NULL || process_dev (dev) == 0)
status = 1;
}
} else {
ped_device_probe_all ();
PedDevice *dev;
for (dev = ped_device_get_next (NULL); dev;
dev = ped_device_get_next (dev))
if (process_dev (dev) == 0)
status = 1;
}
return status;
}