
/***            chmode.c                ***/

/*      New version of the chmod program: accepts inputs of the
        same format as given by the ls -l command, ie it can
        be invoked like 'chmode rwxrw-r-- *' to make the modes
        of each file specified match the template!

        (C) 1984 Dave Taylor - HP Colorado Networks Operation
	Permission is hereby given for NON-PROFIT distribution of
	this software...all donations cheerily accepted!!!

        If automatic aggregate initialization is available, compile with;
          cc -Dauto chmode.c -o chmode
        otherwise, use;
          cc chmode.c -o chmode
*/

#include <stdio.h>

#define ERROR   -1

#define O_RD    256     /** 400 octal **/
#define O_WR    128     /** 200 octal **/
#define O_EX    64      /** 100 octal **/
#define G_RD    32      /**  40 octal **/
#define G_WR    16      /**  20 octal **/
#define G_EX    8       /**  10 octal **/
#define E_RD    4
#define E_WR    2
#define E_EX    1

main(argc, argv)
int argc;
char *argv[];
{
        register int newmode = 0, j = 1;
        char     buffer[9];

        if (argc < 3)
          exit(printf("Usage: %s <graphic mode> <file(s)>\n",argv[0]));

        --argc;

        strncpy(buffer,argv[j++], 9);

        if (strlen(buffer) != 9)
          exit(printf("Usage: %s <9 char graphic mode> <file(s)>\n",argv[0]));

        /** lets figure out the graphic mode translation! **/

        if ((newmode = translate(buffer)) == ERROR) {
          printf("Bad graphic mode designator!  Please use 'rwxrwxrwx' as a template, \n");
          printf("indicating those accesses that you desire to prevent with a dash\n");
          printf("      For example: 'chmode rw-r--r-- test.c'\n");
          exit(1);
        }

        while (--argc > 0)
          chmod(argv[j++], newmode);
}

int
translate(buffer)
char buffer[];
{
        /** translate a graphic representation of file access to
            an equivalent number as defined in CHMOD(2) **/

        register int loc = 0, sum = 0, val; 
#ifdef auto
        char type[] = "rwxrwxrwx"; 
        int mode[] = { O_RD, O_WR, O_EX, G_RD, G_WR, G_EX, E_RD, E_WR, E_EX };
#else
        char type[9]; 
        int mode[9];

        mode[0] = O_RD; mode[1] = O_WR; mode[2] = O_EX;
        mode[3] = G_RD; mode[4] = G_WR; mode[5] = G_EX;
        mode[6] = E_RD; mode[7] = E_WR; mode[8] = E_EX;

        strcpy(type,"rwxrwxrwx");
#endif

        for (loc = 0; loc < 9; loc++)
          if ((val = check(buffer[loc], type[loc], mode[loc])) == ERROR)
            return(ERROR);
          else sum += val;

        return(sum);
}

int
check(ch, type, mask)
char ch;
int mask;
{
        /** check to see if ch is either type or '-', returning
            either mask or ERROR **/

        if (ch == type) return(mask);
        else if (ch == '-') return(0);
        else return(ERROR);
}


