From decwrl!shlump.nac.dec.com!decuac!haven!aplcen!uunet!allbery Tue Jan 30 08:42:57 PST 1990
Article 1290 of comp.sources.misc:
Path: decwrl!shlump.nac.dec.com!decuac!haven!aplcen!uunet!allbery
From: brian@apt.UUCP (Brian Litzinger)
Newsgroups: comp.sources.misc
Subject: v10i025: chall source program submittal
Message-ID: <77160@uunet.UU.NET>
Date: 20 Jan 90 01:16:33 GMT
Sender: allbery@uunet.UU.NET
Organization: APT Technology, Inc.  San Jose, CA,  USA
Lines: 439
Approved: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)

Posting-number: Volume 10, Issue 25
Submitted-by: brian@apt.UUCP (Brian Litzinger)
Archive-name: chall

[And again:  ???  ++bsa]

The following program is just a useless waste of your time, so I'd
just /bin/rm it and go one with more useful endeavours.

I've been accused of posting useless programs in the past, so I think
you should seriously re-consider just tossing this code out.

There really are better ways to do these things.  This whole mess
is just a waste of network bandwidth and I'm surprised the moderator
actually let it slip through.

If you still want to use this program its a program using getopts that
lets you combine chmod, chown, and chgrp into one command called chall.

It doesn't follow any of the BSD combined chown/grp functionality. I'm
a System V'er after all.  It does have one saving grace though, you
can maintain a personal .chall file in your home directory with macros
in it like 'man:bin:bin:444' which means you can say 
    chall -x man foobar
and foobar will be chmod 444 foobar, chown bin foobar, chgrp bin foobar.

See the man page for more information.  It's too bad it doesn't 
recursively decend directories, and it's too bad it doesn't use
the +rw ... stuff of BSD.  The latter I actually tried, but all those
different options, there just didn't seem to be away to do it.

<>  Brian Litzinger @ APT Technology Inc., San Jose, CA
<>  UUCP:  {apple,sun,pyramid}!daver!apt!brian    brian@apt.UUCP
<>  VOICE: 408 370 9077      FAX: 408 370 9291

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of shell archive."
# Contents:  README chall.c chall.1
# Wrapped by brian@apt on Wed Jan 17 00:12:56 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'README' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'README'\"
else
echo shar: Extracting \"'README'\" \(1300 characters\)
sed "s/^X//" >'README' <<'END_OF_FILE'
Xchall
X
XBy Brian E. Litzinger
X
XYou can do what you wish with this code.  Just don't make a profit
Xoff of it.
X
XThe following program is just a useless waste of your time, so I'd
Xjust /bin/rm it and go one with more useful endeavours.
X
XI've been accused of posting useless programs in the past, so I think
Xyou should seriously re-consider just tossing this code out.
X
XThere really are better ways to do these things.  This whole mess
Xis just a waste of network bandwidth and I'm surprised the moderator
Xactually let it slip through.
X
XIf you still want to use this program its a program using getopts that
Xlets you combine chmod, chown, and chgrp into one command called chall.
X
XIt doesn't follow any of the BSD combined chown/grp functionality. I'm
Xa System V'er after all.  It does have one saving grace though, you
Xcan maintain a personal .chall file in your home directory with macros
Xin it like 'man:bin:bin:444' which means you can say 
X    chall -x man foobar
Xand foobar will be chmod 444 foobar, chown bin foobar, chgrp bin foobar.
X
XSee the man page for more information.  It's too bad it doesn't 
Xrecursively decend directories, and it's too bad it doesn't use
Xthe +rw ... stuff of BSD.  The latter I actually tried, but all those
Xdifferent options, there just didn't seem to be away to do it.
X
END_OF_FILE
if test 1300 -ne `wc -c <'README'`; then
    echo shar: \"'README'\" unpacked with wrong size!
fi
# end of 'README'
fi
if test -f 'chall.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'chall.c'\"
else
echo shar: Extracting \"'chall.c'\" \(4143 characters\)
sed "s/^X//" >'chall.c' <<'END_OF_FILE'
X/* $Header: chall.c,v 1.4 89/12/18 18:39:55 brian Locked $ */
X
X/* By Brian E. Litzinger */
X
X#include <stdio.h>
X#include <unistd.h>
X#include <pwd.h>
X#include <grp.h>
X#include <sys/types.h>
X#include <sys/stat.h>
X#include <string.h>
X
Xmain(argc,argv)
Xint argc;
Xchar **argv;
X{
X    int c;
X    extern char *optarg;
X    extern int optind;
X    extern int errno;
X
X    struct stat *malloc();
X
X    struct passwd *p;
X    struct passwd *getpwnam();
X
X    struct group *g;
X    struct group *getgrnam();
X
X    struct stat *f;
X    int stat();
X
X    char t[256];
X    int tlen;
X
X    int cmask;
X
X    FILE *fd;
X
X    char buffer[100];
X
X    char *s;
X    char *q;
X
X    char *home;
X
X    short matchfound;
X
X    short errflag;
X    short dflag;
X    short oflag;
X    short mflag;
X    short gflag;
X    short sflag;
X    short xflag;
X
X    char *directory;
X    char *owner;
X    int Vowner;
X    int OLDowner;
X    char *group;
X    int Vgroup;
X    int OLDgroup;
X    int mode;
X
X    errflag=gflag=mflag=oflag=dflag=xflag=0;
X
X    home=(char *)getenv("HOME");
X
X    /*
X    +r -r +w -w +x -x +u -u +g -g
X    umask((cmask=umask(0));
X    */
X
X    while ((c=getopt(argc,argv,"x:o:u:g:m:d:")) != -1)
X	switch (c) {
X	    case 'x':
X		if (!home) {
X		    fprintf(stderr,"%s: no HOME variable in environment.",
X			    argv[0]);
X		    fprintf(stderr,"%s: Unable to file chall library file",
X			    argv[0]);
X		    exit(2);
X		}
X		matchfound = 0;
X		sprintf(buffer,"%s/.chall",home);
X		if((fd=fopen(buffer,"r"))!=NULL) {
X		    while ( !matchfound && fgets(buffer,sizeof(buffer),fd)) {
X			q = strtok(buffer,":");
X			if (q && !strcmp(optarg,q)) {
X			    matchfound = -1;
X			    if (q=strtok(NULL,":"))
X				if (!oflag) {
X				    owner = q;
X				    oflag++;
X				}
X			    if (q=strtok(NULL,":"))
X				if (!gflag) {
X				    group = q;
X				    gflag++;
X				}
X			    if (q=strtok(NULL,":"))
X				if (!mflag) {
X				    sscanf(q,"%o",&mode);
X				    mflag++;
X				}
X			}
X		    }
X		    close(fd);
X		    if (!matchfound) {
X			fprintf(stderr,"%s: '%s' not found in chall library.\n",
X				argv[0],optarg);
X			exit(2);
X		    }
X		} else {
X		    fprintf(stderr,
X			    "%s: Unable to open ~/.chall library file.\n");
X		    exit(2);
X		}
X		break;
X	    case 'o':
X	    case 'u':
X		owner = optarg;
X		oflag++;
X	    break;
X	    case 'g':
X		group = optarg;
X		gflag++;
X	    break;
X	    case 'm':
X		sscanf(optarg,"%o",&mode);
X		mflag++;
X	    break;
X	    case 'd':
X		if (dflag) errflag++;
X		else {
X		    directory = optarg;
X		    dflag++;
X		}
X		break;
X	    default:
X		errflag++;
X	}
X    if (errflag) {
Xfprintf(stderr,"Illegal option.\n");
Xfprintf(stderr,
X"usage: %s [-o owner] [-g group] [-m mode] [-d directory] files ...\n",
X	argv[0]);
X	exit(1);
X    }
X
X    if ( (oflag) && (!(Vowner=atoi(owner))) && ((p=getpwnam(owner))!=NULL) )
X	    Vowner = p->pw_uid;
X
X    if (gflag) {
X	Vgroup = atoi(group);
X	if (!Vgroup)
X	    if ((g=getgrnam(group))!=NULL)
X		Vgroup = g->gr_gid;
X	    else 
X		if ((p=getpwnam(group))!=NULL)
X		    Vgroup = p->pw_gid;
X    }
X
X    f =  malloc(sizeof(struct stat));
X    if (dflag) {
X	strcpy(t,directory);
X	tlen = strlen(t);
X	t[tlen++]='/';
X    }
X    if ((oflag) || (gflag) || (mflag))
X	for ( ; optind<argc; optind++) {
X	    if ( (dflag) && (argv[optind][0]!='/') ) {
X		strcpy((t+tlen),argv[optind]);
X		s = t;
X	    } else
X		s = argv[optind];
X	    if (access(s,F_OK|W_OK)==0) {
X		if ( (mflag) && (chmod(s,mode)==-1) )
X		    fprintf("Unable to chmod %s\n",s);
X		sflag=1;
X		if ( ((oflag) && (!gflag)) || ((!oflag) && (gflag)) ) {
X		    if (stat(s,f)!=-1) {
X			OLDowner = (int) f->st_uid;
X			OLDgroup = (int) f->st_gid;
X		    }
X		    else {
X			fprintf(stderr,"stat of %s failed(%d)\n",
X				s,errno); 
X			sflag=0;
X		    }
X		}
X		if (sflag) {
X		    if ( (oflag) && (gflag) ) {
X			if (chown(s,Vowner,Vgroup)==-1)
X			    fprintf(stderr,"Unable to chown/grp %s\n",
X				    s);
X		    } else if (oflag) {
X			if (chown(s,Vowner,OLDgroup)==-1)
X			    fprintf(stderr,"Unable to chown %s\n",
X				    s);
X		    } else if (gflag)
X			if (chown(s,OLDowner,Vgroup)==-1)
X			    fprintf(stderr,"Unable to chgrp %s\n",
X				    s);
X		}
X	    } else 
X		fprintf(stderr,"access permission denied on file %s(%d)\n",
X			s,errno);
X	}
X    free(f);
X}
END_OF_FILE
if test 4143 -ne `wc -c <'chall.c'`; then
    echo shar: \"'chall.c'\" unpacked with wrong size!
fi
# end of 'chall.c'
fi
if test -f 'chall.1' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'chall.1'\"
else
echo shar: Extracting \"'chall.1'\" \(2557 characters\)
sed "s/^X//" >'chall.1' <<'END_OF_FILE'
X.TH CHALL 1 09/26/88 "APT Technology, Inc."
X.SH NAME
Xchall \- a replacement for chmod, chgrp, and chmod
X.SH SYNOPSIS
X.B chall
X[
X.B \-o|-u \0owner
X] [
X.B \-g \0group
X] [
X.B \-m \0mode
X] [
X.B \-d\0directory
X] [
X.B \-x \0challdef
X] files ...
X.SH DESCRIPTION
X.I chall
Xis a replacement for the individual commands chmod, chown, and chgrp.
X.PP
XThe
X.I chall
Xprogram has the following five options:
X.PP
X.TP
X.B \-o|-u owner
XSpecifies the new owner to be applied to the list of files.
XIf owner is not a number (uid),
X.I /etc/passwd
Xis searched to translate owner into a uid.
X.I Chall
Xalso allows the user to specify -u instead of -o if the user is more
Xcomfortable with that notation.
X.TP
X.B \-g group
XSpecifies the new group to be applied to the list of files. If group
Xis not a number (gid), 
X.I /etc/group
Xis first searched to translate group into a gid.  If that fails
X.I /etc/passwd
Xis then searched to translate group into a gid.
X.TP
X.B \-m mode
XSpecifies the new mode to be applied to the list of files. Note that
Xthe +x -x +w -w +r -r options of some chmods is not support by
X.I chall.
X.TP
X.B \-d directory
X.I directory
Xis prepended to all file names in the file list that do not begin
Xwith
X.I \/
X(root).
X.TP
X.B \-x challdef
X.I Chall
Xsearches the file
X.I $HOME/.chall
Xlooking for a line which begins with challdef and uses the entries
Xin the rest of the line as the owner, group, and mode to be applied
Xby the 
X.I Chall
Xprogram.  Options fetched from the
X.I $HOME/.chall
Xfile are overridden by explict -o, -u, -g, or -m options in the
Xargument line.
X.SH DIAGNOSTICS
XPermissions and access rights are checked at every operation. Any
Xerrors will be reported on a per file basis.
X.I Chall
Xwill make all the changes possible skipping over errors when possible.
X.SH IDENTIFICATION
XAuthor: Brian Litzinger
X.br
XAPT Technology, Inc., San Jose, CA 95030
X.sp 0
X.SH FILES
X$HOME/.chall
X.SH ENVIROMENT
XHOME
X.SH SEE ALSO
Xchmod(2), chown(2), chgrp(2)
X.SH NOTES
XThe
X.I $HOME/.chall file is uses the following form, and can be
Xcreated with any standard text editor:
X.br
X.ti +0.25i
Xchalldef:owner:group:mode
X.br
XAn example
X.I $HOME/.chall
Xfile might be:
X.br
X.in +0.25i
X.nf
Xroot:root:sys:755
Xbin:bin:bin:555
Xrootuser:root::
Xsysgroup::sys:
Xme:brian::
X.fi
X.in -0.25i
X.SH BUGS
XThe +x -x +w -w +r -r syntax of some chmod commands in not supported
Xby 
X.I
Xchall.
X.br
X.I chall
Xcannot be applied to the executing image of itself as it will get
Xa text file busy error (ETXTBSY) from the operating system.
X.br
XWhen using the -d option resultant file names must not exceed 255
Xcharacters.
END_OF_FILE
if test 2557 -ne `wc -c <'chall.1'`; then
    echo shar: \"'chall.1'\" unpacked with wrong size!
fi
# end of 'chall.1'
fi
echo shar: End of shell archive.
exit 0


