diff options
-rw-r--r-- | src/df.c | 539 |
1 files changed, 265 insertions, 274 deletions
@@ -32,16 +32,6 @@ char *xmalloc (); char *xstrdup (); -static void add_excluded_fs_type __P ((char *fstype)); -static void add_fs_type __P ((char *fstype)); -static void print_header __P ((void)); -static void show_entry __P ((char *path, struct stat *statp)); -static void show_all_entries __P ((void)); -static void show_dev __P ((char *disk, char *mount_point, char *fstype)); -static void show_disk __P ((char *disk)); -static void show_point __P ((char *point, struct stat *statp)); -static void usage __P ((int status)); - /* The maximum length of a human-readable string. Be pessimistic and assume `int' is 64-bits wide. Converting 2^63 - 1 gives the 14-character string, 8796093022208G. The number being converted @@ -139,183 +129,6 @@ static struct option const long_options[] = {NULL, 0, NULL, 0} }; -int -main (int argc, char **argv) -{ - int i; - struct stat *stats; - - program_name = argv[0]; - setlocale (LC_ALL, ""); - bindtextdomain (PACKAGE, LOCALEDIR); - textdomain (PACKAGE); - - fs_select_list = NULL; - fs_exclude_list = NULL; - inode_format = 0; - show_all_fs = 0; - show_listed_fs = 0; - - if (getenv ("POSIXLY_CORRECT")) - kilobyte_blocks = 0; - else - { - char *bs; - kilobyte_blocks = 1; - if ((bs = getenv ("BLOCKSIZE")) - && strncmp (bs, "HUMAN", sizeof ("HUMAN") - 1) == 0) - human_blocks = 1; - } - - print_type = 0; - posix_format = 0; - exit_status = 0; - - while ((i = getopt_long (argc, argv, "aihkmPTt:vx:", long_options, NULL)) - != EOF) - { - switch (i) - { - case 0: /* Long option. */ - break; - case 'a': - show_all_fs = 1; - break; - case 'i': - inode_format = 1; - break; - case 'h': - human_blocks = 1; - kilobyte_blocks = 1; - megabyte_blocks = 0; - break; - case 'k': - human_blocks = 0; - kilobyte_blocks = 1; - megabyte_blocks = 0; - break; - case 'm': - human_blocks = 0; - kilobyte_blocks = 0; - megabyte_blocks = 1; - break; - case 'T': - print_type = 1; - break; - case 'P': - posix_format = 1; - break; - case 129: - require_sync = 1; - break; - case 130: - require_sync = 0; - break; - case 't': - add_fs_type (optarg); - break; - case 'v': /* For SysV compatibility. */ - /* ignore */ - break; - case 'x': - add_excluded_fs_type (optarg); - break; - default: - usage (1); - } - } - - if (show_version) - { - printf ("df - %s\n", PACKAGE_VERSION); - exit (0); - } - - if (show_help) - usage (0); - - if (posix_format && megabyte_blocks) - error (1, 0, _("the option for counting 1MB blocks may not be used\n\ -with the portable output format")); - - if (posix_format && human_blocks) - error (1, 0, - _("the option for printing with adaptive units may not be used\n\ -with the portable output format")); - - /* Fail if the same file system type was both selected and excluded. */ - { - int match = 0; - struct fs_type_list *i; - for (i = fs_select_list; i; i = i->fs_next) - { - struct fs_type_list *j; - for (j = fs_exclude_list; j; j = j->fs_next) - { - if (strcmp (i->fs_name, j->fs_name) == 0) - { - error (0, 0, - _("file system type `%s' both selected and excluded"), - i->fs_name); - match = 1; - break; - } - } - } - if (match) - exit (1); - } - - if (optind == argc) - { -#ifdef lint - /* Suppress `used before initialized' warning. */ - stats = NULL; -#endif - } - else - { - /* stat all the given entries to make sure they get automounted, - if necessary, before reading the filesystem table. */ - stats = (struct stat *) - xmalloc ((argc - optind) * sizeof (struct stat)); - for (i = optind; i < argc; ++i) - if (stat (argv[i], &stats[i - optind])) - { - error (0, errno, "%s", argv[i]); - exit_status = 1; - argv[i] = NULL; - } - } - - mount_list = - read_filesystem_list ((fs_select_list != NULL - || fs_exclude_list != NULL - || print_type), - show_all_fs); - - if (mount_list == NULL) - error (1, errno, _("cannot read table of mounted filesystems")); - - print_header (); - if (require_sync) - sync (); - - if (optind == argc) - show_all_entries (); - else - { - /* Display explicitly requested empty filesystems. */ - show_listed_fs = 1; - - for (i = optind; i < argc; ++i) - if (argv[i]) - show_entry (argv[i], &stats[i - optind]); - } - - exit (exit_status); -} - static void print_header (void) { @@ -339,87 +152,6 @@ print_header (void) printf (" Mounted on\n"); } -/* Show all mounted filesystems, except perhaps those that are of - an unselected type or are empty. */ - -static void -show_all_entries (void) -{ - struct mount_entry *me; - - for (me = mount_list; me; me = me->me_next) - show_dev (me->me_devname, me->me_mountdir, me->me_type); -} - -/* Determine what kind of node PATH is and show the disk usage - for it. STATP is the results of `stat' on PATH. */ - -static void -show_entry (char *path, struct stat *statp) -{ - if (S_ISBLK (statp->st_mode) || S_ISCHR (statp->st_mode)) - show_disk (path); - else - show_point (path, statp); -} - -/* Identify the directory, if any, that device - DISK is mounted on, and show its disk usage. */ - -static void -show_disk (char *disk) -{ - struct mount_entry *me; - - for (me = mount_list; me; me = me->me_next) - if (!strcmp (disk, me->me_devname)) - { - show_dev (me->me_devname, me->me_mountdir, me->me_type); - return; - } - /* No filesystem is mounted on DISK. */ - show_dev (disk, (char *) NULL, (char *) NULL); -} - -/* Figure out which device file or directory POINT is mounted on - and show its disk usage. - STATP is the results of `stat' on POINT. */ - -static void -show_point (char *point, struct stat *statp) -{ - struct stat disk_stats; - struct mount_entry *me; - - for (me = mount_list; me; me = me->me_next) - { - if (me->me_dev == (dev_t) -1) - { - if (stat (me->me_mountdir, &disk_stats) == 0) - me->me_dev = disk_stats.st_dev; - else - { - error (0, errno, "%s", me->me_mountdir); - exit_status = 1; - /* So we won't try and fail repeatedly. */ - me->me_dev = (dev_t) -2; - } - } - - if (statp->st_dev == me->me_dev) - { - /* Skip bogus mtab entries. */ - if (stat (me->me_mountdir, &disk_stats) != 0 || - disk_stats.st_dev != me->me_dev) - continue; - show_dev (me->me_devname, me->me_mountdir, me->me_type); - return; - } - } - error (0, 0, _("cannot find mount point for %s"), point); - exit_status = 1; -} - /* Convert N_1K_BYTE_BLOCKS to a more readable string than %d would. Most people visually process strings of 3-4 digits effectively, but longer strings of digits are more prone to misinterpretation. @@ -508,14 +240,14 @@ excluded_fstype (const char *fstype) If FSTYPE is non-NULL, it is the type of the filesystem on DISK. */ static void -show_dev (char *disk, char *mount_point, char *fstype) +show_dev (const char *disk, const char *mount_point, const char *fstype) { struct fs_usage fsu; long blocks_used; long blocks_percent_used; long inodes_used; long inodes_percent_used; - char *stat_file; + const char *stat_file; if (!selected_fstype (fstype) || excluded_fstype (fstype)) return; @@ -612,15 +344,96 @@ show_dev (char *disk, char *mount_point, char *fstype) putchar ('\n'); } +/* Identify the directory, if any, that device + DISK is mounted on, and show its disk usage. */ + +static void +show_disk (const char *disk) +{ + struct mount_entry *me; + + for (me = mount_list; me; me = me->me_next) + if (!strcmp (disk, me->me_devname)) + { + show_dev (me->me_devname, me->me_mountdir, me->me_type); + return; + } + /* No filesystem is mounted on DISK. */ + show_dev (disk, (char *) NULL, (char *) NULL); +} + +/* Figure out which device file or directory POINT is mounted on + and show its disk usage. + STATP is the results of `stat' on POINT. */ + +static void +show_point (const char *point, const struct stat *statp) +{ + struct stat disk_stats; + struct mount_entry *me; + + for (me = mount_list; me; me = me->me_next) + { + if (me->me_dev == (dev_t) -1) + { + if (stat (me->me_mountdir, &disk_stats) == 0) + me->me_dev = disk_stats.st_dev; + else + { + error (0, errno, "%s", me->me_mountdir); + exit_status = 1; + /* So we won't try and fail repeatedly. */ + me->me_dev = (dev_t) -2; + } + } + + if (statp->st_dev == me->me_dev) + { + /* Skip bogus mtab entries. */ + if (stat (me->me_mountdir, &disk_stats) != 0 || + disk_stats.st_dev != me->me_dev) + continue; + show_dev (me->me_devname, me->me_mountdir, me->me_type); + return; + } + } + error (0, 0, _("cannot find mount point for %s"), point); + exit_status = 1; +} + +/* Determine what kind of node PATH is and show the disk usage + for it. STATP is the results of `stat' on PATH. */ + +static void +show_entry (const char *path, const struct stat *statp) +{ + if (S_ISBLK (statp->st_mode) || S_ISCHR (statp->st_mode)) + show_disk (path); + else + show_point (path, statp); +} + +/* Show all mounted filesystems, except perhaps those that are of + an unselected type or are empty. */ + +static void +show_all_entries (void) +{ + struct mount_entry *me; + + for (me = mount_list; me; me = me->me_next) + show_dev (me->me_devname, me->me_mountdir, me->me_type); +} + /* Add FSTYPE to the list of filesystem types to display. */ static void -add_fs_type (char *fstype) +add_fs_type (const char *fstype) { struct fs_type_list *fsp; fsp = (struct fs_type_list *) xmalloc (sizeof (struct fs_type_list)); - fsp->fs_name = fstype; + fsp->fs_name = (char *) fstype; fsp->fs_next = fs_select_list; fs_select_list = fsp; } @@ -628,12 +441,12 @@ add_fs_type (char *fstype) /* Add FSTYPE to the list of filesystem types to be omitted. */ static void -add_excluded_fs_type (char *fstype) +add_excluded_fs_type (const char *fstype) { struct fs_type_list *fsp; fsp = (struct fs_type_list *) xmalloc (sizeof (struct fs_type_list)); - fsp->fs_name = fstype; + fsp->fs_name = (char *) fstype; fsp->fs_next = fs_exclude_list; fs_exclude_list = fsp; } @@ -668,3 +481,181 @@ or all filesystems by default.\n\ } exit (status); } + +int +main (int argc, char **argv) +{ + int i; + struct stat *stats; + + program_name = argv[0]; + setlocale (LC_ALL, ""); + bindtextdomain (PACKAGE, LOCALEDIR); + textdomain (PACKAGE); + + fs_select_list = NULL; + fs_exclude_list = NULL; + inode_format = 0; + show_all_fs = 0; + show_listed_fs = 0; + + if (getenv ("POSIXLY_CORRECT")) + kilobyte_blocks = 0; + else + { + char *bs; + kilobyte_blocks = 1; + if ((bs = getenv ("BLOCKSIZE")) + && strncmp (bs, "HUMAN", sizeof ("HUMAN") - 1) == 0) + human_blocks = 1; + } + + print_type = 0; + posix_format = 0; + exit_status = 0; + + while ((i = getopt_long (argc, argv, "aihkmPTt:vx:", long_options, NULL)) + != EOF) + { + switch (i) + { + case 0: /* Long option. */ + break; + case 'a': + show_all_fs = 1; + break; + case 'i': + inode_format = 1; + break; + case 'h': + human_blocks = 1; + kilobyte_blocks = 1; + megabyte_blocks = 0; + break; + case 'k': + human_blocks = 0; + kilobyte_blocks = 1; + megabyte_blocks = 0; + break; + case 'm': + human_blocks = 0; + kilobyte_blocks = 0; + megabyte_blocks = 1; + break; + case 'T': + print_type = 1; + break; + case 'P': + posix_format = 1; + break; + case 129: + require_sync = 1; + break; + case 130: + require_sync = 0; + break; + case 't': + add_fs_type (optarg); + break; + case 'v': /* For SysV compatibility. */ + /* ignore */ + break; + case 'x': + add_excluded_fs_type (optarg); + break; + default: + usage (1); + } + } + + if (show_version) + { + printf ("df - %s\n", PACKAGE_VERSION); + exit (0); + } + + if (show_help) + usage (0); + + if (posix_format && megabyte_blocks) + error (1, 0, _("the option for counting 1MB blocks may not be used\n\ +with the portable output format")); + + if (posix_format && human_blocks) + error (1, 0, + _("the option for printing with adaptive units may not be used\n\ +with the portable output format")); + + /* Fail if the same file system type was both selected and excluded. */ + { + int match = 0; + struct fs_type_list *i; + for (i = fs_select_list; i; i = i->fs_next) + { + struct fs_type_list *j; + for (j = fs_exclude_list; j; j = j->fs_next) + { + if (strcmp (i->fs_name, j->fs_name) == 0) + { + error (0, 0, + _("file system type `%s' both selected and excluded"), + i->fs_name); + match = 1; + break; + } + } + } + if (match) + exit (1); + } + + if (optind == argc) + { +#ifdef lint + /* Suppress `used before initialized' warning. */ + stats = NULL; +#endif + } + else + { + /* stat all the given entries to make sure they get automounted, + if necessary, before reading the filesystem table. */ + stats = (struct stat *) + xmalloc ((argc - optind) * sizeof (struct stat)); + for (i = optind; i < argc; ++i) + if (stat (argv[i], &stats[i - optind])) + { + error (0, errno, "%s", argv[i]); + exit_status = 1; + argv[i] = NULL; + } + } + + mount_list = + read_filesystem_list ((fs_select_list != NULL + || fs_exclude_list != NULL + || print_type), + show_all_fs); + + if (mount_list == NULL) + error (1, errno, _("cannot read table of mounted filesystems")); + + print_header (); + if (require_sync) + sync (); + + if (optind == argc) + show_all_entries (); + else + { + /* Display explicitly requested empty filesystems. */ + show_listed_fs = 1; + + for (i = optind; i < argc; ++i) + if (argv[i]) + show_entry (argv[i], &stats[i - optind]); + } + + exit (exit_status); +} + |