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 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 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 * 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 * 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 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 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 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 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