a6d2eaa3e35c1c02dde8fe0d8cb967de6b51665b
[platform/upstream/bash.git] / examples / scripts / adventure.sh
1 #!/bin/bash
2 #       ash -- "Adventure shell"
3 #       last edit:      86/04/21        D A Gwyn
4 #       SCCS ID:        @(#)ash.sh      1.4
5
6 OPATH=$PATH
7
8 ask()
9 {
10         echo -n "$@" '[y/n] '
11         read ans
12
13         case "$ans" in
14         y*|Y*)
15                 return 0
16                 ;;
17         *)
18                 return 1
19                 ;;
20         esac
21 }
22         
23 CAT=${PAGER:-more}
24
25 ash_inst()
26 {
27         cat <<- EOF
28
29                         Instructions for the Adventure shell
30
31         Welcome to the Adventure shell!  In this exploration of the UNIX file
32         system, I will act as your eyes and hands.  As you move around, I will
33         describe whatever is visible and will carry out your commands.  The
34         general form of a command is
35                 Verb Object Extra_stuff.
36         Most commands pay no attention to the "Extra_stuff", and many do not
37         need an "Object".  A typical command is
38                 get all
39         which picks up all files in the current "room" (directory).  You can
40         find out what you are carrying by typing the command
41                 inventory
42         The command "help" results in a full description of all commands that I
43         understand.  To quit the Adventure shell, type
44                 quit
45
46         There are UNIX monsters lurking in the background.  These are also
47         known as "commands with arguments".
48
49         Good luck!
50         EOF
51 }
52
53 ash_help()
54 {
55 echo "I understand the following commands (synonyms in parentheses):"
56 echo ""
57
58 echo "change OBJECT to NEW_NAME       changes the name of the object"
59 echo "clone OBJECT as NEW_NAME        duplicates the object"
60 echo "drop OBJECTS                    leaves the objects in the room"
61 echo "enter (go) PASSAGE              takes the labeled passage"
62 echo "examine OBJECTS                 describes the objects in detail"
63 echo "feed OBJECT to MONSTER          stuffs the object into a UNIX monster"
64 echo "get (take) OBJECTS              picks up the specified objects"
65 echo "gripe (bug)                     report a problem with the Adventure shell"
66 echo "help                            prints this summary"
67 echo "inventory (i)                   tells what you are carrying"
68 echo "kill (destroy) OBJECTS          destroys the objects"
69 echo "look (l)                        describes the room, including hidden objects"
70 echo "open (read) OBJECT              shows the contents of an object"
71 echo "quit (exit)                     leaves the Adventure shell"
72 echo "resurrect OBJECTS               attempts to restore dead objects"
73 echo "steal OBJECT from MONSTER       obtains the object from a UNIX monster"
74 echo "throw OBJECT at daemon          feeds the object to the printer daemon"
75 echo "up                              takes the overhead passage"
76 echo "wake MONSTER                    awakens a UNIX monster"
77 echo "where (w)                       tells you where you are"
78 echo "xyzzy                           moves you to your home"
79 }
80         
81 MAINT=chet@ins.cwru.edu
82
83 PATH=/usr/ucb:/bin:/usr/bin:/usr/local/bin:.
84 export PATH
85
86 trap 'echo Ouch!' 2 3
87 #trap '' 18                     # disable Berkeley job control
88
89 ash_lk(){ echo " $1 " | fgrep " $2 " >&- 2>&-; }
90 ash_pr(){ echo $* | tr ' ' '\012' | pr -5 -t -w75 -l$[ ( $# + 4 ) / 5 ]; }
91 ash_rm(){ echo " $1 " | sed -e "s/ $2 / /" -e 's/^ //' -e 's/ $//'; }
92
93 cd
94 LIM=.limbo                      # $HOME/$LIM contains "destroyed" objects
95 mkdir $LIM >&- 2>&-
96 KNAP=.knapsack                  # $HOME/$KNAP contains objects being "carried"
97 if [ ! -d $KNAP ]
98 then    mkdir $KNAP >&- 2>&-
99         if [ $? = 0 ]
100         then    echo 'You found a discarded empty knapsack.'
101         else    echo 'You have no knapsack to carry things in.'
102                 exit 1
103         fi
104 else    echo 'One moment while I peek in your old knapsack...'
105 fi
106
107 kn=`echo \`ls -a $KNAP | sed -e '/^\.$/d' -e '/^\.\.$/d'\``
108
109 if ask 'Welcome to the Adventure shell!  Do you need instructions?'
110 then
111         ash_inst
112         echo -n 'Type a newline to continue: '
113         read
114 fi
115
116 wiz=false
117 cha=false
118 prev=$LIM
119 while :
120 do      room=`pwd`
121         if [ $room != $prev ]
122         then    if [ $room = $HOME ]
123                 then    echo 'You are in your own home.'
124                 else    echo "You have entered $room."
125                 fi
126                 exs=
127                 obs=
128                 hexs=
129                 hobs=
130                 f=false
131                 for i in `ls -a`
132                 do      case $i in
133                         .|..)   ;;
134                         .*)     if [ -f $i ]
135                                 then    hobs="$hobs $i"
136                                 elif [ -d $i ]
137                                 then    hexs="$hexs $i"
138                                 else    f=true
139                                 fi
140                                 ;;
141                         *)      if [ -f $i ]
142                                 then    obs="$obs $i"
143                                 elif [ -d $i ]
144                                 then    exs="$exs $i"
145                                 else    f=true
146                                 fi
147                                 ;;
148                         esac
149                 done
150                 if [ "$obs" ]
151                 then    echo 'This room contains:'
152                         ash_pr $obs
153                 else    echo 'The room looks empty.'
154                 fi
155                 if [ "$exs" ]
156                 then    echo 'There are exits labeled:'
157                         ash_pr $exs
158                         echo 'as well as a passage overhead.'
159                 else    echo 'There is a passage overhead.'
160                 fi
161                 if sh -c $f
162                 then    echo 'There are shadowy figures in the corner.'
163                 fi
164                 prev=$room
165         fi
166
167         echo -n '-advsh> '                      # prompt
168         read verb obj x
169         if [ $? != 0 ]
170         then    verb=quit               # EOF
171         fi
172
173         case $verb in
174         change)         if [ "$obj" ]
175                         then    if ash_lk "$obs $hobs" "$obj"
176                                 then    set -- $x
177                                         case "$1" in
178                                         to)     if [ "$2" ]
179                                                 then    if [ -f $2 ]
180                                                         then    echo "You must destroy $2 first."
181                                                                 set --
182                                                         fi
183                                                         if [ "$2" ]
184                                                         then    if mv $obj $2 >&- 2>&-
185                                                                 then    echo "The $obj shimmers and turns into $2."
186                                                                         obs=`ash_rm "$2 $obs" "$obj"`
187                                                                 else    echo "There is a cloud of smoke but the $obj is unchanged."
188                                                                 fi
189                                                         fi
190                                                 else    echo 'To what?'
191                                                 fi
192                                                 ;;
193                                         *)      echo "Change $obj to what?"
194                                                 ;;
195                                         esac
196                                 else    if ash_lk "$kn" "$obj"
197                                         then    echo 'You must drop it first.'
198                                         else    echo "I see no $obj here."
199                                         fi
200                                 fi
201                         else    echo 'Change what?'
202                         fi
203                         ;;
204         clone)          if [ "$obj" ]
205                         then    if ash_lk "$obs $hobs" "$obj"
206                                 then    if [ ! -r $obj ]
207                                         then    echo "The $obj does not wish to be cloned."
208                                         else    set -- $x
209                                                 case "$1" in
210                                                 as)     if [ "$2" ]
211                                                         then    if [ -f $2 ]
212                                                                 then    echo "You must destroy $2 first."
213                                                                 else    if cp $obj $2 >&- 2>&-
214                                                                         then    echo "Poof!  When the smoke clears, you see the new $2."
215                                                                                 obs="$obs $2"
216                                                                         else    echo 'You hear a dull thud but no clone appears.'
217                                                                         fi
218                                                                 fi
219                                                         else    echo 'As what?'
220                                                         fi
221                                                         ;;
222                                                 *)      echo "Clone $obj as what?"
223                                                         ;;
224                                                 esac
225                                         fi
226                                 else    if ash_lk "$kn" "$obj"
227                                         then    echo 'You must drop it first.'
228                                         else    echo "I see no $obj here."
229                                         fi
230                                 fi
231                         else    echo 'Clone what?'
232                         fi
233                         ;;
234         drop)           if [ "$obj" ]
235                         then    for it in $obj $x
236                                 do      if ash_lk "$kn" "$it"
237                                         then    if [ -w $it ]
238                                                 then    echo "You must destroy $it first."
239                                                 else    if mv $HOME/$KNAP/$it $it >&- 2>&-
240                                                         then    echo "$it: dropped."
241                                                                 kn=`ash_rm "$kn" "$it"`
242                                                                 obs=`echo $it $obs`
243                                                         else    echo "The $it is caught in your knapsack."
244                                                         fi
245                                                 fi
246                                         else    echo "You're not carrying the $it!"
247                                         fi
248                                 done
249                         else    echo 'Drop what?'
250                         fi
251                         ;;
252         enter|go)       if [ "$obj" ]
253                         then    if [ $obj != up ]
254                                 then    if ash_lk "$exs $hexs" "$obj"
255                                         then    if [ -x $obj ]
256                                                 then    if cd $obj
257                                                         then    echo 'You squeeze through the passage.'
258                                                         else    echo "You can't go that direction."
259                                                         fi
260                                                 else    echo 'An invisible force blocks your way.'
261                                                 fi
262                                         else    echo 'I see no such passage.'
263                                         fi
264                                 else    if cd ..
265                                         then    echo 'You struggle upwards.'
266                                         else    echo "You can't reach that high."
267                                         fi
268                                 fi
269                         else    echo 'Which passage?'
270                         fi
271                         ;;
272         examine)        if [ "$obj" ]
273                         then    if [ $obj = all ]
274                                 then    $obj=`echo $obs $exs`
275                                         x=
276                                 fi
277                                 for it in $obj $x
278                                 do      if ash_lk "$obs $hobs $exs $hexs" "$it"
279                                         then    echo "Upon close inspection of the $it, you see:"
280                                                 ls -ld $it 2>&-
281                                                 if [ $? != 0 ]
282                                                 then    echo "-- when you look directly at the $it, it vanishes."
283                                                 fi
284                                         else    if ash_lk "$kn" "$it"
285                                                 then    echo 'You must drop it first.'
286                                                 else    echo "I see no $it here."
287                                                 fi
288                                         fi
289                                 done
290                         else    echo 'Examine what?'
291                         fi
292                         ;;
293         feed)           if [ "$obj" ]
294                         then    if ash_lk "$obs $hobs" "$obj"
295                                 then    set -- $x
296                                         case "$1" in
297                                         to)     if [ "$2" ]
298                                                 then    shift
299                                                         if PATH=$OPATH $* <$obj 2>&-
300                                                         then    echo "The $1 monster devours your $obj."
301                                                                 if rm -f $obj >&- 2>&-
302                                                                 then    obs=`ash_rm "$obs" "$obj"`
303                                                                 else    echo 'But he spits it back up.'
304                                                                 fi
305                                                         else    echo "The $1 monster holds his nose in disdain."
306                                                         fi
307                                                 else    echo 'To what?'
308                                                 fi
309                                                 ;;
310                                         *)      echo "Feed $obj to what?"
311                                                 ;;
312                                         esac
313                                 else    if ash_lk "$kn" "$obj"
314                                         then    echo 'You must drop it first.'
315                                         else    echo "I see no $obj here."
316                                         fi
317                                 fi
318                         else    echo 'Feed what?'
319                         fi
320                         ;;
321         get|take)       if [ "$obj" ]
322                         then    if [ $obj = all ]
323                                 then    obj="$obs"
324                                         x=
325                                 fi
326                                 for it in $obj $x
327                                 do      if ash_lk "$obs $hobs" "$it"
328                                         then    if ash_lk "$kn" "$it"
329                                                 then    echo 'You already have one.'
330                                                 else    if mv $it $HOME/$KNAP/$it >&- 2>&-
331                                                         then    echo "$it: taken."
332                                                                 kn="$it $kn"
333                                                                 obs=`ash_rm "$obs" "$it"`
334                                                         else    echo "The $it is too heavy."
335                                                         fi
336                                                 fi
337                                         else    echo "I see no $it here."
338                                         fi
339                                 done
340                         else    echo 'Get what?'
341                         fi
342                         ;;
343         gripe|bug)      echo 'Please describe the problem and your situation at the time it failed.\nEnd the bug report with a line containing just a Ctrl-D.'
344                         cat | mail $MAINT -s 'ash bug'
345                         echo 'Thank you!'
346                         ;;
347         help)           ash_help
348                         ;;
349         inventory|i)    if [ "$kn" ]
350                         then    echo 'Your knapsack contains:'
351                                 ash_pr $kn
352                         else    echo 'You are poverty-stricken.'
353                         fi
354                         ;;
355         kill|destroy)   if [ "$obj" ]
356                         then    if [ $obj = all ]
357                                 then    x=
358                                         if ask "Do you really want to attempt to $verb them all?"
359                                         then    obj=`echo $obs`
360                                         else    echo 'Chicken!'
361                                                 obj=
362                                         fi
363                                 fi
364                                 for it in $obj $x
365                                 do      if ash_lk "$obs $hobs" "$it"
366                                         then    if mv $it $HOME/$LIM <&- >&- 2>&-
367                                                 then    if [ $verb = kill ]
368                                                         then    echo "The $it cannot defend himself; he dies."
369                                                         else    echo "You have destroyed the $it; it vanishes."
370                                                         fi
371                                                         obs=`ash_rm "$obs" "$it"`
372                                                 else    if [ $verb = kill ]
373                                                         then    echo "Your feeble blows are no match for the $it."
374                                                         else    echo "The $it is indestructible."
375                                                         fi
376                                                 fi
377                                         else    if ash_lk "$kn" "$it"
378                                                 then    echo "You must drop the $it first."
379                                                         found=false
380                                                 else    echo "I see no $it here."
381                                                 fi
382                                         fi
383                                 done
384                         else    echo 'Kill what?'
385                         fi
386                         ;;
387         look|l)         obs=`echo $obs $hobs`
388                         hobs=
389                         if [ "$obs" ]
390                         then    echo 'The room contains:'
391                                 ash_pr $obs
392                         else    echo 'The room is empty.'
393                         fi
394                         exs=`echo $exs $hexs`
395                         hexs=
396                         if [ "$exs" ]
397                         then    echo 'There are exits plainly labeled:'
398                                 ash_pr $exs
399                                 echo 'and a passage directly overhead.'
400                         else    echo 'The only exit is directly overhead.'
401                         fi
402                         ;;
403         magic)          if [ "$obj" = mode ]
404                         then    if sh -c $cha
405                                 then    echo 'You had your chance and you blew it.'
406                                 else    if ask 'Are you a wizard?'
407                                         then    echo -n 'Prove it!  Say the magic word: '
408                                                 read obj
409                                                 if [ "$obj" = armadillo ]
410                                                 then    echo 'Yes, master!!'
411                                                         wiz=true
412                                                 else    echo "Homie says: I don't think so"
413                                                         cha=true
414                                                 fi
415                                         else    echo "I didn't think so."
416                                         fi
417                                 fi
418                         else    echo 'Nice try.'
419                         fi
420                         ;;
421         open|read)      if [ "$obj" ]
422                         then    if ash_lk "$obs $hobs" "$obj"
423                                 then    if [ -r $obj ]
424                                         then    if [ -s $obj ]
425                                                 then    echo "Opening the $obj reveals:"
426                                                         $CAT < $obj
427                                                         if [ $? != 0 ]
428                                                         then    echo '-- oops, you lost the contents!'
429                                                         fi
430                                                 else    echo "There is nothing inside the $obj."
431                                                 fi
432                                         else    echo "You do not have the proper tools to open the $obj."
433                                         fi
434                                 else    if ash_lk "$kn" "$obj"
435                                         then    echo 'You must drop it first.'
436                                                 found=false
437                                         else    echo "I see no $obj here."
438                                         fi
439                                 fi
440                         else    echo 'Open what?'
441                         fi
442                         ;;
443         quit|exit)      if ask 'Do you really want to quit now?'
444                         then    if [ "$kn" ]
445                                 then    echo 'The contents of your knapsack will still be there next time.'
446                                 fi
447                                 rm -rf $HOME/$LIM
448                                 echo 'See you later!'
449                                 exit 0
450                         fi
451                         ;;
452         resurrect)      if [ "$obj" ]
453                         then    for it in $obj $x
454                                 do      if ash_lk "$obs $hobs" "$it"
455                                         then    echo "The $it is already alive and well."
456                                         else    if mv $HOME/$LIM/$it $it <&- >&- 2>&-
457                                                 then    echo "The $it staggers to his feet."
458                                                         obs=`echo $it $obs`
459                                                 else    echo "There are sparks but no $it appears."
460                                                 fi
461                                         fi
462                                 done
463                         else    echo 'Resurrect what?'
464                         fi
465                         ;;
466         steal)          if [ "$obj" ]
467                         then    if ash_lk "$obs $hobs" "$obj"
468                                 then    echo 'There is already one here.'
469                                 else    set -- $x
470                                         case "$1" in
471                                         from)   if [ "$2" ]
472                                                 then    shift
473                                                         if PATH=$OPATH $* >$obj 2>&-
474                                                         then    echo "The $1 monster drops the $obj."
475                                                                 obs=`echo $obj $obs`
476                                                         else    echo "The $1 monster runs away as you approach."
477                                                                 rm -f $obj >&- 2>&-
478                                                         fi
479                                                 else    echo 'From what?'
480                                                 fi
481                                                 ;;
482                                         *)      echo "Steal $obj from what?"
483                                                 ;;
484                                         esac
485                                 fi
486                         else    echo 'Steal what?'
487                         fi
488                         ;;
489         throw)          if [ "$obj" ]
490                         then    if ash_lk "$obs $hobs" "$obj"
491                                 then    set -- $x
492                                         case "$1" in
493                                         at)     case "$2" in
494                                                 daemon) if sh -c "lpr -r $obj"
495                                                         then    echo "The daemon catches the $obj, turns it into paper,\nand leaves it in the basket."
496                                                                 obs=`ash_rm "$obs" "$obj"`
497                                                         else    echo "The daemon is nowhere to be found."
498                                                         fi
499                                                         ;;
500                                                 *)      echo 'At what?'
501                                                         ;;
502                                                 esac
503                                                 ;;
504                                         *)      echo "Throw $obj at what?"
505                                                 ;;
506                                         esac
507                                 else    if ash_lk "$kn" "$obj"
508                                         then    echo 'It is in your knapsack.'
509                                                 found=false
510                                         else    echo "I see no $obj here."
511                                         fi
512                                 fi
513                         else    echo 'Throw what?'
514                         fi
515                         ;;
516         u|up)           if cd ..
517                         then    echo 'You pull yourself up a level.'
518                         else    echo "You can't reach that high."
519                         fi
520                         ;;
521         wake)           if [ "$obj" ]
522                         then    echo "You awaken the $obj monster:"
523                                 PATH=$OPATH $obj $x
524                                 echo 'The monster slithers back into the darkness.'
525                         else    echo 'Wake what?'
526                         fi
527                         ;;
528         w|where)        echo "You are in $room."
529                         ;;
530         xyzzy)          if cd
531                         then    echo 'A strange feeling comes over you.'
532                         else    echo 'Your spell fizzles out.'
533                         fi
534                         ;;
535         *)              if [ "$verb" ]
536                         then    if sh -c $wiz
537                                 then    PATH=$OPATH $verb $obj $x
538                                 else    echo "I don't know how to \"$verb\"."
539                                         echo 'Type "help" for assistance.'
540                                 fi
541                         else    echo 'Say something!'
542                         fi
543                         ;;
544         esac
545 done