]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - io/open.c
xfsprogs: don't install platform_defs.h
[thirdparty/xfsprogs-dev.git] / io / open.c
1 /*
2 * Copyright (c) 2003-2005 Silicon Graphics, Inc.
3 * All Rights Reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19 #include "command.h"
20 #include "input.h"
21 #include "init.h"
22 #include "io.h"
23
24 #ifndef __O_TMPFILE
25 #if defined __alpha__
26 #define __O_TMPFILE 0100000000
27 #elif defined(__hppa__)
28 #define __O_TMPFILE 040000000
29 #elif defined(__sparc__)
30 #define __O_TMPFILE 0x2000000
31 #else
32 #define __O_TMPFILE 020000000
33 #endif
34 #endif /* __O_TMPFILE */
35
36 #ifndef O_TMPFILE
37 #define O_TMPFILE (__O_TMPFILE | O_DIRECTORY)
38 #endif
39
40 static cmdinfo_t open_cmd;
41 static cmdinfo_t stat_cmd;
42 static cmdinfo_t close_cmd;
43 static cmdinfo_t statfs_cmd;
44 static cmdinfo_t chproj_cmd;
45 static cmdinfo_t lsproj_cmd;
46 static cmdinfo_t extsize_cmd;
47 static prid_t prid;
48 static long extsize;
49
50 off64_t
51 filesize(void)
52 {
53 struct stat64 st;
54
55 if (fstat64(file->fd, &st) < 0) {
56 perror("fstat64");
57 return -1;
58 }
59 return st.st_size;
60 }
61
62 static char *
63 filetype(mode_t mode)
64 {
65 switch (mode & S_IFMT) {
66 case S_IFSOCK:
67 return _("socket");
68 case S_IFDIR:
69 return _("directory");
70 case S_IFCHR:
71 return _("char device");
72 case S_IFBLK:
73 return _("block device");
74 case S_IFREG:
75 return _("regular file");
76 case S_IFLNK:
77 return _("symbolic link");
78 case S_IFIFO:
79 return _("fifo");
80 }
81 return NULL;
82 }
83
84 static int
85 stat_f(
86 int argc,
87 char **argv)
88 {
89 struct dioattr dio;
90 struct fsxattr fsx, fsxa;
91 struct stat64 st;
92 int verbose = (argc == 2 && !strcmp(argv[1], "-v"));
93
94 printf(_("fd.path = \"%s\"\n"), file->name);
95 printf(_("fd.flags = %s,%s,%s%s%s%s%s\n"),
96 file->flags & IO_OSYNC ? _("sync") : _("non-sync"),
97 file->flags & IO_DIRECT ? _("direct") : _("non-direct"),
98 file->flags & IO_READONLY ? _("read-only") : _("read-write"),
99 file->flags & IO_REALTIME ? _(",real-time") : "",
100 file->flags & IO_APPEND ? _(",append-only") : "",
101 file->flags & IO_NONBLOCK ? _(",non-block") : "",
102 file->flags & IO_TMPFILE ? _(",tmpfile") : "");
103 if (fstat64(file->fd, &st) < 0) {
104 perror("fstat64");
105 } else {
106 printf(_("stat.ino = %lld\n"), (long long)st.st_ino);
107 printf(_("stat.type = %s\n"), filetype(st.st_mode));
108 printf(_("stat.size = %lld\n"), (long long)st.st_size);
109 printf(_("stat.blocks = %lld\n"), (long long)st.st_blocks);
110 if (verbose) {
111 printf(_("stat.atime = %s"), ctime(&st.st_atime));
112 printf(_("stat.mtime = %s"), ctime(&st.st_mtime));
113 printf(_("stat.ctime = %s"), ctime(&st.st_ctime));
114 }
115 }
116 if (file->flags & IO_FOREIGN)
117 return 0;
118 if ((xfsctl(file->name, file->fd, XFS_IOC_FSGETXATTR, &fsx)) < 0 ||
119 (xfsctl(file->name, file->fd, XFS_IOC_FSGETXATTRA, &fsxa)) < 0) {
120 perror("XFS_IOC_FSGETXATTR");
121 } else {
122 printf(_("fsxattr.xflags = 0x%x "), fsx.fsx_xflags);
123 printxattr(fsx.fsx_xflags, verbose, 0, file->name, 1, 1);
124 printf(_("fsxattr.projid = %u\n"), fsx.fsx_projid);
125 printf(_("fsxattr.extsize = %u\n"), fsx.fsx_extsize);
126 printf(_("fsxattr.nextents = %u\n"), fsx.fsx_nextents);
127 printf(_("fsxattr.naextents = %u\n"), fsxa.fsx_nextents);
128 }
129 if ((xfsctl(file->name, file->fd, XFS_IOC_DIOINFO, &dio)) < 0) {
130 perror("XFS_IOC_DIOINFO");
131 } else {
132 printf(_("dioattr.mem = 0x%x\n"), dio.d_mem);
133 printf(_("dioattr.miniosz = %u\n"), dio.d_miniosz);
134 printf(_("dioattr.maxiosz = %u\n"), dio.d_maxiosz);
135 }
136 return 0;
137 }
138
139 int
140 openfile(
141 char *path,
142 xfs_fsop_geom_t *geom,
143 int flags,
144 mode_t mode)
145 {
146 int fd;
147 int oflags;
148
149 oflags = flags & IO_READONLY ? O_RDONLY : O_RDWR;
150 if (flags & IO_APPEND)
151 oflags |= O_APPEND;
152 if (flags & IO_CREAT)
153 oflags |= O_CREAT;
154 if (flags & IO_DIRECT)
155 oflags |= O_DIRECT;
156 if (flags & IO_OSYNC)
157 oflags |= O_SYNC;
158 if (flags & IO_TRUNC)
159 oflags |= O_TRUNC;
160 if (flags & IO_NONBLOCK)
161 oflags |= O_NONBLOCK;
162 if (flags & IO_TMPFILE)
163 oflags |= O_TMPFILE;
164
165 fd = open(path, oflags, mode);
166 if (fd < 0) {
167 if (errno == EISDIR &&
168 ((oflags & (O_RDWR|O_TMPFILE)) == O_RDWR)) {
169 /* make it as if we asked for O_RDONLY & try again */
170 oflags &= ~O_RDWR;
171 oflags |= O_RDONLY;
172 flags |= IO_READONLY;
173 fd = open(path, oflags, mode);
174 if (fd < 0) {
175 perror(path);
176 return -1;
177 }
178 } else {
179 perror(path);
180 return -1;
181 }
182 }
183
184 if (!geom || !platform_test_xfs_fd(fd))
185 return fd;
186
187 if (xfsctl(path, fd, XFS_IOC_FSGEOMETRY, geom) < 0) {
188 perror("XFS_IOC_FSGEOMETRY");
189 close(fd);
190 return -1;
191 }
192
193 if (!(flags & IO_READONLY) && (flags & IO_REALTIME)) {
194 struct fsxattr attr;
195
196 if (xfsctl(path, fd, XFS_IOC_FSGETXATTR, &attr) < 0) {
197 perror("XFS_IOC_FSGETXATTR");
198 close(fd);
199 return -1;
200 }
201 if (!(attr.fsx_xflags & XFS_XFLAG_REALTIME)) {
202 attr.fsx_xflags |= XFS_XFLAG_REALTIME;
203 if (xfsctl(path, fd, XFS_IOC_FSSETXATTR, &attr) < 0) {
204 perror("XFS_IOC_FSSETXATTR");
205 close(fd);
206 return -1;
207 }
208 }
209 }
210 return fd;
211 }
212
213 int
214 addfile(
215 char *name,
216 int fd,
217 xfs_fsop_geom_t *geometry,
218 int flags)
219 {
220 char *filename;
221
222 filename = strdup(name);
223 if (!filename) {
224 perror("strdup");
225 close(fd);
226 return -1;
227 }
228
229 /* Extend the table of currently open files */
230 filetable = (fileio_t *)realloc(filetable, /* growing */
231 ++filecount * sizeof(fileio_t));
232 if (!filetable) {
233 perror("realloc");
234 filecount = 0;
235 free(filename);
236 close(fd);
237 return -1;
238 }
239
240 /* Finally, make this the new active open file */
241 file = &filetable[filecount - 1];
242 file->fd = fd;
243 file->flags = flags;
244 file->name = filename;
245 file->geom = *geometry;
246 return 0;
247 }
248
249 static void
250 open_help(void)
251 {
252 printf(_(
253 "\n"
254 " opens a new file in the requested mode\n"
255 "\n"
256 " Example:\n"
257 " 'open -cd /tmp/data' - creates/opens data file read-write for direct IO\n"
258 "\n"
259 " Opens a file for subsequent use by all of the other xfs_io commands.\n"
260 " With no arguments, open uses the stat command to show the current file.\n"
261 " -a -- open with the O_APPEND flag (append-only mode)\n"
262 " -d -- open with O_DIRECT (non-buffered IO, note alignment constraints)\n"
263 " -f -- open with O_CREAT (create the file if it doesn't exist)\n"
264 " -m -- permissions to use in case a new file is created (default 0600)\n"
265 " -n -- open with O_NONBLOCK\n"
266 " -r -- open with O_RDONLY, the default is O_RDWR\n"
267 " -s -- open with O_SYNC\n"
268 " -t -- open with O_TRUNC (truncate the file to zero length if it exists)\n"
269 " -R -- mark the file as a realtime XFS file immediately after opening it\n"
270 " -T -- open with O_TMPFILE (create a file not visible in the namespace)\n"
271 " Note1: usually read/write direct IO requests must be blocksize aligned;\n"
272 " some kernels, however, allow sectorsize alignment for direct IO.\n"
273 " Note2: the bmap for non-regular files can be obtained provided the file\n"
274 " was opened correctly (in particular, must be opened read-only).\n"
275 "\n"));
276 }
277
278 static int
279 open_f(
280 int argc,
281 char **argv)
282 {
283 int c, fd, flags = 0;
284 char *sp;
285 mode_t mode = 0600;
286 xfs_fsop_geom_t geometry = { 0 };
287
288 if (argc == 1) {
289 if (file)
290 return stat_f(argc, argv);
291 fprintf(stderr, _("no files are open, try 'help open'\n"));
292 return 0;
293 }
294
295 while ((c = getopt(argc, argv, "FRTacdfm:nrstx")) != EOF) {
296 switch (c) {
297 case 'F':
298 /* Ignored / deprecated now, handled automatically */
299 break;
300 case 'a':
301 flags |= IO_APPEND;
302 break;
303 case 'c':
304 case 'f':
305 flags |= IO_CREAT;
306 break;
307 case 'd':
308 flags |= IO_DIRECT;
309 break;
310 case 'm':
311 mode = strtoul(optarg, &sp, 0);
312 if (!sp || sp == optarg) {
313 printf(_("non-numeric mode -- %s\n"), optarg);
314 return 0;
315 }
316 break;
317 case 'n':
318 flags |= IO_NONBLOCK;
319 break;
320 case 'r':
321 flags |= IO_READONLY;
322 break;
323 case 's':
324 flags |= IO_OSYNC;
325 break;
326 case 't':
327 flags |= IO_TRUNC;
328 break;
329 case 'R':
330 case 'x': /* backwards compatibility */
331 flags |= IO_REALTIME;
332 break;
333 case 'T':
334 flags |= IO_TMPFILE;
335 break;
336 default:
337 return command_usage(&open_cmd);
338 }
339 }
340
341 if (optind != argc - 1)
342 return command_usage(&open_cmd);
343
344 if ((flags & (IO_READONLY|IO_TMPFILE)) == (IO_READONLY|IO_TMPFILE)) {
345 fprintf(stderr, _("-T and -r options are incompatible\n"));
346 return -1;
347 }
348
349 fd = openfile(argv[optind], &geometry, flags, mode);
350 if (fd < 0)
351 return 0;
352
353 if (!platform_test_xfs_fd(fd))
354 flags |= IO_FOREIGN;
355
356 addfile(argv[optind], fd, &geometry, flags);
357 return 0;
358 }
359
360 static int
361 close_f(
362 int argc,
363 char **argv)
364 {
365 size_t length;
366 unsigned int offset;
367
368 if (close(file->fd) < 0) {
369 perror("close");
370 return 0;
371 }
372 free(file->name);
373
374 /* Shuffle the file table entries down over the removed entry */
375 offset = file - &filetable[0];
376 length = filecount * sizeof(fileio_t);
377 length -= (offset + 1) * sizeof(fileio_t);
378 if (length)
379 memmove(file, file + 1, length);
380
381 /* Resize the memory allocated for the table, possibly freeing */
382 if (--filecount) {
383 filetable = (fileio_t *)realloc(filetable, /* shrinking */
384 filecount * sizeof(fileio_t));
385 if (offset == filecount)
386 offset--;
387 file = filetable + offset;
388 } else {
389 free(filetable);
390 file = filetable = NULL;
391 }
392 filelist_f();
393 return 0;
394 }
395
396 static void
397 lsproj_help(void)
398 {
399 printf(_(
400 "\n"
401 " displays the project identifier associated with the current path\n"
402 "\n"
403 " Options:\n"
404 " -R -- recursively descend (useful when current path is a directory)\n"
405 " -D -- recursively descend, but only list projects on directories\n"
406 "\n"));
407 }
408
409 static int
410 lsproj_callback(
411 const char *path,
412 const struct stat *stat,
413 int status,
414 struct FTW *data)
415 {
416 prid_t projid;
417 int fd;
418
419 if (recurse_dir && !S_ISDIR(stat->st_mode))
420 return 0;
421
422 if ((fd = open(path, O_RDONLY)) == -1) {
423 fprintf(stderr, _("%s: cannot open %s: %s\n"),
424 progname, path, strerror(errno));
425 } else {
426 if (getprojid(path, fd, &projid) == 0)
427 printf("[%u] %s\n", (unsigned int)projid, path);
428 close(fd);
429 }
430 return 0;
431 }
432
433 static int
434 lsproj_f(
435 int argc,
436 char **argv)
437 {
438 prid_t projid;
439 int c;
440
441 recurse_all = recurse_dir = 0;
442 while ((c = getopt(argc, argv, "DR")) != EOF) {
443 switch (c) {
444 case 'D':
445 recurse_all = 0;
446 recurse_dir = 1;
447 break;
448 case 'R':
449 recurse_all = 1;
450 recurse_dir = 0;
451 break;
452 default:
453 return command_usage(&lsproj_cmd);
454 }
455 }
456
457 if (argc != optind)
458 return command_usage(&lsproj_cmd);
459
460 if (recurse_all || recurse_dir)
461 nftw(file->name, lsproj_callback,
462 100, FTW_PHYS | FTW_MOUNT | FTW_DEPTH);
463 else if (getprojid(file->name, file->fd, &projid) < 0)
464 perror("getprojid");
465 else
466 printf(_("projid = %u\n"), (unsigned int)projid);
467 return 0;
468 }
469
470 static void
471 chproj_help(void)
472 {
473 printf(_(
474 "\n"
475 " modifies the project identifier associated with the current path\n"
476 "\n"
477 " -R -- recursively descend (useful when current path is a directory)\n"
478 " -D -- recursively descend, only modifying projects on directories\n"
479 "\n"));
480 }
481
482 static int
483 chproj_callback(
484 const char *path,
485 const struct stat *stat,
486 int status,
487 struct FTW *data)
488 {
489 int fd;
490
491 if (recurse_dir && !S_ISDIR(stat->st_mode))
492 return 0;
493
494 if ((fd = open(path, O_RDONLY)) == -1) {
495 fprintf(stderr, _("%s: cannot open %s: %s\n"),
496 progname, path, strerror(errno));
497 } else {
498 if (setprojid(path, fd, prid) < 0)
499 perror("setprojid");
500 close(fd);
501 }
502 return 0;
503 }
504
505 static int
506 chproj_f(
507 int argc,
508 char **argv)
509 {
510 int c;
511
512 recurse_all = recurse_dir = 0;
513 while ((c = getopt(argc, argv, "DR")) != EOF) {
514 switch (c) {
515 case 'D':
516 recurse_all = 0;
517 recurse_dir = 1;
518 break;
519 case 'R':
520 recurse_all = 1;
521 recurse_dir = 0;
522 break;
523 default:
524 return command_usage(&chproj_cmd);
525 }
526 }
527
528 if (argc != optind + 1)
529 return command_usage(&chproj_cmd);
530
531 prid = prid_from_string(argv[optind]);
532 if (prid == -1) {
533 printf(_("invalid project ID -- %s\n"), argv[optind]);
534 return 0;
535 }
536
537 if (recurse_all || recurse_dir)
538 nftw(file->name, chproj_callback,
539 100, FTW_PHYS | FTW_MOUNT | FTW_DEPTH);
540 else if (setprojid(file->name, file->fd, prid) < 0)
541 perror("setprojid");
542 return 0;
543 }
544
545 static void
546 extsize_help(void)
547 {
548 printf(_(
549 "\n"
550 " report or modify preferred extent size (in bytes) for the current path\n"
551 "\n"
552 " -R -- recursively descend (useful when current path is a directory)\n"
553 " -D -- recursively descend, only modifying extsize on directories\n"
554 "\n"));
555 }
556
557 static int
558 get_extsize(const char *path, int fd)
559 {
560 struct fsxattr fsx;
561
562 if ((xfsctl(path, fd, XFS_IOC_FSGETXATTR, &fsx)) < 0) {
563 printf("%s: XFS_IOC_FSGETXATTR %s: %s\n",
564 progname, path, strerror(errno));
565 return 0;
566 }
567 printf("[%u] %s\n", fsx.fsx_extsize, path);
568 return 0;
569 }
570
571 static int
572 set_extsize(const char *path, int fd, long extsz)
573 {
574 struct fsxattr fsx;
575 struct stat64 stat;
576
577 if (fstat64(fd, &stat) < 0) {
578 perror("fstat64");
579 return 0;
580 }
581 if ((xfsctl(path, fd, XFS_IOC_FSGETXATTR, &fsx)) < 0) {
582 printf("%s: XFS_IOC_FSGETXATTR %s: %s\n",
583 progname, path, strerror(errno));
584 return 0;
585 }
586
587 if (S_ISREG(stat.st_mode)) {
588 fsx.fsx_xflags |= XFS_XFLAG_EXTSIZE;
589 } else if (S_ISDIR(stat.st_mode)) {
590 fsx.fsx_xflags |= XFS_XFLAG_EXTSZINHERIT;
591 } else {
592 printf(_("invalid target file type - file %s\n"), path);
593 return 0;
594 }
595 fsx.fsx_extsize = extsz;
596
597 if ((xfsctl(path, fd, XFS_IOC_FSSETXATTR, &fsx)) < 0) {
598 printf("%s: XFS_IOC_FSSETXATTR %s: %s\n",
599 progname, path, strerror(errno));
600 return 0;
601 }
602
603 return 0;
604 }
605
606 static int
607 get_extsize_callback(
608 const char *path,
609 const struct stat *stat,
610 int status,
611 struct FTW *data)
612 {
613 int fd;
614
615 if (recurse_dir && !S_ISDIR(stat->st_mode))
616 return 0;
617
618 if ((fd = open(path, O_RDONLY)) == -1) {
619 fprintf(stderr, _("%s: cannot open %s: %s\n"),
620 progname, path, strerror(errno));
621 } else {
622 get_extsize(path, fd);
623 close(fd);
624 }
625 return 0;
626 }
627
628 static int
629 set_extsize_callback(
630 const char *path,
631 const struct stat *stat,
632 int status,
633 struct FTW *data)
634 {
635 int fd;
636
637 if (recurse_dir && !S_ISDIR(stat->st_mode))
638 return 0;
639
640 if ((fd = open(path, O_RDONLY)) == -1) {
641 fprintf(stderr, _("%s: cannot open %s: %s\n"),
642 progname, path, strerror(errno));
643 } else {
644 set_extsize(path, fd, extsize);
645 close(fd);
646 }
647 return 0;
648 }
649
650 static int
651 extsize_f(
652 int argc,
653 char **argv)
654 {
655 size_t blocksize, sectsize;
656 int c;
657
658 recurse_all = recurse_dir = 0;
659 init_cvtnum(&blocksize, &sectsize);
660 while ((c = getopt(argc, argv, "DR")) != EOF) {
661 switch (c) {
662 case 'D':
663 recurse_all = 0;
664 recurse_dir = 1;
665 break;
666 case 'R':
667 recurse_all = 1;
668 recurse_dir = 0;
669 break;
670 default:
671 return command_usage(&extsize_cmd);
672 }
673 }
674
675 if (optind < argc) {
676 extsize = (long)cvtnum(blocksize, sectsize, argv[optind]);
677 if (extsize < 0) {
678 printf(_("non-numeric extsize argument -- %s\n"),
679 argv[optind]);
680 return 0;
681 }
682 } else {
683 extsize = -1;
684 }
685
686 if (recurse_all || recurse_dir)
687 nftw(file->name, (extsize >= 0) ?
688 set_extsize_callback : get_extsize_callback,
689 100, FTW_PHYS | FTW_MOUNT | FTW_DEPTH);
690 else if (extsize >= 0)
691 set_extsize(file->name, file->fd, extsize);
692 else
693 get_extsize(file->name, file->fd);
694 return 0;
695 }
696
697 static int
698 statfs_f(
699 int argc,
700 char **argv)
701 {
702 struct xfs_fsop_counts fscounts;
703 struct xfs_fsop_geom fsgeo;
704 struct statfs st;
705
706 printf(_("fd.path = \"%s\"\n"), file->name);
707 if (platform_fstatfs(file->fd, &st) < 0) {
708 perror("fstatfs");
709 } else {
710 printf(_("statfs.f_bsize = %lld\n"), (long long) st.f_bsize);
711 printf(_("statfs.f_blocks = %lld\n"), (long long) st.f_blocks);
712 #if defined(__sgi__)
713 printf(_("statfs.f_frsize = %lld\n"), (long long) st.f_frsize);
714 #else
715 printf(_("statfs.f_bavail = %lld\n"), (long long) st.f_bavail);
716 #endif
717 printf(_("statfs.f_files = %lld\n"), (long long) st.f_files);
718 printf(_("statfs.f_ffree = %lld\n"), (long long) st.f_ffree);
719 }
720 if (file->flags & IO_FOREIGN)
721 return 0;
722 if ((xfsctl(file->name, file->fd, XFS_IOC_FSGEOMETRY_V1, &fsgeo)) < 0) {
723 perror("XFS_IOC_FSGEOMETRY_V1");
724 } else {
725 printf(_("geom.bsize = %u\n"), fsgeo.blocksize);
726 printf(_("geom.agcount = %u\n"), fsgeo.agcount);
727 printf(_("geom.agblocks = %u\n"), fsgeo.agblocks);
728 printf(_("geom.datablocks = %llu\n"),
729 (unsigned long long) fsgeo.datablocks);
730 printf(_("geom.rtblocks = %llu\n"),
731 (unsigned long long) fsgeo.rtblocks);
732 printf(_("geom.rtextents = %llu\n"),
733 (unsigned long long) fsgeo.rtextents);
734 printf(_("geom.rtextsize = %u\n"), fsgeo.rtextsize);
735 printf(_("geom.sunit = %u\n"), fsgeo.sunit);
736 printf(_("geom.swidth = %u\n"), fsgeo.swidth);
737 }
738 if ((xfsctl(file->name, file->fd, XFS_IOC_FSCOUNTS, &fscounts)) < 0) {
739 perror("XFS_IOC_FSCOUNTS");
740 } else {
741 printf(_("counts.freedata = %llu\n"),
742 (unsigned long long) fscounts.freedata);
743 printf(_("counts.freertx = %llu\n"),
744 (unsigned long long) fscounts.freertx);
745 printf(_("counts.freeino = %llu\n"),
746 (unsigned long long) fscounts.freeino);
747 printf(_("counts.allocino = %llu\n"),
748 (unsigned long long) fscounts.allocino);
749 }
750 return 0;
751 }
752
753 void
754 open_init(void)
755 {
756 open_cmd.name = "open";
757 open_cmd.altname = "o";
758 open_cmd.cfunc = open_f;
759 open_cmd.argmin = 0;
760 open_cmd.argmax = -1;
761 open_cmd.flags = CMD_NOMAP_OK | CMD_NOFILE_OK | CMD_FOREIGN_OK;
762 open_cmd.args = _("[-acdrstxT] [path]");
763 open_cmd.oneline = _("open the file specified by path");
764 open_cmd.help = open_help;
765
766 stat_cmd.name = "stat";
767 stat_cmd.cfunc = stat_f;
768 stat_cmd.argmin = 0;
769 stat_cmd.argmax = 1;
770 stat_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK;
771 stat_cmd.args = _("[-v]");
772 stat_cmd.oneline = _("statistics on the currently open file");
773
774 close_cmd.name = "close";
775 close_cmd.altname = "c";
776 close_cmd.cfunc = close_f;
777 close_cmd.argmin = 0;
778 close_cmd.argmax = 0;
779 close_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK;
780 close_cmd.oneline = _("close the current open file");
781
782 statfs_cmd.name = "statfs";
783 statfs_cmd.cfunc = statfs_f;
784 statfs_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK;
785 statfs_cmd.oneline =
786 _("statistics on the filesystem of the currently open file");
787
788 chproj_cmd.name = "chproj";
789 chproj_cmd.cfunc = chproj_f;
790 chproj_cmd.args = _("[-D | -R] projid");
791 chproj_cmd.argmin = 1;
792 chproj_cmd.argmax = -1;
793 chproj_cmd.flags = CMD_NOMAP_OK;
794 chproj_cmd.oneline =
795 _("change project identifier on the currently open file");
796 chproj_cmd.help = chproj_help;
797
798 lsproj_cmd.name = "lsproj";
799 lsproj_cmd.cfunc = lsproj_f;
800 lsproj_cmd.args = _("[-D | -R]");
801 lsproj_cmd.argmin = 0;
802 lsproj_cmd.argmax = -1;
803 lsproj_cmd.flags = CMD_NOMAP_OK;
804 lsproj_cmd.oneline =
805 _("list project identifier set on the currently open file");
806 lsproj_cmd.help = lsproj_help;
807
808 extsize_cmd.name = "extsize";
809 extsize_cmd.cfunc = extsize_f;
810 extsize_cmd.args = _("[-D | -R] [extsize]");
811 extsize_cmd.argmin = 0;
812 extsize_cmd.argmax = -1;
813 extsize_cmd.flags = CMD_NOMAP_OK;
814 extsize_cmd.oneline =
815 _("get/set preferred extent size (in bytes) for the open file");
816 extsize_cmd.help = extsize_help;
817
818 add_command(&open_cmd);
819 add_command(&stat_cmd);
820 add_command(&close_cmd);
821 add_command(&statfs_cmd);
822 add_command(&chproj_cmd);
823 add_command(&lsproj_cmd);
824 add_command(&extsize_cmd);
825 }