/* This file is part of the Project Athena Zephyr Notification System.
 * It contains functions for the windowgram COMPILER, file loading.
 *
 *	Created by:	Mark W Eichin
 *
 *	$Source: /mit/zephyr/src/zwgc/RCS/loader.c,v $
 *	$Author: eichin $
 *
 *	Copyright (c) 1987 by the Massachusetts Institute of Technology.
 *	For copying and distribution information, see the file
 *	"mit-copyright.h". 
 */

#include <zephyr/mit-copyright.h>

#ifndef lint
static char rcsid_loader_c[] = "$Header: loader.c,v 2.4 88/07/10 23:03:45 eichin Exp $";
#endif lint

#include <sys/file.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>

#include "comp_types.h"
#include "ropes.h"
rope *parse_string();

#define MAX_FILE_SIZE 30000
char *malloc();
extern errno;

char *safe_load(fn)
     char *fn;
{
  /*
    Input: fn is a filename to load.
    Output: pointer to a malloc'd area containing the file.

    Side Effects: none, other than nasty messages to users...

    */
  int f;
  struct stat fbuf;
  char *s;
  int stat;
  int i;

  if(fn == NULL)
    {
      printf("zwgc:loader Bad call to safe_load, null filename given!\n");
      return(NULL);
    }

  f = open(fn, O_RDONLY, 0);

  if(f<0)
    {
      /*       com_err("zwgc", errno, "while opening description file"); */
      return(NULL);
    }

  if(fstat(f,&fbuf)<0)
    {
      com_err("zwgc", errno, "while stat'ing description file");
      close(f);
      return(NULL);
    }

  if(fbuf.st_size > MAX_FILE_SIZE)
    {
      printf("zwgc:loader File \"%s\" is ", fn);
      if (fbuf.st_size > (MAX_FILE_SIZE << 1))
	{
	  printf("MUCH ");
	}
      printf("too large (%d) to be a real description. Ignoring.\n",
	     fbuf.st_size);
      close(f);
      return(NULL);
    }

  s = malloc(fbuf.st_size+1);

  stat = read(f, s, fbuf.st_size);
  if (stat == -1)
    {
      com_err("zwgc", errno, "reading description file");
      free(s);
      close(f);
      return(NULL);
    }
  if (stat < fbuf.st_size)
    {
      printf("zwgc:loader partial read on description file, %d/%d\n",
	     stat, fbuf.st_size);
      free(s);
      close(f);
      return(NULL);
    }

  s[stat] = '\0';
  for(i=0; i<stat; i++)
    {
      if(is_blank(s[i])) s[i] = ' ';
      if(is_newline(s[i])) s[i] = '\n';
      if(!is_char(s[i]))
	{
	  printf("zwgc:loader Non ASCII char found, punting file (%03o@%d)\n",
		 s[i], i);
	  free(s);
	  close(f);
	  return(NULL);
	}
    }

  dbg_printf("zwgc:loader Successful read of %d bytes.\n",stat);
  close(f);
  return(s);
}

extern char panic_desc[], blank_desc[];

#include <pwd.h>
char *getenv(), *index(), *strncpy(), *strcpy();
rope *ruser, *rsys, *rpanic, *rblankmsg;

char *load_desc(usr,sys)
     char *usr;
     char *sys;
{
  char *sline, *s1, *s2;
  char *arg;
  struct passwd *pwd;
  char *hmdir, *xfnam;

  hmdir = getenv("HOME");

  if(!hmdir)
    {
      if (!(pwd = getpwuid(getuid())))
	{
	  printf("zwgc:loader Who are you? Your userid is not in the passwd file!\n");
	  exit (1);
	}
      xfnam = malloc(strlen(pwd->pw_dir)+1+strlen(usr)+1);
      (void)strcpy(xfnam,pwd->pw_dir);
    }
  else
    {
      xfnam = malloc(strlen(hmdir)+1+strlen(usr)+1);
      (void)strcpy(xfnam,hmdir);
    }
  strcat(xfnam,"/");
  strcat(xfnam,usr);

  s1 = safe_load(xfnam);
  if(s1)
    {
      int slen=index(s1, '\n')-s1;
      
      sline = strncpy(malloc(slen+1), s1, slen);
      arg = s1;
    }
  else
    {
      *(sline = malloc(1)) = '\0';
      arg = "";
    }
  if(ruser) ropfree(ruser);
  ruser = parse_string(&arg);
  free(s1);			/* we don't need it, we have the rope */
  free(xfnam);

  s2 = safe_load(sys);
  if(s2)
    {
      arg = s2;
    }
  else
    {
      arg = "";
    }
  if(rsys) ropfree(rsys);
  rsys = parse_string(&arg);
  free(s2);			/* we don't need it, we have the rope */

  arg = panic_desc;
  if(rpanic) ropfree(rpanic);
  rpanic = parse_string(&arg);

  arg = blank_desc;
  if(rblankmsg) ropfree(rblankmsg);
  rblankmsg = parse_string(&arg);

  return(sline);
}
