home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 98 / Skunkware 98.iso / osr5 / sco / scripts / config < prev    next >
Encoding:
Korn shell script  |  1997-08-26  |  45.7 KB  |  1,305 lines

  1. #!/bin/ksh
  2. # @(#) config.ksh 1.8 97/05/20
  3. # 93/05/06 john h. dubois iii (john@armory.com)
  4. # 93/06/07 Added userpath option
  5. # 94/01/02 Fixed bug that made userpath fail for csh users
  6. # 94/01/12 Added erase option
  7. # 94/03/05 Added -u option
  8. # 94/03/13 Added -d option.  Make ksh expand $userpath to avoid csh error.
  9. # 94/04/16 Give more detailed error messages when checking path.
  10. # 94/07/09 Fixed quoting of help message.
  11. # 95/01/07 Give VISUAL the same value as EDITOR
  12. # 95/01/29 Added LINES
  13. # 95/02/04 Added forward and biff.
  14. # 95/04/14 Generalized scheme for allowing only valid options.
  15. #          Added .httpreport setup.
  16. # 96/01/19 Increased description field size to 18 chars; added coredumpsize;
  17. #          do InitArrs only if the arrays are going to be used.
  18. # 96/01/24 Make csh limit coredumpsize work.
  19. # 96/01/26 More verbose descriptions of editors.
  20. # 96/01/26 Make .forward be readable by all.
  21. # 96/03/11 Added shell mail notification, timezone, and hushlogin to arrays.
  22. # 96/06/13 Added remaining code neccessary to support hushlogin & shellmail.
  23. # 96/06/17 Put http report levels one per line.
  24. #          Changed mesg and termtype query to be on or off instead of y/n.
  25. #          Do not allow other values to be given for on/off values.
  26. # 96/06/29 Added file versioning and SHOWVERSIONS.
  27. # 96/07/26 Let periodicity be given for http report level.
  28. # 96/12/06 Make d option actually work.  Added D option.
  29. # 97/02/28 Added "allhits" to httpreport levels.
  30. # 97/04/13 Pause after printing help if needed for help to fit on screen.
  31. #          Made short descriptions more verbose.
  32. #          Added "..." from description to value in interactive display.
  33. # 97/05/10 Work better on terminals with few lines: if needed, fit two menu
  34. #          columns into 80 character columns.
  35.  
  36. # todo: Possible additional options: password, timezone, language
  37.  
  38. alias istrue="test 0 -ne"
  39. alias isfalse="test 0 -eq"
  40.  
  41. # Each option must be added to array Vars and all of those in function
  42. # InitArrs.  All vars that are acted on by -b and -c options and which do
  43. # anything besides set env. vars must have code to deal with them in Setup.
  44. # All vars must have code in InitVars, if nothing else to unset them if config
  45. # is run with the -u option.
  46. # Any config options that are stored by other means than writing to .config
  47. # must have special case handing in GetConfig and SetConfig.
  48.  
  49. # Vars[i]    Variable names.
  50. # NumPref    Number of config options.
  51. # Descrip[i]    Short descriptions of config options.
  52. # Verbose[i]    Long (multi-line) descriptions of config options.
  53. # Values[i]    Values of config options
  54. # Defaults[i]    Default values
  55.  
  56. # Ind varname        returns index of varname
  57. # ShowValue varname    prints varname followed by its value
  58. # SetVal var [val]    sets var in Values to val or shell param value
  59. # GetConf        Reads config from config file into Values[] & shell
  60. # AssignVal var=value    Sets var in Values to value
  61. # ShowConfig        Show current configuration
  62.  
  63. # Usage: Ind varname
  64. # Returns the index of varname if it is valid.
  65. # Prints an error message and returns 0 if it is not.
  66. function Ind {
  67.     typeset -i i=1
  68.     while [ i -le NumPref ]; do
  69.     if [ "$1" = ${Vars[i]} ]; then
  70.         return $i
  71.     fi
  72.     let i+=1
  73.     done
  74.     print -u2 "Unknown preference type: $1"
  75.     return 0
  76. }
  77.  
  78. # Usage: SetVal varname [value]
  79. # Sets the variable's shell value and value in Values[] to value, if given,
  80. # or to the value of the shell parameter with the same name if not.
  81. # Prints an error message and returns 0 if varname is invalid.
  82. function SetVal {
  83.     typeset -i Index
  84.  
  85.     Ind "$1"
  86.     Index=$?
  87.     isfalse Index && return 1
  88.     if [ $# = 2 ]; then
  89.     Values[Index]=$2
  90.     eval $1="'$2'"
  91.     else
  92.     eval 'Values[Index]'=\$$1
  93.     fi
  94.     return 0
  95. }
  96.  
  97. # Reads configuration assignments from config file and sets Values[] to them.
  98. # Also sets shell parameters with the var names to the values.
  99. # Uses globals: Vars[]
  100. # If an argument is given, a complaint is printed if no config file is found.
  101. function GetConfig {
  102.     typeset v
  103.  
  104.     if [ ! -f "$PrefFile" ]; then
  105.     [ $# -gt 0 ] && print -u2 \
  106. "You do not have an account configuration file yet.
  107. Use  $name -i  to create one."
  108.     return 1
  109.     elif [ ! -r "$PrefFile" ]; then
  110.     [ $# -gt 0 ] && print -u2 "Your config file is not readable."
  111.     return 1
  112.     else
  113.     unset ${Vars[*]}
  114.     eval "`set_vars $PrefFile`"
  115.     [ -f $HOME/.forward ] && forward="$(<$HOME/.forward)"
  116.     [ -e $HOME/.hushlogin ] && hushlogin=on || hushlogin=off
  117.     if [ -f $HOME/.httpreport ]; then
  118.         # Put all lines on one line
  119.         set -- $(<$HOME/.httpreport)
  120.         httpreport="$*"
  121.     fi
  122.     [ -u "$HOME" ] && versioning=on || versioning=off
  123.     for v in ${Vars[*]}; do
  124.         # convert old parameter values
  125.         case $v in
  126.         mesg)
  127.         case "$mesg" in
  128.         [yY]*)
  129.             mesg=on;;
  130.         [nN]*)
  131.             mesg=off;;
  132.         esac
  133.         ;;
  134.         askterm)
  135.         case "$askterm" in
  136.         [yY]*)
  137.             askterm=on;;
  138.         [nN]*)
  139.             askterm=off;;
  140.         esac
  141.         ;;
  142.         esac
  143.         SetVal $v
  144.     done
  145.     fi
  146.     return 0
  147. }
  148.  
  149. # set_vars 1.1 91/01/23
  150. # set_vars: Read variable assignments, 
  151. # convert values to forms that won't be messed with by the shell,
  152. # and output them in a form that is ready for the shell to evaluate
  153. # usage: eval "`set_vars [ filename ]`"
  154. # where the lines in filename are of the form
  155. # var=value
  156. # value may contain spaces, backslashes, quote characters, etc.;
  157. # they will become part of the value assigned to var by eval.
  158. # Lines that begin with a # (optionally preceded by whitespace)
  159. # and lines that do not contain a '=' are ignored.
  160. function set_vars {
  161. /bin/sed "
  162. /[     ]*#/d
  163. /=/!d
  164. s/'/'\\\\''/g
  165. s/=/='/
  166. s/$/'/" $*
  167. }
  168.  
  169. # Usage: EmitVar shelltype varname value
  170. function EmitVar {
  171.     typeset shelltype=$1 var=$2 val=$3
  172.     # An = is used between var and value even for csh 
  173.     # env vars so that the single-quote-escaping sed script
  174.     # can recognize the start of the value.
  175.     if [ $shelltype = b ]; then
  176.     echo "$var=$val"
  177.     echo "export $var"
  178.     else
  179.     echo "setenv $var=$val"
  180.     fi
  181. }
  182.  
  183. # Uses globals: NumPref, Vars[], GetConfig(), debug
  184. # Usage: Setup b|c
  185. # Emits configuration strings based on contents of .config file
  186. # and carries out these direct login session modifications:
  187. # modifications of termio
  188. # mesg y/n
  189. # mbiff on/off
  190. function Setup {
  191.     GetConfig - || exit 1
  192.     typeset -i i=1
  193.     typeset var val equals shelltype=$1 mesgcmd sttycmd docmd=
  194.  
  195.     # Can't use aliases here due to aliasing bug
  196.     istrue nomodify && docmd="print -u2 debug: Would execute: "
  197.  
  198.     [ $shelltype = b ] && equals== || equals=' '
  199.  
  200.     ### TERM var
  201.     if [ "$askterm" = on ]; then
  202.     print -u2 -n "TERM = ($TERM) " 1>&2
  203.     read term
  204.     # If the user changes terminal type, don't set TERM
  205.     [ -n "$term" -a "$term" != "$TERM" ] && unset LINES
  206.     export TERM=${term:-$TERM}
  207.     fi
  208.     ### mesg y/n
  209.     case "$mesg" in
  210.     on)
  211.     $docmd /bin/mesg y;;
  212.     off)
  213.     $docmd /bin/mesg n;;
  214.     esac
  215.  
  216.     unset sttyopt[*]
  217.     ### stty intr, erase
  218.     [ -n "$interrupt" ] && set -A sttyopt -- intr "$interrupt"
  219.     [ -n "$erase" ] && set -A sttyopt -- "${sttyopt[@]}" erase "$erase"
  220.     [ ${#sttyopt[*]} -gt 0 ] && $docmd /bin/stty "${sttyopt[@]}"
  221.  
  222.     ### biff
  223.     $CanDoBiff && [ -n "$biff" ] && $docmd mbiff $biff > /dev/null
  224.  
  225.     ### PATH
  226.     if [ -n "$userpath" ]; then
  227.     if [ $shelltype = b ]; then
  228.         echo "PATH=$PATH:$userpath"
  229.         echo "export PATH"
  230.     else
  231.         # userpath is liable to have $HOME:other-stuff in it.
  232.         # If $PATH:$userpath is echoed for csh, $HOME::other-stuff
  233.         # will still be in it when csh sees it, and it will
  234.         # think that is a variable modification if : isn't escaped.
  235.         # So, let ksh expand userpath instead of leaving it up to csh.
  236.         eval echo setenv PATH $PATH:$userpath
  237.     fi
  238.     fi
  239.  
  240.     ### coredumpsize
  241.     if [ -n "$coredumpsize" ]; then
  242.     if [ $shelltype = b ]; then
  243.         # bash requires that -Sc be given as a single option (not -S -c)
  244.         echo "ulimit -Sc $((coredumpsize*2)) 2>/dev/null"
  245.     else
  246.         # tcsh brokenness; won't set coredumpsize all the way to hard limit
  247.         # Failure of 'limit' causes sourcing to end immediately, so must
  248.         # test in subshell first & then do it for real based on result.
  249.         print -r \
  250. "if ( { (limit coredumpsize $coredumpsize >& /dev/null) } ) then
  251.     limit coredumpsize $coredumpsize
  252. else
  253.     limit coredumpsize $((coredumpsize-1))
  254. endif"
  255.     fi
  256.     fi
  257.  
  258.     ### shellmail
  259.     # Since we don't know where mail is stored unless the MAIL var is set,
  260.     # about all we can do to turn shell mail notification on is set the "mail"
  261.     # shell variable to the same value as the MAIL env var for the sake of csh.
  262.     case "$shellmail" in
  263.     on)
  264.     if [ $shelltype = c ]; then
  265.         # If MAIL is set and mail isn't, set mail from MAIL
  266.         print \
  267. 'if ($?MAIL && ($?mail == 0)) then
  268.     set mail=$MAIL
  269. endif'
  270.     fi
  271.     ;;
  272.     off)
  273.     if [ $shelltype = b ]; then
  274.         echo 'unset MAIL MAILCHECK MAILPATH'
  275.     else
  276.         # Archaic versions of csh (e.g. SCO's prior to 3.2v5)
  277.         # did not have unsetenv, so redirect error output.
  278.         echo 'unset mail'
  279.         echo 'unsetenv MAIL >&/dev/null'
  280.     fi
  281.     ;;
  282.     esac
  283.  
  284.     ### Other env vars, and checking for non-setup options
  285.     while [ i -le $((NumPref)) ]; do
  286.     var=${Vars[i]}
  287.     eval val=\$${Vars[i]}
  288.     if [[ $var = *([A-Z]) ]]; then
  289.         if [ -n "$val" ]; then
  290.         EmitVar "$shelltype" "$var" "$val"
  291.         # Set VISUAL to the same value as EDITOR
  292.         [ "$var" = EDITOR ] && EmitVar "$shelltype" VISUAL "$val"
  293.         fi
  294.     else
  295.     [[ $var != ?(mesg|askterm|interrupt|erase|userpath|biff|forward|httpreport|coredumpsize|shellmail|hushlogin|versioning) ]] &&
  296.         print -u2 "Unknown config option: $var"
  297.     fi
  298.     let i+=1
  299.     done | /bin/sed "
  300.     /=/s/'/'\\\\''/g
  301.     /=/s/\$/'/
  302.     s/=/$equals'/"
  303.     # On variable assignment lines, enclose the values in single quotes,
  304.     # and replace ' in values with '\'' (close the single-quotes,
  305.     # add an escaped single quote, then reopen the single-quotes).
  306.     # For csh, also replace the = with a space.
  307.     exit 0
  308. }
  309.  
  310. # Usage: AssignVal var=value
  311. function AssignVal {
  312.     SetVal "${1%%=*}" "${1#*=}"
  313. }
  314.  
  315. typeset -i maxCoreH maxCoreS
  316.  
  317. # Usage: chkBins binary-name ...
  318. # Returns comma+space separated list of those that are found.
  319. function chkBins {
  320.     typeset bin
  321.  
  322.     for bin; do
  323.     type "$bin" > /dev/null && bins="$bins, $bin"
  324.     done
  325.     print "${bins#, }"
  326. }
  327.  
  328. # Initialize arrays used in ShowConfig(), Interactive()
  329. function InitArrs {
  330.     typeset editors pagers vitutors
  331.  
  332. # On systems that don't have extended ulimit, set these to 0
  333. [ maxCoreH -eq 0 ] && maxCoreH=$(ulimit -H -c 2>/dev/null || print 0)/2
  334. [ maxCoreS -eq 0 ] && maxCoreS=$(ulimit -S -c 2>/dev/null || print 0)/2
  335.  
  336. # Brief descriptions of configuration options
  337. # Used in ShowConfig() and Interactive()
  338. set -A Descrip \
  339. "" \
  340. "Writability/Talkability" \
  341. "Real Name" \
  342. "Default Terminal Type" \
  343. "Terminal Type Query" \
  344. "Terminal Rows" \
  345. "Default Pager" \
  346. "Default Editor" \
  347. "Interrupt Key" \
  348. "Erase Key" \
  349. "User Path" \
  350. "Mail Forwarding" \
  351. "Immediate Mail Alert" \
  352. "Shell Mail Alert" \
  353. "HTTP Report Levels" \
  354. "Maximum Core Dump Size" \
  355. "Quiet Login" \
  356. "File Versioning (Undelete)" \
  357. "Show File Versions" \
  358. "Timezone"
  359.  
  360. # Short descriptions (<= 16 characters), for users on small terminals
  361. # If empty, uses value from Descrip[]
  362. set -A ShortDescrip \
  363. "" \
  364. "Writability" \
  365. "" \
  366. "Default Termtype" \
  367. "Termtype Query" \
  368. "" \
  369. "" \
  370. "" \
  371. "" \
  372. "" \
  373. "" \
  374. "" \
  375. "Biff Mail Alert" \
  376. "" \
  377. "HTTP Rept Levels" \
  378. "Max Core Dump" \
  379. "" \
  380. "File Versioning" \
  381. "Show Versions" \
  382. ""
  383.  
  384. pagers=$(chkBins less more pg most)
  385. editors=$(chkBins vi emacs uemacs joe elmedit pico ee ted)
  386. vitutors=$(chkBins vilearn vitutor)
  387. [ -n "$vitutors" ] && vitutors=\
  388. " and preferably having run a vi teaching program ($vitutors)"
  389. type msgs > /dev/null && msgcmd=msgs || msgcmd=news
  390.  
  391.  
  392. # Possible values, used in Interactive()
  393. set -A Possib \
  394. "" \
  395. "on or off" \
  396. "Anything" \
  397. "ansi, vt100, tvi912, etc." \
  398. "on or off" \
  399. "A number (positive integer)" \
  400. "$pagers, etc." \
  401. "$editors, etc." \
  402. "^C for control-C, ^? for delete" \
  403. "^H for control-H, ^? for delete" \
  404. "Colon-separated list of directories" \
  405. "Email address (username@host.name)" \
  406. "on or off" \
  407. "on or off" \
  408. "Space-separated list from: standard, wide, html, allhits,
  409. and raw, with each word optionally preceded by monthly: or daily:" \
  410. "An integer between 0 and $maxCoreH, inclusive" \
  411. "on or off" \
  412. "on or off" \
  413. "1 or unset (use '-' to unset it)" \
  414. "AST, EST, CST, MST, PST, YST, HST, SST, or [STZ]offset[DTZ]"
  415.  
  416.  
  417. # Tests for valid values, used in CheckSetVal() (called only by Interactive())
  418. set -A Tests \
  419. '' \
  420. 'onoff "$val"' \
  421. '' \
  422. 'TERM="$val" tput lines' \
  423. 'onoff "$val"' \
  424. '[[ "$val" -gt 0 ]]' \
  425. 'type "$val"' \
  426. 'type "$val"' \
  427. '[[ "$val" = ^? ]]' \
  428. '[[ "$val" = ^? ]]' \
  429. 'CheckPath "$val"' \
  430. '[[ "$(/usr/mmdf/bin/checkaddr -w "$val")" != *"Bad address"* ]]' \
  431. 'onoff "$val"' \
  432. 'onoff "$val"' \
  433. '[[ "$val" = ?(monthly:|daily:)@(standard|wide|html|allhits|raw)*( *( )?(monthly:|daily:)@(standard|wide|html|allhits|raw)) ]]' \
  434. '[[ "$val" -ge 0 && "$val" -le maxCoreH ]]' \
  435. 'onoff "$val"' \
  436. 'onoff "$val"' \
  437. '[[ "$val" = 1 ]]' \
  438. '[[ "$1" = @(AST|EST|CST|MST|PST|YST|HST|SST|*([!-0-9+;,])?([0-2])[0-9]?(:[0-5][0-9]?(:[0-5][0-9]))?(+([!-0-9+;,])?(?([0-2])[0-9]?(:[0-5][0-9]?(:[0-5][0-9]))))?(,+([0-9])?(/?([0-2])[0-9]?(:[0-5][0-9]?(:[0-5][0-9]))))?(,+([0-9])?(/?([0-2])[0-9]?(:[0-5][0-9]?(:[0-5][0-9]))))) ]]'
  439.  
  440. # Warnings for invalid values.
  441. # Used in CheckSetVal() (called only by Interactive())
  442. set -A Warnings \
  443. "" \
  444. "value should be on or off" \
  445. "" \
  446. "invalid terminal type" \
  447. "value should be on or off" \
  448. "value must be a positive integer" \
  449. "no such program" \
  450. "no such program" \
  451. "not a control character" \
  452. "not a control character" \
  453. "path contains bad directories" \
  454. "invalid email address" \
  455. "value should be on or off" \
  456. "value should be on or off" \
  457. "unknown http log level(s)" \
  458. "value should be in the range 0..$maxCoreH" \
  459. "value should be on or off" \
  460. "value should be on or off" \
  461. "value should be 1 or unset (use '-' to unset it)" \
  462. "value must be a known timezone name or a valid timezone specification"
  463.  
  464. # Tests for whether options should be offered - NOT USED YET
  465. set -A OfferTests \
  466. "" \
  467. "[ -x /bin/mesg ]" \
  468. "" \
  469. "" \
  470. "" \
  471. "" \
  472. "" \
  473. "" \
  474. "" \
  475. "" \
  476. "" \
  477. "" \
  478. type mbiff \
  479. "" \
  480. [ -f /etc/default/httpreport ] \
  481. ulimit -c \
  482. "" \
  483. "" \
  484. "" \
  485. ""
  486.  
  487. # Verbose descriptions of configuration options, used in Interactive()
  488. set -A Verbose \
  489. "" \
  490. "Your writability determines whether other users can use the write and talk
  491. commands to communicate with you.  It can be turned on or off for the duration
  492. of a login session by issuing the command \"mesg y\" or \"mesg n\".  You are
  493. initially unwritable when you log in.  Turning on writability within $name
  494. causes you to always become writable immediately after logging in. You can
  495. still turn off writability for the rest of a login session with \"mesg n\". 
  496. Note: if someone sends you a write or talk message while you are logged in, it
  497. does not overwrite whatever you are doing, it just appears on your screen.  You
  498. can use the screen-redraw command of the editor or other application you were
  499. using to redraw the screen, or save your work, exit the application, and
  500. restart it." \
  501. "Your real name is set by the value of the NAME environment variable.  By
  502. default it is set to the value of your \"real name\" as given in the
  503. /etc/passwd file.  \$NAME is used whenever an application wants to know what
  504. your real name is.  The mail and news sending programs use it to tell the
  505. recipient who it was that sent a message, some games use it for the high score
  506. list, and various programs that let you interact with other users use it to
  507. tell them who you are.  Changing your real name within $name changes the value
  508. that \$NAME is set to when you log in.  However, changing this does *not*
  509. change the value stored in the /etc/passwd file.  The main effect of this is
  510. that changing this value does not affect what a remote user sees when using the
  511. \"finger\" protocol to find the real name associated with your login name (for
  512. this reason, the value stored in the /etc/passwd file is often known as the
  513. \"finger name\").  On this system, you cannot change your \"finger name\"." \
  514. "Your default terminal type is the type that you get if you hit return at the
  515. \"TERM = (termtype)\" prompt when you log in, or which you get if you turn off
  516. \"Termtype Query\".  If you leave \"Termtype Query\" on, you can specify a
  517. different terminal type than the default by typing its name before hitting
  518. return.  Your terminal type determines what escape sequences are sent by the
  519. system to do full-screen displays, as required by most of the editors, etc.  It
  520. should match the terminal type that you use, or the terminal type that you set
  521. your communications program to emulate.  vt100 is often a good choice, if you
  522. have that option.  You change your terminal type after logging in by changing
  523. the value of the TERM environment variable.  Read the help for the \"Termtype
  524. Query\" option to find out how to do that." \
  525. "By default, you are asked for a terminal type when you log in on a dialup
  526. (modem) line, or if you didn't have your terminal type set wherever you
  527. remotely logged in from.  If you select \"off\" for \"Terminal type query\",
  528. your terminal type will be set to the value you give for \"Default Terminal
  529. Type\" without you being asked.  You can still change your terminal type from
  530. your shell prompt at any time.  If \"newtermtype\" is the terminal type you
  531. wish to set, you would type one of the following.
  532. If your shell is sh, type:
  533.  
  534. TERM=newtermtype; export TERM
  535.  
  536. If your shell is ksh, bash, or zsh, type:
  537.  
  538. TERM=newtermtype
  539.  
  540. If your shell is csh or tcsh, type:
  541.  
  542. setenv TERM newtermtype" \
  543. "If your terminal emulator displays a number of rows (lines) that is not the
  544. normal number of rows for the terminal type you select (for example, if you
  545. use an emulator with a configurable number of rows), you can set the actual
  546. number here.  If you set \"Termtype Query\" to yes, the value you give for
  547. terminal rows will only take effect if you select your default termtype when
  548. you log in.  Note that the terminal rows setting will cause most, but not all,
  549. programs to use the number of rows you set.  A few ignore this option, and will
  550. try to use the number of rows that is the default for the terminal type you
  551. select.  If you need to change this value after you log in (for example, if you
  552. resize your terminal emulator window), you can do so by changing the value of
  553. the LINES environment variable, as follows.  Substitute the number of lines you
  554. have for \"n\":
  555. If your shell is sh, type: LINES=n; export LINES
  556. If your shell is ksh, bash, or zsh, type: LINES=n
  557. If your shell is csh or tcsh, type: setenv LINES n
  558. If you are using an xterm, scoterm, Sun console, or compatible terminal
  559. emulator, you can have LINES automatically set when you log in by using the
  560. \"resize\" program.  See the resize man page for details (do \"man resize\")." \
  561. "The pager is used to view text one screenfull at a time.  It is invoked by
  562. various utilities (mail, man, msgs, etc.) when it is neccessary to view more
  563. than one screenful of output.
  564. more is the default pager.  It is a simple pager that lets you view each screen
  565. by pressing the space bar.  pg is another simple pager.  It will let you go
  566. backwards in text by giving a page offset, and is less sensitive to terminal
  567. emulation problems because it always draws a full screen at at time.
  568. most is a pager whose main feature is the ability to view multiple files at
  569. once.  Since the pager that you set here is normally used to view only one
  570. file at a time, the only reason to select most is if you are familiar with it.
  571. less is the most capable pager.  It uses the \"vi\" cursor keys and command
  572. set to let you move around in text with ease.  You can use it without knowing
  573. vi, but to get the most out of it, you should read the \"less\" man page (do
  574. \"man less\").
  575. If you don't know which to pick, choose \"less\", since it's fairly easy to use
  576. and its extra capabilities are very useful if you learn about them.  Just
  577. remember that you have to type \"q\" to get out of less when you reach the
  578. end of a document (the man page tells how to change that behaviour)." \
  579. "The editor is used to edit text.  It is automatically run by some applications
  580. (like rn), and is entered by others (like mail) when requested.  The default is
  581. \"vi\".  It is very capable but non-intuitive.  You shouldn't attempt to use it
  582. without having a vi reference handy, or at least having read the man page (do
  583. \"man vi\")$vitutors.
  584. emacs is even more capable than vi, and similar caveats apply to it.  uemacs is
  585. \"micro-emacs\", a smaller, less capable editor mostly compatible with emacs,
  586. and faster to start up if the system is loaded.  joe is an editor with editing
  587. key bindings similar (but not exactly identical) to Word Perfect.  elmedit &
  588. pico are the editors used by default by the Elm & Pine mailers respectively. 
  589. ee & ted are other fairly easy to use but limited-capability editors.
  590. If you already know any of the above editors, you should set your editor to the
  591. one you know.  If you don't know any of them but do know Word Perfect, you will
  592. probably find joe easiest to use.  If you want to know an editor that will be
  593. available on all UNIX systems, you should choose (and learn) vi.  If you will
  594. need to do complex editing tasks, you should learn vi or emacs.  If you don't
  595. have any other reason to select one editor over another, pico is a good
  596. candidate since it is among the easiest to use and has good built-in help." \
  597. "The interrupt key is used to kill running programs.
  598. It is equivalent to control-C and control-break under DOS.
  599. The initial value is delete (the delete key), which is specified as ^?.
  600. The other common value on UNIX systems is control-C, specified as ^C.
  601. Other control keys may be specified as ^x, where x is the control key
  602. to use for the interrupt key.  Various other control keys have special
  603. meanings, so it is safest to use ^C or delete.  You can change your interrupt
  604. key from a shell prompt by typing:
  605. stty intr '^x'
  606. where x is the control key you want to use as your interrupt key." \
  607. "The erase key is used to delete the last character typed.  It causes the
  608. cursor to move back one space.  Depending on other settings, the character that
  609. was there may or may not be erased on the screen (actually, overwritten with a
  610. space), but in either case it is removed from the terminal input buffer.  The
  611. initial value is control-H, which is specified as ^H.  The other common value
  612. is delete (the delete key), which is specified as ^?.  Other control keys may
  613. be specified as ^x, where x is the control key to use for the erase key. 
  614. Various other control keys have special meanings, so it is safest to use ^H or
  615. delete.  If you use delete, make sure you don't set the interrupt key to be
  616. delete.  On a terminal, the backspace key (which sometimes has a left pointing
  617. arrow on it) most often sends control-H, and the DEL (delete) key almost always
  618. sends delete.  If the terminal has a cursor keypad, its left-arrow key usually
  619. sends an escape sequence rather than control-H or delete; if it does, it can't
  620. be used for erase.  If you use control + H for erase, set erase to ^H; if you
  621. use the delete key, set it to ^?; if you use the backspace key, you'll need to
  622. determine whether it sends control-H or delete; if you use your cursor keypad,
  623. you may have to change unless you are using a computer with communications
  624. software that lets you configure the key to send control-H or delete." \
  625. "Your path determines where the shell looks for a program to execute when you
  626. type its name.  The default path includes the directories that most of the
  627. system utilities reside in, and a directory under your home directory called
  628. \"bin\".  It does not contain your home directory.  If you want to be able to run
  629. utilities that will reside in your account, create the \"bin\" directory if it
  630. doesn't already exist (use the command: mkdir \$HOME/bin) and put them there. 
  631. The default path also does not contain the current directory; this prevents you
  632. from accidently running a possibly dangerous executable when you are in a
  633. publicly writable directory or a directory belonging to another user.  The user
  634. path, if any, is added to the end of the standard path.  To include your home
  635. directory in your path, use \"\$HOME\".  To include your current directory, use
  636. \".\".  Don't type in the quotes.  Another directory that some users may want in
  637. their path is /etc.  If you want more than one, separate them with colons,
  638. e.g.: \$HOME:/etc:." \
  639. "Mail forwarding allows you to have your email sent to an account on another
  640. system.  Before setting up mail forwarding, you should send test mail to the
  641. address you intend to forward to to make sure it works as you expect.  An
  642. incorrect forwarding address can cause you to lose all of your mail, or may
  643. set up a mail loop, causing an ever increasing number of error replies to
  644. circulate between accounts.
  645. The forwarding available through this option uses the .forward file, which is
  646. more limited in function that it is on some other systems.  Only true
  647. forwarding can be arranged, not pipe aliases.  A comma-separated list of
  648. addresses may be given.  To forward mail to another account and also keep it
  649. here, give your local account name and the remote address.  Do *not* put a
  650. backslash (\) in front of your account name; that is not neccessary here and
  651. will cause the forwarding to fail.
  652. To do more complex mail processing (for example, pipes), you can use a
  653. .maildelivery file.  Do \"man maildelivery\" to learn about its capabilities.
  654. Also, turning on immediate mail notification will create a prototype
  655. .maildelivery file." \
  656. "Turning immediate mail notification on causes a message to be sent to your
  657. terminal immediately when you receive new mail while logged on.  This can be
  658. distracting if you are using a full-screen application.  You can turn mail
  659. notification on and off interactively with the \"mbiff\" command.  If you set
  660. this option here, mail notification will be reset to the status you give each
  661. time you log in." \
  662. "If shell mail notification is on, your shell will periodically check for
  663. whether you have new mail just before it issues a shell prompt (it does this
  664. only if it has been 10 minutes since the last check).  If you do have new mail,
  665. it inform you before printing the prompt.  This is less intrusive than
  666. immediate notication, but it means that if you're running an application, you
  667. won't find out that you have new mail until you get back to a shell prompt." \
  668. "The HTTP report level determines what types of reports are mailed to you about
  669. accesses of your web pages.
  670. raw       Raw http access log data, with one line for each access.
  671. allhits   For each page accessed, gives time & remote hostname for each access.
  672. standard  Summary with one line for each file accessed, including access count.
  673. wide      This gives the standard report without lines being truncated,
  674.           as is done by default to make them fit an 80-column screen.
  675. html      Like the wide report, but HTML-formatted for viewing as a web page.
  676. Multiple report levels may be given; they should be separated from each other
  677. by spaces.  Also, any report level may be preceded by a periodicity
  678. specification, separated from the level by a colon (:).  The periodicities that
  679. may be specified are daily and monthly.  The levels so restricted will only
  680. be used at the given interval.  If any levels are selected by period, only
  681. levels selected by period will be used.  If no levels are selected by period,
  682. any levels that do not have a periodicity attached to them are used.  For
  683. example, if this list is given:   standard monthly:html
  684. then the monthly report will include only an html report, and the daily report
  685. will include only a standard report (since no daily:level is given)." \
  686. "NOTE: you need only read this and adjust this parameter if you are developing
  687. programs, or are curious about it.
  688. Under certain circumstances, when a process is killed due to an abnormal
  689. condition (e.g. the process attempted to access memory outside of its address
  690. space) the memory image of the process will be written to a file named \"core\"
  691. in its current working directory.  This is useful to users who are writing
  692. programs, because they can use a debugger to analyze the core file to determine
  693. what went wrong with the process.  In general, core dumps are not useful to
  694. users who are not developing programs.  Core dump files tend to be large,
  695. occupying about as much filesystem space as the process occupied memory.  A
  696. typical way for a process to fail is for it to occupy as much memory as it can
  697. and then die, which makes the problem worse.  To avoid this problem, it is
  698. possible to place a limit on the size of a core dump file.  By default, this is
  699. set to 0.  This means that a 0-size file named \"core\" will be created in the
  700. circumstances described above.  If you find these files, you can generally
  701. ignore them or remove them.  However, if you are writing programs and know how
  702. to use the debuggers, you will probably want to increase your coredump size
  703. limit to the maximum allowable." \
  704. "If \"quiet login\" is on, most of the login messages are suppressed.  The
  705. message of the day (login banner), report of new mail messages, and report of
  706. new system messages are not printed.  If you turn this on, be sure to check
  707. regularly for new system messages, using \"$msgcmd\"." \
  708. "Turning on file versioning enables the undelete capability for files within
  709. your home directory.  If file versioning is on and you remove a file or
  710. truncate it to zero length, the file is not actually removed from the
  711. filesystem.  Instead, it is renamed so that it is hidden from view.  This also
  712. happens when you overwrite a file, since that will remove or truncate the
  713. original file.  The file can be restored or removed \"for real\" with the
  714. undelete command.  Only a small number of old file versions are kept, so if you
  715. repeatedly remove/truncate the same file, eventually the earlier versions will
  716. \"fall off the end\" so that they cannot be restored.  Also, the filesystem is
  717. typically \"cleaned up\" at regular intervals by removing old saved versions of
  718. files.  The undelete capability is meant to rectify mistakes that are caught
  719. soon after they are made, not as a long-term backup scheme.  Versioned files
  720. occupy extra filesystem space.  Therefore, versioning is not automatically
  721. enabled for all users; it must be turned on here.  Turning it on here will turn
  722. file versioning on for your home directory and all directories underneath it. 
  723. If you want to have file versioning only on for certain directories, leave it
  724. off here and use undelete to turn it on for those directories with:
  725. undelete -s dirname
  726. You can turn it off again with: undelete -u directoryname
  727. For information on how to use undelete, do: man undelete" \
  728. "SHOWVERSIONS determines whether saved (undeletable) file versions are found
  729. when commands search through directories, as ls does when it lists files and
  730. the shells do when they expand wildcards.  For example, if you set SHOWVERSIONS
  731. to 1, * will expand to all files in the current directory, including saved
  732. versions of files, and ls will list them all.  If SHOWVERSIONS is unset, * will
  733. expand to only current versions of files, and only they will be listed by ls.
  734. Regardless of the setting of SHOWVERSIONS, saved versions can be acted on by
  735. explicitly naming a file with its version information.  For example,
  736. l \"foo;1\"
  737. will list saved version 1 of file foo, if it exists.  The quotes around the
  738. filename are neccessary because the ';' character is special to the shells.
  739. Also, the undelete command is not affected by SHOWVERSIONS; it can always show,
  740. remove, and perform other actions on saved file versions.  SHOWVERSIONS can be
  741. turned on and off during a login session by setting the SHOWVERSIONS
  742. environment variable to 1 to turn it on, and unsetting it to turn it off." \
  743. "Your timezone setting is used by utilities that print timestamps.  For
  744. example, when the \"l\" utility prints the dates for files, it prints them in
  745. the local time indicated by the timezone setting.  The usual form of timezone
  746. setting is \"STZnDTZ\", where STZ is the name of the timezone when daylight
  747. savings time is not in effect, n is the number of hours west of GMT (a negative
  748. number indicates hours east of GMT), and DTZ is the name for the timezone when
  749. daylight savings time is in effect.  If DTZ is not given, the locale is taken
  750. to not have daylight savings time.  Example: the timezone setting PST8PDT
  751. indicates that the timezone is named PST during standard time and PDT during
  752. daylight savings time, and is 8 hours west of GMT (7 hours during daylight
  753. savings time).  Timezone settings can be much more detailed than this; you can
  754. specify hours, minutes, and seconds from GMT individually for standard time and
  755. daylight savings time, specify the exact date and time that daylight savings
  756. time goes into effect and ends (by default, the rules for the United States are
  757. used), etc.  See the timezone(F) man page for complete details (do
  758. \"man F timezone\").  If one of the known time zone names is given by itself,
  759. it will be converted to a complete form."
  760. }
  761.  
  762. # Usage: ShowValue varname
  763. # Prints varname followed by its value.
  764. # Prints an error message and returns 0 if varname is invalid.
  765. function ShowValue {
  766.     typeset -i Ind
  767.     typeset val
  768.  
  769.     Ind "$1"
  770.     Index=$?
  771.     if isfalse Index; then
  772.     return 1
  773.     fi
  774.     eval val=\$${Vars[Index]}
  775.     print "$1: $val"
  776. }
  777.  
  778. function SetConfig {
  779.     typeset -i i=1
  780.     typeset Var fwd htfile hufile
  781.  
  782.     if > $PrefFile; then :; else
  783.     print -u2 "Failed to write configuration file $PrefFile."
  784.     exit 1
  785.     fi
  786.     while [ i -le NumPref ]; do
  787.     Var=${Vars[i]}
  788.     eval val=\$$Var
  789.     case $Var in
  790.     forward)
  791.         fwd=$HOME/.forward
  792.         if [ -n "$val" ]; then
  793.         echo "$val" > $fwd
  794.         # chgrp mmdf $fwd
  795.         # mail sent locally will run w/originator's uid all the way
  796.         # through delivery, so .forward has to be readable by all, not
  797.         # just mmdf.
  798.         chmod a+r $fwd
  799.         chmod a+x $HOME
  800.         elif [ -f $fwd ]; then
  801.         # Since 'forward' var is set from .forward when config is
  802.         # started, if it's gone now user either didn't
  803.         # have one or has explicitly removed it.
  804.         rm $fwd
  805.         fi
  806.         ;;
  807.     httpreport)
  808.         htfile=$HOME/.httpreport
  809.         if [ -n "$val" ]; then
  810.         # Put one level per line, for readability
  811.         > $htfile
  812.         for level in $val; do
  813.             echo "$level" >> $htfile
  814.         done
  815.         elif [ -f $htfile ]; then
  816.         # Since 'httpreport' var is set from .httpreport when config is
  817.         # started, if it's gone now user either didn't
  818.         # have one or has explicitly removed it.
  819.         rm $htfile
  820.         fi
  821.         ;;
  822.     versioning)
  823.         # note: the test for whether file versioning is current only or
  824.         # not is to check only the home dir.
  825.         case "$val" in
  826.         on)
  827.         if [ ! -u "$HOME" ]; then
  828.             print -ru2 -- \
  829.             "Turning on file versioning (this may take a while)."
  830.             undelete -rs -- "$HOME"
  831.             print -ru2 -- "Done turning on file versioning."
  832.         fi
  833.         ;;
  834.         off)
  835.         if [ -u "$HOME" ]; then
  836.             print -ru2 -- \
  837.             "Turning off file versioning (this may take a while)."
  838.             undelete -ru -- "$HOME"
  839.             print -ru2 -- "Done turning off file versioning."
  840.         fi
  841.         ;;
  842.         esac
  843.         ;;
  844.     hushlogin)
  845.         # hushlogin var is set to on or off when config is started.
  846.         # If value is still on or off, touch or remove file if neccessary.
  847.         # If any other value, leave it as is.
  848.         hufile=$HOME/.hushlogin
  849.         if [ "$val" = on ]; then
  850.         [ ! -e $hufile ] && > $hufile
  851.         elif [ "$val" = off -a -e $hufile ]; then
  852.         rm $hufile
  853.         fi
  854.         ;;
  855.     *)
  856.         if [ -n "$val" ]; then
  857.         echo "${Vars[i]}=$val"
  858.         fi
  859.         ;;
  860.     esac
  861.     let i+=1
  862.     done > $PrefFile
  863.     if istrue u; then
  864.     chown $p_uid $PrefFile
  865.     chgrp $p_gid $PrefFile
  866.     fi
  867. }
  868.  
  869. # Usage: ShowConfig
  870. function ShowConfig {
  871.     typeset -i i=1
  872.     typeset val
  873.  
  874.     # All routines that call ShowConfig() will not have done an InitArrs
  875.     # first, and will exit after, so do InitArrs here
  876.     InitArrs
  877.     while [ i -le NumPref ]; do
  878.     eval val=\$${Vars[i]}
  879.     if [ -n "$val" ]; then
  880.         print "${Descrip[i]}: $val"
  881.     fi
  882.     let i+=1
  883.     done
  884. }
  885.  
  886. function CheckPath {
  887.     typeset dir IFS=: 
  888.     typeset -i ret=0 CRet
  889.  
  890.     cd /usr/tmp        # Try to make all relative dirs except . and .. be bad.
  891.     for dir in $1
  892.     do
  893.     CRet=1
  894.     # expand vars
  895.     eval dir=$dir
  896.     if [ ! -a "$dir" ]; then
  897.         print -u3 "$dir: does not exist."
  898.     elif [ ! -d "$dir" ]; then
  899.         print -u3 "$dir: not a directory."
  900.     elif [ ! -x "$dir" ]; then
  901.         print -u3 "$dir: not executable."
  902.     elif [ ! -r "$dir" ]; then
  903.         print -u3 "$dir: not readable."
  904.     else
  905.         CRet=0
  906.     fi
  907.         istrue CRet && ret=1
  908.     done
  909.     return $ret
  910. }
  911.  
  912. function Interactive {
  913.     typeset -i i Map OptNum=1 helpLines maxDescLen=0 lenLimit termLines=0
  914.     typeset -i termCols=0
  915.     typeset Resp r val Menu line
  916.     typeset menuDescrip
  917.  
  918.     InitArrs
  919.     export TERM
  920.     # Set this first in case we're running config for another user,
  921.     # in which case TERM is liable to be changed.
  922.     istrue debug || clear=$(tput clear 2>/dev/null)
  923.     GetConfig || InitVars
  924.     if [ -n "$LINES" ]; then
  925.     termLines=$LINES
  926.     else
  927.     termLines=$(tput lines 2>/dev/null)
  928.     [ termLines -lt 1 ] && termLines=24
  929.     fi
  930.     if [ -n "$COLUMNS" ]; then
  931.     termCols=$COLUMNS
  932.     else
  933.     termCols=$(tput cols 2>/dev/null)
  934.     [ termCols -lt 1 ] && termCols=80
  935.     fi
  936.     PS3="Select an option by number: "
  937.     set -A menuDescrip -- "${Descrip[@]}"
  938.     # If one option per line won't fit on screen, make select double up by
  939.     # making lines shorter; also makes lines shorter if we don't have 80 cols
  940.     if [[ NumPref+5 -gt termLines || termCols -lt 60 ]]; then
  941.     i=1
  942.     while [ i -le NumPref ]; do
  943.         [ -n "${ShortDescrip[i]}" ] && menuDescrip[i]=${ShortDescrip[i]}
  944.         let i+=1
  945.     done
  946.     fi
  947.     i=1
  948.     while [ i -le NumPref ]; do
  949.     [ ${#menuDescrip[i]} -gt maxDescLen ] && maxDescLen=${#menuDescrip[i]}
  950.     let i+=1
  951.     done
  952.     menuDescrip[NumPref+1]="Save & quit"
  953.     menuDescrip[NumPref+2]="Abort (no update)"
  954.     # select requires that max line length be termCols/2-6 to print two columns
  955.     # D is used for description + dots
  956.     if [ NumPref+5 -gt termLines ]; then
  957.     lenLimit=termCols/2-6
  958.     typeset -L$((maxDescLen+1)) D
  959.     else
  960.     lenLimit=termCols-5
  961.     typeset -L$((maxDescLen+3)) D
  962.     fi
  963.     typeset -L$((lenLimit-1)) trunc
  964.     while :; do
  965.     print -n "$clear"
  966.     D="Option"
  967.     print "    $D Current Value"
  968.     D="------"
  969.     print "    $D -------------"
  970.     i=1
  971.     while [ i -le NumPref+2 ]; do
  972.         if [ "${NoOpt[i]}" -ne 1 ]; then
  973.         # Use D to build fixed-width description field
  974.         if [ i -le NumPref ]; then
  975.             D="${menuDescrip[i]} ...................."
  976.             line="$D ${Values[i]}"
  977.         else
  978.             line=${menuDescrip[i]}
  979.         fi
  980.         if [ ${#line} -gt lenLimit ]; then
  981.             trunc=$line
  982.             line="$trunc>"
  983.         fi
  984.         Menu[i]=$line
  985.         Map[OptNum]=i    # Map of menu number to option number
  986.         let OptNum+=1
  987.         fi
  988.         let i+=1
  989.     done
  990.     set -- "${Menu[@]}"
  991.     # Print menu for each iteration
  992.     select Resp; do break; done
  993.     case "$REPLY" in
  994.     $#)
  995.         exit 0;;
  996.     $(($#-1)))
  997.         break;;
  998.     esac
  999.     [ -z "$Resp" ] && continue
  1000.     i=REPLY
  1001.     r=
  1002.     OptNum=${Map[i]}
  1003.     var=${Vars[OptNum]}
  1004.     while [ -z "$r" ]; do
  1005.         print -n "
  1006. Current value of ${Descrip[OptNum]} ($var): ${Values[OptNum]}
  1007. Possible values: ${Possib[OptNum]}
  1008. Enter: a value to set this option to; 'h' for a description of this option;
  1009. '-' to remove this option from your configuration; or press return to retain
  1010. the current value: "
  1011.         read r
  1012.         case "$r" in
  1013.         "")
  1014.         break
  1015.         ;;
  1016.         h)
  1017.         print -r -- "
  1018. ${Verbose[OptNum]}"
  1019.         # Must use wc instead of set -- so that blank lines are counted
  1020.         print -r -- "${Verbose[OptNum]}" | wc -l | read helpLines
  1021.         if [ helpLines+6 -gt termLines ]; then
  1022.             print -rn -- "Press return to continue..."
  1023.             read
  1024.         fi
  1025.         r=
  1026.         ;;
  1027.         -)
  1028.         SetVal $var ""
  1029.         ;;
  1030.         *)
  1031.         CheckSetVal $OptNum "$r"
  1032.         ;;
  1033.         esac
  1034.     done
  1035.     done
  1036. }
  1037.  
  1038. function onoff {
  1039.     [[ "$1" = @(on|off) ]]
  1040. }
  1041.  
  1042. # Usage: CheckSetVal var-index val
  1043. function CheckSetVal {
  1044.     typeset val=$2 oval=$2 stty r2
  1045.  
  1046.     # Discard normal & error output, but save stderr as fd 3
  1047.     # for tests that really want to print
  1048.     istrue debug && print -u2 -- "Test for option $1: ${Tests[$1]}"
  1049.     if eval ${Tests[$1]} >/dev/null 3>&2 2>&1; then
  1050.     SetVal $var "$val"
  1051.     else
  1052.     if [[ "${Tests[$1]}" = onoff* ]]; then
  1053.         print -u2 "Error: ${Warnings[$1]}."
  1054.         r2=n
  1055.     else
  1056.         print -u2 "Warning: ${Warnings[$1]}."
  1057.         print -n "Really set $var to \"$oval\"? "
  1058.         read r2
  1059.     fi
  1060.     if [[ "$r2" = [yY]* ]]; then
  1061.         SetVal $var "$oval"
  1062.     else
  1063.         print -n \
  1064.         "Value of $var not changed.  Press return to continue. "
  1065.         read
  1066.     fi
  1067.     fi
  1068. }
  1069.  
  1070. # Set initial config values for a user who is running config for the first time
  1071. # Get NAME from /etc/passwd, mesg from mesg command, TERM, PAGER, and
  1072. # EDITOR/VISUAL from environment if set else defaults, interrupt and erase from
  1073. # stty, anything else (e.g. LINES) straight from environment with null default.
  1074. # userpath is left null, askterm is set to on.
  1075. function InitVars {
  1076.     if [ -z "$NAME" ]; then
  1077.     # get name from /etc/passwd
  1078. NAME=$(sed -n "/^$USER:[^:]*:[^:]*:[^:]*:/{s///;s/[:,].*//;p;}" /etc/passwd)
  1079.     export NAME
  1080.     fi
  1081.     askterm=on
  1082.  
  1083.     if istrue u; then
  1084.     # If running config for another user, don't set these.
  1085.     unset TERM PAGER EDITOR VISUAL mesg interrupt erase LINES \
  1086.     coredumpsize
  1087.     else
  1088.     set -- $(mesg)
  1089.     mesg=$2
  1090.     [ "$mesg" = n ] && mesg=off || mesg=on
  1091.  
  1092.     export TERM=${TERM:-vt100}
  1093.     export PAGER=${PAGER:-/usr/bin/more}
  1094.     export EDITOR=${VISUAL:-${EDITOR:-/usr/bin/vi}}
  1095.  
  1096.     # Relevant stty -a output line looks like this:
  1097.     # line = 0; intr = ^C; quit = ^\; erase = ^H; kill = ^U; eof = ^D;
  1098.     # eol = ^@; 
  1099.     stty=$(/bin/stty -a)
  1100.     stty=${stty##*intr = }
  1101.     interrupt=${stty%%;*}
  1102.     [ $interrupt = DEL ] && interrupt='^?'
  1103.     stty=${stty##*erase = }
  1104.     erase=${stty%%;*}
  1105.     [ $erase = DEL ] && erase='^?'
  1106.     [ maxCoreS -eq 0 ] && maxCoreS=$(ulimit -S -c 2>/dev/null || print 0)/2
  1107.     coredumpsize=$maxCoreS
  1108.     fi
  1109.     [ -f $HOME/.forward ] && forward="$(<$HOME/.forward)"
  1110.     [ -e $HOME/.hushlogin ] && hushlogin=on || hushlogin=off
  1111.     [ -u "$HOME" ] && versioning=on || versioning=off
  1112.     if [ -f $HOME/.httpreport ]; then
  1113.     # Put all lines on one line
  1114.     set -- $(<$HOME/.httpreport)
  1115.     httpreport="$*"
  1116.     fi
  1117.     # Since we do not have access to csh's internal 'mail' var, just use
  1118.     # these two.
  1119.     [ -n "$MAIL" -o -n "$MAILCHECK" ] && shellmail=on || shellmail=off
  1120.     # This uses $HOME
  1121.     $CanDoBiff && biff=$(mbiff status)
  1122.  
  1123.     for v in ${Vars[*]}; do
  1124.     SetVal $v
  1125.     done
  1126. }
  1127.  
  1128. function Initialize {
  1129.     InitVars
  1130.     SetConfig
  1131.  
  1132.     print "Your account configuration has been initialized as follows:"
  1133.     ShowConfig
  1134.     print \
  1135. "To change these values or read a description of the
  1136. configuration options, use \"$name\" without arguments."
  1137.     exit 0
  1138. }
  1139.  
  1140. function List {
  1141.     GetConfig - || exit 1
  1142.     ShowConfig
  1143.     exit 0
  1144. }
  1145.  
  1146. # @(#) getpwnam.ksh 1.0 94/03/05
  1147. # Usage: getpwnam <name> [<pre>]
  1148. # Reads the passwd file entry for account <name>
  1149. # Sets 7 global variables from fields in the passwd entry:
  1150. # <pre>name    Account name
  1151. # <pre>password    Password field
  1152. # <pre>uid    Login user ID
  1153. # <pre>gid    Login group ID
  1154. # <pre>gcos    GCOS (comment) field
  1155. # <pre>home    Home directory
  1156. # <pre>shell    Login shell
  1157. # Returns 0 on success, 1 on error.
  1158. # If <pre> is not given, pw_ is used.
  1159. # Example: getpwnam spcecdt PW_
  1160. # sets PW_name, PW_password, etc. with fields from spcecdt's passwd entry
  1161. function getpwnam {
  1162.     typeset IFS=: user=$1 p=$2
  1163.  
  1164.     [ $# -lt 1 ] && return 1
  1165.     [ $# -eq 1 ] && p=p_
  1166.  
  1167.     set -- $(grep "^$user:" /etc/passwd 2>/dev/null) || return 1
  1168.     eval $(print -r \
  1169. "${p}name=$1
  1170. ${p}password=$2
  1171. ${p}uid=$3
  1172. ${p}gid=$4
  1173. ${p}gcos=$5
  1174. ${p}home=$6
  1175. ${p}shell=$7" | set_vars)
  1176. }
  1177.  
  1178. ### Start of main program
  1179.  
  1180. name=${0##*/}
  1181. Usage="Usage: $name [-bcdhil] [-f filename] [option[=value]] ..."
  1182. PrefFile=$HOME/.config
  1183. typeset -i u=0 debug=0 nomodify=0
  1184.  
  1185. set -o noglob
  1186.  
  1187. while getopts :bcf:hilu:xdD opt; do
  1188.     case $opt in
  1189.     b|c)
  1190.     action="Setup $opt";;
  1191.     x)
  1192.     debug=1 nomodify=1;;
  1193.     d)
  1194.     nomodify=1;;
  1195.     D)
  1196.     Assignments="interrupt=^C erase=^?"
  1197.     ;;
  1198.     f)
  1199.     PrefFile=$OPTARG;;
  1200.     u)
  1201.     getpwnam "$OPTARG"
  1202.     PrefFile=$p_home/.config
  1203. #    if [ ! -f $PrefFile ]; then
  1204. #        print -u2 "WARNING: This user has no config file.
  1205. #    fi
  1206.     HOME=$p_home
  1207.     USER=$p_name
  1208.     NAME=$p_gcos
  1209.     u=1
  1210.     ;;
  1211.     h)
  1212.     echo \
  1213. "$name: Display or modify account configuration.
  1214. $Usage
  1215. If any option=value parameters are passed, the user's .config file is modified
  1216. with each option named set to the value given for it.  See a .config file for
  1217. the possible option names.
  1218. Options:"'
  1219. -b: Process config file & emit sh/ksh/bash initialization strings.  This is
  1220.     typically used in a .profile or /etc/profile like this: eval "`config -b`"
  1221. -c: Process config file & emit csh/tcsh initialization strings.  This is
  1222.     typically used in a .cshrc or /etc/cshrc like this (modern csh versions
  1223.     could use eval instead):
  1224.     set tmpfile="$HOME/#config.$$"
  1225.     config -c > $tmpfile
  1226.     source $tmpfile
  1227.     rm $tmpfile
  1228. -d: Debug configuration.  Use with -b or -c option to check configuration
  1229.     without modifying login session.  Actions that would modify login
  1230.     session are described without being taken.
  1231. -f<filename>: Read/write <filename> instead of $HOME/.config.
  1232. -h: Print this help.
  1233. -i: Initialize account configuration.
  1234. -l: List current account configuration.
  1235. -u<user>: Process configuration file for <user>.
  1236. -D: Make the erase character be the delete key.  This also sets the interrupt
  1237.     character to be control-C, since it is normally the delete key.  Equivalent
  1238.     to "config interrupt=^C erase=^?".'
  1239.        exit 0
  1240.        ;;
  1241.     l)
  1242.     action=List;;
  1243.     i)
  1244.     action=Initialize;;
  1245.     +?)
  1246.     print -u2 "$name: options should not be preceded by a '+'."
  1247.     exit 1
  1248.     ;;
  1249.     :) 
  1250.     print -r -u2 -- \
  1251.     "$name: Option '$OPTARG' requires a value.  Use -h for help."
  1252.     exit 1
  1253.     ;;
  1254.     ?) 
  1255.     print -u2 "$name: $OPTARG: bad option.  Use -h for help."
  1256.     exit 1
  1257.     ;;
  1258.     esac
  1259. done
  1260.  
  1261.  
  1262.  
  1263. # Configuration file variable names
  1264. # Begin with "" so that first varname will have index 1, etc.
  1265. set -A Vars "" mesg NAME TERM askterm LINES PAGER EDITOR interrupt erase \
  1266. userpath forward biff shellmail httpreport coredumpsize hushlogin versioning \
  1267. SHOWVERSIONS # TZ
  1268. typeset -i NumPref=$((${#Vars[*]}-1))
  1269.  
  1270. if type mbiff > /dev/null; then
  1271.     CanDoBiff=true
  1272. else
  1273.     CanDoBiff=false
  1274.     NoOpt[NumPref-1]=1
  1275. fi
  1276.  
  1277. type httplog > /dev/null || NoOpt[NumPref]=1
  1278.  
  1279. #InitArrs
  1280.  
  1281. # Execute action, if any
  1282. eval $action
  1283.  
  1284. # remove args that were options
  1285. let OPTIND=OPTIND-1
  1286. shift $OPTIND
  1287.  
  1288. [ -n "$Assignments" ] && set -- "$@" $Assignments
  1289.  
  1290. if [ $# -lt 1 ]; then
  1291.     Interactive
  1292. else
  1293.     GetConfig - || exit 1
  1294.     for arg; do
  1295.     if [[ "$arg" = *=* ]]; then
  1296.         AssignVal "$arg"
  1297.     else
  1298.         ShowValue "$arg"
  1299.     fi
  1300.     done
  1301. fi
  1302.  
  1303. SetConfig
  1304. print -u2 "Configuration changes will take effect next time you log in."
  1305.