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