argv@zipcode.com (Dan Heller) (04/22/91)
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.