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 2005 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 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 28*7c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 29*7c478bd9Sstevel@tonic-gate 30*7c478bd9Sstevel@tonic-gate 31*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 32*7c478bd9Sstevel@tonic-gate 33*7c478bd9Sstevel@tonic-gate /* 34*7c478bd9Sstevel@tonic-gate * error/logging/cleanup functions for ttymon. 35*7c478bd9Sstevel@tonic-gate */ 36*7c478bd9Sstevel@tonic-gate 37*7c478bd9Sstevel@tonic-gate #include <unistd.h> 38*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 39*7c478bd9Sstevel@tonic-gate #include <stdio.h> 40*7c478bd9Sstevel@tonic-gate #include <fcntl.h> 41*7c478bd9Sstevel@tonic-gate #include <string.h> 42*7c478bd9Sstevel@tonic-gate #include <errno.h> 43*7c478bd9Sstevel@tonic-gate #include <stdarg.h> 44*7c478bd9Sstevel@tonic-gate #include <time.h> 45*7c478bd9Sstevel@tonic-gate #include <sys/types.h> 46*7c478bd9Sstevel@tonic-gate #include <sys/stat.h> 47*7c478bd9Sstevel@tonic-gate #include <sys/param.h> 48*7c478bd9Sstevel@tonic-gate #include <signal.h> 49*7c478bd9Sstevel@tonic-gate #include <syslog.h> 50*7c478bd9Sstevel@tonic-gate #include "ttymon.h" 51*7c478bd9Sstevel@tonic-gate #include "tmstruct.h" 52*7c478bd9Sstevel@tonic-gate #include "tmextern.h" 53*7c478bd9Sstevel@tonic-gate 54*7c478bd9Sstevel@tonic-gate # ifdef DEBUG 55*7c478bd9Sstevel@tonic-gate extern FILE *Debugfp; 56*7c478bd9Sstevel@tonic-gate # endif 57*7c478bd9Sstevel@tonic-gate 58*7c478bd9Sstevel@tonic-gate const char *appname = "ttymon"; 59*7c478bd9Sstevel@tonic-gate 60*7c478bd9Sstevel@tonic-gate void 61*7c478bd9Sstevel@tonic-gate openttymonlog(void) 62*7c478bd9Sstevel@tonic-gate { 63*7c478bd9Sstevel@tonic-gate int fd, ret; 64*7c478bd9Sstevel@tonic-gate char logfile[MAXPATHLEN]; 65*7c478bd9Sstevel@tonic-gate extern char *Tag; 66*7c478bd9Sstevel@tonic-gate 67*7c478bd9Sstevel@tonic-gate /* the log file resides in /var/saf/pmtag/ */ 68*7c478bd9Sstevel@tonic-gate (void) snprintf(logfile, sizeof (logfile), "%s%s/%s", LOGDIR, Tag, 69*7c478bd9Sstevel@tonic-gate LOGFILE); 70*7c478bd9Sstevel@tonic-gate 71*7c478bd9Sstevel@tonic-gate Logfp = NULL; 72*7c478bd9Sstevel@tonic-gate (void)close(0); 73*7c478bd9Sstevel@tonic-gate if ((fd = open(logfile, O_WRONLY|O_CREAT|O_APPEND,0444)) != -1) 74*7c478bd9Sstevel@tonic-gate if ((ret = fcntl(fd, F_DUPFD, 3)) == 3) { 75*7c478bd9Sstevel@tonic-gate /* set close-on-exec flag */ 76*7c478bd9Sstevel@tonic-gate if (fcntl(ret, F_SETFD, FD_CLOEXEC) == 0) { 77*7c478bd9Sstevel@tonic-gate Logfp = fdopen(ret, "a+"); 78*7c478bd9Sstevel@tonic-gate } 79*7c478bd9Sstevel@tonic-gate } 80*7c478bd9Sstevel@tonic-gate if (!Logfp) { 81*7c478bd9Sstevel@tonic-gate cons_printf("ttymon cannot create log file \"%s\": %s\n", 82*7c478bd9Sstevel@tonic-gate logfile, strerror(errno)); 83*7c478bd9Sstevel@tonic-gate exit(1); 84*7c478bd9Sstevel@tonic-gate } 85*7c478bd9Sstevel@tonic-gate log(" "); 86*7c478bd9Sstevel@tonic-gate log("********** ttymon starting **********"); 87*7c478bd9Sstevel@tonic-gate 88*7c478bd9Sstevel@tonic-gate #ifdef DEBUG 89*7c478bd9Sstevel@tonic-gate log("fd(log)\t = %d", fileno(Logfp)); 90*7c478bd9Sstevel@tonic-gate #endif 91*7c478bd9Sstevel@tonic-gate } 92*7c478bd9Sstevel@tonic-gate 93*7c478bd9Sstevel@tonic-gate static void 94*7c478bd9Sstevel@tonic-gate roll_log() 95*7c478bd9Sstevel@tonic-gate { 96*7c478bd9Sstevel@tonic-gate char logf[MAXPATHLEN]; 97*7c478bd9Sstevel@tonic-gate char ologf[MAXPATHLEN]; 98*7c478bd9Sstevel@tonic-gate char tlogf[MAXPATHLEN]; 99*7c478bd9Sstevel@tonic-gate FILE *nlogfp; 100*7c478bd9Sstevel@tonic-gate struct stat buf; 101*7c478bd9Sstevel@tonic-gate 102*7c478bd9Sstevel@tonic-gate (void) fprintf(Logfp, "Restarting log file\n"); 103*7c478bd9Sstevel@tonic-gate (void) snprintf(logf, sizeof (logf), "%s%s/%s", LOGDIR, Tag, LOGFILE); 104*7c478bd9Sstevel@tonic-gate 105*7c478bd9Sstevel@tonic-gate (void) snprintf(ologf, sizeof (ologf), "%s%s/%s", LOGDIR, Tag, 106*7c478bd9Sstevel@tonic-gate OLOGFILE); 107*7c478bd9Sstevel@tonic-gate 108*7c478bd9Sstevel@tonic-gate (void) snprintf(tlogf, sizeof (tlogf), "%s%s/%s", LOGDIR, Tag, 109*7c478bd9Sstevel@tonic-gate TLOGFILE); 110*7c478bd9Sstevel@tonic-gate 111*7c478bd9Sstevel@tonic-gate if (!stat(ologf, &buf) && rename(ologf, tlogf)) { 112*7c478bd9Sstevel@tonic-gate (void) fprintf(Logfp, "rename old to tmp file failed\n"); 113*7c478bd9Sstevel@tonic-gate } else if (!stat(logf, &buf) && rename(logf, ologf)) { 114*7c478bd9Sstevel@tonic-gate (void) fprintf(Logfp, "rename log to old file failed\n"); 115*7c478bd9Sstevel@tonic-gate /* Restore old log file */ 116*7c478bd9Sstevel@tonic-gate if (!stat(tlogf, &buf) && rename(tlogf, ologf)) 117*7c478bd9Sstevel@tonic-gate (void) fprintf(Logfp, 118*7c478bd9Sstevel@tonic-gate "rename tmp to old file failed\n"); 119*7c478bd9Sstevel@tonic-gate } else if (nlogfp = fopen(logf, "w")) { 120*7c478bd9Sstevel@tonic-gate (void) fclose(Logfp); 121*7c478bd9Sstevel@tonic-gate Logfp = nlogfp; 122*7c478bd9Sstevel@tonic-gate /* reset close-on-exec */ 123*7c478bd9Sstevel@tonic-gate (void) fcntl(fileno(Logfp), F_SETFD, 1); 124*7c478bd9Sstevel@tonic-gate } else { 125*7c478bd9Sstevel@tonic-gate (void) fprintf(Logfp, "log file open failed\n"); 126*7c478bd9Sstevel@tonic-gate /* Restore current and old log file */ 127*7c478bd9Sstevel@tonic-gate if (!stat(ologf, &buf) && rename(ologf, logf)) 128*7c478bd9Sstevel@tonic-gate (void) fprintf(Logfp, 129*7c478bd9Sstevel@tonic-gate "rename old to log file failed\n"); 130*7c478bd9Sstevel@tonic-gate else if (!stat(tlogf, &buf) && rename(tlogf, ologf)) 131*7c478bd9Sstevel@tonic-gate (void) fprintf(Logfp, 132*7c478bd9Sstevel@tonic-gate "rename tmp to old file failed\n"); 133*7c478bd9Sstevel@tonic-gate } 134*7c478bd9Sstevel@tonic-gate 135*7c478bd9Sstevel@tonic-gate (void) unlink(tlogf); /* remove any stale tmp logfile */ 136*7c478bd9Sstevel@tonic-gate } 137*7c478bd9Sstevel@tonic-gate 138*7c478bd9Sstevel@tonic-gate 139*7c478bd9Sstevel@tonic-gate /* 140*7c478bd9Sstevel@tonic-gate * vlog(msg) - common message routine. 141*7c478bd9Sstevel@tonic-gate * - if Logfp is NULL, write message to stderr or CONSOLE 142*7c478bd9Sstevel@tonic-gate */ 143*7c478bd9Sstevel@tonic-gate static void 144*7c478bd9Sstevel@tonic-gate vlog(const char *fmt, va_list ap) 145*7c478bd9Sstevel@tonic-gate { 146*7c478bd9Sstevel@tonic-gate char *timestamp; /* current time in readable form */ 147*7c478bd9Sstevel@tonic-gate time_t clock; /* current time in seconds */ 148*7c478bd9Sstevel@tonic-gate int fd; 149*7c478bd9Sstevel@tonic-gate struct stat buf; 150*7c478bd9Sstevel@tonic-gate 151*7c478bd9Sstevel@tonic-gate if (Logfp) { 152*7c478bd9Sstevel@tonic-gate if ((fstat(fileno(Logfp), &buf) != -1) && 153*7c478bd9Sstevel@tonic-gate (buf.st_size >= Logmaxsz) && !Splflag) { 154*7c478bd9Sstevel@tonic-gate Splflag = 1; 155*7c478bd9Sstevel@tonic-gate roll_log(); 156*7c478bd9Sstevel@tonic-gate Splflag = 0; 157*7c478bd9Sstevel@tonic-gate } 158*7c478bd9Sstevel@tonic-gate 159*7c478bd9Sstevel@tonic-gate (void) time(&clock); 160*7c478bd9Sstevel@tonic-gate timestamp = ctime(&clock); 161*7c478bd9Sstevel@tonic-gate *(strchr(timestamp, '\n')) = '\0'; 162*7c478bd9Sstevel@tonic-gate (void) fprintf(Logfp, "%s; %ld; ", timestamp, getpid()); 163*7c478bd9Sstevel@tonic-gate (void) vfprintf(Logfp, fmt, ap); 164*7c478bd9Sstevel@tonic-gate if (fmt[strlen(fmt) - 1] != '\n') 165*7c478bd9Sstevel@tonic-gate (void) fputc('\n', Logfp); 166*7c478bd9Sstevel@tonic-gate (void) fflush(Logfp); 167*7c478bd9Sstevel@tonic-gate } else if (isatty(STDERR_FILENO)) { 168*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "%s: ", appname); 169*7c478bd9Sstevel@tonic-gate (void) vfprintf(stderr, fmt, ap); 170*7c478bd9Sstevel@tonic-gate if (fmt[strlen(fmt) - 1] != '\n') 171*7c478bd9Sstevel@tonic-gate (void) fputc('\n', stderr); 172*7c478bd9Sstevel@tonic-gate (void) fflush(stderr); 173*7c478bd9Sstevel@tonic-gate } else if ((fd = open(CONSOLE, O_WRONLY|O_NOCTTY)) != -1) { 174*7c478bd9Sstevel@tonic-gate FILE *f = fdopen(fd, "w"); 175*7c478bd9Sstevel@tonic-gate 176*7c478bd9Sstevel@tonic-gate (void) fprintf(f, "%s: ", appname); 177*7c478bd9Sstevel@tonic-gate (void) vfprintf(f, fmt, ap); 178*7c478bd9Sstevel@tonic-gate if (fmt[strlen(fmt) - 1] != '\n') 179*7c478bd9Sstevel@tonic-gate (void) fputc('\n', f); 180*7c478bd9Sstevel@tonic-gate (void) fclose(f); 181*7c478bd9Sstevel@tonic-gate } else { 182*7c478bd9Sstevel@tonic-gate vsyslog(LOG_CRIT, fmt, ap); 183*7c478bd9Sstevel@tonic-gate } 184*7c478bd9Sstevel@tonic-gate } 185*7c478bd9Sstevel@tonic-gate 186*7c478bd9Sstevel@tonic-gate /* 187*7c478bd9Sstevel@tonic-gate * log(fmt, ...) - put a message into the log file 188*7c478bd9Sstevel@tonic-gate * - if Logfp is NULL, write message to stderr or CONSOLE 189*7c478bd9Sstevel@tonic-gate */ 190*7c478bd9Sstevel@tonic-gate /*PRINTFLIKE1*/ 191*7c478bd9Sstevel@tonic-gate void 192*7c478bd9Sstevel@tonic-gate log(const char *fmt, ...) 193*7c478bd9Sstevel@tonic-gate { 194*7c478bd9Sstevel@tonic-gate va_list ap; 195*7c478bd9Sstevel@tonic-gate va_start(ap, fmt); 196*7c478bd9Sstevel@tonic-gate vlog(fmt, ap); 197*7c478bd9Sstevel@tonic-gate va_end(ap); 198*7c478bd9Sstevel@tonic-gate } 199*7c478bd9Sstevel@tonic-gate 200*7c478bd9Sstevel@tonic-gate 201*7c478bd9Sstevel@tonic-gate /* 202*7c478bd9Sstevel@tonic-gate * fatal(fmt, ...) - put a message into the log file, then exit. 203*7c478bd9Sstevel@tonic-gate */ 204*7c478bd9Sstevel@tonic-gate /*PRINTFLIKE1*/ 205*7c478bd9Sstevel@tonic-gate void 206*7c478bd9Sstevel@tonic-gate fatal(const char *fmt, ...) 207*7c478bd9Sstevel@tonic-gate { 208*7c478bd9Sstevel@tonic-gate if (fmt) { 209*7c478bd9Sstevel@tonic-gate va_list ap; 210*7c478bd9Sstevel@tonic-gate va_start(ap, fmt); 211*7c478bd9Sstevel@tonic-gate vlog(fmt, ap); 212*7c478bd9Sstevel@tonic-gate va_end(ap); 213*7c478bd9Sstevel@tonic-gate } 214*7c478bd9Sstevel@tonic-gate log("********** ttymon exiting ***********"); 215*7c478bd9Sstevel@tonic-gate exit(1); 216*7c478bd9Sstevel@tonic-gate } 217*7c478bd9Sstevel@tonic-gate 218*7c478bd9Sstevel@tonic-gate # ifdef DEBUG 219*7c478bd9Sstevel@tonic-gate 220*7c478bd9Sstevel@tonic-gate /* 221*7c478bd9Sstevel@tonic-gate * opendebug - open debugging file, sets global file pointer Debugfp 222*7c478bd9Sstevel@tonic-gate * arg: getty - if TRUE, ttymon is in getty_mode and use a different 223*7c478bd9Sstevel@tonic-gate * debug file 224*7c478bd9Sstevel@tonic-gate */ 225*7c478bd9Sstevel@tonic-gate 226*7c478bd9Sstevel@tonic-gate void 227*7c478bd9Sstevel@tonic-gate opendebug(int getty_mode) 228*7c478bd9Sstevel@tonic-gate { 229*7c478bd9Sstevel@tonic-gate int fd, ret; 230*7c478bd9Sstevel@tonic-gate char debugfile[BUFSIZ]; 231*7c478bd9Sstevel@tonic-gate extern char *Tag; 232*7c478bd9Sstevel@tonic-gate 233*7c478bd9Sstevel@tonic-gate if (!getty_mode) { 234*7c478bd9Sstevel@tonic-gate (void)strcpy(debugfile, LOGDIR); 235*7c478bd9Sstevel@tonic-gate (void)strcat(debugfile, Tag); 236*7c478bd9Sstevel@tonic-gate (void)strcat(debugfile, "/"); 237*7c478bd9Sstevel@tonic-gate (void)strcat(debugfile, DBGFILE); 238*7c478bd9Sstevel@tonic-gate if ((Debugfp = fopen(debugfile, "a+")) == NULL) 239*7c478bd9Sstevel@tonic-gate fatal("open debug file failed"); 240*7c478bd9Sstevel@tonic-gate } 241*7c478bd9Sstevel@tonic-gate else { 242*7c478bd9Sstevel@tonic-gate if ((fd = open(EX_DBG, O_WRONLY|O_APPEND|O_CREAT)) < 0) 243*7c478bd9Sstevel@tonic-gate fatal("open %s failed: %s", EX_DBG, errno); 244*7c478bd9Sstevel@tonic-gate 245*7c478bd9Sstevel@tonic-gate if (fd >= 3) 246*7c478bd9Sstevel@tonic-gate ret = fd; 247*7c478bd9Sstevel@tonic-gate else { 248*7c478bd9Sstevel@tonic-gate if ((ret = fcntl(fd, F_DUPFD, 3)) < 0) 249*7c478bd9Sstevel@tonic-gate fatal("F_DUPFD fcntl failed: %s", 250*7c478bd9Sstevel@tonic-gate strerror(errno)); 251*7c478bd9Sstevel@tonic-gate 252*7c478bd9Sstevel@tonic-gate } 253*7c478bd9Sstevel@tonic-gate if ((Debugfp = fdopen(ret, "a+")) == NULL) 254*7c478bd9Sstevel@tonic-gate fatal("fdopen failed: %s", strerror(errno)); 255*7c478bd9Sstevel@tonic-gate 256*7c478bd9Sstevel@tonic-gate if (ret != fd) 257*7c478bd9Sstevel@tonic-gate (void)close(fd); 258*7c478bd9Sstevel@tonic-gate } 259*7c478bd9Sstevel@tonic-gate /* set close-on-exec flag */ 260*7c478bd9Sstevel@tonic-gate if (fcntl(fileno(Debugfp), F_SETFD, 1) == -1) 261*7c478bd9Sstevel@tonic-gate fatal("F_SETFD fcntl failed: %s", strerror(errno)); 262*7c478bd9Sstevel@tonic-gate } 263*7c478bd9Sstevel@tonic-gate 264*7c478bd9Sstevel@tonic-gate /* 265*7c478bd9Sstevel@tonic-gate * debug(msg) - put a message into debug file 266*7c478bd9Sstevel@tonic-gate */ 267*7c478bd9Sstevel@tonic-gate 268*7c478bd9Sstevel@tonic-gate void 269*7c478bd9Sstevel@tonic-gate debug(const char *fmt, ...) 270*7c478bd9Sstevel@tonic-gate { 271*7c478bd9Sstevel@tonic-gate va_list ap; 272*7c478bd9Sstevel@tonic-gate char *timestamp; /* current time in readable form */ 273*7c478bd9Sstevel@tonic-gate time_t clock; /* current time in seconds */ 274*7c478bd9Sstevel@tonic-gate 275*7c478bd9Sstevel@tonic-gate (void) time(&clock); 276*7c478bd9Sstevel@tonic-gate timestamp = ctime(&clock); 277*7c478bd9Sstevel@tonic-gate *(strchr(timestamp, '\n')) = '\0'; 278*7c478bd9Sstevel@tonic-gate 279*7c478bd9Sstevel@tonic-gate (void) fprintf(Debugfp, "%s; %ld; ", timestamp, getpid()); 280*7c478bd9Sstevel@tonic-gate 281*7c478bd9Sstevel@tonic-gate va_start(ap, fmt); 282*7c478bd9Sstevel@tonic-gate (void) vfprintf(Debugfp, fmt, ap); 283*7c478bd9Sstevel@tonic-gate va_end(ap); 284*7c478bd9Sstevel@tonic-gate 285*7c478bd9Sstevel@tonic-gate (void) fprintf(Debugfp, "\n"); 286*7c478bd9Sstevel@tonic-gate (void) fflush(Debugfp); 287*7c478bd9Sstevel@tonic-gate } 288*7c478bd9Sstevel@tonic-gate #endif 289