--- old/usr/src/cmd/svc/svcs/svcs.c	Mon Aug  5 17:15:39 2019
+++ new/usr/src/cmd/svc/svcs/svcs.c	Mon Aug  5 17:15:39 2019
@@ -22,6 +22,7 @@
 /*
  * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ * Copyright 2015 Nexenta Systems, Inc.  All rights reserved.
  * Copyright (c) 2015, 2016 by Delphix. All rights reserved.
  */
 
@@ -146,6 +147,7 @@
 static int *opt_columns = NULL;		/* Indices into columns to display. */
 static int opt_cnum = 0;
 static int opt_processes = 0;		/* Print processes? */
+static int opt_scripted = 0;		/* No header, tabs as separators. */
 static int *opt_sort = NULL;		/* Indices into columns to sort. */
 static int opt_snum = 0;
 static int opt_nstate_shown = 0;	/* Will nstate be shown? */
@@ -1001,6 +1003,33 @@
 		buf[i] = ~buf[i];
 }
 
+static void
+sprint_str(char **buf, const char *str, size_t width)
+{
+	char *newbuf;
+	size_t newsz = (*buf != NULL ? strlen(*buf) : 0) + 2;
+
+	if (opt_scripted)
+		newsz += strlen(str);
+	else
+		newsz += width;
+
+	newbuf = safe_malloc(newsz);
+
+	if (opt_scripted) {
+		(void) snprintf(newbuf, newsz, "%s%s%s",
+		    *buf != NULL ? *buf : "",
+		    *buf != NULL ? "\t" : "",
+		    str);
+	} else {
+		(void) snprintf(newbuf, newsz, "%s%-*s ",
+		    *buf != NULL ? *buf : "", width, str);
+	}
+
+	free(*buf);
+	*buf = newbuf;
+}
+
 /* CTID */
 #define	CTID_COLUMN_WIDTH		6
 #define	CTID_COLUMN_BUFSIZE		20	/* max ctid_t + space + \0 */
@@ -1010,8 +1039,8 @@
 {
 	int r;
 	uint64_t c;
-	size_t newsize = (*buf ? strlen(*buf) : 0) + CTID_COLUMN_BUFSIZE;
-	char *newbuf = safe_malloc(newsize);
+	char ctid_buf[CTID_COLUMN_BUFSIZE] = { 0 };
+	char *cstr;
 	int restarter_spec;
 
 	/*
@@ -1031,18 +1060,14 @@
 		}
 	}
 
-	if (r == 0)
-		(void) snprintf(newbuf, newsize, "%s%*lu ",
-		    *buf ? *buf : "", CTID_COLUMN_WIDTH, (ctid_t)c);
-	else if (r == E2BIG)
-		(void) snprintf(newbuf, newsize, "%s%*lu* ",
-		    *buf ? *buf : "", CTID_COLUMN_WIDTH - 1, (ctid_t)c);
-	else
-		(void) snprintf(newbuf, newsize, "%s%*s ",
-		    *buf ? *buf : "", CTID_COLUMN_WIDTH, "-");
-	if (*buf)
-		free(*buf);
-	*buf = newbuf;
+	if (r == 0 || r == E2BIG) {
+		if (r == E2BIG)
+			ctid_buf[CTID_COLUMN_BUFSIZE - 2] = '*';
+		cstr = ulltostr(c, &ctid_buf[CTID_COLUMN_BUFSIZE - 2]);
+		sprint_str(buf, cstr, CTID_COLUMN_WIDTH);
+	} else {
+		sprint_str(buf, "-", CTID_COLUMN_WIDTH);
+	}
 }
 
 #define	CTID_SORTKEY_WIDTH		(sizeof (uint64_t))
@@ -1094,8 +1119,6 @@
 sprint_desc(char **buf, scf_walkinfo_t *wip)
 {
 	char *x;
-	size_t newsize;
-	char *newbuf;
 
 	if (common_name_buf == NULL)
 		common_name_buf = safe_malloc(max_scf_value_length + 1);
@@ -1120,17 +1143,7 @@
 		if (*x == '\n')
 			*x = ' ';
 
-	if (strlen(common_name_buf) > DESC_COLUMN_WIDTH)
-		newsize = (*buf ? strlen(*buf) : 0) +
-		    strlen(common_name_buf) + 1;
-	else
-		newsize = (*buf ? strlen(*buf) : 0) + DESC_COLUMN_WIDTH + 1;
-	newbuf = safe_malloc(newsize);
-	(void) snprintf(newbuf, newsize, "%s%-*s ", *buf ? *buf : "",
-	    DESC_COLUMN_WIDTH, common_name_buf);
-	if (*buf)
-		free(*buf);
-	*buf = newbuf;
+	sprint_str(buf, common_name_buf, DESC_COLUMN_WIDTH);
 }
 
 /* ARGSUSED */
@@ -1220,8 +1233,6 @@
 sprint_state(char **buf, scf_walkinfo_t *wip)
 {
 	char state_name[MAX_SCF_STATE_STRING_SZ + 1];
-	size_t newsize;
-	char *newbuf;
 
 	if (wip->pg == NULL) {
 		get_restarter_string_prop(wip->inst, scf_property_state,
@@ -1240,14 +1251,7 @@
 	} else
 		(void) strcpy(state_name, SCF_STATE_STRING_LEGACY);
 
-	newsize = (*buf ? strlen(*buf) : 0) + MAX_SCF_STATE_STRING_SZ + 2;
-	newbuf = safe_malloc(newsize);
-	(void) snprintf(newbuf, newsize, "%s%-*s ", *buf ? *buf : "",
-	    MAX_SCF_STATE_STRING_SZ + 1, state_name);
-
-	if (*buf)
-		free(*buf);
-	*buf = newbuf;
+	sprint_str(buf, state_name, MAX_SCF_STATE_STRING_SZ);
 }
 
 static void
@@ -1259,10 +1263,8 @@
 static void
 sprint_nstate(char **buf, scf_walkinfo_t *wip)
 {
-	char next_state_name[MAX_SCF_STATE_STRING_SZ];
+	char next_state_name[MAX_SCF_STATE_STRING_SZ + 1];
 	boolean_t blank = 0;
-	size_t newsize;
-	char *newbuf;
 
 	if (wip->pg == NULL) {
 		get_restarter_string_prop(wip->inst, scf_property_next_state,
@@ -1272,8 +1274,9 @@
 		if (next_state_name[0] == '\0' ||
 		    strcmp(next_state_name, SCF_STATE_STRING_NONE) == 0)
 			blank = 1;
-	} else
+	} else {
 		blank = 1;
+	}
 
 	if (blank) {
 		next_state_name[0] = '-';
@@ -1280,13 +1283,7 @@
 		next_state_name[1] = '\0';
 	}
 
-	newsize = (*buf ? strlen(*buf) : 0) + MAX_SCF_STATE_STRING_SZ + 1;
-	newbuf = safe_malloc(newsize);
-	(void) snprintf(newbuf, newsize, "%s%-*s ", *buf ? *buf : "",
-	    MAX_SCF_STATE_STRING_SZ - 1, next_state_name);
-	if (*buf)
-		free(*buf);
-	*buf = newbuf;
+	sprint_str(buf, next_state_name, MAX_SCF_STATE_STRING_SZ);
 }
 
 static void
@@ -1298,10 +1295,8 @@
 static void
 sprint_s(char **buf, scf_walkinfo_t *wip)
 {
-	char tmp[3];
-	char state_name[MAX_SCF_STATE_STRING_SZ];
-	size_t newsize = (*buf ? strlen(*buf) : 0) + 4;
-	char *newbuf = safe_malloc(newsize);
+	char state_name[MAX_SCF_STATE_STRING_SZ + 1];
+	char tmp[3] = { 0 };
 
 	if (wip->pg == NULL) {
 		get_restarter_string_prop(wip->inst, scf_property_state,
@@ -1317,20 +1312,15 @@
 		tmp[1] = ' ';
 	}
 	tmp[2] = ' ';
-	(void) snprintf(newbuf, newsize, "%s%-*s", *buf ? *buf : "",
-	    3, tmp);
-	if (*buf)
-		free(*buf);
-	*buf = newbuf;
+
+	sprint_str(buf, tmp, 2);
 }
 
 static void
 sprint_n(char **buf, scf_walkinfo_t *wip)
 {
-	char tmp[2];
-	size_t newsize = (*buf ? strlen(*buf) : 0) + 3;
-	char *newbuf = safe_malloc(newsize);
-	char nstate_name[MAX_SCF_STATE_STRING_SZ];
+	char nstate_name[MAX_SCF_STATE_STRING_SZ + 1];
+	char tmp[2] = { 0 };
 
 	if (wip->pg == NULL) {
 		get_restarter_string_prop(wip->inst, scf_property_next_state,
@@ -1340,24 +1330,19 @@
 			tmp[0] = '-';
 		else
 			tmp[0] = state_to_char(nstate_name);
-	} else
+	} else {
 		tmp[0] = '-';
+	}
 
-	(void) snprintf(newbuf, newsize, "%s%-*s ", *buf ? *buf : "",
-	    2, tmp);
-	if (*buf)
-		free(*buf);
-	*buf = newbuf;
+	sprint_str(buf, tmp, 1);
 }
 
 static void
 sprint_sn(char **buf, scf_walkinfo_t *wip)
 {
-	char tmp[3];
-	size_t newsize = (*buf ? strlen(*buf) : 0) + 4;
-	char *newbuf = safe_malloc(newsize);
-	char nstate_name[MAX_SCF_STATE_STRING_SZ];
-	char state_name[MAX_SCF_STATE_STRING_SZ];
+	char state_name[MAX_SCF_STATE_STRING_SZ + 1];
+	char nstate_name[MAX_SCF_STATE_STRING_SZ + 1];
+	char tmp[3] = { 0 };
 
 	if (wip->pg == NULL) {
 		get_restarter_string_prop(wip->inst, scf_property_state,
@@ -1375,12 +1360,7 @@
 		tmp[1] = '-';
 	}
 
-	tmp[2] = ' ';
-	(void) snprintf(newbuf, newsize, "%s%-*s ", *buf ? *buf : "",
-	    3, tmp);
-	if (*buf)
-		free(*buf);
-	*buf = newbuf;
+	sprint_str(buf, tmp, 2);
 }
 
 /* ARGSUSED */
@@ -1415,16 +1395,15 @@
 static void
 sprint_sta(char **buf, scf_walkinfo_t *wip)
 {
-	char state_name[MAX_SCF_STATE_STRING_SZ];
-	char sta[5];
-	size_t newsize = (*buf ? strlen(*buf) : 0) + 6;
-	char *newbuf = safe_malloc(newsize);
+	char state_name[MAX_SCF_STATE_STRING_SZ + 1];
+	char sta[5] = { 0 };
 
-	if (wip->pg == NULL)
+	if (wip->pg == NULL) {
 		get_restarter_string_prop(wip->inst, scf_property_state,
 		    state_name, sizeof (state_name));
-	else
+	} else {
 		(void) strcpy(state_name, SCF_STATE_STRING_LEGACY);
+	}
 
 	(void) strcpy(sta, state_abbrev(state_name));
 
@@ -1431,34 +1410,25 @@
 	if (wip->pg == NULL && !opt_nstate_shown && transitioning(wip->inst))
 		(void) strcat(sta, "*");
 
-	(void) snprintf(newbuf, newsize, "%s%-4s ", *buf ? *buf : "", sta);
-	if (*buf)
-		free(*buf);
-	*buf = newbuf;
+	sprint_str(buf, sta, 4);
 }
 
 static void
 sprint_nsta(char **buf, scf_walkinfo_t *wip)
 {
-	char state_name[MAX_SCF_STATE_STRING_SZ];
-	size_t newsize = (*buf ? strlen(*buf) : 0) + 6;
-	char *newbuf = safe_malloc(newsize);
+	char state_name[MAX_SCF_STATE_STRING_SZ + 1];
 
-	if (wip->pg == NULL)
+	if (wip->pg == NULL) {
 		get_restarter_string_prop(wip->inst, scf_property_next_state,
 		    state_name, sizeof (state_name));
-	else
+	} else {
 		(void) strcpy(state_name, SCF_STATE_STRING_NONE);
+	}
 
 	if (strcmp(state_name, SCF_STATE_STRING_NONE) == 0)
-		(void) snprintf(newbuf, newsize, "%s%-4s ", *buf ? *buf : "",
-		    "-");
+		sprint_str(buf, "-", 4);
 	else
-		(void) snprintf(newbuf, newsize, "%s%-4s ", *buf ? *buf : "",
-		    state_abbrev(state_name));
-	if (*buf)
-		free(*buf);
-	*buf = newbuf;
+		sprint_str(buf, state_abbrev(state_name), 4);
 }
 
 /* FMRI */
@@ -1467,8 +1437,6 @@
 sprint_fmri(char **buf, scf_walkinfo_t *wip)
 {
 	char *fmri_buf = safe_malloc(max_scf_fmri_length + 1);
-	size_t newsize;
-	char *newbuf;
 
 	if (wip->pg == NULL) {
 		if (scf_instance_to_fmri(wip->inst, fmri_buf,
@@ -1484,17 +1452,8 @@
 			(void) strcat(fmri_buf, LEGACY_UNKNOWN);
 	}
 
-	if (strlen(fmri_buf) > FMRI_COLUMN_WIDTH)
-		newsize = (*buf ? strlen(*buf) : 0) + strlen(fmri_buf) + 2;
-	else
-		newsize = (*buf ? strlen(*buf) : 0) + FMRI_COLUMN_WIDTH + 2;
-	newbuf = safe_malloc(newsize);
-	(void) snprintf(newbuf, newsize, "%s%-*s ", *buf ? *buf : "",
-	    FMRI_COLUMN_WIDTH, fmri_buf);
+	sprint_str(buf, fmri_buf, FMRI_COLUMN_WIDTH);
 	free(fmri_buf);
-	if (*buf)
-		free(*buf);
-	*buf = newbuf;
 }
 
 static void
@@ -1515,8 +1474,6 @@
 sprint_scope(char **buf, scf_walkinfo_t *wip)
 {
 	char *scope_buf = safe_malloc(max_scf_name_length + 1);
-	size_t newsize = (*buf ? strlen(*buf) : 0) + COMPONENT_COLUMN_WIDTH + 2;
-	char *newbuf = safe_malloc(newsize);
 
 	assert(wip->scope != NULL);
 
@@ -1523,11 +1480,7 @@
 	if (scf_scope_get_name(wip->scope, scope_buf, max_scf_name_length) < 0)
 		scfdie();
 
-	(void) snprintf(newbuf, newsize, "%s%-*s ", *buf ? *buf : "",
-	    COMPONENT_COLUMN_WIDTH, scope_buf);
-	if (*buf)
-		free(*buf);
-	*buf = newbuf;
+	sprint_str(buf, scope_buf, COMPONENT_COLUMN_WIDTH);
 	free(scope_buf);
 }
 
@@ -1547,8 +1500,6 @@
 sprint_service(char **buf, scf_walkinfo_t *wip)
 {
 	char *svc_buf = safe_malloc(max_scf_name_length + 1);
-	char *newbuf;
-	size_t newsize;
 
 	if (wip->pg == NULL) {
 		if (scf_service_get_name(wip->svc, svc_buf,
@@ -1560,19 +1511,8 @@
 			(void) strcpy(svc_buf, LEGACY_UNKNOWN);
 	}
 
-
-	if (strlen(svc_buf) > COMPONENT_COLUMN_WIDTH)
-		newsize = (*buf ? strlen(*buf) : 0) + strlen(svc_buf) + 2;
-	else
-		newsize = (*buf ? strlen(*buf) : 0) +
-		    COMPONENT_COLUMN_WIDTH + 2;
-	newbuf = safe_malloc(newsize);
-	(void) snprintf(newbuf, newsize, "%s%-*s ", *buf ? *buf : "",
-	    COMPONENT_COLUMN_WIDTH, svc_buf);
+	sprint_str(buf, svc_buf, COMPONENT_COLUMN_WIDTH);
 	free(svc_buf);
-	if (*buf)
-		free(*buf);
-	*buf = newbuf;
 }
 
 static void
@@ -1591,25 +1531,20 @@
 static void
 sprint_instance(char **buf, scf_walkinfo_t *wip)
 {
-	char *tmp = safe_malloc(max_scf_name_length + 1);
-	size_t newsize = (*buf ? strlen(*buf) : 0) + COMPONENT_COLUMN_WIDTH + 2;
-	char *newbuf = safe_malloc(newsize);
+	char *inst_buf = safe_malloc(max_scf_name_length + 1);
 
 	if (wip->pg == NULL) {
-		if (scf_instance_get_name(wip->inst, tmp,
+		if (scf_instance_get_name(wip->inst, inst_buf,
 		    max_scf_name_length + 1) < 0)
 			scfdie();
 	} else {
-		tmp[0] = '-';
-		tmp[1] = '\0';
+		inst_buf[0] = '-';
+		inst_buf[1] = '\0';
 	}
 
-	(void) snprintf(newbuf, newsize, "%s%-*s ", *buf ? *buf : "",
-	    COMPONENT_COLUMN_WIDTH, tmp);
-	if (*buf)
-		free(*buf);
-	*buf = newbuf;
-	free(tmp);
+
+	sprint_str(buf, inst_buf, COMPONENT_COLUMN_WIDTH);
+	free(inst_buf);
 }
 
 static void
@@ -1627,8 +1562,8 @@
 /* STIME */
 #define	STIME_COLUMN_WIDTH		8
 #define	FORMAT_TIME			"%k:%M:%S"
-#define	FORMAT_DATE			"%b_%d  "
-#define	FORMAT_YEAR			"%Y    "
+#define	FORMAT_DATE			"%b_%d"
+#define	FORMAT_YEAR			"%Y"
 
 /*
  * sprint_stime() will allocate a new buffer and snprintf the services's
@@ -1643,8 +1578,6 @@
 	time_t then;
 	struct tm *tm;
 	char st_buf[STIME_COLUMN_WIDTH + 1];
-	size_t newsize = (*buf ? strlen(*buf) : 0) + STIME_COLUMN_WIDTH + 2;
-	char *newbuf = safe_malloc(newsize);
 
 	if (wip->pg == NULL) {
 		r = get_restarter_time_prop(wip->inst,
@@ -1659,8 +1592,7 @@
 		 * There's something amiss with our service
 		 * so we'll print a '-' for STIME.
 		 */
-		(void) snprintf(newbuf, newsize, "%s%-*s", *buf ? *buf : "",
-		    STIME_COLUMN_WIDTH + 1, "-");
+		sprint_str(buf, "-", STIME_COLUMN_WIDTH);
 	} else {
 		/* tv should be valid so we'll format it */
 		then = (time_t)tv.tv_sec;
@@ -1681,12 +1613,8 @@
 			(void) strftime(st_buf, sizeof (st_buf),
 			    gettext(FORMAT_YEAR), tm);
 		}
-		(void) snprintf(newbuf, newsize, "%s%-*s ", *buf ? *buf : "",
-		    STIME_COLUMN_WIDTH + 1, st_buf);
+		sprint_str(buf, st_buf, STIME_COLUMN_WIDTH);
 	}
-	if (*buf)
-		free(*buf);
-	*buf = newbuf;
 }
 
 #define	STIME_SORTKEY_WIDTH		(sizeof (uint64_t) + sizeof (uint32_t))
@@ -1731,8 +1659,7 @@
 static void
 sprint_zone(char **buf, scf_walkinfo_t *wip)
 {
-	size_t newsize;
-	char *newbuf, *zonename = g_zonename, b[ZONENAME_MAX];
+	char *zonename = g_zonename, b[ZONENAME_MAX];
 
 	if (zonename == NULL) {
 		zoneid_t zoneid = getzoneid();
@@ -1743,18 +1670,7 @@
 		zonename = b;
 	}
 
-	if (strlen(zonename) > ZONE_COLUMN_WIDTH)
-		newsize = (*buf ? strlen(*buf) : 0) + strlen(zonename) + 2;
-	else
-		newsize = (*buf ? strlen(*buf) : 0) + ZONE_COLUMN_WIDTH + 2;
-
-	newbuf = safe_malloc(newsize);
-	(void) snprintf(newbuf, newsize, "%s%-*s ", *buf ? *buf : "",
-	    ZONE_COLUMN_WIDTH, zonename);
-
-	if (*buf)
-		free(*buf);
-	*buf = newbuf;
+	sprint_str(buf, zonename, ZONE_COLUMN_WIDTH);
 }
 
 static void
@@ -1784,7 +1700,7 @@
 		COMPONENT_COLUMN_WIDTH, sortkey_instance },
 	{ "N", 1,  sprint_n, 1, sortkey_nstate },
 	{ "NSTA", 4, sprint_nsta, 1, sortkey_nstate },
-	{ "NSTATE", MAX_SCF_STATE_STRING_SZ - 1, sprint_nstate,
+	{ "NSTATE", MAX_SCF_STATE_STRING_SZ, sprint_nstate,
 		1, sortkey_nstate },
 	{ "S", 2, sprint_s, 1, sortkey_state },
 	{ "SCOPE", COMPONENT_COLUMN_WIDTH, sprint_scope,
@@ -1793,7 +1709,7 @@
 	{ "SVC", COMPONENT_COLUMN_WIDTH, sprint_service,
 		COMPONENT_COLUMN_WIDTH, sortkey_service },
 	{ "STA", 4, sprint_sta, 1, sortkey_state },
-	{ "STATE", MAX_SCF_STATE_STRING_SZ - 1 + 1, sprint_state,
+	{ "STATE", MAX_SCF_STATE_STRING_SZ, sprint_state,
 		1, sortkey_state },
 	{ "STIME", STIME_COLUMN_WIDTH, sprint_stime,
 		STIME_SORTKEY_WIDTH, sortkey_stime },
@@ -1869,14 +1785,13 @@
 static void
 print_usage(const char *progname, FILE *f, boolean_t do_exit)
 {
-	(void) fprintf(f, gettext(
-	    "Usage: %1$s [-aHpv] [-o col[,col ... ]] [-R restarter] "
-	    "[-sS col] [-Z | -z zone ]\n            [<service> ...]\n"
-	    "       %1$s -d | -D [-Hpv] [-o col[,col ... ]] [-sS col] "
-	    "[-Z | -z zone ]\n            [<service> ...]\n"
-	    "       %1$s [-l | -L] [-Z | -z zone] <service> ...\n"
-	    "       %1$s -x [-v] [-Z | -z zone] [<service> ...]\n"
-	    "       %1$s -?\n"), progname);
+	(void) fprintf(f, gettext("usage:\n"
+	    "%1$s\t[-aHpv?] [-o col[,col]...] [-R FMRI-instance]... "
+	    "[-sS col]...\n\t[-z zone|-Z] [FMRI|pattern]...\n"
+	    "%1$s\t{-d|-D} -Hpv? [-o col[,col]...] [-sS col]... [-z zone|-Z]\n"
+	    "\t[FMRI|pattern]...\n"
+	    "%1$s\t{-l|-L} [-v] [-z zone|-Z] {FMRI|pattern}...\n"
+	    "%1$s\t-x [-v] [-z zone|-Z] [FMRI]...\n"), progname);
 
 	if (do_exit)
 		exit(UU_EXIT_USAGE);
@@ -3454,7 +3369,6 @@
 	void (*errfunc)(const char *, ...);
 
 	int show_all = 0;
-	int show_header = 1;
 	int show_zones = 0;
 
 	const char * const options = "aHpvno:R:s:S:dDlL?xZz:";
@@ -3544,7 +3458,7 @@
 		case 'H':
 			if (opt_mode == 'l' || opt_mode == 'x')
 				argserr(progname);
-			show_header = 0;
+			opt_scripted = 1;
 			break;
 
 		case 'p':
@@ -3923,7 +3837,7 @@
 	if (opt_columns == NULL)
 		return (exit_status);
 
-	if (show_header)
+	if (!opt_scripted)
 		print_header();
 
 	(void) uu_avl_walk(lines, print_line, NULL, 0);
