summaryrefslogtreecommitdiffstats
path: root/source/ap/ash/patches/ash-setmode.patch
diff options
context:
space:
mode:
author Patrick J Volkerding <volkerdi@slackware.com>2009-08-26 10:00:38 -0500
committer Eric Hameleers <alien@slackware.com>2018-05-31 22:41:17 +0200
commit5a12e7c134274dba706667107d10d231517d3e05 (patch)
tree55718d5acb710fde798d9f38d0bbaf594ed4b296 /source/ap/ash/patches/ash-setmode.patch
downloadcurrent-5a12e7c134274dba706667107d10d231517d3e05.tar.gz
current-5a12e7c134274dba706667107d10d231517d3e05.tar.xz
Slackware 13.0slackware-13.0
Wed Aug 26 10:00:38 CDT 2009 Slackware 13.0 x86_64 is released as stable! Thanks to everyone who helped make this release possible -- see the RELEASE_NOTES for the credits. The ISOs are off to the replicator. This time it will be a 6 CD-ROM 32-bit set and a dual-sided 32-bit/64-bit x86/x86_64 DVD. We're taking pre-orders now at store.slackware.com. Please consider picking up a copy to help support the project. Once again, thanks to the entire Slackware community for all the help testing and fixing things and offering suggestions during this development cycle. As always, have fun and enjoy! -P.
Diffstat (limited to 'source/ap/ash/patches/ash-setmode.patch')
-rw-r--r--source/ap/ash/patches/ash-setmode.patch510
1 files changed, 510 insertions, 0 deletions
diff --git a/source/ap/ash/patches/ash-setmode.patch b/source/ap/ash/patches/ash-setmode.patch
new file mode 100644
index 000000000..b9a26d9ca
--- /dev/null
+++ b/source/ap/ash/patches/ash-setmode.patch
@@ -0,0 +1,510 @@
+diff -urN netbsd-sh/miscbltin.c ash-0.3.7.orig/miscbltin.c
+--- netbsd-sh/miscbltin.c Fri Jan 12 17:50:37 2001
++++ ash-0.3.7.orig/miscbltin.c Mon Apr 23 22:16:46 2001
+@@ -70,6 +70,15 @@
+
+ #undef rflag
+
++#ifdef __GLIBC__
++mode_t getmode(const void *, mode_t);
++void *setmode(const char *);
++
++#if !defined(__GLIBC__) || __GLIBC__ == 2 && __GLIBC_MINOR__ < 1
++typedef enum __rlimit_resource rlim_t;
++#endif
++#endif
++
+ extern char **argptr; /* argument list for builtin command */
+
+
+diff -urN netbsd-sh/setmode.c ash-0.3.7.orig/setmode.c
+--- netbsd-sh/setmode.c Thu Jan 1 01:00:00 1970
++++ ash-0.3.7.orig/setmode.c Mon Apr 23 22:16:46 2001
+@@ -0,0 +1,486 @@
++/* $NetBSD: setmode.c,v 1.28 2000/01/25 15:43:43 enami Exp $ */
++
++/*
++ * Copyright (c) 1989, 1993, 1994
++ * The Regents of the University of California. All rights reserved.
++ *
++ * This code is derived from software contributed to Berkeley by
++ * Dave Borman at Cray Research, Inc.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the above copyright
++ * notice, this list of conditions and the following disclaimer.
++ * 2. Redistributions in binary form must reproduce the above copyright
++ * notice, this list of conditions and the following disclaimer in the
++ * documentation and/or other materials provided with the distribution.
++ * 3. All advertising materials mentioning features or use of this software
++ * must display the following acknowledgement:
++ * This product includes software developed by the University of
++ * California, Berkeley and its contributors.
++ * 4. Neither the name of the University nor the names of its contributors
++ * may be used to endorse or promote products derived from this software
++ * without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
++ * SUCH DAMAGE.
++ */
++
++#include <sys/cdefs.h>
++#if defined(LIBC_SCCS) && !defined(lint)
++#if 0
++static char sccsid[] = "@(#)setmode.c 8.2 (Berkeley) 3/25/94";
++#else
++__RCSID("$NetBSD: setmode.c,v 1.28 2000/01/25 15:43:43 enami Exp $");
++#endif
++#endif /* LIBC_SCCS and not lint */
++
++#include <sys/types.h>
++#include <sys/stat.h>
++
++#include <assert.h>
++#include <ctype.h>
++#include <errno.h>
++#include <signal.h>
++#include <stdlib.h>
++#include <unistd.h>
++
++#ifdef SETMODE_DEBUG
++#include <stdio.h>
++#endif
++
++#ifdef __weak_alias
++__weak_alias(getmode,_getmode)
++__weak_alias(setmode,_setmode)
++#endif
++
++#ifdef __GLIBC__
++#define S_ISTXT __S_ISVTX
++#endif
++
++#define SET_LEN 6 /* initial # of bitcmd struct to malloc */
++#define SET_LEN_INCR 4 /* # of bitcmd structs to add as needed */
++
++typedef struct bitcmd {
++ char cmd;
++ char cmd2;
++ mode_t bits;
++} BITCMD;
++
++#define CMD2_CLR 0x01
++#define CMD2_SET 0x02
++#define CMD2_GBITS 0x04
++#define CMD2_OBITS 0x08
++#define CMD2_UBITS 0x10
++
++static BITCMD *addcmd __P((BITCMD *, int, int, int, u_int));
++static void compress_mode __P((BITCMD *));
++#ifdef SETMODE_DEBUG
++static void dumpmode __P((BITCMD *));
++#endif
++
++/*
++ * Given the old mode and an array of bitcmd structures, apply the operations
++ * described in the bitcmd structures to the old mode, and return the new mode.
++ * Note that there is no '=' command; a strict assignment is just a '-' (clear
++ * bits) followed by a '+' (set bits).
++ */
++mode_t
++getmode(bbox, omode)
++ const void *bbox;
++ mode_t omode;
++{
++ const BITCMD *set;
++ mode_t clrval, newmode, value;
++
++ _DIAGASSERT(bbox != NULL);
++
++ set = (const BITCMD *)bbox;
++ newmode = omode;
++ for (value = 0;; set++)
++ switch(set->cmd) {
++ /*
++ * When copying the user, group or other bits around, we "know"
++ * where the bits are in the mode so that we can do shifts to
++ * copy them around. If we don't use shifts, it gets real
++ * grundgy with lots of single bit checks and bit sets.
++ */
++ case 'u':
++ value = (newmode & S_IRWXU) >> 6;
++ goto common;
++
++ case 'g':
++ value = (newmode & S_IRWXG) >> 3;
++ goto common;
++
++ case 'o':
++ value = newmode & S_IRWXO;
++common: if (set->cmd2 & CMD2_CLR) {
++ clrval =
++ (set->cmd2 & CMD2_SET) ? S_IRWXO : value;
++ if (set->cmd2 & CMD2_UBITS)
++ newmode &= ~((clrval<<6) & set->bits);
++ if (set->cmd2 & CMD2_GBITS)
++ newmode &= ~((clrval<<3) & set->bits);
++ if (set->cmd2 & CMD2_OBITS)
++ newmode &= ~(clrval & set->bits);
++ }
++ if (set->cmd2 & CMD2_SET) {
++ if (set->cmd2 & CMD2_UBITS)
++ newmode |= (value<<6) & set->bits;
++ if (set->cmd2 & CMD2_GBITS)
++ newmode |= (value<<3) & set->bits;
++ if (set->cmd2 & CMD2_OBITS)
++ newmode |= value & set->bits;
++ }
++ break;
++
++ case '+':
++ newmode |= set->bits;
++ break;
++
++ case '-':
++ newmode &= ~set->bits;
++ break;
++
++ case 'X':
++ if (omode & (S_IFDIR|S_IXUSR|S_IXGRP|S_IXOTH))
++ newmode |= set->bits;
++ break;
++
++ case '\0':
++ default:
++#ifdef SETMODE_DEBUG
++ (void)printf("getmode:%04o -> %04o\n", omode, newmode);
++#endif
++ return (newmode);
++ }
++}
++
++#define ADDCMD(a, b, c, d) do { \
++ if (set >= endset) { \
++ BITCMD *newset; \
++ setlen += SET_LEN_INCR; \
++ newset = realloc(saveset, sizeof(BITCMD) * setlen); \
++ if (newset == NULL) { \
++ free(saveset); \
++ return (NULL); \
++ } \
++ set = newset + (set - saveset); \
++ saveset = newset; \
++ endset = newset + (setlen - 2); \
++ } \
++ set = addcmd(set, (a), (b), (c), (d)); \
++} while (/*CONSTCOND*/0)
++
++#define STANDARD_BITS (S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO)
++
++void *
++setmode(p)
++ const char *p;
++{
++ int perm, who;
++ char op, *ep;
++ BITCMD *set, *saveset, *endset;
++ sigset_t sigset, sigoset;
++ mode_t mask;
++ int equalopdone = 0; /* pacify gcc */
++ int permXbits, setlen;
++
++ if (!*p)
++ return (NULL);
++
++ /*
++ * Get a copy of the mask for the permissions that are mask relative.
++ * Flip the bits, we want what's not set. Since it's possible that
++ * the caller is opening files inside a signal handler, protect them
++ * as best we can.
++ */
++ sigfillset(&sigset);
++ (void)sigprocmask(SIG_BLOCK, &sigset, &sigoset);
++ (void)umask(mask = umask(0));
++ mask = ~mask;
++ (void)sigprocmask(SIG_SETMASK, &sigoset, NULL);
++
++ setlen = SET_LEN + 2;
++
++ if ((set = malloc((u_int)(sizeof(BITCMD) * setlen))) == NULL)
++ return (NULL);
++ saveset = set;
++ endset = set + (setlen - 2);
++
++ /*
++ * If an absolute number, get it and return; disallow non-octal digits
++ * or illegal bits.
++ */
++ if (isdigit((unsigned char)*p)) {
++ perm = (mode_t)strtol(p, &ep, 8);
++ if (*ep || perm & ~(STANDARD_BITS|S_ISTXT)) {
++ free(saveset);
++ return (NULL);
++ }
++ ADDCMD('=', (STANDARD_BITS|S_ISTXT), perm, mask);
++ set->cmd = 0;
++ return (saveset);
++ }
++
++ /*
++ * Build list of structures to set/clear/copy bits as described by
++ * each clause of the symbolic mode.
++ */
++ for (;;) {
++ /* First, find out which bits might be modified. */
++ for (who = 0;; ++p) {
++ switch (*p) {
++ case 'a':
++ who |= STANDARD_BITS;
++ break;
++ case 'u':
++ who |= S_ISUID|S_IRWXU;
++ break;
++ case 'g':
++ who |= S_ISGID|S_IRWXG;
++ break;
++ case 'o':
++ who |= S_IRWXO;
++ break;
++ default:
++ goto getop;
++ }
++ }
++
++getop: if ((op = *p++) != '+' && op != '-' && op != '=') {
++ free(saveset);
++ return (NULL);
++ }
++ if (op == '=')
++ equalopdone = 0;
++
++ who &= ~S_ISTXT;
++ for (perm = 0, permXbits = 0;; ++p) {
++ switch (*p) {
++ case 'r':
++ perm |= S_IRUSR|S_IRGRP|S_IROTH;
++ break;
++ case 's':
++ /*
++ * If specific bits where requested and
++ * only "other" bits ignore set-id.
++ */
++ if (who == 0 || (who & ~S_IRWXO))
++ perm |= S_ISUID|S_ISGID;
++ break;
++ case 't':
++ /*
++ * If specific bits where requested and
++ * only "other" bits ignore set-id.
++ */
++ if (who == 0 || (who & ~S_IRWXO)) {
++ who |= S_ISTXT;
++ perm |= S_ISTXT;
++ }
++ break;
++ case 'w':
++ perm |= S_IWUSR|S_IWGRP|S_IWOTH;
++ break;
++ case 'X':
++ permXbits = S_IXUSR|S_IXGRP|S_IXOTH;
++ break;
++ case 'x':
++ perm |= S_IXUSR|S_IXGRP|S_IXOTH;
++ break;
++ case 'u':
++ case 'g':
++ case 'o':
++ /*
++ * When ever we hit 'u', 'g', or 'o', we have
++ * to flush out any partial mode that we have,
++ * and then do the copying of the mode bits.
++ */
++ if (perm) {
++ ADDCMD(op, who, perm, mask);
++ perm = 0;
++ }
++ if (op == '=')
++ equalopdone = 1;
++ if (op == '+' && permXbits) {
++ ADDCMD('X', who, permXbits, mask);
++ permXbits = 0;
++ }
++ ADDCMD(*p, who, op, mask);
++ break;
++
++ default:
++ /*
++ * Add any permissions that we haven't already
++ * done.
++ */
++ if (perm || (op == '=' && !equalopdone)) {
++ if (op == '=')
++ equalopdone = 1;
++ ADDCMD(op, who, perm, mask);
++ perm = 0;
++ }
++ if (permXbits) {
++ ADDCMD('X', who, permXbits, mask);
++ permXbits = 0;
++ }
++ goto apply;
++ }
++ }
++
++apply: if (!*p)
++ break;
++ if (*p != ',')
++ goto getop;
++ ++p;
++ }
++ set->cmd = 0;
++#ifdef SETMODE_DEBUG
++ (void)printf("Before compress_mode()\n");
++ dumpmode(saveset);
++#endif
++ compress_mode(saveset);
++#ifdef SETMODE_DEBUG
++ (void)printf("After compress_mode()\n");
++ dumpmode(saveset);
++#endif
++ return (saveset);
++}
++
++static BITCMD *
++addcmd(set, op, who, oparg, mask)
++ BITCMD *set;
++ int oparg, who;
++ int op;
++ u_int mask;
++{
++
++ _DIAGASSERT(set != NULL);
++
++ switch (op) {
++ case '=':
++ set->cmd = '-';
++ set->bits = who ? who : STANDARD_BITS;
++ set++;
++
++ op = '+';
++ /* FALLTHROUGH */
++ case '+':
++ case '-':
++ case 'X':
++ set->cmd = op;
++ set->bits = (who ? who : mask) & oparg;
++ break;
++
++ case 'u':
++ case 'g':
++ case 'o':
++ set->cmd = op;
++ if (who) {
++ set->cmd2 = ((who & S_IRUSR) ? CMD2_UBITS : 0) |
++ ((who & S_IRGRP) ? CMD2_GBITS : 0) |
++ ((who & S_IROTH) ? CMD2_OBITS : 0);
++ set->bits = (mode_t)~0;
++ } else {
++ set->cmd2 = CMD2_UBITS | CMD2_GBITS | CMD2_OBITS;
++ set->bits = mask;
++ }
++
++ if (oparg == '+')
++ set->cmd2 |= CMD2_SET;
++ else if (oparg == '-')
++ set->cmd2 |= CMD2_CLR;
++ else if (oparg == '=')
++ set->cmd2 |= CMD2_SET|CMD2_CLR;
++ break;
++ }
++ return (set + 1);
++}
++
++#ifdef SETMODE_DEBUG
++static void
++dumpmode(set)
++ BITCMD *set;
++{
++
++ _DIAGASSERT(set != NULL);
++
++ for (; set->cmd; ++set)
++ (void)printf("cmd: '%c' bits %04o%s%s%s%s%s%s\n",
++ set->cmd, set->bits, set->cmd2 ? " cmd2:" : "",
++ set->cmd2 & CMD2_CLR ? " CLR" : "",
++ set->cmd2 & CMD2_SET ? " SET" : "",
++ set->cmd2 & CMD2_UBITS ? " UBITS" : "",
++ set->cmd2 & CMD2_GBITS ? " GBITS" : "",
++ set->cmd2 & CMD2_OBITS ? " OBITS" : "");
++}
++#endif
++
++/*
++ * Given an array of bitcmd structures, compress by compacting consecutive
++ * '+', '-' and 'X' commands into at most 3 commands, one of each. The 'u',
++ * 'g' and 'o' commands continue to be separate. They could probably be
++ * compacted, but it's not worth the effort.
++ */
++static void
++compress_mode(set)
++ BITCMD *set;
++{
++ BITCMD *nset;
++ int setbits, clrbits, Xbits, op;
++
++ _DIAGASSERT(set != NULL);
++
++ for (nset = set;;) {
++ /* Copy over any 'u', 'g' and 'o' commands. */
++ while ((op = nset->cmd) != '+' && op != '-' && op != 'X') {
++ *set++ = *nset++;
++ if (!op)
++ return;
++ }
++
++ for (setbits = clrbits = Xbits = 0;; nset++) {
++ if ((op = nset->cmd) == '-') {
++ clrbits |= nset->bits;
++ setbits &= ~nset->bits;
++ Xbits &= ~nset->bits;
++ } else if (op == '+') {
++ setbits |= nset->bits;
++ clrbits &= ~nset->bits;
++ Xbits &= ~nset->bits;
++ } else if (op == 'X')
++ Xbits |= nset->bits & ~setbits;
++ else
++ break;
++ }
++ if (clrbits) {
++ set->cmd = '-';
++ set->cmd2 = 0;
++ set->bits = clrbits;
++ set++;
++ }
++ if (setbits) {
++ set->cmd = '+';
++ set->cmd2 = 0;
++ set->bits = setbits;
++ set++;
++ }
++ if (Xbits) {
++ set->cmd = 'X';
++ set->cmd2 = 0;
++ set->bits = Xbits;
++ set++;
++ }
++ }
++}
+