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