]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blame - io/open.c
Merge over several portability changes from xfstest update.
[thirdparty/xfsprogs-dev.git] / io / open.c
CommitLineData
e246ba5f 1/*
f72d20ad 2 * Copyright (c) 2003-2004 Silicon Graphics, Inc. All Rights Reserved.
dfc130f3 3 *
e246ba5f
NS
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of version 2 of the GNU General Public License as
6 * published by the Free Software Foundation.
dfc130f3 7 *
e246ba5f
NS
8 * This program is distributed in the hope that it would be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
dfc130f3 11 *
e246ba5f
NS
12 * Further, this software is distributed without any warranty that it is
13 * free of the rightful claim of any third person regarding infringement
14 * or the like. Any license provided herein, whether implied or
15 * otherwise, applies only to this software file. Patent licenses, if
16 * any, provided herein do not apply to combinations of this program with
17 * other software, or any other product whatsoever.
dfc130f3 18 *
e246ba5f
NS
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write the Free Software Foundation, Inc., 59
21 * Temple Place - Suite 330, Boston MA 02111-1307, USA.
dfc130f3 22 *
e246ba5f
NS
23 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
24 * Mountain View, CA 94043, or:
dfc130f3
RC
25 *
26 * http://www.sgi.com
27 *
28 * For further information regarding this notice, see:
29 *
e246ba5f
NS
30 * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
31 */
dfc130f3 32
1d7e80ee 33#include <xfs/libxfs.h>
e246ba5f 34#include "command.h"
638473d8 35#include "input.h"
e246ba5f 36#include "init.h"
48c46ee3 37#include "io.h"
e246ba5f
NS
38
39static cmdinfo_t open_cmd;
40static cmdinfo_t stat_cmd;
48c46ee3 41static cmdinfo_t close_cmd;
9b5ee343 42static cmdinfo_t setfl_cmd;
e246ba5f 43static cmdinfo_t statfs_cmd;
2c794e6e
NS
44static cmdinfo_t chattr_cmd;
45static cmdinfo_t lsattr_cmd;
9b5ee343 46static cmdinfo_t extsize_cmd;
48c46ee3
NS
47
48off64_t
49filesize(void)
50{
51 struct stat64 st;
52
53 if (fstat64(file->fd, &st) < 0) {
54 perror("fstat64");
55 return -1;
56 }
57 return st.st_size;
58}
59
60static char *
61filetype(mode_t mode)
62{
63 switch (mode & S_IFMT) {
64 case S_IFSOCK:
65 return _("socket");
66 case S_IFDIR:
67 return _("directory");
68 case S_IFCHR:
69 return _("char device");
70 case S_IFBLK:
71 return _("block device");
72 case S_IFREG:
73 return _("regular file");
74 case S_IFLNK:
75 return _("symbolic link");
76 case S_IFIFO:
77 return _("fifo");
78 }
79 return NULL;
80}
81
82static void
83printxattr(int flags, int verbose, int dofname, int dobraces, int doeol)
84{
85 static struct {
86 int flag;
87 char *shortname;
88 char *longname;
89 } *p, xflags[] = {
90 { XFS_XFLAG_REALTIME, "r", "realtime" },
91 { XFS_XFLAG_PREALLOC, "p", "prealloc" },
92 { XFS_XFLAG_IMMUTABLE, "i", "immutable" },
93 { XFS_XFLAG_APPEND, "a", "append-only" },
94 { XFS_XFLAG_SYNC, "s", "sync" },
95 { XFS_XFLAG_NOATIME, "A", "no-atime" },
96 { XFS_XFLAG_NODUMP, "d", "no-dump" },
97 { 0, NULL, NULL }
98 };
99 int first = 1;
100
101 if (dobraces)
102 fputs("[", stdout);
103 for (p = xflags; p->flag; p++) {
104 if (flags & p->flag) {
105 if (verbose) {
106 if (first)
107 first = 0;
108 else
109 fputs(", ", stdout);
110 fputs(p->longname, stdout);
111 } else {
112 fputs(p->shortname, stdout);
113 }
114 } else if (!verbose) {
115 fputs("-", stdout);
116 }
117 }
118 if (dobraces)
119 fputs("]", stdout);
120 if (dofname)
121 printf(" %s ", file->name);
122 if (doeol)
123 fputs("\n", stdout);
124}
125
126static int
127stat_f(
128 int argc,
129 char **argv)
130{
131 struct fsxattr fsx;
132 struct stat64 st;
133 int verbose = (argc == 2 && !strcmp(argv[1], "-v"));
134
135 printf(_("fd.path = \"%s\"\n"), file->name);
136 printf(_("fd.flags = %s,%s,%s%s%s\n"),
137 file->flags & IO_OSYNC ? _("sync") : _("non-sync"),
138 file->flags & IO_DIRECT ? _("direct") : _("non-direct"),
139 file->flags & IO_READONLY ? _("read-only") : _("read-write"),
140 file->flags & IO_REALTIME ? _(",real-time") : "",
141 file->flags & IO_APPEND ? _(",append-only") : "");
142 if (fstat64(file->fd, &st) < 0) {
143 perror("fstat64");
144 } else {
145 printf(_("stat.ino = %lld\n"), (long long)st.st_ino);
146 printf(_("stat.type = %s\n"), filetype(st.st_mode));
147 printf(_("stat.size = %lld\n"), (long long)st.st_size);
148 printf(_("stat.blocks = %lld\n"), (long long)st.st_blocks);
149 if (verbose) {
150 printf(_("stat.atime = %s"), ctime(&st.st_atime));
151 printf(_("stat.mtime = %s"), ctime(&st.st_mtime));
152 printf(_("stat.ctime = %s"), ctime(&st.st_ctime));
153 }
154 }
155 if (file->flags & IO_FOREIGN)
156 return 0;
157 if ((xfsctl(file->name, file->fd, XFS_IOC_FSGETXATTR, &fsx)) < 0) {
158 perror("XFS_IOC_FSGETXATTR");
159 } else {
160 printf(_("xattr.xflags = 0x%x "), fsx.fsx_xflags);
161 printxattr(fsx.fsx_xflags, verbose, 0, 1, 1);
162 printf(_("xattr.extsize = %u\n"), fsx.fsx_extsize);
163 printf(_("xattr.nextents = %u\n"), fsx.fsx_nextents);
164 }
165 return 0;
166}
e246ba5f
NS
167
168int
169openfile(
93d9f139 170 char *path,
638473d8 171 xfs_fsop_geom_t *geom,
48c46ee3
NS
172 int flags,
173 mode_t mode)
e246ba5f
NS
174{
175 int fd;
176 int oflags;
e246ba5f 177
48c46ee3
NS
178 oflags = flags & IO_READONLY ? O_RDONLY : O_RDWR;
179 if (flags & IO_APPEND)
e246ba5f 180 oflags |= O_APPEND;
48c46ee3 181 if (flags & IO_CREAT)
e246ba5f 182 oflags |= O_CREAT;
48c46ee3 183 if (flags & IO_DIRECT)
e246ba5f 184 oflags |= O_DIRECT;
48c46ee3 185 if (flags & IO_OSYNC)
e246ba5f 186 oflags |= O_SYNC;
48c46ee3 187 if (flags & IO_TRUNC)
e246ba5f
NS
188 oflags |= O_TRUNC;
189
48c46ee3 190 fd = open(path, oflags, mode);
e246ba5f 191 if (fd < 0) {
93d9f139 192 perror(path);
e246ba5f
NS
193 return -1;
194 }
48c46ee3 195
db0bb90c
NS
196 if (!geom)
197 return fd;
198
93d9f139 199 if (!platform_test_xfs_fd(fd)) {
e246ba5f
NS
200 fprintf(stderr, _("%s: specified file "
201 "[\"%s\"] is not on an XFS filesystem\n"),
48c46ee3 202 progname, file->name);
e246ba5f
NS
203 close(fd);
204 return -1;
205 }
206
638473d8
NS
207 if (xfsctl(path, fd, XFS_IOC_FSGEOMETRY, geom) < 0) {
208 perror("XFS_IOC_FSGEOMETRY");
209 close(fd);
210 return -1;
211 }
212
48c46ee3 213 if (!(flags & IO_READONLY) && (flags & IO_REALTIME)) {
e246ba5f
NS
214 struct fsxattr attr;
215
93d9f139 216 if (xfsctl(path, fd, XFS_IOC_FSGETXATTR, &attr) < 0) {
e246ba5f
NS
217 perror("XFS_IOC_FSGETXATTR");
218 close(fd);
219 return -1;
220 }
221 if (!(attr.fsx_xflags & XFS_XFLAG_REALTIME)) {
222 attr.fsx_xflags |= XFS_XFLAG_REALTIME;
93d9f139 223 if (xfsctl(path, fd, XFS_IOC_FSSETXATTR, &attr) < 0) {
e246ba5f
NS
224 perror("XFS_IOC_FSSETXATTR");
225 close(fd);
226 return -1;
227 }
228 }
229 }
230 return fd;
231}
232
48c46ee3
NS
233int
234addfile(
235 char *name,
236 int fd,
237 xfs_fsop_geom_t *geometry,
238 int flags)
e246ba5f 239{
48c46ee3
NS
240 char *filename;
241
242 filename = strdup(name);
243 if (!filename) {
244 perror("strdup");
245 close(fd);
246 return -1;
247 }
248
249 /* Extend the table of currently open files */
250 filetable = (fileio_t *)realloc(filetable, /* growing */
251 ++filecount * sizeof(fileio_t));
252 if (!filetable) {
253 perror("realloc");
254 filecount = 0;
255 free(filename);
256 close(fd);
257 return -1;
258 }
259
260 /* Finally, make this the new active open file */
261 file = &filetable[filecount - 1];
262 file->fd = fd;
263 file->flags = flags;
264 file->name = filename;
265 file->geom = *geometry;
e246ba5f
NS
266 return 0;
267}
268
269static void
270open_help(void)
271{
272 printf(_(
273"\n"
48c46ee3 274" opens a new file in the requested mode\n"
e246ba5f
NS
275"\n"
276" Example:\n"
48c46ee3 277" 'open -cd /tmp/data' - creates/opens data file read-write for direct IO\n"
e246ba5f
NS
278"\n"
279" Opens a file for subsequent use by all of the other xfs_io commands.\n"
280" With no arguments, open uses the stat command to show the current file.\n"
f72d20ad 281" -F -- foreign filesystem file, disallow XFS-specific commands\n"
e246ba5f 282" -a -- open with the O_APPEND flag (append-only mode)\n"
e246ba5f 283" -d -- open with O_DIRECT (non-buffered IO, note alignment constraints)\n"
48c46ee3
NS
284" -f -- open with O_CREAT (create the file if it doesn't exist)\n"
285" -m -- permissions to use in case a new file is created (default 0600)\n"
e246ba5f
NS
286" -r -- open with O_RDONLY, the default is O_RDWR\n"
287" -s -- open with O_SYNC\n"
288" -t -- open with O_TRUNC (truncate the file to zero length if it exists)\n"
289" -x -- mark the file as a realtime XFS file immediately after opening it\n"
48c46ee3
NS
290" Note1: usually read/write direct IO requests must be blocksize aligned;\n"
291" some kernels, however, allow sectorsize alignment for direct IO.\n"
292" Note2: the bmap for non-regular files can be obtained provided the file\n"
2c794e6e 293" was opened correctly (in particular, must be opened read-only).\n"
e246ba5f
NS
294"\n"));
295}
296
297static int
298open_f(
299 int argc,
300 char **argv)
301{
48c46ee3
NS
302 int c, fd, flags = 0;
303 char *sp;
304 mode_t mode = 0600;
f72d20ad 305 xfs_fsop_geom_t geometry = { 0 };
e246ba5f 306
48c46ee3
NS
307 if (argc == 1) {
308 if (file)
309 return stat_f(argc, argv);
310 fprintf(stderr, _("no files are open, try 'help open'\n"));
311 return 0;
312 }
e246ba5f 313
48c46ee3 314 while ((c = getopt(argc, argv, "Facdfm:rstx")) != EOF) {
e246ba5f 315 switch (c) {
f72d20ad 316 case 'F':
48c46ee3 317 flags |= IO_FOREIGN;
f72d20ad 318 break;
e246ba5f 319 case 'a':
48c46ee3 320 flags |= IO_APPEND;
e246ba5f
NS
321 break;
322 case 'c':
48c46ee3
NS
323 case 'f':
324 flags |= IO_CREAT;
e246ba5f
NS
325 break;
326 case 'd':
48c46ee3
NS
327 flags |= IO_DIRECT;
328 break;
329 case 'm':
330 mode = strtoul(optarg, &sp, 0);
331 if (!sp || sp == optarg) {
332 printf(_("non-numeric mode -- %s\n"), optarg);
333 return 0;
334 }
e246ba5f
NS
335 break;
336 case 'r':
48c46ee3 337 flags |= IO_READONLY;
e246ba5f
NS
338 break;
339 case 's':
48c46ee3 340 flags |= IO_OSYNC;
e246ba5f
NS
341 break;
342 case 't':
48c46ee3 343 flags |= IO_TRUNC;
e246ba5f
NS
344 break;
345 case 'x':
48c46ee3 346 flags |= IO_REALTIME;
e246ba5f
NS
347 break;
348 default:
48c46ee3 349 return command_usage(&open_cmd);
e246ba5f
NS
350 }
351 }
352
353 if (optind != argc - 1)
48c46ee3 354 return command_usage(&open_cmd);
e246ba5f 355
48c46ee3
NS
356 fd = openfile(argv[optind], flags & IO_FOREIGN ?
357 NULL : &geometry, flags, mode);
e246ba5f
NS
358 if (fd < 0)
359 return 0;
360
48c46ee3 361 addfile(argv[optind], fd, &geometry, flags);
e246ba5f
NS
362 return 0;
363}
364
48c46ee3
NS
365static int
366close_f(
367 int argc,
368 char **argv)
e246ba5f 369{
48c46ee3
NS
370 size_t length;
371 unsigned int offset;
e246ba5f 372
48c46ee3
NS
373 if (close(file->fd) < 0) {
374 perror("close");
375 return 0;
e246ba5f 376 }
48c46ee3
NS
377 free(file->name);
378
379 /* Shuffle the file table entries down over the removed entry */
380 offset = file - &filetable[0];
381 length = filecount * sizeof(fileio_t);
382 length -= (offset + 1) * sizeof(fileio_t);
383 if (length)
384 memmove(file, file + 1, length);
385
386 /* Resize the memory allocated for the table, possibly freeing */
387 if (--filecount) {
388 filetable = (fileio_t *)realloc(filetable, /* shrinking */
389 filecount * sizeof(fileio_t));
390 if (offset == filecount)
391 offset--;
392 file = filetable + offset;
393 } else {
394 free(filetable);
395 file = filetable = NULL;
2c794e6e 396 }
48c46ee3
NS
397 filelist_f();
398 return 0;
2c794e6e
NS
399}
400
401static int
402lsattr_f(
403 int argc,
404 char **argv)
405{
406 struct fsxattr fsx;
407 int c, aflag = 0, vflag = 0;
408
409 while ((c = getopt(argc, argv, "av")) != EOF) {
410 switch (c) {
411 case 'a':
412 aflag = 1;
413 vflag = 0;
414 break;
415 case 'v':
416 aflag = 0;
417 vflag = 1;
418 break;
419 default:
420 printf(_("invalid lsattr argument -- '%c'\n"), c);
421 return 0;
422 }
423 }
424
48c46ee3
NS
425 if ((xfsctl(file->name, file->fd, XFS_IOC_FSGETXATTR, &fsx)) < 0) {
426 perror("XFS_IOC_FSGETXATTR");
2c794e6e
NS
427 } else {
428 printxattr(fsx.fsx_xflags, vflag, !aflag, vflag, !aflag);
429 if (aflag) {
430 fputs("/", stdout);
431 printxattr(-1, 0, 1, 0, 1);
432 }
433 }
434 return 0;
435}
436
437static void
438lsattr_help(void)
439{
440 printf(_(
441"\n"
442" displays the set of extended inode flags associated with the current file\n"
443"\n"
444" Each individual flag is displayed as a single character, in this order:\n"
445" r -- file data is stored in the realtime section\n"
446" p -- file has preallocated extents (cannot be changed using chattr)\n"
447" i -- immutable, file cannot be modified\n"
448" a -- append-only, file can only be appended to\n"
449" s -- all updates are synchronous\n"
450" A -- the access time is not updated for this inode\n"
451" d -- do not include this file in a dump of the filesystem\n"
452"\n"
453" Options:\n"
454" -a -- show all flags which can be set alongside those which are set\n"
455" -v -- verbose mode; show long names of flags, not single characters\n"
456"\n"));
457}
458
459static int
460chattr_f(
461 int argc,
462 char **argv)
463{
464 static struct {
465 int flag;
466 char optc;
467 } *p, xflags[] = {
468 { XFS_XFLAG_REALTIME, 'r' },
469 { XFS_XFLAG_IMMUTABLE, 'i' },
470 { XFS_XFLAG_APPEND, 'a' },
471 { XFS_XFLAG_SYNC, 's' },
472 { XFS_XFLAG_NOATIME, 'A' },
473 { XFS_XFLAG_NODUMP, 'd' },
474 { 0, '\0' }
475 };
476 struct fsxattr attr;
477 unsigned int i = 0;
478 char *c;
479
48c46ee3 480 if (xfsctl(file->name, file->fd, XFS_IOC_FSGETXATTR, &attr) < 0) {
2c794e6e
NS
481 perror("XFS_IOC_FSGETXATTR");
482 return 0;
483 }
484 while (++i < argc) {
485 if (argv[i][0] == '+') {
486 for (c = &argv[i][1]; *c; c++) {
487 for (p = xflags; p->flag; p++) {
488 if (p->optc == *c) {
489 attr.fsx_xflags |= p->flag;
490 break;
491 }
492 }
493 if (!p->flag) {
494 fprintf(stderr, _("%s: unknown flag\n"),
495 progname);
496 return 0;
497 }
498 }
499 } else if (argv[i][0] == '-') {
500 for (c = &argv[i][1]; *c; c++) {
501 for (p = xflags; p->flag; p++) {
502 if (p->optc == *c) {
503 attr.fsx_xflags &= ~p->flag;
504 break;
505 }
506 }
507 if (!p->flag) {
508 fprintf(stderr, _("%s: unknown flag\n"),
509 progname);
510 return 0;
511 }
512 }
513 } else {
514 fprintf(stderr, _("%s: bad chattr command, not +/-X\n"),
515 progname);
516 return 0;
517 }
518 }
48c46ee3 519 if (xfsctl(file->name, file->fd, XFS_IOC_FSSETXATTR, &attr) < 0)
2c794e6e
NS
520 perror("XFS_IOC_FSSETXATTR");
521 return 0;
522}
523
524static void
525chattr_help(void)
526{
527 printf(_(
528"\n"
529" modifies the set of extended inode flags associated with the current file\n"
530"\n"
531" Examples:\n"
532" 'chattr +a' - sets the append-only flag\n"
533" 'chattr -a' - clears the append-only flag\n"
534"\n"
535" +/-r -- set/clear the realtime flag\n"
536" +/-i -- set/clear the immutable flag\n"
537" +/-a -- set/clear the append-only flag\n"
538" +/-s -- set/clear the sync flag\n"
539" +/-A -- set/clear the no-atime flag\n"
540" +/-d -- set/clear the no-dump flag\n"
541" Note1: user must have certain capabilities to modify immutable/append-only.\n"
542" Note2: immutable/append-only files cannot be deleted; removing these files\n"
543" requires the immutable/append-only flag to be cleared first.\n"
544" Note3: the realtime flag can only be set if the filesystem has a realtime\n"
545" section, and the (regular) file must be empty when the flag is set.\n"
546"\n"));
547}
548
9b5ee343
NS
549static int
550setfl_f(
551 int argc,
552 char **argv)
553{
554 int c, flags;
555
48c46ee3 556 flags = fcntl(file->fd, F_GETFL, 0);
9b5ee343
NS
557 if (flags < 0) {
558 perror("fcntl(F_GETFL)");
559 return 0;
560 }
561
562 while ((c = getopt(argc, argv, "ad")) != EOF) {
563 switch (c) {
564 case 'a':
565 if (flags & O_APPEND)
566 flags |= O_APPEND;
567 else
568 flags &= ~O_APPEND;
569 break;
570 case 'd':
571 if (flags & O_DIRECT)
572 flags |= O_DIRECT;
573 else
574 flags &= ~O_DIRECT;
575 break;
576 default:
577 printf(_("invalid setfl argument -- '%c'\n"), c);
578 return 0;
579 }
580 }
581
48c46ee3 582 if (fcntl(file->fd, F_SETFL, flags) < 0)
9b5ee343
NS
583 perror("fcntl(F_SETFL)");
584
585 return 0;
586}
587
588static int
589extsize_f(
590 int argc,
591 char **argv)
592{
593 struct fsxattr fsx;
638473d8 594 long extsize;
48c46ee3 595 int blocksize, sectsize;
9b5ee343 596
48c46ee3
NS
597 init_cvtnum(&blocksize, &sectsize);
598 extsize = (long)cvtnum(blocksize, sectsize, argv[1]);
638473d8 599 if (extsize < 0) {
9b5ee343
NS
600 printf(_("non-numeric extsize argument -- %s\n"), argv[1]);
601 return 0;
602 }
48c46ee3
NS
603 if ((xfsctl(file->name, file->fd, XFS_IOC_FSGETXATTR, &fsx)) < 0) {
604 perror("XFS_IOC_FSGETXATTR");
9b5ee343
NS
605 return 0;
606 }
607 fsx.fsx_extsize = extsize;
48c46ee3
NS
608 if ((xfsctl(file->name, file->fd, XFS_IOC_FSSETXATTR, &fsx)) < 0) {
609 perror("XFS_IOC_FSSETXATTR");
9b5ee343
NS
610 return 0;
611 }
612
613 return 0;
614}
615
e246ba5f
NS
616static int
617statfs_f(
618 int argc,
619 char **argv)
620{
c0211f67 621 struct xfs_fsop_geom fsgeo;
e246ba5f 622 struct statfs st;
e246ba5f 623
48c46ee3
NS
624 printf(_("fd.path = \"%s\"\n"), file->name);
625 if (platform_fstatfs(file->fd, &st) < 0) {
e246ba5f
NS
626 perror("fstatfs");
627 } else {
628 printf(_("statfs.f_bsize = %lld\n"), (long long) st.f_bsize);
629 printf(_("statfs.f_blocks = %lld\n"), (long long) st.f_blocks);
2c794e6e
NS
630#if defined(__sgi__)
631 printf(_("statfs.f_frsize = %lld\n"), (long long) st.f_frsize);
c0211f67 632#else
e246ba5f 633 printf(_("statfs.f_bavail = %lld\n"), (long long) st.f_bavail);
93d9f139 634#endif
2c794e6e
NS
635 printf(_("statfs.f_files = %lld\n"), (long long) st.f_files);
636 printf(_("statfs.f_ffree = %lld\n"), (long long) st.f_ffree);
e246ba5f 637 }
48c46ee3 638 if (file->flags & IO_FOREIGN)
f72d20ad 639 return 0;
48c46ee3
NS
640 if ((xfsctl(file->name, file->fd, XFS_IOC_FSGEOMETRY_V1, &fsgeo)) < 0) {
641 perror("XFS_IOC_FSGEOMETRY_V1");
e246ba5f
NS
642 } else {
643 printf(_("geom.bsize = %u\n"), fsgeo.blocksize);
644 printf(_("geom.agcount = %u\n"), fsgeo.agcount);
645 printf(_("geom.agblocks = %u\n"), fsgeo.agblocks);
646 printf(_("geom.datablocks = %llu\n"),
647 (unsigned long long) fsgeo.datablocks);
648 printf(_("geom.rtblocks = %llu\n"),
649 (unsigned long long) fsgeo.rtblocks);
650 printf(_("geom.rtextents = %llu\n"),
651 (unsigned long long) fsgeo.rtextents);
652 printf(_("geom.rtextsize = %u\n"), fsgeo.rtextsize);
653 printf(_("geom.sunit = %u\n"), fsgeo.sunit);
654 printf(_("geom.swidth = %u\n"), fsgeo.swidth);
655 }
656 return 0;
657}
658
659void
660open_init(void)
661{
662 open_cmd.name = _("open");
663 open_cmd.altname = _("o");
664 open_cmd.cfunc = open_f;
665 open_cmd.argmin = 0;
666 open_cmd.argmax = -1;
48c46ee3 667 open_cmd.flags = CMD_NOMAP_OK | CMD_NOFILE_OK | CMD_FOREIGN_OK;
e246ba5f 668 open_cmd.args = _("[-acdrstx] [path]");
48c46ee3 669 open_cmd.oneline = _("open the file specified by path");
e246ba5f
NS
670 open_cmd.help = open_help;
671
672 stat_cmd.name = _("stat");
673 stat_cmd.cfunc = stat_f;
674 stat_cmd.argmin = 0;
675 stat_cmd.argmax = 1;
48c46ee3 676 stat_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK;
e246ba5f 677 stat_cmd.args = _("[-v]");
48c46ee3
NS
678 stat_cmd.oneline = _("statistics on the currently open file");
679
680 close_cmd.name = _("close");
681 close_cmd.altname = _("c");
682 close_cmd.cfunc = close_f;
683 close_cmd.argmin = 0;
684 close_cmd.argmax = 0;
685 close_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK;
686 close_cmd.oneline = _("close the current open file");
e246ba5f 687
9b5ee343
NS
688 setfl_cmd.name = _("setfl");
689 setfl_cmd.cfunc = setfl_f;
690 setfl_cmd.args = _("[-adx]");
48c46ee3 691 setfl_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK;
9b5ee343
NS
692 setfl_cmd.oneline =
693 _("set/clear append/direct flags on the open file");
694
e246ba5f
NS
695 statfs_cmd.name = _("statfs");
696 statfs_cmd.cfunc = statfs_f;
48c46ee3 697 statfs_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK;
e246ba5f
NS
698 statfs_cmd.oneline =
699 _("statistics on the filesystem of the currently open file");
700
2c794e6e
NS
701 chattr_cmd.name = _("chattr");
702 chattr_cmd.cfunc = chattr_f;
703 chattr_cmd.args = _("[+/-riasAd]");
704 chattr_cmd.argmin = 1;
705 chattr_cmd.argmax = 1;
48c46ee3 706 chattr_cmd.flags = CMD_NOMAP_OK;
2c794e6e
NS
707 chattr_cmd.oneline =
708 _("change extended inode flags on the currently open file");
709 chattr_cmd.help = chattr_help;
710
711 lsattr_cmd.name = _("lsattr");
712 lsattr_cmd.cfunc = lsattr_f;
713 lsattr_cmd.args = _("[-a | -v]");
714 lsattr_cmd.argmin = 0;
715 lsattr_cmd.argmax = 2;
48c46ee3 716 lsattr_cmd.flags = CMD_NOMAP_OK;
2c794e6e
NS
717 lsattr_cmd.oneline =
718 _("list extended inode flags set on the currently open file");
719 lsattr_cmd.help = lsattr_help;
720
9b5ee343
NS
721 extsize_cmd.name = _("extsize");
722 extsize_cmd.cfunc = extsize_f;
723 extsize_cmd.argmin = 1;
724 extsize_cmd.argmax = 1;
48c46ee3 725 extsize_cmd.flags = CMD_NOMAP_OK;
9b5ee343
NS
726 extsize_cmd.oneline =
727 _("set prefered extent size (in bytes) for the open file");
728
e246ba5f
NS
729 add_command(&open_cmd);
730 add_command(&stat_cmd);
48c46ee3 731 add_command(&close_cmd);
9b5ee343 732 add_command(&setfl_cmd);
e246ba5f 733 add_command(&statfs_cmd);
2c794e6e
NS
734 add_command(&chattr_cmd);
735 add_command(&lsattr_cmd);
48c46ee3
NS
736
737 if (expert)
738 add_command(&extsize_cmd);
e246ba5f 739}