Initial revision
This commit is contained in:
commit
1b3b46907a
16 changed files with 2618 additions and 0 deletions
26
.cvsignore
Normal file
26
.cvsignore
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
tags
|
||||||
|
Makefile
|
||||||
|
Makefile.in
|
||||||
|
.deps
|
||||||
|
.libs
|
||||||
|
*.lo
|
||||||
|
*.la
|
||||||
|
*.so*
|
||||||
|
aclocal.m4
|
||||||
|
config.guess
|
||||||
|
config.h.in
|
||||||
|
config.sub
|
||||||
|
configure
|
||||||
|
install-sh
|
||||||
|
ltmain.sh
|
||||||
|
missing
|
||||||
|
mkinstalldirs
|
||||||
|
stamp-h.in
|
||||||
|
stamp-h
|
||||||
|
config.cache
|
||||||
|
config.h
|
||||||
|
config.log
|
||||||
|
config.status
|
||||||
|
libtool
|
||||||
|
*.tar.gz
|
||||||
|
*.info
|
7
AUTHORS
Normal file
7
AUTHORS
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
Stow was written by Bob Glickstein <bobg+stow@zanshin.com>, Zanshin
|
||||||
|
Software, Inc.
|
||||||
|
|
||||||
|
Contributions from Gord Matzigkeit <gord@enci.ucalgary.ca>.
|
||||||
|
|
||||||
|
John Bazik wrote `fastcwd', the Perl subroutine for computing the
|
||||||
|
current working directory.
|
339
COPYING
Normal file
339
COPYING
Normal file
|
@ -0,0 +1,339 @@
|
||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
Version 2, June 1991
|
||||||
|
|
||||||
|
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||||
|
675 Mass Ave, Cambridge, MA 02139, USA
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The licenses for most software are designed to take away your
|
||||||
|
freedom to share and change it. By contrast, the GNU General Public
|
||||||
|
License is intended to guarantee your freedom to share and change free
|
||||||
|
software--to make sure the software is free for all its users. This
|
||||||
|
General Public License applies to most of the Free Software
|
||||||
|
Foundation's software and to any other program whose authors commit to
|
||||||
|
using it. (Some other Free Software Foundation software is covered by
|
||||||
|
the GNU Library General Public License instead.) You can apply it to
|
||||||
|
your programs, too.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom, not
|
||||||
|
price. Our General Public Licenses are designed to make sure that you
|
||||||
|
have the freedom to distribute copies of free software (and charge for
|
||||||
|
this service if you wish), that you receive source code or can get it
|
||||||
|
if you want it, that you can change the software or use pieces of it
|
||||||
|
in new free programs; and that you know you can do these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to make restrictions that forbid
|
||||||
|
anyone to deny you these rights or to ask you to surrender the rights.
|
||||||
|
These restrictions translate to certain responsibilities for you if you
|
||||||
|
distribute copies of the software, or if you modify it.
|
||||||
|
|
||||||
|
For example, if you distribute copies of such a program, whether
|
||||||
|
gratis or for a fee, you must give the recipients all the rights that
|
||||||
|
you have. You must make sure that they, too, receive or can get the
|
||||||
|
source code. And you must show them these terms so they know their
|
||||||
|
rights.
|
||||||
|
|
||||||
|
We protect your rights with two steps: (1) copyright the software, and
|
||||||
|
(2) offer you this license which gives you legal permission to copy,
|
||||||
|
distribute and/or modify the software.
|
||||||
|
|
||||||
|
Also, for each author's protection and ours, we want to make certain
|
||||||
|
that everyone understands that there is no warranty for this free
|
||||||
|
software. If the software is modified by someone else and passed on, we
|
||||||
|
want its recipients to know that what they have is not the original, so
|
||||||
|
that any problems introduced by others will not reflect on the original
|
||||||
|
authors' reputations.
|
||||||
|
|
||||||
|
Finally, any free program is threatened constantly by software
|
||||||
|
patents. We wish to avoid the danger that redistributors of a free
|
||||||
|
program will individually obtain patent licenses, in effect making the
|
||||||
|
program proprietary. To prevent this, we have made it clear that any
|
||||||
|
patent must be licensed for everyone's free use or not licensed at all.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and
|
||||||
|
modification follow.
|
||||||
|
|
||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
|
||||||
|
0. This License applies to any program or other work which contains
|
||||||
|
a notice placed by the copyright holder saying it may be distributed
|
||||||
|
under the terms of this General Public License. The "Program", below,
|
||||||
|
refers to any such program or work, and a "work based on the Program"
|
||||||
|
means either the Program or any derivative work under copyright law:
|
||||||
|
that is to say, a work containing the Program or a portion of it,
|
||||||
|
either verbatim or with modifications and/or translated into another
|
||||||
|
language. (Hereinafter, translation is included without limitation in
|
||||||
|
the term "modification".) Each licensee is addressed as "you".
|
||||||
|
|
||||||
|
Activities other than copying, distribution and modification are not
|
||||||
|
covered by this License; they are outside its scope. The act of
|
||||||
|
running the Program is not restricted, and the output from the Program
|
||||||
|
is covered only if its contents constitute a work based on the
|
||||||
|
Program (independent of having been made by running the Program).
|
||||||
|
Whether that is true depends on what the Program does.
|
||||||
|
|
||||||
|
1. You may copy and distribute verbatim copies of the Program's
|
||||||
|
source code as you receive it, in any medium, provided that you
|
||||||
|
conspicuously and appropriately publish on each copy an appropriate
|
||||||
|
copyright notice and disclaimer of warranty; keep intact all the
|
||||||
|
notices that refer to this License and to the absence of any warranty;
|
||||||
|
and give any other recipients of the Program a copy of this License
|
||||||
|
along with the Program.
|
||||||
|
|
||||||
|
You may charge a fee for the physical act of transferring a copy, and
|
||||||
|
you may at your option offer warranty protection in exchange for a fee.
|
||||||
|
|
||||||
|
2. You may modify your copy or copies of the Program or any portion
|
||||||
|
of it, thus forming a work based on the Program, and copy and
|
||||||
|
distribute such modifications or work under the terms of Section 1
|
||||||
|
above, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) You must cause the modified files to carry prominent notices
|
||||||
|
stating that you changed the files and the date of any change.
|
||||||
|
|
||||||
|
b) You must cause any work that you distribute or publish, that in
|
||||||
|
whole or in part contains or is derived from the Program or any
|
||||||
|
part thereof, to be licensed as a whole at no charge to all third
|
||||||
|
parties under the terms of this License.
|
||||||
|
|
||||||
|
c) If the modified program normally reads commands interactively
|
||||||
|
when run, you must cause it, when started running for such
|
||||||
|
interactive use in the most ordinary way, to print or display an
|
||||||
|
announcement including an appropriate copyright notice and a
|
||||||
|
notice that there is no warranty (or else, saying that you provide
|
||||||
|
a warranty) and that users may redistribute the program under
|
||||||
|
these conditions, and telling the user how to view a copy of this
|
||||||
|
License. (Exception: if the Program itself is interactive but
|
||||||
|
does not normally print such an announcement, your work based on
|
||||||
|
the Program is not required to print an announcement.)
|
||||||
|
|
||||||
|
These requirements apply to the modified work as a whole. If
|
||||||
|
identifiable sections of that work are not derived from the Program,
|
||||||
|
and can be reasonably considered independent and separate works in
|
||||||
|
themselves, then this License, and its terms, do not apply to those
|
||||||
|
sections when you distribute them as separate works. But when you
|
||||||
|
distribute the same sections as part of a whole which is a work based
|
||||||
|
on the Program, the distribution of the whole must be on the terms of
|
||||||
|
this License, whose permissions for other licensees extend to the
|
||||||
|
entire whole, and thus to each and every part regardless of who wrote it.
|
||||||
|
|
||||||
|
Thus, it is not the intent of this section to claim rights or contest
|
||||||
|
your rights to work written entirely by you; rather, the intent is to
|
||||||
|
exercise the right to control the distribution of derivative or
|
||||||
|
collective works based on the Program.
|
||||||
|
|
||||||
|
In addition, mere aggregation of another work not based on the Program
|
||||||
|
with the Program (or with a work based on the Program) on a volume of
|
||||||
|
a storage or distribution medium does not bring the other work under
|
||||||
|
the scope of this License.
|
||||||
|
|
||||||
|
3. You may copy and distribute the Program (or a work based on it,
|
||||||
|
under Section 2) in object code or executable form under the terms of
|
||||||
|
Sections 1 and 2 above provided that you also do one of the following:
|
||||||
|
|
||||||
|
a) Accompany it with the complete corresponding machine-readable
|
||||||
|
source code, which must be distributed under the terms of Sections
|
||||||
|
1 and 2 above on a medium customarily used for software interchange; or,
|
||||||
|
|
||||||
|
b) Accompany it with a written offer, valid for at least three
|
||||||
|
years, to give any third party, for a charge no more than your
|
||||||
|
cost of physically performing source distribution, a complete
|
||||||
|
machine-readable copy of the corresponding source code, to be
|
||||||
|
distributed under the terms of Sections 1 and 2 above on a medium
|
||||||
|
customarily used for software interchange; or,
|
||||||
|
|
||||||
|
c) Accompany it with the information you received as to the offer
|
||||||
|
to distribute corresponding source code. (This alternative is
|
||||||
|
allowed only for noncommercial distribution and only if you
|
||||||
|
received the program in object code or executable form with such
|
||||||
|
an offer, in accord with Subsection b above.)
|
||||||
|
|
||||||
|
The source code for a work means the preferred form of the work for
|
||||||
|
making modifications to it. For an executable work, complete source
|
||||||
|
code means all the source code for all modules it contains, plus any
|
||||||
|
associated interface definition files, plus the scripts used to
|
||||||
|
control compilation and installation of the executable. However, as a
|
||||||
|
special exception, the source code distributed need not include
|
||||||
|
anything that is normally distributed (in either source or binary
|
||||||
|
form) with the major components (compiler, kernel, and so on) of the
|
||||||
|
operating system on which the executable runs, unless that component
|
||||||
|
itself accompanies the executable.
|
||||||
|
|
||||||
|
If distribution of executable or object code is made by offering
|
||||||
|
access to copy from a designated place, then offering equivalent
|
||||||
|
access to copy the source code from the same place counts as
|
||||||
|
distribution of the source code, even though third parties are not
|
||||||
|
compelled to copy the source along with the object code.
|
||||||
|
|
||||||
|
4. You may not copy, modify, sublicense, or distribute the Program
|
||||||
|
except as expressly provided under this License. Any attempt
|
||||||
|
otherwise to copy, modify, sublicense or distribute the Program is
|
||||||
|
void, and will automatically terminate your rights under this License.
|
||||||
|
However, parties who have received copies, or rights, from you under
|
||||||
|
this License will not have their licenses terminated so long as such
|
||||||
|
parties remain in full compliance.
|
||||||
|
|
||||||
|
5. You are not required to accept this License, since you have not
|
||||||
|
signed it. However, nothing else grants you permission to modify or
|
||||||
|
distribute the Program or its derivative works. These actions are
|
||||||
|
prohibited by law if you do not accept this License. Therefore, by
|
||||||
|
modifying or distributing the Program (or any work based on the
|
||||||
|
Program), you indicate your acceptance of this License to do so, and
|
||||||
|
all its terms and conditions for copying, distributing or modifying
|
||||||
|
the Program or works based on it.
|
||||||
|
|
||||||
|
6. Each time you redistribute the Program (or any work based on the
|
||||||
|
Program), the recipient automatically receives a license from the
|
||||||
|
original licensor to copy, distribute or modify the Program subject to
|
||||||
|
these terms and conditions. You may not impose any further
|
||||||
|
restrictions on the recipients' exercise of the rights granted herein.
|
||||||
|
You are not responsible for enforcing compliance by third parties to
|
||||||
|
this License.
|
||||||
|
|
||||||
|
7. If, as a consequence of a court judgment or allegation of patent
|
||||||
|
infringement or for any other reason (not limited to patent issues),
|
||||||
|
conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot
|
||||||
|
distribute so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you
|
||||||
|
may not distribute the Program at all. For example, if a patent
|
||||||
|
license would not permit royalty-free redistribution of the Program by
|
||||||
|
all those who receive copies directly or indirectly through you, then
|
||||||
|
the only way you could satisfy both it and this License would be to
|
||||||
|
refrain entirely from distribution of the Program.
|
||||||
|
|
||||||
|
If any portion of this section is held invalid or unenforceable under
|
||||||
|
any particular circumstance, the balance of the section is intended to
|
||||||
|
apply and the section as a whole is intended to apply in other
|
||||||
|
circumstances.
|
||||||
|
|
||||||
|
It is not the purpose of this section to induce you to infringe any
|
||||||
|
patents or other property right claims or to contest validity of any
|
||||||
|
such claims; this section has the sole purpose of protecting the
|
||||||
|
integrity of the free software distribution system, which is
|
||||||
|
implemented by public license practices. Many people have made
|
||||||
|
generous contributions to the wide range of software distributed
|
||||||
|
through that system in reliance on consistent application of that
|
||||||
|
system; it is up to the author/donor to decide if he or she is willing
|
||||||
|
to distribute software through any other system and a licensee cannot
|
||||||
|
impose that choice.
|
||||||
|
|
||||||
|
This section is intended to make thoroughly clear what is believed to
|
||||||
|
be a consequence of the rest of this License.
|
||||||
|
|
||||||
|
8. If the distribution and/or use of the Program is restricted in
|
||||||
|
certain countries either by patents or by copyrighted interfaces, the
|
||||||
|
original copyright holder who places the Program under this License
|
||||||
|
may add an explicit geographical distribution limitation excluding
|
||||||
|
those countries, so that distribution is permitted only in or among
|
||||||
|
countries not thus excluded. In such case, this License incorporates
|
||||||
|
the limitation as if written in the body of this License.
|
||||||
|
|
||||||
|
9. The Free Software Foundation may publish revised and/or new versions
|
||||||
|
of the General Public License from time to time. Such new versions will
|
||||||
|
be similar in spirit to the present version, but may differ in detail to
|
||||||
|
address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the Program
|
||||||
|
specifies a version number of this License which applies to it and "any
|
||||||
|
later version", you have the option of following the terms and conditions
|
||||||
|
either of that version or of any later version published by the Free
|
||||||
|
Software Foundation. If the Program does not specify a version number of
|
||||||
|
this License, you may choose any version ever published by the Free Software
|
||||||
|
Foundation.
|
||||||
|
|
||||||
|
10. If you wish to incorporate parts of the Program into other free
|
||||||
|
programs whose distribution conditions are different, write to the author
|
||||||
|
to ask for permission. For software which is copyrighted by the Free
|
||||||
|
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||||
|
make exceptions for this. Our decision will be guided by the two goals
|
||||||
|
of preserving the free status of all derivatives of our free software and
|
||||||
|
of promoting the sharing and reuse of software generally.
|
||||||
|
|
||||||
|
NO WARRANTY
|
||||||
|
|
||||||
|
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||||
|
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||||
|
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||||
|
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||||
|
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||||
|
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||||
|
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||||
|
REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||||
|
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||||
|
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||||
|
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||||
|
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||||
|
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||||
|
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||||
|
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGES.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
Appendix: How to Apply These Terms to Your New Programs
|
||||||
|
|
||||||
|
If you develop a new program, and you want it to be of the greatest
|
||||||
|
possible use to the public, the best way to achieve this is to make it
|
||||||
|
free software which everyone can redistribute and change under these terms.
|
||||||
|
|
||||||
|
To do so, attach the following notices to the program. It is safest
|
||||||
|
to attach them to the start of each source file to most effectively
|
||||||
|
convey the exclusion of warranty; and each file should have at least
|
||||||
|
the "copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
<one line to give the program's name and a brief idea of what it does.>
|
||||||
|
Copyright (C) 19yy <name of author>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
|
||||||
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
If the program is interactive, make it output a short notice like this
|
||||||
|
when it starts in an interactive mode:
|
||||||
|
|
||||||
|
Gnomovision version 69, Copyright (C) 19yy name of author
|
||||||
|
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||||
|
This is free software, and you are welcome to redistribute it
|
||||||
|
under certain conditions; type `show c' for details.
|
||||||
|
|
||||||
|
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||||
|
parts of the General Public License. Of course, the commands you use may
|
||||||
|
be called something other than `show w' and `show c'; they could even be
|
||||||
|
mouse-clicks or menu items--whatever suits your program.
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or your
|
||||||
|
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||||
|
necessary. Here is a sample; alter the names:
|
||||||
|
|
||||||
|
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||||
|
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||||
|
|
||||||
|
<signature of Ty Coon>, 1 April 1989
|
||||||
|
Ty Coon, President of Vice
|
||||||
|
|
||||||
|
This General Public License does not permit incorporating your program into
|
||||||
|
proprietary programs. If your program is a subroutine library, you may
|
||||||
|
consider it more useful to permit linking proprietary applications with the
|
||||||
|
library. If this is what you want to do, use the GNU Library General
|
||||||
|
Public License instead of this License.
|
144
ChangeLog
Normal file
144
ChangeLog
Normal file
|
@ -0,0 +1,144 @@
|
||||||
|
Fri Oct 11 22:09:45 1996 Bob Glickstein <bobg@hiro.zanshin.com>
|
||||||
|
|
||||||
|
* stow.html, configure.in: Version 1.3.2.
|
||||||
|
|
||||||
|
* README, stow.texi: Correct the URL again.
|
||||||
|
|
||||||
|
Fri Oct 11 18:20:42 1996 Bob Glickstein <bobg@hiro.zanshin.com>
|
||||||
|
|
||||||
|
* configure.in: Version 1.3.1.
|
||||||
|
|
||||||
|
* stow.html: Update Stow manual URL. Mention version 1.3.1.
|
||||||
|
|
||||||
|
* README: Update Stow URL.
|
||||||
|
|
||||||
|
* Makefile.am: stow-manual.html -> manual.html.
|
||||||
|
|
||||||
|
* stow.texi:
|
||||||
|
Add a reference to the Stow home page on the GNU web server. Change
|
||||||
|
several occurrences of "which" to "that" for grammatical superiority.
|
||||||
|
|
||||||
|
Wed Oct 9 00:34:07 1996 Bob Glickstein <bobg@hiro.zanshin.com>
|
||||||
|
|
||||||
|
* Makefile.am:
|
||||||
|
Add maintainer-only rules for stow-manual.html and stow-manual.texi.
|
||||||
|
|
||||||
|
Wed Oct 9 00:32:31 1996 Bob Glickstein <bobg@hiro.zanshin.com>
|
||||||
|
|
||||||
|
* README: Refer to the new location for the Stow home page.
|
||||||
|
|
||||||
|
* stow.html: Make it right for the GNU web server.
|
||||||
|
|
||||||
|
Tue Oct 8 21:54:09 1996 Bob Glickstein <bobg@hiro.zanshin.com>
|
||||||
|
|
||||||
|
* stow.texi: Document --restow
|
||||||
|
|
||||||
|
* stow.in: Add --restow (-R) option
|
||||||
|
|
||||||
|
* configure.in: Add "perl4" to search for Perl binary.
|
||||||
|
Bump version number to 1.3.
|
||||||
|
|
||||||
|
Mon Jun 24 23:23:03 1996 Bob Glickstein <bobg@hiro.zanshin.com>
|
||||||
|
|
||||||
|
* stow.texi: Delete trailing whitespace.
|
||||||
|
|
||||||
|
Fri Jun 21 19:44:26 1996 Bob Glickstein <bobg@hiro.zanshin.com>
|
||||||
|
|
||||||
|
* Makefile.am:
|
||||||
|
Don't explicitly mention version.texi. Automake now does it
|
||||||
|
automagically, by noticing the `@include version.texi' in
|
||||||
|
stow.texi. Awesome.
|
||||||
|
|
||||||
|
* stow.texi:
|
||||||
|
Use @include instead of @input. This is more Texinfoid, plus
|
||||||
|
allows Automake to automatically deduce the need for
|
||||||
|
version.texi.
|
||||||
|
|
||||||
|
* stow.in:
|
||||||
|
Elide trailing slashes from package names, then complain if
|
||||||
|
package names have slashes in them.
|
||||||
|
|
||||||
|
Tue Jun 18 23:19:04 1996 Bob Glickstein <bobg@hiro.zanshin.com>
|
||||||
|
|
||||||
|
* README: Call it "Gnu Stow".
|
||||||
|
|
||||||
|
Tue Jun 18 22:15:45 1996 Bob Glickstein <bobg@hiro.zanshin.com>
|
||||||
|
|
||||||
|
* configure.in:
|
||||||
|
Bump version number to 1.2.
|
||||||
|
|
||||||
|
Look for Perl under the names `perl' and `perl5'. If not found,
|
||||||
|
print a warning.
|
||||||
|
|
||||||
|
* stow.texi:
|
||||||
|
Add a section about bootstrapping. Add text about hacking Gnu
|
||||||
|
Make output.
|
||||||
|
|
||||||
|
* INSTALL:
|
||||||
|
Describe what happens when Perl isn't found during `configure'.
|
||||||
|
|
||||||
|
Mon Jun 17 19:43:25 1996 Bob Glickstein <bobg@hiro.zanshin.com>
|
||||||
|
|
||||||
|
* THANKS: Thank Fritz.
|
||||||
|
|
||||||
|
Fri Jun 14 19:18:50 1996 Bob Glickstein <bobg@hiro.zanshin.com>
|
||||||
|
|
||||||
|
* AUTHORS: Credit John Bazik and Gord Matzigkeit.
|
||||||
|
|
||||||
|
* stow.texi: Remove a "known bug" -- the pwd dependency is gone.
|
||||||
|
|
||||||
|
* stow.in:
|
||||||
|
Use fastcwd, from fastcwd.pl (which is GPL'd), to remove
|
||||||
|
dependency on an external pwd binary. Suggested by Gord
|
||||||
|
Matzigkeit.
|
||||||
|
|
||||||
|
* stow.in: Add a missing comma.
|
||||||
|
|
||||||
|
Thu Jun 13 21:52:10 1996 Bob Glickstein <bobg@hiro.zanshin.com>
|
||||||
|
|
||||||
|
* stow.in:
|
||||||
|
Change three occurrences of `my' to `local' for Perl 4
|
||||||
|
compatibility.
|
||||||
|
|
||||||
|
Thu Jun 13 18:07:37 1996 Bob Glickstein <bobg@hiro.zanshin.com>
|
||||||
|
|
||||||
|
* configure.in: Bump version number to 1.1.
|
||||||
|
|
||||||
|
* Makefile.am:
|
||||||
|
Add `stow' to the list of clean targets. Don't redirect output
|
||||||
|
directly into a make target.
|
||||||
|
|
||||||
|
* AUTHORS, README:
|
||||||
|
Use <bobg+stow@zanshin.com> as the contact address.
|
||||||
|
|
||||||
|
* TODO: New file.
|
||||||
|
|
||||||
|
* stow.in:
|
||||||
|
Refer to "Gnu Stow" in a few places. Use <bobg+stow@zanshin.com>
|
||||||
|
as the contact address. Handle long and short options. Handle
|
||||||
|
`version' and `help' options. Refer to "packages," not
|
||||||
|
"collections," for consistency with the manual.
|
||||||
|
|
||||||
|
* stow.texi:
|
||||||
|
Refer to "Gnu Stow" in a few places. Use <bobg+stow@zanshin.com>
|
||||||
|
as the contact address. Add sections on Reporting bugs and Known
|
||||||
|
bugs. Create a master menu. Minor rewording. Remove the period
|
||||||
|
from a node name.
|
||||||
|
|
||||||
|
* TODO, THANKS: New files.
|
||||||
|
|
||||||
|
Mon Jun 10 14:44:13 1996 Bob Glickstein <bobg@hiro.zanshin.com>
|
||||||
|
|
||||||
|
* NEWS: Create NEWS file for release. 1.0 now ready.
|
||||||
|
|
||||||
|
* stow.texi: Big revisions in preparation for release.
|
||||||
|
|
||||||
|
Sun Jun 9 15:47:19 1996 Bob Glickstein <bobg@zoger.ipost.com>
|
||||||
|
|
||||||
|
* stow.in: Enhance argument parsing, losing Perl 4 support in the
|
||||||
|
process.
|
||||||
|
(later) Perl 4 support restored.
|
||||||
|
|
||||||
|
Fri Jun 7 12:13:33 1996 Bob Glickstein <bobg@hiro.zanshin.com>
|
||||||
|
|
||||||
|
* Created stow, formerly "depot."
|
108
INSTALL
Normal file
108
INSTALL
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
Basic Installation
|
||||||
|
==================
|
||||||
|
|
||||||
|
Stow is a Perl script. You must have Perl 4 or Perl 5 in order for it
|
||||||
|
to run.
|
||||||
|
|
||||||
|
The steps in building stow are:
|
||||||
|
|
||||||
|
1. `cd' to the directory containing the source code (and this file)
|
||||||
|
and type `./configure' to configure stow for your system. This
|
||||||
|
step will attempt to locate your copy of perl and use its location
|
||||||
|
to create `stow' from `stow.in'. If perl can't be found, you'll
|
||||||
|
have to edit line 1 of `stow' from `#!false' to `#!/path/to/perl'
|
||||||
|
(where /path/to/perl is wherever perl will be found when stow
|
||||||
|
runs).
|
||||||
|
|
||||||
|
2. Type `make' to create stow.info from stow.texi.
|
||||||
|
|
||||||
|
3. Type `make install' to install `stow' and `stow.info'.
|
||||||
|
|
||||||
|
4. You can remove the generated files from the source code directory
|
||||||
|
by typing `make clean'. To also remove the files that `configure'
|
||||||
|
created (so you can compile the package for a different computer),
|
||||||
|
type `make distclean'. There is also a `make maintainer-clean'
|
||||||
|
target, but that is intended mainly for stow's developers. If you
|
||||||
|
use it, you may have to get all sorts of other programs in order
|
||||||
|
to regenerate files that came with the distribution.
|
||||||
|
|
||||||
|
Installation Names
|
||||||
|
==================
|
||||||
|
|
||||||
|
By default, `make install' will install the package's files in
|
||||||
|
`/usr/local/bin' and `/usr/local/info'. You can specify an
|
||||||
|
installation prefix other than `/usr/local' by giving `configure' the
|
||||||
|
option `--prefix=PATH'.
|
||||||
|
|
||||||
|
If the package supports it, you can cause programs to be installed
|
||||||
|
with an extra prefix or suffix on their names by giving `configure'
|
||||||
|
the option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
|
||||||
|
|
||||||
|
Since `stow' is concerned with separating a package's installation
|
||||||
|
tree from its run-time tree, you might want to install `stow' into a
|
||||||
|
directory such as `/usr/local/stow/stow' but have it run out of
|
||||||
|
`/usr/local'. Do this by giving the run-time prefix (e.g.,
|
||||||
|
/usr/local) to configure as described above; then run `make'; then run
|
||||||
|
`make install prefix=/usr/local/stow/stow'. For more information on
|
||||||
|
this technique, see the Stow manual.
|
||||||
|
|
||||||
|
The configuration system
|
||||||
|
========================
|
||||||
|
|
||||||
|
The `configure' shell script attempts to guess correct values for
|
||||||
|
various system-dependent variables used during compilation. It uses
|
||||||
|
those values to create a `Makefile' and to create the `stow' script
|
||||||
|
itself, using Makefile.in and stow.in as templates. Finally, it
|
||||||
|
creates a shell script `config.status' that you can run in the future
|
||||||
|
to recreate the current configuration, a file `config.cache' that
|
||||||
|
saves the results of its tests to speed up reconfiguring, and a file
|
||||||
|
`config.log' containing other output.
|
||||||
|
|
||||||
|
The file `configure.in' is used to create `configure' by a program
|
||||||
|
called `autoconf'. You only need `configure.in' if you want to change
|
||||||
|
it or regenerate `configure' using a newer version of `autoconf'.
|
||||||
|
|
||||||
|
The file `Makefile.am' is used to create `Makefile.in' by a program
|
||||||
|
called `automake'. You only need `Makefile.am' if you want to change
|
||||||
|
it or regenerate `Makefile.in' using a newer version of `automake'.
|
||||||
|
|
||||||
|
Sharing Defaults
|
||||||
|
================
|
||||||
|
|
||||||
|
If you want to set default values for `configure' scripts to share,
|
||||||
|
you can create a site shell script called `config.site' that gives
|
||||||
|
default values for variables like `CC', `cache_file', and `prefix'.
|
||||||
|
`configure' looks for `PREFIX/share/config.site' if it exists, then
|
||||||
|
`PREFIX/etc/config.site' if it exists. Or, you can set the
|
||||||
|
`CONFIG_SITE' environment variable to the location of the site script.
|
||||||
|
A warning: not all `configure' scripts look for a site script.
|
||||||
|
|
||||||
|
Operation Controls
|
||||||
|
==================
|
||||||
|
|
||||||
|
`configure' recognizes the following options to control how it
|
||||||
|
operates.
|
||||||
|
|
||||||
|
`--cache-file=FILE'
|
||||||
|
Use and save the results of the tests in FILE instead of
|
||||||
|
`./config.cache'. Set FILE to `/dev/null' to disable caching, for
|
||||||
|
debugging `configure'.
|
||||||
|
|
||||||
|
`--help'
|
||||||
|
Print a summary of the options to `configure', and exit.
|
||||||
|
|
||||||
|
`--quiet'
|
||||||
|
`--silent'
|
||||||
|
`-q'
|
||||||
|
Do not print messages saying which checks are being made.
|
||||||
|
|
||||||
|
`--srcdir=DIR'
|
||||||
|
Look for the package's source code in directory DIR. Usually
|
||||||
|
`configure' can determine that directory automatically.
|
||||||
|
|
||||||
|
`--version'
|
||||||
|
Print the version of Autoconf used to generate the `configure'
|
||||||
|
script, and exit.
|
||||||
|
|
||||||
|
`configure' also accepts some other, not widely useful, options.
|
||||||
|
|
18
Makefile.am
Normal file
18
Makefile.am
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
## Process this file with Automake to produce Makefile.in
|
||||||
|
|
||||||
|
AUTOMAKE_OPTIONS = dist-shar
|
||||||
|
|
||||||
|
bin_SCRIPTS = stow
|
||||||
|
info_TEXINFOS = stow.texi
|
||||||
|
|
||||||
|
CLEANFILES = stow manual.html manual.texi
|
||||||
|
|
||||||
|
# The rules for manual.html and manual.texi are only used by
|
||||||
|
# the developer
|
||||||
|
manual.html: manual.texi
|
||||||
|
-rm -f $@
|
||||||
|
texi2html -expandinfo -menu -monolithic -verbose $<
|
||||||
|
|
||||||
|
manual.texi: stow.texi
|
||||||
|
-rm -f $@
|
||||||
|
cp $< $@
|
22
NEWS
Normal file
22
NEWS
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
News file for Stow.
|
||||||
|
|
||||||
|
* Changes in version 1.3:
|
||||||
|
** Added --restow option.
|
||||||
|
** Fixed handling of slashes in package names.
|
||||||
|
** Expanded configure-time search for Perl binary.
|
||||||
|
|
||||||
|
* Changes in version 1.2:
|
||||||
|
** Dependency on `pwd' removed.
|
||||||
|
** Perl 4 compatibility fixes.
|
||||||
|
** Manual expanded even more.
|
||||||
|
|
||||||
|
* Changes in version 1.1:
|
||||||
|
** Long and short options now accepted.
|
||||||
|
** Manual expanded.
|
||||||
|
** `make clean' removes stow (which is generated from stow.in).
|
||||||
|
|
||||||
|
* Initial public release (v1.0) of Stow.
|
||||||
|
|
||||||
|
Local variables:
|
||||||
|
mode: outline
|
||||||
|
End:
|
28
README
Normal file
28
README
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
This is GNU Stow, a program for managing the installation of software
|
||||||
|
packages, keeping them separate (/usr/local/stow/emacs
|
||||||
|
vs. /usr/local/stow/perl, for example) while making them appear to be
|
||||||
|
installed in the same place (/usr/local).
|
||||||
|
|
||||||
|
Stow is a Perl script which should run correctly under Perl 4 and Perl
|
||||||
|
5. You must install Perl before running Stow. For more information
|
||||||
|
about Perl, see http://www.perl.com/perl/.
|
||||||
|
|
||||||
|
You can get the latest information about Stow from
|
||||||
|
http://www.gnu.ai.mit.edu/software/stow/stow.html.
|
||||||
|
|
||||||
|
Stow was inspired by Carnegie Mellon's "Depot" program, but is
|
||||||
|
substantially simpler. Whereas Depot requires database files to keep
|
||||||
|
things in sync, Stow stores no extra state between runs, so there's no
|
||||||
|
danger (as there is in Depot) of mangling directories when file
|
||||||
|
hierarchies don't match the database. Also unlike Depot, Stow will
|
||||||
|
never delete any files, directories, or links that appear in a Stow
|
||||||
|
directory (e.g., /usr/local/stow/emacs), so it's always possible to
|
||||||
|
rebuild the target tree (e.g., /usr/local).
|
||||||
|
|
||||||
|
Stow is free software, licensed under the GNU General Public License,
|
||||||
|
which can be found in the file COPYING.
|
||||||
|
|
||||||
|
See INSTALL for installation instructions.
|
||||||
|
|
||||||
|
Please mail comments, questions, and criticisms to the author, Bob
|
||||||
|
Glickstein, <bobg+stow@zanshin.com>.
|
16
THANKS
Normal file
16
THANKS
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
Thanks to the following people for testing, using, commenting on, and
|
||||||
|
otherwise aiding the creation of Stow:
|
||||||
|
|
||||||
|
Miles Bader <miles@gnu.ai.mit.edu>
|
||||||
|
Greg Fox <fox@zanshin.com>
|
||||||
|
David Hartmann <davidh@zanshin.com>
|
||||||
|
Ben Liblit <liblit@well.com>
|
||||||
|
Gord Matzigkeit <gord@enci.ucalgary.ca>
|
||||||
|
Roland McGrath <roland@gnu.ai.mit.edu>
|
||||||
|
Jim Meyering <meyering@asic.sc.ti.com>
|
||||||
|
Fritz Mueller <fritzm@netcom.com>
|
||||||
|
Bart Schaefer <schaefer@nbn.com>
|
||||||
|
Richard Stallman <rms@gnu.ai.mit.edu>
|
||||||
|
Spencer Sun <zorak@netcom.com>
|
||||||
|
Tom Tromey <tromey@cygnus.com>
|
||||||
|
Steve Webster <srw@zanshin.com>
|
47
TODO
Normal file
47
TODO
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
-*- outline -*-
|
||||||
|
|
||||||
|
* Autodetect "foreign" stow directories
|
||||||
|
|
||||||
|
* Fix empty-dir problem (see "Known bugs" in the manual)
|
||||||
|
|
||||||
|
* Continue after conflicts.
|
||||||
|
|
||||||
|
When detecting a conflict, affected subparts of the Stow traversal can
|
||||||
|
be skipped while continuing with other subparts.
|
||||||
|
|
||||||
|
* Traverse links in the target tree?
|
||||||
|
|
||||||
|
From e-mail with meyering@na-net.ornl.gov:
|
||||||
|
|
||||||
|
> My /usr/local/info equivalent is a symlink to /share/info
|
||||||
|
> because I want installs on all systems to put info files in that
|
||||||
|
> directory. With that set-up, stow chokes on fact that
|
||||||
|
> /usr/local/info is a symlink.
|
||||||
|
|
||||||
|
[...] Stow is designed to be paranoid about modifying anything it
|
||||||
|
doesn't "own." If it finds a symlink in the target tree (e.g.,
|
||||||
|
/usr/local/info) which doesn't point into the stow tree, its
|
||||||
|
paranoid response is to leave it the hell alone. But I can see in
|
||||||
|
this case how traversing the link and populating the directory on
|
||||||
|
the far end would be OK. Question: is that a special
|
||||||
|
circumstance, or would it always be OK to populate the far end of
|
||||||
|
a symlink in the target tree (when the symlink points to a
|
||||||
|
directory in a context where a directory is needed)? And: if it's
|
||||||
|
a special circumstance requiring a command-line option, should the
|
||||||
|
option be a mere boolean (such as, "--traverse-target-links") or
|
||||||
|
should it be an enumeration of which links are OK to traverse
|
||||||
|
(such as, "--traversable='info man doc'")?
|
||||||
|
|
||||||
|
* Develop a mechanism for sharing files between packages.
|
||||||
|
|
||||||
|
This would solve the problem of maintaining N platform-specific copies
|
||||||
|
of a package, all of which have many platform-*independent* files
|
||||||
|
which could be shared, such as man pages, info files, etc.
|
||||||
|
|
||||||
|
* Option to ignore certain files in the stow tree.
|
||||||
|
|
||||||
|
For example, --ignore='*~ .#*' (skip Emacs and CVS backup files).
|
||||||
|
|
||||||
|
* Option to ignore links in the stow tree to certain places.
|
||||||
|
|
||||||
|
For example, --ignore-link='/*' (skip absolute links).
|
5
autogen.sh
Executable file
5
autogen.sh
Executable file
|
@ -0,0 +1,5 @@
|
||||||
|
automake --add-missing --copy --gnu
|
||||||
|
libtoolize --copy
|
||||||
|
aclocal
|
||||||
|
autoheader
|
||||||
|
autoconf
|
21
configure.in
Normal file
21
configure.in
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
dnl Process this file with Autoconf to produce configure
|
||||||
|
|
||||||
|
AC_INIT(stow.in)
|
||||||
|
|
||||||
|
PACKAGE=stow
|
||||||
|
VERSION=1.3.2
|
||||||
|
AC_SUBST(PACKAGE)
|
||||||
|
AC_SUBST(VERSION)
|
||||||
|
|
||||||
|
AC_ARG_PROGRAM
|
||||||
|
|
||||||
|
fp_PROG_INSTALL
|
||||||
|
|
||||||
|
AC_PATH_PROGS(PERL, perl perl5 perl4, false)
|
||||||
|
|
||||||
|
if test "x$PERL" = xfalse
|
||||||
|
then
|
||||||
|
echo 'WARNING: Perl not found; you must edit line 1 of `stow'"'"
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_OUTPUT(Makefile stow)
|
91
mdate-sh
Executable file
91
mdate-sh
Executable file
|
@ -0,0 +1,91 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# mdate-sh - get modification time of a file and pretty-print it
|
||||||
|
# Copyright (C) 1995 Software Foundation, Inc.
|
||||||
|
# Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, June 1995
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
# any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
# Prevent date giving response in another language.
|
||||||
|
LANG=C
|
||||||
|
export LANG
|
||||||
|
LC_ALL=C
|
||||||
|
export LC_ALL
|
||||||
|
LC_TIME=C
|
||||||
|
export LC_TIME
|
||||||
|
|
||||||
|
# Get the extended ls output of the file.
|
||||||
|
if ls -L /dev/null 1>/dev/null 2>&1; then
|
||||||
|
set - `ls -L -l $1`
|
||||||
|
else
|
||||||
|
set - `ls -l $1`
|
||||||
|
fi
|
||||||
|
# The month is at least the fourth argument.
|
||||||
|
# (3 shifts here, the next inside the loop)
|
||||||
|
shift
|
||||||
|
shift
|
||||||
|
shift
|
||||||
|
|
||||||
|
# Find the month. Next argument is day, followed by the year or time.
|
||||||
|
month=
|
||||||
|
until test $month
|
||||||
|
do
|
||||||
|
shift
|
||||||
|
case $1 in
|
||||||
|
Jan) month=January; nummonth=1;;
|
||||||
|
Feb) month=February; nummonth=2;;
|
||||||
|
Mar) month=March; nummonth=3;;
|
||||||
|
Apr) month=April; nummonth=4;;
|
||||||
|
May) month=May; nummonth=5;;
|
||||||
|
Jun) month=June; nummonth=6;;
|
||||||
|
Jul) month=July; nummonth=7;;
|
||||||
|
Aug) month=August; nummonth=8;;
|
||||||
|
Sep) month=September; nummonth=9;;
|
||||||
|
Oct) month=October; nummonth=10;;
|
||||||
|
Nov) month=November; nummonth=11;;
|
||||||
|
Dec) month=December; nummonth=12;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
day=$2
|
||||||
|
|
||||||
|
# Here we have to deal with the problem that the ls output gives either
|
||||||
|
# the time of day or the year.
|
||||||
|
case $3 in
|
||||||
|
*:*) set `date`; eval year=\$$#
|
||||||
|
case $2 in
|
||||||
|
Jan) nummonthtod=1;;
|
||||||
|
Feb) nummonthtod=2;;
|
||||||
|
Mar) nummonthtod=3;;
|
||||||
|
Apr) nummonthtod=4;;
|
||||||
|
May) nummonthtod=5;;
|
||||||
|
Jun) nummonthtod=6;;
|
||||||
|
Jul) nummonthtod=7;;
|
||||||
|
Aug) nummonthtod=8;;
|
||||||
|
Sep) nummonthtod=9;;
|
||||||
|
Oct) nummonthtod=10;;
|
||||||
|
Nov) nummonthtod=11;;
|
||||||
|
Dec) nummonthtod=12;;
|
||||||
|
esac
|
||||||
|
# For the first six month of the year the time notation can also
|
||||||
|
# be used for files modified in the last year.
|
||||||
|
if (expr $nummonth \> $nummonthtod) > /dev/null;
|
||||||
|
then
|
||||||
|
year=`expr $year - 1`
|
||||||
|
fi;;
|
||||||
|
*) year=$3;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# The result.
|
||||||
|
echo $day $month $year
|
542
stow.in
Normal file
542
stow.in
Normal file
|
@ -0,0 +1,542 @@
|
||||||
|
#!@PERL@
|
||||||
|
|
||||||
|
# GNU Stow - manage the installation of multiple software packages
|
||||||
|
# Copyright 1993, 1994, 1995, 1996 by Bob Glickstein
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful, but
|
||||||
|
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
# General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
|
||||||
|
$ProgramName = $0;
|
||||||
|
$ProgramName =~ s,.*/,,;
|
||||||
|
|
||||||
|
$Version = '@VERSION@';
|
||||||
|
|
||||||
|
$Conflicts = 0;
|
||||||
|
$Delete = 0;
|
||||||
|
$NotReally = 0;
|
||||||
|
$Verbose = 0;
|
||||||
|
$ReportHelp = 0;
|
||||||
|
$Stow = &fastcwd;
|
||||||
|
$Target = undef;
|
||||||
|
$Restow = 0;
|
||||||
|
|
||||||
|
while (@ARGV && ($_ = $ARGV[0]) && /^-/) {
|
||||||
|
$opt = $';
|
||||||
|
shift;
|
||||||
|
last if /^--$/;
|
||||||
|
|
||||||
|
if ($opt =~ /^-/) {
|
||||||
|
$opt = $';
|
||||||
|
if ($opt =~ /^no?$/i) {
|
||||||
|
$NotReally = 1;
|
||||||
|
} elsif ($opt =~ /^c(o(n(f(l(i(c(ts?)?)?)?)?)?)?)?$/i) {
|
||||||
|
$Conflicts = 1;
|
||||||
|
$NotReally = 1;
|
||||||
|
} elsif ($opt =~ /^dir?/i) {
|
||||||
|
$remainder = $';
|
||||||
|
if ($remainder =~ /^=/) {
|
||||||
|
$Stow = $'; # the stuff after the =
|
||||||
|
} else {
|
||||||
|
$Stow = shift;
|
||||||
|
}
|
||||||
|
} elsif ($opt =~ /^t(a(r(g(et?)?)?)?)?/i) {
|
||||||
|
$remainder = $';
|
||||||
|
if ($remainder =~ /^=/) {
|
||||||
|
$Target = $'; # the stuff after the =
|
||||||
|
} else {
|
||||||
|
$Target = shift;
|
||||||
|
}
|
||||||
|
} elsif ($opt =~ /^verb(o(se?)?)?/i) {
|
||||||
|
$remainder = $';
|
||||||
|
if ($remainder =~ /^=(\d+)/) {
|
||||||
|
$Verbose = $1;
|
||||||
|
} else {
|
||||||
|
++$Verbose;
|
||||||
|
}
|
||||||
|
} elsif ($opt =~ /^de(l(e(te?)?)?)?$/i) {
|
||||||
|
$Delete = 1;
|
||||||
|
} elsif ($opt =~ /^r(e(s(t(o(w?)?)?)?)?)?$/i) {
|
||||||
|
$Restow = 1;
|
||||||
|
} elsif ($opt =~ /^vers(i(on?)?)?$/i) {
|
||||||
|
&version();
|
||||||
|
} else {
|
||||||
|
&usage(($opt =~ /^h(e(lp?)?)?$/) ? undef :
|
||||||
|
"unknown or ambiguous option: $opt");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
@opts = split(//, $opt);
|
||||||
|
while ($_ = shift(@opts)) {
|
||||||
|
if ($_ eq 'n') {
|
||||||
|
$NotReally = 1;
|
||||||
|
} elsif ($_ eq 'c') {
|
||||||
|
$Conflicts = 1;
|
||||||
|
$NotReally = 1;
|
||||||
|
} elsif ($_ eq 'd') {
|
||||||
|
$Stow = (join('', @opts) || shift);
|
||||||
|
@opts = ();
|
||||||
|
} elsif ($_ eq 't') {
|
||||||
|
$Target = (join('', @opts) || shift);
|
||||||
|
@opts = ();
|
||||||
|
} elsif ($_ eq 'v') {
|
||||||
|
++$Verbose;
|
||||||
|
} elsif ($_ eq 'D') {
|
||||||
|
$Delete = 1;
|
||||||
|
} elsif ($_ eq 'R') {
|
||||||
|
$Restow = 1;
|
||||||
|
} elsif ($_ eq 'V') {
|
||||||
|
&version();
|
||||||
|
} else {
|
||||||
|
&usage(($_ eq 'h') ? undef : "unknown option: $_");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&usage("No packages named") unless @ARGV;
|
||||||
|
|
||||||
|
$Target = &parent($Stow) unless $Target;
|
||||||
|
|
||||||
|
chdir($Target) || die "Cannot chdir to target tree $Target ($!)\n";
|
||||||
|
$Target = &fastcwd;
|
||||||
|
|
||||||
|
foreach $package (@ARGV) {
|
||||||
|
$package =~ s,/+$,,; # delete trailing slashes
|
||||||
|
if ($package =~ m,/,) {
|
||||||
|
die "$ProgramName: slashes not permitted in package names\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($Delete || $Restow) {
|
||||||
|
@Collections = @ARGV;
|
||||||
|
&Unstow('', &RelativePath($Target, $Stow));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$Delete || $Restow) {
|
||||||
|
foreach $Collection (@ARGV) {
|
||||||
|
warn "Stowing package $Collection...\n" if $Verbose;
|
||||||
|
&StowContents($Collection, &RelativePath($Target, $Stow));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub CommonParent {
|
||||||
|
local($dir1, $dir2) = @_;
|
||||||
|
local($result, $x);
|
||||||
|
local(@d1) = split(/\/+/, $dir1);
|
||||||
|
local(@d2) = split(/\/+/, $dir2);
|
||||||
|
|
||||||
|
while (@d1 && @d2 && (($x = shift(@d1)) eq shift(@d2))) {
|
||||||
|
$result .= "$x/";
|
||||||
|
}
|
||||||
|
chop($result);
|
||||||
|
$result;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub RelativePath {
|
||||||
|
local($a, $b) = @_;
|
||||||
|
local($c) = &CommonParent($a, $b);
|
||||||
|
local(@a) = split(/\/+/, $a);
|
||||||
|
local(@b) = split(/\/+/, $b);
|
||||||
|
local(@c) = split(/\/+/, $c);
|
||||||
|
|
||||||
|
splice(@a, 0, @c + 0);
|
||||||
|
splice(@b, 0, @c + 0);
|
||||||
|
unshift(@b, (('..') x (@a + 0)));
|
||||||
|
&JoinPaths(@b);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub JoinPaths {
|
||||||
|
local(@paths, @parts);
|
||||||
|
local ($x, $y);
|
||||||
|
local($result) = '';
|
||||||
|
|
||||||
|
$result = '/' if ($_[0] =~ /^\//);
|
||||||
|
foreach $x (@_) {
|
||||||
|
@parts = split(/\/+/, $x);
|
||||||
|
foreach $y (@parts) {
|
||||||
|
push(@paths, $y) if $y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$result .= join('/', @paths);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub Unstow {
|
||||||
|
local($targetdir, $stow) = @_;
|
||||||
|
local(@contents);
|
||||||
|
local($content);
|
||||||
|
local($linktarget, $stowmember, $collection);
|
||||||
|
local(@stowmember);
|
||||||
|
local($pure, $othercollection) = (1, '');
|
||||||
|
local($subpure, $subother);
|
||||||
|
local(@puresubdirs);
|
||||||
|
|
||||||
|
return (0, '') if (&JoinPaths($Target, $targetdir) eq $Stow);
|
||||||
|
return (0, '') if (-e &JoinPaths($Target, $targetdir, '.stow'));
|
||||||
|
warn sprintf("Unstowing in %s\n", &JoinPaths($Target, $targetdir))
|
||||||
|
if ($Verbose > 1);
|
||||||
|
opendir(DIR, &JoinPaths($Target, $targetdir)) ||
|
||||||
|
die "$ProgramName: Cannot read directory \"$dir\" ($!)\n";
|
||||||
|
@contents = readdir(DIR);
|
||||||
|
closedir(DIR);
|
||||||
|
foreach $content (@contents) {
|
||||||
|
next if (($content eq '.') || ($content eq '..'));
|
||||||
|
if (-l &JoinPaths($Target, $targetdir, $content)) {
|
||||||
|
($linktarget = readlink(&JoinPaths($Target,
|
||||||
|
$targetdir,
|
||||||
|
$content)))
|
||||||
|
|| die sprintf("%s: Cannot read link %s (%s)\n",
|
||||||
|
$ProgramName,
|
||||||
|
&JoinPaths($Target, $targetdir, $content),
|
||||||
|
$!);
|
||||||
|
if ($stowmember = &FindStowMember(&JoinPaths($Target,
|
||||||
|
$targetdir),
|
||||||
|
$linktarget)) {
|
||||||
|
@stowmember = split(/\/+/, $stowmember);
|
||||||
|
$collection = shift(@stowmember);
|
||||||
|
if (grep(($collection eq $_), @Collections)) {
|
||||||
|
&DoUnlink(&JoinPaths($Target, $targetdir, $content));
|
||||||
|
} elsif ($pure) {
|
||||||
|
if ($othercollection) {
|
||||||
|
$pure = 0 if ($collection ne $othercollection);
|
||||||
|
} else {
|
||||||
|
$othercollection = $collection;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$pure = 0;
|
||||||
|
}
|
||||||
|
} elsif (-d &JoinPaths($Target, $targetdir, $content)) {
|
||||||
|
($subpure, $subother) = &Unstow(&JoinPaths($targetdir, $content),
|
||||||
|
&JoinPaths('..', $stow));
|
||||||
|
if ($subpure) {
|
||||||
|
push(@puresubdirs, "$content/$subother");
|
||||||
|
}
|
||||||
|
if ($pure) {
|
||||||
|
if ($subpure) {
|
||||||
|
if ($othercollection) {
|
||||||
|
if ($subother) {
|
||||||
|
if ($othercollection ne $subother) {
|
||||||
|
$pure = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} elsif ($subother) {
|
||||||
|
$othercollection = $subother;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$pure = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$pure = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((!$pure || !$targetdir) && @puresubdirs) {
|
||||||
|
&CoalesceTrees($targetdir, $stow, @puresubdirs);
|
||||||
|
}
|
||||||
|
($pure, $othercollection);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub CoalesceTrees {
|
||||||
|
local($parent, $stow, @trees) = @_;
|
||||||
|
local($tree, $collection, $x);
|
||||||
|
|
||||||
|
foreach $x (@trees) {
|
||||||
|
($tree, $collection) = ($x =~ /^(.*)\/(.*)/);
|
||||||
|
&EmptyTree(&JoinPaths($Target, $parent, $tree));
|
||||||
|
&DoRmdir(&JoinPaths($Target, $parent, $tree));
|
||||||
|
if ($collection) {
|
||||||
|
&DoLink(&JoinPaths($stow, $collection, $parent, $tree),
|
||||||
|
&JoinPaths($Target, $parent, $tree));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub EmptyTree {
|
||||||
|
local($dir) = @_;
|
||||||
|
local(@contents);
|
||||||
|
local($content);
|
||||||
|
|
||||||
|
opendir(DIR, $dir)
|
||||||
|
|| die "$ProgramName: Cannot read directory \"$dir\" ($!)\n";
|
||||||
|
@contents = readdir(DIR);
|
||||||
|
closedir(DIR);
|
||||||
|
foreach $content (@contents) {
|
||||||
|
next if (($content eq '.') || ($content eq '..'));
|
||||||
|
if (-l &JoinPaths($dir, $content)) {
|
||||||
|
&DoUnlink(&JoinPaths($dir, $content));
|
||||||
|
} elsif (-d &JoinPaths($dir, $content)) {
|
||||||
|
&EmptyTree(&JoinPaths($dir, $content));
|
||||||
|
&DoRmdir(&JoinPaths($dir, $content));
|
||||||
|
} else {
|
||||||
|
&DoUnlink(&JoinPaths($dir, $content));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub StowContents {
|
||||||
|
local($dir, $stow) = @_;
|
||||||
|
local(@contents);
|
||||||
|
local($content);
|
||||||
|
|
||||||
|
warn "Stowing contents of $dir\n" if ($Verbose > 1);
|
||||||
|
opendir(DIR, &JoinPaths($Stow, $dir))
|
||||||
|
|| die "$ProgramName: Cannot read directory \"$dir\" ($!)\n";
|
||||||
|
@contents = readdir(DIR);
|
||||||
|
closedir(DIR);
|
||||||
|
foreach $content (@contents) {
|
||||||
|
next if (($content eq '.') || ($content eq '..'));
|
||||||
|
if (-d &JoinPaths($Stow, $dir, $content)) {
|
||||||
|
&StowDir(&JoinPaths($dir, $content), $stow);
|
||||||
|
} else {
|
||||||
|
&StowNondir(&JoinPaths($dir, $content), $stow);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub StowDir {
|
||||||
|
local($dir, $stow) = @_;
|
||||||
|
local(@dir) = split(/\/+/, $dir);
|
||||||
|
local($collection) = shift(@dir);
|
||||||
|
local($subdir) = join('/', @dir);
|
||||||
|
local($linktarget, $stowsubdir);
|
||||||
|
|
||||||
|
warn "Stowing directory $dir\n" if ($Verbose > 1);
|
||||||
|
if (-l &JoinPaths($Target, $subdir)) {
|
||||||
|
($linktarget = readlink(&JoinPaths($Target, $subdir)))
|
||||||
|
|| die sprintf("%s: Could not read link %s (%s)\n",
|
||||||
|
$ProgramName,
|
||||||
|
&JoinPaths($Target, $subdir),
|
||||||
|
$!);
|
||||||
|
($stowsubdir =
|
||||||
|
&FindStowMember(sprintf('%s/%s', $Target,
|
||||||
|
join('/', @dir[0..($#dir - 1)])),
|
||||||
|
$linktarget))
|
||||||
|
|| (&Conflict($dir, $subdir), return);
|
||||||
|
if (-e &JoinPaths($Stow, $stowsubdir)) {
|
||||||
|
if ($stowsubdir eq $dir) {
|
||||||
|
warn sprintf("%s already points to %s\n",
|
||||||
|
&JoinPaths($Target, $subdir),
|
||||||
|
&JoinPaths($Stow, $dir))
|
||||||
|
if ($Verbose > 2);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (-d &JoinPaths($Stow, $stowsubdir)) {
|
||||||
|
&DoUnlink(&JoinPaths($Target, $subdir));
|
||||||
|
&DoMkdir(&JoinPaths($Target, $subdir));
|
||||||
|
&StowContents($stowsubdir, &JoinPaths('..', $stow));
|
||||||
|
&StowContents($dir, &JoinPaths('..', $stow));
|
||||||
|
} else {
|
||||||
|
(&Conflict($dir, $subdir), return);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
&DoUnlink(&JoinPaths($Target, $subdir));
|
||||||
|
&DoLink(&JoinPaths($stow, $dir),
|
||||||
|
&JoinPaths($Target, $subdir));
|
||||||
|
}
|
||||||
|
} elsif (-e &JoinPaths($Target, $subdir)) {
|
||||||
|
if (-d &JoinPaths($Target, $subdir)) {
|
||||||
|
&StowContents($dir, &JoinPaths('..', $stow));
|
||||||
|
} else {
|
||||||
|
&Conflict($dir, $subdir);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
&DoLink(&JoinPaths($stow, $dir),
|
||||||
|
&JoinPaths($Target, $subdir));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub StowNondir {
|
||||||
|
local($file, $stow) = @_;
|
||||||
|
local(@file) = split(/\/+/, $file);
|
||||||
|
local($collection) = shift(@file);
|
||||||
|
local($subfile) = join('/', @file);
|
||||||
|
local($linktarget, $stowsubfile);
|
||||||
|
|
||||||
|
if (-l &JoinPaths($Target, $subfile)) {
|
||||||
|
($linktarget = readlink(&JoinPaths($Target, $subfile)))
|
||||||
|
|| die sprintf("%s: Could not read link %s (%s)\n",
|
||||||
|
$ProgramName,
|
||||||
|
&JoinPaths($Target, $subfile),
|
||||||
|
$!);
|
||||||
|
($stowsubfile =
|
||||||
|
&FindStowMember(sprintf('%s/%s', $Target,
|
||||||
|
join('/', @file[0..($#file - 1)])),
|
||||||
|
$linktarget))
|
||||||
|
|| (&Conflict($file, $subfile), return);
|
||||||
|
if (-e &JoinPaths($Stow, $stowsubfile)) {
|
||||||
|
(&Conflict($file, $subfile), return)
|
||||||
|
unless ($stowsubfile eq $file);
|
||||||
|
warn sprintf("%s already points to %s\n",
|
||||||
|
&JoinPaths($Target, $subfile),
|
||||||
|
&JoinPaths($Stow, $file))
|
||||||
|
if ($Verbose > 2);
|
||||||
|
} else {
|
||||||
|
&DoUnlink(&JoinPaths($Target, $subfile));
|
||||||
|
&DoLink(&JoinPaths($stow, $file),
|
||||||
|
&JoinPaths($Target, $subfile));
|
||||||
|
}
|
||||||
|
} elsif (-e &JoinPaths($Target, $subfile)) {
|
||||||
|
&Conflict($file, $subfile);
|
||||||
|
} else {
|
||||||
|
&DoLink(&JoinPaths($stow, $file),
|
||||||
|
&JoinPaths($Target, $subfile));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub DoUnlink {
|
||||||
|
local($file) = @_;
|
||||||
|
|
||||||
|
warn "UNLINK $file\n" if $Verbose;
|
||||||
|
(unlink($file) || die "$ProgramName: Could not unlink $file ($!)\n")
|
||||||
|
unless $NotReally;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub DoRmdir {
|
||||||
|
local($dir) = @_;
|
||||||
|
|
||||||
|
warn "RMDIR $dir\n" if $Verbose;
|
||||||
|
(rmdir($dir) || die "$ProgramName: Could not rmdir $dir ($!)\n")
|
||||||
|
unless $NotReally;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub DoLink {
|
||||||
|
local($target, $name) = @_;
|
||||||
|
|
||||||
|
warn "LINK $name to $target\n" if $Verbose;
|
||||||
|
(symlink($target, $name) ||
|
||||||
|
die "$ProgramName: Could not symlink $name to $target ($!)\n")
|
||||||
|
unless $NotReally;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub DoMkdir {
|
||||||
|
local($dir) = @_;
|
||||||
|
|
||||||
|
warn "MKDIR $dir\n" if $Verbose;
|
||||||
|
(mkdir($dir, 0777)
|
||||||
|
|| die "$ProgramName: Could not make directory $dir ($!)\n")
|
||||||
|
unless $NotReally;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub Conflict {
|
||||||
|
local($a, $b) = @_;
|
||||||
|
|
||||||
|
if ($Conflicts) {
|
||||||
|
warn sprintf("CONFLICT: %s vs. %s\n", &JoinPaths($Stow, $a),
|
||||||
|
&JoinPaths($Target, $b));
|
||||||
|
} else {
|
||||||
|
die sprintf("%s: CONFLICT: %s vs. %s\n",
|
||||||
|
$ProgramName,
|
||||||
|
&JoinPaths($Stow, $a),
|
||||||
|
&JoinPaths($Target, $b));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub FindStowMember {
|
||||||
|
local($start, $path) = @_;
|
||||||
|
local(@x) = split(/\/+/, $start);
|
||||||
|
local(@path) = split(/\/+/, $path);
|
||||||
|
local($x);
|
||||||
|
local(@d) = split(/\/+/, $Stow);
|
||||||
|
|
||||||
|
while (@path) {
|
||||||
|
$x = shift(@path);
|
||||||
|
if ($x eq '..') {
|
||||||
|
pop(@x);
|
||||||
|
return '' unless @x;
|
||||||
|
} elsif ($x) {
|
||||||
|
push(@x, $x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (@x && @d) {
|
||||||
|
if (($x = shift(@x)) ne shift(@d)) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return '' if @d;
|
||||||
|
join('/', @x);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub parent {
|
||||||
|
local($path) = join('/', @_);
|
||||||
|
local(@elts) = split(/\/+/, $path);
|
||||||
|
pop(@elts);
|
||||||
|
join('/', @elts);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub usage {
|
||||||
|
local($msg) = shift;
|
||||||
|
|
||||||
|
if ($msg) {
|
||||||
|
print "$ProgramName: $msg\n";
|
||||||
|
}
|
||||||
|
print "$ProgramName (GNU Stow) version $Version\n\n";
|
||||||
|
print "Usage: $ProgramName [OPTION ...] PACKAGE ...\n";
|
||||||
|
print <<EOT;
|
||||||
|
-n, --no Do not actually make changes
|
||||||
|
-c, --conflicts Scan for conflicts, implies -n
|
||||||
|
-d DIR, --dir=DIR Set stow dir to DIR (default is current dir)
|
||||||
|
-t DIR, --target=DIR Set target to DIR (default is parent of stow dir)
|
||||||
|
-v, --verbose[=N] Increase verboseness (levels are 0,1,2,3;
|
||||||
|
-v or --verbose adds 1; --verbose=N sets level)
|
||||||
|
-D, --delete Unstow instead of stow
|
||||||
|
-R, --restow Restow (like stow -D followed by stow)
|
||||||
|
-V, --version Show Stow version number
|
||||||
|
-h, --help Show this help
|
||||||
|
EOT
|
||||||
|
exit($msg ? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub version {
|
||||||
|
print "$ProgramName (GNU Stow) version $Version\n";
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
# This is from Perl 4's fastcwd.pl, by John Bazik.
|
||||||
|
#
|
||||||
|
# Usage: $cwd = &fastcwd;
|
||||||
|
#
|
||||||
|
# This is a faster version of getcwd. It's also more dangerous
|
||||||
|
# because you might chdir out of a directory that you can't chdir back
|
||||||
|
# into.
|
||||||
|
|
||||||
|
sub fastcwd {
|
||||||
|
local($odev, $oino, $cdev, $cino, $tdev, $tino);
|
||||||
|
local(@path, $path);
|
||||||
|
local(*DIR);
|
||||||
|
|
||||||
|
($cdev, $cino) = stat('.');
|
||||||
|
for (;;) {
|
||||||
|
($odev, $oino) = ($cdev, $cino);
|
||||||
|
chdir('..');
|
||||||
|
($cdev, $cino) = stat('.');
|
||||||
|
last if $odev == $cdev && $oino == $cino;
|
||||||
|
opendir(DIR, '.');
|
||||||
|
for (;;) {
|
||||||
|
$_ = readdir(DIR);
|
||||||
|
next if $_ eq '.';
|
||||||
|
next if $_ eq '..';
|
||||||
|
|
||||||
|
last unless $_;
|
||||||
|
($tdev, $tino) = lstat($_);
|
||||||
|
last unless $tdev != $odev || $tino != $oino;
|
||||||
|
}
|
||||||
|
closedir(DIR);
|
||||||
|
unshift(@path, $_);
|
||||||
|
}
|
||||||
|
chdir($path = '/' . join('/', @path));
|
||||||
|
$path;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Local variables:
|
||||||
|
# mode: perl
|
||||||
|
# End:
|
3
version.texi
Normal file
3
version.texi
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
@set UPDATED 11 October 1996
|
||||||
|
@set EDITION 1.3.2
|
||||||
|
@set VERSION 1.3.2
|
Loading…
Reference in a new issue