/var/lib/sorcery/modules/libsorcery

     1	#!/bin/bash
     2	#---------------------------------------------------------------------
     3	##
     4	## @Synopsis Set of functions used by the internal sorcery scripts
     5	##
     6	## This should really be home to things related to the sorcery script
     7	## itself, not a repository for other functions. (Andrew 5/29/04)
     8	##
     9	## @Copyright Original version Copyright 2001 by Kyle Sallee
    10	## @Copyright Additions/Corrections Copyright 2002 by the Source Mage Team
    11	##
    12	#---------------------------------------------------------------------
    13	
    14	#---------------------------------------------------------------------
    15	## @param branch
    16	##
    17	## Updates the sorcery scripts to their latest version for specified
    18	## branch.
    19	##
    20	#---------------------------------------------------------------------
    21	function update_sorcery_scripts() {
    22	
    23	  local BRANCH=$1
    24	
    25	  debug "libsorcery" "update_sorcery_scripts() (sorcery-$BRANCH)"
    26	
    27	  {
    28	    #This section is to make sure that all sorcery dependencies are cast
    29	    #Keep this outer if until basesystem is in the grimoires properly.
    30	    #(2002/10/13)
    31	    if [[ `codex_find_spell_by_name basesystem` ]] ; then
    32	      if ! spell_ok basesystem  ; then
    33	        cast basesystem
    34	      fi &&
    35	      if [[ "$UPDATEFIX" == on ]] ; then
    36	        cleanse --fix basesystem
    37	      fi
    38	      if [[ $? != 0 ]] ; then
    39	        query "Would you like to continue anyway?" y || return 1
    40	      fi
    41	    fi
    42	  }
    43	
    44	  pushd $TMP_DIR &>/dev/null
    45	  # sorcery is not a spell
    46	  # there is no spoon
    47	  SOURCE=sorcery-$BRANCH.tar.bz2
    48	  SOURCE_DIRECTORY=$BUILD_DIRECTORY/sorcery
    49	  SOURCE_URL=$SORCERY_URL/$SOURCE
    50	
    51	  message  "${MESSAGE_COLOR}Downloading source file"       \
    52	           "${FILE_COLOR}${SOURCE}${DEFAULT_COLOR}"     \
    53	           "for sorcery update."
    54	  url_download "$SOURCE" "$SOURCE_URL" "" "sr_target" "sr_type" || {
    55	    message "${PROBLEM_COLOR}Failed to download sorcery${DEFAULT_COLOR}"
    56	    return 1
    57	  }
    58	  if [[ $sr_type != file ]] ; then
    59	    message "Downloaded type is not a file, file a bug if you see this"
    60	    return 1
    61	  fi
    62	  [[ $sr_target != $SOURCE ]] && mv $sr_target $SOURCE
    63	
    64	  gpg_verify_sorcery $SOURCE $SORCERY_URL
    65	  rc=$?
    66	
    67	  gpg_user_query $rc $SORCERY_BRANCH sorcery || return 1
    68	  popd &>/dev/null
    69	
    70	  local FILENAME=$TMP_DIR/$SOURCE
    71	  # copy the tarball to /var/spool/sorcery after we've downloaded and
    72	  # verified it.
    73	  ensure_dir "$SOURCE_CACHE"
    74	  cp $FILENAME $SOURCE_CACHE
    75	
    76	  mk_source_dir  $SOURCE_DIRECTORY              &&
    77	  cd $BUILD_DIRECTORY
    78	  bzip2  -cdf   $FILENAME                       |
    79	  tar --owner=root --group=root -xf /dev/stdin  &&
    80	  cd      $SOURCE_DIRECTORY                     &&
    81	
    82	  echo `pwd`                                    || return 1
    83	
    84	  # last chance to lock
    85	  message -n "${MESSAGE_COLOR}Waiting for${DEFAULT_COLOR} ${SPELL_COLOR}all${DEFAULT_COLOR}" \
    86	             "${MESSAGE_COLOR}spells to complete...${DEFAULT_COLOR}"
    87	  lock_resources "solo" "cast" # prevent other casts
    88	  excllock_resources "cast" "sorcery" # wait for other casts
    89	  message "done."
    90	  lock_resources "libgrimoire" "install"      &&
    91	
    92	  if test -x ./uninstall && test -f /etc/sorcery/install.log ; then
    93	    message uninstalling...
    94	    ./uninstall
    95	  else
    96	    # rough equivalent to prepare_install...
    97	    rm /etc/sorcery/* 2>/dev/null
    98	    rm /etc/sorcery/licenses/*   2>/dev/null
    99	    rm /etc/sorcery/mirrors/* 2>/dev/null
   100	    rm /var/lib/sorcery/* 2>/dev/null
   101	    rm -r /var/lib/sorcery/modules/* 2>/dev/null
   102	    rm -r /var/lib/sorcery/archspecs/* 2>/dev/null
   103	    rm -r /var/lib/sorcery/build/* 2>/dev/null
   104	  fi
   105	  ./install                                     &&
   106	
   107	  cd /                                          &&
   108	  unlock_resources "libgrimoire" "install"      &&
   109	
   110	  SORCERY_VERSION=`cat /etc/sorcery/version`
   111	
   112	  unlock_resources "solo" "cast"
   113	  unlock_resources "cast" "sorcery"
   114	
   115	  if [ $? -eq 0 ] ; then
   116	    activity_log "update" "sorcery-$BRANCH" "$SORCERY_VERSION" "success"
   117	    rm_source_dir
   118	  else
   119	    activity_log "update" "sorcery-$BRANCH" "$SORCERY_VERSION" "failure"
   120	    if [[  $CLEAN_SOURCE == on ]]; then
   121	      rm_source_dir
   122	    fi
   123	  fi
   124	  message "${MESSAGE_COLOR}Current" \
   125	          "${SPELL_COLOR}sorcery-$BRANCH${DEFAULT_COLOR} ${MESSAGE_COLOR}version" \
   126	          "${VERSION_COLOR}$SORCERY_VERSION${DEFAULT_COLOR}"
   127	  echo
   128	  sorcery_history
   129	  rm $FILENAME
   130	}
   131	
   132	#---------------------------------------------------------------------
   133	##
   134	## Menu query to user asking to set the nice value which sorcery should
   135	## use to run proccesses at.
   136	##
   137	#---------------------------------------------------------------------
   138	function set_nice()  {
   139	
   140	  PROMPT="Please enter the process priority sorcery should run at."
   141	
   142	  if  NICE=`eval $DIALOG '  --ok-label  "Commit"  \
   143	                            --inputbox            \
   144	                            "$PROMPT"             \
   145	                            0 0  "$NICE"'`
   146	  then
   147	     modify_local_config "NICE" "$NICE"
   148	  fi
   149	
   150	}
   151	
   152	#---------------------------------------------------------------------
   153	##
   154	## Menu query to user asking to set the umask value which sorcery should
   155	## use to run proccesses with.
   156	##
   157	#---------------------------------------------------------------------
   158	function set_umask()  {
   159	
   160	  PROMPT="Please enter the permissions mask sorcery should run with."
   161	
   162	  if  UMASK=`eval $DIALOG '  --ok-label  "Commit"  \
   163	                            --inputbox            \
   164	                            "$PROMPT"             \
   165	                            0 0  "$UMASK"'`
   166	  then
   167	     modify_local_config "UMASK" "$UMASK"
   168	  fi
   169	
   170	}
   171	
   172	
   173	#---------------------------------------------------------------------
   174	## @param filename
   175	##
   176	## Displays and/or mails the contents of the file given as the first
   177	## argument.
   178	##
   179	#---------------------------------------------------------------------
   180	function report() {
   181	
   182	  if  !  [  -f  $1  ];  then  return;  fi
   183	
   184	  if  [  "$VIEW_REPORTS"  ==  "on"  ];  then
   185	
   186	    debug  "libsorcery" "Prompting to view $2 for $SPELL"
   187	
   188	    VIEW_PROMPT="View $2 for ${SPELL_COLOR}${SPELL}-${VERSION_COLOR}${VERSION}${DEFAULT_COLOR}?"
   189	    sound  REPORT
   190	    if  query  "$VIEW_PROMPT" n;  then  $PAGER  $1;  fi
   191	  fi
   192	
   193	  if  [  "$MAIL_REPORTS"  ==  "on"  ];  then
   194	    debug  "libsorcery" "Mailing report ($2) for $SPELL to $SORCERER"
   195	    date  -u  |
   196	    mail  -s  "Sorcery Report : $HOSTNAME : $2 for $SPELL-$VERSION"  \
   197	              -a $1 $SORCERER 2>/dev/null
   198	  fi
   199	
   200	  true
   201	
   202	}
   203	
   204	
   205	#---------------------------------------------------------------------
   206	## @param filename
   207	##
   208	## Given a filename, will return the actual filename if a similar
   209	## filename with a different extension exists.
   210	##
   211	#---------------------------------------------------------------------
   212	function guess_filename()  {
   213	
   214	  local filename=$1
   215	
   216	  debug "libsorcery" "Running guess_filename() on $filename"
   217	
   218	  if [[ -f  $filename ]]; then
   219	    echo $filename
   220	  else
   221	    # currently only used from gaze
   222	    if [[ $FUZZ != on ]]; then
   223	      return 1
   224	    else
   225	      local basename=$(sed -r "s/\.(tar\.(gz|bz2)|tgz|gz|bz2)$//" <<< "$filename")
   226	      local extension
   227	      for extension in tar.gz tar.bz2 tgz gz bz2; do
   228	        if [[ -f $basename.$extension ]]; then
   229	          echo $basename.$extension
   230	          return 0
   231	        fi
   232	      done
   233	      return 1
   234	    fi
   235	  fi
   236	
   237	}
   238	
   239	#-------------------------------------------------------------------------
   240	## check if the file exists, or one with a similar compression exists
   241	## @param file
   242	#-------------------------------------------------------------------------
   243	function file_exists()  {
   244	  guess_filename  $1  >  /dev/null
   245	}
   246	
   247	#---------------------------------------------------------------------
   248	##
   249	## Saves the current libraries associated with the spell, from /lib
   250	## and /usr/lib into $SOURCE_DIRECTORY/old.libraries/
   251	## Also runs ldconfig with the saved libraries.
   252	##
   253	#---------------------------------------------------------------------
   254	function save_libraries()  {
   255	
   256	  if    [  -z  "$SOURCE_DIRECTORY"  ]
   257	  then  return
   258	  fi
   259	
   260	  debug  "libsorcery" "Running save_libraries()"
   261	
   262	  OLD_LIBS=$SOURCE_DIRECTORY/old.libraries
   263	  mkdir -p "$OLD_LIBS"
   264	
   265	  SAVED=$OLD_LIBS/$SPELL.saved.libraries
   266	  lock_file "$SAVED"
   267	  rm -rf "$SAVED"
   268	
   269	  OLD_VERSION=`installed_version  $SPELL`
   270	      OLD_LOG=$INSTALL_LOGS/$SPELL-$OLD_VERSION
   271	
   272	  grep "^/lib/\|^/usr/lib" "$OLD_LOG" |
   273	  while  read        LINE;  do
   274	    if [[ -f $LINE ]] &&
   275	         file -bL "$LINE" |
   276	         grep  -q   "shared object"
   277	    then
   278	      if [[ -h $LINE ]]; then
   279	        local DEST=$(readlink "$LINE")
   280	        ln -sf "$DEST" "$OLD_LIBS/$(smgl_basename "$LINE")"
   281	      else
   282	        cp "$LINE" "$OLD_LIBS"
   283	      fi
   284	      echo $OLD_LIBS/$(smgl_basename "$LINE") >> "$SAVED"
   285	    fi
   286	
   287	
   288	  done
   289	
   290	  ldconfig "$OLD_LIBS"
   291	  unlock_file "$SAVED"
   292	
   293	  if  [  -z   "$LD_LIBRARY_PATH"  ]
   294	  then  export  LD_LIBRARY_PATH="$OLD_LIBS"
   295	  else  export  LD_LIBRARY_PATH="$OLD_LIBS:$LD_LIBRARY_PATH"
   296	  fi
   297	
   298	}
   299	
   300	#---------------------------------------------------------------------
   301	##
   302	## Saves the current libraries associated with the spell, from /lib
   303	## and /usr/lib into $SOURCE_DIRECTORY/old.libraries/
   304	## Also runs ldconfig with the saved libraries.
   305	##
   306	#---------------------------------------------------------------------
   307	function save_binaries()  {
   308	  local dir
   309	  if    [  -z  "$SOURCE_DIRECTORY"  ]
   310	  then  return
   311	  fi
   312	
   313	  debug  "libsorcery" "Running save_binaries()"
   314	
   315	  OLD_BINS=$SOURCE_DIRECTORY/old.binaries
   316	  mkdir -p "$OLD_BINS"
   317	
   318	  SAVED=$OLD_BINS/$SPELL.saved.binaries
   319	  lock_file "$SAVED"
   320	  rm -rf "$SAVED"
   321	
   322	  OLD_VERSION=`installed_version  $SPELL`
   323	      OLD_LOG=$INSTALL_LOGS/$SPELL-$OLD_VERSION
   324	
   325	  grep "^/bin/\|^/sbin/\|^/usr/bin/\|^/usr/sbin/" "$OLD_LOG" |
   326	  while  read        LINE;  do
   327	    if [[ -f $LINE ]] &&
   328	         file -bL "$LINE" |
   329	         grep  -q   "executable"
   330	    then
   331	      mkdir -p "$( smgl_dirname "$OLD_BINS/$LINE" )"
   332	      if [[ -h "$LINE" ]]; then
   333	        DEST=$( readlink "$LINE" )
   334	        ln -sf "$DEST" "$OLD_BINS/$LINE"
   335	      else
   336	        cp "$LINE" "$OLD_BINS/$LINE"
   337	      fi
   338	      echo $OLD_BINS/$LINE >> "$SAVED"
   339	    fi
   340	  done
   341	
   342	  unlock_file "$SAVED"
   343	
   344	  for dir in $(find "$OLD_BINS" -type d)
   345	  do
   346	    export PATH=$(envar_prepend_path "$dir" "$PATH")
   347	  done
   348	}
   349	
   350	
   351	#---------------------------------------------------------------------
   352	##
   353	## Runs default ldconfig to stop using the saved libraries
   354	##
   355	#---------------------------------------------------------------------
   356	function release_saved_libraries()  {
   357	  ldconfig
   358	}
   359	
   360	
   361	#---------------------------------------------------------------------
   362	##
   363	## Recovers from a CTRL-C while casting a spell
   364	##
   365	#---------------------------------------------------------------------
   366	function spell_recover()  {
   367	
   368	  debug  "libsorcery" "Running spell_recover()"
   369	
   370	  message  "${MESSAGE_COLOR}Aborting dispel of ${SPELL_COLOR}${SPELL}${DEFAULT_COLOR}" \
   371	           "${MESSAGE_COLOR}and recovering...${DEFAULT_COLOR}"
   372	
   373	  unlock_resources "libgrimoire" "install"
   374	  unlock_resources "cast" "$SPELL"
   375	  unlock_resources "solo" "cast"
   376	  local current_version=$(installed_version $SPELL)
   377	  SUCCESS_LIST=/dev/null
   378	  resurrect_spell $SPELL $current_version
   379	
   380	  exit  130
   381	}
   382	
   383	
   384	#---------------------------------------------------------------------
   385	## @param spell name
   386	## @Stdout section
   387	## Returns the section a spell is in.
   388	##
   389	#---------------------------------------------------------------------
   390	function find_section()  {
   391	
   392	  debug  "libsorcery" "Running find_section() on $1"
   393	
   394	  codex_get_spell_section_name  $1
   395	
   396	}
   397	
   398	
   399	#---------------------------------------------------------------------
   400	##=item directories
   401	##
   402	## @Stdin list of files/dirs/..
   403	## @Stdout list of dirs
   404	##
   405	## Reads a list from standard input, and prints out each entry that is
   406	## a directory (and not a symbolic link to a directory).
   407	#---------------------------------------------------------------------
   408	function directories() {
   409	  local item
   410	  while read item; do
   411	    if [[ -d $item ]] && ! [[ -h $item ]]; then
   412	      echo "$item"
   413	    fi
   414	  done
   415	}
   416	
   417	
   418	#---------------------------------------------------------------------
   419	## @Stdin list of files/dirs/..
   420	## @Stdout list of files
   421	## Reads a list from standard input, and prints out each entry that is
   422	## a file (and not a symbolic link to a file).
   423	##
   424	#---------------------------------------------------------------------
   425	function files()  {
   426	  local item
   427	  while read item; do
   428	    if [[ -f $item ]] && ! [[ -h $item ]]; then
   429	      echo "$item"
   430	    fi
   431	  done
   432	}
   433	
   434	
   435	#---------------------------------------------------------------------
   436	## @Stdin list of files/dirs/..
   437	## @Stdout list of symlinks
   438	## Reads a list from standard input, and prints out each entry that is
   439	## a symbolic linke
   440	##
   441	#---------------------------------------------------------------------
   442	function symlinks()  {
   443	  local item
   444	  while read item; do
   445	    if [[ -h $item ]]; then
   446	      echo "$item"
   447	    fi
   448	  done
   449	}
   450	
   451	
   452	#---------------------------------------------------------------------
   453	## @param filename
   454	## @Stdin list of files/dirs/..
   455	## @Stdout filtered list
   456	## First argument is a file that contains (basic) grep regular expressions.
   457	## They are joined with \|'s and given to grep -v.
   458	## Which will filter standard input to remove entries that match.
   459	## Used to filter out excluded or protected files from install logs.
   460	##
   461	#---------------------------------------------------------------------
   462	function filter() {
   463	  local thing RID_LIST NOT_RID_LIST
   464	  local files each invert
   465	  for each in $@; do
   466	    test -f $each && files="$files $each"
   467	  done
   468	
   469	  if [[ $files ]] ; then
   470	    RID_LIST=$(
   471	      cat $files   |
   472	      grep -v '^!' | while read thing; do
   473	                       echo -n "${thing}\|"
   474	                     done)
   475	    NOT_RID_LIST=$(
   476	      cat $files   |
   477	      grep '^!'    | while read thing; do
   478	                       echo -n "${thing/\!/}\|"
   479	                     done)
   480	    RID_LIST=${RID_LIST%\\|}
   481	    NOT_RID_LIST=${NOT_RID_LIST%\\|}
   482	
   483	    local TMP_SSF=$(make_safe_dir)
   484	    local FILE=$TMP_SSF/ssf
   485	
   486	    if [[ $RID_LIST ]]
   487	    then
   488	      if [[ $NOT_RID_LIST ]]
   489	      then
   490	        cat > $FILE
   491	        {
   492	          grep -v "$NOT_RID_LIST\|$RID_LIST" $FILE
   493	          grep "$NOT_RID_LIST" $FILE
   494	        }
   495	        rm $FILE 2>/dev/null
   496	      else
   497	        grep -v "$RID_LIST"
   498	      fi
   499	    else
   500	      cat
   501	    fi
   502	    rmdir $TMP_SSF 2>/dev/null
   503	  else
   504	    cat
   505	  fi
   506	}
   507	
   508	#---------------------------------------------------------------------
   509	## @param filename
   510	## @Stdin list of files/dirs/..
   511	## @Stdout filtered list
   512	## First argument is a file that contains (basic) grep regular expressions.
   513	## They are joined with \|'s and given to grep
   514	## Which will filter standard input and remove entries
   515	## that do not match.
   516	## Used to filter in config files from install logs.
   517	##
   518	#---------------------------------------------------------------------
   519	function filter_in() {
   520	  local thing RID_LIST NOT_RID_LIST
   521	  local files each
   522	  for each in $@; do
   523	    test -f $each && files="$files $each"
   524	  done
   525	
   526	  if [[ $files ]] ; then
   527	    RID_LIST=$(
   528	      cat $files   |
   529	      grep -v '^!' | while read thing; do
   530	                       echo -n "${thing}\|"
   531	                     done)
   532	    NOT_RID_LIST=$(
   533	      cat $files   |
   534	      grep '^!'    | while read thing; do
   535	                       echo -n "${thing/\!/}\|"
   536	                     done)
   537	    RID_LIST=${RID_LIST%\\|}
   538	    NOT_RID_LIST=${NOT_RID_LIST%\\|}
   539	
   540	    if [[ $RID_LIST ]]
   541	    then
   542	      if [[ $NOT_RID_LIST ]]
   543	      then
   544	        grep "$RID_LIST" |
   545	        grep -v "$NOT_RID_LIST"
   546	      else
   547	        grep "$RID_LIST"
   548	      fi
   549	    else
   550	      # grep '' outputs everything in this case we want nothing
   551	      cat > /dev/null
   552	    fi
   553	  else
   554	    cat
   555	  fi
   556	}
   557	
   558	function filter_generic() {
   559	  local args=$1
   560	  local filter_name=$2
   561	  local system_filter=$3
   562	  local spell_from=$4
   563	  local grimoire_filter section_filter spell_filter spell_dir
   564	  if [[ $spell_from == "codex" ]]
   565	  then
   566	    debug libsorcery "filter_generic codex at : $SCRIPT_DIRECTORY "
   567	    grimoire_filter=$GRIMOIRE/$filter_name
   568	    section_filter=$SECTION_DIRECTORY/$filter_name
   569	    spell_filter=$SCRIPT_DIRECTORY/$filter_name
   570	  else
   571	    if tablet_find_spell_dir $SPELL spell_dir &>/dev/null; then
   572	      debug libsorcery "filter_generic tablet at : $spell_dir "
   573	      tablet_get_spell_filter "$spell_dir" "$filter_name" spell_filter &>/dev/null
   574	      tablet_get_section_filter "$spell_dir" "$filter_name" section_filter &>/dev/null
   575	      tablet_get_grimoire_filter "$spell_dir" "$filter_name" grimoire_filter &>/dev/null
   576	    fi
   577	  fi
   578	  set -- $args
   579	  if [ "$1" == -v ] ; then
   580	    shift
   581	    filter_in "$@" $system_filter $grimoire_filter $section_filter $spell_filter
   582	  else
   583	    filter "$@" $system_filter $grimoire_filter $section_filter $spell_filter
   584	  fi
   585	}
   586	
   587	function filter_volatiles() {
   588	  filter_generic "$*" volatiles $VOLATILES
   589	}
   590	
   591	function filter_configs() {
   592	  filter_generic "$*" configs $CONFIGS
   593	}
   594	
   595	function filter_excluded() {
   596	  filter_generic "$*" excluded $EXCLUDED
   597	}
   598	
   599	function filter_protected() {
   600	  filter_generic "$*" protected $PROTECTED
   601	}
   602	
   603	#---------------------------------------------------------------------
   604	## @Stdin list of files
   605	## @Stdout list of directories
   606	##
   607	## THIS FUNCTION IS DEPRECIATED, use get_dirnames instead! (remove in 1.16)
   608	## Given a list of files from standard input, returns the directory
   609	## of each file.
   610	#---------------------------------------------------------------------
   611	function dirnames()  {
   612	  get_dirnames "$@"
   613	}
   614	
   615	#---------------------------------------------------------------------
   616	##
   617	## Sets some environment variables (such as C<CFLAGS>) based on the
   618	## option passed.  Options may be on or more of:  i386, i486, i586,
   619	## pentium, pentium-mmx, i686, pentiumpro, pentium2, pentium3,
   620	## pentium4, k6, k6-2, k6-3, athlon, athlon-tbird, athlon-4,
   621	## athlon-xp, athlon-mp, powerpc, speedy, tiny, risky, strip
   622	##
   623	#---------------------------------------------------------------------
   624	function optimize()  {
   625	  debug "libsorcery" "In optimize()"
   626	
   627	  unset  CFLAGS CXXFLAGS LDFLAGS CPPFLAGS
   628	  unset  FAST PRELINK RISKY SMALL SPEEDY STRIP TINY
   629	
   630	  # if user specified --no-opts then use only the args from the command line
   631	  # otherwise do the normal stuff
   632	  if [[ $NO_OPTIMIZATION_FLAGS ]] ; then
   633	    export CFLAGS="$OVERRIDE_CFLAGS"
   634	    export CXXFLAGS="$OVERRIDE_CXXFLAGS"
   635	    export LDFLAGS="$OVERRIDE_LDLAGS"
   636	    export CPPFLAGS="$OVERRIDE_CPPFLAGS"
   637	  else
   638	    set_architecture
   639	    debug "ARCHITECTURE='${ARCHITECTURE}'"
   640	    debug "libsorcery" "TARGET='${TARGET}'"
   641	    debug "libsorcery" "OPTIMIZATIONS='${OPTIMIZATIONS}'"
   642	    BUILD=${HOST}
   643	
   644	    debug "libsorcery" "BUILD is $BUILD, HOST is $HOST"
   645	
   646	    CFLAGS="$CFLAGS -pipe"
   647	    for  PARAM  in  $OPTIMIZATIONS;  do
   648	      case  $PARAM  in
   649	        prelink)
   650	          CFLAGS="$CFLAGS -DPIC -fPIC"
   651	          PRELINK="on"
   652	          ;;
   653	
   654	        risky)
   655	          CFLAGS="$CFLAGS -ffast-math -funroll-loops"
   656	          RISKY="on"
   657	          ;;
   658	
   659	        speedy)
   660	          CFLAGS="$CFLAGS $FAST"
   661	          SPEEDY="on"
   662	          ;;
   663	
   664	        strip)
   665	          LDFLAGS="$LDFLAGS -s"
   666	          STRIP="on"
   667	          ;;
   668	
   669	        tiny)
   670	          CFLAGS="$CFLAGS $SMALL"
   671	          TINY="on"
   672	          ;;
   673	
   674	      esac
   675	    done
   676	    # use echo to crunch all the whitespace out for broken configure scripts
   677	    export CXXFLAGS=$(echo $CFLAGS $CUSTOM_CXXFLAGS $OVERRIDE_CXXFLAGS $USER_SPELL_CXXFLAGS)
   678	    export CFLAGS=$(echo $CFLAGS $CUSTOM_CFLAGS $OVERRIDE_CFLAGS $USER_SPELL_CFLAGS)
   679	    export LDFLAGS=$(echo $LDFLAGS $CUSTOM_LDFLAGS $OVERRIDE_LDLAGS $USER_SPELL_LDFLAGS)
   680	    export CPPFLAGS=$(echo $CPPFLAGS $CUSTOM_CPPFLAGS $OVERRIDE_CPPFLAGS $USER_SPELL_CPPFLAGS)
   681	  fi
   682	
   683	}
   684	
   685	#---------------------------------------------------------------------
   686	## @param grimoire-path
   687	## @Stdout history
   688	## Display the history of the grimoire given for review
   689	#---------------------------------------------------------------------
   690	function grimoire_history() {
   691	
   692	  local grimoire="$1"
   693	  if [ -e $grimoire/ChangeLog ] ; then
   694	    local grimoirename="${grimoire##*/}"
   695	    local date="`cat "$STATE_DIRECTORY/$grimoirename.lastupdate" 2> /dev/null`"
   696	    [ -z "$date" ] && date="20030818"
   697	    local datedash=$(echo "$date" | sed 's,^\(....\)\(..\)\(..\)$,\1-\2-\3,')
   698	    get_new_changes "Viewing history since last update ($datedash) for grimoire --  ${grimoirename}  -- :" "$date" "$grimoire/ChangeLog"
   699	  else
   700	    echo  "No ChangeLog in the $grimoire Grimoire, skipping viewing..."
   701	    echo  ""
   702	  fi
   703	  date +%Y%m%d > "$STATE_DIRECTORY/$grimoirename.lastupdate"
   704	}
   705	
   706	
   707	#---------------------------------------------------------------------
   708	## @Stdout history
   709	## Display the history of sorcery for review
   710	##
   711	#---------------------------------------------------------------------
   712	function sorcery_history() {
   713	  local date="`cat "$STATE_DIRECTORY/sorcery.lastupdate" 2> /dev/null`"
   714	  [ -z "$date" ] && date="20030818"
   715	  local datedash="`echo "$date" | sed 's,^\(....\)\(..\)\(..\)$,\1-\2-\3,'`"
   716	
   717	  get_new_changes "Viewing history since last update ($datedash) for sorcery :"  "$date" /usr/share/doc/sorcery/ChangeLog
   718	
   719	  date +%Y%m%d > "$STATE_DIRECTORY/sorcery.lastupdate"
   720	}
   721	
   722	#---------------------------------------------------------------------
   723	##@param old date
   724	##@param changelog
   725	## Get the new changes from passed changelog argument
   726	##
   727	#---------------------------------------------------------------------
   728	function get_new_changes() {
   729	    local msg="$1"
   730	    local date="$2"
   731	    # This needs some explaination:
   732	    # The first item in {}'s extracts the date, assuming the format yyyy-mm-dd
   733	    # then checks if its less than the last-update date ($date). The second
   734	    # part ensures that we're actually looking at a date and not a line
   735	    # of changelog. If both those are true, set 'd' to 1, otherwise d is '0'.
   736	    #
   737	    # In other words, d is 0 until it encounters a starting changelog entry
   738	    # from before the given $date. Then d is 1 for each starting entry. Its
   739	    # always 0 for bulleted changelog lines and blank lines.
   740	    #
   741	    # The second portion begins "NR==1,d". This is special awk syntax
   742	    # that says to run the stuff to the right in {}'s starting once the
   743	    # first statement is true, up through when the second one is true.
   744	    # For example, NR==1,NR==8 would run the right-hand block for lines 1
   745	    # through 8.
   746	    #
   747	    # NR is the line number, so its true on the first line. d is true once the
   748	    # the dates are from before the last update. The if(!d) is necessary
   749	    # to skip the first line where the changelog date is less than $date.
   750	    #
   751	    local changelog="$( awk -v date="$date" '{ d = (strtonum(substr($0,1,4) substr($0,6,2) substr($0,9,2)) < date && strtonum(substr($0,1,4)) > 0); }; NR == 1, d { if (!d) print }' "$3" )"
   752	
   753	    if [[ "$changelog" ]] ; then
   754	      {
   755	        echo "$msg"
   756	        echo "$changelog"
   757	        echo
   758	      }  > $TMP_DIR/pagerdata
   759	      timeout_pager "$TMP_DIR/pagerdata"
   760	      rm $TMP_DIR/pagerdata
   761	    else
   762	      echo "$msg"
   763	      echo "Nothing new."
   764	      echo
   765	    fi
   766	}
   767	
   768	
   769	#---------------------------------------------------------------------
   770	## Pager with timeouts, cannot be used from a pipe.
   771	## Invokes a subshell in case there are other background jobs running
   772	#---------------------------------------------------------------------
   773	function timeout_pager() { (
   774	  $PAGER "$@" &
   775	  sleep 1
   776	  for ((i=0;i<PAGER_TIMEOUT*10;i++)) ; do
   777	    jobs &>/dev/null # this makes bash clean up so the next line works
   778	    [[ "$(jobs)" ]] || return 0
   779	    sleep .1
   780	  done
   781	  jobs -p|xargs kill
   782	  jobs &>/dev/null # hide the [Done [2] blah blah] message
   783	  stty sane
   784	  if query "\nPager timeout, continue viewing $@" n; then
   785	    $PAGER "$@"
   786	  fi
   787	) 2>/dev/null # hides less complaining that it was killed
   788	}
   789	
   790	#---------------------------------------------------------------------
   791	##
   792	## Attempt to fix any spells that may be broken.
   793	##
   794	#---------------------------------------------------------------------
   795	function fix_installed_spells()  {
   796	
   797	  local ANSWER=
   798	
   799	  [  "$AUTOFIX"  ==  "on"  ]  &&  ANSWER=y  ||  ANSWER=n
   800	  if  query  "Attempt to fix spells that may have become broken ?" $ANSWER;  then
   801	    cleanse --fix;
   802	  fi
   803	
   804	  if  [  "$AUTOPRUNE"  ==  "on"  ];  then  prune;  fi
   805	}
   806	
   807	#---------------------------------------------------------------------
   808	## @Stdout log files list
   809	## Returns a list of the log files for each spell.
   810	##
   811	#---------------------------------------------------------------------
   812	function log_list()  {
   813	  local spell version
   814	  while read spell version; do
   815	    # the install and md5sum logs are not compressed
   816	    echo "$INSTALL_LOGS/$spell-$version"
   817	    echo "$MD5SUM_LOGS/$spell-$version"
   818	    # the compile and castfs log usually are compressed
   819	    # FIXME $EXTENSION may be the wrong one if the user changed it
   820	    echo "$COMPILE_LOGS/$spell-$version$EXTENSION"
   821	    echo "$COMPILE_LOGS/$spell-$version.castfs.dbglog$EXTENSION"
   822	  done < <(all_spell_status | cut -d: -f1,4 --output-delimiter=" ")
   823	}
   824	
   825	
   826	#---------------------------------------------------------------------
   827	##
   828	## Removes stale logs.
   829	##
   830	#---------------------------------------------------------------------
   831	function clean_logs()  {
   832	  debug  "libsorcery" "Running clean_logs()"
   833	  local file
   834	
   835	  message "${CHECK_COLOR}Cleaning log files...$DEFAULT_COLOR"
   836	
   837	  {
   838	    # don't try to delete logs of installed spells, as they may not exist
   839	    # tee duplicates the output, so uniq will filter them out
   840	    log_list | sed p
   841	    find $INSTALL_LOGS $MD5SUM_LOGS $COMPILE_LOGS -type f
   842	  } | sort | uniq -u |
   843	  while read file; do
   844	    message "Removing stale log: $file"
   845	    rm "$file"
   846	  done
   847	}
   848	
   849	#---------------------------------------------------------------------
   850	##
   851	## Updates the activity log.
   852	##
   853	#---------------------------------------------------------------------
   854	function activity_log() {
   855	  local date command spell version outcome info
   856	
   857	  lock_file $ACTIVITY_LOG
   858	     date=$(date -u +%Y%m%d:%H%M\(%z\))
   859	  command=$1
   860	    spell=$2
   861	  version=$3
   862	  outcome=$4
   863	     info=$5
   864	  echo -e "$date\t$command\t$spell\t$version\t$outcome\t$info" >> $ACTIVITY_LOG
   865	  unlock_file $ACTIVITY_LOG
   866	}
   867	
   868	
   869	#---------------------------------------------------------------------
   870	##
   871	## Executes the spell's DETAILS file.
   872	##
   873	#---------------------------------------------------------------------
   874	function run_details() {
   875	  debug "libsorcery" "starting run_details for $SPELL"
   876	  if  !  codex_set_current_spell_by_name  $SPELL;  then
   877	    local  GRIMOIRES=`codex_get_all_grimoires`
   878	    message  "${PROBLEM_COLOR}Unable to find spell"        \
   879	             "${SPELL_COLOR}${SPELL}${DEFAULT_COLOR}${PROBLEM_COLOR}"      \
   880	             "in grimoire(s): $GRIMOIRES ${DEFAULT_COLOR}"
   881	    false
   882	  fi
   883	}
   884	
   885	#---------------------------------------------------------------------
   886	##
   887	## unsets variables set by DETAILS. <br>
   888	## vars: SPELL VERSION SOURCE_DIRECTORY WEB_SITE UPDATED ENTERED SHORT SOURCE*
   889	##
   890	## Needs to be merged with the libcodex function since they are both
   891	## needed to fully unset a DETAILS (afk 4/21/04)
   892	##
   893	#---------------------------------------------------------------------
   894	function unset_details()  {
   895	
   896	  local TEMP=""
   897	  local VARS="SPELL VERSION SOURCE_DIRECTORY WEB_SITE UPDATED ENTERED SHORT"
   898	  VARS="$VARS SECURITY_PATCH PATCHLEVEL"
   899	
   900	  # Take care or SOURCEx and SOURCEx_URL
   901	  for i in ${!SOURCE*} ; do
   902	    TEMP=${TEMP}${i}\\n
   903	  done
   904	  # not all SOURCE_* should be deleted (SOURCE_CACHE)
   905	  VARS="$VARS `echo -e $TEMP | egrep "^SOURCE[[:digit:]]*(_URL|_GPG|_IGNORE)?$"`"
   906	
   907	  unset $VARS
   908	}
   909	
   910	
   911	
   912	
   913	#---------------------------------------------------------------------
   914	##
   915	## Runs C<track> and C<archive> on the current spell.
   916	##
   917	## THIS FUNCTION IS DEPRECIATED AND SHOULD NOT BE CALLED FOR ANY REASON
   918	##
   919	#---------------------------------------------------------------------
   920	function boost() {
   921	
   922	  debug  "libsorcery" "Running boost() on $SPELL THIS IS DEPRECIATED"
   923	  echo "Running boost() on $SPELL THIS IS DEPRECIATED, please contact the spell's maintainer and ask them to remove this call"
   924	  true
   925	}
   926	
   927	
   928	#---------------------------------------------------------------------
   929	##
   930	## Given a list of source files, returns true if each file exists.
   931	##
   932	#---------------------------------------------------------------------
   933	function verify_source() {
   934	  local source_file
   935	  for source_file in $@; do
   936	    if ! guess_filename $SOURCE_CACHE/$source_file > /dev/null; then
   937	      message  "${PROBLEM_COLOR}Missing ${FILE_COLOR}$source_file${DEFAULT_COLOR}"
   938	      message  "${PROBLEM_COLOR}Cast aborting.${DEFAULT_COLOR}"
   939	      activity_log  "cast"  "$SPELL"  "$VERSION"  "failure"  \
   940	                    "because it was missing source: $source_file"
   941	      log_failure_reason "missing source"
   942	      return 1
   943	    fi
   944	  done
   945	  return 0
   946	}
   947	
   948	
   949	#---------------------------------------------------------------------
   950	## @param spell
   951	## @Stdout filelist
   952	## Returns a list of each source file used by a spell.  Most have only
   953	## one, but xfree86 for example splits the sources into three separate
   954	## source files.
   955	##
   956	#---------------------------------------------------------------------
   957	function sources()  { (
   958	
   959	  local i srcVar
   960	
   961	  if  [  -z  "$SOURCE"  ];  then
   962	    codex_set_current_spell_by_name  $1
   963	  fi
   964	  get_spell_files
   965	
   966	) }
   967	
   968	#---------------------------------------------------------------------
   969	## @param spell
   970	## @Stdout filelist
   971	## Returns a list of each source file used by a spell.  Most have only
   972	## one, but xfree86 for example splits the sources into three separate
   973	## source files.
   974	##
   975	#---------------------------------------------------------------------
   976	function source_urls()  { (
   977	
   978	  local i srcVar
   979	
   980	  if  [  -z  "$SOURCE"  ];  then
   981	    codex_set_current_spell_by_name  $1
   982	  fi
   983	  get_spell_files_and_urls|while read -a line; do
   984	    unset line[0]
   985	    echo "${line[*]}"
   986	  done
   987	
   988	
   989	) }
   990	
   991	
   992	#---------------------------------------------------------------------
   993	## @Stdout filelist
   994	## Returns a list of files that should not be pruned.
   995	##
   996	#---------------------------------------------------------------------
   997	function generate_keep_list()  {
   998	  local source_keep=$1
   999	  local cache_keep=$2
  1000	  local type=$3
  1001	  if [[ $type == installed_only ]] ; then
  1002	    get_all_spells_with_status ok |
  1003	    sort -u |
  1004	    while read spell; do
  1005	      codex_find_spell_by_name $spell
  1006	    done
  1007	  else
  1008	    codex_get_all_spells
  1009	  fi |
  1010	  (
  1011	  echo sorcery-$SORCERY_BRANCH.tar.bz2
  1012	  while read SPELL_DIRECTORY ; do
  1013	    codex_set_current_spell_quick  $SPELL_DIRECTORY &>/dev/null
  1014	    sources 2>/dev/null
  1015	    ls $INSTALL_CACHE/$SPELL-$VERSION-* 1>&2 2>/dev/null
  1016	    unset VERSION SPELL ${!SOURCE*}
  1017	  done
  1018	  ) 2> $cache_keep > $source_keep
  1019	
  1020	  #Add the README in the cache to list of files to keep
  1021	  echo  README >> $cache_keep
  1022	
  1023	}
  1024	
  1025	
  1026	#---------------------------------------------------------------------
  1027	##
  1028	## Removes unnecessary files from the source cache and install cache.
  1029	##
  1030	#---------------------------------------------------------------------
  1031	function prune()  {
  1032	
  1033	  debug  "libsorcery" "Running prune()"
  1034	  local NO_KEEP
  1035	  local NUM_NO_KEEP=0
  1036	
  1037	  message "${MESSAGE_COLOR}Generating list of files to keep...${DEFAULT_COLOR}"
  1038	  local SOURCE_KEEP="$TMP_DIR/prune-keep-source"
  1039	  local CACHE_KEEP="$TMP_DIR/prune-keep-cache"
  1040	  rm -rf $CACHE_KEEP
  1041	  rm -rf $SOURCE_KEEP
  1042	  generate_keep_list  $SOURCE_KEEP $CACHE_KEEP $1
  1043	
  1044	  message "${MESSAGE_COLOR}Cleaning up source cache" \
  1045	          "(${DEFAULT_COLOR}$SOURCE_CACHE${MESSAGE_COLOR})...${DEFAULT_COLOR}"
  1046	  local SOURCE_RM="$TMP_DIR/prune.rm.source"
  1047	  find $SOURCE_CACHE -follow -mindepth 1 -maxdepth 1 -type f|
  1048	  awk -F/ 'BEGIN {
  1049	             while ( getline < ARGV[1] ) {
  1050	               keep[$NF] = 1;
  1051	             }
  1052	             while ( getline < ARGV[2] ) {
  1053	               if ( keep[$NF] != 1 ) {
  1054	                 print $0;
  1055	               }
  1056	             }
  1057	           }' $SOURCE_KEEP - |sort -u > $SOURCE_RM
  1058	  if test -s $SOURCE_RM ; then
  1059	    NUM_NO_KEEP=$(cat $SOURCE_RM|wc -l)
  1060	
  1061	    message "There are $NUM_NO_KEEP files that can be removed"
  1062	    if query "Edit the list?" "n" ; then
  1063	      edit_file $SOURCE_RM
  1064	    fi
  1065	    if query "Remove the files?" "y" ; then
  1066	      cat $SOURCE_RM|xargs rm
  1067	    fi
  1068	  fi
  1069	
  1070	  message "${MESSAGE_COLOR}Cleaning up install cache" \
  1071	          "(${DEFAULT_COLOR}$INSTALL_CACHE${MESSAGE_COLOR})...${DEFAULT_COLOR}"
  1072	  local CACHE_RM="$TMP_DIR/prune.rm.cache"
  1073	  find $INSTALL_CACHE -mindepth 1 -maxdepth 1 -type f|
  1074	  awk -F/ 'BEGIN {
  1075	             while ( getline < ARGV[1] ) {
  1076	               keep[$NF] = 1;
  1077	             }
  1078	             while ( getline < ARGV[2] ) {
  1079	               if ( keep[$NF] != 1 ) {
  1080	                 print $0;
  1081	               }
  1082	             }
  1083	           }' $CACHE_KEEP - |sort -u > $CACHE_RM
  1084	  if test -s $CACHE_RM ; then
  1085	    NUM_NO_KEEP=$( cat $CACHE_RM | wc -l )
  1086	    message "There are $NUM_NO_KEEP files that can be removed"
  1087	    if query "Edit the list?" "n" ; then
  1088	      edit_file $CACHE_RM
  1089	    fi
  1090	    if query "Remove the files?" "y" ; then
  1091	      cat $CACHE_RM|xargs rm
  1092	    fi
  1093	  fi
  1094	
  1095	  rm  -f  $SOURCE_KEEP $CACHE_KEEP $SOURCE_RM $CACHE_RM
  1096	
  1097	}
  1098	
  1099	
  1100	#---------------------------------------------------------------------
  1101	##
  1102	## Sets DISTCC=[on|off] depending on the value of DISTCC_HOSTS.
  1103	## Adds /var/lib/sorcery/build to the C<PATH> if necessary.
  1104	##
  1105	#---------------------------------------------------------------------
  1106	function invoke_build_dir() {
  1107	
  1108	  # This merits some explaination:
  1109	  #
  1110	  # In the /var/lib/sorcery/build dir are frontends for the compilers
  1111	  # they run CCACHE and DISTCC. By putting them in the front of the path
  1112	  # they get run first, then hand the work off to the real compilers.
  1113	  # The script also loads /etc/sorcery/compile_config, this made it
  1114	  # convenient for building stuff outside of sorcery and taking advantage
  1115	  # of ccache/distcc, just do "export  PATH="/var/lib/sorcery/build:$PATH""
  1116	  # and you're set, you can also edit the DISTCC hosts on the fly.
  1117	  #
  1118	  # Then someone had the bright idea "if we set DISTCC_HOSTS to the empty
  1119	  # string, distcc wont run!" due to a misconception in how this function
  1120	  # worked, that spell hack would only work /some/ of the time: if you
  1121	  # used ccache in addition to distcc, distcc wouldnt get disabled. *Sigh*
  1122	  #
  1123	  # SO...now we're stuck with a bunch of spells in the field disabling
  1124	  # distcc in an broken way, obviously they all cant change overnight. To
  1125	  # make matters worse inside make() we have to fiddle with the number of
  1126	  # make jobs to use in case distcc is disabled (badly).
  1127	  #
  1128	  # so the answer is:
  1129	  # 1) make a new variable "USE_DISTCC" and set it to "off" if distcc
  1130	  # is being disabled by the spell
  1131	  # 2) check if USE_DISTCC == off in run_compiler, but still check the
  1132	  # other signs just in case its being run manually
  1133	  # 3) add a check for DISABLE_DISTCC so spells can start using that someday
  1134	  #   (phase this in after a few months, then phase out the old check below,
  1135	  #   but not in run_compiler)
  1136	  # 4) remove the old stupid logic for MAKE_NJOBS (num_hosts + 1),
  1137	  # instead split MAKE_NJOBS up, add a JOBS_PER_HOST multiplier, and add
  1138	  # MAKE_NJOBS to that. This results in the number of jobs being $MAKE_NJOBS
  1139	  # (default 1) when distcc is disabled (bug 6432), and allows an automatic
  1140	  # increase in the number of jobs per host if its desired.
  1141	  #
  1142	
  1143	  USE_DISTCC=off
  1144	  if [[ $DISABLE_DISTCC != yes ]] ; then
  1145	    if test -n "$DISTCC_HOSTS" && spell_ok distcc ; then
  1146	      USE_DISTCC=on
  1147	    fi
  1148	  fi
  1149	
  1150	  if ! spell_ok ccache ; then
  1151	    CCACHE=off
  1152	  fi
  1153	
  1154	  if [[ "$CCACHE" == on ]] || [[ "$USE_DISTCC" == on ]] ; then
  1155	    export  PATH="$RUN_COMPILER_DIR:$PATH"
  1156	  fi
  1157	}
  1158	
  1159	#---------------------------------------------------------------------
  1160	## @Stdout filelist
  1161	## Returns false if one or more source files for the current spell
  1162	## are missing.
  1163	##
  1164	#---------------------------------------------------------------------
  1165	function verify_sources()  {
  1166	  verify_source $(sources $SPELL)
  1167	}
  1168	
  1169	
  1170	
  1171	#---------------------------------------------------------------------
  1172	##
  1173	## Will set the prefered compression type based on user filled option
  1174	## in dialog menu (either gzip/bzip).
  1175	##
  1176	#---------------------------------------------------------------------
  1177	function set_compression_type() {
  1178	
  1179	  local B_HELP="bzip2 compression (slow, small files)"
  1180	  local P_HELP="parallel bzip2 compression (slow unless on SMP, small files)"
  1181	  local X_HELP="xz compression (slow compress, fast decompress, smallest files)"
  1182	  local G_HELP="gzip compression (fast, larger files)"
  1183	  local T_HELP="no compression/tar (fastest, largest files)"
  1184	
  1185	  while
  1186	
  1187	    COMMAND=`eval $DIALOG '  --title "Currently using : $COMPRESSBIN "  \
  1188	                             --item-help                                \
  1189	                             --ok-label      "Select"                   \
  1190	                             --cancel-label  "Exit"                     \
  1191	                             --menu                                     \
  1192	                             ""                                         \
  1193	                             0 0 0                                      \
  1194	                             "B"  "bzip2 compression"        "$B_HELP"  \
  1195	                             "P"  "pbzip2 compression (parallel bzip2)" "$P_HELP"  \
  1196	                             "X"  "xz compression"           "$X_HELP"  \
  1197	                             "G"  "gzip compression"         "$G_HELP"  \
  1198	                             "T"  "no compression/tar"       "$T_HELP"'`
  1199	
  1200	  do
  1201	    ARCHIVEBIN="tar"
  1202	    modify_local_config "ARCHIVEBIN" "tar"
  1203	
  1204	    case  $COMMAND in
  1205	      B)
  1206	          modify_local_config "COMPRESSBIN" "bzip2" &&
  1207	          COMPRESSBIN="bzip2"                        &&
  1208	          modify_local_config "EXTENSION" ".bz2" ;;
  1209	      P)
  1210	          if ! spell_ok pbzip2; then
  1211	            clear_line
  1212	            message "pbzip2 is not installed on this system! Running cast ...\n"
  1213	            sleep 2
  1214	            cast pbzip2
  1215	          fi &&
  1216	          modify_local_config "COMPRESSBIN" "pbzip2"  &&
  1217	          COMPRESSBIN="pbzip2"                        &&
  1218	          modify_local_config "EXTENSION" ".bz2" ;;
  1219	      X)
  1220	          if ! spell_ok xz-utils; then
  1221	            clear_line
  1222	            message "xz-utils is not installed on this system! Running cast ...\n"
  1223	            sleep 2
  1224	            cast xz-utils
  1225	          fi &&
  1226	          modify_local_config "COMPRESSBIN" "xz"   &&
  1227	          COMPRESSBIN="xz"                         &&
  1228	          modify_local_config "EXTENSION" ".xz"    ;;
  1229	      G)
  1230	          modify_local_config "COMPRESSBIN" "gzip" &&
  1231	          COMPRESSBIN="gzip"                         &&
  1232	          modify_local_config "EXTENSION" ".gz" ;;
  1233	      T)
  1234	          modify_local_config "COMPRESSBIN" ""       &&
  1235	          COMPRESSBIN=""                             &&
  1236	          modify_local_config "EXTENSION" ""         ;;
  1237	    esac
  1238	  done
  1239	
  1240	}
  1241	
  1242	#---------------------------------------------------------------------
  1243	## @param filename
  1244	## @return 0 if filename seems to be compressed
  1245	## @return 1 otherwise
  1246	## Returns true if the name of the file indicates that it should be
  1247	## a compressed file.  In other words, this function returns true if
  1248	## the extension is .gz, .tgz, .bz2, .zip, .rpm, .Z, .xz, .7z or .lzma.
  1249	##
  1250	#---------------------------------------------------------------------
  1251	function filename_indicates_compression()  {
  1252	  grep -qE "^.*\.(gz|tgz|bz2|zip|Z|rpm|xz|7z|lzma)$" <<< "$1"
  1253	}
  1254	
  1255	#---------------------------------------------------------------------
  1256	## Check that we have all the passed grimoires and use them to
  1257	## override the default selection (all)
  1258	#---------------------------------------------------------------------
  1259	function override_grimoires() {
  1260	  local grimoires=$1
  1261	  local grimoire
  1262	
  1263	  for grimoire in $grimoires; do
  1264	    if ! codex_find_grimoire $grimoire > /dev/null; then
  1265	      error_message "Grimoire $grimoire does not exist!"
  1266	      if query "Do you want to add it?" y; then
  1267	        scribe add $grimoire || exit 13
  1268	        echo
  1269	      else
  1270	        list_remove grimoires $grimoire
  1271	      fi
  1272	    fi
  1273	  done
  1274	  [[ -z $grimoires ]] && message "Using default grimoire selection!\n"
  1275	
  1276	  export OVERRIDE_GRIMOIRES="$grimoires"
  1277	}
  1278	
  1279	#---------------------------------------------------------------------
  1280	## Sets the most appropriate params for PAGER
  1281	## @Globals PAGER
  1282	#---------------------------------------------------------------------
  1283	function set_pager() {
  1284	  if [[ -z $PAGER ]]; then
  1285	    if real_spell_ok less; then
  1286	      # pager info
  1287	      # -R: display color codes properly
  1288	      # -F: quit on one-screenfull of data (otherwise scribe pauses on empty updates)
  1289	      # -X: dont do screen init and deinit, gaze install
  1290	      # of a small spell is effectively useless otherwise as the
  1291	      # screen is cleared afterwards.
  1292	      # -f: force it, since we may not be dealing with a regular file
  1293	      PAGER="less -R -F -X -f"
  1294	    else
  1295	      PAGER=cat
  1296	    fi
  1297	    return
  1298	  fi
  1299	
  1300	  local pager_prog
  1301	  local pager_params=${PAGER#* }
  1302	  smgl_basename "${PAGER%% *}" pager_prog
  1303	  # setting PAGER to a single word would give bad parameters
  1304	  [[ $pager_prog == $PAGER ]] && unset pager_params
  1305	
  1306	  # TODO: add any needed options for the rest of the pagers
  1307	  case $pager_prog in
  1308	    less) PAGER="less -R -F -X -f $pager_params" ;;
  1309	    most) PAGER="most $pager_params" ;;
  1310	    w3m)  PAGER="w3m $pager_params" ;;
  1311	    more) PAGER="more $pager_params";;
  1312	    *) ;;
  1313	  esac
  1314	}
  1315	
  1316	#---------------------------------------------------------------------
  1317	##
  1318	## This software is free software; you can redistribute it and/or modify
  1319	## it under the terms of the GNU General Public License as published by
  1320	## the Free Software Foundation; either version 2 of the License, or
  1321	## (at your option) any later version.
  1322	##
  1323	## This software is distributed in the hope that it will be useful,
  1324	## but WITHOUT ANY WARRANTY; without even the implied warranty of
  1325	## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  1326	## GNU General Public License for more details.
  1327	##
  1328	## You should have received a copy of the GNU General Public License
  1329	## along with this software; if not, write to the Free Software
  1330	## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  1331	##
  1332	#---------------------------------------------------------------------