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