#include <stdio.h>
#include <ctype.h>
#include <Intrinsic.h>
#include <../wcl/WcCreate.h>
#include <sys/param.h>
#include <syslog.h>
#include <signal.h>

/* Warning: This is not generally portable.  It does work on the vax,
rt, and mips as of right now. */

#define CONF "/afs/sipb/admin/office/xlogin.conf"
#define CATEGORY "/usr/bin/X11/xrdb -load -n /afs/sipb/admin/office/category.%s -d %s"

#define DEBUG

extern Display *dpy;
extern Widget appShell;
extern int abort_verify();
extern void *malloc(), *realloc();

static char errbuf[BUFSIZ];
static int finis;

void cont()
{
   finis = 1;
}

XtActionsRec cuactions[] = {
   /* not really a cb, but it will work, since it ignores all args. */
   { "Abort", (XtActionProc) abort_verify },
   { "Continue", cont },
};

void initcheckuser(app)
     XtAppContext app;
{
   XtAppAddActions(app, cuactions, XtNumber(cuactions));
}

void do_luser()
{
   XEvent e;

   /* make dialog shell, and wait for response. */

   WcCreateChildrenCB(appShell, "xlogin, luserShell", (caddr_t) 0);
   WcPopupCB(appShell, "*luserShell", (caddr_t) 0);

   syslog(LOG_DEBUG,"Waiting for luser input...");

   /* repeat main_loop here so we can check status & return */
   finis = 0;
   while (!finis) {
      XtAppNextEvent(_XtDefaultAppContext(), &e);
      XtDispatchEvent(&e);
   }

   syslog(LOG_DEBUG,"Carrying on.");
}


static int (*old_chld)();

char *checkuser(user)
     char *user;
{
   FILE *f;
   char *c, *d;
   char hostname[MAXHOSTNAMELEN];
   char cfile[MAXPATHLEN];
   XrmDatabase rdb;
   int bytes, ptr;
   char *rbuf;

   initcheckuser(XtWidgetToApplicationContext(appShell));

   syslog(LOG_DEBUG, "Checking user %s", user);

   if ((f = fopen(CONF, "r")) == NULL)
      return(NULL);

   gethostname(hostname,MAXHOSTNAMELEN);

   /* scan for filename */
   while (fgets(errbuf, sizeof(errbuf), f)) {
      if (errbuf[0] == '#') continue;
      if (errbuf[0] == '.') return(NULL);
      if (!strncmp(errbuf, hostname, strlen(hostname))) break;
   }

   /* scan for . ending hostnames */
   while (fgets(errbuf, sizeof(errbuf), f))
      if (errbuf[0] == '.') break;

   /* scan for username */
   while (fgets(errbuf, sizeof(errbuf), f)) {
      if (errbuf[0] == '#') continue;
      if (errbuf[0] == '*') continue;
      if (!strncmp(errbuf, user, strlen(user))) break;
   }

   if (feof(f) || ferror(f)) {
      fclose(f);
      return(NULL);
   }

   fclose(f);

   /* get category */
   c = errbuf+strlen(user);
   while(isspace(*c)) c++;
   d = c;
   while(!isspace(*d)) d++;
   *d = '\0';

   syslog(LOG_DEBUG, "User %s is in category %s", user, c);

   /* open category file as pipe */

   sprintf(cfile, CATEGORY, c, DisplayString(dpy));

/* popen vfork's, so I need to cancel the handler here, so the default
SIGCHLD handler doesn't screw me over and print a bogon error message
at the same time. */

   old_chld = (int (*)()) signal(SIGCHLD, SIG_IGN);

   if ((f = popen(cfile, "r")) == NULL)
      return(NULL);

   if ((rbuf = (char *) malloc(BUFSIZ)) == NULL)
      return("Ran out of memory checking conf file");

   ptr = 0;

   /* read output of pipe into string */

   while(bytes = fread(rbuf+ptr, 1, BUFSIZ, f)) {
      ptr += bytes;
      if ((rbuf = (char *) realloc(rbuf, rbuf+ptr+BUFSIZ)) == NULL)
	 return("Ran out of memory checking conf file");
   }

   rbuf[ptr] = '\0';

   bytes = pclose(f);

   signal(SIGCHLD, old_chld);

   syslog(LOG_DEBUG, "Resource read (errno=%d) %d bytes.  Text: %s", bytes, ptr, rbuf);

   /* put string into resource database */

   rdb = XrmGetStringDatabase(rbuf);
   XrmPutFileDatabase(rdb, "/tmp/debug.cat");
   XrmMergeDatabases(rdb, &(dpy->db));
   XrmPutFileDatabase(dpy->db, "/tmp/debug.rdb");
   free(rbuf);

   do_luser();

   return(NULL);
}
