1 diff -urN netbsd-sh/miscbltin.c ash-0.3.7.orig/miscbltin.c
2 --- netbsd-sh/miscbltin.c Fri Jan 12 17:50:37 2001
3 +++ ash-0.3.7.orig/miscbltin.c Mon Apr 23 22:16:46 2001
9 +mode_t getmode(const void *, mode_t);
10 +void *setmode(const char *);
12 +#if !defined(__GLIBC__) || __GLIBC__ == 2 && __GLIBC_MINOR__ < 1
13 +typedef enum __rlimit_resource rlim_t;
17 extern char **argptr; /* argument list for builtin command */
20 diff -urN netbsd-sh/setmode.c ash-0.3.7.orig/setmode.c
21 --- netbsd-sh/setmode.c Thu Jan 1 01:00:00 1970
22 +++ ash-0.3.7.orig/setmode.c Mon Apr 23 22:16:46 2001
24 +/* $NetBSD: setmode.c,v 1.28 2000/01/25 15:43:43 enami Exp $ */
27 + * Copyright (c) 1989, 1993, 1994
28 + * The Regents of the University of California. All rights reserved.
30 + * This code is derived from software contributed to Berkeley by
31 + * Dave Borman at Cray Research, Inc.
33 + * Redistribution and use in source and binary forms, with or without
34 + * modification, are permitted provided that the following conditions
36 + * 1. Redistributions of source code must retain the above copyright
37 + * notice, this list of conditions and the following disclaimer.
38 + * 2. Redistributions in binary form must reproduce the above copyright
39 + * notice, this list of conditions and the following disclaimer in the
40 + * documentation and/or other materials provided with the distribution.
41 + * 3. All advertising materials mentioning features or use of this software
42 + * must display the following acknowledgement:
43 + * This product includes software developed by the University of
44 + * California, Berkeley and its contributors.
45 + * 4. Neither the name of the University nor the names of its contributors
46 + * may be used to endorse or promote products derived from this software
47 + * without specific prior written permission.
49 + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
50 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
51 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
52 + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
53 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
54 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
55 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
56 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
57 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
58 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
62 +#include <sys/cdefs.h>
63 +#if defined(LIBC_SCCS) && !defined(lint)
65 +static char sccsid[] = "@(#)setmode.c 8.2 (Berkeley) 3/25/94";
67 +__RCSID("$NetBSD: setmode.c,v 1.28 2000/01/25 15:43:43 enami Exp $");
69 +#endif /* LIBC_SCCS and not lint */
71 +#include <sys/types.h>
72 +#include <sys/stat.h>
86 +__weak_alias(getmode,_getmode)
87 +__weak_alias(setmode,_setmode)
91 +#define S_ISTXT __S_ISVTX
94 +#define SET_LEN 6 /* initial # of bitcmd struct to malloc */
95 +#define SET_LEN_INCR 4 /* # of bitcmd structs to add as needed */
97 +typedef struct bitcmd {
103 +#define CMD2_CLR 0x01
104 +#define CMD2_SET 0x02
105 +#define CMD2_GBITS 0x04
106 +#define CMD2_OBITS 0x08
107 +#define CMD2_UBITS 0x10
109 +static BITCMD *addcmd __P((BITCMD *, int, int, int, u_int));
110 +static void compress_mode __P((BITCMD *));
111 +#ifdef SETMODE_DEBUG
112 +static void dumpmode __P((BITCMD *));
116 + * Given the old mode and an array of bitcmd structures, apply the operations
117 + * described in the bitcmd structures to the old mode, and return the new mode.
118 + * Note that there is no '=' command; a strict assignment is just a '-' (clear
119 + * bits) followed by a '+' (set bits).
122 +getmode(bbox, omode)
127 + mode_t clrval, newmode, value;
129 + _DIAGASSERT(bbox != NULL);
131 + set = (const BITCMD *)bbox;
133 + for (value = 0;; set++)
136 + * When copying the user, group or other bits around, we "know"
137 + * where the bits are in the mode so that we can do shifts to
138 + * copy them around. If we don't use shifts, it gets real
139 + * grundgy with lots of single bit checks and bit sets.
142 + value = (newmode & S_IRWXU) >> 6;
146 + value = (newmode & S_IRWXG) >> 3;
150 + value = newmode & S_IRWXO;
151 +common: if (set->cmd2 & CMD2_CLR) {
153 + (set->cmd2 & CMD2_SET) ? S_IRWXO : value;
154 + if (set->cmd2 & CMD2_UBITS)
155 + newmode &= ~((clrval<<6) & set->bits);
156 + if (set->cmd2 & CMD2_GBITS)
157 + newmode &= ~((clrval<<3) & set->bits);
158 + if (set->cmd2 & CMD2_OBITS)
159 + newmode &= ~(clrval & set->bits);
161 + if (set->cmd2 & CMD2_SET) {
162 + if (set->cmd2 & CMD2_UBITS)
163 + newmode |= (value<<6) & set->bits;
164 + if (set->cmd2 & CMD2_GBITS)
165 + newmode |= (value<<3) & set->bits;
166 + if (set->cmd2 & CMD2_OBITS)
167 + newmode |= value & set->bits;
172 + newmode |= set->bits;
176 + newmode &= ~set->bits;
180 + if (omode & (S_IFDIR|S_IXUSR|S_IXGRP|S_IXOTH))
181 + newmode |= set->bits;
186 +#ifdef SETMODE_DEBUG
187 + (void)printf("getmode:%04o -> %04o\n", omode, newmode);
193 +#define ADDCMD(a, b, c, d) do { \
194 + if (set >= endset) { \
196 + setlen += SET_LEN_INCR; \
197 + newset = realloc(saveset, sizeof(BITCMD) * setlen); \
198 + if (newset == NULL) { \
202 + set = newset + (set - saveset); \
203 + saveset = newset; \
204 + endset = newset + (setlen - 2); \
206 + set = addcmd(set, (a), (b), (c), (d)); \
207 +} while (/*CONSTCOND*/0)
209 +#define STANDARD_BITS (S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO)
217 + BITCMD *set, *saveset, *endset;
218 + sigset_t sigset, sigoset;
220 + int equalopdone = 0; /* pacify gcc */
221 + int permXbits, setlen;
227 + * Get a copy of the mask for the permissions that are mask relative.
228 + * Flip the bits, we want what's not set. Since it's possible that
229 + * the caller is opening files inside a signal handler, protect them
232 + sigfillset(&sigset);
233 + (void)sigprocmask(SIG_BLOCK, &sigset, &sigoset);
234 + (void)umask(mask = umask(0));
236 + (void)sigprocmask(SIG_SETMASK, &sigoset, NULL);
238 + setlen = SET_LEN + 2;
240 + if ((set = malloc((u_int)(sizeof(BITCMD) * setlen))) == NULL)
243 + endset = set + (setlen - 2);
246 + * If an absolute number, get it and return; disallow non-octal digits
249 + if (isdigit((unsigned char)*p)) {
250 + perm = (mode_t)strtol(p, &ep, 8);
251 + if (*ep || perm & ~(STANDARD_BITS|S_ISTXT)) {
255 + ADDCMD('=', (STANDARD_BITS|S_ISTXT), perm, mask);
261 + * Build list of structures to set/clear/copy bits as described by
262 + * each clause of the symbolic mode.
265 + /* First, find out which bits might be modified. */
266 + for (who = 0;; ++p) {
269 + who |= STANDARD_BITS;
272 + who |= S_ISUID|S_IRWXU;
275 + who |= S_ISGID|S_IRWXG;
285 +getop: if ((op = *p++) != '+' && op != '-' && op != '=') {
293 + for (perm = 0, permXbits = 0;; ++p) {
296 + perm |= S_IRUSR|S_IRGRP|S_IROTH;
300 + * If specific bits where requested and
301 + * only "other" bits ignore set-id.
303 + if (who == 0 || (who & ~S_IRWXO))
304 + perm |= S_ISUID|S_ISGID;
308 + * If specific bits where requested and
309 + * only "other" bits ignore set-id.
311 + if (who == 0 || (who & ~S_IRWXO)) {
317 + perm |= S_IWUSR|S_IWGRP|S_IWOTH;
320 + permXbits = S_IXUSR|S_IXGRP|S_IXOTH;
323 + perm |= S_IXUSR|S_IXGRP|S_IXOTH;
329 + * When ever we hit 'u', 'g', or 'o', we have
330 + * to flush out any partial mode that we have,
331 + * and then do the copying of the mode bits.
334 + ADDCMD(op, who, perm, mask);
339 + if (op == '+' && permXbits) {
340 + ADDCMD('X', who, permXbits, mask);
343 + ADDCMD(*p, who, op, mask);
348 + * Add any permissions that we haven't already
351 + if (perm || (op == '=' && !equalopdone)) {
354 + ADDCMD(op, who, perm, mask);
358 + ADDCMD('X', who, permXbits, mask);
372 +#ifdef SETMODE_DEBUG
373 + (void)printf("Before compress_mode()\n");
376 + compress_mode(saveset);
377 +#ifdef SETMODE_DEBUG
378 + (void)printf("After compress_mode()\n");
385 +addcmd(set, op, who, oparg, mask)
392 + _DIAGASSERT(set != NULL);
397 + set->bits = who ? who : STANDARD_BITS;
406 + set->bits = (who ? who : mask) & oparg;
414 + set->cmd2 = ((who & S_IRUSR) ? CMD2_UBITS : 0) |
415 + ((who & S_IRGRP) ? CMD2_GBITS : 0) |
416 + ((who & S_IROTH) ? CMD2_OBITS : 0);
417 + set->bits = (mode_t)~0;
419 + set->cmd2 = CMD2_UBITS | CMD2_GBITS | CMD2_OBITS;
424 + set->cmd2 |= CMD2_SET;
425 + else if (oparg == '-')
426 + set->cmd2 |= CMD2_CLR;
427 + else if (oparg == '=')
428 + set->cmd2 |= CMD2_SET|CMD2_CLR;
434 +#ifdef SETMODE_DEBUG
440 + _DIAGASSERT(set != NULL);
442 + for (; set->cmd; ++set)
443 + (void)printf("cmd: '%c' bits %04o%s%s%s%s%s%s\n",
444 + set->cmd, set->bits, set->cmd2 ? " cmd2:" : "",
445 + set->cmd2 & CMD2_CLR ? " CLR" : "",
446 + set->cmd2 & CMD2_SET ? " SET" : "",
447 + set->cmd2 & CMD2_UBITS ? " UBITS" : "",
448 + set->cmd2 & CMD2_GBITS ? " GBITS" : "",
449 + set->cmd2 & CMD2_OBITS ? " OBITS" : "");
454 + * Given an array of bitcmd structures, compress by compacting consecutive
455 + * '+', '-' and 'X' commands into at most 3 commands, one of each. The 'u',
456 + * 'g' and 'o' commands continue to be separate. They could probably be
457 + * compacted, but it's not worth the effort.
464 + int setbits, clrbits, Xbits, op;
466 + _DIAGASSERT(set != NULL);
468 + for (nset = set;;) {
469 + /* Copy over any 'u', 'g' and 'o' commands. */
470 + while ((op = nset->cmd) != '+' && op != '-' && op != 'X') {
476 + for (setbits = clrbits = Xbits = 0;; nset++) {
477 + if ((op = nset->cmd) == '-') {
478 + clrbits |= nset->bits;
479 + setbits &= ~nset->bits;
480 + Xbits &= ~nset->bits;
481 + } else if (op == '+') {
482 + setbits |= nset->bits;
483 + clrbits &= ~nset->bits;
484 + Xbits &= ~nset->bits;
485 + } else if (op == 'X')
486 + Xbits |= nset->bits & ~setbits;
493 + set->bits = clrbits;
499 + set->bits = setbits;