koreth@ssyx.ucsc.edu (Steven Grimm) (05/30/88)
Submitted-by: bammi@mandrill.ces.cwru.edu (Jwahar R. Bammi)
Posting-number: Volume 1, Issue 42
Archive-name: zmdm/part02
#!/bin/sh
# this is part 2 of a multipart archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file COMMON.H continued
#
CurArch=2
if test ! -r s2_seq_.tmp
then echo "Please unpack part 1 first!"
exit 1; fi
( read Scheck
if test "$Scheck" != $CurArch
then echo "Please unpack part $Scheck next!"
exit 1;
else exit 0; fi
) < s2_seq_.tmp || exit 1
echo "x - Continuing file COMMON.H"
sed 's/^X//' << 'SHAR_EOF' >> COMMON.H
Xextern int Noeofseen;
Xextern int Totsecs; /* total number of sectors this file */
Xextern int Filcnt; /* count of number of files opened */
Xextern int Lfseen;
Xextern unsigned int Rxbuflen; /* Receiver's max buffer length */
Xextern int Tframlen; /* Override for tx frame length */
Xextern int blkopt; /* Override value for zmodem blklen */
Xextern int Rxflags;
Xextern char Lzconv; /* Local ZMODEM file conversion request */
Xextern char Lztrans;
Xextern int Command; /* Send a command, then exit. */
Xextern char *Cmdstr; /* Pointer to the command string */
Xextern int Cmdtries;
Xextern int Cmdack1; /* Rx ACKs command, then do it */
Xextern int Exitcode;
Xextern int Testattn; /* Force receiver to send Attn, etc with qbf. */
Xextern char *qbf;
Xextern long Lastread; /* Beginning offset of last buffer read */
Xextern int Lastc; /* Count of last buffer read or -1 */
Xextern int Dontread; /* Don't read the buffer, it's still there */
Xextern jmp_buf intrjmp; /* For the interrupt on RX CAN */
Xextern jmp_buf abrtjmp; /* for force abort */
Xextern int siggi; /* Line interrupt enable flag */
Xextern int Wantfcs32; /* want to send 32 bit FCS */
Xextern int Znulls; /* Number of nulls to send at beginning of ZDATA hdr */
X
X#ifndef REMOTE
Xextern int *aline_addr; /* Base addr of aline variables */
X#endif
X
Xextern int hlines; /* # of lines on screen */
Xextern int rez; /* current resolution */
Xextern int scolor; /* current fg/bg screen color toggle */
X
X#ifndef REMOTE
Xextern long *ms_ptr; /* Pointer to my screen memory */
X#if (MWC || MANX)
Xextern long *m_screen;
X#else
Xextern long m_screen[];
X#endif /* MWC || MANX */
X#endif /* REMOTE */
X
X#ifdef MWC
Xextern long _stksize;
X#endif /* MWC */
X
X#ifdef DLIBS
Xextern long _STKSIZE;
X#endif /* DLIBS */
X
X#ifdef MANX
Xextern long _STKSIZ;
X#endif /* MANX */
X
Xextern struct stat statbuf; /* Disk Transfer address for Find first etc */
Xextern int Baudrate; /* Current baud rate */
Xextern long drv_map; /* bit vector of valid drives */
X
Xextern BAUDS vbauds[];
Xextern IOREC save, /* the original Iorec is saved here for the duration
X of this process */
X *savep; /* ptr returned by Iorec() */
X
Xextern char iobuf[]; /* My large Rs232 receive buffer */
X
Xextern char *substr();
X
X#ifdef DYNABUF
Xextern long BBUFSIZ;
Xextern unsigned char *dalloc();
X#endif /* DYNABUF */
X
Xextern long pr_time;
X
X/* -eof- */
SHAR_EOF
echo "File COMMON.H is complete"
chmod 0600 COMMON.H || echo "restore of COMMON.H fails"
echo "x - extracting CONFIG.H (Text)"
sed 's/^X//' << 'SHAR_EOF' > CONFIG.H &&
X/*
X * Common Configuration file
X *
X * Jwahar Bammi
X * usenet: mandrill!bammi@{decvax,sun}.UUCP
X * csnet: bammi@mandrill.ces.CWRU.edu
X * arpa: bammi@mandrill.ces.CWRU.edu
X * CompuServe: 71515,155
X */
X
X
X/*
X * Compiler Type
X *
X * Mark Williams C
X * V2.0 or higher REQUIRED
X * V3 tested. (V 3.0.6 is what i got)
X *
X * Alcyon C
X * V 4.14 only tested
X * DLIBS compatible
X * ALN OK
X *
X * MegaMax C/Laser C (or whatever they call it)
X * I refuse to use braindamaged tools !!
X *
X * Manx Aztec C
X * Version 3.6a tested. Produces great code!
X *
X * Lattice C
X * Don't have a copy
X *
X * Comment out one of the #if 0 lines below corresponding to your
X * compiler.
X */
X
X /************** if using Mark Williams C **************/
X
X/* #if 0 */ /* Comment Out this line if using Mark Williams C */
X
X#define COMPILER "Compiled with Mark Williams C V3.0.6"
X#ifndef MWC
X#define MWC 1
X#endif /* MWC */
X#ifdef DLIBS
X#undef DLIBS /* only Alcyon version of DLIBS tested */
X#endif /* DLIBS */
X#ifdef ALCYON
X#undef ALCYON
X#endif /* ALCYON */
X#ifdef MANX
X#undef MANX
X#endif /* MANX */
X
X/* #endif */ /* Comment Out this line if using Mark Williams C */
X
X /************** if using Alcyon C **************/
X
X#if 0 /* comment out this line if using Alcyon C */
X
X#define COMPILER "Compiled with Alcyon C V4.14"
X#ifndef ALCYON
X#define ALCYON 1
X#endif /* ALCYON */
X#ifdef MWC
X#undef MWC
X#endif /* MWC */
X#ifdef MANX
X#undef MANX
X#endif /* MANX */
X
X#endif /* Comment Out this line if using Alcyon C */
X
X /************** if using MANX C **************/
X
X#if 0 /* comment out this line if using MANX C */
X
X#define COMPILER "Compiled with Manx Aztec C V3.6a"
X#ifndef MANX
X#define MANX 1
X#endif /* MANX */
X#ifdef MWC
X#undef MWC
X#endif /* MWC */
X#ifdef ALCYON
X#undef ALCYON
X#endif /* ALCYON */
X
X#endif /* Comment Out this line if using MANX C */
X
X/* ------------------------------------------------------------------------ */
X
X/*
X * Compile Stand Alone versions of RZ and SZ
X *
X * STANDALONE is #define'd, to compile `stand alone' alone versions
X * of RZ and SZ instead of the integrated ZMDM. A lot of folks
X * requested this feature.
X */
X
X#ifndef STANDALONE
X/* #define STANDALONE 1 */ /* define for standalone compilation */
X#endif /* STANDALONE */
X
X/* ------------------------------------------------------------------------ */
X
X/*
X * Compile a REMOTE version of ZMDM
X * REMOTE is #define'd to compile a `remote' version of ZMDM. A remote
X * versions talks through the serial port, instead of the keyboard/screen
X * Useful for dialing up your ST to download/upload files. One of the
X * local BBS's has this version available through a door to enable
X * people to Up/Down load batch using Zmodem protocol.
X *
X */
X#ifndef REMOTE
X/* #define REMOTE 1 */ /* define for remote version */
X#endif /* REMOTE */
X/* ------------------------------------------------------------------------ */
X
X/*
X * Phone Services
X * PHONES is #define'd to compile in the Phone Services module.
X * if PHONES is #define'd you must also define PREDIAL and
X * REDIAL, your modems dial and re-dial commands respectively.
X * NOTE: The REMOTE version of ZMDM does not support the
X * phones module.
X */
X
X#ifndef REMOTE
X/* #if 0 */ /* comment this line if you want the PHONES module */
X
X#define PHONES 1
X /*********** CAUTION: modem specific ***********/
X#define PREDIAL "ATDT" /* Modems dial command */
X#define REDIAL "A/" /* Modems Re-dial command */
X
X/* #endif */ /* comment this line if you want the PHONES module */
X#endif /* REMOTE */
X
X/* ------------------------------------------------------------------------ */
X
X/*
X * Do flow control while doing terminal emulation -
X * this only needs to be defined if you are
X * going to be running Zmdm at 19200 Baud AND
X * you are going to be sending it (from the host)
X * greater that 16k characters in one blast, without
X * any pause whatsoever. For 99.95 % of us mortals
X * this will never be required. Even if it is defined
X * its no big deal, as flow control will not happen
X * unless the condition described above exists.
X * NOTE: flow control is turned off during file transfers.
X */
X/* #define FLOW_CTRL 1 */ /* do flow control */
X
X/* ------------------------------------------------------------------------*/
X
X/*
X * DYNABUF
X * If #define'd use up rest up memory less LEAVEALONE bytes for
X * file buffers. The minimum acceptable size is MINACC
X */
X/* #if 0 */ /* Comment this line to use DYNABUF */
X
X#ifndef DYNABUF
X#define DYNABUF 1
X#define LEAVEALONE 16384L
X#define MINACC 8096L
X#endif
X
X/* #endif */ /* Comment this line to use DYNABUF */
X
X/* ------------------------------------------------------------------------*/
X
X/*
X * Size of file buffer
X *
X * Must be defined. Must be a long. (only define when
X * DYNABUF is NOT define'd).
X *
X */
X#ifndef DYNABUF
X#define BBUFSIZ 32768L /* Size of file/capture buffer */
X#endif /* DYNABUF */
X
X/* ------------------------------------------------------------------------*/
X
X/*
X * Size of Rs232 buffer
X *
X * Must be defined. Must be int (16 bits).
X */
X#define IBUFSIZ 16*1024 /* Size of my Rs232 receive buffer */
X
X/* ------------------------------------------------------------------------*/
X
X/*
X * GMTDIFF
X * Number of seconds from GMT (signed).
X * Must be defined.
X * Must be long.
X */
X#define GMTDIFF (-5L*3600L) /* EST (usa) -ve means behind GMT */
X
X/* ------------------------------------------------------------------------*/
X
X/*
X * Define RECURSE only if you want the expand a directory
X * to all its children feature for `sz', when you specify
X * a directory name as an arg to `sz'.
X *
X */
X#define RECURSE 1
X
X/* ------------------------------------------------------------------------*/
X
X/*
X * define BIGSTACK if you have very deep directory hierarchies
X *
X */
X#ifdef RECURSE
X/* #define BIGSTACK 1 */
X#endif /* RECURSE */
X
X/* ------------------------------------------------------------------------*/
X
X
X/* -eof- */
SHAR_EOF
chmod 0600 CONFIG.H || echo "restore of CONFIG.H fails"
echo "x - extracting DECL.H (Text)"
sed 's/^X//' << 'SHAR_EOF' > DECL.H &&
X /***********************************************\
X * *
X * Decl.h - extern declarations for C libarary *
X * must come after <stdio.h> is included *
X * *
X * Preprocessor symbol `MWC' should be *
X * defined when using Mark Williams C *
X * *
X * Preprocessor symbol `MANX' should be *
X * defined when using Manx Aztec C *
X * *
X \***********************************************/
X
X#ifndef DECL_H
X
Xextern FILE *fopen(), *freopen(), *fdopen();
X#if (!(MANX || MWC))
X#ifndef DLIBS
Xextern FILE *fopena(), *freopa();
Xextern FILE *fopenb(), *freopb();
X#endif /* DLIBS */
X#endif /* MANX || MWC */
X
X#if MANX
Xextern FILE *tmpfile();
X#endif
X
Xextern char *etoa();
Xextern char *ftoa();
X#if (!(MWC || MANX))
X#ifndef DLIBS
Xextern char *getpass();
X#endif
X#endif
X
X#ifndef MANX
Xextern char *index();
Xextern char *rindex();
X#endif
X
Xextern char *mktemp();
Xextern char *strcat();
Xextern char *strcpy();
Xextern char *strncat();
Xextern char *strncpy();
Xextern char *calloc(), *malloc(), *realloc();
X#if (MWC || MANX || DLIBS)
Xextern char *getenv();
X#endif
X
X#if (!(MWC || MANX))
Xextern char *sbrk();
X#endif
Xextern char *gets(), *fgets();
X#if (!(MWC || MANX))
X#ifndef DLIBS
Xextern char *ttyname();
X#endif
X#endif
X
X#if (MWC || MANX)
Xextern char *lmalloc(), *lcalloc(), *lrealloc();
X#endif
X
Xextern double atan();
Xextern double atof();
Xextern double ceil();
Xextern double cos();
Xextern double exp();
Xextern double fabs();
Xextern double floor();
Xextern double fmod();
Xextern double log();
Xextern double pow();
Xextern double sin();
Xextern double sinh();
Xextern double sqrt();
Xextern double tan();
Xextern double tanh();
X
Xextern int strlen();
Xextern int (*signal())();
X
Xextern long atol();
Xextern long ftell();
Xextern long getl();
X
X#ifndef DLIBS
Xextern long lseek(), tell();
X#endif
X
X#if (MWC || MANX)
Xextern char *memchr(), *memcpy(), *memset();
Xextern char *strchr(), *strerror(), *strpbrk(), *strrchr();
Xextern char *strstr(), *strtok();
Xextern double log10();
Xextern double frexp();
Xextern double ldexp();
Xextern double modf();
Xextern double asin(), acos(), atan2(), cosh();
X#endif /* MWC || MANX */
X
X#ifdef MANX
Xextern char *memmove(), *memccpy(), *lmemccpy(), *lmemcpy();
Xextern char *lmemmove(), *lmemchr(), *lmemset(), *strdup();
Xextern char *scdir(), *tmpnam(), *bsearch();
Xextern long labs();
Xextern double cotan();
X
X#define index strchr
X#define rindex strrchr
X
X#endif /* MANX */
X
X#define DECL_H
X#endif
X
X/* -eof- */
SHAR_EOF
chmod 0600 DECL.H || echo "restore of DECL.H fails"
echo "x - extracting EXPANDAR.C (Text)"
sed 's/^X//' << 'SHAR_EOF' > EXPANDAR.C &&
X
X /*
X * Examine each argument given to expandargs()
X * If it is a directory, then expand it
X * to all its component files, recursively
X * till you bottom out.
X * If it is not a directory, then just pass it on.
X *
X * Inputs: routine, argc, argv
X * Outputs: nargc, nargv (calls routine(nargc, nargv))
X * To test: compile with -DTEST
X * define MWC if using Mark Williams C
X * run with a directory as an arg
X * Author: JRB bammi@mandrill.ces.CWRU.edu
X * Requirements: Mark Williams C or Alcyon C
X * Wants lots of Dynamic memory. It
X * all depends upon how many files you
X * have. Use the -P option to prune
X * out subdirectories and do things
X * one at a time, if you keep running
X * out of memory.
X * With Mark Williams i use _stksize = 128K
X * With Alcyon i use memory model 2 (half of
X * of avail memory) in GEMSTART.S
X *
X * WARNINGS: Be CAREFUL about the 40 folder bug. Use
X * GEMBOOT or FOLDRXXX when dealing with
X * a deeply nested file structure.
X *
X * Added -P name prune option at the suggestion of dietz@zhmti
X * Multiple -P's may be given on the command line.
X * -P name may be given anywhere on the command line. -P name
X * will prune the subdirectories named as arguement to -P.
X * ie: when the program is decending the file hierarchy it
X * will not visit the pruned branches.
X * NOTE that the option is -P and not -p
X * (-p is a valid sz option).
X * NOTE that the arguement given to -P can be the name
X * of a file or a directory. In case it is a file,
X * that file is skipped.
X *
X */
X
X/*
X * Expand argc, so that the called routine(nargc,nargv) receives only
X * filenames, in nargv[][]
X *
X ************************************************************************
X * *
X * WARNING: Be CAREFUL about the 40 folder bug. Use *
X * GEMBOOT or FOLDRXXX when dealing with *
X * a deeply nested file structure. *
X * *
X ************************************************************************
X *
X * Jwahar R. Bammi
X * usenet: mandrill!bammi@{decvax,sun}.UUCP
X * csnet: bammi@mandrill.ces.CWRU.edu
X * arpa: bammi@mandrill.ces.CWRU.edu
X * CompuServe: 71515,155
X *
X */
X
X#ifdef TEST
X#include <stdio.h>
X#include <osbind.h>
X#include <ctype.h>
X#endif
X
X#ifdef TRUE
X#undef TRUE
X#endif
X#ifdef OK
X#undef OK
X#endif
X#ifdef FALSE
X#undef FALSE
X#endif
X
X#define TRUE 1
X#define OK 0
X#define FALSE 0
X#define Realloc realloc
X
X#ifdef TEST
Xstruct stat
X{
X char st_sp1[21]; /* Junk */
X char st_mode; /* File attributes */
X int st_time; /* Mod Time */
X int st_date; /* Mod date */
X long st_size; /* File size */
X char st_name[14]; /* File name */
X};
X#endif
X
Xtypedef struct _prunelist {
X char *name; /* name of subdirectory to prune */
X struct _prunelist *next; /* ptr to next */
X} PRUNELIST;
X
Xstatic char *ProgName;
Xstatic PRUNELIST *PruneList = (PRUNELIST *)NULL; /* Head of PruneList */
X
Xstatic char **CopyToNargv();
Xstatic char **ExpandStack();
Xstatic void FreeStack();
Xstatic void FreeNargv();
Xstatic void FreePrune();
Xstatic void FreeUp();
Xstatic int PushDir();
Xstatic char *PopDir();
Xstatic int ProcessDirs();
Xstatic PRUNELIST *AddPrune();
Xstatic int OnPruneList();
Xstatic int isdir();
X
Xextern int existd();
X
Xexpandargs(routine, argc, argv)
Xint (*routine)();
Xint argc;
Xchar **argv;
X{
X register int status;
X int nargc;
X char **nargv;
X extern char **CopyToNargv();
X extern PRUNELIST *AddPrune();
X extern int existd();
X
X nargc = 0;
X nargv = (char **)NULL;
X ProgName = *argv;
X
X /* copy argv[0] blindly */
X if((nargv = CopyToNargv(*argv, nargc, nargv)) == (char **)NULL)
X {
X FreeUp(nargc, nargv);
X return(~OK);
X }
X
X nargc++;
X
X while((--argc) > 0)
X {
X argv++;
X if(**argv == '-')
X {
X /* copy any options except -P */
X#ifdef TEST
X /* some shell pass -P as -p */
X if( ((*argv)[1] == 'P') || ((*argv)[1] == 'p'))
X#else
X if( (*argv)[1] == 'P')
X#endif
X {
X if((--argc) <= 0)
X {
X fprintf(STDERR,"no argument given to -P\n");
X FreeUp(nargc, nargv);
X return(~OK);
X }
X if((PruneList = AddPrune(PruneList,*++argv))
X == (PRUNELIST *)NULL)
X {
X FreeUp(nargc, nargv);
X return(~OK);
X }
X }
X else
X {
X if((nargv = CopyToNargv(*argv, nargc, nargv))
X == (char **)NULL)
X {
X FreeUp(nargc, nargv);
X return(~OK);
X }
X else
X nargc++;
X }
X
X }
X else
X {
X /* If its not on the PruneList then */
X if(!OnPruneList(PruneList, *argv))
X {
X /* if it is a directory, push it */
X if(existd(*argv))
X {
X if((status = PushDir(*argv)) != OK)
X {
X FreeUp(nargc, nargv);
X return(status);
X }
X }
X else
X {
X /* it is NOT a directory, copy to nargv */
X if((nargv = CopyToNargv(*argv, nargc, nargv))
X == (char **)NULL)
X {
X FreeUp(nargc, nargv);
X return(~OK);
X }
X else
X nargc++;
X }
X }
X }
X } /* while */
X
X /* process pushed directories if any */
X if((status = ProcessDirs(&nargc, &nargv)) != OK)
X {
X FreeUp(nargc, nargv);
X return(status);
X }
X /* else Free the Stack and Prune List, call *routine */
X FreeStack();
X FreePrune();
X status = (*routine)(nargc, nargv);
X FreeNargv(nargc, nargv);
X
X return status;
X
X}
X
X/*
X * Expand nargv by an element and copy a String into the new element
X *
X */
Xstatic char **CopyToNargv(string, nargc, nargv)
Xchar *string;
Xint nargc;
Xchar **nargv;
X{
X extern char *malloc(), *Realloc(), *strcpy();
X extern int strlen();
X
X /* expand nargv by 1 element */
X if(nargv == (char **)NULL)
X /* do it with malloc for the first one */
X nargv = (char **)malloc(sizeof(char **));
X else
X /* do it with Realloc for others */
X nargv = (char **)Realloc(nargv, (nargc+1)*sizeof(char **));
X
X if(nargv == (char **)NULL)
X {
X /* failed to get memory */
X fprintf(STDERR,"%s(CopyToNargv()): Out of Memory\n", ProgName);
X return ((char **)NULL);
X }
X
X /* Get mem for string */
X if(( nargv[nargc] = malloc(strlen(string)+1)) == (char *)NULL)
X {
X /* failed to get memory */
X fprintf(STDERR,"%s(CopyToNargv()): Out of Memory\n", ProgName);
X return ((char **)NULL);
X }
X
X /* copy string into nargv[nargc] */
X (void)strcpy( nargv[nargc], string);
X return(nargv);
X}
X
Xstatic char **Stack = (char **)NULL; /* directory stack */
Xstatic char StackSize = 0; /* Size of current Stack */
Xstatic int Top = -1;
X#define STACK_EMPTY (Top < 0)
X#define CHUNKSIZE 16
X
X/*
X * Grow the Stack by one chunk of CHUNKSIZE elements
X *
X */
Xstatic char **ExpandStack(Stack)
Xchar **Stack;
X{
X extern char *malloc(), *Realloc();
X
X /* Grow Stack */
X if(Stack == (char **)NULL)
X /* with malloc */
X Stack = (char **)malloc(CHUNKSIZE * sizeof(char **));
X else
X /* with Realloc */
X Stack = (char **)Realloc(Stack, (StackSize+CHUNKSIZE) *
X sizeof(char **));
X
X if(Stack == (char **)NULL)
X {
X /* outa mem */
X fprintf(STDERR,"%s(ExpandStack()): Out of Memory\n", ProgName);
X return((char **)NULL);
X }
X StackSize += CHUNKSIZE;
X return(Stack);
X}
X
X/*
X * Free the Stack
X *
X */
Xstatic void FreeStack()
X{
X if(StackSize > 0)
X (void)free(Stack);
X Stack = (char **)NULL;
X StackSize = 0;
X Top = -1;
X}
X
X/*
X * Free Nargv
X *
X */
Xstatic void FreeNargv(nargc, nargv)
Xint nargc;
Xchar *nargv[];
X{
X register int i;
X
X for(i = 0; i < nargc; i++)
X (void)free(nargv[i]);
X if(nargc > 0)
X (void)free(nargv);
X}
X
X/*
X * Free the PruneList
X *
X */
Xstatic void FreePrune()
X{
X register PRUNELIST *p, *next;
X
X for(p = PruneList; p != (PRUNELIST *)NULL; p = next)
X {
X next = p->next;
X (void)free(p);
X }
X PruneList = (PRUNELIST *)NULL;
X}
X
X/*
X * FreeUp before bad exit
X *
X */
Xstatic void FreeUp(nargc, nargv)
Xint nargc;
Xchar **nargv;
X{
X FreeStack();
X FreePrune();
X FreeNargv(nargc, nargv);
X}
X
X/*
X * Push a directory name on Stack
X *
X */
Xstatic int PushDir(name)
Xchar *name;
X{
X extern char *malloc(), *strcpy();
X extern int strlen();
X extern char **ExpandStack();
X
X#ifdef DDEBUG
Xprintf("PushDir: %s\n", name);
X#endif
X
X ++Top;
X if(Top >= StackSize)
X {
X if((Stack = ExpandStack(Stack)) == (char **)NULL)
X return(~OK);
X }
X
X if((Stack[Top] = malloc(strlen(name)+1)) == (char *)NULL)
X {
X /* outa mem */
X fprintf(STDERR,"%s(PushDir()): Out of Memory\n", ProgName);
X return(~OK);
X }
X (void)strcpy(Stack[Top], name);
X return(OK);
X}
X
X/*
X * Pop a directory name from the stack
X *
X */
Xstatic char *PopDir()
X{
X register char *r;
X extern char **ShrinkStack();
X
X if(STACK_EMPTY)
X return ((char *)NULL);
X
X r = Stack[Top];
X Top--;
X return(r);
X}
X
Xstatic int BadStatus = FALSE;
X#define BADSTATUS (BadStatus != FALSE)
X#define MAXNAMLEN 128
X
X/*
X * Process directories on the Stack, by adding all the
X * files in a directory to nargv.
X */
Xstatic int ProcessDirs(nargc, nargv)
Xint *nargc;
Xchar ***nargv;
X{
X register char *name;
X register struct stat *dp;
X register int status, slashp;
X char path[MAXNAMLEN+1];
X extern char **CopyToNargv();
X extern char *PopDir();
X extern char *alltolower();
X
X if(BADSTATUS)
X return(~OK);
X
X if(STACK_EMPTY)
X /* Nothing more to do */
X return(OK);
X
X /* Pop a directory from Stack and process */
X if((name = PopDir()) == (char *)NULL)
X {
X /* Oh Oh */
X fprintf(STDERR,"Internal Error (BUG), PopDir returns NULL\n");
X BadStatus = (~FALSE);
X return(~OK);
X }
X
X strcpy(path, name);
X if(path[(strlen(path)-1)] == '\\')
X {
X strcat(path,"*.*");
X slashp = TRUE;
X }
X else
X {
X strcat(path,"\\*.*");
X slashp = FALSE;
X }
X
X /* Open the directory */
X if(Fsfirst(path, 0x0020| 0x0010 | 0x0001) != 0)
X {
X /* trouble opening directory */
X fprintf(STDERR,"Trouble opening %s\n",path);
X /* set BADSTATUS and return */
X BadStatus = (~FALSE);
X return(~OK);
X }
X
X /* get the DTA */
X dp = (struct stat *)Fgetdta();
X
X /* for each entry in the directory, if it is a file
X add to nargv. If it is a directory, Push it onto
X the directory stack.
X */
X do
X {
X if(! ((strcmp(dp->st_name,".") == 0) ||
X (strcmp(dp->st_name,"..") == 0)) )
X {
X strcpy(path, name);
X if(!slashp)
X strcat(path,"\\");
X strcat(path,dp->st_name);
X
X /* If this path is on the PruneList skip */
X if(OnPruneList(PruneList, alltolower(path)))
X continue;
X
X if(!isdir(path, dp->st_mode))
X {
X /* not a dir -- add this to nargv */
X if((*nargv = CopyToNargv(path, *nargc, *nargv))
X == (char **)NULL)
X {
X BadStatus = (~FALSE);
X return(~OK);
X }
X else
X {
X *nargc += 1;
X }
X
X }
X else
X {
X
X /* Push This directory */
X if((status = PushDir(path)) != OK)
X {
X BadStatus = (~FALSE);
X return(status);
X }
X }
X }
X } while(Fsnext() == 0);
X
X free(name); /* done with this directory */
X
X /* go do the rest */
X return (ProcessDirs(nargc, nargv));
X}
X
X/*
X * Add a name to PruneList
X *
X */
Xstatic PRUNELIST *AddPrune(list, name)
XPRUNELIST *list;
Xchar *name;
X{
X extern char *malloc();
X register PRUNELIST *new;
X
X if((new = (PRUNELIST *)malloc(sizeof(PRUNELIST))) == (PRUNELIST *)NULL)
X {
X /* outa mem */
X fprintf(STDERR,"%s(AddPrune()): Out of Memory\n", ProgName);
X return(new);
X }
X
X new->name = name;
X new->next = list;
X
X return(new);
X}
X
X/*
X * Search for name on PruneList
X *
X */
Xstatic int OnPruneList(list, name)
Xregister PRUNELIST *list;
Xregister char *name;
X{
X for(; list != (PRUNELIST *)NULL; list = list->next)
X {
X if(strcmp(list->name, name) == 0)
X return(~FALSE);
X }
X
X return(FALSE);
X}
X
X/*
X * test if a subdirectory exists, without touching the DTA
X * include special case of 'D:\' that Fsfirst does'nt handle correctly
X */
Xstatic int isdir(name, attr)
Xregister char *name;
Xregister int attr;
X{
X /* assuming the DTA buffer is already set up */
X extern long drv_map;
X register int drive;
X
X if(attr & 0x0010)
X return TRUE;
X
X /* Gemdos doesn't like d:\ style dirs */
X if((name[3] == '\0') && (name[2] == '\\') && (name[1] == ':'))
X {
X drive = name[0];
X if(isupper(drive))
X drive = tolower(drive);
X
X drive = drive - 'a';
X if((drv_map & (1L << drive)) == 0)
X return FALSE;
X else
X return TRUE;
X }
X /* Nor does Gemdos understand '.' or '..' */
X /* Hey Atari, don't you guys ever test anything */
X if((strcmp(name,".") == 0) || (strcmp(name,"..") == 0) ||
X (strcmp(name,".\\") == 0) || (strcmp(name,"..\\") == 0))
X return TRUE;
X
X return FALSE;
X}
X
X
X#ifdef TEST
X
X/*
X * convert string to all lower case
X */
Xchar *alltolower(s)
Xchar *s;
X{
X register char *p;
X
X for(p = s; *p != '\0'; p++)
X if(isupper(*p))
X *p = tolower(*p);
X
X return s;
X}
X
X/*
X * test if a subdirectory exists
X * include special case of 'D:\' that Fsfirst does'nt handle correctly
X * (this routine not needed for zmdm, as it is defined in common.c)
X */
Xint existd(name)
Xregister char *name;
X{
X /* assuming the DTA buffer is already set up */
X /* assumes drv_map has been read in drv_map externally */
X extern long drv_map;
X register int drive;
X extern struct stat statbuf;
X
X if (Fsfirst(name , 0x0021|0x0010) == 0)
X {
X if((statbuf.st_mode & 0x0010) == 0x0010)
X return TRUE;
X }
X
X /* Gemdos doesn't like d:\ style dirs */
X if((name[3] == '\0') && (name[2] == '\\') && (name[1] == ':'))
X {
X drive = name[0];
X if(isupper(drive))
X drive = tolower(drive);
X
X drive = drive - 'a';
X if((drv_map & (1L << drive)) == 0)
X return FALSE;
X else
X return TRUE;
X }
X /* Nor does Gemdos understand '.' or '..' */
X /* Hey Atari, don't you guys ever test anything */
X if((strcmp(name,".") == 0) || (strcmp(name,"..") == 0) ||
X (strcmp(name,".\\") == 0) || (strcmp(name,"..\\") == 0))
X return TRUE;
X
X return FALSE;
X}
X
Xint MAIN(argc, argv)
Xint argc;
Xchar **argv;
X{
X register int i;
X
X for(i = 0; i < argc; i++)
X printf("%d:\t%s\n", i, argv[i]);
X
X
X return(0);
X}
X
X
Xstruct stat statbuf; /* Disk Transfer address for Find first etc */
Xlong drv_map;
X
X#ifdef MWC
Xlong _stksize = 128L * 1024L;
X#endif
X
X#ifdef MANX
Xlong _STKSIZ = 128L * 1024L;
X#endif
X
Xmain(argc, argv)
Xint argc;
Xchar **argv;
X{
X /* Set up Dta */
X Fsetdta(&statbuf);
X drv_map = Drvmap();
X
X exit(expandargs(MAIN, argc, argv));
X}
X
X#endif /* TEST */
X
X/* -eof- */
SHAR_EOF
chmod 0600 EXPANDAR.C || echo "restore of EXPANDAR.C fails"
echo "x - extracting FILEIO.C (Text)"
sed 's/^X//' << 'SHAR_EOF' > FILEIO.C &&
X/*
X * File I/O (with large buffers) Module
X *
X * Jwahar Bammi
X * usenet: mandrill!bammi@{decvax,sun}.UUCP
X * csnet: bammi@mandrill.ces.CWRU.edu
X * arpa: bammi@mandrill.ces.CWRU.edu
X * CompuServe: 71515,155
X */
X
X#include "config.h"
X
X#include "zmdm.h"
X#include "common.h"
X
X#define O_RDONLY 1
X#define O_WRONLY 2
X#define O_APONLY 4
X#ifndef DYNABUF
X#define MBUFSIZ (((long)BBUFSIZ)-1L)
X#else
Xstatic long MBUFSIZ;
X#endif /* DYNABUF */
X
Xstatic unsigned char *bptr;
X
Xstatic long flcount = (-1L);
Xstatic int bufmode;
X
Xint stfopen(name, mode)
Xchar *name, *mode;
X{
X register int handl;
X
X switch(*mode)
X {
X case 'r':
X if((handl = Fopen(name, 0)) <= 0)
X return -1;
X bufmode = O_RDONLY;
X break;
X
X case 'w':
X if((handl = Fcreate(name, 0)) <= 0)
X {
X if((handl = Fopen(name, 1)) <= 0)
X return -1;
X }
X bufmode = O_WRONLY;
X break;
X
X case 'a':
X if((handl = Fopen(name, 2)) <= 0)
X return -1;
X Fseek(0L, handl, 2);
X bufmode = O_APONLY;
X break;
X
X default:
X return -1;
X }
X
X#ifdef DYNABUF
X MBUFSIZ = BBUFSIZ - 1L;
X#endif /* DYNABUF */
X
X bptr = bufr;
X flcount = (-1L);
X return handl;
X}
X
Xstfclose(handl)
Xint handl;
X{
X if(bufmode == O_RDONLY)
X return Fclose(handl);
X if(stflush(handl))
X {
X Fclose(handl);
X return -1;
X }
X return Fclose(handl);
X}
X
Xstputc(c, handl)
Xunsigned int c;
Xint handl;
X{
X if(flcount >= MBUFSIZ)
X {
X if(Fwrite(handl, (long)BBUFSIZ, bufr) != (long)BBUFSIZ)
X return -1;
X flcount = (-1L);
X bptr = bufr;
X }
X flcount++;
X *bptr++ = c;
X return 0;
X}
X
Xstgetc(handl)
Xint handl;
X{
X if(flcount <= 0)
X {
X if((flcount = Fread(handl, (long)BBUFSIZ, bufr)) == 0)
X return EOF;
X bptr = bufr;
X }
X flcount--;
X return(*bptr++);
X}
X
Xstflush(handl)
Xint handl;
X{
X if(flcount < 0)
X return 0;
X
X if(Fwrite(handl, (long)(flcount+1L), bufr) != (flcount+1L))
X return -1;
X flcount = (-1L);
X bptr = bufr;
X return 0;
X}
X
Xstfseek(handl, disp, mode)
Xint handl;
Xlong disp;
Xint mode;
X{
X if(bufmode != O_RDONLY)
X if(stflush(handl))
X return -1;
X Fseek(disp, handl, mode);
X flcount = (-1L);
X bptr = bufr;
X return 0;
X}
X
X
X/* -eof- */
SHAR_EOF
chmod 0600 FILEIO.C || echo "restore of FILEIO.C fails"
echo "x - extracting HI5025.S (Text)"
sed 's/^X//' << 'SHAR_EOF' > HI5025.S &&
X/
X/ Make hi rez screen bios handle 50 lines of 8x8 characters
X/
X/ Adapted to Mark Williams C use from origional PD asm posting
X/ from atari corp.
X/
X/ Jwahar Bammi
X/ usenet: cwruecmp!bammi@decvax.UUCP
X/ csnet: bammi@cwru.edu
X/ arpa: bammi@cwru.edu
X/ CompuServe: 71515,155
X/
X/
X .shri
X
X .globl hi50_
X
Xhi50_: / switch to 50 line mode
X link a6,$0 / routine preamble
X
X .word 0xA000 / get the important pointers (line A init)
X
X movea.l 4(a1),a1 / a1 -> 8x8 font header
X
X move.l 72(a1),-0x0A(a0) / v_off_ad <- 8x8 offset table addr
X move.l 76(a1),-0x16(a0) / v_fnt_ad <- 8x8 font data addr
X
X move $8, -0x2E(a0) / v_cel_ht <- 8 8x8 cell height
X move $49, -0x2A(a0) / v_cel_my <- 49 maximum cell "Y"
X move $640,-0x28(a0) / v_cel_wr <- 640 offset to cell Y+1
X
X unlk a6 / routine postable
X rts / and return
X
X
X/
X/ Make hi rez screen bios handle 25 lines of 8x16 characters
X/
X
X .globl hi25_
X
Xhi25_: / Switch to 25 lines display
X link a6,$0 / routine preamble
X
X .word 0xA000 / get the important pointers
X
X movea.l 8(a1),a1 / a1 -> 8x16 font header
X
X move.l 72(a1),-0x0A(a0) / v_off_ad <- 8x16 offset table addr
X move.l 76(a1),-0x16(a0) / v_fnt_ad <- 8x16 font data addr
X
X move $16, -0x2E(a0) / v_cel_ht <- 16 8x16 cell height
X move $24, -0x2A(a0) / v_cel_my <- 24 maximum cell "Y"
X move $1280,-0x28(a0) / v_cel_wr <- 1280 vertical byte offset
X
X unlk a6 / routine postamble
X rts / bye
SHAR_EOF
chmod 0600 HI5025.S || echo "restore of HI5025.S fails"
echo "x - extracting LNK (Text)"
sed 's/^X//' << 'SHAR_EOF' > LNK &&
Xc:\lib\gemstart.o common.o rz.o sz.o transfer.o util.o main.o tyme.o
Xzm.o fileio.o phone.o c:\lib\osbind.o c:\lib\gemlib c:\lib\libf
SHAR_EOF
chmod 0600 LNK || echo "restore of LNK fails"
echo "x - extracting MAIN.C (Text)"
sed 's/^X//' << 'SHAR_EOF' > MAIN.C &&
X/*
X * Main Module
X *
X * Jwahar Bammi
X * usenet: mandrill!bammi@{decvax,sun}.UUCP
X * csnet: bammi@mandrill.ces.CWRU.edu
X * arpa: bammi@mandrill.ces.CWRU.edu
X * CompuServe: 71515,155
X */
X
X#include "config.h"
X
X#include "zmdm.h"
X#include "common.h"
X
X#ifndef Vsync /* Atari forgot these in osbind.h */
X#define Vsync() xbios(37)
X#endif
X
X#define esc 27
X#define cr 0x0d
X#define mvto(r,c) EscSeq('Y');Bconout(2,r+040);Bconout(2,c+040)
X
X
X /* Globals belonging to this module only */
X
Xint rs232 = 1, /* Ports */
X console = 2;
Xint speed, /* rs232 setup parameters */
X#ifdef FLOW_CTRL
X flowctl = 1,
X#else
X flowctl = 0,
X#endif
X ucr = -1,
X rsr = -1,
X tsr = -1,
X scr = -1;
X
X/*
X * setRs232() - set rs232 port configuration
X */
X#ifndef REMOTE
Xvoid setRs232 ()
X{
X char ch;
X long conin;
X
X Bconws("Baud rate: ");
X EscSeq('p');
X Bconws("0=19200 1=9600, 2=4800, 3=2400, 4=1200, 5=300\r\n");
X EscSeq('q');
X Bconout(2, '\t');
X EscSeq('p');
X Bconws("What speed==>");
X EscSeq('q');
X
X conin = Bconin(console); /* get speed */
X if ((conin & 0x00FF0000L) == 0x00610000L)
X {
X his_screen();
X ResetIoBuf();
X finish();
X }
X ch = (char) (conin & 0x007f);
X Bconout(2, ' ');
X switch (ch)
X {
X case '0': /* 19200 */
X speed = 0;
X Bconws("19200");
X Baudrate = 19200;
X break;
X
X case '1':
X speed = 1; /* 9600 */
X Bconws("9600");
X Baudrate = 9600;
X break;
X
X case '2':
X speed = 2; /* 4800 */
X Bconws("4800");
X Baudrate = 4800;
X break;
X
X case '3':
X speed = 4; /* 2400 */
X Bconws("2400");
X Baudrate = 2400;
X break;
X
X case '4':
X speed = 7; /* 1200 */
X Bconws("1200");
X Baudrate = 1200;
X break;
X
X case '5':
X speed = 9; /* 300 */
X Bconws("300");
X Baudrate = 300;
X break;
X
X default:
X speed = getbaud();
X Bconws(BAUD_STRING(speed));
X Baudrate = BAUD_RATE(speed);
X }
X Bconws(" Baud\r\n");
X
X /* Set new Baud rate */
X
X/* Txoff(); */
X Rsconf(speed, flowctl, ucr, rsr, tsr, scr);
X Vsync(); Vsync();
X/* Txon(); */
X
X
X}
X#else
Xvoid setRs232 ()
X{
X char ch;
X long conin;
X
X Bauxws("Baud rate: ");
X Bauxws("0=19200 1=9600, 2=4800, 3=2400, 4=1200, 5=300\r\n");
X Bconout(1, '\t');
X Bauxws("What speed==>");
X
X conin = Bconin(1); /* get speed */
X if (((int)(conin & 0x007f) & CTRL('U')) == CTRL('U'))
X {
X his_screen();
X ResetIoBuf();
X finish();
X }
X ch = (char) (conin & 0x007f);
X Bconout(1, ' ');
X switch (ch)
X {
X case '0': /* 19200 */
X speed = 0;
X Bauxws("19200");
X Baudrate = 19200;
X break;
X
X case '1':
X speed = 1; /* 9600 */
X Bauxws("9600");
X Baudrate = 9600;
X break;
X
X case '2':
X speed = 2; /* 4800 */
X Bauxws("4800");
X Baudrate = 4800;
X break;
X
X case '3':
X speed = 4; /* 2400 */
X Bauxws("2400");
X Baudrate = 2400;
X break;
X
X case '4':
X speed = 7; /* 1200 */
X Bauxws("1200");
X Baudrate = 1200;
X break;
X
X case '5':
X speed = 9; /* 300 */
X Bauxws("300");
X Baudrate = 300;
X break;
X
X default:
X speed = getbaud();
X Bauxws(BAUD_STRING(speed));
X Baudrate = BAUD_RATE(speed);
X }
X Bauxws(" Baud\r\n");
X
X /* Set new Baud rate */
X
X/* Txoff(); */
X Rsconf(speed, flowctl, ucr, rsr, tsr, scr);
X Vsync(); Vsync();
X/* Txon(); */
X
X
X}
X#endif /* REMOTE */
X
X/*
X * help() - display help info and menu
X */
X#ifndef REMOTE
Xvoid help ()
X{
X register long conin;
X register int x;
X extern char *r_filename();
X
X my_screen(); /* Switch to my screen memory */
X EscSeq('v'); /* wrap at end of line */
X EscSeq('E'); /* clear screen */
X
X mvto(2,25);
X EscSeq('p');
X Bconws("ZMDM Version ");
X Bconws(ZMDMVERSION);
X EscSeq('q');
X EscSeq('p');
X x = strlen(COMPILER);
X x = (80 - x)/2;
X mvto(3,x);
X Bconws(COMPILER);
X EscSeq('q');
X mvto(5,25);
X Bconws("ST Enthusiasts @ ces.CWRU.edu\r\n\n");
X
X /* Put up menu */
X Bconws("\r\n\t");
X EscSeq('p'); /* reverse video */
X Bconws("Undo");
X EscSeq('q'); /* quit reverse video */
X Bconws(" to exit.\r\n");
X
X Bconws("\t");
X EscSeq('p'); /* reverse video */
X Bconws("Help");
X EscSeq('q'); /* quit reverse video */
X Bconws(" for this message.\r\n");
X
X Bconws("\t");
X EscSeq('p'); /* reverse video */
X Bconws("Escape");
X EscSeq('q'); /* quit reverse video */
X Bconws(" to send a break.\r\n");
X
X Bconws("\t");
X EscSeq('p'); /* reverse video */
X Bconws("T or t");
X EscSeq('q'); /* quit reverse video */
X Bconws(" to do file transfers and local functions.\r\n");
X
X#ifdef PHONES
X Bconws("\t");
X EscSeq('p'); /* reverse video */
X Bconws("P or p");
X EscSeq('q'); /* quit reverse video */
X Bconws(" for Phone services.\r\n");
X#endif
X
X if(rez == 2)
X {
X Bconws("\t");
X EscSeq('p'); /* reverse video */
X Bconws("H or h");
X EscSeq('q'); /* quit reverse video */
X Bconws(" for Hi Rez Toggle (25/50 Lines).\r\n");
X }
X
X Bconws("\t");
X EscSeq('p'); /* reverse video */
X Bconws("I or i");
X EscSeq('q'); /* quit reverse video */
X Bconws(" to Invert screen colors.\r\n");
X
X Bconws("\t");
X EscSeq('p'); /* reverse video */
X Bconws("Return");
X EscSeq('q'); /* quit reverse video */
X Bconws(" to do nothing.\r\n");
X
X Bconws("\t");
X EscSeq('p'); /* reverse video */
X Bconws("B or b");
X EscSeq('q'); /* quit reverse video */
X Bconws(" to set baud rate. Currently is ");
X EscSeq('p');
X Bconws(BAUD_STRING(speed));
X Bconws(" Baud.\r\n\r\n");
X EscSeq('q');
X
X /* get response */
X conin = Bconin(console);
X
X if ((conin & 0x00FF0000L) == 0x00610000L)
X {
X /* He hit <UNDO> */
X his_screen();
X ResetIoBuf();
X finish();
X }
X
X switch((int)(conin & 0x007f))
X {
X case 'B':
X case 'b':
X /* Set baud rate */
X setRs232();
X break;
X
X case 'T':
X case 't':
X EscSeq('E'); /* clear screen */
X
X /* Set no flow Control */
X#ifdef FLOW_CTRL
X Rsconf(-1,0,-1,-1,-1,-1);
X Vsync(); Vsync();
X
X#endif
X /* Go do transfers */
X transfer();
X
X#ifdef FLOW_CTRL
X /* Flow Control On */
X/* Txoff(); */
X Rsconf(-1,1,-1,-1,-1,-1);
X Vsync(); Vsync();
X/* Txon(); */
X#endif
X his_screen();
X return;
X
X case '\033':
X /* Send a break */
X sendbrk();
X his_screen(); /* Don't wait for the key hit */
X
X return;
X
X case 'i':
X case 'I':
X /* Invert screen colors */
X his_screen();
X if(scolor == 0)
X {
X EscSeq('b'); /* Foreground color 0 */
X Bconout(2, 0);
X EscSeq('c'); /* Background color 1 */
X Bconout(2, 1);
X scolor = 1;
X }
X else
X {
X EscSeq('b'); /* Foreground color 1 */
X Bconout(2, 1);
X EscSeq('c'); /* Background color 0 */
X Bconout(2, 0);
X scolor = 0;
X }
X EscSeq('E'); /* Clear the screen */
X return;
X
X#ifdef PHONES
X case 'p':
X case 'P':
X /* Phone Services */
X phone();
X return;
X#endif
X case 'h':
X case 'H':
X /* Hi rez 25/50 toggle */
X if(rez == 2)
X {
X if(hlines == 25)
X {
X hlines = 50;
X hi50();
X }
X else
X {
X hlines = 25;
X hi25();
X }
X his_screen();
X EscSeq('E'); /* clear screen */
X return;
X }
X /* else fall Through */
X
X default:
X Bconws("No Change\r\n");
X }
X
X /* Wait for a key hit */
X hit_key();
X /* back to terminal screen */
X his_screen();
X}
X#else
Xvoid help ()
X{
X register long conin;
X extern char *r_filename();
X
X my_screen(); /* Switch to my screen memory */
X
X Bauxws("\r\n\n");
X Bauxws(" RZMDM Version ");
X Bauxws(ZMDMVERSION);
X Bauxws("\r\n ");
X Bauxws(COMPILER);
X Bauxws("\r\n\n ST Enthusiasts @ ces.CWRU.edu\r\n\n");
X
X /* Put up menu */
X Bauxws("\r\n\t");
X Bauxws("CTRL-U");
X Bauxws(" to exit.\r\n");
X
X Bauxws("\t");
X Bauxws("CTRL-Z");
X Bauxws(" for this message.\r\n");
X
X Bauxws("\t");
X Bauxws("Escape");
X Bauxws(" to send a break.\r\n");
X
X Bauxws("\t");
X Bauxws("T or t");
X Bauxws(" to do file transfers and local functions.\r\n");
X
X Bauxws("\t");
X Bauxws("Return");
X Bauxws(" to do nothing.\r\n");
X
X Bauxws("\t");
X Bauxws("B or b");
X Bauxws(" to set baud rate. Curently is ");
X Bauxws(BAUD_STRING(speed));
X Bauxws(" Baud.\r\n\r\n");
X
X /* get response */
X conin = Bconin(1);
X
X if (((int)(conin & 0x007f) & CTRL('U')) == CTRL('U'))
X {
X /* He hit <UNDO> */
X his_screen();
X ResetIoBuf();
X finish();
X }
X
X switch((int)(conin & 0x007f))
SHAR_EOF
echo "End of part 2"
echo "File MAIN.C is continued in part 3"
echo "3" > s2_seq_.tmp
exit 0