1 /* $NetBSD: miscbltin.c,v 1.13 1995/03/21 09:09:33 cgd Exp $ */ 2 3 /*- 4 * Copyright (c) 1991, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * This code is derived from software contributed to Berkeley by 8 * Kenneth Almquist. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the University of 21 * California, Berkeley and its contributors. 22 * 4. Neither the name of the University nor the names of its contributors 23 * may be used to endorse or promote products derived from this software 24 * without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 29 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36 * SUCH DAMAGE. 37 */ 38 39 #ifndef lint 40 #if 0 41 static char sccsid[] = "@(#)miscbltin.c 8.2 (Berkeley) 4/16/94"; 42 #else 43 static char rcsid[] = "$NetBSD: miscbltin.c,v 1.13 1995/03/21 09:09:33 cgd Exp $"; 44 #endif 45 #endif /* not lint */ 46 47 /* 48 * Miscelaneous builtins. 49 */ 50 51 #include <sys/types.h> 52 #include <sys/stat.h> 53 #include <unistd.h> 54 #include <ctype.h> 55 #include "shell.h" 56 #include "options.h" 57 #include "var.h" 58 #include "output.h" 59 #include "memalloc.h" 60 #include "error.h" 61 #include "mystring.h" 62 63 #undef eflag 64 65 extern char **argptr; /* argument list for builtin command */ 66 67 68 /* 69 * The read builtin. The -e option causes backslashes to escape the 70 * following character. 71 * 72 * This uses unbuffered input, which may be avoidable in some cases. 73 */ 74 75 int 76 readcmd(argc, argv) 77 int argc; 78 char **argv; 79 { 80 char **ap; 81 int backslash; 82 char c; 83 int eflag; 84 char *prompt; 85 char *ifs; 86 char *p; 87 int startword; 88 int status; 89 int i; 90 91 eflag = 0; 92 prompt = NULL; 93 while ((i = nextopt("ep:")) != '\0') { 94 if (i == 'p') 95 prompt = optarg; 96 else 97 eflag = 1; 98 } 99 if (prompt && isatty(0)) { 100 out2str(prompt); 101 flushall(); 102 } 103 if (*(ap = argptr) == NULL) 104 error("arg count"); 105 if ((ifs = bltinlookup("IFS", 1)) == NULL) 106 ifs = nullstr; 107 status = 0; 108 startword = 1; 109 backslash = 0; 110 STARTSTACKSTR(p); 111 for (;;) { 112 if (read(0, &c, 1) != 1) { 113 status = 1; 114 break; 115 } 116 if (c == '\0') 117 continue; 118 if (backslash) { 119 backslash = 0; 120 if (c != '\n') 121 STPUTC(c, p); 122 continue; 123 } 124 if (eflag && c == '\\') { 125 backslash++; 126 continue; 127 } 128 if (c == '\n') 129 break; 130 if (startword && *ifs == ' ' && strchr(ifs, c)) { 131 continue; 132 } 133 startword = 0; 134 if (backslash && c == '\\') { 135 if (read(0, &c, 1) != 1) { 136 status = 1; 137 break; 138 } 139 STPUTC(c, p); 140 } else if (ap[1] != NULL && strchr(ifs, c) != NULL) { 141 STACKSTRNUL(p); 142 setvar(*ap, stackblock(), 0); 143 ap++; 144 startword = 1; 145 STARTSTACKSTR(p); 146 } else { 147 STPUTC(c, p); 148 } 149 } 150 STACKSTRNUL(p); 151 setvar(*ap, stackblock(), 0); 152 while (*++ap != NULL) 153 setvar(*ap, nullstr, 0); 154 return status; 155 } 156 157 158 159 int 160 umaskcmd(argc, argv) 161 int argc; 162 char **argv; 163 { 164 char *ap; 165 int mask; 166 int i; 167 int symbolic_mode = 0; 168 169 while ((i = nextopt("S")) != '\0') { 170 symbolic_mode = 1; 171 } 172 173 INTOFF; 174 mask = umask(0); 175 umask(mask); 176 INTON; 177 178 if ((ap = *argptr) == NULL) { 179 if (symbolic_mode) { 180 char u[4], g[4], o[4]; 181 182 i = 0; 183 if ((mask & S_IRUSR) == 0) 184 u[i++] = 'r'; 185 if ((mask & S_IWUSR) == 0) 186 u[i++] = 'w'; 187 if ((mask & S_IXUSR) == 0) 188 u[i++] = 'x'; 189 u[i] = '\0'; 190 191 i = 0; 192 if ((mask & S_IRGRP) == 0) 193 g[i++] = 'r'; 194 if ((mask & S_IWGRP) == 0) 195 g[i++] = 'w'; 196 if ((mask & S_IXGRP) == 0) 197 g[i++] = 'x'; 198 g[i] = '\0'; 199 200 i = 0; 201 if ((mask & S_IROTH) == 0) 202 o[i++] = 'r'; 203 if ((mask & S_IWOTH) == 0) 204 o[i++] = 'w'; 205 if ((mask & S_IXOTH) == 0) 206 o[i++] = 'x'; 207 o[i] = '\0'; 208 209 out1fmt("u=%s,g=%s,o=%s\n", u, g, o); 210 } else { 211 out1fmt("%.4o\n", mask); 212 } 213 } else { 214 if (isdigit(*ap)) { 215 mask = 0; 216 do { 217 if (*ap >= '8' || *ap < '0') 218 error("Illegal number: %s", argv[1]); 219 mask = (mask << 3) + (*ap - '0'); 220 } while (*++ap != '\0'); 221 umask(mask); 222 } else { 223 void *set; 224 if ((set = setmode (ap)) == 0) 225 error("Illegal number: %s", ap); 226 227 mask = getmode (set, ~mask & 0777); 228 umask(~mask & 0777); 229 } 230 } 231 return 0; 232 } 233