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