#include<stdio.h>
#include<strings.h>
#include<ctype.h>
#include<krb.h>

#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>

#define fingerfile "/site/usr/etc/finger.conf"
#define logfile "/site/usr/etc/finger.log"

#define upcase(c) ((islower(c)?toupper(c):(c)))

FILE *f;
char line[1000], *wildcard;


char *do_sub (char *sub, char *str, int *max, int quoted)
{
  if (quoted) 
    if (*max<2)
      return str;
    else {
      (*max) -= 2;
      *str++ = '"';
    }
  while (*max && *sub) {
    (*max)--;
    *str++ = *sub++;
  }
  if (quoted) *str++ = '"';
  return str;
}

void substitute (char *source, char *dest, int max)
{
  char c; 
  while (--max) {
    c = *source++;
    switch(c) {
    case 0:
      *dest = 0;
      return;
    case '$':
      c = *source++;
      switch(c) {
      case 0:
      case '$':
	*dest++ = '$';
	break;
      case '*':
      case '!':
	dest = do_sub(wildcard, dest, &max, (c=='*'));
	break;
      default:
	dest = do_sub("Unknown variable",dest,&max,1);
      }
      break;
    default:
      *dest++ = c;
    }
  }
  *dest = 0;
}

void foundit()
{
  char *c, subs[1000];
  
  while (fgets(line,1000,f)) {
    if (c = rindex(line,'\n')) *c = 0;
    if (!strcmp(line,".")) {
      fclose (f);
      exit (0);
    }
    substitute (line,subs,1000);
    switch (subs[0]) {
    case '!':
      fflush(stdout);
      system (subs+1);
      break;
    case '&':
      fprintf(stderr,"%s\n",subs+1);
      break;
    default:
      puts(subs);
    }
  }
}

/* Allows a wildcard at the end of the template.. if so, the
corresponding part in value is returned.  i.e., 

    match("test*","testing") --> "ing"

Then you can use the $* variable in your lines.  This $* is protected
(quoted) since commands are handled with system(); if you want an
uprotected expansion, use $!.

*/

char *match(char *template, char *value)
{
  do {
    if (*template == '*')
      return value;
    else
      if (upcase(*template)!=upcase(*value))
	return NULL;
  } while (*value++, *template++);
  return --value;
}

main (int argc, char **argv)
{
  int scanning;
  char *c, *sname;
  char instance[INST_SZ];

  setenv ("KRBTKFILE","/tmp/finger.tickets", 1);
  strcpy(instance,"salamander");
  if (krb_get_svc_in_tkt ("rcmd",instance,"ATHENA.MIT.EDU",
			  "krbtgt","ATHENA.MIT.EDU",1,"/etc/srvtab") < 0) {
    printf ("No get kerberos tickets dude!\n");
    fflush(stdout);
    exit(0);
  }
  if ((f = fopen(fingerfile,"r")) == NULL) {
    printf ("\nKen's finger daemon is confused.  sorry!\n");
    fflush(stdout);
    exit (0);
  }
  if (argc > 1) 
    sname = argv[1];
  else
    sname = "";
  scanning = 1;
  while (fgets(line,1000,f)) {
    if (c = rindex(line,'\n')) *c = 0;
    if (scanning) 
      if (wildcard = match(line, sname))
	foundit();
      else
	scanning = 0;
    else
      scanning = (!strcmp(line,"."));
  }
  fclose (f);
}
