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