|
Packit Service |
360c39 |
#include <fcntl.h>
|
|
Packit Service |
360c39 |
#include <unistd.h>
|
|
Packit Service |
360c39 |
#include <string.h>
|
|
Packit Service |
360c39 |
#include "libgfs2.h"
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
static void usage(const char *cmd)
|
|
Packit Service |
360c39 |
{
|
|
Packit Service |
360c39 |
printf("A language for modifying and querying a gfs2 file system.\n");
|
|
Packit Service |
360c39 |
printf("Usage: %s [options] <fs_path>\n", cmd);
|
|
Packit Service |
360c39 |
printf("Available options:\n");
|
|
Packit Service |
360c39 |
printf(" -h Print this help message and exit\n");
|
|
Packit Service |
360c39 |
printf(" -f <script_path> Path to script file or '-' for stdin (the default)\n");
|
|
Packit Service |
360c39 |
printf(" -T Print a list of gfs2 structure types and exit\n");
|
|
Packit Service |
360c39 |
printf(" -F <type> Print a list of fields belonging to a type and exit\n");
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
struct cmdopts {
|
|
Packit Service |
360c39 |
char *fspath;
|
|
Packit Service |
360c39 |
FILE *src;
|
|
Packit Service |
360c39 |
unsigned help:1;
|
|
Packit Service |
360c39 |
};
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
static int metastrcmp(const void *a, const void *b)
|
|
Packit Service |
360c39 |
{
|
|
Packit Service |
360c39 |
const struct lgfs2_metadata *m1 = *(struct lgfs2_metadata **)a;
|
|
Packit Service |
360c39 |
const struct lgfs2_metadata *m2 = *(struct lgfs2_metadata **)b;
|
|
Packit Service |
360c39 |
return strcmp(m1->name, m2->name);
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
static void print_structs(void)
|
|
Packit Service |
360c39 |
{
|
|
Packit Service |
360c39 |
const struct lgfs2_metadata *mlist[lgfs2_metadata_size];
|
|
Packit Service |
360c39 |
int i;
|
|
Packit Service |
360c39 |
for (i = 0; i < lgfs2_metadata_size; i++)
|
|
Packit Service |
360c39 |
mlist[i] = &lgfs2_metadata[i];
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
qsort(mlist, lgfs2_metadata_size, sizeof(struct lgfs2_metadata *), metastrcmp);
|
|
Packit Service |
360c39 |
for (i = 0; i < lgfs2_metadata_size; i++)
|
|
Packit Service |
360c39 |
if (mlist[i]->mh_type != GFS2_METATYPE_NONE)
|
|
Packit Service |
360c39 |
printf("%s\n", mlist[i]->name);
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
static void print_fields(const char *name)
|
|
Packit Service |
360c39 |
{
|
|
Packit Service |
360c39 |
const struct lgfs2_metadata *m = lgfs2_find_mtype_name(name, LGFS2_MD_GFS1|LGFS2_MD_GFS2);
|
|
Packit Service |
360c39 |
if (m != NULL) {
|
|
Packit Service |
360c39 |
const struct lgfs2_metafield *fields = m->fields;
|
|
Packit Service |
360c39 |
const unsigned nfields = m->nfields;
|
|
Packit Service |
360c39 |
int i;
|
|
Packit Service |
360c39 |
for (i = 0; i < nfields; i++)
|
|
Packit Service |
360c39 |
printf("0x%.4x %s\n", fields[i].offset, fields[i].name);
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
static int getopts(int argc, char *argv[], struct cmdopts *opts)
|
|
Packit Service |
360c39 |
{
|
|
Packit Service |
360c39 |
int opt;
|
|
Packit Service |
360c39 |
opts->src = stdin;
|
|
Packit Service |
360c39 |
while ((opt = getopt(argc, argv, "F:f:hT")) != -1) {
|
|
Packit Service |
360c39 |
switch (opt) {
|
|
Packit Service |
360c39 |
case 'f':
|
|
Packit Service |
360c39 |
if (strcmp("-", optarg)) {
|
|
Packit Service |
360c39 |
opts->src = fopen(optarg, "r");
|
|
Packit Service |
360c39 |
if (opts->src == NULL) {
|
|
Packit Service |
360c39 |
perror("Failed to open source file");
|
|
Packit Service |
360c39 |
return 1;
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
break;
|
|
Packit Service |
360c39 |
case 'T':
|
|
Packit Service |
360c39 |
print_structs();
|
|
Packit Service |
360c39 |
exit(0);
|
|
Packit Service |
360c39 |
case 'F':
|
|
Packit Service |
360c39 |
print_fields(optarg);
|
|
Packit Service |
360c39 |
exit(0);
|
|
Packit Service |
360c39 |
case 'h':
|
|
Packit Service |
360c39 |
opts->help = 1;
|
|
Packit Service |
360c39 |
return 0;
|
|
Packit Service |
360c39 |
default:
|
|
Packit Service |
360c39 |
fprintf(stderr, "Use -h for help\n");
|
|
Packit Service |
360c39 |
return 1;
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
if (argc - optind != 1) {
|
|
Packit Service |
360c39 |
usage(argv[0]);
|
|
Packit Service |
360c39 |
fprintf(stderr, "Missing file system path. Use -h for help.\n");
|
|
Packit Service |
360c39 |
return 1;
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
opts->fspath = strdup(argv[optind]);
|
|
Packit Service |
360c39 |
if (opts->fspath == NULL) {
|
|
Packit Service |
360c39 |
perror("getopts");
|
|
Packit Service |
360c39 |
return 1;
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
return 0;
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
static int openfs(const char *path, struct gfs2_sbd *sdp)
|
|
Packit Service |
360c39 |
{
|
|
Packit Service |
360c39 |
int fd;
|
|
Packit Service |
360c39 |
int ret;
|
|
Packit Service |
360c39 |
int sane;
|
|
Packit Service |
360c39 |
uint64_t count;
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
fd = open(path, O_RDWR);
|
|
Packit Service |
360c39 |
if (fd < 0) {
|
|
Packit Service |
360c39 |
fprintf(stderr, "Failed to open %s\n", path);
|
|
Packit Service |
360c39 |
return 1;
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
memset(sdp, 0, sizeof(*sdp));
|
|
Packit Service |
360c39 |
sdp->bsize = GFS2_BASIC_BLOCK;
|
|
Packit Service |
360c39 |
sdp->device_fd = fd;
|
|
Packit Service |
360c39 |
ret = compute_constants(sdp);
|
|
Packit Service |
360c39 |
if (ret != 0) {
|
|
Packit Service |
360c39 |
perror("Bad constants");
|
|
Packit Service |
360c39 |
return 1;
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
ret = lgfs2_get_dev_info(fd, &sdp->dinfo);
|
|
Packit Service |
360c39 |
if (ret != 0) {
|
|
Packit Service |
360c39 |
perror("Failed to gather device info");
|
|
Packit Service |
360c39 |
return 1;
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
fix_device_geometry(sdp);
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
ret = read_sb(sdp);
|
|
Packit Service |
360c39 |
if (ret != 0) {
|
|
Packit Service |
360c39 |
perror("Could not read sb");
|
|
Packit Service |
360c39 |
return 1;
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
sdp->master_dir = lgfs2_inode_read(sdp, sdp->sd_sb.sb_master_dir.no_addr);
|
|
Packit Service |
360c39 |
gfs2_lookupi(sdp->master_dir, "rindex", 6, &sdp->md.riinode);
|
|
Packit Service |
360c39 |
sdp->fssize = sdp->device.length;
|
|
Packit Service |
360c39 |
if (sdp->md.riinode) {
|
|
Packit Service |
360c39 |
rindex_read(sdp, 0, &count, &sane);
|
|
Packit Service |
360c39 |
} else {
|
|
Packit Service |
360c39 |
perror("Failed to look up rindex");
|
|
Packit Service |
360c39 |
return 1;
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
return 0;
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
int main(int argc, char *argv[])
|
|
Packit Service |
360c39 |
{
|
|
Packit Service |
360c39 |
int ret;
|
|
Packit Service |
360c39 |
struct cmdopts opts = {NULL, NULL};
|
|
Packit Service |
360c39 |
struct gfs2_sbd sbd;
|
|
Packit Service |
360c39 |
struct lgfs2_lang_result *result;
|
|
Packit Service |
360c39 |
struct lgfs2_lang_state *state;
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
if (getopts(argc, argv, &opts)) {
|
|
Packit Service |
360c39 |
exit(1);
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
if (opts.help) {
|
|
Packit Service |
360c39 |
usage(argv[0]);
|
|
Packit Service |
360c39 |
exit(0);
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
if (openfs(argv[optind], &sbd))
|
|
Packit Service |
360c39 |
exit(1);
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
state = lgfs2_lang_init();
|
|
Packit Service |
360c39 |
if (state == NULL) {
|
|
Packit Service |
360c39 |
perror("lgfs2_lang_init failed");
|
|
Packit Service |
360c39 |
exit(1);
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
ret = lgfs2_lang_parsef(state, opts.src);
|
|
Packit Service |
360c39 |
if (ret != 0) {
|
|
Packit Service |
360c39 |
fprintf(stderr, "Parse failed\n");
|
|
Packit Service |
360c39 |
free(opts.fspath);
|
|
Packit Service |
360c39 |
return ret;
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
for (result = lgfs2_lang_result_next(state, &sbd;;
|
|
Packit Service |
360c39 |
result != NULL;
|
|
Packit Service |
360c39 |
result = lgfs2_lang_result_next(state, &sbd)) {
|
|
Packit Service |
360c39 |
lgfs2_lang_result_print(result);
|
|
Packit Service |
360c39 |
lgfs2_lang_result_free(&result);
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
gfs2_rgrp_free(&sbd.rgtree);
|
|
Packit Service |
360c39 |
inode_put(&sbd.md.riinode);
|
|
Packit Service |
360c39 |
inode_put(&sbd.master_dir);
|
|
Packit Service |
360c39 |
lgfs2_lang_free(&state);
|
|
Packit Service |
360c39 |
free(opts.fspath);
|
|
Packit Service |
360c39 |
return 0;
|
|
Packit Service |
360c39 |
}
|
|
Packit Service |
360c39 |
|
|
Packit Service |
360c39 |
// libgfs2 still requires an external print_it function
|
|
Packit Service |
360c39 |
void print_it(const char *label, const char *fmt, const char *fmt2, ...) { return; }
|