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