#include <stdio.h>
#define MAXUFDS 500
#define USRLEN 70
/* NOTE: look for literal 70's in format strings if changing USRLEN */
/* OWN is a program to maintain and report on a file containing a list of
   who (or what) owns a certain UFD.

   USAGE: own [-a|-m] [ufd|owner] [-ffilespec]
	  Examples:
	    own		-- list all ufds and users on file
	    own [2,31]	-- report who owns [2,31]
	    own watson	-- report all ufds owned by Watson
	    own -m [2,31]--modify owner name for ufd [2,31] (priveleged)
	    own -d [2,33]--delete entry for [2,31]
	    own -a	-- add new entries to file (priveleged)
	    own -fTEST.TMP -- list TEST.TMP instead of [1,5]UFDLIST.TXT
	    own -uDB5:    -- prepends unit spec to [1,5]UFDLIST.TXT
			      and lists from that disk.
	    own -uDB3: -m [2,31] -- modify [2,31] entry in DB3:[1,5]UFDLIST.TXT

    AUTHOR: Allen A. Watson
	    THE RECORD
	    150 River Street
	    Hackensack, NJ 07601
	    (201) 646-4111
*/

int count = 0, lsw=0, asw=0, dsw=0, msw=0, fsw=0, usw=0, found=0;
int ufdsw=0, usersw=0;
int alllist, userlist, ufdlist;
char *ufd, *user, fufd[10], fuser[USRLEN+1];
char *ufdfile = "[1,5]UFDLIST.TXT;              ";	/* filespec buffer */
char *ufdold[MAXUFDS];
char *help[13];
char *s, *c;

remember(u)
char *u;
  {
  register char *p;
  
  if (count == MAXUFDS) error ("too many UFDS; increase MAXUFDS\n");
  if ((p = malloc(10)) == NULL)
    error("Cannot allocate memory, need larger increment\n");
  else
    {
    cpystr(p, u);
    ufdold[count++] = p;
    }
  }

main (argc, argv)
char *argv[];
int argc;

{
  /* declare external format function to format UIC spec */
  char *format();
  register FILE *in, *out;
  register int i, n;

help[0]="OWN is a program to maintain and report on a list";
help[1]="of who (or what) owns a certain UFD.";
help[2]="";
help[3]="   USAGE: own [-a|-m|-d] [ufd|owner] [-ffilespec|-uddnn:]";
help[4]="	  Examples:";
help[5]="	    own		-- list all ufds and users on file";
help[6]="	    own [2,31]	-- report who owns [2,31]";
help[7]="	    own watson	-- report all ufds owned by Watson";
help[8]="	    own -m [2,31]  modify owner for ufd [2,31] (priveleged)";
help[9]="	    own -a	-- add new entries to file (priveleged)";
help[10]="	    own -fTEST.TMP -- list TEST.TMP instead of UFDLIST.TXT";
help[11]="	    own -uddnn: -- prepends unit spec to [1,5]UFDLIST.TXT";
help[12]="	    own -d [2,33]--delete entry for [2,33] (priveleged)";

  tiatt();	/* attach terminal so CNTL/O works */

  /* process arguments */
  if (argc > 4) error ("own usage: own [-m|-a] [ufd] [-ffilespec]");
  while (--argc > 0)
    {
    *s = tolower((*++argv)[0]);
    switch (*s)
      {
      case '-': switch (tolower((*argv)[1]))	/* a switch is given */
		  {
		  case 'a': asw = 1;
		  	    break;
		  case 'm': msw = 1;
			    break;
		  case 'f': cpystr (ufdfile, &((*argv)[2]));
			    fsw = 1;
			    break;
		  case 'u': /* prepend unit to filespec */
			    /* cheat and use help array for temp storage */
			    cpystr(help[0], &((*argv)[2]));
			    strcat(help[0], ufdfile);
			    cpystr(ufdfile, help[0]);
			    usw = 1;
			    break;
		  case 'd': dsw = 1;
			    break;
		  default:  error("own: illegal switch %c\n", (*argv)[1]);
			    break;
		  }
		break;
      case '[': ufdsw++;		/* ufd is given */
		ufd = *argv;
		format(ufd);
		break;
      case '?': /* output help */

		for (n=0; n <= 10; n++)
		  printf ("%s\n", help[n]);
		exit(0);
		break;
      default:  usersw++;
		user = *argv;
		break;
      }
    }
  /* if not add, delete or modify we must be listing */
  lsw = (!asw) && (!msw) && (!dsw);

  /* check validity of combinations */
  if ((msw) && (!ufdsw)) error ("own: to modify, UFD must be given");
  if (msw+asw+dsw+lsw > 1) error("own: invalid switch combination");
  if (usw+fsw > 1) error("own: unit can be included in -ffilespec");

  /* set type of listing wanted */
  alllist = lsw && (!usersw) && (!ufdsw);
  userlist = lsw && usersw;
  ufdlist = lsw && ufdsw;

  /* open files needed */
  if ((in = fopen(ufdfile, "r")) == NULL)
    error ("own: cannot open %s", ufdfile);
  if (dsw || asw || msw)
    if((out = fopen(ufdfile, "w")) == NULL)
      error ("privelege violation: cannot open output file");

  /* do listing if desired */
  if (lsw)
    {
    n = 0;
    while (fscanf(in,"%9s %70s", fufd, fuser) != EOF)
      {
      if ((alllist)
      || (ufdlist && (strcmp(ufd, fufd) == 0))
      || (userlist && (index(fuser, user) != -1)))
	{
	printf("%9s %s\n", fufd, fuser);
	n += 1;
	found = 1;
	}
      }
    if (!found) printf ("%s not found\n", (ufdlist) ? ufd : user);
    else if (!ufdlist) printf("\n%d entries found\n", n);
    }

  /* modify an existing entry */
  if (msw)
    {
    while (fscanf(in,"%9s %70s", fufd, fuser) != EOF)
      {
      if (!found)
        if (strcmp(ufd, fufd) == 0)
	  {
	  printf ("%s %s found\n", fufd, fuser);
	  printf ("Enter new user name\n");
	  scanf("%70s", fuser);
	  for (n = 0; n <= strlen(fuser); n++)
	    fuser[n] = toupper(fuser[n]);
	  found = 1;
	  }
      fprintf(out, "%9s %s\n", fufd, fuser);
      }
    if (!found) printf ("UFD %s not found in file\n", ufd);
    fclose(out);
    }

  /* add new entries */
  if (asw)
    {
    while (fscanf(in, "%9s %70s", fufd, fuser) != EOF)
    /* read existing file and store ufds found */
      {
	remember (fufd);
	fprintf(out, "%9s %s\n", fufd, fuser);
      }
    /* now add the new ufds */
    printf ("Enter new UFD; use CNTL/Z to exit\n");
    while (scanf("%9s", &fufd) != EOF)
      { /* first check if ufd exists in file already */
      format(fufd);
      if ((fufd[0] != '[') || (fufd[strlen(fufd)-1] != ']'))
	{
	printf("UFD %s must have brackets -- [ggg,mmm]\n", fufd);
	continue;
	}
      for (i=0; (i < count) && (strcmp(fufd, ufdold[i]) != 0); i++)
	;
      if (i <= count-1) printf ("UFD %s already on file\n", fufd);
      else  /* add it */
	{
	printf("Enter user of %s\n", fufd);
	scanf("%70s", &fuser);
	for (n = 0; n <= strlen(fuser); n++)
	  fuser[n] = toupper(fuser[n]);
	fprintf(out, "%9s %s\n", fufd, fuser);
	printf("%s %s added to file\n", fufd, fuser);
	remember(fufd);
	}
      printf("Enter new UFD\n");
      }
    fclose(out);
    }
  /* delete entries */
  if (dsw)
    {
      printf("Enter UFD to delete or CNTL/Z to exit\n");
      ufd = malloc (10);
      n = scanf("%9s", ufd);
      if (n != EOF)
	{
	format(ufd);
	printf("looking for %s ...\n", ufd);
	found = 0;
	}
      else found = 1;
      while (fscanf(in, "%9s %70s", fufd, fuser) != EOF)
	{
	if (n == EOF) /* write rest of file after CNTL/Z */
	  fprintf(out, "%9s %s\n", fufd, fuser);
	else
	  {
	  if (strcmp(ufd, fufd) != 0)
	    fprintf(out, "%9s %s\n", fufd, fuser);
	  else	    
	    {
	    found = 1;
            printf ("%s %s deleted\n", fufd, fuser);
	    printf("Enter UFD to delete or CNTL/Z to exit\n");
            n = scanf("%9s", ufd);
            if (n != EOF)
	      {
	      format(ufd);
	      found = 0;
	      }
	    }
	  }
	}
      fclose(out);
      if (!found) printf ("%s not found\n", ufd);
    }
  }
