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

  1. Newsgroups: comp.sources.misc
  2. From: aburt@du.edu (Andrew Burt)
  3. Subject: v38i067:  menushell - A Unix Menuing Shell, Part02/03
  4. Message-ID: <1993Jul30.192523.27864@sparky.sterling.com>
  5. X-Md4-Signature: 0a9354636eb85ed4b2ce1f5f03424e0a
  6. Sender: kent@sparky.sterling.com (Kent Landfield)
  7. Organization: Sterling Software
  8. Date: Fri, 30 Jul 1993 19:25:23 GMT
  9. Approved: kent@sparky.sterling.com
  10.  
  11. Submitted-by: aburt@du.edu (Andrew Burt)
  12. Posting-number: Volume 38, Issue 67
  13. Archive-name: menushell/part02
  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:  functions2.c mshell.1 mshell.h sample.men string.c
  21. #   sysvdiffs.A
  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 2 (of 3)."'
  26. if test -f 'functions2.c' -a "${1}" != "-c" ; then 
  27.   echo shar: Will not clobber existing file \"'functions2.c'\"
  28. else
  29.   echo shar: Extracting \"'functions2.c'\" \(6544 characters\)
  30.   sed "s/^X//" >'functions2.c' <<'END_OF_FILE'
  31. X#include "mshell.h"
  32. X
  33. X
  34. Xextern char     G_homevar      [];
  35. Xextern char     G_uservar      [];
  36. Xextern char     G_termvar      [];
  37. Xextern char     G_mailfile     [WORDLEN];
  38. Xextern char     G_mail_message [WORDLEN];
  39. Xextern int      G_mailsize; 
  40. Xextern struct   stat G_st;
  41. X
  42. X/* ======================================================================= */
  43. Xexecute_command (command, args)
  44. X/* ======================================================================= */
  45. Xchar *command, *args [];
  46. X{
  47. X    /*
  48. X    char * var_args [2 * MAXARGS]; 
  49. X    char * new_var_args [MAXARGS][MAXARGS];
  50. X    */
  51. X    int pid, i, j, count = 0;
  52. X    extern int G_limited;
  53. X
  54. X    G_mail_message[0] = EOS;
  55. X
  56. X    if (G_limited && invalidcommand(args[0])) {
  57. X        printf("Invalid option in restricted menus, sorry.\n");
  58. X        printf("See the 'info' menu for how to get a real menu or shell.  (It's free.)\n");
  59. X        return;
  60. X    }
  61. X    if (strcontains(command, "*;|<>&()[]?'\"`~\\")) {
  62. X        /* let shell handle these */
  63. X        system(command);
  64. X        return;
  65. X    }
  66. X
  67. X    if (strcmp (args[0], CHANGE_DIR) == 0)
  68. X        change_directory (args[1]);
  69. X    else if (strcmp (args[0], SETENV) == 0)
  70. X        /* remove $ sign from environment variable */
  71. X        setenv (args[1], args[2]);
  72. X
  73. X     /* invoke the command using fork & exec *
  74. X      * ==================================== */
  75. X     else if ( ( pid = fork () ) == 0 ) {    /*     child process */
  76. X        signal (SIGINT,  SIG_DFL); 
  77. X        signal (SIGQUIT, SIG_DFL); 
  78. X        execvp(args[0], args);
  79. X        perror(args[0]);
  80. X        exit(1);
  81. X    }
  82. X    else
  83. X        while ( wait (0) !=  -1 )    /*    parent waits for  */
  84. X            ;             /*    child            */
  85. X}
  86. X
  87. X/* ========================================================= */
  88. Xget_actions (input_string, exec_string, args)
  89. X/* ========================================================= */
  90. Xchar *input_string, *exec_string, *args[];
  91. X{
  92. X    char *p = input_string, word[WORDLEN], *val, *type, *realval;
  93. X    char *index(), *prompt(), *ufix(), *strsave(), *strcatsave();
  94. X    int    i = 0;
  95. X
  96. X    /* Display a helpfile, if appropriate *
  97. X     * ================================== */
  98. X    extract_action_word    (input_string, HELPVAL, word, 0);
  99. X    if (word[0])
  100. X        helpfile_display(word);
  101. X
  102. X    /* pull out the actual value of args *
  103. X     * ==================================*/
  104. X
  105. X    i = -1;
  106. X    exec_string[0] = EOS;
  107. X
  108. X    /* XXX - should check i not out of bounds */
  109. X    while ( sscanf(p, "%s", word) == 1 ) {
  110. X        while (isspace(*p))    /* skip spaces, then word... */
  111. X            p++;
  112. X        p += strlen(word);    /* ...for sscanf next time */
  113. X
  114. X        if ((val = index(word, '=')) == NULL) {
  115. X            /* default: treat like arg= */
  116. X            val = word;
  117. X            type = "arg";
  118. X        }
  119. X        else {
  120. X            val[0] = EOS;    /* split word into selector and value */
  121. X            val++;        /* make val point to value part */
  122. X            type = word;
  123. X        }
  124. X
  125. X        /* build an argv entry */
  126. X        if (strcmp(type, "cmd") == 0 || strcmp(type, "arg") == 0)
  127. X            args[++i] = realval = ufix(strsave(val));
  128. X        else if (strcmp(type, "prompt") == 0)
  129. X            args[++i] = realval = strsave(prompt(val));
  130. X        else if (strcmp(type, "aarg") == 0)
  131. X            args[i] = realval = ufix(strcatsave(args[i], val));
  132. X        else if (strcmp(type, "aprompt") == 0)
  133. X            args[i] = realval = strcatsave(args[i], prompt(val));
  134. X
  135. X        /* build string for 'system' just in case */
  136. X        if (strcmp(type, "aarg") != 0 && strcmp(type, "aprompt") != 0)
  137. X            strcat(exec_string, " ");
  138. X        strcat(exec_string, realval);
  139. X    }
  140. X
  141. X    args[++i] = NULL;
  142. X}
  143. X
  144. X/* function to reorder various command line args based on original string *
  145. X ======================================================================== */
  146. Xassign_parameters (varg_ptr, input_line, command, args, aargs, promptval)
  147. Xchar * varg_ptr [2 * MAXARGS];
  148. Xchar input_line  [DESCLEN];
  149. Xchar command     [WORDLEN];
  150. Xchar args        [MAXARGS][WORDLEN];
  151. Xchar aargs       [MAXARGS][WORDLEN];
  152. Xchar promptval   [MAXARGS][WORDLEN];
  153. X
  154. X{
  155. X    char target_string [DESCLEN];
  156. X    int position, i = 0;
  157. X    
  158. X    i = 0;
  159. X    while ( strcmp (input_line, NULLSTR) != 0 ) {
  160. X
  161. X        filter_leading_trailing_blanks_tabs (input_line);
  162. X        if ( (position = strsearch (input_line, " ")) < 0 ) 
  163. X            position = strlen(input_line) - 1;
  164. X
  165. X        target_string[0] = EOS;
  166. X        strncpy ( target_string, input_line, position + 1);
  167. X        target_string [position+1] = EOS;
  168. X        remove_string (input_line, 0, position + 1);
  169. X
  170. X        if ( strsearch (target_string, CMDVAL) >= 0)
  171. X            varg_ptr [i++] = command;
  172. X        else if ( strsearch (target_string, ARGVAL) >= 0) 
  173. X            varg_ptr [i++] = (args++);
  174. X        else if ( strsearch (target_string, AARGVAL) >= 0)
  175. X            varg_ptr [i++] = (aargs++);
  176. X        else if ( strsearch (target_string, PROMPTVAL) >= 0)
  177. X            varg_ptr [i++] = (promptval++);
  178. X        else if (index(target_string, '=') == NULL) /* same as ARGVAL */
  179. X            varg_ptr [i++] = (args++);
  180. X        
  181. X    }    /* while */
  182. X}        /* assign_parameters */
  183. X
  184. Xreorganize (var_args, new_var_args, rcount)
  185. Xchar * var_args [2 * MAXARGS];
  186. Xchar * new_var_args [MAXARGS][MAXARGS];
  187. Xint  * rcount;
  188. X
  189. X{
  190. X    int i, j=0, k=0;
  191. X    char * temp;
  192. X
  193. X    for ( i=0; var_args[i] != NULL; ) {
  194. X
  195. X        while (( !index (var_args[i], PIPECHAR)) && (var_args[i] != NULL))
  196. X            new_var_args[j][k++] = var_args[i++];
  197. X
  198. X        if ( index (var_args[i], PIPECHAR) ) {
  199. X            new_var_args[j++][k] = NULL;
  200. X            k = 0;
  201. X            temp = var_args[i++];
  202. X            temp++;
  203. X            new_var_args[j]  [k++] = temp;
  204. X        }
  205. X    }
  206. X
  207. X    new_var_args [j][k] = NULL;
  208. X    *rcount = j + 1;
  209. X}
  210. X
  211. Xdoexec(args)
  212. Xchar *args[];    /* assumes is run in child process */
  213. X{
  214. X    int fds [2], rpid, i = MAXARGS;
  215. X
  216. X    while (--i > 0)
  217. X        if (args[i] && args[i][0] == PIPECHAR)
  218. X            break;
  219. X
  220. X    if (i > 0) {        /* not first command in pipeline */
  221. X        args[i]++;    /* skip PIPECHAR */
  222. X        pipe(fds);
  223. X        if (fork()) {
  224. X            dup2(fds[1], 1);
  225. X            close(fds[0]);
  226. X            close(fds[1]);
  227. X        }
  228. X        else {    /* child */
  229. X            close(0);
  230. X            dup(fds[0]);
  231. X            close (fds[0]);
  232. X            close (fds[1]);
  233. X
  234. X            while (i < MAXARGS)
  235. X                args[i++] = NULL;
  236. X
  237. X            doexec(args);
  238. X        }
  239. X    }
  240. X
  241. X    execvp(args[i], args+i);
  242. X    perror(args[i]);
  243. X    exit(0);
  244. X}
  245. X
  246. Xstruct command {
  247. X    DL_NODE n;
  248. X    char *c;
  249. X};
  250. X
  251. Xinvalidcommand(cmd)
  252. Xchar *cmd;
  253. X{
  254. X    static int initialized;
  255. X    static DLIST commands;
  256. X    int iscmd();
  257. X
  258. X    if (!initialized) {
  259. X        FILE *fp;
  260. X        char line[256], *p;
  261. X        struct command *c;
  262. X
  263. X        if ((fp = fopen(COMMAND_LIST, "r")) == NULL) {
  264. X            printf("Command list missing!\n");
  265. X            return TRUE;
  266. X        }
  267. X
  268. X        if ((commands = dl_create(DL_FREE)) == NULL) {
  269. X            printf("Out of memory!\n");
  270. X            exit(1);
  271. X        }
  272. X
  273. X        while (fgets(line, sizeof(line), fp)) {
  274. X            if ((p = malloc(strlen(line)+1)) == NULL ||
  275. X                (c = getnode(sizeof(struct command))) == NULL) {
  276. X                printf("Out of memory!\n");
  277. X                exit(1);
  278. X            }
  279. X            strcpy(p, line);
  280. X            p[strlen(p)-1] = '\0';
  281. X            c->c = p;
  282. X            dl_append(commands, c);
  283. X        }
  284. X
  285. X        fclose(fp);
  286. X        initialized = TRUE;
  287. X    }
  288. X
  289. X    return(!dl_lsearch(commands, dl_head(commands), NULL, cmd, iscmd));
  290. X}
  291. X
  292. Xiscmd(c, cmd)
  293. Xstruct command *c;
  294. Xchar *cmd;
  295. X{
  296. X    return(strcmp(cmd, c->c) == 0);
  297. X}
  298. END_OF_FILE
  299.   if test 6544 -ne `wc -c <'functions2.c'`; then
  300.     echo shar: \"'functions2.c'\" unpacked with wrong size!
  301.   fi
  302.   # end of 'functions2.c'
  303. fi
  304. if test -f 'mshell.1' -a "${1}" != "-c" ; then 
  305.   echo shar: Will not clobber existing file \"'mshell.1'\"
  306. else
  307.   echo shar: Extracting \"'mshell.1'\" \(10343 characters\)
  308.   sed "s/^X//" >'mshell.1' <<'END_OF_FILE'
  309. X.TH Mshell 1 "13 July 1993"
  310. X.SH NAME
  311. Xmshell \- menu oriented shell
  312. X.SH SYNOPSIS
  313. X.B mshell
  314. X.RB "[\|" \-r "\|]"
  315. X.RB "[\|" \-s "\|]"
  316. X.B initial-menu 
  317. X.SH DESCRIPTION
  318. X.LP
  319. X.B mshell
  320. Xis a menuing program designed to be used as a login shell or as the primary
  321. Xprogram in a wrapper shell script (to set environment, etc.).  Menus are
  322. Xintended to be simple to create without sacrificing flexibility.
  323. X.SH OPTIONS
  324. X.TP
  325. X.B \-r
  326. X.B mshell
  327. Xruns in "restricted" mode, where only commands found in a command-list file
  328. Xcan be executed.  I.e., some users may have full access to all menu options
  329. Xwhile others run under restriction.  The command-list file is currently
  330. Xhardwired via the COMMAND_LIST #define in the source, but could easily be
  331. Xturned into a command line parameter.  Further, -r inhibits user replies to
  332. Xprompts even for options that are active (to prevent users from entering
  333. Xmetacharacters which may allow unintended access).  Commands must match
  334. X*exactly* the way they are listed in the menu's "cmd=..." line, e.g.,
  335. Xfull path or no path.  See below for additional thoughts on security.
  336. X.TP
  337. X.B \-s
  338. XPrevents the execution of !command at the menu prompt and prevents users from
  339. Xtyping shell meta-characters in their replies to prompts.
  340. XSee below for additional thoughts on security.
  341. X.TP
  342. X.B initial-menu
  343. XThe name or path to the initial menu:
  344. XIf the name has a / in it, that is used as the path to the starting menu;
  345. Xif no /, then $MENUDIR/\fIinitial-menu\fP is used as the menu.
  346. X.br
  347. X.SH NOTES
  348. X.LP
  349. X.SS Startup files
  350. XIf the file .mshellrc exists in $HOME, it is run
  351. Xvia "sh".  Useful to run some intro commands (e.g., personal stty settings),
  352. Xbut note it cannot be used to set variables or other internal state elements.
  353. X.SS Logging
  354. XIf you define LOGDIR (in Makefile) to an existing dir,
  355. Xthen user activity will be logged.  (I suggest the dir should be mode 733 so
  356. Xusers can't poke around as easily).  Every menu pick a user makes is appended to
  357. Xa file named with their username; these files grows without bound and 
  358. Xmust be cleaned up manually.
  359. X.SS Environment variables
  360. XWork inside menu values (as $VAR), as does ~ for home dir.
  361. X.SS Built-in commands
  362. Xcd and setenv are built in.  The built-in command 'menu' invokes
  363. Xmshell recursively (i.e., does not create a new process for submenus).
  364. X.SS Security
  365. XTake great care if you want to use mshell in a secure environment.  It can
  366. Xbe an experiment in futility.  Using the -s and -r options you can control
  367. Xwhat programs users may run; however, note that with just -s users can
  368. Xlikely find clever ways to subvert the security and get a shell.  Even with
  369. Xboth -r and -s in effect, many of the programs you're likely to allow users
  370. Xto run may have ways to gain unintended access.  For example, 'more' allows
  371. Xusers to invoke the shell ('!' command) or vi (e.g. the 'v' command),
  372. Xfrom which they can gain instant
  373. Xshell access.  Monitor what commands you allow in -r \fIvery\fP carefully.
  374. XEven the simplest shell scripts may be subvertible!
  375. X.LP
  376. XIt helps to set the
  377. XSHELL environment variable to something like /bin/true, or better yet, a
  378. Xcommand that echoes "You can't have a shell, sorry."  This still won't foil
  379. Xa determined attack, of course.
  380. X.LP
  381. X.mshellrc is obviously a security risk.
  382. XConsider a wrapper around the menu that removes .mshellrc, for example.
  383. X.LP
  384. XNote that even with all this, mshell
  385. Xshouldn't be trusted for genuine security, since it's nearly impossible to
  386. Xeliminate the ways one can get a shell (I gave it a good whack, modifying
  387. Xbinaries of various programs, hacking on source for others, etc.; it's too
  388. Xmuch hassle and still can be circumvented).
  389. X.SS Multiple commands
  390. XIf the user types pick1,pick2,pick3 then
  391. Xeach will be executed as if the ',' were newlines.  Use 'top,...' to get
  392. X"absolute" picks, starting at the top of the menu tree.
  393. X.SS Macros
  394. XA file named $HOME/.mshellmac is read at startup for macros.  Macros look
  395. Xlike:
  396. X.RS
  397. Xname=commands
  398. X.RE
  399. XFor example:
  400. X.RS
  401. Xhist=top,i,h,x
  402. X.RE
  403. Xwhich on Nyx means <top, info menu, 'h' for history, 'x' to exit menu
  404. Xback to main>.
  405. XExecute macros as
  406. X.RS
  407. X#name
  408. X.RE
  409. Xsuch as
  410. X.RS
  411. X#hist
  412. X.RE
  413. XMacros may be execute inside multi-command lines, as in
  414. X.RS
  415. Xfoo,#hist,bar
  416. X.RE
  417. Xand inside other macros, like
  418. X.RS
  419. Xfoo=a,#hist,b,c
  420. X.RE
  421. X.SS Online help
  422. XIf a menu item has help=filename in the definition, that filename is
  423. Xprinted prior to execution or prompt input.
  424. XUsers can do 'help o' for an option 'o', in which case,
  425. Xif man=xxx is set, "man xxx" is invoked.  Failing that,
  426. X"cmd=zzz" causes "man zzz" to be run.  Thus one may let the cmd= setting
  427. Xdefault except where this invokes the wrong manual page or one wants to
  428. Xspecific a non-man(1) manual page.
  429. X.br
  430. X.ne 4
  431. X.SH MENU DEFINITION
  432. X.LP
  433. XFormat of menu file:
  434. X.RS
  435. X.nf
  436. X
  437. Xscreen layout
  438. X*****
  439. Xkeyword <tab> action_description
  440. X...
  441. X
  442. X.fi
  443. X.RE
  444. XThe top part of the screen is what the users sees -- it is just text,
  445. Xput whatever you want there; there is no specific format rules, just
  446. Xmake it look good.  The bottom describes what commands have what action.
  447. XThe bottom is comprised of two tab-separated columns: a keyword and an
  448. Xaction description.  The keyword can be any string (without a tab in it),
  449. Xusually alpha-numeric.  Presumably these keywords are displayed in the
  450. Xlayout portion so users know what to type, but that's up to you to ensure.
  451. X(That is, there is no marking of items in the top unless you want to for
  452. Xvisual effect.  Further, you can have "invisible" menu options by listing
  453. Xthem in the bottom but not the top; the drawback is that you could have
  454. Xinoperative options if you list them above and forget to list them below.)
  455. X.LP
  456. XThe simplest action description is just a shell command, as in
  457. X.RS
  458. Xw    who | sort
  459. X.RE
  460. Xwhich would execute "who|sort" when a user selects 'w' from the menu.
  461. XThe actions can be any shell code.
  462. X.LP
  463. XThe action descriptions can be built using keywords as follows:
  464. X.TP
  465. Xcmd=name_of_command
  466. Xlike arg=, but no _ translation.  In addition, it specifies this this as
  467. Xthe command to run 'man' for help.
  468. X.TP
  469. Xprompt=prompt_to_print
  470. XPrints prompt
  471. X(will be followed by colon and space).
  472. XThe user's response is interpolated as the next parameter.
  473. X.TP
  474. Xarg=literal
  475. XArgument is included at this position in command string.
  476. XThis is also the default if no \fIkeyword\fP= is given.
  477. X.TP
  478. Xaarg=literal_to_append
  479. XLike arg=, but no space put before it; e.g., to
  480. Xappend a filename extension after a prompted value.
  481. X.TP
  482. Xaprompt=prompt_to_append
  483. XPrompts and appends to previous argument (e.g., a literal value).
  484. X.TP
  485. Xhelp=name_of_helpfile
  486. XPrints said helpfile (printed immediately, i.e., before input or
  487. Xexecution of command).
  488. X.TP
  489. Xman=name_of_manual
  490. XSpecifies manual entry to use for 'help'; useful if cmd= isn't set to something
  491. Xyou want a 'man' on or there isn't anything interesting to set cmd= to.
  492. X.LP
  493. XNotice that no <type>= is the same as "arg=".
  494. X.LP
  495. XIn [a]prompt= and [a]arg=, underscores will be translated to spaces on
  496. Xoutput and
  497. Xare mandatory in multi-word strings (i.e., if you have "prompt=foo bar" the
  498. Xprompt will be foo and bar will be looked on as the next action description
  499. Xword; instead do "prompt=foo_bar").  Tabs in strings don't work (could be
  500. Xhandled similar to _ for space, but aren't at present).
  501. X.LP
  502. XThe result is put into a string; if it has any meta-characters that
  503. Xshould be handled by a shell, then the result is fed to system() so
  504. Xthe shell (csh in particular) can deal with it.  Otherwise, mshell
  505. Xexecutes the command directly.
  506. X.LP
  507. XIf the first keyword listed in the description section is "_init",
  508. Xthis command will be executed upon entry into the menu (before any selection).
  509. X.LP
  510. XAt "Enter choice" prompt, a response beginning with ! causes the remainder
  511. Xof the line to be executed verbatim.  (E.g., !who will run a who.)  (Assuming
  512. Xthis has not been disabled by -s.)
  513. X.LP
  514. XAll menus respond to certain built-in options, namely 'x' to exit the menu,
  515. X'bye' to leave the program, 'top' to return to the top level (initial
  516. Xmenu), and 'help xxx' to invoke the help for option xxx.
  517. X.LP
  518. XA sample menu file might be:
  519. X.RS
  520. X.nf
  521. X                Main menu
  522. X                =========
  523. X
  524. Xf    Upload/Download file menu     i    Information...
  525. Xs    Status/options/users menu    u    Unix file access menu
  526. X
  527. Xc    Communications menu -- bulletins, NetNews, mail, chat
  528. X
  529. Xp    Programming menu
  530. Xe    Education menu            w    Word processing menu
  531. Xg    Games menu            gr    Graphics menu         
  532. Xfaq    Frequently Asked Questions    o    Organization menus
  533. X
  534. Xin      Introduce yourself to other Nyx users
  535. X
  536. Xfund    Info on the "fund drive" to speed up ol' Nyx
  537. X
  538. Xfb    Send feedback to sysop (comments, questions, etc.)
  539. X*****
  540. Xu    cmd=menu arg=$mendir/file.men
  541. Xc    cmd=menu $mendir/comm.men
  542. Xw    cmd=menu $mendir/wp.men
  543. Xp    cmd=menu $mendir/prog.men
  544. Xg    cmd=menu $mendir/games.men
  545. Xs    cmd=menu $mendir/stat.men
  546. Xgr    cmd=menu $mendir/graphics.men
  547. Xi    cmd=menu $mendir/info.men
  548. Xf    cmd=menu $mendir/updownload.men
  549. Xe    cmd=menu $mendir/edu.men
  550. Xo    cmd=menu $mendir/org.men
  551. Xfb    /u5/bin/comment
  552. Xin    /u5/bin/introduction
  553. Xfund    cmd=more -d $mendir/info/fund.drive
  554. Xfaq    cmd=more -d $mendir/info/faq
  555. X
  556. XSome other random example commands:
  557. X
  558. X_init    cmd=cd $downloaddir
  559. Xused    cmd=du -s $HOME
  560. Xs    cmd=fgrep prompt=String_to_find prompt=Files_to_search_(sep._by_spaces)
  561. Xfn    cmd=find $HOME_-name prompt=File -print
  562. Xco    echo 'lines____words____chars'; cmd=wc prompt=File
  563. Xec    cmd=crypt prompt=Input_file > prompt=Output_file
  564. Xa    cd $dldir/.areas/ aprompt=Area# help=$dldir/.areas/.list
  565. Xl    (echo -n "Current area: ";pwd;sort .catalog)|lineup|more
  566. Xs    mail prompt=To help=$mendir/facmain.help
  567. X.fi
  568. X.RE
  569. X.SH RECOMMENDATIONS
  570. X.SS Use full pathnames for filenames.
  571. X.SS Use multiple main menus for different classes of users.
  572. X.SS You'll need various script files as wrappers around commands.
  573. X.SS Look on Nyx (nyx.cs.du.edu, login as 'new') for various examples.
  574. X.SH AUTHOR
  575. X.LP
  576. XOriginal shell script version by Andrew Burt
  577. Xof the University of Denver department of math and computer science.
  578. XInitially coded in C by Dinesh Punjabi (yes, as a student project).
  579. XSubsequent hacks and maintenance by Andrew Burt, reachable as aburt@du.edu.
  580. X.SH BUGS
  581. X.LP
  582. XNo doubt.  I've heard tales of occasional glitches where the menus get
  583. Xvery hosed up, but haven't searched for causes.  I suspect there are some
  584. Xmemory leaks lurking around as well in some of the older code.  The reliance
  585. Xon fixed size strings stems from the original, and should be replaced.
  586. XThe original System V code has not been tested in ages and may no longer even
  587. Xcompile; the newer diffs haven't been tested.
  588. END_OF_FILE
  589.   if test 10343 -ne `wc -c <'mshell.1'`; then
  590.     echo shar: \"'mshell.1'\" unpacked with wrong size!
  591.   fi
  592.   # end of 'mshell.1'
  593. fi
  594. if test -f 'mshell.h' -a "${1}" != "-c" ; then 
  595.   echo shar: Will not clobber existing file \"'mshell.h'\"
  596. else
  597.   echo shar: Extracting \"'mshell.h'\" \(2501 characters\)
  598.   sed "s/^X//" >'mshell.h' <<'END_OF_FILE'
  599. X#include <stdio.h>
  600. X#include <curses.h>
  601. X#include <sys/signal.h>
  602. X#include <pwd.h>
  603. X#include <sys/types.h>
  604. X#include <sys/stat.h>
  605. X#ifdef BSD
  606. X#include <sys/dir.h>        /* accessing the directory structure    */
  607. X#include <sgtty.h>        /* struct for terminal attributes       */
  608. X#endif
  609. X#ifdef SYSV
  610. X#define index    strchr
  611. X#define rindex    strrchr
  612. X/* #include <termio.h>        /* do this if curses.h doesn't */
  613. X#endif
  614. X#include "dl.h"
  615. X
  616. X#define  BLANK           ' '
  617. X#define  COLUMNS         256
  618. X#define  DESCLEN         128
  619. X#define  EOS             '\0'
  620. X#define  EXCLAIM         '!'
  621. X#define  LINES           80
  622. X#define  MAXARGS         10
  623. X#define  MAXLEN          256
  624. X#define  NULLSTR         ""
  625. X#define  MAIL_MESSAGE    "    [You have new mail]"
  626. X#define  OPTLEN          16
  627. X#define  PIPECHAR        '|'
  628. X#define  DELIM_LINE      "*****\n"    /* \n since fgets is used */
  629. X#define  SUFFIX          ".men"
  630. X#define  TAB             '\t'
  631. X#define  HOME_CHAR       "~"
  632. X#define  VISIBLE_SPACE   '_'
  633. X#define  WORDLEN         64
  634. X
  635. X#define  CMDVAL          "cmd="
  636. X#define  ARGVAL          "arg="
  637. X#define  AARGVAL         "aarg="
  638. X#define  HELPVAL         "help="
  639. X#define  PROMPTVAL       "prompt="
  640. X#define  APROMPTVAL      "aprompt="
  641. X#define  HELP            "help"
  642. X#define  MAN             "man="
  643. X#define  BYE             "bye"
  644. X#define  QUIT            "x"
  645. X#define  CHANGE_DIR      "cd"
  646. X#define  SETENV         "setenv"
  647. X
  648. X#ifndef  MAILDIR
  649. X#define  MAILDIR         "/usr/spool/mail/"
  650. X#endif
  651. X#ifndef  MENUDIR
  652. X#define  MENUDIR         "/nyx/lib/menus"
  653. X#endif
  654. X#ifndef  GLOBAL_MACRO_FILE
  655. X#define  GLOBAL_MACRO_FILE         "/nyx/lib/menus/macros"
  656. X#endif
  657. X#ifndef  COMMAND_LIST
  658. X#define  COMMAND_LIST         "/nyx/lib/menus/commands"
  659. X#endif
  660. X
  661. X#ifndef TRUE    /* curses.h may #define */
  662. X#define TRUE   1
  663. X#define FALSE  0
  664. X#endif
  665. X
  666. Xstruct   menu_struct {
  667. X    char curr [WORDLEN];
  668. X    char prev [WORDLEN];
  669. X};
  670. X
  671. X#define void    int
  672. Xint     all_blanks ();
  673. Xvoid    change_directory();
  674. Xvoid    check_for_new_mail ();
  675. Xvoid     helpfile_display ();
  676. Xvoid     display_menu ();
  677. Xvoid     display_prompts ();
  678. Xvoid     execute_command ();
  679. Xvoid     extract_actions ();
  680. Xvoid     extract_action_word ();
  681. Xvoid    filter_leading_trailing_blanks_tabs ();
  682. Xchar *     find_string ();
  683. Xvoid    find_user_details ();
  684. Xchar *  in_string ();
  685. Xvoid    initialize ();
  686. Xvoid     insert_string ();
  687. Xvoid    invoke_unix_system ();
  688. Xvoid     M_Shell ();
  689. Xvoid     read_input_line ();
  690. Xvoid     remove_string ();
  691. Xint     replace_string ();
  692. Xvoid     search_menu_array ();
  693. Xint     strsearch ();
  694. Xvoid     set_terminal_attributes ();
  695. Xint        setenv ();
  696. Xvoid     wait_for_user ();
  697. END_OF_FILE
  698.   if test 2501 -ne `wc -c <'mshell.h'`; then
  699.     echo shar: \"'mshell.h'\" unpacked with wrong size!
  700.   fi
  701.   # end of 'mshell.h'
  702. fi
  703. if test -f 'sample.men' -a "${1}" != "-c" ; then 
  704.   echo shar: Will not clobber existing file \"'sample.men'\"
  705. else
  706.   echo shar: Extracting \"'sample.men'\" \(1455 characters\)
  707.   sed "s/^X//" >'sample.men' <<'END_OF_FILE'
  708. X                Main menu
  709. X                =========
  710. X
  711. Xf    Upload/Download file menu     i    Information...
  712. Xs    Status/options/users menu    u    Unix file access menu
  713. X
  714. Xc    Communications menu -- bulletins, NetNews, mail, chat
  715. X
  716. Xt    TTCC Resources            p    Programming menu
  717. Xe    Education menu            w    Word processing menu
  718. Xg    Games menu            gr    Graphics menu         
  719. Xfaq    Frequently Asked Questions    o    Organization menus
  720. X
  721. Xin      Introduce yourself to other Nyx users
  722. X
  723. Xfund    Info on the "fund drive" to speed up ol' Nyx
  724. X
  725. Xfb    Send feedback to sysop (comments, questions, etc.)
  726. X*****
  727. Xu    cmd=menu arg=$mendir/file.men
  728. Xc    cmd=menu $mendir/comm.men
  729. Xw    cmd=menu $mendir/wp.men
  730. Xp    cmd=menu $mendir/prog.men
  731. Xg    cmd=menu $mendir/games.men
  732. Xs    cmd=menu $mendir/stat.men
  733. Xgr    cmd=menu $mendir/graphics.men
  734. Xi    cmd=menu $mendir/info.men
  735. Xf    cmd=menu $mendir/updownload.men
  736. Xe    cmd=menu $mendir/edu.men
  737. Xo    cmd=menu $mendir/org.men
  738. Xfb    cmd=/u5/bin/comment
  739. Xt    cmd=/u1/bin/ttcclogin
  740. Xin    cmd=/u5/bin/introduction
  741. Xfund    cmd=more -d $mendir/info/fund.drive
  742. Xfaq    cmd=more -d $mendir/info/faq
  743. X
  744. XSome other random example commands:
  745. X
  746. X_init    cmd=cd $dldir
  747. Xused    cmd=du -s $HOME
  748. Xs    cmd=fgrep prompt=String_to_find prompt=Files_to_search_(sep._by_spaces)
  749. Xfn    cmd=find $HOME_-name prompt=File -print
  750. Xco    cmd=echo 'lines____words____chars'; wc prompt=File
  751. Xec    cmd=crypt prompt=Input_file > prompt=Output_file
  752. Xa    cmd=cd $dldir/.areas/ aprompt=Area# help=$dldir/.areas/.list
  753. Xl    cmd=(echo_-n_"Current_area:_";pwd;sort_.catalog)|lineup|more
  754. Xs    cmd=mail help=$mendir/facmain.help prompt=To
  755. END_OF_FILE
  756.   if test 1455 -ne `wc -c <'sample.men'`; then
  757.     echo shar: \"'sample.men'\" unpacked with wrong size!
  758.   fi
  759.   # end of 'sample.men'
  760. fi
  761. if test -f 'string.c' -a "${1}" != "-c" ; then 
  762.   echo shar: Will not clobber existing file \"'string.c'\"
  763. else
  764.   echo shar: Extracting \"'string.c'\" \(8418 characters\)
  765.   sed "s/^X//" >'string.c' <<'END_OF_FILE'
  766. X#include "mshell.h"
  767. X
  768. X#ifdef BSD
  769. X#define strchr    index
  770. X#endif
  771. X
  772. X
  773. X/* function to find the position of sub_string in main_string 
  774. X * ---------------------------------------------------------- */
  775. X
  776. Xstrsearch (main_string, sub_string)
  777. Xchar main_string[], sub_string[];
  778. X{
  779. X    int start_mstring = 0, start_sstring = 0, 
  780. X        factor = 0, answer, main_pos = 0;
  781. X
  782. X        while ( main_string[start_mstring] != EOS  &&
  783. X            sub_string[start_sstring] != EOS )       {
  784. X
  785. X            if ( main_string[start_mstring] !=
  786. X                      sub_string[start_sstring] )  {
  787. X                ++main_pos;
  788. X                start_mstring = main_pos;
  789. X                start_sstring = 0;
  790. X                factor = 0;
  791. X            }
  792. X            else   {
  793. X                ++factor;
  794. X                ++start_mstring;
  795. X                ++start_sstring;
  796. X            }        /* end if-else */
  797. X
  798. X        }            /* end while */
  799. X
  800. X        if (( sub_string[start_sstring] == EOS && factor > 0 ) ||
  801. X            ( main_string[start_mstring] == EOS &&
  802. X               sub_string[start_sstring] == EOS ))   {
  803. X
  804. X            answer = main_pos;
  805. X            return(answer);
  806. X        }
  807. X        else 
  808. X            return(-1);    /* end if-else */
  809. X}                    /* end function strsearch */
  810. X
  811. X/* function to remove string starting at a specified position  
  812. X * ----------------------------------------------------------  */
  813. X
  814. Xremove_string (main_string, start_index, no_of_bytes )
  815. Xchar main_string[];
  816. Xint  start_index, no_of_bytes;
  817. X
  818. X{
  819. X    int index, offset;
  820. X
  821. X    offset = strlen (main_string) - no_of_bytes;
  822. X    /* offset is defined as the index no of the last element which
  823. X     * will be present in the new string or the unremoved bytes +
  824. X     * bytes that need to be repositioned */
  825. X
  826. X    for ( index = start_index; index < offset; ++ index ) 
  827. X        main_string [index] = main_string [index + no_of_bytes];
  828. X
  829. X    main_string[index] = EOS;
  830. X
  831. X}                /* end of function remove_string */
  832. X
  833. X/* replace string function 
  834. X * ----------------------- */
  835. X
  836. Xint replace_string (main_string, old_string, new_string)
  837. Xchar main_string[256], old_string[256], new_string[256]; 
  838. X
  839. X{
  840. X    int  pos;
  841. X
  842. X    pos = strsearch (main_string, old_string);
  843. X
  844. X    if ( pos >= 0 ) {
  845. X        remove_string (main_string, pos, strlen(old_string));
  846. X        insert_string (main_string, new_string, pos);
  847. X        return (TRUE);
  848. X    /*     printf ("\n\n\tnew string is  %s\n\n", main_string); */
  849. X    }
  850. X    else
  851. X        return (FALSE);
  852. X}     /* end function replace_string */
  853. X
  854. X/* function to find insert sub-string in main-string at a specific position
  855. X * ------------------------------------------------------------------------ */
  856. X
  857. Xinsert_string ( main_string, sub_string, position )
  858. Xchar main_string [], sub_string [];
  859. Xint  position;
  860. X
  861. X{
  862. X    int i, j, offset;
  863. X
  864. X    if (sub_string) {
  865. X        offset = strlen(sub_string);
  866. X        j = strlen (main_string);
  867. X
  868. X        for (i = j; i >= position; i--)
  869. X            main_string [i+offset] = main_string [i];
  870. X
  871. X        for (i=0; i < offset ; i++) 
  872. X            main_string [i+position] = sub_string [i];
  873. X
  874. X        main_string [j+offset] = EOS;
  875. X    }
  876. X}
  877. X
  878. X#include <ctype.h>
  879. X
  880. X#define NULL    0
  881. X#define STRLEN    256
  882. X
  883. Xchar *
  884. Xfindvar(s)
  885. Xchar *s;
  886. X{
  887. X    static char var[STRLEN];
  888. X    char *p, *v = var, *strchr();
  889. X
  890. X    if ((p = strchr(s, '$')) == NULL)
  891. X        return (NULL);
  892. X
  893. X    p++;    /* skip $ */
  894. X
  895. X    while (isalnum(*p))
  896. X        *v++ = *p++;
  897. X
  898. X    *v = '\0';
  899. X
  900. X    return(var);
  901. X}
  902. X
  903. Xsubstitute(s)
  904. Xchar *s;
  905. X{
  906. X    char var[STRLEN], *v_in_s, *getenv();
  907. X
  908. X    if ((v_in_s = findvar(s)) == NULL)
  909. X        return(0);
  910. X    
  911. X    sprintf(var, "$%s", v_in_s);
  912. X    replace_string(s, var, getenv(v_in_s));
  913. X    return(1);
  914. X}
  915. X
  916. X#ifdef DEBUGGING
  917. Xmain()
  918. X{
  919. X    char s[STRLEN];
  920. X
  921. X    while (1) {
  922. X        printf("s-> ");
  923. X        gets(s);
  924. X        substitute(s);
  925. X        printf("--> %s\n", s);
  926. X    }
  927. X}
  928. X#endif
  929. X
  930. Xall_blanks (string)
  931. Xchar * string;
  932. X{
  933. X    for ( ; ((*string == BLANK) && (*string != EOS)) ; ++string);
  934. X
  935. X    if ( *string == EOS ) 
  936. X        return (TRUE);
  937. X    else
  938. X        return (FALSE);
  939. X}
  940. X
  941. X/* function to find position  of sub string in a main string 
  942. X * ---------------------------------------------------------- */
  943. X
  944. X/* ========================================= */
  945. Xchar * find_string (main_string, sub_string)
  946. X/* ========================================= */
  947. Xchar main_string[], sub_string[];
  948. X{
  949. X    int start_mstring = 0, start_sstring = 0, 
  950. X        factor = 0, answer, main_pos = 0;
  951. X
  952. X        while ( main_string[start_mstring] != EOS  &&
  953. X            sub_string[start_sstring] != EOS )       {
  954. X
  955. X            if ( main_string[start_mstring] !=
  956. X                      sub_string[start_sstring] )  {
  957. X                ++main_pos;
  958. X                start_mstring = main_pos;
  959. X                start_sstring = 0;
  960. X                factor = 0;
  961. X            }
  962. X            else   {
  963. X                ++factor;
  964. X                ++start_mstring;
  965. X                ++start_sstring;
  966. X            }        /* end if-else */
  967. X
  968. X        }            /* end while */
  969. X
  970. X        if (( sub_string[start_sstring] == EOS && factor > 0 ) ||
  971. X            ( main_string[start_mstring] == EOS &&
  972. X               sub_string[start_sstring] == EOS ))   {
  973. X
  974. X            answer = main_pos;
  975. X            return(&main_string[main_pos]);
  976. X        }
  977. X        else  {
  978. X            /* answer = -1; */
  979. X            return(NULL);    /* end if-else */
  980. X        }
  981. X}                    /* end function find_string */
  982. X
  983. X/******************************************************************************
  984. X * reads a line of input string from the terminal and keeps doing so until    *
  985. X * input string contains no colons                                            *
  986. X *****************************************************************************/
  987. X
  988. X
  989. Xstruct inp_link {
  990. X    DL_NODE n;
  991. X    char *input;
  992. X};
  993. Xstatic DLIST inputstack;
  994. X
  995. Xread_input_line(string)
  996. Xchar *string;
  997. X{
  998. X    extern int G_shell_ok;
  999. X    char *p;
  1000. X
  1001. X    if (string == NULL) {    /* just read and trash line */
  1002. X        int c;
  1003. X        while ((c = getchar()) != '\n' && c != EOF)
  1004. X            ;
  1005. X        return;
  1006. X    }
  1007. X
  1008. X    if (inputstack == NULL)
  1009. X        inputstack = dl_create(DL_FREE);
  1010. X
  1011. X    do {
  1012. X        /* if any input (e.g., from last time) on stack use that... */
  1013. X        if (dl_size(inputstack) > 0) {
  1014. X            struct inp_link *l;
  1015. X            l = (struct inp_link *) dl_shead(inputstack);
  1016. X            strcpy(string, l->input);
  1017. X            free(l->input);
  1018. X            dl_delete(inputstack);
  1019. X        } /* ... else get some new input */
  1020. X        else if (gets(string) == NULL) {
  1021. X            printf("End of input -- quitting...\n");
  1022. X            exit(1);
  1023. X        }
  1024. X
  1025. X        /* if it has a multi-command delim, save rest for next time */
  1026. X#define MULTI_CMD_DELIM ','
  1027. X        if (p = index(string, MULTI_CMD_DELIM)) {
  1028. X            char *strsave();
  1029. X            struct inp_link *l;
  1030. X            *p++ = EOS;
  1031. X            if ((l=getnode(sizeof(*l))) && (l->input=strsave(p)))
  1032. X                dl_prepend(inputstack, l);
  1033. X        }
  1034. X
  1035. X        filter_leading_trailing_blanks_tabs (string);
  1036. X
  1037. X        /* if macro, then expand & push definition on stack */
  1038. X#define MACRO_DELIM '#'
  1039. X        if (string[0] == MACRO_DELIM) {
  1040. X            char *mac_lookup();
  1041. X            char *def = mac_lookup(string+1);
  1042. X            struct inp_link *l;
  1043. X            if (def && (l = getnode(sizeof(*l))) &&
  1044. X                        (l->input = strsave(def)))
  1045. X                dl_prepend(inputstack, l);
  1046. X        }
  1047. X    } while (string[0] == MACRO_DELIM);
  1048. X
  1049. X    /* if not allowing shell, then chop off at funny chars */
  1050. X    if (! G_shell_ok)
  1051. X        truncate_at_invalid_chars (string);
  1052. X
  1053. X}  /* end function read_input_line */
  1054. X
  1055. Xint moreinput()
  1056. X{
  1057. X    return (inputstack && dl_size(inputstack) > 0);
  1058. X}
  1059. X
  1060. X
  1061. X/****************************************************************************
  1062. X * Function to filter out all leading and trailing blanks from a strings    *
  1063. X * Takes a character string as a parameter                                  *
  1064. X ****************************************************************************/
  1065. X
  1066. Xvoid filter_leading_trailing_blanks_tabs ( string )
  1067. Xchar * string;
  1068. X{
  1069. X    int i, j ;
  1070. X
  1071. X    for ( i = 0 ; (( string[i] != EOS ) && (( string[i] == BLANK )
  1072. X                        ||  ( string[i] == TAB   )) ); ++i )
  1073. X        ;
  1074. X    for ( j = 0 ; ( string[j] != EOS ) ; ++j ) 
  1075. X        string[j] = string[j + i];
  1076. X
  1077. X    string[j] = EOS;
  1078. X
  1079. X    for ( i = strlen(string) - 1 ; ( i >= 0 ) ; --i )
  1080. X        if (( string[i] != BLANK ) && ( string[i] != TAB ))
  1081. X            break;
  1082. X
  1083. X    string[i+1] = EOS; 
  1084. X
  1085. X    return ;
  1086. X}
  1087. X
  1088. Xchar *
  1089. Xstrsave(s)
  1090. Xchar *s;
  1091. X{
  1092. X    char *p, *malloc();
  1093. X    if (s == NULL || (p=malloc(strlen(s)+1)) == NULL)
  1094. X        return(NULL);
  1095. X    strcpy(p, s);
  1096. X
  1097. X    return(p);
  1098. X}
  1099. X
  1100. X/* assumes d was malloc'd -- then makes large enough to cat s onto it */
  1101. Xchar *
  1102. Xstrcatsave(d, s)
  1103. Xchar *d, *s;
  1104. X{
  1105. X    char *realloc();
  1106. X
  1107. X    if (d && (d = realloc(d, strlen(d)+strlen(s)+2)))
  1108. X        strcat(d, s);
  1109. X
  1110. X    return(d);
  1111. X}
  1112. X
  1113. X/* replace _ with space */
  1114. Xchar *
  1115. Xufix(s)
  1116. Xchar *s;
  1117. X{
  1118. X    char *p;
  1119. X    for (p = s; p && *p; p++)
  1120. X        if (*p == '_')
  1121. X            *p = ' ';
  1122. X    return(s);
  1123. X}
  1124. X
  1125. Xstrcontains(s, chars)
  1126. Xchar *s, *chars;
  1127. X{
  1128. X    while (*chars)
  1129. X        if (index(s, *chars++))
  1130. X            return(1);
  1131. X    return(0);
  1132. X}
  1133. X
  1134. X/* remove string from no-no chars on */
  1135. Xtruncate_at_invalid_chars (string)
  1136. Xchar *string;
  1137. X{
  1138. X    char *p, *index();
  1139. X    /* XXX - update to use strpbrk */
  1140. X    if (p = index(string, ';'))
  1141. X        *p = EOS;
  1142. X    if (p = index(string, '`'))
  1143. X        *p = EOS;
  1144. X    if (p = index(string, '|'))
  1145. X        *p = EOS;
  1146. X    if (p = index(string, '<'))
  1147. X        *p = EOS;
  1148. X    if (p = index(string, '>'))
  1149. X        *p = EOS;
  1150. X    if (p = index(string, '^'))
  1151. X        *p = EOS;
  1152. X    if (p = index(string, '('))
  1153. X        *p = EOS;
  1154. X    if (p = index(string, '&'))
  1155. X        *p = EOS;
  1156. X}
  1157. END_OF_FILE
  1158.   if test 8418 -ne `wc -c <'string.c'`; then
  1159.     echo shar: \"'string.c'\" unpacked with wrong size!
  1160.   fi
  1161.   # end of 'string.c'
  1162. fi
  1163. if test -f 'sysvdiffs.A' -a "${1}" != "-c" ; then 
  1164.   echo shar: Will not clobber existing file \"'sysvdiffs.A'\"
  1165. else
  1166.   echo shar: Extracting \"'sysvdiffs.A'\" \(25319 characters\)
  1167.   sed "s/^X//" >'sysvdiffs.A' <<'END_OF_FILE'
  1168. XFrom szebra!Saigon.COM!root@sonyusa.Sony.COM Sun Mar 21 22:15:30 1993
  1169. XReturn-Path: <szebra!Saigon.COM!root@sonyusa.Sony.COM>
  1170. XReceived: from Sony.COM by nyx.cs.du.edu (4.1/SMI-4.1)
  1171. X    id AA18581; Sun, 21 Mar 93 22:15:20 MST
  1172. XX-Disclaimer: Nyx is a public access Unix system run by the University
  1173. X    of Denver.  The University has neither control over nor
  1174. X    responsibility for the opinions or correct identity of users.
  1175. XReceived: from sonyusa.Sony.COM!szebra!Saigon.COM by Sony.COM (5.65+/1.34)
  1176. X    id AA18833; Sun, 21 Mar 93 21:05:20 -0800
  1177. XReceived: by sonyusa.Sony.COM (4.0/SMI-4.0)
  1178. X    id AA00651; Sun, 21 Mar 93 21:01:06 PST
  1179. XReceived: by szebra.Saigon.COM (4.1/SVR4.i386-1.02)
  1180. X    id AA19888; Sun, 21 Mar 93 21:55:21 PST
  1181. XDate: Sun, 21 Mar 93 21:55:21 PST
  1182. XMessage-Id: <9303220555.AA19888@szebra.Saigon.COM>
  1183. XFrom: root@szebra.Saigon.COM
  1184. XTo: aburt@nyx.cs.du.edu
  1185. XCc: tin@smsc.Sony.COM
  1186. XSubject: MSH cdifs
  1187. XStatus: OR
  1188. X
  1189. XAndrew,
  1190. X
  1191. X  Here is the context dif of the changes I made to msh.  It is running
  1192. Xon Saigon.COM, or will be when I have all the menus ready.
  1193. X
  1194. XRegards,
  1195. XTin Le
  1196. X
  1197. X-----------------------------------------------------------------
  1198. Xdiff -rc msh/Makefile msh.orig/Makefile
  1199. X*** msh/Makefile    Tue Mar  9 20:37:53 1993
  1200. X--- msh.orig/Makefile    Mon Mar 15 23:26:26 1993
  1201. X***************
  1202. X*** 8,23 ****
  1203. X  #
  1204. X  # Check mshell.h for other options, e.g., max menu sizes.
  1205. X  
  1206. X! MENUDIR='"/usr/local/mshell/menus"'
  1207. X! LOGDIR='"/usr/local/mshell/logs"'
  1208. X! 
  1209. X! CFLAGS =  -g -DSYSV -DMENUDIR=$(MENUDIR) -DLOGDIR=$(LOGDIR) -Xa
  1210. X! LFLAGS= -lcurses -ltermcap
  1211. X  OBJS =    mshell.o main.o string.o functions1.o functions2.o chdir.o mail.o \
  1212. X      settatr.o setenv.o xsystem.o dl.o macro.o
  1213. X  
  1214. X  mshell: $(OBJS)
  1215. X!     cc $(CFLAGS) $(OBJS) $(LFLAGS) -o mshell
  1216. X  
  1217. X  $(OBJS) : mshell.h
  1218. X  
  1219. X--- 8,19 ----
  1220. X  #
  1221. X  # Check mshell.h for other options, e.g., max menu sizes.
  1222. X  
  1223. X! CFLAGS =  -O -DBSD -DMENUDIR='"/nyx/lib/menus"' -DLOGDIR='"/nyx/lib/logs"'
  1224. X  OBJS =    mshell.o main.o string.o functions1.o functions2.o chdir.o mail.o \
  1225. X      settatr.o setenv.o xsystem.o dl.o macro.o
  1226. X  
  1227. X  mshell: $(OBJS)
  1228. X!     cc $(CFLAGS) $(OBJS) -lcurses -ltermcap -o mshell
  1229. X  
  1230. X  $(OBJS) : mshell.h
  1231. X  
  1232. XOnly in msh: RCS
  1233. Xdiff -rc msh/chdir.c msh.orig/chdir.c
  1234. X*** msh/chdir.c    Sun Mar 14 11:32:15 1993
  1235. X--- msh.orig/chdir.c    Mon Mar 15 23:26:26 1993
  1236. X***************
  1237. X*** 1,7 ****
  1238. X  #include "mshell.h"
  1239. X  
  1240. X- static char chdir_rcsid[] = "$Header: /usr3/src/msh/RCS/chdir.c,v 1.1 1993/03/14 19:32:07 root Exp root $";
  1241. X- 
  1242. X  extern char     G_homevar      [];
  1243. X  extern char     G_uservar      [];
  1244. X  extern char     G_termvar      [];
  1245. X--- 1,5 ----
  1246. X***************
  1247. X*** 10,33 ****
  1248. X  extern int      G_mailsize; 
  1249. X  extern struct   stat G_st;
  1250. X  
  1251. X! void change_directory(char *new_dir)
  1252. X  {
  1253. X      char old_dir [MAXLEN]; 
  1254. X      int i;
  1255. X  
  1256. X  #ifdef BSD
  1257. X!     getwd(old_dir);
  1258. X  #endif
  1259. X  #ifdef SYSV
  1260. X      getcwd(old_dir, sizeof(old_dir));
  1261. X  #endif
  1262. X  
  1263. X!     if ( strcmp(new_dir, NULLSTR) == 0 )
  1264. X!         printw("\tno directory change requested !!\n\n");
  1265. X          /* XXX - could cd home */
  1266. X      else {
  1267. X!         printw("\n\n");
  1268. X!         if (chdir(new_dir) != 0) 
  1269. X!             printw("\tNo such directory as %s\n\n\n", new_dir);
  1270. X      }        /* end else strcmp */
  1271. X  }            /* terminate function change_directory */
  1272. X--- 8,33 ----
  1273. X  extern int      G_mailsize; 
  1274. X  extern struct   stat G_st;
  1275. X  
  1276. X! void change_directory(new_dir)
  1277. X! char *new_dir;
  1278. X! 
  1279. X  {
  1280. X      char old_dir [MAXLEN]; 
  1281. X      int i;
  1282. X  
  1283. X  #ifdef BSD
  1284. X!     getwd (old_dir);
  1285. X  #endif
  1286. X  #ifdef SYSV
  1287. X      getcwd(old_dir, sizeof(old_dir));
  1288. X  #endif
  1289. X  
  1290. X!     if ( strcmp ( new_dir, NULLSTR ) == 0 )
  1291. X!         printf ("\t no directory change requested !!\n\n");
  1292. X          /* XXX - could cd home */
  1293. X      else {
  1294. X!         printf ("\n\n");
  1295. X!         if ( chdir (new_dir) != 0 ) 
  1296. X!             printf ("\t No such directory as %s\n\n\n", new_dir );
  1297. X      }        /* end else strcmp */
  1298. X  }            /* terminate function change_directory */
  1299. Xdiff -rc msh/dl.c msh.orig/dl.c
  1300. X*** msh/dl.c    Sun Mar 14 11:32:15 1993
  1301. X--- msh.orig/dl.c    Mon Mar 15 23:26:29 1993
  1302. X***************
  1303. X*** 1,15 ****
  1304. X  /* ============================== dl.c ============================== */
  1305. X  #include "dl.h"
  1306. X  
  1307. X- static char dl_rcsid[] = "$Header: /usr3/src/msh/RCS/dl.c,v 1.1 1993/03/14 19:32:07 root Exp root $";
  1308. X- 
  1309. X- #ifdef SYSV
  1310. X- #include <stdlib.h>
  1311. X- #else
  1312. X  void *malloc();
  1313. X- #endif
  1314. X  
  1315. X! char *getnode(int size)
  1316. X  {
  1317. X      DL_NODE *n;
  1318. X  
  1319. X--- 1,9 ----
  1320. X  /* ============================== dl.c ============================== */
  1321. X  #include "dl.h"
  1322. X  
  1323. X  void *malloc();
  1324. X  
  1325. X! char *getnode(size)
  1326. X  {
  1327. X      DL_NODE *n;
  1328. X  
  1329. X***************
  1330. X*** 17,26 ****
  1331. X          memset(n, '\0', size);
  1332. X          n->size = size;
  1333. X      }
  1334. X!     return((char *)n);
  1335. X  }
  1336. X  
  1337. X! freenode(DL_NODE *n)
  1338. X  {
  1339. X      free(n);
  1340. X  }
  1341. X--- 11,21 ----
  1342. X          memset(n, '\0', size);
  1343. X          n->size = size;
  1344. X      }
  1345. X!     return(n);
  1346. X  }
  1347. X  
  1348. X! freenode(n)
  1349. X! DL_NODE *n;
  1350. X  {
  1351. X      free(n);
  1352. X  }
  1353. X***************
  1354. X*** 28,38 ****
  1355. X  /*
  1356. X   * Create an empty list
  1357. X   */
  1358. X! DLIST dl_create(int flags)
  1359. X  {
  1360. X      DLIST l;
  1361. X  
  1362. X!     if ((l = (DLIST)malloc(sizeof(struct dl))) == NULL)
  1363. X          return NULL;
  1364. X  
  1365. X      l->head = l->tail = l->curr = NULL;
  1366. X--- 23,34 ----
  1367. X  /*
  1368. X   * Create an empty list
  1369. X   */
  1370. X! DLIST dl_create(flags)
  1371. X! int flags;
  1372. X  {
  1373. X      DLIST l;
  1374. X  
  1375. X!     if ((l = (DLIST) malloc(sizeof(struct dl))) == NULL)
  1376. X          return NULL;
  1377. X  
  1378. X      l->head = l->tail = l->curr = NULL;
  1379. X***************
  1380. X*** 44,50 ****
  1381. X  /*
  1382. X   * Free entire list
  1383. X   */
  1384. X! dl_destroy(DLIST l)
  1385. X  {
  1386. X      while (dl_shead(l))
  1387. X          dl_delete(l);
  1388. X--- 40,47 ----
  1389. X  /*
  1390. X   * Free entire list
  1391. X   */
  1392. X! dl_destroy(l)
  1393. X! DLIST l;
  1394. X  {
  1395. X      while (dl_shead(l))
  1396. X          dl_delete(l);
  1397. X***************
  1398. X*** 52,64 ****
  1399. X       * it is assumed that the list head structure itself was
  1400. X       * from dl_create, thus will always be free'd.
  1401. X       */
  1402. X!     free((char *)l);
  1403. X  }
  1404. X  
  1405. X  /*
  1406. X   * Delete specific node
  1407. X   */
  1408. X! dl_delete_node(DLIST l, DL_NODE *n)
  1409. X  {
  1410. X      if (n) {
  1411. X          dl_detach_node(l, n);
  1412. X--- 49,63 ----
  1413. X       * it is assumed that the list head structure itself was
  1414. X       * from dl_create, thus will always be free'd.
  1415. X       */
  1416. X!     free(l);
  1417. X  }
  1418. X  
  1419. X  /*
  1420. X   * Delete specific node
  1421. X   */
  1422. X! dl_delete_node(l, n)
  1423. X! DLIST l;
  1424. X! DL_NODE *n;
  1425. X  {
  1426. X      if (n) {
  1427. X          dl_detach_node(l, n);
  1428. X***************
  1429. X*** 71,77 ****
  1430. X  /*
  1431. X   * Delete node, but leave memory alone
  1432. X   */
  1433. X! dl_detach_node(DLIST l, DL_NODE *n)
  1434. X  {
  1435. X      l->size--;
  1436. X  
  1437. X--- 70,78 ----
  1438. X  /*
  1439. X   * Delete node, but leave memory alone
  1440. X   */
  1441. X! dl_detach_node(l, n)
  1442. X! DLIST l;
  1443. X! DL_NODE *n;
  1444. X  {
  1445. X      l->size--;
  1446. X  
  1447. X***************
  1448. X*** 89,95 ****
  1449. X  /*
  1450. X   * Insert node n before the current location in list l
  1451. X   */
  1452. X! dl_ins_before_node(DLIST l, DL_NODE *n_on_list, DL_NODE *new_n)
  1453. X  {
  1454. X      l->size++;
  1455. X  
  1456. X--- 90,98 ----
  1457. X  /*
  1458. X   * Insert node n before the current location in list l
  1459. X   */
  1460. X! dl_ins_before_node(l, n_on_list, new_n)
  1461. X! DLIST l;
  1462. X! DL_NODE *n_on_list, *new_n;
  1463. X  {
  1464. X      l->size++;
  1465. X  
  1466. X***************
  1467. X*** 114,120 ****
  1468. X      l->curr = new_n;
  1469. X  }
  1470. X  
  1471. X! dl_ins_after_node(DLIST l, DL_NODE *n_on_list, DL_NODE *new_n)
  1472. X  {
  1473. X      l->size++;
  1474. X  
  1475. X--- 117,125 ----
  1476. X      l->curr = new_n;
  1477. X  }
  1478. X  
  1479. X! dl_ins_after_node(l, n_on_list, new_n)
  1480. X! DLIST l;
  1481. X! DL_NODE *n_on_list, *new_n;
  1482. X  {
  1483. X      l->size++;
  1484. X  
  1485. X***************
  1486. X*** 142,148 ****
  1487. X  /*
  1488. X   * Join l2 to the end of l1; l2 is no longer usable
  1489. X   */
  1490. X! dl_cat(DLIST l1, DLIST l2)
  1491. X  {
  1492. X      l1->size += l2->size;
  1493. X      l1->tail->next = l2->head;
  1494. X--- 147,154 ----
  1495. X  /*
  1496. X   * Join l2 to the end of l1; l2 is no longer usable
  1497. X   */
  1498. X! dl_cat(l1, l2)
  1499. X! DLIST l1, l2;
  1500. X  {
  1501. X      l1->size += l2->size;
  1502. X      l1->tail->next = l2->head;
  1503. X***************
  1504. X*** 157,163 ****
  1505. X   *  return pointer to new list.
  1506. X   */
  1507. X  /*  Uncomment and do as exercise
  1508. X! DLIST dl_split_at_node(DLIST l, DL_NODE *n)
  1509. X  {
  1510. X      DLIST newl;
  1511. X  
  1512. X--- 163,171 ----
  1513. X   *  return pointer to new list.
  1514. X   */
  1515. X  /*  Uncomment and do as exercise
  1516. X! DLIST dl_split_at_node(l, n)
  1517. X! DLIST l;
  1518. X! DL_NODE *n;
  1519. X  {
  1520. X      DLIST newl;
  1521. X  
  1522. X***************
  1523. X*** 173,179 ****
  1524. X  }
  1525. X  */
  1526. X  
  1527. X! DLIST dl_copy(DLIST l)
  1528. X  {
  1529. X      DLIST newl;
  1530. X      DL_NODE *n, *newn;
  1531. X--- 181,188 ----
  1532. X  }
  1533. X  */
  1534. X  
  1535. X! DLIST dl_copy(l)
  1536. X! DLIST l;
  1537. X  {
  1538. X      DLIST newl;
  1539. X      DL_NODE *n, *newn;
  1540. X***************
  1541. X*** 182,188 ****
  1542. X          return(NULL);
  1543. X  
  1544. X      foreachnode(l, n) {
  1545. X!         newn = (DL_NODE *)getnode(n->size);
  1546. X          if (newn == NULL) {
  1547. X              dl_destroy(newl);
  1548. X              return(NULL);
  1549. X--- 191,197 ----
  1550. X          return(NULL);
  1551. X  
  1552. X      foreachnode(l, n) {
  1553. X!         newn = getnode(n->size);
  1554. X          if (newn == NULL) {
  1555. X              dl_destroy(newl);
  1556. X              return(NULL);
  1557. X***************
  1558. X*** 194,200 ****
  1559. X      return(newl);
  1560. X  }
  1561. X  
  1562. X! dl_compare(DLIST l1, DLIST l2, int (*func)())
  1563. X  {
  1564. X      int comp;
  1565. X  
  1566. X--- 203,211 ----
  1567. X      return(newl);
  1568. X  }
  1569. X  
  1570. X! dl_compare(l1, l2, func)
  1571. X! DLIST l1, l2;
  1572. X! int (*func)();
  1573. X  {
  1574. X      int comp;
  1575. X  
  1576. X***************
  1577. X*** 212,218 ****
  1578. X          return(0);    /* both ran out at same time */
  1579. X  }
  1580. X  
  1581. X! dl_apply(DLIST l, int (*func)(), char *arg)
  1582. X  {
  1583. X      foreach(l)
  1584. X          (*func)(dl_curr(l), arg);
  1585. X--- 223,232 ----
  1586. X          return(0);    /* both ran out at same time */
  1587. X  }
  1588. X  
  1589. X! dl_apply(l, func, arg)
  1590. X! DLIST l;
  1591. X! int (*func)();
  1592. X! char *arg;
  1593. X  {
  1594. X      foreach(l)
  1595. X          (*func)(dl_curr(l), arg);
  1596. X***************
  1597. X*** 221,228 ****
  1598. X  /*
  1599. X   * Do a linear search on the list, given a start/end point
  1600. X   */
  1601. X! dl_lsearch(DLIST l, DL_NODE *begin, DL_NODE *end,
  1602. X!         void *key, int (*func)())
  1603. X  {
  1604. X      DL_NODE *n;
  1605. X  
  1606. X--- 235,245 ----
  1607. X  /*
  1608. X   * Do a linear search on the list, given a start/end point
  1609. X   */
  1610. X! dl_lsearch(l, begin, end, key, func)
  1611. X! DLIST l;
  1612. X! DL_NODE *begin, *end;
  1613. X! void *key;
  1614. X! int (*func)();
  1615. X  {
  1616. X      DL_NODE *n;
  1617. X  
  1618. X***************
  1619. X*** 246,257 ****
  1620. X  
  1621. X  static int (*dl_sort_user_cmp_fun)();
  1622. X  
  1623. X! dl_sort_cmp_fun(DL_NODE **p1, DL_NODE **p2)
  1624. X  {
  1625. X      return((*dl_sort_user_cmp_fun)(*p1, *p2));
  1626. X  }
  1627. X  
  1628. X! dl_sort(DLIST l, int (*func)())
  1629. X  {
  1630. X      DL_NODE **array;
  1631. X      int i, last;
  1632. X--- 263,277 ----
  1633. X  
  1634. X  static int (*dl_sort_user_cmp_fun)();
  1635. X  
  1636. X! dl_sort_cmp_fun(p1, p2)
  1637. X! DL_NODE **p1, **p2;
  1638. X  {
  1639. X      return((*dl_sort_user_cmp_fun)(*p1, *p2));
  1640. X  }
  1641. X  
  1642. X! dl_sort(l, func)
  1643. X! DLIST l;
  1644. X! int (*func)();
  1645. X  {
  1646. X      DL_NODE **array;
  1647. X      int i, last;
  1648. X***************
  1649. X*** 273,279 ****
  1650. X  }
  1651. X  
  1652. X  /* from a list, make an array of pointers to the list items */
  1653. X! DL_NODE **dl_l2a(DLIST l)
  1654. X  {
  1655. X      DL_NODE *n, **array, **a;
  1656. X  
  1657. X--- 293,301 ----
  1658. X  }
  1659. X  
  1660. X  /* from a list, make an array of pointers to the list items */
  1661. X! DL_NODE **
  1662. X! dl_l2a(l)
  1663. X! DLIST l;
  1664. X  {
  1665. X      DL_NODE *n, **array, **a;
  1666. X  
  1667. X***************
  1668. X*** 288,294 ****
  1669. X  }
  1670. X  
  1671. X  /* turn an array of pointers to the list items into a list */
  1672. X! dl_a2l(DLIST l, DL_NODE **array)
  1673. X  {
  1674. X      int i, last;
  1675. X  
  1676. X--- 310,318 ----
  1677. X  }
  1678. X  
  1679. X  /* turn an array of pointers to the list items into a list */
  1680. X! dl_a2l(l, array)
  1681. X! DLIST l;
  1682. X! DL_NODE **array;
  1683. X  {
  1684. X      int i, last;
  1685. X  
  1686. Xdiff -rc msh/dl.h msh.orig/dl.h
  1687. X*** msh/dl.h    Sun Mar 14 11:32:16 1993
  1688. X--- msh.orig/dl.h    Mon Mar 15 23:26:29 1993
  1689. X***************
  1690. X*** 68,72 ****
  1691. X  
  1692. X  #define foreach(l)        for (dl_shead(l); dl_curr(l); dl_snext(l))
  1693. X  #define foreachnode(l,p)    for ((p)=dl_shead(l); (p); (p)=dl_snext(l))
  1694. X! 
  1695. X! #endif /* DL_H */
  1696. X--- 68,71 ----
  1697. X  
  1698. X  #define foreach(l)        for (dl_shead(l); dl_curr(l); dl_snext(l))
  1699. X  #define foreachnode(l,p)    for ((p)=dl_shead(l); (p); (p)=dl_snext(l))
  1700. X! #endif
  1701. Xdiff -rc msh/functions1.c msh.orig/functions1.c
  1702. X*** msh/functions1.c    Sun Mar 14 11:32:16 1993
  1703. X--- msh.orig/functions1.c    Mon Mar 15 23:26:27 1993
  1704. X***************
  1705. X*** 1,12 ****
  1706. X  #include "mshell.h"
  1707. X  
  1708. X- static char functions1_rcsid[] = "$Header: /usr3/src/msh/RCS/functions1.c,v 1.1 1993/03/14 19:32:07 root Exp root $";
  1709. X- 
  1710. X- #ifdef SYSV
  1711. X- #include <string.h>
  1712. X- #include <stdlib.h>
  1713. X- #endif
  1714. X- 
  1715. X  extern char     G_homevar      [];
  1716. X  extern char     G_uservar      [];
  1717. X  extern char     G_termvar      [];
  1718. X--- 1,5 ----
  1719. X***************
  1720. X*** 15,68 ****
  1721. X  extern int      G_mailsize; 
  1722. X  extern struct   stat G_st;
  1723. X  
  1724. X! void helpfile_display (char *filename)
  1725. X  {
  1726. X      FILE * fp;
  1727. X      char record [DESCLEN];
  1728. X      if (( fp = fopen (filename, "r")) == NULL ) {
  1729. X!         printw("\tNo such helpfile as %s!!\n", filename);
  1730. X          return;
  1731. X      }
  1732. X  
  1733. X      while ( fgets (record, sizeof(record), fp) )
  1734. X          fputs (record, stdout);
  1735. X!     printw("\n");
  1736. X      fclose (fp);
  1737. X  }
  1738. X  
  1739. X  /* ================================ */
  1740. X! char *prompt(char *p)
  1741. X  /* ================================ */
  1742. X  {
  1743. X      static char ans[WORDLEN];
  1744. X      extern int G_limited;
  1745. X  
  1746. X!     printw("%s : ", ufix(p));
  1747. X      if (!G_limited) {
  1748. X!         read_input_line(ans);
  1749. X!         replace_string(ans, HOME_CHAR, getenv(&G_homevar[1])) ;
  1750. X      }
  1751. X      else {
  1752. X          strcpy(ans, "XXX");
  1753. X!         printw("(no input for unvalidated users)");
  1754. X      }
  1755. X!     printw("\n");
  1756. X      return(ans);
  1757. X  }
  1758. X  
  1759. X  /* ================================================ */
  1760. X! void extract_action_word(char *str, char *sub_str, char *dest_str, int flag)
  1761. X  /* ================================================ */
  1762. X  {
  1763. X      char *position, *target;
  1764. X      int startpos = 0, string_length = 0, i = 0;
  1765. X      unsigned  no_of_chars = 0;
  1766. X  
  1767. X!     *dest_str = EOS;        /* initialize dest_str */
  1768. X  
  1769. X      startpos = strsearch (str, sub_str);
  1770. X!                     /* find position of sub-string 
  1771. X!                        in main string             */
  1772. X  
  1773. X      if ( startpos != -1 )                /* if it exists */
  1774. X          target = &str[startpos] + strlen (sub_str);    
  1775. X--- 8,68 ----
  1776. X  extern int      G_mailsize; 
  1777. X  extern struct   stat G_st;
  1778. X  
  1779. X! helpfile_display (filename)
  1780. X! char * filename;
  1781. X! 
  1782. X  {
  1783. X      FILE * fp;
  1784. X      char record [DESCLEN];
  1785. X      if (( fp = fopen (filename, "r")) == NULL ) {
  1786. X!         printf ("\tNo such helpfile as %s\!\!\n", filename);
  1787. X          return;
  1788. X      }
  1789. X  
  1790. X      while ( fgets (record, sizeof(record), fp) )
  1791. X          fputs (record, stdout);
  1792. X!     printf ("\n");
  1793. X      fclose (fp);
  1794. X  }
  1795. X  
  1796. X  /* ================================ */
  1797. X! char *
  1798. X! prompt(p)
  1799. X  /* ================================ */
  1800. X+ char *p;
  1801. X  {
  1802. X      static char ans[WORDLEN];
  1803. X      extern int G_limited;
  1804. X  
  1805. X!     printf ("%s : ", ufix(p));
  1806. X      if (!G_limited) {
  1807. X!         read_input_line (ans);
  1808. X!         replace_string (ans, HOME_CHAR, getenv(&G_homevar[1])) ;
  1809. X      }
  1810. X      else {
  1811. X          strcpy(ans, "XXX");
  1812. X!         printf("(no input for unvalidated users)");
  1813. X      }
  1814. X!     printf ("\n");
  1815. X      return(ans);
  1816. X  }
  1817. X  
  1818. X  /* ================================================ */
  1819. X! extract_action_word ( str, sub_str, dest_str, flag)
  1820. X  /* ================================================ */
  1821. X+ char *str, *sub_str, *dest_str;
  1822. X+ int  flag;
  1823. X+ 
  1824. X  {
  1825. X      char *position, *target;
  1826. X      int startpos = 0, string_length = 0, i = 0;
  1827. X      unsigned  no_of_chars = 0;
  1828. X  
  1829. X!     strcpy (dest_str, NULLSTR);        /* initialize dest_str */
  1830. X  
  1831. X      startpos = strsearch (str, sub_str);
  1832. X!                         /* find position of sub-string 
  1833. X!                            in main string             */
  1834. X  
  1835. X      if ( startpos != -1 )                /* if it exists */
  1836. X          target = &str[startpos] + strlen (sub_str);    
  1837. X***************
  1838. X*** 72,78 ****
  1839. X  
  1840. X      for (position = target;         /* actual value of parameter */
  1841. X          (*position != BLANK) && (*position != EOS);
  1842. X!          ++position, ++no_of_chars) ;
  1843. X  
  1844. X      strncpy (dest_str, target, no_of_chars);  /* copy the required value */
  1845. X      dest_str[no_of_chars] = EOS;
  1846. X--- 72,78 ----
  1847. X  
  1848. X      for (position = target;         /* actual value of parameter */
  1849. X          (*position != BLANK) && (*position != EOS);
  1850. X!          ++position, ++no_of_chars);
  1851. X  
  1852. X      strncpy (dest_str, target, no_of_chars);  /* copy the required value */
  1853. X      dest_str[no_of_chars] = EOS;
  1854. X***************
  1855. X*** 91,103 ****
  1856. X  }
  1857. X  
  1858. X  /* ===================== */
  1859. X! int display_menu(char *menu_name, char *menu_array[],
  1860. X!             int *menu_flag, int *idx)
  1861. X  /* ===================== */
  1862. X  {
  1863. X      FILE * fp;
  1864. X      char junk[COLUMNS] , keyword[DESCLEN], description[DESCLEN],
  1865. X!         action_description[DESCLEN], *fgets(), *index();
  1866. X      register int i;
  1867. X      int delay;
  1868. X  
  1869. X--- 91,107 ----
  1870. X  }
  1871. X  
  1872. X  /* ===================== */
  1873. X! display_menu (menu_name, menu_array, menu_flag, idx)
  1874. X  /* ===================== */
  1875. X+ char * menu_name;
  1876. X+ char * menu_array [];
  1877. X+ int  * menu_flag;
  1878. X+ int  * idx;
  1879. X+ 
  1880. X  {
  1881. X      FILE * fp;
  1882. X      char junk[COLUMNS] , keyword[DESCLEN], description[DESCLEN],
  1883. X!         action_description[DESCLEN], *strsave(), *fgets(), *index();
  1884. X      register int i;
  1885. X      int delay;
  1886. X  
  1887. X***************
  1888. X*** 104,120 ****
  1889. X      if (!moreinput())
  1890. X          clear_screen();
  1891. X  
  1892. X!     check_for_new_mail(G_mail_message);
  1893. X  
  1894. X!     if (*menu_flag == FALSE) {
  1895. X          *menu_flag = TRUE;
  1896. X          if (index(menu_name, '/'))
  1897. X              strcpy(junk, menu_name);
  1898. X          else
  1899. X              sprintf(junk, "%s/%s%s", MENUDIR, menu_name, SUFFIX);
  1900. X!         if ((fp = fopen(junk, "r")) == NULL) {
  1901. X!             printw("\tNo such menu as %s!!!\n", junk);
  1902. X!             refresh();
  1903. X              return(0);
  1904. X          }
  1905. X  
  1906. X--- 108,123 ----
  1907. X      if (!moreinput())
  1908. X          clear_screen();
  1909. X  
  1910. X!     check_for_new_mail (G_mail_message);
  1911. X  
  1912. X!     if ( *menu_flag == FALSE ) {
  1913. X          *menu_flag = TRUE;
  1914. X          if (index(menu_name, '/'))
  1915. X              strcpy(junk, menu_name);
  1916. X          else
  1917. X              sprintf(junk, "%s/%s%s", MENUDIR, menu_name, SUFFIX);
  1918. X!         if (( fp = fopen (junk, "r")) == NULL ) {
  1919. X!             printf ("\tNo such menu as %s!!\n", junk);
  1920. X              return(0);
  1921. X          }
  1922. X  
  1923. X***************
  1924. X*** 124,133 ****
  1925. X              (menu_array[i] = strsave(fgets(junk, COLUMNS, fp)));
  1926. X                i++
  1927. X              )
  1928. X!         {
  1929. X!             if ( strcmp(menu_array[i], DELIM_LINE) == 0 )
  1930. X                  *idx = i;
  1931. X-         }
  1932. X          
  1933. X          fclose (fp);
  1934. X  
  1935. X--- 127,134 ----
  1936. X              (menu_array[i] = strsave(fgets(junk, COLUMNS, fp)));
  1937. X                i++
  1938. X              )
  1939. X!             if ( strcmp (menu_array[i], DELIM_LINE) == 0 )
  1940. X                  *idx = i;
  1941. X          
  1942. X          fclose (fp);
  1943. X  
  1944. X***************
  1945. X*** 138,144 ****
  1946. X      if (strcmp(G_mail_message, "") != 0) {
  1947. X          junk[0] = EOS;
  1948. X          sscanf(menu_array[0], "%[^\n]", junk);
  1949. X!         printw("%s%s\n", junk, G_mail_message);
  1950. X          i = 1;
  1951. X      }
  1952. X      else
  1953. X--- 139,145 ----
  1954. X      if (strcmp(G_mail_message, "") != 0) {
  1955. X          junk[0] = EOS;
  1956. X          sscanf(menu_array[0], "%[^\n]", junk);
  1957. X!         printf("%s%s\n", junk, G_mail_message);
  1958. X          i = 1;
  1959. X      }
  1960. X      else
  1961. X***************
  1962. X*** 146,155 ****
  1963. X  
  1964. X      if (!moreinput())
  1965. X          for (; i < *idx; i++)
  1966. X!             printw("%s", menu_array[i]);
  1967. X!     addch('\n');
  1968. X!     refresh();
  1969. X  
  1970. X      return(1);
  1971. X  }
  1972. X  
  1973. X--- 147,155 ----
  1974. X  
  1975. X      if (!moreinput())
  1976. X          for (; i < *idx; i++)
  1977. X!             fputs(menu_array[i], stdout);
  1978. X  
  1979. X+     printf ("\n");
  1980. X      return(1);
  1981. X  }
  1982. X  
  1983. X***************
  1984. X*** 156,166 ****
  1985. X  /* find the home directory of the person invoking M_Shell */
  1986. X  /* ====================================================== */
  1987. X  
  1988. X! void find_user_details (char *home_dir, char *user_name)
  1989. X  {
  1990. X      struct passwd *pw, *getpwuid();
  1991. X  
  1992. X!     pw = getpwuid (getuid());
  1993. X  
  1994. X       strcpy (home_dir, pw->pw_dir);
  1995. X      strcpy (user_name, pw->pw_name);
  1996. X--- 156,168 ----
  1997. X  /* find the home directory of the person invoking M_Shell */
  1998. X  /* ====================================================== */
  1999. X  
  2000. X! find_user_details (home_dir, user_name)
  2001. X! char * home_dir;
  2002. X! char * user_name;
  2003. X  {
  2004. X      struct passwd *pw, *getpwuid();
  2005. X  
  2006. X!     pw = getpwuid (getuid ());
  2007. X  
  2008. X       strcpy (home_dir, pw->pw_dir);
  2009. X      strcpy (user_name, pw->pw_name);
  2010. X***************
  2011. X*** 167,175 ****
  2012. X  }
  2013. X  
  2014. X  /* ====================================================== */
  2015. X! void search_menu_array (char *menu_array[], int ind,
  2016. X!             char *option, char *string, int *invalid)
  2017. X  /* ====================================================== */
  2018. X  {
  2019. X      int i;
  2020. X      char keyword [WORDLEN];
  2021. X--- 169,181 ----
  2022. X  }
  2023. X  
  2024. X  /* ====================================================== */
  2025. X! search_menu_array (menu_array, ind, option, string, invalid)
  2026. X  /* ====================================================== */
  2027. X+ char * menu_array [];
  2028. X+ int    ind;
  2029. X+ char * option, * string;
  2030. X+ int  * invalid;
  2031. X+ 
  2032. X  {
  2033. X      int i;
  2034. X      char keyword [WORDLEN];
  2035. X***************
  2036. X*** 176,190 ****
  2037. X      char action_description[DESCLEN], junk[DESCLEN];
  2038. X      char opt1[OPTLEN], opt2[OPTLEN];
  2039. X  
  2040. X!     for (i = ++ind; i < LINES ; ++i) {
  2041. X!         sscanf(menu_array[i], "%s    %[^\n]", keyword, action_description);
  2042. X!         if (index (option, BLANK) != NULL) 
  2043. X!             sscanf(option, "%s %[^\n]", opt1, opt2);
  2044. X          else
  2045. X!             strcpy(opt1, option);
  2046. X  
  2047. X!         if ( strcmp(opt1, keyword) == 0 ) {
  2048. X!             strcpy(string, action_description);
  2049. X              *invalid = FALSE;
  2050. X              return;
  2051. X          }
  2052. X--- 182,196 ----
  2053. X      char action_description[DESCLEN], junk[DESCLEN];
  2054. X      char opt1[OPTLEN], opt2[OPTLEN];
  2055. X  
  2056. X!     for ( i = ++ind; i < LINES ; ++i ) {
  2057. X!         sscanf (menu_array[i], "%s    %[^\n]", keyword, action_description);
  2058. X!         if ( index (option, BLANK) != NULL ) 
  2059. X!             sscanf (option, "%s %[^\n]", opt1, opt2);
  2060. X          else
  2061. X!             strcpy (opt1, option);
  2062. X  
  2063. X!         if ( strcmp (opt1, keyword) == 0 ) {
  2064. X!             strcpy (string, action_description);
  2065. X              *invalid = FALSE;
  2066. X              return;
  2067. X          }
  2068. X***************
  2069. X*** 197,213 ****
  2070. X      else
  2071. X          *invalid = TRUE;
  2072. X  
  2073. X!     *string = '\0';
  2074. X  }
  2075. X  
  2076. X! void wait_for_user ()
  2077. X  {
  2078. X!     printw("\nPress ENTER to continue ... ");
  2079. X!     refresh();
  2080. X!     read_input_line(NULL);
  2081. X  }
  2082. X  
  2083. X! void clear_screen()
  2084. X  {
  2085. X      static int doneinit = 0;
  2086. X  
  2087. X--- 203,218 ----
  2088. X      else
  2089. X          *invalid = TRUE;
  2090. X  
  2091. X!     strcpy (string, NULLSTR);
  2092. X  }
  2093. X  
  2094. X! wait_for_user ()
  2095. X  {
  2096. X!     printf("\nHit ENTER to continue ... ");
  2097. X!     read_input_line (NULL);
  2098. X  }
  2099. X  
  2100. X! clear_screen()
  2101. X  {
  2102. X      static int doneinit = 0;
  2103. X  
  2104. Xdiff -rc msh/functions2.c msh.orig/functions2.c
  2105. X*** msh/functions2.c    Sun Mar 14 11:32:17 1993
  2106. X--- msh.orig/functions2.c    Mon Mar 15 23:26:27 1993
  2107. X***************
  2108. X*** 1,12 ****
  2109. X  #include "mshell.h"
  2110. X  
  2111. X- static char functions2_rcsid[] = "$Header: /usr3/src/msh/RCS/functions2.c,v 1.1 1993/03/14 19:32:07 root Exp root $";
  2112. X  
  2113. X- #ifdef SYSV
  2114. X- #include <string.h>
  2115. X- #include <stdlib.h>
  2116. X- #endif
  2117. X- 
  2118. X  extern char     G_homevar      [];
  2119. X  extern char     G_uservar      [];
  2120. X  extern char     G_termvar      [];
  2121. X--- 1,6 ----
  2122. X***************
  2123. X*** 16,23 ****
  2124. X  extern struct   stat G_st;
  2125. X  
  2126. X  /* ======================================================================= */
  2127. X! void execute_command(char *command, char *args[])
  2128. X  /* ======================================================================= */
  2129. X  {
  2130. X      /*
  2131. X      char * var_args [2 * MAXARGS]; 
  2132. X--- 10,18 ----
  2133. X  extern struct   stat G_st;
  2134. X  
  2135. X  /* ======================================================================= */
  2136. X! execute_command (command, args)
  2137. X  /* ======================================================================= */
  2138. X+ char *command, *args [];
  2139. X  {
  2140. X      /*
  2141. X      char * var_args [2 * MAXARGS]; 
  2142. X***************
  2143. X*** 29,36 ****
  2144. X      G_mail_message[0] = EOS;
  2145. X  
  2146. X      if (G_limited && invalidcommand(args[0])) {
  2147. X!         printw("Invalid option in restricted menus, sorry.\n");
  2148. X!         printw("See the 'info' menu for how to get a real menu or shell.  (It's free.)\n");
  2149. X          return;
  2150. X      }
  2151. X      if (strcontains(command, "*;|<>&()[]?'\"`~\\")) {
  2152. X--- 24,31 ----
  2153. X      G_mail_message[0] = EOS;
  2154. X  
  2155. X      if (G_limited && invalidcommand(args[0])) {
  2156. X!         printf("Invalid option in restricted menus, sorry.\n");
  2157. X!         printf("See the 'info' menu for how to get a real menu or shell.  (It's free.)\n");
  2158. X          return;
  2159. X      }
  2160. X      if (strcontains(command, "*;|<>&()[]?'\"`~\\")) {
  2161. X***************
  2162. X*** 118,124 ****
  2163. X  
  2164. X  /* function to reorder various command line args based on original string *
  2165. X   ======================================================================== */
  2166. X! assign_parameters(varg_ptr, input_line, command, args, aargs, promptval)
  2167. X  char * varg_ptr [2 * MAXARGS];
  2168. X  char input_line  [DESCLEN];
  2169. X  char command     [WORDLEN];
  2170. X--- 113,119 ----
  2171. X  
  2172. X  /* function to reorder various command line args based on original string *
  2173. X   ======================================================================== */
  2174. X! assign_parameters (varg_ptr, input_line, command, args, aargs, promptval)
  2175. X  char * varg_ptr [2 * MAXARGS];
  2176. X  char input_line  [DESCLEN];
  2177. X  char command     [WORDLEN];
  2178. X***************
  2179. X*** 125,130 ****
  2180. X--- 120,126 ----
  2181. X  char args        [MAXARGS][WORDLEN];
  2182. X  char aargs       [MAXARGS][WORDLEN];
  2183. X  char promptval   [MAXARGS][WORDLEN];
  2184. X+ 
  2185. X  {
  2186. X      char target_string [DESCLEN];
  2187. X      int position, i = 0;
  2188. X***************
  2189. X*** 144,156 ****
  2190. X          if ( strsearch (target_string, CMDVAL) >= 0)
  2191. X              varg_ptr [i++] = command;
  2192. X          else if ( strsearch (target_string, ARGVAL) >= 0) 
  2193. X!             varg_ptr [i++] = *(args++);
  2194. X          else if ( strsearch (target_string, AARGVAL) >= 0)
  2195. X!             varg_ptr [i++] = *(aargs++);
  2196. X          else if ( strsearch (target_string, PROMPTVAL) >= 0)
  2197. X!             varg_ptr [i++] = *(promptval++);
  2198. X          else if (index(target_string, '=') == NULL) /* same as ARGVAL */
  2199. X!             varg_ptr [i++] = *(args++);
  2200. X          
  2201. X      }    /* while */
  2202. X  }        /* assign_parameters */
  2203. X--- 140,152 ----
  2204. X          if ( strsearch (target_string, CMDVAL) >= 0)
  2205. X              varg_ptr [i++] = command;
  2206. X          else if ( strsearch (target_string, ARGVAL) >= 0) 
  2207. X!             varg_ptr [i++] = (args++);
  2208. X          else if ( strsearch (target_string, AARGVAL) >= 0)
  2209. X!             varg_ptr [i++] = (aargs++);
  2210. X          else if ( strsearch (target_string, PROMPTVAL) >= 0)
  2211. X!             varg_ptr [i++] = (promptval++);
  2212. X          else if (index(target_string, '=') == NULL) /* same as ARGVAL */
  2213. X!             varg_ptr [i++] = (args++);
  2214. X          
  2215. X      }    /* while */
  2216. X  }        /* assign_parameters */
  2217. X***************
  2218. X*** 231,253 ****
  2219. X  
  2220. X      if (!initialized) {
  2221. X          FILE *fp;
  2222. X!         char line[256], *p, *malloc();
  2223. X          struct command *c;
  2224. X  
  2225. X          if ((fp = fopen(COMMAND_LIST, "r")) == NULL) {
  2226. X!             printw("Command list missing!\n");
  2227. X              return TRUE;
  2228. X          }
  2229. X  
  2230. X          if ((commands = dl_create(DL_FREE)) == NULL) {
  2231. X!             printw("Out of memory!\n");
  2232. X              exit(1);
  2233. X          }
  2234. X  
  2235. X          while (fgets(line, sizeof(line), fp)) {
  2236. X              if ((p = malloc(strlen(line)+1)) == NULL ||
  2237. X!                 (c = (struct command *)getnode(sizeof(struct command))) == NULL) {
  2238. X!                 printw("Out of memory!\n");
  2239. X                  exit(1);
  2240. X              }
  2241. X              strcpy(p, line);
  2242. X--- 227,249 ----
  2243. X  
  2244. X      if (!initialized) {
  2245. X          FILE *fp;
  2246. X!         char line[256], *p;
  2247. X          struct command *c;
  2248. X  
  2249. X          if ((fp = fopen(COMMAND_LIST, "r")) == NULL) {
  2250. X!             printf("Command list missing!\n");
  2251. X              return TRUE;
  2252. X          }
  2253. X  
  2254. X          if ((commands = dl_create(DL_FREE)) == NULL) {
  2255. X!             printf("Out of memory!\n");
  2256. X              exit(1);
  2257. X          }
  2258. X  
  2259. X          while (fgets(line, sizeof(line), fp)) {
  2260. X              if ((p = malloc(strlen(line)+1)) == NULL ||
  2261. X!                 (c = getnode(sizeof(struct command))) == NULL) {
  2262. X!                 printf("Out of memory!\n");
  2263. X                  exit(1);
  2264. X              }
  2265. X              strcpy(p, line);
  2266. END_OF_FILE
  2267.   if test 25319 -ne `wc -c <'sysvdiffs.A'`; then
  2268.     echo shar: \"'sysvdiffs.A'\" unpacked with wrong size!
  2269.   elif test -f 'sysvdiffs.B' ; then
  2270.     echo shar: Combining  \"'sysvdiffs.mar93'\" \(61693 characters\)
  2271.     cat 'sysvdiffs.A' 'sysvdiffs.B' > 'sysvdiffs.mar93'
  2272.     if test 61693 -ne `wc -c <'sysvdiffs.mar93'`; then
  2273.       echo shar: \"'sysvdiffs.mar93'\" combined with wrong size!
  2274.     else
  2275.       rm sysvdiffs.A sysvdiffs.B
  2276.     fi
  2277.   fi
  2278.   # end of 'sysvdiffs.A'
  2279. fi
  2280. echo shar: End of archive 2 \(of 3\).
  2281. cp /dev/null ark2isdone
  2282. MISSING=""
  2283. for I in 1 2 3 ; do
  2284.     if test ! -f ark${I}isdone ; then
  2285.     MISSING="${MISSING} ${I}"
  2286.     fi
  2287. done
  2288. if test "${MISSING}" = "" ; then
  2289.     echo You have unpacked all 3 archives.
  2290.     rm -f ark[1-9]isdone
  2291. else
  2292.     echo You still must unpack the following archives:
  2293.     echo "        " ${MISSING}
  2294. fi
  2295. exit 0
  2296. exit 0 # Just in case...
  2297.