LCOV - code coverage report
Current view: top level - libgfs2 - gfs2l.c (source / functions) Hit Total Coverage
Test: gfs2-utils.info Lines: 46 123 37.4 %
Date: 2023-10-25 12:04:14 Functions: 3 7 42.9 %

          Line data    Source code
       1             : #include <fcntl.h>
       2             : #include <unistd.h>
       3             : #include <string.h>
       4             : #include "lang.h"
       5             : #include "libgfs2.h"
       6             : 
       7           0 : static void usage(const char *cmd)
       8             : {
       9           0 :         printf("A language for modifying and querying a gfs2 file system.\n");
      10           0 :         printf("Usage: %s [options] <fs_path>\n", cmd);
      11           0 :         printf("Available options:\n");
      12           0 :         printf("  -h                Print this help message and exit\n");
      13           0 :         printf("  -f <script_path>  Path to script file or '-' for stdin (the default)\n");
      14           0 :         printf("  -T                Print a list of gfs2 structure types and exit\n");
      15           0 :         printf("  -F <type>         Print a list of fields belonging to a type and exit\n");
      16           0 : }
      17             : 
      18             : struct cmdopts {
      19             :         char *fspath;
      20             :         FILE *src;
      21             :         unsigned help:1;
      22             : };
      23             : 
      24           0 : static int metastrcmp(const void *a, const void *b)
      25             : {
      26           0 :         const struct lgfs2_metadata *m1 = *(struct lgfs2_metadata **)a;
      27           0 :         const struct lgfs2_metadata *m2 = *(struct lgfs2_metadata **)b;
      28           0 :         return strcmp(m1->name, m2->name);
      29             : }
      30             : 
      31           0 : static int print_structs(void)
      32             : {
      33             :         const struct lgfs2_metadata **mlist;
      34             :         int i;
      35             : 
      36           0 :         mlist = calloc(lgfs2_metadata_size, sizeof(struct lgfs2_metadata *));
      37           0 :         if (mlist == NULL) {
      38           0 :                 perror("Failed to create metadata type array");
      39           0 :                 return 1;
      40             :         }
      41           0 :         for (i = 0; i < lgfs2_metadata_size; i++)
      42           0 :                 mlist[i] = &lgfs2_metadata[i];
      43             : 
      44           0 :         qsort(mlist, lgfs2_metadata_size, sizeof(struct lgfs2_metadata *), metastrcmp);
      45           0 :         for (i = 0; i < lgfs2_metadata_size; i++)
      46           0 :                 if (mlist[i]->mh_type != GFS2_METATYPE_NONE)
      47           0 :                         printf("%s\n", mlist[i]->name);
      48           0 :         free(mlist);
      49           0 :         return 0;
      50             : }
      51             : 
      52           0 : static void print_fields(const char *name)
      53             : {
      54           0 :         const struct lgfs2_metadata *m = lgfs2_find_mtype_name(name);
      55           0 :         if (m != NULL) {
      56           0 :                 const struct lgfs2_metafield *fields = m->fields;
      57           0 :                 const unsigned nfields = m->nfields;
      58             :                 int i;
      59           0 :                 for (i = 0; i < nfields; i++)
      60           0 :                         printf("0x%.4x %s\n", fields[i].offset, fields[i].name);
      61             :         }
      62           0 : }
      63             : 
      64           8 : static int getopts(int argc, char *argv[], struct cmdopts *opts)
      65             : {
      66             :         int opt;
      67           8 :         opts->src = stdin;
      68           8 :         while ((opt = getopt(argc, argv, "F:f:hT")) != -1) {
      69           0 :                 switch (opt) {
      70           0 :                 case 'f':
      71           0 :                         if (strcmp("-", optarg)) {
      72           0 :                                 opts->src = fopen(optarg, "r");
      73           0 :                                 if (opts->src == NULL) {
      74           0 :                                         perror("Failed to open source file");
      75           0 :                                         return 1;
      76             :                                 }
      77             :                         }
      78           0 :                         break;
      79           0 :                 case 'T':
      80           0 :                         exit(print_structs());
      81           0 :                 case 'F':
      82           0 :                         print_fields(optarg);
      83           0 :                         exit(0);
      84           0 :                 case 'h':
      85           0 :                         opts->help = 1;
      86           0 :                         return 0;
      87           0 :                 default:
      88           0 :                         fprintf(stderr, "Use -h for help\n");
      89           0 :                         return 1;
      90             :                 }
      91             :         }
      92             : 
      93           8 :         if (argc - optind != 1) {
      94           0 :                 usage(argv[0]);
      95           0 :                 fprintf(stderr, "Missing file system path. Use -h for help.\n");
      96           0 :                 return 1;
      97             :         }
      98             : 
      99           8 :         opts->fspath = strdup(argv[optind]);
     100           8 :         if (opts->fspath == NULL) {
     101           0 :                 perror("getopts");
     102           0 :                 return 1;
     103             :         }
     104           8 :         return 0;
     105             : }
     106             : 
     107           8 : static int openfs(const char *path, struct lgfs2_sbd *sdp)
     108             : {
     109             :         int fd;
     110             :         int ret;
     111             :         int ok;
     112             :         uint64_t count;
     113             : 
     114           8 :         fd = open(path, O_RDWR);
     115           8 :         if (fd < 0) {
     116           0 :                 fprintf(stderr, "Failed to open %s\n", path);
     117           0 :                 return 1;
     118             :         }
     119             : 
     120           8 :         memset(sdp, 0, sizeof(*sdp));
     121           8 :         sdp->sd_bsize = GFS2_BASIC_BLOCK;
     122           8 :         sdp->device_fd = fd;
     123           8 :         ret = lgfs2_compute_constants(sdp);
     124           8 :         if (ret != 0) {
     125           0 :                 perror("Bad constants");
     126           0 :                 return 1;
     127             :         }
     128           8 :         ret = lgfs2_get_dev_info(fd, &sdp->dinfo);
     129           8 :         if (ret != 0) {
     130           0 :                 perror("Failed to gather device info");
     131           0 :                 return 1;
     132             :         }
     133           8 :         lgfs2_fix_device_geometry(sdp);
     134             : 
     135           8 :         ret = lgfs2_read_sb(sdp);
     136           8 :         if (ret != 0) {
     137           0 :                 perror("Could not read sb");
     138           0 :                 return 1;
     139             :         }
     140             : 
     141           8 :         sdp->master_dir = lgfs2_inode_read(sdp, sdp->sd_meta_dir.in_addr);
     142           8 :         sdp->md.riinode = lgfs2_lookupi(sdp->master_dir, "rindex", 6);
     143           8 :         sdp->fssize = sdp->device.length;
     144           8 :         if (sdp->md.riinode) {
     145           8 :                 lgfs2_rindex_read(sdp, &count, &ok);
     146             :         } else {
     147           0 :                 perror("Failed to look up rindex");
     148           0 :                 return 1;
     149             :         }
     150           8 :         return 0;
     151             : }
     152             : 
     153           8 : int main(int argc, char *argv[])
     154             : {
     155             :         int ret;
     156           8 :         struct cmdopts opts = {NULL, NULL};
     157             :         struct lgfs2_sbd sbd;
     158             :         struct lgfs2_lang_result *result;
     159             :         struct lgfs2_lang_state *state;
     160             : 
     161           8 :         if (getopts(argc, argv, &opts)) {
     162           0 :                 exit(1);
     163             :         }
     164             : 
     165           8 :         if (opts.help) {
     166           0 :                 usage(argv[0]);
     167           0 :                 exit(0);
     168             :         }
     169             : 
     170           8 :         if (openfs(argv[optind], &sbd))
     171           0 :                 exit(1);
     172             : 
     173           8 :         state = lgfs2_lang_init();
     174           8 :         if (state == NULL) {
     175           0 :                 perror("lgfs2_lang_init failed");
     176           0 :                 exit(1);
     177             :         }
     178             : 
     179           8 :         ret = lgfs2_lang_parsef(state, opts.src);
     180           8 :         if (ret != 0) {
     181           0 :                 fprintf(stderr, "Parse failed\n");
     182           0 :                 free(opts.fspath);
     183           0 :                 return ret;
     184             :         }
     185             : 
     186           8 :         for (result = lgfs2_lang_result_next(state, &sbd);
     187          16 :              result != NULL;
     188           8 :              result = lgfs2_lang_result_next(state, &sbd)) {
     189           8 :                 lgfs2_lang_result_print(result);
     190           8 :                 lgfs2_lang_result_free(&result);
     191             :         }
     192             : 
     193           8 :         lgfs2_rgrp_free(&sbd, &sbd.rgtree);
     194           8 :         lgfs2_inode_put(&sbd.md.riinode);
     195           8 :         lgfs2_inode_put(&sbd.master_dir);
     196           8 :         lgfs2_lang_free(&state);
     197           8 :         free(opts.fspath);
     198           8 :         return 0;
     199             : }

Generated by: LCOV version 1.14