1 /* $OpenBSD: misc.c,v 1.18 2015/12/26 13:48:38 mestre Exp $ */ 2 /* $NetBSD: misc.c,v 1.6 1995/03/21 09:03:09 cgd Exp $ */ 3 4 /*- 5 * Copyright (c) 1980, 1991, 1993 6 * The Regents of the University of California. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. Neither the name of the University nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 */ 32 33 #include <sys/types.h> 34 #include <stdlib.h> 35 #include <unistd.h> 36 #include <stdarg.h> 37 38 #include "csh.h" 39 #include "extern.h" 40 41 static int renum(int, int); 42 43 int 44 any(char *s, int c) 45 { 46 if (!s) 47 return (0); /* Check for nil pointer */ 48 while (*s) 49 if (*s++ == c) 50 return (1); 51 return (0); 52 } 53 54 char * 55 strsave(char *s) 56 { 57 char *n; 58 char *p; 59 60 if (s == NULL) 61 s = ""; 62 for (p = s; *p++;) 63 continue; 64 n = p = xreallocarray(NULL, (p - s), sizeof(char)); 65 while ((*p++ = *s++) != '\0') 66 continue; 67 return (n); 68 } 69 70 Char ** 71 blkend(Char **up) 72 { 73 74 while (*up) 75 up++; 76 return (up); 77 } 78 79 80 void 81 blkpr(FILE *fp, Char **av) 82 { 83 84 for (; *av; av++) { 85 (void) fprintf(fp, "%s", vis_str(*av)); 86 if (av[1]) 87 (void) fprintf(fp, " "); 88 } 89 } 90 91 int 92 blklen(Char **av) 93 { 94 int i = 0; 95 96 while (*av++) 97 i++; 98 return (i); 99 } 100 101 Char ** 102 blkcpy(Char **oav, Char **bv) 103 { 104 Char **av = oav; 105 106 while ((*av++ = *bv++) != NULL) 107 continue; 108 return (oav); 109 } 110 111 Char ** 112 blkcat(Char **up, Char **vp) 113 { 114 115 (void) blkcpy(blkend(up), vp); 116 return (up); 117 } 118 119 void 120 blkfree(Char **av0) 121 { 122 Char **av = av0; 123 124 if (!av0) 125 return; 126 for (; *av; av++) 127 free(* av); 128 free(av0); 129 } 130 131 Char ** 132 saveblk(Char **v) 133 { 134 Char **newv = xcalloc((size_t) (blklen(v) + 1), sizeof(Char **)); 135 Char **onewv = newv; 136 137 while (*v) 138 *newv++ = Strsave(*v++); 139 return (onewv); 140 } 141 142 Char ** 143 blkspl(Char **up, Char **vp) 144 { 145 Char **wp = xcalloc((size_t) (blklen(up) + blklen(vp) + 1), 146 sizeof(Char **)); 147 148 (void) blkcpy(wp, up); 149 return (blkcat(wp, vp)); 150 } 151 152 Char 153 lastchr(Char *cp) 154 { 155 156 if (!cp) 157 return (0); 158 if (!*cp) 159 return (0); 160 while (cp[1]) 161 cp++; 162 return (*cp); 163 } 164 165 /* 166 * This routine is called after an error to close up 167 * any units which may have been left open accidentally. 168 */ 169 void 170 closem(void) 171 { 172 int f; 173 174 for (f = 0; f < sysconf(_SC_OPEN_MAX); f++) 175 if (f != SHIN && f != SHOUT && f != SHERR && f != OLDSTD && 176 f != FSHTTY) 177 (void) close(f); 178 } 179 180 void 181 donefds(void) 182 { 183 (void) close(0); 184 (void) close(1); 185 (void) close(2); 186 187 didfds = 0; 188 } 189 190 /* 191 * Move descriptor i to j. 192 * If j is -1 then we just want to get i to a safe place, 193 * i.e. to a unit > 2. This also happens in dcopy. 194 */ 195 int 196 dmove(int i, int j) 197 { 198 199 if (i == j || i < 0) 200 return (i); 201 if (j >= 0) { 202 (void) dup2(i, j); 203 if (j != i) 204 (void) close(i); 205 return (j); 206 } 207 j = dcopy(i, j); 208 if (j != i) 209 (void) close(i); 210 return (j); 211 } 212 213 int 214 dcopy(int i, int j) 215 { 216 217 if (i == j || i < 0 || (j < 0 && i > 2)) 218 return (i); 219 if (j >= 0) { 220 (void) dup2(i, j); 221 return (j); 222 } 223 (void) close(j); 224 return (renum(i, j)); 225 } 226 227 static int 228 renum(int i, int j) 229 { 230 int k = dup(i); 231 232 if (k < 0) 233 return (-1); 234 if (j == -1 && k > 2) 235 return (k); 236 if (k != j) { 237 j = renum(k, j); 238 (void) close(k); 239 return (j); 240 } 241 return (k); 242 } 243 244 /* 245 * Left shift a command argument list, discarding 246 * the first c arguments. Used in "shift" commands 247 * as well as by commands like "repeat". 248 */ 249 void 250 lshift(Char **v, int c) 251 { 252 Char **u; 253 254 for (u = v; *u && --c >= 0; u++) 255 free(*u); 256 (void) blkcpy(v, u); 257 } 258 259 int 260 number(Char *cp) 261 { 262 if (!cp) 263 return(0); 264 if (*cp == '-') { 265 cp++; 266 if (!Isdigit(*cp)) 267 return (0); 268 cp++; 269 } 270 while (*cp && Isdigit(*cp)) 271 cp++; 272 return (*cp == 0); 273 } 274 275 Char ** 276 copyblk(Char **v) 277 { 278 Char **nv = xcalloc((size_t) (blklen(v) + 1), sizeof(Char **)); 279 280 return (blkcpy(nv, v)); 281 } 282 283 Char * 284 strip(Char *cp) 285 { 286 Char *dp = cp; 287 288 if (!cp) 289 return (cp); 290 while ((*dp++ &= TRIM) != '\0') 291 continue; 292 return (cp); 293 } 294 295 Char * 296 quote(Char *cp) 297 { 298 Char *dp = cp; 299 300 if (!cp) 301 return (cp); 302 while (*dp != '\0') 303 *dp++ |= QUOTE; 304 return (cp); 305 } 306 307 void 308 udvar(Char *name) 309 { 310 311 setname(vis_str(name)); 312 stderror(ERR_NAME | ERR_UNDVAR); 313 } 314 315 int 316 prefix(Char *sub, Char *str) 317 { 318 319 for (;;) { 320 if (*sub == 0) 321 return (1); 322 if (*str == 0) 323 return (0); 324 if (*sub++ != *str++) 325 return (0); 326 } 327 } 328