compositor: fix the over operator
[helenos.git] / uspace / app / df / df.c
blobbf0c918183a4ade39f4762e8f70d608ce739abf7
1 /*
2 * Copyright (c) 2013 Manuele Conti
3 * All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 /** @addtogroup df
30 * @brief Print amounts of free and used disk space.
31 * @{
33 /**
34 * @file
37 #include <cap.h>
38 #include <stdbool.h>
39 #include <stdio.h>
40 #include <stdlib.h>
41 #include <stdint.h>
42 #include <str_error.h>
43 #include <getopt.h>
44 #include <errno.h>
45 #include <adt/list.h>
46 #include <vfs/vfs.h>
47 #include <vfs/vfs_mtab.h>
49 #define NAME "df"
51 #define HEADER_TABLE "Filesystem Size Used Available Used%% Mounted on"
52 #define HEADER_TABLE_BLK "Filesystem Blk. Size Total Used Available Used%% Mounted on"
54 #define PERCENTAGE(x, tot) (tot ? (100ULL * (x) / (tot)) : 0)
56 static bool display_blocks;
58 static errno_t size_to_human_readable(uint64_t, size_t, char **);
59 static void print_header(void);
60 static errno_t print_statfs(vfs_statfs_t *, char *, char *);
61 static void print_usage(void);
63 int main(int argc, char *argv[])
65 int optres, errflg = 0;
66 vfs_statfs_t st;
67 errno_t rc;
69 display_blocks = false;
71 /* Parse command-line options */
72 while ((optres = getopt(argc, argv, ":ubh")) != -1) {
73 switch (optres) {
74 case 'h':
75 print_usage();
76 return 0;
78 case 'b':
79 display_blocks = true;
80 break;
82 case ':':
83 fprintf(stderr, "Option -%c requires an operand\n",
84 optopt);
85 errflg++;
86 break;
88 case '?':
89 fprintf(stderr, "Unrecognized option: -%c\n", optopt);
90 errflg++;
91 break;
93 default:
94 fprintf(stderr,
95 "Unknown error while parsing command line options");
96 errflg++;
97 break;
101 if (optind > argc) {
102 fprintf(stderr, "Too many input parameters\n");
103 errflg++;
106 if (errflg) {
107 print_usage();
108 return 1;
111 LIST_INITIALIZE(mtab_list);
112 vfs_get_mtab_list(&mtab_list);
114 print_header();
115 list_foreach(mtab_list, link, mtab_ent_t, mtab_ent) {
116 if (vfs_statfs_path(mtab_ent->mp, &st) == 0) {
117 rc = print_statfs(&st, mtab_ent->fs_name, mtab_ent->mp);
118 if (rc != EOK)
119 return 1;
120 } else {
121 fprintf(stderr, "Cannot get information for '%s' (%s).\n",
122 mtab_ent->mp, str_error(errno));
126 putchar('\n');
127 return 0;
130 static errno_t size_to_human_readable(uint64_t nblocks, size_t block_size, char **rptr)
132 cap_spec_t cap;
134 cap_from_blocks(nblocks, block_size, &cap);
135 cap_simplify(&cap);
136 return cap_format(&cap, rptr);
139 static void print_header(void)
141 if (!display_blocks)
142 printf(HEADER_TABLE);
143 else
144 printf(HEADER_TABLE_BLK);
146 putchar('\n');
149 static errno_t print_statfs(vfs_statfs_t *st, char *name, char *mountpoint)
151 uint64_t const used_blocks = st->f_blocks - st->f_bfree;
152 unsigned const perc_used = PERCENTAGE(used_blocks, st->f_blocks);
153 char *str;
154 errno_t rc;
156 printf("%10s", name);
158 if (!display_blocks) {
159 /* Print size */
160 rc = size_to_human_readable(st->f_blocks, st->f_bsize, &str);
161 if (rc != EOK)
162 goto error;
163 printf(" %14s", str);
164 free(str);
166 /* Number of used blocks */
167 rc = size_to_human_readable(used_blocks, st->f_bsize, &str);
168 if (rc != EOK)
169 goto error;
170 printf(" %14s", str);
171 free(str);
173 /* Number of available blocks */
174 rc = size_to_human_readable(st->f_bfree, st->f_bsize, &str);
175 if (rc != EOK)
176 goto error;
177 printf(" %14s", str);
178 free(str);
180 /* Percentage of used blocks */
181 printf(" %4u%%", perc_used);
183 /* Mount point */
184 printf(" %s\n", mountpoint);
185 } else {
186 /* Block size / Blocks / Used blocks / Available blocks / Used% / Mounted on */
187 printf(" %10" PRIu32 " %9" PRIu64 " %11" PRIu64 " %11" PRIu64 " %4u%% %s\n",
188 st->f_bsize, st->f_blocks, used_blocks, st->f_bfree,
189 perc_used, mountpoint);
192 return EOK;
193 error:
194 printf("\nError: Out of memory.\n");
195 return ENOMEM;
198 static void print_usage(void)
200 printf("Syntax: %s [<options>] \n", NAME);
201 printf("Options:\n");
202 printf(" -h Print help\n");
203 printf(" -b Print exact block sizes and numbers\n");
206 /** @}