Newer
Older
* All rights reserved.
* This file is part of Obarun. It is subject to the license terms in
* the LICENSE file found in the top-level directory of this
* distribution.
* This file may not be copied, modified, propagated, or distributed
* except according to the terms contained in the LICENSE file./
*/
#include <string.h>
#include <locale.h>
#include <langinfo.h>
#include <sys/types.h>
#include <wchar.h>
#include <unistd.h>//access
#include <oblibs/sastr.h>
#include <oblibs/types.h>
#include <oblibs/string.h>
#include <skalibs/genalloc.h>
#include <skalibs/lolstdio.h>
#include <skalibs/bytestr.h>
#include <skalibs/buffer.h>
#include <66/info.h>
#include <66/utils.h>
#include <66/constants.h>
#include <66/tree.h>
#include <66/enum.h>
#include <66/resolve.h>
#include <66/state.h>
static unsigned int REVERSE = 0 ;
static unsigned int NOFIELD = 1 ;
static unsigned int GRAPH = 0 ;
static wchar_t const field_suffix[] = L" :" ;

Eric Vidal
committed
static char fields[INFO_NKEY][INFO_FIELD_MAXLEN] = {{ 0 }} ;
static void info_display_name(char const *field,char const *treename) ;
static void info_display_current(char const *field,char const *treename) ;
static void info_display_enabled(char const *field,char const *treename) ;
static void info_display_init(char const *field,char const *treename) ;
static void info_display_depends(char const *field,char const *treename) ;
static void info_display_requiredby(char const *field,char const *treename) ;
static void info_display_allow(char const *field,char const *treename) ;
static void info_display_contents(char const *field,char const *treename) ;
static void info_display_groups(char const *field,char const *treename) ;
static info_graph_style *T_STYLE = &graph_default ;
info_opts_map_t const opts_tree_table[] =
{
{ .str = "name", .func = &info_display_name, .id = 0 },
{ .str = "current", .func = &info_display_current, .id = 1 },
{ .str = "enabled", .func = &info_display_enabled, .id = 2 },
{ .str = "init", .func = &info_display_init, .id = 3 },
{ .str = "allowed", .func = &info_display_allow, .id = 4 },
{ .str = "groups", .func = &info_display_groups, .id = 5 },
{ .str = "depends", .func = &info_display_depends, .id = 6 },
{ .str = "requiredby", .func = &info_display_requiredby, .id = 7 },
{ .str = "contents", .func = &info_display_contents, .id = 8 },
#define checkopts(n) if (n >= MAXOPTS) log_die(LOG_EXIT_USER, "too many options")
#define DELIM ','
static void info_display_name(char const *field, char const *treename)
{
if (NOFIELD) info_display_field_name(field) ;
if (!bprintf(buffer_1,"%s",treename))
log_dieusys(LOG_EXIT_SYS,"write to stdout") ;
if (buffer_putsflush(buffer_1,"\n") == -1)
log_dieusys(LOG_EXIT_SYS,"write to stdout") ;
static void info_display_current(char const *field,char const *treename)
int current = tree_iscurrent(pinfo->base.s, treename) ;
if (current < 0)
log_dieu(LOG_EXIT_ZERO, "read resolve file of: ", treename) ;
if (NOFIELD) info_display_field_name(field) ;
if (!bprintf(buffer_1,"%s%s%s", current ? log_color->valid : log_color->warning, current ? "yes":"no",log_color->off))
log_dieusys(LOG_EXIT_SYS,"write to stdout") ;
if (buffer_putsflush(buffer_1,"\n") == -1)
log_dieusys(LOG_EXIT_SYS,"write to stdout") ;
static void info_display_enabled(char const *field,char const *treename)
int enabled = tree_isenabled(pinfo->base.s, treename) ;
if (enabled < 0)
log_dieu(LOG_EXIT_SYS, "read resolve file of: ", treename) ;
if (NOFIELD) info_display_field_name(field) ;
if (!bprintf(buffer_1,"%s%s%s",enabled ? log_color->valid : log_color->warning, enabled ? "yes":"no",log_color->off))
log_dieusys(LOG_EXIT_SYS,"write to stdout") ;
if (buffer_putsflush(buffer_1,"\n") == -1)
log_dieusys(LOG_EXIT_SYS,"write to stdout") ;
static void info_display_init(char const *field,char const *treename)
unsigned int init = tree_isinitialized(pinfo->base.s, treename) ;
if (init == -1) log_dieu(LOG_EXIT_SYS, "resolve file of tree: ", treename) ;
if (NOFIELD) info_display_field_name(field) ;
if (!bprintf(buffer_1,"%s%s%s",init ? log_color->valid : log_color->warning, init ? "yes":"no",log_color->off))
log_dieusys(LOG_EXIT_SYS,"write to stdout") ;
if (buffer_putsflush(buffer_1,"\n") == -1)
log_dieusys(LOG_EXIT_SYS,"write to stdout") ;
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
}
static void info_display_allow(char const *field, char const *treename)
{
stralloc sa = STRALLOC_ZERO ;
resolve_tree_t tres = RESOLVE_TREE_ZERO ;
resolve_wrapper_t_ref wres = resolve_set_struct(DATA_TREE, &tres) ;
if (!resolve_read_g(wres, pinfo->base.s, treename))
log_dieusys(LOG_EXIT_SYS,"read resolve file of tree: ", treename) ;
if (NOFIELD)
info_display_field_name(field) ;
if (tres.nallow) {
if (!sastr_clean_string(&sa, tres.sa.s + tres.allow))
log_dieu(LOG_EXIT_SYS,"clean groups string") ;
if (!sa.len)
goto empty ;
size_t len = sa.len, pos = 0 ;
char t[len + 1] ;
sastr_to_char(t, &sa) ;
sa.len = 0 ;
for (; pos < len ; pos += strlen(t + pos) + 1) {
char *suid = t + pos ;
uid_t uid = 0 ;
if (!uid0_scan(suid, &uid))
log_dieusys(LOG_EXIT_SYS,"get uid of: ",suid) ;
if (pos)
if (!stralloc_cats(&sa," ")) log_die_nomem("stralloc") ;
if (!get_namebyuid(uid,&sa))
log_dieusys(LOG_EXIT_SYS, "get name of uid: ", suid) ;
}
if (!stralloc_0(&sa)) log_die_nomem("stralloc") ;
if (!sastr_rebuild_in_oneline(&sa)) log_dieu(LOG_EXIT_SYS,"rebuild list") ;
if (!stralloc_0(&sa)) log_die_nomem("stralloc") ;
info_display_list(field,&sa) ;
} else {
empty:
if (!bprintf(buffer_1,"%s%s%s\n",log_color->warning,"None",log_color->off))
log_dieusys(LOG_EXIT_SYS,"write to stdout") ;
}
resolve_free(wres) ;
stralloc_free(&sa) ;
}
static void info_display_groups(char const *field, char const *treename)
{
stralloc sa = STRALLOC_ZERO ;
resolve_tree_t tres = RESOLVE_TREE_ZERO ;
resolve_wrapper_t_ref wres = resolve_set_struct(DATA_TREE, &tres) ;
if (!resolve_read_g(wres, pinfo->base.s, treename))
log_dieusys(LOG_EXIT_SYS,"read resolve file of: ", treename) ;
if (NOFIELD)
info_display_field_name(field) ;
if (tres.ngroups) {
if (!sastr_clean_string(&sa, tres.sa.s + tres.groups))
log_dieu(LOG_EXIT_SYS,"clean groups string") ;
info_display_list(field,&sa) ;
} else {
if (!bprintf(buffer_1,"%s%s%s\n",log_color->warning,"None",log_color->off))
log_dieusys(LOG_EXIT_SYS,"write to stdout") ;
}
resolve_free(wres) ;
stralloc_free(&sa) ;
static void info_display_depends(char const *field, char const *treename)
size_t padding = 1 ;
graph_t graph = GRAPH_ZERO ;
stralloc sa = STRALLOC_ZERO ;
if (NOFIELD) padding = info_display_field_name(field) ;
else { field = 0 ; padding = 0 ; }
graph_build_tree(&graph, pinfo->base.s, E_RESOLVE_TREE_MASTER_CONTENTS) ;
r = graph_matrix_get_edge_g_sorted_sa(&sa, &graph, treename, 0, 0) ;
if (r < 0)
log_dieu(LOG_EXIT_SYS, "get the dependencies list") ;
if (!r || !sa.len)
goto empty ;
if (GRAPH) {
if (!bprintf(buffer_1,"%s\n","\\"))
log_dieusys(LOG_EXIT_SYS,"write to stdout") ;
depth_t d = info_graph_init() ;
if (!info_walk(&graph, treename, 0, &info_graph_display_tree, 0, REVERSE, &d, padding, T_STYLE))
log_dieu(LOG_EXIT_SYS,"display the graph dependencies") ;
goto freed ;
} else {
if (REVERSE)
if (!sastr_reverse(&sa))
log_dieu(LOG_EXIT_SYS,"reverse the dependencies list") ;
info_display_list(field,&sa) ;
goto freed ;
}
empty:
if (GRAPH) {
if (!bprintf(buffer_1,"%s\n","\\"))
log_dieusys(LOG_EXIT_SYS,"write to stdout") ;
if (!bprintf(buffer_1,"%*s%s%s%s%s\n",padding, "", T_STYLE->last, log_color->warning,"None",log_color->off))
log_dieusys(LOG_EXIT_SYS,"write to stdout") ;
} else {
if (!bprintf(buffer_1,"%s%s%s\n",log_color->warning,"None",log_color->off))
log_dieusys(LOG_EXIT_SYS,"write to stdout") ;
}
freed:
graph_free_all(&graph) ;
stralloc_free(&sa) ;
}
static void info_display_requiredby(char const *field, char const *treename)
{
int r ;
size_t padding = 1 ;
graph_t graph = GRAPH_ZERO ;
stralloc sa = STRALLOC_ZERO ;
if (NOFIELD) padding = info_display_field_name(field) ;
else { field = 0 ; padding = 0 ; }
graph_build_tree(&graph, pinfo->base.s, E_RESOLVE_TREE_MASTER_CONTENTS) ;
r = graph_matrix_get_edge_g_sorted_sa(&sa, &graph, treename, 1, 0) ;
if (r < 0)
log_dieu(LOG_EXIT_SYS, "get the dependencies list") ;
if (!r || !sa.len)
goto empty ;
if (GRAPH) {
if (!bprintf(buffer_1,"%s\n","\\"))
log_dieusys(LOG_EXIT_SYS,"write to stdout") ;
depth_t d = info_graph_init() ;
if (!info_walk(&graph, treename, 0, &info_graph_display_tree, 1, REVERSE, &d, padding, T_STYLE))
log_dieu(LOG_EXIT_SYS,"display the graph dependencies") ;
goto freed ;
} else {
if (REVERSE)
if (!sastr_reverse(&sa))
log_dieu(LOG_EXIT_SYS,"reverse the dependencies list") ;
info_display_list(field,&sa) ;
goto freed ;
empty:
if (GRAPH) {
if (!bprintf(buffer_1,"%s\n","\\"))
log_dieusys(LOG_EXIT_SYS,"write to stdout") ;
if (!bprintf(buffer_1,"%*s%s%s%s%s\n",padding, "", T_STYLE->last, log_color->warning,"None",log_color->off))
log_dieusys(LOG_EXIT_SYS,"write to stdout") ;
} else {
if (!bprintf(buffer_1,"%s%s%s\n",log_color->warning,"None",log_color->off))
log_dieusys(LOG_EXIT_SYS,"write to stdout") ;
}
freed:
graph_free_all(&graph) ;
stralloc_free(&sa) ;
static void info_display_contents(char const *field, char const *treename)
resolve_service_t ares[SS_MAX_SERVICE + 1] ;
if (NOFIELD) padding = info_display_field_name(field) ;
else { field = 0 ; padding = 0 ; }
graph_build_service(&graph, ares, &areslen, pinfo, STATE_FLAGS_TOPROPAGATE|STATE_FLAGS_WANTUP) ;
if (!bprintf(buffer_1,"%s\n","\\"))
log_dieusys(LOG_EXIT_SYS,"write to stdout") ;
if (!info_walk(&graph, 0, treename, &info_graph_display_service, 0, REVERSE, &d, padding, T_STYLE))
log_dieu(LOG_EXIT_SYS,"display the graph dependencies") ;
} else {
stralloc sa = STRALLOC_ZERO ;
if (!resolve_get_field_tosa_g(&sa, pinfo->base.s, treename, DATA_TREE, E_RESOLVE_TREE_CONTENTS))
log_dieu(LOG_EXIT_SYS, "get tree services list of: ", treename) ;
if (!sa.len)
goto empty ;
log_dieu(LOG_EXIT_SYS,"reverse the dependencies list") ;
if (GRAPH) {
if (!bprintf(buffer_1,"%s\n","\\"))
log_dieusys(LOG_EXIT_SYS,"write to stdout") ;
if (!bprintf(buffer_1,"%*s%s%s%s%s\n",padding, "", T_STYLE->last, log_color->warning,"None",log_color->off))
log_dieusys(LOG_EXIT_SYS,"write to stdout") ;
if (!bprintf(buffer_1,"%s%s%s\n",log_color->warning,"None",log_color->off))
log_dieusys(LOG_EXIT_SYS,"write to stdout") ;
}
}
static void info_display_all(char const *treename,int *what)
{
unsigned int idx = what[i] ;
(*opts_tree_table[idx].func)(fields[opts_tree_table[idx].id],treename) ;
}
}
static void info_parse_options(char const *str,int *what)
{
size_t pos = 0 ;
stralloc sa = STRALLOC_ZERO ;
if (!sastr_clean_string_wdelim(&sa,str,DELIM)) log_dieu(LOG_EXIT_SYS,"parse options") ;
unsigned int n = sastr_len(&sa), nopts = 0 , old ;
checkopts(n) ;
info_opts_map_t const *t ;
for (;pos < sa.len; pos += strlen(sa.s + pos) + 1) {
char *o = sa.s + pos ;
t = opts_tree_table ;
old = nopts ;
for (; t->str; t++) {
what[nopts++] = t->id ;
if (old == nopts)
log_die(LOG_EXIT_SYS,"invalid option: ",o) ;
int ssexec_tree_status(int argc, char const *const *argv, ssexec_t *info)
stralloc sa = STRALLOC_ZERO ;
pinfo = info ;
char const *treename = 0 ;
for (int i = 0 ; i < MAXOPTS ; i++)
what[i] = -1 ;
char buf[MAXOPTS][INFO_FIELD_MAXLEN] = {
"Name",
"Current",
"Enabled",
"Initialized",
"Groups",
"Depends",
"Required by",
subgetopt l = SUBGETOPT_ZERO ;
int opt = subgetopt_r(argc, argv, OPTS_TREE_STATUS, &l) ;
switch (opt)
{
case 'n' : NOFIELD = 0 ; break ;
case 'o' : legacy = 0 ; info_parse_options(l.arg,what) ; break ;
case 'g' : GRAPH = 1 ; break ;
case 'r' : REVERSE = 1 ; break ;
case 'd' : if (!uint0_scan(l.arg, &MAXDEPTH)) log_usage(info->usage, "\n", info->help) ; break ;
default : log_usage(info->usage, "\n", info->help) ;
}
}
argc -= l.ind ; argv += l.ind ;
}
if (argv[0]) treename = argv[0] ;
unsigned int i = 0 ;
for (; i < MAXOPTS - 1 ; i++)
what[i] = i ;
what[i] = -1 ;
}
info_field_align(buf,fields,field_suffix,MAXOPTS) ;
setlocale(LC_ALL, "");
if(!str_diff(nl_langinfo(CODESET), "UTF-8"))
/** should never happens as long as we have
* a default created */
char src[info->base.len + SS_SYSTEM_LEN + 1] ;
auto_strings(src, info->base.s, SS_SYSTEM) ;
if (!scan_mode(src, S_IFDIR)) {
log_info("no tree exist yet") ;
goto freed ;
}
if (!tree_isvalid(info->base.s, treename))
log_dieusys(LOG_EXIT_SYS, "find tree: ", treename) ;
info_display_all(treename, what) ;
graph_build_tree(&graph, pinfo->base.s, E_RESOLVE_TREE_MASTER_CONTENTS) ;
if (!graph_matrix_sort_tosa(&sa, &graph))
log_dieu(LOG_EXIT_SYS, "get the sorted list of trees") ;
info_display_all(sa.s + pos, what) ;
if (buffer_puts(buffer_1,"\n") == -1)
log_dieusys(LOG_EXIT_SYS,"write to stdout") ;
log_info("no tree exist yet") ;
goto freed ;
}
}
if (buffer_flush(buffer_1) == -1)
log_dieusys(LOG_EXIT_SYS, "write to stdout") ;
freed: