1    	#include <stddef.h>
2    	#include <stdarg.h>
3    	#include <string.h>
4    	#include <inttypes.h>
5    	#include <uuid.h>
6    	#include <libgfs2.h>
7    	
8    	#include "hexedit.h"
9    	#include "gfs2hex.h"
10   	#include "struct_print.h"
11   	
12   	static void check_highlight(int highlight)
13   	{
14   		if (!termlines || line >= termlines) /* If printing or out of bounds */
15   			return;
16   		if (dmode == HEX_MODE) {
17   			if (line == (edit_row[dmode] * lines_per_row[dmode]) + 4) {
18   				if (highlight) {
19   					COLORS_HIGHLIGHT;
20   					last_entry_onscreen[dmode] = print_entry_ndx;
21   				} else
22   					COLORS_NORMAL;
23   			}
24   		} else {
25   			if ((line * lines_per_row[dmode]) - 4 ==
26   				(edit_row[dmode] - start_row[dmode]) * lines_per_row[dmode]) {
27   				if (highlight) {
28   					COLORS_HIGHLIGHT;
29   					last_entry_onscreen[dmode] = print_entry_ndx;
30   				}
31   				else
32   					COLORS_NORMAL;
33   			}
34   		}
35   	}
36   	
37   	__attribute__((format(printf,2,4)))
38   	static void print_it(const char *label, const char *fmt, const char *fmt2, ...)
39   	{
40   		va_list args;
41   		char tmp_string[NAME_MAX];
42   		const char *fmtstring;
43   		int decimalsize;
44   	
45   		if (!termlines || line < termlines) {
46   			va_start(args, fmt2);
47   			check_highlight(TRUE);
48   			if (termlines) {
49   				move(line,0);
50   				printw("%s", label);
51   				move(line,24);
52   			} else {
53   				if (!strcmp(label, "  "))
54   					printf("%-11s", label);
55   				else
56   					printf("%-24s", label);
57   			}
58   			vsprintf(tmp_string, fmt, args);
59   	
60   			if (termlines)
61   				printw("%s", tmp_string);
62   			else
63   				printf("%s", tmp_string);
64   			check_highlight(FALSE);
65   	
66   			if (fmt2) {
67   				decimalsize = strlen(tmp_string);
68   				va_end(args);
69   				va_start(args, fmt2);
70   				vsprintf(tmp_string, fmt2, args);
71   				check_highlight(TRUE);
72   				if (termlines) {
73   					move(line, 50);
74   					printw("%s", tmp_string);
75   				} else {
76   					int i;
77   					for (i=20 - decimalsize; i > 0; i--)
78   						printf(" ");
79   					printf("%s", tmp_string);
80   				}
81   				check_highlight(FALSE);
82   			} else {
83   				if (strstr(fmt,"X") || strstr(fmt,"x"))
84   					fmtstring="(hex)";
85   				else if (strstr(fmt,"s"))
86   					fmtstring="";
87   				else
88   					fmtstring="(decimal)";
89   				if (termlines) {
90   					move(line, 50);
91   					printw("%s", fmtstring);
92   				}
93   				else
94   					printf("%s", fmtstring);
95   			}
96   			if (termlines) {
97   				refresh();
98   				if (line == (edit_row[dmode] * lines_per_row[dmode]) + 4) {
99   					strncpy(efield, label + 2, 63); /* it's indented */
100  					efield[63] = '\0';
101  					strcpy(estring, tmp_string);
102  					strncpy(edit_fmt, fmt, 79);
103  					edit_fmt[79] = '\0';
104  					edit_size[dmode] = strlen(estring);
105  					COLORS_NORMAL;
106  				}
107  				last_entry_onscreen[dmode] = (line / lines_per_row[dmode]) - 4;
108  			}
109  			eol(0);
110  			va_end(args);
111  		}
112  	}
113  	
114  	#define printbe16(struct, member) do { \
115  			print_it("  "#member, "%"PRIu16, "0x%"PRIx16, be16_to_cpu(struct->member)); \
116  		} while(0)
117  	#define printbe32(struct, member) do { \
118  			print_it("  "#member, "%"PRIu32, "0x%"PRIx32, be32_to_cpu(struct->member)); \
119  		} while(0)
120  	#define printbe64(struct, member) do { \
121  			print_it("  "#member, "%"PRIu64, "0x%"PRIx64, be64_to_cpu(struct->member)); \
122  		} while(0)
123  	#define print8(struct, member) do { \
124  			print_it("  "#member, "%"PRIu8, "0x%"PRIx8, struct->member); \
125  		} while(0)
126  	
127  	void inum_print(void *nop)
128  	{
129  		struct gfs2_inum *no = nop;
130  	
131  		printbe64(no, no_formal_ino);
132  		printbe64(no, no_addr);
133  	}
134  	
135  	void meta_header_print(void *mhp)
136  	{
137  		struct gfs2_meta_header *mh = mhp;
138  	
139  		print_it("  mh_magic", "0x%08"PRIX32, NULL, be32_to_cpu(mh->mh_magic));
140  		printbe32(mh, mh_type);
141  		printbe32(mh, mh_format);
142  	}
143  	
144  	void sb_print(void *sbp)
145  	{
146  		struct gfs2_sb *sb = sbp;
147  		char readable_uuid[36+1];
148  	
149  		meta_header_print(&sb->sb_header);
150  		printbe32(sb, sb_fs_format);
151  		printbe32(sb, sb_multihost_format);
152  		printbe32(sb, sb_bsize);
153  		printbe32(sb, sb_bsize_shift);
154  		inum_print(&sb->sb_master_dir);
155  		inum_print(&sb->sb_root_dir);
156  		print_it("  sb_lockproto", "%.64s", NULL, sb->sb_lockproto);
157  		print_it("  sb_locktable", "%.64s", NULL, sb->sb_locktable);
158  		uuid_unparse(sb->sb_uuid, readable_uuid);
159  		print_it("  uuid", "%36s", NULL, readable_uuid);
160  	}
161  	
162  	void rindex_print(void *rip)
163  	{
164  		struct gfs2_rindex *ri = rip;
165  	
166  		printbe64(ri, ri_addr);
167  		printbe32(ri, ri_length);
168  		printbe64(ri, ri_data0);
169  		printbe32(ri, ri_data);
170  		printbe32(ri, ri_bitbytes);
171  	}
172  	
173  	void rgrp_print(void *rgp)
174  	{
175  		struct gfs2_rgrp *rg = rgp;
176  	
177  		meta_header_print(&rg->rg_header);
178  		printbe32(rg, rg_flags);
179  		printbe32(rg, rg_free);
180  		printbe32(rg, rg_dinodes);
181  		printbe32(rg, rg_skip);
182  		printbe64(rg, rg_igeneration);
183  		printbe64(rg, rg_data0);
184  		printbe32(rg, rg_data);
185  		printbe32(rg, rg_bitbytes);
186  		printbe32(rg, rg_crc);
187  	}
188  	
189  	void quota_print(void *qp)
190  	{
191  		struct gfs2_quota *q = qp;
192  	
193  		printbe64(q, qu_limit);
194  		printbe64(q, qu_warn);
195  		printbe64(q, qu_value);
196  	}
197  	
198  	void dinode_print(void *dip)
199  	{
200  		struct gfs2_dinode *_di = dip;
201  	
202  		meta_header_print(&_di->di_header);
203  		inum_print(&_di->di_num);
204  	
205  		print_it("  di_mode", "0%"PRIo32, NULL, be32_to_cpu(di->di_mode));
206  		printbe32(_di, di_uid);
207  		printbe32(_di, di_gid);
208  		printbe32(_di, di_nlink);
209  		printbe64(_di, di_size);
210  		printbe64(_di, di_blocks);
211  		printbe64(_di, di_atime);
212  		printbe64(_di, di_mtime);
213  		printbe64(_di, di_ctime);
214  		printbe32(_di, di_major);
215  		printbe32(_di, di_minor);
216  		printbe64(_di, di_goal_meta);
217  		printbe64(_di, di_goal_data);
218  		print_it("  di_flags", "0x%.8"PRIX32, NULL, be32_to_cpu(_di->di_flags));
219  		printbe32(_di, di_payload_format);
220  		printbe16(_di, di_height);
221  		printbe16(_di, di_depth);
222  		printbe32(_di, di_entries);
223  		printbe64(_di, di_eattr);
224  	}
225  	
226  	void leaf_print(void *lfp)
227  	{
228  		struct gfs2_leaf *lf = lfp;
229  	
230  		meta_header_print(&lf->lf_header);
231  		printbe16(lf, lf_depth);
232  		printbe16(lf, lf_entries);
233  		printbe32(lf, lf_dirent_format);
234  		printbe64(lf, lf_next);
235  		printbe64(lf, lf_inode);
236  		printbe32(lf, lf_dist);
237  		printbe32(lf, lf_nsec);
238  		printbe64(lf, lf_sec);
239  	}
240  	
241  	/**
242  	 * Print an extended attribute.
243  	 * eap: Pointer to the start of the extended attribute.
244  	 * lim: Record length limit. Used to check ea_name_len.
245  	 */
246  	void ea_header_print(void *eap, unsigned lim)
247  	{
248  		char buf[GFS2_EA_MAX_NAME_LEN + 1];
249  		struct gfs2_ea_header *ea = eap;
(1) Event assign: After this assignment, the following bits of "len" are known to be unset: "8-31"
Also see events: [bit][dead_error_condition][dead_error_line]
250  		unsigned len = ea->ea_name_len;
251  	
252  		printbe32(ea, ea_rec_len);
253  		printbe32(ea, ea_data_len);
254  		print8(ea, ea_name_len);
255  		print8(ea, ea_type);
256  		print8(ea, ea_flags);
257  		print8(ea, ea_num_ptrs);
258  	
259  		if (sizeof(*ea) + len >= lim)
260  			return;
261  	
(2) Event bit: At condition "len > 255U", the following bits of "len" are known to be unset: "8-31"
(3) Event dead_error_condition: The condition "len > 255U" cannot be true.
Also see events: [assign][dead_error_line]
262  		if (len > GFS2_EA_MAX_NAME_LEN)
(4) Event dead_error_line: Execution cannot reach this statement: "len = 255U;".
Also see events: [assign][bit][dead_error_condition]
263  			len = GFS2_EA_MAX_NAME_LEN;
264  		memcpy(buf, ea + 1, len);
265  		buf[len] = '\0';
266  		print_it("  name", "%s", NULL, buf);
267  	}
268  	
269  	void log_header_print(void *lhp)
270  	{
271  		struct gfs2_log_header *lh = lhp;
272  	
273  		meta_header_print(&lh->lh_header);
274  		printbe64(lh, lh_sequence);
275  		print_it("  lh_flags", "0x%.8"PRIX32, NULL, be32_to_cpu(lh->lh_flags));
276  		printbe32(lh, lh_tail);
277  		printbe32(lh, lh_blkno);
278  		print_it("  lh_hash", "0x%.8"PRIX32, NULL, be32_to_cpu(lh->lh_hash));
279  		print_it("  lh_crc", "0x%.8"PRIX32, NULL, be32_to_cpu(lh->lh_crc));
280  		printbe32(lh, lh_nsec);
281  		printbe64(lh, lh_sec);
282  		printbe64(lh, lh_addr);
283  		printbe64(lh, lh_jinode);
284  		printbe64(lh, lh_statfs_addr);
285  		printbe64(lh, lh_quota_addr);
286  		print_it("  lh_local_total", "%"PRId64, "0x%"PRIx64, be64_to_cpu(lh->lh_local_total));
287  		print_it("  lh_local_free", "%"PRId64, "0x%"PRIx64, be64_to_cpu(lh->lh_local_free));
288  		print_it("  lh_local_dinodes", "%"PRId64, "0x%"PRIx64, be64_to_cpu(lh->lh_local_dinodes));
289  	}
290  	
291  	void log_descriptor_print(void *ldp)
292  	{
293  		struct gfs2_log_descriptor *ld = ldp;
294  	
295  		meta_header_print(&ld->ld_header);
296  		printbe32(ld, ld_type);
297  		printbe32(ld, ld_length);
298  		printbe32(ld, ld_data1);
299  		printbe32(ld, ld_data2);
300  	}
301  	
302  	void statfs_change_print(void *scp)
303  	{
304  		struct gfs2_statfs_change *sc = scp;
305  	
306  		print_it("  sc_total", "%"PRId64, "0x%"PRIx64, be64_to_cpu(sc->sc_total));
307  		print_it("  sc_free", "%"PRId64, "0x%"PRIx64, be64_to_cpu(sc->sc_free));
308  		print_it("  sc_dinodes", "%"PRId64, "0x%"PRIx64, be64_to_cpu(sc->sc_dinodes));
309  	}
310  	
311  	void quota_change_print(void *qcp)
312  	{
313  		struct gfs2_quota_change *qc = qcp;
314  	
315  		print_it("  qc_change", "%"PRId64, "0x%"PRIx64, be64_to_cpu(qc->qc_change));
316  		print_it("  qc_flags", "0x%.8"PRIX32, NULL, be32_to_cpu(qc->qc_flags));
317  		printbe32(qc, qc_id);
318  	}
319