xref: /titanic_51/usr/src/cmd/saf/admutil.c (revision 8eea8e29cc4374d1ee24c25a07f45af132db3499)
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"       /* SVr4.0 1.8*/
27 
28 
29 # include <stdio.h>
30 # include <signal.h>
31 # include <sac.h>
32 # include <sys/types.h>
33 # include <sys/stat.h>
34 # include <unistd.h>
35 # include "misc.h"
36 # include "structs.h"
37 # include "extern.h"
38 
39 
40 /*
41  * error - print out an error message and die
42  *
43  *	args:	msg - message to be printed, Saferrno previously set
44  */
45 
46 void
47 error(msg)
48 char *msg;
49 {
50 	(void) fprintf(stderr, "%s\n", msg);
51 	quit();
52 }
53 
54 
55 /*
56  * quit - exit the program with the status in Saferrno
57  */
58 
59 void
60 quit()
61 {
62 	exit(Saferrno);
63 }
64 
65 
66 /*
67  * make_tempname - generate a temp name to be used for updating files.
68  *		Names will be of the form HOME/xxx/.name, where HOME
69  *		is from misc.h
70  *
71  *	args:	bname - the basename of the file.  For example foo/_config
72  *		        will generate a tempname of HOME/foo/._config
73  */
74 
75 
76 char *
77 make_tempname(bname)
78 char *bname;
79 {
80 	static char buf[SIZE];	/* this is where we put the new name */
81 	char *p;			/* work pointer */
82 
83 	p = strrchr(bname, '/');
84 	if (p == NULL)
85 		(void) sprintf(buf, "%s/.%s", HOME, bname);
86 	else {
87 		(void) strcpy(buf, HOME);
88 		/* this zaps the trailing slash so the '.' can be stuck in */
89 		*p = '\0';
90 		(void) strcat(buf, "/");
91 		(void) strcat(buf, bname);
92 		(void) strcat(buf, "/.");
93 		(void) strcat(buf, (p + 1));
94 		*p = '/';
95 	}
96 	return(buf);
97 }
98 
99 
100 /*
101  * open_temp - open up a temp file
102  *
103  *	args:	tname - temp file name
104  */
105 
106 
107 
108 FILE *
109 open_temp(tname)
110 char *tname;
111 {
112 	FILE *fp;			/* fp associated with tname */
113 	struct sigaction sigact;	/* for signal handling */
114 
115 	sigact.sa_flags = 0;
116 	sigact.sa_handler = SIG_IGN;
117 	(void) sigemptyset(&sigact.sa_mask);
118 	(void) sigaddset(&sigact.sa_mask, SIGHUP);
119 	(void) sigaddset(&sigact.sa_mask, SIGINT);
120 	(void) sigaddset(&sigact.sa_mask, SIGQUIT);
121 	(void) sigaction(SIGHUP, &sigact, NULL);
122 	(void) sigaction(SIGINT, &sigact, NULL);
123 	(void) sigaction(SIGQUIT, &sigact, NULL);
124 	(void) umask(0333);
125 	if (access(tname, 0) != -1) {
126 		Saferrno = E_SAFERR;
127 		error("tempfile busy; try again later");
128 	}
129 	fp = fopen(tname, "w");
130 	if (fp == NULL) {
131 		Saferrno = E_SYSERR;
132 		error("cannot create tempfile");
133 	}
134 	return(fp);
135 }
136 
137 
138 /*
139  * replace - replace one file with another, only returns on success
140  *
141  *	args:	fname - name of target file
142  *		tname - name of source file
143  */
144 
145 
146 void
147 replace(fname, tname)
148 char *fname;
149 char *tname;
150 {
151 	char buf[SIZE];	/* scratch buffer */
152 
153 	(void) sprintf(buf, "%s/%s", HOME, fname);
154 	(void) unlink(buf);
155 	if (rename(tname, buf) < 0) {
156 		Saferrno = E_SYSERR;
157 		(void) unlink(tname);
158 		quit();
159 	}
160 }
161 
162 
163 /*
164  * copy_file - copy information from one file to another, return 0 on
165  *	success, -1 on failure
166  *
167  *	args:	fp - source file's file pointer
168  *		tfp - destination file's file pointer
169  *		start - starting line number
170  *		finish - ending line number (-1 indicates entire file)
171  */
172 
173 
174 copy_file(fp, tfp, start, finish)
175 FILE *fp;
176 FILE *tfp;
177 register int start;
178 register int finish;
179 {
180 	register int i;		/* loop variable */
181 	char dummy[SIZE];	/* scratch buffer */
182 
183 /*
184  * always start from the beginning because line numbers are absolute
185  */
186 
187 	rewind(fp);
188 
189 /*
190  * get to the starting point of interest
191  */
192 
193 	if (start != 1) {
194 		for (i = 1; i < start; i++)
195 			if (!fgets(dummy, SIZE, fp))
196 				return(-1);
197 	}
198 
199 /*
200  * copy as much as was requested
201  */
202 
203 	if (finish != -1) {
204 		for (i = start; i <= finish; i++) {
205 			if (!fgets(dummy, SIZE, fp))
206 				return(-1);
207 			if (fputs(dummy, tfp) == EOF)
208 				return(-1);
209 		}
210 	}
211 	else {
212 		for (;;) {
213 			if (fgets(dummy, SIZE, fp) == NULL) {
214 				if (feof(fp))
215 					break;
216 				else
217 					return(-1);
218 			}
219 			if (fputs(dummy, tfp) == EOF)
220 				return(-1);
221 		}
222 	}
223 	return(0);
224 }
225 
226 
227 /*
228  * find_pm - find an entry in _sactab for a particular port monitor
229  *
230  *	args:	fp - file pointer for _sactab
231  *		pmtag - tag of port monitor we're looking for
232  */
233 
234 find_pm(fp, pmtag)
235 FILE *fp;
236 char *pmtag;
237 {
238 	register char *p;	/* working pointer */
239 	int line = 0;		/* line number we found entry on */
240 	struct sactab stab;	/* place to hold parsed info */
241 	char buf[SIZE];	/* scratch buffer */
242 
243 	while (fgets(buf, SIZE, fp)) {
244 		line++;
245 		p = trim(buf);
246 		if (*p == '\0')
247 			continue;
248 		parse(p, &stab);
249 		if (!(strcmp(stab.sc_tag, pmtag)))
250 			return(line);
251 	}
252 	if (!feof(fp)) {
253 		Saferrno = E_SYSERR;
254 		error("error reading _sactab");
255 		/* NOTREACHED */
256 	}
257 	else
258 		return(0);
259 }
260 
261 
262 /*
263  * do_config - take a config script and put it where it belongs or
264  *		output an existing one.  Saferrno is set if any errors
265  *		are encountered.  Calling routine may choose to quit or
266  *		continue, in which case Saferrno will stay set, but may
267  *		change value if another error is encountered.
268  *
269  *	args:	script - name of file containing script (if NULL, means output
270  *			 existing one instead)
271  *		basename - name of script (relative to HOME (from misc.h))
272  */
273 
274 do_config(script, basename)
275 char *script;
276 char *basename;
277 {
278 	FILE *ifp;		/* file pointer for source file */
279 	FILE *ofp;		/* file pointer for target file */
280 	struct stat statbuf;	/* file status info */
281 	char *tname;		/* name of tempfile */
282 	char buf[SIZE];		/* scratch buffer */
283 
284 	if (script) {
285 		/* we're installing a new configuration script */
286 		if (access(script, 0) == 0) {
287 			if (stat(script, &statbuf) < 0) {
288 				Saferrno = E_SYSERR;
289 				(void) fprintf(stderr, "Could not stat <%s>\n", script);
290 				return(1);
291 			}
292 			if ((statbuf.st_mode & S_IFMT) != S_IFREG) {
293 				(void) fprintf(stderr, "warning - %s not a regular file - ignored\n", script);
294 				return(1);
295 			}
296 		}
297 		else {
298 			Saferrno = E_NOEXIST;
299 			(void) fprintf(stderr, "Invalid request, %s does not exist\n", script);
300 			return(1);
301 		}
302 		ifp = fopen(script, "r");
303 		if (ifp == NULL) {
304 			(void) fprintf(stderr, "Invalid request, can not open %s\n", script);
305 			Saferrno = E_SYSERR;
306 			return(1);
307 		}
308 		tname = make_tempname(basename);
309 		/* note - open_temp only returns if successful */
310 		ofp = open_temp(tname);
311 		while(fgets(buf, SIZE, ifp)) {
312 			if (fputs(buf, ofp) == EOF) {
313 				(void) unlink(tname);
314 				Saferrno = E_SYSERR;
315 				error("error in writing tempfile");
316 			}
317 		}
318 		(void) fclose(ifp);
319 		if (fclose(ofp) == EOF) {
320 			(void) unlink(tname);
321 			Saferrno = E_SYSERR;
322 			error("error closing tempfile");
323 		}
324 		/* note - replace only returns if successful */
325 		replace(basename, tname);
326 		return(0);
327 	}
328 	else {
329 		/* we're outputting a configuration script */
330 		(void) sprintf(buf, "%s/%s", HOME, basename);
331 		if (access(buf, 0) < 0) {
332 			(void) fprintf(stderr, "Invalid request, script does not exist\n");
333 			Saferrno = E_NOEXIST;
334 			return(1);
335 		}
336 		ifp = fopen(buf, "r");
337 		if (ifp == NULL) {
338 			(void) fprintf(stderr, "Invalid request, can not open script\n");
339 			Saferrno = E_SYSERR;
340 			return(1);
341 		}
342 		while (fgets(buf, SIZE, ifp))
343 			(void) fputs(buf, stdout);
344 		(void) fclose(ifp);
345 		return(0);
346 	}
347 }
348