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
/\

Reply via email to