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