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 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 27 * Use is subject to license terms. 28 */ 29 30 #pragma ident "%Z%%M% %I% %E% SMI" 31 32 33 #include <stdio.h> 34 #include <stdlib.h> 35 #include <strings.h> 36 #include <ctype.h> 37 #include <sys/types.h> 38 #include <unistd.h> 39 #include "extern.h" 40 #include "misc.h" 41 #include <sac.h> 42 #include "structs.h" 43 #ifdef SAC 44 #include "msgs.h" 45 #endif 46 47 char Comment[SIZE]; /* place holder for comments */ 48 49 50 /* 51 * nexttok - return next token, essentially a strtok, but it can 52 * deal with null fields and strtok can not 53 * 54 * args: str - the string to be examined, NULL if we should 55 * examine the remembered string 56 * delim - the list of valid delimiters 57 * ros - rest of string flag (1 for rest of string, 0 for 58 * normal processing) 59 */ 60 61 62 char * 63 nexttok(str, delim, ros) 64 char *str; 65 register char *delim; 66 int ros; 67 { 68 static char *savep; /* the remembered string */ 69 register char *p; /* pointer to start of token */ 70 register char *ep; /* pointer to end of token */ 71 72 p = (str == NULL) ? savep : str ; 73 if (ros) 74 return(p); 75 if (p == NULL) 76 return(NULL); 77 ep = strpbrk(p, delim); 78 if (ep == NULL) { 79 savep = NULL; 80 return(p); 81 } 82 savep = ep + 1; 83 *ep = '\0'; 84 return(p); 85 } 86 87 88 /* 89 * parse - parse a line from _sactab. This routine will return if the parse 90 * was successful, otherwise it will output an error and exit. 91 * 92 * args: p - pointer to the data read from the file 93 * sp - pointer to a structure in which the separated fields 94 * are placed 95 * 96 * A line in the file has the following format: 97 * 98 * tag:type:flags:restart_count:command_string #comment 99 */ 100 101 102 void 103 parse(p, sp) 104 register char *p; 105 register struct sactab *sp; 106 { 107 char scratch[SIZE]; /* a scratch buffer */ 108 109 /* 110 * get the PM tag 111 */ 112 113 p = nexttok(p, DELIM, FALSE); 114 if (p == NULL) { 115 # ifdef SAC 116 error(E_BADFILE, EXIT); 117 # else 118 Saferrno = E_SAFERR; 119 error("_sactab file is corrupt"); 120 # endif 121 } 122 if (strlen(p) > PMTAGSIZE) { 123 p[PMTAGSIZE] = '\0'; 124 # ifdef SAC 125 (void) sprintf(scratch, "tag too long, truncated to <%s>", p); 126 log(scratch); 127 # else 128 (void) fprintf(stderr, "tag too long, truncated to <%s>", p); 129 # endif 130 } 131 (void) strcpy(sp->sc_tag, p); 132 133 /* 134 * get the PM type 135 */ 136 137 p = nexttok(NULL, DELIM, FALSE); 138 if (p == NULL) { 139 # ifdef SAC 140 error(E_BADFILE, EXIT); 141 # else 142 Saferrno = E_SAFERR; 143 error("_sactab file is corrupt"); 144 # endif 145 } 146 if (strlen(p) > PMTYPESIZE) { 147 p[PMTYPESIZE] = '\0'; 148 # ifdef SAC 149 (void) sprintf(scratch, "type too long, truncated to <%s>", p); 150 log(scratch); 151 # else 152 (void) fprintf(stderr, "type too long, truncated to <%s>", p); 153 # endif 154 } 155 (void) strcpy(sp->sc_type, p); 156 157 /* 158 * get the flags 159 */ 160 161 p = nexttok(NULL, DELIM, FALSE); 162 if (p == NULL) { 163 # ifdef SAC 164 error(E_BADFILE, EXIT); 165 # else 166 Saferrno = E_SAFERR; 167 error("_sactab file is corrupt"); 168 # endif 169 } 170 sp->sc_flags = 0; 171 while (*p) { 172 switch (*p++) { 173 case 'd': 174 sp->sc_flags |= D_FLAG; 175 break; 176 case 'x': 177 sp->sc_flags |= X_FLAG; 178 break; 179 default: 180 (void) sprintf(scratch, "Unrecognized flag <%c>", *(p - 1)); 181 # ifdef SAC 182 log(scratch); 183 # else 184 Saferrno = E_SAFERR; 185 error(scratch); 186 # endif 187 break; 188 } 189 } 190 191 /* 192 * get the restart count 193 */ 194 195 p = nexttok(NULL, DELIM, FALSE); 196 if (p == NULL) { 197 # ifdef SAC 198 error(E_BADFILE, EXIT); 199 # else 200 Saferrno = E_SAFERR; 201 error("_sactab file is corrupt"); 202 # endif 203 } 204 sp->sc_rsmax = atoi(p); 205 206 /* 207 * get the command string 208 */ 209 210 p = nexttok(NULL, DELIM, FALSE); 211 if (p == NULL) { 212 # ifdef SAC 213 error(E_BADFILE, EXIT); 214 # else 215 Saferrno = E_SAFERR; 216 error("_sactab file is corrupt"); 217 # endif 218 } 219 if ((sp->sc_cmd = malloc((unsigned) (strlen(p) + 1))) == NULL) { 220 # ifdef SAC 221 error(E_MALLOC, EXIT); 222 # else 223 Saferrno = E_SAFERR; 224 error("malloc failed"); 225 # endif 226 } 227 (void) strcpy(sp->sc_cmd, p); 228 229 /* 230 * remember the comment string 231 */ 232 233 if ((sp->sc_comment = malloc((unsigned) (strlen(Comment) + 1))) == NULL) { 234 # ifdef SAC 235 error(E_MALLOC, EXIT); 236 # else 237 Saferrno = E_SAFERR; 238 error("malloc failed"); 239 # endif 240 } 241 (void) strcpy(sp->sc_comment, Comment); 242 } 243 244 245 /* 246 * trim - remove comments, trim off trailing white space, done in place 247 * args: p - string to be acted upon 248 */ 249 250 char * 251 trim(p) 252 register char *p; 253 { 254 register char *tp; /* temp pointer */ 255 256 /* 257 * remove comments, if any, but remember them for later 258 */ 259 260 tp = strchr(p, COMMENT); 261 Comment[0] = '\0'; 262 if (tp) { 263 (void) strcpy(Comment, tp + 1); /* skip the '#' */ 264 *tp = '\0'; 265 tp = strchr(Comment, '\n'); 266 if (tp) 267 *tp ='\0'; 268 } 269 270 /* 271 * remove trailing whitespace, if any 272 */ 273 274 for (tp = p + strlen(p) - 1; tp >= p && isspace(*tp); --tp) 275 *tp = '\0'; 276 return(p); 277 } 278 279 280 /* 281 * pstate - put port monitor state into intelligible form for output 282 * SSTATE is only used by sacadm 283 * 284 * args: state - binary representation of state 285 */ 286 287 char * 288 pstate(unchar state) 289 { 290 switch (state) { 291 case NOTRUNNING: 292 return("NOTRUNNING"); 293 case STARTING: 294 return("STARTING"); 295 case ENABLED: 296 return("ENABLED"); 297 case DISABLED: 298 return("DISABLED"); 299 case STOPPING: 300 return("STOPPING"); 301 case FAILED: 302 return("FAILED"); 303 case UNKNOWN: 304 return("UNKNOWN"); 305 # ifndef SAC 306 case SSTATE: 307 return("NO_SAC"); 308 # endif 309 default: 310 # ifdef SAC 311 error(E_BADSTATE, EXIT); 312 # else 313 Saferrno = E_SAFERR; 314 error("Improper message from SAC\n"); 315 # endif 316 } 317 /* NOTREACHED */ 318 return (NULL); 319 } 320