Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:19

0001 /**
0002  *  df Shell Command Implmentation
0003  *
0004  * @ingroup libfs_msdos MSDOS FileSystem
0005  *
0006  * @brief Obtain MS-DOS filesystem information
0007  */
0008 
0009 /*
0010  *  Copyright (c) 2013 Andrey Mozzhuhin
0011  *
0012  *  The license and distribution terms for this file may be
0013  *  found in the file LICENSE in this distribution or at
0014  *  http://www.rtems.org/license/LICENSE.
0015  */
0016 
0017 #ifdef HAVE_CONFIG_H
0018 #include "config.h"
0019 #endif
0020 
0021 #include <rtems/shell.h>
0022 
0023 #define __need_getopt_newlib
0024 #include <getopt.h>
0025 #include <string.h>
0026 #include <inttypes.h>
0027 
0028 static const char suffixes[] =
0029 { 'B', 'K', 'M', 'G', 'T' };
0030 
0031 struct df_context
0032 {
0033   unsigned block_size;
0034 };
0035 
0036 static unsigned rtems_shell_df_parse_size(const char *str)
0037 {
0038   unsigned result;
0039   char suffix;
0040   int i;
0041 
0042   if (sscanf(str, "%d%c", &result, &suffix) == 2)
0043   {
0044     for (i = 0; i < sizeof(suffixes) / sizeof(suffixes[0]); i++)
0045     {
0046       if (suffix == suffixes[i])
0047         break;
0048       result *= 1024;
0049     }
0050   }
0051   else if (sscanf(str, "%d", &result) != 1)
0052   {
0053     result = 0;
0054   }
0055 
0056   return result;
0057 }
0058 
0059 static char *rtems_shell_df_humanize_size(uint64_t block_size, char *buf,
0060     size_t size)
0061 {
0062   int i = 0;
0063 
0064   while (block_size >= 1024 && i < sizeof(suffixes) / sizeof(suffixes[0]) - 1)
0065   {
0066     block_size /= 1024;
0067     i++;
0068   }
0069 
0070   snprintf(buf, size, "%"PRIu64"%c", block_size, suffixes[i]);
0071   return buf;
0072 }
0073 
0074 static bool rtems_shell_df_print_entry(
0075     const rtems_filesystem_mount_table_entry_t *mt_entry, void *arg)
0076 {
0077   struct df_context *context = arg;
0078 
0079   struct statvfs svfs;
0080   int code;
0081   char f_buf[20], u_buf[20], a_buf[20];
0082 
0083   if ((code = statvfs(mt_entry->target, &svfs)))
0084     return false;
0085 
0086   if (context->block_size > 0)
0087   {
0088     printf(
0089         "%-15s %10" PRIu64 " %9" PRIu64 " %11" PRIu64 " %9" PRIu64 "%% %14s\n",
0090         mt_entry->dev == NULL ? "none" : mt_entry->dev,
0091         (svfs.f_blocks * svfs.f_frsize + (context->block_size - 1)) / context->block_size,
0092         ((svfs.f_blocks - svfs.f_bfree) * svfs.f_frsize + (context->block_size - 1)) / context->block_size,
0093         (svfs.f_bfree * svfs.f_frsize + (context->block_size - 1)) / context->block_size,
0094         ((svfs.f_blocks - svfs.f_bfree) * 100 / svfs.f_blocks),
0095         mt_entry->target == NULL ? "none" : mt_entry->target);
0096   }
0097   else
0098   {
0099     rtems_shell_df_humanize_size(svfs.f_blocks * svfs.f_frsize, f_buf,
0100         sizeof(f_buf));
0101     rtems_shell_df_humanize_size((svfs.f_blocks - svfs.f_bfree) * svfs.f_frsize,
0102         u_buf, sizeof(u_buf));
0103     rtems_shell_df_humanize_size(svfs.f_bfree * svfs.f_frsize, a_buf,
0104         sizeof(a_buf));
0105     printf("%-15s %10s %9s %11s %9" PRIu64 "%% %14s\n",
0106         mt_entry->dev == NULL ? "none" : mt_entry->dev, f_buf, u_buf, a_buf,
0107         (uint64_t)(svfs.f_blocks - svfs.f_bfree) * 100 / svfs.f_blocks,
0108         mt_entry->target == NULL ? "none" : mt_entry->target);
0109   }
0110 
0111   return false;
0112 }
0113 
0114 static int rtems_shell_main_df(int argc, char **argv)
0115 {
0116   int c;
0117   struct getopt_data optdata;
0118   struct df_context context;
0119   char buf[32];
0120 
0121   memset(&optdata, 0, sizeof(optdata));
0122   context.block_size = 1024;
0123 
0124   while ((c = getopt_r(argc, (char**) argv, ":hB:", &optdata)) != -1)
0125   {
0126     switch (c)
0127     {
0128     case 'h':
0129       context.block_size = 0;
0130       break;
0131     case 'B':
0132       context.block_size = rtems_shell_df_parse_size(optdata.optarg);
0133       break;
0134     default:
0135       return -1;
0136     }
0137   }
0138 
0139   if (context.block_size == 0)
0140     printf(
0141         "Filesystem     Size             Used   Available       Use%%     Mounted on\n");
0142   else
0143     printf(
0144         "Filesystem     %s-blocks        Used   Available       Use%%     Mounted on\n",
0145         rtems_shell_df_humanize_size(context.block_size, buf, sizeof(buf)));
0146 
0147   rtems_filesystem_mount_iterate(rtems_shell_df_print_entry, &context);
0148 
0149   return 0;
0150 }
0151 
0152 rtems_shell_cmd_t rtems_shell_DF_Command =
0153 {
0154     "df", /* name */
0155     "[-hB]\n"
0156     " -h  human-readable output\n"
0157     " -B  scale sizes by SIZE before printing them\n", /* usage */
0158     "files", /* topic */
0159     rtems_shell_main_df, /* command */
0160     NULL, /* alias */
0161     NULL /* next */
0162 };