OSDN Git Service

各種プラグインを同梱
authorYOSHIDA Hiroki <hyoshida@appirits.com>
Fri, 31 May 2013 09:06:41 +0000 (18:06 +0900)
committerYOSHIDA Hiroki <hyoshida@appirits.com>
Fri, 31 May 2013 12:25:39 +0000 (21:25 +0900)
92 files changed:
.gitignore
vendor/gems/lhalib-0.8.1/.specification [new file with mode: 0644]
vendor/gems/lhalib-0.8.1/COPYING [new file with mode: 0644]
vendor/gems/lhalib-0.8.1/ChangeLog [new file with mode: 0644]
vendor/gems/lhalib-0.8.1/ext/bitio.c [new file with mode: 0644]
vendor/gems/lhalib-0.8.1/ext/crcio.c [new file with mode: 0644]
vendor/gems/lhalib-0.8.1/ext/depend [new file with mode: 0644]
vendor/gems/lhalib-0.8.1/ext/dhuf.c [new file with mode: 0644]
vendor/gems/lhalib-0.8.1/ext/extconf.rb [new file with mode: 0644]
vendor/gems/lhalib-0.8.1/ext/extract.c [new file with mode: 0644]
vendor/gems/lhalib-0.8.1/ext/header.c [new file with mode: 0644]
vendor/gems/lhalib-0.8.1/ext/huf.c [new file with mode: 0644]
vendor/gems/lhalib-0.8.1/ext/larc.c [new file with mode: 0644]
vendor/gems/lhalib-0.8.1/ext/lha.h [new file with mode: 0644]
vendor/gems/lhalib-0.8.1/ext/lha_macro.h [new file with mode: 0644]
vendor/gems/lhalib-0.8.1/ext/lhalib.c [new file with mode: 0644]
vendor/gems/lhalib-0.8.1/ext/lharc.c [new file with mode: 0644]
vendor/gems/lhalib-0.8.1/ext/lhext.c [new file with mode: 0644]
vendor/gems/lhalib-0.8.1/ext/maketbl.c [new file with mode: 0644]
vendor/gems/lhalib-0.8.1/ext/maketree.c [new file with mode: 0644]
vendor/gems/lhalib-0.8.1/ext/shuf.c [new file with mode: 0644]
vendor/gems/lhalib-0.8.1/ext/slide.c [new file with mode: 0644]
vendor/gems/lhalib-0.8.1/ext/util.c [new file with mode: 0644]
vendor/gems/lhalib-0.8.1/readme.txt [new file with mode: 0644]
vendor/gems/lhalib-0.8.1/setup.rb [new file with mode: 0644]
vendor/gems/lhalib-0.8.1/test/test.dat.org [new file with mode: 0644]
vendor/gems/lhalib-0.8.1/test/test.lzh [new file with mode: 0644]
vendor/gems/lhalib-0.8.1/test/test.rb [new file with mode: 0644]
vendor/gems/lhalib-0.8.1/test/test2.lzh [new file with mode: 0644]
vendor/gems/lhalib-0.8.1/test/testh.h.org [new file with mode: 0644]
vendor/gems/lhalib-0.8.1/test/testlib.c.org [new file with mode: 0644]
vendor/gems/lhalib-0.8.1/test/tmpdir.lzh [new file with mode: 0644]
vendor/plugins/acts_as_paranoid/CHANGELOG [new file with mode: 0644]
vendor/plugins/acts_as_paranoid/MIT-LICENSE [new file with mode: 0644]
vendor/plugins/acts_as_paranoid/README [new file with mode: 0644]
vendor/plugins/acts_as_paranoid/RUNNING_UNIT_TESTS [new file with mode: 0644]
vendor/plugins/acts_as_paranoid/Rakefile [new file with mode: 0644]
vendor/plugins/acts_as_paranoid/init.rb [new file with mode: 0644]
vendor/plugins/acts_as_paranoid/lib/caboose/acts/belongs_to_with_deleted_association.rb [new file with mode: 0644]
vendor/plugins/acts_as_paranoid/lib/caboose/acts/has_many_through_without_deleted_association.rb [new file with mode: 0644]
vendor/plugins/acts_as_paranoid/lib/caboose/acts/paranoid.rb [new file with mode: 0644]
vendor/plugins/acts_as_paranoid/lib/caboose/acts/paranoid_find_wrapper.rb [new file with mode: 0644]
vendor/plugins/acts_as_paranoid/test/database.yml [new file with mode: 0644]
vendor/plugins/acts_as_paranoid/test/fixtures/categories.yml [new file with mode: 0644]
vendor/plugins/acts_as_paranoid/test/fixtures/categories_widgets.yml [new file with mode: 0644]
vendor/plugins/acts_as_paranoid/test/fixtures/taggings.yml [new file with mode: 0644]
vendor/plugins/acts_as_paranoid/test/fixtures/tags.yml [new file with mode: 0644]
vendor/plugins/acts_as_paranoid/test/fixtures/widgets.yml [new file with mode: 0644]
vendor/plugins/acts_as_paranoid/test/paranoid_test.rb [new file with mode: 0644]
vendor/plugins/acts_as_paranoid/test/schema.rb [new file with mode: 0644]
vendor/plugins/acts_as_paranoid/test/test_helper.rb [new file with mode: 0644]
vendor/plugins/double_submit_protection/README [new file with mode: 0644]
vendor/plugins/double_submit_protection/init.rb [new file with mode: 0644]
vendor/plugins/double_submit_protection/lib/double_submit_protection.rb [new file with mode: 0755]
vendor/plugins/image_submit_tag_ext/MIT-LICENSE [new file with mode: 0644]
vendor/plugins/image_submit_tag_ext/README [new file with mode: 0644]
vendor/plugins/image_submit_tag_ext/Rakefile [new file with mode: 0644]
vendor/plugins/image_submit_tag_ext/init.rb [new file with mode: 0644]
vendor/plugins/image_submit_tag_ext/install.rb [new file with mode: 0644]
vendor/plugins/image_submit_tag_ext/lib/image_submit_tag_ext.rb [new file with mode: 0644]
vendor/plugins/image_submit_tag_ext/tasks/image_submit_tag_ext_tasks.rake [new file with mode: 0644]
vendor/plugins/image_submit_tag_ext/test/image_submit_tag_ext_test.rb [new file with mode: 0644]
vendor/plugins/image_submit_tag_ext/test/test_helper.rb [new file with mode: 0644]
vendor/plugins/image_submit_tag_ext/uninstall.rb [new file with mode: 0644]
vendor/plugins/mbmail/MIT-LICENSE [new file with mode: 0644]
vendor/plugins/mbmail/README [new file with mode: 0644]
vendor/plugins/mbmail/Rakefile [new file with mode: 0644]
vendor/plugins/mbmail/init.rb [new file with mode: 0644]
vendor/plugins/mbmail/install.rb [new file with mode: 0644]
vendor/plugins/mbmail/lib/mb_mail.rb [new file with mode: 0644]
vendor/plugins/mbmail/lib/mb_mail/dmail.rb [new file with mode: 0644]
vendor/plugins/mbmail/lib/mb_mail/mb_mailer.rb [new file with mode: 0644]
vendor/plugins/mbmail/lib/tmail/mail.rb [new file with mode: 0644]
vendor/plugins/mbmail/lib/tmail/parser.rb [new file with mode: 0644]
vendor/plugins/mbmail/lib/tmail/unquoter.rb [new file with mode: 0644]
vendor/plugins/mbmail/spec/mb_mail/dmail_spec.rb [new file with mode: 0644]
vendor/plugins/mbmail/spec/mb_mail/mb_mailer_spec.rb [new file with mode: 0644]
vendor/plugins/mbmail/spec/sample/attached.gif [new file with mode: 0644]
vendor/plugins/mbmail/spec/sample/decomail.eml [new file with mode: 0644]
vendor/plugins/mbmail/spec/sample/inlined.gif [new file with mode: 0644]
vendor/plugins/mbmail/spec/sample/test_mb_mailer/testmail.html.erb [new file with mode: 0644]
vendor/plugins/mbmail/spec/spec_helper.rb [new file with mode: 0644]
vendor/plugins/mbmail/tasks/mb_mail_tasks.rake [new file with mode: 0644]
vendor/plugins/mbmail/test/mb_mail_test.rb [new file with mode: 0644]
vendor/plugins/mbmail/uninstall.rb [new file with mode: 0644]
vendor/plugins/rails-active-form/MIT-LICENSE [new file with mode: 0644]
vendor/plugins/rails-active-form/README.rdoc [new file with mode: 0644]
vendor/plugins/rails-active-form/init.rb [new file with mode: 0644]
vendor/plugins/rails-active-form/lib/active_form.rb [new file with mode: 0644]
vendor/plugins/ssl_requirement/README [new file with mode: 0644]
vendor/plugins/ssl_requirement/lib/ssl_requirement.rb [new file with mode: 0644]
vendor/plugins/ssl_requirement/test/ssl_requirement_test.rb [new file with mode: 0644]

index 75043e5..7dae0d0 100644 (file)
@@ -7,6 +7,12 @@ tmp/*
 db/schema.rb
 vendor/plugins/*
 !vendor/plugins/.gitkeep
+!vendor/plugins/acts_as_paranoid
+!vendor/plugins/double_submit_protection
+!vendor/plugins/image_submit_tag_ext
+!vendor/plugins/mbmail
+!vendor/plugins/rails-active-form
+!vendor/plugins/ssl_requirement
 var/run/*
 !var/run/.gitkeep
 config/database.yml
diff --git a/vendor/gems/lhalib-0.8.1/.specification b/vendor/gems/lhalib-0.8.1/.specification
new file mode 100644 (file)
index 0000000..90517f3
--- /dev/null
@@ -0,0 +1,53 @@
+--- !ruby/object:Gem::Specification
+name: lhalib
+version: !ruby/object:Gem::Version
+  version: 0.8.1
+  prerelease: 
+  segments:
+  - 0
+  - 8
+  - 1
+platform: ruby
+authors:
+- arton
+autorequire: 
+bindir: bin
+cert_chain: 
+date: 2006-09-18 00:00:00.000000000 Z
+dependencies: []
+description: LhaLib is an utility that unpack the LHa archived file.
+email: artonx@gmail.com
+executables: []
+extensions:
+- ext/extconf.rb
+extra_rdoc_files: []
+files:
+- ext/extconf.rb
+homepage: http://arton.no-ip.info/collabo/backyard/?LhaLib
+licenses: []
+post_install_message: 
+rdoc_options: []
+require_paths:
+- lib
+required_ruby_version: !ruby/object:Gem::Requirement
+  none: false
+  requirements:
+  - - ! '>='
+    - !ruby/object:Gem::Version
+      version: 1.8.2
+required_rubygems_version: !ruby/object:Gem::Requirement
+  none: false
+  requirements:
+  - - ! '>='
+    - !ruby/object:Gem::Version
+      version: '0'
+requirements:
+- none
+rubyforge_project: 
+rubygems_version: 1.8.23
+signing_key: 
+specification_version: 1
+summary: Ruby LHa Lib
+test_files: []
+has_rdoc: 
+
diff --git a/vendor/gems/lhalib-0.8.1/COPYING b/vendor/gems/lhalib-0.8.1/COPYING
new file mode 100644 (file)
index 0000000..b1e3f5a
--- /dev/null
@@ -0,0 +1,504 @@
+                 GNU LESSER GENERAL PUBLIC LICENSE
+                      Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 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.
+
+[This is the first released version of the Lesser GPL.  It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+                           Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it.  You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+  When we speak of free software, we are referring to freedom of use,
+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 and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+  To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights.  These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  To protect each distributor, we want to make it very clear that
+there is no warranty for the free library.  Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+\f
+  Finally, software patents pose a constant threat to the existence of
+any free program.  We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder.  Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+  Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License.  This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License.  We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+  When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library.  The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom.  The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+  We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License.  It also provides other free software developers Less
+of an advantage over competing non-free programs.  These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries.  However, the Lesser license provides advantages in certain
+special circumstances.
+
+  For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard.  To achieve this, non-free programs must be
+allowed to use the library.  A more frequent case is that a free
+library does the same job as widely used non-free libraries.  In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+  In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software.  For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+  Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+\f
+                 GNU LESSER GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, 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 library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+  
+  1. You may copy and distribute verbatim copies of the Library's
+complete 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 distribute a copy of this License along with the
+Library.
+
+  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.
+\f
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, 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) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+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 Library, 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 Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+\f
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you 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.
+
+  If distribution of 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 satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+\f
+  6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Use a suitable shared library mechanism for linking with the
+    Library.  A suitable mechanism is one that (1) uses at run time a
+    copy of the library already present on the user's computer system,
+    rather than copying library functions into the executable, and (2)
+    will operate properly with a modified version of the library, if
+    the user installs one, as long as the modified version is
+    interface-compatible with the version that the work was made with.
+
+    c) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    d) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    e) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the materials to be 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.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+\f
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library 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.
+
+  9. 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 Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+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 with
+this License.
+\f
+  11. 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 Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library 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 Library.
+
+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.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library 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.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser 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 Library
+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 Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+\f
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+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
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "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
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. 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 LIBRARY 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
+LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+                    END OF TERMS AND CONDITIONS
+\f
+           How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.  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 library's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library 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
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; 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.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+  <signature of Ty Coon>, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!
+
+
diff --git a/vendor/gems/lhalib-0.8.1/ChangeLog b/vendor/gems/lhalib-0.8.1/ChangeLog
new file mode 100644 (file)
index 0000000..5015392
--- /dev/null
@@ -0,0 +1,21 @@
+Mon Sep 18 17:56:00 2006 arton\r
+ *lha.h\r
+       change extern macro for some arrays. because of OS X's linker reports confliction.\r
+Sun Sep 17 23:47:00 2006 arton\r
+ initial reelase\r
+ *bitio.c\r
+ *crcio.c\r
+ *dhuf.c\r
+ *extract.c\r
+ *header.c\r
+ *huf.c\r
+ *larc.c\r
+ *lhext.c\r
+ *maketbl.c\r
+ *shuf.c\r
+ *slide.c\r
+ *util.c\r
+       copy and modifying from lha-1.14i-ac20050924\r
+ *lha.h\r
+ *lharc.c\r
+       reconfig for lhalib\r
diff --git a/vendor/gems/lhalib-0.8.1/ext/bitio.c b/vendor/gems/lhalib-0.8.1/ext/bitio.c
new file mode 100644 (file)
index 0000000..8fea353
--- /dev/null
@@ -0,0 +1,86 @@
+/* ------------------------------------------------------------------------ */
+/* LHa for UNIX                                                             */
+/*              bitio.c -- bit stream                                       */
+/*                                                                          */
+/*      Modified                Nobutaka Watazaki                           */
+/*                                                                          */
+/*  Ver. 1.14   Source All chagned              1995.01.14  N.Watazaki      */
+/*              Separated from crcio.c          2002.10.26  Koji Arai       */
+/* ------------------------------------------------------------------------ */
+#include "lha.h"
+
+static unsigned char subbitbuf, bitcount;
+
+void
+fillbuf(unsigned char n)          /* Shift bitbuf n bits left, read n bits */
+{
+    while (n > bitcount) {
+        n -= bitcount;
+        bitbuf = (bitbuf << bitcount) + (subbitbuf >> (CHAR_BIT - bitcount));
+        if (compsize != 0) {
+            compsize--;
+            subbitbuf = (unsigned char) getc(infile);
+        }
+        else
+            subbitbuf = 0;
+        bitcount = CHAR_BIT;
+    }
+    bitcount -= n;
+    bitbuf = (bitbuf << n) + (subbitbuf >> (CHAR_BIT - n));
+    subbitbuf <<= n;
+}
+
+unsigned short
+getbits(unsigned char n)
+{
+    unsigned short  x;
+
+    x = bitbuf >> (2 * CHAR_BIT - n);
+    fillbuf(n);
+    return x;
+}
+
+void
+putcode(unsigned char n, unsigned short x)           /* Write leftmost n bits of x */
+{
+    while (n >= bitcount) {
+        n -= bitcount;
+        subbitbuf += x >> (USHRT_BIT - bitcount);
+        x <<= bitcount;
+        if (compsize < origsize) {
+            if (fwrite(&subbitbuf, 1, 1, outfile) == 0) {
+                fatal_error("Write error in bitio.c(putcode)");
+            }
+            compsize++;
+        }
+        else
+            unpackable = 1;
+        subbitbuf = 0;
+        bitcount = CHAR_BIT;
+    }
+    subbitbuf += x >> (USHRT_BIT - bitcount);
+    bitcount -= n;
+}
+
+void
+putbits(unsigned char n, unsigned short x)           /* Write rightmost n bits of x */
+{
+    x <<= USHRT_BIT - n;
+    putcode(n, x);
+}
+
+void
+init_getbits( /* void */ )
+{
+    bitbuf = 0;
+    subbitbuf = 0;
+    bitcount = 0;
+    fillbuf(2 * CHAR_BIT);
+}
+
+void
+init_putbits( /* void */ )
+{
+    bitcount = CHAR_BIT;
+    subbitbuf = 0;
+}
diff --git a/vendor/gems/lhalib-0.8.1/ext/crcio.c b/vendor/gems/lhalib-0.8.1/ext/crcio.c
new file mode 100644 (file)
index 0000000..3fb4272
--- /dev/null
@@ -0,0 +1,220 @@
+/* ------------------------------------------------------------------------ */
+/* LHa for UNIX                                                             */
+/*              crcio.c -- crc input / output                               */
+/*                                                                          */
+/*      Modified                Nobutaka Watazaki                           */
+/*                                                                          */
+/*  Ver. 1.14   Source All chagned              1995.01.14  N.Watazaki      */
+/* ------------------------------------------------------------------------ */
+#include "lha.h"
+
+/* ------------------------------------------------------------------------ */
+#ifdef EUC
+static int      putc_euc_cache;
+#endif
+static int      getc_euc_cache;
+
+/* ------------------------------------------------------------------------ */
+void
+make_crctable( /* void */ )
+{
+    unsigned int    i, j, r;
+
+    for (i = 0; i <= UCHAR_MAX; i++) {
+        r = i;
+        for (j = 0; j < CHAR_BIT; j++)
+            if (r & 1)
+                r = (r >> 1) ^ CRCPOLY;
+            else
+                r >>= 1;
+        crctable[i] = r;
+    }
+}
+
+/* ------------------------------------------------------------------------ */
+unsigned int
+calccrc(crc, p, n)
+    unsigned int crc;
+    unsigned char  *p;
+    unsigned int    n;
+{
+    while (n-- > 0)
+        crc = UPDATE_CRC(crc, *p++);
+    return crc;
+}
+
+/* ------------------------------------------------------------------------ */
+int
+fread_crc(crcp, p, n, fp)
+    unsigned int *crcp;
+    unsigned char  *p;
+    int             n;
+    FILE           *fp;
+{
+    if (text_mode)
+        n = fread_txt(p, n, fp);
+    else
+        n = fread(p, 1, n, fp);
+
+    *crcp = calccrc(*crcp, p, n);
+#ifdef NEED_INCREMENTAL_INDICATOR
+    put_indicator(n);
+#endif
+    return n;
+}
+
+/* ------------------------------------------------------------------------ */
+void
+fwrite_crc(crcp, p, n, fp)
+    unsigned int *crcp;
+    unsigned char  *p;
+    int             n;
+    FILE           *fp;
+{
+    *crcp = calccrc(*crcp, p, n);
+#ifdef NEED_INCREMENTAL_INDICATOR
+    put_indicator(n);
+#endif
+    if (fp) {
+        if (text_mode) {
+            if (fwrite_txt(p, n, fp))
+                fatal_error("File write error");
+        }
+        else {
+            if (fwrite(p, 1, n, fp) < n)
+                fatal_error("File write error");
+        }
+    }
+}
+
+/* ------------------------------------------------------------------------ */
+void
+init_code_cache( /* void */ )
+{               /* called from copyfile() in util.c */
+#ifdef EUC
+    putc_euc_cache = EOF;
+#endif
+    getc_euc_cache = EOF;
+}
+
+/* ------------------------------------------------------------------------ */
+#ifdef EUC
+int
+putc_euc(c, fd)
+    int             c;
+    FILE           *fd;
+{
+    int             d;
+
+    if (putc_euc_cache == EOF) {
+        if (!euc_mode || c < 0x81 || c > 0xFC) {
+            return putc(c, fd);
+        }
+        if (c >= 0xA0 && c < 0xE0) {
+            if (putc(0x8E, fd) == EOF) return EOF;  /* single shift */
+            return putc(c, fd);
+        }
+        putc_euc_cache = c; /* save first byte */
+        return c;
+    }
+    d = putc_euc_cache;
+    putc_euc_cache = EOF;
+    if (d >= 0xA0)
+        d -= 0xE0 - 0xA0;
+    if (c > 0x9E) {
+        c = c - 0x9F + 0x21;
+        d = (d - 0x81) * 2 + 0x22;
+    }
+    else {
+        if (c > 0x7E)
+            c--;
+        c -= 0x1F;
+        d = (d - 0x81) * 2 + 0x21;
+    }
+    if (putc(0x80 | d, fd) == EOF) return EOF;
+    return putc(0x80 | c, fd);
+}
+#endif
+
+/* ------------------------------------------------------------------------ */
+int
+fwrite_txt(p, n, fp)
+    unsigned char  *p;
+    int             n;
+    FILE           *fp;
+{
+    while (--n >= 0) {
+        if (*p != '\015' && *p != '\032') {
+#ifdef EUC
+            if (putc_euc(*p, fp) == EOF)
+                break;
+#else
+            if (putc(*p, fp) == EOF)
+                break;
+#endif
+        }
+        p++;
+    }
+    return (ferror(fp));
+}
+
+/* ------------------------------------------------------------------------ */
+int
+fread_txt(p, n, fp)
+    unsigned char  *p;
+    int             n;
+    FILE           *fp;
+{
+    int             c;
+    int             cnt = 0;
+
+    while (cnt < n) {
+        if (getc_euc_cache != EOF) {
+            c = getc_euc_cache;
+            getc_euc_cache = EOF;
+        }
+        else {
+            if ((c = fgetc(fp)) == EOF)
+                break;
+            if (c == '\n') {
+                getc_euc_cache = c;
+                ++origsize;
+                c = '\r';
+            }
+#ifdef EUC
+            else if (euc_mode && (c == 0x8E || (0xA0 < c && c < 0xFF))) {
+                int             d = fgetc(fp);
+                if (d == EOF) {
+                    *p++ = c;
+                    cnt++;
+                    break;
+                }
+                if (c == 0x8E) {    /* single shift (KANA) */
+                    if ((0x20 < d && d < 0x7F) || (0xA0 < d && d < 0xFF))
+                        c = d | 0x80;
+                    else
+                        getc_euc_cache = d;
+                }
+                else {
+                    if (0xA0 < d && d < 0xFF) { /* if GR */
+                        c &= 0x7F;  /* convert to MS-kanji */
+                        d &= 0x7F;
+                        if (!(c & 1)) {
+                            c--;
+                            d += 0x7F - 0x21;
+                        }
+                        if ((d += 0x40 - 0x21) > 0x7E)
+                            d++;
+                        if ((c = (c >> 1) + 0x71) >= 0xA0)
+                            c += 0xE0 - 0xA0;
+                    }
+                    getc_euc_cache = d;
+                }
+            }
+#endif
+        }
+        *p++ = c;
+        cnt++;
+    }
+    return cnt;
+}
diff --git a/vendor/gems/lhalib-0.8.1/ext/depend b/vendor/gems/lhalib-0.8.1/ext/depend
new file mode 100644 (file)
index 0000000..cdb26e6
--- /dev/null
@@ -0,0 +1,15 @@
+lhalib.o : lhalib.c $(hdrdir)/ruby.h $(hdrdir)/config.h $(hdrdir)/defines.h lha.h lha_macro.h
+dhuf.o : dhuf.c lha.h
+extract.o : extract.c lha.h
+header.o : header.c lha.h
+huf.o : huf.c lha.h
+shuf.o : shuf.c lha.h
+slide.o : slide.c lha.h
+lharc.o : lharc.c lha.h
+larc.o : larc.c lha.h
+crcio.o : crcio.c lha.h
+bitio.o : bitio.c lha.h
+maketbl.o : maketbl.c lha.h
+maketree.o : maketree.c lha.h
+util.o : util.c lha.h
+
diff --git a/vendor/gems/lhalib-0.8.1/ext/dhuf.c b/vendor/gems/lhalib-0.8.1/ext/dhuf.c
new file mode 100644 (file)
index 0000000..4e4caa8
--- /dev/null
@@ -0,0 +1,352 @@
+/* ------------------------------------------------------------------------ */
+/* LHa for UNIX                                                             */
+/*              dhuf.c -- Dynamic Hufffman routine                          */
+/*                                                                          */
+/*      Modified                H.Yoshizaki                                 */
+/*                                                                          */
+/*  Ver. 1.14   Source All chagned              1995.01.14  N.Watazaki      */
+/* ------------------------------------------------------------------------ */
+#include "lha.h"
+
+/* ------------------------------------------------------------------------ */
+static short    child[TREESIZE], parent[TREESIZE], block[TREESIZE], edge[TREESIZE], stock[TREESIZE],
+                s_node[TREESIZE / 2];   /* Changed N.Watazaki */
+/*  node[..] -> s_node[..] */
+
+static unsigned short freq[TREESIZE];
+
+static unsigned short total_p;
+static int      avail, n1;
+static int      most_p, nn;
+static unsigned long nextcount;
+/* ------------------------------------------------------------------------ */
+void
+start_c_dyn( /* void */ )
+{
+    int             i, j, f;
+
+    n1 = (n_max >= 256 + maxmatch - THRESHOLD + 1) ? 512 : n_max - 1;
+    for (i = 0; i < TREESIZE_C; i++) {
+        stock[i] = i;
+        block[i] = 0;
+    }
+    for (i = 0, j = n_max * 2 - 2; i < n_max; i++, j--) {
+        freq[j] = 1;
+        child[j] = ~i;
+        s_node[i] = j;
+        block[j] = 1;
+    }
+    avail = 2;
+    edge[1] = n_max - 1;
+    i = n_max * 2 - 2;
+    while (j >= 0) {
+        f = freq[j] = freq[i] + freq[i - 1];
+        child[j] = i;
+        parent[i] = parent[i - 1] = j;
+        if (f == freq[j + 1]) {
+            edge[block[j] = block[j + 1]] = j;
+        }
+        else {
+            edge[block[j] = stock[avail++]] = j;
+        }
+        i -= 2;
+        j--;
+    }
+}
+
+/* ------------------------------------------------------------------------ */
+static void
+start_p_dyn( /* void */ )
+{
+    freq[ROOT_P] = 1;
+    child[ROOT_P] = ~(N_CHAR);
+    s_node[N_CHAR] = ROOT_P;
+    edge[block[ROOT_P] = stock[avail++]] = ROOT_P;
+    most_p = ROOT_P;
+    total_p = 0;
+    nn = 1 << dicbit;
+    nextcount = 64;
+}
+
+/* ------------------------------------------------------------------------ */
+/* lh2 */
+void
+decode_start_dyn( /* void */ )
+{
+    n_max = 286;
+    maxmatch = MAXMATCH;
+    init_getbits();
+    init_code_cache();
+    start_c_dyn();
+    start_p_dyn();
+}
+
+/* ------------------------------------------------------------------------ */
+static void
+reconst(start, end)
+    int             start;
+    int             end;
+{
+    int             i, j, k, l, b;
+    unsigned int    f, g;
+
+    for (i = j = start; i < end; i++) {
+        if ((k = child[i]) < 0) {
+            freq[j] = (freq[i] + 1) / 2;
+            child[j] = k;
+            j++;
+        }
+        if (edge[b = block[i]] == i) {
+            stock[--avail] = b;
+        }
+    }
+    j--;
+    i = end - 1;
+    l = end - 2;
+    while (i >= start) {
+        while (i >= l) {
+            freq[i] = freq[j];
+            child[i] = child[j];
+            i--, j--;
+        }
+        f = freq[l] + freq[l + 1];
+        for (k = start; f < freq[k]; k++);
+        while (j >= k) {
+            freq[i] = freq[j];
+            child[i] = child[j];
+            i--, j--;
+        }
+        freq[i] = f;
+        child[i] = l + 1;
+        i--;
+        l -= 2;
+    }
+    f = 0;
+    for (i = start; i < end; i++) {
+        if ((j = child[i]) < 0)
+            s_node[~j] = i;
+        else
+            parent[j] = parent[j - 1] = i;
+        if ((g = freq[i]) == f) {
+            block[i] = b;
+        }
+        else {
+            edge[b = block[i] = stock[avail++]] = i;
+            f = g;
+        }
+    }
+}
+
+/* ------------------------------------------------------------------------ */
+static int
+swap_inc(p)
+    int             p;
+{
+    int             b, q, r, s;
+
+    b = block[p];
+    if ((q = edge[b]) != p) {   /* swap for leader */
+        r = child[p];
+        s = child[q];
+        child[p] = s;
+        child[q] = r;
+        if (r >= 0)
+            parent[r] = parent[r - 1] = q;
+        else
+            s_node[~r] = q;
+        if (s >= 0)
+            parent[s] = parent[s - 1] = p;
+        else
+            s_node[~s] = p;
+        p = q;
+        goto Adjust;
+    }
+    else if (b == block[p + 1]) {
+Adjust:
+        edge[b]++;
+        if (++freq[p] == freq[p - 1]) {
+            block[p] = block[p - 1];
+        }
+        else {
+            edge[block[p] = stock[avail++]] = p;    /* create block */
+        }
+    }
+    else if (++freq[p] == freq[p - 1]) {
+        stock[--avail] = b; /* delete block */
+        block[p] = block[p - 1];
+    }
+    return parent[p];
+}
+
+/* ------------------------------------------------------------------------ */
+static void
+update_c(p)
+    int             p;
+{
+    int             q;
+
+    if (freq[ROOT_C] == 0x8000) {
+        reconst(0, n_max * 2 - 1);
+    }
+    freq[ROOT_C]++;
+    q = s_node[p];
+    do {
+        q = swap_inc(q);
+    } while (q != ROOT_C);
+}
+
+/* ------------------------------------------------------------------------ */
+static void
+update_p(p)
+    int             p;
+{
+    int             q;
+
+    if (total_p == 0x8000) {
+        reconst(ROOT_P, most_p + 1);
+        total_p = freq[ROOT_P];
+        freq[ROOT_P] = 0xffff;
+    }
+    q = s_node[p + N_CHAR];
+    while (q != ROOT_P) {
+        q = swap_inc(q);
+    }
+    total_p++;
+}
+
+/* ------------------------------------------------------------------------ */
+static void
+make_new_node(p)
+    int             p;
+{
+    int             q, r;
+
+    r = most_p + 1;
+    q = r + 1;
+    s_node[~(child[r] = child[most_p])] = r;
+    child[q] = ~(p + N_CHAR);
+    child[most_p] = q;
+    freq[r] = freq[most_p];
+    freq[q] = 0;
+    block[r] = block[most_p];
+    if (most_p == ROOT_P) {
+        freq[ROOT_P] = 0xffff;
+        edge[block[ROOT_P]]++;
+    }
+    parent[r] = parent[q] = most_p;
+    edge[block[q] = stock[avail++]] = s_node[p + N_CHAR] = most_p = q;
+    update_p(p);
+}
+
+/* ------------------------------------------------------------------------ */
+static void
+encode_c_dyn(c)
+    unsigned int    c;
+{
+    unsigned int    bits;
+    int             p, d, cnt;
+
+    d = c - n1;
+    if (d >= 0) {
+        c = n1;
+    }
+    cnt = bits = 0;
+    p = s_node[c];
+    do {
+        bits >>= 1;
+        if (p & 1) {
+            bits |= 0x80000000L;
+        }
+        cnt++;
+    } while ((p = parent[p]) != ROOT_C);
+    if (cnt <= 16) {
+        putcode(cnt, bits >> 16);
+    } else {
+        putcode(16, bits >> 16);
+        putbits(cnt - 16, bits);
+    }
+    if (d >= 0)
+        putbits(8, d);
+    update_c(c);
+}
+
+/* ------------------------------------------------------------------------ */
+/* lh1, 2 */
+unsigned short
+decode_c_dyn( /* void */ )
+{
+    int             c;
+    short           buf, cnt;
+
+    c = child[ROOT_C];
+    buf = bitbuf;
+    cnt = 0;
+    do {
+        c = child[c - (buf < 0)];
+        buf <<= 1;
+        if (++cnt == 16) {
+            fillbuf(16);
+            buf = bitbuf;
+            cnt = 0;
+        }
+    } while (c > 0);
+    fillbuf(cnt);
+    c = ~c;
+    update_c(c);
+    if (c == n1)
+        c += getbits(8);
+    return c;
+}
+
+/* ------------------------------------------------------------------------ */
+/* lh2 */
+unsigned short
+decode_p_dyn( /* void */ )
+{
+    int             c;
+    short           buf, cnt;
+
+    while (decode_count > nextcount) {
+        make_new_node(nextcount / 64);
+        if ((nextcount += 64) >= nn)
+            nextcount = 0xffffffff;
+    }
+    c = child[ROOT_P];
+    buf = bitbuf;
+    cnt = 0;
+    while (c > 0) {
+        c = child[c - (buf < 0)];
+        buf <<= 1;
+        if (++cnt == 16) {
+            fillbuf(16);
+            buf = bitbuf;
+            cnt = 0;
+        }
+    }
+    fillbuf(cnt);
+    c = (~c) - N_CHAR;
+    update_p(c);
+
+    return (c << 6) + getbits(6);
+}
+
+/* ------------------------------------------------------------------------ */
+/* lh1 */
+void
+output_dyn(code, pos)
+    unsigned int    code;
+    unsigned int    pos;
+{
+    encode_c_dyn(code);
+    if (code >= 0x100) {
+        encode_p_st0(pos);
+    }
+}
+
+/* ------------------------------------------------------------------------ */
+/* lh1 */
+void
+encode_end_dyn( /* void */ )
+{
+    putcode(7, 0);
+}
diff --git a/vendor/gems/lhalib-0.8.1/ext/extconf.rb b/vendor/gems/lhalib-0.8.1/ext/extconf.rb
new file mode 100644 (file)
index 0000000..fc17169
--- /dev/null
@@ -0,0 +1,42 @@
+#----------------------------------
+# extconf.rb
+# $Revision: $
+# $Date: $
+#----------------------------------
+require 'mkmf'
+
+class Path
+
+  def initialize()
+    if File::ALT_SEPARATOR.nil?
+      @file_separator = File::SEPARATOR
+    else
+      @file_separator = File::ALT_SEPARATOR
+    end
+  end
+
+  def include(parent, child)
+    inc = joint(parent, child)
+    $INCFLAGS += " -I#{inc}"
+    $CFLAGS += " -I#{inc}"
+    inc
+  end
+
+  def joint(parent, child)
+    parent + @file_separator + child
+  end
+
+end
+
+def create_lhalib_makefile
+  create_makefile("lhalib")
+end
+
+case RUBY_PLATFORM
+when /mswin32/
+  $CFLAGS += ' /W3'
+when /cygwin/, /mingw/
+  $defs << '-DNONAMELESSUNION'
+end
+create_lhalib_makefile
+
diff --git a/vendor/gems/lhalib-0.8.1/ext/extract.c b/vendor/gems/lhalib-0.8.1/ext/extract.c
new file mode 100644 (file)
index 0000000..229058e
--- /dev/null
@@ -0,0 +1,89 @@
+/* ------------------------------------------------------------------------ */
+/* LHa for UNIX                                                             */
+/*              extract.c -- extrcat from archive                           */
+/*                                                                          */
+/*      Modified                Nobutaka Watazaki                           */
+/*                                                                          */
+/*  Ver. 1.14   Source All chagned              1995.01.14  N.Watazaki      */
+/* ------------------------------------------------------------------------ */
+#include "lha.h"
+
+int
+decode_lzhuf(infp, outfp, original_size, packed_size, name, method, read_sizep)
+    FILE           *infp;
+    FILE           *outfp;
+    size_t          original_size;
+    size_t          packed_size;
+    char           *name;
+    int             method;
+    size_t         *read_sizep;
+{
+    unsigned int crc;
+    struct interfacing intf;
+
+    intf.method = method;
+    intf.infile = infp;
+    intf.outfile = outfp;
+    intf.original = original_size;
+    intf.packed = packed_size;
+    intf.read_size = 0;
+
+    switch (method) {
+    case LZHUFF0_METHOD_NUM:    /* -lh0- */
+        intf.dicbit = LZHUFF0_DICBIT;
+        break;
+    case LZHUFF1_METHOD_NUM:    /* -lh1- */
+        intf.dicbit = LZHUFF1_DICBIT;
+        break;
+    case LZHUFF2_METHOD_NUM:    /* -lh2- */
+        intf.dicbit = LZHUFF2_DICBIT;
+        break;
+    case LZHUFF3_METHOD_NUM:    /* -lh2- */
+        intf.dicbit = LZHUFF3_DICBIT;
+        break;
+    case LZHUFF4_METHOD_NUM:    /* -lh4- */
+        intf.dicbit = LZHUFF4_DICBIT;
+        break;
+    case LZHUFF5_METHOD_NUM:    /* -lh5- */
+        intf.dicbit = LZHUFF5_DICBIT;
+        break;
+    case LZHUFF6_METHOD_NUM:    /* -lh6- */
+        intf.dicbit = LZHUFF6_DICBIT;
+        break;
+    case LZHUFF7_METHOD_NUM:    /* -lh7- */
+        intf.dicbit = LZHUFF7_DICBIT;
+        break;
+    case LARC_METHOD_NUM:       /* -lzs- */
+        intf.dicbit = LARC_DICBIT;
+        break;
+    case LARC5_METHOD_NUM:      /* -lz5- */
+        intf.dicbit = LARC5_DICBIT;
+        break;
+    case LARC4_METHOD_NUM:      /* -lz4- */
+        intf.dicbit = LARC4_DICBIT;
+        break;
+    default:
+        warning("unknown method %d", method);
+        intf.dicbit = LZHUFF5_DICBIT; /* for backward compatibility */
+        break;
+    }
+
+    if (intf.dicbit == 0) { /* LZHUFF0_DICBIT or LARC4_DICBIT */
+        start_indicator(name,
+                        original_size, "Melting ",
+                        2048);
+        *read_sizep = copyfile(infp, outfp,
+                               original_size, 2, &crc);
+    }
+    else {
+        start_indicator(name,
+                        original_size, "Melting ",
+                        1 << intf.dicbit);
+        crc = decode(&intf);
+        *read_sizep = intf.read_size;
+    }
+
+    finish_indicator(name, "Melted  ");
+
+    return crc;
+}
diff --git a/vendor/gems/lhalib-0.8.1/ext/header.c b/vendor/gems/lhalib-0.8.1/ext/header.c
new file mode 100644 (file)
index 0000000..a567817
--- /dev/null
@@ -0,0 +1,1950 @@
+/* ------------------------------------------------------------------------ */
+/* LHa for UNIX                                                             */
+/*              header.c -- header manipulate functions                     */
+/*                                                                          */
+/*      Modified                Nobutaka Watazaki                           */
+/*                                                                          */
+/*  Original                                                Y.Tagawa        */
+/*  modified                                    1991.12.16  M.Oki           */
+/*  Ver. 1.10  Symbolic Link added              1993.10.01  N.Watazaki      */
+/*  Ver. 1.13b Symbolic Link Bug Fix            1994.08.22  N.Watazaki      */
+/*  Ver. 1.14  Source All chagned               1995.01.14  N.Watazaki      */
+/*  Ver. 1.14i bug fixed                        2000.10.06  t.okamoto       */
+/*  Ver. 1.14i Contributed UTF-8 convertion for Mac OS X                    */
+/*                                              2002.06.29  Hiroto Sakai    */
+/*  Ver. 1.14i autoconfiscated & rewritten      2003.02.23  Koji Arai       */
+/*   Modified arton for LhaLib */
+/* ------------------------------------------------------------------------ */
+#include "lha.h"
+
+#define DUMP_HEADER 1           /* for debugging */
+
+static char    *get_ptr;
+#define GET_BYTE()      (*get_ptr++ & 0xff)
+
+#if DUMP_HEADER
+static char    *start_ptr;
+#define setup_get(PTR)  (start_ptr = get_ptr = (PTR))
+#define get_byte()      dump_get_byte()
+#define skip_bytes(len) dump_skip_bytes(len)
+#else
+#define setup_get(PTR)  (get_ptr = (PTR))
+#define get_byte()      GET_BYTE()
+#define skip_bytes(len) (get_ptr += (len))
+#endif
+#define put_ptr         get_ptr
+#define setup_put(PTR)  (put_ptr = (PTR))
+#define put_byte(c)     (*put_ptr++ = (char)(c))
+
+int optional_archive_kanji_code = NONE;
+int optional_system_kanji_code = NONE;
+char *optional_archive_delim = NULL;
+char *optional_system_delim = NULL;
+int optional_filename_case = NONE;
+
+#ifdef MULTIBYTE_FILENAME
+int default_system_kanji_code = MULTIBYTE_FILENAME;
+#else
+int default_system_kanji_code = NONE;
+#endif
+
+int
+calc_sum(p, len)
+    char *p;
+    int len;
+{
+    int sum = 0;
+
+    while (len--) sum += *p++;
+
+    return sum & 0xff;
+}
+
+#if DUMP_HEADER
+static int
+dump_get_byte()
+{
+    int c;
+
+    if (verbose_listing && verbose > 1)
+        printf("%02d %2d: ", get_ptr - start_ptr, 1);
+    c = GET_BYTE();
+    if (verbose_listing && verbose > 1) {
+        if (isprint(c))
+            printf("%d(0x%02x) '%c'\n", c, c, c);
+        else
+            printf("%d(0x%02x)\n", c, c);
+    }
+    return c;
+}
+
+static void
+dump_skip_bytes(len)
+    int len;
+{
+    if (len == 0) return;
+    if (verbose_listing && verbose > 1) {
+        printf("%02d %2d: ", get_ptr - start_ptr, len);
+        while (len--)
+            printf("0x%02x ", GET_BYTE());
+        printf("... ignored\n");
+    }
+    else
+        get_ptr += len;
+}
+#endif
+
+static int
+get_word()
+{
+    int b0, b1;
+    int w;
+
+#if DUMP_HEADER
+    if (verbose_listing && verbose > 1)
+        printf("%02d %2d: ", get_ptr - start_ptr, 2);
+#endif
+    b0 = GET_BYTE();
+    b1 = GET_BYTE();
+    w = (b1 << 8) + b0;
+#if DUMP_HEADER
+    if (verbose_listing && verbose > 1)
+        printf("%d(0x%04x)\n", w, w);
+#endif
+    return w;
+}
+
+static void
+put_word(v)
+    unsigned int    v;
+{
+    put_byte(v);
+    put_byte(v >> 8);
+}
+
+static long
+get_longword()
+{
+    long b0, b1, b2, b3;
+    long l;
+
+#if DUMP_HEADER
+    if (verbose_listing && verbose > 1)
+        printf("%02d %2d: ", get_ptr - start_ptr, 4);
+#endif
+    b0 = GET_BYTE();
+    b1 = GET_BYTE();
+    b2 = GET_BYTE();
+    b3 = GET_BYTE();
+    l = (b3 << 24) + (b2 << 16) + (b1 << 8) + b0;
+#if DUMP_HEADER
+    if (verbose_listing && verbose > 1)
+        printf("%ld(0x%08lx)\n", l, l);
+#endif
+    return l;
+}
+
+static void
+put_longword(v)
+    long v;
+{
+    put_byte(v);
+    put_byte(v >> 8);
+    put_byte(v >> 16);
+    put_byte(v >> 24);
+}
+
+static int
+get_bytes(buf, len, size)
+    char *buf;
+    int len, size;
+{
+    int i;
+
+#if DUMP_HEADER
+    if (verbose_listing && verbose > 1)
+        printf("%02d %2d: \"", get_ptr - start_ptr, len);
+
+    for (i = 0; i < len; i++) {
+        if (i < size) buf[i] = get_ptr[i];
+
+        if (verbose_listing && verbose > 1) {
+            if (isprint(buf[i]))
+                printf("%c", buf[i]);
+            else
+                printf("\\x%02x", (unsigned char)buf[i]);
+        }
+    }
+
+    if (verbose_listing && verbose > 1)
+        printf("\"\n");
+#else
+    for (i = 0; i < len && i < size; i++)
+        buf[i] = get_ptr[i];
+#endif
+
+    get_ptr += len;
+    return i;
+}
+
+static void
+put_bytes(buf, len)
+    char *buf;
+    int len;
+{
+    int i;
+    for (i = 0; i < len; i++)
+        put_byte(buf[i]);
+}
+
+/* added by Koji Arai */
+void
+convert_filename(name, len, size,
+                 from_code, to_code,
+                 from_delim, to_delim,
+                 case_to)
+    char *name;
+    int len;                    /* length of name */
+    int size;                   /* size of name buffer */
+    int from_code, to_code, case_to;
+    char *from_delim, *to_delim;
+
+{
+    int i;
+#ifdef MULTIBYTE_FILENAME
+    char tmp[FILENAME_LENGTH];
+    int to_code_save = NONE;
+
+    if (from_code == CODE_CAP) {
+        len = cap_to_sjis(tmp, name, sizeof(tmp));
+        strncpy(name, tmp, size);
+        name[size-1] = 0;
+        len = strlen(name);
+        from_code = CODE_SJIS;
+    }
+
+    if (to_code == CODE_CAP) {
+        to_code_save = CODE_CAP;
+        to_code = CODE_SJIS;
+    }
+
+    if (from_code == CODE_SJIS && to_code == CODE_UTF8) {
+        for (i = 0; i < len; i++)
+            /* FIXME: provisionally fix for the Mac OS CoreFoundation */
+            if ((unsigned char)name[i] == LHA_PATHSEP)  name[i] = '/';
+        sjis_to_utf8(tmp, name, sizeof(tmp));
+        strncpy(name, tmp, size);
+        name[size-1] = 0;
+        len = strlen(name);
+        for (i = 0; i < len; i++)
+            if (name[i] == '/')  name[i] = LHA_PATHSEP;
+        from_code = CODE_UTF8;
+    }
+    else if (from_code == CODE_UTF8 && to_code == CODE_SJIS) {
+        for (i = 0; i < len; i++)
+            /* FIXME: provisionally fix for the Mac OS CoreFoundation */
+            if ((unsigned char)name[i] == LHA_PATHSEP)  name[i] = '/';
+        utf8_to_sjis(tmp, name, sizeof(tmp));
+        strncpy(name, tmp, size);
+        name[size-1] = 0;
+        len = strlen(name);
+        for (i = 0; i < len; i++)
+            if (name[i] == '/')  name[i] = LHA_PATHSEP;
+        from_code = CODE_SJIS;
+    }
+#endif
+
+    /* special case: if `name' has small lettter, not convert case. */
+    if (from_code == CODE_SJIS && case_to == TO_LOWER) {
+        for (i = 0; i < len; i++) {
+#ifdef MULTIBYTE_FILENAME
+            if (SJIS_FIRST_P(name[i]) && SJIS_SECOND_P(name[i+1]))
+                i++;
+            else
+#endif
+            if (islower(name[i])) {
+                case_to = NONE;
+                break;
+            }
+        }
+    }
+
+    for (i = 0; i < len; i ++) {
+#ifdef MULTIBYTE_FILENAME
+        if (from_code == CODE_EUC &&
+            (unsigned char)name[i] == 0x8e) {
+            if (to_code != CODE_SJIS) {
+                i++;
+                continue;
+            }
+
+            /* X0201 KANA */
+            memmove(name + i, name + i + 1, len - i);
+            len--;
+            continue;
+        }
+        if (from_code == CODE_SJIS && X0201_KANA_P(name[i])) {
+            if (to_code != CODE_EUC) {
+                continue;
+            }
+
+            if (len == size - 1) /* check overflow */
+                len--;
+            memmove(name+i+1, name+i, len-i);
+            name[i] = 0x8e;
+            i++;
+            len++;
+            continue;
+        }
+        if (from_code == CODE_EUC && (name[i] & 0x80) && (name[i+1] & 0x80)) {
+            int c1, c2;
+            if (to_code != CODE_SJIS) {
+                i++;
+                continue;
+            }
+
+            c1 = (unsigned char)name[i];
+            c2 = (unsigned char)name[i+1];
+            euc2sjis(&c1, &c2);
+            name[i] = c1;
+            name[i+1] = c2;
+            i++;
+            continue;
+        }
+        if (from_code == CODE_SJIS &&
+            SJIS_FIRST_P(name[i]) &&
+            SJIS_SECOND_P(name[i+1])) {
+            int c1, c2;
+
+            if (to_code != CODE_EUC) {
+                i++;
+                continue;
+            }
+
+            c1 = (unsigned char)name[i];
+            c2 = (unsigned char)name[i+1];
+            sjis2euc(&c1, &c2);
+            name[i] = c1;
+            name[i+1] = c2;
+            i++;
+            continue;
+        }
+#endif /* MULTIBYTE_FILENAME */
+        {
+            char *ptr;
+
+            /* transpose from_delim to to_delim */
+
+            if ((ptr = strchr(from_delim, name[i])) != NULL) {
+                name[i] = to_delim[ptr - from_delim];
+                continue;
+            }
+        }
+
+        if (case_to == TO_UPPER && islower(name[i])) {
+            name[i] = toupper(name[i]);
+            continue;
+        }
+        if (case_to == TO_LOWER && isupper(name[i])) {
+            name[i] = tolower(name[i]);
+            continue;
+        }
+    }
+
+#ifdef MULTIBYTE_FILENAME
+    if (to_code_save == CODE_CAP) {
+        len = sjis_to_cap(tmp, name, sizeof(tmp));
+        strncpy(name, tmp, size);
+        name[size-1] = 0;
+        len = strlen(name);
+    }
+#endif /* MULTIBYTE_FILENAME */
+}
+
+/*
+ * Generic (MS-DOS style) time stamp format (localtime):
+ *
+ *  31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16
+ * |<---- year-1980 --->|<- month ->|<--- day ---->|
+ *
+ *  15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0
+ * |<--- hour --->|<---- minute --->|<- second/2 ->|
+ *
+ */
+
+static time_t
+generic_to_unix_stamp(t)
+    long t;
+{
+    struct tm tm;
+
+#define subbits(n, off, len) (((n) >> (off)) & ((1 << (len))-1))
+
+    tm.tm_sec  = subbits(t,  0, 5) * 2;
+    tm.tm_min  = subbits(t,  5, 6);
+    tm.tm_hour = subbits(t, 11, 5);
+    tm.tm_mday = subbits(t, 16, 5);
+    tm.tm_mon  = subbits(t, 21, 4) - 1;
+    tm.tm_year = subbits(t, 25, 7) + 80;
+    tm.tm_isdst = -1;
+
+#if HAVE_MKTIME
+    return mktime(&tm);
+#else
+    return timelocal(&tm);
+#endif
+}
+
+static long
+unix_to_generic_stamp(t)
+    time_t t;
+{
+    struct tm *tm = localtime(&t);
+
+    tm->tm_year -= 80;
+    tm->tm_mon += 1;
+
+    return ((long)(tm->tm_year << 25) +
+            (tm->tm_mon  << 21) +
+            (tm->tm_mday << 16) +
+            (tm->tm_hour << 11) +
+            (tm->tm_min  << 5) +
+            (tm->tm_sec / 2));
+}
+
+static unsigned long
+wintime_to_unix_stamp()
+{
+#if HAVE_UINT64_T
+    uint64_t t;
+    uint64_t epoch = ((uint64_t)0x019db1de << 32) + 0xd53e8000;
+                     /* 0x019db1ded53e8000ULL: 1970-01-01 00:00:00 (UTC) */
+
+    t = (unsigned long)get_longword();
+    t |= (uint64_t)(unsigned long)get_longword() << 32;
+    t = (t - epoch) / 10000000;
+    return t;
+#else
+    int i, borrow;
+    unsigned long t, q, x;
+    unsigned long wintime[8];
+    unsigned long epoch[8] = {0x01,0x9d,0xb1,0xde, 0xd5,0x3e,0x80,0x00};
+                                /* 1970-01-01 00:00:00 (UTC) */
+    /* wintime -= epoch */
+    borrow = 0;
+    for (i = 7; i >= 0; i--) {
+        wintime[i] = (unsigned)get_byte() - epoch[i] - borrow;
+        borrow = (wintime[i] > 0xff) ? 1 : 0;
+        wintime[i] &= 0xff;
+    }
+
+    /* q = wintime / 10000000 */
+    t = q = 0;
+    x = 10000000;               /* x: 24bit */
+    for (i = 0; i < 8; i++) {
+        t = (t << 8) + wintime[i]; /* 24bit + 8bit. t must be 32bit variable */
+        q <<= 8;                   /* q must be 32bit (time_t) */
+        q += t / x;
+        t %= x;     /* 24bit */
+    }
+    return q;
+#endif
+}
+
+/*
+ * extended header
+ *
+ *             size  field name
+ *  --------------------------------
+ *  base header:         :
+ *           2 or 4  next-header size  [*1]
+ *  --------------------------------------
+ *  ext header:   1  ext-type            ^
+ *                ?  contents            | [*1] next-header size
+ *           2 or 4  next-header size    v
+ *  --------------------------------------
+ *
+ *  on level 1, 2 header:
+ *    size field is 2 bytes
+ *  on level 3 header:
+ *    size field is 4 bytes
+ */
+
+static ssize_t
+get_extended_header(fp, hdr, header_size, hcrc)
+    FILE *fp;
+    LzHeader *hdr;
+    size_t header_size;
+    unsigned int *hcrc;
+{
+    char data[LZHEADER_STORAGE];
+    int name_length;
+    char dirname[FILENAME_LENGTH];
+    int dir_length = 0;
+    int i;
+    ssize_t whole_size = header_size;
+    int ext_type;
+    int n = 1 + hdr->size_field_length; /* `ext-type' + `next-header size' */
+
+    if (hdr->header_level == 0)
+        return 0;
+
+    name_length = strlen(hdr->name);
+
+    while (header_size) {
+        setup_get(data);
+        if (sizeof(data) < header_size) {
+            error("header size (%ld) too large.", header_size);
+            exit(1);
+        }
+
+        if (fread(data, header_size, 1, fp) == 0) {
+            error("Invalid header (LHa file ?)");
+            return -1;
+        }
+
+        ext_type = get_byte();
+        switch (ext_type) {
+        case 0:
+            /* header crc (CRC-16) */
+            hdr->header_crc = get_word();
+            /* clear buffer for CRC calculation. */
+            data[1] = data[2] = 0;
+            skip_bytes(header_size - n - 2);
+            break;
+        case 1:
+            /* filename */
+            name_length =
+                get_bytes(hdr->name, header_size-n, sizeof(hdr->name)-1);
+            hdr->name[name_length] = 0;
+            break;
+        case 2:
+            /* directory */
+            dir_length = get_bytes(dirname, header_size-n, sizeof(dirname)-1);
+            dirname[dir_length] = 0;
+            break;
+        case 0x40:
+            /* MS-DOS attribute */
+            hdr->attribute = get_word();
+            break;
+        case 0x41:
+            /* Windows time stamp (FILETIME structure) */
+            /* it is time in 100 nano seconds since 1601-01-01 00:00:00 */
+
+            skip_bytes(8); /* create time is ignored */
+
+            /* set last modified time */
+            if (hdr->header_level >= 2)
+                skip_bytes(8);  /* time_t has been already set */
+            else
+                hdr->unix_last_modified_stamp = wintime_to_unix_stamp();
+
+            skip_bytes(8); /* last access time is ignored */
+
+            break;
+        case 0x50:
+            /* UNIX permission */
+            hdr->unix_mode = get_word();
+            break;
+        case 0x51:
+            /* UNIX gid and uid */
+            hdr->unix_gid = get_word();
+            hdr->unix_uid = get_word();
+            break;
+        case 0x52:
+            /* UNIX group name */
+            i = get_bytes(hdr->group, header_size-n, sizeof(hdr->group)-1);
+            hdr->group[i] = '\0';
+            break;
+        case 0x53:
+            /* UNIX user name */
+            i = get_bytes(hdr->user, header_size-n, sizeof(hdr->user)-1);
+            hdr->user[i] = '\0';
+            break;
+        case 0x54:
+            /* UNIX last modified time */
+            hdr->unix_last_modified_stamp = (time_t) get_longword();
+            break;
+        default:
+            /* other headers */
+            /* 0x39: multi-disk header
+               0x3f: uncompressed comment
+               0x42: 64bit large file size
+               0x48-0x4f(?): reserved for authenticity verification
+               0x7d: encapsulation
+               0x7e: extended attribute - platform information
+               0x7f: extended attribute - permission, owner-id and timestamp
+                     (level 3 on OS/2)
+               0xc4: compressed comment (dict size: 4096)
+               0xc5: compressed comment (dict size: 8192)
+               0xc6: compressed comment (dict size: 16384)
+               0xc7: compressed comment (dict size: 32768)
+               0xc8: compressed comment (dict size: 65536)
+               0xd0-0xdf(?): operating systemm specific information
+               0xfc: encapsulation (another opinion)
+               0xfe: extended attribute - platform information(another opinion)
+               0xff: extended attribute - permission, owner-id and timestamp
+                     (level 3 on UNLHA32) */
+            if (verbose)
+                warning("unknown extended header 0x%02x", ext_type);
+            skip_bytes(header_size - n);
+            break;
+        }
+
+        if (hcrc)
+            *hcrc = calccrc(*hcrc, data, header_size);
+
+        if (hdr->size_field_length == 2)
+            whole_size += header_size = get_word();
+        else
+            whole_size += header_size = get_longword();
+    }
+
+    /* concatenate dirname and filename */
+    if (dir_length) {
+        if (name_length + dir_length >= sizeof(hdr->name)) {
+            warning("the length of pathname \"%s%s\" is too long.",
+                    dirname, hdr->name);
+            name_length = sizeof(hdr->name) - dir_length - 1;
+            hdr->name[name_length] = 0;
+        }
+        strcat(dirname, hdr->name); /* ok */
+        strcpy(hdr->name, dirname); /* ok */
+        name_length += dir_length;
+    }
+
+    return whole_size;
+}
+
+#define I_HEADER_SIZE           0               /* level 0,1,2   */
+#define I_HEADER_CHECKSUM       1               /* level 0,1     */
+#define I_METHOD                2               /* level 0,1,2,3 */
+#define I_PACKED_SIZE           7               /* level 0,1,2,3 */
+#define I_ATTRIBUTE             19              /* level 0,1,2,3 */
+#define I_HEADER_LEVEL          20              /* level 0,1,2,3 */
+
+#define COMMON_HEADER_SIZE      21      /* size of common part */
+
+#define I_GENERIC_HEADER_SIZE 24 /* + name_length */
+#define I_LEVEL0_HEADER_SIZE  36 /* + name_length (unix extended) */
+#define I_LEVEL1_HEADER_SIZE  27 /* + name_length */
+#define I_LEVEL2_HEADER_SIZE  26 /* + padding */
+#define I_LEVEL3_HEADER_SIZE  32
+
+/*
+ * level 0 header
+ *
+ *
+ * offset  size  field name
+ * ----------------------------------
+ *     0      1  header size    [*1]
+ *     1      1  header sum
+ *            ---------------------------------------
+ *     2      5  method ID                         ^
+ *     7      4  packed size    [*2]               |
+ *    11      4  original size                     |
+ *    15      2  time                              |
+ *    17      2  date                              |
+ *    19      1  attribute                         | [*1] header size (X+Y+22)
+ *    20      1  level (0x00 fixed)                |
+ *    21      1  name length                       |
+ *    22      X  pathname                          |
+ * X +22      2  file crc (CRC-16)                 |
+ * X +24      Y  ext-header(old style)             v
+ * -------------------------------------------------
+ * X+Y+24        data                              ^
+ *                 :                               | [*2] packed size
+ *                 :                               v
+ * -------------------------------------------------
+ *
+ * ext-header(old style)
+ *     0      1  ext-type ('U')
+ *     1      1  minor version
+ *     2      4  UNIX time
+ *     6      2  mode
+ *     8      2  uid
+ *    10      2  gid
+ *
+ * attribute (MS-DOS)
+ *    bit1  read only
+ *    bit2  hidden
+ *    bit3  system
+ *    bit4  volume label
+ *    bit5  directory
+ *    bit6  archive bit (need to backup)
+ *
+ */
+static int
+get_header_level0(fp, hdr, data)
+    FILE *fp;
+    LzHeader *hdr;
+    char *data;
+{
+    size_t header_size;
+    ssize_t extend_size;
+    int checksum;
+    int name_length;
+    int i;
+
+    hdr->size_field_length = 2; /* in bytes */
+    hdr->header_size = header_size = get_byte();
+    checksum = get_byte();
+
+    if (fread(data + COMMON_HEADER_SIZE,
+              header_size + 2 - COMMON_HEADER_SIZE, 1, fp) == 0) {
+        error("Invalid header (LHarc file ?)");
+        return FALSE;   /* finish */
+    }
+
+    if (calc_sum(data + I_METHOD, header_size) != checksum) {
+        error("Checksum error (LHarc file?)");
+        return FALSE;
+    }
+
+    get_bytes(hdr->method, 5, sizeof(hdr->method));
+    hdr->packed_size = get_longword();
+    hdr->original_size = get_longword();
+    hdr->unix_last_modified_stamp = generic_to_unix_stamp(get_longword());
+    hdr->attribute = get_byte(); /* MS-DOS attribute */
+    hdr->header_level = get_byte();
+    name_length = get_byte();
+    i = get_bytes(hdr->name, name_length, sizeof(hdr->name)-1);
+    hdr->name[i] = '\0';
+
+    /* defaults for other type */
+    hdr->unix_mode = UNIX_FILE_REGULAR | UNIX_RW_RW_RW;
+    hdr->unix_gid = 0;
+    hdr->unix_uid = 0;
+
+    extend_size = header_size+2 - name_length - 24;
+
+    if (extend_size < 0) {
+        if (extend_size == -2) {
+            /* CRC field is not given */
+            hdr->extend_type = EXTEND_GENERIC;
+            hdr->has_crc = FALSE;
+
+            return TRUE;
+        } 
+
+        error("Unkonwn header (lha file?)");
+        exit(1);
+    }
+
+    hdr->has_crc = TRUE;
+    hdr->crc = get_word();
+
+    if (extend_size == 0)
+        return TRUE;
+
+    hdr->extend_type = get_byte();
+    extend_size--;
+
+    if (hdr->extend_type == EXTEND_UNIX) {
+        if (extend_size >= 11) {
+            hdr->minor_version = get_byte();
+            hdr->unix_last_modified_stamp = (time_t) get_longword();
+            hdr->unix_mode = get_word();
+            hdr->unix_uid = get_word();
+            hdr->unix_gid = get_word();
+            extend_size -= 11;
+        } else {
+            hdr->extend_type = EXTEND_GENERIC;
+        }
+    }
+    if (extend_size > 0)
+        skip_bytes(extend_size);
+
+    hdr->header_size += 2;
+    return TRUE;
+}
+
+/*
+ * level 1 header
+ *
+ *
+ * offset   size  field name
+ * -----------------------------------
+ *     0       1  header size   [*1]
+ *     1       1  header sum
+ *             -------------------------------------
+ *     2       5  method ID                        ^
+ *     7       4  skip size     [*2]               |
+ *    11       4  original size                    |
+ *    15       2  time                             |
+ *    17       2  date                             |
+ *    19       1  attribute (0x20 fixed)           | [*1] header size (X+Y+25)
+ *    20       1  level (0x01 fixed)               |
+ *    21       1  name length                      |
+ *    22       X  filename                         |
+ * X+ 22       2  file crc (CRC-16)                |
+ * X+ 24       1  OS ID                            |
+ * X +25       Y  ???                              |
+ * X+Y+25      2  next-header size                 v
+ * -------------------------------------------------
+ * X+Y+27      Z  ext-header                       ^
+ *                 :                               |
+ * -----------------------------------             | [*2] skip size
+ * X+Y+Z+27       data                             |
+ *                 :                               v
+ * -------------------------------------------------
+ *
+ */
+static int
+get_header_level1(fp, hdr, data)
+    FILE *fp;
+    LzHeader *hdr;
+    char *data;
+{
+    size_t header_size;
+    ssize_t extend_size;
+    int checksum;
+    int name_length;
+    int i, dummy;
+
+    hdr->size_field_length = 2; /* in bytes */
+    hdr->header_size = header_size = get_byte();
+    checksum = get_byte();
+
+    if (fread(data + COMMON_HEADER_SIZE,
+              header_size + 2 - COMMON_HEADER_SIZE, 1, fp) == 0) {
+        error("Invalid header (LHarc file ?)");
+        return FALSE;   /* finish */
+    }
+
+    if (calc_sum(data + I_METHOD, header_size) != checksum) {
+        error("Checksum error (LHarc file?)");
+        return FALSE;
+    }
+
+    get_bytes(hdr->method, 5, sizeof(hdr->method));
+    hdr->packed_size = get_longword(); /* skip size */
+    hdr->original_size = get_longword();
+    hdr->unix_last_modified_stamp = generic_to_unix_stamp(get_longword());
+    hdr->attribute = get_byte(); /* 0x20 fixed */
+    hdr->header_level = get_byte();
+
+    name_length = get_byte();
+    i = get_bytes(hdr->name, name_length, sizeof(hdr->name)-1);
+    hdr->name[i] = '\0';
+
+    /* defaults for other type */
+    hdr->unix_mode = UNIX_FILE_REGULAR | UNIX_RW_RW_RW;
+    hdr->unix_gid = 0;
+    hdr->unix_uid = 0;
+
+    hdr->has_crc = TRUE;
+    hdr->crc = get_word();
+    hdr->extend_type = get_byte();
+
+    dummy = header_size+2 - name_length - I_LEVEL1_HEADER_SIZE;
+    if (dummy > 0)
+        skip_bytes(dummy); /* skip old style extend header */
+
+    extend_size = get_word();
+    extend_size = get_extended_header(fp, hdr, extend_size, 0);
+    if (extend_size == -1)
+        return FALSE;
+
+    /* On level 1 header, size fields should be adjusted. */
+    /* the `packed_size' field contains the extended header size. */
+    /* the `header_size' field does not. */
+    hdr->packed_size -= extend_size;
+    hdr->header_size += extend_size + 2;
+
+    return TRUE;
+}
+
+/*
+ * level 2 header
+ *
+ *
+ * offset   size  field name
+ * --------------------------------------------------
+ *     0       2  total header size [*1]           ^
+ *             -----------------------             |
+ *     2       5  method ID                        |
+ *     7       4  packed size       [*2]           |
+ *    11       4  original size                    |
+ *    15       4  time                             |
+ *    19       1  RESERVED (0x20 fixed)            | [*1] total header size
+ *    20       1  level (0x02 fixed)               |      (X+26+(1))
+ *    21       2  file crc (CRC-16)                |
+ *    23       1  OS ID                            |
+ *    24       2  next-header size                 |
+ * -----------------------------------             |
+ *    26       X  ext-header                       |
+ *                 :                               |
+ * -----------------------------------             |
+ * X +26      (1) padding                          v
+ * -------------------------------------------------
+ * X +26+(1)      data                             ^
+ *                 :                               | [*2] packed size
+ *                 :                               v
+ * -------------------------------------------------
+ *
+ */
+static int
+get_header_level2(fp, hdr, data)
+    FILE *fp;
+    LzHeader *hdr;
+    char *data;
+{
+    size_t header_size;
+    ssize_t extend_size;
+    int padding;
+    unsigned int hcrc;
+
+    hdr->size_field_length = 2; /* in bytes */
+    hdr->header_size = header_size = get_word();
+
+    if (fread(data + COMMON_HEADER_SIZE,
+              I_LEVEL2_HEADER_SIZE - COMMON_HEADER_SIZE, 1, fp) == 0) {
+        error("Invalid header (LHarc file ?)");
+        return FALSE;   /* finish */
+    }
+
+    get_bytes(hdr->method, 5, sizeof(hdr->method));
+    hdr->packed_size = get_longword();
+    hdr->original_size = get_longword();
+    hdr->unix_last_modified_stamp = get_longword();
+    hdr->attribute = get_byte(); /* reserved */
+    hdr->header_level = get_byte();
+
+    /* defaults for other type */
+    hdr->unix_mode = UNIX_FILE_REGULAR | UNIX_RW_RW_RW;
+    hdr->unix_gid = 0;
+    hdr->unix_uid = 0;
+
+    hdr->has_crc = TRUE;
+    hdr->crc = get_word();
+    hdr->extend_type = get_byte();
+    extend_size = get_word();
+
+    INITIALIZE_CRC(hcrc);
+    hcrc = calccrc(hcrc, data, get_ptr - data);
+
+    extend_size = get_extended_header(fp, hdr, extend_size, &hcrc);
+    if (extend_size == -1)
+        return FALSE;
+
+    padding = header_size - I_LEVEL2_HEADER_SIZE - extend_size;
+    while (padding--)           /* padding should be 0 or 1 */
+        hcrc = UPDATE_CRC(hcrc, fgetc(fp));
+
+    if (hdr->header_crc != hcrc)
+        error("header CRC error");
+
+    return TRUE;
+}
+
+/*
+ * level 3 header
+ *
+ *
+ * offset   size  field name
+ * --------------------------------------------------
+ *     0       2  size field length (4 fixed)      ^
+ *     2       5  method ID                        |
+ *     7       4  packed size       [*2]           |
+ *    11       4  original size                    |
+ *    15       4  time                             |
+ *    19       1  RESERVED (0x20 fixed)            | [*1] total header size
+ *    20       1  level (0x03 fixed)               |      (X+32)
+ *    21       2  file crc (CRC-16)                |
+ *    23       1  OS ID                            |
+ *    24       4  total header size [*1]           |
+ *    28       4  next-header size                 |
+ * -----------------------------------             |
+ *    32       X  ext-header                       |
+ *                 :                               v
+ * -------------------------------------------------
+ * X +32          data                             ^
+ *                 :                               | [*2] packed size
+ *                 :                               v
+ * -------------------------------------------------
+ *
+ */
+static int
+get_header_level3(fp, hdr, data)
+    FILE *fp;
+    LzHeader *hdr;
+    char *data;
+{
+    size_t header_size;
+    ssize_t extend_size;
+    int padding;
+    unsigned int hcrc;
+
+    hdr->size_field_length = get_word();
+
+    if (fread(data + COMMON_HEADER_SIZE,
+              I_LEVEL3_HEADER_SIZE - COMMON_HEADER_SIZE, 1, fp) == 0) {
+        error("Invalid header (LHarc file ?)");
+        return FALSE;   /* finish */
+    }
+
+    get_bytes(hdr->method, 5, sizeof(hdr->method));
+    hdr->packed_size = get_longword();
+    hdr->original_size = get_longword();
+    hdr->unix_last_modified_stamp = get_longword();
+    hdr->attribute = get_byte(); /* reserved */
+    hdr->header_level = get_byte();
+
+    /* defaults for other type */
+    hdr->unix_mode = UNIX_FILE_REGULAR | UNIX_RW_RW_RW;
+    hdr->unix_gid = 0;
+    hdr->unix_uid = 0;
+
+    hdr->has_crc = TRUE;
+    hdr->crc = get_word();
+    hdr->extend_type = get_byte();
+    hdr->header_size = header_size = get_longword();
+    extend_size = get_longword();
+
+    INITIALIZE_CRC(hcrc);
+    hcrc = calccrc(hcrc, data, get_ptr - data);
+
+    extend_size = get_extended_header(fp, hdr, extend_size, &hcrc);
+    if (extend_size == -1)
+        return FALSE;
+
+    padding = header_size - I_LEVEL3_HEADER_SIZE - extend_size;
+    while (padding--)           /* padding should be 0 */
+        hcrc = UPDATE_CRC(hcrc, fgetc(fp));
+
+    if (hdr->header_crc != hcrc)
+        error("header CRC error");
+
+    return TRUE;
+}
+
+boolean
+get_header(fp, hdr)
+    FILE *fp;
+    LzHeader *hdr;
+{
+    char data[LZHEADER_STORAGE];
+
+    int archive_kanji_code = CODE_SJIS;
+    int system_kanji_code = default_system_kanji_code;
+    char *archive_delim = "\377\\"; /* `\' is for level 0 header and
+                                       broken archive. */
+    char *system_delim = "//";
+    int filename_case = NONE;
+    int end_mark;
+
+    memset(hdr, 0, sizeof(LzHeader));
+
+    setup_get(data);
+
+    if ((end_mark = getc(fp)) == EOF || end_mark == 0) {
+        return FALSE;           /* finish */
+    }
+    data[0] = end_mark;
+
+    if (fread(data + 1, COMMON_HEADER_SIZE - 1, 1, fp) == 0) {
+        error("Invalid header (LHarc file ?)");
+        return FALSE;           /* finish */
+    }
+
+    switch (data[I_HEADER_LEVEL]) {
+    case 0:
+        if (get_header_level0(fp, hdr, data) == FALSE)
+            return FALSE;
+        break;
+    case 1:
+        if (get_header_level1(fp, hdr, data) == FALSE)
+            return FALSE;
+        break;
+    case 2:
+        if (get_header_level2(fp, hdr, data) == FALSE)
+            return FALSE;
+        break;
+    case 3:
+        if (get_header_level3(fp, hdr, data) == FALSE)
+            return FALSE;
+        break;
+    default:
+        error("Unknown level header (level %d)", data[I_HEADER_LEVEL]);
+        return FALSE;
+    }
+
+    /* filename conversion */
+    switch (hdr->extend_type) {
+    case EXTEND_MSDOS:
+        filename_case = noconvertcase ? NONE : TO_LOWER;
+        break;
+    case EXTEND_HUMAN:
+    case EXTEND_OS68K:
+    case EXTEND_XOSK:
+    case EXTEND_UNIX:
+    case EXTEND_JAVA:
+        filename_case = NONE;
+        break;
+
+    case EXTEND_MACOS:
+        archive_delim = "\377/:\\";
+                          /* `\' is for level 0 header and broken archive. */
+        system_delim = "/://";
+        filename_case = NONE;
+        break;
+
+    default:
+        filename_case = noconvertcase ? NONE : TO_LOWER;
+        break;
+    }
+
+    if (optional_archive_kanji_code)
+        archive_kanji_code = optional_archive_kanji_code;
+    if (optional_system_kanji_code)
+        system_kanji_code = optional_system_kanji_code;
+    if (optional_archive_delim)
+        archive_delim = optional_archive_delim;
+    if (optional_system_delim)
+        system_delim = optional_system_delim;
+    if (optional_filename_case)
+        filename_case = optional_filename_case;
+
+    /* kanji code and delimiter conversion */
+    convert_filename(hdr->name, strlen(hdr->name), sizeof(hdr->name),
+                     archive_kanji_code,
+                     system_kanji_code,
+                     archive_delim, system_delim, filename_case);
+
+    if ((hdr->unix_mode & UNIX_FILE_SYMLINK) == UNIX_FILE_SYMLINK) {
+        char *p;
+        /* split symbolic link */
+        p = strchr(hdr->name, '|');
+        if (p) {
+            /* hdr->name is symbolic link name */
+            /* hdr->realname is real name */
+            *p = 0;
+            strcpy(hdr->realname, p+1); /* ok */
+        }
+        else
+            error("unknown symlink name \"%s\"", hdr->name);
+    }
+
+    return TRUE;
+}
+
+/* skip SFX header */
+int
+seek_lha_header(fp)
+    FILE *fp;
+{
+    unsigned char   buffer[64 * 1024]; /* max seek size */
+    unsigned char  *p;
+    int             n;
+
+    n = fread(buffer, 1, sizeof(buffer), fp);
+
+    for (p = buffer; p < buffer + n; p++) {
+        if (! (p[I_METHOD]=='-' && p[I_METHOD+1]=='l' && p[I_METHOD+4]=='-'))
+            continue;
+        /* found "-l??-" keyword (as METHOD type string) */
+
+        /* level 0 or 1 header */
+        if ((p[I_HEADER_LEVEL] == 0 || p[I_HEADER_LEVEL] == 1)
+            && p[I_HEADER_SIZE] > 20
+            && p[I_HEADER_CHECKSUM] == calc_sum(p+2, p[I_HEADER_SIZE])) {
+            if (fseeko(fp, (p - buffer) - n, SEEK_CUR) == -1)
+                fatal_error("cannot seek header");
+            return 0;
+        }
+
+        /* level 2 header */
+        if (p[I_HEADER_LEVEL] == 2
+            && p[I_HEADER_SIZE] >= 24
+            && p[I_ATTRIBUTE] == 0x20) {
+            if (fseeko(fp, (p - buffer) - n, SEEK_CUR) == -1)
+                fatal_error("cannot seek header");
+            return 0;
+        }
+    }
+
+    if (fseeko(fp, -n, SEEK_CUR) == -1)
+        fatal_error("cannot seek header");
+    return -1;
+}
+
+
+/* remove leading `xxxx/..' */
+static char *
+remove_leading_dots(char *path)
+{
+    char *first = path;
+    char *ptr = 0;
+
+    if (strcmp(first, "..") == 0) {
+        warning("Removing leading `..' from member name.");
+        return first+1;         /* change to "." */
+    }
+
+    if (strstr(first, "..") == 0)
+        return first;
+
+    while (path && *path) {
+
+        if (strcmp(path, "..") == 0)
+            ptr = path = path+2;
+        else if (strncmp(path, "../", 3) == 0)
+            ptr = path = path+3;
+        else
+            path = strchr(path, '/');
+
+        if (path && *path == '/') {
+            path++;
+        }
+    }
+
+    if (ptr) {
+        warning("Removing leading `%.*s' from member name.", ptr-first, first);
+        return ptr;
+    }
+
+    return first;
+}
+
+void
+init_header(name, v_stat, hdr)
+    char           *name;
+    struct stat    *v_stat;
+    LzHeader       *hdr;
+{
+    int             len;
+
+    memset(hdr, 0, sizeof(LzHeader));
+
+    /* the `method' member is rewrote by the encoding function.
+       but need set for empty files */
+    memcpy(hdr->method, LZHUFF0_METHOD, METHOD_TYPE_STORAGE);
+
+    hdr->packed_size = 0;
+    hdr->original_size = v_stat->st_size;
+    hdr->attribute = GENERIC_ATTRIBUTE;
+    hdr->header_level = header_level;
+    len = str_safe_copy(hdr->name,
+                        remove_leading_dots(name),
+                        sizeof(hdr->name));
+    hdr->crc = 0x0000;
+    hdr->extend_type = EXTEND_UNIX;
+    hdr->unix_last_modified_stamp = v_stat->st_mtime;
+    /* since 00:00:00 JAN.1.1970 */
+#ifdef NOT_COMPATIBLE_MODE
+    /* Please need your modification in this space. */
+#else
+    hdr->unix_mode = v_stat->st_mode;
+#endif
+
+    hdr->unix_uid = v_stat->st_uid;
+    hdr->unix_gid = v_stat->st_gid;
+
+#if INCLUDE_OWNER_NAME_IN_HEADER
+#if HAVE_GETPWUID
+    {
+        struct passwd *ent = getpwuid(hdr->unix_uid);
+
+        if (ent) {
+            strncpy(hdr->user, ent->pw_name, sizeof(hdr->user));
+            if (hdr->user[sizeof(hdr->user)-1])
+                hdr->user[sizeof(hdr->user)-1] = 0;
+        }
+    }
+#endif
+#if HAVE_GETGRGID
+    {
+        struct group *ent = getgrgid(hdr->unix_gid);
+
+        if (ent) {
+            strncpy(hdr->group, ent->gr_name, sizeof(hdr->group));
+            if (hdr->group[sizeof(hdr->group)-1])
+                hdr->group[sizeof(hdr->group)-1] = 0;
+        }
+    }
+#endif
+#endif /* INCLUDE_OWNER_NAME_IN_HEADER */
+    if (is_directory(v_stat)) {
+        memcpy(hdr->method, LZHDIRS_METHOD, METHOD_TYPE_STORAGE);
+        hdr->attribute = GENERIC_DIRECTORY_ATTRIBUTE;
+        hdr->original_size = 0;
+        if (len > 0 && hdr->name[len - 1] != '/') {
+            if (len < sizeof(hdr->name)-1)
+                strcpy(&hdr->name[len++], "/"); /* ok */
+            else
+                warning("the length of dirname \"%s\" is too long.",
+                        hdr->name);
+        }
+    }
+
+#ifdef S_IFLNK
+    if (is_symlink(v_stat)) {
+        memcpy(hdr->method, LZHDIRS_METHOD, METHOD_TYPE_STORAGE);
+        hdr->attribute = GENERIC_DIRECTORY_ATTRIBUTE;
+        hdr->original_size = 0;
+        readlink(name, hdr->realname, sizeof(hdr->realname));
+    }
+#endif
+}
+
+static void
+write_unix_info(hdr)
+    LzHeader *hdr;
+{
+    /* UNIX specific informations */
+
+    put_word(5);            /* size */
+    put_byte(0x50);         /* permission */
+    put_word(hdr->unix_mode);
+
+    put_word(7);            /* size */
+    put_byte(0x51);         /* gid and uid */
+    put_word(hdr->unix_gid);
+    put_word(hdr->unix_uid);
+
+    if (hdr->group[0]) {
+        int len = strlen(hdr->group);
+        put_word(len + 3);  /* size */
+        put_byte(0x52);     /* group name */
+        put_bytes(hdr->group, len);
+    }
+
+    if (hdr->user[0]) {
+        int len = strlen(hdr->user);
+        put_word(len + 3);  /* size */
+        put_byte(0x53);     /* user name */
+        put_bytes(hdr->user, len);
+    }
+
+    if (hdr->header_level == 1) {
+        put_word(7);        /* size */
+        put_byte(0x54);     /* time stamp */
+        put_longword(hdr->unix_last_modified_stamp);
+    }
+}
+
+static size_t
+write_header_level0(data, hdr, pathname)
+    LzHeader *hdr;
+    char *data, *pathname;
+{
+    int limit;
+    int name_length;
+    size_t header_size;
+
+    setup_put(data);
+    memset(data, 0, LZHEADER_STORAGE);
+
+    put_byte(0x00);             /* header size */
+    put_byte(0x00);             /* check sum */
+    put_bytes(hdr->method, 5);
+    put_longword(hdr->packed_size);
+    put_longword(hdr->original_size);
+    put_longword(unix_to_generic_stamp(hdr->unix_last_modified_stamp));
+    put_byte(hdr->attribute);
+    put_byte(hdr->header_level); /* level 0 */
+
+    /* write pathname (level 0 header contains the directory part) */
+    name_length = strlen(pathname);
+    if (generic_format)
+        limit = 255 - I_GENERIC_HEADER_SIZE + 2;
+    else
+        limit = 255 - I_LEVEL0_HEADER_SIZE + 2;
+
+    if (name_length > limit) {
+        warning("the length of pathname \"%s\" is too long.", pathname);
+        name_length = limit;
+    }
+    put_byte(name_length);
+    put_bytes(pathname, name_length);
+    put_word(hdr->crc);
+
+    if (generic_format) {
+        header_size = I_GENERIC_HEADER_SIZE + name_length - 2;
+        data[I_HEADER_SIZE] = header_size;
+        data[I_HEADER_CHECKSUM] = calc_sum(data + I_METHOD, header_size);
+    } else {
+        /* write old-style extend header */
+        put_byte(EXTEND_UNIX);
+        put_byte(CURRENT_UNIX_MINOR_VERSION);
+        put_longword(hdr->unix_last_modified_stamp);
+        put_word(hdr->unix_mode);
+        put_word(hdr->unix_uid);
+        put_word(hdr->unix_gid);
+
+        /* size of extended header is 12 */
+        header_size = I_LEVEL0_HEADER_SIZE + name_length - 2;
+        data[I_HEADER_SIZE] = header_size;
+        data[I_HEADER_CHECKSUM] = calc_sum(data + I_METHOD, header_size);
+    }
+
+    return header_size + 2;
+}
+
+static size_t
+write_header_level1(data, hdr, pathname)
+    LzHeader *hdr;
+    char *data, *pathname;
+{
+    int name_length, dir_length, limit;
+    char *basename, *dirname;
+    size_t header_size;
+    char *extend_header_top;
+    size_t extend_header_size;
+
+    basename = strrchr(pathname, LHA_PATHSEP);
+    if (basename) {
+        basename++;
+        name_length = strlen(basename);
+        dirname = pathname;
+        dir_length = basename - dirname;
+    }
+    else {
+        basename = pathname;
+        name_length = strlen(basename);
+        dirname = "";
+        dir_length = 0;
+    }
+
+    setup_put(data);
+    memset(data, 0, LZHEADER_STORAGE);
+
+    put_byte(0x00);             /* header size */
+    put_byte(0x00);             /* check sum */
+    put_bytes(hdr->method, 5);
+    put_longword(hdr->packed_size);
+    put_longword(hdr->original_size);
+    put_longword(unix_to_generic_stamp(hdr->unix_last_modified_stamp));
+    put_byte(0x20);
+    put_byte(hdr->header_level); /* level 1 */
+
+    /* level 1 header: write filename (basename only) */
+    limit = 255 - I_LEVEL1_HEADER_SIZE + 2;
+    if (name_length > limit) {
+        put_byte(0);            /* name length */
+    }
+    else {
+        put_byte(name_length);
+        put_bytes(basename, name_length);
+    }
+
+    put_word(hdr->crc);
+
+    if (generic_format)
+        put_byte(0x00);
+    else
+        put_byte(EXTEND_UNIX);
+
+    /* write extend header from here. */
+
+    extend_header_top = put_ptr+2; /* +2 for the field `next header size' */
+    header_size = extend_header_top - data - 2;
+
+    /* write filename and dirname */
+
+    if (name_length > limit) {
+        put_word(name_length + 3); /* size */
+        put_byte(0x01);         /* filename */
+        put_bytes(basename, name_length);
+    }
+
+    if (dir_length > 0) {
+        put_word(dir_length + 3); /* size */
+        put_byte(0x02);         /* dirname */
+        put_bytes(dirname, dir_length);
+    }
+
+    if (!generic_format)
+        write_unix_info(hdr);
+
+    put_word(0x0000);           /* next header size */
+
+    extend_header_size = put_ptr - extend_header_top;
+    /* On level 1 header, the packed size field is contains the ext-header */
+    hdr->packed_size += put_ptr - extend_header_top;
+
+    /* put `skip size' */
+    setup_put(data + I_PACKED_SIZE);
+    put_longword(hdr->packed_size);
+
+    data[I_HEADER_SIZE] = header_size;
+    data[I_HEADER_CHECKSUM] = calc_sum(data + I_METHOD, header_size);
+
+    return header_size + extend_header_size + 2;
+}
+
+static size_t
+write_header_level2(data, hdr, pathname)
+    LzHeader *hdr;
+    char *data, *pathname;
+{
+    int name_length, dir_length;
+    char *basename, *dirname;
+    size_t header_size;
+    char *extend_header_top;
+    char *headercrc_ptr;
+    unsigned int hcrc;
+
+    basename = strrchr(pathname, LHA_PATHSEP);
+    if (basename) {
+        basename++;
+        name_length = strlen(basename);
+        dirname = pathname;
+        dir_length = basename - dirname;
+    }
+    else {
+        basename = pathname;
+        name_length = strlen(basename);
+        dirname = "";
+        dir_length = 0;
+    }
+
+    setup_put(data);
+    memset(data, 0, LZHEADER_STORAGE);
+
+    put_word(0x0000);           /* header size */
+    put_bytes(hdr->method, 5);
+    put_longword(hdr->packed_size);
+    put_longword(hdr->original_size);
+    put_longword(hdr->unix_last_modified_stamp);
+    put_byte(0x20);
+    put_byte(hdr->header_level); /* level 2 */
+
+    put_word(hdr->crc);
+
+    if (generic_format)
+        put_byte(0x00);
+    else
+        put_byte(EXTEND_UNIX);
+
+    /* write extend header from here. */
+
+    extend_header_top = put_ptr+2; /* +2 for the field `next header size' */
+
+    /* write common header */
+    put_word(5);
+    put_byte(0x00);
+    headercrc_ptr = put_ptr;
+    put_word(0x0000);           /* header CRC */
+
+    /* write filename and dirname */
+    /* must have this header, even if the name_length is 0. */
+    put_word(name_length + 3);  /* size */
+    put_byte(0x01);             /* filename */
+    put_bytes(basename, name_length);
+
+    if (dir_length > 0) {
+        put_word(dir_length + 3); /* size */
+        put_byte(0x02);         /* dirname */
+        put_bytes(dirname, dir_length);
+    }
+
+    if (!generic_format)
+        write_unix_info(hdr);
+
+    put_word(0x0000);           /* next header size */
+
+    header_size = put_ptr - data;
+    if ((header_size & 0xff) == 0) {
+        /* cannot put zero at the first byte on level 2 header. */
+        /* adjust header size. */
+        put_byte(0);            /* padding */
+        header_size++;
+    }
+
+    /* put header size */
+    setup_put(data + I_HEADER_SIZE);
+    put_word(header_size);
+
+    /* put header CRC in extended header */
+    INITIALIZE_CRC(hcrc);
+    hcrc = calccrc(hcrc, data, (unsigned int) header_size);
+    setup_put(headercrc_ptr);
+    put_word(hcrc);
+
+    return header_size;
+}
+
+void
+write_header(fp, hdr)
+    FILE           *fp;
+    LzHeader       *hdr;
+{
+    size_t header_size;
+    char data[LZHEADER_STORAGE];
+
+    int archive_kanji_code = CODE_SJIS;
+    int system_kanji_code = default_system_kanji_code;
+    char *archive_delim = "\377";
+    char *system_delim = "/";
+    int filename_case = NONE;
+    char pathname[FILENAME_LENGTH];
+
+    if (optional_archive_kanji_code)
+        archive_kanji_code = optional_archive_kanji_code;
+    if (optional_system_kanji_code)
+        system_kanji_code = optional_system_kanji_code;
+
+    if (generic_format)
+        filename_case = TO_UPPER;
+
+    if (hdr->header_level == 0) {
+        archive_delim = "\\";
+    }
+
+    if ((hdr->unix_mode & UNIX_FILE_SYMLINK) == UNIX_FILE_SYMLINK) {
+        char *p;
+        p = strchr(hdr->name, '|');
+        if (p) {
+            error("symlink name \"%s\" contains '|' char. change it into '_'",
+                  hdr->name);
+            *p = '_';
+        }
+        if (xsnprintf(pathname, sizeof(pathname),
+                      "%s|%s", hdr->name, hdr->realname) == -1)
+            error("file name is too long (%s -> %s)", hdr->name, hdr->realname);
+    }
+    else {
+        strncpy(pathname, hdr->name, sizeof(pathname));
+        pathname[sizeof(pathname)-1] = 0;
+    }
+
+    convert_filename(pathname, strlen(pathname), sizeof(pathname),
+                     system_kanji_code,
+                     archive_kanji_code,
+                     system_delim, archive_delim, filename_case);
+
+    switch (hdr->header_level) {
+    case 0:
+        header_size = write_header_level0(data, hdr, pathname);
+        break;
+    case 1:
+        header_size = write_header_level1(data, hdr, pathname);
+        break;
+    case 2:
+        header_size = write_header_level2(data, hdr, pathname);
+        break;
+    default:
+        error("Unknown level header (level %d)", hdr->header_level);
+        exit(1);
+    }
+
+    if (fwrite(data, header_size, 1, fp) == 0)
+        fatal_error("Cannot write to temporary file");
+}
+
+#if MULTIBYTE_FILENAME
+
+#if defined(__APPLE__)  /* Added by Hiroto Sakai */
+
+#include <CoreFoundation/CFString.h>
+#include <CoreFoundation/CFStringEncodingExt.h>
+
+/* this is not need for Mac OS X v 10.2 later */
+enum {
+  kCFStringEncodingAllowLossyConversion = 1,
+  kCFStringEncodingBasicDirectionLeftToRight = (1 << 1),
+  kCFStringEncodingBasicDirectionRightToLeft = (1 << 2),
+  kCFStringEncodingSubstituteCombinings = (1 << 3),
+  kCFStringEncodingComposeCombinings = (1 << 4),
+  kCFStringEncodingIgnoreCombinings = (1 << 5),
+  kCFStringEncodingUseCanonical = (1 << 6),
+  kCFStringEncodingUseHFSPlusCanonical = (1 << 7),
+  kCFStringEncodingPrependBOM = (1 << 8),
+  kCFStringEncodingDisableCorporateArea = (1 << 9),
+  kCFStringEncodingASCIICompatibleConversion = (1 << 10),
+};
+
+static int
+ConvertEncodingToUTF8(const char* inCStr,
+                      char* outUTF8Buffer,
+                      int outUTF8BufferLength,
+                      unsigned long scriptEncoding,
+                      unsigned long flags)
+{
+    unsigned long unicodeChars;
+    unsigned long srcCharsUsed;
+    unsigned long usedByteLen = 0;
+    UniChar uniStr[512];
+    unsigned long cfResult;
+
+    cfResult = CFStringEncodingBytesToUnicode(scriptEncoding,
+                                              flags,
+                                              (char *)inCStr,
+                                              strlen(inCStr),
+                                              &srcCharsUsed,
+                                              uniStr,
+                                              512,
+                                              &unicodeChars);
+    if (cfResult == 0) {
+        cfResult = CFStringEncodingUnicodeToBytes(kCFStringEncodingUTF8,
+                                                  flags,
+                                                  uniStr,
+                                                  unicodeChars,
+                                                  &srcCharsUsed,
+                                                  (char*)outUTF8Buffer,
+                                                  outUTF8BufferLength - 1,
+                                                  &usedByteLen);
+        outUTF8Buffer[usedByteLen] = '\0';
+    }
+
+    return cfResult;
+}
+
+static int
+ConvertUTF8ToEncoding(const char* inUTF8Buf,
+                      int inUTF8BufLength,
+                      char* outCStrBuffer,
+                      int outCStrBufferLength,
+                      unsigned long scriptEncoding,
+                      unsigned long flags)
+{
+    unsigned long unicodeChars;
+    unsigned long srcCharsUsed;
+    unsigned long usedByteLen = 0;
+    UniChar uniStr[256];
+    unsigned long cfResult;
+
+    cfResult = CFStringEncodingBytesToUnicode(kCFStringEncodingUTF8,
+                                              flags,
+                                              (char*)inUTF8Buf,
+                                              inUTF8BufLength,
+                                              &srcCharsUsed,
+                                              uniStr,
+                                              255,
+                                              &unicodeChars);
+    if (cfResult == 0) {
+        cfResult = CFStringEncodingUnicodeToBytes(scriptEncoding,
+                                                  flags,
+                                                  uniStr,
+                                                  unicodeChars,
+                                                  &srcCharsUsed,
+                                                  (char*)outCStrBuffer,
+                                                  outCStrBufferLength - 1,
+                                                  &usedByteLen);
+        outCStrBuffer[usedByteLen] = '\0';
+    }
+
+    return cfResult;
+}
+
+#elif HAVE_ICONV
+#include <iconv.h>
+
+static int
+ConvertEncodingByIconv(const char *src, char *dst, int dstsize,
+                       const char *srcEnc, const char *dstEnc)
+{
+    iconv_t ic;
+    static char szTmpBuf[2048];
+    char *src_p;
+    char *dst_p;
+    size_t sLen;
+    size_t iLen;
+
+    dst_p = &szTmpBuf[0];
+    iLen = (size_t)sizeof(szTmpBuf)-1;
+    src_p = (char *)src;
+    sLen = (size_t)strlen(src);
+    memset(szTmpBuf, 0, sizeof(szTmpBuf));
+    memset(dst, 0, dstsize);
+
+    ic = iconv_open(dstEnc, srcEnc);
+    if (ic == (iconv_t)-1) {
+        error("iconv_open() failure: %s", strerror(errno));
+        return -1;
+    }
+
+    if (iconv(ic, &src_p, &sLen, &dst_p, &iLen) == (size_t)-1) {
+        error("iconv() failure: %s", strerror(errno));
+        iconv_close(ic);
+        return -1;
+    }
+
+    strncpy(dst, szTmpBuf, dstsize);
+
+    iconv_close(ic);
+
+    return 0;
+}
+#endif /* defined(__APPLE__) */
+
+char *
+sjis_to_utf8(char *dst, const char *src, size_t dstsize)
+{
+#if defined(__APPLE__)
+  dst[0] = '\0';
+  if (ConvertEncodingToUTF8(src, dst, dstsize,
+                            kCFStringEncodingDOSJapanese,
+                            kCFStringEncodingUseHFSPlusCanonical) == 0)
+      return dst;
+#elif HAVE_ICONV
+  if (ConvertEncodingByIconv(src, dst, dstsize, "SJIS", "UTF-8") != -1)
+      return dst;
+#else
+  error("not support utf-8 conversion");
+#endif
+
+  if (dstsize < 1) return dst;
+  dst[dstsize-1] = 0;
+  return strncpy(dst, src, dstsize-1);
+}
+
+char *
+utf8_to_sjis(char *dst, const char *src, size_t dstsize)
+{
+#if defined(__APPLE__)
+  int srclen;
+
+  dst[0] = '\0';
+  srclen = strlen(src);
+  if (ConvertUTF8ToEncoding(src, srclen, dst, dstsize,
+                            kCFStringEncodingDOSJapanese,
+                            kCFStringEncodingUseHFSPlusCanonical) == 0)
+      return dst;
+#elif HAVE_ICONV
+  if (ConvertEncodingByIconv(src, dst, dstsize, "UTF-8", "SJIS") != -1)
+      return dst;
+#else
+  error("not support utf-8 conversion");
+#endif
+
+  if (dstsize < 1) return dst;
+  dst[dstsize-1] = 0;
+  return strncpy(dst, src, dstsize-1);
+}
+
+/*
+ * SJIS <-> EUC ÊÑ´¹´Ø¿ô
+ * ¡ÖÆüËܸì¾ðÊó½èÍý¡×   ¥½¥Õ¥È¥Ð¥ó¥¯(³ô)
+ *  ¤è¤êÈ´¿è(by Koji Arai)
+ */
+void
+euc2sjis(int *p1, int *p2)
+{
+    unsigned char c1 = *p1 & 0x7f;
+    unsigned char c2 = *p2 & 0x7f;
+    int rowoff = c1 < 0x5f ? 0x70 : 0xb0;
+    int celoff = c1 % 2 ? (c2 > 0x5f ? 0x20 : 0x1f) : 0x7e;
+    *p1 = ((c1 + 1) >> 1) + rowoff;
+    *p2 += celoff - 0x80;
+}
+
+void
+sjis2euc(int *p1, int *p2)
+{
+    unsigned char c1 = *p1;
+    unsigned char c2 = *p2;
+    int adjust = c2 < 0x9f;
+    int rowoff = c1 < 0xa0 ? 0x70 : 0xb0;
+    int celoff = adjust ? (c2 > 0x7f ? 0x20 : 0x1f) : 0x7e;
+    *p1 = ((c1 - rowoff) << 1) - adjust;
+    *p2 -= celoff;
+
+    *p1 |= 0x80;
+    *p2 |= 0x80;
+}
+
+static int
+hex2int(int c)
+{
+    switch (c) {
+    case '0': case '1': case '2': case '3': case '4':
+    case '5': case '6': case '7': case '8': case '9':
+        return c - '0';
+
+    case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
+        return c - 'a' + 10;
+
+    case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
+        return c - 'A' + 10;
+    default:
+        return -1;
+    }
+}
+
+static int
+int2hex(int c)
+{
+    switch (c) {
+    case 0: case 1: case 2: case 3: case 4:
+    case 5: case 6: case 7: case 8: case 9:
+        return c + '0';
+
+    case 10: case 11: case 12: case 13: case 14: case 15:
+        return c + 'a' - 10;
+
+    default:
+        return -1;
+    }
+}
+
+int
+cap_to_sjis(char *dst, const char *src, size_t dstsize)
+{
+    int i, j;
+    size_t len = strlen(src);
+    int a, b;
+
+    for (i = j = 0; i < len && i < dstsize; i++) {
+        if (src[i] != ':') {
+            dst[j++] = src[i];
+            continue;
+        }
+
+        i++;
+        a = hex2int((unsigned char)src[i]);
+        b = hex2int((unsigned char)src[i+1]);
+
+        if (a == -1 || b == -1) {
+            /* leave as it */
+            dst[j++] = ':';
+            strncpy(dst+j, src+i, dstsize-j);
+            dst[dstsize-1] = 0;
+            return strlen(dst);
+        }
+
+        i++;
+
+        dst[j++] = a * 16 + b;
+    }
+    dst[j] = 0;
+    return j;
+}
+
+int
+sjis_to_cap(char *dst, const char *src, size_t dstsize)
+{
+    int i, j;
+    size_t len = strlen(src);
+    int a, b;
+
+    for (i = j = 0; i < len && i < dstsize; i++) {
+        if (src[i] == ':') {
+            strncpy(dst+j, ":3a", dstsize-j);
+            dst[dstsize-1] = 0;
+            j = strlen(dst);
+            continue;
+        }
+        if (isprint(src[i])) {
+            dst[j++] = src[i];
+            continue;
+        }
+
+        if (j + 3 >= dstsize) {
+            dst[j] = 0;
+            return j;
+        }
+
+        a = int2hex((unsigned char)src[i] / 16);
+        b = int2hex((unsigned char)src[i] % 16);
+
+        dst[j++] = ':';
+        dst[j++] = a;
+        dst[j++] = b;
+    }
+    dst[j] = 0;
+    return j;
+}
+#endif /* MULTIBYTE_FILENAME */
diff --git a/vendor/gems/lhalib-0.8.1/ext/huf.c b/vendor/gems/lhalib-0.8.1/ext/huf.c
new file mode 100644 (file)
index 0000000..2698500
--- /dev/null
@@ -0,0 +1,490 @@
+/* ------------------------------------------------------------------------ */
+/* LHa for UNIX                                                             */
+/*              huf.c -- new static Huffman                                 */
+/*                                                                          */
+/*      Modified                Nobutaka Watazaki                           */
+/*                                                                          */
+/*  Ver. 1.14   Source All chagned              1995.01.14  N.Watazaki      */
+/*  Ver. 1.14i  Support LH7 & Bug Fixed         2000.10. 6  t.okamoto       */
+/* ------------------------------------------------------------------------ */
+#include "lha.h"
+
+#if HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+
+#if STDC_HEADERS
+#include <stdlib.h>
+#else
+extern char *malloc ();
+#endif
+
+/* ------------------------------------------------------------------------ */
+unsigned short left[2 * NC - 1], right[2 * NC - 1];
+
+unsigned short c_code[NC];      /* encode */
+unsigned short pt_code[NPT];    /* encode */
+
+unsigned short c_table[4096];   /* decode */
+unsigned short pt_table[256];   /* decode */
+
+unsigned short c_freq[2 * NC - 1]; /* encode */
+unsigned short p_freq[2 * NP - 1]; /* encode */
+unsigned short t_freq[2 * NT - 1]; /* encode */
+
+unsigned char  c_len[NC];
+unsigned char  pt_len[NPT];
+
+static unsigned char *buf;      /* encode */
+static unsigned int bufsiz;     /* encode */
+static unsigned short blocksize; /* decode */
+static unsigned short output_pos, output_mask; /* encode */
+
+static int pbit;
+static int np;
+/* ------------------------------------------------------------------------ */
+/*                              Encording                                   */
+/* ------------------------------------------------------------------------ */
+static void
+count_t_freq(/*void*/)
+{
+    short           i, k, n, count;
+
+    for (i = 0; i < NT; i++)
+        t_freq[i] = 0;
+    n = NC;
+    while (n > 0 && c_len[n - 1] == 0)
+        n--;
+    i = 0;
+    while (i < n) {
+        k = c_len[i++];
+        if (k == 0) {
+            count = 1;
+            while (i < n && c_len[i] == 0) {
+                i++;
+                count++;
+            }
+            if (count <= 2)
+                t_freq[0] += count;
+            else if (count <= 18)
+                t_freq[1]++;
+            else if (count == 19) {
+                t_freq[0]++;
+                t_freq[1]++;
+            }
+            else
+                t_freq[2]++;
+        } else
+            t_freq[k + 2]++;
+    }
+}
+
+/* ------------------------------------------------------------------------ */
+static void
+write_pt_len(n, nbit, i_special)
+    short           n;
+    short           nbit;
+    short           i_special;
+{
+    short           i, k;
+
+    while (n > 0 && pt_len[n - 1] == 0)
+        n--;
+    putbits(nbit, n);
+    i = 0;
+    while (i < n) {
+        k = pt_len[i++];
+        if (k <= 6)
+            putbits(3, k);
+        else
+            /* k=7 -> 1110  k=8 -> 11110  k=9 -> 111110 ... */
+            putbits(k - 3, USHRT_MAX << 1);
+        if (i == i_special) {
+            while (i < 6 && pt_len[i] == 0)
+                i++;
+            putbits(2, i - 3);
+        }
+    }
+}
+
+/* ------------------------------------------------------------------------ */
+static void
+write_c_len(/*void*/)
+{
+    short           i, k, n, count;
+
+    n = NC;
+    while (n > 0 && c_len[n - 1] == 0)
+        n--;
+    putbits(CBIT, n);
+    i = 0;
+    while (i < n) {
+        k = c_len[i++];
+        if (k == 0) {
+            count = 1;
+            while (i < n && c_len[i] == 0) {
+                i++;
+                count++;
+            }
+            if (count <= 2) {
+                for (k = 0; k < count; k++)
+                    putcode(pt_len[0], pt_code[0]);
+            }
+            else if (count <= 18) {
+                putcode(pt_len[1], pt_code[1]);
+                putbits(4, count - 3);
+            }
+            else if (count == 19) {
+                putcode(pt_len[0], pt_code[0]);
+                putcode(pt_len[1], pt_code[1]);
+                putbits(4, 15);
+            }
+            else {
+                putcode(pt_len[2], pt_code[2]);
+                putbits(CBIT, count - 20);
+            }
+        }
+        else
+            putcode(pt_len[k + 2], pt_code[k + 2]);
+    }
+}
+
+/* ------------------------------------------------------------------------ */
+static void
+encode_c(c)
+    short           c;
+{
+    putcode(c_len[c], c_code[c]);
+}
+
+/* ------------------------------------------------------------------------ */
+static void
+encode_p(p)
+    unsigned short  p;
+{
+    unsigned short  c, q;
+
+    c = 0;
+    q = p;
+    while (q) {
+        q >>= 1;
+        c++;
+    }
+    putcode(pt_len[c], pt_code[c]);
+    if (c > 1)
+        putbits(c - 1, p);
+}
+
+/* ------------------------------------------------------------------------ */
+static void
+send_block( /* void */ )
+{
+    unsigned char   flags;
+    unsigned short  i, k, root, pos, size;
+
+    root = make_tree(NC, c_freq, c_len, c_code);
+    size = c_freq[root];
+    putbits(16, size);
+    if (root >= NC) {
+        count_t_freq();
+        root = make_tree(NT, t_freq, pt_len, pt_code);
+        if (root >= NT) {
+            write_pt_len(NT, TBIT, 3);
+        } else {
+            putbits(TBIT, 0);
+            putbits(TBIT, root);
+        }
+        write_c_len();
+    } else {
+        putbits(TBIT, 0);
+        putbits(TBIT, 0);
+        putbits(CBIT, 0);
+        putbits(CBIT, root);
+    }
+    root = make_tree(np, p_freq, pt_len, pt_code);
+    if (root >= np) {
+        write_pt_len(np, pbit, -1);
+    }
+    else {
+        putbits(pbit, 0);
+        putbits(pbit, root);
+    }
+    pos = 0;
+    for (i = 0; i < size; i++) {
+        if (i % CHAR_BIT == 0)
+            flags = buf[pos++];
+        else
+            flags <<= 1;
+        if (flags & (1 << (CHAR_BIT - 1))) {
+            encode_c(buf[pos++] + (1 << CHAR_BIT));
+            k = buf[pos++] << CHAR_BIT;
+            k += buf[pos++];
+            encode_p(k);
+        } else
+            encode_c(buf[pos++]);
+        if (unpackable)
+            return;
+    }
+    for (i = 0; i < NC; i++)
+        c_freq[i] = 0;
+    for (i = 0; i < np; i++)
+        p_freq[i] = 0;
+}
+
+/* ------------------------------------------------------------------------ */
+/* lh4, 5, 6, 7 */
+void
+output_st1(c, p)
+    unsigned short  c;
+    unsigned short  p;
+{
+    static unsigned short cpos;
+
+    output_mask >>= 1;
+    if (output_mask == 0) {
+        output_mask = 1 << (CHAR_BIT - 1);
+        if (output_pos >= bufsiz - 3 * CHAR_BIT) {
+            send_block();
+            if (unpackable)
+                return;
+            output_pos = 0;
+        }
+        cpos = output_pos++;
+        buf[cpos] = 0;
+    }
+    buf[output_pos++] = (unsigned char) c;
+    c_freq[c]++;
+    if (c >= (1 << CHAR_BIT)) {
+        buf[cpos] |= output_mask;
+        buf[output_pos++] = (unsigned char) (p >> CHAR_BIT);
+        buf[output_pos++] = (unsigned char) p;
+        c = 0;
+        while (p) {
+            p >>= 1;
+            c++;
+        }
+        p_freq[c]++;
+    }
+}
+
+/* ------------------------------------------------------------------------ */
+unsigned char  *
+alloc_buf( /* void */ )
+{
+    bufsiz = 16 * 1024 *2;  /* 65408U; */ /* t.okamoto */
+    while ((buf = (unsigned char *) malloc(bufsiz)) == NULL) {
+        bufsiz = (bufsiz / 10) * 9;
+        if (bufsiz < 4 * 1024)
+            fatal_error("Not enough memory");
+    }
+    return buf;
+}
+
+/* ------------------------------------------------------------------------ */
+/* lh4, 5, 6, 7 */
+void
+encode_start_st1( /* void */ )
+{
+    int             i;
+
+    switch (dicbit) {
+    case LZHUFF4_DICBIT:
+    case LZHUFF5_DICBIT: pbit = 4; np = LZHUFF5_DICBIT + 1; break;
+    case LZHUFF6_DICBIT: pbit = 5; np = LZHUFF6_DICBIT + 1; break;
+    case LZHUFF7_DICBIT: pbit = 5; np = LZHUFF7_DICBIT + 1; break;
+    default:
+        fatal_error("Cannot use %d bytes dictionary", 1 << dicbit);
+    }
+
+    for (i = 0; i < NC; i++)
+        c_freq[i] = 0;
+    for (i = 0; i < np; i++)
+        p_freq[i] = 0;
+    output_pos = output_mask = 0;
+    init_putbits();
+    init_code_cache();
+    buf[0] = 0;
+}
+
+/* ------------------------------------------------------------------------ */
+/* lh4, 5, 6, 7 */
+void
+encode_end_st1( /* void */ )
+{
+    if (!unpackable) {
+        send_block();
+        putbits(CHAR_BIT - 1, 0);   /* flush remaining bits */
+    }
+}
+
+/* ------------------------------------------------------------------------ */
+/*                              decoding                                    */
+/* ------------------------------------------------------------------------ */
+static void
+read_pt_len(nn, nbit, i_special)
+    short           nn;
+    short           nbit;
+    short           i_special;
+{
+    int           i, c, n;
+
+    n = getbits(nbit);
+    if (n == 0) {
+        c = getbits(nbit);
+        for (i = 0; i < nn; i++)
+            pt_len[i] = 0;
+        for (i = 0; i < 256; i++)
+            pt_table[i] = c;
+    }
+    else {
+        i = 0;
+        while (i < n) {
+            c = peekbits(3);
+            if (c != 7)
+                fillbuf(3);
+            else {
+                unsigned short  mask = 1 << (16 - 4);
+                while (mask & bitbuf) {
+                    mask >>= 1;
+                    c++;
+                }
+                fillbuf(c - 3);
+            }
+
+            pt_len[i++] = c;
+            if (i == i_special) {
+                c = getbits(2);
+                while (--c >= 0)
+                    pt_len[i++] = 0;
+            }
+        }
+        while (i < nn)
+            pt_len[i++] = 0;
+        make_table(nn, pt_len, 8, pt_table);
+    }
+}
+
+/* ------------------------------------------------------------------------ */
+static void
+read_c_len( /* void */ )
+{
+    short           i, c, n;
+
+    n = getbits(CBIT);
+    if (n == 0) {
+        c = getbits(CBIT);
+        for (i = 0; i < NC; i++)
+            c_len[i] = 0;
+        for (i = 0; i < 4096; i++)
+            c_table[i] = c;
+    } else {
+        i = 0;
+        while (i < n) {
+            c = pt_table[peekbits(8)];
+            if (c >= NT) {
+                unsigned short  mask = 1 << (16 - 9);
+                do {
+                    if (bitbuf & mask)
+                        c = right[c];
+                    else
+                        c = left[c];
+                    mask >>= 1;
+                } while (c >= NT);
+            }
+            fillbuf(pt_len[c]);
+            if (c <= 2) {
+                if (c == 0)
+                    c = 1;
+                else if (c == 1)
+                    c = getbits(4) + 3;
+                else
+                    c = getbits(CBIT) + 20;
+                while (--c >= 0)
+                    c_len[i++] = 0;
+            }
+            else
+                c_len[i++] = c - 2;
+        }
+        while (i < NC)
+            c_len[i++] = 0;
+        make_table(NC, c_len, 12, c_table);
+    }
+}
+
+/* ------------------------------------------------------------------------ */
+/* lh4, 5, 6, 7 */
+unsigned short
+decode_c_st1( /*void*/ )
+{
+    unsigned short  j, mask;
+
+    if (blocksize == 0) {
+        blocksize = getbits(16);
+        read_pt_len(NT, TBIT, 3);
+        read_c_len();
+        read_pt_len(np, pbit, -1);
+    }
+    blocksize--;
+    j = c_table[peekbits(12)];
+    if (j < NC)
+        fillbuf(c_len[j]);
+    else {
+        fillbuf(12);
+        mask = 1 << (16 - 1);
+        do {
+            if (bitbuf & mask)
+                j = right[j];
+            else
+                j = left[j];
+            mask >>= 1;
+        } while (j >= NC);
+        fillbuf(c_len[j] - 12);
+    }
+    return j;
+}
+
+/* ------------------------------------------------------------------------ */
+/* lh4, 5, 6, 7 */
+unsigned short
+decode_p_st1( /* void */ )
+{
+    unsigned short  j, mask;
+
+    j = pt_table[peekbits(8)];
+    if (j < np)
+        fillbuf(pt_len[j]);
+    else {
+        fillbuf(8);
+        mask = 1 << (16 - 1);
+        do {
+            if (bitbuf & mask)
+                j = right[j];
+            else
+                j = left[j];
+            mask >>= 1;
+        } while (j >= np);
+        fillbuf(pt_len[j] - 8);
+    }
+    if (j != 0)
+        j = (1 << (j - 1)) + getbits(j - 1);
+    return j;
+}
+
+/* ------------------------------------------------------------------------ */
+/* lh4, 5, 6, 7 */
+void
+decode_start_st1( /* void */ )
+{
+    switch (dicbit) {
+    case LZHUFF4_DICBIT:
+    case LZHUFF5_DICBIT: pbit = 4; np = LZHUFF5_DICBIT + 1; break;
+    case LZHUFF6_DICBIT: pbit = 5; np = LZHUFF6_DICBIT + 1; break;
+    case LZHUFF7_DICBIT: pbit = 5; np = LZHUFF7_DICBIT + 1; break;
+    default:
+        fatal_error("Cannot use %d bytes dictionary", 1 << dicbit);
+    }
+
+    init_getbits();
+    init_code_cache();
+    blocksize = 0;
+}
diff --git a/vendor/gems/lhalib-0.8.1/ext/larc.c b/vendor/gems/lhalib-0.8.1/ext/larc.c
new file mode 100644 (file)
index 0000000..42509c7
--- /dev/null
@@ -0,0 +1,92 @@
+/* ------------------------------------------------------------------------ */
+/* LHa for UNIX                                                             */
+/*              larc.c -- extra *.lzs                                       */
+/*                                                                          */
+/*      Modified                Nobutaka Watazaki                           */
+/*                                                                          */
+/*  Ver. 1.14   Source All chagned              1995.01.14  N.Watazaki      */
+/* ------------------------------------------------------------------------ */
+#include "lha.h"
+
+/* ------------------------------------------------------------------------ */
+static int      flag, flagcnt, matchpos;
+/* ------------------------------------------------------------------------ */
+/* lzs */
+unsigned short
+decode_c_lzs( /*void*/ )
+{
+    if (getbits(1)) {
+        return getbits(8);
+    }
+    else {
+        matchpos = getbits(11);
+        return getbits(4) + 0x100;
+    }
+}
+
+/* ------------------------------------------------------------------------ */
+/* lzs */
+unsigned short
+decode_p_lzs( /*void*/ )
+{
+    return (loc - matchpos - MAGIC0) & 0x7ff;
+}
+
+/* ------------------------------------------------------------------------ */
+/* lzs */
+void
+decode_start_lzs( /*void*/ )
+{
+    init_getbits();
+    init_code_cache();
+}
+
+/* ------------------------------------------------------------------------ */
+/* lz5 */
+unsigned short
+decode_c_lz5( /*void*/ )
+{
+    int             c;
+
+    if (flagcnt == 0) {
+        flagcnt = 8;
+        flag = getc(infile);
+    }
+    flagcnt--;
+    c = getc(infile);
+    if ((flag & 1) == 0) {
+        matchpos = c;
+        c = getc(infile);
+        matchpos += (c & 0xf0) << 4;
+        c &= 0x0f;
+        c += 0x100;
+    }
+    flag >>= 1;
+    return c;
+}
+
+/* ------------------------------------------------------------------------ */
+/* lz5 */
+unsigned short
+decode_p_lz5( /*void*/ )
+{
+    return (loc - matchpos - MAGIC5) & 0xfff;
+}
+
+/* ------------------------------------------------------------------------ */
+/* lz5 */
+void
+decode_start_lz5( /*void*/ )
+{
+    int             i;
+
+    flagcnt = 0;
+    for (i = 0; i < 256; i++)
+        memset(&text[i * 13 + 18], i, 13);
+    for (i = 0; i < 256; i++)
+        text[256 * 13 + 18 + i] = i;
+    for (i = 0; i < 256; i++)
+        text[256 * 13 + 256 + 18 + i] = 255 - i;
+    memset(&text[256 * 13 + 512 + 18], 0, 128);
+    memset(&text[256 * 13 + 512 + 128 + 18], ' ', 128 - 18);
+}
diff --git a/vendor/gems/lhalib-0.8.1/ext/lha.h b/vendor/gems/lhalib-0.8.1/ext/lha.h
new file mode 100644 (file)
index 0000000..7d9a9eb
--- /dev/null
@@ -0,0 +1,404 @@
+/* ------------------------------------------------------------------------ */
+/* LHa for UNIX    Archiver Driver                                          */
+/*                                                                          */
+/*      Modified                Nobutaka Watazaki                           */
+/*                                                                          */
+/*  Ver. 1.14   Soruce All chagned              1995.01.14  N.Watazaki      */
+/*  Ver. 1.14i  Modified and bug fixed          2000.10.06  t.okamoto       */
+/* ------------------------------------------------------------------------ */
+/*      Modified arton for LhaLib */
+/*
+    Included...
+        lharc.h     interface.h     slidehuf.h
+*/
+
+#include "ruby.h"
+
+#include <stdio.h>
+#include <time.h>
+#include <errno.h>
+#include <ctype.h>
+#include <sys/types.h>
+#ifdef HAVE_SYS_FILE_H
+#include <sys/file.h>
+#endif
+#include <sys/stat.h>
+#include <signal.h>
+
+#if HAVE_INTTYPES_H
+# include <inttypes.h>
+#else
+# if HAVE_STDINT_H
+#  include <stdint.h>
+# endif
+#endif
+
+#if STDC_HEADERS
+# include <string.h>
+#else
+# if !HAVE_STRCHR
+#  define strchr index
+#  define strrchr rindex
+# endif
+char *strchr (), *strrchr ();
+# if !HAVE_MEMCPY
+#  define memcmp(s1, s2, n) bcmp ((s1), (s2), (n))
+#  define memcpy(d, s, n) bcopy ((s), (d), (n))
+#  define memmove(d, s, n) bcopy ((s), (d), (n))
+# endif
+#endif
+
+#if STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# if HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif
+
+#ifndef NULL
+#define NULL ((char *)0)
+#endif
+
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#if STDC_HEADERS
+# include <stdarg.h>
+# define va_init(a,b) va_start(a,b)
+#else
+# include <varargs.h>
+# define va_init(a,b) va_start(a)
+#endif
+
+#if HAVE_PWD_H
+# include <pwd.h>
+#endif
+#if HAVE_GRP_H
+# include <grp.h>
+#endif
+
+#if !HAVE_SETUID
+typedef int uid_t;
+#endif
+#if !HAVE_SETGID
+typedef int gid_t;
+#endif
+
+#if !HAVE_UINT64_T
+# define HAVE_UINT64_T 1
+# if SIZEOF_LONG == 8
+    typedef unsigned long uint64_t;
+# elif _WIN32
+    typedef unsigned __int64 uint64_t;
+# elif HAVE_LONG_LONG
+    typedef unsigned long long uint64_t;
+# else
+#  undef HAVE_UINT64_T
+# endif
+#endif
+
+#if _WIN32
+ #if !HAVE_SSIZE_T
+  typedef long ssize_t;
+ #endif
+#endif
+
+#if HAVE_SYS_TIME_H
+# include <sys/time.h>
+#else
+# include <time.h>
+#endif
+
+#if !defined(_WIN32)
+ #if HAVE_UTIME_H
+  #include <utime.h>
+ #else
+  struct utimbuf {
+    time_t actime;
+    time_t modtime;
+  };
+  int utime(const char *, struct utimbuf *);
+ #endif
+#endif
+
+#if HAVE_DIRENT_H
+# include <dirent.h>
+# define NAMLEN(dirent) strlen((dirent)->d_name)
+#else
+# define dirent direct
+# define NAMLEN(dirent) (dirent)->d_namlen
+# if HAVE_SYS_NDIR_H
+#  include <sys/ndir.h>
+# endif
+# if HAVE_SYS_DIR_H
+#  include <sys/dir.h>
+# endif
+# if HAVE_NDIR_H
+#  include <ndir.h>
+# endif
+# ifdef NONSYSTEM_DIR_LIBRARY           /* no use ?? */
+#  include "lhdir.h"
+# endif
+#endif
+
+#if HAVE_FNMATCH_H
+# include <fnmatch.h>
+#else
+int fnmatch(const char *pattern, const char *string, int flags);
+# define FNM_PATHNAME 1
+# define FNM_NOESCAPE 2
+# define FNM_PERIOD   4
+#endif
+
+#ifndef SEEK_SET
+#define SEEK_SET        0
+#define SEEK_CUR        1
+#define SEEK_END        2
+#endif  /* SEEK_SET */
+
+#if HAVE_LIMITS_H
+#include <limits.h>
+#else
+
+#ifndef CHAR_BIT
+#define CHAR_BIT 8
+#endif
+
+#ifndef UCHAR_MAX
+#define UCHAR_MAX ((1<<(sizeof(unsigned char)*8))-1)
+#endif
+
+#ifndef USHRT_MAX
+#define USHRT_MAX ((1<<(sizeof(unsigned short)*8))-1)
+#endif
+
+#ifndef SHRT_MAX
+#define SHRT_MAX ((1<<(sizeof(short)*8-1))-1)
+#endif
+
+#ifndef SHRT_MIN
+#define SHRT_MIN (SHRT_MAX-USHRT_MAX)
+#endif
+
+#ifndef ULONG_MAX
+#define ULONG_MAX ((1<<(sizeof(unsigned long)*8))-1)
+#endif
+
+#ifndef LONG_MAX
+#define LONG_MAX ((1<<(sizeof(long)*8-1))-1)
+#endif
+
+#ifndef LONG_MIN
+#define LONG_MIN (LONG_MAX-ULONG_MAX)
+#endif
+
+#endif /* HAVE_LIMITS_H */
+
+#if !HAVE_FSEEKO
+# define fseeko  fseek
+#endif
+#if !HAVE_FTELLO
+# define ftello  ftell
+#endif
+
+#if defined(NT)
+  #define WNT NT
+  #undef NT
+#endif
+
+#include "lha_macro.h"
+
+#define exit(n) lha_exit(n)
+
+struct encode_option {
+#if defined(__STDC__) || defined(AIX)
+    void            (*output) ();
+    void            (*encode_start) ();
+    void            (*encode_end) ();
+#else
+    int             (*output) ();
+    int             (*encode_start) ();
+    int             (*encode_end) ();
+#endif
+};
+
+struct decode_option {
+    unsigned short  (*decode_c) ();
+    unsigned short  (*decode_p) ();
+#if defined(__STDC__) || defined(AIX)
+    void            (*decode_start) ();
+#else
+    int             (*decode_start) ();
+#endif
+};
+
+/* ------------------------------------------------------------------------ */
+/*  LHa File Type Definition                                                */
+/* ------------------------------------------------------------------------ */
+#if !defined(_WIN32)
+typedef int boolean;            /* TRUE or FALSE */
+#endif
+
+struct string_pool {
+    int             used;
+    int             size;
+    int             n;
+    char           *buffer;
+};
+
+typedef struct LzHeader {
+    size_t          header_size;
+    int             size_field_length;
+    char            method[METHOD_TYPE_STORAGE];
+    size_t          packed_size;
+    size_t          original_size;
+    unsigned char   attribute;
+    unsigned char   header_level;
+    char            name[FILENAME_LENGTH];
+    char            realname[FILENAME_LENGTH];/* real name for symbolic link */
+    unsigned int    crc;      /* file CRC */
+    boolean         has_crc;  /* file CRC */
+    unsigned int    header_crc; /* header CRC */
+    unsigned char   extend_type;
+    unsigned char   minor_version;
+
+    /* extend_type == EXTEND_UNIX  and convert from other type. */
+    time_t          unix_last_modified_stamp;
+    unsigned short  unix_mode;
+    unsigned short  unix_uid;
+    unsigned short  unix_gid;
+    char            user[256];
+    char            group[256];
+}  LzHeader;
+
+struct interfacing {
+    FILE            *infile;
+    FILE            *outfile;
+    size_t          original;
+    size_t          packed;
+    size_t          read_size;
+    int             dicbit;
+    int             method;
+};
+
+
+typedef void addfile_handler(const LzHeader*);
+
+#define LHALIB_EXTERN extern
+
+LHALIB_EXTERN void cmd_extract(const char* archive_name, 
+                            addfile_handler hnd);
+
+#define fatal_error rb_fatal
+#define error rb_warn
+#define message rb_warn
+#define warning rb_warning
+
+LHALIB_EXTERN FILE * open_old_archive(const char* archive);
+LHALIB_EXTERN boolean need_file(const char*);
+LHALIB_EXTERN boolean archive_is_msdos_sfx1(const char*);
+LHALIB_EXTERN void output_dyn();
+LHALIB_EXTERN void encode_start_fix();
+LHALIB_EXTERN void encode_end_dyn();
+LHALIB_EXTERN void output_st1();
+LHALIB_EXTERN void encode_start_st0();
+LHALIB_EXTERN void encode_end_st0();
+LHALIB_EXTERN void encode_start_st1();
+LHALIB_EXTERN void encode_end_st1();
+LHALIB_EXTERN unsigned short decode_c_dyn();
+LHALIB_EXTERN unsigned short decode_p_dyn();
+LHALIB_EXTERN void decode_start_fix();
+LHALIB_EXTERN void decode_start_dyn();
+LHALIB_EXTERN void decode_start_st0();
+LHALIB_EXTERN void decode_start_st1();
+LHALIB_EXTERN unsigned short decode_c_st0();
+LHALIB_EXTERN unsigned short decode_c_st1();
+LHALIB_EXTERN unsigned short decode_p_st0();
+LHALIB_EXTERN unsigned short decode_p_st1();
+LHALIB_EXTERN unsigned short decode_c_lzs();
+LHALIB_EXTERN unsigned short decode_p_lzs();
+LHALIB_EXTERN void decode_start_lzs();
+LHALIB_EXTERN unsigned short decode_c_lz5();
+LHALIB_EXTERN unsigned short decode_p_lz5();
+LHALIB_EXTERN void decode_start_lz5();
+LHALIB_EXTERN void make_crctable();
+LHALIB_EXTERN size_t copyfile(FILE* f1, FILE* f2, size_t size, int text_flg, unsigned int* crcp);
+LHALIB_EXTERN void init_getbits();
+LHALIB_EXTERN void init_code_cache();
+LHALIB_EXTERN void putcode(unsigned char n, unsigned short x);
+LHALIB_EXTERN void putbits(unsigned char n, unsigned short x);
+LHALIB_EXTERN unsigned short getbits(unsigned char n);
+LHALIB_EXTERN void fillbuf(unsigned char n);
+LHALIB_EXTERN void encode_p_st0(unsigned short j);
+
+
+
+#define start_indicator(name, size, ing, len) 0
+#define finish_indicator(name, ed) 0
+
+#if defined(LHALIB_VERSION)
+  #define LHA_EXTERN
+#else
+  #define LHA_EXTERN LHALIB_EXTERN
+#endif
+
+LHALIB_EXTERN boolean lha_force;
+LHALIB_EXTERN boolean lha_verbose;
+LHALIB_EXTERN boolean lha_ignore_directory;
+LHALIB_EXTERN boolean extract_broken_archive;
+LHALIB_EXTERN boolean lha_noconvertcase;
+LHALIB_EXTERN boolean lha_generic_format;
+LHALIB_EXTERN boolean lha_text_mode;
+LHALIB_EXTERN int lha_n_max;
+LHALIB_EXTERN unsigned short lha_maxmatch;
+LHALIB_EXTERN int lha_overwrite;
+LHALIB_EXTERN unsigned short lha_c_freq[], lha_c_table[], lha_c_code[];
+LHALIB_EXTERN unsigned short lha_p_freq[], lha_pt_table[], lha_pt_code[], lha_t_freq[];
+LHALIB_EXTERN unsigned char lha_c_len[], lha_pt_len[];
+LHALIB_EXTERN unsigned short lha_left[], lha_right[];
+
+LHA_EXTERN unsigned short bitbuf;
+LHA_EXTERN unsigned short dicbit;
+LHA_EXTERN size_t lha_decode_count;
+LHA_EXTERN size_t lha_origsize;
+LHA_EXTERN size_t lha_compsize;
+LHA_EXTERN int lha_unpackable;
+LHA_EXTERN unsigned long lha_loc;
+LHA_EXTERN unsigned char* lha_text;
+LHA_EXTERN unsigned int crctable[UCHAR_MAX + 1];
+LHA_EXTERN FILE* infile;
+LHA_EXTERN FILE* outfile;
+LHA_EXTERN int archive_file_gid;
+LHA_EXTERN int archive_file_mode;
+LHA_EXTERN int header_level;
+
+#define force lha_force
+#define verbose lha_verbose
+#define verbose_listing lha_verbose
+#define ignore_directory lha_ignore_directory
+#define n_max lha_n_max
+#define maxmatch lha_maxmatch
+#define decode_count lha_decode_count
+#define unpackable lha_unpackable
+#define left lha_left
+#define right lha_right
+#define c_len lha_c_len
+#define pt_len lha_pt_len
+#define c_freq lha_c_freq
+#define c_table lha_c_table
+#define c_code lha_c_code
+#define p_freq lha_pt_freq
+#define pt_table lha_pt_table
+#define pt_code lha_pt_code
+#define t_freq lha_t_freq
+#define loc lha_loc
+#define text lha_text
+#define origsize lha_origsize
+#define compsize lha_compsize
+#define noconvertcase lha_noconvertcase
+#define generic_format lha_generic_format
+#define text_mode lha_text_mode
+#define overwrite lha_overwrite
diff --git a/vendor/gems/lhalib-0.8.1/ext/lha_macro.h b/vendor/gems/lhalib-0.8.1/ext/lha_macro.h
new file mode 100644 (file)
index 0000000..8689a98
--- /dev/null
@@ -0,0 +1,255 @@
+/* ------------------------------------------------------------------------ */
+/* LHa for UNIX    Archiver Driver  macro define                            */
+/*                                                                          */
+/*      Modified                Nobutaka Watazaki                           */
+/*                                                                          */
+/*  Ver. 1.14   Soruce All chagned              1995.01.14  N.Watazaki      */
+/*  Ver. 1.14g  modified                        2000.05.06  T.OKAMOTO       */
+/* ------------------------------------------------------------------------ */
+
+#define FALSE           0
+#define TRUE            1
+
+#define FILENAME_LENGTH 1024
+
+#if defined __MINGW32__
+# define getuid()       0
+# define chown(file, uid, gid)  0
+# define kill(pid, sig)         0
+#endif
+
+/* ------------------------------------------------------------------------ */
+/* YOUR CUSTOMIZIES                                                         */
+/* ------------------------------------------------------------------------ */
+
+#ifndef ARCHIVENAME_EXTENTION
+#define ARCHIVENAME_EXTENTION   ".lzh"
+#endif
+#ifndef BACKUPNAME_EXTENTION
+#define BACKUPNAME_EXTENTION    ".bak"
+#endif
+
+#define SJIS_FIRST_P(c)         \
+  (((unsigned char)(c) >= 0x80 && (unsigned char)(c) < 0xa0) || \
+   ((unsigned char)(c) >= 0xe0 && (unsigned char)(c) < 0xfd))
+#define SJIS_SECOND_P(c)            \
+  (((unsigned char)(c) >= 0x40 && (unsigned char)(c) < 0xfd) && \
+    (unsigned char)(c) != 0x7f)
+
+#define X0201_KANA_P(c)\
+    (0xa0 < (unsigned char)(c) && (unsigned char)(c) < 0xe0)
+
+/* for filename conversion */
+#define NONE 0
+#define CODE_EUC 1
+#define CODE_SJIS 2
+#define CODE_UTF8 3
+#define CODE_CAP 4              /* Columbia AppleTalk Program */
+#define TO_LOWER 1
+#define TO_UPPER 2
+
+/* ------------------------------------------------------------------------ */
+/*  LHa File Definitions                                                    */
+/* ------------------------------------------------------------------------ */
+#ifdef S_IFLNK
+#define GETSTAT lstat
+#else
+#define GETSTAT stat
+#endif
+
+#define LZHUFF0_METHOD          "-lh0-"
+#define LZHUFF1_METHOD          "-lh1-"
+#define LZHUFF2_METHOD          "-lh2-"
+#define LZHUFF3_METHOD          "-lh3-"
+#define LZHUFF4_METHOD          "-lh4-"
+#define LZHUFF5_METHOD          "-lh5-"
+#define LZHUFF6_METHOD          "-lh6-"
+#define LZHUFF7_METHOD          "-lh7-"
+#define LARC_METHOD             "-lzs-"
+#define LARC5_METHOD            "-lz5-"
+#define LARC4_METHOD            "-lz4-"
+#define LZHDIRS_METHOD          "-lhd-"
+
+#define METHOD_TYPE_STORAGE     5
+
+/* Added N.Watazaki ..V */
+#define LZHUFF0_METHOD_NUM      0
+#define LZHUFF1_METHOD_NUM      1
+#define LZHUFF2_METHOD_NUM      2
+#define LZHUFF3_METHOD_NUM      3
+#define LZHUFF4_METHOD_NUM      4
+#define LZHUFF5_METHOD_NUM      5
+#define LZHUFF6_METHOD_NUM      6
+#define LZHUFF7_METHOD_NUM      7
+#define LARC_METHOD_NUM         8
+#define LARC5_METHOD_NUM        9
+#define LARC4_METHOD_NUM        10
+#define LZHDIRS_METHOD_NUM      11
+/* Added N.Watazaki ..^ */
+
+#define LZHUFF0_DICBIT           0      /* no compress */
+#define LZHUFF1_DICBIT          12      /* 2^12 =  4KB sliding dictionary */
+#define LZHUFF2_DICBIT          13      /* 2^13 =  8KB sliding dictionary */
+#define LZHUFF3_DICBIT          13      /* 2^13 =  8KB sliding dictionary */
+#define LZHUFF4_DICBIT          12      /* 2^12 =  4KB sliding dictionary */
+#define LZHUFF5_DICBIT          13      /* 2^13 =  8KB sliding dictionary */
+#define LZHUFF6_DICBIT          15      /* 2^15 = 32KB sliding dictionary */
+#define LZHUFF7_DICBIT          16      /* 2^16 = 64KB sliding dictionary */
+#define LARC_DICBIT             11      /* 2^11 =  2KB sliding dictionary */
+#define LARC5_DICBIT            12      /* 2^12 =  4KB sliding dictionary */
+#define LARC4_DICBIT             0      /* no compress */
+
+#ifdef SUPPORT_LH7
+#define MAX_DICBIT          LZHUFF7_DICBIT      /* lh7 use 16bits */
+#endif
+#ifndef SUPPORT_LH7
+#define MAX_DICBIT          LZHUFF6_DICBIT      /* lh6 use 15bits */
+#endif
+
+#define MAX_DICSIZ          (1L << MAX_DICBIT)
+
+#define EXTEND_GENERIC          0
+#define EXTEND_UNIX             'U'
+#define EXTEND_MSDOS            'M'
+#define EXTEND_MACOS            'm'
+#define EXTEND_OS9              '9'
+#define EXTEND_OS2              '2'
+#define EXTEND_OS68K            'K'
+#define EXTEND_OS386            '3' /* OS-9000??? */
+#define EXTEND_HUMAN            'H'
+#define EXTEND_CPM              'C'
+#define EXTEND_FLEX             'F'
+#define EXTEND_RUNSER           'R'
+
+/* this OS type is not official */
+
+#define EXTEND_TOWNSOS          'T'
+#define EXTEND_XOSK             'X' /* OS-9 for X68000 (?) */
+#define EXTEND_JAVA             'J'
+
+/*---------------------------------------------------------------------------*/
+
+#define GENERIC_ATTRIBUTE               0x20
+#define GENERIC_DIRECTORY_ATTRIBUTE     0x10
+
+#define CURRENT_UNIX_MINOR_VERSION      0x00
+
+#define LHA_PATHSEP             0xff    /* path separator of the
+                                           filename in lha header.
+                                           it should compare with
+                                           `unsigned char' or `int',
+                                           that is not '\xff', but 0xff. */
+
+#define OSK_RW_RW_RW            0000033
+#define OSK_FILE_REGULAR        0000000
+#define OSK_DIRECTORY_PERM      0000200
+#define OSK_SHARED_PERM         0000100
+#define OSK_OTHER_EXEC_PERM     0000040
+#define OSK_OTHER_WRITE_PERM    0000020
+#define OSK_OTHER_READ_PERM     0000010
+#define OSK_OWNER_EXEC_PERM     0000004
+#define OSK_OWNER_WRITE_PERM    0000002
+#define OSK_OWNER_READ_PERM     0000001
+
+#define UNIX_FILE_TYPEMASK      0170000
+#define UNIX_FILE_REGULAR       0100000
+#define UNIX_FILE_DIRECTORY     0040000
+#define UNIX_FILE_SYMLINK       0120000
+#define UNIX_SETUID             0004000
+#define UNIX_SETGID             0002000
+#define UNIX_STICKYBIT          0001000
+#define UNIX_OWNER_READ_PERM    0000400
+#define UNIX_OWNER_WRITE_PERM   0000200
+#define UNIX_OWNER_EXEC_PERM    0000100
+#define UNIX_GROUP_READ_PERM    0000040
+#define UNIX_GROUP_WRITE_PERM   0000020
+#define UNIX_GROUP_EXEC_PERM    0000010
+#define UNIX_OTHER_READ_PERM    0000004
+#define UNIX_OTHER_WRITE_PERM   0000002
+#define UNIX_OTHER_EXEC_PERM    0000001
+#define UNIX_RW_RW_RW           0000666
+
+#define LZHEADER_STORAGE        4096
+
+/* ------------------------------------------------------------------------ */
+/*  FILE Attribute                                                          */
+/* ------------------------------------------------------------------------ */
+#define is_directory(statp)     (((statp)->st_mode & S_IFMT) == S_IFDIR)
+#define is_symlink(statp)       (((statp)->st_mode & S_IFMT) == S_IFLNK)
+#define is_regularfile(statp)   (((statp)->st_mode & S_IFMT) == S_IFREG)
+
+#if 1 /* assume that fopen() will accepts "b" as binary mode on all systems. */
+#define WRITE_BINARY    "wb"
+#define READ_BINARY     "rb"
+#else
+#define WRITE_BINARY    "w"
+#define READ_BINARY     "r"
+#endif
+
+/* ------------------------------------------------------------------------ */
+/* Individual macro define                                                  */
+/* ------------------------------------------------------------------------ */
+
+/* bitio.c */
+#define peekbits(n)     (bitbuf >> (sizeof(bitbuf)*8 - (n)))
+
+/* crcio.c */
+#define CRCPOLY         0xA001      /* CRC-16 (x^16+x^15+x^2+1) */
+#define INITIALIZE_CRC(crc) ((crc) = 0)
+#define UPDATE_CRC(crc, c) \
+ (crctable[((crc) ^ (c)) & 0xFF] ^ ((crc) >> CHAR_BIT))
+
+/* dhuf.c */
+#define N_CHAR      (256 + 60 - THRESHOLD + 1)
+#define TREESIZE_C  (N_CHAR * 2)
+#define TREESIZE_P  (128 * 2)
+#define TREESIZE    (TREESIZE_C + TREESIZE_P)
+#define ROOT_C      0
+#define ROOT_P      TREESIZE_C
+
+/* huf.c */
+#define USHRT_BIT           16  /* (CHAR_BIT * sizeof(ushort)) */
+#define NP          (MAX_DICBIT + 1)
+#define NT          (USHRT_BIT + 3)
+#define NC          (UCHAR_MAX + MAXMATCH + 2 - THRESHOLD)
+
+#define PBIT        5       /* smallest integer such that (1 << PBIT) > * NP */
+#define TBIT        5       /* smallest integer such that (1 << TBIT) > * NT */
+#define CBIT        9       /* smallest integer such that (1 << CBIT) > * NC */
+
+/*      #if NT > NP #define NPT NT #else #define NPT NP #endif  */
+#define NPT         0x80
+
+/* larc.c */
+#define MAGIC0      18
+#define MAGIC5      19
+
+/* lharc.c */
+#define CMD_UNKNOWN 0
+#define CMD_EXTRACT 1
+#define CMD_ADD     2
+#define CMD_LIST    3
+#define CMD_DELETE  4
+
+#define STREQU(a,b) (((a)[0] == (b)[0]) ? (strcmp ((a),(b)) == 0) : FALSE)
+
+/* shuf.c */
+#define N1          286             /* alphabet size */
+#define N2          (2 * N1 - 1)    /* # of nodes in Huffman tree */
+#define EXTRABITS   8               /* >= log2(F-THRESHOLD+258-N1) */
+#define BUFBITS     16              /* >= log2(MAXBUF) */
+#define LENFIELD    4               /* bit size of length field for tree output */
+
+/* util.c */
+#define BUFFERSIZE  2048
+
+/* slide.c */
+/*
+#define PERCOLATE  1
+#define NIL        0
+#define HASH(p, c) ((p) + ((c) << hash1) + hash2)
+*/
+
+/* slide.c */
+#define MAXMATCH            256 /* formerly F (not more than UCHAR_MAX + 1) */
+#define THRESHOLD           3   /* choose optimal value */
diff --git a/vendor/gems/lhalib-0.8.1/ext/lhalib.c b/vendor/gems/lhalib-0.8.1/ext/lhalib.c
new file mode 100644 (file)
index 0000000..b76bc54
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ * LhaLib for Ruby
+ * Copyright(c) 2006 arton
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * $Id:$
+ */
+
+#define LHALIB_VERSION "0.8.1"
+
+#include "lha.h"
+#include "st.h"
+
+static VALUE lhalib;
+
+boolean lha_force = FALSE;
+boolean lha_verbose = FALSE;
+boolean lha_ignore_directory = FALSE;
+boolean extract_broken_archive = FALSE;
+boolean lha_noconvertcase = FALSE;
+boolean lha_generic_format = FALSE;
+boolean lha_text_mode = FALSE;
+int overwrite = 1;
+int lha_n_max;
+unsigned short lha_maxmatch;
+unsigned short bitbuf;
+size_t lha_decode_count;
+int lha_unpackable;
+unsigned long lha_loc;
+unsigned char* lha_text;
+FILE* infile;
+FILE* outfile;
+int archive_file_gid;
+int archive_file_mode;
+
+static VALUE proc;
+static VALUE id_name;
+static VALUE id_permission;
+static VALUE id_original_size;
+static VALUE id_packed_size;
+static VALUE id_stamp;
+static int file_count;
+
+void lha_exit(int n)
+{
+    rb_raise(rb_eRuntimeError, "LhaLib invalid operation %d", n);
+}
+
+void add_file(const LzHeader* hdr)
+{
+  file_count++;
+  if (!NIL_P(proc))
+  {
+      VALUE hash = rb_hash_new();
+      rb_hash_aset(hash, ID2SYM(id_name), rb_str_new2(hdr->name));
+      rb_hash_aset(hash, ID2SYM(id_permission), INT2FIX(hdr->unix_mode));
+      rb_hash_aset(hash, ID2SYM(id_original_size), INT2FIX(hdr->original_size));
+      rb_hash_aset(hash, ID2SYM(id_packed_size), INT2FIX(hdr->packed_size));
+      rb_hash_aset(hash, ID2SYM(id_stamp), rb_time_new(hdr->unix_last_modified_stamp, 0));
+      rb_yield(hash);
+  }
+}
+
+static VALUE s_ex(int argc, VALUE* argv, VALUE self)
+{
+  VALUE file;
+  proc = Qnil;
+  rb_scan_args(argc, argv, "1&", &file, &proc);
+  rb_check_safe_str(file);
+  rb_secure(4);
+
+  file_count = 0;
+  make_crctable();
+  cmd_extract(StringValueCStr(file), add_file);
+  return INT2FIX(file_count);
+}
+
+
+/*
+ * Class initializer called by Ruby while requiring this library
+ */
+void Init_lhalib()
+{
+    header_level = 2;
+    id_name = rb_intern("name");
+    id_permission = rb_intern("permission");
+    id_original_size = rb_intern("original_size");
+    id_packed_size = rb_intern("packed_size");
+    id_stamp = rb_intern("stamp");
+
+    lhalib = rb_define_module("LhaLib");
+    rb_define_module_function(lhalib, "x", s_ex, -1);
+    rb_define_const(lhalib, "VERSION", rb_str_new2(LHALIB_VERSION));
+
+}
diff --git a/vendor/gems/lhalib-0.8.1/ext/lharc.c b/vendor/gems/lhalib-0.8.1/ext/lharc.c
new file mode 100644 (file)
index 0000000..fd6f62c
--- /dev/null
@@ -0,0 +1,132 @@
+/* ------------------------------------------------------------------------ */
+/* LHa for UNIX                                                             */
+/*              lharc.c -- append to archive                                */
+/*                                                                          */
+/*      Copyright (C) MCMLXXXIX Yooichi.Tagawa                              */
+/*      Modified                Nobutaka Watazaki                           */
+/*                          Thanks to H.Yoshizaki. (MS-DOS LHarc)           */
+/*                                                                          */
+/*  Ver. 0.00  Original                         1988.05.23  Y.Tagawa        */
+/*  Ver. 0.01  Alpha Version (for 4.2BSD)       1989.05.28  Y.Tagawa        */
+/*  Ver. 0.02  Alpha Version Rel.2              1989.05.29  Y.Tagawa        */
+/*  Ver. 0.03  Release #3  Beta Version         1989.07.02  Y.Tagawa        */
+/*  Ver. 0.03a Debug                            1989.07.03  Y.Tagawa        */
+/*  Ver. 0.03b Modified                         1989.07.13  Y.Tagawa        */
+/*  Ver. 0.03c Debug (Thanks to void@rena.dit.junet)                        */
+/*                                              1989.08.09  Y.Tagawa        */
+/*  Ver. 0.03d Modified (quiet and verbose)     1989.09.14  Y.Tagawa        */
+/*  V1.00  Fixed                                1989.09.22  Y.Tagawa        */
+/*  V1.01  Bug Fixed                            1989.12.25  Y.Tagawa        */
+/*                                                                          */
+/*  DOS-Version Original LHx V C2.01        (C) H.Yohizaki                  */
+/*                                                                          */
+/*  V2.00  UNIX Lharc + DOS LHx -> OSK LHx      1990.11.01  Momozou         */
+/*  V2.01  Minor Modified                       1990.11.24  Momozou         */
+/*                                                                          */
+/*  Ver. 0.02  LHx for UNIX                     1991.11.18  M.Oki           */
+/*  Ver. 0.03  LHa for UNIX                     1991.12.17  M.Oki           */
+/*  Ver. 0.04  LHa for UNIX beta version        1992.01.20  M.Oki           */
+/*  Ver. 1.00  LHa for UNIX Fixed               1992.03.19  M.Oki           */
+/*                                                                          */
+/*  Ver. 1.10  for Symbolic Link                1993.06.25  N.Watazaki      */
+/*  Ver. 1.11  for Symbolic Link Bug Fixed      1993.08.18  N.Watazaki      */
+/*  Ver. 1.12  for File Date Check              1993.10.28  N.Watazaki      */
+/*  Ver. 1.13  Bug Fixed (Idicator calcurate)   1994.02.21  N.Watazaki      */
+/*  Ver. 1.13a Bug Fixed (Sym. Link delete)     1994.03.11  N.Watazaki      */
+/*  Ver. 1.13b Bug Fixed (Sym. Link delete)     1994.07.29  N.Watazaki      */
+/*  Ver. 1.14  Source All chagned               1995.01.14  N.Watazaki      */
+/*  Ver. 1.14b,c  Bug Fixed                     1996.03.07  t.okamoto       */
+/*  Ver. 1.14d Version up                       1997.01.12  t.okamoto       */
+/*  Ver. 1.14g Bug Fixed                        2000.05.06  t.okamoto       */
+/*  Ver. 1.14i Modified                         2000.10.06  t.okamoto       */
+/*   Modified arton for LhaLib */
+/* ------------------------------------------------------------------------ */
+
+#include "lha.h"
+
+static int      cmd = CMD_UNKNOWN;
+static int error_occurred;
+
+/* ------------------------------------------------------------------------ */
+/*                                                                          */
+/* ------------------------------------------------------------------------ */
+static          boolean
+open_old_archive_1(name, v_fp)
+    char           *name;
+    FILE          **v_fp;
+{
+    FILE           *fp;
+    struct stat     stbuf;
+
+    if (stat(name, &stbuf) >= 0 &&
+        is_regularfile(&stbuf) &&
+        (fp = fopen(name, READ_BINARY)) != NULL) {
+        *v_fp = fp;
+        archive_file_gid = stbuf.st_gid;
+        archive_file_mode = stbuf.st_mode;
+        return TRUE;
+    }
+
+    *v_fp = NULL;
+    archive_file_gid = -1;
+    return FALSE;
+}
+
+/* ------------------------------------------------------------------------ */
+FILE           *
+open_old_archive(const char* archive_name)
+{
+    FILE           *fp;
+    char           *p;
+    static char expanded_archive_name[FILENAME_LENGTH];
+
+    if (!strcmp(archive_name, "-")) {
+        if (cmd == CMD_EXTRACT || cmd == CMD_LIST) {
+#if __MINGW32__
+            setmode(fileno(stdin), O_BINARY);
+#endif
+            return stdin;
+        }
+        else
+            return NULL;
+    }
+    p = strrchr(archive_name, '.');
+    if (p) {
+        if (strcasecmp(".LZH", p) == 0
+            || strcasecmp(".LZS", p) == 0
+            || strcasecmp(".COM", p) == 0  /* DOS SFX */
+            || strcasecmp(".EXE", p) == 0
+            || strcasecmp(".X", p) == 0    /* HUMAN SFX */
+            || strcasecmp(".BAK", p) == 0) {   /* for BackUp */
+            open_old_archive_1(archive_name, &fp);
+            return fp;
+        }
+    }
+
+    if (open_old_archive_1(archive_name, &fp))
+        return fp;
+    xsnprintf(expanded_archive_name, sizeof(expanded_archive_name),
+              "%s.lzh", archive_name);
+    if (open_old_archive_1(expanded_archive_name, &fp)) {
+        archive_name = expanded_archive_name;
+        return fp;
+    }
+    /*
+     * if ( (errno&0xffff)!=E_PNNF ) { archive_name =
+     * expanded_archive_name; return NULL; }
+     */
+    xsnprintf(expanded_archive_name, sizeof(expanded_archive_name),
+              "%s.lzs", archive_name);
+    if (open_old_archive_1(expanded_archive_name, &fp)) {
+        archive_name = expanded_archive_name;
+        return fp;
+    }
+    return NULL;
+}
+
+boolean
+need_file(const char* name)
+{
+    return TRUE;
+}
+
diff --git a/vendor/gems/lhalib-0.8.1/ext/lhext.c b/vendor/gems/lhalib-0.8.1/ext/lhext.c
new file mode 100644 (file)
index 0000000..453c8fa
--- /dev/null
@@ -0,0 +1,470 @@
+/* ------------------------------------------------------------------------ */
+/* LHa for UNIX                                                             */
+/*              lhext.c -- LHarc extract                                    */
+/*                                                                          */
+/*      Copyright (C) MCMLXXXIX Yooichi.Tagawa                              */
+/*      Modified                Nobutaka Watazaki                           */
+/*                                                                          */
+/*  Ver. 0.00  Original                             1988.05.23  Y.Tagawa    */
+/*  Ver. 1.00  Fixed                                1989.09.22  Y.Tagawa    */
+/*  Ver. 0.03  LHa for UNIX                         1991.12.17  M.Oki       */
+/*  Ver. 1.12  LHa for UNIX                         1993.10.01  N.Watazaki  */
+/*  Ver. 1.13b Symbolic Link Update Bug Fix         1994.06.21  N.Watazaki  */
+/*  Ver. 1.14  Source All chagned                   1995.01.14  N.Watazaki  */
+/*  Ver. 1.14e bugfix                               1999.04.30  T.Okamoto   */
+/*      Modified arton for LhaLib */
+/* ------------------------------------------------------------------------ */
+#include "lha.h"
+/* ------------------------------------------------------------------------ */
+static int      skip_flg = FALSE;   /* FALSE..No Skip , TRUE..Skip */
+static char    *methods[] =
+{
+    LZHUFF0_METHOD, LZHUFF1_METHOD, LZHUFF2_METHOD, LZHUFF3_METHOD,
+    LZHUFF4_METHOD, LZHUFF5_METHOD, LZHUFF6_METHOD, LZHUFF7_METHOD,
+    LARC_METHOD, LARC5_METHOD, LARC4_METHOD,
+    LZHDIRS_METHOD,
+    NULL
+};
+
+static void add_dirinfo(char* name, LzHeader* hdr);
+static void adjust_dirinfo();
+
+/* ------------------------------------------------------------------------ */
+static          boolean
+inquire_extract(name)
+    char           *name;
+{
+    struct stat     stbuf;
+
+    skip_flg = FALSE;
+    if (stat(name, &stbuf) >= 0) {
+        if (!is_regularfile(&stbuf)) {
+            error("\"%s\" already exists (not a file)", name);
+            return FALSE;
+        }
+
+        if (!force) {
+            if (!isatty(0)) {
+                warning("skip to extract %s.", name);
+                return FALSE;
+            }
+
+            switch (overwrite) {
+            case 0:
+            case 1:/* Y/y */
+                break;
+            case 2:
+            case 3:/* N/n */
+            case 8:/* Return */
+                return FALSE;
+            case 4:
+            case 5:/* A/a */
+                force = TRUE;
+                break;
+            case 6:
+            case 7:/* S/s */
+                skip_flg = TRUE;
+                break;
+            }
+        }
+    }
+
+    return TRUE;
+}
+
+/* ------------------------------------------------------------------------ */
+static          boolean
+make_parent_path(name)
+    char           *name;
+{
+    char            path[FILENAME_LENGTH];
+    struct stat     stbuf;
+    register char  *p;
+
+    /* make parent directory name into PATH for recursive call */
+    str_safe_copy(path, name, sizeof(path));
+    for (p = path + strlen(path); p > path; p--)
+        if (p[-1] == '/') {
+            *--p = '\0';
+            break;
+        }
+
+    if (p == path) {
+        message("invalid path name \"%s\"", name);
+        return FALSE;   /* no more parent. */
+    }
+
+    if (GETSTAT(path, &stbuf) >= 0) {
+        if (is_directory(&stbuf))
+            return TRUE;
+    }
+
+    if (verbose)
+        message("Making directory \"%s\".", path);
+
+#if defined __MINGW32__
+    if (mkdir(path) >= 0)
+        return TRUE;
+#else
+    if (mkdir(path, 0777) >= 0) /* try */
+        return TRUE;    /* successful done. */
+#endif
+
+    if (!make_parent_path(path))
+        return FALSE;
+
+#if defined __MINGW32__
+    if (mkdir(path) < 0) {      /* try again */
+        error("Cannot make directory \"%s\"", path);
+        return FALSE;
+    }
+#else
+    if (mkdir(path, 0777) < 0) {    /* try again */
+        error("Cannot make directory \"%s\"", path);
+        return FALSE;
+    }
+#endif
+
+    return TRUE;
+}
+
+/* ------------------------------------------------------------------------ */
+static FILE    *
+open_with_make_path(name)
+    char           *name;
+{
+    FILE           *fp;
+
+    if ((fp = fopen(name, WRITE_BINARY)) == NULL) {
+        if (!make_parent_path(name) ||
+            (fp = fopen(name, WRITE_BINARY)) == NULL)
+            error("Cannot extract a file \"%s\"", name);
+    }
+    return fp;
+}
+
+/* ------------------------------------------------------------------------ */
+static void
+adjust_info(name, hdr)
+    char           *name;
+    LzHeader       *hdr;
+{
+    struct utimbuf utimebuf;
+
+    /* adjust file stamp */
+    utimebuf.actime = utimebuf.modtime = hdr->unix_last_modified_stamp;
+
+    if ((hdr->unix_mode & UNIX_FILE_TYPEMASK) != UNIX_FILE_SYMLINK)
+        utime(name, &utimebuf);
+
+    if (hdr->extend_type == EXTEND_UNIX
+        || hdr->extend_type == EXTEND_OS68K
+        || hdr->extend_type == EXTEND_XOSK) {
+#ifdef NOT_COMPATIBLE_MODE
+        Please need your modification in this space.
+#else
+        if ((hdr->unix_mode & UNIX_FILE_TYPEMASK) != UNIX_FILE_SYMLINK)
+            chmod(name, hdr->unix_mode);
+#endif
+        if (!getuid()){
+            uid_t uid = hdr->unix_uid;
+            gid_t gid = hdr->unix_gid;
+
+#if HAVE_GETPWNAM && HAVE_GETGRNAM
+            if (hdr->user[0]) {
+                struct passwd *ent = getpwnam(hdr->user);
+                if (ent) uid = ent->pw_uid;
+            }
+            if (hdr->group[0]) {
+                struct group *ent = getgrnam(hdr->group);
+                if (ent) gid = ent->gr_gid;
+            }
+#endif
+
+#if HAVE_LCHOWN
+            if ((hdr->unix_mode & UNIX_FILE_TYPEMASK) == UNIX_FILE_SYMLINK)
+                lchown(name, uid, gid);
+            else
+#endif /* HAVE_LCHWON */
+                chown(name, uid, gid);
+        }
+    }
+#if __CYGWIN__
+    else {
+        /* On Cygwin, execute permission should be set for .exe or .dll. */
+        mode_t m;
+
+        umask(m = umask(0));    /* get current umask */
+        chmod(name, 0777 & ~m);
+    }
+#endif
+}
+
+/* ------------------------------------------------------------------------ */
+static size_t
+extract_one(FILE* afp, LzHeader* hdr, addfile_handler hnd)
+{
+    FILE           *fp; /* output file */
+    struct stat     stbuf;
+    char            name[FILENAME_LENGTH];
+    unsigned int crc;
+    int             method;
+    boolean         up_flag;
+    char           *q = hdr->name, c;
+    size_t read_size = 0;
+
+    if (ignore_directory && strrchr(hdr->name, '/')) {
+        q = (char *) strrchr(hdr->name, '/') + 1;
+    }
+    else {
+        if (is_directory_traversal(q)) {
+            fprintf(stderr, "Possible directory traversal hack attempt in %s\n", q);
+            exit(111);
+        }
+
+        if (*q == '/') {
+            while (*q == '/') { q++; }
+
+            /*
+             * if OSK then strip device name
+             */
+            if (hdr->extend_type == EXTEND_OS68K
+                || hdr->extend_type == EXTEND_XOSK) {
+                do
+                    c = (*q++);
+                while (c && c != '/');
+                if (!c || !*q)
+                    q = ".";    /* if device name only */
+            }
+        }
+    }
+
+    str_safe_copy(name, q, sizeof(name));
+
+    /* LZHDIRS_METHOD¤ò»ý¤Ä¥Ø¥Ã¥À¤ò¥Á¥§¥Ã¥¯¤¹¤ë */
+    /* 1999.4.30 t.okamoto */
+    for (method = 0;; method++) {
+        if (methods[method] == NULL) {
+            error("Unknown method \"%.*s\"; \"%s\" will be skiped ...",
+                  5, hdr->method, name);
+            return read_size;
+        }
+        if (memcmp(hdr->method, methods[method], 5) == 0)
+            break;
+    }
+
+    if ((hdr->unix_mode & UNIX_FILE_TYPEMASK) == UNIX_FILE_REGULAR
+        && method != LZHDIRS_METHOD_NUM) {
+    extract_regular:
+
+       if (skip_flg == FALSE)  {
+           up_flag = inquire_extract(name);
+            if (up_flag == FALSE && force == FALSE) {
+                return read_size;
+            }
+        }
+
+        if (skip_flg == TRUE) { /* if skip_flg */
+            if (stat(name, &stbuf) == 0 && force != TRUE) {
+                if (stbuf.st_mtime >= hdr->unix_last_modified_stamp) {
+                    return read_size;
+                }
+            }
+        }
+
+        unlink(name);
+        if ((fp = open_with_make_path(name)) != NULL) {
+            crc = decode_lzhuf(afp, fp,
+                               hdr->original_size, hdr->packed_size,
+                               name, method, &read_size);
+            fclose(fp);
+        }
+        if (!fp)
+            return read_size;
+
+
+        if (hdr->has_crc && crc != hdr->crc)
+            error("CRC error: \"%s\"", name);
+    }
+    else if ((hdr->unix_mode & UNIX_FILE_TYPEMASK) == UNIX_FILE_DIRECTORY
+             || (hdr->unix_mode & UNIX_FILE_TYPEMASK) == UNIX_FILE_SYMLINK
+             || method == LZHDIRS_METHOD_NUM) {
+        /* ¢¬¤³¤ì¤Ç¡¢Symbolic Link ¤Ï¡¢Âç¾æÉפ«¡© */
+        if (!ignore_directory) {
+            /* NAME has trailing SLASH '/', (^_^) */
+            if ((hdr->unix_mode & UNIX_FILE_TYPEMASK) == UNIX_FILE_SYMLINK) {
+                int             l_code;
+
+#ifdef S_IFLNK
+                if (skip_flg == FALSE)  {
+                    up_flag = inquire_extract(name);
+                    if (up_flag == FALSE && force == FALSE) {
+                        return read_size;
+                    }
+                } else {
+                    if (GETSTAT(name, &stbuf) == 0 && force != TRUE) {
+                        if (stbuf.st_mtime >= hdr->unix_last_modified_stamp) {
+                            return read_size;
+                        }
+                    }
+                }
+
+                unlink(name);
+                make_parent_path(name);
+                l_code = symlink(hdr->realname, name);
+                if (l_code < 0) {
+                    warning("Can't make Symbolic Link \"%s\" -> \"%s\"",
+                            name, hdr->realname);
+                }
+#else
+                warning("Can't make Symbolic Link %s -> %s",
+                        name, hdr->realname);
+                return read_size;
+#endif
+            } else { /* make directory */
+                if (!make_parent_path(name))
+                    return read_size;
+                /* save directory information */
+                add_dirinfo(name, hdr);
+            }
+        }
+    }
+    else {
+        if (force)              /* force extract */
+            goto extract_regular;
+        else
+            error("Unknown file type: \"%s\". use `f' option to force extract.", name);
+    }
+
+    adjust_info(name, hdr);
+
+    return read_size;
+}
+
+/* ------------------------------------------------------------------------ */
+/* EXTRACT COMMAND MAIN                                                     */
+/* ------------------------------------------------------------------------ */
+void
+cmd_extract(const char* archive_name, addfile_handler hnd)
+{
+    LzHeader        hdr;
+    off_t           pos;
+    FILE           *afp;
+    size_t read_size;
+
+    /* open archive file */
+    if ((afp = open_old_archive(archive_name)) == NULL)
+        fatal_error("Cannot open archive file \"%s\"", archive_name);
+
+    if (archive_is_msdos_sfx1(archive_name))
+        seek_lha_header(afp);
+
+    /* extract each files */
+    while (get_header(afp, &hdr)) {
+        if (need_file(hdr.name)) {
+            pos = ftello(afp);
+            read_size = extract_one(afp, &hdr, hnd);
+            if (read_size != hdr.packed_size) {
+                /* when error occurred in extract_one(), should adjust
+                   point of file stream */
+                if (pos != -1 && afp != stdin)
+                    fseeko(afp, pos + hdr.packed_size - read_size, SEEK_SET);
+                else {
+                    size_t i = hdr.packed_size - read_size;
+                    while (i--) fgetc(afp);
+                }
+            } else {
+                hnd(&hdr);
+           }
+        } else {
+            if (afp != stdin)
+                fseeko(afp, hdr.packed_size, SEEK_CUR);
+            else {
+                size_t i = hdr.packed_size;
+                while (i--) fgetc(afp);
+            }
+        }
+    }
+
+    /* close archive file */
+    fclose(afp);
+
+    /* adjust directory information */
+    adjust_dirinfo();
+
+    return;
+}
+
+int
+is_directory_traversal(char *path)
+{
+    int state = 0;
+
+    for (; *path; path++) {
+        switch (state) {
+        case 0:
+            if (*path == '.') state = 1;
+            else state = 3;
+            break;
+        case 1:
+            if (*path == '.') state = 2;
+            else if (*path == '/') state = 0;
+            else state = 3;
+            break;
+        case 2:
+            if (*path == '/') return 1;
+            else state = 3;
+            break;
+        case 3:
+            if (*path == '/') state = 0;
+            break;
+        }
+    }
+
+    return state == 2;
+}
+
+/*
+ * restore directory information (time stamp).
+ * added by A.Iriyama  2003.12.12
+ */
+
+typedef struct lhdDirectoryInfo_t {
+    struct lhdDirectoryInfo_t *next;
+    LzHeader hdr;
+} LzHeaderList;
+
+static LzHeaderList *dirinfo;
+
+static void add_dirinfo(char *name, LzHeader *hdr)
+{
+    LzHeaderList *p;
+
+    if (memcmp(hdr->method, LZHDIRS_METHOD, 5) != 0)
+        return;
+
+    p = xmalloc(sizeof(LzHeaderList));
+
+    memcpy(&p->hdr, hdr, sizeof(LzHeader));
+    strncpy(p->hdr.name, name, sizeof(p->hdr.name));
+    p->hdr.name[sizeof(p->hdr.name)-1] = 0;
+
+    {
+        LzHeaderList *tmp = dirinfo;
+        dirinfo = p;
+        dirinfo->next = tmp;
+    }
+}
+
+static void adjust_dirinfo()
+{
+    while (dirinfo) {
+        adjust_info(dirinfo->hdr.name, &dirinfo->hdr);
+
+        {
+            LzHeaderList *tmp = dirinfo;
+            dirinfo = dirinfo->next;
+            free(tmp);
+        }
+    }
+}
diff --git a/vendor/gems/lhalib-0.8.1/ext/maketbl.c b/vendor/gems/lhalib-0.8.1/ext/maketbl.c
new file mode 100644 (file)
index 0000000..9286c5d
--- /dev/null
@@ -0,0 +1,93 @@
+/* ------------------------------------------------------------------------ */
+/* LHa for UNIX                                                             */
+/*              maketbl.c -- makes decoding table                           */
+/*                                                                          */
+/*      Modified                Nobutaka Watazaki                           */
+/*                                                                          */
+/*  Ver. 1.14   Source All chagned              1995.01.14  N.Watazaki      */
+/* ------------------------------------------------------------------------ */
+#include "lha.h"
+
+void
+make_table(nchar, bitlen, tablebits, table)
+    short           nchar;
+    unsigned char   bitlen[];
+    short           tablebits;
+    unsigned short  table[];
+{
+    unsigned short  count[17];  /* count of bitlen */
+    unsigned short  weight[17]; /* 0x10000ul >> bitlen */
+    unsigned short  start[17];  /* first code of bitlen */
+    unsigned short  total;
+    unsigned int    i, l;
+    int             j, k, m, n, avail;
+    unsigned short *p;
+
+    avail = nchar;
+
+    /* initialize */
+    for (i = 1; i <= 16; i++) {
+        count[i] = 0;
+        weight[i] = 1 << (16 - i);
+    }
+
+    /* count */
+    for (i = 0; i < nchar; i++)
+        count[bitlen[i]]++;
+
+    /* calculate first code */
+    total = 0;
+    for (i = 1; i <= 16; i++) {
+        start[i] = total;
+        total += weight[i] * count[i];
+    }
+    if ((total & 0xffff) != 0)
+        error("make_table(): Bad table (5)");
+
+    /* shift data for make table. */
+    m = 16 - tablebits;
+    for (i = 1; i <= tablebits; i++) {
+        start[i] >>= m;
+        weight[i] >>= m;
+    }
+
+    /* initialize */
+    j = start[tablebits + 1] >> m;
+    k = 1 << tablebits;
+    if (j != 0)
+        for (i = j; i < k; i++)
+            table[i] = 0;
+
+    /* create table and tree */
+    for (j = 0; j < nchar; j++) {
+        k = bitlen[j];
+        if (k == 0)
+            continue;
+        l = start[k] + weight[k];
+        if (k <= tablebits) {
+            /* code in table */
+            for (i = start[k]; i < l; i++)
+                table[i] = j;
+        }
+        else {
+            /* code not in table */
+            p = &table[(i = start[k]) >> m];
+            i <<= tablebits;
+            n = k - tablebits;
+            /* make tree (n length) */
+            while (--n >= 0) {
+                if (*p == 0) {
+                    right[avail] = left[avail] = 0;
+                    *p = avail++;
+                }
+                if (i & 0x8000)
+                    p = &right[*p];
+                else
+                    p = &left[*p];
+                i <<= 1;
+            }
+            *p = j;
+        }
+        start[k] = l;
+    }
+}
diff --git a/vendor/gems/lhalib-0.8.1/ext/maketree.c b/vendor/gems/lhalib-0.8.1/ext/maketree.c
new file mode 100644 (file)
index 0000000..d964ec8
--- /dev/null
@@ -0,0 +1,179 @@
+/* ------------------------------------------------------------------------ */
+/* LHa for UNIX                                                             */
+/*              maketree.c -- make Huffman tree                             */
+/*                                                                          */
+/*      Modified                Nobutaka Watazaki                           */
+/*                                                                          */
+/*  Ver. 1.14   Source All chagned              1995.01.14  N.Watazaki      */
+/* ------------------------------------------------------------------------ */
+#include "lha.h"
+
+static void
+make_code(nchar, bitlen, code, leaf_num)
+    int            nchar;
+    unsigned char  *bitlen;
+    unsigned short *code;       /* table */
+    unsigned short *leaf_num;
+{
+    unsigned short  weight[17]; /* 0x10000ul >> bitlen */
+    unsigned short  start[17];  /* start code */
+    unsigned short  total;
+    int i;
+    int c;
+
+    total = 0;
+    for (i = 1; i <= 16; i++) {
+        start[i] = total;
+        weight[i] = 1 << (16 - i);
+        total += weight[i] * leaf_num[i];
+    }
+    for (c = 0; c < nchar; c++) {
+        i = bitlen[c];
+        code[c] = start[i];
+        start[i] += weight[i];
+    }
+}
+
+static void
+count_leaf(node, nchar, leaf_num, depth) /* call with node = root */
+    int node;
+    int nchar;
+    unsigned short leaf_num[];
+    int depth;
+{
+    if (node < nchar)
+        leaf_num[depth < 16 ? depth : 16]++;
+    else {
+        count_leaf(left[node], nchar, leaf_num, depth + 1);
+        count_leaf(right[node], nchar, leaf_num, depth + 1);
+    }
+}
+
+static void
+make_len(nchar, bitlen, sort, leaf_num)
+    int nchar;
+    unsigned char *bitlen;
+    unsigned short *sort;       /* sorted characters */
+    unsigned short *leaf_num;
+{
+    int i, k;
+    unsigned int cum;
+
+    cum = 0;
+    for (i = 16; i > 0; i--) {
+        cum += leaf_num[i] << (16 - i);
+    }
+#if (UINT_MAX != 0xffff)
+    cum &= 0xffff;
+#endif
+    /* adjust len */
+    if (cum) {
+        leaf_num[16] -= cum; /* always leaf_num[16] > cum */
+        do {
+            for (i = 15; i > 0; i--) {
+                if (leaf_num[i]) {
+                    leaf_num[i]--;
+                    leaf_num[i + 1] += 2;
+                    break;
+                }
+            }
+        } while (--cum);
+    }
+    /* make len */
+    for (i = 16; i > 0; i--) {
+        k = leaf_num[i];
+        while (k > 0) {
+            bitlen[*sort++] = i;
+            k--;
+        }
+    }
+}
+
+/* priority queue; send i-th entry down heap */
+static void
+downheap(i, heap, heapsize, freq)
+    int i;
+    short *heap;
+    size_t heapsize;
+    unsigned short *freq;
+{
+    short j, k;
+
+    k = heap[i];
+    while ((j = 2 * i) <= heapsize) {
+        if (j < heapsize && freq[heap[j]] > freq[heap[j + 1]])
+            j++;
+        if (freq[k] <= freq[heap[j]])
+            break;
+        heap[i] = heap[j];
+        i = j;
+    }
+    heap[i] = k;
+}
+
+/* make tree, calculate bitlen[], return root */
+short
+make_tree(nchar, freq, bitlen, code)
+    int             nchar;
+    unsigned short  *freq;
+    unsigned char   *bitlen;
+    unsigned short  *code;
+{
+    short i, j, avail, root;
+    unsigned short *sort;
+
+    short heap[NC + 1];       /* NC >= nchar */
+    size_t heapsize;
+
+    avail = nchar;
+    heapsize = 0;
+    heap[1] = 0;
+    for (i = 0; i < nchar; i++) {
+        bitlen[i] = 0;
+        if (freq[i])
+            heap[++heapsize] = i;
+    }
+    if (heapsize < 2) {
+        code[heap[1]] = 0;
+        return heap[1];
+    }
+
+    /* make priority queue */
+    for (i = heapsize / 2; i >= 1; i--)
+        downheap(i, heap, heapsize, freq);
+
+    /* make huffman tree */
+    sort = code;
+    do {            /* while queue has at least two entries */
+        i = heap[1];    /* take out least-freq entry */
+        if (i < nchar)
+            *sort++ = i;
+        heap[1] = heap[heapsize--];
+        downheap(1, heap, heapsize, freq);
+        j = heap[1];    /* next least-freq entry */
+        if (j < nchar)
+            *sort++ = j;
+        root = avail++;    /* generate new node */
+        freq[root] = freq[i] + freq[j];
+        heap[1] = root;
+        downheap(1, heap, heapsize, freq);    /* put into queue */
+        left[root] = i;
+        right[root] = j;
+    } while (heapsize > 1);
+
+    {
+        unsigned short leaf_num[17];
+
+        /* make leaf_num */
+        memset(leaf_num, 0, sizeof(leaf_num));
+        count_leaf(root, nchar, leaf_num, 0);
+
+        /* make bitlen */
+        make_len(nchar, bitlen, code, leaf_num);
+
+        /* make code table */
+        make_code(nchar, bitlen, code, leaf_num);
+    }
+
+    return root;
+}
diff --git a/vendor/gems/lhalib-0.8.1/ext/shuf.c b/vendor/gems/lhalib-0.8.1/ext/shuf.c
new file mode 100644 (file)
index 0000000..b99563c
--- /dev/null
@@ -0,0 +1,208 @@
+/* ------------------------------------------------------------------------ */
+/* LHa for UNIX                                                             */
+/*              shuf.c -- extract static Huffman coding                     */
+/*                                                                          */
+/*      Modified                Nobutaka Watazaki                           */
+/*                                                                          */
+/*  Ver. 1.14   Source All chagned              1995.01.14  N.Watazaki      */
+/* ------------------------------------------------------------------------ */
+#include "lha.h"
+
+/* ------------------------------------------------------------------------ */
+#undef NP
+#undef NP2
+
+#define NP          (8 * 1024 / 64)
+#define NP2         (NP * 2 - 1)
+/* ------------------------------------------------------------------------ */
+static unsigned int np;
+int             fixed[2][16] = {
+    {3, 0x01, 0x04, 0x0c, 0x18, 0x30, 0},   /* old compatible */
+    {2, 0x01, 0x01, 0x03, 0x06, 0x0D, 0x1F, 0x4E, 0}    /* 8K buf */
+};
+/* ------------------------------------------------------------------------ */
+/* lh3 */
+void
+decode_start_st0( /*void*/ )
+{
+    n_max = 286;
+    maxmatch = MAXMATCH;
+    init_getbits();
+    init_code_cache();
+    np = 1 << (LZHUFF3_DICBIT - 6);
+}
+
+/* ------------------------------------------------------------------------ */
+void
+encode_p_st0(unsigned short j)
+{
+    unsigned short  i;
+
+    i = j >> 6;
+    putcode(pt_len[i], pt_code[i]);
+    putbits(6, j & 0x3f);
+}
+
+/* ------------------------------------------------------------------------ */
+static void
+ready_made(method)
+    int             method;
+{
+    int             i, j;
+    unsigned int    code, weight;
+    int            *tbl;
+
+    tbl = fixed[method];
+    j = *tbl++;
+    weight = 1 << (16 - j);
+    code = 0;
+    for (i = 0; i < np; i++) {
+        while (*tbl == i) {
+            j++;
+            tbl++;
+            weight >>= 1;
+        }
+        pt_len[i] = j;
+        pt_code[i] = code;
+        code += weight;
+    }
+}
+
+/* ------------------------------------------------------------------------ */
+/* lh1 */
+void
+encode_start_fix( /*void*/ )
+{
+    n_max = 314;
+    maxmatch = 60;
+    np = 1 << (12 - 6);
+    init_putbits();
+    init_code_cache();
+    start_c_dyn();
+    ready_made(0);
+}
+
+/* ------------------------------------------------------------------------ */
+static void
+read_tree_c( /*void*/ )
+{               /* read tree from file */
+    int             i, c;
+
+    i = 0;
+    while (i < N1) {
+        if (getbits(1))
+            c_len[i] = getbits(LENFIELD) + 1;
+        else
+            c_len[i] = 0;
+        if (++i == 3 && c_len[0] == 1 && c_len[1] == 1 && c_len[2] == 1) {
+            c = getbits(CBIT);
+            for (i = 0; i < N1; i++)
+                c_len[i] = 0;
+            for (i = 0; i < 4096; i++)
+                c_table[i] = c;
+            return;
+        }
+    }
+    make_table(N1, c_len, 12, c_table);
+}
+
+/* ------------------------------------------------------------------------ */
+static void
+read_tree_p(/*void*/)
+{               /* read tree from file */
+    int             i, c;
+
+    i = 0;
+    while (i < NP) {
+        pt_len[i] = getbits(LENFIELD);
+        if (++i == 3 && pt_len[0] == 1 && pt_len[1] == 1 && pt_len[2] == 1) {
+            c = getbits(LZHUFF3_DICBIT - 6);
+            for (i = 0; i < NP; i++)
+                pt_len[i] = 0;
+            for (i = 0; i < 256; i++)
+                pt_table[i] = c;
+            return;
+        }
+    }
+}
+
+/* ------------------------------------------------------------------------ */
+/* lh1 */
+void
+decode_start_fix(/*void*/)
+{
+    n_max = 314;
+    maxmatch = 60;
+    init_getbits();
+    init_code_cache();
+    np = 1 << (LZHUFF1_DICBIT - 6);
+    start_c_dyn();
+    ready_made(0);
+    make_table(np, pt_len, 8, pt_table);
+}
+
+/* ------------------------------------------------------------------------ */
+/* lh3 */
+unsigned short
+decode_c_st0(/*void*/)
+{
+    int             i, j;
+    static unsigned short blocksize = 0;
+
+    if (blocksize == 0) {   /* read block head */
+        blocksize = getbits(BUFBITS);   /* read block blocksize */
+        read_tree_c();
+        if (getbits(1)) {
+            read_tree_p();
+        }
+        else {
+            ready_made(1);
+        }
+        make_table(NP, pt_len, 8, pt_table);
+    }
+    blocksize--;
+    j = c_table[peekbits(12)];
+    if (j < N1)
+        fillbuf(c_len[j]);
+    else {
+        fillbuf(12);
+        i = bitbuf;
+        do {
+            if ((short) i < 0)
+                j = right[j];
+            else
+                j = left[j];
+            i <<= 1;
+        } while (j >= N1);
+        fillbuf(c_len[j] - 12);
+    }
+    if (j == N1 - 1)
+        j += getbits(EXTRABITS);
+    return j;
+}
+
+/* ------------------------------------------------------------------------ */
+/* lh1, 3 */
+unsigned short
+decode_p_st0(/*void*/)
+{
+    int             i, j;
+
+    j = pt_table[peekbits(8)];
+    if (j < np) {
+        fillbuf(pt_len[j]);
+    }
+    else {
+        fillbuf(8);
+        i = bitbuf;
+        do {
+            if ((short) i < 0)
+                j = right[j];
+            else
+                j = left[j];
+            i <<= 1;
+        } while (j >= np);
+        fillbuf(pt_len[j] - 8);
+    }
+    return (j << 6) + getbits(6);
+}
diff --git a/vendor/gems/lhalib-0.8.1/ext/slide.c b/vendor/gems/lhalib-0.8.1/ext/slide.c
new file mode 100644 (file)
index 0000000..26d93d9
--- /dev/null
@@ -0,0 +1,481 @@
+/* ------------------------------------------------------------------------ */
+/* LHa for UNIX                                                             */
+/*              slide.c -- sliding dictionary with percolating update       */
+/*                                                                          */
+/*      Modified                Nobutaka Watazaki                           */
+/*                                                                          */
+/*  Ver. 1.14d  Exchanging a search algorithm  1997.01.11    T.Okamoto      */
+/* ------------------------------------------------------------------------ */
+
+#if 0
+#define DEBUG 1
+#endif
+
+#include "lha.h"
+
+#ifdef DEBUG
+FILE *fout = NULL;
+static int noslide = 1;
+#endif
+
+/* variables for hash */
+struct hash {
+    unsigned int pos;
+    int too_flag;               /* if 1, matching candidate is too many */
+} *hash;
+static unsigned int *prev;      /* previous posiion associated with hash */
+
+/* hash function: it represents 3 letters from `pos' on `text' */
+#define INIT_HASH(pos) \
+        ((( (text[(pos)] << 5) \
+           ^ text[(pos) + 1]  ) << 5) \
+           ^ text[(pos) + 2]         ) & (unsigned)(HSHSIZ - 1);
+#define NEXT_HASH(hash,pos) \
+        (((hash) << 5) \
+           ^ text[(pos) + 2]         ) & (unsigned)(HSHSIZ - 1);
+
+static struct encode_option encode_define[2] = {
+#if defined(__STDC__) || defined(AIX)
+    /* lh1 */
+    {(void (*) ()) output_dyn,
+     (void (*) ()) encode_start_fix,
+     (void (*) ()) encode_end_dyn},
+    /* lh4, 5, 6, 7 */
+    {(void (*) ()) output_st1,
+     (void (*) ()) encode_start_st1,
+     (void (*) ()) encode_end_st1}
+#else
+    /* lh1 */
+    {(int (*) ()) output_dyn,
+     (int (*) ()) encode_start_fix,
+     (int (*) ()) encode_end_dyn},
+    /* lh4, 5, 6, 7 */
+    {(int (*) ()) output_st1,
+     (int (*) ()) encode_start_st1,
+     (int (*) ()) encode_end_st1}
+#endif
+};
+
+static struct decode_option decode_define[] = {
+    /* lh1 */
+    {decode_c_dyn, decode_p_st0, decode_start_fix},
+    /* lh2 */
+    {decode_c_dyn, decode_p_dyn, decode_start_dyn},
+    /* lh3 */
+    {decode_c_st0, decode_p_st0, decode_start_st0},
+    /* lh4 */
+    {decode_c_st1, decode_p_st1, decode_start_st1},
+    /* lh5 */
+    {decode_c_st1, decode_p_st1, decode_start_st1},
+    /* lh6 */
+    {decode_c_st1, decode_p_st1, decode_start_st1},
+    /* lh7 */
+    {decode_c_st1, decode_p_st1, decode_start_st1},
+    /* lzs */
+    {decode_c_lzs, decode_p_lzs, decode_start_lzs},
+    /* lz5 */
+    {decode_c_lz5, decode_p_lz5, decode_start_lz5}
+};
+
+static struct encode_option encode_set;
+static struct decode_option decode_set;
+
+#define TXTSIZ (MAX_DICSIZ * 2L + MAXMATCH)
+#define HSHSIZ (((unsigned long)1) <<15)
+#define NIL 0
+#define LIMIT 0x100             /* limit of hash chain */
+
+static unsigned int txtsiz;
+static unsigned long dicsiz;
+static unsigned int remainder;
+
+struct matchdata {
+    int len;
+    unsigned int off;
+};
+
+int
+encode_alloc(method)
+    int method;
+{
+    switch (method) {
+    case LZHUFF1_METHOD_NUM:
+        encode_set = encode_define[0];
+        maxmatch = 60;
+        dicbit = LZHUFF1_DICBIT;    /* 12 bits  Changed N.Watazaki */
+        break;
+    case LZHUFF5_METHOD_NUM:
+        encode_set = encode_define[1];
+        maxmatch = MAXMATCH;
+        dicbit = LZHUFF5_DICBIT;    /* 13 bits */
+        break;
+    case LZHUFF6_METHOD_NUM:
+        encode_set = encode_define[1];
+        maxmatch = MAXMATCH;
+        dicbit = LZHUFF6_DICBIT;    /* 15 bits */
+        break;
+    case LZHUFF7_METHOD_NUM:
+        encode_set = encode_define[1];
+        maxmatch = MAXMATCH;
+        dicbit = LZHUFF7_DICBIT;    /* 16 bits */
+        break;
+    default:
+        error("unknown method %d", method);
+        exit(1);
+    }
+
+    dicsiz = (((unsigned long)1) << dicbit);
+    txtsiz = dicsiz*2+maxmatch;
+
+    if (hash) return method;
+
+    alloc_buf();
+
+    hash = (struct hash*)xmalloc(HSHSIZ * sizeof(struct hash));
+    prev = (unsigned int*)xmalloc(MAX_DICSIZ * sizeof(unsigned int));
+    text = (unsigned char*)xmalloc(TXTSIZ);
+
+    return method;
+}
+
+static void
+init_slide()
+{
+    unsigned int i;
+
+    for (i = 0; i < HSHSIZ; i++) {
+        hash[i].pos = NIL;
+        hash[i].too_flag = 0;
+    }
+}
+
+/* update dictionary */
+static void
+update_dict(pos, crc)
+    unsigned int *pos;
+    unsigned int *crc;
+{
+    unsigned int i, j;
+    long n;
+
+    memmove(&text[0], &text[dicsiz], txtsiz - dicsiz);
+
+    n = fread_crc(crc, &text[txtsiz - dicsiz], dicsiz, infile);
+
+    remainder += n;
+
+    *pos -= dicsiz;
+    for (i = 0; i < HSHSIZ; i++) {
+        j = hash[i].pos;
+        hash[i].pos = (j > dicsiz) ? j - dicsiz : NIL;
+        hash[i].too_flag = 0;
+    }
+    for (i = 0; i < dicsiz; i++) {
+        j = prev[i];
+        prev[i] = (j > dicsiz) ? j - dicsiz : NIL;
+    }
+}
+
+/* associate position with token */
+static void
+insert_hash(token, pos)
+    unsigned int token;
+    unsigned int pos;
+{
+    prev[pos & (dicsiz - 1)] = hash[token].pos; /* chain the previous pos. */
+    hash[token].pos = pos;
+}
+
+static void
+search_dict_1(token, pos, off, max, m)
+    unsigned int token;
+    unsigned int pos;
+    unsigned int off;
+    unsigned int max;           /* max. length of matching string */
+    struct matchdata *m;
+{
+    unsigned int chain = 0;
+    unsigned int scan_pos = hash[token].pos;
+    int scan_beg = scan_pos - off;
+    int scan_end = pos - dicsiz;
+    unsigned int len;
+
+    while (scan_beg > scan_end) {
+        chain++;
+
+        if (text[scan_beg + m->len] == text[pos + m->len]) {
+            {
+                /* collate token */
+                unsigned char *a = &text[scan_beg];
+                unsigned char *b = &text[pos];
+
+                for (len = 0; len < max && *a++ == *b++; len++);
+            }
+
+            if (len > m->len) {
+                m->off = pos - scan_beg;
+                m->len = len;
+                if (m->len == max)
+                    break;
+
+#ifdef DEBUG
+                if (noslide) {
+                    if (pos - m->off < dicsiz) {
+                        printf("matchpos=%u scan_pos=%u dicsiz=%u\n",
+                               pos - m->off, scan_pos, dicsiz);
+                    }
+                }
+#endif
+            }
+        }
+        scan_pos = prev[scan_pos & (dicsiz - 1)];
+        scan_beg = scan_pos - off;
+    }
+
+    if (chain >= LIMIT)
+        hash[token].too_flag = 1;
+}
+
+/* search the longest token matching to current token */
+static void
+search_dict(token, pos, min, m)
+    unsigned int token;         /* search token */
+    unsigned int pos;           /* position of token */
+    int min;                    /* min. length of matching string */
+    struct matchdata *m;
+{
+    unsigned int off, tok, max;
+
+    if (min < THRESHOLD - 1) min = THRESHOLD - 1;
+
+    max = maxmatch;
+    m->off = 0;
+    m->len = min;
+
+    off = 0;
+    for (tok = token; hash[tok].too_flag && off < maxmatch - THRESHOLD; ) {
+        /* If matching position is too many, The search key is
+           changed into following token from `off' (for speed). */
+        ++off;
+        tok = NEXT_HASH(tok, pos+off);
+    }
+    if (off == maxmatch - THRESHOLD) {
+        off = 0;
+        tok = token;
+    }
+
+    search_dict_1(tok, pos, off, max, m);
+
+    if (off > 0 && m->len < off + 3)
+        /* re-search */
+        search_dict_1(token, pos, 0, off+2, m);
+
+    if (m->len > remainder) m->len = remainder;
+}
+
+/* slide dictionary */
+static void
+next_token(token, pos, crc)
+    unsigned int *token;
+    unsigned int *pos;
+    unsigned int *crc;
+{
+    remainder--;
+    if (++*pos >= txtsiz - maxmatch) {
+        update_dict(pos, crc);
+#ifdef DEBUG
+        noslide = 0;
+#endif
+    }
+    *token = NEXT_HASH(*token, *pos);
+}
+
+unsigned int
+encode(intf)
+    struct interfacing *intf;
+{
+    unsigned int token, pos, crc;
+    size_t count;
+    struct matchdata match, last;
+
+#ifdef DEBUG
+    if (!fout)
+        fout = xfopen("en", "wt");
+    fprintf(fout, "[filename: %s]\n", reading_filename);
+#endif
+    infile = intf->infile;
+    outfile = intf->outfile;
+    origsize = intf->original;
+    compsize = count = 0L;
+    unpackable = 0;
+
+    INITIALIZE_CRC(crc);
+
+    init_slide();
+
+    encode_set.encode_start();
+    memset(text, ' ', TXTSIZ);
+
+    remainder = fread_crc(&crc, &text[dicsiz], txtsiz-dicsiz, infile);
+
+    match.len = THRESHOLD - 1;
+    match.off = 0;
+    if (match.len > remainder) match.len = remainder;
+
+    pos = dicsiz;
+    token = INIT_HASH(pos);
+    insert_hash(token, pos);     /* associate token and pos */
+
+    while (remainder > 0 && ! unpackable) {
+        last = match;
+
+        next_token(&token, &pos, &crc);
+        search_dict(token, pos, last.len-1, &match);
+        insert_hash(token, pos);
+
+        if (match.len > last.len || last.len < THRESHOLD) {
+            /* output a letter */
+            encode_set.output(text[pos - 1], 0);
+#ifdef DEBUG
+            fprintf(fout, "%u C %02X\n", count, text[pos-1]);
+#endif
+            count++;
+        } else {
+            /* output length and offset */
+            encode_set.output(last.len + (256 - THRESHOLD),
+                              (last.off-1) & (dicsiz-1) );
+
+#ifdef DEBUG
+            {
+                int i;
+                unsigned char *ptr;
+                unsigned int offset = (last.off & (dicsiz-1));
+
+                fprintf(fout, "%u M <%u %u> ",
+                        count, last.len, count - offset);
+
+                ptr = &text[pos-1 - offset];
+                for (i=0; i < last.len; i++)
+                    fprintf(fout, "%02X ", ptr[i]);
+                fprintf(fout, "\n");
+            }
+#endif
+            count += last.len;
+
+            --last.len;
+            while (--last.len > 0) {
+                next_token(&token, &pos, &crc);
+                insert_hash(token, pos);
+            }
+            next_token(&token, &pos, &crc);
+            search_dict(token, pos, THRESHOLD - 1, &match);
+            insert_hash(token, pos);
+        }
+    }
+    encode_set.encode_end();
+
+    intf->packed = compsize;
+    intf->original = count;
+
+    return crc;
+}
+
+unsigned int
+decode(intf)
+    struct interfacing *intf;
+{
+    unsigned int i, c;
+    unsigned int dicsiz1, adjust;
+    unsigned char *dtext;
+    unsigned int crc;
+
+#ifdef DEBUG
+    if (!fout)
+        fout = xfopen("de", "wt");
+    fprintf(fout, "[filename: %s]\n", writing_filename);
+#endif
+
+    infile = intf->infile;
+    outfile = intf->outfile;
+    dicbit = intf->dicbit;
+    origsize = intf->original;
+    compsize = intf->packed;
+    decode_set = decode_define[intf->method - 1];
+
+    INITIALIZE_CRC(crc);
+    dicsiz = 1L << dicbit;
+    dtext = (unsigned char *)xmalloc(dicsiz);
+
+    if (extract_broken_archive)
+
+        /* LHa for UNIX (autoconf) had a fatal bug since version
+           1.14i-ac20030713 (slide.c revision 1.20).
+
+           This bug is possible to make a broken archive, proper LHA
+           cannot extract it (probably it report CRC error).
+
+           If the option "--extract-broken-archive" specified, extract
+           the broken archive made by old LHa for UNIX. */
+        memset(dtext, 0, dicsiz);
+    else
+        memset(dtext, ' ', dicsiz);
+    decode_set.decode_start();
+    dicsiz1 = dicsiz - 1;
+    adjust = 256 - THRESHOLD;
+    if (intf->method == LARC_METHOD_NUM)
+        adjust = 256 - 2;
+
+    decode_count = 0;
+    loc = 0;
+    while (decode_count < origsize) {
+        c = decode_set.decode_c();
+        if (c < 256) {
+#ifdef DEBUG
+          fprintf(fout, "%u C %02X\n", decode_count, c);
+#endif
+            dtext[loc++] = c;
+            if (loc == dicsiz) {
+                fwrite_crc(&crc, dtext, dicsiz, outfile);
+                loc = 0;
+            }
+            decode_count++;
+        }
+        else {
+            struct matchdata match;
+            unsigned int matchpos;
+
+            match.len = c - adjust;
+            match.off = decode_set.decode_p() + 1;
+            matchpos = (loc - match.off) & dicsiz1;
+#ifdef DEBUG
+            fprintf(fout, "%u M <%u %u> ",
+                    decode_count, match.len, decode_count-match.off);
+#endif
+            decode_count += match.len;
+            for (i = 0; i < match.len; i++) {
+                c = dtext[(matchpos + i) & dicsiz1];
+#ifdef DEBUG
+                fprintf(fout, "%02X ", c & 0xff);
+#endif
+                dtext[loc++] = c;
+                if (loc == dicsiz) {
+                    fwrite_crc(&crc, dtext, dicsiz, outfile);
+                    loc = 0;
+                }
+            }
+#ifdef DEBUG
+            fprintf(fout, "\n");
+#endif
+        }
+    }
+    if (loc != 0) {
+        fwrite_crc(&crc, dtext, loc, outfile);
+    }
+
+    free(dtext);
+
+    /* usually read size is intf->packed */
+    intf->read_size = intf->packed - compsize;
+
+    return crc;
+}
diff --git a/vendor/gems/lhalib-0.8.1/ext/util.c b/vendor/gems/lhalib-0.8.1/ext/util.c
new file mode 100644 (file)
index 0000000..39ed4d6
--- /dev/null
@@ -0,0 +1,224 @@
+/* ------------------------------------------------------------------------ */
+/* LHa for UNIX                                                             */
+/*              util.c -- LHarc Util                                        */
+/*                                                                          */
+/*      Modified                Nobutaka Watazaki                           */
+/*                                                                          */
+/*  Ver. 1.14   Source All chagned              1995.01.14  N.Watazaki      */
+/*  Ver. 1.14e  Support for sfx archives        1999.05.28  T.Okamoto       */
+/*      Modified arton for LhaLib */
+/* ------------------------------------------------------------------------ */
+#include "lha.h"
+/*
+ * util.c - part of LHa for UNIX Feb 26 1992 modified by Masaru Oki Mar  4
+ * 1992 modified by Masaru Oki #ifndef USESTRCASECMP added. Mar 31 1992
+ * modified by Masaru Oki #ifdef NOMEMSET added.
+ */
+#include <errno.h>
+
+size_t
+copyfile(FILE* f1, FILE* f2, size_t size, int text_flg, unsigned int* crcp)  /* return: size of source file */
+    /* int text_flg*/             /* 0: binary, 1: read text, 2: write text */
+{
+    unsigned short  xsize;
+    char *buf;
+    size_t rsize = 0;
+
+    if (!text_mode)
+        text_flg = 0;
+
+    buf = (char *)xmalloc(BUFFERSIZE);
+    if (crcp)
+        INITIALIZE_CRC(*crcp);
+    if (text_flg)
+        init_code_cache();
+    while (size > 0) {
+        /* read */
+        if (text_flg & 1) {
+            xsize = fread_txt(buf, BUFFERSIZE, f1);
+            if (xsize == 0)
+                break;
+            if (ferror(f1)) {
+                fatal_error("file read error");
+            }
+        }
+        else {
+            xsize = (size > BUFFERSIZE) ? BUFFERSIZE : size;
+            if (fread(buf, 1, xsize, f1) != xsize) {
+                fatal_error("file read error");
+            }
+            if (size < xsize)
+                size = 0;
+            else
+                size -= xsize;
+        }
+
+        /* write */
+        if (f2) {
+            if (text_flg & 2) {
+                if (fwrite_txt(buf, xsize, f2)) {
+                    fatal_error("file write error");
+                }
+            }
+            else {
+                if (fwrite(buf, 1, xsize, f2) != xsize) {
+                    fatal_error("file write error");
+                }
+            }
+        }
+
+        /* calculate crc */
+        if (crcp) {
+            *crcp = calccrc(*crcp, buf, xsize);
+#ifdef NEED_INCREMENTAL_INDICATOR
+            put_indicator(xsize);
+#endif
+        }
+        rsize += xsize;
+    }
+    free(buf);
+    return rsize;
+}
+
+int
+encode_stored_crc(ifp, ofp, size, original_size_var, write_size_var)
+    FILE *ifp, *ofp;
+    size_t size;
+    size_t *original_size_var;
+    size_t *write_size_var;
+{
+    unsigned int crc;
+
+    size = copyfile(ifp, ofp, size, 1, &crc);
+    *original_size_var = *write_size_var = size;
+    return crc;
+}
+
+/* If TRUE, archive file name is msdos SFX file name. */
+boolean
+archive_is_msdos_sfx1(const char* name)
+{
+    int len = strlen(name);
+
+    if (len >= 4) {
+        if (strcasecmp(".COM", name + len - 4) == 0 ||
+            strcasecmp(".EXE", name + len - 4) == 0)
+            return 1;
+    }
+
+    if (len >= 2 && strcasecmp(".x", name + len - 2) == 0)
+        return 1;
+
+    return 0;
+}
+
+int
+#if STDC_HEADERS
+xsnprintf(char *dest, size_t size, char *fmt, ...)
+#else
+xsnprintf(dest, size, fmt, va_alist)
+    char *dest, *fmt;
+    size_t size;
+    va_dcl
+#endif
+{
+    int len;
+    va_list v;
+
+    va_init(v, fmt);
+    len = vsnprintf(dest, size, fmt, v);
+    va_end(v);
+
+    if (len == -1)
+        return -1;
+
+    if (len >= size) {
+        dest[size-1] = 0;
+        return -1;
+    }
+
+    return 0;
+}
+
+#if !STRCHR_8BIT_CLEAN
+/* 8 bit clean strchr()/strrchr()/memchr()/memrchr() */
+char *
+xstrchr(const char *s, int c)
+{
+    if (c == 0)
+        return (char*)s + strlen(s);
+
+    while (*s) {
+        if ((unsigned char)*s == (unsigned char)c)
+            return (char*)s;
+        s++;
+    }
+
+    return 0;
+}
+
+char *
+xstrrchr(const char *s, int c)
+{
+    char *p = 0;
+
+    while (*s) {
+        if ((unsigned char)*s == (unsigned char)c)
+            p = (char*)s;
+        s++;
+    }
+
+    return p;
+}
+
+char *
+xmemchr(const char *s, int c, size_t n)
+{
+    char *end = (char*)s + n;
+
+    while (s != end) {
+        if ((unsigned char)*s == (unsigned char)c)
+            return (char*)s;
+        s++;
+    }
+
+    return 0;
+}
+
+char *
+xmemrchr(const char *s, int c, size_t n)
+{
+    char *end = (char*)s-1;
+    char *p = 0;
+
+    s += n-1;
+    while (s != end) {
+        if ((unsigned char)*s == (unsigned char)c)
+            p = (char*)s;
+        s--;
+    }
+
+    return p;
+}
+#endif
+
+/* This function is similar to strncpy() but `dst' is always
+   terminated by '\0'. Return the copied string length. */
+int
+str_safe_copy(char *dst, const char *src, int dstsz)
+{
+    int i;
+
+    if (dstsz < 1) return 0;
+
+    for (i = 0; i < dstsz; i++) {
+       if ((dst[i] = src[i]) == '\0')
+           return i;
+    }
+
+    /* here is i == dstsz */
+    dst[--i] = '\0';   /* if eliminated this line,
+                          this function was same as strncpy(). */
+
+    return i;
+}
diff --git a/vendor/gems/lhalib-0.8.1/readme.txt b/vendor/gems/lhalib-0.8.1/readme.txt
new file mode 100644 (file)
index 0000000..440a3ae
--- /dev/null
@@ -0,0 +1,4 @@
+LhaLib is a Ruby extension library that unpack LHarched file.
+
+The C sources were originally written by Y.Tagawa, M.Oki, N.Watazaki, T.Okamoto and other people, and original Lha was written by Y.Yoshizaki in early Japanese Personal Computer days.
+This library is a separate production from original LHa, and released under LGPL (the origianl LHa is distributed under the proprietary license). So the product's responsibility is dedicated by arton.
diff --git a/vendor/gems/lhalib-0.8.1/setup.rb b/vendor/gems/lhalib-0.8.1/setup.rb
new file mode 100644 (file)
index 0000000..c13725d
--- /dev/null
@@ -0,0 +1,1360 @@
+#
+# setup.rb
+#
+# Copyright (c) 2000-2004 Minero Aoki
+#
+# This program is free software.
+# You can distribute/modify this program under the terms of
+# the GNU LGPL, Lesser General Public License version 2.1.
+#
+
+unless Enumerable.method_defined?(:map)   # Ruby 1.4.6
+  module Enumerable
+    alias map collect
+  end
+end
+
+unless File.respond_to?(:read)   # Ruby 1.6
+  def File.read(fname)
+    open(fname) {|f|
+      return f.read
+    }
+  end
+end
+
+def File.binread(fname)
+  open(fname, 'rb') {|f|
+    return f.read
+  }
+end
+
+# for corrupted windows stat(2)
+def File.dir?(path)
+  File.directory?((path[-1,1] == '/') ? path : path + '/')
+end
+
+
+class SetupError < StandardError; end
+
+def setup_rb_error(msg)
+  raise SetupError, msg
+end
+
+#
+# Config
+#
+
+if arg = ARGV.detect {|arg| /\A--rbconfig=/ =~ arg }
+  ARGV.delete(arg)
+  require arg.split(/=/, 2)[1]
+  $".push 'rbconfig.rb'
+else
+  require 'rbconfig'
+end
+
+def multipackage_install?
+  FileTest.directory?(File.dirname($0) + '/packages')
+end
+
+
+class ConfigItem
+  def initialize(name, template, default, desc)
+    @name = name.freeze
+    @template = template
+    @value = default
+    @default = default.dup.freeze
+    @description = desc
+  end
+
+  attr_reader :name
+  attr_reader :description
+
+  attr_accessor :default
+  alias help_default default
+
+  def help_opt
+    "--#{@name}=#{@template}"
+  end
+
+  def value
+    @value
+  end
+
+  def eval(table)
+    @value.gsub(%r<\$([^/]+)>) { table[$1] }
+  end
+
+  def set(val)
+    @value = check(val)
+  end
+
+  private
+
+  def check(val)
+    setup_rb_error "config: --#{name} requires argument" unless val
+    val
+  end
+end
+
+class BoolItem < ConfigItem
+  def config_type
+    'bool'
+  end
+
+  def help_opt
+    "--#{@name}"
+  end
+
+  private
+
+  def check(val)
+    return 'yes' unless val
+    unless /\A(y(es)?|n(o)?|t(rue)?|f(alse))\z/i =~ val
+      setup_rb_error "config: --#{@name} accepts only yes/no for argument"
+    end
+    (/\Ay(es)?|\At(rue)/i =~ value) ? 'yes' : 'no'
+  end
+end
+
+class PathItem < ConfigItem
+  def config_type
+    'path'
+  end
+
+  private
+
+  def check(path)
+    setup_rb_error "config: --#{@name} requires argument"  unless path
+    path[0,1] == '$' ? path : File.expand_path(path)
+  end
+end
+
+class ProgramItem < ConfigItem
+  def config_type
+    'program'
+  end
+end
+
+class SelectItem < ConfigItem
+  def initialize(name, template, default, desc)
+    super
+    @ok = template.split('/')
+  end
+
+  def config_type
+    'select'
+  end
+
+  private
+
+  def check(val)
+    unless @ok.include?(val.strip)
+      setup_rb_error "config: use --#{@name}=#{@template} (#{val})"
+    end
+    val.strip
+  end
+end
+
+class PackageSelectionItem < ConfigItem
+  def initialize(name, template, default, help_default, desc)
+    super name, template, default, desc
+    @help_default = help_default
+  end
+
+  attr_reader :help_default
+
+  def config_type
+    'package'
+  end
+
+  private
+
+  def check(val)
+    unless File.dir?("packages/#{val}")
+      setup_rb_error "config: no such package: #{val}"
+    end
+    val
+  end
+end
+
+class ConfigTable_class
+
+  def initialize(items)
+    @items = items
+    @table = {}
+    items.each do |i|
+      @table[i.name] = i
+    end
+    ALIASES.each do |ali, name|
+      @table[ali] = @table[name]
+    end
+  end
+
+  include Enumerable
+
+  def each(&block)
+    @items.each(&block)
+  end
+
+  def key?(name)
+    @table.key?(name)
+  end
+
+  def lookup(name)
+    @table[name] or raise ArgumentError, "no such config item: #{name}"
+  end
+
+  def add(item)
+    @items.push item
+    @table[item.name] = item
+  end
+
+  def remove(name)
+    item = lookup(name)
+    @items.delete_if {|i| i.name == name }
+    @table.delete_if {|name, i| i.name == name }
+    item
+  end
+
+  def new
+    dup()
+  end
+
+  def savefile
+    '.config'
+  end
+
+  def load
+    begin
+      t = dup()
+      File.foreach(savefile()) do |line|
+        k, v = *line.split(/=/, 2)
+        t[k] = v.strip
+      end
+      t
+    rescue Errno::ENOENT
+      setup_rb_error $!.message + "#{File.basename($0)} config first"
+    end
+  end
+
+  def save
+    @items.each {|i| i.value }
+    File.open(savefile(), 'w') {|f|
+      @items.each do |i|
+        f.printf "%s=%s\n", i.name, i.value if i.value
+      end
+    }
+  end
+
+  def [](key)
+    lookup(key).eval(self)
+  end
+
+  def []=(key, val)
+    lookup(key).set val
+  end
+
+end
+
+c = ::Config::CONFIG
+
+rubypath = c['bindir'] + '/' + c['ruby_install_name']
+
+major = c['MAJOR'].to_i
+minor = c['MINOR'].to_i
+teeny = c['TEENY'].to_i
+version = "#{major}.#{minor}"
+
+# ruby ver. >= 1.4.4?
+newpath_p = ((major >= 2) or
+             ((major == 1) and
+              ((minor >= 5) or
+               ((minor == 4) and (teeny >= 4)))))
+
+if c['rubylibdir']
+  # V < 1.6.3
+  _stdruby         = c['rubylibdir']
+  _siteruby        = c['sitedir']
+  _siterubyver     = c['sitelibdir']
+  _siterubyverarch = c['sitearchdir']
+elsif newpath_p
+  # 1.4.4 <= V <= 1.6.3
+  _stdruby         = "$prefix/lib/ruby/#{version}"
+  _siteruby        = c['sitedir']
+  _siterubyver     = "$siteruby/#{version}"
+  _siterubyverarch = "$siterubyver/#{c['arch']}"
+else
+  # V < 1.4.4
+  _stdruby         = "$prefix/lib/ruby/#{version}"
+  _siteruby        = "$prefix/lib/ruby/#{version}/site_ruby"
+  _siterubyver     = _siteruby
+  _siterubyverarch = "$siterubyver/#{c['arch']}"
+end
+libdir = '-* dummy libdir *-'
+stdruby = '-* dummy rubylibdir *-'
+siteruby = '-* dummy site_ruby *-'
+siterubyver = '-* dummy site_ruby version *-'
+parameterize = lambda {|path|
+  path.sub(/\A#{Regexp.quote(c['prefix'])}/, '$prefix')\
+      .sub(/\A#{Regexp.quote(libdir)}/,      '$libdir')\
+      .sub(/\A#{Regexp.quote(stdruby)}/,     '$stdruby')\
+      .sub(/\A#{Regexp.quote(siteruby)}/,    '$siteruby')\
+      .sub(/\A#{Regexp.quote(siterubyver)}/, '$siterubyver')
+}
+libdir          = parameterize.call(c['libdir'])
+stdruby         = parameterize.call(_stdruby)
+siteruby        = parameterize.call(_siteruby)
+siterubyver     = parameterize.call(_siterubyver)
+siterubyverarch = parameterize.call(_siterubyverarch)
+
+if arg = c['configure_args'].split.detect {|arg| /--with-make-prog=/ =~ arg }
+  makeprog = arg.sub(/'/, '').split(/=/, 2)[1]
+else
+  makeprog = 'make'
+end
+
+common_conf = [
+  PathItem.new('prefix', 'path', c['prefix'],
+               'path prefix of target environment'),
+  PathItem.new('bindir', 'path', parameterize.call(c['bindir']),
+               'the directory for commands'),
+  PathItem.new('libdir', 'path', libdir,
+               'the directory for libraries'),
+  PathItem.new('datadir', 'path', parameterize.call(c['datadir']),
+               'the directory for shared data'),
+  PathItem.new('mandir', 'path', parameterize.call(c['mandir']),
+               'the directory for man pages'),
+  PathItem.new('sysconfdir', 'path', parameterize.call(c['sysconfdir']),
+               'the directory for man pages'),
+  PathItem.new('stdruby', 'path', stdruby,
+               'the directory for standard ruby libraries'),
+  PathItem.new('siteruby', 'path', siteruby,
+      'the directory for version-independent aux ruby libraries'),
+  PathItem.new('siterubyver', 'path', siterubyver,
+               'the directory for aux ruby libraries'),
+  PathItem.new('siterubyverarch', 'path', siterubyverarch,
+               'the directory for aux ruby binaries'),
+  PathItem.new('rbdir', 'path', '$siterubyver',
+               'the directory for ruby scripts'),
+  PathItem.new('sodir', 'path', '$siterubyverarch',
+               'the directory for ruby extentions'),
+  PathItem.new('rubypath', 'path', rubypath,
+               'the path to set to #! line'),
+  ProgramItem.new('rubyprog', 'name', rubypath,
+                  'the ruby program using for installation'),
+  ProgramItem.new('makeprog', 'name', makeprog,
+                  'the make program to compile ruby extentions'),
+  SelectItem.new('shebang', 'all/ruby/never', 'ruby',
+                 'shebang line (#!) editing mode'),
+  BoolItem.new('without-ext', 'yes/no', 'no',
+               'does not compile/install ruby extentions')
+]
+class ConfigTable_class   # open again
+  ALIASES = {
+    'std-ruby'         => 'stdruby',
+    'site-ruby-common' => 'siteruby',     # For backward compatibility
+    'site-ruby'        => 'siterubyver',  # For backward compatibility
+    'bin-dir'          => 'bindir',
+    'bin-dir'          => 'bindir',
+    'rb-dir'           => 'rbdir',
+    'so-dir'           => 'sodir',
+    'data-dir'         => 'datadir',
+    'ruby-path'        => 'rubypath',
+    'ruby-prog'        => 'rubyprog',
+    'ruby'             => 'rubyprog',
+    'make-prog'        => 'makeprog',
+    'make'             => 'makeprog'
+  }
+end
+multipackage_conf = [
+  PackageSelectionItem.new('with', 'name,name...', '', 'ALL',
+                           'package names that you want to install'),
+  PackageSelectionItem.new('without', 'name,name...', '', 'NONE',
+                           'package names that you do not want to install')
+]
+if multipackage_install?
+  ConfigTable = ConfigTable_class.new(common_conf + multipackage_conf)
+else
+  ConfigTable = ConfigTable_class.new(common_conf)
+end
+
+
+module MetaConfigAPI
+
+  def eval_file_ifexist(fname)
+    instance_eval File.read(fname), fname, 1 if File.file?(fname)
+  end
+
+  def config_names
+    ConfigTable.map {|i| i.name }
+  end
+
+  def config?(name)
+    ConfigTable.key?(name)
+  end
+
+  def bool_config?(name)
+    ConfigTable.lookup(name).config_type == 'bool'
+  end
+
+  def path_config?(name)
+    ConfigTable.lookup(name).config_type == 'path'
+  end
+
+  def value_config?(name)
+    case ConfigTable.lookup(name).config_type
+    when 'bool', 'path'
+      true
+    else
+      false
+    end
+  end
+
+  def add_config(item)
+    ConfigTable.add item
+  end
+
+  def add_bool_config(name, default, desc)
+    ConfigTable.add BoolItem.new(name, 'yes/no', default ? 'yes' : 'no', desc)
+  end
+
+  def add_path_config(name, default, desc)
+    ConfigTable.add PathItem.new(name, 'path', default, desc)
+  end
+
+  def set_config_default(name, default)
+    ConfigTable.lookup(name).default = default
+  end
+
+  def remove_config(name)
+    ConfigTable.remove(name)
+  end
+
+end
+
+
+#
+# File Operations
+#
+
+module FileOperations
+
+  def mkdir_p(dirname, prefix = nil)
+    dirname = prefix + File.expand_path(dirname) if prefix
+    $stderr.puts "mkdir -p #{dirname}" if verbose?
+    return if no_harm?
+
+    # does not check '/'... it's too abnormal case
+    dirs = File.expand_path(dirname).split(%r<(?=/)>)
+    if /\A[a-z]:\z/i =~ dirs[0]
+      disk = dirs.shift
+      dirs[0] = disk + dirs[0]
+    end
+    dirs.each_index do |idx|
+      path = dirs[0..idx].join('')
+      Dir.mkdir path unless File.dir?(path)
+    end
+  end
+
+  def rm_f(fname)
+    $stderr.puts "rm -f #{fname}" if verbose?
+    return if no_harm?
+
+    if File.exist?(fname) or File.symlink?(fname)
+      File.chmod 0777, fname
+      File.unlink fname
+    end
+  end
+
+  def rm_rf(dn)
+    $stderr.puts "rm -rf #{dn}" if verbose?
+    return if no_harm?
+
+    Dir.chdir dn
+    Dir.foreach('.') do |fn|
+      next if fn == '.'
+      next if fn == '..'
+      if File.dir?(fn)
+        verbose_off {
+          rm_rf fn
+        }
+      else
+        verbose_off {
+          rm_f fn
+        }
+      end
+    end
+    Dir.chdir '..'
+    Dir.rmdir dn
+  end
+
+  def move_file(src, dest)
+    File.unlink dest if File.exist?(dest)
+    begin
+      File.rename src, dest
+    rescue
+      File.open(dest, 'wb') {|f| f.write File.binread(src) }
+      File.chmod File.stat(src).mode, dest
+      File.unlink src
+    end
+  end
+
+  def install(from, dest, mode, prefix = nil)
+    $stderr.puts "install #{from} #{dest}" if verbose?
+    return if no_harm?
+
+    realdest = prefix ? prefix + File.expand_path(dest) : dest
+    realdest = File.join(realdest, File.basename(from)) if File.dir?(realdest)
+    str = File.binread(from)
+    if diff?(str, realdest)
+      verbose_off {
+        rm_f realdest if File.exist?(realdest)
+      }
+      File.open(realdest, 'wb') {|f|
+        f.write str
+      }
+      File.chmod mode, realdest
+
+      File.open("#{objdir_root()}/InstalledFiles", 'a') {|f|
+        if prefix
+          f.puts realdest.sub(prefix, '')
+        else
+          f.puts realdest
+        end
+      }
+    end
+  end
+
+  def diff?(new_content, path)
+    return true unless File.exist?(path)
+    new_content != File.binread(path)
+  end
+
+  def command(str)
+    $stderr.puts str if verbose?
+    system str or raise RuntimeError, "'system #{str}' failed"
+  end
+
+  def ruby(str)
+    command config('rubyprog') + ' ' + str
+  end
+  
+  def make(task = '')
+    command config('makeprog') + ' ' + task
+  end
+
+  def extdir?(dir)
+    File.exist?(dir + '/MANIFEST')
+  end
+
+  def all_files_in(dirname)
+    Dir.open(dirname) {|d|
+      return d.select {|ent| File.file?("#{dirname}/#{ent}") }
+    }
+  end
+
+  REJECT_DIRS = %w(
+    CVS SCCS RCS CVS.adm .svn
+  )
+
+  def all_dirs_in(dirname)
+    Dir.open(dirname) {|d|
+      return d.select {|n| File.dir?("#{dirname}/#{n}") } - %w(. ..) - REJECT_DIRS
+    }
+  end
+
+end
+
+
+#
+# Main Installer
+#
+
+module HookUtils
+
+  def run_hook(name)
+    try_run_hook "#{curr_srcdir()}/#{name}" or
+    try_run_hook "#{curr_srcdir()}/#{name}.rb"
+  end
+
+  def try_run_hook(fname)
+    return false unless File.file?(fname)
+    begin
+      instance_eval File.read(fname), fname, 1
+    rescue
+      setup_rb_error "hook #{fname} failed:\n" + $!.message
+    end
+    true
+  end
+
+end
+
+
+module HookScriptAPI
+
+  def get_config(key)
+    @config[key]
+  end
+
+  alias config get_config
+
+  def set_config(key, val)
+    @config[key] = val
+  end
+
+  #
+  # srcdir/objdir (works only in the package directory)
+  #
+
+  #abstract srcdir_root
+  #abstract objdir_root
+  #abstract relpath
+
+  def curr_srcdir
+    "#{srcdir_root()}/#{relpath()}"
+  end
+
+  def curr_objdir
+    "#{objdir_root()}/#{relpath()}"
+  end
+
+  def srcfile(path)
+    "#{curr_srcdir()}/#{path}"
+  end
+
+  def srcexist?(path)
+    File.exist?(srcfile(path))
+  end
+
+  def srcdirectory?(path)
+    File.dir?(srcfile(path))
+  end
+  
+  def srcfile?(path)
+    File.file? srcfile(path)
+  end
+
+  def srcentries(path = '.')
+    Dir.open("#{curr_srcdir()}/#{path}") {|d|
+      return d.to_a - %w(. ..)
+    }
+  end
+
+  def srcfiles(path = '.')
+    srcentries(path).select {|fname|
+      File.file?(File.join(curr_srcdir(), path, fname))
+    }
+  end
+
+  def srcdirectories(path = '.')
+    srcentries(path).select {|fname|
+      File.dir?(File.join(curr_srcdir(), path, fname))
+    }
+  end
+
+end
+
+
+class ToplevelInstaller
+
+  Version   = '3.3.1'
+  Copyright = 'Copyright (c) 2000-2004 Minero Aoki'
+
+  TASKS = [
+    [ 'all',      'do config, setup, then install' ],
+    [ 'config',   'saves your configurations' ],
+    [ 'show',     'shows current configuration' ],
+    [ 'setup',    'compiles ruby extentions and others' ],
+    [ 'install',  'installs files' ],
+    [ 'clean',    "does `make clean' for each extention" ],
+    [ 'distclean',"does `make distclean' for each extention" ]
+  ]
+
+  def ToplevelInstaller.invoke
+    instance().invoke
+  end
+
+  @singleton = nil
+
+  def ToplevelInstaller.instance
+    @singleton ||= new(File.dirname($0))
+    @singleton
+  end
+
+  include MetaConfigAPI
+
+  def initialize(ardir_root)
+    @config = nil
+    @options = { 'verbose' => true }
+    @ardir = File.expand_path(ardir_root)
+  end
+
+  def inspect
+    "#<#{self.class} #{__id__()}>"
+  end
+
+  def invoke
+    run_metaconfigs
+    case task = parsearg_global()
+    when nil, 'all'
+      @config = load_config('config')
+      parsearg_config
+      init_installers
+      exec_config
+      exec_setup
+      exec_install
+    else
+      @config = load_config(task)
+      __send__ "parsearg_#{task}"
+      init_installers
+      __send__ "exec_#{task}"
+    end
+  end
+  
+  def run_metaconfigs
+    eval_file_ifexist "#{@ardir}/metaconfig"
+  end
+
+  def load_config(task)
+    case task
+    when 'config'
+      ConfigTable.new
+    when 'clean', 'distclean'
+      if File.exist?(ConfigTable.savefile)
+      then ConfigTable.load
+      else ConfigTable.new
+      end
+    else
+      ConfigTable.load
+    end
+  end
+
+  def init_installers
+    @installer = Installer.new(@config, @options, @ardir, File.expand_path('.'))
+  end
+
+  #
+  # Hook Script API bases
+  #
+
+  def srcdir_root
+    @ardir
+  end
+
+  def objdir_root
+    '.'
+  end
+
+  def relpath
+    '.'
+  end
+
+  #
+  # Option Parsing
+  #
+
+  def parsearg_global
+    valid_task = /\A(?:#{TASKS.map {|task,desc| task }.join '|'})\z/
+
+    while arg = ARGV.shift
+      case arg
+      when /\A\w+\z/
+        setup_rb_error "invalid task: #{arg}" unless valid_task =~ arg
+        return arg
+
+      when '-q', '--quiet'
+        @options['verbose'] = false
+
+      when       '--verbose'
+        @options['verbose'] = true
+
+      when '-h', '--help'
+        print_usage $stdout
+        exit 0
+
+      when '-v', '--version'
+        puts "#{File.basename($0)} version #{Version}"
+        exit 0
+      
+      when '--copyright'
+        puts Copyright
+        exit 0
+
+      else
+        setup_rb_error "unknown global option '#{arg}'"
+      end
+    end
+
+    nil
+  end
+
+
+  def parsearg_no_options
+    unless ARGV.empty?
+      setup_rb_error "#{task}:  unknown options: #{ARGV.join ' '}"
+    end
+  end
+
+  alias parsearg_show       parsearg_no_options
+  alias parsearg_setup      parsearg_no_options
+  alias parsearg_clean      parsearg_no_options
+  alias parsearg_distclean  parsearg_no_options
+
+  def parsearg_config
+    re = /\A--(#{ConfigTable.map {|i| i.name }.join('|')})(?:=(.*))?\z/
+    @options['config-opt'] = []
+
+    while i = ARGV.shift
+      if /\A--?\z/ =~ i
+        @options['config-opt'] = ARGV.dup
+        break
+      end
+      m = re.match(i)  or setup_rb_error "config: unknown option #{i}"
+      name, value = *m.to_a[1,2]
+      @config[name] = value
+    end
+  end
+
+  def parsearg_install
+    @options['no-harm'] = false
+    @options['install-prefix'] = ''
+    while a = ARGV.shift
+      case a
+      when /\A--no-harm\z/
+        @options['no-harm'] = true
+      when /\A--prefix=(.*)\z/
+        path = $1
+        path = File.expand_path(path) unless path[0,1] == '/'
+        @options['install-prefix'] = path
+      else
+        setup_rb_error "install: unknown option #{a}"
+      end
+    end
+  end
+
+  def print_usage(out)
+    out.puts 'Typical Installation Procedure:'
+    out.puts "  $ ruby #{File.basename $0} config"
+    out.puts "  $ ruby #{File.basename $0} setup"
+    out.puts "  # ruby #{File.basename $0} install (may require root privilege)"
+    out.puts
+    out.puts 'Detailed Usage:'
+    out.puts "  ruby #{File.basename $0} <global option>"
+    out.puts "  ruby #{File.basename $0} [<global options>] <task> [<task options>]"
+
+    fmt = "  %-24s %s\n"
+    out.puts
+    out.puts 'Global options:'
+    out.printf fmt, '-q,--quiet',   'suppress message outputs'
+    out.printf fmt, '   --verbose', 'output messages verbosely'
+    out.printf fmt, '-h,--help',    'print this message'
+    out.printf fmt, '-v,--version', 'print version and quit'
+    out.printf fmt, '   --copyright',  'print copyright and quit'
+    out.puts
+    out.puts 'Tasks:'
+    TASKS.each do |name, desc|
+      out.printf fmt, name, desc
+    end
+
+    fmt = "  %-24s %s [%s]\n"
+    out.puts
+    out.puts 'Options for CONFIG or ALL:'
+    ConfigTable.each do |item|
+      out.printf fmt, item.help_opt, item.description, item.help_default
+    end
+    out.printf fmt, '--rbconfig=path', 'rbconfig.rb to load',"running ruby's"
+    out.puts
+    out.puts 'Options for INSTALL:'
+    out.printf fmt, '--no-harm', 'only display what to do if given', 'off'
+    out.printf fmt, '--prefix=path',  'install path prefix', '$prefix'
+    out.puts
+  end
+
+  #
+  # Task Handlers
+  #
+
+  def exec_config
+    @installer.exec_config
+    @config.save   # must be final
+  end
+
+  def exec_setup
+    @installer.exec_setup
+  end
+
+  def exec_install
+    @installer.exec_install
+  end
+
+  def exec_show
+    ConfigTable.each do |i|
+      printf "%-20s %s\n", i.name, i.value
+    end
+  end
+
+  def exec_clean
+    @installer.exec_clean
+  end
+
+  def exec_distclean
+    @installer.exec_distclean
+  end
+
+end
+
+
+class ToplevelInstallerMulti < ToplevelInstaller
+
+  include HookUtils
+  include HookScriptAPI
+  include FileOperations
+
+  def initialize(ardir)
+    super
+    @packages = all_dirs_in("#{@ardir}/packages")
+    raise 'no package exists' if @packages.empty?
+  end
+
+  def run_metaconfigs
+    eval_file_ifexist "#{@ardir}/metaconfig"
+    @packages.each do |name|
+      eval_file_ifexist "#{@ardir}/packages/#{name}/metaconfig"
+    end
+  end
+
+  def init_installers
+    @installers = {}
+    @packages.each do |pack|
+      @installers[pack] = Installer.new(@config, @options,
+                                       "#{@ardir}/packages/#{pack}",
+                                       "packages/#{pack}")
+    end
+
+    with    = extract_selection(config('with'))
+    without = extract_selection(config('without'))
+    @selected = @installers.keys.select {|name|
+                  (with.empty? or with.include?(name)) \
+                      and not without.include?(name)
+                }
+  end
+
+  def extract_selection(list)
+    a = list.split(/,/)
+    a.each do |name|
+      setup_rb_error "no such package: #{name}"  unless @installers.key?(name)
+    end
+    a
+  end
+
+  def print_usage(f)
+    super
+    f.puts 'Inluded packages:'
+    f.puts '  ' + @packages.sort.join(' ')
+    f.puts
+  end
+
+  #
+  # multi-package metaconfig API
+  #
+
+  attr_reader :packages
+
+  def declare_packages(list)
+    raise 'package list is empty' if list.empty?
+    list.each do |name|
+      raise "directory packages/#{name} does not exist"\
+              unless File.dir?("#{@ardir}/packages/#{name}")
+    end
+    @packages = list
+  end
+
+  #
+  # Task Handlers
+  #
+
+  def exec_config
+    run_hook 'pre-config'
+    each_selected_installers {|inst| inst.exec_config }
+    run_hook 'post-config'
+    @config.save   # must be final
+  end
+
+  def exec_setup
+    run_hook 'pre-setup'
+    each_selected_installers {|inst| inst.exec_setup }
+    run_hook 'post-setup'
+  end
+
+  def exec_install
+    run_hook 'pre-install'
+    each_selected_installers {|inst| inst.exec_install }
+    run_hook 'post-install'
+  end
+
+  def exec_clean
+    rm_f ConfigTable.savefile
+    run_hook 'pre-clean'
+    each_selected_installers {|inst| inst.exec_clean }
+    run_hook 'post-clean'
+  end
+
+  def exec_distclean
+    rm_f ConfigTable.savefile
+    run_hook 'pre-distclean'
+    each_selected_installers {|inst| inst.exec_distclean }
+    run_hook 'post-distclean'
+  end
+
+  #
+  # lib
+  #
+
+  def each_selected_installers
+    Dir.mkdir 'packages' unless File.dir?('packages')
+    @selected.each do |pack|
+      $stderr.puts "Processing the package `#{pack}' ..." if @options['verbose']
+      Dir.mkdir "packages/#{pack}" unless File.dir?("packages/#{pack}")
+      Dir.chdir "packages/#{pack}"
+      yield @installers[pack]
+      Dir.chdir '../..'
+    end
+  end
+
+  def verbose?
+    @options['verbose']
+  end
+
+  def no_harm?
+    @options['no-harm']
+  end
+
+end
+
+
+class Installer
+
+  FILETYPES = %w( bin lib ext data )
+
+  include HookScriptAPI
+  include HookUtils
+  include FileOperations
+
+  def initialize(config, opt, srcroot, objroot)
+    @config = config
+    @options = opt
+    @srcdir = File.expand_path(srcroot)
+    @objdir = File.expand_path(objroot)
+    @currdir = '.'
+  end
+
+  def inspect
+    "#<#{self.class} #{File.basename(@srcdir)}>"
+  end
+
+  #
+  # Hook Script API base methods
+  #
+
+  def srcdir_root
+    @srcdir
+  end
+
+  def objdir_root
+    @objdir
+  end
+
+  def relpath
+    @currdir
+  end
+
+  #
+  # configs/options
+  #
+
+  def no_harm?
+    @options['no-harm']
+  end
+
+  def verbose?
+    @options['verbose']
+  end
+
+  def verbose_off
+    begin
+      save, @options['verbose'] = @options['verbose'], false
+      yield
+    ensure
+      @options['verbose'] = save
+    end
+  end
+
+  #
+  # TASK config
+  #
+
+  def exec_config
+    exec_task_traverse 'config'
+  end
+
+  def config_dir_bin(rel)
+  end
+
+  def config_dir_lib(rel)
+  end
+
+  def config_dir_ext(rel)
+    extconf if extdir?(curr_srcdir())
+  end
+
+  def extconf
+    opt = @options['config-opt'].join(' ')
+    command "#{config('rubyprog')} \"#{curr_srcdir()}/extconf.rb\" #{opt}"
+  end
+
+  def config_dir_data(rel)
+  end
+
+  #
+  # TASK setup
+  #
+
+  def exec_setup
+    exec_task_traverse 'setup'
+  end
+
+  def setup_dir_bin(rel)
+    all_files_in(curr_srcdir()).each do |fname|
+      adjust_shebang "#{curr_srcdir()}/#{fname}"
+    end
+  end
+
+  def adjust_shebang(path)
+    return if no_harm?
+    tmpfile = File.basename(path) + '.tmp'
+    begin
+      File.open(path, 'rb') {|r|
+        first = r.gets
+        return unless File.basename(config('rubypath')) == 'ruby'
+        return unless File.basename(first.sub(/\A\#!/, '').split[0]) == 'ruby'
+        $stderr.puts "adjusting shebang: #{File.basename(path)}" if verbose?
+        File.open(tmpfile, 'wb') {|w|
+          w.print first.sub(/\A\#!\s*\S+/, '#! ' + config('rubypath'))
+          w.write r.read
+        }
+        move_file tmpfile, File.basename(path)
+      }
+    ensure
+      File.unlink tmpfile if File.exist?(tmpfile)
+    end
+  end
+
+  def setup_dir_lib(rel)
+  end
+
+  def setup_dir_ext(rel)
+    make if extdir?(curr_srcdir())
+  end
+
+  def setup_dir_data(rel)
+  end
+
+  #
+  # TASK install
+  #
+
+  def exec_install
+    rm_f 'InstalledFiles'
+    exec_task_traverse 'install'
+  end
+
+  def install_dir_bin(rel)
+    install_files collect_filenames_auto(), "#{config('bindir')}/#{rel}", 0755
+  end
+
+  def install_dir_lib(rel)
+    install_files ruby_scripts(), "#{config('rbdir')}/#{rel}", 0644
+  end
+
+  def install_dir_ext(rel)
+    return unless extdir?(curr_srcdir())
+    install_files ruby_extentions('.'),
+                  "#{config('sodir')}/#{File.dirname(rel)}",
+                  0555
+  end
+
+  def install_dir_data(rel)
+    install_files collect_filenames_auto(), "#{config('datadir')}/#{rel}", 0644
+  end
+
+  def install_files(list, dest, mode)
+    mkdir_p dest, @options['install-prefix']
+    list.each do |fname|
+      install fname, dest, mode, @options['install-prefix']
+    end
+  end
+
+  def ruby_scripts
+    collect_filenames_auto().select {|n| /\.rb\z/ =~ n }
+  end
+  
+  # picked up many entries from cvs-1.11.1/src/ignore.c
+  reject_patterns = %w( 
+    core RCSLOG tags TAGS .make.state
+    .nse_depinfo #* .#* cvslog.* ,* .del-* *.olb
+    *~ *.old *.bak *.BAK *.orig *.rej _$* *$
+
+    *.org *.in .*
+  )
+  mapping = {
+    '.' => '\.',
+    '$' => '\$',
+    '#' => '\#',
+    '*' => '.*'
+  }
+  REJECT_PATTERNS = Regexp.new('\A(?:' +
+                               reject_patterns.map {|pat|
+                                 pat.gsub(/[\.\$\#\*]/) {|ch| mapping[ch] }
+                               }.join('|') +
+                               ')\z')
+
+  def collect_filenames_auto
+    mapdir((existfiles() - hookfiles()).reject {|fname|
+             REJECT_PATTERNS =~ fname
+           })
+  end
+
+  def existfiles
+    all_files_in(curr_srcdir()) | all_files_in('.')
+  end
+
+  def hookfiles
+    %w( pre-%s post-%s pre-%s.rb post-%s.rb ).map {|fmt|
+      %w( config setup install clean ).map {|t| sprintf(fmt, t) }
+    }.flatten
+  end
+
+  def mapdir(filelist)
+    filelist.map {|fname|
+      if File.exist?(fname)   # objdir
+        fname
+      else                    # srcdir
+        File.join(curr_srcdir(), fname)
+      end
+    }
+  end
+
+  def ruby_extentions(dir)
+    Dir.open(dir) {|d|
+      ents = d.select {|fname| /\.#{::Config::CONFIG['DLEXT']}\z/ =~ fname }
+      if ents.empty?
+        setup_rb_error "no ruby extention exists: 'ruby #{$0} setup' first"
+      end
+      return ents
+    }
+  end
+
+  #
+  # TASK clean
+  #
+
+  def exec_clean
+    exec_task_traverse 'clean'
+    rm_f ConfigTable.savefile
+    rm_f 'InstalledFiles'
+  end
+
+  def clean_dir_bin(rel)
+  end
+
+  def clean_dir_lib(rel)
+  end
+
+  def clean_dir_ext(rel)
+    return unless extdir?(curr_srcdir())
+    make 'clean' if File.file?('Makefile')
+  end
+
+  def clean_dir_data(rel)
+  end
+
+  #
+  # TASK distclean
+  #
+
+  def exec_distclean
+    exec_task_traverse 'distclean'
+    rm_f ConfigTable.savefile
+    rm_f 'InstalledFiles'
+  end
+
+  def distclean_dir_bin(rel)
+  end
+
+  def distclean_dir_lib(rel)
+  end
+
+  def distclean_dir_ext(rel)
+    return unless extdir?(curr_srcdir())
+    make 'distclean' if File.file?('Makefile')
+  end
+
+  #
+  # lib
+  #
+
+  def exec_task_traverse(task)
+    run_hook "pre-#{task}"
+    FILETYPES.each do |type|
+      if config('without-ext') == 'yes' and type == 'ext'
+        $stderr.puts 'skipping ext/* by user option' if verbose?
+        next
+      end
+      traverse task, type, "#{task}_dir_#{type}"
+    end
+    run_hook "post-#{task}"
+  end
+
+  def traverse(task, rel, mid)
+    dive_into(rel) {
+      run_hook "pre-#{task}"
+      __send__ mid, rel.sub(%r[\A.*?(?:/|\z)], '')
+      all_dirs_in(curr_srcdir()).each do |d|
+        traverse task, "#{rel}/#{d}", mid
+      end
+      run_hook "post-#{task}"
+    }
+  end
+
+  def dive_into(rel)
+    return unless File.dir?("#{@srcdir}/#{rel}")
+
+    dir = File.basename(rel)
+    Dir.mkdir dir unless File.dir?(dir)
+    prevdir = Dir.pwd
+    Dir.chdir dir
+    $stderr.puts '---> ' + rel if verbose?
+    @currdir = rel
+    yield
+    Dir.chdir prevdir
+    $stderr.puts '<--- ' + rel if verbose?
+    @currdir = File.dirname(rel)
+  end
+
+end
+
+
+if $0 == __FILE__
+  begin
+    if multipackage_install?
+      ToplevelInstallerMulti.invoke
+    else
+      ToplevelInstaller.invoke
+    end
+  rescue SetupError
+    raise if $DEBUG
+    $stderr.puts $!.message
+    $stderr.puts "Try 'ruby #{$0} --help' for detailed usage."
+    exit 1
+  end
+end
diff --git a/vendor/gems/lhalib-0.8.1/test/test.dat.org b/vendor/gems/lhalib-0.8.1/test/test.dat.org
new file mode 100644 (file)
index 0000000..c866266
Binary files /dev/null and b/vendor/gems/lhalib-0.8.1/test/test.dat.org differ
diff --git a/vendor/gems/lhalib-0.8.1/test/test.lzh b/vendor/gems/lhalib-0.8.1/test/test.lzh
new file mode 100644 (file)
index 0000000..e40ceeb
Binary files /dev/null and b/vendor/gems/lhalib-0.8.1/test/test.lzh differ
diff --git a/vendor/gems/lhalib-0.8.1/test/test.rb b/vendor/gems/lhalib-0.8.1/test/test.rb
new file mode 100644 (file)
index 0000000..98724cb
--- /dev/null
@@ -0,0 +1,86 @@
+#!/usr/local/env ruby
+# $Id: $
+
+require 'test/unit'
+require 'fileutils'
+require 'lhalib'
+
+puts "start LhaLib(#{LhaLib::VERSION} test"
+class TestLhaLib < Test::Unit::TestCase
+  include LhaLib
+  def setup
+    FileUtils.rm_rf ['test.dat', 'testlib.c', 'testh.h', 'tmp']
+  end
+
+  def tearDown
+  end
+
+  def test_copy_only
+    assert_equal(1, x('test.lzh'))
+    assert(File.exist?('test.dat'))
+    obuff = ' ' * 256
+    (0..255).each do |x|
+      obuff[x] = x
+    end
+    nbuff = nil
+    File.open('test.dat', 'rb') do |f|
+      nbuff = f.read
+    end
+    assert_equal(obuff, nbuff)
+  end
+
+  def test_x
+    assert_equal(2, x('test2.lzh'))
+    assert(File.exist?('testlib.c'))
+    assert(File.exist?('testh.h'))
+    check_file('testlib.c')
+    check_file('testh.h')
+  end
+
+  def test_x_withdir
+    assert_equal(4, x('tmpdir.lzh'))
+    assert(File.exist?('tmp/testlib.c'))
+    assert(File.exist?('tmp/testh.h'))
+    check_file('testlib.c', 'tmp')
+    check_file('testh.h', 'tmp')
+  end
+
+  def test_proc
+    i = 0
+    name = ['tmp/', 'tmp/test.dat', 'tmp/testh.h', 'tmp/testlib.c']
+    size = [0, 256, 9310, 1997]
+    # directory = S_IFDIR | 0755, file = S_IFREG + 0644
+    perm = [040755, 0100644, 0100644, 0100644]
+    cnt = x('tmpdir.lzh') do |info|
+      assert_equal(name[i], info[:name])
+      assert_equal(size[i], info[:original_size])
+      assert_equal(perm[i], info[:permission])
+      i += 1
+    end
+    # normal extract process was done ?
+    assert_equal(4, cnt)
+    assert_equal(4, i)
+    assert(File.exist?('tmp/testlib.c'))
+    assert(File.exist?('tmp/testh.h'))
+    check_file('testlib.c', 'tmp')
+    check_file('testh.h', 'tmp')
+  end
+
+  def test_badarchive
+    assert_equal(0, x('test.rb'))
+  end
+
+  private
+  def check_file(name, dir = nil)
+    org = nil
+    File.open("#{name}.org", 'rb') do |f|
+      org = f.read
+    end
+    ex = nil
+    File.open(dir ? "#{dir}/#{name}" : name, 'rb') do |f|
+      ex = f.read
+    end
+    assert_equal(org, ex)
+  end
+end
+
diff --git a/vendor/gems/lhalib-0.8.1/test/test2.lzh b/vendor/gems/lhalib-0.8.1/test/test2.lzh
new file mode 100644 (file)
index 0000000..f6eeb5e
Binary files /dev/null and b/vendor/gems/lhalib-0.8.1/test/test2.lzh differ
diff --git a/vendor/gems/lhalib-0.8.1/test/testh.h.org b/vendor/gems/lhalib-0.8.1/test/testh.h.org
new file mode 100644 (file)
index 0000000..dad3c99
--- /dev/null
@@ -0,0 +1,377 @@
+/* ------------------------------------------------------------------------ */
+/* LHa for UNIX    Archiver Driver                                          */
+/*                                                                          */
+/*      Modified                Nobutaka Watazaki                           */
+/*                                                                          */
+/*  Ver. 1.14   Soruce All chagned              1995.01.14  N.Watazaki      */
+/*  Ver. 1.14i  Modified and bug fixed          2000.10.06  t.okamoto       */
+/* ------------------------------------------------------------------------ */
+/*      Modified arton for LhaLib */
+/*
+    Included...
+        lharc.h     interface.h     slidehuf.h
+*/
+
+#include "ruby.h"
+
+#include <stdio.h>
+#include <time.h>
+#include <errno.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/file.h>
+#include <sys/stat.h>
+#include <signal.h>
+
+#if HAVE_INTTYPES_H
+# include <inttypes.h>
+#else
+# if HAVE_STDINT_H
+#  include <stdint.h>
+# endif
+#endif
+
+#if STDC_HEADERS
+# include <string.h>
+#else
+# if !HAVE_STRCHR
+#  define strchr index
+#  define strrchr rindex
+# endif
+char *strchr (), *strrchr ();
+# if !HAVE_MEMCPY
+#  define memcmp(s1, s2, n) bcmp ((s1), (s2), (n))
+#  define memcpy(d, s, n) bcopy ((s), (d), (n))
+#  define memmove(d, s, n) bcopy ((s), (d), (n))
+# endif
+#endif
+
+#if STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# if HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif
+
+#ifndef NULL
+#define NULL ((char *)0)
+#endif
+
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#if STDC_HEADERS
+# include <stdarg.h>
+# define va_init(a,b) va_start(a,b)
+#else
+# include <varargs.h>
+# define va_init(a,b) va_start(a)
+#endif
+
+#if HAVE_PWD_H
+# include <pwd.h>
+#endif
+#if HAVE_GRP_H
+# include <grp.h>
+#endif
+
+#if !HAVE_SETUID
+typedef int uid_t;
+#endif
+#if !HAVE_SETGID
+typedef int gid_t;
+#endif
+
+#if !HAVE_UINT64_T
+# define HAVE_UINT64_T 1
+# if SIZEOF_LONG == 8
+    typedef unsigned long uint64_t;
+# elif HAVE_LONG_LONG
+    typedef unsigned long long uint64_t;
+# else
+#  undef HAVE_UINT64_T
+# endif
+#endif
+
+/*
+#if !HAVE_SSIZE_T
+typedef long ssize_t;
+#endif
+*/
+
+#if HAVE_SYS_TIME_H
+# include <sys/time.h>
+#else
+# include <time.h>
+#endif
+
+#if HAVE_UTIME_H
+#include <utime.h>
+#else
+struct utimbuf {
+    time_t actime;
+    time_t modtime;
+};
+int utime(const char *, struct utimbuf *);
+#endif
+
+#if HAVE_DIRENT_H
+# include <dirent.h>
+# define NAMLEN(dirent) strlen((dirent)->d_name)
+#else
+# define dirent direct
+# define NAMLEN(dirent) (dirent)->d_namlen
+# if HAVE_SYS_NDIR_H
+#  include <sys/ndir.h>
+# endif
+# if HAVE_SYS_DIR_H
+#  include <sys/dir.h>
+# endif
+# if HAVE_NDIR_H
+#  include <ndir.h>
+# endif
+# ifdef NONSYSTEM_DIR_LIBRARY           /* no use ?? */
+#  include "lhdir.h"
+# endif
+#endif
+
+#if HAVE_FNMATCH_H
+# include <fnmatch.h>
+#else
+int fnmatch(const char *pattern, const char *string, int flags);
+# define FNM_PATHNAME 1
+# define FNM_NOESCAPE 2
+# define FNM_PERIOD   4
+#endif
+
+#ifndef SEEK_SET
+#define SEEK_SET        0
+#define SEEK_CUR        1
+#define SEEK_END        2
+#endif  /* SEEK_SET */
+
+#if HAVE_LIMITS_H
+#include <limits.h>
+#else
+
+#ifndef CHAR_BIT
+#define CHAR_BIT 8
+#endif
+
+#ifndef UCHAR_MAX
+#define UCHAR_MAX ((1<<(sizeof(unsigned char)*8))-1)
+#endif
+
+#ifndef USHRT_MAX
+#define USHRT_MAX ((1<<(sizeof(unsigned short)*8))-1)
+#endif
+
+#ifndef SHRT_MAX
+#define SHRT_MAX ((1<<(sizeof(short)*8-1))-1)
+#endif
+
+#ifndef SHRT_MIN
+#define SHRT_MIN (SHRT_MAX-USHRT_MAX)
+#endif
+
+#ifndef ULONG_MAX
+#define ULONG_MAX ((1<<(sizeof(unsigned long)*8))-1)
+#endif
+
+#ifndef LONG_MAX
+#define LONG_MAX ((1<<(sizeof(long)*8-1))-1)
+#endif
+
+#ifndef LONG_MIN
+#define LONG_MIN (LONG_MAX-ULONG_MAX)
+#endif
+
+#endif /* HAVE_LIMITS_H */
+
+#if !HAVE_FSEEKO
+# define fseeko  fseek
+#endif
+#if !HAVE_FTELLO
+# define ftello  ftell
+#endif
+
+#include "lha/lha_macro.h"
+
+#define exit(n) lha_exit(n)
+
+struct encode_option {
+#if defined(__STDC__) || defined(AIX)
+    void            (*output) ();
+    void            (*encode_start) ();
+    void            (*encode_end) ();
+#else
+    int             (*output) ();
+    int             (*encode_start) ();
+    int             (*encode_end) ();
+#endif
+};
+
+struct decode_option {
+    unsigned short  (*decode_c) ();
+    unsigned short  (*decode_p) ();
+#if defined(__STDC__) || defined(AIX)
+    void            (*decode_start) ();
+#else
+    int             (*decode_start) ();
+#endif
+};
+
+/* ------------------------------------------------------------------------ */
+/*  LHa File Type Definition                                                */
+/* ------------------------------------------------------------------------ */
+typedef int boolean;            /* TRUE or FALSE */
+
+struct string_pool {
+    int             used;
+    int             size;
+    int             n;
+    char           *buffer;
+};
+
+typedef struct LzHeader {
+    size_t          header_size;
+    int             size_field_length;
+    char            method[METHOD_TYPE_STORAGE];
+    size_t          packed_size;
+    size_t          original_size;
+    unsigned char   attribute;
+    unsigned char   header_level;
+    char            name[FILENAME_LENGTH];
+    char            realname[FILENAME_LENGTH];/* real name for symbolic link */
+    unsigned int    crc;      /* file CRC */
+    boolean         has_crc;  /* file CRC */
+    unsigned int    header_crc; /* header CRC */
+    unsigned char   extend_type;
+    unsigned char   minor_version;
+
+    /* extend_type == EXTEND_UNIX  and convert from other type. */
+    time_t          unix_last_modified_stamp;
+    unsigned short  unix_mode;
+    unsigned short  unix_uid;
+    unsigned short  unix_gid;
+    char            user[256];
+    char            group[256];
+}  LzHeader;
+
+struct interfacing {
+    FILE            *infile;
+    FILE            *outfile;
+    size_t          original;
+    size_t          packed;
+    size_t          read_size;
+    int             dicbit;
+    int             method;
+};
+
+
+typedef void addfile_handler(const char*);
+
+RUBY_EXTERN void cmd_extract(const char* archive_name, 
+                            addfile_handler hnd);
+
+#define fatal_error rb_fatal
+#define warning rb_warning
+
+RUBY_EXTERN FILE * open_old_archive(const char* archive);
+RUBY_EXTERN boolean need_file(const char*);
+RUBY_EXTERN boolean archive_is_msdos_sfx1(const char*);
+RUBY_EXTERN void output_dyn();
+RUBY_EXTERN void encode_start_fix();
+RUBY_EXTERN void encode_end_dyn();
+RUBY_EXTERN void output_st1();
+RUBY_EXTERN void encode_start_st0();
+RUBY_EXTERN void encode_end_st0();
+RUBY_EXTERN void encode_start_st1();
+RUBY_EXTERN void encode_end_st1();
+RUBY_EXTERN unsigned short decode_c_dyn();
+RUBY_EXTERN unsigned short decode_p_dyn();
+RUBY_EXTERN void decode_start_fix();
+RUBY_EXTERN void decode_start_dyn();
+RUBY_EXTERN void decode_start_st0();
+RUBY_EXTERN void decode_start_st1();
+RUBY_EXTERN unsigned short decode_c_st0();
+RUBY_EXTERN unsigned short decode_c_st1();
+RUBY_EXTERN unsigned short decode_p_st0();
+RUBY_EXTERN unsigned short decode_p_st1();
+RUBY_EXTERN unsigned short decode_c_lzs();
+RUBY_EXTERN unsigned short decode_p_lzs();
+RUBY_EXTERN void decode_start_lzs();
+RUBY_EXTERN unsigned short decode_c_lz5();
+RUBY_EXTERN unsigned short decode_p_lz5();
+RUBY_EXTERN void decode_start_lz5();
+RUBY_EXTERN void make_crctable();
+
+#define start_indicator(name, size, ing, len) 0
+#define finish_indicator(name, ed) 0
+
+#if defined(LHALIB_VERSION)
+  #define LHA_EXTERN
+#else
+  #define LHA_EXTERN RUBY_EXTERN
+#endif
+
+RUBY_EXTERN boolean lha_force;
+RUBY_EXTERN boolean lha_verbose;
+RUBY_EXTERN boolean lha_ignore_directory;
+RUBY_EXTERN boolean extract_broken_archive;
+RUBY_EXTERN boolean lha_noconvertcase;
+RUBY_EXTERN boolean lha_generic_format;
+RUBY_EXTERN boolean lha_text_mode;
+RUBY_EXTERN int lha_n_max;
+RUBY_EXTERN unsigned short lha_maxmatch;
+RUBY_EXTERN int lha_overwrite;
+
+LHA_EXTERN unsigned short bitbuf;
+LHA_EXTERN unsigned short dicbit;
+LHA_EXTERN size_t lha_decode_count;
+LHA_EXTERN size_t lha_origsize;
+LHA_EXTERN size_t lha_compsize;
+LHA_EXTERN int lha_unpackable;
+LHA_EXTERN unsigned long lha_loc;
+LHA_EXTERN unsigned char* lha_text;
+LHA_EXTERN unsigned short lha_left[], lha_right[];
+LHA_EXTERN unsigned char lha_c_len[], lha_pt_len[];
+LHA_EXTERN unsigned short lha_c_freq[], lha_c_table[], lha_c_code[];
+LHA_EXTERN unsigned short lha_p_freq[], lha_pt_table[], lha_pt_code[], lha_t_freq[];
+LHA_EXTERN unsigned int crctable[UCHAR_MAX + 1];
+LHA_EXTERN FILE* infile;
+LHA_EXTERN FILE* outfile;
+LHA_EXTERN int archive_file_gid;
+LHA_EXTERN int archive_file_mode;
+LHA_EXTERN int header_level;
+
+#define force lha_force
+#define verbose lha_verbose
+#define verbose_listing lha_verbose
+#define ignore_directory lha_ignore_directory
+#define n_max lha_n_max
+#define maxmatch lha_maxmatch
+#define decode_count lha_decode_count
+#define unpackable lha_unpackable
+#define left lha_left
+#define right lha_right
+#define c_len lha_c_len
+#define pt_len lha_pt_len
+#define c_freq lha_c_freq
+#define c_table lha_c_table
+#define c_code lha_c_code
+#define p_freq lha_pt_freq
+#define pt_table lha_pt_table
+#define pt_code lha_pt_code
+#define t_freq lha_t_freq
+#define loc lha_loc
+#define text lha_text
+#define origsize lha_origsize
+#define compsize lha_compsize
+#define noconvertcase lha_noconvertcase
+#define generic_format lha_generic_format
+#define text_mode lha_text_mode
+#define overwrite lha_overwrite
diff --git a/vendor/gems/lhalib-0.8.1/test/testlib.c.org b/vendor/gems/lhalib-0.8.1/test/testlib.c.org
new file mode 100644 (file)
index 0000000..8072f77
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * LhaLib for Ruby
+ * Copyright(c) 2006 arton
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * $Id:$
+ */
+
+#define LHALIB_VERSION "0.8.0"
+
+#include "lha.h"
+#include "st.h"
+
+static VALUE lhalib;
+
+boolean lha_force = FALSE;
+boolean lha_verbose = FALSE;
+boolean lha_ignore_directory = FALSE;
+boolean extract_broken_archive = FALSE;
+boolean lha_noconvertcase = FALSE;
+boolean lha_generic_format = FALSE;
+boolean lha_text_mode = FALSE;
+int overwrite = 1;
+int lha_n_max;
+unsigned short lha_maxmatch;
+unsigned short bitbuf;
+size_t lha_decode_count;
+int lha_unpackable;
+unsigned long lha_loc;
+unsigned char* lha_text;
+FILE* infile;
+FILE* outfile;
+int archive_file_gid;
+int archive_file_mode;
+
+void add_file(const char* file)
+{
+}
+
+static VALUE s_ex(VALUE self, VALUE file)
+{
+  rb_check_safe_str(file);
+  rb_secure(4);
+  make_crctable();
+  cmd_extract(StringValueCStr(file), add_file);
+}
+
+static VALUE s_open(int argc, VALUE* argv, VALUE self)
+{
+  VALUE file;
+  VALUE proc;
+  rb_scan_args(argc, argv, "1&", &file, &proc);
+  rb_check_safe_str(file);
+  rb_secure(4);
+
+  make_crctable();
+  cmd_extract(StringValueCStr(file), add_file);
+  if (!NIL_P(proc))
+    {
+      rb_yield(file);
+    }
+}
+
+
+/*
+ * Class initializer called by Ruby while requiring this library
+ */
+void Init_lhalib()
+{
+    header_level = 2;
+    lhalib = rb_define_module("LhaLib");
+    rb_define_module_function(lhalib, "x", s_open, -1);
+    rb_define_module_function(lhalib, "x", s_ex, 1);
+    rb_define_const(lhalib, "VERSION", rb_str_new2(LHALIB_VERSION));
+
+}
diff --git a/vendor/gems/lhalib-0.8.1/test/tmpdir.lzh b/vendor/gems/lhalib-0.8.1/test/tmpdir.lzh
new file mode 100644 (file)
index 0000000..1d8ec9e
Binary files /dev/null and b/vendor/gems/lhalib-0.8.1/test/tmpdir.lzh differ
diff --git a/vendor/plugins/acts_as_paranoid/CHANGELOG b/vendor/plugins/acts_as_paranoid/CHANGELOG
new file mode 100644 (file)
index 0000000..f8925c9
--- /dev/null
@@ -0,0 +1,79 @@
+* (16 Apr 2009)
+
+Allow :with_deleted and :only_deleted options to work with count and calculate.
+Fixes compatibility with will_paginate. [James Le Cuirot]
+
+* (4 Oct 2007)
+
+Update for Edge rails: remove support for legacy #count args 
+
+* (2 Feb 2007)
+
+Add support for custom primary keys [Jeff Dean]
+
+* (2 July 2006)
+
+Add paranoid delete_all implementation [Marshall Roch]
+
+* (23 May 2006)
+
+Allow setting of future dates for content expiration.
+
+* (15 May 2006)
+
+Added support for dynamic finders
+
+* (28 Mar 2006)
+
+Updated for Rails 1.1.  I love removing code.
+
+  Refactored #find method
+  Nested Scopes
+
+*0.3.1* (20 Dec 2005)
+
+* took out deleted association code for 'chainsaw butchery of base classes' [sorry Erik Terpstra]
+* verified tests pass on Rails 1.0
+
+*0.3* (27 Nov 2005)
+
+* Deleted models will find deleted associations by default now [Erik Terpstra]
+* Added :group as valid option for find [Michael Dabney]
+* Changed the module namespace to Caboose::Acts::Paranoid
+
+*0.2.0* (6 Nov 2005)
+
+* Upgrade to Rails 1.0 RC4.  ActiveRecord::Base#constrain has been replaced with scope_with.
+
+*0.1.7* (22 Oct 2005)
+
+* Added :with_deleted as a valid option of ActiveRecord::Base#find
+
+*0.1.6* (25 Sep 2005)
+
+* Fixed bug where nested constrains would get clobbered after multiple queries
+
+*0.1.5* (22 Sep 2005)
+
+* Fixed bug where acts_as_paranoid would clobber other constrains
+* Simplified acts_as_paranoid mixin including.
+
+*0.1.4* (18 Sep 2005)
+
+* First RubyForge release
+
+*0.1.3* (18 Sep 2005)
+
+* ignore multiple calls to acts_as_paranoid on the same model
+
+*0.1.2* (18 Sep 2005)
+
+* fixed a bug that kept you from selecting the first deleted record
+
+*0.1.1* (18 Sep 2005)
+
+* Fixed bug that kept you from selecting deleted records by ID
+
+*0.1* (17 Sep 2005)
+
+* Initial gem
diff --git a/vendor/plugins/acts_as_paranoid/MIT-LICENSE b/vendor/plugins/acts_as_paranoid/MIT-LICENSE
new file mode 100644 (file)
index 0000000..5851fda
--- /dev/null
@@ -0,0 +1,20 @@
+Copyright (c) 2005 Rick Olson
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\ No newline at end of file
diff --git a/vendor/plugins/acts_as_paranoid/README b/vendor/plugins/acts_as_paranoid/README
new file mode 100644 (file)
index 0000000..4ecbb2c
--- /dev/null
@@ -0,0 +1,5 @@
+= acts_as_paranoid
+
+Overrides some basic methods for the current model so that calling #destroy sets a 'deleted_at' field to the current timestamp.  ActiveRecord is required.
+
+http://github.com/technoweenie/acts_as_paranoid
\ No newline at end of file
diff --git a/vendor/plugins/acts_as_paranoid/RUNNING_UNIT_TESTS b/vendor/plugins/acts_as_paranoid/RUNNING_UNIT_TESTS
new file mode 100644 (file)
index 0000000..c1e5818
--- /dev/null
@@ -0,0 +1,10 @@
+1. Pick Rails version.  Either dump this plugin in a Rails app and run it from there, or specify it as an ENV var:
+
+  RAILS=2.2.2 rake
+  RAILS=2.2.2 ruby test/paranoid_test.rb
+
+2. Setup your database.  By default sqlite3 is used, and no further setup is necessary.  You can pick any of the listed databases in test/database.yml.  Be sure to create the database first.
+
+  DB=mysql rake
+
+3. Profit!!
\ No newline at end of file
diff --git a/vendor/plugins/acts_as_paranoid/Rakefile b/vendor/plugins/acts_as_paranoid/Rakefile
new file mode 100644 (file)
index 0000000..5b45a1c
--- /dev/null
@@ -0,0 +1,180 @@
+require 'rubygems'
+
+Gem::manage_gems
+
+require 'rake/rdoctask'
+require 'rake/packagetask'
+require 'rake/gempackagetask'
+require 'rake/testtask'
+require 'rake/contrib/rubyforgepublisher'
+
+PKG_NAME      = 'acts_as_paranoid'
+PKG_VERSION   = '0.3.1'
+PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
+PROD_HOST     = "technoweenie@bidwell.textdrive.com"
+RUBY_FORGE_PROJECT = 'ar-paranoid'
+RUBY_FORGE_USER    = 'technoweenie'
+
+desc 'Default: run unit tests.'
+task :default => :test
+
+desc 'Test the calculations plugin.'
+Rake::TestTask.new(:test) do |t|
+  t.libs << 'lib'
+  t.pattern = 'test/**/*_test.rb'
+  t.verbose = true
+end
+
+desc 'Generate documentation for the acts_as_paranoid plugin.'
+Rake::RDocTask.new do |rdoc|
+  rdoc.rdoc_dir = 'html'
+  rdoc.title    = "#{PKG_NAME} -- protect your ActiveRecord objects from accidental deletion"
+  rdoc.options << '--line-numbers --inline-source --accessor cattr_accessor=object'
+  rdoc.template = "#{ENV['template']}.rb" if ENV['template']
+  rdoc.rdoc_files.include('README', 'CHANGELOG', 'RUNNING_UNIT_TESTS')
+  rdoc.rdoc_files.include('lib/**/*.rb')
+end
+
+spec = Gem::Specification.new do |s|
+  s.name            = PKG_NAME
+  s.version         = PKG_VERSION
+  s.platform        = Gem::Platform::RUBY
+  s.summary         = "acts_as_paranoid keeps models from actually being deleted by setting a deleted_at field."
+  s.files           = FileList["{lib,test}/**/*"].to_a + %w(README MIT-LICENSE CHANGELOG RUNNING_UNIT_TESTS)
+  s.files.delete      "acts_as_paranoid_plugin.sqlite.db"
+  s.files.delete      "acts_as_paranoid_plugin.sqlite3.db"
+  s.require_path    = 'lib'
+  s.autorequire     = 'acts_as_paranoid'
+  s.has_rdoc        = true
+  s.test_files      = Dir['test/**/*_test.rb']
+  s.author          = "Rick Olson"
+  s.email           = "technoweenie@gmail.com"
+  s.homepage        = "http://techno-weenie.net"
+end
+
+Rake::GemPackageTask.new(spec) do |pkg|
+  pkg.need_tar = true
+end
+
+desc "Publish the API documentation"
+task :pdoc => [:rdoc] do
+  Rake::RubyForgePublisher.new(RUBY_FORGE_PROJECT, RUBY_FORGE_USER).upload
+end
+
+desc 'Publish the gem and API docs'
+task :publish => [:pdoc, :rubyforge_upload]
+
+desc "Publish the release files to RubyForge."
+task :rubyforge_upload => :package do
+  files = %w(gem tgz).map { |ext| "pkg/#{PKG_FILE_NAME}.#{ext}" }
+
+  if RUBY_FORGE_PROJECT then
+    require 'net/http'
+    require 'open-uri'
+
+    project_uri = "http://rubyforge.org/projects/#{RUBY_FORGE_PROJECT}/"
+    project_data = open(project_uri) { |data| data.read }
+    group_id = project_data[/[?&]group_id=(\d+)/, 1]
+    raise "Couldn't get group id" unless group_id
+
+    # This echos password to shell which is a bit sucky
+    if ENV["RUBY_FORGE_PASSWORD"]
+      password = ENV["RUBY_FORGE_PASSWORD"]
+    else
+      print "#{RUBY_FORGE_USER}@rubyforge.org's password: "
+      password = STDIN.gets.chomp
+    end
+
+    login_response = Net::HTTP.start("rubyforge.org", 80) do |http|
+      data = [
+        "login=1",
+        "form_loginname=#{RUBY_FORGE_USER}",
+        "form_pw=#{password}"
+      ].join("&")
+      http.post("/account/login.php", data)
+    end
+
+    cookie = login_response["set-cookie"]
+    raise "Login failed" unless cookie
+    headers = { "Cookie" => cookie }
+
+    release_uri = "http://rubyforge.org/frs/admin/?group_id=#{group_id}"
+    release_data = open(release_uri, headers) { |data| data.read }
+    package_id = release_data[/[?&]package_id=(\d+)/, 1]
+    raise "Couldn't get package id" unless package_id
+
+    first_file = true
+    release_id = ""
+
+    files.each do |filename|
+      basename  = File.basename(filename)
+      file_ext  = File.extname(filename)
+      file_data = File.open(filename, "rb") { |file| file.read }
+
+      puts "Releasing #{basename}..."
+
+      release_response = Net::HTTP.start("rubyforge.org", 80) do |http|
+        release_date = Time.now.strftime("%Y-%m-%d %H:%M")
+        type_map = {
+          ".zip"    => "3000",
+          ".tgz"    => "3110",
+          ".gz"     => "3110",
+          ".gem"    => "1400"
+        }; type_map.default = "9999"
+        type = type_map[file_ext]
+        boundary = "rubyqMY6QN9bp6e4kS21H4y0zxcvoor"
+
+        query_hash = if first_file then
+          {
+            "group_id" => group_id,
+            "package_id" => package_id,
+            "release_name" => PKG_FILE_NAME,
+            "release_date" => release_date,
+            "type_id" => type,
+            "processor_id" => "8000", # Any
+            "release_notes" => "",
+            "release_changes" => "",
+            "preformatted" => "1",
+            "submit" => "1"
+          }
+        else
+          {
+            "group_id" => group_id,
+            "release_id" => release_id,
+            "package_id" => package_id,
+            "step2" => "1",
+            "type_id" => type,
+            "processor_id" => "8000", # Any
+            "submit" => "Add This File"
+          }
+        end
+
+        query = "?" + query_hash.map do |(name, value)|
+          [name, URI.encode(value)].join("=")
+        end.join("&")
+
+        data = [
+          "--" + boundary,
+          "Content-Disposition: form-data; name=\"userfile\"; filename=\"#{basename}\"",
+          "Content-Type: application/octet-stream",
+          "Content-Transfer-Encoding: binary",
+          "", file_data, ""
+          ].join("\x0D\x0A")
+
+        release_headers = headers.merge(
+          "Content-Type" => "multipart/form-data; boundary=#{boundary}"
+        )
+
+        target = first_file ? "/frs/admin/qrs.php" : "/frs/admin/editrelease.php"
+        http.post(target + query, data, release_headers)
+      end
+
+      if first_file then
+        release_id = release_response.body[/release_id=(\d+)/, 1]
+        raise("Couldn't get release id") unless release_id
+      end
+
+      first_file = false
+    end
+  end
+end
\ No newline at end of file
diff --git a/vendor/plugins/acts_as_paranoid/init.rb b/vendor/plugins/acts_as_paranoid/init.rb
new file mode 100644 (file)
index 0000000..85eaba8
--- /dev/null
@@ -0,0 +1,34 @@
+class << ActiveRecord::Base
+  def belongs_to_with_deleted(association_id, options = {})
+    with_deleted = options.delete :with_deleted
+    belongs_to_without_deleted(association_id, options).tap do
+      if with_deleted
+        reflection = reflect_on_association(association_id)
+        association_accessor_methods(reflection,            Caboose::Acts::BelongsToWithDeletedAssociation)
+        association_constructor_method(:build,  reflection, Caboose::Acts::BelongsToWithDeletedAssociation)
+        association_constructor_method(:create, reflection, Caboose::Acts::BelongsToWithDeletedAssociation)
+      end
+    end
+  end
+  
+  def has_many_without_deleted(association_id, options = {}, &extension)
+    with_deleted = options.delete :with_deleted
+    has_many_with_deleted(association_id, options, &extension).tap do
+      if options[:through] && !with_deleted
+        reflection = reflect_on_association(association_id)
+        collection_reader_method(reflection, Caboose::Acts::HasManyThroughWithoutDeletedAssociation)
+        collection_accessor_methods(reflection, Caboose::Acts::HasManyThroughWithoutDeletedAssociation, false)
+      end
+    end
+  end
+  
+  alias_method_chain :belongs_to, :deleted
+  alias_method :has_many_with_deleted, :has_many
+  alias_method :has_many, :has_many_without_deleted
+  alias_method :exists_with_deleted?, :exists?
+end
+ActiveRecord::Base.send :include, Caboose::Acts::Paranoid
+ActiveRecord::Base.send :include, Caboose::Acts::ParanoidFindWrapper
+class << ActiveRecord::Base
+  alias_method_chain :acts_as_paranoid, :find_wrapper
+end
diff --git a/vendor/plugins/acts_as_paranoid/lib/caboose/acts/belongs_to_with_deleted_association.rb b/vendor/plugins/acts_as_paranoid/lib/caboose/acts/belongs_to_with_deleted_association.rb
new file mode 100644 (file)
index 0000000..3ac6416
--- /dev/null
@@ -0,0 +1,14 @@
+module Caboose # :nodoc:
+  module Acts # :nodoc:
+    class BelongsToWithDeletedAssociation < ActiveRecord::Associations::BelongsToAssociation
+      private
+        def find_target
+          @reflection.klass.find_with_deleted(
+            @owner[@reflection.primary_key_name], 
+            :conditions => conditions,
+            :include    => @reflection.options[:include]
+          )
+        end
+    end
+  end
+end
\ No newline at end of file
diff --git a/vendor/plugins/acts_as_paranoid/lib/caboose/acts/has_many_through_without_deleted_association.rb b/vendor/plugins/acts_as_paranoid/lib/caboose/acts/has_many_through_without_deleted_association.rb
new file mode 100644 (file)
index 0000000..4948a72
--- /dev/null
@@ -0,0 +1,27 @@
+module Caboose # :nodoc:
+  module Acts # :nodoc:
+    class HasManyThroughWithoutDeletedAssociation < ActiveRecord::Associations::HasManyThroughAssociation
+      protected
+        def current_time
+          ActiveRecord::Base.default_timezone == :utc ? Time.now.utc : Time.now
+        end
+
+        def construct_conditions
+          return super unless @reflection.through_reflection.klass.paranoid?
+          table_name = @reflection.through_reflection.table_name
+          conditions = construct_quoted_owner_attributes(@reflection.through_reflection).map do |attr, value|
+            "#{table_name}.#{attr} = #{value}"
+          end
+
+          deleted_attribute = @reflection.through_reflection.klass.deleted_attribute
+          quoted_current_time = @reflection.through_reflection.klass.quote_value(
+            current_time,
+            @reflection.through_reflection.klass.columns_hash[deleted_attribute.to_s])
+          conditions << "#{table_name}.#{deleted_attribute} IS NULL OR #{table_name}.#{deleted_attribute} > #{quoted_current_time}"
+
+          conditions << sql_conditions if sql_conditions
+          "(" + conditions.join(') AND (') + ")"
+        end
+    end
+  end
+end
\ No newline at end of file
diff --git a/vendor/plugins/acts_as_paranoid/lib/caboose/acts/paranoid.rb b/vendor/plugins/acts_as_paranoid/lib/caboose/acts/paranoid.rb
new file mode 100644 (file)
index 0000000..608169d
--- /dev/null
@@ -0,0 +1,208 @@
+module Caboose #:nodoc:
+  module Acts #:nodoc:
+    # Overrides some basic methods for the current model so that calling #destroy sets a 'deleted_at' field to the current timestamp.
+    # This assumes the table has a deleted_at date/time field.  Most normal model operations will work, but there will be some oddities.
+    #
+    #   class Widget < ActiveRecord::Base
+    #     acts_as_paranoid
+    #   end
+    #
+    #   Widget.find(:all)
+    #   # SELECT * FROM widgets WHERE widgets.deleted_at IS NULL
+    #
+    #   Widget.find(:first, :conditions => ['title = ?', 'test'], :order => 'title')
+    #   # SELECT * FROM widgets WHERE widgets.deleted_at IS NULL AND title = 'test' ORDER BY title LIMIT 1
+    #
+    #   Widget.find_with_deleted(:all)
+    #   # SELECT * FROM widgets
+    #
+    #   Widget.find_only_deleted(:all)
+    #   # SELECT * FROM widgets WHERE widgets.deleted_at IS NOT NULL
+    #
+    #   Widget.find_with_deleted(1).deleted?
+    #   # Returns true if the record was previously destroyed, false if not 
+    #
+    #   Widget.count
+    #   # SELECT COUNT(*) FROM widgets WHERE widgets.deleted_at IS NULL
+    #
+    #   Widget.count ['title = ?', 'test']
+    #   # SELECT COUNT(*) FROM widgets WHERE widgets.deleted_at IS NULL AND title = 'test'
+    #
+    #   Widget.count_with_deleted
+    #   # SELECT COUNT(*) FROM widgets
+    #
+    #   Widget.count_only_deleted
+    #   # SELECT COUNT(*) FROM widgets WHERE widgets.deleted_at IS NOT NULL
+    #
+    #   Widget.delete_all
+    #   # UPDATE widgets SET deleted_at = '2005-09-17 17:46:36'
+    #
+    #   Widget.delete_all!
+    #   # DELETE FROM widgets
+    #
+    #   @widget.destroy
+    #   # UPDATE widgets SET deleted_at = '2005-09-17 17:46:36' WHERE id = 1
+    #
+    #   @widget.destroy!
+    #   # DELETE FROM widgets WHERE id = 1
+    # 
+    module Paranoid
+      def self.included(base) # :nodoc:
+        base.extend ClassMethods
+      end
+
+      module ClassMethods
+        def acts_as_paranoid(options = {})
+          unless paranoid? # don't let AR call this twice
+            cattr_accessor :deleted_attribute
+            self.deleted_attribute = options[:with] || :deleted_at
+            alias_method :destroy_without_callbacks!, :destroy_without_callbacks
+            class << self
+              alias_method :find_every_with_deleted,    :find_every
+              alias_method :calculate_with_deleted,     :calculate
+              alias_method :delete_all!,                :delete_all
+            end
+          end
+          include InstanceMethods
+        end
+
+        def paranoid?
+          self.included_modules.include?(InstanceMethods)
+        end
+      end
+
+      module InstanceMethods #:nodoc:
+        def self.included(base) # :nodoc:
+          base.extend ClassMethods
+        end
+
+        module ClassMethods
+          def find_with_deleted(*args)
+            options = args.extract_options!
+            validate_find_options(options)
+            set_readonly_option!(options)
+            options[:with_deleted] = true # yuck!
+
+            case args.first
+              when :first then find_initial(options)
+              when :all   then find_every(options)
+              else             find_from_ids(args, options)
+            end
+          end
+
+          def find_only_deleted(*args)
+            options = args.extract_options!
+            validate_find_options(options)
+            set_readonly_option!(options)
+            options[:only_deleted] = true # yuck!
+
+            case args.first
+              when :first then find_initial(options)
+              when :all   then find_every(options)
+              else             find_from_ids(args, options)
+            end
+          end
+
+          def exists?(*args)
+            with_deleted_scope { exists_with_deleted?(*args) }
+          end
+
+          def exists_only_deleted?(*args)
+            with_only_deleted_scope { exists_with_deleted?(*args) }
+          end
+
+          def count_with_deleted(*args)
+            calculate_with_deleted(:count, *construct_count_options_from_args(*args))
+          end
+
+          def count_only_deleted(*args)
+            with_only_deleted_scope { count_with_deleted(*args) }
+          end
+
+          def count(*args)
+            with, only = extract_deleted_options(args.last) if args.last.is_a?(Hash)
+            
+            with ? count_with_deleted(*args) :
+              only ? count_only_deleted(*args) :
+                with_deleted_scope { count_with_deleted(*args) }
+          end
+
+          def calculate(*args)
+            with, only = extract_deleted_options(args.last) if args.last.is_a?(Hash)
+            
+            with ? calculate_with_deleted(*args) :
+              only ? calculate_only_deleted(*args) :
+                with_deleted_scope { calculate_with_deleted(*args) }
+          end
+
+          def delete_all(conditions = nil)
+            self.update_all ["#{self.deleted_attribute} = ?", current_time], conditions
+          end
+
+          protected
+            def current_time
+              default_timezone == :utc ? Time.now.utc : Time.now
+            end
+
+            def with_deleted_scope(&block)
+              with_scope({:find => { :conditions => ["#{table_name}.#{deleted_attribute} IS NULL OR #{table_name}.#{deleted_attribute} > ?", current_time] } }, :merge, &block)
+            end
+
+            def with_only_deleted_scope(&block)
+              with_scope({:find => { :conditions => ["#{table_name}.#{deleted_attribute} IS NOT NULL AND #{table_name}.#{deleted_attribute} <= ?", current_time] } }, :merge, &block)
+            end
+
+          private
+            # all find calls lead here
+            def find_every(options)
+              with, only = extract_deleted_options(options)
+
+              with ? find_every_with_deleted(options) :
+                only ? with_only_deleted_scope { find_every_with_deleted(options) } :
+                  with_deleted_scope { find_every_with_deleted(options) }
+            end
+
+            def extract_deleted_options(options)
+              return options.delete(:with_deleted), options.delete(:only_deleted)
+            end
+        end
+
+        def destroy_without_callbacks
+          unless new_record?
+            self.class.update_all self.class.send(:sanitize_sql, ["#{self.class.deleted_attribute} = ?", (self.deleted_at = self.class.send(:current_time))]), ["#{self.class.primary_key} = ?", id]
+          end
+          freeze
+        end
+
+        def destroy_with_callbacks!
+          return false if callback(:before_destroy) == false
+          result = destroy_without_callbacks!
+          callback(:after_destroy)
+          result
+        end
+
+        def destroy!
+          transaction { destroy_with_callbacks! }
+        end
+
+        def deleted?
+          !!read_attribute(:deleted_at)
+        end
+
+        def recover!
+          self.deleted_at = nil
+          save!
+        end
+        
+        def recover_with_associations!(*associations)
+          self.recover!
+          associations.to_a.each do |assoc|
+            self.send(assoc).find_with_deleted(:all).each do |a|
+              a.recover! if a.class.paranoid?
+            end
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/vendor/plugins/acts_as_paranoid/lib/caboose/acts/paranoid_find_wrapper.rb b/vendor/plugins/acts_as_paranoid/lib/caboose/acts/paranoid_find_wrapper.rb
new file mode 100644 (file)
index 0000000..d8cdcac
--- /dev/null
@@ -0,0 +1,94 @@
+module Caboose #:nodoc:
+  module Acts #:nodoc:
+    # Adds a wrapper find method which can identify :with_deleted or :only_deleted options
+    # and would call the corresponding acts_as_paranoid finders find_with_deleted or
+    # find_only_deleted methods.
+    #
+    # With this wrapper you can easily change from using this pattern:
+    #
+    #   if some_condition_enabling_access_to_deleted_records?
+    #     @post = Post.find_with_deleted(params[:id])
+    #   else
+    #     @post = Post.find(params[:id])
+    #   end
+    #
+    # to this:
+    #
+    #   @post = Post.find(params[:id], :with_deleted => some_condition_enabling_access_to_deleted_records?)
+    #
+    # Examples
+    #
+    #   class Widget < ActiveRecord::Base
+    #     acts_as_paranoid
+    #   end
+    #
+    #   Widget.find(:all)
+    #   # SELECT * FROM widgets WHERE widgets.deleted_at IS NULL
+    #
+    #   Widget.find(:all, :with_deleted => false)
+    #   # SELECT * FROM widgets WHERE widgets.deleted_at IS NULL
+    #
+    #   Widget.find_with_deleted(:all)
+    #   # SELECT * FROM widgets
+    #
+    #   Widget.find(:all, :with_deleted => true)
+    #   # SELECT * FROM widgets
+    #
+    #   Widget.find_only_deleted(:all)
+    #   # SELECT * FROM widgets WHERE widgets.deleted_at IS NOT NULL
+    #
+    #   Widget.find(:all, :only_deleted => true)
+    #   # SELECT * FROM widgets WHERE widgets.deleted_at IS NOT NULL
+    #
+    #   Widget.find(:all, :only_deleted => false)
+    #   # SELECT * FROM widgets WHERE widgets.deleted_at IS NULL
+    #
+    module ParanoidFindWrapper
+      def self.included(base) # :nodoc:
+        base.extend ClassMethods
+      end
+
+      module ClassMethods
+        def acts_as_paranoid_with_find_wrapper(options = {})
+          unless paranoid? # don't let AR call this twice
+            acts_as_paranoid_without_find_wrapper(options)
+            class << self
+              alias_method :find_without_find_wrapper, :find
+              alias_method :validate_find_options_without_find_wrapper, :validate_find_options
+            end
+          end
+          include InstanceMethods
+        end
+      end
+
+      module InstanceMethods #:nodoc:
+        def self.included(base) # :nodoc:
+          base.extend ClassMethods
+        end
+
+        module ClassMethods
+          # This is a wrapper for the regular "find" so you can pass acts_as_paranoid related
+          # options and determine which finder to call.
+          def find(*args)
+            options = args.extract_options!
+            # Determine who to call.
+            finder_option = VALID_PARANOID_FIND_OPTIONS.detect { |key| options.delete(key) } || :without_find_wrapper
+            finder_method = "find_#{finder_option}".to_sym
+            # Put back the options in the args now that they don't include the extended keys.
+            args << options
+            send(finder_method, *args)
+          end
+
+          protected
+
+            VALID_PARANOID_FIND_OPTIONS = [:with_deleted, :only_deleted]
+
+            def validate_find_options(options) #:nodoc:
+              cleaned_options = options.reject { |k, v| VALID_PARANOID_FIND_OPTIONS.include?(k) }
+              validate_find_options_without_find_wrapper(cleaned_options)
+            end
+        end
+      end
+    end
+  end
+end
diff --git a/vendor/plugins/acts_as_paranoid/test/database.yml b/vendor/plugins/acts_as_paranoid/test/database.yml
new file mode 100644 (file)
index 0000000..cb4e790
--- /dev/null
@@ -0,0 +1,18 @@
+sqlite:
+  :adapter: sqlite
+  :dbfile: acts_as_paranoid_plugin.sqlite.db
+sqlite3:
+  :adapter: sqlite3
+  :dbfile: acts_as_paranoid_plugin.sqlite3.db
+postgresql:
+  :adapter: postgresql
+  :username: postgres
+  :password: postgres
+  :database: acts_as_paranoid_plugin_test
+  :min_messages: ERROR
+mysql:
+  :adapter: mysql
+  :host: localhost
+  :username: rails
+  :password:
+  :database: acts_as_paranoid_plugin_test
\ No newline at end of file
diff --git a/vendor/plugins/acts_as_paranoid/test/fixtures/categories.yml b/vendor/plugins/acts_as_paranoid/test/fixtures/categories.yml
new file mode 100644 (file)
index 0000000..5d8a341
--- /dev/null
@@ -0,0 +1,19 @@
+category_1:
+  id: 1
+  widget_id: 1
+  title: 'category 1'
+category_2:
+  id: 2
+  widget_id: 1
+  title: 'category 2'
+  deleted_at: '2005-01-01 00:00:00'
+category_3:
+  id: 3
+  widget_id: 2
+  title: 'category 3'
+  deleted_at: '2005-01-01 00:00:00'
+category_4:
+  id: 4
+  widget_id: 2
+  title: 'category 4'
+  deleted_at: '2005-01-01 00:00:00'
\ No newline at end of file
diff --git a/vendor/plugins/acts_as_paranoid/test/fixtures/categories_widgets.yml b/vendor/plugins/acts_as_paranoid/test/fixtures/categories_widgets.yml
new file mode 100644 (file)
index 0000000..fcd7eab
--- /dev/null
@@ -0,0 +1,12 @@
+cw_1:
+  category_id: 1
+  widget_id: 1
+cw_2:
+  category_id: 2
+  widget_id: 1
+cw_3:
+  category_id: 3
+  widget_id: 2
+cw_4:
+  category_id: 4
+  widget_id: 2
\ No newline at end of file
diff --git a/vendor/plugins/acts_as_paranoid/test/fixtures/taggings.yml b/vendor/plugins/acts_as_paranoid/test/fixtures/taggings.yml
new file mode 100644 (file)
index 0000000..36ced62
--- /dev/null
@@ -0,0 +1,9 @@
+tagging_1:
+  id: 1
+  tag_id: 1
+  widget_id: 1
+  deleted_at: '2005-01-01 00:00:00'
+tagging_2:
+  id: 2
+  tag_id: 2
+  widget_id: 1
diff --git a/vendor/plugins/acts_as_paranoid/test/fixtures/tags.yml b/vendor/plugins/acts_as_paranoid/test/fixtures/tags.yml
new file mode 100644 (file)
index 0000000..8617beb
--- /dev/null
@@ -0,0 +1,6 @@
+tag_1:
+  id: 1
+  name: 'tag 1'
+tag_2:
+  id: 2
+  name: 'tag 1'
diff --git a/vendor/plugins/acts_as_paranoid/test/fixtures/widgets.yml b/vendor/plugins/acts_as_paranoid/test/fixtures/widgets.yml
new file mode 100644 (file)
index 0000000..5a8b933
--- /dev/null
@@ -0,0 +1,8 @@
+widget_1:
+  id: 1
+  title: 'widget 1'
+widget_2:
+  id: 2
+  title: 'deleted widget 2'
+  deleted_at: '2005-01-01 00:00:00'
+  category_id: 3
diff --git a/vendor/plugins/acts_as_paranoid/test/paranoid_test.rb b/vendor/plugins/acts_as_paranoid/test/paranoid_test.rb
new file mode 100644 (file)
index 0000000..69e6fbe
--- /dev/null
@@ -0,0 +1,287 @@
+require File.join(File.dirname(__FILE__), 'test_helper')
+
+class Widget < ActiveRecord::Base
+  acts_as_paranoid
+  has_many :categories, :dependent => :destroy
+  has_and_belongs_to_many :habtm_categories, :class_name => 'Category'
+  has_one :category
+  belongs_to :parent_category, :class_name => 'Category'
+  has_many :taggings
+  has_many :tags, :through => :taggings
+  has_many :any_tags, :through => :taggings, :class_name => 'Tag', :source => :tag, :with_deleted => true
+end
+
+class Category < ActiveRecord::Base
+  belongs_to :widget
+  belongs_to :any_widget, :class_name => 'Widget', :foreign_key => 'widget_id', :with_deleted => true
+  acts_as_paranoid
+
+  def self.search(name, options = {})
+    find :all, options.merge(:conditions => ['LOWER(title) LIKE ?', "%#{name.to_s.downcase}%"])
+  end
+
+  def self.search_with_deleted(name, options = {})
+    find_with_deleted :all, options.merge(:conditions => ['LOWER(title) LIKE ?', "%#{name.to_s.downcase}%"])
+  end
+end
+
+class Tag < ActiveRecord::Base
+  has_many :taggings
+  has_many :widgets, :through => :taggings
+end
+
+class Tagging < ActiveRecord::Base
+  belongs_to :tag
+  belongs_to :widget
+  acts_as_paranoid
+end
+
+class NonParanoidAndroid < ActiveRecord::Base
+end
+
+class ParanoidTest < Test::Unit::TestCase
+  fixtures :widgets, :categories, :categories_widgets, :tags, :taggings
+  
+  def test_should_recognize_with_deleted_option
+    assert_equal [1, 2], Widget.find(:all, :with_deleted => true).collect { |w| w.id }
+    assert_equal [1], Widget.find(:all, :with_deleted => false).collect { |w| w.id }
+  end
+  
+  def test_should_recognize_only_deleted_option
+    assert_equal [2], Widget.find(:all, :only_deleted => true).collect { |w| w.id }
+    assert_equal [1], Widget.find(:all, :only_deleted => false).collect { |w| w.id }
+  end
+  
+  def test_should_exists_with_deleted
+    assert Widget.exists_with_deleted?(2)
+    assert !Widget.exists?(2)
+  end
+
+  def test_should_exists_only_deleted
+    assert Widget.exists_only_deleted?(2)
+    assert !Widget.exists_only_deleted?(1)
+  end
+
+  def test_should_count_with_deleted
+    assert_equal 1, Widget.count
+    assert_equal 2, Widget.count_with_deleted
+    assert_equal 1, Widget.count_only_deleted
+    assert_equal 2, Widget.calculate_with_deleted(:count, :all)
+  end
+
+  def test_should_set_deleted_at
+    assert_equal 1, Widget.count
+    assert_equal 1, Category.count
+    widgets(:widget_1).destroy
+    assert_equal 0, Widget.count
+    assert_equal 0, Category.count
+    assert_equal 2, Widget.calculate_with_deleted(:count, :all)
+    assert_equal 4, Category.calculate_with_deleted(:count, :all)
+  end
+  
+  def test_should_destroy
+    assert_equal 1, Widget.count
+    assert_equal 1, Category.count
+    widgets(:widget_1).destroy!
+    assert_equal 0, Widget.count
+    assert_equal 0, Category.count
+    assert_equal 1, Widget.count_only_deleted
+    assert_equal 1, Widget.calculate_with_deleted(:count, :all)
+    # Category doesn't get destroyed because the dependent before_destroy callback uses #destroy
+    assert_equal 4, Category.calculate_with_deleted(:count, :all)
+  end
+  
+  def test_should_delete_all
+    assert_equal 1, Widget.count
+    assert_equal 2, Widget.calculate_with_deleted(:count, :all)
+    assert_equal 1, Category.count
+    Widget.delete_all
+    assert_equal 0, Widget.count
+    # delete_all doesn't call #destroy, so the dependent callback never fires
+    assert_equal 1, Category.count
+    assert_equal 2, Widget.calculate_with_deleted(:count, :all)
+  end
+  
+  def test_should_delete_all_with_conditions
+    assert_equal 1, Widget.count
+    assert_equal 2, Widget.calculate_with_deleted(:count, :all)
+    Widget.delete_all("id < 3")
+    assert_equal 0, Widget.count
+    assert_equal 2, Widget.calculate_with_deleted(:count, :all)
+  end
+  
+  def test_should_delete_all2
+    assert_equal 1, Category.count
+    assert_equal 4, Category.calculate_with_deleted(:count, :all)
+    Category.delete_all!
+    assert_equal 0, Category.count
+    assert_equal 0, Category.calculate_with_deleted(:count, :all)
+  end
+  
+  def test_should_delete_all_with_conditions2
+    assert_equal 1, Category.count
+    assert_equal 4, Category.calculate_with_deleted(:count, :all)
+    Category.delete_all!("id < 3")
+    assert_equal 0, Category.count
+    assert_equal 2, Category.calculate_with_deleted(:count, :all)    
+  end
+  
+  def test_should_not_count_deleted
+    assert_equal 1, Widget.count
+    assert_equal 1, Widget.count(:all, :conditions => ['title=?', 'widget 1'])
+    assert_equal 2, Widget.calculate_with_deleted(:count, :all)
+    assert_equal 1, Widget.count_only_deleted
+  end
+  
+  def test_should_find_only_deleted
+    assert_equal [2], Widget.find_only_deleted(:all).collect { |w| w.id }
+    assert_equal [1, 2], Widget.find_with_deleted(:all, :order => 'id').collect { |w| w.id }
+  end
+  
+  def test_should_not_find_deleted
+    assert_equal [widgets(:widget_1)], Widget.find(:all)
+    assert_equal [1, 2], Widget.find_with_deleted(:all, :order => 'id').collect { |w| w.id }
+  end
+  
+  def test_should_not_find_deleted_has_many_associations
+    assert_equal 1, widgets(:widget_1).categories.size
+    assert_equal [categories(:category_1)], widgets(:widget_1).categories
+  end
+  
+  def test_should_not_find_deleted_habtm_associations
+    assert_equal 1, widgets(:widget_1).habtm_categories.size
+    assert_equal [categories(:category_1)], widgets(:widget_1).habtm_categories
+  end
+  
+  def test_should_not_find_deleted_has_many_through_associations
+    assert_equal 1, widgets(:widget_1).tags.size
+    assert_equal [tags(:tag_2)], widgets(:widget_1).tags
+  end
+  
+  def test_should_find_has_many_through_associations_with_deleted
+    assert_equal 2, widgets(:widget_1).any_tags.size
+    assert_equal Tag.find(:all), widgets(:widget_1).any_tags
+  end
+
+  def test_should_not_find_deleted_belongs_to_associations
+    assert_nil Category.find_with_deleted(3).widget
+  end
+
+  def test_should_find_belongs_to_assocation_with_deleted
+    assert_equal Widget.find_with_deleted(2), Category.find_with_deleted(3).any_widget
+  end
+
+  def test_should_find_first_with_deleted
+    assert_equal widgets(:widget_1), Widget.find(:first)
+    assert_equal 2, Widget.find_with_deleted(:first, :order => 'id desc').id
+  end
+  
+  def test_should_find_single_id
+    assert Widget.find(1)
+    assert Widget.find_with_deleted(2)
+    assert_raises(ActiveRecord::RecordNotFound) { Widget.find(2) }
+  end
+  
+  def test_should_find_multiple_ids
+    assert_equal [1,2], Widget.find_with_deleted(1,2).sort_by { |w| w.id }.collect { |w| w.id }
+    assert_equal [1,2], Widget.find_with_deleted([1,2]).sort_by { |w| w.id }.collect { |w| w.id }
+    assert_raises(ActiveRecord::RecordNotFound) { Widget.find(1,2) }
+  end
+  
+  def test_should_ignore_multiple_includes
+    Widget.class_eval { acts_as_paranoid }
+    assert Widget.find(1)
+  end
+
+  def test_should_not_override_scopes_when_counting
+    assert_equal 1, Widget.send(:with_scope, :find => { :conditions => "title = 'widget 1'" }) { Widget.count }
+    assert_equal 0, Widget.send(:with_scope, :find => { :conditions => "title = 'deleted widget 2'" }) { Widget.count }
+    assert_equal 1, Widget.send(:with_scope, :find => { :conditions => "title = 'deleted widget 2'" }) { Widget.calculate_with_deleted(:count, :all) }
+  end
+
+  def test_should_not_override_scopes_when_finding
+    assert_equal [1], Widget.send(:with_scope, :find => { :conditions => "title = 'widget 1'" }) { Widget.find(:all) }.ids
+    assert_equal [],  Widget.send(:with_scope, :find => { :conditions => "title = 'deleted widget 2'" }) { Widget.find(:all) }.ids
+    assert_equal [2], Widget.send(:with_scope, :find => { :conditions => "title = 'deleted widget 2'" }) { Widget.find_with_deleted(:all) }.ids
+  end
+
+  def test_should_allow_multiple_scoped_calls_when_finding
+    Widget.send(:with_scope, :find => { :conditions => "title = 'deleted widget 2'" }) do
+      assert_equal [2], Widget.find_with_deleted(:all).ids
+      assert_equal [2], Widget.find_with_deleted(:all).ids, "clobbers the constrain on the unmodified find"
+      assert_equal [], Widget.find(:all).ids
+      assert_equal [], Widget.find(:all).ids, 'clobbers the constrain on a paranoid find'
+    end
+  end
+
+  def test_should_allow_multiple_scoped_calls_when_counting
+    Widget.send(:with_scope, :find => { :conditions => "title = 'deleted widget 2'" }) do
+      assert_equal 1, Widget.calculate_with_deleted(:count, :all)
+      assert_equal 1, Widget.calculate_with_deleted(:count, :all), "clobbers the constrain on the unmodified find"
+      assert_equal 0, Widget.count
+      assert_equal 0, Widget.count, 'clobbers the constrain on a paranoid find'
+    end
+  end
+
+  def test_should_give_paranoid_status
+    assert Widget.paranoid?
+    assert !NonParanoidAndroid.paranoid?
+  end
+
+  def test_should_give_record_status
+    assert_equal false, Widget.find(1).deleted? 
+    Widget.find(1).destroy
+    assert Widget.find_with_deleted(1).deleted?
+  end
+
+  def test_should_find_deleted_has_many_assocations_on_deleted_records_by_default
+    w = Widget.find_with_deleted 2
+    assert_equal 2, w.categories.find_with_deleted(:all).length
+    assert_equal 2, w.categories.find_with_deleted(:all).size
+  end
+  
+  def test_should_find_deleted_habtm_assocations_on_deleted_records_by_default
+    w = Widget.find_with_deleted 2
+    assert_equal 2, w.habtm_categories.find_with_deleted(:all).length
+    assert_equal 2, w.habtm_categories.find_with_deleted(:all).size
+  end
+
+  def test_dynamic_finders
+    assert     Widget.find_by_id(1)
+    assert_nil Widget.find_by_id(2)
+  end
+
+  def test_custom_finder_methods
+    w = Widget.find_with_deleted(:all).inject({}) { |all, w| all.merge(w.id => w) }
+    assert_equal [1],       Category.search('c').ids
+    assert_equal [1,2,3,4], Category.search_with_deleted('c', :order => 'id').ids
+    assert_equal [1],       widgets(:widget_1).categories.search('c').collect(&:id)
+    assert_equal [1,2],     widgets(:widget_1).categories.search_with_deleted('c').ids
+    assert_equal [],        w[2].categories.search('c').ids
+    assert_equal [3,4],     w[2].categories.search_with_deleted('c').ids
+  end
+  
+  def test_should_recover_record
+    Widget.find(1).destroy
+    assert_equal true, Widget.find_with_deleted(1).deleted? 
+    
+    Widget.find_with_deleted(1).recover!
+    assert_equal false, Widget.find(1).deleted?
+  end
+  
+  def test_should_recover_record_and_has_many_associations
+    Widget.find(1).destroy
+    assert_equal true, Widget.find_with_deleted(1).deleted?
+    assert_equal true, Category.find_with_deleted(1).deleted?
+    
+    Widget.find_with_deleted(1).recover_with_associations!(:categories)
+    assert_equal false, Widget.find(1).deleted?
+    assert_equal false, Category.find(1).deleted?
+  end
+end
+
+class Array
+  def ids
+    collect &:id
+  end
+end
diff --git a/vendor/plugins/acts_as_paranoid/test/schema.rb b/vendor/plugins/acts_as_paranoid/test/schema.rb
new file mode 100644 (file)
index 0000000..e955bae
--- /dev/null
@@ -0,0 +1,30 @@
+ActiveRecord::Schema.define(:version => 1) do
+
+  create_table :widgets, :force => true do |t|
+    t.column :title, :string, :limit => 50
+    t.column :category_id, :integer
+    t.column :deleted_at, :timestamp
+  end
+
+  create_table :categories, :force => true do |t|
+    t.column :widget_id, :integer
+    t.column :title, :string, :limit => 50
+    t.column :deleted_at, :timestamp
+  end
+
+  create_table :categories_widgets, :force => true, :id => false do |t|
+    t.column :category_id, :integer
+    t.column :widget_id, :integer
+  end
+  
+  create_table :tags, :force => true do |t|
+    t.column :name, :string, :limit => 50
+  end
+  
+  create_table :taggings, :force => true do |t|
+    t.column :tag_id, :integer
+    t.column :widget_id, :integer
+    t.column :deleted_at, :timestamp
+  end
+
+end
\ No newline at end of file
diff --git a/vendor/plugins/acts_as_paranoid/test/test_helper.rb b/vendor/plugins/acts_as_paranoid/test/test_helper.rb
new file mode 100644 (file)
index 0000000..8be012e
--- /dev/null
@@ -0,0 +1,47 @@
+$:.unshift(File.dirname(__FILE__) + '/../lib')
+
+require 'test/unit'
+require 'rubygems'
+if ENV['RAILS'].nil?
+  require File.expand_path(File.join(File.dirname(__FILE__), '../../../../config/environment.rb'))
+else
+  # specific rails version targeted
+  # load activerecord and plugin manually
+  gem 'activerecord', "=#{ENV['RAILS']}"
+  require 'active_record'
+  $LOAD_PATH << File.join(File.dirname(__FILE__), '..', 'lib')
+  Dir["#{$LOAD_PATH.last}/**/*.rb"].each do |path| 
+    require path[$LOAD_PATH.last.size + 1..-1]
+  end
+  require File.join(File.dirname(__FILE__), '..', 'init.rb')
+end
+require 'active_record/fixtures'
+
+config = YAML::load(IO.read(File.dirname(__FILE__) + '/database.yml'))
+# do this so fixtures will load
+ActiveRecord::Base.configurations.update config 
+ActiveRecord::Base.logger = Logger.new(File.dirname(__FILE__) + "/debug.log")
+ActiveRecord::Base.establish_connection(config[ENV['DB'] || 'sqlite3'])
+
+load(File.dirname(__FILE__) + "/schema.rb")
+
+Test::Unit::TestCase.fixture_path = File.dirname(__FILE__) + "/fixtures/"
+$LOAD_PATH.unshift(Test::Unit::TestCase.fixture_path)
+
+class Test::Unit::TestCase #:nodoc:
+  def create_fixtures(*table_names)
+    if block_given?
+      Fixtures.create_fixtures(Test::Unit::TestCase.fixture_path, table_names) { yield }
+    else
+      Fixtures.create_fixtures(Test::Unit::TestCase.fixture_path, table_names)
+    end
+  end
+
+  # Turn off transactional fixtures if you're working with MyISAM tables in MySQL
+  self.use_transactional_fixtures = true
+  
+  # Instantiated fixtures are slow, but give you @david where you otherwise would need people(:david)
+  self.use_instantiated_fixtures  = false
+
+  # Add more helper methods to be used by all tests here...
+end
diff --git a/vendor/plugins/double_submit_protection/README b/vendor/plugins/double_submit_protection/README
new file mode 100644 (file)
index 0000000..c68bc09
--- /dev/null
@@ -0,0 +1,73 @@
+= Double Submit Protection Plugin =
+===================================
+
+This plugin implements a symetrical token approach to avoid duplicate posts of data. This is specially
+useful when you're dealing with data-sensitive forms (credit-card processing, for instance), where
+a duplicated posting may lead to a user getting charged twice. This control is done via a
+token placed on user's form and synchronized with the session - whenever the token is different, you
+can simply verify it on the controllers by using the 'double_submit?' method
+
+Version History
+===============
+
+v1.0
+- Initial release of the plugin
+
+v1.0.1
+- Use flash in place of session
+
+v1.0.2
+- Support multiple token
+
+Usage Example
+=============
+
+some_view.html.erb
+----------------------------------------------------------------------
+<%= form_for :blah, :url => { :action => "create" } do |f| %>
+  ... (some form content here)
+  <%=double_submit_token %>
+<% end %>
+
+<%= form_for :foo, :url => { :action => "create" } do |f| %>
+  ... (some form content here)
+  <%=double_submit_token 'foo_submit_token' %>
+<% end %>
+----------------------------------------------------------------------
+
+blah_controller.rb
+----------------------------------------------------------------------
+  def create
+    if double_submit?
+      flash[:message] = 'Whoa, hang in there dude...'
+      render :action => :register
+      return
+    end
+
+    # do something here
+  end
+end
+----------------------------------------------------------------------
+
+foo_controller.rb
+----------------------------------------------------------------------
+  def create
+    if double_submit? 'foo_submit_token'
+      flash[:message] = 'Whoa, hang in there dude...'
+      render :action => :register
+      return
+    end
+
+    # do something here
+  end
+end
+----------------------------------------------------------------------
+
+Inspired by https://github.com/herval/double_submit_protection
+==============================================================
+Copyright (C) 2008 Herval Freire (hervalfreire@gmail.com). No license intended - you are free to duplicate,
+immitate, print this code and shred it to pieces, blog about it, take pictures with it and even say it was
+ brilliantly developed by yourself and brag about it.
+
+===================================
+Dianthu Dia (dianthudia@y7mail.com)
diff --git a/vendor/plugins/double_submit_protection/init.rb b/vendor/plugins/double_submit_protection/init.rb
new file mode 100644 (file)
index 0000000..b4af7fa
--- /dev/null
@@ -0,0 +1,12 @@
+$:.unshift "#{File.dirname(__FILE__)}/lib"
+require 'double_submit_protection'
+
+
+ActionView::Base.class_eval do
+  include Hervalicious::DoubleSubmitProtection::View
+end
+
+
+ActionController::Base.class_eval do
+  include Hervalicious::DoubleSubmitProtection::Controller
+end
diff --git a/vendor/plugins/double_submit_protection/lib/double_submit_protection.rb b/vendor/plugins/double_submit_protection/lib/double_submit_protection.rb
new file mode 100755 (executable)
index 0000000..716702e
--- /dev/null
@@ -0,0 +1,23 @@
+module Hervalicious
+  module DoubleSubmitProtection
+
+    DEFAULT_TOKEN_NAME = 'submit_token'
+
+    module View
+      def double_submit_token(token_name=nil)
+        token_name ||= DEFAULT_TOKEN_NAME
+        flash[token_name] = Digest::MD5.hexdigest(rand.to_s)
+        hidden_field_tag(token_name, flash[token_name])
+      end
+    end
+
+    module Controller
+      def double_submit?(token_name=nil)
+        token_name ||= DEFAULT_TOKEN_NAME
+        token = flash[token_name]
+        token.nil? || ( (request.post? || request.put?) && (token != params[token_name]) )
+      end
+    end
+  end
+end
+
diff --git a/vendor/plugins/image_submit_tag_ext/MIT-LICENSE b/vendor/plugins/image_submit_tag_ext/MIT-LICENSE
new file mode 100644 (file)
index 0000000..ec4ddd4
--- /dev/null
@@ -0,0 +1,20 @@
+Copyright (c) 2010 [name of plugin creator]
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/vendor/plugins/image_submit_tag_ext/README b/vendor/plugins/image_submit_tag_ext/README
new file mode 100644 (file)
index 0000000..9c0d086
--- /dev/null
@@ -0,0 +1,13 @@
+ImageSubmitTagExt
+=================
+
+Added :disable option to image_submit_tag helper, which functions like :disable_with option of submit_tag, prevents the submit button being pressed when the form is submitted.
+
+
+Example
+=======
+
+image_submit_tag("submit.png", :disable => true)
+# => <input onclick="this.disabled = true;result = (this.form.onsubmit ? (this.form.onsubmit() ? this.form.submit() : false) : this.form.submit());if (result == false) { this.disabled = false; }return result;" src="/images/submit.png" type="image" /> 
+
+Copyright (c) 2010 Junya Ishihara, released under the MIT license
diff --git a/vendor/plugins/image_submit_tag_ext/Rakefile b/vendor/plugins/image_submit_tag_ext/Rakefile
new file mode 100644 (file)
index 0000000..4a2cd51
--- /dev/null
@@ -0,0 +1,23 @@
+require 'rake'
+require 'rake/testtask'
+require 'rake/rdoctask'
+
+desc 'Default: run unit tests.'
+task :default => :test
+
+desc 'Test the image_submit_tag_ext plugin.'
+Rake::TestTask.new(:test) do |t|
+  t.libs << 'lib'
+  t.libs << 'test'
+  t.pattern = 'test/**/*_test.rb'
+  t.verbose = true
+end
+
+desc 'Generate documentation for the image_submit_tag_ext plugin.'
+Rake::RDocTask.new(:rdoc) do |rdoc|
+  rdoc.rdoc_dir = 'rdoc'
+  rdoc.title    = 'ImageSubmitTagExt'
+  rdoc.options << '--line-numbers' << '--inline-source'
+  rdoc.rdoc_files.include('README')
+  rdoc.rdoc_files.include('lib/**/*.rb')
+end
diff --git a/vendor/plugins/image_submit_tag_ext/init.rb b/vendor/plugins/image_submit_tag_ext/init.rb
new file mode 100644 (file)
index 0000000..221a45b
--- /dev/null
@@ -0,0 +1,2 @@
+# Include hook code here
+require 'image_submit_tag_ext'
diff --git a/vendor/plugins/image_submit_tag_ext/install.rb b/vendor/plugins/image_submit_tag_ext/install.rb
new file mode 100644 (file)
index 0000000..f7732d3
--- /dev/null
@@ -0,0 +1 @@
+# Install hook code here
diff --git a/vendor/plugins/image_submit_tag_ext/lib/image_submit_tag_ext.rb b/vendor/plugins/image_submit_tag_ext/lib/image_submit_tag_ext.rb
new file mode 100644 (file)
index 0000000..13d7d4b
--- /dev/null
@@ -0,0 +1,36 @@
+# -*- coding: utf-8 -*-
+#
+# ImageSubmitTagExt
+#
+# Added :disable option to image_submit_tag helper, which functions like :disable_with option of submit_tag,
+# prevents the submit button being pressed when the form is submitted.
+#
+# Released under the MIT license
+#
+# Junya Ishihara <junya@champierre.com>
+# http://champierre.com
+#
+
+module ActionView
+  module Helpers
+    module FormTagHelper
+      def image_submit_tag(source, options = {})
+        options.stringify_keys!
+        if confirm = options.delete("confirm")
+          options["onclick"] ||= ''
+          options["onclick"] += "return #{confirm_javascript_function(confirm)};"
+        end
+
+        if disable = options.delete("disable")
+          onclick = "#{options.delete('onclick')};" if options['onclick']
+
+          options["onclick"] = "this.disabled = true;#{onclick}"
+          options["onclick"] << "result = (this.form.onsubmit ? (this.form.onsubmit() ? this.form.submit() : false) : this.form.submit());"
+          options["onclick"] << "if (result == false) { this.disabled = false; }return result;"
+        end
+
+        tag :input, { "type" => "image", "src" => path_to_image(source) }.update(options.stringify_keys)
+      end
+    end
+  end
+end
\ No newline at end of file
diff --git a/vendor/plugins/image_submit_tag_ext/tasks/image_submit_tag_ext_tasks.rake b/vendor/plugins/image_submit_tag_ext/tasks/image_submit_tag_ext_tasks.rake
new file mode 100644 (file)
index 0000000..08fbd80
--- /dev/null
@@ -0,0 +1,4 @@
+# desc "Explaining what the task does"
+# task :image_submit_tag_ext do
+#   # Task goes here
+# end
diff --git a/vendor/plugins/image_submit_tag_ext/test/image_submit_tag_ext_test.rb b/vendor/plugins/image_submit_tag_ext/test/image_submit_tag_ext_test.rb
new file mode 100644 (file)
index 0000000..e033980
--- /dev/null
@@ -0,0 +1,8 @@
+require 'test_helper'
+
+class ImageSubmitTagExtTest < ActiveSupport::TestCase
+  # Replace this with your real tests.
+  test "the truth" do
+    assert true
+  end
+end
diff --git a/vendor/plugins/image_submit_tag_ext/test/test_helper.rb b/vendor/plugins/image_submit_tag_ext/test/test_helper.rb
new file mode 100644 (file)
index 0000000..cf148b8
--- /dev/null
@@ -0,0 +1,3 @@
+require 'rubygems'
+require 'active_support'
+require 'active_support/test_case'
\ No newline at end of file
diff --git a/vendor/plugins/image_submit_tag_ext/uninstall.rb b/vendor/plugins/image_submit_tag_ext/uninstall.rb
new file mode 100644 (file)
index 0000000..9738333
--- /dev/null
@@ -0,0 +1 @@
+# Uninstall hook code here
diff --git a/vendor/plugins/mbmail/MIT-LICENSE b/vendor/plugins/mbmail/MIT-LICENSE
new file mode 100644 (file)
index 0000000..8eaf6db
--- /dev/null
@@ -0,0 +1,20 @@
+Copyright (c) 2008 [name of plugin creator]
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/vendor/plugins/mbmail/README b/vendor/plugins/mbmail/README
new file mode 100644 (file)
index 0000000..270e2a2
--- /dev/null
@@ -0,0 +1,26 @@
+MbMail
+======
+
+MbMail is a rails-plugin for handling mails for mobile-phone in Japan.
+
+* features
+  * DMail
+    * converting deco-mail(text/html mail for mobile-phone) between
+      each formats (NTT DoCoMo, Au, and SoftBank).
+  * MbMailer
+    * switching default charset to 'iso-2022-jp'
+    * accepting 'triple-dotted address (ex. test...@example.com)'
+
+Example
+=======
+
+See spec/mb_mail/*.rb files or http://github.com/tmtysk
+
+Thanks
+======
+
+* emoticon(emoji) conversion table is provided by Jpmobile.
+* mail-header parser and some utils are rewrited from tmail.
+* Sample GIF image is provided by ICHIGO-APORO.
+
+Copyright (c) 2008 tmtysk, released under the MIT license
diff --git a/vendor/plugins/mbmail/Rakefile b/vendor/plugins/mbmail/Rakefile
new file mode 100644 (file)
index 0000000..21307d4
--- /dev/null
@@ -0,0 +1,22 @@
+require 'rake'
+require 'rake/testtask'
+require 'rake/rdoctask'
+
+desc 'Default: run unit tests.'
+task :default => :test
+
+desc 'Test the mb_mail plugin.'
+Rake::TestTask.new(:test) do |t|
+  t.libs << 'lib'
+  t.pattern = 'test/**/*_test.rb'
+  t.verbose = true
+end
+
+desc 'Generate documentation for the mb_mail plugin.'
+Rake::RDocTask.new(:rdoc) do |rdoc|
+  rdoc.rdoc_dir = 'rdoc'
+  rdoc.title    = 'MbMail'
+  rdoc.options << '--line-numbers' << '--inline-source'
+  rdoc.rdoc_files.include('README')
+  rdoc.rdoc_files.include('lib/**/*.rb')
+end
diff --git a/vendor/plugins/mbmail/init.rb b/vendor/plugins/mbmail/init.rb
new file mode 100644 (file)
index 0000000..3c19a74
--- /dev/null
@@ -0,0 +1 @@
+# Include hook code here
diff --git a/vendor/plugins/mbmail/install.rb b/vendor/plugins/mbmail/install.rb
new file mode 100644 (file)
index 0000000..f7732d3
--- /dev/null
@@ -0,0 +1 @@
+# Install hook code here
diff --git a/vendor/plugins/mbmail/lib/mb_mail.rb b/vendor/plugins/mbmail/lib/mb_mail.rb
new file mode 100644 (file)
index 0000000..cc4da47
--- /dev/null
@@ -0,0 +1,7 @@
+require 'rubygems'
+require 'nkf'
+require 'scanf'
+
+#Dir[File.join(File.dirname(__FILE__), 'tmail/**/*.rb')].sort.each { |f| require f }
+Dir[File.join(File.dirname(__FILE__), 'jpmobile/**/*.rb')].sort.each { |f| require f }
+Dir[File.join(File.dirname(__FILE__), 'mb_mail/**/*.rb')].sort.each { |f| require f }
diff --git a/vendor/plugins/mbmail/lib/mb_mail/dmail.rb b/vendor/plugins/mbmail/lib/mb_mail/dmail.rb
new file mode 100644 (file)
index 0000000..97fa2f0
--- /dev/null
@@ -0,0 +1,199 @@
+# 携帯メール対応モジュール
+module MbMail
+
+  # HeaderField 操作用に TMail から移管
+  class HeaderField < TMail::HeaderField; end
+
+  # デコメールクラス
+  class DMail < TMail::Mail
+
+    def []=( key, val )
+      dkey = key.downcase
+
+      if val.nil?
+        @header.delete dkey
+        return nil
+      end
+
+      case val
+      when String
+        header = new_hf(key, val)
+      when HeaderField
+        # HeaderField が与えられた場合、そのままヘッダに代入する
+        header = val
+      when Array
+        ALLOW_MULTIPLE.include? dkey or
+                raise ArgumentError, "#{key}: Header must not be multiple"
+        @header[dkey] = val
+        return val
+      else
+        header = new_hf(key, val.to_s)
+      end
+      if ALLOW_MULTIPLE.include? dkey
+        (@header[dkey] ||= []).push header
+      else
+        @header[dkey] = header
+      end
+
+      val
+    end
+
+    # docomo のデコメールフォーマットに変換する
+    def to_docomo_format
+      converted_for_carrier(:docomo)
+    end
+
+    # au のデコレーションメールフォーマットに変換する
+    def to_au_format
+      converted_for_carrier(:au)
+    end
+
+    # softbank のデコレメールフォーマットに変換する
+    def to_softbank_format
+      converted_for_carrier(:softbank)
+    end
+
+    protected
+
+    # 指定された content-type のパーツを取得する
+    def get_specified_type_parts(mimetype)
+      specified_type_parts = []
+      specified_type_parts << self if Regexp.new("^#{mimetype}$", Regexp::IGNORECASE) =~ self.content_type
+      if /^multipart\/(.+)$/ =~ self.content_type then
+        self.parts.each do |p|
+          specified_type_parts += p.get_specified_type_parts(mimetype)
+        end
+      end
+      specified_type_parts
+    end
+
+    private
+
+    # 指定のキャリアのデコメールフォーマットに変換する
+    # 現時点では、:docomo, :au, :softbank のみ対応
+    def converted_for_carrier(carrier = :docomo)
+      organize_mail_parts
+
+      dm = MbMail::DMail.new
+      self.header.each do |key,value|
+        next if key == 'content-type' # content-type は引き継いだらダメ
+        dm[key] = value.to_s
+      end
+      dm.body = ""
+      dm.content_type = 'multipart/mixed'
+
+      # text/plain パートの作成
+      tp = MbMail::DMail.new
+      case carrier
+      when :docomo
+        tp.content_type = 'text/plain; charset="Shift_JIS"'
+        tp.transfer_encoding = 'Base64'
+        tp.body = Base64.encode64(Jpmobile::Emoticon::unicodecr_to_external(NKF.nkf('-m0 -x -Ws', @text_part.body), Jpmobile::Emoticon::CONVERSION_TABLE_TO_DOCOMO))
+      when :au
+        tp.content_type = 'text/plain; charset="Shift_JIS"'
+        tp.transfer_encoding = 'Base64'
+        tp.body = Base64.encode64(Jpmobile::Emoticon::unicodecr_to_external(NKF.nkf('-m0 -x -Ws', @text_part.body), Jpmobile::Emoticon::CONVERSION_TABLE_TO_AU))
+      when :softbank
+        tp.content_type = 'text/plain; charset="UTF-8"'
+        tp.transfer_encoding = 'Base64'
+        table = Jpmobile::Emoticon::CONVERSION_TABLE_TO_SOFTBANK
+        emoticon_converted = @text_part.body.gsub(/&#x([0-9a-f]{4});/i) do |match|
+          unicode = $1.scanf("%x").first
+          case table[unicode]
+          when Integer
+            [(table[unicode].to_i-0x1000)].pack('U')
+          when String
+            table[unicode]
+          else
+            match
+          end.force_encoding(Encoding::ASCII_8BIT)
+        end
+        tp.body = Base64.encode64(emoticon_converted)
+      else
+        tp.content_type = 'text/plain; charset="UTF-8"'
+        tp.transfer_encoding = 'Base64'
+        tp.body = Base64.encode64(@text_part.body)
+      end
+
+      # text/html パートの作成
+      hp = MbMail::DMail.new
+      case carrier
+      when :docomo
+        hp.content_type = 'text/html; charset="Shift_JIS"'
+        hp.transfer_encoding = 'Base64'
+        hp.body = Base64.encode64(Jpmobile::Emoticon::unicodecr_to_external(NKF.nkf('-m0 -x -Ws', @html_part.body), Jpmobile::Emoticon::CONVERSION_TABLE_TO_DOCOMO))
+      when :au
+        hp.content_type = 'text/html; charset="Shift_JIS"'
+        hp.transfer_encoding = 'Base64'
+        hp.body = Base64.encode64(Jpmobile::Emoticon::unicodecr_to_external(NKF.nkf('-m0 -x -Ws', @html_part.body), Jpmobile::Emoticon::CONVERSION_TABLE_TO_AU))
+      when :softbank
+        hp.content_type = 'text/html; charset="UTF-8"'
+        hp.transfer_encoding = 'Base64'
+        table = Jpmobile::Emoticon::CONVERSION_TABLE_TO_SOFTBANK
+        emoticon_converted = @html_part.body.gsub(/&#x([0-9a-f]{4});/i) do |match|
+          unicode = $1.scanf("%x").first
+          case table[unicode]
+          when Integer
+            [(table[unicode].to_i-0x1000)].pack('U')
+          when String
+            table[unicode]
+          else
+            match
+          end.force_encoding(Encoding::ASCII_8BIT)
+        end
+        hp.body = Base64.encode64(emoticon_converted)
+      else
+        hp.content_type = 'text/plain; charset="UTF-8"'
+        hp.transfer_encoding = 'Base64'
+        hp.body = Base64.encode64(@html_part.body)
+      end
+
+      # キャリアによって multipart 構成を分岐
+      alt_p = MbMail::DMail.new
+      alt_p.body = ""
+      alt_p.content_type = 'multipart/alternative'
+      alt_p.parts << tp
+      alt_p.parts << hp
+      case carrier
+      when :au
+        dm.parts << alt_p
+        @in_lined_image_parts.each do |ip| dm.parts << ip end
+        @attached_image_parts.each do |ap| dm.parts << ap end
+      else
+        rel_p = MbMail::DMail.new
+        rel_p.body = ""
+        rel_p.content_type = 'multipart/related'
+        rel_p.parts << alt_p
+        @in_lined_image_parts.each do |ip| rel_p.parts << ip end
+        dm.parts << rel_p
+        @attached_image_parts.each do |ap| dm.parts << ap end
+      end
+
+      dm
+    end
+
+    # オリジナルのメール構成を解析し、各パーツに分離する
+    def organize_mail_parts
+      @text_part = get_specified_type_parts('text/plain').first
+      @html_part = get_specified_type_parts('text/html').first
+      # いったん全ての画像をインライン扱いとし、
+      # その後本文から参照されていない画像を添付扱いとする
+      # au でいずれの添付タイプについても同等に扱われているため
+      @in_lined_image_parts = get_specified_type_parts('image/(gif|jpeg|jpg)')
+      @in_lined_image_parts.map do |ip| ip.content_disposition = 'inline' end
+      @attached_image_parts = []
+      @in_lined_image_parts.delete_if do |ip|
+        if /TMail\:\:MessageIdHeader\s\"<([\.@_0-9a-zA-Z]+)>/ =~ ip["content-id"].inspect then
+          unless Regexp.new("src=['\"]cid:#{$1}", Regexp::IGNORECASE) =~ @html_part.body then
+            ip.content_disposition = 'attachment'
+            @attached_image_parts << ip
+            true
+          end
+        else
+          false
+        end
+      end
+    end
+  end
+
+end
diff --git a/vendor/plugins/mbmail/lib/mb_mail/mb_mailer.rb b/vendor/plugins/mbmail/lib/mb_mail/mb_mailer.rb
new file mode 100644 (file)
index 0000000..57e08d0
--- /dev/null
@@ -0,0 +1,37 @@
+module MbMail
+  # http://www.kbmj.com/~shinya/rails_seminar/slides/#(33)
+  # JapaneseMailer 実装より
+  class MbMailer < ActionMailer::Base
+
+    Dir[File.join(File.dirname(__FILE__), '../tmail/**/*.rb')].sort.each { |f| require f }
+
+    private
+
+    def initialize_defaults_with_charset(*args)
+      charset 'iso-2022-jp'
+      initialize_defaults_without_charset(*args)
+    end
+
+    alias_method_chain :initialize_defaults, :charset
+
+    def create_mail_with_encode_body
+      @body = NKF.nkf("-Wj", @body) if @parts.empty?
+      create_mail_without_encode_body
+    end
+
+    alias_method_chain :create_mail, :encode_body
+
+    public
+    # ヘッダに日本語を含める場合に用いる base64 カプセリング
+    # http://wiki.fdiary.net/rails/?ActionMailer
+    def base64(text, charset="iso-2022-jp", convert=true)
+      if convert
+        if charset == "iso-2022-jp"
+          text = NKF.nkf('-j -m0', text)
+        end
+      end
+      text = [text].pack('m').delete("\r\n")
+      "=?#{charset}?B?#{text}?="
+    end
+  end
+end
diff --git a/vendor/plugins/mbmail/lib/tmail/mail.rb b/vendor/plugins/mbmail/lib/tmail/mail.rb
new file mode 100644 (file)
index 0000000..1f108b4
--- /dev/null
@@ -0,0 +1,36 @@
+module TMail
+
+  # Mail 構築時に MessageIdHeader が正しく作成できない処理を修正
+  class Mail
+    def []=( key, val )
+      dkey = key.downcase
+
+      if val.nil?
+        @header.delete dkey
+        return nil
+      end
+
+      case val
+      when String
+        header = new_hf(key, val)
+      when HeaderField
+        # HeaderField が与えられた場合、そのままヘッダに代入する
+        header = val
+      when Array
+        ALLOW_MULTIPLE.include? dkey or
+                raise ArgumentError, "#{key}: Header must not be multiple"
+        @header[dkey] = val
+        return val
+      else
+        header = new_hf(key, val.to_s)
+      end
+      if ALLOW_MULTIPLE.include? dkey
+        (@header[dkey] ||= []).push header
+      else
+        @header[dkey] = header
+      end
+
+      val
+    end
+  end
+end
diff --git a/vendor/plugins/mbmail/lib/tmail/parser.rb b/vendor/plugins/mbmail/lib/tmail/parser.rb
new file mode 100644 (file)
index 0000000..6b3470b
--- /dev/null
@@ -0,0 +1,1040 @@
+module TMail
+
+  class Parser < Racc::Parser
+
+module_eval(<<'...end parser.y/module_eval...', 'parser.y', 333)
+
+  include TextUtils
+
+  def Parser.parse(ident, str, comment = nil)
+    new().parse(ident, str, comment)
+  end
+
+  MAILP_DEBUG = false unless
+
+  def initialize
+    self.debug = MAILP_DEBUG
+  end
+
+  def debug=(flag)
+    @yydebug = flag && Racc_debug_parser
+    @scanner_debug = flag
+  end
+
+  def debug
+    @yydebug
+  end
+
+  alias debug? debug
+
+  def parse(ident, str, comments = nil)
+    @scanner = Scanner.new(str, ident, comments)
+    @scanner.debug = @scanner_debug
+    @first = [ident, ident]
+    result = yyparse(self, :parse0)
+    comments.map! {|c| to_kcode(c) } if comments
+    result
+  end
+
+  private
+
+  def parse0(&block)
+    yield @first
+    @scanner.scan(&block)
+  end
+  
+  def on_error(t, val, vstack)
+    raise SyntaxError, "parse error on token #{racc_token2str(t)}"
+  end
+...end parser.y/module_eval...
+##### State transition tables begin ###
+
+racc_action_table = [
+   -69,    23,    25,   147,   148,    29,    31,   106,   107,    16,
+    17,    19,    22,   137,    23,    25,   -69,    32,    29,    31,
+   -69,   155,    16,    17,    19,    22,   -69,    27,    76,    76,
+    32,    23,    25,   156,   100,    29,    31,   143,   144,    16,
+    17,    19,    22,   108,    27,    23,    25,    32,    99,    29,
+    31,   115,   116,    16,    17,    19,    22,   110,    27,    97,
+    76,    32,    23,    25,   121,    95,    29,    31,   113,    79,
+    16,    17,    19,    22,    92,    27,    23,    25,    32,   118,
+    29,    31,    89,    82,    16,    17,    19,    22,   124,    23,
+    25,   100,    32,    29,    31,   126,   127,    16,    17,    19,
+    22,    81,    27,    23,    25,    32,    92,    29,    31,   129,
+   130,    16,    17,    19,    22,    76,    52,    23,    25,    32,
+    76,    29,    31,   131,    80,    16,    17,    19,    22,    79,
+    23,    25,   134,    32,    29,    31,    79,    78,    16,    17,
+    19,    22,    76,    23,    25,    65,    32,    29,    31,    62,
+   140,    16,    17,    19,    22,    76,    23,    25,    60,    32,
+    29,    31,   100,    44,    16,    17,    19,    22,    76,    23,
+    25,   121,    32,    29,    31,   149,   150,    16,    17,    19,
+    22,   153,    27,    23,    25,    32,    68,    29,    31,   154,
+    42,    16,    17,    19,    22,   158,    27,    23,    25,    32,
+   160,    29,    31,    74,    40,    16,    17,    19,    22,    15,
+    23,    25,   165,    32,    29,    31,    40,   167,    16,    17,
+    19,    22,   168,    27,    23,    25,    32,   nil,    29,    31,
+   nil,   nil,    16,    17,    19,    22,   nil,    23,    25,   nil,
+    32,    29,    31,   nil,   nil,    16,    17,    19,    22,   nil,
+    23,    25,   nil,    32,    29,    31,   nil,   nil,    16,    17,
+    19,    22,   nil,    27,    23,    25,    32,   nil,    29,    31,
+    74,   nil,    16,    17,    19,    22,   nil,   nil,    93,   nil,
+    32,    23,    25,   nil,   nil,    29,    31,   nil,   nil,    16,
+    17,    19,    22,   nil,    23,    25,   nil,    32,    29,    31,
+   nil,   nil,    16,    17,    19,    22,   nil,    85,    25,   nil,
+    32,    29,    31,   nil,    88,    16,    17,    19,    22,    85,
+    25,   nil,   nil,    29,    31,   nil,    88,    16,    17,    19,
+    22,     4,     6,     7,     8,     9,    10,    11,    12,    13,
+     1,     2,     3,    85,    25,   nil,   nil,    29,    31,   nil,
+    88,    16,    17,    19,    22,    85,    25,   nil,   nil,    29,
+    31,   nil,    88,    16,    17,    19,    22,    85,    25,   nil,
+   nil,    29,    31,   nil,    88,    16,    17,    19,    22,    85,
+    25,   nil,   nil,    29,    31,   nil,    88,    16,    17,    19,
+    22,    85,    25,   nil,   nil,    29,    31,   nil,    88,    16,
+    17,    19,    22 ]
+
+racc_action_check = [
+    28,    77,    77,   137,   137,    77,    77,    72,    72,    77,
+    77,    77,    77,   127,     2,     2,    28,    77,     2,     2,
+    28,   144,     2,     2,     2,     2,    28,     2,    67,    28,
+     2,     3,     3,   144,    66,     3,     3,   135,   135,     3,
+     3,     3,     3,    73,     3,   153,   153,     3,    62,   153,
+   153,    87,    87,   153,   153,   153,   153,    75,   153,    60,
+    87,   153,    91,    91,    91,    56,    91,    91,    81,    51,
+    91,    91,    91,    91,    50,    91,    71,    71,    91,    90,
+    71,    71,    45,    42,    71,    71,    71,    71,    97,     7,
+     7,    98,    71,     7,     7,    99,   100,     7,     7,     7,
+     7,    41,     7,     8,     8,     7,   103,     8,     8,   105,
+   106,     8,     8,     8,     8,   109,     8,     9,     9,     8,
+   112,     9,     9,   113,    40,     9,     9,     9,     9,    36,
+    10,    10,   118,     9,    10,    10,   122,    33,    10,    10,
+    10,    10,    70,   156,   156,    13,    10,   156,   156,    12,
+   131,   156,   156,   156,   156,   133,    95,    95,    11,   156,
+    95,    95,   136,     6,    95,    95,    95,    95,   139,   128,
+   128,   128,    95,   128,   128,   140,   141,   128,   128,   128,
+   128,   142,   128,    26,    26,   128,    26,    26,    26,   143,
+     5,    26,    26,    26,    26,   149,    26,    27,    27,    26,
+   152,    27,    27,    27,     4,    27,    27,    27,    27,     1,
+    68,    68,   158,    27,    68,    68,   160,   164,    68,    68,
+    68,    68,   165,    68,   123,   123,    68,   nil,   123,   123,
+   nil,   nil,   123,   123,   123,   123,   nil,    55,    55,   nil,
+   123,    55,    55,   nil,   nil,    55,    55,    55,    55,   nil,
+    38,    38,   nil,    55,    38,    38,   nil,   nil,    38,    38,
+    38,    38,   nil,    38,    52,    52,    38,   nil,    52,    52,
+    52,   nil,    52,    52,    52,    52,   nil,   nil,    52,   nil,
+    52,   102,   102,   nil,   nil,   102,   102,   nil,   nil,   102,
+   102,   102,   102,   nil,    59,    59,   nil,   102,    59,    59,
+   nil,   nil,    59,    59,    59,    59,   nil,   115,   115,   nil,
+    59,   115,   115,   nil,   115,   115,   115,   115,   115,    89,
+    89,   nil,   nil,    89,    89,   nil,    89,    89,    89,    89,
+    89,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+     0,     0,     0,   114,   114,   nil,   nil,   114,   114,   nil,
+   114,   114,   114,   114,   114,    44,    44,   nil,   nil,    44,
+    44,   nil,    44,    44,    44,    44,    44,    78,    78,   nil,
+   nil,    78,    78,   nil,    78,    78,    78,    78,    78,    74,
+    74,   nil,   nil,    74,    74,   nil,    74,    74,    74,    74,
+    74,   130,   130,   nil,   nil,   130,   130,   nil,   130,   130,
+   130,   130,   130 ]
+
+racc_action_pointer = [
+   329,   178,     0,    17,   189,   190,   145,    75,    89,   103,
+   116,   144,   118,   114,   nil,   nil,   nil,   nil,   nil,   nil,
+   nil,   nil,   nil,   nil,   nil,   nil,   169,   183,     0,   nil,
+   nil,   nil,   nil,   117,   nil,   nil,   103,   nil,   236,   nil,
+   108,    87,    83,   nil,   341,    63,   nil,   nil,   nil,   nil,
+    58,    43,   250,   nil,   nil,   223,    49,   nil,   nil,   280,
+    30,   nil,    16,   nil,   nil,   nil,     8,    -1,   196,   nil,
+   113,    62,    -9,    15,   365,    28,   nil,   -13,   353,   nil,
+   nil,    53,   nil,   nil,   nil,   nil,   nil,    31,   nil,   305,
+    57,    48,   nil,   nil,   nil,   142,   nil,    74,    65,    64,
+    65,   nil,   267,    90,   nil,    81,    90,   nil,   nil,    86,
+   nil,   nil,    91,   109,   329,   293,   nil,   nil,   117,   nil,
+   nil,   nil,   110,   210,   nil,   nil,   nil,   -20,   155,   nil,
+   377,   136,   nil,   126,   nil,    14,   136,   -27,   nil,   139,
+   158,   161,   156,   174,     6,   nil,   nil,   nil,   nil,   181,
+   nil,   nil,   174,    31,   nil,   nil,   129,   nil,   195,   nil,
+   201,   nil,   nil,   nil,   189,   208,   nil,   nil,   nil ]
+
+racc_action_default = [
+  -111,  -111,  -111,  -111,   -14,  -111,   -20,  -111,  -111,  -111,
+  -111,  -111,  -111,  -111,   -10,   -96,  -107,  -108,   -44,  -109,
+   -78,   -11,  -110,   -80,   -43,  -104,  -111,  -111,   -60,  -105,
+   -55,  -106,   -79,   -68,   -54,   -71,   -45,   -12,  -111,    -1,
+  -111,  -111,  -111,    -2,  -111,   -22,   -51,   -48,   -50,    -3,
+   -40,   -41,  -111,   -46,    -4,   -87,    -5,   -89,    -6,   -91,
+  -111,    -7,   -96,    -8,    -9,  -100,  -102,   -61,   -59,   -56,
+   -69,  -111,  -111,  -111,  -111,   -77,   -75,   -70,  -111,   -57,
+   -15,  -111,   169,   -73,   -81,   -83,   -21,   -24,   -82,  -111,
+   -27,  -111,   -84,   -47,   -90,  -111,   -92,  -111,  -102,  -111,
+  -103,  -101,  -111,   -58,   -52,  -111,  -111,   -64,   -63,   -65,
+   -76,   -72,   -67,  -111,  -111,  -111,   -26,   -23,  -111,   -29,
+   -49,   -85,   -42,   -88,   -93,   -95,   -96,  -111,  -111,   -62,
+  -111,  -111,   -74,   -25,   -28,   -31,  -102,  -111,   -53,   -66,
+  -111,  -111,   -34,  -111,  -111,   -94,   -97,   -99,   -98,  -111,
+   -18,   -13,   -38,  -111,   -30,   -33,  -111,   -32,   -16,   -19,
+   -14,   -35,   -36,   -37,  -111,  -111,   -39,   -86,   -17 ]
+
+racc_goto_table = [
+    39,    67,    70,    73,    24,    37,    69,    57,    59,    38,
+    36,    66,    55,    67,    91,    84,   159,    86,    69,   101,
+   109,    49,    53,   135,   112,   142,    77,    70,    73,   152,
+   119,    90,    45,   157,   161,   151,   141,    21,    14,    18,
+   120,   103,    64,    63,    61,    84,    70,   105,    58,    84,
+   132,   125,    56,    94,    54,    43,     5,    96,    98,   146,
+    84,   133,   117,   nil,   nil,   102,   nil,   128,    77,   nil,
+   104,   nil,   nil,   nil,    38,   111,   139,   nil,   nil,   nil,
+   nil,   nil,   nil,   nil,   nil,    84,    84,   nil,   nil,   145,
+   nil,   nil,   nil,    57,   nil,   nil,   nil,   nil,   123,   122,
+   111,    84,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,
+   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,
+   nil,    94,   136,   nil,   nil,   nil,   nil,   nil,    70,   163,
+   138,    70,   164,   162,    38,   nil,   nil,   nil,   nil,   nil,
+   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,
+   nil,   nil,   nil,   nil,   nil,   nil,   166 ]
+
+racc_goto_check = [
+     2,    37,    37,    29,    13,    13,    28,    42,    42,    36,
+    31,    47,    46,    37,    32,    45,    23,    24,    28,    48,
+    25,     4,     4,    20,    25,    21,    41,    37,    29,    22,
+    19,    18,    17,    26,    27,    16,    15,    12,    11,    33,
+    34,    35,    10,     9,     8,    45,    37,    29,     7,    45,
+    43,    48,     6,    42,     5,     3,     1,    42,    47,    49,
+    45,    25,    24,   nil,   nil,    41,   nil,    32,    41,   nil,
+    13,   nil,   nil,   nil,    36,    42,    25,   nil,   nil,   nil,
+   nil,   nil,   nil,   nil,   nil,    45,    45,   nil,   nil,    48,
+   nil,   nil,   nil,    42,   nil,   nil,   nil,   nil,    46,    31,
+    42,    45,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,
+   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,
+   nil,    42,    47,   nil,   nil,   nil,   nil,   nil,    37,    29,
+    13,    37,    29,    28,    36,   nil,   nil,   nil,   nil,   nil,
+   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,
+   nil,   nil,   nil,   nil,   nil,   nil,     2 ]
+
+racc_goto_pointer = [
+   nil,    56,    -4,    49,    14,    46,    43,    38,    33,    31,
+    29,    37,    35,     2,   nil,   -95,  -106,    26,   -14,   -60,
+   -96,  -110,  -113,  -136,   -27,   -54,  -111,  -119,   -20,   -24,
+   nil,     8,   -36,    37,   -51,   -27,     6,   -25,   nil,   nil,
+   nil,    -2,    -2,   -64,   nil,   -29,     3,    -4,   -47,   -78 ]
+
+racc_goto_default = [
+   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,   nil,
+   nil,   nil,   nil,    48,    41,   nil,   nil,   nil,   nil,   nil,
+   nil,   nil,   nil,   nil,   nil,    87,   nil,   nil,    30,    34,
+    50,    51,   nil,    46,    47,   nil,    26,    28,    71,    72,
+    33,   114,    35,    83,    75,    20,   nil,   nil,   nil,   nil ]
+
+racc_reduce_table = [
+  0, 0, :racc_error,
+  2, 35, :_reduce_1,
+  2, 35, :_reduce_2,
+  2, 35, :_reduce_3,
+  2, 35, :_reduce_4,
+  2, 35, :_reduce_5,
+  2, 35, :_reduce_6,
+  2, 35, :_reduce_7,
+  2, 35, :_reduce_8,
+  2, 35, :_reduce_9,
+  2, 35, :_reduce_10,
+  2, 35, :_reduce_11,
+  2, 35, :_reduce_12,
+  6, 36, :_reduce_13,
+  0, 48, :_reduce_none,
+  2, 48, :_reduce_none,
+  3, 49, :_reduce_16,
+  5, 49, :_reduce_17,
+  1, 50, :_reduce_18,
+  7, 37, :_reduce_19,
+  0, 51, :_reduce_none,
+  2, 51, :_reduce_21,
+  0, 52, :_reduce_none,
+  2, 52, :_reduce_23,
+  1, 58, :_reduce_24,
+  3, 58, :_reduce_25,
+  2, 58, :_reduce_26,
+  0, 53, :_reduce_none,
+  2, 53, :_reduce_28,
+  0, 54, :_reduce_29,
+  3, 54, :_reduce_30,
+  0, 55, :_reduce_none,
+  2, 55, :_reduce_32,
+  2, 55, :_reduce_33,
+  0, 56, :_reduce_none,
+  2, 56, :_reduce_35,
+  1, 61, :_reduce_36,
+  1, 61, :_reduce_37,
+  0, 57, :_reduce_none,
+  2, 57, :_reduce_39,
+  1, 38, :_reduce_none,
+  1, 38, :_reduce_none,
+  3, 38, :_reduce_none,
+  1, 46, :_reduce_none,
+  1, 46, :_reduce_none,
+  1, 46, :_reduce_none,
+  1, 39, :_reduce_none,
+  2, 39, :_reduce_47,
+  1, 64, :_reduce_48,
+  3, 64, :_reduce_49,
+  1, 68, :_reduce_none,
+  1, 68, :_reduce_none,
+  1, 69, :_reduce_52,
+  3, 69, :_reduce_53,
+  1, 47, :_reduce_none,
+  1, 47, :_reduce_none,
+  2, 47, :_reduce_56,
+  2, 67, :_reduce_none,
+  3, 65, :_reduce_58,
+  2, 65, :_reduce_59,
+  1, 70, :_reduce_60,
+  2, 70, :_reduce_61,
+  4, 62, :_reduce_62,
+  3, 62, :_reduce_63,
+  2, 72, :_reduce_none,
+  2, 73, :_reduce_65,
+  4, 73, :_reduce_66,
+  3, 63, :_reduce_67,
+  1, 63, :_reduce_68,
+  1, 74, :_reduce_none,
+  2, 74, :_reduce_70,
+  1, 71, :_reduce_71,
+  3, 71, :_reduce_72,
+  1, 59, :_reduce_73,
+  3, 59, :_reduce_74,
+  1, 78, :_reduce_none,
+  2, 78, :_reduce_76,
+  1, 75, :_reduce_77,
+  1, 76, :_reduce_none,
+  1, 76, :_reduce_none,
+  1, 76, :_reduce_none,
+  1, 77, :_reduce_none,
+  1, 77, :_reduce_none,
+  1, 77, :_reduce_none,
+  1, 66, :_reduce_none,
+  2, 66, :_reduce_none,
+  3, 60, :_reduce_86,
+  1, 40, :_reduce_87,
+  3, 40, :_reduce_88,
+  1, 80, :_reduce_none,
+  2, 80, :_reduce_90,
+  1, 41, :_reduce_91,
+  2, 41, :_reduce_92,
+  3, 42, :_reduce_93,
+  5, 43, :_reduce_94,
+  3, 43, :_reduce_95,
+  0, 81, :_reduce_96,
+  5, 81, :_reduce_97,
+  1, 83, :_reduce_none,
+  1, 83, :_reduce_none,
+  1, 44, :_reduce_100,
+  3, 45, :_reduce_101,
+  0, 82, :_reduce_none,
+  1, 82, :_reduce_none,
+  1, 79, :_reduce_none,
+  1, 79, :_reduce_none,
+  1, 79, :_reduce_none,
+  1, 79, :_reduce_none,
+  1, 79, :_reduce_none,
+  1, 79, :_reduce_none,
+  1, 79, :_reduce_none ]
+
+racc_reduce_n = 111
+
+racc_shift_n = 169
+
+racc_token_table = {
+  false => 0,
+  :error => 1,
+  :DATETIME => 2,
+  :RECEIVED => 3,
+  :MADDRESS => 4,
+  :RETPATH => 5,
+  :KEYWORDS => 6,
+  :ENCRYPTED => 7,
+  :MIMEVERSION => 8,
+  :CTYPE => 9,
+  :CENCODING => 10,
+  :CDISPOSITION => 11,
+  :ADDRESS => 12,
+  :MAILBOX => 13,
+  :DIGIT => 14,
+  :ATOM => 15,
+  "," => 16,
+  ":" => 17,
+  :FROM => 18,
+  :BY => 19,
+  "@" => 20,
+  :DOMLIT => 21,
+  :VIA => 22,
+  :WITH => 23,
+  :ID => 24,
+  :FOR => 25,
+  ";" => 26,
+  "<" => 27,
+  ">" => 28,
+  "." => 29,
+  :QUOTED => 30,
+  :TOKEN => 31,
+  "/" => 32,
+  "=" => 33 }
+
+racc_nt_base = 34
+
+racc_use_result_var = false
+
+Racc_arg = [
+  racc_action_table,
+  racc_action_check,
+  racc_action_default,
+  racc_action_pointer,
+  racc_goto_table,
+  racc_goto_check,
+  racc_goto_default,
+  racc_goto_pointer,
+  racc_nt_base,
+  racc_reduce_table,
+  racc_token_table,
+  racc_shift_n,
+  racc_reduce_n,
+  racc_use_result_var ]
+
+Racc_token_to_s_table = [
+  "$end",
+  "error",
+  "DATETIME",
+  "RECEIVED",
+  "MADDRESS",
+  "RETPATH",
+  "KEYWORDS",
+  "ENCRYPTED",
+  "MIMEVERSION",
+  "CTYPE",
+  "CENCODING",
+  "CDISPOSITION",
+  "ADDRESS",
+  "MAILBOX",
+  "DIGIT",
+  "ATOM",
+  "\",\"",
+  "\":\"",
+  "FROM",
+  "BY",
+  "\"@\"",
+  "DOMLIT",
+  "VIA",
+  "WITH",
+  "ID",
+  "FOR",
+  "\";\"",
+  "\"<\"",
+  "\">\"",
+  "\".\"",
+  "QUOTED",
+  "TOKEN",
+  "\"/\"",
+  "\"=\"",
+  "$start",
+  "content",
+  "datetime",
+  "received",
+  "addrs_TOP",
+  "retpath",
+  "keys",
+  "enc",
+  "version",
+  "ctype",
+  "cencode",
+  "cdisp",
+  "addr_TOP",
+  "mbox",
+  "day",
+  "hour",
+  "zone",
+  "from",
+  "by",
+  "via",
+  "with",
+  "id",
+  "for",
+  "received_datetime",
+  "received_domain",
+  "domain",
+  "msgid",
+  "received_addrspec",
+  "routeaddr",
+  "spec",
+  "addrs",
+  "group_bare",
+  "commas",
+  "group",
+  "addr",
+  "mboxes",
+  "addr_phrase",
+  "local_head",
+  "routes",
+  "at_domains",
+  "local",
+  "dots",
+  "word",
+  "domword",
+  "dot_repeat",
+  "atom",
+  "phrase",
+  "params",
+  "opt_semicolon",
+  "value" ]
+
+Racc_debug_parser = false
+
+##### State transition tables end #####
+
+# reduce 0 omitted
+
+module_eval(<<'.,.,', 'parser.y', 16)
+  def _reduce_1(val, _values)
+     val[1] 
+  end
+.,.,
+
+module_eval(<<'.,.,', 'parser.y', 17)
+  def _reduce_2(val, _values)
+     val[1] 
+  end
+.,.,
+
+module_eval(<<'.,.,', 'parser.y', 18)
+  def _reduce_3(val, _values)
+     val[1] 
+  end
+.,.,
+
+module_eval(<<'.,.,', 'parser.y', 19)
+  def _reduce_4(val, _values)
+     val[1] 
+  end
+.,.,
+
+module_eval(<<'.,.,', 'parser.y', 20)
+  def _reduce_5(val, _values)
+     val[1] 
+  end
+.,.,
+
+module_eval(<<'.,.,', 'parser.y', 21)
+  def _reduce_6(val, _values)
+     val[1] 
+  end
+.,.,
+
+module_eval(<<'.,.,', 'parser.y', 22)
+  def _reduce_7(val, _values)
+     val[1] 
+  end
+.,.,
+
+module_eval(<<'.,.,', 'parser.y', 23)
+  def _reduce_8(val, _values)
+     val[1] 
+  end
+.,.,
+
+module_eval(<<'.,.,', 'parser.y', 24)
+  def _reduce_9(val, _values)
+     val[1] 
+  end
+.,.,
+
+module_eval(<<'.,.,', 'parser.y', 25)
+  def _reduce_10(val, _values)
+     val[1] 
+  end
+.,.,
+
+module_eval(<<'.,.,', 'parser.y', 26)
+  def _reduce_11(val, _values)
+     val[1] 
+  end
+.,.,
+
+module_eval(<<'.,.,', 'parser.y', 27)
+  def _reduce_12(val, _values)
+     val[1] 
+  end
+.,.,
+
+module_eval(<<'.,.,', 'parser.y', 33)
+  def _reduce_13(val, _values)
+                      t = Time.gm(val[3].to_i, val[2][0,3], val[1].to_i, 0, 0, 0)
+                  (t + val[4] - val[5]).localtime
+                
+  end
+.,.,
+
+# reduce 14 omitted
+
+# reduce 15 omitted
+
+module_eval(<<'.,.,', 'parser.y', 42)
+  def _reduce_16(val, _values)
+                      (val[0].to_i * 60 * 60) +
+                  (val[2].to_i * 60)
+                
+  end
+.,.,
+
+module_eval(<<'.,.,', 'parser.y', 47)
+  def _reduce_17(val, _values)
+                      (val[0].to_i * 60 * 60) +
+                  (val[2].to_i * 60) +
+                  (val[4].to_i)
+                
+  end
+.,.,
+
+module_eval(<<'.,.,', 'parser.y', 54)
+  def _reduce_18(val, _values)
+                      timezone_string_to_unixtime(val[0])
+                
+  end
+.,.,
+
+module_eval(<<'.,.,', 'parser.y', 59)
+  def _reduce_19(val, _values)
+                      val
+                
+  end
+.,.,
+
+# reduce 20 omitted
+
+module_eval(<<'.,.,', 'parser.y', 65)
+  def _reduce_21(val, _values)
+                      val[1]
+                
+  end
+.,.,
+
+# reduce 22 omitted
+
+module_eval(<<'.,.,', 'parser.y', 71)
+  def _reduce_23(val, _values)
+                      val[1]
+                
+  end
+.,.,
+
+module_eval(<<'.,.,', 'parser.y', 77)
+  def _reduce_24(val, _values)
+                      join_domain(val[0])
+                
+  end
+.,.,
+
+module_eval(<<'.,.,', 'parser.y', 81)
+  def _reduce_25(val, _values)
+                      join_domain(val[2])
+                
+  end
+.,.,
+
+module_eval(<<'.,.,', 'parser.y', 85)
+  def _reduce_26(val, _values)
+                      join_domain(val[0])
+                
+  end
+.,.,
+
+# reduce 27 omitted
+
+module_eval(<<'.,.,', 'parser.y', 91)
+  def _reduce_28(val, _values)
+                      val[1]
+                
+  end
+.,.,
+
+module_eval(<<'.,.,', 'parser.y', 96)
+  def _reduce_29(val, _values)
+                      []
+                
+  end
+.,.,
+
+module_eval(<<'.,.,', 'parser.y', 100)
+  def _reduce_30(val, _values)
+                      val[0].push val[2]
+                  val[0]
+                
+  end
+.,.,
+
+# reduce 31 omitted
+
+module_eval(<<'.,.,', 'parser.y', 107)
+  def _reduce_32(val, _values)
+                      val[1]
+                
+  end
+.,.,
+
+module_eval(<<'.,.,', 'parser.y', 111)
+  def _reduce_33(val, _values)
+                      val[1]
+                
+  end
+.,.,
+
+# reduce 34 omitted
+
+module_eval(<<'.,.,', 'parser.y', 117)
+  def _reduce_35(val, _values)
+                      val[1]
+                
+  end
+.,.,
+
+module_eval(<<'.,.,', 'parser.y', 123)
+  def _reduce_36(val, _values)
+                      val[0].spec
+                
+  end
+.,.,
+
+module_eval(<<'.,.,', 'parser.y', 127)
+  def _reduce_37(val, _values)
+                      val[0].spec
+                
+  end
+.,.,
+
+# reduce 38 omitted
+
+module_eval(<<'.,.,', 'parser.y', 134)
+  def _reduce_39(val, _values)
+                      val[1]
+                
+  end
+.,.,
+
+# reduce 40 omitted
+
+# reduce 41 omitted
+
+# reduce 42 omitted
+
+# reduce 43 omitted
+
+# reduce 44 omitted
+
+# reduce 45 omitted
+
+# reduce 46 omitted
+
+module_eval(<<'.,.,', 'parser.y', 146)
+  def _reduce_47(val, _values)
+     [ Address.new(nil, nil) ] 
+  end
+.,.,
+
+module_eval(<<'.,.,', 'parser.y', 148)
+  def _reduce_48(val, _values)
+     val 
+  end
+.,.,
+
+module_eval(<<'.,.,', 'parser.y', 149)
+  def _reduce_49(val, _values)
+     val[0].push val[2]; val[0] 
+  end
+.,.,
+
+# reduce 50 omitted
+
+# reduce 51 omitted
+
+module_eval(<<'.,.,', 'parser.y', 156)
+  def _reduce_52(val, _values)
+                      val
+                
+  end
+.,.,
+
+module_eval(<<'.,.,', 'parser.y', 160)
+  def _reduce_53(val, _values)
+                      val[0].push val[2]
+                  val[0]
+                
+  end
+.,.,
+
+# reduce 54 omitted
+
+# reduce 55 omitted
+
+module_eval(<<'.,.,', 'parser.y', 168)
+  def _reduce_56(val, _values)
+                      val[1].phrase = Decoder.decode(val[0])
+                  val[1]
+                
+  end
+.,.,
+
+# reduce 57 omitted
+
+module_eval(<<'.,.,', 'parser.y', 176)
+  def _reduce_58(val, _values)
+                      AddressGroup.new(val[0], val[2])
+                
+  end
+.,.,
+
+module_eval(<<'.,.,', 'parser.y', 178)
+  def _reduce_59(val, _values)
+     AddressGroup.new(val[0], []) 
+  end
+.,.,
+
+module_eval(<<'.,.,', 'parser.y', 181)
+  def _reduce_60(val, _values)
+     val[0].join('.') 
+  end
+.,.,
+
+module_eval(<<'.,.,', 'parser.y', 182)
+  def _reduce_61(val, _values)
+     val[0] << ' ' << val[1].join('.') 
+  end
+.,.,
+
+module_eval(<<'.,.,', 'parser.y', 186)
+  def _reduce_62(val, _values)
+                      val[2].routes.replace val[1]
+                  val[2]
+                
+  end
+.,.,
+
+module_eval(<<'.,.,', 'parser.y', 191)
+  def _reduce_63(val, _values)
+                      val[1]
+                
+  end
+.,.,
+
+# reduce 64 omitted
+
+module_eval(<<'.,.,', 'parser.y', 196)
+  def _reduce_65(val, _values)
+     [ val[1].join('.') ] 
+  end
+.,.,
+
+module_eval(<<'.,.,', 'parser.y', 197)
+  def _reduce_66(val, _values)
+     val[0].push val[3].join('.'); val[0] 
+  end
+.,.,
+
+module_eval(<<'.,.,', 'parser.y', 199)
+  def _reduce_67(val, _values)
+     Address.new( val[0], val[2] ) 
+  end
+.,.,
+
+module_eval(<<'.,.,', 'parser.y', 200)
+  def _reduce_68(val, _values)
+     Address.new( val[0], nil ) 
+  end
+.,.,
+
+# reduce 69 omitted
+
+module_eval(<<'.,.,', 'parser.y', 203)
+  def _reduce_70(val, _values)
+     (val[1] + 1).times { val[0].push '' }; val[0] 
+  end
+.,.,
+
+module_eval(<<'.,.,', 'parser.y', 206)
+  def _reduce_71(val, _values)
+     val 
+  end
+.,.,
+
+module_eval(<<'.,.,', 'parser.y', 209)
+  def _reduce_72(val, _values)
+                      val[1].times do
+                    val[0].push ''
+                  end
+                  val[0].push val[2]
+                  val[0]
+                
+  end
+.,.,
+
+module_eval(<<'.,.,', 'parser.y', 217)
+  def _reduce_73(val, _values)
+     val 
+  end
+.,.,
+
+module_eval(<<'.,.,', 'parser.y', 220)
+  def _reduce_74(val, _values)
+                      val[1].times do
+                    val[0].push ''
+                  end
+                  val[0].push val[2]
+                  val[0]
+                
+  end
+.,.,
+
+# reduce 75 omitted
+
+module_eval(<<'.,.,', 'parser.y', 228)
+  def _reduce_76(val, _values)
+     val[0] + val[1] 
+  end
+.,.,
+
+module_eval(<<'.,.,', 'parser.y', 230)
+  def _reduce_77(val, _values)
+     val[0].size - 1 
+  end
+.,.,
+
+# reduce 78 omitted
+
+# reduce 79 omitted
+
+# reduce 80 omitted
+
+# reduce 81 omitted
+
+# reduce 82 omitted
+
+# reduce 83 omitted
+
+# reduce 84 omitted
+
+# reduce 85 omitted
+
+module_eval(<<'.,.,', 'parser.y', 245)
+  def _reduce_86(val, _values)
+                      val[1] = val[1].spec
+                  val.join('')
+                
+  end
+.,.,
+
+module_eval(<<'.,.,', 'parser.y', 249)
+  def _reduce_87(val, _values)
+     val 
+  end
+.,.,
+
+module_eval(<<'.,.,', 'parser.y', 250)
+  def _reduce_88(val, _values)
+     val[0].push val[2]; val[0] 
+  end
+.,.,
+
+# reduce 89 omitted
+
+module_eval(<<'.,.,', 'parser.y', 253)
+  def _reduce_90(val, _values)
+     val[0] << ' ' << val[1] 
+  end
+.,.,
+
+module_eval(<<'.,.,', 'parser.y', 257)
+  def _reduce_91(val, _values)
+                      val.push nil
+                  val
+                
+  end
+.,.,
+
+module_eval(<<'.,.,', 'parser.y', 262)
+  def _reduce_92(val, _values)
+                      val
+                
+  end
+.,.,
+
+module_eval(<<'.,.,', 'parser.y', 267)
+  def _reduce_93(val, _values)
+                      [ val[0].to_i, val[2].to_i ]
+                
+  end
+.,.,
+
+module_eval(<<'.,.,', 'parser.y', 272)
+  def _reduce_94(val, _values)
+                      [ val[0].downcase, val[2].downcase, decode_params(val[3]) ]
+                
+  end
+.,.,
+
+module_eval(<<'.,.,', 'parser.y', 276)
+  def _reduce_95(val, _values)
+                      [ val[0].downcase, nil, decode_params(val[1]) ]
+                
+  end
+.,.,
+
+module_eval(<<'.,.,', 'parser.y', 281)
+  def _reduce_96(val, _values)
+                      {}
+                
+  end
+.,.,
+
+module_eval(<<'.,.,', 'parser.y', 285)
+  def _reduce_97(val, _values)
+                      val[0][ val[2].downcase ] = val[4]
+                  val[0]
+                
+  end
+.,.,
+
+# reduce 98 omitted
+
+# reduce 99 omitted
+
+module_eval(<<'.,.,', 'parser.y', 294)
+  def _reduce_100(val, _values)
+                      val[0].downcase
+                
+  end
+.,.,
+
+module_eval(<<'.,.,', 'parser.y', 299)
+  def _reduce_101(val, _values)
+                      [ val[0].downcase, decode_params(val[1]) ]
+                
+  end
+.,.,
+
+# reduce 102 omitted
+
+# reduce 103 omitted
+
+# reduce 104 omitted
+
+# reduce 105 omitted
+
+# reduce 106 omitted
+
+# reduce 107 omitted
+
+# reduce 108 omitted
+
+# reduce 109 omitted
+
+# reduce 110 omitted
+
+def _reduce_none(val, _values)
+  val[0]
+end
+
+  end   # class Parser
+end   # module TMail
diff --git a/vendor/plugins/mbmail/lib/tmail/unquoter.rb b/vendor/plugins/mbmail/lib/tmail/unquoter.rb
new file mode 100644 (file)
index 0000000..2390565
--- /dev/null
@@ -0,0 +1,21 @@
+require 'nkf'
+# convert_to で機種依存文字や絵文字に対応するために
+# Unquoter 内で NKF を使用するようにしたもの
+module TMail
+  class Unquoter
+    class << self
+      # http://www.kbmj.com/~shinya/rails_seminar/slides/#(30)
+      def convert_to_with_nkf(text, to, from)
+        if text && to =~ /^utf-8$/i && from =~ /^iso-2022-jp$/i
+          NKF.nkf("-Jw", text)
+        elsif text && from =~ /^utf-8$/i && to =~ /^iso-2022-jp$/i
+          NKF.nkf("-Wj", text)
+        else
+          convert_to_without_nkf(text, to, from)
+        end
+      end
+
+      alias_method_chain :convert_to, :nkf
+    end
+  end
+end
diff --git a/vendor/plugins/mbmail/spec/mb_mail/dmail_spec.rb b/vendor/plugins/mbmail/spec/mb_mail/dmail_spec.rb
new file mode 100644 (file)
index 0000000..dad426f
--- /dev/null
@@ -0,0 +1,82 @@
+require File.dirname(__FILE__) + '/../spec_helper'
+
+describe MbMail::DMail, "は" do
+  it "引数無しで正しく初期化できる" do
+    @d = MbMail::DMail.new
+    @d.should satisfy { |d| d.instance_of? MbMail::DMail }
+  end
+  it "既存の HTML メールを元に正しく初期化できる" do
+    @d = MbMail::DMail.load("#{SAMPLE_DIR}/decomail.eml")
+    @d.should satisfy { |d| d.instance_of? MbMail::DMail }
+  end
+  describe "構築済みの HTML メールを" do
+    before do
+      @dm = MbMail::DMail.new
+
+      # ヘッダの作成
+      @dm.from = "=?iso-2022-jp?B?#{[NKF.nkf('-j -m0', '日本語from')].pack('m').delete("\r\n")}?= <test@example.com>"
+      @dm.subject = "=?iso-2022-jp?B?#{[NKF.nkf('-j -m0', '日本語subject')].pack('m').delete("\r\n")}?="
+      @dm.body = ''
+      @dm.content_type = 'multipart/mixed'
+
+      # 各パートを作成
+      ## インライン画像パート
+      ### インライン画像の content_id
+      ### au 向けは '@' を一つだけ含むようにすること
+      @sample_cid = '<sample_cid@example.com>'
+      @inlined_image_parts = []
+      inlined_image_part = MbMail::DMail.new
+      inlined_image_part.content_type = 'image/gif; name="inlined.gif"'
+      cid_header = MbMail::HeaderField.new('content-id', @sample_cid)
+      cid_header.id = @sample_cid
+      inlined_image_part['content-id'] = cid_header
+      inlined_image_part.transfer_encoding = 'Base64'
+      inlined_image_part.content_disposition = 'inline'
+      inlined_image_part.body = Base64.encode64(File.open("#{SAMPLE_DIR}/inlined.gif").read)
+      @inlined_image_parts << inlined_image_part
+      ## 添付画像パート
+      @attached_image_parts = []
+      attached_image_part = MbMail::DMail.new
+      attached_image_part.content_type = 'image/gif; name="attached.gif"'
+      attached_image_part.transfer_encoding = 'Base64'
+      attached_image_part.content_disposition = 'attachment'
+      attached_image_part.body = Base64.encode64(File.open("#{SAMPLE_DIR}/attached.gif").read)
+      @attached_image_parts << attached_image_part
+      ## 本文 text/plain パート
+      @text_part = MbMail::DMail.new
+      @text_part.transfer_encoding = 'Base64'
+      ### 絵文字変換を使うのであれば Unicode 実体参照に変換しておく
+      @text_part.content_type = 'text/plain; charset="UTF-8"'
+      @text_part.body = Base64.encode64(Jpmobile::Emoticon.utf8_to_unicodecr("日本語メールです。\n絵文字を使用する場合はdocomoのUnicode表記を使用します。\n&#xE63E;これは「晴れ」"))
+      ## 本文 text/html パート
+      @html_part = MbMail::DMail.new
+      @html_part.transfer_encoding = 'Base64'
+      @html_part.content_type = 'text/html; charset="UTF-8"'
+      @html_part.body = Base64.encode64(Jpmobile::Emoticon.utf8_to_unicodecr("<HTML><BODY><DIV>日本語メールです。</DIV><DIV><FONT color='#FF0000;'>絵文字を使用する場合はdocomoのUnicode表記を使用します。</FONT></DIV> <DIV>&#xE63E;これは「晴れ」</DIV> <DIV>インライン画像はcidを指定して<IMG src='cid:#{@sample_cid}'>このように表記します。</DIV></BODY></HTML>"))
+
+      # 各パートを組み立てる
+      # サンプルは docomo と同形式
+      @alt_part = MbMail::DMail.new
+      @alt_part.body = ''
+      @alt_part.content_type = 'multipart/alternative'
+      @alt_part.parts << @text_part
+      @alt_part.parts << @html_part
+      @rel_part = MbMail::DMail.new
+      @rel_part.body = ''
+      @rel_part.content_type = 'multipart/related'
+      @rel_part.parts << @alt_part
+      @inlined_image_parts.each { |ip| @rel_part.parts << ip }
+      @dm.parts << @rel_part
+      @attached_image_parts.each { |ap| @dm.parts << ap }
+    end
+    it "docomo 向けに変換できる" do
+      lambda { @dm.to_docomo_format }.should_not raise_error
+    end
+    it "au 向けに変換できる" do
+      lambda { @dm.to_au_format }.should_not raise_error
+    end
+    it "softbank 向けに変換できる" do
+      lambda { @dm.to_softbank_format }.should_not raise_error
+    end
+  end
+end
diff --git a/vendor/plugins/mbmail/spec/mb_mail/mb_mailer_spec.rb b/vendor/plugins/mbmail/spec/mb_mail/mb_mailer_spec.rb
new file mode 100644 (file)
index 0000000..91c9286
--- /dev/null
@@ -0,0 +1,29 @@
+require File.dirname(__FILE__) + '/../spec_helper'
+
+describe MbMail::MbMailer, "は" do
+  before do
+    class TestMbMailer < MbMail::MbMailer
+      def testmail(sent_at = Time.now)
+        @subject = base64('日本語subject')
+        @recipients = [ INVALID_ADDRESS ]
+        @from = "#{base64('日本語from')} <#{INVALID_ADDRESS}>"
+        @sent_at = sent_at
+      end
+    end
+    TestMbMailer.template_root = SAMPLE_DIR
+    TestMbMailer.delivery_method = :test
+  end
+  it "日本語ヘッダを作成するためのbase64メソッドが使用できる" do
+    MbMail::MbMailer.instance_methods.should include('base64')
+  end
+  it "送信先および送信元に3つ以上の連続ドットを含むメールを正しく作成できる" do
+    TestMbMailer.deliver_testmail
+    TestMbMailer.deliveries.first.to.first.should == INVALID_ADDRESS
+    TestMbMailer.deliveries.first.from.first.should == INVALID_ADDRESS
+  end
+  it "本文に含まれる機種依存文字を iso-2022-jp エンコードにて正しく送信できる" do
+    TestMbMailer.deliver_testmail
+    TestMbMailer.deliveries.first.charset.should == "iso-2022-jp"
+    TestMbMailer.deliveries.first.body.match(Regexp.new("㌧")).should_not be_nil
+  end
+end
diff --git a/vendor/plugins/mbmail/spec/sample/attached.gif b/vendor/plugins/mbmail/spec/sample/attached.gif
new file mode 100644 (file)
index 0000000..9f2c772
Binary files /dev/null and b/vendor/plugins/mbmail/spec/sample/attached.gif differ
diff --git a/vendor/plugins/mbmail/spec/sample/decomail.eml b/vendor/plugins/mbmail/spec/sample/decomail.eml
new file mode 100644 (file)
index 0000000..2c78acd
--- /dev/null
@@ -0,0 +1,49 @@
+From: test@example.com
+To: test@example.com
+Subject: test
+Mime-Version: 1.0
+Content-Type: multipart/mixed; boundary="-----=_NextPart_32760_65996_33696"
+
+
+-------=_NextPart_32760_65996_33696
+Content-Type: multipart/alternative; boundary="-----=_NextPart_35544_68780_36480"
+
+
+-------=_NextPart_35544_68780_36480
+Content-Type: text/plain; charset="iso-2022-jp"
+Content-Transfer-Encoding: 7bit
+
+This is a body of text/plain part.
+
+-------=_NextPart_35544_68780_36480
+Content-Type: text/html; charset="iso-2022-jp"
+Content-Transfer-Encoding: quoted-printable
+
+<HTML><HEAD><META http-equiv=3D=22Content-Type=22 content=3D=22text/html;=
+ charset=3Diso-2022-jp=22></HEAD><BODY><DIV>This is a body of text/html =
+part.<IMG src=3D=22cid:sample_cid=40example.com=22></DIV></BODY></HTML>
+-------=_NextPart_35544_68780_36480--
+
+-------=_NextPart_32760_65996_33696
+Content-Type: image/gif; name="inlined.gif"
+Content-Transfer-Encoding: base64
+Content-Disposition: inline; filename="inlined.gif"
+Content-ID: <sample_cid@example.com>
+
+0lGODlhHgAeAJECAP///wCZ/////wAAACH5BAEAAAIALAAAAAAeAB4AAAJZ
+lI8Sye22WljxoVnZtLz7D4biqGGheQUAtnVsFanA3DosHSs4KmHrC1nNfpmL
+Tsab0IgWlTOJZDWJSSGz+aopgK5or8jRksYlMDlmHqXHa7L7DY/L5/T6uAAA
+Ow==
+
+-------=_NextPart_32760_65996_33696
+Content-Type: image/gif; name="attached.gif"
+Content-Transfer-Encoding: base64
+Content-Disposition: attachment; filename="attached.gif"
+
+R0lGODlhHgAeAJECAP///wBm/////wAAACH5BAEAAAIALAAAAAAeAB4AAAJq
+lI+py+0P4woBVinonRs36oWf5pEIBWigpR5XAMRpp6jxWsGzyaEqnpLxErng
+zqWDDWvBlgG1WzGUP5dxWftJM1XWjfbcskTkMkaLdo5eQuGp1L6ZdcZZmU5P
+3eNyMt59l0RlxtVFeHhYAAA7
+
+-------=_NextPart_32760_65996_33696--
+
diff --git a/vendor/plugins/mbmail/spec/sample/inlined.gif b/vendor/plugins/mbmail/spec/sample/inlined.gif
new file mode 100644 (file)
index 0000000..1ec82c1
Binary files /dev/null and b/vendor/plugins/mbmail/spec/sample/inlined.gif differ
diff --git a/vendor/plugins/mbmail/spec/sample/test_mb_mailer/testmail.html.erb b/vendor/plugins/mbmail/spec/sample/test_mb_mailer/testmail.html.erb
new file mode 100644 (file)
index 0000000..d545ab9
--- /dev/null
@@ -0,0 +1,5 @@
+this is a template of sample mail.
+本文に機種依存文字を含む事もできます。
+㌧
+㌦
+などなど。
diff --git a/vendor/plugins/mbmail/spec/spec_helper.rb b/vendor/plugins/mbmail/spec/spec_helper.rb
new file mode 100644 (file)
index 0000000..057093f
--- /dev/null
@@ -0,0 +1,6 @@
+require 'spec'
+require 'action_controller'
+require 'action_mailer'
+require File.dirname(__FILE__) + "/../lib/mb_mail.rb"
+SAMPLE_DIR = "#{File.dirname(__FILE__)}/sample"
+INVALID_ADDRESS = 'test...test...@example.com'
diff --git a/vendor/plugins/mbmail/tasks/mb_mail_tasks.rake b/vendor/plugins/mbmail/tasks/mb_mail_tasks.rake
new file mode 100644 (file)
index 0000000..7551a99
--- /dev/null
@@ -0,0 +1,4 @@
+# desc "Explaining what the task does"
+# task :mb_mail do
+#   # Task goes here
+# end
diff --git a/vendor/plugins/mbmail/test/mb_mail_test.rb b/vendor/plugins/mbmail/test/mb_mail_test.rb
new file mode 100644 (file)
index 0000000..ee17a49
--- /dev/null
@@ -0,0 +1,8 @@
+require 'test/unit'
+
+class MbMailTest < Test::Unit::TestCase
+  # Replace this with your real tests.
+  def test_this_plugin
+    flunk
+  end
+end
diff --git a/vendor/plugins/mbmail/uninstall.rb b/vendor/plugins/mbmail/uninstall.rb
new file mode 100644 (file)
index 0000000..9738333
--- /dev/null
@@ -0,0 +1 @@
+# Uninstall hook code here
diff --git a/vendor/plugins/rails-active-form/MIT-LICENSE b/vendor/plugins/rails-active-form/MIT-LICENSE
new file mode 100644 (file)
index 0000000..b1d583f
--- /dev/null
@@ -0,0 +1,20 @@
+Copyright (c) 2005-2007 Peter Donald
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\ No newline at end of file
diff --git a/vendor/plugins/rails-active-form/README.rdoc b/vendor/plugins/rails-active-form/README.rdoc
new file mode 100644 (file)
index 0000000..dad062e
--- /dev/null
@@ -0,0 +1,51 @@
+= active-form plugin for Rails
+
+active-form is a plugin that makes it easy to have model objects that support the 
+ActiveRecord Validations but are not backed by database tables. The plugin is designed
+to make it possible to use the ActiveForm derived classes in a very similar manner to
+the ActiveRecord::Base derived objects.
+
+Originally described at;
+
+http://www.realityforge.org/articles/2005/12/02/validations-for-non-activerecord-model-objects
+
+== How To Define An ActiveForm Object
+
+class Search < ActiveForm
+  attr_accessor :text
+  validates_length_of :text, :maximum=>30
+end
+
+== How To Use ActiveForm Object In Controller
+
+class NavigatorController < ApplicationController
+  def search
+    @search = Search.new(params[:search])
+    if @search.valid?
+      ...do search here...
+    end
+  end
+end
+
+== How To Use ActiveForm Object In View
+
+<%= start_form_tag(:action => 'search') %>
+<%= error_messages_for('search') %>
+<%= text_field('search', 'text', {"maxlength" => 30}) %>
+<button type="submit">Save</button>
+<%= end_form_tag %>
+
+== Details
+
+License: Released under the MIT license.
+
+== Credits
+
+Peter Donald <peter at realityforge dot org>.
+Dae San Hwang for fix to work with Rails 1.1.
+Trevor Squires for suggestion to use Reloadable::Subclasses rather than dispatcher hack for Rails 1.1.
+Tim Lucas for patch to allow bulk addition of attributes.
+Geoff Schmidt for adding support for Callbacks.
+Sean Christman for attributes getter.
+Jack Christensen for attributes setter.
+Troy Anderson for fixing human_attribute_name for localizations.
diff --git a/vendor/plugins/rails-active-form/init.rb b/vendor/plugins/rails-active-form/init.rb
new file mode 100644 (file)
index 0000000..67816f2
--- /dev/null
@@ -0,0 +1 @@
+require 'active_form'
diff --git a/vendor/plugins/rails-active-form/lib/active_form.rb b/vendor/plugins/rails-active-form/lib/active_form.rb
new file mode 100644 (file)
index 0000000..263cad0
--- /dev/null
@@ -0,0 +1,111 @@
+# Note ".valid?" method  must occur on object for validates_associated
+class ActiveForm
+  def initialize(attributes = nil)
+    self.attributes = attributes
+    yield self if block_given?
+  end
+
+  def attributes=(attributes)
+    attributes.each do |key,value|
+      send(key.to_s + '=', value)
+    end if attributes
+  end
+
+  def attributes
+    attributes = instance_variables
+    attributes.delete("@errors")
+    Hash[*attributes.collect { |attribute| [attribute[1..-1], instance_variable_get(attribute)] }.flatten]
+  end
+
+  def [](key)
+    instance_variable_get("@#{key}")
+  end
+
+  def []=(key, value)
+    instance_variable_set("@#{key}", value)
+  end
+
+  def method_missing( method_id, *args )
+    if md = /_before_type_cast$/.match(method_id.to_s)
+      attr_name = md.pre_match
+      return self[attr_name] if self.respond_to?(attr_name)
+    end
+    super
+  end
+
+  def to_xml(options = {})
+    options[:root] ||= self.class.to_s.underscore
+    attributes.to_xml(options)
+  end
+
+  alias_method :respond_to_without_attributes?, :respond_to?
+
+  def new_record?
+    true
+  end
+
+  def self.self_and_descendants_from_active_record
+    [self]
+  end
+
+protected 
+  def raise_not_implemented_error(*params)
+    ValidatingModel.raise_not_implemented_error(*params)
+  end
+
+  def self.human_attribute_name(attribute_key_name, options = {})
+    defaults = self_and_descendants_from_active_record.map do |klass|
+      "#{klass.name.underscore}.#{attribute_key_name}""#{klass.name.underscore}.#{attribute_key_name}"
+    end
+    defaults << options[:default] if options[:default]
+    defaults.flatten!
+    defaults << attribute_key_name.humanize
+    options[:count] ||= 1
+    I18n.translate(defaults.shift, options.merge(:default => defaults, :scope => [:activerecord, :attributes]))
+  end
+
+  def self.human_name(options = {})
+    defaults = self_and_descendants_from_active_record.map do |klass|
+      "#{klass.name.underscore}""#{klass.name.underscore}"
+    end
+    defaults << self.name.humanize
+    I18n.translate(defaults.shift, {:scope => [:activerecord, :models], :count => 1, :default => defaults}.merge(options))
+  end
+
+  # these methods must be defined before Validations include
+  alias save raise_not_implemented_error
+  alias update_attribute raise_not_implemented_error
+  alias save! raise_not_implemented_error
+  
+  # The following must be defined prior to Callbacks include
+  alias create_or_update raise_not_implemented_error
+  alias create raise_not_implemented_error
+  alias update raise_not_implemented_error
+  alias destroy raise_not_implemented_error
+
+  def self.instantiate(record)
+    object = allocate
+    object.attributes = record
+    object
+  end
+
+public
+  include ActiveRecord::Validations
+  include ActiveRecord::Callbacks
+
+protected 
+
+  # the following methods must be defined after include so that they overide
+  # methods previously included
+  class << self
+    def raise_not_implemented_error(*params)
+      raise NotImplementedError
+    end
+
+    alias validates_uniqueness_of raise_not_implemented_error
+    alias create! raise_not_implemented_error
+    alias validate_on_create raise_not_implemented_error
+    alias validate_on_update raise_not_implemented_error
+    alias save_with_validation raise_not_implemented_error    
+  end
+end
diff --git a/vendor/plugins/ssl_requirement/README b/vendor/plugins/ssl_requirement/README
new file mode 100644 (file)
index 0000000..afe5a84
--- /dev/null
@@ -0,0 +1,43 @@
+SSL Requirement
+===============
+
+SSL requirement adds a declarative way of specifying that certain actions
+should only be allowed to run under SSL, and if they're accessed without it,
+they should be redirected.
+
+Example:
+
+  class ApplicationController < ActiveRecord::Base
+    include SslRequirement
+  end
+
+  class AccountController < ApplicationController
+    ssl_required :signup, :payment
+    ssl_allowed :index
+    
+    def signup
+      # Non-SSL access will be redirected to SSL
+    end
+    
+    def payment
+      # Non-SSL access will be redirected to SSL
+    end
+
+    def index
+      # This action will work either with or without SSL
+    end
+
+    def other
+      # SSL access will be redirected to non-SSL
+    end
+  end
+  
+You can overwrite the protected method ssl_required? to rely on other things
+than just the declarative specification. Say, only premium accounts get SSL.
+
+P.S.: Beware when you include the SslRequirement module. At the time of
+inclusion, it'll add the before_filter that validates the declarations. Some
+times you'll want to run other before_filters before that. They should then be
+declared ahead of including this module.
+
+Copyright (c) 2005 David Heinemeier Hansson, released under the MIT license
\ No newline at end of file
diff --git a/vendor/plugins/ssl_requirement/lib/ssl_requirement.rb b/vendor/plugins/ssl_requirement/lib/ssl_requirement.rb
new file mode 100644 (file)
index 0000000..dd4a345
--- /dev/null
@@ -0,0 +1,62 @@
+# Copyright (c) 2005 David Heinemeier Hansson
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+module SslRequirement
+  def self.included(controller)
+    controller.extend(ClassMethods)
+    controller.before_filter(:ensure_proper_protocol)
+  end
+
+  module ClassMethods
+    # Specifies that the named actions requires an SSL connection to be performed (which is enforced by ensure_proper_protocol).
+    def ssl_required(*actions)
+      write_inheritable_array(:ssl_required_actions, actions)
+    end
+
+    def ssl_allowed(*actions)
+      write_inheritable_array(:ssl_allowed_actions, actions)
+    end
+  end
+  
+  protected
+    # Returns true if the current action is supposed to run as SSL
+    def ssl_required?
+      (self.class.read_inheritable_attribute(:ssl_required_actions) || []).include?(action_name.to_sym)
+    end
+    
+    def ssl_allowed?
+      (self.class.read_inheritable_attribute(:ssl_allowed_actions) || []).include?(action_name.to_sym)
+    end
+
+  private
+    def ensure_proper_protocol
+      return true if ssl_allowed?
+
+      if ssl_required? && !request.ssl?
+        redirect_to "https://" + request.host + request.request_uri
+        flash.keep
+        return false
+      elsif request.ssl? && !ssl_required?
+        redirect_to "http://" + request.host + request.request_uri
+        flash.keep
+        return false
+      end
+    end
+end
\ No newline at end of file
diff --git a/vendor/plugins/ssl_requirement/test/ssl_requirement_test.rb b/vendor/plugins/ssl_requirement/test/ssl_requirement_test.rb
new file mode 100644 (file)
index 0000000..0dc67ed
--- /dev/null
@@ -0,0 +1,132 @@
+begin
+  require 'action_controller'
+rescue LoadError
+  if ENV['ACTIONCONTROLLER_PATH'].nil?
+    abort <<MSG
+Please set the ACTIONCONTROLLER_PATH environment variable to the directory
+containing the action_controller.rb file.
+MSG
+  else
+    $LOAD_PATH.unshift << ENV['ACTIONCONTROLLER_PATH']
+    begin
+      require 'action_controller'
+    rescue LoadError
+      abort "ActionController could not be found."
+    end
+  end
+end
+
+require 'action_controller/test_process'
+require 'test/unit'
+require "#{File.dirname(__FILE__)}/../lib/ssl_requirement"
+
+ActionController::Base.logger = nil
+ActionController::Routing::Routes.reload rescue nil
+
+class SslRequirementController < ActionController::Base
+  include SslRequirement
+  
+  ssl_required :a, :b
+  ssl_allowed :c
+  
+  def a
+    render :nothing => true
+  end
+  
+  def b
+    render :nothing => true
+  end
+  
+  def c
+    render :nothing => true
+  end
+  
+  def d
+    render :nothing => true
+  end
+  
+  def set_flash
+    flash[:foo] = "bar"
+  end
+end
+
+class SslRequirementTest < Test::Unit::TestCase
+  def setup
+    @controller = SslRequirementController.new
+    @request    = ActionController::TestRequest.new
+    @response   = ActionController::TestResponse.new
+  end
+  
+  def test_redirect_to_https_preserves_flash
+    get :set_flash
+    get :b
+    assert_response :redirect
+    assert_equal "bar", flash[:foo]
+  end
+  
+  def test_not_redirecting_to_https_does_not_preserve_the_flash
+    get :set_flash
+    get :d
+    assert_response :success
+    assert_nil flash[:foo]
+  end
+  
+  def test_redirect_to_http_preserves_flash
+    get :set_flash
+    @request.env['HTTPS'] = "on"
+    get :d
+    assert_response :redirect
+    assert_equal "bar", flash[:foo]
+  end
+  
+  def test_not_redirecting_to_http_does_not_preserve_the_flash
+    get :set_flash
+    @request.env['HTTPS'] = "on"
+    get :a
+    assert_response :success
+    assert_nil flash[:foo]
+  end
+  
+  def test_required_without_ssl
+    assert_not_equal "on", @request.env["HTTPS"]
+    get :a
+    assert_response :redirect
+    assert_match %r{^https://}, @response.headers['Location']
+    get :b
+    assert_response :redirect
+    assert_match %r{^https://}, @response.headers['Location']
+  end
+  
+  def test_required_with_ssl
+    @request.env['HTTPS'] = "on"
+    get :a
+    assert_response :success
+    get :b
+    assert_response :success
+  end
+
+  def test_disallowed_without_ssl
+    assert_not_equal "on", @request.env["HTTPS"]
+    get :d
+    assert_response :success
+  end
+
+  def test_disallowed_with_ssl
+    @request.env['HTTPS'] = "on"
+    get :d
+    assert_response :redirect
+    assert_match %r{^http://}, @response.headers['Location']
+  end
+
+  def test_allowed_without_ssl
+    assert_not_equal "on", @request.env["HTTPS"]
+    get :c
+    assert_response :success
+  end
+
+  def test_allowed_with_ssl
+    @request.env['HTTPS'] = "on"
+    get :c
+    assert_response :success
+  end
+end
\ No newline at end of file