]> git.proxmox.com Git - grub2.git/blame - commands/ls.c
Update source to follow GCS more precisely.
[grub2.git] / commands / ls.c
CommitLineData
db1771cf 1/* ls.c - command to list files and devices */
2/*
4b13b216 3 * GRUB -- GRand Unified Bootloader
7224189a 4 * Copyright (C) 2003,2005 Free Software Foundation, Inc.
db1771cf 5 *
4b13b216 6 * GRUB is free software; you can redistribute it and/or modify
db1771cf 7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
4b13b216 17 * along with GRUB; if not, write to the Free Software
db1771cf 18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
4b13b216 21#include <grub/types.h>
22#include <grub/misc.h>
23#include <grub/mm.h>
24#include <grub/err.h>
25#include <grub/dl.h>
26#include <grub/normal.h>
27#include <grub/arg.h>
28#include <grub/disk.h>
29#include <grub/device.h>
30#include <grub/term.h>
3f1578fe 31#include <grub/partition.h>
4b13b216 32#include <grub/file.h>
db1771cf 33
4b13b216 34static const struct grub_arg_option options[] =
db1771cf 35 {
502c87e8 36 {"long", 'l', 0, "show a long list with more detailed information", 0, 0},
37 {"human-readable", 'h', 0, "print sizes in a human readable format", 0, 0},
38 {"all", 'a', 0, "list all files", 0, 0},
db1771cf 39 {0, 0, 0, 0, 0, 0}
40 };
41
4b13b216 42static const char grub_human_sizes[] = {' ', 'K', 'M', 'G', 'T'};
db1771cf 43
4b13b216 44static grub_err_t
45grub_ls_list_disks (int longlist)
db1771cf 46{
4b13b216 47 auto int grub_ls_print_disks (const char *name);
48 int grub_ls_print_disks (const char *name)
db1771cf 49 {
4b13b216 50 grub_device_t dev;
51 auto int print_partition (const grub_partition_t p);
db1771cf 52
4b13b216 53 int print_partition (const grub_partition_t p)
db1771cf 54 {
4b13b216 55 char *pname = grub_partition_get_name (p);
db1771cf 56
57 if (pname)
58 {
59 if (longlist)
4b13b216 60 grub_print_partinfo (dev, pname);
db1771cf 61 else
4b13b216 62 grub_printf ("(%s,%s) ", name, pname);
db1771cf 63 }
64
65 return 0;
66 }
67
4b13b216 68 dev = grub_device_open (name);
69 grub_errno = GRUB_ERR_NONE;
db1771cf 70
71 if (dev)
72 {
73 if (longlist)
5f3607e0 74 {
75 grub_printf ("Device: %s", name);
76
77 if (! dev->disk || ! dev->disk->has_partitions)
78 {
79 grub_fs_t fs;
80 char *label;
81
82 fs = grub_fs_probe (dev);
83 grub_errno = GRUB_ERR_NONE;
84
85 grub_printf (", Filesystem type %s",
ea409713 86 fs ? fs->name : "unknown");
87
88 if (fs && fs->label)
5f3607e0 89 {
ea409713 90 (fs->label) (dev, &label);
91 if (grub_errno == GRUB_ERR_NONE)
92 {
93 if (label && grub_strlen (label))
94 grub_printf (", Label: %s", label);
95 grub_free (label);
96 }
97 else
98 grub_errno = GRUB_ERR_NONE;
5f3607e0 99 }
5f3607e0 100 }
101
102 grub_putchar ('\n');
103 }
db1771cf 104 else
4b13b216 105 grub_printf ("(%s) ", name);
db1771cf 106
107 if (dev->disk && dev->disk->has_partitions)
108 {
4b13b216 109 grub_partition_iterate (dev->disk, print_partition);
110 grub_errno = GRUB_ERR_NONE;
db1771cf 111 }
112
4b13b216 113 grub_device_close (dev);
db1771cf 114 }
115
116 return 0;
117 }
118
4b13b216 119 grub_disk_dev_iterate (grub_ls_print_disks);
120 grub_putchar ('\n');
121 grub_refresh ();
db1771cf 122
db1771cf 123 return 0;
124}
125
4b13b216 126static grub_err_t
5f968e1e 127grub_ls_list_files (char *dirname, int longlist, int all, int human)
db1771cf 128{
129 char *device_name;
4b13b216 130 grub_fs_t fs;
8a572cd7 131 const char *path;
4b13b216 132 grub_device_t dev;
5f968e1e 133 auto int print_files (const char *filename, int dir);
134 auto int print_files_long (const char *filename, int dir);
135
136 int print_files (const char *filename, int dir)
db1771cf 137 {
138 if (all || filename[0] != '.')
4b13b216 139 grub_printf ("%s%s ", filename, dir ? "/" : "");
db1771cf 140
141 return 0;
142 }
143
5f968e1e 144 int print_files_long (const char *filename, int dir)
db1771cf 145 {
4b13b216 146 char pathname[grub_strlen (dirname) + grub_strlen (filename) + 1];
db1771cf 147
148 if ((! all) && (filename[0] == '.'))
149 return 0;
150
151 if (! dir)
152 {
4b13b216 153 grub_file_t file;
db1771cf 154
4b13b216 155 if (dirname[grub_strlen (dirname) - 1] == '/')
156 grub_sprintf (pathname, "%s%s", dirname, filename);
db1771cf 157 else
4b13b216 158 grub_sprintf (pathname, "%s/%s", dirname, filename);
db1771cf 159
160 /* XXX: For ext2fs symlinks are detected as files while they
161 should be reported as directories. */
4b13b216 162 file = grub_file_open (pathname);
db1771cf 163 if (! file)
164 {
4b13b216 165 grub_errno = 0;
db1771cf 166 return 0;
167 }
168
169 if (! human)
4b13b216 170 grub_printf ("%-12d", file->size);
db1771cf 171 else
172 {
173 float fsize = file->size;
174 int fsz = file->size;
175 int units = 0;
176 char buf[20];
177
178 while (fsz / 1024)
179 {
180 fsize /= 1024;
181 fsz /= 1024;
182 units++;
183 }
184
185 if (units)
186 {
4b13b216 187 grub_sprintf (buf, "%0.2f%c", fsize, grub_human_sizes[units]);
188 grub_printf ("%-12s", buf);
db1771cf 189 }
190 else
4b13b216 191 grub_printf ("%-12d", file->size);
db1771cf 192
193 }
194 (fs->close) (file);
195 }
196 else
4b13b216 197 grub_printf ("%-12s", "DIR");
db1771cf 198
4b13b216 199 grub_printf ("%s%s\n", filename, dir ? "/" : "");
db1771cf 200
201 return 0;
202 }
203
4b13b216 204 device_name = grub_file_get_device_name (dirname);
205 dev = grub_device_open (device_name);
db1771cf 206 if (! dev)
207 goto fail;
208
4b13b216 209 fs = grub_fs_probe (dev);
8a572cd7 210 path = grub_strchr (dirname, ')');
211 if (! path)
212 path = dirname;
213 else
214 path++;
215
db1771cf 216 if (! path && ! device_name)
217 {
4b13b216 218 grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid argument");
db1771cf 219 goto fail;
220 }
221
7224189a 222 if (! *path)
db1771cf 223 {
4b13b216 224 if (grub_errno == GRUB_ERR_UNKNOWN_FS)
225 grub_errno = GRUB_ERR_NONE;
db1771cf 226
ea409713 227 grub_printf ("(%s): Filesystem is %s",
db1771cf 228 device_name, fs ? fs->name : "unknown");
ea409713 229
230 if (fs && fs->label)
231 {
232 char *label;
233
234 (fs->label) (dev, &label);
235 if (grub_errno == GRUB_ERR_NONE)
236 {
237 if (label && grub_strlen (label))
238 grub_printf (", Label: %s", label);
239 grub_free (label);
240 }
241 else
242 grub_errno = GRUB_ERR_NONE;
243 }
244
245 grub_putchar ('\n');
db1771cf 246 }
247 else if (fs)
248 {
249 if (longlist)
250 (fs->dir) (dev, path, print_files_long);
251 else
252 (fs->dir) (dev, path, print_files);
5f968e1e 253
254 if (grub_errno == GRUB_ERR_BAD_FILE_TYPE
255 && path[grub_strlen (path) - 1] != '/')
256 {
257 /* PATH might be a regular file. */
258 char *p;
259 grub_file_t file;
260
261 grub_errno = 0;
262
263 file = grub_file_open (dirname);
264 if (! file)
265 goto fail;
266
267 grub_file_close (file);
268
269 p = grub_strrchr (dirname, '/') + 1;
270 dirname = grub_strndup (dirname, p - dirname);
271 if (! dirname)
272 goto fail;
273
274 all = 1;
275 if (longlist)
276 print_files_long (p, 0);
277 else
278 print_files (p, 0);
279
280 grub_free (dirname);
281 }
282
283 if (grub_errno == GRUB_ERR_NONE)
284 grub_putchar ('\n');
285
4b13b216 286 grub_refresh ();
db1771cf 287 }
288
289 fail:
290 if (dev)
4b13b216 291 grub_device_close (dev);
db1771cf 292
4b13b216 293 grub_free (device_name);
db1771cf 294
295 return 0;
296}
297
4b13b216 298static grub_err_t
299grub_cmd_ls (struct grub_arg_list *state, int argc, char **args)
db1771cf 300{
db1771cf 301 if (argc == 0)
7224189a 302 grub_ls_list_disks (state[0].set);
db1771cf 303 else
4b13b216 304 grub_ls_list_files (args[0], state[0].set, state[2].set,
db1771cf 305 state[1].set);
306
307 return 0;
308}
309
4b13b216 310#ifdef GRUB_UTIL
db1771cf 311void
4b13b216 312grub_ls_init (void)
db1771cf 313{
4b13b216 314 grub_register_command ("ls", grub_cmd_ls, GRUB_COMMAND_FLAG_BOTH,
502c87e8 315 "ls [-l|-h|-a] [FILE]",
316 "List devices and files.", options);
db1771cf 317}
318
319void
4b13b216 320grub_ls_fini (void)
db1771cf 321{
4b13b216 322 grub_unregister_command ("ls");
db1771cf 323}
4b13b216 324#else /* ! GRUB_UTIL */
325GRUB_MOD_INIT
db1771cf 326{
327 (void)mod; /* To stop warning. */
4b13b216 328 grub_register_command ("ls", grub_cmd_ls, GRUB_COMMAND_FLAG_BOTH,
502c87e8 329 "ls [-l|-h|-a] [FILE]",
330 "List devices and files.", options);
db1771cf 331}
332
4b13b216 333GRUB_MOD_FINI
db1771cf 334{
4b13b216 335 grub_unregister_command ("ls");
db1771cf 336}
4b13b216 337#endif /* ! GRUB_UTIL */