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 /* 23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 28 /* All Rights Reserved */ 29 30 31 #pragma ident "%Z%%M% %I% %E% SMI" 32 33 #include <unistd.h> 34 #include <stdarg.h> 35 #include <stdlib.h> 36 #include <stdio.h> 37 #include <errno.h> 38 #include <sys/types.h> 39 #include <ctype.h> 40 #include <string.h> 41 #include <sys/stat.h> 42 #include <fcntl.h> 43 #include <sys/stropts.h> 44 #include <sys/sad.h> 45 #include "ttymon.h" 46 #include "tmstruct.h" 47 #include "tmextern.h" 48 49 #define NSTRPUSH 9 /* should agree with the tunable in */ 50 /* /etc/master.d/kernel */ 51 52 /* 53 * check_device - check to see if the device exists, 54 * - and if it is a character device 55 * - return 0 if everything is ok. Otherwise, return -1 56 */ 57 int 58 check_device(char *device) 59 { 60 struct stat statbuf; 61 62 if ((device == NULL) || (*device == '\0')) { 63 log("error -- device field is missing"); 64 return(-1); 65 } 66 if (*device != '/') { 67 log("error -- must specify full path name for \"%s\".", device); 68 return(-1); 69 } 70 if (access(device, 0) == 0) { 71 if (stat(device,&statbuf) < 0) { 72 log("stat(%s) failed: %s", device, strerror(errno)); 73 return(-1); 74 } 75 if ((statbuf.st_mode & S_IFMT) != S_IFCHR) { 76 log("error -- \"%s\" not character special device", 77 device); 78 return(-1); 79 } 80 } 81 else { 82 log("error -- device \"%s\" does not exist", device); 83 return(-1); 84 } 85 return(0); 86 } 87 88 /* 89 * check_cmd - check to see if the cmd file exists, 90 * - and if it is executable 91 * - return 0 if everything is ok. Otherwise, return -1 92 */ 93 int 94 check_cmd(char *cmd) 95 { 96 struct stat statbuf; 97 char tbuf[BUFSIZ]; 98 char *tp = tbuf; 99 100 if ((cmd == NULL) || (*cmd == '\0')) { 101 log("error -- server command is missing"); 102 return(-1); 103 } 104 (void)strcpy(tp,cmd); 105 (void)strtok(tp, " \t"); 106 if (*tp != '/') { 107 log("error -- must specify full path name for \"%s\".", tp); 108 return(-1); 109 } 110 if (access(tp, 0) == 0) { 111 if (stat(tp,&statbuf) < 0) { 112 log("stat(%s) failed.", tp); 113 return(-1); 114 } 115 if (!(statbuf.st_mode & 0111)) { 116 log("error -- \"%s\" not executable\n", tp); 117 return(-1); 118 } 119 if ((statbuf.st_mode & S_IFMT) != S_IFREG) { 120 log("error -- \"%s\" not a regular file", tp); 121 return(-1); 122 } 123 } 124 else { 125 log("error -- \"%s\" does not exist", tp); 126 return(-1); 127 } 128 return(0); 129 } 130 131 /* 132 * strcheck(sp, flag) - check string 133 * - if flag == ALNUM, all char. are expected to 134 * be alphanumeric 135 * - if flag == NUM, all char. are expected to 136 * be digits and the number must be >= 0 137 * - return 0 if successful, -1 if failed. 138 */ 139 int 140 strcheck(sp, flag) 141 char *sp; /* string ptr */ 142 int flag; /* either NUM or ALNUM */ 143 { 144 register char *cp; 145 if (flag == NUM) { 146 for (cp = sp; *cp; cp++) { 147 if (!isdigit(*cp)) { 148 return(-1); 149 } 150 } 151 } 152 else { /* (flag == ALNUM) */ 153 for (cp = sp; *cp; cp++) { 154 if (!isalnum(*cp)) { 155 return(-1); 156 } 157 } 158 } 159 return(0); 160 } 161 162 /* 163 * vml(modules) - validate a list of modules 164 * - return 0 if successful, -1 if failed 165 */ 166 int 167 vml(modules) 168 char *modules; 169 { 170 char *modp, *svmodp; 171 int i, fd; 172 struct str_mlist newmods[NSTRPUSH]; /* modlist for newlist */ 173 struct str_list newlist; /* modules to be pushed */ 174 175 if ((modules == NULL) || (*modules == '\0')) 176 return(0); 177 178 newlist.sl_modlist = newmods; 179 newlist.sl_nmods = NSTRPUSH; 180 if ((modp = malloc(strlen(modules) + 1)) == NULL) { 181 log("vml: malloc failed"); 182 return (-1); 183 }; 184 svmodp = modp; 185 (void)strcpy(modp, modules); 186 /* 187 * pull mod names out of comma-separated list 188 */ 189 for ( i = 0, modp = strtok(modp, ","); 190 modp != NULL; i++, modp = strtok(NULL, ",") ) { 191 if ( i >= NSTRPUSH) { 192 log("too many modules in <%s>", modules); 193 i = -1; 194 break; 195 } 196 (void)strncpy(newlist.sl_modlist[i].l_name, 197 modp, FMNAMESZ); 198 newlist.sl_modlist[i].l_name[FMNAMESZ] = '\0'; 199 } 200 free(svmodp); 201 if (i == -1) 202 return (-1); 203 newlist.sl_nmods = i; 204 205 /* 206 * Is it a valid list of modules? 207 */ 208 if ((fd = open(USERDEV, O_RDWR)) == -1) { 209 if (errno == EBUSY) { 210 log("Warning - can't validate module list, /dev/sad/user busy"); 211 return(0); 212 } 213 log("open /dev/sad/user failed: %s", strerror(errno)); 214 return(-1); 215 } 216 if ( (i = ioctl(fd, SAD_VML, &newlist)) < 0 ) { 217 log("Validate modules ioctl failed, modules = <%s>: %s", 218 modules, strerror(errno)); 219 (void)close(fd); 220 return(-1); 221 } 222 if ( i != 0 ) { 223 log("Error - invalid STREAMS module list <%s>.", modules); 224 (void)close(fd); 225 return(-1); 226 } 227 (void)close(fd); 228 return(0); 229 } 230 231 /* 232 * copystr(s1, s2) - copy string s2 to string s1 233 * - also put '\' in front of ':' 234 */ 235 void 236 copystr(s1,s2) 237 char *s1, *s2; 238 { 239 while (*s2) { 240 if (*s2 == ':') { 241 *s1++ = '\\'; 242 } 243 *s1++ = *s2++; 244 } 245 *s1 = '\0'; 246 } 247 248 /*PRINTFLIKE1*/ 249 void 250 cons_printf(const char *fmt, ...) 251 { 252 char buf[MAXPATHLEN * 2]; /* enough space for msg including a path */ 253 int fd; 254 va_list ap; 255 256 va_start(ap, fmt); 257 (void) vsnprintf(buf, sizeof (buf), fmt, ap); 258 va_end(ap); 259 260 if ((fd = open(CONSOLE, O_WRONLY|O_NOCTTY)) != -1) 261 (void) write(fd, buf, strlen(buf) + 1); 262 (void) close(fd); 263 } 264