[comp.sources.misc] v02i054: Unify TEXT fields from ACCELL Part 5/5

ustel@well.UUCP (Mark Hargrove) (02/11/88)

Comp.sources.misc: Volume 2, Issue 54
Submitted-By: "Mark Hargrove" <ustel@well.UUCP>
Archive-Name: accell-text/Part5

#!/bin/sh
# to extract, remove the header and type "sh filename"
if `test ! -s ./README2`
then
echo "writing ./README2"
cat > ./README2 << '\Rogue\Monster\'
These are the c-hooks into the ACCELL amgr to use an editor
to edit TEXT fields in the unify database. The file 'fedit.fs'
is the accell forms script that all forms call to fire off the
editor. 'fedit.fq' (uuencoded) is the form definition itself.
Several global variables need to be set for fedit to work, these
are documented in 'fedit.fs'.

The various functions provide the following capabilities:

	edit_txt() : Provides an interface to an editor (or any other
		     program) to modify text/binary fields. The 
		     routine will write the text field out into a
		     temporary file, passing the filename as an
		     argument to the editor program. The fields will
		     be null padded to an allocation boundary when 
		     written back to file.dbv. 

	display_txt() : Will display the first "line" of the 
		        text in the text field into the 
		        supplied screen string field.  The string
			passed as the screen field argument must be
			pre-allocated to whatever display length
			you want.  The easiest way to do this is
			to assign a strings of spaces to it just before
			the call to display_txt().

	show_txt() : A read-only version of edit_txt().

	to_upper() : Convert the supplied string field to UPPER case.

	week_day() : Return the day of the week of today. (0=Sunday,
		     6=Saturday).

	day_of_week() : Return the day of the week of the supplied
		        unify short date field.  We primarily use this
			to detect Saturdays and Sundays when users are
			entering due dates or tickler dates.
\Rogue\Monster\
else
  echo "will not over write ./README2"
fi
if `test ! -s ./Makefile`
then
echo "writing ./Makefile"
cat > ./Makefile << '\Rogue\Monster\'
# custom AMGR makefile

SHELL=/bin/sh
CC = cc 
INCLUDE = $(UUINCLUDE)
CFLAGS = $(INCLUDE) -g
LFLAGS = # -Wl,-n	# used by NCR Tower32, forces shareable text

OBJS = chooktb.o disp_txt.o get_fld_no.o edit_txt.o show_txt.o text_size.o \
		 week_day.o to_upper.o 

amgr0887:	$(OBJS)
		LDFLAGS="$LFLAGS"; export LDFLAGS; amgr.ld amgr0887 $(OBJS)

install:	
		mv amgr0887 $(UNIFY)/../bin

clean:
	/bin/rm *~ *.o
\Rogue\Monster\
else
  echo "will not over write ./Makefile"
fi
if `test ! -s ./chooktb.c`
then
echo "writing ./chooktb.c"
cat > ./chooktb.c << '\Rogue\Monster\'
/**********************************************************************
*
*	chooktb.c - ACCELL/C-Language function hook tables
*
**********************************************************************/

#include <chookincl.h>

extern int display_txt();
extern int edit_txt();
extern int to_upper();
extern int show_txt();
extern int text_size();
extern int week_day();
extern int day_of_week();
#ifdef CP
extern int get_txt();
extern int put_txt();
#endif

CHOOK chooktb[] = 
    {
        { "display_txt", display_txt },
        { "edit_txt", edit_txt },
        { "to_upper", to_upper },
        { "show_txt", show_txt },
        { "text_size", text_size },
        { "week_day", week_day },
        { "day_of_week", day_of_week }
#ifdef CP
       ,{ "get_txt", get_txt },
        { "put_txt", put_txt }
#endif
    };                        

/*** # elements in chook table DO NOT MODIFY ***/;

int nhooks = (sizeof(chooktb)/sizeof(*chooktb)); 
\Rogue\Monster\
else
  echo "will not over write ./chooktb.c"
fi
if `test ! -s ./common.h`
then
echo "writing ./common.h"
cat > ./common.h << '\Rogue\Monster\'
/* stuff common to all language scripts */

#include "mesgnums.h"

#define BLANKS_30 '                              '
#define BLANKS_35 '                                   '
#define BLANKS_40 '                                        '
#define BLANKS_50 '                                                  '
#define BLANKS_60 '                                                            '
#define BLANKS_80 '                                                                                '
#define GENERAL_MGR	16
#define SALES_MGR	4
#define PREVIOUS_FIELD	3
#define ADD_UPDATE	31
\Rogue\Monster\
else
  echo "will not over write ./common.h"
fi
if `test ! -s ./disp_txt.c`
then
echo "writing ./disp_txt.c"
cat > ./disp_txt.c << '\Rogue\Monster\'
/*****************************************************************************
*
* %W%   %G%   %U%
*
*   NAME:           display_txt
*   DESCRIPTION:    Accell/C-hook for displaying a text field
*
*   ACCELL USAGE:   display_txt(target_variable, screen_variable)
*                     where:
*                        target_variable is the long name of
*                                        a UNIFY database field
*                        screen_variable is an ACCELL screen variable
*                                        which MUST be pre-initialized
*                                        to be at least as long as the
*                                        display length of the text field.
*                        
*
*   AUTHOR:         Mark Hargrove
*   DATE:            7/17/87
*
*   Modification History:
*
******************************************************************************/
#include <chookincl.h>
#define YES 1
#define NO  0

int
display_txt(numargs, acclarg)
	int numargs;
	AVAL acclarg[];
{
	char *field_name, *screen_field;
	int rc, field_number, screen_field_width;
	AVAL retval;

	/* set up for an error return condition */
	retval.aknd = A_INT; 
	retval.dfflg = YES;

	if (numargs != 2)
	{
		retval.aval.inval = 1;
		chookrt(&retval);
		return;
	}
	if (acclarg[0].dfflg == NO || acclarg[1].dfflg == NO)
	{
		retval.aval.inval = 2;
		chookrt(&retval);
		return;
	}

	field_name = acclarg[0].aval.stval;
	screen_field = acclarg[1].aval.stval;

	if ((field_number = get_fld_num(field_name)) < 0)
	{
		retval.aval.inval = 3;
		chookrt(&retval);
		return;
	}

	if ((rc = get_txt_hd(screen_field, field_number)) != 0)
	{
		retval.aval.inval = 4;
		chookrt(&retval);
		return;
	}
	retval.aval.inval = 0;
	chookrt(&retval);
	return;
}
\Rogue\Monster\
else
  echo "will not over write ./disp_txt.c"
fi
if `test ! -s ./edit_txt.c`
then
echo "writing ./edit_txt.c"
cat > ./edit_txt.c << '\Rogue\Monster\'
/*****************************************************************************
 *
 *
 *   NAME:           edit_txt
 *   DESCRIPTION:    Accell/C-hook for editing a text field
 *
 *   ACCELL USAGE:   edit_txt(target_variable)
 *                     where:
 *                        target_variable is the long name of
 *                                        a UNIFY database field
 *
 *   AUTHOR:         Howie Johnson
 *                   ^^^^^^^^^^^^^
 *                   Not the world's prettiest C programmer
 *
 *   DATE:           7/17/87
 * 
 *   NOTES:
 *       0  indicates successful termination - buffer not modified
 *       1  indicates successful termination - buffer modified
 *      -1  unsuccessful termination
 *
 *      the buffer memory for the transfer of data from the database
 *      into a temporary file and vice versa is allocated as size 
 *      TRANS_BUF_SIZE or less.
 *
 *   Modification History:
 *   $Log:	edit_txt.c,v $
 * Revision 1.3  88/01/25  12:54:58  mark
 * .dbv bug workaround code installed by scotth.
 * 
 * Revision 1.2  88/01/20  16:24:03  scotth
 * baseline before code changes to workaround dbv problem
 * 
 *
 *****************************************************************************/

#include "fdesc.h"
#include "chookincl.h"
#include "dbtypes.h"
#include "domains.h"
#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <termio.h>

/* do NOT change the following value unless you know *exactly* what
* you're doing
*/
#define TRANS_BUF_SIZE 32752L	/* 32K-16 buffer size */

#define YES    1
#define NO     0

#ifdef DEBUG
#  define DCLOSE      {if (errlog != NULL) {fclose( errlog); errlog=NULL;}}
#  define DPRINT0(s)      {if (errlog != NULL) fprintf( errlog, s);}
#  define DPRINT1(s,a1)      {if (errlog != NULL) fprintf( errlog, s, a1);}
#  define DPRINT2(s,a1,a2)   {if (errlog != NULL) fprintf( errlog, s, a1, a2);}
#  define DPRINT3(s,a1,a2,a3)   {if (errlog != NULL) fprintf( errlog, s, a1, a2, a3);}
#  define DFLUSH      {if (errlog != NULL) fflush( errlog);}
#else
#  define DCLOSE
#  define DPRINT0(s)
#  define DPRINT1(s,a1)
#  define DPRINT2(s,a1,a2)
#  define DPRINT3(s,a1,a2,a3)
#  define DFLUSH
#endif

static char RCS_ID[]="$Header: edit_txt.c,v 1.3 88/01/25 12:54:58 mark Exp $";
static struct termio term_buf, new_termio;
static long dbv_alloc();
static FILE *errlog;
extern int get_fld_num();
extern int errno;
extern int terminate();

int   
edit_txt(numargs, acclarg)
   int numargs;
   AVAL acclarg[];
{
   AVAL retval;
   char *field_name;		/* long name of database field */
   int fld;			/* field number */
   long text_size;		/* Actual size of text in DB */
   off_t   file_size;		/* Actual size of edited temp. file */
   long  t_size;		/* Number of bytes to transfer at a whack */
   int   rc;			/* Return code */
   char tname[20];		/* Name of temporary file */
   int fd;			/* File descriptor */
   char *b_ptr;			/* Pointer to transfer buffer */
   long b_size;			/* Size of transfer buffer */
   FIELDLIST flist;		/* Data transfer descriptor block for gfield and pfield */
   FLDESC fdsc;			/* Data base field descriptor */
   struct stat stat_buf;	/* File status block */
   time_t   mod_time;		/* Last modification time of file */
   char errbuf[256];		/* For output messages */
   char cmdbuf[256];		/* Command line buffer for edit command */
   char *editor;		/* Points to EDIT environment variable */
   int pid;			/* process id of child */
   int wait_sts;		/* Status returned by wait() */
   char *Debug;			/* MISBUG environment value */
   extern char *getenv();

/*********************************** work around code **********************/
   long orig_size, padded_size;
/***************************************************************************/

   /* set up for an error return condition */
   retval.aknd  = A_INT; 
   retval.dfflg = YES;
   Debug = NULL;
   errlog = (FILE *)NULL;

#ifdef DEBUG
   if ((Debug = getenv("MISBUG")) != NULL)
   {
      if (*Debug == '\0')
      {
         Debug = NULL;
         errlog = (FILE *)NULL;
      }
      else if ((errlog = fopen("ferrlog", "a+")) == NULL)
      {
         fprintf(stderr, "couldn't open the errlog for append\n");
         return -1;
      }
      fprintf(stderr, "starting debug, value='%s'\n", Debug);
   }
   else
   {
      fprintf(stderr, "no debug this time\n");
   }
#endif

   DPRINT0("=============== entering edit_txt ============================\n");
   if (numargs < 1)
   {
      DCLOSE;
      retval.aval.inval = -1;
      chookrt(&retval);
      return;
   }
   if (acclarg[0].dfflg == NO) 
   {
      DCLOSE;
      retval.aval.inval = -2;
      chookrt(&retval);
      return;
   }

   field_name = acclarg[0].aval.stval;

   if ((fld = get_fld_num(field_name)) < 0)
   {
      DCLOSE;
      retval.aval.inval = -3;
      chookrt(&retval);
      return;
   }

   /* Initialization */
   b_ptr = NULL;
   tname[0] = '\0'; 
   fd = -1;

   /* Check for valid field type */
   if ((rc = fldesc( fld, &fdsc )) != 1)
   {
      sprintf(errbuf,"edit_txt: got bad field=%d",fld);
      DPRINT1("edit_txt: got bad field=%d\n",fld);
      prtmsg(0,22,errbuf);
      retval.aval.inval = terminate(fd, b_ptr, tname, -1);
      DCLOSE;
      chookrt(&retval);
      return;
   }

   if ((rc = fdsc.f_typ) != TEXT )
   {
      sprintf(errbuf,"edit_txt: got non-TEXT field=%d",fld);
      DPRINT1("edit_txt: got non-TEXT field=%d",fld);
      prtmsg(0,22,errbuf);
      retval.aval.inval = terminate(fd, b_ptr, tname, -1);
      DCLOSE;
      chookrt(&retval);
      return;
   }

   /* Get size of actual text in database */
   if ((rc = gsize(fld,&text_size)) != 0)
   {
      sprintf(errbuf,"edit_txt: can't retrieve gsize for field=%d",fld);
      DPRINT1("edit_txt: can't retrieve gsize for field=%d",fld);
      prtmsg(0,22,errbuf);
      retval.aval.inval = terminate(fd, b_ptr, tname, -1);
      DCLOSE;
      chookrt(&retval);
      return;
   }

/*********************************** work around code **********************/
   /* remember the size of the original text! */
   orig_size = text_size;
   DPRINT1("edit_txt: original size=%d\n", orig_size);
/***************************************************************************/

   /* Open a temporary file */
   strcpy(tname,"edtdbXXXXXX");
   mktemp(tname);
   if ((fd=open(tname, O_RDWR | O_CREAT | O_TRUNC, 0666 )) < 0)
   {
      sprintf(errbuf,"edit_txt: can't open temp. file=%s",tname);
      DPRINT1("edit_txt: can't open temp. file=%s",tname);
      prtmsg(0,22,errbuf);
      retval.aval.inval = terminate(-1,b_ptr,"",-1);
      DCLOSE;
      chookrt(&retval);
      return;
   }

   /* Open buffer for transfer of data from database to temp file */
   b_size = (text_size > TRANS_BUF_SIZE) ? TRANS_BUF_SIZE : text_size;
   DPRINT1("edit_txt: malloc'ed size = %d\n", b_size);
   if ((b_ptr = (char *)malloc((unsigned)b_size)) == NULL)
   {
      sprintf(errbuf,"edit_txt: can't malloc buffer for data transfer");
      DPRINT0("edit_txt: can't malloc buffer for data transfer");
      prtmsg(0,22,errbuf);
      retval.aval.inval = terminate(fd, b_ptr, tname, -1);
      DCLOSE;
      chookrt(&retval);
      return;
   }

   /* Transfer data from database to temporary file */
   flist.fnum = fld;
   flist.fdata = b_ptr;
   flist.mode = FL_TRUNC;
   flist.start = 0L;
   while(text_size > 0L)
   {
      t_size = (text_size > b_size) ? b_size : text_size;
      flist.size = t_size;
      DPRINT3("edit_txt: flist.fnum=%d, flist.start=%d, flist.size=%d\n",
                         flist.fnum, flist.start, flist.size);
      if ((rc = gfield(fld, (char *)0, &flist)) != 0)
      {
         sprintf(errbuf,"edit_txt: gfield error=%d",rc); 
         DPRINT1("\tedit_txt: gfield error=%d",rc); 
         prtmsg(0,22,errbuf);
         retval.aval.inval = terminate(fd, b_ptr, tname, -1);
         DCLOSE;
         chookrt(&retval);
         return;
      }

      if ((rc = write(fd, b_ptr, (unsigned)t_size)) != t_size)
      {
         sprintf(errbuf,"edit_txt: write error on file=%s",tname);  
         DPRINT1("edit_txt: write error on file=%s",tname);  
         prtmsg(0,22,errbuf);
         retval.aval.inval = terminate(fd, b_ptr, tname, -1);
         DCLOSE;
         chookrt(&retval);
         return;
      }
      flist.start += t_size;
      text_size -= t_size;
   }

   /* Free previously allocated buffer */
   free(b_ptr);
   b_ptr = NULL;

   /* Note the file modification time */
   if ((rc = fstat(fd, &stat_buf)) != 0)
   {
      sprintf(errbuf,"edit_txt: can't fstat file=%s",tname);
      DPRINT1("edit_txt: can't fstat file=%s",tname);
      prtmsg(0,22,errbuf);
      retval.aval.inval = terminate(fd, b_ptr, tname, -1);
      DCLOSE;
      chookrt(&retval);
      return;
   }
   mod_time = stat_buf.st_mtime;

   /* Check for EDIT environment variable */
   if ((editor = (char *)getenv("EDIT")) == NULL)
   {
      editor = "/usr/bin/vedit";
      sprintf(errbuf,"EDIT environment variable is not set, using vedit");
      prtmsg(0,22,errbuf);
   }


   /* save stty settings */
   ioctl(0,TCGETA, &term_buf);

   DPRINT0( "TTY Settings:\n");
   DPRINT1( "c_cflag:   %o\n", term_buf.c_cflag);
   DPRINT1( "c_iflag:   %o\n", term_buf.c_iflag);
   DPRINT1( "c_oflag:   %o\n", term_buf.c_oflag);
   DPRINT1( "c_lflag:   %o\n", term_buf.c_lflag);
   DFLUSH;

   /* Establish new termio values for raw input mode */
   new_termio = term_buf;
   new_termio.c_iflag = IGNBRK;
   new_termio.c_lflag = 0;
   new_termio.c_cc[VMIN]  = 1;
   new_termio.c_cc[VTIME] = 0;

   /* set the new values */
   ioctl(0,TCSETA, &new_termio);

   /* Invoke the editor */
   if ((pid = fork()) == 0)
   {
      if (execlp(editor, editor, tname, NULL) == -1)
      {
         sprintf(errbuf, "can't exec %s, %s", editor, tname);
         DPRINT2( "can't exec %s, %s", editor, tname);
         prtmsg(0,22,errbuf);
         DCLOSE;
         exit(-1);
      }
   }
   else
   {

      DPRINT1( "waiting for pid %d\n", pid);
      DFLUSH;
      while((rc=wait(&wait_sts)) != pid )
      {

         DPRINT3( "! wait returned BAD pid %d, status %d, errno %d\n", rc, wait_sts,errno);
         DFLUSH;
         if( rc == -1 )
         {
            DPRINT1( "! killing process no. %d\n",pid);
            DFLUSH;
            rc=kill(pid,9);
            DPRINT2( "kill return code=%d, errno=%d\n",rc,errno);
            DFLUSH;
            break;
         }
      }

      DPRINT2( "  wait returned OK pid %d, status %d\n", rc, wait_sts);
      DFLUSH;

   }
   /* restore stty settings */
   ioctl( 0, TCSETA, &term_buf);

   DPRINT0("edit_txt: after edit\n");
   /* Write file to database if necessary */
   if ((rc = fstat(fd, &stat_buf)) != 0)
   {
      sprintf(errbuf,"edit_txt: can't fstat file=%s",tname);
      DPRINT1("edit_txt: can't fstat file=%s",tname);
      prtmsg(0,22,errbuf);
      retval.aval.inval = terminate(fd, b_ptr, tname, -1);
      DCLOSE;
      chookrt(&retval);
      return;
   }

   if (stat_buf.st_mtime != mod_time) /* then buffer was modified */
   {
      /* Open buffer for transfer of data from database to temp. file */
      file_size = stat_buf.st_size;

/*********************************** work around code **********************/
      DPRINT1("edit_txt: file_size=%d\n", file_size);
      padded_size = dbv_alloc((long)file_size);
      b_size = (padded_size > TRANS_BUF_SIZE) ? TRANS_BUF_SIZE : padded_size;
      DPRINT2("edit_txt: padded_size=%d, b_size=%d\n", padded_size, b_size);
/***************************************************************************/

      if ((b_ptr = (char *)malloc((unsigned)b_size)) == NULL)
      {
         sprintf(errbuf,"edit_txt: can't retrieve gsize for field=%d",fld);
         DPRINT1("edit_txt: can't retrieve gsize for field=%d",fld);
         prtmsg(0,22,errbuf);
         retval.aval.inval = terminate(fd, b_ptr, tname, -1);
         DCLOSE;
         chookrt(&retval);
         return;
      }
   
      /* Transfer data from database to temp. file */
      flist.fnum = fld;
      flist.fdata = b_ptr;
      flist.mode = FL_TRUNC;
      flist.start = 0L;
      (void) lseek(fd,0L,0);   /* Rewind the temp file */

/*********************** work around code modifications **********************/

      while(file_size > 0)
      {
         t_size = ((file_size > b_size) ? b_size : file_size);
         flist.size = ((padded_size > b_size) ? b_size : padded_size);
         DPRINT3("\tedit_txt: flist.start=%d, flist.size=%d, t_size=%d\n",
                  flist.start, flist.size, t_size);
         (void)memset( b_ptr, '\0', b_size);
         if ((rc=read(fd, b_ptr, (unsigned)t_size)) != t_size)
         {
            DPRINT1("edit_txt: read error, rc=%d\n", rc);
            sprintf(errbuf, "edit_txt: error reading file, rc=%d", rc);
            prtmsg(0,22,errbuf);
            retval.aval.inval = terminate(fd, b_ptr, tname, -1);
            chookrt(&retval);
            return;
         }

         if ((rc=pfield(fld,(char *)0,&flist)) != 0)
         {
            sprintf(errbuf,"edit_txt: pfield error=%d",rc); 
            prtmsg(0,22,errbuf);
            retval.aval.inval = terminate(fd, b_ptr, tname, -1);
            DCLOSE;
            chookrt(&retval);
            return;
         }
         flist.start += t_size;
         file_size   -= t_size;
         padded_size -= t_size;
      }

/************************************************************************/

      retval.aval.inval = terminate(fd, b_ptr, tname, 1);
      chookrt(&retval);
   } /* End if (stat_buf . . . */
   else /* buffer was NOT modified */
   {
      retval.aval.inval = terminate(fd, b_ptr, tname, 0);
      chookrt(&retval);
   }
   DCLOSE;
   return;
}

/* Clean up all open files, buffers, and remove temp. file from directory */
int
terminate(fd, b_ptr, file_name, val)
   int fd;      /* File descriptor */
   char *b_ptr;      /* Buffer area */
   char *file_name;   /* Pointer to file name */
   int  val;      /* Value to return */
{
   if (fd >= 0)
   {
      close(fd);
   }   

   if (b_ptr != NULL)
   {
      free(b_ptr);
   }

   if (*file_name != '\0')
   {
      unlink(file_name);
   }
   return(val);
}

/****************************************************************/

struct allocsize {
   long  boundary;	/* break point for allocation changes	*/
   long  increment;	/* allocation increment below this boundary	*/
};
static struct allocsize btab[] = {
      { 32768L-16L, 32L },
      { (1024L*1024L)-16L, 32768L },
      { (1024L*1024L*1024L)-16L, (1024L*1024L) }
   };
#define BTABSIZ (sizeof(btab) / sizeof(btab[0]))

static long
dbv_alloc(insize)
   long insize;
{
   register int i;
   register long retval;

   for (i=0; i < BTABSIZ; ++i)
   {
      if (insize <= btab[i].boundary)
      {
         break;
      }
   }
   retval =  ((insize / btab[i].increment) + 1) * btab[i].increment - 16L;
   if (retval < insize)
   {
      retval += btab[i].increment;
   }
   return retval;
}
\Rogue\Monster\
else
  echo "will not over write ./edit_txt.c"
fi
if `test ! -s ./extern.h`
then
echo "writing ./extern.h"
cat > ./extern.h << '\Rogue\Monster\'
/* external C-Hook declarations */ 

EXTERN C NUMERIC FUNCTION display_txt($x1, RESULT $x2)
EXTERN C NUMERIC FUNCTION edit_txt($x1)
EXTERN C NUMERIC FUNCTION show_txt($x1)
EXTERN C NUMERIC FUNCTION to_upper($x1, RESULT $x2)
EXTERN C NUMERIC FUNCTION text_size($x1)
EXTERN C NUMERIC FUNCTION week_day()
EXTERN C NUMERIC FUNCTION day_of_week($x1)
\Rogue\Monster\
else
  echo "will not over write ./extern.h"
fi
if `test ! -s ./get_fld_no.c`
then
echo "writing ./get_fld_no.c"
cat > ./get_fld_no.c << '\Rogue\Monster\'
#include <stdio.h>
/*
get_fld_num()   --  gets field number from short field name (or long name)

USAGE:
    int	  field	     
    char *string_ptr    Points to name of desired field 

    field = get_fld_num( string_ptr );

NOTES:
	returns zero if name not recognized 
*/
char *fldname();
char *fldsyn();

/*-------------------------------------------------------------*/
int 	get_fld_num( s_ptr )
char *s_ptr;
{
int  max_field;	/* Highest field index in use in system */
int  fld;			/* Counter */
char *t_ptr; 		/* temp. string pointer */
	
	/*----------------------------------------------------------*/
	/* Find out how many fields are in the database */
	max_field = numflds();
	
	/*----------------------------------------------------------*/
	/* Try all short database names looking for a match */
	for (fld=1; fld<=max_field; fld++ )
	{
		if ( (t_ptr=fldsyn(fld)) != NULL )
		{
			if ( strcmp( s_ptr, t_ptr ) == 0 )	
			{
				return( fld );
			}
		}
		
	}

	/*----------------------------------------------------------*/
	/* Try all long database names looking for a match */
	for (fld=1; fld<=max_field; fld++ )
	{
		if ( (t_ptr=fldname(fld)) != NULL )
		{
			if ( strcmp( s_ptr, t_ptr ) == 0 )	
			{
				return( fld );
			}
		}
		
	}

	/*----------------------------------------------------------*/
	/* Field name not recognized */
	return( -1 );
}
\Rogue\Monster\
else
  echo "will not over write ./get_fld_no.c"
fi
if `test ! -s ./show_txt.c`
then
echo "writing ./show_txt.c"
cat > ./show_txt.c << '\Rogue\Monster\'
/*****************************************************************************
*
* %W%   %G%   %U%
*
*   NAME:           show_txt
*   DESCRIPTION:    Accell/C-hook for displaying a text field
*
*   ACCELL USAGE:   show_txt(target_variable)
*                     where:
*                        target_variable is the long name of
*                                        a UNIFY database field
*
*   AUTHOR:         Mark Hargrove (based on code in edit_txt)
*   DATE:           8/6/87
*
*   RETURNS:
*			0 - successful termination
*	     -1 - unsuccessful termintation
*
*      the buffer memory for the transfer of data from the database
*      into a temporary file and vice versa is allocated as size 
*      TRANS_BUF_SIZE or less.
*
*   Modification History:
*
******************************************************************************/
#include "fdesc.h"
#include "chookincl.h"
#include "dbtypes.h"
#include "domains.h"
#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>

#define TRANS_BUF_SIZE 8192L
#define YES   1
#define NO   0

extern int get_fld_num();

int   
show_txt(numargs, acclarg)
   int numargs;
   AVAL acclarg[];
{
   AVAL retval;
   char *field_name;  /* long name of database field */
   int fld;            /* field number */
   long text_size;   /* Actual size of text in DB */
   off_t   file_size;    /* Actual size of edited temp. file */
   long  t_size;      /* Number of bytes to transfer at a whack */
   int   rc;         /* Return code */
   char tname[20];   /* Name of temporary file */
   int fd;            /* File descriptor */
   char *b_ptr;      /* Pointer to transfer buffer */
   long b_size;      /* Size of transfer buffer */
   FIELDLIST flist;   /* Data transfer descriptor block for gfield and pfield */
   FLDESC fdsc;      /* Data base field descriptor */
   struct stat stat_buf; /* File status block */
   time_t   mod_time; /* Last modification time of file */
   char errbuf[256];  /* For output messages */
   char cmdbuf[256];  /* Command line buffer for edit command */
   char *editor;      /* Points to EDIT environment variable */
   int pid;             /* process id of child */


   /* set up for an error return condition */
   retval.aknd = A_INT; 
   retval.dfflg = YES;

   if (numargs != 1)
   {
      retval.aval.inval = -1;
      chookrt(&retval);
      return;
   }
   if (acclarg[0].dfflg == NO)
   {
      retval.aval.inval = -2;
      chookrt(&retval);
      return;
   }

   field_name = acclarg[0].aval.stval;

   if ((fld = get_fld_num(field_name)) < 0)
   {
      retval.aval.inval = -3;
      chookrt(&retval);
      return;
   }

   /* Initialization */
   b_ptr = NULL;
   tname[0] = '\0'; 
   fd = -1;

   /* Check for valid field type */
   if ((rc = fldesc( fld, &fdsc )) != 1)
   {
      sprintf(errbuf,"edit_txt: got bad field=%d",fld);
      prtmsg(0,22,errbuf);
      retval.aval.inval = terminate(fd, b_ptr, tname, -1);
      chookrt(&retval);
      return;
   }

   if ((rc = fdsc.f_typ) != TEXT )
   {
      sprintf(errbuf,"edit_txt: got non-TEXT field=%d",fld);
      prtmsg(0,22,errbuf);
      retval.aval.inval = terminate(fd, b_ptr, tname, -1);
      chookrt(&retval);
      return;
   }

   /* Get size of actual text in database */
   if ((rc = gsize(fld,&text_size)) != 0)
   {
      sprintf(errbuf,"edit_txt: can't retrieve gsize for field=%d",fld);
      prtmsg(0,22,errbuf);
      retval.aval.inval = terminate(fd, b_ptr, tname, -1);
      chookrt(&retval);
      return;
   }
   
   /* Open a temporary file */
   strcpy(tname,"edtdbXXXXXX");
   mktemp(tname);
   if ((fd=open(tname, O_RDWR | O_CREAT | O_TRUNC, 0666 )) < 0)
   {
      sprintf(errbuf,"edit_txt: can't open temp. file=%s",tname);
      prtmsg(0,22,errbuf);
      retval.aval.inval = terminate(-1,b_ptr,"",-1);
      chookrt(&retval);
      return;
   }

   /* Open buffer for transfer of data from database to temp file */
   b_size = (text_size > TRANS_BUF_SIZE) ? TRANS_BUF_SIZE : text_size;
   if ((b_ptr = (char *)malloc((unsigned)b_size)) == NULL)
   {
      sprintf(errbuf,"edit_txt: can't retrieve gsize for field=%d",fld);
      prtmsg(0,22,errbuf);
      retval.aval.inval = terminate(fd, b_ptr, tname, -1);
      chookrt(&retval);
      return;
   }

   /* Transfer data from database to temporary file */
   flist.fnum = fld;
   flist.fdata = b_ptr;
   flist.mode = FL_TRUNC;
   flist.start = (long)0;
   while(text_size > 0)
   {
      t_size = (text_size > b_size) ? b_size : text_size;
      flist.size = t_size;
      if ((rc = gfield(fld,(char *)0,&flist)) != 0)
      {
         sprintf(errbuf,"edit_txt: gfield error=%d",rc); 
         prtmsg(0,22,errbuf);
         retval.aval.inval = terminate(fd, b_ptr, tname, -1);
         chookrt(&retval);
         return;
      }

      if ((rc = write(fd, b_ptr, (unsigned)t_size)) != t_size)
      {
         sprintf(errbuf,"edit_txt: write error on file=%s",tname);  
         prtmsg(0,22,errbuf);
         retval.aval.inval = terminate(fd, b_ptr, tname, -1);
         chookrt(&retval);
         return;
      }
      flist.start += t_size;
      text_size -= t_size;
   }

   /* Free previously allocated buffer */
   free(b_ptr);
   b_ptr = NULL;

   /* Note the file modification time */
   if ((rc = fstat(fd, &stat_buf)) != 0)
   {
      sprintf(errbuf,"edit_txt: can't fstat file=%s",tname);
      prtmsg(0,22,errbuf);
      retval.aval.inval = terminate(fd, b_ptr, tname, -1);
      chookrt(&retval);
      return;
   }
   mod_time = stat_buf.st_mtime;

   /* Check for EDIT environment variable */
   if ((editor = (char *)getenv("EDIT")) == NULL)
   {
      editor = "/usr/bin/vedit";
      sprintf(errbuf,"EDIT environment variable is not set, using vedit editor");
      prtmsg(0,22,errbuf);
   }

   /* Invoke the editor */
   /* setcook();   */
	/*
   strcpy(cmdbuf, editor);
   strcat(cmdbuf, " ");
   strcat(cmdbuf, tname);
   system(cmdbuf);
	*/

   if ((pid = fork()) == 0)
   {
      if (execlp(editor, editor, tname, NULL) == -1)
      {
         sprintf(errbuf, "can't exec %s, %s", editor, tname);
         prtmsg(0,22,errbuf);
         exit(-1);
      }
   }
   else
   {
      wait(NULL);
   }
   setraw();
	retval.aval.inval = terminate(fd, b_ptr, tname, 0);
	chookrt(&retval);
	return;
}
\Rogue\Monster\
else
  echo "will not over write ./show_txt.c"
fi
if `test ! -s ./text_size.c`
then
echo "writing ./text_size.c"
cat > ./text_size.c << '\Rogue\Monster\'
/*****************************************************************************
*
* %W%   %G%   %U%
*
*   NAME:           text_size
*   DESCRIPTION:    Accell/C-hook for determining actual size of a text field
*
*   ACCELL USAGE:   text_size(target_variable)
*                     where:
*                        target_variable is the long name of
*                                        a UNIFY database field
*
*   AUTHOR:         Mark Hargrove
*   DATE:           8/25/87
*
*   RETURNS:
*		 size of text on successul return
*      < 0 on error return
*
******************************************************************************/
#include "fdesc.h"
#include "chookincl.h"
#include "dbtypes.h"
#include "domains.h"
#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>

#define YES   1
#define NO   0

extern int get_fld_num();

int   
text_size(numargs, acclarg)
   int numargs;
   AVAL acclarg[];
{
   AVAL retval;
   char *field_name;  /* long name of database field */
   int fld;            /* field number */
   long txt_size;   /* Actual size of text in DB */
   int   rc;         /* Return code */
   FIELDLIST flist;   /* Data transfer descriptor block for gfield and pfield */
   FLDESC fdsc;      /* Data base field descriptor */
   char errbuf[256];  /* For output messages */

   /* set up for an error return condition */
   retval.aknd = A_INT; 
   retval.dfflg = YES;

   if (numargs != 1)
   {
      retval.aval.inval = -1;
      chookrt(&retval);
      return;
   }
   if (acclarg[0].dfflg == NO)
   {
      retval.aval.inval = -2;
      chookrt(&retval);
      return;
   }

   field_name = acclarg[0].aval.stval;

   if ((fld = get_fld_num(field_name)) < 0)
   {
      retval.aval.inval = -3;
      chookrt(&retval);
      return;
   }

   /* Check for valid field type */
   if ((rc = fldesc( fld, &fdsc )) != 1)
   {
      sprintf(errbuf,"txt_size: got bad field=%d",fld);
      prtmsg(0,22,errbuf);
      retval.aval.inval = -4;
      chookrt(&retval);
      return;
   }

   if ((rc = fdsc.f_typ) != TEXT )
   {
      sprintf(errbuf,"txt_size: got non-TEXT field=%d",fld);
      prtmsg(0,22,errbuf);
      retval.aval.inval = -5;
      chookrt(&retval);
      return;
   }

   /* Get size of actual text in database */
   if ((rc = gsize(fld, &txt_size)) != 0)
   {
      sprintf(errbuf,"text_size: can't retrieve gsize for field=%d",fld);
      prtmsg(0,22,errbuf);
      retval.aval.inval = -6;
      chookrt(&retval);
      return;
   }
	retval.aval.inval = txt_size;
	chookrt(&retval);
	return;
}
\Rogue\Monster\
else
  echo "will not over write ./text_size.c"
fi
if `test ! -s ./to_upper.c`
then
echo "writing ./to_upper.c"
cat > ./to_upper.c << '\Rogue\Monster\'
/*****************************************************************************
*
* %W%   %G%   %U%
*
*   NAME:           to_upper
*   DESCRIPTION:    Accell/C-hook for converting a string to all upper case
*
*   ACCELL USAGE:   to_upper(string)
*                     where:
*                        string 			is a string value
*
*   AUTHOR:         Mark Hargrove
*   DATE:            7/30/87
*
*   Modification History:
*
******************************************************************************/
#include <chookincl.h>
#define YES 1
#define NO  0

int
to_upper(numargs, acclarg)
	int numargs;
	AVAL acclarg[];
{
	AVAL retval;
	register int i;

	/* set up for an error return condition */
	retval.aknd = A_INT; 
	retval.dfflg = YES;

	if (numargs != 2)
	{
		retval.aval.inval = 1;
		chookrt(&retval);
		return;
	}
	if (acclarg[0].dfflg == NO || acclarg[1].dfflg == NO)
	{
		retval.aval.inval = 2;
		chookrt(&retval);
		return;
	}
	if (acclarg[0].aknd != A_STR || acclarg[1].aknd != A_STR)
	{
		retval.aval.inval = 3;
		chookrt(&retval);
		return;
	}
	if (strlen(acclarg[0].aval.stval) > strlen(acclarg[1].aval.stval))
	{
		retval.aval.inval = 4;
		chookrt(&retval);
		return;
	}
	cfill('\0', acclarg[1].aval.stval, strlen(acclarg[1].aval.stval));
	for (i = 0; i < strlen(acclarg[0].aval.stval); i++)
		acclarg[1].aval.stval[i] = toupper(acclarg[0].aval.stval[i]);
		
	retval.aval.inval = 0;
	chookrt(&retval);
	return;
}
\Rogue\Monster\
else
  echo "will not over write ./to_upper.c"
fi
if `test ! -s ./week_day.c`
then
echo "writing ./week_day.c"
cat > ./week_day.c << '\Rogue\Monster\'
/******************************************************************************
*  PROGRAM    :  week_day
*  DESCRIPTION:  returns the day of the week given the current date
*
*  AUTHOR     :  Scott Henry    
*  DATE       :  11/18/87  
******************************************************************************/
#include <time.h>
#include <stdio.h>
#include <chookincl.h>
#define YES 1
#define NO  0
extern int errno;
static char *RCSid = "$Header: week_day.c,v 1.2 88/01/20 16:29:47 root Exp $";

int
week_day(numargs, acclarg)		/* returns 0 = Sunday, 6 = Saturday */
	int numargs;
	AVAL acclarg[];
{
	AVAL	retval;
	long	clock, time();
	struct	tm *timex;

	/* set up for an error return */
	retval.aknd  = A_INT;
	retval.dfflg = YES;
	retval.aval.inval = 0;

	if (numargs == 0)
	{				/* day-of-week based on system clock */
		clock = time((long *)0);
		timex = localtime(&clock);
		retval.aval.inval = timex->tm_wday;
	}
	chookrt(&retval);
	return;
}

/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/

int
day_of_week( numarg, acclarg)
   int numarg;
   AVAL acclarg[];
{
	AVAL	retval;
	long	udate;

	/* set up for an error return */
	retval.aknd  = A_INT;
	retval.dfflg = YES;
	retval.aval.inval = 0;

	if (numarg == 1 && acclarg[0].dfflg == YES && acclarg[0].aknd == A_DATE)
	{				/* day-of-week based on input date */
		udate = acclarg[0].aval.daval;
		retval.aval.inval = (udate + 32764L) % 7;
	}

	chookrt(&retval);
	return;
}

/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
$Log:	week_day.c,v $
 * Revision 1.2  88/01/20  16:29:47  root
 * baseline before code changes to workaround .dbv bug
 * 
 * Revision 1.1  87/11/18  12:19:31  scotth
 * Initial revision
 * 
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
\Rogue\Monster\
else
  echo "will not over write ./week_day.c"
fi
if `test ! -s ./fedit.fs`
then
echo "writing ./fedit.fs"
cat > ./fedit.fs << '\Rogue\Monster\'
/******************************************************************************
*  $Header: fedit.fs,v 2.1 88/01/13 09:30:36 scotth Exp $
*
*  FORM       :  fedit
*  DESCRIPTION:  text editor interface for Accell using c-hooks
*                in the customized AMGR
*
*  AUTHOR     :  Mark Hargrove  
*  DATE       :  11/11/87  
*
******************************************************************************/
#include "extern.h"

FORM fedit

#include "common.h"

/*****************************  FIELD SECTION ********************************/

FIELD s_text

	BEFORE FIELD
		display 'Loading Editor...' for fyi_message
		set $rc to edit_txt($glob_text_field)
		repaint screen
		if $rc < 0 then 
		begin
			display 'edit_txt returned error: ' + val_to_str$($rc) for fyi_message wait
		end
		next action is previous form

/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
$Log:	fedit.fs,v $
Revision 2.1  88/01/13  09:30:36  scotth
Frozen for 1.0 Release

Revision 2.0  87/12/18  12:04:00  scotth
first release

Revision 1.7  87/11/25  08:45:52  scotth
Alpha-1 release

Revision 1.5  87/11/23  14:08:25  scotth
frozen for Alpha test

Revision 1.1  87/11/11  16:14:50  scotth
mostly working state

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
\Rogue\Monster\
else
  echo "will not over write ./fedit.fs"
fi
if `test ! -s ./fedit.fq.uue`
then
echo "writing ./fedit.fq.uue"
cat > ./fedit.fq.uue << '\Rogue\Monster\'

begin 664 fedit.fq
M4U$``0`$```!20```&X``69E9&ET````````````````````````````````N
M`````````````````````````````````````````````````````````````
M``````````````````````````````#R```!<P``````````````````````F
M`````````````````````````````````````````````````````````````
M````````````````````````````````````````````%@`'``$````!````?
M```!````````````````````"``=``8`$@`````````/``IF961I="YH;'``5
M`````0````````````````````````$!`0$!`0$!```!`````'-?=&5X=```A
M```````````!`)@``0`"````````!`!F`PP```,!```````````/<U]I;7!EE
M;F1I;E]H;'``````%@T@(%!L96%S90T@(%=A:70N+BX-#0``````````````/
B`````````````````````````````````````````````````
``
end
size 439
\Rogue\Monster\
else
  echo "will not over write ./fedit.fq.uue"
fi
echo "Finished archive 5 of 5"
exit


-- 
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Mark A. Hargrove                                             U.S. TeleCenters
Voice: 408-496-1800                                          Santa Clara, CA
uucp : {dual, hoptoad, hplabs, portal, ptsfa}!well!ustel