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