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
assert(s1,s2,i1,file,line)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
errent(s1,s2,i1,file,line)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
logError(s1,s2,i1,type,file,line)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 *
timeStamp()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
countProcs(prefix,maxCount)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
cuantos(prefix,dir)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