hurdextras-commit
[Top][All Lists]
Advanced

[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 */



reply via email to

[Prev in Thread] Current Thread [Next in Thread]