[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
cvsfs .cvsignore AUTHORS COPYING ChangeLog HACK...
From: |
Thomas Schwinge |
Subject: |
cvsfs .cvsignore AUTHORS COPYING ChangeLog HACK... |
Date: |
Sat, 31 Mar 2012 19:31:26 +0000 |
CVSROOT: /cvsroot/hurdextras
Module name: cvsfs
Changes by: Thomas Schwinge <tschwinge> 12/03/31 19:31:26
Removed files:
. : .cvsignore AUTHORS COPYING ChangeLog HACKING
Makefile.am NEWS README configure.ac
cvs_connect.c cvs_connect.h cvs_ext.c cvs_ext.h
cvs_files.c cvs_files.h cvs_pserver.c
cvs_pserver.h cvs_tree.c cvs_tree.h cvsfs.1
cvsfs.c cvsfs.h cvsfs.texi fdl.texi netfs.c
node.c node.h tcpip.c tcpip.h
Log message:
cvsfs is now maintained in a Git repository:
<http://git.savannah.gnu.org/cgit/hurd/incubator.git/log/?h=cvsfs/master>
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/cvsfs/.cvsignore?cvsroot=hurdextras&r1=1.7&r2=0
http://cvs.savannah.gnu.org/viewcvs/cvsfs/AUTHORS?cvsroot=hurdextras&r1=1.2&r2=0
http://cvs.savannah.gnu.org/viewcvs/cvsfs/COPYING?cvsroot=hurdextras&r1=1.1.1.1&r2=0
http://cvs.savannah.gnu.org/viewcvs/cvsfs/ChangeLog?cvsroot=hurdextras&r1=1.4&r2=0
http://cvs.savannah.gnu.org/viewcvs/cvsfs/HACKING?cvsroot=hurdextras&r1=1.9&r2=0
http://cvs.savannah.gnu.org/viewcvs/cvsfs/Makefile.am?cvsroot=hurdextras&r1=1.5&r2=0
http://cvs.savannah.gnu.org/viewcvs/cvsfs/NEWS?cvsroot=hurdextras&r1=1.2&r2=0
http://cvs.savannah.gnu.org/viewcvs/cvsfs/README?cvsroot=hurdextras&r1=1.7&r2=0
http://cvs.savannah.gnu.org/viewcvs/cvsfs/configure.ac?cvsroot=hurdextras&r1=1.6&r2=0
http://cvs.savannah.gnu.org/viewcvs/cvsfs/cvs_connect.c?cvsroot=hurdextras&r1=1.19&r2=0
http://cvs.savannah.gnu.org/viewcvs/cvsfs/cvs_connect.h?cvsroot=hurdextras&r1=1.9&r2=0
http://cvs.savannah.gnu.org/viewcvs/cvsfs/cvs_ext.c?cvsroot=hurdextras&r1=1.7&r2=0
http://cvs.savannah.gnu.org/viewcvs/cvsfs/cvs_ext.h?cvsroot=hurdextras&r1=1.2&r2=0
http://cvs.savannah.gnu.org/viewcvs/cvsfs/cvs_files.c?cvsroot=hurdextras&r1=1.14&r2=0
http://cvs.savannah.gnu.org/viewcvs/cvsfs/cvs_files.h?cvsroot=hurdextras&r1=1.5&r2=0
http://cvs.savannah.gnu.org/viewcvs/cvsfs/cvs_pserver.c?cvsroot=hurdextras&r1=1.9&r2=0
http://cvs.savannah.gnu.org/viewcvs/cvsfs/cvs_pserver.h?cvsroot=hurdextras&r1=1.3&r2=0
http://cvs.savannah.gnu.org/viewcvs/cvsfs/cvs_tree.c?cvsroot=hurdextras&r1=1.14&r2=0
http://cvs.savannah.gnu.org/viewcvs/cvsfs/cvs_tree.h?cvsroot=hurdextras&r1=1.4&r2=0
http://cvs.savannah.gnu.org/viewcvs/cvsfs/cvsfs.1?cvsroot=hurdextras&r1=1.4&r2=0
http://cvs.savannah.gnu.org/viewcvs/cvsfs/cvsfs.c?cvsroot=hurdextras&r1=1.17&r2=0
http://cvs.savannah.gnu.org/viewcvs/cvsfs/cvsfs.h?cvsroot=hurdextras&r1=1.15&r2=0
http://cvs.savannah.gnu.org/viewcvs/cvsfs/cvsfs.texi?cvsroot=hurdextras&r1=1.6&r2=0
http://cvs.savannah.gnu.org/viewcvs/cvsfs/fdl.texi?cvsroot=hurdextras&r1=1.1&r2=0
http://cvs.savannah.gnu.org/viewcvs/cvsfs/netfs.c?cvsroot=hurdextras&r1=1.19&r2=0
http://cvs.savannah.gnu.org/viewcvs/cvsfs/node.c?cvsroot=hurdextras&r1=1.10&r2=0
http://cvs.savannah.gnu.org/viewcvs/cvsfs/node.h?cvsroot=hurdextras&r1=1.3&r2=0
http://cvs.savannah.gnu.org/viewcvs/cvsfs/tcpip.c?cvsroot=hurdextras&r1=1.3&r2=0
http://cvs.savannah.gnu.org/viewcvs/cvsfs/tcpip.h?cvsroot=hurdextras&r1=1.2&r2=0
Patches:
Index: .cvsignore
===================================================================
RCS file: .cvsignore
diff -N .cvsignore
--- .cvsignore 16 Nov 2005 21:17:10 -0000 1.7
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,41 +0,0 @@
-cvsfs.info
-*.d
-cvsfs
-*patch*
-*test*
-.deps
-.libs
-Makefile.in
-aclocal.m4
-autom4te.cache
-autoscan.log
-config.h
-config.h.in
-config.log
-config.status
-configure
-libtool
-stamp-h
-stamp-h.in
-Makefile
-stamp-vti
-version.texi
-cvsfs4hurd-0.1.tar.gz
-cvsfs.aux
-cvsfs.cp
-cvsfs.cps
-cvsfs.dvi
-cvsfs.fn
-cvsfs.ky
-cvsfs.log
-cvsfs.pg
-cvsfs.toc
-cvsfs.tp
-cvsfs.vr
-INSTALL
-depcomp
-stamp-h1 stamp-vti
-texinfo.tex
-mdate-sh
-install-sh
-missing
Index: AUTHORS
===================================================================
RCS file: AUTHORS
diff -N AUTHORS
--- AUTHORS 16 Nov 2005 21:18:08 -0000 1.2
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1 +0,0 @@
-Stefan Siegl <address@hidden>
Index: COPYING
===================================================================
RCS file: COPYING
diff -N COPYING
--- COPYING 25 Sep 2004 08:23:29 -0000 1.1.1.1
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,340 +0,0 @@
- GNU GENERAL PUBLIC LICENSE
- Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.
- 59 Temple Place, Suite 330, Boston, MA 02111-1307 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
-
- 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) <year> <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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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) year 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.
Index: ChangeLog
===================================================================
RCS file: ChangeLog
diff -N ChangeLog
--- ChangeLog 14 Apr 2006 19:29:41 -0000 1.4
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,5 +0,0 @@
-#! /bin/sh
-# ChangeLog is more or less available through CVS revision history
-# there is no separate file telling what was changed line by line ...
-
-exec lynx "http://cvs.savannah.nongnu.org/viewcvs/cvsfs/?root=hurdextras"
Index: HACKING
===================================================================
RCS file: HACKING
diff -N HACKING
--- HACKING 16 Nov 2005 21:18:08 -0000 1.9
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,55 +0,0 @@
- you want to use emacs' -*- outline -*- mode, to read this ...
-
-this file is some kind of TODO file, I use it to take down notes, what to
-do, when and how ...
-
-* first things first
-** you're welcome to participate in progressing cvsfs
- if you got questions concerning it, don't hesitate but send me
- a mail to address@hidden
-
-** cvsfs' code is real crap!
-*** do you think so? please tell me what you don't like
- cvsfs is actually my first project, related to the
- Hurd and actually my first step towards OS-near programming.
-
-** cvs_*.[ch] files should stay GNU Hurd independant
- that is, please use POSIX compatible code in those files to keep those
- portable. The other stuff (cvsfs.c, node.c, netfs.c at the time of this
- writing) is OS (aka Hurd) specific and probably needs to completely be
- rewritten when aiming to port to some other platform.
-
-** source code documentation
- all functions in all of cvsfs's files should be well documented,
- this unfortunately isn't the case currently. if you want to, you may
- supply some however. when implementing new stuff, just write it first,
- so that won't happen in future ;)
-
-* todos
-** available stuff left to fix
-*** urgent
-**** expire revision contents to disk
- keep revision's content until translator's exit somewhere below /tmp
- with rather strict umask applied.
-
- is this really clever?? I am not too sure, we can leave it to the
- pager to get rid of old revisions, we don't need anymore ...
-
-*** things that can wait
-
-** new features
- these are somewhat in order of urgency ...
-
-*** support subversion as an alternate backend
-
-*** display a list of available branches and tags
-
-*** make loginfo accessible some way
- (<filenode>/history or something)
-
-*** allow revision access like Linux' cvsfs does
- (using @@ appendixes)
-
-
-jupp, enough for the time being ...
-$Id: HACKING,v 1.9 2005/11/16 21:18:08 stesie Exp $
Index: Makefile.am
===================================================================
RCS file: Makefile.am
diff -N Makefile.am
--- Makefile.am 16 Nov 2005 21:18:08 -0000 1.5
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,23 +0,0 @@
-# Makefile.am
-# Used by automake and configure to create Makefile.
-#
-# Copyright(C) 2004 Stefan Siegl, Germany
-# Written by Stefan Siegl <address@hidden>
-#
-
-bin_PROGRAMS=cvsfs
-
-cvsfs_SOURCES= \
- cvs_connect.c cvs_connect.h \
- cvs_ext.c cvs_ext.h \
- cvs_files.c cvs_files.h \
- cvs_pserver.c cvs_pserver.h \
- cvs_tree.c cvs_tree.h \
- cvsfs.c cvsfs.h \
- netfs.c \
- node.c node.h \
- tcpip.c tcpip.h
-man_MANS=cvsfs.1
-info_TEXINFOS = cvsfs.texi
-
-EXTRA_DIST=${man_MANS}
Index: NEWS
===================================================================
RCS file: NEWS
diff -N NEWS
--- NEWS 10 Oct 2004 12:43:27 -0000 1.2
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1 +0,0 @@
-no news is good news.
Index: README
===================================================================
RCS file: README
diff -N README
--- README 16 Nov 2005 21:18:08 -0000 1.7
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,79 +0,0 @@
-cvsfs - the CVS virtual filesystem for the GNU Hurd
-
-
- what is it?
-==========================
- cvsfs is a virtual (netfs based) filesystem allowing you to mount
- remotely located CVS modules into your local filesystem. The version
- controlled files will appear to you just like regular ones. If you just
- want to view one file (or a small bunch) you furthermore save a lot of
- network bandwidth since only these files will be downloaded. The usual
- way to do so would be to check out the whole tree and deleting it after
- using.
-
-
- how to use it?
-==========================
- create a directory which you'd like to use as the mount point
-
- mkdir -p cvsfs_test
-
- then set up the translator using settrans
-
- settrans -a cvsfs_test /sbin/cvsfs \
- cvs.sourceforge.net /cvsroot/xmltvr3 xmltVR3
-
- the settrans command will take some time to finish, since cvsfs needs
- to download the directory tree first.
-
- If you try to browse a really large cvs module (for example glibc or
- xfree package) you may need to tell settrans not to time the operation
- out (settrans defaults to kill the child process after 60 seconds, you
- may overwrite that using the -t option).
-
- If the settrans command finished successfully, just use
-
- cd cvsfs_test
-
- to enter the directory. Feel free to use ls, emacs, etc. now.
-
-
- cvs server access through :ext:
-========================================
- cvsfs is able to connect to a remotely located repository
- through rsh or ssh instead of only pserver. If you want or need to
- do so, specify -r on the command line.
-
- For example I could use
-
- settrans -a test ./cvsfs -rssh -u stesie savannah.nongnu.org \
- /cvsroot/hurdextras cvsfs
-
- to access the CVS repository of cvsfs.
-
- You probably want to use authorized-keys feature of ssh, as you will
- not be able to enter it interactively, since cvsfs translator does not
- have a connected terminal.
-
-
- it doesn't work! what to do now?
-========================================
- cvsfs is work in progress. If you stumble over a bug, please
- please either tell me by writing an email or by filing a bug
- report.
-
- Before complaining you probably want to make sure that you're
- using the most recent cvs version.
-
- Patches against CVS HEAD are welcome as well of course ;)
-
-
-
-More (detailed) documentation can be found in the cvsfs texinfo
-manual. Enter 'info cvsfs' at the command line to display it.
-
-Have fun with cvsfs
- and enjoy the GNU generation ..
-
-Stefan Siegl <address@hidden>
-$Id: README,v 1.7 2005/11/16 21:18:08 stesie Exp $
Index: configure.ac
===================================================================
RCS file: configure.ac
diff -N configure.ac
--- configure.ac 16 Nov 2005 21:18:08 -0000 1.6
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,39 +0,0 @@
-# -*- Autoconf -*-
-# Process this file with autoconf to produce a configure script.
-#
-# Copyright(C) 2004 by Stefan Siegl <address@hidden>, Germany
-
-AC_PREREQ(2.59)
-AC_INIT(cvsfs, 0.2, address@hidden)
-AC_REVISION($Revision: 1.6 $)
-AC_CONFIG_SRCDIR([cvs_files.c])
-AM_CONFIG_HEADER(config.h)
-
-# Initialize automake
-AM_INIT_AUTOMAKE(cvsfs, 0.2)
-
-# Checks for programs.
-AC_PROG_CC
-
-# Checks for libraries.
-AC_CHECK_LIB([threads], [rwlock_init])
-AC_CHECK_LIB([ports], [hurd_ihash_init])
-AC_CHECK_LIB([fshelp], [fshelp_touch])
-AC_CHECK_LIB([iohelp], [iohelp_initialize_conch])
-#AC_CHECK_LIB([netfs], [netfs_startup])
-
-# Check whether zlib compression is available
-AC_CHECK_LIB(z, gzopen, ,[
- echo "*** zlib development library was not found ***"
- echo "cannot use gzip compressed file download."
- echo ""
- ])
-
-LIBS="-lnetfs $LIBS"
-CFLAGS="$CFLAGS -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64"
-
-# install binaries to /hurd instead of /bin
-bindir=/hurd
-AC_SUBST(bindir)
-
-AC_OUTPUT([Makefile])
Index: cvs_connect.c
===================================================================
RCS file: cvs_connect.c
diff -N cvs_connect.c
--- cvs_connect.c 9 Jun 2006 20:33:07 -0000 1.19
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,416 +0,0 @@
-/**********************************************************
- * cvs_connect.c
- *
- * Copyright (C) 2004, 2005 by Stefan Siegl <address@hidden>, Germany
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Publice License,
- * version 2 or any later. The license is contained in the COPYING
- * file that comes with the cvsfs distribution.
- *
- * connect to cvs server
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include <string.h>
-#include <spin-lock.h>
-#include <signal.h>
-#include <time.h>
-#include <unistd.h>
-
-#include "cvsfs.h"
-#include "cvs_connect.h"
-#include "cvs_pserver.h"
-#include "cvs_ext.h"
-#include "cvs_tree.h"
-
-/* do cvs handshake, aka tell about valid responses and check whether all
- * necessary requests are supported.
- */
-static error_t cvs_handshake(FILE *send, FILE *recv);
-
-/* try to keep one connection to the cvs host open, FILE* handle of our
- * connection + rwlock, which must be held, when modifying
- */
-static struct {
- FILE *send;
- FILE *recv;
-} cvs_cached_conn = { NULL, NULL };
-spin_lock_t cvs_cached_conn_lock;
-time_t cvs_cached_conn_release_time = 0;
-
-/* callback function we install for SIGALRM signal */
-static void cvs_connect_sigalrm_handler(int);
-
-/* callback function we install for SIGUSR1 to force cvstree update */
-static void cvs_connect_sigusr1_handler(int);
-
-/* callback function for SIGUSR2, to force disconnection of cached conn. */
-static void cvs_connect_sigusr2_handler(int);
-
-/* callback function for SIGPIPE signal (i.e. our remote client died) */
-static void cvs_connect_sigpipe_handler(int);
-
-/* cvs_connect_init
- *
- * initialize cvs_connect stuff
- */
-void
-cvs_connect_init(void)
-{
- FUNC_PROLOGUE("cvs_connect_init");
-
- /* first things first: initialize global locks we use */
- spin_lock_init(&cvs_cached_conn_lock);
-
- signal(SIGALRM, cvs_connect_sigalrm_handler);
- alarm(30);
-
- signal(SIGUSR1, cvs_connect_sigusr1_handler);
- signal(SIGUSR2, cvs_connect_sigusr2_handler);
- signal(SIGPIPE, cvs_connect_sigpipe_handler);
-
- FUNC_EPILOGUE_NORET();
-}
-
-/* cvs_connect
- *
- * Try connecting to the cvs host. Return 0 on success.
- * FILE* handles to send and receive are guaranteed to be valid only, if zero
- * status was returned. The handles are line-buffered.
- */
-error_t
-cvs_connect(FILE **send, FILE **recv)
-{
- FUNC_PROLOGUE("cvs_connect");
-
- /* look whether we've got a cached connection available */
- spin_lock(&cvs_cached_conn_lock);
-
- if((*send = cvs_cached_conn.send) && (*recv = cvs_cached_conn.recv))
- {
- cvs_cached_conn.send = NULL;
- cvs_cached_conn.recv = NULL;
-
- /* do a quick still-alive check, in order to avoid confusion of the
- * calling routine
- */
- fprintf(*send, "noop\n");
-
- if(! cvs_wait_ok(*recv))
- {
- /* okay, connection still alive */
- spin_unlock(&cvs_cached_conn_lock);
- FUNC_RETURN(0);
- }
- else
- DEBUG("cvs-connect", "cached connection not alive anymore");
- }
-
- spin_unlock(&cvs_cached_conn_lock);
-
- /* get a fresh, new connection ... */
- FUNC_EPILOGUE(cvs_connect_fresh(send, recv));
-}
-
-
-
-/* cvs_connect_fresh
- *
- * Try connecting to the cvs host, like cvs_connect, but get get
- * a fresh connection ...
- */
-error_t
-cvs_connect_fresh(FILE **send, FILE **recv)
-{
- error_t err = 0;
-
- switch(config.cvs_mode)
- {
- case PSERVER:
- err = cvs_pserver_connect(send, recv);
- break;
-
- case EXT:
- case LOCAL:
- err = cvs_ext_connect(send, recv);
- break;
- }
-
- if(err)
- return err; /* something went wrong, we already logged, what did */
-
- /* still looks good. inform server of our cvs root */
- fprintf(*send, "Root %s\n", config.cvs_root);
-
- if(cvs_handshake(*send, *recv))
- {
- cvs_connection_kill(*send, *recv);
- return EIO;
- }
-
- return 0;
-}
-
-
-/* cvs_connection_release
- *
- * release the connection. the connection may then either be cached
- * and reused on next cvs_connect() or may be closed.
- */
-void
-cvs_connection_release(FILE *send, FILE *recv)
-{
- spin_lock(&cvs_cached_conn_lock);
-
- if(cvs_cached_conn.send)
- /* there's already a cached connection, forget about ours */
- cvs_connection_kill(send, recv);
-
- else
- {
- cvs_cached_conn.send = send;
- cvs_cached_conn.recv = recv;
-
- cvs_cached_conn_release_time = time(NULL);
- }
-
- spin_unlock(&cvs_cached_conn_lock);
-}
-
-
-/* cvs_handshake
- *
- * do cvs handshake, aka tell about valid responses and check whether all
- * necessary requests are supported.
- */
-static error_t
-cvs_handshake(FILE *send, FILE *recv)
-{
- char buf[4096]; /* Valid-requests answer can be really long ... */
-
- fprintf(send, "Valid-responses "
- /* base set of responses, we need to understand those ... */
- "ok error Valid-requests M E "
- "Mod-time "
- /* cvs needs Checked-in Updated Merged and Removed, else it just
- * dies, complaining. However we'll never need to understand those,
- * as long as our filesystem stays readonly.
- */
- "Checked-in Updated Merged Removed"
- "\n");
- fprintf(send, "valid-requests\n");
-
- if(! fgets(buf, sizeof(buf), recv))
- {
- perror(PACKAGE);
- return 1; /* connection gets closed by caller! */
- }
-
- if(strncmp(buf, "Valid-requests ", 15))
- {
- cvs_treat_error(recv, buf);
- return 1; /* connection will be closed by our caller */
- }
- else
- {
- const char **reqs_ptr;
- const char *cvs_needed_reqs[] = {
- "valid-requests", "Root", "Valid-responses", "UseUnchanged",
- "Argument", "rdiff",
-
- /* terminate list */
- NULL
- };
-
- for(reqs_ptr = cvs_needed_reqs; *reqs_ptr; reqs_ptr ++)
- if(! strstr(buf, *reqs_ptr))
- {
- fprintf(stderr, PACKAGE ": cvs server doesn't understand "
- "'%s' command, cannot live with that.\n", *reqs_ptr);
-
- /* tell caller to close connection ... */
- return EIO;
- }
-
-#if HAVE_LIBZ
- /* check whether the server supports gzip compression */
- if(! strstr(buf, "gzip-file-contents"))
- config.gzip_level = 0; /* not supported. */
-#endif
- }
-
-#if HAVE_LIBZ
- /* wait for the 'ok' message of valid-requests ... */
- if(cvs_wait_ok(recv))
- return EIO;
-
- if(config.gzip_level)
- /* request gzip compression ... */
- fprintf(send, "gzip-file-contents %d\n", config.gzip_level);
-
- /* 'ok' of valid-requests already read, therefore simply return. */
- return 0;
-
-#else /* ! HAVE_LIBZ */
- return cvs_wait_ok(recv);
-#endif
-}
-
-
-
-/* cvs_wait_ok
- *
- * read one line from cvs server and make sure, it's an ok message. else
- * call cvs_treat_error. return 0 on 'ok'.
- */
-error_t
-cvs_wait_ok(FILE *cvs_handle)
-{
- char buf[128];
-
- if(fgets(buf, sizeof(buf), cvs_handle))
- {
- if(! strncmp(buf, "ok", 2))
- return 0;
-
- cvs_treat_error(cvs_handle, buf);
- return EIO;
- }
-
- return EIO; /* hmm, didn't work, got eof */
-}
-
-
-
-/* cvs_treat_error
- *
- * notify the user (aka log to somewhere) that we've received some error
- * messages, we don't know how to handle ...
- */
-void
-cvs_treat_error(FILE *cvs_handle, char *msg)
-{
- char buf[128];
-
- do
- if(msg)
- {
- /* chop trailing linefeed off of msg */
- char *ptr = msg + strlen(msg) - 1;
- if(*ptr == 10) *ptr = 0;
-
- if(msg[1] == ' ' && (*msg == 'M' || *msg == 'E'))
- fprintf(stderr, PACKAGE ": %s\n", &msg[2]);
-
- else if(! strncmp(msg, "error ", 6))
- {
- for(msg += 6; *msg && *msg <= '9'; msg ++);
- if(*msg)
- fprintf(stderr, PACKAGE ": error: %s\n", msg);
- return;
- }
-
- else
- fprintf(stderr, PACKAGE ": protocol error, received: %s\n", msg);
- }
- while((msg = fgets(buf, sizeof(buf), cvs_handle)));
-
- /* fprintf(stderr, "leaving treat_error, due to received eof\n"); */
-}
-
-
-
-/* cvs_connect_sigalrm_handler
- *
- * callback function we install for SIGALRM signal
- * -> shutdown cvs server connection if idle for more than 90 seconds
- */
-static void
-cvs_connect_sigalrm_handler(int signal)
-{
- (void) signal;
- static time_t cvs_tree_expiration = 0;
-
- /* update directory tree, by default every 1800 sec. */
- if(! cvs_tree_expiration)
- time(&cvs_tree_expiration);
-
- if(time(NULL) - cvs_tree_expiration > 1800)
- cvs_tree_read(&rootdir);
-
- /* expire rather old cached connections ... */
- spin_lock(&cvs_cached_conn_lock);
-
- if(cvs_cached_conn.send
- && (time(NULL) - cvs_cached_conn_release_time > 90))
- {
- /* okay, connection is rather old, drop it ... */
- fclose(cvs_cached_conn.send);
- if(cvs_cached_conn.send != cvs_cached_conn.recv)
- fclose(cvs_cached_conn.recv);
-
- cvs_cached_conn.send = NULL;
- cvs_cached_conn.recv = NULL;
- }
-
- spin_unlock(&cvs_cached_conn_lock);
-}
-
-
-/* cvs_connect_sigusr1_handler
- *
- * callback function we install for SIGUSR1 to force cvstree update
- */
-static void
-cvs_connect_sigusr1_handler(int sig)
-{
- (void) sig;
- cvs_tree_read(&rootdir);
-}
-
-
-/* cvs_connect_sigusr2_handler
- *
- * callback function for SIGUSR2, to force disconnection of cached conn.
- */
-static void
-cvs_connect_sigusr2_handler(int sig)
-{
- (void) sig;
- spin_lock(&cvs_cached_conn_lock);
-
- if(cvs_cached_conn.send)
- {
- fclose(cvs_cached_conn.send);
- if(cvs_cached_conn.send != cvs_cached_conn.recv)
- fclose(cvs_cached_conn.recv);
-
- cvs_cached_conn.send = NULL;
- cvs_cached_conn.recv = NULL;
- }
-
- spin_unlock(&cvs_cached_conn_lock);
-}
-
-
-
-/* callback function for SIGPIPE signal (i.e. our remote client died) */
-static void
-cvs_connect_sigpipe_handler(int sig)
-{
- FUNC_PROLOGUE_FMT("cvs_connect_sigpipe_hanler", "signal=%d", sig);
-
- /* just ignore the SIGPIPE signal, which we'll receive, if we either read
- * from or write to the pipe to one of our subprocesses (remote shell
- * clients), in case these are not alive anymore.
- *
- * this especially happens if we try to reuse a cache connection,
- * where the remote side has an idle daemon, etc.
- */
-
- FUNC_EPILOGUE_NORET();
-}
Index: cvs_connect.h
===================================================================
RCS file: cvs_connect.h
diff -N cvs_connect.h
--- cvs_connect.h 16 Nov 2005 21:18:08 -0000 1.9
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,56 +0,0 @@
-/**********************************************************
- * cvs_connect.h
- *
- * Copyright 2004, Stefan Siegl <address@hidden>, Germany
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Publice License,
- * version 2 or any later. The license is contained in the COPYING
- * file that comes with the cvsfs distribution.
- *
- * connect to cvs server
- */
-
-#ifndef CVS_CONNECT_H
-#define CVS_CONNECT_H
-
-#include <stdio.h>
-#include "cvsfs.h"
-
-/* initialize cvs_connect stuff, this must be called before using cvs_connect
- */
-void cvs_connect_init(void);
-
-/* Try connecting to the cvs host. Return 0 on success.
- * FILE* handles to send and receive are guaranteed to be valid only, if zero
- * status was returned. The handles are line-buffered.
- */
-error_t cvs_connect(FILE **send, FILE **recv);
-
-/* Try connecting to cvs host, like cvs_connect, but make a fresh connection
- */
-error_t cvs_connect_fresh(FILE **send, FILE **recv);
-
-/* release the connection. the connection may then either be cached
- * and reused on next cvs_connect() or may be closed.
- */
-void cvs_connection_release(FILE *send, FILE *recv);
-
-/* release the connection but don't ever try to cache it. You want to
- * call this in case you stumbled over an error you don't know how to
- * recover from automatically or simple got EOF
- */
-#define cvs_connection_kill(send, recv) \
- do { fclose(send); if(send != recv) fclose(recv); } while(0)
-
-/* read one line from cvs server and make sure, it's an ok message. else
- * call cvs_treat_error. return 0 on 'ok'.
- */
-error_t cvs_wait_ok(FILE *recv_handle);
-
-/* notify the user (aka log to somewhere) that we've received some error
- * messages, we don't know how to handle ...
- */
-void cvs_treat_error(FILE *recv_handle, char *read_msg);
-
-#endif /* CVS_CONNECT_H */
Index: cvs_ext.c
===================================================================
RCS file: cvs_ext.c
diff -N cvs_ext.c
--- cvs_ext.c 16 Nov 2005 21:18:08 -0000 1.7
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,120 +0,0 @@
-/**********************************************************
- * cvs_ext.c
- *
- * Copyright (C) 2004, 2005 by Stefan Siegl <address@hidden>, Germany
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Publice License,
- * version 2 or any later. The license is contained in the COPYING
- * file that comes with the cvsfs distribution.
- *
- * connect to cvs :ext: server
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include <string.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <malloc.h>
-#include <sys/types.h>
-#include <signal.h>
-
-#include "cvsfs.h"
-#include "cvs_ext.h"
-#include "cvs_connect.h"
-
-
-
-/* cvs_ext_connect
- *
- * connect to the cvs :ext: server as further described in the cvsfs_config
- * configuration structure
- */
-error_t
-cvs_ext_connect(FILE **send, FILE **recv)
-{
- char port[10];
- int fd_to_rsh[2], fd_from_rsh[2];
- pid_t pid;
-
- if(pipe(fd_to_rsh))
- return errno;
- if(pipe(fd_from_rsh))
- return errno;
-
- if((pid = fork()) < 0)
- {
- perror(PACKAGE ": cannot fork remote shell client");
- return pid;
- }
-
- if(! pid)
- {
- /* okay, child process, fork to remote shell client */
- close(fd_to_rsh[1]); /* close writing end */
- close(fd_from_rsh[0]); /* close reading end */
-
- if(dup2(fd_to_rsh[0], 0) < 0 || dup2(fd_from_rsh[1], 1) < 0)
- {
- perror(PACKAGE ": unable to dup2 pipe to stdin/stdout");
- exit(1);
- }
-
- if(config.cvs_mode == EXT)
- {
- snprintf(port, sizeof(port), "%d",
- config.cvs_port ? config.cvs_port : 22);
-
- execlp(config.cvs_shell_client, config.cvs_shell_client,
- "-p", port,
- "-l", config.cvs_username, config.cvs_hostname,
- "--", "cvs", "server", NULL);
- }
- else if(config.cvs_mode == LOCAL)
- {
- execlp("cvs", "cvs", "server", NULL);
- }
- else
- {
- fprintf(stderr, PACKAGE ": damn, this line was not reached.\n");
- abort();
- }
-
- exit(1);
- }
-
- close(fd_to_rsh[0]);
- close(fd_from_rsh[1]);
-
- if(! ((*send = fdopen(fd_to_rsh[1], "w"))
- && (*recv = fdopen(fd_from_rsh[0], "r"))))
- {
- perror(PACKAGE ": unable to convert pipe's fds to file streams");
-
- if(send)
- fclose(*send);
- else
- close(fd_to_rsh[1]);
-
- if(recv)
- fclose(*recv);
- else
- close(fd_from_rsh[0]);
-
- kill(pid, SIGTERM);
- return EIO;
- }
-
- if(setvbuf(*send, NULL, _IOLBF, 0) || setvbuf(*recv, NULL, _IOLBF, 0))
- {
- perror(PACKAGE ": cannot force streams to be linebuffered");
- fclose(*send);
- fclose(*recv);
- return EIO;
- }
-
- return 0;
-}
Index: cvs_ext.h
===================================================================
RCS file: cvs_ext.h
diff -N cvs_ext.h
--- cvs_ext.h 16 Nov 2005 21:18:08 -0000 1.2
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,26 +0,0 @@
-/**********************************************************
- * cvs_ext.h
- *
- * Copyright 2004, Stefan Siegl <address@hidden>, Germany
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Publice License,
- * version 2 or any later. The license is contained in the COPYING
- * file that comes with the cvsfs distribution.
- *
- * connect to cvs :ext: server
- */
-
-#ifndef CVS_EXT_H
-#define CVS_EXT_H
-
-#include <stdio.h>
-#include "cvsfs.h"
-
-/* connect to the cvs :ext: server.
- * return 0 on success, only in that case send and recv are guaranteed to
- * be valid. send and recv are already set up to be line buffered.
- */
-error_t cvs_ext_connect(FILE **send, FILE **recv);
-
-#endif /* CVS_EXT_H */
Index: cvs_files.c
===================================================================
RCS file: cvs_files.c
diff -N cvs_files.c
--- cvs_files.c 9 Jun 2006 20:33:08 -0000 1.14
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,640 +0,0 @@
-/**********************************************************
- * cvs_files.c
- *
- * Copyright (C) 2004, 2005 by Stefan Siegl <address@hidden>, Germany
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Publice License,
- * version 2 or any later. The license is contained in the COPYING
- * file that comes with the cvsfs distribution.
- *
- * download arbitrary revisions from cvs host and cache them locally
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include <string.h>
-#include <stdlib.h>
-#include <malloc.h>
-#include <time.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-#ifdef HAVE_LIBZ
-# include <zlib.h>
-#endif
-
-#include "cvsfs.h"
-#include "cvs_files.h"
-#include "cvs_connect.h"
-
-/* cvs_files_print_path_recursively
- *
- * recurse from dir upwards to the root node and write out the directories'
- * names to cvs_handle as falling back.
- */
-static void
-cvs_files_print_path_recursively(FILE *cvs_handle, struct netnode *dir)
-{
- if(dir->parent)
- cvs_files_print_path_recursively(cvs_handle, dir->parent);
- fprintf(cvs_handle, "%s/", dir->name);
-}
-
-
-/* cvs_files_cvsattr_to_mode_t
- *
- * convert cvs mode string to posix style mode_t
- */
-static mode_t
-cvs_files_cvsattr_to_mode_t(const char *ptr)
-{
- const mode_t modes[9] =
- { S_IRUSR, S_IWUSR, S_IXUSR,
- S_IRGRP, S_IWGRP, S_IXGRP,
- S_IROTH, S_IWOTH, S_IXOTH
- };
- const mode_t *stage = modes;
- mode_t perm = 0;
-
- for(;;ptr ++)
- switch(*ptr)
- {
- case 'u': stage = &modes[0]; break;
- case 'g': stage = &modes[3]; break;
- case 'o': stage = &modes[6]; break;
- case '=': break;
- case ',': break;
- case 'r': perm |= stage[0]; break;
- case 'w': perm |= stage[1]; break;
- case 'x': perm |= stage[2]; break;
-
- default:
- return perm;
- }
-}
-
-
-/* gzip flag byte */
-#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */
-#define HEAD_CRC 0x02 /* bit 1 set: header CRC present */
-#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
-#define ORIG_NAME 0x08 /* bit 3 set: original file name present */
-#define COMMENT 0x10 /* bit 4 set: file comment present */
-#define RESERVED 0xE0 /* bits 5..7: reserved */
-
-/* cvs_files_gzip_check_header
- *
- * check the gzip header for validity and move the pointers as necessary.
- * RETURN: 0 on success, 1 if not enough bytes we available or a system error
- * code on trouble
- */
-#ifdef HAVE_LIBZ
-static int
-cvs_files_gzip_check_header(char **data, uInt *len)
-{
- static const char gzip_magic[2] = {0x1f, 0x8b};
- uInt pos = 10;
- int method;
- int flags;
-
- if(*len < 10)
- return 1; /* not enough bytes for the header */
-
- if((*data)[0] != gzip_magic[0] || (*data)[1] != gzip_magic[1])
- return EIO; /* not a gzip magic */
-
- method = (*data)[2];
- flags = (*data)[3];
- if(method != Z_DEFLATED || (flags & RESERVED))
- return EIO; /* not deflated or reserved flags set, what about it?? */
-
- /* bytes 4..9 are time, xflags and os type. ignore 'em ... */
-
- if(flags & EXTRA_FIELD)
- {
- int field_len;
-
- if(*len < pos + 2) return 1; /* not enough data */
-
- field_len = (*data)[pos ++];
- field_len = (*data)[pos ++];
-
- if(*len < pos + field_len) return 1; /* not enough data
- * TODO if extra_field is larger
- * than our gzip in buffer, we
- * got a problem ...
- */
- pos =+ field_len;
- }
-
- if(flags & ORIG_NAME)
- do
- /* skip the original file name ... */
- if(*len < pos + 1) return 1; /* not enough data */
- while((*data)[pos ++]);
-
- if(flags & COMMENT)
- do
- /* skip the comment ... */
- if(*len < pos + 1) return 1; /* not enough data */
- while((*data)[pos ++]);
-
- if(flags & HEAD_CRC)
- {
- /* skip two bytes, i.e. header's crc */
- if(*len < pos + 2) return 1; /* not available */
- pos += 2;
- }
-
- /* okay, we got it, therefore adjust *len and *data accordingly */
- *len -= pos;
- *data += pos;
- return 0;
-}
-#endif /* HAVE_LIBZ */
-
-
-
-/* cvs_files_gzip_inflate
- *
- * gzip inflate given number of bytes from file-handle into content
- * return 0 on success.
- */
-#if HAVE_LIBZ
-static error_t
-cvs_files_gzip_inflate(FILE *recv, size_t bytes, char **content, size_t *len)
-{
- char input[4096]; /* input buffer */
- size_t read;
- z_stream z;
- int got_header = 0;
-
- /* initialize zlib decompression */
- z.next_in = ((Bytef *)input);
- z.avail_in = 0;
- z.next_out = NULL;
- z.zalloc = Z_NULL;
- z.zfree = Z_NULL;
- z.opaque = Z_NULL;
-
- switch(inflateInit2(&z, -MAX_WBITS))
- {
- case Z_OK:
- break; /* it worked, perfect. */
-
- case Z_MEM_ERROR:
- return ENOMEM;
-
- case Z_VERSION_ERROR:
- fprintf(stderr, PACKAGE ": incompatible zlib installed.\n");
- return EIEIO;
-
- default:
- return EIO;
- }
-
- /* read 'bytes' bytes from reader handle, but not more than we can store
- * to input buffer ...
- */
- while(bytes && (read = sizeof(input) -
- ((char*)z.next_in - input) - z.avail_in)
- && (read = fread(z.next_in + z.avail_in, 1,
- read < bytes ? read : bytes, recv)))
- {
- bytes -= read;
- z.avail_in += read;
-
- /* check whether there is a correct gzip header */
- if(! got_header)
- switch(cvs_files_gzip_check_header((char **)&z.next_in, &z.avail_in))
- {
- case 0: /* success */
- got_header = 1;
- break;
-
- case 1: /* not enough data */
- continue;
-
- default:
- inflateEnd(&z);
-
- if(z.next_out)
- free(z.next_out - z.total_out);
-
- return EIO;
- }
-
- /* enlare output buffer, if necessary */
- if(! z.next_out || z.avail_out < (z.avail_in << 2))
- {
- void *ptr;
- size_t alloc = z.next_out ? z.total_out << 1 : 16384;
-
- ptr = realloc(z.next_out - z.total_out, alloc);
- if(! ptr)
- {
- inflateEnd(&z);
- return ENOMEM;
- }
-
- z.next_out = ptr + z.total_out;
- z.avail_out = alloc - z.total_out;
- }
-
- /* inflate data now */
- switch(inflate(&z, Z_NO_FLUSH))
- {
- case Z_OK:
- case Z_STREAM_END:
- case Z_BUF_ERROR: /* this is not fatal, just not enough
- * memory in output buffer
- */
- break;
-
- case Z_NEED_DICT:
- case Z_DATA_ERROR:
- case Z_STREAM_ERROR:
- inflateEnd(&z);
-
- if(z.next_out)
- free(z.next_out - z.total_out);
-
- return EIO;
-
- case Z_MEM_ERROR:
- default:
- inflateEnd(&z);
-
- if(z.next_out)
- free(z.next_out - z.total_out);
-
- return ENOMEM;
- }
-
- /* discard inflated bits from the input buffer ... */
- memmove(input, z.next_in, sizeof(input) - ((char *)z.next_in - input));
- z.next_in = ((Bytef *)input);
- }
-
- if(bytes)
- {
- /* unable to read all data ... */
- inflateEnd(&z);
-
- if(z.next_out)
- free(z.next_out - z.total_out);
-
- return EIO;
- }
-
- while(z.avail_in)
- {
- /* data left in input buffer, call inflate to care for that */
- void *ptr;
- size_t alloc = z.total_out + (z.avail_in << 2);
-
- ptr = realloc(z.next_out - z.total_out, alloc);
- if(! ptr)
- {
- inflateEnd(&z);
- return ENOMEM;
- }
-
- z.next_out = ptr + z.total_out;
- z.avail_out = alloc - z.total_out;
-
- switch(inflate(&z, Z_FINISH))
- {
- case Z_STREAM_END:
- z.avail_in = 0; /* okay, we're done, forget the trailing bits */
-
- case Z_OK:
- case Z_BUF_ERROR: /* this is not fatal, just not enough
- * memory in output buffer
- */
- break;
-
- case Z_NEED_DICT:
- case Z_DATA_ERROR:
- case Z_STREAM_ERROR:
- inflateEnd(&z);
-
- if(z.next_out)
- free(z.next_out - z.total_out);
-
- return EIO;
-
- case Z_MEM_ERROR:
- default:
- inflateEnd(&z);
-
- if(z.next_out)
- free(z.next_out - z.total_out);
-
- return ENOMEM;
- }
- }
-
- inflateEnd(&z);
-
- /* okay, processed data should be at z.next_out - z.total_out */
- free(*content);
- *content = realloc(z.next_out - z.total_out, z.total_out);
- *len = z.total_out;
-
- return 0;
-}
-#endif /* HAVE_LIBZ */
-
-
-
-/* cvs_files_cache
- *
- * Download the revision (as specified by rev) of the specified file.
- */
-error_t
-cvs_files_cache(struct netnode *file, struct revision *rev)
-{
- FUNC_PROLOGUE_FMT("cvs_files_cache", "file=%s, rev=%s", file->name, rev->id);
- FILE *send, *recv;
- char buf[1024]; /* 1k should be enough for most cvs repositories, if
- * cvsfs tell's you to increase this value, please do so.
- *
- * TODO in the far future we may have a fgets-thingy, that
- * allocates it's memory dynamically, which occurs to be
- * a goodthing(TM) ...
- */
-
- if(rev != file->revision)
- {
- /* we're not retrieving the head revision, thus it is likely that
- * the HEAD revision was sent over the line in this session. However
- * cvs server tends to transmit only one 'Mod-time' per file and
- * session.
- *
- * therefore get a fresh connection ...
- */
- if(cvs_connect_fresh(&send, &recv))
- FUNC_RETURN(EIO);
- }
- else if(cvs_connect(&send, &recv))
- FUNC_RETURN(EIO);
-
- /* write out request header */
- fprintf(send,
- "Argument -l\n" /* local dir only */
- "Argument -N\n" /* don't shorten module names */
- "Argument -P\n" /* no empty directories */
- "Argument -d\nArgument .\n" /* checkout to local dir */
- "Argument -r\nArgument %s\n"
- "Argument --\n"
- "Argument ",
- rev->id);
-
- /* write out pathname from rootnode on ... */
- cvs_files_print_path_recursively(send, file->parent);
-
- /* last but not least write out the filename */
- fprintf(send, "%s\n", file->name);
-
- /* okay, send checkout command ... */
- fprintf(send,
- "Directory .\n%s\n" /* cvsroot */
- "co\n", config.cvs_root);
-
- /* example response:
- * *** SERVER ***
- * Mod-time 8 Sep 2004 17:05:43 -0000
- * Updated ./wsdebug/
- * /home/cvs/wsdebug/debug.c
- * /debug.c/1.1///T1.1
- * u=rw,g=rw,o=rw
- * 6285
- * [content]
- */
-
- while(fgets(buf, sizeof(buf), recv))
- {
- char *ptr;
- int buflen = strlen(buf);
-
- ptr = buf + buflen;
- ptr --;
-
- if(*ptr != 10)
- {
- fprintf(stderr, PACKAGE "cvs_files_cache's parse buffer is "
- "too small, stopping for the moment.\n");
- exit(10);
- }
-
- if(buf[0] == '/')
- continue; /* just file name stuff, as we request only one file
- * we don't have to care for that ...
- */
-
- if(! strncmp(buf, "Mod-time ", 9))
- {
- struct tm tm;
- time_t t = 0;
-
- memset(&tm, 0, sizeof(tm));
- if(strptime(&buf[9], "%d %b %Y %T ", &tm))
- t = mktime(&tm);
-
- rev->time = t;
- continue;
- }
-
- if(! strncmp(buf, "Updated ", 8))
- continue; /* pathname of parent directory, don't give a fuck ... */
-
- if(buf[0] == 'M')
- continue; /* probably something like 'M U <filename>' */
-
- if(buf[0] == 'u' && buf[1] == '=')
- rev->perm = cvs_files_cvsattr_to_mode_t(buf);
-
-#if HAVE_LIBZ
- else if(buf[0] == 'z')
- {
- /* okay, we'll see a gzipped data stream
- * the number tells us the number of bytes we will retrieve,
- * not the size of the inflated file!
- */
- size_t bytes = atoi(buf + 1);
- error_t err;
-
- if(! bytes)
- {
- cvs_connection_kill(send, recv);
- FUNC_RETURN(EIO); /* this should not happen, empty file?? */
- }
-
- if((err = cvs_files_gzip_inflate(recv, bytes,
- &rev->contents, &rev->length)))
- {
- cvs_connection_kill(send, recv);
- FUNC_RETURN(err);
- }
- }
-#endif /* HAVE_LIBZ */
-
- else if(buf[0] >= '0' && buf[0] <= '9')
- {
- /* okay, this tells the length of our file.
- * the file is transmitted without compression applied
- */
- size_t read;
- size_t length = atoi(buf);
- size_t bytes = length;
- char *content = malloc(bytes);
- char *ptr = content;
-
- if(! content)
- {
- perror(PACKAGE);
- cvs_connection_kill(send, recv);
- FUNC_RETURN(ENOMEM);
- }
-
- while(bytes && (read = fread(ptr, 1, bytes, recv)))
- {
- bytes -= read;
- ptr += read;
- }
-
- if(bytes)
- {
- /* unable to read all data ... */
- fprintf(stderr, "unable to read whole file %s\n", file->name);
- free(content);
- cvs_connection_kill(send, recv);
- FUNC_RETURN(EIO);
- }
-
- free(rev->contents);
- rev->length = length;
- rev->contents = content;
- }
- else if(! strncmp(buf, "ok", 2))
- {
- cvs_connection_release(send, recv);
- return 0; /* seems like everything went well ... */
- }
- else if(buf[0] == 'E')
- {
- cvs_treat_error(recv, buf);
- cvs_connection_release(send, recv);
- return EIO;
- }
- else if(! strncmp(buf, "error", 5))
- {
- cvs_connection_release(send, recv);
- return EIO;
- }
- else
- break; /* fuck, what the hell is going on here?? get outta here! */
- }
-
- /* well, got EOF, that shouldn't ever happen ... */
- cvs_connection_kill(send, recv);
- FUNC_EPILOGUE(EIO);
-}
-
-
-
-/* cvs_files_hit
- *
- * ask cvs server whether there is a particular revision (as specified by rev)
- * available. return 0 if yes, ENOENT if not. EIO on communication error.
- */
-error_t
-cvs_files_hit(struct netnode *file, struct revision *rev)
-{
- FILE *send, *recv;
- unsigned short int got_something = 0;
-
- char buf[4096]; /* 4k should be enough for most cvs repositories, if
- * cvsfs tell's you to increase this value, please do so.
- */
-
- if(cvs_connect(&send, &recv))
- return EIO;
-
- /* write out request header */
- fprintf(send,
- "UseUnchanged\n"
- "Argument -s\n"
- "Argument -r\nArgument 0\n"
- "Argument -r\nArgument %s\n"
- "Argument ",
- rev->id);
-
- /* write out pathname from rootnode on ... */
- cvs_files_print_path_recursively(send, file->parent);
-
- /* last but not least write out the filename */
- fprintf(send, "%s\n", file->name);
-
- /* we need an rdiff ... */
- fprintf(send, "rdiff\n");
-
- /* okay, now read the server's response, which either is something
- * "M" char padded or an E, error couple.
- */
- while(fgets(buf, sizeof(buf), recv))
- {
- if(! strncmp(buf, "ok", 2))
- {
- cvs_connection_release(send, recv);
-
- if(! got_something)
- return ENOENT; /* no content, sorry. */
-
- return 0; /* jippie, looks perfectly, he? */
- }
-
- if(! strncmp(buf, "error", 5))
- {
- cvs_connection_release(send, recv);
- return EIO;
- }
-
- if(buf[1] != ' ')
- {
- cvs_treat_error(recv, buf);
- cvs_connection_release(send, recv);
- return EIO; /* hm, doesn't look got for us ... */
- }
-
- switch(buf[0])
- {
- case 'E':
- /* cvs_treat_error(recv, buf);
- * cvs_connection_release(send, recv);
- * return EIO;
- *
- * don't call cvs_treat_error since it's probably a
- * "no such tag %s" message ...
- */
- break;
-
- case 'M':
- got_something = 1;
- break;
-
- default:
- cvs_treat_error(recv, buf);
- cvs_connection_release(send, recv);
- return EIO;
- }
- }
-
- /* well, got EOF, that shouldn't ever happen ... */
- cvs_connection_kill(send, recv);
- return EIO;
-}
Index: cvs_files.h
===================================================================
RCS file: cvs_files.h
diff -N cvs_files.h
--- cvs_files.h 16 Nov 2005 21:18:08 -0000 1.5
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,27 +0,0 @@
-/**********************************************************
- * cvs_files.h
- *
- * Copyright 2004, Stefan Siegl <address@hidden>, Germany
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Publice License,
- * version 2 or any later. The license is contained in the COPYING
- * file that comes with the cvsfs distribution.
- *
- * download arbitrary revisions from cvs host and cache them locally
- */
-
-#ifndef CVS_FILES_H
-#define CVS_FILES_H
-
-#include <stdio.h>
-
-/* Download the revision (as specified by rev) of the specified file. */
-error_t cvs_files_cache(struct netnode *file, struct revision *rev);
-
-/* ask cvs server whether there is a particular revision (as specified by rev)
- * available. return 0 if yes, ENOENT if not. EIO on communication error.
- */
-error_t cvs_files_hit(struct netnode *file, struct revision *rev);
-
-#endif /* CVS_FILES_H */
Index: cvs_pserver.c
===================================================================
RCS file: cvs_pserver.c
diff -N cvs_pserver.c
--- cvs_pserver.c 16 Nov 2005 21:18:08 -0000 1.9
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,215 +0,0 @@
-/**********************************************************
- * cvs_pserver.c
- *
- * Copyright 2004, Stefan Siegl <address@hidden>, Germany
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Publice License,
- * version 2 or any later. The license is contained in the COPYING
- * file that comes with the cvsfs distribution.
- *
- * talk pserver protocol
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include <string.h>
-#include <malloc.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <pwd.h>
-#include <stdlib.h>
-
-#include "cvsfs.h"
-#include "cvs_pserver.h"
-#include "tcpip.h"
-#include "cvs_connect.h"
-
-/* look for a password entry in $HOME/.cvspass file, permitting login
- * with credentials from given config structure.
- */
-static char *cvs_pserver_fetch_pw(cvsfs_config *config);
-
-
-
-/* cvs_pserver_connect
- *
- * connect to the cvs pserver as further described in the cvsfs_config
- * configuration structure
- */
-error_t
-cvs_pserver_connect(FILE **send, FILE **recv)
-{
- char buf[128]; /* we only need to read something like I LOVE YOU
- * or some kind of error message (E,M)
- */
- if(! config.cvs_port) config.cvs_port = 2401;
- *send = *recv = tcpip_connect(config.cvs_hostname, config.cvs_port);
-
- if(! *send)
- /* tcpip connection couldn't be brought up, tcpip_connect spit out a
- * logmessage itself ...
- */
- return ENOENT;
-
- if(! config.cvs_password)
- config.cvs_password = cvs_pserver_fetch_pw(&config);
-
- /* okay, now let's talk a little pserver dialect to log in ... */
- fprintf(*send, "BEGIN AUTH REQUEST\n");
- fprintf(*send, "%s\n%s\n%s\n",
- config.cvs_root,
- config.cvs_username,
- config.cvs_password);
- fprintf(*send, "END AUTH REQUEST\n");
-
- /* okay, now watch out for the server's answer,
- * in the hope, that it loves us
- */
- if(! fgets(buf, sizeof(buf), *recv))
- {
- perror(PACKAGE);
- fclose(*send);
- /* fclose(*recv);
- * don't close *recv, it's just another reference to *send!! */
- return EIO;
- }
-
- if(strncmp(buf, "I LOVE YOU", 10))
- {
- cvs_treat_error(*recv, buf);
- fclose(*send);
- /* fclose(*recv); */
- return EPERM;
- }
-
- return 0;
-}
-
-
-
-/* cvs_pserver_fetch_pw
- *
- * look for a password entry in $HOME/.cvspass file, permitting login
- * with credentials from given config structure.
- * make sure to free() the returned memory, if needed!
- */
-static char *
-cvs_pserver_fetch_pw(cvsfs_config *config)
-{
- char buf[512]; /* 512 byte should be enough for most CVSROOTs, if
- * cvsfs tell's you to increase this value, please do so.
- */
- char *cvspass_path;
- FILE *cvspass;
- char *cvsroot;
- int cvsroot_len;
- const char null_pw[] = "A"; /* empty password, returned if we fail */
-
- if(! config->homedir)
- config->homedir = getenv("HOME");
-
- if(! config->homedir)
- {
- /* hmm, HOME environment variable not set, try scaning /etc/passwd
- * for the homedir path ...
- */
- uid_t uid = getuid();
- struct passwd *pwent;
-
- for(pwent = getpwent(); pwent; getpwent())
- if(pwent->pw_uid == uid)
- {
- config->homedir = strdup(pwent->pw_dir);
- break;
- }
-
- endpwent();
- }
-
- if(! config->homedir)
- {
- fprintf(stderr, PACKAGE ": cannot figure out what your homedir is. "
- "trying empty password.\n");
- return strdup(null_pw);
- }
-
- if(! (cvspass_path = malloc(strlen(config->homedir) + 10)))
- {
- perror(PACKAGE);
- return strdup(null_pw); /* I pray for it to have a long lasting life! */
- }
-
- sprintf(cvspass_path, "%s/.cvspass", config->homedir);
-
- if(! (cvspass = fopen(cvspass_path, "r")))
- {
- perror(PACKAGE ": cannot open .cvspass file for reading");
- free(cvspass_path);
- fprintf(stderr, PACKAGE ": trying to log in without password.\n");
- return strdup(null_pw);
- }
-
- free(cvspass_path);
-
- /* predict length of cvsroot string */
- cvsroot_len = 20 + strlen(config->cvs_username) +
- strlen(config->cvs_hostname) + strlen(config->cvs_root);
-
- if(! (cvsroot = malloc(cvsroot_len)))
- {
- fclose(cvspass);
- perror(PACKAGE);
- return strdup(null_pw); /* I pray for it to have a long lasting life! */
- }
-
- cvsroot_len = snprintf(cvsroot, cvsroot_len, ":pserver:address@hidden:%d%s",
- config->cvs_username, config->cvs_hostname,
- config->cvs_port, config->cvs_root);
-
- while(fgets(buf, sizeof(buf), cvspass))
- {
- char *ptr = buf + strlen(buf);
- ptr --;
-
- if(*ptr != 10)
- {
- fprintf(stderr, PACKAGE "cvs_pserver_fetch_pw's parse buffer is "
- "too small, stop for the moment.\n");
- exit(10);
- }
-
- /* chop the linefeed off the end */
- *ptr = 0;
-
- if(buf[0] != '/' || buf[1] != '1' || buf[2] != ' ')
- continue; /* syntax error, well, ignore silently ... */
-
- ptr = buf + 3;
-
- if(strncmp(ptr, cvsroot, cvsroot_len))
- continue; /* didn't match, try next one ... */
-
- ptr += cvsroot_len;
- if(*(ptr ++) != ' ')
- continue; /* missing separator, cvsroot of .cvspass differs ... */
-
- /* okay, ptr points to where the password begins ... */
- fclose(cvspass);
- free(cvsroot);
-
- return strdup(ptr);
- }
-
- /* hmm, eof reached, but no password found! */
- fprintf(stderr, PACKAGE ": cannot find password for CVSROOT '%s' in "
- "your .cvspass file, trying no password at all\n", cvsroot);
-
- fclose(cvspass);
- free(cvsroot);
-
- return strdup(null_pw);
-}
-
Index: cvs_pserver.h
===================================================================
RCS file: cvs_pserver.h
diff -N cvs_pserver.h
--- cvs_pserver.h 16 Nov 2005 21:18:08 -0000 1.3
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,23 +0,0 @@
-/**********************************************************
- * cvs_pserver.h
- *
- * Copyright 2004, Stefan Siegl <address@hidden>, Germany
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Publice License,
- * version 2 or any later. The license is contained in the COPYING
- * file that comes with the cvsfs distribution.
- *
- * talk pserver protocol
- */
-
-#ifndef CVS_PSERVER_H
-#define CVS_PSERVER_H
-
-#include <stdio.h>
-#include "cvsfs.h"
-
-/* connect to the cvs pserver */
-error_t cvs_pserver_connect(FILE **send, FILE **recv);
-
-#endif /* CVS_PSERVER_H */
Index: cvs_tree.c
===================================================================
RCS file: cvs_tree.c
diff -N cvs_tree.c
--- cvs_tree.c 16 Nov 2005 21:18:08 -0000 1.14
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,381 +0,0 @@
-/**********************************************************
- * cvs_tree.c
- *
- * Copyright 2004, Stefan Siegl <address@hidden>, Germany
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Publice License,
- * version 2 or any later. The license is contained in the COPYING
- * file that comes with the cvsfs distribution.
- *
- * download file/directory tree from cvs
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-
-#include "cvs_connect.h"
-#include "cvs_tree.h"
-
-static struct netnode *cvs_tree_enqueue(struct netnode *, const char *);
-
-/* check whether there already is a netnode for the file with the provided
- * name, create a new one, if not. add revision information for HEAD revision.
- */
-static error_t cvs_tree_enqueue_file(struct netnode *cwd, const char *filename,
- const char *revision);
-
-
-/* next file number (aka inode) we will assign */
-volatile unsigned int next_fileno = 1;
-
-
-/* netnode *cvs_tree_read
- *
- * read the whole file and directory tree of the module specified in config
- * structure. The tree is stored in **ptr_to_rootnode, make sure
- * *ptr_to_rootnode is NULL on first call.
- * RETURN: 0 on success
- */
-error_t
-cvs_tree_read(struct netnode **rootdir)
-{
- FUNC_PROLOGUE("cvs_tree_read");
- FILE *send, *recv;
- struct netnode *cwd = (void *) 0xDEADBEEF;
- char *ptr;
- char buf[4096]; /* 4k should be enough for most cvs repositories, if
- * cvsfs tell's you to increase this value, please do so.
- */
-
- if(cvs_connect(&send, &recv))
- FUNC_RETURN(EIO);
-
- fprintf(send,
- "UseUnchanged\n"
- "Argument -s\n" /* we don't want to download the file's contents */
- "Argument -r\nArgument 0\n"
- "Argument -r\nArgument HEAD\n"
- "Argument %s\n"
- "rdiff\n", config.cvs_module);
-
- /* cvs now either answers like this:
- * E cvs rdiff: Diffing <directory>
- * M File <file> is new; HEAD revision <revision>
- *
- * the other possibility is as follows:
- * E cvs rdiff: cannot find module <module> - ignored
- * error
- */
- while(fgets(buf, sizeof(buf), recv))
- {
- ptr = buf + strlen(buf);
- ptr --;
-
- if(*ptr != 10)
- {
- fprintf(stderr, PACKAGE "cvs_tree_read's parse buffer is "
- "too small, stop for the moment.\n");
- exit(10);
- }
-
- /* chop the linefeed off the end */
- *ptr = 0;
-
- if(! strncmp(buf, "ok", 2))
- {
- cvs_connection_release(send, recv);
- FUNC_RETURN(0);
- }
-
- if(! strncmp(buf, "error", 5))
- {
- cvs_connection_release(send, recv);
- FUNC_RETURN(EIO);
- }
-
- if(buf[1] != ' ')
- {
- cvs_treat_error(recv, buf);
- cvs_connection_release(send, recv);
- FUNC_RETURN(EIO);
- }
-
- DEBUG("tree-read", "%s\n", buf);
- switch(buf[0])
- {
- case 'E': /* E cvs rdiff: Diffing <directory> */
- if(! (ptr = strstr(buf, "Diffing ")))
- {
- cvs_treat_error(recv, buf);
- cvs_connection_release(send, recv);
- FUNC_RETURN(EIO);
- }
-
- ptr += 8;
- if(! *rootdir)
- cwd = *rootdir = cvs_tree_enqueue(NULL, ptr);
- else
- cwd = cvs_tree_enqueue(*rootdir, ptr);
-
- if(! cwd)
- {
- cvs_connection_kill(send, recv);
- FUNC_RETURN(ENOMEM);
- }
-
- break;
-
- case 'M': /* M File <file> is new; HEAD revision <revision> */
- if(! (ptr = strstr(buf, "File ")))
- {
- cvs_treat_error(recv, buf);
- cvs_connection_release(send, recv);
- FUNC_RETURN(EIO);
- }
-
- {
- const char *revision;
- const char *filename = (ptr += 5);
-
- if(! (ptr = strstr(filename, " is new")))
- {
- cvs_treat_error(recv, buf);
- cvs_connection_release(send, recv);
- FUNC_RETURN(EIO);
- }
- *(ptr ++) = 0;
-
- revision = ptr;
-
- /* strip leading path from filename */
- while((ptr = strchr(filename, '/')))
- filename = ptr + 1;
-
- if(! (ptr = strstr(revision, "revision ")))
- {
- cvs_treat_error(recv, NULL);
- cvs_connection_release(send, recv);
- FUNC_RETURN(EIO);
- }
-
- revision = (ptr += 9);
-
- if(cvs_tree_enqueue_file(cwd, filename, revision))
- {
- cvs_connection_kill(send, recv);
- FUNC_RETURN(ENOMEM);
- }
-
- break;
- }
-
- default:
- cvs_treat_error(recv, buf);
- cvs_connection_release(send, recv);
- FUNC_RETURN(EIO);
- }
- }
-
- cvs_connection_kill(send, recv);
- FUNC_EPILOGUE(EIO);
-}
-
-
-/* cvs_tree_enqueue(netnode, path)
- *
- * allocate an empty netnode structure for the directory addressed by
- * the argument 'path' and put it into the netnode structure *dir
- */
-static struct netnode *
-cvs_tree_enqueue(struct netnode *dir, const char *path)
-{
- struct netnode *new, *parent = NULL;
- char *end;
-
- DEBUG("tree-enqueue", "root=%s, path=%s\n", dir ? dir->name : NULL, path);
-
- if(! (end = strchr(path, '/')))
- {
- /* request for root directory, else there would be a '/' within
- * path. return existing rootdir (dir), if available.
- */
- if(dir) {
- if(! strcmp(dir->name, path))
- return dir;
-
- parent = dir;
- dir = (parent = dir)->child;
- }
- }
- else do
- {
- /* if we are in repository browsing mode (i.e. top level module's name
- * is '.', compare root dir's children names first, since the CVS server
- * writes something like CVSROOT/Emptydir (omitting the leading '.')
- */
- if(! strcmp(dir->name, "."))
- dir = dir->child;
-
- /* now select this directory from within dir (on the current level) */
- if(dir)
- do
- if(strncmp(dir->name, path, end - path) == 0
- /* make sure not to match partials: */
- && dir->name[end - path] == 0)
- break; /* hey, this is the directory we're looking for! */
- while((dir = dir->sibling));
-
- if(! dir)
- {
- /* this MUST NOT happen, if it occurs anyways, there seems to be
- * something wrong with our cvs server!
- */
- fprintf(stderr, PACKAGE ": unable to find directory '%s'\n", path);
- return NULL;
- }
-
- path = end + 1;
- dir = (parent = dir)->child;
- }
- while((end = strchr(path, '/')));
-
- /* scan parent directory for the entry we're looking for ... */
- if(parent)
- for(new = parent->child; new; new = new->sibling)
- if(! strcmp(new->name, path))
- return new;
-
- /* okay, create new directory structure right in place ... */
- DEBUG("tree-enqueue", "adding new node: parent=%s, path=%s\n",
- parent ? parent->name : NULL, path);
-
- new = malloc(sizeof(*new));
- if(! new)
- {
- perror(PACKAGE);
- return NULL; /* pray for cvsfs to survive! */
- }
-
- new->name = strdup(path);
- new->sibling = dir;
- new->child = NULL;
- new->parent = parent;
- new->revision = NULL; /* mark as a directory */
- new->fileno = next_fileno ++;
- new->node = NULL;
-
- rwlock_init(&new->lock);
-
- if(parent)
- parent->child = new;
-
- return new;
-}
-
-
-/* cvs_tree_enqueue_file
- *
- * check whether there already is a netnode for the file with the provided
- * name, create a new one, if not. add revision information for HEAD revision.
- */
-static error_t
-cvs_tree_enqueue_file(struct netnode *cwd,
- const char *filename, const char *revision)
-{
- struct netnode *entry;
-
- /* cvs_tree_add_rev_struct
- * add a mostly empty revision structure to the specified netnode
- */
- error_t cvs_tree_add_rev_struct(struct netnode *entry, const char *revision)
- {
- struct revision *cached_rev;
-
- rwlock_writer_lock(&entry->lock);
- cached_rev = entry->revision;
-
- if(! (entry->revision = malloc(sizeof(*entry->revision))))
- {
- rwlock_writer_unlock(&entry->lock);
- return ENOMEM; /* pray for cvsfs to survive! */
- }
-
- entry->revision->id = strdup(revision);
- entry->revision->contents = NULL;
- entry->revision->next = cached_rev;
-
- rwlock_init(&entry->revision->lock);
- rwlock_writer_unlock(&entry->lock);
-
- return 0;
- }
-
- /* well, first scan directory tree whether we already have
- * the file we're looking for ...
- */
- for(entry = cwd->child; entry; entry = entry->sibling)
- if(! strcmp(entry->name, filename))
- {
- /* okay, we already got a netnode for file 'filename', check whether
- * revision information is up to date ...
- */
- rwlock_reader_lock(&entry->lock);
- if(! strcmp(revision, entry->revision->id))
- {
- rwlock_reader_unlock(&entry->lock);
- return 0; /* head revision id hasn't changed ... */
- }
- rwlock_reader_unlock(&entry->lock);
-
- /* okay, create new revision struct */
- if(cvs_tree_add_rev_struct(entry, revision))
- return ENOMEM;
-
- return 0;
- }
-
- /* okay, don't have this particular file available,
- * put a new netnode together ...
- */
- if(! (entry = malloc(sizeof(*entry))))
- {
- perror(PACKAGE);
- return ENOMEM; /* pray for cvsfs to survive! */
- }
-
- entry->name = strdup(filename);
- entry->sibling = cwd->child;
- entry->child = NULL;
- entry->parent = cwd;
- entry->fileno = next_fileno ++;
- entry->node = NULL;
-
- /* create lock entry for our new netnode, as it is not linked
- * to somewhere and this is the only thread to update tree info,
- * we don't have to write lock to access entry->revision!
- */
- rwlock_init(&entry->lock);
-
- entry->revision = NULL;
- if(cvs_tree_add_rev_struct(entry, revision))
- {
- perror(PACKAGE);
- free(entry->name);
- free(entry);
- return ENOMEM;
- }
-
- /* do this as late as possible, aka only if the full entry structure
- * is valid, since we do not lock the netnode -- however we're in the
- * only thread touching the tree at all
- */
- cwd->child = entry;
-
- return 0;
-}
Index: cvs_tree.h
===================================================================
RCS file: cvs_tree.h
diff -N cvs_tree.h
--- cvs_tree.h 16 Nov 2005 21:18:08 -0000 1.4
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,26 +0,0 @@
-/**********************************************************
- * cvs_tree.h
- *
- * Copyright 2004, Stefan Siegl <address@hidden>, Germany
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Publice License,
- * version 2 or any later. The license is contained in the COPYING
- * file that comes with the cvsfs distribution.
- *
- * download file/directory tree from cvs
- */
-
-#ifndef CVS_TREE_H
-#define CVS_TREE_H
-
-#include <stdio.h>
-
-/* read the whole file and directory tree of the module specified in config
- * structure. The tree is stored in **ptr_to_rootnode, make sure
- * *ptr_to_rootnode is NULL on first call.
- * RETURN: 0 on success
- */
-error_t cvs_tree_read(struct netnode **ptr_to_rootnode);
-
-#endif /* CVS_TREE_H */
Index: cvsfs.1
===================================================================
RCS file: cvsfs.1
diff -N cvsfs.1
--- cvsfs.1 16 Nov 2005 21:18:08 -0000 1.4
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,92 +0,0 @@
-.TH CVSFS "1" "October 2004" "cvsfs (cvsfs) 0.1" "User Commands"
-.SH NAME
-cvsfs \- mount remotely located cvs module
-.SH SYNOPSIS
-.B cvsfs
-[\fIOPTION\fR...] \fIHOSTNAME CVSROOT MODULE\fR
-.SH DESCRIPTION
-CVS filesystem translator for the GNU Hurd, allowing to mount the remotely
-located CVS module MODULE right into your local filesystem. The version
-controlled files will look like ordinary (local) ones to you afterwards.
-.PP
-Supply the hostname of the CVS pserver as HOSTNAME, the root CVS directory
-(the one, where CVS' CVSROOT directory is located in) as CVSROOT.
-.TP
-\fB\-z\fR, \fB\-\-gzip\fR=\fILEVEL\fR
-use gzip compression of specified level for file transfers.
-A compression level of 1 means be fast, 9 means best compression.
-
-Unlike cvs cvsfs tends to use gzip compression of level 3 by
-default. If you want to turn compression off, you need to
-request level 0.
-.TP
-\fB\-h\fR, \fB\-\-homedir\fR=\fIPATH\fR
-path of your home directory (the directory where cvsfs
-shall look for the .cvspass file, which is used to find
-out which password to use to authenticate)
-.TP
-\fB\-n\fR, \fB\-\-nostats\fR
-do not download revisions to aquire stats information.
-
-cvsfs has to download each whole file if it needs to tell the timestamp
-or set permissions of a particular revision. Therefore cvsfs needs to
-download quite a lot of data if you e.g. need a directory listing with
-true stats information. In case you are not in need of such, you can
-specify this option. Filesize will be reported as zero and timestamp
-as current - no downloading will happen unless you open the file for
-reading.
-.TP
-\fB\-p\fR, \fB\-\-port\fR=\fIPORT\fR
-port to connect to on given host (if not using
-standard port, for pserver 2401)
-.TP
-\fB\-r\fR, \fB\-\-remote\fR[=\fICLIENT\fR]
-connect to CVS server using the remote shell client CLIENT.
-If CLIENT is omitted 'rsh' will be used. If you don't specify
-a --remote option at all, pserver protocol will be used.
-
-Make sure that the shell client you want to use logs in
-automatically since translators (and thus cvsfs translator)
-don't have a connected terminal. Therefore you will not be
-able to enter a password.
-.TP
-\fB\-u\fR, \fB\-\-user\fR=\fIUSERNAME\fR
-username to supply to cvs host when logging in. 'anonymous'
-will be used if you don't specify one. If you want your
-login name to be used, you have to specify that using --user argument
-(unless you logged in as 'anonymous' though)
-.TP
--?, \fB\-\-help\fR
-Write out some help text
-.TP
-\fB\-\-usage\fR
-Give a short usage message
-.TP
-\fB\-V\fR, \fB\-\-version\fR
-Print program version
-.PP
-Mandatory or optional arguments to long options are also mandatory or optional
-for any corresponding short options.
-.PP
-Please mind that cvsfs is currently very much in alpha alike state,
-therefore please do not expect a translator working perfectly right now.
-.PP
-.SH AUTHOR
-Written by Stefan Siegl
-.SH COPYRIGHT
-Copyright \(co 2004, Stefan Siegl <address@hidden>, Germany
-.br
-This is free software; see the source for copying conditions. There is NO
-warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-.SH "SEE ALSO"
-The full documentation for
-.B cvsfs
-is maintained as a Texinfo manual. If the
-.B info
-and
-.B cvsfs
-programs are properly installed at your site, the command
-.IP
-.B info cvsfs
-.PP
-should give you access to the complete manual.
Index: cvsfs.c
===================================================================
RCS file: cvsfs.c
diff -N cvsfs.c
--- cvsfs.c 16 Nov 2005 21:18:08 -0000 1.17
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,280 +0,0 @@
-/**********************************************************
- * cvsfs.c
- *
- * Copyright (C) 2004, 2005 by Stefan Siegl <address@hidden>, Germany
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Publice License,
- * version 2 or any later. The license is contained in the COPYING
- * file that comes with the cvsfs distribution.
- *
- * translator startup code (netfs startup & argp handling)
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include <stdio.h>
-#include <argp.h>
-#include <string.h>
-#include <stdlib.h>
-
-#include <unistd.h>
-#include <error.h>
-#include <netdb.h>
-#include <sys/stat.h>
-#include <hurd/netfs.h>
-
-#include "cvsfs.h"
-#include "cvs_connect.h"
-#include "cvs_tree.h"
-#include "node.h"
-
-/* cvsfs configuration: cvs pserver hostname, rootdir, modulename, etc. */
-cvsfs_config config;
-
-/* cvsfs entry stat template */
-cvsfs_stat_template stat_template;
-
-/* global variables, needed for netfs */
-char *netfs_server_name = PACKAGE;
-char *netfs_server_version = VERSION;
-int netfs_maxsymlinks = 12;
-
-
-
-static error_t parse_cvsfs_opt(int key, char *arg, struct argp_state *state);
-
-static const struct argp_child argp_children[] =
- {
- {&netfs_std_startup_argp, 0, NULL, 0},
- {NULL, 0, NULL, 0}
- };
-
-
-
-/* documentation, written out when called with either --usage or --help */
-const char *argp_program_version = "cvsfs (" PACKAGE ") " VERSION "\n"
-"Written by Stefan Siegl\n\n"
-"Copyright (C) 2004, 2005 Stefan Siegl <address@hidden>, Germany\n"
-"This is free software; see the source for copying conditions. There is NO\n"
-"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
-"\n";
-static char *args_doc = "HOSTNAME CVSROOT MODULE";
-static char *doc = "cvs filesystem translator for the Hurd.\v"
-"Please mind that " PACKAGE " is currently very much in alpha alike state, "
-"therefore please do not expect a translator working perfectly right now.\n\n"
-PACKAGE " translator will show the remotely located CVS module 'MODULE' "
-"from host 'HOSTNAME' as it's files were located right on your computer.";
-
-/* options our translator understands, to be used by libc argp */
-enum
- {
- OPT_PORT = 'p',
- OPT_USER = 'u',
- OPT_HOMEDIR = 'h',
- OPT_REMOTE = 'r',
- OPT_LOCAL = 'l',
- OPT_NOSTATS = 'n',
- OPT_DEBUG = 'd',
-#ifdef HAVE_LIBZ
- OPT_GZIP = 'z',
-#endif
- };
-
-static const struct argp_option cvsfs_options[] =
- {
- { "port", OPT_PORT, "PORT", 0,
- "port to connect to on given host (if not using standard port)", 0 },
- { "user", OPT_USER, "USERNAME", 0,
- "username to supply to cvs host, when logging in", 0 },
- { "homedir", OPT_HOMEDIR, "PATH", 0,
- "path of your home directory (= path to .cvspass file)", 0 },
- { "remote", OPT_REMOTE, "CLIENT", OPTION_ARG_OPTIONAL,
- "connect through :ext: remote shell client CLIENT to cvs host", 0 },
- { "local", OPT_LOCAL, 0, 0,
- "show files from local cvs repository", 0 },
- { "nostats", OPT_NOSTATS, 0, 0,
- "do not download revisions to aquire stats information", 0 },
- { "debug", OPT_DEBUG, "FILE", OPTION_ARG_OPTIONAL,
- "print debug output to FILE or stderr", 0 },
-#if HAVE_LIBZ
- { "gzip", OPT_GZIP, "LEVEL", 0,
- "use gzip compression of specified level for file transfers", 0 },
-#endif
- /* terminate list */
- { NULL, 0, NULL, 0, NULL, 0 }
- };
-
-volatile struct mapped_time_value *cvsfs_maptime;
-
-/* pointer to root netnode */
-struct netnode *rootdir = NULL;
-
-
-int
-main(int argc, char **argv)
-{
- io_statbuf_t ul_stat;
- mach_port_t bootstrap, ul_node;
- struct argp argp =
- {
- cvsfs_options, parse_cvsfs_opt,
- args_doc, doc, argp_children,
- NULL, NULL
- };
-
- cvs_connect_init();
-
- /* reset configuration structure to sane defaults */
- memset(&config, 0, sizeof(config));
- config.cvs_mode = PSERVER;
- config.cvs_username = "anonymous";
- config.debug_port = NULL; /* no debugging by default */
-#if HAVE_LIBZ
- config.gzip_level = 3;
-#endif
-
- /* parse command line parameters, first things first. */
- argp_parse(&argp, argc, argv, 0, 0, 0);
-
- /* set up our translator now ... */
- task_get_bootstrap_port(mach_task_self(), &bootstrap);
- netfs_init();
-
- /* download initial root directory */
- if(cvs_tree_read(&rootdir))
- {
- fprintf(stderr, PACKAGE ": unable to get initial cvs tree, stop.\n");
- return 1;
- }
-
- /* map time */
- if(maptime_map(0, 0, &cvsfs_maptime))
- {
- perror(PACKAGE ": cannot map time");
- return 1;
- }
-
- /* start up netfs stuff */
- ul_node = netfs_startup(bootstrap, 0);
-
- if(io_stat(ul_node, &ul_stat))
- {
- perror(PACKAGE ": cannot stat underlying node");
- return 1;
- }
-
- /* initialize our stat_template structure */
- stat_template.uid = ul_stat.st_uid;
- stat_template.gid = ul_stat.st_gid;
- stat_template.author = ul_stat.st_author;
- stat_template.fsid = getpid();
- stat_template.mode = ul_stat.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO);
-
- /* create our root node */
- netfs_root_node = cvsfs_make_node(rootdir);
- if(! netfs_root_node)
- {
- perror(PACKAGE ": cannot create rootnode");
- return 1;
- }
-
- netfs_server_loop();
- return 1; /* netfs_server_loop doesn't return, exit with status 1, if
- * it returns anyways ...
- */
-}
-
-
-/* parse_cvsfs_opt
- *
- * argp parser function for cvsfs'es command line args
- */
-static error_t
-parse_cvsfs_opt(int key, char *arg, struct argp_state *state)
-{
- switch(key)
- {
- case OPT_PORT:
- config.cvs_port = atoi(arg);
- break;
-
- case OPT_USER:
- config.cvs_username = strdup(arg);
- break;
-
- case OPT_HOMEDIR:
- config.homedir = strdup(arg);
- break;
-
- case OPT_NOSTATS:
- config.nostats = 1;
- break;
-
- case OPT_DEBUG:
- if(arg)
- {
- config.debug_port = fopen(arg, "w");
- if(errno)
- perror(PACKAGE);
- }
-
- /* if either no file was specified or in case we cannot open it,
- * write debugging output to standard error */
- if(! config.debug_port)
- config.debug_port = stderr;
-
- break;
-
-#if HAVE_LIBZ
- case OPT_GZIP:
- config.gzip_level = atoi(arg);
- break;
-#endif
-
- case OPT_REMOTE:
- config.cvs_mode = EXT;
- if(arg)
- config.cvs_shell_client = strdup(arg);
- else
- {
- const char *rsh = getenv("CVS_RSH");
- if(rsh)
- config.cvs_shell_client = strdup(arg);
- else
- config.cvs_shell_client = "rsh";
- }
- break;
-
- case OPT_LOCAL:
- config.cvs_mode = LOCAL;
- break;
-
- case ARGP_KEY_ARGS:
- if(state->argc - state->next != 3)
- argp_usage(state);
- else
- {
- if(strcmp(state->argv[state->next], "localhost"))
- config.cvs_hostname = strdup(state->argv[state->next]);
- else
- config.cvs_mode = LOCAL;
-
- state->next ++;
- config.cvs_root = strdup(state->argv[state->next ++]);
- config.cvs_module = strdup(state->argv[state->next ++]);
- }
- break;
-
- case ARGP_KEY_NO_ARGS:
- argp_usage(state);
- break;
-
- default:
- return ARGP_ERR_UNKNOWN;
- }
-
- return 0;
-}
Index: cvsfs.h
===================================================================
RCS file: cvsfs.h
diff -N cvsfs.h
--- cvsfs.h 16 Nov 2005 21:18:08 -0000 1.15
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,203 +0,0 @@
-/**********************************************************
- * cvsfs.h
- *
- * Copyright (C) 2004, 2005 by Stefan Siegl <address@hidden>, Germany
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Publice License,
- * version 2 or any later. The license is contained in the COPYING
- * file that comes with the cvsfs distribution.
- *
- * configuration structures
- */
-
-#ifndef CVSFS_CONFIG_H
-#define CVSFS_CONFIG_H
-
-#include <maptime.h>
-extern volatile struct mapped_time_value *cvsfs_maptime;
-
-#include <stdio.h>
-#include <rwlock.h>
-
-
-typedef struct {
- enum { PSERVER, EXT, LOCAL } cvs_mode;
- char *cvs_shell_client; /* program to use for :ext: connection */
-
- char *cvs_hostname;
- int cvs_port; /* port no. in localhost's endianess */
-
- char *cvs_username;
- char *cvs_password;
-
- char *cvs_root;
- char *cvs_module;
-
- char *homedir; /* homedir of user (location of .cvspass file) */
-
- /* whether or whether not the user wants to have no true stats information,
- * this would save downloading revisions just to have the timestamp and
- * permissions set correctly.
- */
- unsigned nostats :1;
-
-#if HAVE_LIBZ
- /* which gzip level to use for file requests */
- unsigned gzip_level :4;
-#endif
-
- /* file-handle to write debug information out to,
- * NULL, if no debug info is to be written out */
- FILE *debug_port;
-
-} cvsfs_config;
-extern cvsfs_config config;
-
-
-
-typedef struct {
- __uid_t uid;
- __gid_t gid;
- __uid_t author;
- __fsid_t fsid;
- __mode_t mode;
-} cvsfs_stat_template;
-extern cvsfs_stat_template stat_template;
-
-
-
-struct revision;
-struct revision {
- /* revision id, something like 1.14 or 1.2.1.12 */
- char *id;
-
- /* this revisions access permissions */
- mode_t perm;
-
- /* revision's mtime stamp */
- time_t time;
-
- /* length of contents field */
- size_t length;
-
- /* pointer to this revision's contents */
- char *contents;
-
- /* pointer to the next revision structure, if there are multiple
- * revisions available locally
- */
- struct revision *next;
-
- /* locking mechanism for the revision structure, needs to be held,
- * on read/write access to contents field.
- */
- struct rwlock lock;
-};
-
-
-
-struct netnode;
-struct netnode {
- /* name of this node, aka file or directory */
- char *name;
-
- /* link to the next file or directory, within this directory */
- struct netnode *sibling;
-
- /* link to the first child of this directory, this points to the second
- * child via it's sibling pointer. NULL, if either this directory is empty
- * or this node represents a file
- */
- struct netnode *child;
-
- /* link to the parent netnode of this file or directory */
- struct netnode *parent;
-
- /* head revision number of this netnode, NULL to show, that this node
- * represents a directory!
- */
- struct revision *revision;
-
- /* inode number, assigned to this netnode structure */
- unsigned int fileno;
-
- /* pointer to node structure, assigned to this netnode */
- struct node *node;
-
- /* locking mechanism for the netnode. this needs to be held whenever touching
- * the revisions tree (the linking), access to revision to check whether it
- * is NULL (and therefore a directory) doesn't need to be locked.
- * for the revision structure itself there
- * is a separate lock inside each struct revision.
- *
- * furthermore access to node pointer must be locked.
- */
- struct rwlock lock;
-};
-
-/* pointer to root netnode */
-extern struct netnode *rootdir;
-
-
-
-/* helper macros for debugging ****/
-#define DEBUG(cat,msg...) \
- if(config.debug_port) \
- fprintf(config.debug_port, PACKAGE ": " cat ": " msg);
-
-#define FUNC_PROLOGUE_(func_name, fmt...) \
- do \
- { \
- const char *debug_func_name = func_name; \
- DEBUG("tracing", "entering %s (" __FILE__ ":%d) ", \
- debug_func_name, __LINE__); \
- if(config.debug_port) \
- { \
- fmt; \
- fprintf(config.debug_port, "\n"); \
- }
-
-#define FUNC_PROLOGUE(func_name) \
- FUNC_PROLOGUE_(func_name, (void)0)
-
-#define FUNC_PROLOGUE_FMT(func_name, fmt...) \
- FUNC_PROLOGUE_(func_name, fprintf(config.debug_port, fmt))
-
-#define FUNC_PROLOGUE_NODE(func_name, node) \
- FUNC_PROLOGUE_FMT(func_name, "node=%s", (node)->nn->name)
-
-#define FUNC_EPILOGUE_NORET() \
- DEBUG("tracing", "leaving %s\n", debug_func_name); \
- } while(0);
-
-#define FUNC_RETURN_(ret, fmt) \
- { \
- int retval = (ret); \
- DEBUG("tracing", "leaving %s (" __FILE__ ":%d) ret=%d ", \
- debug_func_name, __LINE__, retval); \
- if(config.debug_port) \
- { \
- fmt; \
- fprintf(config.debug_port, "\n"); \
- } \
- return retval; \
- }
-
-#define FUNC_EPILOGUE_(ret, fmt) \
- FUNC_RETURN_(ret, fmt) \
- } while(0);
-
-#define FUNC_RETURN_FMT(ret, fmt...) \
- FUNC_RETURN_(ret, fprintf(config.debug_port, fmt))
-
-#define FUNC_EPILOGUE_FMT(ret, fmt...) \
- FUNC_EPILOGUE_(ret, fprintf(config.debug_port, fmt))
-
-#define FUNC_RETURN(ret) \
- FUNC_RETURN_(ret, (void)0)
-
-#define FUNC_EPILOGUE(ret) \
- FUNC_EPILOGUE_(ret, (void)0)
-
-#endif /* CVSFS_CONFIG_H */
Index: cvsfs.texi
===================================================================
RCS file: cvsfs.texi
diff -N cvsfs.texi
--- cvsfs.texi 16 Nov 2005 21:18:08 -0000 1.6
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,413 +0,0 @@
-\input texinfo @c -*- texinfo -*-
address@hidden $Id: cvsfs.texi,v 1.6 2005/11/16 21:18:08 stesie Exp $
address@hidden %**start of header
address@hidden cvsfs.info
address@hidden version.texi
address@hidden @sc{cvsfs} virtual filesystem translator
address@hidden pg cp
address@hidden %**end of header
-
-
-
address@hidden
-Copyright @copyright{} 2004, 2005 by Stefan Siegl, Germany
-
address@hidden
-Permission is granted to copy, distribute and/or modify this document
-under the terms of the GNU Free Documentation License, Version 1.1
-or any later version published by the Free Software Foundation;
-with no Invariant Sections, with no
-Front-Cover Texts, and with no Back-Cover Texts.
-A copy of the license is included in the section entitled ``GNU
-Free Documentation License''.
address@hidden quotation
address@hidden copying
-
address@hidden
address@hidden @sc{cvsfs}
address@hidden (virtual CVS filesystem translator for the GNU Hurd)
address@hidden for version @value{VERSION}, @value{UPDATED}
address@hidden Stefan Siegl (@email{stesie@@brokenpipe.de})
-
address@hidden
address@hidden 0pt plus 1filll
-
address@hidden
address@hidden titlepage
-
address@hidden
-
address@hidden
address@hidden Top
address@hidden cvsfs virtual filesystem translator
address@hidden ifnottex
-
-This manual documents version @value{VERSION} of the @sc{cvsfs}
-virtual filesystem translator.
-
-
address@hidden
-
address@hidden
-* Overview:: On how to get in touch.
-* Authentication:: Using username/password to log in.
-* Remote Shell Connections:: Using rsh or ssh to connect to the cvs host.
-* Browsing Local Repositories:: Browsing a local cvs repository with cvsfs
-* File Status Information:: File's status and access permissions.
-* Write Support:: On writing to cvsfs mounted modules.
-* Copying This Manual::
-* Index::
address@hidden menu
-
address@hidden
---------------------------------------------------------------------------
address@hidden Overview
address@hidden Overview
address@hidden Overview
-
-This chapter is for people who have never heard of or at least used @sc{cvsfs},
-and perhaps have not get in touch with version control software before.
-
-If you are already familiar with CVS you probably will not feel
-uncomfortable with @sc{cvsfs} right from the start.
-
address@hidden
-* What is cvsfs?:: What you can do with cvsfs
-* What is cvsfs not?:: Things you cannot solve with cvsfs
-* Sample:: Tour of basic usage
address@hidden menu
-
address@hidden
---------------------------------------------------------------------------
address@hidden What is cvsfs?
address@hidden What is cvsfs?
address@hidden What is cvsfs?
address@hidden Introduction to cvsfs
-
address@hidden is a so called translator for the GNU Hurd operating system,
-enabling to bind remotely located CVS modules right into your local
-file system tree. It allows to view version controlled files right
-the same way you look at ordinary (locally stored) ones.
-
-This software is still being developed, therefore please do not expect
-a program without any bugs.
-
-Mounting a CVS module allows you to view your (or others') version controlled
-files with the programs you are used to. This is, you can view any file,
-checked into CVS, using your favourite text editor (aka emacs) without
-having to check the
-whole module out. Thus you save the time and network bandwidth necessary
-to do a full checkout as @sc{cvsfs} downloads the directory tree only.
-Each file's content is only downloaded if necessary, i.e. if you try to read
-it.
-
address@hidden TODO if cvsfs is little older, perhaps mention it's history
-
address@hidden Source, getting cvsfs sources
-You can get @sc{cvsfs} in a variety of ways, including
-free download from the internet. For more information on
-downloading @sc{cvsfs} and other @sc{cvsfs} topics, see:
-
address@hidden
address@hidden://savannah.nongnu.org/projects/hurdextras/}
address@hidden example
-
address@hidden Mailing list
address@hidden List, mailing list
-There is a mailing list @email{hurdextras-hackers@@nongnu.org},
-which may be used for discussions concerning @sc{cvsfs}.
-To subscribe or unsubscribe write to
address@hidden@@nongnu.org}.
-
address@hidden
---------------------------------------------------------------------------
address@hidden What is cvsfs not?
address@hidden What is cvsfs not?
address@hidden What is cvsfs not?
-
address@hidden can do a lot of things for you, but it does
-not try to be everything for everyone.
-
address@hidden @asis
address@hidden Write support
address@hidden @sc{cvsfs} does not support writing.
-
-Though you might want it to have write support I consider this
-feature useless. What is the advantage of being able to change
-files in the cvsfs virtual filesystem, having to write a log message
-to some obscure target?
-
-I think it would not make things easier compared to the common
address@hidden ci}?
-
address@hidden @sc{cvsfs} is not a replacement for @code{cvs}.
-
-Even though it might look to you as such, but it should not. There
-are quite huge differencies between @sc{cvsfs} and common cvs.
address@hidden aims to be a little tool, allowing to hit and view just a few
files
-out of a nested cvs directory tree. However cvs is thought to check things
-out in order to edit or compile them, i.e. allowing to write,
-etc. That said, it might look more reasonable to compare it with viewcvs
-or similar packages, however these allow to view files over the web only.
-
address@hidden table
-
address@hidden
---------------------------------------------------------------------------
address@hidden Sample
address@hidden Sample
address@hidden Example of a work-session
address@hidden Getting started
-
-As a way of introducing @sc{cvsfs}, we'll go through a
-typical work-session using @sc{cvsfs}. Suppose you
-want to view the CVS repository of wsdebug, a debugger for
-the whitespace programming language.
-
address@hidden Translators, concept
address@hidden Translators, setting up
address@hidden settrans
-The first thing to
-understand is the GNU Hurd's concept of translators. A so called
-translator is a userspace program, translating e.g. network stored
-data to local filesystem nodes. Those translators are set up using
address@hidden
-
-Assuming you have created an empty directory called wsdebug-src,
-you need to enter
-
address@hidden
-settrans -a wsdebug-src cvsfs cvs.berlios.de /cvsroot/wsdebug wsdebug
address@hidden example
-
-to set up an active translator, mapping the CVS module
address@hidden from below @code{/cvsroot/wsdebug} stored on
address@hidden to the specified local directory.
-
-Now you can enter and browse the wsdebug-src directory the way
-you are used to. For example you can @code{cd wsdebug-src}, do
-a @code{ls} to show which files are available and choose one file
-to open with the text editor of your choice. You can even use
-graphical file managers like @code{xfm} to view the directory tree.
-
address@hidden Translators, killing
address@hidden getting rid of cvsfs instance
address@hidden Translators, getting rid
-In order to get rid of the translator leave the wsdebug-src/
-directory tree and enter
-
address@hidden
-settrans -g wsdebug-src
address@hidden example
-
address@hidden
---------------------------------------------------------------------------
address@hidden Authentication
address@hidden Authentication
address@hidden Authentication
address@hidden Username
address@hidden Password, supplied when authenticating
-
address@hidden by default uses the omnipresent CVS pserver protocol to
-connect to the specified CVS remote host. This protocol requires
-to supply login information (thus user-id and password) right after
-connecting.
-
address@hidden .cvspass file
address@hidden anonymous
address@hidden login, username
address@hidden login, anonymously
-As you probably will use @sc{cvsfs} to mainly browse
-CVS repositories of open source projects you are interested in,
-anonymously, @sc{cvsfs} defaults to supply @code{anonymous} as
-your user-id. If not otherwise specified in your @code{.cvspass} file it
-will use an empty password to log in. This is what you probably want,
-if you connect to repositories of sourceforge.net or the quite similar
-developer.berlios.de. However this is not what you might expect, if
-you are very familiar with CVS which tends to supply your username, if
-you don't tell it to use @code{anonymous}!
-
-If you want to connect to a repository where you need to supply a
-real user-id, you need to supply the @option{--user} option, followed
-by the username of your choice.
-
-Before establishing the host connection @sc{cvsfs} tries to scan your
address@hidden file for the password to be used when trying to
-authenticate. If it cannot find the password file or the file simply
-does not tell a suitable password, the translator will bark
-and try logging in without a password (probably failing, if you
-are not using anonymous login credentials).
-
address@hidden homedir
address@hidden /etc/passwd
address@hidden looks for a @code{.cvspass} file in your home directory (as
-specified in @code{/etc/passwd} file) by default. If you - for whatever
reason - want
-it to read from an other password file, supply it's directory using
-the @option{--homedir} option.
-
address@hidden Password, adding to .cvspass
-If there is no entry for the CVSROOT of choice in your password file,
-simply use CVS' @code{login} command. For example, if you would like
-to log into cvsfs's CVS repository using my credentials, do
-something like that:
-
address@hidden
-$ cvs -d:pserver:stesie@@savannah.nongnu.org:/cvsroot/hurdextras login
-CVS password: <password>
-$ settrans -a cvsfs-src /sbin/cvsfs --user stesie \
- savannah.nongnu.org /cvsroot/hurdextras cvsfs
address@hidden example
-
address@hidden
---------------------------------------------------------------------------
address@hidden Remote Shell Connections
address@hidden Remote Shell Connections
address@hidden Remote Shell Connections
address@hidden pserver
address@hidden CVS pserver
address@hidden ssh
address@hidden rsh
address@hidden Shell Client
address@hidden Remote Shell Client (rsh)
-
address@hidden by default uses the pserver protocol to
-connect to the specified CVS remote host. This is what you probably
-want to use, if you are not the developer of the project on which
-sources you would like to glance at. If you want to use @sc{cvsfs} to
-view the source of a sourceforge hosted project you are contributing
-to, you may want to use the @code{ssh} remote shell client to connect
-(because the anonymous cvs server is commonly some hours behind, so
-you will not see most recent changes).
-
-In order to tell @sc{cvsfs} that you want a remote shell client to be used,
-simply supply the @option{--remote} option when calling @code{settrans}.
-However @sc{cvsfs} tends to use the ancient @code{rsh} shell client,
-just like CVS does. If you want to use @code{ssh}, you need to supply
address@hidden (or abbreviated: @option{-rssh}) when launching.
-
address@hidden will use @code{anonymous} as the user-id to the remote
-shell client, if you do not specify your real id using
address@hidden option, therefore be careful when you are too much
-used to using cvs.
-
address@hidden Password, ssh not asking
address@hidden authorized_keys
-Please consider that ssh, or whichever remote shell client you use,
-cannot ask you for your password, since translators are not connected
-to a terminal on the Hurd. Therefore you need to configure it to
-put you straight to the command prompt when calling it something like
address@hidden -l USERNAME HOSTNAME}. To allow this, you probably want to
-create a @code{$HOME/.ssh/authorized_keys} file on the remote host.
-
address@hidden
---------------------------------------------------------------------------
address@hidden Browsing Local Repositories
address@hidden Browsing Local Repositories
address@hidden Browsing Local Repositories
-
-Apart from using @sc{cvsfs} to browse remotely located CVS repositories,
-using either pserver protocol or the :ext: method, you may even use it
-to browse CVS repositories which are located on your computer or
-otherwise mounted into your filesystem.
-
-In order to make @sc{cvsfs} behaving this way, either start it with
address@hidden as the @option{HOSTNAME} or specify the
address@hidden option. Mind that you must not omit the
address@hidden argument in any case, even the latter one. The argument is
-just not going to be evaluated if the @option{--local} option is present.
-
-As an exampe, if you would like, to browse the CVSROOT pseudo module
-of your local host's CVS repository (located at
address@hidden/var/lib/cvs}) type something like this:
-
address@hidden
-$ settrans -a test-node/ /sbin/cvsfs --local - /var/lib/cvs CVSROOT
address@hidden example
-
-You may now enter the directory @code{test-node/}, which allows you to
-browse the CVSROOT module.
-
address@hidden
---------------------------------------------------------------------------
address@hidden File Status Information
address@hidden File Status Information
address@hidden File Status Information
-
-In order to serve true information on each file's status (thus length
-of file, timestamps as well as permissions) @sc{cvsfs} needs
-to download this information from the CVS server. However to retrieve
-this, @sc{cvsfs} has to download the whole revision,
-including it's content.
-
-Suppose you request an @code{ls -lR} from the top directory of the
-mapped CVS module. @sc{cvsfs} will need to download all the files to
-provide the information to you, therefore being painfully slow.
-
-There are two possibilities towards omitting that:
-
address@hidden @asis
address@hidden do not request stats unless you need to
-
-This is probably the easiest possibility, however this involves, that
-you probably cannot use graphical file managers like xfm or gmc, as
-those call @code{stat} function automatically. Furthermore you will
-need to take care of @code{ls} tending to do coloured output, which
-will check for executable flags, etc. as well.
-
address@hidden supply @option{--nostats} option to @sc{cvsfs}
-
-If you supply @option{--nostats} option to this translator you will
-never wait for @sc{cvsfs} to download for simply filling stats
-information. However all files will be reported to be zero bytes long,
-have the current time as their timestamps and have only reading
-permissions set.
-
address@hidden has no possibility to figure out whether a particular file
-is executable. Therefore if you want to run an executable from a
-virtually included CVS module you need to omit using
address@hidden
-
address@hidden table
-
-On the whole you should get used to using @option{--nostats} as you
-probably want to just read through one or two files; opposed to using
address@hidden to serve files to compile a source package.
-
address@hidden
---------------------------------------------------------------------------
address@hidden Write Support
address@hidden Write Support
address@hidden Write Support
-
address@hidden by definition is to be a tool, allowing you to hit and view
-a few files out of a huge, nested cvs controlled directory tree. It
-is not the intention to write another @code{cvs} client, allowing to
-check files in.
-
address@hidden commit
-Actually the question is, is there a clever way to allow easier
-check-in than the way common cvs does? The filesystem related
-approach would be to supply a @code{/commit} file somewhere, where you
-need to supply your log-message to. But that seems to be even
-clumpsier than the common @code{ci} command of cvs.
-
address@hidden unionfs
address@hidden shadowfs
-One thing that might be worth considering is to allow creating
-temporary files in the mapped CVS module, thus allowing to ./configure
-and compile within such a directory. However I suppose using
address@hidden, @code{shadowfs} or something similar would make
-more sense. The only
-problem with this is, that @code{unionfs} does not seem to be far
-enough to do that job now.
-
-You might want to consider, that most packages can be configured
-outside the source directory. For example @sc{cvsfs} is able to do so.
-
address@hidden
---------------------------------------------------------------------------
address@hidden Copying This Manual
address@hidden Copying This Manual
-
address@hidden
-* GNU Free Documentation License:: License for copying this manual.
address@hidden menu
-
address@hidden fdl.texi
-
address@hidden
---------------------------------------------------------------------------
address@hidden Index
address@hidden Index
-
address@hidden cp
address@hidden
Index: fdl.texi
===================================================================
RCS file: fdl.texi
diff -N fdl.texi
--- fdl.texi 8 Oct 2004 19:03:33 -0000 1.1
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,452 +0,0 @@
-
address@hidden GNU Free Documentation License
address@hidden GNU Free Documentation License
-
address@hidden FDL, GNU Free Documentation License
address@hidden Version 1.2, November 2002
-
address@hidden
-Copyright @copyright{} 2000,2001,2002 Free Software Foundation, Inc.
-59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
-
-Everyone is permitted to copy and distribute verbatim copies
-of this license document, but changing it is not allowed.
address@hidden display
-
address@hidden 0
address@hidden
-PREAMBLE
-
-The purpose of this License is to make a manual, textbook, or other
-functional and useful document @dfn{free} in the sense of freedom: to
-assure everyone the effective freedom to copy and redistribute it,
-with or without modifying it, either commercially or noncommercially.
-Secondarily, this License preserves for the author and publisher a way
-to get credit for their work, while not being considered responsible
-for modifications made by others.
-
-This License is a kind of ``copyleft'', which means that derivative
-works of the document must themselves be free in the same sense. It
-complements the GNU General Public License, which is a copyleft
-license designed for free software.
-
-We have designed this License in order to use it for manuals for free
-software, because free software needs free documentation: a free
-program should come with manuals providing the same freedoms that the
-software does. But this License is not limited to software manuals;
-it can be used for any textual work, regardless of subject matter or
-whether it is published as a printed book. We recommend this License
-principally for works whose purpose is instruction or reference.
-
address@hidden
-APPLICABILITY AND DEFINITIONS
-
-This License applies to any manual or other work, in any medium, that
-contains a notice placed by the copyright holder saying it can be
-distributed under the terms of this License. Such a notice grants a
-world-wide, royalty-free license, unlimited in duration, to use that
-work under the conditions stated herein. The ``Document'', below,
-refers to any such manual or work. Any member of the public is a
-licensee, and is addressed as ``you''. You accept the license if you
-copy, modify or distribute the work in a way requiring permission
-under copyright law.
-
-A ``Modified Version'' of the Document means any work containing the
-Document or a portion of it, either copied verbatim, or with
-modifications and/or translated into another language.
-
-A ``Secondary Section'' is a named appendix or a front-matter section
-of the Document that deals exclusively with the relationship of the
-publishers or authors of the Document to the Document's overall
-subject (or to related matters) and contains nothing that could fall
-directly within that overall subject. (Thus, if the Document is in
-part a textbook of mathematics, a Secondary Section may not explain
-any mathematics.) The relationship could be a matter of historical
-connection with the subject or with related matters, or of legal,
-commercial, philosophical, ethical or political position regarding
-them.
-
-The ``Invariant Sections'' are certain Secondary Sections whose titles
-are designated, as being those of Invariant Sections, in the notice
-that says that the Document is released under this License. If a
-section does not fit the above definition of Secondary then it is not
-allowed to be designated as Invariant. The Document may contain zero
-Invariant Sections. If the Document does not identify any Invariant
-Sections then there are none.
-
-The ``Cover Texts'' are certain short passages of text that are listed,
-as Front-Cover Texts or Back-Cover Texts, in the notice that says that
-the Document is released under this License. A Front-Cover Text may
-be at most 5 words, and a Back-Cover Text may be at most 25 words.
-
-A ``Transparent'' copy of the Document means a machine-readable copy,
-represented in a format whose specification is available to the
-general public, that is suitable for revising the document
-straightforwardly with generic text editors or (for images composed of
-pixels) generic paint programs or (for drawings) some widely available
-drawing editor, and that is suitable for input to text formatters or
-for automatic translation to a variety of formats suitable for input
-to text formatters. A copy made in an otherwise Transparent file
-format whose markup, or absence of markup, has been arranged to thwart
-or discourage subsequent modification by readers is not Transparent.
-An image format is not Transparent if used for any substantial amount
-of text. A copy that is not ``Transparent'' is called ``Opaque''.
-
-Examples of suitable formats for Transparent copies include plain
address@hidden without markup, Texinfo input format, address@hidden input
-format, @acronym{SGML} or @acronym{XML} using a publicly available
address@hidden, and standard-conforming simple @acronym{HTML},
-PostScript or @acronym{PDF} designed for human modification. Examples
-of transparent image formats include @acronym{PNG}, @acronym{XCF} and
address@hidden Opaque formats include proprietary formats that can be
-read and edited only by proprietary word processors, @acronym{SGML} or
address@hidden for which the @acronym{DTD} and/or processing tools are
-not generally available, and the machine-generated @acronym{HTML},
-PostScript or @acronym{PDF} produced by some word processors for
-output purposes only.
-
-The ``Title Page'' means, for a printed book, the title page itself,
-plus such following pages as are needed to hold, legibly, the material
-this License requires to appear in the title page. For works in
-formats which do not have any title page as such, ``Title Page'' means
-the text near the most prominent appearance of the work's title,
-preceding the beginning of the body of the text.
-
-A section ``Entitled XYZ'' means a named subunit of the Document whose
-title either is precisely XYZ or contains XYZ in parentheses following
-text that translates XYZ in another language. (Here XYZ stands for a
-specific section name mentioned below, such as ``Acknowledgements'',
-``Dedications'', ``Endorsements'', or ``History''.) To ``Preserve the Title''
-of such a section when you modify the Document means that it remains a
-section ``Entitled XYZ'' according to this definition.
-
-The Document may include Warranty Disclaimers next to the notice which
-states that this License applies to the Document. These Warranty
-Disclaimers are considered to be included by reference in this
-License, but only as regards disclaiming warranties: any other
-implication that these Warranty Disclaimers may have is void and has
-no effect on the meaning of this License.
-
address@hidden
-VERBATIM COPYING
-
-You may copy and distribute the Document in any medium, either
-commercially or noncommercially, provided that this License, the
-copyright notices, and the license notice saying this License applies
-to the Document are reproduced in all copies, and that you add no other
-conditions whatsoever to those of this License. You may not use
-technical measures to obstruct or control the reading or further
-copying of the copies you make or distribute. However, you may accept
-compensation in exchange for copies. If you distribute a large enough
-number of copies you must also follow the conditions in section 3.
-
-You may also lend copies, under the same conditions stated above, and
-you may publicly display copies.
-
address@hidden
-COPYING IN QUANTITY
-
-If you publish printed copies (or copies in media that commonly have
-printed covers) of the Document, numbering more than 100, and the
-Document's license notice requires Cover Texts, you must enclose the
-copies in covers that carry, clearly and legibly, all these Cover
-Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on
-the back cover. Both covers must also clearly and legibly identify
-you as the publisher of these copies. The front cover must present
-the full title with all words of the title equally prominent and
-visible. You may add other material on the covers in addition.
-Copying with changes limited to the covers, as long as they preserve
-the title of the Document and satisfy these conditions, can be treated
-as verbatim copying in other respects.
-
-If the required texts for either cover are too voluminous to fit
-legibly, you should put the first ones listed (as many as fit
-reasonably) on the actual cover, and continue the rest onto adjacent
-pages.
-
-If you publish or distribute Opaque copies of the Document numbering
-more than 100, you must either include a machine-readable Transparent
-copy along with each Opaque copy, or state in or with each Opaque copy
-a computer-network location from which the general network-using
-public has access to download using public-standard network protocols
-a complete Transparent copy of the Document, free of added material.
-If you use the latter option, you must take reasonably prudent steps,
-when you begin distribution of Opaque copies in quantity, to ensure
-that this Transparent copy will remain thus accessible at the stated
-location until at least one year after the last time you distribute an
-Opaque copy (directly or through your agents or retailers) of that
-edition to the public.
-
-It is requested, but not required, that you contact the authors of the
-Document well before redistributing any large number of copies, to give
-them a chance to provide you with an updated version of the Document.
-
address@hidden
-MODIFICATIONS
-
-You may copy and distribute a Modified Version of the Document under
-the conditions of sections 2 and 3 above, provided that you release
-the Modified Version under precisely this License, with the Modified
-Version filling the role of the Document, thus licensing distribution
-and modification of the Modified Version to whoever possesses a copy
-of it. In addition, you must do these things in the Modified Version:
-
address@hidden A
address@hidden
-Use in the Title Page (and on the covers, if any) a title distinct
-from that of the Document, and from those of previous versions
-(which should, if there were any, be listed in the History section
-of the Document). You may use the same title as a previous version
-if the original publisher of that version gives permission.
-
address@hidden
-List on the Title Page, as authors, one or more persons or entities
-responsible for authorship of the modifications in the Modified
-Version, together with at least five of the principal authors of the
-Document (all of its principal authors, if it has fewer than five),
-unless they release you from this requirement.
-
address@hidden
-State on the Title page the name of the publisher of the
-Modified Version, as the publisher.
-
address@hidden
-Preserve all the copyright notices of the Document.
-
address@hidden
-Add an appropriate copyright notice for your modifications
-adjacent to the other copyright notices.
-
address@hidden
-Include, immediately after the copyright notices, a license notice
-giving the public permission to use the Modified Version under the
-terms of this License, in the form shown in the Addendum below.
-
address@hidden
-Preserve in that license notice the full lists of Invariant Sections
-and required Cover Texts given in the Document's license notice.
-
address@hidden
-Include an unaltered copy of this License.
-
address@hidden
-Preserve the section Entitled ``History'', Preserve its Title, and add
-to it an item stating at least the title, year, new authors, and
-publisher of the Modified Version as given on the Title Page. If
-there is no section Entitled ``History'' in the Document, create one
-stating the title, year, authors, and publisher of the Document as
-given on its Title Page, then add an item describing the Modified
-Version as stated in the previous sentence.
-
address@hidden
-Preserve the network location, if any, given in the Document for
-public access to a Transparent copy of the Document, and likewise
-the network locations given in the Document for previous versions
-it was based on. These may be placed in the ``History'' section.
-You may omit a network location for a work that was published at
-least four years before the Document itself, or if the original
-publisher of the version it refers to gives permission.
-
address@hidden
-For any section Entitled ``Acknowledgements'' or ``Dedications'', Preserve
-the Title of the section, and preserve in the section all the
-substance and tone of each of the contributor acknowledgements and/or
-dedications given therein.
-
address@hidden
-Preserve all the Invariant Sections of the Document,
-unaltered in their text and in their titles. Section numbers
-or the equivalent are not considered part of the section titles.
-
address@hidden
-Delete any section Entitled ``Endorsements''. Such a section
-may not be included in the Modified Version.
-
address@hidden
-Do not retitle any existing section to be Entitled ``Endorsements'' or
-to conflict in title with any Invariant Section.
-
address@hidden
-Preserve any Warranty Disclaimers.
address@hidden enumerate
-
-If the Modified Version includes new front-matter sections or
-appendices that qualify as Secondary Sections and contain no material
-copied from the Document, you may at your option designate some or all
-of these sections as invariant. To do this, add their titles to the
-list of Invariant Sections in the Modified Version's license notice.
-These titles must be distinct from any other section titles.
-
-You may add a section Entitled ``Endorsements'', provided it contains
-nothing but endorsements of your Modified Version by various
-parties---for example, statements of peer review or that the text has
-been approved by an organization as the authoritative definition of a
-standard.
-
-You may add a passage of up to five words as a Front-Cover Text, and a
-passage of up to 25 words as a Back-Cover Text, to the end of the list
-of Cover Texts in the Modified Version. Only one passage of
-Front-Cover Text and one of Back-Cover Text may be added by (or
-through arrangements made by) any one entity. If the Document already
-includes a cover text for the same cover, previously added by you or
-by arrangement made by the same entity you are acting on behalf of,
-you may not add another; but you may replace the old one, on explicit
-permission from the previous publisher that added the old one.
-
-The author(s) and publisher(s) of the Document do not by this License
-give permission to use their names for publicity for or to assert or
-imply endorsement of any Modified Version.
-
address@hidden
-COMBINING DOCUMENTS
-
-You may combine the Document with other documents released under this
-License, under the terms defined in section 4 above for modified
-versions, provided that you include in the combination all of the
-Invariant Sections of all of the original documents, unmodified, and
-list them all as Invariant Sections of your combined work in its
-license notice, and that you preserve all their Warranty Disclaimers.
-
-The combined work need only contain one copy of this License, and
-multiple identical Invariant Sections may be replaced with a single
-copy. If there are multiple Invariant Sections with the same name but
-different contents, make the title of each such section unique by
-adding at the end of it, in parentheses, the name of the original
-author or publisher of that section if known, or else a unique number.
-Make the same adjustment to the section titles in the list of
-Invariant Sections in the license notice of the combined work.
-
-In the combination, you must combine any sections Entitled ``History''
-in the various original documents, forming one section Entitled
-``History''; likewise combine any sections Entitled ``Acknowledgements'',
-and any sections Entitled ``Dedications''. You must delete all
-sections Entitled ``Endorsements.''
-
address@hidden
-COLLECTIONS OF DOCUMENTS
-
-You may make a collection consisting of the Document and other documents
-released under this License, and replace the individual copies of this
-License in the various documents with a single copy that is included in
-the collection, provided that you follow the rules of this License for
-verbatim copying of each of the documents in all other respects.
-
-You may extract a single document from such a collection, and distribute
-it individually under this License, provided you insert a copy of this
-License into the extracted document, and follow this License in all
-other respects regarding verbatim copying of that document.
-
address@hidden
-AGGREGATION WITH INDEPENDENT WORKS
-
-A compilation of the Document or its derivatives with other separate
-and independent documents or works, in or on a volume of a storage or
-distribution medium, is called an ``aggregate'' if the copyright
-resulting from the compilation is not used to limit the legal rights
-of the compilation's users beyond what the individual works permit.
-When the Document is included in an aggregate, this License does not
-apply to the other works in the aggregate which are not themselves
-derivative works of the Document.
-
-If the Cover Text requirement of section 3 is applicable to these
-copies of the Document, then if the Document is less than one half of
-the entire aggregate, the Document's Cover Texts may be placed on
-covers that bracket the Document within the aggregate, or the
-electronic equivalent of covers if the Document is in electronic form.
-Otherwise they must appear on printed covers that bracket the whole
-aggregate.
-
address@hidden
-TRANSLATION
-
-Translation is considered a kind of modification, so you may
-distribute translations of the Document under the terms of section 4.
-Replacing Invariant Sections with translations requires special
-permission from their copyright holders, but you may include
-translations of some or all Invariant Sections in addition to the
-original versions of these Invariant Sections. You may include a
-translation of this License, and all the license notices in the
-Document, and any Warranty Disclaimers, provided that you also include
-the original English version of this License and the original versions
-of those notices and disclaimers. In case of a disagreement between
-the translation and the original version of this License or a notice
-or disclaimer, the original version will prevail.
-
-If a section in the Document is Entitled ``Acknowledgements'',
-``Dedications'', or ``History'', the requirement (section 4) to Preserve
-its Title (section 1) will typically require changing the actual
-title.
-
address@hidden
-TERMINATION
-
-You may not copy, modify, sublicense, or distribute the Document except
-as expressly provided for under this License. Any other attempt to
-copy, modify, sublicense or distribute the Document 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.
-
address@hidden
-FUTURE REVISIONS OF THIS LICENSE
-
-The Free Software Foundation may publish new, revised versions
-of the GNU Free Documentation 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. See
address@hidden://www.gnu.org/copyleft/}.
-
-Each version of the License is given a distinguishing version number.
-If the Document specifies that a particular numbered version of this
-License ``or any later version'' applies to it, you have the option of
-following the terms and conditions either of that specified version or
-of any later version that has been published (not as a draft) by the
-Free Software Foundation. If the Document does not specify a version
-number of this License, you may choose any version ever published (not
-as a draft) by the Free Software Foundation.
address@hidden enumerate
-
address@hidden
address@hidden ADDENDUM: How to use this License for your documents
-
-To use this License in a document you have written, include a copy of
-the License in the document and put the following copyright and
-license notices just after the title page:
-
address@hidden
address@hidden
- Copyright (C) @var{year} @var{your name}.
- Permission is granted to copy, distribute and/or modify this document
- under the terms of the GNU Free Documentation License, Version 1.2
- or any later version published by the Free Software Foundation;
- with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
- Texts. A copy of the license is included in the section entitled ``GNU
- Free Documentation License''.
address@hidden group
address@hidden smallexample
-
-If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts,
-replace the ``with...Texts.'' line with this:
-
address@hidden
address@hidden
- with the Invariant Sections being @var{list their titles}, with
- the Front-Cover Texts being @var{list}, and with the Back-Cover Texts
- being @var{list}.
address@hidden group
address@hidden smallexample
-
-If you have Invariant Sections without Cover Texts, or some other
-combination of the three, merge those two alternatives to suit the
-situation.
-
-If your document contains nontrivial examples of program code, we
-recommend releasing these examples in parallel under your choice of
-free software license, such as the GNU General Public License,
-to permit their use in free software.
-
address@hidden Local Variables:
address@hidden ispell-local-pdict: "ispell-dict"
address@hidden End:
-
Index: netfs.c
===================================================================
RCS file: netfs.c
diff -N netfs.c
--- netfs.c 15 Oct 2007 22:08:56 -0000 1.19
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,777 +0,0 @@
-/**********************************************************
- * netfs.c
- *
- * Copyright (C) 2004, 2005, 2007 by Stefan Siegl <address@hidden>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Publice License,
- * version 2 or any later. The license is contained in the COPYING
- * file that comes with the cvsfs distribution.
- *
- * callback functions for libnetfs
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include <stddef.h>
-#include <stdlib.h>
-#include <dirent.h>
-#include <string.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <sys/mman.h>
-
-#include <hurd/netfs.h>
-
-#include <stdio.h>
-
-#include "cvsfs.h"
-#include "cvs_files.h"
-#include "node.h"
-#include "cvs_connect.h"
-
-
-
-/* Make sure that NP->nn_stat is filled with current information. CRED
- identifies the user responsible for the operation. */
-error_t
-netfs_validate_stat (struct node *node, struct iouser *cred)
-{
- (void) cred;
-
- FUNC_PROLOGUE_NODE("netfs_validate_stat", node);
-
- if(! config.nostats
- && node->nn->revision && node->nn->parent)
- {
- if(! node->nn->revision->contents)
- {
- /* head revision not available locally yet, retrieve it ... */
- rwlock_writer_lock(&node->nn->revision->lock);
- cvs_files_cache(node->nn, node->nn->revision);
- rwlock_writer_unlock(&node->nn->revision->lock);
- }
-
- if(node->nn->revision->contents)
- {
- node->nn_stat.st_mode = (node->nn->revision->perm | S_IFREG)
- &~(S_IWUSR | S_IWGRP | S_IWOTH);
- node->nn_stat.st_size = node->nn->revision->length;
- node->nn_stat.st_blocks = (node->nn_stat.st_size >> 9) + 1;
-
- node->nn_stat.st_mtim.tv_sec = node->nn->revision->time;
- node->nn_stat.st_ctim.tv_sec = node->nn->revision->time;
-
- node->nn_stat.st_mtim.tv_nsec = 0;
- node->nn_stat.st_ctim.tv_nsec = 0;
- }
- }
-
- FUNC_EPILOGUE(0);
-}
-
-
-
-/* Read the contents of NODE (a symlink), for USER, into BUF. */
-error_t netfs_attempt_readlink (struct iouser *user, struct node *node,
- char *buf)
-{
- (void) user;
- (void) buf;
-
- FUNC_PROLOGUE_NODE("netfs_attempt_readlink", node);
-
- /* actually we don't have no symlinks in cvsfs, at least not for
- * the time being
- */
-
- FUNC_EPILOGUE(EINVAL);
-}
-
-
-
-/* Attempt to create a file named NAME in DIR for USER with MODE. Set *NODE
- to the new node upon return. On any error, clear *NODE. *NODE should be
- locked on success; no matter what, unlock DIR before returning. */
-error_t
-netfs_attempt_create_file (struct iouser *user, struct node *dir,
- char *name, mode_t mode, struct node **node)
-{
- (void) user;
- (void) mode;
-
- FUNC_PROLOGUE_FMT("netfs_attempt_create_file", "name=%s", name);
-
- *node = 0;
- mutex_unlock (&dir->lock);
-
- FUNC_EPILOGUE(EROFS);
-}
-
-
-
-/* This should attempt a chmod call for the user specified by CRED on node
- NODE, to change the owner to UID and the group to GID. */
-error_t netfs_attempt_chown (struct iouser *cred, struct node *node,
- uid_t uid, uid_t gid)
-{
- (void) cred;
- (void) uid;
- (void) gid;
-
- FUNC_PROLOGUE_NODE("netfs_attempt_chown", node);
- FUNC_EPILOGUE(EROFS);
-}
-
-
-
-/* This should attempt to fetch filesystem status information for the remote
- filesystem, for the user CRED. */
-error_t
-netfs_attempt_statfs (struct iouser *cred, struct node *node,
- fsys_statfsbuf_t *st)
-{
- (void) cred;
- (void) st;
-
- FUNC_PROLOGUE_NODE("netfs_attempt_statfs", node);
- FUNC_EPILOGUE(EOPNOTSUPP);
-}
-
-
-
-/* Attempt to create a new directory named NAME in DIR for USER with mode
- MODE. */
-error_t netfs_attempt_mkdir (struct iouser *user, struct node *dir,
- char *name, mode_t mode)
-{
- (void) user;
- (void) dir;
- (void) mode;
-
- FUNC_PROLOGUE_FMT("netfs_attempt_mkdir", "name=%s", name);
- FUNC_EPILOGUE(EROFS);
-}
-
-
-
-/* This should attempt a chflags call for the user specified by CRED on node
- NODE, to change the flags to FLAGS. */
-error_t netfs_attempt_chflags (struct iouser *cred, struct node *node,
- int flags)
-{
- (void) cred;
- (void) flags;
-
- FUNC_PROLOGUE_NODE("netfs_attempt_chflags", node);
- FUNC_EPILOGUE(EROFS);
-}
-
-
-
-/* Node NODE is being opened by USER, with FLAGS. NEWNODE is nonzero if we
- just created this node. Return an error if we should not permit the open
- to complete because of a permission restriction. */
-error_t
-netfs_check_open_permissions (struct iouser *user, struct node *node,
- int flags, int newnode)
-{
- (void) newnode;
-
- FUNC_PROLOGUE_NODE("netfs_check_open_permissions", node);
- error_t err = 0;
-
- if (flags & O_READ)
- err = fshelp_access (&node->nn_stat, S_IREAD, user);
-
- if (!err && (flags & O_WRITE))
- err = fshelp_access (&node->nn_stat, S_IWRITE, user);
-
- if (!err && (flags & O_EXEC))
- err = fshelp_access (&node->nn_stat, S_IEXEC, user);
-
- FUNC_EPILOGUE(err);
-}
-
-
-
-/* This should attempt a chmod call for the user specified by CRED on node
- NODE, to change the mode to MODE. Unlike the normal Unix and Hurd meaning
- of chmod, this function is also used to attempt to change files into other
- types. If such a transition is attempted which is impossible, then return
- EOPNOTSUPP. */
-error_t netfs_attempt_chmod (struct iouser *cred, struct node *node,
- mode_t mode)
-{
- (void) cred;
- (void) mode;
-
- FUNC_PROLOGUE_NODE("netfs_attempt_chmod", node);
- FUNC_EPILOGUE(EROFS);
-}
-
-
-
-/* Attempt to create an anonymous file related to DIR for USER with MODE.
- Set *NODE to the returned file upon success. No matter what, unlock DIR. */
-error_t netfs_attempt_mkfile (struct iouser *user, struct node *dir,
- mode_t mode, struct node **node)
-{
- (void) user;
- (void) mode;
-
- FUNC_PROLOGUE("netfs_attempt_mkfile");
-
- *node = 0;
- mutex_unlock (&dir->lock);
-
- FUNC_EPILOGUE(EROFS);
-}
-
-
-
-/* This should sync the entire remote filesystem. If WAIT is set, return
- only after sync is completely finished. */
-error_t netfs_attempt_syncfs (struct iouser *cred, int wait)
-{
- (void) cred;
- (void) wait;
-
- FUNC_PROLOGUE("netfs_attempt_syncfs");
-
- /* we don't support writing */
- FUNC_EPILOGUE(0);
-}
-
-
-
-/* This should sync the file NODE completely to disk, for the user CRED. If
- WAIT is set, return only after sync is completely finished. */
-error_t
-netfs_attempt_sync (struct iouser *cred, struct node *node, int wait)
-{
- (void) cred;
- (void) wait;
-
- FUNC_PROLOGUE_NODE("netfs_attempt_sync", node);
-
- /* we don't support writing to files, therefore syncing isn't really
- * much to worry about ...
- */
- FUNC_EPILOGUE(0);
-}
-
-
-
-/* Delete NAME in DIR for USER. */
-error_t netfs_attempt_unlink (struct iouser *user, struct node *dir,
- char *name)
-{
- (void) user;
-
- FUNC_PROLOGUE_FMT("netfs_attempt_unlink", "dir=%s, name=%s",
- dir->nn->name, name);
- FUNC_EPILOGUE(EROFS);
-}
-
-
-
-/* This should attempt to set the size of the file NODE (for user CRED) to
- SIZE bytes long. */
-error_t netfs_attempt_set_size (struct iouser *cred, struct node *node,
- loff_t size)
-{
- (void) cred;
- (void) size;
-
- FUNC_PROLOGUE_NODE("netfs_attempt_set_size", node);
- FUNC_EPILOGUE(EOPNOTSUPP);
-}
-
-
-
-/* Attempt to turn NODE (user CRED) into a device. TYPE is either S_IFBLK or
- S_IFCHR. */
-error_t netfs_attempt_mkdev (struct iouser *cred, struct node *node,
- mode_t type, dev_t indexes)
-{
- (void) cred;
- (void) type;
- (void) indexes;
-
- FUNC_PROLOGUE_NODE("netfs_attempt_mkdev", node);
- FUNC_EPILOGUE(EROFS);
-}
-
-
-
-/* Return the valid access types (bitwise OR of O_READ, O_WRITE, and O_EXEC)
- in *TYPES for file NODE and user CRED. */
-error_t
-netfs_report_access (struct iouser *cred, struct node *node, int *types)
-{
- FUNC_PROLOGUE_NODE("netfs_report_access", node);
- *types = 0;
-
- if (fshelp_access (&node->nn_stat, S_IREAD, cred) == 0)
- *types |= O_READ;
-
- /* we don't support writing to files, therefore don't even think of
- * returning writable ...
- *
- * if (fshelp_access (&node->nn_stat, S_IWRITE, cred) == 0)
- * *types |= O_WRITE;
- */
-
- if (fshelp_access (&node->nn_stat, S_IEXEC, cred) == 0)
- *types |= O_EXEC;
-
- FUNC_EPILOGUE_FMT(0, "types=%d", *types);
-}
-
-
-
-/* Lookup NAME in DIR for USER; set *NODE to the found name upon return. If
- the name was not found, then return ENOENT. On any error, clear *NODE.
- (*NODE, if found, should be locked, this call should unlock DIR no matter
- what.) */
-error_t netfs_attempt_lookup (struct iouser *user, struct node *dir,
- char *name, struct node **node)
-{
- (void) user;
-
- FUNC_PROLOGUE_FMT("netfs_attempt_lookup", "dir=%s, name=%s",
- dir->nn->name, name);
- error_t err = ENOENT;
- struct netnode *nn;
-
- if(! strcmp(name, "."))
- {
- /* lookup for a directory, just return another reference to
- * our cwd 'dir'
- */
- netfs_nref(dir);
-
- *node = dir;
- err = 0;
- }
- else if(! strcmp(name, ".."))
- {
- if(dir->nn->parent)
- {
- /* return a reference to our parent */
- *node = cvsfs_make_node(dir->nn->parent);
- err = 0;
- }
- else
- /* this is the root directory of cvsfs, but the user
- * requests to go up by one. we can't tell, where to go, so ...
- */
- err = EAGAIN;
- }
- else if(dir->nn->revision)
- {
- struct revision *rev;
- struct netnode *nn = dir->nn->parent ? dir->nn : dir->nn->child;
-
- /* read-lock the real netnode - not the virtual one - what wouldn't
- * make much sense.
- */
- rwlock_reader_lock(&nn->lock);
- rev = dir->nn->revision;
-
- for(; rev; rev = rev->next)
- if(! strcmp(rev->id, name))
- break;
-
- rwlock_reader_unlock(&nn->lock);
-
- if(! rev && (rev = malloc(sizeof(*rev))))
- {
- /* okay, we don't have this particular revision available;
- * create a new revision structure and try retrieving it
- */
- rev->id = strdup(name);
- rev->contents = NULL;
- rev->next = NULL;
- rwlock_init(&rev->lock);
-
- if(cvs_files_hit(nn, rev))
- {
- /* unable to hit wanted revision. */
- free(rev->id);
- free(rev);
- rev = NULL;
- }
- else
- {
- /* okay, went well, enqueue into revisions chain */
- rwlock_writer_lock(&nn->lock);
-
- rev->next = nn->revision->next;
- nn->revision->next = rev;
-
- rwlock_writer_unlock(&nn->lock);
- }
- }
-
- if(rev)
- {
- /* cool, we've got that revision! */
- *node = cvsfs_make_virtual_node(nn, rev);
- err = 0;
- }
- }
- else
- {
- for(nn = dir->nn->child; nn; nn = nn->sibling)
- if(! strcmp(nn->name, name))
- {
- err = 0; /* hey, we got it! */
-
- spin_lock(&netfs_node_refcnt_lock);
- /* rwlock_reader_lock(&nn->lock);
- * we don't have to lock nn->lock since it's ref cannot become
- * invalid as we hold netfs_node_refcnt_lock
- */
-
- if((*node = nn->node))
- (*node)->references ++;
-
- spin_unlock(&netfs_node_refcnt_lock);
- /* rwlock_reader_unlock(&nn->lock); */
-
- if(! *node)
- *node = cvsfs_make_node(nn);
-
- break;
- }
- }
-
- if(! err)
- fshelp_touch(&(*node)->nn_stat, TOUCH_ATIME, cvsfs_maptime);
-
- mutex_unlock(&dir->lock);
-
- if(err)
- *node = NULL;
- else
- mutex_lock(&(*node)->lock);
-
- FUNC_EPILOGUE(err);
-}
-
-
-
-/* Create a link in DIR with name NAME to FILE for USER. Note that neither
- DIR nor FILE are locked. If EXCL is set, do not delete the target, but
- return EEXIST if NAME is already found in DIR. */
-error_t netfs_attempt_link (struct iouser *user, struct node *dir,
- struct node *file, char *name, int excl)
-{
- (void) user;
- (void) dir;
- (void) name;
- (void) excl;
-
- FUNC_PROLOGUE_NODE("netfs_attempt_link", file);
- FUNC_EPILOGUE(EROFS);
-}
-
-
-
-/* Attempt to remove directory named NAME in DIR for USER. */
-error_t netfs_attempt_rmdir (struct iouser *user,
- struct node *dir, char *name)
-{
- (void) user;
-
- FUNC_PROLOGUE_FMT("netfs_attempt_rmdir", "dir=%s, name=%s",
- dir->nn->name, name);
- FUNC_EPILOGUE(EROFS);
-}
-
-
-
-/* This should attempt a chauthor call for the user specified by CRED on node
- NODE, to change the author to AUTHOR. */
-error_t netfs_attempt_chauthor (struct iouser *cred, struct node *node,
- uid_t author)
-{
- (void) cred;
- (void) author;
-
- FUNC_PROLOGUE_NODE("netfs_attempt_chauthor", node);
- FUNC_EPILOGUE(EROFS);
-}
-
-
-
-/* Attempt to turn NODE (user CRED) into a symlink with target NAME. */
-error_t netfs_attempt_mksymlink (struct iouser *cred, struct node *node,
- char *name)
-{
- (void) cred;
- (void) name;
-
- FUNC_PROLOGUE_NODE("netfs_attempt_mksymlink", node);
- FUNC_EPILOGUE(EROFS);
-}
-
-
-
-/* Note that in this one call, neither of the specific nodes are locked. */
-error_t netfs_attempt_rename (struct iouser *user, struct node *fromdir,
- char *fromname, struct node *todir,
- char *toname, int excl)
-{
- (void) user;
- (void) fromdir;
- (void) fromname;
- (void) todir;
- (void) toname;
- (void) excl;
-
- FUNC_PROLOGUE("netfs_attempt_rename");
- FUNC_EPILOGUE(EROFS);
-}
-
-
-
-/* Write to the file NODE for user CRED starting at OFSET and continuing for up
- to *LEN bytes from DATA. Set *LEN to the amount seccessfully written upon
- return. */
-error_t netfs_attempt_write (struct iouser *cred, struct node *node,
- loff_t offset, size_t *len, void *data)
-{
- (void) cred;
- (void) offset;
- (void) len;
- (void) data;
-
- FUNC_PROLOGUE_NODE("netfs_attempt_write", node);
- FUNC_EPILOGUE(EROFS);
-}
-
-
-
-/* This should attempt a utimes call for the user specified by CRED on node
- NODE, to change the atime to ATIME and the mtime to MTIME. */
-error_t
-netfs_attempt_utimes (struct iouser *cred, struct node *node,
- struct timespec *atime, struct timespec *mtime)
-{
- (void) cred;
-
- FUNC_PROLOGUE_NODE("netfs_attempt_utimes", node);
- error_t err = fshelp_isowner (&node->nn_stat, cred);
- int flags = TOUCH_CTIME;
-
- if (! err)
- {
- if (mtime)
- {
- node->nn_stat.st_mtim.tv_sec = mtime->tv_sec;
- node->nn_stat.st_mtim.tv_nsec = mtime->tv_nsec;
- }
- else
- flags |= TOUCH_MTIME;
-
- if (atime)
- {
- node->nn_stat.st_atim.tv_sec = atime->tv_sec;
- node->nn_stat.st_atim.tv_nsec = atime->tv_nsec;
- }
- else
- flags |= TOUCH_ATIME;
-
- fshelp_touch (&node->nn_stat, flags, cvsfs_maptime);
- }
-
- FUNC_EPILOGUE(err);
-}
-
-
-
-/* Read from the file NODE for user CRED starting at OFFSET and continuing for
- up to *LEN bytes. Put the data at DATA. Set *LEN to the amount
- successfully read upon return. */
-error_t netfs_attempt_read (struct iouser *cred, struct node *node,
- loff_t offset, size_t *len, void *data)
-{
- (void) cred;
-
- FUNC_PROLOGUE_NODE("netfs_attempt_read", node);
- int maxlen;
-
- if(! node->nn->revision)
- {
- fprintf(stderr, "netfs_attempt_read entered, for something not "
- "being a CVS revision controlled file. getting outta here.\n");
- return EISDIR;
- }
-
- rwlock_reader_lock(&node->nn->lock);
- rwlock_reader_lock(&node->nn->revision->lock);
-
- if(! node->nn->revision->contents)
- {
- /* we don't have the content of this revision cached locally,
- * therefore try to fetch it.
- *
- * TODO: consider whether it's possible (if using non-blocking I/O)
- * to fork a retrieval task, and return 0 bytes for the time being ..
- */
-
- /* oops, we need a writer lock ... */
- rwlock_reader_unlock(&node->nn->revision->lock);
- rwlock_writer_lock(&node->nn->revision->lock);
-
- if(cvs_files_cache(node->nn->parent ? node->nn : node->nn->child,
- node->nn->revision))
- {
- rwlock_writer_unlock(&node->nn->revision->lock);
- rwlock_reader_unlock(&node->nn->lock);
- *len = 0;
- return EIO;
- }
-
- /* TODO consider whether there's a nicer way, so that we don't have
- * to relock two times
- */
- rwlock_writer_unlock(&node->nn->revision->lock);
- rwlock_reader_lock(&node->nn->revision->lock);
- }
-
- maxlen = node->nn->revision->length;
-
- if(offset >= maxlen)
- {
- /* trying to read beyond of file, cowardly refuse to do so ... */
- *len = 0;
- rwlock_reader_unlock(&node->nn->revision->lock);
- rwlock_reader_unlock(&node->nn->lock);
- return 0;
- }
-
- if(*len + offset >= maxlen)
- *len = maxlen - offset;
-
- memcpy(data, node->nn->revision->contents + offset, *len);
- rwlock_reader_unlock(&node->nn->revision->lock);
- rwlock_reader_unlock(&node->nn->lock);
-
- FUNC_EPILOGUE(0);
-}
-
-
-
-/* Returned directory entries are aligned to blocks this many bytes long.
- Must be a power of two. */
-#define DIRENT_ALIGN 4
-#define DIRENT_NAME_OFFS offsetof (struct dirent, d_name)
-
-/* Length is structure before the name + the name + '\0', all
- padded to a four-byte alignment. */
-#define DIRENT_LEN(name_len) \
- ((DIRENT_NAME_OFFS + (name_len) + 1 + (DIRENT_ALIGN - 1)) \
- & ~(DIRENT_ALIGN - 1))
-
-error_t
-netfs_get_dirents (struct iouser *cred, struct node *dir,
- int first_entry, int num_entries, char **data,
- mach_msg_type_number_t *data_len,
- vm_size_t max_data_len, int *data_entries)
-{
- (void) cred;
- (void) max_data_len;
-
- FUNC_PROLOGUE_NODE("netfs_get_dirents", dir);
- error_t err = 0;
- int count = 0;
- struct netnode *first_nn, *nn;
-
- if(dir->nn->revision)
- return ENOTDIR; /* it's a file ... */
-
- /* find the first entry, we shall write out to the user ... */
- for(first_nn = dir->nn->child, count = 2;
- first_nn && first_entry > count;
- first_nn = first_nn->sibling, count ++);
-
- size_t size = 0;
- char *p = *data;
- count = 0;
-
- int add_dir_entry (const char *name, ino_t fileno, int type)
- {
- if (num_entries == -1 || count < num_entries)
- {
- struct dirent hdr;
- size_t name_len = strlen (name);
- size_t sz = DIRENT_LEN (name_len);
-
- if (sz + size > *data_len)
- return 0;
- else
- size += sz;
-
- hdr.d_fileno = fileno;
- hdr.d_reclen = sz;
- hdr.d_type = type;
- hdr.d_namlen = name_len;
-
- memcpy (p, &hdr, DIRENT_NAME_OFFS);
- strcpy (p + DIRENT_NAME_OFFS, name);
- p += sz;
-
- count++;
-
- return 1;
- }
- else
- return 0;
- }
-
- /* Add `.' and `..' entries. */
- if (first_entry == 0)
- add_dir_entry (".", 2, DT_DIR);
- if (first_entry <= 1)
- add_dir_entry ("..", 2, DT_DIR);
-
- /* okay, now tell about the real entries ... */
- for(nn = first_nn; nn; nn = nn->sibling)
- if(! add_dir_entry(nn->name, nn->fileno,
- nn->revision ? DT_REG : DT_DIR))
- break;
-
- *data_len = size;
- *data_entries = count;
-
- fshelp_touch (&dir->nn_stat, TOUCH_ATIME, cvsfs_maptime);
- FUNC_EPILOGUE_FMT(err, "wrote %d entries to %d bytes.", count, size);
-}
-
-
-
-/* Node NP is all done; free all its associated storage. */
-void
-netfs_node_norefs (struct node *node)
-{
- FUNC_PROLOGUE_NODE("netfs_node_norefs", node);
-
- /* the node will be freed, therefore our nn->node pointer will not
- * be valid any longer, therefore reset it
- */
- rwlock_writer_lock(&node->nn->lock);
- node->nn->node = NULL;
- rwlock_writer_unlock(&node->nn->lock);
-
- if(node->nn->revision && !node->nn->parent)
- /* node is a virtual node, therefore we need to free the netnode */
- free(node->nn);
-
- FUNC_EPILOGUE_NORET();
-}
Index: node.c
===================================================================
RCS file: node.c
diff -N node.c
--- node.c 15 Oct 2007 22:08:56 -0000 1.10
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,173 +0,0 @@
-/**********************************************************
- * node.c
- *
- * Copyright 2004, 2007, Stefan Siegl <address@hidden>, Germany
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Publice License,
- * version 2 or any later. The license is contained in the COPYING
- * file that comes with the cvsfs distribution.
- *
- * code related to handling (aka create, etc.) netfs nodes
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include "cvsfs.h"
-#include "node.h"
-
-#include <hurd/netfs.h>
-#include <assert.h>
-#include <stdio.h>
-
-/* next file number (aka inode) we will assign */
-extern volatile unsigned int next_fileno;
-
-
-/* cvsfs_make_node
- *
- * create a struct node* for the specified netnode 'nn'.
- */
-struct node *
-cvsfs_make_node(struct netnode *nn)
-{
- struct node *node;
-
- rwlock_writer_lock(&nn->lock);
-
- if(nn->node)
- {
- /* there already is a node structure, just return another reference
- * to this one, instead of wasting memory for yet another one
- */
- mutex_lock(&nn->node->lock);
- netfs_nref(nn->node);
- mutex_unlock(&nn->node->lock);
-
- rwlock_writer_unlock(&nn->lock);
- return nn->node;
- }
-
- if(! (node = netfs_make_node(nn)))
- {
- rwlock_writer_unlock(&nn->lock);
- return NULL;
- }
-
- /* put timestamp on file */
- fshelp_touch(&node->nn_stat,
- TOUCH_ATIME | TOUCH_MTIME | TOUCH_CTIME, cvsfs_maptime);
-
- /* initialize stats of new node ... */
- node->nn_stat.st_fstype = FSTYPE_MISC;
- node->nn_stat.st_fsid = stat_template.fsid;
- node->nn_stat.st_ino = nn->fileno;
- node->nn_stat.st_mode = stat_template.mode;
- node->nn_stat.st_nlink = 1;
- node->nn_stat.st_uid = stat_template.uid;
- node->nn_stat.st_gid = stat_template.gid;
- node->nn_stat.st_size = 0;
- node->nn_stat.st_blksize = 4096; /* is there a better default?? */
- node->nn_stat.st_blocks = 0;
- node->nn_stat.st_author = stat_template.author;
-
- if(! nn->revision)
- {
- /* we're creating a node for a directory, mark as such! */
- node->nn_stat.st_mode |= S_IFDIR;
-
- /* since we got a directory we need to supply "executable"
- * permissions, so our user is enabled to make use of this dir
- */
- if(node->nn_stat.st_mode & S_IRUSR)
- node->nn_stat.st_mode |= S_IXUSR;
-
- if(node->nn_stat.st_mode & S_IRGRP)
- node->nn_stat.st_mode |= S_IXGRP;
-
- if(node->nn_stat.st_mode & S_IROTH)
- node->nn_stat.st_mode |= S_IXOTH;
- }
- else
- {
- if(nn->revision->contents
- && ! config.nostats)
- {
- node->nn_stat.st_mode = nn->revision->perm;
- node->nn_stat.st_size = nn->revision->length;
- node->nn_stat.st_blocks = (node->nn_stat.st_size >> 9) + 1;
-
- node->nn_stat.st_atim.tv_sec = nn->revision->time;
- node->nn_stat.st_mtim.tv_sec = nn->revision->time;
- node->nn_stat.st_ctim.tv_sec = nn->revision->time;
-
- node->nn_stat.st_atim.tv_nsec = 0;
- node->nn_stat.st_mtim.tv_nsec = 0;
- node->nn_stat.st_ctim.tv_nsec = 0;
- }
-
- /* well, we're creating a new node for a file ... */
- node->nn_stat.st_mode |= S_IFREG;
-
- /* for now simply drop all execute permissions, this needs to be fixed,
- * since CVS support executables, e.g. shell scripts, that we need to
- * support .... FIXME
- */
- node->nn_stat.st_mode &= ~(S_IXUSR | S_IXGRP | S_IXOTH);
- }
-
- /* cvsfs is currently read only, check-ins etc. aren't yet supported,
- * therefore drop permission to write
- */
- node->nn_stat.st_mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH);
-
- nn->node = node;
- rwlock_writer_unlock(&nn->lock);
-
- return node;
-}
-
-
-
-struct node *
-cvsfs_make_virtual_node(struct netnode *nn, struct revision *rev)
-{
- struct node *node;
- struct netnode *new_nn;
-
- if(! nn->revision)
- return NULL; /* we don't create virtual nodes for directories */
-
- /* we need a virtual netnode structure, pointing to the revision
- * of choice ...
- */
- new_nn = malloc(sizeof(*new_nn));
-
- if(! new_nn)
- return NULL;
-
- rwlock_init(&new_nn->lock);
-
- new_nn->sibling = NULL;
- new_nn->parent = NULL;
- new_nn->node = NULL; /* will be assigned by cvsfs_make_node */
- new_nn->name = rev->id;
- new_nn->revision = rev;
- new_nn->fileno = next_fileno ++;
-
- /* keep a pointer to the real nn structure in new_nn->child
- * this is needed if we want to retrieve a version controlled file, since
- * we got to climb up the whole path then ...
- */
- new_nn->child = nn;
-
- if(! (node = cvsfs_make_node(new_nn)))
- {
- free(new_nn);
- return NULL;
- }
-
- return node;
-}
Index: node.h
===================================================================
RCS file: node.h
diff -N node.h
--- node.h 16 Nov 2005 21:18:08 -0000 1.3
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,26 +0,0 @@
-/**********************************************************
- * node.h
- *
- * Copyright 2004, Stefan Siegl <address@hidden>, Germany
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Publice License,
- * version 2 or any later. The license is contained in the COPYING
- * file that comes with the cvsfs distribution.
- *
- * code related to handling (aka create, etc.) netfs nodes
- */
-
-#ifndef NODE_H
-#define NODE_H
-
-/* create a struct node* for the specified netnode 'nn'. */
-struct node *cvsfs_make_node(struct netnode *);
-
-/* create a "virtual" struct node* for the specified netnode, which must
- * represent a version controlled file. Call with revision == NULL to
- * create some kind of parent directory.
- */
-struct node *cvsfs_make_virtual_node(struct netnode *, struct revision *);
-
-#endif /* NODE_H */
Index: tcpip.c
===================================================================
RCS file: tcpip.c
diff -N tcpip.c
--- tcpip.c 16 Nov 2005 21:18:08 -0000 1.3
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,91 +0,0 @@
-/**********************************************************
- * tcpip.c
- *
- * Copyright 2004, Stefan Siegl <address@hidden>, Germany
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Publice License,
- * version 2 or any later. The license is contained in the COPYING
- * file that comes with the cvsfs distribution.
- *
- * speak tcp/ip protocol, aka connect to tcp/ip sockets
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include <stdio.h>
-#include <netdb.h>
-#include <arpa/inet.h>
-#include <netinet/in.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <string.h>
-
-#include "tcpip.h"
-
-/* tcpip_connect
- *
- * try to connect to the specified tcp/ip socket, wrap to stdio.h's FILE*
- * structure and turn on line buffering
- */
-FILE *
-tcpip_connect(const char *hostname, int port)
-{
- int sockfd;
- struct sockaddr_in addr;
- struct in_addr inaddr;
- struct hostent *host;
- FILE *handle;
- const char err_connect[] = PACKAGE ": unable to connect to cvs host";
-
- if(inet_aton(hostname, &inaddr))
- host = gethostbyaddr((char *) &inaddr, sizeof(inaddr), AF_INET);
- else
- host = gethostbyname(hostname);
-
- if(! host)
- {
- herror(err_connect);
- return NULL;
- }
-
- addr.sin_family = AF_INET;
- addr.sin_port = htons(port);
- memcpy(&addr.sin_addr, host->h_addr_list[0], sizeof(addr.sin_addr));
-
- if((sockfd = socket(PF_INET, SOCK_STREAM, 0)) < 0)
- {
- perror(err_connect);
- return NULL;
- }
-
- if(connect(sockfd, (struct sockaddr *) &addr, sizeof(addr)))
- {
- perror(err_connect);
- return NULL;
- }
-
- handle = fdopen(sockfd, "r+");
- if(! handle)
- {
- perror(err_connect);
- close(sockfd);
- return NULL;
- }
-
- if(setvbuf(handle, NULL, _IOLBF, 0))
- {
- perror(err_connect);
- fclose(handle);
- return NULL;
- }
-
- return handle;
-}
-
-
Index: tcpip.h
===================================================================
RCS file: tcpip.h
diff -N tcpip.h
--- tcpip.h 16 Nov 2005 21:18:08 -0000 1.2
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,24 +0,0 @@
-/**********************************************************
- * tcpip.h
- *
- * Copyright 2004, Stefan Siegl <address@hidden>, Germany
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Publice License,
- * version 2 or any later. The license is contained in the COPYING
- * file that comes with the cvsfs distribution.
- *
- * speak tcp/ip protocol, aka connect to tcp/ip sockets
- */
-
-#ifndef TCPIP_H
-#define TCPIP_H
-
-#include <stdio.h>
-
-/* try to connect to the specified tcp/ip socket, wrap to stdio.h's FILE*
- * structure and turn on line buffering
- */
-FILE *tcpip_connect(const char *hostname, int port);
-
-#endif /* TCPIP_H */
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- cvsfs .cvsignore AUTHORS COPYING ChangeLog HACK...,
Thomas Schwinge <=