Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -191,8 +191,8 @@ slattach: $(NET_LIB) slattach.o
plipconfig: $(NET_LIB) plipconfig.o
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ plipconfig.o $(NLIB) $(LDLIBS)

netstat: $(NET_LIB) netstat.o statistics.o
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ netstat.o statistics.o $(NLIB) $(SELIB) $(LDLIBS)
netstat: $(NET_LIB) netstat.o statistics.o lib/escape.o
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ netstat.o statistics.o lib/escape.o $(NLIB) $(SELIB) $(LDLIBS)

iptunnel: $(NET_LIB) iptunnel.o
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ iptunnel.o $(NLIB) $(LDLIBS)
Expand Down
28 changes: 28 additions & 0 deletions include/escape.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* escape.h - printing handling
*
* Copyright © 2011-2023 Jim Warner <james.warner@comcast.net>
* Copyright © 2016-2023 Craig Small <csmall@dropbear.xyz>
* Copyright © 1998-2005 Albert Cahalan
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/

#ifndef ESCAPE_H
#define ESCAPE_H

void escape_str_inplace (char *string, int len);

#endif
3 changes: 2 additions & 1 deletion lib/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ AFGROBJS = inet_gr.o inet6_gr.o ipx_gr.o ddp_gr.o netrom_gr.o ax25_gr.o rose_gr.
AFSROBJS = inet_sr.o inet6_sr.o netrom_sr.o ipx_sr.o setroute.o x25_sr.o
ACTOBJS = slip_ac.o ppp_ac.o activate.o
VARIA = getargs.o masq_info.o proc.o util.o nstrcmp.o interface.o sockets.o
EXTRA = escape.o

# Default Name
NET_LIB_NAME = net-tools
Expand All @@ -41,7 +42,7 @@ SONAME=libnet-tools.so.0

.SUFFIXES: .a .so

all: lib$(NET_LIB_NAME).a # lib$(NET_LIB_NAME).so
all: lib$(NET_LIB_NAME).a escape.o # lib$(NET_LIB_NAME).so

lib$(NET_LIB_NAME).a: Makefile $(TOPDIR)/config.h $(OBJS)
@echo Building $@
Expand Down
111 changes: 111 additions & 0 deletions lib/escape.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Escape character print handling derived from procps
* Copyright 1998-2002 by Albert Cahalan
* Copyright 2020-2022 Jim Warner <james.warner@comcast.net>
*
* Simplification for procps ps:
* Stephen Hemminger <stephen@networkplumber.org>, 2025
* Inplace modification:
* Stanislav Brabec <sbrabec@suse.com>, 2026
*
*/

#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <langinfo.h>

static const char UTF_tab[] = {
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, // 0x00 - 0x0F
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, // 0x10 - 0x1F
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, // 0x20 - 0x2F
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, // 0x30 - 0x3F
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, // 0x40 - 0x4F
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, // 0x50 - 0x5F
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, // 0x60 - 0x6F
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, // 0x70 - 0x7F
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, // 0x80 - 0x8F
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, // 0x90 - 0x9F
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, // 0xA0 - 0xAF
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, // 0xB0 - 0xBF
-1, -1, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, // 0xC0 - 0xCF
2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, // 0xD0 - 0xDF
3, 3, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, // 0xE0 - 0xEF
4, 4, 4, 4, 4, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, // 0xF0 - 0xFF
};

static const unsigned char ESC_tab[] = {
"@..............................." // 0x00 - 0x1F
"||||||||||||||||||||||||||||||||" // 0x20 - 0x3F
"||||||||||||||||||||||||||||||||" // 0x40 - 0x5f
"|||||||||||||||||||||||||||||||." // 0x60 - 0x7F
"????????????????????????????????" // 0x80 - 0x9F
"????????????????????????????????" // 0xA0 - 0xBF
"????????????????????????????????" // 0xC0 - 0xDF
"????????????????????????????????" // 0xE0 - 0xFF
};

static void esc_all(unsigned char *str)
{
// if bad locale/corrupt str, replace non-printing stuff
while (*str) {
unsigned char c = ESC_tab[*str];

if (c != '|')
*str = c;
++str;
}
}

static void esc_ctl(unsigned char *str, int len)
{
int i;

for (i = 0; i < len;) {
// even with a proper locale, strings might be corrupt
int n = UTF_tab[*str];

if (n < 0 || i + n > len) {
esc_all(str);
return;
}
// and eliminate those non-printing control characters
if (*str < 0x20 || *str == 0x7f)
*str = '?';
str += n;
i += n;
}
}

void escape_str_inplace(char *string, int len)
{
static int utf_sw;

if (utf_sw == 0) {
char *enc = nl_langinfo(CODESET);

utf_sw = enc && strcasecmp(enc, "UTF-8") == 0 ? 1 : -1;
}

if (utf_sw < 0)
esc_all((unsigned char *)string);
else
esc_ctl((unsigned char *)string, len);
}
9 changes: 2 additions & 7 deletions netstat.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@
#include "interface.h"
#include "util.h"
#include "proc.h"
#include "escape.h"

#if HAVE_SELINUX
#include <selinux/selinux.h>
Expand Down Expand Up @@ -468,13 +469,7 @@ static void prg_cache_load(void)
// cmdlbuf[sizeof(cmdlbuf) - 1) is already \0
cmdllen = sizeof(cmdlbuf) - 1;
// remove all embedded controls
for(int i=0; i < cmdllen; i++) {
char c = cmdlbuf[i];
if (c == 0) // we dont process arguments
break;
if (c < ' ' || c > '~') // safe 7bit ASCII
cmdlbuf[i] = '.';
}
escape_str_inplace (cmdlbuf, strlen(cmdlbuf));
if (cmdlbuf[0] == '/' && (cmdlp = strrchr(cmdlbuf, '/')))
cmdlp++;
else
Expand Down
Loading