home *** CD-ROM | disk | FTP | other *** search
- From: argv@zipcode.com (Dan Heller)
- Newsgroups: comp.sources.misc
- Subject: v18i070: mush - Mail User's Shell, Part13/22
- Message-ID: <1991Apr22.000428.18915@sparky.IMD.Sterling.COM>
- Date: 22 Apr 91 00:04:28 GMT
- Approved: kent@sparky.imd.sterling.com
- X-Checksum-Snefru: 07578e65 281d7a92 a45fac4b f4b5fd2d
-
- Submitted-by: Dan Heller <argv@zipcode.com>
- Posting-number: Volume 18, Issue 70
- Archive-name: mush/part13
- Supersedes: mush: Volume 12, Issue 28-47
-
- #!/bin/sh
- # do not concatenate these parts, unpack them in order with /bin/sh
- # file makefile.sun continued
- #
- if test ! -r _shar_seq_.tmp; then
- echo 'Please unpack part 1 first!'
- exit 1
- fi
- (read Scheck
- if test "$Scheck" != 13; then
- echo Please unpack part "$Scheck" next!
- exit 1
- else
- exit 0
- fi
- ) < _shar_seq_.tmp || exit 1
- if test ! -f _shar_wnt_.tmp; then
- echo 'x - still skipping makefile.sun'
- else
- echo 'x - continuing file makefile.sun'
- sed 's/^X//' << 'SHAR_EOF' >> 'makefile.sun' &&
- #
- # Note that the default SunOS version for mush is 4.1. If you have an
- # older version of SunOS, you must explicitly define SUN_3_5 or SUN_4_0.
- #
- HDRS= mush.h config.h-dist strings.h bindings.h options.h version.h glob.h
- X
- SRCS= addrs.c bind.c commands.c curs_io.c curses.c dates.c doproc.c \
- X execute.c expr.c file.c fkeys.c folders.c glob.c hdrs.c init.c lock.c \
- X loop.c macros.c mail.c main.c malloc.c misc.c misc_frame.c msgs.c \
- X options.c panels.c pick.c print.c hdr_sw.c setopts.c signals.c sort.c \
- X strings.c tool.c tooledit.c viewopts.c command2.c
- X
- OBJS= addrs.o bind.o commands.o curs_io.o curses.o dates.o doproc.o \
- X execute.o expr.o file.o fkeys.o folders.o glob.o hdrs.o init.o lock.o \
- X loop.o macros.o mail.o main.o malloc.o misc.o misc_frame.o msgs.o \
- X options.o panels.o pick.o print.o hdr_sw.o setopts.o signals.o sort.o \
- X strings.o tool.o tooledit.o viewopts.o command2.o
- X
- IMAGES= mail.icon.1 mail.icon.2
- X
- HELP_FILES= README README-7.0 README-7.1 README-7.2.0 README-7.2.2 \
- X mush.1 cmd_help tool_help Mushrc Mailrc Gnurc \
- X advanced.mushrc sample.mushrc digestify
- X
- MAKES= makefile.sun makefile.bsd makefile.sys.v makefile.xenix makefile.hpux
- X
- # If your SunOS version is 3.5, add -DSUN_3_5 to CFLAGS.
- # If your SunOS version is 4.0, add -DSUN_4_0 to CFLAGS.
- # If you are not using SUNTOOL, use makefile.bsd and add one of
- # -DSUN_3_5, -DSUN_4_0, or -DSUN_4_1 to CFLAGS there.
- CFLAGS= -O -DSUNTOOL -DCURSES -DBSD
- LDFLAGS=
- LIBES= -lcurses -ltermlib -lsuntool -lsunwindow -lpixrect
- OTHERLIBS=
- # Use some variant of this one if you #define MMDF in config.h
- #OTHERLIBS=/usr/src/mmdf/lib/libmmdf.a
- LINTFLAGS= -bxah -Dlint
- X
- mush: $(OBJS)
- X @echo loading...
- X @cc $(LDFLAGS) $(OBJS) $(LIBES) $(OTHERLIBS) -o mush
- X
- $(OBJS): config.h mush.h
- loop.o: version.h
- X
- lint:
- X lint $(LINTFLAGS) $(SRCS) -DSUNTOOL -DCURSES -DBSD
- X
- clean:
- X rm -f *.o core mush
- X
- BINDIR= /usr/local/bin
- LIBDIR= /usr/local/lib
- MRCDIR= /usr/lib
- MANDIR= /usr/local/man/man1
- MANEXT= 1
- X
- install: mush
- X mv mush $(BINDIR)
- X strip $(BINDIR)/mush
- X chmod 0755 $(BINDIR)/mush
- X rm -f $(BINDIR)/mushtool
- X ln -s $(BINDIR)/mush $(BINDIR)/mushtool
- X cp mush.1 $(MANDIR)/mush.$(MANEXT)
- X chmod 0644 $(MANDIR)/mush.$(MANEXT)
- X cp tool_help $(LIBDIR)
- X chmod 0644 $(LIBDIR)/tool_help
- X cp cmd_help $(LIBDIR)
- X chmod 0644 $(LIBDIR)/cmd_help
- X cp Mushrc $(MRCDIR)/Mushrc
- X chmod 0644 $(MRCDIR)/Mushrc
- SHAR_EOF
- echo 'File makefile.sun is complete' &&
- chmod 0644 makefile.sun ||
- echo 'restore of makefile.sun failed'
- Wc_c="`wc -c < 'makefile.sun'`"
- test 2454 -eq "$Wc_c" ||
- echo 'makefile.sun: original size 2454, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= makefile.sys.v ==============
- if test -f 'makefile.sys.v' -a X"$1" != X"-c"; then
- echo 'x - skipping makefile.sys.v (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting makefile.sys.v (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'makefile.sys.v' &&
- # Mush makefile for system V. Note: SIGRET should return void for normal
- # sys-v, but Att PC users should *not* have it defined. See the README!!
- #
- HDRS1= mush.h config.h
- HDRS2= strings.h options.h
- HDRS3= bindings.h glob.h
- HDRS4= version.h
- SRCS1= commands.c dates.c execute.c expr.c folders.c \
- X hdrs.c init.c loop.c mail.c main.c misc.c msgs.c pick.c \
- X print.c setopts.c signals.c sort.c viewopts.c options.c lock.c
- SRCS2= bind.c curs_io.c curses.c file.c strings.c macros.c \
- X addrs.c malloc.c glob.c command2.c
- X
- OBJS1= commands.o dates.o execute.o expr.o folders.o \
- X hdrs.o init.o loop.o mail.o main.o misc.o msgs.o pick.o \
- X print.o setopts.o signals.o sort.o viewopts.o options.o lock.o
- OBJS2= bind.o curs_io.o curses.o file.o strings.o macros.o \
- X addrs.o malloc.o glob.o command2.o
- X
- HELP= README README-7.0 README-7.1 README-7.2.0 README-7.2.2 mush.1 \
- X cmd_help Mushrc Mailrc Gnurc sample.mushrc advanced.mushrc digestify
- X
- # Sun OS systems who wish to compile with sys-v options:
- # CC= /usr/5bin/cc
- # CFLAGS= -O -DSYSV -DCURSES -DUSG -DDIRECTORY
- # LIBS= -L/usr/5lib -lcurses
- X
- # IRIX 3.2 systems (SGI Iris workstations) should add -DDIRECTORY to CFLAGS
- # SCO UNIX 3.2 should add -DDIRECTORY -DSELECT and should avoid library -lx
- X
- CFLAGS= -O -DSYSV -DUSG -DCURSES -DREGCMP -DSIGRET=void
- LDFLAGS=
- LIBS= -lcurses -lPW
- OTHERLIBS=
- # Use some variant of this one if you #define MMDF in config.h
- #OTHERLIBS=/usr/src/mmdf/lib/libmmdf.a
- PROG= mush
- X
- $(PROG): $(OBJS1) $(OBJS2)
- X @echo loading...
- X @$(CC) $(LDFLAGS) $(OBJS1) $(OBJS2) -o $(PROG) $(LIBS) $(OTHERLIBS)
- X
- $(OBJS1): $(HDRS1) $(HDRS2)
- $(OBJS2): $(HDRS1) $(HDRS2) $(HDRS3)
- loop.o: version.h
- X
- BINDIR= /usr/local/bin
- LIBDIR= /usr/local/lib
- MRCDIR= /usr/lib
- MANDIR= /usr/local/man/man1
- MANEXT= 1
- X
- install: mush
- X cp mush $(BINDIR)
- X strip $(BINDIR)/mush
- X chmod 0755 $(BINDIR)/mush
- X cp mush.1 $(MANDIR)/mush.$(MANEXT)
- X chmod 0644 $(MANDIR)/mush.$(MANEXT)
- X cp cmd_help $(LIBDIR)
- X chmod 0644 $(LIBDIR)/cmd_help
- X cp Mushrc $(MRCDIR)/Mushrc
- X chmod 0644 $(MRCDIR)/Mushrc
- SHAR_EOF
- chmod 0644 makefile.sys.v ||
- echo 'restore of makefile.sys.v failed'
- Wc_c="`wc -c < 'makefile.sys.v'`"
- test 2023 -eq "$Wc_c" ||
- echo 'makefile.sys.v: original size 2023, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= makefile.xenix ==============
- if test -f 'makefile.xenix' -a X"$1" != X"-c"; then
- echo 'x - skipping makefile.xenix (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting makefile.xenix (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'makefile.xenix' &&
- #
- # makefile for Xenix machines. See "MODEL" below for your xenix type.
- # some .c files may require the -LARGE compiler flag. Examples below.
- # This makefile assumes an 80386 machine. If you have an 80286, see
- # notes below. This makefile was built for SCO/microsoft xenix --if you
- # are running some other kind of xenix, you might need to change the
- # CFLAGS and LDFLAGS options.
- #
- HDRS= mush.h config.h-dist strings.h bindings.h options.h version.h glob.h
- SRCS1= main.c init.c misc.c execute.c
- SRCS2= signals.c msgs.c pick.c viewopts.c
- SRCS3= sort.c expr.c folders.c dates.c
- SRCS4= loop.c bind.c options.c
- SRCS5= commands.c commands2.c setopts.c hdrs.c
- SRCS6= mail.c print.c
- SRCS7= curses.c curs_io.c
- SRCS8= file.c strings.c malloc.c
- SRCS9= lock.c macros.c addrs.c glob.c
- OBJS= main.o init.o misc.o mail.o hdrs.o execute.o commands.o print.o file.o \
- X signals.o setopts.o msgs.o pick.o sort.o expr.o strings.o \
- X folders.o dates.o loop.o viewopts.o bind.o curses.o curs_io.o \
- X lock.o macros.o options.o addrs.o malloc.o glob.o command2.o
- HELP_FILES= README README-7.0 README-7.1 README-7.2.0 README-7.2.2 mush.1 \
- X cmd_help Mushrc Mailrc Gnurc sample.mushrc advanced.mushrc digestify
- X
- # Memory model. Use -M3e for 80386 machines.
- # Use -M2le -Mt32 -LARGE for 80286 machines.
- MODEL= -M3e
- X
- #
- # 80286 xenix may use this LDFLAGS define:
- #LDFLAGS= -X -lx -M2le -Mt32 -F 8000 -SEG 256 -LARGE
- LDFLAGS= -X -lx -M3
- X
- CFLAGS= $(MODEL) -O -DSYSV -DCURSES -DREGCMP -DUSG
- LIBES= -lcurses -ltermlib
- OTHERLIBS=
- # Use some variant of this one if you #define MMDF in config.h
- #OTHERLIBS=/usr/src/mmdf/lib/libmmdf.a
- X
- mush: $(OBJS)
- X @echo loading...
- X @cc $(LDFLAGS) $(OBJS) $(LIBES) $(OTHERLIBS) -o mush
- X
- $(OBJS): config.h mush.h
- loop.o: version.h
- X
- # For 80286 machines, use these two lines...
- # misc.o: misc.c
- # cc $(CFLAGS) -LARGE -c misc.c
- X
- bind.o: bind.c
- X cc $(CFLAGS) -LARGE -c bind.c
- X
- clean:
- X rm -f *.o core mush
- X
- BINDIR= /usr/local/bin
- LIBDIR= /usr/local/lib
- MRCDIR= /usr/lib
- MANDIR= /usr/local/man/man1
- MANEXT= 1
- X
- install: mush
- X cp mush $(BINDIR)
- X strip $(BINDIR)/mush
- X chmod 0755 $(BINDIR)/mush
- X cp mush.1 $(MANDIR)/mush.$(MANEXT)
- X chmod 0644 $(MANDIR)/mush.$(MANEXT)
- X cp cmd_help $(LIBDIR)
- X chmod 0644 $(LIBDIR)/cmd_help
- X cp Mushrc $(MRCDIR)/Mushrc
- X chmod 0644 $(MRCDIR)/Mushrc
- SHAR_EOF
- chmod 0644 makefile.xenix ||
- echo 'restore of makefile.xenix failed'
- Wc_c="`wc -c < 'makefile.xenix'`"
- test 2293 -eq "$Wc_c" ||
- echo 'makefile.xenix: original size 2293, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= malloc.c ==============
- if test -f 'malloc.c' -a X"$1" != X"-c"; then
- echo 'x - skipping malloc.c (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting malloc.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'malloc.c' &&
- /*
- X * This is a slightly modified version of the malloc.c distributed with
- X * Larry Wall's perl 2.0 sources. RCS and sccs information has been
- X * retained, but modified so that it will not actually affect checkin
- X * or checkout of this file if revision control is used for Mush.
- X *
- X * Other changes include:
- X * Removal of the ASSERT macro and other code related to the
- X * preprocessor definition "debug"
- X *
- X * Replaced #include "perl.h" with #include "mush.h" (guess why)
- X *
- X * Warning messages are now printed with the mush Debug macro,
- X * that is, they are normally suppressed
- X *
- X * Added a calloc() function, using mush's bzero()
- X *
- X * Also, the mush xfree() and free_vec() functions have been moved here.
- X */
- X
- #include "mush.h"
- X
- /*
- X * Compile this portion only if configured for INTERNAL_MALLOC
- X */
- #ifdef INTERNAL_MALLOC
- #ifdef SYSV
- #include <memory.h>
- #define bcopy(src,dst,len) memcpy(dst,src,len)
- #endif /* SYSV */
- #define free xfree /* rename free for mush purposes */
- X
- /* Begin modified perl malloc.c */
- X
- /* Header: malloc.c,v 2.0 88/06/05 00:09:16 root Exp
- X *
- X * Log: malloc.c,v
- X * Revision 2.0 88/06/05 00:09:16 root
- X * Baseline version 2.0.
- X *
- X */
- X
- #ifndef lint
- static char sccsid[] = "malloc.c 4.3 (Berkeley) 9/16/83";
- #endif /* !lint */
- X
- #define RCHECK
- /*
- X * malloc.c (Caltech) 2/21/82
- X * Chris Kingsley, kingsley@cit-20.
- X *
- X * This is a very fast storage allocator. It allocates blocks of a small
- X * number of different sizes, and keeps free lists of each size. Blocks that
- X * don't exactly fit are passed up to the next larger size. In this
- X * implementation, the available sizes are 2^n-4 (or 2^n-12) bytes long.
- X * This is designed for use in a program that uses vast quantities of memory,
- X * but bombs when it runs out.
- X */
- X
- /* I don't much care whether these are defined in sys/types.h--LAW */
- X
- #undef u_char
- #define u_char unsigned char
- #undef u_int
- #define u_int unsigned int
- #undef u_short
- #define u_short unsigned short
- X
- /*
- X * The overhead on a block is at least 4 bytes. When free, this space
- X * contains a pointer to the next free block, and the bottom two bits must
- X * be zero. When in use, the first byte is set to MAGIC, and the second
- X * byte is the size index. The remaining bytes are for alignment.
- X * If range checking is enabled and the size of the block fits
- X * in two bytes, then the top two bytes hold the size of the requested block
- X * plus the range checking words, and the header word MINUS ONE.
- X */
- union overhead {
- X union overhead *ov_next; /* when free */
- X struct {
- X u_char ovu_magic; /* magic number */
- X u_char ovu_index; /* bucket # */
- #ifdef RCHECK
- X u_short ovu_size; /* actual block size */
- X u_int ovu_rmagic; /* range magic number */
- #endif /* RCHECK */
- X } ovu;
- #define ov_magic ovu.ovu_magic
- #define ov_index ovu.ovu_index
- #define ov_size ovu.ovu_size
- #define ov_rmagic ovu.ovu_rmagic
- };
- X
- #define MAGIC 0xff /* magic # on accounting info */
- #define OLDMAGIC 0x7f /* same after a free() */
- #define RMAGIC 0x55555555 /* magic # on range info */
- #ifdef RCHECK
- #define RSLOP sizeof (u_int)
- #else /* !RCHECK */
- #define RSLOP 0
- #endif /* RCHECK */
- X
- /*
- X * nextf[i] is the pointer to the next free block of size 2^(i+3). The
- X * smallest allocatable block is 8 bytes. The overhead information
- X * precedes the data area returned to the user.
- X */
- #define NBUCKETS 30
- static union overhead *nextf[NBUCKETS];
- extern char *sbrk();
- X
- #ifdef MSTATS
- /*
- X * nmalloc[i] is the difference between the number of mallocs and frees
- X * for a given block size.
- X */
- static u_int nmalloc[NBUCKETS];
- #endif /* MSTATS */
- X
- char *
- malloc(nbytes)
- X register unsigned nbytes;
- {
- X register union overhead *p;
- X register int bucket = 0;
- X register unsigned shiftr;
- X
- X if (nbytes == 0)
- X return NULL;
- X /*
- X * Convert amount of memory requested into
- X * closest block size stored in hash buckets
- X * which satisfies request. Account for
- X * space used per block for accounting.
- X */
- X nbytes += sizeof (union overhead) + RSLOP;
- X nbytes = (nbytes + 3) &~ 3;
- X shiftr = (nbytes - 1) >> 2;
- X /* apart from this loop, this is O(1) */
- X while (shiftr >>= 1)
- X bucket++;
- X /*
- X * If nothing in hash bucket right now,
- X * request more memory from the system.
- X */
- X if (nextf[bucket] == (union overhead *)0)
- X morecore(bucket);
- X if ((p = (union overhead *)nextf[bucket]) == (union overhead *)0)
- X return (NULL);
- X /* remove from linked list */
- X if (*((int*)p) > 0x10000000)
- X Debug("Corrupt malloc ptr 0x%x at 0x%x\n",*((int*)p),p);
- X nextf[bucket] = nextf[bucket]->ov_next;
- X p->ov_magic = MAGIC;
- X p->ov_index= bucket;
- #ifdef MSTATS
- X nmalloc[bucket]++;
- #endif /* MSTATS */
- #ifdef RCHECK
- X /*
- X * Record allocated size of block and
- X * bound space with magic numbers.
- X */
- X if (nbytes <= 0x10000)
- X p->ov_size = nbytes - 1;
- X p->ov_rmagic = RMAGIC;
- X *((u_int *)((caddr_t)p + nbytes - RSLOP)) = RMAGIC;
- #endif /* RCHECK */
- X return ((char *)(p + 1));
- }
- X
- /*
- X * Allocate more memory to the indicated bucket.
- X */
- static
- morecore(bucket)
- X register bucket;
- {
- X register union overhead *op;
- X register int rnu; /* 2^rnu bytes will be requested */
- X register int nblks; /* become nblks blocks of the desired size */
- X register int siz;
- X
- X if (nextf[bucket])
- X return;
- X /*
- X * Insure memory is allocated
- X * on a page boundary. Should
- X * make getpageize call?
- X */
- X op = (union overhead *)sbrk(0);
- X if ((long)op & 0x3ff)
- X sbrk(1024 - ((long)op & 0x3ff));
- X /* take 2k unless the block is bigger than that */
- X rnu = (bucket <= 8) ? 11 : bucket + 3;
- X nblks = 1 << (rnu - (bucket + 3)); /* how many blocks to get */
- X if (rnu < bucket)
- X rnu = bucket;
- X op = (union overhead *)sbrk(1 << rnu);
- X /* no more room! */
- X if ((long)op == -1)
- X return;
- X /*
- X * Round up to minimum allocation size boundary
- X * and deduct from block count to reflect.
- X */
- X if ((long)op & 7) {
- X op = (union overhead *)(((long)op + 8) &~ 7);
- X nblks--;
- X }
- X /*
- X * Add new memory allocated to that on
- X * free list for this hash bucket.
- X */
- X nextf[bucket] = op;
- X siz = 1 << (bucket + 3);
- X while (--nblks > 0) {
- X op->ov_next = (union overhead *)((caddr_t)op + siz);
- X op = (union overhead *)((caddr_t)op + siz);
- X }
- }
- X
- void
- free(cp)
- X char *cp;
- {
- X register int size;
- X register union overhead *op;
- X
- X if (cp == NULL || debug > 4)
- X return;
- X op = (union overhead *)((caddr_t)cp - sizeof (union overhead));
- X if (op->ov_magic != MAGIC) {
- X Debug("%s free() ignored\n",
- X op->ov_magic == OLDMAGIC ? "Duplicate" : "Bad");
- X return; /* sanity */
- X }
- X op->ov_magic = OLDMAGIC;
- #ifdef RCHECK
- X if (op->ov_rmagic != RMAGIC) {
- X Debug("Range check failed, free() ignored\n");
- X return;
- X }
- X if (op->ov_index <= 13 &&
- X *(u_int *)((caddr_t)op + op->ov_size + 1 - RSLOP) != RMAGIC) {
- X Debug("Range check failed, free() ignored\n");
- X return;
- X }
- #endif /* RCHECK */
- X if (op->ov_index >= NBUCKETS)
- X return;
- X size = op->ov_index;
- X op->ov_next = nextf[size];
- X nextf[size] = op;
- #ifdef MSTATS
- X nmalloc[size]--;
- #endif /* MSTATS */
- }
- X
- /*
- X * When a program attempts "storage compaction" as mentioned in the
- X * old malloc man page, it realloc's an already freed block. Usually
- X * this is the last block it freed; occasionally it might be farther
- X * back. We have to search all the free lists for the block in order
- X * to determine its bucket: 1st we make one pass thru the lists
- X * checking only the first block in each; if that fails we search
- X * ``reall_srchlen'' blocks in each list for a match (the variable
- X * is extern so the caller can modify it). If that fails we just copy
- X * however many bytes was given to realloc() and hope it's not huge.
- X */
- int reall_srchlen = 4; /* 4 should be plenty, -1 =>'s whole list */
- X
- char *
- realloc(cp, nbytes)
- X char *cp;
- X unsigned nbytes;
- {
- X register u_int onb;
- X union overhead *op;
- X char *res;
- X register int i;
- X int was_alloced = 0;
- X
- X if (cp == NULL)
- X return (malloc(nbytes));
- X op = (union overhead *)((caddr_t)cp - sizeof (union overhead));
- X if (op->ov_magic == MAGIC) {
- X was_alloced++;
- X i = op->ov_index;
- X } else {
- X /*
- X * Already free, doing "compaction".
- X *
- X * Search for the old block of memory on the
- X * free list. First, check the most common
- X * case (last element free'd), then (this failing)
- X * the last ``reall_srchlen'' items free'd.
- X * If all lookups fail, then assume the size of
- X * the memory block being realloc'd is the
- X * smallest possible.
- X */
- X if ((i = findbucket(op, 1)) < 0 &&
- X (i = findbucket(op, reall_srchlen)) < 0)
- X i = 0;
- X }
- X onb = (1 << (i + 3)) - sizeof (*op) - RSLOP;
- #ifdef RCHECK
- X /* There's something wrong with the "onb" size computation, above,
- X * when RCHECK is defined. If you see this comment and can figure
- X * out exactly how "onb" is being used here, let me know. Bart.
- X */
- X if (was_alloced) {
- X free(cp); /* Hack so there's some chance res == cp */
- X was_alloced = 0;
- X }
- #else /* RCHECK */
- X /* avoid the copy if same size block */
- X if (was_alloced &&
- X nbytes <= onb && nbytes > (onb >> 1) - sizeof(*op) - RSLOP)
- X return(cp);
- #endif /* RCHECK */
- X if ((res = malloc(nbytes)) == NULL)
- X return (NULL);
- X if (cp != res) /* common optimization */
- X bcopy(cp, res, (nbytes < onb) ? nbytes : onb);
- X if (was_alloced)
- X free(cp);
- X return (res);
- }
- X
- /*
- X * Search ``srchlen'' elements of each free list for a block whose
- X * header starts at ``freep''. If srchlen is -1 search the whole list.
- X * Return bucket number, or -1 if not found.
- X */
- static
- findbucket(freep, srchlen)
- X union overhead *freep;
- X int srchlen;
- {
- X register union overhead *p;
- X register int i, j;
- X
- X for (i = 0; i < NBUCKETS; i++) {
- X j = 0;
- X for (p = nextf[i]; p && j != srchlen; p = p->ov_next) {
- X if (p == freep)
- X return (i);
- X j++;
- X }
- X }
- X return (-1);
- }
- X
- #ifdef MSTATS
- /*
- X * mstats - print out statistics about malloc
- X *
- X * Prints two lines of numbers, one showing the length of the free list
- X * for each size category, the second showing the number of mallocs -
- X * frees for each size category.
- X */
- mstats(s)
- X char *s;
- {
- X register int i, j;
- X register union overhead *p;
- X int totfree = 0,
- X totused = 0;
- X
- X Debug("Memory allocation statistics %s\nfree:\t", s);
- X for (i = 0; i < NBUCKETS; i++) {
- X for (j = 0, p = nextf[i]; p; p = p->ov_next, j++)
- X ;
- X Debug(" %d", j);
- X totfree += j * (1 << (i + 3));
- X }
- X Debug("\nused:\t");
- X for (i = 0; i < NBUCKETS; i++) {
- X Debug( " %d", nmalloc[i]);
- X totused += nmalloc[i] * (1 << (i + 3));
- X }
- X Debug("\n\tTotal in use: %d, total free: %d\n",
- X totused, totfree);
- }
- #endif /* MSTATS */
- X
- /* End of modified perl malloc.c */
- X
- char *
- calloc(nitems, itemsz)
- u_int nitems, itemsz;
- {
- X char *cp;
- X
- X cp = malloc(nitems * itemsz);
- X bzero(cp, nitems * itemsz);
- X return cp;
- }
- X
- /* These are needed for curses and other external linkage */
- X
- #undef free
- X
- char *
- cfree(p, n, s)
- char *p;
- u_int n, s;
- {
- X xfree(p);
- X return NULL;
- }
- X
- char *
- free(p)
- char *p;
- {
- X xfree(p);
- X return NULL;
- }
- X
- #else /* INTERNAL_MALLOC */
- X
- char *stackbottom; /* set first thing in main() */
- X
- void
- xfree(cp)
- char *cp;
- {
- X extern char end[];
- X
- X if (cp && cp >= end && cp < stackbottom && cp < (char *) &cp && debug < 5)
- X free(cp);
- }
- X
- #endif /* INTERNAL_MALLOC */
- X
- void
- free_elems(argv)
- char **argv;
- {
- X register int n;
- X
- X if (!argv)
- X return;
- X for (n = 0; argv[n]; n++)
- X xfree(argv[n]);
- }
- X
- void
- free_vec(argv)
- char **argv;
- {
- X free_elems(argv);
- X xfree((char *)argv);
- }
- SHAR_EOF
- chmod 0600 malloc.c ||
- echo 'restore of malloc.c failed'
- Wc_c="`wc -c < 'malloc.c'`"
- test 11289 -eq "$Wc_c" ||
- echo 'malloc.c: original size 11289, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= misc.c ==============
- if test -f 'misc.c' -a X"$1" != X"-c"; then
- echo 'x - skipping misc.c (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting misc.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'misc.c' &&
- /* @(#)misc.c (c) copyright 10/18/86 (Dan Heller) */
- X
- #include "mush.h"
- X
- /* check to see if a string describes a message that is within the range of
- X * all messages; if invalid, return 0 and print error. else return msg number
- X */
- chk_msg(s)
- register char *s;
- {
- X register int n;
- X
- X if ((n = atoi(s)) > 0 && n <= msg_cnt)
- X return n;
- X else if (*s == '^' && msg_cnt)
- X return 1;
- X else if (*s == '$' && msg_cnt)
- X return msg_cnt;
- X else if (*s == '.' && msg_cnt)
- X return current_msg+1;
- X print("Invalid message number: %s\n", s);
- X return 0;
- }
- X
- /*
- X * loop thru all msgs starting with current_msg and find next undeleted and
- X * unsaved message. If the variable "wrap" is set, wrap to the beginning of
- X * the message list if we hit the end. otherwise, stop at the end of the list.
- X */
- next_msg()
- {
- X register int n = current_msg;
- X register int wrap = !!do_set(set_options, "wrap") ||
- X istool && !do_set(set_options, "show_deleted");
- X
- X if (!msg_cnt)
- X return current_msg = 0;
- X for (n++; n != current_msg; n++)
- X if (n == msg_cnt) /* hit the end, start back at the beginning */
- X if (!wrap)
- X return current_msg;
- X else
- X n = -1; /* increments to 0 in loop */
- X else if (isoff(msg[n].m_flags, DELETE) &&
- X isoff(msg[n].m_flags, SAVED))
- X return current_msg = n;
- X return current_msg = 0;
- }
- X
- /* since print_help just prints help, always return help() */
- print_help(argc, argv)
- register char **argv;
- {
- X int about = (argv && *argv && **argv == 'a');
- X
- X if (!argc || !*++argv)
- X return help(0, about? "about": "general", cmd_help);
- X if (argv[0][0] == '-')
- X return help(0, about? "about": "help", cmd_help);
- X return help(0, *argv, cmd_help);
- }
- X
- /* since this function does not affect messages, return -1 */
- /*ARGSUSED*/
- help(unused, str, file)
- char *str, *file;
- {
- X register char *p, **text = (char **)str;
- X char buf[BUFSIZ], help_str[32];
- X FILE *fp;
- X
- X /* If no file given, take "str" arg as message to print */
- X if (!file || !*file) {
- #ifdef SUNTOOL
- #ifdef SUN_4_0 /* SunOS 4.0+ */
- X /* SunOS 3.5 doesn't have enough file descriptors */
- X turnon(glob_flags, NEW_FRAME);
- #endif /* SUN_4_0 */
- X strdup(more_prompt, "help");
- #endif /* SUNTOOL */
- X /* use the pager on the args to the function */
- X (void) do_pager(NULL, TRUE);
- X while (*text) {
- X (void) do_pager(*text++, FALSE);
- X if (do_pager("\n", FALSE) == EOF)
- X break;
- X }
- X (void) do_pager(NULL, FALSE);
- X return 0;
- X } else {
- X int d = 0;
- X if ((p = getpath(file, &d)) && d == 0) {
- X if (!(fp = fopen(p, "r"))) {
- X print("Cannot open help file \"%s\".\n", p);
- X return -1;
- X }
- X } else {
- X if (d < 0)
- X print("Cannot open help file \"%s\": %s\n", file, p);
- X else
- X print("Help file \"%s\" is a directory?!?\n", p);
- X return -1;
- X }
- X }
- X
- X /* look for %str% in helpfile */
- X (void) sprintf(help_str, "%%%s%%\n", str);
- X
- X while (p = fgets(buf, sizeof buf, fp))
- X if (*p == '%' && !strcmp(p, help_str))
- X break;
- X if (!p)
- X print("There is no help found for \"%s\".\n", (char *)str);
- X else {
- #ifdef SUNTOOL
- #ifdef SUN_4_0 /* SunOS 4.0+ */
- X /* SunOS 3.5 doesn't have enough file descriptors */
- X turnon(glob_flags, NEW_FRAME);
- #endif /* SUN_4_0 */
- X strdup(more_prompt, sprintf(buf, "%s help", (char *)str));
- #endif /* SUNTOOL */
- X (void) do_pager(NULL, TRUE);
- X while ((p = fgets(buf, sizeof buf, fp)) && strcmp(p, "%%\n"))
- X if (do_pager(buf, FALSE) == EOF)
- X break;
- X (void) do_pager(NULL, FALSE);
- X }
- X (void) fclose(fp);
- X
- X return 0;
- }
- X
- /* return -1 on error or number of arguments in argv that were parsed */
- get_msg_list(argv, list)
- register char **argv;
- char list[];
- {
- X register char *p2, *p, *end, ch;
- X char buf[BUFSIZ];
- X register int n;
- X
- X if (!msg_cnt) {
- X print("No messages.\n");
- X return -1;
- X }
- X if (!argv || !*argv) {
- X if (isoff(glob_flags, IS_PIPE))
- X set_msg_bit(list, current_msg);
- X return 0;
- X }
- X /* first, stuff argv's args into a single char array buffer */
- X (void) argv_to_string(buf, argv);
- X p = buf;
- X
- X Debug("get_msg_list: parsing: (%s): ", p);
- X /* find the end of the message list */
- X skipmsglist(0);
- X end = p;
- X while (*end && end != buf && !isspace(*end))
- X --end;
- X ch = *end, *end = '\0'; /* temporarily plug with nul */
- X p = buf; /* reset to the beginning */
- X /*
- X * if do_range returns NULL, an invalid message was specified
- X */
- X if (!(p2 = do_range(p, list))) {
- X *end = ch; /* just in case */
- X return -1;
- X }
- X /*
- X * if p2 == p (and p isn't $ or ^ or .), then no message list was
- X * specified. set the current message in such cases if we're not piping
- X */
- X if (p2 == p) {
- X if (*p == '$')
- X set_msg_bit(list, msg_cnt-1);
- X else if (*p == '^')
- X set_msg_bit(list, 0);
- X else if (*p == '.' || isoff(glob_flags, IS_PIPE))
- X set_msg_bit(list, current_msg);
- X }
- X for (n = 0; p2 > p && *argv; n++)
- X p2 -= (strlen(*argv++)+1);
- X Debug("parsed %d args\n", n);
- X *end = ch;
- X return n;
- }
- X
- /*
- X * execute a command from a string. f'rinstance: "pick -f foobar"
- X * The string is made into an argv and then run. Errors are printed
- X * if the command failed to make.
- X * NOTES:
- X * NEVER pass straight text: e.g. "pick -f foobar", ALWAYS strcpy(buf, "...")
- X * no history is expanded (ignore_bang).
- X */
- cmd_line(buf, list)
- char buf[], list[];
- {
- X register char **argv;
- X int argc, ret_val = -1;
- X u_long save_do_pipe = ison(glob_flags, DO_PIPE);
- X u_long save_is_pipe = ison(glob_flags, IS_PIPE);
- X char dummy_list[MAXMSGS_BITS];
- X
- X turnoff(glob_flags, DO_PIPE);
- X turnoff(glob_flags, IS_PIPE);
- X if (argv = make_command(buf, TRPL_NULL, &argc))
- X ret_val = do_command(argc, argv, list? list : dummy_list);
- X if (save_do_pipe)
- X turnon(glob_flags, DO_PIPE);
- X else
- X turnoff(glob_flags, DO_PIPE);
- X if (save_is_pipe)
- X turnon(glob_flags, IS_PIPE);
- X else
- X turnoff(glob_flags, IS_PIPE);
- X return ret_val;
- }
- X
- glob_test(s)
- char *s;
- {
- X print("%s: glob_flags =", s);
- X if (ison(glob_flags, DO_UPDATE))
- X print_more(" DO_UPDATE");
- X if (ison(glob_flags, REV_VIDEO))
- X print_more(" REV_VIDEO");
- X if (ison(glob_flags, CONT_PRNT))
- X print_more(" CONT_PRNT");
- X if (ison(glob_flags, DO_SHELL))
- X print_more(" DO_SHELL");
- X if (ison(glob_flags, DO_PIPE))
- X print_more(" DO_PIPE");
- X if (ison(glob_flags, IS_PIPE))
- X print_more(" IS_PIPE");
- X if (ison(glob_flags, IGN_SIGS))
- X print_more(" IGN_SIGS");
- X if (ison(glob_flags, IGN_BANG))
- X print_more(" IGN_BANG");
- X if (ison(glob_flags, ECHO_FLAG))
- X print_more(" ECHO_FLAG");
- X if (ison(glob_flags, IS_GETTING))
- X print_more(" IS_GETTING");
- X if (ison(glob_flags, PRE_CURSES))
- X print_more(" PRE_CURSES");
- X if (ison(glob_flags, READ_ONLY))
- X print_more(" READ_ONLY");
- X if (ison(glob_flags, REDIRECT))
- X print_more(" REDIRECT");
- X if (ison(glob_flags, WAS_INTR))
- X print_more(" WAS_INTR");
- X if (ison(glob_flags, WARNING))
- X print_more(" WARNING");
- X if (ison(glob_flags, NEW_MAIL))
- X print_more(" NEW_MAIL");
- X if (ison(glob_flags, CNTD_CMD))
- X print_more(" CNTD_CMD");
- X if (ison(glob_flags, IS_SENDING))
- X print_more(" IS_SENDING");
- X if (ison(glob_flags, MIL_TIME))
- X print_more(" MIL_TIME");
- X if (ison(glob_flags, DATE_RECV))
- X print_more(" DATE_RECV");
- X if (ison(glob_flags, IN_MACRO))
- X print_more(" IN_MACRO");
- X if (ison(glob_flags, LINE_MACRO))
- X print_more(" LINE_MACRO");
- X if (ison(glob_flags, QUOTE_MACRO))
- X print_more(" QUOTE_MACRO");
- X print_more("\n");
- }
- X
- /*
- X * Change the status flags for messages.
- X * flags +r add the replied-to flag to the current message.
- X * flags -S 4-7 remove the "saved" status on msgs 4-7
- X * flags P * preserves all messages.
- X * The + implies: add this flag to the current message's flag bits
- X * The - implies: delete this flag to the current message's flag bits
- X * No + or - implies that the msg's flag bits are set explicitly.
- X * Marks and priorities are preserved in the m_flags field despite
- X * what we're doing here. Thus, other actions taken by this function
- X * do not affect marks and priorities.
- X */
- msg_flags(c, v, list)
- register char **v, *list;
- {
- X register int i = 0, modify = 0, had_list = 0;
- X register u_long newflag = 0;
- X char sent[32], recv[32];
- X
- X while (v && *v && *++v)
- X for (c = 0; v && v[0] && v[0][c]; c++)
- X switch (lower(v[0][c])) {
- X case '?' : return help(0, "msg_flags", cmd_help);
- X case 'n' : turnon(newflag, UNREAD), turnoff(newflag, OLD);
- X when 'd' : turnon(newflag, DELETE);
- X when 'p' :
- X if (v[0][c] == 'P')
- X turnon(newflag, PRESERVE);
- X else
- X turnon(newflag, PRINTED);
- X when 's' : turnon(newflag, SAVED);
- X when 'u' : turnon(newflag, UNREAD); /* fall thru! */
- X case 'o' : turnon(newflag, OLD);
- X when 'r' :
- X if (v[0][c] == 'R')
- X turnoff(newflag, UNREAD), turnon(newflag, OLD);
- X else
- X turnon(newflag, REPLIED);
- X when 'f' : turnon(newflag, FORWARD);
- X when '+' : modify = 1;
- X when '-' : modify = 2;
- X when '\\' : ; /* skip to the next flag */
- X otherwise:
- X if ((i = get_msg_list(v, list)) <= 0) {
- X print("Unknown flag: %c. Use flags -? for help\n",
- X v[0][c]);
- X return -1;
- X } else {
- X /* advance argv passed the msg-list */
- X v += i;
- X /* c will get ++'ed, so it should be 0 */
- X c = -1;
- X /* record that we have seen a message list */
- X had_list = 1;
- X }
- X }
- X
- X /* If we haven't got a msglist, use current_msg */
- X if (had_list == 0 && isoff(glob_flags, IS_PIPE))
- X set_msg_bit(list, current_msg);
- X
- X for (i = 0; i < msg_cnt; i++) {
- X if (!msg_bit(list, i))
- X continue;
- X else if (!newflag) {
- X wprint("msg %d: offset: %d, lines: %d, bytes: %d, flags:", i+1,
- X msg[i].m_offset, msg[i].m_lines, msg[i].m_size);
- X if (ison(msg[i].m_flags, UNREAD))
- X wprint(" UNREAD");
- X if (ison(msg[i].m_flags, OLD))
- X wprint(" OLD");
- X if (ison(msg[i].m_flags, DELETE))
- X wprint(" DELETE");
- X if (ison(msg[i].m_flags, PRESERVE))
- X wprint(" PRESERVE");
- X if (ison(msg[i].m_flags, REPLIED))
- X wprint(" REPLIED");
- X if (ison(msg[i].m_flags, SAVED))
- X wprint(" SAVED");
- X if (ison(msg[i].m_flags, PRINTED))
- X wprint(" PRINTED");
- X if (ison(msg[i].m_flags, FORWARD))
- X wprint(" FORWARD");
- X if (ison(msg[i].m_flags, UPDATE_STATUS))
- X wprint(" UPDATE_STATUS");
- X for (modify = MAX_PRIORITY; modify > 0; modify--)
- X if (ison(msg[i].m_flags, M_PRIORITY(modify)))
- X wprint(" %c", 'A' + modify - 1);
- X (void) strcpy(sent, date_to_ctime(msg[i].m_date_sent));
- X (void) strcpy(recv, date_to_ctime(msg[i].m_date_recv));
- X wprint("\n\tsent: %s\trecv: %s", sent, recv);
- X } else {
- X u_long save_priority = 0L;
- X if (modify == 0) {
- X int j;
- X for (j = 0; j < MAX_PRIORITY; j++)
- X if (ison(msg[i].m_flags, M_PRIORITY(j)))
- X turnon(save_priority, M_PRIORITY(j));
- X }
- X switch (modify) {
- X case 0: msg[i].m_flags = newflag;
- X when 1: msg[i].m_flags |= newflag;
- X when 2: msg[i].m_flags &= ~newflag;
- X }
- X if (save_priority)
- X msg[i].m_flags |= save_priority;
- X if (isoff(glob_flags, READ_ONLY)) {
- X turnon(glob_flags, DO_UPDATE);
- X turnon(msg[i].m_flags, DO_UPDATE);
- X }
- X }
- X }
- X return 0;
- }
- X
- /*
- X * Internal pager. Start the internal pager by passing the name of
- X * the pager in buf and passing TRUE as start_pager. If the internal
- X * pager is desired, pass NULL as buf. Continue paging by passing
- X * FALSE as start_pager and the buf is the stuff to pass thru to the
- X * pager. End paging by passing NULL as buf and FALSE as start_pager.
- X * start_pager actually has a ternary value -- for use by pipe_msg.
- X * If the pager can't be used, or is null, we're paging ourselves.
- X * Windows does nothing but echo buf to the msg window (this will change).
- X * The "buf" passed to the pager should be a line at a time so as to
- X * count \n's. If there is more than one newline, the first one is nulled
- X * and the next line done by calling do_pager recursively. WARNING: because
- X * "buf" is changed, it is *illegal* for anyone calling this routine to pass
- X * _constant_ strings --they should be strcpy'ed or sprintf'ed into a temp
- X * buff before passing to this routine! Otherwise, ANSI-C compilers will
- X * core dump. This is because constant strings are read-only.
- X * Return EOF if pager died, user exited pager, or if user types 'q'
- X * at the --more-- prompt for the internal pager.
- X *
- X * For windows, copy all the info into a tmpfile and set the pager_textsw
- X * to that file. When the pager ends, delete the file -- textsw will
- X * continue to read it since it does its own buffering.
- X */
- do_pager(buf, start_pager)
- char *buf;
- {
- X static FILE *pp;
- X static int cnt, len;
- X static u_long save_echo_flag;
- #ifdef SUNTOOL
- X static char file[MAXPATHLEN];
- X static Textsw sw;
- X
- X /* pipe_msg will pass -1 for start_pager to avoid this block */
- X if (start_pager > -1 && istool) {
- X if (buf && !start_pager) {
- X if (istool < 2) /* can't use windows yet -- send to stdout */
- X (void) fputs(buf, stdout);
- X else {
- X if (pp)
- X fputs(buf, pp);
- X else
- X textsw_insert(isoff(glob_flags, NEW_FRAME)?
- X pager_textsw : sw, buf, strlen(buf));
- X }
- X } else if (istool >= 2 && start_pager) {
- X Frame text_frame;
- X extern char *more_prompt;
- X char *p;
- X
- X timeout_cursors(TRUE);
- X if (ison(glob_flags, NEW_FRAME)) {
- X char *crt_win = do_set(set_options, "crt_win");
- X text_frame = window_create(tool, FRAME,
- X FRAME_SHOW_LABEL, TRUE,
- X FRAME_LABEL, more_prompt,
- X WIN_HEIGHT, l_height()*(crt_win? atoi(crt_win):12),
- X NULL);
- X sw = window_create(text_frame, TEXTSW,
- X TEXTSW_LINE_BREAK_ACTION, TEXTSW_WRAP_AT_CHAR,
- X TEXTSW_CLIENT_DATA, text_frame,
- X NULL);
- X notify_interpose_event_func(sw, scroll_textwin, NOTIFY_SAFE);
- X } else
- X textsw_reset(pager_textsw, 0, 0);
- X
- X /* find a free tmpfile */
- X if (!(p = getdir(do_set(set_options, "tmpdir"))))
- alted:
- X p = ALTERNATE_HOME;
- X {
- X int pid = getpid();
- X do
- X sprintf(file, "%s/..X%d", p, pid++);
- X while (!Access(file, F_OK));
- X }
- X if (!(pp = mask_fopen(file, "w"))) {
- X if (strcmp(p, ALTERNATE_HOME))
- X goto alted;
- X error("Can't create '%s'", tempfile);
- X }
- X return 0;
- X } else if (!buf && !start_pager) { /* pager is done */
- X if (pp)
- X (void) fclose(pp);
- X window_set(isoff(glob_flags, NEW_FRAME)? pager_textsw : sw,
- X TEXTSW_FILE, file,
- X TEXTSW_READ_ONLY, TRUE,
- X TEXTSW_UPDATE_SCROLLBAR,
- X NULL);
- X if (ison(glob_flags, NEW_FRAME)) {
- X turnoff(glob_flags, NEW_FRAME);
- X window_set(window_get(sw, TEXTSW_CLIENT_DATA),
- X WIN_SHOW, TRUE,
- X FRAME_NO_CONFIRM, TRUE,
- X FRAME_DONE_PROC, window_destroy,
- X NULL);
- X }
- X if (unlink(file) == -1)
- X error("Cannot unlink %s", file);
- X timeout_cursors(FALSE);
- X }
- X return 0;
- X }
- #endif /* SUNTOOL */
- X
- X if (start_pager) {
- X turnon(glob_flags, IGN_SIGS);
- X if (!buf) {
- X /* internal pager */
- X save_echo_flag = ison(glob_flags, ECHO_FLAG);
- X pp = stdout;
- X if (save_echo_flag) {
- X turnoff(glob_flags, ECHO_FLAG);
- X echo_off();
- X }
- X } else {
- X echo_on();
- X if (!(pp = popen(buf, "w")))
- X error(buf);
- X }
- X cnt = len = 0;
- X } else if (!buf) {
- X if (pp && pp != stdout)
- X (void) pclose(pp);
- X pp = NULL_FILE;
- X if (save_echo_flag) {
- X echo_on();
- X turnon(glob_flags, ECHO_FLAG);
- X } else
- X echo_off();
- X turnoff(glob_flags, IGN_SIGS);
- X } else if (pp != stdout)
- X return fputs(buf, pp); /* returns EOF if user exited pager */
- X else {
- X register char c = 0, *cr = index(buf, '\n');
- X len += strlen(buf);
- X if (cr) {
- X int maxlen =
- #ifdef CURSES
- X iscurses ? COLS :
- #endif /* CURSES */
- X 80;
- X if (len > maxlen)
- X cnt += len / maxlen;
- X len = 0;
- X }
- X if (cr && (c = *++cr) != '\0')
- X *cr = 0; /* send one line to stdout and prompt for more */
- X (void) fputs(buf, pp);
- X if (cr && (++cnt / (crt-1))) {
- X int n = c_more(NULL);
- X if (n == '\n' || n == '\r')
- X cnt--; /* go line by line */
- X else if (n == CTRL('D') || lower(n) == 'd' || n < 0) {
- X clearerr(stdin);
- X cnt = ((crt-1)/2);
- X } else if (lower(n) == 'q')
- X /* could check if "c" is set, but... see warning above */
- X return EOF;
- X else
- X cnt = 1;
- X }
- X if (c) {
- X *cr = c;
- X return do_pager(cr, FALSE);
- X }
- X }
- X return 0;
- }
- X
- /* curses based "more" like option */
- c_more(p)
- register char *p;
- {
- X register int c;
- X
- X if (!p)
- X p = "--more--";
- X print_more(p);
- X
- X while ((c = getchar()) >= 0 && c != CTRL('D') && !isspace(c) &&
- X c != '\n' && c != '\r' && lower(c) != 'q' && lower(c) != 'd')
- X bell();
- X if (ison(glob_flags, ECHO_FLAG) && c != '\n' && c != '\r')
- X while (getchar() != '\n');
- X (void) printf("\r%*c\r", strlen(p), ' '); /* remove the prompt */
- X (void) fflush(stdout);
- X return c;
- }
- X
- /*
- X * Your "signature" is of the type:
- X * file_or_path
- X * $variable
- X * \ literal string preceded by a backslash.
- X * The variable will be expanded into its string value.
- X * To sign the letter, the list of addresses is passed to this routine
- X * (separated by whitespace and/or commas). No comment fields!
- X *
- X * If "autosign2" is set, then it must be of the form:
- X * autosign2 = "*user user !host !some!path @dom.ain: ~/.sign2"
- X *
- X * The colon terminates the user/host lists from the "signature" to the right.
- X *
- X * Whitespace or commas separate tokens. If everyone on the list exists in
- X * the autosign2 list, the alternate signature is used. In case of syntax
- X * error, the alternate signature is used without checks (e.g. if the colon
- X * is missing). The alternate signature == null is the same as not signing
- X * the letter. An empty list forces signature2.
- X *
- X * If autosign2 is not set at all, then autosign is checked and used.
- X * autosign = <signature>
- X */
- void
- sign_letter(list, flags, fp)
- register char *list; /* list of addresses -- no comment fields */
- u_long flags;
- FILE *fp;
- {
- X char buf[MAXPATHLEN], *signature;
- X register char *p = NULL;
- X FILE *pp2;
- X int lines = 0, noisy;
- X
- X if (!list)
- X return;
- X while (isspace(*list))
- X list++;
- X if (!*list)
- X return;
- X if (ison(flags, SIGN)) {
- X noisy = !chk_option("quiet", "autosign");
- X if (!(p = do_set(set_options, "autosign2")))
- X buf[0] = 0;
- X else {
- X if (!(signature = index(p, ':')))
- X (void) strcpy(buf, p); /* No colon; use entire string as sig */
- X else {
- X int ret_val = 0;
- X *signature = 0;
- X /* p now points to a list of addresses and p2 points to the
- X * signature format to use. Check that each address in the list
- X * provided (parameter) matches the "addrs" in autosign2.
- X */
- X skipspaces(0);
- X if (!*p)
- X /* autosign2 = " : <signature>" send to all recipients */
- X ret_val = 1;
- X else if (p = alias_to_address(p)) {
- X rm_cmts_in_addr(p);
- X ret_val = compare_addrs(list, p, NULL);
- X }
- X *signature++ = ':'; /* must reset first! */
- X buf[0] = 0;
- X if (ret_val) {
- X while (isspace(*signature))
- X signature++;
- X /* Null signatures don't sign anything. */
- X if (!*strcpy(buf, signature))
- X return;
- X }
- X }
- X }
- X if (!buf[0]) {
- X if (!(p = do_set(set_options, "autosign")) || !*p) {
- X char *home;
- X if (!(home = do_set(set_options, "home")) || !*home)
- X home = ALTERNATE_HOME;
- X (void) sprintf(buf, "%s/%s", home, SIGNATURE);
- X } else
- X (void) strcpy(buf, p);
- X if (noisy)
- X wprint("Signing letter... ");
- X } else if (noisy)
- X wprint("Using alternate signature... ");
- X (void) fseek(fp, 0L, 2); /* guarantee position at end of file */
- X (void) fputc('\n', fp);
- X (void) fflush(fp);
- X if (*buf == '$')
- X if (!(p = do_set(set_options, buf)))
- X wprint("(%s isn't set -- letter not signed)\n", buf);
- X else {
- X putstring(p+1, fp);
- X if (noisy)
- X wprint("\n");
- X }
- X else if (*buf == '\\') {
- X putstring(buf, fp);
- X if (noisy)
- X wprint("\n");
- X } else if (*buf == '[') {
- X char *rbr = index(buf, ']');
- X if (rbr)
- X *rbr = 0;
- X putstring(buf + 1, fp);
- X if (noisy)
- X wprint("\n");
- X } else if (*buf == '|' || *buf == '!') {
- X (void) strcat(buf, " ");
- X (void) strcat(buf, list);
- X if (!(pp2 = popen(buf+1, "r")))
- X error(buf+1);
- X else {
- X turnon(glob_flags, IGN_SIGS);
- X while (fgets(buf, sizeof(buf), pp2)) {
- X int len = strlen(buf);
- X (void) fputs(buf, fp), lines++;
- X if (len < sizeof buf - 1 && buf[len - 1] != '\n')
- X (void) fputc('\n', fp);
- X }
- X (void) pclose(pp2);
- X (void) fflush(fp);
- X turnoff(glob_flags, IGN_SIGS);
- X if (noisy)
- X wprint("added %d line%s\n", lines, lines == 1? "" : "s");
- X }
- X } else {
- X /* precede _file_ signatures ONLY with "-- \n" */
- X (void) fputs("-- \n", fp);
- X (void) fflush(fp);
- X (void) file_to_fp(buf, fp, "r");
- X }
- X }
- X
- X (void) fflush(stdout); /* for sys-v and older xenix */
- X
- X /* if fortune is set, check to see if fortunates is set. If so,
- X * check to see if all the recipient are on the fortunates list.
- X */
- X if (ison(flags, DO_FORTUNE)) {
- X noisy = !chk_option("quiet", "fortune");
- X if (p = do_set(set_options, "fortunates")) {
- X if (!(p = alias_to_address(p)))
- X return; /* no reason to hang around */
- X rm_cmts_in_addr(p);
- X if (!compare_addrs(list, p, buf)) {
- X if (noisy) {
- X wprint("\"fortunates\" does not contain \"%s\".\n", buf);
- X wprint("No fortune added.\n");
- X }
- X return;
- X }
- X }
- X if (noisy)
- X wprint("You may be fortunate... ");
- X if ((p = do_set(set_options, "fortune")) && *p == '/')
- X (void) strcpy(buf, p);
- X else
- X (void) sprintf(buf, "%s %s", FORTUNE, (p && *p == '-')? p: "-s");
- X if (!(pp2 = popen(buf, "r")))
- X error(buf);
- X else {
- X turnon(glob_flags, IGN_SIGS);
- X (void) fseek(fp, 0L, 2); /* go to end of file */
- X while (fgets(buf, sizeof(buf), pp2))
- X (void) fputs(buf, fp), lines++;
- X (void) pclose(pp2);
- X turnoff(glob_flags, IGN_SIGS);
- X (void) fflush(fp);
- X if (noisy)
- X wprint("added %d line%s\n", lines, lines == 1? "" : "s");
- X }
- X }
- X (void) fflush(stdout); /* for sys-v and older xenix */
- }
- X
- X
- /* return -1 since function doesn't affect messages */
- check_flags(flags)
- u_long flags;
- {
- X print_more(" ");
- X if (ison(flags, VERBOSE))
- X print_more("VERBOSE ");
- X if (ison(flags, INCLUDE))
- X print_more("INCLUDE ");
- X if (ison(flags, INCLUDE_H))
- X print_more("INCLUDE_H ");
- X if (ison(flags, EDIT))
- X print_more("EDIT ");
- X if (ison(flags, SIGN))
- X print_more("SIGN ");
- X if (ison(flags, DO_FORTUNE))
- X print_more("DO_FORTUNE ");
- X if (ison(flags, NO_HEADER))
- X print_more("NO_HEADER ");
- X if (ison(flags, DELETE))
- X print_more("DELETE ");
- X if (ison(flags, OLD))
- X print_more("OLD ");
- X if (ison(flags, UNREAD))
- X print_more("UNREAD ");
- X if (ison(flags, UPDATE_STATUS))
- X print_more("UPDATE_STATUS ");
- X if (ison(flags, NO_PAGE))
- X print_more("NO_PAGE ");
- X if (ison(flags, INDENT))
- X print_more("INDENT ");
- X if (ison(flags, NO_IGNORE))
- X print_more("NO_IGNORE ");
- X if (ison(flags, PRESERVE))
- X print_more("PRESERVE ");
- X print_more("\n");
- X return -1;
- }
- SHAR_EOF
- chmod 0644 misc.c ||
- echo 'restore of misc.c failed'
- Wc_c="`wc -c < 'misc.c'`"
- test 22738 -eq "$Wc_c" ||
- echo 'misc.c: original size 22738, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= misc_frame.c ==============
- if test -f 'misc_frame.c' -a X"$1" != X"-c"; then
- echo 'x - skipping misc_frame.c (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting misc_frame.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'misc_frame.c' &&
- /* @(#) misc_frame.c (c) copyright 9/29/89 (Dan Heller) */
- X
- /*
- X * This file contains several functions which create dialog box frames
- X * for (currently) mail aliases and ignored headers. Each dialog box
- X * has a list of some kind and a way to add or delete items from the
- X * list. The list is a textsw which is updated (currently) by do_set().
- X * Public routines:
- X * update_list_textsw(struct options **) updates the textsw list.
- X * do_alias() creates the alias dialog frame box
- X * do_ignore() creates the ignored headers dialog frame box
- X */
- X
- #include "mush.h"
- X
- extern Notify_value fkey_interposer();
- X
- /****************** Mail Aliases ********************/
- X
- Frame alias_frame;
- Panel_item alias_msg, alias_name, alias_value, alias_list_textsw;
- static void set_alias();
- X
- Frame ignore_frame;
- Panel_item ignore_msg, ignore_name, ignore_list_textsw;
- static Panel_setting set_ignore();
- X
- #define MY_FRAME_WIDTH 600
- X
- static void
- frame_help(item)
- Panel_item item;
- {
- X (void) help(0, panel_get(item, PANEL_CLIENT_DATA), tool_help);
- }
- X
- void
- update_list_textsw(list)
- struct options **list;
- {
- X Textsw save = pager_textsw;
- X
- X if (list == &aliases)
- X pager_textsw = alias_list_textsw;
- X else if (list == &ignore_hdr)
- X pager_textsw = ignore_list_textsw;
- X else
- X /* no textsw for this guy yet */
- X return;
- X
- X if (pager_textsw && !!window_get(pager_textsw, WIN_SHOW))
- X (void) do_set(*list, NULL);
- X pager_textsw = save;
- }
- X
- static void
- alias_done()
- {
- X window_destroy(alias_frame);
- X alias_frame = (Frame) 0;
- }
- X
- void
- do_aliases()
- {
- X Panel panel;
- X
- X if (alias_frame) {
- X window_set(alias_frame, WIN_SHOW, TRUE, NULL);
- X return;
- X }
- #ifdef SUN_3_5
- X if (nopenfiles(0) < 5) {
- X print("Too many frames; close one first!\n");
- X return;
- X }
- #endif /* SUN_3_5 */
- X
- X alias_frame = window_create(tool, FRAME,
- X FRAME_SHOW_LABEL, TRUE,
- X FRAME_LABEL, "Mail Aliases",
- X FRAME_NO_CONFIRM, TRUE,
- X FRAME_DONE_PROC, alias_done,
- X WIN_SHOW, TRUE,
- X WIN_WIDTH, MY_FRAME_WIDTH,
- X NULL);
- X
- X panel = window_create(alias_frame, PANEL,
- X PANEL_WIDTH, MY_FRAME_WIDTH,
- X NULL);
- X notify_interpose_event_func(panel, fkey_interposer, NOTIFY_SAFE);
- X
- X panel_create_item(panel, PANEL_BUTTON,
- X PANEL_LABEL_IMAGE,
- X panel_button_image(panel, "Help", 4, mush_font),
- X PANEL_CLIENT_DATA, "aliases",
- X PANEL_NOTIFY_PROC, frame_help,
- X NULL);
- X panel_create_item(panel, PANEL_BUTTON,
- X PANEL_LABEL_IMAGE,
- X panel_button_image(panel, "Set", 3, mush_font),
- X PANEL_NOTIFY_PROC, set_alias,
- X PANEL_CLIENT_DATA, TRUE,
- X NULL);
- X panel_create_item(panel, PANEL_BUTTON,
- X PANEL_LABEL_IMAGE,
- X panel_button_image(panel, "Unset", 5, mush_font),
- X PANEL_NOTIFY_PROC, set_alias,
- X PANEL_CLIENT_DATA, FALSE,
- X NULL);
- X
- X alias_msg = panel_create_item(panel, PANEL_MESSAGE,
- X PANEL_LABEL_STRING,
- X "Type name of alias and address list and select <set> or <unset>",
- X NULL);
- X
- X alias_name = panel_create_item(panel, PANEL_TEXT,
- X PANEL_LABEL_STRING, "Alias Name:",
- X PANEL_VALUE_DISPLAY_LENGTH, 60,
- X NULL);
- X alias_value = panel_create_item(panel, PANEL_TEXT,
- X PANEL_LABEL_STRING, "Alias Address(es):",
- X PANEL_VALUE_DISPLAY_LENGTH, 60,
- X NULL);
- X window_fit_height(panel);
- X
- X alias_list_textsw = window_create(alias_frame, TEXTSW,
- X WIN_BELOW, panel,
- X WIN_WIDTH, MY_FRAME_WIDTH,
- X WIN_HEIGHT, 15 * l_height(),
- #ifdef SUN_4_0 /* SunOS 4.0+ */
- X TEXTSW_LINE_BREAK_ACTION, TEXTSW_WRAP_AT_WORD,
- #else /* SUN_4_0 */
- X TEXTSW_LINE_BREAK_ACTION, TEXTSW_WRAP_AT_CHAR,
- #endif /* SUN_4_0 */
- X NULL);
- X (void) notify_interpose_event_func(alias_list_textsw,
- X fkey_interposer, NOTIFY_SAFE);
- X
- X window_fit_height(alias_frame);
- X update_list_textsw(&aliases);
- }
- X
- static void
- set_alias(item)
- Panel_item item;
- {
- X int argc, set_it = (int)panel_get(item, PANEL_CLIENT_DATA);
- X char buf[BUFSIZ], **argv, *name, *value;
- X
- X name = panel_get_value(alias_name);
- X if (!*name) {
- X panel_set(alias_msg, PANEL_LABEL_STRING, "Need an alias name.", NULL);
- X return;
- X }
- X if (any(name, " \t")) {
- X panel_set(alias_msg,
- X PANEL_LABEL_STRING, "Alias name may not contain spaces.",
- X NULL);
- X return;
- X }
- X if (set_it) {
- X value = panel_get_value(alias_value);
- X if (!*value) {
- X panel_set(alias_msg,
- X PANEL_LABEL_STRING, "Specify alias address(es).",
- X NULL);
- X return;
- X }
- X sprintf(buf, "alias %s %s", name, value);
- X } else
- X sprintf(buf, "unalias %s", name);
- X if (!(argv = mk_argv(buf, &argc, TRUE)) || do_alias(argc, argv) == -1)
- X panel_set(alias_msg,
- X PANEL_LABEL_STRING, "Couldn't set alias.",
- X NULL);
- X else
- X panel_set(alias_msg,
- X PANEL_LABEL_STRING, "",
- X NULL);
- X panel_set_value(alias_name, "");
- X panel_set_value(alias_value, "");
- X free_vec(argv);
- }
- X
- /* int cuz it's also the callback for the text item */
- static Panel_setting
- set_ignore(item)
- Panel_item item;
- {
- X int argc, set_it = (int)panel_get(item, PANEL_CLIENT_DATA);
- X char buf[BUFSIZ], *name, **argv;
- X
- X name = panel_get_value(ignore_name);
- X if (!*name) {
- X panel_set(ignore_msg, PANEL_LABEL_STRING, "Missing header name.", NULL);
- X return PANEL_NONE;
- X }
- X if (set_it)
- X sprintf(buf, "ignore %s", name);
- X else
- X sprintf(buf, "unignore %s", name);
- X /* set() will call update_list_textsw() */
- X if (!(argv = mk_argv(buf, &argc, TRUE)) || set(argc, argv, NULL) == -1)
- X panel_set(ignore_msg,
- X PANEL_LABEL_STRING, "Internal Error!?",
- X NULL);
- X else
- X panel_set(ignore_msg,
- SHAR_EOF
- true || echo 'restore of misc_frame.c failed'
- fi
- echo 'End of part 13'
- echo 'File misc_frame.c is continued in part 14'
- echo 14 > _shar_seq_.tmp
- exit 0
- exit 0 # Just in case...
- --
- Kent Landfield INTERNET: kent@sparky.IMD.Sterling.COM
- Sterling Software, IMD UUCP: uunet!sparky!kent
- Phone: (402) 291-8300 FAX: (402) 291-4362
- Please send comp.sources.misc-related mail to kent@uunet.uu.net.
-