xref: /illumos-gate/usr/src/cmd/bnu/systat.c (revision 7c478bd9)
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:systat.c 2.7 */
27 
28 #include "uucp.h"
29 
30 #define STATNAME(f, n) ((void)sprintf(f, "%s/%s", STATDIR, n))
31 #define S_SIZE 100
32 
33 /*
34  * make system status entry
35  *	name -> system name
36  *	text -> text string to read
37  *	type -> ?
38  * return:
39  *	none
40  */
41 void
42 systat(name, type, text, retry)
43 register int type;
44 char *name, *text;
45 long retry;
46 {
47 	register FILE *fp;
48 	int count;
49 	char filename[MAXFULLNAME], line[S_SIZE];
50 	time_t prestime;
51 	long presretry = 0;
52 	char *vec[5];
53 
54 	line[0] = '\0';
55 	(void) time(&prestime);
56 	count = 0;
57 	STATNAME(filename, name);
58 
59 	fp = fopen(filename, "r");
60 	if (fp != NULL) {
61 		if (fgets(line, S_SIZE, fp) != NULL)
62 			if (getargs(line, vec, 4) == 4) {
63 			    count = atoi(vec[1]);
64 			    presretry = atol(vec[3]);
65 			}
66 		if (count <= 0)
67 			count = 0;
68 		fclose(fp);
69 	}
70 
71 	switch (type) {
72 		/* if there is already a status file - don't change */
73 	case SS_TIME_WRONG:
74 	case SS_LOCKED_DEVICE:
75 	case SS_CANT_ACCESS_DEVICE:
76 		if (count > 1)
77 		    return;
78 		break;
79 
80 		/* reset count on successful call */
81 	case SS_OK:
82 	case SS_INPROGRESS:
83 	case SS_CONVERSATION:	/* failure during conversation - contact ok */
84 		retry = 0;
85 		count = 0;
86 		break;
87 
88 		/* Startup failure means protocol mismatch--some administrative
89 		 * action must be taken
90 		 */
91 	case SS_STARTUP:
92 		retry = MAXRETRYTIME;
93 		count = 0;
94 		break;
95 	default:	/*  increment count and set up retry time */
96 		count++;
97 		if (!retry) {	/* use exponential backoff */
98 		    if (presretry < RETRYTIME)
99 			retry = RETRYTIME;
100 		    else {
101 			retry = presretry + presretry;
102 			if (retry > MAXRETRYTIME)
103 			    retry = MAXRETRYTIME;
104 		    }
105 		}
106 		else {	/* use specified time */
107 		    if (retry < RETRYTIME)
108 			retry = RETRYTIME;
109 		}
110 		break;
111 	}
112 
113 	fp = fopen(filename, "w");
114 	/* can't ASSERT since assert() calls systat() */
115 	if (fp == NULL) {
116 	    errent(Ct_OPEN, filename, errno, __FILE__, __LINE__);
117 	    cleanup(FAIL);
118 	}
119 	(void) chmod(filename, PUB_FILEMODE);
120 	(void) fprintf(fp, "%d %d %ld %ld %s %s\n",
121 		type, count, prestime, retry, text, name);
122 	(void) fclose(fp);
123 	return;
124 }
125 
126 /*
127  * check system status for call
128  *	name -> system to check
129  * return:
130  *	0	-> ok
131  *	>0	-> system status
132  */
133 int
134 callok(name)
135 char *name;
136 {
137 	register FILE *fp;
138 	register int t;
139 	long retrytime;
140 	int count, type;
141 	char filename[MAXFULLNAME], line[S_SIZE];
142 	time_t lasttime, prestime;
143 
144 	STATNAME(filename, name);
145 	fp = fopen(filename, "r");
146 	if (fp == NULL)
147 		return(SS_OK);
148 
149 	if (fgets(line, S_SIZE, fp) == NULL) {
150 
151 		/* no data */
152 		fclose(fp);
153 		(void) unlink(filename);
154 		return(SS_OK);
155 	}
156 
157 	fclose(fp);
158 	(void) time(&prestime);
159 	sscanf(line, "%d%d%ld%ld", &type, &count, &lasttime, &retrytime);
160 	t = type;
161 
162 	switch(t) {
163 	case SS_SEQBAD:
164 	case SS_LOGIN_FAILED:
165 	case SS_DIAL_FAILED:
166 	case SS_BAD_LOG_MCH:
167 	case SS_BADSYSTEM:
168 	case SS_CANT_ACCESS_DEVICE:
169 	case SS_WRONG_MCH:
170 	case SS_RLOCKED:
171 	case SS_RUNKNOWN:
172 	case SS_RLOGIN:
173 	case SS_UNKNOWN_RESPONSE:
174 	case SS_CHAT_FAILED:
175 	case SS_CALLBACK_LOOP:
176 
177 		if (prestime - lasttime < retrytime) {
178 			logent("RETRY TIME NOT REACHED", "NO CALL");
179 			CDEBUG(4, "RETRY TIME (%ld) NOT REACHED\n", retrytime);
180 			return(type);
181 		}
182 
183 		return(SS_OK);
184 	default:
185 		return(SS_OK);
186 	}
187 }
188