Path: utzoo!utgpu!news-server.csri.toronto.edu!torsqnt!hybrid!mdapoz From: mdapoz@hybrid.uucp (Mark Dapoz) Newsgroups: comp.sys.handhelds Subject: Casio BOSS <-> UNIX Interface (part 1 of 2) Keywords: unix boss interface program Message-ID: <1990Jul5.052724.23758@hybrid.UUCP> Date: 5 Jul 90 05:27:24 GMT Sender: mdapoz@hybrid.UUCP (Mark Dapoz) Reply-To: mdapoz%hybrid@cs.toronto.edu Organization: The Home for Unemployed Basselopes, Toronto, Ontario, Canada Lines: 1966 There seems to be a growing interest in how to communicate to a Casio BOSS from machines other than DOS based thingies. Here's my solution of how to get a UNIX machine to transfer information to/from a BOSS. It's not quite as complete as I'd like it to be, but it's good enough to get most people started. The program is known to work on Sys V UNIX, it'll probably work on BSD but I don't have immediate access to it to test it. -mark ---- snip ---- snip ---- snip ---- snip ---- snip ---- snip ---- snip ---- # This is a shell archive. Remove anything before this line, # then unpack it by saving it in a file and typing "sh file". # # Wrapped by mdapoz@hybrid on Thu Jul 5 01:11:42 EDT 1990 # Contents: lib/ include/ bin/ MANIFEST Makefile lib/next_field.c # lib/extract_tele.c lib/boss_open.c lib/boss_read.c lib/extract_memo.c # lib/Makefile lib/extract_bus.c lib/extract_sch.c lib/extract_cal.c # lib/boss_close.c lib/boss_write.c lib/add_tele.c lib/add_end_tx.c # lib/packet_chksm.c lib/text_packet.c lib/add_memo.c lib/date_packet.c # lib/add_sched.c lib/time_packet.c lib/alarm_packet.c lib/add_cal.c # lib/add_bcard.c include/boss.h echo x - MANIFEST sed 's/^@//' > "MANIFEST" <<'@//E*O*F MANIFEST//' total 14 drwxr-xr-x 7 mdapoz staff 240 Jul 5 01:08 ./ drwxrwxrwx 9 root root 2656 Jul 5 01:09 ../ -rw-r--r-- 1 mdapoz staff 771 Jul 5 00:37 Makefile drwxr-xr-x 2 mdapoz staff 64 Jul 5 00:54 bin/ drwxr-xr-x 2 mdapoz staff 192 Jul 5 00:54 cfg/ drwxr-xr-x 2 mdapoz staff 96 Jul 5 00:53 doc/ drwxr-xr-x 2 mdapoz staff 48 Jul 5 00:31 include/ drwxr-xr-x 2 mdapoz staff 736 Jul 5 00:54 lib/ @./bin: total 2 drwxr-xr-x 2 mdapoz staff 64 Jul 5 00:54 ./ drwxr-xr-x 7 mdapoz staff 240 Jul 5 01:08 ../ @./cfg: total 88 drwxr-xr-x 2 mdapoz staff 192 Jul 5 00:54 ./ drwxr-xr-x 7 mdapoz staff 240 Jul 5 01:08 ../ -rw-r--r-- 1 mdapoz staff 732 Jun 26 00:59 Makefile -rw-r--r-- 1 mdapoz staff 11120 Jun 26 00:39 boss.c -rw-r--r-- 1 mdapoz staff 23243 Jun 26 00:41 boss_cfg.y -rw-r--r-- 1 mdapoz staff 6899 Jun 26 00:42 boss_lex.l -rw-r--r-- 1 mdapoz staff 859 Jul 5 00:44 y.tab.h @./doc: total 85 drwxr-xr-x 2 mdapoz staff 96 Jul 5 00:53 ./ drwxr-xr-x 7 mdapoz staff 240 Jul 5 01:08 ../ -rw-r--r-- 1 mdapoz staff 19525 Jun 25 20:15 bosslib.doc -rw-r--r-- 1 mdapoz staff 8567 Jul 5 00:29 grammar.spec -rw-r--r-- 1 mdapoz staff 13610 Jun 25 20:15 protocol.spec @./include: total 13 drwxr-xr-x 2 mdapoz staff 48 Jul 5 00:31 ./ drwxr-xr-x 7 mdapoz staff 240 Jul 5 01:08 ../ -rw-r--r-- 1 mdapoz staff 5227 Jun 26 00:43 boss.h @./lib: total 103 drwxr-xr-x 2 mdapoz staff 736 Jul 5 00:54 ./ drwxr-xr-x 7 mdapoz staff 240 Jul 5 01:08 ../ -rw-r--r-- 1 mdapoz staff 1505 Mar 18 18:14 Makefile -rw-r--r-- 1 mdapoz staff 3370 Jun 26 00:44 add_bcard.c -rw-r--r-- 1 mdapoz staff 2349 Jun 26 00:44 add_cal.c -rw-r--r-- 1 mdapoz staff 848 Jun 26 00:44 add_end_tx.c -rw-r--r-- 1 mdapoz staff 1953 Jun 26 00:44 add_memo.c -rw-r--r-- 1 mdapoz staff 2299 Jun 26 00:45 add_sched.c -rw-r--r-- 1 mdapoz staff 2845 Jun 26 00:45 add_tele.c -rw-r--r-- 1 mdapoz staff 798 Jun 26 00:45 alarm_packet.c -rw-r--r-- 1 mdapoz staff 166 Jun 26 00:45 boss_close.c -rw-r--r-- 1 mdapoz staff 1722 Jun 26 00:45 boss_open.c -rw-r--r-- 1 mdapoz staff 5561 Jun 26 00:45 boss_read.c -rw-r--r-- 1 mdapoz staff 3345 Jun 26 00:46 boss_write.c -rw-r--r-- 1 mdapoz staff 794 Jun 26 00:46 date_packet.c -rw-r--r-- 1 mdapoz staff 4175 Jun 26 00:46 extract_bus.c -rw-r--r-- 1 mdapoz staff 2365 Jun 26 00:46 extract_cal.c -rw-r--r-- 1 mdapoz staff 1906 Jun 26 00:46 extract_memo.c -rw-r--r-- 1 mdapoz staff 3458 Jun 26 00:46 extract_sch.c -rw-r--r-- 1 mdapoz staff 3424 Jun 26 00:46 extract_tele.c -rw-r--r-- 1 mdapoz staff 805 Jun 26 00:47 next_field.c -rw-r--r-- 1 mdapoz staff 464 Jun 26 00:47 packet_chksm.c -rw-r--r-- 1 mdapoz staff 1957 Jun 26 00:49 text_packet.c -rw-r--r-- 1 mdapoz staff 794 Jun 26 00:48 time_packet.c @//E*O*F MANIFEST// chmod u=rw,g=r,o=r MANIFEST echo x - Makefile sed 's/^@//' > "Makefile" <<'@//E*O*F Makefile//' # workaround for System V make bug SHELL = /bin/sh BOSSLIB = libboss TOPDIR = . BINDIR = $(TOPDIR)/bin INCDIR = $(TOPDIR)/include LIBDIR = $(TOPDIR)/lib CFGDIR = $(TOPDIR)/cfg DOCDIR = $(TOPDIR)/doc CC = cc COPTS = -O #CC = gcc #COPTS = -g -shlib LIBS = $(LIBDIR)/$(BOSSLIB).a all: $(BINDIR)/boss $(BINDIR)/boss: $(LIBS) /dev/null cd $(CFGDIR); $(MAKE) CC="$(CC)" COPTS="$(COPTS)" $(LIBS): /dev/null cd $(LIBDIR); $(MAKE) CC="$(CC)" COPTS="$(COPTS)" clean: -rm $(CFGDIR)/*.o $(LIBDIR)/*.o > /dev/null 2>&1 spotless: clean -rm $(LIBS) $(BINDIR)/* > /dev/null 2>&1 tar: tar -cvf $(TOPDIR)/boss.tar $(DOCDIR) $(LIBDIR)/*.c \ $(LIBDIR)/Makefile $(TOPDIR)/Makefile $(INCDIR) \ $(CFGDIR)/boss_cfg.y $(CFGDIR)/boss_lex.l $(CFGDIR)/boss.c \ $(CFGDIR)/Makefile @//E*O*F Makefile// chmod u=rw,g=r,o=r Makefile echo mkdir - lib mkdir lib chmod u=rwx,g=rx,o=rx lib echo x - lib/next_field.c sed 's/^@//' > "lib/next_field.c" <<'@//E*O*F lib/next_field.c//' /* next_field() - scan "string" for tokens separated by "delim" similar to strtok() except null tokens are returned Mark Dapoz */ #include char *next_field(string, delim) char *string; char delim; { static char *position; /* position of last scan */ static int done; /* end of string detected? */ char *start, *anchor; if (string == NULL) { /* NULL indicates same string as last call */ if (done) return(NULL); /* end of string reached */ start=anchor=position; } else { done=0; /* first invocation */ start=anchor=string; } while (*start != delim && *start) /* look for delimiter or end of string */ start++; if (!*start) /* end of string? */ done=1; *start='\0'; /* tokenize */ position=start+1; return(anchor); } @//E*O*F lib/next_field.c// chmod u=rw,g=r,o=r lib/next_field.c echo x - lib/extract_tele.c sed 's/^@//' > "lib/extract_tele.c" <<'@//E*O*F lib/extract_tele.c//' /* extract_tele() - extract telephone entries from a stream of linked list packets Mark Dapoz */ #include #include #include "boss.h" struct telephone *extract_tele(packet_ptr) struct boss_packet *packet_ptr; { int tele_record=0; /* marker to indicate current record is for tele */ char rec_data[384]; /* buffer to hold one record of data */ char *tok_ptr; /* used in breaking up record into fields */ int tok_len; char *mem_ptr; int i; struct telephone *work_tele_ptr; struct telephone *base_tele_ptr; extern char *next_field(); base_tele_ptr=NULL; *rec_data='\0'; do { switch(packet_ptr->header.control) { case SEL_DEST: /* packet for selecting destination */ tele_record=packet_ptr->data[0] == DEST_TEL ? 1 : 0; break; case REC_END: /* end of record packet */ if (tele_record) { /* ignore if telephone not destination */ if (base_tele_ptr == NULL) { /* first record? */ base_tele_ptr=work_tele_ptr=(struct telephone *) malloc(sizeof(struct telephone)); } else { /* add to linked list of records */ work_tele_ptr->next=(struct telephone *) malloc(sizeof(struct telephone)); work_tele_ptr=work_tele_ptr->next; } work_tele_ptr->next=NULL; /* init data in struct */ work_tele_ptr->name= work_tele_ptr->tel_number= work_tele_ptr->addr= work_tele_ptr->free_1= work_tele_ptr->free_2= work_tele_ptr->free_3= work_tele_ptr->free_4= work_tele_ptr->free_5= work_tele_ptr->free_6=NULL; work_tele_ptr->marked = /* marked record? */ packet_ptr->header.target ? 1 : 0; tok_ptr=next_field(rec_data, '\n'); /* split into fields */ for (i=0; tok_ptr!=NULL; tok_ptr=next_field(NULL,'\n'),i++){ if (tok_len=strlen(tok_ptr)) /* allocate room for data*/ mem_ptr=(char *)malloc(tok_len+1); else continue; switch(i) { /* put in appropriate spot in struct */ case 0: work_tele_ptr->name=mem_ptr; strcpy(work_tele_ptr->name, tok_ptr); break; case 1: work_tele_ptr->tel_number=mem_ptr; strcpy(work_tele_ptr->tel_number, tok_ptr); break; case 2: work_tele_ptr->addr=mem_ptr; strcpy(work_tele_ptr->addr, tok_ptr); break; case 3: work_tele_ptr->free_1=mem_ptr; strcpy(work_tele_ptr->free_1, tok_ptr); break; case 4: work_tele_ptr->free_2=mem_ptr; strcpy(work_tele_ptr->free_2, tok_ptr); break; case 5: work_tele_ptr->free_3=mem_ptr; strcpy(work_tele_ptr->free_3, tok_ptr); break; case 6: work_tele_ptr->free_4=mem_ptr; strcpy(work_tele_ptr->free_4, tok_ptr); break; case 7: work_tele_ptr->free_5=mem_ptr; strcpy(work_tele_ptr->free_5, tok_ptr); break; case 8: work_tele_ptr->free_6=mem_ptr; strcpy(work_tele_ptr->free_6, tok_ptr); break; } } } *rec_data='\0'; /* clear data */ break; case TX_END: /* end of transmission packet */ break; case 0: /* not control packet => data packet */ if ((packet_ptr->header.target & 0xf0) != TARG_TEXT || !tele_record) /* make sure it's a text packet */ break; strcat(rec_data, packet_ptr->data); /* build record data */ } packet_ptr=packet_ptr->next; /* follow chain */ } while (packet_ptr->next != NULL); return(base_tele_ptr); } @//E*O*F lib/extract_tele.c// chmod u=rw,g=r,o=r lib/extract_tele.c echo x - lib/boss_open.c sed 's/^@//' > "lib/boss_open.c" <<'@//E*O*F lib/boss_open.c//' /* boss_open() - open the device the BOSS is connected to and set the communications parameters Mark Dapoz */ #include #include #include #define SYSERR -1 /* system error return value */ boss_open(device) char *device; { struct termio term; /* tty info structure */ int boss_fd; /* device file descriptor */ int i; /* open with O_NDELAY first to avoid blocking on the device */ if((i=open(device, O_RDONLY | O_NDELAY)) != SYSERR) { ioctl(i, TCGETA, &term); term.c_cflag |= CLOCAL | CREAD; /* local connection for reading */ term.c_cflag &= ~(CBAUD); /* clear the line */ ioctl(i, TCSETA, &term); ioctl(i, TCXONC, 1); /* start line in case of flow control */ /* here is the real open, which is blocking */ if ((boss_fd = open(device, O_RDWR)) != SYSERR) { close(i); /* fcntl(i, F_SETFD, 0x01); */ } else { perror("Unable to open device"); return(-1); } } else { perror("Unable to open device"); return(-1); } /* * set up terminal parameters: 9600 baud, 8 data bits, 1 stop bit */ if(ioctl(boss_fd, TCGETA, &term) == SYSERR) { perror("Unable to get tty parameters"); return(-1); } term.c_lflag = ISIG; /* enable signals */ term.c_iflag = BRKINT; /* make break cause interrupt */ term.c_oflag &= ~OPOST; /* raw character output */ term.c_cflag = CREAD | CLOCAL | HUPCL | CS8; /* enable receiver */ term.c_cc[VMIN] = 1; term.c_cc[VTIME] = 0; term.c_cflag &= ~CBAUD ; term.c_cflag |= B9600; /* set baud rate */ if (ioctl(boss_fd, TCSETAW, &term) == SYSERR) { perror("Unable to set tty parameters"); return(-1); } return(boss_fd); } @//E*O*F lib/boss_open.c// chmod u=rw,g=r,o=r lib/boss_open.c echo x - lib/boss_read.c sed 's/^@//' > "lib/boss_read.c" <<'@//E*O*F lib/boss_read.c//' /* boss_read() - accept packets from device specified by file descriptor "boss_fd" and put them on a link list of packets Mark Dapoz */ #include #include #include "boss.h" #define DEBUG_STREAM /* debug incomming byte stream */ #undef DEBUG_STREAM #define DEBUG_STATES /* debug state machine */ #undef DEBUG_STATES #ifdef DEBUG_STATES #define dprints(x) printf(x) #else #define dprints(x) #endif struct boss_packet *boss_read(boss_fd) int boss_fd; { char cur_byte, prev_byte=0; /* Data from BOSS */ char start_ack = CRLF_ACK; /* Value of ack for initial handshake */ char record_ack = PROTO_ACK;/* Value of ack for record handshakes */ char record_nack = PROTO_ABORT;/* Value for aborting transfer */ int state=CONNECT; /* Current state withn packet */ int connected=0; /* Already in connect state? */ int nibble=0; /* Portion of byte being received */ int first_crlf=0; /* Dump first occurrence of cr lf */ int hdr_count; /* Amount of packet header received */ int data_count; /* Amount of packet data received */ int rec_count=0; /* Number of records read so far */ int read_rc; /* read(2) return value */ int timeout; /* time to wait for next char */ byte verify_checksum; /* Checksum of packet (provided) */ byte packet_checksum; /* Checksum of packet (calculated) */ struct boss_packet *next_packet; struct boss_packet *packet_ptr; struct boss_packet *base_packet; int read_timeout(); /* interrupt handler */ packet_ptr=(struct boss_packet *)malloc(sizeof(struct boss_packet)); packet_ptr->next=NULL; base_packet=packet_ptr; signal(SIGALRM, read_timeout); timeout=START_TIMEOUT; alarm(timeout); /* limit wait for transfer to start */ while((read_rc=read(boss_fd, &cur_byte, 1)) == 1) { alarm(0); /* turn off any pending alarm */ #ifdef DEBUG_STREAM printf("%02xh\n", cur_byte); #endif switch(state) { case CONNECT: if ((cur_byte == LF) && (prev_byte == CR)) { if (!first_crlf) { first_crlf++; break; } timeout=CHAR_TIMEOUT; /* got initial chars */ write(boss_fd, &start_ack, 1); /* handshake with BOSS */ dprints("Switching to COLON state\n"); state=COLON; } break; case COLON: if (cur_byte != ':') { if (connected) { if (cur_byte != PROTO_ABORT) { /* aborted? */ fprintf(stderr, "Ugh, expecting ':'\n"); fprintf(stderr, "Got '%02xh' instead\n", cur_byte); } return(NULL); } else { dprints("Switching to CONNECT state\n"); state=CONNECT; } } else { connected=1; /* indicate handshake completed */ dprints("Switching to SIZE state\n"); state=SIZE; } break; case SIZE: if (!nibble) nibble++; else { packet_checksum=packet_ptr->size= h2d(prev_byte)*16 + h2d(cur_byte); dprints("Switching to HEADER state\n"); hdr_count=0; /* init header count */ state=HEADER; nibble=0; /* reset nibble counter */ } break; case HEADER: if (!nibble) nibble++; else { switch(hdr_count) { case 0: packet_checksum+=(packet_ptr->header.target= h2d(prev_byte)*16 + h2d(cur_byte)); break; case 1: packet_checksum+=(packet_ptr->header.position= h2d(prev_byte)*16 + h2d(cur_byte)); break; case 2: packet_checksum+=(packet_ptr->header.control= h2d(prev_byte)*16 + h2d(cur_byte)); break; } if (++hdr_count == 3) { dprints("Switching to DATA state\n"); if (packet_ptr->size) state=DATA; /* read data only if size > 0 */ else state=CHECKSUM; data_count=0; } nibble=0; } break; case DATA: if (!nibble) nibble++; else { packet_checksum += (packet_ptr->data[data_count]= h2d(prev_byte)*16 + h2d(cur_byte)); if (++data_count == packet_ptr->size) { packet_ptr->data[packet_ptr->size]='\0'; /* for strcpy*/ dprints("Switching to CHECKSUM state\n"); state=CHECKSUM; } nibble=0; } break; case CHECKSUM: if (!nibble) nibble++; else { packet_ptr->checksum=verify_checksum= h2d(prev_byte)*16 + h2d(cur_byte); if ((((packet_checksum^0xff)+1)&0xff) != verify_checksum) { fprintf(stderr, "Checksum error: %02xh != %02xh\n", verify_checksum, (((packet_checksum^0xff)+1)&0xff)); write(boss_fd, &record_nack, 1); /* abort */ return(NULL); } /* Check if handshake is required */ if (packet_ptr->size == 0 && packet_ptr->header.control == REC_END) { write(boss_fd, &record_ack, 1); /* handshake */ fprintf(stderr, "Record=%d\r", rec_count++); } /* Check if last packet */ if (packet_ptr->size == 0 && packet_ptr->header.control == TX_END) { return(base_packet); /* end of transmission */ } next_packet = (struct boss_packet *) malloc(sizeof(struct boss_packet)); next_packet->next = NULL; packet_ptr->next = next_packet; packet_ptr=next_packet; nibble=0; dprints("Switching to COLON state\n"); state=COLON; } break; default: fprintf(stderr, "panic: invalid state: %02xh\n", state); return(NULL); } prev_byte=cur_byte; alarm(timeout); /* limit wait for next char */ } if (read_rc < 0) return(NULL); else return(base_packet); } read_timeout() /* read timeout interrupt handler */ { fprintf(stderr, "Timeout reading\n"); return(-1); } @//E*O*F lib/boss_read.c// chmod u=rw,g=r,o=r lib/boss_read.c echo x - lib/extract_memo.c sed 's/^@//' > "lib/extract_memo.c" <<'@//E*O*F lib/extract_memo.c//' /* extract_memo() - extract memo entries from a stream of linked list packets Mark Dapoz */ #include #include #include "boss.h" struct memo *extract_memo(packet_ptr) struct boss_packet *packet_ptr; { int memo_record=0; /* marker to indicate current record is for memo */ char rec_data[384]; /* buffer to hold one record of data */ char *mem_ptr; struct memo *work_memo_ptr; struct memo *base_memo_ptr; base_memo_ptr=NULL; *rec_data='\0'; do { switch(packet_ptr->header.control) { case SEL_DEST: /* packet for selecting destination */ memo_record=packet_ptr->data[0] == DEST_MEMO ? 1 : 0; break; case REC_END: /* end of record packet */ if (memo_record) { /* ignore if memo not destination */ if (base_memo_ptr == NULL) { /* first record? */ base_memo_ptr=work_memo_ptr=(struct memo *) malloc(sizeof(struct memo)); } else { /* add to linked list of records */ work_memo_ptr->next=(struct memo *) malloc(sizeof(struct memo)); work_memo_ptr=work_memo_ptr->next; } work_memo_ptr->next=NULL; /* init data in struct */ work_memo_ptr->text=NULL; work_memo_ptr->marked = /* marked record? */ packet_ptr->header.target ? 1 : 0; if (strlen(rec_data)) { /* allocate room for data*/ work_memo_ptr->text=(char *)malloc(strlen(rec_data)+1); strcpy(work_memo_ptr->text, rec_data); } } *rec_data='\0'; /* clear data */ break; case TX_END: /* end of transmission packet */ break; case 0: /* not control packet => data packet */ if ((packet_ptr->header.target & 0xf0) != TARG_TEXT || !memo_record) /* make sure it's a text packet */ break; strcat(rec_data, packet_ptr->data); /* build record data */ } packet_ptr=packet_ptr->next; /* follow chain */ } while (packet_ptr->next != NULL); return(base_memo_ptr); } @//E*O*F lib/extract_memo.c// chmod u=rw,g=r,o=r lib/extract_memo.c echo x - lib/Makefile sed 's/^@//' > "lib/Makefile" <<'@//E*O*F lib/Makefile//' # libboss makefile # workaround for System V make bug SHELL = /bin/sh TOPDIR = .. BINDIR = $(TOPDIR)/bin LIBDIR = $(TOPDIR)/lib INCDIR = $(TOPDIR)/include CFGDIR = $(TOPDIR)/cfg CFLAGS = $(COPTS) -I$(INCDIR) LINTFLAGS=-hau -I$(INCDIR) LIB = $(LIBDIR)/libboss.a # RANLIB is ranlib on non-USG systems, echo on USG systems #RANLIB =ranlib RANLIB =: SRCS = boss_open.c boss_close.c boss_read.c extract_tele.c extract_memo.c \ extract_bus.c extract_sch.c extract_cal.c next_field.c \ boss_write.c add_tele.c packet_chksm.c add_end_tx.c text_packet.c \ add_memo.c add_bcard.c add_sched.c date_packet.c time_packet.c \ alarm_packet.c add_cal.c all: $(LIB) $(LIB): $(SRCS) $(CC) $(CFLAGS) -c $? ar rv $@ *.o $(RANLIB) $@ lint: lint $(LINTFLAGS) $(SRCS) clean: rm -f *.o # header dependencies for libboss.a members add_bcard.o: $(INCDIR)/boss.h add_cal.o: $(INCDIR)/boss.h add_end_tx.o: $(INCDIR)/boss.h add_memo.o: $(INCDIR)/boss.h add_sched.o: $(INCDIR)/boss.h add_tele.o: $(INCDIR)/boss.h alarm_packet.o: $(INCDIR)/boss.h boss_close.o: $(INCDIR)/boss.h boss_open.o: $(INCDIR)/boss.h boss_read.o: $(INCDIR)/boss.h boss_write.o: $(INCDIR)/boss.h date_packet.o: $(INCDIR)/boss.h extract_bus.o: $(INCDIR)/boss.h extract_cal.o: $(INCDIR)/boss.h extract_memo.o: $(INCDIR)/boss.h extract_sch.o: $(INCDIR)/boss.h extract_tele.o: $(INCDIR)/boss.h next_field.o: $(INCDIR)/boss.h packet_chksm.o: $(INCDIR)/boss.h text_packet.o: $(INCDIR)/boss.h time_packet.o: $(INCDIR)/boss.h @//E*O*F lib/Makefile// chmod u=rw,g=r,o=r lib/Makefile echo x - lib/extract_bus.c sed 's/^@//' > "lib/extract_bus.c" <<'@//E*O*F lib/extract_bus.c//' /* extract_bcard() - extract business card entries from a stream of linked list of packets Mark Dapoz */ #include #include #include "boss.h" struct bus_card *extract_bcard(packet_ptr) struct boss_packet *packet_ptr; { int bcard_record=0;/* marker to indicate current record is for bus card */ char rec_data[384]; /* buffer to hold one record of data */ char *tok_ptr; /* used in breaking up record into fields */ int tok_len; char *mem_ptr; int i; struct bus_card *work_bcard_ptr; struct bus_card *base_bcard_ptr; extern char *next_field(); base_bcard_ptr=NULL; *rec_data='\0'; do { switch(packet_ptr->header.control) { case SEL_DEST: /* packet for selecting destination */ bcard_record=packet_ptr->data[0] == DEST_BUS ? 1 : 0; break; case REC_END: /* end of record packet */ if (bcard_record) { /* ignore if bus card not destination */ if (base_bcard_ptr == NULL) { /* first record? */ base_bcard_ptr=work_bcard_ptr=(struct bus_card *) malloc(sizeof(struct bus_card)); } else { /* add to linked list of records */ work_bcard_ptr->next=(struct bus_card *) malloc(sizeof(struct bus_card)); work_bcard_ptr=work_bcard_ptr->next; } work_bcard_ptr->next=NULL; /* init data in struct */ work_bcard_ptr->employer= work_bcard_ptr->name= work_bcard_ptr->tel_number= work_bcard_ptr->position= work_bcard_ptr->dept= work_bcard_ptr->po_box= work_bcard_ptr->addr= work_bcard_ptr->telex= work_bcard_ptr->fax_number= work_bcard_ptr->free_1= work_bcard_ptr->free_2= work_bcard_ptr->free_3= work_bcard_ptr->free_4= work_bcard_ptr->free_5=NULL; work_bcard_ptr->marked = /* marked record? */ packet_ptr->header.target ? 1 : 0; tok_ptr=next_field(rec_data, '\n'); /* split into fields */ for (i=0; tok_ptr!=NULL; tok_ptr=next_field(NULL,'\n'),i++){ if (tok_len=strlen(tok_ptr)) /* allocate room for data*/ mem_ptr=(char *)malloc(tok_len+1); else continue; switch(i) { /* put in appropriate spot in struct */ case 0: work_bcard_ptr->employer=mem_ptr; strcpy(work_bcard_ptr->employer, tok_ptr); break; case 1: work_bcard_ptr->name=mem_ptr; strcpy(work_bcard_ptr->name, tok_ptr); break; case 2: work_bcard_ptr->tel_number=mem_ptr; strcpy(work_bcard_ptr->tel_number, tok_ptr); break; case 3: work_bcard_ptr->position=mem_ptr; strcpy(work_bcard_ptr->position, tok_ptr); break; case 4: work_bcard_ptr->dept=mem_ptr; strcpy(work_bcard_ptr->dept, tok_ptr); break; case 5: work_bcard_ptr->po_box=mem_ptr; strcpy(work_bcard_ptr->po_box, tok_ptr); break; case 6: work_bcard_ptr->addr=mem_ptr; strcpy(work_bcard_ptr->addr, tok_ptr); break; case 7: work_bcard_ptr->telex=mem_ptr; strcpy(work_bcard_ptr->telex, tok_ptr); break; case 8: work_bcard_ptr->fax_number=mem_ptr; strcpy(work_bcard_ptr->fax_number, tok_ptr); break; case 9: work_bcard_ptr->free_1=mem_ptr; strcpy(work_bcard_ptr->free_1, tok_ptr); break; case 10: work_bcard_ptr->free_2=mem_ptr; strcpy(work_bcard_ptr->free_2, tok_ptr); break; case 11: work_bcard_ptr->free_3=mem_ptr; strcpy(work_bcard_ptr->free_3, tok_ptr); break; case 12: work_bcard_ptr->free_4=mem_ptr; strcpy(work_bcard_ptr->free_4, tok_ptr); break; case 13: work_bcard_ptr->free_5=mem_ptr; strcpy(work_bcard_ptr->free_5, tok_ptr); break; } } } *rec_data='\0'; /* clear data */ break; case TX_END: /* end of transmission packet */ break; case 0: /* not control packet => data packet */ if ((packet_ptr->header.target & 0xf0) != TARG_TEXT || !bcard_record) /* make sure it's a text packet */ break; strcat(rec_data, packet_ptr->data); /* build record data */ } packet_ptr=packet_ptr->next; /* follow chain */ } while (packet_ptr->next != NULL); return(base_bcard_ptr); } @//E*O*F lib/extract_bus.c// chmod u=rw,g=r,o=r lib/extract_bus.c echo x - lib/extract_sch.c sed 's/^@//' > "lib/extract_sch.c" <<'@//E*O*F lib/extract_sch.c//' /* extract_sched() - extract schedule entries from a stream of linked list packets Mark Dapoz */ #include #include #include "boss.h" struct schedule *extract_sched(packet_ptr) struct boss_packet *packet_ptr; { int sched_record=0;/* marker to indicate current record is for schedule */ char rec_data[384]; /* buffer to hold one record of data */ char sched_date[22];/* buffer for date of schedule */ char sched_time[12];/* buffer for time of schedule */ char sched_alarm[6];/* buffer for alarm time of schedule */ struct schedule *work_sched_ptr; struct schedule *base_sched_ptr; base_sched_ptr=NULL; *rec_data='\0'; do { switch(packet_ptr->header.control) { case SEL_DEST: /* packet for selecting destination */ sched_record=packet_ptr->data[0] == DEST_SCHED ? 1 : 0; break; case REC_END: /* end of record packet */ if (sched_record) { /* ignore if schedule not destination */ if (base_sched_ptr == NULL) { /* first record? */ base_sched_ptr=work_sched_ptr=(struct schedule *) malloc(sizeof(struct schedule)); } else { /* add to linked list of records */ work_sched_ptr->next=(struct schedule *) malloc(sizeof(struct schedule)); work_sched_ptr=work_sched_ptr->next; } work_sched_ptr->next=NULL; /* init data in struct */ work_sched_ptr->date= work_sched_ptr->time= work_sched_ptr->alarm= work_sched_ptr->text=NULL; work_sched_ptr->marked = /* marked record? */ packet_ptr->header.target ? 1 : 0; if (strlen(sched_date)) { /* allocate room for date */ work_sched_ptr->date=(char *) malloc(strlen(sched_date)+1); strcpy(work_sched_ptr->date, sched_date); } if (strlen(sched_time)) { /* allocate room for time */ work_sched_ptr->time=(char *) malloc(strlen(sched_time)+1); strcpy(work_sched_ptr->time, sched_time); } if (strlen(sched_alarm)) { /* allocate room for alarm */ work_sched_ptr->alarm=(char *) malloc(strlen(sched_alarm)+1); strcpy(work_sched_ptr->alarm, sched_alarm); } if (strlen(sched_alarm)) { /* allocate room for alarm */ work_sched_ptr->alarm=(char *) malloc(strlen(sched_alarm)+1); strcpy(work_sched_ptr->alarm, sched_alarm); } if (strlen(rec_data)) { /* allocate room for description */ work_sched_ptr->text=(char *) malloc(strlen(rec_data)+1); strcpy(work_sched_ptr->text, rec_data); } } *rec_data='\0'; /* clear data */ *sched_date='\0'; *sched_time='\0'; *sched_alarm='\0'; break; case TX_END: /* end of transmission packet */ break; case 0: /* not control packet => data packet */ if ((packet_ptr->header.target & 0xf0) == TARG_TEXT && sched_record) /* make sure it's a text packet */ strcat(rec_data, packet_ptr->data);/*build record data*/ /* time setting packet? */ if (packet_ptr->header.target == TARG_TIME && sched_record) strcpy(sched_time, packet_ptr->data); /* date setting packet? */ if (packet_ptr->header.target == TARG_DATE && sched_record) strcpy(sched_date, packet_ptr->data); /* alarm setting packet? */ if (packet_ptr->header.target == TARG_ALARM && sched_record) strcpy(sched_alarm, packet_ptr->data); break; } packet_ptr=packet_ptr->next; /* follow chain */ } while (packet_ptr->next != NULL); return(base_sched_ptr); } @//E*O*F lib/extract_sch.c// chmod u=rw,g=r,o=r lib/extract_sch.c echo x - lib/extract_cal.c sed 's/^@//' > "lib/extract_cal.c" <<'@//E*O*F lib/extract_cal.c//' /* extract_cal() - extract marked calendar entries from a stream of linked list packets Mark Dapoz */ #include #include #include "boss.h" struct calendar *extract_cal(packet_ptr) struct boss_packet *packet_ptr; { int cal_record=0;/* marker to indicate current record is for calendar */ char cal_date[11]; /* buffer for date of calendar */ int marked_days[4];/* buffer for bitfield of marked days */ struct calendar *work_cal_ptr; struct calendar *base_cal_ptr; base_cal_ptr=NULL; do { switch(packet_ptr->header.control) { case SEL_DEST: /* packet for selecting destination */ cal_record=packet_ptr->data[0] == DEST_CAL ? 1 : 0; break; case REC_END: /* end of record packet */ if (cal_record) { /* ignore if calendar not destination */ if (base_cal_ptr == NULL) { /* first record? */ base_cal_ptr=work_cal_ptr=(struct calendar *) malloc(sizeof(struct calendar)); } else { /* add to linked list of records */ work_cal_ptr->next=(struct calendar *) malloc(sizeof(struct calendar)); work_cal_ptr=work_cal_ptr->next; } work_cal_ptr->next=NULL; /* init data in struct */ work_cal_ptr->month=NULL; if (strlen(cal_date)) { /* allocate room for date */ work_cal_ptr->month=(char *) malloc(strlen(cal_date)+1); strcpy(work_cal_ptr->month, cal_date); } work_cal_ptr->days[0]=marked_days[0]; /* copy bitfields */ work_cal_ptr->days[1]=marked_days[1]; work_cal_ptr->days[2]=marked_days[2]; work_cal_ptr->days[3]=marked_days[3]; } *cal_date='\0'; /* clear data */ marked_days[0]=marked_days[1]=marked_days[2]=marked_days[3]=0; break; case TX_END: /* end of transmission packet */ break; case 0: /* not control packet => data packet */ /* date setting packet? */ if (packet_ptr->header.target == TARG_DATE && cal_record) strcpy(cal_date, packet_ptr->data); /* marked days packet? */ if (packet_ptr->header.target == TARG_MARK && cal_record) { marked_days[0]=packet_ptr->data[0]; marked_days[1]=packet_ptr->data[1]; marked_days[2]=packet_ptr->data[2]; marked_days[3]=packet_ptr->data[3]; } break; } packet_ptr=packet_ptr->next; /* follow chain */ } while (packet_ptr->next != NULL); return(base_cal_ptr); } @//E*O*F lib/extract_cal.c// chmod u=rw,g=r,o=r lib/extract_cal.c echo x - lib/boss_close.c sed 's/^@//' > "lib/boss_close.c" <<'@//E*O*F lib/boss_close.c//' /* boss_close() - close the device the BOSS is connected to Mark Dapoz */ #include boss_close(boss_fd) int boss_fd; { return(close(boss_fd)); } @//E*O*F lib/boss_close.c// chmod u=rw,g=r,o=r lib/boss_close.c echo x - lib/boss_write.c sed 's/^@//' > "lib/boss_write.c" <<'@//E*O*F lib/boss_write.c//' /* boss_write() - write packets from the linked list "boss_packets" to device specified by file descriptor "boss_fd" Mark Dapoz */ #include #include #include "boss.h" #define DEBUG_STREAM /* debug incomming byte stream */ #undef DEBUG_STREAM int boss_write(boss_fd, boss_packets) int boss_fd; struct boss_packet *boss_packets; { int write_timeout(); /* interrupt handler */ char boss_ack; /* type of ack returned by BOSS */ char ascii_buffer[(1+3+256+1)*2]; /* ascii buffer for packet tx */ int buffer_pos; /*location of next char in ascii_buffer */ int i; signal(SIGALRM, write_timeout); alarm(0); #ifdef DEBUG_STREAM printf("writting to BOSS\n"); #endif for (i=0; i < 15; i++) { sprintf(ascii_buffer, "%c%c", CR, LF); /* initial handshake */ write(boss_fd, ascii_buffer, 2); boss_ack=0; signal(SIGALRM, write_timeout); /* just in case no comm */ alarm(2); read(boss_fd, &boss_ack, 1); /* see what its got to say */ alarm(0); /* turn off any pending alarms */ if (boss_ack == CRLF_ACK) { boss_ack=0; signal(SIGALRM, write_timeout); /* flush line */ alarm(1); while(read(boss_fd, &boss_ack, 1) > 0) { /* read what we can */ signal(SIGALRM, write_timeout); alarm(1); } alarm(0); /* turn off any pending alarms */ break; } } if (i == 10) /* successful? */ return(1); while(boss_packets != NULL) { /* run through the list */ buffer_pos=sprintf(ascii_buffer, ":%02X%02X%02X%02X", boss_packets->size, boss_packets->header.target, boss_packets->header.position, boss_packets->header.control); for (i=0; i < boss_packets->size; i++) buffer_pos+=sprintf(ascii_buffer+buffer_pos, "%02X", boss_packets->data[i]); sprintf(ascii_buffer+buffer_pos, "%02X", boss_packets->checksum); #ifdef DEBUG_STREAM printf("%s\n", ascii_buffer); #endif /* dump it one at a time, BOSS can't keep up with write() */ for (i=0; i < strlen(ascii_buffer); i++) write(boss_fd, ascii_buffer+i, 1); /* wait for acks */ if (boss_packets->header.control == REC_END || boss_packets->header.control == SEL_DEST) { /* get response */ #ifdef DEBUG_STREAM if (boss_packets->header.control == REC_END) printf("--- End of Record ---\n\n"); else printf("--- Dest Select Record ---\n\n"); #endif boss_ack=0; signal(SIGALRM, write_timeout); alarm(30); /* just in case no more comm */ read(boss_fd, &boss_ack, 1); alarm(0); /* turn off any pending alarm */ switch (boss_ack) { /* check response from BOSS */ case 0: fprintf(stderr, "No ack received from BOSS\n"); write(boss_fd, "!", 1); /* send abort signal */ return(1); case PROTO_ABORT: fprintf(stderr, "Transfer aborted by BOSS\n"); return(1); case PROTO_LOST: fprintf(stderr, "Sync error\n"); write(boss_fd, "!", 1); /* send abort signal */ return(1); case PROTO_ACK: /* fprintf(stderr, "Record successfully sent\n"); */ break; default: fprintf(stderr, "Transmit error, got %c(%02xh)\n", boss_ack, boss_ack); } } boss_packets=boss_packets->next; /* move to next packet */ } return(0); } write_timeout() /* write timeout interrupt handler */ { #ifdef DEBUG_TIME fprintf(stdout, "Timeout reading\n"); #endif return(1); } @//E*O*F lib/boss_write.c// chmod u=rw,g=r,o=r lib/boss_write.c echo x - lib/add_tele.c sed 's/^@//' > "lib/add_tele.c" <<'@//E*O*F lib/add_tele.c//' /* add_tele() - add telephone entries to a stream of linked list packets Mark Dapoz */ #include #include #include "boss.h" struct boss_packet *last; /* pointer to tail of BOSS packets */ int text_pos; /* current position of text record */ struct boss_packet *add_tele(tele_entry, packet_ptr) struct telephone *tele_entry; struct boss_packet *packet_ptr; { struct boss_packet *head; /* first packet on BOSS packet stream */ struct boss_packet *build_packet; build_packet=(struct boss_packet *)malloc(sizeof(struct boss_packet)); if ((head=last=packet_ptr) != NULL) { for (; last->next !=NULL; last=last->next); /* locate end */ last->next=build_packet; } else head=last=build_packet; /* init list */ /* build select destination packet */ build_packet->size=2; build_packet->header.target=0; build_packet->header.position=0; build_packet->header.control=SEL_DEST; build_packet->data[0]=DEST_TEL; /* we want a telephone entry */ build_packet->data[1]=0; build_packet->next=NULL; packet_checksum(build_packet); last=build_packet; /* adv pointer */ /* run through list of telephone entries to add only adding those entries with real data */ while (tele_entry != NULL) { text_pos=0; /* start at beginning */ if (tele_entry->name != NULL) if (strlen(tele_entry->name)) add_text_packet(tele_entry->name); if (tele_entry->tel_number != NULL) if (strlen(tele_entry->tel_number)) add_text_packet(tele_entry->tel_number); if (tele_entry->addr != NULL) if (strlen(tele_entry->addr)) add_text_packet(tele_entry->addr); if (tele_entry->free_1 != NULL) if (strlen(tele_entry->free_1)) add_text_packet(tele_entry->free_1); if (tele_entry->free_2 != NULL) if (strlen(tele_entry->free_2)) add_text_packet(tele_entry->free_2); if (tele_entry->free_3 != NULL) if (strlen(tele_entry->free_3)) add_text_packet(tele_entry->free_3); if (tele_entry->free_4 != NULL) if (strlen(tele_entry->free_4)) add_text_packet(tele_entry->free_4); if (tele_entry->free_5 != NULL) if (strlen(tele_entry->free_5)) add_text_packet(tele_entry->free_5); if (tele_entry->free_6 != NULL) if (strlen(tele_entry->free_6)) add_text_packet(tele_entry->free_6); /* build end of record packet */ build_packet=(struct boss_packet *)malloc(sizeof(struct boss_packet)); build_packet->size=0; if (tele_entry->marked) /* marked record? */ build_packet->header.target=0x80; else build_packet->header.target=0; build_packet->header.position=0; build_packet->header.control=REC_END; /* end of record */ packet_checksum(build_packet); last->next=build_packet; /* add to linked list of packets */ last=build_packet; last->next=NULL; tele_entry=tele_entry->next; /* next record */ } return(head); } @//E*O*F lib/add_tele.c// chmod u=rw,g=r,o=r lib/add_tele.c echo x - lib/add_end_tx.c sed 's/^@//' > "lib/add_end_tx.c" <<'@//E*O*F lib/add_end_tx.c//' /* add_end_tx() - add end of transmission record to a stream of linked list packets Mark Dapoz */ #include #include #include "boss.h" struct boss_packet *add_end_tx(packet_ptr) struct boss_packet *packet_ptr; { struct boss_packet *head, *last; struct boss_packet *build_packet; build_packet=(struct boss_packet *)malloc(sizeof(struct boss_packet)); if ((head=last=packet_ptr) != NULL) { for (; last->next !=NULL; last=last->next); last->next=build_packet; } else head=last=build_packet; /* build end of transmission packet */ build_packet->size=0; build_packet->header.target=0; build_packet->header.position=0; build_packet->header.control=TX_END; build_packet->next=NULL; packet_checksum(build_packet); /* add to linked list of packets */ return(head); } @//E*O*F lib/add_end_tx.c// chmod u=rw,g=r,o=r lib/add_end_tx.c echo x - lib/packet_chksm.c sed 's/^@//' > "lib/packet_chksm.c" <<'@//E*O*F lib/packet_chksm.c//' /* packet_checksum - calculate the checksum value for a BOSS packet Mark Dapoz */ #include "boss.h" packet_checksum(packet_ptr) struct boss_packet *packet_ptr; { int checksum; int i; i=checksum=packet_ptr->size; checksum+=packet_ptr->header.target; checksum+=packet_ptr->header.position; checksum+=packet_ptr->header.control; for (; i > 0; checksum+=packet_ptr->data[--i]); packet_ptr->checksum=((checksum^0xff)+1)&0xff; } @//E*O*F lib/packet_chksm.c// chmod u=rw,g=r,o=r lib/packet_chksm.c echo x - lib/text_packet.c sed 's/^@//' > "lib/text_packet.c" <<'@//E*O*F lib/text_packet.c//' /* add_text_packet() - add a text selection packet to a stream of linked list of packets Mark Dapoz */ #include #include "boss.h" /* add a text only packet to the stream pointed to by last */ add_text_packet(text) char *text; { extern struct boss_packet *last; /* pointer to tail of BOSS packets */ extern int text_pos; /* current position of text record */ struct boss_packet *build_packet, *alt_packet; int double_packet=0; if (strlen(text)+text_pos > MAX_BOSS_REC) /* check if too big */ return(1); build_packet=(struct boss_packet *)malloc(sizeof(struct boss_packet)); if (strlen(text) < 256) { build_packet->size=strlen(text); strncpy(build_packet->data, text, build_packet->size); } else { /* too big to fit in one packet */ build_packet->size=255; strncpy(build_packet->data, text, 255); build_packet->data[255]='\0'; alt_packet=(struct boss_packet *)malloc(sizeof(struct boss_packet)); strncpy(alt_packet->data, text+255, strlen(text)-255); alt_packet->size=strlen(text)-255; alt_packet->header.target=TARG_TEXT; alt_packet->header.position=0; alt_packet->header.control=0; double_packet=1; } build_packet->header.target=TARG_TEXT; build_packet->header.position=0; build_packet->header.control=0; if (text_pos > 255) { build_packet->header.position=text_pos&0xff; build_packet->header.target+=text_pos/256; } else build_packet->header.position=text_pos; packet_checksum(build_packet); last->next=build_packet; /* add to linked list of packets */ if (double_packet) { if (text_pos+255 > 255) { alt_packet->header.position=(text_pos+255)&0xff; alt_packet->header.target+=(text_pos+255)/256; } else alt_packet->header.position=text_pos+255; packet_checksum(alt_packet); build_packet->next=alt_packet; last=alt_packet; } else last=build_packet; last->next=NULL; text_pos+=strlen(text); return(0); } @//E*O*F lib/text_packet.c// chmod u=rw,g=r,o=r lib/text_packet.c echo x - lib/add_memo.c sed 's/^@//' > "lib/add_memo.c" <<'@//E*O*F lib/add_memo.c//' /* add_memo() - add memo entries to a stream of linked list packets Mark Dapoz */ #include #include #include "boss.h" struct boss_packet *last; /* pointer to tail of BOSS packets */ int text_pos; /* current position of text record */ struct boss_packet *add_memo(memo_entry, packet_ptr) struct memo *memo_entry; struct boss_packet *packet_ptr; { struct boss_packet *head; /* first packet on BOSS packet stream */ struct boss_packet *build_packet; build_packet=(struct boss_packet *)malloc(sizeof(struct boss_packet)); if ((head=last=packet_ptr) != NULL) { for (; last->next !=NULL; last=last->next); /* locate end */ last->next=build_packet; } else head=last=build_packet; /* init list */ /* build select destination packet */ build_packet->size=2; build_packet->header.target=0; build_packet->header.position=0; build_packet->header.control=SEL_DEST; build_packet->data[0]=DEST_MEMO; /* we want a memo entry */ build_packet->data[1]=0; build_packet->next=NULL; packet_checksum(build_packet); last=build_packet; /* adv pointer */ /* run through list of telephone entries to add only adding those entries with real data */ while (memo_entry != NULL) { text_pos=0; /* start at beginning */ if (memo_entry->text != NULL) if (strlen(memo_entry->text)) add_text_packet(memo_entry->text); /* build end of record packet */ build_packet=(struct boss_packet *)malloc(sizeof(struct boss_packet)); build_packet->size=0; if (memo_entry->marked) /* marked record? */ build_packet->header.target=0x80; else build_packet->header.target=0; build_packet->header.position=0; build_packet->header.control=REC_END; /* end of record */ packet_checksum(build_packet); last->next=build_packet; /* add to linked list of packets */ last=build_packet; last->next=NULL; memo_entry=memo_entry->next; /* next record */ } return(head); } @//E*O*F lib/add_memo.c// chmod u=rw,g=r,o=r lib/add_memo.c echo x - lib/date_packet.c sed 's/^@//' > "lib/date_packet.c" <<'@//E*O*F lib/date_packet.c//' /* add_date_packet() - add a date selection packet to a stream of linked list of packets Mark Dapoz */ #include #include #include "boss.h" add_date_packet(date) char *date; { extern struct boss_packet *last; /* pointer to tail of BOSS packets */ struct boss_packet *build_packet; /* build date select packet */ build_packet=(struct boss_packet *)malloc(sizeof(struct boss_packet)); strncpy(build_packet->data, date, build_packet->size=strlen(date)); build_packet->header.target=TARG_DATE; build_packet->header.position=0; build_packet->header.control=0; build_packet->next=NULL; packet_checksum(build_packet); last->next=build_packet; /* add to linked list of packets */ last=build_packet; return(0); } @//E*O*F lib/date_packet.c// chmod u=rw,g=r,o=r lib/date_packet.c echo x - lib/add_sched.c sed 's/^@//' > "lib/add_sched.c" <<'@//E*O*F lib/add_sched.c//' /* add_sched() - add schedule entries to a stream of linked list packets Mark Dapoz */ #include #include #include "boss.h" struct boss_packet *last; /* pointer to tail of BOSS packets */ int text_pos; /* current position of text record */ struct boss_packet *add_sched(sched_entry, packet_ptr) struct schedule *sched_entry; struct boss_packet *packet_ptr; { struct boss_packet *head; /* first packet on BOSS packet stream */ struct boss_packet *build_packet; build_packet=(struct boss_packet *)malloc(sizeof(struct boss_packet)); if ((head=last=packet_ptr) != NULL) { for (; last->next !=NULL; last=last->next); /* locate end */ last->next=build_packet; } else head=last=build_packet; /* init list */ /* build select destination packet */ build_packet->size=2; build_packet->header.target=0; build_packet->header.position=0; build_packet->header.control=SEL_DEST; build_packet->data[0]=DEST_SCHED; /* we want a schedule entry */ build_packet->data[1]=0; build_packet->next=NULL; packet_checksum(build_packet); last=build_packet; /* adv pointer */ /* run through list of telephone entries to add only adding those entries with real data */ while (sched_entry != NULL) { text_pos=0; /* start at beginning */ if (sched_entry->date != NULL) if (strlen(sched_entry->date)) add_date_packet(sched_entry->date); if (sched_entry->time != NULL) if (strlen(sched_entry->time)) add_time_packet(sched_entry->time); if (sched_entry->alarm != NULL) if (strlen(sched_entry->alarm)) add_alarm_packet(sched_entry->alarm); if (sched_entry->text != NULL) if (strlen(sched_entry->text)) add_text_packet(sched_entry->text); /* build end of record packet */ build_packet=(struct boss_packet *)malloc(sizeof(struct boss_packet)); build_packet->size=0; if (sched_entry->marked) /* marked record? */ build_packet->header.target=0x80; else build_packet->header.target=0; build_packet->header.position=0; build_packet->header.control=REC_END; /* end of record */ packet_checksum(build_packet); last->next=build_packet; /* add to linked list of packets */ last=build_packet; last->next=NULL; sched_entry=sched_entry->next; /* next record */ } return(head); } @//E*O*F lib/add_sched.c// chmod u=rw,g=r,o=r lib/add_sched.c echo x - lib/time_packet.c sed 's/^@//' > "lib/time_packet.c" <<'@//E*O*F lib/time_packet.c//' /* add_time_packet() - add a time selection packet to a stream of linked list of packets Mark Dapoz */ #include #include #include "boss.h" add_time_packet(time) char *time; { extern struct boss_packet *last; /* pointer to tail of BOSS packets */ struct boss_packet *build_packet; /* build time select packet */ build_packet=(struct boss_packet *)malloc(sizeof(struct boss_packet)); strncpy(build_packet->data, time, build_packet->size=strlen(time)); build_packet->header.target=TARG_TIME; build_packet->header.position=0; build_packet->header.control=0; build_packet->next=NULL; packet_checksum(build_packet); last->next=build_packet; /* add to linked list of packets */ last=build_packet; return(0); } @//E*O*F lib/time_packet.c// chmod u=rw,g=r,o=r lib/time_packet.c echo x - lib/alarm_packet.c sed 's/^@//' > "lib/alarm_packet.c" <<'@//E*O*F lib/alarm_packet.c//' /* add_alarm_packet() - add an alarm selection packet to a stream of linked list of packets Mark Dapoz */ #include #include #include "boss.h" add_alarm_packet(alarm) char *alarm; { extern struct boss_packet *last; /* pointer to tail of BOSS packets */ struct boss_packet *build_packet; /* build alarm select packet */ build_packet=(struct boss_packet *)malloc(sizeof(struct boss_packet)); strncpy(build_packet->data, alarm, build_packet->size=strlen(alarm)); build_packet->header.target=TARG_ALARM; build_packet->header.position=0; build_packet->header.control=0; build_packet->next=NULL; packet_checksum(build_packet); last->next=build_packet; /* add to linked list of packets */ last=build_packet; return(0); } @//E*O*F lib/alarm_packet.c// chmod u=rw,g=r,o=r lib/alarm_packet.c echo x - lib/add_cal.c sed 's/^@//' > "lib/add_cal.c" <<'@//E*O*F lib/add_cal.c//' /* add_cal() - add calendar entries to a stream of linked list packets Mark Dapoz */ #include #include #include "boss.h" struct boss_packet *last; /* pointer to tail of BOSS packets */ int text_pos; /* current position of text record */ struct boss_packet *add_cal(cal_entry, packet_ptr) struct calendar *cal_entry; struct boss_packet *packet_ptr; { struct boss_packet *head; /* first packet on BOSS packet stream */ struct boss_packet *build_packet; build_packet=(struct boss_packet *)malloc(sizeof(struct boss_packet)); if ((head=last=packet_ptr) != NULL) { for (; last->next !=NULL; last=last->next); /* locate end */ last->next=build_packet; } else head=last=build_packet; /* init list */ /* build select destination packet */ build_packet->size=2; build_packet->header.target=0; build_packet->header.position=0; build_packet->header.control=SEL_DEST; build_packet->data[0]=DEST_CAL; /* we want a calendar entry */ build_packet->data[1]=0; build_packet->next=NULL; packet_checksum(build_packet); last=build_packet; /* adv pointer */ /* run through list of telephone entries to add only adding those entries with real data */ while (cal_entry != NULL) { text_pos=0; /* start at beginning */ if (cal_entry->month != NULL) if (strlen(cal_entry->month)) add_date_packet(cal_entry->month); /* build mark days packet */ build_packet=(struct boss_packet *)malloc(sizeof(struct boss_packet)); build_packet->size=4; /* always 4 bytes of data */ build_packet->header.target=TARG_MARK; /* mark days in calendar */ build_packet->header.position=0; build_packet->header.control=0; memcpy(build_packet->data, cal_entry->days, 4); /* copy data */ packet_checksum(build_packet); last->next=build_packet; /* add to linked list of packets */ last=build_packet; last->next=NULL; /* build end of record packet */ build_packet=(struct boss_packet *)malloc(sizeof(struct boss_packet)); build_packet->size=0; build_packet->header.target=0; build_packet->header.position=0; build_packet->header.control=REC_END; /* end of record */ packet_checksum(build_packet); last->next=build_packet; /* add to linked list of packets */ last=build_packet; last->next=NULL; cal_entry=cal_entry->next; /* next record */ } return(head); } @//E*O*F lib/add_cal.c// chmod u=rw,g=r,o=r lib/add_cal.c echo x - lib/add_bcard.c sed 's/^@//' > "lib/add_bcard.c" <<'@//E*O*F lib/add_bcard.c//' /* add_bcard() - add business card entries to a stream of linked list packets Mark Dapoz */ #include #include #include "boss.h" struct boss_packet *last; /* pointer to tail of BOSS packets */ int text_pos; /* current position of text record */ struct boss_packet *add_bcard(bus_entry, packet_ptr) struct bus_card *bus_entry; struct boss_packet *packet_ptr; { struct boss_packet *head; /* first packet on BOSS packet stream */ struct boss_packet *build_packet; build_packet=(struct boss_packet *)malloc(sizeof(struct boss_packet)); if ((head=last=packet_ptr) != NULL) { for (; last->next !=NULL; last=last->next); /* locate end */ last->next=build_packet; } else head=last=build_packet; /* init list */ /* build select destination packet */ build_packet->size=2; build_packet->header.target=0; build_packet->header.position=0; build_packet->header.control=SEL_DEST; build_packet->data[0]=DEST_BUS; /* we want a business card entry */ build_packet->data[1]=0; build_packet->next=NULL; packet_checksum(build_packet); last=build_packet; /* adv pointer */ /* run through list of business card entries to add only adding those entries with real data */ while (bus_entry != NULL) { text_pos=0; /* start at beginning */ if (bus_entry->employer != NULL) if (strlen(bus_entry->employer)) add_text_packet(bus_entry->employer); if (bus_entry->name != NULL) if (strlen(bus_entry->name)) add_text_packet(bus_entry->name); if (bus_entry->tel_number != NULL) if (strlen(bus_entry->tel_number)) add_text_packet(bus_entry->tel_number); if (bus_entry->position != NULL) if (strlen(bus_entry->position)) add_text_packet(bus_entry->position); if (bus_entry->dept != NULL) if (strlen(bus_entry->dept)) add_text_packet(bus_entry->dept); if (bus_entry->po_box != NULL) if (strlen(bus_entry->po_box)) add_text_packet(bus_entry->po_box); if (bus_entry->addr != NULL) if (strlen(bus_entry->addr)) add_text_packet(bus_entry->addr); if (bus_entry->telex != NULL) if (strlen(bus_entry->telex)) add_text_packet(bus_entry->telex); if (bus_entry->fax_number != NULL) if (strlen(bus_entry->fax_number)) add_text_packet(bus_entry->fax_number); if (bus_entry->free_1 != NULL) if (strlen(bus_entry->free_1)) add_text_packet(bus_entry->free_1); if (bus_entry->free_2 != NULL) if (strlen(bus_entry->free_2)) add_text_packet(bus_entry->free_2); if (bus_entry->free_3 != NULL) if (strlen(bus_entry->free_3)) add_text_packet(bus_entry->free_3); if (bus_entry->free_4 != NULL) if (strlen(bus_entry->free_4)) add_text_packet(bus_entry->free_4); if (bus_entry->free_5 != NULL) if (strlen(bus_entry->free_5)) add_text_packet(bus_entry->free_5); /* build end of record packet */ build_packet=(struct boss_packet *)malloc(sizeof(struct boss_packet)); build_packet->size=0; if (bus_entry->marked) /* marked record? */ build_packet->header.target=0x80; else build_packet->header.target=0; build_packet->header.position=0; build_packet->header.control=REC_END; /* end of record */ packet_checksum(build_packet); last->next=build_packet; /* add to linked list of packets */ last=build_packet; last->next=NULL; bus_entry=bus_entry->next; /* next record */ } return(head); } @//E*O*F lib/add_bcard.c// chmod u=rw,g=r,o=r lib/add_bcard.c echo mkdir - include mkdir include chmod u=rwx,g=rx,o=rx include echo x - include/boss.h sed 's/^@//' > "include/boss.h" <<'@//E*O*F include/boss.h//' /* boss.h - global definitions for BOSS packet structure and state machine declarations. Mark Dapoz 1990/02/11 mdapoz@hybrid.UUCP or mdapoz%hybrid@cs.toronto.edu */ #include #define START_TIMEOUT 120 /* wait for 2 minutes for transfer to start */ #define CHAR_TIMEOUT 5 /* wait for 5 seconds for next char */ #ifndef byte #define byte unsigned char /* 8 bits ? */ #endif /* Packet format: +------+--------+-----------+---------------------------------------+-------+ | | data | Header | Data Bytes | check | | ":" | byte +---+---+---+---+---+---+-----------+---+---+---+---| sum | | | count | | | | | | | ......... | | | | | | +------+--------+---+---+---+---+---+---+-----------+---+---+---+---+-------+ */ struct boss_packet { /* information passed in one BOSS packet */ byte size; /* number of data bytes in packet */ struct packet_header{ byte target; /* target location for packets */ byte position; /* position in record */ byte control; } header; /* control packet information */ byte data[256]; /* packet data bytes */ byte checksum; /* 2's compliment checksum */ struct boss_packet *next; /* pointer to next packet */ }; /* Packet header control byte values */ #define REC_END 0x01 /* end of record indicator */ #define SEL_DEST 0x02 /* BOSS destination selection */ #define TX_END 0xff /* end of transmission indicator */ /* SEL_DEST destination values */ #define DEST_CAL 0x80 /* calendar function */ #define DEST_TEL 0x90 /* telephone directory */ #define DEST_MEMO 0xa0 /* memo pad */ #define DEST_SCHED 0xb0 /* scheduler */ #define DEST_BUS 0xc0 /* business card directory */ /* Packet header target byte values */ #define TARG_TEXT 0x80 /* text data */ #define TARG_ALARM 0xc0 /* set alarm in scheduler */ #define TARG_MARK 0xd0 /* mark days in scheduler */ #define TARG_TIME 0xe0 /* set time in scheduler */ #define TARG_DATE 0xf0 /* set date in scheduler */ #define CR 0x0d /* ascii chars used */ #define LF 0x0a /* states used by state machine */ #define CONNECT 1 /* waiting to connect to BOSS */ #define COLON 2 /* scanning for ":" */ #define SIZE 3 /* reading BOSS packet size */ #define HEADER 4 /* reading BOSS packet header */ #define DATA 5 /* reading BOSS packet data */ #define CHECKSUM 6 /* reading BOSS packet checksum */ #define MAX_BOSS_REC 384 /* maximum amount of info in an entry */ #define CRLF_ACK 0x11 /* positive ack for initial connection */ #define PROTO_ACK '#' /* positive ack for data transfer protocol */ #define PROTO_ABORT '!' /* abort signal for data transfer protocol */ #define PROTO_LOST '?' /* confused signal for data transfer protocol */ /* hexadecimal to decimal conversion */ static int hex2dec[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 10, 11, 12, 13, 14, 15 }; #define h2d(x) (isxdigit(x) ? hex2dec[(toupper(x))-'0'] : 0) /* structures used by library routines */ struct bus_card { /* business card entry structure */ char *employer; char *name; char *tel_number; char *position; char *dept; char *po_box; char *addr; char *telex; char *fax_number; char *free_1; char *free_2; char *free_3; char *free_4; char *free_5; byte marked; /* is this record to be marked */ struct bus_card *next; }; struct telephone { /* telephone directory entry structure */ char *name; char *tel_number; char *addr; char *free_1; char *free_2; char *free_3; char *free_4; char *free_5; char *free_6; byte marked; /* is this record to be marked */ struct telephone *next; }; struct memo { /* memo pad entry structure */ char *text; byte marked; /* is this record to be marked */ struct memo *next; }; struct schedule { /* schedule keeper entry structure */ char *date; char *time; char *alarm; char *text; byte marked; /* is this record to be marked */ struct schedule *next; }; struct calendar { /* calendar entry structure */ char *month; byte days[4]; /* bitfield indicating marked days */ struct calendar *next; }; /* BOSS interface routines */ int boss_open(); /* open a device for BOSS i/o */ int boss_close(); /* close device opened for BOSS i/o */ int boss_write(); /* write BOSS packets */ struct boss_packet *boss_read();/* read BOSS packets */ struct telephone *extract_tele();/* extract telephone entries from packets */ struct bus_card *extract_bcard();/* extract bus card entries from packets */ struct memo *extract_memo(); /* extract memo entries from packets */ struct schedule *extract_sched();/* extract schedule entries from packets */ struct calendar *extract_cal();/* extract marked calendar entries from packets*/ struct boss_packet *add_tele(); /* add telephone entries to packet stream */ struct boss_packet *add_bcard();/* add business card entried to packet stream */ struct boss_packet *add_memo(); /* add memo entries to packet stream */ struct boss_packet *add_sched(); /* add schedule entries to packet stream */ struct boss_packet *add_cal(); /* add calendar entries to packet stream */ /* general purpose functions in libboss.a */ char *next_field(); /* similar to strtok() function */ @//E*O*F include/boss.h// chmod u=rw,g=r,o=r include/boss.h echo mkdir - bin mkdir bin chmod u=rwx,g=rx,o=rx bin echo Inspecting for damage in transit... temp=/tmp/shar$$; dtemp=/tmp/.shar$$ trap "rm -f $temp $dtemp; exit" 0 1 2 3 15 cat > $temp <<\!!! 65 458 3086 MANIFEST 33 95 771 Makefile 32 117 805 next_field.c 113 328 3424 extract_tele.c 60 252 1722 boss_open.c 193 608 5561 boss_read.c 58 227 1906 extract_memo.c 57 149 1505 Makefile 138 366 4175 extract_bus.c 97 353 3458 extract_sch.c 69 238 2365 extract_cal.c 12 22 166 boss_close.c 114 394 3345 boss_write.c 83 258 2845 add_tele.c 32 79 848 add_end_tx.c 20 37 464 packet_chksm.c 62 169 1957 text_packet.c 59 202 1953 add_memo.c 28 74 794 date_packet.c 68 223 2299 add_sched.c 28 74 794 time_packet.c 28 74 798 alarm_packet.c 67 240 2349 add_cal.c 98 296 3370 add_bcard.c 152 796 5227 boss.h 1766 6129 55987 total !!! wc MANIFEST Makefile lib/next_field.c lib/extract_tele.c lib/boss_open.c lib/boss_read.c lib/extract_memo.c lib/Makefile lib/extract_bus.c lib/extract_sch.c lib/extract_cal.c lib/boss_close.c lib/boss_write.c lib/add_tele.c lib/add_end_tx.c lib/packet_chksm.c lib/text_packet.c lib/add_memo.c lib/date_packet.c lib/add_sched.c lib/time_packet.c lib/alarm_packet.c lib/add_cal.c lib/add_bcard.c include/boss.h | sed 's=[^ ]*/==' | diff -b $temp - >$dtemp if [ -s $dtemp ] then echo "Ouch [diff of wc output]:" ; cat $dtemp else echo "No problems found." fi exit 0 -- Managing a software development team | Mark Dapoz is a lot like being on the psychiatric | mdapoz%hybrid@cs.toronto.edu ward. -Mitch Kapor, San Jose Mercury | mdapoz@torvm3.iinus1.ibm.com