home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume24 / zsh2.1 / part04 < prev    next >
Text File  |  1991-10-24  |  49KB  |  1,939 lines

  1. Newsgroups: comp.sources.misc
  2. From: pfalstad@phoenix.Princeton.EDU (Paul Falstad)
  3. Subject:  v24i004:  zsh2.1 - The Z shell, Part04/19
  4. Message-ID: <1991Oct24.190755.25578@sparky.imd.sterling.com>
  5. X-Md4-Signature: 51292069e24941ade188a03166809717
  6. Date: Thu, 24 Oct 1991 19:07:55 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: pfalstad@phoenix.Princeton.EDU (Paul Falstad)
  10. Posting-number: Volume 24, Issue 4
  11. Archive-name: zsh2.1/part04
  12. Environment: BSD
  13. Supersedes: zsh2.00: Volume 18, Issue 84-98
  14.  
  15. #!/bin/sh
  16. # this is zshar.04 (part 4 of zsh2.1.0)
  17. # do not concatenate these parts, unpack them in order with /bin/sh
  18. # file zsh2.1/man/man1/zsh.1 continued
  19. #
  20. if test ! -r _shar_seq_.tmp; then
  21.     echo 'Please unpack part 1 first!'
  22.     exit 1
  23. fi
  24. (read Scheck
  25.  if test "$Scheck" != 4; then
  26.     echo Please unpack part "$Scheck" next!
  27.     exit 1
  28.  else
  29.     exit 0
  30.  fi
  31. ) < _shar_seq_.tmp || exit 1
  32. if test ! -f _shar_wnt_.tmp; then
  33.     echo 'x - still skipping zsh2.1/man/man1/zsh.1'
  34. else
  35. echo 'x - continuing file zsh2.1/man/man1/zsh.1'
  36. sed 's/^X//' << 'SHAR_EOF' >> 'zsh2.1/man/man1/zsh.1' &&
  37. Xafter each command.
  38. XIf \fIsig\fP is \fB0\fP or \fBEXIT\fP
  39. Xand the \fBtrap\fP statement is executed inside the body of a function,
  40. Xthen the command \fIarg\fP is executed after the function completes.
  41. XIf \fIsig\fP is \fB0\fP or \fBEXIT\fP
  42. Xand the \fBtrap\fP statement is not executed inside the body of a function,
  43. Xthen the command \fIarg\fP is executed when the shell terminates.
  44. XThe \fBtrap\fP command with no arguments prints a list of commands
  45. Xassociated with each signal.
  46. X.TP
  47. X\fBtrue\fP
  48. XDo nothing and return an exit code of 0.
  49. X.TP
  50. X\fBtype\fP
  51. XSame as \fBwhence\fP \-\fBv\fP.
  52. X.TP
  53. X\fBtypeset\fP [ \(+-\fBLRZfilrtux [\fIn\fP]] [ \fIname\fP[=\fIvalue\fP] ] ...
  54. XSet attributes and values for shell parameters.
  55. XWhen invoked inside a function, if \fIname\fP is not already
  56. Xdefined, a new parameter is created which will be unset when the
  57. Xfunction completes.
  58. XThe following attributes are valid:
  59. X.RS
  60. X.PD 0
  61. X.TP
  62. X\-\fBL\fP
  63. XLeft justify and remove leading blanks from \fIvalue\fP.
  64. XIf \fIn\fP is nonzero, it defines the width of the field;
  65. Xotherwise it is determined by the width of the value of the first
  66. Xassignment.
  67. XWhen the parameter is printed, it is filled on the right with
  68. Xblanks or truncated if necessary to fit the field.
  69. XLeading zeros are removed if the \-\fBZ\fP flag is also set.
  70. X.TP
  71. X\-\fBR\fP
  72. XRight justify and fill with leading blanks.  If \fIn\fP is nonzero
  73. Xif defines the width of the field;
  74. Xotherwise it is determined by the width of the value of the first
  75. Xassignment.
  76. XWhen the parameter is printed, the field is left filled with
  77. Xblanks or truncated from the end.
  78. X.TP
  79. X\-\fBZ\fP
  80. XRight justify and fill with leading zeros if the first non-blank
  81. Xcharacter is a digit and the \-\fBL\fP flag has not been set.
  82. XIf \fIn\fP is nonzero it defines the width of the field;
  83. Xotherwise it is determined by the width of the value of the
  84. Xfirst assignment.
  85. X.TP
  86. X\-\fBf\fP
  87. XThe names refer to functions rather than parameters.  No assignments
  88. Xcan be made, and the only other valid flags are \-\fBt\fP
  89. Xand \-\fBu\fP.  The flag \-\fBt\fP turns on execution tracing for this
  90. Xfunction.  The flag \-\fBu\fP causes this function to be marked
  91. Xundefined.  The \fBfpath\fP parameter will be searched to find the
  92. Xfunction definition when the function is first referenced.
  93. X.TP
  94. X\-\fBi\fP
  95. XUse an internal integer representation.  If \fBi\fP is nonzero
  96. Xit defines the output arithmetic base, otherwise it is determined by the first
  97. Xassignment.
  98. X.TP
  99. X\-\fBl\fP
  100. XConvert to lower case.
  101. X.TP
  102. X\-\fBr\fP
  103. XThe given \fIname\fPs are marked readonly.
  104. X.TP
  105. X\-\fBt\fP
  106. XTags the named parameters.  Tags have no special meaning to the shell.
  107. X.TP
  108. X\-\fBu\fP
  109. XConvert to upper case.
  110. X.TP
  111. X\-\fBx\fP
  112. XMark for automatic export to the environment of subsequently
  113. Xexecuted commands.
  114. X.RE
  115. X.PD
  116. X.PP
  117. XUsing + rather than \- causes these flags to be turned off.
  118. XIf no arguments are given but flags are specified,
  119. Xa list of named parameters which have these flags set is printed.
  120. XUsing + instead of \- keeps their values from being printed.
  121. XIf no arguments or options are given, the names and attributes
  122. Xof all parameters are printed.
  123. X.TP
  124. X\fBulimit\fP [ \-\fBHSacdfmnt\fP ] [ \fIlimit\fP ]
  125. XSet or display a resource limit.  The value of limit can be a number
  126. Xin the unit specified below or the value \fBunlimited\fP.
  127. XThe \fBH\fP and \fBS\fP flags specify whether the hard limit
  128. Xor the soft limit for the given resource is set.
  129. X.RS
  130. X.PD 0
  131. X.TP
  132. X\-\fBa\fP
  133. XLists all of the current resource limits.
  134. X.TP
  135. X\-\fBc\fP
  136. XThe number of 512-byte blocks on the size of core dumps.
  137. X.TP
  138. X\-\fBd\fP
  139. XThe number of K-bytes on the size of the data segment.
  140. X.TP
  141. X\-\fBf\fP
  142. XThe number of 512-byte blocks on the size of files written.
  143. X.TP
  144. X\-\fBm\fP
  145. XThe number of K-bytes on the size of physical memory.
  146. X.TP
  147. X\-\fBn\fP
  148. XThe number of file descriptors.
  149. X.TP
  150. X\-\fBs\fP
  151. XThe number of K-bytes on the size of the stack.
  152. X.TP
  153. X\-\fBt\fP
  154. XThe number of CPU seconds to be used.
  155. X.RE
  156. X.PD
  157. X.TP
  158. X\fBumask\fP [ \fImask\fP ]
  159. XThe umask is set to \fImask\fP.  \fImask\fP can be either
  160. Xan octal number or a symbolic value as described in \fBchmod\fP(1).
  161. XIf \fImask\fP is omitted, the current value is printed.
  162. X.TP
  163. X\fBunalias\fP \fIname\fP ...
  164. XThe alias definition, if any, for each \fIname\fP is removed.
  165. X.TP
  166. X\fBunfunction\fP \fIname\fP ...
  167. XThe function definition, if any, for each \fIname\fP is removed.
  168. X.TP
  169. X\fBunhash\fP \fIname\fP ...
  170. XThe entry in the command hash table, if any, for each \fIname\fP
  171. Xis removed.
  172. X.TP
  173. X\fBunlimit\fP [ \-\fBh\fP ] \fIresource\fP ...
  174. XThe resource limit for each \fIresource\fP is set to the hard limit.
  175. XIf the \-\fBh\fP flag is given and the shell is running as root,
  176. Xthe hard resource limit for each \fIresource\fP is removed.
  177. X.TP
  178. X\fBunset\fP \fIname\fP ...
  179. XEach named parameter is unset.
  180. X.TP
  181. X\fBunsetopt\fP [ \(+-\fIoptions\fP ] [ \fIname\fP ... ]
  182. XUnset the options for the shell.  All options specified either
  183. Xwith flags or by name are unset.
  184. X.TP
  185. X\fBvared\fP \fIname\fP
  186. XThe value of the parameter \fIname\fP is loaded into the edit
  187. Xbuffer, and the line editor is invoked.  When the editor exits,
  188. X\fIname\fP is set to the string value returned by the editor.
  189. X.TP
  190. X\fBwait\fP [ \fIjob\fP ... ]
  191. XWait for the specified \fIjob\fPs.  If \fIjob\fP is not given
  192. Xthen all currently active child processes are waited for.
  193. XThe exit status from this command is that of the process waited for.
  194. X.TP
  195. X\fBwhence\fP [ \-\fBpv\fP ] \fIname\fP ...
  196. XFor each name, indicate how it would be interpreted if used
  197. Xas a command name.  The \-\fBv\fP flag produces a more verbose
  198. Xreport.  The \-\fBp\fP flag does a path search for \fIname\fP
  199. Xeven if it is a shell function, alias, or reserved word.
  200. X.TP
  201. X\fBwhich\fP
  202. XSame as \fBwhence\fP.
  203. X.RE
  204. X.SH INVOCATION
  205. XIf the \fBNO_RCS\fP option is unset, commands are read
  206. Xfrom $ZDOTDIR/.zshenv first.
  207. X(If \fBZDOTDIR\fP is unset, \fBHOME\fP is used instead).
  208. XThen, if the shell is interactive and
  209. Xthe \fBNO_RCS\fP option is unset, commands are read
  210. Xfrom /etc/zshrc and $ZDOTDIR/.zshrc, in that order, if either file
  211. Xexists.
  212. XIf the first character of argument zero passed to the shell
  213. Xis \-, then the shell is assumed to be a login shell, and commands
  214. Xare read from /etc/zprofile and $ZDOTDIR/.zprofile before .zshrc is read,
  215. Xthen /etc/zlogin and $ZDOTDIR/.zlogin after .zshrc is read.
  216. XIf the \fBNO_RCS\fP option is set, only /etc/zshrc
  217. X/etc/zlogin, and /etc/zprofile may be read.
  218. XIf the \-\fBs\fP flag is not present and an argument is given,
  219. Xthe first argument is taken to be the pathname of a script to
  220. Xexecute.  The remaining arguments are assigned to the positional
  221. Xparameters.  The following flags are interpreted by the shell
  222. Xwhen invoked:
  223. X.TP
  224. X.PD 0
  225. X\-\fBc\fP \fIstring\fP
  226. XRead commands from \fIstring\fP.
  227. X.TP
  228. X\-\fBs\fP
  229. XRead command from the standard input.
  230. X.TP
  231. X\-\fBi\fP
  232. XIf this flag is present or the shell input and output
  233. Xare attached to a terminal, this shell is interactive.
  234. X.PD
  235. X.SH "SEE ALSO"
  236. Xsh(1),
  237. Xcsh(1),
  238. Xtcsh(1),
  239. Xitcsh(1),
  240. Xrc(1),
  241. Xbash(1),
  242. Xash(1),
  243. Xksh(1),
  244. Xclam(1).
  245. X.SH FILES
  246. X$ZDOTDIR/.zshenv
  247. X.br
  248. X$ZDOTDIR/.zshrc
  249. X.br
  250. X$ZDOTDIR/.zlogin
  251. X.br
  252. X$ZDOTDIR/.zlogout
  253. X.br
  254. X$ZDOTDIR/.zprofile
  255. X.br
  256. X/tmp/zsh*
  257. X.br
  258. X/etc/zprofile
  259. X.br
  260. X/etc/zshrc
  261. X.br
  262. X/etc/zlogin
  263. X.SH AUTHOR
  264. XPaul Falstad (pfalstad@phoenix.princeton.edu)
  265. X.SH "UNDOCUMENTED FEATURES"
  266. XNone known, but many suspected.
  267. XPlease mail the author if you find any.
  268. SHAR_EOF
  269. echo 'File zsh2.1/man/man1/zsh.1 is complete' &&
  270. chmod 0644 zsh2.1/man/man1/zsh.1 ||
  271. echo 'restore of zsh2.1/man/man1/zsh.1 failed'
  272. Wc_c="`wc -c < 'zsh2.1/man/man1/zsh.1'`"
  273. test 107626 -eq "$Wc_c" ||
  274.     echo 'zsh2.1/man/man1/zsh.1: original size 107626, current size' "$Wc_c"
  275. rm -f _shar_wnt_.tmp
  276. fi
  277. # ============= zsh2.1/scripts/aproto ==============
  278. if test ! -d 'zsh2.1/scripts'; then
  279.     echo 'x - creating directory zsh2.1/scripts'
  280.     mkdir 'zsh2.1/scripts'
  281. fi
  282. if test -f 'zsh2.1/scripts/aproto' -a X"$1" != X"-c"; then
  283.     echo 'x - skipping zsh2.1/scripts/aproto (File already exists)'
  284.     rm -f _shar_wnt_.tmp
  285. else
  286. > _shar_wnt_.tmp
  287. echo 'x - extracting zsh2.1/scripts/aproto (Text)'
  288. sed 's/^X//' << 'SHAR_EOF' > 'zsh2.1/scripts/aproto' &&
  289. X#! /bin/sh
  290. Xfproto builtin.c >builtin.pro
  291. Xfproto cond.c >cond.pro
  292. Xfproto exec.c >exec.pro
  293. Xfproto glob.c >glob.pro
  294. Xfproto hist.c >hist.pro
  295. Xfproto init.c >init.pro
  296. Xfproto jobs.c >jobs.pro
  297. Xfproto lex.c >lex.pro
  298. Xfproto loop.c >loop.pro
  299. Xfproto math.c >math.pro
  300. Xfproto mem.c >mem.pro
  301. Xfproto params.c >params.pro
  302. Xfproto subst.c >subst.pro
  303. Xfproto table.c >table.pro
  304. Xfproto text.c >text.pro
  305. Xfproto utils.c >utils.pro
  306. Xfproto watch.c >watch.pro
  307. Xfproto parse.c >parse.pro
  308. Xfproto zle_hist.c >zle_hist.pro
  309. Xfproto zle_main.c >zle_main.pro
  310. Xfproto zle_misc.c >zle_misc.pro
  311. Xfproto zle_move.c >zle_move.pro
  312. Xfproto zle_refresh.c >zle_refresh.pro
  313. Xfproto zle_tricky.c >zle_tricky.pro
  314. Xfproto zle_utils.c >zle_utils.pro
  315. Xfproto zle_vi.c >zle_vi.pro
  316. Xfproto zle_word.c >zle_word.pro
  317. SHAR_EOF
  318. chmod 0755 zsh2.1/scripts/aproto ||
  319. echo 'restore of zsh2.1/scripts/aproto failed'
  320. Wc_c="`wc -c < 'zsh2.1/scripts/aproto'`"
  321. test 755 -eq "$Wc_c" ||
  322.     echo 'zsh2.1/scripts/aproto: original size 755, current size' "$Wc_c"
  323. rm -f _shar_wnt_.tmp
  324. fi
  325. # ============= zsh2.1/scripts/fproto ==============
  326. if test -f 'zsh2.1/scripts/fproto' -a X"$1" != X"-c"; then
  327.     echo 'x - skipping zsh2.1/scripts/fproto (File already exists)'
  328.     rm -f _shar_wnt_.tmp
  329. else
  330. > _shar_wnt_.tmp
  331. echo 'x - extracting zsh2.1/scripts/fproto (Text)'
  332. sed 's/^X//' << 'SHAR_EOF' > 'zsh2.1/scripts/fproto' &&
  333. X#! /bin/sh
  334. X# prototype generator
  335. Xsed -n '/\/\*\*\/$/{N;s/^\([^(]*\).*\/\*\*\/.\(.*\)/\1 DCLPROTO((\2))/p;}' $1 | sed -e 's/;/,/g' -e 's/,))$/));/' -e 's/(({))$/((void));/'
  336. X
  337. SHAR_EOF
  338. chmod 0755 zsh2.1/scripts/fproto ||
  339. echo 'restore of zsh2.1/scripts/fproto failed'
  340. Wc_c="`wc -c < 'zsh2.1/scripts/fproto'`"
  341. test 173 -eq "$Wc_c" ||
  342.     echo 'zsh2.1/scripts/fproto: original size 173, current size' "$Wc_c"
  343. rm -f _shar_wnt_.tmp
  344. fi
  345. # ============= zsh2.1/scripts/c2z ==============
  346. if test -f 'zsh2.1/scripts/c2z' -a X"$1" != X"-c"; then
  347.     echo 'x - skipping zsh2.1/scripts/c2z (File already exists)'
  348.     rm -f _shar_wnt_.tmp
  349. else
  350. > _shar_wnt_.tmp
  351. echo 'x - extracting zsh2.1/scripts/c2z (Text)'
  352. sed 's/^X//' << 'SHAR_EOF' > 'zsh2.1/scripts/c2z' &&
  353. X#! /bin/sh
  354. X#
  355. X# c2z - environment conversion tool
  356. X# Contributed by Bart Schaefer
  357. X# (Tweaked a bit by Paul Falstad)
  358. X#
  359. X# This is a quick script to convert csh aliases to zsh aliases/functions.
  360. X# It also converts the csh environment and local variables to zsh.  c2z
  361. X# uses the csh to parse its own dot-files, then processes csh output to
  362. X# convert the csh settings to zsh.
  363. X#
  364. X# When run as a zsh fuction, c2z runs csh as if it were an interactive
  365. X# shell whenever the parent zsh is interactive.  When run as a shell
  366. X# script, the -i switch can be used to force this behavior.
  367. X#
  368. X# The -l (login) switch causes csh to run as if it were a login shell.
  369. X# This is done "properly" if c2z is used as a zsh function, otherwise
  370. X# it's faked by explicitly sourcing .login.  Use with caution if your
  371. X# .login initializes an X server or does other one-time-only startup
  372. X# procedures.
  373. X#
  374. X# usage:
  375. X#    c2z [-i] [-l]
  376. X#
  377. X# You can use this script in your .zshrc or .zlogin files to load your
  378. X# regular csh environment into zsh; for example, in .zlogin:
  379. X#
  380. X#    . =(c2z -l)
  381. X#
  382. X# This is not perfect, but it gets most common aliases and variables.
  383. X# It's also rather time-consuming to do this every time you log in.
  384. X# However, if you're moving from csh to zsh for the first time, this
  385. X# can get you started with a familiar environment right away.
  386. X#
  387. X# In case your mailer eats tabs, $T is set to expand to a tab.
  388. X#
  389. XT="`echo x | tr x '\011'`"
  390. X
  391. X# If we're zsh, we can run "- csh" to get the complete environment.
  392. X#
  393. XMINUS=""
  394. XLOGIN=""
  395. XINTERACT=""
  396. Xcase "$VERSION" in
  397. Xzsh*)
  398. X    case $1 in
  399. X    -l*) MINUS="-" ;;
  400. X    -i*) INTERACT="-i" ;;
  401. X    esac
  402. X    if [[ -o INTERACTIVE ]]; then INTERACT="-i"; fi
  403. X    setopt nobanghist
  404. X    ;;
  405. X*)
  406. X    case $1 in
  407. X    -l*) LOGIN="source ~/.login" ;;
  408. X    -i*) INTERACT="-i" ;;
  409. X    esac
  410. X    ;;
  411. Xesac
  412. X
  413. X( eval $MINUS csh $INTERACT ) <<EOF 2>&1 >/dev/null
  414. X$LOGIN
  415. Xalias >! /tmp/cz$$.a
  416. Xsetenv >! /tmp/cz$$.e
  417. Xset >! /tmp/cz$$.v
  418. XEOF
  419. X
  420. X# save stdin
  421. Xexec 9<&0
  422. X
  423. X# First convert aliases
  424. Xexec < /tmp/cz$$.a
  425. X
  426. X# Taken straight from ctoz except for $T and "alias --"
  427. Xsed -e 's/'"$T"'(\(.*\))/'"$T"'\1/' >/tmp/cz$$.1
  428. Xgrep ! /tmp/cz$$.1 >/tmp/cz$$.2
  429. Xgrep -v ! /tmp/cz$$.1 >/tmp/cz$$.3
  430. Xsed -e "s/'/'"\\\\"''"/g \
  431. X    -e 's/^\([^'"$T"']*\)'"$T"'\(.*\)$/alias -- \1='"'\2'/" \
  432. X    /tmp/cz$$.3
  433. Xsed -e 's/![:#]*/$/g' \
  434. X    -e 's/^\([^'"$T"']*\)'"$T"'\(.*\)$/\1 () { \2 }/' \
  435. X    /tmp/cz$$.2
  436. X
  437. X# Next, convert environment variables
  438. Xexec < /tmp/cz$$.e
  439. X
  440. X# Would be nice to deal with embedded newlines, e.g. in TERMCAP, but ...
  441. Xsed -e '/^SHLVL/d' \
  442. X    -e "s/'/'"\\\\"''"/g \
  443. X    -e "s/^\([A-Za-z0-9_]*=\)/export \1'/" \
  444. X    -e "s/$/'/"
  445. X
  446. X# Finally, convert local variables
  447. Xexec < /tmp/cz$$.v
  448. X
  449. Xsed -e 's/'"$T"'/=/' \
  450. X    -e "s/'/'"\\\\"''"/g \
  451. X    -e '/^[A-Za-z0-9_]*=[^(]/{
  452. X    s/=/='"'/"'
  453. X    s/$/'"'/"'
  454. X    }' |
  455. Xsed -e '/^argv=/d' -e '/^cwd=/d' -e '/^filec=/d' -e '/^status=/d' \
  456. X     -e '/^histchars=/s//HISTCHARS=/' \
  457. X     -e '/^history=/s//HISTSIZE=/' \
  458. X     -e '/^home=/s//HOME=/' \
  459. X     -e '/^ignoreeof=/s/.*/setopt ignoreeof/' \
  460. X     -e '/^noclobber=/s/.*/setopt noclobber/' \
  461. X     -e '/^notify=/d' \
  462. X     -e '/^showdots=/s/.*/setopt globdots/' \
  463. X    -e '/^savehist=/s//HISTFILE=\~\/.zhistory SAVEHIST=/' \
  464. X     -e '/^autolist=/s/.*/setopt autolist/' \
  465. X     -e '/^correct=[cmd]*/s//setopt autocorrect/' \
  466. X     -e '/^who=/s//WATCHFMT=/'
  467. X
  468. X
  469. Xexec 0<&9
  470. X
  471. Xrm /tmp/cz$$.?
  472. Xexit
  473. SHAR_EOF
  474. chmod 0755 zsh2.1/scripts/c2z ||
  475. echo 'restore of zsh2.1/scripts/c2z failed'
  476. Wc_c="`wc -c < 'zsh2.1/scripts/c2z'`"
  477. test 3299 -eq "$Wc_c" ||
  478.     echo 'zsh2.1/scripts/c2z: original size 3299, current size' "$Wc_c"
  479. rm -f _shar_wnt_.tmp
  480. fi
  481. # ============= zsh2.1/src/buildzsh ==============
  482. if test ! -d 'zsh2.1/src'; then
  483.     echo 'x - creating directory zsh2.1/src'
  484.     mkdir 'zsh2.1/src'
  485. fi
  486. if test -f 'zsh2.1/src/buildzsh' -a X"$1" != X"-c"; then
  487.     echo 'x - skipping zsh2.1/src/buildzsh (File already exists)'
  488.     rm -f _shar_wnt_.tmp
  489. else
  490. > _shar_wnt_.tmp
  491. echo 'x - extracting zsh2.1/src/buildzsh (Text)'
  492. sed 's/^X//' << 'SHAR_EOF' > 'zsh2.1/src/buildzsh' &&
  493. X#! /bin/sh
  494. Xecho
  495. Xecho 'Building config.h...' | tr -d '\012'
  496. Xexec >config.h
  497. Xcat <<'foo'
  498. X/* this file is created automatically by buildzsh */
  499. X
  500. X/* define this if you are sysvish */
  501. Xfoo
  502. Xif test -f /usr/include/sys/resource.h
  503. Xthen echo '/* #define SYSV */'
  504. Xelse echo '#define SYSV'
  505. Xfi
  506. Xecho
  507. Xif grep TCGETS /usr/include/sys/termios.h >/dev/null 2>&1
  508. Xthen echo '#define TERMIOS
  509. X/* #define TTY_NEEDS_DRAINING */
  510. X/* #define CLOBBERS_TYPEAHEAD */'
  511. Xelse
  512. Xif grep sgttyb /usr/include/sys/ioctl.h >/dev/null 2>&1
  513. Xthen echo '/* #define TERMIO */'
  514. Xelse echo '#define TERMIO'
  515. Xfi
  516. Xecho '#define TTY_NEEDS_DRAINING
  517. X#define CLOBBERS_TYPEAHEAD'
  518. Xfi
  519. Xecho
  520. Xecho '/* define this if you have a host field in utmp */'
  521. Xif grep ut_host /usr/include/utmp.h >/dev/null
  522. Xthen echo '#define UTMP_HOST'
  523. Xelse echo '/* #define UTMP_HOST */'
  524. Xfi
  525. Xecho
  526. Xecho '/* define this if you have WAITPID */'
  527. X# this next line should read "sed 's/_^H//g'"
  528. X# there should be a _(backspace) there
  529. Xif man 2 wait 2>/dev/null | sed 's/_//g' | grep waitpid >/dev/null
  530. Xthen echo '#define WAITPID'
  531. Xelse echo '/* #define WAITPID */'
  532. Xfi
  533. Xecho
  534. Xecho '/* define this if you have SELECT */'
  535. Xif grep FD_SET /usr/include/sys/types.h >/dev/null
  536. Xthen echo '#define HAS_SELECT'
  537. Xelse echo '/* #define HAS_SELECT */'
  538. Xfi
  539. Xecho
  540. Xecho '/* define this if your signal handlers return void */'
  541. Xif grep SIG_DFL /usr/include/signal.h /usr/include/sys/signal.h |
  542. X    grep void >/dev/null
  543. Xthen echo '#define SIGVOID'
  544. Xelse echo '/* #define SIGVOID */'
  545. Xfi
  546. Xcat <<'foo'
  547. X#ifdef sgi
  548. X#undef SIGVOID
  549. X#endif
  550. Xfoo
  551. Xecho
  552. Xecho '/* define this if signal handlers need to be reset each time */'
  553. Xif grep SIGTSTP /usr/include/signal.h /usr/include/sys/signal.h >/dev/null
  554. Xthen echo '/* #define RESETHANDNEEDED */'
  555. Xelse echo '#define RESETHANDNEEDED'
  556. Xfi
  557. Xecho
  558. Xcat <<'foo'
  559. X#ifdef SIGVOID
  560. X#define HANDTYPE void
  561. X#else
  562. X#define HANDTYPE int
  563. X#define INTHANDTYPE
  564. X#endif
  565. X
  566. X/* a string corresponding to the host type */
  567. Xfoo
  568. Xecho '#define HOSTTYPE "' | tr -d '\012'
  569. X( tcsh -fc 'echo $HOSTTYPE' || arch || echo unknown ) 2>/dev/null |
  570. X    tr -d '\012'
  571. Xecho '"'
  572. Xecho
  573. Xecho '/* the default editor for the fc builtin */'
  574. Xecho '#define DEFFCEDIT "vi"'
  575. Xecho
  576. Xif grep UTMP_FILE /usr/include/utmp.h >/dev/null
  577. Xthen :
  578. Xelse 
  579. Xecho '/* the path of wtmp */'
  580. Xecho '#define WTMP_FILE "' | tr -d '\012'
  581. Xif test -f /etc/wtmp
  582. Xthen echo /etc/wtmp
  583. Xelif test -f /usr/etc/wtmp
  584. Xthen echo /usr/etc/wtmp
  585. Xelif test -f /var/adm/wtmp
  586. Xthen echo /var/adm/wtmp
  587. Xelif test -f /usr/adm/wtmp
  588. Xthen echo /usr/adm/wtmp
  589. Xelse echo /dev/null
  590. Xfi | tr -d '\012'
  591. Xecho '"
  592. X
  593. X/* the path of utmp */
  594. X#define UTMP_FILE "/etc/utmp"
  595. X'
  596. Xfi
  597. Xcat <<'foo'
  598. X/* default prefix for temporary files */
  599. X#define DEFTMPPREFIX "/tmp/zsh"
  600. X
  601. X/* define if you prefer "suspended" to "stopped" */
  602. X#define USE_SUSPENDED
  603. X
  604. X/* the file to source whenever zsh is run; if undefined, don't source
  605. X    anything */
  606. X#define GLOBALZSHRC "/etc/zshrc"
  607. X
  608. X/* the file to source whenever zsh is run as a login shell; if
  609. X    undefined, don't source anything */
  610. X#define GLOBALZLOGIN "/etc/zlogin"
  611. X
  612. X/* the file to source whenever zsh is run as a login shell, before
  613. X    zshrc is read; if undefined, don't source anything */
  614. X#define GLOBALZPROFILE "/etc/zprofile"
  615. X
  616. X/* the default HISTSIZE */
  617. X#define DEFAULT_HISTSIZE 128
  618. X
  619. X/* define if you like interactive comments */
  620. X/*#define INTERACTIVE_COMMENTS*/
  621. X
  622. X#define _BSD_SIGNALS   /* this could be an iris, you never know */
  623. X#define _BSD           /* this could be HP-UX, you never know */
  624. X
  625. X/* if your compiler doesn't like void *, change this to char *
  626. X    and ignore all the warnings.
  627. X*/
  628. X
  629. Xtypedef void *vptr;
  630. X
  631. X#define JOB_CONTROL
  632. Xfoo
  633. Xexec 1>&2
  634. Xecho done
  635. Xecho 'Building signals.h...' | tr -d '\012'
  636. Xecho `csh -fc 'kill -l'` | tr ' ' '\012' >signals.h
  637. Xlct=`wc -l < signals.h`
  638. Xcp signals.h signams.h
  639. X(
  640. Xecho '/* this file is created automatically by buildzsh */
  641. X/* if all this is wrong, blame csh ;-) */
  642. X
  643. X#define SIGCOUNT '"$lct"'
  644. X
  645. X#ifdef GLOBALS
  646. X
  647. Xchar *sigmsg[SIGCOUNT+2] = {
  648. X    "done",'
  649. Xsed -e 's/^/SIG/' -e '/SIGHUP/s//hangup/
  650. X/SIGINT/s//interrupt/
  651. X/SIGQUIT/s//quit/
  652. X/SIGILL/s//illegal instruction/
  653. X/SIGTRAP/s//trace trap/
  654. X/SIGIOT/s//IOT instruction/
  655. X/SIGABRT/s//abort/
  656. X/SIGEMT/s//EMT instruction/
  657. X/SIGFPE/s//floating point exception/
  658. X/SIGKILL/s//killed/
  659. X/SIGBUS/s//bus error/
  660. X/SIGSEGV/s//segmentation fault/
  661. X/SIGSYS/s//bad system call/
  662. X/SIGPIPE/s//broken pipe/
  663. X/SIGTERM/s//terminated/
  664. X/SIGPWR/s//power fail/
  665. X/SIGVTALRM/s//virtual time alarm/
  666. X/SIGCONT/s//continued/
  667. X/SIGXCPU/s//cpu limit exceeded/
  668. X/SIGXFSZ/s//filesize limit exceeded/' -e 's/.*/    "&",/' signals.h
  669. Xecho '    NULL
  670. X};
  671. X
  672. Xchar *sigs[SIGCOUNT+4] = {
  673. X    "EXIT",' ) >sigtmp.h
  674. Xmv sigtmp.h signals.h
  675. Xif grep SIGSTOP signals.h >/dev/null
  676. Xthen ed signals.h <<'foo' >/dev/null 2>&1
  677. X/SIGSTOP/c
  678. X#ifdef USE_SUSPENDED
  679. X    "suspended (signal)",
  680. X#else
  681. X    "stopped (signal)",
  682. X#endif
  683. X.
  684. X/SIGTSTP/c
  685. X#ifdef USE_SUSPENDED
  686. X    "suspended",
  687. X#else
  688. X    "stopped",
  689. X#endif
  690. X.
  691. X/SIGTTIN/c
  692. X#ifdef USE_SUSPENDED
  693. X    "suspended (tty input)",
  694. X#else
  695. X    "stopped (tty input)",
  696. X#endif
  697. X.
  698. X/SIGTTOU/c
  699. X#ifdef USE_SUSPENDED
  700. X    "suspended (tty output)",
  701. X#else
  702. X    "stopped (tty output)",
  703. X#endif
  704. X.
  705. Xw
  706. Xq
  707. Xfoo
  708. Xfi
  709. X(sed 's/.*/    "&",/' signams.h
  710. Xecho '    "ERR",
  711. X    "DEBUG",
  712. X    NULL
  713. X};
  714. X
  715. X#else
  716. X
  717. Xextern char *sigs[SIGCOUNT+4],*sigmsg[SIGCOUNT+2];
  718. X
  719. X#endif') >>signals.h
  720. Xrm signams.h
  721. Xecho done
  722. Xecho 'Building Makefile...' | tr -d '\012'
  723. Xexec >Makefile
  724. Xcat <<'foo'
  725. X#! /bin/make -f
  726. X#
  727. X# Makefile - rather obvious isn't it
  728. X#
  729. X# This file is part of zsh, the Z shell.
  730. X#
  731. X# zsh is free software; no one can prevent you from reading the source
  732. X# code, or giving it to someone else.
  733. X# 
  734. X# This file is copyrighted under the GNU General Public License, which
  735. X# can be found in the file called COPYING.
  736. X# 
  737. X# Copyright (C) 1990, 1991 Paul Falstad
  738. X#
  739. X# zsh is distributed in the hope that it will be useful, but
  740. X# WITHOUT ANY WARRANTY.  No author or distributor accepts
  741. X# responsibility to anyone for the consequences of using it or for
  742. X# whether it serves any particular purpose or works at all, unless he
  743. X# says so in writing.  Refer to the GNU General Public License
  744. X# for full details.
  745. X# 
  746. X# Everyone is granted permission to copy, modify and redistribute
  747. X# zsh, but only under the conditions described in the GNU General Public
  748. X# License.   A copy of this license is supposed to have been given to you
  749. X# along with zsh so you can know your rights and responsibilities.
  750. X# It should be in a file named COPYING.
  751. X# 
  752. X# Among other things, the copyright notice and this notice must be
  753. X# preserved on all copies.
  754. X#
  755. X
  756. XOBJS=builtin.o cond.o exec.o glob.o hist.o init.o jobs.o lex.o loop.o \
  757. Xmath.o mem.o params.o parse.o subst.o table.o text.o utils.o watch.o \
  758. Xzle_bindings.o zle_hist.o zle_main.o zle_misc.o zle_move.o zle_refresh.o \
  759. Xzle_tricky.o zle_utils.o zle_vi.o zle_word.o
  760. X
  761. XBINDIR=/usr/local/bin
  762. XMANDIR=/usr/local/man/man1
  763. X
  764. X# debugging flags
  765. X#CFLAGS=-g -Wreturn-type -Wunused -Wpointer-arith -DQDEBUG
  766. X#CC=gcc -traditional
  767. X
  768. XCC=cc
  769. Xfoo
  770. Xif test -f /usr/include/ndir.h -a ! -f /usr/lib/libBSD.a
  771. Xthen echo 'CFLAGS= -O -Aa'
  772. Xelse echo 'CFLAGS= -O'
  773. Xfi
  774. Xif test -f /usr/lib/libbsd.a
  775. Xthen
  776. Xif grep '^\+' /etc/passwd >/dev/null
  777. Xthen echo 'LIBS= -lcurses -lbsd -lc_s'
  778. Xelse echo 'LIBS= -lcurses -lbsd'
  779. Xfi
  780. Xelif test -f /usr/lib/libcposix.a
  781. Xthen echo 'LIBS= -lcposix -ltermcap'
  782. Xelif test -f /usr/lib/libBSD.a
  783. Xthen echo 'LIBS= -ltermcap -lBSD'
  784. Xelif test -f /usr/lib/libtermcap.a
  785. Xthen echo 'LIBS= -ltermcap'
  786. Xelse echo 'LIBS= -lcurses'
  787. Xfi
  788. Xcat <<'foo'
  789. X
  790. XZSHPATH=zsh
  791. X
  792. X.c.o:
  793. X    $(CC) $(CFLAGS) -c $<
  794. X
  795. Xall: $(ZSHPATH)
  796. X
  797. X$(ZSHPATH): $(OBJS)
  798. X    $(CC) -o $(ZSHPATH) $(OBJS) $(LIBS) $(LFLAGS)
  799. X    
  800. Xtags: /tmp
  801. X    ctags *.[cy]
  802. X
  803. X# I hate this next line
  804. X$(OBJS): config.h zsh.h zle.h signals.h ztype.h funcs.h
  805. X
  806. Xclean:
  807. X    rm -f *.o zsh core 
  808. X
  809. Xcleanall:
  810. X    rm -f *.o zsh core Makefile signals.h config.h
  811. X
  812. Xinstall: zsh
  813. X    install -s -m 755 zsh $(BINDIR)
  814. X    install -m 444 ../man/man1/zsh.1 $(MANDIR)
  815. Xfoo
  816. Xexec 1>&2
  817. Xcat <<'foo'
  818. Xdone
  819. X
  820. XYou may want to look at the files I just created (config.h, Makefile,
  821. Xand signals.h) to make sure they are correct.  Or you may just want
  822. Xto go ahead and try running make now to see what happens.
  823. X
  824. Xfoo
  825. Xecho 'Shall I execute make now?' | tr -d '\012' 
  826. Xread reply
  827. Xecho
  828. Xcase "$reply" in
  829. X[yY]*) exec make ;;
  830. Xesac
  831. X
  832. SHAR_EOF
  833. chmod 0755 zsh2.1/src/buildzsh ||
  834. echo 'restore of zsh2.1/src/buildzsh failed'
  835. Wc_c="`wc -c < 'zsh2.1/src/buildzsh'`"
  836. test 8053 -eq "$Wc_c" ||
  837.     echo 'zsh2.1/src/buildzsh: original size 8053, current size' "$Wc_c"
  838. rm -f _shar_wnt_.tmp
  839. fi
  840. # ============= zsh2.1/src/builtin.c ==============
  841. if test -f 'zsh2.1/src/builtin.c' -a X"$1" != X"-c"; then
  842.     echo 'x - skipping zsh2.1/src/builtin.c (File already exists)'
  843.     rm -f _shar_wnt_.tmp
  844. else
  845. > _shar_wnt_.tmp
  846. echo 'x - extracting zsh2.1/src/builtin.c (Text)'
  847. sed 's/^X//' << 'SHAR_EOF' > 'zsh2.1/src/builtin.c' &&
  848. X/*
  849. X
  850. X    builtin.c - builtin commands
  851. X
  852. X    This file is part of zsh, the Z shell.
  853. X
  854. X    zsh is free software; no one can prevent you from reading the source
  855. X   code, or giving it to someone else.
  856. X
  857. X   This file is copyrighted under the GNU General Public License, which
  858. X   can be found in the file called COPYING.
  859. X
  860. X   Copyright (C) 1990, 1991 Paul Falstad
  861. X
  862. X   zsh is distributed in the hope that it will be useful, but
  863. X   WITHOUT ANY WARRANTY.  No author or distributor accepts
  864. X   responsibility to anyone for the consequences of using it or for
  865. X   whether it serves any particular purpose or works at all, unless he
  866. X   says so in writing.  Refer to the GNU General Public License
  867. X   for full details.
  868. X
  869. X   Everyone is granted permission to copy, modify and redistribute
  870. X   zsh, but only under the conditions described in the GNU General Public
  871. X   License.   A copy of this license is supposed to have been given to you
  872. X   along with zsh so you can know your rights and responsibilities.
  873. X   It should be in a file named COPYING.
  874. X
  875. X   Among other things, the copyright notice and this notice must be
  876. X   preserved on all copies.
  877. X
  878. X*/
  879. X
  880. X#include "zsh.h"
  881. X#include <sys/errno.h>
  882. X#include <sys/times.h>
  883. X
  884. X#define makecond() allocnode(N_COND)
  885. X
  886. X/* builtin flags */
  887. X
  888. X#define BINF_PLUSOPTS        1        /* +xyz legal */
  889. X#define BINF_R                    2        /* this is r (fc -e -) */
  890. X#define BINF_PRINTOPTS        4
  891. X#define BINF_SETOPTS            8
  892. X#define BINF_FCOPTS          16
  893. X#define BINF_TYPEOPT      32
  894. X#define BINF_TYPEOPTS      (BINF_TYPEOPT|BINF_PLUSOPTS)
  895. X#define BINF_ECHOPTS      64
  896. X
  897. X/* builtin funcs */
  898. X
  899. X#define BIN_TYPESET 0
  900. X#define BIN_BG 1
  901. X#define BIN_FG 2
  902. X#define BIN_JOBS 3
  903. X#define BIN_WAIT 4
  904. X#define BIN_DISOWN 5
  905. X#define BIN_BREAK 6
  906. X#define BIN_CONTINUE 7
  907. X#define BIN_EXIT 8
  908. X#define BIN_RETURN 9
  909. X#define BIN_SHIFT 10
  910. X#define BIN_CD 11
  911. X#define BIN_POPD 12
  912. X#define BIN_PUSHD 13
  913. X#define BIN_PRINT 14
  914. X#define BIN_EVAL 15
  915. X#define BIN_SCHED 16
  916. X#define BIN_FC 17
  917. X#define BIN_PUSHLINE 18
  918. X#define BIN_LOGOUT 19
  919. X#define BIN_BUILTIN 20
  920. X#define BIN_TEST 21
  921. X#define BIN_BRACKET 22
  922. X
  923. Xstruct bincmd {
  924. X    char *name;
  925. X    int (*handlerfunc) DCLPROTO((char *,char **,char *,int));
  926. X    int minargs;        /* min # of args */
  927. X    int maxargs;        /* max # of args, or -1 for no limit */
  928. X    int flags;            /* BINF_flags (see above) */
  929. X    int funcid;            /* xbins (see above) for overloaded handlerfuncs */
  930. X    char *optstr;        /* string of legal options */
  931. X    char *defopts;        /* options set by default for overloaded handlerfuncs */
  932. X    };
  933. X
  934. X/* structure for foo=bar assignments */
  935. X
  936. Xstruct asgment {
  937. X    struct asgment *next;
  938. X    char *name,*value;
  939. X    };
  940. X
  941. Xstatic char *auxdata;
  942. Xstatic int auxlen;
  943. Xstatic int showflag = 0,showflag2 = 0;
  944. X
  945. Xstruct bincmd builtins[] = {
  946. X    "[",bin_test,0,-1,0,BIN_BRACKET,NULL,NULL,
  947. X    ".",bin_dot,1,-1,0,0,NULL,NULL,
  948. X    ":",bin_colon,0,-1,0,0,NULL,NULL,
  949. X    "alias",bin_alias,0,-1,0,0,"ga",NULL,
  950. X    "autoload",bin_typeset,0,-1,BINF_TYPEOPTS,0,"tx","fu",
  951. X    "bg",bin_fg,0,-1,0,BIN_BG,NULL,NULL,
  952. X    "bindkey",bin_bindkey,0,-1,0,0,"asvemdrl",NULL,
  953. X    "break",bin_break,0,1,0,BIN_BREAK,NULL,NULL,
  954. X    "builtin",NULL,0,0,0,BIN_BUILTIN,NULL,NULL,
  955. X    "bye",bin_break,0,1,0,BIN_EXIT,NULL,NULL,
  956. X    "cd",bin_cd,0,2,0,BIN_CD,NULL,NULL,
  957. X    "chdir",bin_cd,0,2,0,BIN_CD,NULL,NULL,
  958. X    "continue",bin_break,0,1,0,BIN_CONTINUE,NULL,NULL,
  959. X    "declare",bin_typeset,0,-1,BINF_TYPEOPTS,0,"LRZfilrtux",NULL,
  960. X    "dirs",bin_dirs,0,-1,0,0,"v",NULL,
  961. X    "disable",bin_unhash,1,-1,0,0,NULL,NULL,
  962. X    "disown",bin_fg,1,-1,0,BIN_DISOWN,NULL,NULL,
  963. X    "echo",bin_print,0,-1,BINF_PRINTOPTS|BINF_ECHOPTS,BIN_PRINT,"n","-",
  964. X    "echotc",bin_echotc,1,-1,0,0,NULL,NULL,
  965. X    "enable",bin_enable,1,-1,0,0,NULL,NULL,
  966. X    "eval",bin_eval,0,-1,0,BIN_EVAL,NULL,NULL,
  967. X    "exit",bin_break,0,1,0,BIN_EXIT,NULL,NULL,
  968. X    "export",bin_typeset,0,-1,BINF_TYPEOPTS,0,"LRZfilrtu","x",
  969. X    "false",bin_let,0,0,0,0,NULL,NULL,
  970. X    "fc",bin_fc,0,-1,BINF_FCOPTS,BIN_FC,"nlreRW",NULL,
  971. X    "fg",bin_fg,0,-1,0,BIN_FG,NULL,NULL,
  972. X    "functions",bin_typeset,0,-1,BINF_TYPEOPTS,0,"tu","f",
  973. X    "getln",bin_read,0,-1,0,0,NULL,"zr",
  974. X    "getopts",bin_getopts,2,-1,0,0,NULL,NULL,
  975. X    "hash",bin_hash,2,2,0,0,"r",NULL,
  976. X    "history",bin_fc,0,-1,0,BIN_FC,"nr","l",
  977. X    "integer",bin_typeset,0,-1,BINF_TYPEOPTS,0,"LRZlrtux","i",
  978. X    "jobs",bin_fg,0,-1,0,BIN_JOBS,"lpZ",NULL,
  979. X    "kill",bin_kill,0,-1,0,0,NULL,NULL,
  980. X    "let",bin_let,1,-1,0,0,NULL,NULL,
  981. X    "limit",bin_limit,0,-1,0,0,"sh",NULL,
  982. X    "local",bin_typeset,0,-1,BINF_TYPEOPTS,0,"LRZfilrtux",NULL,
  983. X    "log",bin_log,0,0,0,0,NULL,NULL,
  984. X    "logout",bin_break,0,1,0,BIN_LOGOUT,NULL,NULL,
  985. X    "popd",bin_cd,0,2,0,BIN_POPD,NULL,NULL,
  986. X    "print",bin_print,0,-1,BINF_PRINTOPTS,BIN_PRINT,"RDPnrslz0-",NULL,
  987. X    "pushd",bin_cd,0,2,0,BIN_PUSHD,NULL,NULL,
  988. X    "pushln",bin_print,0,-1,BINF_PRINTOPTS,BIN_PRINT,NULL,"-nz",
  989. X    "pwd",bin_pwd,0,0,0,0,NULL,NULL,
  990. X    "r",bin_fc,0,-1,BINF_R,BIN_FC,"nrl",NULL,
  991. X    "read",bin_read,0,-1,0,0,"rz",NULL,
  992. X    "readonly",bin_typeset,0,-1,BINF_TYPEOPTS,0,"LRZfiltux","r",
  993. X    "rehash",bin_rehash,0,0,0,0,NULL,NULL,
  994. X    "return",bin_break,0,1,0,BIN_RETURN,NULL,NULL,
  995. X    "sched",bin_sched,0,-1,0,0,NULL,NULL,
  996. X    "set",bin_set,0,-1,BINF_SETOPTS|BINF_PLUSOPTS,0,"0123456789ABCDEFGHIJKLMNOPQRSTUWXYZaefghijklnosuvwxy",NULL,
  997. X    "setopt",bin_setopt,0,-1,BINF_PLUSOPTS,0,"0123456789BCDEFGHIJKLMNOPQRSTUWXYZaefghijklmnosuvwxy",NULL,
  998. X    "shift",bin_break,0,1,0,BIN_SHIFT,NULL,NULL,
  999. X    "source",bin_dot,1,-1,0,0,NULL,NULL,
  1000. X    "suspend",bin_suspend,0,0,0,0,"f",NULL,
  1001. X    "test",bin_test,0,-1,0,BIN_TEST,NULL,NULL,
  1002. X    "times",bin_times,0,0,0,0,NULL,NULL,
  1003. X    "trap",bin_trap,0,-1,0,0,NULL,NULL,
  1004. X    "true",bin_colon,0,0,0,0,NULL,NULL,
  1005. X    "type",bin_whence,0,-1,0,0,"p","v",
  1006. X    "typeset",bin_typeset,0,-1,BINF_TYPEOPTS,0,"LRZfilrtux",NULL,
  1007. X    "ulimit",bin_ulimit,0,1,0,0,"HSacdfmnt",NULL,
  1008. X    "umask",bin_umask,0,1,0,0,NULL,NULL,
  1009. X    "unalias",bin_unalias,1,-1,0,0,NULL,NULL,
  1010. X    "unfunction",bin_unhash,1,-1,0,0,NULL,NULL,
  1011. X    "unhash",bin_unhash,1,-1,0,0,NULL,NULL,
  1012. X    "unlimit",bin_unlimit,0,-1,0,0,"h",NULL,
  1013. X    "unset",bin_unset,1,-1,0,0,NULL,NULL,
  1014. X    "unsetopt",bin_setopt,0,-1,BINF_PLUSOPTS,1,"0123456789BCDEFGHIJKLMNOPQRSTUWXYZaefghijklmnosuvwxy",NULL,
  1015. X    "vared",bin_vared,1,1,0,0,NULL,NULL,
  1016. X    "wait",bin_fg,0,-1,0,BIN_WAIT,NULL,NULL,
  1017. X    "whence",bin_whence,0,-1,0,0,"pv",NULL,
  1018. X    "which",bin_whence,0,-1,0,0,"pv",NULL,
  1019. X    NULL,NULL,0,0,0,0,NULL,NULL
  1020. X    };
  1021. X
  1022. X/* print options */
  1023. X
  1024. Xstatic void prtopt()
  1025. X{
  1026. Xstruct option *opp;
  1027. X
  1028. X    if (isset(KSHOPTIONPRINT)) {
  1029. X        printf("Current option settings\n");
  1030. X        for (opp = optns; opp->name; opp++)
  1031. X            printf("%-20s%s\n", opp->name,
  1032. X                (opts[opp->id] == OPT_SET) ? "on" : "off");
  1033. X    } else
  1034. X        for (opp = optns; opp->name; opp++)
  1035. X            if (opts[opp->id] == OPT_SET)
  1036. X                puts(opp->name);
  1037. X}
  1038. X
  1039. X/* add builtins to the command hash table */
  1040. X
  1041. Xvoid addbuiltins() /**/
  1042. X{
  1043. Xstruct cmdnam *c;
  1044. Xstruct bincmd *b;
  1045. Xint t0;
  1046. X
  1047. X    for (t0 = 0, b = builtins; b->name; b++,t0++)
  1048. X        {
  1049. X        c = (Cmdnam) zcalloc(sizeof *c);
  1050. X        c->type = BUILTIN;
  1051. X        c->u.binnum = t0;
  1052. X        addhperm(b->name,c,cmdnamtab,freecmdnam);
  1053. X        }
  1054. X}
  1055. X
  1056. X/* enable */
  1057. X
  1058. Xint bin_enable(name,argv,ops,whocares) /**/
  1059. Xchar *name;char **argv;char *ops;int whocares;
  1060. X{
  1061. Xstruct cmdnam *c;
  1062. Xstruct bincmd *b;
  1063. Xint t0,ret = 0;
  1064. X
  1065. X    for (; *argv; argv++)
  1066. X        {
  1067. X        for (t0 = 0, b = builtins; b->name; b++,t0++)
  1068. X            if (!strcmp(*argv,b->name))
  1069. X                break;
  1070. X        if (!b->name)
  1071. X            {
  1072. X            zerrnam(name,"no such builtin: %s",*argv,0);
  1073. X            ret = 1;
  1074. X            }
  1075. X        else
  1076. X            {
  1077. X            c = (Cmdnam) zcalloc(sizeof *c);
  1078. X            c->type = BUILTIN;
  1079. X            c->u.binnum = t0;
  1080. X            addhperm(b->name,c,cmdnamtab,freecmdnam);
  1081. X            }
  1082. X        }
  1083. X    return ret;
  1084. X}
  1085. X
  1086. X/* :, true */
  1087. X
  1088. Xint bin_colon(name,argv,ops,whocares) /**/
  1089. Xchar *name;char **argv;char *ops;int whocares;
  1090. X{
  1091. X    return 0;
  1092. X}
  1093. X
  1094. X/* break, bye, continue, exit, logout, return, shift */
  1095. X
  1096. Xint bin_break(name,argv,ops,func) /**/
  1097. Xchar *name;char **argv;char *ops;int func;
  1098. X{
  1099. Xint num = -1;
  1100. X
  1101. X    if (*argv)
  1102. X        num = matheval(*argv);
  1103. X    if ((func == BIN_BREAK || func == BIN_CONTINUE) && !loops)
  1104. X        {
  1105. X        if (func == BIN_CONTINUE)
  1106. X            zerrnam(name,"not in loop",NULL,0);
  1107. X        return 1;
  1108. X        }
  1109. X    switch (func)
  1110. X        {
  1111. X        case BIN_CONTINUE:
  1112. X            contflag = 1;
  1113. X        case BIN_BREAK:
  1114. X            breaks = (num == -1) ? 1 : num;
  1115. X            break;
  1116. X        case BIN_LOGOUT:
  1117. X            if (!islogin)
  1118. X                {
  1119. X                zerrnam(name,"not login shell",NULL,0);
  1120. X                return 1;
  1121. X                }
  1122. X        case BIN_EXIT:
  1123. X            zexit((num == -1) ? lastval : num);
  1124. X            break;
  1125. X        case BIN_RETURN:
  1126. X            retflag = 1;
  1127. X            return lastval = (num == -1) ? lastval : num;
  1128. X        case BIN_SHIFT:
  1129. X            {
  1130. X            char **s;
  1131. X
  1132. X            if (num == -1)
  1133. X                num = 1;
  1134. X            if (num > arrlen(pparams))
  1135. X                num = arrlen(pparams);
  1136. X            permalloc();
  1137. X            s = arrdup(pparams+num);
  1138. X            heapalloc();
  1139. X            freearray(pparams);
  1140. X            pparams = s;
  1141. X            break;
  1142. X            }
  1143. X        }
  1144. X    return 0;
  1145. X}
  1146. X
  1147. X/* bg, disown, fg, jobs, wait */
  1148. X
  1149. Xint bin_fg(name,argv,ops,func) /**/
  1150. Xchar *name;char **argv;char *ops;int func;
  1151. X{
  1152. Xint job,lng,firstjob = -1,retval = 0;
  1153. X
  1154. X    if (ops['Z']) { if (*argv) strcpy(hackzero,*argv); return 0; }
  1155. X    lng = (ops['l']) ? 1 : (ops['p']) ? 2 : 0;
  1156. X    if ((func == BIN_FG || func == BIN_BG) && !jobbing)
  1157. X        {
  1158. X        zerrnam(name,"no job control in this shell.",NULL,0);
  1159. X        return 1;
  1160. X        }
  1161. X    if (!(jobtab[curjob].stat & STAT_INUSE))
  1162. X        {
  1163. X        curjob = prevjob; setprevjob();
  1164. X        if (!(jobtab[curjob].stat & STAT_INUSE))
  1165. X            curjob = prevjob; setprevjob();
  1166. X        }
  1167. X    if (func == BIN_JOBS)
  1168. X        stopmsg = 2;
  1169. X    if (!*argv)
  1170. X        if (func == BIN_FG || func == BIN_BG)
  1171. X            {
  1172. X            if (curjob == -1 || curjob == thisjob)
  1173. X                {
  1174. X                zerrnam(name,"no current job",NULL,0);
  1175. X                return 1;
  1176. X                }
  1177. X            firstjob = curjob;
  1178. X            }
  1179. X        else if (func == BIN_JOBS)
  1180. X            {
  1181. X            for (job = 0; job != MAXJOB; job++)
  1182. X                if (job != thisjob && jobtab[job].stat)
  1183. X                    printjob(job+jobtab,lng);
  1184. X            return 0;
  1185. X            }
  1186. X        else
  1187. X            {
  1188. X            for (job = 0; job != MAXJOB; job++)
  1189. X                if (job != thisjob && jobtab[job].stat)
  1190. X                    waitjob(job);
  1191. X            return lastval;
  1192. X            }
  1193. X    for (; (firstjob != -1) || *argv; ( void ) (*argv && argv++))
  1194. X        {
  1195. X        int stopped,ocj = thisjob;
  1196. X
  1197. X        job = (*argv) ? getjob(*argv,name) : firstjob;
  1198. X        firstjob = -1;
  1199. X        if (job == -1)
  1200. X            break;
  1201. X        if (!(jobtab[job].stat & STAT_INUSE))
  1202. X            {
  1203. X            zerrnam(name,"no such job: %d",0,job);
  1204. X            return 1;
  1205. X            }
  1206. X        switch (func)
  1207. X            {
  1208. X            case BIN_FG:
  1209. X            case BIN_BG:
  1210. X                if (stopped = (jobtab[job].stat & STAT_STOPPED))
  1211. X                    makerunning(jobtab+job);
  1212. X                else if (func == BIN_BG)
  1213. X                    {
  1214. X                    zerrnam(name,"job already in background",NULL,0);
  1215. X                    thisjob = ocj;
  1216. X                    return 1;
  1217. X                    }
  1218. X                if (curjob == job)
  1219. X                    {
  1220. X                    curjob = prevjob;
  1221. X                    prevjob = (func == BIN_BG) ? -1 : job;
  1222. X                    }
  1223. X                if (prevjob == job)
  1224. X                    prevjob = -1;
  1225. X                if (prevjob == -1)
  1226. X                    setprevjob();
  1227. X                if (curjob == -1)
  1228. X                    {
  1229. X                    curjob = prevjob;
  1230. X                    setprevjob();
  1231. X                    }
  1232. X                printjob(jobtab+job,(stopped) ? -1 : 0);
  1233. X                if (func == BIN_FG)
  1234. X                    {
  1235. X                    thisjob = job;
  1236. X                    if (strcmp(jobtab[job].cwd,cwd))
  1237. X                        {
  1238. X                        printf("(pwd : ");
  1239. X                        printdir(jobtab[job].cwd);
  1240. X                        printf(")\n");
  1241. X                        }
  1242. X                    fflush(stdout);
  1243. X                    attachtty(jobtab[job].gleader);
  1244. X                    }
  1245. X                if (stopped)
  1246. X                    kill(-jobtab[job].gleader,SIGCONT);
  1247. X                if (func == BIN_FG)
  1248. X                    waitjobs();
  1249. X                break;
  1250. X            case BIN_JOBS:
  1251. X                printjob(job+jobtab,lng);
  1252. X                break;
  1253. X            case BIN_WAIT:
  1254. X                waitjob(job);
  1255. X                retval = lastval;
  1256. X                break;
  1257. X            case BIN_DISOWN:
  1258. X                {
  1259. X                static struct job zero;
  1260. X                jobtab[job] = zero;
  1261. X                break;
  1262. X                }
  1263. X            }
  1264. X        thisjob = ocj;
  1265. X        }
  1266. X    return retval;
  1267. X}
  1268. X
  1269. X/* false, let */
  1270. X
  1271. Xint bin_let(name,argv,ops,func) /**/
  1272. Xchar *name;char **argv;char *ops;int func;
  1273. X{
  1274. Xlong val = 0;
  1275. X
  1276. X    while (*argv)
  1277. X        val = matheval(*argv++);
  1278. X    return !val;
  1279. X}
  1280. X
  1281. X/* print the directory stack */
  1282. X
  1283. Xstatic void pdstack()
  1284. X{
  1285. XLknode node;
  1286. X
  1287. X    printdir(cwd);
  1288. X    for (node = firstnode(dirstack); node; incnode(node))
  1289. X        {
  1290. X        putchar(' ');
  1291. X        printdir(getdata(node));
  1292. X        }
  1293. X    putchar('\n');
  1294. X}
  1295. X
  1296. X/* exit the shell */
  1297. X
  1298. Xint zexit(val) /**/
  1299. Xint val;
  1300. X{
  1301. X    if (isset(MONITOR))
  1302. X        if (!stopmsg)
  1303. X            {
  1304. X            checkjobs();
  1305. X            if (stopmsg)
  1306. X                {
  1307. X                stopmsg = 2;
  1308. X                return 1;
  1309. X                }
  1310. X            }
  1311. X        else
  1312. X            killrunjobs();
  1313. X    savehistfile(getsparam("HISTFILE"),0);
  1314. X    if (islogin && unset(NORCS))
  1315. X        sourcehome(".zlogout");
  1316. X    if (sigtrapped[SIGEXIT])
  1317. X        dotrap(SIGEXIT);
  1318. X    exit(val); return 0;
  1319. X}
  1320. X
  1321. X/* identify an option name */
  1322. X
  1323. Xint optlookup(s) /**/
  1324. Xchar *s;
  1325. X{
  1326. Xchar *t;
  1327. Xstruct option *o;
  1328. X
  1329. X    t = s = strdup(s);
  1330. X    while (*t)
  1331. X        if (*t == '_')
  1332. X            chuck(t);
  1333. X        else
  1334. X            {
  1335. X            *t = tulower(*t);
  1336. X            t++;
  1337. X            }
  1338. X    for (o = optns; o->name; o++)
  1339. X        if (!strcmp(o->name,s))
  1340. X            return o->id;
  1341. X    return -1;
  1342. X}
  1343. X
  1344. X/* setopt, unsetopt */
  1345. X
  1346. Xint bin_setopt(nam,args,ops,isun) /**/
  1347. Xchar *nam;char **args;char *ops;int isun;
  1348. X{
  1349. Xstruct option *opp;
  1350. Xint c;
  1351. X
  1352. X    if (!ops['@'] && !*args)
  1353. X        {
  1354. X        if (!isun)
  1355. X            prtopt();
  1356. X        return 0;
  1357. X        }
  1358. X    for (opp = optns; opp->name; opp++)
  1359. X        if (ops[opp->id] == 1+isun)
  1360. X            opts[opp->id] = OPT_SET;
  1361. X        else if (ops[opp->id] == 2-isun)
  1362. X            opts[opp->id] = OPT_UNSET;
  1363. X    while (*args)
  1364. X        {
  1365. X        c = optlookup(*args++);
  1366. X        if (c != -1)
  1367. X            {
  1368. X            if (c == INTERACTIVE || c == MONITOR)
  1369. X                zerrnam(nam,"can't change that option",NULL,0);
  1370. X            else
  1371. X                opts[c] = (isun) ? OPT_UNSET : OPT_SET;
  1372. X            }
  1373. X        else
  1374. X            {
  1375. X            zerrnam(nam,"no such option: %s",args[-1],0);
  1376. X            return 1;
  1377. X            }
  1378. X        }
  1379. X    return 0;
  1380. X}
  1381. X
  1382. X/* execute func on each member of the hash table ht */
  1383. X
  1384. Xvoid listhtable(ht,func) /**/
  1385. XHashtab ht;HFunc func;
  1386. X{
  1387. Xint t0;
  1388. Xstruct hashnode *hn;
  1389. X
  1390. X    for (t0 = ht->hsize-1; t0 >= 0; t0--)
  1391. X        for (hn = ht->nodes[t0]; hn; hn = hn->next)
  1392. X            func(hn->nam,hn->dat);
  1393. X}
  1394. X
  1395. X/* print a shell function (used with listhtable) */
  1396. X
  1397. Xvoid pshfunc(s,cc) /**/
  1398. Xchar *s;Cmdnam cc;
  1399. X{
  1400. Xchar *t;
  1401. X
  1402. X    if (cc->type != SHFUNC)
  1403. X        return;
  1404. X    if (showflag && (cc->flags & showflag2) != showflag2)
  1405. X        return;
  1406. X    if (cc->flags & PMFLAG_u)
  1407. X        printf("undefined ");
  1408. X    if (cc->flags & PMFLAG_t)
  1409. X        printf("traced ");
  1410. X    if (!cc->u.list || !showflag)
  1411. X        {
  1412. X        printf("%s ()\n",s);
  1413. X        return;
  1414. X        }
  1415. X    t = gettext((vptr) (cc->u.list),1);
  1416. X    printf("%s () {\n\t%s\n}\n",s,t);
  1417. X    free(t);
  1418. X}
  1419. X
  1420. Xvoid niceprint(s) /**/
  1421. Xchar *s;
  1422. X{
  1423. X    niceprintf(s,stdout);
  1424. X}
  1425. X
  1426. Xvoid niceprintf(s,f) /**/
  1427. Xchar *s;FILE *f;
  1428. X{
  1429. X    for (; *s; s++)
  1430. X        {
  1431. X        if (*s >= 32 && *s <= 126)
  1432. X            fputc(*s,f);
  1433. X        else if (*s == '\n')
  1434. X            {
  1435. X            putc('\\',f);
  1436. X            putc('n',f);
  1437. X            }
  1438. X        else
  1439. X            {
  1440. X            putc('^',f);
  1441. X            fputc(*s | 0x40,f);
  1442. X            }
  1443. X        }
  1444. X}
  1445. X
  1446. Xint bin_umask(nam,args,ops,func) /**/
  1447. Xchar *nam;char **args;char *ops;int func;
  1448. X{
  1449. Xint um;
  1450. Xchar *s = *args;
  1451. X
  1452. X    um = umask(0);
  1453. X    umask(um);
  1454. X    if (!s)
  1455. X        {
  1456. X        printf("%03o\n",um);
  1457. X        return 0;
  1458. X        }
  1459. X    if (idigit(*s))
  1460. X        {
  1461. X        um = zstrtol(s,&s,8);
  1462. X        if (*s)
  1463. X            {
  1464. X            zerrnam(nam,"bad umask",NULL,0);
  1465. X            return 1;
  1466. X            }
  1467. X        }
  1468. X    else
  1469. X        {
  1470. X        int whomask,op,mask;
  1471. X
  1472. X        for (;;)
  1473. X            {
  1474. X            if (*s == 'u')
  1475. X                s++, whomask = 0100;
  1476. X            else if (*s == 'g')
  1477. X                s++, whomask = 0010;
  1478. X            else if (*s == 'o')
  1479. X                s++, whomask = 0001;
  1480. X            else
  1481. X                whomask = 0111;
  1482. X            op = *s++;
  1483. X            if (!(op == '+' || op == '-' || op == '='))
  1484. X                {
  1485. X                zerrnam(nam,"bad symbolic mode operator: %c",NULL,op);
  1486. X                return 1;
  1487. X                }
  1488. X            mask = whomask;
  1489. X            if (*s == 'r')
  1490. X                mask *= 04;
  1491. X            else if (*s == 'w')
  1492. X                mask *= 02;
  1493. X            else if (*s != 'x')
  1494. X                {
  1495. X                zerrnam(nam,"bad symbolic mode permission: %c",NULL,*s);
  1496. X                return 1;
  1497. X                }
  1498. X            if (op == '+')
  1499. X                um |= mask;
  1500. X            else if (op == '-')
  1501. X                um &= ~mask;
  1502. X            else /* op == '=' */
  1503. X                um = (um & ~(whomask*07)) | mask;
  1504. X            if (*++s == ',')
  1505. X                s++;
  1506. X            else
  1507. X                break;
  1508. X            }
  1509. X        if (*s)
  1510. X            {
  1511. X            zerrnam(nam,"bad character in symbolic mode: %c",NULL,*s);
  1512. X            return 1;
  1513. X            }
  1514. X        }
  1515. X    umask(um);
  1516. X    return 0;
  1517. X}
  1518. X
  1519. X/* type, whence, which */
  1520. X
  1521. Xint bin_whence(nam,argv,ops,func) /**/
  1522. Xchar *nam;char **argv;char *ops;int func;
  1523. X{
  1524. Xstruct cmdnam *chn;
  1525. Xstruct alias *a;
  1526. Xint retval = 0,v = ops['v'];
  1527. Xchar *cnam;
  1528. X
  1529. X    for (; *argv; argv++)
  1530. X        {
  1531. X        if (!ops['p'] && (a = (Alias) gethnode(*argv,aliastab)) && a->cmd)
  1532. X            {
  1533. X            if (a->cmd < 0)
  1534. X                printf((v) ? "%s is a reserved word\n" : "%s\n",*argv);
  1535. X            else if (!v)
  1536. X                puts(a->text);
  1537. X            else if (a->cmd)
  1538. X                printf("%s is an alias for %s\n",*argv,a->text);
  1539. X            else
  1540. X                printf("%s is a global alias for %s\n",*argv,a->text);
  1541. X            retval = 0;
  1542. X            }
  1543. X        else if (!ops['p'] && (chn = (Cmdnam) gethnode(*argv,cmdnamtab)) &&
  1544. X                (chn->type == SHFUNC || chn->type == BUILTIN))
  1545. X            {
  1546. X            if (chn->type == SHFUNC)
  1547. X                printf((v) ? "%s is a function\n" : "%s\n",*argv);
  1548. X            else
  1549. X                printf((v) ? "%s is a shell builtin\n" : "%s\n",*argv);
  1550. X            retval = 0;
  1551. X            }
  1552. X        else if (!(cnam = findcmd(*argv)))
  1553. X            {
  1554. X            if (v)
  1555. X                printf("%s not found\n",*argv);
  1556. X            retval = 1;
  1557. X            }
  1558. X        else
  1559. X            {
  1560. X            if (v)
  1561. X                printf("%s is %s\n",*argv,cnam);
  1562. X            else
  1563. X                puts(cnam);
  1564. X            retval = 0;
  1565. X            }
  1566. X        }
  1567. X    return retval;
  1568. X}
  1569. X
  1570. X/* cd, chdir, pushd, popd */
  1571. X
  1572. Xint bin_cd(nam,argv,ops,func) /**/
  1573. Xchar *nam;char **argv;char *ops;int func;
  1574. X{
  1575. Xchar *dest;
  1576. X
  1577. X    if (func == BIN_CD && isset(AUTOPUSHD))
  1578. X        func = BIN_PUSHD;
  1579. X    dest = cd_get_dest(nam,argv,ops,func);
  1580. X    if (!dest) return 1;
  1581. X    dest = cd_do_chdir(nam,dest);
  1582. X    if (!dest) return 1;
  1583. X    cd_new_pwd(func,dest);
  1584. X    return 0;
  1585. X}
  1586. X
  1587. Xchar *cd_get_dest(nam,argv,ops,func) /**/
  1588. Xchar *nam;char **argv;char *ops;int func;
  1589. X{
  1590. Xchar *dest;
  1591. X
  1592. X    if (!argv[0])
  1593. X        if (func == BIN_CD || (func == BIN_PUSHD && isset(PUSHDTOHOME)
  1594. X                || !full(dirstack)))
  1595. X            dest = ztrdup(home);
  1596. X        else
  1597. X            dest = getnode(dirstack);
  1598. X    else if (!argv[1]) {
  1599. X        Lknode n;
  1600. X        int dd;
  1601. X
  1602. X        if (argv[0][1] && argv[0][0] == (isset(PUSHDMINUS) ? '-' : '+')) {
  1603. X            dd = atoi(argv[0]+1)-1;
  1604. X            if (dd < 0) {
  1605. X                zerrnam(nam,"bad directory specification",NULL,0);
  1606. X                return NULL;
  1607. X            }
  1608. X            for (n = firstnode(dirstack); n && dd; dd--, incnode(n));
  1609. X            if (!n) {
  1610. X                zerrnam(nam,"no such entry in dir stack",NULL,0);
  1611. X                return NULL;
  1612. X            }
  1613. X            dest = remnode(dirstack,n);
  1614. X        } else if (argv[0][1] && argv[0][0] == (isset(PUSHDMINUS) ? '+' : '-')) {
  1615. X            dd = atoi(argv[0]+1);
  1616. X            for (n = lastnode(dirstack); n != (Lknode) dirstack && dd;
  1617. X                    dd--, n = prevnode(n));
  1618. X            if (n == (Lknode) dirstack) {
  1619. X                zerrnam(nam,"no such entry in dir stack",NULL,0);
  1620. X                return NULL;
  1621. X            }
  1622. X            dest = remnode(dirstack,n);
  1623. X        } else
  1624. X            dest = ztrdup(strcmp(argv[0],"-") ? argv[0] : oldpwd);
  1625. X    } else {
  1626. X        char *u;
  1627. X        int len1,len2,len3;
  1628. X
  1629. X        if (!(u = ztrstr(cwd,argv[0]))) {
  1630. X            zerrnam(nam,"string not in pwd: %s",argv[1],0);
  1631. X            return NULL;
  1632. X        }
  1633. X        len1 = strlen(argv[0]);
  1634. X        len2 = strlen(argv[1]);
  1635. X        len3 = u-cwd;
  1636. X        dest = zalloc(len3+len2+strlen(u+len1)+1);
  1637. X        strncpy(dest,cwd,len3);
  1638. X        strcpy(dest+len3,argv[1]);
  1639. X        strcat(dest,u+len1);
  1640. X    }
  1641. X    return dest;
  1642. X}
  1643. X
  1644. Xchar *cd_do_chdir(nam,dest) /**/
  1645. Xchar *nam; char *dest;
  1646. X{
  1647. Xstatic char buf[MAXPATHLEN], buf2[MAXPATHLEN];
  1648. Xstruct stat sbuf, tbuf;
  1649. Xint origerr, val, t0;
  1650. X
  1651. X    if (*dest == '/') {
  1652. X        convertwd(dest,buf);
  1653. X        free(dest);
  1654. X        val = chdir(buf);
  1655. X        if (val == -1) {
  1656. X            zerrnam(nam,"%e: %s",dest,errno);
  1657. X            free(dest);
  1658. X            return NULL;
  1659. X        }
  1660. X        return buf;
  1661. X    }
  1662. X    for (t0 = -1;; t0++) {
  1663. X        if (t0 == -1) {
  1664. X            sprintf(buf2,"%s/%s",cwd,dest);
  1665. X            strcpy(buf,dest);
  1666. X        } else {
  1667. X            if (!cdpath[t0]) break;
  1668. X            sprintf(buf2,"%s/%s",cdpath[t0],dest);
  1669. X            if (!strncmp(buf2,"../",3))
  1670. X                sprintf(buf2,"%s/%s/%s",cwd,cdpath[t0],dest);
  1671. X        }
  1672. X        convertwd(buf2,buf);
  1673. X        val = chdir(dest);
  1674. X        if (t0 == -1) origerr = errno;
  1675. X        if (val != -1) {
  1676. X            if (stat(buf,&sbuf) == -1)
  1677. X                if (errno == ENOENT) continue;
  1678. X                else break;
  1679. X            if (stat(".",&tbuf) == -1) break;
  1680. X            if (sbuf.st_dev == tbuf.st_dev && sbuf.st_ino == tbuf.st_ino)
  1681. X                break;
  1682. X            chdir(buf);
  1683. X            break;
  1684. X        } else {
  1685. X            val = chdir(buf);
  1686. X            if (val != -1) break;
  1687. X        }
  1688. X    }
  1689. X    if (t0 > -1 && !cdpath[t0]) {
  1690. X        char *s;
  1691. X        if (isset(CDABLEVARS) &&
  1692. X                (s = getsparam(dest)) && *s == '/' && chdir(s) != -1)
  1693. X            strcpy(buf,s);
  1694. X        else {
  1695. X            zerrnam(nam,"%e: %s",dest,origerr);
  1696. X            free(dest);
  1697. X            return NULL;
  1698. X        }
  1699. X    }
  1700. X    free(dest);
  1701. X    if (t0 > -1) {
  1702. X        printdir(buf);
  1703. X        putchar('\n');
  1704. X    }
  1705. X    return buf;
  1706. X}
  1707. X
  1708. Xvoid cd_new_pwd(func,s) /**/
  1709. Xint func; char *s;
  1710. X{
  1711. XParam pm;
  1712. XList l;
  1713. X
  1714. X    oldpwd = cwd;
  1715. X    if (isset(CHASELINKS))
  1716. X        cwd = findcwd(s);
  1717. X    else
  1718. X        cwd = ztrdup(s);
  1719. X    if ((pm = gethnode("PWD", paramtab)) &&
  1720. X         (pm->flags & PMFLAG_x) && pm->env)
  1721. X        pm->env = replenv(pm->env,cwd);
  1722. X    if ((pm = gethnode("OLDPWD", paramtab)) &&
  1723. X         (pm->flags & PMFLAG_x) && pm->env)
  1724. X        pm->env = replenv(pm->env,oldpwd);
  1725. X    if (func == BIN_PUSHD) {
  1726. X        permalloc();
  1727. X        pushnode(dirstack,oldpwd);
  1728. X        heapalloc();
  1729. X    }
  1730. X    if (unset(PUSHDSILENT) && func != BIN_CD && isset(INTERACTIVE))
  1731. X        pdstack();
  1732. X    if (l = getshfunc("chpwd"))
  1733. X        newrunlist(l);
  1734. X    if (dirstacksize != -1 && countnodes(dirstack) >= dirstacksize) {
  1735. X        if (dirstacksize < 2)
  1736. X            dirstacksize = 2;
  1737. X        else
  1738. X            free(remnode(dirstack,lastnode(dirstack)));
  1739. X    }
  1740. X}
  1741. X
  1742. Xvoid convertwd(s,t) /**/
  1743. Xchar *s; char *t;
  1744. X{
  1745. Xchar *u,*start;
  1746. X
  1747. X    *t++ = '/';
  1748. X    start = t;
  1749. X    for (;;) {
  1750. X        while (*s == '/') s++;
  1751. X        for (u = s; *u && *u != '/'; u++);
  1752. X        if (!strncmp(s,".",u-s)) {
  1753. X            ;
  1754. X        } else if (!strncmp(s,"..",u-s)) {
  1755. X            while (t != start && *--t != '/');
  1756. X        } else {
  1757. X            if (t != start) *t++ = '/';
  1758. X            struncpy(&t,s,u-s);
  1759. X        }
  1760. X        if (!*u) break;
  1761. X        s = u;
  1762. X    }
  1763. X    *t = '\0';
  1764. X}
  1765. X
  1766. Xint bin_rehash(name,argv,ops,func) /**/
  1767. Xchar *name;char **argv;char *ops;int func;
  1768. X{
  1769. X    newcmdnamtab();
  1770. X    return 0;
  1771. X}
  1772. X
  1773. Xint bin_hash(name,argv,ops,func) /**/
  1774. Xchar *name;char **argv;char *ops;int func;
  1775. X{
  1776. Xstruct cmdnam *chn;
  1777. X
  1778. X    chn = (Cmdnam) zcalloc(sizeof *chn);
  1779. X    chn->type = EXCMD_PREDOT;
  1780. X    chn->u.nam = ztrdup(argv[1]);
  1781. X    addhnode(ztrdup(argv[0]),chn,cmdnamtab,freecmdnam);
  1782. X    return 0;
  1783. X}
  1784. X
  1785. X/* != 0 if s is a prefix of t */
  1786. X
  1787. Xint prefix(s,t) /**/
  1788. Xchar *s;char *t;
  1789. X{
  1790. X    while (*s && *t && *s == *t) s++,t++;
  1791. X    return (!*s);
  1792. X}
  1793. X
  1794. X/* convert %%, %1, %foo, %?bar? to a job number */
  1795. X
  1796. Xint getjob(s,prog) /**/
  1797. Xchar *s;char *prog;
  1798. X{
  1799. Xint t0,retval;
  1800. X
  1801. X    if (*s != '%')
  1802. X        goto jump;
  1803. X    s++;
  1804. X    if (*s == '%' || *s == '+' || !*s)
  1805. X        {
  1806. X        if (curjob == -1)
  1807. X            {
  1808. X            zerrnam(prog,"no current job",NULL,0);
  1809. X            retval = -1; goto done;
  1810. X            }
  1811. X        retval = curjob; goto done;
  1812. X        }
  1813. X    if (*s == '-')
  1814. X        {
  1815. X        if (prevjob == -1)
  1816. X            {
  1817. X            zerrnam(prog,"no previous job",NULL,0);
  1818. X            retval = -1; goto done;
  1819. X            }
  1820. X        retval = prevjob; goto done;
  1821. X        }
  1822. X    if (idigit(*s))
  1823. X        {
  1824. X        t0 = atoi(s);
  1825. X        if (t0 && t0 < MAXJOB && jobtab[t0].stat && t0 != thisjob)
  1826. X            { retval = t0; goto done; }
  1827. X        zerrnam(prog,"no such job",NULL,0);
  1828. X        retval = -1; goto done;
  1829. X        }
  1830. X    if (*s == '?')
  1831. X        {
  1832. X        struct process *pn;
  1833. X
  1834. X        for (t0 = MAXJOB-1; t0 >= 0; t0--)
  1835. X            if (jobtab[t0].stat && t0 != thisjob)
  1836. X                for (pn = jobtab[t0].procs; pn; pn = pn->next)
  1837. X                    if (ztrstr(pn->text,s+1))
  1838. X                        { retval = t0; goto done; }
  1839. X        zerrnam(prog,"job not found: %s",s,0);
  1840. X        retval = -1; goto done;
  1841. X        }
  1842. Xjump:
  1843. X    if ((t0 = findjobnam(s)) != -1)
  1844. X        { retval = t0; goto done; }
  1845. X    zerrnam(prog,"job not found: %s",s,0);
  1846. X    retval = -1;
  1847. Xdone:
  1848. X    return retval;
  1849. X}
  1850. X
  1851. X/* find a job named s */
  1852. X
  1853. Xint findjobnam(s) /**/
  1854. Xchar *s;
  1855. X{
  1856. Xint t0;
  1857. X
  1858. X    for (t0 = MAXJOB-1; t0 >= 0; t0--)
  1859. X        if (jobtab[t0].stat && jobtab[t0].procs && t0 != thisjob && 
  1860. X                jobtab[t0].procs->text && prefix(s,jobtab[t0].procs->text))
  1861. X            return t0;
  1862. X    return -1;
  1863. X}
  1864. X
  1865. Xint bin_kill(nam,argv,ops,func) /**/
  1866. Xchar *nam;char **argv;char *ops;int func;
  1867. X{
  1868. Xint sig = SIGTERM;
  1869. X
  1870. X    if (*argv && **argv == '-')
  1871. X        {
  1872. X        if (idigit((*argv)[1]))
  1873. X            sig = atoi(*argv+1);
  1874. X        else
  1875. X            {
  1876. X            if ((*argv)[1] == 'l' && (*argv)[2] == '\0')
  1877. X                {
  1878. X                printf("%s",sigs[1]);
  1879. X                for (sig = 2; sig != SIGCOUNT; sig++)
  1880. X                    printf(" %s",sigs[sig]);
  1881. X                putchar('\n');
  1882. X                return 0;
  1883. X                }
  1884. X            for (sig = 0; sig != SIGCOUNT; sig++)
  1885. X                if (!strcmp(sigs[sig],*argv+1))
  1886. X                    break;
  1887. X            if (sig == SIGCOUNT)
  1888. X                {
  1889. X                zerrnam(nam,"unknown signal: SIG%s",*argv+1,0);
  1890. X                zerrnam(nam,"type kill -l for a List of signals",NULL,0);
  1891. X                return 1;
  1892. X                }
  1893. X            }
  1894. X        argv++;
  1895. X        }
  1896. X    while (*argv)
  1897. X        {
  1898. X        if (**argv == '%')
  1899. X            {
  1900. X            int p = getjob(*argv,"kill");
  1901. X
  1902. X            if (p == -1)
  1903. X                return 1;
  1904. X            if (killjb(jobtab+p,sig) == -1)
  1905. X                {
  1906. X                zerrnam("kill","kill failed: %e",NULL,errno);
  1907. X                return 1;
  1908. X                }
  1909. X            if (jobtab[p].stat & STAT_STOPPED)
  1910. X                {
  1911. X                if (sig == SIGCONT)
  1912. X                    jobtab[p].stat &= ~STAT_STOPPED;
  1913. X                if (sig != SIGKILL && sig != SIGCONT && sig != SIGTSTP
  1914. X                        && sig != SIGTTOU && sig != SIGTTIN && sig != SIGSTOP)
  1915. X                    killjb(jobtab+p,SIGCONT);
  1916. X                }
  1917. X            }
  1918. X        else
  1919. X            if (kill(atoi(*argv),sig) == -1)
  1920. X                {
  1921. X                zerrnam("kill","kill failed: %e",NULL,errno);
  1922. X                return 1;
  1923. X                }
  1924. X        argv++;
  1925. SHAR_EOF
  1926. true || echo 'restore of zsh2.1/src/builtin.c failed'
  1927. fi
  1928. echo 'End of zsh2.1.0 part 4'
  1929. echo 'File zsh2.1/src/builtin.c is continued in part 5'
  1930. echo 5 > _shar_seq_.tmp
  1931. exit 0
  1932.  
  1933. exit 0 # Just in case...
  1934. -- 
  1935. Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
  1936. Sterling Software, IMD           UUCP:     uunet!sparky!kent
  1937. Phone:    (402) 291-8300         FAX:      (402) 291-4362
  1938. Please send comp.sources.misc-related mail to kent@uunet.uu.net.
  1939.