xref: /original-bsd/bin/sh/miscbltin.c (revision 01e8f48f)
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  * %sccs.include.redist.c%
9  */
10 
11 #ifndef lint
12 static char sccsid[] = "@(#)miscbltin.c	8.3 (Berkeley) 04/27/95";
13 #endif /* not lint */
14 
15 /*
16  * Miscelaneous builtins.
17  */
18 
19 #include <sys/types.h>
20 #include <sys/stat.h>
21 #include "shell.h"
22 #include "options.h"
23 #include "var.h"
24 #include "output.h"
25 #include "memalloc.h"
26 #include "error.h"
27 #include "mystring.h"
28 
29 #undef eflag
30 
31 extern char **argptr;		/* argument list for builtin command */
32 
33 
34 /*
35  * The read builtin.  The -e option causes backslashes to escape the
36  * following character.
37  *
38  * This uses unbuffered input, which may be avoidable in some cases.
39  */
40 
41 readcmd(argc, argv)  char **argv; {
42 	char **ap;
43 	int backslash;
44 	char c;
45 	int eflag;
46 	char *prompt;
47 	char *ifs;
48 	char *p;
49 	int startword;
50 	int status;
51 	int i;
52 
53 	eflag = 0;
54 	prompt = NULL;
55 	while ((i = nextopt("ep:")) != '\0') {
56 		if (i == 'p')
57 			prompt = optarg;
58 		else
59 			eflag = 1;
60 	}
61 	if (prompt && isatty(0)) {
62 		out2str(prompt);
63 		flushall();
64 	}
65 	if (*(ap = argptr) == NULL)
66 		error("arg count");
67 	if ((ifs = bltinlookup("IFS", 1)) == NULL)
68 		ifs = nullstr;
69 	status = 0;
70 	startword = 1;
71 	backslash = 0;
72 	STARTSTACKSTR(p);
73 	for (;;) {
74 		if (read(0, &c, 1) != 1) {
75 			status = 1;
76 			break;
77 		}
78 		if (c == '\0')
79 			continue;
80 		if (backslash) {
81 			backslash = 0;
82 			if (c != '\n')
83 				STPUTC(c, p);
84 			continue;
85 		}
86 		if (eflag && c == '\\') {
87 			backslash++;
88 			continue;
89 		}
90 		if (c == '\n')
91 			break;
92 		if (startword && *ifs == ' ' && strchr(ifs, c)) {
93 			continue;
94 		}
95 		startword = 0;
96 		if (backslash && c == '\\') {
97 			if (read(0, &c, 1) != 1) {
98 				status = 1;
99 				break;
100 			}
101 			STPUTC(c, p);
102 		} else if (ap[1] != NULL && strchr(ifs, c) != NULL) {
103 			STACKSTRNUL(p);
104 			setvar(*ap, stackblock(), 0);
105 			ap++;
106 			startword = 1;
107 			STARTSTACKSTR(p);
108 		} else {
109 			STPUTC(c, p);
110 		}
111 	}
112 	STACKSTRNUL(p);
113 	setvar(*ap, stackblock(), 0);
114 	while (*++ap != NULL)
115 		setvar(*ap, nullstr, 0);
116 	return status;
117 }
118 
119 
120 
121 umaskcmd(argc, argv)  char **argv; {
122 	extern void *setmode();
123 	extern mode_t getmode();
124 	char *ap;
125 	int mask;
126 	int i;
127 	int symbolic_mode = 0;
128 
129 	while ((i = nextopt("S")) != '\0') {
130 		symbolic_mode = 1;
131 	}
132 
133 	INTOFF;
134 	mask = umask(0);
135 	umask(mask);
136 	INTON;
137 
138 	if ((ap = *argptr) == NULL) {
139 		if (symbolic_mode) {
140 			char u[4], g[4], o[4];
141 
142 			i = 0;
143 			if ((mask & S_IRUSR) == 0)
144 				u[i++] = 'r';
145 			if ((mask & S_IWUSR) == 0)
146 				u[i++] = 'w';
147 			if ((mask & S_IXUSR) == 0)
148 				u[i++] = 'x';
149 			u[i] = '\0';
150 
151 			i = 0;
152 			if ((mask & S_IRGRP) == 0)
153 				g[i++] = 'r';
154 			if ((mask & S_IWGRP) == 0)
155 				g[i++] = 'w';
156 			if ((mask & S_IXGRP) == 0)
157 				g[i++] = 'x';
158 			g[i] = '\0';
159 
160 			i = 0;
161 			if ((mask & S_IROTH) == 0)
162 				o[i++] = 'r';
163 			if ((mask & S_IWOTH) == 0)
164 				o[i++] = 'w';
165 			if ((mask & S_IXOTH) == 0)
166 				o[i++] = 'x';
167 			o[i] = '\0';
168 
169 			out1fmt("u=%s,g=%s,o=%s\n", u, g, o);
170 		} else {
171 			out1fmt("%.4o\n", mask);
172 		}
173 	} else {
174 		if (isdigit(*ap)) {
175 			mask = 0;
176 			do {
177 				if (*ap >= '8' || *ap < '0')
178 					error("Illegal number: %s", argv[1]);
179 				mask = (mask << 3) + (*ap - '0');
180 			} while (*++ap != '\0');
181 			umask(mask);
182 		} else {
183 			void *set;
184 			if ((set = setmode (ap)) == 0)
185 					error("Illegal number: %s", ap);
186 
187 			mask = getmode (set, ~mask & 0777);
188 			umask(~mask & 0777);
189 		}
190 	}
191 	return 0;
192 }
193