Dear tech,
<tl;dr>
One can put a 80 columns tty into a javascript plugin
and display 'listing' like formatted data on a Browser.
This may be as fancy as a <blink> tag,
taste is not something to argue.
Nevertheless those fancy space aligned array,
heir of the continuous feed printer paper,
are not satisfactory unix compliant !
Of course the program output text, and text
is inter operable, but output is dependant of the column amout,
most of program does not bother to check if it is a tty on stdout,
the next program in the pipe chain, shall guess those spacing,
especially if the program change output according to available
room.
For example systat, this amazing openbsd health viewer,
output something close to:
PR D SRC DEST STATE AGE EXP PKTS
udp O 192.168.10.170:25599 69.28.83.155:123 2:2 6894 46 440
udp O 192.168.10.170:42074 198.27.65.66:123 2:2 6894 46 442
tcp I 192.168.10.159:65258 192.168.10.170:22 4:4 6817 86400 5852
But given the number of column digit may be printf with a suffix like K
after the amount as been divided.
Given the situation, 2 possibilities, parse those cases, or directly ask
data to kernel with appropriate ioctl.
Well, i already wrote a perl program that extract the states and put them
into a perl a structure, I assure you, you do not want to read or maintain
this
'code'.
So plague or cholera ? not my choice.
It would be convenient to output structured text info for many system
commands,
not long ago someone wanted to alter ifconfig output and it leads to messy
retro compatibility issue.
As far as i am concern i would enjoy having ifconfig -json that output
{"lo0":{"flags":8049,"hflags":"<UP,LOOPBACK,RUNNING,MULTICAST>",
"mtu":32768,"priority":0 [...] }
instead of
# ifconfig lo0
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 32768
priority: 0
groups: lo
inet6 fe80::1%lo0 prefixlen 64 scopeid 0x4
inet6 ::1 prefixlen 128
inet 127.0.0.1 netmask 0xff000000
This would still be unix phylosophy but also way more easy to maintain
for scripts.
</tl;dr>
Anyway, i slightly modify systat to alter the output, is openbsd interested
in
this kind of modification ?
The current patch output a relaxed json (i did not handle the comma
completly,
this require a field_def modification in my design)
to keep the patch tidy.
# ./obj/systat -b -w 73 states
1 users Load 0.06 0.07 0.07 Wed May 13 10:41:15
2015
PR D SRC DEST STATE AGE EXP PKTS
udp O 192.168.10.170:25599 69.28.83.155:123 2:2 7597 41 484
udp O 192.168.10.170:42074 198.27.65.66:123 2:2 7597 51 486
tcp I 192.168.10.159:65258 192.168.10.170:22 4:4 7520 86400 6132
tcp I 192.168.10.159:65336 192.168.10.170:22 4:4 6821 83201 315
tcp I 192.168.10.159:65344 192.168.10.170:22 4:4 6629 84444 4633
udp O 192.168.10.170:34190 162.219.6.68:123 2:2 2235 43 150
udp O 192.168.10.170:46986 173.243.192.18:123 2:2 172 35 20
# ./obj/systat -bj -w 73 states
{"states":[["proto","direction","source","dest","state","age","expire",packets"],["udp","
192.168.10.170:25599","69.28.83.155:123
","Out","2:2",7851,33,1.259566e-310,1.259566e-310,1.259566e-310,
],["udp","192.168.10.170:42074","198.27.65.66:123
","Out","2:2",7851,56,1.259566e-310,1.259566e-310,1.259566e-310,
],["tcp","192.168.10.159:65258","192.168.10.170:22","In","4:4",7774,86400,1.259566e-310,1.259566e-310,1.259566e-310,
],["tcp","192.168.10.159:65336","192.168.10.170:22","In","4:4",7075,82947,1.259566e-310,1.259566e-310,1.259566e-310,
],["tcp","192.168.10.159:65344","192.168.10.170:22","In","4:4",6883,86352,1.259566e-310,1.259566e-310,1.259566e-310,
],["udp","192.168.10.170:34190","162.219.6.68:123
","Out","2:2",2489,52,1.259566e-310,1.259566e-310,1.259566e-310,
],["udp","192.168.10.170:46986","173.243.192.18:123
","Out","2:2",426,33,1.259566e-310,1.259566e-310,1.259566e-310,
]]}#
This is not a patch proposal but a work that would benefit sysadmin that
script
life.
Would it be pushed when finished, shall it be done differently ?
Index: engine.c
===================================================================
RCS file: /cvs/src/usr.bin/systat/engine.c,v
retrieving revision 1.18
diff -u -p -r1.18 engine.c
--- engine.c 19 Jan 2015 07:39:24 -0000 1.18
+++ engine.c 13 May 2015 14:53:12 -0000
@@ -53,6 +53,7 @@ struct view_ent {
useconds_t udelay = 5000000;
int dispstart = 0;
int interactive = 1;
+int json = 0;
int averageonly = 0;
int maxprint = 0;
int paused = 0;
@@ -267,6 +268,11 @@ print_fld_str(field_def *fld, const char
if (fld->start < 0)
return;
+ if (json) {
+ printf("\"%s\",",str);
+ return;
+ }
+
len = strlen(str);
if (len >= fld->width) {
@@ -671,6 +677,11 @@ print_fld_age(field_def *fld, unsigned i
if (len < 1)
return;
+ if (json) {
+ printf("%u,",age);
+ return;
+ }
+
s = age % 60;
m = age / 60;
h = m / 60;
@@ -724,6 +735,11 @@ print_fld_sdiv(field_def *fld, u_int64_t
if (len < 1)
return;
+ if (json) {
+ printf("%e,",size);
+ return;
+ }
+
tb_start();
if (tbprintft("%llu", size) <= len)
goto ok;
@@ -1012,7 +1028,9 @@ disp_update(void)
home_line = li + maxprint + 1;
}
- print_title();
+ if (json == 0) {
+ print_title();
+ }
if (curr_mgr->print_fn != NULL)
curr_mgr->print_fn();
Index: engine.h
===================================================================
RCS file: /cvs/src/usr.bin/systat/engine.h,v
retrieving revision 1.8
diff -u -p -r1.8 engine.h
--- engine.h 7 Sep 2013 11:43:49 -0000 1.8
+++ engine.h 13 May 2015 14:53:12 -0000
@@ -148,6 +148,7 @@ extern int sortdir;
extern useconds_t udelay;
extern int dispstart;
extern int interactive;
+extern int json;
extern int averageonly;
extern int maxprint;
extern int paused;
Index: main.c
===================================================================
RCS file: /cvs/src/usr.bin/systat/main.c,v
retrieving revision 1.61
diff -u -p -r1.61 main.c
--- main.c 16 Jan 2015 00:03:37 -0000 1.61
+++ main.c 13 May 2015 14:53:12 -0000
@@ -207,7 +207,7 @@ void
usage(void)
{
extern char *__progname;
- fprintf(stderr, "usage: %s [-aBbiNn] [-d count] "
+ fprintf(stderr, "usage: %s [-aBbijNn] [-d count] "
"[-s delay] [-w width] [view] [delay]\n", __progname);
exit(1);
}
@@ -403,7 +403,7 @@ main(int argc, char *argv[])
if (setresgid(gid, gid, gid) == -1)
err(1, "setresgid");
- while ((ch = getopt(argc, argv, "BNabd:ins:w:")) != -1) {
+ while ((ch = getopt(argc, argv, "BNabd:ijns:w:")) != -1) {
switch (ch) {
case 'a':
maxlines = -1;
@@ -424,6 +424,9 @@ main(int argc, char *argv[])
break;
case 'i':
interactive = 1;
+ break;
+ case 'j':
+ json = 1;
break;
case 'N':
nflag = 0;
Index: pftop.c
===================================================================
RCS file: /cvs/src/usr.bin/systat/pftop.c,v
retrieving revision 1.31
diff -u -p -r1.31 pftop.c
--- pftop.c 9 Feb 2015 02:00:38 -0000 1.31
+++ pftop.c 13 May 2015 14:53:12 -0000
@@ -81,6 +81,7 @@ int select_states(void);
int read_states(void);
void sort_states(void);
void print_states(void);
+void print_states_json(void);
int select_rules(void);
int read_rules(void);
@@ -908,6 +909,21 @@ print_state(struct pfsync_state * s, str
return 1;
}
+
+void
+print_states_json(void) {
+ int n, count = 0;
+ printf("{\"states\":[");
+
printf("[\"proto\",\"direction\",\"source\",\"dest\",\"state\",\"age\",\"expire\",packets\"]");
+ for (n = dispstart; n < num_disp; n++) {
+ printf(",[");
+ count += print_state(state_buf + state_ord[n],
+ state_cache[state_ord[n]]);
+ printf("]");
+ }
+ printf("]}");
+}
+
void
print_states(void)
{
@@ -1726,8 +1742,13 @@ initpftop(void)
int cachesize = DEFAULT_CACHE_SIZE;
v = views;
- while(v->name != NULL)
+ while(v->name != NULL) {
+ if ( v->mgr->print_fn == print_states && json == 1 ) {
+ v->mgr->header_fn = NULL;
+ v->mgr->print_fn = print_states_json;
+ }
add_view(v++);
+ }
pf_dev = open("/dev/pf", O_RDONLY);
if (pf_dev == -1) {
Best regards ,
--
---------------------------------------------------------------------------------------------------------------------
() ascii ribbon campaign - against html e-mail
/\