xref: /illumos-gate/usr/src/cmd/coreadm/coreadm.c (revision 7c478bd9)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate  *
4*7c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate  * with the License.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate  * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate  *
14*7c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate  *
20*7c478bd9Sstevel@tonic-gate  * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate  */
22*7c478bd9Sstevel@tonic-gate /*
23*7c478bd9Sstevel@tonic-gate  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
24*7c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
25*7c478bd9Sstevel@tonic-gate  */
26*7c478bd9Sstevel@tonic-gate 
27*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
28*7c478bd9Sstevel@tonic-gate 
29*7c478bd9Sstevel@tonic-gate #include <stdio.h>
30*7c478bd9Sstevel@tonic-gate #include <fcntl.h>
31*7c478bd9Sstevel@tonic-gate #include <ctype.h>
32*7c478bd9Sstevel@tonic-gate #include <string.h>
33*7c478bd9Sstevel@tonic-gate #include <stdlib.h>
34*7c478bd9Sstevel@tonic-gate #include <unistd.h>
35*7c478bd9Sstevel@tonic-gate #include <errno.h>
36*7c478bd9Sstevel@tonic-gate #include <limits.h>
37*7c478bd9Sstevel@tonic-gate #include <libintl.h>
38*7c478bd9Sstevel@tonic-gate #include <locale.h>
39*7c478bd9Sstevel@tonic-gate #include <sys/stat.h>
40*7c478bd9Sstevel@tonic-gate #include <sys/corectl.h>
41*7c478bd9Sstevel@tonic-gate #include <libproc.h>
42*7c478bd9Sstevel@tonic-gate 
43*7c478bd9Sstevel@tonic-gate #define	E_SUCCESS	0		/* Exit status for success */
44*7c478bd9Sstevel@tonic-gate #define	E_ERROR		1		/* Exit status for error */
45*7c478bd9Sstevel@tonic-gate #define	E_USAGE		2		/* Exit status for usage error */
46*7c478bd9Sstevel@tonic-gate 
47*7c478bd9Sstevel@tonic-gate static	const	char	PATH_CONFIG[] = "/etc/coreadm.conf";
48*7c478bd9Sstevel@tonic-gate #define	CF_OWNER	0				/* Uid 0 (root) */
49*7c478bd9Sstevel@tonic-gate #define	CF_GROUP	1				/* Gid 1 (other) */
50*7c478bd9Sstevel@tonic-gate #define	CF_PERM	(S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)	/* Mode 0644 */
51*7c478bd9Sstevel@tonic-gate 
52*7c478bd9Sstevel@tonic-gate static	char		*command;
53*7c478bd9Sstevel@tonic-gate static	char		*glob_pattern;
54*7c478bd9Sstevel@tonic-gate static	size_t		glob_size;
55*7c478bd9Sstevel@tonic-gate static	core_content_t	glob_content = CC_CONTENT_INVALID;
56*7c478bd9Sstevel@tonic-gate static	char		*init_pattern;
57*7c478bd9Sstevel@tonic-gate static	size_t		init_size;
58*7c478bd9Sstevel@tonic-gate static	core_content_t	init_content = CC_CONTENT_INVALID;
59*7c478bd9Sstevel@tonic-gate static	char		*proc_pattern;
60*7c478bd9Sstevel@tonic-gate static	size_t		proc_size;
61*7c478bd9Sstevel@tonic-gate static	core_content_t	proc_content = CC_CONTENT_INVALID;
62*7c478bd9Sstevel@tonic-gate static	int		enable;
63*7c478bd9Sstevel@tonic-gate static	int		disable;
64*7c478bd9Sstevel@tonic-gate 
65*7c478bd9Sstevel@tonic-gate static	int		report_settings(void);
66*7c478bd9Sstevel@tonic-gate static	int		do_processes(int, char **);
67*7c478bd9Sstevel@tonic-gate static	int		do_modify(void);
68*7c478bd9Sstevel@tonic-gate static	int		do_update(void);
69*7c478bd9Sstevel@tonic-gate static	int		write_config(int);
70*7c478bd9Sstevel@tonic-gate 
71*7c478bd9Sstevel@tonic-gate static void
72*7c478bd9Sstevel@tonic-gate usage(void)
73*7c478bd9Sstevel@tonic-gate {
74*7c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr, gettext(
75*7c478bd9Sstevel@tonic-gate "usage:\n"));
76*7c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr, gettext(
77*7c478bd9Sstevel@tonic-gate "    %s [ -g pattern ] [ -i pattern ] [ -G content ] [ -I content ]\n"),
78*7c478bd9Sstevel@tonic-gate 		command);
79*7c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr, gettext(
80*7c478bd9Sstevel@tonic-gate "            [ -e {global | process | global-setid | proc-setid | log} ]\n"));
81*7c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr, gettext(
82*7c478bd9Sstevel@tonic-gate "            [ -d {global | process | global-setid | proc-setid | log} ]\n"));
83*7c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr, gettext(
84*7c478bd9Sstevel@tonic-gate "    %s [ -p pattern ] [ -P content ] [ pid ... ]\n"), command);
85*7c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr, gettext(
86*7c478bd9Sstevel@tonic-gate "    %s -u\n"), command);
87*7c478bd9Sstevel@tonic-gate 	exit(E_USAGE);
88*7c478bd9Sstevel@tonic-gate }
89*7c478bd9Sstevel@tonic-gate 
90*7c478bd9Sstevel@tonic-gate static int
91*7c478bd9Sstevel@tonic-gate perm(void)
92*7c478bd9Sstevel@tonic-gate {
93*7c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr, gettext("%s: insufficient privileges to "
94*7c478bd9Sstevel@tonic-gate 	    "exercise the -[GIgiedu] options\n"), command);
95*7c478bd9Sstevel@tonic-gate 	return (E_USAGE);
96*7c478bd9Sstevel@tonic-gate }
97*7c478bd9Sstevel@tonic-gate 
98*7c478bd9Sstevel@tonic-gate int
99*7c478bd9Sstevel@tonic-gate main(int argc, char **argv)
100*7c478bd9Sstevel@tonic-gate {
101*7c478bd9Sstevel@tonic-gate 	int flag;
102*7c478bd9Sstevel@tonic-gate 	int opt;
103*7c478bd9Sstevel@tonic-gate 	int modify;
104*7c478bd9Sstevel@tonic-gate 	int update = 0;
105*7c478bd9Sstevel@tonic-gate 	int error = 0;
106*7c478bd9Sstevel@tonic-gate 	int npids;
107*7c478bd9Sstevel@tonic-gate 	char **pidlist;
108*7c478bd9Sstevel@tonic-gate 
109*7c478bd9Sstevel@tonic-gate 	char curpid[11];
110*7c478bd9Sstevel@tonic-gate 	char *curpid_ptr = &curpid[0];
111*7c478bd9Sstevel@tonic-gate 
112*7c478bd9Sstevel@tonic-gate 	(void) setlocale(LC_ALL, "");
113*7c478bd9Sstevel@tonic-gate 	(void) textdomain(TEXT_DOMAIN);
114*7c478bd9Sstevel@tonic-gate 
115*7c478bd9Sstevel@tonic-gate 	/* command name (e.g., "coreadm") */
116*7c478bd9Sstevel@tonic-gate 	if ((command = strrchr(argv[0], '/')) != NULL)
117*7c478bd9Sstevel@tonic-gate 		command++;
118*7c478bd9Sstevel@tonic-gate 	else
119*7c478bd9Sstevel@tonic-gate 		command = argv[0];
120*7c478bd9Sstevel@tonic-gate 
121*7c478bd9Sstevel@tonic-gate 	while ((opt = getopt(argc, argv, "g:G:i:I:p:P:e:d:u?")) != EOF) {
122*7c478bd9Sstevel@tonic-gate 		switch (opt) {
123*7c478bd9Sstevel@tonic-gate 		case 'g':
124*7c478bd9Sstevel@tonic-gate 			glob_pattern = optarg;
125*7c478bd9Sstevel@tonic-gate 			glob_size = strlen(glob_pattern) + 1;
126*7c478bd9Sstevel@tonic-gate 			break;
127*7c478bd9Sstevel@tonic-gate 		case 'i':
128*7c478bd9Sstevel@tonic-gate 			init_pattern = optarg;
129*7c478bd9Sstevel@tonic-gate 			init_size = strlen(init_pattern) + 1;
130*7c478bd9Sstevel@tonic-gate 			break;
131*7c478bd9Sstevel@tonic-gate 		case 'p':
132*7c478bd9Sstevel@tonic-gate 			proc_pattern = optarg;
133*7c478bd9Sstevel@tonic-gate 			proc_size = strlen(proc_pattern) + 1;
134*7c478bd9Sstevel@tonic-gate 			break;
135*7c478bd9Sstevel@tonic-gate 		case 'G':
136*7c478bd9Sstevel@tonic-gate 			if (proc_str2content(optarg, &glob_content) != 0) {
137*7c478bd9Sstevel@tonic-gate 				(void) fprintf(stderr, gettext("invalid "
138*7c478bd9Sstevel@tonic-gate 				    "content string '%s'\n"), optarg);
139*7c478bd9Sstevel@tonic-gate 				error = 1;
140*7c478bd9Sstevel@tonic-gate 			}
141*7c478bd9Sstevel@tonic-gate 			break;
142*7c478bd9Sstevel@tonic-gate 		case 'I':
143*7c478bd9Sstevel@tonic-gate 			if (proc_str2content(optarg, &init_content) != 0) {
144*7c478bd9Sstevel@tonic-gate 				(void) fprintf(stderr, gettext("invalid "
145*7c478bd9Sstevel@tonic-gate 				    "content string '%s'\n"), optarg);
146*7c478bd9Sstevel@tonic-gate 				error = 1;
147*7c478bd9Sstevel@tonic-gate 			}
148*7c478bd9Sstevel@tonic-gate 			break;
149*7c478bd9Sstevel@tonic-gate 		case 'P':
150*7c478bd9Sstevel@tonic-gate 			if (proc_str2content(optarg, &proc_content) != 0) {
151*7c478bd9Sstevel@tonic-gate 				(void) fprintf(stderr, gettext("invalid "
152*7c478bd9Sstevel@tonic-gate 				    "content string '%s'\n"), optarg);
153*7c478bd9Sstevel@tonic-gate 				error = 1;
154*7c478bd9Sstevel@tonic-gate 			}
155*7c478bd9Sstevel@tonic-gate 			break;
156*7c478bd9Sstevel@tonic-gate 		case 'e':
157*7c478bd9Sstevel@tonic-gate 		case 'd':
158*7c478bd9Sstevel@tonic-gate 			if (strcmp(optarg, "global") == 0)
159*7c478bd9Sstevel@tonic-gate 				flag = CC_GLOBAL_PATH;
160*7c478bd9Sstevel@tonic-gate 			else if (strcmp(optarg, "process") == 0)
161*7c478bd9Sstevel@tonic-gate 				flag = CC_PROCESS_PATH;
162*7c478bd9Sstevel@tonic-gate 			else if (strcmp(optarg, "global-setid") == 0)
163*7c478bd9Sstevel@tonic-gate 				flag = CC_GLOBAL_SETID;
164*7c478bd9Sstevel@tonic-gate 			else if (strcmp(optarg, "proc-setid") == 0)
165*7c478bd9Sstevel@tonic-gate 				flag = CC_PROCESS_SETID;
166*7c478bd9Sstevel@tonic-gate 			else if (strcmp(optarg, "log") == 0)
167*7c478bd9Sstevel@tonic-gate 				flag = CC_GLOBAL_LOG;
168*7c478bd9Sstevel@tonic-gate 			else {
169*7c478bd9Sstevel@tonic-gate 				flag = 0;
170*7c478bd9Sstevel@tonic-gate 				error = 1;
171*7c478bd9Sstevel@tonic-gate 			}
172*7c478bd9Sstevel@tonic-gate 			if (opt == 'e') {
173*7c478bd9Sstevel@tonic-gate 				enable |= flag;
174*7c478bd9Sstevel@tonic-gate 				disable &= ~flag;
175*7c478bd9Sstevel@tonic-gate 			} else {
176*7c478bd9Sstevel@tonic-gate 				disable |= flag;
177*7c478bd9Sstevel@tonic-gate 				enable &= ~flag;
178*7c478bd9Sstevel@tonic-gate 			}
179*7c478bd9Sstevel@tonic-gate 			break;
180*7c478bd9Sstevel@tonic-gate 		case 'u':
181*7c478bd9Sstevel@tonic-gate 			update = 1;
182*7c478bd9Sstevel@tonic-gate 			break;
183*7c478bd9Sstevel@tonic-gate 		case '?':
184*7c478bd9Sstevel@tonic-gate 		default:
185*7c478bd9Sstevel@tonic-gate 			error = 1;
186*7c478bd9Sstevel@tonic-gate 			break;
187*7c478bd9Sstevel@tonic-gate 		}
188*7c478bd9Sstevel@tonic-gate 	}
189*7c478bd9Sstevel@tonic-gate 
190*7c478bd9Sstevel@tonic-gate 	npids = argc - optind;
191*7c478bd9Sstevel@tonic-gate 	pidlist = argv + optind;
192*7c478bd9Sstevel@tonic-gate 
193*7c478bd9Sstevel@tonic-gate 	if (error)
194*7c478bd9Sstevel@tonic-gate 		usage();
195*7c478bd9Sstevel@tonic-gate 
196*7c478bd9Sstevel@tonic-gate 	/*
197*7c478bd9Sstevel@tonic-gate 	 * If 'modify' is true, we must modify the system settings
198*7c478bd9Sstevel@tonic-gate 	 * and update the configuration file with the new parameters.
199*7c478bd9Sstevel@tonic-gate 	 */
200*7c478bd9Sstevel@tonic-gate 	modify = glob_pattern != NULL || glob_content != CC_CONTENT_INVALID ||
201*7c478bd9Sstevel@tonic-gate 		init_pattern != NULL || init_content != CC_CONTENT_INVALID ||
202*7c478bd9Sstevel@tonic-gate 		(enable | disable) != 0;
203*7c478bd9Sstevel@tonic-gate 
204*7c478bd9Sstevel@tonic-gate 	if (update && (modify || proc_pattern != NULL ||
205*7c478bd9Sstevel@tonic-gate 	    proc_content != CC_CONTENT_INVALID || npids != 0)) {
206*7c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr,
207*7c478bd9Sstevel@tonic-gate 		    gettext(
208*7c478bd9Sstevel@tonic-gate 		    "%s: the -u option must stand alone\n"),
209*7c478bd9Sstevel@tonic-gate 		    command);
210*7c478bd9Sstevel@tonic-gate 		usage();
211*7c478bd9Sstevel@tonic-gate 	}
212*7c478bd9Sstevel@tonic-gate 	if (modify &&
213*7c478bd9Sstevel@tonic-gate 	    (proc_pattern != NULL || proc_content != CC_CONTENT_INVALID)) {
214*7c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr,
215*7c478bd9Sstevel@tonic-gate 		    gettext(
216*7c478bd9Sstevel@tonic-gate 		    "%s: -[GIgied] and -[Pp] options are mutually exclusive\n"),
217*7c478bd9Sstevel@tonic-gate 		    command);
218*7c478bd9Sstevel@tonic-gate 		usage();
219*7c478bd9Sstevel@tonic-gate 	}
220*7c478bd9Sstevel@tonic-gate 	if (modify && npids != 0) {
221*7c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr,
222*7c478bd9Sstevel@tonic-gate 		    gettext(
223*7c478bd9Sstevel@tonic-gate 		    "%s: -[GIgied] options cannot have a process-id list\n"),
224*7c478bd9Sstevel@tonic-gate 		    command);
225*7c478bd9Sstevel@tonic-gate 		usage();
226*7c478bd9Sstevel@tonic-gate 	}
227*7c478bd9Sstevel@tonic-gate 	if ((proc_pattern != NULL || proc_content != CC_CONTENT_INVALID) &&
228*7c478bd9Sstevel@tonic-gate 	    npids == 0) {
229*7c478bd9Sstevel@tonic-gate 		(void) sprintf(curpid, "%u", (uint_t)getppid());
230*7c478bd9Sstevel@tonic-gate 		npids = 1;
231*7c478bd9Sstevel@tonic-gate 		pidlist = &curpid_ptr;
232*7c478bd9Sstevel@tonic-gate 	}
233*7c478bd9Sstevel@tonic-gate 
234*7c478bd9Sstevel@tonic-gate 	if (update)
235*7c478bd9Sstevel@tonic-gate 		return (do_update());
236*7c478bd9Sstevel@tonic-gate 	if (modify)
237*7c478bd9Sstevel@tonic-gate 		return (do_modify());
238*7c478bd9Sstevel@tonic-gate 	if (npids != 0)
239*7c478bd9Sstevel@tonic-gate 		return (do_processes(npids, pidlist));
240*7c478bd9Sstevel@tonic-gate 
241*7c478bd9Sstevel@tonic-gate 	return (report_settings());
242*7c478bd9Sstevel@tonic-gate }
243*7c478bd9Sstevel@tonic-gate 
244*7c478bd9Sstevel@tonic-gate static int
245*7c478bd9Sstevel@tonic-gate report_settings(void)
246*7c478bd9Sstevel@tonic-gate {
247*7c478bd9Sstevel@tonic-gate 	int options;
248*7c478bd9Sstevel@tonic-gate 	char global_path[PATH_MAX];
249*7c478bd9Sstevel@tonic-gate 	char init_path[PATH_MAX];
250*7c478bd9Sstevel@tonic-gate 	core_content_t gcontent, icontent;
251*7c478bd9Sstevel@tonic-gate 	char content_str[80];
252*7c478bd9Sstevel@tonic-gate 
253*7c478bd9Sstevel@tonic-gate 	if ((options = core_get_options()) == -1) {
254*7c478bd9Sstevel@tonic-gate 		perror("core_get_options()");
255*7c478bd9Sstevel@tonic-gate 		return (E_ERROR);
256*7c478bd9Sstevel@tonic-gate 	}
257*7c478bd9Sstevel@tonic-gate 	if (core_get_global_path(global_path, sizeof (global_path)) != 0) {
258*7c478bd9Sstevel@tonic-gate 		perror("core_get_global_path()");
259*7c478bd9Sstevel@tonic-gate 		return (E_ERROR);
260*7c478bd9Sstevel@tonic-gate 	}
261*7c478bd9Sstevel@tonic-gate 	if (core_get_default_path(init_path, sizeof (init_path)) != 0) {
262*7c478bd9Sstevel@tonic-gate 		perror("core_get_default_path()");
263*7c478bd9Sstevel@tonic-gate 		return (E_ERROR);
264*7c478bd9Sstevel@tonic-gate 	}
265*7c478bd9Sstevel@tonic-gate 	if (core_get_global_content(&gcontent) != 0) {
266*7c478bd9Sstevel@tonic-gate 		perror("core_get_global_content()");
267*7c478bd9Sstevel@tonic-gate 		return (E_ERROR);
268*7c478bd9Sstevel@tonic-gate 	}
269*7c478bd9Sstevel@tonic-gate 	if (core_get_default_content(&icontent) != 0) {
270*7c478bd9Sstevel@tonic-gate 		perror("core_get_default_content()");
271*7c478bd9Sstevel@tonic-gate 		return (E_ERROR);
272*7c478bd9Sstevel@tonic-gate 	}
273*7c478bd9Sstevel@tonic-gate 	(void) printf(gettext("     global core file pattern: %s\n"),
274*7c478bd9Sstevel@tonic-gate 	    global_path);
275*7c478bd9Sstevel@tonic-gate 	(void) proc_content2str(gcontent, content_str, sizeof (content_str));
276*7c478bd9Sstevel@tonic-gate 	(void) printf(gettext("     global core file content: %s\n"),
277*7c478bd9Sstevel@tonic-gate 	    content_str);
278*7c478bd9Sstevel@tonic-gate 	(void) printf(gettext("       init core file pattern: %s\n"),
279*7c478bd9Sstevel@tonic-gate 	    init_path);
280*7c478bd9Sstevel@tonic-gate 	(void) proc_content2str(icontent, content_str, sizeof (content_str));
281*7c478bd9Sstevel@tonic-gate 	(void) printf(gettext("       init core file content: %s\n"),
282*7c478bd9Sstevel@tonic-gate 	    content_str);
283*7c478bd9Sstevel@tonic-gate 	(void) printf(gettext("            global core dumps: %s\n"),
284*7c478bd9Sstevel@tonic-gate 	    (options & CC_GLOBAL_PATH)? "enabled" : "disabled");
285*7c478bd9Sstevel@tonic-gate 	(void) printf(gettext("       per-process core dumps: %s\n"),
286*7c478bd9Sstevel@tonic-gate 	    (options & CC_PROCESS_PATH)? "enabled" : "disabled");
287*7c478bd9Sstevel@tonic-gate 	(void) printf(gettext("      global setid core dumps: %s\n"),
288*7c478bd9Sstevel@tonic-gate 	    (options & CC_GLOBAL_SETID)? "enabled" : "disabled");
289*7c478bd9Sstevel@tonic-gate 	(void) printf(gettext(" per-process setid core dumps: %s\n"),
290*7c478bd9Sstevel@tonic-gate 	    (options & CC_PROCESS_SETID)? "enabled" : "disabled");
291*7c478bd9Sstevel@tonic-gate 	(void) printf(gettext("     global core dump logging: %s\n"),
292*7c478bd9Sstevel@tonic-gate 	    (options & CC_GLOBAL_LOG)? "enabled" : "disabled");
293*7c478bd9Sstevel@tonic-gate 	return (E_SUCCESS);
294*7c478bd9Sstevel@tonic-gate }
295*7c478bd9Sstevel@tonic-gate 
296*7c478bd9Sstevel@tonic-gate static int
297*7c478bd9Sstevel@tonic-gate do_processes(int npids, char **pidlist)
298*7c478bd9Sstevel@tonic-gate {
299*7c478bd9Sstevel@tonic-gate 	char process_path[PATH_MAX];
300*7c478bd9Sstevel@tonic-gate 	core_content_t content;
301*7c478bd9Sstevel@tonic-gate 	pid_t pid;
302*7c478bd9Sstevel@tonic-gate 	char *next;
303*7c478bd9Sstevel@tonic-gate 	int rc = E_SUCCESS;
304*7c478bd9Sstevel@tonic-gate 	char content_str[80];
305*7c478bd9Sstevel@tonic-gate 
306*7c478bd9Sstevel@tonic-gate 	if (proc_pattern == NULL && proc_content == CC_CONTENT_INVALID) {
307*7c478bd9Sstevel@tonic-gate 		while (npids-- > 0) {
308*7c478bd9Sstevel@tonic-gate 			pid = strtol(*pidlist, &next, 10);
309*7c478bd9Sstevel@tonic-gate 			if (*next != '\0' || !isdigit(**pidlist)) {
310*7c478bd9Sstevel@tonic-gate 				(void) fprintf(stderr,
311*7c478bd9Sstevel@tonic-gate 				    gettext("%s: invalid process-id\n"),
312*7c478bd9Sstevel@tonic-gate 				    *pidlist);
313*7c478bd9Sstevel@tonic-gate 				rc = E_USAGE;
314*7c478bd9Sstevel@tonic-gate 			} else if (core_get_process_path(process_path,
315*7c478bd9Sstevel@tonic-gate 			    sizeof (process_path), pid) != 0 ||
316*7c478bd9Sstevel@tonic-gate 			    core_get_process_content(&content, pid) != 0) {
317*7c478bd9Sstevel@tonic-gate 				perror(*pidlist);
318*7c478bd9Sstevel@tonic-gate 				rc = E_USAGE;
319*7c478bd9Sstevel@tonic-gate 			} else {
320*7c478bd9Sstevel@tonic-gate 				(void) proc_content2str(content, content_str,
321*7c478bd9Sstevel@tonic-gate 				    sizeof (content_str));
322*7c478bd9Sstevel@tonic-gate 				(void) printf(gettext("%s:\t%s\t%s\n"),
323*7c478bd9Sstevel@tonic-gate 				    *pidlist, process_path, content_str);
324*7c478bd9Sstevel@tonic-gate 			}
325*7c478bd9Sstevel@tonic-gate 			pidlist++;
326*7c478bd9Sstevel@tonic-gate 		}
327*7c478bd9Sstevel@tonic-gate 	} else {
328*7c478bd9Sstevel@tonic-gate 		while (npids-- > 0) {
329*7c478bd9Sstevel@tonic-gate 			pid = strtol(*pidlist, &next, 10);
330*7c478bd9Sstevel@tonic-gate 			if (*next != '\0') {
331*7c478bd9Sstevel@tonic-gate 				(void) fprintf(stderr,
332*7c478bd9Sstevel@tonic-gate 				    gettext("%s: invalid process-id\n"),
333*7c478bd9Sstevel@tonic-gate 				    *pidlist);
334*7c478bd9Sstevel@tonic-gate 				rc = E_USAGE;
335*7c478bd9Sstevel@tonic-gate 			} else {
336*7c478bd9Sstevel@tonic-gate 				if (proc_pattern != NULL &&
337*7c478bd9Sstevel@tonic-gate 				    core_set_process_path(proc_pattern,
338*7c478bd9Sstevel@tonic-gate 				    proc_size, pid) != 0) {
339*7c478bd9Sstevel@tonic-gate 					perror(*pidlist);
340*7c478bd9Sstevel@tonic-gate 					rc = E_USAGE;
341*7c478bd9Sstevel@tonic-gate 				}
342*7c478bd9Sstevel@tonic-gate 
343*7c478bd9Sstevel@tonic-gate 				if (proc_content != CC_CONTENT_INVALID &&
344*7c478bd9Sstevel@tonic-gate 				    core_set_process_content(
345*7c478bd9Sstevel@tonic-gate 				    &proc_content, pid) != 0) {
346*7c478bd9Sstevel@tonic-gate 					perror(*pidlist);
347*7c478bd9Sstevel@tonic-gate 					rc = E_USAGE;
348*7c478bd9Sstevel@tonic-gate 				}
349*7c478bd9Sstevel@tonic-gate 			}
350*7c478bd9Sstevel@tonic-gate 			pidlist++;
351*7c478bd9Sstevel@tonic-gate 		}
352*7c478bd9Sstevel@tonic-gate 	}
353*7c478bd9Sstevel@tonic-gate 
354*7c478bd9Sstevel@tonic-gate 	return (rc);
355*7c478bd9Sstevel@tonic-gate }
356*7c478bd9Sstevel@tonic-gate 
357*7c478bd9Sstevel@tonic-gate static int
358*7c478bd9Sstevel@tonic-gate do_modify(void)
359*7c478bd9Sstevel@tonic-gate {
360*7c478bd9Sstevel@tonic-gate 	int options;
361*7c478bd9Sstevel@tonic-gate 
362*7c478bd9Sstevel@tonic-gate 	if ((options = core_get_options()) == -1) {
363*7c478bd9Sstevel@tonic-gate 		perror("core_get_options()");
364*7c478bd9Sstevel@tonic-gate 		return (E_ERROR);
365*7c478bd9Sstevel@tonic-gate 	}
366*7c478bd9Sstevel@tonic-gate 	options |= enable;
367*7c478bd9Sstevel@tonic-gate 	options &= ~disable;
368*7c478bd9Sstevel@tonic-gate 	if (core_set_options(options) != 0) {
369*7c478bd9Sstevel@tonic-gate 		if (errno == EPERM)
370*7c478bd9Sstevel@tonic-gate 			return (perm());
371*7c478bd9Sstevel@tonic-gate 		perror("core_set_options()");
372*7c478bd9Sstevel@tonic-gate 		return (E_ERROR);
373*7c478bd9Sstevel@tonic-gate 	}
374*7c478bd9Sstevel@tonic-gate 	if (glob_pattern != NULL &&
375*7c478bd9Sstevel@tonic-gate 	    core_set_global_path(glob_pattern, glob_size) != 0) {
376*7c478bd9Sstevel@tonic-gate 		if (errno == EPERM)
377*7c478bd9Sstevel@tonic-gate 			return (perm());
378*7c478bd9Sstevel@tonic-gate 		perror("core_set_global_path()");
379*7c478bd9Sstevel@tonic-gate 		return (E_ERROR);
380*7c478bd9Sstevel@tonic-gate 	}
381*7c478bd9Sstevel@tonic-gate 	if (glob_content != CC_CONTENT_INVALID &&
382*7c478bd9Sstevel@tonic-gate 	    core_set_global_content(&glob_content) != 0) {
383*7c478bd9Sstevel@tonic-gate 		if (errno == EPERM)
384*7c478bd9Sstevel@tonic-gate 			return (perm());
385*7c478bd9Sstevel@tonic-gate 		perror("core_set_global_content()");
386*7c478bd9Sstevel@tonic-gate 		return (E_ERROR);
387*7c478bd9Sstevel@tonic-gate 	}
388*7c478bd9Sstevel@tonic-gate 	if (init_pattern != NULL &&
389*7c478bd9Sstevel@tonic-gate 	    core_set_default_path(init_pattern, init_size) != 0) {
390*7c478bd9Sstevel@tonic-gate 		if (errno == EPERM)
391*7c478bd9Sstevel@tonic-gate 			return (perm());
392*7c478bd9Sstevel@tonic-gate 		perror("core_set_default_path()");
393*7c478bd9Sstevel@tonic-gate 		return (E_ERROR);
394*7c478bd9Sstevel@tonic-gate 	}
395*7c478bd9Sstevel@tonic-gate 	if (init_content != CC_CONTENT_INVALID &&
396*7c478bd9Sstevel@tonic-gate 	    core_set_default_content(&init_content) != 0) {
397*7c478bd9Sstevel@tonic-gate 		if (errno == EPERM)
398*7c478bd9Sstevel@tonic-gate 			return (perm());
399*7c478bd9Sstevel@tonic-gate 		perror("core_set_default_content()");
400*7c478bd9Sstevel@tonic-gate 		return (E_ERROR);
401*7c478bd9Sstevel@tonic-gate 	}
402*7c478bd9Sstevel@tonic-gate 	return (write_config(0));
403*7c478bd9Sstevel@tonic-gate }
404*7c478bd9Sstevel@tonic-gate 
405*7c478bd9Sstevel@tonic-gate /*
406*7c478bd9Sstevel@tonic-gate  * BUFSIZE must be large enough to contain the longest path plus some more.
407*7c478bd9Sstevel@tonic-gate  */
408*7c478bd9Sstevel@tonic-gate #define	BUFSIZE	(PATH_MAX + 80)
409*7c478bd9Sstevel@tonic-gate 
410*7c478bd9Sstevel@tonic-gate static int
411*7c478bd9Sstevel@tonic-gate yes(char *name, char *value, int line)
412*7c478bd9Sstevel@tonic-gate {
413*7c478bd9Sstevel@tonic-gate 	if (strcmp(value, "yes") == 0)
414*7c478bd9Sstevel@tonic-gate 		return (1);
415*7c478bd9Sstevel@tonic-gate 	if (strcmp(value, "no") == 0)
416*7c478bd9Sstevel@tonic-gate 		return (0);
417*7c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr,
418*7c478bd9Sstevel@tonic-gate 		gettext(
419*7c478bd9Sstevel@tonic-gate 		"\"%s\", line %d: warning: value must be yes or no: %s=%s\n"),
420*7c478bd9Sstevel@tonic-gate 		PATH_CONFIG, line, name, value);
421*7c478bd9Sstevel@tonic-gate 	return (0);
422*7c478bd9Sstevel@tonic-gate }
423*7c478bd9Sstevel@tonic-gate 
424*7c478bd9Sstevel@tonic-gate static int
425*7c478bd9Sstevel@tonic-gate do_update(void)
426*7c478bd9Sstevel@tonic-gate {
427*7c478bd9Sstevel@tonic-gate 	FILE *fp;
428*7c478bd9Sstevel@tonic-gate 	int line;
429*7c478bd9Sstevel@tonic-gate 	int options;
430*7c478bd9Sstevel@tonic-gate 	char gpattern[PATH_MAX];
431*7c478bd9Sstevel@tonic-gate 	char ipattern[PATH_MAX];
432*7c478bd9Sstevel@tonic-gate 	core_content_t gcontent, icontent;
433*7c478bd9Sstevel@tonic-gate 	char buf[BUFSIZE];
434*7c478bd9Sstevel@tonic-gate 	char name[BUFSIZE], value[BUFSIZE];
435*7c478bd9Sstevel@tonic-gate 	int n;
436*7c478bd9Sstevel@tonic-gate 	int len;
437*7c478bd9Sstevel@tonic-gate 
438*7c478bd9Sstevel@tonic-gate 	/* defaults */
439*7c478bd9Sstevel@tonic-gate 	options = CC_PROCESS_PATH;
440*7c478bd9Sstevel@tonic-gate 	gpattern[0] = '\0';
441*7c478bd9Sstevel@tonic-gate 	(void) strcpy(ipattern, "core");
442*7c478bd9Sstevel@tonic-gate 	gcontent = icontent = CC_CONTENT_DEFAULT;
443*7c478bd9Sstevel@tonic-gate 
444*7c478bd9Sstevel@tonic-gate 	if ((fp = fopen(PATH_CONFIG, "r")) == NULL) {
445*7c478bd9Sstevel@tonic-gate 		/*
446*7c478bd9Sstevel@tonic-gate 		 * No config file, just accept the current settings.
447*7c478bd9Sstevel@tonic-gate 		 */
448*7c478bd9Sstevel@tonic-gate 		return (write_config(1));
449*7c478bd9Sstevel@tonic-gate 	}
450*7c478bd9Sstevel@tonic-gate 
451*7c478bd9Sstevel@tonic-gate 	for (line = 1; fgets(buf, sizeof (buf), fp) != NULL; line++) {
452*7c478bd9Sstevel@tonic-gate 		/*
453*7c478bd9Sstevel@tonic-gate 		 * Skip comment lines and empty lines.
454*7c478bd9Sstevel@tonic-gate 		 */
455*7c478bd9Sstevel@tonic-gate 		if (buf[0] == '#' || buf[0] == '\n')
456*7c478bd9Sstevel@tonic-gate 			continue;
457*7c478bd9Sstevel@tonic-gate 		/*
458*7c478bd9Sstevel@tonic-gate 		 * Look for "name=value", with optional whitespace on either
459*7c478bd9Sstevel@tonic-gate 		 * side, terminated by a newline, and consuming the whole line.
460*7c478bd9Sstevel@tonic-gate 		 */
461*7c478bd9Sstevel@tonic-gate 		/* LINTED - unbounded string specifier */
462*7c478bd9Sstevel@tonic-gate 		n = sscanf(buf, " %[^=]=%s \n%n", name, value, &len);
463*7c478bd9Sstevel@tonic-gate 		if (n >= 1 && name[0] != '\0' &&
464*7c478bd9Sstevel@tonic-gate 		    (n == 1 || len == strlen(buf))) {
465*7c478bd9Sstevel@tonic-gate 			if (n == 1)
466*7c478bd9Sstevel@tonic-gate 				value[0] = '\0';
467*7c478bd9Sstevel@tonic-gate 			if (strcmp(name, "COREADM_GLOB_PATTERN") == 0) {
468*7c478bd9Sstevel@tonic-gate 				(void) strcpy(gpattern, value);
469*7c478bd9Sstevel@tonic-gate 				continue;
470*7c478bd9Sstevel@tonic-gate 			}
471*7c478bd9Sstevel@tonic-gate 			if (strcmp(name, "COREADM_GLOB_CONTENT") == 0) {
472*7c478bd9Sstevel@tonic-gate 				(void) proc_str2content(value, &gcontent);
473*7c478bd9Sstevel@tonic-gate 				continue;
474*7c478bd9Sstevel@tonic-gate 			}
475*7c478bd9Sstevel@tonic-gate 			if (strcmp(name, "COREADM_INIT_PATTERN") == 0) {
476*7c478bd9Sstevel@tonic-gate 				(void) strcpy(ipattern, value);
477*7c478bd9Sstevel@tonic-gate 				continue;
478*7c478bd9Sstevel@tonic-gate 			}
479*7c478bd9Sstevel@tonic-gate 			if (strcmp(name, "COREADM_INIT_CONTENT") == 0) {
480*7c478bd9Sstevel@tonic-gate 				(void) proc_str2content(value, &icontent);
481*7c478bd9Sstevel@tonic-gate 				continue;
482*7c478bd9Sstevel@tonic-gate 			}
483*7c478bd9Sstevel@tonic-gate 			if (strcmp(name, "COREADM_GLOB_ENABLED") == 0) {
484*7c478bd9Sstevel@tonic-gate 				if (yes(name, value, line))
485*7c478bd9Sstevel@tonic-gate 					options |= CC_GLOBAL_PATH;
486*7c478bd9Sstevel@tonic-gate 				continue;
487*7c478bd9Sstevel@tonic-gate 			}
488*7c478bd9Sstevel@tonic-gate 			if (strcmp(name, "COREADM_PROC_ENABLED") == 0) {
489*7c478bd9Sstevel@tonic-gate 				if (yes(name, value, line))
490*7c478bd9Sstevel@tonic-gate 					options |= CC_PROCESS_PATH;
491*7c478bd9Sstevel@tonic-gate 				else
492*7c478bd9Sstevel@tonic-gate 					options &= ~CC_PROCESS_PATH;
493*7c478bd9Sstevel@tonic-gate 				continue;
494*7c478bd9Sstevel@tonic-gate 			}
495*7c478bd9Sstevel@tonic-gate 			if (strcmp(name, "COREADM_GLOB_SETID_ENABLED") == 0) {
496*7c478bd9Sstevel@tonic-gate 				if (yes(name, value, line))
497*7c478bd9Sstevel@tonic-gate 					options |= CC_GLOBAL_SETID;
498*7c478bd9Sstevel@tonic-gate 				continue;
499*7c478bd9Sstevel@tonic-gate 			}
500*7c478bd9Sstevel@tonic-gate 			if (strcmp(name, "COREADM_PROC_SETID_ENABLED") == 0) {
501*7c478bd9Sstevel@tonic-gate 				if (yes(name, value, line))
502*7c478bd9Sstevel@tonic-gate 					options |= CC_PROCESS_SETID;
503*7c478bd9Sstevel@tonic-gate 				continue;
504*7c478bd9Sstevel@tonic-gate 			}
505*7c478bd9Sstevel@tonic-gate 			if (strcmp(name, "COREADM_GLOB_LOG_ENABLED") == 0) {
506*7c478bd9Sstevel@tonic-gate 				if (yes(name, value, line))
507*7c478bd9Sstevel@tonic-gate 					options |= CC_GLOBAL_LOG;
508*7c478bd9Sstevel@tonic-gate 				continue;
509*7c478bd9Sstevel@tonic-gate 			}
510*7c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr,
511*7c478bd9Sstevel@tonic-gate 				gettext(
512*7c478bd9Sstevel@tonic-gate 			"\"%s\", line %d: warning: invalid token: %s\n"),
513*7c478bd9Sstevel@tonic-gate 				PATH_CONFIG, line, name);
514*7c478bd9Sstevel@tonic-gate 		} else {
515*7c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr,
516*7c478bd9Sstevel@tonic-gate 				gettext("\"%s\", line %d: syntax error\n"),
517*7c478bd9Sstevel@tonic-gate 				PATH_CONFIG, line);
518*7c478bd9Sstevel@tonic-gate 		}
519*7c478bd9Sstevel@tonic-gate 	}
520*7c478bd9Sstevel@tonic-gate 	(void) fclose(fp);
521*7c478bd9Sstevel@tonic-gate 	if (core_set_options(options) != 0) {
522*7c478bd9Sstevel@tonic-gate 		if (errno == EPERM)
523*7c478bd9Sstevel@tonic-gate 			return (perm());
524*7c478bd9Sstevel@tonic-gate 		perror("core_set_options()");
525*7c478bd9Sstevel@tonic-gate 		return (E_ERROR);
526*7c478bd9Sstevel@tonic-gate 	}
527*7c478bd9Sstevel@tonic-gate 	if (core_set_global_path(gpattern, strlen(gpattern) + 1) != 0) {
528*7c478bd9Sstevel@tonic-gate 		if (errno == EPERM)
529*7c478bd9Sstevel@tonic-gate 			return (perm());
530*7c478bd9Sstevel@tonic-gate 		perror("core_set_global_path()");
531*7c478bd9Sstevel@tonic-gate 		return (E_ERROR);
532*7c478bd9Sstevel@tonic-gate 	}
533*7c478bd9Sstevel@tonic-gate 	if (core_set_default_path(ipattern, strlen(ipattern) + 1) != 0) {
534*7c478bd9Sstevel@tonic-gate 		if (errno == EPERM)
535*7c478bd9Sstevel@tonic-gate 			return (perm());
536*7c478bd9Sstevel@tonic-gate 		perror("core_set_default_path()");
537*7c478bd9Sstevel@tonic-gate 		return (E_ERROR);
538*7c478bd9Sstevel@tonic-gate 	}
539*7c478bd9Sstevel@tonic-gate 	if (core_set_global_content(&gcontent) != 0) {
540*7c478bd9Sstevel@tonic-gate 		if (errno == EPERM)
541*7c478bd9Sstevel@tonic-gate 			return (perm());
542*7c478bd9Sstevel@tonic-gate 		perror("core_set_global_content()");
543*7c478bd9Sstevel@tonic-gate 		return (E_ERROR);
544*7c478bd9Sstevel@tonic-gate 	}
545*7c478bd9Sstevel@tonic-gate 	if (core_set_default_content(&icontent) != 0) {
546*7c478bd9Sstevel@tonic-gate 		if (errno == EPERM)
547*7c478bd9Sstevel@tonic-gate 			return (perm());
548*7c478bd9Sstevel@tonic-gate 		perror("core_set_default_content()");
549*7c478bd9Sstevel@tonic-gate 		return (E_ERROR);
550*7c478bd9Sstevel@tonic-gate 	}
551*7c478bd9Sstevel@tonic-gate 	return (write_config(1));
552*7c478bd9Sstevel@tonic-gate }
553*7c478bd9Sstevel@tonic-gate 
554*7c478bd9Sstevel@tonic-gate static int
555*7c478bd9Sstevel@tonic-gate write_config(int justtry)
556*7c478bd9Sstevel@tonic-gate {
557*7c478bd9Sstevel@tonic-gate 	int fd;
558*7c478bd9Sstevel@tonic-gate 	FILE *fp;
559*7c478bd9Sstevel@tonic-gate 	int options;
560*7c478bd9Sstevel@tonic-gate 	char global_path[PATH_MAX];
561*7c478bd9Sstevel@tonic-gate 	char init_path[PATH_MAX];
562*7c478bd9Sstevel@tonic-gate 	core_content_t gcontent, icontent;
563*7c478bd9Sstevel@tonic-gate 	char content_str[PRCONTENTBUFSZ];
564*7c478bd9Sstevel@tonic-gate 
565*7c478bd9Sstevel@tonic-gate 	if ((fd = open(PATH_CONFIG, O_WRONLY | O_CREAT | O_TRUNC,
566*7c478bd9Sstevel@tonic-gate 	    CF_PERM)) == -1) {
567*7c478bd9Sstevel@tonic-gate 		/*
568*7c478bd9Sstevel@tonic-gate 		 * If we're updating the kernel settings from the contents
569*7c478bd9Sstevel@tonic-gate 		 * of the config file, it's not essential that we rewrite
570*7c478bd9Sstevel@tonic-gate 		 * that file.
571*7c478bd9Sstevel@tonic-gate 		 */
572*7c478bd9Sstevel@tonic-gate 		if (justtry)
573*7c478bd9Sstevel@tonic-gate 			return (E_SUCCESS);
574*7c478bd9Sstevel@tonic-gate 
575*7c478bd9Sstevel@tonic-gate 		if (errno == EACCES) {
576*7c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr, gettext("%s: insufficient "
577*7c478bd9Sstevel@tonic-gate 			    "privileges to update %s\n"), command, PATH_CONFIG);
578*7c478bd9Sstevel@tonic-gate 			return (E_SUCCESS);
579*7c478bd9Sstevel@tonic-gate 		}
580*7c478bd9Sstevel@tonic-gate 
581*7c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, gettext("failed to open %s: %s\n"),
582*7c478bd9Sstevel@tonic-gate 		    PATH_CONFIG, strerror(errno));
583*7c478bd9Sstevel@tonic-gate 		return (E_ERROR);
584*7c478bd9Sstevel@tonic-gate 	}
585*7c478bd9Sstevel@tonic-gate 	if ((options = core_get_options()) == -1) {
586*7c478bd9Sstevel@tonic-gate 		perror("core_get_options()");
587*7c478bd9Sstevel@tonic-gate 		goto err;
588*7c478bd9Sstevel@tonic-gate 	}
589*7c478bd9Sstevel@tonic-gate 	if (core_get_global_path(global_path, sizeof (global_path)) != 0) {
590*7c478bd9Sstevel@tonic-gate 		perror("core_get_global_path()");
591*7c478bd9Sstevel@tonic-gate 		goto err;
592*7c478bd9Sstevel@tonic-gate 	}
593*7c478bd9Sstevel@tonic-gate 	if (core_get_default_path(init_path, sizeof (init_path)) != 0) {
594*7c478bd9Sstevel@tonic-gate 		perror("core_get_default_path()");
595*7c478bd9Sstevel@tonic-gate 		goto err;
596*7c478bd9Sstevel@tonic-gate 	}
597*7c478bd9Sstevel@tonic-gate 	if (core_get_global_content(&gcontent) != 0) {
598*7c478bd9Sstevel@tonic-gate 		perror("core_get_global_content()");
599*7c478bd9Sstevel@tonic-gate 		goto err;
600*7c478bd9Sstevel@tonic-gate 	}
601*7c478bd9Sstevel@tonic-gate 	if (core_get_default_content(&icontent) != 0) {
602*7c478bd9Sstevel@tonic-gate 		perror("core_get_default_content()");
603*7c478bd9Sstevel@tonic-gate 		goto err;
604*7c478bd9Sstevel@tonic-gate 	}
605*7c478bd9Sstevel@tonic-gate 	if ((fp = fdopen(fd, "w")) == NULL) {
606*7c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr,
607*7c478bd9Sstevel@tonic-gate 		    gettext("failed to open stream for %s: %s\n"),
608*7c478bd9Sstevel@tonic-gate 		    PATH_CONFIG, strerror(errno));
609*7c478bd9Sstevel@tonic-gate 		goto err;
610*7c478bd9Sstevel@tonic-gate 	}
611*7c478bd9Sstevel@tonic-gate 	(void) fputs(
612*7c478bd9Sstevel@tonic-gate 		"#\n"
613*7c478bd9Sstevel@tonic-gate 		"# coreadm.conf\n"
614*7c478bd9Sstevel@tonic-gate 		"#\n"
615*7c478bd9Sstevel@tonic-gate 		"# Parameters for system core file configuration.\n"
616*7c478bd9Sstevel@tonic-gate 		"# Do NOT edit this file by hand -- use coreadm(1) instead.\n"
617*7c478bd9Sstevel@tonic-gate 		"#\n",
618*7c478bd9Sstevel@tonic-gate 		fp);
619*7c478bd9Sstevel@tonic-gate 
620*7c478bd9Sstevel@tonic-gate 	(void) fprintf(fp, "COREADM_GLOB_PATTERN=%s\n", global_path);
621*7c478bd9Sstevel@tonic-gate 	(void) proc_content2str(gcontent, content_str, sizeof (content_str));
622*7c478bd9Sstevel@tonic-gate 	(void) fprintf(fp, "COREADM_GLOB_CONTENT=%s\n", content_str);
623*7c478bd9Sstevel@tonic-gate 	(void) fprintf(fp, "COREADM_INIT_PATTERN=%s\n", init_path);
624*7c478bd9Sstevel@tonic-gate 	(void) proc_content2str(icontent, content_str, sizeof (content_str));
625*7c478bd9Sstevel@tonic-gate 	(void) fprintf(fp, "COREADM_INIT_CONTENT=%s\n", content_str);
626*7c478bd9Sstevel@tonic-gate 
627*7c478bd9Sstevel@tonic-gate 	(void) fprintf(fp, "COREADM_GLOB_ENABLED=%s\n",
628*7c478bd9Sstevel@tonic-gate 		(options & CC_GLOBAL_PATH)? "yes" : "no");
629*7c478bd9Sstevel@tonic-gate 	(void) fprintf(fp, "COREADM_PROC_ENABLED=%s\n",
630*7c478bd9Sstevel@tonic-gate 		(options & CC_PROCESS_PATH)? "yes" : "no");
631*7c478bd9Sstevel@tonic-gate 	(void) fprintf(fp, "COREADM_GLOB_SETID_ENABLED=%s\n",
632*7c478bd9Sstevel@tonic-gate 		(options & CC_GLOBAL_SETID)? "yes" : "no");
633*7c478bd9Sstevel@tonic-gate 	(void) fprintf(fp, "COREADM_PROC_SETID_ENABLED=%s\n",
634*7c478bd9Sstevel@tonic-gate 		(options & CC_PROCESS_SETID)? "yes" : "no");
635*7c478bd9Sstevel@tonic-gate 	(void) fprintf(fp, "COREADM_GLOB_LOG_ENABLED=%s\n",
636*7c478bd9Sstevel@tonic-gate 		(options & CC_GLOBAL_LOG)? "yes" : "no");
637*7c478bd9Sstevel@tonic-gate 
638*7c478bd9Sstevel@tonic-gate 	(void) fflush(fp);
639*7c478bd9Sstevel@tonic-gate 	(void) fsync(fd);
640*7c478bd9Sstevel@tonic-gate 	(void) fchmod(fd, CF_PERM);
641*7c478bd9Sstevel@tonic-gate 	(void) fchown(fd, CF_OWNER, CF_GROUP);
642*7c478bd9Sstevel@tonic-gate 	(void) fclose(fp);
643*7c478bd9Sstevel@tonic-gate 
644*7c478bd9Sstevel@tonic-gate 	return (0);
645*7c478bd9Sstevel@tonic-gate 
646*7c478bd9Sstevel@tonic-gate err:
647*7c478bd9Sstevel@tonic-gate 	(void) close(fd);
648*7c478bd9Sstevel@tonic-gate 	return (E_ERROR);
649*7c478bd9Sstevel@tonic-gate }
650