/* permsfile.c: implement SunOS /etc/fbtab and Solaris /etc/logindevperm
   functionality to set device permissions on login

Portions of this software are Copyright 1995 by Randall Atkinson and Dan
McDonald, All Rights Reserved. All Rights under this copyright are assigned
to the U.S. Naval Research Laboratory (NRL). The NRL Copyright Notice and
License Agreement applies to this software.

	History:

	Written at NRL for OPIE 2.0.
*/

#include "opie_cfg.h"
#ifdef PERMSFILE
#include <stdio.h>
#include <sys/types.h>
#include <string.h>
#include <syslog.h>

/* Line buffer size (one more than max line length) */
#define BUFSIZE 128
/* Maximum number of list items in a field */
#define LISTSIZE 10

static char buf[BUFSIZE], buf2[8];

char **ftpglob __ARGS((char *));

void opiefatal(x)
char *x;
{
  fprintf(stderr, x);
  exit(1);
}

#include "glob.c"

static getalist(string, list)
char **string;
char **list;
{
  char *s = *string;
  int i = 0;

  while (*s && (*s != '\n') && (*s != ' ') && (*s != '\t'))
    if ((*s == ':') || (*s == ',')) {
      *(s++) = 0;
      list[i++] = *string;
      *string = s;
      if (i == LISTSIZE)
	return i;
    } else
      s++;

  if ((int) (s) - (int) (*string)) {
    *s = 0;
    list[i++] = *string;
  }
  *string = ++s;

  return i;
}

static doaline(line, name, ttyn, uid, gid)
char *line, *name, *ttyn;
uid_t uid;
gid_t gid;
{
  char *ptr, *ptr2;
  int i, j, k;
  int applies, llen;
  char *listbuf[LISTSIZE], **globlist;

  if (ptr = strchr(buf, '#'))
    *ptr = 0;

  /* Skip whitespace */
  for (ptr = buf; *ptr && ((*ptr == ' ') || (*ptr == '\t'));
       ptr++);

  if (!*ptr)
    return;

  /* (Optional) Field 1: user name(s) */
  if ((*ptr != '/') && (*ptr != '~')) {
    llen = getalist(&ptr, listbuf);
    for (applies = i = 0; (i < llen) && !applies; i++)
      if (!strcmp(listbuf[i], name))
	applies++;
    while (*ptr && ((*ptr == ' ') || (*ptr == '\t')))
      ptr++;
    if (!applies || !*ptr)
      return;
  }
  /* Field 2: terminal(s) */
  llen = getalist(&ptr, listbuf);
  for (applies = i = 0; (i < llen) && !applies; i++)
    if (!strcmp(listbuf[i], ttyn))
      applies++;

  while (*ptr && ((*ptr == ' ') || (*ptr == '\t')))
    ptr++;

  if (!applies || !*ptr)
    return;

  /* Field 3: mode */
  for (applies = 0; *ptr && (*ptr >= '0') && (*ptr <= '7');
       applies = (applies << 3) | (*(ptr++) - '0'));

  while (*ptr && ((*ptr == ' ') || (*ptr == '\t')))
    ptr++;

  if (!*ptr)
    return;

  /* Field 4: devices (the fun part...) */
  llen = getalist(&ptr, listbuf);
  for (i = 0; i < llen; i++) {
    globlist = ftpglob(listbuf[i]);
    while (*globlist) {
#ifdef DEBUG
      fprintf(stderr, "setting %s to %d/%d %o\n", *globlist,
	      uid, gid, applies);
#endif	/* DEBUG */
      if (chown(*globlist, uid, gid) < 0)
	if (errno != ENOENT)
	  perror("lchown");
      if (chmod(*(globlist++), applies) < 0)
	if (errno != ENOENT)
	  perror("chmod");
    }
  }
}

permsfile(name, ttyn, uid, gid)
char *name, *ttyn;
uid_t uid;
gid_t gid;
{
  char **foo;
  char *ptr;
  FILE *fh;
  int i, j, k;

  if (!(fh = fopen(PERMSFILE, "r"))) {
    syslog(LOG_ERR, "Can't open %s!", PERMSFILE);
    fprintf(stderr, "Warning: Can't set device permissions.\n");
    return;
  }
  do {
    if (feof(fh))
      return;
    if (fgets(buf, BUFSIZE, fh) == NULL)
      return;
    buf[BUFSIZE] = 0;

    doaline(buf, name, ttyn, uid, gid);
  }
  while (1);
}
#endif	/* PERMSFILE */
