1 /* $OpenBSD: misc.c,v 1.19 2016/08/14 19:45:24 guenther 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 int max = sysconf(_SC_OPEN_MAX); 174 175 for (f = 0; f < max; f++) 176 if (f != SHIN && f != SHOUT && f != SHERR && f != OLDSTD && 177 f != FSHTTY) 178 (void) close(f); 179 } 180 181 void 182 donefds(void) 183 { 184 (void) close(0); 185 (void) close(1); 186 (void) close(2); 187 188 didfds = 0; 189 } 190 191 /* 192 * Move descriptor i to j. 193 * If j is -1 then we just want to get i to a safe place, 194 * i.e. to a unit > 2. This also happens in dcopy. 195 */ 196 int 197 dmove(int i, int j) 198 { 199 200 if (i == j || i < 0) 201 return (i); 202 if (j >= 0) { 203 (void) dup2(i, j); 204 if (j != i) 205 (void) close(i); 206 return (j); 207 } 208 j = dcopy(i, j); 209 if (j != i) 210 (void) close(i); 211 return (j); 212 } 213 214 int 215 dcopy(int i, int j) 216 { 217 218 if (i == j || i < 0 || (j < 0 && i > 2)) 219 return (i); 220 if (j >= 0) { 221 (void) dup2(i, j); 222 return (j); 223 } 224 (void) close(j); 225 return (renum(i, j)); 226 } 227 228 static int 229 renum(int i, int j) 230 { 231 int k = dup(i); 232 233 if (k < 0) 234 return (-1); 235 if (j == -1 && k > 2) 236 return (k); 237 if (k != j) { 238 j = renum(k, j); 239 (void) close(k); 240 return (j); 241 } 242 return (k); 243 } 244 245 /* 246 * Left shift a command argument list, discarding 247 * the first c arguments. Used in "shift" commands 248 * as well as by commands like "repeat". 249 */ 250 void 251 lshift(Char **v, int c) 252 { 253 Char **u; 254 255 for (u = v; *u && --c >= 0; u++) 256 free(*u); 257 (void) blkcpy(v, u); 258 } 259 260 int 261 number(Char *cp) 262 { 263 if (!cp) 264 return(0); 265 if (*cp == '-') { 266 cp++; 267 if (!Isdigit(*cp)) 268 return (0); 269 cp++; 270 } 271 while (*cp && Isdigit(*cp)) 272 cp++; 273 return (*cp == 0); 274 } 275 276 Char ** 277 copyblk(Char **v) 278 { 279 Char **nv = xcalloc((size_t) (blklen(v) + 1), sizeof(Char **)); 280 281 return (blkcpy(nv, v)); 282 } 283 284 Char * 285 strip(Char *cp) 286 { 287 Char *dp = cp; 288 289 if (!cp) 290 return (cp); 291 while ((*dp++ &= TRIM) != '\0') 292 continue; 293 return (cp); 294 } 295 296 Char * 297 quote(Char *cp) 298 { 299 Char *dp = cp; 300 301 if (!cp) 302 return (cp); 303 while (*dp != '\0') 304 *dp++ |= QUOTE; 305 return (cp); 306 } 307 308 void 309 udvar(Char *name) 310 { 311 312 setname(vis_str(name)); 313 stderror(ERR_NAME | ERR_UNDVAR); 314 } 315 316 int 317 prefix(Char *sub, Char *str) 318 { 319 320 for (;;) { 321 if (*sub == 0) 322 return (1); 323 if (*str == 0) 324 return (0); 325 if (*sub++ != *str++) 326 return (0); 327 } 328 } 329