/usr/sbin/gaze

     1	#!/bin/bash
     2	#---------------------------------------------------------------------
     3	## @Synopsis gaze - view sorcery spell management information
     4	## (gaze into the crystal ball)
     5	## @Copyright First version of gaze written & copyrighted 2001 by Brian Peterson
     6	## @Copyright Current version contains none of Brian Peterson's code and is Copyright 2001 by Kyle Sallee
     7	## @Copyright Other additions/corrections Copyright 2002 by the Source Mage Team
     8	#---------------------------------------------------------------------
     9	
    10	
    11	function help">help">help() {
    12	cat << EOF
    13	
    14	Invoke gaze with desired command followed by arguments.
    15	Please note that anything in brackets [] is optional.
    16	
    17	Command         Arguments       Description
    18	
    19	-q              <empty>         disables human style output
    20	
    21	alien           <empty>         Discovers untracked files.
    22	from [-regex]   path/file       Discovers what installed a file.
    23	
    24	search          "phrase"        Searches for "phrase" in the long and short
    25	                                spell descriptions and in the spell name.
    26	search -name    "phrase"        Searches for "phrase" in the spell name.
    27	search -short   "phrase"        Searches for "phrase" in the short spell
    28	                                descriptions
    29	
    30	provides        feature         Displays spells that provide the feature.
    31	
    32	what            spell           Prints the spell's description.
    33	short           spell           Prints the spell's short description.
    34	where   -path   spell           Prints the spell's section or full path.
    35	website | url   spell           Prints the spell's website.
    36	install         spell [version] Views an install log, and sorcery log files for to the spell.
    37	install-full    spell [version] Views an install log including all sorcery state files.
    38	install-spell   spell [version] Views an install log without any sorcery files included.
    39	installed      [spell]          Views installed spells.
    40	version         spell           Views version of spell installed,
    41	                                 and version in the grimoire.
    42	versions        spell           Views version of spell in all grimoires
    43	patchlevels     spell           Views PATCHLEVEL and SECURITY_PATCH value
    44	                                 of spell in all grimoires
    45	license         spell           Views the license of the given spell(s)
    46	license         section         Views the licenses of spells in the given
    47	                                 section(s)
    48	license         license         Views information about the given license(s).
    49	compile         spell [version] Views a compile log. If no optional version
    50	                                 was given, try the installed version,
    51	                                 if the spell is not installed use the
    52	                                 version in the grimoire.
    53	sources         spell           Lists the source files for a spell.
    54	source_urls     spell           Lists the source urls for a spell.
    55	history         spell           Shows history for a spell.
    56	
    57	sum            [spell]          Prints checksums.
    58	md5sum         [spell]          Prints md5sums.
    59	size            spell           Prints total size of all files installed
    60	                                 by this spell
    61	size            -all            Prints total size of all spells, as well
    62	                                 as size of the largest spell
    63	export
    64	                                Makes snapshot of box's configuration:
    65	                                 This includes the list of installed spells,
    66	                                 their dependencies and configure options.
    67	import [--deprecated] snapshot
    68	                                Restores snapshot. --deprecated activates
    69	                                 the old behaviour, useful for old caches.
    70	
    71	section        [section]        Lists all sections. Or all spells in
    72	                                 the specified section.
    73	maintainer     [section]        Lists who is the maintainer for a section
    74	grimoire       [grimoire]       Views a text listing of all grimoires.
    75	                                 Or of the specified grimoire.
    76	grimoires                       Views list of installed grimoires' names
    77	html    [-s]   [grimoire]       Views a html listing of all grimoires.
    78	                                 Or of the specified grimoire.
    79	                                 Additionally displays links to the source
    80	                                 files when -s is given.
    81	
    82	newer           20020521        Shows available spells newer than May 21, 2002.
    83	older           20010521        Shows spells installed before May 21, 2001.
    84	newer last_sorcery_update       Shows spells newer than your previous sorcery
    85	                                 update
    86	newer last_cast                 Shows spells newer than your last casting
    87	
    88	voyeur         [delay or spell]
    89	                                Peeks into spell compilation.
    90	
    91	orphans        <empty>          Displays installed spells that no installed
    92	                                 spells explicitly depend on.
    93	
    94	depends [--fast] [--required] spell [level]
    95	                                 Displays the spells that explicitly or
    96	                                 recursively depend on this spell,
    97	                                 up to \$level levels (infinity if omitted)
    98	                                 --fast omits some information but runs faster
    99	                                 --required omits runtime dependencies
   100	                                 NOTE: the target spell must be installed and
   101	                                 only enabled dependencies are shown
   102	
   103	dependencies    [-c ] [--no-optionals ] spell [level]
   104	                                 Displays the spells this spell explicitly
   105	                                 or recursively depends on, up to \$level
   106	                                 levels (infinity if omitted). -c turns
   107	                                 on compact mode, which will prevent
   108	                                 previously shown trees from being displayed
   109	                                 (avoids loops). --no-optionals skips
   110	                                 optional spells
   111	
   112	SCRIPT NAME      spell            will print the spell script for that spell.
   113	
   114	activity        <empty>          View the activity log
   115	
   116	install-queue   <empty>          View the install queue
   117	
   118	remove-queue    <empty>          View the remove queue
   119	
   120	checkmd5s       [spell|section]  Print a md5 check of spells
   121	
   122	system-info                      Show information about a Source Mage system
   123	
   124	tablet           spell <option>  Show spell information from tablet.
   125	                                 Options: info, depends, sub_depends, spell_config
   126	                                 rsub_depends, roots, dirs, all
   127	
   128	show-held                        Shows all held spells.
   129	
   130	show-exiled                      Shows all exiled spells.
   131	
   132	time [--last|--median|--mean|--weigh-last] spell(s)
   133	                                Shows previous spell cast time (without summon)
   134	                                and total time if more than one spell is
   135	                                specified. Can also show median and mean times.
   136	time --full     spell(s)
   137	                                Shows previous spell cast time (without summon)
   138	                                computed in (all) different manners (see above)
   139	
   140	time-system [--no-orphans] [--last|--median|--mean|--weigh-last]
   141	                                Shows system cast time (without summon)
   142	
   143	EOF
   144	}
   145	
   146	#-----
   147	## override column so that we can pass -q to not columnate.
   148	#-----
   149	function maybe_column">maybe_column()  {
   150	  if [ -n "$GAZE_VERBOSE" ]; then
   151	    cat
   152	  else
   153	    column "$@"
   154	  fi
   155	}
   156	
   157	#-----
   158	## THIS FUNCTION IS DEPRECATED
   159	## To make the <@function export_snapshot> actualy be useful, an import
   160	## is quite handy.
   161	## @param snapshot file
   162	#-----
   163	function import_snapshot_old()  {
   164	  message "${PROBLEM_COLOR}This behaviour is deprecated and can be removed at any time!$DEFAULT_COLOR"
   165	
   166	          SNAPSHOT=$1
   167	  SOURCE_DIRECTORY=$BUILD_DIRECTORY/snapshot
   168	
   169	  if  [  -f  "$1"  ];  then
   170	
   171	    cd  $BUILD_DIRECTORY
   172	    mk_source_dir          $SOURCE_DIRECTORY
   173	
   174	    if  [  -n  "$EXTENSION"  ];  then
   175	      $COMPRESSBIN -dc $SNAPSHOT  |  tar  -x
   176	    else
   177	      tar  -xf  $SNAPSHOT
   178	    fi
   179	
   180	    cd  $SOURCE_DIRECTORY
   181	
   182	    for  LINE  in  `cat  install`;  do
   183	      push_install_queue  $LINE
   184	    done
   185	    report  $INSTALL_QUEUE  "Install Queue"
   186	
   187	    cp  -ai  local  /etc/sorcery
   188	    cp  -ai  etc    /
   189	
   190	    cd  /
   191	    rm_source_dir  $SOURCE_DIRECTORY
   192	
   193	  else
   194	
   195	    message  "Unable to find snapshot  \"$SNAPSHOT\""
   196	    false
   197	
   198	  fi
   199	
   200	}
   201	
   202	#-----
   203	## Construct and echo a filename to save a snapshot in.
   204	#-----
   205	function mk_snapshot_filename() {
   206	  echo "snapshot-$HOSTNAME-$(date -u +%Y%m%d).tar$EXTENSION"
   207	}
   208	
   209	#-----
   210	## Write spell configurations and a list of installed spells to an archive.
   211	## See <@function import_snapshot>
   212	## @param snapshot file
   213	#-----
   214	function export_snapshot()  {
   215	  local snapshot=$1
   216	
   217	  if [[ $UID != 0 ]]; then
   218	    error_message "${PROBLEM_COLOR}gaze export needs to be run as root, aborting...$DEFAULT_COLOR"
   219	    exit 1
   220	  fi
   221	
   222	  SOURCE_DIRECTORY=$BUILD_DIRECTORY/snapshot
   223	  mk_source_dir "$SOURCE_DIRECTORY" || return 1
   224	  mkdir "$SOURCE_DIRECTORY/etc_sorcery_local"
   225	
   226	  cp -a "$CONFIG_CACHE/depends/" "$CONFIG_CACHE/config_option_cache/" \
   227	    "$SOURCE_DIRECTORY/etc_sorcery_local" || return 2
   228	
   229	  get_all_spells_with_status ok > "$SOURCE_DIRECTORY/install"
   230	
   231	  if [[ -n $EXTENSION ]]; then
   232	    tar -C "$BUILD_DIRECTORY" -c snapshot | $COMPRESSBIN > "$snapshot"
   233	  else
   234	    tar -C "$BUILD_DIRECTORY" -cf "$snapshot" snapshot
   235	  fi || return 3
   236	
   237	  rm_source_dir "$SOURCE_DIRECTORY"
   238	  message  "Snapshot \"$snapshot\" created."
   239	}
   240	
   241	#-----
   242	## Reads a snapshot created by <@function export_snapshot>, restores
   243	## spell configuration and saves the list of installed spells into the
   244	## install queue.
   245	## @param snapshot file
   246	#-----
   247	function import_snapshot()  {
   248	  if [[ $UID != 0 ]]; then
   249	    error_message "${PROBLEM_COLOR}gaze import needs to be run as root, aborting...$DEFAULT_COLOR"
   250	    exit 1
   251	  fi
   252	
   253	  if [[ $1 == '--deprecated' ]] ; then
   254	    import_snapshot_old "$2"
   255	    return
   256	  fi
   257	
   258	  local snapshot=$1
   259	  if ! [[ -r $snapshot ]]; then
   260	    error_message "${PROBLEM_COLOR}Unable to read snapshot \"$snapshot\", aborting...$DEFAULT_COLOR"
   261	    exit 1
   262	  fi
   263	
   264	  message -n "Saving previous configuration... "
   265	  export_snapshot "$TMP_DIR/$(mk_snapshot_filename)" || return 13
   266	  message "Done."
   267	
   268	  SOURCE_DIRECTORY=$BUILD_DIRECTORY/snapshot
   269	  mk_source_dir "$SOURCE_DIRECTORY" || return 2
   270	
   271	  # FIXME: use uncompress_unpack
   272	  if [[ -n $EXTENSION ]]; then
   273	    $COMPRESSBIN -dc "$snapshot" | tar -C "$BUILD_DIRECTORY" -x
   274	  else
   275	    tar -C "$BUILD_DIRECTORY" -xf "$snapshot"
   276	  fi || return 3
   277	
   278	  local spell
   279	  for spell in $(cat "$SOURCE_DIRECTORY/install"); do
   280	    push_queue "$INSTALL_QUEUE" "$spell"
   281	  done || return 4
   282	
   283	  cp -a "$SOURCE_DIRECTORY/etc_sorcery_local"/* "$CONFIG_CACHE" || return 5
   284	
   285	  rm_source_dir  "$SOURCE_DIRECTORY"
   286	  message  "$snapshot imported, please use 'cast --queue' to start compiling."
   287	}
   288	
   289	#-----
   290	## Run a simple checksum of a list of files in a file
   291	## Is this used anywhere?
   292	## @param File with list of files the sum
   293	#-----
   294	function checksum() {
   295	  for FILE in `cat $1 | files`; do
   296	    sum -s  $FILE
   297	  done
   298	}
   299	
   300	#-----
   301	## Run an md5sum of a list of files in a file
   302	## Is this used anywhere?
   303	## @param File with list of files the sum
   304	#-----
   305	function md5sum_files() {
   306	  for FILE in `cat $1 | files`; do
   307	    md5sum  "$FILE"
   308	  done
   309	}
   310	
   311	#-----
   312	## Find all files on the system not installed by a spell
   313	## This can be quite time consuming.
   314	#-----
   315	function alien()  {
   316	
   317	  if [[ $GAZE_VERBOSE != false ]] ; then
   318	    message  "In a few minutes I will print files found on this disk"
   319	    message  "that were not installed by sorcery.  This is not a"
   320	    message  "security feature!  Files could still be lurking"
   321	    message  "undetected on this box."
   322	  fi
   323	
   324	  rm    -f  $TMP_DIR/gaze.found
   325	  rm    -f  $TMP_DIR/gaze.known
   326	
   327	  [[ $GAZE_VERBOSE != false ]] &&
   328	  message  "Discovering installed files..."
   329	  { cat $SORCERY_INSTALL_LOG ; find $INSTALL_LOGS/ -type f|xargs cat ; }  |
   330	    files  |  sort  >  $TMP_DIR/gaze.known
   331	
   332	  [[ $GAZE_VERBOSE != false ]] &&
   333	  message  "Discovering ambient files..."
   334	  find $GAZE_ALIEN_PATHS 2>/dev/null | files | filter "$EXCLUDED" | sort >$TMP_DIR/gaze.found
   335	
   336	  diff  -B  -a  -d  $TMP_DIR/gaze.found  $TMP_DIR/gaze.known  |
   337	  grep  -v  "^> "                                     |
   338	  grep      "^< "                                     |
   339	  cut  -c  3-                                         |
   340	  filter  "$PROTECTED"
   341	
   342	  rm  -f  $TMP_DIR/gaze.found
   343	  rm  -f  $TMP_DIR/gaze.known
   344	
   345	}
   346	
   347	#-----
   348	## Lists sections and spells in a grimoire.
   349	## Used by <code>gaze grimoire</code>
   350	## @param Grimoire name
   351	## @Stdout catalog
   352	#-----
   353	function gaze_catalog()  {
   354	
   355	  local grimoire
   356	  {
   357	  if [[ $# -gt 0 ]]; then
   358	        grimoire=$(codex_find_grimoire $1)
   359	        if [[ $? != 0 ]]; then
   360	            echo "No such grimoire $1"
   361	            exit 1;
   362	        fi
   363	  fi
   364	
   365	  [[ $GAZE_VERBOSE != false ]] && echo  "Sorcery Grimoire for `date  -u`"
   366	
   367	  if [ $grimoire ]; then
   368	        echo "Grimoire: " $(smgl_basename $grimoire)
   369	  else
   370	        echo "Grimoires: " $(codex_get_all_grimoires | get_basenames)
   371	  fi
   372	
   373	  COUNT=0
   374	
   375	  for  SECTION  in  `codex_get_all_sections $grimoire`;  do
   376	    if [[ $GAZE_VERBOSE != false ]]; then
   377	      echo
   378	      echo  "-------------------------------------------------"
   379	      echo  "SECTION: $(  smgl_basename  $SECTION  )"
   380	      echo  "-------------------------------------------------"
   381	    else
   382	      echo
   383	      echo  "SECTION: $(  smgl_basename  $SECTION  )"
   384	    fi
   385	    for  spell  in  `codex_get_spells_in_section $SECTION`;  do
   386	      smgl_basename $spell
   387	      ((  COUNT++  ))
   388	    done
   389	  done
   390	
   391	  echo
   392	  echo  "Total spells:  $COUNT"
   393	  } | $PAGER
   394	}
   395	
   396	#-----
   397	## Lists all sections and spells, output is in HTML format
   398	## @param Grimoire
   399	## @Stdout HTML Catalog
   400	#-----
   401	function gaze_catalog_html()  {
   402	
   403	  local grimoire COLS=4
   404	
   405	  if [[ $1 == "-s" ]]; then
   406	        shift;
   407	        (( COLS++ ))
   408	  fi
   409	
   410	  if [[ $# -gt 0 ]]; then
   411	        grimoire=$(codex_find_grimoire $1)
   412	        if [[ $? != 0 ]]; then
   413	            echo "No such grimoire $1"
   414	            exit 1;
   415	        fi
   416	  fi
   417	
   418	  echo  "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 STRICT//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">"
   419	  echo  "<html xmlns=\"http://www.w3.org/1999/xhtml\">"
   420	  echo  "<head>"
   421	  echo  "<title>Sorcery Grimoires for `date  -u`</title>"
   422	  echo  "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-1\" />"
   423	  echo  "<style type=\"text/css\" media=\"all\"> <!--"
   424	  echo  "body"
   425	  echo  "{"
   426	  echo  "background: white;"
   427	  echo  "color: black;"
   428	  echo  "font-family: Verdana, Arial, Helvetica, sans-serif;"
   429	  echo  "font-size: 10pt;"
   430	  echo  "margin:0px;"
   431	  echo "}"
   432	  echo ""
   433	  echo "h1"
   434	  echo "{"
   435	  echo "background: white;"
   436	  echo "color: green;"
   437	  echo "text-align: center;"
   438	  echo "font-family: Verdana, Arial, Helvetica, sans-serif;"
   439	  echo "font-size: 14pt; "
   440	  echo "}"
   441	
   442	  echo "h2"
   443	  echo "{"
   444	  echo "background: white;"
   445	  echo "color: green;"
   446	  echo "text-align: center;"
   447	  echo "font-family: Verdana, Arial, Helvetica, sans-serif;"
   448	  echo "font-size: 12pt; "
   449	  echo "}"
   450	
   451	  echo "table"
   452	  echo "{"
   453	  echo "width: 100%;"
   454	  echo "border-style: solid;"
   455	  echo "border-color: black;"
   456	  echo "border-width: 2px;"
   457	  echo "}"
   458	
   459	  echo "th"
   460	  echo "{"
   461	  echo "vertical-align: top;"
   462	  echo "text-align: left;"
   463	  echo "background: white;"
   464	  echo "color: black;"
   465	  echo "border-style: solid;"
   466	  echo "border-color: black;"
   467	  echo "border-width: 2px;"
   468	  echo "font-size:12pt;"
   469	  echo "}"
   470	
   471	  echo "td"
   472	  echo "{"
   473	  echo "background: white;"
   474	  echo "color: black;"
   475	  echo "vertical-align: top; "
   476	  echo "text-align: left;"
   477	  echo "border-style: solid;"
   478	  echo "border-color: black;"
   479	  echo "border-width: 2px;"
   480	  echo "font-size: 10pt;"
   481	  echo "}"
   482	
   483	  echo "--></style>"
   484	
   485	  echo  "</head>"
   486	  echo  "<body>"
   487	
   488	  echo  "<table>"
   489	
   490	  echo "<tr>"
   491	  echo "<th colspan=\"${COLS}\">"
   492	  echo "<h1>Sorcery Grimoires</h1>"
   493	  echo "<h1>$(date -u)</h1>"
   494	
   495	  if [ $grimoire ]; then
   496	        echo  "<h1>Grimoire: " $(smgl_basename $grimoire)"</h1>"
   497	  else
   498	        echo  "<h1>Grimoires: " $(codex_get_all_grimoires | get_basenames)"</h1>"
   499	  fi
   500	
   501	  echo  "</th>"
   502	  echo  "</tr>"
   503	
   504	  echo  "<tr>"
   505	  echo  "<th>Spell</th>"
   506	  echo  "<th>Version</th>"
   507	  echo  "<th>Updated</th>"
   508	  echo  "<th>Website</th>"
   509	  [[ $COLS -eq 5 ]] && echo "<th>Source</th>"
   510	  echo  "</tr>"
   511	
   512	  ((  COUNT=0  ))
   513	
   514	  for  SECTION  in  `codex_get_all_sections $grimoire`;  do
   515	    echo  "<tr>"
   516	    echo  "<th colspan=\"${COLS}\">"
   517	    echo  "<h2>$( smgl_basename  $SECTION )</h2>"
   518	    echo  "</th></tr>"
   519	    for  SPELL  in  `codex_get_spells_in_section  $SECTION`;  do
   520	      (
   521	        codex_set_current_spell  $SPELL
   522	
   523	        echo  "<tr>"
   524	        if  [  "$SPELL"  ==  "linux"  ]   ||
   525	            [  "$SPELL"  ==  "glibc"  ];  then
   526	            BOLD="<th>"
   527	          UNBOLD="</th>"
   528	        else
   529	            BOLD="<td>"
   530	            UNBOLD="</td>"
   531	        fi
   532	        if  [  -z  "$UPDATED"  ]  &&  [  "$ENTERED"  ];  then
   533	          UPDATED=$ENTERED
   534	        fi
   535	        echo  "${BOLD}${SPELL}${UNBOLD}"
   536	        echo  "${BOLD}${VERSION}${UNBOLD}"
   537	        echo  "<td>$UPDATED</td>"
   538	
   539	        if  [  "$WEB_SITE"  !=  "unknown"  ];  then
   540	            WEBSITE="`echo  $WEB_SITE  |  cut  -c-30`..."
   541	            echo  "<td>"
   542	            echo  "<a href=\"$WEB_SITE\">$WEBSITE</a>"
   543	            echo  "</td>"
   544	        else
   545	            echo  "<td></td>"
   546	        fi
   547	        if [[ $COLS -eq 5 ]]; then
   548	            echo "<td>"
   549	            echo "<a href=\"$SOURCE_URL\">$(echo $SOURCE | cut -c-25)</a>"
   550	           i=2
   551	           ii=SOURCE${i}
   552	           while  [  -n "${!ii}"  ];  do
   553	               iii="${ii}_URL"
   554	               echo "<br />"
   555	               echo "<a href=\"${!iii}\">$(echo ${!ii} | cut -c-25)</a>"
   556	               i=$(($i+1))
   557	               ii=SOURCE${i}
   558	           done
   559	           echo "</td>"
   560	        fi
   561	        echo  "</tr>"
   562	      )
   563	      ((  COUNT++  ))
   564	    done
   565	  done
   566	
   567	
   568	  echo  "<tr>"
   569	  echo "<th colspan=\"${COLS}\">Total spells:  $COUNT</th>"
   570	  echo "</tr>"
   571	  echo  "</table></body></html>"
   572	}
   573	
   574	#-----
   575	## Display a file. Decompresses it if necessary.
   576	## @Note We may want to move this function as it is a generaly handy function
   577	## @param File to display
   578	## @param Message to display if file doesn't exist
   579	#-----
   580	function display()  {
   581	  local file=$(FUZZ=on guess_filename "$1")
   582	  show_file "$file" no "$2"
   583	}
   584	
   585	#-----
   586	## List spells created more recently than the given date
   587	## @param Date
   588	#-----
   589	function newer()  {
   590	
   591	  local DATE=$1
   592	  local COMPUTE
   593	
   594	  if [ x"$DATE" == x"last_sorcery_update" ]; then
   595	    COMPUTE='($3=="update") { a=a+1; if (a>1) { print $1 ; exit } }'
   596	  elif [ x"$DATE" == x"last_cast" ]; then
   597	    COMPUTE='($3 == "cast" && $6 == "success") { print $1 ; exit }'
   598	  elif ! date -d "$DATE" +%Y%m%d > /dev/null; then
   599	    help">help">help | $PAGER
   600	    exit 1
   601	  fi
   602	
   603	  if [ -n "$COMPUTE" ]; then
   604	    DATE=$( tac $ACTIVITY_LOG | awk -F '\t| |:' "$COMPUTE" )
   605	    if [ -z "$DATE" ]; then
   606	      message "${PROBLEM_COLOR}No previous $1 date found${DEFAULT_COLOR}"
   607	      exit 1
   608	    fi
   609	  fi
   610	
   611	  if  [  -n  "$DATE"  ];  then
   612	  (
   613	    echo "Grimoire|Section|Spell|Grimoire Version|Installed Version|Added"
   614	    echo "--------|-------|-----|----------------|-----------------|-----"
   615	    for  SPELL_DIR  in  `codex_get_all_spells`;  do
   616	      unset ENTERED
   617	      .  "$SPELL_DIR/DETAILS" 1>/dev/null 2>&1
   618	      if  [  "$ENTERED"  ]  &&  [  $ENTERED  -gt  $DATE  ];  then
   619	        codex_set_current_spell  $SPELL_DIR
   620	        echo "$GRIMOIRE_NAME|$SECTION|$SPELL|$VERSION|${INSTALLED:="-"}|$ENTERED"
   621	      fi
   622	    done
   623	  ) | maybe_column">maybe_column -t -s "|"
   624	  else
   625	    help">help">help  |  $PAGER
   626	  fi
   627	
   628	}
   629	
   630	#-----
   631	## List spells created less recently than the given date
   632	## @param Date
   633	#-----
   634	function older()  {
   635	
   636	  DATE=$1
   637	  if  [  -n  "$DATE"  ];  then
   638	  (
   639	    echo "Grimoire|Section|Spell|Grimoire Version|Installed Version|Added"
   640	    echo "--------|-------|-----|----------------|-----------------|-----"
   641	    for  SPELL_DIR  in  `codex_get_all_spells`;  do
   642	      unset ENTERED
   643	      .  "$SPELL_DIR/DETAILS" 1>/dev/null 2>&1
   644	      if  [  "$ENTERED"  ]  &&  [  $ENTERED  -lt  $DATE  ];  then
   645	        codex_set_current_spell  $SPELL_DIR
   646	        echo "$GRIMOIRE_NAME|$SECTION|$SPELL|$VERSION|${INSTALLED:="-"}|$ENTERED"
   647	      fi
   648	    done
   649	  ) | maybe_column">maybe_column -t -s "|"
   650	  else
   651	    help">help">help  |  $PAGER
   652	  fi
   653	
   654	}
   655	
   656	#-----
   657	## Find all install logs that mention the given string,
   658	## discarding hits that match state files
   659	## @param mode (-regex to not match literally)
   660	## @param Search string
   661	## @Stdout grep results
   662	#-----
   663	function show_from()  {
   664	  local mode string
   665	
   666	  if [[ -z $2 ]]; then
   667	    string=$1
   668	  else
   669	    mode=$1
   670	    string=$2
   671	  fi
   672	
   673	  if [[ -z $string ]]; then
   674	    error_message "${PROBLEM_COLOR}Missing search string parameter!$DEFAULT_COLOR"
   675	    exit 1
   676	  fi
   677	
   678	  cd $INSTALL_LOGS
   679	
   680	  local matches=$(
   681	    find . -type f -printf "%f\n" |
   682	    # we use grep -e to protect against patterns starting with a dash
   683	    if [[ $mode == -regex ]]; then
   684	      xargs grep -e "$string"
   685	    else
   686	      # match the string literally, but only those at the end of the line
   687	      # substr indices start with 1
   688	      xargs awk -v str="$string" '{ if (substr($0, length($0)-length(str)+1) == str) printf ("%s: %s\n", FILENAME, $0) }'
   689	    fi |
   690	    seperate_state_files /dev/stdin /dev/stdout /dev/null | sort
   691	  )
   692	
   693	  if [[ -n $matches ]]; then
   694	    if [[ $GAZE_VERBOSE != false ]]; then
   695	      echo "$matches"
   696	    fi
   697	    return 1
   698	  fi
   699	  return 0
   700	}
   701	
   702	#-----
   703	## Generalized show component of a spell, BUILD, DEPENDS, etc...
   704	## @param Component
   705	## @param Spell
   706	#-----
   707	function show_spell_component()  {
   708	
   709	  local        COMPONENT=$1
   710	  local       SPELL_NAME=$2
   711	  local  SPELL_DIRECTORY=`codex_find_spell_by_name  $SPELL_NAME`
   712	
   713	  if  [  -z  "$SPELL_DIRECTORY"  ]; then
   714	    message "No such spell '$SPELL_NAME'"
   715	    exit 1
   716	  fi
   717	
   718	  if  [  -e  $SPELL_DIRECTORY/$COMPONENT  ];  then
   719	    $PAGER $SPELL_DIRECTORY/$COMPONENT
   720	  fi
   721	
   722	}
   723	
   724	
   725	#-----------------------------------------------------------------------
   726	## parameter processing for the search routines.
   727	## the case statement should be self-explanatory
   728	## @param (optional) Type pf search (-name or -short)
   729	## @param words to search for
   730	#-----------------------------------------------------------------------
   731	function gaze_search() {
   732	    case $1 in
   733	
   734	     -name) shift; real_name_search  "$@"  ;;
   735	    -short) shift; real_short_search "$@"  ;;
   736	         *)        real_long_search  "$@"  ;;
   737	
   738	    esac | awkuniq
   739	}
   740	
   741	#-----------------------------------------------------------------------
   742	##
   743	## searches for pattern(s) in the name of all spells.
   744	## it searches in the codex.index files for the sake of speed
   745	##
   746	## @Args Patterns
   747	##
   748	#-----------------------------------------------------------------------
   749	function real_name_search() {
   750	    local grimoire pattern
   751	
   752	    for grimoire in $(codex_get_all_grimoires); do
   753	        for pattern in "$@"; do
   754	            gawk ' BEGIN {
   755	                        OFS=""
   756	                        IGNORECASE=1
   757	                        quiet = "'$GAZE_VERBOSE'"
   758	                    }
   759	                    /^[^[:blank:]]*'"$pattern"'/ {
   760	                        if (quiet) {
   761	                            print $1
   762	                        }
   763	                        else {
   764	                            print "'"$pattern"' -> ", $1
   765	                        }
   766	                    }
   767	                ' "$grimoire/$SPELL_INDEX_FILE" 2>/dev/null
   768	        done
   769	    done
   770	}
   771	
   772	
   773	#-----------------------------------------------------------------------
   774	##
   775	## Searches for something in a specified grimoire. Not really sure what
   776	## it looks for or why.
   777	##
   778	## @param Path to grimoire
   779	## @param Spell to look for
   780	## @param Patern to find in the files
   781	## @Stdout The full path to the file, /var/lib/sorcery/codex/grimoire/games/coal/DETAILS
   782	##
   783	#-----------------------------------------------------------------------
   784	function grep_find_grimoire() {
   785	        local path=$1
   786	        local name=$2
   787	        local pattern="$3"
   788	
   789	        codex_find_in_grimoire "$path" "$name" | xargs grep -ilE -- "${pattern}"
   790	}
   791	
   792	#-----------------------------------------------------------------------
   793	##
   794	## searches for pattern(s) in the SHORT field of every SPELL in every
   795	## grimoire
   796	##
   797	## @Args Patterns
   798	##
   799	#-----------------------------------------------------------------------
   800	function real_short_search() {
   801	    local pattern grimoire spell spellname spelldir
   802	
   803	    for pattern in "$@"; do
   804	        for grimoire in $(codex_get_all_grimoires); do
   805	            for spell in $(
   806	    grep_find_grimoire $grimoire "DETAILS" "SHORT=.*${pattern}"
   807	                        ); do
   808	                smgl_dirname "$spell" spelldir
   809	                smgl_basename "$spelldir" spellname
   810	                if [[ $GAZE_VERBOSE == false ]]; then
   811	                    echo $spellname
   812	                else
   813	                    echo "$pattern -> $spellname"
   814	                fi
   815	
   816	            done
   817	        done
   818	    done
   819	}
   820	
   821	
   822	
   823	#-----------------------------------------------------------------------
   824	##
   825	## searches for pattern(s) in the long description of every SPELL in every
   826	## grimoire
   827	##
   828	## @Args Patterns
   829	##
   830	#-----------------------------------------------------------------------
   831	function real_long_search()  {
   832	  local atSpell=0
   833	  local file pattern
   834	  local SEARCH SEARCH_RESULTS
   835	  local spelldir spellname
   836	
   837	  if ! [[ $GAZE_VERBOSE == false ]] ; then
   838	    echo  "Searching...   "
   839	  fi
   840	
   841	  let i=0
   842	
   843	  for pattern in "$@"; do
   844	    SEARCH[$i]=-e
   845	    let i++
   846	    SEARCH[$i]=$pattern
   847	    let i++
   848	  done
   849	
   850	  for file in `codex_get_all_spells | sed 's/$/\/DETAILS/' | xargs grep -ilE "${SEARCH[@]}"`; do
   851	    for ((i=1;i<${#SEARCH[@]};i+=2)) ; do
   852	      pattern=${SEARCH[$i]}
   853	      SEARCH_RESULTS=$(gawk 'BEGIN{ORS = ""; IGNORECASE=1; inLongDesc=0}
   854	        /'"${pattern}"'/{
   855	          if(/^[[:blank:]]*SPELL=.*'"${pattern}"'/)   {print "(Name Match)";        exit 0;}
   856	          if(/^[[:blank:]]*SHORT=.*'"${pattern}"'/)   {print "(Short Description)"; exit 0;}
   857	          if(inLongDesc) {print "(Description)";       exit 0;}
   858	        }
   859	        /cat[[:blank:]]*<<[[:blank:]]*EOF/{inLongDesc = 1;}
   860	        /^EOF$/{inLongDesc=0;} ' $file)
   861	
   862	      if [[ ${SEARCH_RESULTS} ]]; then
   863	        smgl_dirname "$file" spelldir
   864	        smgl_basename "$spelldir" spellname
   865	        if [[ $GAZE_VERBOSE == false ]]; then
   866	          echo "$spellname"
   867	        else
   868	          clear_line
   869	          echo "$pattern ->  $spellname ${SEARCH_RESULTS}"
   870	        fi
   871	      fi
   872	    done
   873	  done
   874	
   875	  if ! [ "$GAZE_VERBOSE" == "false" ]; then
   876	    clear_line
   877	  fi
   878	
   879	
   880	}
   881	
   882	#---------------------------------------------------------------------
   883	##
   884	## Given a feature, shows a list of spells that provide the feature
   885	## or functionality.  For example:
   886	##
   887	##    % gaze provides alsa-drivers
   888	##    alsa-driver
   889	##    linux-devel
   890	##    linux-dj
   891	##
   892	## This output indicates that alsa-driver, linux-devel, and linux-dj
   893	## all provide the alsa-drivers feature.
   894	##
   895	## @param feature
   896	##
   897	#---------------------------------------------------------------------
   898	gaze_provides()  {
   899	
   900	local spell
   901	
   902	  for feature in "$@"; do
   903	        ! [[ $GAZE_VERBOSE == false ]] &&
   904	        message "${SPELL_COLOR}${feature}:${DEFAULT_COLOR}"
   905	        spell=$(find_providers "$feature")
   906	        if [[ "$spell" ]]; then
   907	                echo "$spell"
   908	        else
   909	                echo "no providers found"
   910	        fi
   911	  done
   912	}
   913	
   914	#-----
   915	## Watches a specific exhibisionist
   916	## @param PID of exhibitionist
   917	#-----
   918	function specific_voyeur()
   919	{
   920	  if ! [ -d "/tmp/liblock-0/cast.$1" ]
   921	  then
   922	    return 1
   923	  fi
   924	  nice -n +20                   \
   925	   tail $(find /tmp/sorcery/cast/ -name $1.compile.log )     \
   926	    --follow=name --pid=$(ls "/tmp/liblock-0/cast.$1") 2>/dev/null
   927	}
   928	
   929	#-----
   930	## Watches the first exhibisionist found
   931	## @param PID of exhibitionist
   932	#-----
   933	function any_voyeur()
   934	{
   935	  # We happily assume no spell names contain "cast."
   936	  local FILE=`find /tmp/liblock-0 -maxdepth 1 -mindepth 1 -name "cast.*" |
   937	         sed "s/.*\/cast\.//" | head -n 1`
   938	  [ $FILE ] || return 1
   939	  debug "voyeur" "Looking at spell \"$FILE\""
   940	  nice -n +20                                               \
   941	    tail $(find /tmp/sorcery/cast/ -name $FILE.compile.log )\
   942	         --follow=name --pid=$(ls "/tmp/liblock-0/cast.$FILE") 2>/dev/null
   943	}
   944	
   945	#-----
   946	## Start waiting for an exhibisionist.
   947	## @param (optional) Not sure if this is used... specifies a section or something
   948	#-----
   949	function gaze_activate_voyeur()  {
   950	
   951	  if  [  -n  "$1"  ]  &&
   952	      !  find_section  $1  >  /dev/null
   953	  then  ((  DEFAULT_DELAY  =  $1  *  60  ))
   954	        shift  1
   955	  fi
   956	
   957	  for  SPELL  in  $@;  do
   958	    specific_voyeur $SPELL
   959	  done
   960	
   961	  DEFAULT_DELAY=${DEFAULT_DELAY:=60}
   962	  DELAY=$DEFAULT_DELAY
   963	  message  "${MESSAGE_COLOR}Waiting ${DEFAULT_DELAY} seconds for a cast to begin.${DEFAULT_COLOR}"
   964	  while ((DELAY>0));
   965	  do
   966	    if any_voyeur
   967	    then
   968	      DELAY=$DEFAULT_DELAY
   969	      message "${MESSAGE_COLOR}Waiting ${DEFAULT_DELAY} seconds for another cast to begin.${DEFAULT_COLOR}"
   970	      global_clean_resources # normally an internal liblock function, inserted to clean out dead casts
   971	    else
   972	      sleep 1
   973	      let DELAY--
   974	    fi
   975	  done
   976	
   977	}
   978	
   979	#-----
   980	## Show spells that have no other spell depending on them
   981	#-----
   982	function show_orphans()  {
   983	  local spell each
   984	  compute_reverse_installed_depends my_hash all
   985	  for each in $(get_all_spells_with_status ok); do
   986	    hash_get_ref my_hash $each spell
   987	    if [[ ! $spell ]]; then
   988	      echo "$each"
   989	    fi
   990	  done
   991	}
   992	
   993	#-----
   994	## Show spells that have other spell depending on them
   995	#-----
   996	function show_non_orphans()  {
   997	  local spell each
   998	  compute_reverse_installed_depends my_hash all
   999	  for each in $(get_all_spells_with_status ok); do
  1000	    hash_get_ref my_hash $each spell
  1001	    if [[ $spell ]]; then
  1002	      echo "$each"
  1003	    fi
  1004	  done
  1005	}
  1006	
  1007	
  1008	
  1009	#---------------------------------------------------------------------
  1010	##
  1011	## Shows the website/home page for the given spell.
  1012	## @param Spell
  1013	##
  1014	#---------------------------------------------------------------------
  1015	function gaze_show_website()  {
  1016	
  1017	  for spell in $@; do
  1018	    if  codex_set_current_spell_by_name  $spell;  then
  1019	      if  [  -n  "$WEB_SITE"  ];  then
  1020	        ! [[ $GAZE_VERBOSE == false ]] &&
  1021	        message "${SPELL_COLOR}${spell}:${DEFAULT_COLOR}"
  1022	        echo  $WEB_SITE
  1023	      else
  1024	        echo  "  "
  1025	        echo  "No website found for '$spell'.  If you know of a website for"
  1026	        echo  "'$spell',  please let the Source Mage developers know so that"
  1027	        echo  "it can be included in future versions of the Source Mage"
  1028	        echo  "grimoire.  You can report the omission at the Source Mage"
  1029	        echo  "bug tracking website:"
  1030	        echo  "  "
  1031	        echo  "           http://bugs.sourcemage.org/"
  1032	      fi
  1033	    else
  1034	      echo  "  "
  1035	      echo  "'$spell' is not a spell in the current grimoire(s).  If it's"
  1036	      echo  "not a typo and it's a spell you'd really like to see, consider"
  1037	      echo  "creating a spell for it yourself.  For instructions on how to"
  1038	      echo  "write & submit spells, see the Source Mage Wiki:"
  1039	      echo  "  "
  1040	      echo  "             http://wiki.sourcemage.org."
  1041	    fi
  1042	  done
  1043	}
  1044	
  1045	#---------------------------------------------------------------------
  1046	##
  1047	## Shows the maintainer for the given section.
  1048	## @param section
  1049	##
  1050	#---------------------------------------------------------------------
  1051	function show_maintainer()  {
  1052	
  1053	  local section="$1"
  1054	
  1055	  {
  1056	    echo  "Grimoire|Section|Maintainer"
  1057	    echo  "--------|-------|----------"
  1058	
  1059	    for GRIMOIRE in $(codex_get_all_grimoires); do
  1060	      codex_set_grimoires $GRIMOIRE
  1061	      SECTION=`codex_find_section_by_name $section`
  1062	      if [[ -d "$SECTION" ]]; then
  1063	        if [[ -f "$SECTION/MAINTAINER" ]]; then
  1064	          echo "$(smgl_basename ${GRIMOIRE})|$section|$(<$SECTION/MAINTAINER)"
  1065	        else
  1066	          echo "$(smgl_basename ${GRIMOIRE})|$section|-"
  1067	        fi
  1068	      else
  1069	          echo "$(smgl_basename  ${GRIMOIRE})|-|-"
  1070	      fi
  1071	      codex_set_grimoires $GRIMOIRES
  1072	    done
  1073	  } | maybe_column">maybe_column -t -s "|"
  1074	
  1075	}
  1076	
  1077	
  1078	#---------------------------------------------------------------------
  1079	##
  1080	## Given a section name, shows a table of spells in that section along
  1081	## with their grimoire version and installed verion
  1082	## @param Section
  1083	## @param ...
  1084	##
  1085	#---------------------------------------------------------------------
  1086	function gaze_show_section()  {
  1087	
  1088	  local SECTION_NAME
  1089	
  1090	  if  [  $# -gt 0  ]; then
  1091	
  1092	    (
  1093	      for  SECTION_NAME  in  $@;  do
  1094	        local SECTION=$(codex_find_section_by_name  $SECTION_NAME)
  1095	        [[ $SECTION ]] && codex_get_spell_names $SECTION
  1096	      done
  1097	    ) | maybe_column">maybe_column
  1098	
  1099	  else
  1100	
  1101	    codex_get_all_section_names | maybe_column">maybe_column
  1102	
  1103	  fi
  1104	
  1105	}
  1106	
  1107	
  1108	#---------------------------------------------------------------------
  1109	##
  1110	## Given a section name, shows a table of spells in that section along
  1111	## with their grimoire version and installed verion
  1112	## @param Section
  1113	##
  1114	#---------------------------------------------------------------------
  1115	function gaze_show_section_version_table()  {
  1116	
  1117	   local  SPELLS=`codex_get_spells_in_section $1`
  1118	
  1119	   (
  1120	
  1121	     echo  "Grimoire|Section|Spell|Grimoire Version|Installed Version"
  1122	     echo  "--------|-------|-----|----------------|-----------------"
  1123	
  1124	     for  spell  in  $SPELLS;  do
  1125	
  1126	       codex_set_current_spell  $spell                            &&
  1127	       local  INSTALLED=`installed_version  $SPELL`               &&
  1128	       echo  "$GRIMOIRE_NAME|$SECTION|$SPELL|${VERSION:="-"}|${INSTALLED:="-"}"
  1129	
  1130	     done
  1131	
  1132	   ) | maybe_column">maybe_column -t -s "|"
  1133	
  1134	}
  1135	
  1136	
  1137	#---------------------------------------------------------------------
  1138	##
  1139	## Shows the versions of spells, both the version in the grimoire and
  1140	## the version installed on the system.
  1141	## @param Spell
  1142	## @param ...
  1143	##
  1144	#---------------------------------------------------------------------
  1145	function gaze_show_spell_version_table()  {
  1146	
  1147	  (
  1148	    echo  "Grimoire|Section|Spell|Grimoire Version|Installed Version"
  1149	    echo  "--------|-------|-----|----------------|-----------------"
  1150	
  1151	   for  SPELL  in  $@; do
  1152	
  1153	      codex_set_current_spell  $SPELL                        &&
  1154	      local  INSTALLED=`installed_version  $SPELL`           &&
  1155	      echo  "$GRIMOIRE_NAME|$SECTION|$SPELL|${VERSION:="-"}|${INSTALLED:="-"}"
  1156	
  1157	    done
  1158	
  1159	  ) | maybe_column">maybe_column -t -s "|"
  1160	
  1161	}
  1162	
  1163	
  1164	#---------------------------------------------------------------------
  1165	##
  1166	## Shows the versions of spells, both the version in the grimoire and
  1167	## the version installed on the system.
  1168	## @param Spell or section
  1169	## @param ...
  1170	##
  1171	#---------------------------------------------------------------------
  1172	function gaze_show_version()  {
  1173	
  1174	  local SPELLS_AND_SECTIONS=$@
  1175	  local SPELLS=
  1176	  local UNKNOWN=
  1177	
  1178	  for  spell_or_section  in  $SPELLS_AND_SECTIONS;  do
  1179	
  1180	    if  codex_find_spell_or_section_by_name  $spell_or_section;  then
  1181	
  1182	      [  -n  "$CODEX_FOUND_SECTION"  ]                                      &&
  1183	      gaze_show_section_version_table  $CODEX_FOUND_SECTION  2>  /dev/null  &&
  1184	      echo " "
  1185	
  1186	      [  -n  "$CODEX_FOUND_SPELL"  ]    &&
  1187	      SPELLS="$SPELLS $CODEX_FOUND_SPELL"
  1188	
  1189	    else
  1190	      UNKNOWN="$spell_or_section $UNKNOWN"
  1191	    fi
  1192	
  1193	  done
  1194	
  1195	  [  -n  "$SPELLS"  ]  &&
  1196	  gaze_show_spell_version_table  $SPELLS  2>  /dev/null  &&
  1197	  echo " "
  1198	
  1199	
  1200	  if [[ -n $UNKNOWN ]]; then
  1201	    message "Unknown Spells or Sections"
  1202	    message "--------------------------"
  1203	    message "$UNKNOWN"
  1204	    return 1
  1205	  else
  1206	    return 0
  1207	  fi
  1208	
  1209	}
  1210	
  1211	#---------------------------------------------------------------------
  1212	##
  1213	## Shows the all versions of spell, all versions in all grimoires and
  1214	## the version installed on the system.
  1215	## @param Spell
  1216	##
  1217	#---------------------------------------------------------------------
  1218	function gaze_show_versions()  {
  1219	
  1220	  local SPELL=$1
  1221	
  1222	  if ! codex_does_spell_exist $SPELL
  1223	  then return 1
  1224	  fi
  1225	
  1226	  (
  1227	
  1228	  echo "Grimoire|Section|Spell|Grimoire Version|Installed Version"
  1229	  echo "--------|-------|-----|----------------|-----------------"
  1230	
  1231	  #saving them, since they will be overwritten later
  1232	  if tablet_find_spell_dir "$SPELL" tablet; then
  1233	    # TODO: change this if it will be stored in the less volatile state/packages file
  1234	    tablet_get_grimoire_name $tablet installed_grimoire
  1235	  fi
  1236	  installed=$(installed_version $SPELL)
  1237	
  1238	  for grimoire in $(codex_get_all_grimoires)
  1239	  do
  1240	    if SPELL_DIRECTORY=$(codex_cache_spell_lookup $SPELL $grimoire)
  1241	    then
  1242	      codex_set_current_spell $SPELL_DIRECTORY
  1243	
  1244	      # old states don't have the name stored so fall back to similar old
  1245	      # broken behaviour where the first matching grimoire was used
  1246	      [[ -z $installed_grimoire ]] && installed_grimoire=$GRIMOIRE_NAME
  1247	
  1248	      if [[ $GRIMOIRE_NAME == $installed_grimoire ]]
  1249	      then
  1250	        echo "$GRIMOIRE_NAME|$SECTION|$SPELL|$VERSION|${installed:="-"}"
  1251	      else
  1252	        echo  "$GRIMOIRE_NAME|$SECTION|$SPELL|$VERSION|-"
  1253	      fi
  1254	
  1255	    else
  1256	      # handle also (re)moved spells
  1257	      smgl_basename "$grimoire" name
  1258	      if [[ $name == $installed_grimoire ]]; then
  1259	        echo "$name|-|-|-|$installed"
  1260	      else
  1261	        echo "$name|-|-|-|-"
  1262	      fi
  1263	    fi
  1264	  done
  1265	
  1266	  ) | maybe_column">maybe_column -t -s "|"
  1267	
  1268	  echo
  1269	}
  1270	
  1271	#---------------------------------------------------------------------
  1272	##
  1273	## Shows the all versions of spell, all versions in all grimoires and
  1274	## the version installed on the system.
  1275	## @param Spell
  1276	##
  1277	#---------------------------------------------------------------------
  1278	function gaze_show_patchlevels()  {
  1279	
  1280	  local SPELL=$1
  1281	
  1282	  if ! codex_does_spell_exist $SPELL
  1283	  then return 1
  1284	  fi
  1285	
  1286	  local TB_DIR
  1287	
  1288	  local I_PATCH="-"
  1289	  local I_SPATCH="-"
  1290	  if tablet_find_spell_dir "$SPELL" TB_DIR; then
  1291	    tablet_get_patchlevel "$TB_DIR" I_PATCH
  1292	    tablet_get_security_patch "$TB_DIR" I_SPATCH
  1293	  fi
  1294	
  1295	
  1296	  local ECHO_INSTALLED=1
  1297	  (
  1298	
  1299	  echo "Grimoire|Spell|Grimoire  |Grimoire  |Installed |Installed"
  1300	  echo "        |     |Regular   |Security  |Regular   |Security"
  1301	  echo "        |     |Patchlevel|Patchlevel|Patchlevel|Patchlevel"
  1302	  echo "--------|-----|----------|----------|----------|----------"
  1303	
  1304	  for GRIMOIRE in $(codex_get_all_grimoires)
  1305	  do
  1306	    if SPELL_DIRECTORY=$(codex_cache_spell_lookup $SPELL $GRIMOIRE)
  1307	    then
  1308	      codex_set_current_spell $SPELL_DIRECTORY
  1309	
  1310	      if [ $ECHO_INSTALLED -eq 1 ]; then
  1311	        echo "$GRIMOIRE_NAME|$SPELL|${PATCHLEVEL:-"0"}|${SECURITY_PATCH:-"0"}|${I_PATCH:-0}|${I_SPATCH:-0}"
  1312	        ECHO_INSTALLED=0
  1313	      else
  1314	        echo  "$GRIMOIRE_NAME|$SPELL|${PATCHLEVEL:-0}|${SECURITY_PATCH:-0}|-|-"
  1315	      fi
  1316	
  1317	    else
  1318	      echo "$(smgl_basename $GRIMOIRE)|-|-|-|-|-"
  1319	    fi
  1320	  done
  1321	
  1322	  ) | maybe_column">maybe_column -t -s "|"
  1323	
  1324	  echo
  1325	}
  1326	
  1327	
  1328	#---------------------------------------------------------------------
  1329	##
  1330	## Given a section name, shows a table of spells in that section along
  1331	## with their licenses.
  1332	## @param Section
  1333	##
  1334	#---------------------------------------------------------------------
  1335	function gaze_show_section_license_table()  {
  1336	
  1337	   local  SPELLS=`codex_get_spells_in_section $1`
  1338	
  1339	   (
  1340	
  1341	     echo  "Section|Spell|License(s)"
  1342	     echo  "-------|-----|----------"
  1343	
  1344	     for  spell  in  $SPELLS;  do
  1345	
  1346	       codex_set_current_spell  $spell        &&
  1347	       echo  "$SECTION|$SPELL|${LICENSE[@]}"
  1348	
  1349	     done
  1350	
  1351	   ) | maybe_column">maybe_column -t -s "|"
  1352	
  1353	}
  1354	
  1355	
  1356	#---------------------------------------------------------------------
  1357	##
  1358	## Shows the licenses of spells
  1359	## @param Spell
  1360	## @param ...
  1361	##
  1362	#---------------------------------------------------------------------
  1363	function gaze_show_spell_license_table()  {
  1364	
  1365	  (
  1366	    echo  "Spell|License(s)"
  1367	    echo  "-----|----------"
  1368	
  1369	    for  SPELL  in  $@; do
  1370	
  1371	      codex_set_current_spell  $SPELL                        &&
  1372	      echo "$SPELL|${LICENSE[@]}"
  1373	
  1374	    done
  1375	
  1376	  ) | maybe_column">maybe_column -t -s "|"
  1377	
  1378	}
  1379	
  1380	
  1381	#---------------------------------------------------------------------
  1382	##
  1383	## Shows the information about the given licenses.
  1384	## @param Licence
  1385	## @param ...
  1386	##
  1387	#---------------------------------------------------------------------
  1388	function gaze_show_license_table()  {
  1389	  (
  1390	    echo  "Abbr|License Full Name|URL"
  1391	    echo  "----|-----------------|---"
  1392	
  1393	    for  LICENSE  in  $@; do
  1394	
  1395	      grep -i "^$LICENSE|"  ${SM_LICENSE_LIST}  2> /dev/null
  1396	
  1397	    done
  1398	
  1399	  ) | maybe_column">maybe_column -t -s "|"
  1400	
  1401	}
  1402	
  1403	
  1404	#---------------------------------------------------------------------
  1405	##
  1406	## Shows lising of installed grmoires by grimoire name only.
  1407	##
  1408	#---------------------------------------------------------------------
  1409	function gaze_show_grimoires()  {
  1410	
  1411	  ! [[ $GAZE_VERBOSE == false ]] &&  echo -n "Installed Grimoires: "
  1412	  echo $(codex_get_all_grimoires | get_basenames)
  1413	  exit
  1414	
  1415	}
  1416	
  1417	
  1418	#---------------------------------------------------------------------
  1419	##
  1420	## Shows the licenses of spells if a spell or section name is given.
  1421	## Shows info a license if a license name is given.
  1422	## @param Spell, section, or license
  1423	## @param ...
  1424	##
  1425	#---------------------------------------------------------------------
  1426	function gaze_show_license()  {
  1427	
  1428	  local SPELLS_AND_SECTIONS_AND_LICENSES=$@
  1429	  local SPELLS=
  1430	  local LICENSES=
  1431	  local UNKNOWN=
  1432	
  1433	  for  spell_section_or_license  in  $SPELLS_AND_SECTIONS_AND_LICENSES;  do
  1434	
  1435	    if  codex_find_spell_or_section_by_name  $spell_section_or_license;  then
  1436	
  1437	      [  -n  "$CODEX_FOUND_SECTION"  ]                                      &&
  1438	      gaze_show_section_license_table  $CODEX_FOUND_SECTION  2>  /dev/null  &&
  1439	      echo " "
  1440	
  1441	      [  -n  "$CODEX_FOUND_SPELL"  ]    &&
  1442	      SPELLS="$SPELLS $CODEX_FOUND_SPELL"
  1443	
  1444	    elif  grep -iq "^`esc_str $spell_section_or_license`|"  ${SM_LICENSE_LIST} 2> /dev/null;  then
  1445	      LICENSES="$LICENSES $spell_section_or_license"
  1446	    else
  1447	      UNKNOWN="$spell_section_or_license $UNKNOWN"
  1448	    fi
  1449	
  1450	  done
  1451	
  1452	  [  -n  "$SPELLS"  ]                                    &&
  1453	  gaze_show_spell_license_table  $SPELLS  2>  /dev/null  &&
  1454	  echo " "
  1455	
  1456	  [  -n  "$LICENSES"  ]                              &&
  1457	  gaze_show_license_table  $LICENSES  2>  /dev/null  &&
  1458	  echo " "
  1459	
  1460	
  1461	  [  -n  "$UNKNOWN"  ]                              &&
  1462	  message "Unknown Spells or Sections or Licenses"  &&
  1463	  message "--------------------------------------"  &&
  1464	  message "$UNKNOWN"
  1465	
  1466	}
  1467	
  1468	#-----
  1469	##
  1470	## Displays the installed version of spells
  1471	## @param Spell
  1472	## @param ...
  1473	##
  1474	#-----
  1475	function gaze_show_installed() {
  1476	
  1477	  local total_rc=0
  1478	  if [ -z  "$1" ]
  1479	  then
  1480	    grep -v ':exiled:[^:]*$' $SPELL_STATUS | $PAGER
  1481	  else
  1482	    for spell in "$@"; do
  1483	      ! [[ $GAZE_VERBOSE == false ]] &&
  1484	      message  "${SPELL_COLOR}${spell}:${DEFAULT_COLOR}"
  1485	      VERSION=$(installed_version  $spell)
  1486	      if  [  -n  "$VERSION"  ]; then
  1487	        echo "$VERSION"
  1488	      else
  1489	        total_rc=1
  1490	        message  "not installed"
  1491	      fi
  1492	    done
  1493	  fi
  1494	  return $total_rc
  1495	}
  1496	
  1497	#-----
  1498	##
  1499	## Display the SHORT description of spells
  1500	## @param Spell
  1501	## @param ...
  1502	##
  1503	#-----
  1504	function gaze_show_short_description() {
  1505	
  1506	  for spell in $@; do
  1507	    if codex_find_spell_by_name $spell > /dev/null; then
  1508	        ! [[ $GAZE_VERBOSE == false ]] &&
  1509	        message "${SPELL_COLOR}${spell}:${DEFAULT_COLOR}"
  1510	        (
  1511	          codex_set_current_spell_by_name  $spell           &&
  1512	          echo "$SHORT"
  1513	        )                                                 ||
  1514	        { message  "No details found! Please file a bug!"
  1515	          return 1
  1516	        }
  1517	    else
  1518	      message "$spell -> no such spell"
  1519	    fi
  1520	    if ! [[ $GAZE_VERBOSE == false ]]; then echo; fi
  1521	  done
  1522	}
  1523	
  1524	#-----
  1525	##
  1526	## Display the long description of spells
  1527	## @param Spell
  1528	## @param ...
  1529	##
  1530	#-----
  1531	function gaze_show_long_description() {
  1532	
  1533	  for spell in $@; do
  1534	    if codex_find_spell_by_name $spell > /dev/null; then
  1535	        ! [[ $GAZE_VERBOSE == false ]] &&
  1536	        message "${SPELL_COLOR}${spell}:${DEFAULT_COLOR}"
  1537	        (
  1538	          codex_set_current_spell_by_name  $spell           &&
  1539	          codex_get_spell_description  $SPELL_DIRECTORY
  1540	        )                                       ||
  1541	        {
  1542	          message "No details found! Please file a bug!" &&
  1543	          return 1
  1544	        }
  1545	    else
  1546	      message "$spell -> no such spell"
  1547	    fi
  1548	    if [[ $GAZE_VERBOSE == false ]]; then
  1549	      echo --- --- ---
  1550	    else
  1551	      echo
  1552	    fi
  1553	  done
  1554	}
  1555	
  1556	#-----
  1557	##
  1558	## Display the section spells are located in
  1559	## @param Spell
  1560	## @param ...
  1561	##
  1562	#-----
  1563	function gaze_show_where() {
  1564	
  1565	  local SHOW_PATH
  1566	  if [[ $1 == "-path" ]]; then
  1567	    SHOW_PATH=true
  1568	    shift
  1569	  fi
  1570	
  1571	  for spell in $@; do
  1572	    if [[ $SHOW_PATH == true ]]; then
  1573	      SECTION="$(codex_find_spell_by_name $spell)"
  1574	    else
  1575	      SECTION="$(codex_get_spell_section_name $spell)"
  1576	    fi
  1577	
  1578	    if ! [[ $GAZE_VERBOSE == false ]]; then
  1579	      if [[ $SECTION ]]; then
  1580	        message "$spell -> $SECTION"
  1581	      else
  1582	        message "$spell -> no such spell"
  1583	      fi
  1584	    else
  1585	      [[ $SECTION ]] && message "$SECTION"
  1586	    fi
  1587	  done
  1588	}
  1589	
  1590	#-----
  1591	##
  1592	## Display what spells depend on the given spell
  1593	## @param The given spell
  1594	##
  1595	#-----
  1596	function gaze_show_depends() {
  1597	    local fast all=yes
  1598	    while true; do
  1599	        if [[ $1 == --fast ]] ; then
  1600	            fast=yes
  1601	            shift
  1602	            continue
  1603	        elif [[ $1 == --required ]]; then
  1604	          unset all
  1605	          shift
  1606	          continue
  1607	        fi
  1608	        break
  1609	    done
  1610	    local spell=$1
  1611	    codex_does_spell_exist "$spell"  &&
  1612	    if [[ "$GAZE_VERBOSE" == false ]] || [[ "$fast" ]]; then
  1613	      show_up_depends "$1" "$2" "$fast" "$all"
  1614	    else
  1615	      show_up_depends  "$1" "$2" "verbose" "$all"|
  1616	      awk -F: '{ printf("%s depends on %s (%s)\n",$1,$2,$4);}'
  1617	    fi
  1618	
  1619	
  1620	}
  1621	
  1622	#-----
  1623	##
  1624	## @See <@function gaze_show_depends>
  1625	## @param Spell
  1626	## @param (optional) depth to recurse for
  1627	##
  1628	#-----
  1629	function gaze_show_dependencies() {
  1630	    local FOUND SPELL NO_OPTIONALS
  1631	
  1632	    while true; do
  1633	        # Check for the compact mode flag
  1634	        if [[ $1 == -c ]] ; then
  1635	            FOUND="$TMP_DIR/gaze.seen.$$"
  1636	            echo -n > $FOUND
  1637	            shift
  1638	            continue
  1639	        fi
  1640	        # Check for the no optionals flag
  1641	        if [[ $1 == --no-optionals ]] ; then
  1642	            NO_OPTIONALS=yes
  1643	            shift
  1644	            continue
  1645	        fi
  1646	        break
  1647	    done
  1648	
  1649	    SPELL=$1
  1650	    codex_does_spell_exist "$SPELL"  || exit 1
  1651	
  1652	    [[ $# == 2 ]] && MAX_DEPTH=$2
  1653	
  1654	    (
  1655	        query() {
  1656	            return 0
  1657	        }
  1658	        depends() {
  1659	                [[ $1 == -sub ]] && shift 2
  1660	                recurse "$1" $DEPTH "depends"
  1661	                return 0
  1662	        }
  1663	        optional_depends() {
  1664	                [[ $1 == -sub ]] && shift 2
  1665	                [[ $NO_OPTIONALS ]] ||
  1666	                recurse "$1" $DEPTH "optional"
  1667	                return 0
  1668	        }
  1669	        runtime_depends() {
  1670	                [[ $1 == -sub ]] && shift 2
  1671	                recurse "$1" $DEPTH "runtime"
  1672	                return 0
  1673	        }
  1674	        suggest_depends() {
  1675	                [[ $1 == -sub ]] && shift 2
  1676	                recurse "$1" $DEPTH "suggest"
  1677	                return 0
  1678	        }
  1679	        force_depends() {
  1680	            return 0
  1681	        }
  1682	        sub_depends() {
  1683	            return 0
  1684	        }
  1685	        repeat () {
  1686	            local CHAR="$1" COUNT="$2"
  1687	
  1688	            while (( COUNT-- )); do echo -en "$CHAR"; done
  1689	        }
  1690	
  1691	# These functions shouldn't do anything in this function.
  1692	# Eventualy, they should be separated into two lists, ones
  1693	# that may be used in DEPENDS, and ones that shouldn't be
  1694	        define_functions ': ;'              \
  1695	        real_persistent_save real_query_string config_get_option \
  1696	        config_set_option real_config_query real_config_query_option \
  1697	        real_config_query_string real_list_add
  1698	
  1699	# real_config_query_list should set $1 to something reasonable:
  1700	        real_config_query_list() { eval "$1='$3'"; }
  1701	
  1702	        recurse () {
  1703	            local name=$1 DEPTH=$2 WHAT=$3
  1704	            local found_before=""
  1705	
  1706	            if ! [[ $name ]] ; then
  1707	                return ;
  1708	            fi
  1709	
  1710	
  1711	            [[ $MAX_DEPTH ]] && [[ $DEPTH -ge $MAX_DEPTH ]] && return 1
  1712	            grep () {
  1713	               local foo
  1714	               smgl_which grep foo &&
  1715	               $foo "$@"
  1716	            }
  1717	            [[ $FOUND ]] &&
  1718	                grep -q '^'$name'$' $FOUND &&
  1719	                found_before=" (see above for tree)"
  1720	
  1721	            repeat "\t" $DEPTH
  1722	            echo "$name ($WHAT)${found_before}"
  1723	            if [[ $found_before ]] ; then
  1724	                return ;
  1725	            elif [[ $FOUND ]] ; then
  1726	                echo "$name" >> $FOUND
  1727	            fi
  1728	
  1729	            local SPELL_DIRECTORY=$(codex_find_spell_by_name $name)
  1730	            [[ -e "$SPELL_DIRECTORY/DEPENDS" ]] &&
  1731	            (
  1732	                let DEPTH++
  1733	                define_functions ':;' grep
  1734	                codex_get_spell_paths $SPELL_DIRECTORY
  1735	                source "$SPELL_DIRECTORY/DEPENDS" 2>/dev/null
  1736	            )
  1737	        }
  1738	        recurse $SPELL
  1739	    )
  1740	    [[ $FOUND ]] && rm $FOUND
  1741	}
  1742	
  1743	#-----
  1744	##
  1745	## Display the size all installed spell use and the largest among them
  1746	##
  1747	#-----
  1748	function gaze_show_size_all() {
  1749	  local each date status version install_log
  1750	  local current_spell=0 current_size=0 current_info
  1751	  local max_size=0 max_spell total_size=0 total_files=0
  1752	  local installed_spells=$(all_spell_status | sed -n '/:exiled:/! s,:, ,gp')
  1753	  local spell_count=$(wc -l <<< "$installed_spells")
  1754	
  1755	  echo "This will take a while and cause lots of disk I/O..."
  1756	  while read each date status version; do
  1757	    let current_spell++
  1758	    install_log="$INSTALL_LOGS/$each-$version"
  1759	    current_info=$(
  1760	      while read entry; do
  1761	        test -f "$entry" && echo "'$entry'"
  1762	      done < $install_log | xargs du -b -c | awk 'END {print $1,NR-1}'
  1763	    )
  1764	    current_info=( $current_info )
  1765	    current_size=${current_info[0]}
  1766	    if [[ $current_size -gt $max_size ]]; then
  1767	      max_size=$current_size
  1768	      max_spell=$each
  1769	    fi
  1770	    let total_size+=$current_size
  1771	    let total_files+=${current_info[1]}
  1772	    progress_bar $current_spell $spell_count
  1773	  done <<< "$installed_spells"
  1774	  clear_line
  1775	  echo $spell_count $total_size $total_files | awk \
  1776	    'END { print $1" spells -> "$2" bytes ("int($2/1024+0.5)" K, "int($2/1024/1024+0.5)" M, "int($2/1024/1024/1024+0.5)" G) in "$3" files." }'
  1777	  echo
  1778	  echo "Largest spell:"
  1779	  gaze_show_size $max_spell
  1780	}
  1781	
  1782	#-----
  1783	##
  1784	## Display the space an installed spell uses
  1785	## @param Spell
  1786	## @param ...
  1787	##
  1788	#-----
  1789	function gaze_show_size() {
  1790	    local spell each
  1791	
  1792	    if [[ $1 == "-all" ]]; then
  1793	        if [[ $# == 1 ]]; then
  1794	            gaze_show_size_all
  1795	        else
  1796	            help">help">help
  1797	        fi
  1798	        exit 0
  1799	    fi
  1800	
  1801	    for spell in "$@"; do
  1802	        if ! spell_ok $spell ; then
  1803	          message "$spell is not installed"
  1804	          continue
  1805	        fi
  1806	        local version=$(installed_version $spell)
  1807	        local file="$INSTALL_LOGS/$spell-$version"
  1808	        if ! test -e $file ; then
  1809	           message "No install log for $spell ($file)"
  1810	           continue
  1811	        fi
  1812	        while read each; do
  1813	          test -f "$each" && echo $each
  1814	        done < $file | xargs du -b |
  1815	            awk '{ x += $1 }
  1816	                END { print "'$spell' -> " x " bytes ("int(x/1024+0.5)" K, "int(x/1024/1024+0.5)" M) in " NR " files." }'
  1817	    done
  1818	}
  1819	
  1820	#---------------------------------------------------------------------
  1821	##
  1822	## displays a spell's install log
  1823	##
  1824	## @param spell - the spell name
  1825	## @param version - version for that spell
  1826	## @param type - If empty show the log without state files, if "spell"
  1827	##        show log without sorcery log files eitther, if "full" show the entire
  1828	##        log including sorcery state files
  1829	##
  1830	#---------------------------------------------------------------------
  1831	function gaze_install() {
  1832	  local SPELL=$1
  1833	  local VERSION=$2
  1834	  local TYPE=$3
  1835	
  1836	  local log=$INSTALL_LOGS/$SPELL-$VERSION
  1837	  test -f $log || {
  1838	    message "Install log for $SPELL does not exist"
  1839	    return 1
  1840	  }
  1841	
  1842	  if [[ "$TYPE" == full ]] ; then
  1843	    sort $log | $PAGER
  1844	  elif [[ "$TYPE" == spell ]] ; then
  1845	    seperate_state_files $log /dev/stdout /dev/null | sort | $PAGER
  1846	  else
  1847	    {
  1848	      seperate_state_files $log /dev/stderr /dev/stdout | grep $LOG_DIRECTORY
  1849	    } 2>&1 | sort | $PAGER
  1850	  fi
  1851	
  1852	}
  1853	
  1854	#---------------------------------------------------------------------
  1855	##
  1856	## used by system_info()
  1857	##
  1858	#---------------------------------------------------------------------
  1859	function figure_installed()
  1860	{
  1861	  local version
  1862	  version=$(installed_version  $1)
  1863	  if  [  -n  "$version"  ]; then
  1864	    message  "[${version}]"
  1865	  else
  1866	    message  "[not installed]"
  1867	  fi
  1868	}
  1869	
  1870	#---------------------------------------------------------------------
  1871	##
  1872	## display spell information from tablet
  1873	## @param spell
  1874	## @param command (info, depends, sub_depends, spell_config, rsub_depends, roots, dirs, all)
  1875	## @Stdout information of spell from tablet
  1876	#---------------------------------------------------------------------
  1877	function gaze_tablet() {
  1878	  local spell=$1
  1879	  local command=$2
  1880	  local spell spell_directory spell_depends section_name version
  1881	  local patchlevel security_patch spell_persistent_config sub_depends build_api
  1882	  local file
  1883	  [[ -z $spell ]] && return 1
  1884	  if ! spell_ok $spell ;then
  1885	    message "${SPELL_COLOR}$spell${PROBLEM_COLOR} isn't installed!" \
  1886	            "${DEFAULT_COLOR}"
  1887	    return 1
  1888	  fi
  1889	  # get spell_directory that is used in all comands
  1890	  tablet_find_spell_dir $spell spell_directory
  1891	
  1892	  function gaze_tablet_display() {
  1893	    message "${PROBLEM_COLOR}---{ $2: $3 }---${DEFAULT_COLOR}"
  1894	    if [[ -d $1 ]]; then
  1895	      message "Not a file, skipping ..."
  1896	    elif [[ -s $1 && $(file -b --mime-encoding $1) == binary ]]; then
  1897	      message "Binary file, skipping ..."
  1898	    else
  1899	      PAGER=cat show_file "$1" no "$3 is missing or empty"
  1900	    fi
  1901	  }
  1902	  function gaze_tablet_sub() {
  1903	    local command=$1
  1904	    local cat_file=${command}_file
  1905	    tablet_get_$command $spell_directory ${cat_file}
  1906	    gaze_tablet_display "${!cat_file}" "$spell" "$command"
  1907	  }
  1908	
  1909	  case $command in
  1910	    info)
  1911	      tablet_get_section_name $spell_directory section_name
  1912	      tablet_get_version $spell_directory version
  1913	      tablet_get_patchlevel $spell_directory patchlevel
  1914	      tablet_get_security_patch $spell_directory security_patch
  1915	      tablet_get_build_api $spell_directory build_api
  1916	      # not in all tablets yet
  1917	      tablet_get_grimoire_name $spell_directory grimoire_name
  1918	      # basic information (section & version)
  1919	      message "${MESSAGE_COLOR}grimoire / section / spell: ${SPELL_COLOR}" \
  1920	              "$grimoire_name / $section_name / $spell${DEFAULT_COLOR}"
  1921	      message "${MESSAGE_COLOR}version / patchlevel / security patchlevel:${VERSION_COLOR} $version /" \
  1922	              "$patchlevel / $security_patch${DEFAULT_COLOR}"
  1923	      message "${MESSAGE_COLOR}Build API:${VERSION_COLOR} $build_api${DEFAULT_COLOR}"
  1924	    ;;
  1925	    depends)
  1926	      gaze_tablet_sub depends
  1927	    ;;
  1928	    spell_config)
  1929	      gaze_tablet_sub persistent_config
  1930	    ;;
  1931	    sub_depends)
  1932	      gaze_tablet_sub sub_depends
  1933	    ;;
  1934	    rsub_depends)
  1935	      gaze_tablet_sub rsub_depends
  1936	    ;;
  1937	    roots)
  1938	      gaze_tablet_sub roots
  1939	    ;;
  1940	    spell-files)
  1941	      for file in $spell_directory/spell/* ;do
  1942	        gaze_tablet_display "$file" "$spell" "${file##*/}"
  1943	      done
  1944	    ;;
  1945	    dirs)
  1946	      message "${MESSAGE_COLOR}Tablet dir:${DEFAULT_COLOR} $spell_directory"
  1947	      message "${MESSAGE_COLOR}Grimoire dir:${DEFAULT_COLOR} $spell_directory/grimoire"
  1948	      message "${MESSAGE_COLOR}Section dir:${DEFAULT_COLOR} $spell_directory/section"
  1949	      message "${MESSAGE_COLOR}Spell dir:${DEFAULT_COLOR} $spell_directory/spell"
  1950	    ;;
  1951	    all)
  1952	      gaze_tablet $spell info
  1953	      gaze_tablet_sub depends
  1954	      gaze_tablet_sub persistent_config
  1955	      gaze_tablet_sub rsub_depends
  1956	      gaze_tablet_sub sub_depends
  1957	      gaze_tablet_sub roots
  1958	      gaze_tablet $spell spell-files
  1959	      gaze_tablet $spell dirs
  1960	    ;;
  1961	    *)
  1962	      gaze_tablet $spell info
  1963	      gaze_tablet_sub depends
  1964	      gaze_tablet_sub persistent_config
  1965	      gaze_tablet_sub rsub_depends
  1966	      gaze_tablet_sub sub_depends
  1967	    ;;
  1968	  esac
  1969	
  1970	}
  1971	
  1972	
  1973	#---------------------------------------------------------------------
  1974	##
  1975	## displays various information about a Source Mage system
  1976	##
  1977	#---------------------------------------------------------------------
  1978	function gaze_system_info()
  1979	{
  1980	  local base_system
  1981	  local cur_spell
  1982	  local section
  1983	  local version
  1984	  local variable
  1985	  local mirror
  1986	  local idx
  1987	  local grimoire
  1988	
  1989	  #---
  1990	  ## Section: ISO VERSION
  1991	  #---
  1992	
  1993	  message -n "${PROBLEM_COLOR}--------------------{"
  1994	  message -n "Section:         ISO VERSION"
  1995	  message    "}--------------------${DEFAULT_COLOR}"
  1996	
  1997	  if [[ -e /etc/sourcemage-release ]]
  1998	  then
  1999	    cat /etc/sourcemage-release | sed '/^$/d'
  2000	  elif [[ -e /etc/smgl.iso ]]
  2001	  then
  2002	    cat /etc/smgl.iso | sed '/^$/d'
  2003	  else
  2004	    message -n "${MESSAGE_COLOR}Couldn't determine what was used to install "
  2005	    message -n "this system. Consider adding some information to "
  2006	    message    "/etc/sourcemage-release${DEFAULT_COLOR}"
  2007	  fi
  2008	
  2009	  #---
  2010	  ## Section: UNAME
  2011	  #---
  2012	
  2013	  message -n "${PROBLEM_COLOR}--------------------{"
  2014	  message -n "Section:               UNAME"
  2015	  message    "}--------------------${DEFAULT_COLOR}"
  2016	
  2017	  uname -a
  2018	
  2019	  #---
  2020	  ## Section: BASESYSTEM
  2021	  #---
  2022	
  2023	  message -n "${PROBLEM_COLOR}--------------------{"
  2024	  message -n "Section:          BASESYSTEM"
  2025	  message    "}--------------------${DEFAULT_COLOR}"
  2026	
  2027	  #---
  2028	  ## Need a list of the base spell and ALL of it's DIRECT
  2029	  ## depends(what's in DEPENDS)
  2030	  ## base_system="$(gaze dependencies basesystem 2 | sed
  2031	  ## -e "s/()//" -e 's/ (depends)//' -e 's/ (optional)//' | tr "\n" " " )"
  2032	  #---
  2033	
  2034	  version="$(figure_installed basesystem)"
  2035	  section="$(codex_get_spell_section_name basesystem)"
  2036	  message -n "${MESSAGE_COLOR}${section}/basesystem:\t"
  2037	  message    "${QUERY_COLOR}${version}${DEFAULT_COLOR}\n"
  2038	
  2039	  compute_installed_depends on_down_deps x on
  2040	  compute_installed_depends off_down_deps x off
  2041	  {
  2042	  for curr_spell in $(hash_get on_down_deps basesystem)
  2043	  do
  2044	    version="$(figure_installed $curr_spell)"
  2045	    section="$(codex_get_spell_section_name $curr_spell)"
  2046	    message -n "${MESSAGE_COLOR}${section}/${curr_spell}:\t"
  2047	    message    "${QUERY_COLOR}${version}${DEFAULT_COLOR}"
  2048	  done
  2049	  for curr_spell in $(hash_get off_down_deps basesystem)
  2050	  do
  2051	    version="$(figure_installed $curr_spell)"
  2052	    section="$(codex_get_spell_section_name $curr_spell)"
  2053	    message -n "${MESSAGE_COLOR}${section}/${curr_spell}:\t"
  2054	    message    "${QUERY_COLOR}${version} (disabled)${DEFAULT_COLOR}"
  2055	  done
  2056	  } | sort
  2057	
  2058	  #---
  2059	  ## Section: CODEX
  2060	  #---
  2061	
  2062	  message -n "${PROBLEM_COLOR}--------------------{"
  2063	  message -n "Section:               CODEX"
  2064	  message    "}--------------------${DEFAULT_COLOR}"
  2065	
  2066	  let idx=0
  2067	  for grimoire in $(codex_get_all_grimoires)
  2068	  do
  2069	    message "${QUERY_COLOR} [$idx]: $(smgl_basename "$grimoire"):${DEFAULT_COLOR}" \
  2070	            "${MESSAGE_COLOR}$grimoire${DEFAULT_COLOR}"
  2071	    let idx+=1
  2072	  done
  2073	
  2074	  #---
  2075	  ## Section: SORCERY CONFIG
  2076	  #---
  2077	
  2078	  message -n "${PROBLEM_COLOR}--------------------{"
  2079	  message -n "Section:      SORCERY CONFIG"
  2080	  message    "}--------------------${DEFAULT_COLOR}"
  2081	
  2082	  for variable in PROMPT_DELAY DOWNLOAD_RATE PATCH SOUND SORCERER CABAL \
  2083	                  NICE SORCERY_BRANCH DEF_INSTALL_INIT DEF_ENABLE_INIT \
  2084	                  DEF_INSTALL_XINETD DEF_ENABLE_XINETD DEF_INIT_VS_XINETD \
  2085	                  COMPRESSBIN EXTENSION URL_HTTP_FTP_TIMEOUT MD5SUM_DL \
  2086	                  GPG_VERIFY_SPELL_LEVEL ARCHIVE AUTOFIX UPDATEFIX AUTOPRUNE \
  2087	                  GATHER_DOCS MAIL_REPORTS VIEW_REPORTS PRESERVE SUSTAIN \
  2088	                  TMPFS VOYEUR REAP STORE_CONF_LOG NET_SELECT CONFIG_LOC \
  2089	                  CLEAN_SOURCE CROSS_INSTALL SET_TERM_TITLE SCREEN \
  2090	                  DEBUG SUPER_DEBUG BUILD_DIRECTORY
  2091	  do
  2092	    message -n "${MESSAGE_COLOR}$variable="
  2093	    message    "${QUERY_COLOR}\"${!variable}\"${DEFAULT_COLOR}"
  2094	  done
  2095	
  2096	  #---
  2097	  ## Section: STATE CONFIG
  2098	  #---
  2099	
  2100	  message -n "${PROBLEM_COLOR}--------------------{"
  2101	  message -n "Section:        STATE CONFIG"
  2102	  message    "}--------------------${DEFAULT_COLOR}"
  2103	
  2104	  for variable in INSTALL_ROOT STATE_ROOT INSTALL_CACHE TRACK_ROOT
  2105	  do
  2106	    message -n "${MESSAGE_COLOR}$variable="
  2107	    message    "${QUERY_COLOR}\"${!variable}\"${DEFAULT_COLOR}"
  2108	  done
  2109	
  2110	  #---
  2111	  ## Section: COMPILER CONFIG
  2112	  #---
  2113	
  2114	  message -n "${PROBLEM_COLOR}--------------------{"
  2115	  message -n "Section:     COMPILER CONFIG"
  2116	  message    "}--------------------${DEFAULT_COLOR}"
  2117	
  2118	  message -n "${MESSAGE_COLOR}SMGL_COMPAT_ARCHS=${DEFAULT_COLOR}"
  2119	  for each in ${SMGL_COMPAT_ARCHS[@]}
  2120	  do
  2121	    message -n "${QUERY_COLOR}${each}${DEFAULT_COLOR}/"
  2122	  done
  2123	  message -n "\n"
  2124	
  2125	  for variable in ARCHITECTURE OPTIMIZATIONS CUSTOM_CFLAGS CUSTOM_CXXFLAGS \
  2126	                  CUSTOM_LDFLAGS CFLAGS CXXFLAGS LDFLAGS HOST CCACHE \
  2127	                  DISTCC_HOSTS JOBS_PER_HOST MAKE_NJOBS CCACHE_DIR
  2128	  do
  2129	    message -n "${MESSAGE_COLOR}$variable="
  2130	    message    "${QUERY_COLOR}\"${!variable}\"${DEFAULT_COLOR}"
  2131	  done
  2132	
  2133	  #---
  2134	  ## Section: VERIFICATION CONFIG
  2135	  #---
  2136	
  2137	  message -n "${PROBLEM_COLOR}--------------------{"
  2138	  message -n "Section: VERIFICATION CONFIG"
  2139	  message    "}--------------------${DEFAULT_COLOR}"
  2140	
  2141	  for variable in VRF_ALLOWED_LEVELS VRF_ALLOW_NEW_LEVELS VRF_ALLOWED_HASHES \
  2142	                  VRF_ALLOW_NEW_HASHES GPG_VERIFY_SORCERY GPG_VERIFY_GRIMOIRE
  2143	  do
  2144	    message -n "${MESSAGE_COLOR}$variable="
  2145	    message    "${QUERY_COLOR}\"${!variable}\"${DEFAULT_COLOR}"
  2146	  done
  2147	
  2148	  #---
  2149	  ## Section: CLEANSE CONFIG
  2150	  #---
  2151	
  2152	  message -n "${PROBLEM_COLOR}--------------------{"
  2153	  message -n "Section:      CLEANSE CONFIG"
  2154	  message    "}--------------------${DEFAULT_COLOR}"
  2155	
  2156	  for variable in FIND_CHECK MD5SUM_CHECK LDD_CHECK SYM_CHECK
  2157	  do
  2158	    message -n "${MESSAGE_COLOR}$variable="
  2159	    message    "${QUERY_COLOR}\"${!variable}\"${DEFAULT_COLOR}"
  2160	  done
  2161	
  2162	  #---
  2163	  ## Section: DISPEL CONFIG
  2164	  #---
  2165	
  2166	  message -n "${PROBLEM_COLOR}--------------------{"
  2167	  message -n "Section:       DISPEL CONFIG"
  2168	  message    "}--------------------${DEFAULT_COLOR}"
  2169	
  2170	  for variable in ORPHAN_MENU_DEFAULT NONORPHAN_MENU_DEFAULT \
  2171	                  RECAST_PARENT_MENU_DEFAULT DISPEL_PARENT_MENU_DEFAULT
  2172	  do
  2173	    message -n "${MESSAGE_COLOR}$variable="
  2174	    message    "${QUERY_COLOR}\"${!variable}\"${DEFAULT_COLOR}"
  2175	  done
  2176	
  2177	  #---
  2178	  ## Section: LOCALE CONFIG
  2179	  #---
  2180	
  2181	  message -n "${PROBLEM_COLOR}--------------------{"
  2182	  message -n "Section:       LOCALE CONFIG"
  2183	  message    "}--------------------${DEFAULT_COLOR}"
  2184	
  2185	  for variable in LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY \
  2186	                  LC_MESSAGES LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE \
  2187	                  LC_MEASUREMENT LC_IDENTIFICATION LC_ALL
  2188	  do
  2189	    if [[ ! -z ${!variable} ]]
  2190	    then
  2191	      message -n "${MESSAGE_COLOR}$variable="
  2192	      message    "${QUERY_COLOR}\"${!variable}\"${DEFAULT_COLOR}"
  2193	    fi
  2194	  done
  2195	
  2196	  #---
  2197	  ## Section: FACILITIES
  2198	  #---
  2199	
  2200	  message -n "${PROBLEM_COLOR}--------------------{"
  2201	  message -n "Section:          FACILITIES"
  2202	  message    "}--------------------${DEFAULT_COLOR}"
  2203	
  2204	  cat /etc/sysconfig/facilities | sed -e '/^$/d' -e '/^#.*$/d'
  2205	
  2206	  #---
  2207	  ## Section: MIRRORS
  2208	  #---
  2209	
  2210	  message -n "${PROBLEM_COLOR}--------------------{"
  2211	  message -n "Section:             MIRRORS"
  2212	  message    "}--------------------${DEFAULT_COLOR}"
  2213	
  2214	  for mirror in APACHE_URL CTAN_URL GNOME_URL GNU_URL KDE_URL KERNEL_URL \
  2215	                PERL_CPAN_URL SORCERY_URL SOURCEFORGE_URL XFREE86_URL CODEX_URL
  2216	  do
  2217	    message -n "${MESSAGE_COLOR}$mirror="
  2218	    message    "${QUERY_COLOR}\"${!mirror}\"${DEFAULT_COLOR}"
  2219	  done
  2220	
  2221	}
  2222	
  2223	#---------------------------------------------------------------------
  2224	##
  2225	## prints all spells of a given status.
  2226	## @param status - what are we looking for
  2227	## @param describe - how is that staus described in english
  2228	##
  2229	#---------------------------------------------------------------------
  2230	function gaze_show_spells_by_status() {
  2231	    message -n "${MESSAGE_COLOR}The following spells are set to"
  2232	    message -n "${DEFAULT_COLOR} $2:"
  2233	    message    "${SPELL_COLOR}"
  2234	    get_all_spells_with_status $1 | sort | maybe_column">maybe_column
  2235	    message -n "${DEFAULT_COLOR}"
  2236	}
  2237	
  2238	#---------------------------------------------------------------------
  2239	##
  2240	## Display the time spells took to compile and install. If gaze is in
  2241	## silent mode, pad all the times as needed.
  2242	##
  2243	## @param Type (optional) - tells which time calculation to use
  2244	## @param Spell
  2245	## @param ...
  2246	##
  2247	#---------------------------------------------------------------------
  2248	function gaze_time() {
  2249	
  2250	  local diff time sum=0 err_sum=() n=0 spell type
  2251	  if [[ $1 == -* ]]; then
  2252	    type=$1
  2253	    shift
  2254	    if [[ $type == --full ]]; then
  2255	      gaze_time_full "$@"
  2256	      return
  2257	    fi
  2258	  fi
  2259	
  2260	  for spell in "$@"; do
  2261	    diff=$(compute_cast_time $spell $type)
  2262	    if [[ -z $diff ]]; then
  2263	      message "${SPELL_COLOR}$spell$PROBLEM_COLOR wasn't cast yet at all!" \
  2264	        "${DEFAULT_COLOR}"
  2265	      continue
  2266	    fi
  2267	    if [[ ${diff% *} == $diff ]]; then
  2268	      (( sum += $diff ))
  2269	    else
  2270	      (( sum += ${diff% *}, n++ )) # we'll count the error separately
  2271	      err_sum[n]=${diff#* }
  2272	    fi
  2273	
  2274	    if [[ $GAZE_VERBOSE != false ]]; then
  2275	      message -n "Casting ${SPELL_COLOR}$spell$DEFAULT_COLOR took "
  2276	      pretty_print_time $diff
  2277	    else
  2278	      echo "$spell:$diff"
  2279	    fi
  2280	  done
  2281	
  2282	  if [[ -n $2 ]]; then
  2283	    message -n "${MESSAGE_COLOR}Total time:$DEFAULT_COLOR "
  2284	    if [[ $GAZE_VERBOSE != false ]]; then
  2285	      pretty_print_time $sum $(compute_total_error "${err_sum[@]}")
  2286	    else
  2287	      echo $sum $(compute_total_error "${err_sum[@]}")
  2288	    fi
  2289	  fi
  2290	}
  2291	
  2292	#---------------------------------------------------------------------
  2293	##
  2294	## Display the time spells took to compile and install. If gaze is in
  2295	## silent mode, pad all the times as needed. Prints all the available
  2296	## times.
  2297	##
  2298	## @param Spell
  2299	## @param ...
  2300	##
  2301	#---------------------------------------------------------------------
  2302	function gaze_time_full() {
  2303	  local spell
  2304	
  2305	  for spell in "$@"; do
  2306	    compute_all_cast_times $spell $GAZE_VERBOSE
  2307	    if [[ $? != 0 ]]; then
  2308	      message "${SPELL_COLOR}$spell$PROBLEM_COLOR wasn't cast yet at all!" \
  2309	        "${DEFAULT_COLOR}"
  2310	      continue
  2311	    fi
  2312	  done
  2313	}
  2314	
  2315	#---------------------------------------------------------------------
  2316	##
  2317	## Display the time all installed spells took to compile and install.
  2318	## If --no-orphans is passed, they are skipped.
  2319	##
  2320	## @param orphans (optional) - skip orphans
  2321	## @param type - see gaze_time
  2322	##
  2323	#---------------------------------------------------------------------
  2324	function gaze_time_system() {
  2325	  local type orphans
  2326	
  2327	  while [[ $1 == -* ]]; do
  2328	    if [[ $1 == --no-orphans ]]; then
  2329	      orphans=no
  2330	    else
  2331	      type=$1
  2332	    fi
  2333	    shift
  2334	  done
  2335	
  2336	  if [[ $orphans == no ]]; then
  2337	    gaze_time $type $(show_non_orphans | sort -u)
  2338	  else
  2339	    gaze_time $type $(get_all_spells_with_status ok | sort)
  2340	  fi
  2341	}
  2342	
  2343	parse()  {
  2344	
  2345	  # Maintain "TMP_DIR is always set as a global" invariant in the case of
  2346	  # non-root users, this leaves vague security holes but they're limited
  2347	  # to files the non-root user can access.
  2348	  # a future goal is to make mk_tmp_dirs work for regular users too...
  2349	  if  [  "$UID"  -gt  0  ];  then
  2350	    export TMP_DIR=/tmp
  2351	  else
  2352	    mk_tmp_dirs gaze
  2353	  fi
  2354	
  2355	  [[ $UID != 0 ]] && test "$NICE" -lt 0 && NICE=0
  2356	  renice $NICE -p $$ >/dev/null
  2357	
  2358	  while [[ -n "$1" ]] && [[ ${1:0:1} == "-" ]] ; do
  2359	    case $1 in
  2360	      -q) GAZE_VERBOSE=false
  2361	          PAGER=cat
  2362	          shift
  2363	          ;;
  2364	      -g) for grimoire in $2; do
  2365	            if ! codex_find_grimoire $grimoire >/dev/null; then
  2366	              message "${PROBLEM_COLOR}No such grimoire: " \
  2367	                      "${DEFAULT_COLOR}$grimoire"
  2368	              return 1
  2369	            fi
  2370	            codex_set_grimoires $2
  2371	          done
  2372	          shift 2
  2373	          ;;
  2374	      *) help">help">help ; exit ;;
  2375	    esac
  2376	  done
  2377	
  2378	
  2379	  SPELL=$2
  2380	  SECTION=$2
  2381	  VERSION=`installed_version  $SPELL`
  2382	
  2383	  case  $1  in
  2384	
  2385	        # Spell components. In alphabetical order.
  2386	           BUILD)  show_spell_component $1 $2            ;;
  2387	       CONFIGURE)  show_spell_component $1 $2            ;;
  2388	       CONFLICTS)  show_spell_component $1 $2            ;;
  2389	         DETAILS)  show_spell_component $1 $2            ;;
  2390	         DEPENDS)  show_spell_component $1 $2            ;;
  2391	        DOWNLOAD)  show_spell_component $1 $2            ;;
  2392	           FINAL)  show_spell_component $1 $2            ;;
  2393	         HISTORY)  show_spell_component $1 $2            ;;
  2394	         INSTALL)  show_spell_component $1 $2            ;;
  2395	  INSTALL_EXTRAS)  show_spell_component $1 $2            ;;
  2396	           PATCH)  show_spell_component $1 $2            ;;
  2397	      POST_BUILD)  show_spell_component $1 $2            ;;
  2398	    POST_INSTALL)  show_spell_component $1 $2            ;;
  2399	     POST_REMOVE)  show_spell_component $1 $2            ;;
  2400	  POST_RESURRECT)  show_spell_component $1 $2            ;;
  2401	       PRE_BUILD)  show_spell_component $1 $2            ;;
  2402	     PRE_INSTALL)  show_spell_component $1 $2            ;;
  2403	      PRE_REMOVE)  show_spell_component $1 $2            ;;
  2404	   PRE_RESURRECT)  show_spell_component $1 $2            ;;
  2405	 PRE_SUB_DEPENDS)  show_spell_component $1 $2            ;;
  2406	         PREPARE)  show_spell_component $1 $2            ;;
  2407	        PROVIDES)  show_spell_component $1 $2            ;;
  2408	        SECURITY)  show_spell_component $1 $2            ;;
  2409	     SUB_DEPENDS)  show_spell_component $1 $2            ;;
  2410	        TRANSFER)  show_spell_component $1 $2            ;;
  2411	   TRIGGER_CHECK)  show_spell_component $1 $2            ;;
  2412	        TRIGGERS)  show_spell_component $1 $2            ;;
  2413	     UP_TRIGGERS)  show_spell_component $1 $2            ;;
  2414	
  2415	        # Other options
  2416	            html)  shift; gaze_catalog_html $@           ;;
  2417	          export)  export_snapshot "$(mk_snapshot_filename)" ;;
  2418	          import)  shift; import_snapshot "$@"           ;;
  2419	         section)  shift; gaze_show_section $@           ;;
  2420	         version)  shift; gaze_show_version $@           ;;
  2421	        versions)  shift; gaze_show_versions $@          ;;
  2422	     patchlevels)  shift; gaze_show_patchlevels $@       ;;
  2423	         license)  shift; gaze_show_license $@           ;;
  2424	           alien)  alien                                 ;;
  2425	     system-info)  gaze_system_info                      ;;
  2426	          tablet)  shift; gaze_tablet $1 $2              ;;
  2427	        activity)  display $ACTIVITY_LOG                 ;;
  2428	            from)  shift; show_from "$@"                 ;;
  2429	           newer)  newer             $2                  ;;
  2430	           older)  older             $2                  ;;
  2431	         sources)  sources           $SPELL              ;;
  2432	     source_urls)  source_urls       $SPELL              ;;
  2433	        grimoire)  shift; gaze_catalog $@                ;;
  2434	       grimoires)  gaze_show_grimoires                   ;;
  2435	          search)  shift; gaze_search "$@"               ;;
  2436	        provides)  shift; gaze_provides $@               ;;
  2437	         depends)  shift; gaze_show_depends  "$@"        ;;
  2438	    dependencies)  shift; gaze_show_dependencies  "$@"   ;;
  2439	         orphans)  show_orphans | sort                   ;;
  2440	         history)  show_spell_component HISTORY  "$2"    ;;
  2441	     website|url)  shift; gaze_show_website           $@ ;;
  2442	      maintainer)  shift; show_maintainer             $@ ;;
  2443	       installed)  shift; gaze_show_installed         $@ ;;
  2444	       show-held)  gaze_show_spells_by_status held hold  ;;
  2445	     show-exiled)  gaze_show_spells_by_status exiled exiled ;;
  2446	           short)  shift; gaze_show_short_description $@ ;;
  2447	            what)  shift; gaze_show_long_description  $@ ;;
  2448	           where)  shift; gaze_show_where             $@ ;;
  2449	            size)  shift; gaze_show_size              $@ ;;
  2450	       checkmd5s)  shift; gaze_md5check               $@ ;;
  2451	            time)  shift; gaze_time                   $@ ;;
  2452	     time-system)  shift; gaze_time_system            $@ ;;
  2453	    compile)  if  [  -n  "$3"        ];  then
  2454	                  VERSION=$3
  2455	              elif  [  -z  "$VERSION"  ];  then
  2456	                  codex_set_current_spell_by_name  $2
  2457	              fi
  2458	              display  $COMPILE_LOGS/$SPELL-$VERSION$EXTENSION   \
  2459	                       "Compile log for $SPELL-$VERSION does not exist"
  2460	              ;;
  2461	
  2462	        install) [[ -n $3 ]] && VERSION="$3"
  2463	                 gaze_install $SPELL $VERSION ;;
  2464	   install-full) [[ -n $3 ]] && VERSION="$3"
  2465	                 gaze_install $SPELL $VERSION full ;;
  2466	  install-spell) [[ -n $3 ]] && VERSION="$3"
  2467	                 gaze_install $SPELL $VERSION spell ;;
  2468	
  2469	    sum)  [  -n  "$SPELL"  ]                         &&
  2470	          checksum  "$INSTALL_LOGS/$SPELL-$VERSION"  ||
  2471	          checksum  "$INSTALL_LOGS/*"
  2472	          ;;
  2473	
  2474	
  2475	    md5sum)  [  -n  "$SPELL"  ]                             &&
  2476	             md5sum_files  "$INSTALL_LOGS/$SPELL-$VERSION"  ||
  2477	             md5sum_files  "$INSTALL_LOGS/*"
  2478	             ;;
  2479	
  2480	   voyeur)  shift  1;  gaze_activate_voyeur  $@  ;;
  2481	
  2482	 install-queue)  if [[ -s $INSTALL_QUEUE ]]; then
  2483	                   $PAGER $INSTALL_QUEUE
  2484	                 else
  2485	                   message "Install queue does not exist or is empty"
  2486	                 fi
  2487	                 ;;
  2488	
  2489	  remove-queue)  display  $REMOVE_QUEUE   "Remove queue does not exist"   ;;
  2490	
  2491	             *)  help">help">help  ;;
  2492	
  2493	  esac
  2494	
  2495	  # dont put code here unless you save the return value from the case/esac code
  2496	
  2497	}
  2498	
  2499	. /etc/sorcery/config
  2500	if  [  $#  == 0  ];  then
  2501	  help">help">help  |  $PAGER
  2502	else
  2503	  trap exit PIPE
  2504	  parse  "$@"
  2505	  rc=$?
  2506	  if  [  ${TMP_DIR:0:13} ==  "/tmp/sorcery/"  ];  then
  2507	    cleanup_tmp_dir $TMP_DIR
  2508	  fi
  2509	  exit $rc
  2510	fi
  2511	
  2512	
  2513	#---------------------------------------------------------------------
  2514	##=back
  2515	##
  2516	##=head1 LICENSE
  2517	##
  2518	## This software is free software; you can redistribute it and/or modify
  2519	## it under the terms of the GNU General Public License as published by
  2520	## the Free Software Foundation; either version 2 of the License, or
  2521	## (at your option) any later version.
  2522	##
  2523	## This software is distributed in the hope that it will be useful,
  2524	## but WITHOUT ANY WARRANTY; without even the implied warranty of
  2525	## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  2526	## GNU General Public License for more details.
  2527	##
  2528	## You should have received a copy of the GNU General Public License
  2529	## along with this software; if not, write to the Free Software
  2530	## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  2531	##
  2532	#---------------------------------------------------------------------