xref: /netbsd-src/external/gpl2/dtc/dist/fstree.c (revision cc7d2833ecf67da5a5ddc470841931eb9f6723e4)
1 /*	$NetBSD: fstree.c,v 1.1.1.3 2019/12/22 12:34:04 skrll Exp $	*/
2 
3 // SPDX-License-Identifier: GPL-2.0-or-later
4 /*
5  * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation.  2005.
6  */
7 
8 #include "dtc.h"
9 
10 #include <dirent.h>
11 #include <sys/stat.h>
12 
read_fstree(const char * dirname)13 static struct node *read_fstree(const char *dirname)
14 {
15 	DIR *d;
16 	struct dirent *de;
17 	struct stat st;
18 	struct node *tree;
19 
20 	d = opendir(dirname);
21 	if (!d)
22 		die("Couldn't opendir() \"%s\": %s\n", dirname, strerror(errno));
23 
24 	tree = build_node(NULL, NULL, NULL);
25 
26 	while ((de = readdir(d)) != NULL) {
27 		char *tmpname;
28 
29 		if (streq(de->d_name, ".")
30 		    || streq(de->d_name, ".."))
31 			continue;
32 
33 		tmpname = join_path(dirname, de->d_name);
34 
35 		if (lstat(tmpname, &st) < 0)
36 			die("stat(%s): %s\n", tmpname, strerror(errno));
37 
38 		if (S_ISREG(st.st_mode)) {
39 			struct property *prop;
40 			FILE *pfile;
41 
42 			pfile = fopen(tmpname, "rb");
43 			if (! pfile) {
44 				fprintf(stderr,
45 					"WARNING: Cannot open %s: %s\n",
46 					tmpname, strerror(errno));
47 			} else {
48 				prop = build_property(xstrdup(de->d_name),
49 						      data_copy_file(pfile,
50 								     st.st_size),
51 						      NULL);
52 				add_property(tree, prop);
53 				fclose(pfile);
54 			}
55 		} else if (S_ISDIR(st.st_mode)) {
56 			struct node *newchild;
57 
58 			newchild = read_fstree(tmpname);
59 			newchild = name_node(newchild, xstrdup(de->d_name));
60 			add_child(tree, newchild);
61 		}
62 
63 		free(tmpname);
64 	}
65 
66 	closedir(d);
67 	return tree;
68 }
69 
dt_from_fs(const char * dirname)70 struct dt_info *dt_from_fs(const char *dirname)
71 {
72 	struct node *tree;
73 
74 	tree = read_fstree(dirname);
75 	tree = name_node(tree, "");
76 
77 	return build_dt_info(DTSF_V1, NULL, tree, guess_boot_cpuid(tree));
78 }
79