Commits

Anonymous committed b74243f

Initial commit of all files from ecap-0.1.0.tar.gz.

  • Participants

Comments (0)

Files changed (37)

+syntax: glob
+# This line is a comment, and will be skipped.
+# Empty lines are skipped too.
+
+# Backup files left behind by the Emacs editor.
+*~
+
+# Lock files used by the Emacs editor.
+# Notice that the "#" character is quoted with a backslash.
+# This prevents it from being interpreted as starting a comment.
+.\#*
+
+# Temporary files used by the vim editor.
+.*.swp
+
+# A hidden file created by the Mac OS X Finder.
+.DS_Store
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.  We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors.  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+  To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights.  Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received.  You must make sure that they, too, receive
+or can get the source code.  And you must show them these terms so they
+know their rights.
+
+  Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+  For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software.  For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+  Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so.  This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software.  The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable.  Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products.  If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+  Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary.  To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                       TERMS AND CONDITIONS
+
+  0. Definitions.
+
+  "This License" refers to version 3 of the GNU General Public License.
+
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+  "The Program" refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as "you".  "Licensees" and
+"recipients" may be individuals or organizations.
+
+  To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy.  The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+  A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+  To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy.  Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+  To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies.  Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+  An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License.  If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+  1. Source Code.
+
+  The "source code" for a work means the preferred form of the work
+for making modifications to it.  "Object code" means any non-source
+form of a work.
+
+  A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+  The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form.  A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+  The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities.  However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work.  For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+  The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+  The Corresponding Source for a work in source code form is that
+same work.
+
+  2. Basic Permissions.
+
+  All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met.  This License explicitly affirms your unlimited
+permission to run the unmodified Program.  The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work.  This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+  You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force.  You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright.  Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+  Conveying under any other circumstances is permitted solely under
+the conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+  No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+  When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+  4. Conveying Verbatim Copies.
+
+  You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+  You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+  You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+    a) The work must carry prominent notices stating that you modified
+    it, and giving a relevant date.
+
+    b) The work must carry prominent notices stating that it is
+    released under this License and any conditions added under section
+    7.  This requirement modifies the requirement in section 4 to
+    "keep intact all notices".
+
+    c) You must license the entire work, as a whole, under this
+    License to anyone who comes into possession of a copy.  This
+    License will therefore apply, along with any applicable section 7
+    additional terms, to the whole of the work, and all its parts,
+    regardless of how they are packaged.  This License gives no
+    permission to license the work in any other way, but it does not
+    invalidate such permission if you have separately received it.
+
+    d) If the work has interactive user interfaces, each must display
+    Appropriate Legal Notices; however, if the Program has interactive
+    interfaces that do not display Appropriate Legal Notices, your
+    work need not make them do so.
+
+  A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit.  Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+  You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+    a) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by the
+    Corresponding Source fixed on a durable physical medium
+    customarily used for software interchange.
+
+    b) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by a
+    written offer, valid for at least three years and valid for as
+    long as you offer spare parts or customer support for that product
+    model, to give anyone who possesses the object code either (1) a
+    copy of the Corresponding Source for all the software in the
+    product that is covered by this License, on a durable physical
+    medium customarily used for software interchange, for a price no
+    more than your reasonable cost of physically performing this
+    conveying of source, or (2) access to copy the
+    Corresponding Source from a network server at no charge.
+
+    c) Convey individual copies of the object code with a copy of the
+    written offer to provide the Corresponding Source.  This
+    alternative is allowed only occasionally and noncommercially, and
+    only if you received the object code with such an offer, in accord
+    with subsection 6b.
+
+    d) Convey the object code by offering access from a designated
+    place (gratis or for a charge), and offer equivalent access to the
+    Corresponding Source in the same way through the same place at no
+    further charge.  You need not require recipients to copy the
+    Corresponding Source along with the object code.  If the place to
+    copy the object code is a network server, the Corresponding Source
+    may be on a different server (operated by you or a third party)
+    that supports equivalent copying facilities, provided you maintain
+    clear directions next to the object code saying where to find the
+    Corresponding Source.  Regardless of what server hosts the
+    Corresponding Source, you remain obligated to ensure that it is
+    available for as long as needed to satisfy these requirements.
+
+    e) Convey the object code using peer-to-peer transmission, provided
+    you inform other peers where the object code and Corresponding
+    Source of the work are being offered to the general public at no
+    charge under subsection 6d.
+
+  A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+  A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling.  In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage.  For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product.  A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+  "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source.  The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+  If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information.  But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+  The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed.  Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+  Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+  7. Additional Terms.
+
+  "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law.  If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+  When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it.  (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.)  You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+  Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+    a) Disclaiming warranty or limiting liability differently from the
+    terms of sections 15 and 16 of this License; or
+
+    b) Requiring preservation of specified reasonable legal notices or
+    author attributions in that material or in the Appropriate Legal
+    Notices displayed by works containing it; or
+
+    c) Prohibiting misrepresentation of the origin of that material, or
+    requiring that modified versions of such material be marked in
+    reasonable ways as different from the original version; or
+
+    d) Limiting the use for publicity purposes of names of licensors or
+    authors of the material; or
+
+    e) Declining to grant rights under trademark law for use of some
+    trade names, trademarks, or service marks; or
+
+    f) Requiring indemnification of licensors and authors of that
+    material by anyone who conveys the material (or modified versions of
+    it) with contractual assumptions of liability to the recipient, for
+    any liability that these contractual assumptions directly impose on
+    those licensors and authors.
+
+  All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10.  If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term.  If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+  If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+  Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+  8. Termination.
+
+  You may not propagate or modify a covered work except as expressly
+provided under this License.  Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+  However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+  Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+  Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License.  If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+  You are not required to accept this License in order to receive or
+run a copy of the Program.  Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance.  However,
+nothing other than this License grants you permission to propagate or
+modify any covered work.  These actions infringe copyright if you do
+not accept this License.  Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+  Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License.  You are not responsible
+for enforcing compliance by third parties with this License.
+
+  An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations.  If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+  You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License.  For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+  11. Patents.
+
+  A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based.  The
+work thus licensed is called the contributor's "contributor version".
+
+  A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version.  For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+  Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+  In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement).  To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+  If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients.  "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+  If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+  A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License.  You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+  Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+  If 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 convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all.  For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+  13. Use with the GNU Affero General Public License.
+
+  Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work.  The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+  14. Revised Versions of this License.
+
+  The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+  Each version is given a distinguishing version number.  If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation.  If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+  If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+  Later license versions may give you additional or different
+permissions.  However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+  15. Disclaimer of Warranty.
+
+  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. Limitation of Liability.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+  17. Interpretation of Sections 15 and 16.
+
+  If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+  If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+    <program>  Copyright (C) <year>  <name of author>
+    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+  You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+  The GNU General Public License does not permit incorporating your program
+into proprietary programs.  If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.  But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
+#
+# INSTALL - Installation instructions for Ecap
+#
+
+Overview
+--------
+There are two directories included that contain a snapshot of the release.
+Since the code is written in Tcl, there's no compile step. You basically 
+copy the contents of each directory to the appropriate machine where it's 
+needed to run:
+
+1) agent: contains the directory layout and all files for ecapad, the Ecap
+   Agent Daemon. ecapad is deployed on machines where the network traffic
+   captures should be done.
+2) www: contains the directory layout and all files for ecaprd, the Ecap
+   Requestor Daemon and the Ecap web server CGI scripts. ecaprd and the CGI
+   scripts are deployed on the machine that runs your web server and is where
+   users login and initiate/view network traffic captures.
+
+You can run an agent and www deployment on the same machine, or you can run
+them in a one-to-many or many-to-many relationship as needed for your
+environment. A typical scenario is Ecap is run in a one-to-many
+configuration, that is, there is one www machine and many agent machines. In
+this scenario, the www machine sends capture requests to the agent machines
+where the captures are done. Once a capture is completed on the agent, the
+agent sends it back to the www machine where it's available for viewing in
+the user's web browser.
+
+NOTE: The way the code works currently, the captures are done on the agent
+machines and the output is a text summary line generated by tshark. The 
+actual binary capture file is not sent back to the www machine. This is an
+obvious limitation that prevents the web server CGI scripts from displaying
+additional capture data to the user. This is probably one of the first
+enhancements that should be made to the code; if the binary capture file is
+sent back to the www machine, the capture viewer CGI code could be enhanced
+to display additional capture data to the user.
+
+Requirements
+------------
+0) Unix-like OS (Linux, *BSD, etc.)
+1) Tcl (8.3 and 8.4 tested)
+2) TclX (Extended Tcl)
+3) Apache (www machine only, 1.3 and 2.2 tested)
+   Could be another web server if you know how to configure CGI and map
+   an alias dir to "/ecap/".
+4) tshark (agent machine only, part of Wireshark)
+5) SSH client and server (ssh publickey authentication and scp)
+6) This shouldn't be a requirement, but it is at this early stage:
+   unless you want to do a lot of manual editing of source and configuration
+   files, you should plan on using the default installation directory of:
+   /usr/local/ecap
+
+Example Install on Ubuntu 10.04
+-------------------------------
+
+1) sudo apt-get install openssh-client openssh-server
+
+2) sudo apt-get install tcl8.4 tclx8.4 apache2 tshark
+
+3) on agent machines, copy the "agent/usr/local/ecap" directory tree to
+   "/usr/local", like:
+   cd ecap-x.x.x/
+   sudo cp -pR agent/usr/local/ecap /usr/local/
+   sudo adduser --disabled-password --gecos "ecap requestor daemon" ecaprd
+   sudo adduser --disabled-password --gecos "ecap agent daemon" ecapad
+   sudo chown -R ecapad:ecapad /usr/local/ecap
+   sudo chown ecapad:ecaprd /usr/local/ecap/inbound
+   sudo chmod 775 /usr/local/ecap/inbound
+
+4) on www machines, copy the "www/usr/local/ecap" directory tree to
+   "/usr/local", like:
+   cd ecap-x.x.x/
+   sudo cp -pR www/usr/local/ecap /usr/local/
+   sudo adduser --disabled-password --gecos "ecap requestor daemon" ecaprd
+   sudo adduser --disabled-password --gecos "ecap agent daemon" ecapad
+   sudo chown -R ecaprd:ecaprd /usr/local/ecap
+   sudo chown ecaprd:ecapad /usr/local/ecap/inbound
+   sudo chmod 775 /usr/local/ecap/inbound
+   sudo chown ecaprd:ecapad /usr/local/ecap/inbound-rd
+   sudo chmod 775 /usr/local/ecap/inbound-rd
+   sudo chown ecaprd:ecapad /usr/local/ecap/log
+   sudo chmod 775 /usr/local/ecap/log
+   sudo chown ecaprd:ecapad /usr/local/ecap/tmp
+   sudo chmod 775 /usr/local/ecap/tmp
+   # look in your apache2.conf for the user apache is run as;
+   # it may be a reference to an environment variable defined in the file
+   # /etc/apache2/envvars
+   # use this user and group as the arguments to the chown command below;
+   # in this case, user and group are both "www-data"
+   sudo chown www-data:ecaprd /usr/local/ecap/www/request
+   sudo chmod 775 /usr/local/ecap/www/request
+
+5) If deploying an agent and www on the same machine, make sure ecapad has
+   write permissions on the captures directory:
+   sudo chown ecapad:ecapad /usr/local/ecap/captures
+
+6) Add CGI directives to Apache conf to enable CGI. See the example
+   configuration in "www/etc/apache/ecap-httpd-example.conf":
+   sudo cp www/etc/apache/ecap.passwd /etc/apache2/
+   sudo vi /etc/apache2/apache2.conf
+   # copy and paste directives between ecap comment lines from example
+   # Apache conf referenced above
+   # Re-start apache:
+   sudo /etc/init.d/apache2 restart
+   # setup users/passwords in ecap.passwd
+   sudo htpasswd /etc/apache2/ecap.passwd username
+
+7) Generate and configure ssh keys for users ecaprd and ecapad for
+   ssh publickey authentication. See the example ssh configuration files
+   in "agent/home/" and "www/home/" for each user. Basically, ecaprd needs
+   to be able to use publickey authentication to login to agent (ecapad)
+   machines, and ecapad needs to be able to do the same to www (ecaprd)
+   machines. scp as well as remote shell commands via ssh are used to copy
+   and move files on machines. Make sure the ".ssh" directory in the user's
+   home directory is owned by that user and has the correct permissions:
+   sudo chown -R ecaprd:ecaprd /home/ecaprd/.ssh
+   sudo chmod 700 /home/ecaprd/.ssh
+   sudo chmod 600 /home/ecaprd/.ssh/authorized_keys
+   sudo chmod 600 /home/ecaprd/.ssh/my-ssh-rsa-key
+   # the permissions above also apply to the agent (ecapad) machine,
+   # just use "ecapad" instead of "ecaprd"
+   #
+   A good test is to login as ecaprd/ecapad on each machine and then ssh to
+   all the other machines it should be able to connect to. One thing this
+   allows you to handle is the prompting ssh does when it connects to a new
+   machine it has never seen. This allows you the chance to answer "yes".
+   If you have ssh publickey authentication setup correctly, you should be
+   able to just type "ssh ecaprd@10.1.1.1" or "ssh ecapad@10.3.3.3" and be
+   logged-in and sitting at a shell prompt with no other typing on your part.
+   #
+   Example commands for setting up ssh publickey authentication for user
+   ecaprd on www machine:
+   cd /home/ecaprd
+   sudo mkdir .ssh
+   sudo chmod 700 .ssh
+   sudo ssh-keygen -t rsa -C ecaprd -f .ssh/ssh-key-ecaprd
+   # press enter for no passphrase or be prepared to setup an ssh agent for
+   # handling keys with passphrases
+   Reference the publickey file in ecaprd's ssh config file:
+   sudo vi .ssh/config
+   # copy/paste the lines below into the .ssh/config file:
+   Host *
+       IdentityFile ~/.ssh/ssh-key-ecaprd
+       ForwardX11 no
+       RhostsAuthentication no
+       RhostsRSAAuthentication no
+       PasswordAuthentication no
+       Port 22
+       Protocol 2
+   # end of example .ssh/config file
+   sudo chown -R ecaprd:ecaprd .ssh
+   # you should now have in the .ssh dir two files:
+   sudo ls -la .ssh/
+   # ssh-key-ecaprd:     the ssh private key file
+   # ssh-key-ecaprd.pub: the ssh public key file
+   Copy the public key file (.pub) you just created above to the .ssh
+   directory in ecaprd's home directory on all agent machines and copy it
+   again in the same .ssh directory to the name "authorized_keys", which
+   authorizes sshd to allow ecaprd to login. If the agent is on the same
+   machine as www, you can do this:
+   sudo cp -p /home/ecaprd/.ssh/ssh-key-ecaprd.pub \
+       /home/ecaprd/.ssh/authorized_keys
+   Run the following command on the www machine for each agent machine the
+   www machine needs to connect to, passing the ip address or hostname
+   used in the ecaprd.conf REMOTE_HOST line(s) (this allows you to answer
+   yes to the authenticity prompt ssh presents when it sees a new host). Make
+   sure you use the same value that's specified in the REMOTE_HOST line for
+   the remote host (ip address or hostname) below:
+   sudo sudo -u ecaprd ssh 10.1.1.1
+   sudo sudo -u ecaprd ssh 10.2.2.2
+   If things are working properly, you should be able to run the command(s)
+   above and see a shell prompt on the remote machine without typing anything.
+   #
+   The last step of this ssh publickey authentication setup example is to
+   do the exact same thing you just did above, except for this time,
+   use "ecapad" instead of "ecaprd" in the commands. And also, where it says
+   "www" machine, use the "agent" machine instead. In other words, you're
+   setting things up to move files in the opposite direction now, from the
+   agent (capture) machine to the www machine. Remember, you must do this
+   for each agent machine. When copying multiple ecapad publickeys to www,
+   after the first time you run:
+   sudo cp -p /home/ecapad/.ssh/ssh-key-ecapad.pub \
+          /home/ecapad/.ssh/authorized_keys
+   use the command below instead so you don't overwrite existing keys:
+   sudo cat /home/ecapad/.ssh/ssh-key-ecapad.pub \
+          >> /home/ecapad/.ssh/authorized_keys
+
+8) Edit "/usr/local/ecap/www/cgi/pcap.conf" and add your capture filters and
+   tagid's that reference capture agents. A tagid is simply a unique name
+   you create and use to identify a capture agent (ecapad) and a physical
+   interface on that machine used for capturing network traffic. The tagid's
+   you use should match whatever you setup in the ecaprd.conf and ecapad.conf
+   on the respective ecaprd and ecapad machines. The tagid's are how Ecap
+   knows where to send capture requests.
+
+9) Agent machines need to run tshark to perform network traffic captures.
+   This requires special permissions. See the link below for background info:
+   http://wiki.wireshark.org/CaptureSetup/CapturePrivileges
+   Some Linux kernels support File Capabilities that you can enable to
+   allow capture privileges for non-root users.
+   See below for more info:
+   http://packetlife.net/blog/2010/mar/19/sniffing-wireshark-non-root-user/
+   For example, on Ubuntu 10.04, you can run:
+   sudo apt-get install libcap2-bin
+   sudo setcap cap_net_raw,cap_net_admin=eip /usr/bin/dumpcap
+
+10) Edit the daemon configuration file(s) in "/usr/local/ecap/etc" to setup
+    the options for your environment and start the agent and www daemons.
+    The only directives you should really need to edit in the ecaprd.conf and
+    ecapad.conf are the REMOTE_HOST lines. The tagid's used in these lines
+    should match what you've defined in "/usr/local/ecap/www/cgi/pcap.conf".
+    In ecaprd.conf in the REMOTE_HOST line, enter the matching tagid from
+    pcap.conf and the destination agent's ip address or hostname where the
+    capture should take place. Make sure that if you used an ip address to
+    setup and test ssh publickey authentication, that you use an ip address
+    here too. Or if you used a hostname, then enter the hostname you used
+    for ssh.
+    Do the same for ecapad.conf on the agent machines and make sure the
+    tagid's in the REMOTE_HOST lines match the interface name where you
+    want the capture done. The "remote_hostname" field should be the ip
+    address or hostname of the www machine (ecaprd) that sent the request.
+    If you used the default installation path of "/usr/local/ecap", you
+    should be able to start the daemons with:
+    sudo /usr/local/ecap/etc/ecaprd.sh start
+    sudo /usr/local/ecap/etc/ecapad.sh start
+    To stop them, use stop:
+    sudo /usr/local/ecap/etc/ecaprd.sh stop
+    sudo /usr/local/ecap/etc/ecapad.sh stop
+    These are simple init scripts, but you should be able to use them somehow
+    with your OS to get them to run automatically at boot time. This is
+    OS-dependent, so check your system configuration documentation for details
+    on the extra steps that are needed for them to run automatically at boot.
+
+11) Point your browser to your www machine and try the URL:
+    http://10.3.3.3/ecap/index.tcl
+
+Troubleshooting
+---------------
+
+1) Check the daemon log(s) on each machine:
+   /usr/local/ecap/log/ecaprd.log
+   /usr/local/ecap/log/ecapad.log
+   The error messages should be heplful, they're quite verbose. The most
+   likely issues are going to be with ssh publickey authentication. This
+   is difficult to configure and tedious if you haven't done it before.
+   Go back through the installation steps for ssh and make sure all the
+   files in the .ssh directory for each user on each machine has the correct
+   permissions and owner. Also make sure you've tested ssh in each direction
+   from each machine for each user and you get no ssh authenticity prompts.
+   Using the "-v" option with ssh is sometimes helpful as it prints
+   additional output when it runs, like:
+   sudo sudo -u ecaprd ssh -v 10.1.1.1
+
+2) Check to make sure the ecapad user on agent machines can run tshark.
+   tshark requires special permissions from the OS when run as a non-root
+   user. A simple test would be to run the command below as ecapad:
+   tshark -n -i eth0
+
+3) Check the Apache error log:
+   /var/log/apache2/error.log

agent/home/ecaprd/.ssh/authorized_keys

+ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEApzvUtBla0Vc7Pu183wI06CpEdvMKpWwaK944fx0g4pyuJw1DExlbbl9VTjRmvJLgrT61UbxLLtdlAcnqGW3ay7QvxXqP5ttivyuhTnWdzji7P/YytF4BRQKKJ2fJOLdgFTXQRiim2wQopam1CDAUeCt6QRdbX0rwqy1gDatz2dE= ecaprd daemon

agent/home/ecaprd/.ssh/ecaprd-sshkey.pub

+ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEApzvUtBla0Vc7Pu183wI06CpEdvMKpWwaK944fx0g4pyuJw1DExlbbl9VTjRmvJLgrT61UbxLLtdlAcnqGW3ay7QvxXqP5ttivyuhTnWdzji7P/YytF4BRQKKJ2fJOLdgFTXQRiim2wQopam1CDAUeCt6QRdbX0rwqy1gDatz2dE= ecaprd daemon

agent/usr/local/ecap/captures/.hg_keep_dir

Empty file added.

agent/usr/local/ecap/etc/ecapad-agent2-example.conf

+#
+#  ecapad.conf  -  ecap Agent Daemon configuration file
+#
+#
+#  Syntax/Formatting:
+#
+#	1) Lines that begin with "#" are comment lines.
+#	2) Blank lines are ignored.
+#	3) No whitespace should start a line or appear between the
+#	   directive name and "=".
+#	4) If whitespace appears after "=", it's included as part
+#	   of the value associated with the directive.
+#
+
+################################################################################
+#  Begin General Server Section
+################################################################################
+
+# 'Work_Dir' specifies ecapad's main working directory. It should be exclusive
+# to ecapad since it writes and deletes files here.
+# Use an absolute path (i.e. has a leading slash).
+#
+WORK_DIR=/usr/local/ecap/tmp
+
+# 'Log_File' specifies the log path/filename.
+# Use an absolute path (i.e. has a leading slash).
+#
+LOG_FILE=/usr/local/ecap/log/ecapad.log
+
+# 'Proc_User' specifies the user name the process should run as.
+#
+# Note: SSH should be configured appropriately for this user so it can
+# access remote requestor hosts using public-key authentication.
+# See the directive 'Remote_Host'.
+#
+PROC_USER=ecapad
+
+# 'Proc_Group' specifies the group name the process should run as.
+#
+PROC_GROUP=ecapad
+
+# 'Pid_File' specifies the path and file name for ecaprd's PID file.
+# (Case-sensitive, omit trailing backslash, maximum of 512 characters)
+#
+PID_FILE=/usr/local/ecap/tmp/ecapad.pid
+
+# 'Proc_Sleep_Time' specifies the amount of time, in seconds, that ecapad 
+# will sleep between scans of the "proc" directory. This value does NOT 
+# specify a time interval for directory scans to run. In other words, if you 
+# enter a value of "10", ecapad will not scan the directory every 10 seconds.
+# Instead, ecapad will scan the "proc" directory, move any files, sleep for
+# 10 seconds and then repeat the process. You need to add the processing time
+# to 'Proc_Sleep_Time' to calculate when it will process/scan the directory.
+#
+PROC_SLEEP_TIME=5
+
+################################################################################
+#  End General Server Section
+################################################################################
+
+################################################################################
+#  Begin Capture Application Section
+################################################################################
+
+# 'Capture_App_Binary' specifies the application to use for traffic capture.
+#
+CAPTURE_APP_BINARY=/usr/bin/tshark
+
+# 'Capture_App_Args' specifies any application specific options or arguments
+# to use for traffic capture. Use the variable "%i" as a substitute for
+# the interface name. (See the 'Remote_Host' directive and "if_name".)
+#
+CAPTURE_APP_ARGS=-n -s 0 -t ad -i %i
+
+# 'Capture_App_Max' specifies the maximum number of simultaneous capture
+# application processes to allow. This provides a sanity check and prevents
+# starvation of system resources.
+#
+CAPTURE_APP_MAX=20
+
+################################################################################
+#  End Capture Application Section
+################################################################################
+
+
+################################################################################
+#  Begin Local Capture/Request File Directory Section
+################################################################################
+
+# 'Capture_Dir' specifies the directory where capture files are written
+# by tethereal.
+# Use an absolute path (i.e. a leading slash).
+#
+CAPTURE_DIR=/usr/local/ecap/captures
+
+# 'Inbound_Dir' specifies the directory where files are placed by remote
+# ecap agents (ecapad) that are then moved to 'Request_Dir' for ecap CGI.
+# Use an absolute path (i.e. a leading slash).
+#
+INBOUND_DIR=/usr/local/ecap/inbound
+
+################################################################################
+#  End Local Capture/Request File Directory Section
+################################################################################
+
+
+################################################################################
+#  Begin Remote Capture/Status File Host/Directory Section
+################################################################################
+
+# 'Remote_Host' specifies the tag id, remote host and directory where capture
+# files and request status files are placed via SSH. The tag id should match
+# the value ecap CGI and ecaprd uses to uniquely identify the host where
+# request files originate. Multiple lines are allowed to support more than one
+# remote requestor and/or capture interface.
+#
+#	Value: space delimited string containing:
+#		"tag_id if_name remote_hostname remote_directory"
+#
+REMOTE_HOST=agent2 eth2 10.3.3.3 /usr/local/ecap/inbound-rd
+
+################################################################################
+#  End Remote Capture/Status File Host/Directory Section
+################################################################################
+
+################################################################################
+# Begin SSH Section
+################################################################################
+
+# 'Ssh_Binary' specifies the location of the "ssh" binary.
+# Any options needed should go in the SSH client config file.
+#
+SSH_BINARY=/usr/bin/ssh
+
+# 'Scp_Binary' specifies the location of the "scp" binary.
+# Any options needed should go in the SSH client config file.
+#
+SCP_BINARY=/usr/bin/scp
+
+################################################################################
+# End SSH Section
+################################################################################

agent/usr/local/ecap/etc/ecapad.conf

+#
+#  ecapad.conf  -  ecap Agent Daemon configuration file
+#
+#
+#  Syntax/Formatting:
+#
+#	1) Lines that begin with "#" are comment lines.
+#	2) Blank lines are ignored.
+#	3) No whitespace should start a line or appear between the
+#	   directive name and "=".
+#	4) If whitespace appears after "=", it's included as part
+#	   of the value associated with the directive.
+#
+
+################################################################################
+#  Begin General Server Section
+################################################################################
+
+# 'Work_Dir' specifies ecapad's main working directory. It should be exclusive
+# to ecapad since it writes and deletes files here.
+# Use an absolute path (i.e. has a leading slash).
+#
+WORK_DIR=/usr/local/ecap/tmp
+
+# 'Log_File' specifies the log path/filename.
+# Use an absolute path (i.e. has a leading slash).
+#
+LOG_FILE=/usr/local/ecap/log/ecapad.log
+
+# 'Proc_User' specifies the user name the process should run as.
+#
+# Note: SSH should be configured appropriately for this user so it can
+# access remote requestor hosts using public-key authentication.
+# See the directive 'Remote_Host'.
+#
+PROC_USER=ecapad
+
+# 'Proc_Group' specifies the group name the process should run as.
+#
+PROC_GROUP=ecapad
+
+# 'Pid_File' specifies the path and file name for ecaprd's PID file.
+# (Case-sensitive, omit trailing backslash, maximum of 512 characters)
+#
+PID_FILE=/usr/local/ecap/tmp/ecapad.pid
+
+# 'Proc_Sleep_Time' specifies the amount of time, in seconds, that ecapad 
+# will sleep between scans of the "proc" directory. This value does NOT 
+# specify a time interval for directory scans to run. In other words, if you 
+# enter a value of "10", ecapad will not scan the directory every 10 seconds.
+# Instead, ecapad will scan the "proc" directory, move any files, sleep for
+# 10 seconds and then repeat the process. You need to add the processing time
+# to 'Proc_Sleep_Time' to calculate when it will process/scan the directory.
+#
+PROC_SLEEP_TIME=5
+
+################################################################################
+#  End General Server Section
+################################################################################
+
+################################################################################
+#  Begin Capture Application Section
+################################################################################
+
+# 'Capture_App_Binary' specifies the application to use for traffic capture.
+#
+CAPTURE_APP_BINARY=/usr/bin/tshark
+
+# 'Capture_App_Args' specifies any application specific options or arguments
+# to use for traffic capture. Use the variable "%i" as a substitute for
+# the interface name. (See the 'Remote_Host' directive and "if_name".)
+#
+CAPTURE_APP_ARGS=-n -s 0 -t ad -i %i
+
+# 'Capture_App_Max' specifies the maximum number of simultaneous capture
+# application processes to allow. This provides a sanity check and prevents
+# starvation of system resources.
+#
+CAPTURE_APP_MAX=20
+
+################################################################################
+#  End Capture Application Section
+################################################################################
+
+
+################################################################################
+#  Begin Local Capture/Request File Directory Section
+################################################################################
+
+# 'Capture_Dir' specifies the directory where capture files are written
+# by tethereal.
+# Use an absolute path (i.e. a leading slash).
+#
+CAPTURE_DIR=/usr/local/ecap/captures
+
+# 'Inbound_Dir' specifies the directory where files are placed by remote
+# ecap agents (ecapad) that are then moved to 'Request_Dir' for ecap CGI.
+# Use an absolute path (i.e. a leading slash).
+#
+INBOUND_DIR=/usr/local/ecap/inbound
+
+################################################################################
+#  End Local Capture/Request File Directory Section
+################################################################################
+
+
+################################################################################
+#  Begin Remote Capture/Status File Host/Directory Section
+################################################################################
+
+# 'Remote_Host' specifies the tag id, remote host and directory where capture
+# files and request status files are placed via SSH. The tag id should match
+# the value ecap CGI and ecaprd uses to uniquely identify the host where
+# request files originate. Multiple lines are allowed to support more than one
+# remote requestor and/or capture interface.
+#
+#	Value: space delimited string containing:
+#		"tag_id if_name remote_hostname remote_directory"
+#
+REMOTE_HOST=agent1 eth1 10.3.3.3 /usr/local/ecap/inbound-rd
+
+################################################################################
+#  End Remote Capture/Status File Host/Directory Section
+################################################################################
+
+################################################################################
+# Begin SSH Section
+################################################################################
+
+# 'Ssh_Binary' specifies the location of the "ssh" binary.
+# Any options needed should go in the SSH client config file.
+#
+SSH_BINARY=/usr/bin/ssh
+
+# 'Scp_Binary' specifies the location of the "scp" binary.
+# Any options needed should go in the SSH client config file.
+#
+SCP_BINARY=/usr/bin/scp
+
+################################################################################
+# End SSH Section
+################################################################################

agent/usr/local/ecap/etc/ecapad.sh

+#!/bin/sh
+
+APP_BIN=/usr/local/ecap/sbin/ecapad.tcl
+CONF_FNAME=/usr/local/ecap/etc/ecapad.conf
+PID_FNAME=/usr/local/ecap/tmp/ecapad.pid
+
+case "$1" in
+'start')
+	$APP_BIN -c $CONF_FNAME > /dev/null && echo 'starting ecapad'
+	;;
+'stop')
+	if [ -r $PID_FNAME ] ; then
+		/bin/kill `cat $PID_FNAME` > /dev/null && echo 'stopping ecapad'
+	fi
+	;;
+*)
+	echo "Usage: `basename $0` {start|stop}" >&2
+	;;
+esac
+
+exit 0

agent/usr/local/ecap/inbound/.hg_keep_dir

Empty file added.

agent/usr/local/ecap/log/.hg_keep_dir

Empty file added.

agent/usr/local/ecap/sbin/ecapad.tcl

+#!/usr/bin/env tclsh
+
+#
+# ecapad.tcl - ecap Agent Daemon
+#
+# Runs traffic captures and copies capture and request status files
+# via SSH to ecap requestor hosts.
+#
+#############################################################################
+#
+#   Copyright (c) 2011 Nathan Jennings <nathanj567 AT gmail.com>
+#
+#   This file is part of ecap.
+#
+#   ecap is free software: you can redistribute it and/or modify
+#   it under the terms of the GNU General Public License as published by
+#   the Free Software Foundation, either version 3 of the License, or
+#   (at your option) any later version.
+#
+#   ecap is distributed in the hope that it will be useful,
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#   GNU General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with ecap.  If not, see <http://www.gnu.org/licenses/>.
+#
+#############################################################################
+#
+# Notes and conventions:
+#	1) All global variables start with "glb_".
+#	2) All ecapad implemented functions (local procs) start with "ead_".
+#
+
+# source universe globals
+source /usr/local/ecap/sbin/shared.tcl
+
+# get TclX
+package require Tclx 8.0
+
+##############################################################################
+# Global variables (section begin)
+##############################################################################
+
+# default configuration filename
+set glb_conf_fname "/usr/local/ecap/etc/ecapad.conf"
+
+##############################################################################
+# Should not have to modify anything below this line for a normal install
+# (i.e. if app is moved to another installation directory or environment).
+##############################################################################
+
+# app names/versions
+set glb_app_name "ecapad"
+set glb_app_desc "Ecap Agent Daemon"
+set glb_app_version "0.1.1"
+
+# conf file params
+set glb_work_dir ""				;# working dir
+set glb_log_fname ""			;# log filename
+set glb_proc_user ""			;# user name to run as
+set glb_proc_group ""			;# group name to run as
+set glb_pid_fname ""			;# pid filename
+set glb_proc_sleep_time 0		;# sleep time between dir passes
+# capture app
+set glb_capapp_bin ""			;# capture app binary
+set glb_capapp_args ""			;# capture app arguments
+set glb_capapp_max 0			;# capture app max
+# local paths
+set glb_capture_dir ""			;# capture dir for traffic capture data
+set glb_inbound_dir ""			;# inbound dir for remote agents
+# remote hosts
+set glb_remotes [list]			;# list of remote requestor hosts w/parms
+# ssh
+set glb_ssh_bin ""				;# ssh binary
+set glb_scp_bin ""				;# scp binary
+
+# log file id
+set glb_log_file 1
+
+# pid file id
+set glb_pid_file 1
+
+# app signal flag (set > 0 by sighandler)
+set glb_signal_flag 0
+
+# child signal flag
+set glb_signal_child 0
+
+# number of current capture children
+set glb_cap_childs 0
+
+# debug flag (keeps us in the foreground; no daemon; log to stdout)
+set glb_debug_flag 0
+
+# ead_sleep() needs a global for vwait()
+set glb_sleep_end 0
+
+# after script id
+set glb_after_id ""
+
+##############################################################################
+# Global variables (section end)
+##############################################################################
+
+##############################################################################
+# Local functions (section begin)
+##############################################################################
+
+#
+# Read conf file; place directive values in globals.
+#
+# Returns:
+#	0: if successful
+#  >0: if error
+#
+proc ead_read_conf {conf_fname} {
+
+	global glb_app_name errorCode
+	global glb_work_dir glb_log_fname
+	global glb_proc_user glb_proc_group glb_pid_fname glb_proc_sleep_time
+	global glb_capture_dir glb_inbound_dir glb_remotes
+	global glb_ssh_bin glb_scp_bin glb_capapp_bin glb_capapp_args glb_capapp_max
+
+	# open conf file
+	if {[catch {open $conf_fname r} file]} {
+		puts stderr "error opening $glb_app_name conf file: $conf_fname ($errorCode)"
+		return 1
+	}
+	
+	# count line numbers
+	set lnum 0
+
+	# loop thru each line
+	while {[gets $file line] >= 0} {
+	
+		# keep track of line numbers
+		incr lnum
+
+		# check for empty/whitespace line
+		if {[string length $line] == 0} {
+			continue
+		} elseif {[regexp {^[ \t]+$} $line]} {
+			continue
+		}
+
+		# check for comment line
+		if {[regexp {^#} $line]} {
+			continue
+		}
+
+		# WORK_DIR
+		if {[regexp {^WORK_DIR=(.*)} $line match glb_work_dir]} {
+			continue
+		# LOG_FILE
+		} elseif {[regexp {^LOG_FILE=(.*)} $line match glb_log_fname]} {
+			continue
+		# PROC_USER
+		} elseif {[regexp {^PROC_USER=(.*)} $line match glb_proc_user]} {
+			continue
+		# PROC_GROUP
+		} elseif {[regexp {^PROC_GROUP=(.*)} $line match glb_proc_group]} {
+			continue
+		# PID_FILE_DIR
+		} elseif {[regexp {^PID_FILE=(.*)} $line match glb_pid_fname]} {
+			continue
+		# PROC_SLEEP_TIME
+		} elseif {[regexp {^PROC_SLEEP_TIME=(.*)} $line match \
+					glb_proc_sleep_time]} {
+			continue
+		# CAPTURE_APP_BINARY
+		} elseif {[regexp {^CAPTURE_APP_BINARY=(.*)} $line match \
+					glb_capapp_bin]} {
+			continue
+		# CAPTURE_APP_ARGS
+		} elseif {[regexp {^CAPTURE_APP_ARGS=(.*)} $line match \
+					glb_capapp_args]} {
+			continue
+		# CAPTURE_APP_MAX
+		} elseif {[regexp {^CAPTURE_APP_MAX=(.*)} $line match \
+					glb_capapp_max]} {
+			continue
+		# CAPTURE_DIR
+		} elseif {[regexp {^CAPTURE_DIR=(.*)} $line match \
+					glb_capture_dir]} {
+			continue
+		# INBOUND_DIR
+		} elseif {[regexp {^INBOUND_DIR=(.*)} $line match \
+					glb_inbound_dir]} {
+			continue
+		# REMOTE_HOST
+		} elseif {[regexp {^REMOTE_HOST=(.*)} $line match \
+					tmp_remote]} {
+			lappend glb_remotes $tmp_remote
+			continue
+		# SSH_BINARY
+		} elseif {[regexp {^SSH_BINARY=(.*)} $line match \
+					glb_ssh_bin]} {
+			continue
+		# SCP_BINARY
+		} elseif {[regexp {^SCP_BINARY=(.*)} $line match \
+					glb_scp_bin]} {
+			continue
+		# line not recognized
+		} else {
+			puts stderr "error reading $glb_app_name conf file: line $lnum not recognized"
+			puts stderr "offending line: $line"
+			close $file
+			return 2
+		}
+
+	}
+
+	close $file
+
+return 0
+}
+
+#
+# Validate values read from conf file.
+#
+# Returns:
+#  <0: if error
+#	0: if successful
+#  >0: number of conf file directives that failed validation
+#
+proc ead_validate_conf {} {
+
+	global glb_work_dir glb_log_fname
+	global glb_proc_user glb_proc_group glb_pid_fname glb_proc_sleep_time
+	global glb_capture_dir glb_inbound_dir glb_remotes
+	global glb_ssh_bin glb_scp_bin glb_capapp_bin glb_capapp_args glb_capapp_max
+
+	# keep count of validation errors
+	set numerrs 0
+
+	# WORK_DIR
+	if {[string length $glb_work_dir] == 0} {
+		puts stderr "conf file value WORK_DIR not found"
+		incr numerrs
+	}
+	# LOG_FILE
+	if {[string length $glb_log_fname] == 0} {
+		puts stderr "conf file value LOG_FILE not found"
+		incr numerrs
+	}
+	# PROC_USER
+	if {[string length $glb_proc_user] == 0} {
+		puts stderr "conf file value PROC_USER not found"
+		incr numerrs
+	}
+	# PROC_GROUP
+	if {[string length $glb_proc_group] == 0} {
+		puts stderr "conf file value PROC_GROUP not found"
+		incr numerrs
+	}
+	# PID_FILE
+	if {[string length $glb_pid_fname] == 0} {
+		puts stderr "conf file value PID_FILE not found"
+		incr numerrs
+	}
+	# PROC_SLEEP_TIME
+	if {$glb_proc_sleep_time < 1} {
+		puts stderr "PROC_SLEEP_TIME value must be 1 or greater"
+		incr numerrs
+	}
+	# CAPTURE_APP_BINARY
+	if {[string length $glb_capapp_bin] == 0} {
+		puts stderr "conf file value CAPTURE_APP_BINARY not found"
+		incr numerrs
+	}
+	# CAPTURE_APP_ARGS
+	if {[string length $glb_capapp_args] == 0} {
+		puts stderr "conf file value CAPTURE_APP_ARGS not found"
+		incr numerrs
+	}
+	# CAPTURE_APP_MAX
+	if {$glb_capapp_max < 1} {
+		puts stderr "CAPTURE_APP_MAX value must be 1 or greater"
+		incr numerrs
+	}
+	# CAPTURE_DIR
+	if {[string length $glb_capture_dir] == 0} {
+		puts stderr "conf file value CAPTURE_DIR not found"
+		incr numerrs
+	}
+	# INBOUND_DIR
+	if {[string length $glb_inbound_dir] == 0} {
+		puts stderr "conf file value INBOUND_DIR not found"
+		incr numerrs
+	}
+	# REMOTE_HOST
+	if {[string length [join $glb_remotes]] == 0} {
+		puts stderr "conf file value REMOTE_HOST not found"
+		incr numerrs
+	}
+	# SSH_BINARY
+	if {[string length $glb_ssh_bin] == 0} {
+		puts stderr "conf file value SSH_BINARY not found"
+		incr numerrs
+	}
+	# SCP_BINARY
+	if {[string length $glb_scp_bin] == 0} {
+		puts stderr "conf file value SCP_BINARY not found"
+		incr numerrs
+	}
+
+return $numerrs
+}
+
+#
+# Print banner/version information.
+#
+proc ead_print_banner {} {
+
+	global glb_app_name glb_app_desc glb_app_version
+	global glb_conf_fname
+
+	puts stdout "$glb_app_name ($glb_app_desc) Version $glb_app_version"
+	puts stdout "Default configuration filename: $glb_conf_fname"
+
+return 0
+}
+
+#
+# Print command-line usage.
+#
+proc ead_print_usage {} {
+
+	global glb_app_name
+
+	ead_print_banner
+	puts stdout ""
+	
+	puts stdout "Usage: $glb_app_name \[-a\] \[-c conf_file\] \[-d\] \[-h\] \[-v\]"
+	puts stdout ""
+	puts stdout "   -c conf_file      specify alternate configuration file"
+	puts stdout "   -d                set debug mode, don't fork into background"
+	puts stdout "   -h                print this help text and exit"
+	puts stdout "   -v                print version and exit"
+
+	puts stdout ""
+
+return 0
+}
+
+#
+# Get/parse command-line arguments.
+#
+# Returns:
+#	0: if successful
+#  >0: if error
+#
+proc ead_get_args {argc argv} {
+
+	global glb_debug_flag glb_conf_fname glb_app_name
+
+	for {set i 0} {$i < [llength $argv]} {incr i} {
+		switch -- [lindex $argv $i] {
+			-c	{ if {[string length [lindex $argv [expr $i + 1]]] > 0} {
+						incr i; set glb_conf_fname [lindex $argv $i]
+					} else {
+						puts stderr "conf file not specified after -c"
+						return 1
+					} }
+			-d	{ set glb_debug_flag 1 }
+			-h	{ ead_print_usage; exit 0 }
+			-v	{ ead_print_banner; exit 0 }
+			default	{ puts stderr "unrecognized argument: [lindex $argv $i]"
+						return 2 }
+		}
+	}
+
+	if {$argc > 0} {
+		puts stdout "$glb_app_name command-line options: $argv"
+	} else {
+		puts stdout "$glb_app_name command-line options: <none>"
+	}
+
+return 0
+}
+
+#
+# Log message.
+#
+# Returns:
+#	0: if successful
+#  >0: if error
+#
+proc ead_log {level msg} {
+
+	global glb_log_file
+	global glb_debug_flag
+
+	# construct message
+	set tmpmsg "[clock format [clock seconds] -format "%Y-%m-%d %T"] $level $msg"
+
+	# write to file
+	puts $glb_log_file $tmpmsg
+	flush $glb_log_file
+	
+	# write to console
+	if {$glb_debug_flag != 0} {
+		puts stdout $tmpmsg
+		flush stdout
+	}
+
+return 0
+}
+
+#
+# Open logging.
+#
+# Returns:
+#	0: if successful
+#  >0: if error
+#
+proc ead_log_open {} {
+
+	global errorCode
+	global glb_log_fname
+	global glb_log_file
+
+	# open log file
+	if {[catch {open $glb_log_fname a} glb_log_file]} {
+		puts stderr "error opening log file: $glb_log_fname ($errorCode)"
+		return 1
+	}
+
+return 0
+}
+
+#
+# Close logging.
+#
+# Returns:
+#	0: if successful
+#  >0: if error
+#
+proc ead_log_close {} {
+
+	global glb_log_file
+
+	close $glb_log_file
+
+return 0
+}
+
+#
+# Write pid to file.
+#
+# XXX - There's a usability problem here for Windows users with the pid file.
+#       Windows (at least on XP) seems to not do advisory file locking, like
+#       Unix. Maybe this is the default and can be changed somehow. Anyway,
+#       users will get read (permission) errors if they try to "type", or
+#       otherwise read, the pid file. In contrast, on Unix, the way the code
+#       currently works is a nice feature; we use flock to get advisory file
+#       locking on the pid file. This allows us to to detect if there's a
+#       currently running instance while allowing another process to read the
+#       file (pid) at the same time.
+#
+# Returns:
+#	0: if successful
+#	1: if pid file is locked
+#  >1: if error
+#
+proc ead_write_pid_file {} {
+
+	global errorCode
+	global glb_pid_file
+	global glb_pid_fname
+
+	# open file
+	if {[catch {open "$glb_pid_fname" {RDWR CREAT}} glb_pid_file]} {
+		ead_log ERROR "ead_write_pid_file() error opening pid file: $glb_pid_fname ($errorCode)"
+		return 2
+	}
+	
+	# try to get exclusive (write) lock
+	if {[flock -write -nowait $glb_pid_file 0 0 start] == 0} {
+		ead_log ERROR "pid file in use (locked): $glb_pid_fname"
+		# Note: no need to close here, ead_exit() does it
+		return 1
+	}
+
+	# write pid
+	puts -nonewline $glb_pid_file "[format "%-7s" [id process]]"
+	flush $glb_pid_file
+
+return 0
+}
+
+#
+# Setup signal handlers for:
+#	SIGTERM, SIGINT, SIGQUIT, SIGHUP
+#
+# Returns:
+#	0: if successful
+#  >0: if error
+#
+proc ead_set_signal_handlers {} {
+
+	# check for signal() "-restart" support
+	if {[infox have_signal_restart] == 1} {
+		ead_log INFO "signal supports -restart"
+		signal -restart trap SIGTERM "ead_signal_handler_term"
+		signal -restart trap SIGINT "ead_signal_handler_int"
+		if {[ead_plat_unix]} {
+			signal -restart trap SIGQUIT "ead_signal_handler_quit"
+			signal -restart trap SIGHUP "ead_signal_handler_hup"
+			signal -restart trap SIGCHLD "ead_signal_handler_chld"
+		}
+	# if no "-restart" support
+	} else {
+		ead_log INFO "signal does not support -restart"
+		signal trap SIGTERM "ead_signal_handler_term"
+		signal trap SIGINT "ead_signal_handler_int"
+		if {[ead_plat_unix]} {
+			signal trap SIGQUIT "ead_signal_handler_quit"
+			signal trap SIGHUP "ead_signal_handler_hup"
+			signal trap SIGCHLD "ead_signal_handler_chld"
+		}
+	}
+
+return 0
+}
+
+#
+# Handle signal SIGTERM.
+#
+# Returns:
+#	0: if successful
+#  >0: if error
+#
+proc ead_signal_handler_term {} {
+
+	global glb_signal_flag glb_sleep_end
+
+	# set flag to 1 for sigterm
+	set glb_signal_flag 1
+
+	# wakeup vwait() if we're sleeping
+	set glb_sleep_end 1
+
+return 0
+}
+
+#
+# Handle signal SIGINT.
+#
+# Returns:
+#	0: if successful
+#  >0: if error
+#
+proc ead_signal_handler_int {} {
+
+	global glb_signal_flag glb_sleep_end
+
+	# set flag to 2 for sigint
+	set glb_signal_flag 2
+
+	# wakeup vwait() if we're sleeping
+	set glb_sleep_end 1
+
+return 0
+}
+
+#
+# Handle signal SIGQUIT.
+#
+# Returns:
+#	0: if successful
+#  >0: if error
+#
+proc ead_signal_handler_quit {} {
+
+	global glb_signal_flag glb_sleep_end
+
+	# set flag to 3 for sigquit
+	set glb_signal_flag 3
+
+	# wakeup vwait() if we're sleeping
+	set glb_sleep_end 1
+
+return 0
+}
+
+#
+# Handle signal SIGHUP.
+#
+# Returns:
+#	0: if successful
+#  >0: if error
+#
+proc ead_signal_handler_hup {} {
+
+	global glb_signal_flag glb_sleep_end
+
+	# set flag to 4 for sighup
+	set glb_signal_flag 4
+
+	# wakeup vwait() if we're sleeping
+	set glb_sleep_end 1
+
+return 0
+}
+
+#
+# Handle signal SIGCHLD.
+#
+# Returns:
+#   0: if successful
+#  >0: if error
+#
+proc ead_signal_handler_chld {} {
+
+	global glb_signal_child glb_sleep_end
+
+	# set flag for sigchld
+	set glb_signal_child 1
+
+	# wakeup vwait() if we're sleeping
+	set glb_sleep_end 1
+
+return 0
+}
+
+#
+# Check for system signals. If we should shutdown, do it.
+# The "term" argument, if set to 1, will cause graceful
+# shutdown processing to occur and then exit with a code
+# of "$code". The "child" argument, if true, silences
+# some exit log messages to prevent confusion.
+#
+# Returns:
+#	0: if successful
+#  >0: if error
+#
+proc ead_check_signals {{term 0} {code 0} {child 0}} {
+
+	global errorCode glb_signal_flag glb_signal_child glb_cap_childs
+	global glb_log_fname glb_log_file glb_pid_fname glb_pid_file
+
+	# check if we should wait for children
+	if {$glb_signal_child} {
+		# wait until empty list
+		while {1} {
+			if {[catch {wait -nohang} wl]} {
+				break
+			}
+			if {[llength $wl] != 0} {
+				# maintain proper child count
+				set glb_cap_childs [expr $glb_cap_childs - 1]
+				ead_log INFO "waited for child: $wl ($glb_cap_childs)"
+			} else {
+				# reset child flag
+				set glb_signal_child 0
+				break
+			}
+		}
+	}
+	
+	# check if caller said we should exit, set sigterm flag
+	if {$term == 1} {
+		set glb_signal_flag 1
+	}
+	
+	if {$glb_signal_flag == 0} {
+		return 0
+	}
+	
+	# log caught signal
+	if {$glb_signal_flag == 1} {
+		set signame "sigterm"
+	} elseif {$glb_signal_flag == 2} {
+		set signame "sigint"
+	} elseif {$glb_signal_flag == 3} {
+		set signame "sigquit"
+	} elseif {$glb_signal_flag == 4} {
+		set glb_signal_flag 0
+		ead_log INFO "received signal (sighup), reopening log file"
+		# close log file
+		close $glb_log_file
+		# re-open log file
+		# XXX - yes, if there's an error and we're a daemon we can't log an error
+		# to a file we just failed to open. :o( Run it in debug mode. :P
+		if {[catch {open $glb_log_fname a} glb_log_file]} {
+			ead_log ERROR "error re-opening log file: $glb_log_fname ($errorCode)"
+		}
+		return 0
+	} else {
+		set signame "unknown"
+	}
+	
+	# if we're a child, get out now
+	if {$child} {
+		ead_log_close
+		exit $code
+	}
+	
+	ead_log INFO "received shutdown signal ($signame)"
+	
+	# do shutdown processing and exit gracefully
+	ead_log INFO "closing log file and exiting"
+	ead_log_close
+
+	# if pid file is locked, don't delete it (if Windows, close it 1st (locking?))
+	if {[ead_plat_unix]} {
+		if {$code != 17} { file delete "$glb_pid_fname" }
+		close $glb_pid_file
+	} else {
+		close $glb_pid_file
+		if {$code != 17} { file delete "$glb_pid_fname" }
+	}
+	
+	if {$term == 1} {
+		exit $code
+	}
+	
+	exit 0
+}
+
+#
+# Exit application with an exit code passed from caller.
+#
+proc ead_exit {{code 0} {child 0}} {
+
+	ead_check_signals 1 $code $child
+
+}
+
+#
+# Sleep for n seconds.
+#
+# Returns:
+#	0: if successful
+#  >0: if error
+#
+proc ead_sleep {seconds} {
+
+	global glb_sleep_end glb_after_id
+
+	# Note: if you change the "after" script, remember to also update the
+	# cancellation of it as well in the child capture code
+	set glb_after_id [after [expr {int($seconds * 1000)}] {set glb_sleep_end 1}]
+	vwait glb_sleep_end
+
+return 0
+}
+
+#
+# Detects if currently running platform is *nix.
+#
+# Returns:
+#	0: if we're not on *nix
+#	1: if we're on *nix
+#
+proc ead_plat_unix {} {
+
+	global tcl_platform
+
+	set pf [lindex [array get tcl_platform "platform"] 1]
+	
+	if {[string compare -nocase "$pf" "unix"] == 0} {
+		return 1
+	} else {
+		return 0
+	}
+
+}