[comp.sources.sun] v02i030: Casio BOSS Digital Diary <-> Sparcstation, Part04/06

mcgrew@aramis.rutgers.edu (Charles Mcgrew) (10/24/90)

Submitted-by: chuck@trantor.harris-atd.com (Chuck Musciano)
Posting-number: Volume 2, Issue 30
Archive-name: boss-sparc/part04

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 4 (of 6)."
# Contents:  boss.info casio_slave.c object.c print.c
# Wrapped by chuck@melmac on Tue Oct 16 08:53:05 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'boss.info' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'boss.info'\"
else
echo shar: Extracting \"'boss.info'\" \(7734 characters\)
sed "s/^X//" >'boss.info' <<'END_OF_FILE'
X# 
X# boss.info - User interface object help text.
X# This file was generated by `gxv' from `boss.G'.
X# DO NOT EDIT BY HAND.
X# 
X:main_control
XBoss 1.0 provides an interface between your workstation and a Casio BOSS Digital Diary.  Using Boss 1.0, you can load and store data to and from your Casio BOSS.
X# 
X:file_button
XThe "File" button provides access to the basic Boss functions: loading and storing data, as well as converting schedule items to other formats.
X# 
X:view_button
XThe "View" button provides access to the "Clear entries" dialog box.
X# 
X:edit_button
XThe "Edit" button provides access to the "Port Properties" dialog box.
X# 
X:main_display
XBoss 1.0 provides an interface between your workstation and a Casio BOSS Digital Diary.  Using Boss 1.0, you can load and store data to and from your Casio BOSS.
X# 
X:message1
XThe icons displayed in the Boss 1.0 main window indicate the number of items currently held by the tool.  The values will change during load and clear operations.
X# 
X:message2
XThe icons displayed in the Boss 1.0 main window indicate the number of items currently held by the tool.  The values will change during load and clear operations.
X# 
X:message3
XThe icons displayed in the Boss 1.0 main window indicate the number of items currently held by the tool.  The values will change during load and clear operations.
X# 
X:message4
XThe icons displayed in the Boss 1.0 main window indicate the number of items currently held by the tool.  The values will change during load and clear operations.
X# 
X:message5
XThe icons displayed in the Boss 1.0 main window indicate the number of items currently held by the tool.  The values will change during load and clear operations.
X# 
X:phone
XThis value indicates the number of phone objects curently held by Boss 1.0.  Clearing entries or loading new data may cause this value to change.
X# 
X:schedule
XThis value indicates the number of schedule objects curently held by Boss 1.0.  Clearing entries or loading new data may cause this value to change.
X# 
X:memo
XThis value indicates the number of memo objects curently held by Boss 1.0.  Clearing entries or loading new data may cause this value to change.
X# 
X:card
XThis value indicates the number of business card objects curently held by Boss 1.0.  Clearing entries or loading new data may cause this value to change.
X# 
X:calendar
XThis value indicates the number of calendar objects curently held by Boss 1.0.  Clearing entries or loading new data may cause this value to change.
X# 
X:load_control
XThe "Load Data" dialog reads BOSS objects from one of three sources: the BOSS itself, a special Casio-format file, or a plain ASCII text file.  This data is then stored in the Boss's internal memory.
X
XWhen reading from the Casio BOSS, data is read from your machine's serial port.
X
XWhen reading from a Casio-format file, the file must have been previously written by Boss.
X
XData read from ASCII files is converted into a sequence of memo entries, with as much text as possible placed into each entry.
X# 
X:source
XThis selection lets you choose the source from which BOSS data will be read.
X
XWhen reading from the Casio BOSS, data is read from your machine's serial port.
X
XWhen reading from a Casio-format file, the file must have been previously written by Boss.
X
XData read from ASCII files is converted into a sequence of memo entries, with as much text as possible placed into each entry.
X# 
X:casio_source
XThis text field is enabled when you choose to load data from a Casio-format file.  You should specify the name of a file previously created by Boss using the "Casio-format file" option of the "Store Data" dialog.
X# 
X:ascii_source
XThis text field is used to specify the name of a file from which ASCII text will be read and converted into BOSS memo entries.
X# 
X:load_accept
XWhen the "Load" button is pressed, data will be read from the selected source.
X
XIf you are reading from a Casio BOSS, make sure that you click this button BEFORE you start transmission by pressing "Set" on the BOSS.
X# 
X:store_control
XThe "Store Data" dialog lets you store any or all items held in Boss memory to either your Casio BOSS, a Casio-format file, or a plain ASCII file.
X
XWhen storing to the BOSS, items will be written to the serial port.
X
XWhen writing a Casio-format file, all object attributes are preserved for later reloading by Boss.  This format should be used to back up your BOSS data.
X
XASCII text files can be used to transfer BOSS data to another tool, and is suitable for printing.
X
X# 
X:store_data
XThis selection lets you choose which items will be stored in the selected destination.  Only those items slected here will be written to the destination.
X# 
X:dest
XThis selection lets you choose the destination to which BOSS data will be stored.
X
XWhen storing to the BOSS, items will be written to the serial port.
X
XWhen writing a Casio-format file, all object attributes are preserved for later reloading by Boss.  This format should be used to back up your BOSS data.
X
XASCII text files can be used to transfer BOSS data to another tool, and is suitable for printing.
X
X# 
X:casio_dest
XThis text field is enabled when you choose to store data to a Casio-format file.  data written to this file is intended to be read only by Boss.
X# 
X:ascii_dest
XThis text field is used to specify the name of a file to which ASCII text will be written.
X# 
X:store_accept
XWhen the "Store" button is clicked, the selected data objects are written to the specified destination.
X# 
X:clear_control
XThe "Clear Data" dialog box lets you delete objects from the Boss 1.0 memory.  You may want to delete items from memory before loading new data, since the load operation does not clear old entries before reading in new ones.
X# 
X:clear_data
XThis selection lets you choose which items will be cleared from the Boss memory.
X# 
X:clear_accept
XWhen pressed, this button will clear the selected items from the Boss memory.
X# 
X:port_control
XThe "Port Properties" dialog lets you modify the port used to communicate with the Casio BOSS.  You should adjust the settings in this dialog box to match the communications settings in your Casio BOSS.
X# 
X:port_port
XThis setting lets you choose which port Casio data will be read and written to.  Select the port into which you have plugged your Casio BOSS serial cable.
X# 
X:port_baud
XThis setting lets you set the baud rate at which communication with your Casio BOSS will occur.  The value should match the rate set in your BOSS communication settings.
X
XHigher rates mean faster transfers, but errors may occur.  If you experience transmission errors, use a slower rate.
X# 
X:port_parity
XThis setting lets you set the parity at which communication with your Casio BOSS will occur.  The value should match the parity set in your BOSS communication settings.
X
X# 
X:port_accept
XClicking the "Apply" button will make the selected port properties the new values to be used for subsequent communication with the Casio BOSS.
X# 
X:port_reset
XClicking the "Reset" button will restore the port properties to the values in effect when you entered this dialog box.
X# 
X:schedule_control
XThe "Schedule Appointments" dialog box lets you convert BOSS schedule entries into formats compatible with other schedule management tools.
X# 
X:schedule_format
XThis selection lets you choose the format to which the BOSS schedule items will be converted.
X# 
X:appt_file
XIf you are converting schedule items to calentool format, this text field lets you enter the name of the file containing your calentool appointments.  Normally, this is ~/.appointments.
X# 
X:schedule_accept
XWhen you click the "Schedule" button, the schedule items held in Boss memory will be converted to the desired format.  Certain files may be modified during the conversion.
END_OF_FILE
if test 7734 -ne `wc -c <'boss.info'`; then
    echo shar: \"'boss.info'\" unpacked with wrong size!
fi
# end of 'boss.info'
fi
if test -f 'casio_slave.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'casio_slave.c'\"
else
echo shar: Extracting \"'casio_slave.c'\" \(9482 characters\)
sed "s/^X//" >'casio_slave.c' <<'END_OF_FILE'
X/************************************************************************/
X/*	Copyright 1990 by Chuck Musciano and Harris Corporation		*/
X/*									*/
X/*	Permission to use, copy, modify, and distribute this software	*/
X/*	and its documentation for any purpose and without fee is	*/
X/*	hereby granted, provided that the above copyright notice	*/
X/*	appear in all copies and that both that copyright notice and	*/
X/*	this permission notice appear in supporting documentation, and	*/
X/*	that the name of Chuck Musciano and Harris Corporation not be	*/
X/*	used in advertising or publicity pertaining to distribution	*/
X/*	of the software without specific, written prior permission.	*/
X/*	Chuck Musciano and Harris Corporation make no representations	*/
X/*	about the suitability of this software for any purpose.  It is	*/
X/*	provided "as is" without express or implied warranty.		*/
X/*									*/
X/*	This code contains data and information that is proprietary	*/
X/*	to Casio Corporation.  You may be subject to legal action if	*/
X/*	this information is released without explicit permission from	*/
X/*	Casio.								*/
X/************************************************************************/
X
X/************************************************************************/
X/*									*/
X/*	casio_slave.c		handle low-level BOSS i/o		*/
X/*									*/
X/************************************************************************/
X
X#include	<stdio.h>
X#include	<sys/types.h>
X#include	<sys/time.h>
X#include	<sys/termios.h>
X#include	<sys/file.h>
X
X#include	"manifest.h"
X#include	"casio.h"
X#include	"protocol.h"
X
XPUBLIC	int	errno;
XPUBLIC	char	*sys_errlist[];
X
XPRIVATE	int	baud_rate[] = {B1200, B2400, B4800, B9600};
XPRIVATE	int	parity[] = {PARENB, PARENB | PARODD, 0};
X
XPRIVATE	int	casio = -1;
XPRIVATE	int	previous_byte = -1;
X
XPRIVATE	FILE	*commands_in;
XPRIVATE	FILE	*results_out;
X
X/************************************************************************/
XPRIVATE	return_result(a, b, c, d, e, f)
X
Xint	a, b, c, d, e, f;
X
X{	char	buf[512];
X
X	if (a == NULL)
X	   putc(0, results_out);
X	else {
X	   sprintf(buf, a, b, c, d, e, f);
X	   putc(strlen(buf), results_out);
X	   fprintf(results_out, buf);
X	   }
X	fflush(results_out);
X}
X
X/************************************************************************/
XPRIVATE	open_casio(port, baud, par)
X
Xchar	*port;
Xint	baud;
Xint	par;
X
X{	struct	termios tbuf;
X
X	if ((casio = open(port, O_RDWR)) == -1) {
X	   return_result("could not access %s", port);
X	   return;
X	   }
X	if (ioctl(casio, TCGETS, &tbuf) == -1) {
X	   close(casio);
X	   casio = -1;
X	   return_result("error getting parameters for %s (%s)", port, sys_errlist[errno]);
X	   return;
X	   }
X	tbuf.c_iflag = IGNBRK | IXON | IXOFF;
X	tbuf.c_oflag = 0;
X	tbuf.c_cflag = baud_rate[baud] | parity[par] | CS8 | CREAD;
X	tbuf.c_lflag = 0;
X	tbuf.c_cc[VMIN] = 0;
X	tbuf.c_cc[VTIME] = 0;
X	if (ioctl(casio, TCSETS, &tbuf) == -1) {
X	   close(casio);
X	   casio = -1;
X	   return_result("error setting parameters for %s (%s)", port, sys_errlist[errno]);
X	   return;
X	   }
X	return_result(NULL);
X}
X
X/************************************************************************/
XPRIVATE	close_casio()
X
X{
X	close(casio);
X	casio = -1;
X	return_result(NULL);
X}
X
X/************************************************************************/
XPRIVATE	int	read_casio(buf, len, max_time)
X
Xbyte	*buf;
Xint	len;
X
X{	int	result, amount;
X	fd_set	fd;
X	struct	timeval	timeout;
X
X	amount = 0;
X	if (previous_byte != -1) {
X	   *buf = previous_byte;
X	   amount++;
X	   previous_byte = -1;
X	   }
X	timeout.tv_sec = max_time / 1000;
X	timeout.tv_usec = (max_time % 1000) * 1000;
X	while (amount < len) {
X	   FD_ZERO(&fd);
X	   FD_SET(casio, &fd);
X	   switch (select(getdtablesize(), &fd, NULL, NULL, &timeout)) {
X	      case 0  : return_result(NULL);
X	      		return(amount);
X	      case 1  : result = read(casio, buf + amount, len - amount);
X	   	        if (result == -1) {
X	   		   return_result("error reading from BOSS: %s", sys_errlist[errno]);
X	   		   return(-1);
X	   		   }
X	   	        else
X	   	           amount += result;
X	   	        break;
X	      default : return_result("error awaiting data from BOSS: %s", sys_errlist[errno]);
X	   	        return(-1);
X	      }
X	   }
X	return_result(NULL);
X	return(len);
X}
X
X/************************************************************************/
XPRIVATE	int	write_casio(buf, len)
X
Xbyte	*buf;
Xint	len;
X
X{	int	result;
X
X	if ((result = write(casio, buf, len)) == -1)
X	   return_result("error writing to BOSS: %s", sys_errlist[errno]);
X	else
X	   return_result(NULL);
X	return(result);
X}
X
X/************************************************************************/
XPRIVATE	enable_flow_control()
X
X{	struct	termios tbuf;
X
X	if (casio != -1)
X	   if (ioctl(casio, TCGETS, &tbuf) == -1)
X	      return_result("error getting parameters for BOSS in enable_flow_control: %s", sys_errlist[errno]);
X	   else {
X	      tbuf.c_iflag |= IXON | IXOFF;
X	      if (ioctl(casio, TCSETS, &tbuf) == -1)
X	         return_result("error setting parameters for BOSS in enable_flow_control: %s", sys_errlist[errno]);
X	      else
X	         return_result(NULL);
X	      }
X	else
X	   return_result("attempt to enable flow control without opening BOSS");
X}
X
X/************************************************************************/
XPRIVATE	disable_flow_control()
X
X{	struct	termios tbuf;
X
X	if (casio != -1)
X	   if (ioctl(casio, TCGETS, &tbuf) == -1)
X	      return_result("error getting parameters for BOSS in disable_flow_control: %s", sys_errlist[errno]);
X	   else {
X	      tbuf.c_iflag &= ~(IXON | IXOFF);
X	      if (ioctl(casio, TCSETS, &tbuf) == -1)
X	         return_result("error setting parameters for BOSS in disable_flow_control: %s", sys_errlist[errno]);
X	      else
X	         return_result(NULL);
X	      }
X	else
X	   return_result("attempt to disable flow control without opening BOSS");
X}
X
X/************************************************************************/
XPRIVATE	flush_casio()
X
X{
X	if (ioctl(casio, TCFLSH, 2) == -1)
X	   return_result("could not flush BOSS output queue: %s", sys_errlist[errno]);
X	else
X	   return_result(NULL);
X}
X
X/************************************************************************/
XPRIVATE	unget_byte(b)
X
Xbyte	b;
X
X{
X	if (previous_byte == -1) {
X	   previous_byte = b;
X	   return_result(NULL);
X	   }
X	else
X	   return_result("unget_byte overrun!");
X}
X
X/************************************************************************/
XEXPORT	start_slave_handler(commands, results)
X
Xint	commands;
Xint	results;
X
X{	int	buf_size, cmd, baud, parity, len, b, timeout;
X	char	*buf;
X
X	if ((commands_in = fdopen(commands, "r")) == NULL) {
X	   fprintf(stderr, "Could not fdopen commands: %s", sys_errlist[errno]);
X	   exit(1);
X	   }
X	if ((results_out = fdopen(results, "w")) == NULL) {
X	   fprintf(stderr, "Could not fdopen results: %s", sys_errlist[errno]);
X	   exit(1);
X	   }
X	buf = (char *) malloc(buf_size = 1024);
X	while ((cmd = getc(commands_in)) != EOF)
X	   switch (cmd) {
X	      case OPEN_CASIO           : if ((baud = getc(commands_in)) != EOF)
X	      				     if ((parity = getc(commands_in)) != EOF)
X	      				        if ((len = getc(commands_in)) != EOF)
X	      				           if (fread(buf, 1, len, commands_in) == len) {
X	      				              if (buf_size < len)
X	      				                 buf = (char *) realloc(buf, buf_size = len);
X	      				              buf[len] = '\0';
X	      				              open_casio(buf, baud, parity);
X	      				              continue;
X	      				              }
X	      				  return_result("Error reading OPEN_CASIO parameters in Casio slave");
X	      				  break;
X	      case CLOSE_CASIO          : close_casio();
X	      				  break;
X	      case READ_CASIO           : if (fread(&len, 1, sizeof(int), commands_in) == sizeof(int))
X	      				     if (fread(&timeout, 1, sizeof(int), commands_in) == sizeof(int)) {
X	      				        if (buf_size < len)
X	      				           buf = (char *) realloc(buf, buf_size = len);
X	      				        if ((b = read_casio(buf, len, timeout)) != -1) {
X	      				           fwrite(&b, 1, sizeof(int), results_out);
X	      				           if (b > 0)
X	      				              fwrite(buf, 1, b, results_out);
X	      				           fflush(results_out);
X	      				           continue;
X	      				           }
X	      				        }
X	      				  return_result("Error reading READ_CASIO parameters in Casio slave");
X	      				  break;
X	      case WRITE_CASIO          : if (fread(&len, 1, sizeof(int), commands_in) == sizeof(int)) {
X	      				     if (buf_size < len)
X	      				        buf = (char *) realloc(buf, buf_size = len);
X	      				     if (fread(buf, 1, len, commands_in) == len) {
X	      				        if ((b = write_casio(buf, len)) != -1) {
X	      				           fwrite(&b, 1, sizeof(int), results_out);
X	      				           fflush(results_out);
X	      				           continue;
X	      				           }
X	      				        }
X	      				     }
X	      				  return_result("Error reading WRITE_CASIO parameters in Casio slave");
X	      				  break;
X	      case ENABLE_FLOW_CONTROL  : enable_flow_control();
X	      				  break;
X	      case DISABLE_FLOW_CONTROL : disable_flow_control();
X	      				  break;
X	      case FLUSH_CASIO          : flush_casio();
X	      				  break;
X	      case UNGET_BYTE           : if ((b = getc(commands_in)) != EOF)
X	      				     unget_byte(b);
X	      				  break;
X	      default                   : return_result("Unknown protocol command: %d", cmd);
X	      				  break;
X	      }
X	close(commands);
X	close(results);
X}
END_OF_FILE
if test 9482 -ne `wc -c <'casio_slave.c'`; then
    echo shar: \"'casio_slave.c'\" unpacked with wrong size!
fi
# end of 'casio_slave.c'
fi
if test -f 'object.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'object.c'\"
else
echo shar: Extracting \"'object.c'\" \(10076 characters\)
sed "s/^X//" >'object.c' <<'END_OF_FILE'
X/************************************************************************/
X/*	Copyright 1990 by Chuck Musciano and Harris Corporation		*/
X/*									*/
X/*	Permission to use, copy, modify, and distribute this software	*/
X/*	and its documentation for any purpose and without fee is	*/
X/*	hereby granted, provided that the above copyright notice	*/
X/*	appear in all copies and that both that copyright notice and	*/
X/*	this permission notice appear in supporting documentation, and	*/
X/*	that the name of Chuck Musciano and Harris Corporation not be	*/
X/*	used in advertising or publicity pertaining to distribution	*/
X/*	of the software without specific, written prior permission.	*/
X/*	Chuck Musciano and Harris Corporation make no representations	*/
X/*	about the suitability of this software for any purpose.  It is	*/
X/*	provided "as is" without express or implied warranty.		*/
X/*									*/
X/*	This code contains data and information that is proprietary	*/
X/*	to Casio Corporation.  You may be subject to legal action if	*/
X/*	this information is released without explicit permission from	*/
X/*	Casio.								*/
X/************************************************************************/
X
X/************************************************************************/
X/*									*/
X/*	object.c	manage BOSS data objects			*/
X/*									*/
X/************************************************************************/
X
X#include	"manifest.h"
X#include	"record.h"
X#include	"object.h"
X
XPRIVATE	char	*object_name[] = {"telephone", "schedule", "memo", "card", "calendar"};
X
X/************************************************************************/
XEXPORT	object	*create_object()
X
X{	object	*obj;
X
X	obj = (object *) malloc(sizeof(object));
X	bzero(obj, sizeof(object));
X	return(obj);
X}
X
X/************************************************************************/
XEXPORT	free_object(obj)
X
Xobject	*obj;
X
X{
X	if (obj->buf)
X	   free(obj->buf);
X	free(obj);
X}
X
X/************************************************************************/
XEXPORT	free_object_list(obj)
X
Xobject	*obj;
X
X{	object	*o;
X
X	while (obj) {
X	   o = obj;
X	   obj = obj->next;
X	   free_object(o);
X	   }
X}
X
X/************************************************************************/
XEXPORT	object	*text_to_object(buf)
X
Xbyte	*buf;
X
X{	object	*obj;
X
X	obj = create_object();
X	obj->kind = OBJ_MEMO;
X	obj->buf = (byte *) malloc(sizeof(byte) * MAX_OBJECT_DATA);
X	strcpy(obj->buf, buf);
X	for (buf = obj->buf; *buf; buf++)
X	   if (*buf == '\n')
X	      *buf = '\r';
X	obj->mem_memo = obj->buf;
X	return(obj);
X}
X
X/************************************************************************/
XEXPORT	object	*record_to_object(rec)
X
Xrecord	*rec;
X
X{	object	*obj;
X	byte	*p;
X	int	i;
X
X	if (rec->type != REC_MODE)
X	   return(NULL);
X	obj = create_object();
X	obj->from_casio = TRUE;
X	for ( ; rec; rec = rec->next)
X	   switch(rec->type) {
X	      case REC_DATA     : if (address_kind(rec->address) == REC_DATA_DATA) {
X	      			     if (obj->buf == NULL) {
X	      			        obj->buf = (byte *) malloc(sizeof(byte) * MAX_OBJECT_DATA);
X	      			        bzero(obj->buf, sizeof(byte) * MAX_OBJECT_DATA);
X	      			        }
X	      			     bcopy(rec->data, obj->buf + address_start(rec->address), rec->length);
X	      			     }
X	      			  else if (address_kind(rec->address) == REC_DATA_ALARM) {
X	      			     if (obj->kind == OBJ_SCHEDULE)
X	      			        ascii_to_time(rec->data, &obj->sch_alarm_time, NULL);
X	      			     else {
X	      			        error("alarm data encountered for %s object", object_name[obj->kind]);
X	      			        free_object(obj);
X	      			        return(NULL);
X	      			        }
X	      			     }
X	      			  else if (address_kind(rec->address) == REC_DATA_BINARY) {
X	      			     if (obj->kind == OBJ_CALENDAR)
X	      			        obj->cal_marked = ascii_to_long(rec->data);
X	      			     else {
X	      			        error("binary data encountered for %s object", object_name[obj->kind]);
X	      			        free_object(obj);
X	      			        return(NULL);
X	      			        }
X	      			     }
X	      			  else if (address_kind(rec->address) == REC_DATA_TIME) {
X	      			     if (obj->kind == OBJ_SCHEDULE)
X	      			        ascii_to_time(rec->data, &(obj->sch_start_time), &(obj->sch_stop_time));
X	      			     else {
X	      			        error("time data encountered for %s object", object_name[obj->kind]);
X	      			        free_object(obj);
X	      			        return(NULL);
X	      			        }
X	      			     }
X	      			  else if (address_kind(rec->address) == REC_DATA_DATE) {
X	      			     if (obj->kind == OBJ_SCHEDULE)
X	      			        ascii_to_date(rec->data, &(obj->sch_date));
X	      			     else if (obj->kind == OBJ_CALENDAR)
X	      			        ascii_to_date(rec->data, &(obj->cal_date));
X	      			     else {
X	      			        error("date data encountered for %s object", object_name[obj->kind]);
X	      			        free_object(obj);
X	      			        return(NULL);
X	      			        }
X	      			     }
X	      			  else {
X	      			     error("unknown address offset (%04x) in record_to_object", address_kind(rec->address));
X	      			     free_object(obj);
X	      			     return(NULL);
X	      			     }
X	      			  break;
X	      case REC_REGISTER : if (rec->address == REC_REGISTER_MARKED)
X	      			     obj->marked = TRUE;
X	      			  if (rec->next != NULL)
X	      			     error("extra data after register record in record_to_object");
X	      			  break;
X	      case REC_MODE     : if (*((word *) rec->data) == REC_MODE_CALENDAR)
X	      			     obj->kind = OBJ_CALENDAR;
X	      			  else if (*((word *) rec->data) == REC_MODE_TELEPHONE)
X	      			     obj->kind = OBJ_TELEPHONE;
X	      			  else if (*((word *) rec->data) == REC_MODE_MEMO)
X	      			     obj->kind = OBJ_MEMO;
X	      			  else if (*((word *) rec->data) == REC_MODE_SCHEDULE) {
X	      			     obj->kind = OBJ_SCHEDULE;
X	      			     obj->sch_start_time.hour = INVALID_TIME;
X	      			     obj->sch_stop_time.hour = INVALID_TIME;
X	      			     obj->sch_alarm_time.hour = INVALID_TIME;
X	      			     }
X	      			  else if (*((word *) rec->data) == REC_MODE_CARD)
X	      			     obj->kind = OBJ_CARD;
X	      			  else {
X	      			     error("unknown record mode (%04x) in record_to_object", *((word *) rec->data));
X	      			     free_object(obj);
X	      			     return(NULL);
X	      			     }
X	      			  break;
X	      default		: error("unknown record type (%02x) in record_to_object", rec->type);
X	      			  free_object(obj);
X	      			  return(NULL);
X	      }
X	if (obj->buf) {
X	   obj->field[0] = obj->buf;
X	   for (p = obj->buf, i = 1; *p; p++)
X	      if (*p == CASIO_END_ENTRY) {
X	         *p = '\0';
X	         obj->field[i++] = p + 1;
X	         }
X	   for ( ; i < MAX_FIELDS; i++)
X	      obj->field[i] = NULL;
X	   }
X	else
X	   for (i = 0; i < MAX_FIELDS; i++)
X	      obj->field[i] = NULL;
X	return(obj);
X}
X
X/************************************************************************/
XEXPORT	record	*object_to_record(obj)
X
Xobject	*obj;
X
X{	record	*head, *rec;
X	int	i;
X	byte	*p, *q;
X
X	head = rec = make_mode_record(0); /* use a dummy mode value */
X	if (obj->kind == OBJ_TELEPHONE)
X	   *((word *) rec->data) = REC_MODE_TELEPHONE;
X	else if (obj->kind == OBJ_MEMO)
X	   *((word *) rec->data) = REC_MODE_MEMO;
X	else if (obj->kind == OBJ_CARD)
X	   *((word *) rec->data) = REC_MODE_CARD;
X	else if (obj->kind == OBJ_SCHEDULE) {
X	   *((word *) rec->data) = REC_MODE_SCHEDULE;
X	   rec->next = make_date_record(&(obj->sch_date));
X	   rec = rec->next;
X	   if (obj->sch_start_time.hour != INVALID_TIME) {
X	      rec->next = make_time_record(REC_DATA_TIME, &(obj->sch_start_time), &(obj->sch_stop_time));
X	      rec = rec->next;
X	      }
X	   if (obj->sch_alarm_time.hour != INVALID_TIME) {
X	      rec->next = make_time_record(REC_DATA_ALARM, &(obj->sch_alarm_time), NULL);
X	      rec = rec->next;
X	      }
X	   }
X	else if (obj->kind == OBJ_CALENDAR) {
X	   *((word *) rec->data) = REC_MODE_CALENDAR;
X	   rec->next = make_date_record(&(obj->cal_date));
X	   rec = rec->next;
X	   rec->next = create_record();
X	   rec = rec->next;
X	   rec->type = REC_DATA;
X	   rec->address = REC_DATA_BINARY;
X	   rec->length = 4;
X	   long_to_ascii(obj->cal_marked, rec->data);
X	   }
X	else {
X	   error("unknown object (%d) passed to object_to_record", obj->kind);
X	   free_record(head);
X	   return(NULL);
X	   }
X	for (i = 0; i < MAX_FIELDS; i++)
X	   if (p = obj->field[i])
X	      do {
X	         rec->next = create_record();
X	         rec = rec->next;
X	         rec->type = REC_DATA;
X	         if (q = (byte *) index(p, CASIO_END_LINE))
X	            rec->length = q - p + 1;
X	         else
X	            rec->length = strlen(p) + 1;
X	         rec->address = REC_DATA_DATA + p - obj->buf;
X	         bcopy(p, rec->data, rec->length - 1);
X	         if (q) {
X	            rec->data[rec->length - 1] = CASIO_END_LINE;
X	            p = q + 1;
X	            }
X	         else if (obj->field[i + 1]) {
X	            rec->data[rec->length - 1] = CASIO_END_ENTRY;
X	            p += rec->length - 1;
X	            }
X	         else {
X	            rec->length--;
X	            p += rec->length;
X	            }
X	         } while (*p);
X	rec->next = create_record();
X	rec = rec->next;
X	rec->length = 0;
X	rec->type = REC_REGISTER;
X	rec->address = obj->marked? REC_REGISTER_MARKED : REC_REGISTER_NORMAL;
X	return(head);
X}
X
X/************************************************************************/
XEXPORT	int	send_object(obj)
X
Xobject	*obj;
X
X{	record	*rec, *r;
X
X	rec = object_to_record(obj);
X	if (!send_record(rec))
X	   return(FALSE);
X	while (rec) {
X	   r = rec;
X	   rec = rec->next;
X	   free_record(r);
X	   }
X	if (!wait_for_acknowledgement()) {
X	   error("BOSS did not acknowledge receipt of object");
X	   return(FALSE);
X	   }
X	return(TRUE);
X}
X
X/************************************************************************/
XEXPORT	object	*receive_object()
X
X{	record	*rec, *r;
X	object	*obj;
X
X	if (rec = receive_record()) {
X	   acknowledge_object();
X	   obj = record_to_object(rec);
X	   while (rec) {
X	      r = rec;
X	      rec = rec->next;
X	      free_record(r);
X	      }
X	   return(obj);
X	   }
X	else
X	   return(NULL);
X}
END_OF_FILE
if test 10076 -ne `wc -c <'object.c'`; then
    echo shar: \"'object.c'\" unpacked with wrong size!
fi
# end of 'object.c'
fi
if test -f 'print.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'print.c'\"
else
echo shar: Extracting \"'print.c'\" \(8114 characters\)
sed "s/^X//" >'print.c' <<'END_OF_FILE'
X/************************************************************************/
X/*	Copyright 1990 by Chuck Musciano and Harris Corporation		*/
X/*									*/
X/*	Permission to use, copy, modify, and distribute this software	*/
X/*	and its documentation for any purpose and without fee is	*/
X/*	hereby granted, provided that the above copyright notice	*/
X/*	appear in all copies and that both that copyright notice and	*/
X/*	this permission notice appear in supporting documentation, and	*/
X/*	that the name of Chuck Musciano and Harris Corporation not be	*/
X/*	used in advertising or publicity pertaining to distribution	*/
X/*	of the software without specific, written prior permission.	*/
X/*	Chuck Musciano and Harris Corporation make no representations	*/
X/*	about the suitability of this software for any purpose.  It is	*/
X/*	provided "as is" without express or implied warranty.		*/
X/*									*/
X/*	This code contains data and information that is proprietary	*/
X/*	to Casio Corporation.  You may be subject to legal action if	*/
X/*	this information is released without explicit permission from	*/
X/*	Casio.								*/
X/************************************************************************/
X
X/************************************************************************/
X/*									*/
X/*	print.c	handle text output of objects				*/
X/*									*/
X/************************************************************************/
X
X#include	<stdio.h>
X#include	<ctype.h>
X
X#include	"manifest.h"
X#include	"object.h"
X
XPRIVATE	char	*month[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
X
X/************************************************************************/
XPRIVATE	internal_date(f, d)
X
XFILE	*f;
Xdate	*d;
X
X{
X	fprintf(f, "   {date\t%d/%02d/%4d}\n", d->month, d->day, d->year);
X}
X
X/************************************************************************/
XPRIVATE	internal_time(f, name, t)
X
XFILE	*f;
Xchar	*name;
Xtime	*t;
X
X{
X	if (t->hour != INVALID_TIME)
X	   fprintf(f, "   {%s\t%2d:%02d}\n", name, t->hour, t->minute);
X}
X
X/************************************************************************/
XPRIVATE	internal_attribute(f, name, field)
X
XFILE	*f;
Xchar	*name;
Xbyte	*field;
X
X{
X	if (field && *field) {
X	   fprintf(f, "   {%s\t\"", name);
X	   for ( ; *field; field++)
X	      if (*field == '"')
X	         fprintf(f, "\\\"");
X	      else if (*field >= '\177')
X	         fprintf(f, "\\%03o", *field);
X	      else if (iscntrl(*field))
X	         fprintf(f, "^%c", *field + '@');
X	      else
X	         fprintf(f, "%c", *field);
X	   fprintf(f, "\"}\n");
X	   }
X}
X
X/************************************************************************/
XPRIVATE	print_date(f, d)
X
XFILE	*f;
Xdate	*d;
X
X{
X	fprintf(f, "%s %d, %d ", month[d->month - 1], d->day, d->year);
X}
X
X/************************************************************************/
XPRIVATE	print_time(f, leader, t)
X
XFILE	*f;
Xchar	*leader;
Xtime	*t;
X
X{
X	if (t->hour != INVALID_TIME)
X	   fprintf(f, "%s%2d:%02d", leader, t->hour, t->minute);
X}
X
X/************************************************************************/
XPRIVATE	print_string(f, str)
X
XFILE	*f;
Xbyte	*str;
X
X{
X	if (str && *str) {
X	   for ( ; *str; str++)
X	      if (*str == '\r')
X	         fprintf(f, "\n");
X	      else if (*str >= '\177')
X	         fprintf(f, "?");
X	      else if (iscntrl(*str))
X	         fprintf(f, "^%c", *str + '@');
X	      else
X	         fprintf(f, "%c", *str);
X	   fprintf(f, "\n");
X	   }
X}
X
X/************************************************************************/
XPRIVATE	print_pair(f, p, q)
X
XFILE	*f;
Xchar	*p;
Xchar	*q;
X
X{	int	i;
X
X	if (p == NULL)
X	   p = "";
X	if (q == NULL)
X	   q = "";
X	fprintf(f, "%s%*s%s\n", p, 32 - strlen(p) - strlen(q), " ", q);
X}
X
X/************************************************************************/
XEXPORT	print_object_internal(f, obj)
X
XFILE	*f;
Xobject	*obj;
X
X{	int	i;
X
X	fprintf(f, "{");
X	if (obj->kind == OBJ_TELEPHONE) {
X	   fprintf(f, "telephone\n");
X	   internal_attribute(f, "name",    obj->pho_name);
X	   internal_attribute(f, "number",  obj->pho_number);
X	   internal_attribute(f, "address", obj->pho_address);
X	   internal_attribute(f, "extra_1", obj->pho_extra_1);
X	   internal_attribute(f, "extra_2", obj->pho_extra_2);
X	   internal_attribute(f, "extra_3", obj->pho_extra_3);
X	   internal_attribute(f, "extra_4", obj->pho_extra_4);
X	   internal_attribute(f, "extra_5", obj->pho_extra_5);
X	   internal_attribute(f, "extra_6", obj->pho_extra_6);
X	   }
X	else if (obj->kind == OBJ_SCHEDULE) {
X	   fprintf(f, "schedule\n");
X	   internal_date(f, &obj->sch_date);
X	   internal_time(f, "start", &obj->sch_start_time);
X	   internal_time(f, "stop", &obj->sch_stop_time);
X	   internal_time(f, "alarm", &obj->sch_alarm_time);
X	   internal_attribute(f, "memo", obj->sch_memo);
X	   }
X	else if (obj->kind == OBJ_MEMO) {
X	   fprintf(f, "memo\n");
X	   internal_attribute(f, "memo", obj->mem_memo);
X	   }
X	else if (obj->kind == OBJ_CARD) {
X	   fprintf(f, "card\n");
X	   internal_attribute(f, "employer",   obj->car_employer);
X	   internal_attribute(f, "name",       obj->car_name);
X	   internal_attribute(f, "number",     obj->car_number);
X	   internal_attribute(f, "position",   obj->car_position);
X	   internal_attribute(f, "department", obj->car_department);
X	   internal_attribute(f, "pobox",      obj->car_pobox);
X	   internal_attribute(f, "address",    obj->car_address);
X	   internal_attribute(f, "telex",      obj->car_telex);
X	   internal_attribute(f, "fax",        obj->car_fax);
X	   internal_attribute(f, "extra_1",    obj->car_extra_1);
X	   internal_attribute(f, "extra_2",    obj->car_extra_2);
X	   internal_attribute(f, "extra_3",    obj->car_extra_3);
X	   internal_attribute(f, "extra_4",    obj->car_extra_4);
X	   internal_attribute(f, "extra_5",    obj->car_extra_5);
X	   internal_attribute(f, "extra_6",    obj->car_extra_6);
X	   }
X	else if (obj->kind == OBJ_CALENDAR) {
X	   fprintf(f, "calendar\n");
X	   internal_date(f, &obj->cal_date);
X	   if (obj->cal_marked) {
X	      fprintf(f, "   {highlight");
X	      for (i = 1; i <= 31; i++)
X	         if (obj->cal_marked & (1 << (i - 1)))
X	            fprintf(f, " %d", i);
X	      fprintf(f, "}\n");
X	      }
X	   }
X	else
X	   error("unknown object passed to print_object_internal (%d)", obj->kind);
X	if (obj->marked)
X	   fprintf("   {marked}\n");
X	fprintf(f, "}\n");
X}
X
X/************************************************************************/
XEXPORT	print_object_ascii(f, obj)
X
XFILE	*f;
Xobject	*obj;
X
X{	int	i;
X
X	if (obj->kind == OBJ_TELEPHONE) {
X	   print_pair(f, obj->pho_name, obj->pho_number);
X	   print_string(f, obj->pho_address);
X	   print_string(f, obj->pho_extra_1);
X	   print_string(f, obj->pho_extra_2);
X	   print_string(f, obj->pho_extra_3);
X	   print_string(f, obj->pho_extra_4);
X	   print_string(f, obj->pho_extra_5);
X	   print_string(f, obj->pho_extra_6);
X	   }
X	else if (obj->kind == OBJ_SCHEDULE) {
X	   print_date(f, &obj->sch_date);
X	   print_time(f, " ", &obj->sch_start_time);
X	   print_time(f, "-", &obj->sch_stop_time);
X	   print_time(f, " @", &obj->sch_alarm_time);
X	   fprintf(f, "\n");
X	   print_string(f, obj->sch_memo);
X	   }
X	else if (obj->kind == OBJ_MEMO) {
X	   print_string(f, obj->mem_memo);
X	   }
X	else if (obj->kind == OBJ_CARD) {
X	   print_pair(f, obj->car_name, obj->car_number);
X	   print_string(f, obj->car_employer);
X	   print_string(f, obj->car_position);
X	   print_string(f, obj->car_department);
X	   print_string(f, obj->car_pobox);
X	   print_string(f, obj->car_address);
X	   print_string(f, obj->car_telex);
X	   print_string(f, obj->car_fax);
X	   print_string(f, obj->car_extra_1);
X	   print_string(f, obj->car_extra_2);
X	   print_string(f, obj->car_extra_3);
X	   print_string(f, obj->car_extra_4);
X	   print_string(f, obj->car_extra_5);
X	   print_string(f, obj->car_extra_6);
X	   }
X	else if (obj->kind == OBJ_CALENDAR) {
X	   fprintf(f, "%s %d:", month[obj->cal_date.month - 1], obj->cal_date.year);
X	   for (i = 1; i <= 31; i++)
X	      if (obj->cal_marked & (1 << (i - 1)))
X	         fprintf(f, " %d", i);
X	   fprintf(f, "\n");
X	   }
X	else
X	   error("unknown object passed to print_object_ascii (%d)", obj->kind);
X	fprintf(f, "\n");
X}
END_OF_FILE
if test 8114 -ne `wc -c <'print.c'`; then
    echo shar: \"'print.c'\" unpacked with wrong size!
fi
# end of 'print.c'
fi
echo shar: End of archive 4 \(of 6\).
cp /dev/null ark4isdone
MISSING=""
for I in 1 2 3 4 5 6 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 6 archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0

Chuck Musciano				ARPA  : chuck@trantor.harris-atd.com
Harris Corporation 			Usenet: ...!uunet!x102a!trantor!chuck
PO Box 37, MS 3A/1912			AT&T  : (407) 727-6131
Melbourne, FL 32902			FAX   : (407) 729-2537

A good newspaper is never good enough,
	but a lousy newspaper is a joy forever.		-- Garrison Keillor