🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.sys.atari.st
Article #24774

Uemail source (2 of 12)

#24774
From: RDROYA01
Date: Thu, 05 Feb 1987 04:29
858 lines
28400 bytes
#       This is a shell archive.
#       Remove everything above and including the cut line.
#       Then run the rest of the file through sh.
#----cut here-----cut here-----cut here-----cut here----#
#!/bin/sh
# shar: Shell Archiver
#       Run the following text with /bin/sh to create:
#       file.c
#       fileio.c
#       print.c
# This archive created: Tue Feb  3 17:51:53 1987
cat << \SHAR_EOF > file.c
/*
 * The routines in this file
 * handle the reading and writing of
 * disk files. All of details about the
 * reading and writing of the disk are
 * in "fileio.c".
 */
#include        <stdio.h>
#include        "ed.h"
 
unsigned char   insflag = FALSE;        /* Flag for C mode in newline() */
 
/*
 * Read a file into the current
 * buffer. This is really easy; all you do it
 * find the name of the file, and call the standard
 * "read a file into the current buffer" code.
 * Bound to "C-X C-R".
 */
fileread(f, n)
register int f, n;
{
        register int    s;
        char            fname[NFILEN];
 
        if ((s=mlreply("Read file: ", fname, NFILEN)) != TRUE)
                return (s);
        return (readin(fname));
}
 
/*
 * Select a file for editing.
 * Look around to see if you can find the
 * file in another buffer; if you can find it
 * just switch to the buffer. If you cannot find
 * the file, create a new buffer, read in the
 * text, and switch to the new buffer.
 * Bound to C-X C-V.
 */
filevisit(f, n)
register int f, n;
{
        register BUFFER *bp;
        register WINDOW *wp;
        register LINE   *lp;
        register int    i;
        register int    s;
        char            bname[NBUFN];
        char            fname[NFILEN];
 
        if ((s=mlreply("Visit file: ", fname, NFILEN)) != TRUE)
                return (s);
        strcpy(lastbuf, curbp->b_bname);
        for (bp=bheadp; bp!=NULL; bp=bp->b_bufp) {
                if ((bp->b_flag&BFTEMP)==0 && strcmp(bp->b_fname, fname)==0) {
                        if (--curbp->b_nwnd == 0) {
                                curbp->b_dotp  = curwp->w_dotp;
                                curbp->b_doto  = curwp->w_doto;
                                curbp->b_markp = curwp->w_markp;
                                curbp->b_marko = curwp->w_marko;
                        }
                        curbp = bp;
                        curwp->w_bufp  = bp;
                        if (bp->b_nwnd++ == 0) {
                                curwp->w_dotp  = bp->b_dotp;
                                curwp->w_doto  = bp->b_doto;
                                curwp->w_markp = bp->b_markp;
                                curwp->w_marko = bp->b_marko;
                        } else {
                                wp = wheadp;
                                while (wp != NULL) {
                                        if (wp!=curwp && wp->w_bufp==bp) {
                                                curwp->w_dotp  = wp->w_dotp;
                                                curwp->w_doto  = wp->w_doto;
                                                curwp->w_markp = wp->w_markp;
                                                curwp->w_marko = wp->w_marko;
                                                break;
                                        }
                                        wp = wp->w_wndp;
                                }
                        }
                        lp = curwp->w_dotp;
                        i = curwp->w_ntrows/2;
                        while (i-- && lback(lp)!=curbp->b_linep)
                                lp = lback(lp);
                        curwp->w_linep = lp;
                        curwp->w_flag |= WFMODE|WFHARD;
                        mlwrite("[Old buffer]");
                        return (TRUE);
                }
        }
        makename(bname, fname);                 /* New buffer name.     */
        while ((bp=bfind(bname, FALSE, 0)) != NULL) {
                s = mlreply("Buffer name: ", bname, NBUFN);
                if (s == ABORT)                 /* ^G to just quit      */
                        return (s);
                if (s == FALSE) {               /* CR to clobber it     */
                        makename(bname, fname);
                        break;
                }
        }
        if (bp==NULL && (bp=bfind(bname, TRUE, 0))==NULL) {
                mlwrite("Cannot create buffer");
                return (FALSE);
        }
        if (--curbp->b_nwnd == 0) {             /* Undisplay.           */
                curbp->b_dotp = curwp->w_dotp;
                curbp->b_doto = curwp->w_doto;
                curbp->b_markp = curwp->w_markp;
                curbp->b_marko = curwp->w_marko;
        }
        curbp = bp;                             /* Switch to it.        */
        curwp->w_bufp = bp;
        curbp->b_nwnd++;
        return (readin(fname));                 /* Read it in.          */
}
 
/*
 * Read file "fname" into the current
 * buffer, blowing away any text found there. Called
 * by both the read and visit commands. Return the final
 * status of the read. Also called by the mainline,
 * to read in a file specified on the command line as
 * an argument.
 */
readin(fname)
char    fname[];
{
        register LINE   *lp1;
        register LINE   *lp2;
        register int    i;
        register WINDOW *wp;
        register BUFFER *bp;
        register int    s;
        register int    nbytes;
        register int    nline;
        char            line[NLINE];
 
        bp = curbp;                             /* Cheap.               */
        if ((s=bclear(bp)) != TRUE)             /* Might be old.        */
                return (s);
        bp->b_flag &= ~(BFTEMP|BFCHG);
        if (fname[0] == '~')                    /* an alias request */
                if ((s=parsefn(fname))==FALSE)
                        s = FIOFNF;
        strcpy(bp->b_fname, fname);
        if ((s=ffropen(fname)) == FIOERR)       /* Hard file open.      */
                goto out;
        if (s == FIOFNF) {                      /* File not found.      */
                mlwrite("[New file]");
                goto out;
        }
        mlwrite("[Reading %s]",fname);
        nline = 0;
        while ((s=ffgetline(line, NLINE)) == FIOSUC) {
                nbytes = strlen(line);
                if ((lp1=lalloc(nbytes)) == NULL) {
                        s = FIOERR;             /* Keep message on the  */
                        break;                  /* display.             */
                }
                lp2 = lback(curbp->b_linep);
                lp2->l_fp = lp1;
                lp1->l_fp = curbp->b_linep;
                lp1->l_bp = lp2;
                curbp->b_linep->l_bp = lp1;
                for (i=0; i<nbytes; ++i)
                        lputc(lp1, i, line[i]);
                ++nline;
        }
        ffclose();                              /* Ignore errors.       */
        if (s == FIOEOF) {                      /* Don't zap message!   */
                if (nline == 1)
                        mlwrite("[Read %d line]",nline);
                else
                        mlwrite("[Read %d lines]", nline);
        }
out:
        for (wp=wheadp; wp!=NULL; wp=wp->w_wndp) {
                if (wp->w_bufp == curbp) {
                        wp->w_linep = lforw(curbp->b_linep);
                        wp->w_dotp  = lforw(curbp->b_linep);
                        wp->w_doto  = 0;
                        wp->w_markp = curwp->w_dotp;
                        wp->w_marko = 0;
                        wp->w_flag |= WFMODE|WFHARD;
                }
        }
        if (s == FIOERR)                        /* False if error.      */
                return (FALSE);
        return (TRUE);
}
 
/*
 * Take a file name, and from it
 * fabricate a buffer name. This routine knows
 * about the syntax of file names on the target system.
 * I suppose that this information could be put in
 * a better place than a line of code.
 */
makename(bname, fname)
char    bname[];
char    fname[];
{
        register char   *cp1;
        register char   *cp2;
 
        if (fname[0] == '~')
                parsefn(fname);
        cp1 = &fname[0];
        while (*cp1 != 0)
                ++cp1;
#if     VMS
        while (cp1!=&fname[0] && cp1[-1]!=':' && cp1[-1]!=']')
                --cp1;
#endif
#if     CPM
        while (cp1!=&fname[0] && cp1[-1]!=':')
                --cp1;
#endif
#if     ST
        while (cp1!=&fname[0] && cp1[-1]!=':' && cp1[-1]!='\\')
                --cp1;
#endif
#if     V7
        while (cp1!=&fname[0] && cp1[-1]!='/')
                --cp1;
#endif
        cp2 = &bname[0];
        while (cp2!=&bname[NBUFN-1] && *cp1!=0 && *cp1!=';')
                *cp2++ = *cp1++;
        *cp2 = 0;
}
 
/*
 * Ask for a file name, and write the
 * contents of the current buffer to that file.
 * Update the remembered file name and clear the
 * buffer changed flag. This handling of file names
 * is different from the earlier versions, and
 * is more compatable with Gosling EMACS than
 * with ITS EMACS. Bound to "C-X C-W".
 */
filewrite(f, n)
register int f, n;
{
        register int    s;
        char            fname[NFILEN];
 
        if ((s=mlreply("Write file: ", fname, NFILEN)) != TRUE)
                return (s);
        if ((s=writeout(fname)) == TRUE) {
                strcpy(curbp->b_fname, fname);
                curbp->b_flag &= ~BFCHG;
                upmode();                       /* Update mode lines.   */
        }
        return (s);
}
 
/*
 * Save the contents of the current
 * buffer in its associatd file. No nothing
 * if nothing has changed (this may be a bug, not a
 * feature). Error if there is no remembered file
 * name for the buffer. Bound to "C-X C-S". May
 * get called by "C-Z".
 */
filesave(f, n)
register int f, n;
{
        register int    s;
 
        if ((curbp->b_flag&BFCHG) == 0)         /* Return, no changes.  */
                return (TRUE);
        if (curbp->b_fname[0] == 0) {           /* Must have a name.    */
                filename(f,n);                  /* prompt user for a name */
                if (curbp->b_fname[0] == 0)     /* still no name        */
                        return (FALSE);
        }
        if ((s=writeout(curbp->b_fname)) == TRUE) {
                curbp->b_flag &= ~BFCHG;
                upmode();                       /* Update mode lines.   */
 
        }
        return (s);
}
 
/*
 * This function performs the details of file
 * writing. Uses the file management routines in the
 * "fileio.c" package. The number of lines written is
 * displayed. Sadly, it looks inside a LINE; provide
 * a macro for this. Most of the grief is error
 * checking of some sort.
 */
writeout(fn)
char    fn[];
{
        register int    s;
        register LINE   *lp;
        register int    nline;
 
        if (fn[0] == '~')                       /* an alias request */
                if ((s=parsefn(fn))==FALSE)
                        return(FALSE);
        if ((s=ffwopen(fn)) != FIOSUC)          /* Open writes message. */
                return (FALSE);
        mlwrite("[Writing: %s]", fn);
        lp = lforw(curbp->b_linep);             /* First line.          */
        nline = 0;                              /* Number of lines.     */
        while (lp != curbp->b_linep) {
                if ((s=ffputline(&lp->l_text[0], llength(lp))) != FIOSUC)
                        break;
                ++nline;
                lp = lforw(lp);
        }
        if (s == FIOSUC) {                      /* No write error.      */
                s = ffclose();
                if (s == FIOSUC) {              /* No close error.      */
                        if (nline == 1)
                                mlwrite("[Wrote %d line]",nline);
                        else
                                mlwrite("[Wrote %d lines]", nline);
                }
        } else                                  /* Ignore close error   */
                ffclose();                      /* if a write error.    */
        if (s != FIOSUC)                        /* Some sort of error.  */
                return (FALSE);
        return (TRUE);
}
 
/*
 * The command allows the user
 * to modify the file name associated with
 * the current buffer. It is like the "f" command
 * in UNIX "ed". The operation is simple; just zap
 * the name in the BUFFER structure, and mark the windows
 * as needing an update. You can type a blank line at the
 * prompt if you wish.
 */
filename(f, n)
register int f, n;
{
        register int    s;
        char            fname[NFILEN];
 
        if ((s=mlreply("Name: ", fname, NFILEN)) == ABORT)
                return (s);
        if (fname[0] == '~')                    /* an alias request */
                s=parsefn(fname);
        if (s == FALSE)
                strcpy(curbp->b_fname, "");
        else
                strcpy(curbp->b_fname, fname);
        upmode();
        return (TRUE);
}
 
/* WRITEREG eXtended command  Write defined region to file.  Prompt
 * for filename.  Error if any sub-function returns failure. Bound to
 * CTLX-R.
 */
writereg(f, n)
register int f, n;
{
        register int    s;
        char            buf[NLINE];
        char            fname[NFILEN];
 
        n = 0;
        f = 0;
 
        if ((s=mlreply("Write region: ", fname, NFILEN)) == ABORT || s == FALSE)
                return(s);
        if (copyregion(NULL, NULL) != TRUE)
                return (FALSE);
        if ((s=ffwopen(fname)) != FIOSUC)
                return (s);
        while ((s=kremove(n++)) != EOF)
                {
                if (s != '\n' && f < NLINE)
                        buf[f++] = s;
                else
                        {
                        ffputline(buf, f);
                        f=0;
                        }
                }
        if ((s=ffclose()) == FIOERR)
                return(s);
        else
                mlwrite("[Region written to %s]",fname);
        return(TRUE);
}
 
/* FILEINSERT  eXtended command insert existing file at point.  All of the
 * necessary updating is done by the usual insert commands.  Bound to ^X-I.
 */
 
fileinsert(f, n)
register int f, n;
{
        char fname[NFILEN];
        char line[NLINE];
        register int c;
        register int nline;
        register int omarko;
        register LINE *omarkp;
 
        nline = 0;
 
        if ((f=mlreply("Insert file: ", fname, NFILEN)) == ABORT || f == FALSE)
                return(f);
        if (fname[0] == '~')
                if ((f=parsefn(fname))==FALSE)
                        return(f);
        if (ffropen(fname) == FIOFNF)
                {
                mlwrite("File: %s not found", fname);
                return (FALSE);
                }
        insflag = TRUE;
        /* save current place in buffer */
        if ((omarkp=lback(curwp->w_dotp)) == curbp->b_linep)
                omarkp = NULL;
        omarko = curwp->w_doto;
        mlwrite("[Mark set]");
        /* the standard routines take care of update */
        while ((f=ffgetline(line, NLINE)) == FIOSUC)
                {
                n = 0;
                ++nline;
                while ((c=line[n++]) !=NULL)
                        if (linsert(1, c) == FALSE)
                                {
                                insflag = FALSE;
                                return (FALSE);
                                }
                if (newline(FALSE, 1) == FALSE)
                        {
                        insflag = FALSE;
                        return (FALSE);
                        }
                }
        ffclose();
        if (f == FIOEOF)
                {
                if (nline == 1)
                        mlwrite("[Inserted %d line]",nline);
                else
                        mlwrite("[Inserted %d lines]", nline);
                }
        insflag = FALSE;
        /* The following code is needed if we want to insert a file
         * the way GNU does (returning to the point of insertion
         * when done).  The problem is with files inserted when the
         * current point is at the end or beginning of the buffer.
         */
        if (omarkp == NULL)
                /* inserted at beginning */
                {
                curwp->w_markp = curwp->w_dotp;
                curwp->w_marko = curwp->w_doto;
                gotobob(FALSE,TRUE);
                curwp->w_doto = omarko;
                }
        else
                /* inserted at end or in the midst */
                {
                curwp->w_markp = omarkp;
                curwp->w_marko = omarko;
                swapmark(FALSE,TRUE);
                forwline(NULL,1);
                }
        if (f == FIOERR)
                return (FALSE);
        return (TRUE);
}
 
parsefn(fname)
char fname[];
{
        register char   *ptr;
        char            *index(), *alias();
        char            template[NFILEN];
 
        if ((ptr=index(fname,'\\'))!=(char *)NULL)
                {
                *ptr = '\0';    /* ptr++==file; fname==alias */
                if (alias(&template[0],&fname[1])==(char *)NULL)
                        return(FALSE);
                strcat(template,++ptr);
                strcpy(fname,template);
                }
        else
                return(FALSE);
        return(TRUE);
}
SHAR_EOF
cat << \SHAR_EOF > fileio.c
/*
 * The routines in this file
 * read and write ASCII files from the
 * disk. All of the knowledge about files
 * are here. A better message writing
 * scheme should be used.
 */
#include        <stdio.h>
#include        "ed.h"
 
FILE    *ffp;                   /* File pointer, all functions. */
 
/*
 * Open a file for reading.
 */
ffropen(fn)
char    *fn;
{
        if ((ffp=fopen(fn, "r")) == NULL)
                return (FIOFNF);
        return (FIOSUC);
}
 
/*
 * Open a file for writing.
 * Return TRUE if all is well, and
 * FALSE on error (cannot create).
 */
ffwopen(fn)
char    *fn;
{
#if     VMS
        register int    fd;
 
        if ((fd=creat(fn, 0666, "rfm=var", "rat=cr")) < 0
        || (ffp=fdopen(fd, "w")) == NULL) {
#else
        if ((ffp=fopen(fn, "w")) == NULL) {
#endif
                mlwrite("Cannot open file for writing");
                return (FIOERR);
        }
        return (FIOSUC);
}
 
/*
 * Close a file.
 * Should look at the status in all systems.
 */
ffclose()
{
#if     ALCYON
        if (fclose(ffp) != FALSE) {
                mlwrite("Error closing file");
                return(FIOERR);
        }
        return(FIOSUC);
#endif
        fclose(ffp);
        return (FIOSUC);
}
 
/*
 * Write a line to the already
 * opened file. The "buf" points to the
 * buffer, and the "nbuf" is its length, less
 * the free newline. Return the status.
 * Check only at the newline.
 */
ffputline(buf, nbuf)
register char   buf[];
register int nbuf;
{
        register int    i;
 
        for (i=0; i<nbuf; ++i)
                putc(buf[i]&0xFF, ffp);
        putc('\n', ffp);
        if (ferror(ffp) != FALSE) {
                mlwrite("Write I/O error");
                return (FIOERR);
        }
        return (FIOSUC);
}
 
/*
 * Read a line from a file,
 * and store the bytes in the supplied
 * buffer. The "nbuf" is the length of the
 * buffer. Complain about long lines and lines
 * at the end of the file that don't have a
 * newline present. Check for I/O errors
 * too. Return status.
 */
ffgetline(buf, nbuf)
register char   buf[];
register int nbuf;
{
        register int    c;
        register int    i;
 
        i = 0;
        while ((c=getc(ffp))!=EOF && c!='\n') {
                if (i >= nbuf-1) {
                        mlwrite("File has long line");
                        return (FIOERR);
                }
                buf[i++] = c;
        }
        if (c == EOF) {
                if (ferror(ffp) != FALSE) {
                        mlwrite("File read error");
                        return (FIOERR);
                }
                if (i != 0) {
                        mlwrite("File has funny line at EOF");
                        return (FIOERR);
                }
                return (FIOEOF);
        }
        buf[i] = 0;
        return (FIOSUC);
}
 
/* Function to handle printing file pageheaders.  Needs access to ffp,
 * so it's here rather than in print.c where it probably belongs.  Two
 * lines of top margin and three lines between header and text are wired in.
 */
 
prhdg(f, pagenum, rm)
int f;
int pagenum;
int rm;
{
        fflush(ffp);
        if (f == TRUE)
                fprintf(ffp, "\f\n\n%*s\n%*s\n%*d\n\n\n",
                        rm, &prnhdr[0], rm, &prndate[0],
                        rm, pagenum);
        else
                fprintf(ffp, "\n\n%*s\n%*s\n\n\n\n",
                        rm, &prnhdr[0], rm, &prndate[0]);
 
        return(TRUE);
}
 
SHAR_EOF
cat << \SHAR_EOF > print.c
/* Output is only to the printer.  We need to test for printer
 * connect before doing anything.  If no connect, return FALSE.
 * These functions should allow line height and header selection
 * via a menu.
 */
 
#include <stdio.h>
#include <osbind.h>
#include "ed.h"
#include "printer.h"
 
/* PRINT eXtended command  Handles the print buffer function.  Gets user
 * parameters, calls printer init, and reports errors.  Bound to ^X <TAB>.
 */
 
static  char prnfin[NFILEN];
 
print(f, n)
register int f;
register int n;
{
 
        register int s,i;
        register int lm, rm, cw;
        char buf[MYBUF];
        lm = 6;         /* for now use 6 char left margins */
        cw = 12;        /* for now use 12 char pitch */
        i  = 0;
 
        if (n > 1)
                pagelen = n;    /* pagelen is set by routine in page.c */
 
        /* Eventually change these mode line questions into a window */
        /* on the screen using the cursor keys to select options */
 
        if (isnprint || (PRNRDY == NULL))
                {
                mlwrite("Device LST: is being used");
                return(FALSE);
                }
        if((s = readpattern("What is your name? ", &prnhdr[0])) != TRUE)
                return(s);
        if((s = readpattern("What is today's date? ", &prndate[0])) != TRUE)
                return(s);
        if((s = mlyesno("Do you want double spacing? ")) == FALSE)
                spacing = 1;
        else
                spacing = 2;
 
        strcpy(prnfin,"~temp\\prn.fin");
        parsefn(prnfin);
        mlwrite("[Writing buffer file: %s page length = %d]", prnfin,pagelen);
 
        if(! tabsize)
                temptab = 8;
        else
                temptab = tabsize;
 
        rm = 80;
 
        printout(prnfin, rm);   /* Temp file for buffer */
        if((in = open(prnfin, 0)) == EOF)
                {
                mlwrite("OPEN failure on buffer file");
                return(FALSE);
                }
        setprn(cw, spacing, temptab, lm, rm); /* Initialize printer */
        isnprint = TRUE;                        /* We are printing */
        /* Initially fill printer buffer */
        if ((s = read(in, buf, MYBUF)) > NULL)
                while (s--)
                        {
                        if (buf[i] == '\n')
                                Cprnout('\r');
                        if (!(int)gemdos(0x5,buf[i++]))
                                {
                                mlwrite("Write error on LST:");
                                return(FIOERR);
                                }
                        }
                return(TRUE);
}
 
/* SETPRN Local function to set printer parameters.  Mostly uses macros from
 * printer.h
 */
 
static int
setprn(pitch, lheight, tabstop, lmarg, rmarg)
register int pitch, lheight, tabstop, lmarg, rmarg;
{
        register int i;
        pitch -= 2;
        lheight = (lheight * 5) + 4;    /* this sort of gives single and */
                                        /* double spacing @ 6 per inch */
        RESET;
        for(i=0;i<lmarg;i++)
                PRINT(SPACE);
        SET_LMARG;
        while(rmarg)
                {
                for(i=0;i<tabstop;i++,--rmarg)
                        PRINT(SPACE);
                SET_TAB;
                }
        PRINT(CR);
        SET_PITCH(pitch);
        SET_HEIGHT(lheight);
        return(TRUE);
}
 
/*
 * This function performs the details of file buffer
 * printing. Uses the file management routines in the
 * "fileio.c" package.
 */
 
static int
printout(fn, marg)
register char   *fn;
register int marg;
{
        register int    s;
        register LINE   *lp;
        register int    nline;
        register short f;
 
        f = FALSE;                              /* first time through */
 
        if ((s=ffwopen(fn)) != FIOSUC)          /* Open writes message. */
                return (FALSE);
        lp = lforw(curbp->b_linep);             /* First line.          */
        nline = 0;                              /* Number of lines.     */
        linecnt = 0;
        pagecnt = 1;
        while (lp != curbp->b_linep)
                {
                if (linecnt == 0)
                        {
                        if((s=prhdg(f, pagecnt++, marg)) != TRUE)
                                break;
                        f = TRUE;               /* Each new page gets \f */
                        linecnt += 9;
                        }
                if ((s=ffputline(&lp->l_text[0], llength(lp))) != FIOSUC)
                        break;
                ++nline;
                lp = lforw(lp);
                if(linecnt > pagelen - 3)
                        {
                        linecnt = 0;
                        continue;
                        }
                ++linecnt;
        }
        if (s == FIOSUC)                        /* No write error.      */
                s = ffclose();
        if (s != FIOSUC)                        /* Some sort of error.  */
                return (FALSE);
        return (TRUE);
}
 
/* This function reads the temp file written above and writes the file to
 * the list device.  It then deletes the temp file.
 */
 
prnbuf()
{
        register int stat;
        register int i;
        char buf[BUFSIZE];
        i = 0;
 
        if ((stat = read(in, buf, BUFSIZE)) > NULL)
                {
                while(stat--)
                        {
                        if (buf[i] == '\n')
                                Cprnout('\r');
                        if (!(int)gemdos(0x5,buf[i++]))
                                {
                                mlwrite("Write error on LST:");
                                return(FIOERR);
                                }
                        }
                return(TRUE);
                }
        isnprint = FALSE;
        close(in);
        unlink(prnfin);
        NEWPAGE;
        mlwrite("[Printing completed]");
        update();
        return(TRUE);
}
SHAR_EOF
#       End of shell archive
exit 0
%NONAME-W-NOMSG, Message number 00000000
Technical Details
Message-ID: <8702051840.AA11841@ucbvax.Berkeley.EDU>
Path: arc1-ca.pugleaf.net!utzoo!watmath!clyde!cbatt!ucbvax!ULKYVX.BITNET!RDROYA01

Show 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!cbatt!ucbvax!ULKYVX.BITNET!RDROYA01
From: RDROYA01@ULKYVX.BITNET.UUCP
Newsgroups: comp.sys.atari.st
Subject: Uemail source (2 of 12)
Message-ID: <8702051840.AA11841@ucbvax.Berkeley.EDU>
Date: Wed, 4-Feb-87 23:29:00 EST
Article-I.D.: ucbvax.8702051840.AA11841
Posted: Wed Feb  4 23:29:00 1987
Date-Received: Sat, 7-Feb-87 12:48:28 EST
Sender: daemon@ucbvax.BERKELEY.EDU
Organization: University of Louisville
Lines: 858