* GNU Library General Public License for more details.
*/
#include <sys/types.h>
-#include "../proc/procps.h"
-#include "common.h"
+#include <string.h>
+#include "procps.h"
+#include "escape.h"
+#include "readproc.h"
+// What it would be for a UTF-8 locale:
+// "Z-------------------------------"
+// "********************************"
+// "********************************"
+// "*******************************-"
+// "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" Trailing UTF-8, and badness in 8-bit.
+// "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy" Trailing UTF-8, and safe in 8-bit.
+// "--222222222222222222222222222222"
+// ".333333333333.3.44444444555566--" The '.' means '3', with problem chars.
+//
+// Problems include non-shortest forms, UTF-16, and non-characters.
+// The 4-byte, 5-byte, and 6-byte sequences are full of trouble too.
+
+#if 0
/* sanitize a string, without the nice BSD library function: */
/* strvis(vis_args, k->ki_args, VIS_TAB | VIS_NL | VIS_NOSLASH) */
int octal_escape_str(char *restrict dst, const char *restrict src, size_t n){
*(dst++) = '\0';
return i;
}
+#endif
/* sanitize a string via one-way mangle */
-int simple_escape_str(char *restrict dst, const char *restrict src, size_t n){
+int escape_str(char *restrict dst, const char *restrict src, size_t bytes){
unsigned char c;
size_t i;
const char codes[] =
"********************************"
"********************************"
"********************************";
- for(i=0; i<n;){
+ bytes--; // allow room for NUL character
+ for(i=0; i<bytes;){
c = (unsigned char) *(src++);
switch(codes[c]){
case 'Z':
}
leave:
*(dst++) = '\0';
- return i;
+ return i+1; // bytes of text, excluding the NUL
}
-/* escape a string as desired */
-int escape_str(char *restrict dst, const char *restrict src, size_t n){
- return simple_escape_str(dst, src, n);
-}
+/////////////////////////////////////////////////
-/* escape an argv or environment string array */
-int escape_strlist(char *restrict dst, const char *restrict const *restrict src, size_t n){
+// escape an argv or environment string array
+//
+// bytes arg means sizeof(buf)
+int escape_strlist(char *restrict dst, const char *restrict const *restrict src, size_t bytes){
size_t i = 0;
- while(*src){
- i += simple_escape_str(dst+i, *src, n-i);
- if((n-i > 1) && src[1]) dst[i++] = ' ';
+
+//if(!*src){ just never call this function without checking first
+// do something nice
+//}
+
+ for(;;){
+ i += escape_str(dst+i, *src, bytes-i);
+ if(bytes-i < 3) break; // need room for space, a character, and the NUL
src++;
+ if(!*src) break; // need something to print
+ dst[i++] = ' ';
}
- return i;
+ return i; // bytes of text, excluding the NUL
+}
+
+///////////////////////////////////////////////////
+
+int escape_command(char *restrict const outbuf, const proc_t *restrict const pp, int bytes, int glyphs, unsigned flags){
+ int overhead = 1; // the trailing NUL
+ int end = 0;
+
+ if(bytes > glyphs+1) bytes=glyphs+1; // FIXME: assumes 8-bit locale
+
+ if(flags & ESC_ARGS){
+ const char **lc = (const char**)pp->cmdline;
+ if(lc && *lc) return escape_strlist(outbuf, lc, bytes);
+ }
+ if(flags & ESC_BRACKETS){
+ overhead += 2;
+ }
+ if(flags & ESC_DEFUNCT){
+ if(pp->state=='Z') overhead += 10; // chars in " <defunct>"
+ else flags &= ~ESC_DEFUNCT;
+ }
+ if(overhead >= bytes){ // if no room for even one byte of the command name
+ // you'd damn well better have _some_ space
+ outbuf[0] = '-';
+ outbuf[1] = '\0';
+ return 1;
+ }
+ if(flags & ESC_BRACKETS){
+ outbuf[end++] = '[';
+ }
+ end += escape_str(outbuf+end, pp->cmd, bytes-overhead);
+
+ // Hmmm, do we want "[foo] <defunct>" or "[foo <defunct>]"?
+ if(flags & ESC_BRACKETS){
+ outbuf[end++] = ']';
+ }
+ if(flags & ESC_DEFUNCT){
+ memcpy(outbuf+end, " <defunct>", 10);
+ end += 10;
+ }
+
+ outbuf[end] = '\0';
+ return end; // bytes or glyphs, not including the NUL
}
--- /dev/null
+#ifndef PROCPS_PROC_ESCAPE_H
+#define PROCPS_PROC_ESCAPE_H
+
+//#include <stdio.h>
+#include <sys/types.h>
+#include "procps.h"
+#include "readproc.h"
+
+EXTERN_C_BEGIN
+
+#define ESC_ARGS 0x1 // try to use cmdline instead of cmd
+#define ESC_BRACKETS 0x2 // if using cmd, put '[' and ']' around it
+#define ESC_DEFUNCT 0x4 // mark zombies with " <defunct>"
+
+extern int escape_strlist(char *restrict dst, const char *restrict const *restrict src, size_t n);
+extern int escape_str(char *restrict dst, const char *restrict src, size_t n);
+extern int octal_escape_str(char *restrict dst, const char *restrict src, size_t n);
+extern int simple_escape_str(char *restrict dst, const char *restrict src, size_t n);
+
+extern int escape_command(char *restrict const outbuf, const proc_t *restrict const pp, int bytes, int glyphs, unsigned flags);
+
+EXTERN_C_END
+#endif