Use err(), instread of errx()
[eleutheria.git] / proplib / prop_parse_du.c
blobc22ab1ffa3ee7afe7ee03d305a6eecc49a0008e8
1 /*
2 * [root dictionary]
3 * [child dictionary]
4 * [path]
5 * [size]
6 * [type]
7 * [child dictionary]
8 * [path]
9 * [size]
10 * [type]
11 * ...
13 * Compile with:
14 * gcc prop_du.c -o prop_du -lprop -Wall -W -Wextra -ansi -pedantic
17 #include <err.h>
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
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 */
25 #define MAX_STR 100
26 #define MAX_TOKENS 3
28 /* */
29 FILE *fp = NULL;
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);
38 int main(void)
40 char str[MAX_STR];
41 char *tokens[MAX_TOKENS]; /* for du(1) output parse */
42 char *last, *p;
43 int i, ret;
45 /* Register cleanup function */
46 if (atexit(cleanup) == -1) {
47 perror("atexit()");
48 exit(EXIT_FAILURE);
51 /* Initiate pipe stream to du(1) */
52 fp = popen("du", "r");
53 if (fp == NULL)
54 exit(EXIT_FAILURE);
56 /* Create root dictionary */
57 prd = prop_dictionary_create_with_capacity(INIT_ROOT_CAPACITY);
58 if (prd == NULL)
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 */
64 i = 0;
65 p = strtok_r(str, "\t", &last);
66 while (p && i < MAX_TOKENS - 1) {
67 tokens[i++] = p;
68 p = strtok_r(NULL, "\t", &last);
70 tokens[i] = NULL;
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);
77 if (pcd == NULL)
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()");
127 return EXIT_SUCCESS;
130 void cleanup(void)
132 /* Close pipe */
133 if (!fp) {
134 if (pclose(fp) == -1)
135 warn("pclose()");
138 /* Release proplib objects */
139 if (prd != NULL)
140 prop_object_release(prd);
141 if (prd != NULL)
142 prop_object_release(pcd);
143 if (ps != NULL)
144 prop_object_release(pn);
145 if (pn != NULL)
146 prop_object_release(ps);