14 * gcc prop_du.c -o prop_du -lprop -Wall -W -Wextra -ansi -pedantic
21 #include <prop/proplib.h>
23 #define INIT_ROOT_CAPACITY 100 /* root's dict initial capacity */
24 #define INIT_CHILD_CAPACITY 3 /* child's dict initial capacity */
30 prop_dictionary_t prd
= NULL
; /* root dictionary */
31 prop_dictionary_t pcd
= NULL
; /* child dictionary */
32 prop_number_t ps
= NULL
; /* path name */
33 prop_string_t pn
= NULL
; /* size in bytes */
35 /* Function prototypes */
36 static void cleanup(void);
41 char *tokens
[MAX_TOKENS
]; /* for du(1) output parse */
45 /* Register cleanup function */
46 if (atexit(cleanup
) == -1) {
51 /* Initiate pipe stream to du(1) */
52 fp
= popen("du", "r");
56 /* Create root dictionary */
57 prd
= prop_dictionary_create_with_capacity(INIT_ROOT_CAPACITY
);
59 err(EXIT_FAILURE
, "prop_dictionary_create_with_capacity()");
61 /* Read from stream */
62 while (fgets(str
, MAX_STR
, fp
) != NULL
) {
63 /* Parse output of du(1) command */
65 p
= strtok_r(str
, "\t", &last
);
66 while (p
&& i
< MAX_TOKENS
- 1) {
68 p
= strtok_r(NULL
, "\t", &last
);
72 /* Trim '\n' from tokens[1] */
73 (tokens
[1])[strlen(tokens
[1]) - 1] = '\0';
75 /* Create child dictionary */
76 pcd
= prop_dictionary_create_with_capacity(INIT_CHILD_CAPACITY
);
78 err(EXIT_FAILURE
, "prop_dictionary_create_with_capacity()");
81 * tokens[0] holds the size in bytes
83 * We use a signed prop_number_t object, so that
84 * when externalized it will be represented as decimal
85 * (unsigned numbers are externalized in base-16).
87 * Note: atoi() does not detect errors, but we trust
88 * du(1) to provide us with valid input. Otherwise,
89 * we should use strtol(3) or sscanf(3).
91 pn
= prop_number_create_integer(atoi(tokens
[0]));
93 /* tokens[1] holds the path */
94 ps
= prop_string_create_cstring(tokens
[1]);
96 /* Add path to child dictionary */
97 if (prop_dictionary_set(pcd
, "path", ps
) == FALSE
)
98 err(EXIT_FAILURE
, "prop_dictionary_set()");
100 /* Add size to child dictionary */
101 if (prop_dictionary_set(pcd
, "size in bytes", pn
) == FALSE
)
102 err(EXIT_FAILURE
, "prop_dictionary_set()");
104 /* Add child dictionary to root dictionary */
105 if (prop_dictionary_set(prd
, tokens
[1], pcd
) == FALSE
)
106 err(EXIT_FAILURE
, "prop_dictionary_set()");
108 /* Release `pn' and `ps' */
109 prop_object_release(pn
);
110 prop_object_release(ps
);
112 /* Release child dictionary */
113 prop_object_release(pcd
);
116 /* Externalize root dictionary to file in XML representation */
117 if (prop_dictionary_externalize_to_file(prd
, "./data.xml") == FALSE
)
118 err(EXIT_FAILURE
, "prop_dictionary_externalize_to_file()");
120 /* Release root dictionary */
121 prop_object_release(prd
);
123 /* Close pipe stream */
124 if (pclose(fp
) == -1)
125 err(EXIT_FAILURE
, "pclose()");
134 if (pclose(fp
) == -1)
138 /* Release proplib objects */
140 prop_object_release(prd
);
142 prop_object_release(pcd
);
144 prop_object_release(pn
);
146 prop_object_release(ps
);