Article View: net.micro.atari16
Article #957GEM-Kermit (Part 4 of 6)
From: axel
Date: Fri, 20 Jun 1986 03:05
Date: Fri, 20 Jun 1986 03:05
738 lines
21166 bytes
21166 bytes
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create:
# define.h
# stkdef.uuc
# stkerm.c
# stkfio.c
# stkgcm.c
# stkgem.c
# This archive created: Fri Jun 20 02:33:33 1986
export PATH; PATH=/bin:/usr/bin:$PATH
if test -f 'define.h'
then
echo shar: "will not over-write existing file 'define.h'"
else
cat << \SHAR_EOF > 'define.h'
/************************************************************************/
/* DEFINE.H Typical miscellaneous C definitions. */
/* Copyright 1985 Atari Corp. */
/* changed by B.Nebel (NIL & NULL) 12-5-86 */
/************************************************************************/
#define NIL 0L /* Nil Pointer */
#define NULL 0L /* synonym */
#define NO 0 /* "FALSE" */
#define YES 1 /* "TRUE" */
#define TRUE 1
#define FALSE 0
#define EOS '\0' /* End of String marker */
#define EOF (-1) /* End of File marker */
#define NEWLINE '\n' /* Carriage Return */
#define FAILURE (-1) /* Function failure return val */
#define SUCCESS (0) /* Function success return val */
#define FOREVER for(;;) /* Infinite loop declaration */
SHAR_EOF
fi
if test -f 'stkdef.uuc'
then
echo shar: "will not over-write existing file 'stkdef.uuc'"
else
cat << \SHAR_EOF > 'stkdef.uuc'
begin 777 stkobj.def
M (\ )+15)-14Y5 P$ 341%4TL 0! $U&24Q%
M % 0!-5%)!3E, !@$ 34]05$E/3@ !D! %13
M14Y$ : 0!44D5#14E610 '0$ 5$=%5 !X!
M %1&24Y)4T@ ? 0!40EE% (@$ 3T))3E1204X
M ",! $]44D%.3$]' $ -+15)005)!30 "0$ 04)/551+15(
M "@! $]&24Q705). J 0!/2$%.1%-(00 *0$ 3U!!1$1)
M3D< "L! $]005)#2$%. F 0!/4$%24T%610 $!0$ 2U!3
M4$-+3 ! 8! $M04E!#2TP 0( 0!+4%-424U/ $"0$
M2U!25$E-3P ! T! $M04T5/3 0. 0!+4%)%3TP $
M$ $ 2U!34$%$0P !!0! $M04U!#2U-4 05 0!+4%)00TM35
M $%P$ 2U!25%523@ !!H! $M04U%53U1% 09 0!+4%)154]4
M10 $&P$ 2U!%6$E43TL !!P! $M004)/4E0 % -+15)$
M25-03 % @$ 2T1314Y$ !0,! $M$4D5#14E6 4% 0!+
M1$9)3$Y!30 %" $ 2T1#3E9&24P !0L! $M$1D-.5 47
M 0!+1$)#3E0 %&@$ 2T103E5- !0X! $M$0E!3
M 41 0!+1$Y!2T-.5 %% $ 2T1424U#3E0 !(! $9$14Q%5$4
M 3 0!&4D5.04U% % $ 1E%5250 ! L! $M034%8
M5%)9 ' -+4D%"3U)4 ' P$ 2U)!0D]+ !P<! $M2
M04)-15-3 E 0!/1$5"54< 4P $$@$ 2U!0041, %,
M!$M224Y)15)2 & %+4D%"3U54 & @$ 2U)!0D]53TL
M $ !$M21DE,15@ " 1+4D9)3$Y%6 + $ 3U!!4D=%5
M !1P! $M21$%"3U)4 6 0!&5%E010 &P$ 5%!55
M , !$M%4DY920 ( %+4DU$3U194 0 !2U)-
M1$]$14P ( 4M2341/4D5. # %+4DU$3U)%,@ "0 #
M2U)-15-34P "0$! $U334]210 D" 0!-4T5/1@
M!0 $2U)$14Q$3TX 0 !$M24D5.1$]. * %+4D]$3U-!5@
M "P !2U)/1$]'150 8 !$M21$5,15)2 ' 1+4E)%3D52
M4@ # !2U)41$]33D0 T 4M25$1/4D5# . %+4E1$
M3U!55 #P !2U)41$]'150 @ !$M25%)!15)2 0 %+
M4D]$3T1%0@ $0 !2U)/1$]41@ D !$M21$)#3%-$ *
M 1+4E1&0TQ31 "P $2T524D9/4$X P !$M24T%61$].
M . 1+4D=%5$1/3@ #P $2U)$14)$3TX ! !$M25$9$3TX
M 4> 0!+1%!#3E0 ) P$ 35-'4TY$0D< "04! $U31T9)
M3$Y8 D$ 0!-4T=33D121 )!P$ 35-'4TY$1D0 "08! $U3
M1T524E!+ D( 0!-4T=43$Y04P )"0$ 35-'1$%44%, "10!
M $U31U1,3E!2 D5 0!-4T=$05104@ )"@$ 35-'0TA+15(
M"0L! $U31U534D%" D, 0!-4T=424U/50 )#0$ 35-'1%-4050
M "0X! $U31U120452 D/ 0!-4T=35$%410 )$ $ 35-'1D]0
M3@ "1$! $U31T524D9/ D2 0!-4T=31D%31@ )$P$ 35-'
M5%)%3T8 "18! $U31T9.15A4 D7 0!-4T=.15=&20 #0 $
M2U)#3TY&04( !2$! $M$4T5.1%, 4@ 0!+1%)%0T5)4P &
M!P$ 2U)!5DU- %, !@@! $M2059$050 D9 0!-4T=73U!%4@
M )&@$ 35-'15)33D$ "1@! $U31U!23T52 D; 0!-4T=214-2
M1 )' $ 35-'1D%41D4 "1T! $U31T9205-& 1 1+4E!2
M3T524@ $@ $2U)73U!%4E( !, !$M21D%41D52 DA 0!-
M4T=214-"1P )(@$ 35-'4D5#1D0 !<! $9$1E)%10 2
M -+4D1&4D5% 2 0$ 2U)$1DE$ $@(! $M21$9"60
M !(# 0!+4D1&3TL )'P$ 345'2$Y$1D$ !2,! $M21%)$64]+
M 4B 0!+4D121D-420 )'@$ 35-'0TA33D0 "2 ! $U31T-(
M1DQ5 DC 0!-4T=#2%)$ )) $ 35-'0TA0040 "24! $U3
H1T-(5TA# DF 0!-4T=(3D1/2P +0$ 3U1)34]55 "4!
end
SHAR_EOF
fi
if test -f 'stkerm.c'
then
echo shar: "will not over-write existing file 'stkerm.c'"
else
cat << \SHAR_EOF > 'stkerm.c'
/*
* stkerm.c ATARI ST kermit main program
*/
#define EXTERN /* global variables are actually declared here */
#include <stdio.h> /* common I/O definitions */
#include "stkinc.h" /* global ST KERMIT defintions */
/*
* K e r m i t File Transfer Utility
*
* UNIX Kermit, Columbia University, 1981, 1982, 1983
* Bill Catchings, Bob Cattani, Chris Maio, Frank da Cruz, Alan Crosswell
*
* Also: Jim Guyton, Rand Corporation
* Walter Underwood, Ford Aerospace
* Glenn Seaton, Kennedy Space Center
* Bradley Bosch,
* Robert Larson, U. of Southern California <Blarson@usc-ecl>
* James Jones
*
*
*/
/* Adaption to ATARI ST by Bernhard Nebel (NEBEL@DB0TUI11.BITNET)
* in March 1986.
* Actually, I used the OS9 Version (1.5) instead of the original C-Kermit
*/
/*
* Modification History:
* March, 17, 1986 Bernhard Nebel
* Implementation of GEM interface
*
* May, 16, 1986 BN
* Adaption of old V1.5 os9 Kermit to ATARI ST
*
*/
/*
* m a i n
*
* Main routine - initialize and start dispatch routine
*/
main()
{
if (w_init_screen()) /* setup screen */
{
init_params(); /* init global parameters */
w_multi(); /* do actual dispatching */
w_exit_screen(); /* clear up everything */
};
}
SHAR_EOF
fi
if test -f 'stkfio.c'
then
echo shar: "will not over-write existing file 'stkfio.c'"
else
cat << \SHAR_EOF > 'stkfio.c'
/*
* stfio.c ATARI ST kermit file i/o operations
*/
#include <osbind.h> /* TOS bindings */
#include <stdio.h> /* common I/O defs */
#include "stkinc.h" /* common ST KERMIT defs */
extern FILE *fopen();
extern FILE *fopenb();
extern char *strcpy();
extern char *strcat();
extern char *rindex();
extern char *index();
/*
* Global Variables
*/
struct dta_struct {
char resv[21];
char attrib;
int ctim;
int cdat;
int lbfsize;
int hbfsize;
char fname[14];
};
struct dta_struct dta;
/*
* file selection functions
*/
fremnode(path)
char path[];
/* remove last node (i.e. actual filename) in path spec */
{char *bsptr;
bsptr = rindex(path,'\\');
if ((bsptr == NIL) || (bsptr == &path[2]))
{
path[2] = '\\';
path[3] = '\0';
}
else
*bsptr = '\0';
}
faddnode(path,node)
char *path, *node;
/* add name to path spec, which is terminated by a '\' */
{
if (path[3] != '\0') strcat(path,"\\");
strcat(path,node);
}
fgetpath(path)
char path[];
/* get current path */
{
Dgetpath(&path[2],0);
path[0] = Dgetdrv() + 'A';
path[1] = ':';
if (path[2] == '\0') strcat(path,"\\");
}
fsetpath(path)
char path[];
{
Dsetdrv(path[0]-'A');
Dsetpath(&path[2]);
}
int fgetfilename(path,name,newfullname)
char path[], name[], newfullname[];
/* request filename from user */
/* full file name will be delivered on newfullname */
/* path and name are'nt changed */
/* on abort return FALSE else TRUE */
{
int button;
char tname[PFILNAMLEN];
strcpy(newfullname,path);
faddnode(newfullname,"*.*");
strcpy(tname,name);
fsel_input(newfullname,tname,&button);
fremnode(newfullname);
faddnode(newfullname,tname);
return button;
}
int fsetfilename(path,name)
/* ask user for new filename */
/* result will be delivered on path and name */
/* also the path will be changed !*/
/* and the DTA will be set! */
/* on abort FALSE will be returned */
char path[],name[];
{int button;
faddnode(path,"*.*");
fsel_input(path,name,&button);
fremnode(path);
fsetpath(path);
if (button)
Fsetdta(&dta);
return button;
}
/*
* get first file that match
*/
int f1stfil(name)
char name[];
{
if (Fsfirst(name,0) != 0)
return FALSE;
strcpy(filnam,dta.fname);
return TRUE;
}
/*
* get next file name
*/
int fnxtfil()
{
if (Fsnext() != 0)
return FALSE;
strcpy(filnam,dta.fname);
return TRUE;
}
SHAR_EOF
fi
if test -f 'stkgcm.c'
then
echo shar: "will not over-write existing file 'stkgcm.c'"
else
cat << \SHAR_EOF > 'stkgcm.c'
/*
* stkgcm.c generic commands for ATARI ST Kermit
*/
#include <stdio.h>
#include "stkinc.h"
/*
* Kermit Quit to Host Server Function
*
* by W. G. Seaton NASA SC-LPS-32 11/15/84
*
* 07/01/85 ral add error handling
*/
gencmdsw(cmd)
char cmd;
{
int len, num;
int retries;
for (retries = 0; retries < MAXTRY; retries++) {
packet[0] = cmd; /* Generic command */
spack('G', 0, 1, packet); /* Send Generic command */
switch(state = rpack(&len, &num, packet)) { /* get response */
case 'Y':
if (num == 0) {
return(TRUE);
}
break; /* not the ack for this packet */
case 'N': /* remote NAKed packet */
case FALSE: /* timeout or bad packet */
nakcnt++;
break;
case 'A':
return(FALSE); /* user abort*/
case 'E':
prerrpkt(packet);
return(FALSE);
default:
nakcnt++;
break;
};
dt_packets(TRUE);
}
return(FALSE);
}
SHAR_EOF
fi
if test -f 'stkgem.c'
then
echo shar: "will not over-write existing file 'stkgem.c'"
else
cat << \SHAR_EOF > 'stkgem.c'
/*
* "stkgem.c" ATARI ST GEM Window & Screen Management
*/
#include <osbind.h> /* TOS binding */
#include <stdio.h> /* common I/O defs */
#include <obdefs.h> /* common Object definitions */
#include <gemdefs.h> /* common GEM definitions */
#include "stkinc.h" /* common KERMIT definitions */
#include "stkobj.h" /* KERMIT object definitions */
extern FILE *fopen(),*fopenb();
/* communication variables for AES & VDI */
int contrl[12];
int intin[128];
int ptsin[128];
int intout[128];
int ptsout[128];
int workin[12];
int workout[57];
/* global variables */
int vdi_handle; /* handle for workstation */
int wi_handle; /* handle for one (fake) window */
int ap_id;
OBJECT /* addrs of objects */
*menu_addr,
*obj_addr;
int mbuf[8]; /* message buffer */
int gl_wchar, gl_hchar, gl_wbox, gl_hbox; /* parameters of virt. works. */
int xdesk, ydesk, hdesk, wdesk; /* desktop parameters */
/* initialize screen */
w_init_screen()
{int i,dummy;
ap_id = appl_init();
vdi_handle = graf_handle(&gl_wchar,&gl_hchar,&gl_wbox,&gl_hbox);
wind_get(0,WF_WORKXYWH,&xdesk,&ydesk,&wdesk,&hdesk);
for (i = 0; i < 10; i++) workin[i] = 1;
workin[10] = 2; /* use RC coordinates */
v_opnvwk(workin, &vdi_handle, workout);
if (!rsrc_load(KER_RSC))
{form_error(2);
return FALSE;
};
if (rsrc_gaddr(0,0,&menu_addr) == 0)
{form_alert(1,"[3][Resource File Format?][ABORT]");
return FALSE;
};
rsrc_gaddr(R_TREE,KERMENU,&menu_addr);
menu_bar(menu_addr,1);
return TRUE;
}
/* terminate code for screen management */
w_exit_screen()
{
v_clsvwk(vdi_handle);
appl_exit();
}
/* the main dispatcher */
w_multi()
{char *objstr;
check_options();
fgetpath(kpathname);
fgetpath(gpathname);
graf_mouse(ARROW,0x0L);
while (TRUE)
{evnt_mesag(mbuf);
wind_update(1); /* deselect menu */
if (mbuf[0] == MN_SELECTED)
{switch (mbuf[3])
{case MDESK: /* Desk */
if (mbuf[4] == ABOUTKER)
{
rsrc_gaddr(R_TREE,KRABOUT,&obj_addr);
objstr = (obj_addr[KRAVMM].ob_spec)->te_ptext;
sprintf(objstr,"%2d%02d",VERSION,RELEASE);
objstr = (obj_addr[KRAVDAT].ob_spec)->te_ptext;
sprintf(objstr,VERDATE);
displ_object(KRABOUT,-1,-1,MDESK,&obj_addr);
form_do(obj_addr,-1);
destroy_object(KRABOUT,-1,-1,MDESK);
change_state(obj_addr,KRABOUOK,NORMAL);
};
break;
case MFILE: /* File Menu */
switch (mbuf[4])
{case FQUIT:
fsetpath(kpathname);
if (debug) fclose(deb);
if (translog) fclose(log);
wind_update(0);
return; /* return and quit */
case FDELETE:
mdelfile(); break;
case FTYPE:
mtypefile(); break;
case FRENAME:
mrenfile(); break;
case FDFREE:
mdfree(); break;
}; /* switch on mbuf[4] in case MFILE */
break;
case MTRANS: /* Transfer Menu */
do_transfer(mbuf[4]);
break;
case MOPTION:
do_options(mbuf[4]);
break;
}; /* switch on mbuf[3] */
menu_tnormal(menu_addr,mbuf[3],1);
}; /* if message for us */
wind_update(0);
}; /* while */
} /* w_multi */
/*
* display an alert message
*/
displ_alert(cnt,obix)
int cnt,obix;
{long aaddr;
rsrc_gaddr(R_STRING,obix,&aaddr);
cnt = form_alert(cnt,aaddr);
return cnt;
}
/*
* change state of an object but don't display
*/
change_state(tree,ix,state)
long tree;
int state,ix;
{
objc_change(tree,ix,0,xdesk,ydesk,wdesk,hdesk,state,0);
}
/*
* draw an object
*/
displ_object(ix, x, y, menuix, ad)
int ix, x, y, menuix;
long int *ad;
/* if x or y < 0 then the centered position is used */
/* if y == 0 then y will be half a box below the menu bar */
/* otherwise the new x,y positions are used
/* menuix is the subindex of a menu title which is used for */
/* dial form. if -1 no growing box is displayed */
/* if -2 no dial form */
{ int obj_x, obj_y, obj_w, obj_h;
rsrc_gaddr(R_TREE,ix,ad);
form_center(*ad,&obj_x,&obj_y,&obj_w,&obj_h);
obj_x = ((x >= 0) ? x : obj_x);
y = ((y == 0) ? (ydesk+(gl_hbox/3)) : y);
obj_y = ((y >= 0) ? y : obj_y);
(*ad)->ob_x = obj_x + 3;
(*ad)->ob_y = obj_y + 3;
if (menuix == -1)
form_dial(0,0,0,0,0,obj_x,obj_y,obj_w,obj_h);
else if (menuix >= 0)
{
form_dial(0,menu_addr[menuix].ob_x,0,4*gl_wbox,gl_hbox,
obj_x,obj_y,obj_w,obj_h);
form_dial(1,menu_addr[menuix].ob_x,0,4*gl_wbox,gl_hbox,
obj_x,obj_y,obj_w,obj_h);
};
objc_draw(*ad,ROOT,MAX_DEPTH,obj_x,obj_y,obj_w,obj_h);
}
/*
* destroy an object
*/
destroy_object(ix, x, y, menuix)
int ix, x, y, menuix;
/* same parameter conventions as above */
{long ad;
int obj_x, obj_y, obj_w, obj_h;
rsrc_gaddr(R_TREE,ix,&ad);
form_center(ad,&obj_x,&obj_y,&obj_w,&obj_h);
obj_x = ((x >= 0) ? x : obj_x);
y = ((y == 0) ? (ydesk+(gl_hbox/3)) : y);
obj_y = ((y >= 0) ? y : obj_y);
(ad)->ob_x = obj_x + 3;
(ad)->ob_y = obj_y + 3;
if (menuix == -1)
form_dial(3,0,0,0,0,obj_x,obj_y,obj_w,obj_h);
else if (menuix >= 0)
{
form_dial(2,menu_addr[menuix].ob_x,0,4*gl_wbox,gl_hbox,
obj_x,obj_y,obj_w,obj_h);
form_dial(3,menu_addr[menuix].ob_x,0,4*gl_wbox,gl_hbox,
obj_x,obj_y,obj_w,obj_h);
};
}
/*
* some terminal functions
*/
/*
* type out a file in terminal mode
*/
mtypefile()
{
int lcnt;
char c, resp;
char *cp;
displ_object(KRMDOTYP,-1,0,MFILE,&obj_addr);
if (!fsetfilename(gpathname,filnam))
{destroy_object(KRMDOTYP,-1,0,MFILE);
return;
};
fp = fopen(filnam,"r");
if (fp == NIL)
{displ_alert(1,KRFILNEX);
destroy_object(KRMDOTYP,-1,0,MFILE);
return;};
destroy_object(KRMDOTYP,-1,0,MFILE);
menu_tnormal(menu_addr,MFILE,1);
init_terminal();
rsrc_gaddr(R_TREE,KRMESSS,&obj_addr);
while (Cconis()) Cnecin();
lcnt = 0;
while (TRUE)
{c = getc(fp);
if (feof(fp) || ferror(fp)) break;
Crawio(c);
if (c == '\n')
{Crawio(CR);
if (++lcnt > 22)
{lcnt = 0;
for (cp = obj_addr[MSMORE].ob_spec; *cp; cp++)
Crawio(*cp);
resp = Crawcin();
if (resp == ETX) break;
Crawio(CR);
v_eeol(vdi_handle);
};
};
};
if (resp != ETX)
{Crawio(CR);
Crawio(LF);
for (cp = obj_addr[MSEOF].ob_spec; *cp; cp++)
Crawio(*cp);
Crawcin();
};
fclose(fp);
exit_terminal();
}
/*
* init workstation as a terminal
*/
int init_terminal()
{
graf_mouse(M_OFF,NIL);
wi_handle = wind_create(0,xdesk,ydesk,wdesk,hdesk);
graf_growbox(menu_addr[MFILE].ob_x,0,4*gl_wbox,gl_hbox,
xdesk,ydesk,wdesk,hdesk);
wind_open(wi_handle,xdesk,ydesk,wdesk,hdesk);
v_enter_cur(vdi_handle);
v_curhome(vdi_handle);
v_eeos(vdi_handle);
}
/*
* exit terminal mode
*/
exit_terminal()
{
v_curhome(vdi_handle);
v_eeos(vdi_handle);
v_exit_cur(vdi_handle);
menu_bar(menu_addr,1);
wind_close(wi_handle);
wind_delete(wi_handle);
graf_shrinkbox(menu_addr[MFILE].ob_x,0,gl_wbox,gl_hbox,
xdesk,ydesk,wdesk,hdesk);
graf_mouse(M_ON,NIL);
}
/*
* ask for file and delete
*/
mdelfile()
{long addr;
displ_object(KRMDODEL,-1,0,MFILE,&addr);
if (fsetfilename(gpathname,filnam))
if (access(filnam,4) != 0)
displ_alert(1,KRFILNEX);
else
{
if (unlink(filnam) != 0)
displ_alert(1,KRDELERR);
else
displ_alert(1,KRDELDON);
};
destroy_object(KRMDODEL,-1,0,MFILE);
};
/*
* rename a file
*/
mrenfile()
{char oname[FILNAMLEN],
nname[FILNAMLEN];
OBJECT *objp;
int objx;
displ_object(KRMDOREN,-1,0,MFILE,&objp);
objx = KRMDOREN;
if (fsetfilename(gpathname,filnam))
if (access(filnam,4) != 0)
displ_alert(1,KRFILNEX);
else
{strcpy(oname,gpathname);
strcat(oname,filnam);
destroy_object(KRMDOREN,-1,0,MFILE);
displ_object(KRMDORE2,-1,0,MFILE,&objx);
objx = KRMDORE2;
if (fsetfilename(gpathname,filnam))
if (access(filnam,2) == 0)
displ_alert(1,KRFILEX);
else
{strcpy(nname,gpathname);
strcat(nname,filnam);
destroy_object(KRMDORE2,-1,0,MFILE);
objx = -1;
if (Frename(0,oname,nname) != 0)
displ_alert(1,KRRENERR);
else
displ_alert(1,KRRENDON);
};
};
if (objx >= 0)
destroy_object(objx,-1,0,MFILE);
}
/* display free disk space */
mdfree()
{OBJECT *objp;
char *bytp, *idp;
long int infbuf[4];
rsrc_gaddr(R_TREE,KRDFREE,&objp);
bytp = objp[KRDFBY].ob_spec->te_ptext;
idp = objp[KRDFID].ob_spec->te_ptext;
*bytp = '\0';
*idp = Dgetdrv() + 'A';
displ_object(KRDFREE,-1,-1,MFILE,&objp);
form_do(objp,KRDFID);
change_state(objp,KRDFOK,NORMAL);
if (Dfree(infbuf,*idp - 'A' + 1) != 0)
strcpy(bytp,"????????");
else
sprintf(bytp,"%ld",(infbuf[0] * infbuf[2] * infbuf[3]));
displ_object(KRDFREE,-1,-1,-2,&objp);
form_do(objp,-1);
change_state(objp,KRDFOK,NORMAL);
destroy_object(KRDFREE,-1,-1,MFILE);
}
SHAR_EOF
fi
exit 0
# End of shell archive
Technical Details
Message-ID:
<600013@coma.UUCP>Path:
arc1-ca.pugleaf.net!utzoo!watmath!clyde!burl!ulysses!mhuxr!mhuxt!houxm!whuxl!whuxlm!akgua!gatech!seismo!mcvax!unido!coma!axelShow Full Headers
Complete Article Headers
Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: arc1-ca.pugleaf.net!utzoo!watmath!clyde!burl!ulysses!mhuxr!mhuxt!houxm!whuxl!whuxlm!akgua!gatech!seismo!mcvax!unido!coma!axel From: axel@coma.UUCP Newsgroups: net.micro.atari16 Subject: GEM-Kermit (Part 4 of 6) Message-ID: <600013@coma.UUCP> Date: Thu, 19-Jun-86 23:05:00 EDT Article-I.D.: coma.600013 Posted: Thu Jun 19 23:05:00 1986 Date-Received: Sat, 28-Jun-86 04:05:00 EDT Sender: notes@unido.UUCP Lines: 739 Nf-ID: #N:coma:600013:000:20563 Nf-From: coma!axel Jun 20 04:05:00 1986