/* add a new line to @tb, the content is based on @st */ static int add_line_from_stat(struct libscols_table *tb, struct libscols_line *parent, int parent_fd, struct stat *st, const char *name) { struct libscols_line *ln; char modbuf[11], *p; mode_t mode = st->st_mode; int rc = 0; ln = scols_table_new_line(tb, parent); if (!ln) err(EXIT_FAILURE, "failed to create output line"); /* MODE; local buffer, use scols_line_set_data() that calls strdup() */ xstrmode(mode, modbuf); if (scols_line_set_data(ln, COL_MODE, modbuf)) goto fail; /* SIZE; already allocated string, use scols_line_refer_data() */ p = size_to_human_string(0, st->st_size); if (!p || scols_line_refer_data(ln, COL_SIZE, p)) goto fail; /* NAME */ if (scols_line_set_data(ln, COL_NAME, name)) goto fail; /* colors */ if (scols_table_colors_wanted(tb)) { struct libscols_cell *ce = scols_line_get_cell(ln, COL_NAME); if (S_ISDIR(mode)) scols_cell_set_color(ce, "blue"); else if (S_ISLNK(mode)) scols_cell_set_color(ce, "cyan"); else if (S_ISBLK(mode)) scols_cell_set_color(ce, "magenta"); else if ((mode & S_IXOTH) || (mode & S_IXGRP) || (mode & S_IXUSR)) scols_cell_set_color(ce, "green"); } if (S_ISDIR(st->st_mode)) { int fd; if (parent_fd >= 0) fd = openat(parent_fd, name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC); else fd = open(name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC); if (fd >= 0) { rc = add_children(tb, ln, fd); close(fd); } } return rc; fail: err(EXIT_FAILURE, "failed to create cell data"); return -1; }
static struct libscols_line *get_line_with_id(struct libscols_table *tb, int col_id, const char *id) { struct libscols_line *ln; struct libscols_iter *itr = scols_new_iter(SCOLS_ITER_FORWARD); while (scols_table_next_line(tb, itr, &ln) == 0) { struct libscols_cell *ce = scols_line_get_cell(ln, col_id); const char *data = ce ? scols_cell_get_data(ce) : NULL; if (data && strcmp(data, id) == 0) break; } scols_free_iter(itr); return ln; }
static void compose_tree(struct libscols_table *tb, int parent_col, int id_col) { struct libscols_line *ln; struct libscols_iter *itr = scols_new_iter(SCOLS_ITER_FORWARD); while (scols_table_next_line(tb, itr, &ln) == 0) { struct libscols_line *parent = NULL; struct libscols_cell *ce = scols_line_get_cell(ln, parent_col); const char *data = ce ? scols_cell_get_data(ce) : NULL; if (data) parent = get_line_with_id(tb, id_col, data); if (parent) scols_line_add_child(parent, ln); } scols_free_iter(itr); }