home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 2 / 2321 < prev    next >
Encoding:
Internet Message Format  |  1990-12-28  |  75.1 KB

  1. From: pfalstad@phoenix.Princeton.EDU (Paul John Falstad)
  2. Newsgroups: alt.sources
  3. Subject: zsh - ksh/tcsh-like shell (part 2 of 8)
  4. Message-ID: <4743@idunno.Princeton.EDU>
  5. Date: 14 Dec 90 23:29:51 GMT
  6.  
  7. ---cut here---cut here---cut here---
  8. -bash(1),
  9. -ksh(1),
  10. -cat(1),
  11. -cd(1),
  12. -chmod(1),
  13. -cut(1),
  14. -echo(1),
  15. -emacs(1),
  16. -env(1),
  17. -gmacs(1),
  18. -newgrp(1),
  19. -stty(1),
  20. -test(1),
  21. -umask(1),
  22. -vi(1),
  23. -dup(2),
  24. -exec(2),
  25. -fork(2),
  26. -ioctl(2),
  27. -lseek(2),
  28. -paste(1),
  29. -pipe(2),
  30. -signal(2),
  31. -umask(2),
  32. -ulimit(2),
  33. -wait(2),
  34. -rand(3),
  35. -a.out(5),
  36. -profile(5),
  37. -environ(7),
  38. -xtetris(6).
  39. -.SH AUTHOR
  40. -Paul Falstad <pfalstad@phoenix.princeton.edu>
  41. -.PP
  42. -The command line editor is a hacked-up version
  43. -of the GNU readline library,
  44. -written by Brian Fox (<bfox@ai.MIT.Edu>) of the Free
  45. -Software Foundation.  This shell is therefore
  46. -under the GNU public license.  I eventually plan
  47. -to write my own command line editor to make everything
  48. -my own code, but \fBzsh\fP will probably still be under
  49. -the GPL, or perhaps something less restrictive.
  50. -.SH CAVEATS
  51. -.PP
  52. -Using
  53. -.B fc
  54. -built-in command within a compound command will cause the whole
  55. -command to disappear from the history file.
  56. -.PP
  57. -Shell functions are put in the function table when their declarations
  58. -are parsed, not when they are executed.  Thus function declarations
  59. -inside \fBif\fP clauses, for example, will not work as expected.
  60. -(This is a bug, not a caveat.)
  61. -.PP
  62. -The command line editor gets confused if you have termcap sequences
  63. -(like %S) in your prompt.
  64. -.PP
  65. -The main shell does not get along with the command line editor.
  66. -One of them will have to go.
  67. -.PP
  68. -Use of this shell is reserved for faculty, staff,
  69. -graduate students,
  70. -and special guests
  71. -of the Princeton University 
  72. -Computer Science department.
  73. End of zsh.1
  74. echo COPYING 1>&2
  75. sed 's/^-//' >COPYING <<'End of COPYING'
  76. -
  77. -            GNU GENERAL PUBLIC LICENSE
  78. -             Version 1, February 1989
  79. -
  80. - Copyright (C) 1989 Free Software Foundation, Inc.
  81. -                    675 Mass Ave, Cambridge, MA 02139, USA
  82. - Everyone is permitted to copy and distribute verbatim copies
  83. - of this license document, but changing it is not allowed.
  84. -
  85. -                Preamble
  86. -
  87. -  The license agreements of most software companies try to keep users
  88. -at the mercy of those companies.  By contrast, our General Public
  89. -License is intended to guarantee your freedom to share and change free
  90. -software--to make sure the software is free for all its users.  The
  91. -General Public License applies to the Free Software Foundation's
  92. -software and to any other program whose authors commit to using it.
  93. -You can use it for your programs, too.
  94. -
  95. -  When we speak of free software, we are referring to freedom, not
  96. -price.  Specifically, the General Public License is designed to make
  97. -sure that you have the freedom to give away or sell copies of free
  98. -software, that you receive source code or can get it if you want it,
  99. -that you can change the software or use pieces of it in new free
  100. -programs; and that you know you can do these things.
  101. -
  102. -  To protect your rights, we need to make restrictions that forbid
  103. -anyone to deny you these rights or to ask you to surrender the rights.
  104. -These restrictions translate to certain responsibilities for you if you
  105. -distribute copies of the software, or if you modify it.
  106. -
  107. -  For example, if you distribute copies of a such a program, whether
  108. -gratis or for a fee, you must give the recipients all the rights that
  109. -you have.  You must make sure that they, too, receive or can get the
  110. -source code.  And you must tell them their rights.
  111. -
  112. -  We protect your rights with two steps: (1) copyright the software, and
  113. -(2) offer you this license which gives you legal permission to copy,
  114. -distribute and/or modify the software.
  115. -
  116. -  Also, for each author's protection and ours, we want to make certain
  117. -that everyone understands that there is no warranty for this free
  118. -software.  If the software is modified by someone else and passed on, we
  119. -want its recipients to know that what they have is not the original, so
  120. -that any problems introduced by others will not reflect on the original
  121. -authors' reputations.
  122. -
  123. -  The precise terms and conditions for copying, distribution and
  124. -modification follow.
  125. -
  126. -            GNU GENERAL PUBLIC LICENSE
  127. -   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
  128. -
  129. -  0. This License Agreement applies to any program or other work which
  130. -contains a notice placed by the copyright holder saying it may be
  131. -distributed under the terms of this General Public License.  The
  132. -"Program", below, refers to any such program or work, and a "work based
  133. -on the Program" means either the Program or any work containing the
  134. -Program or a portion of it, either verbatim or with modifications.  Each
  135. -licensee is addressed as "you".
  136. -
  137. -  1. You may copy and distribute verbatim copies of the Program's source
  138. -code as you receive it, in any medium, provided that you conspicuously and
  139. -appropriately publish on each copy an appropriate copyright notice and
  140. -disclaimer of warranty; keep intact all the notices that refer to this
  141. -General Public License and to the absence of any warranty; and give any
  142. -other recipients of the Program a copy of this General Public License
  143. -along with the Program.  You may charge a fee for the physical act of
  144. -transferring a copy.
  145. -
  146. -  2. You may modify your copy or copies of the Program or any portion of
  147. -it, and copy and distribute such modifications under the terms of Paragraph
  148. -1 above, provided that you also do the following:
  149. -
  150. -    a) cause the modified files to carry prominent notices stating that
  151. -    you changed the files and the date of any change; and
  152. -
  153. -    b) cause the whole of any work that you distribute or publish, that
  154. -    in whole or in part contains the Program or any part thereof, either
  155. -    with or without modifications, to be licensed at no charge to all
  156. -    third parties under the terms of this General Public License (except
  157. -    that you may choose to grant warranty protection to some or all
  158. -    third parties, at your option).
  159. -
  160. -    c) If the modified program normally reads commands interactively when
  161. -    run, you must cause it, when started running for such interactive use
  162. -    in the simplest and most usual way, to print or display an
  163. -    announcement including an appropriate copyright notice and a notice
  164. -    that there is no warranty (or else, saying that you provide a
  165. -    warranty) and that users may redistribute the program under these
  166. -    conditions, and telling the user how to view a copy of this General
  167. -    Public License.
  168. -
  169. -    d) You may charge a fee for the physical act of transferring a
  170. -    copy, and you may at your option offer warranty protection in
  171. -    exchange for a fee.
  172. -
  173. -Mere aggregation of another independent work with the Program (or its
  174. -derivative) on a volume of a storage or distribution medium does not bring
  175. -the other work under the scope of these terms.
  176. -
  177. -  3. You may copy and distribute the Program (or a portion or derivative of
  178. -it, under Paragraph 2) in object code or executable form under the terms of
  179. -Paragraphs 1 and 2 above provided that you also do one of the following:
  180. -
  181. -    a) accompany it with the complete corresponding machine-readable
  182. -    source code, which must be distributed under the terms of
  183. -    Paragraphs 1 and 2 above; or,
  184. -
  185. -    b) accompany it with a written offer, valid for at least three
  186. -    years, to give any third party free (except for a nominal charge
  187. -    for the cost of distribution) a complete machine-readable copy of the
  188. -    corresponding source code, to be distributed under the terms of
  189. -    Paragraphs 1 and 2 above; or,
  190. -
  191. -    c) accompany it with the information you received as to where the
  192. -    corresponding source code may be obtained.  (This alternative is
  193. -    allowed only for noncommercial distribution and only if you
  194. -    received the program in object code or executable form alone.)
  195. -
  196. -Source code for a work means the preferred form of the work for making
  197. -modifications to it.  For an executable file, complete source code means
  198. -all the source code for all modules it contains; but, as a special
  199. -exception, it need not include source code for modules which are standard
  200. -libraries that accompany the operating system on which the executable
  201. -file runs, or for standard header files or definitions files that
  202. -accompany that operating system.
  203. -
  204. -  4. You may not copy, modify, sublicense, distribute or transfer the
  205. -Program except as expressly provided under this General Public License.
  206. -Any attempt otherwise to copy, modify, sublicense, distribute or transfer
  207. -the Program is void, and will automatically terminate your rights to use
  208. -the Program under this License.  However, parties who have received
  209. -copies, or rights to use copies, from you under this General Public
  210. -License will not have their licenses terminated so long as such parties
  211. -remain in full compliance.
  212. -
  213. -  5. By copying, distributing or modifying the Program (or any work based
  214. -on the Program) you indicate your acceptance of this license to do so,
  215. -and all its terms and conditions.
  216. -
  217. -  6. Each time you redistribute the Program (or any work based on the
  218. -Program), the recipient automatically receives a license from the original
  219. -licensor to copy, distribute or modify the Program subject to these
  220. -terms and conditions.  You may not impose any further restrictions on the
  221. -recipients' exercise of the rights granted herein.
  222. -
  223. -  7. The Free Software Foundation may publish revised and/or new versions
  224. -of the General Public License from time to time.  Such new versions will
  225. -be similar in spirit to the present version, but may differ in detail to
  226. -address new problems or concerns.
  227. -
  228. -Each version is given a distinguishing version number.  If the Program
  229. -specifies a version number of the license which applies to it and "any
  230. -later version", you have the option of following the terms and conditions
  231. -either of that version or of any later version published by the Free
  232. -Software Foundation.  If the Program does not specify a version number of
  233. -the license, you may choose any version ever published by the Free Software
  234. -Foundation.
  235. -
  236. -  8. If you wish to incorporate parts of the Program into other free
  237. -programs whose distribution conditions are different, write to the author
  238. -to ask for permission.  For software which is copyrighted by the Free
  239. -Software Foundation, write to the Free Software Foundation; we sometimes
  240. -make exceptions for this.  Our decision will be guided by the two goals
  241. -of preserving the free status of all derivatives of our free software and
  242. -of promoting the sharing and reuse of software generally.
  243. -
  244. -                NO WARRANTY
  245. -
  246. -  9. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
  247. -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
  248. -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
  249. -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
  250. -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  251. -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
  252. -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
  253. -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
  254. -REPAIR OR CORRECTION.
  255. -
  256. -  10. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
  257. -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
  258. -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
  259. -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
  260. -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
  261. -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
  262. -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
  263. -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
  264. -POSSIBILITY OF SUCH DAMAGES.
  265. -
  266. -             END OF TERMS AND CONDITIONS
  267. -
  268. -    Appendix: How to Apply These Terms to Your New Programs
  269. -
  270. -  If you develop a new program, and you want it to be of the greatest
  271. -possible use to humanity, the best way to achieve this is to make it
  272. -free software which everyone can redistribute and change under these
  273. -terms.
  274. -
  275. -  To do so, attach the following notices to the program.  It is safest to
  276. -attach them to the start of each source file to most effectively convey
  277. -the exclusion of warranty; and each file should have at least the
  278. -"copyright" line and a pointer to where the full notice is found.
  279. -
  280. -    <one line to give the program's name and a brief idea of what it does.>
  281. -    Copyright (C) 19yy  <name of author>
  282. -
  283. -    This program is free software; you can redistribute it and/or modify
  284. -    it under the terms of the GNU General Public License as published by
  285. -    the Free Software Foundation; either version 1, or (at your option)
  286. -    any later version.
  287. -
  288. -    This program is distributed in the hope that it will be useful,
  289. -    but WITHOUT ANY WARRANTY; without even the implied warranty of
  290. -    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  291. -    GNU General Public License for more details.
  292. -
  293. -    You should have received a copy of the GNU General Public License
  294. -    along with this program; if not, write to the Free Software
  295. -    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  296. -
  297. -Also add information on how to contact you by electronic and paper mail.
  298. -
  299. -If the program is interactive, make it output a short notice like this
  300. -when it starts in an interactive mode:
  301. -
  302. -    Gnomovision version 69, Copyright (C) 19xx name of author
  303. -    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
  304. -    This is free software, and you are welcome to redistribute it
  305. -    under certain conditions; type `show c' for details.
  306. -
  307. -The hypothetical commands `show w' and `show c' should show the
  308. -appropriate parts of the General Public License.  Of course, the
  309. -commands you use may be called something other than `show w' and `show
  310. -c'; they could even be mouse-clicks or menu items--whatever suits your
  311. -program.
  312. -
  313. -You should also get your employer (if you work as a programmer) or your
  314. -school, if any, to sign a "copyright disclaimer" for the program, if
  315. -necessary.  Here a sample; alter the names:
  316. -
  317. -  Yoyodyne, Inc., hereby disclaims all copyright interest in the
  318. -  program `Gnomovision' (a program to direct compilers to make passes
  319. -  at assemblers) written by James Hacker.
  320. -
  321. -  <signature of Ty Coon>, 1 April 1989
  322. -  Ty Coon, President of Vice
  323. -
  324. -That's all there is to it!
  325. End of COPYING
  326. echo README 1>&2
  327. sed 's/^-//' >README <<'End of README'
  328. -Read "INSTALL" for information on getting this shell running.
  329. -
  330. -zsh is free software.  See the file COPYING for copying permission.
  331. -
  332. -    This shell was "developed" by me, Paul Falstad, a sophomore at Princeton
  333. -University.  I borrowed _heavily_ from ksh, bash, tcsh, sh, and csh, as
  334. -well as adding a few (IMHO) useful features.  zsh was at first intended
  335. -to be a subset of csh for the Commodore Amiga, but the project sort of
  336. -ballooned; now I want it to be a cross between ksh and tcsh.  It should
  337. -be a powerful "command and programming language" that is well-designed
  338. -and logical (like ksh), but it should also be built for humans (like
  339. -tcsh), with all the neat features like spell checking, login/logout
  340. -watching and termcap support that are probably too weird to make it into
  341. -an AT&T product.  This version of the shell has fallen far short of that
  342. -goal; I just wanted to release _something_, because this is obviously
  343. -going to be an extremely long project.
  344. -
  345. -    This is version v1.0 of zsh.  I incorporated the GNU "readline"
  346. -editor, written by Brian Fox, into the shell, just to make my life
  347. -temporarily easier.  I made lots of changes to it, so if there are any
  348. -bugs in the editor, they're probably my fault.  readline will not be a
  349. -part of the next version of zsh.
  350. -
  351. -    If anyone has any questions, suggestions, comments, bugs, flames, or
  352. -any other mail of any kind, send it to pfalstad@phoenix.princeton.edu.
  353. -Thanks to Kartik Subbarao, Daniel Bernstein ("Yay.  So sell it."),
  354. -Kennedy Lemke, Chet Ramey (for the bash man page, and for putting features
  355. -in the man page that weren't in our version of bash), Brian Fox (for
  356. -helping me put off a lot of work, and for writing bash), Richard M. Stallman
  357. -(for gdb and gcc; not for emacs though ;-) ) and many others.
  358. -
  359. End of README
  360. echo INSTALL 1>&2
  361. sed 's/^-//' >INSTALL <<'End of INSTALL'
  362. -I was not able to port zsh to many platforms because I don't have
  363. -accounts on many platforms.  It shouldn't be too much trouble if you
  364. -manage to decipher my code.  I have tested zsh on SunOS 4.1, SunOS 4.0.3,
  365. -4.3BSD UNIX.
  366. -
  367. -You need to edit the files config.h, config.local.h, makefile, and
  368. -readline/Makefile.  The comments should make clear what you have to do.
  369. -Note that the files in the readline directory have been greatly
  370. -modified, so you can't just copy over your changes from bash if you
  371. -have it installed.
  372. -
  373. -Once you have done that, you might be able to do a make without any
  374. -problem.  If you have trouble, and can't get zsh to work, send me mail,
  375. -and I'll try to help.  If anyone manages to get zsh ported to some other
  376. -platform, please mail me so I can tell other people about your changes
  377. -and incorporate them into the next version.
  378. -
  379. End of INSTALL
  380. echo makefile 1>&2
  381. sed 's/^-//' >makefile <<'End of makefile'
  382. -#! /bin/make -f
  383. -#
  384. -#    makefile for zsh
  385. -#
  386. -#    This file is part of zsh, the Z shell.
  387. -#
  388. -#  zsh is free software; no one can prevent you from reading the source
  389. -#  code, or giving it to someone else.
  390. -#  This file is copyrighted under the GNU General Public License, which
  391. -#  can be found in the file called COPYING.
  392. -#
  393. -#  Copyright (C) 1990 Paul Falstad
  394. -#
  395. -#  zsh is distributed in the hope that it will be useful, but
  396. -#  WITHOUT ANY WARRANTY.  No author or distributor accepts
  397. -#  responsibility to anyone for the consequences of using it or for
  398. -#  whether it serves any particular purpose or works at all, unless he
  399. -#  says so in writing.  Refer to the GNU General Public License
  400. -#  for full details.
  401. -#
  402. -#  Everyone is granted permission to copy, modify and redistribute
  403. -#  zsh, but only under the conditions described in the GNU General Public
  404. -#  License.   A copy of this license is supposed to have been given to you
  405. -#  along with zsh so you can know your rights and responsibilities.
  406. -#  It should be in a file named COPYING.
  407. -#
  408. -#  Among other things, the copyright notice and this notice must be
  409. -#  preserved on all copies.
  410. -#
  411. -OBJS=hist.o glob.o table.o subst.o builtin.o loop.o vars.o\
  412. -parse.o lex.o init.o jobs.o exec.o zhistory.o utils.o math.o test.o
  413. -READLINE=readline/funmap.o readline/keymaps.o readline/readline.o
  414. -BINDIR=/usr/local/bin
  415. -MANDIR=/usr/local/man/man1
  416. -CFLAGS=-O -fstrength-reduce -fomit-frame-pointer -finline-functions \
  417. -    -fsigned-char -fdelayed-branch
  418. -CC=gcc
  419. -ZSHPATH=zsh
  420. -THINGS_TO_TAR=zsh.1 COPYING README INSTALL makefile sample.zshrc \
  421. -sample.zlogin sample.zshrc.mine sample.zlogin.mine \
  422. -alias.pro builtin.c builtin.pro config.h config.local.h \
  423. -exec.c exec.pro funcs.h glob.c glob.pro hist.c hist.pro init.c \
  424. -init.pro jobs.c jobs.pro lex.c lex.pro loop.c loop.pro math.c \
  425. -math.pro parse.c parse.pro subst.c subst.pro table.c \
  426. -table.pro test.c test.pro utils.c utils.pro vars.c vars.pro zhistory.c \
  427. -readline/chardefs.h readline/emacs_keymap.c \
  428. -readline/funmap.c readline/history.h readline/keymaps.c \
  429. -readline/keymaps.h readline/readline.c readline/readline.h \
  430. -readline/vi_keymap.c readline/vi_mode.c readline/Makefile \
  431. -zsh.h proto
  432. -
  433. -.c.o:
  434. -    $(CC) $(CFLAGS) -c -o $*.o $<
  435. -
  436. -$(ZSHPATH): $(OBJS) $(READLINE)
  437. -    $(CC) -o $(ZSHPATH) $(OBJS) $(READLINE) -s -ltermcap
  438. -
  439. -$(OBJS): config.h
  440. -
  441. -zhistory.o: readline/history.h
  442. -
  443. -$(READLINE):
  444. -    cd readline;make
  445. -
  446. -clean:
  447. -    rm -f *.o zsh core readline/*.o
  448. -
  449. -install: zsh
  450. -    install -s -m 755 zsh $(BINDIR)
  451. -    install -m 444 zsh.1 $(MANDIR)
  452. -
  453. -tar: zsh.tar.Z
  454. -
  455. -zsh.tar: $(THINGS_TO_TAR)
  456. -    tar -cf zsh.tar $(THINGS_TO_TAR)
  457. -
  458. -zsh.tar.Z: zsh.tar
  459. -    compress -f zsh.tar
  460. -
  461. -shar: $(THINGS_TO_TAR)
  462. -    bundle $(THINGS_TO_TAR) > zsh.shar
  463. -
  464. End of makefile
  465. echo sample.zshrc 1>&2
  466. sed 's/^-//' >sample.zshrc <<'End of sample.zshrc'
  467. -setenv() { export $1=$2 }
  468. -
  469. -umask 022
  470. -
  471. -PATH=$HOME/scr:$HOME/bin/$HOSTTYPE:/usr/local/bin:/usr/ucb:\
  472. -/usr/bin:/bin:/usr/local/bin/X11:/usr/etc:/etc
  473. -CDPATH=$HOME:/usr:/
  474. -export MANPATH=/usr/man:/usr/local/man
  475. -
  476. -HISTSIZE=50
  477. -setopt ignoreeof
  478. -
  479. -PROMPT='%n@%m [%h] %# '
  480. -
  481. -alias a alias
  482. -
  483. -a vi.     'vi ~/.cshrc'
  484. -a s.     '. ~/.cshrc'
  485. -a more. 'more ~/.cshrc'
  486. -
  487. -chpwd() { pwd; ls -F }
  488. -lsl() { ls -algF $* | more }
  489. -
  490. -a back cd -
  491. -a h history
  492. -a cls     /usr/ucb/clear
  493. -a type     cat
  494. -a copy     cp
  495. -a move     mv
  496. -a del     rm
  497. -a lo     exit
  498. -a lsa     'ls -aF'
  499. -a dir   'ls -l'
  500. -a ll    'ls -F'
  501. -
  502. End of sample.zshrc
  503. echo sample.zlogin 1>&2
  504. sed 's/^-//' >sample.zlogin <<'End of sample.zlogin'
  505. -eval $(tset -Q -s '?xterm')
  506. -stty dec crt kill ^U dsusp ^X
  507. -msgs -q
  508. -date
  509. -biff y
  510. -
  511. -WATCH=$(echo $(<~/.friends) | tr ' ' :)
  512. -MAIL=/usr/spool/mail/$USERNAME
  513. -export DISPLAY=$(hostname):0.0
  514. -
  515. -limit coredumpsize 0
  516. -/usr/games/fortune
  517. -uptime
  518. End of sample.zlogin
  519. echo sample.zshrc.mine 1>&2
  520. sed 's/^-//' >sample.zshrc.mine <<'End of sample.zshrc.mine'
  521. -#
  522. -# my rc file for zsh
  523. -#
  524. -PATH=~/scr:~/bin/$HOSTTYPE:/usr/princeton/bin:/usr/ucb:/usr/bin:/bin:\
  525. -/u/maruchck/scr:/u/cs320/bin:/u/maruchck/bin:\
  526. -/usr/princeton/bin/X11:/usr/etc:/etc
  527. -CDPATH=~:~/src/cs320:~/src
  528. -umask 022
  529. -alias a alias
  530. -a pd pushd
  531. -a pop popd
  532. -limit core 0
  533. -a c cp
  534. -a grep egrep
  535. -a ps sps
  536. -a j jobs
  537. -a hide 'ARGV0=$(randline ~/pub/strings) '
  538. -a rn hide /usr/princeton/bin/rn.4.1
  539. -a v mv
  540. -a t cat
  541. -a where hostname'; echo >/dev/null'
  542. -a l ls -AF
  543. -a m make
  544. -a mm hide less 
  545. -a talk hide talk
  546. -a h history
  547. -a a.out ./a.out
  548. -a more less
  549. -a strings strings -
  550. -a lock lock -p
  551. -a nw 'l -ltr | tail'
  552. -a -a 'M' \| less
  553. -a -a 'GF' \| fgrep -f ~/.friends
  554. -a -a 'sub' subbarao
  555. -a -a 'mjm' maruchck
  556. -a -a 'paswd' '<(ypcat passwd)'
  557. -a -a 'cex' '/u/pup/centrex'
  558. -a rable ls -AFltrd '*(R)'
  559. -a nrable ls -AFltrd '*(^R)'
  560. -a ';' vi
  561. -a 0 vi
  562. -a '<<' more
  563. -mostglob egrep sed
  564. -noglob find
  565. -PROMPT='Z %h %M:%~ '
  566. -FCEDIT=vi
  567. -LESSTERM=$(echo $TERMCAP | sed s/:ti=[^:]*:te=[^:]*:/:ti=:te=:/)
  568. -a less TERMCAP='"$LESSTERM"' /usr/princeton/bin/less
  569. -zsh=~/src/zsh
  570. -a k9 kill -9
  571. -cx() { chmod +x $* }
  572. -acx() { chmod 755 $* }
  573. -mere() { nroff -man -Tman $1 | less -s }
  574. -
  575. -[ `tty` = /dev/console ] || {
  576. -    PERIOD=40
  577. -    periodic() {
  578. -        echo checking news...  # check news every 40 minutes
  579. -        rn -c
  580. -    }
  581. -}
  582. -
  583. -randline() {
  584. -    integer z;
  585. -    z=$(wc -l <$1)
  586. -    sed -n $[RANDOM%z+1]p $1
  587. -    unset z
  588. -}
  589. -
  590. -eval "proto () { $(grep -v '^#' ~/scr/proto) }"
  591. -
  592. -snoop() {
  593. -    (( $# )) || set `users`
  594. -    fgrep -i -f </u/pup/st{udents,aff} <(
  595. -        for i
  596. -        do
  597. -            ypmatch $i passwd
  598. -        done | cut -d: -f5 | cut -d, -f1 |
  599. -            awk '{ printf "%s,%s\n",$NF,substr($1,1,1) }') 
  600. -}
  601. -
  602. -MAIL=/usr/spool/mail/pfalstad
  603. -MAILCHECK=30
  604. -HISTSIZE=600
  605. -setopt notify globdots autolist correct dextract pushdtohome cdablevars
  606. -unsetopt bgnice
  607. -WATCH=$(echo $(<~/.friends) | tr ' ' :)
  608. -WATCHFMT='%n %a %l from %m at %t.'
  609. -LOGCHECK=0
  610. -
  611. -[ -t ] && {
  612. -    (cd ; hostname >! .where)
  613. -}
  614. -
  615. -export MANPATH=/usr/man:/usr/princeton/man:/u/cad/man
  616. -
  617. -setenv() { export $1=$2 }
  618. -
  619. End of sample.zshrc.mine
  620. echo sample.zlogin.mine 1>&2
  621. sed 's/^-//' >sample.zlogin.mine <<'End of sample.zlogin.mine'
  622. -#
  623. -# my login file for zsh
  624. -#
  625. -cd
  626. -ls -l /etc/motd
  627. -stty dec new cr0
  628. -eval $(tset -s -Q '?xterm')
  629. -stty -tabs
  630. -umask 022
  631. -export MAIL=/usr/spool/mail/$USER
  632. -MAILCHECK=60
  633. -# biff y
  634. -msgs -fp
  635. -uptime
  636. -/usr/games/fortune
  637. -log
  638. -echo Thought for the day: $(randline ~/pub/commands)
  639. -from 2>/dev/null
  640. -cat .todo
  641. -cat '. '
  642. -echo last login $(date) on $(hostname) >! .' '
  643. End of sample.zlogin.mine
  644. echo alias.pro 1>&2
  645. sed 's/^-//' >alias.pro <<'End of alias.pro'
  646. -char *dynread(char stop);
  647. -int filesub(void **namptr);
  648. -char *gethome(char *user,int len);
  649. -char *completehome(char *user,int len);
  650. -char *getsparmval(char *s,int len);
  651. -void setparml(char *s,int len,char *v);
  652. -void parmsub(table list);
  653. -void parminsall(table l,Node *nn,char **aptr,char **bptr);
  654. -void comminsall(table l,Node *nn,char **aptr,char **bptr);
  655. -void parmsuber(void **aptr,char **bptr);
  656. -void modify(void **str,char **ptr);
  657. -void tabmodify(table tab,char **ptr);
  658. -int napply(int (*func)(void **),table list);
  659. -int napplysplit(int (*func)(void **),table list);
  660. -void split(Node node,table list);
  661. -char *dstackent(int val);
  662. -void doshfuncs(comm comm);
  663. -void execshfunc(comm comm);
  664. -struct anode *mkanode(char *txt,int cmflag);
  665. -char *docompsubs(char *str,int *i);
  666. -void docmdsubs(char **str);
  667. -void dovarsubs(char **str);
  668. End of alias.pro
  669. echo builtin.c 1>&2
  670. sed 's/^-//' >builtin.c <<'End of builtin.c'
  671. -/*
  672. -
  673. -    builtin.c - handles builtin commands
  674. -
  675. -    This file is part of zsh, the Z shell.
  676. -
  677. -   zsh is free software; no one can prevent you from reading the source
  678. -   code, or giving it to someone else.
  679. -   This file is copyrighted under the GNU General Public License, which
  680. -   can be found in the file called COPYING.
  681. -
  682. -   Copyright (C) 1990 Paul Falstad
  683. -
  684. -   zsh is distributed in the hope that it will be useful, but
  685. -   WITHOUT ANY WARRANTY.  No author or distributor accepts
  686. -   responsibility to anyone for the consequences of using it or for
  687. -   whether it serves any particular purpose or works at all, unless he
  688. -   says so in writing.  Refer to the GNU General Public License
  689. -   for full details.
  690. -
  691. -   Everyone is granted permission to copy, modify and redistribute
  692. -   zsh, but only under the conditions described in the GNU General Public
  693. -   License.   A copy of this license is supposed to have been given to you
  694. -   along with zsh so you can know your rights and responsibilities.
  695. -   It should be in a file named COPYING.
  696. -
  697. -   Among other things, the copyright notice and this notice must be
  698. -   preserved on all copies.
  699. -
  700. -*/
  701. -
  702. -#include "zsh.h"
  703. -#include "funcs.h"
  704. -#include <sys/signal.h>
  705. -#include <sys/fcntl.h>
  706. -#include <sys/errno.h>
  707. -#include <utmp.h>
  708. -#define MAXPATHLEN 1024
  709. -
  710. -int echo(comm comm)
  711. -{
  712. -table list;
  713. -char *str;
  714. -int nline = 1;
  715. -    list = comm->args;
  716. -    if (full(list))
  717. -        if (!strcmp("--",list->first->dat))
  718. -            free(getnode(list));
  719. -        else if (!strcmp("-n",list->first->dat))
  720. -            {
  721. -            free(getnode(list));
  722. -            nline = 0;
  723. -            }
  724. -    if (str = getnode(list))
  725. -        {
  726. -        printf("%s",str);
  727. -        free(str);
  728. -        while (str = getnode(list))
  729. -            {
  730. -            printf(" %s",str);
  731. -            free(str);
  732. -            }
  733. -        }
  734. -    if (nline)
  735. -        printf("\n");
  736. -    return 0;
  737. -}
  738. -
  739. -/* print the directory stack */
  740. -
  741. -void pdstack(void)
  742. -{
  743. -Node node;
  744. -
  745. -    printdir(cwd);
  746. -    for (node = dirstack->first; node; node = node->next)
  747. -        {
  748. -        putchar(' ');
  749. -        printdir(node->dat);
  750. -        }
  751. -    putchar('\n');
  752. -}
  753. -
  754. -/* exit */
  755. -
  756. -int zexit(comm comm)
  757. -{
  758. -    if (interact)
  759. -        if (!stopmsg)
  760. -            {
  761. -            checkjobs();
  762. -            if (stopmsg)
  763. -                {
  764. -                stopmsg = 2;
  765. -                return 1;
  766. -                }
  767. -            }
  768. -        else
  769. -            killrunjobs();
  770. -    if (islogin && unset(NORCS))
  771. -        sourcehome(".zlogout");
  772. -    if (comm && full(comm->args))
  773. -        lastval = atoi(getnode(comm->args));
  774. -    if (sigtrapped[SIGEXIT])
  775. -        dotrap(SIGEXIT);
  776. -    exit(lastval); return 0;
  777. -}
  778. -
  779. -/* return */
  780. -
  781. -int zreturn(comm comm)
  782. -{
  783. -    if (full(comm->args))
  784. -        lastval = atoi(getnode(comm->args));
  785. -    retflag = 1;
  786. -    return lastval;
  787. -}
  788. -
  789. -int logout(comm comm)
  790. -{
  791. -    if (!islogin)
  792. -        {
  793. -        zerrnam("logout","not login shell");
  794. -        return 1;
  795. -        }
  796. -    return zexit(comm);
  797. -}
  798. -
  799. -int Unset(comm comm)
  800. -{
  801. -table list = comm->args;
  802. -char *s;
  803. -    while (full(list))
  804. -        {
  805. -        s = getnode(list);
  806. -        unsetparm(s);
  807. -        free(s);
  808. -        }
  809. -    return 0;
  810. -}
  811. -
  812. -int set(comm comm)
  813. -{
  814. -char *s,*t;
  815. -
  816. -    if (!full(comm->args))
  817. -        {
  818. -        char **p = environ;
  819. -
  820. -        while (*p)
  821. -            puts(*p++);
  822. -        listhtable(parmhtab,(void (*)(char *,char *)) pparm);
  823. -        return 0;
  824. -        }
  825. -    s = getnode(comm->args);
  826. -    t = getnode(pparms);
  827. -    freetable(pparms,freestr);
  828. -    pparms = newtable();
  829. -    addnode(pparms,t);
  830. -    while (s)
  831. -        {
  832. -        addnode(pparms,s);
  833. -        s = getnode(comm->args);
  834. -        }
  835. -    return 0;
  836. -}
  837. -
  838. -struct option {
  839. -    char *name;
  840. -    char id;
  841. -    };
  842. -
  843. -static struct option optns[] = {
  844. -    "clobber",'1',
  845. -    "nobadpattern",'2',
  846. -    "nonomatch",'3',
  847. -    "globdots",'4',
  848. -    "notify",'5',
  849. -    "allexport",'a',
  850. -    "errexit",'e',
  851. -    "bgnice",'6',
  852. -    "ignoreeof",'7',
  853. -    "keyword",'k',
  854. -    "markdirs",'8',
  855. -    "monitor",'m',
  856. -    "noexec",'n',
  857. -    "noglob",'F',
  858. -    "norcs",'f',
  859. -    "shinstdin",'s',
  860. -    "nounset",'u',
  861. -    "verbose",'v',
  862. -    "xtrace",'x',
  863. -    "interactive",'i',
  864. -    "autolist",'9',
  865. -    "correct",'0',
  866. -    "dextract",'A',
  867. -    "nobeep",'B',
  868. -    "printexitvalue",'C',
  869. -    "pushdtohome",'D',
  870. -    "pushdsilent",'E',
  871. -    "nullglob",'G',
  872. -    "rmstarsilent",'H',
  873. -    "ignorebraces",'I',
  874. -    "cdablevars",'J',
  875. -    "nobanghist",'K',
  876. -    NULL,0
  877. -};
  878. -
  879. -int setopt(comm comm)
  880. -{
  881. -    return csetopt(comm,0);
  882. -}
  883. -
  884. -int unsetopt(comm comm)
  885. -{
  886. -    return csetopt(comm,1);
  887. -}
  888. -
  889. -/* common code for setopt and unsetopt */
  890. -
  891. -int csetopt(comm comm,int isun)
  892. -{
  893. -char *s,*os,*cmd;
  894. -int flag;
  895. -struct option *opp;
  896. -
  897. -    cmd = (isun) ? "unsetopt" : "setopt";
  898. -    if (!full(comm->args))
  899. -        {
  900. -        if (isun)
  901. -            return 0;
  902. -        for (opp = optns; opp->name; opp++)
  903. -            if (opts[opp->id] == OPT_SET)
  904. -                puts(opp->name);
  905. -        return 0;
  906. -        }
  907. -    while ((os = s = getnode(comm->args)) && ((flag = *s == '-') || *s == '+'))
  908. -        {
  909. -        while (*++s)
  910. -            if (*s == INTERACTIVE || *s == MONITOR)
  911. -                zerrnam(cmd,"can't change that option");
  912. -            else if (opts[*s & 0x7f] != OPT_INVALID)
  913. -                opts[*s & 0x7f] = (flag^isun) ? OPT_SET : OPT_UNSET;
  914. -            else
  915. -                zerrnam(cmd,"illegal option: %c",*s);
  916. -        free(os);
  917. -        }
  918. -    if (!s)
  919. -        return 0;
  920. -    while (s)
  921. -        {
  922. -        for (opp = optns; opp->name; opp++)
  923. -            if (!strcmp(opp->name,s))
  924. -                break;
  925. -        if (opp->name)
  926. -            {
  927. -            if (opp->id == INTERACTIVE || opp->id == MONITOR)
  928. -                zerrnam(cmd,"can't change that option");
  929. -            else
  930. -                opts[opp->id] = (isun) ? OPT_UNSET : OPT_SET;
  931. -            }
  932. -        else
  933. -            {
  934. -            zerrnam(cmd,"no such option: %s",s);
  935. -            free(s);
  936. -            return 1;
  937. -            }
  938. -        free(s);
  939. -        s = getnode(comm->args);
  940. -        }
  941. -    return 0;
  942. -}
  943. -
  944. -/* print a positional parameter */
  945. -
  946. -void pparm(char *s,struct pmnode *t)
  947. -{
  948. -    if (s && t)
  949. -        if (t->isint)
  950. -            printf("%s=%ld\n",s,t->u.val);
  951. -        else
  952. -            {
  953. -            printf("%s=",s);
  954. -            niceprint(t->u.str);
  955. -            putchar('\n');
  956. -            }
  957. -}
  958. -
  959. -int dirs(comm comm)
  960. -{
  961. -    if (comm->args->first)
  962. -        {
  963. -        if (dirstack)
  964. -            freetable(dirstack,freestr);
  965. -        dirstack = comm->args;
  966. -        comm->args = NULL;
  967. -        }
  968. -    else
  969. -        pdstack();
  970. -    return 0;
  971. -}
  972. -
  973. -/* call func once for each entry in a hash table */
  974. -
  975. -void listhtable(htable ht,void (*func)(char *,char *))
  976. -{
  977. -int t0;
  978. -struct hnode *hn;
  979. -
  980. -    for (t0 = ht->hsize-1; t0 >= 0; t0--)
  981. -        for (hn = ht->nodes[t0]; hn; hn = hn->hchain)
  982. -            func(hn->nam,hn->dat);
  983. -}
  984. -
  985. -/* print an alias (used with listhtable) */
  986. -
  987. -void palias(char *s,struct anode *t)
  988. -{
  989. -    if (t && t->cmd >= 0)
  990. -        {
  991. -        printf((t->cmd) ? "alias %-13s " : "alias -a %-10s ",s);
  992. -        niceprint(t->text);
  993. -        putchar('\n');
  994. -        }
  995. -}
  996. -
  997. -/* print a shell function (used with listhtable) */
  998. -
  999. -void pshfunc(char *s,list l)
  1000. -{
  1001. -char *t;
  1002. -
  1003. -    t = getltext(l);
  1004. -    untokenize(t);
  1005. -    printf("%s() {\n%s\n}\n",s,t);
  1006. -    free(t);
  1007. -}
  1008. -
  1009. -void niceprint(char *s)
  1010. -{
  1011. -    niceprintf(s,stdout);
  1012. -}
  1013. -
  1014. -void niceprintf(char *s,FILE *f)
  1015. -{
  1016. -    for (; *s; s++)
  1017. -        {
  1018. -        if (*s >= 32 && *s <= 126)
  1019. -            fputc(*s,f);
  1020. -        else if (*s == '\n')
  1021. -            {
  1022. -            putc('\\',f);
  1023. -            putc('n',f);
  1024. -            }
  1025. -        else
  1026. -            {
  1027. -            putc('^',f);
  1028. -            fputc(*s | 0x40,f);
  1029. -            }
  1030. -        }
  1031. -}
  1032. -
  1033. -/* build a command line from a linked list */
  1034. -
  1035. -char *buildline(table t)
  1036. -{
  1037. -char *str = strdup(""),*s,*os;
  1038. -
  1039. -    while (s = getnode(t))
  1040. -        {
  1041. -        os = str;
  1042. -        str = (*os) ? tricat(os," ",s) : strdup(s);
  1043. -        free(s);
  1044. -        free(os);
  1045. -        }
  1046. -    return str;
  1047. -}
  1048. -
  1049. -int Alias(comm comm)
  1050. -{
  1051. -char *s1,*s2;
  1052. -int anyflag = 0;
  1053. -
  1054. -    if (!(s1 = getnode(comm->args)))
  1055. -        {
  1056. -        listhtable(alhtab,(void (*)(char *,char *)) palias);
  1057. -        return 0;
  1058. -        }
  1059. -    if (!strcmp(s1,"-a"))
  1060. -        {
  1061. -        anyflag = 1;
  1062. -        free(s1);
  1063. -        if (!(s1 = getnode(comm->args)))
  1064. -            {
  1065. -            zerrnam("alias","alias -a requires 2 arguments");
  1066. -            return 1;
  1067. -            }
  1068. -        }
  1069. -    if (!comm->args->first)
  1070. -        {
  1071. -        palias(s1,gethnode(s1,alhtab));
  1072. -        free(s1);
  1073. -        return 0;
  1074. -        }
  1075. -    s2 = buildline(comm->args);
  1076. -    addhnode(s1,mkanode(s2,!anyflag),alhtab,freeanode);
  1077. -    return 0;
  1078. -}
  1079. -
  1080. -int cd(comm comm)
  1081. -{
  1082. -    if (!full(comm->args))
  1083. -        return chcd("cd",strdup(getparm("HOME")));
  1084. -    if (comm->args->first->next)
  1085. -        {
  1086. -        char *s,*t,*u,*v;
  1087. -        int sl,tl;
  1088. -
  1089. -        if (comm->args->first->next->next)
  1090. -            {
  1091. -            zerrnam("cd","too many arguments");
  1092. -            return 1;
  1093. -            }
  1094. -        s = getnode(comm->args);
  1095. -        t = getnode(comm->args);
  1096. -        if (!(u = (char *) strstr(cwd,s)))
  1097. -            {
  1098. -            zerrnam("cd","string not in pwd: %s",s);
  1099. -            return 1;
  1100. -            }
  1101. -        sl = strlen(s);
  1102. -        tl = strlen(t);
  1103. -        v = zalloc((u-cwd)+tl+strlen(u+sl)+1);
  1104. -        strncpy(v,cwd,u-cwd);
  1105. -        strcpy(v+(u-cwd),t);
  1106. -        strcat(v,u+sl);
  1107. -        free(s);
  1108. -        free(t);
  1109. -        return chcd("cd",v);
  1110. -        }
  1111. -    return chcd("cd",getnode(comm->args));
  1112. -}
  1113. -
  1114. -int dot(comm comm)
  1115. -{
  1116. -char *s;
  1117. -
  1118. -    if (!full(comm->args))
  1119. -        return 1;
  1120. -    s = getnode(comm->args);
  1121. -    if (source(s))
  1122. -        {
  1123. -        zerrnam(".","%e: %s",errno,s);
  1124. -        free(s);
  1125. -        return 1;
  1126. -        }
  1127. -    free(s);
  1128. -    return 0;
  1129. -}
  1130. -
  1131. -int Umask(comm comm)
  1132. -{
  1133. -char *s,*t;
  1134. -int t0;
  1135. -
  1136. -    if (!full(comm->args))
  1137. -        {
  1138. -        t0 = umask(0);
  1139. -        umask(t0);
  1140. -        printf("%03o\n",t0);
  1141. -        return 0;
  1142. -        }
  1143. -    s = getnode(comm->args);
  1144. -    t0 = strtol(s,&t,8);
  1145. -    if (*t)
  1146. -        {
  1147. -        zerrnam("umask","bad umask");
  1148. -        free(s);
  1149. -        return 1;
  1150. -        }
  1151. -    umask(t0);
  1152. -    free(s);
  1153. -    return 0;
  1154. -}
  1155. -
  1156. -int which(comm comm)
  1157. -{
  1158. -struct chnode *chn;
  1159. -struct anode *a;
  1160. -char *str = getnode(comm->args),*cnam;
  1161. -
  1162. -    if (!str)
  1163. -        {
  1164. -        zerrnam("which","argument required");
  1165. -        return 1;
  1166. -        }
  1167. -    if ((a = gethnode(str,alhtab)) && a->cmd)
  1168. -        {
  1169. -        if (a->cmd < 0)
  1170. -            printf("%s: shell reserved word\n",str);
  1171. -        else
  1172. -            printf("%s: aliased to %s\n",str,a->text);
  1173. -        free(str);
  1174. -        return 0;
  1175. -        }
  1176. -    if (gethnode(str,shfunchtab))
  1177. -        printf("%s: shell function\n",str);
  1178. -    else if (chn = gethnode(str,chtab))
  1179. -        {
  1180. -        if (chn->type != BUILTIN)
  1181. -            puts(chn->u.nam);
  1182. -        else
  1183. -            printf("%s: shell built-in command\n",str);
  1184. -        }
  1185. -    else if (!(cnam = findcmd(str)))
  1186. -        {
  1187. -        zerr("command not found: %s",str);
  1188. -        free(str);
  1189. -        return 1;
  1190. -        }
  1191. -    else
  1192. -        puts(cnam);
  1193. -    free(str);
  1194. -    return 0;
  1195. -}
  1196. -int popd(comm comm)
  1197. -{
  1198. -int val = 0;
  1199. -char *s;
  1200. -Node node;
  1201. -
  1202. -    if (comm->args->first && *(s = comm->args->first->dat) == '+')
  1203. -        val = atoi(s+1);
  1204. -    if (val--)
  1205. -        {
  1206. -        if (val < 0)
  1207. -            node = dirstack->last;
  1208. -        else
  1209. -            for (node = dirstack->first; val && node; node = node->next,
  1210. -                val--);
  1211. -        free(remnode(dirstack,node));
  1212. -        if (unset(PUSHDSILENT))
  1213. -            pdstack();
  1214. -        return 0;
  1215. -        }
  1216. -    else
  1217. -        {
  1218. -        if (!full(dirstack))
  1219. -            {
  1220. -            zerrnam("popd","dir stack empty");
  1221. -            return 1;
  1222. -            }
  1223. -        val = chcd("popd",getnode(dirstack));
  1224. -        if (unset(PUSHDSILENT))
  1225. -            pdstack();
  1226. -        return val;
  1227. -        }
  1228. -}
  1229. -int pushd(comm comm)
  1230. -{
  1231. -char *s;
  1232. -int num;
  1233. -
  1234. -    if (comm->args->first)
  1235. -        {
  1236. -        s = getnode(comm->args);
  1237. -        
  1238. -        if (*s == '+')
  1239. -            {
  1240. -            if (!(num = atoi(s+1)))
  1241. -                {
  1242. -                free(s);
  1243. -                return 0;
  1244. -                }
  1245. -            free(s);
  1246. -            if (isset(DEXTRACT))
  1247. -                {
  1248. -                Node n = dirstack->first;
  1249. -
  1250. -                insnode(dirstack,(Node) dirstack,strdup(cwd));
  1251. -                while (--num && n)
  1252. -                    n = n->next;
  1253. -                if (!n)
  1254. -                    {
  1255. -                    zerrnam("pushd","not that many dir stack entries");
  1256. -                    return 1;
  1257. -                    }
  1258. -                insnode(dirstack,(Node) dirstack,remnode(dirstack,n));
  1259. -                }
  1260. -            else
  1261. -                {
  1262. -                addnode(dirstack,strdup(cwd));
  1263. -                while(--num)
  1264. -                    addnode(dirstack,getnode(dirstack));
  1265. -                }
  1266. -            num = chcd("pushd",getnode(dirstack));
  1267. -            if (unset(PUSHDSILENT))
  1268. -                pdstack();
  1269. -            return num;
  1270. -            }
  1271. -        pushnode(dirstack,strdup(cwd));
  1272. -        num = chcd("pushd",s);
  1273. -        if (num)
  1274. -            free(getnode(dirstack));
  1275. -        else if (unset(PUSHDSILENT))
  1276. -            pdstack();
  1277. -        return num;
  1278. -        }
  1279. -    else
  1280. -        {
  1281. -        char *s;
  1282. -        
  1283. -        if (isset(PUSHDTOHOME))
  1284. -            s = strdup(getparm("HOME"));
  1285. -        else
  1286. -            s = getnode(dirstack);
  1287. -        if (!s)
  1288. -            {
  1289. -            zerrnam("pushd","dir stack empty");
  1290. -            return 1;
  1291. -            }
  1292. -        pushnode(dirstack,strdup(cwd));
  1293. -        num = chcd("pushd",s);
  1294. -        if (num)
  1295. -            free(getnode(dirstack));
  1296. -        else if (unset(PUSHDSILENT))
  1297. -            pdstack();
  1298. -        return num;
  1299. -        }
  1300. -}
  1301. -
  1302. -/* common code for pushd, popd, cd */
  1303. -
  1304. -int chcd(char *cnam,char *cd)
  1305. -{
  1306. -char *s,*t;
  1307. -char buf[MAXPATHLEN],*new = cd;
  1308. -int t0,val,esav,pnew = 0;
  1309. -
  1310. -    if (cd[0] == '-' && !cd[1])
  1311. -        {
  1312. -        free(cd);
  1313. -        cd = getparm("OLDPWD");
  1314. -        cd = strdup((cd) ? cd : ".");
  1315. -        }
  1316. -    if (*cd == '/')
  1317. -        {
  1318. -        val = chdir(new = cd);
  1319. -        esav = errno;
  1320. -        }
  1321. -    else
  1322. -        for (t0 = 0; t0 != cdpathct; t0++)
  1323. -            {
  1324. -            sprintf(buf,"%s/%s",cdpath[t0],cd);
  1325. -            if ((val = chdir(new = buf)) != -1)
  1326. -                {
  1327. -                if (t0)
  1328. -                    pnew = 1;
  1329. -                break;
  1330. -                }
  1331. -            if (t0 && errno != ENOENT && errno != ENOTDIR)
  1332. -                zerrnam(cnam,"warning: %e: %s",errno,buf);
  1333. -            if (!t0)
  1334. -                esav = errno;
  1335. -            }
  1336. -    if (val == -1 && errno == ENOENT)
  1337. -        {
  1338. -        t = strdup(cd);
  1339. -        if (isset(CDABLEVARS) && (s = getparm(t)) && *s == '/')
  1340. -            if (chdir(new = s) != -1)
  1341. -                {
  1342. -                val = 0;
  1343. -                pnew = 1;
  1344. -                goto goneto;
  1345. -                }
  1346. -        free(t);
  1347. -        zerrnam(cnam,"%e: %s",esav,cd);
  1348. -        free(cd);
  1349. -        return 1;
  1350. -        }
  1351. -goneto:
  1352. -    if (val == -1)
  1353. -        {
  1354. -        zerrnam(cnam,"%e: %s",esav,cd);
  1355. -        free(cd);
  1356. -        return 1;
  1357. -        }
  1358. -    else
  1359. -        {
  1360. -        list l;
  1361. -
  1362. -        if (cwd)
  1363. -            setparm(strdup("OLDPWD"),cwd,0,0);
  1364. -        cwd = findcwd(new);
  1365. -        setparm(strdup("PWD"),strdup(cwd),0,0);
  1366. -        if (pnew)
  1367. -            {
  1368. -            printdir(cwd);
  1369. -            putchar('\n');
  1370. -            }
  1371. -        if (l = gethnode("chpwd",shfunchtab))
  1372. -            newrunlist(l);
  1373. -        }
  1374. -    return 0;
  1375. -}
  1376. -int shift(comm comm)
  1377. -{
  1378. -char *s;
  1379. -int sh = 1;
  1380. -    if (comm->args->first && (s = comm->args->first->dat))
  1381. -        sh = atoi(s);
  1382. -    while (sh-- && pparms->first->next)
  1383. -        remnode(pparms,pparms->first->next);
  1384. -    return 0;
  1385. -}
  1386. -int unhash(comm comm)
  1387. -{
  1388. -char *s;
  1389. -    if (!(s = getnode(comm->args)))
  1390. -        {
  1391. -        zerrnam("unhash","argument required");
  1392. -        return 1;
  1393. -        }
  1394. -    while (s)
  1395. -        {
  1396. -        if (!gethnode(s,chtab))
  1397. -            {
  1398. -            zerrnam("unhash","not in command table: %s",s);
  1399. -            return 1;
  1400. -            }
  1401. -        free(remhnode(s,chtab));
  1402. -        free(s);
  1403. -        s = getnode(comm->args);
  1404. -        }
  1405. -    return 0;
  1406. -}
  1407. -
  1408. -int rehash(comm comm)
  1409. -{
  1410. -    parsepath();
  1411. -    return 0;
  1412. -}
  1413. -
  1414. -int hash(comm comm)
  1415. -{
  1416. -char *s,*t;
  1417. -struct chnode *chn;
  1418. -
  1419. -    if (!(s = getnode(comm->args)) || !(t = getnode(comm->args)))
  1420. -        {
  1421. -        zerrnam("hash","not enough arguments");
  1422. -        if (s)
  1423. -            free(s);
  1424. -        return 1;
  1425. -        }
  1426. -    chn = alloc(sizeof(struct chnode));
  1427. -    chn->type = EXCMD_PREDOT;
  1428. -    chn->globstat = GLOB;
  1429. -    chn->u.nam = t;
  1430. -    addhnode(s,chn,chtab,freechnode);
  1431. -    return 0;
  1432. -}
  1433. -
  1434. -int Break(comm comm)
  1435. -{
  1436. -char *s;
  1437. -    if (!loops)
  1438. -        {
  1439. -        zerrnam("break","not in loop");
  1440. -        return 1;
  1441. -        }
  1442. -    if (!(s = getnode(comm->args)))
  1443. -        breaks = 1;
  1444. -    else if (atoi(s))
  1445. -        {
  1446. -        breaks = atoi(s);
  1447. -        free(s);
  1448. -        }
  1449. -    else
  1450. -        {
  1451. -        zerrnam("break","numeric argument required");
  1452. -        free(s);
  1453. -        return 1;
  1454. -        }
  1455. -    return 0;
  1456. -}
  1457. -int colon(comm comm)
  1458. -{
  1459. -    return 0;
  1460. -}
  1461. -int Glob(comm comm)
  1462. -{
  1463. -struct chnode *chn;
  1464. -char *s;
  1465. -    while (s = getnode(comm->args))
  1466. -        {
  1467. -        chn = gethnode(s,chtab);
  1468. -        free(s);
  1469. -        if (chn)
  1470. -            chn->globstat = GLOB;
  1471. -        }
  1472. -    return 0;
  1473. -}
  1474. -int noglob(comm comm)
  1475. -{
  1476. -struct chnode *chn;
  1477. -char *s;
  1478. -    while (s = getnode(comm->args))
  1479. -        {
  1480. -        chn = gethnode(s,chtab);
  1481. -        free(s);
  1482. -        if (chn)
  1483. -            chn->globstat = NOGLOB;
  1484. -        }
  1485. -    return 0;
  1486. -}
  1487. -int mostglob(comm comm)
  1488. -{
  1489. -struct chnode *chn;
  1490. -char *s;
  1491. -    while (s = getnode(comm->args))
  1492. -        {
  1493. -        chn = gethnode(s,chtab);
  1494. -        free(s);
  1495. -        if (chn)
  1496. -            chn->globstat = MOSTGLOB;
  1497. -        }
  1498. -    return 0;
  1499. -}
  1500. -
  1501. -int unfunction(comm comm)
  1502. -{
  1503. -char *s1;
  1504. -list l;
  1505. -
  1506. -    while (s1 = getnode(comm->args))
  1507. -        {
  1508. -        unsettrap(s1);
  1509. -        if (l = remhnode(s1,shfunchtab))
  1510. -            freelist(l);
  1511. -        free(s1);
  1512. -        }
  1513. -    return 0;
  1514. -}
  1515. -
  1516. -int unalias(comm comm)
  1517. -{
  1518. -char *s1;
  1519. -struct anode *an;
  1520. -
  1521. -    while (s1 = getnode(comm->args))
  1522. -        {
  1523. -        if (an = remhnode(s1,alhtab))
  1524. -            freeanode(an);
  1525. -        free(s1);
  1526. -        }
  1527. -    return 0;
  1528. -}
  1529. -
  1530. -/* != 0 if s is a prefix of t */
  1531. -
  1532. -int prefix(char *s,char *t)
  1533. -{
  1534. -    while (*s && *t && *s == *t) s++,t++;
  1535. -    return (!*s);
  1536. -}
  1537. -
  1538. -/* convert %%, %1, %foo, %?bar? to a job number */
  1539. -
  1540. -int getjob(char *s,char *prog)
  1541. -{
  1542. -int t0,retval;
  1543. -char *os = s;
  1544. -
  1545. -    if (*s++ != '%')
  1546. -        {
  1547. -        zerrnam(prog,"bad job specifier");
  1548. -        retval = -1; goto done;
  1549. -        }
  1550. -    if (*s == '%' || *s == '+' || !*s)
  1551. -        {
  1552. -        if (topjob == -1)
  1553. -            {
  1554. -            zerrnam(prog,"no current job");
  1555. -            retval = -1; goto done;
  1556. -            }
  1557. -        retval = topjob; goto done;
  1558. -        }
  1559. -    if (*s == '-')
  1560. -        {
  1561. -        if (prevjob == -1)
  1562. -            {
  1563. -            zerrnam(prog,"no previous job");
  1564. -            retval = -1; goto done;
  1565. -            }
  1566. -        retval = prevjob; goto done;
  1567. -        }
  1568. -    if (isdigit(*s))
  1569. -        {
  1570. -        t0 = atoi(s);
  1571. -        if (t0 && t0 < MAXJOB && jobtab[t0].stat && t0 != curjob)
  1572. -            { retval = t0; goto done; }
  1573. -        zerrnam(prog,"no such job");
  1574. -        retval = -1; goto done;
  1575. -        }
  1576. -    if (*s == '?')
  1577. -        {
  1578. -        struct procnode *pn;
  1579. -
  1580. -        for (t0 = 0; t0 != MAXJOB; t0++)
  1581. -            if (jobtab[t0].stat && t0 != curjob)
  1582. -                for (pn = jobtab[t0].procs; pn; pn = pn->next)
  1583. -                    if (strstr(pn->text,s+1))
  1584. -                        { retval = t0; goto done; }
  1585. -        zerrnam(prog,"job not found: %s",s);
  1586. -        retval = -1; goto done;
  1587. -        }
  1588. -    for (t0 = 0; t0 != MAXJOB; t0++)
  1589. -        if (jobtab[t0].stat && jobtab[t0].procs && t0 != curjob && 
  1590. -                prefix(s,jobtab[t0].procs->text))
  1591. -            { retval = t0; goto done; }
  1592. -    zerrnam(prog,"job not found: %s",s);
  1593. -    retval = -1;
  1594. -done:
  1595. -    free(os);
  1596. -    return retval;
  1597. -}
  1598. -
  1599. -int fg(comm comm)
  1600. -{
  1601. -char *s1;
  1602. -int ocj = curjob,job;
  1603. -
  1604. -    scanjobs();
  1605. -    if (!jobbing)
  1606. -        {
  1607. -        zerr("no job control in this shell.");
  1608. -        return 1;
  1609. -        }
  1610. -    if (s1 = getnode(comm->args))
  1611. -        job = getjob(s1,"fg");
  1612. -    else
  1613. -        {
  1614. -        if (topjob == -1 || topjob == curjob)
  1615. -            {
  1616. -            zerrnam("fg","no current job");
  1617. -            return 1;
  1618. -            }
  1619. -        job = topjob;
  1620. -        }
  1621. -    if (job == -1)
  1622. -        return 1;
  1623. -    makerunning(jobtab+job);
  1624. -    if (topjob == job)
  1625. -        {
  1626. -        topjob = prevjob;
  1627. -        prevjob = job;
  1628. -        }
  1629. -    if (prevjob == job)
  1630. -        setprevjob();
  1631. -    printjob(jobtab+job,-1);
  1632. -    curjob = job;
  1633. -    if (strcmp(jobtab[job].cwd,cwd))
  1634. -        {
  1635. -        printf("(pwd: ");
  1636. -        printdir(jobtab[job].cwd);
  1637. -        printf(")\n");
  1638. -        }
  1639. -    settyinfo(&jobtab[job].ttyinfo);
  1640. -    attachtty(jobtab[job].gleader);
  1641. -    killpg(jobtab[job].gleader,SIGCONT);
  1642. -    waitjobs();
  1643. -    curjob = ocj;
  1644. -    return 0;
  1645. -}
  1646. -
  1647. -int bg(comm comm)
  1648. -{
  1649. -char *s1;
  1650. -int job,stopped;
  1651. -
  1652. -    scanjobs();
  1653. -    if (!jobbing)
  1654. -        {
  1655. -        zerr("no job control in this shell.");
  1656. -        return 1;
  1657. -        }
  1658. -    if (s1 = getnode(comm->args))
  1659. -        job = getjob(s1,"bg");
  1660. -    else
  1661. -        {
  1662. -        if (topjob == -1 || topjob == curjob)
  1663. -            {
  1664. -            zerrnam("bg","no current job");
  1665. -            return 1;
  1666. -            }
  1667. -        job = topjob;
  1668. -        }
  1669. -    if (job == -1)
  1670. -        return 1;
  1671. -    if (!(jobtab[job].stat & STAT_STOPPED))
  1672. -        {
  1673. -        zerrnam("bg","job already in background");
  1674. -        return 1;
  1675. -        }
  1676. -    stopped = jobtab[job].stat & STAT_STOPPED;
  1677. -    if (stopped)
  1678. -        makerunning(jobtab+job);
  1679. -    if (topjob == job)
  1680. -        {
  1681. -        topjob = prevjob;
  1682. -        prevjob = -1;
  1683. -        }
  1684. -    if (prevjob == job)
  1685. -        prevjob = -1;
  1686. -    if (prevjob == -1)
  1687. -        setprevjob();
  1688. -    if (topjob == -1)
  1689. -        {
  1690. -        topjob = prevjob;
  1691. -        setprevjob();
  1692. -        }
  1693. -    printjob(jobtab+job,(stopped) ? -1 : 0);
  1694. -    if (stopped)
  1695. -        killpg(jobtab[job].gleader,SIGCONT);
  1696. -    return 0;
  1697. -}
  1698. -
  1699. -int jobs(comm comm)
  1700. -{
  1701. -int job,lng = 0;
  1702. -
  1703. -    if (full(comm->args))
  1704. -        {
  1705. -        if (comm->args->first->next || (strcmp(comm->args->first->dat,"-l")
  1706. -                && strcmp(comm->args->first->dat,"-p")))
  1707. -            {
  1708. -            zerrnam("jobs","usage: jobs [ -lp ]");
  1709. -            return 1;
  1710. -            }
  1711. -        lng = (strcmp(comm->args->first->dat,"-l")) ? 2 : 1;
  1712. -        }
  1713. -    for (job = 0; job != MAXJOB; job++)
  1714. -        if (job != curjob && jobtab[job].stat)
  1715. -            printjob(job+jobtab,lng);
  1716. -    stopmsg = 2;
  1717. -    return 0;
  1718. -}
  1719. -
  1720. -int Kill(comm comm)
  1721. -{
  1722. -int sig = SIGTERM;
  1723. -char *s;
  1724. -
  1725. -    s = getnode(comm->args);
  1726. -    if (s && *s == '-')
  1727. -        {
  1728. -        if (isdigit(s[1]))
  1729. -            sig = atoi(s+1);
  1730. -        else
  1731. -            {
  1732. -            if (s[1] == 'l' && s[2] == '\0')
  1733. -                {
  1734. -                printf("%s",sigs[0]);
  1735. -                for (sig = 1; sig != SIGCOUNT; sig++)
  1736. -                    printf(" %s",sigs[sig]);
  1737. -                putchar('\n');
  1738. -                return 0;
  1739. -                }
  1740. -            for (sig = 0; sig != SIGCOUNT; sig++)
  1741. -                if (!strcmp(sigs[sig],s+1))
  1742. -                    break;
  1743. -            if (sig == SIGCOUNT)
  1744. -                {
  1745. -                zerrnam("kill","unknown signal: SIG%s",s+1);
  1746. -                zerrnam("kill","type kill -l for a list of signals");
  1747. -                return 1;
  1748. -                }
  1749. -            }
  1750. -        s = getnode(comm->args);
  1751. -        }
  1752. -    while (s)
  1753. -        {
  1754. -        if (*s == '%')
  1755. -            {
  1756. -            int job = getjob(s,"kill");
  1757. -
  1758. -            if (killjb(jobtab+job,sig) == -1)
  1759. -                {
  1760. -                zerrnam("kill","kill failed: %e",errno);
  1761. -                return 1;
  1762. -                }
  1763. -            if (jobtab[job].stat & STAT_STOPPED && sig == SIGCONT)
  1764. -                jobtab[job].stat &= ~STAT_STOPPED;
  1765. -            if (sig != SIGKILL)
  1766. -                killpg(jobtab[job].gleader,SIGCONT);
  1767. -            }
  1768. -        else
  1769. -            if (kill(atoi(s),sig) == -1)
  1770. -                {
  1771. -                zerrnam("kill","kill failed: %e");
  1772. -                return 1;
  1773. -                }
  1774. -        s = getnode(comm->args);
  1775. -        }
  1776. -    return 0;
  1777. -}
  1778. -
  1779. -int export(comm comm)
  1780. -{
  1781. -char *s,*t;
  1782. -struct pmnode *pm;
  1783. -
  1784. -    while (s = getnode(comm->args))
  1785. -        {
  1786. -        if (t = strchr(s,'='))
  1787. -            {
  1788. -            *t = '\0';
  1789. -            if (pm = gethnode(s,parmhtab))
  1790. -                freepm(remhnode(s,parmhtab));
  1791. -            *t = '=';
  1792. -            putenv(s);
  1793. -            }
  1794. -        else
  1795. -            {
  1796. -            if (!(pm = gethnode(s,parmhtab)))
  1797. -                {
  1798. -                if (!getenv(s))
  1799. -                    {
  1800. -                    zerrnam("export","parameter not set: %s",s);
  1801. -                    free(s);
  1802. -                    return 1;
  1803. -                    }
  1804. -                }
  1805. -            else if (pm->isint)
  1806. -                {
  1807. -                zerrnam("export","can't export integer parameters");
  1808. -                free(s);
  1809. -                return 1;
  1810. -                }
  1811. -            else
  1812. -                {
  1813. -                t = tricat(s,"=",pm->u.str);
  1814. -                putenv(t);
  1815. -                free(remhnode(s,parmhtab));
  1816. -                }
  1817. -            }
  1818. -        }
  1819. -    return 0;
  1820. -}
  1821. -
  1822. -int integer(comm comm)
  1823. -{
  1824. -char *s,*t;
  1825. -struct pmnode *uu;
  1826. -
  1827. -    while (s = getnode(comm->args))
  1828. -        {
  1829. -        if (t = strchr(s,'='))
  1830. -            {
  1831. -            *t = '\0';
  1832. -            setparm(s,t+1,0,1);
  1833. -            *t = '=';
  1834. -            }
  1835. -        else
  1836. -            {
  1837. -            uu = gethnode(s,parmhtab);
  1838. -            if (uu)
  1839. -                {
  1840. -                if (!uu->isint)
  1841. -                    {
  1842. -                    uu->isint = 1;
  1843. -                    uu->u.val = matheval(uu->u.str);
  1844. -                    }
  1845. -                }
  1846. -            else
  1847. -                setiparm(s,0,1);
  1848. -            }
  1849. -        }
  1850. -    return 0;
  1851. -}
  1852. -
  1853. -static char *recs[] = {
  1854. -    "cputime","filesize","datasize","stacksize","coredumpsize",
  1855. -    "resident","descriptors"
  1856. -    };
  1857. -
  1858. -int limit(comm comm)
  1859. -{
  1860. -char *s;
  1861. -int hard = 0,t0,lim;
  1862. -long val;
  1863. -
  1864. -    if (!(s = getnode(comm->args)))
  1865. -        {
  1866. -        showlimits(0,-1);
  1867. -        return 0;
  1868. -        }
  1869. -    if (!strcmp(s,"-s"))
  1870. -        {
  1871. -        if (full(comm->args))
  1872. -            zerr("limit","arguments after -s ignored");
  1873. -        for (t0 = 0; t0 != RLIM_NLIMITS; t0++)
  1874. -            if (setrlimit(t0,limits+t0) < 0)
  1875. -                zerr("limit","setrlimit failed: %e",errno);
  1876. -        return 0;
  1877. -        }
  1878. -    if (!strcmp(s,"-h"))
  1879. -        {
  1880. -        hard = 1;
  1881. -        free(s);
  1882. -        if (!(s = getnode(comm->args)))
  1883. -            {
  1884. -            showlimits(1,-1);
  1885. -            return 0;
  1886. -            }
  1887. -        }
  1888. -    while (s)
  1889. -        {
  1890. -        for (lim = -1, t0 = 0; t0 != RLIM_NLIMITS; t0++)
  1891. -            if (!strncmp(recs[t0],s,strlen(s)))
  1892. -                {
  1893. -                if (lim != -1)
  1894. -                    lim = -2;
  1895. -                else
  1896. -                    lim = t0;
  1897. -                }
  1898. -        if (lim < 0)
  1899. -            {
  1900. -            zerrnam("limit",
  1901. -                (lim == -2) ? "ambiguous resource specification: %s"
  1902. -                                : "no such resource: %s",s);
  1903. -            free(s);
  1904. -            return 1;
  1905. -            }
  1906. -        free(s);
  1907. -        if (!(s = getnode(comm->args)))
  1908. -            {
  1909. -            showlimits(hard,lim);
  1910. -            return 0;
  1911. -            }
  1912. -        if (!lim)
  1913. -            {
  1914. -            char *ss = s;
  1915. -            
  1916. -            val = strtol(s,&s,10);
  1917. -            if (*s)
  1918. -                if ((*s == 'h' || *s == 'H') && !s[1])
  1919. -                    val *= 3600L;
  1920. -                else if ((*s == 'm' || *s == 'M') && !s[1])
  1921. -                    val *= 60L;
  1922. -                else if (*s == ':')
  1923. -                    val = val*60+strtol(s+1,&s,10);
  1924. -                else
  1925. -                    {
  1926. -                    zerrnam("limit","unknown scaling factor: %s",s);
  1927. -                    free(ss);
  1928. -                    return 1;
  1929. -                    }
  1930. -            }
  1931. -#ifdef RLIMIT_NOFILE
  1932. -        else if (lim == RLIMIT_NOFILE)
  1933. -            val = strtol(s,&s,10);
  1934. -#endif
  1935. -        else
  1936. -            {
  1937. -            char *ss = s;
  1938. -            
  1939. -            val = strtol(s,&s,10);
  1940. -            if (!*s || ((*s == 'k' || *s == 'K') && !s[1]))
  1941. -                val *= 1024L;
  1942. -            else if ((*s == 'M' || *s == 'm') && !s[1])
  1943. -                val *= 1024L*1024;
  1944. -            else
  1945. -                {
  1946. -                zerrnam("limit","unknown scaling factor: %s",s);
  1947. -                free(ss);
  1948. -                return 1;
  1949. -                }
  1950. -            free(ss);
  1951. -            }
  1952. -        if (hard)
  1953. -            if (val > limits[lim].rlim_max && geteuid())
  1954. -                {
  1955. -                zerrnam("limit","can't raise hard limits");
  1956. -                return 1;
  1957. -                }
  1958. -            else
  1959. -                {
  1960. -                limits[lim].rlim_max = val;
  1961. -                if (limits[lim].rlim_max < limits[lim].rlim_cur)
  1962. -                    limits[lim].rlim_cur = limits[lim].rlim_max;
  1963. -                }
  1964. -        else
  1965. -            if (val > limits[lim].rlim_max)
  1966. -                {
  1967. -                zerrnam("limit","limit exceeds hard limit");
  1968. -                return 1;
  1969. -                }
  1970. -            else
  1971. -                limits[lim].rlim_cur = val;
  1972. -        s = getnode(comm->args);
  1973. -        }
  1974. -    return 0;
  1975. -}
  1976. -
  1977. -int unlimit(comm comm)
  1978. -{
  1979. -char *s = getnode(comm->args);
  1980. -int hard = 0,t0,lim;
  1981. -
  1982. -    if (s && !strcmp(s,"-h"))
  1983. -        {
  1984. -        hard = 1;
  1985. -        if (geteuid())
  1986. -            {
  1987. -            zerrnam("unlimit","can't remove hard limits");
  1988. -            return 1;
  1989. -            }
  1990. -        free(s);
  1991. -        s = getnode(comm->args);
  1992. -        }
  1993. -    if (!s)
  1994. -        {
  1995. -        for (t0 = 0; t0 != RLIM_NLIMITS; t0++)
  1996. -            {
  1997. -            if (hard)
  1998. -                limits[t0].rlim_max = RLIM_INFINITY;
  1999. -            else
  2000. -                limits[t0].rlim_cur = limits[t0].rlim_max;
  2001. -            }
  2002. -        return 0;
  2003. -        }
  2004. -    while (s)
  2005. -        {
  2006. -        for (lim = -1, t0 = 0; t0 != RLIM_NLIMITS; t0++)
  2007. -            if (!strncmp(recs[t0],s,strlen(s)))
  2008. -                {
  2009. -                if (lim != -1)
  2010. -                    lim = -2;
  2011. -                else
  2012. -                    lim = t0;
  2013. -                }
  2014. -        if (lim < 0)
  2015. -            {
  2016. -            zerrnam("unlimit",
  2017. -                (lim == -2) ? "ambiguous resource specification: %s"
  2018. -                                : "no such resource: %s",s);
  2019. -            free(s);
  2020. -            return 1;
  2021. -            }
  2022. -        free(s);
  2023. -        if (hard)
  2024. -            limits[lim].rlim_max = RLIM_INFINITY;
  2025. -        else
  2026. -            limits[lim].rlim_cur = limits[lim].rlim_max;
  2027. -        s = getnode(comm->args);
  2028. -        }
  2029. -    return 0;
  2030. -}
  2031. -
  2032. -void showlimits(int hard,int lim)
  2033. -{
  2034. -int t0;
  2035. -long val;
  2036. -
  2037. -    for (t0 = 0; t0 != RLIM_NLIMITS; t0++)
  2038. -        if (t0 == lim || lim == -1)
  2039. -            {
  2040. -            printf("%-16s",recs[t0]);
  2041. -            val = (hard) ? limits[t0].rlim_max : limits[t0].rlim_cur;
  2042. -            if (val == RLIM_INFINITY)
  2043. -                printf("unlimited\n");
  2044. -            else if (!t0)
  2045. -                printf("%d:%02d:%02d\n",(int) (val/3600),
  2046. -                    (int) (val/60) % 60,(int) (val % 60));
  2047. -#ifdef RLIMIT_NOFILE
  2048. -            else if (t0 == RLIMIT_NOFILE)
  2049. -                printf("%d\n",(int) val);
  2050. -#endif
  2051. -            else if (val >= 1024L*1024L)
  2052. -                printf("%ldMb\n",val/(1024L*1024L));
  2053. -            else
  2054. -                printf("%ldKb\n",val/1024L);
  2055. -            }
  2056. -}
  2057. -
  2058. -int sched(comm comm)
  2059. -{
  2060. -char *s = getnode(comm->args);
  2061. -time_t t;
  2062. -long h,m;
  2063. -struct tm *tm;
  2064. -struct schnode *sch,*sch2,*schl;
  2065. -int t0;
  2066. -
  2067. -    if (s && *s == '-')
  2068. -        {
  2069. -        t0 = atoi(s+1);
  2070. -
  2071. -        if (!t0)
  2072. -            {
  2073. -            zerrnam("sched","usage for delete: sched -<item#>.");
  2074. -            return 1;
  2075. -            }
  2076. -        for (schl = (struct schnode *) &scheds, sch = scheds, t0--;
  2077. -                sch && t0; sch = (schl = sch)->next, t0--);
  2078. -        if (!sch)
  2079. -            {
  2080. -            zerrnam("sched","not that many entries");
  2081. -            return 1;
  2082. -            }
  2083. -        schl->next = sch->next;
  2084. -        free(sch->cmd);
  2085. -        free(sch);
  2086. -        return 0;
  2087. -        }
  2088. -    if (s && !full(comm->args))
  2089. -        {
  2090. -        zerrnam("sched","not enough arguments");
  2091. -        return 1;
  2092. -        }
  2093. -    if (!s)
  2094. -        {
  2095. -        char tbuf[40];
  2096. -
  2097. -        for (t0 = 1, sch = scheds; sch; sch = sch->next,t0++)
  2098. -            {
  2099. -            t = sch->time;
  2100. -            tm = localtime(&t);
  2101. -            strftime(tbuf,20,"%a %b %e %k:%M:%S",tm);
  2102. -            printf("%3d %s %s\n",t0,tbuf,sch->cmd);
  2103. -            }
  2104. -        return 0;
  2105. -        }
  2106. -    if (*s == '+')
  2107. -        {
  2108. -        h = strtol(s+1,&s,10);
  2109. -        if (*s != ':')
  2110. -            {
  2111. -            zerrnam("sched","bad time specifier");
  2112. -            return 1;
  2113. -            }
  2114. -        m = strtol(s+1,&s,10);
  2115. -        if (*s)
  2116. -            {
  2117. -            zerrnam("sched","bad time specifier");
  2118. -            return 1;
  2119. -            }
  2120. -        t = time(NULL)+h*3600+m*60;
  2121. -        }
  2122. -    else
  2123. -        {
  2124. -        h = strtol(s,&s,10);
  2125. -        if (*s != ':')
  2126. -            {
  2127. -            zerrnam("sched","bad time specifier");
  2128. -            return 1;
  2129. -            }
  2130. -        m = strtol(s+1,&s,10);
  2131. -        if (*s && *s != 'a' && *s != 'p')
  2132. -            {
  2133. -            zerrnam("sched","bad time specifier");
  2134. -            return 1;
  2135. -            }
  2136. -        t = time(NULL);
  2137. -        tm = localtime(&t);
  2138. -        t -= tm->tm_sec+tm->tm_min*60+tm->tm_hour*3600;
  2139. -        if (*s == 'p')
  2140. -            h += 12;
  2141. -        t += h*3600+m*60;
  2142. -        if (t < time(NULL))
  2143. -            t += 3600*24;
  2144. -        }
  2145. -    sch = alloc(sizeof(struct schnode));
  2146. -    sch->time = t;
  2147. -    sch->cmd = buildline(comm->args);
  2148. -    sch->next = NULL;
  2149. -    for (sch2 = (struct schnode *) &scheds; sch2->next; sch2 = sch2->next);
  2150. -    sch2->next = sch;
  2151. -    return 0;
  2152. -}
  2153. -
  2154. -int eval(comm comm)
  2155. -{
  2156. -char *s = buildline(comm->args);
  2157. -list list;
  2158. -
  2159. -    hungets(s);
  2160. -    strinbeg();
  2161. -    if (!(list = parlist(1)))
  2162. -        {
  2163. -        hflush();
  2164. -        strinend();
  2165. -        return 1;
  2166. -        }
  2167. -    strinend();
  2168. -    runlist(list);
  2169. -    return lastval;
  2170. -}
  2171. -
  2172. -int Brk(comm comm)
  2173. -{
  2174. -    printf("%lx\n",(long) sbrk(0));
  2175. -    return 0;
  2176. -}
  2177. -
  2178. -static struct utmp *wtab;
  2179. -static int wtabsz;
  2180. -
  2181. -int log(comm comm)
  2182. -{
  2183. -    if (!getparm("WATCH"))
  2184. -        return 1;
  2185. -    if (wtab)
  2186. -        free(wtab);
  2187. -    wtab = (struct utmp *) zalloc(1);
  2188. -    wtabsz = 0;
  2189. -    watch();
  2190. -    return 0;
  2191. -}
  2192. -
  2193. -int let(comm comm)
  2194. -{
  2195. -char *str;
  2196. -long val;
  2197. -
  2198. -    while (str = getnode(comm->args))
  2199. -        val = matheval(str);
  2200. -    return !val;
  2201. -}
  2202. -
  2203. -int Read(comm comm)
  2204. -{
  2205. -char *str,*pmpt;
  2206. -int r = 0,bsiz,c,gotnl = 0;
  2207. -char *buf,*bptr;
  2208. -char cc;
  2209. -
  2210. -    str = getnode(comm->args);
  2211. -    if (str && !strcmp(str,"-r"))
  2212. -        {
  2213. -        r = 1;
  2214. -        str = getnode(comm->args);
  2215. -        }
  2216. -    if (!str)
  2217. -        str = strdup("REPLY");
  2218. -    if (interact)
  2219. -        {
  2220. -        for (pmpt = str; *pmpt && *pmpt != '?'; pmpt++);
  2221. -        if (*pmpt++)
  2222. -            {
  2223. -            write(2,pmpt,strlen(pmpt));
  2224. -            *pmpt = '\0';
  2225. -            }
  2226. -        }
  2227. -    while (full(comm->args))
  2228. -        {
  2229. -        buf = bptr = zalloc(bsiz = 64);
  2230. -        FOREVER
  2231. -            {
  2232. -            if (gotnl)
  2233. -                break;
  2234. -            if (read(0,&cc,1) == 1)
  2235. -                c = cc;
  2236. -            else
  2237. -                c = EOF;
  2238. -            if (c == EOF || znspace(c))
  2239. -                break;
  2240. -            *bptr++ = c;
  2241. -            if (bptr == buf+bsiz)
  2242. -                {
  2243. -                buf = realloc(buf,bsiz *= 2);
  2244. -                bptr = buf+(bsiz/2);
  2245. -                }
  2246. -            }
  2247. -        if (c == EOF)
  2248. -            return 1;
  2249. -        if (c == '\n')
  2250. -            gotnl = 1;
  2251. -        *bptr = '\0';
  2252. -        setparm(str,buf,0,0);
  2253. -        str = getnode(comm->args);
  2254. -        }
  2255. -    buf = bptr = zalloc(bsiz = 64);
  2256. -    if (!gotnl)
  2257. -        FOREVER
  2258. -            {
  2259. -            if (read(0,&cc,1) == 1)
  2260. -                c = cc;
  2261. -            else
  2262. -                c = EOF;
  2263. -            if (c == EOF || c == '\n')
  2264. -                break;
  2265. -            *bptr++ = c;
  2266. -            if (bptr == buf+bsiz)
  2267. -                {
  2268. -                buf = realloc(buf,bsiz *= 2);
  2269. -                bptr = buf+(bsiz/2);
  2270. -                }
  2271. -            *bptr = '\0';
  2272. -            }
  2273. -    if (c == EOF)
  2274. -        return 1;
  2275. -    setparm(str,buf,0,0);
  2276. -    return 0;
  2277. -}
  2278. -
  2279. -int fc(comm comm)
  2280. -{
  2281. -char *ename = getparm("FCEDIT"),*str,*s;
  2282. -int n = 0,l = 0,r = 0,first = -1,last = -1,retval;
  2283. -table subs = NULL;
  2284. -
  2285. -    if (!interact)
  2286. -        {
  2287. -        zerrnam("fc","not interactive shell");
  2288. -        return 1;
  2289. -        }
  2290. -    remhist();
  2291. -    if (!ename)
  2292. -        ename = DEFFCEDIT;
  2293. -    str = getnode(comm->args);
  2294. -    for (; str && *str == '-' && str[1] && !isdigit(str[1]);
  2295. -            str = getnode(comm->args))
  2296. -        while (str[1])
  2297. -            switch(*++str)
  2298. -                {
  2299. -                case 'e':
  2300. -                    if (str[1])
  2301. -                        {
  2302. -                        zerrnam("fc","editor name expected after -e");
  2303. -                        return 1;
  2304. -                        }
  2305. -                    ename = getnode(comm->args);
  2306. -                    if (!ename)
  2307. -                        {
  2308. -                        zerrnam("fc","editor name expected after -e");
  2309. -                        return 1;
  2310. -                        }
  2311. -                    break;
  2312. -                case 'n':
  2313. -                    n = 1;
  2314. -                    break;
  2315. -                case 'l':
  2316. -                    l = 1;
  2317. -                    break;
  2318. -                case 'r':
  2319. -                    r = 1;
  2320. -                    break;
  2321. -                default:
  2322. -                    zerrnam("fc","bad option: %c",*str);
  2323. -                    return 1;
  2324. -                }
  2325. -    subs = newtable();
  2326. -    while (str)
  2327. -        {
  2328. -        for (s = str; *s && *s != '='; s++);
  2329. -        if (!*s)
  2330. -            break;
  2331. -        *s++ = '\0';
  2332. -        addnode(subs,str);
  2333. -        addnode(subs,s);
  2334. -        str = getnode(comm->args);
  2335. -        }
  2336. -    if (str)
  2337. -        {
  2338. -        first = fcgetcomm(str);
  2339. -        if (first == -1)
  2340. -            {
  2341. -            freetable(subs,freestr);
  2342. -            return 1;
  2343. -            }
  2344. -        str = getnode(comm->args);
  2345. -        }
  2346. -    if (str)
  2347. -        {
  2348. -        last = fcgetcomm(str);
  2349. -        if (last == -1)
  2350. -            {
  2351. -            freetable(subs,freestr);
  2352. -            return 1;
  2353. -            }
  2354. -        if (full(comm->args))
  2355. -            {
  2356. -            zerrnam("fc","too many arguments");
  2357. -            freetable(subs,freestr);
  2358. -            return 1;
  2359. -            }
  2360. -        }
  2361. -    if (first == -1)
  2362. -        {
  2363. -        first = (l) ? cev-16 : cev;
  2364. -        if (last == -1)
  2365. -            last = cev;
  2366. -        }
  2367. -    if (first < tfev)
  2368. -        first = tfev;
  2369. -    if (last == -1)
  2370. -        last = first;
  2371. -    if (l)
  2372. -        retval = fclist(stdout,!n,r,first,last,subs);
  2373. -    else
  2374. -        {
  2375. -        FILE *out;
  2376. -        char *fn = gettemp();
  2377. -
  2378. -        out = fopen(fn,"w");
  2379. -        if (!out)
  2380. -            zerrnam("fc","can't open temp file: %e",errno);
  2381. -        else
  2382. -            {
  2383. -            retval = 1;
  2384. -            if (!fclist(out,0,r,first,last,subs))
  2385. -                if (fcedit(ename,fn))
  2386. -                    if (stuff(fn))
  2387. -                        zerrnam("fc","%e: %s",errno,s);
  2388. -                    else
  2389. -                        retval = 0;
  2390. -            }
  2391. -        unlink(fn);
  2392. -        free(fn);
  2393. -        }
  2394. -    freetable(subs,freestr);
  2395. -    return retval;
  2396. -}
  2397. -
  2398. -/* get the history event associated with s */
  2399. -
  2400. -int fcgetcomm(char *s)
  2401. -{
  2402. -int cmd;
  2403. -
  2404. -    if (cmd = atoi(s))
  2405. -        {
  2406. -        if (cmd < 0)
  2407. -            cmd = cev+cmd+1;
  2408. -        return cmd;
  2409. -        }
  2410. -    cmd = hcomsearch(s);
  2411. -    if (cmd == -1)
  2412. -        zerrnam("fc","event not found: %s",s);
  2413. -    return cmd;
  2414. -}
  2415. -
  2416. -/* list a series of history events to a file */
  2417. -
  2418. -int fclist(FILE *f,int n,int r,int first,int last,table subs)
  2419. -{
  2420. -int done = 0,ct;
  2421. -Node node;
  2422. -char *s;
  2423. -
  2424. -    if (!subs->first)
  2425. -        done = 1;
  2426. -    last -= first;
  2427. -    first -= tfev;
  2428. -    if (r)
  2429. -        first += last;
  2430. -    for (node = histlist->first,ct = first; ct && node;
  2431. -        node = node->next, ct--);
  2432. -    first += tfev;
  2433. -    while (last-- >= 0)
  2434. -        {
  2435. -        if (!node)
  2436. -            {
  2437. -            zerrnam("fc","no such event: %d",first);
  2438. -            return 1;
  2439. -            }
  2440. -        s = makehlist(node->dat,0);
  2441. -        done |= fcsubs(&s,subs);
  2442. -        if (n)
  2443. -            fprintf(f,"%5d  ",first);
  2444. -        if (f == stdout)
  2445. -            {
  2446. -            niceprintf(s,f);
  2447. -            putc('\n',f);
  2448. -            }
  2449. -        else
  2450. -            fprintf(f,"%s\n",s);
  2451. -        node = (r) ? node->last : node->next;
  2452. -        (r) ? first-- : first++;
  2453. -        }
  2454. -    if (f != stdout)
  2455. -        fclose(f);
  2456. -    if (!done)
  2457. -        {
  2458. -        zerrnam("fc","no substitutions performed");
  2459. -        return 1;
  2460. -        }
  2461. -    return 0;
  2462. -}
  2463. -
  2464. -/* perform old=new substituion */
  2465. -
  2466. -int fcsubs(char **sp,table tab)
  2467. -{
  2468. -Node n;
  2469. -char *s1,*s2,*s3,*s4,*s = *sp,*s5;
  2470. -int subbed = 0;
  2471. -
  2472. -    for (n = tab->first; n; )
  2473. -        {
  2474. -        s1 = n->dat;
  2475. -        n = n->next;
  2476. -        s2 = n->dat;
  2477. -        n = n->next;
  2478. -        s5 = s;
  2479. -        while (s3 = (char *) strstr(s5,s1))
  2480. -            {
  2481. -            s4 = zalloc(1+(s3-s)+strlen(s2)+strlen(s3+strlen(s1)));
  2482. -            strncpy(s4,s,s3-s);
  2483. -            s4[s3-s] = '\0';
  2484. -            strcat(s4,s2);
  2485. -            s5 = s4+strlen(s4);
  2486. -            strcat(s4,s3+strlen(s1));
  2487. -            free(s);
  2488. -            s = s4;
  2489. -            subbed = 1;
  2490. -            }
  2491. -        }
  2492. -    *sp = s;
  2493. -    return subbed;
  2494. -}
  2495. -
  2496. -int fcedit(char *ename,char *fn)
  2497. -{
  2498. -    if (!strcmp(ename,"-"))
  2499. -        return 1;
  2500. -    return !zyztem(ename,fn);
  2501. -}
  2502. -
  2503. -int disown(comm comm)
  2504. -{
  2505. -char *str;
  2506. -int t0;
  2507. -static struct jobnode zero;
  2508. -
  2509. -    while (str = getnode(comm->args))
  2510. -        {
  2511. -        t0 = getjob(str,"disown");
  2512. -        if (t0 == -1)
  2513. -            return 1;
  2514. -        jobtab[t0] = zero;
  2515. -        }
  2516. -    return 0;
  2517. -}
  2518. -
  2519. -int function(comm comm)
  2520. -{
  2521. -    if (full(comm->args))
  2522. -        {
  2523. -        zerrnam("function","too many arguments");
  2524. -        return 1;
  2525. -        }
  2526. -    listhtable(shfunchtab,(void (*)(char *,char *)) pshfunc);
  2527. -    return 0;
  2528. -}
  2529. -
  2530. -int (*funcs[])(comm) = {
  2531. -    echo,zexit,logout,Unset,dirs,
  2532. -    Alias,cd,which,popd,
  2533. -   dot,pushd,shift,unhash,Break,
  2534. -    colon,Glob,noglob,mostglob,unalias,
  2535. -    fg,bg,jobs,Kill,export,
  2536. -    Umask,cd,limit,unlimit,eval,
  2537. -    unfunction,set,Brk,log,builtin,
  2538. -    sched,let,fc,
  2539. -    rehash,hash,disown,test,Read,
  2540. -    integer,setopt,unsetopt,zreturn,function,
  2541. -    test,
  2542. -    NULL
  2543. -    };
  2544. -char *funcnams[] = {
  2545. -    "echo","exit","logout","unset","dirs",
  2546. -    "alias","cd","which","popd",
  2547. -    ".","pushd","shift","unhash","break",
  2548. -    ":","glob","noglob","mostglob","unalias",
  2549. -    "fg","bg","jobs","kill","export",
  2550. -    "umask","chdir","limit","unlimit","eval",
  2551. -    "unfunction","set","brk","log","builtin",
  2552. -    "sched","let","fc",
  2553. -    "rehash","hash","disown","test","read",
  2554. -    "integer","setopt","unsetopt","return","function",
  2555. -    "["
  2556. -    };
  2557. -
  2558. -int builtin(comm comm)
  2559. -{
  2560. -char *s;
  2561. -int t0;
  2562. -
  2563. -    s = getnode(comm->args);
  2564. -    if (!s)
  2565. -        {
  2566. -        zerrnam("builtin","not enough arguments");
  2567. -        return 1;
  2568. -        }
  2569. -    for (t0 = 0; funcs[t0]; t0++)
  2570. -        if (!strcmp(funcnams[t0],s))
  2571. -            break;
  2572. -    if (!funcs[t0])
  2573. -        {
  2574. -        zerrnam("builtin","no such builtin: %s",s);
  2575. -        return 1;
  2576. -        }
  2577. -    return (funcs[t0])(comm);
  2578. -}
  2579. -
  2580. -/* add builtins to the command hash table */
  2581. -
  2582. -void addintern(htable ht)
  2583. -{
  2584. -int (**ptr)(comm);
  2585. -struct chnode *ch;
  2586. -char **nam;
  2587. -    for (ptr = funcs, nam = funcnams; *ptr; ptr++,nam++)
  2588. -        {
  2589. -        ch = alloc(sizeof(struct chnode));
  2590. -        ch->type = BUILTIN;
  2591. -        ch->u.func = *ptr;
  2592. -        addhnode(strdup(*nam),ch,ht,freechnode);
  2593. -        }
  2594. -}
  2595. -
  2596. -/* get the time of login/logout for WATCH */
  2597. -
  2598. -static time_t getlogtime(struct utmp *u,int inout)
  2599. -{
  2600. -FILE *in;
  2601. -struct utmp uu;
  2602. -int first = 1;
  2603. -
  2604. -    if (inout)
  2605. -        return u->ut_time;
  2606. -    if (!(in = fopen(WTMP_FILE,"r")))
  2607. -        return time(NULL);
  2608. -    fseek(in,0,2);
  2609. -    do
  2610. -        {
  2611. -        if (fseek(in,((first) ? -1 : -2)*sizeof(struct utmp),1))
  2612. -            {
  2613. -            fclose(in);
  2614. -            return time(NULL);
  2615. -            }
  2616. -        first = 0;
  2617. -        if (!fread(&uu,sizeof(struct utmp),1,in))
  2618. -            {
  2619. -            fclose(in);
  2620. -            return time(NULL);
  2621. -            }
  2622. -        }
  2623. -    while (memcmp(&uu,u,sizeof(struct utmp)));
  2624. -    do
  2625. -        if (!fread(&uu,sizeof(struct utmp),1,in))
  2626. -            {
  2627. -            fclose(in);
  2628. -            return time(NULL);
  2629. -            }
  2630. -    while (strncmp(uu.ut_line,u->ut_line,8));
  2631. -    fclose(in);
  2632. -    return uu.ut_time;
  2633. -}
  2634. -
  2635. -/* print a login/logout event */
  2636. -
  2637. -static void watchlog2(int inout,struct utmp *u,char *fmt)
  2638. -{
  2639. -char *p,buf[40],*bf;
  2640. -int i;
  2641. -time_t timet;
  2642. -struct tm *tm = NULL;
  2643. -
  2644. -    while (*fmt)
  2645. -        if (*fmt != '%')
  2646. -            putchar(*fmt++);
  2647. -        else
  2648. -            {
  2649. -            fmt++;
  2650. -            switch(*fmt++)
  2651. -                {
  2652. -                case 'n':
  2653. -                    printf("%.*s",8,u->ut_name);
  2654. -                    break;
  2655. -                case 'a':
  2656. -                    printf("%s",(!inout) ? "logged off" : "logged on");
  2657. -                    break;
  2658. -                case 'l':
  2659. -                    printf("%.*s",5,u->ut_line+3);
  2660. -                    break;
  2661. -                case 'm':
  2662. -                    for (p = u->ut_host,i = 16; i && *p;i--,p++)
  2663. -                        {
  2664. -                        if (*p == '.' && !isdigit(p[1]))
  2665. -                            break;
  2666. -                        putchar(*p);
  2667. -                        }
  2668. -                    break;
  2669. -                case 'M':
  2670. -                    printf("%.*s",16,u->ut_host);
  2671. -                    break;
  2672. -                case 't':
  2673. -                case '@':
  2674. -                    timet = getlogtime(u,inout);
  2675. -                    tm = localtime(&timet);
  2676. -                    strftime(buf,40,"%l:%M%p",tm);
  2677. -                    printf("%s",(*buf == ' ') ? buf+1 : buf);
  2678. -                    break;
  2679. -                case 'T':
  2680. -                    timet = getlogtime(u,inout);
  2681. -                    tm = localtime(&timet);
  2682. -                    strftime(buf,40,"%k:%M",tm);
  2683. -                    printf("%s",buf);
  2684. -                    break;
  2685. -                case 'w':
  2686. -                    timet = getlogtime(u,inout);
  2687. -                    tm = localtime(&timet);
  2688. -                    strftime(buf,40,"%a %e",tm);
  2689. -                    printf("%s",buf);
  2690. -                    break;
  2691. -                case 'W':
  2692. -                    timet = getlogtime(u,inout);
  2693. -                    tm = localtime(&timet);
  2694. -                    strftime(buf,40,"%m/%d/%y",tm);
  2695. -                    printf("%s",buf);
  2696. -                    break;
  2697. -                case 'D':
  2698. -                    timet = getlogtime(u,inout);
  2699. -                    tm = localtime(&timet);
  2700. -                    strftime(buf,40,"%y-%m-%d",tm);
  2701. -                    printf("%s",buf);
  2702. -                    break;
  2703. -                case '%':
  2704. -                    putchar('%');
  2705. -                    break;
  2706. -                case 'S':
  2707. -                    bf = buf;
  2708. -                    if (tgetstr("so",&bf))
  2709. -                        fputs(buf,stdout);
  2710. -                    break;
  2711. -                case 's':
  2712. -                    bf = buf;
  2713. -                    if (tgetstr("se",&bf))
  2714. -                        fputs(buf,stdout);
  2715. -                    break;
  2716. -                case 'B':
  2717. -                    bf = buf;
  2718. -                    if (tgetstr("md",&bf))
  2719. -                        fputs(buf,stdout);
  2720. -                    break;
  2721. -                case 'b':
  2722. -                    bf = buf;
  2723. -                    if (tgetstr("me",&bf))
  2724. -                        fputs(buf,stdout);
  2725. -                    break;
  2726. -                case 'U':
  2727. -                    bf = buf;
  2728. -                    if (tgetstr("us",&bf))
  2729. -                        fputs(buf,stdout);
  2730. -                    break;
  2731. -                case 'u':
  2732. -                    bf = buf;
  2733. -                    if (tgetstr("ue",&bf))
  2734. -                        fputs(buf,stdout);
  2735. -                    break;
  2736. -                default:
  2737. -                    putchar('%');
  2738. -                    putchar(fmt[-1]);
  2739. -                    break;
  2740. -                }
  2741. -            }
  2742. -    putchar('\n');
  2743. -}
  2744. -
  2745. -/* check the list for login/logouts */
  2746. -
  2747. -static void watchlog(int inout,struct utmp *u,char *w,char *fmt)
  2748. -{
  2749. -char *v;
  2750. -
  2751. -    if (!strcmp(w,"all"))
  2752. -        {
  2753. -        watchlog2(inout,u,fmt);
  2754. -        return;
  2755. -        }
  2756. -    for(;;)
  2757. -        if (v = strchr(w,':'))
  2758. -            {
  2759. -            if (!strncmp(u->ut_name,w,v-w))
  2760. -                watchlog2(inout,u,fmt);
  2761. -            w = v+1;
  2762. -            }
  2763. -        else
  2764. -            {
  2765. -            if (!strncmp(u->ut_name,w,8))
  2766. -                watchlog2(inout,u,fmt);
  2767. -            break;
  2768. -            }
  2769. -}
  2770. -
  2771. -/* compare 2 utmp entries */
  2772. -
  2773. -static int ucmp(struct utmp *u,struct utmp *v)
  2774. -{
  2775. -    if (u->ut_time == v->ut_time)
  2776. -        return strncmp(u->ut_line,v->ut_line,8);
  2777. -    return u->ut_time - v->ut_time;
  2778. -}
  2779. -
  2780. -/* initialize the user list */
  2781. -
  2782. -void readwtab(void)
  2783. -{
  2784. -struct utmp *uptr;
  2785. -int wtabmax = 32;
  2786. -FILE *in;
  2787. -
  2788. -    wtabsz = 0;
  2789. -    uptr = wtab = (struct utmp *) zalloc(wtabmax*sizeof(struct utmp));
  2790. -    in = fopen(UTMP_FILE,"r");
  2791. -    while (fread(uptr,sizeof(struct utmp),1,in))
  2792. -        if (uptr->ut_host[0])
  2793. -            {
  2794. -            uptr++;
  2795. -            if (++wtabsz == wtabmax)
  2796. -                uptr = (wtab = (struct utmp *) realloc(wtab,(wtabmax*=2)*
  2797. -                    sizeof(struct utmp)))+wtabsz;
  2798. -            }
  2799. -    fclose(in);
  2800. -    if (wtabsz)
  2801. -        qsort(wtab,wtabsz,sizeof(struct utmp),ucmp);
  2802. -}
  2803. -
  2804. -/* check for login/logout events; executed before each prompt
  2805. -    if WATCH is set */
  2806. -
  2807. -void watch(void)
  2808. -{
  2809. -char *s = getparm("WATCH");
  2810. -char *fmt = getparm("WATCHFMT");
  2811. -FILE *in;
  2812. -int utabsz = 0,utabmax = wtabsz+4,uct,wct;
  2813. -struct utmp *utab,*uptr,*wptr;
  2814. -
  2815. -    holdintr();
  2816. -    if (!fmt)
  2817. -        fmt = "%n has %a %l from %m.";
  2818. -    if (!wtab)
  2819. -        {
  2820. -        readwtab();
  2821. -        noholdintr();
  2822. -        return;
  2823. -        }
  2824. -    uptr = utab = (struct utmp *) zalloc(utabmax*sizeof(struct utmp));
  2825. -    in = fopen(UTMP_FILE,"r");
  2826. -    while (fread(uptr,sizeof *uptr,1,in))
  2827. -        if (uptr->ut_host[0])
  2828. -            {
  2829. -            uptr++;
  2830. -            if (++utabsz == utabmax)
  2831. -                uptr = (utab = (struct utmp *) realloc(utab,(utabmax*=2)*
  2832. -                    sizeof(struct utmp)))+utabsz;
  2833. -            }
  2834. -    fclose(in);
  2835. -    noholdintr();
  2836. -    if (errflag)
  2837. -        {
  2838. -        free(utab);
  2839. -        return;
  2840. -        }
  2841. -    if (utabsz)
  2842. -        qsort(utab,utabsz,sizeof(struct utmp),ucmp);
  2843. -
  2844. -    wct = wtabsz; uct = utabsz;
  2845. -    uptr = utab; wptr = wtab;
  2846. -    if (errflag)
  2847. -        {
  2848. -        free(utab);
  2849. -        return;
  2850. -        }
  2851. -    while ((uct || wct) && !errflag)
  2852. -        if (!uct || (wct && ucmp(uptr,wptr) > 0))
  2853. -            wct--,watchlog(0,wptr++,s,fmt);
  2854. -        else if (!wct || (uct && ucmp(uptr,wptr) < 0))
  2855. -            uct--,watchlog(1,uptr++,s,fmt);
  2856. -        else
  2857. -            uptr++,wptr++,wct--,uct--;
  2858. -    free(wtab);
  2859. -    wtab = utab;
  2860. -    wtabsz = utabsz;
  2861. -    fflush(stdout);
  2862. -}
  2863. -
  2864. End of builtin.c
  2865. echo builtin.pro 1>&2
  2866. sed 's/^-//' >builtin.pro <<'End of builtin.pro'
  2867. -int echo(comm comm);
  2868. -void pdstack(void);
  2869. -int zexit(comm comm);
  2870. -int zreturn(comm comm);
  2871. -int logout(comm comm);
  2872. -int Unset(comm comm);
  2873. -int set(comm comm);
  2874. -int setopt(comm comm);
  2875. -int unsetopt(comm comm);
  2876. -int csetopt(comm comm,int isun);
  2877. -void pparm(char *s,struct pmnode *t);
  2878. -int dirs(comm comm);
  2879. -void listhtable(htable ht,void (*func)(char *,char *));
  2880. -void palias(char *s,struct anode *t);
  2881. -void pshfunc(char *s,list l);
  2882. -void niceprint(char *s);
  2883. -void niceprintf(char *s,FILE *f);
  2884. -char *buildline(table t);
  2885. -int Alias(comm comm);
  2886. -int cd(comm comm);
  2887. -int dot(comm comm);
  2888. -int Umask(comm comm);
  2889. -int which(comm comm);
  2890. -int popd(comm comm);
  2891. -int pushd(comm comm);
  2892. -int chcd(char *cnam,char *cd);
  2893. -int shift(comm comm);
  2894. -int unhash(comm comm);
  2895. -int rehash(comm comm);
  2896. -int hash(comm comm);
  2897. -int Break(comm comm);
  2898. -int colon(comm comm);
  2899. -int Glob(comm comm);
  2900. -int noglob(comm comm);
  2901. -int mostglob(comm comm);
  2902. -int unfunction(comm comm);
  2903. -int unalias(comm comm);
  2904. -int prefix(char *s,char *t);
  2905. -int getjob(char *s,char *prog);
  2906. -int fg(comm comm);
  2907. -int bg(comm comm);
  2908. -int jobs(comm comm);
  2909. -int Kill(comm comm);
  2910. -int export(comm comm);
  2911. -int integer(comm comm);
  2912. -int limit(comm comm);
  2913. -int unlimit(comm comm);
  2914. -void showlimits(int hard,int lim);
  2915. -int sched(comm comm);
  2916. -int eval(comm comm);
  2917. -int Brk(comm comm);
  2918. -int log(comm comm);
  2919. -int let(comm comm);
  2920. -int Read(comm comm);
  2921. -int fc(comm comm);
  2922. -int fcgetcomm(char *s);
  2923. -int fclist(FILE *f,int n,int r,int first,int last,table subs);
  2924. -int fcsubs(char **sp,table tab);
  2925. -int fcedit(char *ename,char *fn);
  2926. -int disown(comm comm);
  2927. -int function(comm comm);
  2928. -int builtin(comm comm);
  2929. -void addintern(htable ht);
  2930. -void readwtab(void);
  2931. -void watch(void);
  2932. End of builtin.pro
  2933. echo config.h 1>&2
  2934. sed 's/^-//' >config.h <<'End of config.h'
  2935. -/*
  2936. -
  2937. -    config.h - configuration file
  2938. -
  2939. -    This file is part of zsh, the Z shell.
  2940. -
  2941. -   zsh is free software; no one can prevent you from reading the source
  2942. -   code, or giving it to someone else.
  2943. -   This file is copyrighted under the GNU General Public License, which
  2944. -   can be found in the file called COPYING.
  2945. -
  2946. -   Copyright (C) 1990 Paul Falstad
  2947. -
  2948. -   zsh is distributed in the hope that it will be useful, but
  2949. -   WITHOUT ANY WARRANTY.  No author or distributor accepts
  2950. -   responsibility to anyone for the consequences of using it or for
  2951. -   whether it serves any particular purpose or works at all, unless he
  2952. -   says so in writing.  Refer to the GNU General Public License
  2953. -   for full details.
  2954. -
  2955. -   Everyone is granted permission to copy, modify and redistribute
  2956. -   zsh, but only under the conditions described in the GNU General Public
  2957. -   License.   A copy of this license is supposed to have been given to you
  2958. -   along with zsh so you can know your rights and responsibilities.
  2959. -   It should be in a file named COPYING.
  2960. -
  2961. -   Among other things, the copyright notice and this notice must be
  2962. -   preserved on all copies.
  2963. -
  2964. -*/
  2965. -
  2966. -/* define this if you have WAITPID */
  2967. -
  2968. -#define WAITPID
  2969. -
  2970. -/* define if the return type of signal handlers is int */
  2971. -
  2972. -/* #define INTHANDTYPE  */
  2973. -
  2974. -/* the return type of handlers */
  2975. -
  2976. -#define HANDTYPE void
  2977. -
  2978. -/* define this if you have putenv */
  2979. -
  2980. -#define PUTENV 
  2981. -
  2982. -/* define this if you have strstr */
  2983. -
  2984. -#define STRSTR
  2985. -
  2986. -/* define this if you have strftime */
  2987. -
  2988. -/* #define STRFTIME */
  2989. -
  2990. -/* define if you have struct termios, else struct sgttyb */
  2991. -
  2992. -#define TERMIOS
  2993. -
  2994. -#include "config.local.h"
  2995. -
  2996. End of config.h
  2997. echo config.local.h 1>&2
  2998. sed 's/^-//' >config.local.h <<'End of config.local.h'
  2999. -/*
  3000. -
  3001. -    config.local.h - local machine configuration file
  3002. -
  3003. -    This file is part of zsh, the Z shell.
  3004. -
  3005. -   zsh is free software; no one can prevent you from reading the source
  3006. -   code, or giving it to someone else.
  3007. -   This file is copyrighted under the GNU General Public License, which
  3008. -   can be found in the file called COPYING.
  3009. -
  3010. -   Copyright (C) 1990 Paul Falstad
  3011. -
  3012. -   zsh is distributed in the hope that it will be useful, but
  3013. -   WITHOUT ANY WARRANTY.  No author or distributor accepts
  3014. -   responsibility to anyone for the consequences of using it or for
  3015. -   whether it serves any particular purpose or works at all, unless he
  3016. -   says so in writing.  Refer to the GNU General Public License
  3017. -   for full details.
  3018. -
  3019. -   Everyone is granted permission to copy, modify and redistribute
  3020. -   zsh, but only under the conditions described in the GNU General Public
  3021. -   License.   A copy of this license is supposed to have been given to you
  3022. -   along with zsh so you can know your rights and responsibilities.
  3023. -   It should be in a file named COPYING.
  3024. -
  3025. -   Among other things, the copyright notice and this notice must be
  3026. -   preserved on all copies.
  3027. -
  3028. -*/
  3029. -
  3030. -/* a string corresponding to the host type */
  3031. -
  3032. -#define HOSTTYP "sun4"
  3033. -
  3034. -/* define if you prefer "suspended" to "stopped" */
  3035. -
  3036. -#define USE_SUSPENDED
  3037. -
  3038. -/* the path of zsh in the file system */
  3039. -
  3040. -#define MYSELF "/usr/princeton/bin/zsh"
  3041. -
  3042. -/* the default editor for the fc builtin */
  3043. -
  3044. -#define DEFFCEDIT "/usr/ucb/vi"
  3045. -
  3046. -/* the file to source whenever zsh is run; if undefined, don't source
  3047. -    anything */
  3048. -
  3049. -#define GLOBALZSHRC "/etc/zshrc"
  3050. -
  3051. -/* the file to source whenever zsh is run as a login shell; if
  3052. -    undefined, don't source anything */
  3053. -
  3054. -#define GLOBALZLOGIN "/etc/zlogin"
  3055. -
  3056. -/* the default HISTSIZE */
  3057. -
  3058. -#define DEFAULT_HISTSIZE 128
  3059. -
  3060. -/* the path of utmp */
  3061. -
  3062. -#define UTMP_FILE "/etc/utmp"
  3063. -
  3064. -/* the path of wtmp */
  3065. -
  3066. -#define WTMP_FILE "/var/adm/wtmp"
  3067. -
  3068. -/* define if you have problems with job control or tty modes.
  3069. -    gcc-cpp does not seem to handle ioctls correctly. */
  3070. -
  3071. -/*#define BUGGY_GCC*/
  3072. -
  3073. -/* define if you like interactive comments */
  3074. -
  3075. -/*#define INTERACTIVE_COMMENTS*/
  3076. -
  3077. -/* define if you want warnings about nonexistent path components */
  3078. -
  3079. -#define PATH_WARNINGS
  3080. -
  3081. End of config.local.h
  3082. echo exec.c 1>&2
  3083. sed 's/^-//' >exec.c <<'End of exec.c'
  3084. -/*
  3085. -
  3086. -    exec.c - command execution
  3087. -
  3088. -    This file is part of zsh, the Z shell.
  3089. -
  3090. -   zsh is free software; no one can prevent you from reading the source
  3091. -   code, or giving it to someone else.
  3092. -   This file is copyrighted under the GNU General Public License, which
  3093. -   can be found in the file called COPYING.
  3094. -
  3095. -   Copyright (C) 1990 Paul Falstad
  3096. -
  3097. -   zsh is distributed in the hope that it will be useful, but
  3098. -   WITHOUT ANY WARRANTY.  No author or distributor accepts
  3099. -   responsibility to anyone for the consequences of using it or for
  3100. -   whether it serves any particular purpose or works at all, unless he
  3101. -   says so in writing.  Refer to the GNU General Public License
  3102. -   for full details.
  3103. -
  3104. -   Everyone is granted permission to copy, modify and redistribute
  3105. -   zsh, but only under the conditions described in the GNU General Public
  3106. -   License.   A copy of this license is supposed to have been given to you
  3107. -   along with zsh so you can know your rights and responsibilities.
  3108. -   It should be in a file named COPYING.
  3109. -
  3110. -   Among other things, the copyright notice and this notice must be
  3111. -   preserved on all copies.
  3112. -
  3113. -*/
  3114. -
  3115. -#include "zsh.h"
  3116. -#include "funcs.h"
  3117. -#include <sys/errno.h>
  3118. -#include <sys/dir.h>
  3119. -
  3120. -#define execerr() { if (forked) exit(1); freecmd(comm); \
  3121. -    closemnodes(mfds); errflag = 1; return; }
  3122. -#define magicerr() { if (magic) putc('\n',stderr); errflag = 1; }
  3123. -
  3124. -/* execute a string */
  3125. -
  3126. -void execstring(char *s)
  3127. -{
  3128. -list l;
  3129. -
  3130. -    hungets(strdup("\n"));
  3131. -    hungets(s);
  3132. -    strinbeg();
  3133. -    if (!(l = parlist(1)))
  3134. -        {
  3135. -        strinend();
  3136. -        hflush();
  3137. -        return;
  3138. -        }
  3139. -    if (peek != EOF && peek != EMPTY)
  3140. -        {
  3141. -        strinend();
  3142. -        hflush();
  3143. -        return;
  3144. -        }
  3145. -    strinend();
  3146. -    execlist(l);
  3147. -}
  3148. -
  3149. -/* duplicate a list and run it */
  3150. -
  3151. -void newrunlist(list l)
  3152. -{
  3153. -list a = duplist(l); runlist(a);
  3154. -}
  3155. -
  3156. -/* fork and set limits */
  3157. -
  3158. -int phork(void)
  3159. -{
  3160. -int pid = fork(),t0;
  3161. -
  3162. -    if (pid == -1)
  3163. -        {
  3164. -        zerr("fork failed: %e",errno);
  3165. -        return -1;
  3166. -        }
  3167. -    if (!pid)
  3168. -        for (t0 = 0; t0 != RLIM_NLIMITS; t0++)
  3169. -            setrlimit(t0,limits+t0);
  3170. -    return pid;
  3171. -}
  3172. -
  3173. -/* execute a current shell command */
  3174. -
  3175. -void execcursh(comm comm)
  3176. -{
  3177. -    runlist(comm->left);
  3178. -    comm->left = NULL;
  3179. -}
  3180. -
  3181. -/* execve an external command */
  3182. -
  3183. -void execute(char *arg0,table args)
  3184. -{
  3185. -char **argv;
  3186. -char *z,*s,buf[MAXPATHLEN],buf2[MAXPATHLEN];
  3187. -struct chnode *cn;
  3188. -int t0,tl,ee = 0;
  3189. -
  3190. -#define zexecve(X,Y,Z) {execve(z=(X),Y,Z);\
  3191. -    if(errno!=ENOENT){ee = errno;strcpy(buf2,buf);}}
  3192. -
  3193. -    cn = gethnode(arg0,chtab);
  3194. -    if (s = getenv("STTY"))
  3195. -        zyztem("stty",s);
  3196. -    if (z = getenv("ARGV0"))
  3197. -        z = strdup(z);
  3198. -    else
  3199. -        z = arg0;
  3200. -    argv = makecline(z,args);
  3201. -    fixsigs();
  3202. -    if (cn)
  3203. -        {
  3204. -        if (cn->type == EXCMD_POSTDOT)
  3205. -            {zexecve(arg0,argv,environ);}
  3206. -        {zexecve(cn->u.nam,argv,environ);}
  3207. -        }
  3208. -    for (s = arg0; *s; s++)
  3209. -        if (*s == '/')
  3210. -            {
  3211. -            execve(arg0,argv,environ);
  3212. -            zerr("%e: %s",errno,arg0);
  3213. -            _exit(1);
  3214. -            }
  3215. -    for (t0 = pathct; t0; t0--,path++)
  3216. -        if (**path == '.')
  3217. -            {zexecve(arg0,argv,environ);}
  3218. -        else
  3219. -            {
  3220. -            tl = strlen(*path);
  3221. -            strcpy(buf,*path);
  3222. -            buf[tl] = '/';
  3223. -            if (strlen(arg0)+strlen(buf)+1 >= MAXPATHLEN)
  3224. -                {
  3225. -                zerr("command too long: %s",arg0);
  3226. -                _exit(1);
  3227. -                }
  3228. -            strcpy(buf+tl+1,arg0);
  3229. -            {zexecve(buf,argv,environ);}
  3230. -            }
  3231. -    if (ee)
  3232. -        {
  3233. -        z = buf2;
  3234. -        errno = ee;
  3235. -        goto errs;
  3236. -        }
  3237. -    zerr("command not found: %s",arg0);
  3238. -    _exit(1);
  3239. -errs:
  3240. -    zerr("%e: %s",errno,z);
  3241. -    _exit(1);
  3242. -}
  3243. -
  3244. -#define try(X) { if (!access(X,X_OK)) return strdup(X); }
  3245. -
  3246. -/* get the pathname of a command */
  3247. -
  3248. -char *findcmd(char *arg0)
  3249. -{
  3250. -char *s,buf[MAXPATHLEN];
  3251. -int t0,tl;
  3252. -struct chnode *cn = gethnode(arg0,chtab);
  3253. -char **pp = path;
  3254. -
  3255. -    if (cn)
  3256. -        {
  3257. -        if (cn->type == EXCMD_POSTDOT)
  3258. -            {
  3259. -            strcpy(buf,"./");
  3260. -            strcat(buf,arg0);
  3261. -            try(buf);
  3262. -            }
  3263. -        try(cn->u.nam);
  3264. -        }
  3265. -    for (s = arg0; *s; s++)
  3266. -        if (*s == '/')
  3267. -            {
  3268. -            try(arg0);
  3269. -            goto failed;
  3270. -            }
  3271. -    for (t0 = pathct; t0; t0--,pp++)
  3272. -        if (**pp == '.')
  3273. -            {
  3274. -            strcpy(buf,"./");
  3275. -            strcat(buf,arg0);
  3276. -            try(buf);
  3277. -            }
  3278. -        else
  3279. -            {
  3280. -            tl = strlen(*pp);
  3281. -            strcpy(buf,*pp);
  3282. -            buf[tl] = '/';
  3283. -            strcpy(buf+tl+1,arg0);
  3284. -            try(buf);
  3285. -            }
  3286. -failed:
  3287. -    return NULL;
  3288. -}
  3289. -
  3290. -void execlist(list list)
  3291. -{
  3292. -    execlist1(list);
  3293. -    freelist(list);
  3294. -}
  3295. -
  3296. -void execlist1(list list)
  3297. -{
  3298. -    if (breaks)
  3299. -        return;
  3300. -    switch(list->type)
  3301. -        {
  3302. -        case SYNC:
  3303. -        case ASYNC:
  3304. -            execlist2(list->left,list->type,!list->right);
  3305. -            if (sigtrapped[SIGDEBUG])
  3306. -                dotrap(SIGDEBUG);
  3307. -            if (sigtrapped[SIGERR] && lastval)
  3308. -                dotrap(SIGERR);
  3309. -            if (list->right && !retflag)
  3310. -                execlist1(list->right);
  3311. -            break;
  3312. -        }
  3313. -}
  3314. -
  3315. -void execlist2(list2 list,int type,int last1)
  3316. -{
  3317. -    switch(list->type)
  3318. -        {
  3319. -        case END:
  3320. -            execpline(list,type,last1);
  3321. -            break;
  3322. -        case ORNEXT:
  3323. -            if (!execpline(list,SYNC,0))
  3324. -                execlist2(list->right,type,last1);
  3325. -            break;
  3326. -        case ANDNEXT:
  3327. -            if (execpline(list,SYNC,0))
  3328. -                execlist2(list->right,type,last1);
  3329. -            break;
  3330. -        }
  3331. -}
  3332. -
  3333. -int execpline(list2 l,int how,int last1)
  3334. -{
  3335. -int ipipe[2] = {0,0},opipe[2] = {0,0};
  3336. -
  3337. -    sigblock(sigmask(SIGCHLD));
  3338. -    curjob = getfreejob(); 
  3339. -    initjob(l->flags);
  3340. -    if (l->flags & PFLAG_COPROC)
  3341. -        {
  3342. -        how = ASYNC;
  3343. -        mpipe(ipipe);
  3344. -        mpipe(opipe);
  3345. -        if (spin)
  3346. -            {
  3347. -            close(spin);
  3348. -            close(spout);
  3349. -            }
  3350. -        spin = ipipe[0];
  3351. -        spout = opipe[1];
  3352. -        }
  3353. -    execpline2(l->left,how,opipe[0],ipipe[1],last1);
  3354. -    if (how == ASYNC)
  3355. -        {
  3356. -        spawnjob();
  3357. -        sigsetmask(0);
  3358. -        return 1;
  3359. -        }
  3360. -    else
  3361. -        {
  3362. -        waitjobs();
  3363. -        sigsetmask(0);
  3364. -        if (l->flags & PFLAG_NOT)
  3365. -            lastval = !lastval;
  3366. -        return !lastval;
  3367. -        }
  3368. -}
  3369. -
  3370. -void execpline2(pline pline,int how,int input,int output,int last1)
  3371. -{
  3372. -int pid;
  3373. -int pipes[2];
  3374. -
  3375. -    if (breaks)
  3376. -        return;
  3377. -    if (!pline)
  3378. -        return;
  3379. -    if (pline->type == END)
  3380. -        {
  3381. -        execcomm(pline->left,input,output,how==ASYNC,last1);
  3382. -        pline->left = NULL;
  3383. -        }
  3384. -    else
  3385. -        {
  3386. -        mpipe(pipes);
  3387. -
  3388. -        /* if we are doing "foo | bar" where foo is a current
  3389. -            shell command, do foo in the current shell and do
  3390. -            the rest of the pipeline in a subshell. */
  3391. -
  3392. -        if (pline->left->type >= CURSH && how == SYNC)
  3393. -            {
  3394. -            if (!(pid = fork()))
  3395. -                {
  3396. ---cut here---cut here---cut here---
  3397.