home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume38 / menushll / part03 < prev    next >
Encoding:
Text File  |  1993-07-30  |  32.1 KB  |  1,414 lines

  1. Newsgroups: comp.sources.misc
  2. From: aburt@du.edu (Andrew Burt)
  3. Subject: v38i068:  menushell - A Unix Menuing Shell, Part03/03
  4. Message-ID: <1993Jul30.192633.27986@sparky.sterling.com>
  5. X-Md4-Signature: 8e1464bb85eb0829580bf8f2efc6555f
  6. Sender: kent@sparky.sterling.com (Kent Landfield)
  7. Organization: Sterling Software
  8. Date: Fri, 30 Jul 1993 19:26:33 GMT
  9. Approved: kent@sparky.sterling.com
  10.  
  11. Submitted-by: aburt@du.edu (Andrew Burt)
  12. Posting-number: Volume 38, Issue 68
  13. Archive-name: menushell/part03
  14. Environment: BSD, with untested SVR4 diffs
  15.  
  16. #! /bin/sh
  17. # This is a shell archive.  Remove anything before this line, then feed it
  18. # into a shell via "sh file" or similar.  To overwrite existing files,
  19. # type "sh file -c".
  20. # Contents:  Makefile chdir.c dl.c dl.h functions1.c macro.c mail.c
  21. #   main.c menulogin mshell.c settatr.c xsystem.c
  22. # Wrapped by kent@sparky on Mon Jul 26 16:41:40 1993
  23. PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin ; export PATH
  24. echo If this archive is complete, you will see the following message:
  25. echo '          "shar: End of archive 3 (of 3)."'
  26. if test -f 'Makefile' -a "${1}" != "-c" ; then 
  27.   echo shar: Will not clobber existing file \"'Makefile'\"
  28. else
  29.   echo shar: Extracting \"'Makefile'\" \(713 characters\)
  30.   sed "s/^X//" >'Makefile' <<'END_OF_FILE'
  31. X# Options:
  32. X# define SYSV or BSD in CFLAGS
  33. X# define MENUDIR as the default dir to find menus in (if invoked as
  34. X#    "mshell foo.men", it will look for MENUDIR/foo.men)
  35. X# define LOGDIR as the dir where logs of menu picks will be logged for each
  36. X#    user (as LOGDIR/username)
  37. X# define MAILDIR as the dir to find mail files in (/usr/spool/mail/ by default)
  38. X#
  39. X# Check mshell.h for other options, e.g., max menu sizes.
  40. X
  41. XCFLAGS =  -O -DBSD -DMENUDIR='"/nyx/lib/menus"' -DLOGDIR='"/nyx/lib/logs"'
  42. XOBJS =    mshell.o main.o string.o functions1.o functions2.o chdir.o mail.o \
  43. X    settatr.o setenv.o xsystem.o dl.o macro.o
  44. X
  45. Xmshell: $(OBJS)
  46. X    cc $(CFLAGS) $(OBJS) -lcurses -ltermcap -o mshell
  47. X
  48. X$(OBJS) : mshell.h
  49. X
  50. Xclean:
  51. X    rm *.o mshell
  52. END_OF_FILE
  53.   if test 713 -ne `wc -c <'Makefile'`; then
  54.     echo shar: \"'Makefile'\" unpacked with wrong size!
  55.   fi
  56.   # end of 'Makefile'
  57. fi
  58. if test -f 'chdir.c' -a "${1}" != "-c" ; then 
  59.   echo shar: Will not clobber existing file \"'chdir.c'\"
  60. else
  61.   echo shar: Extracting \"'chdir.c'\" \(749 characters\)
  62.   sed "s/^X//" >'chdir.c' <<'END_OF_FILE'
  63. X#include "mshell.h"
  64. X
  65. Xextern char     G_homevar      [];
  66. Xextern char     G_uservar      [];
  67. Xextern char     G_termvar      [];
  68. Xextern char     G_mailfile     [WORDLEN];
  69. Xextern char     G_mail_message [WORDLEN];
  70. Xextern int      G_mailsize; 
  71. Xextern struct   stat G_st;
  72. X
  73. Xvoid change_directory(new_dir)
  74. Xchar *new_dir;
  75. X
  76. X{
  77. X    char old_dir [MAXLEN]; 
  78. X    int i;
  79. X
  80. X#ifdef BSD
  81. X    getwd (old_dir);
  82. X#endif
  83. X#ifdef SYSV
  84. X    getcwd(old_dir, sizeof(old_dir));
  85. X#endif
  86. X
  87. X    if ( strcmp ( new_dir, NULLSTR ) == 0 )
  88. X        printf ("\t no directory change requested !!\n\n");
  89. X        /* XXX - could cd home */
  90. X    else {
  91. X        printf ("\n\n");
  92. X        if ( chdir (new_dir) != 0 ) 
  93. X            printf ("\t No such directory as %s\n\n\n", new_dir );
  94. X    }        /* end else strcmp */
  95. X}            /* terminate function change_directory */
  96. END_OF_FILE
  97.   if test 749 -ne `wc -c <'chdir.c'`; then
  98.     echo shar: \"'chdir.c'\" unpacked with wrong size!
  99.   fi
  100.   # end of 'chdir.c'
  101. fi
  102. if test -f 'dl.c' -a "${1}" != "-c" ; then 
  103.   echo shar: Will not clobber existing file \"'dl.c'\"
  104. else
  105.   echo shar: Extracting \"'dl.c'\" \(5419 characters\)
  106.   sed "s/^X//" >'dl.c' <<'END_OF_FILE'
  107. X/* ============================== dl.c ============================== */
  108. X#include "dl.h"
  109. X
  110. Xvoid *malloc();
  111. X
  112. Xchar *getnode(size)
  113. X{
  114. X    DL_NODE *n;
  115. X
  116. X    if (n = (DL_NODE *) malloc(size)) {
  117. X        memset(n, '\0', size);
  118. X        n->size = size;
  119. X    }
  120. X    return(n);
  121. X}
  122. X
  123. Xfreenode(n)
  124. XDL_NODE *n;
  125. X{
  126. X    free(n);
  127. X}
  128. X
  129. X/*
  130. X * Create an empty list
  131. X */
  132. XDLIST dl_create(flags)
  133. Xint flags;
  134. X{
  135. X    DLIST l;
  136. X
  137. X    if ((l = (DLIST) malloc(sizeof(struct dl))) == NULL)
  138. X        return NULL;
  139. X
  140. X    l->head = l->tail = l->curr = NULL;
  141. X    l->size = 0;
  142. X    l->flags = flags;
  143. X    return(l);
  144. X}
  145. X
  146. X/*
  147. X * Free entire list
  148. X */
  149. Xdl_destroy(l)
  150. XDLIST l;
  151. X{
  152. X    while (dl_shead(l))
  153. X        dl_delete(l);
  154. X    /*
  155. X     * it is assumed that the list head structure itself was
  156. X     * from dl_create, thus will always be free'd.
  157. X     */
  158. X    free(l);
  159. X}
  160. X
  161. X/*
  162. X * Delete specific node
  163. X */
  164. Xdl_delete_node(l, n)
  165. XDLIST l;
  166. XDL_NODE *n;
  167. X{
  168. X    if (n) {
  169. X        dl_detach_node(l, n);
  170. X
  171. X        if ((l->flags & DL_FREE) == DL_FREE)
  172. X            freenode(n);
  173. X    }
  174. X}
  175. X
  176. X/*
  177. X * Delete node, but leave memory alone
  178. X */
  179. Xdl_detach_node(l, n)
  180. XDLIST l;
  181. XDL_NODE *n;
  182. X{
  183. X    l->size--;
  184. X
  185. X    l->curr = n->next;
  186. X    if (n->prev)
  187. X        n->prev->next = n->next;
  188. X    else
  189. X        l->head = n->next;
  190. X    if (n->next)
  191. X        n->next->prev = n->prev;
  192. X    else
  193. X        l->tail = n->prev;
  194. X}
  195. X
  196. X/*
  197. X * Insert node n before the current location in list l
  198. X */
  199. Xdl_ins_before_node(l, n_on_list, new_n)
  200. XDLIST l;
  201. XDL_NODE *n_on_list, *new_n;
  202. X{
  203. X    l->size++;
  204. X
  205. X    if (l->head == NULL) {
  206. X        l->head = l->tail = l->curr = new_n;
  207. X        new_n->next = new_n->prev = NULL;
  208. X        return;
  209. X    }
  210. X
  211. X    dl_set(l, n_on_list);
  212. X    if (l->curr == NULL)
  213. X        l->curr = l->head;
  214. X
  215. X    new_n->prev = l->curr->prev;
  216. X    new_n->next = l->curr;
  217. X    if (l->curr->prev)
  218. X        l->curr->prev->next = new_n;
  219. X    else
  220. X        l->head = new_n;        /* else l->curr == l->head */
  221. X    l->curr->prev = new_n;
  222. X
  223. X    l->curr = new_n;
  224. X}
  225. X
  226. Xdl_ins_after_node(l, n_on_list, new_n)
  227. XDLIST l;
  228. XDL_NODE *n_on_list, *new_n;
  229. X{
  230. X    l->size++;
  231. X
  232. X    if (l->head == NULL) {
  233. X        l->head = l->tail = l->curr = new_n;
  234. X        new_n->next = new_n->prev = NULL;
  235. X        return;
  236. X    }
  237. X
  238. X    dl_set(l, n_on_list);
  239. X    if (l->curr == NULL)
  240. X        l->curr = l->tail;
  241. X
  242. X    new_n->prev = l->curr;
  243. X    new_n->next = l->curr->next;
  244. X    if (l->curr->next)
  245. X        l->curr->next->prev = new_n;
  246. X    else
  247. X        l->tail = new_n;        /* else l->curr == l->tail */
  248. X    l->curr->next = new_n;
  249. X
  250. X    l->curr = new_n;
  251. X}
  252. X
  253. X/*
  254. X * Join l2 to the end of l1; l2 is no longer usable
  255. X */
  256. Xdl_cat(l1, l2)
  257. XDLIST l1, l2;
  258. X{
  259. X    l1->size += l2->size;
  260. X    l1->tail->next = l2->head;
  261. X    l2->head->prev = l1->tail;
  262. X    l1->tail = l2->tail;
  263. X
  264. X    free(l2);
  265. X}
  266. X
  267. X/*
  268. X *  Split list 'l' into two, so that 'n' is the first node of the new list,
  269. X *  return pointer to new list.
  270. X */
  271. X/*  Uncomment and do as exercise
  272. XDLIST dl_split_at_node(l, n)
  273. XDLIST l;
  274. XDL_NODE *n;
  275. X{
  276. X    DLIST newl;
  277. X
  278. X    if ((newl = dl_create(dl_flags(l))) == NULL)
  279. X        return(NULL);
  280. X
  281. X    newl->size = count from current pos to end
  282. X    l->size = count up to current pos (l->size - newl->size)
  283. X
  284. X    adjust pointers (last of l, first of newl (i.e., n))
  285. X
  286. X    return newl
  287. X}
  288. X*/
  289. X
  290. XDLIST dl_copy(l)
  291. XDLIST l;
  292. X{
  293. X    DLIST newl;
  294. X    DL_NODE *n, *newn;
  295. X
  296. X    if ((newl = dl_create(dl_flags(l))) == NULL)
  297. X        return(NULL);
  298. X
  299. X    foreachnode(l, n) {
  300. X        newn = getnode(n->size);
  301. X        if (newn == NULL) {
  302. X            dl_destroy(newl);
  303. X            return(NULL);
  304. X        }
  305. X        memcpy(newn, n, n->size);    /* copies ptrs, but is ok */
  306. X        dl_append(newl, newn);
  307. X    }
  308. X
  309. X    return(newl);
  310. X}
  311. X
  312. Xdl_compare(l1, l2, func)
  313. XDLIST l1, l2;
  314. Xint (*func)();
  315. X{
  316. X    int comp;
  317. X
  318. X    for (dl_shead(l1), dl_shead(l2);
  319. X         dl_curr(l1) && dl_curr(l2);
  320. X         dl_snext(l1), dl_snext(l2))
  321. X        if ((comp = (*func)(dl_curr(l1), dl_curr(l2))) != 0)
  322. X            return(comp);
  323. X
  324. X    if (dl_curr(l1))
  325. X        return(1);    /* l2 ran out first */
  326. X    else if (dl_curr(l2))
  327. X        return(-1);    /* l1 ran out first */
  328. X    else
  329. X        return(0);    /* both ran out at same time */
  330. X}
  331. X
  332. Xdl_apply(l, func, arg)
  333. XDLIST l;
  334. Xint (*func)();
  335. Xchar *arg;
  336. X{
  337. X    foreach(l)
  338. X        (*func)(dl_curr(l), arg);
  339. X}
  340. X
  341. X/*
  342. X * Do a linear search on the list, given a start/end point
  343. X */
  344. Xdl_lsearch(l, begin, end, key, func)
  345. XDLIST l;
  346. XDL_NODE *begin, *end;
  347. Xvoid *key;
  348. Xint (*func)();
  349. X{
  350. X    DL_NODE *n;
  351. X
  352. X    for (n = begin; n != end; n = n->next)
  353. X        if ((*func)(n, key)) {
  354. X            l->curr = n;
  355. X            return(TRUE);
  356. X        }
  357. X
  358. X    return(FALSE);
  359. X}
  360. X
  361. X/*
  362. X * dl_sort - take a list and a 'qsort' type cmp func & sort
  363. X *
  364. X * since we make an array of ptrs, qsort really needs a cmp func
  365. X * that follows a pointer to pointer to user struct; but this is
  366. X * ugly for users, so dl_sort_cmp_fun does one indirection then
  367. X * calls the users cmp func.
  368. X */
  369. X
  370. Xstatic int (*dl_sort_user_cmp_fun)();
  371. X
  372. Xdl_sort_cmp_fun(p1, p2)
  373. XDL_NODE **p1, **p2;
  374. X{
  375. X    return((*dl_sort_user_cmp_fun)(*p1, *p2));
  376. X}
  377. X
  378. Xdl_sort(l, func)
  379. XDLIST l;
  380. Xint (*func)();
  381. X{
  382. X    DL_NODE **array;
  383. X    int i, last;
  384. X
  385. X    if (l->size <= 1)
  386. X        return(0);
  387. X
  388. X    if ((array = dl_l2a(l)) == NULL)
  389. X        return(-1);
  390. X
  391. X    dl_sort_user_cmp_fun = func;
  392. X    qsort(array, l->size, sizeof(DL_NODE *), dl_sort_cmp_fun);
  393. X
  394. X    dl_a2l(l, array);
  395. X
  396. X    free(array);
  397. X
  398. X    return(0);
  399. X}
  400. X
  401. X/* from a list, make an array of pointers to the list items */
  402. XDL_NODE **
  403. Xdl_l2a(l)
  404. XDLIST l;
  405. X{
  406. X    DL_NODE *n, **array, **a;
  407. X
  408. X    array = (DL_NODE **) malloc(l->size*sizeof(DL_NODE *));
  409. X    if (array == NULL)
  410. X        return(NULL);
  411. X    
  412. X    for (n = l->head, a = array; n != NULL; n = n->next, a++)
  413. X        *a = n;
  414. X
  415. X    return(array);
  416. X}
  417. X
  418. X/* turn an array of pointers to the list items into a list */
  419. Xdl_a2l(l, array)
  420. XDLIST l;
  421. XDL_NODE **array;
  422. X{
  423. X    int i, last;
  424. X
  425. X    l->head = array[0];
  426. X    l->head->prev = NULL;
  427. X    l->head->next = array[1];
  428. X
  429. X    last = l->size - 1;
  430. X    for (i = 1; i < last; i++) {
  431. X        array[i]->next = array[i+1];
  432. X        array[i]->prev = array[i-1];
  433. X    }
  434. X
  435. X    l->tail = array[last];
  436. X    l->tail->next = NULL;
  437. X    l->tail->prev = array[last-1];
  438. X}
  439. END_OF_FILE
  440.   if test 5419 -ne `wc -c <'dl.c'`; then
  441.     echo shar: \"'dl.c'\" unpacked with wrong size!
  442.   fi
  443.   # end of 'dl.c'
  444. fi
  445. if test -f 'dl.h' -a "${1}" != "-c" ; then 
  446.   echo shar: Will not clobber existing file \"'dl.h'\"
  447. else
  448.   echo shar: Extracting \"'dl.h'\" \(2471 characters\)
  449.   sed "s/^X//" >'dl.h' <<'END_OF_FILE'
  450. X/* ============================== dl.h ============================== */
  451. X#ifndef DL_H
  452. X#define DL_H    /* so it isn't included more than once */
  453. X
  454. X#ifndef TRUE
  455. X#define TRUE    1
  456. X#define FALSE    0
  457. X#endif
  458. X
  459. X/*
  460. X * Template for other "derived" node types.  We assume a struct dl_node is at
  461. X * the front of the derived type.  Thus dl.c knows nothing about user data.
  462. X */
  463. Xtypedef struct dl_node {
  464. X        struct dl_node *next;
  465. X        struct dl_node *prev;
  466. X        int size;                       /* number of bytes of data following */
  467. X} DL_NODE;
  468. X
  469. X/*
  470. X * Structure to refer to a doubly-linked list.
  471. X */
  472. Xtypedef struct dl {
  473. X        DL_NODE *head;
  474. X        DL_NODE *tail;
  475. X        DL_NODE *curr;
  476. X        int size;                       /* number of nodes in list */
  477. X        int flags;
  478. X} *DLIST;
  479. X
  480. Xchar *getnode();
  481. XDLIST dl_create(), dl_copy();
  482. XDL_NODE **dl_l2a();
  483. X
  484. X#define dl_head(dl)        ((void *) ((dl)->head))
  485. X#define dl_tail(dl)        ((void *) ((dl)->tail))
  486. X#define dl_curr(dl)        ((void *) ((dl)->curr))
  487. X#define dl_size(dl)        ((dl)->size)
  488. X#define dl_flags(dl)        ((dl)->flags)
  489. X#define dl_prev(dl)        ((void *) ((dl)->curr->prev))
  490. X#define dl_next(dl)        ((void *) ((dl)->curr->next))
  491. X#define dl_set(dl, n)        ((void *) ((dl)->curr = (DL_NODE *) (n)))
  492. X#define dl_shead(dl)        ((void *) (dl_set(dl, dl_head(dl))))
  493. X#define dl_stail(dl)        ((void *) (dl_set(dl, dl_tail(dl))))
  494. X#define dl_snext(dl)        ((void *) (dl_set(dl, dl_next(dl))))
  495. X#define dl_sprev(dl)        ((void *) (dl_set(dl, dl_prev(dl))))
  496. X#define dl_nextof(n)        ((void *) (((DL_NODE *)(n))->next))
  497. X#define dl_prevof(n)        ((void *) (((DL_NODE *)(n))->prev))
  498. X#define dl_sflags(dl,f)        ((dl)->flags = (f))
  499. X#define dl_searchlist(l,key,func)  (dl_lsearch(l, dl_head(l), NULL, key, func))
  500. X#define dl_delete(l)        (dl_delete_node(l, dl_curr(l)))
  501. X#define dl_detach(l)        (dl_detach_node(l, dl_curr(l)))
  502. X#define dl_ins_after(l, n)    (dl_ins_after_node(l, dl_curr(l), n))
  503. X#define dl_ins_before(l, n)    (dl_ins_before_node(l, dl_curr(l), n))
  504. X#define dl_append(l, n)        (dl_ins_after_node(l, dl_tail(l), n))
  505. X#define dl_prepend(l, n)    (dl_ins_before_node(l, dl_head(l), n))
  506. X#define dl_split(l, n)        (dl_split_at_node(l, dl_curr(l)))
  507. X
  508. X/* Whether to free() nodes upon deletion or not. */
  509. X#define DL_FREE         1
  510. X#define DL_NOFREE       0
  511. X
  512. X#ifndef NULL
  513. X#define NULL    (0)
  514. X#endif
  515. X
  516. X#define NIL     ((void *) 0)            /* for passing as param */
  517. X
  518. X#define foreach(l)        for (dl_shead(l); dl_curr(l); dl_snext(l))
  519. X#define foreachnode(l,p)    for ((p)=dl_shead(l); (p); (p)=dl_snext(l))
  520. X#endif
  521. END_OF_FILE
  522.   if test 2471 -ne `wc -c <'dl.h'`; then
  523.     echo shar: \"'dl.h'\" unpacked with wrong size!
  524.   fi
  525.   # end of 'dl.h'
  526. fi
  527. if test -f 'functions1.c' -a "${1}" != "-c" ; then 
  528.   echo shar: Will not clobber existing file \"'functions1.c'\"
  529. else
  530.   echo shar: Extracting \"'functions1.c'\" \(4933 characters\)
  531.   sed "s/^X//" >'functions1.c' <<'END_OF_FILE'
  532. X#include "mshell.h"
  533. X
  534. Xextern char     G_homevar      [];
  535. Xextern char     G_uservar      [];
  536. Xextern char     G_termvar      [];
  537. Xextern char     G_mailfile     [WORDLEN];
  538. Xextern char     G_mail_message [WORDLEN];
  539. Xextern int      G_mailsize; 
  540. Xextern struct   stat G_st;
  541. X
  542. Xhelpfile_display (filename)
  543. Xchar * filename;
  544. X
  545. X{
  546. X    FILE * fp;
  547. X    char record [DESCLEN];
  548. X    if (( fp = fopen (filename, "r")) == NULL ) {
  549. X        printf ("\tNo such helpfile as %s\!\!\n", filename);
  550. X        return;
  551. X    }
  552. X
  553. X    while ( fgets (record, sizeof(record), fp) )
  554. X        fputs (record, stdout);
  555. X    printf ("\n");
  556. X    fclose (fp);
  557. X}
  558. X
  559. X/* ================================ */
  560. Xchar *
  561. Xprompt(p)
  562. X/* ================================ */
  563. Xchar *p;
  564. X{
  565. X    static char ans[WORDLEN];
  566. X    extern int G_limited;
  567. X
  568. X    printf ("%s : ", ufix(p));
  569. X    if (!G_limited) {
  570. X        read_input_line (ans);
  571. X        replace_string (ans, HOME_CHAR, getenv(&G_homevar[1])) ;
  572. X    }
  573. X    else {
  574. X        strcpy(ans, "XXX");
  575. X        printf("(no input for unvalidated users)");
  576. X    }
  577. X    printf ("\n");
  578. X    return(ans);
  579. X}
  580. X
  581. X/* ================================================ */
  582. Xextract_action_word ( str, sub_str, dest_str, flag)
  583. X/* ================================================ */
  584. Xchar *str, *sub_str, *dest_str;
  585. Xint  flag;
  586. X
  587. X{
  588. X    char *position, *target;
  589. X    int startpos = 0, string_length = 0, i = 0;
  590. X    unsigned  no_of_chars = 0;
  591. X
  592. X    strcpy (dest_str, NULLSTR);        /* initialize dest_str */
  593. X
  594. X    startpos = strsearch (str, sub_str);
  595. X                        /* find position of sub-string 
  596. X                           in main string             */
  597. X
  598. X    if ( startpos != -1 )                /* if it exists */
  599. X        target = &str[startpos] + strlen (sub_str);    
  600. X                            /* assign target */
  601. X    else
  602. X        return;                /* no such string found */
  603. X
  604. X    for (position = target;         /* actual value of parameter */
  605. X        (*position != BLANK) && (*position != EOS);
  606. X         ++position, ++no_of_chars);
  607. X
  608. X    strncpy (dest_str, target, no_of_chars);  /* copy the required value */
  609. X    dest_str[no_of_chars] = EOS;
  610. X
  611. X    string_length = strlen(sub_str) + no_of_chars;
  612. X
  613. X    if ( *position != EOS )
  614. X        ++string_length ;
  615. X
  616. X    remove_string (str, startpos, string_length) ;
  617. X
  618. X    if ( flag ) 
  619. X        for (i = 0; dest_str[i] != EOS ; ++i)
  620. X            if ( dest_str[i] == VISIBLE_SPACE ) 
  621. X                dest_str[i] = BLANK;
  622. X}
  623. X
  624. X/* ===================== */
  625. Xdisplay_menu (menu_name, menu_array, menu_flag, idx)
  626. X/* ===================== */
  627. Xchar * menu_name;
  628. Xchar * menu_array [];
  629. Xint  * menu_flag;
  630. Xint  * idx;
  631. X
  632. X{
  633. X    FILE * fp;
  634. X    char junk[COLUMNS] , keyword[DESCLEN], description[DESCLEN],
  635. X        action_description[DESCLEN], *strsave(), *fgets(), *index();
  636. X    register int i;
  637. X    int delay;
  638. X
  639. X    if (!moreinput())
  640. X        clear_screen();
  641. X
  642. X    check_for_new_mail (G_mail_message);
  643. X
  644. X    if ( *menu_flag == FALSE ) {
  645. X        *menu_flag = TRUE;
  646. X        if (index(menu_name, '/'))
  647. X            strcpy(junk, menu_name);
  648. X        else
  649. X            sprintf(junk, "%s/%s%s", MENUDIR, menu_name, SUFFIX);
  650. X        if (( fp = fopen (junk, "r")) == NULL ) {
  651. X            printf ("\tNo such menu as %s!!\n", junk);
  652. X            return(0);
  653. X        }
  654. X
  655. X        for (
  656. X              i = *idx = 0;
  657. X              i < LINES &&
  658. X            (menu_array[i] = strsave(fgets(junk, COLUMNS, fp)));
  659. X              i++
  660. X            )
  661. X            if ( strcmp (menu_array[i], DELIM_LINE) == 0 )
  662. X                *idx = i;
  663. X        
  664. X        fclose (fp);
  665. X
  666. X        for ( ; i < LINES; i++)
  667. X            menu_array[i] = strsave("");
  668. X    }
  669. X
  670. X    if (strcmp(G_mail_message, "") != 0) {
  671. X        junk[0] = EOS;
  672. X        sscanf(menu_array[0], "%[^\n]", junk);
  673. X        printf("%s%s\n", junk, G_mail_message);
  674. X        i = 1;
  675. X    }
  676. X    else
  677. X        i = 0;
  678. X
  679. X    if (!moreinput())
  680. X        for (; i < *idx; i++)
  681. X            fputs(menu_array[i], stdout);
  682. X
  683. X    printf ("\n");
  684. X    return(1);
  685. X}
  686. X
  687. X/* find the home directory of the person invoking M_Shell */
  688. X/* ====================================================== */
  689. X
  690. Xfind_user_details (home_dir, user_name)
  691. Xchar * home_dir;
  692. Xchar * user_name;
  693. X{
  694. X    struct passwd *pw, *getpwuid();
  695. X
  696. X    pw = getpwuid (getuid ());
  697. X
  698. X     strcpy (home_dir, pw->pw_dir);
  699. X    strcpy (user_name, pw->pw_name);
  700. X}
  701. X
  702. X/* ====================================================== */
  703. Xsearch_menu_array (menu_array, ind, option, string, invalid)
  704. X/* ====================================================== */
  705. Xchar * menu_array [];
  706. Xint    ind;
  707. Xchar * option, * string;
  708. Xint  * invalid;
  709. X
  710. X{
  711. X    int i;
  712. X    char keyword [WORDLEN];
  713. X    char action_description[DESCLEN], junk[DESCLEN];
  714. X    char opt1[OPTLEN], opt2[OPTLEN];
  715. X
  716. X    for ( i = ++ind; i < LINES ; ++i ) {
  717. X        sscanf (menu_array[i], "%s    %[^\n]", keyword, action_description);
  718. X        if ( index (option, BLANK) != NULL ) 
  719. X            sscanf (option, "%s %[^\n]", opt1, opt2);
  720. X        else
  721. X            strcpy (opt1, option);
  722. X
  723. X        if ( strcmp (opt1, keyword) == 0 ) {
  724. X            strcpy (string, action_description);
  725. X            *invalid = FALSE;
  726. X            return;
  727. X        }
  728. X    }
  729. X
  730. X    if ( all_blanks(option)            || strcmp(option, QUIT) == 0 ||
  731. X             strncmp(option, HELP, 4) == 0 || strcmp(option, BYE)  == 0 ||
  732. X         strcmp(option, "T") == 0      || strcmp(option, "top") == 0)
  733. X        *invalid = FALSE;
  734. X    else
  735. X        *invalid = TRUE;
  736. X
  737. X    strcpy (string, NULLSTR);
  738. X}
  739. X
  740. Xwait_for_user ()
  741. X{
  742. X    printf("\nHit ENTER to continue ... ");
  743. X    read_input_line (NULL);
  744. X}
  745. X
  746. Xclear_screen()
  747. X{
  748. X    static int doneinit = 0;
  749. X
  750. X    if (!doneinit) {
  751. X        initscr();
  752. X        doneinit++;
  753. X    }
  754. X    clear();
  755. X    refresh();
  756. X}
  757. END_OF_FILE
  758.   if test 4933 -ne `wc -c <'functions1.c'`; then
  759.     echo shar: \"'functions1.c'\" unpacked with wrong size!
  760.   fi
  761.   # end of 'functions1.c'
  762. fi
  763. if test -f 'macro.c' -a "${1}" != "-c" ; then 
  764.   echo shar: Will not clobber existing file \"'macro.c'\"
  765. else
  766.   echo shar: Extracting \"'macro.c'\" \(815 characters\)
  767.   sed "s/^X//" >'macro.c' <<'END_OF_FILE'
  768. X#include "mshell.h"
  769. X
  770. Xstruct macro {
  771. X    DL_NODE n;
  772. X    char *name;
  773. X    char *def;
  774. X};
  775. X
  776. Xstatic DLIST macrolist;
  777. X
  778. Xchar *
  779. Xmac_lookup(name)
  780. Xchar *name;
  781. X{
  782. X    struct macro *m;
  783. X
  784. X    if (macrolist)
  785. X        foreachnode(macrolist, m)
  786. X            if (strcmp(m->name, name) == 0)
  787. X                return(m->def);
  788. X
  789. X    /* note: could do a help/list macro here as builtin */
  790. X
  791. X    printf("No definition for macro %s\n", name);
  792. X    return("");
  793. X}
  794. X
  795. Xload_macrofile(f)
  796. Xchar *f;
  797. X{
  798. X    FILE *fp;
  799. X    char line[MAXLEN], name[MAXLEN], def[MAXLEN];
  800. X    struct macro *m;
  801. X
  802. X    if ((fp = fopen(f, "r")) == NULL)
  803. X        return;
  804. X
  805. X    if (!macrolist)
  806. X        macrolist = dl_create(DL_FREE);
  807. X
  808. X    while (fgets(line, MAXLEN, fp))
  809. X        if (
  810. X            sscanf(line, "%[^=]=%[^\n]\n", name, def) == 2 &&
  811. X            (m = getnode(sizeof(*m))) &&
  812. X            (m->name = strsave(name)) &&
  813. X            (m->def = strsave(def))
  814. X        )
  815. X            dl_prepend(macrolist, m);
  816. X    fclose(fp);
  817. X}
  818. END_OF_FILE
  819.   if test 815 -ne `wc -c <'macro.c'`; then
  820.     echo shar: \"'macro.c'\" unpacked with wrong size!
  821.   fi
  822.   # end of 'macro.c'
  823. fi
  824. if test -f 'mail.c' -a "${1}" != "-c" ; then 
  825.   echo shar: Will not clobber existing file \"'mail.c'\"
  826. else
  827.   echo shar: Extracting \"'mail.c'\" \(498 characters\)
  828.   sed "s/^X//" >'mail.c' <<'END_OF_FILE'
  829. X#include "mshell.h"
  830. X
  831. X
  832. Xextern char     G_homevar      [];
  833. Xextern char     G_uservar      [];
  834. Xextern char     G_termvar      [];
  835. Xextern char     G_mailfile     [WORDLEN];
  836. Xextern char     G_mail_message [WORDLEN];
  837. Xextern int      G_mailsize; 
  838. Xextern struct   stat G_st;
  839. X
  840. Xcheck_for_new_mail (message)
  841. Xchar * message;
  842. X{
  843. X    off_t new_mail_size;
  844. X
  845. X    stat (G_mailfile, &G_st);
  846. X
  847. X    new_mail_size = G_st.st_size;
  848. X
  849. X    if ( new_mail_size > G_mailsize )
  850. X        strcpy ( message, MAIL_MESSAGE );
  851. X
  852. X    G_mailsize = new_mail_size;
  853. X}
  854. END_OF_FILE
  855.   if test 498 -ne `wc -c <'mail.c'`; then
  856.     echo shar: \"'mail.c'\" unpacked with wrong size!
  857.   fi
  858.   # end of 'mail.c'
  859. fi
  860. if test -f 'main.c' -a "${1}" != "-c" ; then 
  861.   echo shar: Will not clobber existing file \"'main.c'\"
  862. else
  863.   echo shar: Extracting \"'main.c'\" \(1840 characters\)
  864.   sed "s/^X//" >'main.c' <<'END_OF_FILE'
  865. X/*
  866. X * Mshell
  867. X *
  868. X * A menu shell.
  869. X *
  870. X * Copyright 1991 by Andrew Burt and the University of Denver.
  871. X */
  872. X#include "mshell.h"
  873. X
  874. Xchar     G_homevar      [] = { "$HOME" };
  875. Xchar     G_uservar      [] = { "$USER" };
  876. Xchar      G_termvar      [] = { "$TERM" };
  877. Xchar     G_mailfile     [WORDLEN];
  878. Xchar     G_mail_message [WORDLEN];
  879. Xint      G_mailsize; 
  880. Xstruct   stat G_st;
  881. Xint     G_shell_ok;
  882. Xint     G_limited = FALSE;
  883. X
  884. Xmain (argc, argv)
  885. Xint     argc;
  886. Xchar ** argv;
  887. X
  888. X{
  889. X    char menu[WORDLEN];
  890. X    char menuname[WORDLEN];
  891. X    char *progname = argv[0];
  892. X
  893. X    G_shell_ok = TRUE;
  894. X    if ( argc > 1 && strcmp(argv[1], "-s") == 0 ) {
  895. X        G_shell_ok = FALSE;
  896. X        argc--;
  897. X        argv++;
  898. X    }
  899. X    else if ( argc > 1 && strcmp(argv[1], "-r") == 0 ) {
  900. X        G_limited = TRUE;
  901. X        G_shell_ok = FALSE;
  902. X        argc--;
  903. X        argv++;
  904. X    }
  905. X
  906. X    if ( argc < 2 ) {
  907. X        printf ("Usage: %s <primary menu name>\n", progname);
  908. X        exit (1);
  909. X    }
  910. X
  911. X    strcpy ( G_mailfile, MAILDIR );
  912. X    strcat ( G_mailfile, getenv(&G_uservar[1]) );
  913. X    G_mail_message[0] = EOS;
  914. X
  915. X    stat ( G_mailfile, &G_st );
  916. X    G_mailsize = G_st.st_size;
  917. X    if (G_mailsize > 0)
  918. X        strcpy(G_mail_message, "    [You have mail.]");
  919. X    else
  920. X        G_mail_message[0] = EOS;
  921. X
  922. X#ifdef check_parent
  923. X    if ( getppid() == 1 )            /* Mshell is login shell */
  924. X#endif
  925. X        set_terminal_attributes();
  926. X    set_resource_limits();
  927. X
  928. X    rc();
  929. X    openlog();
  930. X    load_macrofile(GLOBAL_MACRO_FILE);
  931. X    load_macrofile(".mshellmac");
  932. X
  933. X    M_Shell (argv[1]);
  934. X    bye(0);
  935. X}
  936. X
  937. Xrc()
  938. X{
  939. X    if (!G_shell_ok)
  940. X        return;
  941. X
  942. X    if (access(".mshellrc", 0) == -1)    /* assumedly now in home dir */
  943. X        return;
  944. X
  945. X    system("sh .mshellrc");
  946. X}
  947. X
  948. X#ifndef LOGDIR
  949. X#define LOGDIR "/u1/logs"
  950. X#endif
  951. X
  952. XFILE *logfp;
  953. Xopenlog()
  954. X{
  955. X    struct passwd *pw;
  956. X    char fn[32];
  957. X
  958. X    if ((pw = getpwuid(getuid())) == NULL)
  959. X        return;
  960. X    sprintf(fn, "%s/%s", LOGDIR, pw->pw_name);
  961. X    logfp = fopen(fn, "a");
  962. X    chmod(fn, 0600);
  963. X}
  964. X
  965. Xlog(s1, s2)
  966. Xchar *s1, *s2;
  967. X{
  968. X    if (logfp)
  969. X        fprintf(logfp, "%s %s\n", s1, s2);
  970. X}
  971. END_OF_FILE
  972.   if test 1840 -ne `wc -c <'main.c'`; then
  973.     echo shar: \"'main.c'\" unpacked with wrong size!
  974.   fi
  975.   # end of 'main.c'
  976. fi
  977. if test -f 'menulogin' -a "${1}" != "-c" ; then 
  978.   echo shar: Will not clobber existing file \"'menulogin'\"
  979. else
  980.   echo shar: Extracting \"'menulogin'\" \(1739 characters\)
  981.   sed "s/^X//" >'menulogin' <<'END_OF_FILE'
  982. X#!/bin/sh
  983. X
  984. X# Sample login wrapper -- name as /.../menulogin or /.../menuloginsh
  985. X# and it'll allow shell or not as it ends with ...sh.  Could also be
  986. X# modified to enable -r for some naming scheme.
  987. X# This junk is pretty Nyx specific, and outdated, but the idea's the thing.
  988. X
  989. Xecho "Configuring..."
  990. X
  991. Xset `du -s .`
  992. Xecho "FYI, your disk usage is: $1 K."
  993. Xif [ "$1" -gt 100 ]; then
  994. X    echo "Reminder, please keep your home dirs small (under 100 K)."
  995. X    echo "There's plenty of temp space elsewhere."
  996. X
  997. X    free=`/u1/bin/pdf`
  998. X    if [ "$free" -lt 20000 ]; then
  999. X        echo "Note that free space (for EVERYONE) is tight: only $free K."
  1000. X        echo "(And you are using more than 100 K -- hint hint.)"
  1001. X        echo "Use the 'du2' option on the status menu for more info."
  1002. X        if [ "$free" -lt 5000 ]; then
  1003. X            echo "***Indeed, with so little space, consider it imperative -- clean up immediately!"
  1004. X        fi
  1005. X    fi
  1006. Xfi
  1007. X
  1008. Xmendir=/u5/lib/menus
  1009. Xdldir=/u3/lib/download
  1010. Xif [ -r $HOME/.termtype ]; then
  1011. X    . $HOME/.termtype
  1012. Xelse
  1013. X#    TERM=dw1
  1014. X    TERM=vt100
  1015. X    TERMCAP=/etc/termcap
  1016. Xfi
  1017. XPATH=/u1/bin:/u5/bin:/usr/ucb:/bin:/usr/bin:.
  1018. Xif [ -r $HOME/.editor ]; then
  1019. X    EDITOR=$HOME/.editor
  1020. Xelse
  1021. X    EDITOR=/u5/bin/smile
  1022. Xfi
  1023. Xif [ -f $HOME/.biffy ]; then
  1024. X    biff y
  1025. Xfi
  1026. Xif [ -f $HOME/.mesgn ]; then
  1027. X    mesg n
  1028. Xfi
  1029. Xif [ -f $HOME/.environment ]; then
  1030. X    . $HOME/.environment
  1031. Xfi
  1032. Xcase $0 in
  1033. X    *sh)
  1034. X        # shell is ok
  1035. X        SHELL=/bin/csh
  1036. X        opt=""
  1037. X        ;;
  1038. X    *)
  1039. X        # shell is not allowed
  1040. X        SHELL=/u1/bin/noshell
  1041. X        opt="-s"
  1042. X        ;;
  1043. Xesac
  1044. X
  1045. Xexport PATH
  1046. Xexport SHELL
  1047. Xexport mendir
  1048. Xexport dldir
  1049. Xexport EDITOR
  1050. Xexport TERMCAP
  1051. Xexport TERM
  1052. X
  1053. Xif [ -r $HOME/.rninit ]; then
  1054. X    RNINIT=$HOME/.rninit
  1055. X    export RNINIT
  1056. Xfi
  1057. Xstty -tabs crt susp undef dsusp undef -nohang erase '^h' kill '^u' intr '^c'
  1058. Xecho "Hit ENTER to continue...\c"
  1059. Xread xxx
  1060. Xexec /u5/bin/mshell $opt main
  1061. END_OF_FILE
  1062.   if test 1739 -ne `wc -c <'menulogin'`; then
  1063.     echo shar: \"'menulogin'\" unpacked with wrong size!
  1064.   fi
  1065.   chmod +x 'menulogin'
  1066.   # end of 'menulogin'
  1067. fi
  1068. if test -f 'mshell.c' -a "${1}" != "-c" ; then 
  1069.   echo shar: Will not clobber existing file \"'mshell.c'\"
  1070. else
  1071.   echo shar: Extracting \"'mshell.c'\" \(5001 characters\)
  1072.   sed "s/^X//" >'mshell.c' <<'END_OF_FILE'
  1073. X#include "mshell.h"
  1074. X#include <setjmp.h>
  1075. Xchar * index ();
  1076. X
  1077. X
  1078. Xextern char     G_homevar      [];
  1079. Xextern char     G_uservar      [];
  1080. Xextern char     G_termvar      [];
  1081. Xextern char     G_mailfile     [WORDLEN];
  1082. Xextern char     G_mail_message [WORDLEN];
  1083. Xextern int      G_mailsize; 
  1084. Xextern int      G_shell_ok; 
  1085. Xextern struct   stat G_st;
  1086. X
  1087. X/* ================== */
  1088. XM_Shell (m)
  1089. X/* ================== */
  1090. X
  1091. Xchar *m;
  1092. X
  1093. X{
  1094. X    char opt           [WORDLEN],
  1095. X         opt1          [OPTLEN],
  1096. X         opt2          [OPTLEN],
  1097. X         action_string [DESCLEN],
  1098. X         exec_string   [DESCLEN],
  1099. X         *args         [MAXARGS],
  1100. X         *menu_array   [LINES],
  1101. X         tmpword       [WORDLEN],
  1102. X         *malloc();
  1103. X
  1104. X    int  i, 
  1105. X         idx,
  1106. X         invalid_option = FALSE,
  1107. X         firsttime = TRUE,
  1108. X         dontdisplay = FALSE,
  1109. X         unix_flag,
  1110. X         menu_flag,
  1111. X         exit();
  1112. X
  1113. X    static jmp_buf topenv;
  1114. X    static int topenvset;
  1115. X
  1116. X    menu_flag = FALSE;
  1117. X    signal (SIGHUP,  exit);
  1118. X    signal (SIGINT,  SIG_IGN);    /* ignore all ^C interrupts */
  1119. X    signal (SIGQUIT, SIG_IGN);    /* ignore all ^\ interrupts */
  1120. X    signal (SIGTSTP, SIG_IGN);    /* ignore all ^Z interrupts */
  1121. X    signal (SIGPIPE, SIG_IGN);    /* ignore dead pipes */
  1122. X    log("enter", m);
  1123. X
  1124. X    while TRUE {
  1125. X
  1126. X        if (!topenvset) {
  1127. X            topenvset = TRUE;
  1128. X            setjmp(topenv);
  1129. X        }
  1130. X
  1131. X        unix_flag = FALSE;
  1132. X
  1133. X        /* keep looping until a valid response has been entered *
  1134. X         * ==================================================== */
  1135. X        do {
  1136. X            if (display_menu(m, menu_array, &menu_flag, &idx) == 0)
  1137. X                return;
  1138. X
  1139. X            if ( firsttime ) {
  1140. X                firsttime = FALSE;
  1141. X                search_menu_array (menu_array, idx, "_init",
  1142. X                    action_string, &invalid_option);
  1143. X                if (!invalid_option) {
  1144. X                    while (substitute(action_string))
  1145. X                        ;
  1146. X                    get_actions (action_string,
  1147. X                        exec_string, args);
  1148. X                    execute_command (exec_string, args);
  1149. X                }
  1150. X                else    
  1151. X                    invalid_option = FALSE;
  1152. X            }
  1153. X
  1154. X            if ( invalid_option )
  1155. X                printf ("No such choice as '%s'.", opt);
  1156. X
  1157. X            if (!moreinput())
  1158. X                printf ("\tSelect choice [or help, x, top, bye]: ");
  1159. X            opt[0] = 0;
  1160. X            read_input_line (opt);
  1161. X            log("    ", opt);
  1162. X            invalid_option = FALSE;
  1163. X            putchar('\n');
  1164. X
  1165. X            /* if first character of option is an "!"    *
  1166. X             * character then invoke the remaining line  *
  1167. X             * using the C system function               *
  1168. X             * ======================================== */
  1169. X
  1170. X            if ( !opt[0] )
  1171. X                continue;
  1172. X            else if ( opt[0] == EXCLAIM && G_shell_ok ) {
  1173. X                system(opt+1);
  1174. X                unix_flag = TRUE;
  1175. X                wait_for_user ();
  1176. X            }
  1177. X            else {
  1178. X                search_menu_array (menu_array, idx, opt,
  1179. X                    action_string, &invalid_option);
  1180. X            }
  1181. X        }
  1182. X        while ( invalid_option );
  1183. X
  1184. X        if ( unix_flag || !opt[0] )
  1185. X        /* bypass execution of code until end of while(TRUE) loop *
  1186. X         * ====================================================== */
  1187. X            continue;
  1188. X
  1189. X
  1190. X        /* replace environment variables with values */
  1191. X        while (substitute(action_string))
  1192. X            ;
  1193. X
  1194. X    /* remove actual values of commands and arguments from action-string */
  1195. X    /* ================================================================= */
  1196. X        get_actions (action_string, exec_string, args);
  1197. X
  1198. X    /* display any prompt and get values if specified in the command line */
  1199. X    /* ================================================================== */
  1200. X        opt1[0] = EOS;
  1201. X        opt2[0] = EOS;
  1202. X
  1203. X        if ( index (opt, BLANK) != NULL )
  1204. X            sscanf (opt, "%s %s", opt1, opt2);
  1205. X        else
  1206. X            strcpy (opt1, opt);
  1207. X
  1208. X        if ( strcmp (opt1, HELP) == 0 ) {
  1209. X            if ( strcmp (opt2, NULLSTR) == 0 )
  1210. X                strcpy(opt2, prompt("Help on which choice"));
  1211. X
  1212. X            search_menu_array (menu_array, idx, opt2,
  1213. X                   action_string, &invalid_option);
  1214. X
  1215. X            if ( strcmp (action_string, NULLSTR) == 0 ) {
  1216. X                invalid_option = TRUE;
  1217. X                printf ("\tNo such help option name as: %s\!\!\n", opt2);
  1218. X            }
  1219. X            else {
  1220. X                tmpword[0] = EOS;
  1221. X                extract_action_word (action_string, MAN, tmpword, 0);
  1222. X                if ( strcmp (tmpword, NULLSTR) == 0 ) 
  1223. X                    extract_action_word (action_string, CMDVAL, tmpword, 0);
  1224. X                if (strcmp(tmpword, NULLSTR) != 0)
  1225. X                    do_man(tmpword);
  1226. X            }
  1227. X
  1228. X/*            if ( invalid_option ) {*/
  1229. X                invalid_option = FALSE;
  1230. X                wait_for_user ();
  1231. X/*            }*/
  1232. X            continue;
  1233. X        }
  1234. X
  1235. X    /* if the command is to invoke another menu then do not exec    *
  1236. X     * but call M_Shell recursively                    *
  1237. X     * =========================================================    */
  1238. X        if ( all_blanks (opt) ) 
  1239. X            ;
  1240. X        else if (strcmp (opt, BYE)  == 0)
  1241. X            bye(0);
  1242. X        else if (strcmp (opt, QUIT) == 0) {
  1243. X            for (i = 0; i < LINES; i++)
  1244. X                if (menu_array[i])
  1245. X                    free(menu_array[i]);
  1246. X            log("exit", m);
  1247. X            return;
  1248. X        }
  1249. X        else if (strcmp(opt, "T") == 0 || strcmp(opt, "top") == 0) {
  1250. X            for (i = 0; i < LINES; i++)
  1251. X                if (menu_array[i])
  1252. X                    free(menu_array[i]);
  1253. X            longjmp(topenv, 1);
  1254. X        }
  1255. X        else if ( strcmp(args[0], "menu") == 0 )
  1256. X            M_Shell (args[1]);
  1257. X        else {
  1258. X            execute_command (exec_string, args);
  1259. X            wait_for_user();
  1260. X        }
  1261. X    }
  1262. X}
  1263. X
  1264. Xdo_man(entry)
  1265. Xchar *entry;
  1266. X{
  1267. X    char cmd[WORDLEN], *p, *rindex();
  1268. X
  1269. X    if (p = rindex(entry, '/'))
  1270. X        entry = p+1;
  1271. X
  1272. X    sprintf(cmd, "man %s", entry);
  1273. X    system(cmd);
  1274. X}
  1275. X
  1276. Xbye(status)
  1277. Xint status;
  1278. X{
  1279. X    printf("\nLogging out -- come back again soon...\n\n");
  1280. X    exit(status);
  1281. X}
  1282. END_OF_FILE
  1283.   if test 5001 -ne `wc -c <'mshell.c'`; then
  1284.     echo shar: \"'mshell.c'\" unpacked with wrong size!
  1285.   fi
  1286.   # end of 'mshell.c'
  1287. fi
  1288. if test -f 'settatr.c' -a "${1}" != "-c" ; then 
  1289.   echo shar: Will not clobber existing file \"'settatr.c'\"
  1290. else
  1291.   echo shar: Extracting \"'settatr.c'\" \(1148 characters\)
  1292.   sed "s/^X//" >'settatr.c' <<'END_OF_FILE'
  1293. X#include "mshell.h"
  1294. X#include <sys/time.h>
  1295. X#include <sys/resource.h>
  1296. X
  1297. Xset_terminal_attributes()
  1298. X{
  1299. X#ifdef BSD
  1300. X    struct sgttyb  sg;
  1301. X    struct tchars  tc;
  1302. X    struct ltchars lt;
  1303. X    int ldisc = NTTYDISC;
  1304. X
  1305. X    ioctl ( 0, TIOCSETD, &ldisc );
  1306. X
  1307. X    ioctl ( 0, TIOCGETP, &sg );
  1308. X    if (access(".stty", 0) == -1) {    /* not already set up */
  1309. X        sg.sg_erase = '\b';
  1310. X        sg.sg_kill  = 21;    /* ^U */
  1311. X        sg.sg_flags |= XTABS;
  1312. X    }
  1313. X    sg.sg_flags |= ECHO;
  1314. X    sg.sg_flags &= ~ RAW;
  1315. X    sg.sg_flags &= ~ CBREAK;
  1316. X    sg.sg_flags |= CRMOD;
  1317. X    ioctl ( 0, TIOCSETP, &sg );
  1318. X
  1319. X    ioctl ( 0, TIOCGETC, &tc );
  1320. X    tc.t_intrc  = 3;    /* ^C */
  1321. X    ioctl ( 0, TIOCSETC, &tc );
  1322. X
  1323. X    ioctl ( 0, TIOCGLTC, < );
  1324. X    lt.t_werasc = 23;    /* ^W */
  1325. X    lt.t_rprntc = 18;    /* ^R */
  1326. X    ioctl ( 0, TIOCSLTC, < );
  1327. X#endif
  1328. X#ifdef SYSV
  1329. X    struct termio t;
  1330. X
  1331. X    ioctl ( 0, TCGETA, &t );
  1332. X
  1333. X    t.c_cc[VINTR] = '\003';
  1334. X    t.c_cc[VERASE] = '\b';
  1335. X    t.c_cc[VKILL] = '\025';
  1336. X    t.c_iflag = IGNBRK | IGNPAR | ICRNL | IXON ;
  1337. X    t.c_oflag = OPOST | ONLCR ;
  1338. X    t.c_lflag = ISIG | ICANON | ECHO | ECHOE | ECHOK ;
  1339. X    t.c_cflag |= TAB3;
  1340. X
  1341. X    ioctl ( 0, TCSETA, &t );
  1342. X#endif
  1343. X}
  1344. Xset_resource_limits()
  1345. X{
  1346. X    struct rlimit lim;
  1347. X
  1348. X    lim.rlim_cur = lim.rlim_max = 0;
  1349. X    setrlimit(RLIMIT_CORE, &lim);
  1350. X}
  1351. END_OF_FILE
  1352.   if test 1148 -ne `wc -c <'settatr.c'`; then
  1353.     echo shar: \"'settatr.c'\" unpacked with wrong size!
  1354.   fi
  1355.   # end of 'settatr.c'
  1356. fi
  1357. if test -f 'xsystem.c' -a "${1}" != "-c" ; then 
  1358.   echo shar: Will not clobber existing file \"'xsystem.c'\"
  1359. else
  1360.   echo shar: Extracting \"'xsystem.c'\" \(578 characters\)
  1361.   sed "s/^X//" >'xsystem.c' <<'END_OF_FILE'
  1362. X/*
  1363. X * Pilfered from berkeley code.
  1364. X */
  1365. X#if defined(LIBC_SCCS) && !defined(lint)
  1366. Xstatic char sccsid[] = "@(#)system.c    5.2 (Berkeley) 3/9/86";
  1367. X#endif LIBC_SCCS and not lint
  1368. X
  1369. X#include    <signal.h>
  1370. X
  1371. Xsystem(s)
  1372. Xchar *s;
  1373. X{
  1374. X    int status, pid, w;
  1375. X    register int (*istat)(), (*qstat)();
  1376. X
  1377. X    if ((pid = vfork()) == 0) {
  1378. X        execl("/bin/csh", "csh", "-fc", s, 0);
  1379. X        _exit(127);
  1380. X    }
  1381. X    istat = signal(SIGINT, SIG_IGN);
  1382. X    qstat = signal(SIGQUIT, SIG_IGN);
  1383. X    while ((w = wait(&status)) != pid && w != -1)
  1384. X        ;
  1385. X    if (w == -1)
  1386. X        status = -1;
  1387. X    signal(SIGINT, istat);
  1388. X    signal(SIGQUIT, qstat);
  1389. X    return(status);
  1390. X}
  1391. END_OF_FILE
  1392.   if test 578 -ne `wc -c <'xsystem.c'`; then
  1393.     echo shar: \"'xsystem.c'\" unpacked with wrong size!
  1394.   fi
  1395.   # end of 'xsystem.c'
  1396. fi
  1397. echo shar: End of archive 3 \(of 3\).
  1398. cp /dev/null ark3isdone
  1399. MISSING=""
  1400. for I in 1 2 3 ; do
  1401.     if test ! -f ark${I}isdone ; then
  1402.     MISSING="${MISSING} ${I}"
  1403.     fi
  1404. done
  1405. if test "${MISSING}" = "" ; then
  1406.     echo You have unpacked all 3 archives.
  1407.     rm -f ark[1-9]isdone
  1408. else
  1409.     echo You still must unpack the following archives:
  1410.     echo "        " ${MISSING}
  1411. fi
  1412. exit 0
  1413. exit 0 # Just in case...
  1414.