home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume18 / mush / part13 < prev    next >
Internet Message Format  |  1991-04-22  |  51KB

  1. From: argv@zipcode.com (Dan Heller)
  2. Newsgroups: comp.sources.misc
  3. Subject: v18i070:  mush - Mail User's Shell, Part13/22
  4. Message-ID: <1991Apr22.000428.18915@sparky.IMD.Sterling.COM>
  5. Date: 22 Apr 91 00:04:28 GMT
  6. Approved: kent@sparky.imd.sterling.com
  7. X-Checksum-Snefru: 07578e65 281d7a92 a45fac4b f4b5fd2d
  8.  
  9. Submitted-by: Dan Heller <argv@zipcode.com>
  10. Posting-number: Volume 18, Issue 70
  11. Archive-name: mush/part13
  12. Supersedes: mush: Volume 12, Issue 28-47
  13.  
  14. #!/bin/sh
  15. # do not concatenate these parts, unpack them in order with /bin/sh
  16. # file makefile.sun continued
  17. #
  18. if test ! -r _shar_seq_.tmp; then
  19.     echo 'Please unpack part 1 first!'
  20.     exit 1
  21. fi
  22. (read Scheck
  23.  if test "$Scheck" != 13; then
  24.     echo Please unpack part "$Scheck" next!
  25.     exit 1
  26.  else
  27.     exit 0
  28.  fi
  29. ) < _shar_seq_.tmp || exit 1
  30. if test ! -f _shar_wnt_.tmp; then
  31.     echo 'x - still skipping makefile.sun'
  32. else
  33. echo 'x - continuing file makefile.sun'
  34. sed 's/^X//' << 'SHAR_EOF' >> 'makefile.sun' &&
  35. #
  36. # Note that the default SunOS version for mush is 4.1.  If you have an
  37. # older version of SunOS, you must explicitly define SUN_3_5 or SUN_4_0.
  38. #
  39. HDRS= mush.h config.h-dist strings.h bindings.h options.h version.h glob.h
  40. X
  41. SRCS= addrs.c bind.c commands.c curs_io.c curses.c dates.c doproc.c \
  42. X      execute.c expr.c file.c fkeys.c folders.c glob.c hdrs.c init.c lock.c \
  43. X      loop.c macros.c mail.c main.c malloc.c misc.c misc_frame.c msgs.c \
  44. X      options.c panels.c pick.c print.c hdr_sw.c setopts.c signals.c sort.c \
  45. X      strings.c tool.c tooledit.c viewopts.c command2.c
  46. X
  47. OBJS= addrs.o bind.o commands.o curs_io.o curses.o dates.o doproc.o \
  48. X      execute.o expr.o file.o fkeys.o folders.o glob.o hdrs.o init.o lock.o \
  49. X      loop.o macros.o mail.o main.o malloc.o misc.o misc_frame.o msgs.o \
  50. X      options.o panels.o pick.o print.o hdr_sw.o setopts.o signals.o sort.o \
  51. X      strings.o tool.o tooledit.o viewopts.o command2.o
  52. X
  53. IMAGES= mail.icon.1 mail.icon.2
  54. X
  55. HELP_FILES= README README-7.0 README-7.1 README-7.2.0 README-7.2.2 \
  56. X            mush.1 cmd_help tool_help Mushrc Mailrc Gnurc \
  57. X        advanced.mushrc sample.mushrc digestify
  58. X
  59. MAKES= makefile.sun makefile.bsd makefile.sys.v makefile.xenix makefile.hpux
  60. X
  61. # If your SunOS version is 3.5, add -DSUN_3_5 to CFLAGS.
  62. # If your SunOS version is 4.0, add -DSUN_4_0 to CFLAGS.
  63. # If you are not using SUNTOOL, use makefile.bsd and add one of
  64. #    -DSUN_3_5, -DSUN_4_0, or -DSUN_4_1 to CFLAGS there.
  65. CFLAGS= -O -DSUNTOOL -DCURSES -DBSD
  66. LDFLAGS=
  67. LIBES= -lcurses -ltermlib -lsuntool -lsunwindow -lpixrect
  68. OTHERLIBS=
  69. # Use some variant of this one if you #define MMDF in config.h
  70. #OTHERLIBS=/usr/src/mmdf/lib/libmmdf.a
  71. LINTFLAGS= -bxah -Dlint
  72. X
  73. mush: $(OBJS)
  74. X    @echo loading...
  75. X    @cc $(LDFLAGS) $(OBJS) $(LIBES) $(OTHERLIBS) -o mush
  76. X
  77. $(OBJS): config.h mush.h
  78. loop.o: version.h
  79. X
  80. lint:
  81. X    lint $(LINTFLAGS) $(SRCS) -DSUNTOOL -DCURSES -DBSD
  82. X
  83. clean:
  84. X    rm -f *.o core mush
  85. X
  86. BINDIR= /usr/local/bin
  87. LIBDIR= /usr/local/lib
  88. MRCDIR= /usr/lib
  89. MANDIR= /usr/local/man/man1
  90. MANEXT= 1
  91. X
  92. install: mush
  93. X    mv mush $(BINDIR)
  94. X    strip $(BINDIR)/mush
  95. X    chmod 0755 $(BINDIR)/mush
  96. X    rm -f $(BINDIR)/mushtool
  97. X    ln -s $(BINDIR)/mush $(BINDIR)/mushtool
  98. X    cp mush.1 $(MANDIR)/mush.$(MANEXT)
  99. X    chmod 0644 $(MANDIR)/mush.$(MANEXT)
  100. X    cp tool_help $(LIBDIR)
  101. X    chmod 0644 $(LIBDIR)/tool_help
  102. X    cp cmd_help $(LIBDIR)
  103. X    chmod 0644 $(LIBDIR)/cmd_help
  104. X    cp Mushrc $(MRCDIR)/Mushrc
  105. X    chmod 0644 $(MRCDIR)/Mushrc
  106. SHAR_EOF
  107. echo 'File makefile.sun is complete' &&
  108. chmod 0644 makefile.sun ||
  109. echo 'restore of makefile.sun failed'
  110. Wc_c="`wc -c < 'makefile.sun'`"
  111. test 2454 -eq "$Wc_c" ||
  112.     echo 'makefile.sun: original size 2454, current size' "$Wc_c"
  113. rm -f _shar_wnt_.tmp
  114. fi
  115. # ============= makefile.sys.v ==============
  116. if test -f 'makefile.sys.v' -a X"$1" != X"-c"; then
  117.     echo 'x - skipping makefile.sys.v (File already exists)'
  118.     rm -f _shar_wnt_.tmp
  119. else
  120. > _shar_wnt_.tmp
  121. echo 'x - extracting makefile.sys.v (Text)'
  122. sed 's/^X//' << 'SHAR_EOF' > 'makefile.sys.v' &&
  123. # Mush makefile for system V.  Note: SIGRET should return void for normal
  124. # sys-v, but Att PC users should *not* have it defined.  See the README!!
  125. #
  126. HDRS1= mush.h config.h
  127. HDRS2= strings.h options.h
  128. HDRS3= bindings.h glob.h
  129. HDRS4= version.h
  130. SRCS1= commands.c dates.c execute.c expr.c folders.c \
  131. X    hdrs.c init.c loop.c mail.c main.c misc.c msgs.c pick.c \
  132. X    print.c setopts.c signals.c sort.c viewopts.c options.c lock.c
  133. SRCS2= bind.c curs_io.c curses.c file.c strings.c macros.c \
  134. X    addrs.c malloc.c glob.c command2.c
  135. X
  136. OBJS1= commands.o dates.o execute.o expr.o folders.o \
  137. X    hdrs.o init.o loop.o mail.o main.o misc.o msgs.o pick.o \
  138. X    print.o setopts.o signals.o sort.o viewopts.o options.o lock.o
  139. OBJS2= bind.o curs_io.o curses.o file.o strings.o macros.o \
  140. X    addrs.o malloc.o glob.o command2.o
  141. X
  142. HELP= README README-7.0 README-7.1 README-7.2.0 README-7.2.2 mush.1 \
  143. X    cmd_help Mushrc Mailrc Gnurc sample.mushrc advanced.mushrc digestify
  144. X
  145. # Sun OS systems who wish to compile with sys-v options:
  146. # CC= /usr/5bin/cc
  147. # CFLAGS=     -O -DSYSV -DCURSES -DUSG -DDIRECTORY
  148. # LIBS= -L/usr/5lib -lcurses
  149. X
  150. # IRIX 3.2 systems (SGI Iris workstations) should add -DDIRECTORY to CFLAGS
  151. # SCO UNIX 3.2 should add -DDIRECTORY -DSELECT and should avoid library -lx
  152. X
  153. CFLAGS=     -O -DSYSV -DUSG -DCURSES -DREGCMP -DSIGRET=void
  154. LDFLAGS=
  155. LIBS=         -lcurses -lPW
  156. OTHERLIBS=
  157. # Use some variant of this one if you #define MMDF in config.h
  158. #OTHERLIBS=/usr/src/mmdf/lib/libmmdf.a
  159. PROG=        mush
  160. X
  161. $(PROG): $(OBJS1) $(OBJS2)
  162. X    @echo loading...
  163. X    @$(CC) $(LDFLAGS) $(OBJS1) $(OBJS2) -o $(PROG) $(LIBS) $(OTHERLIBS)
  164. X
  165. $(OBJS1): $(HDRS1) $(HDRS2)
  166. $(OBJS2): $(HDRS1) $(HDRS2) $(HDRS3)
  167. loop.o: version.h
  168. X
  169. BINDIR= /usr/local/bin
  170. LIBDIR= /usr/local/lib
  171. MRCDIR= /usr/lib
  172. MANDIR= /usr/local/man/man1
  173. MANEXT= 1
  174. X
  175. install: mush
  176. X    cp mush $(BINDIR)
  177. X    strip $(BINDIR)/mush
  178. X    chmod 0755 $(BINDIR)/mush
  179. X    cp mush.1 $(MANDIR)/mush.$(MANEXT)
  180. X    chmod 0644 $(MANDIR)/mush.$(MANEXT)
  181. X    cp cmd_help $(LIBDIR)
  182. X    chmod 0644 $(LIBDIR)/cmd_help
  183. X    cp Mushrc $(MRCDIR)/Mushrc
  184. X    chmod 0644 $(MRCDIR)/Mushrc
  185. SHAR_EOF
  186. chmod 0644 makefile.sys.v ||
  187. echo 'restore of makefile.sys.v failed'
  188. Wc_c="`wc -c < 'makefile.sys.v'`"
  189. test 2023 -eq "$Wc_c" ||
  190.     echo 'makefile.sys.v: original size 2023, current size' "$Wc_c"
  191. rm -f _shar_wnt_.tmp
  192. fi
  193. # ============= makefile.xenix ==============
  194. if test -f 'makefile.xenix' -a X"$1" != X"-c"; then
  195.     echo 'x - skipping makefile.xenix (File already exists)'
  196.     rm -f _shar_wnt_.tmp
  197. else
  198. > _shar_wnt_.tmp
  199. echo 'x - extracting makefile.xenix (Text)'
  200. sed 's/^X//' << 'SHAR_EOF' > 'makefile.xenix' &&
  201. #
  202. # makefile for Xenix machines.  See "MODEL" below for your xenix type.
  203. # some .c files may require the -LARGE compiler flag.  Examples below.
  204. # This makefile assumes an 80386 machine.  If you have an 80286, see
  205. # notes below.  This makefile was built for SCO/microsoft xenix --if you
  206. # are running some other kind of xenix, you might need to change the
  207. # CFLAGS and LDFLAGS options.
  208. #
  209. HDRS= mush.h config.h-dist strings.h bindings.h options.h version.h glob.h
  210. SRCS1= main.c init.c misc.c execute.c
  211. SRCS2= signals.c msgs.c pick.c viewopts.c
  212. SRCS3= sort.c expr.c folders.c dates.c
  213. SRCS4= loop.c bind.c options.c
  214. SRCS5= commands.c commands2.c setopts.c hdrs.c
  215. SRCS6= mail.c print.c
  216. SRCS7= curses.c curs_io.c
  217. SRCS8= file.c strings.c malloc.c
  218. SRCS9= lock.c macros.c addrs.c glob.c
  219. OBJS= main.o init.o misc.o mail.o hdrs.o execute.o commands.o print.o file.o \
  220. X      signals.o setopts.o msgs.o pick.o sort.o expr.o strings.o \
  221. X      folders.o dates.o loop.o viewopts.o bind.o curses.o curs_io.o \
  222. X      lock.o macros.o options.o addrs.o malloc.o glob.o command2.o
  223. HELP_FILES= README README-7.0 README-7.1 README-7.2.0 README-7.2.2 mush.1 \
  224. X    cmd_help Mushrc Mailrc Gnurc sample.mushrc advanced.mushrc digestify
  225. X
  226. # Memory model.  Use -M3e for 80386 machines.
  227. # Use -M2le -Mt32 -LARGE for 80286 machines.
  228. MODEL= -M3e
  229. X
  230. #
  231. # 80286 xenix may use this LDFLAGS define:
  232. #LDFLAGS= -X -lx -M2le -Mt32 -F 8000 -SEG 256 -LARGE
  233. LDFLAGS= -X -lx -M3
  234. X
  235. CFLAGS= $(MODEL) -O -DSYSV -DCURSES -DREGCMP -DUSG 
  236. LIBES= -lcurses -ltermlib
  237. OTHERLIBS=
  238. # Use some variant of this one if you #define MMDF in config.h
  239. #OTHERLIBS=/usr/src/mmdf/lib/libmmdf.a
  240. X
  241. mush: $(OBJS)
  242. X    @echo loading...
  243. X    @cc $(LDFLAGS) $(OBJS) $(LIBES) $(OTHERLIBS) -o mush
  244. X
  245. $(OBJS): config.h mush.h
  246. loop.o: version.h
  247. X
  248. # For 80286 machines, use these two lines...
  249. # misc.o:    misc.c
  250. #     cc $(CFLAGS) -LARGE -c misc.c
  251. X
  252. bind.o:    bind.c
  253. X    cc $(CFLAGS) -LARGE -c bind.c
  254. X
  255. clean:
  256. X    rm -f *.o core mush
  257. X
  258. BINDIR= /usr/local/bin
  259. LIBDIR= /usr/local/lib
  260. MRCDIR= /usr/lib
  261. MANDIR= /usr/local/man/man1
  262. MANEXT= 1
  263. X
  264. install: mush
  265. X    cp mush $(BINDIR)
  266. X    strip $(BINDIR)/mush
  267. X    chmod 0755 $(BINDIR)/mush
  268. X    cp mush.1 $(MANDIR)/mush.$(MANEXT)
  269. X    chmod 0644 $(MANDIR)/mush.$(MANEXT)
  270. X    cp cmd_help $(LIBDIR)
  271. X    chmod 0644 $(LIBDIR)/cmd_help
  272. X    cp Mushrc $(MRCDIR)/Mushrc
  273. X    chmod 0644 $(MRCDIR)/Mushrc
  274. SHAR_EOF
  275. chmod 0644 makefile.xenix ||
  276. echo 'restore of makefile.xenix failed'
  277. Wc_c="`wc -c < 'makefile.xenix'`"
  278. test 2293 -eq "$Wc_c" ||
  279.     echo 'makefile.xenix: original size 2293, current size' "$Wc_c"
  280. rm -f _shar_wnt_.tmp
  281. fi
  282. # ============= malloc.c ==============
  283. if test -f 'malloc.c' -a X"$1" != X"-c"; then
  284.     echo 'x - skipping malloc.c (File already exists)'
  285.     rm -f _shar_wnt_.tmp
  286. else
  287. > _shar_wnt_.tmp
  288. echo 'x - extracting malloc.c (Text)'
  289. sed 's/^X//' << 'SHAR_EOF' > 'malloc.c' &&
  290. /*
  291. X * This is a slightly modified version of the malloc.c distributed with
  292. X * Larry Wall's perl 2.0 sources.  RCS and sccs information has been
  293. X * retained, but modified so that it will not actually affect checkin
  294. X * or checkout of this file if revision control is used for Mush.
  295. X *
  296. X * Other changes include:
  297. X *    Removal of the ASSERT macro and other code related to the
  298. X *    preprocessor definition "debug"
  299. X *
  300. X *    Replaced #include "perl.h" with #include "mush.h" (guess why)
  301. X *
  302. X *    Warning messages are now printed with the mush Debug macro,
  303. X *    that is, they are normally suppressed
  304. X *
  305. X *    Added a calloc() function, using mush's bzero()
  306. X *
  307. X * Also, the mush xfree() and free_vec() functions have been moved here.
  308. X */
  309. X
  310. #include "mush.h"
  311. X
  312. /*
  313. X * Compile this portion only if configured for INTERNAL_MALLOC
  314. X */
  315. #ifdef INTERNAL_MALLOC
  316. #ifdef SYSV
  317. #include <memory.h>
  318. #define bcopy(src,dst,len)    memcpy(dst,src,len)
  319. #endif /* SYSV */
  320. #define free xfree    /* rename free for mush purposes */
  321. X
  322. /* Begin modified perl malloc.c */
  323. X
  324. /* Header: malloc.c,v 2.0 88/06/05 00:09:16 root Exp
  325. X *
  326. X * Log:    malloc.c,v
  327. X * Revision 2.0  88/06/05  00:09:16  root
  328. X * Baseline version 2.0.
  329. X * 
  330. X */
  331. X
  332. #ifndef lint
  333. static char sccsid[] = "malloc.c    4.3 (Berkeley) 9/16/83";
  334. #endif /* !lint */
  335. X
  336. #define RCHECK
  337. /*
  338. X * malloc.c (Caltech) 2/21/82
  339. X * Chris Kingsley, kingsley@cit-20.
  340. X *
  341. X * This is a very fast storage allocator.  It allocates blocks of a small 
  342. X * number of different sizes, and keeps free lists of each size.  Blocks that
  343. X * don't exactly fit are passed up to the next larger size.  In this 
  344. X * implementation, the available sizes are 2^n-4 (or 2^n-12) bytes long.
  345. X * This is designed for use in a program that uses vast quantities of memory,
  346. X * but bombs when it runs out. 
  347. X */
  348. X
  349. /* I don't much care whether these are defined in sys/types.h--LAW */
  350. X
  351. #undef u_char
  352. #define u_char unsigned char
  353. #undef u_int
  354. #define u_int unsigned int
  355. #undef u_short
  356. #define u_short unsigned short
  357. X
  358. /*
  359. X * The overhead on a block is at least 4 bytes.  When free, this space
  360. X * contains a pointer to the next free block, and the bottom two bits must
  361. X * be zero.  When in use, the first byte is set to MAGIC, and the second
  362. X * byte is the size index.  The remaining bytes are for alignment.
  363. X * If range checking is enabled and the size of the block fits
  364. X * in two bytes, then the top two bytes hold the size of the requested block
  365. X * plus the range checking words, and the header word MINUS ONE.
  366. X */
  367. union    overhead {
  368. X    union    overhead *ov_next;    /* when free */
  369. X    struct {
  370. X        u_char    ovu_magic;    /* magic number */
  371. X        u_char    ovu_index;    /* bucket # */
  372. #ifdef RCHECK
  373. X        u_short    ovu_size;    /* actual block size */
  374. X        u_int    ovu_rmagic;    /* range magic number */
  375. #endif /* RCHECK */
  376. X    } ovu;
  377. #define    ov_magic    ovu.ovu_magic
  378. #define    ov_index    ovu.ovu_index
  379. #define    ov_size        ovu.ovu_size
  380. #define    ov_rmagic    ovu.ovu_rmagic
  381. };
  382. X
  383. #define    MAGIC        0xff        /* magic # on accounting info */
  384. #define OLDMAGIC    0x7f        /* same after a free() */
  385. #define RMAGIC        0x55555555    /* magic # on range info */
  386. #ifdef RCHECK
  387. #define    RSLOP        sizeof (u_int)
  388. #else /* !RCHECK */
  389. #define    RSLOP        0
  390. #endif /* RCHECK */
  391. X
  392. /*
  393. X * nextf[i] is the pointer to the next free block of size 2^(i+3).  The
  394. X * smallest allocatable block is 8 bytes.  The overhead information
  395. X * precedes the data area returned to the user.
  396. X */
  397. #define    NBUCKETS 30
  398. static    union overhead *nextf[NBUCKETS];
  399. extern    char *sbrk();
  400. X
  401. #ifdef MSTATS
  402. /*
  403. X * nmalloc[i] is the difference between the number of mallocs and frees
  404. X * for a given block size.
  405. X */
  406. static    u_int nmalloc[NBUCKETS];
  407. #endif /* MSTATS */
  408. X
  409. char *
  410. malloc(nbytes)
  411. X    register unsigned nbytes;
  412. {
  413. X    register union overhead *p;
  414. X    register int bucket = 0;
  415. X    register unsigned shiftr;
  416. X
  417. X    if (nbytes == 0)
  418. X        return NULL;
  419. X    /*
  420. X     * Convert amount of memory requested into
  421. X     * closest block size stored in hash buckets
  422. X     * which satisfies request.  Account for
  423. X     * space used per block for accounting.
  424. X     */
  425. X    nbytes += sizeof (union overhead) + RSLOP;
  426. X    nbytes = (nbytes + 3) &~ 3; 
  427. X    shiftr = (nbytes - 1) >> 2;
  428. X    /* apart from this loop, this is O(1) */
  429. X    while (shiftr >>= 1)
  430. X        bucket++;
  431. X    /*
  432. X     * If nothing in hash bucket right now,
  433. X     * request more memory from the system.
  434. X     */
  435. X    if (nextf[bucket] == (union overhead *)0)    
  436. X        morecore(bucket);
  437. X    if ((p = (union overhead *)nextf[bucket]) == (union overhead *)0)
  438. X        return (NULL);
  439. X    /* remove from linked list */
  440. X    if (*((int*)p) > 0x10000000)
  441. X        Debug("Corrupt malloc ptr 0x%x at 0x%x\n",*((int*)p),p);
  442. X    nextf[bucket] = nextf[bucket]->ov_next;
  443. X    p->ov_magic = MAGIC;
  444. X    p->ov_index= bucket;
  445. #ifdef MSTATS
  446. X    nmalloc[bucket]++;
  447. #endif /* MSTATS */
  448. #ifdef RCHECK
  449. X    /*
  450. X     * Record allocated size of block and
  451. X     * bound space with magic numbers.
  452. X     */
  453. X    if (nbytes <= 0x10000)
  454. X        p->ov_size = nbytes - 1;
  455. X    p->ov_rmagic = RMAGIC;
  456. X    *((u_int *)((caddr_t)p + nbytes - RSLOP)) = RMAGIC;
  457. #endif /* RCHECK */
  458. X    return ((char *)(p + 1));
  459. }
  460. X
  461. /*
  462. X * Allocate more memory to the indicated bucket.
  463. X */
  464. static
  465. morecore(bucket)
  466. X    register bucket;
  467. {
  468. X    register union overhead *op;
  469. X    register int rnu;       /* 2^rnu bytes will be requested */
  470. X    register int nblks;     /* become nblks blocks of the desired size */
  471. X    register int siz;
  472. X
  473. X    if (nextf[bucket])
  474. X        return;
  475. X    /*
  476. X     * Insure memory is allocated
  477. X     * on a page boundary.  Should
  478. X     * make getpageize call?
  479. X     */
  480. X    op = (union overhead *)sbrk(0);
  481. X    if ((long)op & 0x3ff)
  482. X        sbrk(1024 - ((long)op & 0x3ff));
  483. X    /* take 2k unless the block is bigger than that */
  484. X    rnu = (bucket <= 8) ? 11 : bucket + 3;
  485. X    nblks = 1 << (rnu - (bucket + 3));  /* how many blocks to get */
  486. X    if (rnu < bucket)
  487. X        rnu = bucket;
  488. X    op = (union overhead *)sbrk(1 << rnu);
  489. X    /* no more room! */
  490. X    if ((long)op == -1)
  491. X        return;
  492. X    /*
  493. X     * Round up to minimum allocation size boundary
  494. X     * and deduct from block count to reflect.
  495. X     */
  496. X    if ((long)op & 7) {
  497. X        op = (union overhead *)(((long)op + 8) &~ 7);
  498. X        nblks--;
  499. X    }
  500. X    /*
  501. X     * Add new memory allocated to that on
  502. X     * free list for this hash bucket.
  503. X     */
  504. X    nextf[bucket] = op;
  505. X    siz = 1 << (bucket + 3);
  506. X    while (--nblks > 0) {
  507. X        op->ov_next = (union overhead *)((caddr_t)op + siz);
  508. X        op = (union overhead *)((caddr_t)op + siz);
  509. X    }
  510. }
  511. X
  512. void
  513. free(cp)
  514. X    char *cp;
  515. {   
  516. X    register int size;
  517. X    register union overhead *op;
  518. X
  519. X    if (cp == NULL || debug > 4)
  520. X        return;
  521. X    op = (union overhead *)((caddr_t)cp - sizeof (union overhead));
  522. X    if (op->ov_magic != MAGIC) {
  523. X        Debug("%s free() ignored\n",
  524. X            op->ov_magic == OLDMAGIC ? "Duplicate" : "Bad");
  525. X        return;                /* sanity */
  526. X    }
  527. X    op->ov_magic = OLDMAGIC;
  528. #ifdef RCHECK
  529. X    if (op->ov_rmagic != RMAGIC) {
  530. X        Debug("Range check failed, free() ignored\n");
  531. X        return;
  532. X    }
  533. X    if (op->ov_index <= 13 &&
  534. X        *(u_int *)((caddr_t)op + op->ov_size + 1 - RSLOP) != RMAGIC) {
  535. X        Debug("Range check failed, free() ignored\n");
  536. X        return;
  537. X    }
  538. #endif /* RCHECK */
  539. X    if (op->ov_index >= NBUCKETS)
  540. X        return;
  541. X    size = op->ov_index;
  542. X    op->ov_next = nextf[size];
  543. X    nextf[size] = op;
  544. #ifdef MSTATS
  545. X    nmalloc[size]--;
  546. #endif /* MSTATS */
  547. }
  548. X
  549. /*
  550. X * When a program attempts "storage compaction" as mentioned in the
  551. X * old malloc man page, it realloc's an already freed block.  Usually
  552. X * this is the last block it freed; occasionally it might be farther
  553. X * back.  We have to search all the free lists for the block in order
  554. X * to determine its bucket: 1st we make one pass thru the lists
  555. X * checking only the first block in each; if that fails we search
  556. X * ``reall_srchlen'' blocks in each list for a match (the variable
  557. X * is extern so the caller can modify it).  If that fails we just copy
  558. X * however many bytes was given to realloc() and hope it's not huge.
  559. X */
  560. int reall_srchlen = 4;    /* 4 should be plenty, -1 =>'s whole list */
  561. X
  562. char *
  563. realloc(cp, nbytes)
  564. X    char *cp;
  565. X    unsigned nbytes;
  566. {   
  567. X    register u_int onb;
  568. X    union overhead *op;
  569. X    char *res;
  570. X    register int i;
  571. X    int was_alloced = 0;
  572. X
  573. X    if (cp == NULL)
  574. X        return (malloc(nbytes));
  575. X    op = (union overhead *)((caddr_t)cp - sizeof (union overhead));
  576. X    if (op->ov_magic == MAGIC) {
  577. X        was_alloced++;
  578. X        i = op->ov_index;
  579. X    } else {
  580. X        /*
  581. X         * Already free, doing "compaction".
  582. X         *
  583. X         * Search for the old block of memory on the
  584. X         * free list.  First, check the most common
  585. X         * case (last element free'd), then (this failing)
  586. X         * the last ``reall_srchlen'' items free'd.
  587. X         * If all lookups fail, then assume the size of
  588. X         * the memory block being realloc'd is the
  589. X         * smallest possible.
  590. X         */
  591. X        if ((i = findbucket(op, 1)) < 0 &&
  592. X            (i = findbucket(op, reall_srchlen)) < 0)
  593. X            i = 0;
  594. X    }
  595. X    onb = (1 << (i + 3)) - sizeof (*op) - RSLOP;
  596. #ifdef RCHECK
  597. X    /* There's something wrong with the "onb" size computation, above,
  598. X     * when RCHECK is defined.  If you see this comment and can figure
  599. X     * out exactly how "onb" is being used here, let me know.  Bart.
  600. X     */
  601. X    if (was_alloced) {
  602. X        free(cp);    /* Hack so there's some chance res == cp */
  603. X        was_alloced = 0;
  604. X    }
  605. #else /* RCHECK */
  606. X    /* avoid the copy if same size block */
  607. X    if (was_alloced &&
  608. X        nbytes <= onb && nbytes > (onb >> 1) - sizeof(*op) - RSLOP)
  609. X        return(cp);
  610. #endif /* RCHECK */
  611. X    if ((res = malloc(nbytes)) == NULL)
  612. X        return (NULL);
  613. X    if (cp != res)            /* common optimization */
  614. X        bcopy(cp, res, (nbytes < onb) ? nbytes : onb);
  615. X    if (was_alloced)
  616. X        free(cp);
  617. X    return (res);
  618. }
  619. X
  620. /*
  621. X * Search ``srchlen'' elements of each free list for a block whose
  622. X * header starts at ``freep''.  If srchlen is -1 search the whole list.
  623. X * Return bucket number, or -1 if not found.
  624. X */
  625. static
  626. findbucket(freep, srchlen)
  627. X    union overhead *freep;
  628. X    int srchlen;
  629. {
  630. X    register union overhead *p;
  631. X    register int i, j;
  632. X
  633. X    for (i = 0; i < NBUCKETS; i++) {
  634. X        j = 0;
  635. X        for (p = nextf[i]; p && j != srchlen; p = p->ov_next) {
  636. X            if (p == freep)
  637. X                return (i);
  638. X            j++;
  639. X        }
  640. X    }
  641. X    return (-1);
  642. }
  643. X
  644. #ifdef MSTATS
  645. /*
  646. X * mstats - print out statistics about malloc
  647. X * 
  648. X * Prints two lines of numbers, one showing the length of the free list
  649. X * for each size category, the second showing the number of mallocs -
  650. X * frees for each size category.
  651. X */
  652. mstats(s)
  653. X    char *s;
  654. {
  655. X    register int i, j;
  656. X    register union overhead *p;
  657. X    int totfree = 0,
  658. X    totused = 0;
  659. X
  660. X    Debug("Memory allocation statistics %s\nfree:\t", s);
  661. X    for (i = 0; i < NBUCKETS; i++) {
  662. X        for (j = 0, p = nextf[i]; p; p = p->ov_next, j++)
  663. X            ;
  664. X        Debug(" %d", j);
  665. X        totfree += j * (1 << (i + 3));
  666. X    }
  667. X    Debug("\nused:\t");
  668. X    for (i = 0; i < NBUCKETS; i++) {
  669. X        Debug( " %d", nmalloc[i]);
  670. X        totused += nmalloc[i] * (1 << (i + 3));
  671. X    }
  672. X    Debug("\n\tTotal in use: %d, total free: %d\n",
  673. X        totused, totfree);
  674. }
  675. #endif /* MSTATS */
  676. X
  677. /* End of modified perl malloc.c */
  678. X
  679. char *
  680. calloc(nitems, itemsz)
  681. u_int nitems, itemsz;
  682. {
  683. X    char *cp;
  684. X
  685. X    cp = malloc(nitems * itemsz);
  686. X    bzero(cp, nitems * itemsz);
  687. X    return cp;
  688. }
  689. X
  690. /* These are needed for curses and other external linkage */
  691. X
  692. #undef free
  693. X
  694. char *
  695. cfree(p, n, s)
  696. char *p;
  697. u_int n, s;
  698. {
  699. X    xfree(p);
  700. X    return NULL;
  701. }
  702. X
  703. char *
  704. free(p)
  705. char *p;
  706. {
  707. X    xfree(p);
  708. X    return NULL;
  709. }
  710. X
  711. #else /* INTERNAL_MALLOC */
  712. X
  713. char *stackbottom;    /* set first thing in main() */
  714. X
  715. void
  716. xfree(cp)
  717. char *cp;
  718. {
  719. X    extern char end[];
  720. X
  721. X    if (cp && cp >= end && cp < stackbottom && cp < (char *) &cp && debug < 5)
  722. X    free(cp);
  723. }
  724. X
  725. #endif /* INTERNAL_MALLOC */
  726. X
  727. void
  728. free_elems(argv)
  729. char **argv;
  730. {
  731. X    register int n;
  732. X
  733. X    if (!argv)
  734. X    return;
  735. X    for (n = 0; argv[n]; n++)
  736. X    xfree(argv[n]);
  737. }
  738. X
  739. void
  740. free_vec(argv)
  741. char **argv;
  742. {
  743. X    free_elems(argv);
  744. X    xfree((char *)argv);
  745. }
  746. SHAR_EOF
  747. chmod 0600 malloc.c ||
  748. echo 'restore of malloc.c failed'
  749. Wc_c="`wc -c < 'malloc.c'`"
  750. test 11289 -eq "$Wc_c" ||
  751.     echo 'malloc.c: original size 11289, current size' "$Wc_c"
  752. rm -f _shar_wnt_.tmp
  753. fi
  754. # ============= misc.c ==============
  755. if test -f 'misc.c' -a X"$1" != X"-c"; then
  756.     echo 'x - skipping misc.c (File already exists)'
  757.     rm -f _shar_wnt_.tmp
  758. else
  759. > _shar_wnt_.tmp
  760. echo 'x - extracting misc.c (Text)'
  761. sed 's/^X//' << 'SHAR_EOF' > 'misc.c' &&
  762. /* @(#)misc.c    (c) copyright 10/18/86 (Dan Heller) */
  763. X
  764. #include "mush.h"
  765. X
  766. /* check to see if a string describes a message that is within the range of
  767. X * all messages; if invalid, return 0 and print error. else return msg number
  768. X */
  769. chk_msg(s)
  770. register char *s;
  771. {
  772. X    register int n;
  773. X
  774. X    if ((n = atoi(s)) > 0 && n <= msg_cnt)
  775. X    return n;
  776. X    else if (*s == '^' && msg_cnt)
  777. X    return 1;
  778. X    else if (*s == '$' && msg_cnt)
  779. X    return msg_cnt;
  780. X    else if (*s == '.' && msg_cnt)
  781. X    return current_msg+1;
  782. X    print("Invalid message number: %s\n", s);
  783. X    return 0;
  784. }
  785. X
  786. /*
  787. X * loop thru all msgs starting with current_msg and find next undeleted and
  788. X * unsaved message.  If the variable "wrap" is set, wrap to the beginning of
  789. X * the message list if we hit the end.  otherwise, stop at the end of the list.
  790. X */
  791. next_msg()
  792. {
  793. X    register int n = current_msg;
  794. X    register int wrap = !!do_set(set_options, "wrap") ||
  795. X    istool && !do_set(set_options, "show_deleted");
  796. X
  797. X    if (!msg_cnt)
  798. X    return current_msg = 0;
  799. X    for (n++; n != current_msg; n++)
  800. X    if (n == msg_cnt)     /* hit the end, start back at the beginning */
  801. X        if (!wrap)
  802. X        return current_msg;
  803. X        else
  804. X        n = -1; /* increments to 0 in  loop  */
  805. X    else if (isoff(msg[n].m_flags, DELETE) &&
  806. X         isoff(msg[n].m_flags, SAVED))
  807. X        return current_msg = n;
  808. X    return current_msg = 0;
  809. }
  810. X
  811. /* since print_help just prints help, always return help() */
  812. print_help(argc, argv)
  813. register char **argv;
  814. {
  815. X    int about = (argv && *argv && **argv == 'a');
  816. X
  817. X    if (!argc || !*++argv)
  818. X    return help(0, about? "about": "general", cmd_help);
  819. X    if (argv[0][0] == '-')
  820. X    return help(0, about? "about": "help", cmd_help);
  821. X    return help(0, *argv, cmd_help);
  822. }
  823. X
  824. /* since this function does not affect messages, return -1 */
  825. /*ARGSUSED*/
  826. help(unused, str, file)
  827. char *str, *file;
  828. {
  829. X    register char    *p, **text = (char **)str;
  830. X    char        buf[BUFSIZ], help_str[32];
  831. X    FILE        *fp;
  832. X
  833. X    /* If no file given, take "str" arg as message to print */
  834. X    if (!file || !*file) {
  835. #ifdef SUNTOOL
  836. #ifdef SUN_4_0 /* SunOS 4.0+ */
  837. X    /* SunOS 3.5 doesn't have enough file descriptors */
  838. X    turnon(glob_flags, NEW_FRAME);
  839. #endif /* SUN_4_0 */
  840. X    strdup(more_prompt, "help");
  841. #endif /* SUNTOOL */
  842. X    /* use the pager on the args to the function */
  843. X    (void) do_pager(NULL, TRUE);
  844. X    while (*text) {
  845. X        (void) do_pager(*text++, FALSE);
  846. X        if (do_pager("\n", FALSE) == EOF)
  847. X        break;
  848. X    }
  849. X    (void) do_pager(NULL, FALSE);
  850. X    return 0;
  851. X    } else {
  852. X    int d = 0;
  853. X    if ((p = getpath(file, &d)) && d == 0) {
  854. X        if (!(fp = fopen(p, "r"))) {
  855. X        print("Cannot open help file \"%s\".\n", p);
  856. X        return -1;
  857. X        }
  858. X    } else {
  859. X        if (d < 0)
  860. X        print("Cannot open help file \"%s\": %s\n", file, p);
  861. X        else
  862. X        print("Help file \"%s\" is a directory?!?\n", p);
  863. X        return -1;
  864. X    }
  865. X    }
  866. X
  867. X    /* look for %str% in helpfile */
  868. X    (void) sprintf(help_str, "%%%s%%\n", str);
  869. X
  870. X    while (p = fgets(buf, sizeof buf, fp))
  871. X    if (*p == '%' && !strcmp(p, help_str))
  872. X        break;
  873. X    if (!p)
  874. X    print("There is no help found for \"%s\".\n", (char *)str);
  875. X    else {
  876. #ifdef SUNTOOL
  877. #ifdef SUN_4_0 /* SunOS 4.0+ */
  878. X    /* SunOS 3.5 doesn't have enough file descriptors */
  879. X    turnon(glob_flags, NEW_FRAME);
  880. #endif /* SUN_4_0 */
  881. X    strdup(more_prompt, sprintf(buf, "%s help", (char *)str));
  882. #endif /* SUNTOOL */
  883. X    (void) do_pager(NULL, TRUE);
  884. X    while ((p = fgets(buf, sizeof buf, fp)) && strcmp(p, "%%\n"))
  885. X        if (do_pager(buf, FALSE) == EOF)
  886. X        break;
  887. X    (void) do_pager(NULL, FALSE);
  888. X    }
  889. X    (void) fclose(fp);
  890. X
  891. X    return 0;
  892. }
  893. X
  894. /* return -1 on error or number of arguments in argv that were parsed */
  895. get_msg_list(argv, list)
  896. register char **argv;
  897. char list[];
  898. {
  899. X    register char *p2, *p, *end, ch;
  900. X    char buf[BUFSIZ];
  901. X    register int n;
  902. X
  903. X    if (!msg_cnt) {
  904. X    print("No messages.\n");
  905. X    return -1;
  906. X    }
  907. X    if (!argv || !*argv) {
  908. X    if (isoff(glob_flags, IS_PIPE))
  909. X        set_msg_bit(list, current_msg);
  910. X    return 0;
  911. X    }
  912. X    /* first, stuff argv's args into a single char array buffer */
  913. X    (void) argv_to_string(buf, argv);
  914. X    p = buf;
  915. X
  916. X    Debug("get_msg_list: parsing: (%s): ", p);
  917. X    /* find the end of the message list */
  918. X    skipmsglist(0);
  919. X    end = p;
  920. X    while (*end && end != buf && !isspace(*end))
  921. X    --end;
  922. X    ch = *end, *end = '\0'; /* temporarily plug with nul */
  923. X    p = buf; /* reset to the beginning */
  924. X    /*
  925. X     * if do_range returns NULL, an invalid message was specified
  926. X     */
  927. X    if (!(p2 = do_range(p, list))) {
  928. X    *end = ch; /* just in case */
  929. X    return -1;
  930. X    }
  931. X    /*
  932. X     * if p2 == p (and p isn't $ or ^ or .), then no message list was
  933. X     * specified.  set the current message in such cases if we're not piping
  934. X     */
  935. X    if (p2 == p) {
  936. X    if (*p == '$')
  937. X        set_msg_bit(list, msg_cnt-1);
  938. X    else if (*p == '^')
  939. X        set_msg_bit(list, 0);
  940. X    else if (*p == '.' || isoff(glob_flags, IS_PIPE))
  941. X        set_msg_bit(list, current_msg);
  942. X    }
  943. X    for (n = 0; p2 > p && *argv; n++)
  944. X    p2 -= (strlen(*argv++)+1);
  945. X    Debug("parsed %d args\n", n);
  946. X    *end = ch;
  947. X    return n;
  948. }
  949. X
  950. /*
  951. X * execute a command from a string.  f'rinstance: "pick -f foobar"
  952. X * The string is made into an argv and then run.  Errors are printed
  953. X * if the command failed to make.
  954. X * NOTES:
  955. X *   NEVER pass straight text: e.g. "pick -f foobar", ALWAYS strcpy(buf, "...")
  956. X *   no history is expanded (ignore_bang).
  957. X */
  958. cmd_line(buf, list)
  959. char buf[], list[];
  960. {
  961. X    register char **argv;
  962. X    int argc, ret_val = -1;
  963. X    u_long save_do_pipe = ison(glob_flags, DO_PIPE);
  964. X    u_long save_is_pipe = ison(glob_flags, IS_PIPE);
  965. X    char dummy_list[MAXMSGS_BITS];
  966. X
  967. X    turnoff(glob_flags, DO_PIPE);
  968. X    turnoff(glob_flags, IS_PIPE);
  969. X    if (argv = make_command(buf, TRPL_NULL, &argc))
  970. X    ret_val = do_command(argc, argv, list? list : dummy_list);
  971. X    if (save_do_pipe)
  972. X    turnon(glob_flags, DO_PIPE);
  973. X    else
  974. X    turnoff(glob_flags, DO_PIPE);
  975. X    if (save_is_pipe)
  976. X    turnon(glob_flags, IS_PIPE);
  977. X    else
  978. X    turnoff(glob_flags, IS_PIPE);
  979. X    return ret_val;
  980. }
  981. X
  982. glob_test(s)
  983. char *s;
  984. {
  985. X    print("%s: glob_flags =", s);
  986. X    if (ison(glob_flags, DO_UPDATE))
  987. X    print_more(" DO_UPDATE");
  988. X    if (ison(glob_flags, REV_VIDEO))
  989. X    print_more(" REV_VIDEO");
  990. X    if (ison(glob_flags, CONT_PRNT))
  991. X    print_more(" CONT_PRNT");
  992. X    if (ison(glob_flags, DO_SHELL))
  993. X    print_more(" DO_SHELL");
  994. X    if (ison(glob_flags, DO_PIPE))
  995. X    print_more(" DO_PIPE");
  996. X    if (ison(glob_flags, IS_PIPE))
  997. X    print_more(" IS_PIPE");
  998. X    if (ison(glob_flags, IGN_SIGS))
  999. X    print_more(" IGN_SIGS");
  1000. X    if (ison(glob_flags, IGN_BANG))
  1001. X    print_more(" IGN_BANG");
  1002. X    if (ison(glob_flags, ECHO_FLAG))
  1003. X    print_more(" ECHO_FLAG");
  1004. X    if (ison(glob_flags, IS_GETTING))
  1005. X    print_more(" IS_GETTING");
  1006. X    if (ison(glob_flags, PRE_CURSES))
  1007. X    print_more(" PRE_CURSES");
  1008. X    if (ison(glob_flags, READ_ONLY))
  1009. X    print_more(" READ_ONLY");
  1010. X    if (ison(glob_flags, REDIRECT))
  1011. X    print_more(" REDIRECT");
  1012. X    if (ison(glob_flags, WAS_INTR))
  1013. X    print_more(" WAS_INTR");
  1014. X    if (ison(glob_flags, WARNING))
  1015. X    print_more(" WARNING");
  1016. X    if (ison(glob_flags, NEW_MAIL))
  1017. X    print_more(" NEW_MAIL");
  1018. X    if (ison(glob_flags, CNTD_CMD))
  1019. X    print_more(" CNTD_CMD");
  1020. X    if (ison(glob_flags, IS_SENDING))
  1021. X    print_more(" IS_SENDING");
  1022. X    if (ison(glob_flags, MIL_TIME))
  1023. X    print_more(" MIL_TIME");
  1024. X    if (ison(glob_flags, DATE_RECV))
  1025. X    print_more(" DATE_RECV");
  1026. X    if (ison(glob_flags, IN_MACRO))
  1027. X    print_more(" IN_MACRO");
  1028. X    if (ison(glob_flags, LINE_MACRO))
  1029. X    print_more(" LINE_MACRO");
  1030. X    if (ison(glob_flags, QUOTE_MACRO))
  1031. X    print_more(" QUOTE_MACRO");
  1032. X    print_more("\n");
  1033. }
  1034. X
  1035. /*
  1036. X * Change the status flags for messages.
  1037. X *    flags +r        add the replied-to flag to the current message.
  1038. X *    flags -S 4-7    remove the "saved" status on msgs 4-7
  1039. X *    flags P *        preserves all messages.
  1040. X * The + implies: add this flag to the current message's flag bits
  1041. X * The - implies: delete this flag to the current message's flag bits
  1042. X * No + or - implies that the msg's flag bits are set explicitly.
  1043. X * Marks and priorities are preserved in the m_flags field despite
  1044. X * what we're doing here.  Thus, other actions taken by this function
  1045. X * do not affect marks and priorities.
  1046. X */
  1047. msg_flags(c, v, list)
  1048. register char **v, *list;
  1049. {
  1050. X    register int    i = 0, modify = 0, had_list = 0;
  1051. X    register u_long    newflag = 0;
  1052. X    char        sent[32], recv[32];
  1053. X
  1054. X    while (v && *v && *++v)
  1055. X    for (c = 0; v && v[0] && v[0][c]; c++)
  1056. X        switch (lower(v[0][c])) {
  1057. X        case '?' : return help(0, "msg_flags", cmd_help);
  1058. X        case 'n' : turnon(newflag, UNREAD), turnoff(newflag, OLD);
  1059. X        when 'd' : turnon(newflag, DELETE);
  1060. X        when 'p' :
  1061. X            if (v[0][c] == 'P')
  1062. X            turnon(newflag, PRESERVE);
  1063. X            else
  1064. X            turnon(newflag, PRINTED);
  1065. X        when 's' : turnon(newflag, SAVED);
  1066. X        when 'u' : turnon(newflag, UNREAD); /* fall thru! */
  1067. X        case 'o' : turnon(newflag, OLD);
  1068. X        when 'r' :
  1069. X            if (v[0][c] == 'R')
  1070. X            turnoff(newflag, UNREAD), turnon(newflag, OLD);
  1071. X            else
  1072. X            turnon(newflag, REPLIED);
  1073. X        when 'f' : turnon(newflag, FORWARD);
  1074. X        when '+' : modify = 1;
  1075. X        when '-' : modify = 2;
  1076. X        when '\\' : ; /* skip to the next flag */
  1077. X        otherwise:
  1078. X            if ((i = get_msg_list(v, list)) <= 0) {
  1079. X            print("Unknown flag: %c.  Use flags -? for help\n",
  1080. X                v[0][c]);
  1081. X            return -1;
  1082. X            } else {
  1083. X            /* advance argv passed the msg-list */
  1084. X            v += i;
  1085. X            /* c will get ++'ed, so it should be 0 */
  1086. X            c = -1;
  1087. X            /* record that we have seen a message list */
  1088. X            had_list = 1;
  1089. X            }
  1090. X        }
  1091. X
  1092. X    /* If we haven't got a msglist, use current_msg */
  1093. X    if (had_list == 0 && isoff(glob_flags, IS_PIPE))
  1094. X    set_msg_bit(list, current_msg);
  1095. X
  1096. X    for (i = 0; i < msg_cnt; i++) {
  1097. X    if (!msg_bit(list, i))
  1098. X        continue;
  1099. X    else if (!newflag) {
  1100. X        wprint("msg %d: offset: %d, lines: %d, bytes: %d, flags:", i+1,
  1101. X        msg[i].m_offset, msg[i].m_lines, msg[i].m_size);
  1102. X        if (ison(msg[i].m_flags, UNREAD))
  1103. X        wprint(" UNREAD");
  1104. X        if (ison(msg[i].m_flags, OLD))
  1105. X        wprint(" OLD");
  1106. X        if (ison(msg[i].m_flags, DELETE))
  1107. X        wprint(" DELETE");
  1108. X        if (ison(msg[i].m_flags, PRESERVE))
  1109. X        wprint(" PRESERVE");
  1110. X        if (ison(msg[i].m_flags, REPLIED))
  1111. X        wprint(" REPLIED");
  1112. X        if (ison(msg[i].m_flags, SAVED))
  1113. X        wprint(" SAVED");
  1114. X        if (ison(msg[i].m_flags, PRINTED))
  1115. X        wprint(" PRINTED");
  1116. X        if (ison(msg[i].m_flags, FORWARD))
  1117. X        wprint(" FORWARD");
  1118. X        if (ison(msg[i].m_flags, UPDATE_STATUS))
  1119. X        wprint(" UPDATE_STATUS");
  1120. X        for (modify = MAX_PRIORITY; modify > 0; modify--)
  1121. X        if (ison(msg[i].m_flags, M_PRIORITY(modify)))
  1122. X            wprint(" %c", 'A' + modify - 1);
  1123. X        (void) strcpy(sent, date_to_ctime(msg[i].m_date_sent));
  1124. X        (void) strcpy(recv, date_to_ctime(msg[i].m_date_recv));
  1125. X        wprint("\n\tsent: %s\trecv: %s", sent, recv);
  1126. X    } else {
  1127. X        u_long save_priority = 0L;
  1128. X        if (modify == 0) {
  1129. X        int j;
  1130. X        for (j = 0; j < MAX_PRIORITY; j++)
  1131. X            if (ison(msg[i].m_flags, M_PRIORITY(j)))
  1132. X            turnon(save_priority, M_PRIORITY(j));
  1133. X        }
  1134. X        switch (modify) {
  1135. X        case 0: msg[i].m_flags = newflag;
  1136. X        when 1: msg[i].m_flags |= newflag;
  1137. X        when 2: msg[i].m_flags &= ~newflag;
  1138. X        }
  1139. X        if (save_priority)
  1140. X        msg[i].m_flags |= save_priority;
  1141. X        if (isoff(glob_flags, READ_ONLY)) {
  1142. X        turnon(glob_flags, DO_UPDATE);
  1143. X        turnon(msg[i].m_flags, DO_UPDATE);
  1144. X        }
  1145. X    }
  1146. X    }
  1147. X    return 0;
  1148. }
  1149. X
  1150. /*
  1151. X * Internal pager.  Start the internal pager by passing the name of
  1152. X * the pager in buf and passing TRUE as start_pager. If the internal
  1153. X * pager is desired, pass NULL as buf.  Continue paging by passing
  1154. X * FALSE as start_pager and the buf is the stuff to pass thru to the
  1155. X * pager.  End paging by passing NULL as buf and FALSE as start_pager.
  1156. X * start_pager actually has a ternary value -- for use by pipe_msg.
  1157. X * If the pager can't be used, or is null, we're paging ourselves.
  1158. X * Windows does nothing but echo buf to the msg window (this will change).
  1159. X * The "buf" passed to the pager should be a line at a time so as to
  1160. X * count \n's.  If there is more than one newline, the first one is nulled
  1161. X * and the next line done by calling do_pager recursively.  WARNING: because
  1162. X * "buf" is changed, it is *illegal* for anyone calling this routine to pass
  1163. X * _constant_ strings --they should be strcpy'ed or sprintf'ed into a temp
  1164. X * buff before passing to this routine!  Otherwise, ANSI-C compilers will
  1165. X * core dump.  This is because constant strings are read-only.
  1166. X * Return EOF if pager died, user exited pager, or if user types 'q'
  1167. X * at the --more-- prompt for the internal pager.
  1168. X *
  1169. X * For windows, copy all the info into a tmpfile and set the pager_textsw
  1170. X * to that file.  When the pager ends, delete the file -- textsw will
  1171. X * continue to read it since it does its own buffering.
  1172. X */
  1173. do_pager(buf, start_pager)
  1174. char *buf;
  1175. {
  1176. X    static FILE *pp;
  1177. X    static int cnt, len;
  1178. X    static u_long save_echo_flag;
  1179. #ifdef SUNTOOL
  1180. X    static char file[MAXPATHLEN];
  1181. X    static Textsw sw;
  1182. X
  1183. X    /* pipe_msg will pass -1 for start_pager to avoid this block */
  1184. X    if (start_pager > -1 && istool) {
  1185. X    if (buf && !start_pager) {
  1186. X        if (istool < 2) /* can't use windows yet -- send to stdout */
  1187. X        (void) fputs(buf, stdout);
  1188. X        else {
  1189. X        if (pp)
  1190. X            fputs(buf, pp);
  1191. X        else
  1192. X            textsw_insert(isoff(glob_flags, NEW_FRAME)?
  1193. X            pager_textsw : sw, buf, strlen(buf));
  1194. X        }
  1195. X    } else if (istool >= 2 && start_pager) {
  1196. X        Frame text_frame;
  1197. X        extern char *more_prompt;
  1198. X        char *p;
  1199. X
  1200. X        timeout_cursors(TRUE);
  1201. X        if (ison(glob_flags, NEW_FRAME)) {
  1202. X        char *crt_win = do_set(set_options, "crt_win");
  1203. X        text_frame = window_create(tool, FRAME,
  1204. X            FRAME_SHOW_LABEL,    TRUE,
  1205. X            FRAME_LABEL,    more_prompt,
  1206. X            WIN_HEIGHT,        l_height()*(crt_win? atoi(crt_win):12),
  1207. X            NULL);
  1208. X        sw = window_create(text_frame, TEXTSW,
  1209. X            TEXTSW_LINE_BREAK_ACTION,    TEXTSW_WRAP_AT_CHAR,
  1210. X            TEXTSW_CLIENT_DATA,        text_frame,
  1211. X            NULL);
  1212. X        notify_interpose_event_func(sw, scroll_textwin, NOTIFY_SAFE);
  1213. X        } else
  1214. X        textsw_reset(pager_textsw, 0, 0);
  1215. X
  1216. X        /* find a free tmpfile */
  1217. X        if (!(p = getdir(do_set(set_options, "tmpdir"))))
  1218. alted:
  1219. X        p = ALTERNATE_HOME;
  1220. X        {
  1221. X        int pid = getpid();
  1222. X        do
  1223. X            sprintf(file, "%s/..X%d", p, pid++);
  1224. X        while (!Access(file, F_OK));
  1225. X        }
  1226. X        if (!(pp = mask_fopen(file, "w"))) {
  1227. X        if (strcmp(p, ALTERNATE_HOME))
  1228. X            goto alted;
  1229. X        error("Can't create '%s'", tempfile);
  1230. X        }
  1231. X        return 0;
  1232. X    } else if (!buf && !start_pager) { /* pager is done */
  1233. X        if (pp)
  1234. X        (void) fclose(pp);
  1235. X        window_set(isoff(glob_flags, NEW_FRAME)? pager_textsw : sw,
  1236. X        TEXTSW_FILE,        file,
  1237. X        TEXTSW_READ_ONLY,    TRUE,
  1238. X        TEXTSW_UPDATE_SCROLLBAR,
  1239. X        NULL);
  1240. X        if (ison(glob_flags, NEW_FRAME)) {
  1241. X        turnoff(glob_flags, NEW_FRAME);
  1242. X        window_set(window_get(sw, TEXTSW_CLIENT_DATA),
  1243. X            WIN_SHOW,        TRUE,
  1244. X            FRAME_NO_CONFIRM,    TRUE,
  1245. X            FRAME_DONE_PROC,    window_destroy,
  1246. X            NULL);
  1247. X        }
  1248. X        if (unlink(file) == -1)
  1249. X        error("Cannot unlink %s", file);
  1250. X        timeout_cursors(FALSE);
  1251. X    }
  1252. X    return 0;
  1253. X    }
  1254. #endif /* SUNTOOL */
  1255. X
  1256. X    if (start_pager) {
  1257. X    turnon(glob_flags, IGN_SIGS);
  1258. X    if (!buf) {
  1259. X        /* internal pager */
  1260. X        save_echo_flag = ison(glob_flags, ECHO_FLAG);
  1261. X        pp = stdout;
  1262. X        if (save_echo_flag) {
  1263. X        turnoff(glob_flags, ECHO_FLAG);
  1264. X        echo_off();
  1265. X        }
  1266. X    } else {
  1267. X        echo_on();
  1268. X        if (!(pp = popen(buf, "w")))
  1269. X        error(buf);
  1270. X    }
  1271. X    cnt = len = 0;
  1272. X    } else if (!buf) {
  1273. X    if (pp && pp != stdout)
  1274. X        (void) pclose(pp);
  1275. X    pp = NULL_FILE;
  1276. X    if (save_echo_flag) {
  1277. X        echo_on();
  1278. X        turnon(glob_flags, ECHO_FLAG);
  1279. X    } else
  1280. X        echo_off();
  1281. X    turnoff(glob_flags, IGN_SIGS);
  1282. X    } else if (pp != stdout)
  1283. X    return fputs(buf, pp); /* returns EOF if user exited pager */
  1284. X    else {
  1285. X    register char c = 0, *cr = index(buf, '\n');
  1286. X    len += strlen(buf);
  1287. X    if (cr) {
  1288. X        int maxlen =
  1289. #ifdef CURSES
  1290. X        iscurses ? COLS :
  1291. #endif /* CURSES */
  1292. X        80;
  1293. X        if (len > maxlen)
  1294. X        cnt += len / maxlen;
  1295. X        len = 0;
  1296. X    }
  1297. X    if (cr && (c = *++cr) != '\0')
  1298. X        *cr = 0; /* send one line to stdout and prompt for more */
  1299. X    (void) fputs(buf, pp);
  1300. X    if (cr && (++cnt / (crt-1))) {
  1301. X        int n = c_more(NULL);
  1302. X        if (n == '\n' || n == '\r')
  1303. X        cnt--; /* go line by line */
  1304. X        else if (n == CTRL('D') || lower(n) == 'd' || n < 0) {
  1305. X        clearerr(stdin);
  1306. X        cnt = ((crt-1)/2);
  1307. X        } else if (lower(n) == 'q')
  1308. X        /* could check if "c" is set, but... see warning above */
  1309. X        return EOF;
  1310. X        else
  1311. X        cnt = 1;
  1312. X    }
  1313. X    if (c) {
  1314. X        *cr = c;
  1315. X        return do_pager(cr, FALSE);
  1316. X    }
  1317. X    }
  1318. X    return 0;
  1319. }
  1320. X
  1321. /* curses based "more" like option */
  1322. c_more(p)
  1323. register char *p;
  1324. {
  1325. X    register int c;
  1326. X
  1327. X    if (!p)
  1328. X    p = "--more--";
  1329. X    print_more(p);
  1330. X
  1331. X    while ((c = getchar()) >= 0 && c != CTRL('D') && !isspace(c) &&
  1332. X        c != '\n' && c != '\r' && lower(c) != 'q' && lower(c) != 'd')
  1333. X    bell();
  1334. X    if (ison(glob_flags, ECHO_FLAG) && c != '\n' && c != '\r')
  1335. X    while (getchar() != '\n');
  1336. X    (void) printf("\r%*c\r", strlen(p), ' '); /* remove the prompt */
  1337. X    (void) fflush(stdout);
  1338. X    return c;
  1339. }
  1340. X
  1341. /*
  1342. X * Your "signature" is of the type:
  1343. X *    file_or_path
  1344. X *    $variable
  1345. X *    \ literal string preceded by a backslash.
  1346. X * The variable will be expanded into its string value.
  1347. X * To sign the letter, the list of addresses is passed to this routine
  1348. X * (separated by whitespace and/or commas).  No comment fields!
  1349. X *
  1350. X * If "autosign2" is set, then it must be of the form:
  1351. X *    autosign2 = "*user user !host !some!path @dom.ain: ~/.sign2"
  1352. X *
  1353. X * The colon terminates the user/host lists from the "signature" to the right.
  1354. X *
  1355. X * Whitespace or commas separate tokens.  If everyone on the list exists in
  1356. X * the autosign2 list, the alternate signature is used. In case of syntax
  1357. X * error, the alternate signature is used without checks (e.g. if the colon
  1358. X * is missing).  The alternate signature == null is the same as not signing
  1359. X * the letter. An empty list forces signature2.
  1360. X *
  1361. X * If autosign2 is not set at all, then autosign is checked and used.
  1362. X * autosign = <signature>
  1363. X */
  1364. void
  1365. sign_letter(list, flags, fp)
  1366. register char *list; /* list of addresses -- no comment fields */
  1367. u_long flags;
  1368. FILE *fp;
  1369. {
  1370. X    char buf[MAXPATHLEN], *signature;
  1371. X    register char *p = NULL;
  1372. X    FILE     *pp2;
  1373. X    int     lines = 0, noisy;
  1374. X
  1375. X    if (!list)
  1376. X    return;
  1377. X    while (isspace(*list))
  1378. X    list++;
  1379. X    if (!*list)
  1380. X    return;
  1381. X    if (ison(flags, SIGN)) {
  1382. X    noisy = !chk_option("quiet", "autosign");
  1383. X    if (!(p = do_set(set_options, "autosign2")))
  1384. X        buf[0] = 0;
  1385. X    else {
  1386. X        if (!(signature = index(p, ':')))
  1387. X        (void) strcpy(buf, p); /* No colon; use entire string as sig */
  1388. X        else {
  1389. X        int ret_val = 0;
  1390. X        *signature = 0;
  1391. X        /* p now points to a list of addresses and p2 points to the
  1392. X         * signature format to use. Check that each address in the list
  1393. X         * provided (parameter) matches the "addrs" in autosign2.
  1394. X         */
  1395. X        skipspaces(0);
  1396. X        if (!*p)
  1397. X            /* autosign2 = " : <signature>"  send to all recipients */
  1398. X            ret_val = 1;
  1399. X        else if (p = alias_to_address(p)) {
  1400. X            rm_cmts_in_addr(p);
  1401. X            ret_val = compare_addrs(list, p, NULL);
  1402. X        }
  1403. X        *signature++ = ':'; /* must reset first! */
  1404. X        buf[0] = 0;
  1405. X        if (ret_val) {
  1406. X            while (isspace(*signature))
  1407. X            signature++;
  1408. X            /* Null signatures don't sign anything. */
  1409. X            if (!*strcpy(buf, signature))
  1410. X            return;
  1411. X        }
  1412. X        }
  1413. X    }
  1414. X    if (!buf[0]) {
  1415. X        if (!(p = do_set(set_options, "autosign")) || !*p) {
  1416. X        char *home;
  1417. X        if (!(home = do_set(set_options, "home")) || !*home)
  1418. X            home = ALTERNATE_HOME;
  1419. X        (void) sprintf(buf, "%s/%s", home, SIGNATURE);
  1420. X        } else
  1421. X        (void) strcpy(buf, p);
  1422. X        if (noisy)
  1423. X        wprint("Signing letter... ");
  1424. X    } else if (noisy)
  1425. X        wprint("Using alternate signature... ");
  1426. X    (void) fseek(fp, 0L, 2); /* guarantee position at end of file */
  1427. X    (void) fputc('\n', fp);
  1428. X    (void) fflush(fp);
  1429. X    if (*buf == '$')
  1430. X        if (!(p = do_set(set_options, buf)))
  1431. X        wprint("(%s isn't set -- letter not signed)\n", buf);
  1432. X        else {
  1433. X        putstring(p+1, fp);
  1434. X        if (noisy)
  1435. X            wprint("\n");
  1436. X        }
  1437. X    else if (*buf == '\\') {
  1438. X        putstring(buf, fp);
  1439. X        if (noisy)
  1440. X        wprint("\n");
  1441. X    } else if (*buf == '[') {
  1442. X        char *rbr = index(buf, ']');
  1443. X        if (rbr)
  1444. X        *rbr = 0;
  1445. X        putstring(buf + 1, fp);
  1446. X        if (noisy)
  1447. X        wprint("\n");
  1448. X    } else if (*buf == '|' || *buf == '!') {
  1449. X        (void) strcat(buf, " ");
  1450. X        (void) strcat(buf, list);
  1451. X        if (!(pp2 = popen(buf+1, "r")))
  1452. X        error(buf+1);
  1453. X        else {
  1454. X        turnon(glob_flags, IGN_SIGS);
  1455. X        while (fgets(buf, sizeof(buf), pp2)) {
  1456. X            int len = strlen(buf);
  1457. X            (void) fputs(buf, fp), lines++;
  1458. X            if (len < sizeof buf - 1 && buf[len - 1] != '\n')
  1459. X            (void) fputc('\n', fp);
  1460. X        }
  1461. X        (void) pclose(pp2);
  1462. X        (void) fflush(fp);
  1463. X        turnoff(glob_flags, IGN_SIGS);
  1464. X        if (noisy)
  1465. X            wprint("added %d line%s\n", lines, lines == 1? "" : "s");
  1466. X        }
  1467. X    } else {
  1468. X        /* precede _file_ signatures ONLY with "-- \n" */
  1469. X        (void) fputs("-- \n", fp);
  1470. X        (void) fflush(fp);
  1471. X        (void) file_to_fp(buf, fp, "r");
  1472. X    }
  1473. X    }
  1474. X
  1475. X    (void) fflush(stdout); /* for sys-v and older xenix */
  1476. X
  1477. X    /* if fortune is set, check to see if fortunates is set. If so,
  1478. X     * check to see if all the recipient are on the fortunates list.
  1479. X     */
  1480. X    if (ison(flags, DO_FORTUNE)) {
  1481. X    noisy = !chk_option("quiet", "fortune");
  1482. X    if (p = do_set(set_options, "fortunates")) {
  1483. X        if (!(p = alias_to_address(p)))
  1484. X        return; /* no reason to hang around */
  1485. X        rm_cmts_in_addr(p);
  1486. X        if (!compare_addrs(list, p, buf)) {
  1487. X        if (noisy) {
  1488. X            wprint("\"fortunates\" does not contain \"%s\".\n", buf);
  1489. X            wprint("No fortune added.\n");
  1490. X        }
  1491. X        return;
  1492. X        }
  1493. X    }
  1494. X    if (noisy)
  1495. X        wprint("You may be fortunate... ");
  1496. X    if ((p = do_set(set_options, "fortune")) && *p == '/')
  1497. X        (void) strcpy(buf, p);
  1498. X    else
  1499. X        (void) sprintf(buf, "%s %s", FORTUNE, (p && *p == '-')? p: "-s");
  1500. X    if (!(pp2 = popen(buf, "r")))
  1501. X        error(buf);
  1502. X    else {
  1503. X        turnon(glob_flags, IGN_SIGS);
  1504. X        (void) fseek(fp, 0L, 2); /* go to end of file */
  1505. X        while (fgets(buf, sizeof(buf), pp2))
  1506. X        (void) fputs(buf, fp), lines++;
  1507. X        (void) pclose(pp2);
  1508. X        turnoff(glob_flags, IGN_SIGS);
  1509. X        (void) fflush(fp);
  1510. X        if (noisy)
  1511. X        wprint("added %d line%s\n", lines, lines == 1? "" : "s");
  1512. X    }
  1513. X    }
  1514. X    (void) fflush(stdout); /* for sys-v and older xenix */
  1515. }
  1516. X
  1517. X
  1518. /* return -1 since function doesn't affect messages */
  1519. check_flags(flags)
  1520. u_long flags;
  1521. {
  1522. X    print_more(" ");
  1523. X    if (ison(flags, VERBOSE))
  1524. X    print_more("VERBOSE ");
  1525. X    if (ison(flags, INCLUDE))
  1526. X    print_more("INCLUDE ");
  1527. X    if (ison(flags, INCLUDE_H))
  1528. X    print_more("INCLUDE_H ");
  1529. X    if (ison(flags, EDIT))
  1530. X    print_more("EDIT ");
  1531. X    if (ison(flags, SIGN))
  1532. X    print_more("SIGN ");
  1533. X    if (ison(flags, DO_FORTUNE))
  1534. X    print_more("DO_FORTUNE ");
  1535. X    if (ison(flags, NO_HEADER))
  1536. X    print_more("NO_HEADER ");
  1537. X    if (ison(flags, DELETE))
  1538. X    print_more("DELETE ");
  1539. X    if (ison(flags, OLD))
  1540. X    print_more("OLD ");
  1541. X    if (ison(flags, UNREAD))
  1542. X    print_more("UNREAD ");
  1543. X    if (ison(flags, UPDATE_STATUS))
  1544. X    print_more("UPDATE_STATUS ");
  1545. X    if (ison(flags, NO_PAGE))
  1546. X    print_more("NO_PAGE ");
  1547. X    if (ison(flags, INDENT))
  1548. X    print_more("INDENT ");
  1549. X    if (ison(flags, NO_IGNORE))
  1550. X    print_more("NO_IGNORE ");
  1551. X    if (ison(flags, PRESERVE))
  1552. X    print_more("PRESERVE ");
  1553. X    print_more("\n");
  1554. X    return -1;
  1555. }
  1556. SHAR_EOF
  1557. chmod 0644 misc.c ||
  1558. echo 'restore of misc.c failed'
  1559. Wc_c="`wc -c < 'misc.c'`"
  1560. test 22738 -eq "$Wc_c" ||
  1561.     echo 'misc.c: original size 22738, current size' "$Wc_c"
  1562. rm -f _shar_wnt_.tmp
  1563. fi
  1564. # ============= misc_frame.c ==============
  1565. if test -f 'misc_frame.c' -a X"$1" != X"-c"; then
  1566.     echo 'x - skipping misc_frame.c (File already exists)'
  1567.     rm -f _shar_wnt_.tmp
  1568. else
  1569. > _shar_wnt_.tmp
  1570. echo 'x - extracting misc_frame.c (Text)'
  1571. sed 's/^X//' << 'SHAR_EOF' > 'misc_frame.c' &&
  1572. /* @(#) misc_frame.c    (c) copyright    9/29/89 (Dan Heller) */
  1573. X
  1574. /*
  1575. X * This file contains several functions which create dialog box frames
  1576. X * for (currently) mail aliases and ignored headers.  Each dialog box
  1577. X * has a list of some kind and a way to add or delete items from the
  1578. X * list.  The list is a textsw which is updated (currently) by do_set().
  1579. X * Public routines:
  1580. X *    update_list_textsw(struct options **) updates the textsw list.
  1581. X *    do_alias()    creates the alias dialog frame box
  1582. X *    do_ignore()    creates the ignored headers dialog frame box
  1583. X */
  1584. X
  1585. #include "mush.h"
  1586. X
  1587. extern Notify_value fkey_interposer();
  1588. X
  1589. /****************** Mail Aliases ********************/
  1590. X
  1591. Frame    alias_frame;
  1592. Panel_item alias_msg, alias_name, alias_value, alias_list_textsw;
  1593. static void set_alias();
  1594. X
  1595. Frame    ignore_frame;
  1596. Panel_item ignore_msg, ignore_name, ignore_list_textsw;
  1597. static Panel_setting set_ignore();
  1598. X
  1599. #define MY_FRAME_WIDTH    600
  1600. X
  1601. static void
  1602. frame_help(item)
  1603. Panel_item item;
  1604. {
  1605. X    (void) help(0, panel_get(item, PANEL_CLIENT_DATA), tool_help);
  1606. }
  1607. X
  1608. void
  1609. update_list_textsw(list)
  1610. struct options **list;
  1611. {
  1612. X    Textsw save = pager_textsw;
  1613. X
  1614. X    if (list == &aliases)
  1615. X    pager_textsw = alias_list_textsw;
  1616. X    else if (list == &ignore_hdr)
  1617. X    pager_textsw = ignore_list_textsw;
  1618. X    else
  1619. X    /* no textsw for this guy yet */
  1620. X    return;
  1621. X
  1622. X    if (pager_textsw && !!window_get(pager_textsw, WIN_SHOW))
  1623. X    (void) do_set(*list, NULL);
  1624. X    pager_textsw = save;
  1625. }
  1626. X
  1627. static void
  1628. alias_done()
  1629. {
  1630. X    window_destroy(alias_frame);
  1631. X    alias_frame = (Frame) 0;
  1632. }
  1633. X
  1634. void
  1635. do_aliases()
  1636. {
  1637. X    Panel    panel;
  1638. X
  1639. X    if (alias_frame) {
  1640. X    window_set(alias_frame, WIN_SHOW, TRUE, NULL);
  1641. X    return;
  1642. X    }
  1643. #ifdef SUN_3_5
  1644. X    if (nopenfiles(0) < 5) {
  1645. X    print("Too many frames; close one first!\n");
  1646. X    return;
  1647. X    }
  1648. #endif /* SUN_3_5 */
  1649. X
  1650. X    alias_frame = window_create(tool, FRAME,
  1651. X    FRAME_SHOW_LABEL,    TRUE,
  1652. X    FRAME_LABEL,        "Mail Aliases",
  1653. X    FRAME_NO_CONFIRM,    TRUE,
  1654. X    FRAME_DONE_PROC,    alias_done,
  1655. X    WIN_SHOW,        TRUE,
  1656. X    WIN_WIDTH,        MY_FRAME_WIDTH,
  1657. X    NULL);
  1658. X
  1659. X    panel = window_create(alias_frame, PANEL,
  1660. X    PANEL_WIDTH,        MY_FRAME_WIDTH,
  1661. X    NULL);
  1662. X    notify_interpose_event_func(panel, fkey_interposer, NOTIFY_SAFE);
  1663. X
  1664. X    panel_create_item(panel, PANEL_BUTTON,
  1665. X    PANEL_LABEL_IMAGE,
  1666. X        panel_button_image(panel, "Help", 4, mush_font),
  1667. X    PANEL_CLIENT_DATA,    "aliases",
  1668. X    PANEL_NOTIFY_PROC,    frame_help,
  1669. X    NULL);
  1670. X    panel_create_item(panel, PANEL_BUTTON,
  1671. X    PANEL_LABEL_IMAGE,
  1672. X        panel_button_image(panel, "Set", 3, mush_font),
  1673. X    PANEL_NOTIFY_PROC,    set_alias,
  1674. X    PANEL_CLIENT_DATA,    TRUE,
  1675. X    NULL);
  1676. X    panel_create_item(panel, PANEL_BUTTON,
  1677. X    PANEL_LABEL_IMAGE,
  1678. X        panel_button_image(panel, "Unset", 5, mush_font),
  1679. X    PANEL_NOTIFY_PROC,    set_alias,
  1680. X    PANEL_CLIENT_DATA,    FALSE,
  1681. X    NULL);
  1682. X
  1683. X    alias_msg = panel_create_item(panel, PANEL_MESSAGE,
  1684. X    PANEL_LABEL_STRING,
  1685. X        "Type name of alias and address list and select <set> or <unset>",
  1686. X    NULL);
  1687. X
  1688. X    alias_name = panel_create_item(panel, PANEL_TEXT,
  1689. X    PANEL_LABEL_STRING,    "Alias Name:",
  1690. X    PANEL_VALUE_DISPLAY_LENGTH, 60,
  1691. X    NULL);
  1692. X    alias_value = panel_create_item(panel, PANEL_TEXT,
  1693. X    PANEL_LABEL_STRING,    "Alias Address(es):",
  1694. X    PANEL_VALUE_DISPLAY_LENGTH, 60,
  1695. X    NULL);
  1696. X    window_fit_height(panel);
  1697. X
  1698. X    alias_list_textsw = window_create(alias_frame, TEXTSW,
  1699. X    WIN_BELOW,            panel,
  1700. X    WIN_WIDTH,            MY_FRAME_WIDTH,
  1701. X    WIN_HEIGHT,            15 * l_height(),
  1702. #ifdef SUN_4_0 /* SunOS 4.0+ */
  1703. X    TEXTSW_LINE_BREAK_ACTION,    TEXTSW_WRAP_AT_WORD,
  1704. #else /* SUN_4_0 */
  1705. X    TEXTSW_LINE_BREAK_ACTION,    TEXTSW_WRAP_AT_CHAR,
  1706. #endif /* SUN_4_0 */
  1707. X    NULL);
  1708. X    (void) notify_interpose_event_func(alias_list_textsw,
  1709. X    fkey_interposer, NOTIFY_SAFE);
  1710. X
  1711. X    window_fit_height(alias_frame);
  1712. X    update_list_textsw(&aliases);
  1713. }
  1714. X
  1715. static void
  1716. set_alias(item)
  1717. Panel_item item;
  1718. {
  1719. X    int argc, set_it = (int)panel_get(item, PANEL_CLIENT_DATA);
  1720. X    char buf[BUFSIZ], **argv, *name, *value;
  1721. X
  1722. X    name = panel_get_value(alias_name);
  1723. X    if (!*name) {
  1724. X    panel_set(alias_msg, PANEL_LABEL_STRING, "Need an alias name.", NULL);
  1725. X    return;
  1726. X    }
  1727. X    if (any(name, " \t")) {
  1728. X    panel_set(alias_msg,
  1729. X        PANEL_LABEL_STRING, "Alias name may not contain spaces.",
  1730. X        NULL);
  1731. X    return;
  1732. X    }
  1733. X    if (set_it) {
  1734. X    value = panel_get_value(alias_value);
  1735. X    if (!*value) {
  1736. X        panel_set(alias_msg,
  1737. X        PANEL_LABEL_STRING, "Specify alias address(es).",
  1738. X        NULL);
  1739. X        return;
  1740. X    }
  1741. X    sprintf(buf, "alias %s %s", name, value);
  1742. X    } else
  1743. X    sprintf(buf, "unalias %s", name);
  1744. X    if (!(argv = mk_argv(buf, &argc, TRUE)) || do_alias(argc, argv) == -1)
  1745. X    panel_set(alias_msg,
  1746. X        PANEL_LABEL_STRING, "Couldn't set alias.",
  1747. X        NULL);
  1748. X    else
  1749. X    panel_set(alias_msg,
  1750. X        PANEL_LABEL_STRING, "",
  1751. X        NULL);
  1752. X    panel_set_value(alias_name, "");
  1753. X    panel_set_value(alias_value, "");
  1754. X    free_vec(argv);
  1755. }
  1756. X
  1757. /* int cuz it's also the callback for the text item */
  1758. static Panel_setting
  1759. set_ignore(item)
  1760. Panel_item item;
  1761. {
  1762. X    int argc, set_it = (int)panel_get(item, PANEL_CLIENT_DATA);
  1763. X    char buf[BUFSIZ], *name, **argv;
  1764. X
  1765. X    name = panel_get_value(ignore_name);
  1766. X    if (!*name) {
  1767. X    panel_set(ignore_msg, PANEL_LABEL_STRING, "Missing header name.", NULL);
  1768. X    return PANEL_NONE;
  1769. X    }
  1770. X    if (set_it)
  1771. X    sprintf(buf, "ignore %s", name);
  1772. X    else
  1773. X    sprintf(buf, "unignore %s", name);
  1774. X    /* set() will call update_list_textsw() */
  1775. X    if (!(argv = mk_argv(buf, &argc, TRUE)) || set(argc, argv, NULL) == -1)
  1776. X    panel_set(ignore_msg,
  1777. X        PANEL_LABEL_STRING, "Internal Error!?",
  1778. X        NULL);
  1779. X    else
  1780. X    panel_set(ignore_msg,
  1781. SHAR_EOF
  1782. true || echo 'restore of misc_frame.c failed'
  1783. fi
  1784. echo 'End of  part 13'
  1785. echo 'File misc_frame.c is continued in part 14'
  1786. echo 14 > _shar_seq_.tmp
  1787. exit 0
  1788. exit 0 # Just in case...
  1789. -- 
  1790. Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
  1791. Sterling Software, IMD           UUCP:     uunet!sparky!kent
  1792. Phone:    (402) 291-8300         FAX:      (402) 291-4362
  1793. Please send comp.sources.misc-related mail to kent@uunet.uu.net.
  1794.