More comments & minor rearrangemets
[eleutheria.git] / proplib / prop_du.c
blob278b1b09c2090b2ca24e3cc9198afc01341e08c3
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_CAPACITY 100
24 #define MAX_STR 100
25 #define MAX_TOKENS 3
27 int main(void)
29 char str[MAX_STR];
30 char *tokens[MAX_TOKENS]; /* for du(1) output parse */
31 char *last, *p;
32 int i, ret;
33 FILE *fp;
34 prop_dictionary_t prd; /* root dictionary */
35 prop_dictionary_t pcd; /* child dictionary */
36 prop_number_t pn; /* for size in bytes */
37 prop_string_t ps; /* path name */
39 /* Initiate pipe stream to du(1) */
40 fp = popen("du", "r");
41 if (fp == NULL) {
42 perror("popen()");
43 exit(EXIT_FAILURE);
46 /* Create root dictionary */
47 prd = prop_dictionary_create_with_capacity(INIT_CAPACITY);
48 if (prd == NULL) {
49 pclose(fp);
50 err(EXIT_FAILURE, "prop_dictionary_create_with_capacity()");
53 /* Read from stream */
54 while (fgets(str, MAX_STR, fp) != NULL) {
55 /* Parse output of du(1) command */
56 i = 0;
57 p = strtok_r(str, "\t", &last);
58 while (p && i < MAX_TOKENS - 1) {
59 tokens[i++] = p;
60 p = strtok_r(NULL, "\t", &last);
62 tokens[i] = NULL;
64 /* Trim '\n' from tokens[1] */
65 (tokens[1])[strlen(tokens[1]) - 1] = '\0';
67 /* Create child dictionary */
68 pcd = prop_dictionary_create_with_capacity(INIT_CAPACITY);
69 if (pcd == NULL) {
70 prop_object_release(prd);
71 err(EXIT_FAILURE, "prop_dictionary_create_with_capacity()");
74 /* tokens[1] holds the path */
75 ps = prop_string_create_cstring(tokens[1]);
78 * tokens[0] holds the size in bytes
80 * We use a signed prop_number_t object, so that
81 * when externalized it will be represented as decimal
82 * (unsigned numbers are externalized in base-16).
84 * Note: atoi() does not detect errors, but we trust
85 * du(1) to provide us with valid input. Otherwise,
86 * we should use strtol(3) or sscanf(3).
88 pn = prop_number_create_integer(atoi(tokens[0]));
90 /* Add path to child dictionary */
91 if (prop_dictionary_set(pcd, "path", ps) == FALSE) {
92 prop_object_release(pn);
93 prop_object_release(ps);
94 prop_object_release(pcd);
95 prop_object_release(prd);
98 /* Add size to child dictionary */
99 if (prop_dictionary_set(pcd, "size in bytes", pn) == FALSE) {
100 prop_object_release(pn);
101 prop_object_release(pcd);
102 prop_object_release(prd);
103 err(EXIT_FAILURE, "prop_dictionary_set()");
106 /* Add child dictionary to root dictionary */
107 prop_dictionary_set(prd, tokens[1], pcd);
109 /* Release `pn' and `ps' */
110 prop_object_release(pn);
111 prop_object_release(ps);
113 /* Release child dictionary */
114 prop_object_release(pcd);
117 /* Externalize root dictionary to file in XML representation */
118 if (prop_dictionary_externalize_to_file(prd, "./data.xml") == FALSE) {
119 prop_object_release(prd);
120 err(EXIT_FAILURE, "prop_dictionary_externalize_to_file()");
123 /* Release root dictionary */
124 prop_object_release(prd);
126 /* Close pipe stream */
127 if (pclose(fp) == -1)
128 err(EXIT_FAILURE, "pclose()");
130 return EXIT_SUCCESS;