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