/* * blockdev.c --- Do various simple block device ioctls from the command line * aeb, 991028 */ #include #include #include #include #include #include #include #include #include "nls.h" const char *progname; struct bdc { char *name; char *iocname; long ioc; int argtype; #define ARGNONE 0 #define ARGINTA 1 #define ARGINTP 2 #define ARGINTG 3 #define ARGLINTG 4 long argval; char *argname; char *help; } bdcms[] = { #ifdef BLKROSET { "--setro", "BLKROSET", BLKROSET, ARGINTP, 1, NULL, N_("set read-only") }, { "--setrw", "BLKROSET", BLKROSET, ARGINTP, 0, NULL, N_("set read-write") }, #endif #ifdef BLKROGET { "--getro", "BLKROGET", BLKROGET, ARGINTG, -1, NULL, N_("get read-only") }, #endif #ifdef BLKSSZGET { "--getss", "BLKSSZGET", BLKSSZGET, ARGINTG, -1, NULL, N_("get sectorsize") }, #endif #ifdef BLKGETSIZE { "--getsize", "BLKGETSIZE", BLKGETSIZE, ARGLINTG, -1, NULL, N_("get size") }, #endif #ifdef BLKRASET { "--setra", "BLKRASET", BLKRASET, ARGINTA, 0, "READAHEAD", N_("set readahead") }, #endif #ifdef BLKRAGET { "--getra", "BLKRAGET", BLKRAGET, ARGLINTG, -1, NULL, N_("get readahead") }, #endif #ifdef BLKFLSBUF { "--flushbufs", "BLKFLSBUF", BLKFLSBUF, ARGNONE, 0, NULL, N_("flush buffers") }, #endif #ifdef BLKRRPART { "--rereadpt", "BLKRRPART", BLKRRPART, ARGNONE, 0, NULL, N_("reread partition table") }, #endif }; #define SIZE(a) (sizeof(a)/sizeof((a)[0])) static void usage(void) { int i; fprintf(stderr, _("Usage: %s [-V] [-v|-q] commands devices\n"), progname); fprintf(stderr, _("Available commands:\n")); for (i = 0; i < SIZE(bdcms); i++) { fprintf(stderr, "\t%s", bdcms[i].name); if (bdcms[i].argname) fprintf(stderr, " %s", bdcms[i].argname); if (bdcms[i].help) fprintf(stderr, "\t(%s)", _(bdcms[i].help)); fprintf(stderr, "\n"); } exit(1); } int find_cmd(char *s) { int j; for (j = 0; j < SIZE(bdcms); j++) if (!strcmp(s, bdcms[j].name)) return j; return -1; } void do_commands(int fd, char **argv, int d); int main(int argc, char **argv) { int fd, d, j, k; char *p; /* egcs-2.91.66 is buggy and says: blockdev.c:93: warning: `d' might be used uninitialized */ d = 0; progname = argv[0]; if ((p = strrchr(progname, '/')) != NULL) progname = p+1; setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); if (argc < 2) usage(); /* -V not together with commands */ if (!strcmp(argv[1], "-V") || !strcmp(argv[1], "--version")) { printf("%s from %s\n", progname, util_linux_version); exit(0); } /* do each of the commands on each of the devices */ /* devices start after last command */ for (d = 1; d < argc; d++) { j = find_cmd(argv[d]); if (j >= 0) { if (bdcms[j].argtype == ARGINTA) d++; continue; } if (!strcmp(argv[d], "--")) { d++; break; } if (argv[d][0] != '-') break; } if (d >= argc) usage(); for (k = d; k < argc; k++) { fd = open(argv[k], O_RDONLY, 0); if (fd < 0) { perror(argv[k]); exit(1); } do_commands(fd, argv, d); } return 0; } void do_commands(int fd, char **argv, int d) { int res, i, j; int iarg; long larg; int verbose = 0; for (i = 1; i < d; i++) { if (!strcmp(argv[i], "-v")) { verbose = 1; continue; } if (!strcmp(argv[i], "-q")) { verbose = 0; continue; } j = find_cmd(argv[i]); if (j == -1) { fprintf(stderr, _("%s: Unknown command: %s\n"), progname, argv[i]); usage(); } switch(bdcms[j].argtype) { default: case ARGNONE: res = ioctl(fd, bdcms[j].ioc, 0); break; case ARGINTA: if (i == d-1) { fprintf(stderr, _("%s requires an argument\n"), bdcms[j].name); usage(); } iarg = atoi(argv[++i]); res = ioctl(fd, bdcms[j].ioc, iarg); break; case ARGINTP: case ARGINTG: iarg = bdcms[j].argval; res = ioctl(fd, bdcms[j].ioc, &iarg); break; case ARGLINTG: larg = bdcms[j].argval; res = ioctl(fd, bdcms[j].ioc, &larg); break; } if (res == -1) { perror(bdcms[j].iocname); if (verbose) printf("%s failed.\n", _(bdcms[j].help)); exit(1); } switch(bdcms[j].argtype) { case ARGINTG: if (verbose) printf("%s: %d\n", _(bdcms[j].help), iarg); else printf("%d\n", iarg); break; case ARGLINTG: if (verbose) printf("%s: %ld\n", _(bdcms[j].help), larg); else printf("%ld\n", larg); break; default: if (verbose) printf("%s succeeded.\n", _(bdcms[j].help)); break; } } }