RCS_ID_C="$Id: umask.c,v 2.2 1994/02/17 02:12:13 ppessi Exp $";
/*
 * umask.c -- print or change the umask
 *
 * Author: ppessi <Pekka.Pessi@hut.fi>
 *
 * Copyright © 1994 AmiTCP/IP Group, <AmiTCP-group@hut.fi>
 *                  Helsinki University of Technology, Finland.
 *
 * Created      : Tue Jan 11 22:33:06 1994 ppessi
 * Last modified: Thu Feb 17 01:07:18 1994 ppessi
 */

#include "umask_rev.h"

static const char version[] = VERSTAG " "
"Copyright © 1994 AmiTCP/IP Group, <amitcp-group@hut.fi>\n"
  "Helsinki University of Technology, Finland.\n";

#include <pwd.h>
#include <grp.h>
#include <unistd.h>

#include <proto/usergroup.h>
#include <proto/dos.h>

#include <clib/exec_protos.h>
extern struct ExecBase* SysBase;
#include <pragmas/exec_sysbase_pragmas.h>

#include <dos/dos.h>

#include <string.h>
#include <stdlib.h>

#define USERGROUPVERSION 2	/* minimum version to use */

#ifndef MAXLINELENGTH 
#define MAXLINELENGTH 1024
#endif

LONG UMask(void)
{
  LONG retval = RETURN_FAIL;
  struct DosLibrary *DOSBase;
  struct ExecBase *SysBase;
  struct Library *UserGroupBase;

  SysBase = *(struct ExecBase**)4;
  DOSBase = (struct DosLibrary *)OpenLibrary("dos.library", 37L);
  UserGroupBase = OpenLibrary(USERGROUPNAME, USERGROUPVERSION);
  
  if (DOSBase && UserGroupBase) {
    mode_t mask = getumask();

    const char *template = "-S=SYMBOLIC/S,mask";
    struct {
      LONG   a_symbolic;
      STRPTR a_newmask;
    } args[1] = { 0 };
    struct RDArgs *rdargs = NULL;

    retval = RETURN_OK;

    rdargs = ReadArgs((UBYTE *)template, (LONG *)args, NULL);

    if (rdargs == NULL) {
      PrintFault(IoErr(), "umask");
      retval = RETURN_ERROR;
    } else if (args->a_newmask) {
      mode_t newmask = 0;
      UBYTE *np = args->a_newmask, c;

      for (;;) {
	c = *np++;

	if (c == '\0') {
	  umask(newmask);
	  retval = RETURN_OK;
	  break;
	} else if (c >= '0' && c < '8') {
	  newmask <<= 3;
	  newmask += c - '0';
	  if (newmask > 0777)
	    break;
	} else {
	  break;
	}
      }
      if (c) {
	Printf("umask: `%s' is not octal mask from 000 to 777\n", 
	       args->a_newmask);
      }
    } else if (args->a_symbolic) {
      static const char symbolic[] = 
	"rwx\0" "rw\0\0" "rx\0\0" "r\0\0\0" "wx\0\0" "w\0\0\0" "x\0\0\0" "";
      Printf("u=%s,g=%s,o=%s\n", 
	     symbolic + 4 * ((mask >> 6) & 7),
	     symbolic + 4 * ((mask >> 3) & 7),
	     symbolic + 4 * ((mask >> 0) & 7));
      retval = RETURN_OK;
    } else {
      Printf("%lc%lc%lc\n",
	     mask >> 6 & 7 | '0',
	     mask >> 3 & 7 | '0',
	     mask >> 0 & 7 | '0');
      retval = RETURN_OK;
    }
    if (rdargs) {
      FreeArgs(rdargs);
    }
  }

  if (UserGroupBase) {
    CloseLibrary(UserGroupBase);
  } else {
    Printf("id: cannot open %s\n", USERGROUPNAME);
  }

  if (DOSBase)
    CloseLibrary((struct Library *)DOSBase);

  return retval;
}
