/*
 * chown.c
 *
 * Uses the c library functions fparse and fnopen to process a
 * possible wild card spec and set the owner of a file.
 * Also chains xab's to the fab set up by fparse.
 */
#include <stdio.h>
#include <fabdef.h>
#include <rmsdef.h>
#include <shrdef.h>

char *index();
extern errno;

struct descr {
        int len;
        char *addr;
};

$XAB xpro; /* xab block for protection and UIC */

main(argc, argv)
char **argv;
{
        register char *fn,*uic;
        register group,member;
        register FILE *fw;
        register struct $fab *fp;
        int     running = 1;
        int     v = 0;
        int     putbuf[10];
        struct descr fnam;

        if (argc < 3) {
                fprintf(stderr,"chown: usage: chown [UIC] filespec\n");
                exit(2);
        }
        if (argv[1][0] == '-') {
                ++argv;
                switch(argv[0][1]) {
                case 'v':case 'V':
                        v=1;
                        break;
                }
        }
        uic = *++argv;
        fn = *++argv;
        if (*uic == '[') uic++;
        if (*uic == ',') {
                group = 0;
                *uic++;
        } else {
                group = octal(uic);
                uic = index(uic, ',');
                if (uic == 0) {
                        fprintf(stderr, "chown: bad UIC format - missing member number\n");
                        uic = "";
                } else {
                        uic++;
                }
        }
        if (*uic == '\0') {
                member = 0;
        } else {
                member = octal(uic);
        }
        xpro.cod = 19; xpro.bln = 16;
        fw = fparse(fn, "r");
        if (fw == NULL) {
                fnam.len = strlen(fn);
                fnam.addr = fn;
                putbuf[0] = 5;
                putbuf[1] = (2<<16)|SHR$_PARSEFAIL|(errno&0x7);
                putbuf[2] = 1;
                putbuf[3] = &fnam;
                putbuf[4] = errno;
                error(putbuf);
                exit((1<<28)|putbuf[1]); /* inhibit message printing */
        }
        fp = fileno(fw)->fab;
        fp->fac = FAB$M_PUT;
        fp->xab = &xpro;
        while (running) {
                if (fnopen(fw) != NULL) {
                        if (v) printf(" %.*s [%03o,%03o]\n",fp->nam->rsl,fp->nam->rsa,
                                xpro.grp,xpro.mbm);
                        if (group) xpro.grp = group;
                        if (member) xpro.mbm = member;
                } else {
                        if (errno == 0) {
                                running = 0;
                                break;
                        }
                        fnam.len = fp->nam->rsl;
                        fnam.addr = fp->nam->rsa;
                        putbuf[0] = 5;
                        putbuf[1] = (2<<16)|SHR$_OPENOUT|(errno&0x7);
                        putbuf[2] = 1;
                        putbuf[3] = &fnam;
                        putbuf[4] = errno;
                        error (putbuf);
                }
                errno = 0;
        }
        if (errno != 0) {
                putbuf[0]=2; putbuf[1]=errno;
                error(putbuf);
                exit((1<<28)|errno); /* Inhibit message printing */
        } else  return(0);
}

#include <ctype.h>

octal(str)
register char *str;
{
        register num = 0;
        register base = 8;

        while (isdigit(*str))
                num = num*base + (*str++ - '0');
        return(num);
}

error(buf)
int     *buf;
{
        struct descr facnam;

        facnam.addr = "CHOWN";
        facnam.len = 5;
        sys$putmsg(buf,0,&facnam);
}
