home *** CD-ROM | disk | FTP | other *** search
/ Garbo / Garbo.cdr / pc / source / mush.lzh / mush.4 < prev    next >
Encoding:
Text File  |  1990-05-06  |  54.5 KB  |  1,613 lines

  1.  
  2. #! /bin/sh
  3. # This is a shell archive.  Remove anything before this line, then feed it
  4. # into a shell via "sh file" or similar.  To overwrite existing files,
  5. # type "sh file -c".
  6. # The tool that generated this appeared in the comp.sources.unix newsgroup;
  7. # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
  8. # If this archive is complete, you will see the following message at the end:
  9. #        "End of archive 4 (of 19)."
  10. # Contents:  mush/cmd_help mush/init.c
  11. # Wrapped by argv@turnpike on Wed May  2 13:59:21 1990
  12. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  13. if test -f 'mush/cmd_help' -a "${1}" != "-c" ; then 
  14.   echo shar: Will not clobber existing file \"'mush/cmd_help'\"
  15. else
  16. echo shar: Extracting \"'mush/cmd_help'\" \(39046 characters\)
  17. sed "s/^X//" >'mush/cmd_help' <<'END_OF_FILE'
  18. X/* @(#)cmd_help    1.4    10/24/88 (Dan heller) */
  19. X
  20. X%?%
  21. X      ? [command]
  22. X
  23. XThe `?' command will give you a list of legal commands.  Most
  24. Xcommands accept -? as an option.  This will give you specialized
  25. Xhelp with that particular command.
  26. X
  27. XIf the optional argument is given, help for that command is shown.
  28. X%%
  29. X
  30. X%ignore%
  31. X      ignore/unignore [headers]
  32. X
  33. XUse this command to set the message headers you would like not
  34. Xto be printed when you read a message. If no header specified,
  35. Xthen a list of all headers currently being ignored is printed.
  36. XYou must specify a header for unignore.
  37. X
  38. XYou can set the variable $alwaysignore to force normally
  39. Xignored headers to be ignored while saving messages, forwarding
  40. Xmessages or including messages into message buffers.
  41. X
  42. XSee also the variable $show_hdrs.
  43. X%%
  44. X
  45. X%set%
  46. X      set/unset [variable [= value]]
  47. X
  48. XWith no parameters, set lists all variables and their values.
  49. XTo set a boolean variable (on or off), use:
  50. X    set variable
  51. XTo set a variable's value to a string, use:
  52. X    set variable = value
  53. X
  54. XIf you want double-quotes or white-space embedded in a string,
  55. Xencase the string in single quotes.  If you want single quotes
  56. Xin a string, encase the string in double quotes.
  57. X
  58. XFor a list of all variables with special meanings, use:
  59. X    set ?all
  60. XFor help on a particular one of these variables, use:
  61. X    set ?variable_name
  62. X%%
  63. X
  64. X%readmsg%
  65. X      print [msg_list]
  66. X      type [msg_list]
  67. X      top [msg_list]
  68. X      next [msg_list]
  69. X      previous [msg_list]
  70. X
  71. XYou can read messages in different ways.  "type" and "print"
  72. Xwill print the current message.  "top" will only print the first
  73. XN lines of the current message where N is the value of the
  74. Xvariable "crt".  "next" will go to the next unread message and
  75. Xprint that.  "previous" will go back and read the first unread
  76. Xmessage previous to the current.  "^" will print the first
  77. Xmessage, "$" will print the last.
  78. X
  79. XAny of these commands can be followed by a message list, and
  80. Xeach message in that list will be printed (or piped to other
  81. Xcommands).
  82. X
  83. XSee also "help msg_list" and the variable $autoprint.
  84. X%%
  85. X
  86. X%alts%
  87. X      alts [hostnames]
  88. X
  89. XThe alts command sets a list of hostnames on which you have an
  90. Xaccount.  Normally, when you respond to all recipients of mail,
  91. Xyour account name will be listed as if you wished to send
  92. Xyourself mail.  If you don't have metoo set, then your name will
  93. Xbe removed from the mailing list if your login name is on the
  94. Xlist and the host specified is in the alternates list.  The
  95. Xspecial parameter `*' instructs alts to match all hostnames; in
  96. Xthat case, only the login name is tested.
  97. X%%
  98. X
  99. X%source%
  100. X      source/saveopts [file]
  101. X
  102. XThe source/saveopts commands will load/save all variable
  103. Xsettings, options, aliases, cmd's, ignored headers ...
  104. Xeverything you can set, it loads or saves.  The file read or
  105. Xwritten follows these rules:
  106. X
  107. X1) If a filename is given, that file is used
  108. X2) The file described by the environment variable MAILRC
  109. X3) In the user's home directory: .mushrc (if it exists)
  110. X4) In the user's home directory: .mailrc (if it exists)
  111. X
  112. XIf saveopts is used and the file exists, confirmation will be
  113. Xrequested before the file is overwritten.
  114. X%%
  115. X
  116. X%help%
  117. X      help [item]
  118. X
  119. XType "help" with no arguments for a list of valid items.
  120. X%%
  121. X
  122. X%general%
  123. XThis is the general help message.  To get help on a specific
  124. Xcommand, try "command -?".  Extended help is given by typing
  125. X"help item" where item is one of:
  126. X    path, msg_list, prompt, hdr_format
  127. XHelp with msg_list is highly advisable!
  128. X
  129. XType "?" to get a list of available commands.  Try "? command"
  130. Xto get help on the particular command that you specify.
  131. X
  132. XUse "set ?variable" to get help with specific variables.
  133. X%%
  134. X
  135. X%path%
  136. XWhenever "path" is specified, the following syntax is legal
  137. Xbesides the normal path addressing scheme used by unix:
  138. X ~[user]   -- the home directory of specified user (yours by default)
  139. X %[user]   --/usr/spool/mail/login_name [user_name] (yours by default)
  140. X +file     --the directory described by `set folder'; file is `file'
  141. X%%
  142. X
  143. X%msg_list%
  144. XA "msg_list" references one or more messages.  The user
  145. Xspecifies a group of messages according to a special syntax.
  146. X
  147. X *      All messages.
  148. X ^      The first message.
  149. X $      The last message.
  150. X .      The current message.
  151. X N-M    A range of messages between N and M, inclusive.
  152. X
  153. XIn the last case, N and M may be * ^ $ . or digits referencing
  154. Xexplicit message numbers.  The range must be in ascending order.
  155. X
  156. XYou can also negate messages by placing the message list inside
  157. Xbraces, `{' `}' -- thus, the expression "2-19 {11-14}"
  158. Xreferences messages 2 through 19 except for those from 11
  159. Xthrough 14.
  160. X
  161. XCommands can be "piped" to one another, because the return value
  162. Xof a command is a msg_list, not text.  For example,
  163. X    pick -f fred | lpr
  164. Xwill find all messages "from fred" and send them to the printer.
  165. X
  166. XCommands dealing with more than one message process them in
  167. Xnumeric order -- not necessarily the order specified.  Thus, the
  168. Xcommand "save 1-5 9 7 6 file" will save the messages in
  169. Xascending order, not in the order given.
  170. X%%
  171. X
  172. X%hdr_format%
  173. XThis variable controls the display of message headers.  Use:
  174. X    set hdr_format="string"
  175. Xto change the header display.  The string uses printf style
  176. Xformatting and follows these conventions:
  177. X    %a  address of the author
  178. X    %c  number of characters (bytes) in the message
  179. X    %d  entire date of the message (see "date_received" variable)
  180. X    %f  "From" field (author name and address)
  181. X    %i  the message-id (may or may not be present)
  182. X    %l  number of lines in the message
  183. X    %M  month name of the message
  184. X    %N  day of the month (number)
  185. X    %n  name of the author
  186. X    %s  subject of the message
  187. X    %t  "To" field (recipients)
  188. X    %T  time of the message (see "mil_time" variable)
  189. X    %W  day of the week (Sun, Mon, etc.)
  190. X    %Y  year of the message 
  191. X    %y  year (last 2 digits only)
  192. X    \n  a newline
  193. X    \t  a tab
  194. X
  195. XA field specifier may be used in any % expansion.  Thus, "%20s"
  196. Xwill print the first 20 characters of the Subject.  No matter
  197. Xwhat the formatting string, the message number, the status of
  198. Xthe message and a '>' (if this is the "current" message) is
  199. Xbefore any user defined format is printed.
  200. X%%
  201. X
  202. X%prompt%
  203. XThis variable controls the prompt that mush will display.
  204. X    set prompt = "string"
  205. XThe "string" follows printf style formatting conventions:
  206. X    %F  full path of the current working folder
  207. X    %f  name (path tail) of the current folder
  208. X    %m  current message number
  209. X    %n  number of new messages
  210. X    %u  number of unread messages
  211. X    %d  number of deleted messages
  212. X    %t  total number of messages
  213. X    %T  current time
  214. X    %N  day of the month (number) (today)
  215. X    %W  weekday name (today)
  216. X    %M  month name (this month)
  217. X    %Y  year (this year)
  218. X    %y  year (last 2 digits only)
  219. X    \n  newline
  220. X    \t  tab
  221. X%%
  222. X
  223. X%preserve%
  224. X      preserve [msg_list]
  225. X
  226. XThe "preserve" command marks messages to be saved in your system
  227. Xmailbox.  Unless explicitly preserved, all mail that you read
  228. Xwill be saved in ~/mbox (or the file specified by $mbox).  Deleted
  229. Xmessages are preserved only if also undeleted (see "delete -?").
  230. XWhen a message is preserved, the `P' status bit will appear in the
  231. Xheader summary display for that message.
  232. X
  233. XThe "unpreserve" command reverses the effect of "preserve".
  234. X
  235. XSetting the boolean variable $hold is equivalent to preserving
  236. Xeach message as you read it, except that no `P' status is set.
  237. X%%
  238. X
  239. X%save%
  240. X      save/write/copy [-s|-S|-a|-A] [-f] [msg_list] [filename]
  241. X
  242. XIf no filename is specified, ~/mbox (or the value of the
  243. Xvariable "mbox") is used.  Save and write will append msg if
  244. X`file' already exists.  Specifying -f will overwrite the
  245. Xfile (e.g., erasing it first).
  246. X
  247. XTo save messages to a filename beginning with a digit, escape
  248. Xthe filename with a backslash (\).
  249. X
  250. XThe "write" command will write message without the headers (msg
  251. Xbody only).  Save and write both mark messages for deletion
  252. Xunless $keepsave is set.  The "copy" command is identical to
  253. X"save" except that messages are not marked for deletion
  254. X(identical to having the variable "keepsave" set).
  255. X
  256. XThe -s and -S options save messages to files named by the
  257. Xsubject of the message.  If more than one message is specified,
  258. Xthen the message subject of each message is used.  If -S is
  259. Xspecified, then the subject of the first message is used for all
  260. Xmessages.  Spaces and forward slashes (/) are converted to
  261. Xunderscores (_).
  262. X
  263. XThe -a and -A options save messages by author's login name.
  264. X%%
  265. X
  266. X%lpr%
  267. X      lpr [-n] [-h] [msg_list]
  268. X
  269. XSend a message to the printer.  The options are:
  270. X  -n      print body of message only (no headers)
  271. X  -h      do not print ignored headers
  272. X  -Pxx    print on printer xx
  273. X
  274. XThe variable $printer can be used to specify a default printer;
  275. Xfor example, "set printer=lp" is the same as always using "-Plp".
  276. XThe variable $print_cmd can be used to specify a program other
  277. Xthan "lpr" to use for printing.
  278. X
  279. XSee also the variable $alwaysignore.
  280. X%%
  281. X
  282. X%mail%
  283. X      mail [mail-flags] [recipients]
  284. X
  285. XCompose and send a mail message.  The possible flags are:
  286. X  -b bcc-addrs    set blind-carbon-copy recipients
  287. X  -c cc-addrs     set carbon-copy recipients
  288. X  -e              immediately enter editor (autoedit)
  289. X  -E              edit outgoing headers
  290. X  -f [msg-list]   forward msg-list (not indented)
  291. X  -F              add fortune to the end of message
  292. X  -h file         read file as prepared draft (with headers)
  293. X  -H file         read file as prepared text (without headers)
  294. X  -i [msg-list]   include msg-list in letter
  295. X  -I [msg-list]   include msg-list with headers in letter
  296. X  -s [subject]    prompt for or set subject
  297. X  -u              do not append signatures and fortunes
  298. X  -U              send draft immediately (use with -h or -H)
  299. X  -v              verbose (not available on some systems)
  300. X
  301. XThe -f option will add new headers and automatically send the
  302. Xindicated messages to the list of recipients unless -E or -e
  303. Xis also given.  The -I and -i options will read the indicated
  304. Xmessages into the text of your letter, surrounded by the text
  305. Xof variables pre_indent_str, indent_str, and post_indent_str.
  306. X
  307. XThe -h option reads a draft file, which should already include
  308. Xmessage headers.  The -H option reads a text file, which should
  309. XNOT include headers.  If the -U option is also given, the draft
  310. Xis sent immediately.
  311. X
  312. XSee also the variables $ask, $askcc, $autoedit, $autoinclude,
  313. X$autosign, $autosign2, $dot, $edit_hdrs, $escape, $fortune,
  314. X$fortunates, $logfile, $record, $no_expand, $no_hdrs, $realname,
  315. X$sendmail, $verbose, $verify, and $wrapcolumn.
  316. X%%
  317. X
  318. X%respond%
  319. X      replysender/replyall [msg-list] [-r path] [mail-flags] [recipients]
  320. X
  321. XThe "replysender" command replies only to the sender of a
  322. Xmessage, whereas "replyall" responds to everyone on the To: and
  323. XCc: lines of the message.
  324. X
  325. XThe command "reply" is identical to "replysender".
  326. X
  327. XIf a message list is indicated, then each message on the list is
  328. Xreplied to in the same manner.  If -r is specified with a host or
  329. Xpath (uucp-style), then each address in the list is routed via
  330. Xthis path.  This overrides the value of auto_route (see man page).
  331. X
  332. XThe address of the author is obtained from certain headers in
  333. Xhis message to you.  Unless you specify otherwise, mush will
  334. Xsearch for the headers Reply-To: Return-Path: and From:.  You
  335. Xcan override these values by setting the variable reply_to_hdr.
  336. X
  337. X    set reply_to_hdr = "sender reply-to return-path from_"
  338. X
  339. XThis example shows that mush will search for (in order), the
  340. Xheaders listed in the reply_to_hdr variable.  If one header isn't
  341. Xfound, then mush looks for the next in the list.  If none of the
  342. Xheaders in the list are found, the default headers (mentioned
  343. Xabove) are searched.  The last header listed in the example is
  344. Xthe special "From " header.  See the man page for more details.
  345. X
  346. XType "mail -?" for information on legal mail flags.
  347. X
  348. XSee also the variables $auto_route, $domain_route, $in_reply_to,
  349. X$known_hosts, $metoo, $reply_to_hdr, and those listed by "mail -?".
  350. X%%
  351. X
  352. X%sort%
  353. X      sort [-i] [-r|a|d|l|R|s|S]
  354. X
  355. X  -i         ignore case in alphabetical sorts
  356. X  -r         reverse order of next criteria
  357. X
  358. X  -a         by author (alphabetical)
  359. X  -d         according to date
  360. X  -l         by length (size)
  361. X  -R         by subject including Re: (alphabetical)
  362. X  -s         by subject ignoring Re: (alphabetical)
  363. X  -S         by status
  364. X
  365. XAny combination of the options can be given.  Each comparison
  366. Xproceeds from left to right through the list of criteria,
  367. Xstopping when an ordering has been determined or no criteria
  368. Xremain.  The optional -r flag will reverse the order of the
  369. Xnext comparison specified.  Example:
  370. X
  371. X      sort -i -a -r -d
  372. X
  373. XThe above will sort by author first, ignoring case, and will
  374. Xsort by reverse date (most recent first) for each author.  The
  375. X-r option can be given once for each criterion and applies
  376. Xonly to the first criterion that follows it.  Giving -r twice
  377. Xin succession (-r -r) does NOT negate the reversal!  Whatever
  378. Xoption follows the rightmost -r will have its sense reversed.
  379. X
  380. XUnlike -r, the -i option is recognized at most once and applies
  381. Xto all alphabetical sorts in the list of criteria.
  382. X
  383. XBy default (no parameters), sort orders messages by status:
  384. XNew, unread messages are first, followed by preserved messages
  385. Xand finally the deleted messages are placed at the end.  If -r
  386. Xis the only flag given, the status order is reversed.
  387. X
  388. XIf the $date_received variable is set, sorting by date is
  389. Xdone using the date you received the message.  Otherwise,
  390. Xmessages are sorted by date sent by the original author.
  391. X
  392. XSee also the variable $sort.
  393. X%%
  394. X
  395. X%pick%
  396. X      pick [+<num>] [-<num>] [-r msg_list] [-x] [-i] [-h hdr] [-f|s|t]
  397. X    [-d [-][date]] [-ago [+|-] [n days] [n weeks] [n months]] [[-e] <pat>]
  398. X
  399. XSearch for patterns within messages.  Entire messages are
  400. Xsearched for <pattern> unless -f, -h, -s, or -t is specified.
  401. XOnly one of -d, -f, -h, -s, -t and -ago can be specified; no
  402. Xpattern is used with -d and -ago; and -x may not be used in
  403. Xconjunction with +<num> and/or -<num>.
  404. X
  405. X  +<num>        return only the first <num>ber messages matched
  406. X  -<num>        return only the last <num>ber messages matched
  407. X  -x            return all the messages which do NOT match
  408. X  -e        remaining arguments are the <pat> (`e'xpression)
  409. X  -f            match pattern in the "From:" field (author) only
  410. X  -s            match pattern in the "Subject:" header only
  411. X  -t            match pattern in the "To:" field only
  412. X  -h hdr        match pattern in specified header field only
  413. X  -i            ignore case of letters in when matching
  414. X  -r msg_list   restrict the range of messages search to msg_list
  415. X  -d            select messages sent on [+ after] [- before] date
  416. X        A "date" is of the form:  [+-][month]/[date[/year]]
  417. X        Omitted fields default to today's values.  Examples:
  418. X          pick -d 4/20     messages on Apr 20, this year
  419. X          pick -d -/2/85   on or before the 2nd, this month, 1985
  420. X          pick -d +5/4     on or after May 4, this year
  421. X          pick -d /        finds today's messages only
  422. X        At least one `/' char must be used in a date.  There is
  423. X    no strong date checking; 2/30 would be considered valid.
  424. X  -ago          select messages relative to the current date
  425. X    Date formats for "ago" are more verbose than for -d; see
  426. X    the manual page for details.
  427. X
  428. XExamples:
  429. X    Find the first 5 messages with the subject "Telephone Message":
  430. X    pick +5 -s Telephone Message
  431. X    Find the first 2 messages of the last 4 that are to "mush-users":
  432. X    pick -4 +2 -t mush-users
  433. X    Find those among messages 1 to 10 that are 2 months or more old:
  434. X    pick -r 1-10 -ago -2m
  435. X    Find messages that are 1 week old or newer:
  436. X    pick -ago +1w
  437. X    Find messages that contain "-request" in the Resent-From field:
  438. X    pick -h resent-from -e -request
  439. X
  440. XA description of the pick operation will be printed before the search
  441. Xis performed, unless the value of the variable $quiet contains the
  442. Xfield "pick", or pick is piped to another mush command.
  443. X%%
  444. X
  445. X%alias%
  446. X      alias [name [namelist]]
  447. X
  448. XOptions for alias:
  449. X alias                       print all namelists
  450. X alias name                  print namelist associated with name
  451. X alias name namelist         set "name" to the value of namelist
  452. X unalias namelist            unalias names in namelist
  453. X
  454. XA "namelist" consists of one or more addresses.  An address may
  455. Xbe a name already set to another list, a valid user, a file or
  456. Xa program.  Filenames must be full pathnames, i.e., they must
  457. Xbegin with a '/' (or with a ~, which expands to some home dir).
  458. XA "program" must start with a pipe symbol and be encased in
  459. Xquotes:
  460. X
  461. X    "|program_name"
  462. X
  463. XThe command "expand" will print addresses (including sublists)
  464. Xassociated with the given alias.
  465. X
  466. XSee also the variable $no_expand.
  467. X%%
  468. X
  469. X%from%
  470. X      from [+|-] [msg-list]
  471. X
  472. XWith no parameters, "from" will print the current message's
  473. Xheader line.  If given a message list, "from" will print the
  474. Xheaders of the listed messages.
  475. X
  476. XThe special parameters `-' and `+' can be given to move the
  477. Xcurrent message pointer to the previous or next message
  478. Xrespectively, while also printing that message's header.
  479. X
  480. XIf a message list was given in addition to `-' or `+', then
  481. Xthe current message pointer will be set to the first or last
  482. Xmessage, respectively, in the message list given.
  483. X
  484. XExamples:
  485. X
  486. X    from - 10-30 {16}
  487. Xwill print the headers of messages 10 through 30 except for
  488. Xmessage 16 and set the current message pointer to 10.
  489. X
  490. X    pick -f Dan | from +
  491. Xwill print the headers of all messages that contain "Dan" in the
  492. Xauthor's name and set the current message pointer to the last
  493. Xone of that kind in the list.
  494. X
  495. X    from +
  496. Xwill print the header of the message after the current message
  497. Xand increment the current message pointer to that message.
  498. X
  499. XSee also the "headers" command and "help hdr_format".
  500. X%%
  501. X
  502. X%my_hdr%
  503. X      my_hdr [header[: string]]
  504. X
  505. XThis command is used to set, unset or view your personalized
  506. Xmessage headers.  These headers are included in all your
  507. Xoutgoing mail.
  508. X
  509. XOptions for my_hdr:
  510. X  my_hdr            show all headers
  511. X  my_hdr header            show value of header
  512. X  my_hdr header: string        set header to string
  513. X  un_hdr header            unset header
  514. X
  515. XNote that there is no space between the header name and the
  516. Xcolon in the third form of the command.
  517. X%%
  518. X
  519. X%fkey%
  520. X      fkey [<sequence> [command]]
  521. X      unfkey <sequence>
  522. X
  523. XThis command is used to make function key settings in Suntools
  524. X(graphics) mode.  When run as a tool (-t on command line),
  525. Xchoose the Options item, and the "function key" menu option.
  526. X
  527. XThe unfkey command removes the setting for a given string.
  528. X%%
  529. X
  530. X%cmd%
  531. X      cmd [name [value]]
  532. X
  533. XThis function is used to establish command aliases; cmd's are
  534. Xjust like aliases in the C-shell.  Options are:
  535. X  cmd                       view all commands
  536. X  cmd command               show value of command
  537. X  cmd command value         set command to value
  538. X  uncmd command             unset command
  539. X
  540. XThe value must be quoted if it is to contain command separators
  541. Xsuch as `;' or `|'.
  542. X
  543. XIf you want to reference history commands within a cmd,
  544. Xescape the ! with a backslash.  For example:
  545. X
  546. X    cmd r 'replysender \!* ; delete -t'
  547. X
  548. Xwill cmd "r" to reply using whatever parameters you have given on
  549. Xthe command line and then delete that message and print the next
  550. Xmessage (-t parameter to "delete").
  551. X%%
  552. X
  553. X%headers%
  554. X      headers [+|-|N] [[-H]:c]
  555. X  +    print the next screenful (or use the 'z' command).
  556. X  -    print the previous screenful (or use 'z-' ).
  557. X  N    print a screenful starting at message number N.
  558. X  -H:c  where `c' is one of
  559. X     a  all messages (mostly for the mush startup option -H:c)
  560. X     d  deleted messages
  561. X     n  new messages
  562. X     o  old messages
  563. X     p  preserved messages
  564. X     r  replied-to messages
  565. X     s  saved messages
  566. X     u  unread messages
  567. X
  568. XThe "headers" command prints out a screenful of headers.
  569. XDeleted messages are not normally shown; set "show_deleted" to
  570. Xinclude deleted messages.
  571. X
  572. XThe command ":c" is equivalent to "headers -H:c".  The -H can be
  573. Xomitted, i.e., "headers :c" will also work.
  574. X
  575. XSee also "help hdr_format".
  576. X%%
  577. X
  578. X%folder%
  579. X      folder [-N] [-n] [-r] [%[user]|#|&|file]
  580. X
  581. X  -N       do not display the list of headers
  582. X  -n       do not update the current folder before changing
  583. X  -r       read only mode (cannot write changes to new folder)
  584. X  %[user]  change to /usr/spool/mail/[user] (you by default)
  585. X  #        change to folder accessed previous to current folder
  586. X  &        change to "mbox" -- default is $mbox or ~/mbox
  587. X
  588. XThe "folder" command changes the current folder; with no parameters,
  589. Xit prints the name of the current folder.  For compatibility with
  590. Xolder versions, the single character `!' is equivalent to -n.
  591. X
  592. X"Folder" treats the characters `+' and `~' as metacharacters when
  593. Xthey are the first character of a file name.  `~' is expanded to the
  594. Xname of the user's home directory, or to another user's home if it
  595. Xis given as "~username" (no `/' between the `~' and the name).  `+'
  596. Xis expanded to the user's folder directory ("~/Mail" or the value of
  597. X$folder); no `/' is required between `+' and the file name, so both
  598. X"+file" and "+/file" refer to the same file.
  599. X
  600. XThe "update" command updates the current folder.  In this case, only
  601. Xthe -N and -r options are recognized; "update -r" changes the current
  602. Xfolder to read only mode AFTER updating it.
  603. X
  604. XSee also the variable $folder.
  605. X%%
  606. X
  607. X%quit%
  608. X      quit/exit
  609. X
  610. XThese commands end a mush session.  "quit" will update your
  611. Xmailbox; if new mail has come in, you will be told so and given
  612. Xan option whether to really quit or not.  "exit" will leave mush
  613. Xneither updating your mailbox nor checking for new mail.
  614. X%%
  615. X
  616. X%ls%
  617. X      ls [options]
  618. X
  619. XThe "ls" command is exactly like the UNIX command "ls".  All
  620. Xparameters are the same.  The "folders" command is equivalent
  621. Xto doing "ls -FR $folder" from the Mush prompt.
  622. X%%
  623. X
  624. X%shell%
  625. X      sh [command]
  626. X
  627. XIf a "command" is given, that UNIX command will be executed
  628. Xunder the Bourne shell.  If no command is specified, then an
  629. Xinteractive shell will be started. The environment variable
  630. XSHELL or the local mail shell variable $shell describes the
  631. Xshell to invoke.  If none is set, then the default shell is
  632. Xdefined by the system administrator (currently set to csh).
  633. X
  634. XUsers on systems with job control will probably have little
  635. Xuse for the sh command.
  636. X%%
  637. X
  638. X%stop%
  639. X      stop
  640. X
  641. XThe stop command sends a stop signal to the mail shell.  It is
  642. Xequivalent to your tty job-control stop character (often ^Z).
  643. XSince the mush shell never needs to be exited, the command 'q'
  644. Xmay be "cmd"ed to "stop;await" and csh users may have
  645. X    alias mail %mush
  646. Xto bring mush into the foreground rather than having to invoke
  647. Xit again.  New mail will be read into the shell automatically
  648. Xand much time and energy is saved.
  649. X%%
  650. X
  651. X%curses%
  652. X      curses
  653. X
  654. XThe curses-based interface for Mush does not require a graphics
  655. Xdisplay, but does requires a terminal which can handle upline
  656. Xcursor movement capabilities.  All commands are one or two
  657. Xkeystroke commands and are executed as soon as the key is typed.
  658. X
  659. XFor a list of current key-to-command bindings, use the "bind"
  660. Xcommand (defaults to 'b' in curses mode).
  661. X
  662. XSee also the variable $curses_help.
  663. X%%
  664. X
  665. X%bind%
  666. X      bind [<sequence> <curses-command> [<parameters>]]
  667. X      unbind <sequence>
  668. X
  669. XBinding is done for the curses interface only.  It allows the
  670. Xuser to bind keystrokes or key sequences to curses-interface
  671. Xcommands.  You cannot bind keystrokes to regular mush commands
  672. Xusing bind.
  673. X
  674. XA bound key-sequence (input by the user) will be converted into
  675. Xthe curses command it is bound to.  For a list of all curses
  676. Xcommands, issue the "bind" command and follow the instructions
  677. Xto get a list.  Currently, parameters are ignored for all curses
  678. Xcommands except the special command "macro".
  679. X
  680. XWhen specifying sequences, you may enter almost anything at the
  681. Xkeyboard that you want to type.  This includes most control
  682. Xcharacters.  A special syntax is provided to specify control
  683. Xcharacters if you wish to set up default key bindings in your
  684. Xinitialization file without using real control characters.
  685. X
  686. XTo bind keystrokes that are control characters in the
  687. Xinitialization file, you must use the notation "\CX" where "X"
  688. Xis an upper-case letter representing the control key you want to
  689. Xuse. "\CN" would be control-N; "\n" is carriage return.  You may
  690. Xnot bind keyboard generated signals; for most users, those key
  691. Xsequences are control-C and control-\.  For users with job
  692. Xcontrol, the suspend characters (usually control-Z and
  693. Xcontrol-Y) are also ignored.
  694. X
  695. XTo specify the escape key, use "\E"; "\C[" will not work.
  696. X
  697. XTrying to bind a key sequence which prefixes another sequence is
  698. Xan error and the user is warned that the longer binding will not
  699. Xwork.  The binding will take place, however, because it is
  700. Xpossible to unbind the shorter sequence, thus validating the
  701. Xlonger sequence.
  702. X
  703. XThe special curses command "macro" allows a string to be
  704. Xexecuted just as if the user typed it directly.  Issue the
  705. X"bind-macro" command for more details.
  706. X
  707. XBindings are removed with the "unbind" command.
  708. X%%
  709. X
  710. X%msg_flags%
  711. X      flags [[+|-] [flag-bits]] [msg-list]
  712. X
  713. XAny sensible combination of these flag-bits may be used:
  714. X  D    deleted
  715. X  f    forwarded
  716. X  N    new
  717. X  O    old
  718. X  P    preserved
  719. X  p    printed
  720. X  R    read
  721. X  r    replied-to
  722. X  S    saved
  723. X  U    unread
  724. X
  725. XThis command displays the status of messages by default.
  726. XIf a msg-list is specified, it will tell which bits of the
  727. Xmessage are set.  If any (one or more) of the bits are
  728. Xgiven and no + or - modifier is specified, then the status
  729. Xof each message in the list will be set to that status
  730. Xabsolutely (other status flags are lost).  However, if a +
  731. Xor - is specified, then the status is modified for that bit
  732. Xto on (+) or off (-).
  733. X
  734. XIf no list is given, then the list of messages is taken
  735. Xfrom a pipe (if piped) or the current message is used.
  736. X%%
  737. X
  738. X%setenv%
  739. X      setenv VARIABLE [value]
  740. X
  741. XVariable names may be any string, but traditionally environment
  742. Xvariables are all upper case.  If no "value" is specified, then
  743. Xthe variable name will be set to an empty string.  If the value
  744. Xcontains spaces, you should enclose the string in quotation
  745. Xmarks.  Use printenv to print a list of all your environment
  746. Xvariables.
  747. X%%
  748. X
  749. X%unsetenv%
  750. X      unsetenv VARIABLE
  751. X
  752. XYou must specify one and only one variable to unset in your
  753. Xenvironment variable settings.  Use printenv to print a list of
  754. Xall your environment variables.
  755. X%%
  756. X
  757. X%printenv%
  758. X      printenv [VARIABLE]
  759. X
  760. XDisplay the entire current environment, or the value of the
  761. Xspecified environment variable.
  762. X
  763. XAlso see "setenv" and "unsetenv".
  764. X%%
  765. X
  766. X%edit_msg%
  767. X      edit [msg_list]
  768. X
  769. XThe "edit" command lets you edit messages in your folder.  The
  770. Xeditor used is determined by the variable $editor, the environment
  771. Xvariable EDITOR, the variable $visual and the environment variable
  772. XVISUAL in that order.  If none of those variables are set, the
  773. Xdefault visual editor will be used.  The "v" command is the same
  774. Xas "edit" but will test only $visual and VISUAL.
  775. X
  776. XWhen editing messages, be careful not to remove certain message
  777. Xheaders such as Date:, From:, or any others that look important.
  778. XIf you remove or change something you shouldn't have, you will
  779. Xbe notified and the temporary file used to edit the message will
  780. Xnot be removed.
  781. X%%
  782. X
  783. X%bind-macro%
  784. X      bind-macro [<sequence> [<expansion>]]
  785. X
  786. XThe "bind-macro" command allows you to set macros in curses
  787. Xmode, so that one keystroke (or a few) will act as though you
  788. Xhad typed a longer sequence.  Using "bind-macro" is equivalent
  789. Xto specifying the "macro" special command as a parameter to
  790. Xthe "bind" command.
  791. X
  792. XGiven no parameters, "bind-macro" will list all current curses
  793. Xmode macros.  Given only a <sequence>, it will show the current
  794. Xbinding for that sequence.  Given both a <sequence> and an
  795. X<expansion>, it will create a macro such that, when the
  796. X<sequence> is typed in curses mode, the effect will be the same
  797. Xas if the <expansion> had been typed instead.
  798. X
  799. XThe same format for control characters that is used for the
  800. X"bind" command may be used in both the <sequence> and the
  801. X<expansion>, i.e.,
  802. X    \Cx     control-x (where x is a capital letter)
  803. X    \E      the escape character (\C[ does NOT work!)
  804. X    \n      a newline (other C-style escapes also work)
  805. X
  806. XExample:
  807. X    bind-macro F [folder]+record\n
  808. X
  809. XIf you are in curses mode and hit the F key, then the curses
  810. Xmode command "folder" will execute and +record (followed by
  811. Xa carriage return) will be entered as if you typed it.
  812. X
  813. XMacros are removed with the "unbind" command, see "bind -?".
  814. X
  815. XAlso see the "map" and "map!" commands.
  816. X%%
  817. X
  818. X%map%
  819. X      map [<sequence> [<expansion>]]
  820. X      unmap <sequence>
  821. X
  822. XThe "map" command allows you to use one keystroke (or a few) and
  823. Xhave it act as though you had typed a longer sequence.
  824. X
  825. XGiven no parameters, "map" will list all current line mode
  826. Xmacros.  Given only a <sequence>, it will show the current
  827. Xbinding for that sequence.  Given both a <sequence> and an
  828. X<expansion>, it will create a macro such that, when the
  829. X<sequence> is typed in line mode, the effect will be the same
  830. Xas if the <expansion> had been typed instead.
  831. X
  832. XThe same format for control characters that is used for the
  833. X"bind" command may be used in both the <sequence> and the
  834. X<expansion>, i.e.,
  835. X    \Cx     control-x (where x is a capital letter)
  836. X    \E      the escape character (\C[ does NOT work!)
  837. X    \n      a newline (other C-style escapes also work)
  838. X
  839. XExample:
  840. X    map & print\n
  841. X
  842. XIf you are not in curses mode and hit the & key, then it will
  843. Xbe as if you typed the word "print" and hit carriage return.
  844. X
  845. XTo type a character without having the mapping expanded, precede
  846. Xthe character with a backslash (\).
  847. X
  848. XMappings are removed with the "unmap" command.
  849. X
  850. XAlso see the "map!" and "bind" commands.
  851. X%%
  852. X
  853. X%map!%
  854. X      map! [<sequence> [<expansion>]]
  855. X      unmap! <sequence>
  856. X
  857. XThe "map!" command allows you to set macros in message
  858. Xcomposition mode, so that one keystroke (or a few) will act
  859. Xas though you had typed a longer sequence.  map!'s take
  860. Xeffect regardless of whether you started the letter from
  861. Xcurses mode or line mode.
  862. X
  863. XGiven no parameters, "map!" will list all composition mode
  864. Xmacros.  Given only a <sequence>, it will show the current
  865. Xbinding for that sequence.  Given both a <sequence> and an
  866. X<expansion>, it will create a macro such that, when the
  867. X<sequence> is typed in message composition mode, the effect will
  868. Xbe the same as if the <expansion> had been typed instead.
  869. X
  870. XThe same format for control characters that is used for the
  871. X"bind" command may be used in both the <sequence> and the
  872. X<expansion>, i.e.,
  873. X    \Cx     control-x (where x is a capital letter)
  874. X    \E      the escape character (\C[ does NOT work!)
  875. X    \n      a newline (other C-style escapes also work)
  876. X
  877. XExample:
  878. X    map! ! <BANG>
  879. X
  880. XIf you are typing in a letter regardless of which interface you
  881. Xuse and you hit the ! key, then it would be as if you typed the
  882. Xkeys "<BANG>".
  883. X
  884. XTo type a character without having the mapping expanded, precede
  885. Xthe character with a backslash (\).
  886. X
  887. XMappings are removed with the "unmap!" command.
  888. X
  889. XAlso see the "bind" and "map" commands.
  890. X%%
  891. X
  892. X%eval%
  893. X      eval [-h|-p] args ...
  894. X
  895. XThis command causes its arguments to be re-parsed and then
  896. Xexecuted as a mush command.  Example:
  897. X
  898. X    set initprompt='"$hostname:$cwd "'
  899. X    eval set prompt=$initprompt
  900. X
  901. XIf the -h flag is given, then eval looks for formatting parameters
  902. Xas defined for the variable $hdr_format, and expands the formats
  903. Xfor the "current" message before executing the command.  Example:
  904. X
  905. X    eval -h pick -f %f
  906. X
  907. Xwill find all messages from the same author as the current message.
  908. X
  909. XIf the -p flag is given, then eval expands formatting parameters as
  910. Xas defined for the variable $prompt.  The -h and -p flags may not be
  911. Xused together in the same eval.
  912. X%%
  913. X
  914. X%pipe_msg%
  915. X      pipe [-p pattern] [msg-list] [unix-command] [cmd-args]
  916. X
  917. XThis command is used to send a message to a unix command.  The
  918. Xcommand will take its input from the message(s) passed to the pipe
  919. Xcommand.  By default, the entire message (including headers) is
  920. Xsent.  Ignored headers (see "ignore -?" and "set ?show_hdrs") can
  921. Xbe suppressed by setting the variable $alwaysignore.
  922. X
  923. XYou can pipe (|) messages to this command rather than give a
  924. Xmsg-list, but if no msg-list is given and there is no pipe, the
  925. Xcurrent message is used.  The unix-command is executed via "sh",
  926. Xso csh aliases may not be used.
  927. X
  928. XIf invoked with a capital letter (Pipe), only the bodies of the
  929. Xmessages will be fed to the unix-command -- all headers will be
  930. Xomitted.
  931. X
  932. XA pattern can be specified to indicate which line should start
  933. Xthe lines that are sent to the unix command.  The pattern must
  934. Xmatch literally (no regular-expressions) at the beginning of a
  935. Xline.  Once the pattern is found, that line and all succeeding
  936. Xlines are sent to the unix command.
  937. X
  938. XIf the unix-command is omitted, then /bin/sh is used and the 
  939. Xpattern searched for is "#!".  Therefore, "pipe" with no arguments
  940. Xcan be used to treat a message as a shell script.
  941. X
  942. XExamples:
  943. X    pipe patch         -- send the current message to "patch"
  944. X    pipe -p %! lpr     -- send the message to a postscript printer
  945. X    pipe 2 7 more      -- send messages 2 and 7 through "more"
  946. X    1 | Pipe nroff     -- send the body of message 1 to "nroff"
  947. X%%
  948. X
  949. X%merge%
  950. X      merge [-N] folder-name
  951. X
  952. XThe contents of the specified folder are read into the current
  953. Xfolder.  If -N is not specified, a header summary is printed
  954. Xfor each message read (see "headers -?").
  955. X
  956. XA list of all the merged messages is returned for use in pipes.
  957. X%%
  958. X
  959. X%echo%
  960. X    echo [-n] [-h | -p] args
  961. X
  962. XEcho simply echoes the parameters to the command back to the user.
  963. X
  964. XIf the -n flag is given, then no newline is appended.
  965. XIf the -h flag is given, then echo looks for formatting parameters
  966. Xas if the "from" command were given on the "current" message.
  967. XIf the -p flag is given, then echo looks for formatting parameters
  968. Xas if your prompt were changed temporarily.
  969. X
  970. XExamples:
  971. X    echo -h This message is from %a and is dated %d
  972. Xmight produce:
  973. X    This message is from island!argv and is dated Dec 14, 1988.
  974. X
  975. X    echo -p There are %n new messages to read in %f.
  976. Xmight produce:
  977. X    There are 5 new messages to read in /usr/spool/mail/argv.
  978. X
  979. XNote that -h and -p cannot be specified together.
  980. X%%
  981. X
  982. X%undigest%
  983. X    undigest [-m] [-p pattern] [msg_list] [filename]
  984. X
  985. XA "digest" is a mail message which is a collection of other mail messages
  986. Xmailed to a "moderator" by other users.  The moderator compiles all the
  987. Xmessages into a folder and sends the result to all the subscribers of the
  988. Xmailing list.  The undigest command disassembles the entries into the set
  989. Xof messages which comprises the digest.
  990. X
  991. XThe -m option will merge these messages into the current folder.  Otherwise,
  992. Xif a filename is specified, a new folder is created and the user can change
  993. Xfolders to read the messages separately.
  994. X
  995. XThe -p option specifies an alternate pattern to use as the digest article
  996. Xseparator.  The pattern must match literally at the beginning of a line.
  997. XThe default pattern is "--------" (eight hyphens).
  998. X
  999. XIf a message list is specified, each digest is disassembled to the same
  1000. Xfilename (if given).  If no filename is given and the user did not request
  1001. Xa merge, then a folder is created based on the subject of the digest.
  1002. X%%
  1003. X
  1004. X%await%
  1005. X    await [-T delay]
  1006. X
  1007. XInstructs the shell to wait for new mail to arrive.  New mail is checked
  1008. Xevery 30 seconds by default; a different delay can be specified by using
  1009. Xthe -T option.
  1010. X
  1011. XIf this command is used in a pipe, its output is its input plus the list
  1012. Xof new messages that have arrived.  For example, to show the headers of
  1013. Xall new messages, and set the current message to the first new message:
  1014. X
  1015. X    await | from -
  1016. X
  1017. XThe await command terminates only when new mail arrives or a keyboard
  1018. Xinterrupt is generated.
  1019. X%%
  1020. X
  1021. X%cd%
  1022. X      cd [directory]
  1023. X
  1024. XChange the current working directory to the specified directory,
  1025. Xor to the user's home directory if none was given.
  1026. X
  1027. XIf the variable $cdpath is set to a list of directory names,
  1028. Xand the argument directory is not an absolute path, mush will
  1029. Xsearch the cdpath directories in the order given for the new
  1030. Xdirectory and change to the first one found.  NOTE:  The current
  1031. Xdirectory "." MUST BE INCLUDED in the cdpath or it will not be
  1032. Xsearched!  This differs from csh, which prefers "." be left out.
  1033. X%%
  1034. X
  1035. X%pwd%
  1036. X      pwd
  1037. X
  1038. XPrints the current working directory.  The variable $cwd also
  1039. Xholds the current working directory unless reset by the user.
  1040. X%%
  1041. X
  1042. X%delete%
  1043. X      delete/undelete [msg-list]
  1044. X
  1045. XThe "delete" command marks the listed messages as deleted.  If
  1046. Xno message list is given, the current message is deleted.
  1047. X
  1048. XDeleted messages are not shown in the header summary display
  1049. Xexcept in curses mode and when the variable $show_deleted is set.
  1050. XDeleted messages are ignored by the "pipe" command and by the
  1051. Xcommands that display messages (see "print -?"), but most other
  1052. Xcommands include all messages whether deleted or not.
  1053. X
  1054. XDeleted messages are lost forever when the folder is updated (by
  1055. Xthe "update" command, by changing folders without the "!" flag,
  1056. Xor by exiting with "quit").  Messages can be recovered by the
  1057. X"undelete" command at any time BEFORE the folder is updated.
  1058. X
  1059. XSee also the variable $show_deleted.
  1060. X%%
  1061. X
  1062. X%history%
  1063. X      history [-h] [-r] [number]
  1064. X
  1065. XDisplay the command history that mush has recorded, as in csh.
  1066. XOption -h suppresses the history numbers, and option -r shows
  1067. Xthe history in reverse order (most recent first).  If a number
  1068. Xis given, that many commands of history are displayed.
  1069. X
  1070. XThe number of commands that mush records is controlled by the
  1071. Xvariable $history.  If $history is not set, mush will save only
  1072. Xthe previous command (equivalent to history=1).
  1073. X
  1074. XThe basic forms of history reference are (N is a number and
  1075. Xstr is any string):
  1076. X
  1077. X  !str      most recent command beginning with str
  1078. X  !?str?    most recent command containing str
  1079. X  !N        command N from the history list
  1080. X  !-N       command N previous to the current one
  1081. X  !!        previous command (same as !-1)
  1082. X  !$        last word of previous command
  1083. X  !*        all arguments of previous command
  1084. X
  1085. XModifiers (H can be str, ?str?, N or -N, n is a number or $):
  1086. X
  1087. X  !H:$      last word of referenced command
  1088. X  !H:n      n'th word of referenced command
  1089. X  !H:n-m    n'th through m'th words of command
  1090. X  !H:-n     word 0 (command name) through n of command
  1091. X  !H:*      all arguments of command (same as !H:1-$)
  1092. X  !H:n-     word n through next-to-last word
  1093. X  !H:p      print but don't execute command
  1094. X
  1095. X  !{R}str   append str to reference R (R is any form above)
  1096. X
  1097. XIt is not currently possible to combine :p with any of the
  1098. Xother modifiers.
  1099. X
  1100. XAlso see the variable $nonobang.
  1101. X%%
  1102. X
  1103. X%folders%
  1104. X      folders
  1105. X
  1106. XList the files in the directory described by the variable $folder.
  1107. XThese files are assumed to be folders of mail messages that can
  1108. Xbe read in by the "folder" command (see "folder -?").
  1109. X
  1110. XAlso see the "ls" command.
  1111. X%%
  1112. X
  1113. X%stty%
  1114. X      stty [options]
  1115. X
  1116. XThe "stty" command is equivalent to the UNIX command "stty".  All
  1117. Xoptions are the same.  Some settings will be temporarily changed
  1118. Xwhile mush is running, but will be restored when mush exits.
  1119. X%%
  1120. END_OF_FILE
  1121. if test 39046 -ne `wc -c <'mush/cmd_help'`; then
  1122.     echo shar: \"'mush/cmd_help'\" unpacked with wrong size!
  1123. fi
  1124. # end of 'mush/cmd_help'
  1125. fi
  1126. if test -f 'mush/init.c' -a "${1}" != "-c" ; then 
  1127.   echo shar: Will not clobber existing file \"'mush/init.c'\"
  1128. else
  1129. echo shar: Extracting \"'mush/init.c'\" \(13422 characters\)
  1130. sed "s/^X//" >'mush/init.c' <<'END_OF_FILE'
  1131. X/* init.c    (c) copyright 1986 (Dan Heller) */
  1132. X
  1133. X/* init.c -- functions and whatnot that initialize everything */
  1134. X#include "mush.h"
  1135. X#include <pwd.h>
  1136. X
  1137. X#ifdef BSD
  1138. X#include <netdb.h>
  1139. X#endif /* BSD */
  1140. X
  1141. X#ifdef SYSV
  1142. X#include <sys/utsname.h>
  1143. X#endif /* SYSV */
  1144. X
  1145. Xvoid
  1146. Xinit()
  1147. X{
  1148. X    char         *home, *realname, *argv[4];
  1149. X    extern char        *getlogin();
  1150. X    char        buf[MAXPATHLEN];
  1151. X#ifdef SYSV
  1152. X    extern struct passwd *getpwuid();  /* sys-v forgot this in pwd.h! */
  1153. X    struct utsname ourhost;
  1154. X#else
  1155. X    char ourhost[128];
  1156. X#endif /* SYSV */
  1157. X    register char     *p;
  1158. X    struct passwd     *entry;
  1159. X    int            cnt;
  1160. X#ifdef BSD
  1161. X    struct hostent     *hp;
  1162. X#endif /* BSD */
  1163. X
  1164. X    home = getenv("HOME");
  1165. X    if (realname = getenv("NAME")) {
  1166. X    (void) strcpy(buf, realname);
  1167. X    }
  1168. X    argv[1] = "=";
  1169. X    argv[3] = NULL;
  1170. X
  1171. X    if (!(entry = getpwuid(getuid())))
  1172. X    if (p = getlogin())
  1173. X        strdup(login, p);
  1174. X    else {
  1175. X        login = "unknown";
  1176. X        print("I don't know you, but that's ok.\n");
  1177. X    }
  1178. X    else {
  1179. X    strdup(login, entry->pw_name);
  1180. X    if (!home || !*home)
  1181. X        home = entry->pw_dir;
  1182. X    if (!realname && (realname = entry->pw_gecos)) {
  1183. X        if (p = index(realname, ','))
  1184. X        *p = 0;
  1185. X        for (p = buf; *realname; realname++)
  1186. X        if (*realname == '&')
  1187. X            *p++ = upper(*login), p += Strcpy(p, login+1);
  1188. X        else
  1189. X            *p++ = *realname;
  1190. X        *p = 0;
  1191. X    }
  1192. X    endpwent();
  1193. X    }
  1194. X    if (!home || !*home || Access(home, W_OK)) {
  1195. X    if (home && *home)
  1196. X        error(home);
  1197. X    else
  1198. X        print("No home!? ");
  1199. X    print_more("Using \"%s\" as home.\n", ALTERNATE_HOME);
  1200. X    } else {
  1201. X    argv[0] = "home";
  1202. X    argv[2] = home;
  1203. X    (void) add_option(&set_options, argv);
  1204. X    }
  1205. X    if (realname) {
  1206. X    /* realname has already been copied to buf */
  1207. X    argv[0] = "realname";
  1208. X    argv[2] = buf;
  1209. X    (void) add_option(&set_options, argv);
  1210. X    }
  1211. X    crt = 24;
  1212. X    screen = 18;
  1213. X    wrapcolumn = 0; /* Default is no wrap */
  1214. X    escape = DEF_ESCAPE;
  1215. X    prompt = DEF_PROMPT;
  1216. X
  1217. X#ifdef BSD
  1218. X    (void) gethostname(ourhost, sizeof ourhost);
  1219. X    if (!(hp = gethostbyname(ourhost))) {
  1220. X    error("gethostbyname: %s", ourhost);
  1221. X    if (ourname = (char **)calloc((unsigned)2, sizeof (char *)))
  1222. X        strdup(ourname[0], ourhost);
  1223. X    } else {
  1224. X    int n = 0;
  1225. X    cnt = 2; /* 1 for ourhost and 1 for NULL terminator */
  1226. X    for (p = hp->h_name; p && *p; p = hp->h_aliases[n++])
  1227. X        if (strcmp(ourhost, p)) /* if host name is different */
  1228. X        cnt++;
  1229. X    if (ourname = (char **)calloc((unsigned)cnt, sizeof (char *))) {
  1230. X        ourname[--cnt] = NULL;
  1231. X        for (p = hp->h_name; p && *p && n >= 0; p = hp->h_aliases[--n])
  1232. X        if (strcmp(ourhost, p)) /* if host name is different */
  1233. X            ourname[--cnt] = savestr(p);
  1234. X        strdup(ourname[0], ourhost); /* cnt better be 0! */
  1235. X    }
  1236. X    }
  1237. X#endif /* BSD */
  1238. X#ifdef SYSV
  1239. X    if (ourname = (char **)calloc((unsigned)2, sizeof (char *))) {
  1240. X    if ((uname (&ourhost) >= 0) && (*ourhost.nodename))
  1241. X        ourname[0] = savestr(ourhost.nodename);
  1242. X    else {
  1243. X        /* Try to use uuname -l to get host's name if uname didn't work */
  1244. X        char buff[50];
  1245. X        char *p;
  1246. X        FILE *F;
  1247. X
  1248. X        if (F = popen("exec uuname -l", "r")) {
  1249. X        if ((fgets(buff, sizeof buff, F) == buff) &&
  1250. X            (p = strchr(buff, '\n'))) {
  1251. X            *p = '\0';        /* eliminate newline */
  1252. X            ourname[0] = savestr (buff);
  1253. X        }
  1254. X        (void)pclose(F);
  1255. X        }
  1256. X    }
  1257. X    }
  1258. X#endif /* SYSV */
  1259. X    if (ourname && ourname[0]) {
  1260. X    for (p = buf, cnt = 0; ourname[cnt]; cnt++) {
  1261. X        if (cnt)
  1262. X        *p++ = ' ';
  1263. X        p += Strcpy(p, ourname[cnt]);
  1264. X    }
  1265. X    argv[0] = "hostname";
  1266. X    argv[2] = buf;
  1267. X    (void) add_option(&set_options, argv);
  1268. X    }
  1269. X
  1270. X    init_bindings();
  1271. X}
  1272. X
  1273. X/*
  1274. X * Source a file, or just the default file.  Since sourcing files
  1275. X * means reading possible aliases, don't expand the ! as history
  1276. X * by setting the IGN_BANG flag.  Since a command in the sourced file
  1277. X * may call source on another file, this routine may be called from
  1278. X * within itself.  Continue to ignore ! chars by setting save_bang (local).
  1279. X *
  1280. X * Try opening the file passed to us.  If not given, check for the correct
  1281. X * .rc file which is found in the user's home dir.
  1282. X *
  1283. X * return -1 for filesystem errors, -2 for attempting to read a directory.
  1284. X */
  1285. Xsource(argc, argv)
  1286. Xchar **argv;
  1287. X{
  1288. X    register char *p;
  1289. X    FILE      *fp;
  1290. X    char       file[MAXPATHLEN];
  1291. X    u_long      save_bang = ison(glob_flags, IGN_BANG);
  1292. X    int          line_no = 0;
  1293. X
  1294. X    if (argc && *++argv && !strcmp(*argv, "-?"))
  1295. X    return help(0, "source", cmd_help);
  1296. X    if (argc && *argv)
  1297. X    (void) strcpy(file, *argv);
  1298. X    else if ((p = getenv("MUSHRC")) && *p || (p = getenv("MAILRC")) && *p)
  1299. X    (void) strcpy(file, p);
  1300. X    else {
  1301. X    char *home = do_set(set_options, "home");
  1302. X    if (!home || !*home)
  1303. X        home = ALTERNATE_HOME;
  1304. X    if (Access(sprintf(file, "%s/%s", home, MAILRC), R_OK)
  1305. X        && Access(sprintf(file, "%s/%s", home, ALTERNATE_RC), R_OK))
  1306. X        if (argc || argv)
  1307. X        (void) strcpy(file, DEFAULT_RC);
  1308. X        else
  1309. X        return -1;
  1310. X    }
  1311. X
  1312. X    argc = 0; /* don't ignore ENOENT */
  1313. X    p = getpath(file, &argc);
  1314. X    /* Try the ALT_DEF_RC if DEFAULT_RC fails */
  1315. X    if (argc && !strcmp(file, DEFAULT_RC)) {
  1316. X    argc = 0; /* don't ignore ENOENT */
  1317. X    (void) strcpy(file, ALT_DEF_RC);
  1318. X    p = getpath(file, &argc);
  1319. X    }
  1320. X    if (argc) {
  1321. X    /* Don't print error messages for missing default files */
  1322. X    if (strcmp(file, ALT_DEF_RC))
  1323. X        if (argc == -1) {
  1324. X        print("%s: %s\n", file, p);
  1325. X        return -1;
  1326. X        } else {
  1327. X        print("%s is a directory.\n", file);
  1328. X        return -2;
  1329. X        }
  1330. X    return -1;
  1331. X    }
  1332. X    if (!(fp = fopen(p, "r"))) {
  1333. X    if (errno != ENOENT)
  1334. X        error("Can't open %s", p);
  1335. X    return -1;
  1336. X    }
  1337. X    turnon(glob_flags, IGN_BANG); /* ignore ! when reading record files */
  1338. X    (void) strcpy(file, p);
  1339. X    (void) src_parse(file, fp, 0, 0, &line_no);
  1340. X    /* if we entered the routine ignoring !, leave it that way. */
  1341. X    if (!save_bang)
  1342. X    turnoff(glob_flags, IGN_BANG);
  1343. X    /* Sourcing might change things, so abort pipes/macros */
  1344. X    return 0 - (in_pipe() || in_macro());
  1345. X}
  1346. X
  1347. X/*
  1348. X * Do the actual file parsing for source().  The first argument should
  1349. X * be the name of the file referenced by the second argument.  The third
  1350. X * argument is used for handling nested if_else_endif expressions.  The
  1351. X * fourth argument is used to keep track of the recursion depth, and the
  1352. X * last argument keeps track of the line number in the current file.
  1353. X *
  1354. X * This function calls itself recursively.  It also calls do_command(),
  1355. X * which may in turn call source() recursively.
  1356. X *
  1357. X * If-then-else nesting algorithm:
  1358. X *  On any "if" (whether parsing or not), increment if_else
  1359. X *  On true "if" when parsing, evaluate by recursion
  1360. X *  On false "if" when parsing, set find_else equal to if_else
  1361. X *  On any "if" when not parsing, set find_endif equal to if_else
  1362. X *  On "else", invert parsing only when find_else equals if_else
  1363. X *  When "if" was false and there is nesting, recur for "else"
  1364. X *  Skip nested "if...endif" when find_else or find_endif true
  1365. X *  On "endif" or when recursion returns, decrement if_else
  1366. X *  On "endif", test both find_endif and find_else against if_else:
  1367. X *   when either matches, reset that one;
  1368. X *   when the lesser (less nested) matches, resume parsing
  1369. X *  On "endif", when if_else hits 0, continue (depth 0) or return
  1370. X */
  1371. Xsrc_parse(file, fp, if_else, depth, line_no)
  1372. Xchar    *file;
  1373. XFILE    *fp;
  1374. Xint      if_else, depth, *line_no;
  1375. X{
  1376. X    register char *p, *p2, **newargv;
  1377. X    static int    exited;
  1378. X    int       parsing = 1, cont_line = 0;
  1379. X    int          find_else = 0, find_endif = 0;
  1380. X    char       line[BUFSIZ];
  1381. X    int          argc;
  1382. X
  1383. X    exited = 0;
  1384. X
  1385. X    while (p = fgets(&line[cont_line], BUFSIZ - cont_line, fp)) {
  1386. X    (*line_no)++;
  1387. X    if (*(p2 = no_newln(p)) == '\\') {
  1388. X        *p2++ = ' ';
  1389. X        cont_line = p2 - line;
  1390. X        continue;
  1391. X    } else
  1392. X        cont_line = 0;
  1393. X    /* don't consider comments (#) in lines. check if # is within quotes */
  1394. X    if (p = any(line, "\"'#\\")) {
  1395. X        register int balanced = 1;
  1396. X        do {
  1397. X        if (*p == '\\' && p[1])
  1398. X            p = any(p+2, "\"'#\\");
  1399. X        else if (*p != '#') {
  1400. X            /* first find matching quote */
  1401. X            register char *quote = index(p+1, *p);
  1402. X            if (!quote) {
  1403. X            print("%s: line %d: unbalanced %c.\n",
  1404. X                file, *line_no, *p);
  1405. X            balanced = 0;
  1406. X            } else
  1407. X            p = any(quote+1, "\"'#\\");
  1408. X        }
  1409. X        } while (p && *p != '#' && balanced);
  1410. X        if (!balanced)
  1411. X        continue;
  1412. X        if (p && *p == '#')
  1413. X        *p = 0; /* found a Comment: null terminate line at comment */
  1414. X    }
  1415. X    if (!*line || !parsing && !(newargv = mk_argv(line, &argc, 0))
  1416. X    || parsing && !(newargv = make_command(line, TRPL_NULL, &argc))) {
  1417. X        if (!strncmp(line, "if", 2))
  1418. X        find_else = ++if_else, parsing = FALSE;
  1419. X        continue;
  1420. X    }
  1421. X    if (!strcmp(newargv[0], "endif")) {
  1422. X        if (!if_else)
  1423. X        print("%s: line %d: endif with no \"if\".\n", file, *line_no);
  1424. X        else {
  1425. X        /* If looking for an else or endif, reset parsing */
  1426. X        if (find_endif && find_endif == if_else) {
  1427. X            if (find_endif <= find_else || !find_else)
  1428. X            parsing = 1, find_else = 0;
  1429. X            find_endif = 0;
  1430. X        }
  1431. X        /* Note: find_else never < find_endif */
  1432. X        if (find_else && find_else == if_else)
  1433. X            parsing = !parsing, find_else = 0;
  1434. X        /* Decrement if_else and check depth */
  1435. X        if (--if_else == 0)
  1436. X            /* Resume parsing if at the top */
  1437. X            if (depth == 0)
  1438. X            parsing = 1;
  1439. X            /* Return if not at the top */
  1440. X            else
  1441. X            return 1;
  1442. X        }
  1443. X        goto bad;
  1444. X    } else if (!strcmp(newargv[0], "else")) {
  1445. X        if (!if_else)
  1446. X        print("%s: line %d: if-less \"else\".\n", file, *line_no);
  1447. X        /* If inside an else, ignore nested else;
  1448. X         *  otherwise, recur when if_else > 1 */
  1449. X        else if (!find_else && !find_endif && !parsing) {
  1450. X        parsing = src_parse(file, fp, 1, depth + 1, line_no);
  1451. X        --if_else;
  1452. X        } else if (find_else == if_else || if_else == 1) {
  1453. X        find_else = 0;
  1454. X        parsing = !parsing;
  1455. X        if (!parsing)
  1456. X            find_endif = if_else;
  1457. X        }
  1458. X        goto bad;
  1459. X    } else if (!strcmp(newargv[0], "if")) {
  1460. X        /* if statements are of the form:
  1461. X         *     if expr
  1462. X         *     if !expr  or  if ! expr
  1463. X         *     if expr == expr   or   if expr != expr
  1464. X         */
  1465. X        int equals = TRUE, pattern = FALSE;
  1466. X        register char *lhs = newargv[1], *rhs = NULL;
  1467. X
  1468. X        if_else++;
  1469. X        /* If parsing, set parsing to 0 until
  1470. X         *  evaluating the "if" proves otherwise.
  1471. X         * If not parsing, skip to the "endif".
  1472. X         */
  1473. X        if (parsing)
  1474. X        parsing = 0;
  1475. X        else {
  1476. X        if (!find_endif)
  1477. X            find_endif = if_else;
  1478. X        goto bad;
  1479. X        }
  1480. X        if (!lhs || !*lhs) {
  1481. X        print("%s: line %d: if what?\n", file, *line_no);
  1482. X        goto bad;
  1483. X        }
  1484. X        /* "lhs" is the left hand side of the equation
  1485. X         * In this instance, we're doing case 2 above (check for negation).
  1486. X         */
  1487. X        if (*lhs == '!') {
  1488. X        if (!*++lhs && !(lhs = newargv[2])) {
  1489. X            print("%s: line %d: syntax error: \"if ! <what?>\"\n",
  1490. X            file, *line_no);
  1491. X            goto bad;
  1492. X        }
  1493. X        equals = FALSE;
  1494. X        }
  1495. X        if (*lhs == '-' && (lhs[1] == 'e' || lhs[1] == 'z') && !lhs[2]) {
  1496. X        char *path;
  1497. X        int n = 1; /* ignore ENOENT, I'll handle it here */
  1498. X        struct stat statb;
  1499. X
  1500. X        /* check for existence or zero-length folders/files */
  1501. X        if (argc > 3 + (!equals)) {
  1502. X            print("%s: line %d: if %s \"filename\"\n",
  1503. X            file, *line_no, lhs);
  1504. X            goto bad;
  1505. X        }
  1506. X        path = getpath(newargv[argc-1], &n);
  1507. X        parsing = !equals ^ (n == -1 || n == 1 && lhs[1] == 'e' ||
  1508. X            !stat(path, &statb) && (lhs[1] == 'e' || !statb.st_size));
  1509. X        } else {
  1510. X        if (equals && argc > 2) {
  1511. X            if (argc != 4) {
  1512. X            print("%s: %d: argument count error: %d args.\n",
  1513. X                file, *line_no, argc);
  1514. X            goto bad;
  1515. X            }
  1516. X            /* now check newargv[2] for == or != or =~ or !~ */
  1517. X            if (!strcmp(newargv[2], "!=") ||
  1518. X                (pattern = !strcmp(newargv[2], "!~")))
  1519. X            equals = !equals;
  1520. X            else if (!strcmp(newargv[2], "=~"))
  1521. X            pattern = TRUE;
  1522. X            else if (strcmp(newargv[2], "==")) {
  1523. X            print("%s: %d: use `==' or `!=' only.\n",
  1524. X                file, *line_no);
  1525. X            goto bad;
  1526. X            }
  1527. X            rhs = newargv[3];
  1528. X        }
  1529. X        if (rhs) {
  1530. X            /* Some fun tricks with booleans here.
  1531. X             * Extra ! ops make sure all == are on 0 or 1;
  1532. X             * aside from that, we want (glob == equals)
  1533. X             * or (!strcmp == equals).  Make sense?  
  1534. X             */
  1535. X            if (pattern && !glob(lhs,rhs) == !equals)
  1536. X            parsing = 1;
  1537. X            else if (!pattern && !strcmp(lhs, rhs) == !!equals)
  1538. X            parsing = 1;
  1539. X        } else if (isdigit(*lhs))
  1540. X            parsing = !!(atoi(lhs) ? equals : !equals);
  1541. X        else if (!strcmp(lhs, "redirect") && (!isatty(0) != !equals)
  1542. X              /* (ison(glob_flags, REDIRECT) && equals ||
  1543. X               isoff(glob_flags, REDIRECT) && !equals) */
  1544. X            || !strcmp(lhs, "is_shell") && (!is_shell == !equals)
  1545. X            || !strcmp(lhs, "is_sending") &&
  1546. X              (ison(glob_flags, IS_SENDING) && equals ||
  1547. X               isoff(glob_flags, IS_SENDING) && !equals)
  1548. X            || !strcmp(lhs, "hdrs_only") &&
  1549. X              (hdrs_only && equals || !hdrs_only && !equals)
  1550. X            || !strcmp(lhs, "istool") &&
  1551. X              (istool && equals || !istool && !equals)
  1552. X            || !strcmp(lhs, "iscurses") &&
  1553. X              ((iscurses || ison(glob_flags, PRE_CURSES)) && equals
  1554. X              || (isoff(glob_flags, PRE_CURSES) &&
  1555. X                  !iscurses && !equals)))
  1556. X            parsing = 1;
  1557. X        }
  1558. X        if (parsing) {
  1559. X        parsing = src_parse(file, fp, 1, depth + 1, line_no);
  1560. X        --if_else;
  1561. X        }
  1562. X        else
  1563. X        find_else = if_else; /* Look for a matching else */
  1564. Xbad:
  1565. X        free_vec(newargv);
  1566. X        continue;
  1567. X    }
  1568. X    if (parsing && argc > 0)
  1569. X        if (!strcmp(newargv[0], "exit")) {
  1570. X        if_else = find_else = find_endif = 0;
  1571. X        exited = 1;
  1572. X        break;
  1573. X        } else {
  1574. X        (void) do_command(argc, newargv, msg_list);
  1575. X        exited = 0;
  1576. X        }
  1577. X    else
  1578. X        free_vec(newargv);
  1579. X    }
  1580. X    if (if_else && !exited)
  1581. X    print("%s: missing endif\n", file);
  1582. X    if (depth == 0)
  1583. X    (void) fclose(fp);
  1584. X    else
  1585. X    (void) fseek(fp, 0L, 2); /* Skip ahead to the end */
  1586. X    return 0;
  1587. X}
  1588. END_OF_FILE
  1589. if test 13422 -ne `wc -c <'mush/init.c'`; then
  1590.     echo shar: \"'mush/init.c'\" unpacked with wrong size!
  1591. fi
  1592. # end of 'mush/init.c'
  1593. fi
  1594. echo shar: End of archive 4 \(of 19\).
  1595. cp /dev/null ark4isdone
  1596. MISSING=""
  1597. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ; do
  1598.     if test ! -f ark${I}isdone ; then
  1599.     MISSING="${MISSING} ${I}"
  1600.     fi
  1601. done
  1602. if test "${MISSING}" = "" ; then
  1603.     echo You have unpacked all 19 archives.
  1604.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1605. else
  1606.     echo You still need to unpack the following archives:
  1607.     echo "        " ${MISSING}
  1608. fi
  1609. ##  End of shell archive.
  1610. exit 0
  1611.  
  1612.  
  1613.