/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2005 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ /* All Rights Reserved */ #pragma ident "%Z%%M% %I% %E% SMI" /* * error/logging/cleanup functions for ttymon. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include "ttymon.h" #include "tmstruct.h" #include "tmextern.h" # ifdef DEBUG extern FILE *Debugfp; # endif const char *appname = "ttymon"; void openttymonlog(void) { int fd, ret; char logfile[MAXPATHLEN]; extern char *Tag; /* the log file resides in /var/saf/pmtag/ */ (void) snprintf(logfile, sizeof (logfile), "%s%s/%s", LOGDIR, Tag, LOGFILE); Logfp = NULL; (void)close(0); if ((fd = open(logfile, O_WRONLY|O_CREAT|O_APPEND,0444)) != -1) if ((ret = fcntl(fd, F_DUPFD, 3)) == 3) { /* set close-on-exec flag */ if (fcntl(ret, F_SETFD, FD_CLOEXEC) == 0) { Logfp = fdopen(ret, "a+"); } } if (!Logfp) { cons_printf("ttymon cannot create log file \"%s\": %s\n", logfile, strerror(errno)); exit(1); } log(" "); log("********** ttymon starting **********"); #ifdef DEBUG log("fd(log)\t = %d", fileno(Logfp)); #endif } static void roll_log() { char logf[MAXPATHLEN]; char ologf[MAXPATHLEN]; char tlogf[MAXPATHLEN]; FILE *nlogfp; struct stat buf; (void) fprintf(Logfp, "Restarting log file\n"); (void) snprintf(logf, sizeof (logf), "%s%s/%s", LOGDIR, Tag, LOGFILE); (void) snprintf(ologf, sizeof (ologf), "%s%s/%s", LOGDIR, Tag, OLOGFILE); (void) snprintf(tlogf, sizeof (tlogf), "%s%s/%s", LOGDIR, Tag, TLOGFILE); if (!stat(ologf, &buf) && rename(ologf, tlogf)) { (void) fprintf(Logfp, "rename old to tmp file failed\n"); } else if (!stat(logf, &buf) && rename(logf, ologf)) { (void) fprintf(Logfp, "rename log to old file failed\n"); /* Restore old log file */ if (!stat(tlogf, &buf) && rename(tlogf, ologf)) (void) fprintf(Logfp, "rename tmp to old file failed\n"); } else if (nlogfp = fopen(logf, "w")) { (void) fclose(Logfp); Logfp = nlogfp; /* reset close-on-exec */ (void) fcntl(fileno(Logfp), F_SETFD, 1); } else { (void) fprintf(Logfp, "log file open failed\n"); /* Restore current and old log file */ if (!stat(ologf, &buf) && rename(ologf, logf)) (void) fprintf(Logfp, "rename old to log file failed\n"); else if (!stat(tlogf, &buf) && rename(tlogf, ologf)) (void) fprintf(Logfp, "rename tmp to old file failed\n"); } (void) unlink(tlogf); /* remove any stale tmp logfile */ } /* * vlog(msg) - common message routine. * - if Logfp is NULL, write message to stderr or CONSOLE */ static void vlog(const char *fmt, va_list ap) { char *timestamp; /* current time in readable form */ time_t clock; /* current time in seconds */ int fd; struct stat buf; if (Logfp) { if ((fstat(fileno(Logfp), &buf) != -1) && (buf.st_size >= Logmaxsz) && !Splflag) { Splflag = 1; roll_log(); Splflag = 0; } (void) time(&clock); timestamp = ctime(&clock); *(strchr(timestamp, '\n')) = '\0'; (void) fprintf(Logfp, "%s; %ld; ", timestamp, getpid()); (void) vfprintf(Logfp, fmt, ap); if (fmt[strlen(fmt) - 1] != '\n') (void) fputc('\n', Logfp); (void) fflush(Logfp); } else if (isatty(STDERR_FILENO)) { (void) fprintf(stderr, "%s: ", appname); (void) vfprintf(stderr, fmt, ap); if (fmt[strlen(fmt) - 1] != '\n') (void) fputc('\n', stderr); (void) fflush(stderr); } else if ((fd = open(CONSOLE, O_WRONLY|O_NOCTTY)) != -1) { FILE *f = fdopen(fd, "w"); (void) fprintf(f, "%s: ", appname); (void) vfprintf(f, fmt, ap); if (fmt[strlen(fmt) - 1] != '\n') (void) fputc('\n', f); (void) fclose(f); } else { vsyslog(LOG_CRIT, fmt, ap); } } /* * log(fmt, ...) - put a message into the log file * - if Logfp is NULL, write message to stderr or CONSOLE */ /*PRINTFLIKE1*/ void log(const char *fmt, ...) { va_list ap; va_start(ap, fmt); vlog(fmt, ap); va_end(ap); } /* * fatal(fmt, ...) - put a message into the log file, then exit. */ /*PRINTFLIKE1*/ void fatal(const char *fmt, ...) { if (fmt) { va_list ap; va_start(ap, fmt); vlog(fmt, ap); va_end(ap); } log("********** ttymon exiting ***********"); exit(1); } # ifdef DEBUG /* * opendebug - open debugging file, sets global file pointer Debugfp * arg: getty - if TRUE, ttymon is in getty_mode and use a different * debug file */ void opendebug(int getty_mode) { int fd, ret; char debugfile[BUFSIZ]; extern char *Tag; if (!getty_mode) { (void)strcpy(debugfile, LOGDIR); (void)strcat(debugfile, Tag); (void)strcat(debugfile, "/"); (void)strcat(debugfile, DBGFILE); if ((Debugfp = fopen(debugfile, "a+")) == NULL) fatal("open debug file failed"); } else { if ((fd = open(EX_DBG, O_WRONLY|O_APPEND|O_CREAT)) < 0) fatal("open %s failed: %s", EX_DBG, errno); if (fd >= 3) ret = fd; else { if ((ret = fcntl(fd, F_DUPFD, 3)) < 0) fatal("F_DUPFD fcntl failed: %s", strerror(errno)); } if ((Debugfp = fdopen(ret, "a+")) == NULL) fatal("fdopen failed: %s", strerror(errno)); if (ret != fd) (void)close(fd); } /* set close-on-exec flag */ if (fcntl(fileno(Debugfp), F_SETFD, 1) == -1) fatal("F_SETFD fcntl failed: %s", strerror(errno)); } /* * debug(msg) - put a message into debug file */ void debug(const char *fmt, ...) { va_list ap; char *timestamp; /* current time in readable form */ time_t clock; /* current time in seconds */ (void) time(&clock); timestamp = ctime(&clock); *(strchr(timestamp, '\n')) = '\0'; (void) fprintf(Debugfp, "%s; %ld; ", timestamp, getpid()); va_start(ap, fmt); (void) vfprintf(Debugfp, fmt, ap); va_end(ap); (void) fprintf(Debugfp, "\n"); (void) fflush(Debugfp); } #endif