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 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 23*7c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 24*7c478bd9Sstevel@tonic-gate 25*7c478bd9Sstevel@tonic-gate 26*7c478bd9Sstevel@tonic-gate #ident "%Z%%M% %I% %E% SMI" /* from SVR4 bnu:utility.c 2.9 */ 27*7c478bd9Sstevel@tonic-gate 28*7c478bd9Sstevel@tonic-gate #include "uucp.h" 29*7c478bd9Sstevel@tonic-gate 30*7c478bd9Sstevel@tonic-gate 31*7c478bd9Sstevel@tonic-gate static void logError(); 32*7c478bd9Sstevel@tonic-gate extern int cuantos(), gnamef(); 33*7c478bd9Sstevel@tonic-gate 34*7c478bd9Sstevel@tonic-gate #define TY_ASSERT 1 35*7c478bd9Sstevel@tonic-gate #define TY_ERROR 2 36*7c478bd9Sstevel@tonic-gate 37*7c478bd9Sstevel@tonic-gate /* 38*7c478bd9Sstevel@tonic-gate * produce an assert error message 39*7c478bd9Sstevel@tonic-gate * input: 40*7c478bd9Sstevel@tonic-gate * s1 - string 1 41*7c478bd9Sstevel@tonic-gate * s2 - string 2 42*7c478bd9Sstevel@tonic-gate * i1 - integer 1 (usually errno) 43*7c478bd9Sstevel@tonic-gate * file - __FILE of calling module 44*7c478bd9Sstevel@tonic-gate * line - __LINE__ of calling module 45*7c478bd9Sstevel@tonic-gate */ 46*7c478bd9Sstevel@tonic-gate void 47*7c478bd9Sstevel@tonic-gate assert(s1, s2, i1, file, line) 48*7c478bd9Sstevel@tonic-gate char *s1, *s2, *file; 49*7c478bd9Sstevel@tonic-gate { 50*7c478bd9Sstevel@tonic-gate logError(s1, s2, i1, TY_ASSERT, file, line); 51*7c478bd9Sstevel@tonic-gate return; 52*7c478bd9Sstevel@tonic-gate } 53*7c478bd9Sstevel@tonic-gate 54*7c478bd9Sstevel@tonic-gate 55*7c478bd9Sstevel@tonic-gate /* 56*7c478bd9Sstevel@tonic-gate * produce an assert error message 57*7c478bd9Sstevel@tonic-gate * input: -- same as assert 58*7c478bd9Sstevel@tonic-gate */ 59*7c478bd9Sstevel@tonic-gate void 60*7c478bd9Sstevel@tonic-gate errent(s1, s2, i1, file, line) 61*7c478bd9Sstevel@tonic-gate char *s1, *s2, *file; 62*7c478bd9Sstevel@tonic-gate { 63*7c478bd9Sstevel@tonic-gate logError(s1, s2, i1, TY_ERROR, file, line); 64*7c478bd9Sstevel@tonic-gate return; 65*7c478bd9Sstevel@tonic-gate } 66*7c478bd9Sstevel@tonic-gate 67*7c478bd9Sstevel@tonic-gate #define EFORMAT "%sERROR (%.9s) pid: %ld (%s) %s %s (%d) [FILE: %s, LINE: %d]\n" 68*7c478bd9Sstevel@tonic-gate 69*7c478bd9Sstevel@tonic-gate static void 70*7c478bd9Sstevel@tonic-gate logError(s1, s2, i1, type, file, line) 71*7c478bd9Sstevel@tonic-gate char *s1, *s2, *file; 72*7c478bd9Sstevel@tonic-gate { 73*7c478bd9Sstevel@tonic-gate register FILE *errlog; 74*7c478bd9Sstevel@tonic-gate char text[BUFSIZ]; 75*7c478bd9Sstevel@tonic-gate pid_t pid; 76*7c478bd9Sstevel@tonic-gate 77*7c478bd9Sstevel@tonic-gate if (Debug) 78*7c478bd9Sstevel@tonic-gate errlog = stderr; 79*7c478bd9Sstevel@tonic-gate else { 80*7c478bd9Sstevel@tonic-gate errlog = fopen(ERRLOG, "a"); 81*7c478bd9Sstevel@tonic-gate (void) chmod(ERRLOG, PUB_FILEMODE); 82*7c478bd9Sstevel@tonic-gate } 83*7c478bd9Sstevel@tonic-gate if (errlog == NULL) 84*7c478bd9Sstevel@tonic-gate return; 85*7c478bd9Sstevel@tonic-gate 86*7c478bd9Sstevel@tonic-gate pid = getpid(); 87*7c478bd9Sstevel@tonic-gate 88*7c478bd9Sstevel@tonic-gate (void) fprintf(errlog, EFORMAT, type == TY_ASSERT ? "ASSERT " : " ", 89*7c478bd9Sstevel@tonic-gate Progname, (long) pid, timeStamp(), s1, s2, i1, file, line); 90*7c478bd9Sstevel@tonic-gate 91*7c478bd9Sstevel@tonic-gate if (!Debug) 92*7c478bd9Sstevel@tonic-gate (void) fclose(errlog); 93*7c478bd9Sstevel@tonic-gate 94*7c478bd9Sstevel@tonic-gate (void) sprintf(text, " %sERROR %.100s %.100s (%.9s)", 95*7c478bd9Sstevel@tonic-gate type == TY_ASSERT ? "ASSERT " : " ", 96*7c478bd9Sstevel@tonic-gate s1, s2, Progname); 97*7c478bd9Sstevel@tonic-gate if (type == TY_ASSERT) 98*7c478bd9Sstevel@tonic-gate systat(Rmtname, SS_ASSERT_ERROR, text, Retrytime); 99*7c478bd9Sstevel@tonic-gate return; 100*7c478bd9Sstevel@tonic-gate } 101*7c478bd9Sstevel@tonic-gate 102*7c478bd9Sstevel@tonic-gate 103*7c478bd9Sstevel@tonic-gate /* timeStamp - create standard time string 104*7c478bd9Sstevel@tonic-gate * return 105*7c478bd9Sstevel@tonic-gate * pointer to time string 106*7c478bd9Sstevel@tonic-gate */ 107*7c478bd9Sstevel@tonic-gate 108*7c478bd9Sstevel@tonic-gate char * 109*7c478bd9Sstevel@tonic-gate timeStamp() 110*7c478bd9Sstevel@tonic-gate { 111*7c478bd9Sstevel@tonic-gate register struct tm *tp; 112*7c478bd9Sstevel@tonic-gate time_t clock; 113*7c478bd9Sstevel@tonic-gate static char str[20]; 114*7c478bd9Sstevel@tonic-gate 115*7c478bd9Sstevel@tonic-gate (void) time(&clock); 116*7c478bd9Sstevel@tonic-gate tp = localtime(&clock); 117*7c478bd9Sstevel@tonic-gate (void) sprintf(str, "%d/%d-%d:%2.2d:%2.2d", tp->tm_mon + 1, 118*7c478bd9Sstevel@tonic-gate tp->tm_mday, tp->tm_hour, tp->tm_min, tp->tm_sec); 119*7c478bd9Sstevel@tonic-gate return(str); 120*7c478bd9Sstevel@tonic-gate } 121*7c478bd9Sstevel@tonic-gate 122*7c478bd9Sstevel@tonic-gate 123*7c478bd9Sstevel@tonic-gate /* 124*7c478bd9Sstevel@tonic-gate * Function: countProcs - Count Process to Stay Within Limits 125*7c478bd9Sstevel@tonic-gate * 126*7c478bd9Sstevel@tonic-gate * There are a number of cases in BNU when we want to limit the number 127*7c478bd9Sstevel@tonic-gate * of processes of a certain type that are running at a given time. This 128*7c478bd9Sstevel@tonic-gate * process is used to check the number of existing processes, to determine 129*7c478bd9Sstevel@tonic-gate * if a new one is allowed. 130*7c478bd9Sstevel@tonic-gate * 131*7c478bd9Sstevel@tonic-gate * The strategy is that all processes of a given type will place a lock 132*7c478bd9Sstevel@tonic-gate * file with a specific prefix in a single directory, usually 133*7c478bd9Sstevel@tonic-gate * /var/spool/locks. The caller of this function must provide a full 134*7c478bd9Sstevel@tonic-gate * path prefix, and countProcs will count the number of files that begin 135*7c478bd9Sstevel@tonic-gate * with the prefix and compare the count to the allowable maximum. 136*7c478bd9Sstevel@tonic-gate * 137*7c478bd9Sstevel@tonic-gate * Parameters: 138*7c478bd9Sstevel@tonic-gate * 139*7c478bd9Sstevel@tonic-gate * prefix - A full path prefix for lock files that identify 140*7c478bd9Sstevel@tonic-gate * processes that are to be counted. 141*7c478bd9Sstevel@tonic-gate * maxCount - Maximum number of allowable processes. 142*7c478bd9Sstevel@tonic-gate * 143*7c478bd9Sstevel@tonic-gate * Returns: 144*7c478bd9Sstevel@tonic-gate * 145*7c478bd9Sstevel@tonic-gate * TRUE is returned if this process is allowed to continue, and 146*7c478bd9Sstevel@tonic-gate * FALSE is returned if the maximum is exceeded. 147*7c478bd9Sstevel@tonic-gate */ 148*7c478bd9Sstevel@tonic-gate 149*7c478bd9Sstevel@tonic-gate int 150*7c478bd9Sstevel@tonic-gate countProcs (prefix, maxCount) 151*7c478bd9Sstevel@tonic-gate 152*7c478bd9Sstevel@tonic-gate char * prefix; 153*7c478bd9Sstevel@tonic-gate int maxCount; 154*7c478bd9Sstevel@tonic-gate 155*7c478bd9Sstevel@tonic-gate { 156*7c478bd9Sstevel@tonic-gate register char * namePrefix; /* Points to file name part */ 157*7c478bd9Sstevel@tonic-gate 158*7c478bd9Sstevel@tonic-gate char directory[MAXNAMESIZE]; 159*7c478bd9Sstevel@tonic-gate register int processes; /* Count of processes. */ 160*7c478bd9Sstevel@tonic-gate 161*7c478bd9Sstevel@tonic-gate /* Separate prefix into directory part and file name part. */ 162*7c478bd9Sstevel@tonic-gate 163*7c478bd9Sstevel@tonic-gate strncpy(directory, prefix, MAXNAMESIZE); 164*7c478bd9Sstevel@tonic-gate directory[MAXNAMESIZE-1] = NULLCHAR; 165*7c478bd9Sstevel@tonic-gate namePrefix = strrchr(directory, '/'); 166*7c478bd9Sstevel@tonic-gate ASSERT(namePrefix != NULL, "No file name in", prefix, 0); 167*7c478bd9Sstevel@tonic-gate *namePrefix++ = NULLCHAR; /* Terminate directory part */ 168*7c478bd9Sstevel@tonic-gate 169*7c478bd9Sstevel@tonic-gate /* Check to see if we can continue. */ 170*7c478bd9Sstevel@tonic-gate 171*7c478bd9Sstevel@tonic-gate processes = cuantos(namePrefix, directory); 172*7c478bd9Sstevel@tonic-gate if (processes <= maxCount) 173*7c478bd9Sstevel@tonic-gate return TRUE; 174*7c478bd9Sstevel@tonic-gate else 175*7c478bd9Sstevel@tonic-gate return FALSE; 176*7c478bd9Sstevel@tonic-gate } 177*7c478bd9Sstevel@tonic-gate 178*7c478bd9Sstevel@tonic-gate 179*7c478bd9Sstevel@tonic-gate /* 180*7c478bd9Sstevel@tonic-gate * return the number of files in directory <dir> who's names 181*7c478bd9Sstevel@tonic-gate * begin with <prefix> 182*7c478bd9Sstevel@tonic-gate * This is used to count the number of processes of a certain 183*7c478bd9Sstevel@tonic-gate * type that are currently running. 184*7c478bd9Sstevel@tonic-gate * 185*7c478bd9Sstevel@tonic-gate */ 186*7c478bd9Sstevel@tonic-gate int 187*7c478bd9Sstevel@tonic-gate cuantos(prefix, dir) 188*7c478bd9Sstevel@tonic-gate char *prefix, *dir; 189*7c478bd9Sstevel@tonic-gate { 190*7c478bd9Sstevel@tonic-gate int i = 0; 191*7c478bd9Sstevel@tonic-gate DIR *pdir; 192*7c478bd9Sstevel@tonic-gate char fullname[MAXNAMESIZE], file[MAXNAMESIZE]; 193*7c478bd9Sstevel@tonic-gate 194*7c478bd9Sstevel@tonic-gate pdir = opendir(dir); 195*7c478bd9Sstevel@tonic-gate ASSERT(pdir != NULL, Ct_OPEN, dir, errno); 196*7c478bd9Sstevel@tonic-gate 197*7c478bd9Sstevel@tonic-gate while (gnamef(pdir, file) == TRUE) 198*7c478bd9Sstevel@tonic-gate if (PREFIX(prefix, file)) { 199*7c478bd9Sstevel@tonic-gate (void) sprintf(fullname, "%s/%s", dir, file); 200*7c478bd9Sstevel@tonic-gate if (cklock(fullname)) 201*7c478bd9Sstevel@tonic-gate i++; 202*7c478bd9Sstevel@tonic-gate } 203*7c478bd9Sstevel@tonic-gate closedir(pdir); 204*7c478bd9Sstevel@tonic-gate return(i); 205*7c478bd9Sstevel@tonic-gate } 206