#include <stdio.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/file.h>
#include <sys/param.h>
#include <netinet/in.h>
#include <rpc/rpc.h>
#include <rpcsvc/ypclnt.h>
#include <rpcsvc/yp_prot.h>
#include <sys/stat.h>

#define TITLEMAP        "yeats.bytitle"
#define FIRSTMAP        "yeats.byfirst"

char *yeatsdomain;

static char *readpoem();
static int setdomain();
static void fixline();

static int first = 1;

char *
getyeatsbytitle(title) char *title;
{
 char scratch[BUFSIZ];
 char *filename;
 int flength;

 if(setdomain() != 0)
   return(NULL);

 fixline(scratch,title,BUFSIZ);

 if(yp_match(yeatsdomain,TITLEMAP,
             scratch,strlen(scratch),
             &filename,&flength) != 0)
   return(NULL);

 filename[flength] = '\0';
 return(readpoem(filename));
}

char *
getyeatsbyfirst(first) char *first;
{
 char scratch[BUFSIZ];
 char *filename;
 int flength;

 if(setdomain() != 0)
   return(NULL);

 fixline(scratch,first,BUFSIZ);

 if(yp_match(yeatsdomain,FIRSTMAP,
                   scratch,strlen(scratch),
                   &filename,&flength) != 0)
   return(NULL);

 filename[flength] = '\0';
 return(readpoem(filename));
}

setyeatsent()
{
 first = 1;
 if(setdomain() != 0)
   return(-1);
 else
   return(0);
}

endyeatsent()
{
 first = 1;
 yeatsdomain = NULL;   /* force new lookup of domain */
 return(0);
}

char *
getyeatsent()
{
 int err;
 char *key, *filename;
 int flength;
 static int keylen;
 static char lastkey[MAXPATHLEN];

 if(setdomain() != 0)
   return(NULL);

 if(first)
   err = yp_first(yeatsdomain,TITLEMAP,
                  &key,&keylen,&filename,&flength);
 else
   err = yp_next(yeatsdomain,TITLEMAP,
                 lastkey,keylen,
                 &key,&keylen,&filename,&flength);

 if(err)
   return(NULL);
 else
   bcopy(key,lastkey,keylen);

 first = 0;

 filename[flength] = '\0';
 return(readpoem(filename));
}

static void
fixline(out,in,max) char *out, *in; int max;
{
 int i;

 for(i=0,max--; (*in != '\0') && (i < max);i++)
   if(isupper(*in))
     *out++ = tolower(*in++);
   else if(isspace(*in)) {
     *out++ = '_';
     while(isspace(*in))
       *in++;
   }
   else
     *out++ = *in++;

 *out = '\0';
}

static int
setdomain()
{
 int err;

 if((yeatsdomain == NULL) && (err = yp_get_default_domain(&yeatsdomain)))
   return(err);
 else
   return(0);
}

static char *
readpoem(path) char *path;
{
 char *poem;
 struct stat st;
 int fd;

 if(stat(path,&st) < 0)
   return(NULL);

 if((fd = open(path,O_RDONLY)) < 0)
   return(NULL);

 if((poem = (char *)malloc(st.st_size+1)) == NULL) {
   close(fd);
   return(NULL);
 }

 if(read(fd,poem,st.st_size) != st.st_size) {
   free(poem);
   close(fd);
   return(NULL);
 }

 poem[st.st_size] = '\0';
 close(fd);
 return(poem);
}